Initial commit

This commit is contained in:
Teriuihi 2021-09-16 22:33:59 +02:00
commit a18f9bdbb5
10 changed files with 590 additions and 0 deletions

51
.gitignore vendored Normal file
View File

@ -0,0 +1,51 @@
#
.idea
run
.gradle/
build/
# Eclipse stuff
.classpath
.project
.settings/
# VSCode stuff
.vscode/
# netbeans
nbproject/
nbactions.xml
# we use maven!
build.xml
# maven
target/
dependency-reduced-pom.xml
# vim
.*.sw[a-p]
# various other potential build files
build/
bin/
dist/
manifest.mf
# Mac filesystem dust
.DS_Store/
.DS_Store
# intellij
*.iml
*.ipr
*.iws
.idea/
out/
# Linux temp files
*~
!gradle/wrapper/gradle-wrapper.jar
build.bat

43
pom.xml Normal file
View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>ShutdownInfo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
</properties>
<repositories>
<repository>
<id>velocity</id>
<url>https://repo.velocitypowered.com/snapshots/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>com.velocitypowered</groupId>
<artifactId>velocity-api</artifactId>
<version>1.1.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<version>4.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,75 @@
package com.alttd.shutdowninfo;
import com.alttd.shutdowninfo.commands.Reload;
import com.alttd.shutdowninfo.commands.ShutDown;
import com.alttd.shutdowninfo.config.Config;
import com.alttd.shutdowninfo.listeners.PingListener;
import com.alttd.shutdowninfo.listeners.ProxyPlayerListener;
import com.alttd.shutdowninfo.util.ALogger;
import com.google.inject.Inject;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import java.io.File;
import java.nio.file.Path;
import java.util.logging.Logger;
@Plugin(id = "shutdowninfo", name = "ShutdownInfo", version = "1.0.0",
description = "A plugin to show shutdown information.",
authors = {"teri"}
)
public class ShutdownInfo {
private static ShutdownInfo plugin;
private final ProxyServer server;
private final Logger logger;
private final Path dataDirectory;
@Inject
public ShutdownInfo(ProxyServer proxyServer, Logger proxyLogger, @DataDirectory Path proxydataDirectory)
{
plugin = this;
server = proxyServer;
logger = proxyLogger;
dataDirectory = proxydataDirectory;
}
@Subscribe
public void onProxyInitialization(ProxyInitializeEvent event) {
ALogger.init(logger);
ReloadConfig();
server.getEventManager().register(this, new ProxyPlayerListener());
server.getEventManager().register(this, new PingListener());
loadCommands();
}
public void ReloadConfig() {
Config.init();
ALogger.info("Reloaded ShutdownInfo config.");
}
public void loadCommands() {// all (proxy)commands go here
new Reload(server);
new ShutDown(server);
}
public File getDataDirectory() {
return dataDirectory.toFile();
}
public static ShutdownInfo getPlugin() {
return plugin;
}
public Logger getLogger() {
return logger;
}
public ProxyServer getProxy() {
return server;
}
}

View File

@ -0,0 +1,31 @@
package com.alttd.shutdowninfo.commands;
import com.alttd.shutdowninfo.ShutdownInfo;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.velocitypowered.api.command.BrigadierCommand;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.ProxyServer;
public class Reload {
public Reload(ProxyServer proxyServer) {
LiteralCommandNode<CommandSource> command = LiteralArgumentBuilder
.<CommandSource>literal("shutdowninforeload")
.requires(ctx -> ctx.hasPermission("command.proxy.shutdowninforeload"))
.executes(context -> {
ShutdownInfo.getPlugin().ReloadConfig();
return 1;
})
.build();
BrigadierCommand brigadierCommand = new BrigadierCommand(command);
CommandMeta.Builder metaBuilder = proxyServer.getCommandManager().metaBuilder(brigadierCommand);
CommandMeta meta = metaBuilder.build();
proxyServer.getCommandManager().register(meta, brigadierCommand);
}
}

View File

@ -0,0 +1,59 @@
package com.alttd.shutdowninfo.commands;
import com.alttd.shutdowninfo.ShutdownInfo;
import com.alttd.shutdowninfo.config.Config;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.velocitypowered.api.command.BrigadierCommand;
import com.velocitypowered.api.command.CommandMeta;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.proxy.ProxyServer;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
public class ShutDown {
public ShutDown(ProxyServer proxyServer) {
Component ShutDownStart = MiniMessage.get().parse("<red>You have started the shutdown.</red>");
Component ShutDownEnd = MiniMessage.get().parse("<green>You have ended the shutdown.</green>");
LiteralCommandNode<CommandSource> commandStart = LiteralArgumentBuilder
.<CommandSource>literal("shutdownstart")
.requires(ctx -> ctx.hasPermission("command.proxy.shutdown"))
.executes(context -> {
Config.setWhitelist(true);
context.getSource().sendMessage(ShutDownStart);
Component message = MiniMessage.get().parse(Config.KICK_MESSAGE);
ShutdownInfo.getPlugin().getProxy().getAllPlayers().stream()
.filter(player -> !player.hasPermission("shutdown.bypass"))
.forEach(player -> player.disconnect(message));
return 1;
})
.build();
LiteralCommandNode<CommandSource> commandEnd = LiteralArgumentBuilder
.<CommandSource>literal("shutdownend")
.requires(ctx -> ctx.hasPermission("command.proxy.shutdown"))
.executes(context -> {
Config.setWhitelist(false);
context.getSource().sendMessage(ShutDownEnd);
return 1;
})
.build();
BrigadierCommand brigadierCommandStart = new BrigadierCommand(commandStart);
BrigadierCommand brigadierCommandEnd = new BrigadierCommand(commandEnd);
CommandMeta.Builder metaBuilderStart = proxyServer.getCommandManager().metaBuilder(brigadierCommandStart);
CommandMeta.Builder metaBuilderEnd = proxyServer.getCommandManager().metaBuilder(brigadierCommandEnd);
CommandMeta metaStart = metaBuilderStart.build();
CommandMeta metaEnd = metaBuilderEnd.build();
proxyServer.getCommandManager().register(metaStart, brigadierCommandStart);
proxyServer.getCommandManager().register(metaEnd, brigadierCommandEnd);
}
}

View File

@ -0,0 +1,182 @@
package com.alttd.shutdowninfo.config;
import com.google.common.base.Throwables;
import com.google.common.reflect.TypeToken;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.ConfigurationOptions;
import ninja.leaping.configurate.objectmapping.ObjectMappingException;
import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
import org.yaml.snakeyaml.DumperOptions;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
public final class Config {
private static final Pattern PATH_PATTERN = Pattern.compile("\\.");
private static final String HEADER = "";
private static File CONFIG_FILE;
public static ConfigurationNode config;
public static YAMLConfigurationLoader configLoader;
static int version;
static boolean verbose;
public static File CONFIGPATH;
public static void init() { // todo setup share for the config
CONFIGPATH = new File(System.getProperty("user.home") + File.separator + "share" + File.separator + "configs" + File.separator + "ShutdownInfo");
CONFIG_FILE = new File(CONFIGPATH, "config.yml");
configLoader = YAMLConfigurationLoader.builder()
.setFile(CONFIG_FILE)
.setFlowStyle(DumperOptions.FlowStyle.BLOCK)
.build();
if (!CONFIG_FILE.getParentFile().exists()) {
if (!CONFIG_FILE.getParentFile().mkdirs()) {
return;
}
}
if (!CONFIG_FILE.exists()) {
try {
if (!CONFIG_FILE.createNewFile()) {
return;
}
} catch (IOException error) {
error.printStackTrace();
}
}
try {
config = configLoader.load(ConfigurationOptions.defaults().setHeader(HEADER));
} catch (IOException e) {
e.printStackTrace();
}
verbose = getBoolean("verbose", true);
version = getInt("config-version", 1);
readConfig(Config.class, null);
try {
configLoader.save(config);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void readConfig(Class<?> clazz, Object instance) {
for (Method method : clazz.getDeclaredMethods()) {
if (Modifier.isPrivate(method.getModifiers())) {
if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) {
try {
method.setAccessible(true);
method.invoke(instance);
} catch (InvocationTargetException | IllegalAccessException ex) {
throw Throwables.propagate(ex.getCause());
}
}
}
}
try {
configLoader.save(config);
} catch (IOException ex) {
throw Throwables.propagate(ex.getCause());
}
}
public static void saveConfig() {
try {
configLoader.save(config);
} catch (IOException ex) {
throw Throwables.propagate(ex.getCause());
}
}
private static Object[] splitPath(String key) {
return PATH_PATTERN.split(key);
}
private static void set(String path, Object def) {
if (config.getNode(splitPath(path)).isVirtual())
config.getNode(splitPath(path)).setValue(def);
}
private static void setString(String path, String def) {
try {
if (config.getNode(splitPath(path)).isVirtual())
config.getNode(splitPath(path)).setValue(TypeToken.of(String.class), def);
} catch (ObjectMappingException ex) {
}
}
private static boolean getBoolean(String path, boolean def) {
set(path, def);
return config.getNode(splitPath(path)).getBoolean(def);
}
private static double getDouble(String path, double def) {
set(path, def);
return config.getNode(splitPath(path)).getDouble(def);
}
private static int getInt(String path, int def) {
set(path, def);
return config.getNode(splitPath(path)).getInt(def);
}
private static String getString(String path, String def) {
setString(path, def);
return config.getNode(splitPath(path)).getString(def);
}
private static Long getLong(String path, Long def) {
set(path, def);
return config.getNode(splitPath(path)).getLong(def);
}
private static <T> List<String> getList(String path, T def) {
try {
set(path, def);
return config.getNode(splitPath(path)).getList(TypeToken.of(String.class));
} catch (ObjectMappingException ex) {
}
return new ArrayList<>();
}
private static ConfigurationNode getNode(String path) {
if (config.getNode(splitPath(path)).isVirtual()) {
//new RegexConfig("Dummy");
}
config.getChildrenMap();
return config.getNode(splitPath(path));
}
/** ONLY EDIT ANYTHING BELOW THIS LINE **/
public static String KICK_MESSAGE = "<red>The server has been whitelisted</red>";
public static String WHITELIST_MESSAGE = "<red>This server is currently whitelisted.</red>";
public static String PING_MESSAGE = "<red>This server is currently whitelisted.</red>";
private static void messages() {
KICK_MESSAGE = getString("messages.kick", KICK_MESSAGE);
WHITELIST_MESSAGE = getString("messages.whitelist", WHITELIST_MESSAGE);
PING_MESSAGE = getString("messages.ping", PING_MESSAGE);
}
public static boolean WHITELIST = false;
private static void settings() {
WHITELIST = getBoolean("settings.whitelist", false);
}
public static void setWhitelist(boolean state)
{
config.getNode(splitPath("settings.whitelist")).setValue(state);
saveConfig();
WHITELIST = state;
}
}

View File

@ -0,0 +1,32 @@
package com.alttd.shutdowninfo.events;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.minimessage.Template;
import java.util.Collections;
import java.util.List;
public class WhitelistKickEvent {
private final Player player;
private String message;
List<Template> templates;
public WhitelistKickEvent(Player player, String message, List<Template> templates) {
this.player = player;
this.message = message;
this.templates = templates;
}
public Player getPlayer() {return player;}
public String getMessage() {return message;}
public void appendMessage(String append) {message += append;}
public List<Template> getTemplates()
{
return Collections.unmodifiableList(templates);
}
public void appendTemplates(Template... templates) {this.templates.addAll(List.of(templates));}
}

View File

@ -0,0 +1,33 @@
package com.alttd.shutdowninfo.listeners;
import com.alttd.shutdowninfo.config.Config;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
import com.velocitypowered.api.proxy.server.ServerPing;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
public class PingListener {
MiniMessage miniMessage;
public PingListener() {
miniMessage = MiniMessage.get();
}
@Subscribe
public void onPing(ProxyPingEvent event) {
if (!Config.WHITELIST)
return;
ServerPing.Builder builder = event.getPing().asBuilder();
Component component = miniMessage.parse(Config.PING_MESSAGE);
builder.onlinePlayers(-1);
builder.maximumPlayers(0);
builder.clearSamplePlayers();
builder.description(component);
event.setPing(builder.build());
}
}

View File

@ -0,0 +1,55 @@
package com.alttd.shutdowninfo.listeners;
import com.alttd.shutdowninfo.ShutdownInfo;
import com.alttd.shutdowninfo.config.Config;
import com.alttd.shutdowninfo.events.WhitelistKickEvent;
import com.velocitypowered.api.event.ResultedEvent;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.connection.LoginEvent;
import com.velocitypowered.api.proxy.Player;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.Template;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
public class ProxyPlayerListener {
MiniMessage miniMessage;
public ProxyPlayerListener()
{
miniMessage = MiniMessage.get();
}
@Subscribe
public void playerLogin(LoginEvent event)
{
if (!Config.WHITELIST)
return;
Player player = event.getPlayer();
if (event.getPlayer().hasPermission("shutdown.bypass"))
return;
List<Template> templates = new ArrayList<>(List.of(
Template.of("player", player.getUsername())
));
CompletableFuture<WhitelistKickEvent> whitelistKickEvent = ShutdownInfo.getPlugin().getProxy().getEventManager()
.fire(new WhitelistKickEvent(player, Config.WHITELIST_MESSAGE, templates));
try {
WhitelistKickEvent result = whitelistKickEvent.get();
Component component = miniMessage.parse(result.getMessage(), result.getTemplates());
event.setResult(ResultedEvent.ComponentResult.denied(component));
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,29 @@
package com.alttd.shutdowninfo.util;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ALogger {
private static Logger logger;
public static void init(Logger log) {
logger = log;
}
private void log(String message) {
logger.info(message);
}
public static void warn(String message) {
logger.warning(message);
}
public static void info(String message) {
logger.info(message);
}
public static void error(String message) {
logger.log(Level.SEVERE, message);
}
}