diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..ba49d37 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,26 @@ +# Will simply build your gradle project. +name: Build Gradle Project + +# This action will run every time you push to the "dev" branch. +on: + push: + branches: + - "dev*" + +jobs: + build-project: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-java@v3 + with: + distribution: temurin + java-version: 21 + - name: Checkout project sources + uses: actions/checkout@v3 + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + - name: Make gradlew executable + run: chmod +x ./gradlew + - name: Run build with Gradle Wrapper + run: ./gradlew build \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7fefd82..d1b11b3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ build common/build gameserver/build -proxy/build \ No newline at end of file +proxy/build +run/ \ No newline at end of file diff --git a/README.md b/README.md index f4a845e..a7a9aba 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,6 @@ plugins folder in your Velocity server. Simply alter anything in the `config.yml` that is generated located in `./plugins/reconnect/config.yml`. -To allow users to reconnect, make sure they have the permission `velocity.reconnect`! -

(back to top)

diff --git a/build.gradle.kts b/build.gradle.kts index b4424c4..98b7bc7 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -40,13 +40,6 @@ tasks { mergeServiceFiles() } runVelocity { -// velocityVersion(libs.versions.velocity.api.get()) + velocityVersion(libs.versions.velocity.get()) } -// withType(xyz.jpenilla.runtask.task.AbstractRun::class) { -// javaLauncher.set(javaToolchains.launcherFor { -// languageVersion = JavaLanguageVersion.of(17) -// vendor = JvmVendorSpec.JETBRAINS -// }) -// jvmArgs("-XX:+AllowEnhancedClassRedefinition", "-XX:+AllowRedefinitionToAddDeleteMethods") -// } } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index dee29cc..4e1ed09 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -9,6 +9,15 @@ pluginManagement { } plugins { - // add toolchain resolver - id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" + id("com.gradle.enterprise") version("3.15") +} + +gradleEnterprise { + if (System.getenv("CI") != null) { + buildScan { + publishAlways() + termsOfServiceUrl = "https://gradle.com/terms-of-service" + termsOfServiceAgree = "yes" + } + } } \ No newline at end of file diff --git a/src/main/java/com/mattmx/reconnect/ReconnectConfig.java b/src/main/java/com/mattmx/reconnect/ReconnectConfig.java index 117ec87..056c032 100644 --- a/src/main/java/com/mattmx/reconnect/ReconnectConfig.java +++ b/src/main/java/com/mattmx/reconnect/ReconnectConfig.java @@ -1,9 +1,11 @@ package com.mattmx.reconnect; +import org.spongepowered.configurate.objectmapping.ConfigSerializable; import org.spongepowered.configurate.objectmapping.meta.Comment; import java.util.List; +@ConfigSerializable public class ReconnectConfig { @Comment("Do we want to send players a message when they are reconnected to a server?") @@ -47,12 +49,14 @@ public class ReconnectConfig { """) public StorageOptions storage = new StorageOptions(); + @ConfigSerializable public static class StorageOptions { public String method = "yaml"; public StorageOptionsData data = new StorageOptionsData(); } + @ConfigSerializable public static class StorageOptionsData { public String address = "localhost:3306"; @Comment("For sqlite or yaml storage types this will be the file location.") @@ -64,12 +68,13 @@ public static class StorageOptionsData { Advanced connection pool settings. Most users will not need to change these. https://github.com/brettwooldridge/HikariCP/blob/dev/README.md#gear-configuration-knobs-baby """) - public AdvancedConnectionOptions connectionOptions = new AdvancedConnectionOptions(); + public AdvancedConnectionParams connectionParameters = new AdvancedConnectionParams(); } - public static class AdvancedConnectionOptions { + @ConfigSerializable + public static class AdvancedConnectionParams { public boolean useJdbcString = false; - public String jdbcString = "jdbc:mysql://host:3306/db"; + public String jdbcString = "jdbc:mysql://localhost:3306/db"; public long connectionTimeout = 30000; public long idleTimeout = 600000; public long keepAliveTime = 0; diff --git a/src/main/java/com/mattmx/reconnect/ReconnectListener.java b/src/main/java/com/mattmx/reconnect/ReconnectListener.java index ab42f81..d96ddd2 100644 --- a/src/main/java/com/mattmx/reconnect/ReconnectListener.java +++ b/src/main/java/com/mattmx/reconnect/ReconnectListener.java @@ -33,9 +33,6 @@ public void onChooseInitialServer(@NotNull PlayerChooseInitialServerEvent event) Player player = event.getPlayer(); - // Check if they have the basic permission node - if (!player.hasPermission("velocity.reconnect")) return; - String previousServerName = plugin.getStorageManager() .getStorageMethod() .getLastServer(player.getUniqueId()); diff --git a/src/main/java/com/mattmx/reconnect/ReconnectVelocity.java b/src/main/java/com/mattmx/reconnect/ReconnectVelocity.java index 3a43df1..2a1c109 100644 --- a/src/main/java/com/mattmx/reconnect/ReconnectVelocity.java +++ b/src/main/java/com/mattmx/reconnect/ReconnectVelocity.java @@ -3,7 +3,6 @@ import com.google.inject.Inject; import com.mattmx.reconnect.storage.*; import com.mattmx.reconnect.util.updater.UpdateChecker; -import com.moandjiezana.toml.Toml; import com.moandjiezana.toml.TomlWriter; import com.velocitypowered.api.event.Subscribe; import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; @@ -15,6 +14,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; import java.io.BufferedWriter; import java.io.File; @@ -41,6 +43,8 @@ public class ReconnectVelocity { private final @Nullable Logger logger; private final @Nullable Path dataDirectory; + private final File configLocation; + private final YamlConfigurationLoader loader; private @Nullable ReconnectConfig config; private @Nullable StorageManager storage; private UpdateChecker checker; @@ -51,6 +55,12 @@ public ReconnectVelocity(@Nullable ProxyServer server, @Nullable Logger logger, this.logger = logger; this.dataDirectory = dataDirectory; + configLocation = getDataDirectory().resolve("config.yml").toFile(); + + loader = YamlConfigurationLoader.builder() + .file(configLocation) + .build(); + instance = this; saveDefaultConfig(); @@ -59,12 +69,12 @@ public ReconnectVelocity(@Nullable ProxyServer server, @Nullable Logger logger, StorageManager.registerStorageMethod(new MariaDbStorage()); StorageManager.registerStorageMethod(new SQLiteStorage()); StorageManager.registerStorageMethod(new YamlStorage()); - StorageManager.registerStorageMethod(new LuckPermsStorage()); + if (proxy.getPluginManager().isLoaded("luckperms")) { + StorageManager.registerStorageMethod(new LuckPermsStorage()); + } ReconnectCommand.register(this); - loadStorage(); - checker = new UpdateChecker(); if (checker.get("https://api.github.com/repos/Matt-MX/ReconnectVelocity/releases/latest") @@ -82,38 +92,41 @@ public void loadStorage() { Objects.requireNonNull(method, "That storage method is invalid!"); // Shutdown current manager - getStorageManager().end(); + if (storage != null) { + storage.end(); + } storage = StorageManager.createStorageManager(method); + + getLogger().info("Using {} as storage method!", storage.getStorageMethod().getId()); } @SuppressWarnings({"ResultOfMethodCallIgnored"}) public void saveDefaultConfig() { - File filePath = getDataDirectory() - .resolve("config.toml") - .toFile(); - - if (!filePath.exists()) { - filePath.getParentFile().mkdirs(); + if (!configLocation.exists()) { + configLocation.getParentFile().mkdirs(); try { - filePath.createNewFile(); - try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) { - writer.write(new TomlWriter().write(new ReconnectConfig())); - } + ConfigurationNode node = loader.load(); + node.set(ReconnectConfig.class, new ReconnectConfig()); + loader.save(node); } catch (IOException e) { throw new RuntimeException(e); } } - this.config = new Toml() - .read(filePath) - .to(ReconnectConfig.class); + try { + this.config = loader.load().get(ReconnectConfig.class); + } catch (ConfigurateException e) { + throw new RuntimeException(e); + } } @Subscribe public void onProxyInitialization(ProxyInitializeEvent event) { + loadStorage(); + getProxy().getEventManager().register(this, new ReconnectListener(this)); } diff --git a/src/main/java/com/mattmx/reconnect/storage/LuckPermsStorage.java b/src/main/java/com/mattmx/reconnect/storage/LuckPermsStorage.java index 73ca486..1111ccc 100644 --- a/src/main/java/com/mattmx/reconnect/storage/LuckPermsStorage.java +++ b/src/main/java/com/mattmx/reconnect/storage/LuckPermsStorage.java @@ -1,5 +1,6 @@ package com.mattmx.reconnect.storage; +import com.mattmx.reconnect.ReconnectCommand; import com.mattmx.reconnect.ReconnectVelocity; import net.luckperms.api.LuckPermsProvider; import net.luckperms.api.model.user.User; @@ -18,6 +19,7 @@ public void init() { ReconnectVelocity.get().getLogger().warn("LuckPerms is not installed!"); exception.printStackTrace(); } + ReconnectVelocity.get().getLogger().info("LuckPerms found!"); } @Override @@ -55,6 +57,6 @@ public String getLastServer(String uuid) { @Override public String getMethod() { - return null; + return "luckperms"; } } diff --git a/src/main/java/com/mattmx/reconnect/storage/MariaDbStorage.java b/src/main/java/com/mattmx/reconnect/storage/MariaDbStorage.java index 3c21b7a..827be79 100644 --- a/src/main/java/com/mattmx/reconnect/storage/MariaDbStorage.java +++ b/src/main/java/com/mattmx/reconnect/storage/MariaDbStorage.java @@ -19,19 +19,19 @@ public void init() { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setDriverClassName(org.mariadb.jdbc.Driver.class.getName()); - if (config.storage.data.connectionOptions.useJdbcString) { - hikariConfig.setJdbcUrl(config.storage.data.connectionOptions.jdbcString); + if (config.storage.data.connectionParameters.useJdbcString) { + hikariConfig.setJdbcUrl(config.storage.data.connectionParameters.jdbcString); } else { hikariConfig.setJdbcUrl("jdbc:mariadb://" + config.storage.data.address + "/" + config.storage.data.database); } hikariConfig.setUsername(config.storage.data.username); hikariConfig.setPassword(config.storage.data.password); - hikariConfig.setConnectionTimeout(config.storage.data.connectionOptions.connectionTimeout); - hikariConfig.setIdleTimeout(config.storage.data.connectionOptions.idleTimeout); - hikariConfig.setKeepaliveTime(config.storage.data.connectionOptions.keepAliveTime); - hikariConfig.setMaxLifetime(config.storage.data.connectionOptions.maxLifetime); - hikariConfig.setMinimumIdle(config.storage.data.connectionOptions.minimumIdle); - hikariConfig.setMaximumPoolSize(config.storage.data.connectionOptions.maximumPoolSize); + hikariConfig.setConnectionTimeout(config.storage.data.connectionParameters.connectionTimeout); + hikariConfig.setIdleTimeout(config.storage.data.connectionParameters.idleTimeout); + hikariConfig.setKeepaliveTime(config.storage.data.connectionParameters.keepAliveTime); + hikariConfig.setMaxLifetime(config.storage.data.connectionParameters.maxLifetime); + hikariConfig.setMinimumIdle(config.storage.data.connectionParameters.minimumIdle); + hikariConfig.setMaximumPoolSize(config.storage.data.connectionParameters.maximumPoolSize); hikariConfig.setPoolName("reconnect"); ds = new HikariDataSource(hikariConfig); diff --git a/src/main/java/com/mattmx/reconnect/storage/MySqlStorage.java b/src/main/java/com/mattmx/reconnect/storage/MySqlStorage.java index dad7285..50a5ce6 100644 --- a/src/main/java/com/mattmx/reconnect/storage/MySqlStorage.java +++ b/src/main/java/com/mattmx/reconnect/storage/MySqlStorage.java @@ -19,19 +19,19 @@ public void init() { HikariConfig hikariConfig = new HikariConfig(); hikariConfig.setDriverClassName(org.mariadb.jdbc.Driver.class.getName()); - if (config.storage.data.connectionOptions.useJdbcString) { - hikariConfig.setJdbcUrl(config.storage.data.connectionOptions.jdbcString); + if (config.storage.data.connectionParameters.useJdbcString) { + hikariConfig.setJdbcUrl(config.storage.data.connectionParameters.jdbcString); } else { hikariConfig.setJdbcUrl("jdbc:mariadb://" + config.storage.data.address + "/" + config.storage.data.database); } hikariConfig.setUsername(config.storage.data.username); hikariConfig.setPassword(config.storage.data.password); - hikariConfig.setConnectionTimeout(config.storage.data.connectionOptions.connectionTimeout); - hikariConfig.setIdleTimeout(config.storage.data.connectionOptions.idleTimeout); - hikariConfig.setKeepaliveTime(config.storage.data.connectionOptions.keepAliveTime); - hikariConfig.setMaxLifetime(config.storage.data.connectionOptions.maxLifetime); - hikariConfig.setMinimumIdle(config.storage.data.connectionOptions.minimumIdle); - hikariConfig.setMaximumPoolSize(config.storage.data.connectionOptions.maximumPoolSize); + hikariConfig.setConnectionTimeout(config.storage.data.connectionParameters.connectionTimeout); + hikariConfig.setIdleTimeout(config.storage.data.connectionParameters.idleTimeout); + hikariConfig.setKeepaliveTime(config.storage.data.connectionParameters.keepAliveTime); + hikariConfig.setMaxLifetime(config.storage.data.connectionParameters.maxLifetime); + hikariConfig.setMinimumIdle(config.storage.data.connectionParameters.minimumIdle); + hikariConfig.setMaximumPoolSize(config.storage.data.connectionParameters.maximumPoolSize); hikariConfig.setPoolName("reconnect"); ds = new HikariDataSource(hikariConfig); diff --git a/src/main/java/com/mattmx/reconnect/storage/StorageManager.java b/src/main/java/com/mattmx/reconnect/storage/StorageManager.java index a10371f..ee577ac 100644 --- a/src/main/java/com/mattmx/reconnect/storage/StorageManager.java +++ b/src/main/java/com/mattmx/reconnect/storage/StorageManager.java @@ -9,38 +9,31 @@ public class StorageManager { private static final HashMap methods = new HashMap<>(); - private @Nullable StorageMethod currentStorageMethod; + private final @NotNull StorageMethod currentStorageMethod; + + public StorageManager(@NotNull StorageMethod method) { + this.currentStorageMethod = method; + } public void init() { - Objects.requireNonNull(currentStorageMethod, "Storage not initialized! Can't call init until it is initialized.").init(); + currentStorageMethod.init(); } public void end() { - Objects.requireNonNull(currentStorageMethod, "Storage not initialized! Can't call end until it is initialized.").save(); + currentStorageMethod.save(); } public @NotNull StorageMethod getStorageMethod() { - if (this.currentStorageMethod == null) { - throw new RuntimeException("There has been no Storage Method set!"); - } - return this.currentStorageMethod; } - public void setCurrentStorageMethod(@NotNull StorageMethod currentStorageMethod) { - this.currentStorageMethod = currentStorageMethod; - } - public static void registerStorageMethod(@NotNull StorageMethod method) { methods.put(method.getId(), method); } public static StorageManager createStorageManager(@NotNull StorageMethod method) { - StorageManager manager = new StorageManager(); - manager.setCurrentStorageMethod(method); - + StorageManager manager = new StorageManager(method); manager.init(); - return manager; } diff --git a/src/main/java/com/mattmx/reconnect/storage/YamlStorage.java b/src/main/java/com/mattmx/reconnect/storage/YamlStorage.java index 700f22f..e465552 100644 --- a/src/main/java/com/mattmx/reconnect/storage/YamlStorage.java +++ b/src/main/java/com/mattmx/reconnect/storage/YamlStorage.java @@ -1,19 +1,27 @@ package com.mattmx.reconnect.storage; import com.mattmx.reconnect.ReconnectVelocity; +import com.velocitypowered.api.scheduler.ScheduledTask; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.simpleyaml.configuration.file.YamlConfiguration; import java.io.File; import java.io.IOException; +import java.time.Duration; +import java.util.Objects; +import java.util.Optional; public class YamlStorage extends StorageMethod { - public YamlConfiguration data; - public File dataPath = ReconnectVelocity.get() + public @Nullable YamlConfiguration data; + public @NotNull File dataPath = ReconnectVelocity.get() .getDataDirectory() .resolve("data.yml") .toFile(); + private @Nullable ScheduledTask autoSaveTask; + @Override public void init() { if (!dataPath.exists()) { @@ -25,24 +33,36 @@ public void init() { } data = YamlConfiguration.loadConfiguration(dataPath); + + autoSaveTask = ReconnectVelocity.get() + .getProxy() + .getScheduler() + .buildTask(ReconnectVelocity.get(), this::saveData) + .repeat(Duration.ofMinutes(5L)) + .schedule(); } @Override public void setLastServer(String uuid, String servername) { - data.set(uuid, servername); + Objects.requireNonNull(data).set(uuid, servername); } @Override public String getLastServer(String uuid) { - return data.getString(uuid); + return Objects.requireNonNull(data).getString(uuid); } @Override public void save() { + saveData(); + Optional.ofNullable(autoSaveTask).ifPresent(ScheduledTask::cancel); + } + + private void saveData() { try { - data.save(dataPath); - } catch (IOException e) { - e.printStackTrace(); + Objects.requireNonNull(data).save(dataPath); + } catch (IOException exception) { + exception.printStackTrace(); } }