diff --git a/languages/en_EN.yml b/languages/en_EN.yml index 4d3184af7..3a73a4594 100644 --- a/languages/en_EN.yml +++ b/languages/en_EN.yml @@ -1,7 +1,7 @@ language: name: "English (UK)" locale: "en_GB" - version: "1.9.7" + version: "2.0.0" author: "Presti" command: perform: diff --git a/pom.xml b/pom.xml index 4dd24dc0a..08fa8adef 100644 --- a/pom.xml +++ b/pom.xml @@ -123,7 +123,7 @@ se.michaelthelin.spotify spotify-web-api-java - 7.2.1 + 7.2.2 commons-codec @@ -180,6 +180,11 @@ + + org.slf4j + slf4j-api + 2.0.3 + ch.qos.logback logback-classic diff --git a/src/main/java/de/presti/ree6/language/Language.java b/src/main/java/de/presti/ree6/language/Language.java index 9103b19e1..1deed8055 100644 --- a/src/main/java/de/presti/ree6/language/Language.java +++ b/src/main/java/de/presti/ree6/language/Language.java @@ -128,4 +128,31 @@ public String getResource(@NotNull String key, @Nullable Object... parameter) { if (!resources.containsKey(key)) return "Missing language resource!"; return String.format(resources.get(key), parameter); } + + /** + * Compare the current Language version with another Language. + * @param language The Language to compare with. + * @return The result of the comparison. True, if it should update | False, if it should not be updated. + */ + public boolean compareVersion(Language language) { + if (language == null) return false; + if (language.getVersion() == null) return false; + if (version == null) return true; + if (language.getVersion().equals(version)) return false; + + String[] split = version.split("\\."); + + int mayor = Integer.parseInt(split[0]); + int minor = Integer.parseInt(split[1]); + int patch = Integer.parseInt(split[2]); + + String[] split2 = language.getVersion().split("\\."); + int otherMayor = Integer.parseInt(split2[0]); + int otherMinor = Integer.parseInt(split2[1]); + int otherPatch = Integer.parseInt(split2[2]); + + if (otherMayor > mayor) return true; + if (otherMayor == mayor && otherMinor > minor) return true; + return otherMayor == mayor && otherMinor == minor && otherPatch > patch; + } } diff --git a/src/main/java/de/presti/ree6/language/LanguageService.java b/src/main/java/de/presti/ree6/language/LanguageService.java index b78f4d7b0..38351e6d7 100644 --- a/src/main/java/de/presti/ree6/language/LanguageService.java +++ b/src/main/java/de/presti/ree6/language/LanguageService.java @@ -39,8 +39,8 @@ public static void downloadLanguages() { Path languageFile = Path.of("languages/", language + ".yml"); - if (Files.exists(languageFile)) { - log.info("Ignoring Language download: {}", language); + if (!languageFile.toAbsolutePath().startsWith(Path.of("languages/").toAbsolutePath())) { + log.info("Ignoring Language download, since Path Traversal has been detected!"); return; } @@ -49,7 +49,23 @@ public static void downloadLanguages() { try (InputStream inputStream = RequestUtility.request(RequestUtility.Request.builder().url(download).build())) { if (inputStream == null) return; - Files.copy(inputStream, languageFile); + if (Files.exists(languageFile)) { + log.info("Language file {} already exists! Will compare version!", language); + YamlConfiguration newLanguageYaml = YamlConfiguration.loadConfiguration(inputStream); + Language newLanguage = new Language(newLanguageYaml); + Language oldLanguage = new Language(YamlConfiguration.loadConfiguration(languageFile.toFile())); + if (newLanguage.compareVersion(oldLanguage)) { + log.info("Language file {} is outdated!\nWill update!", language); + if (!languageFile.toFile().delete()) { + log.info("Failed to delete old Language file {}!", language); + } + newLanguageYaml.save(languageFile.toFile()); + } else { + log.info("Language file {} is up to date!", language); + } + } else { + Files.copy(inputStream, languageFile); + } } catch (IOException exception) { log.error("An error occurred while downloading the language file!", exception); } diff --git a/src/main/java/de/presti/ree6/main/Main.java b/src/main/java/de/presti/ree6/main/Main.java index 1f2bfcc9b..1c78ab445 100644 --- a/src/main/java/de/presti/ree6/main/Main.java +++ b/src/main/java/de/presti/ree6/main/Main.java @@ -1,7 +1,6 @@ package de.presti.ree6.main; import com.google.gson.JsonObject; -import com.zaxxer.hikari.HikariDataSource; import de.presti.ree6.addons.AddonLoader; import de.presti.ree6.addons.AddonManager; import de.presti.ree6.audio.AudioPlayerSendHandler; @@ -82,11 +81,6 @@ public class Main { */ Config config; - /** - * A reference to the Bots' generell data source. - */ - HikariDataSource dataSource; - /** * String used to identify the last day. */ @@ -116,7 +110,7 @@ public static void main(String[] args) { Sentry.init(options -> { String dsn = instance.config.getConfiguration().getString("sentry.dsn"); - options.setDsn(dsn == null ? "" : dsn); + options.setDsn((dsn == null || dsn.equalsIgnoreCase("yourSentryDSNHere")) ? "" : dsn); // Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring. // We recommend adjusting this value in production. options.setTracesSampleRate(1.0); @@ -411,15 +405,6 @@ public MusicWorker getMusicWorker() { return musicWorker; } - /** - * Retrieve the Instance of the {@link HikariDataSource}. - * - * @return the {@link HikariDataSource} instance. - */ - public HikariDataSource getDataSource() { - return dataSource; - } - /** * Retrieve the Instance of the Config. * diff --git a/src/main/java/de/presti/ree6/main/MigrationMain.java b/src/main/java/de/presti/ree6/main/MigrationMain.java index 86db65dfd..1a2bd9fb2 100644 --- a/src/main/java/de/presti/ree6/main/MigrationMain.java +++ b/src/main/java/de/presti/ree6/main/MigrationMain.java @@ -41,11 +41,10 @@ public static void main(String[] args) { instance.config.init(); // Create a new connection between the Application and the SQL-Server. - instance.sqlConnector = new SQLConnector(instance.config.getConfiguration().getString("mysql.user"), - instance.config.getConfiguration().getString("mysql.db"), instance.config.getConfiguration().getString("mysql.pw"), - instance.config.getConfiguration().getString("mysql.host"), instance.config.getConfiguration().getInt("mysql.port")); + instance.sqlConnector = new SQLConnector(instance.config.getConfiguration().getString("hikari.sql.user"), + instance.config.getConfiguration().getString("hikari.sql.db"), instance.config.getConfiguration().getString("hikari.sql.pw"), + instance.config.getConfiguration().getString("hikari.sql.host"), instance.config.getConfiguration().getInt("hikari.sql.port")); new MigrationBuilder().name(args.length != 0 ? args[0] : "NOTGIVEN").build(instance.sqlConnector).storeMigration(); } - } diff --git a/src/main/java/de/presti/ree6/sql/SQLConnector.java b/src/main/java/de/presti/ree6/sql/SQLConnector.java index 0a3f379b5..b77f4d8bb 100644 --- a/src/main/java/de/presti/ree6/sql/SQLConnector.java +++ b/src/main/java/de/presti/ree6/sql/SQLConnector.java @@ -98,6 +98,8 @@ public void connectToSQLServer() { HikariConfig hConfig = new HikariConfig(); hConfig.setJdbcUrl(SQLSession.getJdbcURL()); + hConfig.setUsername(Main.getInstance().getConfig().getConfiguration().getString("hikari.sql.user")); + hConfig.setPassword(Main.getInstance().getConfig().getConfiguration().getString("hikari.sql.pw")); hConfig.setMaximumPoolSize(SQLSession.getMaxPoolSize()); dataSource = new HikariDataSource(hConfig); log.info("Service (SQL) has been started. Connection was successful."); @@ -140,12 +142,10 @@ public String buildConnectionURL() { switch (Main.getInstance().getConfig().getConfiguration().getString("hikari.misc.storage").toLowerCase()) { case "mariadb" -> { - jdbcUrl = "jdbc:mariadb://%s:%s/%s?user=%s&password=%s"; + jdbcUrl = "jdbc:mariadb://%s:%s/%s"; jdbcUrl = jdbcUrl.formatted(databaseServerIP, databaseServerPort, - databaseName, - databaseUser, - databasePassword); + databaseName); } default -> { diff --git a/src/main/java/de/presti/ree6/sql/SQLSession.java b/src/main/java/de/presti/ree6/sql/SQLSession.java index 19ed166de..90e42be78 100644 --- a/src/main/java/de/presti/ree6/sql/SQLSession.java +++ b/src/main/java/de/presti/ree6/sql/SQLSession.java @@ -1,6 +1,7 @@ package de.presti.ree6.sql; import com.google.gson.JsonElement; +import de.presti.ree6.main.Main; import de.presti.ree6.utils.data.TypUtil; import jakarta.persistence.AttributeConverter; import lombok.extern.slf4j.Slf4j; @@ -38,7 +39,7 @@ public class SQLSession { * Build a new SessionFactory or return the current one. * @return The SessionFactory. */ - public static SessionFactory buildSessionFactory() { + public static SessionFactory buildSessionFactory(String username, String password) { if (sessionFactory != null) return getSessionFactory(); try { @@ -47,8 +48,13 @@ public static SessionFactory buildSessionFactory() { properties.put("hibernate.connection.datasource", "com.zaxxer.hikari.HikariDataSource"); properties.put("hibernate.connection.provider_class", "org.hibernate.hikaricp.internal.HikariCPConnectionProvider"); properties.put("hibernate.connection.url", jdbcURL); - properties.put("hibernate.hikari.maximumPoolSize", maxPoolSize); + properties.put("hibernate.connection.username", username); + properties.put("hibernate.connection.password", password); + properties.put("hibernate.hikari.maximumPoolSize", String.valueOf(maxPoolSize)); properties.put("hibernate.dialect","org.hibernate.dialect.MariaDBDialect"); + properties.put("hibernate.hbm2ddl.auto", "update"); + properties.put("hibernate.show_sql", true); + properties.put("hibernate.format_sql", true); configuration.addProperties(properties); configuration.addPackage("de.presti.ree6.sql.entities"); configuration.addAttributeConverter(new AttributeConverter() { @@ -78,10 +84,9 @@ public String convertToDatabaseColumn(byte[] dbData) { ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); return sessionFactory = configuration.buildSessionFactory(serviceRegistry); - } - catch (Throwable ex) { + } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed - log.error("Initial SessionFactory creation failed." + ex); + log.error("Initial SessionFactory creation failed.", ex); throw new ExceptionInInitializerError(ex); } } @@ -123,6 +128,10 @@ public static int getMaxPoolSize() { * @return The SessionFactory. */ public static SessionFactory getSessionFactory() { + if (sessionFactory == null) + return sessionFactory = buildSessionFactory( + Main.getInstance().getConfig().getConfiguration().getString("hikari.sql.user"), + Main.getInstance().getConfig().getConfiguration().getString("hikari.sql.pw")); return sessionFactory; } } diff --git a/src/main/java/de/presti/ree6/sql/entities/Recording.java b/src/main/java/de/presti/ree6/sql/entities/Recording.java index a94623fcf..73d2d0658 100644 --- a/src/main/java/de/presti/ree6/sql/entities/Recording.java +++ b/src/main/java/de/presti/ree6/sql/entities/Recording.java @@ -1,11 +1,9 @@ package de.presti.ree6.sql.entities; import com.google.gson.JsonArray; +import com.google.gson.JsonElement; import de.presti.ree6.utils.others.RandomUtils; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; +import jakarta.persistence.*; /** * This class is used to represent a Ree6-Voice-Recording, in our Database. @@ -42,14 +40,16 @@ public class Recording { /** * The WAV-File bytes. */ + @Convert @Column(name = "recording") byte[] recording; /** * An JsonArray containing the IDs of the Users who have participated in the Recording. */ + @Convert @Column(name = "participants") - JsonArray jsonArray; + JsonElement jsonArray; /** * Value used to tell us when this entry was made. @@ -71,7 +71,7 @@ public Recording() { * @param recording the WAV-File bytes. * @param jsonArray an JsonArray containing the IDs of the Users who have participated in the Recording. */ - public Recording(String guildId, String voiceId, String creatorId, byte[] recording, JsonArray jsonArray) { + public Recording(String guildId, String voiceId, String creatorId, byte[] recording, JsonElement jsonArray) { this.identifier = RandomUtils.getRandomBase64String(16); this.guildId = guildId; this.voiceId = voiceId; @@ -126,7 +126,7 @@ public byte[] getRecording() { * @return the IDs of the Users who have participated in the Recording. */ public JsonArray getJsonArray() { - return jsonArray; + return jsonArray.getAsJsonArray(); } /** diff --git a/src/main/java/de/presti/ree6/sql/entities/stats/ChannelStats.java b/src/main/java/de/presti/ree6/sql/entities/stats/ChannelStats.java index 97be404e3..95933564e 100644 --- a/src/main/java/de/presti/ree6/sql/entities/stats/ChannelStats.java +++ b/src/main/java/de/presti/ree6/sql/entities/stats/ChannelStats.java @@ -15,7 +15,7 @@ public class ChannelStats { * The PrimaryKey of the Entity. */ @Id - @GeneratedValue + @GeneratedValue(strategy=GenerationType.AUTO) @Column(name = "id") private int id;