forked from MagicBane/Server
				
			
				 835 changed files with 168392 additions and 0 deletions
			
			
		| @ -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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      Magicbane Emulator Project © 2013 - 2022
 | ||||||
|  | //                www.magicbane.com
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | package engine.ai.utilities; | ||||||
|  | 
 | ||||||
|  | public class PowerUtilities { | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | 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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | 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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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 @@ | |||||||
|  | // • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | ||||||
|  | // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | ||||||
|  | // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | ||||||
|  | // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | ||||||
|  | // ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | ||||||
|  | //      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