From 8973e85a53502e91065c801d9b6948c8bc487109 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Tue, 23 May 2023 22:14:51 +0900 Subject: [PATCH 01/18] =?UTF-8?q?[update]=E3=82=A2=E3=82=AB=E3=82=A6?= =?UTF-8?q?=E3=83=B3=E3=83=88=E3=83=9E=E3=83=8D=E3=83=BC=E3=82=B8=E3=83=A3?= =?UTF-8?q?=E3=82=92=E6=8A=BD=E8=B1=A1=E5=8C=96=E3=81=97=E5=90=84=E3=83=A1?= =?UTF-8?q?=E3=82=BD=E3=83=83=E3=83=89=E3=82=92=E9=9D=9E=E5=90=8C=E6=9C=9F?= =?UTF-8?q?=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../discordconnect/DiscordConnect.java | 21 ++- .../account/AccountManager.java | 59 ++++++ .../discordconnect/account/LinkedAccount.java | 25 +++ .../account/db/DatabaseConfig.java | 19 ++ .../account/db/YamlAccountManager.java | 175 ++++++++++++++++++ .../listener/DiscordListener.java | 7 +- .../discordconnect/util/AccountManager.java | 127 ------------- .../discordconnect/util/ConfigManager.java | 17 ++ src/main/resources/config.yml | 14 ++ 9 files changed, 329 insertions(+), 135 deletions(-) create mode 100644 src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java create mode 100644 src/main/java/work/novablog/mcplugin/discordconnect/account/LinkedAccount.java create mode 100644 src/main/java/work/novablog/mcplugin/discordconnect/account/db/DatabaseConfig.java create mode 100644 src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java delete mode 100644 src/main/java/work/novablog/mcplugin/discordconnect/util/AccountManager.java diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java index 2891126..0ea9fcd 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java @@ -7,12 +7,14 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import org.jetbrains.annotations.NotNull; +import work.novablog.mcplugin.discordconnect.account.AccountManager; +import work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig; +import work.novablog.mcplugin.discordconnect.account.db.YamlAccountManager; import work.novablog.mcplugin.discordconnect.command.BukkitCommand; import work.novablog.mcplugin.discordconnect.command.DiscordCommandExecutor; import work.novablog.mcplugin.discordconnect.command.DiscordStandardCommand; import work.novablog.mcplugin.discordconnect.listener.BukkitListener; import work.novablog.mcplugin.discordconnect.listener.LunaChatListener; -import work.novablog.mcplugin.discordconnect.util.AccountManager; import work.novablog.mcplugin.discordconnect.util.ConfigManager; import work.novablog.mcplugin.discordconnect.util.GithubAPI; import work.novablog.mcplugin.discordconnect.util.discord.BotManager; @@ -20,7 +22,6 @@ import javax.annotation.Nullable; import javax.security.auth.login.LoginException; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Optional; @@ -38,7 +39,7 @@ public final class DiscordConnect extends JavaPlugin { private UUIDCacheData uuidCacheData; private LunaChatListener lunaChatListener; - private final AccountManager accountManager = new AccountManager(new File(getDataFolder(), "accounts.yml")); + private @Nullable AccountManager accountManager; /** * インスタンスを返します @@ -56,7 +57,7 @@ public static DiscordConnect getInstance() { return botManager; } - public AccountManager getAccountManager() { + public @Nullable AccountManager getAccountManager() { return accountManager; } @@ -128,7 +129,14 @@ public void init() { e.printStackTrace(); return; } - accountManager.loadFile(); + + DatabaseConfig dbConfig = configManager.getAccountsDatabaseConfig(); + if (dbConfig instanceof YamlAccountManager.DatabaseConfig) { + accountManager = new YamlAccountManager(getDataFolder(), ((YamlAccountManager.DatabaseConfig) dbConfig)); + } else { + throw new IllegalArgumentException("Unknown database type: " + dbConfig); + } + accountManager.init().whenComplete((v, th) -> th.printStackTrace()); discordCommandExecutor.setAdminRole(configManager.adminRole); @@ -203,5 +211,8 @@ public void init() { public void onDisable() { if(botManager != null) botManager.botShutdown(false); if(discordWebhookSenders != null) discordWebhookSenders.forEach(DiscordWebhookSender::shutdown); + + if (accountManager != null) + accountManager.close().whenComplete((v, th) -> th.printStackTrace()); } } diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java new file mode 100644 index 0000000..cdd3904 --- /dev/null +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java @@ -0,0 +1,59 @@ +package work.novablog.mcplugin.discordconnect.account; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ThreadLocalRandom; + +public abstract class AccountManager { + private final Map linkingCodes = new ConcurrentHashMap<>(); + + + public abstract CompletableFuture init(); + + public abstract CompletableFuture close(); + + + public final String generateCode(UUID playerUuid) { + String codeString; + do { + int code = ThreadLocalRandom.current().nextInt(10000); + codeString = String.format("%04d", code); + + } while (linkingCodes.putIfAbsent(codeString, playerUuid) != null); + return codeString; + } + + public final @Nullable UUID removeMinecraftIdByLinkCode(@NotNull String code) { + return linkingCodes.remove(code); + } + + public final Map linkingCodes() { + return linkingCodes; + } + + + public abstract CompletableFuture<@NotNull Boolean> isLinkedDiscord(@NotNull UUID minecraftId); + + public abstract CompletableFuture<@Nullable Long> getLinkedDiscordId(@NotNull UUID minecraftId); + + public abstract CompletableFuture linkedDiscordId(@NotNull UUID minecraftId, long discordId); + + public abstract CompletableFuture<@NotNull Boolean> isLinkedMinecraft(long discordId); + + public abstract CompletableFuture<@Nullable UUID> getLinkedMinecraftId(long discordId); + + public abstract CompletableFuture unlinkByMinecraftId(@NotNull UUID minecraftId); + + public abstract CompletableFuture unlinkByDiscordId(long discordId); + + + public abstract CompletableFuture getLinkedAccountAll(); + + public abstract CompletableFuture getLinkedAccountCount(); + +} diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/LinkedAccount.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/LinkedAccount.java new file mode 100644 index 0000000..defbd42 --- /dev/null +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/LinkedAccount.java @@ -0,0 +1,25 @@ +package work.novablog.mcplugin.discordconnect.account; + +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +public class LinkedAccount { + + private final @NotNull UUID minecraftId; + private final long discordId; + + public LinkedAccount(@NotNull UUID minecraftId, long discordId) { + this.minecraftId = minecraftId; + this.discordId = discordId; + } + + public @NotNull UUID getMinecraftId() { + return minecraftId; + } + + public long getDiscordId() { + return discordId; + } + +} diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/DatabaseConfig.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/DatabaseConfig.java new file mode 100644 index 0000000..ab99a1f --- /dev/null +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/DatabaseConfig.java @@ -0,0 +1,19 @@ +package work.novablog.mcplugin.discordconnect.account.db; + +import org.bukkit.configuration.ConfigurationSection; + +public abstract class DatabaseConfig { + + protected final ConfigurationSection config; + + public DatabaseConfig(ConfigurationSection config) { + this.config = config; + } + + public abstract String getType(); + + public ConfigurationSection getConfig() { + return config; + } + +} diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java new file mode 100644 index 0000000..1ae01e6 --- /dev/null +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java @@ -0,0 +1,175 @@ +package work.novablog.mcplugin.discordconnect.account.db; + +import com.google.common.collect.Maps; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import work.novablog.mcplugin.discordconnect.account.AccountManager; +import work.novablog.mcplugin.discordconnect.account.LinkedAccount; + +import java.io.File; +import java.io.IOException; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.function.Supplier; + +public class YamlAccountManager extends AccountManager { + private final Map discordAccounts = Maps.newConcurrentMap(); + private final File dataFilePath; + private final DatabaseConfig config; + + public YamlAccountManager(File dataDir, DatabaseConfig config) { + this.config = config; + this.dataFilePath = new File(dataDir, config.getFile()); + } + + + public File getFilePath() { + return dataFilePath; + } + + @Override + public CompletableFuture init() { + discordAccounts.clear(); + if (dataFilePath.isFile()) { + ConfigurationSection ids = YamlConfiguration.loadConfiguration(dataFilePath).getConfigurationSection("ids"); + if (ids != null) { + for (String key : ids.getKeys(false)) { + UUID uuid; + try { + uuid = UUID.fromString(key); + } catch (IllegalArgumentException e) { + continue; + } + long discordId = ids.getLong(key); + discordAccounts.put(uuid, discordId); + } + } + } + return CompletableFuture.completedFuture(null); + } + + @Override + public CompletableFuture close() { + YamlConfiguration config; + if (dataFilePath.isFile()) { + config = YamlConfiguration.loadConfiguration(dataFilePath); + } else { + config = new YamlConfiguration(); + } + + config.set("ids", null); + discordAccounts.forEach((uuid, accountId) -> + config.set("ids." + uuid.toString(), accountId)); + + try { + config.save(dataFilePath); + } catch (IOException e) { + CompletableFuture f = new CompletableFuture<>(); + f.completeExceptionally(e); + return f; + } + return CompletableFuture.completedFuture(null); + } + + + @Override + public CompletableFuture<@NotNull Boolean> isLinkedDiscord(@NotNull UUID minecraftId) { + return runCurrent(() -> discordAccounts.containsKey(minecraftId)); + } + + @Override + public CompletableFuture<@Nullable Long> getLinkedDiscordId(@NotNull UUID minecraftId) { + return runCurrent(() -> discordAccounts.get(minecraftId)); + } + + @Override + public CompletableFuture linkedDiscordId(@NotNull UUID minecraftId, long discordId) { + return runCurrent(() -> { + discordAccounts.put(minecraftId, discordId); + }); + } + + @Override + public CompletableFuture<@NotNull Boolean> isLinkedMinecraft(long discordId) { + return runCurrent(() -> discordAccounts.containsValue(discordId)); + } + + @Override + public CompletableFuture<@Nullable UUID> getLinkedMinecraftId(long discordId) { + return runCurrent(() -> discordAccounts.entrySet().stream() + .filter(e -> e.getValue() == discordId) + .map(Map.Entry::getKey) + .findFirst() + .orElse(null)); + } + + @Override + public CompletableFuture unlinkByMinecraftId(@NotNull UUID minecraftId) { + return runCurrent(() -> { + discordAccounts.remove(minecraftId); + }); + } + + @Override + public CompletableFuture unlinkByDiscordId(long discordId) { + return runCurrent(() -> { + discordAccounts.values().removeIf(dId -> dId == discordId); + }); + } + + + @Override + public CompletableFuture getLinkedAccountAll() { + return runCurrent(() -> discordAccounts.entrySet().stream() + .map(e -> new LinkedAccount(e.getKey(), e.getValue())) + .toArray(LinkedAccount[]::new)); + } + + @Override + public CompletableFuture getLinkedAccountCount() { + return CompletableFuture.completedFuture(discordAccounts.size()); + } + + + private CompletableFuture runCurrent(Supplier runnable) { + try { + return CompletableFuture.completedFuture(runnable.get()); + } catch (Throwable e) { + CompletableFuture f = new CompletableFuture<>(); + f.completeExceptionally(e); + return f; + } + } + + private CompletableFuture runCurrent(Runnable runnable) { + try { + runnable.run(); + return CompletableFuture.completedFuture(null); + } catch (Throwable e) { + CompletableFuture f = new CompletableFuture<>(); + f.completeExceptionally(e); + return f; + } + } + + + public static class DatabaseConfig extends work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig { + public DatabaseConfig(ConfigurationSection config) { + super(config); + } + + @Override + public String getType() { + return "yaml"; + } + + public String getFile() { + return config.getString("file", "./accounts.yml"); + } + + } + +} diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java b/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java index e04fde5..d4c7fc8 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java @@ -15,8 +15,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import work.novablog.mcplugin.discordconnect.DiscordConnect; +import work.novablog.mcplugin.discordconnect.account.AccountManager; import work.novablog.mcplugin.discordconnect.command.DiscordCommandExecutor; -import work.novablog.mcplugin.discordconnect.util.AccountManager; import work.novablog.mcplugin.discordconnect.util.ConfigManager; import work.novablog.mcplugin.discordconnect.util.discord.BotManager; @@ -171,6 +171,8 @@ public void onMessageReceived(@NotNull MessageReceivedEvent receivedMessage) { private boolean processLinkCodeMessage(MessageReceivedEvent event, long userId) { String content = event.getMessage().getContentStripped(); AccountManager mgr = DiscordConnect.getInstance().getAccountManager(); + if (mgr == null) + return false; Matcher matcher = Pattern.compile("(\\d+)").matcher(content); while (matcher.find()) { @@ -183,8 +185,7 @@ private boolean processLinkCodeMessage(MessageReceivedEvent event, long userId) if (player == null) return true; - mgr.setLinkedDiscordId(uuid, userId); - mgr.saveFile(); + mgr.linkedDiscordId(uuid, userId).whenComplete((v, th) -> th.printStackTrace()); String mcid = player.getName(); diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/util/AccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/util/AccountManager.java deleted file mode 100644 index 4f066c5..0000000 --- a/src/main/java/work/novablog/mcplugin/discordconnect/util/AccountManager.java +++ /dev/null @@ -1,127 +0,0 @@ -package work.novablog.mcplugin.discordconnect.util; - -import com.google.common.collect.Maps; -import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.YamlConfiguration; -import org.jetbrains.annotations.Nullable; - -import java.io.File; -import java.io.IOException; -import java.util.Collections; -import java.util.Map; -import java.util.UUID; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ThreadLocalRandom; - -public class AccountManager { - private final Map discordAccounts = Maps.newHashMap(); - private final Map linkingCodes = new ConcurrentHashMap<>(); - private final File dataFilePath; - - public AccountManager(File dataFilePath) { - this.dataFilePath = dataFilePath; - } - - - public String generateCode(UUID playerUuid) { - String codeString; - do { - int code = ThreadLocalRandom.current().nextInt(10000); - codeString = String.format("%04d", code); - - } while (linkingCodes.putIfAbsent(codeString, playerUuid) != null); - return codeString; - } - - public @Nullable UUID removeMinecraftIdByLinkCode(String code) { - return linkingCodes.remove(code); - } - - - public File getFilePath() { - return dataFilePath; - } - - public boolean saveFile() { - YamlConfiguration config; - if (dataFilePath.isFile()) { - config = YamlConfiguration.loadConfiguration(dataFilePath); - } else { - config = new YamlConfiguration(); - } - - config.set("ids", null); - discordAccounts.forEach((uuid, accountId) -> - config.set("ids." + uuid.toString(), accountId)); - - try { - config.save(dataFilePath); - } catch (IOException e) { - e.printStackTrace(); - return false; - } - return true; - } - - public void loadFile() { - discordAccounts.clear(); - if (dataFilePath.isFile()) { - ConfigurationSection ids = YamlConfiguration.loadConfiguration(dataFilePath).getConfigurationSection("ids"); - if (ids != null) { - for (String key : ids.getKeys(false)) { - UUID uuid; - try { - uuid = UUID.fromString(key); - } catch (IllegalArgumentException e) { - continue; - } - long discordId = ids.getLong(key); - discordAccounts.put(uuid, discordId); - } - } - } - } - - - public boolean isLinkedDiscord(UUID minecraftId) { - return discordAccounts.containsKey(minecraftId); - } - - public @Nullable Long getLinkedDiscordId(UUID minecraftId) { - return discordAccounts.get(minecraftId); - } - - public void setLinkedDiscordId(UUID minecraftId, long discordId) { - discordAccounts.put(minecraftId, discordId); - } - - public boolean isLinkedMinecraft(long discordId) { - return discordAccounts.containsValue(discordId); - } - - public @Nullable UUID getLinkedMinecraftId(long discordId) { - return discordAccounts.entrySet().stream() - .filter(e -> e.getValue() == discordId) - .map(Map.Entry::getKey) - .findFirst() - .orElse(null); - } - - public void unlinkByMinecraftId(UUID minecraftId) { - discordAccounts.remove(minecraftId); - } - - public void unlinkByDiscordId(long discordId) { - discordAccounts.values().removeIf(dId -> dId == discordId); - } - - - public Map discordAccounts() { - return discordAccounts; - } - - public Map getDiscordAccounts() { - return Collections.unmodifiableMap(discordAccounts); - } - -} diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java index 4fd7735..8807957 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java @@ -1,8 +1,11 @@ package work.novablog.mcplugin.discordconnect.util; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; +import work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig; +import work.novablog.mcplugin.discordconnect.account.db.YamlAccountManager; import java.io.File; import java.io.IOException; @@ -10,11 +13,13 @@ import java.nio.file.Files; import java.util.List; import java.util.Locale; +import java.util.Optional; public class ConfigManager { private static final int CONFIG_LATEST = 3; private static YamlConfiguration langData; + private final DatabaseConfig accountsDatabaseConfig; public String botToken; public List botWebhookURLs; @@ -83,6 +88,14 @@ public ConfigManager(@NotNull Plugin plugin) throws IOException { lunaChatJapanizeFormat = pluginConfig.getString("japanizeFormat"); linkedToConsoleCommand = pluginConfig.getString("linkedToConsoleCommand"); + + String dbType = Optional.ofNullable(pluginConfig.getString("accounts.dbType")).orElse("yaml"); + ConfigurationSection accountsDatabaseConfigSection = pluginConfig.getConfigurationSection("accounts.database." + dbType); + if (dbType.equalsIgnoreCase("yaml")) { + accountsDatabaseConfig = new YamlAccountManager.DatabaseConfig(accountsDatabaseConfigSection); + } else { + throw new IllegalArgumentException("Unknown database type: " + dbType); + } } private YamlConfiguration getConfigData(Plugin plugin) throws IOException { @@ -108,6 +121,10 @@ private YamlConfiguration getLangData(Plugin plugin) throws IOException { return YamlConfiguration.loadConfiguration(langFile); } + public DatabaseConfig getAccountsDatabaseConfig() { + return accountsDatabaseConfig; + } + private void backupOldFile(Plugin plugin, String targetFileName) throws IOException { File oldFile = new File(plugin.getDataFolder(), targetFileName + "_old"); Files.deleteIfExists(oldFile.toPath()); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 06063be..61e55f0 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -30,5 +30,19 @@ japanizeFormat: "__JP__: {japanized}" # {discordId} --- DiscordユーザーID linkedToConsoleCommand: "" +# アカウントに関するデータベース設定 +accounts: + dbType: yaml # 現在は yaml のみ対応 + database: + yaml: + file: ./accounts.yml + sqlite: + file: ./accounts.db + mysql: + username: root + password: "password" + address: localhost:3306 + database: "discordconnect_accounts" + # この値は変更しないでください! (Don't change the value!) configVersion: 4 \ No newline at end of file From 69ef656ac71dcaa6e42d3ec955afb127ae27fea0 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Tue, 23 May 2023 22:17:41 +0900 Subject: [PATCH 02/18] =?UTF-8?q?[fix]AccountManager.linkedDiscordId=20?= =?UTF-8?q?=E3=82=92=20linkDiscordId=20=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcplugin/discordconnect/account/AccountManager.java | 2 +- .../mcplugin/discordconnect/account/db/YamlAccountManager.java | 2 +- .../mcplugin/discordconnect/listener/DiscordListener.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java index cdd3904..4f08589 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java @@ -41,7 +41,7 @@ public final Map linkingCodes() { public abstract CompletableFuture<@Nullable Long> getLinkedDiscordId(@NotNull UUID minecraftId); - public abstract CompletableFuture linkedDiscordId(@NotNull UUID minecraftId, long discordId); + public abstract CompletableFuture linkDiscordId(@NotNull UUID minecraftId, long discordId); public abstract CompletableFuture<@NotNull Boolean> isLinkedMinecraft(long discordId); diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java index 1ae01e6..82a502a 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java @@ -86,7 +86,7 @@ public CompletableFuture close() { } @Override - public CompletableFuture linkedDiscordId(@NotNull UUID minecraftId, long discordId) { + public CompletableFuture linkDiscordId(@NotNull UUID minecraftId, long discordId) { return runCurrent(() -> { discordAccounts.put(minecraftId, discordId); }); diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java b/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java index d4c7fc8..1b8e339 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java @@ -185,7 +185,7 @@ private boolean processLinkCodeMessage(MessageReceivedEvent event, long userId) if (player == null) return true; - mgr.linkedDiscordId(uuid, userId).whenComplete((v, th) -> th.printStackTrace()); + mgr.linkDiscordId(uuid, userId).whenComplete((v, th) -> th.printStackTrace()); String mcid = player.getName(); From 2cfe7ff1904dcd4c1282da7f6be08eeb66b9f449 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Tue, 23 May 2023 22:24:15 +0900 Subject: [PATCH 03/18] =?UTF-8?q?[fix]=E3=83=AA=E3=83=B3=E3=82=AF=E3=81=8C?= =?UTF-8?q?DB=E3=81=AB=E6=9B=B8=E3=81=8D=E8=BE=BC=E3=82=81=E3=81=9F?= =?UTF-8?q?=E3=82=89=E3=83=AA=E3=83=B3=E3=82=AF=E5=AE=8C=E4=BA=86=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=82=92=E5=AE=9F=E8=A1=8C=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../listener/DiscordListener.java | 65 +++++++++++-------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java b/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java index 1b8e339..91678fa 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java @@ -3,6 +3,7 @@ import com.gmail.necnionch.myapp.markdownconverter.MarkComponent; import com.gmail.necnionch.myapp.markdownconverter.MarkdownConverter; import net.dv8tion.jda.api.entities.ChannelType; +import net.dv8tion.jda.api.entities.MessageChannel; import net.dv8tion.jda.api.entities.User; import net.dv8tion.jda.api.events.message.MessageReceivedEvent; import net.dv8tion.jda.api.hooks.ListenerAdapter; @@ -185,41 +186,49 @@ private boolean processLinkCodeMessage(MessageReceivedEvent event, long userId) if (player == null) return true; - mgr.linkDiscordId(uuid, userId).whenComplete((v, th) -> th.printStackTrace()); + mgr.linkDiscordId(uuid, userId).whenComplete((v, th) -> { + if (th != null) { + th.printStackTrace(); + } else { + Bukkit.getScheduler().callSyncMethod(DiscordConnect.getInstance(), () -> { + processLinkedPlayer(player, event.getAuthor(), event.getChannel()); + return null; + }); + } + }); + return true; + } + return false; + } - String mcid = player.getName(); + private void processLinkedPlayer(Player player, User user, MessageChannel channel) { + String mcid = player.getName(); + try { + player.sendMessage(ConfigManager.Message.accountLinkLinked.toString() + .replaceAll("\\{user}", user.getAsTag())); - User author = event.getAuthor(); - try { - player.sendMessage(ConfigManager.Message.accountLinkLinked.toString() - .replaceAll("\\{user}", author.getAsTag())); + channel.sendMessage(ConfigManager.Message.accountLinkLinkedToDiscord.toString() + .replaceAll("\\{mcid}", mcid)) + .queue(); + + } catch (Throwable e) { + e.printStackTrace(); + } - event.getChannel().sendMessage(ConfigManager.Message.accountLinkLinkedToDiscord.toString() - .replaceAll("\\{mcid}", mcid)) - .queue(); + String linkedCommand = linkedToConsoleCommand; + if (linkedCommand != null && !linkedCommand.isEmpty()) { + try { + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), linkedCommand + .replaceAll("\\{playerId}", player.getUniqueId().toString()) + .replaceAll("\\{discordId}", user.getId()) + .replaceAll("\\{player}", player.getName()) + .replaceAll("\\{discord}", user.getAsTag()) + ); } catch (Throwable e) { e.printStackTrace(); } - - String linkedCommand = linkedToConsoleCommand; - if (linkedCommand != null && !linkedCommand.isEmpty()) { - Bukkit.getScheduler().callSyncMethod(DiscordConnect.getInstance(), () -> { - try { - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), linkedCommand - .replaceAll("\\{playerId}", player.getUniqueId().toString()) - .replaceAll("\\{discordId}", author.getId()) - .replaceAll("\\{player}", player.getName()) - .replaceAll("\\{discord}", author.getAsTag()) - ); - } catch (Throwable e) { - e.printStackTrace(); - } - return null; - }); - } - return true; } - return false; } + } From c80adb2a9fad83b7e6990e39ef9658717186e6ac Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 14:17:24 +0900 Subject: [PATCH 04/18] =?UTF-8?q?[fix]accounts=E3=82=BB=E3=82=AF=E3=82=B7?= =?UTF-8?q?=E3=83=A7=E3=83=B3=E3=81=8C=20config.yml=20=E3=81=AB=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E3=81=97=E3=81=AA=E3=81=84=E6=99=82=E3=81=AE=E3=82=A8?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=82=92=E9=98=B2=E3=81=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcplugin/discordconnect/util/ConfigManager.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java index 8807957..b48c941 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java @@ -90,9 +90,12 @@ public ConfigManager(@NotNull Plugin plugin) throws IOException { linkedToConsoleCommand = pluginConfig.getString("linkedToConsoleCommand"); String dbType = Optional.ofNullable(pluginConfig.getString("accounts.dbType")).orElse("yaml"); - ConfigurationSection accountsDatabaseConfigSection = pluginConfig.getConfigurationSection("accounts.database." + dbType); + ConfigurationSection dbSection = pluginConfig.getConfigurationSection("accounts.database." + dbType); + if (dbSection == null) + dbSection = new YamlConfiguration(); + if (dbType.equalsIgnoreCase("yaml")) { - accountsDatabaseConfig = new YamlAccountManager.DatabaseConfig(accountsDatabaseConfigSection); + accountsDatabaseConfig = new YamlAccountManager.DatabaseConfig(dbSection); } else { throw new IllegalArgumentException("Unknown database type: " + dbType); } From 386f7944b5bff928744023c1c132e2ff71187ef5 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 14:19:25 +0900 Subject: [PATCH 05/18] =?UTF-8?q?[update]YamlAccountManager=E3=81=AE?= =?UTF-8?q?=E5=88=9D=E6=9C=9F=E5=8C=96=E5=87=A6=E7=90=86=E3=82=92Future?= =?UTF-8?q?=E3=81=A7=E5=9B=B2=E3=81=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../account/db/YamlAccountManager.java | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java index 82a502a..0d02f85 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java @@ -26,12 +26,11 @@ public YamlAccountManager(File dataDir, DatabaseConfig config) { } - public File getFilePath() { - return dataFilePath; + public DatabaseConfig getConfig() { + return config; } - @Override - public CompletableFuture init() { + public void loadFile() { discordAccounts.clear(); if (dataFilePath.isFile()) { ConfigurationSection ids = YamlConfiguration.loadConfiguration(dataFilePath).getConfigurationSection("ids"); @@ -48,11 +47,9 @@ public CompletableFuture init() { } } } - return CompletableFuture.completedFuture(null); } - @Override - public CompletableFuture close() { + public void saveFile() throws IOException { YamlConfiguration config; if (dataFilePath.isFile()) { config = YamlConfiguration.loadConfiguration(dataFilePath); @@ -64,14 +61,25 @@ public CompletableFuture close() { discordAccounts.forEach((uuid, accountId) -> config.set("ids." + uuid.toString(), accountId)); - try { - config.save(dataFilePath); - } catch (IOException e) { - CompletableFuture f = new CompletableFuture<>(); - f.completeExceptionally(e); - return f; - } - return CompletableFuture.completedFuture(null); + config.save(dataFilePath); + } + + + @Override + public CompletableFuture init() { + return runCurrent(this::loadFile); + } + + @Override + public CompletableFuture close() { + return runCurrent(() -> { + try { + saveFile(); + } catch (IOException e) { + e.printStackTrace(); + } + discordAccounts.clear(); + }); } From 13e6e2c1db9489592742051b5b1700c413af9515 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 14:28:11 +0900 Subject: [PATCH 06/18] =?UTF-8?q?[fix]YamlAccountManager=E3=81=8C=E5=A4=89?= =?UTF-8?q?=E6=9B=B4=E3=82=92=E4=BF=9D=E5=AD=98=E3=81=97=E3=81=AA=E3=81=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../account/db/YamlAccountManager.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java index 0d02f85..6922f6c 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java @@ -73,11 +73,7 @@ public CompletableFuture init() { @Override public CompletableFuture close() { return runCurrent(() -> { - try { - saveFile(); - } catch (IOException e) { - e.printStackTrace(); - } + saveFile(); discordAccounts.clear(); }); } @@ -97,6 +93,7 @@ public CompletableFuture close() { public CompletableFuture linkDiscordId(@NotNull UUID minecraftId, long discordId) { return runCurrent(() -> { discordAccounts.put(minecraftId, discordId); + saveFile(); }); } @@ -117,14 +114,16 @@ public CompletableFuture linkDiscordId(@NotNull UUID minecraftId, long dis @Override public CompletableFuture unlinkByMinecraftId(@NotNull UUID minecraftId) { return runCurrent(() -> { - discordAccounts.remove(minecraftId); + if (discordAccounts.remove(minecraftId) != null) + saveFile(); }); } @Override public CompletableFuture unlinkByDiscordId(long discordId) { return runCurrent(() -> { - discordAccounts.values().removeIf(dId -> dId == discordId); + if (discordAccounts.values().removeIf(dId -> dId == discordId)) + saveFile(); }); } @@ -152,7 +151,7 @@ private CompletableFuture runCurrent(Supplier runnable) { } } - private CompletableFuture runCurrent(Runnable runnable) { + private CompletableFuture runCurrent(ThrowRunnable runnable) { try { runnable.run(); return CompletableFuture.completedFuture(null); @@ -163,6 +162,10 @@ private CompletableFuture runCurrent(Runnable runnable) { } } + private interface ThrowRunnable { + void run() throws Throwable; + } + public static class DatabaseConfig extends work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig { public DatabaseConfig(ConfigurationSection config) { From 78ddea301e097ef54ae74e7ac4b040c7bf9fba08 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 14:44:41 +0900 Subject: [PATCH 07/18] =?UTF-8?q?[update]AccountManager=E3=81=AE=E6=8E=A5?= =?UTF-8?q?=E7=B6=9A/=E5=88=87=E6=96=AD=E3=83=A1=E3=82=BD=E3=83=83?= =?UTF-8?q?=E3=83=89=E3=82=92=E5=90=8C=E6=9C=9F=E5=87=A6=E7=90=86=E3=81=AB?= =?UTF-8?q?=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcplugin/discordconnect/DiscordConnect.java | 15 ++++++++++++--- .../discordconnect/account/AccountManager.java | 5 +++-- .../account/db/YamlAccountManager.java | 12 +++++------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java index 0ea9fcd..bf65768 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java @@ -136,7 +136,11 @@ public void init() { } else { throw new IllegalArgumentException("Unknown database type: " + dbConfig); } - accountManager.init().whenComplete((v, th) -> th.printStackTrace()); + try { + accountManager.connect(); + } catch (IOException e) { + e.printStackTrace(); + } discordCommandExecutor.setAdminRole(configManager.adminRole); @@ -212,7 +216,12 @@ public void onDisable() { if(botManager != null) botManager.botShutdown(false); if(discordWebhookSenders != null) discordWebhookSenders.forEach(DiscordWebhookSender::shutdown); - if (accountManager != null) - accountManager.close().whenComplete((v, th) -> th.printStackTrace()); + if (accountManager != null) { + try { + accountManager.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } } diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java index 4f08589..5c9281d 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java @@ -3,6 +3,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.IOException; import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -13,9 +14,9 @@ public abstract class AccountManager { private final Map linkingCodes = new ConcurrentHashMap<>(); - public abstract CompletableFuture init(); + public abstract void connect() throws IOException; - public abstract CompletableFuture close(); + public abstract void close() throws IOException; public final String generateCode(UUID playerUuid) { diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java index 6922f6c..efe4696 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/YamlAccountManager.java @@ -66,16 +66,14 @@ public void saveFile() throws IOException { @Override - public CompletableFuture init() { - return runCurrent(this::loadFile); + public void connect() { + loadFile(); } @Override - public CompletableFuture close() { - return runCurrent(() -> { - saveFile(); - discordAccounts.clear(); - }); + public void close() throws IOException { + saveFile(); + discordAccounts.clear(); } From 48ce66269ae533d4dab0b16e6474a259d953e2f7 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 14:47:00 +0900 Subject: [PATCH 08/18] =?UTF-8?q?[fix]=E3=83=97=E3=83=A9=E3=82=B0=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E3=81=AE=E5=88=9D=E6=9C=9F=E5=8C=96=E3=81=AB=E5=A4=B1?= =?UTF-8?q?=E6=95=97=E3=81=97=E3=81=9F=E3=82=89=20setEnabled(false)=20?= =?UTF-8?q?=E3=81=A7=E7=84=A1=E5=8A=B9=E5=8C=96=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../discordconnect/DiscordConnect.java | 24 +++++++------------ 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java index bf65768..cceed34 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java @@ -106,7 +106,12 @@ public void onEnable() { discordCommandExecutor = new DiscordCommandExecutor(); discordCommandExecutor.registerCommand(new DiscordStandardCommand()); - init(); + try { + init(); + } catch (Throwable e) { + e.printStackTrace(); + setEnabled(false); + } } /** @@ -116,31 +121,20 @@ public void onEnable() { * 複数回呼び出した場合、新しいconfigデータが読み出されます *

*/ - public void init() { + public void init() throws IOException { if(botManager != null) botManager.botShutdown(true); if(discordWebhookSenders != null) discordWebhookSenders.forEach(DiscordWebhookSender::shutdown); if(bukkitListener != null) HandlerList.unregisterAll(bukkitListener); if(lunaChatListener != null) HandlerList.unregisterAll(lunaChatListener); - ConfigManager configManager; - try { - configManager = new ConfigManager(this); - } catch (IOException e) { - e.printStackTrace(); - return; - } - + ConfigManager configManager = new ConfigManager(this); DatabaseConfig dbConfig = configManager.getAccountsDatabaseConfig(); if (dbConfig instanceof YamlAccountManager.DatabaseConfig) { accountManager = new YamlAccountManager(getDataFolder(), ((YamlAccountManager.DatabaseConfig) dbConfig)); } else { throw new IllegalArgumentException("Unknown database type: " + dbConfig); } - try { - accountManager.connect(); - } catch (IOException e) { - e.printStackTrace(); - } + accountManager.connect(); discordCommandExecutor.setAdminRole(configManager.adminRole); From e273818a2c9ef574e195349808bf277bd130c21c Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 14:47:30 +0900 Subject: [PATCH 09/18] =?UTF-8?q?[fix]=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=82=92=E7=99=BB=E9=8C=B2=E3=81=99=E3=82=8B=E5=89=8D=E3=81=AB?= =?UTF-8?q?=E3=83=97=E3=83=A9=E3=82=B0=E3=82=A4=E3=83=B3=E3=82=92=E5=88=9D?= =?UTF-8?q?=E6=9C=9F=E5=8C=96=E3=81=95=E3=81=9B=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcplugin/discordconnect/DiscordConnect.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java index cceed34..5bb5af6 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java @@ -100,18 +100,19 @@ public void onEnable() { lunaChatAPI = ((LunaChatBukkit) temp).getLunaChatAPI(); } - //コマンドの追加 - Optional.ofNullable(getCommand("discordconnect")) - .ifPresent(cmd -> cmd.setExecutor(new BukkitCommand())); - discordCommandExecutor = new DiscordCommandExecutor(); - discordCommandExecutor.registerCommand(new DiscordStandardCommand()); - try { init(); } catch (Throwable e) { e.printStackTrace(); setEnabled(false); + return; } + + //コマンドの追加 + Optional.ofNullable(getCommand("discordconnect")) + .ifPresent(cmd -> cmd.setExecutor(new BukkitCommand())); + discordCommandExecutor = new DiscordCommandExecutor(); + discordCommandExecutor.registerCommand(new DiscordStandardCommand()); } /** From 08daf203612f8f2958f545a3de57e8f8ba41658b Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 15:01:21 +0900 Subject: [PATCH 10/18] =?UTF-8?q?[fix]=E8=A8=AD=E5=AE=9A=E5=86=8D=E8=AA=AD?= =?UTF-8?q?=E3=81=BF=E8=BE=BC=E3=81=BF=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=81=A7init=E3=82=92try=E3=81=A7=E5=9B=B2=E3=81=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcplugin/discordconnect/command/BukkitCommand.java | 8 +++++++- .../discordconnect/command/DiscordStandardCommand.java | 6 +++++- .../mcplugin/discordconnect/util/ConfigManager.java | 1 + src/main/resources/ja_JP.yml | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java b/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java index f2d61b0..47f689d 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java @@ -46,7 +46,13 @@ public void linkCmd(CommandSender sender, String[] args) { } public void reloadCmd(CommandSender sender, String[] args) { - DiscordConnect.getInstance().init(); + try { + DiscordConnect.getInstance().init(); + } catch (Throwable e) { + e.printStackTrace(); + sender.sendMessage(ConfigManager.Message.configReloadFailed.toString()); + return; + } sender.sendMessage(ConfigManager.Message.configReloaded.toString()); } diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/command/DiscordStandardCommand.java b/src/main/java/work/novablog/mcplugin/discordconnect/command/DiscordStandardCommand.java index 72b76c6..0601f91 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/command/DiscordStandardCommand.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/command/DiscordStandardCommand.java @@ -103,6 +103,10 @@ public void reloadCmd(Member member, DiscordBotSender channel, String[] args) { eb.setDescription(ConfigManager.Message.discordCommandReloading.toString()); channel.addQueue(eb.build()); - DiscordConnect.getInstance().init(); + try { + DiscordConnect.getInstance().init(); + } catch (Throwable e) { + e.printStackTrace(); + } } } diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java index b48c941..ccc5158 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java @@ -147,6 +147,7 @@ public enum Message { botIsReady, botRestarted, configReloaded, + configReloadFailed, configPropertyIsNull, dispatchedCommand, bungeeCommandPlayerOnly, diff --git a/src/main/resources/ja_JP.yml b/src/main/resources/ja_JP.yml index ae16e02..0858d4e 100644 --- a/src/main/resources/ja_JP.yml +++ b/src/main/resources/ja_JP.yml @@ -7,6 +7,7 @@ normalShutdown: "botのシャットダウンを行います" botIsReady: "botのログインが完了しました" botRestarted: "botの再起動が完了しました" configReloaded: "§2configの再読込が完了しました" +configReloadFailed: "§cconfigの再読込中にエラーが発生しました" configPropertyIsNull: "コンフィグの {property} プロパティが定義されていません。" dispatchedCommand: "ユーザーID {authorId} がコマンド {commandLine} を実行しました。" From 68025315e1d345346e1ab6320d711c52f6f9331d Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 15:01:21 +0900 Subject: [PATCH 11/18] =?UTF-8?q?[fix]=E8=A8=AD=E5=AE=9A=E5=86=8D=E8=AA=AD?= =?UTF-8?q?=E3=81=BF=E8=BE=BC=E3=81=BF=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=81=A7init=E3=82=92try=E3=81=A7=E5=9B=B2=E3=81=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcplugin/discordconnect/command/BukkitCommand.java | 8 +++++++- .../discordconnect/command/DiscordStandardCommand.java | 6 +++++- .../mcplugin/discordconnect/util/ConfigManager.java | 1 + src/main/resources/ja_JP.yml | 1 + 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java b/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java index f2d61b0..47f689d 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java @@ -46,7 +46,13 @@ public void linkCmd(CommandSender sender, String[] args) { } public void reloadCmd(CommandSender sender, String[] args) { - DiscordConnect.getInstance().init(); + try { + DiscordConnect.getInstance().init(); + } catch (Throwable e) { + e.printStackTrace(); + sender.sendMessage(ConfigManager.Message.configReloadFailed.toString()); + return; + } sender.sendMessage(ConfigManager.Message.configReloaded.toString()); } diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/command/DiscordStandardCommand.java b/src/main/java/work/novablog/mcplugin/discordconnect/command/DiscordStandardCommand.java index 72b76c6..0601f91 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/command/DiscordStandardCommand.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/command/DiscordStandardCommand.java @@ -103,6 +103,10 @@ public void reloadCmd(Member member, DiscordBotSender channel, String[] args) { eb.setDescription(ConfigManager.Message.discordCommandReloading.toString()); channel.addQueue(eb.build()); - DiscordConnect.getInstance().init(); + try { + DiscordConnect.getInstance().init(); + } catch (Throwable e) { + e.printStackTrace(); + } } } diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java index b48c941..ccc5158 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java @@ -147,6 +147,7 @@ public enum Message { botIsReady, botRestarted, configReloaded, + configReloadFailed, configPropertyIsNull, dispatchedCommand, bungeeCommandPlayerOnly, diff --git a/src/main/resources/ja_JP.yml b/src/main/resources/ja_JP.yml index ae16e02..0858d4e 100644 --- a/src/main/resources/ja_JP.yml +++ b/src/main/resources/ja_JP.yml @@ -7,6 +7,7 @@ normalShutdown: "botのシャットダウンを行います" botIsReady: "botのログインが完了しました" botRestarted: "botの再起動が完了しました" configReloaded: "§2configの再読込が完了しました" +configReloadFailed: "§cconfigの再読込中にエラーが発生しました" configPropertyIsNull: "コンフィグの {property} プロパティが定義されていません。" dispatchedCommand: "ユーザーID {authorId} がコマンド {commandLine} を実行しました。" From ff0688ccd66f845b95e2df756e3bcd317bf2852c Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 17:10:34 +0900 Subject: [PATCH 12/18] =?UTF-8?q?[add]SQLite=E3=83=87=E3=83=BC=E3=82=BF?= =?UTF-8?q?=E3=83=99=E3=83=BC=E3=82=B9=E3=81=AE=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../discordconnect/DiscordConnect.java | 3 + .../account/db/SQLiteAccountManager.java | 290 ++++++++++++++++++ .../discordconnect/util/ConfigManager.java | 3 + src/main/resources/config.yml | 3 +- 5 files changed, 299 insertions(+), 1 deletion(-) create mode 100644 src/main/java/work/novablog/mcplugin/discordconnect/account/db/SQLiteAccountManager.java diff --git a/build.gradle b/build.gradle index 16e9d74..bd5f47f 100644 --- a/build.gradle +++ b/build.gradle @@ -32,6 +32,7 @@ dependencies { implementation("net.dv8tion:JDA:5.0.0-alpha.3") { exclude module: 'opus-java' } + implementation('com.zaxxer:HikariCP:5.0.1') implementation 'club.minnced:discord-webhooks:0.7.4' implementation 'com.fasterxml.jackson.core:jackson-core:2.13.1' implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.1' diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java index cceed34..7423674 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull; import work.novablog.mcplugin.discordconnect.account.AccountManager; import work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig; +import work.novablog.mcplugin.discordconnect.account.db.SQLiteAccountManager; import work.novablog.mcplugin.discordconnect.account.db.YamlAccountManager; import work.novablog.mcplugin.discordconnect.command.BukkitCommand; import work.novablog.mcplugin.discordconnect.command.DiscordCommandExecutor; @@ -131,6 +132,8 @@ public void init() throws IOException { DatabaseConfig dbConfig = configManager.getAccountsDatabaseConfig(); if (dbConfig instanceof YamlAccountManager.DatabaseConfig) { accountManager = new YamlAccountManager(getDataFolder(), ((YamlAccountManager.DatabaseConfig) dbConfig)); + } else if (dbConfig instanceof SQLiteAccountManager.DatabaseConfig) { + accountManager = new SQLiteAccountManager(getDataFolder(), ((SQLiteAccountManager.DatabaseConfig) dbConfig)); } else { throw new IllegalArgumentException("Unknown database type: " + dbConfig); } diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/SQLiteAccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/SQLiteAccountManager.java new file mode 100644 index 0000000..f28c472 --- /dev/null +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/SQLiteAccountManager.java @@ -0,0 +1,290 @@ +package work.novablog.mcplugin.discordconnect.account.db; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import work.novablog.mcplugin.discordconnect.account.AccountManager; +import work.novablog.mcplugin.discordconnect.account.LinkedAccount; + +import java.io.File; +import java.io.IOException; +import java.sql.*; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +public class SQLiteAccountManager extends AccountManager { + + private final DatabaseConfig config; + private final File dataDir; + private @Nullable HikariDataSource hikari; + + public SQLiteAccountManager(File dataDir, DatabaseConfig config) { + this.dataDir = dataDir; + this.config = config; + } + + public DatabaseConfig getConfig() { + return config; + } + + @Override + public void connect() throws IOException { + HikariConfig config = new HikariConfig(); + config.setDriverClassName("org.sqlite.JDBC"); + config.setJdbcUrl("jdbc:sqlite:" + new File(dataDir, this.config.getFile())); + config.setConnectionInitSql("SELECT 1"); + config.setAutoCommit(true); + this.config.getProperties().forEach(config::addDataSourceProperty); + hikari = new HikariDataSource(config); + initDatabase(); + } + + @Override + public void close() { + if (hikari != null) { + hikari.close(); + } + hikari = null; + } + + public void initDatabase() throws IOException { + if (hikari == null) + throw new IOException("database closed"); + + try (Connection conn = hikari.getConnection(); + Statement stmt = conn.createStatement()) { + String sql = "CREATE TABLE IF NOT EXISTS linked (mc_uuid VARCHAR(36) UNIQUE, discord_id BIGINT, link_time BIGINT)"; + stmt.execute(sql); + } catch (SQLException e) { + throw new IOException(e); + } + } + + + @Override + public CompletableFuture<@NotNull Boolean> isLinkedDiscord(@NotNull UUID minecraftId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT 1 FROM `linked` WHERE `mc_uuid` = ? LIMIT 1"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, minecraftId.toString().toLowerCase(Locale.ROOT)); + ResultSet rs = stmt.executeQuery(); + return rs.next(); + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture<@Nullable Long> getLinkedDiscordId(@NotNull UUID minecraftId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT `discord_id` FROM `linked` WHERE `mc_uuid` = ? LIMIT 1"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, minecraftId.toString().toLowerCase(Locale.ROOT)); + ResultSet rs = stmt.executeQuery(); + + if (rs.next()) + return rs.getLong("discord_id"); + return null; + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture linkDiscordId(@NotNull UUID minecraftId, long discordId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + try (Connection conn = hikari.getConnection()) { + try (PreparedStatement stmt = conn.prepareStatement("DELETE FROM `linked` WHERE `discord_id` = ?")) { + stmt.setLong(1, discordId); + stmt.execute(); + } + + try (PreparedStatement stmt = conn.prepareStatement("REPLACE INTO `linked` VALUES (?, ?, ?)")) { + stmt.setString(1, minecraftId.toString().toLowerCase(Locale.ROOT)); + stmt.setLong(2, discordId); + stmt.setLong(3, System.currentTimeMillis()); + stmt.executeUpdate(); + } + + } catch (SQLException e) { + throw new CompletionException(e); + } + return null; + }); + } + + @Override + public CompletableFuture<@NotNull Boolean> isLinkedMinecraft(long discordId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT 1 FROM `linked` WHERE `discord_id` = ? LIMIT 1"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setLong(1, discordId); + ResultSet rs = stmt.executeQuery(); + return rs.next(); + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture<@Nullable UUID> getLinkedMinecraftId(long discordId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT `mc_uuid` FROM `linked` WHERE `discord_id` = ? LIMIT 1"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setLong(1, discordId); + ResultSet rs = stmt.executeQuery(); + + if (rs.next()) + return UUID.fromString(rs.getString("mc_uuid")); + return null; + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture unlinkByMinecraftId(@NotNull UUID minecraftId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "DELETE FROM `linked` WHERE `mc_uuid` = ?"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, minecraftId.toString().toLowerCase(Locale.ROOT)); + stmt.executeUpdate(); + + } catch (SQLException e) { + throw new CompletionException(e); + } + return null; + }); + } + + @Override + public CompletableFuture unlinkByDiscordId(long discordId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "DELETE FROM `linked` WHERE `discord_id` = ?"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setLong(1, discordId); + stmt.executeUpdate(); + + } catch (SQLException e) { + throw new CompletionException(e); + } + return null; + }); + } + + @Override + public CompletableFuture getLinkedAccountAll() { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT `mc_uuid`, `discord_id` FROM `linked`"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql); + ResultSet rs = stmt.executeQuery()) { + + List data = Lists.newArrayList(); + while (rs.next()) + data.add(new LinkedAccount(UUID.fromString(rs.getString(1)), rs.getLong(2))); + + return data.toArray(new LinkedAccount[0]); + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture getLinkedAccountCount() { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT COUNT(*) AS `total` FROM `linked`"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql); + ResultSet rs = stmt.executeQuery()) { + + if (rs.next()) + return rs.getInt("total"); + return 0; + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + + public static class DatabaseConfig extends work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig { + + public DatabaseConfig(ConfigurationSection config) { + super(config); + } + + @Override + public String getType() { + return "sqlite"; + } + + public String getFile() { + return config.getString("file", "./accounts.yml"); + } + + public Map getProperties() { + ConfigurationSection props = config.getConfigurationSection("properties"); + if (props == null) + return Collections.emptyMap(); + + Map values = Maps.newHashMap(); + for (String key : props.getKeys(false)) { + values.put(key, props.get(key)); + } + + return values; + } + + } + +} diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java index ccc5158..39e9d45 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java @@ -5,6 +5,7 @@ import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig; +import work.novablog.mcplugin.discordconnect.account.db.SQLiteAccountManager; import work.novablog.mcplugin.discordconnect.account.db.YamlAccountManager; import java.io.File; @@ -96,6 +97,8 @@ public ConfigManager(@NotNull Plugin plugin) throws IOException { if (dbType.equalsIgnoreCase("yaml")) { accountsDatabaseConfig = new YamlAccountManager.DatabaseConfig(dbSection); + } else if (dbType.equalsIgnoreCase("sqlite")) { + accountsDatabaseConfig = new SQLiteAccountManager.DatabaseConfig(dbSection); } else { throw new IllegalArgumentException("Unknown database type: " + dbType); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 61e55f0..08de631 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -32,12 +32,13 @@ linkedToConsoleCommand: "" # アカウントに関するデータベース設定 accounts: - dbType: yaml # 現在は yaml のみ対応 + dbType: yaml # 現在は yaml, sqlite のみ対応 database: yaml: file: ./accounts.yml sqlite: file: ./accounts.db + properties: {} mysql: username: root password: "password" From 4d6f14a1e00e19a9a73290e4b37101a7aec8b705 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 17:24:52 +0900 Subject: [PATCH 13/18] =?UTF-8?q?[add]MySQL=E3=83=87=E3=83=BC=E3=82=BF?= =?UTF-8?q?=E3=83=99=E3=83=BC=E3=82=B9=E3=81=AE=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../discordconnect/DiscordConnect.java | 3 + .../account/db/MySQLAccountManager.java | 291 ++++++++++++++++++ .../discordconnect/util/ConfigManager.java | 3 + src/main/resources/config.yml | 7 +- 4 files changed, 301 insertions(+), 3 deletions(-) create mode 100644 src/main/java/work/novablog/mcplugin/discordconnect/account/db/MySQLAccountManager.java diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java index 7423674..28316b3 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java @@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull; import work.novablog.mcplugin.discordconnect.account.AccountManager; import work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig; +import work.novablog.mcplugin.discordconnect.account.db.MySQLAccountManager; import work.novablog.mcplugin.discordconnect.account.db.SQLiteAccountManager; import work.novablog.mcplugin.discordconnect.account.db.YamlAccountManager; import work.novablog.mcplugin.discordconnect.command.BukkitCommand; @@ -134,6 +135,8 @@ public void init() throws IOException { accountManager = new YamlAccountManager(getDataFolder(), ((YamlAccountManager.DatabaseConfig) dbConfig)); } else if (dbConfig instanceof SQLiteAccountManager.DatabaseConfig) { accountManager = new SQLiteAccountManager(getDataFolder(), ((SQLiteAccountManager.DatabaseConfig) dbConfig)); + } else if (dbConfig instanceof MySQLAccountManager.DatabaseConfig) { + accountManager = new MySQLAccountManager(((MySQLAccountManager.DatabaseConfig) dbConfig)); } else { throw new IllegalArgumentException("Unknown database type: " + dbConfig); } diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/db/MySQLAccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/MySQLAccountManager.java new file mode 100644 index 0000000..c73479d --- /dev/null +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/db/MySQLAccountManager.java @@ -0,0 +1,291 @@ +package work.novablog.mcplugin.discordconnect.account.db; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.bukkit.configuration.ConfigurationSection; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import work.novablog.mcplugin.discordconnect.account.AccountManager; +import work.novablog.mcplugin.discordconnect.account.LinkedAccount; + +import java.io.IOException; +import java.sql.*; +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; + +public class MySQLAccountManager extends AccountManager { + + private final DatabaseConfig config; + private @Nullable HikariDataSource hikari; + + public MySQLAccountManager(DatabaseConfig config) { + this.config = config; + } + + public DatabaseConfig getConfig() { + return config; + } + + @Override + public void connect() throws IOException { + HikariConfig config = new HikariConfig(); + config.setDriverClassName("com.mysql.jdbc.Driver"); + config.setJdbcUrl("jdbc:mysql://" + this.config.getAddress() + "/" + this.config.getDatabase()); + config.setConnectionInitSql("SELECT 1"); + config.setAutoCommit(true); + this.config.getProperties().forEach(config::addDataSourceProperty); + hikari = new HikariDataSource(config); + initDatabase(); + } + + @Override + public void close() { + if (hikari != null) { + hikari.close(); + } + hikari = null; + } + + public void initDatabase() throws IOException { + if (hikari == null) + throw new IOException("database closed"); + + try (Connection conn = hikari.getConnection(); + Statement stmt = conn.createStatement()) { + String sql = "CREATE TABLE IF NOT EXISTS linked (mc_uuid VARCHAR(36) UNIQUE, discord_id BIGINT, link_time BIGINT)"; + stmt.execute(sql); + } catch (SQLException e) { + throw new IOException(e); + } + } + + + @Override + public CompletableFuture<@NotNull Boolean> isLinkedDiscord(@NotNull UUID minecraftId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT 1 FROM `linked` WHERE `mc_uuid` = ? LIMIT 1"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, minecraftId.toString().toLowerCase(Locale.ROOT)); + ResultSet rs = stmt.executeQuery(); + return rs.next(); + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture<@Nullable Long> getLinkedDiscordId(@NotNull UUID minecraftId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT `discord_id` FROM `linked` WHERE `mc_uuid` = ? LIMIT 1"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, minecraftId.toString().toLowerCase(Locale.ROOT)); + ResultSet rs = stmt.executeQuery(); + + if (rs.next()) + return rs.getLong("discord_id"); + return null; + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture linkDiscordId(@NotNull UUID minecraftId, long discordId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + try (Connection conn = hikari.getConnection()) { + try (PreparedStatement stmt = conn.prepareStatement("DELETE FROM `linked` WHERE `discord_id` = ?")) { + stmt.setLong(1, discordId); + stmt.execute(); + } + + try (PreparedStatement stmt = conn.prepareStatement("REPLACE INTO `linked` VALUES (?, ?, ?)")) { + stmt.setString(1, minecraftId.toString().toLowerCase(Locale.ROOT)); + stmt.setLong(2, discordId); + stmt.setLong(3, System.currentTimeMillis()); + stmt.executeUpdate(); + } + + } catch (SQLException e) { + throw new CompletionException(e); + } + return null; + }); + } + + @Override + public CompletableFuture<@NotNull Boolean> isLinkedMinecraft(long discordId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT 1 FROM `linked` WHERE `discord_id` = ? LIMIT 1"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setLong(1, discordId); + ResultSet rs = stmt.executeQuery(); + return rs.next(); + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture<@Nullable UUID> getLinkedMinecraftId(long discordId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT `mc_uuid` FROM `linked` WHERE `discord_id` = ? LIMIT 1"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setLong(1, discordId); + ResultSet rs = stmt.executeQuery(); + + if (rs.next()) + return UUID.fromString(rs.getString("mc_uuid")); + return null; + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture unlinkByMinecraftId(@NotNull UUID minecraftId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "DELETE FROM `linked` WHERE `mc_uuid` = ?"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setString(1, minecraftId.toString().toLowerCase(Locale.ROOT)); + stmt.executeUpdate(); + + } catch (SQLException e) { + throw new CompletionException(e); + } + return null; + }); + } + + @Override + public CompletableFuture unlinkByDiscordId(long discordId) { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "DELETE FROM `linked` WHERE `discord_id` = ?"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql)) { + stmt.setLong(1, discordId); + stmt.executeUpdate(); + + } catch (SQLException e) { + throw new CompletionException(e); + } + return null; + }); + } + + @Override + public CompletableFuture getLinkedAccountAll() { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT `mc_uuid`, `discord_id` FROM `linked`"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql); + ResultSet rs = stmt.executeQuery()) { + + List data = Lists.newArrayList(); + while (rs.next()) + data.add(new LinkedAccount(UUID.fromString(rs.getString(1)), rs.getLong(2))); + + return data.toArray(new LinkedAccount[0]); + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + @Override + public CompletableFuture getLinkedAccountCount() { + return CompletableFuture.supplyAsync(() -> { + if (hikari == null) + throw new CompletionException(new IOException("database closed")); + + String sql = "SELECT COUNT(*) AS `total` FROM `linked`"; + try (Connection conn = hikari.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql); + ResultSet rs = stmt.executeQuery()) { + + if (rs.next()) + return rs.getInt("total"); + return 0; + + } catch (SQLException e) { + throw new CompletionException(e); + } + }); + } + + + public static class DatabaseConfig extends work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig { + + public DatabaseConfig(ConfigurationSection config) { + super(config); + } + + @Override + public String getType() { + return "mysql"; + } + + public String getAddress() { + return config.getString("address", "localhost:3306"); + } + + public String getDatabase() { + return config.getString("database", "discordconnect_accounts"); + } + + public Map getProperties() { + ConfigurationSection props = config.getConfigurationSection("properties"); + if (props == null) + return Collections.emptyMap(); + + Map values = Maps.newHashMap(); + for (String key : props.getKeys(false)) { + values.put(key, props.get(key)); + } + + return values; + } + + } + +} diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java index 39e9d45..e958dd4 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java @@ -5,6 +5,7 @@ import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig; +import work.novablog.mcplugin.discordconnect.account.db.MySQLAccountManager; import work.novablog.mcplugin.discordconnect.account.db.SQLiteAccountManager; import work.novablog.mcplugin.discordconnect.account.db.YamlAccountManager; @@ -99,6 +100,8 @@ public ConfigManager(@NotNull Plugin plugin) throws IOException { accountsDatabaseConfig = new YamlAccountManager.DatabaseConfig(dbSection); } else if (dbType.equalsIgnoreCase("sqlite")) { accountsDatabaseConfig = new SQLiteAccountManager.DatabaseConfig(dbSection); + } else if (dbType.equalsIgnoreCase("mysql")) { + accountsDatabaseConfig = new MySQLAccountManager.DatabaseConfig(dbSection); } else { throw new IllegalArgumentException("Unknown database type: " + dbType); } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 08de631..4d67d10 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -32,7 +32,7 @@ linkedToConsoleCommand: "" # アカウントに関するデータベース設定 accounts: - dbType: yaml # 現在は yaml, sqlite のみ対応 + dbType: yaml database: yaml: file: ./accounts.yml @@ -40,10 +40,11 @@ accounts: file: ./accounts.db properties: {} mysql: - username: root - password: "password" address: localhost:3306 database: "discordconnect_accounts" + properties: + user: root + password: password # この値は変更しないでください! (Don't change the value!) configVersion: 4 \ No newline at end of file From 6080d0119e2cbd48b53c43d6d08618b50214e287 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 17:32:09 +0900 Subject: [PATCH 14/18] =?UTF-8?q?[update]=E3=83=87=E3=83=BC=E3=82=BF?= =?UTF-8?q?=E3=83=99=E3=83=BC=E3=82=B9=E3=82=BF=E3=82=A4=E3=83=97=E3=81=AE?= =?UTF-8?q?=E5=88=A4=E5=AE=9A=E3=82=92=E4=BD=9C=E6=88=90=E3=83=A1=E3=82=BD?= =?UTF-8?q?=E3=83=83=E3=83=89=E3=81=AB=E7=A7=BB=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../discordconnect/DiscordConnect.java | 14 ++------- .../account/AccountManager.java | 31 +++++++++++++++++++ .../discordconnect/util/ConfigManager.java | 14 ++------- 3 files changed, 35 insertions(+), 24 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java index 28316b3..cad39db 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java @@ -9,9 +9,6 @@ import org.jetbrains.annotations.NotNull; import work.novablog.mcplugin.discordconnect.account.AccountManager; import work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig; -import work.novablog.mcplugin.discordconnect.account.db.MySQLAccountManager; -import work.novablog.mcplugin.discordconnect.account.db.SQLiteAccountManager; -import work.novablog.mcplugin.discordconnect.account.db.YamlAccountManager; import work.novablog.mcplugin.discordconnect.command.BukkitCommand; import work.novablog.mcplugin.discordconnect.command.DiscordCommandExecutor; import work.novablog.mcplugin.discordconnect.command.DiscordStandardCommand; @@ -130,16 +127,9 @@ public void init() throws IOException { if(lunaChatListener != null) HandlerList.unregisterAll(lunaChatListener); ConfigManager configManager = new ConfigManager(this); + DatabaseConfig dbConfig = configManager.getAccountsDatabaseConfig(); - if (dbConfig instanceof YamlAccountManager.DatabaseConfig) { - accountManager = new YamlAccountManager(getDataFolder(), ((YamlAccountManager.DatabaseConfig) dbConfig)); - } else if (dbConfig instanceof SQLiteAccountManager.DatabaseConfig) { - accountManager = new SQLiteAccountManager(getDataFolder(), ((SQLiteAccountManager.DatabaseConfig) dbConfig)); - } else if (dbConfig instanceof MySQLAccountManager.DatabaseConfig) { - accountManager = new MySQLAccountManager(((MySQLAccountManager.DatabaseConfig) dbConfig)); - } else { - throw new IllegalArgumentException("Unknown database type: " + dbConfig); - } + accountManager = AccountManager.createManager(dbConfig, this); accountManager.connect(); discordCommandExecutor.setAdminRole(configManager.adminRole); diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java index 5c9281d..02b2ee7 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java @@ -1,9 +1,16 @@ package work.novablog.mcplugin.discordconnect.account; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig; +import work.novablog.mcplugin.discordconnect.account.db.MySQLAccountManager; +import work.novablog.mcplugin.discordconnect.account.db.SQLiteAccountManager; +import work.novablog.mcplugin.discordconnect.account.db.YamlAccountManager; import java.io.IOException; +import java.util.Locale; import java.util.Map; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -57,4 +64,28 @@ public final Map linkingCodes() { public abstract CompletableFuture getLinkedAccountCount(); + + public static DatabaseConfig createDatabaseConfig(String dbType, ConfigurationSection config) { + switch (dbType.toLowerCase(Locale.ROOT)) { + case "yaml": + return new YamlAccountManager.DatabaseConfig(config); + case "sqlite": + return new SQLiteAccountManager.DatabaseConfig(config); + case "mysql": + return new MySQLAccountManager.DatabaseConfig(config); + } + throw new IllegalArgumentException("Unknown database type: " + dbType); + } + + public static AccountManager createManager(DatabaseConfig config, Plugin plugin) { + if (config instanceof YamlAccountManager.DatabaseConfig) { + return new YamlAccountManager(plugin.getDataFolder(), ((YamlAccountManager.DatabaseConfig) config)); + } else if (config instanceof SQLiteAccountManager.DatabaseConfig) { + return new SQLiteAccountManager(plugin.getDataFolder(), ((SQLiteAccountManager.DatabaseConfig) config)); + } else if (config instanceof MySQLAccountManager.DatabaseConfig) { + return new MySQLAccountManager(((MySQLAccountManager.DatabaseConfig) config)); + } + throw new IllegalArgumentException("Unknown database config: " + config.getClass().getSimpleName()); + } + } diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java index e958dd4..7e35e6d 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java @@ -4,10 +4,8 @@ import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; +import work.novablog.mcplugin.discordconnect.account.AccountManager; import work.novablog.mcplugin.discordconnect.account.db.DatabaseConfig; -import work.novablog.mcplugin.discordconnect.account.db.MySQLAccountManager; -import work.novablog.mcplugin.discordconnect.account.db.SQLiteAccountManager; -import work.novablog.mcplugin.discordconnect.account.db.YamlAccountManager; import java.io.File; import java.io.IOException; @@ -96,15 +94,7 @@ public ConfigManager(@NotNull Plugin plugin) throws IOException { if (dbSection == null) dbSection = new YamlConfiguration(); - if (dbType.equalsIgnoreCase("yaml")) { - accountsDatabaseConfig = new YamlAccountManager.DatabaseConfig(dbSection); - } else if (dbType.equalsIgnoreCase("sqlite")) { - accountsDatabaseConfig = new SQLiteAccountManager.DatabaseConfig(dbSection); - } else if (dbType.equalsIgnoreCase("mysql")) { - accountsDatabaseConfig = new MySQLAccountManager.DatabaseConfig(dbSection); - } else { - throw new IllegalArgumentException("Unknown database type: " + dbType); - } + accountsDatabaseConfig = AccountManager.createDatabaseConfig(dbType, dbSection); } private YamlConfiguration getConfigData(Plugin plugin) throws IOException { From ab23983f73f30eef9cf81f7c21c984808b4e1e61 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Wed, 24 May 2023 17:38:24 +0900 Subject: [PATCH 15/18] =?UTF-8?q?[fix]=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=82=92=E7=99=BB=E9=8C=B2=E3=81=97=E3=81=9F=E5=BE=8C=E3=81=AB?= =?UTF-8?q?=E3=83=97=E3=83=A9=E3=82=B0=E3=82=A4=E3=83=B3=E3=82=92=E5=88=9D?= =?UTF-8?q?=E6=9C=9F=E5=8C=96=E3=81=95=E3=81=9B=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mcplugin/discordconnect/DiscordConnect.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java index 871b01e..cad39db 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java @@ -99,19 +99,18 @@ public void onEnable() { lunaChatAPI = ((LunaChatBukkit) temp).getLunaChatAPI(); } + //コマンドの追加 + Optional.ofNullable(getCommand("discordconnect")) + .ifPresent(cmd -> cmd.setExecutor(new BukkitCommand())); + discordCommandExecutor = new DiscordCommandExecutor(); + discordCommandExecutor.registerCommand(new DiscordStandardCommand()); + try { init(); } catch (Throwable e) { e.printStackTrace(); setEnabled(false); - return; } - - //コマンドの追加 - Optional.ofNullable(getCommand("discordconnect")) - .ifPresent(cmd -> cmd.setExecutor(new BukkitCommand())); - discordCommandExecutor = new DiscordCommandExecutor(); - discordCommandExecutor.registerCommand(new DiscordStandardCommand()); } /** From 63ec13af3d19ba96425ec63f7f4cc49c84762730 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Sat, 17 Aug 2024 10:57:39 +0900 Subject: [PATCH 16/18] =?UTF-8?q?[fix]Avatar=20API=20=E3=82=92=20Mineskin?= =?UTF-8?q?=20=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../novablog/mcplugin/discordconnect/util/ConvertUtil.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConvertUtil.java b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConvertUtil.java index b30b1be..de902d8 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConvertUtil.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConvertUtil.java @@ -5,7 +5,7 @@ import java.util.UUID; public class ConvertUtil { - private static final String AVATAR_IMG_URL = "https://crafatar.com/avatars/{uuid}?size=512&default=MHF_Steve&overlay"; + private static final String AVATAR_IMG_URL = "https://mineskin.eu/helm/{uuid}/100.png"; /** * MinecraftプレイヤーのUUIDからアバターのURLを取得します @@ -14,7 +14,7 @@ public class ConvertUtil { *

* @param uuid プレイヤーのUUID * @return プレイヤーのアバターURL - * @see crafatarを利用させていただいています + * @see Mineskinを利用させていただいています */ public static String getMinecraftAvatarURL(@NotNull UUID uuid) { String uuidText = uuid.toString(); From 45747539d9a32efa0f9f25cffd44db18c5f6a928 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Sat, 17 Aug 2024 12:29:01 +0900 Subject: [PATCH 17/18] =?UTF-8?q?[add]=E5=8F=82=E5=8A=A0=E3=81=99=E3=82=8B?= =?UTF-8?q?=E3=81=9F=E3=82=81=E3=81=AB=E3=82=A2=E3=82=AB=E3=82=A6=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=83=AA=E3=83=B3=E3=82=AF=E3=82=92=E5=BF=85=E9=A0=88?= =?UTF-8?q?=E3=81=AB=E3=81=99=E3=82=8B=E8=A8=AD=E5=AE=9A/=E5=AE=9F?= =?UTF-8?q?=E8=A3=85=E3=81=AE=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../discordconnect/DiscordConnect.java | 2 +- .../account/AccountManager.java | 8 ++- .../discordconnect/command/BukkitCommand.java | 2 +- .../listener/BukkitListener.java | 52 +++++++++++++++++-- .../listener/DiscordListener.java | 23 ++++---- .../discordconnect/util/ConfigManager.java | 8 +++ src/main/resources/config.yml | 2 + src/main/resources/ja_JP.yml | 2 + 8 files changed, 80 insertions(+), 19 deletions(-) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java index cad39db..6ee00bc 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/DiscordConnect.java @@ -162,7 +162,7 @@ public void init() throws IOException { } //BungeecordイベントのListenerを登録 - bukkitListener = new BukkitListener(configManager.fromMinecraftToDiscordName); + bukkitListener = new BukkitListener(configManager); getServer().getPluginManager().registerEvents(bukkitListener, this); if(lunaChatAPI != null) { lunaChatListener = new LunaChatListener( diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java index 02b2ee7..c7186fc 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/account/AccountManager.java @@ -19,6 +19,7 @@ public abstract class AccountManager { private final Map linkingCodes = new ConcurrentHashMap<>(); + private final Map names = new ConcurrentHashMap<>(); public abstract void connect() throws IOException; @@ -26,7 +27,8 @@ public abstract class AccountManager { public abstract void close() throws IOException; - public final String generateCode(UUID playerUuid) { + public final String generateCode(UUID playerUuid, String playerName) { + names.put(playerUuid, playerName); String codeString; do { int code = ThreadLocalRandom.current().nextInt(10000); @@ -36,6 +38,10 @@ public final String generateCode(UUID playerUuid) { return codeString; } + public @Nullable String getLinkingPlayerName(UUID playerId) { + return names.get(playerId); + } + public final @Nullable UUID removeMinecraftIdByLinkCode(@NotNull String code) { return linkingCodes.remove(code); } diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java b/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java index 47f689d..1a52bac 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/command/BukkitCommand.java @@ -38,7 +38,7 @@ public void linkCmd(CommandSender sender, String[] args) { } Player player = (Player) sender; String botName = instance.getBotManager().getBotUser().getName(); - String code = instance.getAccountManager().generateCode(player.getUniqueId()); + String code = instance.getAccountManager().generateCode(player.getUniqueId(), player.getName()); sender.sendMessage(ConfigManager.Message.accountLinkShowCode.toString() .replaceAll("\\{bot}", botName) diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/listener/BukkitListener.java b/src/main/java/work/novablog/mcplugin/discordconnect/listener/BukkitListener.java index 7f89406..be716a5 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/listener/BukkitListener.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/listener/BukkitListener.java @@ -8,10 +8,12 @@ import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.AsyncPlayerChatEvent; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; import org.jetbrains.annotations.NotNull; import work.novablog.mcplugin.discordconnect.DiscordConnect; +import work.novablog.mcplugin.discordconnect.account.AccountManager; import work.novablog.mcplugin.discordconnect.util.ConfigManager; import work.novablog.mcplugin.discordconnect.util.ConvertUtil; import work.novablog.mcplugin.discordconnect.util.discord.BotManager; @@ -19,16 +21,21 @@ import java.awt.*; import java.util.ArrayList; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; public class BukkitListener implements Listener { + private final ConfigManager config; private final String fromMinecraftToDiscordName; /** * bungeecordのイベントを受け取るインスタンスを生成します - * @param fromMinecraftToDiscordName マイクラからDiscordへ転送するときの名前欄のフォーマット + * @param config プラグイン設定 */ - public BukkitListener(@NotNull String fromMinecraftToDiscordName) { - this.fromMinecraftToDiscordName = fromMinecraftToDiscordName; + public BukkitListener(@NotNull ConfigManager config) { + this.config = config; + this.fromMinecraftToDiscordName = config.fromMinecraftToDiscordName; } /** @@ -60,6 +67,45 @@ public void onChat(AsyncPlayerChatEvent event) { } } + @EventHandler + public void onPreLogin(AsyncPlayerPreLoginEvent event) { + if (!config.isAccountLinkRequired() || !AsyncPlayerPreLoginEvent.Result.ALLOWED.equals(event.getLoginResult())) + return; + + DiscordConnect plugin = DiscordConnect.getInstance(); + UUID playerId = event.getUniqueId(); + String playerName = event.getName(); + AccountManager accountManager = plugin.getAccountManager(); + + try { + Objects.requireNonNull(accountManager, "Account Manager not loaded"); + Boolean linked = accountManager.isLinkedDiscord(playerId).get(); + + if (Boolean.TRUE.equals(linked)) { + return; // linked + } + + // create code + BotManager botManager = Objects.requireNonNull(plugin.getBotManager(), "Bot Manager not loaded"); + String botName = botManager.getBotUser().getName(); + + String code = accountManager.linkingCodes().entrySet().stream() + .filter(e -> playerId.equals(e.getValue())) + .map(Map.Entry::getKey) + .findAny() + .orElseGet(() -> accountManager.generateCode(playerId, playerName)); + + event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, ConfigManager.Message.accountLinkRequired.toString() + .replaceAll("\\{bot}", botName) + .replaceAll("\\{code}", code)); + + + } catch (Throwable e) { + e.printStackTrace(); + event.disallow(AsyncPlayerPreLoginEvent.Result.KICK_OTHER, ConfigManager.Message.accountLinkProcessError.toString()); + } + } + /** * プレイヤーがログインしたら実行されます * @param e ログイン情報 diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java b/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java index 91678fa..382f7ce 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/listener/DiscordListener.java @@ -12,7 +12,6 @@ import net.md_5.bungee.api.chat.ComponentBuilder; import net.md_5.bungee.api.chat.TextComponent; import org.bukkit.Bukkit; -import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import work.novablog.mcplugin.discordconnect.DiscordConnect; @@ -182,16 +181,13 @@ private boolean processLinkCodeMessage(MessageReceivedEvent event, long userId) if (uuid == null) continue; - Player player = Optional.ofNullable(Bukkit.getOfflinePlayer(uuid).getPlayer()).orElse(null); - if (player == null) - return true; - mgr.linkDiscordId(uuid, userId).whenComplete((v, th) -> { if (th != null) { th.printStackTrace(); } else { Bukkit.getScheduler().callSyncMethod(DiscordConnect.getInstance(), () -> { - processLinkedPlayer(player, event.getAuthor(), event.getChannel()); + String playerName = Objects.requireNonNull(mgr.getLinkingPlayerName(uuid)); + processLinkedPlayer(uuid, playerName, event.getAuthor(), event.getChannel()); return null; }); } @@ -201,14 +197,15 @@ private boolean processLinkCodeMessage(MessageReceivedEvent event, long userId) return false; } - private void processLinkedPlayer(Player player, User user, MessageChannel channel) { - String mcid = player.getName(); + private void processLinkedPlayer(UUID playerId, String playerName, User user, MessageChannel channel) { try { - player.sendMessage(ConfigManager.Message.accountLinkLinked.toString() - .replaceAll("\\{user}", user.getAsTag())); + Optional.ofNullable(Bukkit.getPlayer(playerId)).ifPresent(p -> + p.sendMessage(ConfigManager.Message.accountLinkLinked.toString() + .replaceAll("\\{user}", user.getAsTag())) + ); channel.sendMessage(ConfigManager.Message.accountLinkLinkedToDiscord.toString() - .replaceAll("\\{mcid}", mcid)) + .replaceAll("\\{mcid}", playerName)) .queue(); } catch (Throwable e) { @@ -220,9 +217,9 @@ private void processLinkedPlayer(Player player, User user, MessageChannel channe try { Bukkit.dispatchCommand(Bukkit.getConsoleSender(), linkedCommand - .replaceAll("\\{playerId}", player.getUniqueId().toString()) + .replaceAll("\\{playerId}", playerId.toString()) .replaceAll("\\{discordId}", user.getId()) - .replaceAll("\\{player}", player.getName()) + .replaceAll("\\{player}", playerName) .replaceAll("\\{discord}", user.getAsTag()) ); } catch (Throwable e) { diff --git a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java index 7e35e6d..62d2f5f 100644 --- a/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java +++ b/src/main/java/work/novablog/mcplugin/discordconnect/util/ConfigManager.java @@ -20,6 +20,7 @@ public class ConfigManager { private static YamlConfiguration langData; private final DatabaseConfig accountsDatabaseConfig; + private final boolean accountLinkRequired; public String botToken; public List botWebhookURLs; @@ -93,6 +94,7 @@ public ConfigManager(@NotNull Plugin plugin) throws IOException { ConfigurationSection dbSection = pluginConfig.getConfigurationSection("accounts.database." + dbType); if (dbSection == null) dbSection = new YamlConfiguration(); + accountLinkRequired = pluginConfig.getBoolean("accounts.requireLink", false); accountsDatabaseConfig = AccountManager.createDatabaseConfig(dbType, dbSection); } @@ -124,6 +126,10 @@ public DatabaseConfig getAccountsDatabaseConfig() { return accountsDatabaseConfig; } + public boolean isAccountLinkRequired() { + return accountLinkRequired; + } + private void backupOldFile(Plugin plugin, String targetFileName) throws IOException { File oldFile = new File(plugin.getDataFolder(), targetFileName + "_old"); Files.deleteIfExists(oldFile.toPath()); @@ -156,6 +162,8 @@ public enum Message { accountLinkLinkedToDiscord, accountLinkLinked, accountLinkShowCode, + accountLinkRequired, + accountLinkProcessError, bungeeCommandDenied, bungeeCommandNotFound, diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 4d67d10..91b0d3b 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -32,6 +32,8 @@ linkedToConsoleCommand: "" # アカウントに関するデータベース設定 accounts: + # 参加するためにリンクが必要 + requireLink: false dbType: yaml database: yaml: diff --git a/src/main/resources/ja_JP.yml b/src/main/resources/ja_JP.yml index 0858d4e..58bbb0b 100644 --- a/src/main/resources/ja_JP.yml +++ b/src/main/resources/ja_JP.yml @@ -19,6 +19,8 @@ pluginIsLatest: "プラグインは最新バージョンです({current})" accountLinkLinkedToDiscord: "Minecraftアカウント {mcid} と連携しました!" accountLinkLinked: "§6Discordアカウント §f{user}§6 と連携しました!" accountLinkShowCode: "§eDiscordボット §f{bot}§e に §6{code}§e を送信してください" +accountLinkRequired: "§7このサーバーに接続するには、§fDiscord §7とのリンクが必要です\n§eDiscordボット §f{bot} §eに §6{code} §eを送信してください" +accountLinkProcessError: "§cアカウント処理に失敗しました。管理者にお問い合わせください。" bungeeCommandDenied: "§cあなたはこのコマンドを実行する権限を持っていません!" bungeeCommandNotFound: "§cコマンドが見つかりません!" From 12aef92679215a6bc1b2fcbd3597986fdc0c3d98 Mon Sep 17 00:00:00 2001 From: Necnion8 Date: Sat, 9 Nov 2024 17:03:54 +0900 Subject: [PATCH 18/18] =?UTF-8?q?[update]jar=E3=83=95=E3=82=A1=E3=82=A4?= =?UTF-8?q?=E3=83=AB=E5=90=8D=E3=82=92=20DiscordConnect-old-spigot=20?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index bd5f47f..25542a8 100644 --- a/build.gradle +++ b/build.gradle @@ -51,7 +51,7 @@ shadowJar { group = 'work.novablog.mcplugin' version = '3.1' description = 'DiscordConnect' -archivesBaseName = 'DiscordConnect-spigot' +archivesBaseName = 'DiscordConnect-old-spigot' java.sourceCompatibility = JavaVersion.VERSION_1_8 tasks.withType(JavaCompile) {