Update to v0.2 #2

Merge aplicado
Awakened-Redstone mesclou 5 commits from development into master 2025-07-24 04:34:53 +00:00
35 arquivos alterados com 1493 adições e 676 exclusões
Mostrando apenas as alterações do commit baa2bb701c - Mostrar todos os commits

Update to v0.2

Luna Fox 2021-03-18 18:44:35 -03:00

Ver arquivo

@ -5,6 +5,7 @@ plugins {
repositories {
mavenCentral()
jcenter()
maven { url 'https://jitpack.io' }
}
archivesBaseName = project.archives_base_name
@ -18,15 +19,22 @@ dependencies {
minecraft "com.mojang:minecraft:${project.minecraft_version}"
mappings "net.fabricmc:yarn:${project.yarn_mappings}:v2"
modImplementation "net.fabricmc:fabric-loader:${project.loader_version}"
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
//modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}"
include(modImplementation(fabricApi.module("fabric-lifecycle-events-v1", project.fabric_version)))
include(modImplementation(fabricApi.module("fabric-api-base", project.fabric_version)))
implementation include("org.xerial:sqlite-jdbc:3.34.0")
implementation include("com.jagrosh:jda-utilities-command:3.0.5")
implementation include("com.jagrosh:jda-utilities-commons:3.0.5")
implementation include("com.jagrosh:jda-utilities-menu:3.0.5")
implementation include("com.jagrosh:jda-utilities-examples:3.0.5")
implementation include("com.jagrosh:jda-utilities-doc:3.0.5")
implementation include('net.dv8tion:JDA:4.2.0_231') {
exclude module: 'opus-java'
}
implementation include('org.apache.logging.log4j:log4j-slf4j-impl:2.8.1')
include "net.sf.trove4j:trove4j:3.0.3"
include 'org.slf4j:slf4j-nop:1.7.25'
include 'org.slf4j:slf4j-api:1.7.25'
include 'org.apache.commons:commons-collections4:4.1'
include 'com.neovisionaries:nv-websocket-client:2.10'
@ -35,7 +43,6 @@ dependencies {
include 'com.fasterxml.jackson.core:jackson-databind:2.10.1'
include 'com.fasterxml.jackson.core:jackson-annotations:2.10.1'
include 'com.fasterxml.jackson.core:jackson-core:2.10.1'
}
compileJava {

Ver arquivo

@ -1,10 +1,9 @@
org.gradle.jvmargs=-Xmx1G
minecraft_version=21w08b
yarn_mappings=21w08b+build.2
loader_version=0.11.2
mod_version=0.1.3
minecraft_version=21w10a
yarn_mappings=21w10a+build.10
loader_version=0.11.3
mod_version=0.2
maven_group=com.awakenedredstone
archives_base_name=autowhitelist
fabric_version=0.31.1+1.17
build_version=0
fabric_version=0.32.2+1.17

Ver arquivo

@ -3,32 +3,44 @@ package com.awakenedredstone.autowhitelist;
import com.awakenedredstone.autowhitelist.config.Config;
import com.awakenedredstone.autowhitelist.config.ConfigData;
import com.awakenedredstone.autowhitelist.json.JsonHelper;
import com.awakenedredstone.autowhitelist.database.SQLite;
import com.awakenedredstone.autowhitelist.util.MemberPlayer;
import com.awakenedredstone.autowhitelist.lang.JigsawLanguage;
import com.awakenedredstone.autowhitelist.mixin.ServerConfigEntryMixin;
import com.awakenedredstone.autowhitelist.server.AutoWhitelistServer;
import com.awakenedredstone.autowhitelist.util.ExtendedGameProfile;
import com.awakenedredstone.autowhitelist.util.InvalidTeamNameException;
import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelist;
import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelistEntry;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.mojang.authlib.GameProfile;
import net.fabricmc.api.ModInitializer;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.scoreboard.Team;
import net.minecraft.server.*;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.WhitelistEntry;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.awakenedredstone.autowhitelist.lang.JigsawLanguage.translations;
public class AutoWhitelist implements ModInitializer {
public static Thread scheduledUpdateThread;
public static MinecraftServer server;
public static final Config config = new Config();
public static final Logger logger = LogManager.getLogger("AutoWhitelist");
public static final Logger LOGGER = LogManager.getLogger("AutoWhitelist");
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
private static final File configFile = new File(config.getConfigDirectory(), "AutoWhitelist.json");
@ -38,98 +50,89 @@ public class AutoWhitelist implements ModInitializer {
}
public static void updateWhitelist() {
logger.info("Updating whitelist.");
PlayerManager playerManager = server.getPlayerManager();
Whitelist whitelist = playerManager.getWhitelist();
List<String> usernames = new SQLite().getUsernames();
ExtendedWhitelist whitelist = (ExtendedWhitelist) playerManager.getWhitelist();
Scoreboard scoreboard = server.getScoreboard();
Collection<? extends WhitelistEntry> entries = whitelist.getEntries();
for (Map.Entry<String, JsonElement> entry : AutoWhitelist.config.getConfigs().get("whitelist").getAsJsonObject().entrySet()) {
Scoreboard scoreboard = server.getScoreboard();
Team team = scoreboard.getTeam(entry.getKey());
List<GameProfile> profiles = entries.stream().map(v -> {
((ServerConfigEntryMixin<?>) v).callGetKey();
return (GameProfile) ((ServerConfigEntryMixin<?>) v).getKey();
}).collect(Collectors.toList());
for (GameProfile profile : profiles) {
GameProfile profile1 = server.getUserCache().getByUuid(profile.getId());
try {
if (profile1 == null) {
removePlayer((ExtendedGameProfile) profile);
continue;
}
} catch (ClassCastException ignored) {
whitelist.remove(profile);
scoreboard.clearPlayerTeam(profile.getName());
continue;
}
if (!profile.getName().equals(profile1.getName())) {
try {
ExtendedGameProfile isExtended = (ExtendedGameProfile) profile;
whitelist.remove(isExtended);
whitelist.add(new ExtendedWhitelistEntry(new ExtendedGameProfile(profile1.getId(), profile1.getName(), isExtended.getTeam(), isExtended.getDiscordId())));
} catch (ClassCastException ignored) {
whitelist.remove(profile);
whitelist.add(new WhitelistEntry(profile1));
}
}
}
List<ExtendedGameProfile> extendedProfiles = profiles.stream().map(v -> {
try {
return (ExtendedGameProfile) v;
} catch (ClassCastException e) {
return null;
}
}).filter(Objects::nonNull).collect(Collectors.toList());
getConfigData().whitelist.keySet().forEach(teamName -> {
Team team = scoreboard.getTeam(teamName);
if (team == null) {
logger.error("Could not update whitelist, got null Team!");
LOGGER.error("Could not check for invalid players on team \"{}\", got \"null\" when trying to get \"net.minecraft.scoreboard.Team\" from \"{}\"", teamName, teamName, new InvalidTeamNameException("Tried to get \"net.minecraft.scoreboard.Team\" from \"" + teamName + "\" but got \"null\"."));
return;
}
List<String> invalidPlayers = team.getPlayerList().stream().filter(player -> {
try {
GameProfile profile = new GameProfile(UUID.fromString(getUUID(player)), player);
return !usernames.contains(player) && !playerManager.isOperator(profile);
} catch (Exception e) {
logger.error("Failed to update whitelist!", e);
return false;
}
GameProfile profile = profiles.stream().filter(v -> v.getName().equals(player)).findFirst().orElse(null);
if (profile == null) return true;
return !whitelist.isAllowed(profile);
}).collect(Collectors.toList());
invalidPlayers.forEach(player -> scoreboard.removePlayerFromTeam(player, team));
}
});
try {
for (String username : playerManager.getWhitelistedNames()) {
GameProfile profile = new GameProfile(UUID.fromString(getUUID(username)), username);
if (!usernames.contains(username) && !playerManager.isOperator(profile)) {
whitelist.remove(new WhitelistEntry(profile));
}
}
} catch (Exception e) {
logger.error("Failed to update whitelist!", e);
return;
}
Scoreboard scoreboard = server.getScoreboard();
for (MemberPlayer player : new SQLite().getMembers()) {
for (ExtendedGameProfile player : extendedProfiles) {
if (player == null) continue;
Team team = scoreboard.getTeam(player.getTeam());
if (team == null) {
logger.error("Could not update whitelist, got null Team!");
LOGGER.error("Could not check team information of \"{}\", got \"null\" when trying to get \"net.minecraft.scoreboard.Team\" from \"{}\"", player.getName(), player.getTeam(), new InvalidTeamNameException("Tried to get \"net.minecraft.scoreboard.Team\" from \"" + player.getTeam() + "\" but got \"null\"."));
return;
}
if (!whitelist.isAllowed(player.getProfile())) {
whitelist.add(new WhitelistEntry(player.getProfile()));
}
if (scoreboard.getPlayerTeam(player.getProfile().getName()) != team) {
scoreboard.addPlayerToTeam(player.getProfile().getName(), team);
if (scoreboard.getPlayerTeam(player.getName()) != team) {
scoreboard.clearPlayerTeam(player.getName());
scoreboard.addPlayerToTeam(player.getName(), team);
}
}
logger.info("Whitelist update complete.");
server.kickNonWhitelistedPlayers(server.getCommandSource());
}
public static void removePlayer(GameProfile player) {
public static void removePlayer(ExtendedGameProfile player) {
if (server.getPlayerManager().getWhitelist().isAllowed(player)) {
server.getPlayerManager().getWhitelist().remove(new WhitelistEntry(player));
server.getPlayerManager().getWhitelist().remove(new ExtendedWhitelistEntry(player));
Scoreboard scoreboard = server.getScoreboard();
scoreboard.clearPlayerTeam(player.getName());
}
}
private static String getUUID(String username) throws Exception {
URL url = new URL(String.format("https://api.mojang.com/users/profiles/minecraft/%s", username));
try (InputStream is = url.openStream()) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String jsonText = readAll(rd);
JsonParser parser = new JsonParser();
JsonElement json = parser.parse(jsonText);
String _uuid = json.getAsJsonObject().get("id").getAsString();
if (_uuid.length() != 32) throw new IllegalArgumentException("Invalid UUID string:" + _uuid);
String[] split = new String[]{_uuid.substring(0, 8), _uuid.substring(8, 12), _uuid.substring(12, 16), _uuid.substring(16, 20), _uuid.substring(20, 32)};
StringBuilder uuid_ = new StringBuilder(36);
uuid_.append(split[0]).append("-");
uuid_.append(split[1]).append("-");
uuid_.append(split[2]).append("-");
uuid_.append(split[3]).append("-");
uuid_.append(split[4]);
return uuid_.toString();
}
}
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
@Override
public void onInitialize() {
File dir = config.getConfigDirectory();
@ -139,7 +142,28 @@ public class AutoWhitelist implements ModInitializer {
}
}
config.loadConfigs();
}
public static void reloadTranslations() {
try {
translations.clear();
{
InputStream inputStream = AutoWhitelistServer.class.getResource("/messages.json").openStream();
JigsawLanguage.load(inputStream, translations::put);
}
File file = new File(config.getConfigDirectory(), "AutoWhitelist-assets/messages.json");
File folder = new File(config.getConfigDirectory(), "AutoWhitelist-assets");
if (!folder.exists()) {
folder.mkdir();
}
if (!file.exists()) {
Files.copy(AutoWhitelistServer.class.getResource("/messages.json").openStream(), file.toPath());
}
InputStream inputStream = Files.newInputStream(file.toPath());
JigsawLanguage.load(inputStream, translations::put);
} catch (IOException ignored) {
}
}
}

Ver arquivo

@ -2,53 +2,62 @@ package com.awakenedredstone.autowhitelist.commands;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.discord.Bot;
import com.awakenedredstone.autowhitelist.database.SQLite;
import com.awakenedredstone.autowhitelist.util.MemberPlayer;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import net.minecraft.command.CommandSource;
import net.minecraft.server.command.CommandManager;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.LiteralText;
import java.util.List;
import static com.awakenedredstone.autowhitelist.util.Debugger.analyzeTimings;
public class AutoWhitelistCommand {
public static void register(CommandDispatcher<ServerCommandSource> dispatcher) {
dispatcher.register(CommandManager.literal("auto-whitelist").requires((source) -> {
return source.hasPermissionLevel(4);
}).then(CommandManager.literal("reload").executes((source) -> {
}).then((CommandManager.literal("reload").executes((source) -> {
executeReload(source.getSource());
return 0;
})).then(CommandManager.literal("remove").then(CommandManager.argument("target", StringArgumentType.word()).suggests((commandContext, suggestionsBuilder) -> {
List<GameProfile> players = new SQLite().getPlayers();
return CommandSource.suggestMatching(players.stream().map(GameProfile::getName), suggestionsBuilder);
}).executes((commandContext) -> {
return executeAdd((ServerCommandSource) commandContext.getSource(), StringArgumentType.getString(commandContext, "target"));
})).then(CommandManager.literal("bot").executes((source) -> {
executeSpecificReload(source.getSource(), ReloadableObjects.BOT);
return 0;
})).then(CommandManager.literal("config").executes((source) -> {
executeSpecificReload(source.getSource(), ReloadableObjects.CONFIG);
return 0;
})).then(CommandManager.literal("translations").executes((source) -> {
executeSpecificReload(source.getSource(), ReloadableObjects.TRANSLATIONS);
return 0;
}))));
}
private static int executeAdd(ServerCommandSource source, String target) {
MemberPlayer member = new SQLite().getMemberByNick(target);
GameProfile profile = member.getProfile();
boolean success = new SQLite().removeMemberByNick(target);
if (success)
AutoWhitelist.removePlayer(profile);
if (success) {
source.sendFeedback(new LiteralText(String.format("Removed %s from the database. Whitelist has been updated.", target)), true);
return 1;
} else {
source.sendFeedback(new LiteralText(String.format("Failed to remove %s from the database.", target)), true);
return 0;
public static void executeReload(ServerCommandSource source) {
source.sendFeedback(new LiteralText("Reloading AutoWhitelist configurations, please wait."), true);
analyzeTimings("Config#loadConfigs", AutoWhitelist.config::loadConfigs);
analyzeTimings("AutoWhitelist#reloadTranslations", AutoWhitelist::reloadTranslations);
source.sendFeedback(new LiteralText("Restarting bot, please wait."), true);
analyzeTimings("Bot#reloadBot", () -> Bot.getInstance().reloadBot(source));
}
public static void executeSpecificReload(ServerCommandSource source, ReloadableObjects type) {
switch (type) {
case BOT:
source.sendFeedback(new LiteralText("Restarting bot, please wait."), true);
analyzeTimings("Bot#reloadBot", () -> Bot.getInstance().reloadBot(source));
break;
case CONFIG:
source.sendFeedback(new LiteralText("Reloading configurations."), true);
analyzeTimings("Config#loadConfigs", AutoWhitelist.config::loadConfigs);
break;
case TRANSLATIONS:
source.sendFeedback(new LiteralText("Reloading translations."), true);
analyzeTimings("AutoWhitelist#reloadTranslations", AutoWhitelist::reloadTranslations);
break;
}
}
public static void executeReload(ServerCommandSource source) {
AutoWhitelist.logger.warn("Reloading configurations, please wait.");
source.sendFeedback(new LiteralText("Reloading AutoWhitelist configurations, please wait."), true);
AutoWhitelist.config.loadConfigs();
Bot.getInstance().reloadBot(source);
private enum ReloadableObjects {
BOT,
CONFIG,
TRANSLATIONS
}
}

Ver arquivo

@ -3,18 +3,20 @@ package com.awakenedredstone.autowhitelist.config;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.json.JsonHelper;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import net.minecraft.text.LiteralText;
import java.io.*;
import java.nio.file.Files;
import java.util.stream.Collectors;
public class Config {
private JsonObject config;
private ConfigData configData;
private final File configFile = new File(getConfigDirectory(), "AutoWhitelist.json");
private final int configVersion = 2;
public File getConfigDirectory() {
return new File(".", "config");
@ -25,23 +27,46 @@ public class Config {
try (BufferedReader reader = new BufferedReader(new FileReader(configFile))) {
String json = reader.lines().collect(Collectors.joining("\n"));
StringReader stringReader = new StringReader(json);
JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
if (jsonObject.get("version") == null || jsonObject.get("version").getAsInt() != configVersion) {
Files.copy(configFile.toPath(), new File(getConfigDirectory(), "AutoWhitelist_old.json").toPath());
JsonObject newJson = new JsonObject();
newJson.add("version", new JsonPrimitive(configVersion));
newJson.add("whitelistScheduledVerificationSeconds", jsonObject.get("whitelist-auto-update-delay-seconds"));
newJson.add("prefix", jsonObject.get("prefix"));
newJson.add("token", jsonObject.get("token"));
newJson.add("clientId", jsonObject.get("application-id"));
newJson.add("discordServerId", jsonObject.get("discord-server-id"));
newJson.add("whitelist", jsonObject.get("whitelist"));
JsonHelper.writeJsonToFile(newJson, configFile);
}
configData = AutoWhitelist.GSON.fromJson(stringReader, ConfigData.class);
if (configData.whitelistScheduledVerificationSeconds < 30) {
AutoWhitelist.LOGGER.warn("Whitelist scheduled verification time is really low. It is not recommended to have it lower than 30 seconds, since it can affect the server performance.");
AutoWhitelist.server.getCommandSource().sendFeedback(new LiteralText("Whitelist scheduled verification time is really low. It is not recommended to have it lower than 30 seconds, since it can affect the server performance."), true);
}
} catch (IOException e) {
e.printStackTrace();
AutoWhitelist.LOGGER.error(e);
}
}
}
public JsonObject generateDefaultConfig() {
JsonObject json = new JsonObject();
json.add("whitelistAutoUpdateDelaySeconds", new JsonPrimitive(60L));
json.add("version", new JsonPrimitive(configVersion));
json.add("whitelistScheduledVerificationSeconds", new JsonPrimitive(60L));
json.add("prefix", new JsonPrimitive("np!"));
json.add("token", new JsonPrimitive("bot-token"));
json.add("clientId", new JsonPrimitive("client-id"));
json.add("discordServerId", new JsonPrimitive("discord-server-id"));
JsonObject whitelistJson = JsonHelper.getNestedObject(json, "whitelist", true);
if (whitelistJson == null) {
AutoWhitelist.logger.error("Something went wrong when generating the default config file!");
AutoWhitelist.LOGGER.error("Something went wrong when generating the default config file!");
return json;
}
@ -61,11 +86,8 @@ public class Config {
return json;
}
public JsonObject getConfigs() {
return config;
}
public ConfigData getConfigData() {
return configData;
}
}

Ver arquivo

@ -5,10 +5,10 @@ import java.util.Map;
public class ConfigData {
public long whitelistAutoUpdateDelaySeconds;
public long whitelistScheduledVerificationSeconds;
public String prefix;
public String token;
public String applicationId;
public String clientId;
public String discordServerId;
public Map<String, List<String>> whitelist;
}

Ver arquivo

@ -1,4 +0,0 @@
package com.awakenedredstone.autowhitelist.database;
public class JsonDatabase {
}

Ver arquivo

@ -1,231 +1,58 @@
package com.awakenedredstone.autowhitelist.database;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.util.MemberPlayer;
import com.mojang.authlib.GameProfile;
import com.awakenedredstone.autowhitelist.util.ExtendedGameProfile;
import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelistEntry;
import net.minecraft.server.MinecraftServer;
import java.io.File;
import java.sql.*;
import java.util.*;
import java.util.ArrayList;
import java.util.UUID;
public class SQLite {
public static Connection connection;
private static Connection connection;
public void connect() {
File dir = new File("./config/AutoWhitelist");
if(!dir.exists() || !dir.isDirectory()) {
AutoWhitelist.logger.info("Could not find database. A new one will be created.");
dir.mkdir();
//AutoWhitelist.LOGGER.info("Could not find database. A new one will be created.");
return;
}
File file = new File("./config/AutoWhitelist/users.db");
if (!file.exists()) return;
try {
String url = "jdbc:sqlite:config/AutoWhitelist/users.db";
connection = DriverManager.getConnection(url);
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to load database", e);
AutoWhitelist.LOGGER.error("Failed to load old database", e);
return;
}
try {
Statement statement = connection.createStatement();
statement.execute("CREATE TABLE IF NOT EXISTS \"data\" (" +
"\"ID\" TEXT NOT NULL UNIQUE, " +
"\"UUID\" TEXT NOT NULL UNIQUE, " +
"\"USERNAME\" TEXT NOT NULL UNIQUE, " +
"\"TEAM\" TEXT NOT NULL)");
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to load database!", e);
}
databaseChange();
}
public void updateData(String id, String username, String uuid, String team) {
private void databaseChange() {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
AutoWhitelist.LOGGER.error("Connection to database not existent. Unable to query data.");
return;
}
try {
PreparedStatement statement = connection.prepareStatement("UPDATE `data` SET \"USERNAME\"=?, \"TEAM\"=? WHERE \"ID\"=? AND \"UUID\"=?");
statement.setString(1, username);
statement.setString(2, team);
statement.setString(3, id);
statement.setString(4, uuid);
statement.executeUpdate();
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to update the database!", e);
}
}
public void updateData(String id, String username, String uuid) {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
return;
}
try {
PreparedStatement statement = connection.prepareStatement("UPDATE `data` SET \"USERNAME\"=? WHERE \"ID\"=? AND \"UUID\"=?");
statement.setString(1, username);
statement.setString(2, id);
statement.setString(3, uuid);
statement.executeUpdate();
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to update the database!", e);
}
}
public List<String> getIds() {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
return Collections.emptyList();
}
try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM `data`");
ResultSet results = statement.executeQuery();
ArrayList<String> ids = new ArrayList<>();
ArrayList<ExtendedGameProfile> players = new ArrayList<>();
while (results.next()) {
ids.add(results.getString("ID"));
players.add(new ExtendedGameProfile(UUID.fromString(results.getString("UUID")), results.getString("USERNAME"), results.getString("TEAM"), results.getString("ID")));
}
return ids;
AutoWhitelist.server.getPlayerManager().getWhitelist().values().clear();
players.forEach(v -> AutoWhitelist.server.getPlayerManager().getWhitelist().add(new ExtendedWhitelistEntry(v)));
connection.close();
new File("./config/AutoWhitelist/users.db").delete();
new File("./config/AutoWhitelist").delete();
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to get the data from the database!", e);
return Collections.emptyList();
}
}
public List<MemberPlayer> getMembers() {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
return Collections.emptyList();
}
try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM `data`");
ResultSet results = statement.executeQuery();
ArrayList<MemberPlayer> players = new ArrayList<>();
while (results.next()) {
players.add(new MemberPlayer(new GameProfile(UUID.fromString(results.getString("UUID")), results.getString("USERNAME")), results.getString("TEAM"), results.getString("ID")));
}
return players;
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to get the data from the database!", e);
return Collections.emptyList();
}
}
public List<GameProfile> getPlayers() {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
return Collections.emptyList();
}
try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM `data`");
ResultSet results = statement.executeQuery();
ArrayList<GameProfile> players = new ArrayList<>();
while (results.next()) {
players.add(new GameProfile(UUID.fromString(results.getString("UUID")), results.getString("USERNAME")));
}
return players;
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to get the data from the database!", e);
return Collections.emptyList();
}
}
public List<String> getUsernames() {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
return Collections.emptyList();
}
try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM `data`");
ResultSet results = statement.executeQuery();
ArrayList<String> usernames = new ArrayList<>();
while (results.next()) {
usernames.add(results.getString("USERNAME"));
}
return usernames;
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to get the data from the database!", e);
return Collections.emptyList();
}
}
public MemberPlayer getMemberByNick(String nickname) {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
return null;
}
try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM `data` WHERE \"USERNAME\"=?");
statement.setString(1, nickname);
ResultSet results = statement.executeQuery();
results.next();
return new MemberPlayer(new GameProfile(UUID.fromString(results.getString("UUID")), results.getString("USERNAME")), results.getString("TEAM"), results.getString("ID"));
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to get the data from the database!", e);
return null;
}
}
public void addMember(String id, String username, String uuid, String team) {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
return;
}
try {
PreparedStatement statement = connection.prepareStatement("INSERT INTO `data` VALUES (?,?,?,?)");
statement.setString(1, id);
statement.setString(2, uuid);
statement.setString(3, username);
statement.setString(4, team);
statement.executeUpdate();
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to update the database!", e);
}
}
public boolean removeMemberById(String id) {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
return false;
}
try {
PreparedStatement statement = connection.prepareStatement("DELETE FROM `data` WHERE \"ID\"=?");
statement.setString(1, id);
statement.executeUpdate();
return true;
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to update the database!", e);
return false;
}
}
public boolean removeMemberByNick(String nickname) {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
return false;
}
try {
PreparedStatement statement = connection.prepareStatement("DELETE FROM `data` WHERE \"USERNAME\"=?");
statement.setString(1, nickname);
statement.executeUpdate();
return true;
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to update the database!", e);
return false;
}
}
public boolean removeMemberByUuid(String uuid) {
if (connection == null) {
AutoWhitelist.logger.error("Connection to database not existent. Unable to query data.");
return false;
}
try {
PreparedStatement statement = connection.prepareStatement("DELETE FROM `data` WHERE \"UUID\"=?");
statement.setString(1, uuid);
statement.executeUpdate();
return true;
} catch (SQLException e) {
AutoWhitelist.logger.error("Failed to update the database!", e);
return false;
AutoWhitelist.LOGGER.error("Failed to get the data from the old database", e);
}
}
}

Ver arquivo

@ -1,87 +1,43 @@
package com.awakenedredstone.autowhitelist.discord;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.database.SQLite;
import com.awakenedredstone.autowhitelist.util.InvalidResultException;
import com.awakenedredstone.autowhitelist.util.MemberPlayer;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.mojang.authlib.GameProfile;
import net.dv8tion.jda.api.EmbedBuilder;
import com.awakenedredstone.autowhitelist.lang.TranslatableText;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.events.ReadyEvent;
import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent;
import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.requests.restaction.MessageAction;
import net.dv8tion.jda.api.utils.MemberCachePolicy;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.scoreboard.Team;
import net.minecraft.server.WhitelistEntry;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.LiteralText;
import org.jetbrains.annotations.NotNull;
import net.minecraft.util.logging.UncaughtExceptionHandler;
import javax.security.auth.login.LoginException;
import java.io.*;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
public class Bot extends ListenerAdapter {
public class Bot implements Runnable {
private static Bot instance;
static ScheduledFuture<?> scheduledUpdate;
static JDA jda = null;
private static String token = AutoWhitelist.config.getConfigs().get("token").getAsString();
private static String appId = AutoWhitelist.config.getConfigs().get("application-id").getAsString();
static String serverId = AutoWhitelist.config.getConfigs().get("discord-server-id").getAsString();
static String prefix = AutoWhitelist.config.getConfigs().get("prefix").getAsString();
static long updateDelay = AutoWhitelist.config.getConfigs().get("whitelist-auto-update-delay-seconds").getAsLong();
public Bot() {
init();
}
private void sendFeedbackMessage(MessageChannel channel, String title, String message) {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
embedBuilder.setTitle(title);
embedBuilder.setDescription(message);
embedBuilder.setFooter("Minecraft PhoenixSC Edition");
MessageAction messageAction = channel.sendMessage(embedBuilder.build());
messageAction.queue();
}
private void sendTempFeedbackMessage(MessageChannel channel, String title, String message, int seconds) {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
embedBuilder.setTitle(title);
embedBuilder.setDescription(message);
embedBuilder.setFooter(String.format("This message will be deleted %s seconds after being sent.", seconds));
MessageAction messageAction = channel.sendMessage(embedBuilder.build());
messageAction.queue(m -> m.delete().queueAfter(seconds, TimeUnit.SECONDS));
}
public static JDA jda = null;
private static String token = AutoWhitelist.getConfigData().token;
private static String clientId = AutoWhitelist.getConfigData().clientId;
public static String serverId = AutoWhitelist.getConfigData().discordServerId;
public static String prefix = AutoWhitelist.getConfigData().prefix;
public static long updateDelay = AutoWhitelist.getConfigData().whitelistScheduledVerificationSeconds;
public static Map<String, String> whitelistDataMap = new HashMap<>();
public static void stopBot() {
if (jda != null) {
scheduledUpdate.cancel(true);
jda.shutdown();
if (scheduledUpdate != null) {
scheduledUpdate.cancel(false);
try {
scheduledUpdate.get();
} catch (Exception ignored) {
}
}
if (jda != null) jda.shutdown();
}
public static Bot getInstance() {
@ -89,237 +45,48 @@ public class Bot extends ListenerAdapter {
}
public void reloadBot(ServerCommandSource source) {
token = AutoWhitelist.config.getConfigs().get("token").getAsString();
appId = AutoWhitelist.config.getConfigs().get("application-id").getAsString();
serverId = AutoWhitelist.config.getConfigs().get("discord-server-id").getAsString();
prefix = AutoWhitelist.config.getConfigs().get("prefix").getAsString();
updateDelay = AutoWhitelist.config.getConfigs().get("whitelist-auto-update-delay-seconds").getAsLong();
source.sendFeedback(new LiteralText("Restarting the discord."), true);
scheduledUpdate.cancel(true);
jda.shutdown();
whitelistDataMap.clear();
AutoWhitelist.getConfigData().whitelist.forEach((v, k) -> k.forEach(id_ -> whitelistDataMap.put(id_, v)));
token = AutoWhitelist.getConfigData().token;
clientId = AutoWhitelist.getConfigData().clientId;
serverId = AutoWhitelist.getConfigData().discordServerId;
prefix = AutoWhitelist.getConfigData().prefix;
updateDelay = AutoWhitelist.getConfigData().whitelistScheduledVerificationSeconds;
if (scheduledUpdate != null) {
scheduledUpdate.cancel(false);
try {
scheduledUpdate.get();
} catch (Exception ignored) {
}
}
if (jda != null) jda.shutdown();
Thread thread = new Thread(new Bot());
thread.setName("AutoWhitelist Bot");
thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler(AutoWhitelist.LOGGER));
thread.setDaemon(true);
thread.start();
source.sendFeedback(new LiteralText("Discord bot starting."), true);
}
public void run() {
init();
source.sendFeedback(new LiteralText("Discord discord starting."), true);
}
private void init() {
try {
if (whitelistDataMap.isEmpty()) AutoWhitelist.getConfigData().whitelist.forEach((v, k) -> k.forEach(id_ -> whitelistDataMap.put(id_, v)));
jda = JDABuilder.createDefault(token).enableIntents(GatewayIntent.GUILD_MEMBERS).setMemberCachePolicy(MemberCachePolicy.ALL).build();
jda.addEventListener(new BotEventListener());
jda.getPresence().setActivity(Activity.playing("on the Member Server"));
try {
jda.getPresence().setActivity(Activity.of(Activity.ActivityType.valueOf(new TranslatableText("bot.activity.type").getString().toUpperCase()), new TranslatableText("bot.activity.message").getString()));
} catch (IllegalArgumentException | NullPointerException e) {
AutoWhitelist.LOGGER.error("Failed to set bot activity, the chosen activity type value is not valid.");
}
instance = this;
} catch (LoginException e) {
AutoWhitelist.logger.error("Failed to start discord, please verify the token.");
AutoWhitelist.LOGGER.error("Failed to start bot, please verify the token.");
}
}
/*@Override
public void onReady(@NotNull ReadyEvent e) {
AutoWhitelist.logger.info("Bot started. Parsing registered users.");
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(4);
scheduledUpdate = scheduler.scheduleWithFixedDelay(this::updateWhitelist, 0, updateDelay, TimeUnit.SECONDS);
}*/
@Override
public void onGuildMemberRemove(@NotNull GuildMemberRemoveEvent e) {
User user = e.getUser();
List<MemberPlayer> players = new ArrayList<>();
new SQLite().getMembers().stream().filter(member -> user.getId().equals(member.getUserId())).findFirst().ifPresent(players::add);
if (players.size() > 1) {
AutoWhitelist.logger.error("Found more than one registered user with same discord id: " + user.getId());
return;
} else if (players.size() == 0) return;
MemberPlayer player = players.get(0);
if (!AutoWhitelist.server.getPlayerManager().isOperator(player.getProfile())) {
new SQLite().removeMemberById(player.getUserId());
AutoWhitelist.removePlayer(player.getProfile());
}
}
private void updateWhitelist() {
List<String> ids = new SQLite().getIds();
List<MemberPlayer> memberList = new SQLite().getMembers();
Guild guild = jda.getGuildById(serverId);
if (guild == null) {
AutoWhitelist.logger.error("Failed to get discord server, got null");
return;
}
guild.loadMembers().onSuccess(members -> {
List<Member> users = members.stream().filter(member -> ids.contains(member.getId())).collect(Collectors.toList());
for (Member user : users) {
List<MemberPlayer> players = memberList.stream().filter(player -> user.getId().equals(player.getUserId())).collect(Collectors.toList());
MemberPlayer player = players.get(0);
List<String> roles = getMemberRoles();
List<Role> userRoles = user.getRoles().stream().filter((role) -> roles.contains(role.getId())).collect(Collectors.toList());
if (userRoles.size() >= 1) {
int higher = 0;
Role best = null;
for (Role role : userRoles) {
if (role.getPosition() > higher) {
higher = role.getPosition();
best = role;
}
}
if (best == null) {
AutoWhitelist.logger.error("Failed to get best tier role!");
return;
}
for (Map.Entry<String, JsonElement> entry : AutoWhitelist.config.getConfigs().get("whitelist").getAsJsonObject().entrySet()) {
JsonArray jsonArray = entry.getValue().getAsJsonArray();
for (JsonElement value : jsonArray) {
if (value.getAsString().equals(best.getId())) {
if (ids.contains(user.getId()) && !player.getTeam().equals(entry.getKey())) {
try {
new SQLite().updateData(user.getId(), getUsername(player.getProfile().getId().toString()), player.getProfile().getId().toString(), entry.getKey());
} catch (IOException e) {
AutoWhitelist.logger.error("Failed to get username!", e);
return;
}
}
}
}
}
} else if (!AutoWhitelist.server.getPlayerManager().isOperator(player.getProfile())) {
new SQLite().removeMemberById(player.getUserId());
AutoWhitelist.removePlayer(player.getProfile());
}
}
AutoWhitelist.updateWhitelist();
});
}
@Override
public void onMessageReceived(@NotNull MessageReceivedEvent e) {
if (e.isWebhookMessage() || e.getAuthor().isBot() || e.getChannelType() != ChannelType.TEXT) return;
if (!e.getMessage().getContentRaw().startsWith(prefix + "register")) return;
Member author = e.getMember();
if (author == null) { sendFeedbackMessage(e.getChannel(), "Something went wrong.", "Sorry I could not get your discord user. With so you haven't been added to the server."); return; }
Message _message = e.getMessage();
String message = _message.getContentRaw();
message = message.replaceFirst(prefix + "register ", "");
String[] values = message.split(" ");
{
if (new SQLite().getIds().contains(author.getId())) {
sendFeedbackMessage(e.getChannel(), "You only can register one account", "You can't have more than one Minecraft account registered.");
return;
}
}
{
if (values.length != 1) {
sendFeedbackMessage(e.getChannel(), "Invalid command usage.", String.format("Please not that the command is `%sregister <minecraft nickname> <uuid>`\nExample: `%sregister Notch`", prefix, prefix));
return;
} else if (values[0].length() > 16 || values[0].length() < 3) {
sendFeedbackMessage(e.getChannel(), "Invalid nickname.", "The nickname you inserted is either too big or too small.");
return;
}
}
sendTempFeedbackMessage(e.getChannel(), "Command feedback.", "Your request has been received and is being processed, if you don't get another feedback message in the next minute than please contact a moderator.", 10);
List<String> roles = getMemberRoles();
List<Role> userRoles = author.getRoles().stream().filter((role) -> roles.contains(role.getId())).collect(Collectors.toList());
if (userRoles.size() >= 1) {
int higher = 0;
Role best = null;
for (Role role : userRoles) {
if (role.getPosition() > higher) {
higher = role.getPosition();
best = role;
}
}
if (best == null) {
sendFeedbackMessage(e.getChannel(), "Something really bad happened.", "I was unable to get your best member role, due to that issue I couldn't add you to the server, please inform a moderator or PhoenixSC.");
return;
}
for (Map.Entry<String, JsonElement> entry : AutoWhitelist.config.getConfigs().get("whitelist").getAsJsonObject().entrySet()) {
JsonArray jsonArray = entry.getValue().getAsJsonArray();
for (JsonElement value : jsonArray) {
if (value.getAsString().equals(best.getId())) {
if (!new SQLite().getIds().contains(author.getId())) {
try {
String uuid = getUUID(values[0]);
List<GameProfile> players = new SQLite().getPlayers();
if (players.stream().map(GameProfile::getName).anyMatch(username -> username.equals(values[0])) && players.stream().map(GameProfile::getId).anyMatch(uuid_ -> uuid_.toString().equals(uuid))) {
sendFeedbackMessage(e.getChannel(), "This account is already registered.", "The username you inserted is already registered in the database.");
return;
}
new SQLite().addMember(author.getId(), values[0], uuid, entry.getKey());
AutoWhitelist.server.getPlayerManager().getWhitelist().add(new WhitelistEntry(new GameProfile(UUID.fromString(uuid), values[0])));
Scoreboard scoreboard = AutoWhitelist.server.getScoreboard();
Team team = scoreboard.getTeam(entry.getKey());
if (team == null) {
sendFeedbackMessage(e.getChannel(), "Something really bad happened.", "I could not get the team equivalent to your member level, due to this issue I couldn't add you to the server, please inform a moderator or PhoenixSC.");
return;
}
scoreboard.addPlayerToTeam(values[0], team);
sendFeedbackMessage(e.getChannel(), "Welcome to the group!", "Your Minecraft account has been added to the database and soon you will be able to join the server.");
} catch (IOException exception) {
sendFeedbackMessage(e.getChannel(), "Something really bad happened.", "I was unable to get your UUID, due to this issue I couldn't add you to the server, please inform a moderator or PhoenixSC.");
AutoWhitelist.logger.error("Failed to get UUID.", exception);
return;
} catch (InvalidResultException exception) {
sendFeedbackMessage(e.getChannel(), "Something went wrong.", "Seams that the username you inserted is not of an original Minecraft Java Edition account or the Mojang API is down. Please check if your username is correct, if it is than try again later.");
return;
}
}
}
}
}
} else {
sendFeedbackMessage(e.getChannel(), "Sorry, but I couldn't accept your request.", "It seams that you don't have the required subscription/member level or don't have your Twitch/Youtube account linked to your Discord account.");
}
}
private List<String> getMemberRoles() {
List<String> roles = new ArrayList<>();
for (Map.Entry<String, JsonElement> entry : AutoWhitelist.config.getConfigs().get("whitelist").getAsJsonObject().entrySet()) {
entry.getValue().getAsJsonArray().forEach((element) -> roles.add(element.getAsString()));
}
return roles;
}
private String getUUID(String username) throws IOException, InvalidResultException {
URL url = new URL(String.format("https://api.mojang.com/users/profiles/minecraft/%s", username));
try (InputStream is = url.openStream()) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String jsonText = readAll(rd);
JsonParser parser = new JsonParser();
JsonElement json = parser.parse(jsonText);
if (json.isJsonNull() || json.getAsJsonObject().get("id") == null)
throw new InvalidResultException("Invalid username:" + username);
String _uuid = json.getAsJsonObject().get("id").getAsString();
if (_uuid.length() != 32) throw new InvalidResultException("Invalid UUID string:" + _uuid);
String[] split = new String[]{_uuid.substring(0, 8), _uuid.substring(8, 12), _uuid.substring(12, 16), _uuid.substring(16, 20), _uuid.substring(20, 32)};
return split[0] + "-" + split[1] + "-" + split[2] + "-" + split[3] + "-" + split[4];
}
}
private String getUsername(String uuid) throws IOException {
URL url = new URL(String.format("https://sessionserver.mojang.com/session/minecraft/profile/%s", uuid));
try (InputStream is = url.openStream()) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String jsonText = readAll(rd);
JsonParser parser = new JsonParser();
JsonElement json = parser.parse(jsonText);
return json.getAsJsonObject().get("name").getAsString();
}
}
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
}

Ver arquivo

@ -1,23 +1,195 @@
package com.awakenedredstone.autowhitelist.discord;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.discord.commands.RegisterCommand;
import com.awakenedredstone.autowhitelist.discord.commands.developer.BotStatusCommand;
import com.awakenedredstone.autowhitelist.discord.commands.developer.ServerStatusCommand;
import com.awakenedredstone.autowhitelist.discord.commands.developer.StatusCommand;
import com.awakenedredstone.autowhitelist.mixin.ServerConfigEntryMixin;
import com.awakenedredstone.autowhitelist.util.ExtendedGameProfile;
import com.awakenedredstone.autowhitelist.util.FailedToUpdateWhitelistException;
import com.awakenedredstone.autowhitelist.util.InvalidTeamNameException;
import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelist;
import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelistEntry;
import com.jagrosh.jdautilities.command.Command;
import com.jagrosh.jdautilities.command.CommandClient;
import com.jagrosh.jdautilities.command.CommandClientBuilder;
import com.jagrosh.jdautilities.command.CommandEvent;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.*;
import net.dv8tion.jda.api.events.ReadyEvent;
import net.dv8tion.jda.api.events.guild.member.GuildMemberRemoveEvent;
import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleAddEvent;
import net.dv8tion.jda.api.events.guild.member.GuildMemberRoleRemoveEvent;
import net.dv8tion.jda.api.hooks.ListenerAdapter;
import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.scoreboard.Team;
import org.jetbrains.annotations.NotNull;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.*;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import static com.awakenedredstone.autowhitelist.discord.Bot.*;
import static com.awakenedredstone.autowhitelist.util.Debugger.analyzeTimings;
public class BotEventListener extends ListenerAdapter {
//
@Override
public void onReady(@NotNull ReadyEvent e) {
AutoWhitelist.logger.info("Bot started. Parsing registered users.");
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(4);
scheduledUpdate = scheduler.scheduleWithFixedDelay(this::updateWhitelist, 0, updateDelay, TimeUnit.SECONDS);
AutoWhitelist.LOGGER.info("Bot started. Parsing registered users.");
CommandClientBuilder builder = new CommandClientBuilder();
builder.setPrefix(prefix);
builder.setOwnerId("387745099204919297");
builder.setHelpConsumer(generateHelpConsumer());
builder.addCommands(
new RegisterCommand(),
//Developer commands
new ServerStatusCommand(),
new BotStatusCommand(),
new StatusCommand()
);
CommandClient command = builder.build();
jda.addEventListener(command);
if (scheduledUpdate != null) {
scheduledUpdate.cancel(false);
try {
scheduledUpdate.get();
} catch (Exception ignored) {
}
}
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduledUpdate = scheduler.scheduleWithFixedDelay(new DiscordDataProcessor(), 0, updateDelay, TimeUnit.SECONDS);
}
private Consumer<CommandEvent> generateHelpConsumer() {
return (event) -> {
EmbedBuilder builder = new EmbedBuilder().setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
Command.Category category;
List<MessageEmbed.Field> fields = new ArrayList<>();
for (Command command : event.getClient().getCommands()) {
if (!command.isHidden() && (!command.isOwnerCommand() || event.isOwner())) {
String command_ = "\n`" +
event.getClient().getPrefix() +
(prefix == null ? " " : "") +
command.getName() +
(command.getArguments() == null ? "" : " " + command.getArguments()) +
"` \u200E \u200E | \u200E \u200E " + command.getHelp();
category = command.getCategory();
fields.add(new MessageEmbed.Field(category == null ? "No Category" : category.getName(), command_, false));
}
}
List<MessageEmbed.Field> mergedFields = new ArrayList<>();
String commands = "";
String lastName = "";
for (MessageEmbed.Field field : fields) {
if (Objects.equals(field.getName(), lastName)) {
commands += "\n" + field.getValue();
if (fields.get(fields.size() - 1) == field) {
mergedFields.add(new MessageEmbed.Field(lastName, commands, false));
}
} else if (!commands.isEmpty()) {
mergedFields.add(new MessageEmbed.Field(lastName, commands, false));
commands = "";
commands += "\n" + field.getValue();
lastName = field.getName();
} else {
commands += field.getValue();
lastName = field.getName();
}
}
mergedFields.forEach(builder::addField);
event.reply(builder.build());
};
}
@Override
public void onGuildMemberRemove(@NotNull GuildMemberRemoveEvent e) {
User user = e.getUser();
ExtendedWhitelist whitelist = (ExtendedWhitelist) AutoWhitelist.server.getPlayerManager().getWhitelist();
List<ExtendedGameProfile> players = new ArrayList<>();
whitelist.getEntries().stream().filter(entry -> {
((ServerConfigEntryMixin<?>) entry).callGetKey();
try {
return user.getId().equals(((ExtendedGameProfile) ((ServerConfigEntryMixin<?>) entry).getKey()).getDiscordId());
} catch (ClassCastException exception) {
return false;
}
}).findFirst().map(v -> {
((ServerConfigEntryMixin<?>) v).callGetKey();
return (ExtendedGameProfile) ((ServerConfigEntryMixin<?>) v).getKey();
}).ifPresent(players::add);
if (players.size() > 1) {
AutoWhitelist.LOGGER.error("Found more than one registered user with same discord id: {}", user.getId(), new FailedToUpdateWhitelistException("Could not update the whitelist, found multiple"));
return;
} else if (players.size() == 0) return;
ExtendedGameProfile player = players.get(0);
if (!AutoWhitelist.server.getPlayerManager().isOperator(player)) {
AutoWhitelist.removePlayer(player);
}
}
@Override
public void onGuildMemberRoleAdd(@NotNull GuildMemberRoleAddEvent e) {
updateUser(e.getMember(), e.getRoles());
}
@Override
public void onGuildMemberRoleRemove(@NotNull GuildMemberRoleRemoveEvent e) {
updateUser(e.getMember(), e.getRoles());
}
private void updateUser(Member member, List<Role> roles) {
analyzeTimings("BotEventListener#updateUser", () -> {
if (Collections.disjoint(roles.stream().map(Role::getId).collect(Collectors.toList()), new ArrayList<>(whitelistDataMap.keySet()))) {
return;
}
ExtendedWhitelist whitelist = (ExtendedWhitelist) AutoWhitelist.server.getPlayerManager().getWhitelist();
List<ExtendedGameProfile> profiles = whitelist.getFromDiscordId(member.getId());
if (profiles.isEmpty()) return;
if (profiles.size() > 1) {
AutoWhitelist.LOGGER.warn("Duplicate entries of Discord user with id {}. All of them will be removed.", member.getId());
profiles.forEach(profile -> whitelist.remove(new ExtendedWhitelistEntry(new ExtendedGameProfile(profile.getId(), profile.getName(), profile.getTeam(), profile.getDiscordId()))));
return;
}
List<String> validRoles = member.getRoles().stream().map(Role::getId).filter(whitelistDataMap::containsKey).collect(Collectors.toList());
if (validRoles.isEmpty()) {
ExtendedGameProfile profile = profiles.get(0);
AutoWhitelist.removePlayer(profile);
return;
}
String highestRole = validRoles.get(0);
String teamName = whitelistDataMap.get(highestRole);
ExtendedGameProfile profile = profiles.get(0);
if (!profile.getTeam().equals(teamName)) {
whitelist.remove(profile);
whitelist.add(new ExtendedWhitelistEntry(new ExtendedGameProfile(profile.getId(), profile.getName(), teamName, profile.getDiscordId())));
Scoreboard scoreboard = AutoWhitelist.server.getScoreboard();
Team team = scoreboard.getTeam(teamName);
if (team == null) {
AutoWhitelist.LOGGER.error("Could not check team information of \"{}\", got \"null\" when trying to get \"net.minecraft.scoreboard.Team\" from \"{}\"", profile.getName(), profile.getTeam(), new InvalidTeamNameException("Tried to get \"net.minecraft.scoreboard.Team\" from \"" + profile.getTeam() + "\" but got \"null\"."));
return;
}
scoreboard.addPlayerToTeam(profile.getName(), team);
}
});
}
}

Ver arquivo

@ -0,0 +1,85 @@
package com.awakenedredstone.autowhitelist.discord;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.MessageBuilder;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.requests.restaction.MessageAction;
import net.minecraft.text.Text;
import java.awt.*;
import java.util.concurrent.TimeUnit;
public class BotHelper extends Bot {
public static void sendFeedbackMessage(MessageChannel channel, Text title, Text message) {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
embedBuilder.setTitle(title.getString());
embedBuilder.setDescription(message.getString());
embedBuilder.setFooter("Minecraft PhoenixSC Edition");
MessageAction messageAction = channel.sendMessage(embedBuilder.build());
messageAction.queue();
}
public static void sendFeedbackMessage(MessageChannel channel, Text title, Text message, MessageType type) {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
embedBuilder.setTitle(title.getString());
embedBuilder.setDescription(message.getString());
embedBuilder.setFooter("Minecraft PhoenixSC Edition");
embedBuilder.setColor(type.hexColor);
MessageAction messageAction = channel.sendMessage(embedBuilder.build());
messageAction.queue();
}
public static void sendTempFeedbackMessage(MessageChannel channel, Text title, Text message, int seconds) {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
embedBuilder.setTitle(title.getString());
embedBuilder.setDescription(message.getString());
embedBuilder.setFooter(String.format("This message will be deleted %s seconds after being sent.", seconds));
MessageAction messageAction = channel.sendMessage(embedBuilder.build());
messageAction.queue(m -> m.delete().queueAfter(seconds, TimeUnit.SECONDS));
}
public static Message generateFeedbackMessage(Text title, Text message) {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
embedBuilder.setTitle(title.getString());
embedBuilder.setDescription(message.getString());
embedBuilder.setFooter("Minecraft PhoenixSC Edition");
return new MessageBuilder(embedBuilder.build()).build();
}
public static Message generateFeedbackMessage(Text title, Text message, MessageType type) {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
embedBuilder.setTitle(title.getString());
embedBuilder.setDescription(message.getString());
embedBuilder.setFooter("Minecraft PhoenixSC Edition");
embedBuilder.setColor(type.hexColor);
return new MessageBuilder(embedBuilder.build()).build();
}
public enum MessageType {
DEBUG(new Color(19, 40, 138)),
NORMAL(Role.DEFAULT_COLOR_RAW),
INFO(new Color(176, 154, 15)),
SUCCESS(new Color(50, 134, 25)),
WARNING(new Color(208, 102, 21)),
ERROR(new Color(141, 29, 29)),
FATAL(new Color(212, 4, 4));
private final int hexColor;
MessageType(Color hexColor) {
this.hexColor = hexColor.getRGB();
}
MessageType(int hexColor) {
this.hexColor = hexColor;
}
}
}

Ver arquivo

@ -1,27 +1,29 @@
package com.awakenedredstone.autowhitelist.discord;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.config.ConfigData;
import com.awakenedredstone.autowhitelist.database.SQLite;
import com.awakenedredstone.autowhitelist.util.MemberPlayer;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.awakenedredstone.autowhitelist.mixin.ServerConfigEntryMixin;
import com.awakenedredstone.autowhitelist.util.ExtendedGameProfile;
import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelist;
import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelistEntry;
import net.dv8tion.jda.api.entities.Guild;
import net.dv8tion.jda.api.entities.ISnowflake;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Role;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.awakenedredstone.autowhitelist.discord.Bot.*;
import static com.awakenedredstone.autowhitelist.util.Debugger.analyzeTimings;
public class DiscordDataProcessor {
public class DiscordDataProcessor implements Runnable {
private void updateWhitelist() {
/* private void updateWhitelist() {
List<String> ids = new SQLite().getIds();
List<MemberPlayer> memberList = new SQLite().getMembers();
List<ExtendedGameProfile> memberList = new SQLite().getMembers();
Guild guild = jda.getGuildById(serverId);
if (guild == null) {
AutoWhitelist.logger.error("Failed to get discord server, got null");
@ -32,8 +34,8 @@ public class DiscordDataProcessor {
for (Member user : users) {
List<MemberPlayer> players = memberList.stream().filter(player -> user.getId().equals(player.getUserId())).collect(Collectors.toList());
MemberPlayer player = players.get(0);
List<ExtendedGameProfile> players = memberList.stream().filter(player -> user.getId().equals(player.getDiscordId())).collect(Collectors.toList());
ExtendedGameProfile player = players.get(0);
List<String> roles = getMemberRoles();
List<Role> userRoles = user.getRoles().stream().filter((role) -> roles.contains(role.getId())).collect(Collectors.toList());
@ -56,7 +58,7 @@ public class DiscordDataProcessor {
if (value.getAsString().equals(best.getId())) {
if (ids.contains(user.getId()) && !player.getTeam().equals(entry.getKey())) {
try {
new SQLite().updateData(user.getId(), getUsername(player.getProfile().getId().toString()), player.getProfile().getId().toString(), entry.getKey());
new SQLite().updateData(user.getId(), getUsername(player.getId().toString()), player.getId().toString(), entry.getKey());
} catch (IOException e) {
AutoWhitelist.logger.error("Failed to get username!", e);
return;
@ -65,11 +67,66 @@ public class DiscordDataProcessor {
}
}
}
} else if (!AutoWhitelist.server.getPlayerManager().isOperator(player.getProfile())) {
new SQLite().removeMemberById(player.getUserId());
AutoWhitelist.removePlayer(player.getProfile());
} else if (!AutoWhitelist.server.getPlayerManager().isOperator(player)) {
new SQLite().removeMemberById(player.getDiscordId());
AutoWhitelist.removePlayer(player);
}
}
});
}*/
@Override
public void run() {
updateWhitelist();
}
public void updateWhitelist() {
analyzeTimings("DiscordDataProcessor#updateWhitelist", () -> {
Guild guild = jda.getGuildById(serverId);
if (guild == null) {
return;
}
ExtendedWhitelist whitelist = (ExtendedWhitelist) AutoWhitelist.server.getPlayerManager().getWhitelist();
List<Member> members = guild.findMembers(v -> {
if (v.getUser().isBot()) return false;
return !Collections.disjoint(v.getRoles().stream().map(Role::getId).collect(Collectors.toList()), new ArrayList<>(whitelistDataMap.keySet()));
}).get();
List<String> memberIds = members.stream().map(ISnowflake::getId).collect(Collectors.toList());
List<ExtendedGameProfile> invalidPlayers = whitelist.getEntries().stream().map(entry -> {
((ServerConfigEntryMixin<?>) entry).callGetKey();
try {
return (ExtendedGameProfile) ((ServerConfigEntryMixin<?>) entry).getKey();
} catch (ClassCastException exception) {
return null;
}
}).filter(Objects::nonNull).filter(entry -> !memberIds.contains(entry.getDiscordId())).collect(Collectors.toList());
if (!invalidPlayers.isEmpty()) {
for (ExtendedGameProfile invalidPlayer : invalidPlayers) {
AutoWhitelist.removePlayer(invalidPlayer);
}
}
for (Member member : members) {
String highestRole = member.getRoles().stream().map(Role::getId).filter(whitelistDataMap::containsKey).collect(Collectors.toList()).get(0);
String teamName = whitelistDataMap.get(highestRole);
List<ExtendedGameProfile> profiles = whitelist.getFromDiscordId(member.getId());
if (profiles.isEmpty()) continue;
if (profiles.size() > 1) {
AutoWhitelist.LOGGER.warn("Duplicate entries of Discord user with id {}. All of them will be removed.", member.getId());
profiles.forEach(profile -> whitelist.remove(new ExtendedWhitelistEntry(new ExtendedGameProfile(profile.getId(), profile.getName(), profile.getTeam(), profile.getDiscordId()))));
continue;
}
ExtendedGameProfile profile = profiles.get(0);
if (!profile.getTeam().equals(teamName)) {
whitelist.remove(profile);
whitelist.add(new ExtendedWhitelistEntry(new ExtendedGameProfile(profile.getId(), profile.getName(), teamName, profile.getDiscordId())));
}
}
});
analyzeTimings("AutoWhitelist#updateWhitelist", AutoWhitelist::updateWhitelist);
}
}

Ver arquivo

@ -0,0 +1,134 @@
package com.awakenedredstone.autowhitelist.discord.commands;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.discord.BotHelper;
import com.awakenedredstone.autowhitelist.mixin.ServerConfigEntryMixin;
import com.awakenedredstone.autowhitelist.util.ExtendedGameProfile;
import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelist;
import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelistEntry;
import com.jagrosh.jdautilities.command.Command;
import com.jagrosh.jdautilities.command.CommandEvent;
import com.mojang.authlib.GameProfile;
import net.dv8tion.jda.api.Permission;
import net.dv8tion.jda.api.entities.Member;
import net.dv8tion.jda.api.entities.Message;
import net.dv8tion.jda.api.entities.MessageChannel;
import net.dv8tion.jda.api.entities.Role;
import net.dv8tion.jda.api.requests.restaction.MessageAction;
import net.minecraft.scoreboard.Team;
import net.minecraft.server.MinecraftServer;
import net.minecraft.text.LiteralText;
import com.awakenedredstone.autowhitelist.lang.TranslatableText;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import static com.awakenedredstone.autowhitelist.discord.Bot.whitelistDataMap;
import static com.awakenedredstone.autowhitelist.discord.BotHelper.*;
import static com.awakenedredstone.autowhitelist.util.Debugger.analyzeTimings;
import static net.dv8tion.jda.api.Permission.*;
public class RegisterCommand extends Command {
public RegisterCommand() {
this.name = "register";
this.help = "Adds the informed minecraft account to the Member Server whitelist. [Members only]";
this.category = new Category("Server integration");
this.botPermissions = new Permission[]{MESSAGE_ATTACH_FILES, MESSAGE_HISTORY, MESSAGE_EMBED_LINKS, MESSAGE_READ, MESSAGE_WRITE, VIEW_CHANNEL};
this.arguments = "<minecraft username>";
this.guildOnly = true;
}
@Override
protected void execute(CommandEvent e) {
analyzeTimings("RegisterCommand#execute", () -> {
MessageChannel channel = e.getChannel();
Member member = e.getMember();
if (member == null) return;
sendTempFeedbackMessage(e.getChannel(), new TranslatableText("command.feedback.received.title"), new TranslatableText("command.feedback.received.message"), 7);
String id = member.getId();
List<Role> roles = member.getRoles();
boolean accepted = !Collections.disjoint(roles.stream().map(Role::getId).collect(Collectors.toList()), new ArrayList<>(whitelistDataMap.keySet()));
if (accepted) {
MinecraftServer server = AutoWhitelist.server;
ExtendedWhitelist whitelist = (ExtendedWhitelist) server.getPlayerManager().getWhitelist();
boolean hasAccountWhitelisted = whitelist.getEntries().stream().map(entry -> {
((ServerConfigEntryMixin<?>) entry).callGetKey();
try {
return ((ExtendedGameProfile) ((ServerConfigEntryMixin<?>) entry).getKey()).getDiscordId();
} catch (ClassCastException exception) {
return null;
}
}).filter(Objects::nonNull).anyMatch(id_ -> id_.equals(id));
if (hasAccountWhitelisted) {
BotHelper.sendFeedbackMessage(channel, new TranslatableText("command.register.already_registered.title"), new TranslatableText("command.register.already_registered.message"), MessageType.WARNING);
return;
}
String highestRole = roles.stream().map(Role::getId).filter(whitelistDataMap::containsKey).collect(Collectors.toList()).get(0);
String teamName = whitelistDataMap.get(highestRole);
Team team = server.getScoreboard().getTeam(teamName);
if (team == null) {
BotHelper.sendFeedbackMessage(channel, new TranslatableText("command.fail.title"), new TranslatableText("command.register.fatal.null_team", teamName), BotHelper.MessageType.FATAL);
return;
}
String arguments = e.getArgs();
if (arguments.isEmpty()) {
BotHelper.sendFeedbackMessage(channel, new TranslatableText("command.few_args.title"), new TranslatableText("command.few_args.message"), MessageType.WARNING);
return;
}
String[] args = arguments.split(" ");
if (args.length > 1) {
BotHelper.sendFeedbackMessage(channel, new TranslatableText("command.too_many_args.title"), new TranslatableText("command.too_many_args.message"), MessageType.WARNING);
return;
}
String arg = args[0];
{
if (arg.length() > 16) {
sendFeedbackMessage(e.getChannel(), new TranslatableText("command.register.invalid_username.title"), new TranslatableText("command.register.invalid_username.message.too_long"), MessageType.WARNING);
return;
} else if (arg.length() < 3) {
sendFeedbackMessage(e.getChannel(), new TranslatableText("command.register.invalid_username.title"), new TranslatableText("command.register.invalid_username.message.too_short"), MessageType.WARNING);
return;
}
}
{
}
GameProfile profile = server.getUserCache().findByName(arg);
if (profile == null) {
BotHelper.sendFeedbackMessage(channel, new TranslatableText("command.fail.title"), new TranslatableText("command.register.fail.account_data", arg), BotHelper.MessageType.ERROR);
return;
}
ExtendedGameProfile extendedProfile = new ExtendedGameProfile(profile.getId(), profile.getName(), teamName, id);
boolean whitelisted;
whitelisted = whitelist.isAllowed(extendedProfile);
if (!whitelisted)
whitelisted = server.getPlayerManager().getWhitelist().isAllowed(new GameProfile(profile.getId(), arg));
if (whitelisted) {
BotHelper.sendFeedbackMessage(channel, new TranslatableText("command.register.username_already_registered.title"), new TranslatableText("command.register.username_already_registered.title"), BotHelper.MessageType.ERROR);
} else {
Message message = BotHelper.generateFeedbackMessage(new TranslatableText("command.register.last_steps.title"), new LiteralText("command.register.last_steps.message"), BotHelper.MessageType.INFO);
MessageAction feedbackMessage = channel.sendMessage(message);
feedbackMessage.queue(message_ -> {
whitelist.add(new ExtendedWhitelistEntry(extendedProfile));
server.getScoreboard().addPlayerToTeam(profile.getName(), team);
message_.editMessage(BotHelper.generateFeedbackMessage(new TranslatableText("command.register.success.title"), new TranslatableText("command.register.success.message"), BotHelper.MessageType.SUCCESS)).queue();
});
}
} else {
BotHelper.sendFeedbackMessage(channel, new TranslatableText("command.register.fail.not_allowed.title"), new TranslatableText("command.register.fail.not_allowed.message"), MessageType.NORMAL);
}
});
}
}

Ver arquivo

@ -0,0 +1,38 @@
package com.awakenedredstone.autowhitelist.discord.commands.developer;
import com.jagrosh.jdautilities.command.CommandEvent;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.ChannelType;
import static com.awakenedredstone.autowhitelist.discord.Bot.jda;
import static com.awakenedredstone.autowhitelist.util.Debugger.analyzeTimings;
public class BotStatusCommand extends DeveloperCommand {
public BotStatusCommand() {
super();
this.name = "botStatus";
this.help = "Shows the bot status.";
this.aliases = new String[]{"botInfo"};
}
@Override
protected void execute(CommandEvent event) {
if (event.getChannelType() != ChannelType.PRIVATE) return;
analyzeTimings("BotStatusCommand#execute", () -> {
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
embedBuilder.setTitle("Bot Status Log");
embedBuilder.setDescription("**Bot status:** " + jda.getStatus().toString());
jda.getRestPing().queue(restPing -> {
String output ="\n" + "**Gateway ping:** " + jda.getGatewayPing() + " ms" +
"\n" + "**Rest ping:** " + restPing + " ms";
embedBuilder.addField("Discord timings", output, false);
event.getChannel().sendMessage(embedBuilder.build()).queue();
});
});
}
}

Ver arquivo

@ -0,0 +1,12 @@
package com.awakenedredstone.autowhitelist.discord.commands.developer;
import com.jagrosh.jdautilities.command.Command;
public abstract class DeveloperCommand extends Command {
public DeveloperCommand() {
this.category = new Category("Developer tools | Debugging");
this.guildOnly = false;
this.ownerCommand = true;
}
}

Ver arquivo

@ -0,0 +1,64 @@
package com.awakenedredstone.autowhitelist.discord.commands.developer;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.jagrosh.jdautilities.command.CommandEvent;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.ChannelType;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerManager;
import net.minecraft.util.Util;
import net.minecraft.util.math.MathHelper;
import static com.awakenedredstone.autowhitelist.discord.Bot.jda;
import static com.awakenedredstone.autowhitelist.util.Debugger.analyzeTimings;
public class ServerStatusCommand extends DeveloperCommand {
public ServerStatusCommand() {
super();
this.name = "serverStatus";
this.help = "Shows the Minecraft server status.";
this.aliases = new String[]{"serverInfo"};
}
@Override
protected void execute(CommandEvent event) {
if (event.getChannelType() != ChannelType.PRIVATE) return;
analyzeTimings("ServerStatusCommand#execute", () -> {
MinecraftServer server = AutoWhitelist.server;
PlayerManager playerManager = server.getPlayerManager();
long l = Util.getMeasuringTimeMs() - server.getServerStartTime();
double MSPT = MathHelper.average(server.lastTickLengths) * 1.0E-6D;
double TPS = 1000.0D / Math.max(50, MSPT);
double MAX_POSSIBLE_TPS = 1000.0D / MSPT;
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
embedBuilder.setTitle("Server Status Log");
embedBuilder.setDescription("**Server status:** " + (getServerStatus(server).equals("Running.") ? (l > 2000L ? String.format("Running %sms behind.", l) : "Running.") : getServerStatus(server)));
String output = "" +
"\n" + "**MSPT:** " + String.format("%.2f", MSPT) + " ms" +
"\n" + "**TPS:** " + String.format("%.2f", TPS) +
"\n" + "**MAX TPS:** " + String.format("%.2f", MAX_POSSIBLE_TPS);
embedBuilder.addField("Server timings", output, true);
StringBuilder serverInformation = new StringBuilder();
serverInformation.append("**Server game version:** ").append(server.getVersion()).append("\n");
serverInformation.append("**Total whitelisted players:** ").append(playerManager.getWhitelistedNames().length).append("\n");
serverInformation.append("**Total online players:** ").append(server.getCurrentPlayerCount()).append("/").append(server.getMaxPlayerCount());
embedBuilder.addField("Server information", serverInformation.toString(), true);
event.getChannel().sendMessage(embedBuilder.build()).queue();
});
}
private String getServerStatus(MinecraftServer server) {
if (server.isStopped()) return "Stopped.";
if (server.isRunning()) return "Running.";
return "Unknown.";
}
}

Ver arquivo

@ -0,0 +1,59 @@
package com.awakenedredstone.autowhitelist.discord.commands.developer;
import com.awakenedredstone.autowhitelist.util.Debugger;
import com.jagrosh.jdautilities.command.CommandEvent;
import net.dv8tion.jda.api.EmbedBuilder;
import net.dv8tion.jda.api.entities.ChannelType;
import net.minecraft.util.math.MathHelper;
import oshi.SystemInfo;
import oshi.hardware.Processor;
import java.util.Arrays;
import java.util.Map;
import static com.awakenedredstone.autowhitelist.discord.Bot.jda;
import static com.awakenedredstone.autowhitelist.util.Debugger.analyzeTimings;
public class StatusCommand extends DeveloperCommand {
public StatusCommand() {
this.name = "status";
this.help = "Shows the system status.";
this.aliases = new String[]{"info"};
}
@Override
protected void execute(CommandEvent event) {
if (event.getChannelType() != ChannelType.PRIVATE) return;
analyzeTimings("StatusCommand#execute", () -> {
Runtime runtime = Runtime.getRuntime();
EmbedBuilder embedBuilder = new EmbedBuilder();
embedBuilder.setAuthor(jda.getSelfUser().getName(), "https://discord.com", jda.getSelfUser().getAvatarUrl());
embedBuilder.setTitle("Status Log");
long[] processorsLoad;
try {
processorsLoad = Arrays.stream(new SystemInfo().getHardware().getProcessors()).map(Processor::getLoad).mapToLong(v -> v.longValue() * 100L).toArray();
} catch (UnsupportedOperationException exception) {
processorsLoad = new long[]{-1};
}
String output1 = "" +
"\n" + "**CPU: **" + (processorsLoad[0] != -1L ? MathHelper.average(processorsLoad) + "%" : "Unknown") +
"\n" + "**RAM: **" + (runtime.totalMemory() - runtime.freeMemory()) / 1024L / 1024L + "MB / " + runtime.totalMemory() / 1024L / 1024L + "MB" + String.format(" (%s%% free)", Runtime.getRuntime().freeMemory() * 100L / Runtime.getRuntime().maxMemory());
embedBuilder.setDescription(output1);
StringBuilder output2 = new StringBuilder();
for (Map.Entry<String, long[]> entry : Debugger.timings.entrySet()) {
String method = entry.getKey();
long[] times = entry.getValue();
output2.append("\n").append("**").append(method).append(":** ").append(Debugger.formatTimings(Arrays.stream(times).min().orElse(-1))).append("/").append(Debugger.formatTimings(MathHelper.average(times))).append("/").append(Debugger.formatTimings(Arrays.stream(times).max().orElse(-1)));
}
embedBuilder.addField("Processing timings", output2.toString(), true);
event.getChannel().sendMessage(embedBuilder.build()).queue();
});
}
}

Ver arquivo

@ -29,7 +29,7 @@ public class JsonHelper {
return element;
} catch (Exception e) {
AutoWhitelist.logger.error("Failed to parse the JSON file '{}'", fileName, e);
AutoWhitelist.LOGGER.error("Failed to parse the JSON file '{}'", fileName, e);
}
}
@ -46,14 +46,14 @@ public class JsonHelper {
return true;
} catch (IOException e) {
AutoWhitelist.logger.warn("Failed to write JSON data to file '{}'", file.getAbsolutePath(), e);
AutoWhitelist.LOGGER.warn("Failed to write JSON data to file '{}'", file.getAbsolutePath(), e);
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (Exception e) {
AutoWhitelist.logger.warn("Failed to close JSON file", e);
AutoWhitelist.LOGGER.warn("Failed to close JSON file", e);
}
}

Ver arquivo

@ -1,6 +0,0 @@
package com.awakenedredstone.autowhitelist.json;
public class JsonProcessor {
}

Ver arquivo

@ -0,0 +1,35 @@
package com.awakenedredstone.autowhitelist.lang;
import com.google.common.collect.Maps;
import net.minecraft.client.resource.language.ReorderingUtil;
import net.minecraft.text.OrderedText;
import net.minecraft.text.StringVisitable;
import net.minecraft.util.Language;
import java.util.Map;
public class JigsawLanguage extends Language {
public static final Map<String, String> translations = Maps.newHashMap();
private final boolean rightToLeft = false;
private static final Language instance = new JigsawLanguage();
public String get(String key) {
return translations.getOrDefault(key, key);
}
public boolean hasTranslation(String key) {
return translations.containsKey(key);
}
public boolean isRightToLeft() {
return this.rightToLeft;
}
public OrderedText reorder(StringVisitable text) {
return ReorderingUtil.reorder(text, this.rightToLeft);
}
public static Language getInstance() {
return instance;
}
}

Ver arquivo

@ -0,0 +1,137 @@
package com.awakenedredstone.autowhitelist.lang;
import com.google.common.collect.Lists;
import net.minecraft.text.StringVisitable;
import net.minecraft.text.Text;
import net.minecraft.text.TranslationException;
import net.minecraft.util.Language;
import org.jetbrains.annotations.Nullable;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TranslatableText extends net.minecraft.text.TranslatableText {
private static final Object[] EMPTY_ARGUMENTS = new Object[0];
private static final StringVisitable LITERAL_PERCENT_SIGN = StringVisitable.plain("%");
private static final StringVisitable NULL_ARGUMENT = StringVisitable.plain("null");
private final String key;
private final Object[] args;
@Nullable
private Language languageCache;
private final List<StringVisitable> translations = Lists.newArrayList();
private static final Pattern ARG_FORMAT = Pattern.compile("%(?:(\\d+)\\$)?([A-Za-z%]|$)");
public TranslatableText(String key) {
super(key);
this.key = key;
this.args = EMPTY_ARGUMENTS;
}
public TranslatableText(String key, Object... args) {
super(key, args);
this.key = key;
this.args = args;
}
private void updateTranslations() {
Language language = JigsawLanguage.getInstance();
if (language != this.languageCache) {
this.languageCache = language;
this.translations.clear();
String string = language.get(this.key);
try {
this.setTranslation(string);
} catch (TranslationException var4) {
this.translations.clear();
this.translations.add(StringVisitable.plain(string));
}
}
}
private void setTranslation(String translation) {
Matcher matcher = ARG_FORMAT.matcher(translation);
try {
int i = 0;
int j;
int l;
for (j = 0; matcher.find(j); j = l) {
int k = matcher.start();
l = matcher.end();
String string2;
if (k > j) {
string2 = translation.substring(j, k);
if (string2.indexOf(37) != -1) {
throw new IllegalArgumentException();
}
this.translations.add(StringVisitable.plain(string2));
}
string2 = matcher.group(2);
String string3 = translation.substring(k, l);
if ("%".equals(string2) && "%%".equals(string3)) {
this.translations.add(LITERAL_PERCENT_SIGN);
} else {
if (!"s".equals(string2)) {
throw new TranslationException(this, "Unsupported format: '" + string3 + "'");
}
String string4 = matcher.group(1);
int m = string4 != null ? Integer.parseInt(string4) - 1 : i++;
if (m < this.args.length) {
this.translations.add(this.getArg(m));
}
}
}
if (j < translation.length()) {
String string5 = translation.substring(j);
if (string5.indexOf(37) != -1) {
throw new IllegalArgumentException();
}
this.translations.add(StringVisitable.plain(string5));
}
} catch (IllegalArgumentException var11) {
throw new TranslationException(this, var11);
}
}
private StringVisitable getArg(int index) {
if (index >= this.args.length) {
throw new TranslationException(this, index);
} else {
Object object = this.args[index];
if (object instanceof Text) {
return (Text) object;
} else {
return object == null ? NULL_ARGUMENT : StringVisitable.plain(object.toString());
}
}
}
public <T> Optional<T> visitSelf(StringVisitable.Visitor<T> visitor) {
this.updateTranslations();
Iterator var2 = this.translations.iterator();
Optional optional;
do {
if (!var2.hasNext()) {
return Optional.empty();
}
StringVisitable stringVisitable = (StringVisitable) var2.next();
optional = stringVisitable.visit(visitor);
} while (!optional.isPresent());
return optional;
}
}

Ver arquivo

@ -0,0 +1,15 @@
package com.awakenedredstone.autowhitelist.mixin;
import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelist;
import net.minecraft.server.PlayerManager;
import net.minecraft.server.Whitelist;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import static net.minecraft.server.PlayerManager.WHITELIST_FILE;
@Mixin(PlayerManager.class)
public class PlayerManagerMixin {
@Final @Shadow private final Whitelist whitelist = new ExtendedWhitelist(WHITELIST_FILE);
}

Ver arquivo

@ -0,0 +1,14 @@
package com.awakenedredstone.autowhitelist.mixin;
import net.minecraft.server.ServerConfigEntry;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.gen.Invoker;
@Mixin(ServerConfigEntry.class)
public interface ServerConfigEntryMixin<T> {
@Invoker T callGetKey();
@Accessor T getKey();
}

Ver arquivo

@ -1,13 +1,23 @@
package com.awakenedredstone.autowhitelist.server;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.discord.Bot;
import com.awakenedredstone.autowhitelist.commands.AutoWhitelistCommand;
import com.awakenedredstone.autowhitelist.database.SQLite;
import com.awakenedredstone.autowhitelist.discord.Bot;
import com.awakenedredstone.autowhitelist.lang.JigsawLanguage;
import net.fabricmc.api.DedicatedServerModInitializer;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.minecraft.util.logging.UncaughtExceptionHandler;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import static com.awakenedredstone.autowhitelist.AutoWhitelist.config;
import static com.awakenedredstone.autowhitelist.lang.JigsawLanguage.translations;
@Environment(EnvType.SERVER)
public class AutoWhitelistServer implements DedicatedServerModInitializer {
@ -15,10 +25,35 @@ public class AutoWhitelistServer implements DedicatedServerModInitializer {
@Override
public void onInitializeServer() {
ServerLifecycleEvents.SERVER_STARTING.register(server -> AutoWhitelistCommand.register(server.getCommandManager().getDispatcher()));
ServerLifecycleEvents.SERVER_STOPPED.register((server -> Bot.stopBot()));
ServerLifecycleEvents.SERVER_STOPPING.register((server -> Bot.stopBot()));
ServerLifecycleEvents.SERVER_STARTED.register((server -> {
AutoWhitelist.server = server;
new Bot();
new SQLite().connect();
try {
{
InputStream inputStream = AutoWhitelistServer.class.getResource("/messages.json").openStream();
JigsawLanguage.load(inputStream, translations::put);
}
File file = new File(config.getConfigDirectory(), "AutoWhitelist-assets/messages.json");
File folder = new File(config.getConfigDirectory(), "AutoWhitelist-assets");
if (!folder.exists()) {
folder.mkdir();
}
if (!file.exists()) {
Files.copy(AutoWhitelistServer.class.getResource("/messages.json").openStream(), file.toPath());
}
InputStream inputStream = Files.newInputStream(file.toPath());
JigsawLanguage.load(inputStream, translations::put);
} catch (IOException ignored) {
}
Thread thread = new Thread(new Bot());
thread.setName("AutoWhitelist Bot");
thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler(AutoWhitelist.LOGGER));
thread.setDaemon(true);
thread.start();
}));
}

Ver arquivo

@ -0,0 +1,53 @@
package com.awakenedredstone.autowhitelist.util;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Debugger {
public static final Map<String, long[]> timings = new HashMap<>();
public static void analyzeTimings(String method, Dummy dummy) {
long start = System.nanoTime();
dummy.dummy();
long time = ((System.nanoTime() - start) / 1000);
timings.putIfAbsent(method, new long[]{time});
List<Long> longs = Arrays.stream(timings.get(method)).boxed().collect(Collectors.toList());
longs.add(time);
timings.put(method, longs.stream().mapToLong(l -> l).toArray());
}
public static String formatTimings(long time) {
String metric = "\u00B5s";
if (time > 5000) {
time /= 1000;
metric = "ms";
}
if (time > 10000) {
time /= 1000;
metric = "s";
}
return time + metric;
}
public static String formatTimings(double time) {
String metric = "\u00B5s";
if (time > 5000) {
time /= 1000;
metric = "ms";
}
if (time > 10000) {
time /= 1000;
metric = "s";
}
return String.format("%.2f", time) + metric;
}
public interface Dummy {
void dummy();
}
}

Ver arquivo

@ -0,0 +1,25 @@
package com.awakenedredstone.autowhitelist.util;
import com.mojang.authlib.GameProfile;
import java.util.UUID;
public class ExtendedGameProfile extends GameProfile {
private final String team;
private final String discordId;
public ExtendedGameProfile(UUID id, String name, String team, String discordId) {
super(id, name);
this.team = team;
this.discordId = discordId;
}
public String getTeam() {
return team;
}
public String getDiscordId() {
return discordId;
}
}

Ver arquivo

@ -0,0 +1,20 @@
package com.awakenedredstone.autowhitelist.util;
public class FailedToUpdateWhitelistException extends Exception {
public FailedToUpdateWhitelistException() {
super();
}
public FailedToUpdateWhitelistException(String message) {
super(message);
}
public FailedToUpdateWhitelistException(String message, Throwable cause) {
super(message, cause);
}
public FailedToUpdateWhitelistException(Throwable cause) {
super(cause);
}
}

Ver arquivo

@ -0,0 +1,20 @@
package com.awakenedredstone.autowhitelist.util;
public class InvalidTeamNameException extends Exception {
public InvalidTeamNameException() {
super();
}
public InvalidTeamNameException(String message) {
super(message);
}
public InvalidTeamNameException(String message, Throwable cause) {
super(message, cause);
}
public InvalidTeamNameException(Throwable cause) {
super(cause);
}
}

Ver arquivo

@ -1,28 +0,0 @@
package com.awakenedredstone.autowhitelist.util;
import com.mojang.authlib.GameProfile;
public class MemberPlayer {
private final String userId;
private final GameProfile profile;
private final String team;
public MemberPlayer(GameProfile profile, String team, String userId) {
this.profile = profile;
this.team = team;
this.userId = userId;
}
public GameProfile getProfile() {
return profile;
}
public String getTeam() {
return team;
}
public String getUserId() {
return userId;
}
}

Ver arquivo

@ -0,0 +1,44 @@
package com.awakenedredstone.autowhitelist.util;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import java.io.*;
import java.lang.reflect.Type;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import static com.awakenedredstone.autowhitelist.AutoWhitelist.GSON;
public class UrlQuery {
private static String readAll(Reader rd) throws IOException {
StringBuilder sb = new StringBuilder();
int cp;
while ((cp = rd.read()) != -1) {
sb.append((char) cp);
}
return sb.toString();
}
public static Map<String, String> getMojangStatus() throws IOException {
URL url = new URL("https://status.mojang.com/check");
try (InputStream is = url.openStream()) {
BufferedReader rd = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8));
String jsonText = readAll(rd);
JsonParser parser = new JsonParser();
JsonElement json = parser.parse(jsonText);
JsonArray statusArray = json.getAsJsonArray();
Type type = new TypeToken<Map<String, String>>(){}.getType();
return GSON.fromJson(statusArray.toString(), type);
}
}
public static String statusOf(String url) throws IOException {
return getMojangStatus().get(url);
}
}

Ver arquivo

@ -0,0 +1,97 @@
package com.awakenedredstone.autowhitelist.whitelist;
import com.awakenedredstone.autowhitelist.mixin.ServerConfigEntryMixin;
import com.awakenedredstone.autowhitelist.util.ExtendedGameProfile;
import com.google.gson.JsonObject;
import com.mojang.authlib.GameProfile;
import net.minecraft.server.ServerConfigEntry;
import net.minecraft.server.Whitelist;
import net.minecraft.server.WhitelistEntry;
import javax.annotation.Nullable;
import java.io.File;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public class ExtendedWhitelist extends Whitelist {
public ExtendedWhitelist(File file) {
super(file);
}
protected ServerConfigEntry<GameProfile> fromJson(JsonObject json) {
ExtendedWhitelistEntry entry = new ExtendedWhitelistEntry(json);
try {
((ServerConfigEntryMixin<?>) entry).callGetKey();
if (((ServerConfigEntryMixin<?>) entry).getKey() != null) return entry;
else return new WhitelistEntry(json);
} catch (ClassCastException e) {
return new WhitelistEntry(json);
}
}
public boolean isAllowed(ExtendedGameProfile profile) {
return this.contains(profile);
}
protected String toString(ExtendedGameProfile gameProfile) {
return gameProfile.getId().toString();
}
public JsonObject fromProfile(ExtendedWhitelistEntry entry) {
JsonObject json = new JsonObject();
entry.fromJson(json);
return json;
}
public Collection<? extends WhitelistEntry> getEntries() {
return this.values();
}
public void remove(String var5, Type type) {
switch (type) {
case DISCORD_ID:
values().stream().filter(entry -> {
((ServerConfigEntryMixin<?>) entry).callGetKey();
try {
return ((ExtendedGameProfile) ((ServerConfigEntryMixin<?>) entry).getKey()).getDiscordId().equals(var5);
} catch (ClassCastException exception) {
return false;
}
}).forEach(whitelistEntry -> remove((ExtendedGameProfile) ((ServerConfigEntryMixin<?>) whitelistEntry).getKey()));
break;
case USERNAME:
values().stream().filter(entry -> {
((ServerConfigEntryMixin<?>) entry).callGetKey();
return ((GameProfile) ((ServerConfigEntryMixin<?>) entry).getKey()).getName().equals(var5);
}).forEach(whitelistEntry -> remove((GameProfile) ((ServerConfigEntryMixin<?>) whitelistEntry).getKey()));
break;
}
}
public List<ExtendedGameProfile> getFromDiscordId(String var5) {
return values().stream().filter(entry -> {
((ServerConfigEntryMixin<?>) entry).callGetKey();
try {
return ((ExtendedGameProfile) ((ServerConfigEntryMixin<?>) entry).getKey()).getDiscordId().equals(var5);
} catch (ClassCastException exception) {
return false;
}
}).map(whitelistEntry -> (ExtendedGameProfile) ((ServerConfigEntryMixin<?>) whitelistEntry).getKey()).collect(Collectors.toList());
}
@Nullable
public GameProfile getFromUsername(String var5) {
return values().stream().filter(entry -> {
((ServerConfigEntryMixin<?>) entry).callGetKey();
return ((GameProfile) ((ServerConfigEntryMixin<?>) entry).getKey()).getName().equals(var5);
}).map(whitelistEntry -> (GameProfile) ((ServerConfigEntryMixin<?>) whitelistEntry).getKey()).findFirst().orElse(null);
}
public enum Type {
DISCORD_ID,
USERNAME
}
}

Ver arquivo

@ -0,0 +1,51 @@
package com.awakenedredstone.autowhitelist.whitelist;
import com.awakenedredstone.autowhitelist.mixin.ServerConfigEntryMixin;
import com.awakenedredstone.autowhitelist.util.ExtendedGameProfile;
import com.google.gson.JsonObject;
import net.minecraft.server.WhitelistEntry;
import java.util.UUID;
public class ExtendedWhitelistEntry extends WhitelistEntry {
public ExtendedWhitelistEntry(ExtendedGameProfile profile) {
super(profile);
}
public ExtendedWhitelistEntry(JsonObject json) {
super(profileFromJson(json));
}
public ExtendedGameProfile getProfile() {
((ServerConfigEntryMixin<?>) this).callGetKey();
return (ExtendedGameProfile) ((ServerConfigEntryMixin<?>) this).getKey();
}
protected void fromJson(JsonObject json) {
((ServerConfigEntryMixin<?>) this).callGetKey();
if (((ServerConfigEntryMixin<?>) this).getKey() != null && ((ExtendedGameProfile) ((ServerConfigEntryMixin<?>) this).getKey()).getId() != null) {
json.addProperty("uuid", ((ExtendedGameProfile) ((ServerConfigEntryMixin<?>) this).getKey()).getId().toString());
json.addProperty("name", ((ExtendedGameProfile) ((ServerConfigEntryMixin<?>) this).getKey()).getName());
json.addProperty("team", ((ExtendedGameProfile) ((ServerConfigEntryMixin<?>) this).getKey()).getTeam());
json.addProperty("discordId", ((ExtendedGameProfile) ((ServerConfigEntryMixin<?>) this).getKey()).getDiscordId());
}
}
private static ExtendedGameProfile profileFromJson(JsonObject json) {
if (json.has("uuid") && json.has("name") && json.has("discordId") && json.has("team")) {
String string = json.get("uuid").getAsString();
UUID uUID2;
try {
uUID2 = UUID.fromString(string);
} catch (Throwable var4) {
return null;
}
return new ExtendedGameProfile(uUID2, json.get("name").getAsString(), json.get("team").getAsString(), json.get("discordId").getAsString());
} else {
return null;
}
}
}

Ver arquivo

@ -4,6 +4,8 @@
"package": "com.awakenedredstone.autowhitelist.mixin",
"compatibilityLevel": "JAVA_8",
"mixins": [
"PlayerManagerMixin",
"ServerConfigEntryMixin"
],
"client": [
],

Ver arquivo

@ -24,7 +24,6 @@
],
"depends": {
"fabricloader": ">=0.11.2",
"fabric": "*",
"minecraft": ">=1.17-alpha.21.8.b"
}
}

Ver arquivo

@ -0,0 +1,32 @@
{
"command.register.success.title": "Welcome to the group!",
"command.register.success.message": "Your Minecraft account has been added to the whitelist.\nPlease remember that snapshots are buggy and unstable, so **please** verify before reporting them.\n\n_Please don't mess with what PhoenixSC is working on, you can get your entry removed._",
"command.register.last_steps.title": "Finishing some last things.",
"command.register.last_steps.message": "You request has been accepted.\nPlease wait while I add you to the server whitelist.\nI'll let you know when everything is done.",
"command.register.username_already_registered.title": "This username is already registered.",
"command.register.username_already_registered.message": "The username you inserted is already whitelisted on the server.",
"command.register.already_registered.title": "You're already registered.",
"command.register.already_registered.message": "You already have an account registered. Alt accounts aren't supported. If you want to change the account ask someone with OP on the server to remove your entry.",
"command.register.fatal.null_team": "I could not add you to the whitelist.\n```Tried to get \"net.minecraft.scoreboard.Team\" from \"%s\" but got \"null\".```",
"command.register.invalid_username.title": "Invalid username.",
"command.register.invalid_username.message.too_long": "The username you inserted is too big, a **Minecraft Java Edition** username can be up to 16 characters.",
"command.register.invalid_username.message.too_short": "The username you inserted is too small, a **Minecraft Java Edition** username has to be at least 3 characters long.",
"command.register.fail.not_allowed.title": "Sorry, but I couldn't accept your request.",
"command.register.fail.not_allowed.message": "It seams that you don't have the required subscription/member level or don't have your Twitch/Youtube account linked to your Discord account.",
"command.register.fail.account_data": "I couldn't get the public account data of \"%s\". Is it a valid **Minecraft Java Edition** username?\n_It is only possible to register Minecraft Java Edition accounts._",
"command.fail.title": "Something went wrong.",
"command.few_args.title": "Not enough arguments.",
"command.few_args.message": "You didn't put the minimum amount of arguments required.\nCheck the help command to see the command usage.",
"command.too_many_args.title": "Too many arguments.",
"command.too_many_args.message": "You put too many arguments on the command.\nCheck the help command to see the command usage.",
"command.feedback.received.title": "Command feedback.",
"command.feedback.received.message": "Your request has been received and is being processed, if you don't get another feedback message in the next minute than please contact a moderator.",
"bot.activity.type": "DEFAULT",
"bot.activity.message": "on the Member Server"
}