diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/HubRepository.java b/Plugins/Mineplex.Hub/src/mineplex/hub/HubRepository.java index 416e12206..80e9c0501 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/HubRepository.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/HubRepository.java @@ -28,9 +28,11 @@ public class HubRepository private static String CREATE_NEWS_TABLE = "CREATE TABLE IF NOT EXISTS newsList (id INT NOT NULL AUTO_INCREMENT, newsString VARCHAR(256), newsPosition INT, PRIMARY KEY (id));"; private static String RETRIEVE_NEWS_ENTRIES = "SELECT newsString, newsPosition FROM newsList;"; + private static String RETRIEVE_MAX_NEWS_POSITION = "SELECT MAX(newsPosition) AS newsPosition FROM newsList;"; private static String ADD_NEWS_ENTRY = "INSERT INTO newsList (newsString, newsPosition) VALUES(?,?);"; private static String SET_NEWS_ENTRY = "UPDATE newsList SET newsString = ? WHERE newsPosition = ?;"; private static String DELETE_NEWS_ENTRY = "DELETE FROM newsList WHERE newsPosition = ?;"; + private static String RECALC_NEWS_POSITIONS = "UPDATE newsList SET newsPosition = newsPosition - 1 WHERE newsPosition > ?;"; private Connection _connection = null; @@ -171,4 +173,146 @@ public class HubRepository return result != 0; } + + public int retrieveMaxNewsPosition() + { + int result = 0; + ResultSet resultSet = null; + PreparedStatement preparedStatement = null; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(RETRIEVE_MAX_NEWS_POSITION); + resultSet = preparedStatement.executeQuery(); + + while (resultSet.next()) + { + result = Integer.parseInt(resultSet.getString(1)); + } + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + return result; + } + + public boolean addNewsEntry(String newsEntry) + { + int result = 0; + int maxPos = retrieveMaxNewsPosition(); + PreparedStatement preparedStatement = null; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(ADD_NEWS_ENTRY); + preparedStatement.setString(1, newsEntry); + preparedStatement.setInt(2, maxPos + 1); + + result = preparedStatement.executeUpdate(); + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + return result != 0; + } + + public boolean deleteNewsEntry(int newsPosition) + { + int result = 0; + int maxPos = retrieveMaxNewsPosition(); + PreparedStatement preparedStatement = null; + + try + { + synchronized (_connectionLock) + { + if (_connection.isClosed()) + { + _connection = DriverManager.getConnection(_connectionString, _userName, _password); + } + + preparedStatement = _connection.prepareStatement(DELETE_NEWS_ENTRY); + preparedStatement.setInt(1, newsPosition); + result = preparedStatement.executeUpdate(); + + if (result != 0 && maxPos != newsPosition) + { + preparedStatement.close(); + + preparedStatement = _connection.prepareStatement(RECALC_NEWS_POSITIONS); + preparedStatement.setInt(1, newsPosition); + + result = preparedStatement.executeUpdate(); + } + } + } + catch (Exception exception) + { + exception.printStackTrace(); + } + finally + { + if (preparedStatement != null) + { + try + { + preparedStatement.close(); + } + catch (SQLException e) + { + e.printStackTrace(); + } + } + } + + return result != 0; + } } diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/NewsCommand.java b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/NewsCommand.java index 050cd7065..f8084f3ab 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/commands/NewsCommand.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/commands/NewsCommand.java @@ -15,7 +15,7 @@ import mineplex.hub.HubManager; import mineplex.hub.modules.NewsManager; public class NewsCommand extends CommandBase -{ +{ public NewsCommand(HubManager plugin) { super(plugin, Rank.ADMIN, "news"); @@ -24,7 +24,7 @@ public class NewsCommand extends CommandBase @Override public void Execute(final Player caller, final String[] args) { - NewsManager newsMang = Plugin.GetNewsManager(); + final NewsManager newsMang = Plugin.GetNewsManager(); if (args == null || args.length == 0) { @@ -35,45 +35,110 @@ public class NewsCommand extends CommandBase UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cWhite + "news add " + C.cGray + " - Adds specified news entry string to database at end of table.")); UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cWhite + "news delete #" + C.cGray + " - Removes specified (numbered) news entry string from database.")); UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cWhite + "news set # " + C.cGray + " - Updates specified (numbered) news entry string in database.")); - return; - + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cWhite + "*Please Note: " + C.cGray + "Updates to server news entries from the database are on a 4 minute refresh cycle!")); + return; } else if (args.length == 1 && args[0].equalsIgnoreCase("list")) { - UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cGray + "Current server news messages will be listed here...")); + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cGray + "Current server news messages:")); newsMang.RetriveNewsEntries(new Callback>() { - public void run(HashMap newsEntries) + public void run(final HashMap newsEntries) { - for (Iterator iterator = newsEntries.keySet().iterator(); iterator.hasNext();) + // Order newsEntries set or its output by newsPosition, not hash order... + newsMang.RetrieveMaxNewsPosition(new Callback() { - String newsPosition = iterator.next(); - String newsEntry = newsEntries.get(newsPosition); + public void run(Integer maxPosition) + { + String[] newsStrings = new String[maxPosition]; + for (Iterator iterator = newsEntries.keySet().iterator(); iterator.hasNext();) + { + String newsPosition = iterator.next(); + newsStrings[Integer.parseInt(newsPosition) - 1] = newsEntries.get(newsPosition); + //iterator.remove(); + } - UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cGold + "News " + newsPosition + C.cGray + " : " + newsEntry)); - //iterator.remove(); - } + for (int i = 0; i < newsStrings.length; i++) + { + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cGold + "News " + (i + 1) + C.cGray + " : " + newsStrings[i])); + } + } + }); } }); return; } - else if (args.length == 2) + else if (args.length >= 2 && args.length <= 128) { - if (args[0].equalsIgnoreCase("add")) + if (args[0].equalsIgnoreCase("delete") && args.length == 2) { - UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cGray + "This is where future messages like, " + C.cGold + "'" + args[1] + "'" + C.cGray + " will be added to server news!")); + final int newsPosition; + try + { + newsPosition = Integer.parseInt(args[1]); + } + catch (Exception exception) + { + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cRed + "The specified news position is invalid!")); + return; + } + newsMang.DeleteNewsEntry(newsPosition, new Callback() + { + public void run(Boolean success) + { + if (success) + { + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cGray + "The news entry at position " + C.cGold + newsPosition + C.cGray + " has been deleted!")); + } + else + { + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cRed + "There was an error deleting the news entry; likely the specified news position was invalid!")); + } + } + }); return; } - else if (args[0].equalsIgnoreCase("delete")) + else if (args[0].equalsIgnoreCase("add")) { - UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cGray + "This is where future messages at positions like, " + C.cGold + "'News Position: " + C.cGold + args[1] + "'" + C.cGray + " will be removed from server news!")); + String newsEntry = ""; + for (int i = 1; i < args.length; i++) + { + newsEntry += args[i] + " "; + } + newsEntry = newsEntry.substring(0, newsEntry.length() - 1); + + // Check for 256 character length for MySQL! + if (newsEntry.length() > 256) + { + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cRed + "The specified news entry is too long [> 256 characters]!")); + return; + } + + newsMang.AddNewsEntry(newsEntry, new Callback() + { + public void run(Boolean success) + { + if (success) + { + String newsEntry = ""; + for (int i = 1; i < args.length; i++) + { + newsEntry += args[i] + " "; + } + newsEntry = newsEntry.substring(0, newsEntry.length() - 1); + + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cGray + "The news entry: " + C.cGold + newsEntry + C.cGray + " has been added to the database!")); + } + else + { + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cRed + "There was an error adding the news entry to the database!")); + } + } + }); return; - } - } - else if (args.length >= 3 && args.length <= 128) - { - if (args[0].equalsIgnoreCase("set")) + } + else if (args[0].equalsIgnoreCase("set")) { final int newsPosition; String newsEntry = ""; @@ -83,7 +148,12 @@ public class NewsCommand extends CommandBase } newsEntry = newsEntry.substring(0, newsEntry.length() - 1); - // TODO: Check for 256 character length for MySQL! + // Check for 256 character length for MySQL! + if (newsEntry.length() > 256) + { + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cRed + "The specified news entry is too long [> 256 characters]!")); + return; + } try { @@ -117,6 +187,8 @@ public class NewsCommand extends CommandBase }); return; } + UtilPlayer.message(caller, F.main(Plugin.GetName(), C.cRed + "Your arguments are inappropriate for this command!")); + return; } else { diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/NewsManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/NewsManager.java index 46012840e..c553598aa 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/NewsManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/NewsManager.java @@ -1,6 +1,7 @@ package mineplex.hub.modules; import java.util.HashMap; +import java.util.Iterator; import org.bukkit.Bukkit; import org.bukkit.ChatColor; @@ -10,7 +11,9 @@ import org.bukkit.event.EventHandler; import mineplex.core.MiniPlugin; import mineplex.core.common.util.C; import mineplex.core.common.util.Callback; +import mineplex.core.common.util.F; import mineplex.core.common.util.UtilDisplay; +import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilTime; import mineplex.core.updater.UpdateType; @@ -45,6 +48,33 @@ public class NewsManager extends MiniPlugin "Champions: " + C.cYellow + C.Bold + "Team Deathmatch Beta", "Survival: " + C.cGreen + C.Bold + "UHC Alpha", }; + + RefreshNews(); + } + + private void RefreshNews() + { + RetriveNewsEntries(new Callback>() + { + public void run(final HashMap newsEntries) + { + // Order newsEntries set or its output by newsPosition, not hash order... + RetrieveMaxNewsPosition(new Callback() + { + public void run(Integer maxPosition) + { + String[] newsStrings = new String[maxPosition]; + for (Iterator iterator = newsEntries.keySet().iterator(); iterator.hasNext();) + { + String newsPosition = iterator.next(); + newsStrings[Integer.parseInt(newsPosition) - 1] = newsEntries.get(newsPosition); + } + + _news = newsStrings; + } + }); + } + }); } public void RetriveNewsEntries(final Callback> callback) @@ -91,6 +121,81 @@ public class NewsManager extends MiniPlugin }); } + public void AddNewsEntry(final String newsEntry, final Callback callback) + { + if (callback == null) + return; + + Bukkit.getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() + { + public void run() + { + final Boolean success = _repository.addNewsEntry(newsEntry); + + Bukkit.getScheduler().runTask(GetPlugin(), new Runnable() + { + public void run() + { + callback.run(success); + } + }); + } + }); + } + + public void DeleteNewsEntry(final int newsPosition, final Callback callback) + { + if (callback == null) + return; + + Bukkit.getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() + { + public void run() + { + final Boolean success = _repository.deleteNewsEntry(newsPosition); + + Bukkit.getScheduler().runTask(GetPlugin(), new Runnable() + { + public void run() + { + callback.run(success); + } + }); + } + }); + } + + public void RetrieveMaxNewsPosition(final Callback callback) + { + if (callback == null) + return; + + Bukkit.getScheduler().runTaskAsynchronously(GetPlugin(), new Runnable() + { + public void run() + { + final Integer position = _repository.retrieveMaxNewsPosition(); + + Bukkit.getScheduler().runTask(GetPlugin(), new Runnable() + { + public void run() + { + callback.run(position); + } + }); + } + }); + } + + @EventHandler + public void NewsUpdate(UpdateEvent event) + { + if (event.getType() != UpdateType.MIN_04) + return; + + RefreshNews(); + } + @EventHandler public void FlightUpdate(UpdateEvent event) {