From 2873d0d031ecf0579067f2dc22dd41a9f1a419c4 Mon Sep 17 00:00:00 2001 From: P0nk Date: Fri, 2 Apr 2021 13:52:44 +0200 Subject: [PATCH 1/9] Update database credentials --- config.yaml | 4 ++-- tools/MapleArrowFetcher/src/tools/DatabaseConnection.java | 4 ++-- .../src/tools/DatabaseConnection.java | 4 ++-- .../src/maplecashdropfetcher/MapleCashDropFetcher.java | 4 ++-- tools/MapleCashDropFetcher/src/tools/DatabaseConnection.java | 4 ++-- .../maplecodecoupongenerator/MapleCodeCouponGenerator.java | 4 ++-- .../src/maplecouponinstaller/MapleCouponInstaller.java | 4 ++-- .../MapleGachaponItemidRetriever.java | 4 ++-- .../src/mapleidretriever/MapleIdRetriever.java | 4 ++-- .../src/maplenoitemidfetcher/MapleNoItemIdFetcher.java | 4 ++-- .../src/tools/DatabaseConnection.java | 4 ++-- tools/MapleMesoFetcher/src/tools/DatabaseConnection.java | 4 ++-- .../src/maplemobbookindexer/MapleMobBookIndexer.java | 4 ++-- .../src/maplemobbookupdate/MapleMobBookUpdate.java | 4 ++-- .../src/maplequestitemfetcher/MapleQuestItemFetcher.java | 4 ++-- tools/MapleQuestItemFetcher/src/tools/DatabaseConnection.java | 4 ++-- .../src/maplereactordropfetcher/MapleReactorDropFetcher.java | 4 ++-- .../src/mapleskillmakerfetcher/MapleSkillMakerFetcher.java | 4 ++-- .../MapleSkillMakerReagentIndexer.java | 4 ++-- .../src/tools/DatabaseConnection.java | 4 ++-- 20 files changed, 40 insertions(+), 40 deletions(-) diff --git a/config.yaml b/config.yaml index 2fa1000331..4bc57105bd 100644 --- a/config.yaml +++ b/config.yaml @@ -163,8 +163,8 @@ server: #Database Configuration DB_URL: "jdbc:mysql://localhost:3306/cosmic" - DB_USER: "snail" - DB_PASS: "shell" + DB_USER: "cosmic_server" + DB_PASS: "snailshell" DB_CONNECTION_POOL: true #Installs a connection pool to hub DB connections. Set false to default. #Login Configuration diff --git a/tools/MapleArrowFetcher/src/tools/DatabaseConnection.java b/tools/MapleArrowFetcher/src/tools/DatabaseConnection.java index 0b882cb279..b887280343 100644 --- a/tools/MapleArrowFetcher/src/tools/DatabaseConnection.java +++ b/tools/MapleArrowFetcher/src/tools/DatabaseConnection.java @@ -10,8 +10,8 @@ import java.sql.SQLException; */ public class DatabaseConnection { private static String DB_URL = "jdbc:mysql://localhost:3306/cosmic"; - private static String DB_USER = "snail"; - private static String DB_PASS = "shell"; + private static String DB_USER = "cosmic_server"; + private static String DB_PASS = "snailshell"; public static final int RETURN_GENERATED_KEYS = 1; diff --git a/tools/MapleCashCosmeticsFetcher/src/tools/DatabaseConnection.java b/tools/MapleCashCosmeticsFetcher/src/tools/DatabaseConnection.java index 0b882cb279..b887280343 100644 --- a/tools/MapleCashCosmeticsFetcher/src/tools/DatabaseConnection.java +++ b/tools/MapleCashCosmeticsFetcher/src/tools/DatabaseConnection.java @@ -10,8 +10,8 @@ import java.sql.SQLException; */ public class DatabaseConnection { private static String DB_URL = "jdbc:mysql://localhost:3306/cosmic"; - private static String DB_USER = "snail"; - private static String DB_PASS = "shell"; + private static String DB_USER = "cosmic_server"; + private static String DB_PASS = "snailshell"; public static final int RETURN_GENERATED_KEYS = 1; diff --git a/tools/MapleCashDropFetcher/src/maplecashdropfetcher/MapleCashDropFetcher.java b/tools/MapleCashDropFetcher/src/maplecashdropfetcher/MapleCashDropFetcher.java index dadddcdc29..cc610c9fcd 100644 --- a/tools/MapleCashDropFetcher/src/maplecashdropfetcher/MapleCashDropFetcher.java +++ b/tools/MapleCashDropFetcher/src/maplecashdropfetcher/MapleCashDropFetcher.java @@ -50,8 +50,8 @@ import tools.Pair; public class MapleCashDropFetcher { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static String wzPath = "../../wz"; diff --git a/tools/MapleCashDropFetcher/src/tools/DatabaseConnection.java b/tools/MapleCashDropFetcher/src/tools/DatabaseConnection.java index 0b882cb279..b887280343 100644 --- a/tools/MapleCashDropFetcher/src/tools/DatabaseConnection.java +++ b/tools/MapleCashDropFetcher/src/tools/DatabaseConnection.java @@ -10,8 +10,8 @@ import java.sql.SQLException; */ public class DatabaseConnection { private static String DB_URL = "jdbc:mysql://localhost:3306/cosmic"; - private static String DB_USER = "snail"; - private static String DB_PASS = "shell"; + private static String DB_USER = "cosmic_server"; + private static String DB_PASS = "snailshell"; public static final int RETURN_GENERATED_KEYS = 1; diff --git a/tools/MapleCodeCouponGenerator/src/maplecodecoupongenerator/MapleCodeCouponGenerator.java b/tools/MapleCodeCouponGenerator/src/maplecodecoupongenerator/MapleCodeCouponGenerator.java index ac3a25d7cb..45e2abab35 100644 --- a/tools/MapleCodeCouponGenerator/src/maplecodecoupongenerator/MapleCodeCouponGenerator.java +++ b/tools/MapleCodeCouponGenerator/src/maplecodecoupongenerator/MapleCodeCouponGenerator.java @@ -47,8 +47,8 @@ import java.sql.Statement; public class MapleCodeCouponGenerator { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static Connection con = null; static InputStreamReader fileReader = null; diff --git a/tools/MapleCouponInstaller/src/maplecouponinstaller/MapleCouponInstaller.java b/tools/MapleCouponInstaller/src/maplecouponinstaller/MapleCouponInstaller.java index 81c466170f..659a48550b 100644 --- a/tools/MapleCouponInstaller/src/maplecouponinstaller/MapleCouponInstaller.java +++ b/tools/MapleCouponInstaller/src/maplecouponinstaller/MapleCouponInstaller.java @@ -37,8 +37,8 @@ import java.sql.SQLException; public class MapleCouponInstaller { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static Connection con = null; static InputStreamReader fileReader = null; diff --git a/tools/MapleGachaponItemidRetriever/src/maplegachaponitemidretriever/MapleGachaponItemidRetriever.java b/tools/MapleGachaponItemidRetriever/src/maplegachaponitemidretriever/MapleGachaponItemidRetriever.java index 76438d274a..b490a31156 100644 --- a/tools/MapleGachaponItemidRetriever/src/maplegachaponitemidretriever/MapleGachaponItemidRetriever.java +++ b/tools/MapleGachaponItemidRetriever/src/maplegachaponitemidretriever/MapleGachaponItemidRetriever.java @@ -57,8 +57,8 @@ public class MapleGachaponItemidRetriever { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static Connection con = null; static InputStreamReader fileReader = null; diff --git a/tools/MapleIdRetriever/src/mapleidretriever/MapleIdRetriever.java b/tools/MapleIdRetriever/src/mapleidretriever/MapleIdRetriever.java index d9a7b66837..7ac88eb733 100644 --- a/tools/MapleIdRetriever/src/mapleidretriever/MapleIdRetriever.java +++ b/tools/MapleIdRetriever/src/mapleidretriever/MapleIdRetriever.java @@ -50,8 +50,8 @@ public class MapleIdRetriever { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static Connection con = null; static InputStreamReader fileReader = null; diff --git a/tools/MapleInvalidItemIdFetcher/src/maplenoitemidfetcher/MapleNoItemIdFetcher.java b/tools/MapleInvalidItemIdFetcher/src/maplenoitemidfetcher/MapleNoItemIdFetcher.java index 985d9d7d79..1647758035 100644 --- a/tools/MapleInvalidItemIdFetcher/src/maplenoitemidfetcher/MapleNoItemIdFetcher.java +++ b/tools/MapleInvalidItemIdFetcher/src/maplenoitemidfetcher/MapleNoItemIdFetcher.java @@ -50,8 +50,8 @@ import java.util.Set; public class MapleNoItemIdFetcher { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static String wzPath = "../../wz"; static String newFile = "lib/result.txt"; diff --git a/tools/MapleInvalidItemWithNoNameFetcher/src/tools/DatabaseConnection.java b/tools/MapleInvalidItemWithNoNameFetcher/src/tools/DatabaseConnection.java index 0b882cb279..b887280343 100644 --- a/tools/MapleInvalidItemWithNoNameFetcher/src/tools/DatabaseConnection.java +++ b/tools/MapleInvalidItemWithNoNameFetcher/src/tools/DatabaseConnection.java @@ -10,8 +10,8 @@ import java.sql.SQLException; */ public class DatabaseConnection { private static String DB_URL = "jdbc:mysql://localhost:3306/cosmic"; - private static String DB_USER = "snail"; - private static String DB_PASS = "shell"; + private static String DB_USER = "cosmic_server"; + private static String DB_PASS = "snailshell"; public static final int RETURN_GENERATED_KEYS = 1; diff --git a/tools/MapleMesoFetcher/src/tools/DatabaseConnection.java b/tools/MapleMesoFetcher/src/tools/DatabaseConnection.java index 0b882cb279..b887280343 100644 --- a/tools/MapleMesoFetcher/src/tools/DatabaseConnection.java +++ b/tools/MapleMesoFetcher/src/tools/DatabaseConnection.java @@ -10,8 +10,8 @@ import java.sql.SQLException; */ public class DatabaseConnection { private static String DB_URL = "jdbc:mysql://localhost:3306/cosmic"; - private static String DB_USER = "snail"; - private static String DB_PASS = "shell"; + private static String DB_USER = "cosmic_server"; + private static String DB_PASS = "snailshell"; public static final int RETURN_GENERATED_KEYS = 1; diff --git a/tools/MapleMobBookIndexer/src/maplemobbookindexer/MapleMobBookIndexer.java b/tools/MapleMobBookIndexer/src/maplemobbookindexer/MapleMobBookIndexer.java index 87a5a28288..ded162c95c 100644 --- a/tools/MapleMobBookIndexer/src/maplemobbookindexer/MapleMobBookIndexer.java +++ b/tools/MapleMobBookIndexer/src/maplemobbookindexer/MapleMobBookIndexer.java @@ -38,8 +38,8 @@ import java.io.*; public class MapleMobBookIndexer { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static String fileName = "lib/MonsterBook.img.xml"; diff --git a/tools/MapleMobBookUpdate/src/maplemobbookupdate/MapleMobBookUpdate.java b/tools/MapleMobBookUpdate/src/maplemobbookupdate/MapleMobBookUpdate.java index 83db149e45..158ce16788 100644 --- a/tools/MapleMobBookUpdate/src/maplemobbookupdate/MapleMobBookUpdate.java +++ b/tools/MapleMobBookUpdate/src/maplemobbookupdate/MapleMobBookUpdate.java @@ -48,8 +48,8 @@ import java.io.*; public class MapleMobBookUpdate { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static String fileName = "lib/MonsterBook.img.xml"; static String newFile = "lib/MonsterBook_updated.img.xml"; diff --git a/tools/MapleQuestItemFetcher/src/maplequestitemfetcher/MapleQuestItemFetcher.java b/tools/MapleQuestItemFetcher/src/maplequestitemfetcher/MapleQuestItemFetcher.java index 5cb97996f0..53c6fd5120 100644 --- a/tools/MapleQuestItemFetcher/src/maplequestitemfetcher/MapleQuestItemFetcher.java +++ b/tools/MapleQuestItemFetcher/src/maplequestitemfetcher/MapleQuestItemFetcher.java @@ -67,8 +67,8 @@ public class MapleQuestItemFetcher { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static String wzPath = "../../wz"; static String directoryName = "../.."; diff --git a/tools/MapleQuestItemFetcher/src/tools/DatabaseConnection.java b/tools/MapleQuestItemFetcher/src/tools/DatabaseConnection.java index 0b882cb279..b887280343 100644 --- a/tools/MapleQuestItemFetcher/src/tools/DatabaseConnection.java +++ b/tools/MapleQuestItemFetcher/src/tools/DatabaseConnection.java @@ -10,8 +10,8 @@ import java.sql.SQLException; */ public class DatabaseConnection { private static String DB_URL = "jdbc:mysql://localhost:3306/cosmic"; - private static String DB_USER = "snail"; - private static String DB_PASS = "shell"; + private static String DB_USER = "cosmic_server"; + private static String DB_PASS = "snailshell"; public static final int RETURN_GENERATED_KEYS = 1; diff --git a/tools/MapleReactorDropFetcher/src/maplereactordropfetcher/MapleReactorDropFetcher.java b/tools/MapleReactorDropFetcher/src/maplereactordropfetcher/MapleReactorDropFetcher.java index 880c83c037..c0ab9703f4 100644 --- a/tools/MapleReactorDropFetcher/src/maplereactordropfetcher/MapleReactorDropFetcher.java +++ b/tools/MapleReactorDropFetcher/src/maplereactordropfetcher/MapleReactorDropFetcher.java @@ -46,8 +46,8 @@ import java.io.File; public class MapleReactorDropFetcher { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static String reactorScriptPath = "../../scripts/reactor"; diff --git a/tools/MapleSkillMakerFetcher/src/mapleskillmakerfetcher/MapleSkillMakerFetcher.java b/tools/MapleSkillMakerFetcher/src/mapleskillmakerfetcher/MapleSkillMakerFetcher.java index 75b3f70e36..a2dc506673 100644 --- a/tools/MapleSkillMakerFetcher/src/mapleskillmakerfetcher/MapleSkillMakerFetcher.java +++ b/tools/MapleSkillMakerFetcher/src/mapleskillmakerfetcher/MapleSkillMakerFetcher.java @@ -38,8 +38,8 @@ import java.io.*; public class MapleSkillMakerFetcher { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static String fileName = "../../wz/Etc.wz/ItemMake.img.xml"; static String newFile = "lib/MakerData.sql"; diff --git a/tools/MapleSkillMakerReagentIndexer/src/mapleskillmakerreagentindexer/MapleSkillMakerReagentIndexer.java b/tools/MapleSkillMakerReagentIndexer/src/mapleskillmakerreagentindexer/MapleSkillMakerReagentIndexer.java index 8cbffaff2a..c4f012fcab 100644 --- a/tools/MapleSkillMakerReagentIndexer/src/mapleskillmakerreagentindexer/MapleSkillMakerReagentIndexer.java +++ b/tools/MapleSkillMakerReagentIndexer/src/mapleskillmakerreagentindexer/MapleSkillMakerReagentIndexer.java @@ -42,8 +42,8 @@ import java.util.List; public class MapleSkillMakerReagentIndexer { static String host = "jdbc:mysql://localhost:3306/cosmic"; static String driver = "com.mysql.jdbc.Driver"; - static String username = "snail"; - static String password = "shell"; + static String username = "cosmic_server"; + static String password = "snailshell"; static String fileName = "../../wz/Item.wz/Etc/0425.img.xml"; static String newFile = "lib/MakerReagentData.sql"; diff --git a/tools/MapleSkillbookChanceFetcher/src/tools/DatabaseConnection.java b/tools/MapleSkillbookChanceFetcher/src/tools/DatabaseConnection.java index 0b882cb279..b887280343 100644 --- a/tools/MapleSkillbookChanceFetcher/src/tools/DatabaseConnection.java +++ b/tools/MapleSkillbookChanceFetcher/src/tools/DatabaseConnection.java @@ -10,8 +10,8 @@ import java.sql.SQLException; */ public class DatabaseConnection { private static String DB_URL = "jdbc:mysql://localhost:3306/cosmic"; - private static String DB_USER = "snail"; - private static String DB_PASS = "shell"; + private static String DB_USER = "cosmic_server"; + private static String DB_PASS = "snailshell"; public static final int RETURN_GENERATED_KEYS = 1; From 05bd668cc293db335f993355cb9545c32d1396ff Mon Sep 17 00:00:00 2001 From: P0nk Date: Fri, 2 Apr 2021 14:08:41 +0200 Subject: [PATCH 2/9] Upgrade to MySQL 8 Workaround for exception thrown by ResultSet#beforeFirst(): "Operation not allowed for a result set of type ResultSet.TYPE_FORWARD_ONLY" --- pom.xml | 2 +- src/main/java/net/server/Server.java | 4 +++- src/main/java/server/maps/MapleHiredMerchant.java | 7 +++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 81c5f754bc..7341ff2b53 100644 --- a/pom.xml +++ b/pom.xml @@ -31,7 +31,7 @@ mysql mysql-connector-java - 5.1.6 + 8.0.23 org.slf4j diff --git a/src/main/java/net/server/Server.java b/src/main/java/net/server/Server.java index f85be22624..2673df652d 100644 --- a/src/main/java/net/server/Server.java +++ b/src/main/java/net/server/Server.java @@ -1620,7 +1620,9 @@ public class Server { private static void applyAllWorldTransfers() { try (Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("SELECT * FROM worldtransfers WHERE completionTime IS NULL")) { + PreparedStatement ps = con.prepareStatement("SELECT * FROM worldtransfers WHERE completionTime IS NULL", + ResultSet.TYPE_SCROLL_SENSITIVE, + ResultSet.CONCUR_READ_ONLY)) { ResultSet rs = ps.executeQuery(); List removedTransfers = new LinkedList(); while(rs.next()) { diff --git a/src/main/java/server/maps/MapleHiredMerchant.java b/src/main/java/server/maps/MapleHiredMerchant.java index 261238e411..c87619d310 100644 --- a/src/main/java/server/maps/MapleHiredMerchant.java +++ b/src/main/java/server/maps/MapleHiredMerchant.java @@ -30,7 +30,6 @@ import client.inventory.MapleInventoryType; import client.inventory.manipulator.MapleInventoryManipulator; import client.inventory.manipulator.MapleKarmaManipulator; import client.processor.npc.FredrickProcessor; -import com.mysql.jdbc.Statement; import config.YamlConfig; import java.sql.Connection; import java.sql.PreparedStatement; @@ -309,7 +308,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject { } merchantMesos += price; - try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET MerchantMesos = ? WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) { + try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET MerchantMesos = ? WHERE id = ?", PreparedStatement.RETURN_GENERATED_KEYS)) { ps.setInt(1, (int) Math.min(merchantMesos, Integer.MAX_VALUE)); ps.setInt(2, ownerId); ps.executeUpdate(); @@ -383,7 +382,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject { } else { try { Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("UPDATE characters SET HasMerchant = 0 WHERE id = ?", Statement.RETURN_GENERATED_KEYS); + PreparedStatement ps = con.prepareStatement("UPDATE characters SET HasMerchant = 0 WHERE id = ?", PreparedStatement.RETURN_GENERATED_KEYS); ps.setInt(1, ownerId); ps.executeUpdate(); @@ -442,7 +441,7 @@ public class MapleHiredMerchant extends AbstractMapleMapObject { player.setHasMerchant(false); } else { Connection con = DatabaseConnection.getConnection(); - try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET HasMerchant = 0 WHERE id = ?", Statement.RETURN_GENERATED_KEYS)) { + try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET HasMerchant = 0 WHERE id = ?", PreparedStatement.RETURN_GENERATED_KEYS)) { ps.setInt(1, ownerId); ps.executeUpdate(); } From 45331d17b05a9d21690cd248f4977496cfce28cc Mon Sep 17 00:00:00 2001 From: P0nk Date: Fri, 2 Apr 2021 14:20:45 +0200 Subject: [PATCH 3/9] Set up connection pool and enforce usage of it Attempt to initialize connection pool on startup until a timeout. --- config.yaml | 1 - src/main/java/config/ServerConfig.java | 1 - src/main/java/net/server/Server.java | 7 +- src/main/java/tools/DatabaseConnection.java | 130 ++++++++------------ 4 files changed, 59 insertions(+), 80 deletions(-) diff --git a/config.yaml b/config.yaml index 4bc57105bd..e23faaa268 100644 --- a/config.yaml +++ b/config.yaml @@ -165,7 +165,6 @@ server: DB_URL: "jdbc:mysql://localhost:3306/cosmic" DB_USER: "cosmic_server" DB_PASS: "snailshell" - DB_CONNECTION_POOL: true #Installs a connection pool to hub DB connections. Set false to default. #Login Configuration WORLDS: 1 #Initial number of worlds on the server. diff --git a/src/main/java/config/ServerConfig.java b/src/main/java/config/ServerConfig.java index fbef750367..2feeec8b4d 100644 --- a/src/main/java/config/ServerConfig.java +++ b/src/main/java/config/ServerConfig.java @@ -8,7 +8,6 @@ public class ServerConfig { public String DB_URL; public String DB_USER; public String DB_PASS; - public boolean DB_CONNECTION_POOL; //Login Configuration public int WORLDS; diff --git a/src/main/java/net/server/Server.java b/src/main/java/net/server/Server.java index 2673df652d..ea99fd3c1f 100644 --- a/src/main/java/net/server/Server.java +++ b/src/main/java/net/server/Server.java @@ -866,8 +866,13 @@ public class Server { public void init() { System.out.println("Cosmic v" + ServerConstants.VERSION + " starting up.\r\n"); - if(YamlConfig.config.server.SHUTDOWNHOOK) + if(YamlConfig.config.server.SHUTDOWNHOOK) { Runtime.getRuntime().addShutdownHook(new Thread(shutdown(false))); + } + + if (!DatabaseConnection.initializeConnectionPool()) { + throw new IllegalStateException("Failed to initiate a connection to the database"); + } TimeZone.setDefault(TimeZone.getTimeZone(YamlConfig.config.server.TIMEZONE)); diff --git a/src/main/java/tools/DatabaseConnection.java b/src/main/java/tools/DatabaseConnection.java index e408be455f..821b30bb1b 100644 --- a/src/main/java/tools/DatabaseConnection.java +++ b/src/main/java/tools/DatabaseConnection.java @@ -1,10 +1,10 @@ package tools; import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; import java.sql.DriverManager; import java.sql.SQLException; +import java.time.Instant; + import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; @@ -16,82 +16,58 @@ import config.YamlConfig; * @author Ronan - some connection pool to this beautiful code */ public class DatabaseConnection { - private static HikariDataSource ds; - - public static Connection getConnection() throws SQLException { - if(ds != null) { - try { - return ds.getConnection(); - } catch (SQLException sqle) { - sqle.printStackTrace(); - } - } - - int denies = 0; - while(true) { // There is no way it can pass with a null out of here? - try { - return DriverManager.getConnection(YamlConfig.config.server.DB_URL, YamlConfig.config.server.DB_USER, YamlConfig.config.server.DB_PASS); - } catch (SQLException sqle) { - denies++; - - if(denies == 3) { - // Give up, throw exception. Nothing good will come from this. - FilePrinter.printError(FilePrinter.SQL_EXCEPTION, "SQL Driver refused to give a connection after " + denies + " tries. Problem: " + sqle.getMessage()); - throw sqle; - } - } - } - } - - private static int getNumberOfAccounts() { - try { - Connection con = DriverManager.getConnection(YamlConfig.config.server.DB_URL, YamlConfig.config.server.DB_USER, YamlConfig.config.server.DB_PASS); - try (PreparedStatement ps = con.prepareStatement("SELECT count(*) FROM accounts")) { - try (ResultSet rs = ps.executeQuery()) { - rs.next(); - return rs.getInt(1); - } - } finally { - con.close(); - } - } catch(SQLException sqle) { - return 20; - } - } - - public DatabaseConnection() { - try { - Class.forName("com.mysql.jdbc.Driver"); // touch the mysql driver - } catch (ClassNotFoundException e) { - System.out.println("[SEVERE] SQL Driver Not Found. Consider death by clams."); - e.printStackTrace(); - } - - ds = null; - - if(YamlConfig.config.server.DB_CONNECTION_POOL) { - // Connection Pool on database ftw! - - HikariConfig config = new HikariConfig(); - config.setJdbcUrl(YamlConfig.config.server.DB_URL); - - config.setUsername(YamlConfig.config.server.DB_USER); - config.setPassword(YamlConfig.config.server.DB_PASS); - - // Make sure pool size is comfortable for the worst case scenario. - // Under 100 accounts? Make it 10. Over 10000 accounts? Make it 30. - int poolSize = (int)Math.ceil(0.00202020202 * getNumberOfAccounts() + 9.797979798); - if(poolSize < 10) poolSize = 10; - else if(poolSize > 30) poolSize = 30; - - config.setConnectionTimeout(30 * 1000); - config.setMaximumPoolSize(poolSize); - - config.addDataSourceProperty("cachePrepStmts", true); - config.addDataSourceProperty("prepStmtCacheSize", 25); - config.addDataSourceProperty("prepStmtCacheSqlLimit", 2048); + private static HikariDataSource dataSource; - ds = new HikariDataSource(config); + public static Connection getConnection() throws SQLException { + if (dataSource == null) { + throw new IllegalStateException("Unable to get connection from uninitialized connection pool"); } + + return dataSource.getConnection(); + } + + private static HikariConfig getConfig() { + HikariConfig config = new HikariConfig(); + + config.setJdbcUrl(YamlConfig.config.server.DB_URL); + config.setUsername(YamlConfig.config.server.DB_USER); + config.setPassword(YamlConfig.config.server.DB_PASS); + + config.setConnectionTimeout(30 * 1000); // Hikari default + config.setMaximumPoolSize(10); // Hikari default + + config.addDataSourceProperty("cachePrepStmts", true); + config.addDataSourceProperty("prepStmtCacheSize", 25); + config.addDataSourceProperty("prepStmtCacheSqlLimit", 2048); + + return config; + } + + /** + * Initiate connection to the database + * + * @return true if connection to the database initiated successfully, false if not successful + */ + public static boolean initializeConnectionPool() { + final int timeoutSeconds = 60; + final Instant timeout = Instant.now().plusSeconds(timeoutSeconds); + + System.out.println("Initializing connection pool..."); + final HikariConfig config = getConfig(); + HikariDataSource hikariDataSource; + int attempt = 1; + while (Instant.now().isBefore(timeout)) { + try { + hikariDataSource = new HikariDataSource(config); + } catch (Exception e) { + System.err.printf("Failed to initialize database connection pool after %d attempt(s)%n", attempt++); + continue; + } + dataSource = hikariDataSource; + return true; + } + + // Timed out - failed to initialize + return false; } } From 7169a74e945e0bdb9bb72045a1c57893a2549e0b Mon Sep 17 00:00:00 2001 From: P0nk Date: Fri, 2 Apr 2021 15:14:55 +0200 Subject: [PATCH 4/9] Make connection pool init timeout configurable --- config.yaml | 1 + src/main/java/config/ServerConfig.java | 1 + src/main/java/tools/DatabaseConnection.java | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config.yaml b/config.yaml index e23faaa268..b53999d5b0 100644 --- a/config.yaml +++ b/config.yaml @@ -165,6 +165,7 @@ server: DB_URL: "jdbc:mysql://localhost:3306/cosmic" DB_USER: "cosmic_server" DB_PASS: "snailshell" + INIT_CONNECTION_POOL_TIMEOUT: 60 # Seconds #Login Configuration WORLDS: 1 #Initial number of worlds on the server. diff --git a/src/main/java/config/ServerConfig.java b/src/main/java/config/ServerConfig.java index 2feeec8b4d..df37b3d8b0 100644 --- a/src/main/java/config/ServerConfig.java +++ b/src/main/java/config/ServerConfig.java @@ -8,6 +8,7 @@ public class ServerConfig { public String DB_URL; public String DB_USER; public String DB_PASS; + public int INIT_CONNECTION_POOL_TIMEOUT; //Login Configuration public int WORLDS; diff --git a/src/main/java/tools/DatabaseConnection.java b/src/main/java/tools/DatabaseConnection.java index 821b30bb1b..0e6df919a1 100644 --- a/src/main/java/tools/DatabaseConnection.java +++ b/src/main/java/tools/DatabaseConnection.java @@ -49,7 +49,7 @@ public class DatabaseConnection { * @return true if connection to the database initiated successfully, false if not successful */ public static boolean initializeConnectionPool() { - final int timeoutSeconds = 60; + final int timeoutSeconds = YamlConfig.config.server.INIT_CONNECTION_POOL_TIMEOUT; final Instant timeout = Instant.now().plusSeconds(timeoutSeconds); System.out.println("Initializing connection pool..."); From 754ab67de7991e983dcc207979ce9f59139e6322 Mon Sep 17 00:00:00 2001 From: P0nk Date: Fri, 2 Apr 2021 16:11:41 +0200 Subject: [PATCH 5/9] Change default birthday and tempban to fix conversion issue ResultSet#getLong on a timestamp field is not allowed --- sql/db_database.sql | 4 ++-- src/main/java/client/DefaultDates.java | 19 +++++++++++++++ src/main/java/client/MapleCharacter.java | 10 ++++++-- src/main/java/client/MapleClient.java | 23 +++++++++---------- .../handlers/login/LoginPasswordHandler.java | 13 +++++------ 5 files changed, 46 insertions(+), 23 deletions(-) create mode 100644 src/main/java/client/DefaultDates.java diff --git a/sql/db_database.sql b/sql/db_database.sql index 1431167768..1d381f546c 100644 --- a/sql/db_database.sql +++ b/sql/db_database.sql @@ -21,7 +21,7 @@ CREATE TABLE IF NOT EXISTS `accounts` ( `loggedin` tinyint(4) NOT NULL DEFAULT '0', `lastlogin` timestamp NULL DEFAULT NULL, `createdat` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, - `birthday` date NOT NULL DEFAULT '0000-00-00', + `birthday` date NOT NULL DEFAULT '2005-05-11', `banned` tinyint(1) NOT NULL DEFAULT '0', `banreason` text, `macs` tinytext, @@ -30,7 +30,7 @@ CREATE TABLE IF NOT EXISTS `accounts` ( `nxPrepaid` int(11) DEFAULT NULL, `characterslots` tinyint(2) NOT NULL DEFAULT '3', `gender` tinyint(2) NOT NULL DEFAULT '10', - `tempban` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', + `tempban` timestamp NOT NULL DEFAULT '2005-05-11 00:00:00', `greason` tinyint(4) NOT NULL DEFAULT '0', `tos` tinyint(1) NOT NULL DEFAULT '0', `sitelogged` text, diff --git a/src/main/java/client/DefaultDates.java b/src/main/java/client/DefaultDates.java new file mode 100644 index 0000000000..68cbb3690d --- /dev/null +++ b/src/main/java/client/DefaultDates.java @@ -0,0 +1,19 @@ +package client; + +import java.time.LocalDate; +import java.time.LocalDateTime; + +final public class DefaultDates { + // May 11 2005 is the date MapleGlobal released, so it's a symbolic default value + + private DefaultDates() { + } + + public static LocalDate getBirthday() { + return LocalDate.parse("2005-05-11"); + } + + public static LocalDateTime getTempban() { + return LocalDateTime.parse("2005-05-11T00:00:00"); + } +} diff --git a/src/main/java/client/MapleCharacter.java b/src/main/java/client/MapleCharacter.java index e26a8ac49a..680eb48bc2 100644 --- a/src/main/java/client/MapleCharacter.java +++ b/src/main/java/client/MapleCharacter.java @@ -30,6 +30,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -11036,8 +11037,13 @@ public class MapleCharacter extends AbstractMapleCharacterObject { try (PreparedStatement ps = con.prepareStatement("SELECT tempban FROM accounts WHERE id = ?")) { ps.setInt(1, accountId); ResultSet rs = ps.executeQuery(); - if(!rs.next()) return "Account does not exist."; - if(rs.getLong("tempban") != 0 && !rs.getString("tempban").equals("2018-06-20 00:00:00.0")) return "Account has been banned."; + if (!rs.next()) { + return "Account does not exist."; + } + LocalDateTime tempban = rs.getTimestamp("tempban").toLocalDateTime(); + if(!tempban.equals(DefaultDates.getTempban())) { + return "Account has been banned."; + } } catch(SQLException e) { e.printStackTrace(); FilePrinter.printError(FilePrinter.CHANGE_CHARACTER_NAME, e); diff --git a/src/main/java/client/MapleClient.java b/src/main/java/client/MapleClient.java index bd8b34e773..8f131fa660 100644 --- a/src/main/java/client/MapleClient.java +++ b/src/main/java/client/MapleClient.java @@ -25,10 +25,8 @@ import java.io.*; import java.net.InetAddress; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; +import java.sql.*; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -647,23 +645,24 @@ public class MapleClient { ResultSet rs = null; final Calendar lTempban = Calendar.getInstance(); try { - con = DatabaseConnection.getConnection(); + con = DatabaseConnection.getConnection(); ps = con.prepareStatement("SELECT `tempban` FROM accounts WHERE id = ?"); ps.setInt(1, getAccID()); rs = ps.executeQuery(); if (!rs.next()) { return null; } - long blubb = rs.getLong("tempban"); - - if (blubb == 0 || rs.getString("tempban").equals("2018-06-20 00:00:00.0")) { // 0000-00-00 or 2018-06-20 (default set in LoginPasswordHandler) + + final Timestamp tempban = rs.getTimestamp("tempban"); + if (tempban.toLocalDateTime().equals(DefaultDates.getTempban())) { return null; } - lTempban.setTimeInMillis(rs.getTimestamp("tempban").getTime()); + + lTempban.setTimeInMillis(tempban.getTime()); tempBanCalendar = lTempban; return lTempban; } catch (SQLException e) { - e.printStackTrace(); + e.printStackTrace(); } finally { try { if (ps != null) { @@ -672,11 +671,11 @@ public class MapleClient { if (rs != null) { rs.close(); } - if (con != null && !con.isClosed()) { + if (con != null && !con.isClosed()) { con.close(); } } catch (SQLException e) { - e.printStackTrace(); + e.printStackTrace(); } } return null;//why oh why!?! diff --git a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java index c5ddfed5c4..3039be8627 100644 --- a/src/main/java/net/server/handlers/login/LoginPasswordHandler.java +++ b/src/main/java/net/server/handlers/login/LoginPasswordHandler.java @@ -21,11 +21,11 @@ */ package net.server.handlers.login; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; +import java.sql.*; +import java.time.LocalDateTime; import java.util.Calendar; +import client.DefaultDates; import config.YamlConfig; import net.MaplePacketHandler; import net.server.Server; @@ -35,8 +35,7 @@ import tools.HexTool; import tools.MaplePacketCreator; import tools.data.input.SeekableLittleEndianAccessor; import client.MapleClient; -import java.sql.ResultSet; -import java.sql.Statement; + import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -100,8 +99,8 @@ public final class LoginPasswordHandler implements MaplePacketHandler { ps = con.prepareStatement("INSERT INTO accounts (name, password, birthday, tempban) VALUES (?, ?, ?, ?);", Statement.RETURN_GENERATED_KEYS); //Jayd: Added birthday, tempban ps.setString(1, login); ps.setString(2, YamlConfig.config.server.BCRYPT_MIGRATION ? BCrypt.hashpw(pwd, BCrypt.gensalt(12)) : hashpwSHA512(pwd)); - ps.setString(3, "2018-06-20"); //Jayd's idea: was added to solve the MySQL 5.7 strict checking (birthday) - ps.setString(4, "2018-06-20"); //Jayd's idea: was added to solve the MySQL 5.7 strict checking (tempban) + ps.setDate(3, Date.valueOf(DefaultDates.getBirthday())); + ps.setTimestamp(4, Timestamp.valueOf(DefaultDates.getTempban())); ps.executeUpdate(); ResultSet rs = ps.getGeneratedKeys(); From 08a0407417bde676fa927d559ada04313585060d Mon Sep 17 00:00:00 2001 From: P0nk Date: Fri, 2 Apr 2021 16:41:44 +0200 Subject: [PATCH 6/9] Explicitly set scrolling mode where ResultSet is used for scrolling --- src/main/java/client/MapleCharacter.java | 3 ++- src/main/java/client/MonsterBook.java | 5 +++-- src/main/java/net/server/Server.java | 3 +-- .../server/channel/handlers/BBSOperationHandler.java | 3 ++- src/main/java/net/server/guild/MapleGuild.java | 11 ++++++----- 5 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/main/java/client/MapleCharacter.java b/src/main/java/client/MapleCharacter.java index 680eb48bc2..479450066d 100644 --- a/src/main/java/client/MapleCharacter.java +++ b/src/main/java/client/MapleCharacter.java @@ -9778,7 +9778,8 @@ public class MapleCharacter extends AbstractMapleCharacterObject { public void showNote() { try { Connection con = DatabaseConnection.getConnection(); - try (PreparedStatement ps = con.prepareStatement("SELECT * FROM notes WHERE `to` = ? AND `deleted` = 0", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)) { + try (PreparedStatement ps = con.prepareStatement("SELECT * FROM notes WHERE `to` = ? AND `deleted` = 0", + ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE)) { ps.setString(1, this.getName()); try (ResultSet rs = ps.executeQuery()) { rs.last(); diff --git a/src/main/java/client/MonsterBook.java b/src/main/java/client/MonsterBook.java index 235362d78f..95f320b298 100644 --- a/src/main/java/client/MonsterBook.java +++ b/src/main/java/client/MonsterBook.java @@ -247,9 +247,10 @@ public final class MonsterBook { public static int[] getCardTierSize() { try { Connection con = DatabaseConnection.getConnection(); - PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) FROM monstercarddata GROUP BY floor(cardid / 1000);"); + PreparedStatement ps = con.prepareStatement("SELECT COUNT(*) FROM monstercarddata GROUP BY floor(cardid / 1000);", + ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY); ResultSet rs = ps.executeQuery(); - + rs.last(); int[] tierSizes = new int[rs.getRow()]; rs.beforeFirst(); diff --git a/src/main/java/net/server/Server.java b/src/main/java/net/server/Server.java index ea99fd3c1f..27b8025f26 100644 --- a/src/main/java/net/server/Server.java +++ b/src/main/java/net/server/Server.java @@ -1626,8 +1626,7 @@ public class Server { private static void applyAllWorldTransfers() { try (Connection con = DatabaseConnection.getConnection(); PreparedStatement ps = con.prepareStatement("SELECT * FROM worldtransfers WHERE completionTime IS NULL", - ResultSet.TYPE_SCROLL_SENSITIVE, - ResultSet.CONCUR_READ_ONLY)) { + ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { ResultSet rs = ps.executeQuery(); List removedTransfers = new LinkedList(); while(rs.next()) { diff --git a/src/main/java/net/server/channel/handlers/BBSOperationHandler.java b/src/main/java/net/server/channel/handlers/BBSOperationHandler.java index 6f97a56e92..be4e545506 100644 --- a/src/main/java/net/server/channel/handlers/BBSOperationHandler.java +++ b/src/main/java/net/server/channel/handlers/BBSOperationHandler.java @@ -98,7 +98,8 @@ public final class BBSOperationHandler extends AbstractMaplePacketHandler { private static void listBBSThreads(MapleClient c, int start) { try { Connection con = DatabaseConnection.getConnection(); - try (PreparedStatement ps = con.prepareStatement("SELECT * FROM bbs_threads WHERE guildid = ? ORDER BY localthreadid DESC")) { + try (PreparedStatement ps = con.prepareStatement("SELECT * FROM bbs_threads WHERE guildid = ? ORDER BY localthreadid DESC", + ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { ps.setInt(1, c.getPlayer().getGuildId()); try (ResultSet rs = ps.executeQuery()) { c.announce(MaplePacketCreator.BBSThreadList(rs, start)); diff --git a/src/main/java/net/server/guild/MapleGuild.java b/src/main/java/net/server/guild/MapleGuild.java index a682cda6d7..73d7edc7e8 100644 --- a/src/main/java/net/server/guild/MapleGuild.java +++ b/src/main/java/net/server/guild/MapleGuild.java @@ -76,7 +76,7 @@ public class MapleGuild { con = DatabaseConnection.getConnection(); PreparedStatement ps = con.prepareStatement("SELECT * FROM guilds WHERE guildid = " + guildid); ResultSet rs = ps.executeQuery(); - if (!rs.first()) { + if (!rs.next()) { id = -1; ps.close(); rs.close(); @@ -102,7 +102,7 @@ public class MapleGuild { ps = con.prepareStatement("SELECT id, name, level, job, guildrank, allianceRank FROM characters WHERE guildid = ? ORDER BY guildrank ASC, name ASC"); ps.setInt(1, guildid); rs = ps.executeQuery(); - if (!rs.first()) { + if (!rs.next()) { rs.close(); ps.close(); return; @@ -436,7 +436,7 @@ public class MapleGuild { PreparedStatement ps = con.prepareStatement("SELECT guildid FROM guilds WHERE name = ?"); ps.setString(1, name); ResultSet rs = ps.executeQuery(); - if (rs.first()) { + if (rs.next()) { ps.close(); rs.close(); return 0; @@ -454,7 +454,7 @@ public class MapleGuild { ps = con.prepareStatement("SELECT guildid FROM guilds WHERE leader = ?"); ps.setInt(1, leaderId); rs = ps.executeQuery(); - rs.first(); + rs.next(); int guildId = rs.getInt("guildid"); rs.close(); ps.close(); @@ -779,7 +779,8 @@ public class MapleGuild { try { ResultSet rs; Connection con = DatabaseConnection.getConnection(); - try (PreparedStatement ps = con.prepareStatement("SELECT `name`, `GP`, `logoBG`, `logoBGColor`, `logo`, `logoColor` FROM guilds ORDER BY `GP` DESC LIMIT 50")) { + try (PreparedStatement ps = con.prepareStatement("SELECT `name`, `GP`, `logoBG`, `logoBGColor`, `logo`, `logoColor` FROM guilds ORDER BY `GP` DESC LIMIT 50", + ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY)) { rs = ps.executeQuery(); c.announce(MaplePacketCreator.showGuildRanks(npcid, rs)); } From 8b7e989fed9fbe7915d525a20c0627e6ba60548f Mon Sep 17 00:00:00 2001 From: P0nk Date: Fri, 2 Apr 2021 20:16:57 +0200 Subject: [PATCH 7/9] Use native way for connection pool init timeout --- src/main/java/tools/DatabaseConnection.java | 26 ++++++++++----------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/main/java/tools/DatabaseConnection.java b/src/main/java/tools/DatabaseConnection.java index 0e6df919a1..3901a3ab65 100644 --- a/src/main/java/tools/DatabaseConnection.java +++ b/src/main/java/tools/DatabaseConnection.java @@ -1,9 +1,10 @@ package tools; import java.sql.Connection; -import java.sql.DriverManager; import java.sql.SQLException; +import java.time.Duration; import java.time.Instant; +import java.util.concurrent.TimeUnit; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; @@ -33,6 +34,8 @@ public class DatabaseConnection { config.setUsername(YamlConfig.config.server.DB_USER); config.setPassword(YamlConfig.config.server.DB_PASS); + final int initFailTimeoutSeconds = YamlConfig.config.server.INIT_CONNECTION_POOL_TIMEOUT; + config.setInitializationFailTimeout(TimeUnit.SECONDS.toMillis(initFailTimeoutSeconds)); config.setConnectionTimeout(30 * 1000); // Hikari default config.setMaximumPoolSize(10); // Hikari default @@ -49,22 +52,17 @@ public class DatabaseConnection { * @return true if connection to the database initiated successfully, false if not successful */ public static boolean initializeConnectionPool() { - final int timeoutSeconds = YamlConfig.config.server.INIT_CONNECTION_POOL_TIMEOUT; - final Instant timeout = Instant.now().plusSeconds(timeoutSeconds); - System.out.println("Initializing connection pool..."); final HikariConfig config = getConfig(); - HikariDataSource hikariDataSource; - int attempt = 1; - while (Instant.now().isBefore(timeout)) { - try { - hikariDataSource = new HikariDataSource(config); - } catch (Exception e) { - System.err.printf("Failed to initialize database connection pool after %d attempt(s)%n", attempt++); - continue; - } - dataSource = hikariDataSource; + Instant initStart = Instant.now(); + try { + dataSource = new HikariDataSource(config); + long initDuration = Duration.between(initStart, Instant.now()).toMillis(); + System.out.printf("Connection pool initialized in %d ms%n", initDuration); return true; + } catch (Exception e) { + long timeout = Duration.between(initStart, Instant.now()).getSeconds(); + System.err.printf("Failed to initialize database connection pool. Gave up after %d seconds.%n", timeout); } // Timed out - failed to initialize From 90687007f5c1f67b04a005c1a730db34217bd338 Mon Sep 17 00:00:00 2001 From: P0nk Date: Sat, 3 Apr 2021 14:59:37 +0200 Subject: [PATCH 8/9] Rework Docker support - Use multi-stage build for the application image - Utilize connection pool init timeout for waiting on database container startup, "docker-compose-wait" dependency is no longer required - Override database host through environment variable - used in docker-compose - Rename database scripts for explicit ordering (db container loads them alphabetically) --- .dockerignore | 3 +++ .gitignore | 1 + Dockerfile | 27 ++++++++++++------- config.yaml | 3 ++- docker-compose.yml | 16 ++++++----- sql/{db_database.sql => 1-db_database.sql} | 0 sql/{db_drops.sql => 2-db_drops.sql} | 0 ...{db_shopupdate.sql => 3-db_shopupdate.sql} | 0 src/main/java/config/ServerConfig.java | 3 ++- src/main/java/tools/DatabaseConnection.java | 11 +++++++- 10 files changed, 44 insertions(+), 20 deletions(-) create mode 100644 .dockerignore rename sql/{db_database.sql => 1-db_database.sql} (100%) rename sql/{db_drops.sql => 2-db_drops.sql} (100%) rename sql/{db_shopupdate.sql => 3-db_shopupdate.sql} (100%) diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000000..3fbb8c079e --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +/docs +/handbook +/tools \ No newline at end of file diff --git a/.gitignore b/.gitignore index 99c411b1fa..d13e4644ed 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .idea/ *.iml /target +/docker-db-data # build files diff --git a/Dockerfile b/Dockerfile index d37cf08b8e..b24fea224d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,20 @@ -# Docker support, thanks to xinyifly +# Initial Docker support thanks to xinyifly -FROM openjdk:8u171-jdk-alpine -RUN apk -U add tini -WORKDIR /mnt +# +# Build stage +# +FROM maven:3.6.3-jdk-8 AS build +COPY src /home/app/src +COPY pom.xml /home/app +RUN mvn -f /home/app/pom.xml clean package + +# +# Package stage +# +FROM openjdk:8 +COPY --from=build /home/app/target/Cosmic.jar /usr/local/lib/Cosmic.jar COPY ./ ./ -RUN sh ./posix-compile.sh -ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.6.0/wait /wait -RUN chmod +x /wait - EXPOSE 8484 7575 7576 7577 -ENTRYPOINT ["tini", "--"] -CMD /wait && sh ./posix-launch.sh +ENTRYPOINT ["java", "-jar", "/usr/local/lib/Cosmic.jar"] + + diff --git a/config.yaml b/config.yaml index b53999d5b0..4caedb49ea 100644 --- a/config.yaml +++ b/config.yaml @@ -162,7 +162,8 @@ server: USE_THREAD_TRACKER: false #[SEVERE] This deadlock auditing thing will bloat the memory as fast as the time frame one takes to lose track of a raindrop on a tempesting day. Only for debugging purposes. #Database Configuration - DB_URL: "jdbc:mysql://localhost:3306/cosmic" + DB_URL_FORMAT: "jdbc:mysql://%s:3306/cosmic" + DB_HOST: "localhost" DB_USER: "cosmic_server" DB_PASS: "snailshell" INIT_CONNECTION_POOL_TIMEOUT: 60 # Seconds diff --git a/docker-compose.yml b/docker-compose.yml index eb87edac6b..fc7334dedd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,20 +1,22 @@ version: '3' services: maplestory: - network_mode: "host" build: . depends_on: - db + ports: + - "8484:8484" + - "7575-7577:7575-7577" environment: - WAIT_HOSTS: localhost:3306 + DB_HOST: "db" db: - network_mode: "host" - image: mysql:5.6 + image: mysql:8.0.23 environment: - MYSQL_ALLOW_EMPTY_PASSWORD: "yes" + MYSQL_RANDOM_ROOT_PASSWORD: "true" MYSQL_DATABASE: "cosmic" - MYSQL_USER: "root" - MYSQL_PASSWORD: "" + MYSQL_USER: "cosmic_server" + MYSQL_PASSWORD: "snailshell" volumes: + - ./docker-db-data:/var/lib/mysql - ./sql:/docker-entrypoint-initdb.d diff --git a/sql/db_database.sql b/sql/1-db_database.sql similarity index 100% rename from sql/db_database.sql rename to sql/1-db_database.sql diff --git a/sql/db_drops.sql b/sql/2-db_drops.sql similarity index 100% rename from sql/db_drops.sql rename to sql/2-db_drops.sql diff --git a/sql/db_shopupdate.sql b/sql/3-db_shopupdate.sql similarity index 100% rename from sql/db_shopupdate.sql rename to sql/3-db_shopupdate.sql diff --git a/src/main/java/config/ServerConfig.java b/src/main/java/config/ServerConfig.java index df37b3d8b0..721c577e16 100644 --- a/src/main/java/config/ServerConfig.java +++ b/src/main/java/config/ServerConfig.java @@ -5,7 +5,8 @@ public class ServerConfig { public boolean USE_THREAD_TRACKER; //Database Configuration - public String DB_URL; + public String DB_URL_FORMAT; + public String DB_HOST; public String DB_USER; public String DB_PASS; public int INIT_CONNECTION_POOL_TIMEOUT; diff --git a/src/main/java/tools/DatabaseConnection.java b/src/main/java/tools/DatabaseConnection.java index 3901a3ab65..875bf7ef44 100644 --- a/src/main/java/tools/DatabaseConnection.java +++ b/src/main/java/tools/DatabaseConnection.java @@ -27,10 +27,19 @@ public class DatabaseConnection { return dataSource.getConnection(); } + private static String getDbUrl() { + // Environment variables override what's defined in the config file + // This feature is used for the Docker support + String hostOverride = System.getenv("DB_HOST"); + String host = hostOverride != null ? hostOverride : YamlConfig.config.server.DB_HOST; + String dbUrl = String.format(YamlConfig.config.server.DB_URL_FORMAT, host); + return dbUrl; + } + private static HikariConfig getConfig() { HikariConfig config = new HikariConfig(); - config.setJdbcUrl(YamlConfig.config.server.DB_URL); + config.setJdbcUrl(getDbUrl()); config.setUsername(YamlConfig.config.server.DB_USER); config.setPassword(YamlConfig.config.server.DB_PASS); From 34e3cd1cbd03c4434c4efbee7da11bbc6ecbff6d Mon Sep 17 00:00:00 2001 From: P0nk Date: Sat, 3 Apr 2021 15:23:10 +0200 Subject: [PATCH 9/9] Clean up unused files --- launchtest.bat | 61 ------------------------------------------------ linux-compile.sh | 4 ---- linux-launch.sh | 4 ---- posix-compile.sh | 11 --------- posix-launch.sh | 7 ------ 5 files changed, 87 deletions(-) delete mode 100644 launchtest.bat delete mode 100755 linux-compile.sh delete mode 100644 linux-launch.sh delete mode 100644 posix-compile.sh delete mode 100644 posix-launch.sh diff --git a/launchtest.bat b/launchtest.bat deleted file mode 100644 index b6a02eb5a9..0000000000 --- a/launchtest.bat +++ /dev/null @@ -1,61 +0,0 @@ -REM // 'launchtest.bat' Author: Tochi -@echo off -set a=0 -title HeavenMS: Offline -color 1b -:clear -cls -echo HeavenMS Server Launcher -echo. -echo Commands: -echo ------------------------------------------------------------- -echo start - Start HeavenMS server -echo shutdown - Shut down HeavenMS server and close Launcher File -echo reset - Resets HeavenMS Launcher File -echo clear - Clear this window -echo ------------------------------------------------------------- -echo. - -:command -set /p s="Enter command: " -if "%s%"=="start" goto :start -if "%s%"=="shutdown" goto :shutdown -if "%s%"=="reset" goto :reset -if "%s%"=="clear" goto :clear -echo Wrong Command. -echo. -goto :command - -:start -if "%a%"=="1" ( -echo HeavenMS is already active! -echo. -goto :command -) -color 4c -echo This might take a while.... -echo. -title HeavenMS: activating -echo Server Launching... -start /b launch.bat -color 2a -title HeavenMS: Online -set a=1 -ping localhost -w 10000 >nul -echo. -goto :command - -:shutdown -color 4c -title HeavenMS: Shutting Down... -echo The Server Launcher will be close in a few seconds. -ping localhost -w 100000 >nul -taskkill /im cmd.exe - -:reset -color 4c -title HeavenMS: Resetting... -echo Please type 'start' in command box after bat file have been resetted. -ping localhost -w 100000 >nul -start launchtest.bat REM // thanks Paxum for noting that 'launchtest.bat' is to be used here -taskkill /im cmd.exe \ No newline at end of file diff --git a/linux-compile.sh b/linux-compile.sh deleted file mode 100755 index 9cfec04218..0000000000 --- a/linux-compile.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -# thanks to lkxyyjx -sudo ant -Dplatforms.JDK_1.7.home=/opt/jdk1.7.0_80 compile -sudo ant -Dplatforms.JDK_1.7.home=/opt/jdk1.7.0_80 jar \ No newline at end of file diff --git a/linux-launch.sh b/linux-launch.sh deleted file mode 100644 index 40557cec8e..0000000000 --- a/linux-launch.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh -# cores in classpath, thanks to lkxyyjx -export CLASSPATH=".:dist/*:cores/*" -java -Xmx2048m -Dwzpath=wz/ net.server.Server \ No newline at end of file diff --git a/posix-compile.sh b/posix-compile.sh deleted file mode 100644 index 1880dd8b58..0000000000 --- a/posix-compile.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/bash -# compilation script for posix-compliant systems - -src=src -dist=dist - -cores=$(echo cores/*) -cores=${cores// /:} - -mkdir -p $dist -javac -d $dist -cp $cores $(find $src -name "*.java") diff --git a/posix-launch.sh b/posix-launch.sh deleted file mode 100644 index 9222538da7..0000000000 --- a/posix-launch.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -# launch script -cores=$(echo cores/*) -cores=${cores// /:} -cp=.:dist:$cores - -java -Xmx2048m -Dwzpath=wz -cp $cp net.server.Server