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.Info;
import fns.patchwork.command.annotation.Permissive; import fns.patchwork.command.annotation.Permissive;
import fns.patchwork.command.annotation.Subcommand; import fns.patchwork.command.annotation.Subcommand;
import fns.patchwork.security.Node; import fns.patchwork.permissible.Node;
import fns.patchwork.security.NodeType; import fns.patchwork.permissible.NodeType;
import fns.patchwork.security.PermissionHolder; import fns.patchwork.permissible.PermissionHolder;
import fns.patchwork.user.User; import fns.patchwork.user.User;
import java.time.Duration; import java.time.Duration;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;

View File

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

View File

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

View File

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

View File

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

View File

@ -23,9 +23,9 @@
package fns.datura.perms; package fns.datura.perms;
import fns.patchwork.security.Node; import fns.patchwork.permissible.Node;
import fns.patchwork.security.NodeBuilder; import fns.patchwork.permissible.NodeBuilder;
import fns.patchwork.security.NodeType; import fns.patchwork.permissible.NodeType;
public class PermissionNodeBuilder implements NodeBuilder 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.Registration;
import fns.patchwork.base.Shortcuts; import fns.patchwork.base.Shortcuts;
import fns.patchwork.display.adminchat.AdminChatFormat; import fns.patchwork.display.adminchat.AdminChatFormat;
import fns.patchwork.security.Group; import fns.patchwork.permissible.Group;
import fns.patchwork.sql.SQL; import fns.patchwork.sql.SQL;
import fns.patchwork.user.User; import fns.patchwork.user.User;
import fns.patchwork.user.UserData; import fns.patchwork.user.UserData;
import fns.patchwork.utils.logging.FreedomLogger; import fns.patchwork.utils.logging.FNS4J;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
@ -132,7 +132,7 @@ public class SimpleUserData implements UserData
"\nStack trace: " + "\nStack trace: " +
ExceptionUtils.getStackTrace(ex); ExceptionUtils.getStackTrace(ex);
FreedomLogger.getLogger("Datura") FNS4J.getLogger("Datura")
.error(sb); .error(sb);
} }

View File

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

View File

@ -28,12 +28,12 @@ import fns.patchwork.economy.CompletedTransaction;
import fns.patchwork.economy.EconomicEntity; import fns.patchwork.economy.EconomicEntity;
import fns.patchwork.economy.TransactionLogger; import fns.patchwork.economy.TransactionLogger;
import fns.patchwork.economy.TransactionResult; import fns.patchwork.economy.TransactionResult;
import fns.patchwork.utils.logging.FreedomLogger; import fns.patchwork.utils.logging.FNS4J;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
public class SimpleTransactionLogger implements TransactionLogger public class SimpleTransactionLogger implements TransactionLogger
{ {
private final MutableAudienceForwarder audience = MutableAudienceForwarder.from(FreedomLogger.getLogger("Fossil")); private final MutableAudienceForwarder audience = MutableAudienceForwarder.from(FNS4J.getLogger("Fossil"));
@Override @Override
public void logTransaction(final CompletedTransaction completedTransaction) 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.Permissive;
import fns.patchwork.command.annotation.Subcommand; import fns.patchwork.command.annotation.Subcommand;
import fns.patchwork.provider.ContextProvider; import fns.patchwork.provider.ContextProvider;
import fns.patchwork.utils.logging.FreedomLogger; import fns.patchwork.utils.logging.FNS4J;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -135,7 +135,7 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
} }
catch (Exception ex) catch (Exception ex)
{ {
FreedomLogger.getLogger("Patchwork") FNS4J.getLogger("Patchwork")
.error(ex); .error(ex);
} }
@ -184,7 +184,7 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
final Object obj = provider.fromString(arg, argType); final Object obj = provider.fromString(arg, argType);
if (obj == null) if (obj == null)
{ {
FreedomLogger.getLogger("Datura") FNS4J.getLogger("Datura")
.error("Failed to parse argument " + arg + " for type " + argType.getName()); .error("Failed to parse argument " + arg + " for type " + argType.getName());
return; return;
} }
@ -207,7 +207,7 @@ public final class BukkitDelegate extends Command implements PluginIdentifiableC
} }
catch (Exception ex) catch (Exception ex)
{ {
FreedomLogger.getLogger("Patchwork") FNS4J.getLogger("Patchwork")
.error(ex); .error(ex);
} }
} }

View File

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

View File

@ -23,7 +23,7 @@
package fns.patchwork.display; package fns.patchwork.display;
import fns.patchwork.utils.kyori.FreedomAdventure; import fns.patchwork.kyori.PlainTextWrapper;
import org.bukkit.entity.HumanEntity; import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryType; import org.bukkit.event.inventory.InventoryType;
@ -73,7 +73,7 @@ public class DisplayableView extends InventoryView
this.top = top; this.top = top;
this.bottom = bottom; this.bottom = bottom;
this.type = InventoryType.CHEST; this.type = InventoryType.CHEST;
this.title = FreedomAdventure.toPlainText(type.defaultTitle()); this.title = PlainTextWrapper.toPlainText(type.defaultTitle());
} }
@Override @Override
@ -116,6 +116,6 @@ public class DisplayableView extends InventoryView
@Override @Override
public @NotNull String getOriginalTitle() 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.Patchwork;
import fns.patchwork.base.Registration; import fns.patchwork.base.Registration;
import fns.patchwork.base.Shortcuts; import fns.patchwork.permissible.Groups;
import fns.patchwork.security.Groups;
import fns.patchwork.user.UserData; import fns.patchwork.user.UserData;
import io.papermc.paper.event.player.AsyncChatEvent; import io.papermc.paper.event.player.AsyncChatEvent;
import java.util.HashMap; import java.util.HashMap;

View File

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

View File

@ -21,7 +21,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
package fns.patchwork.utils.kyori; package fns.patchwork.kyori;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextDecoration; 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. * 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 unsafe = MiniMessage.miniMessage();
private static final MiniMessage safe = MiniMessage.builder() private static final MiniMessage safe = MiniMessage.builder()
@ -48,7 +48,7 @@ public class FreedomMiniMessage
)) ))
.build(); .build();
private FreedomMiniMessage() private MiniMessageWrapper()
{ {
throw new UnsupportedOperationException("Instantiation of a static utility class is not supported."); 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) public static Component deserialize(final boolean safe, final String input, final TagResolver... placeholders)
{ {
return (safe return (safe
? FreedomMiniMessage.safe ? MiniMessageWrapper.safe
: unsafe).deserialize(input, placeholders); : unsafe).deserialize(input, placeholders);
} }
@ -80,7 +80,7 @@ public class FreedomMiniMessage
public static String serialize(final boolean safe, final Component input) public static String serialize(final boolean safe, final Component input)
{ {
return (safe return (safe
? FreedomMiniMessage.safe ? MiniMessageWrapper.safe
: unsafe).serialize(input); : unsafe).serialize(input);
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,7 +25,7 @@ package fns.patchwork.user;
import fns.patchwork.economy.EconomicEntity; import fns.patchwork.economy.EconomicEntity;
import fns.patchwork.economy.EconomicEntityData; import fns.patchwork.economy.EconomicEntityData;
import fns.patchwork.security.PermissionHolder; import fns.patchwork.permissible.PermissionHolder;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
public interface User extends PermissionHolder, EconomicEntity 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.display.adminchat.AdminChatFormat;
import fns.patchwork.economy.EconomicEntityData; import fns.patchwork.economy.EconomicEntityData;
import fns.patchwork.security.Group; import fns.patchwork.permissible.Group;
import java.util.UUID; import java.util.UUID;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;

View File

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

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