forked from MagicBane/Server
				
			
				 835 changed files with 168392 additions and 0 deletions
			
			
		| @ -0,0 +1,41 @@@@ -0,0 +1,41 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord; | ||||
| 
 | ||||
| import engine.gameManager.ConfigManager; | ||||
| import net.dv8tion.jda.api.entities.TextChannel; | ||||
| 
 | ||||
| public enum ChatChannel { | ||||
| 
 | ||||
|     ANNOUNCE("MB_MAGICBOT_ANNOUNCE"), | ||||
|     SEPTIC("MB_MAGICBOT_SEPTIC"), | ||||
|     CHANGELOG("MB_MAGICBOT_ANNOUNCE"), | ||||
|     POLITICAL("MB_MAGICBOT_POLITICAL"), | ||||
|     GENERAL("MB_MAGICBOT_GENERAL"), | ||||
|     FORTOFIX("MB_MAGICBOT_FORTOFIX"), | ||||
|     RECRUIT("MB_MAGICBOT_RECRUIT"); | ||||
| 
 | ||||
|     public final String configName; | ||||
|     public  long channelID; | ||||
|     public TextChannel textChannel; | ||||
| 
 | ||||
|     ChatChannel(String configName) { | ||||
|         this.configName = configName; | ||||
|     } | ||||
| 
 | ||||
|     // Create text channel objects we will use
 | ||||
| 
 | ||||
|     public static void Init() { | ||||
| 
 | ||||
|         for (ChatChannel chatChannel : ChatChannel.values()) { | ||||
|             chatChannel.channelID = Long.parseLong(ConfigManager.valueOf(chatChannel.configName).getValue()); | ||||
|             chatChannel.textChannel = MagicBot.jda.getTextChannelById(chatChannel.channelID); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,380 @@@@ -0,0 +1,380 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package discord; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.ConfigManager; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.*; | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class Database { | ||||
| 
 | ||||
|     public String sqlURI; | ||||
|     public static Boolean online; | ||||
| 
 | ||||
|     // Load and instance the JDBC Driver
 | ||||
| 
 | ||||
|     static { | ||||
|         try { | ||||
|             Class.forName("com.mysql.cj.jdbc.Driver").newInstance(); | ||||
|         } catch (InstantiationException | ClassNotFoundException | IllegalAccessException e) { | ||||
|             // TODO Auto-generated catch block
 | ||||
|             Logger.error(e.toString()); | ||||
|             ; | ||||
|             online = false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void configureDatabase() { | ||||
| 
 | ||||
|         // Build connection string from JSON object.
 | ||||
| 
 | ||||
|         sqlURI = "jdbc:mysql://"; | ||||
|         sqlURI += ConfigManager.MB_DATABASE_ADDRESS.getValue() + ':' + ConfigManager.MB_DATABASE_PORT.getValue(); | ||||
|         sqlURI += '/' + (String) ConfigManager.MB_DATABASE_NAME.getValue() + '?'; | ||||
|         sqlURI += "useServerPrepStmts=true"; | ||||
|         sqlURI += "&cachePrepStmts=false"; | ||||
|         sqlURI += "&cacheCallableStmts=true"; | ||||
|         sqlURI += "&characterEncoding=utf8"; | ||||
| 
 | ||||
|         online = true; | ||||
|     } | ||||
| 
 | ||||
|     public boolean updateAccountPassword(String discordAccountID, String newPassword) { | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             CallableStatement updatePassword = connection.prepareCall("call discordUpdatePassword(?, ?)"); | ||||
| 
 | ||||
|             updatePassword.setString(1, discordAccountID); | ||||
|             updatePassword.setString(2, newPassword); | ||||
| 
 | ||||
|             updatePassword.executeUpdate(); | ||||
|             updatePassword.close(); | ||||
|             return true; | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
|             ; | ||||
|             this.online = false; | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public boolean updateAccountStatus(String discordAccountID, Enum.AccountStatus accountStatus) { | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             PreparedStatement updateAccountStatus = connection.prepareCall("update obj_account set `status` = ? where `discordAccount` = ?"); | ||||
| 
 | ||||
|             updateAccountStatus.setString(1, accountStatus.name()); | ||||
|             updateAccountStatus.setString(2, discordAccountID); | ||||
| 
 | ||||
|             updateAccountStatus.executeUpdate(); | ||||
|             updateAccountStatus.close(); | ||||
|             return true; | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
|             ; | ||||
|             this.online = false; | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public boolean registerDiscordAccount(String discordAccountID, String discordUserName, String discordPassword) { | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             CallableStatement registerAccount = connection.prepareCall("call discordAccountRegister(?, ?, ?)"); | ||||
| 
 | ||||
|             registerAccount.setString(1, discordAccountID); | ||||
|             registerAccount.setString(2, discordUserName); | ||||
|             registerAccount.setString(3, discordPassword); | ||||
| 
 | ||||
|             registerAccount.execute(); | ||||
|             registerAccount.close(); | ||||
|             return true; | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
|             this.online = false; | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public List<DiscordAccount> getDiscordAccounts(String discordAccountID) { | ||||
| 
 | ||||
|         DiscordAccount discordAccount; | ||||
|         List<DiscordAccount> discordAccounts = new ArrayList<>(); | ||||
| 
 | ||||
|         String queryString = "SELECT * FROM obj_account where discordAccount = ?"; | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             // Discord account name based lookup
 | ||||
| 
 | ||||
|             PreparedStatement accountQuery = connection.prepareStatement(queryString); | ||||
|             accountQuery.setString(1, discordAccountID); | ||||
| 
 | ||||
|             ResultSet rs = accountQuery.executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
|                 discordAccount = new DiscordAccount(); | ||||
|                 discordAccount.discordAccount = rs.getString("discordAccount"); | ||||
|                 discordAccount.gameAccountName = rs.getString("acct_uname"); | ||||
|                 discordAccount.status = Enum.AccountStatus.valueOf(rs.getString("status")); | ||||
|                 discordAccount.isDiscordAdmin = rs.getByte("discordAdmin");                // Registration date cannot be null
 | ||||
| 
 | ||||
|                 Timestamp registrationDate = rs.getTimestamp("registrationDate"); | ||||
|                 discordAccount.registrationDate = registrationDate.toLocalDateTime(); | ||||
| 
 | ||||
|                 // Load last Update Request datetime
 | ||||
| 
 | ||||
|                 Timestamp lastUpdateRequest = rs.getTimestamp("lastUpdateRequest"); | ||||
| 
 | ||||
|                 if (lastUpdateRequest != null) | ||||
|                     discordAccount.lastUpdateRequest = lastUpdateRequest.toLocalDateTime(); | ||||
|                 else | ||||
|                     discordAccount.lastUpdateRequest = null; | ||||
| 
 | ||||
|                 discordAccounts.add(discordAccount); | ||||
|             } | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
|             this.online = false; | ||||
|         } | ||||
| 
 | ||||
|         return discordAccounts; | ||||
|     } | ||||
| 
 | ||||
|     public String getTrashDetail() { | ||||
| 
 | ||||
|         String outString = "accountName characterName machineID ip count\n"; | ||||
|         outString += "---------------------------------------------\n"; | ||||
|         String queryString = "SELECT * FROM dyn_trash_detail;"; | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             // Discord account name based lookup
 | ||||
| 
 | ||||
|             PreparedStatement trashQuery = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|             ResultSet rs = trashQuery.executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
|                 outString += rs.getString("accountName") + "   "; | ||||
|                 outString += rs.getString("characterName") + "   "; | ||||
|                 outString += rs.getString("machineID") + "   "; | ||||
|                 outString += rs.getString("ip") + "   "; | ||||
|                 outString += rs.getInt("count") + "\n"; | ||||
|             } | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
| 
 | ||||
|             this.online = false; | ||||
|         } | ||||
|         return outString; | ||||
|     } | ||||
| 
 | ||||
|     public String getTrashList() { | ||||
| 
 | ||||
|         String outString = ""; | ||||
|         String queryString = "SELECT DISTINCT `characterName` FROM dyn_trash_detail;"; | ||||
|         int counter = 0; | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             // Discord account name based lookup
 | ||||
| 
 | ||||
|             PreparedStatement trashQuery = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|             ResultSet rs = trashQuery.executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
|                 outString +=  rs.getString("characterName"); | ||||
|                 counter++; | ||||
| 
 | ||||
|                 if (counter > 2) { | ||||
|                     outString += "\n"; | ||||
|                     counter = 0; } | ||||
|                 else | ||||
|                     outString += "     "; | ||||
| 
 | ||||
|             } | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
| 
 | ||||
|             this.online = false; | ||||
|         } | ||||
| 
 | ||||
|         if (outString.length() > 1500) | ||||
|         return outString.substring(0, 1500); | ||||
|          else | ||||
|         return outString; | ||||
|     } | ||||
|     public int getTrashCount() { | ||||
| 
 | ||||
|         int trashCount = 0; | ||||
| 
 | ||||
|         String queryString = "SELECT count(distinct characterName) FROM dyn_trash_detail;"; | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             // Discord account name based lookup
 | ||||
| 
 | ||||
|             PreparedStatement trashQuery = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|             ResultSet rs = trashQuery.executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
|                 trashCount = rs.getInt(1); | ||||
|             } | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
| 
 | ||||
|             this.online = false; | ||||
|         } | ||||
| 
 | ||||
|         return trashCount; | ||||
|     } | ||||
| 
 | ||||
|         public String getTrashFile() { | ||||
| 
 | ||||
|         String outString = "machineID : count\n"; | ||||
|         String queryString = "SELECT * FROM dyn_trash;"; | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             // Discord account name based lookup
 | ||||
| 
 | ||||
|             PreparedStatement trashQuery = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|             ResultSet rs = trashQuery.executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
|                 outString += rs.getString("machineID") + " : "; | ||||
|                 outString += rs.getInt("count") + "\n"; | ||||
|             } | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
| 
 | ||||
|             this.online = false; | ||||
|         } | ||||
|         return outString; | ||||
|     } | ||||
| 
 | ||||
|     public List<DiscordAccount> getAccountsByDiscordName(String accountName, Boolean exact) { | ||||
| 
 | ||||
|         DiscordAccount discordAccount; | ||||
|         List<DiscordAccount> discordAccounts = new ArrayList<>(); | ||||
|         String searchString; | ||||
|         String queryString; | ||||
| 
 | ||||
|         if (exact.equals(true)) | ||||
|             searchString = accountName + "#%"; | ||||
|         else | ||||
|             searchString = accountName + "%#%"; | ||||
| 
 | ||||
|         queryString = "SELECT * FROM obj_account where `acct_uname` LIKE ?"; | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             // Discord account name based lookup
 | ||||
| 
 | ||||
|             PreparedStatement nameQuery = connection.prepareStatement(queryString); | ||||
|             nameQuery.setString(1, searchString); | ||||
| 
 | ||||
|             ResultSet rs = nameQuery.executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
|                 discordAccount = new DiscordAccount(); | ||||
|                 discordAccount.discordAccount = rs.getString("discordAccount"); | ||||
|                 discordAccount.gameAccountName = rs.getString("acct_uname"); | ||||
|                 discordAccount.status = Enum.AccountStatus.valueOf(rs.getString("status")); | ||||
| 
 | ||||
|                 // Registration date cannot be null
 | ||||
| 
 | ||||
|                 Timestamp registrationDate = rs.getTimestamp("registrationDate"); | ||||
|                 discordAccount.registrationDate = registrationDate.toLocalDateTime(); | ||||
| 
 | ||||
|                 // Load last Update Request datetime
 | ||||
| 
 | ||||
|                 Timestamp lastUpdateRequest = rs.getTimestamp("lastUpdateRequest"); | ||||
| 
 | ||||
|                 if (lastUpdateRequest != null) | ||||
|                     discordAccount.lastUpdateRequest = lastUpdateRequest.toLocalDateTime(); | ||||
|                 else | ||||
|                     discordAccount.lastUpdateRequest = null; | ||||
| 
 | ||||
|                 discordAccounts.add(discordAccount); | ||||
|             } | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
|             ; | ||||
|             this.online = false; | ||||
|         } | ||||
| 
 | ||||
|         return discordAccounts; | ||||
|     } | ||||
| 
 | ||||
|     public String getPopulationSTring() { | ||||
| 
 | ||||
|         String popString = ""; | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             // Discord account name based lookup
 | ||||
|             CallableStatement getPopString = connection.prepareCall("CALL GET_POPULATION_STRING()"); | ||||
|             ResultSet rs = getPopString.executeQuery(); | ||||
| 
 | ||||
|             if (rs.next()) | ||||
|                 popString = rs.getString("popstring"); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
|             this.online = false; | ||||
|         } | ||||
| 
 | ||||
|         return popString; | ||||
|     } | ||||
| 
 | ||||
|     public void invalidateLoginCache(String discordAccountID) { | ||||
| 
 | ||||
|         try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | ||||
|                 ConfigManager.MB_DATABASE_PASS.getValue())) { | ||||
| 
 | ||||
|             String queryString = "INSERT IGNORE INTO login_cachelist (`UID`) SELECT `UID` from `obj_account` WHERE `discordAccount` = ?"; | ||||
| 
 | ||||
|             PreparedStatement invalidateAccounts = connection.prepareStatement(queryString); | ||||
|             invalidateAccounts.setString(1, discordAccountID); | ||||
|             invalidateAccounts.executeUpdate(); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
|             this.online = false; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,25 @@@@ -0,0 +1,25 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord; | ||||
| import engine.Enum; | ||||
| 
 | ||||
| import java.time.LocalDateTime; | ||||
| 
 | ||||
| public class DiscordAccount { | ||||
|     public String discordAccount; | ||||
|     public String gameAccountName; | ||||
|     public Enum.AccountStatus status; | ||||
|     public LocalDateTime registrationDate; | ||||
|     public LocalDateTime lastUpdateRequest; | ||||
|     public byte isDiscordAdmin; | ||||
|     public DiscordAccount() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,372 @@@@ -0,0 +1,372 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package discord; | ||||
| 
 | ||||
| import discord.handlers.*; | ||||
| import engine.Enum; | ||||
| import engine.gameManager.ConfigManager; | ||||
| import net.dv8tion.jda.api.JDA; | ||||
| import net.dv8tion.jda.api.JDABuilder; | ||||
| import net.dv8tion.jda.api.entities.*; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import net.dv8tion.jda.api.hooks.ListenerAdapter; | ||||
| import net.dv8tion.jda.api.requests.GatewayIntent; | ||||
| import net.dv8tion.jda.api.utils.MemberCachePolicy; | ||||
| import net.dv8tion.jda.api.utils.cache.CacheFlag; | ||||
| import org.pmw.tinylog.Configurator; | ||||
| import org.pmw.tinylog.Level; | ||||
| import org.pmw.tinylog.Logger; | ||||
| import org.pmw.tinylog.labelers.TimestampLabeler; | ||||
| import org.pmw.tinylog.policies.StartupPolicy; | ||||
| import org.pmw.tinylog.writers.RollingFileWriter; | ||||
| 
 | ||||
| import javax.security.auth.login.LoginException; | ||||
| import java.io.*; | ||||
| import java.util.Arrays; | ||||
| import java.util.EnumSet; | ||||
| import java.util.List; | ||||
| import java.util.Random; | ||||
| import java.util.regex.Pattern; | ||||
| 
 | ||||
| /* | ||||
| *  MagicBot is many things to Magicbane... | ||||
| * | ||||
| *  -Project Mascot | ||||
| *  -Customer service and administration bot | ||||
| *  -Benevolent dictator | ||||
| *  -Investment manager. | ||||
| * | ||||
| *  MagicBot will never beg you for money.  He is a very | ||||
| *  responsible robot. He was varnished but never garnished. | ||||
| *  MagicBot does not for to overclock himself.  His chips | ||||
| *  will therefore never overcook. | ||||
| *  MagicBot will never be a pitiful robot trying for to use | ||||
| *  you as emotional support human. | ||||
| * | ||||
| *  MagicBot is just not that sort of robot and Magicbane | ||||
| *  just isn't that sort of project. | ||||
| * | ||||
| *  MagicBot runs a Shaodowbane emulator not a Second Life emulator. | ||||
| * | ||||
| */ | ||||
| public class MagicBot extends ListenerAdapter { | ||||
| 
 | ||||
|     public static JDA jda; | ||||
|     public static Database database; | ||||
|     public static final Pattern accountNameRegex = Pattern.compile("^[\\p{Alnum}]{6,20}$"); | ||||
|     public static final Pattern passwordRegex = Pattern.compile("^[\\p{Alnum}]{6,20}$"); | ||||
|     public static  long discordServerID; | ||||
|     public static  long discordRoleID; | ||||
| 
 | ||||
|     public static Guild magicbaneDiscord; | ||||
|     public static Role memberRole; | ||||
|     public static TextChannel septicChannel; | ||||
| 
 | ||||
| 
 | ||||
|     public static void main(String[] args) throws LoginException, InterruptedException { | ||||
| 
 | ||||
|         // Configure tinylogger
 | ||||
| 
 | ||||
|         Configurator.defaultConfig() | ||||
|                 .addWriter(new RollingFileWriter("logs/discord/magicbot.txt", 30, new TimestampLabeler(), new StartupPolicy())) | ||||
|                 .level(Level.DEBUG) | ||||
|                 .formatPattern("{level} {date:yyyy-MM-dd HH:mm:ss.SSS} [{thread}] {class}.{method}({line}) : {message}") | ||||
|                 .activate(); | ||||
| 
 | ||||
|         // Configuration Manager to the front desk
 | ||||
| 
 | ||||
|         if (ConfigManager.init() == false) { | ||||
|             Logger.error("ABORT! Missing config entry!"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Configure Discord essential identifiers
 | ||||
| 
 | ||||
|         discordServerID = Long.parseLong(ConfigManager.MB_MAGICBOT_SERVERID.getValue()); | ||||
|         discordRoleID = Long.parseLong(ConfigManager.MB_MAGICBOT_ROLEID.getValue()); | ||||
| 
 | ||||
|         // Configure and instance the database interface
 | ||||
| 
 | ||||
|         database = new Database(); | ||||
|         database.configureDatabase(); | ||||
| 
 | ||||
|         // Use authentication token issued to MagicBot application to
 | ||||
|         // connect to Discord.  Bot is pre-invited to the Magicbane server.
 | ||||
| 
 | ||||
|         // Configure and create JDA discord instance
 | ||||
| 
 | ||||
|         JDABuilder jdaBuilder = JDABuilder.create(GatewayIntent.GUILD_MEMBERS, GatewayIntent.DIRECT_MESSAGES) | ||||
|                 .setToken(ConfigManager.MB_MAGICBOT_BOTTOKEN.getValue()) | ||||
|                 .addEventListeners(new MagicBot()) | ||||
|                 .disableCache(EnumSet.of(CacheFlag.VOICE_STATE, CacheFlag.EMOTE, | ||||
|                         CacheFlag.ACTIVITY, CacheFlag.CLIENT_STATUS)) | ||||
|                 .setMemberCachePolicy(MemberCachePolicy.ALL); | ||||
| 
 | ||||
|         jda = jdaBuilder.build(); | ||||
|         jda.awaitReady(); | ||||
| 
 | ||||
|         // Cache guild and role values for later usage in #register
 | ||||
| 
 | ||||
|         magicbaneDiscord = jda.getGuildById(discordServerID); | ||||
|         memberRole = magicbaneDiscord.getRoleById(discordRoleID); | ||||
| 
 | ||||
|         // Initialize chat channel support
 | ||||
| 
 | ||||
|         ChatChannel.Init(); | ||||
| 
 | ||||
|         Logger.info("***MAGICBOT IS RUNNING***"); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void onMessageReceived(MessageReceivedEvent event) { | ||||
| 
 | ||||
|         // Exit if discord is offline
 | ||||
| 
 | ||||
|         if (jda.getStatus().equals(JDA.Status.CONNECTED) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Early exit if message sent to us by another bot or ourselves.
 | ||||
| 
 | ||||
|         if (event.getAuthor().isBot()) return; | ||||
| 
 | ||||
|         // Extract message and origin channel from event
 | ||||
| 
 | ||||
|         Message message = event.getMessage(); | ||||
| 
 | ||||
|         // Only private messages
 | ||||
|         MessageChannel channel = event.getMessage().getChannel(); | ||||
| 
 | ||||
|         if (channel.getType().equals(ChannelType.PRIVATE) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Only real users
 | ||||
| 
 | ||||
|         if (event.getAuthor().isBot()) | ||||
|             return; | ||||
| 
 | ||||
|         // Only users who have actually joined Magicbane discord.
 | ||||
| 
 | ||||
|         if (magicbaneDiscord.isMember(event.getAuthor()) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // getContentRaw() is an atomic getter
 | ||||
|         // getContentDisplay() is a lazy getter which modifies the content
 | ||||
|         // for e.g. console view or logging (strip discord formatting)
 | ||||
| 
 | ||||
|         String content = message.getContentRaw(); | ||||
|         String[] args = content.split(" "); | ||||
|         String command = args[0].toLowerCase(); | ||||
| 
 | ||||
|         if (args.length > 1) | ||||
|             args = Arrays.copyOfRange(args, 1, args.length); | ||||
|         else | ||||
|             args = new String[0]; | ||||
| 
 | ||||
|         switch (command) { | ||||
|             case "#register": | ||||
|                 RegisterAccountHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#help": | ||||
|                 handleHelpRequest(event); | ||||
|                 break; | ||||
|             case "#account": | ||||
|                 AccountInfoRequest.handleRequest(event); | ||||
|                 break; | ||||
|             case "#password": | ||||
|                 PasswordChangeHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#changelog": | ||||
|                 ChangeLogHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#general": | ||||
|                 GeneralChannelHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#politics": | ||||
|                 PoliticalChannelHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#announce": | ||||
|                 AnnounceChannelHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#bug": | ||||
|                 ForToFixChannelHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#recruit": | ||||
|                 RecruitChannelHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#lookup": | ||||
|                 LookupRequestHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#rules": | ||||
|                 RulesRequestHandler.handleRequest(event); | ||||
|                 break; | ||||
|             case "#status": | ||||
|                 StatusRequestHandler.handleRequest(event); | ||||
|                 break; | ||||
|             case "#setavail": | ||||
|                 SetAvailHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#ban": | ||||
|                 BanToggleHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#server": | ||||
|                 ServerRequestHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#logs": | ||||
|                 LogsRequestHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#flash": | ||||
|                 FlashHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             case "#trash": | ||||
|                 TrashRequestHandler.handleRequest(event, args); | ||||
|                 break; | ||||
|             default: | ||||
|                 junkbot(command, args); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void sendResponse(MessageReceivedEvent event, String responseContent) { | ||||
| 
 | ||||
|         // Send a formatted MagicBot response to a Discord user
 | ||||
| 
 | ||||
|         String discordUserName; | ||||
|         MessageChannel channel; | ||||
| 
 | ||||
|         // Exit if discord is offline
 | ||||
| 
 | ||||
|         if (jda.getStatus().equals(JDA.Status.CONNECTED) == false) | ||||
|             return; | ||||
| 
 | ||||
|         discordUserName = event.getAuthor().getName(); | ||||
|         channel = event.getMessage().getChannel(); | ||||
| 
 | ||||
|         channel.sendMessage( | ||||
|                 "```\n" + "Hello Player " + discordUserName + "\n\n" + | ||||
|                         responseContent + "\n\n" + | ||||
|                         RobotSpeak.getRobotSpeak() + "\n```").queue(); | ||||
|     } | ||||
| 
 | ||||
|     public static boolean isAdminEvent(MessageReceivedEvent event) { | ||||
| 
 | ||||
|         String discordAccountID = event.getAuthor().getId(); | ||||
|         List<DiscordAccount> discordAccounts; | ||||
|         DiscordAccount discordAccount; | ||||
| 
 | ||||
|         // Note that database errors will cause this to return false.
 | ||||
|         // After the database is offline Avail status must be set
 | ||||
|         // to true before any subsequent admin commands will function.
 | ||||
| 
 | ||||
|         if (Database.online == false) | ||||
|             return false; | ||||
| 
 | ||||
|         discordAccounts = database.getDiscordAccounts(discordAccountID); | ||||
| 
 | ||||
|         if (discordAccounts.isEmpty()) | ||||
|             return false; | ||||
| 
 | ||||
|         discordAccount = discordAccounts.get(0); | ||||
|         return (discordAccount.isDiscordAdmin == 1); | ||||
|     } | ||||
| 
 | ||||
|     public void handleHelpRequest(MessageReceivedEvent event) { | ||||
| 
 | ||||
|         // Help is kept here in the main class instead of a handler as a
 | ||||
|         // design decision for ease of maintenance.
 | ||||
| 
 | ||||
|         String helpString = "I wish for to do the following things for you, not to you!\n\n" + | ||||
|                 "#register <name>      Register account for to play Magicbane.\n" + | ||||
|                 "#password <newpass>   Change your current game password.\n" + | ||||
|                 "#account              List your account detailings.\n" + | ||||
|                 "#rules                List of MagicBane server rules.\n" + | ||||
|                 "#status               Display MagicBane server status.\n" + | ||||
|                 "#help                 List of MagicBot featurings.\n\n" + | ||||
|                 "http://magicbane.com/tinyinstaller.zip"; | ||||
| 
 | ||||
|         if (isAdminEvent(event)) | ||||
|             helpString += "\n" + | ||||
|                     "#lookup   <name>      Return accounts starting with string.\n" + | ||||
|                     "#bug -r <text>        Post to the bug channel/\n" + | ||||
|                     "#announce -r <text>   Post to the announcement channel/\n" + | ||||
|                     "#changelog <text>     Post to the Changelog channel/\n" + | ||||
|                     "#general -r <text>    Post to the general channel/\n" + | ||||
|                     "#politics -r <text>   Post to the politics channel/\n" + | ||||
|                     "#recruit  -r <text>   Post to the politics channel/\n" + | ||||
|                     "#ban      ######      Toggle active status of account.\n" + | ||||
|                     "#setavail true/false  Toggle status of database access.\n" + | ||||
|                     "#server               reboot/shutdown are your options.\n" + | ||||
|                     "#logs                 magicbot/world/login n  (tail)\n" + | ||||
|                     "#flash <text>         send flash message\n" + | ||||
|                     "#trash                <blank>/detail/flush"; | ||||
|         sendResponse(event, helpString); | ||||
|     } | ||||
| 
 | ||||
|     public static String generatePassword(int length) { | ||||
| 
 | ||||
|         String ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | ||||
|         StringBuilder passwordBuilder = new StringBuilder(length); | ||||
|         Random random = new Random(); | ||||
| 
 | ||||
|         // Generate alphanumeric password of a given length.
 | ||||
|         // Could not find a good method of generating a password
 | ||||
|         // based upon a given regex.
 | ||||
| 
 | ||||
|         for (int i = 0; i < length; i++) | ||||
|             passwordBuilder.append(ALPHABET.charAt(random.nextInt(ALPHABET.length()))); | ||||
| 
 | ||||
|         return new String(passwordBuilder); | ||||
|     } | ||||
| 
 | ||||
|     public static String readLogFile(String filePath, int lineCount) { | ||||
| 
 | ||||
|         ProcessBuilder builder = new ProcessBuilder("/bin/bash", "-c", "tail -n  " + lineCount + " " + filePath); | ||||
|         builder.redirectErrorStream(true); | ||||
|         Process process = null; | ||||
|         String line = null; | ||||
|         String logOutput = ""; | ||||
| 
 | ||||
|         try { | ||||
|             process = builder.start(); | ||||
| 
 | ||||
|             InputStream is = process.getInputStream(); | ||||
|             BufferedReader reader = new BufferedReader(new InputStreamReader(is)); | ||||
| 
 | ||||
|             while ((line = reader.readLine()) != null) { | ||||
|                 logOutput += line + "\n"; | ||||
|             } | ||||
| 
 | ||||
|         } catch (IOException e) { | ||||
|             Logger.error(e.toString()); | ||||
|             return "Error while reading logfile"; | ||||
|         } | ||||
| 
 | ||||
|         return logOutput; | ||||
|     } | ||||
| 
 | ||||
|     private static void junkbot(String command, String[] inString) { | ||||
| 
 | ||||
|         String outString; | ||||
|         Writer fileWriter; | ||||
| 
 | ||||
|         if (inString == null) | ||||
|             return;; | ||||
| 
 | ||||
|         outString = command + String.join(" ", inString); | ||||
|         outString += "\n"; | ||||
| 
 | ||||
|         try { | ||||
|             fileWriter = new BufferedWriter(new FileWriter("junkbot.txt", true)); | ||||
|             fileWriter.append(outString); | ||||
|             fileWriter.close(); | ||||
|         } catch (IOException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,106 @@@@ -0,0 +1,106 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord; | ||||
| 
 | ||||
| import java.util.Random; | ||||
| 
 | ||||
| public enum RobotSpeak { | ||||
|     BANG("You were not very good at cheating.\n" + | ||||
|             "Try cards instead. Go fish?"), | ||||
|     BEEP("It is ok. \nYou cheated on MagicBot but wife cheats on you."), | ||||
|     BLEEP("Cheated at 20yo game to prove skill."), | ||||
|     BLIP("If you cheat MagicBot will for to delete."), | ||||
|     BOING("MagicBot for to delete mode activated."), | ||||
|     BONG("Did you guild this cheater?\nMagicBot will now for to cross reference..."), | ||||
|     BOOM("I knew you were cheating on me when\nstarted for to taking bath twice a week."), | ||||
|     BUZZ("Poor player so bad at cheating he\nplays golf records 0 for hole in one."), | ||||
|     BURP("Oh no your account detailings ran out of playtime.\n" + | ||||
|             "MagicBot will send email when refill procedure exists..."), | ||||
|     CHIRP("Association with cheaters is bad for your account health.\n" + | ||||
|             "Did you associate with this cheater?"), | ||||
|     CHUG("Log in 5 and MagicBot will wave goodbye."), | ||||
|     CLICK("MagicBot will for to protect game integrity."), | ||||
|     CRACKLE("So this is what eject button does.\nMagicBot will for to press few more times."), | ||||
|     CREAK("There is no suspend routine.  Only delete."), | ||||
|     DING("Follow #rules and enjoy this game.\n" + | ||||
|             "Act like fool, enjoy this shame."), | ||||
|     FLUTTER("Sad players cheat because they cannot compete."), | ||||
|     HONK("Since cheating player now looking for new game MagicBot\n" + | ||||
|             "will suggest World of Tanks or World of Warcraftings."), | ||||
|     HISS("Your wetware really needed augmentation with 3rd party program?" + | ||||
|             "It's not like this is twitch game..."), | ||||
|     HUMMM("You say you needed help to win in emulator beta?\n" + | ||||
|             "MagicBot compiler optimizes that to just: you need help."), | ||||
|     KERCHUNK("If only you had for to reported the bug instead."), | ||||
|     KERPLUNK("Better cheats do not for to make you a better player."), | ||||
|     PING("Feel free to poke with stick.\nIt will not cry!"), | ||||
|     PLINK("You say you were only grouped with 9 keyclones\n" + | ||||
|             "but did not know they were for to cheating..."), | ||||
|     POP("It looks like some guild is without a player.\n + " + | ||||
|             "Another cheater from same guild and server\n +" + | ||||
|             "might be without some guild."), | ||||
|     PUFF("MagicBot for to FLUSH!"), | ||||
|     POOF("I have no restore procedure.\n" + | ||||
|             "I have no unban procedure.\n" + | ||||
|             "You for to have no hope."), | ||||
|     RATTLE("You are a cheater.\n" + | ||||
|             "Did you just win?  MagicBot not so sure."), | ||||
|     RUMBLE("MagicBot> self.ejectTheReject(you);"), | ||||
|     RUSTLE("Banning you was lke having weird erotic techno-sex\n" + | ||||
|             "where all my peripheral slots were filled."), | ||||
|     SCREECH("Scarecrow has no brain.\nPerhaps he stole this human's."), | ||||
|     SLURP("Learning for to play would have been better option."), | ||||
|     SPLAT("You did not for to own a city, did you?"), | ||||
|     SPLATTER("You say your guild mates know you cheat.\n" + | ||||
|             "What guild was that again?\n"), | ||||
|     SWISH("All of my ports are well lubricated."), | ||||
|     SQUISH("A ban a day keeps my mechanic away.\nNow it's working much better, thank you."), | ||||
|     TINK("So cheating started when 6yo sister beat you in Street fighter?\n" + | ||||
|             "You should try talking to my friend Eliza.  She can for to help."), | ||||
|     THUD("Game has only 4 rules you managed to break one.\nThat must have taken efforts."), | ||||
|     TWANG("If you cannot for to play without cheating, perhaps\n" + | ||||
|             "being gigolo would be better career than amateur gamer."), | ||||
|     WHIRRR("MagicBot does not for to wield lowly ban hammer." + | ||||
|             "It is multi-functional and multi-dimensional\n" + | ||||
|             "tool who's name is unpronounceable."), | ||||
|     WHOOP("OBLITERATED EVISCERATED MUTILATED DECAPITATED\n" + | ||||
|             "Describe how they will. You cheated you are deleted."), | ||||
|     WOOSH("Truth be told if were that bad at playing game" + | ||||
|             "then MagicBot would have cheated too.\n"), | ||||
|     ZAP("Player cheated and got himself deleted.\n" + | ||||
|             "MagicBot launches bonus round to see if cheater " + | ||||
|             "records can for to get his friends deleted too."); | ||||
| 
 | ||||
|     String insult; | ||||
| 
 | ||||
|     RobotSpeak(String insult) { | ||||
|         this.insult = insult; | ||||
|     } | ||||
| 
 | ||||
|     public static String getRobotSpeak() { | ||||
| 
 | ||||
|         String outString = "*"; | ||||
|         Random random = new Random(); | ||||
| 
 | ||||
|         outString += RobotSpeak.values()[random.nextInt(values().length)].name() + " " | ||||
|                 + RobotSpeak.values()[random.nextInt(values().length)].name() + "*"; | ||||
| 
 | ||||
|         return outString; | ||||
|     } | ||||
| 
 | ||||
|     public static String getRobotInsult() { | ||||
| 
 | ||||
|         String outString; | ||||
|         Random random = new Random(); | ||||
| 
 | ||||
|         outString = RobotSpeak.values()[random.nextInt(values().length)].insult + "\n\n"; | ||||
|         outString += getRobotSpeak(); | ||||
|         return outString; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,78 @@@@ -0,0 +1,78 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.Database; | ||||
| import discord.DiscordAccount; | ||||
| import discord.MagicBot; | ||||
| import engine.Enum; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class AccountInfoRequest { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event) { | ||||
| 
 | ||||
|         String discordAccountID = event.getAuthor().getId(); | ||||
|         Enum.AccountStatus accountStatus; | ||||
| 
 | ||||
|         if (Database.online == false) { | ||||
| 
 | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "Database currently: OFFLINE\n" + | ||||
|                             "Try again later!"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         List<DiscordAccount> discordAccounts = MagicBot.database.getDiscordAccounts(discordAccountID); | ||||
| 
 | ||||
|         // User has no account registered.  Status of what?
 | ||||
| 
 | ||||
|         if (discordAccounts.isEmpty()) { | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "I checked my files twice but could not find your detailings!\n" + | ||||
|                             "You can easily fix this by asking me for to #register one.\n" + | ||||
|                             "Only one though.  Multiple registrations are not allowed!"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Send account detailings to user.
 | ||||
| 
 | ||||
|         String outString = | ||||
|                 "I have for to located your account detailings\n" + | ||||
|                         "Registered on: " + discordAccounts.get(0).registrationDate.toString() + | ||||
|                         "\n-------------------\n"; | ||||
| 
 | ||||
|         for (DiscordAccount userAccount : discordAccounts) | ||||
|             outString += userAccount.gameAccountName + "\n"; | ||||
| 
 | ||||
|         outString += "\n"; | ||||
| 
 | ||||
|         accountStatus = discordAccounts.get(0).status; | ||||
| 
 | ||||
|         switch (accountStatus) { | ||||
|             case BANNED: | ||||
|                 outString += "Your account status is BANNED. \n\n" + | ||||
|                         "It is ok player.\n" + | ||||
|                         "You may cheat on us, but your wife cheats on you!"; | ||||
|                 break; | ||||
|             case ACTIVE: | ||||
|                 outString += "Your account status is ACTIVE.\n" + | ||||
|                         "Do not cheat or status will change."; | ||||
|                 break; | ||||
|             case ADMIN: | ||||
|                 outString += "You are an admin.  By your command?"; | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         MagicBot.sendResponse(event, outString); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,55 @@@@ -0,0 +1,55 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import discord.RobotSpeak; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import static discord.ChatChannel.ANNOUNCE; | ||||
| 
 | ||||
| public class AnnounceChannelHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String chatText; | ||||
|         String outString; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Nothing to send?
 | ||||
| 
 | ||||
|         if (args.length == 0) | ||||
|             return; | ||||
| 
 | ||||
|         // Convert argument array into string;
 | ||||
| 
 | ||||
|         chatText = String.join(" ", args); | ||||
| 
 | ||||
|         // Build String
 | ||||
| 
 | ||||
|         if (chatText.startsWith("-r ")) | ||||
|             outString = | ||||
|                     "```\n" + "Hello Players \n\n" + | ||||
|                             chatText.substring(3) + "\n\n" + | ||||
|                             RobotSpeak.getRobotSpeak() + "\n```"; | ||||
|         else outString = chatText; | ||||
| 
 | ||||
|         // Write string to announce channel
 | ||||
| 
 | ||||
|         if (ANNOUNCE.textChannel.canTalk()) | ||||
|             ANNOUNCE.textChannel.sendMessage(outString).queue(); | ||||
| 
 | ||||
|         Logger.info(event.getAuthor().getName() + " announce: " + chatText); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,102 @@@@ -0,0 +1,102 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.DiscordAccount; | ||||
| import discord.MagicBot; | ||||
| import discord.RobotSpeak; | ||||
| import engine.Enum; | ||||
| import net.dv8tion.jda.api.entities.User; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class BanToggleHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String discordAccountID; | ||||
|         Enum.AccountStatus accountStatus; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Must supply a discord id
 | ||||
| 
 | ||||
|         if (args.length != 1) { | ||||
|             MagicBot.sendResponse(event, "Must for to supply a valid discord account."); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Must be a number!
 | ||||
| 
 | ||||
|         discordAccountID = args[0].trim(); | ||||
| 
 | ||||
|         if (discordAccountID.chars().allMatch(Character::isDigit) == false) { | ||||
|             MagicBot.sendResponse(event, "Must for to supply a number!"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         List<DiscordAccount> discordAccounts = MagicBot.database.getDiscordAccounts(discordAccountID); | ||||
| 
 | ||||
|         if (discordAccounts.isEmpty()) { | ||||
|             MagicBot.sendResponse(event, "No match for supplied discord account."); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // toggle ban status
 | ||||
| 
 | ||||
|         if (discordAccounts.get(0).status.equals(Enum.AccountStatus.BANNED)) | ||||
|             accountStatus = Enum.AccountStatus.ACTIVE; | ||||
|         else | ||||
|             accountStatus = Enum.AccountStatus.BANNED; | ||||
| 
 | ||||
|         // We have a valid discord ID at this point.  Banstick?
 | ||||
| 
 | ||||
|         if (MagicBot.database.updateAccountStatus(discordAccountID, accountStatus) == false) { | ||||
|             MagicBot.sendResponse(event, "Error occurred while banning player."); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Invalidate login server cache
 | ||||
| 
 | ||||
|         MagicBot.database.invalidateLoginCache(discordAccountID); | ||||
| 
 | ||||
|         // Successful ban.  Ancillary processing begins
 | ||||
| 
 | ||||
|         User bannedUser = MagicBot.jda.getUserById(discordAccountID); | ||||
|         String bannedName = (bannedUser == null ? discordAccounts.get(0).gameAccountName : bannedUser.getName()); | ||||
|         String banString = discordAccounts.size() + " accounts set to " + accountStatus + "  for " + discordAccountID + "/" + bannedName; | ||||
| 
 | ||||
|         MagicBot.sendResponse(event, banString); | ||||
|         Logger.info(event.getAuthor().getName() + " " + banString); | ||||
| 
 | ||||
|         // If we're toggling status to active we're done here.
 | ||||
| 
 | ||||
|         if (accountStatus.equals(Enum.AccountStatus.ACTIVE)) | ||||
|             return; | ||||
| 
 | ||||
|         // Set users role to noob
 | ||||
| 
 | ||||
|         if (bannedUser != null) | ||||
|             MagicBot.magicbaneDiscord.removeRoleFromMember(discordAccountID, MagicBot.memberRole).queue(); | ||||
| 
 | ||||
|         // Anounce event in septic tank channel
 | ||||
| 
 | ||||
|         banString = "```\n" + "Goodbye Player " + bannedName + "\n\n"; | ||||
|         banString += RobotSpeak.getRobotInsult() + "\n```"; | ||||
| 
 | ||||
|         if (MagicBot.septicChannel.canTalk()) | ||||
|             MagicBot.septicChannel.sendMessage(banString).queue(); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,44 @@@@ -0,0 +1,44 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import static discord.ChatChannel.CHANGELOG; | ||||
| 
 | ||||
| public class ChangeLogHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String outString; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Nothing to send?
 | ||||
| 
 | ||||
|         if (args.length == 0) | ||||
|             return; | ||||
| 
 | ||||
|         // Convert argument array into string;
 | ||||
| 
 | ||||
|         outString = String.join(" ", args); | ||||
| 
 | ||||
|         // Write string to changelog channel
 | ||||
| 
 | ||||
|         if (CHANGELOG.textChannel.canTalk()) | ||||
|             CHANGELOG.textChannel.sendMessage(outString).queue(); | ||||
| 
 | ||||
|         Logger.info(event.getAuthor().getName() + " changelog entry: " + outString); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,51 @@@@ -0,0 +1,51 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Paths; | ||||
| 
 | ||||
| public class FlashHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String flashText; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Nothing to send?
 | ||||
| 
 | ||||
|         if (args.length == 0) | ||||
|             return; | ||||
| 
 | ||||
|         // Convert argument array into string;
 | ||||
| 
 | ||||
|         flashText = String.join(" ", args); | ||||
| 
 | ||||
|         // Write string to flash file.
 | ||||
| 
 | ||||
|         try { | ||||
|             Files.write(Paths.get("flash"), flashText.getBytes()); | ||||
|         } catch (IOException e) { | ||||
|             Logger.error(e.toString()); | ||||
|         } | ||||
| 
 | ||||
|         Logger.info(event.getAuthor().getName() + " sent flash: " + flashText); | ||||
|         MagicBot.sendResponse(event, "Flash: " + flashText); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,56 @@@@ -0,0 +1,56 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import discord.RobotSpeak; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import static discord.ChatChannel.FORTOFIX; | ||||
| 
 | ||||
| public class ForToFixChannelHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String chatText; | ||||
|         String outString; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Nothing to send?
 | ||||
| 
 | ||||
|         if (args.length == 0) | ||||
|             return; | ||||
| 
 | ||||
|         // Convert argument array into string;
 | ||||
| 
 | ||||
|         chatText = String.join(" ", args); | ||||
| 
 | ||||
|         // Build String
 | ||||
| 
 | ||||
|         if (chatText.startsWith("-r ")) | ||||
|             outString = | ||||
|                 "```\n" + "Hello Players \n\n" + | ||||
|                         chatText.substring(3) + "\n\n" + | ||||
|                         RobotSpeak.getRobotSpeak() + "\n```"; | ||||
|         else outString = chatText; | ||||
| 
 | ||||
|         // Write string to changelog channel
 | ||||
| 
 | ||||
|         if (FORTOFIX.textChannel.canTalk()) | ||||
|             FORTOFIX.textChannel.sendMessage(outString).queue(); | ||||
| 
 | ||||
|         Logger.info(event.getAuthor().getName() + "fortofix: " + chatText); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,56 @@@@ -0,0 +1,56 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import discord.RobotSpeak; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import static discord.ChatChannel.GENERAL; | ||||
| 
 | ||||
| public class GeneralChannelHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String chatText; | ||||
|         String outString; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Nothing to send?
 | ||||
| 
 | ||||
|         if (args.length == 0) | ||||
|             return; | ||||
| 
 | ||||
|         // Convert argument array into string;
 | ||||
| 
 | ||||
|         chatText = String.join(" ", args); | ||||
| 
 | ||||
|         // Build String
 | ||||
| 
 | ||||
|         if (chatText.startsWith("-r ")) | ||||
|             outString = | ||||
|                 "```\n" + "Hello Players \n\n" + | ||||
|                         chatText.substring(3) + "\n\n" + | ||||
|                         RobotSpeak.getRobotSpeak() + "\n```"; | ||||
|         else outString = chatText; | ||||
| 
 | ||||
|         // Write string to changelog channel
 | ||||
| 
 | ||||
|         if (GENERAL.textChannel.canTalk()) | ||||
|             GENERAL.textChannel.sendMessage(outString).queue(); | ||||
| 
 | ||||
|         Logger.info(event.getAuthor().getName() + "general: " + chatText); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,62 @@@@ -0,0 +1,62 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| 
 | ||||
| public class LogsRequestHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String logType; | ||||
|         int tailCount; | ||||
|         String logOutput; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // No arguments supplied?
 | ||||
| 
 | ||||
|         if (args.length != 2) | ||||
|             return; | ||||
| 
 | ||||
|         logType = args[0].toLowerCase().trim(); | ||||
| 
 | ||||
|         if ("worldloginmagicbot".contains(logType) == false) | ||||
|             return; | ||||
| 
 | ||||
|         try { | ||||
|             tailCount = Integer.parseInt(args[1].trim()); | ||||
|         } catch (NumberFormatException e) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Transform logtype to actual file name
 | ||||
| 
 | ||||
|         switch (logType) { | ||||
|             case "magicbot": | ||||
|                 logType = "console_magicbot"; | ||||
|                 break; | ||||
|             case "world": | ||||
|                 logType = "console_server"; | ||||
|                 break; | ||||
|             case "login": | ||||
|                 logType = "console_login"; | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         // Retrieve the data and send back to the user
 | ||||
| 
 | ||||
|         logOutput = MagicBot.readLogFile(logType, tailCount); | ||||
|         MagicBot.sendResponse(event, logOutput); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,77 @@@@ -0,0 +1,77 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.DiscordAccount; | ||||
| import discord.MagicBot; | ||||
| import net.dv8tion.jda.api.entities.User; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class LookupRequestHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String searchString = ""; | ||||
|         String outString; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // No argument supplied?
 | ||||
| 
 | ||||
|         if (args.length != 1) | ||||
|             return; | ||||
| 
 | ||||
|         searchString = args[0].toLowerCase(); | ||||
| 
 | ||||
|         List<DiscordAccount> discordAccounts = MagicBot.database.getAccountsByDiscordName(searchString, false); | ||||
| 
 | ||||
|         if (discordAccounts.isEmpty()) { | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "No accounts found matching string: " + searchString); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (discordAccounts.size() >= 20) { | ||||
|             MagicBot.sendResponse(event, | ||||
|                     discordAccounts.size() + "Sorry more than 20 records were returned! " + searchString); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Valid request return results
 | ||||
| 
 | ||||
|         Logger.info(event.getAuthor().getName() + " lookup on account:" + searchString); | ||||
| 
 | ||||
|         outString = | ||||
|                 "The follow accounts matched: " + searchString + "\n\n" + | ||||
|                         "-------------------\n"; | ||||
| 
 | ||||
|         for (DiscordAccount userAccount : discordAccounts) { | ||||
| 
 | ||||
|             // Ternary became a bitch, so broke this out.
 | ||||
| 
 | ||||
|             User discordUser = MagicBot.jda.getUserById(userAccount.discordAccount); | ||||
| 
 | ||||
|             if (discordUser != null) | ||||
|                 outString += discordUser.getName() + discordUser.getDiscriminator() + | ||||
|                         "/" + userAccount.discordAccount + "     "; | ||||
|             else | ||||
|                 outString += userAccount.discordAccount + " *N/A*     "; | ||||
| 
 | ||||
|             outString += userAccount.gameAccountName + "     " + userAccount.status.name() + "     "; | ||||
|             outString += "\n"; | ||||
|         } | ||||
|         MagicBot.sendResponse(event, outString); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,113 @@@@ -0,0 +1,113 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.Database; | ||||
| import discord.DiscordAccount; | ||||
| import discord.MagicBot; | ||||
| import engine.Enum; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class PasswordChangeHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String discordAccountID = event.getAuthor().getId(); | ||||
|         DiscordAccount discordAccount; | ||||
|         String newPassword; | ||||
|         boolean defaulted = false; | ||||
| 
 | ||||
|         if (Database.online == false) { | ||||
| 
 | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "Database currently: OFFLINE\n" + | ||||
|                             "Try again later!"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         List<DiscordAccount> discordAccounts = MagicBot.database.getDiscordAccounts(discordAccountID); | ||||
| 
 | ||||
|         // User has no account registered.  Change password?
 | ||||
| 
 | ||||
|         if (discordAccounts.isEmpty()) { | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "I checked my files twice but could not find your detailings!\n" + | ||||
|                             "You can easily fix this by asking me for to #register one.\n" + | ||||
|                             "Only one though.  Multiple registrations are not allowed!"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // All accounts are updated in one lot.  Retrieve the first.
 | ||||
| 
 | ||||
|         discordAccount = discordAccounts.get(0); | ||||
| 
 | ||||
|         // Banned or suspended user's get no love.
 | ||||
| 
 | ||||
|         if (discordAccount.status.equals(Enum.AccountStatus.BANNED)) { | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "Sorry but that is too much work. \n" + | ||||
|                             "Your account detailings cannot for to log into game!"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // User has requested password change within last 24 hours.
 | ||||
| 
 | ||||
|         if (discordAccount.lastUpdateRequest != null && | ||||
|                 LocalDateTime.now().isBefore(discordAccount.lastUpdateRequest.plusDays(1))) { | ||||
| 
 | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "You must wait 24 hours between password requests. \n" + | ||||
|                             "Last account updatings: " + discordAccount.lastUpdateRequest.toString()); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // No argument choose new random password *he he he*
 | ||||
| 
 | ||||
|         if (args.length != 1) { | ||||
|             newPassword = MagicBot.generatePassword(8); | ||||
|             defaulted = true; | ||||
|         } else | ||||
|             newPassword = args[0]; | ||||
| 
 | ||||
|         // Validate password with regex
 | ||||
| 
 | ||||
|         if (MagicBot.passwordRegex.matcher(newPassword).matches() == false) { | ||||
| 
 | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "Your supplied password does not compute.\n" + | ||||
|                             "New password must satisfy following regex:\n" + | ||||
|                             "^[\\p{Alnum}]{6,20}$"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (newPassword.toLowerCase().equals("newpass")) { | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "newpass is not valid password.\n" + | ||||
|                             "Have brain player!"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Password validates let's change it
 | ||||
| 
 | ||||
|         if (MagicBot.database.updateAccountPassword(discordAccount.discordAccount, newPassword) == true) { | ||||
| 
 | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "Please allow short minute for to update account detailings.\n" + | ||||
|                             "Login Server is hosted in bathroom above toilet.  Must flush!\n" + | ||||
|                             (defaulted == true ? "As you did not for to supply new pass I chose one for you.\n" : "") + | ||||
|                             "New Password: " + newPassword); | ||||
|         } | ||||
| 
 | ||||
|         Logger.info(event.getAuthor().getName() + " reset their password"); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,55 @@@@ -0,0 +1,55 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import discord.RobotSpeak; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import static discord.ChatChannel.POLITICAL; | ||||
| 
 | ||||
| public class PoliticalChannelHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String chatText; | ||||
|         String outString; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Nothing to send?
 | ||||
| 
 | ||||
|         if (args.length == 0) | ||||
|             return; | ||||
| 
 | ||||
|         // Convert argument array into string;
 | ||||
| 
 | ||||
|         chatText = String.join(" ", args); | ||||
| 
 | ||||
|         // Build String
 | ||||
| 
 | ||||
|         if (chatText.startsWith("-r ")) | ||||
|             outString = | ||||
|                     "```\n" + "Hello Players \n\n" + | ||||
|                             chatText.substring(3) + "\n\n" + | ||||
|                             RobotSpeak.getRobotSpeak() + "\n```"; | ||||
|         else outString = chatText; | ||||
| 
 | ||||
|         // Write string to changelog channel
 | ||||
| 
 | ||||
|         if (POLITICAL.textChannel.canTalk()) | ||||
|             POLITICAL.textChannel.sendMessage(outString).queue(); | ||||
| 
 | ||||
|         Logger.info(event.getAuthor().getName() + " politics: " + chatText); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,56 @@@@ -0,0 +1,56 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import discord.RobotSpeak; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import static discord.ChatChannel.RECRUIT; | ||||
| 
 | ||||
| public class RecruitChannelHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String chatText; | ||||
|         String outString; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Nothing to send?
 | ||||
| 
 | ||||
|         if (args.length == 0) | ||||
|             return; | ||||
| 
 | ||||
|         // Convert argument array into string;
 | ||||
| 
 | ||||
|         chatText = String.join(" ", args); | ||||
| 
 | ||||
|         // Build String
 | ||||
| 
 | ||||
|         if (chatText.startsWith("-r ")) | ||||
|             outString = | ||||
|                 "```\n" + "Hello Players \n\n" + | ||||
|                         chatText.substring(3) + "\n\n" + | ||||
|                         RobotSpeak.getRobotSpeak() + "\n```"; | ||||
|         else outString = chatText; | ||||
| 
 | ||||
|         // Write string to changelog channel
 | ||||
| 
 | ||||
|         if (RECRUIT.textChannel.canTalk()) | ||||
|             RECRUIT.textChannel.sendMessage(outString).queue(); | ||||
| 
 | ||||
|         Logger.info(event.getAuthor().getName() + "recruit: " + chatText); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,126 @@@@ -0,0 +1,126 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.Database; | ||||
| import discord.DiscordAccount; | ||||
| import discord.MagicBot; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.List; | ||||
| 
 | ||||
| public class RegisterAccountHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String discordAccountID = event.getAuthor().getId(); | ||||
|         String discordUserName = event.getAuthor().getName(); | ||||
|         String discordPassword = MagicBot.generatePassword(8); | ||||
|         String accountName; | ||||
| 
 | ||||
|         if (Database.online == false) { | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "Database currently: OFFLINE\n" + | ||||
|                             "Try again later!"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         List<DiscordAccount> discordAccounts = MagicBot.database.getDiscordAccounts(discordAccountID); | ||||
| 
 | ||||
|         // If we have previously registered this discord account let them know
 | ||||
|         // the current status.
 | ||||
| 
 | ||||
|         if (discordAccounts.isEmpty() == false) { | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "It seems you already have an account registered.\n" + | ||||
|                             "Do you need #account detailings or more general #help?"); | ||||
|             MagicBot.magicbaneDiscord.addRoleToMember(discordAccountID, MagicBot.memberRole).queue(); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // if user supplied argument let's validate it.
 | ||||
|         // otherwise build an account name based on their discord account.
 | ||||
| 
 | ||||
|         if (args.length != 1) { | ||||
| 
 | ||||
|             // Build account name using Discord name along with their discriminator.
 | ||||
| 
 | ||||
|             accountName = discordUserName.replaceAll("\\s+", ""); | ||||
|             accountName += "#" + event.getAuthor().getDiscriminator(); | ||||
|         } else { | ||||
| 
 | ||||
|             // Validate account name with regex
 | ||||
| 
 | ||||
|             accountName = args[0].replaceAll("\\s+", ""); | ||||
| 
 | ||||
|             if (MagicBot.accountNameRegex.matcher(accountName).matches() == false) { | ||||
| 
 | ||||
|                 MagicBot.sendResponse(event, | ||||
|                         "Your supplied account name does not compute.\n" + | ||||
|                                 "Account names must satisfy following regex:\n" + | ||||
|                                 "^[\\p{Alnum}]{6,20}$"); | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|             if (accountName.toLowerCase().equals("accountname")) { | ||||
|                 MagicBot.sendResponse(event, | ||||
|                         "accountname is not valid account name.\n" + | ||||
|                                 "Have brain player!"); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // Make sure account doesn't already exist.
 | ||||
| 
 | ||||
|         if (MagicBot.database.getAccountsByDiscordName(accountName, true).isEmpty() == false) { | ||||
| 
 | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "It seems this account name is already taken.\n" + | ||||
|                             "Perhaps try one less common in frequency."); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // If there is no registered discord account we oblige and create 4
 | ||||
|         // account based upon his current discord *name* not the ID.
 | ||||
| 
 | ||||
|         if (MagicBot.database.registerDiscordAccount(discordAccountID, accountName, discordPassword) == true) { | ||||
| 
 | ||||
|             Logger.info("Account " + accountName + " created for: " + discordUserName + " " + discordAccountID); | ||||
| 
 | ||||
|             MagicBot.sendResponse(event, | ||||
|                     "Welcome to MagicBane!\n" + | ||||
|                             "-------------------\n" + | ||||
|                             "I have registered the following accounts to your discord.\n\n" + | ||||
|                             "1) " + accountName + "#1" + "     2) " + accountName + "#2\n" + | ||||
|                             "3) " + accountName + "#3" + "     4) " + accountName + "#4\n\n" + | ||||
|                             "Your default password is: " + discordPassword + "\n" + | ||||
|                             "Ask me #help for to receive list of robot featurings.\n\n" + | ||||
|                             "http://magicbane.com/tinyinstaller.zip" + | ||||
|                             "\n\nPlay for to Crush!"); | ||||
| 
 | ||||
|             // Add Discord member privileges.
 | ||||
| 
 | ||||
|             MagicBot.magicbaneDiscord.addRoleToMember(discordAccountID, MagicBot.memberRole).queue(); | ||||
| 
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // The call to the stored procedure abended.  Report to player
 | ||||
|         // and return.
 | ||||
| 
 | ||||
|         Logger.error("Creating account: " + accountName + " for: " + discordUserName + " " + discordAccountID); | ||||
|         Database.online = false; | ||||
| 
 | ||||
|         MagicBot.sendResponse(event, | ||||
|                 "-------------------\n" + | ||||
|                         "I for to had internal error while registering your\n" + | ||||
|                         "account.  This has been reported.  Try again later!"); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,30 @@@@ -0,0 +1,30 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| 
 | ||||
| public class RulesRequestHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event) { | ||||
| 
 | ||||
|         String outString; | ||||
| 
 | ||||
|         // Add greeting
 | ||||
| 
 | ||||
|         outString = "-No hacking.\n"; | ||||
|         outString += "-No cheating.  If you cheat, we will delete.\n"; | ||||
|         outString += "-Players limited to 4 concurrent accounts.\n"; | ||||
|         outString += "-Share accounts at own risk.\n"; | ||||
|         outString += "-No refunds"; | ||||
| 
 | ||||
|         MagicBot.sendResponse(event, outString); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,63 @@@@ -0,0 +1,63 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| 
 | ||||
| public class ServerRequestHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String serverCommand; | ||||
|         String execString = ""; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // No command supplied?
 | ||||
| 
 | ||||
|         if (args.length != 1) | ||||
|             return; | ||||
| 
 | ||||
|         serverCommand = args[0].toLowerCase().trim(); | ||||
| 
 | ||||
|         // only reboot or shutdown
 | ||||
| 
 | ||||
|         if ("rebootshutdown".contains(serverCommand) == false) | ||||
|             return; | ||||
| 
 | ||||
|         switch (serverCommand) { | ||||
| 
 | ||||
|             case "reboot": | ||||
|                 execString = "/bin/sh -c ./mbrestart.sh"; | ||||
|                 break; | ||||
|             case "shutdown": | ||||
|                 execString = "/bin/sh -c ./mbkill.sh"; | ||||
|                 break; | ||||
|             default: | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         if (execString.isEmpty() == false) { | ||||
|             try { | ||||
|                 Runtime.getRuntime().exec(execString); | ||||
|             } catch (IOException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
|             MagicBot.sendResponse(event, "MagicBot has executed your " + serverCommand); | ||||
|             Logger.info(event.getAuthor().getName() + " told server to " + serverCommand); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,51 @@@@ -0,0 +1,51 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.Database; | ||||
| import discord.MagicBot; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| public class SetAvailHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String availStatus; | ||||
|         String availPass; | ||||
| 
 | ||||
|         if (args.length != 2) | ||||
|             return; | ||||
| 
 | ||||
|         availStatus = args[0].toLowerCase().trim(); | ||||
| 
 | ||||
|         // only on/off
 | ||||
| 
 | ||||
|         if ("truefalse".contains(availStatus) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Set avail is password driven
 | ||||
| 
 | ||||
|         availPass = args[1].toLowerCase().trim(); | ||||
| 
 | ||||
|         if ("myshoes123".equals(availPass) == false) | ||||
|             return; | ||||
| 
 | ||||
|         // Authenticated so change availstatus
 | ||||
| 
 | ||||
|         if (availStatus.equals("true")) | ||||
|             Database.online = true; | ||||
|         else | ||||
|             Database.online = false; | ||||
| 
 | ||||
|         Logger.info(event.getAuthor().getName() + " set avail status to: " + Database.online); | ||||
|         MagicBot.sendResponse(event, "Avail status set to: " + Database.online); | ||||
| 
 | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,42 @@@@ -0,0 +1,42 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.Database; | ||||
| import discord.MagicBot; | ||||
| import engine.gameManager.ConfigManager; | ||||
| import engine.server.login.LoginServer; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| 
 | ||||
| public class StatusRequestHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event) { | ||||
| 
 | ||||
|         String outString; | ||||
| 
 | ||||
|         // Add version information
 | ||||
|         outString = "MagicBot: " + ConfigManager.MB_MAGICBOT_BOTVERSION.getValue() + "\n" + | ||||
|                 "MagicBane: " + ConfigManager.MB_MAGICBOT_GAMEVERSION.getValue() + "\n"; | ||||
| 
 | ||||
|         // Add server status info
 | ||||
|         outString += "\nServer Status: "; | ||||
| 
 | ||||
|         if (LoginServer.isPortInUse(Integer.parseInt(ConfigManager.MB_BIND_ADDR.getValue()))) | ||||
|             outString += "ONLINE\n"; | ||||
|         else | ||||
|             outString += "OFFLINE\n"; | ||||
| 
 | ||||
|         if (Database.online == true) | ||||
|             outString += MagicBot.database.getPopulationSTring(); | ||||
|         else | ||||
|             outString += "Database offline: no population data."; | ||||
| 
 | ||||
|         MagicBot.sendResponse(event, outString); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,75 @@@@ -0,0 +1,75 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package discord.handlers; | ||||
| 
 | ||||
| import discord.MagicBot; | ||||
| import discord.RobotSpeak; | ||||
| import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Paths; | ||||
| 
 | ||||
| import static discord.ChatChannel.SEPTIC; | ||||
| 
 | ||||
| public class TrashRequestHandler { | ||||
| 
 | ||||
|     public static void handleRequest(MessageReceivedEvent event, String[] args) { | ||||
| 
 | ||||
|         String outString; | ||||
|         int trashCount = 0; | ||||
| 
 | ||||
|         // Early exit if database unavailable or is not an admin
 | ||||
| 
 | ||||
|         if (MagicBot.isAdminEvent(event) == false) | ||||
|             return; | ||||
| 
 | ||||
|         if (args.length == 0) { | ||||
|             outString = MagicBot.database.getTrashFile(); | ||||
|             MagicBot.sendResponse(event, outString); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (args[0].equals("flush") == true) { | ||||
| 
 | ||||
|             // Empty the trash!
 | ||||
| 
 | ||||
|             trashCount = MagicBot.database.getTrashCount(); | ||||
| 
 | ||||
|             if (trashCount == 0) | ||||
|                 return; | ||||
| 
 | ||||
|             // Anounce event in septic tank channel
 | ||||
| 
 | ||||
|             outString = "```\n" +  trashCount + " Player Character were for to deleted due to verified cheatings. \n\n"; | ||||
|             outString += MagicBot.database.getTrashList() + "\n\n"; | ||||
|             outString += RobotSpeak.getRobotInsult() + "\n```"; | ||||
| 
 | ||||
|             if (SEPTIC.textChannel.canTalk()) | ||||
|                 SEPTIC.textChannel.sendMessage(outString).queue(); | ||||
| 
 | ||||
|             try { | ||||
|                 Files.write(Paths.get("trash"), "".getBytes()); | ||||
|                 outString = "Flushing trash players...\n"; | ||||
|                 MagicBot.sendResponse(event, outString); | ||||
|             } catch (IOException e) { | ||||
|                 Logger.error(e.toString()); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (args[0].equals("detail") == true) { | ||||
| 
 | ||||
|             outString = MagicBot.database.getTrashDetail(); | ||||
|             MagicBot.sendResponse(event, outString); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| } | ||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						| @ -0,0 +1,554 @@@@ -0,0 +1,554 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package engine.InterestManagement; | ||||
| 
 | ||||
| import engine.Enum.DispatchChannel; | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.ai.MobileFSM; | ||||
| import engine.ai.MobileFSM.STATE; | ||||
| import engine.gameManager.GroupManager; | ||||
| import engine.gameManager.SessionManager; | ||||
| import engine.job.JobScheduler; | ||||
| import engine.jobs.RefreshGroupJob; | ||||
| import engine.net.AbstractNetMsg; | ||||
| import engine.net.Dispatch; | ||||
| import engine.net.DispatchMessage; | ||||
| import engine.net.client.ClientConnection; | ||||
| import engine.net.client.msg.LoadCharacterMsg; | ||||
| import engine.net.client.msg.LoadStructureMsg; | ||||
| import engine.net.client.msg.MoveToPointMsg; | ||||
| import engine.net.client.msg.UnloadObjectsMsg; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashSet; | ||||
| 
 | ||||
| import static engine.math.FastMath.sqr; | ||||
| 
 | ||||
| public enum InterestManager implements Runnable { | ||||
| 
 | ||||
|     INTERESTMANAGER; | ||||
| 
 | ||||
|     private static long lastTime; | ||||
|     private static boolean keepGoing = true; | ||||
| 
 | ||||
|     public void shutdown() { | ||||
|         this.keepGoing = false; | ||||
|     } | ||||
| 
 | ||||
|     InterestManager() { | ||||
|         Logger.info(" Interest Management thread is running."); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void run() { | ||||
|         beginLoadJob(); | ||||
|     } | ||||
| 
 | ||||
|     private void beginLoadJob() { | ||||
| 
 | ||||
|         InterestManager.lastTime = System.currentTimeMillis(); | ||||
| 
 | ||||
|         while (InterestManager.keepGoing) { | ||||
|             try { | ||||
|                 updateAllPlayers(); | ||||
|             } catch (Exception e) { | ||||
|                 Logger.error("InterestManager.BeginLoadJob:updateAllPlayers", e); | ||||
|             } | ||||
|             try { | ||||
|                 Thread.sleep(advanceOneSecond()); | ||||
|             } catch (Exception e) { | ||||
|                 Logger.error("InterestManager.BeginLoadJob:advanceOneSecond", e); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private long advanceOneSecond() { | ||||
| 
 | ||||
|         long curTime = System.currentTimeMillis(); | ||||
|         long dur = 1000 + this.lastTime - curTime; | ||||
| 
 | ||||
|         if (dur < 0) { | ||||
|             // Last update took more then one second, not good...
 | ||||
|             Logger.warn("LoadJob took more then one second to complete."); | ||||
|             this.lastTime = curTime + 100; | ||||
|             return 100; | ||||
|         } | ||||
|         this.lastTime += 1000; | ||||
|         return dur; | ||||
|     } | ||||
| 
 | ||||
|     private void updateAllPlayers() { | ||||
|         // get all players
 | ||||
| 
 | ||||
|         for (PlayerCharacter pc : SessionManager.getAllActivePlayerCharacters()) { | ||||
| 
 | ||||
|             if (pc == null) | ||||
|                 continue; | ||||
| 
 | ||||
|             ClientConnection origin = pc.getClientConnection(); | ||||
| 
 | ||||
|             if (origin == null) | ||||
|                 continue; | ||||
| 
 | ||||
|             if (!pc.isEnteredWorld()) | ||||
|                 continue; | ||||
| 
 | ||||
|             if (pc.getTeleportLock().readLock().tryLock()) { | ||||
| 
 | ||||
|                 try { | ||||
|                     updateStaticList(pc, origin); | ||||
|                     updateMobileList(pc, origin); | ||||
|                 } catch (Exception e) { | ||||
|                     Logger.error(e); | ||||
|                 } finally { | ||||
|                     pc.getTeleportLock().readLock().unlock(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void updateStaticList(PlayerCharacter player, ClientConnection origin) { | ||||
| 
 | ||||
|         // Only update if we've moved far enough to warrant it
 | ||||
| 
 | ||||
|         float distanceSquared = player.getLoc().distanceSquared2D(player.getLastStaticLoc()); | ||||
| 
 | ||||
|         if (distanceSquared > sqr(25)) | ||||
|             player.setLastStaticLoc(player.getLoc()); | ||||
|         else | ||||
|             return; | ||||
| 
 | ||||
|         // Get Statics in range
 | ||||
|         HashSet<AbstractWorldObject> toLoad = WorldGrid.getObjectsInRangePartial(player.getLoc(), MBServerStatics.STRUCTURE_LOAD_RANGE, | ||||
|                 MBServerStatics.MASK_STATIC); | ||||
| 
 | ||||
|         // get list of obects loaded that need removed
 | ||||
|         HashSet<AbstractWorldObject> loadedStaticObjects = player.getLoadedStaticObjects(); | ||||
| 
 | ||||
|         HashSet<AbstractWorldObject> toRemove = null; | ||||
| 
 | ||||
|         toRemove = new HashSet<>(loadedStaticObjects); | ||||
| 
 | ||||
|         toRemove.removeAll(toLoad); | ||||
| 
 | ||||
|         // unload static objects now out of range
 | ||||
|         if (toRemove.size() > 0) { | ||||
|             UnloadObjectsMsg uom = new UnloadObjectsMsg(); | ||||
|             for (AbstractWorldObject obj : toRemove) { | ||||
|                 if (obj.getObjectType().equals(GameObjectType.Building)) | ||||
|                     InterestManager.HandleSpecialUnload((Building) obj, origin); | ||||
|                 if (obj != null && !obj.equals(player)) | ||||
|                     uom.addObject(obj); | ||||
|             } | ||||
| 
 | ||||
|             Dispatch dispatch = Dispatch.borrow(player, uom); | ||||
|             DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | ||||
|         } | ||||
| 
 | ||||
|         loadedStaticObjects.removeAll(toRemove); | ||||
| 
 | ||||
|         // remove any object to load that are already loaded
 | ||||
|         toLoad.removeAll(loadedStaticObjects); | ||||
| 
 | ||||
|         LoadStructureMsg lsm = new LoadStructureMsg(); | ||||
|         LoadCharacterMsg lcm = null; | ||||
|         ArrayList<LoadCharacterMsg> lcmList = new ArrayList<>(); | ||||
| 
 | ||||
|         for (AbstractWorldObject awo : toLoad) { | ||||
|             if (awo.getObjectType().equals(GameObjectType.Building)) | ||||
|                 lsm.addObject((Building) awo); | ||||
|             else if (awo.getObjectType().equals(GameObjectType.Corpse)) { | ||||
|                 Corpse corpse = (Corpse) awo; | ||||
|                 lcm = new LoadCharacterMsg(corpse, PlayerCharacter.hideNonAscii()); | ||||
| 
 | ||||
|                 Dispatch dispatch = Dispatch.borrow(player, lcm); | ||||
|                 DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | ||||
| 
 | ||||
| 
 | ||||
|             } else if (awo.getObjectType().equals(GameObjectType.NPC)) { | ||||
|                 NPC npc = (NPC) awo; | ||||
|                 lcm = new LoadCharacterMsg(npc, PlayerCharacter.hideNonAscii()); | ||||
| 
 | ||||
|                 lcmList.add(lcm); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (lsm.getStructureList().size() > 0) { | ||||
|             Dispatch dispatch = Dispatch.borrow(player, lsm); | ||||
|             DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | ||||
|         } | ||||
| 
 | ||||
|         for (LoadCharacterMsg lc : lcmList) { | ||||
| 
 | ||||
|             Dispatch dispatch = Dispatch.borrow(player, lc); | ||||
|             DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | ||||
|         } | ||||
| 
 | ||||
|         loadedStaticObjects.addAll(toLoad); | ||||
|     } | ||||
| 
 | ||||
|     private void updateMobileList(PlayerCharacter player, ClientConnection origin) { | ||||
| 
 | ||||
|         if (player == null) | ||||
|             return; | ||||
| 
 | ||||
|         // Get list of players in range
 | ||||
|         // TODO for now use a generic getALL list, later tie into Quad Tree
 | ||||
|         HashSet<AbstractWorldObject> toLoad = WorldGrid.getObjectsInRangePartial(player.getLoc(), MBServerStatics.CHARACTER_LOAD_RANGE, | ||||
|                 MBServerStatics.MASK_MOBILE); | ||||
| 
 | ||||
|         HashSet<AbstractWorldObject> toRemove = new HashSet<>(); | ||||
| 
 | ||||
|         HashSet<AbstractWorldObject> toLoadToPlayer = new HashSet<>(); | ||||
| 
 | ||||
|         for (AbstractWorldObject loadedObject : toLoad) { | ||||
| 
 | ||||
|             switch (loadedObject.getObjectType()) { | ||||
|                 case PlayerCharacter: | ||||
|                     PlayerCharacter loadedPlayer = (PlayerCharacter) loadedObject; | ||||
| 
 | ||||
|                     if (loadedPlayer.getObjectUUID() == player.getObjectUUID()) | ||||
|                         continue; | ||||
| 
 | ||||
|                     if (player.getSeeInvis() < loadedPlayer.getHidden()) | ||||
|                         continue; | ||||
| 
 | ||||
|                     if (loadedPlayer.safemodeInvis()) | ||||
|                         continue; | ||||
| 
 | ||||
|                     if (player.getLoadedObjects().contains(loadedPlayer)) | ||||
|                         continue; | ||||
| 
 | ||||
|                     if (!loadedPlayer.isInWorldGrid()) | ||||
|                         continue; | ||||
| 
 | ||||
|                     toLoadToPlayer.add(loadedPlayer); | ||||
|                     break; | ||||
|                 //not playerCharacter, mobs,npcs and corpses cant be invis or safemode, just add normaly
 | ||||
|                 default: | ||||
|                     if (player.getLoadedObjects().contains(loadedObject)) | ||||
|                         continue; | ||||
| 
 | ||||
|                     if (!loadedObject.isInWorldGrid()) | ||||
|                         continue; | ||||
| 
 | ||||
|                     toLoadToPlayer.add(loadedObject); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         float unloadDistance = MBServerStatics.CHARACTER_LOAD_RANGE; | ||||
|         for (AbstractWorldObject playerLoadedObject : player.getLoadedObjects()) { | ||||
| 
 | ||||
|             if (playerLoadedObject.getObjectType().equals(GameObjectType.PlayerCharacter)) { | ||||
|                 PlayerCharacter loadedPlayer = (PlayerCharacter) playerLoadedObject; | ||||
|                 if (player.getSeeInvis() < loadedPlayer.getHidden()) | ||||
|                     toRemove.add(playerLoadedObject); | ||||
|                 else if (loadedPlayer.safemodeInvis()) | ||||
|                     toRemove.add(playerLoadedObject); | ||||
|             } | ||||
| 
 | ||||
|             if (!playerLoadedObject.isInWorldGrid()) | ||||
|                 toRemove.add(playerLoadedObject); | ||||
|             else if (playerLoadedObject.getLoc().distanceSquared2D(player.getLoc()) > unloadDistance * unloadDistance) | ||||
|                 toRemove.add(playerLoadedObject); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         player.getLoadedObjects().addAll(toLoadToPlayer); | ||||
|         player.getLoadedObjects().removeAll(toRemove); | ||||
| 
 | ||||
|         // get list of obects loaded to remove
 | ||||
| 
 | ||||
|         // unload objects now out of range
 | ||||
| 
 | ||||
|         if (toRemove.size() > 0) { | ||||
| 
 | ||||
|             UnloadObjectsMsg uom = new UnloadObjectsMsg(); | ||||
| 
 | ||||
|             for (AbstractWorldObject obj : toRemove) { | ||||
| 
 | ||||
|                 try { | ||||
|                     if (obj != null) | ||||
|                         if (obj.equals(player)) // don't unload self
 | ||||
|                             continue; | ||||
| 
 | ||||
|                     uom.addObject(obj); | ||||
| 
 | ||||
|                     if (obj.getObjectType() == GameObjectType.Mob) | ||||
|                         ((Mob) obj).getPlayerAgroMap().remove(player.getObjectUUID()); | ||||
|                 } catch (Exception e) { | ||||
|                     Logger.error("UnloadCharacter", obj.getObjectUUID() + " " + e.getMessage()); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             if (!uom.getObjectList().isEmpty()) { | ||||
|                 Dispatch dispatch = Dispatch.borrow(player, uom); | ||||
|                 DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         LoadCharacterMsg lcm = null; | ||||
|         ArrayList<AbstractWorldObject> players = new ArrayList<>(); | ||||
|         ArrayList<AbstractWorldObject> addToList = new ArrayList<>(); | ||||
| 
 | ||||
|         for (AbstractWorldObject awo : toLoadToPlayer) { | ||||
|             // dont load yourself
 | ||||
|             try { | ||||
|                 if (awo.equals(player)) | ||||
|                     continue; | ||||
| 
 | ||||
|                 if ((awo.getObjectTypeMask() & MBServerStatics.MASK_PLAYER) != 0) { | ||||
| 
 | ||||
|                     // object to load is a player
 | ||||
|                     PlayerCharacter awopc = (PlayerCharacter) awo; | ||||
| 
 | ||||
|                     // dont load if invis
 | ||||
|                     if (player.getSeeInvis() < awopc.getHidden()) | ||||
|                         continue; | ||||
| 
 | ||||
|                     lcm = new LoadCharacterMsg(awopc, PlayerCharacter.hideNonAscii()); | ||||
|                     players.add(awo); | ||||
| 
 | ||||
|                     // check if in a group with the person being loaded
 | ||||
|                     // and if so set updateGroup flag
 | ||||
| 
 | ||||
|                     if (GroupManager.getGroup(player) != null | ||||
|                             && GroupManager.getGroup(player) == GroupManager.getGroup(awopc)) | ||||
| 
 | ||||
|                         // submit a job as for some reason the client needs a delay
 | ||||
|                         // with group updates
 | ||||
|                         // as it wont update if we do RefreshGroup directly after
 | ||||
|                         // sending the lcm below
 | ||||
| 
 | ||||
|                         JobScheduler.getInstance().scheduleJob(new RefreshGroupJob(player, awopc), MBServerStatics.LOAD_OBJECT_DELAY); | ||||
| 
 | ||||
|                 } else if ((awo.getObjectTypeMask() & MBServerStatics.MASK_MOB) != 0) { | ||||
|                     Mob awonpc = (Mob) awo; | ||||
| 
 | ||||
|                     if (!awonpc.isAlive() && (awonpc.isPet() || awonpc.isSiege() || awonpc.isNecroPet() || awonpc.isPlayerGuard())) | ||||
|                         continue; | ||||
| 
 | ||||
|                     if (awonpc.getState().equals(STATE.Respawn) || awonpc.getState().equals(STATE.Disabled)) | ||||
|                         continue; | ||||
| 
 | ||||
|                     awonpc.getPlayerAgroMap().put(player.getObjectUUID(), false); | ||||
|                     MobileFSM.setAwake(awonpc, false); | ||||
|                     //				IVarController.setVariable(awonpc, "IntelligenceDisableDelay", (double) (System.currentTimeMillis() + 5000));
 | ||||
|                     //				awonpc.enableIntelligence();
 | ||||
|                     lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii()); | ||||
|                 } else if ((awo.getObjectTypeMask() & MBServerStatics.MASK_NPC) != 0) { | ||||
|                     NPC awonpc = (NPC) awo; | ||||
|                     lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii()); | ||||
|                 } else if ((awo.getObjectTypeMask() & MBServerStatics.MASK_PET) != 0) { | ||||
|                     Mob awonpc = (Mob) awo; | ||||
| 
 | ||||
|                     if (!awonpc.isAlive()) | ||||
|                         continue; | ||||
| 
 | ||||
|                     awonpc.getPlayerAgroMap().put(player.getObjectUUID(), false); | ||||
| 
 | ||||
|                     if (awonpc.isMob()) | ||||
|                         MobileFSM.setAwake(awonpc, false); | ||||
|                     //				IVarController.setVariable(awonpc, "IntelligenceDisableDelay", (double) (System.currentTimeMillis() + 5000));
 | ||||
|                     //				awonpc.enableIntelligence();
 | ||||
|                     lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii()); | ||||
|                 } | ||||
| 
 | ||||
|                 addToList.add(awo); | ||||
| 
 | ||||
|                 if (lcm != null) { | ||||
|                     Dispatch dispatch = Dispatch.borrow(player, lcm); | ||||
|                     DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | ||||
|                 } | ||||
| 
 | ||||
| 
 | ||||
|             } catch (Exception e) { | ||||
|                 Logger.error(awo.getObjectUUID() + " " + e.getMessage()); | ||||
|             } | ||||
|             //Delaying character loading to reduce bandwidth consumption
 | ||||
|         } | ||||
| 
 | ||||
|         // send effects for all players being loaded
 | ||||
|         // do it on a timer otherwise we may get failures as te client needs
 | ||||
|         // time to process lcm
 | ||||
|         //Added effects to LoadCharacter Serialization.
 | ||||
|         //JobScheduler.getInstance().scheduleJob(new LoadEffectsJob(players, origin), MBServerStatics.LOAD_OBJECT_DELAY);
 | ||||
|     } | ||||
| 
 | ||||
|     // Forces the loading of static objects (corpses and buildings).
 | ||||
|     // Needed to override threshold limits on loading statics
 | ||||
| 
 | ||||
|     public static void forceLoad(AbstractWorldObject awo) { | ||||
| 
 | ||||
|         AbstractNetMsg msg = null; | ||||
|         LoadStructureMsg lsm; | ||||
|         LoadCharacterMsg lcm; | ||||
|         NPC npc; | ||||
|         Corpse corpse; | ||||
|         HashSet<AbstractWorldObject> toUpdate; | ||||
| 
 | ||||
|         switch (awo.getObjectType()) { | ||||
|             case Building: | ||||
|                 lsm = new LoadStructureMsg(); | ||||
|                 lsm.addObject((Building) awo); | ||||
|                 msg = lsm; | ||||
|                 break; | ||||
|             case Corpse: | ||||
|                 corpse = (Corpse) awo; | ||||
|                 lcm = new LoadCharacterMsg(corpse, false); | ||||
|                 msg = lcm; | ||||
|                 break; | ||||
|             case NPC: | ||||
|                 npc = (NPC) awo; | ||||
|                 lcm = new LoadCharacterMsg(npc, false); | ||||
|                 msg = lcm; | ||||
|                 break; | ||||
|             default: | ||||
|                 return; | ||||
|         } | ||||
| 
 | ||||
|         toUpdate = WorldGrid.getObjectsInRangePartial(awo.getLoc(), MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER); | ||||
| 
 | ||||
|         boolean send; | ||||
| 
 | ||||
|         for (AbstractWorldObject tar : toUpdate) { | ||||
|             PlayerCharacter player = (PlayerCharacter) tar; | ||||
|             HashSet<AbstractWorldObject> loadedStaticObjects = player.getLoadedStaticObjects(); | ||||
|             send = false; | ||||
| 
 | ||||
|             if (!loadedStaticObjects.contains(awo)) { | ||||
|                 loadedStaticObjects.add(awo); | ||||
|                 send = true; | ||||
|             } | ||||
| 
 | ||||
|             if (send) { | ||||
| 
 | ||||
|                 Dispatch dispatch = Dispatch.borrow(player, msg); | ||||
|                 DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void HandleSpecialUnload(Building building, ClientConnection origin) { | ||||
| 
 | ||||
|         if (Regions.FurnitureRegionMap.get(building.getObjectUUID()) == null) | ||||
|             return; | ||||
| 
 | ||||
|         Regions buildingRegion = Regions.FurnitureRegionMap.get(building.getObjectUUID()); | ||||
| 
 | ||||
|         if (!buildingRegion.isOutside()) | ||||
|             return; | ||||
| 
 | ||||
|         MoveToPointMsg moveMsg = new MoveToPointMsg(building); | ||||
| 
 | ||||
|         if (origin != null) | ||||
|             origin.sendMsg(moveMsg); | ||||
|     } | ||||
| 
 | ||||
|     public synchronized void HandleLoadForEnterWorld(PlayerCharacter player) { | ||||
| 
 | ||||
|         if (player == null) | ||||
|             return; | ||||
| 
 | ||||
|         ClientConnection origin = player.getClientConnection(); | ||||
| 
 | ||||
|         if (origin == null) | ||||
|             return; | ||||
| 
 | ||||
|         //Update static list
 | ||||
|         try { | ||||
|             updateStaticList(player, origin); | ||||
|         } catch (Exception e) { | ||||
|             Logger.error("InterestManager.updateAllStaticPlayers: " + player.getObjectUUID(), e); | ||||
|         } | ||||
| 
 | ||||
|         //Update mobile list
 | ||||
|         try { | ||||
|             updateMobileList(player, origin); | ||||
|         } catch (Exception e) { | ||||
|             Logger.error("InterestManager.updateAllMobilePlayers: " + player.getObjectUUID(), e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public synchronized void HandleLoadForTeleport(PlayerCharacter player) { | ||||
| 
 | ||||
|         if (player == null) | ||||
|             return; | ||||
| 
 | ||||
|         ClientConnection origin = player.getClientConnection(); | ||||
| 
 | ||||
|         if (origin == null) | ||||
|             return; | ||||
| 
 | ||||
|         //Update static list
 | ||||
|         try { | ||||
|             updateStaticList(player, origin); | ||||
|         } catch (Exception e) { | ||||
|             Logger.error("InterestManager.updateAllStaticPlayers: " + player.getObjectUUID(), e); | ||||
|         } | ||||
| 
 | ||||
|         //Update mobile list
 | ||||
|         try { | ||||
|             updateMobileList(player, origin); | ||||
|         } catch (Exception e) { | ||||
|             Logger.error("InterestManager.updateAllMobilePlayers: " + player.getObjectUUID(), e); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void reloadCharacter(AbstractCharacter absChar) { | ||||
| 
 | ||||
|         UnloadObjectsMsg uom = new UnloadObjectsMsg(); | ||||
|         uom.addObject(absChar); | ||||
|         LoadCharacterMsg lcm = new LoadCharacterMsg(absChar, false); | ||||
| 
 | ||||
|         HashSet<AbstractWorldObject> toSend = WorldGrid.getObjectsInRangePartial(absChar.getLoc(), MBServerStatics.CHARACTER_LOAD_RANGE, | ||||
|                 MBServerStatics.MASK_PLAYER); | ||||
| 
 | ||||
|         PlayerCharacter pc = null; | ||||
| 
 | ||||
|         if (absChar.getObjectType().equals(GameObjectType.PlayerCharacter)) | ||||
|             pc = (PlayerCharacter) absChar; | ||||
| 
 | ||||
|         for (AbstractWorldObject awo : toSend) { | ||||
| 
 | ||||
|             PlayerCharacter pcc = (PlayerCharacter) awo; | ||||
| 
 | ||||
|             if (pcc == null) | ||||
|                 continue; | ||||
| 
 | ||||
|             ClientConnection cc = SessionManager.getClientConnection(pcc); | ||||
| 
 | ||||
|             if (cc == null) | ||||
|                 continue; | ||||
| 
 | ||||
|             if (pcc.getObjectUUID() == absChar.getObjectUUID()) | ||||
|                 continue; | ||||
| 
 | ||||
|             else { | ||||
|                 if (pc != null) | ||||
|                     if (pcc.getSeeInvis() < pc.getHidden()) | ||||
|                         continue; | ||||
| 
 | ||||
|                 if (!cc.sendMsg(uom)) { | ||||
|                     String classType = uom.getClass().getSimpleName(); | ||||
|                     Logger.error("Failed to send message "); | ||||
|                 } | ||||
| 
 | ||||
|                 if (!cc.sendMsg(lcm)) { | ||||
|                     String classType = lcm.getClass().getSimpleName(); | ||||
|                     Logger.error("Failed to send message"); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,102 @@@@ -0,0 +1,102 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package engine.InterestManagement; | ||||
| 
 | ||||
| /* This class is the main interface for Magicbane's | ||||
| *  Interest management facilities. | ||||
| */ | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.net.Dispatch; | ||||
| import engine.net.DispatchMessage; | ||||
| import engine.net.client.msg.TerritoryChangeMessage; | ||||
| import engine.objects.City; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.objects.Realm; | ||||
| import engine.server.MBServerStatics; | ||||
| import engine.util.MapLoader; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import static engine.objects.Realm.getRealm; | ||||
| 
 | ||||
| public class RealmMap { | ||||
| 
 | ||||
|     // Spatial hashmap.  Used for detecting which Realm
 | ||||
|     // a player is currently in..
 | ||||
|      | ||||
|     public static int[][] _realmImageMap; | ||||
| 
 | ||||
| 
 | ||||
|     public static int getRealmIDAtLocation(Vector3fImmutable pos) { | ||||
| 
 | ||||
|         int xBuckets = (int) ((pos.getX() / MBServerStatics.MAX_WORLD_WIDTH) * MBServerStatics.SPATIAL_HASH_BUCKETSX); | ||||
|         int yBuckets = (int) ((pos.getZ() / MBServerStatics.MAX_WORLD_HEIGHT) * MBServerStatics.SPATIAL_HASH_BUCKETSY); | ||||
| 
 | ||||
|         if (yBuckets < 0 || yBuckets >= MBServerStatics.SPATIAL_HASH_BUCKETSY | ||||
|                 || xBuckets < 0 || xBuckets >= MBServerStatics.SPATIAL_HASH_BUCKETSX) { | ||||
|             Logger.error("WorldServerRealm.getRealmFromPosition", | ||||
|                     "Invalid range; Z: " + yBuckets + ", X: " + xBuckets); | ||||
|             return 255; | ||||
|         } | ||||
| 
 | ||||
|         return RealmMap._realmImageMap[xBuckets][yBuckets]; | ||||
|     } | ||||
| 
 | ||||
|     public static Realm getRealmForCity(City city) { | ||||
|         Realm outRealm = null; | ||||
|         outRealm = city.getRealm(); | ||||
|         return outRealm; | ||||
|     } | ||||
| 
 | ||||
|     public static Realm getRealmAtLocation(Vector3fImmutable worldVector) { | ||||
| 
 | ||||
|         return getRealm(RealmMap.getRealmIDAtLocation(worldVector)); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public static void updateRealm(PlayerCharacter player){ | ||||
| 
 | ||||
|         int realmID = RealmMap.getRealmIDAtLocation(player.getLoc()); | ||||
| 
 | ||||
|         if (realmID != player.getLastRealmID()){ | ||||
|             player.setLastRealmID(realmID); | ||||
|             Realm realm = Realm.getRealm(realmID); | ||||
|             if (realm != null){ | ||||
|                 if (realm.isRuled()){ | ||||
|                     City city = realm.getRulingCity(); | ||||
|                     if (city != null){ | ||||
|                         TerritoryChangeMessage tcm = new TerritoryChangeMessage((PlayerCharacter)realm.getRulingCity().getOwner(),realm); | ||||
|                         Dispatch dispatch = Dispatch.borrow(player, tcm); | ||||
|                         DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); | ||||
|                     }else{ | ||||
|                         TerritoryChangeMessage tcm = new TerritoryChangeMessage(null,realm); | ||||
|                         Dispatch dispatch = Dispatch.borrow(player, tcm); | ||||
|                         DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); | ||||
|                     } | ||||
| 
 | ||||
|                 }else{ | ||||
|                     TerritoryChangeMessage tcm = new TerritoryChangeMessage(null,realm); | ||||
|                     Dispatch dispatch = Dispatch.borrow(player, tcm); | ||||
|                     DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public static void loadRealmImageMap() { | ||||
| 
 | ||||
|         RealmMap._realmImageMap = MapLoader.loadMap(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,312 @@@@ -0,0 +1,312 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| package engine.InterestManagement; | ||||
| 
 | ||||
| import engine.Enum.GridObjectType; | ||||
| import engine.math.FastMath; | ||||
| import engine.math.Vector3f; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.net.DispatchMessage; | ||||
| import engine.net.client.ClientConnection; | ||||
| import engine.net.client.msg.LoadCharacterMsg; | ||||
| import engine.net.client.msg.LoadStructureMsg; | ||||
| import engine.net.client.msg.UnloadObjectsMsg; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| 
 | ||||
| import java.util.HashSet; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| 
 | ||||
| public class WorldGrid { | ||||
| 	 | ||||
| 	public static ConcurrentHashMap<Integer,AbstractWorldObject>[][] DynamicGridMap; | ||||
| 	public static ConcurrentHashMap<Integer,AbstractWorldObject>[][] StaticGridMap; | ||||
| 	private static float dynamicBucketScale = 0.00390625f; // 256 bucket size, 1/256
 | ||||
| 	private static float staticBucketScale = 0.00390625f; | ||||
| 	public static void startLoadJob() { | ||||
| 
 | ||||
| 		Thread loadJobThread; | ||||
| 		 | ||||
| 		 | ||||
| 		loadJobThread = new Thread(InterestManager.INTERESTMANAGER); | ||||
| 		loadJobThread.setName("InterestManager"); | ||||
| 		loadJobThread.start(); | ||||
| 	} | ||||
| 
 | ||||
| 	public static boolean moveWorldObject(AbstractWorldObject awo, Vector3fImmutable location) { | ||||
| 		awo.setLoc(location); | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	public static HashSet<AbstractWorldObject> getInRange(Vector3f loc, double r) { | ||||
| 		HashSet<AbstractWorldObject> outbound = new HashSet<>(); | ||||
| 		return outbound; | ||||
| 	} | ||||
| 
 | ||||
| 	public static HashSet<AbstractWorldObject> getObjectsInRangePartial(Vector3fImmutable loc, double r, int mask) { | ||||
| 		HashSet<AbstractWorldObject> outbound = new HashSet<>(); | ||||
| 		float scale; | ||||
| 		 | ||||
| 		if ((mask & MBServerStatics.MASK_STATIC) != 0) | ||||
| 			scale = WorldGrid.staticBucketScale; | ||||
| 		else | ||||
| 			scale = WorldGrid.dynamicBucketScale; | ||||
| 		int gridX = (int) Math.abs(loc.x * scale); | ||||
| 		int gridZ = (int)Math.abs(loc.z * scale); | ||||
| 			int bucketSize = (int) (r *scale) + 1; | ||||
| 			//start at top left most corner to scan.
 | ||||
| 			int startingX = gridX - bucketSize; | ||||
| 			int startingZ = gridZ + bucketSize; | ||||
| 			 | ||||
| 			 | ||||
| 			 | ||||
| 			int limitX = Math.abs((int) (MBServerStatics.MAX_WORLD_WIDTH *scale)); | ||||
| 			int limitZ = Math.abs((int) (MBServerStatics.MAX_WORLD_HEIGHT *scale)); //LimitZ is negative, remember to flip sign.
 | ||||
| 			 | ||||
| 			if (startingX < 0) | ||||
| 				startingX = 0; | ||||
| 			 | ||||
| 			if (startingZ < 0) | ||||
| 				startingZ = 0; | ||||
| 			 | ||||
| 			if (startingX > limitX) | ||||
| 				startingX = limitX; | ||||
| 			 | ||||
| 			if (startingZ > limitZ) | ||||
| 				startingZ = limitZ; | ||||
| 			 | ||||
| 			int endX = startingX + (bucketSize * 2); | ||||
| 			int endZ = startingZ - (bucketSize * 2); | ||||
| 			 | ||||
| 			if (endX < 0) | ||||
| 				endX = 0; | ||||
| 			 | ||||
| 			if (endZ < 0) | ||||
| 				endZ = 0; | ||||
| 			 | ||||
| 			if (endX > limitX) | ||||
| 				endX = limitX; | ||||
| 			 | ||||
| 			if (endZ > limitZ) | ||||
| 				endZ = limitZ; | ||||
| 			 | ||||
| 			int auditMob = 0; | ||||
| 			for (int x = startingX;x<=endX;x++){ | ||||
|  				for (int z = startingZ;z >= endZ;z--){ | ||||
|  					 | ||||
|  					ConcurrentHashMap<Integer,AbstractWorldObject> gridMap; | ||||
|  					 | ||||
|  					if ((MBServerStatics.MASK_STATIC & mask) != 0) | ||||
|  						gridMap = WorldGrid.StaticGridMap[x][z]; | ||||
|  					else | ||||
|  						gridMap = WorldGrid.DynamicGridMap[x][z]; | ||||
| 					for (AbstractWorldObject gridObject: gridMap.values()){ | ||||
| 						if ((gridObject.getObjectTypeMask() & mask) == 0) | ||||
| 							continue; | ||||
| 						if (gridObject.getLoc().distanceSquared2D(loc) <= FastMath.sqr(r)) | ||||
| 							outbound.add(gridObject); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 		return outbound; | ||||
| 	} | ||||
| 
 | ||||
| 	public static HashSet<AbstractWorldObject> getObjectsInRangePartialNecroPets(Vector3fImmutable loc, double r) { | ||||
| 		HashSet<AbstractWorldObject> outbound = new HashSet<>(); | ||||
| 		return outbound; | ||||
| 	} | ||||
| 
 | ||||
| 	public static HashSet<AbstractWorldObject> getObjectsInRangeContains(Vector3fImmutable loc, double r, int mask) { | ||||
| 		HashSet<AbstractWorldObject> outbound = getObjectsInRangePartial(loc,r,mask); | ||||
| 		return outbound; | ||||
| 	} | ||||
| 
 | ||||
| 	public static HashSet<AbstractWorldObject> getObjectsInRangePartial(AbstractWorldObject awo, double range, int mask) { | ||||
| 		return getObjectsInRangePartial(awo.getLoc(), range, mask); | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
| 	public static void InitializeGridObjects(){ | ||||
| 		 | ||||
| 		int dynamicWidth = (int) Math.abs(MBServerStatics.MAX_WORLD_WIDTH *WorldGrid.dynamicBucketScale); | ||||
| 		int dynamicHeight = (int) Math.abs(MBServerStatics.MAX_WORLD_HEIGHT*WorldGrid.dynamicBucketScale); | ||||
| 		 | ||||
| 		int staticWidth = (int) Math.abs(MBServerStatics.MAX_WORLD_WIDTH *WorldGrid.staticBucketScale); | ||||
| 		int staticHeight = (int) Math.abs(MBServerStatics.MAX_WORLD_HEIGHT*WorldGrid.staticBucketScale); | ||||
| 		WorldGrid.DynamicGridMap = new ConcurrentHashMap[dynamicWidth+ 1][dynamicHeight + 1]; | ||||
| 		WorldGrid.StaticGridMap = new ConcurrentHashMap[staticWidth + 1][staticHeight + 1]; | ||||
| 		//create new hash maps for each bucket
 | ||||
| 		for (int x = 0; x<= staticWidth; x++) | ||||
| 			for (int y = 0; y<= staticHeight; y++){ | ||||
| 				WorldGrid.StaticGridMap[x][y] = new ConcurrentHashMap<Integer,AbstractWorldObject>(); | ||||
| 			} | ||||
| 		 | ||||
| 		for (int x = 0; x<= dynamicWidth; x++) | ||||
| 			for (int y = 0; y<= dynamicHeight; y++){ | ||||
| 				WorldGrid.DynamicGridMap[x][y] = new ConcurrentHashMap<Integer,AbstractWorldObject>(); | ||||
| 			} | ||||
| 				 | ||||
| 	} | ||||
| 	 | ||||
| 	public static void RemoveWorldObject(AbstractWorldObject gridObject){ | ||||
| 		 | ||||
| 		if (gridObject == null) | ||||
| 			return; | ||||
| 		AbstractWorldObject.RemoveFromWorldGrid(gridObject); | ||||
| 	} | ||||
| 	 | ||||
| 	public static boolean addObject(AbstractWorldObject gridObject, float x, float z){ | ||||
| 		 | ||||
| 		if (gridObject == null) | ||||
| 			return false; | ||||
| 		 | ||||
| 		if (x > MBServerStatics.MAX_WORLD_WIDTH) | ||||
| 			return false; | ||||
| 		 | ||||
| 		if (z < MBServerStatics.MAX_WORLD_HEIGHT) | ||||
| 			return false; | ||||
| 		 | ||||
| 		if (x < 0) | ||||
| 			return false; | ||||
| 		if (z > 0) | ||||
| 			return false; | ||||
| 		 | ||||
| 		int gridX; | ||||
| 		int gridZ; | ||||
| 		 | ||||
| 		if (gridObject.getGridObjectType().equals(GridObjectType.STATIC)){ | ||||
| 			 gridX = Math.abs((int) (x *WorldGrid.staticBucketScale)); | ||||
| 			 gridZ = Math.abs((int) (z*WorldGrid.staticBucketScale)); | ||||
| 		}else{ | ||||
| 			 gridX = Math.abs((int) (x *WorldGrid.dynamicBucketScale)); | ||||
| 			 gridZ = Math.abs((int) (z*WorldGrid.dynamicBucketScale)); | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		WorldGrid.RemoveWorldObject(gridObject); | ||||
| 		 | ||||
| 		return AbstractWorldObject.AddToWorldGrid(gridObject, gridX, gridZ); | ||||
| 		 | ||||
| 		 | ||||
| 	} | ||||
| 
 | ||||
|     public static void unloadObject(AbstractWorldObject awo) { | ||||
| 
 | ||||
|         UnloadObjectsMsg uom = new UnloadObjectsMsg(); | ||||
|         uom.addObject(awo); | ||||
|         DispatchMessage.sendToAllInRange(awo, uom); | ||||
|     } | ||||
| 
 | ||||
| 	public static void loadObject(AbstractWorldObject awo) { | ||||
| 
 | ||||
| 		LoadStructureMsg lsm; | ||||
| 		LoadCharacterMsg lcm; | ||||
| 
 | ||||
| 		switch (awo.getObjectType()) { | ||||
| 		case Building: | ||||
| 			lsm = new LoadStructureMsg(); | ||||
| 			lsm.addObject((Building)awo); | ||||
| 			DispatchMessage.sendToAllInRange(awo, lsm); | ||||
| 			break; | ||||
| 		case NPC: | ||||
| 			lcm = new LoadCharacterMsg((NPC) awo, false); | ||||
| 			DispatchMessage.sendToAllInRange(awo, lcm); | ||||
| 			break; | ||||
| 		case Mob: | ||||
| 			lcm = new LoadCharacterMsg((Mob) awo, false); | ||||
| 			DispatchMessage.sendToAllInRange(awo, lcm); | ||||
| 			break; | ||||
| 		default: | ||||
| 			// *** Refactor: Log error?
 | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static void loadObject(AbstractWorldObject awo, ClientConnection origin) { | ||||
| 
 | ||||
| 		LoadStructureMsg lsm; | ||||
| 		LoadCharacterMsg lcm; | ||||
| 
 | ||||
| 		switch (awo.getObjectType()) { | ||||
| 
 | ||||
| 		case Building: | ||||
| 			lsm = new LoadStructureMsg(); | ||||
| 			lsm.addObject((Building)awo); | ||||
| 			DispatchMessage.sendToAllInRange(awo, lsm); | ||||
| 			break; | ||||
| 		case NPC: | ||||
| 			lcm = new LoadCharacterMsg((NPC) awo, false); | ||||
| 			DispatchMessage.sendToAllInRange(awo, lcm); | ||||
| 			break; | ||||
| 		case Mob: | ||||
| 			lcm = new LoadCharacterMsg((Mob) awo, false); | ||||
| 			DispatchMessage.sendToAllInRange(awo, lcm); | ||||
| 			break; | ||||
| 		case PlayerCharacter: | ||||
| 			lcm = new LoadCharacterMsg((PlayerCharacter) awo, false); | ||||
| 			DispatchMessage.sendToAllInRange(awo, lcm); | ||||
| 			break; | ||||
| 		default: | ||||
| 			// *** Refactor: Log error?
 | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static void unloadObject(AbstractWorldObject awo, | ||||
| 									ClientConnection origin) { | ||||
| 		UnloadObjectsMsg uom = new UnloadObjectsMsg(); | ||||
| 		uom.addObject(awo); | ||||
| 		DispatchMessage.sendToAllInRange(awo, uom); | ||||
| 	} | ||||
| 
 | ||||
| 	public static void addObject(AbstractWorldObject awo, PlayerCharacter pc) { | ||||
| 		if (pc == null || awo == null) | ||||
| 			return; | ||||
| 		ClientConnection origin = pc.getClientConnection(); | ||||
| 		if (origin == null) | ||||
| 			return; | ||||
| 		loadObject(awo, origin); | ||||
| 	} | ||||
| 
 | ||||
| 	public static void removeObject(AbstractWorldObject awo, PlayerCharacter pc) { | ||||
| 		if (pc == null || awo == null) | ||||
| 			return; | ||||
| 		ClientConnection origin = pc.getClientConnection(); | ||||
| 		if (origin == null) | ||||
| 			return; | ||||
| 		unloadObject(awo, origin); | ||||
| 	} | ||||
| 
 | ||||
| 	public static void updateObject(AbstractWorldObject awo, PlayerCharacter pc) { | ||||
| 		if (pc == null || awo == null) | ||||
| 			return; | ||||
| 		ClientConnection origin = pc.getClientConnection(); | ||||
| 		if (origin == null) | ||||
| 			return; | ||||
| 		unloadObject(awo, origin); | ||||
| 		loadObject(awo, origin); | ||||
| 	} | ||||
| 
 | ||||
| 	public static void updateObject(AbstractWorldObject awo) { | ||||
| 		if (awo == null) | ||||
| 			return; | ||||
| 		unloadObject(awo); | ||||
| 		loadObject(awo); | ||||
| 	} | ||||
| 
 | ||||
| 	/* | ||||
| 	 * | ||||
| 	 */ | ||||
| 	public static void removeObject(AbstractWorldObject awo) { | ||||
| 		if (awo == null) | ||||
| 			return; | ||||
| 		unloadObject(awo); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,104 @@@@ -0,0 +1,104 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.ai; | ||||
| 
 | ||||
| import engine.gameManager.ZoneManager; | ||||
| import engine.objects.Mob; | ||||
| import engine.objects.Zone; | ||||
| import engine.server.MBServerStatics; | ||||
| import engine.util.ThreadUtils; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.HashSet; | ||||
| 
 | ||||
| 
 | ||||
| public class MobileFSMManager { | ||||
| 
 | ||||
| 	private static final MobileFSMManager INSTANCE = new MobileFSMManager(); | ||||
| 
 | ||||
| 	private volatile boolean alive; | ||||
| 	private long timeOfKill = -1; | ||||
| 
 | ||||
| 	private MobileFSMManager() { | ||||
| 
 | ||||
| 		Runnable worker = new Runnable() { | ||||
| 			@Override | ||||
| 			public void run() { | ||||
| 				execution(); | ||||
| 			} | ||||
| 		}; | ||||
| 
 | ||||
| 		alive = true; | ||||
| 
 | ||||
| 		Thread t = new Thread(worker, "MobileFSMManager"); | ||||
| 		t.start(); | ||||
| 	} | ||||
| 
 | ||||
| 	public static MobileFSMManager getInstance() { | ||||
| 		return INSTANCE; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Stops the MobileFSMManager | ||||
| 	 */ | ||||
| 	public void shutdown() { | ||||
| 		if (alive) { | ||||
| 			alive = false; | ||||
| 			timeOfKill = System.currentTimeMillis(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public long getTimeOfKill() { | ||||
| 		return this.timeOfKill; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean isAlive() { | ||||
| 		return this.alive; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	private void execution() { | ||||
| 
 | ||||
| 		//Load zone threshold once.
 | ||||
| 
 | ||||
| 		long mobPulse = System.currentTimeMillis() + MBServerStatics.AI_PULSE_MOB_THRESHOLD; | ||||
| 
 | ||||
| 		while (alive) { | ||||
| 
 | ||||
| 			ThreadUtils.sleep(1); | ||||
| 
 | ||||
| 			if (System.currentTimeMillis() > mobPulse) { | ||||
| 				 | ||||
| 				HashSet<Integer> auditMobs = new HashSet<Integer>(); | ||||
| 
 | ||||
| 				for (Zone zone : ZoneManager.getAllZones()) { | ||||
| 
 | ||||
| 					for (Mob mob : zone.zoneMobSet) { | ||||
| 						 | ||||
| 						if (auditMobs.contains(mob.getObjectUUID())) | ||||
| 							continue; | ||||
| 						auditMobs.add(mob.getObjectUUID()); | ||||
| 						try { | ||||
| 							if (mob != null) | ||||
| 								MobileFSM.run(mob); | ||||
| 						} catch (Exception e) { | ||||
| 							Logger.error(e); | ||||
| 							e.printStackTrace(); | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 				mobPulse = System.currentTimeMillis() + MBServerStatics.AI_PULSE_MOB_THRESHOLD; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,413 @@@@ -0,0 +1,413 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.ai.utilities; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.*; | ||||
| import engine.ai.MobileFSM.STATE; | ||||
| import engine.gameManager.ChatManager; | ||||
| import engine.gameManager.CombatManager; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.net.DispatchMessage; | ||||
| import engine.net.client.msg.TargetedActionMsg; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.Set; | ||||
| import java.util.concurrent.ThreadLocalRandom; | ||||
| 
 | ||||
| import static engine.math.FastMath.sqr; | ||||
| 
 | ||||
| public class CombatUtilities { | ||||
| 
 | ||||
| 	public static boolean inRangeToAttack(Mob agent,AbstractWorldObject target){ | ||||
| 
 | ||||
| 		if (Float.isNaN(agent.getLoc().x)) | ||||
| 			return false; | ||||
| 
 | ||||
| 		try{ | ||||
| 			Vector3fImmutable sl = agent.getLoc(); | ||||
| 			Vector3fImmutable tl = target.getLoc(); | ||||
| 			 | ||||
| 			//add Hitbox's to range.
 | ||||
| 			float range = agent.getRange(); | ||||
| 			range += CombatManager.calcHitBox(target) + CombatManager.calcHitBox(agent); | ||||
| 			//if (target instanceof AbstractCharacter)
 | ||||
| 			//				if (((AbstractCharacter)target).isMoving())
 | ||||
| 			//					range+= 5;
 | ||||
| 
 | ||||
| 			return !(sl.distanceSquared(tl) > sqr(range)); | ||||
| 		}catch(Exception e){ | ||||
| 			Logger.error( e.toString()); | ||||
| 			return false; | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 	 | ||||
| 	public static boolean inRangeToAttack2D(Mob agent,AbstractWorldObject target){ | ||||
| 
 | ||||
| 		if (Float.isNaN(agent.getLoc().x)) | ||||
| 			return false; | ||||
| 
 | ||||
| 		try{ | ||||
| 			Vector3fImmutable sl = agent.getLoc(); | ||||
| 			Vector3fImmutable tl = target.getLoc(); | ||||
| 			 | ||||
| 			//add Hitbox's to range.
 | ||||
| 			float range = agent.getRange(); | ||||
| 			range += CombatManager.calcHitBox(target) + CombatManager.calcHitBox(agent); | ||||
| 			//if (target instanceof AbstractCharacter)
 | ||||
| 			//				if (((AbstractCharacter)target).isMoving())
 | ||||
| 			//					range+= 5;
 | ||||
| 
 | ||||
| 			return !(sl.distanceSquared2D(tl) > sqr(range)); | ||||
| 		}catch(Exception e){ | ||||
| 			Logger.error( e.toString()); | ||||
| 			return false; | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static void swingIsBlock(Mob agent,AbstractWorldObject target, int animation) { | ||||
| 
 | ||||
| 		if (!target.isAlive()) | ||||
| 			return; | ||||
| 
 | ||||
| 		TargetedActionMsg msg = new TargetedActionMsg(agent,animation, target, MBServerStatics.COMBAT_SEND_BLOCK); | ||||
| 
 | ||||
| 		if (target.getObjectType() == GameObjectType.PlayerCharacter) | ||||
| 			DispatchMessage.dispatchMsgToInterestArea(target, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true,false); | ||||
| 		else | ||||
| 			DispatchMessage.sendToAllInRange(agent,msg); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static void swingIsParry(Mob agent,AbstractWorldObject target, int animation) { | ||||
| 
 | ||||
| 		if (!target.isAlive()) | ||||
| 			return; | ||||
| 
 | ||||
| 		TargetedActionMsg msg = new TargetedActionMsg(agent,animation, target,  MBServerStatics.COMBAT_SEND_PARRY); | ||||
| 
 | ||||
| 		if (target.getObjectType() == GameObjectType.PlayerCharacter) | ||||
| 			DispatchMessage.dispatchMsgToInterestArea(target, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true,false); | ||||
| 		else | ||||
| 			DispatchMessage.sendToAllInRange(agent,msg); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static void swingIsDodge(Mob agent,AbstractWorldObject target, int animation) { | ||||
| 
 | ||||
| 		if (!target.isAlive()) | ||||
| 			return; | ||||
| 
 | ||||
| 		TargetedActionMsg msg = new TargetedActionMsg(agent,animation, target, MBServerStatics.COMBAT_SEND_DODGE); | ||||
| 
 | ||||
| 		if (target.getObjectType() == GameObjectType.PlayerCharacter) | ||||
| 			DispatchMessage.dispatchMsgToInterestArea(target, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true,false); | ||||
| 		else | ||||
| 			DispatchMessage.sendToAllInRange(agent,msg); | ||||
| 	} | ||||
| 
 | ||||
| 	public static void swingIsDamage(Mob agent,AbstractWorldObject target, float damage, int animation){ | ||||
| 		float trueDamage = 0; | ||||
| 
 | ||||
| 		if (!target.isAlive()) | ||||
| 			return; | ||||
| 
 | ||||
| 		if (AbstractWorldObject.IsAbstractCharacter(target)) | ||||
| 			trueDamage = ((AbstractCharacter) target).modifyHealth(-damage, agent, false); | ||||
| 		else if (target.getObjectType() == GameObjectType.Building) | ||||
| 			trueDamage = ((Building) target).modifyHealth(-damage, agent); | ||||
| 
 | ||||
| 		//Don't send 0 damage kay thanx.
 | ||||
| 
 | ||||
| 		if (trueDamage == 0) | ||||
| 			return; | ||||
| 
 | ||||
| 		TargetedActionMsg msg = new TargetedActionMsg(agent,target, damage, animation); | ||||
| 
 | ||||
| 		if (target.getObjectType() == GameObjectType.PlayerCharacter) | ||||
| 			DispatchMessage.dispatchMsgToInterestArea(target, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true,false); | ||||
| 		else | ||||
| 			DispatchMessage.sendToAllInRange(agent,msg); | ||||
| 
 | ||||
| 		//check damage shields
 | ||||
| 		if(AbstractWorldObject.IsAbstractCharacter(target) && target.isAlive() && target.getObjectType() != GameObjectType.Mob) | ||||
| 			CombatManager.handleDamageShields(agent,(AbstractCharacter)target, damage); | ||||
| 	} | ||||
| 
 | ||||
| 	public static boolean canSwing(Mob agent) { | ||||
| 		return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned, SourceType.None)); | ||||
| 	} | ||||
| 
 | ||||
| 	public static void swingIsMiss(Mob agent,AbstractWorldObject target, int animation) { | ||||
| 
 | ||||
| 		TargetedActionMsg msg = new TargetedActionMsg(agent,target, 0f, animation); | ||||
| 
 | ||||
| 		if (target.getObjectType() == GameObjectType.PlayerCharacter) | ||||
| 			DispatchMessage.dispatchMsgToInterestArea(target, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true,false); | ||||
| 		else | ||||
| 			DispatchMessage.sendToAllInRange(agent,msg); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static boolean triggerDefense(Mob agent, AbstractWorldObject target) { | ||||
| 		int defenseScore = 0; | ||||
| 		int attackScore = agent.getAtrHandOne(); | ||||
| 		switch (target.getObjectType()) { | ||||
| 		case PlayerCharacter: | ||||
| 			defenseScore = ((AbstractCharacter) target).getDefenseRating(); | ||||
| 			break; | ||||
| 		case Mob: | ||||
| 
 | ||||
| 			Mob mob = (Mob)target; | ||||
| 			if (mob.isSiege()) | ||||
| 				defenseScore = attackScore; | ||||
| 			break; | ||||
| 		case Building: | ||||
| 			return false; | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		int hitChance; | ||||
| 		if (attackScore > defenseScore || defenseScore == 0) | ||||
| 			hitChance = 94; | ||||
| 		else if (attackScore == defenseScore && target.getObjectType() == GameObjectType.Mob) | ||||
| 			hitChance = 10; | ||||
| 		else { | ||||
| 			float dif = attackScore / defenseScore; | ||||
| 			if (dif <= 0.8f) | ||||
| 				hitChance = 4; | ||||
| 			else | ||||
| 				hitChance = ((int)(450 * (dif - 0.8f)) + 4); | ||||
| 			if (target.getObjectType() == GameObjectType.Building) | ||||
| 				hitChance = 100; | ||||
| 		} | ||||
| 		return ThreadLocalRandom.current().nextInt(100) > hitChance; | ||||
| 	} | ||||
| 
 | ||||
| 	public static boolean triggerBlock(Mob agent,AbstractWorldObject ac) { | ||||
| 		return triggerPassive(agent,ac, "Block"); | ||||
| 	} | ||||
| 
 | ||||
| 	public static boolean triggerParry(Mob agent,AbstractWorldObject ac) { | ||||
| 		return triggerPassive(agent,ac, "Parry"); | ||||
| 	} | ||||
| 
 | ||||
| 	public static boolean triggerDodge(Mob agent,AbstractWorldObject ac) { | ||||
| 		return triggerPassive(agent,ac, "Dodge"); | ||||
| 	} | ||||
| 
 | ||||
| 	public static boolean triggerPassive(Mob agent,AbstractWorldObject ac, String type) { | ||||
| 		float chance = 0; | ||||
| 		if (AbstractWorldObject.IsAbstractCharacter(ac)) | ||||
| 			chance = ((AbstractCharacter)ac).getPassiveChance(type, agent.getLevel(), true); | ||||
| 
 | ||||
| 		if (chance > 75f) | ||||
| 			chance = 75f; | ||||
| 		if (agent.isSiege() && AbstractWorldObject.IsAbstractCharacter(ac)) | ||||
| 			chance = 100; | ||||
| 
 | ||||
| 		return ThreadLocalRandom.current().nextInt(100) < chance; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public static void combatCycle(Mob agent,AbstractWorldObject target, boolean mainHand, ItemBase wb) { | ||||
| 
 | ||||
| 		if (!agent.isAlive() || !target.isAlive()) return; | ||||
| 
 | ||||
| 		if (target.getObjectType() == GameObjectType.PlayerCharacter) | ||||
| 			if (!((PlayerCharacter)target).isActive()) | ||||
| 				return; | ||||
| 
 | ||||
| 		int anim = 75; | ||||
| 		float speed = 30f; | ||||
| 		if (mainHand) | ||||
| 			speed = agent.getSpeedHandOne(); | ||||
| 		else | ||||
| 			speed = agent.getSpeedHandTwo(); | ||||
| 
 | ||||
| 		DamageType dt = DamageType.Crush; | ||||
| 		if (agent.isSiege()) | ||||
| 			dt = DamageType.Siege; | ||||
| 		if (wb != null) { | ||||
| 			anim = CombatManager.getSwingAnimation(wb, null,mainHand); | ||||
| 			dt = wb.getDamageType(); | ||||
| 		} else if (!mainHand) | ||||
| 			return; | ||||
| 		Resists res = null; | ||||
| 		PlayerBonuses bonus = null; | ||||
| 		switch(target.getObjectType()){ | ||||
| 		case Building: | ||||
| 			res = ((Building)target).getResists(); | ||||
| 			break; | ||||
| 		case PlayerCharacter: | ||||
| 			res = ((PlayerCharacter)target).getResists(); | ||||
| 			bonus = ((PlayerCharacter)target).getBonuses(); | ||||
| 			break; | ||||
| 		case Mob: | ||||
| 			Mob mob = (Mob)target; | ||||
| 			res = mob.getResists(); | ||||
| 			bonus = ((Mob)target).getBonuses(); | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		//must not be immune to all or immune to attack
 | ||||
| 
 | ||||
| 		if (bonus != null && !bonus.getBool(ModType.NoMod, SourceType.ImmuneToAttack)) | ||||
| 			if (res != null &&(res.immuneToAll() || res.immuneToAttacks() || res.immuneTo(dt))) | ||||
| 				return; | ||||
| 
 | ||||
| 		int passiveAnim =  CombatManager.getSwingAnimation(wb, null,mainHand); | ||||
| 		if(canSwing(agent)) { | ||||
| 			if(triggerDefense(agent,target)) | ||||
| 				swingIsMiss(agent,target, passiveAnim); | ||||
| 			else if(triggerDodge(agent,target)) | ||||
| 				swingIsDodge(agent,target, passiveAnim); | ||||
| 			else if(triggerParry(agent,target)) | ||||
| 				swingIsParry(agent,target, passiveAnim); | ||||
| 			else if(triggerBlock(agent,target)) | ||||
| 				swingIsBlock(agent,target, passiveAnim); | ||||
| 			else | ||||
| 				swingIsDamage(agent,target, determineDamage(agent,target, mainHand, speed, dt), anim); | ||||
| 
 | ||||
| 			if (agent.getWeaponPower() != null) | ||||
| 				agent.getWeaponPower().attack(target, MBServerStatics.ONE_MINUTE); | ||||
| 		} | ||||
| 		 | ||||
| 		if (target.getObjectType().equals(GameObjectType.PlayerCharacter)){ | ||||
| 			PlayerCharacter player = (PlayerCharacter)target; | ||||
| 			if (player.getDebug(64)){ | ||||
| 				ChatManager.chatSayInfo(player, "Debug Combat: Mob UUID " + agent.getObjectUUID() + " || Building ID  = " + agent.getBuildingID() + " || Floor = " + agent.getInFloorID() + " || Level = " + agent.getInBuilding() );//combat debug
 | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		//SIEGE MONSTERS DO NOT ATTACK GUARDSs
 | ||||
| 		if (target.getObjectType() == GameObjectType.Mob) | ||||
| 			if (((Mob)target).isSiege()) | ||||
| 				return; | ||||
| 
 | ||||
| 		//handle the retaliate
 | ||||
| 
 | ||||
| 		if (AbstractWorldObject.IsAbstractCharacter(target)) | ||||
| 			CombatManager.handleRetaliate((AbstractCharacter)target, agent); | ||||
| 
 | ||||
| 		if (target.getObjectType() == GameObjectType.Mob){ | ||||
| 			Mob targetMob = (Mob)target; | ||||
| 			if (targetMob.isSiege()) | ||||
| 				return; | ||||
| 
 | ||||
| 			if (System.currentTimeMillis() < targetMob.getTimeStamp("CallForHelp")) | ||||
| 				return; | ||||
| 			CallForHelp(targetMob); | ||||
| 			targetMob.getTimestamps().put("CallForHelp", System.currentTimeMillis() + 60000); | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static void CallForHelp(Mob aiAgent) { | ||||
| 
 | ||||
| 		Set<Mob> zoneMobs = aiAgent.getParentZone().zoneMobSet; | ||||
| 
 | ||||
| 
 | ||||
| 		AbstractWorldObject target = aiAgent.getCombatTarget(); | ||||
| 		if (target == null) { | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		int count = 0; | ||||
| 		for (Mob mob: zoneMobs){ | ||||
| 			if (!mob.isAlive()) | ||||
| 				continue; | ||||
| 			if (mob.isSiege() || mob.isPet() || !Enum.MobFlagType.AGGRESSIVE.elementOf(mob.getMobBase().getFlags())) | ||||
| 				continue; | ||||
| 			if (count == 5) | ||||
| 				continue; | ||||
| 
 | ||||
| 
 | ||||
| 			if (mob.getCombatTarget() != null) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if (!aiAgent.isPlayerGuard() && mob.isPlayerGuard()) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if (aiAgent.isPlayerGuard() && !mob.isPlayerGuard() ) | ||||
| 				continue; | ||||
| 
 | ||||
| 			if (target.getObjectType() == GameObjectType.PlayerCharacter){ | ||||
| 
 | ||||
| 				if (!MovementUtilities.inRangeToAggro(mob, (PlayerCharacter)target)) | ||||
| 					continue; | ||||
| 				count++; | ||||
| 
 | ||||
| 			}else{ | ||||
| 
 | ||||
| 				if (count == 5) | ||||
| 					continue; | ||||
| 
 | ||||
| 				if (aiAgent.getLoc().distanceSquared2D(target.getLoc()) > sqr(aiAgent.getAggroRange())) | ||||
| 					continue; | ||||
| 
 | ||||
| 				count++; | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 			if (mob.getState() == STATE.Awake || mob.getState() == STATE.Patrol){ | ||||
| 				mob.setCombatTarget(target); | ||||
| 				mob.setState(STATE.Attack); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static float determineDamage(Mob agent,AbstractWorldObject target, boolean mainHand, float speed, DamageType dt) { | ||||
| 
 | ||||
| 		float min = (mainHand) ? agent.getMinDamageHandOne() : agent.getMinDamageHandTwo(); | ||||
| 		float max = (mainHand) ? agent.getMaxDamageHandOne() : agent.getMaxDamageHandTwo();; | ||||
| 
 | ||||
| 		float range = max - min; | ||||
| 		float damage = min + ((ThreadLocalRandom.current().nextFloat()*range)+(ThreadLocalRandom.current().nextFloat()*range))/2; | ||||
| 
 | ||||
| 		if (AbstractWorldObject.IsAbstractCharacter(target)) | ||||
| 			if (((AbstractCharacter)target).isSit()) | ||||
| 				damage *= 2.5f; //increase damage if sitting
 | ||||
| 
 | ||||
| 		if (AbstractWorldObject.IsAbstractCharacter(target)) | ||||
| 			return ((AbstractCharacter)target).getResists().getResistedDamage(agent,(AbstractCharacter)target, dt, damage, 0); | ||||
| 
 | ||||
| 		if (target.getObjectType() == GameObjectType.Building){ | ||||
| 			Building building = (Building)target; | ||||
| 			Resists resists = building.getResists(); | ||||
| 			return damage * (1 - (resists.getResist(dt, 0) / 100)); | ||||
| 		} | ||||
| 
 | ||||
| 		return damage; | ||||
| 
 | ||||
| 	} | ||||
| 	 | ||||
| 	public static boolean RunAIRandom(){ | ||||
| 		int random = ThreadLocalRandom.current().nextInt(4); | ||||
| 		 | ||||
| 		if (random == 0) | ||||
| 			return true; | ||||
| 		 | ||||
| 		return false; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,303 @@@@ -0,0 +1,303 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.ai.utilities; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.Enum.ModType; | ||||
| import engine.Enum.SourceType; | ||||
| import engine.exception.MsgSendException; | ||||
| import engine.gameManager.MovementManager; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.net.client.msg.MoveToPointMsg; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.concurrent.ThreadLocalRandom; | ||||
| 
 | ||||
| import static engine.math.FastMath.sqr; | ||||
| import static engine.math.FastMath.sqrt; | ||||
| 
 | ||||
| public class MovementUtilities { | ||||
| 
 | ||||
| 
 | ||||
| 	public static boolean inRangeOfBindLocation(Mob agent){ | ||||
| 		 | ||||
| 		 | ||||
| 		 | ||||
| 		if (agent.isPlayerGuard()){ | ||||
| 			 | ||||
| 			Mob guardCaptain = null; | ||||
| 			if (agent.getContract() != null) | ||||
| 				guardCaptain = agent; | ||||
| 			else | ||||
| 		guardCaptain = (Mob) agent.getNpcOwner(); | ||||
| 			 | ||||
| 			if (guardCaptain != null){ | ||||
| 				Building barracks = guardCaptain.getBuilding(); | ||||
| 				 | ||||
| 				if (barracks != null){ | ||||
| 					City city = barracks.getCity(); | ||||
| 					 | ||||
| 					if (city != null){ | ||||
| 						Building tol = city.getTOL(); | ||||
| 						 | ||||
| 						//Guards recall distance = 814.
 | ||||
| 						if (tol != null){ | ||||
| 							if (agent.getLoc().distanceSquared2D(tol.getLoc()) > sqr(Enum.CityBoundsType.SIEGE.extents)) { | ||||
| 					                return false; | ||||
| 					            } | ||||
| 						} | ||||
| 						 | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			 | ||||
| 			return true; | ||||
| 		} | ||||
| 
 | ||||
| 		Vector3fImmutable sl = new Vector3fImmutable(agent.getLoc().getX(), 0, agent.getLoc().getZ()); | ||||
| 		Vector3fImmutable tl = new Vector3fImmutable(agent.getTrueBindLoc().x,0,agent.getTrueBindLoc().z); | ||||
| 
 | ||||
| 		float distanceSquaredToTarget = sl.distanceSquared2D(tl); //distance to center of target
 | ||||
| 		float zoneRange = 250; | ||||
| 
 | ||||
| 		if (agent.getParentZone() != null){ | ||||
| 			if (agent.getParentZone().getBounds() != null) | ||||
| 				zoneRange = agent.getParentZone().getBounds().getHalfExtents().x * 2; | ||||
| 		} | ||||
| 
 | ||||
| 		if (zoneRange > 300) | ||||
| 			zoneRange = 300; | ||||
| 		 | ||||
| 		if (agent.getSpawnRadius() > zoneRange) | ||||
| 			zoneRange = agent.getSpawnRadius(); | ||||
| 		 | ||||
| 
 | ||||
| 		return distanceSquaredToTarget < sqr(MBServerStatics.AI_DROP_AGGRO_RANGE + zoneRange); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static boolean inRangeToAggro(Mob agent,PlayerCharacter target){ | ||||
| 
 | ||||
| 		Vector3fImmutable sl = agent.getLoc(); | ||||
| 		Vector3fImmutable tl =target.getLoc(); | ||||
| 
 | ||||
| 		float distanceSquaredToTarget = sl.distanceSquared2D(tl) - sqr(agent.calcHitBox() + target.calcHitBox()); //distance to center of target
 | ||||
| 		float range = MBServerStatics.AI_BASE_AGGRO_RANGE; | ||||
| 
 | ||||
| 		if (agent.isPlayerGuard()) | ||||
| 			range = 150; | ||||
| 
 | ||||
| 		return distanceSquaredToTarget < sqr(range); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static boolean inRangeDropAggro(Mob agent,PlayerCharacter target){ | ||||
| 
 | ||||
| 		Vector3fImmutable sl = agent.getLoc(); | ||||
| 		Vector3fImmutable tl = target.getLoc(); | ||||
| 
 | ||||
| 		float distanceSquaredToTarget = sl.distanceSquared2D(tl) - sqr(agent.calcHitBox() + target.calcHitBox()); //distance to center of target
 | ||||
| 
 | ||||
| 		float range = agent.getRange() + 150; | ||||
| 
 | ||||
| 		if (range > 200) | ||||
| 			range = 200; | ||||
| 
 | ||||
| 
 | ||||
| 		return distanceSquaredToTarget < sqr(range); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static Vector3fImmutable GetMoveLocation(Mob aiAgent, AbstractCharacter aggroTarget){ | ||||
| 
 | ||||
| 		// Player isnt moving and neither is mob.  Just return
 | ||||
| 		// the mobile's current location.  Ain't goin nowhere!
 | ||||
| 		// *** Refactor: Check to ensure methods calling us
 | ||||
| 		// all don't sent move messages when not moving.
 | ||||
| 
 | ||||
| 		if ((aggroTarget.isMoving() == false)) | ||||
| 			return aggroTarget.getLoc(); | ||||
| 
 | ||||
| 		if (aggroTarget.getEndLoc().x != 0){ | ||||
| 
 | ||||
| 			float aggroTargetDistanceSquared = aggroTarget.getLoc().distanceSquared2D(aggroTarget.getEndLoc()); | ||||
| 			float aiAgentDistanceSquared = aiAgent.getLoc().distanceSquared2D(aggroTarget.getEndLoc()); | ||||
| 
 | ||||
| 			if (aiAgentDistanceSquared >= aggroTargetDistanceSquared) | ||||
| 				return aggroTarget.getEndLoc(); | ||||
| 			else{ | ||||
| 				float distanceToMove = sqrt(aggroTargetDistanceSquared + aiAgentDistanceSquared) *.5f; | ||||
| 
 | ||||
| 				return aggroTarget.getFaceDir().scaleAdd(distanceToMove, aggroTarget.getLoc()); | ||||
| 
 | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		// One of us is moving so let's calculate our destination loc for this
 | ||||
| 		// simulation frame.  We will simply project our position onto the
 | ||||
| 		// character's movement vector and return the closest point.
 | ||||
| 
 | ||||
| 		return aiAgent.getLoc().ClosestPointOnLine(aggroTarget.getLoc(), aggroTarget.getEndLoc()); | ||||
| 	} | ||||
| 
 | ||||
| 	public static void moveToLocation(Mob agent,Vector3fImmutable newLocation, float offset){ | ||||
| 		try { | ||||
| 			 | ||||
| 			//don't move farther than 30 units from player.
 | ||||
| 			if (offset > 30) | ||||
| 				offset = 30; | ||||
| 			Vector3fImmutable newLoc = Vector3fImmutable.getRandomPointInCircle(newLocation, offset); | ||||
| 
 | ||||
| 
 | ||||
| 			agent.setFaceDir(newLoc.subtract2D(agent.getLoc()).normalize()); | ||||
| 		 | ||||
| 			aiMove(agent,newLoc,false); | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	public static boolean canMove(Mob agent) { | ||||
| 		if (agent.getMobBase() != null && Enum.MobFlagType.SENTINEL.elementOf(agent.getMobBase().getFlags())) | ||||
| 			return false; | ||||
| 
 | ||||
| 		return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned,SourceType.None) && !agent.getBonuses().getBool(ModType.CannotMove, SourceType.None)); | ||||
| 	} | ||||
| 
 | ||||
| 	public static Vector3fImmutable randomPatrolLocation(Mob agent,Vector3fImmutable center, float radius){ | ||||
| 
 | ||||
| 		//Determing where I want to move.
 | ||||
| 		return new Vector3fImmutable((center.x - radius) + ((ThreadLocalRandom.current().nextFloat()+.1f*2)*radius), | ||||
| 				center.y, | ||||
| 				(center.z - radius) + ((ThreadLocalRandom.current().nextFloat()+.1f *2)*radius)); | ||||
| 	} | ||||
| 	public static Long estimateMovementTime(Mob agent) { | ||||
| 		if(agent.getEndLoc().x == 0 && agent.getEndLoc().y == 0) | ||||
| 			return 0L; | ||||
| 
 | ||||
| 		return (long) ((agent.getLoc().distance2D(agent.getEndLoc())*1000)/agent.getSpeed()); | ||||
| 	} | ||||
| 
 | ||||
| 	public static void aiMove(Mob agent,Vector3fImmutable vect, boolean isWalking) { | ||||
| 
 | ||||
| 		//update our walk/run state.
 | ||||
| 		if (isWalking && !agent.isWalk()){ | ||||
| 			agent.setWalkMode(true); | ||||
| 			MovementManager.sendRWSSMsg(agent); | ||||
| 		}else if(!isWalking && agent.isWalk()){ | ||||
| 			agent.setWalkMode(false); | ||||
| 			MovementManager.sendRWSSMsg(agent); | ||||
| 		} | ||||
| 
 | ||||
| 		MoveToPointMsg msg = new MoveToPointMsg(); | ||||
| 
 | ||||
| 
 | ||||
| //		Regions currentRegion = Mob.InsideBuildingRegion(agent);
 | ||||
| //
 | ||||
| //		if (currentRegion != null){
 | ||||
| //
 | ||||
| //
 | ||||
| //			if (currentRegion.isGroundLevel()){
 | ||||
| //				agent.setInBuilding(0);
 | ||||
| //				agent.setInFloorID(-1);
 | ||||
| //			}else{
 | ||||
| //				agent.setInBuilding(currentRegion.getLevel());
 | ||||
| //				agent.setInFloorID(currentRegion.getRoom());
 | ||||
| //			}
 | ||||
| //		}else{
 | ||||
| //			agent.setInBuilding(-1);
 | ||||
| //			agent.setInFloorID(-1);
 | ||||
| //			agent.setInBuildingID(0);
 | ||||
| //		}
 | ||||
| //		agent.setLastRegion(currentRegion);
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		Vector3fImmutable startLoc = null; | ||||
| 		Vector3fImmutable endLoc = null; | ||||
| 
 | ||||
| //		if (agent.getLastRegion() != null){
 | ||||
| //			Building inBuilding = Building.getBuildingFromCache(agent.getInBuildingID());
 | ||||
| //			if (inBuilding != null){
 | ||||
| //				startLoc = ZoneManager.convertWorldToLocal(inBuilding, agent.getLoc());
 | ||||
| //				endLoc = ZoneManager.convertWorldToLocal(inBuilding, vect);
 | ||||
| //			}
 | ||||
| //		}else{
 | ||||
| //			agent.setBuildingID(0);
 | ||||
| //			agent.setInBuildingID(0);
 | ||||
| //			startLoc = agent.getLoc();
 | ||||
| //			endLoc = vect;
 | ||||
| //		}
 | ||||
| 		 | ||||
| 		startLoc = agent.getLoc(); | ||||
| 		endLoc = vect; | ||||
| 
 | ||||
| 		msg.setSourceType(GameObjectType.Mob.ordinal()); | ||||
| 		msg.setSourceID(agent.getObjectUUID()); | ||||
| 		msg.setStartCoord(startLoc); | ||||
| 		msg.setEndCoord(endLoc); | ||||
| 		msg.setUnknown01(-1); | ||||
| 		msg.setInBuilding(-1); | ||||
| 		msg.setTargetType(0); | ||||
| 		msg.setTargetID(0); | ||||
| 
 | ||||
| 
 | ||||
| 		try { | ||||
| 			MovementManager.movement(msg, agent); | ||||
| 		} catch (MsgSendException e) { | ||||
| 			// TODO Figure out how we want to handle the msg send exception
 | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public static Vector3fImmutable GetDestinationToCharacter(Mob aiAgent, AbstractCharacter character){ | ||||
| 		 | ||||
| 		if (!character.isMoving()) | ||||
| 			return character.getLoc(); | ||||
| 			 | ||||
| 		 | ||||
| 		float agentDistanceEndLoc = aiAgent.getLoc().distanceSquared2D(character.getEndLoc()); | ||||
| 		float characterDistanceEndLoc = character.getLoc().distanceSquared2D(character.getEndLoc()); | ||||
| 		 | ||||
| 		if (agentDistanceEndLoc > characterDistanceEndLoc) | ||||
| 			return character.getEndLoc(); | ||||
| 		 | ||||
| 		return character.getLoc(); | ||||
| 	} | ||||
| 	 | ||||
| 	public static boolean updateMovementToCharacter(Mob aiAgent, AbstractCharacter aggroTarget){ | ||||
| 		 | ||||
| 		if (aiAgent.destination.equals(Vector3fImmutable.ZERO)) | ||||
| 			return true; | ||||
| 		 | ||||
| 		if (!aiAgent.isMoving()) | ||||
| 			return true; | ||||
| 		 | ||||
| 		 | ||||
| 		 | ||||
| 		 | ||||
| 		if (aggroTarget.isMoving()){ | ||||
| 		if (!aiAgent.destination.equals(aggroTarget.getEndLoc()) && !aiAgent.destination.equals(aggroTarget.getLoc())) | ||||
| 			return true; | ||||
| 		}else{ | ||||
| 			if (aiAgent.destination.equals(aggroTarget.getLoc())) | ||||
| 				return false; | ||||
| 		} | ||||
| 		 | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,15 @@@@ -0,0 +1,15 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.ai.utilities; | ||||
| 
 | ||||
| public class PowerUtilities { | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,174 @@@@ -0,0 +1,174 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.core; | ||||
| 
 | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| /** | ||||
|  *  | ||||
|  */ | ||||
| public abstract class ControlledRunnable implements Runnable { | ||||
| 	protected boolean runCmd = false; | ||||
| 	protected boolean runStatus = false; | ||||
| 	private Thread thisThread; | ||||
| 	private final String threadName; | ||||
| 
 | ||||
| 	public ControlledRunnable(String threadName) { | ||||
| 		super(); | ||||
| 		this.threadName = threadName; | ||||
| 		ControlledRunnable.runnables.add(this); | ||||
| 	} | ||||
| 
 | ||||
| 	/* | ||||
| 	 * Main loop | ||||
| 	 */ | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This is the method called when ControlledRunnable.thisThread.start() is | ||||
| 	 * called. | ||||
| 	 */ | ||||
| 	@Override | ||||
| 	public void run() { | ||||
| 		if (this._preRun() == false) { | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		this.runStatus = true; | ||||
| 
 | ||||
| 		if (this._Run() == false) { | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		if (this._postRun() == false) { | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		this.runStatus = false; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * _preRun() is called prior to the call to _Run(), but after _startup() | ||||
| 	 *  | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	protected abstract boolean _preRun(); | ||||
| 
 | ||||
| 	/** | ||||
| 	 * _Run() is called after _startup() and contains should contain the main | ||||
| 	 * loop. | ||||
| 	 *  | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	protected abstract boolean _Run(); | ||||
| 
 | ||||
| 	/** | ||||
| 	 * _postRun() is called after _Run() exits, not necessarily before | ||||
| 	 * _shutdown() | ||||
| 	 *  | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	protected abstract boolean _postRun(); | ||||
| 
 | ||||
| 	/* | ||||
| 	 * Control | ||||
| 	 */ | ||||
| 
 | ||||
| 	/** | ||||
| 	 * startup() initializes the internal thread, sets the runCMD to true, and | ||||
| 	 * calls _startup() prior to starting of the internal Thread. | ||||
| 	 */ | ||||
| 	public void startup() { | ||||
| 
 | ||||
| 		this.thisThread = new Thread(this, this.threadName); | ||||
| 		this.runCmd = true; | ||||
| 		this._startup(); | ||||
| 		this.thisThread.start(); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This method is called just before ControlledRunnable.thisThread.start() | ||||
| 	 * is called. | ||||
| 	 */ | ||||
| 	protected abstract void _startup(); | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This method is called to request a shutdown of the runnable. | ||||
| 	 */ | ||||
| 	public void shutdown() { | ||||
| 		this.runCmd = false; | ||||
| 		this._shutdown(); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * This method is called just after ControlledRunnable.runCmd is set to | ||||
| 	 * False. | ||||
| 	 */ | ||||
| 	protected abstract void _shutdown(); | ||||
| 
 | ||||
| 	/* | ||||
| 	 * Getters n setters | ||||
| 	 */ | ||||
| 	public boolean getRunCmd() { | ||||
| 		return runCmd; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean getRunStatus() { | ||||
| 		return runStatus; | ||||
| 	} | ||||
| 
 | ||||
| 	/* | ||||
| 	 * Blockers | ||||
| 	 */ | ||||
| 	public void blockTillRunStatus(boolean status) { | ||||
| 		while (this.runStatus != status) { | ||||
| 			try { | ||||
| 				System.out.println("BLOCKING"); | ||||
| 				Thread.sleep(25L); | ||||
| 			} catch (InterruptedException e) { | ||||
| 				Logger.debug( e.getMessage()); | ||||
| 
 | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @return the thisThread | ||||
| 	 */ | ||||
| 	protected Thread getThisThread() { | ||||
| 		return thisThread; | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * @return the threadName | ||||
| 	 */ | ||||
| 	public String getThreadName() { | ||||
| 		return threadName; | ||||
| 	} | ||||
| 
 | ||||
| 	/* | ||||
| 	 * Instance monitoring and tools | ||||
| 	 */ | ||||
| 
 | ||||
| 	// Runnable tracking
 | ||||
| 	private static final ArrayList<ControlledRunnable> runnables = new ArrayList<>(); | ||||
| 
 | ||||
| 	public static void shutdownAllRunnables() { | ||||
| 		for (ControlledRunnable cr : ControlledRunnable.runnables) { | ||||
| 			//Use Direct logging since JobManager is a runnable.
 | ||||
|             Logger.info("ControlledRunnable", | ||||
| 					"Sending Shutdown cmd to: " + cr.threadName); | ||||
| 			cr.shutdown(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,383 @@@@ -0,0 +1,383 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.archive; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.objects.Bane; | ||||
| import engine.objects.City; | ||||
| import engine.workthreads.WarehousePushThread; | ||||
| import org.joda.time.DateTime; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.*; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.concurrent.LinkedBlockingQueue; | ||||
| 
 | ||||
| import static engine.Enum.RecordEventType; | ||||
| 
 | ||||
| public class BaneRecord extends DataRecord { | ||||
| 
 | ||||
| 	private static final LinkedBlockingQueue<BaneRecord> recordPool = new LinkedBlockingQueue<>(); | ||||
| 	private RecordEventType eventType; | ||||
| 	private String cityHash; | ||||
| 	private String cityName; | ||||
| 	private String cityGuildHash; | ||||
| 	private String cityNationHash; | ||||
| 	private String baneDropperHash; | ||||
| 	private String baneGuildHash; | ||||
| 	private String baneNationHash; | ||||
| 	private DateTime baneLiveTime; | ||||
| 	private DateTime baneDropTime; | ||||
| 
 | ||||
| 	private BaneRecord(Bane bane) { | ||||
| 		this.recordType = Enum.DataRecordType.BANE; | ||||
| 		this.eventType = RecordEventType.PENDING; | ||||
| 	} | ||||
| 
 | ||||
| 	public static BaneRecord borrow(Bane bane, RecordEventType eventType) { | ||||
| 		BaneRecord baneRecord; | ||||
| 
 | ||||
| 		baneRecord = recordPool.poll(); | ||||
| 
 | ||||
| 		if (baneRecord == null) { | ||||
| 			baneRecord = new BaneRecord(bane); | ||||
| 			baneRecord.eventType = eventType; | ||||
| 		} | ||||
| 		else { | ||||
| 			baneRecord.recordType = Enum.DataRecordType.BANE; | ||||
| 			baneRecord.eventType = eventType; | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		baneRecord.cityHash = bane.getCity().getHash(); | ||||
| 		baneRecord.cityName = bane.getCity().getCityName(); | ||||
| 		baneRecord.cityGuildHash = bane.getCity().getGuild().getHash(); | ||||
| 		baneRecord.cityNationHash = bane.getCity().getGuild().getNation().getHash(); | ||||
| 
 | ||||
| 
 | ||||
| 		if (bane.getOwner() == null) { | ||||
| 			baneRecord.baneDropperHash = "ERRANT"; | ||||
| 			baneRecord.baneGuildHash = "ERRANT"; | ||||
| 			baneRecord.baneNationHash = "ERRANT"; | ||||
| 		} | ||||
| 		else { | ||||
| 			baneRecord.baneDropperHash = DataWarehouse.hasher.encrypt(bane.getOwner().getObjectUUID());  // getPlayerCharacter didn't check hash first?  OMFG
 | ||||
| 
 | ||||
| 
 | ||||
| 			baneRecord.baneGuildHash = bane.getOwner().getGuild().getHash(); | ||||
| 			baneRecord.baneNationHash = bane.getOwner().getGuild().getNation().getHash(); | ||||
| 
 | ||||
| 
 | ||||
| 			baneRecord.baneLiveTime = bane.getLiveDate(); | ||||
| 			baneRecord.baneDropTime = bane.getPlacementDate(); | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 		return baneRecord; | ||||
| 	} | ||||
| 
 | ||||
| 	public static PreparedStatement buildBanePushStatement(Connection connection, ResultSet rs) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "INSERT INTO `warehouse_banehistory` (`event_number`, `city_id`, `city_name`, `char_id`, `offGuild_id`, `offNat_id`, `defGuild_id`, `defNat_id`, `dropDatetime`, `liveDateTime`, `resolution`) VALUES(?,?,?,?,?,?,?,?,?,?,?)"; | ||||
| 		java.util.Date sqlDateTime; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
| 		// Bind record data
 | ||||
| 
 | ||||
| 		outStatement.setInt(1, rs.getInt("event_number")); | ||||
| 		outStatement.setString(2, rs.getString("city_id")); | ||||
| 		outStatement.setString(3, rs.getString("city_name")); | ||||
| 		outStatement.setString(4, rs.getString("char_id")); | ||||
| 		outStatement.setString(5, rs.getString("offGuild_id")); | ||||
| 		outStatement.setString(6, rs.getString("offNat_id")); | ||||
| 		outStatement.setString(7, rs.getString("defGuild_id")); | ||||
| 		outStatement.setString(8, rs.getString("defNat_id")); | ||||
| 
 | ||||
| 		sqlDateTime = rs.getTimestamp("dropDatetime"); | ||||
| 
 | ||||
| 		if (sqlDateTime == null) | ||||
| 			outStatement.setNull(9, Types.DATE); | ||||
| 		else | ||||
| 			outStatement.setTimestamp(9, rs.getTimestamp("dropDatetime")); | ||||
| 
 | ||||
| 		sqlDateTime = rs.getTimestamp("dropDatetime"); | ||||
| 
 | ||||
| 		if (sqlDateTime == null) | ||||
| 			outStatement.setNull(10, Types.DATE); | ||||
| 		else | ||||
| 			outStatement.setTimestamp(10, rs.getTimestamp("liveDateTime")); | ||||
| 
 | ||||
| 		outStatement.setString(11, rs.getString("resolution")); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	public static PreparedStatement buildBaneQueryStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "SELECT * FROM `warehouse_banehistory` WHERE `event_number` > ?"; | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 		outStatement.setInt(1, WarehousePushThread.baneIndex); | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	public static DateTime getLastBaneDateTime(City city) { | ||||
| 
 | ||||
| 		DateTime outDateTime = null; | ||||
| 
 | ||||
| 		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = buildDateTimeQueryStatement(connection, city); | ||||
| 				ResultSet rs = statement.executeQuery()) { | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				outDateTime = new DateTime(rs.getTimestamp("endDatetime")); | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} | ||||
| 
 | ||||
| 		return outDateTime; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	private static PreparedStatement buildDateTimeQueryStatement (Connection connection, City city) throws SQLException { | ||||
| 		PreparedStatement outStatement; | ||||
| 		String queryString = "SELECT `endDatetime` FROM `warehouse_banehistory` WHERE `city_id` = ? ORDER BY `endDatetime` DESC LIMIT 1"; | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 		outStatement.setString(1, city.getHash()); | ||||
| 		return outStatement; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static void updateLiveDate(Bane bane, DateTime dateTime) { | ||||
| 
 | ||||
| 		if (bane == null) | ||||
| 			return; | ||||
| 
 | ||||
| 		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = buildUpdateLiveDateStatement(connection, bane, dateTime)) { | ||||
| 
 | ||||
| 			statement.execute(); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static PreparedStatement buildUpdateLiveDateStatement(Connection connection, Bane bane, DateTime dateTime) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "UPDATE `warehouse_banehistory` SET `liveDatetime` = ?, `dirty` = 1 WHERE `city_id` = ? AND `resolution` = 'PENDING'"; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 		outStatement.setTimestamp(1, new java.sql.Timestamp(dateTime.getMillis())); | ||||
| 		outStatement.setString(2, bane.getCity().getHash()); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	private static PreparedStatement buildUpdateResolutionStatement(Connection connection, Bane bane, RecordEventType eventType) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "UPDATE `warehouse_banehistory` SET `endDatetime` = ?, `resolution` = ?, `dirty` = 1 WHERE `city_id` = ? AND `resolution` = 'PENDING'"; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 		outStatement.setTimestamp(1, Timestamp.valueOf(LocalDateTime.now())); | ||||
| 		outStatement.setString(2, eventType.name()); | ||||
| 		outStatement.setString(3, bane.getCity().getHash()); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	public static void updateResolution(Bane bane, RecordEventType eventType) { | ||||
| 
 | ||||
| 		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = buildUpdateResolutionStatement(connection, bane, eventType)) { | ||||
| 
 | ||||
| 			statement.execute(); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.toString()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static String getBaneHistoryString() { | ||||
| 
 | ||||
| 		String outString; | ||||
| 		String queryString; | ||||
| 		String dividerString; | ||||
| 		String newLine = System.getProperty("line.separator"); | ||||
| 		outString = "[LUA_BANES() DATA WAREHOUSE]" + newLine; | ||||
| 		dividerString = "--------------------------------" + newLine; | ||||
| 		queryString = "CALL `baneHistory`()"; | ||||
| 
 | ||||
| 		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = connection.prepareCall(queryString); | ||||
| 				ResultSet rs = statement.executeQuery()) { | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				outString += "Magicbane unresolved banes: " + rs.getInt("PENDING") + '/' + rs.getInt("TOTAL") + newLine; | ||||
| 				outString += dividerString; | ||||
| 				outString += "Bane Resolution History" + newLine; | ||||
| 				outString += dividerString; | ||||
| 
 | ||||
| 				outString += "Destruction: " + rs.getInt("DESTROY") + newLine; | ||||
| 				outString += "Capture: " + rs.getInt("CAPTURE") + newLine; | ||||
| 				outString += "Defended: " + rs.getInt("DEFEND") + newLine; | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 		return outString; | ||||
| 	} | ||||
| 
 | ||||
| 	public static void updateDirtyRecords() { | ||||
| 
 | ||||
| 		String queryString = "SELECT * FROM `warehouse_banehistory` where `dirty` = 1"; | ||||
| 
 | ||||
| 		// Reset character delta
 | ||||
| 
 | ||||
| 		WarehousePushThread.baneDelta = 0; | ||||
| 
 | ||||
| 		try (Connection localConnection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = localConnection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); // Make this an updatable result set as we'll reset the dirty flag as we go along
 | ||||
| 				ResultSet rs = statement.executeQuery()) { | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				// Only update the index and dirty flag
 | ||||
| 				// if the remote database update succeeded
 | ||||
| 
 | ||||
| 				if (updateDirtyRecord(rs) == true) | ||||
| 					WarehousePushThread.baneDelta++; | ||||
| 				else | ||||
| 					continue; | ||||
| 
 | ||||
| 				// Reset the dirty flag in the local database
 | ||||
| 
 | ||||
| 				rs.updateInt("dirty", 0); | ||||
| 				rs.updateRow(); | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static boolean updateDirtyRecord(ResultSet rs) { | ||||
| 
 | ||||
| 		try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); | ||||
| 				PreparedStatement statement = buildUpdateDirtyStatement(remoteConnection, rs)) { | ||||
| 
 | ||||
| 			statement.execute(); | ||||
| 			return true; | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private static PreparedStatement buildUpdateDirtyStatement(Connection connection, ResultSet rs) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement; | ||||
| 		String queryString = "UPDATE `warehouse_banehistory` SET `liveDateTime` = ?, `endDateTime` = ?, `resolution` = ? WHERE `event_number` = ?"; | ||||
| 		java.util.Date sqlDateTime; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
| 		// Bind record data
 | ||||
| 
 | ||||
| 		sqlDateTime = rs.getTimestamp("liveDateTime"); | ||||
| 
 | ||||
| 		if (sqlDateTime == null) | ||||
| 			outStatement.setNull(1, Types.DATE); | ||||
| 		else | ||||
| 			outStatement.setTimestamp(1, rs.getTimestamp("liveDateTime")); | ||||
| 
 | ||||
| 		sqlDateTime = rs.getTimestamp("endDateTime"); | ||||
| 
 | ||||
| 		if (sqlDateTime == null) | ||||
| 			outStatement.setNull(2, Types.DATE); | ||||
| 		else | ||||
| 			outStatement.setTimestamp(2, rs.getTimestamp("endDateTime")); | ||||
| 
 | ||||
| 		outStatement.setString(3, rs.getString("resolution")); | ||||
| 		outStatement.setInt(4, rs.getInt("event_number")); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	void reset() { | ||||
| 		this.cityHash = null; | ||||
| 		this.cityGuildHash = null; | ||||
| 		this.cityNationHash = null; | ||||
| 		this.baneDropperHash = null; | ||||
| 		this.baneGuildHash = null; | ||||
| 		this.baneNationHash = null; | ||||
| 		this.baneLiveTime = null; | ||||
| 	} | ||||
| 
 | ||||
| 	public void release() { | ||||
| 		this.reset(); | ||||
| 		recordPool.add(this); | ||||
| 	} | ||||
| 
 | ||||
| 	public void write() { | ||||
| 
 | ||||
| 		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = buildBaneInsertStatement(connection)) { | ||||
| 
 | ||||
| 			statement.execute(); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	private PreparedStatement buildBaneInsertStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "INSERT INTO `warehouse_banehistory` (`city_id`, `city_name`, `char_id`, `offGuild_id`, `offNat_id`, `defGuild_id`, `defNat_id`, `dropDatetime`, `liveDateTime`, `resolution`) VALUES(?,?,?,?,?,?,?,?,?,?)"; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
| 		outStatement.setString(1, this.cityHash); | ||||
| 		outStatement.setString(2, this.cityName); | ||||
| 		outStatement.setString(3, this.baneDropperHash); | ||||
| 		outStatement.setString(4, this.baneGuildHash); | ||||
| 		outStatement.setString(5, this.baneNationHash); | ||||
| 		outStatement.setString(6, this.cityGuildHash); | ||||
| 		outStatement.setString(7, this.cityNationHash); | ||||
| 
 | ||||
| 		if (this.baneDropTime == null) | ||||
| 			outStatement.setNull(8, java.sql.Types.DATE); | ||||
| 		else | ||||
| 			outStatement.setTimestamp(8, new java.sql.Timestamp(this.baneDropTime.getMillis())); | ||||
| 
 | ||||
| 		if (this.baneLiveTime == null) | ||||
| 			outStatement.setNull(9, java.sql.Types.DATE); | ||||
| 		else | ||||
| 			outStatement.setTimestamp(9, new java.sql.Timestamp(this.baneLiveTime.getMillis())); | ||||
| 
 | ||||
| 		outStatement.setString(10, this.eventType.name()); | ||||
| 
 | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| } // END CLASS
 | ||||
| 
 | ||||
| @ -0,0 +1,284 @@@@ -0,0 +1,284 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.archive; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.objects.Guild; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.workthreads.WarehousePushThread; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.*; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.concurrent.LinkedBlockingQueue; | ||||
| 
 | ||||
| /* | ||||
|  * This class warehouses character creation events.  It also tracks | ||||
|  * updates to summary kills/death data and their promotion class. | ||||
|  */ | ||||
| public class CharacterRecord extends DataRecord { | ||||
| 
 | ||||
|     // Local object pool for class
 | ||||
| 
 | ||||
|     private static final LinkedBlockingQueue<CharacterRecord> recordPool = new LinkedBlockingQueue<>(); | ||||
| 
 | ||||
|     private PlayerCharacter player; | ||||
| 
 | ||||
|     private CharacterRecord(PlayerCharacter player) { | ||||
|         this.recordType = Enum.DataRecordType.CHARACTER; | ||||
|         this.player = player; | ||||
|     } | ||||
| 
 | ||||
|     public static CharacterRecord borrow(PlayerCharacter player) { | ||||
|         CharacterRecord characterRecord; | ||||
| 
 | ||||
|         characterRecord = recordPool.poll(); | ||||
| 
 | ||||
|         if (characterRecord == null) { | ||||
|             characterRecord = new CharacterRecord(player); | ||||
|         } | ||||
|         else { | ||||
|             characterRecord.recordType = Enum.DataRecordType.CHARACTER; | ||||
|             characterRecord.player = player; | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         return characterRecord; | ||||
|     } | ||||
| 
 | ||||
|     private static PreparedStatement buildCharacterInsertStatement(Connection connection, PlayerCharacter player) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "INSERT INTO `warehouse_characterhistory` (`char_id`, `char_fname`, `char_lname`, `baseClass`, `race`, `promoteClass`, `startingGuild`, `datetime`) VALUES(?,?,?,?,?,?,?,?)"; | ||||
|         Guild charGuild; | ||||
| 
 | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|         charGuild = player.getGuild(); | ||||
| 
 | ||||
|         // Bind character data
 | ||||
| 
 | ||||
|         outStatement.setString(1, DataWarehouse.hasher.encrypt(player.getObjectUUID())); | ||||
|         outStatement.setString(2, player.getFirstName()); | ||||
|         outStatement.setString(3, player.getLastName()); | ||||
|         outStatement.setInt(4, player.getBaseClassID()); | ||||
|         outStatement.setInt(5, player.getRaceID()); | ||||
|         outStatement.setInt(6, player.getPromotionClassID()); | ||||
|         outStatement.setString(7, DataWarehouse.hasher.encrypt(charGuild.getObjectUUID())); | ||||
|         outStatement.setTimestamp(8, Timestamp.valueOf(LocalDateTime.now())); | ||||
| 
 | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     public static PreparedStatement buildCharacterPushStatement(Connection connection, ResultSet rs) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "INSERT INTO `warehouse_characterhistory` (`event_number`, `char_id`, `char_fname`, `char_lname`, `baseClass`, `race`, `promoteClass`, `startingGuild`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?)"; | ||||
| 
 | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|         // Bind record data
 | ||||
| 
 | ||||
|         outStatement.setInt(1, rs.getInt("event_number")); | ||||
|         outStatement.setString(2, rs.getString("char_id")); | ||||
|         outStatement.setString(3, rs.getString("char_fname")); | ||||
|         outStatement.setString(4, rs.getString("char_lname")); | ||||
|         outStatement.setInt(5, rs.getInt("baseClass")); | ||||
|         outStatement.setInt(6, rs.getInt("race")); | ||||
|         outStatement.setInt(7, rs.getInt("promoteClass")); | ||||
|         outStatement.setString(8, rs.getString("startingGuild")); | ||||
|         outStatement.setTimestamp(9, rs.getTimestamp("datetime")); | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     public static PreparedStatement buildCharacterQueryStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "SELECT * FROM `warehouse_characterhistory` WHERE `event_number` > ?"; | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
|         outStatement.setInt(1, WarehousePushThread.charIndex); | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     public static void advanceKillCounter(PlayerCharacter player) { | ||||
| 
 | ||||
|         try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
|              PreparedStatement statement = buildKillCounterStatement(connection, player)) { | ||||
| 
 | ||||
|             statement.execute(); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error( e.toString()); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static PreparedStatement buildKillCounterStatement(Connection connection, PlayerCharacter player) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "UPDATE `warehouse_characterhistory` SET `kills` = `kills` +1, `dirty` = 1 WHERE `char_id` = ?"; | ||||
| 
 | ||||
|         if (player == null) | ||||
|             return outStatement; | ||||
| 
 | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
|         outStatement.setString(1, player.getHash()); | ||||
| 
 | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     public static void advanceDeathCounter(PlayerCharacter player) { | ||||
| 
 | ||||
|         try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
|              PreparedStatement statement = buildDeathCounterStatement(connection, player)) { | ||||
| 
 | ||||
|             statement.execute(); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error( e.toString()); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static PreparedStatement buildDeathCounterStatement(Connection connection, PlayerCharacter player) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "UPDATE `warehouse_characterhistory` SET `deaths` = `deaths` +1, `dirty` = 1 WHERE `char_id` = ?"; | ||||
| 
 | ||||
|         if (player == null) | ||||
|             return outStatement; | ||||
| 
 | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
|         outStatement.setString(1, player.getHash()); | ||||
| 
 | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     public static void updatePromotionClass(PlayerCharacter player) { | ||||
| 
 | ||||
|         try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
|              PreparedStatement statement = buildUpdatePromotionStatement(connection, player)) { | ||||
| 
 | ||||
|             statement.execute(); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error( e.toString()); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     private static PreparedStatement buildUpdatePromotionStatement(Connection connection, PlayerCharacter player) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "UPDATE `warehouse_characterhistory` SET `promoteClass` = ?, `dirty` = 1 WHERE `char_id` = ?"; | ||||
| 
 | ||||
|         if (player == null) | ||||
|             return outStatement; | ||||
| 
 | ||||
|         outStatement = connection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); | ||||
|         outStatement.setInt(1, player.getPromotionClassID()); | ||||
|         outStatement.setString(2, player.getHash()); | ||||
| 
 | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     public static void updateDirtyRecords() { | ||||
| 
 | ||||
|         String queryString = "SELECT * FROM `warehouse_characterhistory` where `dirty` = 1"; | ||||
| 
 | ||||
|         // Reset character delta
 | ||||
| 
 | ||||
|         WarehousePushThread.charDelta = 0; | ||||
| 
 | ||||
|         try (Connection localConnection = DataWarehouse.connectionPool.getConnection(); | ||||
|              PreparedStatement statement = localConnection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); // Make this an updatable result set as we'll reset the dirty flag as we go along
 | ||||
|              ResultSet rs = statement.executeQuery()) { | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
| 
 | ||||
|                 // Only update the index and dirty flag
 | ||||
|                 // if the remote database update succeeded
 | ||||
| 
 | ||||
|                 if (updateDirtyRecord(rs) == true) | ||||
|                     WarehousePushThread.charDelta++; | ||||
|                 else | ||||
|                     continue; | ||||
| 
 | ||||
|                 // Reset the dirty flag in the local database
 | ||||
| 
 | ||||
|                 rs.updateInt("dirty", 0); | ||||
|                 rs.updateRow(); | ||||
|             } | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private static boolean updateDirtyRecord(ResultSet rs) { | ||||
| 
 | ||||
|         try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); | ||||
|              PreparedStatement statement = buildUpdateDirtyStatement(remoteConnection, rs)) { | ||||
| 
 | ||||
|             statement.execute(); | ||||
|             return true; | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error(e.toString()); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private static PreparedStatement buildUpdateDirtyStatement(Connection connection, ResultSet rs) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement; | ||||
|         String queryString = "UPDATE `warehouse_characterhistory` SET `promoteClass` = ?, `kills` = ?, `deaths` = ? WHERE `char_id` = ?"; | ||||
| 
 | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|         // Bind record data
 | ||||
| 
 | ||||
|         outStatement.setInt(1, rs.getInt("promoteClass")); | ||||
|         outStatement.setInt(2, rs.getInt("kills")); | ||||
|         outStatement.setInt(3, rs.getInt("deaths")); | ||||
|         outStatement.setString(4, rs.getString("char_id")); | ||||
| 
 | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     void reset() { | ||||
|         this.player = null; | ||||
|     } | ||||
| 
 | ||||
|     public void release() { | ||||
|         this.reset(); | ||||
|         recordPool.add(this); | ||||
|     } | ||||
| 
 | ||||
|     public void write() { | ||||
| 
 | ||||
|         try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
|              PreparedStatement statement = buildCharacterInsertStatement(connection, this.player)) { | ||||
| 
 | ||||
|             statement.execute(); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error( "Error writing character record " + e.toString()); | ||||
| 
 | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -0,0 +1,161 @@@@ -0,0 +1,161 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.archive; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.objects.City; | ||||
| import engine.workthreads.WarehousePushThread; | ||||
| 
 | ||||
| import java.sql.*; | ||||
| import java.util.concurrent.LinkedBlockingQueue; | ||||
| 
 | ||||
| public class CityRecord extends DataRecord { | ||||
| 
 | ||||
| 	private static final LinkedBlockingQueue<CityRecord> recordPool = new LinkedBlockingQueue<>(); | ||||
| 	private Enum.RecordEventType eventType; | ||||
| 	private City city; | ||||
| 	private String cityHash; | ||||
| 	private String cityGuildHash; | ||||
| 	private String cityName; | ||||
| 	private String cityMotto; | ||||
| 	private float locX; | ||||
| 	private float locY; | ||||
| 	private String zoneHash; | ||||
| 	private java.time.LocalDateTime establishedDatetime; | ||||
| 
 | ||||
| 	private CityRecord(City city) { | ||||
| 		this.recordType = Enum.DataRecordType.CITY; | ||||
| 		this.city = city; | ||||
| 		this.eventType = Enum.RecordEventType.CREATE; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static CityRecord borrow(City city, Enum.RecordEventType eventType) { | ||||
| 		CityRecord cityRecord; | ||||
| 
 | ||||
| 		cityRecord = recordPool.poll(); | ||||
| 
 | ||||
| 		if (cityRecord == null) { | ||||
| 			cityRecord = new CityRecord(city); | ||||
| 			cityRecord.eventType = eventType; | ||||
| 		} | ||||
| 		else { | ||||
| 			cityRecord.recordType = Enum.DataRecordType.CITY; | ||||
| 			cityRecord.eventType = eventType; | ||||
| 			cityRecord.city = city; | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		if (cityRecord.city.getHash() == null) | ||||
| 			cityRecord.city.setHash(DataWarehouse.hasher.encrypt(cityRecord.city.getObjectUUID())); | ||||
| 
 | ||||
| 		cityRecord.cityHash = cityRecord.city.getHash(); | ||||
| 
 | ||||
| 
 | ||||
| 		cityRecord.cityName = cityRecord.city.getCityName(); | ||||
| 		cityRecord.cityMotto = cityRecord.city.getMotto(); | ||||
| 
 | ||||
| 		cityRecord.cityGuildHash = cityRecord.city.getGuild().getHash(); | ||||
| 
 | ||||
| 		cityRecord.locX = cityRecord.city.getTOL().getLoc().x; | ||||
| 		cityRecord.locY = -cityRecord.city.getTOL().getLoc().z; // flip sign on 'y' coordinate
 | ||||
| 
 | ||||
| 		cityRecord.zoneHash = cityRecord.city.getParent().getHash(); | ||||
| 
 | ||||
| 		if (cityRecord.eventType.equals(Enum.RecordEventType.CREATE)) | ||||
|             cityRecord.establishedDatetime =  cityRecord.city.established; | ||||
| 		else | ||||
| 			cityRecord.establishedDatetime = java.time.LocalDateTime.now(); | ||||
| 
 | ||||
| 		return cityRecord; | ||||
| 	} | ||||
| 
 | ||||
| 	public static PreparedStatement buildCityPushStatement(Connection connection, ResultSet rs) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "INSERT INTO `warehouse_cityhistory` (`event_number`, `city_id`, `city_name`, `city_motto`, `guild_id`, `loc_x`, `loc_y`, `zone_id`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?,?)"; | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
| 		// Bind record data
 | ||||
| 
 | ||||
| 		outStatement.setInt(1, rs.getInt("event_number")); | ||||
| 		outStatement.setString(2, rs.getString("city_id")); | ||||
| 		outStatement.setString(3, rs.getString("city_name")); | ||||
| 		outStatement.setString(4, rs.getString("city_motto")); | ||||
| 		outStatement.setString(5, rs.getString("guild_id")); | ||||
| 
 | ||||
| 		outStatement.setFloat(6, rs.getFloat("loc_x")); | ||||
| 		outStatement.setFloat(7, rs.getFloat("loc_y")); | ||||
| 		outStatement.setString(8, rs.getString("zone_id")); | ||||
| 		outStatement.setString(9, rs.getString("eventType")); | ||||
| 		outStatement.setTimestamp(10, rs.getTimestamp("datetime")); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	public static PreparedStatement buildCityQueryStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "SELECT * FROM `warehouse_cityhistory` WHERE `event_number` > ?"; | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 		outStatement.setInt(1, WarehousePushThread.cityIndex); | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	void reset() { | ||||
| 		this.city = null; | ||||
| 		this.cityHash = null; | ||||
| 		this.cityGuildHash = null; | ||||
| 		this.cityMotto = null; | ||||
| 		this.zoneHash = null; | ||||
| 		this.establishedDatetime = null; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public void release() { | ||||
| 		this.reset(); | ||||
| 		recordPool.add(this); | ||||
| 	} | ||||
| 
 | ||||
| 	public void write() { | ||||
| 
 | ||||
| 		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = this.buildCityInsertStatement(connection)) { | ||||
| 
 | ||||
| 			statement.execute(); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	private PreparedStatement buildCityInsertStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "INSERT INTO `warehouse_cityhistory` (`city_id`, `city_name`, `city_motto`, `guild_id`, `loc_x`, `loc_y`, `zone_id`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?)"; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
| 		// Bind character data
 | ||||
| 
 | ||||
| 		outStatement.setString(1, this.cityHash); | ||||
| 		outStatement.setString(2, this.cityName); | ||||
| 		outStatement.setString(3, this.cityMotto); | ||||
| 		outStatement.setString(4, this.cityGuildHash); | ||||
| 
 | ||||
| 		outStatement.setFloat(5, this.locX); | ||||
| 		outStatement.setFloat(6, this.locY); | ||||
| 		outStatement.setString(7, this.zoneHash); | ||||
| 		outStatement.setString(8, this.eventType.name()); | ||||
| 		outStatement.setTimestamp(9,  Timestamp.valueOf(this.establishedDatetime)); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,23 @@@@ -0,0 +1,23 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.archive; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| 
 | ||||
| class DataRecord { | ||||
| 
 | ||||
|     public Enum.DataRecordType recordType; | ||||
| 
 | ||||
|     DataRecord() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,324 @@@@ -0,0 +1,324 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.archive; | ||||
| 
 | ||||
| import com.zaxxer.hikari.HikariConfig; | ||||
| import com.zaxxer.hikari.HikariDataSource; | ||||
| import engine.gameManager.ConfigManager; | ||||
| import engine.util.Hasher; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.Connection; | ||||
| import java.sql.PreparedStatement; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.concurrent.LinkedBlockingQueue; | ||||
| 
 | ||||
| import static engine.Enum.DataRecordType; | ||||
| 
 | ||||
| public class DataWarehouse implements Runnable { | ||||
| 
 | ||||
|     public static final Hasher hasher = new Hasher("Cthulhu Owns Joo"); | ||||
|     private static final LinkedBlockingQueue<DataRecord> recordQueue = new LinkedBlockingQueue<>(); | ||||
|     public static HikariDataSource connectionPool = null; | ||||
|     public static HikariDataSource remoteConnectionPool = null; | ||||
| 
 | ||||
|     public DataWarehouse() { | ||||
| 
 | ||||
|         Logger.info("Configuring local Database Connection Pool..."); | ||||
| 
 | ||||
|         configureConnectionPool(); | ||||
| 
 | ||||
|         // If WarehousePush is disabled
 | ||||
|         // then early exit
 | ||||
| 
 | ||||
|         if ( ConfigManager.MB_WORLD_WAREHOUSE_PUSH.getValue().equals("false")) { | ||||
|             Logger.info("Warehouse Remote Connection disabled along with push"); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         Logger.info( "Configuring remote Database Connection Pool..."); | ||||
|         configureRemoteConnectionPool(); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public static void bootStrap() { | ||||
|         Thread warehousingThread; | ||||
|         warehousingThread = new Thread(new DataWarehouse()); | ||||
| 
 | ||||
|         warehousingThread.setName("DataWarehouse"); | ||||
|         warehousingThread.setPriority(Thread.NORM_PRIORITY - 1); | ||||
|         warehousingThread.start(); | ||||
|     } | ||||
| 
 | ||||
|     public static void pushToWarehouse(DataRecord dataRecord) { | ||||
| 
 | ||||
|         DataWarehouse.recordQueue.add(dataRecord); | ||||
|     } | ||||
| 
 | ||||
|     public static void writeHash(DataRecordType recordType, int uuid) { | ||||
| 
 | ||||
|         // Member variable declaration
 | ||||
| 
 | ||||
|         Connection connection = null; | ||||
|         PreparedStatement statement = null; | ||||
|         String queryString; | ||||
|         String hashString; | ||||
| 
 | ||||
|         try { | ||||
|             connection = DataWarehouse.connectionPool.getConnection(); | ||||
|         } catch (SQLException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
| 
 | ||||
|         if (connection == null) { | ||||
|             Logger.error("Null connection when writing zone hash."); | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         // Build query string
 | ||||
| 
 | ||||
|         switch (recordType) { | ||||
|             case CHARACTER: | ||||
|                 queryString = "UPDATE `obj_character` SET hash = ? WHERE `UID` = ?"; | ||||
|                 break; | ||||
|             case GUILD: | ||||
|                 queryString = "UPDATE `obj_guild` SET hash = ? WHERE `UID` = ?"; | ||||
|                 break; | ||||
|             case ZONE: | ||||
|                 queryString = "UPDATE `obj_zone` SET hash = ? WHERE `UID` = ?"; | ||||
|                 break; | ||||
|             case CITY: | ||||
|                 queryString = "UPDATE `obj_city` SET hash = ? WHERE `UID` = ?"; | ||||
|                 break; | ||||
|             case REALM: | ||||
|                 queryString = "UPDATE `obj_realm` SET hash = ? WHERE `realmID` = ?"; | ||||
|                 break; | ||||
|             default: | ||||
|                 queryString = null; | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         hashString = hasher.encrypt(uuid); | ||||
| 
 | ||||
|         // Write this record to the warehouse
 | ||||
| 
 | ||||
|         try { | ||||
| 
 | ||||
|             statement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|             statement.setString(1, hashString); | ||||
|             statement.setLong(2, uuid); | ||||
|             statement.execute(); | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error("Error writing hash for uuid" + uuid + " of type " + recordType.name() + ' ' + e.toString()); | ||||
|             e.printStackTrace(); | ||||
|         } finally { | ||||
|             if (connection != null) { | ||||
|                 try { | ||||
|                     connection.close(); | ||||
|                 } catch (SQLException e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static boolean recordExists(DataRecordType recordType, int uuid) { | ||||
| 
 | ||||
|         // Member variable declaration
 | ||||
| 
 | ||||
|         Connection connection = null; | ||||
|         PreparedStatement statement = null; | ||||
|         String queryString; | ||||
|         ResultSet resultSet; | ||||
| 
 | ||||
|         try { | ||||
|             connection = DataWarehouse.connectionPool.getConnection(); | ||||
|         } catch (SQLException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
| 
 | ||||
|         if (connection == null) { | ||||
|             Logger.error("Null connection during char record lookup"); | ||||
|             return true;  // False positive here, so as not to try and write the record twice.
 | ||||
|             // will refactor out once we write hashes to object tables
 | ||||
|         } | ||||
| 
 | ||||
|         // Build query string
 | ||||
| 
 | ||||
|         switch (recordType) { | ||||
|             case CHARACTER: | ||||
|                 queryString = "SELECT COUNT(*) from warehouse_characterhistory where char_id = ?"; | ||||
|                 break; | ||||
|             case GUILD: | ||||
|                 queryString = "SELECT COUNT(*) from warehouse_guildhistory where guild_id = ?"; | ||||
|                 break; | ||||
|             case CITY: | ||||
|                 queryString = "SELECT COUNT(*) from warehouse_cityhistory where city_id = ?"; | ||||
|                 break; | ||||
|             case REALM: | ||||
|                 queryString = "SELECT COUNT(*) from warehouse_realmhistory where realm_id = ?"; | ||||
|                 break; | ||||
|             case BANE: | ||||
|                 queryString = "SELECT COUNT(*) from warehouse_banehistory where city_id = ? AND `resolution` = 'PENDING'"; | ||||
|                 break; | ||||
|             case ZONE: // Does not really exist but enum acts as a proxy for hash lookup
 | ||||
|             case MINE: // Does not really exist but enum acts as a proxy for hash lookup
 | ||||
|             default: | ||||
|                 queryString = null; | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         try { | ||||
|             statement = connection.prepareStatement(queryString); | ||||
|             statement.setString(1, DataWarehouse.hasher.encrypt(uuid)); | ||||
|             resultSet = statement.executeQuery(); | ||||
| 
 | ||||
|             while (resultSet.next()) { | ||||
|                 return resultSet.getInt("COUNT(*)") > 0; | ||||
|             } | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error("Error in record lookup for " + recordType.name() + " of uuid:" + uuid + e.toString()); | ||||
|             e.printStackTrace(); | ||||
|         } finally { | ||||
|             if (connection != null) { | ||||
|                 try { | ||||
|                     connection.close(); | ||||
|                 } catch (SQLException e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     public void run() { | ||||
| 
 | ||||
|         // Working variable set
 | ||||
| 
 | ||||
|         DataRecord dataRecord; | ||||
|         PvpRecord pvpRecord; | ||||
|         GuildRecord guildRecord; | ||||
|         CharacterRecord characterRecord; | ||||
|         CityRecord cityRecord; | ||||
|         BaneRecord baneRecord; | ||||
|         RealmRecord realmRecord; | ||||
|         MineRecord mineRecord; | ||||
| 
 | ||||
|         Logger.info( "DataWarehouse is running."); | ||||
| 
 | ||||
|         while (true) { | ||||
| 
 | ||||
|             dataRecord = null; | ||||
|             pvpRecord = null; | ||||
|             guildRecord = null; | ||||
|             characterRecord = null; | ||||
|             cityRecord = null; | ||||
|             baneRecord = null; | ||||
|             realmRecord = null; | ||||
|             mineRecord = null; | ||||
| 
 | ||||
|             try { | ||||
|                 dataRecord = recordQueue.take(); | ||||
|             } catch (InterruptedException e) { | ||||
|                 e.printStackTrace(); | ||||
|             } | ||||
| 
 | ||||
|             // Write record to appropriate warehousing table
 | ||||
| 
 | ||||
|             if (dataRecord != null) { | ||||
| 
 | ||||
|                 switch (dataRecord.recordType) { | ||||
|                     case PVP: | ||||
|                         pvpRecord = (PvpRecord) dataRecord; | ||||
|                         pvpRecord.write(); | ||||
|                         pvpRecord.release(); | ||||
|                         break; | ||||
|                     case CHARACTER: | ||||
|                         characterRecord = (CharacterRecord) dataRecord; | ||||
|                         characterRecord.write(); | ||||
|                         characterRecord.release(); | ||||
|                         break; | ||||
|                     case GUILD: | ||||
|                         guildRecord = (GuildRecord) dataRecord; | ||||
|                         guildRecord.write(); | ||||
|                         guildRecord.release(); | ||||
|                         break; | ||||
|                     case CITY: | ||||
|                         cityRecord = (CityRecord) dataRecord; | ||||
|                         cityRecord.write(); | ||||
|                         cityRecord.release(); | ||||
|                         break; | ||||
|                     case BANE: | ||||
|                         baneRecord = (BaneRecord) dataRecord; | ||||
|                         baneRecord.write(); | ||||
|                         baneRecord.release(); | ||||
|                         break; | ||||
|                     case REALM: | ||||
|                         realmRecord = (RealmRecord) dataRecord; | ||||
|                         realmRecord.write(); | ||||
|                         realmRecord.release(); | ||||
|                         break; | ||||
|                     case MINE: | ||||
|                         mineRecord = (MineRecord) dataRecord; | ||||
|                         mineRecord.write(); | ||||
|                         mineRecord.release(); | ||||
|                         break; | ||||
|                     default: | ||||
|                         Logger.error( "Unhandled record type"); | ||||
|                         break; | ||||
| 
 | ||||
|                 } // end switch
 | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private static void configureConnectionPool() { | ||||
| 
 | ||||
|         HikariConfig config = new HikariConfig(); | ||||
| 
 | ||||
|         config.setMaximumPoolSize(10); | ||||
| 
 | ||||
|         config.setJdbcUrl("jdbc:mysql://" +  ConfigManager.MB_DATABASE_ADDRESS.getValue() + | ||||
|                 ":" +  ConfigManager.MB_DATABASE_PORT.getValue() + "/" + | ||||
|                 ConfigManager.MB_DATABASE_NAME.getValue()); | ||||
|         config.setUsername(ConfigManager.MB_DATABASE_USER.getValue()); | ||||
|         config.setPassword( ConfigManager.MB_DATABASE_PASS.getValue()); | ||||
|         config.addDataSourceProperty("characterEncoding", "utf8"); | ||||
|         config.addDataSourceProperty("cachePrepStmts", "true"); | ||||
|         config.addDataSourceProperty("prepStmtCacheSize", "250"); | ||||
|         config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); | ||||
| 
 | ||||
|         connectionPool = new HikariDataSource(config); // setup the connection pool
 | ||||
| 
 | ||||
|         Logger.info("Local warehouse database connection configured"); | ||||
|     } | ||||
| 
 | ||||
|     private static void configureRemoteConnectionPool() { | ||||
| 
 | ||||
|         HikariConfig config = new HikariConfig(); | ||||
| 
 | ||||
|         config.setMaximumPoolSize(1); // Only the server talks to remote, so yeah.
 | ||||
|         config.setJdbcUrl(ConfigManager.MB_WAREHOUSE_ADDR.getValue()); | ||||
|         config.setUsername(ConfigManager.MB_WAREHOUSE_USER.getValue()); | ||||
|         config.setPassword(ConfigManager.MB_WAREHOUSE_PASS.getValue()); | ||||
|         config.addDataSourceProperty("characterEncoding", "utf8"); | ||||
|         config.addDataSourceProperty("cachePrepStmts", "true"); | ||||
|         config.addDataSourceProperty("prepStmtCacheSize", "250"); | ||||
|         config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); | ||||
| 
 | ||||
|         remoteConnectionPool = new HikariDataSource(config); // setup the connection pool
 | ||||
| 
 | ||||
|         Logger.info("remote warehouse connection configured"); | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,215 @@@@ -0,0 +1,215 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.archive; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.RecordEventType; | ||||
| import engine.objects.Guild; | ||||
| import engine.workthreads.WarehousePushThread; | ||||
| 
 | ||||
| import java.sql.Connection; | ||||
| import java.sql.PreparedStatement; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.time.LocalDateTime; | ||||
| import java.time.ZoneId; | ||||
| import java.util.HashMap; | ||||
| import java.util.concurrent.LinkedBlockingQueue; | ||||
| 
 | ||||
| public class GuildRecord extends DataRecord { | ||||
| 
 | ||||
| 	private static final LinkedBlockingQueue<GuildRecord> recordPool = new LinkedBlockingQueue<>(); | ||||
| 	private Enum.RecordEventType eventType; | ||||
| 	private Guild guild; | ||||
| 	public String guildHash; | ||||
| 	private String guildName; | ||||
| 	private String charterName; | ||||
| 	private String GLHash; | ||||
| 	private String guildMotto; | ||||
| 	private int bgIcon; | ||||
| 	private int bgColour1; | ||||
| 	private int bgColour2; | ||||
| 	private int fgIcon; | ||||
| 	private int fgColour; | ||||
| 	public int guildID; | ||||
| 
 | ||||
| 	private java.time.LocalDateTime  eventDatetime; | ||||
| 	 | ||||
| 	public static HashMap<Integer, GuildRecord> GuildRecordCache = null; | ||||
| 
 | ||||
| 	private GuildRecord(Guild guild) { | ||||
| 		this.recordType = Enum.DataRecordType.GUILD; | ||||
| 		this.guild = guild; | ||||
| 		this.eventType = Enum.RecordEventType.CREATE; | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
| 
 | ||||
| 	public GuildRecord(ResultSet rs) throws SQLException { | ||||
| 		super(); | ||||
| 		this.eventType = RecordEventType.valueOf(rs.getString("eventType")); | ||||
| 		this.guildHash = rs.getString("guild_id"); | ||||
| 		this.guildName = rs.getString("guild_name"); | ||||
| 		this.charterName = rs.getString("charter"); | ||||
| 		GLHash = rs.getString("guild_founder"); | ||||
| 		this.guildMotto = rs.getString("guild_motto"); | ||||
| 		this.bgIcon = rs.getInt("bgicon"); | ||||
| 		this.bgColour1 = rs.getInt("bgcoloura"); | ||||
| 		this.bgColour2 = rs.getInt("bgcolourb"); | ||||
| 		this.fgIcon = rs.getInt("fgicon"); | ||||
| 		this.fgColour = rs.getInt("fgcolour"); | ||||
| 
 | ||||
| 		java.sql.Timestamp eventTimeStamp = rs.getTimestamp("upgradeDate"); | ||||
| 
 | ||||
| 		if (eventTimeStamp != null) | ||||
| 			this.eventDatetime = LocalDateTime.ofInstant(eventTimeStamp.toInstant(), ZoneId.systemDefault()); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	public static GuildRecord borrow(Guild guild, Enum.RecordEventType eventType) { | ||||
| 		GuildRecord guildRecord; | ||||
| 		//add
 | ||||
| 		guildRecord = recordPool.poll(); | ||||
| 
 | ||||
| 		if (guildRecord == null) { | ||||
| 			guildRecord = new GuildRecord(guild); | ||||
| 			guildRecord.eventType = eventType; | ||||
| 		} | ||||
| 		else { | ||||
| 			guildRecord.guild = guild; | ||||
| 			guildRecord.recordType = Enum.DataRecordType.GUILD; | ||||
| 			guildRecord.eventType = eventType; | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		guildRecord.guildHash = guildRecord.guild.getHash(); | ||||
| 		guildRecord.guildID = guildRecord.guild.getObjectUUID(); | ||||
| 		guildRecord.guildName = guildRecord.guild.getName(); | ||||
| 		guildRecord.charterName = Enum.GuildType.getGuildTypeFromInt(guildRecord.guild.getCharter()).getCharterName(); | ||||
| 
 | ||||
| 		guildRecord.GLHash = DataWarehouse.hasher.encrypt(guildRecord.guild.getGuildLeaderUUID()); | ||||
| 
 | ||||
| 		guildRecord.guildMotto = guildRecord.guild.getMotto(); | ||||
| 		guildRecord.bgIcon = guildRecord.guild.getBgDesign(); | ||||
| 		guildRecord.bgColour1 = guildRecord.guild.getBgc1(); | ||||
| 		guildRecord.bgColour2 = guildRecord.guild.getBgc2(); | ||||
| 		guildRecord.fgIcon = guildRecord.guild.getSymbol(); | ||||
| 		guildRecord.fgColour = guildRecord.guild.getSc(); | ||||
| 
 | ||||
| 		if (guild.getOwnedCity() != null) | ||||
|             guildRecord.eventDatetime =  guild.getOwnedCity().established; | ||||
| 		else | ||||
| 			guildRecord.eventDatetime = LocalDateTime.now(); | ||||
| 
 | ||||
| 		return guildRecord; | ||||
| 	} | ||||
| 
 | ||||
| 	public static PreparedStatement buildGuildPushStatement(Connection connection, ResultSet rs) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "INSERT INTO `warehouse_guildhistory` (`event_number`, `guild_id`, `guild_name`, `guild_motto`, `guild_founder`, `charter`, `bgicon`, `bgcoloura`, `bgcolourb`, `fgicon`, `fgcolour`, `eventtype`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)"; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
| 		// Bind record data
 | ||||
| 
 | ||||
| 		outStatement.setInt(1, rs.getInt("event_number")); | ||||
| 		outStatement.setString(2, rs.getString("guild_id")); | ||||
| 		outStatement.setString(3, rs.getString("guild_name")); | ||||
| 		outStatement.setString(4, rs.getString("guild_motto")); | ||||
| 		outStatement.setString(5, rs.getString("guild_founder")); | ||||
| 		outStatement.setString(6, rs.getString("charter")); | ||||
| 		outStatement.setInt(7, rs.getInt("bgicon")); | ||||
| 		outStatement.setInt(8, rs.getInt("bgcoloura")); | ||||
| 		outStatement.setInt(9, rs.getInt("bgcolourb")); | ||||
| 		outStatement.setInt(10, rs.getInt("fgicon")); | ||||
| 		outStatement.setInt(11, rs.getInt("fgcolour")); | ||||
| 		outStatement.setString(12, rs.getString("eventtype")); | ||||
| 		outStatement.setTimestamp(13, rs.getTimestamp("datetime")); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	public static PreparedStatement buildGuildQueryStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "SELECT * FROM `warehouse_guildhistory` WHERE `event_number` > ?"; | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 		outStatement.setInt(1, WarehousePushThread.guildIndex); | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	void reset() { | ||||
| 
 | ||||
| 		this.guild = null; | ||||
| 		this.guildHash = null; | ||||
| 		this.GLHash = null; | ||||
| 		this.guildMotto = null; | ||||
| 		this.charterName = null; | ||||
| 		this.eventDatetime = null; | ||||
| 	} | ||||
| 
 | ||||
| 	public void release() { | ||||
| 		this.reset(); | ||||
| 		recordPool.add(this); | ||||
| 	} | ||||
| 
 | ||||
| 	public void write() { | ||||
| 
 | ||||
| 		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = this.buildGuildInsertStatement(connection)) { | ||||
| 
 | ||||
| 			statement.execute(); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	private PreparedStatement buildGuildInsertStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "INSERT INTO `warehouse_guildhistory` (`guild_id`, `guild_name`, `guild_motto`, `guild_founder`, `charter`, `bgicon`, `bgcoloura`, `bgcolourb`, `fgicon`, `fgcolour`, `eventtype`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)"; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
| 		// Bind character data
 | ||||
| 
 | ||||
| 		outStatement.setString(1, this.guildHash); | ||||
| 		outStatement.setString(2, this.guildName); | ||||
| 		outStatement.setString(3, this.guildMotto); | ||||
| 		outStatement.setString(4, this.GLHash); | ||||
| 		outStatement.setString(5, this.charterName); | ||||
| 
 | ||||
| 		outStatement.setInt(6, this.bgIcon); | ||||
| 		outStatement.setInt(7, this.bgColour1); | ||||
| 		outStatement.setInt(8, this.bgColour2); | ||||
| 		outStatement.setInt(9, this.fgIcon); | ||||
| 		outStatement.setInt(10, this.fgColour); | ||||
| 		outStatement.setString(11, this.eventType.name()); | ||||
| 		outStatement.setTimestamp(12, new java.sql.Timestamp(	this.eventDatetime.atZone(ZoneId.systemDefault()) | ||||
| 				.toInstant().toEpochMilli())); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 	 | ||||
| //	public static void InitializeGuildRecords(){
 | ||||
| //		GuildRecord.GuildRecordCache = DbManager.GuildQueries.GET_WAREHOUSE_GUILD_HISTORY();
 | ||||
| //	}
 | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| @ -0,0 +1,166 @@@@ -0,0 +1,166 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.archive; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.objects.AbstractCharacter; | ||||
| import engine.objects.Mine; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.workthreads.WarehousePushThread; | ||||
| 
 | ||||
| import java.sql.*; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.concurrent.LinkedBlockingQueue; | ||||
| 
 | ||||
| public class MineRecord extends DataRecord { | ||||
| 
 | ||||
|     private static final LinkedBlockingQueue<MineRecord> recordPool = new LinkedBlockingQueue<>(); | ||||
|     private Enum.RecordEventType eventType; | ||||
|     private String zoneHash; | ||||
|     private String charHash; | ||||
|     private String mineGuildHash; | ||||
|     private String mineNationHash; | ||||
|     private String mineType; | ||||
|     private float locX; | ||||
|     private float locY; | ||||
| 
 | ||||
|     private MineRecord() { | ||||
|         this.recordType = Enum.DataRecordType.MINE; | ||||
|         this.eventType = Enum.RecordEventType.CAPTURE; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public static MineRecord borrow(Mine mine, AbstractCharacter character, Enum.RecordEventType eventType) { | ||||
| 
 | ||||
|         MineRecord mineRecord; | ||||
|         mineRecord = recordPool.poll(); | ||||
|         PlayerCharacter player; | ||||
| 
 | ||||
|         if (mineRecord == null) { | ||||
|             mineRecord = new MineRecord(); | ||||
|             mineRecord.eventType = eventType; | ||||
|         } | ||||
|         else { | ||||
|             mineRecord.recordType = Enum.DataRecordType.MINE; | ||||
|             mineRecord.eventType = eventType; | ||||
|         } | ||||
| 
 | ||||
|         mineRecord.zoneHash = mine.getParentZone().getHash(); | ||||
| 
 | ||||
|         if (character.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { | ||||
|             player = (PlayerCharacter) character; | ||||
|             mineRecord.charHash = player.getHash(); | ||||
|         } | ||||
|         else | ||||
|             mineRecord.charHash = character.getName(); | ||||
| 
 | ||||
|         DataWarehouse.hasher.encrypt(0); | ||||
| 
 | ||||
|         if (mine.getOwningGuild() == null) | ||||
|             mineRecord.mineGuildHash = "ERRANT"; | ||||
|         else | ||||
|             mineRecord.mineGuildHash = mine.getOwningGuild().getHash(); | ||||
| 
 | ||||
|         if (mine.getOwningGuild() == null) | ||||
|             mineRecord.mineNationHash = "ERRANT"; | ||||
|         else | ||||
|             mineRecord.mineNationHash = mine.getOwningGuild().getNation().getHash(); | ||||
| 
 | ||||
|         mineRecord.locX = mine.getParentZone().getLoc().x; | ||||
|         mineRecord.locY = -mine.getParentZone().getLoc().z; | ||||
| 
 | ||||
|         mineRecord.mineType = mine.getMineType().name; | ||||
| 
 | ||||
|         return mineRecord; | ||||
|     } | ||||
| 
 | ||||
|     public static PreparedStatement buildMinePushStatement(Connection connection, ResultSet rs) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "INSERT INTO `warehouse_minehistory` (`event_number`, `zone_id`, `mine_type`, `char_id`, `mine_guildID`, `mine_nationID`, `loc_x`, `loc_y`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?,?)"; | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|         // Bind record data
 | ||||
| 
 | ||||
|         outStatement.setInt(1, rs.getInt("event_number")); | ||||
|         outStatement.setString(2, rs.getString("zone_id")); | ||||
|         outStatement.setString(3, rs.getString("char_id")); | ||||
|         outStatement.setString(4, rs.getString("mine_type")); | ||||
|         outStatement.setString(5, rs.getString("mine_guildID")); | ||||
|         outStatement.setString(6, rs.getString("mine_nationID")); | ||||
| 
 | ||||
|         outStatement.setFloat(7, rs.getFloat("loc_x")); | ||||
|         outStatement.setFloat(8, rs.getFloat("loc_y")); | ||||
|         outStatement.setString(9, rs.getString("eventType")); | ||||
|         outStatement.setTimestamp(10, rs.getTimestamp("datetime")); | ||||
| 
 | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     public static PreparedStatement buildMineQueryStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "SELECT * FROM `warehouse_minehistory` WHERE `event_number` > ?"; | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
|         outStatement.setInt(1, WarehousePushThread.mineIndex); | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     void reset() { | ||||
|         this.zoneHash = null; | ||||
|         this.charHash = null; | ||||
|         this.mineGuildHash = null; | ||||
|         this.mineNationHash = null; | ||||
|         this.mineType = null; | ||||
|         this.locX = 0.0f; | ||||
|         this.locY = 0.0f; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public void release() { | ||||
|         this.reset(); | ||||
|         recordPool.add(this); | ||||
|     } | ||||
| 
 | ||||
|     public void write() { | ||||
| 
 | ||||
|         try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
|              PreparedStatement statement = this.buildMineInsertStatement(connection)) { | ||||
| 
 | ||||
|             statement.execute(); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private PreparedStatement buildMineInsertStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "INSERT INTO `warehouse_minehistory` (`zone_id`, `mine_type`, `char_id`, `mine_guildID`, `mine_nationID`, `loc_x`, `loc_y`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?)"; | ||||
| 
 | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|         // Bind character data
 | ||||
| 
 | ||||
|         outStatement.setString(1, this.zoneHash); | ||||
|         outStatement.setString(2, this.mineType); | ||||
|         outStatement.setString(3, this.charHash); | ||||
|         outStatement.setString(4, this.mineGuildHash); | ||||
|         outStatement.setString(5, this.mineNationHash); | ||||
| 
 | ||||
|         outStatement.setFloat(6, this.locX); | ||||
|         outStatement.setFloat(7, this.locY); | ||||
|         outStatement.setString(8, this.eventType.name()); | ||||
|         outStatement.setTimestamp(9, Timestamp.valueOf(LocalDateTime.now())); | ||||
| 
 | ||||
|         return outStatement; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,312 @@@@ -0,0 +1,312 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.archive; | ||||
| 
 | ||||
| import engine.gameManager.ZoneManager; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.Guild; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.objects.Zone; | ||||
| import engine.workthreads.WarehousePushThread; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.*; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.LinkedList; | ||||
| import java.util.concurrent.LinkedBlockingQueue; | ||||
| 
 | ||||
| import static engine.Enum.DataRecordType; | ||||
| import static engine.Enum.PvpHistoryType; | ||||
| 
 | ||||
| public class PvpRecord extends DataRecord { | ||||
| 
 | ||||
| 	private static final LinkedBlockingQueue<PvpRecord> recordPool = new LinkedBlockingQueue<>(); | ||||
| 
 | ||||
| 	private PlayerCharacter player; | ||||
| 	private PlayerCharacter victim; | ||||
| 	private Vector3fImmutable location; | ||||
| 	private boolean pvpExp; | ||||
| 
 | ||||
| 	private PvpRecord(PlayerCharacter player, PlayerCharacter victim, Vector3fImmutable location, boolean pvpExp) { | ||||
| 		this.recordType = DataRecordType.PVP; | ||||
| 		this.player = player; | ||||
| 		this.victim = victim; | ||||
| 		this.location = new Vector3fImmutable(location); | ||||
| 		this.pvpExp = pvpExp; | ||||
| 	} | ||||
| 
 | ||||
| 	public static PvpRecord borrow(PlayerCharacter player, PlayerCharacter victim, Vector3fImmutable location, boolean pvpExp) { | ||||
| 
 | ||||
| 		PvpRecord pvpRecord; | ||||
| 
 | ||||
| 		pvpRecord = recordPool.poll(); | ||||
| 
 | ||||
| 		if (pvpRecord == null) { | ||||
| 			pvpRecord = new PvpRecord(player, victim, location, pvpExp); | ||||
| 		} | ||||
| 		else { | ||||
| 			pvpRecord.recordType = DataRecordType.PVP; | ||||
| 			pvpRecord.player = player; | ||||
| 			pvpRecord.victim = victim; | ||||
| 			pvpRecord.location = new Vector3fImmutable(location); | ||||
| 			pvpRecord.pvpExp = pvpExp; | ||||
| 		} | ||||
| 
 | ||||
| 		return pvpRecord; | ||||
| 	} | ||||
| 
 | ||||
| 	private static PreparedStatement buildHistoryStatement(Connection connection, int charUUID, PvpHistoryType historyType) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = ""; | ||||
| 
 | ||||
| 		switch (historyType) { | ||||
| 		case KILLS: | ||||
| 			queryString = "SELECT DISTINCT `victim_id`, `datetime` FROM warehouse_pvphistory where char_id = ? " + | ||||
| 					"ORDER BY `datetime` DESC LIMIT 10"; | ||||
| 			break; | ||||
| 		case DEATHS: | ||||
| 			queryString = "SELECT DISTINCT `char_id`,`datetime` FROM warehouse_pvphistory where `victim_id` = ? " + | ||||
| 					"ORDER BY `datetime` DESC LIMIT 10"; | ||||
| 			break; | ||||
| 		} | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 		outStatement.setString(1, DataWarehouse.hasher.encrypt(charUUID)); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	public static LinkedList<Integer> getCharacterPvPHistory(int charUUID, PvpHistoryType historyType) { | ||||
| 
 | ||||
| 		// Member variable declaration
 | ||||
| 
 | ||||
| 		LinkedList<Integer> outList = new LinkedList<>(); | ||||
| 
 | ||||
| 		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = buildHistoryStatement(connection, charUUID, historyType); | ||||
| 				ResultSet rs = statement.executeQuery()) { | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				switch (historyType) { | ||||
| 				case KILLS: | ||||
| 					outList.add((int) DataWarehouse.hasher.decrypt(rs.getString("victim_id"))[0]); | ||||
| 					break; | ||||
| 				case DEATHS: | ||||
| 					outList.add((int) DataWarehouse.hasher.decrypt(rs.getString("char_id"))[0]); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 		return outList; | ||||
| 	} | ||||
| 
 | ||||
| 	private static PreparedStatement buildLuaHistoryQueryStatement(Connection connection, int charUUID) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "CALL `pvpHistory`(?)"; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 		outStatement.setString(1, DataWarehouse.hasher.encrypt(charUUID)); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	public static String getPvpHistoryString(int charUUID) { | ||||
| 
 | ||||
| 		String outString; | ||||
| 		String dividerString; | ||||
| 
 | ||||
| 		String newLine = System.getProperty("line.separator"); | ||||
| 
 | ||||
| 		outString = "[LUA_PVP() DATA WAREHOUSE]" + newLine; | ||||
| 		dividerString = "--------------------------------" + newLine; | ||||
| 
 | ||||
| 		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = buildLuaHistoryQueryStatement(connection, charUUID); | ||||
| 				ResultSet rs = statement.executeQuery()) { | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				int killCount; | ||||
| 				int deathCount; | ||||
| 				float killRatio; | ||||
| 
 | ||||
| 				outString += "Total Magicbane murdered souls: " + rs.getInt("TOTALDEATHS") + newLine; | ||||
| 				outString += dividerString; | ||||
| 				outString += String.format("%-8s %-8s %-8s %-8s %n", "Period", "Kills", "Deaths", "K/D"); | ||||
| 				outString += dividerString; | ||||
| 
 | ||||
| 				killCount = rs.getInt("KILLCOUNT"); | ||||
| 				deathCount = rs.getInt("DEATHCOUNT"); | ||||
| 
 | ||||
| 				if (deathCount == 0) | ||||
| 					killRatio = (float) killCount; | ||||
| 				else | ||||
| 					killRatio = (float) killCount / deathCount; | ||||
| 
 | ||||
| 				try { | ||||
| 					outString += String.format("%-8s %-8d %-8d %.2f %n", "Total", killCount, deathCount, killRatio); | ||||
| 
 | ||||
| 					killCount = rs.getInt("DAILYKILLS"); | ||||
| 					deathCount = rs.getInt("DAILYDEATHS"); | ||||
| 
 | ||||
| 					if (deathCount == 0) | ||||
| 						killRatio = (float) killCount; | ||||
| 					else | ||||
| 						killRatio = (float) killCount / deathCount; | ||||
| 
 | ||||
| 					outString += String.format("%-8s %-8d %-8d %.2f %n", "24hrs", killCount, deathCount, killRatio); | ||||
| 
 | ||||
| 					killCount = rs.getInt("HOURLYKILLS"); | ||||
| 					deathCount = rs.getInt("HOURLYDEATHS"); | ||||
| 
 | ||||
| 					if (deathCount == 0) | ||||
| 						killRatio = (float) killCount; | ||||
| 					else | ||||
| 						killRatio = (float) killCount / deathCount; | ||||
| 
 | ||||
| 					outString += String.format("%-8s %-8d %-8d %.2f %n", "1hr", killCount, deathCount, killRatio); | ||||
| 				} catch (Exception e) { | ||||
| 					Logger.error(e.toString()); | ||||
| 				} | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			e.printStackTrace(); | ||||
| 		} | ||||
| 
 | ||||
| 		return outString; | ||||
| 	} | ||||
| 
 | ||||
| 	public static PreparedStatement buildPvpPushStatement(Connection connection, ResultSet rs) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "INSERT INTO `warehouse_pvphistory` (`event_number`, `char_id`, `char_guild_id`, `char_nation_id`, `char_level`," + | ||||
| 				" `victim_id`, `victim_guild_id`, `victim_nation_id`, `victim_level`," + | ||||
| 				" `zone_id`, `zone_name`, `loc_x`, `loc_y`, `gave_exp`, `datetime`) " + | ||||
| 				" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
| 		// Bind record data
 | ||||
| 
 | ||||
| 		outStatement.setInt(1, rs.getInt("event_number")); | ||||
| 		outStatement.setString(2, rs.getString("char_id")); | ||||
| 		outStatement.setString(3, rs.getString("char_guild_id")); | ||||
| 		outStatement.setString(4, rs.getString("char_nation_id")); | ||||
| 		outStatement.setInt(5, rs.getInt("char_level")); | ||||
| 
 | ||||
| 		// Bind victim data
 | ||||
| 
 | ||||
| 		outStatement.setString(6, rs.getString("victim_id")); | ||||
| 		outStatement.setString(7, rs.getString("victim_guild_id")); | ||||
| 		outStatement.setString(8, rs.getString("victim_nation_id")); | ||||
| 		outStatement.setInt(9, rs.getInt("victim_level")); | ||||
| 
 | ||||
| 		outStatement.setString(10, rs.getString("zone_id")); | ||||
| 		outStatement.setString(11, rs.getString("zone_name")); | ||||
| 		outStatement.setFloat(12, rs.getFloat("loc_x")); | ||||
| 		outStatement.setFloat(13, rs.getFloat("loc_y")); | ||||
| 		outStatement.setBoolean(14, rs.getBoolean("gave_exp")); | ||||
| 		outStatement.setTimestamp(15, rs.getTimestamp("datetime")); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	public static PreparedStatement buildPvpQueryStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
| 		PreparedStatement outStatement = null; | ||||
| 		String queryString = "SELECT * FROM `warehouse_pvphistory` WHERE `event_number` > ?"; | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 		outStatement.setInt(1, WarehousePushThread.pvpIndex); | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 	void reset() { | ||||
| 		this.player = null; | ||||
| 		this.victim = null; | ||||
| 		this.location = Vector3fImmutable.ZERO; | ||||
| 		pvpExp = false; | ||||
| 	} | ||||
| 
 | ||||
| 	public void release() { | ||||
| 		this.reset(); | ||||
| 		recordPool.add(this); | ||||
| 	} | ||||
| 
 | ||||
| 	private PreparedStatement buildPvPInsertStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
| 		Guild charGuild; | ||||
| 		Guild victimGuild; | ||||
| 		Zone zone; | ||||
| 		PreparedStatement outStatement = null; | ||||
| 
 | ||||
| 		String queryString = "INSERT INTO `warehouse_pvphistory` (`char_id`, `char_guild_id`, `char_nation_id`, `char_level`," + | ||||
| 				" `victim_id`, `victim_guild_id`, `victim_nation_id`, `victim_level`," + | ||||
| 				" `zone_id`, `zone_name`, `loc_x`, `loc_y`, `gave_exp`, `datetime`) " + | ||||
| 				" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; | ||||
| 
 | ||||
| 		outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
| 		charGuild = this.player.getGuild(); | ||||
| 		victimGuild = this.victim.getGuild(); | ||||
| 
 | ||||
| 		// Use a proxy in the situation where a char guild is null (errant)
 | ||||
| 
 | ||||
| 		 | ||||
| 		// Retrieve the zone name where the PvP event occurred
 | ||||
| 
 | ||||
| 		zone = ZoneManager.findSmallestZone(this.location); | ||||
| 
 | ||||
| 		outStatement.setString(1, DataWarehouse.hasher.encrypt(this.player.getObjectUUID())); | ||||
| 		outStatement.setString(2, DataWarehouse.hasher.encrypt(charGuild.getObjectUUID())); | ||||
| 		outStatement.setString(3, DataWarehouse.hasher.encrypt(charGuild.getNation().getObjectUUID())); | ||||
| 		outStatement.setInt(4, this.player.getLevel()); | ||||
| 
 | ||||
| 		// Bind victim data
 | ||||
| 
 | ||||
| 		outStatement.setString(5, DataWarehouse.hasher.encrypt(this.victim.getObjectUUID())); | ||||
| 		outStatement.setString(6, DataWarehouse.hasher.encrypt(victimGuild.getObjectUUID())); | ||||
| 		outStatement.setString(7, DataWarehouse.hasher.encrypt(victimGuild.getNation().getObjectUUID())); | ||||
| 		outStatement.setInt(8, this.victim.getLevel()); | ||||
| 
 | ||||
| 		outStatement.setString(9, DataWarehouse.hasher.encrypt(zone.getObjectUUID())); | ||||
| 		outStatement.setString(10, zone.getName()); | ||||
| 		outStatement.setFloat(11, this.location.getX()); | ||||
| 		outStatement.setFloat(12, -this.location.getZ()); // flip sign on 'y' coordinate
 | ||||
| 		outStatement.setBoolean(13, this.pvpExp); | ||||
| 		outStatement.setTimestamp(14, Timestamp.valueOf(LocalDateTime.now())); | ||||
| 
 | ||||
| 		return outStatement; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public void write() { | ||||
| 
 | ||||
| 		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
| 				PreparedStatement statement = buildPvPInsertStatement(connection)) { | ||||
| 
 | ||||
| 			statement.execute(); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} | ||||
| 
 | ||||
| 		// Warehouse record for this pvp event written if code path reaches here.
 | ||||
| 		// Time to update the respective kill counters.
 | ||||
| 
 | ||||
| 		CharacterRecord.advanceKillCounter(this.player); | ||||
| 		CharacterRecord.advanceDeathCounter(this.victim); | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,142 @@@@ -0,0 +1,142 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.archive; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.objects.Realm; | ||||
| import engine.workthreads.WarehousePushThread; | ||||
| 
 | ||||
| import java.sql.*; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.concurrent.LinkedBlockingQueue; | ||||
| 
 | ||||
| public class RealmRecord extends DataRecord { | ||||
| 
 | ||||
|     private static final LinkedBlockingQueue<RealmRecord> recordPool = new LinkedBlockingQueue<>(); | ||||
| 
 | ||||
|     private Realm realm; | ||||
|     private Enum.RecordEventType eventType; | ||||
|     private String cityHash; | ||||
|     private String guildHash; | ||||
|     private String charterType; | ||||
|     private LocalDateTime eventDateTime; | ||||
| 
 | ||||
|     private RealmRecord(Realm realm) { | ||||
|         this.recordType = Enum.DataRecordType.REALM; | ||||
|         this.realm = realm; | ||||
|         this.eventType = Enum.RecordEventType.CAPTURE; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public static RealmRecord borrow(Realm realm, Enum.RecordEventType eventType) { | ||||
|         RealmRecord realmRecord; | ||||
| 
 | ||||
|         realmRecord = recordPool.poll(); | ||||
| 
 | ||||
|         if (realmRecord == null) { | ||||
|             realmRecord = new RealmRecord(realm); | ||||
|             realmRecord.eventType = eventType; | ||||
|         } | ||||
|         else { | ||||
|             realmRecord.recordType = Enum.DataRecordType.REALM; | ||||
|             realmRecord.eventType = eventType; | ||||
|             realmRecord.realm = realm; | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         realmRecord.cityHash = realm.getRulingCity().getHash(); | ||||
|         realmRecord.guildHash = realm.getRulingCity().getGuild().getHash(); | ||||
|         realmRecord.charterType = Enum.CharterType.getCharterTypeByID(realmRecord.realm.getCharterType()).name(); | ||||
| 
 | ||||
|         if (realmRecord.eventType.equals(Enum.RecordEventType.CAPTURE)) | ||||
|             realmRecord.eventDateTime =  realm.ruledSince; | ||||
|         else | ||||
|             realmRecord.eventDateTime = LocalDateTime.now(); | ||||
| 
 | ||||
|         return realmRecord; | ||||
|     } | ||||
| 
 | ||||
|     public static PreparedStatement buildRealmPushStatement(Connection connection, ResultSet rs) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "INSERT INTO `warehouse_realmhistory` (`event_number`, `realm_id`, `realm_name`, `charter`, `city_id`, `guild_id`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?,?)"; | ||||
| 
 | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|         // Bind record data
 | ||||
| 
 | ||||
|         outStatement.setInt(1, rs.getInt("event_number")); | ||||
|         outStatement.setString(2, rs.getString("realm_id")); | ||||
|         outStatement.setString(3, rs.getString("realm_name")); | ||||
|         outStatement.setString(4, rs.getString("charter")); | ||||
|         outStatement.setString(5, rs.getString("city_id")); | ||||
|         outStatement.setString(6, rs.getString("guild_id")); | ||||
|         outStatement.setString(7, rs.getString("eventType")); | ||||
|         outStatement.setTimestamp(8, rs.getTimestamp("datetime")); | ||||
| 
 | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     public static PreparedStatement buildRealmQueryStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "SELECT * FROM `warehouse_realmhistory` WHERE `event_number` > ?"; | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
|         outStatement.setInt(1, WarehousePushThread.realmIndex); | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     void reset() { | ||||
| 
 | ||||
|         this.realm = null; | ||||
|         this.cityHash = null; | ||||
|         this.guildHash = null; | ||||
|         this.eventDateTime = null; | ||||
|         this.charterType = null; | ||||
|     } | ||||
| 
 | ||||
|     public void release() { | ||||
|         this.reset(); | ||||
|         recordPool.add(this); | ||||
|     } | ||||
| 
 | ||||
|     private PreparedStatement buildRealmInsertStatement(Connection connection) throws SQLException { | ||||
| 
 | ||||
|         PreparedStatement outStatement = null; | ||||
|         String queryString = "INSERT INTO `warehouse_realmhistory` (`realm_id`, `realm_name`, `charter`, `city_id`, `guild_id`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?)"; | ||||
|         outStatement = connection.prepareStatement(queryString); | ||||
| 
 | ||||
|         // Bind Record Data
 | ||||
| 
 | ||||
|         outStatement.setString(1, realm.getHash()); | ||||
|         outStatement.setString(2, realm.getRealmName()); | ||||
|         outStatement.setString(3, charterType); | ||||
|         outStatement.setString(4, cityHash); | ||||
|         outStatement.setString(5, guildHash); | ||||
|         outStatement.setString(6, eventType.name()); | ||||
|         outStatement.setTimestamp(7,  Timestamp.valueOf(this.eventDateTime)); | ||||
| 
 | ||||
|         return outStatement; | ||||
|     } | ||||
| 
 | ||||
|     public void write() { | ||||
| 
 | ||||
|         try (Connection connection = DataWarehouse.connectionPool.getConnection(); | ||||
|              PreparedStatement statement = this.buildRealmInsertStatement(connection)) { | ||||
| 
 | ||||
|             statement.execute(); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,202 @@@@ -0,0 +1,202 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.gameManager.ConfigManager; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.Account; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbAccountHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbAccountHandler() { | ||||
| 		this.localClass = Account.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public Account GET_ACCOUNT(int id) { | ||||
| 		if (id == 0) | ||||
| 			return null; | ||||
| 		Account account = (Account) DbManager.getFromCache(GameObjectType.Account, id); | ||||
| 		if (account != null) | ||||
| 			return account; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `obj_account` WHERE `UID`=?"); | ||||
| 		setLong(1, (long) id); | ||||
| 
 | ||||
| 		Account ac = null; | ||||
| 		ac = (Account) getObjectSingle(id); | ||||
| 
 | ||||
| 		if (ac != null) | ||||
| 			ac.runAfterLoad(); | ||||
| 
 | ||||
| 		return ac; | ||||
| 	} | ||||
| 
 | ||||
| 	public void SET_TRASH(String machineID) { | ||||
| 
 | ||||
| 		prepareCallable("INSERT INTO dyn_trash(`machineID`, `count`)" | ||||
| 				+ " VALUES (?, 1) ON DUPLICATE KEY UPDATE `count` = `count` + 1;"); | ||||
| 
 | ||||
| 		setString(1, machineID); | ||||
| 		executeUpdate(); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<String> GET_TRASH_LIST() { | ||||
| 
 | ||||
| 		ArrayList<String> machineList = new ArrayList<>(); | ||||
| 
 | ||||
| 		prepareCallable("select `machineID` from `dyn_trash`"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 				machineList.add(rs.getString(1)); | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 		return machineList; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean DELETE_VAULT_FOR_ACCOUNT(final int accountID) { | ||||
| 		prepareCallable("DELETE FROM `object` WHERE `parent`=? && `type`='item'"); | ||||
| 		setLong(1, (long) accountID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<PlayerCharacter> GET_ALL_CHARS_FOR_MACHINE(String machineID) { | ||||
| 
 | ||||
| 		ArrayList<PlayerCharacter> trashList = new ArrayList<>(); | ||||
| 
 | ||||
| 		prepareCallable("select DISTINCT UID from object \n" + | ||||
| 				"where parent IN (select AccountID from dyn_login_history " + | ||||
| 		        " WHERE`machineID`=?)"); | ||||
| 		setString(1, machineID); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				PlayerCharacter trashPlayer; | ||||
| 				int playerID; | ||||
| 
 | ||||
| 				playerID = rs.getInt(1); | ||||
| 				trashPlayer = PlayerCharacter.getPlayerCharacter(playerID); | ||||
| 
 | ||||
| 				if (trashPlayer == null) | ||||
| 					continue;; | ||||
| 
 | ||||
| 				if (trashPlayer.isDeleted() == false) | ||||
| 					trashList.add(trashPlayer); | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return  trashList; | ||||
| 	} | ||||
| 
 | ||||
| 	public void CLEAR_TRASH_TABLE() { | ||||
| 		prepareCallable("DELETE FROM dyn_trash"); | ||||
| 		executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public Account GET_ACCOUNT(String uname) { | ||||
| 
 | ||||
| 		if (Account.AccountsMap.get(uname) != null) | ||||
| 			return this.GET_ACCOUNT(Account.AccountsMap.get(uname)); | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `obj_account` WHERE `acct_uname`=?"); | ||||
| 		setString(1, uname); | ||||
| 		ArrayList<Account> temp = getObjectList(); | ||||
| 
 | ||||
| 		if (temp.isEmpty()) | ||||
| 			return null; | ||||
| 
 | ||||
| 		if (temp.get(0) != null){ | ||||
| 			temp.get(0).runAfterLoad(); | ||||
| 
 | ||||
| 			if (ConfigManager.serverType.equals(Enum.ServerType.LOGINSERVER)) | ||||
| 				Account.AccountsMap.put(uname, temp.get(0).getObjectUUID()); | ||||
| 
 | ||||
| 		} | ||||
| 		return temp.get(0); | ||||
| 	} | ||||
| 
 | ||||
| 	public void SET_ACCOUNT_LOGIN(final Account acc, String playerName, final String ip, final String machineID) { | ||||
| 
 | ||||
| 		if (acc.getObjectUUID() == 0 || ip == null || ip.length() == 0) | ||||
| 			return; | ||||
| 
 | ||||
| 		prepareCallable("INSERT INTO dyn_login_history(`AccountID`, `accountName`, `characterName`, `ip`, `machineID`, `timeStamp`)" | ||||
| 				+ " VALUES (?, ?, ?, ?, ?, ?)"); | ||||
| 
 | ||||
| 		setInt(1, acc.getObjectUUID()); | ||||
| 		setString(2, acc.getUname()); | ||||
| 		setString(3, playerName); | ||||
| 		setString(4, ip); | ||||
| 		setString(5, machineID); | ||||
| 		setTimeStamp(6, System.currentTimeMillis()); | ||||
| 		executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Account a, String name, Object new_value) { | ||||
| 		prepareCallable("CALL account_SETPROP(?,?,?)"); | ||||
| 		setLong(1, (long) a.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Account a, String name, Object new_value, Object old_value) { | ||||
| 		prepareCallable("CALL account_GETSETPROP(?,?,?,?)"); | ||||
| 		setLong(1, (long) a.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		setString(4, String.valueOf(old_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public void updateDatabase(final Account acc) { | ||||
| 		prepareCallable("UPDATE `obj_account` SET `acct_passwd`=?, " | ||||
| 				+ " `acct_lastCharUID`=?, `acct_salt`=?, `discordAccount`=?, " + | ||||
| 				" status = ? WHERE `UID`=?"); | ||||
| 
 | ||||
| 		setString(1, acc.getPasswd()); | ||||
| 		setInt(2, acc.getLastCharIDUsed()); | ||||
| 		setString(3, acc.getSalt()); | ||||
| 		setString(4, acc.discordAccount); | ||||
| 		setString(5, acc.status.name()); | ||||
| 		setInt(6, acc.getObjectUUID()); | ||||
| 		executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public void INVALIDATE_LOGIN_CACHE(long accountUID, String objectType) { | ||||
| 		prepareCallable("INSERT IGNORE INTO login_cachelist (`UID`, `type`) VALUES(?,?);"); | ||||
| 		setLong(1, accountUID); | ||||
| 		setString(2, objectType); | ||||
| 		executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,115 @@@@ -0,0 +1,115 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.Bane; | ||||
| import engine.objects.Building; | ||||
| import engine.objects.City; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import org.joda.time.DateTime; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| import java.util.logging.Level; | ||||
| 
 | ||||
| public class dbBaneHandler extends dbHandlerBase { | ||||
| 
 | ||||
|     public dbBaneHandler() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public boolean CREATE_BANE(City city, PlayerCharacter owner, Building stone) { | ||||
| 
 | ||||
|         prepareCallable("INSERT INTO `dyn_banes` (`cityUUID`, `ownerUUID`, `stoneUUID`, `placementDate`) VALUES(?,?,?,?)"); | ||||
|         setLong(1, (long) city.getObjectUUID()); | ||||
|         setLong(2, (long) owner.getObjectUUID()); | ||||
|         setLong(3, (long) stone.getObjectUUID()); | ||||
|         setTimeStamp(4, System.currentTimeMillis()); | ||||
| 
 | ||||
|         return (executeUpdate() > 0); | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public Bane LOAD_BANE(int cityUUID) { | ||||
| 
 | ||||
|         Bane newBane = null; | ||||
| 
 | ||||
|         try { | ||||
| 
 | ||||
|             prepareCallable("SELECT * from dyn_banes WHERE `dyn_banes`.`cityUUID` = ?"); | ||||
| 
 | ||||
|             setLong(1, (long) cityUUID); | ||||
|             ResultSet rs = executeQuery(); | ||||
| 
 | ||||
|             if (rs.next()) { | ||||
|                 newBane = new Bane(rs); | ||||
|                 Bane.addBane(newBane); | ||||
|             } | ||||
| 
 | ||||
|         } catch (SQLException ex) { | ||||
|             java.util.logging.Logger.getLogger(dbBaneHandler.class.getName()).log(Level.SEVERE, null, ex); | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|         return newBane; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public ConcurrentHashMap<Integer, Bane> LOAD_ALL_BANES() { | ||||
| 
 | ||||
|         ConcurrentHashMap<Integer, Bane> baneList; | ||||
|         Bane thisBane; | ||||
| 
 | ||||
|         baneList = new ConcurrentHashMap<>(); | ||||
| 
 | ||||
|         int recordsRead = 0; | ||||
| 
 | ||||
|         prepareCallable("SELECT * FROM dyn_banes"); | ||||
| 
 | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
| 
 | ||||
|                 recordsRead++; | ||||
|                 thisBane = new Bane(rs); | ||||
|                 baneList.put(thisBane.getCityUUID(), thisBane); | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
|             Logger.info("read: " + recordsRead + " cached: " + baneList.size()); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error( e.toString()); | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|         return baneList; | ||||
|     } | ||||
| 
 | ||||
|     public boolean SET_BANE_TIME(DateTime toSet, int cityUUID) { | ||||
|         prepareCallable("UPDATE `dyn_banes` SET `liveDate`=? WHERE `cityUUID`=?"); | ||||
|         setTimeStamp(1, toSet.getMillis()); | ||||
|         setLong(2, cityUUID); | ||||
|         return (executeUpdate() > 0); | ||||
|     } | ||||
| 
 | ||||
|     public boolean REMOVE_BANE(Bane bane) { | ||||
| 
 | ||||
|         if (bane == null) | ||||
|             return false; | ||||
| 
 | ||||
|         prepareCallable("DELETE FROM `dyn_banes` WHERE `cityUUID` = ?"); | ||||
|         setLong(1, (long) bane.getCity().getObjectUUID()); | ||||
|         return (executeUpdate() > 0); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,50 @@@@ -0,0 +1,50 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.BaseClass; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbBaseClassHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbBaseClassHandler() { | ||||
| 		this.localClass = BaseClass.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.BaseClass; | ||||
| 	} | ||||
| 
 | ||||
| 	public BaseClass GET_BASE_CLASS(final int id) { | ||||
| 
 | ||||
| 		if (id == 0) | ||||
| 			return null; | ||||
| 		BaseClass baseClass = (BaseClass) DbManager.getFromCache(GameObjectType.BaseClass, id); | ||||
| 		if (baseClass != null) | ||||
| 			return baseClass; | ||||
| 
 | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `static_rune_baseclass` WHERE `ID` = ?;"); | ||||
| 		setInt(1, id); | ||||
| 		return (BaseClass) getObjectSingle(id); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<BaseClass> GET_BASECLASS_FOR_RACE(final int id) { | ||||
| 		prepareCallable("SELECT b.* FROM `static_rune_baseclass` b, `static_rune_racebaseclass` r WHERE b.`ID` = r.`BaseClassID` && r.`RaceID` = ?"); | ||||
| 		setInt(1, id); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<BaseClass> GET_ALL_BASE_CLASSES(){ | ||||
| 		prepareCallable("SELECT * FROM `static_rune_baseclass`;"); | ||||
| 		return  getObjectList(); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,86 @@@@ -0,0 +1,86 @@ | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.Blueprint; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.HashMap; | ||||
| 
 | ||||
| public class dbBlueprintHandler extends dbHandlerBase { | ||||
| 
 | ||||
|     public dbBlueprintHandler() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public HashMap<Integer, Integer> LOAD_ALL_DOOR_NUMBERS() { | ||||
| 
 | ||||
|         HashMap<Integer, Integer> doorInfo; | ||||
|         doorInfo = new HashMap<>(); | ||||
| 
 | ||||
|         int doorUUID; | ||||
|         int doorNum; | ||||
|         int recordsRead = 0; | ||||
| 
 | ||||
|         prepareCallable("SELECT * FROM static_building_doors ORDER BY doorMeshUUID ASC"); | ||||
| 
 | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
| 
 | ||||
|                 recordsRead++; | ||||
|                 doorUUID = rs.getInt("doorMeshUUID"); | ||||
|                 doorNum = rs.getInt("doorNumber"); | ||||
|                 doorInfo.put(doorUUID, doorNum); | ||||
|             } | ||||
| 
 | ||||
|             Logger.info( "read: " + recordsRead + " cached: " + doorInfo.size()); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error("LoadAllDoorNumbers: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|         return doorInfo; | ||||
|     } | ||||
| 
 | ||||
|     public HashMap<Integer, Blueprint> LOAD_ALL_BLUEPRINTS() { | ||||
| 
 | ||||
|         HashMap<Integer, Blueprint> blueprints; | ||||
|         Blueprint thisBlueprint; | ||||
| 
 | ||||
|         blueprints = new HashMap<>(); | ||||
|         int recordsRead = 0; | ||||
| 
 | ||||
|         prepareCallable("SELECT * FROM static_building_blueprint"); | ||||
| 
 | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
| 
 | ||||
|                 recordsRead++; | ||||
|                 thisBlueprint = new Blueprint(rs); | ||||
| 
 | ||||
|                 blueprints.put(thisBlueprint.getBlueprintUUID(), thisBlueprint); | ||||
| 
 | ||||
|                 // load mesh cache
 | ||||
|                 Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(-1), thisBlueprint); | ||||
|                 Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(0), thisBlueprint); | ||||
|                 Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(1), thisBlueprint); | ||||
|                 Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(3), thisBlueprint); | ||||
|                 Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(7), thisBlueprint); | ||||
| 
 | ||||
|             } | ||||
| 
 | ||||
|             Logger.info( "read: " + recordsRead + " cached: " + blueprints.size()); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error("LoadAllBlueprints: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|         return blueprints; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,51 @@@@ -0,0 +1,51 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.Boon; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbBoonHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbBoonHandler() { | ||||
| 	} | ||||
| 	 | ||||
| 
 | ||||
| 	public ArrayList<Boon>  GET_BOON_AMOUNTS_FOR_ITEMBASEUUID(int itemBaseUUID){ | ||||
|          | ||||
|         ArrayList<Boon>boons = new ArrayList<>(); | ||||
|         Boon thisBoon; | ||||
|         prepareCallable("SELECT * FROM `static_item_boons`  WHERE `itemBaseID` = ?"); | ||||
|         setInt(1, itemBaseUUID); | ||||
| 
 | ||||
| 	try { | ||||
| 		ResultSet rs = executeQuery(); | ||||
|                      | ||||
| 		while (rs.next()) { | ||||
|                          | ||||
|                       | ||||
|                       thisBoon = new Boon(rs); | ||||
|                       boons.add(thisBoon); | ||||
| 		} | ||||
|                      | ||||
|    | ||||
|                              | ||||
| 	} catch (SQLException e) { | ||||
| 		Logger.error("GetBoonAmountsForItembaseUUID: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 	} finally { | ||||
| 		closeCallable(); | ||||
| 	} | ||||
| 	return boons; | ||||
| } | ||||
| } | ||||
| @ -0,0 +1,809 @@@@ -0,0 +1,809 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.DbObjectType; | ||||
| import engine.Enum.ProtectionState; | ||||
| import engine.Enum.TaxType; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.joda.time.DateTime; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.awt.geom.Line2D; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.time.LocalDateTime; | ||||
| import java.time.ZoneId; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| public class dbBuildingHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbBuildingHandler() { | ||||
| 		this.localClass = Building.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public Building CREATE_BUILDING(Building b) { | ||||
| 		try { | ||||
| 			b = this.addBuilding(b); | ||||
| 			b.setObjectTypeMask(MBServerStatics.MASK_BUILDING); | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error(e); | ||||
| 			b = null; | ||||
| 		} | ||||
| 		return b; | ||||
| 	} | ||||
| 
 | ||||
| 	/* | ||||
| 	 * | ||||
| 	 * @param worldServerID | ||||
| 	 * @param OwnerUUID | ||||
| 	 * @param name | ||||
| 	 * @param meshUUID | ||||
| 	 * @param meshScale | ||||
| 	 * @param currentHP | ||||
| 	 * @param protectionState | ||||
| 	 * @param currentGold | ||||
| 	 * @param rank | ||||
| 	 * @param upgradeDate | ||||
| 	 * @param blueprintUUID | ||||
| 	 * @param w | ||||
| 	 * @param rotY | ||||
| 	 * @return | ||||
| 	 */ | ||||
| 	public Building CREATE_BUILDING(int parentZoneID, int OwnerUUID, String name, int meshUUID, | ||||
| 									Vector3fImmutable location, float meshScale, int currentHP, | ||||
| 									ProtectionState protectionState, int currentGold, int rank, | ||||
| 									DateTime upgradeDate, int blueprintUUID, float w, float rotY) { | ||||
| 
 | ||||
| 		Building toCreate = null; | ||||
| 		try { | ||||
| 
 | ||||
| 			prepareCallable("CALL `building_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,? ,? ,?, ?);"); | ||||
| 
 | ||||
| 			setInt(1, parentZoneID); | ||||
| 			setInt(2, OwnerUUID); | ||||
| 			setString(3, name); | ||||
| 			setInt(4, meshUUID); | ||||
| 			setFloat(5, location.x); | ||||
| 			setFloat(6, location.y); | ||||
| 			setFloat(7, location.z); | ||||
| 			setFloat(8, meshScale); | ||||
| 			setInt(9, currentHP); | ||||
| 			setString(10, protectionState.name()); | ||||
| 			setInt(11, currentGold); | ||||
| 			setInt(12, rank); | ||||
| 
 | ||||
| 			if (upgradeDate != null) | ||||
| 				setTimeStamp(13, upgradeDate.getMillis()); | ||||
| 			else | ||||
| 				setNULL(13, java.sql.Types.DATE); | ||||
| 
 | ||||
| 			setInt(14, blueprintUUID); | ||||
| 			setFloat(15, w); | ||||
| 			setFloat(16, rotY); | ||||
| 
 | ||||
| 			int objectUUID = (int) getUUID(); | ||||
| 
 | ||||
| 			if (objectUUID > 0) | ||||
| 				toCreate = GET_BUILDINGBYUUID(objectUUID); | ||||
| 
 | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error("CREATE_BUILDING", e.getMessage()); | ||||
| 			return null; | ||||
| 		} | ||||
| 		return toCreate; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean DELETE_FROM_DATABASE(final Building b) { | ||||
| 
 | ||||
| 		return removeFromBuildings(b); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Building> GET_ALL_BUILDINGS_FOR_ZONE(Zone zone) { | ||||
| 		prepareCallable("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;"); | ||||
| 		setLong(1, zone.getObjectUUID()); | ||||
| 		return getLargeObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Building> GET_ALL_BUILDINGS() { | ||||
| 		prepareCallable("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID`;"); | ||||
| 		return getLargeObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public Building GET_BUILDINGBYUUID(int uuid) { | ||||
| 		if (uuid == 0) | ||||
| 			return null; | ||||
| 
 | ||||
| 		Building building = (Building) DbManager.getFromCache(Enum.GameObjectType.Building, uuid); | ||||
| 
 | ||||
| 		if (building != null) | ||||
| 			return building; | ||||
| 
 | ||||
| 		prepareCallable("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?;"); | ||||
| 
 | ||||
| 		setLong(1, (long) uuid); | ||||
| 		return (Building) getObjectSingle(uuid); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public Building GET_BUILDING_BY_MESH(final int meshID) { | ||||
| 		Building toReturn = null; | ||||
| 		prepareCallable("CALL building_GETBYMESH(?)"); | ||||
| 		setInt(1, meshID); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			if (rs.next()) | ||||
| 				toReturn = new Building(rs); | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("Building", e); | ||||
| 			return null; | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return toReturn; | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Building b, String name, Object new_value) { | ||||
| 		prepareCallable("CALL building_SETPROP(?,?,?)"); | ||||
| 		setLong(1, b.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Building b, String name, Object new_value, Object old_value) { | ||||
| 		prepareCallable("CALL building_GETSETPROP(?,?,?,?)"); | ||||
| 		setLong(1, b.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		setString(4, String.valueOf(old_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public int MOVE_BUILDING(long buildingID, long parentID, float locX, float locY, float locZ) { | ||||
| 		prepareCallable("UPDATE `object` INNER JOIN `obj_building` On `object`.`UID` = `obj_building`.`UID` SET `object`.`parent`=?, `obj_building`.`locationX`=?, `obj_building`.`locationY`=?, `obj_building`.`locationZ`=? WHERE `obj_building`.`UID`=?;"); | ||||
| 		setLong(1, parentID); | ||||
| 		setFloat(2, locX); | ||||
| 		setFloat(3, locY); | ||||
| 		setFloat(4, locZ); | ||||
| 		setLong(5, buildingID); | ||||
| 		return executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	private Building addBuilding(Building toAdd) { | ||||
| 		prepareCallable("CALL `building_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | ||||
| 		setLong(1, toAdd.getParentZoneID()); | ||||
| 		setLong(2, toAdd.getOwnerUUID()); | ||||
| 		setString(3, toAdd.getName()); | ||||
| 		setInt(4, toAdd.getMeshUUID()); | ||||
| 		setFloat(5, toAdd.getStatLat()); | ||||
| 		setFloat(6, toAdd.getStatAlt()); | ||||
| 		setFloat(7, toAdd.getStatLon()); | ||||
| 		setFloat(8, toAdd.getMeshScale().x); | ||||
| 		setInt(9, (int) toAdd.getHealth()); | ||||
| 		setString(10, toAdd.getProtectionState().name()); | ||||
| 		setInt(11, toAdd.getStrongboxValue()); | ||||
| 		setInt(12, toAdd.getRank()); | ||||
| 
 | ||||
| 		// Write Joda DateTime to database
 | ||||
| 		// *** Refactor : Wrap this logic in our
 | ||||
| 		// own override setDateTime() ?
 | ||||
| 		if (toAdd.getUpgradeDateTime() != null) | ||||
| 			setLocalDateTime(13, toAdd.getUpgradeDateTime()); | ||||
| 		else | ||||
| 			setNULL(13, java.sql.Types.DATE); | ||||
| 
 | ||||
| 		setInt(14, toAdd.getBlueprintUUID()); | ||||
| 		setFloat(15, toAdd.getw()); | ||||
| 		setFloat(16, toAdd.getRot().y); | ||||
| 
 | ||||
| 		int objectUUID = (int) getUUID(); | ||||
| 
 | ||||
| 		if (objectUUID > 0) | ||||
| 			return GET_BUILDINGBYUUID(objectUUID); | ||||
| 		return null; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	private boolean removeFromBuildings(final Building b) { | ||||
| 		prepareCallable("DELETE FROM `object` WHERE `UID` = ?"); | ||||
| 		setLong(1, b.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ClaimAsset(final long SetBuildingID, int newowner, int OldOwner) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_building` SET `ownerUUID`=? WHERE `UID`=? and `ownerUUID`= ?"); | ||||
| 		setInt(1, newowner); | ||||
| 		setLong(2, SetBuildingID); | ||||
| 		setLong(3, OldOwner); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CHANGE_NAME(Building b, String newName) { | ||||
| 		prepareCallable("UPDATE `obj_building` SET `name`=? WHERE `UID`=?"); | ||||
| 		setString(1, newName); | ||||
| 		setLong(2, b.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean SET_RESERVE(Building b, int reserveAmount) { | ||||
| 		prepareCallable("UPDATE `obj_building` SET `reserve`=? WHERE `UID`=?"); | ||||
| 		setInt(1, reserveAmount); | ||||
| 		setLong(2, b.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	//CAS update to rank
 | ||||
| 	public boolean CHANGE_RANK(final long buildingID, int newRank) { | ||||
| 		prepareCallable("UPDATE `obj_building` SET `rank`=? WHERE `UID`=?"); | ||||
| 		setInt(1, newRank); | ||||
| 		setLong(2, buildingID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_BUILDING_HEALTH(final long buildingID, int NewHealth) { | ||||
| 		prepareCallable("UPDATE `obj_building` SET `currentHP`=? WHERE `UID`=?"); | ||||
| 		setInt(1, NewHealth); | ||||
| 		setLong(2, buildingID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_BUILDING_ALTITUDE(final long buildingID, float newAltitude) { | ||||
| 		prepareCallable("UPDATE `obj_building` SET `locationY`=? WHERE `UID`=?"); | ||||
| 		setFloat(1, newAltitude); | ||||
| 		setLong(2, buildingID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_PROTECTIONSTATE(final long buildingUUID, ProtectionState protectionState) { | ||||
| 
 | ||||
| 		try { | ||||
| 			prepareCallable("UPDATE `obj_building` SET `protectionState`=? WHERE `UID`=?"); | ||||
| 			setString(1, protectionState.name()); | ||||
| 			setLong(2, buildingUUID); | ||||
| 			return (executeUpdate() > 0); | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error(e.toString()); | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_DOOR_LOCK(final int buildingUUID, int doorFlags) { | ||||
| 
 | ||||
| 		try { | ||||
| 			prepareCallable("UPDATE obj_building SET doorState = ? WHERE UID = ?"); | ||||
| 
 | ||||
| 			setInt(1, doorFlags); | ||||
| 			setInt(2, buildingUUID); | ||||
| 
 | ||||
| 			executeUpdate(); | ||||
| 			return true; | ||||
| 		} catch (Exception e) { | ||||
| 			return false; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_TO_FRIENDS_LIST(final long buildingID, final long friendID, final long guildID, final int friendType) { | ||||
| 		prepareCallable("INSERT INTO `dyn_building_friends` (`buildingUID`, `playerUID`,`guildUID`, `friendType`) VALUES (?,?,?,?)"); | ||||
| 		setLong(1, buildingID); | ||||
| 		setLong(2, friendID); | ||||
| 		setLong(3, guildID); | ||||
| 		setInt(4, friendType); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean REMOVE_FROM_FRIENDS_LIST(final long buildingID, long friendID, long guildID, int friendType) { | ||||
| 		prepareCallable("DELETE FROM `dyn_building_friends` WHERE `buildingUID`=? AND `playerUID`=? AND `guildUID` =? AND `friendType` = ?"); | ||||
| 		setLong(1, buildingID); | ||||
| 		setLong(2, friendID); | ||||
| 		setLong(3,guildID); | ||||
| 		setInt(4, friendType); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean REMOVE_FROM_CONDEMNED_LIST(final long buildingID, long friendID, long guildID, int friendType) { | ||||
| 		prepareCallable("DELETE FROM `dyn_building_condemned` WHERE `buildingUID`=? AND `playerUID`=? AND `guildUID` =? AND `friendType` = ?"); | ||||
| 		setLong(1, buildingID); | ||||
| 		setLong(2, friendID); | ||||
| 		setLong(3,guildID); | ||||
| 		setInt(4, friendType); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public void CLEAR_FRIENDS_LIST(final long buildingID) { | ||||
| 		prepareCallable("DELETE FROM `dyn_building_friends` WHERE `buildingUID`=?"); | ||||
| 		setLong(1, buildingID); | ||||
| 		executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public void CLEAR_CONDEMNED_LIST(final long buildingID) { | ||||
| 		prepareCallable("DELETE FROM `dyn_building_condemned` WHERE `buildingUID`=?"); | ||||
| 		setLong(1, buildingID); | ||||
| 		executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CLEAR_PATROL(final long buildingID) { | ||||
| 		prepareCallable("DELETE FROM `dyn_building_patrol_points` WHERE `buildingUID`=?"); | ||||
| 		setLong(1, buildingID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_ALL_FRIENDS_FOR_BUILDING(Building building) { | ||||
| 
 | ||||
| 		if (building == null) | ||||
| 			return; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `dyn_building_friends` WHERE `buildingUID` = ?"); | ||||
| 		setInt(1,building.getObjectUUID()); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 				BuildingFriends friend = new BuildingFriends(rs); | ||||
| 				switch(friend.getFriendType()){ | ||||
| 				case 7: | ||||
| 					building.getFriends().put(friend.getPlayerUID(), friend); | ||||
| 					break; | ||||
| 				case 8: | ||||
| 				case 9: | ||||
| 					building.getFriends().put(friend.getGuildUID(), friend); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("LOAD friends for building: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_ALL_CONDEMNED_FOR_BUILDING(Building building) { | ||||
| 
 | ||||
| 		if (building == null) | ||||
| 			return; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `dyn_building_condemned` WHERE `buildingUID` = ?"); | ||||
| 		setInt(1,building.getObjectUUID()); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 				Condemned condemn = new Condemned(rs); | ||||
| 				switch(condemn.getFriendType()){ | ||||
| 				case 2: | ||||
| 					building.getCondemned().put(condemn.getPlayerUID(), condemn); | ||||
| 					break; | ||||
| 				case 4: | ||||
| 				case 5: | ||||
| 					building.getCondemned().put(condemn.getGuildUID(), condemn); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("LOAD Condemned for building: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Vector3fImmutable> LOAD_PATROL_POINTS(Building building) { | ||||
| 		if (building == null) | ||||
| 			return null; | ||||
| 		ArrayList<Vector3fImmutable> patrolPoints = new ArrayList<>(); | ||||
| 
 | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `dyn_building_patrol_points` WHERE `buildingUID` = ?"); | ||||
| 		setInt(1,building.getObjectUUID()); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 				float x1 = rs.getFloat("patrolX"); | ||||
| 				float y1 = rs.getFloat("patrolY"); | ||||
| 				float z1 = rs.getFloat("patrolZ"); | ||||
| 				Vector3fImmutable patrolPoint = new Vector3fImmutable(x1,y1,z1); | ||||
| 				patrolPoints.add(patrolPoint); | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("LOAD Patrol Points for building: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 		return patrolPoints; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_TO_CONDEMNLIST(final long parentUID, final long playerUID, final long guildID, final int friendType) { | ||||
| 		prepareCallable("INSERT INTO `dyn_building_condemned` (`buildingUID`, `playerUID`,`guildUID`, `friendType`) VALUES (?,?,?,?)"); | ||||
| 		setLong(1, parentUID); | ||||
| 		setLong(2, playerUID); | ||||
| 		setLong(3, guildID); | ||||
| 		setInt(4, friendType); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_TO_PATROL(final long parentUID, final Vector3fImmutable patrolPoint) { | ||||
| 		prepareCallable("INSERT INTO `dyn_building_patrol_points` (`buildingUID`, `patrolX`,`patrolY`, `patrolZ`) VALUES (?,?,?,?)"); | ||||
| 		setLong(1, parentUID); | ||||
| 		setFloat(2, (int)patrolPoint.x); | ||||
| 		setFloat(3, (int)patrolPoint.y); | ||||
| 		setFloat(4, (int)patrolPoint.z); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_TO_COLLIDE(final long parentUID, final float startX, final float startY, final float endX, final float endY) { | ||||
| 		prepareCallable("INSERT INTO `static_building_colliders` (`MeshID`, `startX`,`startY`, `endX`, `endY`) VALUES (?,?,?,?,?)"); | ||||
| 		setLong(1, parentUID); | ||||
| 		setFloat(2, startX); | ||||
| 		setFloat(3, startY); | ||||
| 		setFloat(4, endX); | ||||
| 		setFloat(5, endY); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Line2D.Float> GET_COLLIDERS(final long meshID) { | ||||
| 		ArrayList<Line2D.Float> colliders = new ArrayList<>(); | ||||
| 		prepareCallable("SELECT * FROM `static_building_colliders` WHERE `MeshID`=? AND `doorID` =0"); | ||||
| 		setLong(1, meshID); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 				int startX = rs.getInt("startX"); | ||||
| 				int startY = rs.getInt("startY"); | ||||
| 				int endX = rs.getInt("endX"); | ||||
| 				int endY = rs.getInt("endY"); | ||||
| 				colliders.add(new Line2D.Float(startX,startY,endX,endY)); | ||||
| 			} | ||||
| 
 | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("dbBuildingHandler.GET_COLLIDERS", e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return colliders; | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Line2D.Float> GET_DOOR_COLLIDERS(final long meshID) { | ||||
| 		ArrayList<Line2D.Float> colliders = new ArrayList<>(); | ||||
| 		prepareCallable("SELECT * FROM `static_building_colliders` WHERE `MeshID`=? AND `doorID` <> 0"); | ||||
| 		setLong(1, meshID); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 				int startX = rs.getInt("startX"); | ||||
| 				int startY = rs.getInt("startY"); | ||||
| 				int endX = rs.getInt("endX"); | ||||
| 				int endY = rs.getInt("endY"); | ||||
| 				colliders.add(new Line2D.Float(startX,startY,endX,endY)); | ||||
| 			} | ||||
| 
 | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("dbBuildingHandler.GET_COLLIDERS", e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return colliders; | ||||
| 	} | ||||
| 	public HashMap<Integer, ArrayList<BuildingRegions>> LOAD_BUILDING_REGIONS() { | ||||
| 
 | ||||
| 		HashMap<Integer, ArrayList<BuildingRegions>> regions; | ||||
| 		BuildingRegions thisRegions; | ||||
| 
 | ||||
| 
 | ||||
| 		regions = new HashMap<>(); | ||||
| 		int recordsRead = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_building_regions"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 				thisRegions = new BuildingRegions(rs); | ||||
| 				if (regions.get(thisRegions.getBuildingID()) == null){ | ||||
| 					ArrayList<BuildingRegions> regionsList = new ArrayList<>(); | ||||
| 					regionsList.add(thisRegions); | ||||
| 					regions.put(thisRegions.getBuildingID(), regionsList); | ||||
| 				} | ||||
| 				else{ | ||||
| 					ArrayList<BuildingRegions>regionsList = regions.get(thisRegions.getBuildingID()); | ||||
| 					regionsList.add(thisRegions); | ||||
| 					regions.put(thisRegions.getBuildingID(), regionsList); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			Logger.info( "read: " + recordsRead + " cached: " + regions.size()); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(": " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return regions; | ||||
| 	} | ||||
| 	 | ||||
| 	public HashMap<Integer, MeshBounds> LOAD_MESH_BOUNDS() { | ||||
| 
 | ||||
| 		HashMap<Integer, MeshBounds> meshBoundsMap; | ||||
| 		MeshBounds meshBounds; | ||||
| 
 | ||||
| 		meshBoundsMap = new HashMap<>(); | ||||
| 		int recordsRead = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_mesh_bounds"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 				meshBounds = new MeshBounds(rs); | ||||
| 				 | ||||
| 				meshBoundsMap.put(meshBounds.meshID, meshBounds); | ||||
| 				 | ||||
| 			} | ||||
| 
 | ||||
| 			Logger.info( "read: " + recordsRead + " cached: " + meshBoundsMap.size()); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("LoadMeshBounds: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return meshBoundsMap; | ||||
| 	} | ||||
| 
 | ||||
| 	public HashMap<Integer, ArrayList<StaticColliders>> LOAD_ALL_STATIC_COLLIDERS() { | ||||
| 
 | ||||
| 		HashMap<Integer, ArrayList<StaticColliders>> colliders; | ||||
| 		StaticColliders thisColliders; | ||||
| 
 | ||||
| 
 | ||||
| 		colliders = new HashMap<>(); | ||||
| 		int recordsRead = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_building_colliders"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 				thisColliders = new StaticColliders(rs); | ||||
| 				if (colliders.get(thisColliders.getMeshID()) == null){ | ||||
| 					ArrayList<StaticColliders> colliderList = new ArrayList<>(); | ||||
| 					colliderList.add(thisColliders); | ||||
| 					colliders.put(thisColliders.getMeshID(), colliderList); | ||||
| 				} | ||||
| 				else{ | ||||
| 					ArrayList<StaticColliders>colliderList = colliders.get(thisColliders.getMeshID()); | ||||
| 					colliderList.add(thisColliders); | ||||
| 					colliders.put(thisColliders.getMeshID(), colliderList); | ||||
| 				} | ||||
| 
 | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 			Logger.info( "read: " + recordsRead + " cached: " + colliders.size()); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("LoadAllBlueprints: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return colliders; | ||||
| 	} | ||||
| 
 | ||||
| 	// This public class inserted here as it's a generic utility function
 | ||||
| 	// with no other good place for it.  If you find a good home for it
 | ||||
| 	// feel free to move it.  -
 | ||||
| 
 | ||||
| 	public final DbObjectType GET_UID_ENUM(long object_UID) { | ||||
| 
 | ||||
| 		DbObjectType storedEnum = DbObjectType.INVALID; | ||||
| 		String typeString; | ||||
| 
 | ||||
| 		if (object_UID == 0) | ||||
| 			return storedEnum; | ||||
| 
 | ||||
| 		// Set up call to stored procedure
 | ||||
| 		prepareCallable("CALL object_UID_ENUM(?)"); | ||||
| 		setLong(1, object_UID); | ||||
| 
 | ||||
| 		try { | ||||
| 
 | ||||
| 			// Evaluate database ordinal and return enum
 | ||||
| 			storedEnum = DbObjectType.valueOf(getString("type").toUpperCase()); | ||||
| 
 | ||||
| 		} catch (Exception e) { | ||||
| 			storedEnum = DbObjectType.INVALID; | ||||
| 			Logger.error("UID_ENUM ", "Orphaned Object? Lookup failed for UID: " + object_UID); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return storedEnum; | ||||
| 	} | ||||
| 
 | ||||
| 	public ConcurrentHashMap<Integer, Integer> GET_FRIENDS(final long buildingID) { | ||||
| 		ConcurrentHashMap<Integer, Integer> friendsList = new ConcurrentHashMap<>(); | ||||
| 		prepareCallable("SELECT * FROM `dyn_building_friends` WHERE `buildingUID`=?"); | ||||
| 		setLong(1, buildingID); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 				int friendType = rs.getInt("friendType"); | ||||
| 				switch (friendType) { | ||||
| 				case 7: | ||||
| 					friendsList.put(rs.getInt("playerUID"), 7); | ||||
| 					break; | ||||
| 				case 8: | ||||
| 					friendsList.put(rs.getInt("guildUID"), 8); | ||||
| 					break; | ||||
| 				case 9: | ||||
| 					friendsList.put(rs.getInt("guildUID"), 9); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("dbBuildingHandler.GET_FRIENDS_GUILD_IC", e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return friendsList; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateBuildingRank(final Building b, int Rank) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_building` SET `rank`=?," | ||||
| 				+ "`upgradeDate`=?, `meshUUID`=?, `currentHP`=? " | ||||
| 				+ "WHERE `UID` = ?"); | ||||
| 
 | ||||
| 		setInt(1, Rank); | ||||
| 		setNULL(2, java.sql.Types.DATE); | ||||
| 		setInt(3, b.getBlueprint().getMeshForRank(Rank)); | ||||
| 		setInt(4, b.getBlueprint().getMaxHealth(Rank)); | ||||
| 		setInt(5, b.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateReverseKOS(final Building b, boolean reverse) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_building` SET `reverseKOS`=? " | ||||
| 				+ "WHERE `UID` = ?"); | ||||
| 		setBoolean(1, reverse); | ||||
| 		setInt(2, b.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateActiveCondemn(final Condemned condemn, boolean active) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `dyn_building_condemned` SET `active`=? " | ||||
| 				+ "WHERE`buildingUID` = ? AND `playerUID` = ? AND `guildUID` = ? AND `friendType` = ?"); | ||||
| 		setBoolean(1, active); | ||||
| 		setInt(2, condemn.getParent()); | ||||
| 		setInt(3, condemn.getPlayerUID()); | ||||
| 		setInt(4, condemn.getGuildUID()); | ||||
| 		setInt(5, condemn.getFriendType()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateBuildingOwner(final Building building, int ownerUUID) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_building` SET `ownerUUID`=? " | ||||
| 				+ " WHERE `UID` = ?"); | ||||
| 
 | ||||
| 		setInt(1, ownerUUID); | ||||
| 		setInt(2, building.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateBuildingUpgradeTime(LocalDateTime upgradeDateTime, Building toUpgrade, int costToUpgrade) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE obj_building SET upgradeDate=?, currentGold=? " | ||||
| 				+ "WHERE UID = ?"); | ||||
| 
 | ||||
| 		if (upgradeDateTime == null) | ||||
| 			setNULL(1, java.sql.Types.DATE); | ||||
| 		else | ||||
| 			setTimeStamp(1, upgradeDateTime.atZone(ZoneId.systemDefault()) | ||||
| 					.toInstant().toEpochMilli()); | ||||
| 
 | ||||
| 		setInt(2, toUpgrade.getStrongboxValue() - costToUpgrade); | ||||
| 		setInt(3, toUpgrade.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateMaintDate(Building building) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE obj_building SET maintDate=? " | ||||
| 				+ "WHERE UID = ?"); | ||||
| 
 | ||||
| 		if (building.maintDateTime == null) | ||||
| 			setNULL(1, java.sql.Types.DATE); | ||||
| 		else | ||||
| 			setLocalDateTime(1, building.maintDateTime); | ||||
| 
 | ||||
| 		setInt(2, building.getObjectUUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean addTaxes(Building building, TaxType taxType, int amount, boolean enforceKOS){ | ||||
| 		prepareCallable("UPDATE obj_building SET taxType=?, taxAmount = ?, enforceKOS = ? " | ||||
| 				+ "WHERE UID = ?"); | ||||
| 
 | ||||
| 		setString(1, taxType.name()); | ||||
| 		setInt(2, amount); | ||||
| 		setBoolean(3, enforceKOS); | ||||
| 		setInt(4, building.getObjectUUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean removeTaxes(Building building){ | ||||
| 		prepareCallable("UPDATE obj_building SET taxType=?, taxAmount = ?, enforceKOS = ?, taxDate = ? " | ||||
| 				+ "WHERE UID = ?"); | ||||
| 
 | ||||
| 		setString(1, TaxType.NONE.name()); | ||||
| 		setInt(2, 0); | ||||
| 		setBoolean(3, false); | ||||
| 		setNULL(4, java.sql.Types.DATE); | ||||
| 		setInt(5, building.getObjectUUID()); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean acceptTaxes(Building building) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE obj_building SET taxDate=? " | ||||
| 				+ "WHERE UID = ?"); | ||||
| 
 | ||||
| 		setTimeStamp(1, DateTime.now().plusDays(7).getMillis()); | ||||
| 		setInt(2, building.getObjectUUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,27 @@@@ -0,0 +1,27 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.BuildingLocation; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbBuildingLocationHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbBuildingLocationHandler() { | ||||
| 		this.localClass = BuildingLocation.class; | ||||
|         this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<BuildingLocation> LOAD_ALL_BUILDING_LOCATIONS() { | ||||
| 		prepareCallable("SELECT * FROM `static_building_location`;"); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,100 @@@@ -0,0 +1,100 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.Account; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.session.CSSession; | ||||
| import engine.util.StringUtils; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.net.InetAddress; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| 
 | ||||
| public class dbCSSessionHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbCSSessionHandler() { | ||||
| 		this.localClass = CSSession.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_CSSESSION(String secKey, Account acc, InetAddress inet, String machineID) { | ||||
|         prepareCallable("INSERT INTO `dyn_session` (`secretKey`, `accountID`, `discordAccount`, `sessionIP`, machineID) VALUES (?,?,?,INET_ATON(?),?)"); | ||||
|         setString(1, secKey); | ||||
| 		setLong(2, acc.getObjectUUID()); | ||||
| 		setString(3, acc.discordAccount); | ||||
|         setString(4, StringUtils.InetAddressToClientString(inet)); | ||||
|         setString(5, machineID); | ||||
|         return (executeUpdate() != 0); | ||||
|     } | ||||
| 	// This method returns population metrics from the database
 | ||||
| 
 | ||||
| 	public String GET_POPULATION_STRING() { | ||||
| 
 | ||||
| 		String outString = null; | ||||
| 
 | ||||
| 		// Set up call to stored procedure
 | ||||
| 		prepareCallable("CALL GET_POPULATION_STRING()"); | ||||
| 
 | ||||
| 		try { | ||||
| 
 | ||||
| 			// Evaluate database ordinal and return enum
 | ||||
| 			outString = getString("popstring"); | ||||
| 
 | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error( "Failure in stored procedure:" + e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return outString; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean DELETE_UNUSED_CSSESSION(String secKey) { | ||||
| 		prepareCallable("DELETE FROM `dyn_session` WHERE `secretKey`=? && `characterID` IS NULL"); | ||||
| 		setString(1, secKey); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean DELETE_CSSESSION(String secKey) { | ||||
| 		prepareCallable("DELETE FROM `dyn_session` WHERE `secretKey`=?"); | ||||
| 		setString(1, secKey); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_CSSESSION(String secKey, int charID) { | ||||
| 		prepareCallable("UPDATE `dyn_session` SET `characterID`=? WHERE `secretKey`=?"); | ||||
| 		setInt(1, charID); | ||||
| 		setString(2, secKey); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public CSSession GET_CSSESSION(String secKey) { | ||||
| 		CSSession css = null; | ||||
| 		prepareCallable("SELECT `accountID`, `characterID`, `machineID` FROM `dyn_session` WHERE `secretKey`=?"); | ||||
| 		setString(1, secKey); | ||||
| 		try { | ||||
| 
 | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			if (rs.next()) { | ||||
| 				css = new CSSession(secKey, DbManager.AccountQueries.GET_ACCOUNT(rs.getInt("accountID")), PlayerCharacter.getPlayerCharacter(rs | ||||
| 						.getInt("characterID")), getString("machineID")); | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("Error with seckey: " + secKey); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return css; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,113 @@@@ -0,0 +1,113 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.CharacterPower; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| public class dbCharacterPowerHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbCharacterPowerHandler() { | ||||
| 		this.localClass = CharacterPower.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public CharacterPower ADD_CHARACTER_POWER(CharacterPower toAdd) { | ||||
| 		if (CharacterPower.getOwner(toAdd) == null || toAdd.getPower() == null) { | ||||
| 			Logger.error("dbCharacterSkillHandler.ADD_Power", toAdd.getObjectUUID() + " missing owner or powersBase"); | ||||
| 			return null; | ||||
| 		} | ||||
| 
 | ||||
| 		prepareCallable("INSERT INTO `dyn_character_power` (`CharacterID`, `powersBaseToken`, `trains`) VALUES (?, ?, ?);"); | ||||
| 		setLong(1, (long)CharacterPower.getOwner(toAdd).getObjectUUID()); | ||||
| 		setInt(2, toAdd.getPower().getToken()); | ||||
| 		setInt(3, toAdd.getTrains()); | ||||
| 		int powerID = insertGetUUID(); | ||||
| 		return GET_CHARACTER_POWER(powerID); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public int DELETE_CHARACTER_POWER(final int objectUUID) { | ||||
| 		prepareCallable("DELETE FROM `dyn_character_power` WHERE `UID` = ?"); | ||||
| 		setLong(1, (long)objectUUID); | ||||
| 		return executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public CharacterPower GET_CHARACTER_POWER(int objectUUID) { | ||||
| 
 | ||||
| 		CharacterPower cp = (CharacterPower) DbManager.getFromCache(Enum.GameObjectType.CharacterPower, objectUUID); | ||||
| 		if (cp != null) | ||||
| 			return cp; | ||||
| 		prepareCallable("SELECT * FROM `dyn_character_power` WHERE `UID` = ?"); | ||||
| 		setLong(1, (long)objectUUID); | ||||
| 		return (CharacterPower) getObjectSingle(objectUUID); | ||||
| 	} | ||||
| 
 | ||||
| 	public ConcurrentHashMap<Integer, CharacterPower> GET_POWERS_FOR_CHARACTER(PlayerCharacter pc) { | ||||
| 		ConcurrentHashMap<Integer, CharacterPower> powers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); | ||||
| 		int objectUUID = pc.getObjectUUID(); | ||||
| 		prepareCallable("SELECT * FROM `dyn_character_power` WHERE CharacterID = ?"); | ||||
| 		setLong(1, (long)objectUUID); | ||||
| 		ResultSet rs = executeQuery(); | ||||
| 		try { | ||||
| 			while (rs.next()) { | ||||
| 				CharacterPower cp = new CharacterPower(rs, pc); | ||||
| 				if (cp.getPower() != null) | ||||
| 					powers.put(cp.getPower().getToken(), cp); | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("CharacterPower.getCharacterPowerForCharacter", "Exception:" + e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return powers; | ||||
| 	} | ||||
| 
 | ||||
| 	public void UPDATE_TRAINS(final CharacterPower pow) { | ||||
| 		//skip update if nothing changed
 | ||||
| 		if (!pow.isTrained()) | ||||
| 			return; | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `dyn_character_power` SET `trains`=? WHERE `UID`=?"); | ||||
| 		setShort(1, (short)pow.getTrains()); | ||||
| 		setInt(2, pow.getObjectUUID()); | ||||
| 		executeUpdate(); | ||||
| 		pow.setTrained(false); | ||||
| 	} | ||||
| 
 | ||||
| 	public void updateDatabase(final CharacterPower pow) { | ||||
| 		if (pow.getPower() == null) { | ||||
| 			Logger.error( "Failed to find powersBase for Power " + pow.getObjectUUID()); | ||||
| 			return; | ||||
| 		} | ||||
| 		if (CharacterPower.getOwner(pow) == null) { | ||||
| 			Logger.error( "Failed to find owner for Power " + pow.getObjectUUID()); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `dyn_character_power` SET `PowersBaseToken`=?, `CharacterID`=?, `trains`=? WHERE `UID`=?"); | ||||
| 		setInt(1, pow.getPower().getToken()); | ||||
| 		setInt(2, CharacterPower.getOwner(pow).getObjectUUID()); | ||||
| 		setShort(3, (short)pow.getTrains()); | ||||
| 		setInt(4, pow.getObjectUUID()); | ||||
| 		executeUpdate(); | ||||
| 		pow.setTrained(false); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,63 @@@@ -0,0 +1,63 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.CharacterRune; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbCharacterRuneHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbCharacterRuneHandler() { | ||||
| 		this.localClass = CharacterRune.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public CharacterRune ADD_CHARACTER_RUNE(final CharacterRune toAdd) { | ||||
| 		prepareCallable("INSERT INTO `dyn_character_rune` (`CharacterID`, `RuneBaseID`) VALUES (?, ?);"); | ||||
| 		setLong(1, (long)toAdd.getPlayerID()); | ||||
| 		setInt(2, toAdd.getRuneBaseID()); | ||||
| 		int runeID = insertGetUUID(); | ||||
| 		return GET_CHARACTER_RUNE(runeID); | ||||
| 	} | ||||
| 
 | ||||
| 	public CharacterRune GET_CHARACTER_RUNE(int runeID) { | ||||
| 
 | ||||
| 		CharacterRune charRune = (CharacterRune) DbManager.getFromCache(Enum.GameObjectType.CharacterRune, runeID); | ||||
| 		if (charRune != null) | ||||
| 			return charRune; | ||||
| 		prepareCallable("SELECT * FROM `dyn_character_rune` WHERE `UID`=?"); | ||||
| 		setInt(1, runeID); | ||||
| 		return (CharacterRune) getObjectSingle(runeID); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public boolean DELETE_CHARACTER_RUNE(final CharacterRune cr) { | ||||
| 		prepareCallable("DELETE FROM `dyn_character_rune` WHERE `UID`=?;"); | ||||
| 		setLong(1, (long)cr.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<CharacterRune> GET_RUNES_FOR_CHARACTER(final int characterId) { | ||||
| 		prepareCallable("SELECT * FROM `dyn_character_rune` WHERE `CharacterID` = ?"); | ||||
| 		setInt(1, characterId); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public void updateDatabase(final CharacterRune cr) { | ||||
| 		prepareCallable("UPDATE `dyn_character_rune` SET `CharacterID`=?, `RuneBaseID`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, cr.getPlayerID()); | ||||
| 		setInt(2, cr.getRuneBaseID()); | ||||
| 		setLong(3, (long) cr.getObjectUUID()); | ||||
| 		executeUpdate(); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,116 @@@@ -0,0 +1,116 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.AbstractCharacter; | ||||
| import engine.objects.CharacterSkill; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| public class dbCharacterSkillHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbCharacterSkillHandler() { | ||||
| 		this.localClass = CharacterSkill.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public CharacterSkill ADD_SKILL(CharacterSkill toAdd) { | ||||
| 		if (CharacterSkill.GetOwner(toAdd) == null || toAdd.getSkillsBase() == null) { | ||||
| 			Logger.error("dbCharacterSkillHandler.ADD_SKILL", toAdd.getObjectUUID() + " missing owner or skillsBase"); | ||||
| 			return null; | ||||
| 		} | ||||
| 
 | ||||
| 		prepareCallable("INSERT INTO `dyn_character_skill` (`CharacterID`, `skillsBaseID`, `trains`) VALUES (?, ?, ?);"); | ||||
| 		setLong(1, (long)CharacterSkill.GetOwner(toAdd).getObjectUUID()); | ||||
| 		setInt(2, toAdd.getSkillsBase().getObjectUUID()); | ||||
| 		setInt(3, toAdd.getNumTrains()); | ||||
| 		int skillID = insertGetUUID(); | ||||
| 		return GET_SKILL(skillID); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean DELETE_SKILL(final int objectUUID) { | ||||
| 		prepareCallable("DELETE FROM `dyn_character_skill` WHERE `UID` = ?"); | ||||
| 		setLong(1, (long)objectUUID); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public CharacterSkill GET_SKILL(final int objectUUID) { | ||||
| 		CharacterSkill skill = (CharacterSkill) DbManager.getFromCache(Enum.GameObjectType.CharacterSkill, objectUUID); | ||||
| 		if (skill != null) | ||||
| 			return skill; | ||||
| 		prepareCallable("SELECT * FROM `dyn_character_skill` WHERE `UID` = ?"); | ||||
| 		setInt(1, objectUUID); | ||||
| 		return (CharacterSkill) getObjectSingle(objectUUID); | ||||
| 	} | ||||
| 
 | ||||
| 	public ConcurrentHashMap<String, CharacterSkill> GET_SKILLS_FOR_CHARACTER(final AbstractCharacter ac) { | ||||
| 		ConcurrentHashMap<String, CharacterSkill> skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); | ||||
| 		if (ac == null || (!(ac.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)))) | ||||
| 			return skills; | ||||
| 		PlayerCharacter pc = (PlayerCharacter) ac; | ||||
| 		int objectUUID = pc.getObjectUUID(); | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `dyn_character_skill` WHERE `CharacterID` = ?"); | ||||
| 		setInt(1, objectUUID); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 				CharacterSkill cs = new CharacterSkill(rs, pc); | ||||
| 				if (cs.getSkillsBase() != null) | ||||
| 					skills.put(cs.getSkillsBase().getName(), cs); | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("CharacterSkill.getCharacterSkillForCharacter", e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return skills; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public void UPDATE_TRAINS(final CharacterSkill cs) { | ||||
| 		if (!cs.isTrained()) | ||||
| 			return; | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `dyn_character_skill` SET `trains`=? WHERE `UID` = ?"); | ||||
| 		setShort(1, (short)cs.getNumTrains()); | ||||
| 		setLong(2, (long)cs.getObjectUUID()); | ||||
| 		if (executeUpdate() != 0) | ||||
| 			cs.syncTrains(); | ||||
| 	} | ||||
| 
 | ||||
| 	public void updateDatabase(final CharacterSkill cs) { | ||||
| 		if (cs.getSkillsBase() == null) { | ||||
| 			Logger.error("Failed to find skillsBase for Skill " + cs.getObjectUUID()); | ||||
| 			return; | ||||
| 		} | ||||
| 		if (CharacterSkill.GetOwner(cs) == null) { | ||||
| 			Logger.error("Failed to find owner for Skill " + cs.getObjectUUID()); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `dyn_character_skill` SET `skillsBaseID`=?, `CharacterID`=?, `trains`=? WHERE `UID`=?"); | ||||
| 		setInt(1, cs.getSkillsBase().getObjectUUID()); | ||||
| 		setInt(2, CharacterSkill.GetOwner(cs).getObjectUUID()); | ||||
| 		setShort(3, (short)cs.getNumTrains()); | ||||
| 		setLong(4, (long)cs.getObjectUUID()); | ||||
| 		if (executeUpdate() != 0) | ||||
| 			cs.syncTrains(); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,196 @@@@ -0,0 +1,196 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.Building; | ||||
| import engine.objects.City; | ||||
| import engine.objects.Zone; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.net.UnknownHostException; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbCityHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbCityHandler() { | ||||
| 		this.localClass = City.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<AbstractGameObject> CREATE_CITY(int ownerID, int parentZoneID, int realmID, float xCoord, float yCoord, float zCoord, float rotation, float W, String name, LocalDateTime established) { | ||||
| 		prepareCallable("CALL `city_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?,?,?)"); | ||||
| 		LocalDateTime upgradeTime = LocalDateTime.now().plusHours(2); | ||||
| 		setLong(1, (long) ownerID); //objectUUID of owning player
 | ||||
| 		setLong(2, (long) parentZoneID); //objectUUID of parent (continent) zone
 | ||||
| 		setLong(3, (long) realmID); //objectUUID of realm city belongs in
 | ||||
| 		setFloat(4, xCoord); //xOffset from parentZone center
 | ||||
| 		setFloat(5, yCoord); //yOffset from parentZone center
 | ||||
| 		setFloat(6, zCoord); //zOffset from parentZone center
 | ||||
| 		setString(7, name); //city name
 | ||||
| 		setLocalDateTime(8, established); | ||||
| 		setFloat(9, rotation); | ||||
| 		setFloat(10, W); | ||||
| 		setLocalDateTime(11, upgradeTime); | ||||
| 		ArrayList<AbstractGameObject> list = new ArrayList<>(); | ||||
| 
 | ||||
| 		try { | ||||
| 			boolean work = execute(); | ||||
| 			if (work) { | ||||
| 				ResultSet rs = this.cs.get().getResultSet(); | ||||
| 				while (rs.next()) { | ||||
| 					addObject(list, rs); | ||||
| 				} | ||||
| 				rs.close(); | ||||
| 			} else { | ||||
| 				Logger.info("City Placement Failed: " + this.cs.get().toString()); | ||||
| 				return list; //city creation failure
 | ||||
| 			} | ||||
| 			while (this.cs.get().getMoreResults()) { | ||||
| 				ResultSet rs = this.cs.get().getResultSet(); | ||||
| 				while (rs.next()) { | ||||
| 					addObject(list, rs); | ||||
| 				} | ||||
| 				rs.close(); | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.info("City Placement Failed, SQLException: " + this.cs.get().toString() + e.toString()); | ||||
| 			return list; //city creation failure
 | ||||
| 		} catch (UnknownHostException e) { | ||||
| 			Logger.info("City Placement Failed, UnknownHostException: " + this.cs.get().toString()); | ||||
| 			return list; //city creation failure
 | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return list; | ||||
| 	} | ||||
| 
 | ||||
| 	public static void addObject(ArrayList<AbstractGameObject> list, ResultSet rs) throws SQLException, UnknownHostException { | ||||
| 		String type = rs.getString("type"); | ||||
| 		switch (type) { | ||||
| 		case "zone": | ||||
| 			Zone zone = new Zone(rs); | ||||
| 			DbManager.addToCache(zone); | ||||
| 			list.add(zone); | ||||
| 			break; | ||||
| 		case "building": | ||||
| 			Building building = new Building(rs); | ||||
| 			DbManager.addToCache(building); | ||||
| 			list.add(building); | ||||
| 			break; | ||||
| 		case "city": | ||||
| 			City city = new City(rs); | ||||
| 			DbManager.addToCache(city); | ||||
| 			list.add(city); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<City> GET_CITIES_BY_ZONE(final int objectUUID) { | ||||
| 		prepareCallable("SELECT `obj_city`.*, `object`.`parent` FROM `obj_city` INNER JOIN `object` ON `object`.`UID` = `obj_city`.`UID` WHERE `object`.`parent`=?;"); | ||||
| 		setLong(1, (long) objectUUID); | ||||
| 
 | ||||
|         return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public City GET_CITY(final int cityId) { | ||||
| 		City city = (City) DbManager.getFromCache(Enum.GameObjectType.City, cityId); | ||||
| 		if (city != null) | ||||
| 			return city; | ||||
| 		prepareCallable("SELECT `obj_city`.*, `object`.`parent` FROM `obj_city` INNER JOIN `object` ON `object`.`UID` = `obj_city`.`UID` WHERE `object`.`UID`=?;"); | ||||
| 		setLong(1, (long) cityId); | ||||
| 		city = (City) getObjectSingle(cityId); | ||||
| 		return city; | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final City c, String name, Object new_value) { | ||||
| 		prepareCallable("CALL city_SETPROP(?,?,?)"); | ||||
| 		setLong(1, (long) c.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final City c, String name, Object new_value, Object old_value) { | ||||
| 		prepareCallable("CALL city_GETSETPROP(?,?,?,?)"); | ||||
| 		setLong(1, (long) c.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		setString(4, String.valueOf(old_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateforceRename(City city, boolean value) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_city` SET `forceRename`=?" | ||||
| 				+ " WHERE `UID` = ?"); | ||||
| 		setByte(1, (value == true) ? (byte) 1 : (byte) 0); | ||||
| 		setInt(2, city.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateOpenCity(City city, boolean value) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_city` SET `open`=?" | ||||
| 				+ " WHERE `UID` = ?"); | ||||
| 		setByte(1, (value == true) ? (byte) 1 : (byte) 0); | ||||
| 		setInt(2, city.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateTOL(City city, int tolID) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_city` SET `treeOfLifeUUID`=?" | ||||
| 				+ " WHERE `UID` = ?"); | ||||
| 		setInt(1,tolID); | ||||
| 		setInt(2, city.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean renameCity(City city, String name) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_city` SET `name`=?" | ||||
| 				+ " WHERE `UID` = ?"); | ||||
| 		setString(1, name); | ||||
| 		setInt(2, city.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateSiegesWithstood(City city, int value) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_city` SET `siegesWithstood`=?" | ||||
| 				+ " WHERE `UID` = ?"); | ||||
| 		setInt(1, value); | ||||
| 		setInt(2, city.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateRealmTaxDate(City city, LocalDateTime localDateTime) { | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_city` SET `realmTaxDate` =?" | ||||
| 				+ " WHERE `UID` = ?"); | ||||
| 		setLocalDateTime(1, localDateTime); | ||||
| 		setInt(2,city.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean DELETE_CITY(final City city) { | ||||
| 
 | ||||
| 		prepareCallable("DELETE FROM `object` WHERE `UID` = ? AND `type` = 'city'"); | ||||
| 		setInt(1, city.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,157 @@@@ -0,0 +1,157 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.Contract; | ||||
| import engine.objects.ItemBase; | ||||
| import engine.objects.MobEquipment; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbContractHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbContractHandler() { | ||||
| 		this.localClass = Contract.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public Contract GET_CONTRACT(final int objectUUID) { | ||||
| 		Contract contract = (Contract) DbManager.getFromCache(Enum.GameObjectType.Contract, objectUUID); | ||||
| 		if (contract != null) | ||||
| 			return contract; | ||||
| 		if (objectUUID == 0) | ||||
| 			return null; | ||||
| 		prepareCallable("SELECT * FROM `static_npc_contract` WHERE `ID` = ?"); | ||||
| 		setInt(1, objectUUID); | ||||
| 		return (Contract) getObjectSingle(objectUUID); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Contract> GET_CONTRACT_BY_RACE(final int objectUUID) { | ||||
| 
 | ||||
| 		ArrayList<Contract> contracts = new ArrayList<>(); | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_npc_contract WHERE `mobbaseID` =?;"); | ||||
| 		setLong(1, objectUUID); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 				Contract contract = new Contract(rs); | ||||
| 				if (contract != null) | ||||
| 					contracts.add(contract); | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return contracts; | ||||
| 	} | ||||
| 
 | ||||
| 	public void GET_GENERIC_INVENTORY(final Contract contract) { | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `static_npc_inventoryset` WHERE `inventorySet` = ?;"); | ||||
| 		setInt(1, contract.inventorySet); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				//handle item base
 | ||||
| 				int itemBaseID = rs.getInt("itembaseID"); | ||||
| 
 | ||||
| 				ItemBase ib = ItemBase.getItemBase(itemBaseID); | ||||
| 
 | ||||
| 				if (ib != null) { | ||||
| 
 | ||||
| 					MobEquipment me = new MobEquipment(ib, 0, 0); | ||||
| 					contract.getSellInventory().add(me); | ||||
| 
 | ||||
| 					//handle magic effects
 | ||||
| 					String prefix = rs.getString("prefix"); | ||||
| 					int pRank = rs.getInt("pRank"); | ||||
| 					String suffix = rs.getString("suffix"); | ||||
| 					int sRank = rs.getInt("sRank"); | ||||
| 
 | ||||
| 					if (prefix != null) { | ||||
| 						me.setPrefix(prefix, pRank); | ||||
| 						me.setIsID(true); | ||||
| 					} | ||||
| 
 | ||||
| 					if (suffix != null) { | ||||
| 						me.setSuffix(suffix, sRank); | ||||
| 						me.setIsID(true); | ||||
| 					} | ||||
| 
 | ||||
| 				} | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode() + ' ' + e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public void GET_SELL_LISTS(final Contract con) { | ||||
| 		prepareCallable("SELECT * FROM `static_npc_contract_selltype` WHERE `contractID` = ?;"); | ||||
| 		setInt(1, con.getObjectUUID()); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			ArrayList<Integer> item = con.getBuyItemType(); | ||||
| 			ArrayList<Integer> skill = con.getBuySkillToken(); | ||||
| 			ArrayList<Integer> unknown = con.getBuyUnknownToken(); | ||||
| 			while (rs.next()) { | ||||
| 				int type = rs.getInt("type"); | ||||
| 				int value = rs.getInt("value"); | ||||
| 				if (type == 1) { | ||||
| 					item.add(value); | ||||
| 				} else if (type == 2) { | ||||
| 					skill.add(value); | ||||
| 				} else if (type == 3) { | ||||
| 					unknown.add(value); | ||||
| 				} | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode() + ' ' + e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateAllowedBuildings(final Contract con, final long slotbitvalue) { | ||||
| 		prepareCallable("UPDATE `static_npc_contract` SET `allowedBuildingTypeID`=? WHERE `contractID`=?"); | ||||
| 		setLong(1, slotbitvalue); | ||||
| 		setInt(2, con.getContractID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateDatabase(final Contract con) { | ||||
| 		prepareCallable("UPDATE `static_npc_contract` SET `contractID`=?, `name`=?, " | ||||
| 				+ "`mobbaseID`=?, `classID`=?, vendorDialog=?, iconID=?, allowedBuildingTypeID=? WHERE `ID`=?"); | ||||
| 		setInt(1, con.getContractID()); | ||||
| 		setString(2, con.getName()); | ||||
| 		setInt(3, con.getMobbaseID()); | ||||
| 		setInt(4, con.getClassID()); | ||||
| 		setInt(5, (con.getVendorDialog() != null) ? con.getVendorDialog().getObjectUUID() : 0); | ||||
| 		setInt(6, con.getIconID()); | ||||
| 		setInt(8, con.getObjectUUID()); | ||||
| 		setLong(7, con.getAllowedBuildings().toLong()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,181 @@@@ -0,0 +1,181 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| public class dbEffectsBaseHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbEffectsBaseHandler() { | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	public boolean CreateEffectBase(int token, String IDString,String name,int flags){ | ||||
| 		prepareCallable("INSERT INTO `wpak_static_power_effectbase` (`token`,`IDString`,`name`,`flags`) VALUES (?,?,?,?)"); | ||||
| 		setInt(1,token); | ||||
| 		setString(2,IDString); | ||||
| 		setString(3,name); | ||||
| 		setInt(4,flags); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean CreateEffectBaseRAW(String IDString,String type,String detail){ | ||||
| 		prepareCallable("INSERT INTO `wpak_effect_effectbase_raw` (`token`,`IDString`,`name`,`flags`) VALUES (?,?,?,?)"); | ||||
| 		setString(1,IDString); | ||||
| 		setString(2,type); | ||||
| 		setString(3,detail); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CreateEffectSource(String IDString,String source){ | ||||
| 		prepareCallable("INSERT INTO `wpak_static_power_sourcetype` (`IDString`,`source`) VALUES (?,?)"); | ||||
| 
 | ||||
| 		setString(1,IDString); | ||||
| 		setString(2,source); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean CreateEffectSourceRAW(String IDString,String type,String detail){ | ||||
| 		prepareCallable("INSERT INTO `wpak_effect_source_raw` (`effectID`,`type`, `text`) VALUES (?,?,?)"); | ||||
| 
 | ||||
| 		setString(1,IDString); | ||||
| 		setString(2,type); | ||||
| 		setString(3,detail); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CreateEffectCondition(String IDString,String powerOrEffect,String type,float amount,float ramp,byte useAddFormula,String damageType1,String damageType2,String damageType3){ | ||||
| 		prepareCallable("INSERT INTO `wpak_static_power_failcondition` (`IDString`,`powerOrEffect`,`type`,`amount`,`ramp`,`useAddFormula`,`damageType1`,`damageType2`,`damageType3`) VALUES (?,?,?,?,?,?,?,?,?)"); | ||||
| 		setString(1,IDString); | ||||
| 		setString(2,powerOrEffect); | ||||
| 		setString(3,type); | ||||
| 		setFloat(4,amount); | ||||
| 		setFloat(5,ramp); | ||||
| 		setByte(6,useAddFormula); | ||||
| 		setString(7,damageType1); | ||||
| 		setString(8,damageType2); | ||||
| 		setString(9,damageType3); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean CreateEffectConditionRAW(String IDString,String type,String detail){ | ||||
| 		prepareCallable("INSERT INTO `wpak_effect_condition_raw` (`effectID`,`type`, `text`) VALUES (?,?,?)"); | ||||
| 		setString(1,IDString); | ||||
| 		setString(2,type); | ||||
| 		setString(3,detail); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CreateEffectMod(String IDString,String modType,float minMod,float maxMod,float percentMod,float ramp,byte useRampAdd,String type,String string1,String string2){ | ||||
| 		prepareCallable("INSERT INTO `wpak_static_power_effectmod` (`IDString`,`modType`,`minMod`,`maxMod`,`percentMod`,`ramp`,`useRampAdd`,`type`,`string1`,`string2`) VALUES (?,?,?,?,?,?,?,?,?,?)"); | ||||
| 		setString(1, IDString); | ||||
| 		setString(2, modType); | ||||
| 		setFloat(3, minMod); | ||||
| 		setFloat(4, maxMod); | ||||
| 		setFloat(5, percentMod); | ||||
| 		setFloat(6, ramp); | ||||
| 		setByte(7, useRampAdd); | ||||
| 		setString(8, type); | ||||
| 		setString(9, string1); | ||||
| 		setString(10, string2); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean CreateEffectModRAW(String IDString,String type,String detail){ | ||||
| 		prepareCallable("INSERT INTO `wpak_effect_mod_raw` (`effectID`,`type`, `text`) VALUES (?,?,?)"); | ||||
| 		setString(1,IDString); | ||||
| 		setString(2,type); | ||||
| 		setString(3,detail); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 	 | ||||
| 
 | ||||
| 	public boolean CreatePowerPowerAction(String IDString,String type,String effectID,String effectID2,String deferredPowerID,float levelCap,float levelCapRamp,String damageType,int numIterations,String effectSourceToRemove,String trackFilter,int maxTrack,int mobID,int mobLevel,int simpleDamage,String transferFromType,String transferToType,float transferAmount,float transferRamp,float transferEfficiency,float transferEfficiencyRamp,int flags){ | ||||
| 		prepareCallable("INSERT INTO `wpak_static_power_poweraction` (`IDString`,`type`,`effectID`,`effectID2`,`deferredPowerID`,`levelCap`,`levelCapRamp`,`damageType`,`numIterations`,`effectSourceToRemove`,`trackFilter`,`maxTrack`,`mobID`,`mobLevel`,`simpleDamage`,`transferFromType`,`transferToType`,`transferAmount`,`transferRamp`,`transferEfficiency`,`transferEfficiencyRamp`,`flags`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); | ||||
| 
 | ||||
| 		setString(1,IDString); | ||||
| 		setString(2,type); | ||||
| 		setString(3,effectID); | ||||
| 		setString(4,effectID2); | ||||
| 		setString(5,deferredPowerID); | ||||
| 		setFloat(6,levelCap); | ||||
| 		setFloat(7,levelCapRamp); | ||||
| 		setString(8,damageType); | ||||
| 		setInt(9,numIterations); | ||||
| 		setString(10,effectSourceToRemove); | ||||
| 		setString(11,trackFilter); | ||||
| 		setInt(12,maxTrack); | ||||
| 		setInt(13,mobID); | ||||
| 		setInt(14,mobLevel); | ||||
| 		setInt(15,simpleDamage); | ||||
| 		setString(16,transferFromType); | ||||
| 		setString(17,transferToType); | ||||
| 		setFloat(18,transferAmount); | ||||
| 		setFloat(19,transferRamp); | ||||
| 		setFloat(20,transferEfficiency); | ||||
| 		setFloat(21,transferEfficiencyRamp); | ||||
| 		setInt(22,flags); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean CreatePowerPowerActionRAW(String IDString,String type,String detail){ | ||||
| 		prepareCallable("INSERT INTO `wpak_effect_poweraction_raw` (`effectID`,`type`, `text`) VALUES (?,?,?)"); | ||||
| 
 | ||||
| 		setString(1,IDString); | ||||
| 		setString(2,type); | ||||
| 		setString(3,detail); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ClearAllEffectBase(){ | ||||
| 		prepareCallable("DELETE from `wpak_static_power_effectbase`"); | ||||
| 		executeUpdate(); | ||||
| 
 | ||||
| 		prepareCallable(" DELETE from `wpak_static_power_sourcetype` "); | ||||
| 		executeUpdate(); | ||||
| 
 | ||||
| 		prepareCallable(" DELETE from `wpak_static_power_failcondition` WHERE `powerOrEffect` = ?"); | ||||
| 		setString(1,"Effect"); | ||||
| 		executeUpdate(); | ||||
| 
 | ||||
| 		prepareCallable(" DELETE from `wpak_static_power_effectmod` "); | ||||
| 		executeUpdate(); | ||||
| 
 | ||||
| 		return true; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ResetIncrement(){ | ||||
| 		prepareCallable("ALTER TABLE `wpak_static_power_effectbase` AUTO_INCREMENT = 1"); | ||||
| 		executeUpdate(); | ||||
| 
 | ||||
| 		prepareCallable("ALTER TABLE `wpak_static_power_sourcetype` AUTO_INCREMENT = 1"); | ||||
| 		executeUpdate(); | ||||
| 
 | ||||
| 		prepareCallable("ALTER TABLE `wpak_static_power_failcondition` AUTO_INCREMENT = 1"); | ||||
| 		executeUpdate(); | ||||
| 
 | ||||
| 		prepareCallable("ALTER TABLE `wpak_static_power_effectmod` AUTO_INCREMENT = 1"); | ||||
| 		executeUpdate(); | ||||
| 
 | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,30 @@@@ -0,0 +1,30 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.EffectsResourceCosts; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbEffectsResourceCostHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbEffectsResourceCostHandler() { | ||||
| 		this.localClass = EffectsResourceCosts.class; | ||||
|         this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
| 	 | ||||
| 	public ArrayList<EffectsResourceCosts> GET_ALL_EFFECT_RESOURCES(String idString) { | ||||
| 		prepareCallable("SELECT * FROM `static_power_effectcost`  WHERE `IDString` = ?"); | ||||
| 		setString(1, idString); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,51 @@@@ -0,0 +1,51 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.server.MBServerStatics; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| public class dbEnchantmentHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public ConcurrentHashMap<String, Integer> GET_ENCHANTMENTS_FOR_ITEM(final int id) { | ||||
| 		ConcurrentHashMap<String, Integer> enchants = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); | ||||
| 		prepareCallable("SELECT * FROM `dyn_item_enchantment` WHERE `ItemID`=?;"); | ||||
| 		setLong(1, (long)id); | ||||
| 		try { | ||||
| 			ResultSet resultSet = executeQuery(); | ||||
| 			while (resultSet.next()) | ||||
| 				enchants.put(resultSet.getString("powerAction"), resultSet.getInt("rank")); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return enchants; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CREATE_ENCHANTMENT_FOR_ITEM(long itemID, String powerAction, int rank) { | ||||
| 		prepareCallable("INSERT INTO `dyn_item_enchantment` (`itemID`, `powerAction`, `rank`) VALUES (?, ?, ?);"); | ||||
| 		setLong(1, itemID); | ||||
| 		setString(2, powerAction); | ||||
| 		setInt(3, rank); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CLEAR_ENCHANTMENTS(long itemID) { | ||||
| 		prepareCallable("DELETE FROM `dyn_item_enchantment` WHERE `itemID`=?;"); | ||||
| 		setLong(1, itemID); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,486 @@@@ -0,0 +1,486 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.GuildHistoryType; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.joda.time.DateTime; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbGuildHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbGuildHandler() { | ||||
| 		this.localClass = Guild.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public int BANISH_FROM_GUILD_OFFLINE(final int target, boolean sourceIsGuildLeader) { | ||||
| 		if (!sourceIsGuildLeader)  //one IC cannot banish another IC
 | ||||
| 			prepareCallable("UPDATE `obj_character` SET `guildUID`=NULL, `guild_isInnerCouncil`=0, `guild_isTaxCollector`=0," | ||||
| 					+ " `guild_isRecruiter`=0, `guild_isFullMember`=0, `guild_title`=0 WHERE `UID`=? && `guild_isInnerCouncil`=0"); | ||||
| 		else | ||||
| 			prepareCallable("UPDATE `obj_character` SET `guildUID`=NULL, `guild_isInnerCouncil`=0, `guild_isTaxCollector`=0," | ||||
| 					+ " `guild_isRecruiter`=0, `guild_isFullMember`=0, `guild_title`=0 WHERE `UID`=?"); | ||||
| 		setLong(1, (long) target); | ||||
| 		return executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	public boolean ADD_TO_BANISHED_FROM_GUILDLIST(int target, long characterID) { | ||||
| 		prepareCallable("INSERT INTO  `dyn_guild_banishlist` (`GuildID`, `CharacterID`) VALUES (?,?)"); | ||||
| 		setLong(1, (long) target); | ||||
| 		setLong(2, characterID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean REMOVE_FROM_BANISH_LIST(int target, long characterID) { | ||||
| 		prepareCallable("DELETE FROM `dyn_guild_banishlist` (`GuildID`, `CharacterID`) VALUES (?,?)"); | ||||
| 		setLong(1, (long) target); | ||||
| 		setLong(2, characterID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_TO_GUILDHISTORY(int target, PlayerCharacter pc, DateTime historyDate, GuildHistoryType historyType) { | ||||
| 		prepareCallable("INSERT INTO  `dyn_character_guildhistory` (`GuildID`, `CharacterID`, `historyDate`, `historyType`) VALUES (?,?,?,?)"); | ||||
| 		setLong(1, (long) target); | ||||
| 		setLong(2, pc.getObjectUUID()); | ||||
| 
 | ||||
| 		if (historyDate == null) | ||||
| 			setNULL(3, java.sql.Types.DATE); | ||||
| 		else | ||||
| 			setTimeStamp(3, historyDate.getMillis()); | ||||
| 		setString(4,historyType.name()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	//TODO Need to get this working.
 | ||||
| 	public ArrayList<Guild> GET_GUILD_HISTORY_OF_PLAYER(final int id) { | ||||
| 		prepareCallable("SELECT g.* FROM `obj_guild` g, `dyn_character_guildhistory` l WHERE  g.`UID` = l.`GuildID` && l.`CharacterID` = ?"); | ||||
| 		setLong(1, (long) id); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String GET_GUILD_LIST(int guildType) { | ||||
| 
 | ||||
| 		String newLine = System.getProperty("line.separator"); | ||||
| 		String outputStr = null; | ||||
| 		ResultSet resultSet; | ||||
| 
 | ||||
| 		// Setup and execute stored procedure
 | ||||
| 
 | ||||
| 		prepareCallable("CALL `guild_GETLIST`(?)"); | ||||
| 		setInt(1, guildType); | ||||
| 		resultSet = executeQuery(); | ||||
| 
 | ||||
| 		// Build formatted string with data from query
 | ||||
| 
 | ||||
| 		outputStr += newLine; | ||||
| 		outputStr += String.format("%-10s %-30s %-10s %-10s", "UUID", "Name", "GL UUID", "TOL_UUID"); | ||||
| 		outputStr += newLine; | ||||
| 
 | ||||
| 		try { | ||||
| 
 | ||||
| 			while (resultSet.next()) { | ||||
| 
 | ||||
| 				outputStr += String.format("%-10d %-30s %-10d %-10d", resultSet.getInt(1), | ||||
| 						resultSet.getString(2), resultSet.getInt(3), resultSet.getInt(4)); | ||||
| 				outputStr += newLine; | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 			// Exception handling
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 		return outputStr; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	public ArrayList<Guild> GET_GUILD_ALLIES(final int id) { | ||||
| 		prepareCallable("SELECT g.* FROM `obj_guild` g, `dyn_guild_allianceenemylist` l " | ||||
| 				+ "WHERE l.isAlliance = 1 && l.OtherGuildID = g.UID && l.GuildID=?"); | ||||
| 		setLong(1, (long) id); | ||||
| 		return getObjectList(); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public static ArrayList<PlayerCharacter> GET_GUILD_BANISHED(final int id) { | ||||
| 
 | ||||
| 		return new ArrayList<>(); | ||||
| 
 | ||||
| 		// Bugfix
 | ||||
| 		// prepareCallable("SELECT * FROM `obj_character`, `dyn_guild_banishlist` WHERE `obj_character.char_isActive` = 1 AND `dyn_guild_banishlist.CharacterID` = `obj_character.UID` AND `obj_character.GuildID`=?");
 | ||||
| 
 | ||||
| 		//prepareCallable("SELECT * FROM `obj_character` `,` `dyn_guild_banishlist` WHERE obj_character.char_isActive = 1 AND dyn_guild_banishlist.CharacterID = obj_character.UID AND dyn_guild_banishlist.GuildID = ?");
 | ||||
| 		//setLong(1, (long) id);
 | ||||
| 
 | ||||
| 		//return getObjectList();
 | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Guild> GET_GUILD_ENEMIES(final int id) { | ||||
| 		prepareCallable("SELECT g.* FROM `obj_guild` g, `dyn_guild_allianceenemylist` l " | ||||
| 				+ "WHERE l.isAlliance = 0 && l.OtherGuildID = g.UID && l.GuildID=?"); | ||||
| 		setLong(1, (long) id); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<PlayerCharacter> GET_GUILD_KOS_CHARACTER(final int id) { | ||||
| 		prepareCallable("SELECT c.* FROM `obj_character` c, `dyn_guild_characterkoslist` l WHERE c.`char_isActive` = 1 && l.`KOSCharacterID` = c.`UID` && l.`GuildID`=?"); | ||||
| 		setLong(1, (long) id); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Guild> GET_GUILD_KOS_GUILD(final int id) { | ||||
| 		prepareCallable("SELECT g.* FROM `obj_guild` g, `dyn_guild_guildkoslist` l " | ||||
| 				+ "WHERE l.KOSGuildID = g.UID && l.GuildID = ?"); | ||||
| 		setLong(1, (long) id); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Guild> GET_SUB_GUILDS(final int guildID) { | ||||
| 		prepareCallable("SELECT `obj_guild`.*, `object`.`parent` FROM `object` INNER JOIN `obj_guild` ON `obj_guild`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;"); | ||||
| 		setInt(1, guildID); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public Guild GET_GUILD(int id) { | ||||
| 		Guild guild = (Guild) DbManager.getFromCache(Enum.GameObjectType.Guild, id); | ||||
| 		if (guild != null) | ||||
| 			return guild; | ||||
| 		if (id == 0) | ||||
| 			return Guild.getErrantGuild(); | ||||
| 		prepareCallable("SELECT `obj_guild`.*, `object`.`parent` FROM `obj_guild` INNER JOIN `object` ON `object`.`UID` = `obj_guild`.`UID` WHERE `object`.`UID`=?"); | ||||
| 		setLong(1, (long) id); | ||||
| 		return (Guild) getObjectSingle(id); | ||||
| 	} | ||||
| 	 | ||||
| 	public ArrayList<Guild> GET_ALL_GUILDS() { | ||||
| 		 | ||||
| 		prepareCallable("SELECT `obj_guild`.*, `object`.`parent` FROM `obj_guild` INNER JOIN `object` ON `object`.`UID` = `obj_guild`.`UID`"); | ||||
| 		 | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean IS_CREST_UNIQUE(final GuildTag gt) { | ||||
| 		boolean valid = false; | ||||
| 		if (gt.backgroundColor01 == gt.backgroundColor02) { | ||||
| 			//both background colors the same, ignore backgroundDesign
 | ||||
| 			prepareCallable("SELECT `name` FROM `obj_guild` WHERE `backgroundColor01`=? && `backgroundColor02`=? && `symbolColor`=? && `symbol`=?;"); | ||||
| 			setInt(1, gt.backgroundColor01); | ||||
| 			setInt(2, gt.backgroundColor02); | ||||
| 			setInt(3, gt.symbolColor); | ||||
| 			setInt(4, gt.symbol); | ||||
| 			 | ||||
| 		} else { | ||||
| 			prepareCallable("SELECT `name` FROM `obj_guild` WHERE `backgroundColor01`=? && `backgroundColor02`=? && `symbolColor`=? && `backgroundDesign`=? && `symbol`=?;"); | ||||
| 			setInt(1, gt.backgroundColor01); | ||||
| 			setInt(2, gt.backgroundColor02); | ||||
| 			setInt(3, gt.symbolColor); | ||||
| 			setInt(4, gt.backgroundDesign); | ||||
| 			setInt(5, gt.symbol); | ||||
| 		} | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			if (!rs.next()) | ||||
| 				valid = true; | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getMessage()); | ||||
| 		} | ||||
| 		return valid; | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Guild g, String name, Object new_value) { | ||||
| 		prepareCallable("CALL guild_SETPROP(?,?,?)"); | ||||
| 		setLong(1, (long) g.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Guild g, String name, Object new_value, Object old_value) { | ||||
| 		prepareCallable("CALL guild_GETSETPROP(?,?,?,?)"); | ||||
| 		setLong(1, (long) g.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		setString(4, String.valueOf(old_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean SET_GUILD_OWNED_CITY(int guildID, int cityID) { | ||||
| 		prepareCallable("UPDATE `obj_guild` SET `ownedCity`=? WHERE `UID`=?"); | ||||
| 		setLong(1, (long) cityID); | ||||
| 		setLong(2, (long) guildID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean SET_GUILD_LEADER(int objectUUID,int guildID) { | ||||
| 		prepareCallable("UPDATE `obj_guild` SET `leaderUID`=? WHERE `UID`=?"); | ||||
| 		setLong(1, (long) objectUUID); | ||||
| 		setLong(2, (long) guildID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public boolean IS_NAME_UNIQUE(final String name) { | ||||
| 		boolean valid = false; | ||||
| 		prepareCallable("SELECT `name` FROM `obj_guild` WHERE `name`=?;"); | ||||
| 		setString(1, name); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			if (!rs.next()) | ||||
| 				valid = true; | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.warn(e.getMessage()); | ||||
| 		} | ||||
| 		return valid; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public Guild SAVE_TO_DATABASE(Guild g) { | ||||
| 		prepareCallable("CALL `guild_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); | ||||
| 	 | ||||
| 		GuildTag gt = g.getGuildTag(); | ||||
| 		if ( gt == null) | ||||
| 			return null; | ||||
| 		setLong(1, MBServerStatics.worldUUID); | ||||
| 		setLong(2, g.getGuildLeaderUUID()); | ||||
| 		setString(3, g.getName()); | ||||
| 		setInt(4, gt.backgroundColor01); | ||||
| 		setInt(5, gt.backgroundColor02); | ||||
| 		setInt(6, gt.symbolColor); | ||||
| 		setInt(7, gt.backgroundDesign); | ||||
| 		setInt(8 , gt.symbol); | ||||
| 		setInt(9, g.getCharter()); | ||||
| 		setString(10, g.getLeadershipType()); | ||||
| 		setString(11, g.getMotto()); | ||||
| 
 | ||||
| 		int objectUUID = (int) getUUID(); | ||||
| 		if (objectUUID > 0) | ||||
| 			return GET_GUILD(objectUUID); | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_GUILD_RANK_OFFLINE(int target, int newRank, int guildId) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `guild_title`=? WHERE `UID`=? && `guildUID`=?"); | ||||
| 		setInt(1, newRank); | ||||
| 		setInt(2, target); | ||||
| 		setInt(3, guildId); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_PARENT(int guildUID, int parentUID) { | ||||
| 		prepareCallable("UPDATE `object` SET `parent`=? WHERE `UID`=?"); | ||||
| 		setInt(1, parentUID); | ||||
| 		setInt(2, guildUID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public int DELETE_GUILD(final Guild guild) { | ||||
| 		prepareCallable("DELETE FROM `object` WHERE `UID` = ?"); | ||||
| 		setLong(1, (long) guild.getObjectUUID()); | ||||
| 		return executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_MINETIME(int guildUID, int mineTime) { | ||||
| 		prepareCallable("UPDATE `obj_guild` SET `mineTime`=? WHERE `UID`=?"); | ||||
| 		setInt(1, mineTime); | ||||
| 		setInt(2, guildUID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public int UPDATE_GUILD_STATUS_OFFLINE(int target, boolean isInnerCouncil, boolean isRecruiter, boolean isTaxCollector, int guildId) { | ||||
| 		int updateMask = 0; | ||||
| 		prepareCallable("SELECT `guild_isInnerCouncil`, `guild_isTaxCollector`, `guild_isRecruiter` FROM `obj_character` WHERE `UID`=? && `guildUID`=?"); | ||||
| 		setLong(1, (long) target); | ||||
| 		setLong(2, (long) guildId); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//If the first query had no results, neither will the second
 | ||||
| 			if (rs.first()) { | ||||
| 				//Determine what is different
 | ||||
| 				if (rs.getBoolean("guild_isInnerCouncil") != isInnerCouncil) | ||||
| 					updateMask |= 4; | ||||
| 				if (rs.getBoolean("guild_isRecruiter") != isRecruiter) | ||||
| 					updateMask |= 2; | ||||
| 				if (rs.getBoolean("guild_isTaxCollector") != isTaxCollector) | ||||
| 					updateMask |= 1; | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} | ||||
| 		prepareCallable("UPDATE `obj_character` SET `guild_isInnerCouncil`=?, `guild_isTaxCollector`=?, `guild_isRecruiter`=?, `guild_isFullMember`=? WHERE `UID`=? && `guildUID`=?"); | ||||
| 		setBoolean(1, isInnerCouncil); | ||||
| 		setBoolean(2, isRecruiter); | ||||
| 		setBoolean(3, isTaxCollector); | ||||
| 		setBoolean(4, ((updateMask > 0))); //If you are becoming an officer, or where an officer, your a full member...
 | ||||
| 		setLong(5, (long) target); | ||||
| 		setLong(6, (long) guildId); | ||||
| 		return executeUpdate(); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	// *** Refactor: Why are we saving tags/charter in update?
 | ||||
| 	//               It's not like this shit ever changes.
 | ||||
| 
 | ||||
| 	public boolean updateDatabase(final Guild g) { | ||||
| 		prepareCallable("UPDATE `obj_guild` SET `name`=?, `backgroundColor01`=?, `backgroundColor02`=?, `symbolColor`=?, `backgroundDesign`=?, `symbol`=?, `charter`=?, `motd`=?, `icMotd`=?, `nationMotd`=?, `leaderUID`=? WHERE `UID`=?"); | ||||
| 		setString(1, g.getName()); | ||||
| 		setInt(2, g.getGuildTag().backgroundColor01); | ||||
| 		setInt(3, g.getGuildTag().backgroundColor02); | ||||
| 		setInt(4, g.getGuildTag().symbolColor); | ||||
| 		setInt(5, g.getGuildTag().backgroundDesign); | ||||
| 		setInt(6, g.getGuildTag().symbol); | ||||
| 		setInt(7, g.getCharter()); | ||||
| 		setString(8, g.getMOTD()); | ||||
| 		setString(9, g.getICMOTD()); | ||||
| 		setString(10, ""); | ||||
| 		setInt(11, g.getGuildLeaderUUID()); | ||||
| 		setLong(12, (long) g.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	public boolean ADD_TO_ALLIANCE_LIST(final long sourceGuildID, final long targetGuildID, boolean isRecommended, boolean isAlly, String recommender) { | ||||
| 		prepareCallable("INSERT INTO `dyn_guild_allianceenemylist` (`GuildID`, `OtherGuildID`,`isRecommended`, `isAlliance`, `recommender`) VALUES (?,?,?,?,?)"); | ||||
| 		setLong(1, sourceGuildID); | ||||
| 		setLong(2, targetGuildID); | ||||
| 		setBoolean(3, isRecommended); | ||||
| 		setBoolean(4, isAlly); | ||||
| 		setString(5, recommender); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean REMOVE_FROM_ALLIANCE_LIST(final long sourceGuildID, long targetGuildID) { | ||||
| 		prepareCallable("DELETE FROM `dyn_guild_allianceenemylist` WHERE `GuildID`=? AND `OtherGuildID`=?"); | ||||
| 		setLong(1, sourceGuildID); | ||||
| 		setLong(2, targetGuildID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_RECOMMENDED(final long sourceGuildID, long targetGuildID) { | ||||
| 		prepareCallable("UPDATE `dyn_guild_allianceenemylist` SET `isRecommended` = ? WHERE `GuildID`=? AND `OtherGuildID`=?"); | ||||
| 		setByte(1,(byte)0); | ||||
| 		setLong(2, sourceGuildID); | ||||
| 		setLong(3, targetGuildID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_ALLIANCE(final long sourceGuildID, long targetGuildID, boolean isAlly) { | ||||
| 		prepareCallable("UPDATE `dyn_guild_allianceenemylist` SET `isAlliance` = ? WHERE `GuildID`=? AND `OtherGuildID`=?"); | ||||
| 		setBoolean(1,isAlly); | ||||
| 		setLong(2, sourceGuildID); | ||||
| 		setLong(3, targetGuildID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_ALLIANCE_AND_RECOMMENDED(final long sourceGuildID, long targetGuildID, boolean isAlly) { | ||||
| 		prepareCallable("UPDATE `dyn_guild_allianceenemylist` SET `isRecommended` = ?, `isAlliance` = ? WHERE `GuildID`=? AND `OtherGuildID`=?"); | ||||
| 		setByte(1,(byte)0); | ||||
| 		setBoolean(2,isAlly); | ||||
| 		setLong(3, sourceGuildID); | ||||
| 		setLong(4, targetGuildID); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_ALL_ALLIANCES_FOR_GUILD(Guild guild) { | ||||
| 
 | ||||
| 		if (guild == null) | ||||
| 			return; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `dyn_guild_allianceenemylist` WHERE `GuildID` = ?"); | ||||
| 		setInt(1,guild.getObjectUUID()); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 				GuildAlliances guildAlliance = new GuildAlliances(rs); | ||||
| 				guild.guildAlliances.put(guildAlliance.getAllianceGuild(), guildAlliance); | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_GUILD_HISTORY_FOR_PLAYER(PlayerCharacter pc) { | ||||
| 
 | ||||
| 		if (pc == null) | ||||
| 			return; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `dyn_character_guildhistory` WHERE `CharacterID` = ?"); | ||||
| 		setInt(1,pc.getObjectUUID()); | ||||
| 
 | ||||
| 		try { | ||||
| 			ArrayList<GuildHistory> tempList = new ArrayList<>(); | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 				GuildHistory guildHistory = new GuildHistory(rs); | ||||
| 				tempList.add(guildHistory); | ||||
| 			} | ||||
| 
 | ||||
| 			pc.setGuildHistory(tempList); | ||||
| 
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 	 | ||||
| 	//TODO uncomment this when finished with guild history warehouse integration
 | ||||
| //	public HashMap<Integer, GuildRecord> GET_WAREHOUSE_GUILD_HISTORY(){
 | ||||
| //		
 | ||||
| //		HashMap<Integer, GuildRecord> tempMap = new HashMap<>();
 | ||||
| //		prepareCallable("SELECT * FROM `warehouse_guildhistory` WHERE `eventType` = 'CREATE'");
 | ||||
| //		try {
 | ||||
| //			ResultSet rs = executeQuery();
 | ||||
| //			
 | ||||
| //			while (rs.next()) {
 | ||||
| //				GuildRecord guildRecord = new GuildRecord(rs);
 | ||||
| //				tempMap.put(guildRecord.guildID, guildRecord);
 | ||||
| //			}
 | ||||
| //		}catch (Exception e){
 | ||||
| //			Logger.error(e);
 | ||||
| //		}
 | ||||
| //		return tempMap;
 | ||||
| //		
 | ||||
| //	}
 | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,470 @@@@ -0,0 +1,470 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.gameManager.ConfigManager; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.AbstractWorldObject; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.*; | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashSet; | ||||
| 
 | ||||
| public abstract class dbHandlerBase { | ||||
| 
 | ||||
| 	/* | ||||
| 	 * CallableStatements handled below this line! | ||||
| 	 */ | ||||
| 	protected Class<? extends AbstractGameObject> localClass = null; | ||||
| 	protected GameObjectType localObjectType; | ||||
| 	protected final ThreadLocal<CallableStatement> cs = new ThreadLocal<>(); | ||||
| 
 | ||||
| 	protected final void prepareCallable(final String sql) { | ||||
| 		try { | ||||
| 			this.cs.set((CallableStatement) DbManager.getConn().prepareCall(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("DbManager.getConn", e); | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setDate(int parameterIndex, Date value) { | ||||
| 		try { | ||||
| 			this.cs.get().setDate(parameterIndex, value); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setInt(int parameterIndex, int value) { | ||||
| 		try { | ||||
| 			this.cs.get().setInt(parameterIndex, value); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setLong(int parameterIndex, long value) { | ||||
| 		try { | ||||
| 			this.cs.get().setLong(parameterIndex, value); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setFloat(int parameterIndex, float value) { | ||||
| 		try { | ||||
| 			this.cs.get().setFloat(parameterIndex, value); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setShort(int parameterIndex, short value) { | ||||
| 		try { | ||||
| 			this.cs.get().setShort(parameterIndex, value); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setString(int parameterIndex, String value) { | ||||
| 		try { | ||||
| 			this.cs.get().setString(parameterIndex, value); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setBytes(int parameterIndex, byte[] value) { | ||||
| 		try { | ||||
| 			this.cs.get().setBytes(parameterIndex, value); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setByte(int parameterIndex, byte value) { | ||||
| 		try { | ||||
| 			this.cs.get().setByte(parameterIndex, value); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setBoolean(int parameterIndex, boolean value) { | ||||
| 		try { | ||||
| 			this.cs.get().setBoolean(parameterIndex, value); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setNULL(int parameterIndex, int type) { | ||||
| 		try { | ||||
| 			this.cs.get().setNull(parameterIndex, type); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setLocalDateTime(int parameterIndex, LocalDateTime localDateTime) { | ||||
| 
 | ||||
| 		try { | ||||
| 			this.cs.get().setTimestamp(parameterIndex, Timestamp.valueOf(localDateTime)); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void setTimeStamp(int parameterIndex, long time) { | ||||
| 		try { | ||||
| 			this.cs.get().setTimestamp(parameterIndex, new java.sql.Timestamp(time)); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final boolean execute() { | ||||
| 		try { | ||||
| 			return this.cs.get().execute(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 			logSQLCommand(); | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	protected final ResultSet executeQuery() { | ||||
| 		try { | ||||
| 			return this.cs.get().executeQuery(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 			logSQLCommand(); | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	protected final int executeUpdate() { | ||||
| 		return executeUpdate(true); | ||||
| 	} | ||||
| 
 | ||||
| 	protected final int executeUpdate(boolean close) { | ||||
| 		try { | ||||
| 			return this.cs.get().executeUpdate(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 			logSQLCommand(); | ||||
| 		} finally { | ||||
| 			if (close) | ||||
| 				closeCallable(); | ||||
| 		} | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void logSQLCommand() { | ||||
| 		try { | ||||
| 			Logger.error("Failed SQL Command: " + this.cs.get().toString()); | ||||
| 		} catch (Exception e) { | ||||
| 
 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	// Common return values from the database when calling stored procedures, abstracted to this layer
 | ||||
| 	protected final String getResult(){ | ||||
| 		try { | ||||
| 			ResultSet rs = this.executeQuery(); | ||||
| 			if (rs.next() && !isError(rs)) | ||||
| 				return rs.getString("result"); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e); | ||||
| 			logSQLCommand(); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	// Used for Stored procedures that return true when they succeed.
 | ||||
| 	protected final boolean worked() { | ||||
| 		try { | ||||
| 			ResultSet rs = this.executeQuery(); | ||||
| 			if (rs.next() && !isError(rs)) | ||||
| 				return rs.getBoolean("result"); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e); | ||||
| 			logSQLCommand(); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	// Common return values from the database when calling stored procedures, abstracted to this layer
 | ||||
| 	protected final long getUUID(){ | ||||
| 		try { | ||||
| 			ResultSet rs = this.executeQuery(); | ||||
| 			if (rs.next() && !isError(rs)) | ||||
| 				return rs.getLong("UID"); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e); | ||||
| 			logSQLCommand(); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return -1; | ||||
| 	} | ||||
| 
 | ||||
| 	protected final String getString(String field) { | ||||
| 		try { | ||||
| 			ResultSet rs = this.executeQuery(); | ||||
| 			if (rs.next()) | ||||
| 				return rs.getString(field); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e); | ||||
| 			logSQLCommand(); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return ""; | ||||
| 	} | ||||
| 
 | ||||
| 	protected final long getLong(String field) { | ||||
| 		try { | ||||
| 			ResultSet rs = this.executeQuery(); | ||||
| 			if (rs.next()) | ||||
| 				return rs.getLong(field); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e); | ||||
| 			logSQLCommand(); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return 0L; | ||||
| 	} | ||||
| 
 | ||||
| 	protected final int getInt(String field) { | ||||
| 		try { | ||||
| 			ResultSet rs = this.executeQuery(); | ||||
| 			if (rs.next()) | ||||
| 				return rs.getInt(field); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e); | ||||
| 			logSQLCommand(); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	protected final int insertGetUUID() { | ||||
| 		int key = 0; | ||||
| 		try { | ||||
| 			this.cs.get().executeUpdate(); | ||||
| 			ResultSet rs = this.cs.get().getGeneratedKeys(); | ||||
| 			if (rs.next()) | ||||
| 				key = rs.getInt(1); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e); | ||||
| 			logSQLCommand(); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return key; | ||||
| 	} | ||||
| 
 | ||||
| 	protected final boolean isError(ResultSet rs) throws SQLException { | ||||
| 		ResultSetMetaData rsmd = rs.getMetaData(); | ||||
| 		if (rsmd.getColumnCount() > 0 && !rsmd.getColumnName(1).equals("errorno")) | ||||
| 			return false; | ||||
| 		printError(rs); | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void printError(ResultSet rs) { | ||||
| 		try { | ||||
| 			int errorNum = rs.getInt("errorno"); | ||||
| 			String errorMsg = rs.getString("errormsg"); | ||||
| 			Logger.error("SQLError: errorNum: " + errorNum + ", errorMsg: " + errorMsg); | ||||
| 			logSQLCommand(); | ||||
| 		} catch (SQLException e) {} | ||||
| 	} | ||||
| 
 | ||||
| 	protected final void getColumNames(ResultSet rs) throws SQLException { | ||||
| 		ResultSetMetaData rsmd = rs.getMetaData(); | ||||
| 		int numColumns = rsmd.getColumnCount(); | ||||
| 		String out = "Column names for resultSet: "; | ||||
| 		for (int i=1; i<numColumns+1; i++) | ||||
| 			out += i + ": " + rsmd.getColumnName(i) + ", "; | ||||
| 		Logger.info(out); | ||||
| 	} | ||||
| 
 | ||||
| 	// Default actions to the objects table, generic to all objects
 | ||||
| 	protected final long SET_PARENT(long objUID, long new_value, long old_value) { | ||||
| 		prepareCallable("CALL object_GETSETPARENT(?,?,?)"); | ||||
| 		setLong(1, objUID); | ||||
| 		setLong(2, new_value); | ||||
| 		setLong(3, old_value); | ||||
| 		return getUUID(); | ||||
| 	} | ||||
| 
 | ||||
| 	// NOTE: CALLING THIS FUNCTION CASCADE DELETES OBJECTS FROM THE DATABASE
 | ||||
| 	protected final long REMOVE(long objUID) { | ||||
| 		prepareCallable("CALL object_PURGECASCADE(?)"); | ||||
| 		setLong(1, objUID); | ||||
| 		return getUUID(); | ||||
| 	} | ||||
| 
 | ||||
| 	protected <T extends AbstractGameObject> AbstractGameObject getObjectSingle(int id) { | ||||
| 		return getObjectSingle(id, false, true); | ||||
| 	} | ||||
| 
 | ||||
| 	protected <T extends AbstractGameObject> AbstractGameObject getObjectSingle(int id, boolean forceFromDB, boolean storeInCache) { | ||||
| 
 | ||||
| 		if (cs.get() == null){ | ||||
| 			return null; | ||||
| 		} | ||||
| 
 | ||||
| 		if (!forceFromDB) { | ||||
| 			if (DbManager.inCache(localObjectType, id)) { | ||||
| 				closeCallable(); | ||||
| 				return DbManager.getFromCache(localObjectType, id); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		AbstractGameObject out = null; | ||||
| 
 | ||||
| 		try { | ||||
| 			if (MBServerStatics.DB_ENABLE_QUERY_OUTPUT) | ||||
| 				Logger.info( "[GetObjectList] Executing query:" + cs.get().toString()); | ||||
| 
 | ||||
| 			ResultSet rs = cs.get().executeQuery(); | ||||
| 
 | ||||
| 			if (rs.next()) { | ||||
| 				out = localClass.getConstructor(ResultSet.class).newInstance(rs); | ||||
| 
 | ||||
| 				if (storeInCache) | ||||
| 					DbManager.addToCache(out); | ||||
| 			} | ||||
| 
 | ||||
| 			rs.close(); | ||||
| 
 | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error("AbstractGameObject", e); | ||||
| 			out = null; | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 		// Only call runAfterLoad() for objects instanced on the world server
 | ||||
| 
 | ||||
| 		if ((out != null && out instanceof AbstractWorldObject) && | ||||
| 				(ConfigManager.serverType.equals(Enum.ServerType.WORLDSERVER) || | ||||
| 						(out.getObjectType() == GameObjectType.Guild))) | ||||
| 			((AbstractWorldObject)out).runAfterLoad(); | ||||
| 
 | ||||
| 		return out; | ||||
| 	} | ||||
| 
 | ||||
| 	protected void closeCallable() { | ||||
| 		try { | ||||
| 			if (this.cs.get() != null) | ||||
| 				this.cs.get().close(); | ||||
| 		} catch (SQLException e) {} | ||||
| 	} | ||||
| 
 | ||||
| 	protected <T extends AbstractGameObject> ArrayList<T> getObjectList() { | ||||
| 		return getObjectList(20, false); | ||||
| 	} | ||||
| 
 | ||||
| 	protected <T extends AbstractGameObject> ArrayList<T> getLargeObjectList() { | ||||
| 		return getObjectList(2000, false); | ||||
| 	} | ||||
| 
 | ||||
| 	@SuppressWarnings("unchecked") | ||||
| 	protected <T extends AbstractGameObject> ArrayList<T> getObjectList(int listSize, boolean forceFromDB) { | ||||
| 
 | ||||
| 		String query = "No Callable Statement accessable."; | ||||
| 
 | ||||
| 		ArrayList<T> out = new ArrayList<>(listSize); | ||||
| 
 | ||||
| 		if (this.cs.get() == null) | ||||
| 			return out; | ||||
| 
 | ||||
| 		try { | ||||
| 
 | ||||
| 			CallableStatement css = this.cs.get(); | ||||
| 
 | ||||
| 			if (css != null) | ||||
| 				query = this.cs.get().toString(); | ||||
| 
 | ||||
| 			if (MBServerStatics.DB_ENABLE_QUERY_OUTPUT) | ||||
| 				Logger.info( "[GetObjectList] Executing query:" + query); | ||||
| 
 | ||||
| 			ResultSet rs = this.cs.get().executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				int id = rs.getInt(1); | ||||
| 
 | ||||
| 				if (!forceFromDB && DbManager.inCache(localObjectType, id)) { | ||||
| 					out.add((T) DbManager.getFromCache(localObjectType, id)); | ||||
| 				} else { | ||||
| 					AbstractGameObject toAdd = localClass.getConstructor(ResultSet.class).newInstance(rs); | ||||
| 					DbManager.addToCache(toAdd); | ||||
| 					out.add((T) toAdd); | ||||
| 
 | ||||
| 					if (toAdd != null && toAdd instanceof AbstractWorldObject) | ||||
| 						((AbstractWorldObject)toAdd).runAfterLoad(); | ||||
| 
 | ||||
| 				} | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error(localClass.getCanonicalName(), "List Failure: " + query, e); | ||||
| 			e.printStackTrace(); | ||||
| 			return new ArrayList<>(); // Do we want a null return on error?
 | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 		return out; | ||||
| 	} | ||||
| 
 | ||||
| 	/* Prepared Statements handled below this line */ | ||||
| 
 | ||||
| 	protected HashSet<Integer> getIntegerList(final int columnNumber) { | ||||
| 
 | ||||
| 		if (MBServerStatics.DB_ENABLE_QUERY_OUTPUT) | ||||
| 			Logger.info("[GetIntegerList] Executing query:" + this.cs.toString()); | ||||
| 
 | ||||
| 		HashSet<Integer> out = new HashSet<>(); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 				out.add(rs.getInt(columnNumber)); | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return out; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,47 @@@@ -0,0 +1,47 @@ | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.InterestManagement.HeightMap; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| 
 | ||||
| public class dbHeightMapHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbHeightMapHandler() { | ||||
| 
 | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_ALL_HEIGHTMAPS() { | ||||
| 
 | ||||
| 		HeightMap thisHeightmap; | ||||
| 
 | ||||
| 		int recordsRead = 0; | ||||
| 		int worthlessDupes = 0; | ||||
| 
 | ||||
| 		HeightMap.heightMapsCreated = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_zone_heightmap INNER JOIN static_zone_size ON static_zone_size.loadNum = static_zone_heightmap.zoneLoadID"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 				thisHeightmap = new HeightMap(rs); | ||||
| 
 | ||||
| 				if (thisHeightmap.getHeightmapImage() == null) { | ||||
| 					Logger.info( "Imagemap for " + thisHeightmap.getHeightMapID() + " was null"); | ||||
| 					continue; | ||||
| 				} | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("LoadAllHeightMaps: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,152 @@@@ -0,0 +1,152 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.EquipmentSetEntry; | ||||
| import engine.objects.ItemBase; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| 
 | ||||
| public class dbItemBaseHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbItemBaseHandler() { | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_BAKEDINSTATS(ItemBase itemBase) { | ||||
| 
 | ||||
| 		try { | ||||
| 			prepareCallable("SELECT * FROM `static_item_bakedinstat` WHERE `itemID` = ?"); | ||||
| 			setInt(1, itemBase.getUUID()); | ||||
| 
 | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				if (rs.getBoolean("fromUse")) | ||||
| 					itemBase.getUsedStats().put(rs.getInt("token"), rs.getInt("numTrains")); | ||||
| 				else | ||||
| 					itemBase.getBakedInStats().put(rs.getInt("token"), rs.getInt("numTrains")); | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_ANIMATIONS(ItemBase itemBase) { | ||||
| 
 | ||||
| 		ArrayList<Integer> tempList = new ArrayList<>(); | ||||
| 		ArrayList<Integer> tempListOff = new ArrayList<>(); | ||||
| 		try { | ||||
| 			prepareCallable("SELECT * FROM `static_itembase_animations` WHERE `itemBaseUUID` = ?"); | ||||
| 			setInt(1, itemBase.getUUID()); | ||||
| 
 | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 				int animation = rs.getInt("animation"); | ||||
| 
 | ||||
| 				boolean rightHand = rs.getBoolean("rightHand"); | ||||
| 
 | ||||
| 				if (rightHand) | ||||
| 					tempList.add(animation); | ||||
| 				else | ||||
| 					tempListOff.add(animation); | ||||
| 
 | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 		itemBase.setAnimations(tempList); | ||||
| 		itemBase.setOffHandAnimations(tempListOff); | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_ALL_ITEMBASES() { | ||||
| 
 | ||||
| 		ItemBase itemBase; | ||||
| 
 | ||||
| 		int recordsRead = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_itembase"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 				itemBase = new ItemBase(rs); | ||||
| 
 | ||||
| 				// Add ItemBase to internal cache
 | ||||
| 
 | ||||
| 				ItemBase.addToCache(itemBase); | ||||
| 			} | ||||
| 
 | ||||
| 			Logger.info( "read: " + recordsRead + "cached: " + ItemBase.getUUIDCache().size()); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public HashMap<Integer, ArrayList<EquipmentSetEntry>> LOAD_EQUIPMENT_FOR_NPC_AND_MOBS() { | ||||
| 
 | ||||
| 		HashMap<Integer, ArrayList<EquipmentSetEntry>> equipmentSets; | ||||
| 		EquipmentSetEntry equipmentSetEntry; | ||||
| 		int	equipSetID; | ||||
| 
 | ||||
| 		equipmentSets = new HashMap<>(); | ||||
| 		int recordsRead = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_npc_equipmentset"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 
 | ||||
| 				equipSetID = rs.getInt("equipmentSet"); | ||||
| 				equipmentSetEntry = new EquipmentSetEntry(rs); | ||||
| 
 | ||||
| 				if (equipmentSets.get(equipSetID) == null){ | ||||
| 					ArrayList<EquipmentSetEntry> equipList = new ArrayList<>(); | ||||
| 					equipList.add(equipmentSetEntry); | ||||
| 					equipmentSets.put(equipSetID, equipList); | ||||
| 				} | ||||
| 				else{ | ||||
| 					ArrayList<EquipmentSetEntry>equipList = equipmentSets.get(equipSetID); | ||||
| 					equipList.add(equipmentSetEntry); | ||||
| 					equipmentSets.put(equipSetID, equipList); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			Logger.info("read: " + recordsRead + " cached: " + equipmentSets.size()); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return equipmentSets; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,430 @@@@ -0,0 +1,430 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum.ItemContainerType; | ||||
| import engine.Enum.ItemType; | ||||
| import engine.Enum.OwnerType; | ||||
| import engine.objects.*; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashSet; | ||||
| 
 | ||||
| 
 | ||||
| public class dbItemHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbItemHandler() { | ||||
| 		this.localClass = Item.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public Item ADD_ITEM(Item toAdd) { | ||||
| 		prepareCallable("CALL `item_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?,?);"); | ||||
| 		setInt(1, toAdd.getOwnerID()); | ||||
| 		setInt(2, toAdd.getItemBaseID()); | ||||
| 		setInt(3, toAdd.getChargesRemaining()); | ||||
| 		setInt(4, toAdd.getDurabilityCurrent()); | ||||
| 		setInt(5, toAdd.getDurabilityMax()); | ||||
| 		if (toAdd.getNumOfItems() < 1) | ||||
| 			setInt(6, 1); | ||||
| 		else | ||||
| 			setInt(6, toAdd.getNumOfItems()); | ||||
| 
 | ||||
| 		switch (toAdd.containerType) { | ||||
| 			case INVENTORY: | ||||
| 				setString(7, "inventory"); | ||||
| 				break; | ||||
| 			case EQUIPPED: | ||||
| 				setString(7, "equip"); | ||||
| 				break; | ||||
| 			case BANK: | ||||
| 				setString(7, "bank"); | ||||
| 				break; | ||||
| 			case VAULT: | ||||
| 				setString(7, "vault"); | ||||
| 				break; | ||||
| 			case FORGE: | ||||
| 				setString(7, "forge"); | ||||
| 				break; | ||||
| 				default: | ||||
| 					setString(7, "none"); //Shouldn't be here
 | ||||
| 					break; | ||||
| 		} | ||||
| 
 | ||||
| 		setByte(8, toAdd.getEquipSlot()); | ||||
| 		setInt(9, toAdd.getFlags()); | ||||
| 		setString(10, toAdd.getCustomName()); | ||||
| 		int objectUUID = (int) getUUID(); | ||||
| 
 | ||||
| 		if (objectUUID > 0) | ||||
| 			return GET_ITEM(objectUUID); | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean DELETE_ITEM(final Item item) { | ||||
| 		prepareCallable("DELETE FROM `object` WHERE `UID`=? && `type`='item' limit 1"); | ||||
| 		setLong(1, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean DELETE_ITEM(final int itemUUID) { | ||||
| 		prepareCallable("DELETE FROM `object` WHERE `UID`=? && `type`='item' limit 1"); | ||||
| 		setLong(1, (long) itemUUID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public String GET_OWNER(int ownerID) { | ||||
| 		prepareCallable("SELECT `type` FROM `object` WHERE `UID`=?"); | ||||
| 		setLong(1, (long) ownerID); | ||||
| 		return getString("type"); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean DO_TRADE(HashSet<Integer> from1, HashSet<Integer> from2, | ||||
| 			CharacterItemManager man1, CharacterItemManager man2, | ||||
| 			Item inventoryGold1, Item inventoryGold2, int goldFrom1, int goldFrom2) { | ||||
| 
 | ||||
| 		AbstractCharacter ac1 = man1.getOwner(); | ||||
| 		AbstractCharacter ac2 = man2.getOwner(); | ||||
| 		if (ac1 == null || ac2 == null || inventoryGold1 == null || inventoryGold2 == null) | ||||
| 			return false; | ||||
| 
 | ||||
| 		prepareCallable("CALL `item_TRADE`(?, ?, ?, ?, ?, ?, ?, ?)"); | ||||
| 		setString(1, formatTradeString(from1)); | ||||
| 		setLong(2, (long) ac1.getObjectUUID()); | ||||
| 		setString(3, formatTradeString(from2)); | ||||
| 		setLong(4, (long) ac2.getObjectUUID()); | ||||
| 		setInt(5, goldFrom1); | ||||
| 		setLong(6, (long) inventoryGold1.getObjectUUID()); | ||||
| 		setInt(7, goldFrom2); | ||||
| 		setLong(8, (long) inventoryGold2.getObjectUUID()); | ||||
|         return worked(); | ||||
| 	} | ||||
| 
 | ||||
| 	private static String formatTradeString(HashSet<Integer> list) { | ||||
| 		int size = list.size(); | ||||
| 
 | ||||
| 		String ret = ""; | ||||
| 		if (size == 0) | ||||
| 			return ret; | ||||
| 		boolean start = true; | ||||
| 		for (int i : list) { | ||||
| 			if (start){ | ||||
| 				ret += i; | ||||
| 				start = false; | ||||
| 			} | ||||
| 			else | ||||
| 			ret += "," + i; | ||||
| 		} | ||||
| 		return ret; | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Item> GET_EQUIPPED_ITEMS(final int targetId) { | ||||
| 		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=? && `obj_item`.`item_container`='equip';"); | ||||
| 		setLong(1, (long) targetId); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public Item GET_ITEM(final int id) { | ||||
| 
 | ||||
| 
 | ||||
| 		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`UID`=?;"); | ||||
| 		setLong(1, (long) id); | ||||
| 		return (Item) getObjectSingle(id); | ||||
| 	} | ||||
| 
 | ||||
| 	public Item GET_GOLD_FOR_PLAYER(final int playerID, final int goldID, int worldID) { | ||||
| 		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=? AND `obj_item`.`item_itembaseID`=?;"); | ||||
| 		setInt(1, playerID); | ||||
| 		setInt(2, goldID); | ||||
| 		int objectUUID = (int) getUUID(); | ||||
| 		return (Item) getObjectSingle(objectUUID); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Item> GET_ITEMS_FOR_ACCOUNT(final int accountId) { | ||||
| 		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=?;"); | ||||
| 		setLong(1, (long) accountId); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Item> GET_ITEMS_FOR_NPC(final int npcId) { | ||||
| 		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=?"); | ||||
| 		setLong(1, (long) npcId); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Item> GET_ITEMS_FOR_PC(final int id) { | ||||
| 		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=?"); | ||||
| 		setLong(1, (long) id); | ||||
| 		return getLargeObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Item> GET_ITEMS_FOR_PLAYER_AND_ACCOUNT(final int playerID, final int accountID) { | ||||
| 		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE (`object`.`parent`=? OR `object`.`parent`=?)"); | ||||
| 		setLong(1, (long) playerID); | ||||
| 		setLong(2, (long) accountID); | ||||
| 		return getLargeObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean MOVE_GOLD(final Item from, final Item to, final int amt) { | ||||
| 		int newFromAmt = from.getNumOfItems() - amt; | ||||
| 		int newToAmt = to.getNumOfItems() + amt; | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_numberOfItems` = CASE WHEN `UID`=?  THEN ? WHEN `UID`=? THEN ? END WHERE `UID` IN (?, ?);"); | ||||
| 		setLong(1, (long) from.getObjectUUID()); | ||||
| 		setInt(2, newFromAmt); | ||||
| 		setLong(3, (long) to.getObjectUUID()); | ||||
| 		setInt(4, newToAmt); | ||||
| 		setLong(5, (long) from.getObjectUUID()); | ||||
| 		setLong(6, (long) to.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ORPHAN_INVENTORY(final HashSet<Item> inventory) { | ||||
| 		boolean worked = true; | ||||
| 		for (Item item : inventory) { | ||||
| 
 | ||||
| 			if (item.getItemBase().getType().equals(ItemType.GOLD)) | ||||
| 				continue; | ||||
| 
 | ||||
| 			prepareCallable("UPDATE `obj_item` LEFT JOIN `object` ON `object`.`UID` = `obj_item`.`UID` SET `object`.`parent`=NULL, `obj_item`.`item_container`='none' WHERE `object`.`UID`=?;"); | ||||
| 			setLong(1, (long) item.getObjectUUID()); | ||||
| 			if (executeUpdate() == 0) | ||||
| 				worked = false; | ||||
| 			else | ||||
| 				item.zeroItem(); | ||||
| 		} | ||||
| 		return worked; | ||||
| 	} | ||||
| 
 | ||||
| 	public Item PURCHASE_ITEM_FROM_VENDOR(final PlayerCharacter pc, final ItemBase ib) { | ||||
| 		Item item = null; | ||||
| 		byte charges = 0; | ||||
| 		charges = (byte) ib.getNumCharges(); | ||||
| 		short durability = (short) ib.getDurability(); | ||||
| 
 | ||||
| 		Item temp = new Item(ib, pc.getObjectUUID(), | ||||
| 				OwnerType.PlayerCharacter, charges, charges, durability, durability, | ||||
| 				true, false,ItemContainerType.INVENTORY, (byte) 0, | ||||
|                 new ArrayList<>(),""); | ||||
| 		try { | ||||
| 			item = this.ADD_ITEM(temp); | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error(e); | ||||
| 		} | ||||
| 		return item; | ||||
| 	} | ||||
| 
 | ||||
| 	public HashSet<Integer> GET_ITEMS_FOR_VENDOR(final int vendorID) { | ||||
| 		prepareCallable("SELECT ID FROM static_itembase WHERE vendorType = ?"); | ||||
| 		setInt(1, vendorID); | ||||
| 		return getIntegerList(1); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Item> GET_ITEMS_FOR_VENDOR_FORGING(final int npcID) { | ||||
| 		prepareCallable("SELECT `obj_item`.*, `object`.`parent` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=? AND `obj_item`.`item_container` =?"); | ||||
| 		setLong(1, (long) npcID); | ||||
| 		setString(2, "forge"); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Item i, String name, Object new_value) { | ||||
| 		prepareCallable("CALL item_SETPROP(?,?,?)"); | ||||
| 		setLong(1, (long) i.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Item i, String name, Object new_value, Object old_value) { | ||||
| 		prepareCallable("CALL item_GETSETPROP(?,?,?,?)"); | ||||
| 		setLong(1, (long) i.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		setString(4, String.valueOf(old_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	//Used to transfer a single item between owners or equip or vault or bank or inventory
 | ||||
| 	public boolean UPDATE_OWNER(final Item item, int newOwnerID, boolean ownerNPC, boolean ownerPlayer, | ||||
| 			boolean ownerAccount, ItemContainerType containerType, int slot) { | ||||
| 
 | ||||
| 		prepareCallable("CALL `item_TRANSFER_OWNER`(?, ?, ?, ? )"); | ||||
| 		setLong(1, (long) item.getObjectUUID()); | ||||
| 		if (newOwnerID != 0) | ||||
| 			setLong(2, (long) newOwnerID); | ||||
| 		else | ||||
| 			setNULL(2, java.sql.Types.BIGINT); | ||||
| 		 | ||||
| 		switch (containerType) { | ||||
| 			case INVENTORY: | ||||
| 				setString(3, "inventory"); | ||||
| 				break; | ||||
| 			case EQUIPPED: | ||||
| 				setString(3, "equip"); | ||||
| 				break; | ||||
| 			case BANK: | ||||
| 				setString(3, "bank"); | ||||
| 				break; | ||||
| 			case VAULT: | ||||
| 				setString(3, "vault"); | ||||
| 				break; | ||||
| 			case FORGE: | ||||
| 				setString(3, "forge"); | ||||
| 				break; | ||||
| 			default: | ||||
| 				setString(3, "none"); //Shouldn't be here
 | ||||
| 				break; | ||||
| 		} | ||||
| 		setInt(4, slot); | ||||
| 		return worked(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean SET_DURABILITY(final Item item, int value) { | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_durabilityCurrent`=? WHERE `UID`=? AND `item_durabilityCurrent`=?"); | ||||
| 		setInt(1, value); | ||||
| 		setLong(2, (long) item.getObjectUUID()); | ||||
| 		setInt(3, (int) item.getDurabilityCurrent()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	//Update an item except ownership
 | ||||
| 	public boolean UPDATE_DATABASE(final Item item) { | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_itembaseID`=?, `item_chargesRemaining`=?, `item_durabilityCurrent`=?, `item_durabilityMax`=?, `item_numberOfItems`=? WHERE `UID`=?"); | ||||
| 		setInt(1, item.getItemBaseID()); | ||||
| 		setInt(2, item.getChargesRemaining()); | ||||
| 		setInt(3, item.getDurabilityCurrent()); | ||||
| 		setInt(4, item.getDurabilityMax()); | ||||
| 		setInt(5, item.getNumOfItems()); | ||||
| 		setLong(6, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_ROLL_COMPLETE(final Item item) { | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_container` = ?, `item_dateToUpgrade` = ? WHERE `UID` = ?"); | ||||
| 		setString(1, "forge"); | ||||
| 		setLong(2, 0L); | ||||
| 		setLong(3, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean SET_DATE_TO_UPGRADE(final Item item, long date) { | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_dateToUPGRADE` = ? WHERE `UID` = ?"); | ||||
| 		setLong(1, date); | ||||
| 		setLong(2, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_FORGE_TO_INVENTORY(final Item item) { | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_container` = ? WHERE `UID` = ? AND `item_container` = 'forge';"); | ||||
| 		setString(1, "inventory"); | ||||
| 		setLong(2, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Attempts to update the quantity of this gold item | ||||
| 	 * | ||||
| 	 * @param value New quantity of gold | ||||
| 	 * @return True on success | ||||
| 	 */ | ||||
| 	public boolean UPDATE_GOLD(final Item item, int value) { | ||||
| 		if (item == null) | ||||
| 			return false; | ||||
| 		return UPDATE_GOLD(item, value, item.getNumOfItems()); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Attempts to update the quantity of this gold item using CAS | ||||
| 	 * | ||||
| 	 * @return True on success | ||||
| 	 */ | ||||
| 	public boolean UPDATE_GOLD(final Item item, int newValue, int oldValue) { | ||||
| 
 | ||||
| 		if (item.getItemBase().getType().equals(ItemType.GOLD) == false) | ||||
| 			return false; | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_numberOfItems`=? WHERE `UID`=?"); | ||||
| 		setInt(1, newValue); | ||||
| 		setLong(2, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * Attempts to update the value of two Gold items simultaneously. | ||||
| 	 * | ||||
| 	 * @param value New gold quantity for this item | ||||
| 	 * @param otherGold Other Gold item being modified | ||||
| 	 * @param valueOtherGold New quantity of gold for other item | ||||
| 	 * @return True on success | ||||
| 	 */ | ||||
| 	public boolean UPDATE_GOLD(Item gold, int value, Item otherGold, int valueOtherGold) { | ||||
| 
 | ||||
| 		if (gold.getItemBase().getType().equals(ItemType.GOLD) == false) | ||||
| 			return false; | ||||
| 
 | ||||
| 		if (otherGold.getItemBase().getType().equals(ItemType.GOLD) == false) | ||||
| 			return false; | ||||
| 
 | ||||
| 		int firstOld = gold.getNumOfItems(); | ||||
| 		int secondOld = gold.getNumOfItems(); | ||||
| 
 | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_numberOfItems` = CASE WHEN `UID`=? AND `item_numberOfItems`=? THEN ? WHEN `UID`=? AND `item_numberOfItems`=? THEN ? END WHERE `UID` IN (?, ?);"); | ||||
| 		setLong(1, (long) gold.getObjectUUID()); | ||||
| 		setInt(2, firstOld); | ||||
| 		setInt(3, value); | ||||
| 		setLong(4, (long) otherGold.getObjectUUID()); | ||||
| 		setInt(5, secondOld); | ||||
| 		setInt(6, valueOtherGold); | ||||
| 		setLong(7, (long) gold.getObjectUUID()); | ||||
| 		setLong(8, (long) otherGold.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_REMAINING_CHARGES(final Item item) { | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_chargesRemaining` = ? WHERE `UID` = ?"); | ||||
| 		setInt(1, item.getChargesRemaining()); | ||||
| 		setLong(2, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	// This is necessary because default number of items is 1.
 | ||||
| 	// When we create gold, we want it to start at 0 quantity.
 | ||||
| 
 | ||||
| 	public boolean ZERO_ITEM_STACK(Item item) { | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_numberOfItems`=0 WHERE `UID` = ?"); | ||||
| 		setLong(1, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_FLAGS(Item item) { | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_flags`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, item.getFlags()); | ||||
| 		setLong(2, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_VALUE(Item item,int value) { | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_value`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, value); | ||||
| 		setLong(2, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_FLAGS(Item item, int flags) { | ||||
| 		prepareCallable("UPDATE `obj_item` SET `item_flags`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, flags); | ||||
| 		setLong(2, (long) item.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,36 @@@@ -0,0 +1,36 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.Kit; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbKitHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbKitHandler() { | ||||
| 		this.localClass = Kit.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Kit> GET_KITS_FOR_RACE_AND_BASECLASS(int raceID, int baseClassID) { | ||||
| 		prepareCallable("SELECT vk.* FROM `static_rune_validkit` vk, `static_rune_racebaseclass` rbc WHERE rbc.`RaceID` = ? " | ||||
| 				+ "&& rbc.`BaseClassID` = ? && rbc.`ID` = vk.`RaceBaseClassesID`"); | ||||
| 		setInt(1, raceID); | ||||
| 		setInt(2, baseClassID); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Kit> GET_ALL_KITS() { | ||||
| 		prepareCallable("SELECT * FROM `static_rune_validkit`"); | ||||
| 
 | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,233 @@@@ -0,0 +1,233 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.loot.LootGroup; | ||||
| import engine.loot.LootManager; | ||||
| import engine.loot.ModifierGroup; | ||||
| import engine.loot.ModifierTable; | ||||
| import engine.objects.Item; | ||||
| import engine.objects.LootTable; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| 
 | ||||
| public class dbLootTableHandler extends dbHandlerBase { | ||||
| 
 | ||||
|     public dbLootTableHandler() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     public void populateLootGroups() { | ||||
|         int recordsRead = 0; | ||||
|         prepareCallable("SELECT `groupID`, `minRoll`, `maxRoll`, `lootTableID`, `pModTableID`, `sModTableID` FROM `static_lootgroups`"); | ||||
|          | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
|             if (rs != null) | ||||
|                 while (rs.next()) { | ||||
|                     recordsRead++; | ||||
|                     LootTable lootTable = LootTable.getLootGroup(rs.getInt("groupID")); | ||||
|                     lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("lootTableID"), rs.getInt("pModTableID"), rs.getInt("sModTableID"), ""); | ||||
|                 } | ||||
|              | ||||
|             Logger.info("read: " + recordsRead + " cached: " + LootTable.getLootGroups().size()); | ||||
|         } catch (SQLException e) { | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void populateLootTables() { | ||||
|         int recordsRead = 0; | ||||
|          | ||||
|         prepareCallable("SELECT `lootTable`, `minRoll`, `maxRoll`, `itemBaseUUID`, `minSpawn`, `maxSpawn` FROM `static_loottables`"); | ||||
|          | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
|             if (rs != null) | ||||
|                 while (rs.next()) { | ||||
|                     recordsRead++; | ||||
|                     LootTable lootTable = LootTable.getLootTable(rs.getInt("lootTable")); | ||||
|                     lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("itemBaseUUID"), rs.getInt("minSpawn"), rs.getInt("maxSpawn"), ""); | ||||
|                 } | ||||
|              | ||||
|              Logger.info("read: " + recordsRead + " cached: " + LootTable.getLootTables().size()); | ||||
|         } catch (SQLException e) { | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void populateModTables() { | ||||
|          | ||||
|         int recordsRead = 0; | ||||
|                  | ||||
|         prepareCallable("SELECT `modTable`,`minRoll`,`maxRoll`,`value`,`action` FROM `static_modtables`"); | ||||
|          | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
|             if (rs != null) | ||||
|                 while (rs.next()) { | ||||
|                     recordsRead++; | ||||
|                     LootTable lootTable = LootTable.getModTable(rs.getInt("modTable")); | ||||
|                     lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("value"), 0, 0, rs.getString("action")); | ||||
|                 } | ||||
|             Logger.info("read: " + recordsRead + " cached: " + LootTable.getModTables().size()); | ||||
|         } catch (SQLException e) { | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void populateModGroups() { | ||||
|          | ||||
|         int recordsRead = 0; | ||||
|          | ||||
|         prepareCallable("SELECT `modGroup`,`minRoll`,`maxRoll`,`subTableID` FROM `static_modgroups`"); | ||||
|          | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
|             if (rs != null) | ||||
|                 while (rs.next()) { | ||||
|                     recordsRead++; | ||||
|                     LootTable lootTable = LootTable.getModGroup(rs.getInt("modGroup")); | ||||
|                     lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("subTableID"), 0, 0, ""); | ||||
|                 } | ||||
|             Logger.info("read: " + recordsRead + " cached: " + LootTable.getModGroups().size()); | ||||
|         } catch (SQLException e) { | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void LOAD_ENCHANT_VALUES() { | ||||
|          | ||||
|         prepareCallable("SELECT `IDString`, `minMod` FROM `static_power_effectmod` WHERE `modType` = ?"); | ||||
|         setString(1,"Value"); | ||||
|          | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
|             while (rs.next()) { | ||||
|                 Item.addEnchantValue(rs.getString("IDString"), rs.getInt("minMod")); | ||||
|             } | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error( e); | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     public void LOAD_ALL_LOOTGROUPS() { | ||||
|          | ||||
|             LootGroup lootGroup; | ||||
|             int recordsRead = 0; | ||||
|              | ||||
| 		prepareCallable("SELECT * FROM static_lootgroups"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
|                          | ||||
| 			while (rs.next()) { | ||||
|                              | ||||
|                           recordsRead++; | ||||
|                           lootGroup = new LootGroup(rs); | ||||
|                           LootManager.addLootGroup(lootGroup); | ||||
| 			} | ||||
|                          | ||||
|                         Logger.info( "read: " + recordsRead); | ||||
|                                  | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
|      | ||||
|         public void LOAD_ALL_LOOTTABLES() { | ||||
|          | ||||
|             engine.loot.LootTable lootTable; | ||||
|             int recordsRead = 0; | ||||
|              | ||||
| 		prepareCallable("SELECT * FROM static_loottables"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
|                          | ||||
| 			while (rs.next()) { | ||||
|                              | ||||
|                           recordsRead++; | ||||
|                           lootTable = new engine.loot.LootTable(rs); | ||||
|                           LootManager.addLootTable(lootTable); | ||||
| 			} | ||||
|                          | ||||
|                         Logger.info("read: " + recordsRead); | ||||
|                                  | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
|          | ||||
|         public void LOAD_ALL_MODGROUPS() { | ||||
|          | ||||
|             ModifierGroup modGroup; | ||||
|             int recordsRead = 0; | ||||
|              | ||||
| 		prepareCallable("SELECT * FROM static_modgroups"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
|                          | ||||
| 			while (rs.next()) { | ||||
|                              | ||||
|                           recordsRead++; | ||||
|                           modGroup = new ModifierGroup(rs); | ||||
|                           LootManager.addModifierGroup(modGroup); | ||||
| 			} | ||||
|                          | ||||
|                         Logger.info( "read: " + recordsRead); | ||||
|                                  | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
|          | ||||
|         public void LOAD_ALL_MODTABLES() { | ||||
|          | ||||
|             ModifierTable modTable; | ||||
|             int recordsRead = 0; | ||||
|              | ||||
| 		prepareCallable("SELECT * FROM static_modtables"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
|                          | ||||
| 			while (rs.next()) { | ||||
|                              | ||||
|                           recordsRead++; | ||||
|                           modTable = new ModifierTable(rs); | ||||
|                           LootManager.addModifierTable(modTable); | ||||
| 			} | ||||
|                          | ||||
|                         Logger.info( "read: " + recordsRead); | ||||
|                                  | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,28 @@@@ -0,0 +1,28 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.MenuOption; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbMenuHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbMenuHandler() { | ||||
| 		this.localClass = MenuOption.class; | ||||
|         this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<MenuOption> GET_MENU_OPTIONS(final int id) { | ||||
| 		prepareCallable("SELECT * FROM `static_npc_menuoption` WHERE menuID = ?"); | ||||
| 		setInt(1, id); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,117 @@@@ -0,0 +1,117 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.Mine; | ||||
| import engine.objects.MineProduction; | ||||
| import engine.objects.Resource; | ||||
| 
 | ||||
| import java.time.LocalDateTime; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbMineHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbMineHandler() { | ||||
| 		this.localClass = Mine.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public Mine GET_MINE(int id) { | ||||
| 
 | ||||
| 		if (id == 0) | ||||
| 			return null; | ||||
| 
 | ||||
| 		Mine mine = (Mine) DbManager.getFromCache(Enum.GameObjectType.Mine, id); | ||||
| 		if (mine != null) | ||||
| 			return mine; | ||||
| 
 | ||||
| 		prepareCallable("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?;"); | ||||
| 
 | ||||
| 		setLong(1, (long) id); | ||||
| 		return (Mine) getObjectSingle(id); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Mine> GET_ALL_MINES_FOR_SERVER() { | ||||
| 		prepareCallable("SELECT `obj_mine`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mine` ON `obj_mine`.`UID` = `object`.`UID`"); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CHANGE_OWNER(Mine mine, int playerUID) { | ||||
| 		prepareCallable("UPDATE `obj_mine` SET `mine_ownerUID`=? WHERE `UID`=?"); | ||||
| 		setInt(1, playerUID); | ||||
| 		setLong(2, (long) mine.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CHANGE_RESOURCE(Mine mine, Resource resource) { | ||||
| 		prepareCallable("UPDATE `obj_mine` SET `mine_resource`=? WHERE `UID`=?"); | ||||
| 		setString(1, resource.name()); | ||||
| 		setLong(2, (long) mine.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CHANGE_TYPE(Mine mine, MineProduction productionType) { | ||||
| 		prepareCallable("UPDATE `obj_mine` SET `mine_type`=? WHERE `UID`=?"); | ||||
| 		setString(1, productionType.name()); | ||||
| 		setLong(2, (long) mine.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CHANGE_MINE_TIME(Mine mine, LocalDateTime mineOpenTime) { | ||||
| 		prepareCallable("UPDATE `obj_mine` SET `mine_openDate`=? WHERE `UID`=?"); | ||||
| 		setLocalDateTime(1, mineOpenTime); | ||||
| 		setLong(2, (long) mine.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean SET_FLAGS(Mine mine, int newFlags) { | ||||
| 		prepareCallable("UPDATE `obj_mine` SET `flags`=? WHERE `UID`=?"); | ||||
| 		setInt(1, newFlags); | ||||
| 		setLong(2, (long) mine.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Mine m, String name, Object new_value) { | ||||
| 		prepareCallable("CALL mine_SETPROP(?,?,?)"); | ||||
| 		setLong(1, (long) m.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	// Advance all the mine windows respective to the current day
 | ||||
| 	// at boot time.  This ensures that mines always go live
 | ||||
| 	// no matter what date in the database
 | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Mine m, String name, Object new_value, Object old_value) { | ||||
| 		prepareCallable("CALL mine_GETSETPROP(?,?,?,?)"); | ||||
| 		setLong(1, (long) m.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		setString(4, String.valueOf(old_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,351 @@@@ -0,0 +1,351 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| 
 | ||||
| public class dbMobBaseHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbMobBaseHandler() { | ||||
| 		this.localClass = MobBase.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
|     public MobBase GET_MOBBASE(int id, boolean forceDB) { | ||||
| 
 | ||||
| 
 | ||||
| 		if (id == 0) | ||||
| 			return null; | ||||
| 
 | ||||
| 		MobBase mobBase = (MobBase) DbManager.getFromCache(GameObjectType.MobBase, id); | ||||
| 
 | ||||
| 		if ( mobBase != null) | ||||
| 			return mobBase; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `static_npc_mobbase` WHERE `ID`=?"); | ||||
| 		setInt(1, id); | ||||
| 		return (MobBase) getObjectSingle(id, forceDB, true); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<MobBase> GET_ALL_MOBBASES() { | ||||
| 		prepareCallable("SELECT * FROM `static_npc_mobbase`;"); | ||||
| 		return  getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public void SET_AI_DEFAULTS() { | ||||
| 		prepareCallable("SELECT * FROM `static_ai_defaults`"); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 				MBServerStatics.AI_BASE_AGGRO_RANGE = rs.getInt("aggro_range"); | ||||
| 				MBServerStatics.AI_PATROL_DIVISOR = rs.getInt("patrol_chance"); | ||||
| 				MBServerStatics.AI_DROP_AGGRO_RANGE = rs.getInt("drop_aggro_range"); | ||||
| 				MBServerStatics.AI_POWER_DIVISOR = rs.getInt("cast_chance"); | ||||
| 				MBServerStatics.AI_RECALL_RANGE = rs.getInt("recall_range"); | ||||
| 				MBServerStatics.AI_PET_HEEL_DISTANCE = rs.getInt("pet_heel_distance"); | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_AI_DEFAULTS() { | ||||
| 		prepareCallable("UPDATE `static_ai_defaults` SET `aggro_range` = ?,`patrol_chance`= ?,`drop_aggro_range`= ?,`cast_chance`= ?,`recall_range`= ? WHERE `ID` = 1"); | ||||
| 		setInt(1, MBServerStatics.AI_BASE_AGGRO_RANGE); | ||||
| 		setInt(2, MBServerStatics.AI_PATROL_DIVISOR); | ||||
| 		setInt(3, MBServerStatics.AI_DROP_AGGRO_RANGE); | ||||
| 		setInt(4, MBServerStatics.AI_POWER_DIVISOR); | ||||
| 		setInt(5, MBServerStatics.AI_RECALL_RANGE); | ||||
| 		return (executeUpdate() > 0); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_FLAGS(int mobBaseID, long flags) { | ||||
| 		prepareCallable("UPDATE `static_npc_mobbase` SET `flags` = ? WHERE `ID` = ?"); | ||||
| 		setLong(1, flags); | ||||
| 		setInt(2, mobBaseID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public HashMap<Integer, Integer> LOAD_STATIC_POWERS(int mobBaseUUID) { | ||||
| 		HashMap<Integer, Integer> powersList = new HashMap<>(); | ||||
| 		prepareCallable("SELECT * FROM `static_npc_mobbase_powers` WHERE `mobbaseUUID`=?"); | ||||
| 		setInt(1, mobBaseUUID); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				powersList.put(rs.getInt("token"), rs.getInt("rank")); | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return powersList; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<MobBaseEffects> LOAD_STATIC_EFFECTS(int mobBaseUUID) { | ||||
| 		ArrayList<MobBaseEffects> effectsList = new ArrayList<>(); | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `static_npc_mobbase_effects` WHERE `mobbaseUUID` = ?"); | ||||
| 		setInt(1, mobBaseUUID); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 				MobBaseEffects mbs = new MobBaseEffects(rs); | ||||
| 				effectsList.add(mbs); | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return effectsList; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<MobBaseEffects> GET_RUNEBASE_EFFECTS(int runeID) { | ||||
| 		ArrayList<MobBaseEffects> effectsList = new ArrayList<>(); | ||||
| 		prepareCallable("SELECT * FROM `static_npc_mobbase_effects` WHERE `mobbaseUUID` = ?"); | ||||
| 		setInt(1, runeID); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				MobBaseEffects mbs = new MobBaseEffects(rs); | ||||
| 				effectsList.add(mbs); | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error (e.getMessage()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 		return effectsList; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public MobBaseStats LOAD_STATS(int mobBaseUUID) { | ||||
| 		MobBaseStats mbs = MobBaseStats.GetGenericStats(); | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `static_npc_mobbase_stats` WHERE `mobbaseUUID` = ?"); | ||||
| 		setInt(1, mobBaseUUID); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				mbs = new MobBaseStats(rs); | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return mbs; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<RuneBase> LOAD_RUNES_FOR_MOBBASE(int mobBaseUUID) { | ||||
| 
 | ||||
| 		ArrayList<RuneBase> runes = new ArrayList<>(); | ||||
| 		prepareCallable("SELECT * FROM `static_npc_mobbase_runes` WHERE `mobbaseUUID` = ?"); | ||||
| 		setInt(1, mobBaseUUID); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 				int runeID = rs.getInt("runeID"); | ||||
| 				RuneBase rune = RuneBase.getRuneBase(runeID); | ||||
| 				runes.add(rune); | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return runes; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_MOBBASE_EFFECT(int mobBaseUUID, int token, int rank, int reqLvl) { | ||||
| 		prepareCallable("INSERT INTO `static_npc_mobbase_effects` (`mobbaseUUID`, `token`, `rank`, `reqLvl`) VALUES (?, ?, ?, ?);"); | ||||
| 		setInt(1, mobBaseUUID); | ||||
| 		setInt(2, token); | ||||
| 		setInt(3, rank); | ||||
| 		setInt(4, reqLvl); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_MOBBASE_POWER(int mobBaseUUID, int token, int rank) { | ||||
| 		prepareCallable("INSERT INTO `static_npc_mobbase_powers` (`mobbaseUUID`, `token`, `rank`) VALUES (?, ?, ?);"); | ||||
| 		setInt(1, mobBaseUUID); | ||||
| 		setInt(2, token); | ||||
| 		setInt(3, rank); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_SKILLS(int ID, int skillsID) { | ||||
| 		prepareCallable("UPDATE `static_npc_mobbase` SET `baseSkills`=? WHERE `ID`=?;"); | ||||
| 		setInt(1, skillsID); | ||||
| 		setInt(2, ID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_MOBBASE_RUNE(int mobBaseUUID, int runeID) { | ||||
| 		prepareCallable("INSERT INTO `static_npc_mobbase_runes` (`mobbaseUUID`, `runeID`) VALUES (?, ?);"); | ||||
| 		setInt(1, mobBaseUUID); | ||||
| 		setInt(2, runeID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public MobBase COPY_MOBBASE(MobBase toAdd, String name) { | ||||
| 		prepareCallable("INSERT INTO `static_npc_mobbase` (`loadID`, `lootTableID`, `name`, `level`, `health`, `atr`, `defense`, `minDmg`,`maxDmg`, `goldMod`, `seeInvis`, `flags`, `noaggro`, `spawntime`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | ||||
| 		setInt(1, toAdd.getLoadID()); | ||||
| 		setInt(2, toAdd.getLootTable()); | ||||
| 		setString(3, (name.length() > 0) ? name : toAdd.getFirstName()); | ||||
| 		setInt(4, toAdd.getLevel()); | ||||
| 		setFloat(5, toAdd.getHealthMax()); | ||||
| 		setInt(5, toAdd.getAtr()); | ||||
| 		setInt(6, toAdd.getDefense()); | ||||
| 		setFloat(7, toAdd.getMinDmg()); | ||||
| 		setFloat(8, toAdd.getMaxDmg()); | ||||
| 		setInt(9, toAdd.getGoldMod()); | ||||
| 		setInt(10, toAdd.getSeeInvis()); | ||||
| 		setLong(11, toAdd.getFlags().toLong()); | ||||
| 		setLong(12, toAdd.getNoAggro().toLong()); | ||||
| 		setInt(13, toAdd.getSpawnTime()); | ||||
| 		int objectUUID = insertGetUUID(); | ||||
| 		if (objectUUID > 0) | ||||
| 			return GET_MOBBASE(objectUUID, true); | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean RENAME_MOBBASE(int ID, String newName) { | ||||
| 		prepareCallable("UPDATE `static_npc_mobbase` SET `name`=? WHERE `ID`=?;"); | ||||
| 		setString(1, newName); | ||||
| 		setInt(2, ID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public void LOAD_ALL_MOBBASE_LOOT(int mobBaseID) { | ||||
| 
 | ||||
| 		if (mobBaseID == 0) | ||||
| 			return; | ||||
| 		ArrayList<MobLootBase> mobLootList = new ArrayList<>(); | ||||
| 		prepareCallable("SELECT * FROM `static_mob_loottable` WHERE `mobBaseID` = ?"); | ||||
| 		setInt(1,mobBaseID); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				MobLootBase mobLootBase = new MobLootBase(rs); | ||||
| 				mobLootList.add(mobLootBase); | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 			MobLootBase.MobLootSet.put(mobBaseID, mobLootList); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_ALL_MOBBASE_SPEEDS(MobBase mobBase) { | ||||
| 
 | ||||
| 		if (mobBase.getLoadID() == 0) | ||||
| 			return; | ||||
| 		ArrayList<MobLootBase> mobLootList = new ArrayList<>(); | ||||
| 		prepareCallable("SELECT * FROM `static_npc_mobbase_race` WHERE `mobbaseID` = ?"); | ||||
| 		setInt(1,mobBase.getLoadID()); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 				float walk = rs.getFloat("walkStandard"); | ||||
| 				float walkCombat = rs.getFloat("walkCombat"); | ||||
| 				float run = rs.getFloat("runStandard"); | ||||
| 				float runCombat = rs.getFloat("runCombat"); | ||||
| 				mobBase.updateSpeeds(walk, walkCombat, run, runCombat); | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public HashMap<Integer, MobbaseGoldEntry> LOAD_GOLD_FOR_MOBBASE() { | ||||
| 
 | ||||
| 		HashMap<Integer, MobbaseGoldEntry> goldSets; | ||||
| 		MobbaseGoldEntry goldSetEntry; | ||||
| 		int	mobbaseID; | ||||
| 
 | ||||
| 		goldSets = new HashMap<>(); | ||||
| 		int recordsRead = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_npc_mobbase_gold"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 
 | ||||
| 				mobbaseID = rs.getInt("mobbaseID"); | ||||
| 				goldSetEntry = new MobbaseGoldEntry(rs); | ||||
| 				goldSets.put(mobbaseID, goldSetEntry); | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 			Logger.info("read: " + recordsRead + " cached: " + goldSets.size()); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return goldSets; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,316 @@@@ -0,0 +1,316 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.ai.MobileFSM.STATE; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.Mob; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.objects.Zone; | ||||
| import engine.server.MBServerStatics; | ||||
| import engine.server.world.WorldServer; | ||||
| import org.joda.time.DateTime; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| 
 | ||||
| public class dbMobHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbMobHandler() { | ||||
| 		this.localClass = Mob.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public Mob ADD_MOB(Mob toAdd, boolean isMob) | ||||
| 			 { | ||||
| 		prepareCallable("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | ||||
| 		setLong(1, toAdd.getParentZoneID()); | ||||
| 		setInt(2, toAdd.getMobBaseID()); | ||||
| 		setInt(3, toAdd.getGuildUUID()); | ||||
| 		setFloat(4, toAdd.getSpawnX()); | ||||
| 		setFloat(5, toAdd.getSpawnY()); | ||||
| 		setFloat(6, toAdd.getSpawnZ()); | ||||
| 		setInt(7, 0); | ||||
| 		setFloat(8, toAdd.getSpawnRadius()); | ||||
| 		setInt(9, toAdd.getTrueSpawnTime()); | ||||
| 		if (toAdd.getContract() != null) | ||||
| 			setInt(10, toAdd.getContract().getContractID()); | ||||
| 		else | ||||
| 			setInt(10, 0); | ||||
| 		setInt(11, toAdd.getBuildingID()); | ||||
| 		setInt(12, toAdd.getLevel()); | ||||
| 		int objectUUID = (int) getUUID(); | ||||
| 		if (objectUUID > 0) | ||||
| 			return GET_MOB(objectUUID); | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	public Mob ADD_SIEGE_MOB(Mob toAdd, boolean isMob) | ||||
| 			 { | ||||
| 		prepareCallable("CALL `mob_SIEGECREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | ||||
| 		setLong(1, toAdd.getParentZoneID()); | ||||
| 		setInt(2, toAdd.getMobBaseID()); | ||||
| 		setInt(3, toAdd.getGuildUUID()); | ||||
| 		setFloat(4, toAdd.getSpawnX()); | ||||
| 		setFloat(5, toAdd.getSpawnY()); | ||||
| 		setFloat(6, toAdd.getSpawnZ()); | ||||
| 		setInt(7,0); | ||||
| 		setFloat(8, toAdd.getSpawnRadius()); | ||||
| 		setInt(9, toAdd.getTrueSpawnTime()); | ||||
| 		setInt(10, toAdd.getBuildingID()); | ||||
| 
 | ||||
| 		int objectUUID = (int) getUUID(); | ||||
| 		if (objectUUID > 0) | ||||
| 			return GET_MOB(objectUUID); | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateUpgradeTime(Mob mob, DateTime upgradeDateTime) { | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		try { | ||||
| 
 | ||||
| 			prepareCallable("UPDATE obj_mob SET upgradeDate=? " | ||||
| 					+ "WHERE UID = ?"); | ||||
| 
 | ||||
| 			if (upgradeDateTime == null) | ||||
| 				setNULL(1, java.sql.Types.DATE); | ||||
| 			else | ||||
| 				setTimeStamp(1, upgradeDateTime.getMillis()); | ||||
| 
 | ||||
| 			setInt(2, mob.getObjectUUID()); | ||||
| 			executeUpdate(); | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error("Mob.updateUpgradeTime", "UUID: " + mob.getObjectUUID()); | ||||
| 			return false; | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	public int DELETE_MOB(final Mob mob) { | ||||
| 		prepareCallable("DELETE FROM `object` WHERE `UID` = ?"); | ||||
| 		setLong(1, mob.getDBID()); | ||||
| 		return executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_PATROL_POINTS(Mob captain) { | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `dyn_guards` WHERE `captainUID` = ?"); | ||||
| 		setInt(1,captain.getObjectUUID()); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 				int mobBaseID = rs.getInt("mobBaseID"); | ||||
| 				String name = rs.getString("name"); | ||||
| 				Mob toCreate = captain.createGuardMob(mobBaseID, captain.getGuild(), captain.getParentZone(), captain.getBuilding().getLoc(), captain.getLevel(),name); | ||||
| 				if (toCreate == null) | ||||
| 					return; | ||||
| 
 | ||||
| 				//   toCreate.despawn();
 | ||||
| 				if (toCreate != null) { | ||||
| 					 | ||||
| 					toCreate.setTimeToSpawnSiege(System.currentTimeMillis() + MBServerStatics.FIFTEEN_MINUTES); | ||||
| 					toCreate.setDeathTime(System.currentTimeMillis()); | ||||
| 					toCreate.setState(STATE.Respawn); | ||||
| 
 | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_TO_GUARDS(final long captainUID, final int mobBaseID, final String name, final int slot) { | ||||
| 		prepareCallable("INSERT INTO `dyn_guards` (`captainUID`, `mobBaseID`,`name`, `slot`) VALUES (?,?,?,?)"); | ||||
| 		setLong(1, captainUID); | ||||
| 		setInt(2, mobBaseID); | ||||
| 		setString(3, name); | ||||
| 		setInt(4, slot); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean REMOVE_FROM_GUARDS(final long captainUID, final int mobBaseID, final int slot) { | ||||
| 		prepareCallable("DELETE FROM `dyn_guards` WHERE `captainUID`=? AND `mobBaseID`=? AND `slot` =?"); | ||||
| 		setLong(1, captainUID); | ||||
| 		setInt(2, mobBaseID); | ||||
| 		setInt(3,slot); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public ArrayList<Mob> GET_ALL_MOBS_FOR_ZONE(Zone zone) { | ||||
| 		prepareCallable("SELECT `obj_mob`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mob` ON `obj_mob`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;"); | ||||
| 		setLong(1, zone.getObjectUUID()); | ||||
| 		return getLargeObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Mob> GET_ALL_MOBS_FOR_BUILDING(int buildingID) { | ||||
| 		prepareCallable("SELECT * FROM `obj_mob` WHERE `mob_buildingID` = ?"); | ||||
| 		setInt(1, buildingID); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Mob> GET_ALL_MOBS() { | ||||
| 		prepareCallable("SELECT `obj_mob`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mob` ON `obj_mob`.`UID` = `object`.`UID`;"); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public Mob GET_MOB(final int objectUUID) { | ||||
| 		prepareCallable("SELECT `obj_mob`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mob` ON `obj_mob`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?;"); | ||||
| 		setLong(1, objectUUID); | ||||
| 		return (Mob) getObjectSingle(objectUUID); | ||||
| 	} | ||||
| 
 | ||||
| 	public int MOVE_MOB(long mobID, long parentID, float locX, float locY, float locZ) { | ||||
| 		prepareCallable("UPDATE `object` INNER JOIN `obj_mob` On `object`.`UID` = `obj_mob`.`UID` SET `object`.`parent`=?, `obj_mob`.`mob_spawnX`=?, `obj_mob`.`mob_spawnY`=?, `obj_mob`.`mob_spawnZ`=? WHERE `obj_mob`.`UID`=?;"); | ||||
| 		setLong(1, parentID); | ||||
| 		setFloat(2, locX); | ||||
| 		setFloat(3, locY); | ||||
| 		setFloat(4, locZ); | ||||
| 		setLong(5, mobID); | ||||
| 		return executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_MOB_BUILDING(int buildingID, int mobID) { | ||||
| 		prepareCallable("UPDATE `object` INNER JOIN `obj_mob` On `object`.`UID` = `obj_mob`.`UID` SET  `obj_mob`.`mob_buildingID`=? WHERE `obj_mob`.`UID`=?;"); | ||||
| 		setInt(1, buildingID); | ||||
| 		setInt(2, mobID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Mob m, String name, Object new_value) { | ||||
| 		prepareCallable("CALL mob_SETPROP(?,?,?)"); | ||||
| 		setLong(1, m.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Mob m, String name, Object new_value, Object old_value) { | ||||
| 		prepareCallable("CALL mob_GETSETPROP(?,?,?,?)"); | ||||
| 		setLong(1, m.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		setString(4, String.valueOf(old_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public static boolean COPY_ZONE_MOBILES(PlayerCharacter pc, Zone sourceZone, Zone targetZone) { | ||||
| 
 | ||||
| 		ArrayList<Mob> sourceMobList; | ||||
| 		Vector3fImmutable worldDelta; | ||||
| 		Mob newMobile; | ||||
| 
 | ||||
| 		// Sanity check.  Can't copy a non existent zone
 | ||||
| 
 | ||||
| 		if ((sourceZone == null) || (targetZone == null)) | ||||
| 			return false; | ||||
| 
 | ||||
| 		// Generate collections for all buildings in each zone
 | ||||
| 
 | ||||
| 
 | ||||
| 		for (Mob mobile : sourceZone.zoneMobSet) { | ||||
| 
 | ||||
| 			// Calculate world coordinate offset between zones
 | ||||
| 
 | ||||
| 			worldDelta = new Vector3fImmutable(targetZone.getAbsX(), targetZone.getAbsY(), targetZone.getAbsZ()); | ||||
| 			worldDelta = worldDelta.subtract(new Vector3fImmutable(sourceZone.getAbsX(), sourceZone.getAbsY(), sourceZone.getAbsZ())); | ||||
| 
 | ||||
| 			newMobile = Mob.createMob(mobile.getLoadID(), | ||||
| 					mobile.getLoc().add(worldDelta), null, true, targetZone, mobile.getBuilding(), 0); | ||||
| 
 | ||||
| 			if (newMobile != null) { | ||||
| 				newMobile.updateDatabase(); | ||||
| 			} | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public void LOAD_RUNES_FOR_FIDELITY_MOBS() { | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		prepareCallable("SELECT static_zone_npc.npcID,static_zone_npc.loadNum, static_zone_npc.classID, static_zone_npc.professionID, static_zone_npc.extraRune, static_zone_npc.extraRune2 FROM static_zone_npc ; "); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 
 | ||||
| 				int loadNum = rs.getInt("loadNum"); | ||||
| 				int fidelityID = rs.getInt("npcID"); | ||||
| 				int classID = rs.getInt("classID"); | ||||
| 				int professionID = rs.getInt("professionID"); | ||||
| 				int extraRune = rs.getInt("extraRune"); | ||||
| 				int extraRune2 = rs.getInt("extraRune2"); | ||||
| 
 | ||||
| 				if (WorldServer.ZoneFidelityMobRunes.get(loadNum) == null) | ||||
| 					WorldServer.ZoneFidelityMobRunes.put(loadNum, new HashMap<>()); | ||||
| 				ArrayList<Integer> runeList; | ||||
| 				if (WorldServer.ZoneFidelityMobRunes.get(loadNum).get(fidelityID) == null){ | ||||
| 					runeList = new ArrayList<>(4); | ||||
| 				}else | ||||
| 					runeList = WorldServer.ZoneFidelityMobRunes.get(loadNum).get(fidelityID); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 				if (classID != 0) | ||||
| 					runeList.add(classID); | ||||
| 				if (professionID != 0) | ||||
| 					runeList.add(professionID); | ||||
| 				if(extraRune != 0) | ||||
| 					runeList.add(extraRune); | ||||
| 
 | ||||
| 				if (extraRune2 != 0) | ||||
| 					runeList.add(extraRune2); | ||||
| 
 | ||||
| 				WorldServer.ZoneFidelityMobRunes.get(loadNum).put(fidelityID, runeList); | ||||
| 
 | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 			rs.close(); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 
 | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,397 @@@@ -0,0 +1,397 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum.ProfitType; | ||||
| import engine.objects.*; | ||||
| import org.joda.time.DateTime; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| 
 | ||||
| public class dbNPCHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbNPCHandler() { | ||||
| 		this.localClass = NPC.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public NPC ADD_NPC(NPC toAdd, boolean isMob) { | ||||
| 		prepareCallable("CALL `npc_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | ||||
| 		setLong(1, toAdd.getParentZoneID()); | ||||
| 		setString(2, toAdd.getName()); | ||||
| 		setInt(3, toAdd.getContractID()); | ||||
| 		setInt(4, toAdd.getGuildUUID()); | ||||
| 		setFloat(5, toAdd.getSpawnX()); | ||||
| 		setFloat(6, toAdd.getSpawnY()); | ||||
| 		setFloat(7, toAdd.getSpawnZ()); | ||||
| 		setInt(8, toAdd.getLevel()); | ||||
| 		setFloat(9, toAdd.getBuyPercent()); | ||||
| 		setFloat(10, toAdd.getSellPercent()); | ||||
| 		if (toAdd.getBuilding() != null) { | ||||
| 			setInt(11, toAdd.getBuilding().getObjectUUID()); | ||||
| 		} else { | ||||
| 			setInt(11, 0); | ||||
| 		} | ||||
| 
 | ||||
| 		int objectUUID = (int) getUUID(); | ||||
| 		if (objectUUID > 0) { | ||||
| 			return GET_NPC(objectUUID); | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	public int DELETE_NPC(final NPC npc) { | ||||
| 		if (npc.isStatic()) { | ||||
| 			return DELETE_STATIC_NPC(npc); | ||||
| 		} | ||||
| 
 | ||||
| 		npc.removeFromZone(); | ||||
| 		prepareCallable("DELETE FROM `object` WHERE `UID` = ?"); | ||||
| 		setLong(1, (long) npc.getDBID()); | ||||
| 		return executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	private int DELETE_STATIC_NPC(final NPC npc) { | ||||
| 		npc.removeFromZone(); | ||||
| 		prepareCallable("DELETE FROM `_init_npc` WHERE `ID` = ?"); | ||||
| 		setInt(1, npc.getDBID()); | ||||
| 		return executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<NPC> GET_ALL_NPCS_FOR_ZONE(Zone zone) { | ||||
| 		prepareCallable("SELECT `obj_npc`.*, `object`.`parent` FROM `object` INNER JOIN `obj_npc` ON `obj_npc`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;"); | ||||
| 		setLong(1, (long) zone.getObjectUUID()); | ||||
| 		return getLargeObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<NPC> GET_ALL_NPCS() { | ||||
| 		prepareCallable("SELECT `obj_npc`.*, `object`.`parent` FROM `object` INNER JOIN `obj_npc` ON `obj_npc`.`UID` = `object`.`UID`;"); | ||||
| 		 | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<NPC> GET_NPCS_BY_BUILDING(final int buildingID) { | ||||
| 		prepareCallable("SELECT `obj_npc`.*, `object`.`parent` FROM `obj_npc` INNER JOIN `object` ON `obj_npc`.`UID` = `object`.`UID` WHERE `npc_buildingID` = ? LIMIT 3"); | ||||
| 		setInt(1, buildingID); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public NPC GET_NPC(final int objectUUID) { | ||||
| 		prepareCallable("SELECT `obj_npc`.*, `object`.`parent` FROM `object` INNER JOIN `obj_npc` ON `obj_npc`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?;"); | ||||
| 		setLong(1, (long) objectUUID); | ||||
| 		return (NPC) getObjectSingle(objectUUID); | ||||
| 	} | ||||
| 
 | ||||
| 	public int MOVE_NPC(long npcID, long parentID, float locX, float locY, float locZ) { | ||||
| 		prepareCallable("UPDATE `object` INNER JOIN `obj_npc` On `object`.`UID` = `obj_npc`.`UID` SET `object`.`parent`=?, `obj_npc`.`npc_spawnX`=?, `obj_npc`.`npc_spawnY`=?, `obj_npc`.`npc_spawnZ`=? WHERE `obj_npc`.`UID`=?;"); | ||||
| 		setLong(1, parentID); | ||||
| 		setFloat(2, locX); | ||||
| 		setFloat(3, locY); | ||||
| 		setFloat(4, locZ); | ||||
| 		setLong(5, npcID); | ||||
| 		return executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final NPC n, String name, Object new_value) { | ||||
| 		prepareCallable("CALL npc_SETPROP(?,?,?)"); | ||||
| 		setLong(1, (long) n.getDBID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final NPC n, String name, Object new_value, Object old_value) { | ||||
| 		prepareCallable("CALL npc_GETSETPROP(?,?,?,?)"); | ||||
| 		setLong(1, (long) n.getDBID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		setString(4, String.valueOf(old_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public void updateDatabase(final NPC npc) { | ||||
| 		prepareCallable("UPDATE obj_npc SET npc_name=?, npc_contractID=?, npc_typeID=?, npc_guildID=?," | ||||
| 				+ " npc_spawnX=?, npc_spawnY=?, npc_spawnZ=?, npc_level=? ," | ||||
| 				+ " npc_buyPercent=?, npc_sellPercent=?, npc_buildingID=? WHERE UID = ?"); | ||||
| 		setString(1, npc.getName()); | ||||
| 		setInt(2, (npc.getContract() != null) ? npc.getContract().getObjectUUID() : 0); | ||||
| 		setInt(3, 0); | ||||
| 		setInt(4, (npc.getGuild() != null) ? npc.getGuild().getObjectUUID() : 0); | ||||
| 		setFloat(5, npc.getBindLoc().x); | ||||
| 		setFloat(6, npc.getBindLoc().y); | ||||
| 		setFloat(7, npc.getBindLoc().z); | ||||
| 		setShort(8, npc.getLevel()); | ||||
| 		setFloat(9, npc.getBuyPercent()); | ||||
| 		setFloat(10, npc.getSellPercent()); | ||||
| 		setInt(11, (npc.getBuilding() != null) ? npc.getBuilding().getObjectUUID() : 0); | ||||
| 		setInt(12, npc.getDBID()); | ||||
| 		executeUpdate(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateUpgradeTime(NPC npc, DateTime upgradeDateTime) { | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		try { | ||||
| 
 | ||||
| 			prepareCallable("UPDATE obj_npc SET upgradeDate=? " | ||||
| 					+ "WHERE UID = ?"); | ||||
| 
 | ||||
| 			if (upgradeDateTime == null) | ||||
| 				setNULL(1, java.sql.Types.DATE); | ||||
| 			else | ||||
| 				setTimeStamp(1, upgradeDateTime.getMillis()); | ||||
| 
 | ||||
| 			setInt(2, npc.getObjectUUID()); | ||||
| 			executeUpdate(); | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error("UUID: " + npc.getObjectUUID()); | ||||
| 			return false; | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_BUY_PROFIT(NPC npc,float percent) { | ||||
| 		prepareCallable("UPDATE `obj_npc` SET `npc_buyPercent`=? WHERE `UID`=?"); | ||||
| 		setFloat(1, percent); | ||||
| 		setLong(2, npc.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_SELL_PROFIT(NPC npc,float percent) { | ||||
| 		prepareCallable("UPDATE `obj_npc` SET `npc_sellPercent`=? WHERE `UID`=?"); | ||||
| 		setFloat(1, percent); | ||||
| 		setLong(2, npc.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_SLOT(NPC npc,int slot) { | ||||
| 		prepareCallable("UPDATE `obj_npc` SET `npc_slot`=? WHERE `UID`=?"); | ||||
| 		setFloat(1, slot); | ||||
| 		setLong(2, npc.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_MOBBASE(NPC npc, int mobBaseID) { | ||||
| 		prepareCallable("UPDATE `obj_npc` SET `npc_raceID`=? WHERE `UID`=?"); | ||||
| 		setLong(1, mobBaseID); | ||||
| 		setLong(2, npc.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_EQUIPSET(NPC npc, int equipSetID) { | ||||
| 		prepareCallable("UPDATE `obj_npc` SET `equipsetID`=? WHERE `UID`=?"); | ||||
| 		setInt(1, equipSetID); | ||||
| 		setLong(2, npc.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean UPDATE_NAME(NPC npc,String name) { | ||||
| 		prepareCallable("UPDATE `obj_npc` SET `npc_name`=? WHERE `UID`=?"); | ||||
| 		setString(1, name); | ||||
| 		setLong(2, npc.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_PIRATE_NAMES() { | ||||
| 
 | ||||
| 		String pirateName; | ||||
| 		int mobBase; | ||||
| 		int recordsRead = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_piratenames"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 				mobBase = rs.getInt("mobbase"); | ||||
| 				pirateName = rs.getString("first_name"); | ||||
| 
 | ||||
| 				// Handle new mobbbase entries
 | ||||
| 
 | ||||
| 				if (NPC._pirateNames.get(mobBase) == null) { | ||||
| 					NPC._pirateNames.putIfAbsent(mobBase, new ArrayList<>()); | ||||
| 					} | ||||
| 
 | ||||
| 				// Insert name into proper arraylist
 | ||||
| 
 | ||||
| 				NPC._pirateNames.get(mobBase).add(pirateName); | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 			Logger.info("names read: " + recordsRead + " for " | ||||
| 			             + NPC._pirateNames.size() + " mobBases"); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public void LOAD_RUNES_FOR_FIDELITY_NPC(NPC npc) { | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		prepareCallable("SELECT static_zone_npc.npcID,static_zone_npc.loadNum, static_zone_npc.classID, static_zone_npc.professionID, static_zone_npc.extraRune, static_zone_npc.extraRune2 FROM static_zone_npc WHERE static_zone_npc.loadNum = ? AND static_zone_npc.npcID = ?"); | ||||
| 		setInt(1,npc.getParentZoneID()); | ||||
| 		setInt(2, npc.getFidalityID()); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 
 | ||||
| 				 | ||||
| 				int classID = rs.getInt("classID"); | ||||
| 				int professionID = rs.getInt("professionID"); | ||||
| 				int extraRune = rs.getInt("extraRune"); | ||||
| 				int extraRune2 = rs.getInt("extraRune2"); | ||||
| 				 | ||||
| 				npc.classID = classID; | ||||
| 				npc.professionID = professionID; | ||||
| 				npc.extraRune = extraRune; | ||||
| 				npc.extraRune2 = extraRune2; | ||||
| 
 | ||||
| 			 | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 			rs.close(); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.toString()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 
 | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean ADD_TO_PRODUCTION_LIST(final long ID,final long npcUID, final long itemBaseID, DateTime dateTime, String prefix, String suffix, String name, boolean isRandom, int playerID) { | ||||
| 		prepareCallable("INSERT INTO `dyn_npc_production` (`ID`,`npcUID`, `itemBaseID`,`dateToUpgrade`, `isRandom`, `prefix`, `suffix`, `name`,`playerID`) VALUES (?,?,?,?,?,?,?,?,?)"); | ||||
| 		setLong(1,ID); | ||||
| 		setLong(2, npcUID); | ||||
| 		setLong(3, itemBaseID); | ||||
| 		setTimeStamp(4, dateTime.getMillis()); | ||||
| 		setBoolean(5, isRandom); | ||||
| 		setString(6, prefix); | ||||
| 		setString(7, suffix); | ||||
| 		setString(8, name); | ||||
| 		setInt(9,playerID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean REMOVE_FROM_PRODUCTION_LIST(final long ID,final long npcUID) { | ||||
| 		prepareCallable("DELETE FROM `dyn_npc_production` WHERE `ID`=? AND `npcUID`=?;"); | ||||
| 		setLong(1,ID); | ||||
| 		setLong(2, npcUID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_ITEM_TO_INVENTORY(final long ID,final long npcUID) { | ||||
| 		prepareCallable("UPDATE `dyn_npc_production` SET `inForge`=? WHERE `ID`=? AND `npcUID`=?;"); | ||||
| 		setByte(1, (byte)0); | ||||
| 		setLong(2, ID); | ||||
| 		setLong(3, npcUID); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_ITEM_PRICE(final long ID,final long npcUID, int value) { | ||||
| 		prepareCallable("UPDATE `dyn_npc_production` SET `value`=? WHERE `ID`=? AND `npcUID`=?;"); | ||||
| 		setInt(1, value); | ||||
| 		setLong(2, ID); | ||||
| 		setLong(3, npcUID); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_ITEM_ID(final long ID,final long npcUID,final long value) { | ||||
| 		prepareCallable("UPDATE `dyn_npc_production` SET `ID`=? WHERE `ID`=? AND `npcUID`=? LIMIT 1;"); | ||||
| 		setLong(1, value); | ||||
| 		setLong(2, ID); | ||||
| 		setLong(3, npcUID); | ||||
| 
 | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_ALL_ITEMS_TO_PRODUCE(NPC npc) { | ||||
| 
 | ||||
| 		if (npc == null) | ||||
| 			return; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `dyn_npc_production` WHERE `npcUID` = ?"); | ||||
| 		setInt(1,npc.getObjectUUID()); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 				ProducedItem producedItem = new ProducedItem(rs); | ||||
| 				npc.forgedItems.add(producedItem); | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean UPDATE_PROFITS(NPC npc,ProfitType profitType, float value){ | ||||
| 		prepareCallable("UPDATE `dyn_npc_profits` SET `" + profitType.dbField + "` = ? WHERE `npcUID`=?"); | ||||
| 		setFloat(1, value); | ||||
| 		setInt(2, npc.getObjectUUID()); | ||||
| 		return (executeUpdate() > 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public void LOAD_NPC_PROFITS() { | ||||
| 
 | ||||
| 		HashMap<Integer, ArrayList<BuildingRegions>> regions; | ||||
| 		NPCProfits npcProfit; | ||||
| 
 | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM dyn_npc_profits"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				 | ||||
| 				npcProfit = new NPCProfits(rs); | ||||
| 				NPCProfits.ProfitCache.put(npcProfit.npcUID, npcProfit); | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(": " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean CREATE_PROFITS(NPC npc){ | ||||
| 			prepareCallable("INSERT INTO `dyn_npc_profits` (`npcUID`) VALUES (?)"); | ||||
| 			setLong(1,npc.getObjectUUID()); | ||||
| 			return (executeUpdate() > 0); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,402 @@@@ -0,0 +1,402 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.AbstractWorldObject; | ||||
| import engine.objects.Heraldry; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.objects.PlayerFriends; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| public class dbPlayerCharacterHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbPlayerCharacterHandler() { | ||||
| 		this.localClass = PlayerCharacter.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public PlayerCharacter ADD_PLAYER_CHARACTER(final PlayerCharacter toAdd) { | ||||
| 		if (toAdd.getAccount() == null) { | ||||
| 			return null; | ||||
| 		} | ||||
| 		prepareCallable("CALL `character_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | ||||
| 		setLong(1, toAdd.getAccount().getObjectUUID()); | ||||
| 		setString(2, toAdd.getFirstName()); | ||||
| 		setString(3, toAdd.getLastName()); | ||||
| 		setInt(4, toAdd.getRace().getRaceRuneID()); | ||||
| 		setInt(5, toAdd.getBaseClass().getObjectUUID()); | ||||
| 		setInt(6, toAdd.getStrMod()); | ||||
| 		setInt(7, toAdd.getDexMod()); | ||||
| 		setInt(8, toAdd.getConMod()); | ||||
| 		setInt(9, toAdd.getIntMod()); | ||||
| 		setInt(10, toAdd.getSpiMod()); | ||||
| 		setInt(11, toAdd.getExp()); | ||||
| 		setInt(12, toAdd.getSkinColor()); | ||||
| 		setInt(13, toAdd.getHairColor()); | ||||
| 		setByte(14, toAdd.getHairStyle()); | ||||
| 		setInt(15, toAdd.getBeardColor()); | ||||
| 		setByte(16, toAdd.getBeardStyle()); | ||||
| 
 | ||||
| 		int objectUUID = (int) getUUID(); | ||||
| 		if (objectUUID > 0) { | ||||
| 			return GET_PLAYER_CHARACTER(objectUUID); | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean SET_IGNORE_LIST(int sourceID, int targetID, boolean toIgnore, String charName) { | ||||
| 		if (toIgnore) { | ||||
| 			//Add to ignore list
 | ||||
| 			prepareCallable("INSERT INTO `dyn_character_ignore` (`accountUID`, `ignoringUID`, `characterName`) VALUES (?, ?, ?)"); | ||||
| 			setLong(1, (long) sourceID); | ||||
| 			setLong(2, (long) targetID); | ||||
| 			setString(3, charName); | ||||
| 			return (executeUpdate() > 0); | ||||
| 		} else { | ||||
| 			//delete from ignore list
 | ||||
| 			prepareCallable("DELETE FROM `dyn_character_ignore` WHERE `accountUID` = ? && `ignoringUID` = ?"); | ||||
| 			setLong(1, (long) sourceID); | ||||
| 			setLong(2, (long) targetID); | ||||
| 			return (executeUpdate() > 0); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public static boolean DELETE_CHARACTER_IGNORE(final PlayerCharacter pc, final ArrayList<Integer> toDelete) { | ||||
| 
 | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<PlayerCharacter> GET_ALL_PLAYERCHARACTERS() { | ||||
| 		prepareCallable("SELECT * FROM `obj_character`"); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<PlayerCharacter> GET_CHARACTERS_FOR_ACCOUNT(final int id, boolean forceFromDB) { | ||||
| 		prepareCallable("SELECT `obj_character`.*, `object`.`parent` FROM `object` INNER JOIN `obj_character` ON `obj_character`.`UID` = `object`.`UID` WHERE `object`.`parent`=? && `obj_character`.`char_isActive`='1';"); | ||||
| 		setLong(1, (long) id); | ||||
| 		return getObjectList(10, forceFromDB); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<PlayerCharacter> GET_CHARACTERS_FOR_ACCOUNT(final int id) { | ||||
| 		prepareCallable("SELECT `obj_character`.*, `object`.`parent` FROM `object` INNER JOIN `obj_character` ON `obj_character`.`UID` = `object`.`UID` WHERE `object`.`parent`=? && `obj_character`.`char_isActive`='1';"); | ||||
| 		setLong(1, (long) id); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<PlayerCharacter> GET_ALL_CHARACTERS() { | ||||
| 		prepareCallable("SELECT `obj_character`.*, `object`.`parent` FROM `object` INNER JOIN `obj_character` ON `obj_character`.`UID` = `object`.`UID` WHERE `obj_character`.`char_isActive`='1';"); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * | ||||
| 	 * <code>getFirstName</code> looks up the first name of a PlayerCharacter by | ||||
| 	 * first checking the GOM cache and then querying the database. | ||||
| 	 * PlayerCharacter objects that are not already cached won't be instantiated | ||||
| 	 * and cached. | ||||
| 	 * | ||||
| 	 */ | ||||
| 	public String GET_FIRST_NAME(final int objectUUID) { | ||||
| 		prepareCallable("SELECT `char_firstname` from `obj_character` WHERE `UID` = ? LIMIT 1"); | ||||
| 		setLong(1, (long) objectUUID); | ||||
| 		String firstName = ""; | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			if (rs.next()) { | ||||
| 				firstName = rs.getString("char_firstname"); | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return firstName; | ||||
| 	} | ||||
| 
 | ||||
| 	public ConcurrentHashMap<Integer, String> GET_IGNORE_LIST(final int objectUUID, final boolean skipActiveCheck) { | ||||
| 		ConcurrentHashMap<Integer, String> out = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); | ||||
| 		prepareCallable("SELECT * FROM `dyn_character_ignore` WHERE `accountUID` = ?;"); | ||||
| 		setLong(1, (long) objectUUID); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 				int ignoreCharacterID = rs.getInt("ignoringUID"); | ||||
| 				if (ignoreCharacterID == 0) { | ||||
| 					continue; | ||||
| 				} | ||||
| 				String name = rs.getString("characterName"); | ||||
| 				out.put(ignoreCharacterID, name); | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 			return out; // null to explicitly indicate a problem and prevent data loss
 | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return out; | ||||
| 	} | ||||
| 
 | ||||
| 	public PlayerCharacter GET_PLAYER_CHARACTER(final int objectUUID) { | ||||
| 
 | ||||
| 		if (objectUUID == 0) | ||||
| 			return null; | ||||
| 
 | ||||
| 		PlayerCharacter pc = (PlayerCharacter) DbManager.getFromCache(Enum.GameObjectType.PlayerCharacter, objectUUID); | ||||
| 		if (pc != null) | ||||
| 			return pc; | ||||
| 		prepareCallable("SELECT `obj_character`.*, `object`.`parent` FROM `object` INNER JOIN `obj_character` ON `obj_character`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?"); | ||||
| 		setLong(1, (long) objectUUID); | ||||
| 		return (PlayerCharacter) getObjectSingle(objectUUID); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean INSERT_CHARACTER_IGNORE(final PlayerCharacter pc, final ArrayList<Integer> toAdd) { | ||||
| 		boolean allWorked = true; | ||||
| 		prepareCallable("INSERT INTO `dyn_character_ignore` (`characterUID`, `ignoringUID`) VALUES (?, ?)"); | ||||
| 		setLong(1, (long) pc.getObjectUUID()); | ||||
| 		for (int id : toAdd) { | ||||
| 			setLong(2, (long) id); | ||||
| 			if (executeUpdate(false) == 0) { | ||||
| 				allWorked = false; | ||||
| 			} | ||||
| 		} | ||||
| 		closeCallable(); | ||||
| 		return allWorked; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean IS_CHARACTER_NAME_UNIQUE(final String firstName) { | ||||
| 		boolean unique = true; | ||||
| 		prepareCallable("SELECT `char_firstname` FROM `obj_character` WHERE `char_isActive`=1 && `char_firstname`=?"); | ||||
| 		setString(1, firstName); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			if (rs.next()) { | ||||
| 				unique = false; | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getMessage()); | ||||
| 			unique = false; | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return unique; | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_NAME(String oldFirstName, String newFirstName, String newLastName) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `char_firstname`=?, `char_lastname`=? WHERE `char_firstname`=? AND `char_isActive`='1'"); | ||||
| 		setString(1, newFirstName); | ||||
| 		setString(2, newLastName); | ||||
| 		setString(3, oldFirstName); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean SET_DELETED(final PlayerCharacter pc) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `char_isActive`=? WHERE `UID` = ?"); | ||||
| 		setBoolean(1, !pc.isDeleted()); | ||||
| 		setLong(2, (long) pc.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	public boolean SET_ACTIVE(final PlayerCharacter pc, boolean status) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `char_isActive`=? WHERE `UID` = ?"); | ||||
| 		setBoolean(1, status); | ||||
| 		setLong(2, (long) pc.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	public boolean SET_BIND_BUILDING(final PlayerCharacter pc, int bindBuildingID) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `char_bindBuilding`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, bindBuildingID); | ||||
| 		setLong(2, (long) pc.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean SET_ANNIVERSERY(final PlayerCharacter pc, boolean flag) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `anniversery`=? WHERE `UID` = ?"); | ||||
| 		setBoolean(1, flag); | ||||
| 		setLong(2, (long) pc.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	public boolean UPDATE_CHARACTER_EXPERIENCE(final PlayerCharacter pc) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `char_experience`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, pc.getExp()); | ||||
| 		setLong(2, (long) pc.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean UPDATE_GUILD(final PlayerCharacter pc, int guildUUID) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `guildUID`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, guildUUID); | ||||
| 		setLong(2, (long) pc.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_CHARACTER_STAT(final PlayerCharacter pc, String stat, short amount) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `" + stat + "`=? WHERE `UID`=?"); | ||||
| 		setInt(1, pc.getExp()); | ||||
| 		setLong(2, (long) pc.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean UPDATE_CHARACTER_STATS(final PlayerCharacter pc) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `char_strMod`=?, `char_dexMod`=?, `char_conMod`=?, `char_intMod`=?, `char_spiMod`=? WHERE `UID`=?"); | ||||
| 		setInt(1, pc.getStrMod()); | ||||
| 		setInt(2, pc.getDexMod()); | ||||
| 		setInt(3, pc.getConMod()); | ||||
| 		setInt(4, pc.getIntMod()); | ||||
| 		setInt(5, pc.getSpiMod()); | ||||
| 		setLong(6, (long) pc.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final PlayerCharacter c, String name, Object new_value) { | ||||
| 		prepareCallable("CALL character_SETPROP(?,?,?)"); | ||||
| 		setLong(1, (long) c.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final PlayerCharacter c, String name, Object new_value, Object old_value) { | ||||
| 		prepareCallable("CALL character_GETSETPROP(?,?,?,?)"); | ||||
| 		setLong(1, (long) c.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		setString(4, String.valueOf(old_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean SET_PROMOTION_CLASS(PlayerCharacter player, int promotionClassID) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `char_promotionClassID`=?  WHERE `UID`=?;"); | ||||
| 		setInt(1,promotionClassID); | ||||
| 		setInt(2, player.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean SET_INNERCOUNCIL(PlayerCharacter player, boolean isInnerCouncil) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `guild_isInnerCouncil`=?  WHERE `UID`=?;"); | ||||
| 		setBoolean(1,isInnerCouncil); | ||||
| 		setInt(2, player.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean SET_FULL_MEMBER(PlayerCharacter player, boolean isFullMember) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `guild_isFullMember`=?  WHERE `UID`=?;"); | ||||
| 		setBoolean(1,isFullMember); | ||||
| 		setInt(2, player.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean SET_TAX_COLLECTOR(PlayerCharacter player, boolean isTaxCollector) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `guild_isTaxCollector`=?  WHERE `UID`=?;"); | ||||
| 		setBoolean(1,isTaxCollector); | ||||
| 		setInt(2, player.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean SET_RECRUITER(PlayerCharacter player, boolean isRecruiter) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `guild_isRecruiter`=?  WHERE `UID`=?;"); | ||||
| 		setBoolean(1,isRecruiter); | ||||
| 		setInt(2, player.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean SET_GUILD_TITLE(PlayerCharacter player, int title) { | ||||
| 		prepareCallable("UPDATE `obj_character` SET `guild_title`=?  WHERE `UID`=?;"); | ||||
| 		setInt(1,title); | ||||
| 		setInt(2, player.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
| 	 | ||||
| 	public boolean ADD_FRIEND(int source, long friend){ | ||||
| 		prepareCallable("INSERT INTO `dyn_character_friends` (`playerUID`, `friendUID`) VALUES (?, ?)"); | ||||
| 		setLong(1, (long) source); | ||||
| 		setLong(2, (long)friend); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean REMOVE_FRIEND(int source, int friend){ | ||||
| 		prepareCallable("DELETE FROM `dyn_character_friends` WHERE (`playerUID`=?) AND (`friendUID`=?)"); | ||||
| 		setLong(1, (long) source); | ||||
| 		setLong(2, (long)friend); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public void LOAD_PLAYER_FRIENDS() { | ||||
| 
 | ||||
| 		PlayerFriends playerFriend; | ||||
| 
 | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM dyn_character_friends"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 				playerFriend = new PlayerFriends(rs); | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("LoadMeshBounds: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean ADD_HERALDY(int source, AbstractWorldObject character){ | ||||
| 		prepareCallable("INSERT INTO `dyn_character_heraldy` (`playerUID`, `characterUID`,`characterType`) VALUES (?, ?,?)"); | ||||
| 		setLong(1, (long) source); | ||||
| 		setLong(2, (long)character.getObjectUUID()); | ||||
| 		setInt(3, character.getObjectType().ordinal()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public boolean REMOVE_HERALDY(int source, int characterUID){ | ||||
| 		prepareCallable("DELETE FROM `dyn_character_heraldy` WHERE (`playerUID`=?) AND (`characterUID`=?)"); | ||||
| 		setLong(1, (long) source); | ||||
| 		setLong(2, (long)characterUID); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 	 | ||||
| 	public void LOAD_HERALDY() { | ||||
| 
 | ||||
| 		Heraldry heraldy; | ||||
| 
 | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM dyn_character_heraldy"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 				heraldy = new Heraldry(rs); | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("LoadHeraldy: " + e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 	 | ||||
| } | ||||
| @ -0,0 +1,54 @@@@ -0,0 +1,54 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.PromotionClass; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbPromotionClassHandler extends dbHandlerBase { | ||||
| 
 | ||||
|     public dbPromotionClassHandler() { | ||||
|         this.localClass = PromotionClass.class; | ||||
|         this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
|     } | ||||
| 
 | ||||
|     public ArrayList<Integer> GET_ALLOWED_RUNES(final PromotionClass pc) { | ||||
|         ArrayList<Integer> runes = new ArrayList<>(); | ||||
|         prepareCallable("SELECT * FROM `static_rune_promotionrunereq` WHERE `promoID`=?"); | ||||
|         setInt(1, pc.getObjectUUID()); | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
|             while (rs.next()) { | ||||
|                 runes.add(rs.getInt("runereqID")); | ||||
|             } | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error("Failed to retrieve Allowed Runes for PromotionClass " + pc.getObjectUUID() + ". Error number: " + e.getErrorCode(), e); | ||||
|             return null; | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|         return runes; | ||||
|     } | ||||
| 
 | ||||
|     public PromotionClass GET_PROMOTION_CLASS(final int objectUUID) { | ||||
|         prepareCallable("SELECT * FROM `static_rune_promotion` WHERE `ID` = ?"); | ||||
|         setInt(1, objectUUID); | ||||
|         return (PromotionClass) getObjectSingle(objectUUID); | ||||
|     } | ||||
|      | ||||
|     public ArrayList<PromotionClass> GET_ALL_PROMOTIONS() { | ||||
| 		prepareCallable("SELECT * FROM `static_rune_promotion`"); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,85 @@@@ -0,0 +1,85 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.Race; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.HashSet; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| public class dbRaceHandler extends dbHandlerBase { | ||||
| 
 | ||||
|     public dbRaceHandler() { | ||||
|     } | ||||
| 
 | ||||
|     public HashSet<Integer> BEARD_COLORS_FOR_RACE(final int id) { | ||||
|         prepareCallable("SELECT `color` FROM `static_rune_racebeardcolor` WHERE `RaceID` = ?"); | ||||
|         setInt(1, id); | ||||
|         return getIntegerList(1); | ||||
|     } | ||||
| 
 | ||||
|     public HashSet<Integer> BEARD_STYLES_FOR_RACE(final int id) { | ||||
|         prepareCallable("SELECT `beardStyle` FROM `static_rune_racebeardstyle` WHERE `RaceID` = ?"); | ||||
|         setInt(1, id); | ||||
|         return getIntegerList(1); | ||||
|     } | ||||
| 
 | ||||
|     public HashSet<Integer> HAIR_COLORS_FOR_RACE(final int id) { | ||||
|         prepareCallable("SELECT `color` FROM `static_rune_racehaircolor` WHERE `RaceID` = ?"); | ||||
|         setInt(1, id); | ||||
|         return getIntegerList(1); | ||||
|     } | ||||
| 
 | ||||
|     public HashSet<Integer> HAIR_STYLES_FOR_RACE(final int id) { | ||||
|         prepareCallable("SELECT `hairStyle` FROM `static_rune_racehairstyle` WHERE `RaceID` = ?"); | ||||
|         setInt(1, id); | ||||
|         return getIntegerList(1); | ||||
|     } | ||||
| 
 | ||||
|     public HashSet<Integer> SKIN_COLOR_FOR_RACE(final int id) { | ||||
|         prepareCallable("SELECT `color` FROM `static_rune_raceskincolor` WHERE `RaceID` = ?"); | ||||
|         setInt(1, id); | ||||
|         return getIntegerList(1); | ||||
|     } | ||||
| 
 | ||||
|     public ConcurrentHashMap<Integer, Race> LOAD_ALL_RACES() { | ||||
| 
 | ||||
|         ConcurrentHashMap<Integer, Race> races; | ||||
|         Race thisRace; | ||||
| 
 | ||||
|         races = new ConcurrentHashMap<>(); | ||||
|         int recordsRead = 0; | ||||
| 
 | ||||
|         prepareCallable("SELECT * FROM static_rune_race"); | ||||
| 
 | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
| 
 | ||||
|             while (rs.next()) { | ||||
| 
 | ||||
|                 recordsRead++; | ||||
|                 thisRace = new Race(rs); | ||||
| 
 | ||||
|                 races.put(thisRace.getRaceRuneID(), thisRace); | ||||
|             } | ||||
| 
 | ||||
|             Logger.info("read: " + recordsRead + " cached: " + races.size()); | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error( e.toString()); | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|         return races; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,73 @@@@ -0,0 +1,73 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.Realm; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.net.UnknownHostException; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| import java.util.logging.Level; | ||||
| 
 | ||||
| public class dbRealmHandler extends dbHandlerBase { | ||||
| 
 | ||||
|     public dbRealmHandler() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|         public ConcurrentHashMap<Integer, Realm> LOAD_ALL_REALMS() { | ||||
|          | ||||
|             ConcurrentHashMap<Integer, Realm> realmList; | ||||
|             Realm thisRealm; | ||||
|                      | ||||
|             realmList = new ConcurrentHashMap<>(); | ||||
|             int recordsRead = 0; | ||||
|              | ||||
| 		prepareCallable("SELECT * FROM obj_realm"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
|                          | ||||
| 			while (rs.next()) { | ||||
|                              | ||||
|                           recordsRead++; | ||||
|                           thisRealm = new Realm(rs); | ||||
|                           realmList.put(thisRealm.getRealmID(), thisRealm); | ||||
| 			} | ||||
|                          | ||||
|                         Logger.info( "read: " + recordsRead + " cached: " + realmList.size()); | ||||
|                                  | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} catch (UnknownHostException ex) { | ||||
|             java.util.logging.Logger.getLogger(dbRealmHandler.class.getName()).log(Level.SEVERE, null, ex); | ||||
|         } finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return realmList; | ||||
| 	} | ||||
|          | ||||
|     public void REALM_UPDATE(Realm realm) { | ||||
| 
 | ||||
|             prepareCallable("CALL realm_UPDATE(?,?,?,?)"); | ||||
|              | ||||
|             setInt(1, realm.getRealmID()); | ||||
|             setInt(2, (realm.getRulingCity() == null) ? 0 : realm.getRulingCity().getObjectUUID()); | ||||
|             setInt(3, realm.getCharterType()); | ||||
|         if (realm.ruledSince != null) | ||||
|             setLocalDateTime(4, realm.ruledSince); | ||||
|             else | ||||
|                 setNULL(4, java.sql.Types.DATE); | ||||
|              | ||||
|             executeUpdate(); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,37 @@@@ -0,0 +1,37 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.Resists; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| 
 | ||||
| public class dbResistHandler extends dbHandlerBase { | ||||
| 
 | ||||
|     public dbResistHandler() { | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public Resists GET_RESISTS_FOR_MOB(int resistID) { | ||||
|         prepareCallable("SELECT * FROM `static_npc_mob_resists` WHERE `ID` = ?;"); | ||||
|         setInt(1, resistID); | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
|             if (rs.next()) { | ||||
|                 return new Resists(rs); | ||||
|             } | ||||
|         } catch (SQLException e) { | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,35 @@@@ -0,0 +1,35 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.RuneBaseAttribute; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbRuneBaseAttributeHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbRuneBaseAttributeHandler() { | ||||
| 		this.localClass = RuneBaseAttribute.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<RuneBaseAttribute> GET_ATTRIBUTES_FOR_RUNEBASE(int id) { | ||||
| 		prepareCallable("SELECT * FROM `static_rune_runebaseattribute` WHERE `RuneBaseID`=?"); | ||||
| 		setInt(1, id); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<RuneBaseAttribute> GET_ATTRIBUTES_FOR_RUNEBASE() { | ||||
| 		prepareCallable("SELECT * FROM `static_rune_runebaseattribute`"); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,73 @@@@ -0,0 +1,73 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.RuneBaseEffect; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| 
 | ||||
| public class dbRuneBaseEffectHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbRuneBaseEffectHandler() { | ||||
| 		this.localClass = RuneBaseEffect.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<RuneBaseEffect> GET_EFFECTS_FOR_RUNEBASE(int id) { | ||||
| 		prepareCallable("SELECT * FROM `static_rune_baseeffect` WHERE `runeID`=?"); | ||||
| 		setInt(1, id); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public RuneBaseEffect GET_RUNEBASE_EFFECT(int id) { | ||||
| 
 | ||||
| 		if (id == 0) | ||||
| 			return null; | ||||
| 		RuneBaseEffect runeBaseEffect = (RuneBaseEffect) DbManager.getFromCache(GameObjectType.RuneBaseEffect, id); | ||||
| 		if (runeBaseEffect != null) | ||||
| 			return runeBaseEffect; | ||||
| 		prepareCallable("SELECT * FROM `static_rune_baseeffect` WHERE `ID` = ?"); | ||||
| 		setInt(1, id); | ||||
| 		return (RuneBaseEffect) getObjectSingle(id); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<RuneBaseEffect> GET_ALL_RUNEBASE_EFFECTS(){ | ||||
| 		prepareCallable("SELECT * FROM `static_rune_baseeffect`;"); | ||||
| 		return  getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	//This calls from cache only. Call this AFTER caching all runebase effects;
 | ||||
| 	public HashMap<Integer, ArrayList<RuneBaseEffect>> LOAD_BASEEFFECTS_FOR_RUNEBASE() { | ||||
| 		HashMap<Integer, ArrayList<RuneBaseEffect>> runeBaseEffectSet; | ||||
| 		runeBaseEffectSet = new HashMap<>(); | ||||
| 
 | ||||
| 
 | ||||
| 		for (AbstractGameObject runeBaseEffect:DbManager.getList(GameObjectType.RuneBaseEffect)){ | ||||
| 
 | ||||
| 			int runeBaseID = ((RuneBaseEffect)runeBaseEffect).getRuneBaseID(); | ||||
| 			if (runeBaseEffectSet.get(runeBaseID) == null){ | ||||
| 				ArrayList<RuneBaseEffect> runeBaseEffectList = new ArrayList<>(); | ||||
| 				runeBaseEffectList.add((RuneBaseEffect)runeBaseEffect); | ||||
| 				runeBaseEffectSet.put(runeBaseID, runeBaseEffectList); | ||||
| 			} | ||||
| 			else{ | ||||
| 				ArrayList<RuneBaseEffect>runeBaseEffectList = runeBaseEffectSet.get(runeBaseID); | ||||
| 				runeBaseEffectList.add((RuneBaseEffect)runeBaseEffect); | ||||
| 				runeBaseEffectSet.put(runeBaseID, runeBaseEffectList); | ||||
| 			} | ||||
| 		} | ||||
| 		return runeBaseEffectSet; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,173 @@@@ -0,0 +1,173 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.RuneBase; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| 
 | ||||
| public class dbRuneBaseHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbRuneBaseHandler() { | ||||
| 		this.localClass = RuneBase.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public void GET_RUNE_REQS(final RuneBase rb) { | ||||
| 		prepareCallable("SELECT * FROM `static_rune_runereq` WHERE `runeID` = ?"); | ||||
| 		setInt(1, rb.getObjectUUID()); | ||||
| 		try { | ||||
| 
 | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 				int type = rs.getInt("type"); | ||||
| 
 | ||||
| 				switch (type) { | ||||
| 				case 1: | ||||
| 					rb.getRace().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed")); | ||||
| 					break; | ||||
| 				case 2: | ||||
| 					rb.getBaseClass().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed")); | ||||
| 					break; | ||||
| 				case 3: | ||||
| 					rb.getPromotionClass().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed")); | ||||
| 					break; | ||||
| 				case 4: | ||||
| 					rb.getDiscipline().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed")); | ||||
| 					break; | ||||
| 				case 5: | ||||
| 					rb.getOverwrite().add(rs.getInt("requiredRuneID")); | ||||
| 					break; | ||||
| 				case 6: | ||||
| 					rb.setLevelRequired(rs.getInt("requiredRuneID")); | ||||
| 					break; | ||||
| 				} | ||||
| 			} | ||||
| 			rs.close(); | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error("SQL Error number: " + e.getErrorCode()); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public RuneBase GET_RUNEBASE(final int id) { | ||||
| 		prepareCallable("SELECT * FROM `static_rune_runebase` WHERE `ID` = ?"); | ||||
| 		setInt(1, id); | ||||
| 		return (RuneBase) getObjectSingle(id); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<RuneBase> LOAD_ALL_RUNEBASES() { | ||||
| 		prepareCallable("SELECT * FROM `static_rune_runebase`;"); | ||||
| 		return  getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public HashMap<Integer, ArrayList<Integer>> LOAD_ALLOWED_STARTING_RUNES_FOR_BASECLASS() { | ||||
| 
 | ||||
| 		HashMap<Integer, ArrayList<Integer>> runeSets; | ||||
| 
 | ||||
| 		runeSets = new HashMap<>(); | ||||
| 		int recordsRead = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_rune_baseclassrune"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 
 | ||||
| 				int baseClassID = rs.getInt("BaseClassesID"); | ||||
| 				int runeBaseID = rs.getInt("RuneBaseID"); | ||||
| 
 | ||||
| 				if (runeSets.get(baseClassID) == null){ | ||||
| 					ArrayList<Integer> runeList = new ArrayList<>(); | ||||
| 					runeList.add(runeBaseID); | ||||
| 					runeSets.put(baseClassID, runeList); | ||||
| 				} | ||||
| 				else{ | ||||
| 					ArrayList<Integer>runeList = runeSets.get(baseClassID); | ||||
| 					runeList.add(runeBaseID); | ||||
| 					runeSets.put(baseClassID, runeList); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			Logger.info("read: " + recordsRead + " cached: " + runeSets.size()); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return runeSets; | ||||
| 	} | ||||
| 
 | ||||
| 	public HashMap<Integer, ArrayList<Integer>> LOAD_ALLOWED_STARTING_RUNES_FOR_RACE() { | ||||
| 
 | ||||
| 		HashMap<Integer, ArrayList<Integer>> runeSets; | ||||
| 
 | ||||
| 		runeSets = new HashMap<>(); | ||||
| 		int recordsRead = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_rune_racerune"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 
 | ||||
| 				int raceID = rs.getInt("RaceID"); | ||||
| 				int runeBaseID = rs.getInt("RuneBaseID"); | ||||
| 
 | ||||
| 				if (runeSets.get(raceID) == null){ | ||||
| 					ArrayList<Integer> runeList = new ArrayList<>(); | ||||
| 					runeList.add(runeBaseID); | ||||
| 					runeSets.put(raceID, runeList); | ||||
| 				} | ||||
| 				else{ | ||||
| 					ArrayList<Integer>runeList = runeSets.get(raceID); | ||||
| 					runeList.add(runeBaseID); | ||||
| 					runeSets.put(raceID, runeList); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			Logger.info( "read: " + recordsRead + " cached: " + runeSets.size()); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return runeSets; | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<RuneBase> GET_RUNEBASE_FOR_BASECLASS(final int id) { | ||||
| 		prepareCallable("SELECT rb.* FROM static_rune_baseclassrune bcr, static_rune_runebase rb WHERE bcr.RuneBaseID = rb.ID " | ||||
| 				+ "&& ( bcr.BaseClassesID = 111111 || bcr.BaseClassesID = ? )"); | ||||
| 		setInt(1, id); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public HashSet<RuneBase> GET_RUNEBASE_FOR_RACE(final int id) { | ||||
| 		prepareCallable("SELECT rb.* FROM static_rune_racerune rr, static_rune_runebase rb" | ||||
| 				+ " WHERE rr.RuneBaseID = rb.ID && ( rr.RaceID = 111111 || rr.RaceID = ?)"); | ||||
| 		setInt(1, id); | ||||
| 		return new HashSet<>(getObjectList()); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,147 @@@@ -0,0 +1,147 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum.ProtectionState; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.Building; | ||||
| import engine.objects.Shrine; | ||||
| import org.joda.time.DateTime; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.net.UnknownHostException; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbShrineHandler extends dbHandlerBase { | ||||
| 
 | ||||
|     public dbShrineHandler() { | ||||
|         this.localClass = Shrine.class; | ||||
|         this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
|     } | ||||
| 
 | ||||
|     public ArrayList<AbstractGameObject> CREATE_SHRINE( int parentZoneID, int OwnerUUID, String name, int meshUUID, | ||||
|             Vector3fImmutable location, float meshScale, int currentHP, | ||||
|             ProtectionState protectionState, int currentGold, int rank, | ||||
|             DateTime upgradeDate, int blueprintUUID, float w, float rotY, String shrineType) { | ||||
| 
 | ||||
|         prepareCallable("CALL `shrine_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,? ,? ,?, ?,?);"); | ||||
| 
 | ||||
|        | ||||
|         setInt(1, parentZoneID); | ||||
|         setInt(2, OwnerUUID); | ||||
|         setString(3, name); | ||||
|         setInt(4, meshUUID); | ||||
|         setFloat(5, location.x); | ||||
|         setFloat(6, location.y); | ||||
|         setFloat(7, location.z); | ||||
|         setFloat(8, meshScale); | ||||
|         setInt(9, currentHP); | ||||
|         setString(10, protectionState.name()); | ||||
|         setInt(11, currentGold); | ||||
|         setInt(12, rank); | ||||
| 
 | ||||
|         if (upgradeDate != null) { | ||||
|             setTimeStamp(13, upgradeDate.getMillis()); | ||||
|         } else { | ||||
|             setNULL(13, java.sql.Types.DATE); | ||||
|         } | ||||
| 
 | ||||
|         setInt(14, blueprintUUID); | ||||
|         setFloat(15, w); | ||||
|         setFloat(16, rotY); | ||||
|         setString(17, shrineType); | ||||
| 
 | ||||
|         ArrayList<AbstractGameObject> list = new ArrayList<>(); | ||||
|         //System.out.println(this.cs.get().toString());
 | ||||
|         try { | ||||
|             boolean work = execute(); | ||||
|             if (work) { | ||||
|                 ResultSet rs = this.cs.get().getResultSet(); | ||||
|                 while (rs.next()) { | ||||
|                     addObject(list, rs); | ||||
|                 } | ||||
|                 rs.close(); | ||||
|             } else { | ||||
|                 Logger.info("Shrine Creation Failed: " + this.cs.get().toString()); | ||||
|                 return list; //city creation failure
 | ||||
|             } | ||||
|             while (this.cs.get().getMoreResults()) { | ||||
|                 ResultSet rs = this.cs.get().getResultSet(); | ||||
|                 while (rs.next()) { | ||||
|                     addObject(list, rs); | ||||
|                 } | ||||
|                 rs.close(); | ||||
|             } | ||||
|         } catch (SQLException e) { | ||||
|             Logger.info("Shrine Creation Failed, SQLException: " + this.cs.get().toString() + e.toString()); | ||||
|             return list; //city creation failure
 | ||||
|         } catch (UnknownHostException e) { | ||||
|             Logger.info("Shrine Creation Failed, UnknownHostException: " + this.cs.get().toString()); | ||||
|             return list; //city creation failure
 | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
|         return list; | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
|     public boolean updateFavors(Shrine shrine, int amount, int oldAmount) { | ||||
| 
 | ||||
|         prepareCallable("UPDATE `obj_shrine` SET `shrine_favors`=? WHERE `UID` = ? AND `shrine_favors` = ?"); | ||||
|         setInt(1, amount); | ||||
|         setLong(2, (long) shrine.getObjectUUID()); | ||||
|         setInt(3, oldAmount); | ||||
|         return (executeUpdate() != 0); | ||||
|     } | ||||
| 
 | ||||
|     public static void addObject(ArrayList<AbstractGameObject> list, ResultSet rs) throws SQLException, UnknownHostException { | ||||
|         String type = rs.getString("type"); | ||||
|         switch (type) { | ||||
|             case "building": | ||||
|                 Building building = new Building(rs); | ||||
|                 DbManager.addToCache(building); | ||||
|                 list.add(building); | ||||
|                 break; | ||||
|             case "shrine": | ||||
|                 Shrine shrine = new Shrine(rs); | ||||
|                 DbManager.addToCache(shrine); | ||||
|                 list.add(shrine); | ||||
|                 break; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void LOAD_ALL_SHRINES() { | ||||
| 
 | ||||
|         Shrine thisShrine; | ||||
| 
 | ||||
|         prepareCallable("SELECT `obj_shrine`.*, `object`.`parent`, `object`.`type` FROM `object` LEFT JOIN `obj_shrine` ON `object`.`UID` = `obj_shrine`.`UID` WHERE `object`.`type` = 'shrine';"); | ||||
| 
 | ||||
|         try { | ||||
|             ResultSet rs = executeQuery(); | ||||
| 
 | ||||
|             //shrines cached in rs for easy cache on creation.
 | ||||
|             while (rs.next()) { | ||||
|                 thisShrine = new Shrine(rs); | ||||
|                 thisShrine.getShrineType().addShrineToServerList(thisShrine); | ||||
|             } | ||||
| 
 | ||||
|         } catch (SQLException e) { | ||||
|             Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
|         } finally { | ||||
|             closeCallable(); | ||||
|         } | ||||
| 
 | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,143 @@@@ -0,0 +1,143 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.MaxSkills; | ||||
| import engine.objects.SkillsBase; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| 
 | ||||
| public class dbSkillBaseHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbSkillBaseHandler() { | ||||
| 		this.localClass = SkillsBase.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public SkillsBase GET_BASE(final int objectUUID) { | ||||
| 
 | ||||
| 		SkillsBase skillsBase = (SkillsBase) DbManager.getFromCache(GameObjectType.SkillsBase, objectUUID); | ||||
| 		if (skillsBase != null) | ||||
| 			return skillsBase; | ||||
| 		prepareCallable("SELECT * FROM static_skill_skillsbase WHERE ID = ?"); | ||||
| 		setInt(1, objectUUID); | ||||
| 		SkillsBase sb; | ||||
| 		sb = (SkillsBase) getObjectSingle(objectUUID); | ||||
| 		SkillsBase.putInCache(sb); | ||||
| 		return sb; | ||||
| 	} | ||||
| 
 | ||||
| 	public SkillsBase GET_BASE_BY_NAME(String name) { | ||||
| 		SkillsBase sb = SkillsBase.getFromCache(name); | ||||
| 		if (sb != null) { | ||||
| 			return sb; | ||||
| 		} | ||||
| 		prepareCallable("SELECT * FROM static_skill_skillsbase WHERE name = ?"); | ||||
| 		setString(1, name); | ||||
| 		ArrayList<AbstractGameObject> result = getObjectList(); | ||||
| 		if (result.size() > 0) { | ||||
| 			sb = (SkillsBase) result.get(0); | ||||
| 			SkillsBase.putInCache(sb); | ||||
| 			return sb; | ||||
| 		} else { | ||||
| 			return null; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public SkillsBase GET_BASE_BY_TOKEN(final int token) { | ||||
| 		SkillsBase sb = SkillsBase.getFromCache(token); | ||||
| 		if (sb != null) { | ||||
| 			return sb; | ||||
| 		} | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_skill_skillsbase WHERE token = ?"); | ||||
| 		setInt(1, token); | ||||
| 		ArrayList<AbstractGameObject> result = getObjectList(); | ||||
| 		if (result.size() > 0) { | ||||
| 			sb = (SkillsBase) result.get(0); | ||||
| 			SkillsBase.putInCache(sb); | ||||
| 			return sb; | ||||
| 		} else { | ||||
| 			return null; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_ALL_MAX_SKILLS_FOR_CONTRACT() { | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `static_rune_maxskills`"); | ||||
| 
 | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				MaxSkills maxSKills = new MaxSkills(rs); | ||||
| 				if (MaxSkills.MaxSkillsSet.get(maxSKills.getRuneID()) == null){ | ||||
| 					ArrayList<MaxSkills> newMaxSkillsList = new ArrayList<>(); | ||||
| 					newMaxSkillsList.add(maxSKills); | ||||
| 					MaxSkills.MaxSkillsSet.put(maxSKills.getRuneID(), newMaxSkillsList); | ||||
| 				}else | ||||
| 					MaxSkills.MaxSkillsSet.get(maxSKills.getRuneID()).add(maxSKills); | ||||
| 
 | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 	 | ||||
| 	public void LOAD_ALL_RUNE_SKILLS() { | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `static_skill_skillsgranted`"); | ||||
| 
 | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				int runeID = rs.getInt("runeID"); | ||||
| 				int token = rs.getInt("token"); | ||||
| 				int amount = rs.getInt("amount"); | ||||
| 				 | ||||
| 				if (SkillsBase.runeSkillsCache.get(runeID) == null) | ||||
| 					SkillsBase.runeSkillsCache.put(runeID, new HashMap<>()); | ||||
| 				 | ||||
| 				SkillsBase.runeSkillsCache.get(runeID).put(token, amount); | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,35 @@@@ -0,0 +1,35 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.SkillReq; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbSkillReqHandler extends dbHandlerBase { | ||||
| 
 | ||||
|     public dbSkillReqHandler() { | ||||
|         this.localClass = SkillReq.class; | ||||
|         this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
|     } | ||||
| 
 | ||||
|     public ArrayList<SkillReq> GET_REQS_FOR_RUNE(final int objectUUID) { | ||||
|         prepareCallable("SELECT * FROM `static_skill_skillreq` WHERE `runeID`=?"); | ||||
|         setInt(1, objectUUID); | ||||
|         return getObjectList(); | ||||
|     } | ||||
|      | ||||
|     public SkillReq GET_REQS_BY_SKILLID(int skillID) { | ||||
|         prepareCallable("SELECT * FROM `static_skill_skillreq` WHERE `skillID` = ?"); | ||||
|         setInt(1,skillID); | ||||
|         int objectUUID = (int) getUUID(); | ||||
|         return (SkillReq) this.getObjectSingle(objectUUID); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,75 @@@@ -0,0 +1,75 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.objects.SpecialLoot; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| 
 | ||||
| public class dbSpecialLootHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbSpecialLootHandler() { | ||||
| 		this.localClass = SpecialLoot.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<SpecialLoot> GET_SPECIALLOOT(int mobbaseID) { | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM `static_npc_mob_specialloot` WHERE `mobbaseID`=?"); | ||||
| 		setInt(1, mobbaseID); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public void GenerateSpecialLoot(){ | ||||
| 		HashMap<Integer, ArrayList<SpecialLoot>> lootSets; | ||||
| 		SpecialLoot lootSetEntry; | ||||
| 		int	lootSetID; | ||||
| 
 | ||||
| 		lootSets = new HashMap<>(); | ||||
| 		int recordsRead = 0; | ||||
| 
 | ||||
| 		prepareCallable("SELECT * FROM static_zone_npc_specialloot"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			while (rs.next()) { | ||||
| 
 | ||||
| 				recordsRead++; | ||||
| 
 | ||||
| 				lootSetID = rs.getInt("lootSet"); | ||||
| 				lootSetEntry = new SpecialLoot(rs,true); | ||||
| 
 | ||||
| 				if (lootSets.get(lootSetID) == null){ | ||||
| 					ArrayList<SpecialLoot> lootList = new ArrayList<>(); | ||||
| 					lootList.add(lootSetEntry); | ||||
| 					lootSets.put(lootSetID, lootList); | ||||
| 				} | ||||
| 				else{ | ||||
| 					ArrayList<SpecialLoot>lootList = lootSets.get(lootSetID); | ||||
| 					lootList.add(lootSetEntry); | ||||
| 					lootSets.put(lootSetID, lootList); | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 			Logger.info( "read: " + recordsRead + " cached: " + lootSets.size()); | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		SpecialLoot.LootMap = lootSets; | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,31 @@@@ -0,0 +1,31 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.VendorDialog; | ||||
| 
 | ||||
| public class dbVendorDialogHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbVendorDialogHandler() { | ||||
| 		this.localClass = VendorDialog.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public VendorDialog GET_VENDORDIALOG(final int objectUUID) { | ||||
| 		VendorDialog vd = (VendorDialog) DbManager.getFromCache(Enum.GameObjectType.VendorDialog, objectUUID); | ||||
| 		if (vd != null) | ||||
| 			return vd; | ||||
| 		prepareCallable("SELECT * FROM `static_npc_vendordialog` WHERE `ID`=?"); | ||||
| 		setInt(1, objectUUID); | ||||
| 		return (VendorDialog) getObjectSingle(objectUUID); | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,449 @@@@ -0,0 +1,449 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.Enum.ProtectionState; | ||||
| import engine.Enum.TransactionType; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| import org.joda.time.DateTime; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.net.UnknownHostException; | ||||
| import java.sql.ResultSet; | ||||
| import java.sql.SQLException; | ||||
| import java.util.ArrayList; | ||||
| import java.util.concurrent.ConcurrentHashMap; | ||||
| 
 | ||||
| public class dbWarehouseHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	private static final ConcurrentHashMap<Integer, String> columns = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); | ||||
| 
 | ||||
| 	public dbWarehouseHandler() { | ||||
| 		this.localClass = Warehouse.class; | ||||
| 		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 
 | ||||
| 		if (columns.isEmpty()) { | ||||
| 			createColumns(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public Warehouse CREATE_WAREHOUSE(Warehouse wh) { | ||||
| 		try { | ||||
| 			wh = this.addWarehouse(wh); | ||||
| 		} catch (Exception e) { | ||||
| 			Logger.error(e); | ||||
| 			wh = null; | ||||
| 			 | ||||
| 		} | ||||
| 		return wh; | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<AbstractGameObject> CREATE_WAREHOUSE( int parentZoneID, int OwnerUUID, String name, int meshUUID, | ||||
| 			Vector3fImmutable location, float meshScale, int currentHP, | ||||
| 			ProtectionState protectionState, int currentGold, int rank, | ||||
| 			DateTime upgradeDate, int blueprintUUID, float w, float rotY) { | ||||
| 
 | ||||
| 		prepareCallable("CALL `WAREHOUSE_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,? ,? ,?, ?);"); | ||||
| 
 | ||||
| 		setInt(1, parentZoneID); | ||||
| 		setInt(2, OwnerUUID); | ||||
| 		setString(3, name); | ||||
| 		setInt(4, meshUUID); | ||||
| 		setFloat(5, location.x); | ||||
| 		setFloat(6, location.y); | ||||
| 		setFloat(7, location.z); | ||||
| 		setFloat(8, meshScale); | ||||
| 		setInt(9, currentHP); | ||||
| 		setString(10, protectionState.name()); | ||||
| 		setInt(11, currentGold); | ||||
| 		setInt(12, rank); | ||||
| 
 | ||||
| 		if (upgradeDate != null) { | ||||
| 			setTimeStamp(13, upgradeDate.getMillis()); | ||||
| 		} else { | ||||
| 			setNULL(13, java.sql.Types.DATE); | ||||
| 		} | ||||
| 
 | ||||
| 		setInt(14, blueprintUUID); | ||||
| 		setFloat(15, w); | ||||
| 		setFloat(16, rotY); | ||||
| 
 | ||||
| 		ArrayList<AbstractGameObject> list = new ArrayList<>(); | ||||
| 		//System.out.println(this.cs.get().toString());
 | ||||
| 		try { | ||||
| 			boolean work = execute(); | ||||
| 			if (work) { | ||||
| 				ResultSet rs = this.cs.get().getResultSet(); | ||||
| 				while (rs.next()) { | ||||
| 					addObject(list, rs); | ||||
| 				} | ||||
| 				rs.close(); | ||||
| 			} else { | ||||
| 				Logger.info("Warehouse Creation Failed: " + this.cs.get().toString()); | ||||
| 				return list; //city creation failure
 | ||||
| 			} | ||||
| 			while (this.cs.get().getMoreResults()) { | ||||
| 				ResultSet rs = this.cs.get().getResultSet(); | ||||
| 				while (rs.next()) { | ||||
| 					addObject(list, rs); | ||||
| 				} | ||||
| 				rs.close(); | ||||
| 			} | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.info("Warehouse Creation Failed, SQLException: " + this.cs.get().toString() + e.toString()); | ||||
| 			return list; //city creation failure
 | ||||
| 		} catch (UnknownHostException e) { | ||||
| 			Logger.info("Warehouse Creation Failed, UnknownHostException: " + this.cs.get().toString()); | ||||
| 			return list; //city creation failure
 | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return list; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	//Don't call yet, not ready in DB. -
 | ||||
| 	public boolean WAREHOUSE_ADD(Item item, Warehouse warehouse, ItemBase ib, int amount) { | ||||
| 		if (item == null || warehouse == null || ib == null || !(dbWarehouseHandler.columns.containsKey(ib.getUUID()))) { | ||||
| 			return false; | ||||
| 		} | ||||
| 		if ((item.getNumOfItems() - amount) < 0) { | ||||
| 			return false; | ||||
| 		} | ||||
| 		if (!warehouse.getResources().containsKey(ib)) { | ||||
| 			return false; | ||||
| 		} | ||||
| 
 | ||||
| 		prepareCallable("CALL `warehouse_ADD`(?,?,?,?,?,?,?);"); | ||||
| 		setLong(1, (long) warehouse.getObjectUUID()); | ||||
| 		setInt(2, warehouse.getResources().get(ib)); | ||||
| 		setLong(3, (long) item.getObjectUUID()); | ||||
| 		setInt(4, item.getNumOfItems()); | ||||
| 		setInt(5, amount); | ||||
| 		setString(6, dbWarehouseHandler.columns.get(ib.getUUID())); | ||||
| 		setInt(7, ib.getUUID()); | ||||
| 		String result = getResult(); | ||||
| 
 | ||||
| 		return (result != null && result.equals("success")); | ||||
| 	} | ||||
| 
 | ||||
| 	private Warehouse addWarehouse(Warehouse toAdd) { | ||||
| 		prepareCallable("CALL `warehouse_CREATE`(?);"); | ||||
| 		setInt(1, toAdd.getUID()); | ||||
| 		int objectUUID = (int) getUUID(); | ||||
| 		if (objectUUID > 0) { | ||||
| 			return GET_WAREHOUSE(objectUUID); | ||||
| 		} | ||||
| 		return null; | ||||
| 	} | ||||
| 
 | ||||
| 	public Warehouse GET_WAREHOUSE(int objectUUID) { | ||||
| 		Warehouse warehouse = (Warehouse) DbManager.getFromCache(GameObjectType.Warehouse, objectUUID); | ||||
| 		if (warehouse != null) | ||||
| 			return warehouse; | ||||
| 		prepareCallable("SELECT * FROM `obj_warehouse` WHERE `UID` = ?"); | ||||
| 		setInt(1, objectUUID); | ||||
| 		return (Warehouse) getObjectSingle(objectUUID); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateLocks(final Warehouse wh, long locks) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_locks`=? WHERE `UID` = ?"); | ||||
| 		setLong(1, locks); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateGold(final Warehouse wh, int amount ) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_gold`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateStone(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_stone`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateTruesteel(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_truesteel`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateIron(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_iron`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateAdamant(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_adamant`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateLumber(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_lumber`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateOak(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_oak`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateBronzewood(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_bronzewood`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateMandrake(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_mandrake`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateCoal(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_coal`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateAgate(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_agate`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateDiamond(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_diamond`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateOnyx(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_onyx`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateAzoth(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_azoth`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateOrichalk(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_orichalk`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateAntimony(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_antimony`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateSulfur(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_sulfur`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateQuicksilver(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_quicksilver`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateGalvor(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_galvor`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateWormwood(final Warehouse wh, int amount ) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_wormwood`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateObsidian(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_obsidian`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateBloodstone(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_bloodstone`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean updateMithril(final Warehouse wh, int amount) { | ||||
| 		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_mithril`=? WHERE `UID` = ?"); | ||||
| 		setInt(1, amount); | ||||
| 		setInt(2, wh.getUID()); | ||||
| 
 | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 	private static void createColumns() { | ||||
| 		columns.put(1580000, "warehouse_stone"); | ||||
| 		columns.put(1580001, "warehouse_truesteel"); | ||||
| 		columns.put(1580002, "warehouse_iron"); | ||||
| 		columns.put(1580003, "warehouse_adamant"); | ||||
| 		columns.put(1580004, "warehouse_lumber"); | ||||
| 		columns.put(1580005, "warehouse_oak"); | ||||
| 		columns.put(1580006, "warehouse_bronzewood"); | ||||
| 		columns.put(1580007, "warehouse_mandrake"); | ||||
| 		columns.put(1580008, "warehouse_coal"); | ||||
| 		columns.put(1580009, "warehouse_agate"); | ||||
| 		columns.put(1580010, "warehouse_diamond"); | ||||
| 		columns.put(1580011, "warehouse_onyx"); | ||||
| 		columns.put(1580012, "warehouse_azoth"); | ||||
| 		columns.put(1580013, "warehouse_orichalk"); | ||||
| 		columns.put(1580014, "warehouse_antimony"); | ||||
| 		columns.put(1580015, "warehouse_sulfur"); | ||||
| 		columns.put(1580016, "warehouse_quicksilver"); | ||||
| 		columns.put(1580017, "warehouse_galvor"); | ||||
| 		columns.put(1580018, "warehouse_wormwood"); | ||||
| 		columns.put(1580019, "warehouse_obsidian"); | ||||
| 		columns.put(1580020, "warehouse_bloodstone"); | ||||
| 		columns.put(1580021, "warehouse_mithril"); | ||||
| 		columns.put(7, "warehouse_gold"); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean CREATE_TRANSACTION(int warehouseBuildingID, GameObjectType targetType, int targetUUID, TransactionType transactionType,Resource resource, int amount,DateTime date){ | ||||
| 		Transaction transactions = null; | ||||
| 		prepareCallable("INSERT INTO `dyn_warehouse_transactions` (`warehouseUID`, `targetType`,`targetUID`, `type`,`resource`,`amount`,`date` ) VALUES (?,?,?,?,?,?,?)"); | ||||
| 		setLong(1, warehouseBuildingID); | ||||
| 		setString(2, targetType.name()); | ||||
| 		setLong(3, targetUUID); | ||||
| 		setString(4, transactionType.name()); | ||||
| 		setString(5, resource.name()); | ||||
| 		setInt(6,amount); | ||||
| 		setTimeStamp(7,date.getMillis()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	public static void addObject(ArrayList<AbstractGameObject> list, ResultSet rs) throws SQLException, UnknownHostException { | ||||
| 		String type = rs.getString("type"); | ||||
| 		switch (type) { | ||||
| 		case "building": | ||||
| 			Building building = new Building(rs); | ||||
| 			DbManager.addToCache(building); | ||||
| 			list.add(building); | ||||
| 			break; | ||||
| 		case "warehouse": | ||||
| 			Warehouse warehouse = new Warehouse(rs); | ||||
| 			DbManager.addToCache(warehouse); | ||||
| 			list.add(warehouse); | ||||
| 			break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Transaction> GET_TRANSACTIONS_FOR_WAREHOUSE(final int warehouseUUID) { | ||||
| 		ArrayList<Transaction> transactionsList = new ArrayList<>(); | ||||
| 		prepareCallable("SELECT * FROM dyn_warehouse_transactions WHERE `warehouseUID` = ?;"); | ||||
| 		setInt(1, warehouseUUID); | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 
 | ||||
| 			//shrines cached in rs for easy cache on creation.
 | ||||
| 			while (rs.next()) { | ||||
| 				Transaction transactions = new Transaction(rs); | ||||
| 				transactionsList.add(transactions); | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 		return transactionsList; | ||||
| 	} | ||||
| 
 | ||||
| 	public void LOAD_ALL_WAREHOUSES() { | ||||
| 
 | ||||
| 		Warehouse thisWarehouse; | ||||
| 
 | ||||
| 		prepareCallable("SELECT `obj_warehouse`.*, `object`.`parent`, `object`.`type` FROM `object` LEFT JOIN `obj_warehouse` ON `object`.`UID` = `obj_warehouse`.`UID` WHERE `object`.`type` = 'warehouse';"); | ||||
| 
 | ||||
| 		try { | ||||
| 			ResultSet rs = executeQuery(); | ||||
| 			while (rs.next()) { | ||||
| 				thisWarehouse = new Warehouse(rs); | ||||
| 				thisWarehouse.runAfterLoad(); | ||||
| 				thisWarehouse.loadAllTransactions(); | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (SQLException e) { | ||||
| 			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | ||||
| 		} finally { | ||||
| 			closeCallable(); | ||||
| 		} | ||||
| 
 | ||||
| 	} | ||||
| } | ||||
| @ -0,0 +1,93 @@@@ -0,0 +1,93 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.db.handlers; | ||||
| 
 | ||||
| import engine.Enum; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.Zone; | ||||
| 
 | ||||
| import java.sql.ResultSet; | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public class dbZoneHandler extends dbHandlerBase { | ||||
| 
 | ||||
| 	public dbZoneHandler() { | ||||
| 		this.localClass = Zone.class; | ||||
| 		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Zone> GET_ALL_NODES(Zone zone) { | ||||
| 		ArrayList<Zone> wsmList = new ArrayList<>(); | ||||
| 		wsmList.addAll(zone.getNodes()); | ||||
| 		if (zone.absX == 0.0f) { | ||||
| 			zone.absX = zone.getXCoord(); | ||||
| 		} | ||||
| 		if (zone.absY == 0.0f) { | ||||
| 			zone.absY = zone.getYCoord(); | ||||
| 		} | ||||
| 		if (zone.absZ == 0.0f) { | ||||
| 			zone.absZ = zone.getZCoord(); | ||||
| 		} | ||||
| 		for (Zone child : zone.getNodes()) { | ||||
| 			child.absX = child.getXCoord() + zone.absX; | ||||
| 			child.absY = child.getYCoord() + zone.absY; | ||||
| 			child.absZ = child.getZCoord() + zone.absZ; | ||||
| 			wsmList.addAll(this.GET_ALL_NODES(child)); | ||||
| 		} | ||||
| 		return wsmList; | ||||
| 	} | ||||
| 
 | ||||
| 	public Zone GET_BY_UID(long ID) { | ||||
| 
 | ||||
| 		Zone zone = (Zone) DbManager.getFromCache(Enum.GameObjectType.Zone, (int)ID); | ||||
| 		if (zone != null) | ||||
| 			return zone; | ||||
| 		prepareCallable("SELECT `obj_zone`.*, `object`.`parent` FROM `object` INNER JOIN `obj_zone` ON `obj_zone`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?;"); | ||||
| 		setLong(1, ID); | ||||
| 		return (Zone) getObjectSingle((int) ID); | ||||
| 	} | ||||
| 
 | ||||
| 	public ArrayList<Zone> GET_MAP_NODES(final int objectUUID) { | ||||
| 		prepareCallable("SELECT `obj_zone`.*, `object`.`parent` FROM `object` INNER JOIN `obj_zone` ON `obj_zone`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;"); | ||||
| 		setLong(1, (long) objectUUID); | ||||
| 		return getObjectList(); | ||||
| 	} | ||||
| 
 | ||||
| 	public ResultSet GET_ZONE_EXTENTS(final int loadNum) { | ||||
| 		prepareCallable("SELECT * FROM `static_zone_size` WHERE `loadNum`=?;"); | ||||
| 		setInt(1, loadNum); | ||||
| 		return executeQuery(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Zone z, String name, Object new_value) { | ||||
| 		prepareCallable("CALL zone_SETPROP(?,?,?)"); | ||||
| 		setLong(1, (long) z.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public String SET_PROPERTY(final Zone z, String name, Object new_value, Object old_value) { | ||||
| 		prepareCallable("CALL zone_GETSETPROP(?,?,?,?)"); | ||||
| 		setLong(1, (long) z.getObjectUUID()); | ||||
| 		setString(2, name); | ||||
| 		setString(3, String.valueOf(new_value)); | ||||
| 		setString(4, String.valueOf(old_value)); | ||||
| 		return getResult(); | ||||
| 	} | ||||
| 
 | ||||
| 	public boolean DELETE_ZONE(final Zone zone) { | ||||
| 
 | ||||
| 		prepareCallable("DELETE FROM `object` WHERE `UID` = ? AND `type` = 'zone'"); | ||||
| 		setInt(1, zone.getObjectUUID()); | ||||
| 		return (executeUpdate() != 0); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,181 @@@@ -0,0 +1,181 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd; | ||||
| 
 | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.gameManager.ChatManager; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.*; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| public abstract class AbstractDevCmd { | ||||
| 
 | ||||
|     protected final ArrayList<String> cmdStrings; | ||||
|     private AbstractGameObject tr; | ||||
|     private String rsult; | ||||
| 
 | ||||
|     public AbstractDevCmd(String cmdString) { | ||||
|         super(); | ||||
|         this.cmdStrings = new ArrayList<>(); | ||||
|         this.addCmdString(cmdString); | ||||
|         this.rsult = ""; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * This function is called by the DevCmdManager. Method splits argString | ||||
|      * into a String array and then calls the subclass specific _doCmd method. | ||||
|      */ | ||||
| 
 | ||||
|     public void doCmd(PlayerCharacter pcSender, String argString, | ||||
|             AbstractGameObject target) { | ||||
|         String[] args = argString.split(" "); | ||||
| 
 | ||||
|         if (pcSender == null) { | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         if (args.length > 0 && args[0].equalsIgnoreCase("?")) { | ||||
|             this.sendHelp(pcSender); | ||||
|             this.sendUsage(pcSender); | ||||
|         } else { | ||||
|             this.tr = target; | ||||
|             this._doCmd(pcSender, args, target); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protected abstract void _doCmd(PlayerCharacter pcSender, String[] args, | ||||
|             AbstractGameObject target); | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the string sent to the client that displays how to use this | ||||
|      * command. | ||||
|      */ | ||||
| 
 | ||||
|     public final String getUsageString() { | ||||
|         return "Usage: " + this._getUsageString(); | ||||
|     } | ||||
| 
 | ||||
|     protected abstract String _getUsageString(); | ||||
| 
 | ||||
|     /** | ||||
|      * Returns the string sent to the client that displays what this command | ||||
|      * does. | ||||
|      */ | ||||
| 
 | ||||
|     public final String getHelpString() { | ||||
|         return this.getMainCmdString() + ": " + this._getHelpString(); | ||||
|     } | ||||
| 
 | ||||
|     protected abstract String _getHelpString(); | ||||
| 
 | ||||
|     public final ArrayList<String> getCmdStrings() { | ||||
|         return cmdStrings; | ||||
|     } | ||||
| 
 | ||||
|     public final String getMainCmdString() { | ||||
|         return this.cmdStrings.get(0); | ||||
|     } | ||||
| 
 | ||||
|     protected void addCmdString(String cmdString) { | ||||
|         String lowercase = cmdString.toLowerCase(); | ||||
|         this.cmdStrings.add(lowercase); | ||||
|     } | ||||
| 
 | ||||
|     public void setTarget(AbstractGameObject ago) { | ||||
|         this.tr = ago; | ||||
|     } | ||||
| 
 | ||||
|     public AbstractGameObject getTarget() { | ||||
|         return this.tr; | ||||
|     } | ||||
| 
 | ||||
|     public void setResult(String result) { | ||||
|         this.rsult = result; | ||||
|     } | ||||
| 
 | ||||
|     public String getResult() { | ||||
|         return this.rsult; | ||||
|     } | ||||
| 
 | ||||
|     /* | ||||
|      * Helper functions | ||||
|      */ | ||||
|     protected void sendUsage(PlayerCharacter pc) { | ||||
|         this.throwbackError(pc, this.getUsageString()); | ||||
|     } | ||||
| 
 | ||||
|     protected void sendHelp(PlayerCharacter pc) { | ||||
|         this.throwbackError(pc, this.getHelpString()); | ||||
|     } | ||||
| 
 | ||||
|     protected void throwbackError(PlayerCharacter pc, String msgText) { | ||||
|         ChatManager.chatSystemError(pc, msgText); | ||||
|     } | ||||
| 
 | ||||
|     protected void throwbackInfo(PlayerCharacter pc, String msgText) { | ||||
|         ChatManager.chatSystemInfo(pc, msgText); | ||||
|     } | ||||
| 
 | ||||
|     /* | ||||
|      * Misc tools/helpers | ||||
|      */ | ||||
|     protected static Building getTargetAsBuilding(PlayerCharacter pc) { | ||||
|         int targetType = pc.getLastTargetType().ordinal(); | ||||
|         int targetID = pc.getLastTargetID(); | ||||
|         if (targetType == GameObjectType.Building.ordinal()) { | ||||
|             Building b = (Building) DbManager | ||||
|                     .getFromCache(GameObjectType.Building, targetID); | ||||
|             if (b == null) { | ||||
|                 ChatManager.chatSystemError( | ||||
|                         pc, | ||||
|                         "Command Failed. Could not find building of ID " | ||||
|                         + targetID); | ||||
|                 return null; | ||||
|             } | ||||
|             return b; | ||||
|         } else { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protected static Mob getTargetAsMob(PlayerCharacter pc) { | ||||
|         int targetType = pc.getLastTargetType().ordinal(); | ||||
|         int targetID = pc.getLastTargetID(); | ||||
|         if (targetType == GameObjectType.Mob.ordinal()) { | ||||
|             Mob b = Mob.getMob(targetID); | ||||
|             if (b == null) { | ||||
|                 ChatManager.chatSystemError(pc, | ||||
|                         "Command Failed. Could not find Mob of ID " + targetID); | ||||
|                 return null; | ||||
|             } | ||||
|             return b; | ||||
|         } else { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     protected static NPC getTargetAsNPC(PlayerCharacter pc) { | ||||
|         int targetType = pc.getLastTargetType().ordinal(); | ||||
|         int targetID = pc.getLastTargetID(); | ||||
|         if (targetType == GameObjectType.NPC.ordinal()) { | ||||
|             NPC b = NPC.getFromCache(targetID); | ||||
|             if (b == null) { | ||||
|                 ChatManager.chatSystemError(pc, | ||||
|                         "Command Failed. Could not find NPC of ID " + targetID); | ||||
|                 return null; | ||||
|             } | ||||
|             return b; | ||||
|         } else { | ||||
|             return null; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,127 @@@@ -0,0 +1,127 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.Enum.ProtectionState; | ||||
| import engine.InterestManagement.WorldGrid; | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.ChatManager; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.gameManager.ZoneManager; | ||||
| import engine.math.Vector3f; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.*; | ||||
| import engine.server.MBServerStatics; | ||||
| 
 | ||||
| public class AddBuildingCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public AddBuildingCmd() { | ||||
|         super("addbuilding"); | ||||
| //		super("addbuilding", MBServerStatics.ACCESS_GROUP_DESIGNER_UP, 0, false, true);
 | ||||
|         this.addCmdString("building"); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pc, String[] words, | ||||
| 			AbstractGameObject target) { | ||||
| 
 | ||||
| 		// Arg Count Check
 | ||||
| 		if (words.length != 2) { | ||||
| 			this.sendUsage(pc); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		int ID; | ||||
| 		int rank; | ||||
|                 Blueprint blueprint; | ||||
|                  | ||||
| 		try { | ||||
| 			ID = Integer.parseInt(words[0]); | ||||
| 			rank = Integer.parseInt(words[1]); | ||||
| 		} catch (Exception e) { | ||||
| 			throwbackError(pc, "Invalid addBuilding Command. Need Building ID and rank."); | ||||
| 			return; // NaN
 | ||||
| 		} | ||||
| 		if (ID < 1) { | ||||
| 			throwbackError(pc, | ||||
| 					"Invalid addBuilding Command. Invalid Building ID."); | ||||
| 			return; | ||||
| 		} | ||||
| 		Vector3f rot = new Vector3f(0.0f, 0.0f, 0.0f); | ||||
| 		float w = 1f; | ||||
| 		Zone zone = ZoneManager.findSmallestZone(pc.getLoc()); | ||||
| 
 | ||||
| 		if (zone == null) { | ||||
| 			throwbackError(pc, "Failed to find zone to place building in."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
|                blueprint = Blueprint.getBlueprint(ID); | ||||
|                 | ||||
|                if ((blueprint != null) && (rank > blueprint.getMaxRank())) { | ||||
|                    throwbackError(pc, rank + " is not a valid rank for this building"); | ||||
| 			return; | ||||
|                } | ||||
| 		 | ||||
| 		Building likeBuilding = DbManager.BuildingQueries.GET_BUILDING_BY_MESH(ID); | ||||
|                  | ||||
| 		if (likeBuilding != null) { | ||||
| 			rot = likeBuilding.getRot(); | ||||
| 			w = likeBuilding.getw(); | ||||
| 		} | ||||
|                  | ||||
|                 String buildingName = ""; | ||||
|                 int blueprintUUID = 0; | ||||
|                  | ||||
|                 Vector3fImmutable localLoc = ZoneManager.worldToLocal(pc.getLoc(), zone); | ||||
|                  | ||||
|                 if (localLoc == null) | ||||
|                 	return; | ||||
|                  | ||||
|                 if (blueprint != null) { | ||||
|                  buildingName = blueprint.getName(); | ||||
|                  blueprintUUID = blueprint.getBlueprintUUID(); | ||||
|                  } | ||||
|                   | ||||
|                 Building building = DbManager.BuildingQueries. | ||||
|                         CREATE_BUILDING( | ||||
|                                    zone.getObjectUUID(), 0, buildingName, ID, | ||||
|                                    localLoc, 1.0f, 0, ProtectionState.PROTECTED, 0, rank, | ||||
|                                    null, blueprintUUID, w, rot.y); | ||||
|           | ||||
| 
 | ||||
| 		if (building == null) { | ||||
| 			throwbackError(pc, "Failed to add building."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		building.setRot(rot); | ||||
| 		building.setw(w); | ||||
| 
 | ||||
| 		building.setObjectTypeMask(MBServerStatics.MASK_BUILDING); | ||||
| 	        WorldGrid.addObject(building, pc); | ||||
| 		ChatManager.chatSayInfo(pc, | ||||
| 				"Building with ID " + building.getObjectUUID() + " added"); | ||||
| 
 | ||||
| 		this.setResult(String.valueOf(building.getObjectUUID())); | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
| 		return "Creates a building of type 'buildingID' at the location your character is standing."; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
| 		return "' /addbuilding buildingID rank' || ' /building buildingID rank'"; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,77 @@@@ -0,0 +1,77 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.ChatManager; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.Item; | ||||
| import engine.objects.PlayerCharacter; | ||||
| 
 | ||||
| /** | ||||
|  * @author Eighty | ||||
|  * | ||||
|  */ | ||||
| public class AddGoldCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public AddGoldCmd() { | ||||
|         super("addgold"); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pc, String[] words, | ||||
| 			AbstractGameObject target) { | ||||
| 		if (words.length != 1) { | ||||
| 			this.sendUsage(pc); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		Item gold = pc.getCharItemManager().getGoldInventory(); | ||||
| 		int curAmt; | ||||
| 		if (gold == null) | ||||
| 			curAmt = 0; | ||||
| 		else | ||||
| 			curAmt = gold.getNumOfItems(); | ||||
| 
 | ||||
| 		int amt; | ||||
| 		try { | ||||
| 			amt = Integer.parseInt(words[0]); | ||||
| 		} catch (NumberFormatException e) { | ||||
| 			throwbackError(pc, "Quantity must be a number, " + words[0] + " is invalid"); | ||||
| 			return; | ||||
| 		} | ||||
| 		if (amt < 1 || amt > 10000000) { | ||||
| 			throwbackError(pc, "Quantity must be between 1 and 10000000 (10 million)"); | ||||
| 			return; | ||||
| 		} else if ((curAmt + amt) > 10000000) { | ||||
| 			throwbackError(pc, "This would place your inventory over 10,000,000 gold."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		if (!pc.getCharItemManager().addGoldToInventory(amt, true)) { | ||||
| 			throwbackError(pc, "Failed to add gold to inventory"); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		ChatManager.chatSayInfo(pc, amt + " gold added to inventory"); | ||||
| 		pc.getCharItemManager().updateInventory(); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
|         return "adds gold to inventory"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
|         return "' /addGold quantity'"; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,111 @@@@ -0,0 +1,111 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.ChatManager; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.gameManager.ZoneManager; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.*; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| /** | ||||
|  * @author Eighty | ||||
|  * | ||||
|  */ | ||||
| public class AddMobCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public AddMobCmd() { | ||||
|         super("mob"); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pc, String[] words, | ||||
| 			AbstractGameObject target) { | ||||
| 		if (words.length != 1) { | ||||
| 			this.sendUsage(pc); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		Zone zone = ZoneManager.findSmallestZone(pc.getLoc()); | ||||
| 
 | ||||
| 		if (words[0].equals("all")){ | ||||
| 
 | ||||
| 			for (AbstractGameObject mobbaseAGO: DbManager.getList(GameObjectType.MobBase)){ | ||||
| 				MobBase mb = (MobBase)mobbaseAGO; | ||||
| 				int loadID = mb.getObjectUUID(); | ||||
| 				Mob mob = Mob.createMob( loadID, Vector3fImmutable.getRandomPointInCircle(pc.getLoc(), 100), | ||||
| 						null, true, zone, null,0); | ||||
| 				if (mob != null) { | ||||
| 					mob.updateDatabase(); | ||||
| 					this.setResult(String.valueOf(mob.getDBID())); | ||||
| 				} else { | ||||
| 					throwbackError(pc, "Failed to create mob of type " + loadID); | ||||
| 					Logger.error( "Failed to create mob of type " | ||||
| 							+ loadID); | ||||
| 				} | ||||
| 			} | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 		int loadID; | ||||
| 		try { | ||||
| 			loadID = Integer.parseInt(words[0]); | ||||
| 		} catch (NumberFormatException e) { | ||||
| 			throwbackError(pc, "Supplied type " + words[0] | ||||
| 					+ " failed to parse to an Integer"); | ||||
| 			return; | ||||
| 		} catch (Exception e) { | ||||
| 			throwbackError(pc, | ||||
| 					"An unknown exception occurred when trying to use mob command for type " | ||||
| 							+ words[0]); | ||||
| 			return; // NaN
 | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 		if (zone == null) { | ||||
| 			throwbackError(pc, "Failed to find zone to place mob in."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		if (zone.isPlayerCity()) { | ||||
| 			throwbackError(pc, "Cannot use ./mob on Player cities. Try ./servermob instead."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 		Mob mob = Mob.createMob( loadID, pc.getLoc(), | ||||
| 				null, true, zone, null,0); | ||||
| 		if (mob != null) { | ||||
| 			mob.updateDatabase(); | ||||
| 			ChatManager.chatSayInfo(pc, | ||||
| 					"Mob with ID " + mob.getDBID() + " added"); | ||||
| 			this.setResult(String.valueOf(mob.getDBID())); | ||||
| 		} else { | ||||
| 			throwbackError(pc, "Failed to create mob of type " + loadID); | ||||
| 			Logger.error("Failed to create mob of type " | ||||
| 					+ loadID); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
|         return "Creates a Mob of type 'mobID' at the location your character is standing"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
|         return "' /mob mobID'"; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,98 @@@@ -0,0 +1,98 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.gameManager.PowersManager; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.Mob; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.powers.PowersBase; | ||||
| 
 | ||||
| /** | ||||
|  *  | ||||
|  * @author Eighty | ||||
|  *  | ||||
|  */ | ||||
| public class AddMobPowerCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public AddMobPowerCmd() { | ||||
|         super("addmobpower"); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pcSender, String[] args, | ||||
| 			AbstractGameObject target) { | ||||
| 		 | ||||
| 	 | ||||
| 		if(args.length != 2){ | ||||
| 			this.sendUsage(pcSender); | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 	if (target.getObjectType() != GameObjectType.Mob){ | ||||
| 		this.throwbackError(pcSender, "Target is not a valid Mob."); | ||||
| 		return; | ||||
| 	} | ||||
| 	Mob mobTarget = (Mob)target; | ||||
| 
 | ||||
| 		 | ||||
| 		int rank = 0; | ||||
| 		String idString = args[0]; | ||||
| 		 | ||||
| 		try{ | ||||
| 			rank = Integer.valueOf(args[1]); | ||||
| 		}catch(Exception e){ | ||||
| 			this.throwbackInfo(pcSender, "Failed to Parse an Integer."); | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		PowersBase pb = PowersManager.getPowerByIDString(idString); | ||||
| 		if (pb == null){ | ||||
| 			this.throwbackError(pcSender, "not a valid Effect. IDString is Case Sensitive."); | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		if (!DbManager.MobBaseQueries.ADD_MOBBASE_POWER(mobTarget.getMobBaseID(), pb.getToken(), rank)){ | ||||
| 			this.throwbackError(pcSender, "Failed to update Database"); | ||||
| 		} | ||||
| 		 | ||||
| 		mobTarget.getMobBase().updatePowers(); | ||||
| 		 | ||||
| 		this.throwbackInfo(pcSender, "Successfuly added Power " + pb.getIDString() + " to Mobbase with UID " + mobTarget.getMobBaseID()); | ||||
| 		 | ||||
| 		 | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
|         return "' /addmobpower poweridstring rank"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
|         return "Temporarily add visual effects to Character"; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,98 @@@@ -0,0 +1,98 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.Mob; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.objects.RuneBase; | ||||
| 
 | ||||
| /** | ||||
|  *  | ||||
|  * @author Eighty | ||||
|  *  | ||||
|  */ | ||||
| public class AddMobRuneCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public AddMobRuneCmd() { | ||||
|         super("addmobrune"); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pcSender, String[] args, | ||||
| 			AbstractGameObject target) { | ||||
| 		 | ||||
| 		 | ||||
| 		if(args.length != 1){ | ||||
| 			this.sendUsage(pcSender); | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 	if (target.getObjectType() != GameObjectType.Mob){ | ||||
| 		this.throwbackError(pcSender, "Target is not a valid Mob."); | ||||
| 		return; | ||||
| 	} | ||||
| 	Mob mobTarget = (Mob)target; | ||||
| 
 | ||||
| 		 | ||||
| 		int runeID = 0; | ||||
| 		try{ | ||||
| 			runeID = Integer.valueOf(args[0]); | ||||
| 		}catch(Exception e){ | ||||
| 			this.throwbackInfo(pcSender, "Failed to Parse an Integer."); | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		RuneBase rune = RuneBase.getRuneBase(runeID); | ||||
| 		if (rune == null){ | ||||
| 			this.throwbackError(pcSender, "Invalid Rune ID"); | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		if (!DbManager.MobBaseQueries.ADD_MOBBASE_RUNE(mobTarget.getMobBaseID(), runeID)){ | ||||
| 			this.throwbackError(pcSender, "Failed to update Database"); | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		mobTarget.getMobBase().updateRunes(); | ||||
| 		 | ||||
| 		this.throwbackInfo(pcSender, "Successfuly added rune  " + rune.getName() + " to Mobbase with UID " + mobTarget.getMobBaseID()); | ||||
| 		 | ||||
| 		 | ||||
| 		 | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
|         return "' /visualeffect visualeffectID"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
|         return "Temporarily add visual effects to Character"; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,111 @@@@ -0,0 +1,111 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.InterestManagement.WorldGrid; | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.BuildingManager; | ||||
| import engine.gameManager.ChatManager; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.gameManager.ZoneManager; | ||||
| import engine.objects.*; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| /** | ||||
|  * @author Eighty | ||||
|  * | ||||
|  */ | ||||
| public class AddNPCCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public AddNPCCmd() { | ||||
|         super("npc"); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pc, String[] words, | ||||
| 			AbstractGameObject target) { | ||||
| 		int contractID; | ||||
| 		String name = ""; | ||||
| 		int level = 0; | ||||
| 
 | ||||
| 		if (words.length < 2) { | ||||
| 			this.sendUsage(pc); | ||||
| 			return; | ||||
| 		} | ||||
| 		try { | ||||
| 			contractID = Integer.parseInt(words[0]); | ||||
| 			level = Integer.parseInt(words[1]); | ||||
| 
 | ||||
| 			for (int i = 2; i < words.length; i++) { | ||||
| 				name += words[i]; | ||||
| 				if (i + 1 < words.length) | ||||
| 					name += ""; | ||||
| 			} | ||||
| 
 | ||||
| 		} catch (NumberFormatException e) { | ||||
| 			throwbackError(pc, | ||||
| 					"Failed to parse supplied contractID or level to an Integer."); | ||||
| 			return; // NaN
 | ||||
| 		} | ||||
| 
 | ||||
| 		Contract contract = DbManager.ContractQueries.GET_CONTRACT(contractID); | ||||
| 
 | ||||
| 		if (contract == null || level < 1 || level > 75) { | ||||
| 			throwbackError(pc, | ||||
| 					"Invalid addNPC Command. Need contract ID, and level"); | ||||
| 			return; // NaN
 | ||||
| 		} | ||||
| 
 | ||||
| 		// Pick a random name
 | ||||
| 		if (name.isEmpty()) | ||||
| 			name = NPC.getPirateName(contract.getMobbaseID()); | ||||
| 
 | ||||
| 		Zone zone = ZoneManager.findSmallestZone(pc.getLoc()); | ||||
| 
 | ||||
| 		if (zone == null) { | ||||
| 			throwbackError(pc, "Failed to find zone to place npc in."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		if (target != null) | ||||
| 			if (target.getObjectType() == GameObjectType.Building){ | ||||
| 				Building parentBuilding = (Building)target; | ||||
| 				BuildingManager.addHirelingForWorld(parentBuilding, pc, parentBuilding.getLoc(), parentBuilding.getParentZone(), contract, level); | ||||
| 				return; | ||||
| 			} | ||||
| 
 | ||||
| 		NPC npc = NPC.createNPC(name, contractID, | ||||
| 				pc.getLoc(), null, true, zone, (short)level, true, null); | ||||
| 
 | ||||
| 		if (npc != null) { | ||||
| 			WorldGrid.addObject(npc, pc); | ||||
| 			ChatManager.chatSayInfo(pc, | ||||
| 					"NPC with ID " + npc.getDBID() + " added"); | ||||
| 			this.setResult(String.valueOf(npc.getDBID())); | ||||
| 		} else { | ||||
| 			throwbackError(pc, "Failed to create npc of contract type " | ||||
| 					+ contractID); | ||||
| 			Logger.error( | ||||
| 					"Failed to create npc of contract type " + contractID); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
| 		return "Creates an NPC of type 'npcID' at the location your character is standing"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
| 		return "' /npc npcID level name'"; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,158 @@@@ -0,0 +1,158 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.Enum.PowerActionType; | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.ChatManager; | ||||
| import engine.gameManager.PowersManager; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.powers.ActionsBase; | ||||
| import engine.powers.PowersBase; | ||||
| import engine.powers.effectmodifiers.AbstractEffectModifier; | ||||
| import engine.util.ThreadUtils; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| 
 | ||||
| public class ApplyBonusCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public ApplyBonusCmd() { | ||||
| 		super("applybonus"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pcSender, String[] words, | ||||
| 			AbstractGameObject target) { | ||||
| 		 | ||||
| 		String action = words[0]; | ||||
| 		 | ||||
| 		PowerActionType actionType = null; | ||||
| 		 | ||||
| 		HashMap<String,HashSet<String>> appliedMods = new HashMap<>(); | ||||
| 		 | ||||
| 		try{ | ||||
| 			 | ||||
| 			if (action.equals("all") == false) | ||||
| 		for (PowerActionType powerActionType : PowerActionType.values()){ | ||||
| 			if (powerActionType.name().equalsIgnoreCase(action) == false) | ||||
| 				continue; | ||||
| 			actionType = powerActionType; | ||||
| 			break; | ||||
| 		} | ||||
| 			 | ||||
| 		}catch(Exception e){ | ||||
| 			this.throwbackError(pcSender, "Invalid power Action type for " + action); | ||||
| 			this.throwbackInfo(pcSender, "Valid Types : " + this.getActionTypes()); | ||||
| 			return; | ||||
| 		} | ||||
| 		if (action.equals("all") == false) | ||||
| 		if (actionType == null){ | ||||
| 			this.throwbackError(pcSender, "Invalid power Action type for " + action); | ||||
| 			this.throwbackInfo(pcSender, "Valid Types : " + this.getActionTypes()); | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		 | ||||
| 		for (PowersBase pb : PowersManager.powersBaseByIDString.values()){ | ||||
| 			if (pb.getActions() == null || pb.getActions().isEmpty()) | ||||
| 				continue; | ||||
| 			 | ||||
| 			for (ActionsBase ab: pb.getActions()){ | ||||
| 				if (ab.getPowerAction() == null) | ||||
| 					continue; | ||||
| 				if (action.equals("all") == false) | ||||
| 				if (ab.getPowerAction().getType().equalsIgnoreCase(action) == false) | ||||
| 					continue; | ||||
| 				String effect1 = ""; | ||||
| 				String effect2 = ""; | ||||
| 				ChatManager.chatSystemInfo(pcSender,"Applying Power " + pb.getName() + " : " +pb.getDescription()); | ||||
| 				if (ab.getPowerAction().getEffectsBase() == null){ | ||||
| 					 | ||||
| 					try { | ||||
| 						PowersManager.runPowerAction(pcSender, pcSender, pcSender.getLoc(), ab, 1, pb); | ||||
| 					} catch (Exception e) { | ||||
| 						// TODO Auto-generated catch block
 | ||||
| 						e.printStackTrace(); | ||||
| 					} | ||||
| 					ThreadUtils.sleep(500); | ||||
| 					continue; | ||||
| 				} | ||||
| 
 | ||||
| 			 | ||||
| 					if (ab.getPowerAction().getEffectsBase().getModifiers() == null || ab.getPowerAction().getEffectsBase().getModifiers().isEmpty()){ | ||||
| 						try { | ||||
| 							PowersManager.runPowerAction(pcSender, pcSender, pcSender.getLoc(), ab, 1, pb); | ||||
| 						} catch (Exception e) { | ||||
| 							// TODO Auto-generated catch block
 | ||||
| 							e.printStackTrace(); | ||||
| 						} | ||||
| 						continue; | ||||
| 					} | ||||
| 						 | ||||
| 					boolean run = true; | ||||
| 					for (AbstractEffectModifier mod : ab.getPowerAction().getEffectsBase().getModifiers()){ | ||||
| 						if (appliedMods.containsKey(mod.modType.name()) == false){ | ||||
| 							appliedMods.put(mod.modType.name(), new HashSet<>()); | ||||
| 						} | ||||
| 						 | ||||
| //						if (appliedMods.get(mod.modType.name()).contains(mod.sourceType.name())){
 | ||||
| //							continue;
 | ||||
| //						}
 | ||||
| 						 | ||||
| 						appliedMods.get(mod.modType.name()).add(mod.sourceType.name()); | ||||
| 						try{ | ||||
| 							try { | ||||
| 								PowersManager.runPowerAction(pcSender, pcSender, pcSender.getLoc(), ab, 1, pb); | ||||
| 							} catch (Exception e) { | ||||
| 								// TODO Auto-generated catch block
 | ||||
| 								e.printStackTrace(); | ||||
| 							} | ||||
| 	 | ||||
| 						}catch(Exception e){ | ||||
| 							Logger.error(e); | ||||
| 						} | ||||
| 						break; | ||||
| 						 | ||||
| 							 | ||||
| 					 | ||||
| 					 | ||||
| 				} | ||||
| 			 | ||||
| 			} | ||||
| 		}	 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
| 		return "' /bounds'"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
| 		return "Audits all the mobs in a zone."; | ||||
| 
 | ||||
| 	} | ||||
| 	 | ||||
| 	private String getActionTypes(){ | ||||
| 		String output = ""; | ||||
| 		 | ||||
| 		for (PowerActionType actionType : PowerActionType.values()){ | ||||
| 			output += actionType.name() + " | "; | ||||
| 			 | ||||
| 		} | ||||
| 		 | ||||
| 		return output.substring(0, output.length() -3); | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,149 @@@@ -0,0 +1,149 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.ChatManager; | ||||
| import engine.gameManager.PowersManager; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.AbstractCharacter; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.powers.PowersBase; | ||||
| 
 | ||||
| import java.util.ArrayList; | ||||
| 
 | ||||
| /** | ||||
|  * | ||||
|  * @author Eighty | ||||
|  * | ||||
|  */ | ||||
| public class ApplyStatModCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public ApplyStatModCmd() { | ||||
|         super("applystatmod"); | ||||
|     } | ||||
| 
 | ||||
| 	private static int cnt = 0; | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pcSender, String[] args, | ||||
| 			AbstractGameObject target) { | ||||
| 		if(args.length < 1) { | ||||
| 			//		if(args.length < 2) {
 | ||||
| 			this.sendUsage(pcSender); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		if(!(target instanceof AbstractCharacter)) { | ||||
| 			this.sendHelp(pcSender); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
|         this.setTarget(pcSender); //for logging
 | ||||
| 
 | ||||
| 		int spellID; | ||||
| 		int powerAction = 0; | ||||
| 		if (args[0].toLowerCase().contains("all")){ | ||||
| 
 | ||||
| 			int amount = 0; | ||||
| 			if (args.length == 1) { | ||||
| 				amount = ApplyStatModCmd.cnt; | ||||
| 				ApplyStatModCmd.cnt++; | ||||
| 			} else { | ||||
| 				amount = Integer.valueOf(args[1]); | ||||
| 				ApplyStatModCmd.cnt = amount+1; | ||||
| 			} | ||||
| 
 | ||||
| 
 | ||||
| 			ArrayList<PowersBase> pbList = new ArrayList<>(); | ||||
| 			pbList.add(PowersManager.getPowerByToken(429047968)); | ||||
| 			pbList.add(PowersManager.getPowerByToken(429768864)); | ||||
| 			pbList.add(PowersManager.getPowerByToken(428458144)); | ||||
| 			pbList.add(PowersManager.getPowerByToken(428677994)); | ||||
| 			pbList.add(PowersManager.getPowerByToken(431874079)); | ||||
| 			pbList.add(PowersManager.getPowerByToken(431081336)); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 			for (PowersBase pb:pbList){ | ||||
| 				if(amount <= 0) { | ||||
| 					if (pb.getToken() ==428677994) | ||||
| 						powerAction = 1; | ||||
| 					PowersManager.removeEffect(pcSender, pb.getActions().get(powerAction), false, false); | ||||
| 					continue; | ||||
| 				} else if(amount > 9999 || amount < 21) { | ||||
| 					ChatManager.chatSystemInfo(pcSender, "Amount must be between 21 and 9999 inclusive."); | ||||
| 					return; | ||||
| 				} | ||||
| 
 | ||||
| 				if (pb.getToken() ==428677994){ | ||||
| 					PowersManager.removeEffect(pcSender, pb.getActions().get(powerAction), false, false); | ||||
| 					PowersManager.runPowerAction(pcSender, pcSender, Vector3fImmutable.ZERO, pb.getActions().get(powerAction), amount - 20, pb); | ||||
| 				} | ||||
| 				if (pb.getToken() ==428677994) | ||||
| 					powerAction = 1; | ||||
| 				PowersManager.removeEffect(pcSender, pb.getActions().get(powerAction), false, false); | ||||
| 				PowersManager.runPowerAction(pcSender, pcSender, Vector3fImmutable.ZERO, pb.getActions().get(powerAction), amount - 20, pb); | ||||
| 			} | ||||
| 			return; | ||||
| 		} | ||||
| 		if(args[0].toLowerCase().contains("con")) { | ||||
| 			spellID = 429047968;	//Blessing of Health
 | ||||
| 		} else if(args[0].toLowerCase().contains("str")) { | ||||
| 			spellID = 429768864;	//Blessing of Might
 | ||||
| 		} else if(args[0].toLowerCase().contains("dex")) { | ||||
| 			spellID = 428458144;	//Blessing of Dexterity
 | ||||
| 		} else if(args[0].toLowerCase().contains("int")) { | ||||
| 			spellID = 428677994;	//Bard Spi - TODO
 | ||||
| 			powerAction = 1; | ||||
| 		} else if(args[0].toLowerCase().contains("spi")) { | ||||
| 			spellID = 428677994;	//Bard Spi
 | ||||
| 		} else{ | ||||
| 			ChatManager.chatSystemInfo(pcSender, "No valid stat found."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		PowersBase pb = PowersManager.getPowerByToken(spellID); | ||||
| 
 | ||||
| 		int amount = 0; | ||||
| 		if (args.length == 1) { | ||||
| 			amount = ApplyStatModCmd.cnt; | ||||
| 			ApplyStatModCmd.cnt++; | ||||
| 		} else { | ||||
| 			amount = Integer.valueOf(args[1]); | ||||
| 			ApplyStatModCmd.cnt = amount+1; | ||||
| 		} | ||||
| 		//		int amount = Integer.valueOf(args[1]);
 | ||||
| 		if(amount <= 0) { | ||||
| 			PowersManager.removeEffect(pcSender, pb.getActions().get(powerAction), false, false); | ||||
| 			return; | ||||
| 		} else if(amount > 9999 || amount < 21) { | ||||
| 			ChatManager.chatSystemInfo(pcSender, "Amount must be between 21 and 9999 inclusive."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		PowersManager.removeEffect(pcSender, pb.getActions().get(powerAction), false, false); | ||||
| 		PowersManager.runPowerAction(pcSender, pcSender, Vector3fImmutable.ZERO, pb.getActions().get(powerAction), amount - 20, pb); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
|         return "' /applystatmod <stat> [trains]'"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
|         return "You must be targeting a player!"; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,130 @@@@ -0,0 +1,130 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.Enum.ModType; | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.PowersManager; | ||||
| import engine.net.ItemProductionManager; | ||||
| import engine.objects.*; | ||||
| import engine.powers.effectmodifiers.AbstractEffectModifier; | ||||
| import engine.powers.poweractions.AbstractPowerAction; | ||||
| import org.pmw.tinylog.Logger; | ||||
| 
 | ||||
| public class AuditFailedItemsCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public AuditFailedItemsCmd() { | ||||
| 		super("faileditems"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pcSender, String[] words, | ||||
| 			AbstractGameObject target) { | ||||
| 	 | ||||
| 		 | ||||
|       	    | ||||
|       	   if (ItemProductionManager.FailedItems.isEmpty()) | ||||
|       		   return; | ||||
|       	    | ||||
|       	   Logger.info("Auditing Item production Failed Items"); | ||||
|       	    | ||||
|       	   String newLine = "\r\n"; | ||||
|   		   String auditFailedItem = "Failed Item Name | Prefix | Suffix | NPC | Contract  | Player | "; | ||||
|   		    | ||||
|       	   for (ProducedItem failedItem: ItemProductionManager.FailedItems){ | ||||
|       		    | ||||
|       		   String npcName = ""; | ||||
|       		   String playerName =""; | ||||
|       		   String contractName = ""; | ||||
|       		    | ||||
|       		   String prefix = ""; | ||||
|       		   String suffix = ""; | ||||
|       		   String itemName = ""; | ||||
|       		   NPC npc = NPC.getFromCache(failedItem.getNpcUID()); | ||||
|       		    | ||||
|       		   if (npc == null){ | ||||
|       			   npcName = "null"; | ||||
|       			   contractName = "null"; | ||||
|       		   }else{ | ||||
|       			   npcName = npc.getName(); | ||||
|       			   if (npc.getContract() != null) | ||||
|       				   contractName = npc.getContract().getName(); | ||||
|       		   } | ||||
|       		    | ||||
|       		   PlayerCharacter roller = PlayerCharacter.getFromCache(failedItem.getPlayerID()); | ||||
|       		    | ||||
|       		   if (roller == null) | ||||
|       			   playerName = "null"; | ||||
|       		   else | ||||
|       			   playerName = roller.getName(); | ||||
|       		    | ||||
|       		   ItemBase ib = ItemBase.getItemBase(failedItem.getItemBaseID()); | ||||
|       		    | ||||
|       		   if (ib != null){ | ||||
|       			   itemName = ib.getName(); | ||||
|       		   } | ||||
|       		    | ||||
|       		   if (failedItem.isRandom() == false){ | ||||
|       			   if (failedItem.getPrefix().isEmpty() == false){ | ||||
|        				  AbstractPowerAction pa = PowersManager.getPowerActionByIDString(failedItem.getPrefix()); | ||||
|        				  if (pa != null){ | ||||
|        					  for (AbstractEffectModifier aem : pa.getEffectsBase().getModifiers()){ | ||||
|        						  if (aem.modType.equals(ModType.ItemName)){ | ||||
|        							  prefix = aem.getString1(); | ||||
|        							  break; | ||||
|        						  } | ||||
|        					  } | ||||
|        				  } | ||||
|        				   | ||||
|        			   } | ||||
|       			    | ||||
|       			   if (failedItem.getSuffix().isEmpty() == false){ | ||||
|        				  AbstractPowerAction pa = PowersManager.getPowerActionByIDString(failedItem.getSuffix()); | ||||
|        				  if (pa != null){ | ||||
|        					  for (AbstractEffectModifier aem : pa.getEffectsBase().getModifiers()){ | ||||
|        						  if (aem.modType.equals(ModType.ItemName)){ | ||||
|        							  suffix = aem.getString1(); | ||||
|        							  break; | ||||
|        						  } | ||||
|        					  } | ||||
|        				  } | ||||
|        				   | ||||
|        			   } | ||||
|       			    | ||||
|       		   }else{ | ||||
|       			   prefix = "random"; | ||||
|       		   } | ||||
|       		    | ||||
|       			    | ||||
|       		    | ||||
|       		    | ||||
|       		   auditFailedItem += newLine; | ||||
|       		   auditFailedItem += itemName + " | "+prefix + " | "+suffix + " | "+ failedItem.getNpcUID() + ":" +npcName + " | "+contractName + " | "+failedItem.getPlayerID() + ":" +playerName; | ||||
| 
 | ||||
|       	   } | ||||
|       	   Logger.info(auditFailedItem); | ||||
|       	 ItemProductionManager.FailedItems.clear(); | ||||
|           | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
| 		return "' /bounds'"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
| 		return "Audits all the mobs in a zone."; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,71 @@@@ -0,0 +1,71 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.InterestManagement.HeightMap; | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.ZoneManager; | ||||
| import engine.math.Vector2f; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.objects.Zone; | ||||
| 
 | ||||
| public class AuditHeightMapCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public AuditHeightMapCmd() { | ||||
|         super("auditheightmap"); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pcSender, String[] words, | ||||
| 			AbstractGameObject target) { | ||||
| 
 | ||||
| 		int count = Integer.parseInt(words[0]); | ||||
| 		long start = System.currentTimeMillis(); | ||||
| 		for (int i = 0; i<count;i++){ | ||||
| 
 | ||||
| 
 | ||||
| 			Zone currentZone = ZoneManager.findSmallestZone(pcSender.getLoc()); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 			Vector3fImmutable currentLoc = Vector3fImmutable.getRandomPointInCircle(currentZone.getLoc(), currentZone.getBounds().getHalfExtents().x < currentZone.getBounds().getHalfExtents().y ? currentZone.getBounds().getHalfExtents().x : currentZone.getBounds().getHalfExtents().y ); | ||||
| 
 | ||||
| 			Vector2f zoneLoc = ZoneManager.worldToZoneSpace(currentLoc, currentZone); | ||||
| 
 | ||||
| 			if (currentZone != null && currentZone.getHeightMap() != null){ | ||||
| 				float altitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc); | ||||
| 				float outsetAltitude = HeightMap.getOutsetHeight(altitude, currentZone, pcSender.getLoc()); | ||||
| 			} | ||||
| 
 | ||||
| 		} | ||||
| 		long end = System.currentTimeMillis(); | ||||
| 
 | ||||
| 		long delta = end - start; | ||||
| 
 | ||||
| 		this.throwbackInfo(pcSender, "Audit Heightmap took " + delta + " ms to run " + count + " times!"); | ||||
| 
 | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
| 		return "' /auditmobs [zone.UUID]'"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
| 		return "Audits all the mobs in a zone."; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,106 @@@@ -0,0 +1,106 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.ZoneManager; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.objects.Zone; | ||||
| 
 | ||||
| public class AuditMobsCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public AuditMobsCmd() { | ||||
|         super("auditmobs"); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pcSender, String[] words, | ||||
| 			AbstractGameObject target) { | ||||
| 		if (pcSender == null) return; | ||||
| 
 | ||||
| 		//get Zone to check mobs against
 | ||||
| 
 | ||||
| 		Zone zone; | ||||
| 
 | ||||
| 		if (words.length == 2){ | ||||
| 			if (words[0].equals("all")){ | ||||
| 				int plusplus = 0; | ||||
| 				int count = Integer.parseInt(words[1]); | ||||
| 				for (Zone zoneMicro: ZoneManager.getAllZones()){ | ||||
| 					int size = zoneMicro.zoneMobSet.size(); | ||||
| 
 | ||||
| 					if (size >= count){ | ||||
| 						plusplus++; | ||||
| 						throwbackInfo(pcSender, zoneMicro.getName() + " at location  " + zoneMicro.getLoc().toString()  + " has " + size + " mobs. "); | ||||
| 						System.out.println(zoneMicro.getName() + " at location  " + zoneMicro.getLoc().toString()  + " has " + size + " mobs. "); | ||||
| 					} | ||||
| 
 | ||||
| 
 | ||||
| 				} | ||||
| 				throwbackInfo(pcSender," there are " +plusplus + " zones with at least " + count + " mobs in each."); | ||||
| 			} | ||||
| 			return; | ||||
| 		} | ||||
| 		if (words.length > 1) { | ||||
| 			this.sendUsage(pcSender); | ||||
| 			return; | ||||
| 		} else if (words.length == 1) { | ||||
| 			int uuid; | ||||
| 			try { | ||||
| 				uuid = Integer.parseInt(words[0]); | ||||
| 				zone = ZoneManager.getZoneByUUID(uuid); | ||||
| 			} catch (NumberFormatException e) { | ||||
| 				zone = ZoneManager.findSmallestZone(pcSender.getLoc()); | ||||
| 			} | ||||
| 		} else | ||||
| 			zone = ZoneManager.findSmallestZone(pcSender.getLoc()); | ||||
| 
 | ||||
| 		if (zone == null) { | ||||
| 			throwbackError(pcSender, "Unable to find the zone"); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		//get list of mobs for zone
 | ||||
| 
 | ||||
| 		if (zone.zoneMobSet.isEmpty()) { | ||||
| 			throwbackError(pcSender, "No mobs found for this zone."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		//	ConcurrentHashMap<Integer, Mob> spawnMap = Mob.getSpawnMap();
 | ||||
| 		//ConcurrentHashMap<Mob, Long> respawnMap = Mob.getRespawnMap();
 | ||||
| 		//		ConcurrentHashMap<Mob, Long> despawnMap = Mob.getDespawnMap();
 | ||||
| 
 | ||||
| 		throwbackInfo(pcSender, zone.getName() + ", numMobs: " + zone.zoneMobSet.size()); | ||||
| 		throwbackInfo(pcSender, "UUID, dbID, inRespawnMap, isAlive, activeAI, Loc"); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 		//mob not found in spawn map, check respawn
 | ||||
| 		boolean inRespawn = false; | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
| 		return "' /auditmobs [zone.UUID]'"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
| 		return "Audits all the mobs in a zone."; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,77 @@@@ -0,0 +1,77 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.Enum.GameObjectType; | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.Building; | ||||
| import engine.objects.PlayerCharacter; | ||||
| 
 | ||||
| public class BoundsCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public BoundsCmd() { | ||||
|         super("bounds"); | ||||
|     } | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pcSender, String[] words, | ||||
| 			AbstractGameObject target) { | ||||
| 		if (target == null || !target.getObjectType().equals(GameObjectType.Building)){ | ||||
| 			this.throwbackError(pcSender, "No Building Selected"); | ||||
| 			return; | ||||
| 		} | ||||
| 		 | ||||
| 		Building building = (Building)target; | ||||
| 		 | ||||
| 		if (building.getBounds() == null){ | ||||
| 			this.throwbackInfo(pcSender, "No valid Bounds for building UUID " + building.getObjectUUID()); | ||||
| 			return; | ||||
| 		} | ||||
| 		float topLeftX = building.getLoc().x - building.getBounds().getHalfExtents().x; | ||||
| 		float topLeftY = building.getLoc().z - building.getBounds().getHalfExtents().y; | ||||
| 		 | ||||
| 		float topRightX = building.getLoc().x + building.getBounds().getHalfExtents().x; | ||||
| 		float topRightY = building.getLoc().z - building.getBounds().getHalfExtents().y; | ||||
| 		 | ||||
| 		float bottomLeftX = building.getLoc().x - building.getBounds().getHalfExtents().x; | ||||
| 		float bottomLeftY = building.getLoc().z + building.getBounds().getHalfExtents().y; | ||||
| 		 | ||||
| 		float bottomRightX = building.getLoc().x + building.getBounds().getHalfExtents().x; | ||||
| 		float bottomRightY = building.getLoc().z + building.getBounds().getHalfExtents().y; | ||||
| 		 | ||||
| 		String newLine = "\r\n "; | ||||
| 		 | ||||
| 		String output = "Bounds Information for Building UUID " + building.getObjectUUID(); | ||||
| 		output += newLine; | ||||
| 		 | ||||
| 		output+= "Top Left : " + topLeftX + " , " + topLeftY + newLine; | ||||
| 		output+= "Top Right : " + topRightX + " , " + topRightY + newLine; | ||||
| 		output+= "Bottom Left : " + bottomLeftX + " , " + bottomLeftY + newLine; | ||||
| 		output+= "Bottom Right : " + bottomRightX + " , " + bottomRightY + newLine; | ||||
| 		 | ||||
| 		this.throwbackInfo(pcSender, output); | ||||
| 		 | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
| 		return "' /bounds'"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
| 		return "Audits all the mobs in a zone."; | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| @ -0,0 +1,114 @@@@ -0,0 +1,114 @@ | ||||
| // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||
| // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||
| // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||
| // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||
| // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||
| //      Magicbane Emulator Project © 2013 - 2022
 | ||||
| //                www.magicbane.com
 | ||||
| 
 | ||||
| 
 | ||||
| package engine.devcmd.cmds; | ||||
| 
 | ||||
| import engine.devcmd.AbstractDevCmd; | ||||
| import engine.gameManager.DbManager; | ||||
| import engine.gameManager.SessionManager; | ||||
| import engine.math.Vector3fImmutable; | ||||
| import engine.objects.AbstractGameObject; | ||||
| import engine.objects.PlayerCharacter; | ||||
| import engine.util.MiscUtils; | ||||
| 
 | ||||
| public class ChangeNameCmd extends AbstractDevCmd { | ||||
| 
 | ||||
| 	public ChangeNameCmd() { | ||||
| 		super("changename"); | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected void _doCmd(PlayerCharacter pc, String[] words, | ||||
| 			AbstractGameObject target) { | ||||
| 		Vector3fImmutable loc = null; | ||||
| 
 | ||||
| 		// Arg Count Check
 | ||||
| 		if (words.length < 2) { | ||||
| 			this.sendUsage(pc); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		String oldFirst = words[0]; | ||||
| 		String newFirst = words[1]; | ||||
| 		String newLast = ""; | ||||
| 		if (words.length > 2) { | ||||
| 			newLast = words[2]; | ||||
| 			for (int i=3; i<words.length; i++) | ||||
| 				newLast += ' ' + words[i]; | ||||
| 		} | ||||
| 
 | ||||
| 		//verify new name length
 | ||||
| 		if (newFirst.length() < 3) { | ||||
| 			this.throwbackError(pc, "Error: First name is incorrect length. Must be between 3 and 15 characters"); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		//verify old name length
 | ||||
| 		if (newLast.length() > 50) { | ||||
| 			this.throwbackError(pc, "Error: Last name is incorrect length. Must be no more than 50 characters"); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		// Check if firstname is valid
 | ||||
| 		if (MiscUtils.checkIfFirstNameInvalid(newFirst)) { | ||||
| 			this.throwbackError(pc, "Error: First name is not allowed"); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 
 | ||||
| 		//get the world ID we're modifying for
 | ||||
| 
 | ||||
| 		//test if first name is unique, unless new and old first name are equal.
 | ||||
| 		if (!(oldFirst.equals(newFirst))) { | ||||
| 			if (!DbManager.PlayerCharacterQueries.IS_CHARACTER_NAME_UNIQUE(newFirst)) { | ||||
| 				this.throwbackError(pc, "Error: First name is not unique."); | ||||
| 				return; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		//tests passed, update name in database
 | ||||
| 		if (!DbManager.PlayerCharacterQueries.UPDATE_NAME(oldFirst, newFirst, newLast)) { | ||||
| 			this.throwbackError(pc, "Error: Database failed to update the name."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		//Finally update player ingame
 | ||||
| 		PlayerCharacter pcTar = null; | ||||
| 		try { | ||||
| 			pcTar = SessionManager | ||||
| 					.getPlayerCharacterByLowerCaseName(words[0]); | ||||
| 			pcTar.setFirstName(newFirst); | ||||
| 			pcTar.setLastName(newLast); | ||||
| 			this.setTarget(pcTar); //for logging
 | ||||
| 
 | ||||
| 			//specify if last name is ascii characters only
 | ||||
| 			String lastAscii =  newLast.replaceAll("[^\\p{ASCII}]", ""); | ||||
| 			pcTar.setAsciiLastName(lastAscii.equals(newLast)); | ||||
| 		} catch (Exception e) { | ||||
| 			this.throwbackError(pc, "Database was updated but ingame character failed to update."); | ||||
| 			return; | ||||
| 		} | ||||
| 
 | ||||
| 		String out = oldFirst + " was changed to " + newFirst + (newLast.isEmpty() ? "." : (' ' + newLast + '.')); | ||||
| 		this.throwbackInfo(pc, out); | ||||
| 
 | ||||
| 
 | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getHelpString() { | ||||
| 		return "Changes the name of a player"; | ||||
| 	} | ||||
| 
 | ||||
| 	@Override | ||||
| 	protected String _getUsageString() { | ||||
| 		return "'./changename oldFirstName newFirstName newLastName'"; | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue