From 2ae3d89496c1586f8c9b9f1da44aab68ca7c2fe3 Mon Sep 17 00:00:00 2001 From: Jonathan Williams Date: Sat, 19 Jul 2014 13:56:03 -0700 Subject: [PATCH] Fixed issue with RepositoryBase and Friend/MysqlRepo Each db call on login gets its own async after the first two account calls are finished. --- .../core/account/CoreClientManager.java | 33 +++++++---- .../event/RetrieveClientInformationEvent.java | 16 +++++ .../repository/MysqlAccountRepository.java | 11 +++- .../core/database/RepositoryBase.java | 56 +++--------------- .../src/mineplex/core/elo/EloManager.java | 56 ++++++++++++++---- .../core/friend/data/FriendRepository.java | 4 +- .../core/preferences/PreferencesManager.java | 16 ++++- .../src/mineplex/core/stats/StatsManager.java | 11 +++- .../Mineplex.Hub/src/mineplex/hub/Hub.java | 2 +- Website/LOCWebsite.suo | Bin 474624 -> 474624 bytes 10 files changed, 125 insertions(+), 80 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java index 32500667c..7d933b10a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java @@ -122,7 +122,6 @@ public class CoreClientManager extends MiniPlugin @EventHandler(priority = EventPriority.LOWEST) public void AsyncLogin(AsyncPlayerPreLoginEvent event) { - TimingManager.start(event.getName() + " logging in ASYNC."); try { LoadClient(Add(event.getName()), event.getUniqueId(), event.getAddress().getHostAddress()); @@ -132,6 +131,8 @@ public class CoreClientManager extends MiniPlugin Logger.Instance.log(exception); event.disallow(Result.KICK_OTHER, "Error retrieving information from web, please retry in a minute."); + + System.out.println(exception.getMessage()); } if (Bukkit.hasWhitelist() && !Get(event.getName()).GetRank().Has(Rank.MODERATOR)) @@ -146,12 +147,12 @@ public class CoreClientManager extends MiniPlugin event.disallow(Result.KICK_WHITELIST, "You are not whitelisted my friend."); } - - TimingManager.stop(event.getName() + " logging in ASYNC."); } private void LoadClient(CoreClient client, UUID uuid, String ipAddress) { + TimingManager.start(client.GetPlayerName() + " LoadClient Total."); + // Prep for mysql ClientToken token = null; @@ -170,30 +171,38 @@ public class CoreClientManager extends MiniPlugin // Load client in miniplugins Bukkit.getServer().getPluginManager().callEvent(new AsyncClientLoadEvent(token, client)); + + RetrieveClientInformationEvent clientInformationEvent = new RetrieveClientInformationEvent(client.GetPlayerName(), uuid); try { // Mysql - Bukkit.getServer().getPluginManager().callEvent(new RetrieveClientInformationEvent(client.GetPlayerName(), uuid)); + Bukkit.getServer().getPluginManager().callEvent(clientInformationEvent); } catch (Exception exception) { Logger.Instance.log(exception); System.out.println("Error running RetrieveClientInformationEvent" + exception.getMessage()); } - } - - @EventHandler(priority = EventPriority.MONITOR) - public void LoginTiming(PlayerLoginEvent event) - { - TimingManager.stop(event.getPlayer().getName() + " logging in SYNC."); + + while (clientInformationEvent.processing()) + { + try + { + Thread.sleep(1); + } + catch (InterruptedException e) + { + e.printStackTrace(); + } + } + + TimingManager.stop(client.GetPlayerName() + " LoadClient Total."); } @EventHandler(priority = EventPriority.LOWEST) public void Login(PlayerLoginEvent event) { - TimingManager.start(event.getPlayer().getName() + " logging in SYNC."); - synchronized(_clientLock) { if (!_clientList.containsKey(event.getPlayer().getName())) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/event/RetrieveClientInformationEvent.java b/Plugins/Mineplex.Core/src/mineplex/core/account/event/RetrieveClientInformationEvent.java index f8d2a1a8b..a07d87528 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/account/event/RetrieveClientInformationEvent.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/account/event/RetrieveClientInformationEvent.java @@ -11,6 +11,7 @@ public class RetrieveClientInformationEvent extends Event private String _playerName; private UUID _uuid; + private int _processingCount; public RetrieveClientInformationEvent(String playerName, UUID uuid) { @@ -37,4 +38,19 @@ public class RetrieveClientInformationEvent extends Event { return _uuid; } + + public void incrementProcessingCount() + { + _processingCount++; + } + + public boolean processing() + { + return _processingCount > 0; + } + + public void decreaseProcessingCount() + { + _processingCount--; + } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/repository/MysqlAccountRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/account/repository/MysqlAccountRepository.java index 899fd2228..638c3b8cd 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/account/repository/MysqlAccountRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/account/repository/MysqlAccountRepository.java @@ -8,7 +8,8 @@ import mineplex.core.database.column.ColumnVarChar; public class MysqlAccountRepository extends RepositoryBase { private static String CREATE_ACCOUNT_TABLE = "CREATE TABLE IF NOT EXISTS accounts (id INT NOT NULL AUTO_INCREMENT, uuid VARCHAR(100), name VARCHAR(40), gems INT, rank VARCHAR(40), rankPerm BOOL, rankExpire LONG, lastLogin LONG, totalPlayTime LONG, PRIMARY KEY (id), UNIQUE INDEX uuidIndex (uuid), UNIQUE INDEX nameIndex (name), INDEX rankIndex (rank));"; - private static String ACCOUNT_LOGIN = "INSERT INTO accounts (uuid, name, lastLogin) values(?, ?, now()) ON DUPLICATE KEY UPDATE name=VALUES(name), lastLogin=VALUES(lastLogin);"; + private static String ACCOUNT_LOGIN_NEW = "INSERT INTO accounts (uuid, name, lastLogin) values(?, ?, now()) ON DUPLICATE KEY UPDATE name=VALUES(name), lastLogin=VALUES(lastLogin);"; + private static String ACCOUNT_LOGIN_UPDATE = "UPDATE accounts SET uuid=?, name=?, lastLogin=now() WHERE uuid = ?;"; public MysqlAccountRepository(JavaPlugin plugin) { @@ -26,6 +27,12 @@ public class MysqlAccountRepository extends RepositoryBase public void login(String uuid, String name) { - executeUpdate(ACCOUNT_LOGIN, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("name", 40, name)); + int affectedRows = executeUpdate(ACCOUNT_LOGIN_UPDATE, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("name", 40, name), new ColumnVarChar("uuid", 100, uuid)); + + if (affectedRows == 0) + { + executeUpdate(ACCOUNT_LOGIN_NEW, new ColumnVarChar("uuid", 100, uuid), new ColumnVarChar("name", 40, name)); + System.out.println("Executed LOGIN_NEW"); + } } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/database/RepositoryBase.java b/Plugins/Mineplex.Core/src/mineplex/core/database/RepositoryBase.java index a8f280fd3..e5fb8d38d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/database/RepositoryBase.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/database/RepositoryBase.java @@ -61,15 +61,16 @@ public abstract class RepositoryBase protected int executeUpdate(String query, Column...columns) { - Connection connection = null; PreparedStatement preparedStatement = null; int affectedRows = 0; try { - connection = DriverManager.getConnection(_connectionString, _userName, _password); - preparedStatement = connection.prepareStatement(query); + if (_connection == null || !_connection.isValid(1)) + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + + preparedStatement = _connection.prepareStatement(query); for (int i=0; i < columns.length; i++) { @@ -95,18 +96,6 @@ public abstract class RepositoryBase e.printStackTrace(); } } - - if (connection != null) - { - try - { - connection.close(); - } - catch (SQLException e) - { - e.printStackTrace(); - } - } } return affectedRows; @@ -149,13 +138,14 @@ public abstract class RepositoryBase protected void executeQuery(String query, ResultSetCallable callable, Column...columns) { - Connection connection = null; PreparedStatement preparedStatement = null; try { - connection = DriverManager.getConnection(_connectionString, _userName, _password); - preparedStatement = connection.prepareStatement(query); + if (_connection == null || !_connection.isValid(1)) + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + + preparedStatement = _connection.prepareStatement(query); executeQuery(preparedStatement, callable, columns); } @@ -176,31 +166,15 @@ public abstract class RepositoryBase e.printStackTrace(); } } - - if (connection != null) - { - try - { - connection.close(); - } - catch (SQLException e) - { - e.printStackTrace(); - } - } } } protected int executeUpdate(PreparedStatement preparedStatement, Column...columns) { - Connection connection = null; - int affectedRows = 0; try { - connection = DriverManager.getConnection(_connectionString, _userName, _password); - for (int i=0; i < columns.length; i++) { columns[i].setValue(preparedStatement, i+1); @@ -212,20 +186,6 @@ public abstract class RepositoryBase { exception.printStackTrace(); } - finally - { - if (connection != null) - { - try - { - connection.close(); - } - catch (SQLException e) - { - e.printStackTrace(); - } - } - } return affectedRows; } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java index 10981c224..fc567f9a8 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/elo/EloManager.java @@ -5,12 +5,16 @@ import java.util.UUID; import mineplex.core.MiniPlugin; import mineplex.core.account.event.RetrieveClientInformationEvent; import mineplex.core.common.util.NautHashMap; +import mineplex.core.timing.TimingManager; +import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.plugin.java.JavaPlugin; public class EloManager extends MiniPlugin { + private static Object _playerEloLock = new Object(); + private EloRepository _repository; private EloRatingSystem _ratingSystem; private NautHashMap> _playerElos; @@ -41,20 +45,39 @@ public class EloManager extends MiniPlugin } @EventHandler - public void retrievePlayersElos(RetrieveClientInformationEvent event) + public void retrievePlayersElos(final RetrieveClientInformationEvent event) { - _playerElos.put(event.getUniqueId().toString(), _repository.loadClientInformation(event.getUniqueId())); + event.incrementProcessingCount(); + Bukkit.getServer().getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() + { + public void run() + { + TimingManager.start(event.getPlayerName() + " elo Account call."); + NautHashMap eloMap = _repository.loadClientInformation(event.getUniqueId()); + TimingManager.stop(event.getPlayerName() + " elo Account call."); + + synchronized (_playerEloLock) + { + _playerElos.put(event.getUniqueId().toString(), eloMap); + } + + event.decreaseProcessingCount(); + } + }); } public int getElo(UUID uuid, String gameType) { int elo = 1000; - if (_playerElos.containsKey(uuid.toString())) + synchronized (_playerEloLock) { - if (_playerElos.get(uuid.toString()).containsKey(gameType)) + if (_playerElos.containsKey(uuid.toString())) { - elo = _playerElos.get(uuid.toString()).get(gameType); + if (_playerElos.get(uuid.toString()).containsKey(gameType)) + { + elo = _playerElos.get(uuid.toString()).get(gameType); + } } } @@ -94,16 +117,25 @@ public class EloManager extends MiniPlugin saveElo(uuid.toString(), gameType, elo); } - public void saveElo(String uuid, String gameType, int elo) + public void saveElo(final String uuid, final String gameType, final int elo) { - _repository.saveElo(uuid, gameType, elo); - - if (_playerElos.containsKey(uuid)) + Bukkit.getServer().getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() { - if (_playerElos.get(uuid).containsKey(gameType)) + public void run() { - _playerElos.get(uuid).put(gameType, elo); + _repository.saveElo(uuid, gameType, elo); + + synchronized (_playerEloLock) + { + if (_playerElos.containsKey(uuid)) + { + if (_playerElos.get(uuid).containsKey(gameType)) + { + _playerElos.get(uuid).put(gameType, elo); + } + } + } } - } + }); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java index 697c971f3..45bbdaf37 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/friend/data/FriendRepository.java @@ -14,8 +14,8 @@ import mineplex.core.database.column.ColumnVarChar; public class FriendRepository extends RepositoryBase { - private static String CREATE_FRIEND_TABLE = "CREATE TABLE IF NOT EXISTS accountFriend (id INT NOT NULL AUTO_INCREMENT, uuidSource VARCHAR(100), uuidTarget VARCHAR(100), mutual BOOL, PRIMARY KEY (id), INDEX uuidTargetIndex (uuidTarget));"; - private static String RETRIEVE_MULTIPLE_FRIEND_RECORDS = "SELECT uuidSource, tA.Name, mutual FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget LEFT JOIN playerMap ON tA.name = playerName WHERE uuidSource IN "; + private static String CREATE_FRIEND_TABLE = "CREATE TABLE IF NOT EXISTS accountFriend (id INT NOT NULL AUTO_INCREMENT, uuidSource VARCHAR(100), uuidTarget VARCHAR(100), mutual BOOL, PRIMARY KEY (id), INDEX uuidIndex (uuidSource, uuidTarget));"; + private static String RETRIEVE_MULTIPLE_FRIEND_RECORDS = "SELECT uuidSource, tA.Name, mutual, serverName, tA.lastLogin FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget LEFT JOIN playerMap ON tA.name = playerName WHERE uuidSource IN "; private static String RETRIEVE_FRIEND_RECORDS = "SELECT tA.Name, mutual, serverName, tA.lastLogin FROM accountFriend INNER Join accounts AS fA ON fA.uuid = uuidSource INNER JOIN accounts AS tA ON tA.uuid = uuidTarget LEFT JOIN playerMap ON tA.name = playerName WHERE uuidSource = ?;"; private static String ADD_FRIEND_RECORD = "INSERT INTO accountFriend (uuidSource, uuidTarget) SELECT fA.uuid AS uuidSource, tA.uuid AS uuidTarget FROM accounts as fA LEFT JOIN accounts AS tA ON tA.name = ? WHERE fA.uuid = ?;"; private static String DELETE_FRIEND_RECORD = "DELETE aF FROM accountFriend AS aF INNER JOIN accounts ON accounts.name = ? WHERE uuidSource = ? AND uuidTarget = accounts.uuid;"; diff --git a/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java b/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java index e8a219c49..96d089e18 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java @@ -2,6 +2,7 @@ package mineplex.core.preferences; import java.util.Map.Entry; +import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -19,6 +20,7 @@ import mineplex.core.donation.DonationManager; import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.preferences.command.PreferencesCommand; import mineplex.core.preferences.ui.PreferencesShop; +import mineplex.core.timing.TimingManager; import mineplex.core.updater.UpdateType; import mineplex.core.updater.event.UpdateEvent; @@ -64,9 +66,19 @@ public class PreferencesManager extends MiniClientPlugin } @Override - protected void loadClientInformation(RetrieveClientInformationEvent event) + protected void loadClientInformation(final RetrieveClientInformationEvent event) { - Set(event.getPlayerName(), _repository.loadClientInformation(event.getUniqueId())); + event.incrementProcessingCount(); + Bukkit.getServer().getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() + { + public void run() + { + TimingManager.start(event.getPlayerName() + " pref Account call."); + Set(event.getPlayerName(), _repository.loadClientInformation(event.getUniqueId())); + TimingManager.stop(event.getPlayerName() + " pref Account call."); + event.decreaseProcessingCount(); + } + }); } public void savePreferences(Player caller) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/stats/StatsManager.java b/Plugins/Mineplex.Core/src/mineplex/core/stats/StatsManager.java index 9bae81a48..b4672454c 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/stats/StatsManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/stats/StatsManager.java @@ -8,6 +8,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map.Entry; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.player.PlayerQuitEvent; @@ -126,8 +127,16 @@ public class StatsManager extends MiniPlugin } @EventHandler - public void loadPlayerStats(RetrieveClientInformationEvent event) + public void loadPlayerStats(final RetrieveClientInformationEvent event) { + event.incrementProcessingCount(); + Bukkit.getServer().getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() + { + public void run() + { + event.decreaseProcessingCount(); + } + }); /* HA YOU THOUGHT I WAS GOING TO RUN DIDN'T YOU? */ if (true) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index d4e894465..e65d5966a 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -91,7 +91,7 @@ public class Hub extends JavaPlugin implements IRelation //Main Modules ServerStatusManager serverStatusManager = new ServerStatusManager(this, new LagMeter(this, clientManager)); PacketHandler packetHandler = new PacketHandler(this); - new FriendManager(this, packetHandler); + //new FriendManager(this, packetHandler); PartyManager partyManager = new PartyManager(this, clientManager, preferenceManager); Portal portal = new Portal(this, serverStatusManager.getCurrentServerName()); AntiHack.Initialize(this, punish, portal); diff --git a/Website/LOCWebsite.suo b/Website/LOCWebsite.suo index 047b052394fc5ac25c67c05b1d8bf61f7e28ca0c..6f1b215ace93b35e47f04c76d6467fb1162a7030 100644 GIT binary patch delta 12362 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 D?}iM$ delta 12890 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 Do=#z(