Add Veritas, Tyr, also other changes

This commit is contained in:
Paul Reilly 2023-08-26 19:05:45 -05:00
parent 8e2e466864
commit a676207afa
37 changed files with 851 additions and 64 deletions

View File

@ -30,9 +30,9 @@ import fns.patchwork.command.annotation.Completion;
import fns.patchwork.command.annotation.Info;
import fns.patchwork.command.annotation.Permissive;
import fns.patchwork.command.annotation.Subcommand;
import fns.patchwork.security.Node;
import fns.patchwork.security.NodeType;
import fns.patchwork.security.PermissionHolder;
import fns.patchwork.permissible.Node;
import fns.patchwork.permissible.NodeType;
import fns.patchwork.permissible.PermissionHolder;
import fns.patchwork.user.User;
import java.time.Duration;
import org.bukkit.command.CommandSender;

View File

@ -23,8 +23,8 @@
package fns.datura.perms;
import fns.patchwork.security.Node;
import fns.patchwork.security.NodeType;
import fns.patchwork.permissible.Node;
import fns.patchwork.permissible.NodeType;
public class DefaultNodes
{

View File

@ -25,8 +25,8 @@ package fns.datura.perms;
import fns.patchwork.base.Patchwork;
import fns.patchwork.base.Shortcuts;
import fns.patchwork.security.Group;
import fns.patchwork.security.Node;
import fns.patchwork.permissible.Group;
import fns.patchwork.permissible.Node;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

View File

@ -28,7 +28,7 @@ import fns.datura.user.SimpleUserData;
import fns.patchwork.base.Patchwork;
import fns.patchwork.base.Registration;
import fns.patchwork.base.Shortcuts;
import fns.patchwork.security.Node;
import fns.patchwork.permissible.Node;
import fns.patchwork.user.User;
import fns.patchwork.user.UserData;
import java.util.HashMap;

View File

@ -23,8 +23,8 @@
package fns.datura.perms;
import fns.patchwork.security.Node;
import fns.patchwork.security.NodeType;
import fns.patchwork.permissible.Node;
import fns.patchwork.permissible.NodeType;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionDefault;

View File

@ -23,9 +23,9 @@
package fns.datura.perms;
import fns.patchwork.security.Node;
import fns.patchwork.security.NodeBuilder;
import fns.patchwork.security.NodeType;
import fns.patchwork.permissible.Node;
import fns.patchwork.permissible.NodeBuilder;
import fns.patchwork.permissible.NodeType;
public class PermissionNodeBuilder implements NodeBuilder
{

View File

@ -29,11 +29,11 @@ import fns.patchwork.base.Patchwork;
import fns.patchwork.base.Registration;
import fns.patchwork.base.Shortcuts;
import fns.patchwork.display.adminchat.AdminChatFormat;
import fns.patchwork.security.Group;
import fns.patchwork.permissible.Group;
import fns.patchwork.sql.SQL;
import fns.patchwork.user.User;
import fns.patchwork.user.UserData;
import fns.patchwork.utils.logging.FreedomLogger;
import fns.patchwork.utils.logging.FNS4J;
import java.sql.SQLException;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;
@ -132,8 +132,8 @@ public class SimpleUserData implements UserData
"\nStack trace: " +
ExceptionUtils.getStackTrace(ex);
FreedomLogger.getLogger("Datura")
.error(sb);
FNS4J.getLogger("Datura")
.error(sb);
}
final Player player = Bukkit.getPlayer(UUID.fromString(uuid));

View File

@ -27,7 +27,7 @@ import fns.patchwork.command.Commander;
import fns.patchwork.command.annotation.Base;
import fns.patchwork.command.annotation.Info;
import fns.patchwork.command.annotation.Permissive;
import fns.patchwork.utils.kyori.FreedomMiniMessage;
import fns.patchwork.kyori.MiniMessageWrapper;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
@ -48,7 +48,7 @@ public class CakeCommand extends Commander
@Base
public void broadcastCake(final CommandSender sender)
{
Bukkit.getServer().sendMessage(FreedomMiniMessage.deserialize(true,
Bukkit.getServer().sendMessage(MiniMessageWrapper.deserialize(true,
"<rainbow>But there's no sense crying over " +
"every mistake. You just keep on trying " +
"till you run out of " +
@ -56,7 +56,7 @@ public class CakeCommand extends Commander
final ItemStack stack = new ItemStack(Material.CAKE, 1);
final ItemMeta meta = stack.getItemMeta();
meta.displayName(FreedomMiniMessage.deserialize(true, "<dark_gray>The <white>Lie"));
meta.displayName(MiniMessageWrapper.deserialize(true, "<dark_gray>The <white>Lie"));
stack.setItemMeta(meta);
Bukkit.getOnlinePlayers()

View File

@ -28,12 +28,12 @@ import fns.patchwork.economy.CompletedTransaction;
import fns.patchwork.economy.EconomicEntity;
import fns.patchwork.economy.TransactionLogger;
import fns.patchwork.economy.TransactionResult;
import fns.patchwork.utils.logging.FreedomLogger;
import fns.patchwork.utils.logging.FNS4J;
import net.kyori.adventure.text.Component;
public class SimpleTransactionLogger implements TransactionLogger
{
private final MutableAudienceForwarder audience = MutableAudienceForwarder.from(FreedomLogger.getLogger("Fossil"));
private final MutableAudienceForwarder audience = MutableAudienceForwarder.from(FNS4J.getLogger("Fossil"));
@Override
public void logTransaction(final CompletedTransaction completedTransaction)

View File

@ -28,7 +28,7 @@ import fns.patchwork.command.annotation.Info;
import fns.patchwork.command.annotation.Permissive;
import fns.patchwork.command.annotation.Subcommand;
import fns.patchwork.provider.ContextProvider;
import fns.patchwork.utils.logging.FreedomLogger;
import fns.patchwork.utils.logging.FNS4J;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -135,8 +135,8 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
}
catch (Exception ex)
{
FreedomLogger.getLogger("Patchwork")
.error(ex);
FNS4J.getLogger("Patchwork")
.error(ex);
}
return true;
@ -184,8 +184,8 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
final Object obj = provider.fromString(arg, argType);
if (obj == null)
{
FreedomLogger.getLogger("Datura")
.error("Failed to parse argument " + arg + " for type " + argType.getName());
FNS4J.getLogger("Datura")
.error("Failed to parse argument " + arg + " for type " + argType.getName());
return;
}
objects[i] = obj;
@ -207,8 +207,8 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
}
catch (Exception ex)
{
FreedomLogger.getLogger("Patchwork")
.error(ex);
FNS4J.getLogger("Patchwork")
.error(ex);
}
}

View File

@ -23,7 +23,7 @@
package fns.patchwork.data;
import fns.patchwork.security.Group;
import fns.patchwork.permissible.Group;
import java.util.ArrayList;
import java.util.List;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;

View File

@ -23,7 +23,7 @@
package fns.patchwork.display;
import fns.patchwork.utils.kyori.FreedomAdventure;
import fns.patchwork.kyori.PlainTextWrapper;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType;
@ -73,7 +73,7 @@ public class DisplayableView extends InventoryView
this.top = top;
this.bottom = bottom;
this.type = InventoryType.CHEST;
this.title = FreedomAdventure.toPlainText(type.defaultTitle());
this.title = PlainTextWrapper.toPlainText(type.defaultTitle());
}
@Override
@ -116,6 +116,6 @@ public class DisplayableView extends InventoryView
@Override
public @NotNull String getOriginalTitle()
{
return FreedomAdventure.toPlainText(type.defaultTitle());
return PlainTextWrapper.toPlainText(type.defaultTitle());
}
}

View File

@ -25,8 +25,7 @@ package fns.patchwork.display.adminchat;
import fns.patchwork.base.Patchwork;
import fns.patchwork.base.Registration;
import fns.patchwork.base.Shortcuts;
import fns.patchwork.security.Groups;
import fns.patchwork.permissible.Groups;
import fns.patchwork.user.UserData;
import io.papermc.paper.event.player.AsyncChatEvent;
import java.util.HashMap;

View File

@ -21,7 +21,7 @@
* SOFTWARE.
*/
package fns.patchwork.utils.kyori;
package fns.patchwork.kyori;
import fns.patchwork.base.Patchwork;
import net.kyori.adventure.chat.ChatType;
@ -40,7 +40,7 @@ import org.bukkit.plugin.java.JavaPlugin;
* <br>
* As a result, we need to conform to those specifications even if we do not use this feature.
*/
public final class KyoriConstants
public final class ChatBinder
{
private static final ChatType type = ChatType.CHAT;
@ -49,7 +49,7 @@ public final class KyoriConstants
*/
public static final ChatType.Bound PATCHWORK = fromPlugin(Patchwork.class);
private KyoriConstants()
private ChatBinder()
{
}

View File

@ -21,7 +21,7 @@
* SOFTWARE.
*/
package fns.patchwork.utils.kyori;
package fns.patchwork.kyori;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration;
@ -32,7 +32,7 @@ import net.kyori.adventure.text.minimessage.tag.standard.StandardTags;
/**
* This class contains a wrapper for a MiniMessage serializer.
*/
public class FreedomMiniMessage
public class MiniMessageWrapper
{
private static final MiniMessage unsafe = MiniMessage.miniMessage();
private static final MiniMessage safe = MiniMessage.builder()
@ -48,7 +48,7 @@ public class FreedomMiniMessage
))
.build();
private FreedomMiniMessage()
private MiniMessageWrapper()
{
throw new UnsupportedOperationException("Instantiation of a static utility class is not supported.");
}
@ -65,7 +65,7 @@ public class FreedomMiniMessage
public static Component deserialize(final boolean safe, final String input, final TagResolver... placeholders)
{
return (safe
? FreedomMiniMessage.safe
? MiniMessageWrapper.safe
: unsafe).deserialize(input, placeholders);
}
@ -80,7 +80,7 @@ public class FreedomMiniMessage
public static String serialize(final boolean safe, final Component input)
{
return (safe
? FreedomMiniMessage.safe
? MiniMessageWrapper.safe
: unsafe).serialize(input);
}
}

View File

@ -21,7 +21,7 @@
* SOFTWARE.
*/
package fns.patchwork.utils.kyori;
package fns.patchwork.kyori;
import java.util.function.Supplier;
import net.kyori.adventure.text.Component;
@ -31,12 +31,12 @@ import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
* This class contains the only reference to plain text component serializer, and allows access to it via wrapper
* functions.
*/
public class FreedomAdventure
public class PlainTextWrapper
{
private static final PlainTextComponentSerializer PLAIN_TEXT_COMPONENT_SERIALIZER =
PlainTextComponentSerializer.plainText();
private FreedomAdventure()
private PlainTextWrapper()
{
throw new UnsupportedOperationException("Instantiation of a static utility class is not supported.");
}

View File

@ -21,7 +21,7 @@
* SOFTWARE.
*/
package fns.patchwork.security;
package fns.patchwork.permissible;
import net.kyori.adventure.text.Component;

View File

@ -21,7 +21,7 @@
* SOFTWARE.
*/
package fns.patchwork.security;
package fns.patchwork.permissible;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

View File

@ -21,7 +21,7 @@
* SOFTWARE.
*/
package fns.patchwork.security;
package fns.patchwork.permissible;
import javax.annotation.concurrent.Immutable;
import org.bukkit.permissions.Permission;

View File

@ -21,7 +21,7 @@
* SOFTWARE.
*/
package fns.patchwork.security;
package fns.patchwork.permissible;
public interface NodeBuilder
{

View File

@ -21,7 +21,7 @@
* SOFTWARE.
*/
package fns.patchwork.security;
package fns.patchwork.permissible;
public enum NodeType
{

View File

@ -21,7 +21,7 @@
* SOFTWARE.
*/
package fns.patchwork.security;
package fns.patchwork.permissible;
import java.util.Set;
import java.util.UUID;

View File

@ -25,7 +25,7 @@ package fns.patchwork.user;
import fns.patchwork.economy.EconomicEntity;
import fns.patchwork.economy.EconomicEntityData;
import fns.patchwork.security.PermissionHolder;
import fns.patchwork.permissible.PermissionHolder;
import net.kyori.adventure.text.Component;
public interface User extends PermissionHolder, EconomicEntity

View File

@ -25,7 +25,7 @@ package fns.patchwork.user;
import fns.patchwork.display.adminchat.AdminChatFormat;
import fns.patchwork.economy.EconomicEntityData;
import fns.patchwork.security.Group;
import fns.patchwork.permissible.Group;
import java.util.UUID;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

View File

@ -23,7 +23,7 @@
package fns.patchwork.utils.logging;
import fns.patchwork.utils.kyori.FreedomAdventure;
import fns.patchwork.kyori.PlainTextWrapper;
import java.util.function.Supplier;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.chat.ChatType;
@ -34,19 +34,21 @@ import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class FreedomLogger implements Audience
public class FNS4J implements Audience
{
private final Logger logger;
private boolean debug = false;
private FreedomLogger(final String moduleName)
public static final FNS4J PATCHWORK = getLogger("Patchwork");
private FNS4J(final String moduleName)
{
this.logger = LoggerFactory.getLogger("FreedomNetworkSuite::" + moduleName);
}
public static FreedomLogger getLogger(final String moduleName)
public static FNS4J getLogger(final String moduleName)
{
return new FreedomLogger(moduleName);
return new FNS4J(moduleName);
}
public void setDebugMode(final boolean debug)
@ -87,7 +89,7 @@ public class FreedomLogger implements Audience
*/
public String infoComponent(final Component component)
{
final String plainText = FreedomAdventure.toPlainText(component);
final String plainText = PlainTextWrapper.toPlainText(component);
logger.info(plainText);
return plainText;
@ -120,7 +122,7 @@ public class FreedomLogger implements Audience
*/
public void warnComponent(final Component component)
{
final String plainText = FreedomAdventure.toPlainText(component);
final String plainText = PlainTextWrapper.toPlainText(component);
logger.warn(plainText);
}
@ -179,7 +181,7 @@ public class FreedomLogger implements Audience
*/
public String errorComponent(final Component component)
{
final String plainText = FreedomAdventure.toPlainText(component);
final String plainText = PlainTextWrapper.toPlainText(component);
logger.error(plainText);
@ -228,7 +230,7 @@ public class FreedomLogger implements Audience
*/
public String debugComponent(final Component component)
{
final String plainText = FreedomAdventure.toPlainText(component);
final String plainText = PlainTextWrapper.toPlainText(component);
this.debug(plainText);

42
Tyr/.gitignore vendored Normal file
View File

@ -0,0 +1,42 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

25
Tyr/build.gradle Normal file
View File

@ -0,0 +1,25 @@
plugins {
id 'java'
}
group = 'fns.tyr'
version = '1.0.0'
repositories {
mavenCentral()
}
dependencies {
compileOnly project(":Patchwork")
compileOnly project(":Datura")
library 'com.hierynomus:sshj:0.28.0'
library 'org.bouncycastle:bcprov-jdk18on:1.76'
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
}
test {
useJUnitPlatform()
}

View File

@ -0,0 +1,62 @@
# MIT License
#
# Copyright (c) 2023 Total Freedom Server Network
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# RCON and SSH configuration file for Tyr (Remote SSH to RCON module).
# This section represents the RCON connection configuration for the server.
rcon:
# The host to connect to.
host: localhost
# The RCON port to connect to.
port: 25575
# The password to use when connecting.
password: password
# The timeout to use when connecting.
timeout: 10s
# The maximum number of packets to receive before terminating the connection
# To prevent extensive packet flooding.
max-packets: 1000
# This section represents the SSH connection configuration for the server.
ssh:
# The host to connect to.
host: localhost
# The SSH port to connect to.
port: 22
# The username to use when connecting.
username: root
# The password to use when connecting.
password: password
# The timeout to use when connecting.
timeout: 10s

42
Veritas/.gitignore vendored Normal file
View File

@ -0,0 +1,42 @@
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

23
Veritas/build.gradle Normal file
View File

@ -0,0 +1,23 @@
plugins {
id 'java'
}
group = 'fns.veritas'
version = '1.0.0'
repositories {
mavenCentral()
}
dependencies {
compileOnly project(":Patchwork")
compileOnly project(":Datura")
library 'com.discord4j:discord4j-core:3.2.5'
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
}
test {
useJUnitPlatform()
}

View File

@ -0,0 +1,54 @@
/*
* This file is part of Freedom-Network-Suite - https://github.com/AtlasMediaGroup/Freedom-Network-Suite
* Copyright (C) 2023 Total Freedom Server Network and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fns.veritas;
import fns.patchwork.utils.logging.FNS4J;
import fns.veritas.client.BotClient;
import fns.veritas.client.BotConfig;
public class Aggregate
{
private final FNS4J logger;
private final BotClient bot;
private final Veritas plugin;
public Aggregate(final Veritas plugin)
{
this.plugin = plugin;
this.logger = FNS4J.getLogger(plugin.getName());
this.bot = new BotClient(new BotConfig(plugin));
}
public FNS4J getLogger() {
return logger;
}
public BotClient getBot() {
return bot;
}
public Veritas getPlugin() {
return plugin;
}
}

View File

@ -0,0 +1,46 @@
/*
* This file is part of Freedom-Network-Suite - https://github.com/AtlasMediaGroup/Freedom-Network-Suite
* Copyright (C) 2023 Total Freedom Server Network and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fns.veritas;
import org.bukkit.plugin.java.JavaPlugin;
public class Veritas extends JavaPlugin
{
private Aggregate aggregate;
@Override
public void onEnable()
{
this.aggregate = new Aggregate(this);
getAggregate()
.getLogger()
.info("Veritas has been enabled!");
}
public Aggregate getAggregate()
{
return aggregate;
}
}

View File

@ -0,0 +1,116 @@
/*
* This file is part of Freedom-Network-Suite - https://github.com/AtlasMediaGroup/Freedom-Network-Suite
* Copyright (C) 2023 Total Freedom Server Network and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fns.veritas.bukkit;
import fns.veritas.Veritas;
import fns.veritas.client.BotClient;
import io.papermc.paper.event.player.AsyncChatEvent;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.GameRule;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent;
public class BukkitNative implements Listener
{
private final BotClient bot;
private final Veritas plugin;
public BukkitNative(final Veritas plugin)
{
this.plugin = plugin;
this.bot = plugin.getAggregate().getBot();
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event)
{
plugin.getAggregate()
.getBot()
.messageChatChannel("**" + plugin.getAggregate()
.getBot()
.deformat(event.getPlayer().getName())
+ " joined the server" + "**", true);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerLeave(PlayerQuitEvent event)
{
plugin.getAggregate()
.getBot()
.messageChatChannel("**"
+ plugin.getAggregate()
.getBot()
.deformat(event.getPlayer().getName())
+ " left the server" + "**", true);
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerDeath(PlayerDeathEvent event)
{
//Avoiding NPE Unboxing Warnings
Boolean b = event.getEntity()
.getWorld()
.getGameRuleValue(GameRule.SHOW_DEATH_MESSAGES);
if (b == null || !b)
{
return;
}
Component deathMessage = event.deathMessage();
if (deathMessage != null)
{
plugin.getAggregate()
.getBot()
.messageChatChannel("**"
+ plugin.getAggregate()
.getBot()
.deformat(
PlainTextComponentSerializer.plainText()
.serialize(
deathMessage))
+ "**", true);
}
}
@EventHandler(ignoreCancelled = true)
public void onAsyncPlayerChat(final AsyncChatEvent event)
{
Player player = event.getPlayer();
String message = PlainTextComponentSerializer.plainText().serialize(event.message());
if (!plugin.getServer().hasWhitelist() && bot != null)
{
plugin.getAggregate().getBot().messageChatChannel(player.getName()
+ " \u00BB "
+ message, true);
}
}
}

View File

@ -0,0 +1,108 @@
/*
* This file is part of Freedom-Network-Suite - https://github.com/AtlasMediaGroup/Freedom-Network-Suite
* Copyright (C) 2023 Total Freedom Server Network and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fns.veritas.bukkit;
import discord4j.core.event.domain.message.MessageCreateEvent;
import discord4j.core.object.entity.Attachment;
import discord4j.core.object.entity.Member;
import discord4j.core.object.entity.Message;
import fns.veritas.Veritas;
import fns.veritas.client.BotClient;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
public class ServerListener
{
private final BotClient bot;
private final Veritas plugin;
public ServerListener(final Veritas plugin)
{
this.plugin = plugin;
this.bot = plugin.getAggregate().getBot();
}
public void minecraftChatBound()
{
bot.getClient()
.getEventDispatcher()
.on(MessageCreateEvent.class)
.filter(m -> m.getMessage()
.getChannelId()
.equals(bot.getChatChannelId()))
.filter(m -> m.getMember().orElse(null) != null)
.filter(m -> !m.getMessage()
.getAuthor()
.orElseThrow(IllegalAccessError::new)
.getId()
.equals(plugin.getAggregate().getBot().getClient().getSelfId()))
.doOnError(plugin.getAggregate().getLogger()::error)
.subscribe(this::doMessageBodyDetails);
}
private void doMessageBodyDetails(MessageCreateEvent m)
{
Member member = m.getMember().orElseThrow();
Message msg = m.getMessage();
TextComponent.Builder builder = Component.text();
TextComponent prefix = Component.text("[", NamedTextColor.DARK_GRAY)
.append(Component.text("Discord", NamedTextColor.DARK_AQUA)
.hoverEvent(HoverEvent.showText(
Component.text("Click to join our Discord server!")))
.clickEvent(ClickEvent.openUrl(
plugin.getAggregate().getBot().getInviteLink())))
.append(Component.text("] ", NamedTextColor.DARK_GRAY));
TextComponent user = Component.empty();
user = user.append(Component.text(member.getDisplayName().trim()));
TextComponent message = Component.text(": ", NamedTextColor.DARK_GRAY)
.append(
Component.text(msg.getContent(), NamedTextColor.WHITE));
// Attachments
if (!msg.getAttachments().isEmpty())
{
if (!msg.getContent().isEmpty())
{
message = message.append(Component.space());
}
for (Attachment attachment : msg.getAttachments())
{
message = message.append(Component.text("[Media] ", NamedTextColor.YELLOW)
.hoverEvent(HoverEvent.showText(Component.text(attachment.getUrl())))
.clickEvent(ClickEvent.openUrl(attachment.getUrl())));
}
}
Bukkit.broadcast(builder.append(prefix, user, message).build());
}
}

View File

@ -0,0 +1,147 @@
/*
* This file is part of Freedom-Network-Suite - https://github.com/AtlasMediaGroup/Freedom-Network-Suite
* Copyright (C) 2023 Total Freedom Server Network and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fns.veritas.client;
import com.google.common.collect.ImmutableList;
import discord4j.common.util.Snowflake;
import discord4j.core.DiscordClientBuilder;
import discord4j.core.GatewayDiscordClient;
import discord4j.core.object.entity.Guild;
import discord4j.core.object.entity.Message;
import discord4j.core.object.entity.channel.TextChannel;
import discord4j.core.spec.MessageCreateSpec;
import reactor.core.publisher.Mono;
public class BotClient
{
private final GatewayDiscordClient client;
private final BotConfig config;
private final ImmutableList<String> DISCORD_SUBDOMAINS;
public BotClient(final BotConfig config)
{
this.config = config;
this.DISCORD_SUBDOMAINS = ImmutableList.of("discordapp.com", "discord.com", "discord.gg");
this.client = DiscordClientBuilder.create(config.getToken())
.build()
.login()
.block();
}
public void validateConnection()
{
if (client == null)
throw new IllegalStateException();
}
public String getBotId()
{
return client.getSelfId().asString();
}
public Mono<Guild> getServerGuildId()
{
return client.getGuildById(config.getId());
}
public GatewayDiscordClient getClient()
{
return client;
}
public Snowflake getChatChannelId()
{
return config.getChatChannelId();
}
public Snowflake getLogChannelId()
{
return config.getLogChannelId();
}
public String getInviteLink()
{
return config.getInviteLink();
}
public void messageChatChannel(String message, boolean system)
{
String chat_channel_id = config.getChatChannelId().asString();
String sanitizedMessage = (system) ? message : sanitizeChatMessage(message);
if (sanitizedMessage.isBlank())
return;
if (!chat_channel_id.isEmpty())
{
MessageCreateSpec spec = MessageCreateSpec.builder()
.content(sanitizedMessage)
.build();
Mono<Message> sentMessage = getClient()
.getChannelById(config.getChatChannelId())
.ofType(TextChannel.class)
.flatMap(c -> c.createMessage(spec));
sentMessage.subscribe();
}
}
private String sanitizeChatMessage(String message)
{
String newMessage = message;
if (message.contains("@"))
{
// \u200B is Zero Width Space, invisible on Discord
newMessage = message.replace("@", "@\u200B");
}
if (message.toLowerCase().contains("discord.gg")) // discord.gg/invite works as an invite
{
return "";
}
for (String subdomain : DISCORD_SUBDOMAINS)
{
if (message.toLowerCase().contains(subdomain + "/invite"))
{
return "";
}
}
if (message.contains("§"))
{
newMessage = message.replace("§", "");
}
return deformat(newMessage);
}
public String deformat(String input)
{
return input.replaceAll("([_\\\\`*>|])", "\\\\$1");
}
}

View File

@ -0,0 +1,118 @@
/*
* This file is part of Freedom-Network-Suite - https://github.com/AtlasMediaGroup/Freedom-Network-Suite
* Copyright (C) 2023 Total Freedom Server Network and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package fns.veritas.client;
import discord4j.common.util.Snowflake;
import discord4j.discordjson.Id;
import fns.patchwork.config.WrappedBukkitConfiguration;
import fns.veritas.Veritas;
import java.io.File;
import java.io.IOException;
import java.util.function.Function;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.jetbrains.annotations.NonNls;
public class BotConfig
{
@NonNls
public static final String GUILD_ID = "guild_id";
@NonNls
private static final String BOT_TOKEN = "bot_token";
private final WrappedBukkitConfiguration config;
public BotConfig(final Veritas plugin)
{
this.config = new WrappedBukkitConfiguration(f0(plugin),
new File(plugin.getDataFolder(), "config.yml"));
}
public String getToken()
{
return config.getString(BOT_TOKEN);
}
public String getPrefix()
{
return config.getString("bot_prefix");
}
public Snowflake getId()
{
return Snowflake.of(config.getString(GUILD_ID));
}
public Snowflake getChatChannelId()
{
return Snowflake.of(config.getString("channel_id"));
}
public Snowflake getLogChannelId()
{
return Snowflake.of(config.getString("log_channel_id"));
}
public String getInviteLink()
{
return config.getString("invite_link");
}
private Function<File, FileConfiguration> f0(final Veritas plugin)
{
return f ->
{
FileConfiguration fc = YamlConfiguration.loadConfiguration(f);
if (!fc.contains(BOT_TOKEN))
{
try
{
plugin.saveResource(f.getName(), true);
fc.load(f);
}
catch (IOException | InvalidConfigurationException ex)
{
fc.addDefault(BOT_TOKEN, "token");
fc.addDefault("bot_prefix", "!");
fc.addDefault(GUILD_ID, GUILD_ID);
fc.addDefault("channel_id", "nil");
fc.addDefault("log_channel_id", "nil");
fc.addDefault("invite_link", "https://discord.gg/invite");
fc.options().copyDefaults(true);
try
{
fc.save(f);
}
catch (IOException e)
{
plugin.getAggregate().getLogger().error(e);
}
}
}
return fc;
};
}
}

View File

@ -3,4 +3,7 @@ include 'Patchwork'
include 'Datura'
include 'Fossil'
include 'Corvo'
include 'Cladis'
include 'Cladis'
include 'Tyr'
include 'Veritas'