From dda3ebc7b4c4612c5faebeb6f7dbb15400425ea7 Mon Sep 17 00:00:00 2001 From: microwin7 Date: Fri, 23 Aug 2024 21:58:57 +0300 Subject: [PATCH 1/6] [FIX] RejectedExecutionException after cancelled Download task --- .../src/main/java/pro/gravit/launcher/base/Downloader.java | 1 - 1 file changed, 1 deletion(-) diff --git a/LauncherAPI/src/main/java/pro/gravit/launcher/base/Downloader.java b/LauncherAPI/src/main/java/pro/gravit/launcher/base/Downloader.java index 6fb5bd20..01c80c8d 100644 --- a/LauncherAPI/src/main/java/pro/gravit/launcher/base/Downloader.java +++ b/LauncherAPI/src/main/java/pro/gravit/launcher/base/Downloader.java @@ -141,7 +141,6 @@ public void cancel() { } } tasks.clear(); - executor.shutdownNow(); } public boolean isCanceled() { From 9d870849a1ee0e17139b652c90f9d8a578d93c7e Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Wed, 18 Sep 2024 16:36:15 +0700 Subject: [PATCH 2/6] [ANY] Update dependencies --- props.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/props.gradle b/props.gradle index 8c8498c3..3d5fc90f 100644 --- a/props.gradle +++ b/props.gradle @@ -1,10 +1,10 @@ project.ext { verAsm = '9.7' verNetty = '4.1.111.Final' - verOshiCore = '6.6.2' + verOshiCore = '6.6.4' verJunit = '5.10.2' verJansi = '2.4.1' - verJline = '3.26.1' + verJline = '3.26.3' verJwt = '0.12.5' verGson = '2.11.0' verBcpkix = '1.78.1' @@ -12,7 +12,7 @@ verLog4j = '2.23.1' verMySQLConn = '9.0.0' verMariaDBConn = '3.4.0' - verPostgreSQLConn = '42.7.3' - verH2Conn = '2.2.224' + verPostgreSQLConn = '42.7.4' + verH2Conn = '2.3.232' verProguard = '7.5.0' } From 7dcb08fdaf4b0a84037829a198be53af882eb8e8 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sat, 28 Sep 2024 01:47:55 +0700 Subject: [PATCH 3/6] [FEATURE] Support HWID in SQLCoreProvider --- .../auth/core/SQLCoreProvider.java | 366 +++++++++++++++++- 1 file changed, 359 insertions(+), 7 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/SQLCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/SQLCoreProvider.java index 49161f85..34d131e3 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/SQLCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/SQLCoreProvider.java @@ -1,11 +1,25 @@ package pro.gravit.launchserver.auth.core; +import pro.gravit.launcher.base.request.secure.HardwareReportRequest; import pro.gravit.launchserver.LaunchServer; import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.auth.HikariSQLSourceConfig; +import pro.gravit.launchserver.auth.MySQLSourceConfig; import pro.gravit.launchserver.auth.SQLSourceConfig; +import pro.gravit.launchserver.auth.core.interfaces.UserHardware; +import pro.gravit.launchserver.auth.core.interfaces.provider.AuthSupportHardware; +import pro.gravit.launchserver.auth.core.interfaces.session.UserSessionSupportHardware; +import pro.gravit.utils.helper.IOHelper; -public class SQLCoreProvider extends AbstractSQLCoreProvider { +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.sql.*; +import java.util.Base64; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +public class SQLCoreProvider extends AbstractSQLCoreProvider implements AuthSupportHardware { public HikariSQLSourceConfig holder; @Override @@ -14,14 +28,352 @@ public void close() { holder.close(); } - @Override - public void init(LaunchServer server, AuthProviderPair pair) { - holder.init(); - super.init(server, pair); - } - @Override public SQLSourceConfig getSQLConfig() { return holder; } + + + public String hardwareIdColumn; + public String tableHWID = "hwids"; + public String tableHWIDLog = "hwidLog"; + public double criticalCompareLevel = 1.0; + private transient String sqlFindHardwareByPublicKey; + private transient String sqlFindHardwareByData; + private transient String sqlFindHardwareById; + private transient String sqlCreateHardware; + private transient String sqlCreateHWIDLog; + private transient String sqlUpdateHardwarePublicKey; + private transient String sqlUpdateHardwareBanned; + private transient String sqlUpdateUsers; + private transient String sqlUsersByHwidId; + + @Override + public void init(LaunchServer server, AuthProviderPair pair) { + holder.init(); + super.init(server, pair); + String userInfoCols = makeUserCols(); + String hardwareInfoCols = "id, hwDiskId, baseboardSerialNumber, displayId, bitness, totalMemory, logicalProcessors, physicalProcessors, processorMaxFreq, battery, id, graphicCard, banned, publicKey"; + if (sqlFindHardwareByPublicKey == null) + sqlFindHardwareByPublicKey = "SELECT %s FROM %s WHERE publicKey = ?".formatted(hardwareInfoCols, tableHWID); + if (sqlFindHardwareById == null) + sqlFindHardwareById = "SELECT %s FROM %s WHERE id = ?".formatted(hardwareInfoCols, tableHWID); + if (sqlUsersByHwidId == null) + sqlUsersByHwidId = "SELECT %s FROM %s WHERE %s = ?".formatted(userInfoCols, table, hardwareIdColumn); + if (sqlFindHardwareByData == null) + sqlFindHardwareByData = "SELECT %s FROM %s".formatted(hardwareInfoCols, tableHWID); + if (sqlCreateHardware == null) + sqlCreateHardware = "INSERT INTO %s (publickey, hwDiskId, baseboardSerialNumber, displayId, bitness, totalMemory, logicalProcessors, physicalProcessors, processorMaxFreq, graphicCard, battery, banned) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, '0')".formatted(tableHWID); + if (sqlCreateHWIDLog == null) + sqlCreateHWIDLog = "INSERT INTO %s (hwidId, newPublicKey) VALUES (?, ?)".formatted(tableHWIDLog); + if (sqlUpdateHardwarePublicKey == null) + sqlUpdateHardwarePublicKey = "UPDATE %s SET publicKey = ? WHERE id = ?".formatted(tableHWID); + sqlUpdateHardwareBanned = "UPDATE %s SET banned = ? WHERE id = ?".formatted(tableHWID); + sqlUpdateUsers = "UPDATE %s SET %s = ? WHERE %s = ?".formatted(table, hardwareIdColumn, uuidColumn); + } + + @Override + protected String makeUserCols() { + return super.makeUserCols().concat(", ").concat(hardwareIdColumn); + } + + @Override + protected SQLUser constructUser(ResultSet set) throws SQLException { + return set.next() ? new SQLUser(UUID.fromString(set.getString(uuidColumn)), set.getString(usernameColumn), + set.getString(accessTokenColumn), set.getString(serverIDColumn), set.getString(passwordColumn), set.getLong(hardwareIdColumn)) : null; + } + + private SQLUserHardware fetchHardwareInfo(ResultSet set) throws SQLException, IOException { + HardwareReportRequest.HardwareInfo hardwareInfo = new HardwareReportRequest.HardwareInfo(); + hardwareInfo.hwDiskId = set.getString("hwDiskId"); + hardwareInfo.baseboardSerialNumber = set.getString("baseboardSerialNumber"); + byte[] displayId = set.getBytes("displayId"); + hardwareInfo.displayId = displayId == null ? null : displayId; + hardwareInfo.bitness = set.getInt("bitness"); + hardwareInfo.totalMemory = set.getLong("totalMemory"); + hardwareInfo.logicalProcessors = set.getInt("logicalProcessors"); + hardwareInfo.physicalProcessors = set.getInt("physicalProcessors"); + hardwareInfo.processorMaxFreq = set.getLong("processorMaxFreq"); + hardwareInfo.battery = set.getBoolean("battery"); + hardwareInfo.graphicCard = set.getString("graphicCard"); + byte[] publicKey = set.getBytes("publicKey"); + long id = set.getLong("id"); + boolean banned = set.getBoolean("banned"); + return new SQLUserHardware(hardwareInfo, publicKey, id, banned); + } + + private void setUserHardwareId(Connection connection, UUID uuid, long hwidId) throws SQLException { + PreparedStatement s = connection.prepareStatement(sqlUpdateUsers); + s.setLong(1, hwidId); + s.setString(2, uuid.toString()); + s.executeUpdate(); + } + + @Override + public UserHardware getHardwareInfoByPublicKey(byte[] publicKey) { + try (Connection connection = holder.getConnection()) { + connection.setAutoCommit(false); + PreparedStatement s = connection.prepareStatement(sqlFindHardwareByPublicKey); + s.setBytes(1, publicKey); + try (ResultSet set = s.executeQuery()) { + if (set.next()) { + connection.commit(); + return fetchHardwareInfo(set); + } else { + connection.commit(); + return null; + } + } + } catch (SQLException | IOException throwables) { + logger.error("SQL Error", throwables); + return null; + } + } + + @Override + public UserHardware getHardwareInfoByData(HardwareReportRequest.HardwareInfo info) { + try (Connection connection = holder.getConnection()) { + connection.setAutoCommit(false); + PreparedStatement s = connection.prepareStatement(sqlFindHardwareByData); + try (ResultSet set = s.executeQuery()) { + while (set.next()) { + SQLUserHardware hw = fetchHardwareInfo(set); + AuthSupportHardware.HardwareInfoCompareResult result = compareHardwareInfo(hw.getHardwareInfo(), info); + if (result.compareLevel > criticalCompareLevel) { + connection.commit(); + return hw; + } else { + connection.commit(); + } + } + } + } catch (SQLException | IOException throwables) { + logger.error("SQL Error", throwables); + } + return null; + } + + @Override + public UserHardware getHardwareInfoById(String id) { + try (Connection connection = holder.getConnection()) { + connection.setAutoCommit(false); + PreparedStatement s = connection.prepareStatement(sqlFindHardwareById); + s.setLong(1, Long.parseLong(id)); + try (ResultSet set = s.executeQuery()) { + if (set.next()) { + connection.commit(); + return fetchHardwareInfo(set); + } else { + connection.commit(); + return null; + } + } + } catch (SQLException | IOException throwables) { + logger.error("SQL Error", throwables); + return null; + } + } + + @Override + public UserHardware createHardwareInfo(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey) { + try (Connection connection = holder.getConnection()) { + connection.setAutoCommit(false); + PreparedStatement s = connection.prepareStatement(sqlCreateHardware, Statement.RETURN_GENERATED_KEYS); + s.setBytes(1, publicKey); + s.setString(2, hardwareInfo.hwDiskId); + s.setString(3, hardwareInfo.baseboardSerialNumber); + s.setBytes(4, hardwareInfo.displayId == null ? null : hardwareInfo.displayId); + s.setInt(5, hardwareInfo.bitness); + s.setLong(6, hardwareInfo.totalMemory); + s.setInt(7, hardwareInfo.logicalProcessors); + s.setInt(8, hardwareInfo.physicalProcessors); + s.setLong(9, hardwareInfo.processorMaxFreq); + s.setString(10, hardwareInfo.graphicCard); + s.setBoolean(11, hardwareInfo.battery); + s.executeUpdate(); + try (ResultSet generatedKeys = s.getGeneratedKeys()) { + if (generatedKeys.next()) { + //writeHwidLog(connection, generatedKeys.getLong(1), publicKey); + long id = generatedKeys.getLong(1); + connection.commit(); + return new SQLUserHardware(hardwareInfo, publicKey, id, false); + } + } + connection.commit(); + return null; + } catch (SQLException throwables) { + logger.error("SQL Error", throwables); + return null; + } + } + + @Override + public void connectUserAndHardware(UserSession userSession, UserHardware hardware) { + AbstractSQLCoreProvider.SQLUserSession SQLUserSession = (AbstractSQLCoreProvider.SQLUserSession) userSession; + SQLUser SQLUser = (SQLUser) SQLUserSession.getUser(); + SQLUserHardware SQLUserHardware = (SQLUserHardware) hardware; + if (SQLUser.hwidId == SQLUserHardware.id) return; + SQLUser.hwidId = SQLUserHardware.id; + try (Connection connection = holder.getConnection()) { + setUserHardwareId(connection, SQLUser.getUUID(), SQLUserHardware.id); + } catch (SQLException throwables) { + logger.error("SQL Error", throwables); + } + } + + @Override + public void addPublicKeyToHardwareInfo(UserHardware hardware, byte[] publicKey) { + SQLUserHardware SQLUserHardware = (SQLUserHardware) hardware; + SQLUserHardware.publicKey = publicKey; + try (Connection connection = holder.getConnection()) { + connection.setAutoCommit(false); + PreparedStatement s = connection.prepareStatement(sqlUpdateHardwarePublicKey); + s.setBytes(1, publicKey); + s.setLong(2, SQLUserHardware.id); + s.executeUpdate(); + connection.commit(); + } catch (SQLException e) { + logger.error("SQL error", e); + } + } + + @Override + public Iterable getUsersByHardwareInfo(UserHardware hardware) { + List users = new LinkedList<>(); + try (Connection c = holder.getConnection()) { + c.setAutoCommit(false); + PreparedStatement s = c.prepareStatement(sqlUsersByHwidId); + s.setLong(1, Long.parseLong(hardware.getId())); + s.setQueryTimeout(MySQLSourceConfig.TIMEOUT); + try (ResultSet set = s.executeQuery()) { + while (!set.isLast()) { + users.add(constructUser(set)); + } + } + c.commit(); + } catch (SQLException e) { + logger.error("SQL error", e); + return null; + } + return users; + } + + @Override + public void banHardware(UserHardware hardware) { + SQLUserHardware SQLUserHardware = (SQLUserHardware) hardware; + SQLUserHardware.banned = true; + try (Connection connection = holder.getConnection()) { + PreparedStatement s = connection.prepareStatement(sqlUpdateHardwareBanned); + s.setBoolean(1, true); + s.setLong(2, SQLUserHardware.id); + s.executeUpdate(); + } catch (SQLException e) { + logger.error("SQL Error", e); + } + } + + @Override + public void unbanHardware(UserHardware hardware) { + SQLUserHardware SQLUserHardware = (SQLUserHardware) hardware; + SQLUserHardware.banned = false; + try (Connection connection = holder.getConnection()) { + PreparedStatement s = connection.prepareStatement(sqlUpdateHardwareBanned); + s.setBoolean(1, false); + s.setLong(2, SQLUserHardware.id); + s.executeUpdate(); + } catch (SQLException e) { + logger.error("SQL error", e); + } + } + + @Override + protected AbstractSQLCoreProvider.SQLUserSession createSession(AbstractSQLCoreProvider.SQLUser user) { + return new SQLUserSession(user); + } + + public class SQLUserSession extends AbstractSQLCoreProvider.SQLUserSession implements UserSessionSupportHardware { + private transient SQLUser SQLUser; + protected transient SQLUserHardware hardware; + + public SQLUserSession(AbstractSQLCoreProvider.SQLUser user) { + super(user); + SQLUser = (SQLUser) user; + } + + @Override + public String getHardwareId() { + return SQLUser.hwidId == 0 ? null : String.valueOf(SQLUser.hwidId); + } + + @Override + public UserHardware getHardware() { + if(hardware == null) { + hardware = (SQLUserHardware) getHardwareInfoById(String.valueOf(SQLUser.hwidId)); + } + return hardware; + } + } + + public static class SQLUserHardware implements UserHardware { + private final HardwareReportRequest.HardwareInfo hardwareInfo; + private final long id; + private byte[] publicKey; + private boolean banned; + + public SQLUserHardware(HardwareReportRequest.HardwareInfo hardwareInfo, byte[] publicKey, long id, boolean banned) { + this.hardwareInfo = hardwareInfo; + this.publicKey = publicKey; + this.id = id; + this.banned = banned; + } + + @Override + public HardwareReportRequest.HardwareInfo getHardwareInfo() { + return hardwareInfo; + } + + @Override + public byte[] getPublicKey() { + return publicKey; + } + + @Override + public String getId() { + return String.valueOf(id); + } + + @Override + public boolean isBanned() { + return banned; + } + + @Override + public String toString() { + return "SQLUserHardware{" + + "hardwareInfo=" + hardwareInfo + + ", publicKey=" + (publicKey == null ? null : new String(Base64.getEncoder().encode(publicKey))) + + ", id=" + id + + ", banned=" + banned + + '}'; + } + } + + public static class SQLUser extends AbstractSQLCoreProvider.SQLUser { + protected long hwidId; + + public SQLUser(UUID uuid, String username, String accessToken, String serverId, String password, long hwidId) { + super(uuid, username, accessToken, serverId, password); + this.hwidId = hwidId; + } + + @Override + public String toString() { + return "SQLUser{" + + "uuid=" + uuid + + ", username='" + username + '\'' + + ", permissions=" + permissions + + ", hwidId=" + hwidId + + '}'; + } + } } From c7f4d8ac49a94b633ed4e53c3cab3fcc8112c3ad Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sat, 28 Sep 2024 02:27:42 +0700 Subject: [PATCH 4/6] [FEATURE] Support initializeAtStart --- .../launchserver/auth/HikariSQLSourceConfig.java | 14 +++++++++++++- .../launchserver/auth/core/MySQLCoreProvider.java | 1 + .../auth/core/PostgresSQLCoreProvider.java | 8 ++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/HikariSQLSourceConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/HikariSQLSourceConfig.java index 974ce17e..54e2f69f 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/HikariSQLSourceConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/HikariSQLSourceConfig.java @@ -9,18 +9,25 @@ import java.util.function.Consumer; public class HikariSQLSourceConfig implements SQLSourceConfig { - private transient HikariDataSource dataSource; + private transient volatile HikariDataSource dataSource; private String dsClass; private Properties dsProps; private String driverClass; private String jdbcUrl; private String username; private String password; + private boolean initializeAtStart; public void init() { if (dataSource != null) { return; } + if(initializeAtStart) { + initializeConnection(); + } + } + + private void initializeConnection() { HikariConfig config = new HikariConfig(); consumeIfNotNull(config::setDataSourceClassName, dsClass); consumeIfNotNull(config::setDataSourceProperties, dsProps); @@ -34,6 +41,11 @@ public void init() { @Override public Connection getConnection() throws SQLException { + if(dataSource == null && !initializeAtStart) { + synchronized (this) { + initializeConnection(); + } + } return dataSource.getConnection(); } diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MySQLCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MySQLCoreProvider.java index af1045ca..85dbd336 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MySQLCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/MySQLCoreProvider.java @@ -44,6 +44,7 @@ public SQLSourceConfig getSQLConfig() { @Override public void init(LaunchServer server, AuthProviderPair pair) { super.init(server, pair); + logger.warn("Method 'mysql' deprecated and may be removed in future release. Please use new 'sql' method: https://gravitlauncher.com/auth"); String userInfoCols = makeUserCols(); String hardwareInfoCols = "id, hwDiskId, baseboardSerialNumber, displayId, bitness, totalMemory, logicalProcessors, physicalProcessors, processorMaxFreq, battery, id, graphicCard, banned, publicKey"; if (sqlFindHardwareByPublicKey == null) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/PostgresSQLCoreProvider.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/PostgresSQLCoreProvider.java index 98e36940..9b6122f8 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/PostgresSQLCoreProvider.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/core/PostgresSQLCoreProvider.java @@ -1,5 +1,7 @@ package pro.gravit.launchserver.auth.core; +import pro.gravit.launchserver.LaunchServer; +import pro.gravit.launchserver.auth.AuthProviderPair; import pro.gravit.launchserver.auth.PostgreSQLSourceConfig; import pro.gravit.launchserver.auth.SQLSourceConfig; @@ -10,4 +12,10 @@ public class PostgresSQLCoreProvider extends AbstractSQLCoreProvider { public SQLSourceConfig getSQLConfig() { return postgresSQLHolder; } + + @Override + public void init(LaunchServer server, AuthProviderPair pair) { + super.init(server, pair); + logger.warn("Method 'postgresql' deprecated and may be removed in future release. Please use new 'sql' method: https://gravitlauncher.com/auth"); + } } From cc2bce4300e2c2bac2781406bb271cf11ef188af Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sat, 28 Sep 2024 02:29:19 +0700 Subject: [PATCH 5/6] [FIX] initializeAtStart thread safety --- .../pro/gravit/launchserver/auth/HikariSQLSourceConfig.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/HikariSQLSourceConfig.java b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/HikariSQLSourceConfig.java index 54e2f69f..ba4924dc 100644 --- a/LaunchServer/src/main/java/pro/gravit/launchserver/auth/HikariSQLSourceConfig.java +++ b/LaunchServer/src/main/java/pro/gravit/launchserver/auth/HikariSQLSourceConfig.java @@ -19,15 +19,15 @@ public class HikariSQLSourceConfig implements SQLSourceConfig { private boolean initializeAtStart; public void init() { - if (dataSource != null) { - return; - } if(initializeAtStart) { initializeConnection(); } } private void initializeConnection() { + if (dataSource != null) { + return; + } HikariConfig config = new HikariConfig(); consumeIfNotNull(config::setDataSourceClassName, dsClass); consumeIfNotNull(config::setDataSourceProperties, dsProps); From 070a5d9b69d81f4220aff30cbc9e686bf31e7bc0 Mon Sep 17 00:00:00 2001 From: Gravita <12893402+gravit0@users.noreply.github.com> Date: Sat, 28 Sep 2024 20:31:10 +0700 Subject: [PATCH 6/6] [ANY] 5.6.7 release --- LauncherCore/src/main/java/pro/gravit/utils/Version.java | 2 +- build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LauncherCore/src/main/java/pro/gravit/utils/Version.java b/LauncherCore/src/main/java/pro/gravit/utils/Version.java index aac03549..fbbeee4c 100644 --- a/LauncherCore/src/main/java/pro/gravit/utils/Version.java +++ b/LauncherCore/src/main/java/pro/gravit/utils/Version.java @@ -6,7 +6,7 @@ public final class Version implements Comparable { public static final int MAJOR = 5; public static final int MINOR = 6; - public static final int PATCH = 6; + public static final int PATCH = 7; public static final int BUILD = 1; public static final Version.Type RELEASE = Type.STABLE; public final int major; diff --git a/build.gradle b/build.gradle index 4f30a8a7..0d8b8a34 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ id 'org.openjfx.javafxplugin' version '0.1.0' apply false } group = 'pro.gravit.launcher' -version = '5.6.6' +version = '5.6.7' apply from: 'props.gradle'