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

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;
};
}
}