Make database operations during startup consistent
Use the same Connection. and log things in a similar fashion
This commit is contained in:
@@ -19,6 +19,8 @@
|
|||||||
*/
|
*/
|
||||||
package client.inventory.manipulator;
|
package client.inventory.manipulator;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import tools.DatabaseConnection;
|
import tools.DatabaseConnection;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
@@ -32,7 +34,7 @@ import java.util.Set;
|
|||||||
* @author RonanLana
|
* @author RonanLana
|
||||||
*/
|
*/
|
||||||
public class MapleCashidGenerator {
|
public class MapleCashidGenerator {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(MapleCashidGenerator.class);
|
||||||
private final static Set<Integer> existentCashids = new HashSet<>(10000);
|
private final static Set<Integer> existentCashids = new HashSet<>(10000);
|
||||||
private static Integer runningCashid = 0;
|
private static Integer runningCashid = 0;
|
||||||
|
|
||||||
@@ -49,13 +51,9 @@ public class MapleCashidGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void loadExistentCashIdsFromDb() {
|
public static synchronized void loadExistentCashIdsFromDb(Connection con) throws SQLException {
|
||||||
try (Connection con = DatabaseConnection.getConnection()) {
|
loadExistentCashIdsFromQuery(con, "SELECT id FROM rings");
|
||||||
loadExistentCashIdsFromQuery(con, "SELECT id FROM rings");
|
loadExistentCashIdsFromQuery(con, "SELECT petid FROM pets");
|
||||||
loadExistentCashIdsFromQuery(con, "SELECT petid FROM pets");
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
runningCashid = 0;
|
runningCashid = 0;
|
||||||
do {
|
do {
|
||||||
@@ -67,7 +65,11 @@ public class MapleCashidGenerator {
|
|||||||
runningCashid++;
|
runningCashid++;
|
||||||
if (runningCashid >= 777000000) {
|
if (runningCashid >= 777000000) {
|
||||||
existentCashids.clear();
|
existentCashids.clear();
|
||||||
loadExistentCashIdsFromDb();
|
try (Connection con = DatabaseConnection.getConnection()) {
|
||||||
|
loadExistentCashIdsFromDb(con);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.warn("Failed to reset overflowing cash ids", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ import java.sql.Connection;
|
|||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
import java.time.Instant;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.concurrent.atomic.AtomicLong;
|
import java.util.concurrent.atomic.AtomicLong;
|
||||||
@@ -625,7 +626,7 @@ public class Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateActiveCoupons() throws SQLException {
|
public void updateActiveCoupons(Connection con) throws SQLException {
|
||||||
synchronized (activeCoupons) {
|
synchronized (activeCoupons) {
|
||||||
activeCoupons.clear();
|
activeCoupons.clear();
|
||||||
Calendar c = Calendar.getInstance();
|
Calendar c = Calendar.getInstance();
|
||||||
@@ -633,23 +634,19 @@ public class Server {
|
|||||||
int weekDay = c.get(Calendar.DAY_OF_WEEK);
|
int weekDay = c.get(Calendar.DAY_OF_WEEK);
|
||||||
int hourDay = c.get(Calendar.HOUR_OF_DAY);
|
int hourDay = c.get(Calendar.HOUR_OF_DAY);
|
||||||
|
|
||||||
try (Connection con = DatabaseConnection.getConnection()) {
|
int weekdayMask = (1 << weekDay);
|
||||||
|
PreparedStatement ps = con.prepareStatement("SELECT couponid FROM nxcoupons WHERE (activeday & ?) = ? AND starthour <= ? AND endhour > ?");
|
||||||
|
ps.setInt(1, weekdayMask);
|
||||||
|
ps.setInt(2, weekdayMask);
|
||||||
|
ps.setInt(3, hourDay);
|
||||||
|
ps.setInt(4, hourDay);
|
||||||
|
|
||||||
int weekdayMask = (1 << weekDay);
|
try (ResultSet rs = ps.executeQuery()) {
|
||||||
PreparedStatement ps = con.prepareStatement("SELECT couponid FROM nxcoupons WHERE (activeday & ?) = ? AND starthour <= ? AND endhour > ?");
|
while (rs.next()) {
|
||||||
ps.setInt(1, weekdayMask);
|
activeCoupons.add(rs.getInt("couponid"));
|
||||||
ps.setInt(2, weekdayMask);
|
|
||||||
ps.setInt(3, hourDay);
|
|
||||||
ps.setInt(4, hourDay);
|
|
||||||
|
|
||||||
try (ResultSet rs = ps.executeQuery()) {
|
|
||||||
while (rs.next()) {
|
|
||||||
activeCoupons.add(rs.getInt("couponid"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -837,26 +834,19 @@ public class Server {
|
|||||||
TimeZone.setDefault(TimeZone.getTimeZone(YamlConfig.config.server.TIMEZONE));
|
TimeZone.setDefault(TimeZone.getTimeZone(YamlConfig.config.server.TIMEZONE));
|
||||||
|
|
||||||
try (Connection con = DatabaseConnection.getConnection()) {
|
try (Connection con = DatabaseConnection.getConnection()) {
|
||||||
try (PreparedStatement ps = con.prepareStatement("UPDATE accounts SET loggedin = 0")) {
|
setAllLoggedOut(con);
|
||||||
ps.executeUpdate();
|
setAllMerchantsInactive(con);
|
||||||
}
|
|
||||||
|
|
||||||
try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET HasMerchant = 0")) {
|
|
||||||
ps.executeUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanNxcodeCoupons(con);
|
cleanNxcodeCoupons(con);
|
||||||
loadCouponRates(con);
|
loadCouponRates(con);
|
||||||
updateActiveCoupons();
|
updateActiveCoupons(con);
|
||||||
|
MapleCashidGenerator.loadExistentCashIdsFromDb(con);
|
||||||
|
applyAllNameChanges(con); // -- name changes can be missed by INSTANT_NAME_CHANGE --
|
||||||
|
applyAllWorldTransfers(con);
|
||||||
} catch (SQLException sqle) {
|
} catch (SQLException sqle) {
|
||||||
sqle.printStackTrace();
|
log.error("Failed to run all startup-bound database tasks", sqle);
|
||||||
|
throw new IllegalStateException(sqle);
|
||||||
}
|
}
|
||||||
|
|
||||||
applyAllNameChanges(); // -- name changes can be missed by INSTANT_NAME_CHANGE --
|
|
||||||
applyAllWorldTransfers();
|
|
||||||
//MaplePet.clearMissingPetsFromDb(); // thanks Optimist for noticing this taking too long to run
|
|
||||||
MapleCashidGenerator.loadExistentCashIdsFromDb();
|
|
||||||
|
|
||||||
ThreadManager.getInstance().start();
|
ThreadManager.getInstance().start();
|
||||||
initializeTimelyTasks(); // aggregated method for timely tasks thanks to lxconan
|
initializeTimelyTasks(); // aggregated method for timely tasks thanks to lxconan
|
||||||
|
|
||||||
@@ -931,6 +921,18 @@ public class Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void setAllLoggedOut(Connection con) throws SQLException {
|
||||||
|
try (PreparedStatement ps = con.prepareStatement("UPDATE accounts SET loggedin = 0")) {
|
||||||
|
ps.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void setAllMerchantsInactive(Connection con) throws SQLException {
|
||||||
|
try (PreparedStatement ps = con.prepareStatement("UPDATE characters SET HasMerchant = 0")) {
|
||||||
|
ps.executeUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void initializeTimelyTasks() {
|
private void initializeTimelyTasks() {
|
||||||
TimerManager tMan = TimerManager.getInstance();
|
TimerManager tMan = TimerManager.getInstance();
|
||||||
tMan.start();
|
tMan.start();
|
||||||
@@ -1570,9 +1572,8 @@ public class Server {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void applyAllNameChanges() {
|
private static void applyAllNameChanges(Connection con) throws SQLException {
|
||||||
try (Connection con = DatabaseConnection.getConnection();
|
try (PreparedStatement ps = con.prepareStatement("SELECT * FROM namechanges WHERE completionTime IS NULL");
|
||||||
PreparedStatement ps = con.prepareStatement("SELECT * FROM namechanges WHERE completionTime IS NULL");
|
|
||||||
ResultSet rs = ps.executeQuery()) {
|
ResultSet rs = ps.executeQuery()) {
|
||||||
List<Pair<String, String>> changedNames = new LinkedList<>(); //logging only
|
List<Pair<String, String>> changedNames = new LinkedList<>(); //logging only
|
||||||
|
|
||||||
@@ -1596,18 +1597,17 @@ public class Server {
|
|||||||
}
|
}
|
||||||
//log
|
//log
|
||||||
for (Pair<String, String> namePair : changedNames) {
|
for (Pair<String, String> namePair : changedNames) {
|
||||||
FilePrinter.print(FilePrinter.CHANGE_CHARACTER_NAME, "Name change applied : from \"" + namePair.getLeft() + "\" to \"" + namePair.getRight() + "\" at " + Calendar.getInstance().getTime().toString());
|
log.info("Name change applied - from: \"{}\" to \"{}\" at {}", namePair.getLeft(), namePair.getRight(), Instant.now());
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
log.warn("Failed to retrieve list of pending name changes", e);
|
||||||
FilePrinter.printError(FilePrinter.CHANGE_CHARACTER_NAME, e, "Failed to retrieve list of pending name changes.");
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void applyAllWorldTransfers() {
|
private static void applyAllWorldTransfers(Connection con) throws SQLException {
|
||||||
try (Connection con = DatabaseConnection.getConnection();
|
try (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_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
||||||
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
|
||||||
ResultSet rs = ps.executeQuery()) {
|
ResultSet rs = ps.executeQuery()) {
|
||||||
List<Integer> removedTransfers = new LinkedList<>();
|
List<Integer> removedTransfers = new LinkedList<>();
|
||||||
while (rs.next()) {
|
while (rs.next()) {
|
||||||
@@ -1658,11 +1658,11 @@ public class Server {
|
|||||||
int charId = worldTransferPair.getLeft();
|
int charId = worldTransferPair.getLeft();
|
||||||
int oldWorld = worldTransferPair.getRight().getLeft();
|
int oldWorld = worldTransferPair.getRight().getLeft();
|
||||||
int newWorld = worldTransferPair.getRight().getRight();
|
int newWorld = worldTransferPair.getRight().getRight();
|
||||||
FilePrinter.print(FilePrinter.WORLD_TRANSFER, "World transfer applied : Character ID " + charId + " from World " + oldWorld + " to World " + newWorld + " at " + Calendar.getInstance().getTime().toString());
|
log.info("World transfer applied - character id {} from world {} to world {} at {}", charId, oldWorld, newWorld, Instant.now());
|
||||||
}
|
}
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
e.printStackTrace();
|
log.warn("Failed to retrieve list of pending world transfers", e);
|
||||||
FilePrinter.printError(FilePrinter.WORLD_TRANSFER, e, "Failed to retrieve list of pending world transfers.");
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,12 @@
|
|||||||
*/
|
*/
|
||||||
package net.server.task;
|
package net.server.task;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import net.server.Server;
|
import net.server.Server;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import tools.DatabaseConnection;
|
||||||
import tools.FilePrinter;
|
import tools.FilePrinter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -28,13 +32,17 @@ import tools.FilePrinter;
|
|||||||
* @info Thread responsible for maintaining coupons EXP & DROP effects active
|
* @info Thread responsible for maintaining coupons EXP & DROP effects active
|
||||||
*/
|
*/
|
||||||
public class CouponTask implements Runnable {
|
public class CouponTask implements Runnable {
|
||||||
|
private static final Logger log = LoggerFactory.getLogger(CouponTask.class);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
try {
|
try {
|
||||||
Server.getInstance().updateActiveCoupons();
|
try (Connection con = DatabaseConnection.getConnection()) {
|
||||||
|
Server.getInstance().updateActiveCoupons(con);
|
||||||
|
}
|
||||||
Server.getInstance().commitActiveCoupons();
|
Server.getInstance().commitActiveCoupons();
|
||||||
} catch(SQLException sqle) {
|
} catch (SQLException sqle) {
|
||||||
FilePrinter.printError(FilePrinter.EXCEPTION_CAUGHT, "Unexpected SQL error: " + sqle.getMessage());
|
log.error("Error updating coupon effects", sqle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user