diff --git a/api/src/main/java/com/discordsrv/api/DiscordSRVApi.java b/api/src/main/java/com/discordsrv/api/DiscordSRVApi.java index 314fcbec..81e16873 100644 --- a/api/src/main/java/com/discordsrv/api/DiscordSRVApi.java +++ b/api/src/main/java/com/discordsrv/api/DiscordSRVApi.java @@ -63,6 +63,7 @@ public interface DiscordSRVApi { * The profile manager, access the profiles of players and/or users. * @return the instance of {@link IProfileManager} */ + @NotNull IProfileManager profileManager(); /** @@ -177,30 +178,24 @@ public interface DiscordSRVApi { * DiscordSRV is shutting down. * @see #isShutdown() */ - SHUTTING_DOWN(false, true), + SHUTTING_DOWN, /** * DiscordSRV has shutdown. * @see #isShutdown() */ - SHUTDOWN(false, true), + SHUTDOWN, ; private final boolean error; - private final boolean shutdown; Status() { this(false); } Status(boolean error) { - this(error, false); - } - - Status(boolean error, boolean shutdown) { this.error = error; - this.shutdown = shutdown; } public boolean isError() { @@ -208,7 +203,7 @@ public interface DiscordSRVApi { } public boolean isShutdown() { - return shutdown; + return this == SHUTDOWN || this == SHUTTING_DOWN; } public boolean isStartupError() { diff --git a/api/src/main/java/com/discordsrv/api/profile/IProfile.java b/api/src/main/java/com/discordsrv/api/profile/IProfile.java index 83536c5a..b4de30e5 100644 --- a/api/src/main/java/com/discordsrv/api/profile/IProfile.java +++ b/api/src/main/java/com/discordsrv/api/profile/IProfile.java @@ -23,20 +23,21 @@ package com.discordsrv.api.profile; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; +import java.util.Optional; import java.util.UUID; public interface IProfile { - @Nullable - UUID uniqueId(); + @NotNull + Optional playerUUID(); - @Nullable - Long userId(); + @NotNull + Optional userId(); default boolean isLinked() { - return uniqueId() != null && userId() != null; + return playerUUID().isPresent() && userId().isPresent(); } } diff --git a/api/src/main/java/com/discordsrv/api/profile/IProfileManager.java b/api/src/main/java/com/discordsrv/api/profile/IProfileManager.java index 43291a22..e35a5f96 100644 --- a/api/src/main/java/com/discordsrv/api/profile/IProfileManager.java +++ b/api/src/main/java/com/discordsrv/api/profile/IProfileManager.java @@ -29,11 +29,11 @@ import java.util.concurrent.CompletableFuture; public interface IProfileManager { - CompletableFuture> lookupProfile(UUID playerUUID); + CompletableFuture lookupProfile(UUID playerUUID); - Optional getProfile(UUID playerUUID); + Optional getProfile(UUID playerUUID); - CompletableFuture> lookupProfile(long userId); + CompletableFuture lookupProfile(long userId); - Optional getProfile(long userId); + Optional getProfile(long userId); } diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/BukkitDiscordSRV.java b/bukkit/src/main/java/com/discordsrv/bukkit/BukkitDiscordSRV.java index 4e49fde8..aa02c854 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/BukkitDiscordSRV.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/BukkitDiscordSRV.java @@ -26,6 +26,7 @@ import com.discordsrv.bukkit.config.manager.BukkitConnectionConfigManager; import com.discordsrv.bukkit.console.BukkitConsole; import com.discordsrv.bukkit.integration.VaultIntegration; import com.discordsrv.bukkit.listener.BukkitChatListener; +import com.discordsrv.bukkit.listener.BukkitConnectionListener; import com.discordsrv.bukkit.listener.BukkitDeathListener; import com.discordsrv.bukkit.listener.BukkitStatusMessageListener; import com.discordsrv.bukkit.player.BukkitPlayerProvider; @@ -178,6 +179,7 @@ public class BukkitDiscordSRV extends ServerDiscordSRV. + */ + +package com.discordsrv.bukkit.listener; + +import com.discordsrv.bukkit.BukkitDiscordSRV; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerLoginEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +public class BukkitConnectionListener implements Listener { + + private final BukkitDiscordSRV discordSRV; + + public BukkitConnectionListener(BukkitDiscordSRV discordSRV) { + this.discordSRV = discordSRV; + + for (Player onlinePlayer : discordSRV.server().getOnlinePlayers()) { + discordSRV.profileManager().loadProfile(onlinePlayer.getUniqueId()); + } + } + + @EventHandler(priority = EventPriority.NORMAL) + public void onPlayerLoginNormal(PlayerLoginEvent event) { + if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { + return; + } + + discordSRV.profileManager().loadProfile(event.getPlayer().getUniqueId()); + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerLoginMonitor(PlayerLoginEvent event) { + if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) { + // Unload in case got blocked after NORMAL + discordSRV.profileManager().unloadProfile(event.getPlayer().getUniqueId()); + } + } + + @EventHandler(priority = EventPriority.MONITOR) + public void onPlayerQuit(PlayerQuitEvent event) { + discordSRV.profileManager().unloadProfile(event.getPlayer().getUniqueId()); + } +} diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitOfflinePlayer.java b/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitOfflinePlayer.java index 8b4896be..c0a96c7e 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitOfflinePlayer.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitOfflinePlayer.java @@ -20,6 +20,7 @@ package com.discordsrv.bukkit.player; import com.discordsrv.bukkit.BukkitDiscordSRV; import com.discordsrv.common.player.IOfflinePlayer; +import com.discordsrv.common.profile.Profile; import net.kyori.adventure.identity.Identity; import org.bukkit.OfflinePlayer; import org.jetbrains.annotations.NotNull; @@ -42,6 +43,11 @@ public class BukkitOfflinePlayer implements IOfflinePlayer { return offlinePlayer.getName(); } + @Override + public Profile profile() { + return discordSRV.profileManager().getProfile(uniqueId()).orElseThrow(IllegalStateException::new); + } + @Override public @NotNull Identity identity() { return identity; diff --git a/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitPlayerProvider.java b/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitPlayerProvider.java index a353f3b9..b1b2822e 100644 --- a/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitPlayerProvider.java +++ b/bukkit/src/main/java/com/discordsrv/bukkit/player/BukkitPlayerProvider.java @@ -53,7 +53,7 @@ public class BukkitPlayerProvider extends ServerPlayerProvider playerProvider(); // DiscordSRVApi @Override @@ -69,11 +71,11 @@ public interface DiscordSRV extends DiscordSRVApi { @Override @NotNull - PlaceholderServiceImpl placeholderService(); + ProfileManager profileManager(); @Override @NotNull - AbstractPlayerProvider playerProvider(); + PlaceholderServiceImpl placeholderService(); @Override @NotNull diff --git a/common/src/main/java/com/discordsrv/common/config/main/LinkedAccountConfig.java b/common/src/main/java/com/discordsrv/common/config/main/LinkedAccountConfig.java new file mode 100644 index 00000000..1ebefc32 --- /dev/null +++ b/common/src/main/java/com/discordsrv/common/config/main/LinkedAccountConfig.java @@ -0,0 +1,35 @@ +/* + * This file is part of DiscordSRV, licensed under the GPLv3 License + * Copyright (c) 2016-2022 Austin "Scarsz" Shapiro, Henri "Vankka" Schubin and DiscordSRV contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.discordsrv.common.config.main; + +import org.spongepowered.configurate.objectmapping.ConfigSerializable; +import org.spongepowered.configurate.objectmapping.meta.Comment; + +@ConfigSerializable +public class LinkedAccountConfig { + + @Comment("Should linked accounts be enabled?") + public boolean enabled = true; + + @Comment("The linked account provider\n" + + "\n" + + " - auto: Automatically chooses the most suitable linked accounts storage\n" + + " - storage: Store linked accounts from the configured databased") + public String provider = "auto"; +} diff --git a/common/src/main/java/com/discordsrv/common/config/main/MainConfig.java b/common/src/main/java/com/discordsrv/common/config/main/MainConfig.java index 57dd945e..eba30d41 100644 --- a/common/src/main/java/com/discordsrv/common/config/main/MainConfig.java +++ b/common/src/main/java/com/discordsrv/common/config/main/MainConfig.java @@ -43,6 +43,8 @@ public class MainConfig implements Config { put(ChannelConfig.DEFAULT_KEY, new BaseChannelConfig()); }}; + public LinkedAccountConfig linkedAccounts = new LinkedAccountConfig(); + public List channelUpdaters = new ArrayList<>(Collections.singletonList(new ChannelUpdaterConfig())); @Comment("Configuration options for group-role synchronization") diff --git a/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java b/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java index ababb491..f064f578 100644 --- a/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java +++ b/common/src/main/java/com/discordsrv/common/groupsync/GroupSyncModule.java @@ -23,7 +23,6 @@ import com.discordsrv.api.discord.api.entity.guild.DiscordRole; import com.discordsrv.api.discord.events.member.role.DiscordMemberRoleAddEvent; import com.discordsrv.api.discord.events.member.role.DiscordMemberRoleRemoveEvent; import com.discordsrv.api.event.bus.Subscribe; -import com.discordsrv.api.profile.IProfile; import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.config.main.GroupSyncConfig; import com.discordsrv.common.debug.DebugGenerateEvent; @@ -166,12 +165,12 @@ public class GroupSyncModule extends AbstractModule { private CompletableFuture lookupLinkedAccount(UUID player) { return discordSRV.profileManager().lookupProfile(player) - .thenApply(profile -> profile.map(IProfile::userId).orElse(null)); + .thenApply(profile -> profile.userId().orElse(null)); } private CompletableFuture lookupLinkedAccount(long userId) { return discordSRV.profileManager().lookupProfile(userId) - .thenApply(profile -> profile.map(IProfile::uniqueId).orElse(null)); + .thenApply(profile -> profile.playerUUID().orElse(null)); } // Permission data helper methods diff --git a/common/src/main/java/com/discordsrv/common/linking/LinkStore.java b/common/src/main/java/com/discordsrv/common/linking/LinkStore.java index fe2e68d0..3785e5cd 100644 --- a/common/src/main/java/com/discordsrv/common/linking/LinkStore.java +++ b/common/src/main/java/com/discordsrv/common/linking/LinkStore.java @@ -25,7 +25,7 @@ import java.util.concurrent.CompletableFuture; public interface LinkStore { - CompletableFuture link(@NotNull UUID playerUUID, long userId); + CompletableFuture createLink(@NotNull UUID playerUUID, long userId); CompletableFuture getLinkedAccountCount(); } diff --git a/common/src/main/java/com/discordsrv/common/linking/impl/MemoryLinker.java b/common/src/main/java/com/discordsrv/common/linking/impl/MemoryLinker.java index 2f010a58..33f57382 100644 --- a/common/src/main/java/com/discordsrv/common/linking/impl/MemoryLinker.java +++ b/common/src/main/java/com/discordsrv/common/linking/impl/MemoryLinker.java @@ -43,7 +43,7 @@ public class MemoryLinker implements LinkProvider, LinkStore { } @Override - public CompletableFuture link(@NotNull UUID playerUUID, long userId) { + public CompletableFuture createLink(@NotNull UUID playerUUID, long userId) { map.put(playerUUID, userId); return CompletableFuture.completedFuture(null); } diff --git a/common/src/main/java/com/discordsrv/common/linking/impl/StorageLinker.java b/common/src/main/java/com/discordsrv/common/linking/impl/StorageLinker.java index 91eb40b7..4c5b8cec 100644 --- a/common/src/main/java/com/discordsrv/common/linking/impl/StorageLinker.java +++ b/common/src/main/java/com/discordsrv/common/linking/impl/StorageLinker.java @@ -31,6 +31,7 @@ public class StorageLinker extends CachedLinkProvider implements LinkProvider, L public StorageLinker(DiscordSRV discordSRV) { super(discordSRV); + discordSRV.logger().info("Using storage for linked accounts"); } @Override @@ -50,9 +51,9 @@ public class StorageLinker extends CachedLinkProvider implements LinkProvider, L } @Override - public CompletableFuture link(@NotNull UUID playerUUID, long userId) { + public CompletableFuture createLink(@NotNull UUID playerUUID, long userId) { return CompletableFuture.runAsync( - () -> discordSRV.storage().link(playerUUID, userId), + () -> discordSRV.storage().createLink(playerUUID, userId), discordSRV.scheduler().executor() ); } diff --git a/common/src/main/java/com/discordsrv/common/player/IOfflinePlayer.java b/common/src/main/java/com/discordsrv/common/player/IOfflinePlayer.java index f008eae4..a6410e46 100644 --- a/common/src/main/java/com/discordsrv/common/player/IOfflinePlayer.java +++ b/common/src/main/java/com/discordsrv/common/player/IOfflinePlayer.java @@ -19,6 +19,7 @@ package com.discordsrv.common.player; import com.discordsrv.api.placeholder.annotation.Placeholder; +import com.discordsrv.common.profile.Profile; import net.kyori.adventure.identity.Identified; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -38,4 +39,6 @@ public interface IOfflinePlayer extends Identified { default UUID uniqueId() { return identity().uuid(); } + + Profile profile(); } diff --git a/common/src/main/java/com/discordsrv/common/player/IPlayer.java b/common/src/main/java/com/discordsrv/common/player/IPlayer.java index d2e03bdd..ed92da9b 100644 --- a/common/src/main/java/com/discordsrv/common/player/IPlayer.java +++ b/common/src/main/java/com/discordsrv/common/player/IPlayer.java @@ -36,7 +36,6 @@ public interface IPlayer extends DiscordSRVPlayer, IOfflinePlayer, ICommandSende DiscordSRV discordSRV(); - @Override @NotNull String username(); diff --git a/common/src/main/java/com/discordsrv/common/profile/Profile.java b/common/src/main/java/com/discordsrv/common/profile/Profile.java index fdcb85ea..f544a027 100644 --- a/common/src/main/java/com/discordsrv/common/profile/Profile.java +++ b/common/src/main/java/com/discordsrv/common/profile/Profile.java @@ -19,27 +19,28 @@ package com.discordsrv.common.profile; import com.discordsrv.api.profile.IProfile; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; +import java.util.Optional; import java.util.UUID; public class Profile implements IProfile { - private final UUID uuid; + private final UUID playerUUID; private final Long userId; - public Profile(UUID uuid, Long userId) { - this.uuid = uuid; + public Profile(UUID playerUUID, Long userId) { + this.playerUUID = playerUUID; this.userId = userId; } @Override - public @Nullable UUID uniqueId() { - return uuid; + public @NotNull Optional playerUUID() { + return Optional.ofNullable(playerUUID); } @Override - public @Nullable Long userId() { - return userId; + public @NotNull Optional userId() { + return Optional.ofNullable(userId); } } diff --git a/common/src/main/java/com/discordsrv/common/profile/ProfileManager.java b/common/src/main/java/com/discordsrv/common/profile/ProfileManager.java index 192f2a4c..c9ba8a66 100644 --- a/common/src/main/java/com/discordsrv/common/profile/ProfileManager.java +++ b/common/src/main/java/com/discordsrv/common/profile/ProfileManager.java @@ -19,40 +19,64 @@ package com.discordsrv.common.profile; import com.discordsrv.api.profile.IProfileManager; -import com.discordsrv.api.profile.IProfile; import com.discordsrv.common.DiscordSRV; +import org.jetbrains.annotations.Blocking; +import java.util.Map; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; public class ProfileManager implements IProfileManager { private final DiscordSRV discordSRV; + private final Map profiles = new ConcurrentHashMap<>(); + private final Map discordUserMap = new ConcurrentHashMap<>(); public ProfileManager(DiscordSRV discordSRV) { this.discordSRV = discordSRV; } + @Blocking + public void loadProfile(UUID playerUUID) { + Profile profile = lookupProfile(playerUUID).join(); + profiles.put(playerUUID, profile); + if (profile.isLinked()) { + discordUserMap.put(profile.userId().orElseThrow(AssertionError::new), profile); + } + } + + public void unloadProfile(UUID playerUUID) { + Profile profile = profiles.remove(playerUUID); + if (profile == null) { + return; + } + + if (profile.isLinked()) { + discordUserMap.remove(profile.userId().orElseThrow(AssertionError::new)); + } + } + @Override - public CompletableFuture> lookupProfile(UUID playerUUID) { + public CompletableFuture lookupProfile(UUID playerUUID) { return discordSRV.linkProvider().getUserId(playerUUID) - .thenApply(opt -> Optional.of(new Profile(playerUUID, opt.orElse(null)))); + .thenApply(opt -> new Profile(playerUUID, opt.orElse(null))); } @Override - public Optional getProfile(UUID playerUUID) { - return Optional.empty(); + public Optional getProfile(UUID playerUUID) { + return Optional.ofNullable(profiles.get(playerUUID)); } @Override - public CompletableFuture> lookupProfile(long userId) { + public CompletableFuture lookupProfile(long userId) { return discordSRV.linkProvider().getPlayerUUID(userId) - .thenApply(opt -> Optional.of(new Profile(opt.orElse(null), userId))); + .thenApply(opt -> new Profile(opt.orElse(null), userId)); } @Override - public Optional getProfile(long userId) { - return Optional.empty(); + public Optional getProfile(long userId) { + return Optional.ofNullable(discordUserMap.get(userId)); } } diff --git a/common/src/main/java/com/discordsrv/common/storage/Storage.java b/common/src/main/java/com/discordsrv/common/storage/Storage.java index 6ec7e77a..bf7fedd2 100644 --- a/common/src/main/java/com/discordsrv/common/storage/Storage.java +++ b/common/src/main/java/com/discordsrv/common/storage/Storage.java @@ -36,7 +36,7 @@ public interface Storage { @Nullable UUID getPlayerUUID(long userId); - void link(@NotNull UUID player, long userId); + void createLink(@NotNull UUID player, long userId); int getLinkedAccountCount(); diff --git a/common/src/main/java/com/discordsrv/common/storage/StorageType.java b/common/src/main/java/com/discordsrv/common/storage/StorageType.java index 23f67b9e..d1dacea6 100644 --- a/common/src/main/java/com/discordsrv/common/storage/StorageType.java +++ b/common/src/main/java/com/discordsrv/common/storage/StorageType.java @@ -26,14 +26,16 @@ import java.util.function.Function; public enum StorageType { - H2(H2Storage::new, false), - MYSQL(MySQLStorage::new, true); + H2(H2Storage::new, "H2", false), + MYSQL(MySQLStorage::new, "MySQL", true); private final Function storageFunction; + private final String prettyName; private final boolean hikari; - StorageType(Function storageFunction, boolean hikari) { + StorageType(Function storageFunction, String prettyName, boolean hikari) { this.storageFunction = storageFunction; + this.prettyName = prettyName; this.hikari = hikari; } @@ -41,6 +43,10 @@ public enum StorageType { return storageFunction; } + public String prettyName() { + return prettyName; + } + public boolean hikari() { return hikari; } diff --git a/common/src/main/java/com/discordsrv/common/storage/impl/sql/SQLStorage.java b/common/src/main/java/com/discordsrv/common/storage/impl/sql/SQLStorage.java index 0d43c421..6fc271ac 100644 --- a/common/src/main/java/com/discordsrv/common/storage/impl/sql/SQLStorage.java +++ b/common/src/main/java/com/discordsrv/common/storage/impl/sql/SQLStorage.java @@ -18,9 +18,11 @@ package com.discordsrv.common.storage.impl.sql; +import com.discordsrv.common.DiscordSRV; import com.discordsrv.common.exception.StorageException; import com.discordsrv.common.function.CheckedConsumer; import com.discordsrv.common.function.CheckedFunction; +import com.discordsrv.common.linking.impl.StorageLinker; import com.discordsrv.common.storage.Storage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,9 +32,15 @@ import java.util.UUID; public abstract class SQLStorage implements Storage { + protected final DiscordSRV discordSRV; + + public SQLStorage(DiscordSRV discordSRV) { + this.discordSRV = discordSRV; + } + public abstract Connection getConnection(); public abstract boolean isAutoCloseConnections(); - public abstract void createTables(Connection connection) throws SQLException; + public abstract void createTables(Connection connection, boolean linkedAccounts) throws SQLException; private void useConnection(CheckedConsumer connectionConsumer) throws StorageException { useConnection(connection -> { @@ -63,7 +71,7 @@ public abstract class SQLStorage implements Storage { @Override public void initialize() { - useConnection(this::createTables); + useConnection((CheckedConsumer) connection -> createTables(connection, discordSRV.linkProvider() instanceof StorageLinker)); } @Override @@ -97,7 +105,7 @@ public abstract class SQLStorage implements Storage { } @Override - public void link(@NotNull UUID player, long userId) { + public void createLink(@NotNull UUID player, long userId) { useConnection(connection -> { try (PreparedStatement statement = connection.prepareStatement("insert into LINKED_ACCOUNTS (PLAYER_UUID, USER_ID) values (?, ?);")) { statement.setObject(1, player); diff --git a/common/src/main/java/com/discordsrv/common/storage/impl/sql/file/H2Storage.java b/common/src/main/java/com/discordsrv/common/storage/impl/sql/file/H2Storage.java index af5152d7..0a46b138 100644 --- a/common/src/main/java/com/discordsrv/common/storage/impl/sql/file/H2Storage.java +++ b/common/src/main/java/com/discordsrv/common/storage/impl/sql/file/H2Storage.java @@ -34,12 +34,11 @@ import java.util.Properties; public class H2Storage extends SQLStorage { - private final DiscordSRV discordSRV; private IsolatedClassLoader classLoader; private Connection connection; public H2Storage(DiscordSRV discordSRV) { - this.discordSRV = discordSRV; + super(discordSRV); } @Override @@ -101,15 +100,17 @@ public class H2Storage extends SQLStorage { } @Override - public void createTables(Connection connection) throws SQLException { - try (Statement statement = connection.createStatement()) { - statement.execute( - "create table if not exists LINKED_ACCOUNTS " - + "(ID int not null auto_increment, " - + "PLAYER_UUID varchar(36), " - + "USER_ID bigint, " - + "constraint LINKED_ACCOUNTS_PK primary key (ID)" - + ")"); + public void createTables(Connection connection, boolean linkedAccounts) throws SQLException { + if (linkedAccounts) { + try (Statement statement = connection.createStatement()) { + statement.execute( + "create table if not exists LINKED_ACCOUNTS " + + "(ID int not null auto_increment, " + + "PLAYER_UUID varchar(36), " + + "USER_ID bigint, " + + "constraint LINKED_ACCOUNTS_PK primary key (ID)" + + ")"); + } } } } diff --git a/common/src/main/java/com/discordsrv/common/storage/impl/sql/hikari/HikariStorage.java b/common/src/main/java/com/discordsrv/common/storage/impl/sql/hikari/HikariStorage.java index 92c80f2b..e02c683f 100644 --- a/common/src/main/java/com/discordsrv/common/storage/impl/sql/hikari/HikariStorage.java +++ b/common/src/main/java/com/discordsrv/common/storage/impl/sql/hikari/HikariStorage.java @@ -31,11 +31,10 @@ import java.sql.SQLException; public abstract class HikariStorage extends SQLStorage { - protected final DiscordSRV discordSRV; private HikariDataSource hikariDataSource; public HikariStorage(DiscordSRV discordSRV) { - this.discordSRV = discordSRV; + super(discordSRV); } protected abstract void applyConfiguration(HikariConfig config, StorageConfig storageConfig); diff --git a/common/src/main/java/com/discordsrv/common/storage/impl/sql/hikari/MySQLStorage.java b/common/src/main/java/com/discordsrv/common/storage/impl/sql/hikari/MySQLStorage.java index e3e2127a..e4b276f0 100644 --- a/common/src/main/java/com/discordsrv/common/storage/impl/sql/hikari/MySQLStorage.java +++ b/common/src/main/java/com/discordsrv/common/storage/impl/sql/hikari/MySQLStorage.java @@ -52,15 +52,17 @@ public class MySQLStorage extends HikariStorage { } @Override - public void createTables(Connection connection) throws SQLException { - try (Statement statement = connection.createStatement()) { - statement.execute( - "create table if not exists LINKED_ACCOUNTS " - + "(ID int not null auto_increment, " - + "PLAYER_UUID varchar(36), " - + "USER_ID bigint, " - + "constraint LINKED_ACCOUNTS_PK primary key (ID)" - + ")"); + public void createTables(Connection connection, boolean linkedAccounts) throws SQLException { + if (linkedAccounts) { + try (Statement statement = connection.createStatement()) { + statement.execute( + "create table if not exists LINKED_ACCOUNTS " + + "(ID int not null auto_increment, " + + "PLAYER_UUID varchar(36), " + + "USER_ID bigint, " + + "constraint LINKED_ACCOUNTS_PK primary key (ID)" + + ")"); + } } } diff --git a/sponge/src/main/java/com/discordsrv/sponge/player/SpongeOfflinePlayer.java b/sponge/src/main/java/com/discordsrv/sponge/player/SpongeOfflinePlayer.java index 2099dd37..1e201aa5 100644 --- a/sponge/src/main/java/com/discordsrv/sponge/player/SpongeOfflinePlayer.java +++ b/sponge/src/main/java/com/discordsrv/sponge/player/SpongeOfflinePlayer.java @@ -19,15 +19,19 @@ package com.discordsrv.sponge.player; import com.discordsrv.common.player.IOfflinePlayer; +import com.discordsrv.common.profile.Profile; +import com.discordsrv.sponge.SpongeDiscordSRV; import net.kyori.adventure.identity.Identity; import org.jetbrains.annotations.NotNull; import org.spongepowered.api.entity.living.player.User; public class SpongeOfflinePlayer implements IOfflinePlayer { + protected final SpongeDiscordSRV discordSRV; private final User user; - public SpongeOfflinePlayer(User user) { + public SpongeOfflinePlayer(SpongeDiscordSRV discordSRV, User user) { + this.discordSRV = discordSRV; this.user = user; } @@ -36,6 +40,11 @@ public class SpongeOfflinePlayer implements IOfflinePlayer { return user.name(); } + @Override + public Profile profile() { + return discordSRV.profileManager().getProfile(uniqueId()).orElseThrow(IllegalStateException::new); + } + @Override public @NotNull Identity identity() { return user.profile(); diff --git a/sponge/src/main/java/com/discordsrv/sponge/player/SpongePlayer.java b/sponge/src/main/java/com/discordsrv/sponge/player/SpongePlayer.java index 4a638d65..ef25d5f8 100644 --- a/sponge/src/main/java/com/discordsrv/sponge/player/SpongePlayer.java +++ b/sponge/src/main/java/com/discordsrv/sponge/player/SpongePlayer.java @@ -29,12 +29,10 @@ import org.spongepowered.api.entity.living.player.server.ServerPlayer; public class SpongePlayer extends SpongeOfflinePlayer implements IPlayer { - private final SpongeDiscordSRV discordSRV; private final ServerPlayer player; public SpongePlayer(SpongeDiscordSRV discordSRV, ServerPlayer player) { - super(player.user()); - this.discordSRV = discordSRV; + super(discordSRV, player.user()); this.player = player; } diff --git a/sponge/src/main/java/com/discordsrv/sponge/player/SpongePlayerProvider.java b/sponge/src/main/java/com/discordsrv/sponge/player/SpongePlayerProvider.java index 50991a82..2d84ff80 100644 --- a/sponge/src/main/java/com/discordsrv/sponge/player/SpongePlayerProvider.java +++ b/sponge/src/main/java/com/discordsrv/sponge/player/SpongePlayerProvider.java @@ -71,7 +71,7 @@ public class SpongePlayerProvider extends ServerPlayerProvider