init:
This commit is contained in:
commit
3f8830dce7
65 changed files with 4561 additions and 0 deletions
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Compiled class file
|
||||
*.class
|
||||
|
||||
# Log file
|
||||
*.log
|
||||
|
||||
# BlueJ files
|
||||
*.ctxt
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
|
||||
# Virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
|
||||
# IntelliJ files
|
||||
/YourSiteeCore.iml
|
||||
/target/
|
||||
/.idea/
|
||||
/dependency-reduced-pom.xml
|
2
README.md
Normal file
2
README.md
Normal file
|
@ -0,0 +1,2 @@
|
|||
# ysmp-core
|
||||
A core plugin for the YourSitee SMP Minecraft server.
|
83
pom.xml
Normal file
83
pom.xml
Normal file
|
@ -0,0 +1,83 @@
|
|||
<?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>dev.inventex.yoursitee.core</groupId>
|
||||
<artifactId>YourSiteeCore</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
<!-- SpigotMC repository -->
|
||||
<repository>
|
||||
<id>spigot-repo</id>
|
||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!--This adds the Spigot API artifact to the build -->
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.20.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.jetbrains/annotations -->
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>24.0.1</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.28</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.mongodb/mongo-java-driver -->
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongo-java-driver</artifactId>
|
||||
<version>3.12.14</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.inventex.octa</groupId>
|
||||
<artifactId>Octa</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.inventex.discord</groupId>
|
||||
<artifactId>DiscordClient</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
<build>
|
||||
<finalName>ysmp-core</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-shade-plugin</artifactId>
|
||||
<version>3.2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>shade</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
15
src/main/java/ee/yoursit/core/Main.java
Normal file
15
src/main/java/ee/yoursit/core/Main.java
Normal file
|
@ -0,0 +1,15 @@
|
|||
package ee.yoursit.core;
|
||||
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
public class Main extends JavaPlugin {
|
||||
@Override
|
||||
public void onEnable() {
|
||||
YsmpCore.INSTANCE.enable(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
YsmpCore.INSTANCE.disable();
|
||||
}
|
||||
}
|
119
src/main/java/ee/yoursit/core/YsmpCore.java
Normal file
119
src/main/java/ee/yoursit/core/YsmpCore.java
Normal file
|
@ -0,0 +1,119 @@
|
|||
package ee.yoursit.core;
|
||||
|
||||
import dev.inventex.discord.DiscordClient;
|
||||
import dev.inventex.discord.DiscordClientBuilder;
|
||||
import ee.yoursit.core.config.Config;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.DataManager;
|
||||
import ee.yoursit.core.data.PlayerData;
|
||||
import ee.yoursit.core.database.Database;
|
||||
import ee.yoursit.core.database.service.*;
|
||||
import ee.yoursit.core.module.*;
|
||||
import lombok.Getter;
|
||||
import net.dv8tion.jda.api.requests.GatewayIntent;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
@Getter
|
||||
public enum YsmpCore {
|
||||
INSTANCE;
|
||||
|
||||
private JavaPlugin plugin;
|
||||
|
||||
private Config config, messages;
|
||||
private DataManager dataManager;
|
||||
private Database database;
|
||||
|
||||
private Location spawnLoc, verifyLoc;
|
||||
|
||||
private UserService userService;
|
||||
private GroupService groupService;
|
||||
private InviteService inviteService;
|
||||
private BanService banService;
|
||||
private VerificationService verificationService;
|
||||
|
||||
private CommandRegistry bukkitCommands, discordCommands;
|
||||
|
||||
private DiscordClient client;
|
||||
|
||||
public void enable(JavaPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
loadConfig();
|
||||
loadDatabase();
|
||||
|
||||
createDiscordClient();
|
||||
|
||||
loadCommands();
|
||||
|
||||
Bukkit
|
||||
.getPluginManager()
|
||||
.registerEvents(new BukkitListener(), plugin);
|
||||
}
|
||||
|
||||
private void loadConfig() {
|
||||
plugin.getDataFolder().mkdir();
|
||||
|
||||
config = new Config("config");
|
||||
messages = new Config("messages");
|
||||
|
||||
config.load();
|
||||
messages.load();
|
||||
|
||||
Messages.init(messages);
|
||||
|
||||
Bukkit
|
||||
.getScheduler()
|
||||
.runTask(plugin, () -> {
|
||||
spawnLoc = config.getLocation("spawn");
|
||||
verifyLoc = config.getLocation("verify");
|
||||
});
|
||||
}
|
||||
|
||||
private void loadDatabase() {
|
||||
dataManager = new DataManager();
|
||||
database = new Database("127.0.0.1", 27017);
|
||||
database.connect();
|
||||
|
||||
userService = new UserService();
|
||||
groupService = new GroupService();
|
||||
groupService.loadGroups();
|
||||
inviteService = new InviteService();
|
||||
banService = new BanService();
|
||||
verificationService = new VerificationService();
|
||||
}
|
||||
|
||||
private void loadCommands() {
|
||||
bukkitCommands = new BukkitCommandRegistry();
|
||||
bukkitCommands.load();
|
||||
|
||||
discordCommands = new DiscordCommandRegistry();
|
||||
}
|
||||
|
||||
private void createDiscordClient() {
|
||||
try {
|
||||
String token = config.getString("bot-token");
|
||||
client = new DiscordClientBuilder(token)
|
||||
.useMembers()
|
||||
.useRoles()
|
||||
.enableIntents(GatewayIntent.MESSAGE_CONTENT)
|
||||
.build();
|
||||
client.registerEvents(new DiscordListener());
|
||||
} catch (LoginException e) {
|
||||
System.err.println("Unable to create discord client");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
database.disconnect();
|
||||
|
||||
bukkitCommands.unload();
|
||||
discordCommands.unload();
|
||||
|
||||
client.getJda().shutdown();
|
||||
}
|
||||
}
|
145
src/main/java/ee/yoursit/core/command/bukkit/api/Argument.java
Normal file
145
src/main/java/ee/yoursit/core/command/bukkit/api/Argument.java
Normal file
|
@ -0,0 +1,145 @@
|
|||
package ee.yoursit.core.command.bukkit.api;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Getter
|
||||
public class Argument {
|
||||
@NotNull
|
||||
private final String name;
|
||||
|
||||
@NotNull
|
||||
private final String[] aliases;
|
||||
|
||||
private final boolean consoleAllowed;
|
||||
|
||||
@NotNull
|
||||
private final List<Argument> subArguments = new ArrayList<>();
|
||||
|
||||
public Argument() {
|
||||
CommandInfo info = getClass().getAnnotation(CommandInfo.class);
|
||||
if (info == null)
|
||||
throw new IllegalStateException(getClass().getName() + " is not annotated with "
|
||||
+ CommandInfo.class);
|
||||
name = info.name();
|
||||
aliases = info.aliases();
|
||||
consoleAllowed = info.consoleAllowed();
|
||||
create();
|
||||
}
|
||||
|
||||
public void create() {
|
||||
}
|
||||
|
||||
public void onCommand(@NotNull CommandContext context) throws Exception {
|
||||
}
|
||||
|
||||
public Completion onTabComplete(@NotNull CommandContext context) throws Exception {
|
||||
return Completion.EMPTY;
|
||||
}
|
||||
|
||||
public void onCommandError(@NotNull CommandContext context, @NotNull Throwable error) {
|
||||
throw new CommandException("Error whilst handling command execution", error);
|
||||
}
|
||||
|
||||
public Completion onTabCompleteError(@NotNull CommandContext context, @NotNull Throwable error) {
|
||||
throw new CommandException("Error whilst handling command tab completion", error);
|
||||
}
|
||||
|
||||
private void executeCommand(@NotNull CommandContext context) {
|
||||
try {
|
||||
onCommand(context);
|
||||
} catch (Exception e) {
|
||||
onCommandError(context, e);
|
||||
}
|
||||
}
|
||||
|
||||
private Completion executeTabCompletion(@NotNull CommandContext context) {
|
||||
try {
|
||||
return onTabComplete(context);
|
||||
} catch (Exception e) {
|
||||
return onTabCompleteError(context, e);
|
||||
}
|
||||
}
|
||||
|
||||
public final void addArgument(@NotNull Argument argument) {
|
||||
subArguments.add(argument);
|
||||
}
|
||||
|
||||
public final void execute(@NotNull CommandSender sender, @NotNull String[] args) {
|
||||
if (!(sender instanceof Player) && !consoleAllowed) {
|
||||
sender.sendMessage(ChatColor.RED + "Console is not allowed to execute this command.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.length == 0 || subArguments.isEmpty()) {
|
||||
executeCommand(new CommandContext(sender, args));
|
||||
return;
|
||||
}
|
||||
|
||||
String name = args[0];
|
||||
for (Argument argument : subArguments) {
|
||||
if (!argument.test(name))
|
||||
continue;
|
||||
|
||||
String[] subArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
argument.execute(sender, subArgs);
|
||||
return;
|
||||
}
|
||||
|
||||
executeCommand(new CommandContext(sender, args));
|
||||
}
|
||||
|
||||
public final Completion complete(@NotNull CommandSender sender, @NotNull String[] args) {
|
||||
if (subArguments.isEmpty())
|
||||
return executeTabCompletion(new CommandContext(sender, args));
|
||||
|
||||
if (args.length == 0) {
|
||||
Stream<String> stream = subArguments
|
||||
.stream()
|
||||
.map(Argument::getName);
|
||||
return Completion.of(stream);
|
||||
}
|
||||
|
||||
else if (args.length == 1) {
|
||||
String prefix = args[0].toLowerCase();
|
||||
Stream<String> stream = subArguments
|
||||
.stream()
|
||||
.map(Argument::getName)
|
||||
.filter(name -> name.startsWith(prefix));
|
||||
return Completion.of(stream);
|
||||
}
|
||||
|
||||
else {
|
||||
String name = args[0].toLowerCase();
|
||||
for (Argument argument : subArguments) {
|
||||
if (!argument.test(name))
|
||||
continue;
|
||||
|
||||
String[] subArgs = Arrays.copyOfRange(args, 1, args.length);
|
||||
return argument.complete(sender, subArgs);
|
||||
}
|
||||
}
|
||||
|
||||
return executeTabCompletion(new CommandContext(sender, args));
|
||||
}
|
||||
|
||||
public final boolean test(@NotNull String name) {
|
||||
if (name.equals(this.name))
|
||||
return true;
|
||||
|
||||
for (String alias : aliases) {
|
||||
if (name.equals(alias))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package ee.yoursit.core.command.bukkit.api;
|
||||
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Command extends Argument {
|
||||
public final void register() {
|
||||
PluginCommand command = YsmpCore.INSTANCE.getPlugin().getCommand(getName());
|
||||
if (command == null)
|
||||
throw new IllegalStateException("Command '" + getName() + "' is not registered in the plugin.yml");
|
||||
|
||||
command.setExecutor((sender, cmd, label, args) -> {
|
||||
execute(sender, args);
|
||||
return true;
|
||||
});
|
||||
command.setTabCompleter((sender, cmd, label, args) -> complete(sender, args).getData());
|
||||
command.setAliases(Arrays.asList(getAliases()));
|
||||
}
|
||||
|
||||
public final void unregister() {
|
||||
PluginCommand command = YsmpCore.INSTANCE.getPlugin().getCommand(getName());
|
||||
if (command == null)
|
||||
throw new IllegalStateException("Command '" + getName() + "' is not registered in the plugin.yml");
|
||||
|
||||
command.setExecutor(null);
|
||||
command.setTabCompleter(null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
package ee.yoursit.core.command.bukkit.api;
|
||||
|
||||
import dev.inventex.octa.data.convertible.Convertible;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class CommandContext {
|
||||
@NotNull
|
||||
@Getter
|
||||
private final CommandSender sender;
|
||||
|
||||
@NotNull
|
||||
private final String[] args;
|
||||
|
||||
public boolean isPlayer() {
|
||||
return sender instanceof Player;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Player getPlayer() {
|
||||
if (!isPlayer())
|
||||
throw new IllegalStateException("CommandSender is not a player");
|
||||
return (Player) sender;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return args.length == 0;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return args.length;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String[] getData() {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getStringRaw(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? args[index]
|
||||
: null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Convertible<String, String> getString(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.completed(args[index])
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Convertible<String, Integer> getInt(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], Integer::parseInt)
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Convertible<String, Float> getFloat(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], Float::parseFloat)
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Convertible<String, Double> getDouble(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], Double::parseDouble)
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Convertible<String, Boolean> getBoolean(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], value -> switch (value.toLowerCase()) {
|
||||
case "enable", "allow", "true", "yes", "on", "y" -> true;
|
||||
default -> false;
|
||||
})
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Convertible<String, Player> getPlayer(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], Bukkit::getPlayer)
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Convertible<String, Player> getPlayerExact(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], Bukkit::getPlayerExact)
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Convertible<String, World> getWorld(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], Bukkit::getWorld)
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
public Convertible<String, Material> getMaterial(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], s -> Material.getMaterial(s.toUpperCase()))
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
public Convertible<String, PotionEffectType> getPotionEffectByName(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], s -> PotionEffectType.getByName(s.toUpperCase()))
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
public Convertible<String, PotionEffectType> getPotionEffectById(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], s -> PotionEffectType.getById(Integer.parseInt(s)))
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
public Convertible<String, PotionEffectType> getPotionEffect(int index) {
|
||||
return index >= 0 && index < args.length
|
||||
? Convertible.of(args[index], s -> {
|
||||
PotionEffectType type = PotionEffectType.getByName(s.toUpperCase());
|
||||
if (type != null)
|
||||
return type;
|
||||
|
||||
return PotionEffectType.getById(Integer.parseInt(s));
|
||||
})
|
||||
: Convertible.empty();
|
||||
}
|
||||
|
||||
public void reply(String message) {
|
||||
sender.sendMessage(message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package ee.yoursit.core.command.bukkit.api;
|
||||
|
||||
public class CommandException extends RuntimeException {
|
||||
public CommandException() {
|
||||
}
|
||||
|
||||
public CommandException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public CommandException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public CommandException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public CommandException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
|
||||
super(message, cause, enableSuppression, writableStackTrace);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package ee.yoursit.core.command.bukkit.api;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
public @interface CommandInfo {
|
||||
String name();
|
||||
|
||||
String[] aliases() default {};
|
||||
|
||||
boolean consoleAllowed() default true;
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package ee.yoursit.core.command.bukkit.api;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@AllArgsConstructor
|
||||
public class Completion {
|
||||
public final static Completion EMPTY = of(Collections.emptyList());
|
||||
|
||||
public final static Completion PLAYERS = of((List<String>) null);
|
||||
|
||||
@Nullable
|
||||
@Getter
|
||||
private final List<String> data;
|
||||
|
||||
public Completion push(@NotNull String element) {
|
||||
assert data != null : "Cannot push element to PLAYER_LIST completion";
|
||||
data.add(element);
|
||||
return this;
|
||||
}
|
||||
|
||||
public static Completion of(List<String> data) {
|
||||
return new Completion(data != null ? new ArrayList<>(data) : null);
|
||||
}
|
||||
|
||||
public static Completion of(String... data) {
|
||||
return new Completion(new ArrayList<>(Arrays.asList(data)));
|
||||
}
|
||||
|
||||
public static Completion of(Stream<String> data) {
|
||||
return new Completion(data != null ? data.collect(Collectors.toList()) : null);
|
||||
}
|
||||
|
||||
public static Completion empty() {
|
||||
return new Completion(new ArrayList<>());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,322 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.admin;
|
||||
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
import dev.inventex.octa.data.convertible.Convertible;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.command.bukkit.api.Completion;
|
||||
import ee.yoursit.core.command.bukkit.impl.admin.group.CreateArgument;
|
||||
import ee.yoursit.core.command.bukkit.impl.admin.group.DeleteArgument;
|
||||
import ee.yoursit.core.command.bukkit.impl.admin.group.ListArgument;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.database.entity.impl.Group;
|
||||
import ee.yoursit.core.database.entity.impl.User;
|
||||
import ee.yoursit.core.util.Message;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CommandInfo(name = "group")
|
||||
public class GroupCommand extends Command {
|
||||
@Override
|
||||
public void create() {
|
||||
addArgument(new CreateArgument());
|
||||
addArgument(new DeleteArgument());
|
||||
addArgument(new ListArgument());
|
||||
}
|
||||
|
||||
// TODO reword command system, so I don't need to do these manually >:(
|
||||
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) throws Exception {
|
||||
if (!(context.getSender().hasPermission("ysmp.admin"))) {
|
||||
context.reply(Messages.NO_PERMISSION);
|
||||
return;
|
||||
}
|
||||
|
||||
Convertible<String, String> groupArg = context.getString(0);
|
||||
if (groupArg.isEmpty()) {
|
||||
context.reply(Messages.GROUP_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String name = groupArg.get();
|
||||
YsmpCore.INSTANCE
|
||||
.getGroupService()
|
||||
.getGroup(name)
|
||||
.tryThen(group -> handleGroup(context, group))
|
||||
.except(err ->
|
||||
context.reply(Messages.GROUP_NOT_EXISTS
|
||||
.replace("{group}", name)));
|
||||
}
|
||||
|
||||
private void handleGroup(CommandContext context, Group group) throws Exception {
|
||||
Convertible<String, String> commandArg = context.getString(1);
|
||||
if (commandArg.isEmpty()) {
|
||||
context.reply(Messages.GROUP_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (commandArg.get()) {
|
||||
case "meta" -> handleGroupMeta(context, group);
|
||||
case "permission" -> handleGroupPermission(context, group);
|
||||
case "grant" -> handleGroupGrant(context, group);
|
||||
default -> context.reply(Messages.GROUP_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleGroupMeta(CommandContext context, Group group) throws Exception {
|
||||
Convertible<String, String> metaTypeArg = context.getString(2);
|
||||
if (metaTypeArg.isEmpty()) {
|
||||
context.reply(Messages.GROUP_META_PREFIX_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (metaTypeArg.get()) {
|
||||
case "prefix" -> handleMetaPrefix(context, group);
|
||||
case "suffix" -> handleMetaSuffix(context, group);
|
||||
case "tabprefix" -> handleMetaTabPrefix(context, group);
|
||||
case "tabsuffix" -> handleMetaTabSuffix(context, group);
|
||||
case "info" -> handleMetaInfo(context, group);
|
||||
default -> context.reply(Messages.GROUP_META_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMetaPrefix(CommandContext context, Group group) throws Exception {
|
||||
if (context.getString(3).isEmpty()) {
|
||||
context.reply(Messages.GROUP_META_PREFIX_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String prefix = Arrays
|
||||
.stream(context.getData())
|
||||
.skip(3)
|
||||
.collect(Collectors.joining(" "));
|
||||
|
||||
group.getPrefix().set(prefix);
|
||||
prefix = Message.translate(prefix);
|
||||
|
||||
context.reply(Messages.GROUP_META_PREFIX_SET
|
||||
.replace("{group}", group.getName().get())
|
||||
.replace("{prefix}", prefix));
|
||||
}
|
||||
|
||||
private void handleMetaSuffix(CommandContext context, Group group) throws Exception {
|
||||
if (context.getString(3).isEmpty()) {
|
||||
context.reply(Messages.GROUP_META_SUFFIX_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String suffix = Arrays
|
||||
.stream(context.getData())
|
||||
.skip(3)
|
||||
.collect(Collectors.joining(" "));
|
||||
|
||||
group.getSuffix().set(suffix);
|
||||
suffix = Message.translate(suffix);
|
||||
|
||||
context.reply(Messages.GROUP_META_SUFFIX_SET
|
||||
.replace("{group}", group.getName().get())
|
||||
.replace("{suffix}", suffix));
|
||||
}
|
||||
|
||||
private void handleMetaTabPrefix(CommandContext context, Group group) throws Exception {
|
||||
if (context.getString(3).isEmpty()) {
|
||||
context.reply(Messages.GROUP_META_TAB_PREFIX_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String tabPrefix = Arrays
|
||||
.stream(context.getData())
|
||||
.skip(3)
|
||||
.collect(Collectors.joining(" "));
|
||||
|
||||
group.getTabPrefix().set(tabPrefix);
|
||||
tabPrefix = Message.translate(tabPrefix);
|
||||
|
||||
context.reply(Messages.GROUP_META_TAB_PREFIX_SET
|
||||
.replace("{group}", group.getName().get())
|
||||
.replace("{tabprefix}", tabPrefix));
|
||||
}
|
||||
|
||||
private void handleMetaTabSuffix(CommandContext context, Group group) throws Exception {
|
||||
if (context.getString(3).isEmpty()) {
|
||||
context.reply(Messages.GROUP_META_TAB_SUFFIX_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String tabSuffix = Arrays
|
||||
.stream(context.getData())
|
||||
.skip(3)
|
||||
.collect(Collectors.joining(" "));
|
||||
|
||||
group.getTabSuffix().set(tabSuffix);
|
||||
tabSuffix = Message.translate(tabSuffix);
|
||||
|
||||
context.reply(Messages.GROUP_META_TAB_SUFFIX_SET
|
||||
.replace("{group}", group.getName().get())
|
||||
.replace("{tabsuffix}", tabSuffix));
|
||||
}
|
||||
|
||||
private void handleMetaInfo(CommandContext context, Group group) {
|
||||
String name = group.getName().get();
|
||||
String prefix = group.getPrefix().get();
|
||||
String suffix = group.getSuffix().get();
|
||||
String tabPrefix = group.getTabPrefix().get();
|
||||
String tabSuffix = group.getTabSuffix().get();
|
||||
|
||||
String message = Messages.GROUP_META_INFO
|
||||
.replace("{group}", Message.translate(name))
|
||||
.replace("{prefix}", Message.translate(prefix != null ? prefix : "not set"))
|
||||
.replace("{suffix}", Message.translate(suffix != null ? suffix : "not set"))
|
||||
.replace("{tabprefix}", Message.translate(tabPrefix != null ? tabPrefix : "not set"))
|
||||
.replace("{tabsuffix}", Message.translate(tabSuffix != null ? tabSuffix : "not set"));
|
||||
|
||||
context.reply(message);
|
||||
}
|
||||
|
||||
private void handleGroupPermission(CommandContext context, Group group) throws Exception {
|
||||
Convertible<String, String> actionArg = context.getString(4);
|
||||
if (actionArg.isEmpty()) {
|
||||
context.reply(Messages.GROUP_PERMISSION_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (actionArg.get()) {
|
||||
case "set" -> handleGroupPermissionSet(context, group);
|
||||
case "unset" -> handleGroupPermissionUnset(context, group);
|
||||
default -> context.reply(Messages.GROUP_PERMISSION_USAGE);
|
||||
}
|
||||
}
|
||||
|
||||
private void handleGroupPermissionSet(CommandContext context, Group group) throws Exception {
|
||||
Convertible<String, String> permissionArg = context.getString(5);
|
||||
if (permissionArg.isEmpty()) {
|
||||
context.reply(Messages.GROUP_PERMISSION_SET_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
Convertible<String, Boolean> stateArg = context.getBoolean(6);
|
||||
if (stateArg.isEmpty()) {
|
||||
context.reply(Messages.GROUP_PERMISSION_SET_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String permission = permissionArg.get();
|
||||
Boolean state = stateArg.get();
|
||||
|
||||
group.getPermissions().set(permission, state);
|
||||
|
||||
context.reply(Messages.GROUP_PERMISSION_SET_UPDATED
|
||||
.replace("{group}", group.getName().get())
|
||||
.replace("{permission}", permission)
|
||||
.replace("{state}", String.valueOf(state)));
|
||||
}
|
||||
|
||||
private void handleGroupPermissionUnset(CommandContext context, Group group) throws Exception {
|
||||
Convertible<String, String> permissionArg = context.getString(5);
|
||||
if (permissionArg.isEmpty()) {
|
||||
context.reply(Messages.GROUP_PERMISSION_UNSET_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String permission = permissionArg.get();
|
||||
group.getPermissions().unset(permission);
|
||||
|
||||
context.reply(Messages.GROUP_PERMISSION_UNSET_UPDATED
|
||||
.replace("{group}", group.getName().get())
|
||||
.replace("{permission}", permission));
|
||||
}
|
||||
|
||||
private void handleGroupGrant(CommandContext context, Group group) throws Exception {
|
||||
Convertible<String, String> playerArg = context.getString(2);
|
||||
if (playerArg.isEmpty()) {
|
||||
context.reply(Messages.GROUP_GRANT_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String player = playerArg.get();
|
||||
Future<User> future;
|
||||
|
||||
Player onlinePlayer = Bukkit.getPlayerExact(player);
|
||||
if (onlinePlayer != null) {
|
||||
future = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(onlinePlayer)
|
||||
.getUser();
|
||||
} else {
|
||||
future = YsmpCore.INSTANCE
|
||||
.getUserService()
|
||||
.getUser(player);
|
||||
}
|
||||
|
||||
future
|
||||
.then(user -> {
|
||||
user.getGroup().set(group.getName().get());
|
||||
context.reply(Messages.GROUP_GRANT_GRANTED
|
||||
.replace("{group}", group.getName().get())
|
||||
.replace("{player}", player));
|
||||
})
|
||||
.except(err -> context.reply(Messages.NO_SUCH_USER
|
||||
.replace("{name}", player)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Completion onTabComplete(@NotNull CommandContext context) throws Exception {
|
||||
if (!(context.getSender().hasPermission("ysmp.admin")))
|
||||
return Completion.EMPTY;
|
||||
|
||||
// this command system is a piece of shit, so I have to do it manually
|
||||
if (context.size() == 0) {
|
||||
Completion completion = Completion.of("create", "delete");
|
||||
List<String> groups = YsmpCore.INSTANCE
|
||||
.getGroupService()
|
||||
.getGroupCache()
|
||||
.values()
|
||||
.stream()
|
||||
.map(group -> group.getName().get())
|
||||
.toList();
|
||||
completion.getData().addAll(groups);
|
||||
return completion;
|
||||
}
|
||||
|
||||
else if (context.size() == 1) {
|
||||
String arg = context.getString(0).get();
|
||||
if (arg.equals("create") || arg.equals("delete"))
|
||||
return Completion.EMPTY;
|
||||
return Completion.of("meta", "permission", "grant");
|
||||
}
|
||||
|
||||
else if (context.size() == 2) {
|
||||
String action = context.getString(1).get();
|
||||
if (action.equals(""))
|
||||
return Completion.of("meta", "permission", "grant");
|
||||
|
||||
if (action.startsWith("m"))
|
||||
return Completion.of("meta");
|
||||
else if (action.startsWith("p"))
|
||||
return Completion.of("permission");
|
||||
else if (action.startsWith("g"))
|
||||
return Completion.of("grant");
|
||||
}
|
||||
|
||||
else if (context.size() == 3) {
|
||||
String action = context.getString(1).get();
|
||||
|
||||
return switch (action) {
|
||||
case "meta" -> Completion.of("info", "prefix", "suffix", "tabprefix", "tabsuffix");
|
||||
case "permission" -> Completion.of("set", "unset");
|
||||
case "grant" -> Completion.PLAYERS;
|
||||
default -> Completion.EMPTY;
|
||||
};
|
||||
}
|
||||
|
||||
return Completion.EMPTY;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.admin.group;
|
||||
|
||||
import dev.inventex.octa.data.convertible.Convertible;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Argument;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.Group;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
@CommandInfo(name = "create")
|
||||
public class CreateArgument extends Argument {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) throws Exception {
|
||||
if (!(context.getSender().hasPermission("ysmp.admin"))) {
|
||||
context.reply(Messages.NO_PERMISSION);
|
||||
return;
|
||||
}
|
||||
|
||||
Convertible<String, String> nameArg = context.getString(0);
|
||||
if (nameArg.isEmpty()) {
|
||||
context.reply(Messages.GROUP_CREATE_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String name = nameArg.get();
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getGroupService()
|
||||
.getGroup(name)
|
||||
.then(group -> context.reply(Messages.GROUP_CREATE_ALREADY_EXISTS
|
||||
.replace("{group}", name)))
|
||||
.tryExcept(err -> createGroup(context, name));
|
||||
}
|
||||
|
||||
private void createGroup(CommandContext context, String name) throws Exception {
|
||||
Group group = EntitySerializer.init(Group.class);
|
||||
|
||||
group.getName().init(name);
|
||||
group.getPermissions().init(new HashMap<>());
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getGroupService()
|
||||
.addGroup(group)
|
||||
.get();
|
||||
|
||||
context.reply(Messages.GROUP_CREATE_CREATED
|
||||
.replace("{group}", name));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.admin.group;
|
||||
|
||||
import dev.inventex.octa.data.convertible.Convertible;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@CommandInfo(name = "delete")
|
||||
public class DeleteArgument extends Command {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) throws Exception {
|
||||
if (!(context.getSender().hasPermission("ysmp.admin"))) {
|
||||
context.reply(Messages.NO_PERMISSION);
|
||||
return;
|
||||
}
|
||||
|
||||
Convertible<String, String> nameArg = context.getString(0);
|
||||
if (nameArg.isEmpty()) {
|
||||
context.reply(Messages.GROUP_CREATE_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
String name = nameArg.get();
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getGroupService()
|
||||
.getGroup(name)
|
||||
.tryThen(group -> {
|
||||
if (group == null) {
|
||||
context.reply(Messages.GROUP_DELETE_NOT_EXISTS
|
||||
.replace("{group}", name));
|
||||
return;
|
||||
}
|
||||
|
||||
deleteGroup(context, name);
|
||||
})
|
||||
.except(System.err::println);
|
||||
}
|
||||
|
||||
private void deleteGroup(CommandContext context, String name) throws Exception {
|
||||
YsmpCore.INSTANCE
|
||||
.getGroupService()
|
||||
.removeGroup(name)
|
||||
.get();
|
||||
|
||||
context.reply(Messages.GROUP_DELETE_DELETED
|
||||
.replace("{group}", name));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.admin.group;
|
||||
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Argument;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.database.entity.impl.Group;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CommandInfo(name = "list")
|
||||
public class ListArgument extends Argument {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) throws Exception {
|
||||
if (!(context.getSender().hasPermission("ysmp.admin"))) {
|
||||
context.reply(Messages.NO_PERMISSION);
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<Group> groups = YsmpCore.INSTANCE
|
||||
.getGroupService()
|
||||
.getGroupCache()
|
||||
.values();
|
||||
|
||||
if (groups.isEmpty()) {
|
||||
context.reply(Messages.GROUP_NO_GROUPS);
|
||||
return;
|
||||
}
|
||||
|
||||
String list = groups
|
||||
.stream()
|
||||
.map(group -> group.getName().get())
|
||||
.collect(Collectors.joining(", "));
|
||||
|
||||
context.reply(Messages.GROUP_LIST
|
||||
.replace("{list}", list));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.home;
|
||||
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.PlayerData;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@CommandInfo(name = "delhome")
|
||||
public class DelHomeCommand extends Command {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) {
|
||||
Player player = context.getPlayer();
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(player);
|
||||
|
||||
data
|
||||
.getUser()
|
||||
.then(user -> {
|
||||
if (user.getHome().get() == null) {
|
||||
context.reply(Messages.HOME_NOT_SET);
|
||||
return;
|
||||
}
|
||||
|
||||
user.getHome().set(null);
|
||||
context.reply(Messages.HOME_DELETED);
|
||||
})
|
||||
.except(e -> context.reply(Messages.INTERNAL_ERROR));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.home;
|
||||
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.command.bukkit.api.Completion;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.PlayerData;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@CommandInfo(name = "home")
|
||||
public class HomeCommand extends Command {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) {
|
||||
Player player = context.getPlayer();
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(player);
|
||||
|
||||
data
|
||||
.getUser()
|
||||
.then(user -> {
|
||||
Location home = user.getHome().get();
|
||||
if (home == null) {
|
||||
context.reply(Messages.HOME_NOT_SET);
|
||||
return;
|
||||
}
|
||||
|
||||
player.teleport(home);
|
||||
context.reply(Messages.HOME_TELEPORTING);
|
||||
})
|
||||
.except(e -> context.reply(Messages.INTERNAL_ERROR));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Completion onTabComplete(@NotNull CommandContext context) {
|
||||
return Completion.EMPTY;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.home;
|
||||
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.command.bukkit.api.Completion;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.PlayerData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@CommandInfo(name = "sethome")
|
||||
public class SetHomeCommand extends Command {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) {
|
||||
Player player = context.getPlayer();
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(player);
|
||||
|
||||
data
|
||||
.getUser()
|
||||
.then(user -> {
|
||||
user.getHome().set(player.getLocation());
|
||||
context.reply(Messages.HOME_UPDATED);
|
||||
})
|
||||
.except(e -> context.reply(Messages.INTERNAL_ERROR));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Completion onTabComplete(@NotNull CommandContext context) {
|
||||
return Completion.EMPTY;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.invite;
|
||||
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.PlayerData;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.User;
|
||||
import ee.yoursit.core.database.entity.impl.Verification;
|
||||
import ee.yoursit.core.util.Constants;
|
||||
import lombok.SneakyThrows;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@CommandInfo(name = "verify")
|
||||
public class VerifyCommand extends Command {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) throws Exception {
|
||||
Player player = context.getPlayer();
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(player);
|
||||
|
||||
if (!data.isVerifying()) {
|
||||
context.reply(Messages.INVITE_ALREADY_VERIFIED);
|
||||
return;
|
||||
}
|
||||
|
||||
String code = context.getString(0).get();
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getVerificationService()
|
||||
.getVerification(code)
|
||||
.then(verification -> verifyUser(player, data, verification))
|
||||
.except(e -> data.kick(Messages.INVITE_INVALID_CODE));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void verifyUser(Player player, PlayerData data, Verification verification) {
|
||||
JDA jda = YsmpCore.INSTANCE
|
||||
.getClient()
|
||||
.getJda();
|
||||
|
||||
Guild guild = jda.getGuildById(Constants.YSMP_SERVER);
|
||||
assert guild != null;
|
||||
|
||||
Member member = guild.getMemberById(verification.getDiscordId().get());
|
||||
if (member == null) {
|
||||
player.sendMessage(Messages.INVITE_NOT_JOINED_GUILD);
|
||||
return;
|
||||
}
|
||||
|
||||
User user = createUser(player, verification);
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getUserService()
|
||||
.addUser(user)
|
||||
.get();
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getVerificationService()
|
||||
.removeVerification(verification)
|
||||
.get();
|
||||
|
||||
data.setVerifying(false);
|
||||
|
||||
Role role = jda.getRoleById(Constants.PLAYER);
|
||||
assert role != null;
|
||||
|
||||
guild
|
||||
.addRoleToMember(member, role)
|
||||
.queue();
|
||||
|
||||
player.sendMessage(Messages.INVITE_VERIFIED);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private User createUser(Player player, Verification verification) {
|
||||
User user = EntitySerializer.init(User.class);
|
||||
|
||||
user.getUsername().init(player.getName());
|
||||
user.getUuid().init(player.getUniqueId());
|
||||
user.getDiscordId().init(verification.getDiscordId().get());
|
||||
|
||||
user.getRegistered().init(System.currentTimeMillis());
|
||||
user.getLastOnline().init(System.currentTimeMillis());
|
||||
user.getPlayTime().init(0L);
|
||||
|
||||
user.getInvite().set(verification.getCode().get());
|
||||
user.getGroup().init("Invited");
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.message;
|
||||
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.command.bukkit.api.Completion;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.DataManager;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CommandInfo(name = "message", aliases = {"msg", "m", "pm", "dm"})
|
||||
public class MessageCommand extends Command {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) throws Exception {
|
||||
if (context.size() < 2) {
|
||||
context.reply(Messages.PRIVATE_MESSAGE_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = context.getPlayer();
|
||||
Player target = context.getPlayer(0).get();
|
||||
|
||||
if (target == null) {
|
||||
context.reply(Messages
|
||||
.PLAYER_NOT_ONLINE
|
||||
.replace("{player}", context.getStringRaw(0)));
|
||||
return;
|
||||
}
|
||||
|
||||
String message = Arrays.stream(context.getData())
|
||||
.skip(1)
|
||||
.collect(Collectors.joining(" "));
|
||||
|
||||
player.sendMessage(Messages.PRIVATE_MESSAGE_SEND
|
||||
.replace("{player}", target.getName())
|
||||
.replace("{message}", message));
|
||||
|
||||
target.sendMessage(Messages.PRIVATE_MESSAGE_RECEIVE
|
||||
.replace("{player}", player.getName())
|
||||
.replace("{message}", message));
|
||||
|
||||
DataManager dataManager = YsmpCore.INSTANCE.getDataManager();
|
||||
dataManager.get(player).setLastMessenger(target.getUniqueId());
|
||||
dataManager.get(target).setLastMessenger(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Completion onTabComplete(@NotNull CommandContext context) {
|
||||
return Completion.PLAYERS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.message;
|
||||
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.command.bukkit.api.Completion;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.PlayerData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@CommandInfo(name = "reply", aliases = {"r", "repl"})
|
||||
public class ReplyCommand extends Command {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) throws Exception {
|
||||
Player player = context.getPlayer();
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(player);
|
||||
|
||||
Player messenger = data.getLastMessenger();
|
||||
if (messenger == null) {
|
||||
context.reply(Messages.PRIVATE_MESSAGE_NO_OPEN_CHANNELS);
|
||||
return;
|
||||
}
|
||||
|
||||
String message = String.join(" ", context.getData());
|
||||
|
||||
player.sendMessage(Messages.PRIVATE_MESSAGE_SEND
|
||||
.replace("{player}", messenger.getName())
|
||||
.replace("{message}", message));
|
||||
|
||||
messenger.sendMessage(Messages.PRIVATE_MESSAGE_RECEIVE
|
||||
.replace("{player}", player.getName())
|
||||
.replace("{message}", message));
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(messenger)
|
||||
.setLastMessenger(player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Completion onTabComplete(@NotNull CommandContext context) throws Exception {
|
||||
return Completion.PLAYERS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.teleport;
|
||||
|
||||
import dev.inventex.octa.data.convertible.Convertible;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.command.bukkit.api.Completion;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.PlayerData;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
@CommandInfo(name = "tpaccept")
|
||||
public class TeleportAccept extends Command {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) throws Exception {
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(context.getPlayer());
|
||||
|
||||
Map<UUID, Long> teleportRequests = data.getTeleportRequests();
|
||||
|
||||
if (teleportRequests.isEmpty()) {
|
||||
context.reply(Messages.TELEPORT_NO_REQUESTS);
|
||||
return;
|
||||
}
|
||||
|
||||
Convertible<String, Player> targetParam = context.getPlayer(0);
|
||||
Player player = context.getPlayer();
|
||||
Player target;
|
||||
|
||||
if (!targetParam.isEmpty())
|
||||
target = targetParam.get();
|
||||
else {
|
||||
UUID next = teleportRequests
|
||||
.keySet()
|
||||
.iterator()
|
||||
.next();
|
||||
target = Bukkit.getPlayer(next);
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
if (targetParam.isEmpty())
|
||||
context.reply(Messages.TELEPORT_NO_REQUESTS);
|
||||
else
|
||||
context.reply(Messages
|
||||
.TELEPORT_NO_REQUEST_FROM
|
||||
.replace("{player}", context.getStringRaw(0)));
|
||||
return;
|
||||
}
|
||||
|
||||
target.teleport(player.getLocation());
|
||||
|
||||
target.sendMessage(Messages
|
||||
.TELEPORT_ACCEPT_SEND
|
||||
.replace("{player}", player.getName()));
|
||||
player.sendMessage(Messages
|
||||
.TELEPORT_ACCEPT_RECEIVE
|
||||
.replace("{player}", target.getName()));
|
||||
|
||||
data.removeTeleportRequest(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Completion onTabComplete(@NotNull CommandContext context) {
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(context.getPlayer());
|
||||
|
||||
return Completion.of(data
|
||||
.getTeleportRequests()
|
||||
.keySet()
|
||||
.stream()
|
||||
.map(Bukkit::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.map(Player::getName));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.teleport;
|
||||
|
||||
import dev.inventex.octa.data.convertible.Convertible;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.command.bukkit.api.Completion;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.PlayerData;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
@CommandInfo(name = "tpdeny", aliases = {"tpdecline"})
|
||||
public class TeleportDeny extends Command {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) throws Exception {
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(context.getPlayer());
|
||||
|
||||
Map<UUID, Long> teleportRequests = data.getTeleportRequests();
|
||||
|
||||
if (teleportRequests.isEmpty()) {
|
||||
context.reply(Messages.TELEPORT_NO_REQUESTS);
|
||||
return;
|
||||
}
|
||||
|
||||
Convertible<String, Player> targetParam = context.getPlayer(0);
|
||||
Player player = context.getPlayer();
|
||||
Player target;
|
||||
|
||||
if (!targetParam.isEmpty())
|
||||
target = targetParam.get();
|
||||
else {
|
||||
UUID next = teleportRequests
|
||||
.keySet()
|
||||
.iterator()
|
||||
.next();
|
||||
target = Bukkit.getPlayer(next);
|
||||
}
|
||||
|
||||
if (target == null) {
|
||||
if (targetParam.isEmpty())
|
||||
context.reply(Messages.TELEPORT_NO_REQUESTS);
|
||||
else
|
||||
context.reply(Messages
|
||||
.TELEPORT_NO_REQUEST_FROM
|
||||
.replace("{player}", context.getStringRaw(0)));
|
||||
return;
|
||||
}
|
||||
|
||||
data.removeTeleportRequest(target);
|
||||
|
||||
target.sendMessage(Messages
|
||||
.TELEPORT_DECLINE_SEND
|
||||
.replace("{player}", player.getName()));
|
||||
player.sendMessage(Messages
|
||||
.TELEPORT_DECLINE_RECEIVE
|
||||
.replace("{player}", target.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Completion onTabComplete(@NotNull CommandContext context) {
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(context.getPlayer());
|
||||
|
||||
return Completion.of(data
|
||||
.getTeleportRequests()
|
||||
.keySet()
|
||||
.stream()
|
||||
.map(Bukkit::getPlayer)
|
||||
.filter(Objects::nonNull)
|
||||
.map(Player::getName));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package ee.yoursit.core.command.bukkit.impl.teleport;
|
||||
|
||||
import dev.inventex.octa.data.convertible.Convertible;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandContext;
|
||||
import ee.yoursit.core.command.bukkit.api.CommandInfo;
|
||||
import ee.yoursit.core.command.bukkit.api.Completion;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.PlayerData;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@CommandInfo(name = "tpa")
|
||||
public class TeleportRequest extends Command {
|
||||
@Override
|
||||
public void onCommand(@NotNull CommandContext context) {
|
||||
Convertible<String, Player> playerArg = context.getPlayer(0);
|
||||
if (playerArg.isEmpty()) {
|
||||
context.reply(Messages.TELEPORT_REQUEST_USAGE);
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = context.getPlayer();
|
||||
Player target = playerArg.getOrDefault(null);
|
||||
|
||||
if (target == null) {
|
||||
context.reply(Messages.PLAYER_NOT_ONLINE);
|
||||
return;
|
||||
}
|
||||
|
||||
PlayerData targetData = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(target);
|
||||
|
||||
if (targetData.getTeleportRequest(player) != null) {
|
||||
context.reply(Messages
|
||||
.TELEPORT_REQUEST_ALREADY
|
||||
.replace("{player}", target.getName()));
|
||||
return;
|
||||
}
|
||||
|
||||
targetData.addTeleportRequest(player);
|
||||
|
||||
context.reply(Messages.TELEPORT_REQUEST_SEND
|
||||
.replace("{player}", target.getName()));
|
||||
target.sendMessage(Messages.TELEPORT_REQUEST_RECEIVE
|
||||
.replace("{player}", target.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Completion onTabComplete(@NotNull CommandContext context) {
|
||||
return Completion.PLAYERS;
|
||||
}
|
||||
}
|
119
src/main/java/ee/yoursit/core/command/discord/BanCommand.java
Normal file
119
src/main/java/ee/yoursit/core/command/discord/BanCommand.java
Normal file
|
@ -0,0 +1,119 @@
|
|||
package ee.yoursit.core.command.discord;
|
||||
|
||||
import dev.inventex.discord.command.slash.CommandContext;
|
||||
import dev.inventex.discord.command.slash.SlashCommand;
|
||||
import dev.inventex.discord.command.slash.SlashCommandInfo;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.Ban;
|
||||
import ee.yoursit.core.database.entity.impl.User;
|
||||
import ee.yoursit.core.util.Constants;
|
||||
import lombok.SneakyThrows;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@SlashCommandInfo(name = "ban", description = "Remove a player from the server.")
|
||||
public class BanCommand extends SlashCommand {
|
||||
@Override
|
||||
protected void initialize() {
|
||||
addOption(
|
||||
OptionType.USER,
|
||||
"target",
|
||||
"Target user to be removed",
|
||||
true, false
|
||||
);
|
||||
addOption(
|
||||
OptionType.STRING,
|
||||
"reason",
|
||||
"The reason for the removal",
|
||||
true, false
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext context) {
|
||||
String reason = context.getString("reason");
|
||||
|
||||
Guild guild = YsmpCore.INSTANCE
|
||||
.getClient()
|
||||
.getJda()
|
||||
.getGuildById(Constants.YSMP_SERVER);
|
||||
assert guild != null : "Unable to fetch YSMP guild";
|
||||
|
||||
Role role = guild.getRoleById(Constants.BANNED);
|
||||
assert role != null : "Unable to fetch Banned role";
|
||||
|
||||
Member member = guild.getMember(context.getUser("target"));
|
||||
assert member != null : "Unable to fetch target member";
|
||||
|
||||
guild
|
||||
.addRoleToMember(member, role)
|
||||
.queue();
|
||||
|
||||
String nickname = member.getNickname();
|
||||
if (nickname == null)
|
||||
return;
|
||||
|
||||
Player player = Bukkit.getPlayer(nickname);
|
||||
if (player != null) {
|
||||
YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(player)
|
||||
.kick(Messages.BANNED_FROM_SERVER);
|
||||
}
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getUserService()
|
||||
.getUser(nickname)
|
||||
.then(user -> {
|
||||
Member self = context.getInteraction().getMember();
|
||||
assert self != null;
|
||||
|
||||
banUser(context, user, self.getNickname(), reason);
|
||||
})
|
||||
.except(Throwable::printStackTrace);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void banUser(CommandContext context, User user, String nickname, String reason) {
|
||||
user.getBanned().set(true);
|
||||
|
||||
User moderator = YsmpCore.INSTANCE
|
||||
.getUserService()
|
||||
.getUser(nickname)
|
||||
.get();
|
||||
|
||||
Ban ban = EntitySerializer.init(Ban.class);
|
||||
ban.getBanId().init(UUID.randomUUID());
|
||||
ban.getModerator().init(moderator.getUuid().get());
|
||||
ban.getTarget().init(user.getUuid().get());
|
||||
ban.getReason().init(reason);
|
||||
ban.getTimestamp().init(System.currentTimeMillis());
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getBanService()
|
||||
.createBan(ban);
|
||||
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("User Banned")
|
||||
.setColor(Constants.TRANSPARENT)
|
||||
.addField("Target", user.getUsername().get(), true)
|
||||
.addField("Moderator", moderator.getUsername().get(), true)
|
||||
.addField("Reason", reason, true)
|
||||
.build();
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.replyEmbeds(embed)
|
||||
.queue();
|
||||
}
|
||||
}
|
138
src/main/java/ee/yoursit/core/command/discord/InviteCommand.java
Normal file
138
src/main/java/ee/yoursit/core/command/discord/InviteCommand.java
Normal file
|
@ -0,0 +1,138 @@
|
|||
package ee.yoursit.core.command.discord;
|
||||
|
||||
import dev.inventex.discord.command.slash.CommandContext;
|
||||
import dev.inventex.discord.command.slash.SlashCommand;
|
||||
import dev.inventex.discord.command.slash.SlashCommandInfo;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.Invite;
|
||||
import ee.yoursit.core.database.entity.impl.User;
|
||||
import ee.yoursit.core.util.Constants;
|
||||
import ee.yoursit.core.util.InviteGenerator;
|
||||
import lombok.SneakyThrows;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@SlashCommandInfo(name = "invite", description = "Create an invite code for the YSMP server")
|
||||
public class InviteCommand extends SlashCommand {
|
||||
private final InviteGenerator generator = new InviteGenerator(5, 4);
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext context) {
|
||||
Member member = context
|
||||
.getInteraction()
|
||||
.getMember();
|
||||
assert member != null;
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getUserService()
|
||||
.getUser(member.getNickname())
|
||||
.then(user -> createInvite(context, user))
|
||||
.except(e -> handleNotUser(context));
|
||||
}
|
||||
|
||||
private void createInvite(CommandContext context, User user) {
|
||||
Guild guild = context
|
||||
.getInteraction()
|
||||
.getGuild();
|
||||
|
||||
Member member = context
|
||||
.getInteraction()
|
||||
.getMember();
|
||||
|
||||
assert member != null;
|
||||
assert guild != null;
|
||||
|
||||
int invites = user.getInvites().size();
|
||||
int maxInvites = getMaxInvites(member, guild);
|
||||
|
||||
if (invites >= maxInvites) {
|
||||
exceededInvites(context);
|
||||
return;
|
||||
}
|
||||
|
||||
Invite invite = newInvite(user);
|
||||
YsmpCore.INSTANCE
|
||||
.getInviteService()
|
||||
.createInvite(invite);
|
||||
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("Invite Created")
|
||||
.setDescription("```" + invite.getCode().get() + "```")
|
||||
.setColor(Color.GREEN)
|
||||
.build();
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.deferReply(true)
|
||||
.addEmbeds(embed)
|
||||
.queue();
|
||||
}
|
||||
|
||||
private int getMaxInvites(Member member, Guild guild) {
|
||||
Role premium = guild.getRoleById(Constants.PREMIUM);
|
||||
Role business = guild.getRoleById(Constants.BUSINESS);
|
||||
|
||||
assert premium != null;
|
||||
assert business != null;
|
||||
|
||||
boolean hasPremiumOrHigher = member
|
||||
.getRoles()
|
||||
.stream()
|
||||
.anyMatch(role -> role.getPosition() >= business.getPosition());
|
||||
|
||||
if (hasPremiumOrHigher)
|
||||
return 2;
|
||||
|
||||
boolean hasBusiness = member
|
||||
.getRoles()
|
||||
.stream()
|
||||
.anyMatch(role -> role.getPosition() == premium.getPosition());
|
||||
|
||||
return hasBusiness ? 1 : 0;
|
||||
}
|
||||
|
||||
private void exceededInvites(CommandContext context) {
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("Error")
|
||||
.setDescription(Messages.INVITE_LIMIT_EXCEEDED)
|
||||
.setColor(Color.RED)
|
||||
.build();
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.replyEmbeds(embed)
|
||||
.queue();
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private Invite newInvite(User user) {
|
||||
Invite invite = EntitySerializer.init(Invite.class);
|
||||
|
||||
invite.getCode().init(generator.generate());
|
||||
invite.getUsed().init(false);
|
||||
invite.getCreator().init(user.getUuid().get().toString());
|
||||
|
||||
return invite;
|
||||
}
|
||||
|
||||
private void handleNotUser(CommandContext context) {
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("Error")
|
||||
.setDescription(Messages.NOT_A_USER)
|
||||
.setColor(Color.RED)
|
||||
.build();
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.deferReply(true)
|
||||
.addEmbeds(embed)
|
||||
.queue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package ee.yoursit.core.command.discord;
|
||||
|
||||
import dev.inventex.discord.command.slash.CommandContext;
|
||||
import dev.inventex.discord.command.slash.SlashCommand;
|
||||
import dev.inventex.discord.command.slash.SlashCommandInfo;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.util.Constants;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SlashCommandInfo(name = "players", description = "List the online players on the server.")
|
||||
public class PlayersCommand extends SlashCommand {
|
||||
@Override
|
||||
public void execute(CommandContext context) {
|
||||
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
|
||||
String players = onlinePlayers
|
||||
.stream()
|
||||
.map(Player::getName)
|
||||
.collect(Collectors.joining(", "));
|
||||
|
||||
if (onlinePlayers.isEmpty())
|
||||
players = Messages.NO_PLAYERS_ONLINE;
|
||||
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("Online Players")
|
||||
.setDescription(players)
|
||||
.setColor(Constants.TRANSPARENT)
|
||||
.build();
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.replyEmbeds(embed)
|
||||
.queue();
|
||||
}
|
||||
}
|
140
src/main/java/ee/yoursit/core/command/discord/SmpCommand.java
Normal file
140
src/main/java/ee/yoursit/core/command/discord/SmpCommand.java
Normal file
|
@ -0,0 +1,140 @@
|
|||
package ee.yoursit.core.command.discord;
|
||||
|
||||
import dev.inventex.discord.command.slash.CommandContext;
|
||||
import dev.inventex.discord.command.slash.SlashCommand;
|
||||
import dev.inventex.discord.command.slash.SlashCommandInfo;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.Invite;
|
||||
import ee.yoursit.core.database.entity.impl.Verification;
|
||||
import ee.yoursit.core.util.Constants;
|
||||
import ee.yoursit.core.util.InviteGenerator;
|
||||
import lombok.SneakyThrows;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@SlashCommandInfo(name = "smp", description = "Invite yourself to the YourSitee SMP server.")
|
||||
public class SmpCommand extends SlashCommand {
|
||||
private final InviteGenerator generator = new InviteGenerator(5, 4);
|
||||
|
||||
@Override
|
||||
protected void initialize() {
|
||||
addOption(OptionType.STRING,
|
||||
"username",
|
||||
"The in-game name of your Minecraft account",
|
||||
true, false
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void execute(CommandContext context) {
|
||||
Member member = context
|
||||
.getInteraction()
|
||||
.getMember();
|
||||
assert member != null;
|
||||
|
||||
Guild guild = YsmpCore.INSTANCE
|
||||
.getClient()
|
||||
.getJda()
|
||||
.getGuildById(Constants.YSMP_SERVER);
|
||||
assert guild != null;
|
||||
|
||||
Member smpMember = guild.getMember(member.getUser());
|
||||
if (smpMember != null
|
||||
&& smpMember
|
||||
.getRoles()
|
||||
.stream()
|
||||
.anyMatch(role -> role.getIdLong() == Constants.PLAYER)
|
||||
) {
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("Error")
|
||||
.setDescription(Messages.ALREADY_USER)
|
||||
.setColor(Color.RED)
|
||||
.build();
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.deferReply(true)
|
||||
.addEmbeds(embed)
|
||||
.queue();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Verification existingVerification = YsmpCore.INSTANCE
|
||||
.getVerificationService()
|
||||
.getVerification(member.getIdLong())
|
||||
.getOrDefault(null);
|
||||
|
||||
if (existingVerification != null) {
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("Error")
|
||||
.setDescription(Messages.INVITE_ALREADY_VERIFYING_SELF)
|
||||
.setColor(Color.RED)
|
||||
.build();
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.deferReply(true)
|
||||
.addEmbeds(embed)
|
||||
.queue();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
String code = generator.generate();
|
||||
|
||||
Invite invite = EntitySerializer.init(Invite.class);
|
||||
invite.getCode().init(code);
|
||||
invite.getCreator().init("Server");
|
||||
invite.getUsed().init(false);
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getInviteService()
|
||||
.createInvite(invite)
|
||||
.then(e -> invite(context, member, code))
|
||||
.except(System.err::println);
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private void invite(CommandContext context, Member member, String code) {
|
||||
String username = context.getString("username");
|
||||
|
||||
Verification verification = EntitySerializer.init(Verification.class);
|
||||
verification.getDiscordId().init(member.getIdLong());
|
||||
verification.getUsername().init(username);
|
||||
verification.getCode().init(code);
|
||||
verification.getCreation().init(System.currentTimeMillis());
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getVerificationService()
|
||||
.addVerification(verification)
|
||||
.get();
|
||||
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("You have been invited")
|
||||
.setDescription(Messages.INVITE_VERIFICATION
|
||||
.replace("{code}", code))
|
||||
.setColor(Constants.TRANSPARENT)
|
||||
.build();
|
||||
|
||||
String discordLink = YsmpCore.INSTANCE
|
||||
.getConfig()
|
||||
.getString("ysmp-invite");
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.deferReply(true)
|
||||
.addEmbeds(embed)
|
||||
.addContent(discordLink)
|
||||
.queue();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package ee.yoursit.core.command.discord;
|
||||
|
||||
import dev.inventex.discord.command.slash.CommandContext;
|
||||
import dev.inventex.discord.command.slash.SlashCommand;
|
||||
import dev.inventex.discord.command.slash.SlashCommandInfo;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.database.entity.impl.User;
|
||||
import ee.yoursit.core.util.Constants;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.entities.Role;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
|
||||
@SlashCommandInfo(name = "unban", description = "Revoke the ban of a player.")
|
||||
public class UnbanCommand extends SlashCommand {
|
||||
@Override
|
||||
protected void initialize() {
|
||||
addOption(
|
||||
OptionType.USER,
|
||||
"target",
|
||||
"Target user to be removed",
|
||||
true, false
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext context) {
|
||||
Guild guild = YsmpCore.INSTANCE
|
||||
.getClient()
|
||||
.getJda()
|
||||
.getGuildById(Constants.YSMP_SERVER);
|
||||
assert guild != null : "Unable to fetch YSMP guild";
|
||||
|
||||
Role role = guild.getRoleById(Constants.BANNED);
|
||||
assert role != null : "Unable to fetch Banned role";
|
||||
|
||||
Member member = guild.getMember(context.getUser("target"));
|
||||
assert member != null : "Unable to fetch target member";
|
||||
|
||||
guild
|
||||
.removeRoleFromMember(member, role)
|
||||
.queue();
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getUserService()
|
||||
.getUser(member.getNickname())
|
||||
.then(user -> unbanUser(context, user))
|
||||
.except(Throwable::printStackTrace);
|
||||
}
|
||||
|
||||
private void unbanUser(CommandContext context, User user) {
|
||||
user.getBanned().set(false);
|
||||
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("User Unbanned")
|
||||
.setColor(Constants.TRANSPARENT)
|
||||
.addField("Target", user.getUsername().get(), true)
|
||||
.addField("Moderator", context.getInteraction().getUser().getName(), true)
|
||||
.build();
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.replyEmbeds(embed)
|
||||
.queue();
|
||||
}
|
||||
}
|
118
src/main/java/ee/yoursit/core/command/discord/VerifyCommand.java
Normal file
118
src/main/java/ee/yoursit/core/command/discord/VerifyCommand.java
Normal file
|
@ -0,0 +1,118 @@
|
|||
package ee.yoursit.core.command.discord;
|
||||
|
||||
import dev.inventex.discord.command.slash.CommandContext;
|
||||
import dev.inventex.discord.command.slash.SlashCommand;
|
||||
import dev.inventex.discord.command.slash.SlashCommandInfo;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.Invite;
|
||||
import ee.yoursit.core.database.entity.impl.Verification;
|
||||
import ee.yoursit.core.util.Constants;
|
||||
import lombok.SneakyThrows;
|
||||
import net.dv8tion.jda.api.EmbedBuilder;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.entities.Member;
|
||||
import net.dv8tion.jda.api.entities.MessageEmbed;
|
||||
import net.dv8tion.jda.api.interactions.commands.OptionType;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
@SlashCommandInfo(name = "verify", description = "Accept an invitation from an SMP player.")
|
||||
public class VerifyCommand extends SlashCommand {
|
||||
@Override
|
||||
protected void initialize() {
|
||||
addOption(
|
||||
OptionType.STRING,
|
||||
"code",
|
||||
"The invite code generated by a user",
|
||||
true, false
|
||||
);
|
||||
addOption(OptionType.STRING,
|
||||
"username",
|
||||
"The in-game name of your Minecraft account",
|
||||
true, false
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandContext context) {
|
||||
Guild guild = context.getInteraction().getGuild();
|
||||
if (guild == null || guild.getIdLong() != Constants.YSMP_SERVER) {
|
||||
handleError(context, Messages.INVITE_NOT_ON_GUILD);
|
||||
return;
|
||||
}
|
||||
|
||||
String code = context.getString("code");
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getInviteService()
|
||||
.getInvite(code)
|
||||
.then(invite -> acceptInvite(context, invite))
|
||||
.except(e -> handleError(context, Messages.INVITE_NOT_FOUND));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private synchronized void acceptInvite(CommandContext context, Invite invite) {
|
||||
if (invite.getUsed().get()) {
|
||||
handleError(context, Messages.INVITE_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
|
||||
Verification existingVerification = YsmpCore.INSTANCE
|
||||
.getVerificationService()
|
||||
.getVerification(invite.getCode().get())
|
||||
.get();
|
||||
|
||||
if (existingVerification != null) {
|
||||
handleError(context, Messages.INVITE_ALREADY_VERIFYING);
|
||||
return;
|
||||
}
|
||||
|
||||
Member member = context
|
||||
.getInteraction()
|
||||
.getMember();
|
||||
assert member != null;
|
||||
|
||||
String username = context.getString("username");
|
||||
String code = context.getString("code");
|
||||
|
||||
Verification verification = EntitySerializer.init(Verification.class);
|
||||
verification.getDiscordId().init(member.getIdLong());
|
||||
verification.getUsername().init(username);
|
||||
verification.getCode().init(code);
|
||||
verification.getCreation().init(System.currentTimeMillis());
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getVerificationService()
|
||||
.addVerification(verification)
|
||||
.get();
|
||||
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("Verification")
|
||||
.setDescription(Messages.INVITE_VERIFICATION
|
||||
.replace("{code}", code))
|
||||
.setColor(Constants.TRANSPARENT)
|
||||
.build();
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.deferReply(true)
|
||||
.addEmbeds(embed)
|
||||
.queue();
|
||||
}
|
||||
|
||||
private void handleError(CommandContext context, String message) {
|
||||
MessageEmbed embed = new EmbedBuilder()
|
||||
.setTitle("Error")
|
||||
.setDescription(message)
|
||||
.setColor(Color.RED)
|
||||
.build();
|
||||
|
||||
context
|
||||
.getInteraction()
|
||||
.deferReply(true)
|
||||
.addEmbeds(embed)
|
||||
.queue();
|
||||
}
|
||||
}
|
329
src/main/java/ee/yoursit/core/config/Config.java
Normal file
329
src/main/java/ee/yoursit/core/config/Config.java
Normal file
|
@ -0,0 +1,329 @@
|
|||
package ee.yoursit.core.config;
|
||||
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.util.Message;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
public class Config {
|
||||
private final Executor executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
@Getter
|
||||
private final String name;
|
||||
private final File file;
|
||||
|
||||
@Getter
|
||||
private FileConfiguration config;
|
||||
|
||||
public Config(String name) {
|
||||
this.name = name;
|
||||
file = new File(YsmpCore.INSTANCE.getPlugin().getDataFolder(), name + ".yml");
|
||||
reload();
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
createConfig();
|
||||
} catch (IOException e) {
|
||||
Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Unable to reload config file '" + file.getName() + "'");
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
load();
|
||||
}
|
||||
|
||||
public void reloadAsync() {
|
||||
if (!file.exists())
|
||||
createConfigAsync(null);
|
||||
loadAsync();
|
||||
}
|
||||
|
||||
public void reloadAsync(Runnable action) {
|
||||
if (!file.exists())
|
||||
createConfigAsync(action);
|
||||
loadAsync();
|
||||
}
|
||||
|
||||
public void save() {
|
||||
try {
|
||||
config.save(file);
|
||||
} catch (IOException e) {
|
||||
Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Unable to save config file '" + file.getName() + "'");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void saveAsync() {
|
||||
executor.execute(this::save);
|
||||
}
|
||||
|
||||
public void load() {
|
||||
try {
|
||||
config = new YamlConfiguration();
|
||||
FileInputStream stream = new FileInputStream(file);
|
||||
config.load(new InputStreamReader(stream, StandardCharsets.UTF_8));
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Unable to load config file", e);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadAsync() {
|
||||
executor.execute(this::load);
|
||||
}
|
||||
|
||||
private void createConfig() throws IOException {
|
||||
if (!file.createNewFile())
|
||||
throw new RuntimeException("Unable to create config.yml");
|
||||
|
||||
InputStream stream = YsmpCore.class.getClassLoader().getResourceAsStream(name + ".yml");
|
||||
if (stream == null)
|
||||
throw new RuntimeException("File config.yml is missing from class path.");
|
||||
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(stream, StandardCharsets.UTF_8));
|
||||
StringBuilder content = new StringBuilder();
|
||||
String line;
|
||||
|
||||
while ((line = reader.readLine()) != null)
|
||||
content.append(line).append('\n');
|
||||
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter(Files.newOutputStream(file.toPath()), StandardCharsets.UTF_8)) {
|
||||
writer.write(content.toString());
|
||||
}
|
||||
}
|
||||
|
||||
private void createConfigAsync(Runnable action) {
|
||||
executor.execute(() -> {
|
||||
try {
|
||||
createConfig();
|
||||
action.run();
|
||||
} catch (Exception e) {
|
||||
Bukkit.getConsoleSender().sendMessage(ChatColor.RED + "Error whilst creating config file '" + file.getName() + "'");
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public boolean getOrDefault(String path, boolean defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return config.getBoolean(path);
|
||||
else {
|
||||
config.set(path, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public int getOrDefault(String path, int defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return config.getInt(path);
|
||||
else {
|
||||
config.set(path, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public int getOrDefaultNoSet(String path, int defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return config.getInt(path);
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public long getOrDefault(String path, long defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return config.getInt(path);
|
||||
else {
|
||||
config.set(path, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public double getOrDefault(String path, double defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return config.getDouble(path);
|
||||
else {
|
||||
config.set(path, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public float getOrDefault(String path, float defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return (float) config.getDouble(path);
|
||||
else {
|
||||
config.set(path, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public String getOrDefault(String path, String defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return config.getString(path);
|
||||
else {
|
||||
if (defaultValue != null)
|
||||
config.set(path, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public String getString(String path) {
|
||||
return config.getString(path);
|
||||
}
|
||||
|
||||
public long getLong(String path) {
|
||||
return config.getLong(path);
|
||||
}
|
||||
|
||||
public String getOrDefaultNoSet(String path, String defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return config.getString(path);
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public String getF(String path) {
|
||||
String string = config.getString(path);
|
||||
if (string == null)
|
||||
throw new IllegalStateException("No such config option: " + path);
|
||||
return Message.translate(string);
|
||||
}
|
||||
|
||||
public String getOrDefaultF(String path, String defaultValue) {
|
||||
String result;
|
||||
if (config.isSet(path))
|
||||
result = config.getString(path);
|
||||
else {
|
||||
result = defaultValue;
|
||||
if (defaultValue == null)
|
||||
return null;
|
||||
config.set(path, result);
|
||||
}
|
||||
return Message.translate(result);
|
||||
}
|
||||
|
||||
public String getOrDefaultFLS(String path, String... defaultValue) {
|
||||
String result;
|
||||
if (config.isSet(path)) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Iterator<String> iterator = config.getStringList(path).iterator();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
builder.append(iterator.next());
|
||||
if (iterator.hasNext())
|
||||
builder.append('\n');
|
||||
}
|
||||
|
||||
result = builder.toString();
|
||||
} else {
|
||||
result = String.join("\n", defaultValue);
|
||||
config.set(path, Arrays.asList(defaultValue));
|
||||
}
|
||||
return Message.translate(result);
|
||||
}
|
||||
|
||||
public Material getOrDefault(String path, Material defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return Material.getMaterial(config.getString(path));
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
public List<String> getOrDefaultFL(String path, String... defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return config
|
||||
.getStringList(path)
|
||||
.stream()
|
||||
.map(s -> Message.translate(s))
|
||||
.toList();
|
||||
|
||||
else if (defaultValue.length > 0) {
|
||||
List<String> result = Arrays
|
||||
.stream(defaultValue)
|
||||
.map(s -> Message.translate(s))
|
||||
.toList();
|
||||
|
||||
config.set(path, result);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> getOrDefault(String path, List<String> defaultValue) {
|
||||
if (config.isSet(path))
|
||||
return config.getStringList(path);
|
||||
else {
|
||||
config.set(path, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public Location getOrDefault(String path, Location defaultValue) {
|
||||
if (config.isSet(path)) {
|
||||
String world = config.getString(path + ".world");
|
||||
if (world == null)
|
||||
return null;
|
||||
|
||||
return new Location(
|
||||
Bukkit.getWorld(world),
|
||||
getOrDefault(path + ".posX", 0D),
|
||||
getOrDefault(path + ".posY", 0D),
|
||||
getOrDefault(path + ".posZ", 0D),
|
||||
getOrDefault(path + ".yaw", 0F),
|
||||
getOrDefault(path + ".pitch", 0F)
|
||||
);
|
||||
} else {
|
||||
setLocation(path, defaultValue);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public Location getLocation(String path) {
|
||||
return config.getLocation(path);
|
||||
}
|
||||
|
||||
public void setLocation(String path, Location location) {
|
||||
if (location == null) {
|
||||
config.set(path, new HashMap<>());
|
||||
return;
|
||||
}
|
||||
|
||||
config.set(path + ".world", location.getWorld().getName());
|
||||
config.set(path + ".posX", location.getX());
|
||||
config.set(path + ".posY", location.getY());
|
||||
config.set(path + ".posZ", location.getZ());
|
||||
config.set(path + ".yaw", location.getYaw());
|
||||
config.set(path + ".pitch", location.getPitch());
|
||||
}
|
||||
|
||||
public Set<String> getKeys(String path) {
|
||||
ConfigurationSection section = config.getConfigurationSection(path);
|
||||
if (section == null)
|
||||
return new HashSet<>();
|
||||
return section.getKeys(false);
|
||||
}
|
||||
|
||||
public void set(String path, Object value) {
|
||||
config.set(path, value);
|
||||
}
|
||||
|
||||
public void unset(String path) {
|
||||
config.set(path, null);
|
||||
}
|
||||
|
||||
public boolean isSet(String path) {
|
||||
return config.isSet(path);
|
||||
}
|
||||
}
|
148
src/main/java/ee/yoursit/core/config/Messages.java
Normal file
148
src/main/java/ee/yoursit/core/config/Messages.java
Normal file
|
@ -0,0 +1,148 @@
|
|||
package ee.yoursit.core.config;
|
||||
|
||||
public class Messages {
|
||||
public static String INTERNAL_ERROR;
|
||||
|
||||
public static String PLAYER_JOIN, PLAYER_LEAVE;
|
||||
|
||||
public static String PLAYER_NOT_ONLINE, NO_PLAYERS_ONLINE, NOT_A_USER, ALREADY_USER;
|
||||
|
||||
public static String TELEPORT_REQUEST_SEND, TELEPORT_REQUEST_RECEIVE, TELEPORT_REQUEST_USAGE,
|
||||
TELEPORT_REQUEST_ALREADY;
|
||||
|
||||
public static String TELEPORT_ACCEPT_SEND, TELEPORT_ACCEPT_RECEIVE;
|
||||
public static String TELEPORT_DECLINE_SEND, TELEPORT_DECLINE_RECEIVE;
|
||||
|
||||
public static String TELEPORT_NO_REQUESTS, TELEPORT_NO_REQUEST_FROM;
|
||||
|
||||
public static String PRIVATE_MESSAGE_SEND, PRIVATE_MESSAGE_RECEIVE, PRIVATE_MESSAGE_USAGE,
|
||||
PRIVATE_MESSAGE_NO_OPEN_CHANNELS;
|
||||
|
||||
public static String HOME_UPDATED, HOME_TELEPORTING, HOME_NOT_SET, HOME_DELETED;
|
||||
|
||||
public static String AUTO_SLEEP;
|
||||
|
||||
public static String BANNED_FROM_SERVER, NOT_WHITELISTED, UNABLE_TO_FETCH;
|
||||
|
||||
public static String ACTIVITY_PLAYERS, ACTIVITY_DISCORD, ACTIVITY_ADDRESS;
|
||||
|
||||
public static String NO_SUCH_USER, NO_PERMISSION;
|
||||
|
||||
public static String INVITE_LIMIT_EXCEEDED, INVITE_NOT_FOUND, INVITE_NOT_ON_GUILD,
|
||||
INVITE_VERIFIED, INVITE_VERIFICATION, INVITE_ALREADY_VERIFYING,
|
||||
INVITE_ALREADY_VERIFIED, INVITE_USE_VERIFY, INVITE_VERIFY_TIMEOUT,
|
||||
INVITE_INVALID_CODE, INVITE_NOT_JOINED_GUILD, INVITE_ALREADY_VERIFYING_SELF;
|
||||
|
||||
public static String GROUP_USAGE, GROUP_NOT_EXISTS,
|
||||
GROUP_CREATE_USAGE, GROUP_CREATE_ALREADY_EXISTS, GROUP_CREATE_CREATED,
|
||||
GROUP_DELETE_USAGE, GROUP_DELETE_NOT_EXISTS, GROUP_DELETE_DELETED,
|
||||
GROUP_LIST, GROUP_NO_GROUPS,
|
||||
GROUP_META_USAGE, GROUP_META_INFO,
|
||||
GROUP_META_PREFIX_USAGE, GROUP_META_PREFIX_SET,
|
||||
GROUP_META_SUFFIX_USAGE, GROUP_META_SUFFIX_SET,
|
||||
GROUP_META_TAB_PREFIX_USAGE, GROUP_META_TAB_PREFIX_SET,
|
||||
GROUP_META_TAB_SUFFIX_USAGE, GROUP_META_TAB_SUFFIX_SET,
|
||||
GROUP_PERMISSION_USAGE,
|
||||
GROUP_PERMISSION_SET_USAGE, GROUP_PERMISSION_SET_UPDATED,
|
||||
GROUP_PERMISSION_UNSET_USAGE, GROUP_PERMISSION_UNSET_UPDATED,
|
||||
GROUP_GRANT_USAGE, GROUP_GRANT_GRANTED;
|
||||
|
||||
public static void init(Config config) {
|
||||
INTERNAL_ERROR = config.getF("internal-error");
|
||||
|
||||
PLAYER_JOIN = config.getF("player-join");
|
||||
PLAYER_LEAVE = config.getF("player-leave");
|
||||
|
||||
PLAYER_NOT_ONLINE = config.getF("player-not-online");
|
||||
NO_PLAYERS_ONLINE = config.getF("no-players-online");
|
||||
NOT_A_USER = config.getF("not-a-user");
|
||||
ALREADY_USER = config.getF("already-user");
|
||||
|
||||
TELEPORT_REQUEST_SEND = config.getF("teleport-request.send");
|
||||
TELEPORT_REQUEST_RECEIVE = config.getF("teleport-request.receive");
|
||||
TELEPORT_REQUEST_USAGE = config.getF("teleport-request.usage");
|
||||
TELEPORT_REQUEST_ALREADY = config.getF("teleport-request.already");
|
||||
|
||||
TELEPORT_NO_REQUESTS = config.getF("teleport.no-requests");
|
||||
TELEPORT_NO_REQUEST_FROM = config.getF("teleport.no-request-from");
|
||||
|
||||
TELEPORT_ACCEPT_SEND = config.getF("teleport-accept.send");
|
||||
TELEPORT_ACCEPT_RECEIVE = config.getF("teleport-accept.receive");
|
||||
|
||||
TELEPORT_DECLINE_SEND = config.getF("teleport-decline.send");
|
||||
TELEPORT_DECLINE_RECEIVE = config.getF("teleport-decline.receive");
|
||||
|
||||
PRIVATE_MESSAGE_SEND = config.getF("private-message.send");
|
||||
PRIVATE_MESSAGE_RECEIVE = config.getF("private-message.receive");
|
||||
PRIVATE_MESSAGE_USAGE = config.getF("private-message.usage");
|
||||
PRIVATE_MESSAGE_NO_OPEN_CHANNELS = config.getF("private-message.no-open-channels");
|
||||
|
||||
HOME_UPDATED = config.getF("home.updated");
|
||||
HOME_TELEPORTING = config.getF("home.teleporting");
|
||||
HOME_NOT_SET = config.getF("home.not-set");
|
||||
HOME_DELETED = config.getF("home.deleted");
|
||||
|
||||
AUTO_SLEEP = config.getF("auto-sleep");
|
||||
|
||||
BANNED_FROM_SERVER = config.getF("banned-from-server");
|
||||
NOT_WHITELISTED = config.getF("not-whitelisted");
|
||||
UNABLE_TO_FETCH = config.getF("unable-to-fetch");
|
||||
|
||||
ACTIVITY_PLAYERS = config.getF("activity.players");
|
||||
ACTIVITY_DISCORD = config.getF("activity.discord");
|
||||
ACTIVITY_ADDRESS = config.getF("activity.address");
|
||||
|
||||
NO_SUCH_USER = config.getF("no-such-user");
|
||||
NO_PERMISSION = config.getF("no-permission");
|
||||
|
||||
INVITE_LIMIT_EXCEEDED = config.getF("invite.limit-exceeded");
|
||||
INVITE_NOT_FOUND = config.getF("invite.not-found");
|
||||
INVITE_NOT_ON_GUILD = config.getF("invite.not-on-guild");
|
||||
INVITE_VERIFIED = config.getF("invite.verified");
|
||||
INVITE_VERIFICATION = config.getF("invite.verification");
|
||||
INVITE_ALREADY_VERIFYING = config.getF("invite.already-verifying");
|
||||
INVITE_ALREADY_VERIFIED = config.getF("invite.already-verified");
|
||||
INVITE_USE_VERIFY = config.getF("invite.use-verify");
|
||||
INVITE_VERIFY_TIMEOUT = config.getF("invite.verify-timeout");
|
||||
INVITE_INVALID_CODE = config.getF("invite.invalid-code");
|
||||
INVITE_NOT_JOINED_GUILD = config.getF("invite.not-joined-guild");
|
||||
INVITE_ALREADY_VERIFYING_SELF = config.getF("invite.already-verifying-self");
|
||||
|
||||
GROUP_USAGE = config.getF("group.usage");
|
||||
GROUP_NOT_EXISTS = config.getF("group.not-exists");
|
||||
|
||||
GROUP_CREATE_USAGE = config.getF("group.create.usage");
|
||||
GROUP_CREATE_ALREADY_EXISTS = config.getF("group.create.already-exists");
|
||||
GROUP_CREATE_CREATED = config.getF("group.create.created");
|
||||
|
||||
GROUP_DELETE_USAGE = config.getF("group.delete.usage");
|
||||
GROUP_DELETE_NOT_EXISTS = config.getF("group.delete.not-exists");
|
||||
GROUP_DELETE_DELETED = config.getF("group.delete.deleted");
|
||||
|
||||
GROUP_LIST = config.getF("group.list");
|
||||
GROUP_NO_GROUPS = config.getF("group.no-groups");
|
||||
|
||||
GROUP_META_USAGE = config.getF("group.meta.usage");
|
||||
GROUP_META_INFO = config.getF("group.meta.info");
|
||||
|
||||
GROUP_META_PREFIX_USAGE = config.getF("group.meta.prefix.usage");
|
||||
GROUP_META_PREFIX_SET = config.getF("group.meta.prefix.set");
|
||||
|
||||
GROUP_META_TAB_PREFIX_USAGE = config.getF("group.meta.tab-prefix.usage");
|
||||
GROUP_META_TAB_PREFIX_SET = config.getF("group.meta.tab-prefix.set");
|
||||
|
||||
GROUP_META_TAB_SUFFIX_USAGE = config.getF("group.meta.tab-suffix.usage");
|
||||
GROUP_META_TAB_SUFFIX_SET = config.getF("group.meta.tab-suffix.set");
|
||||
|
||||
GROUP_PERMISSION_USAGE = config.getF("group.permission.usage");
|
||||
|
||||
GROUP_PERMISSION_SET_USAGE = config.getF("group.permission.set.usage");
|
||||
GROUP_PERMISSION_SET_UPDATED = config.getF("group.permission.set.updated");
|
||||
|
||||
GROUP_PERMISSION_UNSET_USAGE = config.getF("group.permission.unset.usage");
|
||||
GROUP_PERMISSION_UNSET_UPDATED = config.getF("group.permission.unset.updated");
|
||||
|
||||
GROUP_GRANT_USAGE = config.getF("group.grant.usage");
|
||||
GROUP_GRANT_GRANTED = config.getF("group.grant.granted");
|
||||
}
|
||||
}
|
49
src/main/java/ee/yoursit/core/data/DataManager.java
Normal file
49
src/main/java/ee/yoursit/core/data/DataManager.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package ee.yoursit.core.data;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import lombok.Getter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Getter
|
||||
public class DataManager {
|
||||
private final Map<UUID, PlayerData> playerData = Maps.newConcurrentMap();
|
||||
|
||||
public DataManager() {
|
||||
Bukkit
|
||||
.getOnlinePlayers()
|
||||
.forEach(this::add);
|
||||
|
||||
Bukkit
|
||||
.getScheduler()
|
||||
.scheduleSyncRepeatingTask(YsmpCore.INSTANCE.getPlugin(),
|
||||
this::updateOnline, 20 * 60, 20 * 60);
|
||||
}
|
||||
|
||||
private void updateOnline() {
|
||||
playerData
|
||||
.values()
|
||||
.forEach(PlayerData::updateLastOnline);
|
||||
}
|
||||
|
||||
public PlayerData add(Player player) {
|
||||
PlayerData data = new PlayerData(player);
|
||||
playerData.put(player.getUniqueId(), data);
|
||||
return data;
|
||||
}
|
||||
|
||||
public PlayerData remove(Player player) {
|
||||
return playerData.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
public PlayerData get(Player player) {
|
||||
return playerData.get(player.getUniqueId());
|
||||
}
|
||||
|
||||
public PlayerData get(UUID uuid) {
|
||||
return playerData.get(uuid);
|
||||
}
|
||||
}
|
167
src/main/java/ee/yoursit/core/data/PlayerData.java
Normal file
167
src/main/java/ee/yoursit/core/data/PlayerData.java
Normal file
|
@ -0,0 +1,167 @@
|
|||
package ee.yoursit.core.data;
|
||||
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
import dev.inventex.octa.concurrent.future.FutureTimeoutException;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.database.entity.impl.Group;
|
||||
import ee.yoursit.core.database.entity.impl.User;
|
||||
import ee.yoursit.core.database.entity.impl.Verification;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class PlayerData {
|
||||
public static final int TELEPORT_REQUEST_LIFETIME = 1000 * 30;
|
||||
|
||||
private final Map<UUID, Long> teleportRequests = new HashMap<>();
|
||||
|
||||
private final Reference<Player> player;
|
||||
|
||||
private boolean online;
|
||||
private long joinTime;
|
||||
|
||||
@Nullable
|
||||
private UUID lastMessenger;
|
||||
|
||||
private Future<User> user;
|
||||
|
||||
@Setter
|
||||
private boolean verifying;
|
||||
private Verification verification;
|
||||
|
||||
public PlayerData(Player player) {
|
||||
this.player = new WeakReference<>(player);
|
||||
|
||||
Bukkit.getScheduler().scheduleSyncRepeatingTask(YsmpCore.INSTANCE.getPlugin(),
|
||||
this::cleanUpExpiredRequests, 20L, 20L);
|
||||
|
||||
user = YsmpCore.INSTANCE
|
||||
.getUserService()
|
||||
.getUser(player.getUniqueId())
|
||||
.timeout(3, TimeUnit.SECONDS)
|
||||
.except(this::handleUserNotFound);
|
||||
}
|
||||
|
||||
private void handleUserNotFound(Throwable err) {
|
||||
Player player = this.player.get();
|
||||
if (player == null)
|
||||
return;
|
||||
|
||||
if (err instanceof FutureTimeoutException) {
|
||||
kick(Messages.UNABLE_TO_FETCH);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Verification verification = YsmpCore.INSTANCE
|
||||
.getVerificationService()
|
||||
.getVerification(player)
|
||||
.getOrDefault(null);
|
||||
|
||||
if (verification != null) {
|
||||
handleVerification(player, verification);
|
||||
return;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
kick(Messages.NOT_WHITELISTED);
|
||||
}
|
||||
|
||||
private void handleVerification(Player player, Verification verification) {
|
||||
try {
|
||||
teleport(YsmpCore.INSTANCE.getVerifyLoc());
|
||||
player.sendMessage(Messages.INVITE_USE_VERIFY);
|
||||
|
||||
verifying = true;
|
||||
this.verification = verification;
|
||||
|
||||
long timeout = YsmpCore.INSTANCE
|
||||
.getConfig()
|
||||
.getLong("verify-timeout");
|
||||
|
||||
Bukkit
|
||||
.getScheduler()
|
||||
.scheduleSyncDelayedTask(YsmpCore.INSTANCE.getPlugin(), () -> {
|
||||
if (verifying)
|
||||
kick(Messages.INVITE_VERIFY_TIMEOUT);
|
||||
}, timeout * 20);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateLastOnline() {
|
||||
user.then(u -> u
|
||||
.getLastOnline()
|
||||
.set(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
public Future<Group> getGroup() {
|
||||
return getUser().tryTransform(user ->
|
||||
YsmpCore.INSTANCE
|
||||
.getGroupService()
|
||||
.getGroup(user.getGroup().get())
|
||||
.get());
|
||||
}
|
||||
|
||||
public void addTeleportRequest(Player requester) {
|
||||
teleportRequests.put(requester.getUniqueId(), System.currentTimeMillis());
|
||||
}
|
||||
|
||||
public void removeTeleportRequest(Player requester) {
|
||||
teleportRequests.remove(requester.getUniqueId());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long getTeleportRequest(Player requester) {
|
||||
return teleportRequests.get(requester.getUniqueId());
|
||||
}
|
||||
|
||||
private void cleanUpExpiredRequests() {
|
||||
long now = System.currentTimeMillis();
|
||||
teleportRequests
|
||||
.entrySet()
|
||||
.removeIf(entry -> now - entry.getValue() > TELEPORT_REQUEST_LIFETIME);
|
||||
}
|
||||
|
||||
public Player getLastMessenger() {
|
||||
if (lastMessenger == null)
|
||||
return null;
|
||||
return Bukkit.getPlayer(lastMessenger);
|
||||
}
|
||||
|
||||
public void kick(String reason) {
|
||||
sync(() -> {
|
||||
Player player = this.player.get();
|
||||
if (player != null)
|
||||
player.kickPlayer(reason);
|
||||
});
|
||||
}
|
||||
|
||||
public void teleport(Location location) {
|
||||
sync(() -> {
|
||||
Player player = this.player.get();
|
||||
if (player != null)
|
||||
player.teleport(location);
|
||||
});
|
||||
}
|
||||
|
||||
private void sync(Runnable task) {
|
||||
Bukkit
|
||||
.getScheduler()
|
||||
.runTask(YsmpCore.INSTANCE.getPlugin(), task);
|
||||
}
|
||||
}
|
39
src/main/java/ee/yoursit/core/database/Database.java
Normal file
39
src/main/java/ee/yoursit/core/database/Database.java
Normal file
|
@ -0,0 +1,39 @@
|
|||
package ee.yoursit.core.database;
|
||||
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import ee.yoursit.core.database.entity.impl.*;
|
||||
import lombok.Getter;
|
||||
import org.bson.Document;
|
||||
|
||||
@Getter
|
||||
public class Database {
|
||||
private final String host;
|
||||
private final int port;
|
||||
|
||||
private MongoClient client;
|
||||
|
||||
private MongoCollection<Document> users, groups, invites, bans, verifications;
|
||||
|
||||
public Database(String host, int port) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void connect() {
|
||||
client = new MongoClient(host, port);
|
||||
|
||||
MongoDatabase database = client.getDatabase("ysmp");
|
||||
|
||||
User.setCollection(users = database.getCollection("users"));
|
||||
Group.setCollection(groups = database.getCollection("groups"));
|
||||
Invite.setCollection(invites = database.getCollection("invites"));
|
||||
Ban.setCollection(bans = database.getCollection("bans"));
|
||||
Verification.setCollection(verifications = database.getCollection("verifications"));
|
||||
}
|
||||
|
||||
public void disconnect() {
|
||||
client.close();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package ee.yoursit.core.database.entity.api;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
public interface Entity {
|
||||
Bson query();
|
||||
|
||||
MongoCollection<Document> collection();
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
package ee.yoursit.core.database.entity.api;
|
||||
|
||||
import com.mongodb.client.model.Updates;
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class EntityProperty<T> {
|
||||
private static final Map<Class<?>, Object> FALLBACK = new HashMap<>();
|
||||
static {
|
||||
FALLBACK.put(Byte.class, (byte) 0);
|
||||
FALLBACK.put(Short.class, (short) 0);
|
||||
FALLBACK.put(Integer.class, 0);
|
||||
FALLBACK.put(Float.class, 0F);
|
||||
FALLBACK.put(Double.class, 0D);
|
||||
FALLBACK.put(Long.class, 0L);
|
||||
FALLBACK.put(Boolean.class, false);
|
||||
FALLBACK.put(Character.class, (char) 0);
|
||||
FALLBACK.put(Number.class, 0);
|
||||
FALLBACK.put(List.class, new ArrayList<>());
|
||||
FALLBACK.put(Map.class, new HashMap<>());
|
||||
}
|
||||
|
||||
private final Entity entity;
|
||||
private final String name;
|
||||
|
||||
@Getter
|
||||
private final Class<T> type;
|
||||
|
||||
public T value;
|
||||
private boolean init = false;
|
||||
|
||||
public EntityProperty(Entity entity, String name, Class<T> type, T value) {
|
||||
this(entity, name, type);
|
||||
init(value);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final T get() {
|
||||
if (!init && FALLBACK.containsKey(type))
|
||||
return (T) FALLBACK.get(type);
|
||||
return value;
|
||||
}
|
||||
|
||||
@MutateEntity
|
||||
public final Future<Void> set(T value) {
|
||||
this.value = value;
|
||||
init = true;
|
||||
return mutate();
|
||||
}
|
||||
|
||||
public final void init(T value) {
|
||||
this.value = value;
|
||||
init = true;
|
||||
}
|
||||
|
||||
@MutateEntity
|
||||
public final Future<Void> mutate() {
|
||||
return Future.completeAsync(() -> {
|
||||
try {
|
||||
Object serialize = EntitySerializer.serialize(type, value);
|
||||
entity
|
||||
.collection()
|
||||
.updateOne(entity.query(), Updates.set(name, serialize));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,142 @@
|
|||
package ee.yoursit.core.database.entity.api;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
public class EntitySerializer {
|
||||
private static final Set<Class<?>> NUMBERS = new HashSet<>();
|
||||
static {
|
||||
NUMBERS.add(byte.class);
|
||||
NUMBERS.add(short.class);
|
||||
NUMBERS.add(int.class);
|
||||
NUMBERS.add(long.class);
|
||||
NUMBERS.add(float.class);
|
||||
NUMBERS.add(double.class);
|
||||
NUMBERS.add(Byte.class);
|
||||
NUMBERS.add(Short.class);
|
||||
NUMBERS.add(Integer.class);
|
||||
NUMBERS.add(Long.class);
|
||||
NUMBERS.add(Float.class);
|
||||
NUMBERS.add(Double.class);
|
||||
NUMBERS.add(Number.class);
|
||||
}
|
||||
|
||||
public static <T extends Entity> Document serialize(T entity) {
|
||||
Document document = new Document();
|
||||
|
||||
for (Field field : entity.getClass().getDeclaredFields()) {
|
||||
if (Modifier.isTransient(field.getModifiers()))
|
||||
continue;
|
||||
|
||||
field.setAccessible(true);
|
||||
|
||||
try {
|
||||
@SuppressWarnings("rawtypes")
|
||||
EntityProperty property = (EntityProperty) field.get(entity);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Object serialize = serialize(property.getType(), property.get());
|
||||
document.append(field.getName(), serialize);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return document;
|
||||
}
|
||||
|
||||
public static <T> Object serialize(Class<T> type, Object object) {
|
||||
if (object == null)
|
||||
return null;
|
||||
|
||||
else if (NUMBERS.contains(type))
|
||||
return type.isInstance(object)
|
||||
? object
|
||||
: Double.parseDouble(String.valueOf(object));
|
||||
|
||||
else if (object instanceof UUID)
|
||||
return object.toString();
|
||||
|
||||
else if (object instanceof Location location)
|
||||
return location.serialize();
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
public static <T extends Entity> T deserialize(Document document, Class<T> type) throws Exception {
|
||||
if (document == null)
|
||||
throw new IllegalStateException("Trying to deserialize null document.");
|
||||
|
||||
T entity = type.getConstructor().newInstance();
|
||||
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
if (Modifier.isTransient(field.getModifiers()))
|
||||
continue;
|
||||
|
||||
field.setAccessible(true);
|
||||
|
||||
try {
|
||||
Object value = document.get(field.getName());
|
||||
|
||||
ParameterizedType genericType = (ParameterizedType) field.getGenericType();
|
||||
Class<?> propertyType = (Class<?>) genericType.getActualTypeArguments()[0];
|
||||
|
||||
Object deserialize = deserialize(propertyType, value);
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
EntityProperty property = new EntityProperty(entity, field.getName(), propertyType, deserialize);
|
||||
field.set(entity, property);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Object deserialize(Class<T> type, Object object) {
|
||||
if (object == null)
|
||||
return null;
|
||||
|
||||
if (NUMBERS.contains(type))
|
||||
return type.isInstance(object)
|
||||
? object
|
||||
: Double.parseDouble(String.valueOf(object));
|
||||
|
||||
else if (UUID.class.isAssignableFrom(type))
|
||||
return UUID.fromString(String.valueOf(object));
|
||||
|
||||
else if (Location.class.isAssignableFrom(type))
|
||||
return Location.deserialize((Map<String, Object>) object);
|
||||
return object;
|
||||
}
|
||||
|
||||
public static <T extends Entity> T init(Class<T> type) throws Exception {
|
||||
T entity = type.getConstructor().newInstance();
|
||||
|
||||
int fieldIndex = 0;
|
||||
for (Field field : type.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers()))
|
||||
continue;
|
||||
|
||||
Class<?> fieldType = field.getType();
|
||||
if (!EntityProperty.class.isAssignableFrom(fieldType))
|
||||
continue;
|
||||
|
||||
ParameterizedType genericType = (ParameterizedType) field.getGenericType();
|
||||
Class<?> propertyType = (Class<?>) genericType.getActualTypeArguments()[0];
|
||||
|
||||
Constructor<?> constructor = fieldType.getConstructor(Entity.class, String.class, Class.class);
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
Object property = constructor.newInstance(entity, field.getName(), propertyType);
|
||||
|
||||
field.setAccessible(true);
|
||||
field.set(entity, property);
|
||||
}
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package ee.yoursit.core.database.entity.api;
|
||||
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ListEntityProperty<T> extends EntityProperty<List<T>> {
|
||||
public ListEntityProperty(Entity entity, String name, Class<List<T>> type, List<T> value) {
|
||||
super(entity, name, type, value);
|
||||
}
|
||||
|
||||
public ListEntityProperty(Entity entity, String name, Class<List<T>> type) {
|
||||
super(entity, name, type);
|
||||
}
|
||||
|
||||
@MutateEntity
|
||||
public Future<Boolean> push(T value) {
|
||||
List<T> list = get();
|
||||
if (list == null)
|
||||
init(list = new ArrayList<>());
|
||||
boolean add = list.add(value);
|
||||
return mutate().transform(e -> add);
|
||||
}
|
||||
|
||||
@MutateEntity
|
||||
public Future<Boolean> pull(T value) {
|
||||
List<T> list = get();
|
||||
if (list == null)
|
||||
return Future.completed(false);
|
||||
boolean removed = list.remove(value);
|
||||
return mutate().transform(e -> removed);
|
||||
}
|
||||
|
||||
@MutateEntity
|
||||
public Future<T> pop(int index) {
|
||||
List<T> list = get();
|
||||
if (list == null)
|
||||
return Future.completed((T) null);
|
||||
T removed = list.remove(index);
|
||||
return mutate().transform(e -> removed);
|
||||
}
|
||||
|
||||
public T get(int index) {
|
||||
List<T> list = get();
|
||||
if (list == null)
|
||||
return null;
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
List<T> list = get();
|
||||
return list != null ? list.size() : 0;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package ee.yoursit.core.database.entity.api;
|
||||
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MapEntityProperty<K, V> extends EntityProperty<Map<K, V>> {
|
||||
public MapEntityProperty(Entity entity, String name, Class<Map<K, V>> type, Map<K, V> value) {
|
||||
super(entity, name, type, value);
|
||||
}
|
||||
|
||||
public MapEntityProperty(Entity entity, String name, Class<Map<K, V>> type) {
|
||||
super(entity, name, type);
|
||||
}
|
||||
|
||||
@MutateEntity
|
||||
public Future<V> set(K key, V value) {
|
||||
Map<K, V> map = get();
|
||||
if (map == null)
|
||||
init(map = new HashMap<>());
|
||||
V oldValue = map.put(key, value);
|
||||
return mutate().transform(e -> oldValue);
|
||||
}
|
||||
|
||||
@MutateEntity
|
||||
public Future<V> unset(K key) {
|
||||
Map<K, V> map = get();
|
||||
if (map == null)
|
||||
return null;
|
||||
V oldValue = map.remove(key);
|
||||
return mutate().transform(e -> oldValue);
|
||||
}
|
||||
|
||||
public V get(K key) {
|
||||
Map<K, V> map = get();
|
||||
if (map == null)
|
||||
return null;
|
||||
return map.get(key);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
package ee.yoursit.core.database.entity.api;
|
||||
|
||||
public @interface MutateEntity {
|
||||
}
|
42
src/main/java/ee/yoursit/core/database/entity/impl/Ban.java
Normal file
42
src/main/java/ee/yoursit/core/database/entity/impl/Ban.java
Normal file
|
@ -0,0 +1,42 @@
|
|||
package ee.yoursit.core.database.entity.impl;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import ee.yoursit.core.database.entity.api.Entity;
|
||||
import ee.yoursit.core.database.entity.api.EntityProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
public class Ban implements Entity {
|
||||
@Setter
|
||||
private static MongoCollection<Document> collection;
|
||||
|
||||
private EntityProperty<UUID> banId, moderator, target;
|
||||
|
||||
private EntityProperty<String> reason;
|
||||
|
||||
private EntityProperty<Long> timestamp;
|
||||
|
||||
@Override
|
||||
public Bson query() {
|
||||
return Filters.eq("banId", banId.get().toString());
|
||||
}
|
||||
|
||||
public static Bson queryId(UUID banId) {
|
||||
return Filters.eq("banId", banId.toString());
|
||||
}
|
||||
|
||||
public static Bson queryTarget(UUID target) {
|
||||
return Filters.eq("target", target.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoCollection<Document> collection() {
|
||||
return collection;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package ee.yoursit.core.database.entity.impl;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import ee.yoursit.core.database.entity.api.Entity;
|
||||
import ee.yoursit.core.database.entity.api.EntityProperty;
|
||||
import ee.yoursit.core.database.entity.api.MapEntityProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static com.mongodb.client.model.Filters.eq;
|
||||
|
||||
@Getter
|
||||
public class Group implements Entity {
|
||||
@Setter
|
||||
private static MongoCollection<Document> collection;
|
||||
|
||||
private EntityProperty<String> name;
|
||||
|
||||
private EntityProperty<String> prefix, suffix;
|
||||
private EntityProperty<String> tabPrefix, tabSuffix;
|
||||
|
||||
private MapEntityProperty<String, Boolean> permissions;
|
||||
|
||||
public static Bson query(String name) {
|
||||
return eq("name", name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bson query() {
|
||||
return Filters.eq("name", name.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoCollection<Document> collection() {
|
||||
return collection;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package ee.yoursit.core.database.entity.impl;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import ee.yoursit.core.database.entity.api.Entity;
|
||||
import ee.yoursit.core.database.entity.api.EntityProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
@Getter
|
||||
public class Invite implements Entity {
|
||||
@Setter
|
||||
static MongoCollection<Document> collection;
|
||||
|
||||
private EntityProperty<String> code;
|
||||
private EntityProperty<Boolean> used;
|
||||
private EntityProperty<String> creator;
|
||||
|
||||
@Override
|
||||
public Bson query() {
|
||||
return Filters.eq("code", code.get());
|
||||
}
|
||||
|
||||
public static Bson query(String code) {
|
||||
return Filters.eq("code", code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoCollection<Document> collection() {
|
||||
return collection;
|
||||
}
|
||||
}
|
55
src/main/java/ee/yoursit/core/database/entity/impl/User.java
Normal file
55
src/main/java/ee/yoursit/core/database/entity/impl/User.java
Normal file
|
@ -0,0 +1,55 @@
|
|||
package ee.yoursit.core.database.entity.impl;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import ee.yoursit.core.database.entity.api.Entity;
|
||||
import ee.yoursit.core.database.entity.api.EntityProperty;
|
||||
import ee.yoursit.core.database.entity.api.ListEntityProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
import org.bukkit.Location;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.mongodb.client.model.Filters.*;
|
||||
|
||||
@Getter
|
||||
public class User implements Entity {
|
||||
@Setter
|
||||
private static MongoCollection<Document> collection;
|
||||
|
||||
private EntityProperty<String> username;
|
||||
private EntityProperty<UUID> uuid;
|
||||
private EntityProperty<Long> discordId;
|
||||
|
||||
private EntityProperty<Long> registered;
|
||||
private EntityProperty<Long> lastOnline;
|
||||
private EntityProperty<Long> playTime;
|
||||
|
||||
private EntityProperty<String> group;
|
||||
private EntityProperty<Location> home;
|
||||
|
||||
private EntityProperty<Boolean> banned;
|
||||
|
||||
private EntityProperty<String> invite;
|
||||
private ListEntityProperty<String> invites;
|
||||
|
||||
public static Bson query(UUID uuid) {
|
||||
return eq("uuid", uuid.toString());
|
||||
}
|
||||
|
||||
public static Bson query(String username) {
|
||||
return eq("username", username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bson query() {
|
||||
return eq("uuid", uuid.get().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoCollection<Document> collection() {
|
||||
return collection;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
package ee.yoursit.core.database.entity.impl;
|
||||
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.model.Filters;
|
||||
import ee.yoursit.core.database.entity.api.Entity;
|
||||
import ee.yoursit.core.database.entity.api.EntityProperty;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.bson.Document;
|
||||
import org.bson.conversions.Bson;
|
||||
|
||||
@Getter
|
||||
public class Verification implements Entity {
|
||||
@Setter
|
||||
private static MongoCollection<Document> collection;
|
||||
|
||||
private EntityProperty<Long> discordId;
|
||||
private EntityProperty<String> username;
|
||||
private EntityProperty<String> code;
|
||||
private EntityProperty<Long> creation;
|
||||
|
||||
@Override
|
||||
public Bson query() {
|
||||
return Filters.eq("code", code.get());
|
||||
}
|
||||
|
||||
public static Bson queryCode(String code) {
|
||||
return Filters.eq("code", code);
|
||||
}
|
||||
|
||||
public static Bson queryName(String name) {
|
||||
return Filters.eq("username", name);
|
||||
}
|
||||
|
||||
public static Bson queryId(long discordId) {
|
||||
return Filters.eq("discordId", discordId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MongoCollection<Document> collection() {
|
||||
return collection;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package ee.yoursit.core.database.service;
|
||||
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.Ban;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class BanService {
|
||||
public Future<Ban> getBanById(UUID banId) {
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getInvites()
|
||||
.find(Ban.queryId(banId))
|
||||
.first();
|
||||
|
||||
return EntitySerializer.deserialize(document, Ban.class);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Ban> getBanByTarget(UUID target) {
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getInvites()
|
||||
.find(Ban.queryTarget(target))
|
||||
.first();
|
||||
|
||||
return EntitySerializer.deserialize(document, Ban.class);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Void> createBan(Ban ban) {
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = EntitySerializer.serialize(ban);
|
||||
YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getInvites()
|
||||
.insertOne(document);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package ee.yoursit.core.database.service;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.MongoCursor;
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.Group;
|
||||
import lombok.Getter;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class GroupService {
|
||||
@Getter
|
||||
private final Map<String, Group> groupCache = Maps.newConcurrentMap();
|
||||
|
||||
public void loadGroups() {
|
||||
try (MongoCursor<Document> cursor = YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getGroups()
|
||||
.find()
|
||||
.cursor()) {
|
||||
while (cursor.hasNext()) {
|
||||
loadGroup(cursor.next());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadGroup(Document document) {
|
||||
try {
|
||||
Group group = EntitySerializer.deserialize(document, Group.class);
|
||||
groupCache.put(group.getName().get(), group);
|
||||
} catch (Exception e) {
|
||||
System.err.println("Unable to load group " + document);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Future<Group> getGroup(String name) {
|
||||
Group group = groupCache.get(name);
|
||||
if (group != null)
|
||||
return Future.completed(group);
|
||||
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getGroups()
|
||||
.find(Group.query(name))
|
||||
.first();
|
||||
|
||||
return EntitySerializer.deserialize(document, Group.class);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Void> addGroup(Group group) {
|
||||
if (groupCache.containsKey(group.getName().get()))
|
||||
return Future.failed(new IllegalStateException("Group '" + group.getName() + "' already exists."));
|
||||
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = EntitySerializer.serialize(group);
|
||||
YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getGroups()
|
||||
.insertOne(document);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Void> removeGroup(String name) {
|
||||
groupCache.remove(name);
|
||||
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getGroups()
|
||||
.deleteOne(Group.query(name));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package ee.yoursit.core.database.service;
|
||||
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.Invite;
|
||||
import org.bson.Document;
|
||||
|
||||
public class InviteService {
|
||||
public Future<Invite> getInvite(String code) {
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getInvites()
|
||||
.find(Invite.query(code))
|
||||
.first();
|
||||
|
||||
return EntitySerializer.deserialize(document, Invite.class);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Void> createInvite(Invite invite) {
|
||||
return Future.completeAsync(() -> {
|
||||
Document document = EntitySerializer.serialize(invite);
|
||||
YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getInvites()
|
||||
.insertOne(document);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package ee.yoursit.core.database.service;
|
||||
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.User;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class UserService {
|
||||
public Future<User> getUser(UUID uuid) {
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getUsers()
|
||||
.find(User.query(uuid))
|
||||
.first();
|
||||
|
||||
return EntitySerializer.deserialize(document, User.class);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<User> getUser(String name) {
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getUsers()
|
||||
.find(User.query(name))
|
||||
.first();
|
||||
|
||||
return EntitySerializer.deserialize(document, User.class);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Void> addUser(User user) {
|
||||
return Future.completeAsync(() -> {
|
||||
Document document = EntitySerializer.serialize(user);
|
||||
YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getUsers()
|
||||
.insertOne(document);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package ee.yoursit.core.database.service;
|
||||
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.database.entity.api.EntitySerializer;
|
||||
import ee.yoursit.core.database.entity.impl.User;
|
||||
import ee.yoursit.core.database.entity.impl.Verification;
|
||||
import org.bson.Document;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class VerificationService {
|
||||
public Future<Verification> getVerification(String code) {
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getVerifications()
|
||||
.find(Verification.queryCode(code))
|
||||
.first();
|
||||
|
||||
return EntitySerializer.deserialize(document, Verification.class);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Verification> getVerification(long discordId) {
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getVerifications()
|
||||
.find(Verification.queryId(discordId))
|
||||
.first();
|
||||
|
||||
return EntitySerializer.deserialize(document, Verification.class);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Verification> getVerification(Player player) {
|
||||
return Future.tryCompleteAsync(() -> {
|
||||
Document document = YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getVerifications()
|
||||
.find(Verification.queryName(player.getName()))
|
||||
.first();
|
||||
|
||||
return EntitySerializer.deserialize(document, Verification.class);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Void> addVerification(Verification verification) {
|
||||
return Future.completeAsync(() -> {
|
||||
Document document = EntitySerializer.serialize(verification);
|
||||
YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getVerifications()
|
||||
.insertOne(document);
|
||||
});
|
||||
}
|
||||
|
||||
public Future<Void> removeVerification(Verification verification) {
|
||||
return Future.completeAsync(() -> {
|
||||
YsmpCore.INSTANCE
|
||||
.getDatabase()
|
||||
.getVerifications()
|
||||
.deleteOne(verification.query());
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package ee.yoursit.core.module;
|
||||
|
||||
import ee.yoursit.core.command.bukkit.api.Command;
|
||||
import ee.yoursit.core.command.bukkit.impl.admin.GroupCommand;
|
||||
import ee.yoursit.core.command.bukkit.impl.home.DelHomeCommand;
|
||||
import ee.yoursit.core.command.bukkit.impl.home.HomeCommand;
|
||||
import ee.yoursit.core.command.bukkit.impl.home.SetHomeCommand;
|
||||
import ee.yoursit.core.command.bukkit.impl.invite.VerifyCommand;
|
||||
import ee.yoursit.core.command.bukkit.impl.message.MessageCommand;
|
||||
import ee.yoursit.core.command.bukkit.impl.message.ReplyCommand;
|
||||
import ee.yoursit.core.command.bukkit.impl.teleport.TeleportAccept;
|
||||
import ee.yoursit.core.command.bukkit.impl.teleport.TeleportDeny;
|
||||
import ee.yoursit.core.command.bukkit.impl.teleport.TeleportRequest;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitCommandRegistry implements CommandRegistry {
|
||||
private final Class<?>[] classes = {
|
||||
TeleportRequest.class,
|
||||
TeleportAccept.class,
|
||||
TeleportDeny.class,
|
||||
|
||||
MessageCommand.class,
|
||||
ReplyCommand.class,
|
||||
|
||||
SetHomeCommand.class,
|
||||
DelHomeCommand.class,
|
||||
HomeCommand.class,
|
||||
|
||||
VerifyCommand.class,
|
||||
|
||||
GroupCommand.class
|
||||
};
|
||||
|
||||
private final Constructor<?>[] constructors = new Constructor[classes.length];
|
||||
|
||||
private final List<Command> commands = new ArrayList<>(classes.length);
|
||||
|
||||
public BukkitCommandRegistry() {
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
Class<?> command = classes[i];
|
||||
try {
|
||||
constructors[i] = command.getDeclaredConstructor();
|
||||
} catch (NoSuchMethodException e) {
|
||||
System.err.println("Unable to load command " + command.getSimpleName() + ":");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
for (Constructor<?> constructor : constructors) {
|
||||
try {
|
||||
Command command = (Command) constructor.newInstance();
|
||||
commands.add(command);
|
||||
command.register();
|
||||
} catch (Exception e) {
|
||||
System.err.println("Unable to instantiate check " + constructor.getDeclaringClass().getSimpleName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
for (Command command : commands)
|
||||
command.unregister();
|
||||
}
|
||||
}
|
170
src/main/java/ee/yoursit/core/module/BukkitListener.java
Normal file
170
src/main/java/ee/yoursit/core/module/BukkitListener.java
Normal file
|
@ -0,0 +1,170 @@
|
|||
package ee.yoursit.core.module;
|
||||
|
||||
import dev.inventex.octa.concurrent.future.Future;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import ee.yoursit.core.data.PlayerData;
|
||||
import ee.yoursit.core.database.entity.impl.Group;
|
||||
import ee.yoursit.core.database.entity.impl.User;
|
||||
import ee.yoursit.core.util.Message;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Cancellable;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.*;
|
||||
import org.bukkit.event.server.ServerListPingEvent;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BukkitListener implements Listener {
|
||||
private final Set<UUID> sleeping = new HashSet<>();
|
||||
|
||||
@EventHandler
|
||||
public void onLogin(PlayerLoginEvent event) {
|
||||
YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.add(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(player);
|
||||
|
||||
data.setOnline(true);
|
||||
data.setJoinTime(System.currentTimeMillis());
|
||||
data.updateLastOnline();
|
||||
|
||||
String message = Messages
|
||||
.PLAYER_JOIN
|
||||
.replace("{player}", player.getName());
|
||||
|
||||
event.setJoinMessage(message);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onQuit(PlayerQuitEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(player)
|
||||
.updateLastOnline();
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.remove(player);
|
||||
|
||||
String message = Messages
|
||||
.PLAYER_LEAVE
|
||||
.replace("{player}", player.getName());
|
||||
|
||||
event.setQuitMessage(message);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onBedEnter(PlayerBedEnterEvent event) {
|
||||
Collection<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers();
|
||||
long sleeping = onlinePlayers
|
||||
.stream()
|
||||
.filter(Player::isSleeping)
|
||||
.count();
|
||||
long total = onlinePlayers.size();
|
||||
|
||||
float ratio = (float) sleeping / (float) total;
|
||||
if (ratio >= 2F / 3F) {
|
||||
event
|
||||
.getPlayer()
|
||||
.getWorld()
|
||||
.setTime(0);
|
||||
onlinePlayers.forEach(player -> player.sendMessage(Messages.AUTO_SLEEP));
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPing(ServerListPingEvent event) {
|
||||
String motd = Message.translate(
|
||||
"""
|
||||
&b&lYourSitee SMP &f&l❘ 1.20.1
|
||||
&f ▶ Visit yoursit.ee/smp for more info
|
||||
"""
|
||||
);
|
||||
event.setMotd(motd);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onMove(PlayerMoveEvent event) {
|
||||
Vector from = event.getFrom().toVector();
|
||||
Vector to = event.getTo().toVector();
|
||||
|
||||
double distance = from.distance(to);
|
||||
if (distance < .01)
|
||||
return;
|
||||
|
||||
cancelVerifying(event.getPlayer(), event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onCommand(PlayerCommandPreprocessEvent event) {
|
||||
String command = event
|
||||
.getMessage()
|
||||
.split(" ")[0]
|
||||
.substring(1);
|
||||
|
||||
if (command.equals("verify"))
|
||||
return;
|
||||
|
||||
cancelVerifying(event.getPlayer(), event);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onChat(AsyncPlayerChatEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
cancelVerifying(player, event);
|
||||
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(player);
|
||||
|
||||
Group group = null;
|
||||
try {
|
||||
User user = data
|
||||
.getUser()
|
||||
.get();
|
||||
|
||||
group = YsmpCore.INSTANCE
|
||||
.getGroupService()
|
||||
.getGroup(user.getGroup().get())
|
||||
.get();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
String prefix = null, suffix = null;
|
||||
if (group != null) {
|
||||
prefix = group.getPrefix().get();
|
||||
suffix = group.getSuffix().get();
|
||||
}
|
||||
if (prefix == null) prefix = "";
|
||||
if (suffix == null) suffix = "";
|
||||
|
||||
String format = "&r" + prefix + player.getName() + "&r" + suffix + "&7: &r" + event.getMessage();
|
||||
event.setFormat(Message.translate(format));
|
||||
}
|
||||
|
||||
private void cancelVerifying(Player player, Cancellable cancellable) {
|
||||
PlayerData data = YsmpCore.INSTANCE
|
||||
.getDataManager()
|
||||
.get(player);
|
||||
|
||||
if (data.isVerifying())
|
||||
cancellable.setCancelled(true);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package ee.yoursit.core.module;
|
||||
|
||||
public interface CommandRegistry {
|
||||
void load();
|
||||
|
||||
void unload();
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package ee.yoursit.core.module;
|
||||
|
||||
import dev.inventex.discord.command.CommandManager;
|
||||
import dev.inventex.discord.command.slash.SlashCommand;
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.command.discord.*;
|
||||
import ee.yoursit.core.util.Constants;
|
||||
import net.dv8tion.jda.api.JDA;
|
||||
import net.dv8tion.jda.api.entities.Guild;
|
||||
import net.dv8tion.jda.api.interactions.commands.Command;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class DiscordCommandRegistry implements CommandRegistry {
|
||||
private final Class<?>[] classes = {
|
||||
PlayersCommand.class,
|
||||
BanCommand.class,
|
||||
UnbanCommand.class,
|
||||
InviteCommand.class,
|
||||
VerifyCommand.class,
|
||||
SmpCommand.class
|
||||
};
|
||||
|
||||
private final Constructor<?>[] constructors = new Constructor[classes.length];
|
||||
|
||||
private final List<SlashCommand> commands = new ArrayList<>(classes.length);
|
||||
|
||||
public DiscordCommandRegistry() {
|
||||
for (int i = 0; i < classes.length; i++) {
|
||||
Class<?> command = classes[i];
|
||||
try {
|
||||
constructors[i] = command.getDeclaredConstructor();
|
||||
}
|
||||
catch (NoSuchMethodException e) {
|
||||
System.err.println("Unable to load command " + command.getSimpleName() + ":");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
JDA jda = YsmpCore.INSTANCE
|
||||
.getClient()
|
||||
.getJda();
|
||||
|
||||
jda
|
||||
.retrieveCommands()
|
||||
.queue(list -> {
|
||||
for (Command command : list) {
|
||||
command
|
||||
.delete()
|
||||
.queue();
|
||||
}
|
||||
});
|
||||
|
||||
Guild guild = jda.getGuildById(Constants.YSMP_SERVER);
|
||||
assert guild != null;
|
||||
|
||||
CommandManager commandManager = YsmpCore.INSTANCE
|
||||
.getClient()
|
||||
.getCommandManager();
|
||||
|
||||
for (Constructor<?> constructor : constructors) {
|
||||
try {
|
||||
SlashCommand command = (SlashCommand) constructor.newInstance();
|
||||
commands.add(command);
|
||||
|
||||
if (command instanceof SmpCommand) {
|
||||
Guild main = jda.getGuildById(Constants.MAIN_SERVER);
|
||||
assert main != null;
|
||||
|
||||
commandManager.registerToGuild(command, main);
|
||||
continue;
|
||||
}
|
||||
|
||||
commandManager.registerToGuild(command, guild);
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.err.println("Unable to instantiate check " + constructor.getDeclaringClass().getSimpleName());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unload() {
|
||||
}
|
||||
}
|
64
src/main/java/ee/yoursit/core/module/DiscordListener.java
Normal file
64
src/main/java/ee/yoursit/core/module/DiscordListener.java
Normal file
|
@ -0,0 +1,64 @@
|
|||
package ee.yoursit.core.module;
|
||||
|
||||
import ee.yoursit.core.YsmpCore;
|
||||
import ee.yoursit.core.config.Messages;
|
||||
import net.dv8tion.jda.api.entities.Activity;
|
||||
import net.dv8tion.jda.api.entities.SelfUser;
|
||||
import net.dv8tion.jda.api.events.session.ReadyEvent;
|
||||
import net.dv8tion.jda.api.hooks.ListenerAdapter;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class DiscordListener extends ListenerAdapter {
|
||||
private static final int ACTIVITY_UPDATE = 1000 * 5;
|
||||
|
||||
private int actionIndex = 0;
|
||||
|
||||
public void onReady(ReadyEvent event) {
|
||||
SelfUser user = event.getJDA().getSelfUser();
|
||||
System.out.println("Logged in as " + user.getName() + "#" + user.getDiscriminator());
|
||||
|
||||
TimerTask task = new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateActivity();
|
||||
}
|
||||
};
|
||||
|
||||
Timer timer = new Timer();
|
||||
timer.scheduleAtFixedRate(task, ACTIVITY_UPDATE, ACTIVITY_UPDATE);
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getDiscordCommands()
|
||||
.load();
|
||||
}
|
||||
|
||||
private void updateActivity() {
|
||||
ActivityState[] values = ActivityState.values();
|
||||
ActivityState state = values[actionIndex++ % values.length];
|
||||
|
||||
Activity activity = switch (state) {
|
||||
case LIST_PLAYERS -> {
|
||||
String count = String.valueOf(Bukkit.getOnlinePlayers().size());
|
||||
yield Activity.watching(Messages.ACTIVITY_PLAYERS
|
||||
.replace("{count}", count));
|
||||
}
|
||||
case SHOW_DISCORD_LINK -> Activity.playing(Messages.ACTIVITY_DISCORD);
|
||||
case SHOW_SERVER_ADDRESS -> Activity.playing(Messages.ACTIVITY_ADDRESS);
|
||||
};
|
||||
|
||||
YsmpCore.INSTANCE
|
||||
.getClient()
|
||||
.getJda()
|
||||
.getPresence()
|
||||
.setActivity(activity);
|
||||
}
|
||||
|
||||
public enum ActivityState {
|
||||
LIST_PLAYERS,
|
||||
SHOW_DISCORD_LINK,
|
||||
SHOW_SERVER_ADDRESS
|
||||
}
|
||||
}
|
9
src/main/java/ee/yoursit/core/util/ClickAction.java
Normal file
9
src/main/java/ee/yoursit/core/util/ClickAction.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
package ee.yoursit.core.util;
|
||||
|
||||
public enum ClickAction {
|
||||
OPEN_URL,
|
||||
OPEN_FILE,
|
||||
RUN_COMMAND,
|
||||
SUGGEST_COMMAND,
|
||||
CHANGE_PAGE
|
||||
}
|
16
src/main/java/ee/yoursit/core/util/Constants.java
Normal file
16
src/main/java/ee/yoursit/core/util/Constants.java
Normal file
|
@ -0,0 +1,16 @@
|
|||
package ee.yoursit.core.util;
|
||||
|
||||
public class Constants {
|
||||
public static final long YSMP_SERVER = 598949514052894721L,
|
||||
MAIN_SERVER = 886538767995895839L;
|
||||
|
||||
public static final int TRANSPARENT = 0x313338;
|
||||
|
||||
public static final long SERVER_LEADER = 1107079573763543152L,
|
||||
PREMIUM = 1107244269112148109L,
|
||||
BUSINESS = 1107244259163246603L,
|
||||
INVITED = 1107080146051158046L,
|
||||
PLAYER = 1107080049716375582L;
|
||||
|
||||
public static final long BANNED = 1124263377439555644L;
|
||||
}
|
8
src/main/java/ee/yoursit/core/util/HoverAction.java
Normal file
8
src/main/java/ee/yoursit/core/util/HoverAction.java
Normal file
|
@ -0,0 +1,8 @@
|
|||
package ee.yoursit.core.util;
|
||||
|
||||
public enum HoverAction {
|
||||
SHOW_TEXT,
|
||||
SHOW_ACHIEVEMENT,
|
||||
SHOW_ITEM,
|
||||
SHOW_ENTITY
|
||||
}
|
32
src/main/java/ee/yoursit/core/util/InviteGenerator.java
Normal file
32
src/main/java/ee/yoursit/core/util/InviteGenerator.java
Normal file
|
@ -0,0 +1,32 @@
|
|||
package ee.yoursit.core.util;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public class InviteGenerator {
|
||||
private static final String LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
private static final String DIGITS = "0123456789";
|
||||
|
||||
private static final char[] CHARS = (LETTERS + DIGITS).toCharArray();
|
||||
|
||||
private static final Random random = new Random();
|
||||
|
||||
private final int length;
|
||||
private final int count;
|
||||
|
||||
public String generate() {
|
||||
char[] buffer = new char[length * count + (count - 1)];
|
||||
for (int index = 0, offset = 0; index < buffer.length; index++) {
|
||||
if (offset == length) {
|
||||
buffer[index] = '-';
|
||||
offset = 0;
|
||||
} else {
|
||||
buffer[index] = CHARS[random.nextInt(CHARS.length)];
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
return new String(buffer);
|
||||
}
|
||||
}
|
79
src/main/java/ee/yoursit/core/util/Message.java
Normal file
79
src/main/java/ee/yoursit/core/util/Message.java
Normal file
|
@ -0,0 +1,79 @@
|
|||
package ee.yoursit.core.util;
|
||||
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.md_5.bungee.api.chat.*;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Message {
|
||||
private final TextComponent component;
|
||||
|
||||
public Message(String message, Object... args) {
|
||||
component = new TextComponent(translate(message, args));
|
||||
}
|
||||
|
||||
public Message() {
|
||||
component = new TextComponent();
|
||||
}
|
||||
|
||||
public Message click(ClickAction action, String message, Object... args) {
|
||||
ClickEvent.Action clickAction = ClickEvent.Action.valueOf(action.name());
|
||||
component.setClickEvent(new ClickEvent(clickAction, translate(message, args)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Message click(String command, Object... args) {
|
||||
return click(ClickAction.RUN_COMMAND, command, args);
|
||||
}
|
||||
|
||||
public Message hover(HoverAction action, String message, Object... args) {
|
||||
HoverEvent.Action hoverAction = HoverEvent.Action.valueOf(action.name());
|
||||
BaseComponent[] data = new ComponentBuilder(translate(message, args)).create();
|
||||
component.setHoverEvent(new HoverEvent(hoverAction, data));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Message hover(String message, Object... args) {
|
||||
return hover(HoverAction.SHOW_TEXT, message, args);
|
||||
}
|
||||
|
||||
public Message add(String message, Object... args) {
|
||||
component.addExtra(translate(message, args));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Message add(Message message) {
|
||||
component.addExtra(message.component);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void send(Player player) {
|
||||
player.spigot().sendMessage(component);
|
||||
}
|
||||
|
||||
public void send(CommandSender sender) {
|
||||
if (sender instanceof Player)
|
||||
((Player) sender).spigot().sendMessage(component);
|
||||
else
|
||||
sender.sendMessage(component.toLegacyText());
|
||||
}
|
||||
|
||||
public static String translate(String message, Object... args) {
|
||||
message = String.format(message, args);
|
||||
|
||||
Pattern pattern = Pattern.compile("#[a-fA-F0-9]{6}");
|
||||
Matcher matcher = pattern.matcher(message);
|
||||
|
||||
while (matcher.find()) {
|
||||
String color = message.substring(matcher.start(), matcher.end());
|
||||
message = message.replace(color, String.valueOf(ChatColor.of(color)));
|
||||
matcher = pattern.matcher(message);
|
||||
}
|
||||
|
||||
return ChatColor.translateAlternateColorCodes('&', message);
|
||||
}
|
||||
}
|
||||
|
23
src/main/resources/config.yml
Normal file
23
src/main/resources/config.yml
Normal file
|
@ -0,0 +1,23 @@
|
|||
bot-token: 'AAAA-AAAA-AAAA-AAAA'
|
||||
|
||||
spawn:
|
||||
==: org.bukkit.Location
|
||||
world: world
|
||||
x: 100.0
|
||||
y: 100.0
|
||||
z: 100.0
|
||||
yaw: 0.0
|
||||
pitch: 0.0
|
||||
|
||||
verify:
|
||||
==: org.bukkit.Location
|
||||
world: verification
|
||||
x: 0.0
|
||||
y: 57.0
|
||||
z: 0.0
|
||||
yaw: 0.0
|
||||
pitch: 0.0
|
||||
|
||||
verify-timeout: 60
|
||||
|
||||
ysmp-invite: "https://discord.gg/3sdUGhNNHp"
|
107
src/main/resources/messages.yml
Normal file
107
src/main/resources/messages.yml
Normal file
|
@ -0,0 +1,107 @@
|
|||
internal-error: "&c&lERROR &7An internal error occurred whilst trying to perform this command"
|
||||
|
||||
player-join: "&a● &f{player}"
|
||||
player-leave: "&c● &f{player}"
|
||||
|
||||
player-not-online: "&c{player} is not online"
|
||||
no-players-online: "There are no online players at the moment"
|
||||
not-a-user: "You are not a registered YSMP user"
|
||||
already-user: "You are already a member of the YourSitee SMP"
|
||||
|
||||
banned-from-server: "&c&lUnable to connect\n&7You have been banned from the server"
|
||||
not-whitelisted: "&c&lERROR\n&7You are not whitelisted on this server"
|
||||
unable-to-fetch: "&c&lERROR\n&7Unable to fetch player data\nTry again later"
|
||||
|
||||
invite:
|
||||
limit-exceeded: "You have exceeded your invite creation limit"
|
||||
not-found: "The specified invite does not exist or has been already used"
|
||||
not-on-guild: "You can only accept invites in the YSMP discord server"
|
||||
not-joined-guild: "&c&lERROR &7You need to join the YSMP discord server to be able to verify"
|
||||
verification: "In order to verify your Minecraft username, you need to join `smp.yoursit.ee` and type in the following command: ```/verify {code}```"
|
||||
use-verify: "&6&lVERIFY &7Type &f/verify <your code> &7in order to gain access for the server"
|
||||
verify-timeout: "&c&lVERIFY\n&7You have exceeded the verification timeout"
|
||||
verified: "&6&lYSMP &7You are now eligible to play on the YourSitee SMP server\n"
|
||||
already-verified: "&c&lERROR &7You are already verified"
|
||||
already-verifying: "This invite is already being verified by another user"
|
||||
already-verifying-self: "You are already in the verification process"
|
||||
invalid-code: "&c&lERROR\n&7The specified invite does not exist or has been already used"
|
||||
|
||||
teleport-request:
|
||||
send: "&6&lTELEPORT &fYou have sent a teleport request to &e{player}"
|
||||
receive: "&6&lTELEPORT &e{player} &fhas sent you a teleport request"
|
||||
usage: "&c&lUSAGE &7/tpa <player>"
|
||||
already: "&c&lERROR &7You have already sent a teleport request to &f{player}"
|
||||
|
||||
teleport-accept:
|
||||
send: "&6&lTELEPORT &fyou have accepted &e{player}&f's teleport request"
|
||||
receive: "&6&lTELEPORT &e{player} &faccepted your teleport request"
|
||||
|
||||
teleport-decline:
|
||||
send: "&6&lTELEPORT &fyou have decliend &e{player}&f's teleport request"
|
||||
receive: "&6&lTELEPORT &e{player} &fhas declined your teleport request"
|
||||
|
||||
teleport:
|
||||
no-requests: "&c&lERROR &7You don't have any teleport requests"
|
||||
no-request-from: "&c&lERROR &f{player} did not send you a teleport request"
|
||||
|
||||
private-message:
|
||||
send: "&6&lFROM &e{player} &8► &f{message}"
|
||||
receive: "&6&lTO &e{player} &8► &f{message}"
|
||||
usage: "&c&lUSAGE &7/msg <player> <message>"
|
||||
no-open-channels: "&c&lERROR &7You don't have any private message channels open right now"
|
||||
|
||||
home:
|
||||
updated: "&6&lHOME &7You have successfully assigned a new home location"
|
||||
teleporting: "&6&lHOME &7Teleporting to home"
|
||||
not-set: "&c&lERROR &7You don't have a home location set"
|
||||
deleted: "&6&lHOME &7You have successfully deleted your home location"
|
||||
|
||||
auto-sleep: "&6&lYSMP &7More than 2/3 of the players are sleeping. Switching to day..."
|
||||
|
||||
activity:
|
||||
players: "{count} online players"
|
||||
discord: "yoursit.ee/smp"
|
||||
address: "smp.yoursit.ee"
|
||||
|
||||
no-such-user: "&c&lERROR &7No such user &7{name}"
|
||||
no-permission: "&c&lERROR &7You don't have permission to use this command"
|
||||
|
||||
group:
|
||||
not-exists: "&c&lERROR &7Group &f{group} &7does not exist"
|
||||
usage: "&c&lUSAGE &7/group <create|delete|list|group> <meta|permission|grant> [...args]"
|
||||
create:
|
||||
usage: "&c&lUSAGE &7/group create <name>"
|
||||
already-exists: "&c&lERROR &7Group &f{group} &7already exists"
|
||||
created: "&6&lGROUP &7Successfully created group &f{group}"
|
||||
delete:
|
||||
usage: "&c&lUSAGE &7/group delete <name>"
|
||||
not-exists: "&c&lERROR &7Group &f{group} &7does not exist"
|
||||
deleted: "&6&lGROUP &7Group &f{group} &7has been deleted"
|
||||
list: "&6&lGROUP &7Available groups: &f{list}"
|
||||
no-groups: "&6&lGROUP &7There are no available groups yet"
|
||||
meta:
|
||||
usage: "&c&lUSAGE &7/group <group> meta <prefix|suffix|tabprefix|tabsuffix> [..args]"
|
||||
info: "&6&lGROUP &7Group &f{group} &7meta information:\n &7prefix: &r{prefix}\n &7suffix: &r{suffix}\n &7tab prefix: &r{tabprefix}\n &7tab suffix: &r{tabsuffix}"
|
||||
prefix:
|
||||
usage: "&c&lUSAGE &7/group <group> meta prefix <prefix>"
|
||||
set: "&6&lGROUP &7Updated group &f{group} &7prefix to &r{prefix}"
|
||||
suffix:
|
||||
usage: "&c&lUSAGE &7/group <group> meta suffix <suffix>"
|
||||
set: "&6&lGROUP &7Updated group &f{group} &7suffix to &r{suffix}"
|
||||
tab-prefix:
|
||||
usage: "&c&lUSAGE &7/group <group> meta tabprefix <prefix>"
|
||||
set: "&6&lGROUP &7Updated group &f{group} &7tab prefix to &r{tabprefix}"
|
||||
tab-suffix:
|
||||
usage: "&c&lUSAGE &7/group <group> meta tabsuffix <suffix>"
|
||||
set: "&6&lGROUP &7Updated group &f{group} &7tab suffix to &r{tabsuffix}"
|
||||
permission:
|
||||
usage: "&c&lUSAGE &7/group <group> permission <set|unset> [..args]"
|
||||
set:
|
||||
usage: "&c&lUSAGE &7/group <group> permission set <permission> <state>"
|
||||
updated: "&6&lGROUP &7Set group &f{group} &7permission &f{permission} &7to &f{state}"
|
||||
unset:
|
||||
usage: "&c&lUSAGE &7/group <group> permission unset <permission>"
|
||||
updated: "&6&lGROUP &7Unset group &f{group} &7permission &f{permission}"
|
||||
grant:
|
||||
usage: "&c&lUSAGE &7/group <group> grant <user>"
|
||||
granted: "&6&lGROUP &7Granted group &f{group} &7to player &f{player}"
|
38
src/main/resources/plugin.yml
Normal file
38
src/main/resources/plugin.yml
Normal file
|
@ -0,0 +1,38 @@
|
|||
name: ysmp-core
|
||||
version: 0.1.1
|
||||
main: ee.yoursit.core.Main
|
||||
author: AdvancedAntiSkid
|
||||
website: yoursit.ee
|
||||
api-version: 1.20
|
||||
softdepend:
|
||||
- Multiverse-Core
|
||||
|
||||
commands:
|
||||
tpa:
|
||||
usage: Send a teleportation request to the specified player
|
||||
tpaccept:
|
||||
usage: Accept the teleportation request of a player
|
||||
tpdeny:
|
||||
usage: Decline the teleportation request of a player
|
||||
message:
|
||||
usage: Send a private message to a player
|
||||
aliases:
|
||||
- msg
|
||||
- m
|
||||
- pm
|
||||
- dm
|
||||
reply:
|
||||
usage: Reply to the private message to a player
|
||||
aliases:
|
||||
- repl
|
||||
- r
|
||||
sethome:
|
||||
usage: Update your home location
|
||||
delhome:
|
||||
usage: Delete your home location
|
||||
home:
|
||||
usage: Teleport to your home location
|
||||
verify:
|
||||
usage: Verify invitation code
|
||||
group:
|
||||
usage: Manage groups and permissions
|
9
src/test/java/GeneratorTest.java
Normal file
9
src/test/java/GeneratorTest.java
Normal file
|
@ -0,0 +1,9 @@
|
|||
import ee.yoursit.core.util.InviteGenerator;
|
||||
|
||||
public class GeneratorTest {
|
||||
public static void main(String[] args) {
|
||||
InviteGenerator generator = new InviteGenerator(5, 4);
|
||||
String invite = generator.generate();
|
||||
System.out.println(invite);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue