Update development #5

Merge aplicado
Awakened-Redstone mesclou 27 commits from temp into development 2022-02-18 19:01:36 +00:00
31 arquivos alterados com 1636 adições e 364 exclusões
Mostrando apenas as alterações do commit f69ad77ad9 - Mostrar todos os commits

Merge pull request #2 from Awakened-Redstone/development

Update to v0.2
Awakened-Redstone 2021-03-18 18:55:45 -03:00 commit de GitHub
Nenhuma chave conhecida encontrada para esta assinatura no banco de dados
ID da chave GPG: 4AEE18F83AFDEB23

Ver arquivo

@ -1,126 +1,138 @@
package com.awakenedredstone.autowhitelist; package com.awakenedredstone.autowhitelist;
import com.awakenedredstone.autowhitelist.config.Config; import com.awakenedredstone.autowhitelist.config.Config;
import com.awakenedredstone.autowhitelist.config.JsonHelper; import com.awakenedredstone.autowhitelist.config.ConfigData;
import com.awakenedredstone.autowhitelist.database.SQLite; import com.awakenedredstone.autowhitelist.json.JsonHelper;
import com.awakenedredstone.autowhitelist.util.MemberPlayer; import com.awakenedredstone.autowhitelist.lang.JigsawLanguage;
import com.google.gson.JsonElement; import com.awakenedredstone.autowhitelist.mixin.ServerConfigEntryMixin;
import com.google.gson.JsonParser; 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.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
import net.fabricmc.api.ModInitializer; import net.fabricmc.api.ModInitializer;
import net.minecraft.scoreboard.Scoreboard; import net.minecraft.scoreboard.Scoreboard;
import net.minecraft.scoreboard.Team; 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.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.io.*; import java.io.File;
import java.net.URL; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.io.InputStream;
import java.util.*; import java.nio.file.Files;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.awakenedredstone.autowhitelist.lang.JigsawLanguage.translations;
public class AutoWhitelist implements ModInitializer { public class AutoWhitelist implements ModInitializer {
public static final Config config = new Config(); public static Thread scheduledUpdateThread;
private static final File configFile = new File(config.getConfigDirectory(), "AutoWhitelist.json");
public static MinecraftServer server; public static MinecraftServer server;
public static final Logger logger = LogManager.getLogger("AutoWhitelist"); public static final Config config = new Config();
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");
public static ConfigData getConfigData() {
return config.getConfigData();
}
public static void updateWhitelist() { public static void updateWhitelist() {
logger.info("Updating whitelist.");
PlayerManager playerManager = server.getPlayerManager(); PlayerManager playerManager = server.getPlayerManager();
Whitelist whitelist = playerManager.getWhitelist(); ExtendedWhitelist whitelist = (ExtendedWhitelist) playerManager.getWhitelist();
List<String> usernames = new SQLite().getUsernames(); Scoreboard scoreboard = server.getScoreboard();
Collection<? extends WhitelistEntry> entries = whitelist.getEntries();
for (Map.Entry<String, JsonElement> entry : AutoWhitelist.config.getConfigs().get("whitelist").getAsJsonObject().entrySet()) { List<GameProfile> profiles = entries.stream().map(v -> {
Scoreboard scoreboard = server.getScoreboard(); ((ServerConfigEntryMixin<?>) v).callGetKey();
Team team = scoreboard.getTeam(entry.getKey()); 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) { 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; return;
} }
List<String> invalidPlayers = team.getPlayerList().stream().filter(player -> { List<String> invalidPlayers = team.getPlayerList().stream().filter(player -> {
try { GameProfile profile = profiles.stream().filter(v -> v.getName().equals(player)).findFirst().orElse(null);
GameProfile profile = new GameProfile(UUID.fromString(getUUID(player)), player); if (profile == null) return true;
return !usernames.contains(player) && !playerManager.isOperator(profile); return !whitelist.isAllowed(profile);
} catch (Exception e) {
logger.error("Failed to update whitelist!", e);
return false;
}
}).collect(Collectors.toList()); }).collect(Collectors.toList());
invalidPlayers.forEach(player -> scoreboard.removePlayerFromTeam(player, team)); invalidPlayers.forEach(player -> scoreboard.removePlayerFromTeam(player, team));
} });
try { for (ExtendedGameProfile player : extendedProfiles) {
for (String username : playerManager.getWhitelistedNames()) { if (player == null) continue;
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()) {
Team team = scoreboard.getTeam(player.getTeam()); Team team = scoreboard.getTeam(player.getTeam());
if (team == null) { 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; return;
} }
if (!whitelist.isAllowed(player.getProfile())) { if (scoreboard.getPlayerTeam(player.getName()) != team) {
whitelist.add(new WhitelistEntry(player.getProfile())); scoreboard.clearPlayerTeam(player.getName());
} scoreboard.addPlayerToTeam(player.getName(), team);
if (scoreboard.getPlayerTeam(player.getProfile().getName()) != team) {
scoreboard.addPlayerToTeam(player.getProfile().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)) { 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 scoreboard = server.getScoreboard();
scoreboard.clearPlayerTeam(player.getName()); 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 @Override
public void onInitialize() { public void onInitialize() {
File dir = config.getConfigDirectory(); File dir = config.getConfigDirectory();
@ -130,7 +142,28 @@ public class AutoWhitelist implements ModInitializer {
} }
} }
config.loadConfigs(); 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

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

Ver arquivo

@ -1,17 +1,22 @@
package com.awakenedredstone.autowhitelist.config; package com.awakenedredstone.autowhitelist.config;
import com.awakenedredstone.autowhitelist.AutoWhitelist; import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.json.JsonHelper;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import net.minecraft.text.LiteralText;
import java.io.File; import java.io.*;
import java.nio.file.Files;
import java.util.stream.Collectors;
public class Config { public class Config {
private JsonObject config; private ConfigData configData;
private final File configFile = new File(getConfigDirectory(), "AutoWhitelist.json"); private final File configFile = new File(getConfigDirectory(), "AutoWhitelist.json");
private final int configVersion = 2;
public File getConfigDirectory() { public File getConfigDirectory() {
return new File(".", "config"); return new File(".", "config");
@ -19,24 +24,49 @@ public class Config {
public void loadConfigs() { public void loadConfigs() {
if (configFile.exists() && configFile.isFile() && configFile.canRead()) { if (configFile.exists() && configFile.isFile() && configFile.canRead()) {
JsonElement element = JsonHelper.parseJsonFile(configFile); try (BufferedReader reader = new BufferedReader(new FileReader(configFile))) {
String json = reader.lines().collect(Collectors.joining("\n"));
StringReader stringReader = new StringReader(json);
if (element != null && element.isJsonObject()) { JsonObject jsonObject = new JsonParser().parse(json).getAsJsonObject();
config = element.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) {
AutoWhitelist.LOGGER.error(e);
} }
} }
} }
public JsonObject generateDefaultConfig() { public JsonObject generateDefaultConfig() {
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
json.add("whitelist-auto-update-delay-seconds", new JsonPrimitive(60L)); json.add("version", new JsonPrimitive(configVersion));
json.add("whitelistScheduledVerificationSeconds", new JsonPrimitive(60L));
json.add("prefix", new JsonPrimitive("np!")); json.add("prefix", new JsonPrimitive("np!"));
json.add("token", new JsonPrimitive("bot-token")); json.add("token", new JsonPrimitive("bot-token"));
json.add("application-id", new JsonPrimitive("application-id")); json.add("clientId", new JsonPrimitive("client-id"));
json.add("discord-server-id", new JsonPrimitive("discord-server-id")); json.add("discordServerId", new JsonPrimitive("discord-server-id"));
JsonObject whitelistJson = JsonHelper.getNestedObject(json, "whitelist", true); JsonObject whitelistJson = JsonHelper.getNestedObject(json, "whitelist", true);
if (whitelistJson == null) { 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; return json;
} }
@ -56,7 +86,8 @@ public class Config {
return json; return json;
} }
public JsonObject getConfigs() { public ConfigData getConfigData() {
return config; return configData;
} }
} }

Ver arquivo

@ -0,0 +1,14 @@
package com.awakenedredstone.autowhitelist.config;
import java.util.List;
import java.util.Map;
public class ConfigData {
public long whitelistScheduledVerificationSeconds;
public String prefix;
public String token;
public String clientId;
public String discordServerId;
public Map<String, List<String>> whitelist;
}

Ver arquivo

@ -1,231 +1,58 @@
package com.awakenedredstone.autowhitelist.database; package com.awakenedredstone.autowhitelist.database;
import com.awakenedredstone.autowhitelist.AutoWhitelist; import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.util.MemberPlayer; import com.awakenedredstone.autowhitelist.util.ExtendedGameProfile;
import com.mojang.authlib.GameProfile; import com.awakenedredstone.autowhitelist.whitelist.ExtendedWhitelistEntry;
import net.minecraft.server.MinecraftServer;
import java.io.File; import java.io.File;
import java.sql.*; import java.sql.*;
import java.util.*; import java.util.ArrayList;
import java.util.UUID;
public class SQLite { public class SQLite {
public static Connection connection; private static Connection connection;
public void connect() { public void connect() {
File dir = new File("./config/AutoWhitelist"); File dir = new File("./config/AutoWhitelist");
if(!dir.exists() || !dir.isDirectory()) { if(!dir.exists() || !dir.isDirectory()) {
AutoWhitelist.logger.info("Could not find database. A new one will be created."); //AutoWhitelist.LOGGER.info("Could not find database. A new one will be created.");
dir.mkdir(); return;
} }
File file = new File("./config/AutoWhitelist/users.db");
if (!file.exists()) return;
try { try {
String url = "jdbc:sqlite:config/AutoWhitelist/users.db"; String url = "jdbc:sqlite:config/AutoWhitelist/users.db";
connection = DriverManager.getConnection(url); connection = DriverManager.getConnection(url);
} catch (SQLException e) { } catch (SQLException e) {
AutoWhitelist.logger.error("Failed to load database", e); AutoWhitelist.LOGGER.error("Failed to load old database", e);
return; return;
} }
try { databaseChange();
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);
}
} }
public void updateData(String id, String username, String uuid, String team) { private void databaseChange() {
if (connection == null) { 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; 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 { try {
PreparedStatement statement = connection.prepareStatement("SELECT * FROM `data`"); PreparedStatement statement = connection.prepareStatement("SELECT * FROM `data`");
ResultSet results = statement.executeQuery(); ResultSet results = statement.executeQuery();
ArrayList<String> ids = new ArrayList<>(); ArrayList<ExtendedGameProfile> players = new ArrayList<>();
while (results.next()) { 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) { } catch (SQLException e) {
AutoWhitelist.logger.error("Failed to get the data from the database!", e); AutoWhitelist.LOGGER.error("Failed to get the data from the old 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;
} }
} }
} }

Ver arquivo

@ -0,0 +1,92 @@
package com.awakenedredstone.autowhitelist.discord;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.lang.TranslatableText;
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.JDABuilder;
import net.dv8tion.jda.api.entities.Activity;
import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.utils.MemberCachePolicy;
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.LiteralText;
import net.minecraft.util.logging.UncaughtExceptionHandler;
import javax.security.auth.login.LoginException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;
public class Bot implements Runnable {
private static Bot instance;
static ScheduledFuture<?> scheduledUpdate;
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 (scheduledUpdate != null) {
scheduledUpdate.cancel(false);
try {
scheduledUpdate.get();
} catch (Exception ignored) {
}
}
if (jda != null) jda.shutdown();
}
public static Bot getInstance() {
return instance;
}
public void reloadBot(ServerCommandSource source) {
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();
}
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());
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 bot, please verify the token.");
}
}
}

Ver arquivo

@ -0,0 +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.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.");
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

@ -0,0 +1,132 @@
package com.awakenedredstone.autowhitelist.discord;
import com.awakenedredstone.autowhitelist.AutoWhitelist;
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.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.*;
import static com.awakenedredstone.autowhitelist.util.Debugger.analyzeTimings;
public class DiscordDataProcessor implements Runnable {
/* private void updateWhitelist() {
List<String> ids = new SQLite().getIds();
List<ExtendedGameProfile> 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<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());
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.getId().toString()), player.getId().toString(), entry.getKey());
} catch (IOException e) {
AutoWhitelist.logger.error("Failed to get username!", e);
return;
}
}
}
}
}
} 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

@ -1,7 +1,9 @@
package com.awakenedredstone.autowhitelist.config; package com.awakenedredstone.autowhitelist.json;
import com.awakenedredstone.autowhitelist.AutoWhitelist; import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.google.gson.*; import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File; import java.io.File;
@ -9,9 +11,9 @@ import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
public class JsonHelper { import static com.awakenedredstone.autowhitelist.AutoWhitelist.GSON;
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); public class JsonHelper {
@Nullable @Nullable
public static JsonElement parseJsonFile(File file) { public static JsonElement parseJsonFile(File file) {
@ -27,7 +29,7 @@ public class JsonHelper {
return element; return element;
} catch (Exception e) { } 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);
} }
} }
@ -44,14 +46,14 @@ public class JsonHelper {
return true; return true;
} catch (IOException e) { } 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 { } finally {
try { try {
if (writer != null) { if (writer != null) {
writer.close(); writer.close();
} }
} catch (Exception e) { } catch (Exception e) {
AutoWhitelist.logger.warn("Failed to close JSON file", e); AutoWhitelist.LOGGER.warn("Failed to close JSON file", e);
} }
} }

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,25 +1,59 @@
package com.awakenedredstone.autowhitelist.server; package com.awakenedredstone.autowhitelist.server;
import com.awakenedredstone.autowhitelist.AutoWhitelist; import com.awakenedredstone.autowhitelist.AutoWhitelist;
import com.awakenedredstone.autowhitelist.bot.Bot;
import com.awakenedredstone.autowhitelist.commands.AutoWhitelistCommand; import com.awakenedredstone.autowhitelist.commands.AutoWhitelistCommand;
import com.awakenedredstone.autowhitelist.database.SQLite; 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.DedicatedServerModInitializer;
import net.fabricmc.api.EnvType; import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment; import net.fabricmc.api.Environment;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; 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) @Environment(EnvType.SERVER)
public class AutoWhitelistServer implements DedicatedServerModInitializer { public class AutoWhitelistServer implements DedicatedServerModInitializer {
@Override @Override
public void onInitializeServer() { public void onInitializeServer() {
new SQLite().connect();
ServerLifecycleEvents.SERVER_STARTING.register(server -> AutoWhitelistCommand.register(server.getCommandManager().getDispatcher())); 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 -> { ServerLifecycleEvents.SERVER_STARTED.register((server -> {
AutoWhitelist.server = 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", "package": "com.awakenedredstone.autowhitelist.mixin",
"compatibilityLevel": "JAVA_8", "compatibilityLevel": "JAVA_8",
"mixins": [ "mixins": [
"PlayerManagerMixin",
"ServerConfigEntryMixin"
], ],
"client": [ "client": [
], ],

Ver arquivo

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