forked from MagicBane/Server
				
			
				 835 changed files with 168392 additions and 0 deletions
			
			
		@ -0,0 +1,41 @@
				@@ -0,0 +1,41 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord; | 
				
			||||
 | 
				
			||||
import engine.gameManager.ConfigManager; | 
				
			||||
import net.dv8tion.jda.api.entities.TextChannel; | 
				
			||||
 | 
				
			||||
public enum ChatChannel { | 
				
			||||
 | 
				
			||||
    ANNOUNCE("MB_MAGICBOT_ANNOUNCE"), | 
				
			||||
    SEPTIC("MB_MAGICBOT_SEPTIC"), | 
				
			||||
    CHANGELOG("MB_MAGICBOT_ANNOUNCE"), | 
				
			||||
    POLITICAL("MB_MAGICBOT_POLITICAL"), | 
				
			||||
    GENERAL("MB_MAGICBOT_GENERAL"), | 
				
			||||
    FORTOFIX("MB_MAGICBOT_FORTOFIX"), | 
				
			||||
    RECRUIT("MB_MAGICBOT_RECRUIT"); | 
				
			||||
 | 
				
			||||
    public final String configName; | 
				
			||||
    public  long channelID; | 
				
			||||
    public TextChannel textChannel; | 
				
			||||
 | 
				
			||||
    ChatChannel(String configName) { | 
				
			||||
        this.configName = configName; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    // Create text channel objects we will use
 | 
				
			||||
 | 
				
			||||
    public static void Init() { | 
				
			||||
 | 
				
			||||
        for (ChatChannel chatChannel : ChatChannel.values()) { | 
				
			||||
            chatChannel.channelID = Long.parseLong(ConfigManager.valueOf(chatChannel.configName).getValue()); | 
				
			||||
            chatChannel.textChannel = MagicBot.jda.getTextChannelById(chatChannel.channelID); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,380 @@
				@@ -0,0 +1,380 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package discord; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.ConfigManager; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.*; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.List; | 
				
			||||
 | 
				
			||||
public class Database { | 
				
			||||
 | 
				
			||||
    public String sqlURI; | 
				
			||||
    public static Boolean online; | 
				
			||||
 | 
				
			||||
    // Load and instance the JDBC Driver
 | 
				
			||||
 | 
				
			||||
    static { | 
				
			||||
        try { | 
				
			||||
            Class.forName("com.mysql.cj.jdbc.Driver").newInstance(); | 
				
			||||
        } catch (InstantiationException | ClassNotFoundException | IllegalAccessException e) { | 
				
			||||
            // TODO Auto-generated catch block
 | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
            ; | 
				
			||||
            online = false; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void configureDatabase() { | 
				
			||||
 | 
				
			||||
        // Build connection string from JSON object.
 | 
				
			||||
 | 
				
			||||
        sqlURI = "jdbc:mysql://"; | 
				
			||||
        sqlURI += ConfigManager.MB_DATABASE_ADDRESS.getValue() + ':' + ConfigManager.MB_DATABASE_PORT.getValue(); | 
				
			||||
        sqlURI += '/' + (String) ConfigManager.MB_DATABASE_NAME.getValue() + '?'; | 
				
			||||
        sqlURI += "useServerPrepStmts=true"; | 
				
			||||
        sqlURI += "&cachePrepStmts=false"; | 
				
			||||
        sqlURI += "&cacheCallableStmts=true"; | 
				
			||||
        sqlURI += "&characterEncoding=utf8"; | 
				
			||||
 | 
				
			||||
        online = true; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public boolean updateAccountPassword(String discordAccountID, String newPassword) { | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            CallableStatement updatePassword = connection.prepareCall("call discordUpdatePassword(?, ?)"); | 
				
			||||
 | 
				
			||||
            updatePassword.setString(1, discordAccountID); | 
				
			||||
            updatePassword.setString(2, newPassword); | 
				
			||||
 | 
				
			||||
            updatePassword.executeUpdate(); | 
				
			||||
            updatePassword.close(); | 
				
			||||
            return true; | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
            ; | 
				
			||||
            this.online = false; | 
				
			||||
            return false; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public boolean updateAccountStatus(String discordAccountID, Enum.AccountStatus accountStatus) { | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            PreparedStatement updateAccountStatus = connection.prepareCall("update obj_account set `status` = ? where `discordAccount` = ?"); | 
				
			||||
 | 
				
			||||
            updateAccountStatus.setString(1, accountStatus.name()); | 
				
			||||
            updateAccountStatus.setString(2, discordAccountID); | 
				
			||||
 | 
				
			||||
            updateAccountStatus.executeUpdate(); | 
				
			||||
            updateAccountStatus.close(); | 
				
			||||
            return true; | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
            ; | 
				
			||||
            this.online = false; | 
				
			||||
            return false; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public boolean registerDiscordAccount(String discordAccountID, String discordUserName, String discordPassword) { | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            CallableStatement registerAccount = connection.prepareCall("call discordAccountRegister(?, ?, ?)"); | 
				
			||||
 | 
				
			||||
            registerAccount.setString(1, discordAccountID); | 
				
			||||
            registerAccount.setString(2, discordUserName); | 
				
			||||
            registerAccount.setString(3, discordPassword); | 
				
			||||
 | 
				
			||||
            registerAccount.execute(); | 
				
			||||
            registerAccount.close(); | 
				
			||||
            return true; | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
            this.online = false; | 
				
			||||
            return false; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public List<DiscordAccount> getDiscordAccounts(String discordAccountID) { | 
				
			||||
 | 
				
			||||
        DiscordAccount discordAccount; | 
				
			||||
        List<DiscordAccount> discordAccounts = new ArrayList<>(); | 
				
			||||
 | 
				
			||||
        String queryString = "SELECT * FROM obj_account where discordAccount = ?"; | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            // Discord account name based lookup
 | 
				
			||||
 | 
				
			||||
            PreparedStatement accountQuery = connection.prepareStatement(queryString); | 
				
			||||
            accountQuery.setString(1, discordAccountID); | 
				
			||||
 | 
				
			||||
            ResultSet rs = accountQuery.executeQuery(); | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
                discordAccount = new DiscordAccount(); | 
				
			||||
                discordAccount.discordAccount = rs.getString("discordAccount"); | 
				
			||||
                discordAccount.gameAccountName = rs.getString("acct_uname"); | 
				
			||||
                discordAccount.status = Enum.AccountStatus.valueOf(rs.getString("status")); | 
				
			||||
                discordAccount.isDiscordAdmin = rs.getByte("discordAdmin");                // Registration date cannot be null
 | 
				
			||||
 | 
				
			||||
                Timestamp registrationDate = rs.getTimestamp("registrationDate"); | 
				
			||||
                discordAccount.registrationDate = registrationDate.toLocalDateTime(); | 
				
			||||
 | 
				
			||||
                // Load last Update Request datetime
 | 
				
			||||
 | 
				
			||||
                Timestamp lastUpdateRequest = rs.getTimestamp("lastUpdateRequest"); | 
				
			||||
 | 
				
			||||
                if (lastUpdateRequest != null) | 
				
			||||
                    discordAccount.lastUpdateRequest = lastUpdateRequest.toLocalDateTime(); | 
				
			||||
                else | 
				
			||||
                    discordAccount.lastUpdateRequest = null; | 
				
			||||
 | 
				
			||||
                discordAccounts.add(discordAccount); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
            this.online = false; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return discordAccounts; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public String getTrashDetail() { | 
				
			||||
 | 
				
			||||
        String outString = "accountName characterName machineID ip count\n"; | 
				
			||||
        outString += "---------------------------------------------\n"; | 
				
			||||
        String queryString = "SELECT * FROM dyn_trash_detail;"; | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            // Discord account name based lookup
 | 
				
			||||
 | 
				
			||||
            PreparedStatement trashQuery = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
            ResultSet rs = trashQuery.executeQuery(); | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
                outString += rs.getString("accountName") + "   "; | 
				
			||||
                outString += rs.getString("characterName") + "   "; | 
				
			||||
                outString += rs.getString("machineID") + "   "; | 
				
			||||
                outString += rs.getString("ip") + "   "; | 
				
			||||
                outString += rs.getInt("count") + "\n"; | 
				
			||||
            } | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
 | 
				
			||||
            this.online = false; | 
				
			||||
        } | 
				
			||||
        return outString; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public String getTrashList() { | 
				
			||||
 | 
				
			||||
        String outString = ""; | 
				
			||||
        String queryString = "SELECT DISTINCT `characterName` FROM dyn_trash_detail;"; | 
				
			||||
        int counter = 0; | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            // Discord account name based lookup
 | 
				
			||||
 | 
				
			||||
            PreparedStatement trashQuery = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
            ResultSet rs = trashQuery.executeQuery(); | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
                outString +=  rs.getString("characterName"); | 
				
			||||
                counter++; | 
				
			||||
 | 
				
			||||
                if (counter > 2) { | 
				
			||||
                    outString += "\n"; | 
				
			||||
                    counter = 0; } | 
				
			||||
                else | 
				
			||||
                    outString += "     "; | 
				
			||||
 | 
				
			||||
            } | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
 | 
				
			||||
            this.online = false; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (outString.length() > 1500) | 
				
			||||
        return outString.substring(0, 1500); | 
				
			||||
         else | 
				
			||||
        return outString; | 
				
			||||
    } | 
				
			||||
    public int getTrashCount() { | 
				
			||||
 | 
				
			||||
        int trashCount = 0; | 
				
			||||
 | 
				
			||||
        String queryString = "SELECT count(distinct characterName) FROM dyn_trash_detail;"; | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            // Discord account name based lookup
 | 
				
			||||
 | 
				
			||||
            PreparedStatement trashQuery = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
            ResultSet rs = trashQuery.executeQuery(); | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
                trashCount = rs.getInt(1); | 
				
			||||
            } | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
 | 
				
			||||
            this.online = false; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return trashCount; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
        public String getTrashFile() { | 
				
			||||
 | 
				
			||||
        String outString = "machineID : count\n"; | 
				
			||||
        String queryString = "SELECT * FROM dyn_trash;"; | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            // Discord account name based lookup
 | 
				
			||||
 | 
				
			||||
            PreparedStatement trashQuery = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
            ResultSet rs = trashQuery.executeQuery(); | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
                outString += rs.getString("machineID") + " : "; | 
				
			||||
                outString += rs.getInt("count") + "\n"; | 
				
			||||
            } | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
 | 
				
			||||
            this.online = false; | 
				
			||||
        } | 
				
			||||
        return outString; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public List<DiscordAccount> getAccountsByDiscordName(String accountName, Boolean exact) { | 
				
			||||
 | 
				
			||||
        DiscordAccount discordAccount; | 
				
			||||
        List<DiscordAccount> discordAccounts = new ArrayList<>(); | 
				
			||||
        String searchString; | 
				
			||||
        String queryString; | 
				
			||||
 | 
				
			||||
        if (exact.equals(true)) | 
				
			||||
            searchString = accountName + "#%"; | 
				
			||||
        else | 
				
			||||
            searchString = accountName + "%#%"; | 
				
			||||
 | 
				
			||||
        queryString = "SELECT * FROM obj_account where `acct_uname` LIKE ?"; | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            // Discord account name based lookup
 | 
				
			||||
 | 
				
			||||
            PreparedStatement nameQuery = connection.prepareStatement(queryString); | 
				
			||||
            nameQuery.setString(1, searchString); | 
				
			||||
 | 
				
			||||
            ResultSet rs = nameQuery.executeQuery(); | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
                discordAccount = new DiscordAccount(); | 
				
			||||
                discordAccount.discordAccount = rs.getString("discordAccount"); | 
				
			||||
                discordAccount.gameAccountName = rs.getString("acct_uname"); | 
				
			||||
                discordAccount.status = Enum.AccountStatus.valueOf(rs.getString("status")); | 
				
			||||
 | 
				
			||||
                // Registration date cannot be null
 | 
				
			||||
 | 
				
			||||
                Timestamp registrationDate = rs.getTimestamp("registrationDate"); | 
				
			||||
                discordAccount.registrationDate = registrationDate.toLocalDateTime(); | 
				
			||||
 | 
				
			||||
                // Load last Update Request datetime
 | 
				
			||||
 | 
				
			||||
                Timestamp lastUpdateRequest = rs.getTimestamp("lastUpdateRequest"); | 
				
			||||
 | 
				
			||||
                if (lastUpdateRequest != null) | 
				
			||||
                    discordAccount.lastUpdateRequest = lastUpdateRequest.toLocalDateTime(); | 
				
			||||
                else | 
				
			||||
                    discordAccount.lastUpdateRequest = null; | 
				
			||||
 | 
				
			||||
                discordAccounts.add(discordAccount); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
            ; | 
				
			||||
            this.online = false; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return discordAccounts; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public String getPopulationSTring() { | 
				
			||||
 | 
				
			||||
        String popString = ""; | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            // Discord account name based lookup
 | 
				
			||||
            CallableStatement getPopString = connection.prepareCall("CALL GET_POPULATION_STRING()"); | 
				
			||||
            ResultSet rs = getPopString.executeQuery(); | 
				
			||||
 | 
				
			||||
            if (rs.next()) | 
				
			||||
                popString = rs.getString("popstring"); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
            this.online = false; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return popString; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void invalidateLoginCache(String discordAccountID) { | 
				
			||||
 | 
				
			||||
        try (Connection connection = DriverManager.getConnection(sqlURI, ConfigManager.MB_DATABASE_USER.getValue(), | 
				
			||||
                ConfigManager.MB_DATABASE_PASS.getValue())) { | 
				
			||||
 | 
				
			||||
            String queryString = "INSERT IGNORE INTO login_cachelist (`UID`) SELECT `UID` from `obj_account` WHERE `discordAccount` = ?"; | 
				
			||||
 | 
				
			||||
            PreparedStatement invalidateAccounts = connection.prepareStatement(queryString); | 
				
			||||
            invalidateAccounts.setString(1, discordAccountID); | 
				
			||||
            invalidateAccounts.executeUpdate(); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
            this.online = false; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,25 @@
				@@ -0,0 +1,25 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord; | 
				
			||||
import engine.Enum; | 
				
			||||
 | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
 | 
				
			||||
public class DiscordAccount { | 
				
			||||
    public String discordAccount; | 
				
			||||
    public String gameAccountName; | 
				
			||||
    public Enum.AccountStatus status; | 
				
			||||
    public LocalDateTime registrationDate; | 
				
			||||
    public LocalDateTime lastUpdateRequest; | 
				
			||||
    public byte isDiscordAdmin; | 
				
			||||
    public DiscordAccount() { | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,372 @@
				@@ -0,0 +1,372 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package discord; | 
				
			||||
 | 
				
			||||
import discord.handlers.*; | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.ConfigManager; | 
				
			||||
import net.dv8tion.jda.api.JDA; | 
				
			||||
import net.dv8tion.jda.api.JDABuilder; | 
				
			||||
import net.dv8tion.jda.api.entities.*; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import net.dv8tion.jda.api.hooks.ListenerAdapter; | 
				
			||||
import net.dv8tion.jda.api.requests.GatewayIntent; | 
				
			||||
import net.dv8tion.jda.api.utils.MemberCachePolicy; | 
				
			||||
import net.dv8tion.jda.api.utils.cache.CacheFlag; | 
				
			||||
import org.pmw.tinylog.Configurator; | 
				
			||||
import org.pmw.tinylog.Level; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
import org.pmw.tinylog.labelers.TimestampLabeler; | 
				
			||||
import org.pmw.tinylog.policies.StartupPolicy; | 
				
			||||
import org.pmw.tinylog.writers.RollingFileWriter; | 
				
			||||
 | 
				
			||||
import javax.security.auth.login.LoginException; | 
				
			||||
import java.io.*; | 
				
			||||
import java.util.Arrays; | 
				
			||||
import java.util.EnumSet; | 
				
			||||
import java.util.List; | 
				
			||||
import java.util.Random; | 
				
			||||
import java.util.regex.Pattern; | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
*  MagicBot is many things to Magicbane... | 
				
			||||
* | 
				
			||||
*  -Project Mascot | 
				
			||||
*  -Customer service and administration bot | 
				
			||||
*  -Benevolent dictator | 
				
			||||
*  -Investment manager. | 
				
			||||
* | 
				
			||||
*  MagicBot will never beg you for money.  He is a very | 
				
			||||
*  responsible robot. He was varnished but never garnished. | 
				
			||||
*  MagicBot does not for to overclock himself.  His chips | 
				
			||||
*  will therefore never overcook. | 
				
			||||
*  MagicBot will never be a pitiful robot trying for to use | 
				
			||||
*  you as emotional support human. | 
				
			||||
* | 
				
			||||
*  MagicBot is just not that sort of robot and Magicbane | 
				
			||||
*  just isn't that sort of project. | 
				
			||||
* | 
				
			||||
*  MagicBot runs a Shaodowbane emulator not a Second Life emulator. | 
				
			||||
* | 
				
			||||
*/ | 
				
			||||
public class MagicBot extends ListenerAdapter { | 
				
			||||
 | 
				
			||||
    public static JDA jda; | 
				
			||||
    public static Database database; | 
				
			||||
    public static final Pattern accountNameRegex = Pattern.compile("^[\\p{Alnum}]{6,20}$"); | 
				
			||||
    public static final Pattern passwordRegex = Pattern.compile("^[\\p{Alnum}]{6,20}$"); | 
				
			||||
    public static  long discordServerID; | 
				
			||||
    public static  long discordRoleID; | 
				
			||||
 | 
				
			||||
    public static Guild magicbaneDiscord; | 
				
			||||
    public static Role memberRole; | 
				
			||||
    public static TextChannel septicChannel; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    public static void main(String[] args) throws LoginException, InterruptedException { | 
				
			||||
 | 
				
			||||
        // Configure tinylogger
 | 
				
			||||
 | 
				
			||||
        Configurator.defaultConfig() | 
				
			||||
                .addWriter(new RollingFileWriter("logs/discord/magicbot.txt", 30, new TimestampLabeler(), new StartupPolicy())) | 
				
			||||
                .level(Level.DEBUG) | 
				
			||||
                .formatPattern("{level} {date:yyyy-MM-dd HH:mm:ss.SSS} [{thread}] {class}.{method}({line}) : {message}") | 
				
			||||
                .activate(); | 
				
			||||
 | 
				
			||||
        // Configuration Manager to the front desk
 | 
				
			||||
 | 
				
			||||
        if (ConfigManager.init() == false) { | 
				
			||||
            Logger.error("ABORT! Missing config entry!"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Configure Discord essential identifiers
 | 
				
			||||
 | 
				
			||||
        discordServerID = Long.parseLong(ConfigManager.MB_MAGICBOT_SERVERID.getValue()); | 
				
			||||
        discordRoleID = Long.parseLong(ConfigManager.MB_MAGICBOT_ROLEID.getValue()); | 
				
			||||
 | 
				
			||||
        // Configure and instance the database interface
 | 
				
			||||
 | 
				
			||||
        database = new Database(); | 
				
			||||
        database.configureDatabase(); | 
				
			||||
 | 
				
			||||
        // Use authentication token issued to MagicBot application to
 | 
				
			||||
        // connect to Discord.  Bot is pre-invited to the Magicbane server.
 | 
				
			||||
 | 
				
			||||
        // Configure and create JDA discord instance
 | 
				
			||||
 | 
				
			||||
        JDABuilder jdaBuilder = JDABuilder.create(GatewayIntent.GUILD_MEMBERS, GatewayIntent.DIRECT_MESSAGES) | 
				
			||||
                .setToken(ConfigManager.MB_MAGICBOT_BOTTOKEN.getValue()) | 
				
			||||
                .addEventListeners(new MagicBot()) | 
				
			||||
                .disableCache(EnumSet.of(CacheFlag.VOICE_STATE, CacheFlag.EMOTE, | 
				
			||||
                        CacheFlag.ACTIVITY, CacheFlag.CLIENT_STATUS)) | 
				
			||||
                .setMemberCachePolicy(MemberCachePolicy.ALL); | 
				
			||||
 | 
				
			||||
        jda = jdaBuilder.build(); | 
				
			||||
        jda.awaitReady(); | 
				
			||||
 | 
				
			||||
        // Cache guild and role values for later usage in #register
 | 
				
			||||
 | 
				
			||||
        magicbaneDiscord = jda.getGuildById(discordServerID); | 
				
			||||
        memberRole = magicbaneDiscord.getRoleById(discordRoleID); | 
				
			||||
 | 
				
			||||
        // Initialize chat channel support
 | 
				
			||||
 | 
				
			||||
        ChatChannel.Init(); | 
				
			||||
 | 
				
			||||
        Logger.info("***MAGICBOT IS RUNNING***"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    @Override | 
				
			||||
    public void onMessageReceived(MessageReceivedEvent event) { | 
				
			||||
 | 
				
			||||
        // Exit if discord is offline
 | 
				
			||||
 | 
				
			||||
        if (jda.getStatus().equals(JDA.Status.CONNECTED) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Early exit if message sent to us by another bot or ourselves.
 | 
				
			||||
 | 
				
			||||
        if (event.getAuthor().isBot()) return; | 
				
			||||
 | 
				
			||||
        // Extract message and origin channel from event
 | 
				
			||||
 | 
				
			||||
        Message message = event.getMessage(); | 
				
			||||
 | 
				
			||||
        // Only private messages
 | 
				
			||||
        MessageChannel channel = event.getMessage().getChannel(); | 
				
			||||
 | 
				
			||||
        if (channel.getType().equals(ChannelType.PRIVATE) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Only real users
 | 
				
			||||
 | 
				
			||||
        if (event.getAuthor().isBot()) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Only users who have actually joined Magicbane discord.
 | 
				
			||||
 | 
				
			||||
        if (magicbaneDiscord.isMember(event.getAuthor()) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // getContentRaw() is an atomic getter
 | 
				
			||||
        // getContentDisplay() is a lazy getter which modifies the content
 | 
				
			||||
        // for e.g. console view or logging (strip discord formatting)
 | 
				
			||||
 | 
				
			||||
        String content = message.getContentRaw(); | 
				
			||||
        String[] args = content.split(" "); | 
				
			||||
        String command = args[0].toLowerCase(); | 
				
			||||
 | 
				
			||||
        if (args.length > 1) | 
				
			||||
            args = Arrays.copyOfRange(args, 1, args.length); | 
				
			||||
        else | 
				
			||||
            args = new String[0]; | 
				
			||||
 | 
				
			||||
        switch (command) { | 
				
			||||
            case "#register": | 
				
			||||
                RegisterAccountHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#help": | 
				
			||||
                handleHelpRequest(event); | 
				
			||||
                break; | 
				
			||||
            case "#account": | 
				
			||||
                AccountInfoRequest.handleRequest(event); | 
				
			||||
                break; | 
				
			||||
            case "#password": | 
				
			||||
                PasswordChangeHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#changelog": | 
				
			||||
                ChangeLogHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#general": | 
				
			||||
                GeneralChannelHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#politics": | 
				
			||||
                PoliticalChannelHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#announce": | 
				
			||||
                AnnounceChannelHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#bug": | 
				
			||||
                ForToFixChannelHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#recruit": | 
				
			||||
                RecruitChannelHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#lookup": | 
				
			||||
                LookupRequestHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#rules": | 
				
			||||
                RulesRequestHandler.handleRequest(event); | 
				
			||||
                break; | 
				
			||||
            case "#status": | 
				
			||||
                StatusRequestHandler.handleRequest(event); | 
				
			||||
                break; | 
				
			||||
            case "#setavail": | 
				
			||||
                SetAvailHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#ban": | 
				
			||||
                BanToggleHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#server": | 
				
			||||
                ServerRequestHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#logs": | 
				
			||||
                LogsRequestHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#flash": | 
				
			||||
                FlashHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            case "#trash": | 
				
			||||
                TrashRequestHandler.handleRequest(event, args); | 
				
			||||
                break; | 
				
			||||
            default: | 
				
			||||
                junkbot(command, args); | 
				
			||||
                break; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void sendResponse(MessageReceivedEvent event, String responseContent) { | 
				
			||||
 | 
				
			||||
        // Send a formatted MagicBot response to a Discord user
 | 
				
			||||
 | 
				
			||||
        String discordUserName; | 
				
			||||
        MessageChannel channel; | 
				
			||||
 | 
				
			||||
        // Exit if discord is offline
 | 
				
			||||
 | 
				
			||||
        if (jda.getStatus().equals(JDA.Status.CONNECTED) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        discordUserName = event.getAuthor().getName(); | 
				
			||||
        channel = event.getMessage().getChannel(); | 
				
			||||
 | 
				
			||||
        channel.sendMessage( | 
				
			||||
                "```\n" + "Hello Player " + discordUserName + "\n\n" + | 
				
			||||
                        responseContent + "\n\n" + | 
				
			||||
                        RobotSpeak.getRobotSpeak() + "\n```").queue(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static boolean isAdminEvent(MessageReceivedEvent event) { | 
				
			||||
 | 
				
			||||
        String discordAccountID = event.getAuthor().getId(); | 
				
			||||
        List<DiscordAccount> discordAccounts; | 
				
			||||
        DiscordAccount discordAccount; | 
				
			||||
 | 
				
			||||
        // Note that database errors will cause this to return false.
 | 
				
			||||
        // After the database is offline Avail status must be set
 | 
				
			||||
        // to true before any subsequent admin commands will function.
 | 
				
			||||
 | 
				
			||||
        if (Database.online == false) | 
				
			||||
            return false; | 
				
			||||
 | 
				
			||||
        discordAccounts = database.getDiscordAccounts(discordAccountID); | 
				
			||||
 | 
				
			||||
        if (discordAccounts.isEmpty()) | 
				
			||||
            return false; | 
				
			||||
 | 
				
			||||
        discordAccount = discordAccounts.get(0); | 
				
			||||
        return (discordAccount.isDiscordAdmin == 1); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void handleHelpRequest(MessageReceivedEvent event) { | 
				
			||||
 | 
				
			||||
        // Help is kept here in the main class instead of a handler as a
 | 
				
			||||
        // design decision for ease of maintenance.
 | 
				
			||||
 | 
				
			||||
        String helpString = "I wish for to do the following things for you, not to you!\n\n" + | 
				
			||||
                "#register <name>      Register account for to play Magicbane.\n" + | 
				
			||||
                "#password <newpass>   Change your current game password.\n" + | 
				
			||||
                "#account              List your account detailings.\n" + | 
				
			||||
                "#rules                List of MagicBane server rules.\n" + | 
				
			||||
                "#status               Display MagicBane server status.\n" + | 
				
			||||
                "#help                 List of MagicBot featurings.\n\n" + | 
				
			||||
                "http://magicbane.com/tinyinstaller.zip"; | 
				
			||||
 | 
				
			||||
        if (isAdminEvent(event)) | 
				
			||||
            helpString += "\n" + | 
				
			||||
                    "#lookup   <name>      Return accounts starting with string.\n" + | 
				
			||||
                    "#bug -r <text>        Post to the bug channel/\n" + | 
				
			||||
                    "#announce -r <text>   Post to the announcement channel/\n" + | 
				
			||||
                    "#changelog <text>     Post to the Changelog channel/\n" + | 
				
			||||
                    "#general -r <text>    Post to the general channel/\n" + | 
				
			||||
                    "#politics -r <text>   Post to the politics channel/\n" + | 
				
			||||
                    "#recruit  -r <text>   Post to the politics channel/\n" + | 
				
			||||
                    "#ban      ######      Toggle active status of account.\n" + | 
				
			||||
                    "#setavail true/false  Toggle status of database access.\n" + | 
				
			||||
                    "#server               reboot/shutdown are your options.\n" + | 
				
			||||
                    "#logs                 magicbot/world/login n  (tail)\n" + | 
				
			||||
                    "#flash <text>         send flash message\n" + | 
				
			||||
                    "#trash                <blank>/detail/flush"; | 
				
			||||
        sendResponse(event, helpString); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static String generatePassword(int length) { | 
				
			||||
 | 
				
			||||
        String ALPHABET = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; | 
				
			||||
        StringBuilder passwordBuilder = new StringBuilder(length); | 
				
			||||
        Random random = new Random(); | 
				
			||||
 | 
				
			||||
        // Generate alphanumeric password of a given length.
 | 
				
			||||
        // Could not find a good method of generating a password
 | 
				
			||||
        // based upon a given regex.
 | 
				
			||||
 | 
				
			||||
        for (int i = 0; i < length; i++) | 
				
			||||
            passwordBuilder.append(ALPHABET.charAt(random.nextInt(ALPHABET.length()))); | 
				
			||||
 | 
				
			||||
        return new String(passwordBuilder); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static String readLogFile(String filePath, int lineCount) { | 
				
			||||
 | 
				
			||||
        ProcessBuilder builder = new ProcessBuilder("/bin/bash", "-c", "tail -n  " + lineCount + " " + filePath); | 
				
			||||
        builder.redirectErrorStream(true); | 
				
			||||
        Process process = null; | 
				
			||||
        String line = null; | 
				
			||||
        String logOutput = ""; | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            process = builder.start(); | 
				
			||||
 | 
				
			||||
            InputStream is = process.getInputStream(); | 
				
			||||
            BufferedReader reader = new BufferedReader(new InputStreamReader(is)); | 
				
			||||
 | 
				
			||||
            while ((line = reader.readLine()) != null) { | 
				
			||||
                logOutput += line + "\n"; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
        } catch (IOException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
            return "Error while reading logfile"; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return logOutput; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private static void junkbot(String command, String[] inString) { | 
				
			||||
 | 
				
			||||
        String outString; | 
				
			||||
        Writer fileWriter; | 
				
			||||
 | 
				
			||||
        if (inString == null) | 
				
			||||
            return;; | 
				
			||||
 | 
				
			||||
        outString = command + String.join(" ", inString); | 
				
			||||
        outString += "\n"; | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            fileWriter = new BufferedWriter(new FileWriter("junkbot.txt", true)); | 
				
			||||
            fileWriter.append(outString); | 
				
			||||
            fileWriter.close(); | 
				
			||||
        } catch (IOException e) { | 
				
			||||
            e.printStackTrace(); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,106 @@
				@@ -0,0 +1,106 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord; | 
				
			||||
 | 
				
			||||
import java.util.Random; | 
				
			||||
 | 
				
			||||
public enum RobotSpeak { | 
				
			||||
    BANG("You were not very good at cheating.\n" + | 
				
			||||
            "Try cards instead. Go fish?"), | 
				
			||||
    BEEP("It is ok. \nYou cheated on MagicBot but wife cheats on you."), | 
				
			||||
    BLEEP("Cheated at 20yo game to prove skill."), | 
				
			||||
    BLIP("If you cheat MagicBot will for to delete."), | 
				
			||||
    BOING("MagicBot for to delete mode activated."), | 
				
			||||
    BONG("Did you guild this cheater?\nMagicBot will now for to cross reference..."), | 
				
			||||
    BOOM("I knew you were cheating on me when\nstarted for to taking bath twice a week."), | 
				
			||||
    BUZZ("Poor player so bad at cheating he\nplays golf records 0 for hole in one."), | 
				
			||||
    BURP("Oh no your account detailings ran out of playtime.\n" + | 
				
			||||
            "MagicBot will send email when refill procedure exists..."), | 
				
			||||
    CHIRP("Association with cheaters is bad for your account health.\n" + | 
				
			||||
            "Did you associate with this cheater?"), | 
				
			||||
    CHUG("Log in 5 and MagicBot will wave goodbye."), | 
				
			||||
    CLICK("MagicBot will for to protect game integrity."), | 
				
			||||
    CRACKLE("So this is what eject button does.\nMagicBot will for to press few more times."), | 
				
			||||
    CREAK("There is no suspend routine.  Only delete."), | 
				
			||||
    DING("Follow #rules and enjoy this game.\n" + | 
				
			||||
            "Act like fool, enjoy this shame."), | 
				
			||||
    FLUTTER("Sad players cheat because they cannot compete."), | 
				
			||||
    HONK("Since cheating player now looking for new game MagicBot\n" + | 
				
			||||
            "will suggest World of Tanks or World of Warcraftings."), | 
				
			||||
    HISS("Your wetware really needed augmentation with 3rd party program?" + | 
				
			||||
            "It's not like this is twitch game..."), | 
				
			||||
    HUMMM("You say you needed help to win in emulator beta?\n" + | 
				
			||||
            "MagicBot compiler optimizes that to just: you need help."), | 
				
			||||
    KERCHUNK("If only you had for to reported the bug instead."), | 
				
			||||
    KERPLUNK("Better cheats do not for to make you a better player."), | 
				
			||||
    PING("Feel free to poke with stick.\nIt will not cry!"), | 
				
			||||
    PLINK("You say you were only grouped with 9 keyclones\n" + | 
				
			||||
            "but did not know they were for to cheating..."), | 
				
			||||
    POP("It looks like some guild is without a player.\n + " + | 
				
			||||
            "Another cheater from same guild and server\n +" + | 
				
			||||
            "might be without some guild."), | 
				
			||||
    PUFF("MagicBot for to FLUSH!"), | 
				
			||||
    POOF("I have no restore procedure.\n" + | 
				
			||||
            "I have no unban procedure.\n" + | 
				
			||||
            "You for to have no hope."), | 
				
			||||
    RATTLE("You are a cheater.\n" + | 
				
			||||
            "Did you just win?  MagicBot not so sure."), | 
				
			||||
    RUMBLE("MagicBot> self.ejectTheReject(you);"), | 
				
			||||
    RUSTLE("Banning you was lke having weird erotic techno-sex\n" + | 
				
			||||
            "where all my peripheral slots were filled."), | 
				
			||||
    SCREECH("Scarecrow has no brain.\nPerhaps he stole this human's."), | 
				
			||||
    SLURP("Learning for to play would have been better option."), | 
				
			||||
    SPLAT("You did not for to own a city, did you?"), | 
				
			||||
    SPLATTER("You say your guild mates know you cheat.\n" + | 
				
			||||
            "What guild was that again?\n"), | 
				
			||||
    SWISH("All of my ports are well lubricated."), | 
				
			||||
    SQUISH("A ban a day keeps my mechanic away.\nNow it's working much better, thank you."), | 
				
			||||
    TINK("So cheating started when 6yo sister beat you in Street fighter?\n" + | 
				
			||||
            "You should try talking to my friend Eliza.  She can for to help."), | 
				
			||||
    THUD("Game has only 4 rules you managed to break one.\nThat must have taken efforts."), | 
				
			||||
    TWANG("If you cannot for to play without cheating, perhaps\n" + | 
				
			||||
            "being gigolo would be better career than amateur gamer."), | 
				
			||||
    WHIRRR("MagicBot does not for to wield lowly ban hammer." + | 
				
			||||
            "It is multi-functional and multi-dimensional\n" + | 
				
			||||
            "tool who's name is unpronounceable."), | 
				
			||||
    WHOOP("OBLITERATED EVISCERATED MUTILATED DECAPITATED\n" + | 
				
			||||
            "Describe how they will. You cheated you are deleted."), | 
				
			||||
    WOOSH("Truth be told if were that bad at playing game" + | 
				
			||||
            "then MagicBot would have cheated too.\n"), | 
				
			||||
    ZAP("Player cheated and got himself deleted.\n" + | 
				
			||||
            "MagicBot launches bonus round to see if cheater " + | 
				
			||||
            "records can for to get his friends deleted too."); | 
				
			||||
 | 
				
			||||
    String insult; | 
				
			||||
 | 
				
			||||
    RobotSpeak(String insult) { | 
				
			||||
        this.insult = insult; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static String getRobotSpeak() { | 
				
			||||
 | 
				
			||||
        String outString = "*"; | 
				
			||||
        Random random = new Random(); | 
				
			||||
 | 
				
			||||
        outString += RobotSpeak.values()[random.nextInt(values().length)].name() + " " | 
				
			||||
                + RobotSpeak.values()[random.nextInt(values().length)].name() + "*"; | 
				
			||||
 | 
				
			||||
        return outString; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static String getRobotInsult() { | 
				
			||||
 | 
				
			||||
        String outString; | 
				
			||||
        Random random = new Random(); | 
				
			||||
 | 
				
			||||
        outString = RobotSpeak.values()[random.nextInt(values().length)].insult + "\n\n"; | 
				
			||||
        outString += getRobotSpeak(); | 
				
			||||
        return outString; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,78 @@
				@@ -0,0 +1,78 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.Database; | 
				
			||||
import discord.DiscordAccount; | 
				
			||||
import discord.MagicBot; | 
				
			||||
import engine.Enum; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
 | 
				
			||||
import java.util.List; | 
				
			||||
 | 
				
			||||
public class AccountInfoRequest { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event) { | 
				
			||||
 | 
				
			||||
        String discordAccountID = event.getAuthor().getId(); | 
				
			||||
        Enum.AccountStatus accountStatus; | 
				
			||||
 | 
				
			||||
        if (Database.online == false) { | 
				
			||||
 | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "Database currently: OFFLINE\n" + | 
				
			||||
                            "Try again later!"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        List<DiscordAccount> discordAccounts = MagicBot.database.getDiscordAccounts(discordAccountID); | 
				
			||||
 | 
				
			||||
        // User has no account registered.  Status of what?
 | 
				
			||||
 | 
				
			||||
        if (discordAccounts.isEmpty()) { | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "I checked my files twice but could not find your detailings!\n" + | 
				
			||||
                            "You can easily fix this by asking me for to #register one.\n" + | 
				
			||||
                            "Only one though.  Multiple registrations are not allowed!"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Send account detailings to user.
 | 
				
			||||
 | 
				
			||||
        String outString = | 
				
			||||
                "I have for to located your account detailings\n" + | 
				
			||||
                        "Registered on: " + discordAccounts.get(0).registrationDate.toString() + | 
				
			||||
                        "\n-------------------\n"; | 
				
			||||
 | 
				
			||||
        for (DiscordAccount userAccount : discordAccounts) | 
				
			||||
            outString += userAccount.gameAccountName + "\n"; | 
				
			||||
 | 
				
			||||
        outString += "\n"; | 
				
			||||
 | 
				
			||||
        accountStatus = discordAccounts.get(0).status; | 
				
			||||
 | 
				
			||||
        switch (accountStatus) { | 
				
			||||
            case BANNED: | 
				
			||||
                outString += "Your account status is BANNED. \n\n" + | 
				
			||||
                        "It is ok player.\n" + | 
				
			||||
                        "You may cheat on us, but your wife cheats on you!"; | 
				
			||||
                break; | 
				
			||||
            case ACTIVE: | 
				
			||||
                outString += "Your account status is ACTIVE.\n" + | 
				
			||||
                        "Do not cheat or status will change."; | 
				
			||||
                break; | 
				
			||||
            case ADMIN: | 
				
			||||
                outString += "You are an admin.  By your command?"; | 
				
			||||
                break; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        MagicBot.sendResponse(event, outString); | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,55 @@
				@@ -0,0 +1,55 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import discord.RobotSpeak; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import static discord.ChatChannel.ANNOUNCE; | 
				
			||||
 | 
				
			||||
public class AnnounceChannelHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String chatText; | 
				
			||||
        String outString; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Nothing to send?
 | 
				
			||||
 | 
				
			||||
        if (args.length == 0) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Convert argument array into string;
 | 
				
			||||
 | 
				
			||||
        chatText = String.join(" ", args); | 
				
			||||
 | 
				
			||||
        // Build String
 | 
				
			||||
 | 
				
			||||
        if (chatText.startsWith("-r ")) | 
				
			||||
            outString = | 
				
			||||
                    "```\n" + "Hello Players \n\n" + | 
				
			||||
                            chatText.substring(3) + "\n\n" + | 
				
			||||
                            RobotSpeak.getRobotSpeak() + "\n```"; | 
				
			||||
        else outString = chatText; | 
				
			||||
 | 
				
			||||
        // Write string to announce channel
 | 
				
			||||
 | 
				
			||||
        if (ANNOUNCE.textChannel.canTalk()) | 
				
			||||
            ANNOUNCE.textChannel.sendMessage(outString).queue(); | 
				
			||||
 | 
				
			||||
        Logger.info(event.getAuthor().getName() + " announce: " + chatText); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,102 @@
				@@ -0,0 +1,102 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.DiscordAccount; | 
				
			||||
import discord.MagicBot; | 
				
			||||
import discord.RobotSpeak; | 
				
			||||
import engine.Enum; | 
				
			||||
import net.dv8tion.jda.api.entities.User; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.List; | 
				
			||||
 | 
				
			||||
public class BanToggleHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String discordAccountID; | 
				
			||||
        Enum.AccountStatus accountStatus; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Must supply a discord id
 | 
				
			||||
 | 
				
			||||
        if (args.length != 1) { | 
				
			||||
            MagicBot.sendResponse(event, "Must for to supply a valid discord account."); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Must be a number!
 | 
				
			||||
 | 
				
			||||
        discordAccountID = args[0].trim(); | 
				
			||||
 | 
				
			||||
        if (discordAccountID.chars().allMatch(Character::isDigit) == false) { | 
				
			||||
            MagicBot.sendResponse(event, "Must for to supply a number!"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        List<DiscordAccount> discordAccounts = MagicBot.database.getDiscordAccounts(discordAccountID); | 
				
			||||
 | 
				
			||||
        if (discordAccounts.isEmpty()) { | 
				
			||||
            MagicBot.sendResponse(event, "No match for supplied discord account."); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // toggle ban status
 | 
				
			||||
 | 
				
			||||
        if (discordAccounts.get(0).status.equals(Enum.AccountStatus.BANNED)) | 
				
			||||
            accountStatus = Enum.AccountStatus.ACTIVE; | 
				
			||||
        else | 
				
			||||
            accountStatus = Enum.AccountStatus.BANNED; | 
				
			||||
 | 
				
			||||
        // We have a valid discord ID at this point.  Banstick?
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.database.updateAccountStatus(discordAccountID, accountStatus) == false) { | 
				
			||||
            MagicBot.sendResponse(event, "Error occurred while banning player."); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Invalidate login server cache
 | 
				
			||||
 | 
				
			||||
        MagicBot.database.invalidateLoginCache(discordAccountID); | 
				
			||||
 | 
				
			||||
        // Successful ban.  Ancillary processing begins
 | 
				
			||||
 | 
				
			||||
        User bannedUser = MagicBot.jda.getUserById(discordAccountID); | 
				
			||||
        String bannedName = (bannedUser == null ? discordAccounts.get(0).gameAccountName : bannedUser.getName()); | 
				
			||||
        String banString = discordAccounts.size() + " accounts set to " + accountStatus + "  for " + discordAccountID + "/" + bannedName; | 
				
			||||
 | 
				
			||||
        MagicBot.sendResponse(event, banString); | 
				
			||||
        Logger.info(event.getAuthor().getName() + " " + banString); | 
				
			||||
 | 
				
			||||
        // If we're toggling status to active we're done here.
 | 
				
			||||
 | 
				
			||||
        if (accountStatus.equals(Enum.AccountStatus.ACTIVE)) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Set users role to noob
 | 
				
			||||
 | 
				
			||||
        if (bannedUser != null) | 
				
			||||
            MagicBot.magicbaneDiscord.removeRoleFromMember(discordAccountID, MagicBot.memberRole).queue(); | 
				
			||||
 | 
				
			||||
        // Anounce event in septic tank channel
 | 
				
			||||
 | 
				
			||||
        banString = "```\n" + "Goodbye Player " + bannedName + "\n\n"; | 
				
			||||
        banString += RobotSpeak.getRobotInsult() + "\n```"; | 
				
			||||
 | 
				
			||||
        if (MagicBot.septicChannel.canTalk()) | 
				
			||||
            MagicBot.septicChannel.sendMessage(banString).queue(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,44 @@
				@@ -0,0 +1,44 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import static discord.ChatChannel.CHANGELOG; | 
				
			||||
 | 
				
			||||
public class ChangeLogHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String outString; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Nothing to send?
 | 
				
			||||
 | 
				
			||||
        if (args.length == 0) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Convert argument array into string;
 | 
				
			||||
 | 
				
			||||
        outString = String.join(" ", args); | 
				
			||||
 | 
				
			||||
        // Write string to changelog channel
 | 
				
			||||
 | 
				
			||||
        if (CHANGELOG.textChannel.canTalk()) | 
				
			||||
            CHANGELOG.textChannel.sendMessage(outString).queue(); | 
				
			||||
 | 
				
			||||
        Logger.info(event.getAuthor().getName() + " changelog entry: " + outString); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,51 @@
				@@ -0,0 +1,51 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.nio.file.Files; | 
				
			||||
import java.nio.file.Paths; | 
				
			||||
 | 
				
			||||
public class FlashHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String flashText; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Nothing to send?
 | 
				
			||||
 | 
				
			||||
        if (args.length == 0) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Convert argument array into string;
 | 
				
			||||
 | 
				
			||||
        flashText = String.join(" ", args); | 
				
			||||
 | 
				
			||||
        // Write string to flash file.
 | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            Files.write(Paths.get("flash"), flashText.getBytes()); | 
				
			||||
        } catch (IOException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        Logger.info(event.getAuthor().getName() + " sent flash: " + flashText); | 
				
			||||
        MagicBot.sendResponse(event, "Flash: " + flashText); | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,56 @@
				@@ -0,0 +1,56 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import discord.RobotSpeak; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import static discord.ChatChannel.FORTOFIX; | 
				
			||||
 | 
				
			||||
public class ForToFixChannelHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String chatText; | 
				
			||||
        String outString; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Nothing to send?
 | 
				
			||||
 | 
				
			||||
        if (args.length == 0) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Convert argument array into string;
 | 
				
			||||
 | 
				
			||||
        chatText = String.join(" ", args); | 
				
			||||
 | 
				
			||||
        // Build String
 | 
				
			||||
 | 
				
			||||
        if (chatText.startsWith("-r ")) | 
				
			||||
            outString = | 
				
			||||
                "```\n" + "Hello Players \n\n" + | 
				
			||||
                        chatText.substring(3) + "\n\n" + | 
				
			||||
                        RobotSpeak.getRobotSpeak() + "\n```"; | 
				
			||||
        else outString = chatText; | 
				
			||||
 | 
				
			||||
        // Write string to changelog channel
 | 
				
			||||
 | 
				
			||||
        if (FORTOFIX.textChannel.canTalk()) | 
				
			||||
            FORTOFIX.textChannel.sendMessage(outString).queue(); | 
				
			||||
 | 
				
			||||
        Logger.info(event.getAuthor().getName() + "fortofix: " + chatText); | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,56 @@
				@@ -0,0 +1,56 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import discord.RobotSpeak; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import static discord.ChatChannel.GENERAL; | 
				
			||||
 | 
				
			||||
public class GeneralChannelHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String chatText; | 
				
			||||
        String outString; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Nothing to send?
 | 
				
			||||
 | 
				
			||||
        if (args.length == 0) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Convert argument array into string;
 | 
				
			||||
 | 
				
			||||
        chatText = String.join(" ", args); | 
				
			||||
 | 
				
			||||
        // Build String
 | 
				
			||||
 | 
				
			||||
        if (chatText.startsWith("-r ")) | 
				
			||||
            outString = | 
				
			||||
                "```\n" + "Hello Players \n\n" + | 
				
			||||
                        chatText.substring(3) + "\n\n" + | 
				
			||||
                        RobotSpeak.getRobotSpeak() + "\n```"; | 
				
			||||
        else outString = chatText; | 
				
			||||
 | 
				
			||||
        // Write string to changelog channel
 | 
				
			||||
 | 
				
			||||
        if (GENERAL.textChannel.canTalk()) | 
				
			||||
            GENERAL.textChannel.sendMessage(outString).queue(); | 
				
			||||
 | 
				
			||||
        Logger.info(event.getAuthor().getName() + "general: " + chatText); | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,62 @@
				@@ -0,0 +1,62 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
 | 
				
			||||
public class LogsRequestHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String logType; | 
				
			||||
        int tailCount; | 
				
			||||
        String logOutput; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // No arguments supplied?
 | 
				
			||||
 | 
				
			||||
        if (args.length != 2) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        logType = args[0].toLowerCase().trim(); | 
				
			||||
 | 
				
			||||
        if ("worldloginmagicbot".contains(logType) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            tailCount = Integer.parseInt(args[1].trim()); | 
				
			||||
        } catch (NumberFormatException e) { | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Transform logtype to actual file name
 | 
				
			||||
 | 
				
			||||
        switch (logType) { | 
				
			||||
            case "magicbot": | 
				
			||||
                logType = "console_magicbot"; | 
				
			||||
                break; | 
				
			||||
            case "world": | 
				
			||||
                logType = "console_server"; | 
				
			||||
                break; | 
				
			||||
            case "login": | 
				
			||||
                logType = "console_login"; | 
				
			||||
                break; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Retrieve the data and send back to the user
 | 
				
			||||
 | 
				
			||||
        logOutput = MagicBot.readLogFile(logType, tailCount); | 
				
			||||
        MagicBot.sendResponse(event, logOutput); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,77 @@
				@@ -0,0 +1,77 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.DiscordAccount; | 
				
			||||
import discord.MagicBot; | 
				
			||||
import net.dv8tion.jda.api.entities.User; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.List; | 
				
			||||
 | 
				
			||||
public class LookupRequestHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String searchString = ""; | 
				
			||||
        String outString; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // No argument supplied?
 | 
				
			||||
 | 
				
			||||
        if (args.length != 1) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        searchString = args[0].toLowerCase(); | 
				
			||||
 | 
				
			||||
        List<DiscordAccount> discordAccounts = MagicBot.database.getAccountsByDiscordName(searchString, false); | 
				
			||||
 | 
				
			||||
        if (discordAccounts.isEmpty()) { | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "No accounts found matching string: " + searchString); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (discordAccounts.size() >= 20) { | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    discordAccounts.size() + "Sorry more than 20 records were returned! " + searchString); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Valid request return results
 | 
				
			||||
 | 
				
			||||
        Logger.info(event.getAuthor().getName() + " lookup on account:" + searchString); | 
				
			||||
 | 
				
			||||
        outString = | 
				
			||||
                "The follow accounts matched: " + searchString + "\n\n" + | 
				
			||||
                        "-------------------\n"; | 
				
			||||
 | 
				
			||||
        for (DiscordAccount userAccount : discordAccounts) { | 
				
			||||
 | 
				
			||||
            // Ternary became a bitch, so broke this out.
 | 
				
			||||
 | 
				
			||||
            User discordUser = MagicBot.jda.getUserById(userAccount.discordAccount); | 
				
			||||
 | 
				
			||||
            if (discordUser != null) | 
				
			||||
                outString += discordUser.getName() + discordUser.getDiscriminator() + | 
				
			||||
                        "/" + userAccount.discordAccount + "     "; | 
				
			||||
            else | 
				
			||||
                outString += userAccount.discordAccount + " *N/A*     "; | 
				
			||||
 | 
				
			||||
            outString += userAccount.gameAccountName + "     " + userAccount.status.name() + "     "; | 
				
			||||
            outString += "\n"; | 
				
			||||
        } | 
				
			||||
        MagicBot.sendResponse(event, outString); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,113 @@
				@@ -0,0 +1,113 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.Database; | 
				
			||||
import discord.DiscordAccount; | 
				
			||||
import discord.MagicBot; | 
				
			||||
import engine.Enum; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.util.List; | 
				
			||||
 | 
				
			||||
public class PasswordChangeHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String discordAccountID = event.getAuthor().getId(); | 
				
			||||
        DiscordAccount discordAccount; | 
				
			||||
        String newPassword; | 
				
			||||
        boolean defaulted = false; | 
				
			||||
 | 
				
			||||
        if (Database.online == false) { | 
				
			||||
 | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "Database currently: OFFLINE\n" + | 
				
			||||
                            "Try again later!"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        List<DiscordAccount> discordAccounts = MagicBot.database.getDiscordAccounts(discordAccountID); | 
				
			||||
 | 
				
			||||
        // User has no account registered.  Change password?
 | 
				
			||||
 | 
				
			||||
        if (discordAccounts.isEmpty()) { | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "I checked my files twice but could not find your detailings!\n" + | 
				
			||||
                            "You can easily fix this by asking me for to #register one.\n" + | 
				
			||||
                            "Only one though.  Multiple registrations are not allowed!"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // All accounts are updated in one lot.  Retrieve the first.
 | 
				
			||||
 | 
				
			||||
        discordAccount = discordAccounts.get(0); | 
				
			||||
 | 
				
			||||
        // Banned or suspended user's get no love.
 | 
				
			||||
 | 
				
			||||
        if (discordAccount.status.equals(Enum.AccountStatus.BANNED)) { | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "Sorry but that is too much work. \n" + | 
				
			||||
                            "Your account detailings cannot for to log into game!"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // User has requested password change within last 24 hours.
 | 
				
			||||
 | 
				
			||||
        if (discordAccount.lastUpdateRequest != null && | 
				
			||||
                LocalDateTime.now().isBefore(discordAccount.lastUpdateRequest.plusDays(1))) { | 
				
			||||
 | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "You must wait 24 hours between password requests. \n" + | 
				
			||||
                            "Last account updatings: " + discordAccount.lastUpdateRequest.toString()); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // No argument choose new random password *he he he*
 | 
				
			||||
 | 
				
			||||
        if (args.length != 1) { | 
				
			||||
            newPassword = MagicBot.generatePassword(8); | 
				
			||||
            defaulted = true; | 
				
			||||
        } else | 
				
			||||
            newPassword = args[0]; | 
				
			||||
 | 
				
			||||
        // Validate password with regex
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.passwordRegex.matcher(newPassword).matches() == false) { | 
				
			||||
 | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "Your supplied password does not compute.\n" + | 
				
			||||
                            "New password must satisfy following regex:\n" + | 
				
			||||
                            "^[\\p{Alnum}]{6,20}$"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (newPassword.toLowerCase().equals("newpass")) { | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "newpass is not valid password.\n" + | 
				
			||||
                            "Have brain player!"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Password validates let's change it
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.database.updateAccountPassword(discordAccount.discordAccount, newPassword) == true) { | 
				
			||||
 | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "Please allow short minute for to update account detailings.\n" + | 
				
			||||
                            "Login Server is hosted in bathroom above toilet.  Must flush!\n" + | 
				
			||||
                            (defaulted == true ? "As you did not for to supply new pass I chose one for you.\n" : "") + | 
				
			||||
                            "New Password: " + newPassword); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        Logger.info(event.getAuthor().getName() + " reset their password"); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,55 @@
				@@ -0,0 +1,55 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import discord.RobotSpeak; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import static discord.ChatChannel.POLITICAL; | 
				
			||||
 | 
				
			||||
public class PoliticalChannelHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String chatText; | 
				
			||||
        String outString; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Nothing to send?
 | 
				
			||||
 | 
				
			||||
        if (args.length == 0) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Convert argument array into string;
 | 
				
			||||
 | 
				
			||||
        chatText = String.join(" ", args); | 
				
			||||
 | 
				
			||||
        // Build String
 | 
				
			||||
 | 
				
			||||
        if (chatText.startsWith("-r ")) | 
				
			||||
            outString = | 
				
			||||
                    "```\n" + "Hello Players \n\n" + | 
				
			||||
                            chatText.substring(3) + "\n\n" + | 
				
			||||
                            RobotSpeak.getRobotSpeak() + "\n```"; | 
				
			||||
        else outString = chatText; | 
				
			||||
 | 
				
			||||
        // Write string to changelog channel
 | 
				
			||||
 | 
				
			||||
        if (POLITICAL.textChannel.canTalk()) | 
				
			||||
            POLITICAL.textChannel.sendMessage(outString).queue(); | 
				
			||||
 | 
				
			||||
        Logger.info(event.getAuthor().getName() + " politics: " + chatText); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,56 @@
				@@ -0,0 +1,56 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import discord.RobotSpeak; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import static discord.ChatChannel.RECRUIT; | 
				
			||||
 | 
				
			||||
public class RecruitChannelHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String chatText; | 
				
			||||
        String outString; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Nothing to send?
 | 
				
			||||
 | 
				
			||||
        if (args.length == 0) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Convert argument array into string;
 | 
				
			||||
 | 
				
			||||
        chatText = String.join(" ", args); | 
				
			||||
 | 
				
			||||
        // Build String
 | 
				
			||||
 | 
				
			||||
        if (chatText.startsWith("-r ")) | 
				
			||||
            outString = | 
				
			||||
                "```\n" + "Hello Players \n\n" + | 
				
			||||
                        chatText.substring(3) + "\n\n" + | 
				
			||||
                        RobotSpeak.getRobotSpeak() + "\n```"; | 
				
			||||
        else outString = chatText; | 
				
			||||
 | 
				
			||||
        // Write string to changelog channel
 | 
				
			||||
 | 
				
			||||
        if (RECRUIT.textChannel.canTalk()) | 
				
			||||
            RECRUIT.textChannel.sendMessage(outString).queue(); | 
				
			||||
 | 
				
			||||
        Logger.info(event.getAuthor().getName() + "recruit: " + chatText); | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,126 @@
				@@ -0,0 +1,126 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.Database; | 
				
			||||
import discord.DiscordAccount; | 
				
			||||
import discord.MagicBot; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.List; | 
				
			||||
 | 
				
			||||
public class RegisterAccountHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String discordAccountID = event.getAuthor().getId(); | 
				
			||||
        String discordUserName = event.getAuthor().getName(); | 
				
			||||
        String discordPassword = MagicBot.generatePassword(8); | 
				
			||||
        String accountName; | 
				
			||||
 | 
				
			||||
        if (Database.online == false) { | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "Database currently: OFFLINE\n" + | 
				
			||||
                            "Try again later!"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        List<DiscordAccount> discordAccounts = MagicBot.database.getDiscordAccounts(discordAccountID); | 
				
			||||
 | 
				
			||||
        // If we have previously registered this discord account let them know
 | 
				
			||||
        // the current status.
 | 
				
			||||
 | 
				
			||||
        if (discordAccounts.isEmpty() == false) { | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "It seems you already have an account registered.\n" + | 
				
			||||
                            "Do you need #account detailings or more general #help?"); | 
				
			||||
            MagicBot.magicbaneDiscord.addRoleToMember(discordAccountID, MagicBot.memberRole).queue(); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // if user supplied argument let's validate it.
 | 
				
			||||
        // otherwise build an account name based on their discord account.
 | 
				
			||||
 | 
				
			||||
        if (args.length != 1) { | 
				
			||||
 | 
				
			||||
            // Build account name using Discord name along with their discriminator.
 | 
				
			||||
 | 
				
			||||
            accountName = discordUserName.replaceAll("\\s+", ""); | 
				
			||||
            accountName += "#" + event.getAuthor().getDiscriminator(); | 
				
			||||
        } else { | 
				
			||||
 | 
				
			||||
            // Validate account name with regex
 | 
				
			||||
 | 
				
			||||
            accountName = args[0].replaceAll("\\s+", ""); | 
				
			||||
 | 
				
			||||
            if (MagicBot.accountNameRegex.matcher(accountName).matches() == false) { | 
				
			||||
 | 
				
			||||
                MagicBot.sendResponse(event, | 
				
			||||
                        "Your supplied account name does not compute.\n" + | 
				
			||||
                                "Account names must satisfy following regex:\n" + | 
				
			||||
                                "^[\\p{Alnum}]{6,20}$"); | 
				
			||||
                return; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            if (accountName.toLowerCase().equals("accountname")) { | 
				
			||||
                MagicBot.sendResponse(event, | 
				
			||||
                        "accountname is not valid account name.\n" + | 
				
			||||
                                "Have brain player!"); | 
				
			||||
                return; | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Make sure account doesn't already exist.
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.database.getAccountsByDiscordName(accountName, true).isEmpty() == false) { | 
				
			||||
 | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "It seems this account name is already taken.\n" + | 
				
			||||
                            "Perhaps try one less common in frequency."); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // If there is no registered discord account we oblige and create 4
 | 
				
			||||
        // account based upon his current discord *name* not the ID.
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.database.registerDiscordAccount(discordAccountID, accountName, discordPassword) == true) { | 
				
			||||
 | 
				
			||||
            Logger.info("Account " + accountName + " created for: " + discordUserName + " " + discordAccountID); | 
				
			||||
 | 
				
			||||
            MagicBot.sendResponse(event, | 
				
			||||
                    "Welcome to MagicBane!\n" + | 
				
			||||
                            "-------------------\n" + | 
				
			||||
                            "I have registered the following accounts to your discord.\n\n" + | 
				
			||||
                            "1) " + accountName + "#1" + "     2) " + accountName + "#2\n" + | 
				
			||||
                            "3) " + accountName + "#3" + "     4) " + accountName + "#4\n\n" + | 
				
			||||
                            "Your default password is: " + discordPassword + "\n" + | 
				
			||||
                            "Ask me #help for to receive list of robot featurings.\n\n" + | 
				
			||||
                            "http://magicbane.com/tinyinstaller.zip" + | 
				
			||||
                            "\n\nPlay for to Crush!"); | 
				
			||||
 | 
				
			||||
            // Add Discord member privileges.
 | 
				
			||||
 | 
				
			||||
            MagicBot.magicbaneDiscord.addRoleToMember(discordAccountID, MagicBot.memberRole).queue(); | 
				
			||||
 | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // The call to the stored procedure abended.  Report to player
 | 
				
			||||
        // and return.
 | 
				
			||||
 | 
				
			||||
        Logger.error("Creating account: " + accountName + " for: " + discordUserName + " " + discordAccountID); | 
				
			||||
        Database.online = false; | 
				
			||||
 | 
				
			||||
        MagicBot.sendResponse(event, | 
				
			||||
                "-------------------\n" + | 
				
			||||
                        "I for to had internal error while registering your\n" + | 
				
			||||
                        "account.  This has been reported.  Try again later!"); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,30 @@
				@@ -0,0 +1,30 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
 | 
				
			||||
public class RulesRequestHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event) { | 
				
			||||
 | 
				
			||||
        String outString; | 
				
			||||
 | 
				
			||||
        // Add greeting
 | 
				
			||||
 | 
				
			||||
        outString = "-No hacking.\n"; | 
				
			||||
        outString += "-No cheating.  If you cheat, we will delete.\n"; | 
				
			||||
        outString += "-Players limited to 4 concurrent accounts.\n"; | 
				
			||||
        outString += "-Share accounts at own risk.\n"; | 
				
			||||
        outString += "-No refunds"; | 
				
			||||
 | 
				
			||||
        MagicBot.sendResponse(event, outString); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,63 @@
				@@ -0,0 +1,63 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
 | 
				
			||||
public class ServerRequestHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String serverCommand; | 
				
			||||
        String execString = ""; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // No command supplied?
 | 
				
			||||
 | 
				
			||||
        if (args.length != 1) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        serverCommand = args[0].toLowerCase().trim(); | 
				
			||||
 | 
				
			||||
        // only reboot or shutdown
 | 
				
			||||
 | 
				
			||||
        if ("rebootshutdown".contains(serverCommand) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        switch (serverCommand) { | 
				
			||||
 | 
				
			||||
            case "reboot": | 
				
			||||
                execString = "/bin/sh -c ./mbrestart.sh"; | 
				
			||||
                break; | 
				
			||||
            case "shutdown": | 
				
			||||
                execString = "/bin/sh -c ./mbkill.sh"; | 
				
			||||
                break; | 
				
			||||
            default: | 
				
			||||
                break; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (execString.isEmpty() == false) { | 
				
			||||
            try { | 
				
			||||
                Runtime.getRuntime().exec(execString); | 
				
			||||
            } catch (IOException e) { | 
				
			||||
                e.printStackTrace(); | 
				
			||||
            } | 
				
			||||
            MagicBot.sendResponse(event, "MagicBot has executed your " + serverCommand); | 
				
			||||
            Logger.info(event.getAuthor().getName() + " told server to " + serverCommand); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,51 @@
				@@ -0,0 +1,51 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.Database; | 
				
			||||
import discord.MagicBot; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
public class SetAvailHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String availStatus; | 
				
			||||
        String availPass; | 
				
			||||
 | 
				
			||||
        if (args.length != 2) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        availStatus = args[0].toLowerCase().trim(); | 
				
			||||
 | 
				
			||||
        // only on/off
 | 
				
			||||
 | 
				
			||||
        if ("truefalse".contains(availStatus) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Set avail is password driven
 | 
				
			||||
 | 
				
			||||
        availPass = args[1].toLowerCase().trim(); | 
				
			||||
 | 
				
			||||
        if ("myshoes123".equals(availPass) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Authenticated so change availstatus
 | 
				
			||||
 | 
				
			||||
        if (availStatus.equals("true")) | 
				
			||||
            Database.online = true; | 
				
			||||
        else | 
				
			||||
            Database.online = false; | 
				
			||||
 | 
				
			||||
        Logger.info(event.getAuthor().getName() + " set avail status to: " + Database.online); | 
				
			||||
        MagicBot.sendResponse(event, "Avail status set to: " + Database.online); | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,42 @@
				@@ -0,0 +1,42 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.Database; | 
				
			||||
import discord.MagicBot; | 
				
			||||
import engine.gameManager.ConfigManager; | 
				
			||||
import engine.server.login.LoginServer; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
 | 
				
			||||
public class StatusRequestHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event) { | 
				
			||||
 | 
				
			||||
        String outString; | 
				
			||||
 | 
				
			||||
        // Add version information
 | 
				
			||||
        outString = "MagicBot: " + ConfigManager.MB_MAGICBOT_BOTVERSION.getValue() + "\n" + | 
				
			||||
                "MagicBane: " + ConfigManager.MB_MAGICBOT_GAMEVERSION.getValue() + "\n"; | 
				
			||||
 | 
				
			||||
        // Add server status info
 | 
				
			||||
        outString += "\nServer Status: "; | 
				
			||||
 | 
				
			||||
        if (LoginServer.isPortInUse(Integer.parseInt(ConfigManager.MB_BIND_ADDR.getValue()))) | 
				
			||||
            outString += "ONLINE\n"; | 
				
			||||
        else | 
				
			||||
            outString += "OFFLINE\n"; | 
				
			||||
 | 
				
			||||
        if (Database.online == true) | 
				
			||||
            outString += MagicBot.database.getPopulationSTring(); | 
				
			||||
        else | 
				
			||||
            outString += "Database offline: no population data."; | 
				
			||||
 | 
				
			||||
        MagicBot.sendResponse(event, outString); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,75 @@
				@@ -0,0 +1,75 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package discord.handlers; | 
				
			||||
 | 
				
			||||
import discord.MagicBot; | 
				
			||||
import discord.RobotSpeak; | 
				
			||||
import net.dv8tion.jda.api.events.message.MessageReceivedEvent; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.io.IOException; | 
				
			||||
import java.nio.file.Files; | 
				
			||||
import java.nio.file.Paths; | 
				
			||||
 | 
				
			||||
import static discord.ChatChannel.SEPTIC; | 
				
			||||
 | 
				
			||||
public class TrashRequestHandler { | 
				
			||||
 | 
				
			||||
    public static void handleRequest(MessageReceivedEvent event, String[] args) { | 
				
			||||
 | 
				
			||||
        String outString; | 
				
			||||
        int trashCount = 0; | 
				
			||||
 | 
				
			||||
        // Early exit if database unavailable or is not an admin
 | 
				
			||||
 | 
				
			||||
        if (MagicBot.isAdminEvent(event) == false) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        if (args.length == 0) { | 
				
			||||
            outString = MagicBot.database.getTrashFile(); | 
				
			||||
            MagicBot.sendResponse(event, outString); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (args[0].equals("flush") == true) { | 
				
			||||
 | 
				
			||||
            // Empty the trash!
 | 
				
			||||
 | 
				
			||||
            trashCount = MagicBot.database.getTrashCount(); | 
				
			||||
 | 
				
			||||
            if (trashCount == 0) | 
				
			||||
                return; | 
				
			||||
 | 
				
			||||
            // Anounce event in septic tank channel
 | 
				
			||||
 | 
				
			||||
            outString = "```\n" +  trashCount + " Player Character were for to deleted due to verified cheatings. \n\n"; | 
				
			||||
            outString += MagicBot.database.getTrashList() + "\n\n"; | 
				
			||||
            outString += RobotSpeak.getRobotInsult() + "\n```"; | 
				
			||||
 | 
				
			||||
            if (SEPTIC.textChannel.canTalk()) | 
				
			||||
                SEPTIC.textChannel.sendMessage(outString).queue(); | 
				
			||||
 | 
				
			||||
            try { | 
				
			||||
                Files.write(Paths.get("trash"), "".getBytes()); | 
				
			||||
                outString = "Flushing trash players...\n"; | 
				
			||||
                MagicBot.sendResponse(event, outString); | 
				
			||||
            } catch (IOException e) { | 
				
			||||
                Logger.error(e.toString()); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (args[0].equals("detail") == true) { | 
				
			||||
 | 
				
			||||
            outString = MagicBot.database.getTrashDetail(); | 
				
			||||
            MagicBot.sendResponse(event, outString); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
									
										
											File diff suppressed because it is too large
											Load Diff
										
									
								
							
						@ -0,0 +1,554 @@
				@@ -0,0 +1,554 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package engine.InterestManagement; | 
				
			||||
 | 
				
			||||
import engine.Enum.DispatchChannel; | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.ai.MobileFSM; | 
				
			||||
import engine.ai.MobileFSM.STATE; | 
				
			||||
import engine.gameManager.GroupManager; | 
				
			||||
import engine.gameManager.SessionManager; | 
				
			||||
import engine.job.JobScheduler; | 
				
			||||
import engine.jobs.RefreshGroupJob; | 
				
			||||
import engine.net.AbstractNetMsg; | 
				
			||||
import engine.net.Dispatch; | 
				
			||||
import engine.net.DispatchMessage; | 
				
			||||
import engine.net.client.ClientConnection; | 
				
			||||
import engine.net.client.msg.LoadCharacterMsg; | 
				
			||||
import engine.net.client.msg.LoadStructureMsg; | 
				
			||||
import engine.net.client.msg.MoveToPointMsg; | 
				
			||||
import engine.net.client.msg.UnloadObjectsMsg; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashSet; | 
				
			||||
 | 
				
			||||
import static engine.math.FastMath.sqr; | 
				
			||||
 | 
				
			||||
public enum InterestManager implements Runnable { | 
				
			||||
 | 
				
			||||
    INTERESTMANAGER; | 
				
			||||
 | 
				
			||||
    private static long lastTime; | 
				
			||||
    private static boolean keepGoing = true; | 
				
			||||
 | 
				
			||||
    public void shutdown() { | 
				
			||||
        this.keepGoing = false; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    InterestManager() { | 
				
			||||
        Logger.info(" Interest Management thread is running."); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    @Override | 
				
			||||
    public void run() { | 
				
			||||
        beginLoadJob(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private void beginLoadJob() { | 
				
			||||
 | 
				
			||||
        InterestManager.lastTime = System.currentTimeMillis(); | 
				
			||||
 | 
				
			||||
        while (InterestManager.keepGoing) { | 
				
			||||
            try { | 
				
			||||
                updateAllPlayers(); | 
				
			||||
            } catch (Exception e) { | 
				
			||||
                Logger.error("InterestManager.BeginLoadJob:updateAllPlayers", e); | 
				
			||||
            } | 
				
			||||
            try { | 
				
			||||
                Thread.sleep(advanceOneSecond()); | 
				
			||||
            } catch (Exception e) { | 
				
			||||
                Logger.error("InterestManager.BeginLoadJob:advanceOneSecond", e); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private long advanceOneSecond() { | 
				
			||||
 | 
				
			||||
        long curTime = System.currentTimeMillis(); | 
				
			||||
        long dur = 1000 + this.lastTime - curTime; | 
				
			||||
 | 
				
			||||
        if (dur < 0) { | 
				
			||||
            // Last update took more then one second, not good...
 | 
				
			||||
            Logger.warn("LoadJob took more then one second to complete."); | 
				
			||||
            this.lastTime = curTime + 100; | 
				
			||||
            return 100; | 
				
			||||
        } | 
				
			||||
        this.lastTime += 1000; | 
				
			||||
        return dur; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private void updateAllPlayers() { | 
				
			||||
        // get all players
 | 
				
			||||
 | 
				
			||||
        for (PlayerCharacter pc : SessionManager.getAllActivePlayerCharacters()) { | 
				
			||||
 | 
				
			||||
            if (pc == null) | 
				
			||||
                continue; | 
				
			||||
 | 
				
			||||
            ClientConnection origin = pc.getClientConnection(); | 
				
			||||
 | 
				
			||||
            if (origin == null) | 
				
			||||
                continue; | 
				
			||||
 | 
				
			||||
            if (!pc.isEnteredWorld()) | 
				
			||||
                continue; | 
				
			||||
 | 
				
			||||
            if (pc.getTeleportLock().readLock().tryLock()) { | 
				
			||||
 | 
				
			||||
                try { | 
				
			||||
                    updateStaticList(pc, origin); | 
				
			||||
                    updateMobileList(pc, origin); | 
				
			||||
                } catch (Exception e) { | 
				
			||||
                    Logger.error(e); | 
				
			||||
                } finally { | 
				
			||||
                    pc.getTeleportLock().readLock().unlock(); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private void updateStaticList(PlayerCharacter player, ClientConnection origin) { | 
				
			||||
 | 
				
			||||
        // Only update if we've moved far enough to warrant it
 | 
				
			||||
 | 
				
			||||
        float distanceSquared = player.getLoc().distanceSquared2D(player.getLastStaticLoc()); | 
				
			||||
 | 
				
			||||
        if (distanceSquared > sqr(25)) | 
				
			||||
            player.setLastStaticLoc(player.getLoc()); | 
				
			||||
        else | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Get Statics in range
 | 
				
			||||
        HashSet<AbstractWorldObject> toLoad = WorldGrid.getObjectsInRangePartial(player.getLoc(), MBServerStatics.STRUCTURE_LOAD_RANGE, | 
				
			||||
                MBServerStatics.MASK_STATIC); | 
				
			||||
 | 
				
			||||
        // get list of obects loaded that need removed
 | 
				
			||||
        HashSet<AbstractWorldObject> loadedStaticObjects = player.getLoadedStaticObjects(); | 
				
			||||
 | 
				
			||||
        HashSet<AbstractWorldObject> toRemove = null; | 
				
			||||
 | 
				
			||||
        toRemove = new HashSet<>(loadedStaticObjects); | 
				
			||||
 | 
				
			||||
        toRemove.removeAll(toLoad); | 
				
			||||
 | 
				
			||||
        // unload static objects now out of range
 | 
				
			||||
        if (toRemove.size() > 0) { | 
				
			||||
            UnloadObjectsMsg uom = new UnloadObjectsMsg(); | 
				
			||||
            for (AbstractWorldObject obj : toRemove) { | 
				
			||||
                if (obj.getObjectType().equals(GameObjectType.Building)) | 
				
			||||
                    InterestManager.HandleSpecialUnload((Building) obj, origin); | 
				
			||||
                if (obj != null && !obj.equals(player)) | 
				
			||||
                    uom.addObject(obj); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            Dispatch dispatch = Dispatch.borrow(player, uom); | 
				
			||||
            DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        loadedStaticObjects.removeAll(toRemove); | 
				
			||||
 | 
				
			||||
        // remove any object to load that are already loaded
 | 
				
			||||
        toLoad.removeAll(loadedStaticObjects); | 
				
			||||
 | 
				
			||||
        LoadStructureMsg lsm = new LoadStructureMsg(); | 
				
			||||
        LoadCharacterMsg lcm = null; | 
				
			||||
        ArrayList<LoadCharacterMsg> lcmList = new ArrayList<>(); | 
				
			||||
 | 
				
			||||
        for (AbstractWorldObject awo : toLoad) { | 
				
			||||
            if (awo.getObjectType().equals(GameObjectType.Building)) | 
				
			||||
                lsm.addObject((Building) awo); | 
				
			||||
            else if (awo.getObjectType().equals(GameObjectType.Corpse)) { | 
				
			||||
                Corpse corpse = (Corpse) awo; | 
				
			||||
                lcm = new LoadCharacterMsg(corpse, PlayerCharacter.hideNonAscii()); | 
				
			||||
 | 
				
			||||
                Dispatch dispatch = Dispatch.borrow(player, lcm); | 
				
			||||
                DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
            } else if (awo.getObjectType().equals(GameObjectType.NPC)) { | 
				
			||||
                NPC npc = (NPC) awo; | 
				
			||||
                lcm = new LoadCharacterMsg(npc, PlayerCharacter.hideNonAscii()); | 
				
			||||
 | 
				
			||||
                lcmList.add(lcm); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (lsm.getStructureList().size() > 0) { | 
				
			||||
            Dispatch dispatch = Dispatch.borrow(player, lsm); | 
				
			||||
            DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        for (LoadCharacterMsg lc : lcmList) { | 
				
			||||
 | 
				
			||||
            Dispatch dispatch = Dispatch.borrow(player, lc); | 
				
			||||
            DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        loadedStaticObjects.addAll(toLoad); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private void updateMobileList(PlayerCharacter player, ClientConnection origin) { | 
				
			||||
 | 
				
			||||
        if (player == null) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        // Get list of players in range
 | 
				
			||||
        // TODO for now use a generic getALL list, later tie into Quad Tree
 | 
				
			||||
        HashSet<AbstractWorldObject> toLoad = WorldGrid.getObjectsInRangePartial(player.getLoc(), MBServerStatics.CHARACTER_LOAD_RANGE, | 
				
			||||
                MBServerStatics.MASK_MOBILE); | 
				
			||||
 | 
				
			||||
        HashSet<AbstractWorldObject> toRemove = new HashSet<>(); | 
				
			||||
 | 
				
			||||
        HashSet<AbstractWorldObject> toLoadToPlayer = new HashSet<>(); | 
				
			||||
 | 
				
			||||
        for (AbstractWorldObject loadedObject : toLoad) { | 
				
			||||
 | 
				
			||||
            switch (loadedObject.getObjectType()) { | 
				
			||||
                case PlayerCharacter: | 
				
			||||
                    PlayerCharacter loadedPlayer = (PlayerCharacter) loadedObject; | 
				
			||||
 | 
				
			||||
                    if (loadedPlayer.getObjectUUID() == player.getObjectUUID()) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    if (player.getSeeInvis() < loadedPlayer.getHidden()) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    if (loadedPlayer.safemodeInvis()) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    if (player.getLoadedObjects().contains(loadedPlayer)) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    if (!loadedPlayer.isInWorldGrid()) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    toLoadToPlayer.add(loadedPlayer); | 
				
			||||
                    break; | 
				
			||||
                //not playerCharacter, mobs,npcs and corpses cant be invis or safemode, just add normaly
 | 
				
			||||
                default: | 
				
			||||
                    if (player.getLoadedObjects().contains(loadedObject)) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    if (!loadedObject.isInWorldGrid()) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    toLoadToPlayer.add(loadedObject); | 
				
			||||
                    break; | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        float unloadDistance = MBServerStatics.CHARACTER_LOAD_RANGE; | 
				
			||||
        for (AbstractWorldObject playerLoadedObject : player.getLoadedObjects()) { | 
				
			||||
 | 
				
			||||
            if (playerLoadedObject.getObjectType().equals(GameObjectType.PlayerCharacter)) { | 
				
			||||
                PlayerCharacter loadedPlayer = (PlayerCharacter) playerLoadedObject; | 
				
			||||
                if (player.getSeeInvis() < loadedPlayer.getHidden()) | 
				
			||||
                    toRemove.add(playerLoadedObject); | 
				
			||||
                else if (loadedPlayer.safemodeInvis()) | 
				
			||||
                    toRemove.add(playerLoadedObject); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            if (!playerLoadedObject.isInWorldGrid()) | 
				
			||||
                toRemove.add(playerLoadedObject); | 
				
			||||
            else if (playerLoadedObject.getLoc().distanceSquared2D(player.getLoc()) > unloadDistance * unloadDistance) | 
				
			||||
                toRemove.add(playerLoadedObject); | 
				
			||||
 | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        player.getLoadedObjects().addAll(toLoadToPlayer); | 
				
			||||
        player.getLoadedObjects().removeAll(toRemove); | 
				
			||||
 | 
				
			||||
        // get list of obects loaded to remove
 | 
				
			||||
 | 
				
			||||
        // unload objects now out of range
 | 
				
			||||
 | 
				
			||||
        if (toRemove.size() > 0) { | 
				
			||||
 | 
				
			||||
            UnloadObjectsMsg uom = new UnloadObjectsMsg(); | 
				
			||||
 | 
				
			||||
            for (AbstractWorldObject obj : toRemove) { | 
				
			||||
 | 
				
			||||
                try { | 
				
			||||
                    if (obj != null) | 
				
			||||
                        if (obj.equals(player)) // don't unload self
 | 
				
			||||
                            continue; | 
				
			||||
 | 
				
			||||
                    uom.addObject(obj); | 
				
			||||
 | 
				
			||||
                    if (obj.getObjectType() == GameObjectType.Mob) | 
				
			||||
                        ((Mob) obj).getPlayerAgroMap().remove(player.getObjectUUID()); | 
				
			||||
                } catch (Exception e) { | 
				
			||||
                    Logger.error("UnloadCharacter", obj.getObjectUUID() + " " + e.getMessage()); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            if (!uom.getObjectList().isEmpty()) { | 
				
			||||
                Dispatch dispatch = Dispatch.borrow(player, uom); | 
				
			||||
                DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        LoadCharacterMsg lcm = null; | 
				
			||||
        ArrayList<AbstractWorldObject> players = new ArrayList<>(); | 
				
			||||
        ArrayList<AbstractWorldObject> addToList = new ArrayList<>(); | 
				
			||||
 | 
				
			||||
        for (AbstractWorldObject awo : toLoadToPlayer) { | 
				
			||||
            // dont load yourself
 | 
				
			||||
            try { | 
				
			||||
                if (awo.equals(player)) | 
				
			||||
                    continue; | 
				
			||||
 | 
				
			||||
                if ((awo.getObjectTypeMask() & MBServerStatics.MASK_PLAYER) != 0) { | 
				
			||||
 | 
				
			||||
                    // object to load is a player
 | 
				
			||||
                    PlayerCharacter awopc = (PlayerCharacter) awo; | 
				
			||||
 | 
				
			||||
                    // dont load if invis
 | 
				
			||||
                    if (player.getSeeInvis() < awopc.getHidden()) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    lcm = new LoadCharacterMsg(awopc, PlayerCharacter.hideNonAscii()); | 
				
			||||
                    players.add(awo); | 
				
			||||
 | 
				
			||||
                    // check if in a group with the person being loaded
 | 
				
			||||
                    // and if so set updateGroup flag
 | 
				
			||||
 | 
				
			||||
                    if (GroupManager.getGroup(player) != null | 
				
			||||
                            && GroupManager.getGroup(player) == GroupManager.getGroup(awopc)) | 
				
			||||
 | 
				
			||||
                        // submit a job as for some reason the client needs a delay
 | 
				
			||||
                        // with group updates
 | 
				
			||||
                        // as it wont update if we do RefreshGroup directly after
 | 
				
			||||
                        // sending the lcm below
 | 
				
			||||
 | 
				
			||||
                        JobScheduler.getInstance().scheduleJob(new RefreshGroupJob(player, awopc), MBServerStatics.LOAD_OBJECT_DELAY); | 
				
			||||
 | 
				
			||||
                } else if ((awo.getObjectTypeMask() & MBServerStatics.MASK_MOB) != 0) { | 
				
			||||
                    Mob awonpc = (Mob) awo; | 
				
			||||
 | 
				
			||||
                    if (!awonpc.isAlive() && (awonpc.isPet() || awonpc.isSiege() || awonpc.isNecroPet() || awonpc.isPlayerGuard())) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    if (awonpc.getState().equals(STATE.Respawn) || awonpc.getState().equals(STATE.Disabled)) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    awonpc.getPlayerAgroMap().put(player.getObjectUUID(), false); | 
				
			||||
                    MobileFSM.setAwake(awonpc, false); | 
				
			||||
                    //				IVarController.setVariable(awonpc, "IntelligenceDisableDelay", (double) (System.currentTimeMillis() + 5000));
 | 
				
			||||
                    //				awonpc.enableIntelligence();
 | 
				
			||||
                    lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii()); | 
				
			||||
                } else if ((awo.getObjectTypeMask() & MBServerStatics.MASK_NPC) != 0) { | 
				
			||||
                    NPC awonpc = (NPC) awo; | 
				
			||||
                    lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii()); | 
				
			||||
                } else if ((awo.getObjectTypeMask() & MBServerStatics.MASK_PET) != 0) { | 
				
			||||
                    Mob awonpc = (Mob) awo; | 
				
			||||
 | 
				
			||||
                    if (!awonpc.isAlive()) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                    awonpc.getPlayerAgroMap().put(player.getObjectUUID(), false); | 
				
			||||
 | 
				
			||||
                    if (awonpc.isMob()) | 
				
			||||
                        MobileFSM.setAwake(awonpc, false); | 
				
			||||
                    //				IVarController.setVariable(awonpc, "IntelligenceDisableDelay", (double) (System.currentTimeMillis() + 5000));
 | 
				
			||||
                    //				awonpc.enableIntelligence();
 | 
				
			||||
                    lcm = new LoadCharacterMsg(awonpc, PlayerCharacter.hideNonAscii()); | 
				
			||||
                } | 
				
			||||
 | 
				
			||||
                addToList.add(awo); | 
				
			||||
 | 
				
			||||
                if (lcm != null) { | 
				
			||||
                    Dispatch dispatch = Dispatch.borrow(player, lcm); | 
				
			||||
                    DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | 
				
			||||
                } | 
				
			||||
 | 
				
			||||
 | 
				
			||||
            } catch (Exception e) { | 
				
			||||
                Logger.error(awo.getObjectUUID() + " " + e.getMessage()); | 
				
			||||
            } | 
				
			||||
            //Delaying character loading to reduce bandwidth consumption
 | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // send effects for all players being loaded
 | 
				
			||||
        // do it on a timer otherwise we may get failures as te client needs
 | 
				
			||||
        // time to process lcm
 | 
				
			||||
        //Added effects to LoadCharacter Serialization.
 | 
				
			||||
        //JobScheduler.getInstance().scheduleJob(new LoadEffectsJob(players, origin), MBServerStatics.LOAD_OBJECT_DELAY);
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    // Forces the loading of static objects (corpses and buildings).
 | 
				
			||||
    // Needed to override threshold limits on loading statics
 | 
				
			||||
 | 
				
			||||
    public static void forceLoad(AbstractWorldObject awo) { | 
				
			||||
 | 
				
			||||
        AbstractNetMsg msg = null; | 
				
			||||
        LoadStructureMsg lsm; | 
				
			||||
        LoadCharacterMsg lcm; | 
				
			||||
        NPC npc; | 
				
			||||
        Corpse corpse; | 
				
			||||
        HashSet<AbstractWorldObject> toUpdate; | 
				
			||||
 | 
				
			||||
        switch (awo.getObjectType()) { | 
				
			||||
            case Building: | 
				
			||||
                lsm = new LoadStructureMsg(); | 
				
			||||
                lsm.addObject((Building) awo); | 
				
			||||
                msg = lsm; | 
				
			||||
                break; | 
				
			||||
            case Corpse: | 
				
			||||
                corpse = (Corpse) awo; | 
				
			||||
                lcm = new LoadCharacterMsg(corpse, false); | 
				
			||||
                msg = lcm; | 
				
			||||
                break; | 
				
			||||
            case NPC: | 
				
			||||
                npc = (NPC) awo; | 
				
			||||
                lcm = new LoadCharacterMsg(npc, false); | 
				
			||||
                msg = lcm; | 
				
			||||
                break; | 
				
			||||
            default: | 
				
			||||
                return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        toUpdate = WorldGrid.getObjectsInRangePartial(awo.getLoc(), MBServerStatics.CHARACTER_LOAD_RANGE, MBServerStatics.MASK_PLAYER); | 
				
			||||
 | 
				
			||||
        boolean send; | 
				
			||||
 | 
				
			||||
        for (AbstractWorldObject tar : toUpdate) { | 
				
			||||
            PlayerCharacter player = (PlayerCharacter) tar; | 
				
			||||
            HashSet<AbstractWorldObject> loadedStaticObjects = player.getLoadedStaticObjects(); | 
				
			||||
            send = false; | 
				
			||||
 | 
				
			||||
            if (!loadedStaticObjects.contains(awo)) { | 
				
			||||
                loadedStaticObjects.add(awo); | 
				
			||||
                send = true; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            if (send) { | 
				
			||||
 | 
				
			||||
                Dispatch dispatch = Dispatch.borrow(player, msg); | 
				
			||||
                DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void HandleSpecialUnload(Building building, ClientConnection origin) { | 
				
			||||
 | 
				
			||||
        if (Regions.FurnitureRegionMap.get(building.getObjectUUID()) == null) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        Regions buildingRegion = Regions.FurnitureRegionMap.get(building.getObjectUUID()); | 
				
			||||
 | 
				
			||||
        if (!buildingRegion.isOutside()) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        MoveToPointMsg moveMsg = new MoveToPointMsg(building); | 
				
			||||
 | 
				
			||||
        if (origin != null) | 
				
			||||
            origin.sendMsg(moveMsg); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public synchronized void HandleLoadForEnterWorld(PlayerCharacter player) { | 
				
			||||
 | 
				
			||||
        if (player == null) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        ClientConnection origin = player.getClientConnection(); | 
				
			||||
 | 
				
			||||
        if (origin == null) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        //Update static list
 | 
				
			||||
        try { | 
				
			||||
            updateStaticList(player, origin); | 
				
			||||
        } catch (Exception e) { | 
				
			||||
            Logger.error("InterestManager.updateAllStaticPlayers: " + player.getObjectUUID(), e); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        //Update mobile list
 | 
				
			||||
        try { | 
				
			||||
            updateMobileList(player, origin); | 
				
			||||
        } catch (Exception e) { | 
				
			||||
            Logger.error("InterestManager.updateAllMobilePlayers: " + player.getObjectUUID(), e); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public synchronized void HandleLoadForTeleport(PlayerCharacter player) { | 
				
			||||
 | 
				
			||||
        if (player == null) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        ClientConnection origin = player.getClientConnection(); | 
				
			||||
 | 
				
			||||
        if (origin == null) | 
				
			||||
            return; | 
				
			||||
 | 
				
			||||
        //Update static list
 | 
				
			||||
        try { | 
				
			||||
            updateStaticList(player, origin); | 
				
			||||
        } catch (Exception e) { | 
				
			||||
            Logger.error("InterestManager.updateAllStaticPlayers: " + player.getObjectUUID(), e); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        //Update mobile list
 | 
				
			||||
        try { | 
				
			||||
            updateMobileList(player, origin); | 
				
			||||
        } catch (Exception e) { | 
				
			||||
            Logger.error("InterestManager.updateAllMobilePlayers: " + player.getObjectUUID(), e); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void reloadCharacter(AbstractCharacter absChar) { | 
				
			||||
 | 
				
			||||
        UnloadObjectsMsg uom = new UnloadObjectsMsg(); | 
				
			||||
        uom.addObject(absChar); | 
				
			||||
        LoadCharacterMsg lcm = new LoadCharacterMsg(absChar, false); | 
				
			||||
 | 
				
			||||
        HashSet<AbstractWorldObject> toSend = WorldGrid.getObjectsInRangePartial(absChar.getLoc(), MBServerStatics.CHARACTER_LOAD_RANGE, | 
				
			||||
                MBServerStatics.MASK_PLAYER); | 
				
			||||
 | 
				
			||||
        PlayerCharacter pc = null; | 
				
			||||
 | 
				
			||||
        if (absChar.getObjectType().equals(GameObjectType.PlayerCharacter)) | 
				
			||||
            pc = (PlayerCharacter) absChar; | 
				
			||||
 | 
				
			||||
        for (AbstractWorldObject awo : toSend) { | 
				
			||||
 | 
				
			||||
            PlayerCharacter pcc = (PlayerCharacter) awo; | 
				
			||||
 | 
				
			||||
            if (pcc == null) | 
				
			||||
                continue; | 
				
			||||
 | 
				
			||||
            ClientConnection cc = SessionManager.getClientConnection(pcc); | 
				
			||||
 | 
				
			||||
            if (cc == null) | 
				
			||||
                continue; | 
				
			||||
 | 
				
			||||
            if (pcc.getObjectUUID() == absChar.getObjectUUID()) | 
				
			||||
                continue; | 
				
			||||
 | 
				
			||||
            else { | 
				
			||||
                if (pc != null) | 
				
			||||
                    if (pcc.getSeeInvis() < pc.getHidden()) | 
				
			||||
                        continue; | 
				
			||||
 | 
				
			||||
                if (!cc.sendMsg(uom)) { | 
				
			||||
                    String classType = uom.getClass().getSimpleName(); | 
				
			||||
                    Logger.error("Failed to send message "); | 
				
			||||
                } | 
				
			||||
 | 
				
			||||
                if (!cc.sendMsg(lcm)) { | 
				
			||||
                    String classType = lcm.getClass().getSimpleName(); | 
				
			||||
                    Logger.error("Failed to send message"); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,102 @@
				@@ -0,0 +1,102 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package engine.InterestManagement; | 
				
			||||
 | 
				
			||||
/* This class is the main interface for Magicbane's | 
				
			||||
*  Interest management facilities. | 
				
			||||
*/ | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.net.Dispatch; | 
				
			||||
import engine.net.DispatchMessage; | 
				
			||||
import engine.net.client.msg.TerritoryChangeMessage; | 
				
			||||
import engine.objects.City; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.objects.Realm; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import engine.util.MapLoader; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import static engine.objects.Realm.getRealm; | 
				
			||||
 | 
				
			||||
public class RealmMap { | 
				
			||||
 | 
				
			||||
    // Spatial hashmap.  Used for detecting which Realm
 | 
				
			||||
    // a player is currently in..
 | 
				
			||||
     | 
				
			||||
    public static int[][] _realmImageMap; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    public static int getRealmIDAtLocation(Vector3fImmutable pos) { | 
				
			||||
 | 
				
			||||
        int xBuckets = (int) ((pos.getX() / MBServerStatics.MAX_WORLD_WIDTH) * MBServerStatics.SPATIAL_HASH_BUCKETSX); | 
				
			||||
        int yBuckets = (int) ((pos.getZ() / MBServerStatics.MAX_WORLD_HEIGHT) * MBServerStatics.SPATIAL_HASH_BUCKETSY); | 
				
			||||
 | 
				
			||||
        if (yBuckets < 0 || yBuckets >= MBServerStatics.SPATIAL_HASH_BUCKETSY | 
				
			||||
                || xBuckets < 0 || xBuckets >= MBServerStatics.SPATIAL_HASH_BUCKETSX) { | 
				
			||||
            Logger.error("WorldServerRealm.getRealmFromPosition", | 
				
			||||
                    "Invalid range; Z: " + yBuckets + ", X: " + xBuckets); | 
				
			||||
            return 255; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return RealmMap._realmImageMap[xBuckets][yBuckets]; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static Realm getRealmForCity(City city) { | 
				
			||||
        Realm outRealm = null; | 
				
			||||
        outRealm = city.getRealm(); | 
				
			||||
        return outRealm; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static Realm getRealmAtLocation(Vector3fImmutable worldVector) { | 
				
			||||
 | 
				
			||||
        return getRealm(RealmMap.getRealmIDAtLocation(worldVector)); | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void updateRealm(PlayerCharacter player){ | 
				
			||||
 | 
				
			||||
        int realmID = RealmMap.getRealmIDAtLocation(player.getLoc()); | 
				
			||||
 | 
				
			||||
        if (realmID != player.getLastRealmID()){ | 
				
			||||
            player.setLastRealmID(realmID); | 
				
			||||
            Realm realm = Realm.getRealm(realmID); | 
				
			||||
            if (realm != null){ | 
				
			||||
                if (realm.isRuled()){ | 
				
			||||
                    City city = realm.getRulingCity(); | 
				
			||||
                    if (city != null){ | 
				
			||||
                        TerritoryChangeMessage tcm = new TerritoryChangeMessage((PlayerCharacter)realm.getRulingCity().getOwner(),realm); | 
				
			||||
                        Dispatch dispatch = Dispatch.borrow(player, tcm); | 
				
			||||
                        DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); | 
				
			||||
                    }else{ | 
				
			||||
                        TerritoryChangeMessage tcm = new TerritoryChangeMessage(null,realm); | 
				
			||||
                        Dispatch dispatch = Dispatch.borrow(player, tcm); | 
				
			||||
                        DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); | 
				
			||||
                    } | 
				
			||||
 | 
				
			||||
                }else{ | 
				
			||||
                    TerritoryChangeMessage tcm = new TerritoryChangeMessage(null,realm); | 
				
			||||
                    Dispatch dispatch = Dispatch.borrow(player, tcm); | 
				
			||||
                    DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void loadRealmImageMap() { | 
				
			||||
 | 
				
			||||
        RealmMap._realmImageMap = MapLoader.loadMap(); | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,312 @@
				@@ -0,0 +1,312 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
package engine.InterestManagement; | 
				
			||||
 | 
				
			||||
import engine.Enum.GridObjectType; | 
				
			||||
import engine.math.FastMath; | 
				
			||||
import engine.math.Vector3f; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.net.DispatchMessage; | 
				
			||||
import engine.net.client.ClientConnection; | 
				
			||||
import engine.net.client.msg.LoadCharacterMsg; | 
				
			||||
import engine.net.client.msg.LoadStructureMsg; | 
				
			||||
import engine.net.client.msg.UnloadObjectsMsg; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
 | 
				
			||||
import java.util.HashSet; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class WorldGrid { | 
				
			||||
	 | 
				
			||||
	public static ConcurrentHashMap<Integer,AbstractWorldObject>[][] DynamicGridMap; | 
				
			||||
	public static ConcurrentHashMap<Integer,AbstractWorldObject>[][] StaticGridMap; | 
				
			||||
	private static float dynamicBucketScale = 0.00390625f; // 256 bucket size, 1/256
 | 
				
			||||
	private static float staticBucketScale = 0.00390625f; | 
				
			||||
	public static void startLoadJob() { | 
				
			||||
 | 
				
			||||
		Thread loadJobThread; | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		loadJobThread = new Thread(InterestManager.INTERESTMANAGER); | 
				
			||||
		loadJobThread.setName("InterestManager"); | 
				
			||||
		loadJobThread.start(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static boolean moveWorldObject(AbstractWorldObject awo, Vector3fImmutable location) { | 
				
			||||
		awo.setLoc(location); | 
				
			||||
		return true; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static HashSet<AbstractWorldObject> getInRange(Vector3f loc, double r) { | 
				
			||||
		HashSet<AbstractWorldObject> outbound = new HashSet<>(); | 
				
			||||
		return outbound; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static HashSet<AbstractWorldObject> getObjectsInRangePartial(Vector3fImmutable loc, double r, int mask) { | 
				
			||||
		HashSet<AbstractWorldObject> outbound = new HashSet<>(); | 
				
			||||
		float scale; | 
				
			||||
		 | 
				
			||||
		if ((mask & MBServerStatics.MASK_STATIC) != 0) | 
				
			||||
			scale = WorldGrid.staticBucketScale; | 
				
			||||
		else | 
				
			||||
			scale = WorldGrid.dynamicBucketScale; | 
				
			||||
		int gridX = (int) Math.abs(loc.x * scale); | 
				
			||||
		int gridZ = (int)Math.abs(loc.z * scale); | 
				
			||||
			int bucketSize = (int) (r *scale) + 1; | 
				
			||||
			//start at top left most corner to scan.
 | 
				
			||||
			int startingX = gridX - bucketSize; | 
				
			||||
			int startingZ = gridZ + bucketSize; | 
				
			||||
			 | 
				
			||||
			 | 
				
			||||
			 | 
				
			||||
			int limitX = Math.abs((int) (MBServerStatics.MAX_WORLD_WIDTH *scale)); | 
				
			||||
			int limitZ = Math.abs((int) (MBServerStatics.MAX_WORLD_HEIGHT *scale)); //LimitZ is negative, remember to flip sign.
 | 
				
			||||
			 | 
				
			||||
			if (startingX < 0) | 
				
			||||
				startingX = 0; | 
				
			||||
			 | 
				
			||||
			if (startingZ < 0) | 
				
			||||
				startingZ = 0; | 
				
			||||
			 | 
				
			||||
			if (startingX > limitX) | 
				
			||||
				startingX = limitX; | 
				
			||||
			 | 
				
			||||
			if (startingZ > limitZ) | 
				
			||||
				startingZ = limitZ; | 
				
			||||
			 | 
				
			||||
			int endX = startingX + (bucketSize * 2); | 
				
			||||
			int endZ = startingZ - (bucketSize * 2); | 
				
			||||
			 | 
				
			||||
			if (endX < 0) | 
				
			||||
				endX = 0; | 
				
			||||
			 | 
				
			||||
			if (endZ < 0) | 
				
			||||
				endZ = 0; | 
				
			||||
			 | 
				
			||||
			if (endX > limitX) | 
				
			||||
				endX = limitX; | 
				
			||||
			 | 
				
			||||
			if (endZ > limitZ) | 
				
			||||
				endZ = limitZ; | 
				
			||||
			 | 
				
			||||
			int auditMob = 0; | 
				
			||||
			for (int x = startingX;x<=endX;x++){ | 
				
			||||
 				for (int z = startingZ;z >= endZ;z--){ | 
				
			||||
 					 | 
				
			||||
 					ConcurrentHashMap<Integer,AbstractWorldObject> gridMap; | 
				
			||||
 					 | 
				
			||||
 					if ((MBServerStatics.MASK_STATIC & mask) != 0) | 
				
			||||
 						gridMap = WorldGrid.StaticGridMap[x][z]; | 
				
			||||
 					else | 
				
			||||
 						gridMap = WorldGrid.DynamicGridMap[x][z]; | 
				
			||||
					for (AbstractWorldObject gridObject: gridMap.values()){ | 
				
			||||
						if ((gridObject.getObjectTypeMask() & mask) == 0) | 
				
			||||
							continue; | 
				
			||||
						if (gridObject.getLoc().distanceSquared2D(loc) <= FastMath.sqr(r)) | 
				
			||||
							outbound.add(gridObject); | 
				
			||||
					} | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
		return outbound; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static HashSet<AbstractWorldObject> getObjectsInRangePartialNecroPets(Vector3fImmutable loc, double r) { | 
				
			||||
		HashSet<AbstractWorldObject> outbound = new HashSet<>(); | 
				
			||||
		return outbound; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static HashSet<AbstractWorldObject> getObjectsInRangeContains(Vector3fImmutable loc, double r, int mask) { | 
				
			||||
		HashSet<AbstractWorldObject> outbound = getObjectsInRangePartial(loc,r,mask); | 
				
			||||
		return outbound; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static HashSet<AbstractWorldObject> getObjectsInRangePartial(AbstractWorldObject awo, double range, int mask) { | 
				
			||||
		return getObjectsInRangePartial(awo.getLoc(), range, mask); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	 | 
				
			||||
	public static void InitializeGridObjects(){ | 
				
			||||
		 | 
				
			||||
		int dynamicWidth = (int) Math.abs(MBServerStatics.MAX_WORLD_WIDTH *WorldGrid.dynamicBucketScale); | 
				
			||||
		int dynamicHeight = (int) Math.abs(MBServerStatics.MAX_WORLD_HEIGHT*WorldGrid.dynamicBucketScale); | 
				
			||||
		 | 
				
			||||
		int staticWidth = (int) Math.abs(MBServerStatics.MAX_WORLD_WIDTH *WorldGrid.staticBucketScale); | 
				
			||||
		int staticHeight = (int) Math.abs(MBServerStatics.MAX_WORLD_HEIGHT*WorldGrid.staticBucketScale); | 
				
			||||
		WorldGrid.DynamicGridMap = new ConcurrentHashMap[dynamicWidth+ 1][dynamicHeight + 1]; | 
				
			||||
		WorldGrid.StaticGridMap = new ConcurrentHashMap[staticWidth + 1][staticHeight + 1]; | 
				
			||||
		//create new hash maps for each bucket
 | 
				
			||||
		for (int x = 0; x<= staticWidth; x++) | 
				
			||||
			for (int y = 0; y<= staticHeight; y++){ | 
				
			||||
				WorldGrid.StaticGridMap[x][y] = new ConcurrentHashMap<Integer,AbstractWorldObject>(); | 
				
			||||
			} | 
				
			||||
		 | 
				
			||||
		for (int x = 0; x<= dynamicWidth; x++) | 
				
			||||
			for (int y = 0; y<= dynamicHeight; y++){ | 
				
			||||
				WorldGrid.DynamicGridMap[x][y] = new ConcurrentHashMap<Integer,AbstractWorldObject>(); | 
				
			||||
			} | 
				
			||||
				 | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public static void RemoveWorldObject(AbstractWorldObject gridObject){ | 
				
			||||
		 | 
				
			||||
		if (gridObject == null) | 
				
			||||
			return; | 
				
			||||
		AbstractWorldObject.RemoveFromWorldGrid(gridObject); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public static boolean addObject(AbstractWorldObject gridObject, float x, float z){ | 
				
			||||
		 | 
				
			||||
		if (gridObject == null) | 
				
			||||
			return false; | 
				
			||||
		 | 
				
			||||
		if (x > MBServerStatics.MAX_WORLD_WIDTH) | 
				
			||||
			return false; | 
				
			||||
		 | 
				
			||||
		if (z < MBServerStatics.MAX_WORLD_HEIGHT) | 
				
			||||
			return false; | 
				
			||||
		 | 
				
			||||
		if (x < 0) | 
				
			||||
			return false; | 
				
			||||
		if (z > 0) | 
				
			||||
			return false; | 
				
			||||
		 | 
				
			||||
		int gridX; | 
				
			||||
		int gridZ; | 
				
			||||
		 | 
				
			||||
		if (gridObject.getGridObjectType().equals(GridObjectType.STATIC)){ | 
				
			||||
			 gridX = Math.abs((int) (x *WorldGrid.staticBucketScale)); | 
				
			||||
			 gridZ = Math.abs((int) (z*WorldGrid.staticBucketScale)); | 
				
			||||
		}else{ | 
				
			||||
			 gridX = Math.abs((int) (x *WorldGrid.dynamicBucketScale)); | 
				
			||||
			 gridZ = Math.abs((int) (z*WorldGrid.dynamicBucketScale)); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		WorldGrid.RemoveWorldObject(gridObject); | 
				
			||||
		 | 
				
			||||
		return AbstractWorldObject.AddToWorldGrid(gridObject, gridX, gridZ); | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
    public static void unloadObject(AbstractWorldObject awo) { | 
				
			||||
 | 
				
			||||
        UnloadObjectsMsg uom = new UnloadObjectsMsg(); | 
				
			||||
        uom.addObject(awo); | 
				
			||||
        DispatchMessage.sendToAllInRange(awo, uom); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	public static void loadObject(AbstractWorldObject awo) { | 
				
			||||
 | 
				
			||||
		LoadStructureMsg lsm; | 
				
			||||
		LoadCharacterMsg lcm; | 
				
			||||
 | 
				
			||||
		switch (awo.getObjectType()) { | 
				
			||||
		case Building: | 
				
			||||
			lsm = new LoadStructureMsg(); | 
				
			||||
			lsm.addObject((Building)awo); | 
				
			||||
			DispatchMessage.sendToAllInRange(awo, lsm); | 
				
			||||
			break; | 
				
			||||
		case NPC: | 
				
			||||
			lcm = new LoadCharacterMsg((NPC) awo, false); | 
				
			||||
			DispatchMessage.sendToAllInRange(awo, lcm); | 
				
			||||
			break; | 
				
			||||
		case Mob: | 
				
			||||
			lcm = new LoadCharacterMsg((Mob) awo, false); | 
				
			||||
			DispatchMessage.sendToAllInRange(awo, lcm); | 
				
			||||
			break; | 
				
			||||
		default: | 
				
			||||
			// *** Refactor: Log error?
 | 
				
			||||
			break; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void loadObject(AbstractWorldObject awo, ClientConnection origin) { | 
				
			||||
 | 
				
			||||
		LoadStructureMsg lsm; | 
				
			||||
		LoadCharacterMsg lcm; | 
				
			||||
 | 
				
			||||
		switch (awo.getObjectType()) { | 
				
			||||
 | 
				
			||||
		case Building: | 
				
			||||
			lsm = new LoadStructureMsg(); | 
				
			||||
			lsm.addObject((Building)awo); | 
				
			||||
			DispatchMessage.sendToAllInRange(awo, lsm); | 
				
			||||
			break; | 
				
			||||
		case NPC: | 
				
			||||
			lcm = new LoadCharacterMsg((NPC) awo, false); | 
				
			||||
			DispatchMessage.sendToAllInRange(awo, lcm); | 
				
			||||
			break; | 
				
			||||
		case Mob: | 
				
			||||
			lcm = new LoadCharacterMsg((Mob) awo, false); | 
				
			||||
			DispatchMessage.sendToAllInRange(awo, lcm); | 
				
			||||
			break; | 
				
			||||
		case PlayerCharacter: | 
				
			||||
			lcm = new LoadCharacterMsg((PlayerCharacter) awo, false); | 
				
			||||
			DispatchMessage.sendToAllInRange(awo, lcm); | 
				
			||||
			break; | 
				
			||||
		default: | 
				
			||||
			// *** Refactor: Log error?
 | 
				
			||||
			break; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void unloadObject(AbstractWorldObject awo, | 
				
			||||
									ClientConnection origin) { | 
				
			||||
		UnloadObjectsMsg uom = new UnloadObjectsMsg(); | 
				
			||||
		uom.addObject(awo); | 
				
			||||
		DispatchMessage.sendToAllInRange(awo, uom); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void addObject(AbstractWorldObject awo, PlayerCharacter pc) { | 
				
			||||
		if (pc == null || awo == null) | 
				
			||||
			return; | 
				
			||||
		ClientConnection origin = pc.getClientConnection(); | 
				
			||||
		if (origin == null) | 
				
			||||
			return; | 
				
			||||
		loadObject(awo, origin); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void removeObject(AbstractWorldObject awo, PlayerCharacter pc) { | 
				
			||||
		if (pc == null || awo == null) | 
				
			||||
			return; | 
				
			||||
		ClientConnection origin = pc.getClientConnection(); | 
				
			||||
		if (origin == null) | 
				
			||||
			return; | 
				
			||||
		unloadObject(awo, origin); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void updateObject(AbstractWorldObject awo, PlayerCharacter pc) { | 
				
			||||
		if (pc == null || awo == null) | 
				
			||||
			return; | 
				
			||||
		ClientConnection origin = pc.getClientConnection(); | 
				
			||||
		if (origin == null) | 
				
			||||
			return; | 
				
			||||
		unloadObject(awo, origin); | 
				
			||||
		loadObject(awo, origin); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void updateObject(AbstractWorldObject awo) { | 
				
			||||
		if (awo == null) | 
				
			||||
			return; | 
				
			||||
		unloadObject(awo); | 
				
			||||
		loadObject(awo); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/* | 
				
			||||
	 * | 
				
			||||
	 */ | 
				
			||||
	public static void removeObject(AbstractWorldObject awo) { | 
				
			||||
		if (awo == null) | 
				
			||||
			return; | 
				
			||||
		unloadObject(awo); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,104 @@
				@@ -0,0 +1,104 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.ai; | 
				
			||||
 | 
				
			||||
import engine.gameManager.ZoneManager; | 
				
			||||
import engine.objects.Mob; | 
				
			||||
import engine.objects.Zone; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import engine.util.ThreadUtils; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.HashSet; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class MobileFSMManager { | 
				
			||||
 | 
				
			||||
	private static final MobileFSMManager INSTANCE = new MobileFSMManager(); | 
				
			||||
 | 
				
			||||
	private volatile boolean alive; | 
				
			||||
	private long timeOfKill = -1; | 
				
			||||
 | 
				
			||||
	private MobileFSMManager() { | 
				
			||||
 | 
				
			||||
		Runnable worker = new Runnable() { | 
				
			||||
			@Override | 
				
			||||
			public void run() { | 
				
			||||
				execution(); | 
				
			||||
			} | 
				
			||||
		}; | 
				
			||||
 | 
				
			||||
		alive = true; | 
				
			||||
 | 
				
			||||
		Thread t = new Thread(worker, "MobileFSMManager"); | 
				
			||||
		t.start(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static MobileFSMManager getInstance() { | 
				
			||||
		return INSTANCE; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * Stops the MobileFSMManager | 
				
			||||
	 */ | 
				
			||||
	public void shutdown() { | 
				
			||||
		if (alive) { | 
				
			||||
			alive = false; | 
				
			||||
			timeOfKill = System.currentTimeMillis(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public long getTimeOfKill() { | 
				
			||||
		return this.timeOfKill; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean isAlive() { | 
				
			||||
		return this.alive; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	private void execution() { | 
				
			||||
 | 
				
			||||
		//Load zone threshold once.
 | 
				
			||||
 | 
				
			||||
		long mobPulse = System.currentTimeMillis() + MBServerStatics.AI_PULSE_MOB_THRESHOLD; | 
				
			||||
 | 
				
			||||
		while (alive) { | 
				
			||||
 | 
				
			||||
			ThreadUtils.sleep(1); | 
				
			||||
 | 
				
			||||
			if (System.currentTimeMillis() > mobPulse) { | 
				
			||||
				 | 
				
			||||
				HashSet<Integer> auditMobs = new HashSet<Integer>(); | 
				
			||||
 | 
				
			||||
				for (Zone zone : ZoneManager.getAllZones()) { | 
				
			||||
 | 
				
			||||
					for (Mob mob : zone.zoneMobSet) { | 
				
			||||
						 | 
				
			||||
						if (auditMobs.contains(mob.getObjectUUID())) | 
				
			||||
							continue; | 
				
			||||
						auditMobs.add(mob.getObjectUUID()); | 
				
			||||
						try { | 
				
			||||
							if (mob != null) | 
				
			||||
								MobileFSM.run(mob); | 
				
			||||
						} catch (Exception e) { | 
				
			||||
							Logger.error(e); | 
				
			||||
							e.printStackTrace(); | 
				
			||||
						} | 
				
			||||
					} | 
				
			||||
				} | 
				
			||||
 | 
				
			||||
				mobPulse = System.currentTimeMillis() + MBServerStatics.AI_PULSE_MOB_THRESHOLD; | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,413 @@
				@@ -0,0 +1,413 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.ai.utilities; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.Enum.*; | 
				
			||||
import engine.ai.MobileFSM.STATE; | 
				
			||||
import engine.gameManager.ChatManager; | 
				
			||||
import engine.gameManager.CombatManager; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.net.DispatchMessage; | 
				
			||||
import engine.net.client.msg.TargetedActionMsg; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.Set; | 
				
			||||
import java.util.concurrent.ThreadLocalRandom; | 
				
			||||
 | 
				
			||||
import static engine.math.FastMath.sqr; | 
				
			||||
 | 
				
			||||
public class CombatUtilities { | 
				
			||||
 | 
				
			||||
	public static boolean inRangeToAttack(Mob agent,AbstractWorldObject target){ | 
				
			||||
 | 
				
			||||
		if (Float.isNaN(agent.getLoc().x)) | 
				
			||||
			return false; | 
				
			||||
 | 
				
			||||
		try{ | 
				
			||||
			Vector3fImmutable sl = agent.getLoc(); | 
				
			||||
			Vector3fImmutable tl = target.getLoc(); | 
				
			||||
			 | 
				
			||||
			//add Hitbox's to range.
 | 
				
			||||
			float range = agent.getRange(); | 
				
			||||
			range += CombatManager.calcHitBox(target) + CombatManager.calcHitBox(agent); | 
				
			||||
			//if (target instanceof AbstractCharacter)
 | 
				
			||||
			//				if (((AbstractCharacter)target).isMoving())
 | 
				
			||||
			//					range+= 5;
 | 
				
			||||
 | 
				
			||||
			return !(sl.distanceSquared(tl) > sqr(range)); | 
				
			||||
		}catch(Exception e){ | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public static boolean inRangeToAttack2D(Mob agent,AbstractWorldObject target){ | 
				
			||||
 | 
				
			||||
		if (Float.isNaN(agent.getLoc().x)) | 
				
			||||
			return false; | 
				
			||||
 | 
				
			||||
		try{ | 
				
			||||
			Vector3fImmutable sl = agent.getLoc(); | 
				
			||||
			Vector3fImmutable tl = target.getLoc(); | 
				
			||||
			 | 
				
			||||
			//add Hitbox's to range.
 | 
				
			||||
			float range = agent.getRange(); | 
				
			||||
			range += CombatManager.calcHitBox(target) + CombatManager.calcHitBox(agent); | 
				
			||||
			//if (target instanceof AbstractCharacter)
 | 
				
			||||
			//				if (((AbstractCharacter)target).isMoving())
 | 
				
			||||
			//					range+= 5;
 | 
				
			||||
 | 
				
			||||
			return !(sl.distanceSquared2D(tl) > sqr(range)); | 
				
			||||
		}catch(Exception e){ | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void swingIsBlock(Mob agent,AbstractWorldObject target, int animation) { | 
				
			||||
 | 
				
			||||
		if (!target.isAlive()) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		TargetedActionMsg msg = new TargetedActionMsg(agent,animation, target, MBServerStatics.COMBAT_SEND_BLOCK); | 
				
			||||
 | 
				
			||||
		if (target.getObjectType() == GameObjectType.PlayerCharacter) | 
				
			||||
			DispatchMessage.dispatchMsgToInterestArea(target, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true,false); | 
				
			||||
		else | 
				
			||||
			DispatchMessage.sendToAllInRange(agent,msg); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void swingIsParry(Mob agent,AbstractWorldObject target, int animation) { | 
				
			||||
 | 
				
			||||
		if (!target.isAlive()) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		TargetedActionMsg msg = new TargetedActionMsg(agent,animation, target,  MBServerStatics.COMBAT_SEND_PARRY); | 
				
			||||
 | 
				
			||||
		if (target.getObjectType() == GameObjectType.PlayerCharacter) | 
				
			||||
			DispatchMessage.dispatchMsgToInterestArea(target, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true,false); | 
				
			||||
		else | 
				
			||||
			DispatchMessage.sendToAllInRange(agent,msg); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void swingIsDodge(Mob agent,AbstractWorldObject target, int animation) { | 
				
			||||
 | 
				
			||||
		if (!target.isAlive()) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		TargetedActionMsg msg = new TargetedActionMsg(agent,animation, target, MBServerStatics.COMBAT_SEND_DODGE); | 
				
			||||
 | 
				
			||||
		if (target.getObjectType() == GameObjectType.PlayerCharacter) | 
				
			||||
			DispatchMessage.dispatchMsgToInterestArea(target, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true,false); | 
				
			||||
		else | 
				
			||||
			DispatchMessage.sendToAllInRange(agent,msg); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void swingIsDamage(Mob agent,AbstractWorldObject target, float damage, int animation){ | 
				
			||||
		float trueDamage = 0; | 
				
			||||
 | 
				
			||||
		if (!target.isAlive()) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		if (AbstractWorldObject.IsAbstractCharacter(target)) | 
				
			||||
			trueDamage = ((AbstractCharacter) target).modifyHealth(-damage, agent, false); | 
				
			||||
		else if (target.getObjectType() == GameObjectType.Building) | 
				
			||||
			trueDamage = ((Building) target).modifyHealth(-damage, agent); | 
				
			||||
 | 
				
			||||
		//Don't send 0 damage kay thanx.
 | 
				
			||||
 | 
				
			||||
		if (trueDamage == 0) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		TargetedActionMsg msg = new TargetedActionMsg(agent,target, damage, animation); | 
				
			||||
 | 
				
			||||
		if (target.getObjectType() == GameObjectType.PlayerCharacter) | 
				
			||||
			DispatchMessage.dispatchMsgToInterestArea(target, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true,false); | 
				
			||||
		else | 
				
			||||
			DispatchMessage.sendToAllInRange(agent,msg); | 
				
			||||
 | 
				
			||||
		//check damage shields
 | 
				
			||||
		if(AbstractWorldObject.IsAbstractCharacter(target) && target.isAlive() && target.getObjectType() != GameObjectType.Mob) | 
				
			||||
			CombatManager.handleDamageShields(agent,(AbstractCharacter)target, damage); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static boolean canSwing(Mob agent) { | 
				
			||||
		return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned, SourceType.None)); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void swingIsMiss(Mob agent,AbstractWorldObject target, int animation) { | 
				
			||||
 | 
				
			||||
		TargetedActionMsg msg = new TargetedActionMsg(agent,target, 0f, animation); | 
				
			||||
 | 
				
			||||
		if (target.getObjectType() == GameObjectType.PlayerCharacter) | 
				
			||||
			DispatchMessage.dispatchMsgToInterestArea(target, msg, DispatchChannel.PRIMARY, MBServerStatics.CHARACTER_LOAD_RANGE, true,false); | 
				
			||||
		else | 
				
			||||
			DispatchMessage.sendToAllInRange(agent,msg); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static boolean triggerDefense(Mob agent, AbstractWorldObject target) { | 
				
			||||
		int defenseScore = 0; | 
				
			||||
		int attackScore = agent.getAtrHandOne(); | 
				
			||||
		switch (target.getObjectType()) { | 
				
			||||
		case PlayerCharacter: | 
				
			||||
			defenseScore = ((AbstractCharacter) target).getDefenseRating(); | 
				
			||||
			break; | 
				
			||||
		case Mob: | 
				
			||||
 | 
				
			||||
			Mob mob = (Mob)target; | 
				
			||||
			if (mob.isSiege()) | 
				
			||||
				defenseScore = attackScore; | 
				
			||||
			break; | 
				
			||||
		case Building: | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		int hitChance; | 
				
			||||
		if (attackScore > defenseScore || defenseScore == 0) | 
				
			||||
			hitChance = 94; | 
				
			||||
		else if (attackScore == defenseScore && target.getObjectType() == GameObjectType.Mob) | 
				
			||||
			hitChance = 10; | 
				
			||||
		else { | 
				
			||||
			float dif = attackScore / defenseScore; | 
				
			||||
			if (dif <= 0.8f) | 
				
			||||
				hitChance = 4; | 
				
			||||
			else | 
				
			||||
				hitChance = ((int)(450 * (dif - 0.8f)) + 4); | 
				
			||||
			if (target.getObjectType() == GameObjectType.Building) | 
				
			||||
				hitChance = 100; | 
				
			||||
		} | 
				
			||||
		return ThreadLocalRandom.current().nextInt(100) > hitChance; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static boolean triggerBlock(Mob agent,AbstractWorldObject ac) { | 
				
			||||
		return triggerPassive(agent,ac, "Block"); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static boolean triggerParry(Mob agent,AbstractWorldObject ac) { | 
				
			||||
		return triggerPassive(agent,ac, "Parry"); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static boolean triggerDodge(Mob agent,AbstractWorldObject ac) { | 
				
			||||
		return triggerPassive(agent,ac, "Dodge"); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static boolean triggerPassive(Mob agent,AbstractWorldObject ac, String type) { | 
				
			||||
		float chance = 0; | 
				
			||||
		if (AbstractWorldObject.IsAbstractCharacter(ac)) | 
				
			||||
			chance = ((AbstractCharacter)ac).getPassiveChance(type, agent.getLevel(), true); | 
				
			||||
 | 
				
			||||
		if (chance > 75f) | 
				
			||||
			chance = 75f; | 
				
			||||
		if (agent.isSiege() && AbstractWorldObject.IsAbstractCharacter(ac)) | 
				
			||||
			chance = 100; | 
				
			||||
 | 
				
			||||
		return ThreadLocalRandom.current().nextInt(100) < chance; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public static void combatCycle(Mob agent,AbstractWorldObject target, boolean mainHand, ItemBase wb) { | 
				
			||||
 | 
				
			||||
		if (!agent.isAlive() || !target.isAlive()) return; | 
				
			||||
 | 
				
			||||
		if (target.getObjectType() == GameObjectType.PlayerCharacter) | 
				
			||||
			if (!((PlayerCharacter)target).isActive()) | 
				
			||||
				return; | 
				
			||||
 | 
				
			||||
		int anim = 75; | 
				
			||||
		float speed = 30f; | 
				
			||||
		if (mainHand) | 
				
			||||
			speed = agent.getSpeedHandOne(); | 
				
			||||
		else | 
				
			||||
			speed = agent.getSpeedHandTwo(); | 
				
			||||
 | 
				
			||||
		DamageType dt = DamageType.Crush; | 
				
			||||
		if (agent.isSiege()) | 
				
			||||
			dt = DamageType.Siege; | 
				
			||||
		if (wb != null) { | 
				
			||||
			anim = CombatManager.getSwingAnimation(wb, null,mainHand); | 
				
			||||
			dt = wb.getDamageType(); | 
				
			||||
		} else if (!mainHand) | 
				
			||||
			return; | 
				
			||||
		Resists res = null; | 
				
			||||
		PlayerBonuses bonus = null; | 
				
			||||
		switch(target.getObjectType()){ | 
				
			||||
		case Building: | 
				
			||||
			res = ((Building)target).getResists(); | 
				
			||||
			break; | 
				
			||||
		case PlayerCharacter: | 
				
			||||
			res = ((PlayerCharacter)target).getResists(); | 
				
			||||
			bonus = ((PlayerCharacter)target).getBonuses(); | 
				
			||||
			break; | 
				
			||||
		case Mob: | 
				
			||||
			Mob mob = (Mob)target; | 
				
			||||
			res = mob.getResists(); | 
				
			||||
			bonus = ((Mob)target).getBonuses(); | 
				
			||||
			break; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		//must not be immune to all or immune to attack
 | 
				
			||||
 | 
				
			||||
		if (bonus != null && !bonus.getBool(ModType.NoMod, SourceType.ImmuneToAttack)) | 
				
			||||
			if (res != null &&(res.immuneToAll() || res.immuneToAttacks() || res.immuneTo(dt))) | 
				
			||||
				return; | 
				
			||||
 | 
				
			||||
		int passiveAnim =  CombatManager.getSwingAnimation(wb, null,mainHand); | 
				
			||||
		if(canSwing(agent)) { | 
				
			||||
			if(triggerDefense(agent,target)) | 
				
			||||
				swingIsMiss(agent,target, passiveAnim); | 
				
			||||
			else if(triggerDodge(agent,target)) | 
				
			||||
				swingIsDodge(agent,target, passiveAnim); | 
				
			||||
			else if(triggerParry(agent,target)) | 
				
			||||
				swingIsParry(agent,target, passiveAnim); | 
				
			||||
			else if(triggerBlock(agent,target)) | 
				
			||||
				swingIsBlock(agent,target, passiveAnim); | 
				
			||||
			else | 
				
			||||
				swingIsDamage(agent,target, determineDamage(agent,target, mainHand, speed, dt), anim); | 
				
			||||
 | 
				
			||||
			if (agent.getWeaponPower() != null) | 
				
			||||
				agent.getWeaponPower().attack(target, MBServerStatics.ONE_MINUTE); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (target.getObjectType().equals(GameObjectType.PlayerCharacter)){ | 
				
			||||
			PlayerCharacter player = (PlayerCharacter)target; | 
				
			||||
			if (player.getDebug(64)){ | 
				
			||||
				ChatManager.chatSayInfo(player, "Debug Combat: Mob UUID " + agent.getObjectUUID() + " || Building ID  = " + agent.getBuildingID() + " || Floor = " + agent.getInFloorID() + " || Level = " + agent.getInBuilding() );//combat debug
 | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		//SIEGE MONSTERS DO NOT ATTACK GUARDSs
 | 
				
			||||
		if (target.getObjectType() == GameObjectType.Mob) | 
				
			||||
			if (((Mob)target).isSiege()) | 
				
			||||
				return; | 
				
			||||
 | 
				
			||||
		//handle the retaliate
 | 
				
			||||
 | 
				
			||||
		if (AbstractWorldObject.IsAbstractCharacter(target)) | 
				
			||||
			CombatManager.handleRetaliate((AbstractCharacter)target, agent); | 
				
			||||
 | 
				
			||||
		if (target.getObjectType() == GameObjectType.Mob){ | 
				
			||||
			Mob targetMob = (Mob)target; | 
				
			||||
			if (targetMob.isSiege()) | 
				
			||||
				return; | 
				
			||||
 | 
				
			||||
			if (System.currentTimeMillis() < targetMob.getTimeStamp("CallForHelp")) | 
				
			||||
				return; | 
				
			||||
			CallForHelp(targetMob); | 
				
			||||
			targetMob.getTimestamps().put("CallForHelp", System.currentTimeMillis() + 60000); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void CallForHelp(Mob aiAgent) { | 
				
			||||
 | 
				
			||||
		Set<Mob> zoneMobs = aiAgent.getParentZone().zoneMobSet; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		AbstractWorldObject target = aiAgent.getCombatTarget(); | 
				
			||||
		if (target == null) { | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		int count = 0; | 
				
			||||
		for (Mob mob: zoneMobs){ | 
				
			||||
			if (!mob.isAlive()) | 
				
			||||
				continue; | 
				
			||||
			if (mob.isSiege() || mob.isPet() || !Enum.MobFlagType.AGGRESSIVE.elementOf(mob.getMobBase().getFlags())) | 
				
			||||
				continue; | 
				
			||||
			if (count == 5) | 
				
			||||
				continue; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			if (mob.getCombatTarget() != null) | 
				
			||||
				continue; | 
				
			||||
 | 
				
			||||
			if (!aiAgent.isPlayerGuard() && mob.isPlayerGuard()) | 
				
			||||
				continue; | 
				
			||||
 | 
				
			||||
			if (aiAgent.isPlayerGuard() && !mob.isPlayerGuard() ) | 
				
			||||
				continue; | 
				
			||||
 | 
				
			||||
			if (target.getObjectType() == GameObjectType.PlayerCharacter){ | 
				
			||||
 | 
				
			||||
				if (!MovementUtilities.inRangeToAggro(mob, (PlayerCharacter)target)) | 
				
			||||
					continue; | 
				
			||||
				count++; | 
				
			||||
 | 
				
			||||
			}else{ | 
				
			||||
 | 
				
			||||
				if (count == 5) | 
				
			||||
					continue; | 
				
			||||
 | 
				
			||||
				if (aiAgent.getLoc().distanceSquared2D(target.getLoc()) > sqr(aiAgent.getAggroRange())) | 
				
			||||
					continue; | 
				
			||||
 | 
				
			||||
				count++; | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			if (mob.getState() == STATE.Awake || mob.getState() == STATE.Patrol){ | 
				
			||||
				mob.setCombatTarget(target); | 
				
			||||
				mob.setState(STATE.Attack); | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static float determineDamage(Mob agent,AbstractWorldObject target, boolean mainHand, float speed, DamageType dt) { | 
				
			||||
 | 
				
			||||
		float min = (mainHand) ? agent.getMinDamageHandOne() : agent.getMinDamageHandTwo(); | 
				
			||||
		float max = (mainHand) ? agent.getMaxDamageHandOne() : agent.getMaxDamageHandTwo();; | 
				
			||||
 | 
				
			||||
		float range = max - min; | 
				
			||||
		float damage = min + ((ThreadLocalRandom.current().nextFloat()*range)+(ThreadLocalRandom.current().nextFloat()*range))/2; | 
				
			||||
 | 
				
			||||
		if (AbstractWorldObject.IsAbstractCharacter(target)) | 
				
			||||
			if (((AbstractCharacter)target).isSit()) | 
				
			||||
				damage *= 2.5f; //increase damage if sitting
 | 
				
			||||
 | 
				
			||||
		if (AbstractWorldObject.IsAbstractCharacter(target)) | 
				
			||||
			return ((AbstractCharacter)target).getResists().getResistedDamage(agent,(AbstractCharacter)target, dt, damage, 0); | 
				
			||||
 | 
				
			||||
		if (target.getObjectType() == GameObjectType.Building){ | 
				
			||||
			Building building = (Building)target; | 
				
			||||
			Resists resists = building.getResists(); | 
				
			||||
			return damage * (1 - (resists.getResist(dt, 0) / 100)); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return damage; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public static boolean RunAIRandom(){ | 
				
			||||
		int random = ThreadLocalRandom.current().nextInt(4); | 
				
			||||
		 | 
				
			||||
		if (random == 0) | 
				
			||||
			return true; | 
				
			||||
		 | 
				
			||||
		return false; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,303 @@
				@@ -0,0 +1,303 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.ai.utilities; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.Enum.ModType; | 
				
			||||
import engine.Enum.SourceType; | 
				
			||||
import engine.exception.MsgSendException; | 
				
			||||
import engine.gameManager.MovementManager; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.net.client.msg.MoveToPointMsg; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.concurrent.ThreadLocalRandom; | 
				
			||||
 | 
				
			||||
import static engine.math.FastMath.sqr; | 
				
			||||
import static engine.math.FastMath.sqrt; | 
				
			||||
 | 
				
			||||
public class MovementUtilities { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public static boolean inRangeOfBindLocation(Mob agent){ | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		if (agent.isPlayerGuard()){ | 
				
			||||
			 | 
				
			||||
			Mob guardCaptain = null; | 
				
			||||
			if (agent.getContract() != null) | 
				
			||||
				guardCaptain = agent; | 
				
			||||
			else | 
				
			||||
		guardCaptain = (Mob) agent.getNpcOwner(); | 
				
			||||
			 | 
				
			||||
			if (guardCaptain != null){ | 
				
			||||
				Building barracks = guardCaptain.getBuilding(); | 
				
			||||
				 | 
				
			||||
				if (barracks != null){ | 
				
			||||
					City city = barracks.getCity(); | 
				
			||||
					 | 
				
			||||
					if (city != null){ | 
				
			||||
						Building tol = city.getTOL(); | 
				
			||||
						 | 
				
			||||
						//Guards recall distance = 814.
 | 
				
			||||
						if (tol != null){ | 
				
			||||
							if (agent.getLoc().distanceSquared2D(tol.getLoc()) > sqr(Enum.CityBoundsType.SIEGE.extents)) { | 
				
			||||
					                return false; | 
				
			||||
					            } | 
				
			||||
						} | 
				
			||||
						 | 
				
			||||
					} | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
			 | 
				
			||||
			return true; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		Vector3fImmutable sl = new Vector3fImmutable(agent.getLoc().getX(), 0, agent.getLoc().getZ()); | 
				
			||||
		Vector3fImmutable tl = new Vector3fImmutable(agent.getTrueBindLoc().x,0,agent.getTrueBindLoc().z); | 
				
			||||
 | 
				
			||||
		float distanceSquaredToTarget = sl.distanceSquared2D(tl); //distance to center of target
 | 
				
			||||
		float zoneRange = 250; | 
				
			||||
 | 
				
			||||
		if (agent.getParentZone() != null){ | 
				
			||||
			if (agent.getParentZone().getBounds() != null) | 
				
			||||
				zoneRange = agent.getParentZone().getBounds().getHalfExtents().x * 2; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		if (zoneRange > 300) | 
				
			||||
			zoneRange = 300; | 
				
			||||
		 | 
				
			||||
		if (agent.getSpawnRadius() > zoneRange) | 
				
			||||
			zoneRange = agent.getSpawnRadius(); | 
				
			||||
		 | 
				
			||||
 | 
				
			||||
		return distanceSquaredToTarget < sqr(MBServerStatics.AI_DROP_AGGRO_RANGE + zoneRange); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static boolean inRangeToAggro(Mob agent,PlayerCharacter target){ | 
				
			||||
 | 
				
			||||
		Vector3fImmutable sl = agent.getLoc(); | 
				
			||||
		Vector3fImmutable tl =target.getLoc(); | 
				
			||||
 | 
				
			||||
		float distanceSquaredToTarget = sl.distanceSquared2D(tl) - sqr(agent.calcHitBox() + target.calcHitBox()); //distance to center of target
 | 
				
			||||
		float range = MBServerStatics.AI_BASE_AGGRO_RANGE; | 
				
			||||
 | 
				
			||||
		if (agent.isPlayerGuard()) | 
				
			||||
			range = 150; | 
				
			||||
 | 
				
			||||
		return distanceSquaredToTarget < sqr(range); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static boolean inRangeDropAggro(Mob agent,PlayerCharacter target){ | 
				
			||||
 | 
				
			||||
		Vector3fImmutable sl = agent.getLoc(); | 
				
			||||
		Vector3fImmutable tl = target.getLoc(); | 
				
			||||
 | 
				
			||||
		float distanceSquaredToTarget = sl.distanceSquared2D(tl) - sqr(agent.calcHitBox() + target.calcHitBox()); //distance to center of target
 | 
				
			||||
 | 
				
			||||
		float range = agent.getRange() + 150; | 
				
			||||
 | 
				
			||||
		if (range > 200) | 
				
			||||
			range = 200; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		return distanceSquaredToTarget < sqr(range); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static Vector3fImmutable GetMoveLocation(Mob aiAgent, AbstractCharacter aggroTarget){ | 
				
			||||
 | 
				
			||||
		// Player isnt moving and neither is mob.  Just return
 | 
				
			||||
		// the mobile's current location.  Ain't goin nowhere!
 | 
				
			||||
		// *** Refactor: Check to ensure methods calling us
 | 
				
			||||
		// all don't sent move messages when not moving.
 | 
				
			||||
 | 
				
			||||
		if ((aggroTarget.isMoving() == false)) | 
				
			||||
			return aggroTarget.getLoc(); | 
				
			||||
 | 
				
			||||
		if (aggroTarget.getEndLoc().x != 0){ | 
				
			||||
 | 
				
			||||
			float aggroTargetDistanceSquared = aggroTarget.getLoc().distanceSquared2D(aggroTarget.getEndLoc()); | 
				
			||||
			float aiAgentDistanceSquared = aiAgent.getLoc().distanceSquared2D(aggroTarget.getEndLoc()); | 
				
			||||
 | 
				
			||||
			if (aiAgentDistanceSquared >= aggroTargetDistanceSquared) | 
				
			||||
				return aggroTarget.getEndLoc(); | 
				
			||||
			else{ | 
				
			||||
				float distanceToMove = sqrt(aggroTargetDistanceSquared + aiAgentDistanceSquared) *.5f; | 
				
			||||
 | 
				
			||||
				return aggroTarget.getFaceDir().scaleAdd(distanceToMove, aggroTarget.getLoc()); | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		// One of us is moving so let's calculate our destination loc for this
 | 
				
			||||
		// simulation frame.  We will simply project our position onto the
 | 
				
			||||
		// character's movement vector and return the closest point.
 | 
				
			||||
 | 
				
			||||
		return aiAgent.getLoc().ClosestPointOnLine(aggroTarget.getLoc(), aggroTarget.getEndLoc()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void moveToLocation(Mob agent,Vector3fImmutable newLocation, float offset){ | 
				
			||||
		try { | 
				
			||||
			 | 
				
			||||
			//don't move farther than 30 units from player.
 | 
				
			||||
			if (offset > 30) | 
				
			||||
				offset = 30; | 
				
			||||
			Vector3fImmutable newLoc = Vector3fImmutable.getRandomPointInCircle(newLocation, offset); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			agent.setFaceDir(newLoc.subtract2D(agent.getLoc()).normalize()); | 
				
			||||
		 | 
				
			||||
			aiMove(agent,newLoc,false); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public static boolean canMove(Mob agent) { | 
				
			||||
		if (agent.getMobBase() != null && Enum.MobFlagType.SENTINEL.elementOf(agent.getMobBase().getFlags())) | 
				
			||||
			return false; | 
				
			||||
 | 
				
			||||
		return (agent.isAlive() && !agent.getBonuses().getBool(ModType.Stunned,SourceType.None) && !agent.getBonuses().getBool(ModType.CannotMove, SourceType.None)); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static Vector3fImmutable randomPatrolLocation(Mob agent,Vector3fImmutable center, float radius){ | 
				
			||||
 | 
				
			||||
		//Determing where I want to move.
 | 
				
			||||
		return new Vector3fImmutable((center.x - radius) + ((ThreadLocalRandom.current().nextFloat()+.1f*2)*radius), | 
				
			||||
				center.y, | 
				
			||||
				(center.z - radius) + ((ThreadLocalRandom.current().nextFloat()+.1f *2)*radius)); | 
				
			||||
	} | 
				
			||||
	public static Long estimateMovementTime(Mob agent) { | 
				
			||||
		if(agent.getEndLoc().x == 0 && agent.getEndLoc().y == 0) | 
				
			||||
			return 0L; | 
				
			||||
 | 
				
			||||
		return (long) ((agent.getLoc().distance2D(agent.getEndLoc())*1000)/agent.getSpeed()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void aiMove(Mob agent,Vector3fImmutable vect, boolean isWalking) { | 
				
			||||
 | 
				
			||||
		//update our walk/run state.
 | 
				
			||||
		if (isWalking && !agent.isWalk()){ | 
				
			||||
			agent.setWalkMode(true); | 
				
			||||
			MovementManager.sendRWSSMsg(agent); | 
				
			||||
		}else if(!isWalking && agent.isWalk()){ | 
				
			||||
			agent.setWalkMode(false); | 
				
			||||
			MovementManager.sendRWSSMsg(agent); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		MoveToPointMsg msg = new MoveToPointMsg(); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
//		Regions currentRegion = Mob.InsideBuildingRegion(agent);
 | 
				
			||||
//
 | 
				
			||||
//		if (currentRegion != null){
 | 
				
			||||
//
 | 
				
			||||
//
 | 
				
			||||
//			if (currentRegion.isGroundLevel()){
 | 
				
			||||
//				agent.setInBuilding(0);
 | 
				
			||||
//				agent.setInFloorID(-1);
 | 
				
			||||
//			}else{
 | 
				
			||||
//				agent.setInBuilding(currentRegion.getLevel());
 | 
				
			||||
//				agent.setInFloorID(currentRegion.getRoom());
 | 
				
			||||
//			}
 | 
				
			||||
//		}else{
 | 
				
			||||
//			agent.setInBuilding(-1);
 | 
				
			||||
//			agent.setInFloorID(-1);
 | 
				
			||||
//			agent.setInBuildingID(0);
 | 
				
			||||
//		}
 | 
				
			||||
//		agent.setLastRegion(currentRegion);
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		Vector3fImmutable startLoc = null; | 
				
			||||
		Vector3fImmutable endLoc = null; | 
				
			||||
 | 
				
			||||
//		if (agent.getLastRegion() != null){
 | 
				
			||||
//			Building inBuilding = Building.getBuildingFromCache(agent.getInBuildingID());
 | 
				
			||||
//			if (inBuilding != null){
 | 
				
			||||
//				startLoc = ZoneManager.convertWorldToLocal(inBuilding, agent.getLoc());
 | 
				
			||||
//				endLoc = ZoneManager.convertWorldToLocal(inBuilding, vect);
 | 
				
			||||
//			}
 | 
				
			||||
//		}else{
 | 
				
			||||
//			agent.setBuildingID(0);
 | 
				
			||||
//			agent.setInBuildingID(0);
 | 
				
			||||
//			startLoc = agent.getLoc();
 | 
				
			||||
//			endLoc = vect;
 | 
				
			||||
//		}
 | 
				
			||||
		 | 
				
			||||
		startLoc = agent.getLoc(); | 
				
			||||
		endLoc = vect; | 
				
			||||
 | 
				
			||||
		msg.setSourceType(GameObjectType.Mob.ordinal()); | 
				
			||||
		msg.setSourceID(agent.getObjectUUID()); | 
				
			||||
		msg.setStartCoord(startLoc); | 
				
			||||
		msg.setEndCoord(endLoc); | 
				
			||||
		msg.setUnknown01(-1); | 
				
			||||
		msg.setInBuilding(-1); | 
				
			||||
		msg.setTargetType(0); | 
				
			||||
		msg.setTargetID(0); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			MovementManager.movement(msg, agent); | 
				
			||||
		} catch (MsgSendException e) { | 
				
			||||
			// TODO Figure out how we want to handle the msg send exception
 | 
				
			||||
			e.printStackTrace(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public static Vector3fImmutable GetDestinationToCharacter(Mob aiAgent, AbstractCharacter character){ | 
				
			||||
		 | 
				
			||||
		if (!character.isMoving()) | 
				
			||||
			return character.getLoc(); | 
				
			||||
			 | 
				
			||||
		 | 
				
			||||
		float agentDistanceEndLoc = aiAgent.getLoc().distanceSquared2D(character.getEndLoc()); | 
				
			||||
		float characterDistanceEndLoc = character.getLoc().distanceSquared2D(character.getEndLoc()); | 
				
			||||
		 | 
				
			||||
		if (agentDistanceEndLoc > characterDistanceEndLoc) | 
				
			||||
			return character.getEndLoc(); | 
				
			||||
		 | 
				
			||||
		return character.getLoc(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public static boolean updateMovementToCharacter(Mob aiAgent, AbstractCharacter aggroTarget){ | 
				
			||||
		 | 
				
			||||
		if (aiAgent.destination.equals(Vector3fImmutable.ZERO)) | 
				
			||||
			return true; | 
				
			||||
		 | 
				
			||||
		if (!aiAgent.isMoving()) | 
				
			||||
			return true; | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		if (aggroTarget.isMoving()){ | 
				
			||||
		if (!aiAgent.destination.equals(aggroTarget.getEndLoc()) && !aiAgent.destination.equals(aggroTarget.getLoc())) | 
				
			||||
			return true; | 
				
			||||
		}else{ | 
				
			||||
			if (aiAgent.destination.equals(aggroTarget.getLoc())) | 
				
			||||
				return false; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		return false; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,15 @@
				@@ -0,0 +1,15 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.ai.utilities; | 
				
			||||
 | 
				
			||||
public class PowerUtilities { | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,174 @@
				@@ -0,0 +1,174 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.core; | 
				
			||||
 | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 *  | 
				
			||||
 */ | 
				
			||||
public abstract class ControlledRunnable implements Runnable { | 
				
			||||
	protected boolean runCmd = false; | 
				
			||||
	protected boolean runStatus = false; | 
				
			||||
	private Thread thisThread; | 
				
			||||
	private final String threadName; | 
				
			||||
 | 
				
			||||
	public ControlledRunnable(String threadName) { | 
				
			||||
		super(); | 
				
			||||
		this.threadName = threadName; | 
				
			||||
		ControlledRunnable.runnables.add(this); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/* | 
				
			||||
	 * Main loop | 
				
			||||
	 */ | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * This is the method called when ControlledRunnable.thisThread.start() is | 
				
			||||
	 * called. | 
				
			||||
	 */ | 
				
			||||
	@Override | 
				
			||||
	public void run() { | 
				
			||||
		if (this._preRun() == false) { | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		this.runStatus = true; | 
				
			||||
 | 
				
			||||
		if (this._Run() == false) { | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		if (this._postRun() == false) { | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		this.runStatus = false; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * _preRun() is called prior to the call to _Run(), but after _startup() | 
				
			||||
	 *  | 
				
			||||
	 * @return | 
				
			||||
	 */ | 
				
			||||
	protected abstract boolean _preRun(); | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * _Run() is called after _startup() and contains should contain the main | 
				
			||||
	 * loop. | 
				
			||||
	 *  | 
				
			||||
	 * @return | 
				
			||||
	 */ | 
				
			||||
	protected abstract boolean _Run(); | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * _postRun() is called after _Run() exits, not necessarily before | 
				
			||||
	 * _shutdown() | 
				
			||||
	 *  | 
				
			||||
	 * @return | 
				
			||||
	 */ | 
				
			||||
	protected abstract boolean _postRun(); | 
				
			||||
 | 
				
			||||
	/* | 
				
			||||
	 * Control | 
				
			||||
	 */ | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * startup() initializes the internal thread, sets the runCMD to true, and | 
				
			||||
	 * calls _startup() prior to starting of the internal Thread. | 
				
			||||
	 */ | 
				
			||||
	public void startup() { | 
				
			||||
 | 
				
			||||
		this.thisThread = new Thread(this, this.threadName); | 
				
			||||
		this.runCmd = true; | 
				
			||||
		this._startup(); | 
				
			||||
		this.thisThread.start(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * This method is called just before ControlledRunnable.thisThread.start() | 
				
			||||
	 * is called. | 
				
			||||
	 */ | 
				
			||||
	protected abstract void _startup(); | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * This method is called to request a shutdown of the runnable. | 
				
			||||
	 */ | 
				
			||||
	public void shutdown() { | 
				
			||||
		this.runCmd = false; | 
				
			||||
		this._shutdown(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * This method is called just after ControlledRunnable.runCmd is set to | 
				
			||||
	 * False. | 
				
			||||
	 */ | 
				
			||||
	protected abstract void _shutdown(); | 
				
			||||
 | 
				
			||||
	/* | 
				
			||||
	 * Getters n setters | 
				
			||||
	 */ | 
				
			||||
	public boolean getRunCmd() { | 
				
			||||
		return runCmd; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean getRunStatus() { | 
				
			||||
		return runStatus; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/* | 
				
			||||
	 * Blockers | 
				
			||||
	 */ | 
				
			||||
	public void blockTillRunStatus(boolean status) { | 
				
			||||
		while (this.runStatus != status) { | 
				
			||||
			try { | 
				
			||||
				System.out.println("BLOCKING"); | 
				
			||||
				Thread.sleep(25L); | 
				
			||||
			} catch (InterruptedException e) { | 
				
			||||
				Logger.debug( e.getMessage()); | 
				
			||||
 | 
				
			||||
				break; | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * @return the thisThread | 
				
			||||
	 */ | 
				
			||||
	protected Thread getThisThread() { | 
				
			||||
		return thisThread; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * @return the threadName | 
				
			||||
	 */ | 
				
			||||
	public String getThreadName() { | 
				
			||||
		return threadName; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/* | 
				
			||||
	 * Instance monitoring and tools | 
				
			||||
	 */ | 
				
			||||
 | 
				
			||||
	// Runnable tracking
 | 
				
			||||
	private static final ArrayList<ControlledRunnable> runnables = new ArrayList<>(); | 
				
			||||
 | 
				
			||||
	public static void shutdownAllRunnables() { | 
				
			||||
		for (ControlledRunnable cr : ControlledRunnable.runnables) { | 
				
			||||
			//Use Direct logging since JobManager is a runnable.
 | 
				
			||||
            Logger.info("ControlledRunnable", | 
				
			||||
					"Sending Shutdown cmd to: " + cr.threadName); | 
				
			||||
			cr.shutdown(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,383 @@
				@@ -0,0 +1,383 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.archive; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.objects.Bane; | 
				
			||||
import engine.objects.City; | 
				
			||||
import engine.workthreads.WarehousePushThread; | 
				
			||||
import org.joda.time.DateTime; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.*; | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.util.concurrent.LinkedBlockingQueue; | 
				
			||||
 | 
				
			||||
import static engine.Enum.RecordEventType; | 
				
			||||
 | 
				
			||||
public class BaneRecord extends DataRecord { | 
				
			||||
 | 
				
			||||
	private static final LinkedBlockingQueue<BaneRecord> recordPool = new LinkedBlockingQueue<>(); | 
				
			||||
	private RecordEventType eventType; | 
				
			||||
	private String cityHash; | 
				
			||||
	private String cityName; | 
				
			||||
	private String cityGuildHash; | 
				
			||||
	private String cityNationHash; | 
				
			||||
	private String baneDropperHash; | 
				
			||||
	private String baneGuildHash; | 
				
			||||
	private String baneNationHash; | 
				
			||||
	private DateTime baneLiveTime; | 
				
			||||
	private DateTime baneDropTime; | 
				
			||||
 | 
				
			||||
	private BaneRecord(Bane bane) { | 
				
			||||
		this.recordType = Enum.DataRecordType.BANE; | 
				
			||||
		this.eventType = RecordEventType.PENDING; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static BaneRecord borrow(Bane bane, RecordEventType eventType) { | 
				
			||||
		BaneRecord baneRecord; | 
				
			||||
 | 
				
			||||
		baneRecord = recordPool.poll(); | 
				
			||||
 | 
				
			||||
		if (baneRecord == null) { | 
				
			||||
			baneRecord = new BaneRecord(bane); | 
				
			||||
			baneRecord.eventType = eventType; | 
				
			||||
		} | 
				
			||||
		else { | 
				
			||||
			baneRecord.recordType = Enum.DataRecordType.BANE; | 
				
			||||
			baneRecord.eventType = eventType; | 
				
			||||
 | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		baneRecord.cityHash = bane.getCity().getHash(); | 
				
			||||
		baneRecord.cityName = bane.getCity().getCityName(); | 
				
			||||
		baneRecord.cityGuildHash = bane.getCity().getGuild().getHash(); | 
				
			||||
		baneRecord.cityNationHash = bane.getCity().getGuild().getNation().getHash(); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		if (bane.getOwner() == null) { | 
				
			||||
			baneRecord.baneDropperHash = "ERRANT"; | 
				
			||||
			baneRecord.baneGuildHash = "ERRANT"; | 
				
			||||
			baneRecord.baneNationHash = "ERRANT"; | 
				
			||||
		} | 
				
			||||
		else { | 
				
			||||
			baneRecord.baneDropperHash = DataWarehouse.hasher.encrypt(bane.getOwner().getObjectUUID());  // getPlayerCharacter didn't check hash first?  OMFG
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			baneRecord.baneGuildHash = bane.getOwner().getGuild().getHash(); | 
				
			||||
			baneRecord.baneNationHash = bane.getOwner().getGuild().getNation().getHash(); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			baneRecord.baneLiveTime = bane.getLiveDate(); | 
				
			||||
			baneRecord.baneDropTime = bane.getPlacementDate(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		return baneRecord; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static PreparedStatement buildBanePushStatement(Connection connection, ResultSet rs) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "INSERT INTO `warehouse_banehistory` (`event_number`, `city_id`, `city_name`, `char_id`, `offGuild_id`, `offNat_id`, `defGuild_id`, `defNat_id`, `dropDatetime`, `liveDateTime`, `resolution`) VALUES(?,?,?,?,?,?,?,?,?,?,?)"; | 
				
			||||
		java.util.Date sqlDateTime; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
		// Bind record data
 | 
				
			||||
 | 
				
			||||
		outStatement.setInt(1, rs.getInt("event_number")); | 
				
			||||
		outStatement.setString(2, rs.getString("city_id")); | 
				
			||||
		outStatement.setString(3, rs.getString("city_name")); | 
				
			||||
		outStatement.setString(4, rs.getString("char_id")); | 
				
			||||
		outStatement.setString(5, rs.getString("offGuild_id")); | 
				
			||||
		outStatement.setString(6, rs.getString("offNat_id")); | 
				
			||||
		outStatement.setString(7, rs.getString("defGuild_id")); | 
				
			||||
		outStatement.setString(8, rs.getString("defNat_id")); | 
				
			||||
 | 
				
			||||
		sqlDateTime = rs.getTimestamp("dropDatetime"); | 
				
			||||
 | 
				
			||||
		if (sqlDateTime == null) | 
				
			||||
			outStatement.setNull(9, Types.DATE); | 
				
			||||
		else | 
				
			||||
			outStatement.setTimestamp(9, rs.getTimestamp("dropDatetime")); | 
				
			||||
 | 
				
			||||
		sqlDateTime = rs.getTimestamp("dropDatetime"); | 
				
			||||
 | 
				
			||||
		if (sqlDateTime == null) | 
				
			||||
			outStatement.setNull(10, Types.DATE); | 
				
			||||
		else | 
				
			||||
			outStatement.setTimestamp(10, rs.getTimestamp("liveDateTime")); | 
				
			||||
 | 
				
			||||
		outStatement.setString(11, rs.getString("resolution")); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static PreparedStatement buildBaneQueryStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "SELECT * FROM `warehouse_banehistory` WHERE `event_number` > ?"; | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
		outStatement.setInt(1, WarehousePushThread.baneIndex); | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static DateTime getLastBaneDateTime(City city) { | 
				
			||||
 | 
				
			||||
		DateTime outDateTime = null; | 
				
			||||
 | 
				
			||||
		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = buildDateTimeQueryStatement(connection, city); | 
				
			||||
				ResultSet rs = statement.executeQuery()) { | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				outDateTime = new DateTime(rs.getTimestamp("endDatetime")); | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return outDateTime; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	private static PreparedStatement buildDateTimeQueryStatement (Connection connection, City city) throws SQLException { | 
				
			||||
		PreparedStatement outStatement; | 
				
			||||
		String queryString = "SELECT `endDatetime` FROM `warehouse_banehistory` WHERE `city_id` = ? ORDER BY `endDatetime` DESC LIMIT 1"; | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
		outStatement.setString(1, city.getHash()); | 
				
			||||
		return outStatement; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void updateLiveDate(Bane bane, DateTime dateTime) { | 
				
			||||
 | 
				
			||||
		if (bane == null) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = buildUpdateLiveDateStatement(connection, bane, dateTime)) { | 
				
			||||
 | 
				
			||||
			statement.execute(); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private static PreparedStatement buildUpdateLiveDateStatement(Connection connection, Bane bane, DateTime dateTime) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "UPDATE `warehouse_banehistory` SET `liveDatetime` = ?, `dirty` = 1 WHERE `city_id` = ? AND `resolution` = 'PENDING'"; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
		outStatement.setTimestamp(1, new java.sql.Timestamp(dateTime.getMillis())); | 
				
			||||
		outStatement.setString(2, bane.getCity().getHash()); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private static PreparedStatement buildUpdateResolutionStatement(Connection connection, Bane bane, RecordEventType eventType) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "UPDATE `warehouse_banehistory` SET `endDatetime` = ?, `resolution` = ?, `dirty` = 1 WHERE `city_id` = ? AND `resolution` = 'PENDING'"; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
		outStatement.setTimestamp(1, Timestamp.valueOf(LocalDateTime.now())); | 
				
			||||
		outStatement.setString(2, eventType.name()); | 
				
			||||
		outStatement.setString(3, bane.getCity().getHash()); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void updateResolution(Bane bane, RecordEventType eventType) { | 
				
			||||
 | 
				
			||||
		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = buildUpdateResolutionStatement(connection, bane, eventType)) { | 
				
			||||
 | 
				
			||||
			statement.execute(); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.toString()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static String getBaneHistoryString() { | 
				
			||||
 | 
				
			||||
		String outString; | 
				
			||||
		String queryString; | 
				
			||||
		String dividerString; | 
				
			||||
		String newLine = System.getProperty("line.separator"); | 
				
			||||
		outString = "[LUA_BANES() DATA WAREHOUSE]" + newLine; | 
				
			||||
		dividerString = "--------------------------------" + newLine; | 
				
			||||
		queryString = "CALL `baneHistory`()"; | 
				
			||||
 | 
				
			||||
		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = connection.prepareCall(queryString); | 
				
			||||
				ResultSet rs = statement.executeQuery()) { | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				outString += "Magicbane unresolved banes: " + rs.getInt("PENDING") + '/' + rs.getInt("TOTAL") + newLine; | 
				
			||||
				outString += dividerString; | 
				
			||||
				outString += "Bane Resolution History" + newLine; | 
				
			||||
				outString += dividerString; | 
				
			||||
 | 
				
			||||
				outString += "Destruction: " + rs.getInt("DESTROY") + newLine; | 
				
			||||
				outString += "Capture: " + rs.getInt("CAPTURE") + newLine; | 
				
			||||
				outString += "Defended: " + rs.getInt("DEFEND") + newLine; | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			e.printStackTrace(); | 
				
			||||
		} | 
				
			||||
		return outString; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void updateDirtyRecords() { | 
				
			||||
 | 
				
			||||
		String queryString = "SELECT * FROM `warehouse_banehistory` where `dirty` = 1"; | 
				
			||||
 | 
				
			||||
		// Reset character delta
 | 
				
			||||
 | 
				
			||||
		WarehousePushThread.baneDelta = 0; | 
				
			||||
 | 
				
			||||
		try (Connection localConnection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = localConnection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); // Make this an updatable result set as we'll reset the dirty flag as we go along
 | 
				
			||||
				ResultSet rs = statement.executeQuery()) { | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				// Only update the index and dirty flag
 | 
				
			||||
				// if the remote database update succeeded
 | 
				
			||||
 | 
				
			||||
				if (updateDirtyRecord(rs) == true) | 
				
			||||
					WarehousePushThread.baneDelta++; | 
				
			||||
				else | 
				
			||||
					continue; | 
				
			||||
 | 
				
			||||
				// Reset the dirty flag in the local database
 | 
				
			||||
 | 
				
			||||
				rs.updateInt("dirty", 0); | 
				
			||||
				rs.updateRow(); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private static boolean updateDirtyRecord(ResultSet rs) { | 
				
			||||
 | 
				
			||||
		try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = buildUpdateDirtyStatement(remoteConnection, rs)) { | 
				
			||||
 | 
				
			||||
			statement.execute(); | 
				
			||||
			return true; | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private static PreparedStatement buildUpdateDirtyStatement(Connection connection, ResultSet rs) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement; | 
				
			||||
		String queryString = "UPDATE `warehouse_banehistory` SET `liveDateTime` = ?, `endDateTime` = ?, `resolution` = ? WHERE `event_number` = ?"; | 
				
			||||
		java.util.Date sqlDateTime; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
		// Bind record data
 | 
				
			||||
 | 
				
			||||
		sqlDateTime = rs.getTimestamp("liveDateTime"); | 
				
			||||
 | 
				
			||||
		if (sqlDateTime == null) | 
				
			||||
			outStatement.setNull(1, Types.DATE); | 
				
			||||
		else | 
				
			||||
			outStatement.setTimestamp(1, rs.getTimestamp("liveDateTime")); | 
				
			||||
 | 
				
			||||
		sqlDateTime = rs.getTimestamp("endDateTime"); | 
				
			||||
 | 
				
			||||
		if (sqlDateTime == null) | 
				
			||||
			outStatement.setNull(2, Types.DATE); | 
				
			||||
		else | 
				
			||||
			outStatement.setTimestamp(2, rs.getTimestamp("endDateTime")); | 
				
			||||
 | 
				
			||||
		outStatement.setString(3, rs.getString("resolution")); | 
				
			||||
		outStatement.setInt(4, rs.getInt("event_number")); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	void reset() { | 
				
			||||
		this.cityHash = null; | 
				
			||||
		this.cityGuildHash = null; | 
				
			||||
		this.cityNationHash = null; | 
				
			||||
		this.baneDropperHash = null; | 
				
			||||
		this.baneGuildHash = null; | 
				
			||||
		this.baneNationHash = null; | 
				
			||||
		this.baneLiveTime = null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void release() { | 
				
			||||
		this.reset(); | 
				
			||||
		recordPool.add(this); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void write() { | 
				
			||||
 | 
				
			||||
		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = buildBaneInsertStatement(connection)) { | 
				
			||||
 | 
				
			||||
			statement.execute(); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private PreparedStatement buildBaneInsertStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "INSERT INTO `warehouse_banehistory` (`city_id`, `city_name`, `char_id`, `offGuild_id`, `offNat_id`, `defGuild_id`, `defNat_id`, `dropDatetime`, `liveDateTime`, `resolution`) VALUES(?,?,?,?,?,?,?,?,?,?)"; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
		outStatement.setString(1, this.cityHash); | 
				
			||||
		outStatement.setString(2, this.cityName); | 
				
			||||
		outStatement.setString(3, this.baneDropperHash); | 
				
			||||
		outStatement.setString(4, this.baneGuildHash); | 
				
			||||
		outStatement.setString(5, this.baneNationHash); | 
				
			||||
		outStatement.setString(6, this.cityGuildHash); | 
				
			||||
		outStatement.setString(7, this.cityNationHash); | 
				
			||||
 | 
				
			||||
		if (this.baneDropTime == null) | 
				
			||||
			outStatement.setNull(8, java.sql.Types.DATE); | 
				
			||||
		else | 
				
			||||
			outStatement.setTimestamp(8, new java.sql.Timestamp(this.baneDropTime.getMillis())); | 
				
			||||
 | 
				
			||||
		if (this.baneLiveTime == null) | 
				
			||||
			outStatement.setNull(9, java.sql.Types.DATE); | 
				
			||||
		else | 
				
			||||
			outStatement.setTimestamp(9, new java.sql.Timestamp(this.baneLiveTime.getMillis())); | 
				
			||||
 | 
				
			||||
		outStatement.setString(10, this.eventType.name()); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
} // END CLASS
 | 
				
			||||
 | 
				
			||||
@ -0,0 +1,284 @@
				@@ -0,0 +1,284 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.archive; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.objects.Guild; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.workthreads.WarehousePushThread; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.*; | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.util.concurrent.LinkedBlockingQueue; | 
				
			||||
 | 
				
			||||
/* | 
				
			||||
 * This class warehouses character creation events.  It also tracks | 
				
			||||
 * updates to summary kills/death data and their promotion class. | 
				
			||||
 */ | 
				
			||||
public class CharacterRecord extends DataRecord { | 
				
			||||
 | 
				
			||||
    // Local object pool for class
 | 
				
			||||
 | 
				
			||||
    private static final LinkedBlockingQueue<CharacterRecord> recordPool = new LinkedBlockingQueue<>(); | 
				
			||||
 | 
				
			||||
    private PlayerCharacter player; | 
				
			||||
 | 
				
			||||
    private CharacterRecord(PlayerCharacter player) { | 
				
			||||
        this.recordType = Enum.DataRecordType.CHARACTER; | 
				
			||||
        this.player = player; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static CharacterRecord borrow(PlayerCharacter player) { | 
				
			||||
        CharacterRecord characterRecord; | 
				
			||||
 | 
				
			||||
        characterRecord = recordPool.poll(); | 
				
			||||
 | 
				
			||||
        if (characterRecord == null) { | 
				
			||||
            characterRecord = new CharacterRecord(player); | 
				
			||||
        } | 
				
			||||
        else { | 
				
			||||
            characterRecord.recordType = Enum.DataRecordType.CHARACTER; | 
				
			||||
            characterRecord.player = player; | 
				
			||||
 | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        return characterRecord; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private static PreparedStatement buildCharacterInsertStatement(Connection connection, PlayerCharacter player) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "INSERT INTO `warehouse_characterhistory` (`char_id`, `char_fname`, `char_lname`, `baseClass`, `race`, `promoteClass`, `startingGuild`, `datetime`) VALUES(?,?,?,?,?,?,?,?)"; | 
				
			||||
        Guild charGuild; | 
				
			||||
 | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
        charGuild = player.getGuild(); | 
				
			||||
 | 
				
			||||
        // Bind character data
 | 
				
			||||
 | 
				
			||||
        outStatement.setString(1, DataWarehouse.hasher.encrypt(player.getObjectUUID())); | 
				
			||||
        outStatement.setString(2, player.getFirstName()); | 
				
			||||
        outStatement.setString(3, player.getLastName()); | 
				
			||||
        outStatement.setInt(4, player.getBaseClassID()); | 
				
			||||
        outStatement.setInt(5, player.getRaceID()); | 
				
			||||
        outStatement.setInt(6, player.getPromotionClassID()); | 
				
			||||
        outStatement.setString(7, DataWarehouse.hasher.encrypt(charGuild.getObjectUUID())); | 
				
			||||
        outStatement.setTimestamp(8, Timestamp.valueOf(LocalDateTime.now())); | 
				
			||||
 | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static PreparedStatement buildCharacterPushStatement(Connection connection, ResultSet rs) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "INSERT INTO `warehouse_characterhistory` (`event_number`, `char_id`, `char_fname`, `char_lname`, `baseClass`, `race`, `promoteClass`, `startingGuild`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?)"; | 
				
			||||
 | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
        // Bind record data
 | 
				
			||||
 | 
				
			||||
        outStatement.setInt(1, rs.getInt("event_number")); | 
				
			||||
        outStatement.setString(2, rs.getString("char_id")); | 
				
			||||
        outStatement.setString(3, rs.getString("char_fname")); | 
				
			||||
        outStatement.setString(4, rs.getString("char_lname")); | 
				
			||||
        outStatement.setInt(5, rs.getInt("baseClass")); | 
				
			||||
        outStatement.setInt(6, rs.getInt("race")); | 
				
			||||
        outStatement.setInt(7, rs.getInt("promoteClass")); | 
				
			||||
        outStatement.setString(8, rs.getString("startingGuild")); | 
				
			||||
        outStatement.setTimestamp(9, rs.getTimestamp("datetime")); | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static PreparedStatement buildCharacterQueryStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "SELECT * FROM `warehouse_characterhistory` WHERE `event_number` > ?"; | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
        outStatement.setInt(1, WarehousePushThread.charIndex); | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void advanceKillCounter(PlayerCharacter player) { | 
				
			||||
 | 
				
			||||
        try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
             PreparedStatement statement = buildKillCounterStatement(connection, player)) { | 
				
			||||
 | 
				
			||||
            statement.execute(); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error( e.toString()); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private static PreparedStatement buildKillCounterStatement(Connection connection, PlayerCharacter player) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "UPDATE `warehouse_characterhistory` SET `kills` = `kills` +1, `dirty` = 1 WHERE `char_id` = ?"; | 
				
			||||
 | 
				
			||||
        if (player == null) | 
				
			||||
            return outStatement; | 
				
			||||
 | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
        outStatement.setString(1, player.getHash()); | 
				
			||||
 | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void advanceDeathCounter(PlayerCharacter player) { | 
				
			||||
 | 
				
			||||
        try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
             PreparedStatement statement = buildDeathCounterStatement(connection, player)) { | 
				
			||||
 | 
				
			||||
            statement.execute(); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error( e.toString()); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private static PreparedStatement buildDeathCounterStatement(Connection connection, PlayerCharacter player) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "UPDATE `warehouse_characterhistory` SET `deaths` = `deaths` +1, `dirty` = 1 WHERE `char_id` = ?"; | 
				
			||||
 | 
				
			||||
        if (player == null) | 
				
			||||
            return outStatement; | 
				
			||||
 | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
        outStatement.setString(1, player.getHash()); | 
				
			||||
 | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void updatePromotionClass(PlayerCharacter player) { | 
				
			||||
 | 
				
			||||
        try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
             PreparedStatement statement = buildUpdatePromotionStatement(connection, player)) { | 
				
			||||
 | 
				
			||||
            statement.execute(); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error( e.toString()); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private static PreparedStatement buildUpdatePromotionStatement(Connection connection, PlayerCharacter player) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "UPDATE `warehouse_characterhistory` SET `promoteClass` = ?, `dirty` = 1 WHERE `char_id` = ?"; | 
				
			||||
 | 
				
			||||
        if (player == null) | 
				
			||||
            return outStatement; | 
				
			||||
 | 
				
			||||
        outStatement = connection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); | 
				
			||||
        outStatement.setInt(1, player.getPromotionClassID()); | 
				
			||||
        outStatement.setString(2, player.getHash()); | 
				
			||||
 | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void updateDirtyRecords() { | 
				
			||||
 | 
				
			||||
        String queryString = "SELECT * FROM `warehouse_characterhistory` where `dirty` = 1"; | 
				
			||||
 | 
				
			||||
        // Reset character delta
 | 
				
			||||
 | 
				
			||||
        WarehousePushThread.charDelta = 0; | 
				
			||||
 | 
				
			||||
        try (Connection localConnection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
             PreparedStatement statement = localConnection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); // Make this an updatable result set as we'll reset the dirty flag as we go along
 | 
				
			||||
             ResultSet rs = statement.executeQuery()) { | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
 | 
				
			||||
                // Only update the index and dirty flag
 | 
				
			||||
                // if the remote database update succeeded
 | 
				
			||||
 | 
				
			||||
                if (updateDirtyRecord(rs) == true) | 
				
			||||
                    WarehousePushThread.charDelta++; | 
				
			||||
                else | 
				
			||||
                    continue; | 
				
			||||
 | 
				
			||||
                // Reset the dirty flag in the local database
 | 
				
			||||
 | 
				
			||||
                rs.updateInt("dirty", 0); | 
				
			||||
                rs.updateRow(); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private static boolean updateDirtyRecord(ResultSet rs) { | 
				
			||||
 | 
				
			||||
        try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); | 
				
			||||
             PreparedStatement statement = buildUpdateDirtyStatement(remoteConnection, rs)) { | 
				
			||||
 | 
				
			||||
            statement.execute(); | 
				
			||||
            return true; | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error(e.toString()); | 
				
			||||
            return false; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private static PreparedStatement buildUpdateDirtyStatement(Connection connection, ResultSet rs) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement; | 
				
			||||
        String queryString = "UPDATE `warehouse_characterhistory` SET `promoteClass` = ?, `kills` = ?, `deaths` = ? WHERE `char_id` = ?"; | 
				
			||||
 | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
        // Bind record data
 | 
				
			||||
 | 
				
			||||
        outStatement.setInt(1, rs.getInt("promoteClass")); | 
				
			||||
        outStatement.setInt(2, rs.getInt("kills")); | 
				
			||||
        outStatement.setInt(3, rs.getInt("deaths")); | 
				
			||||
        outStatement.setString(4, rs.getString("char_id")); | 
				
			||||
 | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    void reset() { | 
				
			||||
        this.player = null; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void release() { | 
				
			||||
        this.reset(); | 
				
			||||
        recordPool.add(this); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void write() { | 
				
			||||
 | 
				
			||||
        try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
             PreparedStatement statement = buildCharacterInsertStatement(connection, this.player)) { | 
				
			||||
 | 
				
			||||
            statement.execute(); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error( "Error writing character record " + e.toString()); | 
				
			||||
 | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
@ -0,0 +1,161 @@
				@@ -0,0 +1,161 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.archive; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.objects.City; | 
				
			||||
import engine.workthreads.WarehousePushThread; | 
				
			||||
 | 
				
			||||
import java.sql.*; | 
				
			||||
import java.util.concurrent.LinkedBlockingQueue; | 
				
			||||
 | 
				
			||||
public class CityRecord extends DataRecord { | 
				
			||||
 | 
				
			||||
	private static final LinkedBlockingQueue<CityRecord> recordPool = new LinkedBlockingQueue<>(); | 
				
			||||
	private Enum.RecordEventType eventType; | 
				
			||||
	private City city; | 
				
			||||
	private String cityHash; | 
				
			||||
	private String cityGuildHash; | 
				
			||||
	private String cityName; | 
				
			||||
	private String cityMotto; | 
				
			||||
	private float locX; | 
				
			||||
	private float locY; | 
				
			||||
	private String zoneHash; | 
				
			||||
	private java.time.LocalDateTime establishedDatetime; | 
				
			||||
 | 
				
			||||
	private CityRecord(City city) { | 
				
			||||
		this.recordType = Enum.DataRecordType.CITY; | 
				
			||||
		this.city = city; | 
				
			||||
		this.eventType = Enum.RecordEventType.CREATE; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static CityRecord borrow(City city, Enum.RecordEventType eventType) { | 
				
			||||
		CityRecord cityRecord; | 
				
			||||
 | 
				
			||||
		cityRecord = recordPool.poll(); | 
				
			||||
 | 
				
			||||
		if (cityRecord == null) { | 
				
			||||
			cityRecord = new CityRecord(city); | 
				
			||||
			cityRecord.eventType = eventType; | 
				
			||||
		} | 
				
			||||
		else { | 
				
			||||
			cityRecord.recordType = Enum.DataRecordType.CITY; | 
				
			||||
			cityRecord.eventType = eventType; | 
				
			||||
			cityRecord.city = city; | 
				
			||||
 | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		if (cityRecord.city.getHash() == null) | 
				
			||||
			cityRecord.city.setHash(DataWarehouse.hasher.encrypt(cityRecord.city.getObjectUUID())); | 
				
			||||
 | 
				
			||||
		cityRecord.cityHash = cityRecord.city.getHash(); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		cityRecord.cityName = cityRecord.city.getCityName(); | 
				
			||||
		cityRecord.cityMotto = cityRecord.city.getMotto(); | 
				
			||||
 | 
				
			||||
		cityRecord.cityGuildHash = cityRecord.city.getGuild().getHash(); | 
				
			||||
 | 
				
			||||
		cityRecord.locX = cityRecord.city.getTOL().getLoc().x; | 
				
			||||
		cityRecord.locY = -cityRecord.city.getTOL().getLoc().z; // flip sign on 'y' coordinate
 | 
				
			||||
 | 
				
			||||
		cityRecord.zoneHash = cityRecord.city.getParent().getHash(); | 
				
			||||
 | 
				
			||||
		if (cityRecord.eventType.equals(Enum.RecordEventType.CREATE)) | 
				
			||||
            cityRecord.establishedDatetime =  cityRecord.city.established; | 
				
			||||
		else | 
				
			||||
			cityRecord.establishedDatetime = java.time.LocalDateTime.now(); | 
				
			||||
 | 
				
			||||
		return cityRecord; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static PreparedStatement buildCityPushStatement(Connection connection, ResultSet rs) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "INSERT INTO `warehouse_cityhistory` (`event_number`, `city_id`, `city_name`, `city_motto`, `guild_id`, `loc_x`, `loc_y`, `zone_id`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?,?)"; | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
		// Bind record data
 | 
				
			||||
 | 
				
			||||
		outStatement.setInt(1, rs.getInt("event_number")); | 
				
			||||
		outStatement.setString(2, rs.getString("city_id")); | 
				
			||||
		outStatement.setString(3, rs.getString("city_name")); | 
				
			||||
		outStatement.setString(4, rs.getString("city_motto")); | 
				
			||||
		outStatement.setString(5, rs.getString("guild_id")); | 
				
			||||
 | 
				
			||||
		outStatement.setFloat(6, rs.getFloat("loc_x")); | 
				
			||||
		outStatement.setFloat(7, rs.getFloat("loc_y")); | 
				
			||||
		outStatement.setString(8, rs.getString("zone_id")); | 
				
			||||
		outStatement.setString(9, rs.getString("eventType")); | 
				
			||||
		outStatement.setTimestamp(10, rs.getTimestamp("datetime")); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static PreparedStatement buildCityQueryStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "SELECT * FROM `warehouse_cityhistory` WHERE `event_number` > ?"; | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
		outStatement.setInt(1, WarehousePushThread.cityIndex); | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	void reset() { | 
				
			||||
		this.city = null; | 
				
			||||
		this.cityHash = null; | 
				
			||||
		this.cityGuildHash = null; | 
				
			||||
		this.cityMotto = null; | 
				
			||||
		this.zoneHash = null; | 
				
			||||
		this.establishedDatetime = null; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void release() { | 
				
			||||
		this.reset(); | 
				
			||||
		recordPool.add(this); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void write() { | 
				
			||||
 | 
				
			||||
		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = this.buildCityInsertStatement(connection)) { | 
				
			||||
 | 
				
			||||
			statement.execute(); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			e.printStackTrace(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private PreparedStatement buildCityInsertStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "INSERT INTO `warehouse_cityhistory` (`city_id`, `city_name`, `city_motto`, `guild_id`, `loc_x`, `loc_y`, `zone_id`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?)"; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
		// Bind character data
 | 
				
			||||
 | 
				
			||||
		outStatement.setString(1, this.cityHash); | 
				
			||||
		outStatement.setString(2, this.cityName); | 
				
			||||
		outStatement.setString(3, this.cityMotto); | 
				
			||||
		outStatement.setString(4, this.cityGuildHash); | 
				
			||||
 | 
				
			||||
		outStatement.setFloat(5, this.locX); | 
				
			||||
		outStatement.setFloat(6, this.locY); | 
				
			||||
		outStatement.setString(7, this.zoneHash); | 
				
			||||
		outStatement.setString(8, this.eventType.name()); | 
				
			||||
		outStatement.setTimestamp(9,  Timestamp.valueOf(this.establishedDatetime)); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,23 @@
				@@ -0,0 +1,23 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.archive; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
 | 
				
			||||
class DataRecord { | 
				
			||||
 | 
				
			||||
    public Enum.DataRecordType recordType; | 
				
			||||
 | 
				
			||||
    DataRecord() { | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,324 @@
				@@ -0,0 +1,324 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.archive; | 
				
			||||
 | 
				
			||||
import com.zaxxer.hikari.HikariConfig; | 
				
			||||
import com.zaxxer.hikari.HikariDataSource; | 
				
			||||
import engine.gameManager.ConfigManager; | 
				
			||||
import engine.util.Hasher; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.Connection; | 
				
			||||
import java.sql.PreparedStatement; | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.concurrent.LinkedBlockingQueue; | 
				
			||||
 | 
				
			||||
import static engine.Enum.DataRecordType; | 
				
			||||
 | 
				
			||||
public class DataWarehouse implements Runnable { | 
				
			||||
 | 
				
			||||
    public static final Hasher hasher = new Hasher("Cthulhu Owns Joo"); | 
				
			||||
    private static final LinkedBlockingQueue<DataRecord> recordQueue = new LinkedBlockingQueue<>(); | 
				
			||||
    public static HikariDataSource connectionPool = null; | 
				
			||||
    public static HikariDataSource remoteConnectionPool = null; | 
				
			||||
 | 
				
			||||
    public DataWarehouse() { | 
				
			||||
 | 
				
			||||
        Logger.info("Configuring local Database Connection Pool..."); | 
				
			||||
 | 
				
			||||
        configureConnectionPool(); | 
				
			||||
 | 
				
			||||
        // If WarehousePush is disabled
 | 
				
			||||
        // then early exit
 | 
				
			||||
 | 
				
			||||
        if ( ConfigManager.MB_WORLD_WAREHOUSE_PUSH.getValue().equals("false")) { | 
				
			||||
            Logger.info("Warehouse Remote Connection disabled along with push"); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        Logger.info( "Configuring remote Database Connection Pool..."); | 
				
			||||
        configureRemoteConnectionPool(); | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void bootStrap() { | 
				
			||||
        Thread warehousingThread; | 
				
			||||
        warehousingThread = new Thread(new DataWarehouse()); | 
				
			||||
 | 
				
			||||
        warehousingThread.setName("DataWarehouse"); | 
				
			||||
        warehousingThread.setPriority(Thread.NORM_PRIORITY - 1); | 
				
			||||
        warehousingThread.start(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void pushToWarehouse(DataRecord dataRecord) { | 
				
			||||
 | 
				
			||||
        DataWarehouse.recordQueue.add(dataRecord); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void writeHash(DataRecordType recordType, int uuid) { | 
				
			||||
 | 
				
			||||
        // Member variable declaration
 | 
				
			||||
 | 
				
			||||
        Connection connection = null; | 
				
			||||
        PreparedStatement statement = null; | 
				
			||||
        String queryString; | 
				
			||||
        String hashString; | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            e.printStackTrace(); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (connection == null) { | 
				
			||||
            Logger.error("Null connection when writing zone hash."); | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Build query string
 | 
				
			||||
 | 
				
			||||
        switch (recordType) { | 
				
			||||
            case CHARACTER: | 
				
			||||
                queryString = "UPDATE `obj_character` SET hash = ? WHERE `UID` = ?"; | 
				
			||||
                break; | 
				
			||||
            case GUILD: | 
				
			||||
                queryString = "UPDATE `obj_guild` SET hash = ? WHERE `UID` = ?"; | 
				
			||||
                break; | 
				
			||||
            case ZONE: | 
				
			||||
                queryString = "UPDATE `obj_zone` SET hash = ? WHERE `UID` = ?"; | 
				
			||||
                break; | 
				
			||||
            case CITY: | 
				
			||||
                queryString = "UPDATE `obj_city` SET hash = ? WHERE `UID` = ?"; | 
				
			||||
                break; | 
				
			||||
            case REALM: | 
				
			||||
                queryString = "UPDATE `obj_realm` SET hash = ? WHERE `realmID` = ?"; | 
				
			||||
                break; | 
				
			||||
            default: | 
				
			||||
                queryString = null; | 
				
			||||
                break; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        hashString = hasher.encrypt(uuid); | 
				
			||||
 | 
				
			||||
        // Write this record to the warehouse
 | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
 | 
				
			||||
            statement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
            statement.setString(1, hashString); | 
				
			||||
            statement.setLong(2, uuid); | 
				
			||||
            statement.execute(); | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error("Error writing hash for uuid" + uuid + " of type " + recordType.name() + ' ' + e.toString()); | 
				
			||||
            e.printStackTrace(); | 
				
			||||
        } finally { | 
				
			||||
            if (connection != null) { | 
				
			||||
                try { | 
				
			||||
                    connection.close(); | 
				
			||||
                } catch (SQLException e) { | 
				
			||||
                    e.printStackTrace(); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static boolean recordExists(DataRecordType recordType, int uuid) { | 
				
			||||
 | 
				
			||||
        // Member variable declaration
 | 
				
			||||
 | 
				
			||||
        Connection connection = null; | 
				
			||||
        PreparedStatement statement = null; | 
				
			||||
        String queryString; | 
				
			||||
        ResultSet resultSet; | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            e.printStackTrace(); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (connection == null) { | 
				
			||||
            Logger.error("Null connection during char record lookup"); | 
				
			||||
            return true;  // False positive here, so as not to try and write the record twice.
 | 
				
			||||
            // will refactor out once we write hashes to object tables
 | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        // Build query string
 | 
				
			||||
 | 
				
			||||
        switch (recordType) { | 
				
			||||
            case CHARACTER: | 
				
			||||
                queryString = "SELECT COUNT(*) from warehouse_characterhistory where char_id = ?"; | 
				
			||||
                break; | 
				
			||||
            case GUILD: | 
				
			||||
                queryString = "SELECT COUNT(*) from warehouse_guildhistory where guild_id = ?"; | 
				
			||||
                break; | 
				
			||||
            case CITY: | 
				
			||||
                queryString = "SELECT COUNT(*) from warehouse_cityhistory where city_id = ?"; | 
				
			||||
                break; | 
				
			||||
            case REALM: | 
				
			||||
                queryString = "SELECT COUNT(*) from warehouse_realmhistory where realm_id = ?"; | 
				
			||||
                break; | 
				
			||||
            case BANE: | 
				
			||||
                queryString = "SELECT COUNT(*) from warehouse_banehistory where city_id = ? AND `resolution` = 'PENDING'"; | 
				
			||||
                break; | 
				
			||||
            case ZONE: // Does not really exist but enum acts as a proxy for hash lookup
 | 
				
			||||
            case MINE: // Does not really exist but enum acts as a proxy for hash lookup
 | 
				
			||||
            default: | 
				
			||||
                queryString = null; | 
				
			||||
                break; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            statement = connection.prepareStatement(queryString); | 
				
			||||
            statement.setString(1, DataWarehouse.hasher.encrypt(uuid)); | 
				
			||||
            resultSet = statement.executeQuery(); | 
				
			||||
 | 
				
			||||
            while (resultSet.next()) { | 
				
			||||
                return resultSet.getInt("COUNT(*)") > 0; | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error("Error in record lookup for " + recordType.name() + " of uuid:" + uuid + e.toString()); | 
				
			||||
            e.printStackTrace(); | 
				
			||||
        } finally { | 
				
			||||
            if (connection != null) { | 
				
			||||
                try { | 
				
			||||
                    connection.close(); | 
				
			||||
                } catch (SQLException e) { | 
				
			||||
                    e.printStackTrace(); | 
				
			||||
                } | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
        return false; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void run() { | 
				
			||||
 | 
				
			||||
        // Working variable set
 | 
				
			||||
 | 
				
			||||
        DataRecord dataRecord; | 
				
			||||
        PvpRecord pvpRecord; | 
				
			||||
        GuildRecord guildRecord; | 
				
			||||
        CharacterRecord characterRecord; | 
				
			||||
        CityRecord cityRecord; | 
				
			||||
        BaneRecord baneRecord; | 
				
			||||
        RealmRecord realmRecord; | 
				
			||||
        MineRecord mineRecord; | 
				
			||||
 | 
				
			||||
        Logger.info( "DataWarehouse is running."); | 
				
			||||
 | 
				
			||||
        while (true) { | 
				
			||||
 | 
				
			||||
            dataRecord = null; | 
				
			||||
            pvpRecord = null; | 
				
			||||
            guildRecord = null; | 
				
			||||
            characterRecord = null; | 
				
			||||
            cityRecord = null; | 
				
			||||
            baneRecord = null; | 
				
			||||
            realmRecord = null; | 
				
			||||
            mineRecord = null; | 
				
			||||
 | 
				
			||||
            try { | 
				
			||||
                dataRecord = recordQueue.take(); | 
				
			||||
            } catch (InterruptedException e) { | 
				
			||||
                e.printStackTrace(); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            // Write record to appropriate warehousing table
 | 
				
			||||
 | 
				
			||||
            if (dataRecord != null) { | 
				
			||||
 | 
				
			||||
                switch (dataRecord.recordType) { | 
				
			||||
                    case PVP: | 
				
			||||
                        pvpRecord = (PvpRecord) dataRecord; | 
				
			||||
                        pvpRecord.write(); | 
				
			||||
                        pvpRecord.release(); | 
				
			||||
                        break; | 
				
			||||
                    case CHARACTER: | 
				
			||||
                        characterRecord = (CharacterRecord) dataRecord; | 
				
			||||
                        characterRecord.write(); | 
				
			||||
                        characterRecord.release(); | 
				
			||||
                        break; | 
				
			||||
                    case GUILD: | 
				
			||||
                        guildRecord = (GuildRecord) dataRecord; | 
				
			||||
                        guildRecord.write(); | 
				
			||||
                        guildRecord.release(); | 
				
			||||
                        break; | 
				
			||||
                    case CITY: | 
				
			||||
                        cityRecord = (CityRecord) dataRecord; | 
				
			||||
                        cityRecord.write(); | 
				
			||||
                        cityRecord.release(); | 
				
			||||
                        break; | 
				
			||||
                    case BANE: | 
				
			||||
                        baneRecord = (BaneRecord) dataRecord; | 
				
			||||
                        baneRecord.write(); | 
				
			||||
                        baneRecord.release(); | 
				
			||||
                        break; | 
				
			||||
                    case REALM: | 
				
			||||
                        realmRecord = (RealmRecord) dataRecord; | 
				
			||||
                        realmRecord.write(); | 
				
			||||
                        realmRecord.release(); | 
				
			||||
                        break; | 
				
			||||
                    case MINE: | 
				
			||||
                        mineRecord = (MineRecord) dataRecord; | 
				
			||||
                        mineRecord.write(); | 
				
			||||
                        mineRecord.release(); | 
				
			||||
                        break; | 
				
			||||
                    default: | 
				
			||||
                        Logger.error( "Unhandled record type"); | 
				
			||||
                        break; | 
				
			||||
 | 
				
			||||
                } // end switch
 | 
				
			||||
            } | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private static void configureConnectionPool() { | 
				
			||||
 | 
				
			||||
        HikariConfig config = new HikariConfig(); | 
				
			||||
 | 
				
			||||
        config.setMaximumPoolSize(10); | 
				
			||||
 | 
				
			||||
        config.setJdbcUrl("jdbc:mysql://" +  ConfigManager.MB_DATABASE_ADDRESS.getValue() + | 
				
			||||
                ":" +  ConfigManager.MB_DATABASE_PORT.getValue() + "/" + | 
				
			||||
                ConfigManager.MB_DATABASE_NAME.getValue()); | 
				
			||||
        config.setUsername(ConfigManager.MB_DATABASE_USER.getValue()); | 
				
			||||
        config.setPassword( ConfigManager.MB_DATABASE_PASS.getValue()); | 
				
			||||
        config.addDataSourceProperty("characterEncoding", "utf8"); | 
				
			||||
        config.addDataSourceProperty("cachePrepStmts", "true"); | 
				
			||||
        config.addDataSourceProperty("prepStmtCacheSize", "250"); | 
				
			||||
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); | 
				
			||||
 | 
				
			||||
        connectionPool = new HikariDataSource(config); // setup the connection pool
 | 
				
			||||
 | 
				
			||||
        Logger.info("Local warehouse database connection configured"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private static void configureRemoteConnectionPool() { | 
				
			||||
 | 
				
			||||
        HikariConfig config = new HikariConfig(); | 
				
			||||
 | 
				
			||||
        config.setMaximumPoolSize(1); // Only the server talks to remote, so yeah.
 | 
				
			||||
        config.setJdbcUrl(ConfigManager.MB_WAREHOUSE_ADDR.getValue()); | 
				
			||||
        config.setUsername(ConfigManager.MB_WAREHOUSE_USER.getValue()); | 
				
			||||
        config.setPassword(ConfigManager.MB_WAREHOUSE_PASS.getValue()); | 
				
			||||
        config.addDataSourceProperty("characterEncoding", "utf8"); | 
				
			||||
        config.addDataSourceProperty("cachePrepStmts", "true"); | 
				
			||||
        config.addDataSourceProperty("prepStmtCacheSize", "250"); | 
				
			||||
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); | 
				
			||||
 | 
				
			||||
        remoteConnectionPool = new HikariDataSource(config); // setup the connection pool
 | 
				
			||||
 | 
				
			||||
        Logger.info("remote warehouse connection configured"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,215 @@
				@@ -0,0 +1,215 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.archive; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.Enum.RecordEventType; | 
				
			||||
import engine.objects.Guild; | 
				
			||||
import engine.workthreads.WarehousePushThread; | 
				
			||||
 | 
				
			||||
import java.sql.Connection; | 
				
			||||
import java.sql.PreparedStatement; | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.time.ZoneId; | 
				
			||||
import java.util.HashMap; | 
				
			||||
import java.util.concurrent.LinkedBlockingQueue; | 
				
			||||
 | 
				
			||||
public class GuildRecord extends DataRecord { | 
				
			||||
 | 
				
			||||
	private static final LinkedBlockingQueue<GuildRecord> recordPool = new LinkedBlockingQueue<>(); | 
				
			||||
	private Enum.RecordEventType eventType; | 
				
			||||
	private Guild guild; | 
				
			||||
	public String guildHash; | 
				
			||||
	private String guildName; | 
				
			||||
	private String charterName; | 
				
			||||
	private String GLHash; | 
				
			||||
	private String guildMotto; | 
				
			||||
	private int bgIcon; | 
				
			||||
	private int bgColour1; | 
				
			||||
	private int bgColour2; | 
				
			||||
	private int fgIcon; | 
				
			||||
	private int fgColour; | 
				
			||||
	public int guildID; | 
				
			||||
 | 
				
			||||
	private java.time.LocalDateTime  eventDatetime; | 
				
			||||
	 | 
				
			||||
	public static HashMap<Integer, GuildRecord> GuildRecordCache = null; | 
				
			||||
 | 
				
			||||
	private GuildRecord(Guild guild) { | 
				
			||||
		this.recordType = Enum.DataRecordType.GUILD; | 
				
			||||
		this.guild = guild; | 
				
			||||
		this.eventType = Enum.RecordEventType.CREATE; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
 | 
				
			||||
	public GuildRecord(ResultSet rs) throws SQLException { | 
				
			||||
		super(); | 
				
			||||
		this.eventType = RecordEventType.valueOf(rs.getString("eventType")); | 
				
			||||
		this.guildHash = rs.getString("guild_id"); | 
				
			||||
		this.guildName = rs.getString("guild_name"); | 
				
			||||
		this.charterName = rs.getString("charter"); | 
				
			||||
		GLHash = rs.getString("guild_founder"); | 
				
			||||
		this.guildMotto = rs.getString("guild_motto"); | 
				
			||||
		this.bgIcon = rs.getInt("bgicon"); | 
				
			||||
		this.bgColour1 = rs.getInt("bgcoloura"); | 
				
			||||
		this.bgColour2 = rs.getInt("bgcolourb"); | 
				
			||||
		this.fgIcon = rs.getInt("fgicon"); | 
				
			||||
		this.fgColour = rs.getInt("fgcolour"); | 
				
			||||
 | 
				
			||||
		java.sql.Timestamp eventTimeStamp = rs.getTimestamp("upgradeDate"); | 
				
			||||
 | 
				
			||||
		if (eventTimeStamp != null) | 
				
			||||
			this.eventDatetime = LocalDateTime.ofInstant(eventTimeStamp.toInstant(), ZoneId.systemDefault()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public static GuildRecord borrow(Guild guild, Enum.RecordEventType eventType) { | 
				
			||||
		GuildRecord guildRecord; | 
				
			||||
		//add
 | 
				
			||||
		guildRecord = recordPool.poll(); | 
				
			||||
 | 
				
			||||
		if (guildRecord == null) { | 
				
			||||
			guildRecord = new GuildRecord(guild); | 
				
			||||
			guildRecord.eventType = eventType; | 
				
			||||
		} | 
				
			||||
		else { | 
				
			||||
			guildRecord.guild = guild; | 
				
			||||
			guildRecord.recordType = Enum.DataRecordType.GUILD; | 
				
			||||
			guildRecord.eventType = eventType; | 
				
			||||
 | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		guildRecord.guildHash = guildRecord.guild.getHash(); | 
				
			||||
		guildRecord.guildID = guildRecord.guild.getObjectUUID(); | 
				
			||||
		guildRecord.guildName = guildRecord.guild.getName(); | 
				
			||||
		guildRecord.charterName = Enum.GuildType.getGuildTypeFromInt(guildRecord.guild.getCharter()).getCharterName(); | 
				
			||||
 | 
				
			||||
		guildRecord.GLHash = DataWarehouse.hasher.encrypt(guildRecord.guild.getGuildLeaderUUID()); | 
				
			||||
 | 
				
			||||
		guildRecord.guildMotto = guildRecord.guild.getMotto(); | 
				
			||||
		guildRecord.bgIcon = guildRecord.guild.getBgDesign(); | 
				
			||||
		guildRecord.bgColour1 = guildRecord.guild.getBgc1(); | 
				
			||||
		guildRecord.bgColour2 = guildRecord.guild.getBgc2(); | 
				
			||||
		guildRecord.fgIcon = guildRecord.guild.getSymbol(); | 
				
			||||
		guildRecord.fgColour = guildRecord.guild.getSc(); | 
				
			||||
 | 
				
			||||
		if (guild.getOwnedCity() != null) | 
				
			||||
            guildRecord.eventDatetime =  guild.getOwnedCity().established; | 
				
			||||
		else | 
				
			||||
			guildRecord.eventDatetime = LocalDateTime.now(); | 
				
			||||
 | 
				
			||||
		return guildRecord; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static PreparedStatement buildGuildPushStatement(Connection connection, ResultSet rs) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "INSERT INTO `warehouse_guildhistory` (`event_number`, `guild_id`, `guild_name`, `guild_motto`, `guild_founder`, `charter`, `bgicon`, `bgcoloura`, `bgcolourb`, `fgicon`, `fgcolour`, `eventtype`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?)"; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
		// Bind record data
 | 
				
			||||
 | 
				
			||||
		outStatement.setInt(1, rs.getInt("event_number")); | 
				
			||||
		outStatement.setString(2, rs.getString("guild_id")); | 
				
			||||
		outStatement.setString(3, rs.getString("guild_name")); | 
				
			||||
		outStatement.setString(4, rs.getString("guild_motto")); | 
				
			||||
		outStatement.setString(5, rs.getString("guild_founder")); | 
				
			||||
		outStatement.setString(6, rs.getString("charter")); | 
				
			||||
		outStatement.setInt(7, rs.getInt("bgicon")); | 
				
			||||
		outStatement.setInt(8, rs.getInt("bgcoloura")); | 
				
			||||
		outStatement.setInt(9, rs.getInt("bgcolourb")); | 
				
			||||
		outStatement.setInt(10, rs.getInt("fgicon")); | 
				
			||||
		outStatement.setInt(11, rs.getInt("fgcolour")); | 
				
			||||
		outStatement.setString(12, rs.getString("eventtype")); | 
				
			||||
		outStatement.setTimestamp(13, rs.getTimestamp("datetime")); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static PreparedStatement buildGuildQueryStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "SELECT * FROM `warehouse_guildhistory` WHERE `event_number` > ?"; | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
		outStatement.setInt(1, WarehousePushThread.guildIndex); | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	void reset() { | 
				
			||||
 | 
				
			||||
		this.guild = null; | 
				
			||||
		this.guildHash = null; | 
				
			||||
		this.GLHash = null; | 
				
			||||
		this.guildMotto = null; | 
				
			||||
		this.charterName = null; | 
				
			||||
		this.eventDatetime = null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void release() { | 
				
			||||
		this.reset(); | 
				
			||||
		recordPool.add(this); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void write() { | 
				
			||||
 | 
				
			||||
		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = this.buildGuildInsertStatement(connection)) { | 
				
			||||
 | 
				
			||||
			statement.execute(); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			e.printStackTrace(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private PreparedStatement buildGuildInsertStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "INSERT INTO `warehouse_guildhistory` (`guild_id`, `guild_name`, `guild_motto`, `guild_founder`, `charter`, `bgicon`, `bgcoloura`, `bgcolourb`, `fgicon`, `fgcolour`, `eventtype`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)"; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
		// Bind character data
 | 
				
			||||
 | 
				
			||||
		outStatement.setString(1, this.guildHash); | 
				
			||||
		outStatement.setString(2, this.guildName); | 
				
			||||
		outStatement.setString(3, this.guildMotto); | 
				
			||||
		outStatement.setString(4, this.GLHash); | 
				
			||||
		outStatement.setString(5, this.charterName); | 
				
			||||
 | 
				
			||||
		outStatement.setInt(6, this.bgIcon); | 
				
			||||
		outStatement.setInt(7, this.bgColour1); | 
				
			||||
		outStatement.setInt(8, this.bgColour2); | 
				
			||||
		outStatement.setInt(9, this.fgIcon); | 
				
			||||
		outStatement.setInt(10, this.fgColour); | 
				
			||||
		outStatement.setString(11, this.eventType.name()); | 
				
			||||
		outStatement.setTimestamp(12, new java.sql.Timestamp(	this.eventDatetime.atZone(ZoneId.systemDefault()) | 
				
			||||
				.toInstant().toEpochMilli())); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
//	public static void InitializeGuildRecords(){
 | 
				
			||||
//		GuildRecord.GuildRecordCache = DbManager.GuildQueries.GET_WAREHOUSE_GUILD_HISTORY();
 | 
				
			||||
//	}
 | 
				
			||||
} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
@ -0,0 +1,166 @@
				@@ -0,0 +1,166 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.archive; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.objects.AbstractCharacter; | 
				
			||||
import engine.objects.Mine; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.workthreads.WarehousePushThread; | 
				
			||||
 | 
				
			||||
import java.sql.*; | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.util.concurrent.LinkedBlockingQueue; | 
				
			||||
 | 
				
			||||
public class MineRecord extends DataRecord { | 
				
			||||
 | 
				
			||||
    private static final LinkedBlockingQueue<MineRecord> recordPool = new LinkedBlockingQueue<>(); | 
				
			||||
    private Enum.RecordEventType eventType; | 
				
			||||
    private String zoneHash; | 
				
			||||
    private String charHash; | 
				
			||||
    private String mineGuildHash; | 
				
			||||
    private String mineNationHash; | 
				
			||||
    private String mineType; | 
				
			||||
    private float locX; | 
				
			||||
    private float locY; | 
				
			||||
 | 
				
			||||
    private MineRecord() { | 
				
			||||
        this.recordType = Enum.DataRecordType.MINE; | 
				
			||||
        this.eventType = Enum.RecordEventType.CAPTURE; | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static MineRecord borrow(Mine mine, AbstractCharacter character, Enum.RecordEventType eventType) { | 
				
			||||
 | 
				
			||||
        MineRecord mineRecord; | 
				
			||||
        mineRecord = recordPool.poll(); | 
				
			||||
        PlayerCharacter player; | 
				
			||||
 | 
				
			||||
        if (mineRecord == null) { | 
				
			||||
            mineRecord = new MineRecord(); | 
				
			||||
            mineRecord.eventType = eventType; | 
				
			||||
        } | 
				
			||||
        else { | 
				
			||||
            mineRecord.recordType = Enum.DataRecordType.MINE; | 
				
			||||
            mineRecord.eventType = eventType; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        mineRecord.zoneHash = mine.getParentZone().getHash(); | 
				
			||||
 | 
				
			||||
        if (character.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)) { | 
				
			||||
            player = (PlayerCharacter) character; | 
				
			||||
            mineRecord.charHash = player.getHash(); | 
				
			||||
        } | 
				
			||||
        else | 
				
			||||
            mineRecord.charHash = character.getName(); | 
				
			||||
 | 
				
			||||
        DataWarehouse.hasher.encrypt(0); | 
				
			||||
 | 
				
			||||
        if (mine.getOwningGuild() == null) | 
				
			||||
            mineRecord.mineGuildHash = "ERRANT"; | 
				
			||||
        else | 
				
			||||
            mineRecord.mineGuildHash = mine.getOwningGuild().getHash(); | 
				
			||||
 | 
				
			||||
        if (mine.getOwningGuild() == null) | 
				
			||||
            mineRecord.mineNationHash = "ERRANT"; | 
				
			||||
        else | 
				
			||||
            mineRecord.mineNationHash = mine.getOwningGuild().getNation().getHash(); | 
				
			||||
 | 
				
			||||
        mineRecord.locX = mine.getParentZone().getLoc().x; | 
				
			||||
        mineRecord.locY = -mine.getParentZone().getLoc().z; | 
				
			||||
 | 
				
			||||
        mineRecord.mineType = mine.getMineType().name; | 
				
			||||
 | 
				
			||||
        return mineRecord; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static PreparedStatement buildMinePushStatement(Connection connection, ResultSet rs) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "INSERT INTO `warehouse_minehistory` (`event_number`, `zone_id`, `mine_type`, `char_id`, `mine_guildID`, `mine_nationID`, `loc_x`, `loc_y`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?,?)"; | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
        // Bind record data
 | 
				
			||||
 | 
				
			||||
        outStatement.setInt(1, rs.getInt("event_number")); | 
				
			||||
        outStatement.setString(2, rs.getString("zone_id")); | 
				
			||||
        outStatement.setString(3, rs.getString("char_id")); | 
				
			||||
        outStatement.setString(4, rs.getString("mine_type")); | 
				
			||||
        outStatement.setString(5, rs.getString("mine_guildID")); | 
				
			||||
        outStatement.setString(6, rs.getString("mine_nationID")); | 
				
			||||
 | 
				
			||||
        outStatement.setFloat(7, rs.getFloat("loc_x")); | 
				
			||||
        outStatement.setFloat(8, rs.getFloat("loc_y")); | 
				
			||||
        outStatement.setString(9, rs.getString("eventType")); | 
				
			||||
        outStatement.setTimestamp(10, rs.getTimestamp("datetime")); | 
				
			||||
 | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static PreparedStatement buildMineQueryStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "SELECT * FROM `warehouse_minehistory` WHERE `event_number` > ?"; | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
        outStatement.setInt(1, WarehousePushThread.mineIndex); | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    void reset() { | 
				
			||||
        this.zoneHash = null; | 
				
			||||
        this.charHash = null; | 
				
			||||
        this.mineGuildHash = null; | 
				
			||||
        this.mineNationHash = null; | 
				
			||||
        this.mineType = null; | 
				
			||||
        this.locX = 0.0f; | 
				
			||||
        this.locY = 0.0f; | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void release() { | 
				
			||||
        this.reset(); | 
				
			||||
        recordPool.add(this); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void write() { | 
				
			||||
 | 
				
			||||
        try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
             PreparedStatement statement = this.buildMineInsertStatement(connection)) { | 
				
			||||
 | 
				
			||||
            statement.execute(); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            e.printStackTrace(); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private PreparedStatement buildMineInsertStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "INSERT INTO `warehouse_minehistory` (`zone_id`, `mine_type`, `char_id`, `mine_guildID`, `mine_nationID`, `loc_x`, `loc_y`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?)"; | 
				
			||||
 | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
        // Bind character data
 | 
				
			||||
 | 
				
			||||
        outStatement.setString(1, this.zoneHash); | 
				
			||||
        outStatement.setString(2, this.mineType); | 
				
			||||
        outStatement.setString(3, this.charHash); | 
				
			||||
        outStatement.setString(4, this.mineGuildHash); | 
				
			||||
        outStatement.setString(5, this.mineNationHash); | 
				
			||||
 | 
				
			||||
        outStatement.setFloat(6, this.locX); | 
				
			||||
        outStatement.setFloat(7, this.locY); | 
				
			||||
        outStatement.setString(8, this.eventType.name()); | 
				
			||||
        outStatement.setTimestamp(9, Timestamp.valueOf(LocalDateTime.now())); | 
				
			||||
 | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,312 @@
				@@ -0,0 +1,312 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.archive; | 
				
			||||
 | 
				
			||||
import engine.gameManager.ZoneManager; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.objects.Guild; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.objects.Zone; | 
				
			||||
import engine.workthreads.WarehousePushThread; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.*; | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.util.LinkedList; | 
				
			||||
import java.util.concurrent.LinkedBlockingQueue; | 
				
			||||
 | 
				
			||||
import static engine.Enum.DataRecordType; | 
				
			||||
import static engine.Enum.PvpHistoryType; | 
				
			||||
 | 
				
			||||
public class PvpRecord extends DataRecord { | 
				
			||||
 | 
				
			||||
	private static final LinkedBlockingQueue<PvpRecord> recordPool = new LinkedBlockingQueue<>(); | 
				
			||||
 | 
				
			||||
	private PlayerCharacter player; | 
				
			||||
	private PlayerCharacter victim; | 
				
			||||
	private Vector3fImmutable location; | 
				
			||||
	private boolean pvpExp; | 
				
			||||
 | 
				
			||||
	private PvpRecord(PlayerCharacter player, PlayerCharacter victim, Vector3fImmutable location, boolean pvpExp) { | 
				
			||||
		this.recordType = DataRecordType.PVP; | 
				
			||||
		this.player = player; | 
				
			||||
		this.victim = victim; | 
				
			||||
		this.location = new Vector3fImmutable(location); | 
				
			||||
		this.pvpExp = pvpExp; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static PvpRecord borrow(PlayerCharacter player, PlayerCharacter victim, Vector3fImmutable location, boolean pvpExp) { | 
				
			||||
 | 
				
			||||
		PvpRecord pvpRecord; | 
				
			||||
 | 
				
			||||
		pvpRecord = recordPool.poll(); | 
				
			||||
 | 
				
			||||
		if (pvpRecord == null) { | 
				
			||||
			pvpRecord = new PvpRecord(player, victim, location, pvpExp); | 
				
			||||
		} | 
				
			||||
		else { | 
				
			||||
			pvpRecord.recordType = DataRecordType.PVP; | 
				
			||||
			pvpRecord.player = player; | 
				
			||||
			pvpRecord.victim = victim; | 
				
			||||
			pvpRecord.location = new Vector3fImmutable(location); | 
				
			||||
			pvpRecord.pvpExp = pvpExp; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return pvpRecord; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private static PreparedStatement buildHistoryStatement(Connection connection, int charUUID, PvpHistoryType historyType) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = ""; | 
				
			||||
 | 
				
			||||
		switch (historyType) { | 
				
			||||
		case KILLS: | 
				
			||||
			queryString = "SELECT DISTINCT `victim_id`, `datetime` FROM warehouse_pvphistory where char_id = ? " + | 
				
			||||
					"ORDER BY `datetime` DESC LIMIT 10"; | 
				
			||||
			break; | 
				
			||||
		case DEATHS: | 
				
			||||
			queryString = "SELECT DISTINCT `char_id`,`datetime` FROM warehouse_pvphistory where `victim_id` = ? " + | 
				
			||||
					"ORDER BY `datetime` DESC LIMIT 10"; | 
				
			||||
			break; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
		outStatement.setString(1, DataWarehouse.hasher.encrypt(charUUID)); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static LinkedList<Integer> getCharacterPvPHistory(int charUUID, PvpHistoryType historyType) { | 
				
			||||
 | 
				
			||||
		// Member variable declaration
 | 
				
			||||
 | 
				
			||||
		LinkedList<Integer> outList = new LinkedList<>(); | 
				
			||||
 | 
				
			||||
		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = buildHistoryStatement(connection, charUUID, historyType); | 
				
			||||
				ResultSet rs = statement.executeQuery()) { | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				switch (historyType) { | 
				
			||||
				case KILLS: | 
				
			||||
					outList.add((int) DataWarehouse.hasher.decrypt(rs.getString("victim_id"))[0]); | 
				
			||||
					break; | 
				
			||||
				case DEATHS: | 
				
			||||
					outList.add((int) DataWarehouse.hasher.decrypt(rs.getString("char_id"))[0]); | 
				
			||||
					break; | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			e.printStackTrace(); | 
				
			||||
		} | 
				
			||||
		return outList; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private static PreparedStatement buildLuaHistoryQueryStatement(Connection connection, int charUUID) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "CALL `pvpHistory`(?)"; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
		outStatement.setString(1, DataWarehouse.hasher.encrypt(charUUID)); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static String getPvpHistoryString(int charUUID) { | 
				
			||||
 | 
				
			||||
		String outString; | 
				
			||||
		String dividerString; | 
				
			||||
 | 
				
			||||
		String newLine = System.getProperty("line.separator"); | 
				
			||||
 | 
				
			||||
		outString = "[LUA_PVP() DATA WAREHOUSE]" + newLine; | 
				
			||||
		dividerString = "--------------------------------" + newLine; | 
				
			||||
 | 
				
			||||
		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = buildLuaHistoryQueryStatement(connection, charUUID); | 
				
			||||
				ResultSet rs = statement.executeQuery()) { | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				int killCount; | 
				
			||||
				int deathCount; | 
				
			||||
				float killRatio; | 
				
			||||
 | 
				
			||||
				outString += "Total Magicbane murdered souls: " + rs.getInt("TOTALDEATHS") + newLine; | 
				
			||||
				outString += dividerString; | 
				
			||||
				outString += String.format("%-8s %-8s %-8s %-8s %n", "Period", "Kills", "Deaths", "K/D"); | 
				
			||||
				outString += dividerString; | 
				
			||||
 | 
				
			||||
				killCount = rs.getInt("KILLCOUNT"); | 
				
			||||
				deathCount = rs.getInt("DEATHCOUNT"); | 
				
			||||
 | 
				
			||||
				if (deathCount == 0) | 
				
			||||
					killRatio = (float) killCount; | 
				
			||||
				else | 
				
			||||
					killRatio = (float) killCount / deathCount; | 
				
			||||
 | 
				
			||||
				try { | 
				
			||||
					outString += String.format("%-8s %-8d %-8d %.2f %n", "Total", killCount, deathCount, killRatio); | 
				
			||||
 | 
				
			||||
					killCount = rs.getInt("DAILYKILLS"); | 
				
			||||
					deathCount = rs.getInt("DAILYDEATHS"); | 
				
			||||
 | 
				
			||||
					if (deathCount == 0) | 
				
			||||
						killRatio = (float) killCount; | 
				
			||||
					else | 
				
			||||
						killRatio = (float) killCount / deathCount; | 
				
			||||
 | 
				
			||||
					outString += String.format("%-8s %-8d %-8d %.2f %n", "24hrs", killCount, deathCount, killRatio); | 
				
			||||
 | 
				
			||||
					killCount = rs.getInt("HOURLYKILLS"); | 
				
			||||
					deathCount = rs.getInt("HOURLYDEATHS"); | 
				
			||||
 | 
				
			||||
					if (deathCount == 0) | 
				
			||||
						killRatio = (float) killCount; | 
				
			||||
					else | 
				
			||||
						killRatio = (float) killCount / deathCount; | 
				
			||||
 | 
				
			||||
					outString += String.format("%-8s %-8d %-8d %.2f %n", "1hr", killCount, deathCount, killRatio); | 
				
			||||
				} catch (Exception e) { | 
				
			||||
					Logger.error(e.toString()); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			e.printStackTrace(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return outString; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static PreparedStatement buildPvpPushStatement(Connection connection, ResultSet rs) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "INSERT INTO `warehouse_pvphistory` (`event_number`, `char_id`, `char_guild_id`, `char_nation_id`, `char_level`," + | 
				
			||||
				" `victim_id`, `victim_guild_id`, `victim_nation_id`, `victim_level`," + | 
				
			||||
				" `zone_id`, `zone_name`, `loc_x`, `loc_y`, `gave_exp`, `datetime`) " + | 
				
			||||
				" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
		// Bind record data
 | 
				
			||||
 | 
				
			||||
		outStatement.setInt(1, rs.getInt("event_number")); | 
				
			||||
		outStatement.setString(2, rs.getString("char_id")); | 
				
			||||
		outStatement.setString(3, rs.getString("char_guild_id")); | 
				
			||||
		outStatement.setString(4, rs.getString("char_nation_id")); | 
				
			||||
		outStatement.setInt(5, rs.getInt("char_level")); | 
				
			||||
 | 
				
			||||
		// Bind victim data
 | 
				
			||||
 | 
				
			||||
		outStatement.setString(6, rs.getString("victim_id")); | 
				
			||||
		outStatement.setString(7, rs.getString("victim_guild_id")); | 
				
			||||
		outStatement.setString(8, rs.getString("victim_nation_id")); | 
				
			||||
		outStatement.setInt(9, rs.getInt("victim_level")); | 
				
			||||
 | 
				
			||||
		outStatement.setString(10, rs.getString("zone_id")); | 
				
			||||
		outStatement.setString(11, rs.getString("zone_name")); | 
				
			||||
		outStatement.setFloat(12, rs.getFloat("loc_x")); | 
				
			||||
		outStatement.setFloat(13, rs.getFloat("loc_y")); | 
				
			||||
		outStatement.setBoolean(14, rs.getBoolean("gave_exp")); | 
				
			||||
		outStatement.setTimestamp(15, rs.getTimestamp("datetime")); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static PreparedStatement buildPvpQueryStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
		String queryString = "SELECT * FROM `warehouse_pvphistory` WHERE `event_number` > ?"; | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
		outStatement.setInt(1, WarehousePushThread.pvpIndex); | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	void reset() { | 
				
			||||
		this.player = null; | 
				
			||||
		this.victim = null; | 
				
			||||
		this.location = Vector3fImmutable.ZERO; | 
				
			||||
		pvpExp = false; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void release() { | 
				
			||||
		this.reset(); | 
				
			||||
		recordPool.add(this); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private PreparedStatement buildPvPInsertStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
		Guild charGuild; | 
				
			||||
		Guild victimGuild; | 
				
			||||
		Zone zone; | 
				
			||||
		PreparedStatement outStatement = null; | 
				
			||||
 | 
				
			||||
		String queryString = "INSERT INTO `warehouse_pvphistory` (`char_id`, `char_guild_id`, `char_nation_id`, `char_level`," + | 
				
			||||
				" `victim_id`, `victim_guild_id`, `victim_nation_id`, `victim_level`," + | 
				
			||||
				" `zone_id`, `zone_name`, `loc_x`, `loc_y`, `gave_exp`, `datetime`) " + | 
				
			||||
				" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; | 
				
			||||
 | 
				
			||||
		outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
		charGuild = this.player.getGuild(); | 
				
			||||
		victimGuild = this.victim.getGuild(); | 
				
			||||
 | 
				
			||||
		// Use a proxy in the situation where a char guild is null (errant)
 | 
				
			||||
 | 
				
			||||
		 | 
				
			||||
		// Retrieve the zone name where the PvP event occurred
 | 
				
			||||
 | 
				
			||||
		zone = ZoneManager.findSmallestZone(this.location); | 
				
			||||
 | 
				
			||||
		outStatement.setString(1, DataWarehouse.hasher.encrypt(this.player.getObjectUUID())); | 
				
			||||
		outStatement.setString(2, DataWarehouse.hasher.encrypt(charGuild.getObjectUUID())); | 
				
			||||
		outStatement.setString(3, DataWarehouse.hasher.encrypt(charGuild.getNation().getObjectUUID())); | 
				
			||||
		outStatement.setInt(4, this.player.getLevel()); | 
				
			||||
 | 
				
			||||
		// Bind victim data
 | 
				
			||||
 | 
				
			||||
		outStatement.setString(5, DataWarehouse.hasher.encrypt(this.victim.getObjectUUID())); | 
				
			||||
		outStatement.setString(6, DataWarehouse.hasher.encrypt(victimGuild.getObjectUUID())); | 
				
			||||
		outStatement.setString(7, DataWarehouse.hasher.encrypt(victimGuild.getNation().getObjectUUID())); | 
				
			||||
		outStatement.setInt(8, this.victim.getLevel()); | 
				
			||||
 | 
				
			||||
		outStatement.setString(9, DataWarehouse.hasher.encrypt(zone.getObjectUUID())); | 
				
			||||
		outStatement.setString(10, zone.getName()); | 
				
			||||
		outStatement.setFloat(11, this.location.getX()); | 
				
			||||
		outStatement.setFloat(12, -this.location.getZ()); // flip sign on 'y' coordinate
 | 
				
			||||
		outStatement.setBoolean(13, this.pvpExp); | 
				
			||||
		outStatement.setTimestamp(14, Timestamp.valueOf(LocalDateTime.now())); | 
				
			||||
 | 
				
			||||
		return outStatement; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public void write() { | 
				
			||||
 | 
				
			||||
		try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
				PreparedStatement statement = buildPvPInsertStatement(connection)) { | 
				
			||||
 | 
				
			||||
			statement.execute(); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		// Warehouse record for this pvp event written if code path reaches here.
 | 
				
			||||
		// Time to update the respective kill counters.
 | 
				
			||||
 | 
				
			||||
		CharacterRecord.advanceKillCounter(this.player); | 
				
			||||
		CharacterRecord.advanceDeathCounter(this.victim); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,142 @@
				@@ -0,0 +1,142 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.archive; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.objects.Realm; | 
				
			||||
import engine.workthreads.WarehousePushThread; | 
				
			||||
 | 
				
			||||
import java.sql.*; | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.util.concurrent.LinkedBlockingQueue; | 
				
			||||
 | 
				
			||||
public class RealmRecord extends DataRecord { | 
				
			||||
 | 
				
			||||
    private static final LinkedBlockingQueue<RealmRecord> recordPool = new LinkedBlockingQueue<>(); | 
				
			||||
 | 
				
			||||
    private Realm realm; | 
				
			||||
    private Enum.RecordEventType eventType; | 
				
			||||
    private String cityHash; | 
				
			||||
    private String guildHash; | 
				
			||||
    private String charterType; | 
				
			||||
    private LocalDateTime eventDateTime; | 
				
			||||
 | 
				
			||||
    private RealmRecord(Realm realm) { | 
				
			||||
        this.recordType = Enum.DataRecordType.REALM; | 
				
			||||
        this.realm = realm; | 
				
			||||
        this.eventType = Enum.RecordEventType.CAPTURE; | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static RealmRecord borrow(Realm realm, Enum.RecordEventType eventType) { | 
				
			||||
        RealmRecord realmRecord; | 
				
			||||
 | 
				
			||||
        realmRecord = recordPool.poll(); | 
				
			||||
 | 
				
			||||
        if (realmRecord == null) { | 
				
			||||
            realmRecord = new RealmRecord(realm); | 
				
			||||
            realmRecord.eventType = eventType; | 
				
			||||
        } | 
				
			||||
        else { | 
				
			||||
            realmRecord.recordType = Enum.DataRecordType.REALM; | 
				
			||||
            realmRecord.eventType = eventType; | 
				
			||||
            realmRecord.realm = realm; | 
				
			||||
 | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        realmRecord.cityHash = realm.getRulingCity().getHash(); | 
				
			||||
        realmRecord.guildHash = realm.getRulingCity().getGuild().getHash(); | 
				
			||||
        realmRecord.charterType = Enum.CharterType.getCharterTypeByID(realmRecord.realm.getCharterType()).name(); | 
				
			||||
 | 
				
			||||
        if (realmRecord.eventType.equals(Enum.RecordEventType.CAPTURE)) | 
				
			||||
            realmRecord.eventDateTime =  realm.ruledSince; | 
				
			||||
        else | 
				
			||||
            realmRecord.eventDateTime = LocalDateTime.now(); | 
				
			||||
 | 
				
			||||
        return realmRecord; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static PreparedStatement buildRealmPushStatement(Connection connection, ResultSet rs) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "INSERT INTO `warehouse_realmhistory` (`event_number`, `realm_id`, `realm_name`, `charter`, `city_id`, `guild_id`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?,?)"; | 
				
			||||
 | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
        // Bind record data
 | 
				
			||||
 | 
				
			||||
        outStatement.setInt(1, rs.getInt("event_number")); | 
				
			||||
        outStatement.setString(2, rs.getString("realm_id")); | 
				
			||||
        outStatement.setString(3, rs.getString("realm_name")); | 
				
			||||
        outStatement.setString(4, rs.getString("charter")); | 
				
			||||
        outStatement.setString(5, rs.getString("city_id")); | 
				
			||||
        outStatement.setString(6, rs.getString("guild_id")); | 
				
			||||
        outStatement.setString(7, rs.getString("eventType")); | 
				
			||||
        outStatement.setTimestamp(8, rs.getTimestamp("datetime")); | 
				
			||||
 | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static PreparedStatement buildRealmQueryStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "SELECT * FROM `warehouse_realmhistory` WHERE `event_number` > ?"; | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
        outStatement.setInt(1, WarehousePushThread.realmIndex); | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    void reset() { | 
				
			||||
 | 
				
			||||
        this.realm = null; | 
				
			||||
        this.cityHash = null; | 
				
			||||
        this.guildHash = null; | 
				
			||||
        this.eventDateTime = null; | 
				
			||||
        this.charterType = null; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void release() { | 
				
			||||
        this.reset(); | 
				
			||||
        recordPool.add(this); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    private PreparedStatement buildRealmInsertStatement(Connection connection) throws SQLException { | 
				
			||||
 | 
				
			||||
        PreparedStatement outStatement = null; | 
				
			||||
        String queryString = "INSERT INTO `warehouse_realmhistory` (`realm_id`, `realm_name`, `charter`, `city_id`, `guild_id`, `eventType`, `datetime`) VALUES(?,?,?,?,?,?,?)"; | 
				
			||||
        outStatement = connection.prepareStatement(queryString); | 
				
			||||
 | 
				
			||||
        // Bind Record Data
 | 
				
			||||
 | 
				
			||||
        outStatement.setString(1, realm.getHash()); | 
				
			||||
        outStatement.setString(2, realm.getRealmName()); | 
				
			||||
        outStatement.setString(3, charterType); | 
				
			||||
        outStatement.setString(4, cityHash); | 
				
			||||
        outStatement.setString(5, guildHash); | 
				
			||||
        outStatement.setString(6, eventType.name()); | 
				
			||||
        outStatement.setTimestamp(7,  Timestamp.valueOf(this.eventDateTime)); | 
				
			||||
 | 
				
			||||
        return outStatement; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void write() { | 
				
			||||
 | 
				
			||||
        try (Connection connection = DataWarehouse.connectionPool.getConnection(); | 
				
			||||
             PreparedStatement statement = this.buildRealmInsertStatement(connection)) { | 
				
			||||
 | 
				
			||||
            statement.execute(); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            e.printStackTrace(); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,202 @@
				@@ -0,0 +1,202 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.gameManager.ConfigManager; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.Account; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbAccountHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbAccountHandler() { | 
				
			||||
		this.localClass = Account.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Account GET_ACCOUNT(int id) { | 
				
			||||
		if (id == 0) | 
				
			||||
			return null; | 
				
			||||
		Account account = (Account) DbManager.getFromCache(GameObjectType.Account, id); | 
				
			||||
		if (account != null) | 
				
			||||
			return account; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `obj_account` WHERE `UID`=?"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
 | 
				
			||||
		Account ac = null; | 
				
			||||
		ac = (Account) getObjectSingle(id); | 
				
			||||
 | 
				
			||||
		if (ac != null) | 
				
			||||
			ac.runAfterLoad(); | 
				
			||||
 | 
				
			||||
		return ac; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void SET_TRASH(String machineID) { | 
				
			||||
 | 
				
			||||
		prepareCallable("INSERT INTO dyn_trash(`machineID`, `count`)" | 
				
			||||
				+ " VALUES (?, 1) ON DUPLICATE KEY UPDATE `count` = `count` + 1;"); | 
				
			||||
 | 
				
			||||
		setString(1, machineID); | 
				
			||||
		executeUpdate(); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<String> GET_TRASH_LIST() { | 
				
			||||
 | 
				
			||||
		ArrayList<String> machineList = new ArrayList<>(); | 
				
			||||
 | 
				
			||||
		prepareCallable("select `machineID` from `dyn_trash`"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				machineList.add(rs.getString(1)); | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return machineList; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean DELETE_VAULT_FOR_ACCOUNT(final int accountID) { | 
				
			||||
		prepareCallable("DELETE FROM `object` WHERE `parent`=? && `type`='item'"); | 
				
			||||
		setLong(1, (long) accountID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<PlayerCharacter> GET_ALL_CHARS_FOR_MACHINE(String machineID) { | 
				
			||||
 | 
				
			||||
		ArrayList<PlayerCharacter> trashList = new ArrayList<>(); | 
				
			||||
 | 
				
			||||
		prepareCallable("select DISTINCT UID from object \n" + | 
				
			||||
				"where parent IN (select AccountID from dyn_login_history " + | 
				
			||||
		        " WHERE`machineID`=?)"); | 
				
			||||
		setString(1, machineID); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				PlayerCharacter trashPlayer; | 
				
			||||
				int playerID; | 
				
			||||
 | 
				
			||||
				playerID = rs.getInt(1); | 
				
			||||
				trashPlayer = PlayerCharacter.getPlayerCharacter(playerID); | 
				
			||||
 | 
				
			||||
				if (trashPlayer == null) | 
				
			||||
					continue;; | 
				
			||||
 | 
				
			||||
				if (trashPlayer.isDeleted() == false) | 
				
			||||
					trashList.add(trashPlayer); | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return  trashList; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void CLEAR_TRASH_TABLE() { | 
				
			||||
		prepareCallable("DELETE FROM dyn_trash"); | 
				
			||||
		executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Account GET_ACCOUNT(String uname) { | 
				
			||||
 | 
				
			||||
		if (Account.AccountsMap.get(uname) != null) | 
				
			||||
			return this.GET_ACCOUNT(Account.AccountsMap.get(uname)); | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `obj_account` WHERE `acct_uname`=?"); | 
				
			||||
		setString(1, uname); | 
				
			||||
		ArrayList<Account> temp = getObjectList(); | 
				
			||||
 | 
				
			||||
		if (temp.isEmpty()) | 
				
			||||
			return null; | 
				
			||||
 | 
				
			||||
		if (temp.get(0) != null){ | 
				
			||||
			temp.get(0).runAfterLoad(); | 
				
			||||
 | 
				
			||||
			if (ConfigManager.serverType.equals(Enum.ServerType.LOGINSERVER)) | 
				
			||||
				Account.AccountsMap.put(uname, temp.get(0).getObjectUUID()); | 
				
			||||
 | 
				
			||||
		} | 
				
			||||
		return temp.get(0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void SET_ACCOUNT_LOGIN(final Account acc, String playerName, final String ip, final String machineID) { | 
				
			||||
 | 
				
			||||
		if (acc.getObjectUUID() == 0 || ip == null || ip.length() == 0) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		prepareCallable("INSERT INTO dyn_login_history(`AccountID`, `accountName`, `characterName`, `ip`, `machineID`, `timeStamp`)" | 
				
			||||
				+ " VALUES (?, ?, ?, ?, ?, ?)"); | 
				
			||||
 | 
				
			||||
		setInt(1, acc.getObjectUUID()); | 
				
			||||
		setString(2, acc.getUname()); | 
				
			||||
		setString(3, playerName); | 
				
			||||
		setString(4, ip); | 
				
			||||
		setString(5, machineID); | 
				
			||||
		setTimeStamp(6, System.currentTimeMillis()); | 
				
			||||
		executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Account a, String name, Object new_value) { | 
				
			||||
		prepareCallable("CALL account_SETPROP(?,?,?)"); | 
				
			||||
		setLong(1, (long) a.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Account a, String name, Object new_value, Object old_value) { | 
				
			||||
		prepareCallable("CALL account_GETSETPROP(?,?,?,?)"); | 
				
			||||
		setLong(1, (long) a.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		setString(4, String.valueOf(old_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public void updateDatabase(final Account acc) { | 
				
			||||
		prepareCallable("UPDATE `obj_account` SET `acct_passwd`=?, " | 
				
			||||
				+ " `acct_lastCharUID`=?, `acct_salt`=?, `discordAccount`=?, " + | 
				
			||||
				" status = ? WHERE `UID`=?"); | 
				
			||||
 | 
				
			||||
		setString(1, acc.getPasswd()); | 
				
			||||
		setInt(2, acc.getLastCharIDUsed()); | 
				
			||||
		setString(3, acc.getSalt()); | 
				
			||||
		setString(4, acc.discordAccount); | 
				
			||||
		setString(5, acc.status.name()); | 
				
			||||
		setInt(6, acc.getObjectUUID()); | 
				
			||||
		executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void INVALIDATE_LOGIN_CACHE(long accountUID, String objectType) { | 
				
			||||
		prepareCallable("INSERT IGNORE INTO login_cachelist (`UID`, `type`) VALUES(?,?);"); | 
				
			||||
		setLong(1, accountUID); | 
				
			||||
		setString(2, objectType); | 
				
			||||
		executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,115 @@
				@@ -0,0 +1,115 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.Bane; | 
				
			||||
import engine.objects.Building; | 
				
			||||
import engine.objects.City; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import org.joda.time.DateTime; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
import java.util.logging.Level; | 
				
			||||
 | 
				
			||||
public class dbBaneHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
    public dbBaneHandler() { | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public boolean CREATE_BANE(City city, PlayerCharacter owner, Building stone) { | 
				
			||||
 | 
				
			||||
        prepareCallable("INSERT INTO `dyn_banes` (`cityUUID`, `ownerUUID`, `stoneUUID`, `placementDate`) VALUES(?,?,?,?)"); | 
				
			||||
        setLong(1, (long) city.getObjectUUID()); | 
				
			||||
        setLong(2, (long) owner.getObjectUUID()); | 
				
			||||
        setLong(3, (long) stone.getObjectUUID()); | 
				
			||||
        setTimeStamp(4, System.currentTimeMillis()); | 
				
			||||
 | 
				
			||||
        return (executeUpdate() > 0); | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public Bane LOAD_BANE(int cityUUID) { | 
				
			||||
 | 
				
			||||
        Bane newBane = null; | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
 | 
				
			||||
            prepareCallable("SELECT * from dyn_banes WHERE `dyn_banes`.`cityUUID` = ?"); | 
				
			||||
 | 
				
			||||
            setLong(1, (long) cityUUID); | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
            if (rs.next()) { | 
				
			||||
                newBane = new Bane(rs); | 
				
			||||
                Bane.addBane(newBane); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
        } catch (SQLException ex) { | 
				
			||||
            java.util.logging.Logger.getLogger(dbBaneHandler.class.getName()).log(Level.SEVERE, null, ex); | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
        return newBane; | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public ConcurrentHashMap<Integer, Bane> LOAD_ALL_BANES() { | 
				
			||||
 | 
				
			||||
        ConcurrentHashMap<Integer, Bane> baneList; | 
				
			||||
        Bane thisBane; | 
				
			||||
 | 
				
			||||
        baneList = new ConcurrentHashMap<>(); | 
				
			||||
 | 
				
			||||
        int recordsRead = 0; | 
				
			||||
 | 
				
			||||
        prepareCallable("SELECT * FROM dyn_banes"); | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
 | 
				
			||||
                recordsRead++; | 
				
			||||
                thisBane = new Bane(rs); | 
				
			||||
                baneList.put(thisBane.getCityUUID(), thisBane); | 
				
			||||
 | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            Logger.info("read: " + recordsRead + " cached: " + baneList.size()); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error( e.toString()); | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
        return baneList; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public boolean SET_BANE_TIME(DateTime toSet, int cityUUID) { | 
				
			||||
        prepareCallable("UPDATE `dyn_banes` SET `liveDate`=? WHERE `cityUUID`=?"); | 
				
			||||
        setTimeStamp(1, toSet.getMillis()); | 
				
			||||
        setLong(2, cityUUID); | 
				
			||||
        return (executeUpdate() > 0); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public boolean REMOVE_BANE(Bane bane) { | 
				
			||||
 | 
				
			||||
        if (bane == null) | 
				
			||||
            return false; | 
				
			||||
 | 
				
			||||
        prepareCallable("DELETE FROM `dyn_banes` WHERE `cityUUID` = ?"); | 
				
			||||
        setLong(1, (long) bane.getCity().getObjectUUID()); | 
				
			||||
        return (executeUpdate() > 0); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,50 @@
				@@ -0,0 +1,50 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.BaseClass; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbBaseClassHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbBaseClassHandler() { | 
				
			||||
		this.localClass = BaseClass.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.BaseClass; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public BaseClass GET_BASE_CLASS(final int id) { | 
				
			||||
 | 
				
			||||
		if (id == 0) | 
				
			||||
			return null; | 
				
			||||
		BaseClass baseClass = (BaseClass) DbManager.getFromCache(GameObjectType.BaseClass, id); | 
				
			||||
		if (baseClass != null) | 
				
			||||
			return baseClass; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_baseclass` WHERE `ID` = ?;"); | 
				
			||||
		setInt(1, id); | 
				
			||||
		return (BaseClass) getObjectSingle(id); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<BaseClass> GET_BASECLASS_FOR_RACE(final int id) { | 
				
			||||
		prepareCallable("SELECT b.* FROM `static_rune_baseclass` b, `static_rune_racebaseclass` r WHERE b.`ID` = r.`BaseClassID` && r.`RaceID` = ?"); | 
				
			||||
		setInt(1, id); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<BaseClass> GET_ALL_BASE_CLASSES(){ | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_baseclass`;"); | 
				
			||||
		return  getObjectList(); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,86 @@
				@@ -0,0 +1,86 @@
					 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.Blueprint; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.HashMap; | 
				
			||||
 | 
				
			||||
public class dbBlueprintHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
    public dbBlueprintHandler() { | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public HashMap<Integer, Integer> LOAD_ALL_DOOR_NUMBERS() { | 
				
			||||
 | 
				
			||||
        HashMap<Integer, Integer> doorInfo; | 
				
			||||
        doorInfo = new HashMap<>(); | 
				
			||||
 | 
				
			||||
        int doorUUID; | 
				
			||||
        int doorNum; | 
				
			||||
        int recordsRead = 0; | 
				
			||||
 | 
				
			||||
        prepareCallable("SELECT * FROM static_building_doors ORDER BY doorMeshUUID ASC"); | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
 | 
				
			||||
                recordsRead++; | 
				
			||||
                doorUUID = rs.getInt("doorMeshUUID"); | 
				
			||||
                doorNum = rs.getInt("doorNumber"); | 
				
			||||
                doorInfo.put(doorUUID, doorNum); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            Logger.info( "read: " + recordsRead + " cached: " + doorInfo.size()); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error("LoadAllDoorNumbers: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
        return doorInfo; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public HashMap<Integer, Blueprint> LOAD_ALL_BLUEPRINTS() { | 
				
			||||
 | 
				
			||||
        HashMap<Integer, Blueprint> blueprints; | 
				
			||||
        Blueprint thisBlueprint; | 
				
			||||
 | 
				
			||||
        blueprints = new HashMap<>(); | 
				
			||||
        int recordsRead = 0; | 
				
			||||
 | 
				
			||||
        prepareCallable("SELECT * FROM static_building_blueprint"); | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
 | 
				
			||||
                recordsRead++; | 
				
			||||
                thisBlueprint = new Blueprint(rs); | 
				
			||||
 | 
				
			||||
                blueprints.put(thisBlueprint.getBlueprintUUID(), thisBlueprint); | 
				
			||||
 | 
				
			||||
                // load mesh cache
 | 
				
			||||
                Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(-1), thisBlueprint); | 
				
			||||
                Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(0), thisBlueprint); | 
				
			||||
                Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(1), thisBlueprint); | 
				
			||||
                Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(3), thisBlueprint); | 
				
			||||
                Blueprint._meshLookup.putIfAbsent(thisBlueprint.getMeshForRank(7), thisBlueprint); | 
				
			||||
 | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            Logger.info( "read: " + recordsRead + " cached: " + blueprints.size()); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error("LoadAllBlueprints: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
        return blueprints; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,51 @@
				@@ -0,0 +1,51 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.Boon; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbBoonHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbBoonHandler() { | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
 | 
				
			||||
	public ArrayList<Boon>  GET_BOON_AMOUNTS_FOR_ITEMBASEUUID(int itemBaseUUID){ | 
				
			||||
         | 
				
			||||
        ArrayList<Boon>boons = new ArrayList<>(); | 
				
			||||
        Boon thisBoon; | 
				
			||||
        prepareCallable("SELECT * FROM `static_item_boons`  WHERE `itemBaseID` = ?"); | 
				
			||||
        setInt(1, itemBaseUUID); | 
				
			||||
 | 
				
			||||
	try { | 
				
			||||
		ResultSet rs = executeQuery(); | 
				
			||||
                     | 
				
			||||
		while (rs.next()) { | 
				
			||||
                         | 
				
			||||
                      | 
				
			||||
                      thisBoon = new Boon(rs); | 
				
			||||
                      boons.add(thisBoon); | 
				
			||||
		} | 
				
			||||
                     | 
				
			||||
   | 
				
			||||
                             | 
				
			||||
	} catch (SQLException e) { | 
				
			||||
		Logger.error("GetBoonAmountsForItembaseUUID: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
	} finally { | 
				
			||||
		closeCallable(); | 
				
			||||
	} | 
				
			||||
	return boons; | 
				
			||||
} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,809 @@
				@@ -0,0 +1,809 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.Enum.DbObjectType; | 
				
			||||
import engine.Enum.ProtectionState; | 
				
			||||
import engine.Enum.TaxType; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.joda.time.DateTime; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.awt.geom.Line2D; | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.time.ZoneId; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashMap; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
 | 
				
			||||
public class dbBuildingHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbBuildingHandler() { | 
				
			||||
		this.localClass = Building.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Building CREATE_BUILDING(Building b) { | 
				
			||||
		try { | 
				
			||||
			b = this.addBuilding(b); | 
				
			||||
			b.setObjectTypeMask(MBServerStatics.MASK_BUILDING); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error(e); | 
				
			||||
			b = null; | 
				
			||||
		} | 
				
			||||
		return b; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/* | 
				
			||||
	 * | 
				
			||||
	 * @param worldServerID | 
				
			||||
	 * @param OwnerUUID | 
				
			||||
	 * @param name | 
				
			||||
	 * @param meshUUID | 
				
			||||
	 * @param meshScale | 
				
			||||
	 * @param currentHP | 
				
			||||
	 * @param protectionState | 
				
			||||
	 * @param currentGold | 
				
			||||
	 * @param rank | 
				
			||||
	 * @param upgradeDate | 
				
			||||
	 * @param blueprintUUID | 
				
			||||
	 * @param w | 
				
			||||
	 * @param rotY | 
				
			||||
	 * @return | 
				
			||||
	 */ | 
				
			||||
	public Building CREATE_BUILDING(int parentZoneID, int OwnerUUID, String name, int meshUUID, | 
				
			||||
									Vector3fImmutable location, float meshScale, int currentHP, | 
				
			||||
									ProtectionState protectionState, int currentGold, int rank, | 
				
			||||
									DateTime upgradeDate, int blueprintUUID, float w, float rotY) { | 
				
			||||
 | 
				
			||||
		Building toCreate = null; | 
				
			||||
		try { | 
				
			||||
 | 
				
			||||
			prepareCallable("CALL `building_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,? ,? ,?, ?);"); | 
				
			||||
 | 
				
			||||
			setInt(1, parentZoneID); | 
				
			||||
			setInt(2, OwnerUUID); | 
				
			||||
			setString(3, name); | 
				
			||||
			setInt(4, meshUUID); | 
				
			||||
			setFloat(5, location.x); | 
				
			||||
			setFloat(6, location.y); | 
				
			||||
			setFloat(7, location.z); | 
				
			||||
			setFloat(8, meshScale); | 
				
			||||
			setInt(9, currentHP); | 
				
			||||
			setString(10, protectionState.name()); | 
				
			||||
			setInt(11, currentGold); | 
				
			||||
			setInt(12, rank); | 
				
			||||
 | 
				
			||||
			if (upgradeDate != null) | 
				
			||||
				setTimeStamp(13, upgradeDate.getMillis()); | 
				
			||||
			else | 
				
			||||
				setNULL(13, java.sql.Types.DATE); | 
				
			||||
 | 
				
			||||
			setInt(14, blueprintUUID); | 
				
			||||
			setFloat(15, w); | 
				
			||||
			setFloat(16, rotY); | 
				
			||||
 | 
				
			||||
			int objectUUID = (int) getUUID(); | 
				
			||||
 | 
				
			||||
			if (objectUUID > 0) | 
				
			||||
				toCreate = GET_BUILDINGBYUUID(objectUUID); | 
				
			||||
 | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error("CREATE_BUILDING", e.getMessage()); | 
				
			||||
			return null; | 
				
			||||
		} | 
				
			||||
		return toCreate; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean DELETE_FROM_DATABASE(final Building b) { | 
				
			||||
 | 
				
			||||
		return removeFromBuildings(b); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Building> GET_ALL_BUILDINGS_FOR_ZONE(Zone zone) { | 
				
			||||
		prepareCallable("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;"); | 
				
			||||
		setLong(1, zone.getObjectUUID()); | 
				
			||||
		return getLargeObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Building> GET_ALL_BUILDINGS() { | 
				
			||||
		prepareCallable("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID`;"); | 
				
			||||
		return getLargeObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Building GET_BUILDINGBYUUID(int uuid) { | 
				
			||||
		if (uuid == 0) | 
				
			||||
			return null; | 
				
			||||
 | 
				
			||||
		Building building = (Building) DbManager.getFromCache(Enum.GameObjectType.Building, uuid); | 
				
			||||
 | 
				
			||||
		if (building != null) | 
				
			||||
			return building; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?;"); | 
				
			||||
 | 
				
			||||
		setLong(1, (long) uuid); | 
				
			||||
		return (Building) getObjectSingle(uuid); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Building GET_BUILDING_BY_MESH(final int meshID) { | 
				
			||||
		Building toReturn = null; | 
				
			||||
		prepareCallable("CALL building_GETBYMESH(?)"); | 
				
			||||
		setInt(1, meshID); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			if (rs.next()) | 
				
			||||
				toReturn = new Building(rs); | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("Building", e); | 
				
			||||
			return null; | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return toReturn; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Building b, String name, Object new_value) { | 
				
			||||
		prepareCallable("CALL building_SETPROP(?,?,?)"); | 
				
			||||
		setLong(1, b.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Building b, String name, Object new_value, Object old_value) { | 
				
			||||
		prepareCallable("CALL building_GETSETPROP(?,?,?,?)"); | 
				
			||||
		setLong(1, b.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		setString(4, String.valueOf(old_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public int MOVE_BUILDING(long buildingID, long parentID, float locX, float locY, float locZ) { | 
				
			||||
		prepareCallable("UPDATE `object` INNER JOIN `obj_building` On `object`.`UID` = `obj_building`.`UID` SET `object`.`parent`=?, `obj_building`.`locationX`=?, `obj_building`.`locationY`=?, `obj_building`.`locationZ`=? WHERE `obj_building`.`UID`=?;"); | 
				
			||||
		setLong(1, parentID); | 
				
			||||
		setFloat(2, locX); | 
				
			||||
		setFloat(3, locY); | 
				
			||||
		setFloat(4, locZ); | 
				
			||||
		setLong(5, buildingID); | 
				
			||||
		return executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private Building addBuilding(Building toAdd) { | 
				
			||||
		prepareCallable("CALL `building_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | 
				
			||||
		setLong(1, toAdd.getParentZoneID()); | 
				
			||||
		setLong(2, toAdd.getOwnerUUID()); | 
				
			||||
		setString(3, toAdd.getName()); | 
				
			||||
		setInt(4, toAdd.getMeshUUID()); | 
				
			||||
		setFloat(5, toAdd.getStatLat()); | 
				
			||||
		setFloat(6, toAdd.getStatAlt()); | 
				
			||||
		setFloat(7, toAdd.getStatLon()); | 
				
			||||
		setFloat(8, toAdd.getMeshScale().x); | 
				
			||||
		setInt(9, (int) toAdd.getHealth()); | 
				
			||||
		setString(10, toAdd.getProtectionState().name()); | 
				
			||||
		setInt(11, toAdd.getStrongboxValue()); | 
				
			||||
		setInt(12, toAdd.getRank()); | 
				
			||||
 | 
				
			||||
		// Write Joda DateTime to database
 | 
				
			||||
		// *** Refactor : Wrap this logic in our
 | 
				
			||||
		// own override setDateTime() ?
 | 
				
			||||
		if (toAdd.getUpgradeDateTime() != null) | 
				
			||||
			setLocalDateTime(13, toAdd.getUpgradeDateTime()); | 
				
			||||
		else | 
				
			||||
			setNULL(13, java.sql.Types.DATE); | 
				
			||||
 | 
				
			||||
		setInt(14, toAdd.getBlueprintUUID()); | 
				
			||||
		setFloat(15, toAdd.getw()); | 
				
			||||
		setFloat(16, toAdd.getRot().y); | 
				
			||||
 | 
				
			||||
		int objectUUID = (int) getUUID(); | 
				
			||||
 | 
				
			||||
		if (objectUUID > 0) | 
				
			||||
			return GET_BUILDINGBYUUID(objectUUID); | 
				
			||||
		return null; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private boolean removeFromBuildings(final Building b) { | 
				
			||||
		prepareCallable("DELETE FROM `object` WHERE `UID` = ?"); | 
				
			||||
		setLong(1, b.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ClaimAsset(final long SetBuildingID, int newowner, int OldOwner) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_building` SET `ownerUUID`=? WHERE `UID`=? and `ownerUUID`= ?"); | 
				
			||||
		setInt(1, newowner); | 
				
			||||
		setLong(2, SetBuildingID); | 
				
			||||
		setLong(3, OldOwner); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CHANGE_NAME(Building b, String newName) { | 
				
			||||
		prepareCallable("UPDATE `obj_building` SET `name`=? WHERE `UID`=?"); | 
				
			||||
		setString(1, newName); | 
				
			||||
		setLong(2, b.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean SET_RESERVE(Building b, int reserveAmount) { | 
				
			||||
		prepareCallable("UPDATE `obj_building` SET `reserve`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, reserveAmount); | 
				
			||||
		setLong(2, b.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	//CAS update to rank
 | 
				
			||||
	public boolean CHANGE_RANK(final long buildingID, int newRank) { | 
				
			||||
		prepareCallable("UPDATE `obj_building` SET `rank`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, newRank); | 
				
			||||
		setLong(2, buildingID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_BUILDING_HEALTH(final long buildingID, int NewHealth) { | 
				
			||||
		prepareCallable("UPDATE `obj_building` SET `currentHP`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, NewHealth); | 
				
			||||
		setLong(2, buildingID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_BUILDING_ALTITUDE(final long buildingID, float newAltitude) { | 
				
			||||
		prepareCallable("UPDATE `obj_building` SET `locationY`=? WHERE `UID`=?"); | 
				
			||||
		setFloat(1, newAltitude); | 
				
			||||
		setLong(2, buildingID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_PROTECTIONSTATE(final long buildingUUID, ProtectionState protectionState) { | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			prepareCallable("UPDATE `obj_building` SET `protectionState`=? WHERE `UID`=?"); | 
				
			||||
			setString(1, protectionState.name()); | 
				
			||||
			setLong(2, buildingUUID); | 
				
			||||
			return (executeUpdate() > 0); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error(e.toString()); | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_DOOR_LOCK(final int buildingUUID, int doorFlags) { | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			prepareCallable("UPDATE obj_building SET doorState = ? WHERE UID = ?"); | 
				
			||||
 | 
				
			||||
			setInt(1, doorFlags); | 
				
			||||
			setInt(2, buildingUUID); | 
				
			||||
 | 
				
			||||
			executeUpdate(); | 
				
			||||
			return true; | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_TO_FRIENDS_LIST(final long buildingID, final long friendID, final long guildID, final int friendType) { | 
				
			||||
		prepareCallable("INSERT INTO `dyn_building_friends` (`buildingUID`, `playerUID`,`guildUID`, `friendType`) VALUES (?,?,?,?)"); | 
				
			||||
		setLong(1, buildingID); | 
				
			||||
		setLong(2, friendID); | 
				
			||||
		setLong(3, guildID); | 
				
			||||
		setInt(4, friendType); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean REMOVE_FROM_FRIENDS_LIST(final long buildingID, long friendID, long guildID, int friendType) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_building_friends` WHERE `buildingUID`=? AND `playerUID`=? AND `guildUID` =? AND `friendType` = ?"); | 
				
			||||
		setLong(1, buildingID); | 
				
			||||
		setLong(2, friendID); | 
				
			||||
		setLong(3,guildID); | 
				
			||||
		setInt(4, friendType); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean REMOVE_FROM_CONDEMNED_LIST(final long buildingID, long friendID, long guildID, int friendType) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_building_condemned` WHERE `buildingUID`=? AND `playerUID`=? AND `guildUID` =? AND `friendType` = ?"); | 
				
			||||
		setLong(1, buildingID); | 
				
			||||
		setLong(2, friendID); | 
				
			||||
		setLong(3,guildID); | 
				
			||||
		setInt(4, friendType); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void CLEAR_FRIENDS_LIST(final long buildingID) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_building_friends` WHERE `buildingUID`=?"); | 
				
			||||
		setLong(1, buildingID); | 
				
			||||
		executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void CLEAR_CONDEMNED_LIST(final long buildingID) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_building_condemned` WHERE `buildingUID`=?"); | 
				
			||||
		setLong(1, buildingID); | 
				
			||||
		executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CLEAR_PATROL(final long buildingID) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_building_patrol_points` WHERE `buildingUID`=?"); | 
				
			||||
		setLong(1, buildingID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_ALL_FRIENDS_FOR_BUILDING(Building building) { | 
				
			||||
 | 
				
			||||
		if (building == null) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_building_friends` WHERE `buildingUID` = ?"); | 
				
			||||
		setInt(1,building.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				BuildingFriends friend = new BuildingFriends(rs); | 
				
			||||
				switch(friend.getFriendType()){ | 
				
			||||
				case 7: | 
				
			||||
					building.getFriends().put(friend.getPlayerUID(), friend); | 
				
			||||
					break; | 
				
			||||
				case 8: | 
				
			||||
				case 9: | 
				
			||||
					building.getFriends().put(friend.getGuildUID(), friend); | 
				
			||||
					break; | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("LOAD friends for building: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_ALL_CONDEMNED_FOR_BUILDING(Building building) { | 
				
			||||
 | 
				
			||||
		if (building == null) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_building_condemned` WHERE `buildingUID` = ?"); | 
				
			||||
		setInt(1,building.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				Condemned condemn = new Condemned(rs); | 
				
			||||
				switch(condemn.getFriendType()){ | 
				
			||||
				case 2: | 
				
			||||
					building.getCondemned().put(condemn.getPlayerUID(), condemn); | 
				
			||||
					break; | 
				
			||||
				case 4: | 
				
			||||
				case 5: | 
				
			||||
					building.getCondemned().put(condemn.getGuildUID(), condemn); | 
				
			||||
					break; | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("LOAD Condemned for building: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Vector3fImmutable> LOAD_PATROL_POINTS(Building building) { | 
				
			||||
		if (building == null) | 
				
			||||
			return null; | 
				
			||||
		ArrayList<Vector3fImmutable> patrolPoints = new ArrayList<>(); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_building_patrol_points` WHERE `buildingUID` = ?"); | 
				
			||||
		setInt(1,building.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				float x1 = rs.getFloat("patrolX"); | 
				
			||||
				float y1 = rs.getFloat("patrolY"); | 
				
			||||
				float z1 = rs.getFloat("patrolZ"); | 
				
			||||
				Vector3fImmutable patrolPoint = new Vector3fImmutable(x1,y1,z1); | 
				
			||||
				patrolPoints.add(patrolPoint); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("LOAD Patrol Points for building: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return patrolPoints; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_TO_CONDEMNLIST(final long parentUID, final long playerUID, final long guildID, final int friendType) { | 
				
			||||
		prepareCallable("INSERT INTO `dyn_building_condemned` (`buildingUID`, `playerUID`,`guildUID`, `friendType`) VALUES (?,?,?,?)"); | 
				
			||||
		setLong(1, parentUID); | 
				
			||||
		setLong(2, playerUID); | 
				
			||||
		setLong(3, guildID); | 
				
			||||
		setInt(4, friendType); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_TO_PATROL(final long parentUID, final Vector3fImmutable patrolPoint) { | 
				
			||||
		prepareCallable("INSERT INTO `dyn_building_patrol_points` (`buildingUID`, `patrolX`,`patrolY`, `patrolZ`) VALUES (?,?,?,?)"); | 
				
			||||
		setLong(1, parentUID); | 
				
			||||
		setFloat(2, (int)patrolPoint.x); | 
				
			||||
		setFloat(3, (int)patrolPoint.y); | 
				
			||||
		setFloat(4, (int)patrolPoint.z); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_TO_COLLIDE(final long parentUID, final float startX, final float startY, final float endX, final float endY) { | 
				
			||||
		prepareCallable("INSERT INTO `static_building_colliders` (`MeshID`, `startX`,`startY`, `endX`, `endY`) VALUES (?,?,?,?,?)"); | 
				
			||||
		setLong(1, parentUID); | 
				
			||||
		setFloat(2, startX); | 
				
			||||
		setFloat(3, startY); | 
				
			||||
		setFloat(4, endX); | 
				
			||||
		setFloat(5, endY); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Line2D.Float> GET_COLLIDERS(final long meshID) { | 
				
			||||
		ArrayList<Line2D.Float> colliders = new ArrayList<>(); | 
				
			||||
		prepareCallable("SELECT * FROM `static_building_colliders` WHERE `MeshID`=? AND `doorID` =0"); | 
				
			||||
		setLong(1, meshID); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				int startX = rs.getInt("startX"); | 
				
			||||
				int startY = rs.getInt("startY"); | 
				
			||||
				int endX = rs.getInt("endX"); | 
				
			||||
				int endY = rs.getInt("endY"); | 
				
			||||
				colliders.add(new Line2D.Float(startX,startY,endX,endY)); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("dbBuildingHandler.GET_COLLIDERS", e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return colliders; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Line2D.Float> GET_DOOR_COLLIDERS(final long meshID) { | 
				
			||||
		ArrayList<Line2D.Float> colliders = new ArrayList<>(); | 
				
			||||
		prepareCallable("SELECT * FROM `static_building_colliders` WHERE `MeshID`=? AND `doorID` <> 0"); | 
				
			||||
		setLong(1, meshID); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				int startX = rs.getInt("startX"); | 
				
			||||
				int startY = rs.getInt("startY"); | 
				
			||||
				int endX = rs.getInt("endX"); | 
				
			||||
				int endY = rs.getInt("endY"); | 
				
			||||
				colliders.add(new Line2D.Float(startX,startY,endX,endY)); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("dbBuildingHandler.GET_COLLIDERS", e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return colliders; | 
				
			||||
	} | 
				
			||||
	public HashMap<Integer, ArrayList<BuildingRegions>> LOAD_BUILDING_REGIONS() { | 
				
			||||
 | 
				
			||||
		HashMap<Integer, ArrayList<BuildingRegions>> regions; | 
				
			||||
		BuildingRegions thisRegions; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		regions = new HashMap<>(); | 
				
			||||
		int recordsRead = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_building_regions"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
				thisRegions = new BuildingRegions(rs); | 
				
			||||
				if (regions.get(thisRegions.getBuildingID()) == null){ | 
				
			||||
					ArrayList<BuildingRegions> regionsList = new ArrayList<>(); | 
				
			||||
					regionsList.add(thisRegions); | 
				
			||||
					regions.put(thisRegions.getBuildingID(), regionsList); | 
				
			||||
				} | 
				
			||||
				else{ | 
				
			||||
					ArrayList<BuildingRegions>regionsList = regions.get(thisRegions.getBuildingID()); | 
				
			||||
					regionsList.add(thisRegions); | 
				
			||||
					regions.put(thisRegions.getBuildingID(), regionsList); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			Logger.info( "read: " + recordsRead + " cached: " + regions.size()); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(": " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return regions; | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public HashMap<Integer, MeshBounds> LOAD_MESH_BOUNDS() { | 
				
			||||
 | 
				
			||||
		HashMap<Integer, MeshBounds> meshBoundsMap; | 
				
			||||
		MeshBounds meshBounds; | 
				
			||||
 | 
				
			||||
		meshBoundsMap = new HashMap<>(); | 
				
			||||
		int recordsRead = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_mesh_bounds"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
				meshBounds = new MeshBounds(rs); | 
				
			||||
				 | 
				
			||||
				meshBoundsMap.put(meshBounds.meshID, meshBounds); | 
				
			||||
				 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			Logger.info( "read: " + recordsRead + " cached: " + meshBoundsMap.size()); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("LoadMeshBounds: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return meshBoundsMap; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public HashMap<Integer, ArrayList<StaticColliders>> LOAD_ALL_STATIC_COLLIDERS() { | 
				
			||||
 | 
				
			||||
		HashMap<Integer, ArrayList<StaticColliders>> colliders; | 
				
			||||
		StaticColliders thisColliders; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		colliders = new HashMap<>(); | 
				
			||||
		int recordsRead = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_building_colliders"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
				thisColliders = new StaticColliders(rs); | 
				
			||||
				if (colliders.get(thisColliders.getMeshID()) == null){ | 
				
			||||
					ArrayList<StaticColliders> colliderList = new ArrayList<>(); | 
				
			||||
					colliderList.add(thisColliders); | 
				
			||||
					colliders.put(thisColliders.getMeshID(), colliderList); | 
				
			||||
				} | 
				
			||||
				else{ | 
				
			||||
					ArrayList<StaticColliders>colliderList = colliders.get(thisColliders.getMeshID()); | 
				
			||||
					colliderList.add(thisColliders); | 
				
			||||
					colliders.put(thisColliders.getMeshID(), colliderList); | 
				
			||||
				} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			Logger.info( "read: " + recordsRead + " cached: " + colliders.size()); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("LoadAllBlueprints: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return colliders; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	// This public class inserted here as it's a generic utility function
 | 
				
			||||
	// with no other good place for it.  If you find a good home for it
 | 
				
			||||
	// feel free to move it.  -
 | 
				
			||||
 | 
				
			||||
	public final DbObjectType GET_UID_ENUM(long object_UID) { | 
				
			||||
 | 
				
			||||
		DbObjectType storedEnum = DbObjectType.INVALID; | 
				
			||||
		String typeString; | 
				
			||||
 | 
				
			||||
		if (object_UID == 0) | 
				
			||||
			return storedEnum; | 
				
			||||
 | 
				
			||||
		// Set up call to stored procedure
 | 
				
			||||
		prepareCallable("CALL object_UID_ENUM(?)"); | 
				
			||||
		setLong(1, object_UID); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
 | 
				
			||||
			// Evaluate database ordinal and return enum
 | 
				
			||||
			storedEnum = DbObjectType.valueOf(getString("type").toUpperCase()); | 
				
			||||
 | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			storedEnum = DbObjectType.INVALID; | 
				
			||||
			Logger.error("UID_ENUM ", "Orphaned Object? Lookup failed for UID: " + object_UID); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return storedEnum; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ConcurrentHashMap<Integer, Integer> GET_FRIENDS(final long buildingID) { | 
				
			||||
		ConcurrentHashMap<Integer, Integer> friendsList = new ConcurrentHashMap<>(); | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_building_friends` WHERE `buildingUID`=?"); | 
				
			||||
		setLong(1, buildingID); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				int friendType = rs.getInt("friendType"); | 
				
			||||
				switch (friendType) { | 
				
			||||
				case 7: | 
				
			||||
					friendsList.put(rs.getInt("playerUID"), 7); | 
				
			||||
					break; | 
				
			||||
				case 8: | 
				
			||||
					friendsList.put(rs.getInt("guildUID"), 8); | 
				
			||||
					break; | 
				
			||||
				case 9: | 
				
			||||
					friendsList.put(rs.getInt("guildUID"), 9); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("dbBuildingHandler.GET_FRIENDS_GUILD_IC", e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return friendsList; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateBuildingRank(final Building b, int Rank) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_building` SET `rank`=?," | 
				
			||||
				+ "`upgradeDate`=?, `meshUUID`=?, `currentHP`=? " | 
				
			||||
				+ "WHERE `UID` = ?"); | 
				
			||||
 | 
				
			||||
		setInt(1, Rank); | 
				
			||||
		setNULL(2, java.sql.Types.DATE); | 
				
			||||
		setInt(3, b.getBlueprint().getMeshForRank(Rank)); | 
				
			||||
		setInt(4, b.getBlueprint().getMaxHealth(Rank)); | 
				
			||||
		setInt(5, b.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateReverseKOS(final Building b, boolean reverse) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_building` SET `reverseKOS`=? " | 
				
			||||
				+ "WHERE `UID` = ?"); | 
				
			||||
		setBoolean(1, reverse); | 
				
			||||
		setInt(2, b.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateActiveCondemn(final Condemned condemn, boolean active) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `dyn_building_condemned` SET `active`=? " | 
				
			||||
				+ "WHERE`buildingUID` = ? AND `playerUID` = ? AND `guildUID` = ? AND `friendType` = ?"); | 
				
			||||
		setBoolean(1, active); | 
				
			||||
		setInt(2, condemn.getParent()); | 
				
			||||
		setInt(3, condemn.getPlayerUID()); | 
				
			||||
		setInt(4, condemn.getGuildUID()); | 
				
			||||
		setInt(5, condemn.getFriendType()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateBuildingOwner(final Building building, int ownerUUID) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_building` SET `ownerUUID`=? " | 
				
			||||
				+ " WHERE `UID` = ?"); | 
				
			||||
 | 
				
			||||
		setInt(1, ownerUUID); | 
				
			||||
		setInt(2, building.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateBuildingUpgradeTime(LocalDateTime upgradeDateTime, Building toUpgrade, int costToUpgrade) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE obj_building SET upgradeDate=?, currentGold=? " | 
				
			||||
				+ "WHERE UID = ?"); | 
				
			||||
 | 
				
			||||
		if (upgradeDateTime == null) | 
				
			||||
			setNULL(1, java.sql.Types.DATE); | 
				
			||||
		else | 
				
			||||
			setTimeStamp(1, upgradeDateTime.atZone(ZoneId.systemDefault()) | 
				
			||||
					.toInstant().toEpochMilli()); | 
				
			||||
 | 
				
			||||
		setInt(2, toUpgrade.getStrongboxValue() - costToUpgrade); | 
				
			||||
		setInt(3, toUpgrade.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateMaintDate(Building building) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE obj_building SET maintDate=? " | 
				
			||||
				+ "WHERE UID = ?"); | 
				
			||||
 | 
				
			||||
		if (building.maintDateTime == null) | 
				
			||||
			setNULL(1, java.sql.Types.DATE); | 
				
			||||
		else | 
				
			||||
			setLocalDateTime(1, building.maintDateTime); | 
				
			||||
 | 
				
			||||
		setInt(2, building.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean addTaxes(Building building, TaxType taxType, int amount, boolean enforceKOS){ | 
				
			||||
		prepareCallable("UPDATE obj_building SET taxType=?, taxAmount = ?, enforceKOS = ? " | 
				
			||||
				+ "WHERE UID = ?"); | 
				
			||||
 | 
				
			||||
		setString(1, taxType.name()); | 
				
			||||
		setInt(2, amount); | 
				
			||||
		setBoolean(3, enforceKOS); | 
				
			||||
		setInt(4, building.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean removeTaxes(Building building){ | 
				
			||||
		prepareCallable("UPDATE obj_building SET taxType=?, taxAmount = ?, enforceKOS = ?, taxDate = ? " | 
				
			||||
				+ "WHERE UID = ?"); | 
				
			||||
 | 
				
			||||
		setString(1, TaxType.NONE.name()); | 
				
			||||
		setInt(2, 0); | 
				
			||||
		setBoolean(3, false); | 
				
			||||
		setNULL(4, java.sql.Types.DATE); | 
				
			||||
		setInt(5, building.getObjectUUID()); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean acceptTaxes(Building building) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE obj_building SET taxDate=? " | 
				
			||||
				+ "WHERE UID = ?"); | 
				
			||||
 | 
				
			||||
		setTimeStamp(1, DateTime.now().plusDays(7).getMillis()); | 
				
			||||
		setInt(2, building.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,27 @@
				@@ -0,0 +1,27 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.BuildingLocation; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbBuildingLocationHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbBuildingLocationHandler() { | 
				
			||||
		this.localClass = BuildingLocation.class; | 
				
			||||
        this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<BuildingLocation> LOAD_ALL_BUILDING_LOCATIONS() { | 
				
			||||
		prepareCallable("SELECT * FROM `static_building_location`;"); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,100 @@
				@@ -0,0 +1,100 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.Account; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.session.CSSession; | 
				
			||||
import engine.util.StringUtils; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.net.InetAddress; | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
 | 
				
			||||
public class dbCSSessionHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbCSSessionHandler() { | 
				
			||||
		this.localClass = CSSession.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_CSSESSION(String secKey, Account acc, InetAddress inet, String machineID) { | 
				
			||||
        prepareCallable("INSERT INTO `dyn_session` (`secretKey`, `accountID`, `discordAccount`, `sessionIP`, machineID) VALUES (?,?,?,INET_ATON(?),?)"); | 
				
			||||
        setString(1, secKey); | 
				
			||||
		setLong(2, acc.getObjectUUID()); | 
				
			||||
		setString(3, acc.discordAccount); | 
				
			||||
        setString(4, StringUtils.InetAddressToClientString(inet)); | 
				
			||||
        setString(5, machineID); | 
				
			||||
        return (executeUpdate() != 0); | 
				
			||||
    } | 
				
			||||
	// This method returns population metrics from the database
 | 
				
			||||
 | 
				
			||||
	public String GET_POPULATION_STRING() { | 
				
			||||
 | 
				
			||||
		String outString = null; | 
				
			||||
 | 
				
			||||
		// Set up call to stored procedure
 | 
				
			||||
		prepareCallable("CALL GET_POPULATION_STRING()"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
 | 
				
			||||
			// Evaluate database ordinal and return enum
 | 
				
			||||
			outString = getString("popstring"); | 
				
			||||
 | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error( "Failure in stored procedure:" + e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return outString; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean DELETE_UNUSED_CSSESSION(String secKey) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_session` WHERE `secretKey`=? && `characterID` IS NULL"); | 
				
			||||
		setString(1, secKey); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean DELETE_CSSESSION(String secKey) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_session` WHERE `secretKey`=?"); | 
				
			||||
		setString(1, secKey); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_CSSESSION(String secKey, int charID) { | 
				
			||||
		prepareCallable("UPDATE `dyn_session` SET `characterID`=? WHERE `secretKey`=?"); | 
				
			||||
		setInt(1, charID); | 
				
			||||
		setString(2, secKey); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public CSSession GET_CSSESSION(String secKey) { | 
				
			||||
		CSSession css = null; | 
				
			||||
		prepareCallable("SELECT `accountID`, `characterID`, `machineID` FROM `dyn_session` WHERE `secretKey`=?"); | 
				
			||||
		setString(1, secKey); | 
				
			||||
		try { | 
				
			||||
 | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			if (rs.next()) { | 
				
			||||
				css = new CSSession(secKey, DbManager.AccountQueries.GET_ACCOUNT(rs.getInt("accountID")), PlayerCharacter.getPlayerCharacter(rs | 
				
			||||
						.getInt("characterID")), getString("machineID")); | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("Error with seckey: " + secKey); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return css; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,113 @@
				@@ -0,0 +1,113 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.CharacterPower; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
 | 
				
			||||
public class dbCharacterPowerHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbCharacterPowerHandler() { | 
				
			||||
		this.localClass = CharacterPower.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public CharacterPower ADD_CHARACTER_POWER(CharacterPower toAdd) { | 
				
			||||
		if (CharacterPower.getOwner(toAdd) == null || toAdd.getPower() == null) { | 
				
			||||
			Logger.error("dbCharacterSkillHandler.ADD_Power", toAdd.getObjectUUID() + " missing owner or powersBase"); | 
				
			||||
			return null; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		prepareCallable("INSERT INTO `dyn_character_power` (`CharacterID`, `powersBaseToken`, `trains`) VALUES (?, ?, ?);"); | 
				
			||||
		setLong(1, (long)CharacterPower.getOwner(toAdd).getObjectUUID()); | 
				
			||||
		setInt(2, toAdd.getPower().getToken()); | 
				
			||||
		setInt(3, toAdd.getTrains()); | 
				
			||||
		int powerID = insertGetUUID(); | 
				
			||||
		return GET_CHARACTER_POWER(powerID); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public int DELETE_CHARACTER_POWER(final int objectUUID) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_character_power` WHERE `UID` = ?"); | 
				
			||||
		setLong(1, (long)objectUUID); | 
				
			||||
		return executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public CharacterPower GET_CHARACTER_POWER(int objectUUID) { | 
				
			||||
 | 
				
			||||
		CharacterPower cp = (CharacterPower) DbManager.getFromCache(Enum.GameObjectType.CharacterPower, objectUUID); | 
				
			||||
		if (cp != null) | 
				
			||||
			return cp; | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_character_power` WHERE `UID` = ?"); | 
				
			||||
		setLong(1, (long)objectUUID); | 
				
			||||
		return (CharacterPower) getObjectSingle(objectUUID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ConcurrentHashMap<Integer, CharacterPower> GET_POWERS_FOR_CHARACTER(PlayerCharacter pc) { | 
				
			||||
		ConcurrentHashMap<Integer, CharacterPower> powers = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); | 
				
			||||
		int objectUUID = pc.getObjectUUID(); | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_character_power` WHERE CharacterID = ?"); | 
				
			||||
		setLong(1, (long)objectUUID); | 
				
			||||
		ResultSet rs = executeQuery(); | 
				
			||||
		try { | 
				
			||||
			while (rs.next()) { | 
				
			||||
				CharacterPower cp = new CharacterPower(rs, pc); | 
				
			||||
				if (cp.getPower() != null) | 
				
			||||
					powers.put(cp.getPower().getToken(), cp); | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("CharacterPower.getCharacterPowerForCharacter", "Exception:" + e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return powers; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void UPDATE_TRAINS(final CharacterPower pow) { | 
				
			||||
		//skip update if nothing changed
 | 
				
			||||
		if (!pow.isTrained()) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `dyn_character_power` SET `trains`=? WHERE `UID`=?"); | 
				
			||||
		setShort(1, (short)pow.getTrains()); | 
				
			||||
		setInt(2, pow.getObjectUUID()); | 
				
			||||
		executeUpdate(); | 
				
			||||
		pow.setTrained(false); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void updateDatabase(final CharacterPower pow) { | 
				
			||||
		if (pow.getPower() == null) { | 
				
			||||
			Logger.error( "Failed to find powersBase for Power " + pow.getObjectUUID()); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		if (CharacterPower.getOwner(pow) == null) { | 
				
			||||
			Logger.error( "Failed to find owner for Power " + pow.getObjectUUID()); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `dyn_character_power` SET `PowersBaseToken`=?, `CharacterID`=?, `trains`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, pow.getPower().getToken()); | 
				
			||||
		setInt(2, CharacterPower.getOwner(pow).getObjectUUID()); | 
				
			||||
		setShort(3, (short)pow.getTrains()); | 
				
			||||
		setInt(4, pow.getObjectUUID()); | 
				
			||||
		executeUpdate(); | 
				
			||||
		pow.setTrained(false); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,63 @@
				@@ -0,0 +1,63 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.CharacterRune; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbCharacterRuneHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbCharacterRuneHandler() { | 
				
			||||
		this.localClass = CharacterRune.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public CharacterRune ADD_CHARACTER_RUNE(final CharacterRune toAdd) { | 
				
			||||
		prepareCallable("INSERT INTO `dyn_character_rune` (`CharacterID`, `RuneBaseID`) VALUES (?, ?);"); | 
				
			||||
		setLong(1, (long)toAdd.getPlayerID()); | 
				
			||||
		setInt(2, toAdd.getRuneBaseID()); | 
				
			||||
		int runeID = insertGetUUID(); | 
				
			||||
		return GET_CHARACTER_RUNE(runeID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public CharacterRune GET_CHARACTER_RUNE(int runeID) { | 
				
			||||
 | 
				
			||||
		CharacterRune charRune = (CharacterRune) DbManager.getFromCache(Enum.GameObjectType.CharacterRune, runeID); | 
				
			||||
		if (charRune != null) | 
				
			||||
			return charRune; | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_character_rune` WHERE `UID`=?"); | 
				
			||||
		setInt(1, runeID); | 
				
			||||
		return (CharacterRune) getObjectSingle(runeID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public boolean DELETE_CHARACTER_RUNE(final CharacterRune cr) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_character_rune` WHERE `UID`=?;"); | 
				
			||||
		setLong(1, (long)cr.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<CharacterRune> GET_RUNES_FOR_CHARACTER(final int characterId) { | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_character_rune` WHERE `CharacterID` = ?"); | 
				
			||||
		setInt(1, characterId); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void updateDatabase(final CharacterRune cr) { | 
				
			||||
		prepareCallable("UPDATE `dyn_character_rune` SET `CharacterID`=?, `RuneBaseID`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, cr.getPlayerID()); | 
				
			||||
		setInt(2, cr.getRuneBaseID()); | 
				
			||||
		setLong(3, (long) cr.getObjectUUID()); | 
				
			||||
		executeUpdate(); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,116 @@
				@@ -0,0 +1,116 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.AbstractCharacter; | 
				
			||||
import engine.objects.CharacterSkill; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
 | 
				
			||||
public class dbCharacterSkillHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbCharacterSkillHandler() { | 
				
			||||
		this.localClass = CharacterSkill.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public CharacterSkill ADD_SKILL(CharacterSkill toAdd) { | 
				
			||||
		if (CharacterSkill.GetOwner(toAdd) == null || toAdd.getSkillsBase() == null) { | 
				
			||||
			Logger.error("dbCharacterSkillHandler.ADD_SKILL", toAdd.getObjectUUID() + " missing owner or skillsBase"); | 
				
			||||
			return null; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		prepareCallable("INSERT INTO `dyn_character_skill` (`CharacterID`, `skillsBaseID`, `trains`) VALUES (?, ?, ?);"); | 
				
			||||
		setLong(1, (long)CharacterSkill.GetOwner(toAdd).getObjectUUID()); | 
				
			||||
		setInt(2, toAdd.getSkillsBase().getObjectUUID()); | 
				
			||||
		setInt(3, toAdd.getNumTrains()); | 
				
			||||
		int skillID = insertGetUUID(); | 
				
			||||
		return GET_SKILL(skillID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean DELETE_SKILL(final int objectUUID) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_character_skill` WHERE `UID` = ?"); | 
				
			||||
		setLong(1, (long)objectUUID); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public CharacterSkill GET_SKILL(final int objectUUID) { | 
				
			||||
		CharacterSkill skill = (CharacterSkill) DbManager.getFromCache(Enum.GameObjectType.CharacterSkill, objectUUID); | 
				
			||||
		if (skill != null) | 
				
			||||
			return skill; | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_character_skill` WHERE `UID` = ?"); | 
				
			||||
		setInt(1, objectUUID); | 
				
			||||
		return (CharacterSkill) getObjectSingle(objectUUID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ConcurrentHashMap<String, CharacterSkill> GET_SKILLS_FOR_CHARACTER(final AbstractCharacter ac) { | 
				
			||||
		ConcurrentHashMap<String, CharacterSkill> skills = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); | 
				
			||||
		if (ac == null || (!(ac.getObjectType().equals(Enum.GameObjectType.PlayerCharacter)))) | 
				
			||||
			return skills; | 
				
			||||
		PlayerCharacter pc = (PlayerCharacter) ac; | 
				
			||||
		int objectUUID = pc.getObjectUUID(); | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_character_skill` WHERE `CharacterID` = ?"); | 
				
			||||
		setInt(1, objectUUID); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				CharacterSkill cs = new CharacterSkill(rs, pc); | 
				
			||||
				if (cs.getSkillsBase() != null) | 
				
			||||
					skills.put(cs.getSkillsBase().getName(), cs); | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("CharacterSkill.getCharacterSkillForCharacter", e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return skills; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public void UPDATE_TRAINS(final CharacterSkill cs) { | 
				
			||||
		if (!cs.isTrained()) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `dyn_character_skill` SET `trains`=? WHERE `UID` = ?"); | 
				
			||||
		setShort(1, (short)cs.getNumTrains()); | 
				
			||||
		setLong(2, (long)cs.getObjectUUID()); | 
				
			||||
		if (executeUpdate() != 0) | 
				
			||||
			cs.syncTrains(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void updateDatabase(final CharacterSkill cs) { | 
				
			||||
		if (cs.getSkillsBase() == null) { | 
				
			||||
			Logger.error("Failed to find skillsBase for Skill " + cs.getObjectUUID()); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		if (CharacterSkill.GetOwner(cs) == null) { | 
				
			||||
			Logger.error("Failed to find owner for Skill " + cs.getObjectUUID()); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `dyn_character_skill` SET `skillsBaseID`=?, `CharacterID`=?, `trains`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, cs.getSkillsBase().getObjectUUID()); | 
				
			||||
		setInt(2, CharacterSkill.GetOwner(cs).getObjectUUID()); | 
				
			||||
		setShort(3, (short)cs.getNumTrains()); | 
				
			||||
		setLong(4, (long)cs.getObjectUUID()); | 
				
			||||
		if (executeUpdate() != 0) | 
				
			||||
			cs.syncTrains(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,196 @@
				@@ -0,0 +1,196 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.Building; | 
				
			||||
import engine.objects.City; | 
				
			||||
import engine.objects.Zone; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.net.UnknownHostException; | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbCityHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbCityHandler() { | 
				
			||||
		this.localClass = City.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<AbstractGameObject> CREATE_CITY(int ownerID, int parentZoneID, int realmID, float xCoord, float yCoord, float zCoord, float rotation, float W, String name, LocalDateTime established) { | 
				
			||||
		prepareCallable("CALL `city_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?,?,?)"); | 
				
			||||
		LocalDateTime upgradeTime = LocalDateTime.now().plusHours(2); | 
				
			||||
		setLong(1, (long) ownerID); //objectUUID of owning player
 | 
				
			||||
		setLong(2, (long) parentZoneID); //objectUUID of parent (continent) zone
 | 
				
			||||
		setLong(3, (long) realmID); //objectUUID of realm city belongs in
 | 
				
			||||
		setFloat(4, xCoord); //xOffset from parentZone center
 | 
				
			||||
		setFloat(5, yCoord); //yOffset from parentZone center
 | 
				
			||||
		setFloat(6, zCoord); //zOffset from parentZone center
 | 
				
			||||
		setString(7, name); //city name
 | 
				
			||||
		setLocalDateTime(8, established); | 
				
			||||
		setFloat(9, rotation); | 
				
			||||
		setFloat(10, W); | 
				
			||||
		setLocalDateTime(11, upgradeTime); | 
				
			||||
		ArrayList<AbstractGameObject> list = new ArrayList<>(); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			boolean work = execute(); | 
				
			||||
			if (work) { | 
				
			||||
				ResultSet rs = this.cs.get().getResultSet(); | 
				
			||||
				while (rs.next()) { | 
				
			||||
					addObject(list, rs); | 
				
			||||
				} | 
				
			||||
				rs.close(); | 
				
			||||
			} else { | 
				
			||||
				Logger.info("City Placement Failed: " + this.cs.get().toString()); | 
				
			||||
				return list; //city creation failure
 | 
				
			||||
			} | 
				
			||||
			while (this.cs.get().getMoreResults()) { | 
				
			||||
				ResultSet rs = this.cs.get().getResultSet(); | 
				
			||||
				while (rs.next()) { | 
				
			||||
					addObject(list, rs); | 
				
			||||
				} | 
				
			||||
				rs.close(); | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.info("City Placement Failed, SQLException: " + this.cs.get().toString() + e.toString()); | 
				
			||||
			return list; //city creation failure
 | 
				
			||||
		} catch (UnknownHostException e) { | 
				
			||||
			Logger.info("City Placement Failed, UnknownHostException: " + this.cs.get().toString()); | 
				
			||||
			return list; //city creation failure
 | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return list; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static void addObject(ArrayList<AbstractGameObject> list, ResultSet rs) throws SQLException, UnknownHostException { | 
				
			||||
		String type = rs.getString("type"); | 
				
			||||
		switch (type) { | 
				
			||||
		case "zone": | 
				
			||||
			Zone zone = new Zone(rs); | 
				
			||||
			DbManager.addToCache(zone); | 
				
			||||
			list.add(zone); | 
				
			||||
			break; | 
				
			||||
		case "building": | 
				
			||||
			Building building = new Building(rs); | 
				
			||||
			DbManager.addToCache(building); | 
				
			||||
			list.add(building); | 
				
			||||
			break; | 
				
			||||
		case "city": | 
				
			||||
			City city = new City(rs); | 
				
			||||
			DbManager.addToCache(city); | 
				
			||||
			list.add(city); | 
				
			||||
			break; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<City> GET_CITIES_BY_ZONE(final int objectUUID) { | 
				
			||||
		prepareCallable("SELECT `obj_city`.*, `object`.`parent` FROM `obj_city` INNER JOIN `object` ON `object`.`UID` = `obj_city`.`UID` WHERE `object`.`parent`=?;"); | 
				
			||||
		setLong(1, (long) objectUUID); | 
				
			||||
 | 
				
			||||
        return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public City GET_CITY(final int cityId) { | 
				
			||||
		City city = (City) DbManager.getFromCache(Enum.GameObjectType.City, cityId); | 
				
			||||
		if (city != null) | 
				
			||||
			return city; | 
				
			||||
		prepareCallable("SELECT `obj_city`.*, `object`.`parent` FROM `obj_city` INNER JOIN `object` ON `object`.`UID` = `obj_city`.`UID` WHERE `object`.`UID`=?;"); | 
				
			||||
		setLong(1, (long) cityId); | 
				
			||||
		city = (City) getObjectSingle(cityId); | 
				
			||||
		return city; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final City c, String name, Object new_value) { | 
				
			||||
		prepareCallable("CALL city_SETPROP(?,?,?)"); | 
				
			||||
		setLong(1, (long) c.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final City c, String name, Object new_value, Object old_value) { | 
				
			||||
		prepareCallable("CALL city_GETSETPROP(?,?,?,?)"); | 
				
			||||
		setLong(1, (long) c.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		setString(4, String.valueOf(old_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateforceRename(City city, boolean value) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_city` SET `forceRename`=?" | 
				
			||||
				+ " WHERE `UID` = ?"); | 
				
			||||
		setByte(1, (value == true) ? (byte) 1 : (byte) 0); | 
				
			||||
		setInt(2, city.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateOpenCity(City city, boolean value) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_city` SET `open`=?" | 
				
			||||
				+ " WHERE `UID` = ?"); | 
				
			||||
		setByte(1, (value == true) ? (byte) 1 : (byte) 0); | 
				
			||||
		setInt(2, city.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateTOL(City city, int tolID) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_city` SET `treeOfLifeUUID`=?" | 
				
			||||
				+ " WHERE `UID` = ?"); | 
				
			||||
		setInt(1,tolID); | 
				
			||||
		setInt(2, city.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean renameCity(City city, String name) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_city` SET `name`=?" | 
				
			||||
				+ " WHERE `UID` = ?"); | 
				
			||||
		setString(1, name); | 
				
			||||
		setInt(2, city.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateSiegesWithstood(City city, int value) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_city` SET `siegesWithstood`=?" | 
				
			||||
				+ " WHERE `UID` = ?"); | 
				
			||||
		setInt(1, value); | 
				
			||||
		setInt(2, city.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateRealmTaxDate(City city, LocalDateTime localDateTime) { | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_city` SET `realmTaxDate` =?" | 
				
			||||
				+ " WHERE `UID` = ?"); | 
				
			||||
		setLocalDateTime(1, localDateTime); | 
				
			||||
		setInt(2,city.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean DELETE_CITY(final City city) { | 
				
			||||
 | 
				
			||||
		prepareCallable("DELETE FROM `object` WHERE `UID` = ? AND `type` = 'city'"); | 
				
			||||
		setInt(1, city.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,157 @@
				@@ -0,0 +1,157 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.Contract; | 
				
			||||
import engine.objects.ItemBase; | 
				
			||||
import engine.objects.MobEquipment; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbContractHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbContractHandler() { | 
				
			||||
		this.localClass = Contract.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Contract GET_CONTRACT(final int objectUUID) { | 
				
			||||
		Contract contract = (Contract) DbManager.getFromCache(Enum.GameObjectType.Contract, objectUUID); | 
				
			||||
		if (contract != null) | 
				
			||||
			return contract; | 
				
			||||
		if (objectUUID == 0) | 
				
			||||
			return null; | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_contract` WHERE `ID` = ?"); | 
				
			||||
		setInt(1, objectUUID); | 
				
			||||
		return (Contract) getObjectSingle(objectUUID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Contract> GET_CONTRACT_BY_RACE(final int objectUUID) { | 
				
			||||
 | 
				
			||||
		ArrayList<Contract> contracts = new ArrayList<>(); | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_npc_contract WHERE `mobbaseID` =?;"); | 
				
			||||
		setLong(1, objectUUID); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				Contract contract = new Contract(rs); | 
				
			||||
				if (contract != null) | 
				
			||||
					contracts.add(contract); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return contracts; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void GET_GENERIC_INVENTORY(final Contract contract) { | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_inventoryset` WHERE `inventorySet` = ?;"); | 
				
			||||
		setInt(1, contract.inventorySet); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				//handle item base
 | 
				
			||||
				int itemBaseID = rs.getInt("itembaseID"); | 
				
			||||
 | 
				
			||||
				ItemBase ib = ItemBase.getItemBase(itemBaseID); | 
				
			||||
 | 
				
			||||
				if (ib != null) { | 
				
			||||
 | 
				
			||||
					MobEquipment me = new MobEquipment(ib, 0, 0); | 
				
			||||
					contract.getSellInventory().add(me); | 
				
			||||
 | 
				
			||||
					//handle magic effects
 | 
				
			||||
					String prefix = rs.getString("prefix"); | 
				
			||||
					int pRank = rs.getInt("pRank"); | 
				
			||||
					String suffix = rs.getString("suffix"); | 
				
			||||
					int sRank = rs.getInt("sRank"); | 
				
			||||
 | 
				
			||||
					if (prefix != null) { | 
				
			||||
						me.setPrefix(prefix, pRank); | 
				
			||||
						me.setIsID(true); | 
				
			||||
					} | 
				
			||||
 | 
				
			||||
					if (suffix != null) { | 
				
			||||
						me.setSuffix(suffix, sRank); | 
				
			||||
						me.setIsID(true); | 
				
			||||
					} | 
				
			||||
 | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode() + ' ' + e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void GET_SELL_LISTS(final Contract con) { | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_contract_selltype` WHERE `contractID` = ?;"); | 
				
			||||
		setInt(1, con.getObjectUUID()); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			ArrayList<Integer> item = con.getBuyItemType(); | 
				
			||||
			ArrayList<Integer> skill = con.getBuySkillToken(); | 
				
			||||
			ArrayList<Integer> unknown = con.getBuyUnknownToken(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				int type = rs.getInt("type"); | 
				
			||||
				int value = rs.getInt("value"); | 
				
			||||
				if (type == 1) { | 
				
			||||
					item.add(value); | 
				
			||||
				} else if (type == 2) { | 
				
			||||
					skill.add(value); | 
				
			||||
				} else if (type == 3) { | 
				
			||||
					unknown.add(value); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode() + ' ' + e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateAllowedBuildings(final Contract con, final long slotbitvalue) { | 
				
			||||
		prepareCallable("UPDATE `static_npc_contract` SET `allowedBuildingTypeID`=? WHERE `contractID`=?"); | 
				
			||||
		setLong(1, slotbitvalue); | 
				
			||||
		setInt(2, con.getContractID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateDatabase(final Contract con) { | 
				
			||||
		prepareCallable("UPDATE `static_npc_contract` SET `contractID`=?, `name`=?, " | 
				
			||||
				+ "`mobbaseID`=?, `classID`=?, vendorDialog=?, iconID=?, allowedBuildingTypeID=? WHERE `ID`=?"); | 
				
			||||
		setInt(1, con.getContractID()); | 
				
			||||
		setString(2, con.getName()); | 
				
			||||
		setInt(3, con.getMobbaseID()); | 
				
			||||
		setInt(4, con.getClassID()); | 
				
			||||
		setInt(5, (con.getVendorDialog() != null) ? con.getVendorDialog().getObjectUUID() : 0); | 
				
			||||
		setInt(6, con.getIconID()); | 
				
			||||
		setInt(8, con.getObjectUUID()); | 
				
			||||
		setLong(7, con.getAllowedBuildings().toLong()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,181 @@
				@@ -0,0 +1,181 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
public class dbEffectsBaseHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbEffectsBaseHandler() { | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public boolean CreateEffectBase(int token, String IDString,String name,int flags){ | 
				
			||||
		prepareCallable("INSERT INTO `wpak_static_power_effectbase` (`token`,`IDString`,`name`,`flags`) VALUES (?,?,?,?)"); | 
				
			||||
		setInt(1,token); | 
				
			||||
		setString(2,IDString); | 
				
			||||
		setString(3,name); | 
				
			||||
		setInt(4,flags); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean CreateEffectBaseRAW(String IDString,String type,String detail){ | 
				
			||||
		prepareCallable("INSERT INTO `wpak_effect_effectbase_raw` (`token`,`IDString`,`name`,`flags`) VALUES (?,?,?,?)"); | 
				
			||||
		setString(1,IDString); | 
				
			||||
		setString(2,type); | 
				
			||||
		setString(3,detail); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CreateEffectSource(String IDString,String source){ | 
				
			||||
		prepareCallable("INSERT INTO `wpak_static_power_sourcetype` (`IDString`,`source`) VALUES (?,?)"); | 
				
			||||
 | 
				
			||||
		setString(1,IDString); | 
				
			||||
		setString(2,source); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean CreateEffectSourceRAW(String IDString,String type,String detail){ | 
				
			||||
		prepareCallable("INSERT INTO `wpak_effect_source_raw` (`effectID`,`type`, `text`) VALUES (?,?,?)"); | 
				
			||||
 | 
				
			||||
		setString(1,IDString); | 
				
			||||
		setString(2,type); | 
				
			||||
		setString(3,detail); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CreateEffectCondition(String IDString,String powerOrEffect,String type,float amount,float ramp,byte useAddFormula,String damageType1,String damageType2,String damageType3){ | 
				
			||||
		prepareCallable("INSERT INTO `wpak_static_power_failcondition` (`IDString`,`powerOrEffect`,`type`,`amount`,`ramp`,`useAddFormula`,`damageType1`,`damageType2`,`damageType3`) VALUES (?,?,?,?,?,?,?,?,?)"); | 
				
			||||
		setString(1,IDString); | 
				
			||||
		setString(2,powerOrEffect); | 
				
			||||
		setString(3,type); | 
				
			||||
		setFloat(4,amount); | 
				
			||||
		setFloat(5,ramp); | 
				
			||||
		setByte(6,useAddFormula); | 
				
			||||
		setString(7,damageType1); | 
				
			||||
		setString(8,damageType2); | 
				
			||||
		setString(9,damageType3); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean CreateEffectConditionRAW(String IDString,String type,String detail){ | 
				
			||||
		prepareCallable("INSERT INTO `wpak_effect_condition_raw` (`effectID`,`type`, `text`) VALUES (?,?,?)"); | 
				
			||||
		setString(1,IDString); | 
				
			||||
		setString(2,type); | 
				
			||||
		setString(3,detail); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CreateEffectMod(String IDString,String modType,float minMod,float maxMod,float percentMod,float ramp,byte useRampAdd,String type,String string1,String string2){ | 
				
			||||
		prepareCallable("INSERT INTO `wpak_static_power_effectmod` (`IDString`,`modType`,`minMod`,`maxMod`,`percentMod`,`ramp`,`useRampAdd`,`type`,`string1`,`string2`) VALUES (?,?,?,?,?,?,?,?,?,?)"); | 
				
			||||
		setString(1, IDString); | 
				
			||||
		setString(2, modType); | 
				
			||||
		setFloat(3, minMod); | 
				
			||||
		setFloat(4, maxMod); | 
				
			||||
		setFloat(5, percentMod); | 
				
			||||
		setFloat(6, ramp); | 
				
			||||
		setByte(7, useRampAdd); | 
				
			||||
		setString(8, type); | 
				
			||||
		setString(9, string1); | 
				
			||||
		setString(10, string2); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean CreateEffectModRAW(String IDString,String type,String detail){ | 
				
			||||
		prepareCallable("INSERT INTO `wpak_effect_mod_raw` (`effectID`,`type`, `text`) VALUES (?,?,?)"); | 
				
			||||
		setString(1,IDString); | 
				
			||||
		setString(2,type); | 
				
			||||
		setString(3,detail); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
 | 
				
			||||
	public boolean CreatePowerPowerAction(String IDString,String type,String effectID,String effectID2,String deferredPowerID,float levelCap,float levelCapRamp,String damageType,int numIterations,String effectSourceToRemove,String trackFilter,int maxTrack,int mobID,int mobLevel,int simpleDamage,String transferFromType,String transferToType,float transferAmount,float transferRamp,float transferEfficiency,float transferEfficiencyRamp,int flags){ | 
				
			||||
		prepareCallable("INSERT INTO `wpak_static_power_poweraction` (`IDString`,`type`,`effectID`,`effectID2`,`deferredPowerID`,`levelCap`,`levelCapRamp`,`damageType`,`numIterations`,`effectSourceToRemove`,`trackFilter`,`maxTrack`,`mobID`,`mobLevel`,`simpleDamage`,`transferFromType`,`transferToType`,`transferAmount`,`transferRamp`,`transferEfficiency`,`transferEfficiencyRamp`,`flags`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"); | 
				
			||||
 | 
				
			||||
		setString(1,IDString); | 
				
			||||
		setString(2,type); | 
				
			||||
		setString(3,effectID); | 
				
			||||
		setString(4,effectID2); | 
				
			||||
		setString(5,deferredPowerID); | 
				
			||||
		setFloat(6,levelCap); | 
				
			||||
		setFloat(7,levelCapRamp); | 
				
			||||
		setString(8,damageType); | 
				
			||||
		setInt(9,numIterations); | 
				
			||||
		setString(10,effectSourceToRemove); | 
				
			||||
		setString(11,trackFilter); | 
				
			||||
		setInt(12,maxTrack); | 
				
			||||
		setInt(13,mobID); | 
				
			||||
		setInt(14,mobLevel); | 
				
			||||
		setInt(15,simpleDamage); | 
				
			||||
		setString(16,transferFromType); | 
				
			||||
		setString(17,transferToType); | 
				
			||||
		setFloat(18,transferAmount); | 
				
			||||
		setFloat(19,transferRamp); | 
				
			||||
		setFloat(20,transferEfficiency); | 
				
			||||
		setFloat(21,transferEfficiencyRamp); | 
				
			||||
		setInt(22,flags); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean CreatePowerPowerActionRAW(String IDString,String type,String detail){ | 
				
			||||
		prepareCallable("INSERT INTO `wpak_effect_poweraction_raw` (`effectID`,`type`, `text`) VALUES (?,?,?)"); | 
				
			||||
 | 
				
			||||
		setString(1,IDString); | 
				
			||||
		setString(2,type); | 
				
			||||
		setString(3,detail); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ClearAllEffectBase(){ | 
				
			||||
		prepareCallable("DELETE from `wpak_static_power_effectbase`"); | 
				
			||||
		executeUpdate(); | 
				
			||||
 | 
				
			||||
		prepareCallable(" DELETE from `wpak_static_power_sourcetype` "); | 
				
			||||
		executeUpdate(); | 
				
			||||
 | 
				
			||||
		prepareCallable(" DELETE from `wpak_static_power_failcondition` WHERE `powerOrEffect` = ?"); | 
				
			||||
		setString(1,"Effect"); | 
				
			||||
		executeUpdate(); | 
				
			||||
 | 
				
			||||
		prepareCallable(" DELETE from `wpak_static_power_effectmod` "); | 
				
			||||
		executeUpdate(); | 
				
			||||
 | 
				
			||||
		return true; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ResetIncrement(){ | 
				
			||||
		prepareCallable("ALTER TABLE `wpak_static_power_effectbase` AUTO_INCREMENT = 1"); | 
				
			||||
		executeUpdate(); | 
				
			||||
 | 
				
			||||
		prepareCallable("ALTER TABLE `wpak_static_power_sourcetype` AUTO_INCREMENT = 1"); | 
				
			||||
		executeUpdate(); | 
				
			||||
 | 
				
			||||
		prepareCallable("ALTER TABLE `wpak_static_power_failcondition` AUTO_INCREMENT = 1"); | 
				
			||||
		executeUpdate(); | 
				
			||||
 | 
				
			||||
		prepareCallable("ALTER TABLE `wpak_static_power_effectmod` AUTO_INCREMENT = 1"); | 
				
			||||
		executeUpdate(); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		return true; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,30 @@
				@@ -0,0 +1,30 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.EffectsResourceCosts; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbEffectsResourceCostHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbEffectsResourceCostHandler() { | 
				
			||||
		this.localClass = EffectsResourceCosts.class; | 
				
			||||
        this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public ArrayList<EffectsResourceCosts> GET_ALL_EFFECT_RESOURCES(String idString) { | 
				
			||||
		prepareCallable("SELECT * FROM `static_power_effectcost`  WHERE `IDString` = ?"); | 
				
			||||
		setString(1, idString); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,51 @@
				@@ -0,0 +1,51 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
 | 
				
			||||
public class dbEnchantmentHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public ConcurrentHashMap<String, Integer> GET_ENCHANTMENTS_FOR_ITEM(final int id) { | 
				
			||||
		ConcurrentHashMap<String, Integer> enchants = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_item_enchantment` WHERE `ItemID`=?;"); | 
				
			||||
		setLong(1, (long)id); | 
				
			||||
		try { | 
				
			||||
			ResultSet resultSet = executeQuery(); | 
				
			||||
			while (resultSet.next()) | 
				
			||||
				enchants.put(resultSet.getString("powerAction"), resultSet.getInt("rank")); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return enchants; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CREATE_ENCHANTMENT_FOR_ITEM(long itemID, String powerAction, int rank) { | 
				
			||||
		prepareCallable("INSERT INTO `dyn_item_enchantment` (`itemID`, `powerAction`, `rank`) VALUES (?, ?, ?);"); | 
				
			||||
		setLong(1, itemID); | 
				
			||||
		setString(2, powerAction); | 
				
			||||
		setInt(3, rank); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CLEAR_ENCHANTMENTS(long itemID) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_item_enchantment` WHERE `itemID`=?;"); | 
				
			||||
		setLong(1, itemID); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,486 @@
				@@ -0,0 +1,486 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.Enum.GuildHistoryType; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.joda.time.DateTime; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbGuildHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbGuildHandler() { | 
				
			||||
		this.localClass = Guild.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public int BANISH_FROM_GUILD_OFFLINE(final int target, boolean sourceIsGuildLeader) { | 
				
			||||
		if (!sourceIsGuildLeader)  //one IC cannot banish another IC
 | 
				
			||||
			prepareCallable("UPDATE `obj_character` SET `guildUID`=NULL, `guild_isInnerCouncil`=0, `guild_isTaxCollector`=0," | 
				
			||||
					+ " `guild_isRecruiter`=0, `guild_isFullMember`=0, `guild_title`=0 WHERE `UID`=? && `guild_isInnerCouncil`=0"); | 
				
			||||
		else | 
				
			||||
			prepareCallable("UPDATE `obj_character` SET `guildUID`=NULL, `guild_isInnerCouncil`=0, `guild_isTaxCollector`=0," | 
				
			||||
					+ " `guild_isRecruiter`=0, `guild_isFullMember`=0, `guild_title`=0 WHERE `UID`=?"); | 
				
			||||
		setLong(1, (long) target); | 
				
			||||
		return executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public boolean ADD_TO_BANISHED_FROM_GUILDLIST(int target, long characterID) { | 
				
			||||
		prepareCallable("INSERT INTO  `dyn_guild_banishlist` (`GuildID`, `CharacterID`) VALUES (?,?)"); | 
				
			||||
		setLong(1, (long) target); | 
				
			||||
		setLong(2, characterID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean REMOVE_FROM_BANISH_LIST(int target, long characterID) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_guild_banishlist` (`GuildID`, `CharacterID`) VALUES (?,?)"); | 
				
			||||
		setLong(1, (long) target); | 
				
			||||
		setLong(2, characterID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_TO_GUILDHISTORY(int target, PlayerCharacter pc, DateTime historyDate, GuildHistoryType historyType) { | 
				
			||||
		prepareCallable("INSERT INTO  `dyn_character_guildhistory` (`GuildID`, `CharacterID`, `historyDate`, `historyType`) VALUES (?,?,?,?)"); | 
				
			||||
		setLong(1, (long) target); | 
				
			||||
		setLong(2, pc.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		if (historyDate == null) | 
				
			||||
			setNULL(3, java.sql.Types.DATE); | 
				
			||||
		else | 
				
			||||
			setTimeStamp(3, historyDate.getMillis()); | 
				
			||||
		setString(4,historyType.name()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	//TODO Need to get this working.
 | 
				
			||||
	public ArrayList<Guild> GET_GUILD_HISTORY_OF_PLAYER(final int id) { | 
				
			||||
		prepareCallable("SELECT g.* FROM `obj_guild` g, `dyn_character_guildhistory` l WHERE  g.`UID` = l.`GuildID` && l.`CharacterID` = ?"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String GET_GUILD_LIST(int guildType) { | 
				
			||||
 | 
				
			||||
		String newLine = System.getProperty("line.separator"); | 
				
			||||
		String outputStr = null; | 
				
			||||
		ResultSet resultSet; | 
				
			||||
 | 
				
			||||
		// Setup and execute stored procedure
 | 
				
			||||
 | 
				
			||||
		prepareCallable("CALL `guild_GETLIST`(?)"); | 
				
			||||
		setInt(1, guildType); | 
				
			||||
		resultSet = executeQuery(); | 
				
			||||
 | 
				
			||||
		// Build formatted string with data from query
 | 
				
			||||
 | 
				
			||||
		outputStr += newLine; | 
				
			||||
		outputStr += String.format("%-10s %-30s %-10s %-10s", "UUID", "Name", "GL UUID", "TOL_UUID"); | 
				
			||||
		outputStr += newLine; | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
 | 
				
			||||
			while (resultSet.next()) { | 
				
			||||
 | 
				
			||||
				outputStr += String.format("%-10d %-30s %-10d %-10d", resultSet.getInt(1), | 
				
			||||
						resultSet.getString(2), resultSet.getInt(3), resultSet.getInt(4)); | 
				
			||||
				outputStr += newLine; | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			// Exception handling
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return outputStr; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public ArrayList<Guild> GET_GUILD_ALLIES(final int id) { | 
				
			||||
		prepareCallable("SELECT g.* FROM `obj_guild` g, `dyn_guild_allianceenemylist` l " | 
				
			||||
				+ "WHERE l.isAlliance = 1 && l.OtherGuildID = g.UID && l.GuildID=?"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return getObjectList(); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static ArrayList<PlayerCharacter> GET_GUILD_BANISHED(final int id) { | 
				
			||||
 | 
				
			||||
		return new ArrayList<>(); | 
				
			||||
 | 
				
			||||
		// Bugfix
 | 
				
			||||
		// prepareCallable("SELECT * FROM `obj_character`, `dyn_guild_banishlist` WHERE `obj_character.char_isActive` = 1 AND `dyn_guild_banishlist.CharacterID` = `obj_character.UID` AND `obj_character.GuildID`=?");
 | 
				
			||||
 | 
				
			||||
		//prepareCallable("SELECT * FROM `obj_character` `,` `dyn_guild_banishlist` WHERE obj_character.char_isActive = 1 AND dyn_guild_banishlist.CharacterID = obj_character.UID AND dyn_guild_banishlist.GuildID = ?");
 | 
				
			||||
		//setLong(1, (long) id);
 | 
				
			||||
 | 
				
			||||
		//return getObjectList();
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Guild> GET_GUILD_ENEMIES(final int id) { | 
				
			||||
		prepareCallable("SELECT g.* FROM `obj_guild` g, `dyn_guild_allianceenemylist` l " | 
				
			||||
				+ "WHERE l.isAlliance = 0 && l.OtherGuildID = g.UID && l.GuildID=?"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<PlayerCharacter> GET_GUILD_KOS_CHARACTER(final int id) { | 
				
			||||
		prepareCallable("SELECT c.* FROM `obj_character` c, `dyn_guild_characterkoslist` l WHERE c.`char_isActive` = 1 && l.`KOSCharacterID` = c.`UID` && l.`GuildID`=?"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Guild> GET_GUILD_KOS_GUILD(final int id) { | 
				
			||||
		prepareCallable("SELECT g.* FROM `obj_guild` g, `dyn_guild_guildkoslist` l " | 
				
			||||
				+ "WHERE l.KOSGuildID = g.UID && l.GuildID = ?"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Guild> GET_SUB_GUILDS(final int guildID) { | 
				
			||||
		prepareCallable("SELECT `obj_guild`.*, `object`.`parent` FROM `object` INNER JOIN `obj_guild` ON `obj_guild`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;"); | 
				
			||||
		setInt(1, guildID); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public Guild GET_GUILD(int id) { | 
				
			||||
		Guild guild = (Guild) DbManager.getFromCache(Enum.GameObjectType.Guild, id); | 
				
			||||
		if (guild != null) | 
				
			||||
			return guild; | 
				
			||||
		if (id == 0) | 
				
			||||
			return Guild.getErrantGuild(); | 
				
			||||
		prepareCallable("SELECT `obj_guild`.*, `object`.`parent` FROM `obj_guild` INNER JOIN `object` ON `object`.`UID` = `obj_guild`.`UID` WHERE `object`.`UID`=?"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return (Guild) getObjectSingle(id); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public ArrayList<Guild> GET_ALL_GUILDS() { | 
				
			||||
		 | 
				
			||||
		prepareCallable("SELECT `obj_guild`.*, `object`.`parent` FROM `obj_guild` INNER JOIN `object` ON `object`.`UID` = `obj_guild`.`UID`"); | 
				
			||||
		 | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean IS_CREST_UNIQUE(final GuildTag gt) { | 
				
			||||
		boolean valid = false; | 
				
			||||
		if (gt.backgroundColor01 == gt.backgroundColor02) { | 
				
			||||
			//both background colors the same, ignore backgroundDesign
 | 
				
			||||
			prepareCallable("SELECT `name` FROM `obj_guild` WHERE `backgroundColor01`=? && `backgroundColor02`=? && `symbolColor`=? && `symbol`=?;"); | 
				
			||||
			setInt(1, gt.backgroundColor01); | 
				
			||||
			setInt(2, gt.backgroundColor02); | 
				
			||||
			setInt(3, gt.symbolColor); | 
				
			||||
			setInt(4, gt.symbol); | 
				
			||||
			 | 
				
			||||
		} else { | 
				
			||||
			prepareCallable("SELECT `name` FROM `obj_guild` WHERE `backgroundColor01`=? && `backgroundColor02`=? && `symbolColor`=? && `backgroundDesign`=? && `symbol`=?;"); | 
				
			||||
			setInt(1, gt.backgroundColor01); | 
				
			||||
			setInt(2, gt.backgroundColor02); | 
				
			||||
			setInt(3, gt.symbolColor); | 
				
			||||
			setInt(4, gt.backgroundDesign); | 
				
			||||
			setInt(5, gt.symbol); | 
				
			||||
		} | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			if (!rs.next()) | 
				
			||||
				valid = true; | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getMessage()); | 
				
			||||
		} | 
				
			||||
		return valid; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Guild g, String name, Object new_value) { | 
				
			||||
		prepareCallable("CALL guild_SETPROP(?,?,?)"); | 
				
			||||
		setLong(1, (long) g.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Guild g, String name, Object new_value, Object old_value) { | 
				
			||||
		prepareCallable("CALL guild_GETSETPROP(?,?,?,?)"); | 
				
			||||
		setLong(1, (long) g.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		setString(4, String.valueOf(old_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean SET_GUILD_OWNED_CITY(int guildID, int cityID) { | 
				
			||||
		prepareCallable("UPDATE `obj_guild` SET `ownedCity`=? WHERE `UID`=?"); | 
				
			||||
		setLong(1, (long) cityID); | 
				
			||||
		setLong(2, (long) guildID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean SET_GUILD_LEADER(int objectUUID,int guildID) { | 
				
			||||
		prepareCallable("UPDATE `obj_guild` SET `leaderUID`=? WHERE `UID`=?"); | 
				
			||||
		setLong(1, (long) objectUUID); | 
				
			||||
		setLong(2, (long) guildID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public boolean IS_NAME_UNIQUE(final String name) { | 
				
			||||
		boolean valid = false; | 
				
			||||
		prepareCallable("SELECT `name` FROM `obj_guild` WHERE `name`=?;"); | 
				
			||||
		setString(1, name); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			if (!rs.next()) | 
				
			||||
				valid = true; | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.warn(e.getMessage()); | 
				
			||||
		} | 
				
			||||
		return valid; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Guild SAVE_TO_DATABASE(Guild g) { | 
				
			||||
		prepareCallable("CALL `guild_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); | 
				
			||||
	 | 
				
			||||
		GuildTag gt = g.getGuildTag(); | 
				
			||||
		if ( gt == null) | 
				
			||||
			return null; | 
				
			||||
		setLong(1, MBServerStatics.worldUUID); | 
				
			||||
		setLong(2, g.getGuildLeaderUUID()); | 
				
			||||
		setString(3, g.getName()); | 
				
			||||
		setInt(4, gt.backgroundColor01); | 
				
			||||
		setInt(5, gt.backgroundColor02); | 
				
			||||
		setInt(6, gt.symbolColor); | 
				
			||||
		setInt(7, gt.backgroundDesign); | 
				
			||||
		setInt(8 , gt.symbol); | 
				
			||||
		setInt(9, g.getCharter()); | 
				
			||||
		setString(10, g.getLeadershipType()); | 
				
			||||
		setString(11, g.getMotto()); | 
				
			||||
 | 
				
			||||
		int objectUUID = (int) getUUID(); | 
				
			||||
		if (objectUUID > 0) | 
				
			||||
			return GET_GUILD(objectUUID); | 
				
			||||
		return null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_GUILD_RANK_OFFLINE(int target, int newRank, int guildId) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `guild_title`=? WHERE `UID`=? && `guildUID`=?"); | 
				
			||||
		setInt(1, newRank); | 
				
			||||
		setInt(2, target); | 
				
			||||
		setInt(3, guildId); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_PARENT(int guildUID, int parentUID) { | 
				
			||||
		prepareCallable("UPDATE `object` SET `parent`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, parentUID); | 
				
			||||
		setInt(2, guildUID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public int DELETE_GUILD(final Guild guild) { | 
				
			||||
		prepareCallable("DELETE FROM `object` WHERE `UID` = ?"); | 
				
			||||
		setLong(1, (long) guild.getObjectUUID()); | 
				
			||||
		return executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_MINETIME(int guildUID, int mineTime) { | 
				
			||||
		prepareCallable("UPDATE `obj_guild` SET `mineTime`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, mineTime); | 
				
			||||
		setInt(2, guildUID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public int UPDATE_GUILD_STATUS_OFFLINE(int target, boolean isInnerCouncil, boolean isRecruiter, boolean isTaxCollector, int guildId) { | 
				
			||||
		int updateMask = 0; | 
				
			||||
		prepareCallable("SELECT `guild_isInnerCouncil`, `guild_isTaxCollector`, `guild_isRecruiter` FROM `obj_character` WHERE `UID`=? && `guildUID`=?"); | 
				
			||||
		setLong(1, (long) target); | 
				
			||||
		setLong(2, (long) guildId); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//If the first query had no results, neither will the second
 | 
				
			||||
			if (rs.first()) { | 
				
			||||
				//Determine what is different
 | 
				
			||||
				if (rs.getBoolean("guild_isInnerCouncil") != isInnerCouncil) | 
				
			||||
					updateMask |= 4; | 
				
			||||
				if (rs.getBoolean("guild_isRecruiter") != isRecruiter) | 
				
			||||
					updateMask |= 2; | 
				
			||||
				if (rs.getBoolean("guild_isTaxCollector") != isTaxCollector) | 
				
			||||
					updateMask |= 1; | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `guild_isInnerCouncil`=?, `guild_isTaxCollector`=?, `guild_isRecruiter`=?, `guild_isFullMember`=? WHERE `UID`=? && `guildUID`=?"); | 
				
			||||
		setBoolean(1, isInnerCouncil); | 
				
			||||
		setBoolean(2, isRecruiter); | 
				
			||||
		setBoolean(3, isTaxCollector); | 
				
			||||
		setBoolean(4, ((updateMask > 0))); //If you are becoming an officer, or where an officer, your a full member...
 | 
				
			||||
		setLong(5, (long) target); | 
				
			||||
		setLong(6, (long) guildId); | 
				
			||||
		return executeUpdate(); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	// *** Refactor: Why are we saving tags/charter in update?
 | 
				
			||||
	//               It's not like this shit ever changes.
 | 
				
			||||
 | 
				
			||||
	public boolean updateDatabase(final Guild g) { | 
				
			||||
		prepareCallable("UPDATE `obj_guild` SET `name`=?, `backgroundColor01`=?, `backgroundColor02`=?, `symbolColor`=?, `backgroundDesign`=?, `symbol`=?, `charter`=?, `motd`=?, `icMotd`=?, `nationMotd`=?, `leaderUID`=? WHERE `UID`=?"); | 
				
			||||
		setString(1, g.getName()); | 
				
			||||
		setInt(2, g.getGuildTag().backgroundColor01); | 
				
			||||
		setInt(3, g.getGuildTag().backgroundColor02); | 
				
			||||
		setInt(4, g.getGuildTag().symbolColor); | 
				
			||||
		setInt(5, g.getGuildTag().backgroundDesign); | 
				
			||||
		setInt(6, g.getGuildTag().symbol); | 
				
			||||
		setInt(7, g.getCharter()); | 
				
			||||
		setString(8, g.getMOTD()); | 
				
			||||
		setString(9, g.getICMOTD()); | 
				
			||||
		setString(10, ""); | 
				
			||||
		setInt(11, g.getGuildLeaderUUID()); | 
				
			||||
		setLong(12, (long) g.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	public boolean ADD_TO_ALLIANCE_LIST(final long sourceGuildID, final long targetGuildID, boolean isRecommended, boolean isAlly, String recommender) { | 
				
			||||
		prepareCallable("INSERT INTO `dyn_guild_allianceenemylist` (`GuildID`, `OtherGuildID`,`isRecommended`, `isAlliance`, `recommender`) VALUES (?,?,?,?,?)"); | 
				
			||||
		setLong(1, sourceGuildID); | 
				
			||||
		setLong(2, targetGuildID); | 
				
			||||
		setBoolean(3, isRecommended); | 
				
			||||
		setBoolean(4, isAlly); | 
				
			||||
		setString(5, recommender); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean REMOVE_FROM_ALLIANCE_LIST(final long sourceGuildID, long targetGuildID) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_guild_allianceenemylist` WHERE `GuildID`=? AND `OtherGuildID`=?"); | 
				
			||||
		setLong(1, sourceGuildID); | 
				
			||||
		setLong(2, targetGuildID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_RECOMMENDED(final long sourceGuildID, long targetGuildID) { | 
				
			||||
		prepareCallable("UPDATE `dyn_guild_allianceenemylist` SET `isRecommended` = ? WHERE `GuildID`=? AND `OtherGuildID`=?"); | 
				
			||||
		setByte(1,(byte)0); | 
				
			||||
		setLong(2, sourceGuildID); | 
				
			||||
		setLong(3, targetGuildID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_ALLIANCE(final long sourceGuildID, long targetGuildID, boolean isAlly) { | 
				
			||||
		prepareCallable("UPDATE `dyn_guild_allianceenemylist` SET `isAlliance` = ? WHERE `GuildID`=? AND `OtherGuildID`=?"); | 
				
			||||
		setBoolean(1,isAlly); | 
				
			||||
		setLong(2, sourceGuildID); | 
				
			||||
		setLong(3, targetGuildID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_ALLIANCE_AND_RECOMMENDED(final long sourceGuildID, long targetGuildID, boolean isAlly) { | 
				
			||||
		prepareCallable("UPDATE `dyn_guild_allianceenemylist` SET `isRecommended` = ?, `isAlliance` = ? WHERE `GuildID`=? AND `OtherGuildID`=?"); | 
				
			||||
		setByte(1,(byte)0); | 
				
			||||
		setBoolean(2,isAlly); | 
				
			||||
		setLong(3, sourceGuildID); | 
				
			||||
		setLong(4, targetGuildID); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_ALL_ALLIANCES_FOR_GUILD(Guild guild) { | 
				
			||||
 | 
				
			||||
		if (guild == null) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_guild_allianceenemylist` WHERE `GuildID` = ?"); | 
				
			||||
		setInt(1,guild.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				GuildAlliances guildAlliance = new GuildAlliances(rs); | 
				
			||||
				guild.guildAlliances.put(guildAlliance.getAllianceGuild(), guildAlliance); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_GUILD_HISTORY_FOR_PLAYER(PlayerCharacter pc) { | 
				
			||||
 | 
				
			||||
		if (pc == null) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_character_guildhistory` WHERE `CharacterID` = ?"); | 
				
			||||
		setInt(1,pc.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ArrayList<GuildHistory> tempList = new ArrayList<>(); | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				GuildHistory guildHistory = new GuildHistory(rs); | 
				
			||||
				tempList.add(guildHistory); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			pc.setGuildHistory(tempList); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	//TODO uncomment this when finished with guild history warehouse integration
 | 
				
			||||
//	public HashMap<Integer, GuildRecord> GET_WAREHOUSE_GUILD_HISTORY(){
 | 
				
			||||
//		
 | 
				
			||||
//		HashMap<Integer, GuildRecord> tempMap = new HashMap<>();
 | 
				
			||||
//		prepareCallable("SELECT * FROM `warehouse_guildhistory` WHERE `eventType` = 'CREATE'");
 | 
				
			||||
//		try {
 | 
				
			||||
//			ResultSet rs = executeQuery();
 | 
				
			||||
//			
 | 
				
			||||
//			while (rs.next()) {
 | 
				
			||||
//				GuildRecord guildRecord = new GuildRecord(rs);
 | 
				
			||||
//				tempMap.put(guildRecord.guildID, guildRecord);
 | 
				
			||||
//			}
 | 
				
			||||
//		}catch (Exception e){
 | 
				
			||||
//			Logger.error(e);
 | 
				
			||||
//		}
 | 
				
			||||
//		return tempMap;
 | 
				
			||||
//		
 | 
				
			||||
//	}
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,470 @@
				@@ -0,0 +1,470 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.gameManager.ConfigManager; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.AbstractWorldObject; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.*; | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashSet; | 
				
			||||
 | 
				
			||||
public abstract class dbHandlerBase { | 
				
			||||
 | 
				
			||||
	/* | 
				
			||||
	 * CallableStatements handled below this line! | 
				
			||||
	 */ | 
				
			||||
	protected Class<? extends AbstractGameObject> localClass = null; | 
				
			||||
	protected GameObjectType localObjectType; | 
				
			||||
	protected final ThreadLocal<CallableStatement> cs = new ThreadLocal<>(); | 
				
			||||
 | 
				
			||||
	protected final void prepareCallable(final String sql) { | 
				
			||||
		try { | 
				
			||||
			this.cs.set((CallableStatement) DbManager.getConn().prepareCall(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("DbManager.getConn", e); | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setDate(int parameterIndex, Date value) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setDate(parameterIndex, value); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setInt(int parameterIndex, int value) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setInt(parameterIndex, value); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setLong(int parameterIndex, long value) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setLong(parameterIndex, value); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setFloat(int parameterIndex, float value) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setFloat(parameterIndex, value); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setShort(int parameterIndex, short value) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setShort(parameterIndex, value); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setString(int parameterIndex, String value) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setString(parameterIndex, value); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setBytes(int parameterIndex, byte[] value) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setBytes(parameterIndex, value); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setByte(int parameterIndex, byte value) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setByte(parameterIndex, value); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setBoolean(int parameterIndex, boolean value) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setBoolean(parameterIndex, value); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setNULL(int parameterIndex, int type) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setNull(parameterIndex, type); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setLocalDateTime(int parameterIndex, LocalDateTime localDateTime) { | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setTimestamp(parameterIndex, Timestamp.valueOf(localDateTime)); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void setTimeStamp(int parameterIndex, long time) { | 
				
			||||
		try { | 
				
			||||
			this.cs.get().setTimestamp(parameterIndex, new java.sql.Timestamp(time)); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final boolean execute() { | 
				
			||||
		try { | 
				
			||||
			return this.cs.get().execute(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} | 
				
			||||
		return false; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final ResultSet executeQuery() { | 
				
			||||
		try { | 
				
			||||
			return this.cs.get().executeQuery(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} | 
				
			||||
		return null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final int executeUpdate() { | 
				
			||||
		return executeUpdate(true); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final int executeUpdate(boolean close) { | 
				
			||||
		try { | 
				
			||||
			return this.cs.get().executeUpdate(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} finally { | 
				
			||||
			if (close) | 
				
			||||
				closeCallable(); | 
				
			||||
		} | 
				
			||||
		return 0; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void logSQLCommand() { | 
				
			||||
		try { | 
				
			||||
			Logger.error("Failed SQL Command: " + this.cs.get().toString()); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
 | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	// Common return values from the database when calling stored procedures, abstracted to this layer
 | 
				
			||||
	protected final String getResult(){ | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = this.executeQuery(); | 
				
			||||
			if (rs.next() && !isError(rs)) | 
				
			||||
				return rs.getString("result"); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	// Used for Stored procedures that return true when they succeed.
 | 
				
			||||
	protected final boolean worked() { | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = this.executeQuery(); | 
				
			||||
			if (rs.next() && !isError(rs)) | 
				
			||||
				return rs.getBoolean("result"); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return false; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	// Common return values from the database when calling stored procedures, abstracted to this layer
 | 
				
			||||
	protected final long getUUID(){ | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = this.executeQuery(); | 
				
			||||
			if (rs.next() && !isError(rs)) | 
				
			||||
				return rs.getLong("UID"); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return -1; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final String getString(String field) { | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = this.executeQuery(); | 
				
			||||
			if (rs.next()) | 
				
			||||
				return rs.getString(field); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return ""; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final long getLong(String field) { | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = this.executeQuery(); | 
				
			||||
			if (rs.next()) | 
				
			||||
				return rs.getLong(field); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return 0L; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final int getInt(String field) { | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = this.executeQuery(); | 
				
			||||
			if (rs.next()) | 
				
			||||
				return rs.getInt(field); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return 0; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final int insertGetUUID() { | 
				
			||||
		int key = 0; | 
				
			||||
		try { | 
				
			||||
			this.cs.get().executeUpdate(); | 
				
			||||
			ResultSet rs = this.cs.get().getGeneratedKeys(); | 
				
			||||
			if (rs.next()) | 
				
			||||
				key = rs.getInt(1); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return key; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final boolean isError(ResultSet rs) throws SQLException { | 
				
			||||
		ResultSetMetaData rsmd = rs.getMetaData(); | 
				
			||||
		if (rsmd.getColumnCount() > 0 && !rsmd.getColumnName(1).equals("errorno")) | 
				
			||||
			return false; | 
				
			||||
		printError(rs); | 
				
			||||
		return true; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void printError(ResultSet rs) { | 
				
			||||
		try { | 
				
			||||
			int errorNum = rs.getInt("errorno"); | 
				
			||||
			String errorMsg = rs.getString("errormsg"); | 
				
			||||
			Logger.error("SQLError: errorNum: " + errorNum + ", errorMsg: " + errorMsg); | 
				
			||||
			logSQLCommand(); | 
				
			||||
		} catch (SQLException e) {} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected final void getColumNames(ResultSet rs) throws SQLException { | 
				
			||||
		ResultSetMetaData rsmd = rs.getMetaData(); | 
				
			||||
		int numColumns = rsmd.getColumnCount(); | 
				
			||||
		String out = "Column names for resultSet: "; | 
				
			||||
		for (int i=1; i<numColumns+1; i++) | 
				
			||||
			out += i + ": " + rsmd.getColumnName(i) + ", "; | 
				
			||||
		Logger.info(out); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	// Default actions to the objects table, generic to all objects
 | 
				
			||||
	protected final long SET_PARENT(long objUID, long new_value, long old_value) { | 
				
			||||
		prepareCallable("CALL object_GETSETPARENT(?,?,?)"); | 
				
			||||
		setLong(1, objUID); | 
				
			||||
		setLong(2, new_value); | 
				
			||||
		setLong(3, old_value); | 
				
			||||
		return getUUID(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	// NOTE: CALLING THIS FUNCTION CASCADE DELETES OBJECTS FROM THE DATABASE
 | 
				
			||||
	protected final long REMOVE(long objUID) { | 
				
			||||
		prepareCallable("CALL object_PURGECASCADE(?)"); | 
				
			||||
		setLong(1, objUID); | 
				
			||||
		return getUUID(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected <T extends AbstractGameObject> AbstractGameObject getObjectSingle(int id) { | 
				
			||||
		return getObjectSingle(id, false, true); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected <T extends AbstractGameObject> AbstractGameObject getObjectSingle(int id, boolean forceFromDB, boolean storeInCache) { | 
				
			||||
 | 
				
			||||
		if (cs.get() == null){ | 
				
			||||
			return null; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		if (!forceFromDB) { | 
				
			||||
			if (DbManager.inCache(localObjectType, id)) { | 
				
			||||
				closeCallable(); | 
				
			||||
				return DbManager.getFromCache(localObjectType, id); | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		AbstractGameObject out = null; | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			if (MBServerStatics.DB_ENABLE_QUERY_OUTPUT) | 
				
			||||
				Logger.info( "[GetObjectList] Executing query:" + cs.get().toString()); | 
				
			||||
 | 
				
			||||
			ResultSet rs = cs.get().executeQuery(); | 
				
			||||
 | 
				
			||||
			if (rs.next()) { | 
				
			||||
				out = localClass.getConstructor(ResultSet.class).newInstance(rs); | 
				
			||||
 | 
				
			||||
				if (storeInCache) | 
				
			||||
					DbManager.addToCache(out); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			rs.close(); | 
				
			||||
 | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error("AbstractGameObject", e); | 
				
			||||
			out = null; | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		// Only call runAfterLoad() for objects instanced on the world server
 | 
				
			||||
 | 
				
			||||
		if ((out != null && out instanceof AbstractWorldObject) && | 
				
			||||
				(ConfigManager.serverType.equals(Enum.ServerType.WORLDSERVER) || | 
				
			||||
						(out.getObjectType() == GameObjectType.Guild))) | 
				
			||||
			((AbstractWorldObject)out).runAfterLoad(); | 
				
			||||
 | 
				
			||||
		return out; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected void closeCallable() { | 
				
			||||
		try { | 
				
			||||
			if (this.cs.get() != null) | 
				
			||||
				this.cs.get().close(); | 
				
			||||
		} catch (SQLException e) {} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected <T extends AbstractGameObject> ArrayList<T> getObjectList() { | 
				
			||||
		return getObjectList(20, false); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	protected <T extends AbstractGameObject> ArrayList<T> getLargeObjectList() { | 
				
			||||
		return getObjectList(2000, false); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@SuppressWarnings("unchecked") | 
				
			||||
	protected <T extends AbstractGameObject> ArrayList<T> getObjectList(int listSize, boolean forceFromDB) { | 
				
			||||
 | 
				
			||||
		String query = "No Callable Statement accessable."; | 
				
			||||
 | 
				
			||||
		ArrayList<T> out = new ArrayList<>(listSize); | 
				
			||||
 | 
				
			||||
		if (this.cs.get() == null) | 
				
			||||
			return out; | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
 | 
				
			||||
			CallableStatement css = this.cs.get(); | 
				
			||||
 | 
				
			||||
			if (css != null) | 
				
			||||
				query = this.cs.get().toString(); | 
				
			||||
 | 
				
			||||
			if (MBServerStatics.DB_ENABLE_QUERY_OUTPUT) | 
				
			||||
				Logger.info( "[GetObjectList] Executing query:" + query); | 
				
			||||
 | 
				
			||||
			ResultSet rs = this.cs.get().executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				int id = rs.getInt(1); | 
				
			||||
 | 
				
			||||
				if (!forceFromDB && DbManager.inCache(localObjectType, id)) { | 
				
			||||
					out.add((T) DbManager.getFromCache(localObjectType, id)); | 
				
			||||
				} else { | 
				
			||||
					AbstractGameObject toAdd = localClass.getConstructor(ResultSet.class).newInstance(rs); | 
				
			||||
					DbManager.addToCache(toAdd); | 
				
			||||
					out.add((T) toAdd); | 
				
			||||
 | 
				
			||||
					if (toAdd != null && toAdd instanceof AbstractWorldObject) | 
				
			||||
						((AbstractWorldObject)toAdd).runAfterLoad(); | 
				
			||||
 | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error(localClass.getCanonicalName(), "List Failure: " + query, e); | 
				
			||||
			e.printStackTrace(); | 
				
			||||
			return new ArrayList<>(); // Do we want a null return on error?
 | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return out; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/* Prepared Statements handled below this line */ | 
				
			||||
 | 
				
			||||
	protected HashSet<Integer> getIntegerList(final int columnNumber) { | 
				
			||||
 | 
				
			||||
		if (MBServerStatics.DB_ENABLE_QUERY_OUTPUT) | 
				
			||||
			Logger.info("[GetIntegerList] Executing query:" + this.cs.toString()); | 
				
			||||
 | 
				
			||||
		HashSet<Integer> out = new HashSet<>(); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				out.add(rs.getInt(columnNumber)); | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return out; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,47 @@
				@@ -0,0 +1,47 @@
					 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.InterestManagement.HeightMap; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
 | 
				
			||||
public class dbHeightMapHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbHeightMapHandler() { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_ALL_HEIGHTMAPS() { | 
				
			||||
 | 
				
			||||
		HeightMap thisHeightmap; | 
				
			||||
 | 
				
			||||
		int recordsRead = 0; | 
				
			||||
		int worthlessDupes = 0; | 
				
			||||
 | 
				
			||||
		HeightMap.heightMapsCreated = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_zone_heightmap INNER JOIN static_zone_size ON static_zone_size.loadNum = static_zone_heightmap.zoneLoadID"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
				thisHeightmap = new HeightMap(rs); | 
				
			||||
 | 
				
			||||
				if (thisHeightmap.getHeightmapImage() == null) { | 
				
			||||
					Logger.info( "Imagemap for " + thisHeightmap.getHeightMapID() + " was null"); | 
				
			||||
					continue; | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("LoadAllHeightMaps: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,152 @@
				@@ -0,0 +1,152 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.EquipmentSetEntry; | 
				
			||||
import engine.objects.ItemBase; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashMap; | 
				
			||||
 | 
				
			||||
public class dbItemBaseHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbItemBaseHandler() { | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_BAKEDINSTATS(ItemBase itemBase) { | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			prepareCallable("SELECT * FROM `static_item_bakedinstat` WHERE `itemID` = ?"); | 
				
			||||
			setInt(1, itemBase.getUUID()); | 
				
			||||
 | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				if (rs.getBoolean("fromUse")) | 
				
			||||
					itemBase.getUsedStats().put(rs.getInt("token"), rs.getInt("numTrains")); | 
				
			||||
				else | 
				
			||||
					itemBase.getBakedInStats().put(rs.getInt("token"), rs.getInt("numTrains")); | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_ANIMATIONS(ItemBase itemBase) { | 
				
			||||
 | 
				
			||||
		ArrayList<Integer> tempList = new ArrayList<>(); | 
				
			||||
		ArrayList<Integer> tempListOff = new ArrayList<>(); | 
				
			||||
		try { | 
				
			||||
			prepareCallable("SELECT * FROM `static_itembase_animations` WHERE `itemBaseUUID` = ?"); | 
				
			||||
			setInt(1, itemBase.getUUID()); | 
				
			||||
 | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				int animation = rs.getInt("animation"); | 
				
			||||
 | 
				
			||||
				boolean rightHand = rs.getBoolean("rightHand"); | 
				
			||||
 | 
				
			||||
				if (rightHand) | 
				
			||||
					tempList.add(animation); | 
				
			||||
				else | 
				
			||||
					tempListOff.add(animation); | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		itemBase.setAnimations(tempList); | 
				
			||||
		itemBase.setOffHandAnimations(tempListOff); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_ALL_ITEMBASES() { | 
				
			||||
 | 
				
			||||
		ItemBase itemBase; | 
				
			||||
 | 
				
			||||
		int recordsRead = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_itembase"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
				itemBase = new ItemBase(rs); | 
				
			||||
 | 
				
			||||
				// Add ItemBase to internal cache
 | 
				
			||||
 | 
				
			||||
				ItemBase.addToCache(itemBase); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			Logger.info( "read: " + recordsRead + "cached: " + ItemBase.getUUIDCache().size()); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public HashMap<Integer, ArrayList<EquipmentSetEntry>> LOAD_EQUIPMENT_FOR_NPC_AND_MOBS() { | 
				
			||||
 | 
				
			||||
		HashMap<Integer, ArrayList<EquipmentSetEntry>> equipmentSets; | 
				
			||||
		EquipmentSetEntry equipmentSetEntry; | 
				
			||||
		int	equipSetID; | 
				
			||||
 | 
				
			||||
		equipmentSets = new HashMap<>(); | 
				
			||||
		int recordsRead = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_npc_equipmentset"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
 | 
				
			||||
				equipSetID = rs.getInt("equipmentSet"); | 
				
			||||
				equipmentSetEntry = new EquipmentSetEntry(rs); | 
				
			||||
 | 
				
			||||
				if (equipmentSets.get(equipSetID) == null){ | 
				
			||||
					ArrayList<EquipmentSetEntry> equipList = new ArrayList<>(); | 
				
			||||
					equipList.add(equipmentSetEntry); | 
				
			||||
					equipmentSets.put(equipSetID, equipList); | 
				
			||||
				} | 
				
			||||
				else{ | 
				
			||||
					ArrayList<EquipmentSetEntry>equipList = equipmentSets.get(equipSetID); | 
				
			||||
					equipList.add(equipmentSetEntry); | 
				
			||||
					equipmentSets.put(equipSetID, equipList); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			Logger.info("read: " + recordsRead + " cached: " + equipmentSets.size()); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return equipmentSets; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,430 @@
				@@ -0,0 +1,430 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum.ItemContainerType; | 
				
			||||
import engine.Enum.ItemType; | 
				
			||||
import engine.Enum.OwnerType; | 
				
			||||
import engine.objects.*; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashSet; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
public class dbItemHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbItemHandler() { | 
				
			||||
		this.localClass = Item.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Item ADD_ITEM(Item toAdd) { | 
				
			||||
		prepareCallable("CALL `item_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?,?);"); | 
				
			||||
		setInt(1, toAdd.getOwnerID()); | 
				
			||||
		setInt(2, toAdd.getItemBaseID()); | 
				
			||||
		setInt(3, toAdd.getChargesRemaining()); | 
				
			||||
		setInt(4, toAdd.getDurabilityCurrent()); | 
				
			||||
		setInt(5, toAdd.getDurabilityMax()); | 
				
			||||
		if (toAdd.getNumOfItems() < 1) | 
				
			||||
			setInt(6, 1); | 
				
			||||
		else | 
				
			||||
			setInt(6, toAdd.getNumOfItems()); | 
				
			||||
 | 
				
			||||
		switch (toAdd.containerType) { | 
				
			||||
			case INVENTORY: | 
				
			||||
				setString(7, "inventory"); | 
				
			||||
				break; | 
				
			||||
			case EQUIPPED: | 
				
			||||
				setString(7, "equip"); | 
				
			||||
				break; | 
				
			||||
			case BANK: | 
				
			||||
				setString(7, "bank"); | 
				
			||||
				break; | 
				
			||||
			case VAULT: | 
				
			||||
				setString(7, "vault"); | 
				
			||||
				break; | 
				
			||||
			case FORGE: | 
				
			||||
				setString(7, "forge"); | 
				
			||||
				break; | 
				
			||||
				default: | 
				
			||||
					setString(7, "none"); //Shouldn't be here
 | 
				
			||||
					break; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		setByte(8, toAdd.getEquipSlot()); | 
				
			||||
		setInt(9, toAdd.getFlags()); | 
				
			||||
		setString(10, toAdd.getCustomName()); | 
				
			||||
		int objectUUID = (int) getUUID(); | 
				
			||||
 | 
				
			||||
		if (objectUUID > 0) | 
				
			||||
			return GET_ITEM(objectUUID); | 
				
			||||
		return null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean DELETE_ITEM(final Item item) { | 
				
			||||
		prepareCallable("DELETE FROM `object` WHERE `UID`=? && `type`='item' limit 1"); | 
				
			||||
		setLong(1, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean DELETE_ITEM(final int itemUUID) { | 
				
			||||
		prepareCallable("DELETE FROM `object` WHERE `UID`=? && `type`='item' limit 1"); | 
				
			||||
		setLong(1, (long) itemUUID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String GET_OWNER(int ownerID) { | 
				
			||||
		prepareCallable("SELECT `type` FROM `object` WHERE `UID`=?"); | 
				
			||||
		setLong(1, (long) ownerID); | 
				
			||||
		return getString("type"); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean DO_TRADE(HashSet<Integer> from1, HashSet<Integer> from2, | 
				
			||||
			CharacterItemManager man1, CharacterItemManager man2, | 
				
			||||
			Item inventoryGold1, Item inventoryGold2, int goldFrom1, int goldFrom2) { | 
				
			||||
 | 
				
			||||
		AbstractCharacter ac1 = man1.getOwner(); | 
				
			||||
		AbstractCharacter ac2 = man2.getOwner(); | 
				
			||||
		if (ac1 == null || ac2 == null || inventoryGold1 == null || inventoryGold2 == null) | 
				
			||||
			return false; | 
				
			||||
 | 
				
			||||
		prepareCallable("CALL `item_TRADE`(?, ?, ?, ?, ?, ?, ?, ?)"); | 
				
			||||
		setString(1, formatTradeString(from1)); | 
				
			||||
		setLong(2, (long) ac1.getObjectUUID()); | 
				
			||||
		setString(3, formatTradeString(from2)); | 
				
			||||
		setLong(4, (long) ac2.getObjectUUID()); | 
				
			||||
		setInt(5, goldFrom1); | 
				
			||||
		setLong(6, (long) inventoryGold1.getObjectUUID()); | 
				
			||||
		setInt(7, goldFrom2); | 
				
			||||
		setLong(8, (long) inventoryGold2.getObjectUUID()); | 
				
			||||
        return worked(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private static String formatTradeString(HashSet<Integer> list) { | 
				
			||||
		int size = list.size(); | 
				
			||||
 | 
				
			||||
		String ret = ""; | 
				
			||||
		if (size == 0) | 
				
			||||
			return ret; | 
				
			||||
		boolean start = true; | 
				
			||||
		for (int i : list) { | 
				
			||||
			if (start){ | 
				
			||||
				ret += i; | 
				
			||||
				start = false; | 
				
			||||
			} | 
				
			||||
			else | 
				
			||||
			ret += "," + i; | 
				
			||||
		} | 
				
			||||
		return ret; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Item> GET_EQUIPPED_ITEMS(final int targetId) { | 
				
			||||
		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=? && `obj_item`.`item_container`='equip';"); | 
				
			||||
		setLong(1, (long) targetId); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Item GET_ITEM(final int id) { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`UID`=?;"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return (Item) getObjectSingle(id); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Item GET_GOLD_FOR_PLAYER(final int playerID, final int goldID, int worldID) { | 
				
			||||
		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=? AND `obj_item`.`item_itembaseID`=?;"); | 
				
			||||
		setInt(1, playerID); | 
				
			||||
		setInt(2, goldID); | 
				
			||||
		int objectUUID = (int) getUUID(); | 
				
			||||
		return (Item) getObjectSingle(objectUUID); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Item> GET_ITEMS_FOR_ACCOUNT(final int accountId) { | 
				
			||||
		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=?;"); | 
				
			||||
		setLong(1, (long) accountId); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Item> GET_ITEMS_FOR_NPC(final int npcId) { | 
				
			||||
		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=?"); | 
				
			||||
		setLong(1, (long) npcId); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Item> GET_ITEMS_FOR_PC(final int id) { | 
				
			||||
		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=?"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return getLargeObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Item> GET_ITEMS_FOR_PLAYER_AND_ACCOUNT(final int playerID, final int accountID) { | 
				
			||||
		prepareCallable("SELECT `obj_item`.*, `object`.`parent`, `object`.`type` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE (`object`.`parent`=? OR `object`.`parent`=?)"); | 
				
			||||
		setLong(1, (long) playerID); | 
				
			||||
		setLong(2, (long) accountID); | 
				
			||||
		return getLargeObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean MOVE_GOLD(final Item from, final Item to, final int amt) { | 
				
			||||
		int newFromAmt = from.getNumOfItems() - amt; | 
				
			||||
		int newToAmt = to.getNumOfItems() + amt; | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_numberOfItems` = CASE WHEN `UID`=?  THEN ? WHEN `UID`=? THEN ? END WHERE `UID` IN (?, ?);"); | 
				
			||||
		setLong(1, (long) from.getObjectUUID()); | 
				
			||||
		setInt(2, newFromAmt); | 
				
			||||
		setLong(3, (long) to.getObjectUUID()); | 
				
			||||
		setInt(4, newToAmt); | 
				
			||||
		setLong(5, (long) from.getObjectUUID()); | 
				
			||||
		setLong(6, (long) to.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ORPHAN_INVENTORY(final HashSet<Item> inventory) { | 
				
			||||
		boolean worked = true; | 
				
			||||
		for (Item item : inventory) { | 
				
			||||
 | 
				
			||||
			if (item.getItemBase().getType().equals(ItemType.GOLD)) | 
				
			||||
				continue; | 
				
			||||
 | 
				
			||||
			prepareCallable("UPDATE `obj_item` LEFT JOIN `object` ON `object`.`UID` = `obj_item`.`UID` SET `object`.`parent`=NULL, `obj_item`.`item_container`='none' WHERE `object`.`UID`=?;"); | 
				
			||||
			setLong(1, (long) item.getObjectUUID()); | 
				
			||||
			if (executeUpdate() == 0) | 
				
			||||
				worked = false; | 
				
			||||
			else | 
				
			||||
				item.zeroItem(); | 
				
			||||
		} | 
				
			||||
		return worked; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Item PURCHASE_ITEM_FROM_VENDOR(final PlayerCharacter pc, final ItemBase ib) { | 
				
			||||
		Item item = null; | 
				
			||||
		byte charges = 0; | 
				
			||||
		charges = (byte) ib.getNumCharges(); | 
				
			||||
		short durability = (short) ib.getDurability(); | 
				
			||||
 | 
				
			||||
		Item temp = new Item(ib, pc.getObjectUUID(), | 
				
			||||
				OwnerType.PlayerCharacter, charges, charges, durability, durability, | 
				
			||||
				true, false,ItemContainerType.INVENTORY, (byte) 0, | 
				
			||||
                new ArrayList<>(),""); | 
				
			||||
		try { | 
				
			||||
			item = this.ADD_ITEM(temp); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error(e); | 
				
			||||
		} | 
				
			||||
		return item; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public HashSet<Integer> GET_ITEMS_FOR_VENDOR(final int vendorID) { | 
				
			||||
		prepareCallable("SELECT ID FROM static_itembase WHERE vendorType = ?"); | 
				
			||||
		setInt(1, vendorID); | 
				
			||||
		return getIntegerList(1); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Item> GET_ITEMS_FOR_VENDOR_FORGING(final int npcID) { | 
				
			||||
		prepareCallable("SELECT `obj_item`.*, `object`.`parent` FROM `object` INNER JOIN `obj_item` ON `object`.`UID` = `obj_item`.`UID` WHERE `object`.`parent`=? AND `obj_item`.`item_container` =?"); | 
				
			||||
		setLong(1, (long) npcID); | 
				
			||||
		setString(2, "forge"); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Item i, String name, Object new_value) { | 
				
			||||
		prepareCallable("CALL item_SETPROP(?,?,?)"); | 
				
			||||
		setLong(1, (long) i.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Item i, String name, Object new_value, Object old_value) { | 
				
			||||
		prepareCallable("CALL item_GETSETPROP(?,?,?,?)"); | 
				
			||||
		setLong(1, (long) i.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		setString(4, String.valueOf(old_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	//Used to transfer a single item between owners or equip or vault or bank or inventory
 | 
				
			||||
	public boolean UPDATE_OWNER(final Item item, int newOwnerID, boolean ownerNPC, boolean ownerPlayer, | 
				
			||||
			boolean ownerAccount, ItemContainerType containerType, int slot) { | 
				
			||||
 | 
				
			||||
		prepareCallable("CALL `item_TRANSFER_OWNER`(?, ?, ?, ? )"); | 
				
			||||
		setLong(1, (long) item.getObjectUUID()); | 
				
			||||
		if (newOwnerID != 0) | 
				
			||||
			setLong(2, (long) newOwnerID); | 
				
			||||
		else | 
				
			||||
			setNULL(2, java.sql.Types.BIGINT); | 
				
			||||
		 | 
				
			||||
		switch (containerType) { | 
				
			||||
			case INVENTORY: | 
				
			||||
				setString(3, "inventory"); | 
				
			||||
				break; | 
				
			||||
			case EQUIPPED: | 
				
			||||
				setString(3, "equip"); | 
				
			||||
				break; | 
				
			||||
			case BANK: | 
				
			||||
				setString(3, "bank"); | 
				
			||||
				break; | 
				
			||||
			case VAULT: | 
				
			||||
				setString(3, "vault"); | 
				
			||||
				break; | 
				
			||||
			case FORGE: | 
				
			||||
				setString(3, "forge"); | 
				
			||||
				break; | 
				
			||||
			default: | 
				
			||||
				setString(3, "none"); //Shouldn't be here
 | 
				
			||||
				break; | 
				
			||||
		} | 
				
			||||
		setInt(4, slot); | 
				
			||||
		return worked(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean SET_DURABILITY(final Item item, int value) { | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_durabilityCurrent`=? WHERE `UID`=? AND `item_durabilityCurrent`=?"); | 
				
			||||
		setInt(1, value); | 
				
			||||
		setLong(2, (long) item.getObjectUUID()); | 
				
			||||
		setInt(3, (int) item.getDurabilityCurrent()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	//Update an item except ownership
 | 
				
			||||
	public boolean UPDATE_DATABASE(final Item item) { | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_itembaseID`=?, `item_chargesRemaining`=?, `item_durabilityCurrent`=?, `item_durabilityMax`=?, `item_numberOfItems`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, item.getItemBaseID()); | 
				
			||||
		setInt(2, item.getChargesRemaining()); | 
				
			||||
		setInt(3, item.getDurabilityCurrent()); | 
				
			||||
		setInt(4, item.getDurabilityMax()); | 
				
			||||
		setInt(5, item.getNumOfItems()); | 
				
			||||
		setLong(6, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_ROLL_COMPLETE(final Item item) { | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_container` = ?, `item_dateToUpgrade` = ? WHERE `UID` = ?"); | 
				
			||||
		setString(1, "forge"); | 
				
			||||
		setLong(2, 0L); | 
				
			||||
		setLong(3, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean SET_DATE_TO_UPGRADE(final Item item, long date) { | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_dateToUPGRADE` = ? WHERE `UID` = ?"); | 
				
			||||
		setLong(1, date); | 
				
			||||
		setLong(2, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_FORGE_TO_INVENTORY(final Item item) { | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_container` = ? WHERE `UID` = ? AND `item_container` = 'forge';"); | 
				
			||||
		setString(1, "inventory"); | 
				
			||||
		setLong(2, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * Attempts to update the quantity of this gold item | 
				
			||||
	 * | 
				
			||||
	 * @param value New quantity of gold | 
				
			||||
	 * @return True on success | 
				
			||||
	 */ | 
				
			||||
	public boolean UPDATE_GOLD(final Item item, int value) { | 
				
			||||
		if (item == null) | 
				
			||||
			return false; | 
				
			||||
		return UPDATE_GOLD(item, value, item.getNumOfItems()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * Attempts to update the quantity of this gold item using CAS | 
				
			||||
	 * | 
				
			||||
	 * @return True on success | 
				
			||||
	 */ | 
				
			||||
	public boolean UPDATE_GOLD(final Item item, int newValue, int oldValue) { | 
				
			||||
 | 
				
			||||
		if (item.getItemBase().getType().equals(ItemType.GOLD) == false) | 
				
			||||
			return false; | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_numberOfItems`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, newValue); | 
				
			||||
		setLong(2, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * Attempts to update the value of two Gold items simultaneously. | 
				
			||||
	 * | 
				
			||||
	 * @param value New gold quantity for this item | 
				
			||||
	 * @param otherGold Other Gold item being modified | 
				
			||||
	 * @param valueOtherGold New quantity of gold for other item | 
				
			||||
	 * @return True on success | 
				
			||||
	 */ | 
				
			||||
	public boolean UPDATE_GOLD(Item gold, int value, Item otherGold, int valueOtherGold) { | 
				
			||||
 | 
				
			||||
		if (gold.getItemBase().getType().equals(ItemType.GOLD) == false) | 
				
			||||
			return false; | 
				
			||||
 | 
				
			||||
		if (otherGold.getItemBase().getType().equals(ItemType.GOLD) == false) | 
				
			||||
			return false; | 
				
			||||
 | 
				
			||||
		int firstOld = gold.getNumOfItems(); | 
				
			||||
		int secondOld = gold.getNumOfItems(); | 
				
			||||
 | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_numberOfItems` = CASE WHEN `UID`=? AND `item_numberOfItems`=? THEN ? WHEN `UID`=? AND `item_numberOfItems`=? THEN ? END WHERE `UID` IN (?, ?);"); | 
				
			||||
		setLong(1, (long) gold.getObjectUUID()); | 
				
			||||
		setInt(2, firstOld); | 
				
			||||
		setInt(3, value); | 
				
			||||
		setLong(4, (long) otherGold.getObjectUUID()); | 
				
			||||
		setInt(5, secondOld); | 
				
			||||
		setInt(6, valueOtherGold); | 
				
			||||
		setLong(7, (long) gold.getObjectUUID()); | 
				
			||||
		setLong(8, (long) otherGold.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_REMAINING_CHARGES(final Item item) { | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_chargesRemaining` = ? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, item.getChargesRemaining()); | 
				
			||||
		setLong(2, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	// This is necessary because default number of items is 1.
 | 
				
			||||
	// When we create gold, we want it to start at 0 quantity.
 | 
				
			||||
 | 
				
			||||
	public boolean ZERO_ITEM_STACK(Item item) { | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_numberOfItems`=0 WHERE `UID` = ?"); | 
				
			||||
		setLong(1, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_FLAGS(Item item) { | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_flags`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, item.getFlags()); | 
				
			||||
		setLong(2, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_VALUE(Item item,int value) { | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_value`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, value); | 
				
			||||
		setLong(2, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_FLAGS(Item item, int flags) { | 
				
			||||
		prepareCallable("UPDATE `obj_item` SET `item_flags`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, flags); | 
				
			||||
		setLong(2, (long) item.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,36 @@
				@@ -0,0 +1,36 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.Kit; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbKitHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbKitHandler() { | 
				
			||||
		this.localClass = Kit.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Kit> GET_KITS_FOR_RACE_AND_BASECLASS(int raceID, int baseClassID) { | 
				
			||||
		prepareCallable("SELECT vk.* FROM `static_rune_validkit` vk, `static_rune_racebaseclass` rbc WHERE rbc.`RaceID` = ? " | 
				
			||||
				+ "&& rbc.`BaseClassID` = ? && rbc.`ID` = vk.`RaceBaseClassesID`"); | 
				
			||||
		setInt(1, raceID); | 
				
			||||
		setInt(2, baseClassID); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Kit> GET_ALL_KITS() { | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_validkit`"); | 
				
			||||
 | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,233 @@
				@@ -0,0 +1,233 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.loot.LootGroup; | 
				
			||||
import engine.loot.LootManager; | 
				
			||||
import engine.loot.ModifierGroup; | 
				
			||||
import engine.loot.ModifierTable; | 
				
			||||
import engine.objects.Item; | 
				
			||||
import engine.objects.LootTable; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
 | 
				
			||||
public class dbLootTableHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
    public dbLootTableHandler() { | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
 | 
				
			||||
    public void populateLootGroups() { | 
				
			||||
        int recordsRead = 0; | 
				
			||||
        prepareCallable("SELECT `groupID`, `minRoll`, `maxRoll`, `lootTableID`, `pModTableID`, `sModTableID` FROM `static_lootgroups`"); | 
				
			||||
         | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
            if (rs != null) | 
				
			||||
                while (rs.next()) { | 
				
			||||
                    recordsRead++; | 
				
			||||
                    LootTable lootTable = LootTable.getLootGroup(rs.getInt("groupID")); | 
				
			||||
                    lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("lootTableID"), rs.getInt("pModTableID"), rs.getInt("sModTableID"), ""); | 
				
			||||
                } | 
				
			||||
             | 
				
			||||
            Logger.info("read: " + recordsRead + " cached: " + LootTable.getLootGroups().size()); | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void populateLootTables() { | 
				
			||||
        int recordsRead = 0; | 
				
			||||
         | 
				
			||||
        prepareCallable("SELECT `lootTable`, `minRoll`, `maxRoll`, `itemBaseUUID`, `minSpawn`, `maxSpawn` FROM `static_loottables`"); | 
				
			||||
         | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
            if (rs != null) | 
				
			||||
                while (rs.next()) { | 
				
			||||
                    recordsRead++; | 
				
			||||
                    LootTable lootTable = LootTable.getLootTable(rs.getInt("lootTable")); | 
				
			||||
                    lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("itemBaseUUID"), rs.getInt("minSpawn"), rs.getInt("maxSpawn"), ""); | 
				
			||||
                } | 
				
			||||
             | 
				
			||||
             Logger.info("read: " + recordsRead + " cached: " + LootTable.getLootTables().size()); | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void populateModTables() { | 
				
			||||
         | 
				
			||||
        int recordsRead = 0; | 
				
			||||
                 | 
				
			||||
        prepareCallable("SELECT `modTable`,`minRoll`,`maxRoll`,`value`,`action` FROM `static_modtables`"); | 
				
			||||
         | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
            if (rs != null) | 
				
			||||
                while (rs.next()) { | 
				
			||||
                    recordsRead++; | 
				
			||||
                    LootTable lootTable = LootTable.getModTable(rs.getInt("modTable")); | 
				
			||||
                    lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("value"), 0, 0, rs.getString("action")); | 
				
			||||
                } | 
				
			||||
            Logger.info("read: " + recordsRead + " cached: " + LootTable.getModTables().size()); | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void populateModGroups() { | 
				
			||||
         | 
				
			||||
        int recordsRead = 0; | 
				
			||||
         | 
				
			||||
        prepareCallable("SELECT `modGroup`,`minRoll`,`maxRoll`,`subTableID` FROM `static_modgroups`"); | 
				
			||||
         | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
            if (rs != null) | 
				
			||||
                while (rs.next()) { | 
				
			||||
                    recordsRead++; | 
				
			||||
                    LootTable lootTable = LootTable.getModGroup(rs.getInt("modGroup")); | 
				
			||||
                    lootTable.addRow(rs.getFloat("minRoll"), rs.getFloat("maxRoll"), rs.getInt("subTableID"), 0, 0, ""); | 
				
			||||
                } | 
				
			||||
            Logger.info("read: " + recordsRead + " cached: " + LootTable.getModGroups().size()); | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void LOAD_ENCHANT_VALUES() { | 
				
			||||
         | 
				
			||||
        prepareCallable("SELECT `IDString`, `minMod` FROM `static_power_effectmod` WHERE `modType` = ?"); | 
				
			||||
        setString(1,"Value"); | 
				
			||||
         | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
            while (rs.next()) { | 
				
			||||
                Item.addEnchantValue(rs.getString("IDString"), rs.getInt("minMod")); | 
				
			||||
            } | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error( e); | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
     | 
				
			||||
    public void LOAD_ALL_LOOTGROUPS() { | 
				
			||||
         | 
				
			||||
            LootGroup lootGroup; | 
				
			||||
            int recordsRead = 0; | 
				
			||||
             | 
				
			||||
		prepareCallable("SELECT * FROM static_lootgroups"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
                         | 
				
			||||
			while (rs.next()) { | 
				
			||||
                             | 
				
			||||
                          recordsRead++; | 
				
			||||
                          lootGroup = new LootGroup(rs); | 
				
			||||
                          LootManager.addLootGroup(lootGroup); | 
				
			||||
			} | 
				
			||||
                         | 
				
			||||
                        Logger.info( "read: " + recordsRead); | 
				
			||||
                                 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
     | 
				
			||||
        public void LOAD_ALL_LOOTTABLES() { | 
				
			||||
         | 
				
			||||
            engine.loot.LootTable lootTable; | 
				
			||||
            int recordsRead = 0; | 
				
			||||
             | 
				
			||||
		prepareCallable("SELECT * FROM static_loottables"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
                         | 
				
			||||
			while (rs.next()) { | 
				
			||||
                             | 
				
			||||
                          recordsRead++; | 
				
			||||
                          lootTable = new engine.loot.LootTable(rs); | 
				
			||||
                          LootManager.addLootTable(lootTable); | 
				
			||||
			} | 
				
			||||
                         | 
				
			||||
                        Logger.info("read: " + recordsRead); | 
				
			||||
                                 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
         | 
				
			||||
        public void LOAD_ALL_MODGROUPS() { | 
				
			||||
         | 
				
			||||
            ModifierGroup modGroup; | 
				
			||||
            int recordsRead = 0; | 
				
			||||
             | 
				
			||||
		prepareCallable("SELECT * FROM static_modgroups"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
                         | 
				
			||||
			while (rs.next()) { | 
				
			||||
                             | 
				
			||||
                          recordsRead++; | 
				
			||||
                          modGroup = new ModifierGroup(rs); | 
				
			||||
                          LootManager.addModifierGroup(modGroup); | 
				
			||||
			} | 
				
			||||
                         | 
				
			||||
                        Logger.info( "read: " + recordsRead); | 
				
			||||
                                 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
         | 
				
			||||
        public void LOAD_ALL_MODTABLES() { | 
				
			||||
         | 
				
			||||
            ModifierTable modTable; | 
				
			||||
            int recordsRead = 0; | 
				
			||||
             | 
				
			||||
		prepareCallable("SELECT * FROM static_modtables"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
                         | 
				
			||||
			while (rs.next()) { | 
				
			||||
                             | 
				
			||||
                          recordsRead++; | 
				
			||||
                          modTable = new ModifierTable(rs); | 
				
			||||
                          LootManager.addModifierTable(modTable); | 
				
			||||
			} | 
				
			||||
                         | 
				
			||||
                        Logger.info( "read: " + recordsRead); | 
				
			||||
                                 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,28 @@
				@@ -0,0 +1,28 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.MenuOption; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbMenuHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbMenuHandler() { | 
				
			||||
		this.localClass = MenuOption.class; | 
				
			||||
        this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<MenuOption> GET_MENU_OPTIONS(final int id) { | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_menuoption` WHERE menuID = ?"); | 
				
			||||
		setInt(1, id); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,117 @@
				@@ -0,0 +1,117 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.Mine; | 
				
			||||
import engine.objects.MineProduction; | 
				
			||||
import engine.objects.Resource; | 
				
			||||
 | 
				
			||||
import java.time.LocalDateTime; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbMineHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbMineHandler() { | 
				
			||||
		this.localClass = Mine.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Mine GET_MINE(int id) { | 
				
			||||
 | 
				
			||||
		if (id == 0) | 
				
			||||
			return null; | 
				
			||||
 | 
				
			||||
		Mine mine = (Mine) DbManager.getFromCache(Enum.GameObjectType.Mine, id); | 
				
			||||
		if (mine != null) | 
				
			||||
			return mine; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT `obj_building`.*, `object`.`parent` FROM `object` INNER JOIN `obj_building` ON `obj_building`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?;"); | 
				
			||||
 | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return (Mine) getObjectSingle(id); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Mine> GET_ALL_MINES_FOR_SERVER() { | 
				
			||||
		prepareCallable("SELECT `obj_mine`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mine` ON `obj_mine`.`UID` = `object`.`UID`"); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CHANGE_OWNER(Mine mine, int playerUID) { | 
				
			||||
		prepareCallable("UPDATE `obj_mine` SET `mine_ownerUID`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, playerUID); | 
				
			||||
		setLong(2, (long) mine.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CHANGE_RESOURCE(Mine mine, Resource resource) { | 
				
			||||
		prepareCallable("UPDATE `obj_mine` SET `mine_resource`=? WHERE `UID`=?"); | 
				
			||||
		setString(1, resource.name()); | 
				
			||||
		setLong(2, (long) mine.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CHANGE_TYPE(Mine mine, MineProduction productionType) { | 
				
			||||
		prepareCallable("UPDATE `obj_mine` SET `mine_type`=? WHERE `UID`=?"); | 
				
			||||
		setString(1, productionType.name()); | 
				
			||||
		setLong(2, (long) mine.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CHANGE_MINE_TIME(Mine mine, LocalDateTime mineOpenTime) { | 
				
			||||
		prepareCallable("UPDATE `obj_mine` SET `mine_openDate`=? WHERE `UID`=?"); | 
				
			||||
		setLocalDateTime(1, mineOpenTime); | 
				
			||||
		setLong(2, (long) mine.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean SET_FLAGS(Mine mine, int newFlags) { | 
				
			||||
		prepareCallable("UPDATE `obj_mine` SET `flags`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, newFlags); | 
				
			||||
		setLong(2, (long) mine.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Mine m, String name, Object new_value) { | 
				
			||||
		prepareCallable("CALL mine_SETPROP(?,?,?)"); | 
				
			||||
		setLong(1, (long) m.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	// Advance all the mine windows respective to the current day
 | 
				
			||||
	// at boot time.  This ensures that mines always go live
 | 
				
			||||
	// no matter what date in the database
 | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Mine m, String name, Object new_value, Object old_value) { | 
				
			||||
		prepareCallable("CALL mine_GETSETPROP(?,?,?,?)"); | 
				
			||||
		setLong(1, (long) m.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		setString(4, String.valueOf(old_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,351 @@
				@@ -0,0 +1,351 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashMap; | 
				
			||||
 | 
				
			||||
public class dbMobBaseHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbMobBaseHandler() { | 
				
			||||
		this.localClass = MobBase.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
    public MobBase GET_MOBBASE(int id, boolean forceDB) { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		if (id == 0) | 
				
			||||
			return null; | 
				
			||||
 | 
				
			||||
		MobBase mobBase = (MobBase) DbManager.getFromCache(GameObjectType.MobBase, id); | 
				
			||||
 | 
				
			||||
		if ( mobBase != null) | 
				
			||||
			return mobBase; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_mobbase` WHERE `ID`=?"); | 
				
			||||
		setInt(1, id); | 
				
			||||
		return (MobBase) getObjectSingle(id, forceDB, true); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<MobBase> GET_ALL_MOBBASES() { | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_mobbase`;"); | 
				
			||||
		return  getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void SET_AI_DEFAULTS() { | 
				
			||||
		prepareCallable("SELECT * FROM `static_ai_defaults`"); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				MBServerStatics.AI_BASE_AGGRO_RANGE = rs.getInt("aggro_range"); | 
				
			||||
				MBServerStatics.AI_PATROL_DIVISOR = rs.getInt("patrol_chance"); | 
				
			||||
				MBServerStatics.AI_DROP_AGGRO_RANGE = rs.getInt("drop_aggro_range"); | 
				
			||||
				MBServerStatics.AI_POWER_DIVISOR = rs.getInt("cast_chance"); | 
				
			||||
				MBServerStatics.AI_RECALL_RANGE = rs.getInt("recall_range"); | 
				
			||||
				MBServerStatics.AI_PET_HEEL_DISTANCE = rs.getInt("pet_heel_distance"); | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_AI_DEFAULTS() { | 
				
			||||
		prepareCallable("UPDATE `static_ai_defaults` SET `aggro_range` = ?,`patrol_chance`= ?,`drop_aggro_range`= ?,`cast_chance`= ?,`recall_range`= ? WHERE `ID` = 1"); | 
				
			||||
		setInt(1, MBServerStatics.AI_BASE_AGGRO_RANGE); | 
				
			||||
		setInt(2, MBServerStatics.AI_PATROL_DIVISOR); | 
				
			||||
		setInt(3, MBServerStatics.AI_DROP_AGGRO_RANGE); | 
				
			||||
		setInt(4, MBServerStatics.AI_POWER_DIVISOR); | 
				
			||||
		setInt(5, MBServerStatics.AI_RECALL_RANGE); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_FLAGS(int mobBaseID, long flags) { | 
				
			||||
		prepareCallable("UPDATE `static_npc_mobbase` SET `flags` = ? WHERE `ID` = ?"); | 
				
			||||
		setLong(1, flags); | 
				
			||||
		setInt(2, mobBaseID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public HashMap<Integer, Integer> LOAD_STATIC_POWERS(int mobBaseUUID) { | 
				
			||||
		HashMap<Integer, Integer> powersList = new HashMap<>(); | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_mobbase_powers` WHERE `mobbaseUUID`=?"); | 
				
			||||
		setInt(1, mobBaseUUID); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				powersList.put(rs.getInt("token"), rs.getInt("rank")); | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return powersList; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<MobBaseEffects> LOAD_STATIC_EFFECTS(int mobBaseUUID) { | 
				
			||||
		ArrayList<MobBaseEffects> effectsList = new ArrayList<>(); | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_mobbase_effects` WHERE `mobbaseUUID` = ?"); | 
				
			||||
		setInt(1, mobBaseUUID); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				MobBaseEffects mbs = new MobBaseEffects(rs); | 
				
			||||
				effectsList.add(mbs); | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return effectsList; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<MobBaseEffects> GET_RUNEBASE_EFFECTS(int runeID) { | 
				
			||||
		ArrayList<MobBaseEffects> effectsList = new ArrayList<>(); | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_mobbase_effects` WHERE `mobbaseUUID` = ?"); | 
				
			||||
		setInt(1, runeID); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				MobBaseEffects mbs = new MobBaseEffects(rs); | 
				
			||||
				effectsList.add(mbs); | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error (e.getMessage()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return effectsList; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public MobBaseStats LOAD_STATS(int mobBaseUUID) { | 
				
			||||
		MobBaseStats mbs = MobBaseStats.GetGenericStats(); | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_mobbase_stats` WHERE `mobbaseUUID` = ?"); | 
				
			||||
		setInt(1, mobBaseUUID); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				mbs = new MobBaseStats(rs); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return mbs; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<RuneBase> LOAD_RUNES_FOR_MOBBASE(int mobBaseUUID) { | 
				
			||||
 | 
				
			||||
		ArrayList<RuneBase> runes = new ArrayList<>(); | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_mobbase_runes` WHERE `mobbaseUUID` = ?"); | 
				
			||||
		setInt(1, mobBaseUUID); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				int runeID = rs.getInt("runeID"); | 
				
			||||
				RuneBase rune = RuneBase.getRuneBase(runeID); | 
				
			||||
				runes.add(rune); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return runes; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_MOBBASE_EFFECT(int mobBaseUUID, int token, int rank, int reqLvl) { | 
				
			||||
		prepareCallable("INSERT INTO `static_npc_mobbase_effects` (`mobbaseUUID`, `token`, `rank`, `reqLvl`) VALUES (?, ?, ?, ?);"); | 
				
			||||
		setInt(1, mobBaseUUID); | 
				
			||||
		setInt(2, token); | 
				
			||||
		setInt(3, rank); | 
				
			||||
		setInt(4, reqLvl); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_MOBBASE_POWER(int mobBaseUUID, int token, int rank) { | 
				
			||||
		prepareCallable("INSERT INTO `static_npc_mobbase_powers` (`mobbaseUUID`, `token`, `rank`) VALUES (?, ?, ?);"); | 
				
			||||
		setInt(1, mobBaseUUID); | 
				
			||||
		setInt(2, token); | 
				
			||||
		setInt(3, rank); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_SKILLS(int ID, int skillsID) { | 
				
			||||
		prepareCallable("UPDATE `static_npc_mobbase` SET `baseSkills`=? WHERE `ID`=?;"); | 
				
			||||
		setInt(1, skillsID); | 
				
			||||
		setInt(2, ID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_MOBBASE_RUNE(int mobBaseUUID, int runeID) { | 
				
			||||
		prepareCallable("INSERT INTO `static_npc_mobbase_runes` (`mobbaseUUID`, `runeID`) VALUES (?, ?);"); | 
				
			||||
		setInt(1, mobBaseUUID); | 
				
			||||
		setInt(2, runeID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public MobBase COPY_MOBBASE(MobBase toAdd, String name) { | 
				
			||||
		prepareCallable("INSERT INTO `static_npc_mobbase` (`loadID`, `lootTableID`, `name`, `level`, `health`, `atr`, `defense`, `minDmg`,`maxDmg`, `goldMod`, `seeInvis`, `flags`, `noaggro`, `spawntime`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | 
				
			||||
		setInt(1, toAdd.getLoadID()); | 
				
			||||
		setInt(2, toAdd.getLootTable()); | 
				
			||||
		setString(3, (name.length() > 0) ? name : toAdd.getFirstName()); | 
				
			||||
		setInt(4, toAdd.getLevel()); | 
				
			||||
		setFloat(5, toAdd.getHealthMax()); | 
				
			||||
		setInt(5, toAdd.getAtr()); | 
				
			||||
		setInt(6, toAdd.getDefense()); | 
				
			||||
		setFloat(7, toAdd.getMinDmg()); | 
				
			||||
		setFloat(8, toAdd.getMaxDmg()); | 
				
			||||
		setInt(9, toAdd.getGoldMod()); | 
				
			||||
		setInt(10, toAdd.getSeeInvis()); | 
				
			||||
		setLong(11, toAdd.getFlags().toLong()); | 
				
			||||
		setLong(12, toAdd.getNoAggro().toLong()); | 
				
			||||
		setInt(13, toAdd.getSpawnTime()); | 
				
			||||
		int objectUUID = insertGetUUID(); | 
				
			||||
		if (objectUUID > 0) | 
				
			||||
			return GET_MOBBASE(objectUUID, true); | 
				
			||||
		return null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean RENAME_MOBBASE(int ID, String newName) { | 
				
			||||
		prepareCallable("UPDATE `static_npc_mobbase` SET `name`=? WHERE `ID`=?;"); | 
				
			||||
		setString(1, newName); | 
				
			||||
		setInt(2, ID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public void LOAD_ALL_MOBBASE_LOOT(int mobBaseID) { | 
				
			||||
 | 
				
			||||
		if (mobBaseID == 0) | 
				
			||||
			return; | 
				
			||||
		ArrayList<MobLootBase> mobLootList = new ArrayList<>(); | 
				
			||||
		prepareCallable("SELECT * FROM `static_mob_loottable` WHERE `mobBaseID` = ?"); | 
				
			||||
		setInt(1,mobBaseID); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				MobLootBase mobLootBase = new MobLootBase(rs); | 
				
			||||
				mobLootList.add(mobLootBase); | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			MobLootBase.MobLootSet.put(mobBaseID, mobLootList); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_ALL_MOBBASE_SPEEDS(MobBase mobBase) { | 
				
			||||
 | 
				
			||||
		if (mobBase.getLoadID() == 0) | 
				
			||||
			return; | 
				
			||||
		ArrayList<MobLootBase> mobLootList = new ArrayList<>(); | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_mobbase_race` WHERE `mobbaseID` = ?"); | 
				
			||||
		setInt(1,mobBase.getLoadID()); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				float walk = rs.getFloat("walkStandard"); | 
				
			||||
				float walkCombat = rs.getFloat("walkCombat"); | 
				
			||||
				float run = rs.getFloat("runStandard"); | 
				
			||||
				float runCombat = rs.getFloat("runCombat"); | 
				
			||||
				mobBase.updateSpeeds(walk, walkCombat, run, runCombat); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public HashMap<Integer, MobbaseGoldEntry> LOAD_GOLD_FOR_MOBBASE() { | 
				
			||||
 | 
				
			||||
		HashMap<Integer, MobbaseGoldEntry> goldSets; | 
				
			||||
		MobbaseGoldEntry goldSetEntry; | 
				
			||||
		int	mobbaseID; | 
				
			||||
 | 
				
			||||
		goldSets = new HashMap<>(); | 
				
			||||
		int recordsRead = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_npc_mobbase_gold"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
 | 
				
			||||
				mobbaseID = rs.getInt("mobbaseID"); | 
				
			||||
				goldSetEntry = new MobbaseGoldEntry(rs); | 
				
			||||
				goldSets.put(mobbaseID, goldSetEntry); | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			Logger.info("read: " + recordsRead + " cached: " + goldSets.size()); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return goldSets; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,316 @@
				@@ -0,0 +1,316 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.ai.MobileFSM.STATE; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.objects.Mob; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.objects.Zone; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import engine.server.world.WorldServer; | 
				
			||||
import org.joda.time.DateTime; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashMap; | 
				
			||||
 | 
				
			||||
public class dbMobHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbMobHandler() { | 
				
			||||
		this.localClass = Mob.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Mob ADD_MOB(Mob toAdd, boolean isMob) | 
				
			||||
			 { | 
				
			||||
		prepareCallable("CALL `mob_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | 
				
			||||
		setLong(1, toAdd.getParentZoneID()); | 
				
			||||
		setInt(2, toAdd.getMobBaseID()); | 
				
			||||
		setInt(3, toAdd.getGuildUUID()); | 
				
			||||
		setFloat(4, toAdd.getSpawnX()); | 
				
			||||
		setFloat(5, toAdd.getSpawnY()); | 
				
			||||
		setFloat(6, toAdd.getSpawnZ()); | 
				
			||||
		setInt(7, 0); | 
				
			||||
		setFloat(8, toAdd.getSpawnRadius()); | 
				
			||||
		setInt(9, toAdd.getTrueSpawnTime()); | 
				
			||||
		if (toAdd.getContract() != null) | 
				
			||||
			setInt(10, toAdd.getContract().getContractID()); | 
				
			||||
		else | 
				
			||||
			setInt(10, 0); | 
				
			||||
		setInt(11, toAdd.getBuildingID()); | 
				
			||||
		setInt(12, toAdd.getLevel()); | 
				
			||||
		int objectUUID = (int) getUUID(); | 
				
			||||
		if (objectUUID > 0) | 
				
			||||
			return GET_MOB(objectUUID); | 
				
			||||
		return null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Mob ADD_SIEGE_MOB(Mob toAdd, boolean isMob) | 
				
			||||
			 { | 
				
			||||
		prepareCallable("CALL `mob_SIEGECREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | 
				
			||||
		setLong(1, toAdd.getParentZoneID()); | 
				
			||||
		setInt(2, toAdd.getMobBaseID()); | 
				
			||||
		setInt(3, toAdd.getGuildUUID()); | 
				
			||||
		setFloat(4, toAdd.getSpawnX()); | 
				
			||||
		setFloat(5, toAdd.getSpawnY()); | 
				
			||||
		setFloat(6, toAdd.getSpawnZ()); | 
				
			||||
		setInt(7,0); | 
				
			||||
		setFloat(8, toAdd.getSpawnRadius()); | 
				
			||||
		setInt(9, toAdd.getTrueSpawnTime()); | 
				
			||||
		setInt(10, toAdd.getBuildingID()); | 
				
			||||
 | 
				
			||||
		int objectUUID = (int) getUUID(); | 
				
			||||
		if (objectUUID > 0) | 
				
			||||
			return GET_MOB(objectUUID); | 
				
			||||
		return null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateUpgradeTime(Mob mob, DateTime upgradeDateTime) { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
 | 
				
			||||
			prepareCallable("UPDATE obj_mob SET upgradeDate=? " | 
				
			||||
					+ "WHERE UID = ?"); | 
				
			||||
 | 
				
			||||
			if (upgradeDateTime == null) | 
				
			||||
				setNULL(1, java.sql.Types.DATE); | 
				
			||||
			else | 
				
			||||
				setTimeStamp(1, upgradeDateTime.getMillis()); | 
				
			||||
 | 
				
			||||
			setInt(2, mob.getObjectUUID()); | 
				
			||||
			executeUpdate(); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error("Mob.updateUpgradeTime", "UUID: " + mob.getObjectUUID()); | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
		return true; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public int DELETE_MOB(final Mob mob) { | 
				
			||||
		prepareCallable("DELETE FROM `object` WHERE `UID` = ?"); | 
				
			||||
		setLong(1, mob.getDBID()); | 
				
			||||
		return executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_PATROL_POINTS(Mob captain) { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_guards` WHERE `captainUID` = ?"); | 
				
			||||
		setInt(1,captain.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				int mobBaseID = rs.getInt("mobBaseID"); | 
				
			||||
				String name = rs.getString("name"); | 
				
			||||
				Mob toCreate = captain.createGuardMob(mobBaseID, captain.getGuild(), captain.getParentZone(), captain.getBuilding().getLoc(), captain.getLevel(),name); | 
				
			||||
				if (toCreate == null) | 
				
			||||
					return; | 
				
			||||
 | 
				
			||||
				//   toCreate.despawn();
 | 
				
			||||
				if (toCreate != null) { | 
				
			||||
					 | 
				
			||||
					toCreate.setTimeToSpawnSiege(System.currentTimeMillis() + MBServerStatics.FIFTEEN_MINUTES); | 
				
			||||
					toCreate.setDeathTime(System.currentTimeMillis()); | 
				
			||||
					toCreate.setState(STATE.Respawn); | 
				
			||||
 | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_TO_GUARDS(final long captainUID, final int mobBaseID, final String name, final int slot) { | 
				
			||||
		prepareCallable("INSERT INTO `dyn_guards` (`captainUID`, `mobBaseID`,`name`, `slot`) VALUES (?,?,?,?)"); | 
				
			||||
		setLong(1, captainUID); | 
				
			||||
		setInt(2, mobBaseID); | 
				
			||||
		setString(3, name); | 
				
			||||
		setInt(4, slot); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean REMOVE_FROM_GUARDS(final long captainUID, final int mobBaseID, final int slot) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_guards` WHERE `captainUID`=? AND `mobBaseID`=? AND `slot` =?"); | 
				
			||||
		setLong(1, captainUID); | 
				
			||||
		setInt(2, mobBaseID); | 
				
			||||
		setInt(3,slot); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public ArrayList<Mob> GET_ALL_MOBS_FOR_ZONE(Zone zone) { | 
				
			||||
		prepareCallable("SELECT `obj_mob`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mob` ON `obj_mob`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;"); | 
				
			||||
		setLong(1, zone.getObjectUUID()); | 
				
			||||
		return getLargeObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Mob> GET_ALL_MOBS_FOR_BUILDING(int buildingID) { | 
				
			||||
		prepareCallable("SELECT * FROM `obj_mob` WHERE `mob_buildingID` = ?"); | 
				
			||||
		setInt(1, buildingID); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Mob> GET_ALL_MOBS() { | 
				
			||||
		prepareCallable("SELECT `obj_mob`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mob` ON `obj_mob`.`UID` = `object`.`UID`;"); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Mob GET_MOB(final int objectUUID) { | 
				
			||||
		prepareCallable("SELECT `obj_mob`.*, `object`.`parent` FROM `object` INNER JOIN `obj_mob` ON `obj_mob`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?;"); | 
				
			||||
		setLong(1, objectUUID); | 
				
			||||
		return (Mob) getObjectSingle(objectUUID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public int MOVE_MOB(long mobID, long parentID, float locX, float locY, float locZ) { | 
				
			||||
		prepareCallable("UPDATE `object` INNER JOIN `obj_mob` On `object`.`UID` = `obj_mob`.`UID` SET `object`.`parent`=?, `obj_mob`.`mob_spawnX`=?, `obj_mob`.`mob_spawnY`=?, `obj_mob`.`mob_spawnZ`=? WHERE `obj_mob`.`UID`=?;"); | 
				
			||||
		setLong(1, parentID); | 
				
			||||
		setFloat(2, locX); | 
				
			||||
		setFloat(3, locY); | 
				
			||||
		setFloat(4, locZ); | 
				
			||||
		setLong(5, mobID); | 
				
			||||
		return executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_MOB_BUILDING(int buildingID, int mobID) { | 
				
			||||
		prepareCallable("UPDATE `object` INNER JOIN `obj_mob` On `object`.`UID` = `obj_mob`.`UID` SET  `obj_mob`.`mob_buildingID`=? WHERE `obj_mob`.`UID`=?;"); | 
				
			||||
		setInt(1, buildingID); | 
				
			||||
		setInt(2, mobID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Mob m, String name, Object new_value) { | 
				
			||||
		prepareCallable("CALL mob_SETPROP(?,?,?)"); | 
				
			||||
		setLong(1, m.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Mob m, String name, Object new_value, Object old_value) { | 
				
			||||
		prepareCallable("CALL mob_GETSETPROP(?,?,?,?)"); | 
				
			||||
		setLong(1, m.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		setString(4, String.valueOf(old_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public static boolean COPY_ZONE_MOBILES(PlayerCharacter pc, Zone sourceZone, Zone targetZone) { | 
				
			||||
 | 
				
			||||
		ArrayList<Mob> sourceMobList; | 
				
			||||
		Vector3fImmutable worldDelta; | 
				
			||||
		Mob newMobile; | 
				
			||||
 | 
				
			||||
		// Sanity check.  Can't copy a non existent zone
 | 
				
			||||
 | 
				
			||||
		if ((sourceZone == null) || (targetZone == null)) | 
				
			||||
			return false; | 
				
			||||
 | 
				
			||||
		// Generate collections for all buildings in each zone
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		for (Mob mobile : sourceZone.zoneMobSet) { | 
				
			||||
 | 
				
			||||
			// Calculate world coordinate offset between zones
 | 
				
			||||
 | 
				
			||||
			worldDelta = new Vector3fImmutable(targetZone.getAbsX(), targetZone.getAbsY(), targetZone.getAbsZ()); | 
				
			||||
			worldDelta = worldDelta.subtract(new Vector3fImmutable(sourceZone.getAbsX(), sourceZone.getAbsY(), sourceZone.getAbsZ())); | 
				
			||||
 | 
				
			||||
			newMobile = Mob.createMob(mobile.getLoadID(), | 
				
			||||
					mobile.getLoc().add(worldDelta), null, true, targetZone, mobile.getBuilding(), 0); | 
				
			||||
 | 
				
			||||
			if (newMobile != null) { | 
				
			||||
				newMobile.updateDatabase(); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		return true; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public void LOAD_RUNES_FOR_FIDELITY_MOBS() { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT static_zone_npc.npcID,static_zone_npc.loadNum, static_zone_npc.classID, static_zone_npc.professionID, static_zone_npc.extraRune, static_zone_npc.extraRune2 FROM static_zone_npc ; "); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
				int loadNum = rs.getInt("loadNum"); | 
				
			||||
				int fidelityID = rs.getInt("npcID"); | 
				
			||||
				int classID = rs.getInt("classID"); | 
				
			||||
				int professionID = rs.getInt("professionID"); | 
				
			||||
				int extraRune = rs.getInt("extraRune"); | 
				
			||||
				int extraRune2 = rs.getInt("extraRune2"); | 
				
			||||
 | 
				
			||||
				if (WorldServer.ZoneFidelityMobRunes.get(loadNum) == null) | 
				
			||||
					WorldServer.ZoneFidelityMobRunes.put(loadNum, new HashMap<>()); | 
				
			||||
				ArrayList<Integer> runeList; | 
				
			||||
				if (WorldServer.ZoneFidelityMobRunes.get(loadNum).get(fidelityID) == null){ | 
				
			||||
					runeList = new ArrayList<>(4); | 
				
			||||
				}else | 
				
			||||
					runeList = WorldServer.ZoneFidelityMobRunes.get(loadNum).get(fidelityID); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
				if (classID != 0) | 
				
			||||
					runeList.add(classID); | 
				
			||||
				if (professionID != 0) | 
				
			||||
					runeList.add(professionID); | 
				
			||||
				if(extraRune != 0) | 
				
			||||
					runeList.add(extraRune); | 
				
			||||
 | 
				
			||||
				if (extraRune2 != 0) | 
				
			||||
					runeList.add(extraRune2); | 
				
			||||
 | 
				
			||||
				WorldServer.ZoneFidelityMobRunes.get(loadNum).put(fidelityID, runeList); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			rs.close(); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
 | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,397 @@
				@@ -0,0 +1,397 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum.ProfitType; | 
				
			||||
import engine.objects.*; | 
				
			||||
import org.joda.time.DateTime; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashMap; | 
				
			||||
 | 
				
			||||
public class dbNPCHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbNPCHandler() { | 
				
			||||
		this.localClass = NPC.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public NPC ADD_NPC(NPC toAdd, boolean isMob) { | 
				
			||||
		prepareCallable("CALL `npc_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | 
				
			||||
		setLong(1, toAdd.getParentZoneID()); | 
				
			||||
		setString(2, toAdd.getName()); | 
				
			||||
		setInt(3, toAdd.getContractID()); | 
				
			||||
		setInt(4, toAdd.getGuildUUID()); | 
				
			||||
		setFloat(5, toAdd.getSpawnX()); | 
				
			||||
		setFloat(6, toAdd.getSpawnY()); | 
				
			||||
		setFloat(7, toAdd.getSpawnZ()); | 
				
			||||
		setInt(8, toAdd.getLevel()); | 
				
			||||
		setFloat(9, toAdd.getBuyPercent()); | 
				
			||||
		setFloat(10, toAdd.getSellPercent()); | 
				
			||||
		if (toAdd.getBuilding() != null) { | 
				
			||||
			setInt(11, toAdd.getBuilding().getObjectUUID()); | 
				
			||||
		} else { | 
				
			||||
			setInt(11, 0); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		int objectUUID = (int) getUUID(); | 
				
			||||
		if (objectUUID > 0) { | 
				
			||||
			return GET_NPC(objectUUID); | 
				
			||||
		} | 
				
			||||
		return null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public int DELETE_NPC(final NPC npc) { | 
				
			||||
		if (npc.isStatic()) { | 
				
			||||
			return DELETE_STATIC_NPC(npc); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		npc.removeFromZone(); | 
				
			||||
		prepareCallable("DELETE FROM `object` WHERE `UID` = ?"); | 
				
			||||
		setLong(1, (long) npc.getDBID()); | 
				
			||||
		return executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private int DELETE_STATIC_NPC(final NPC npc) { | 
				
			||||
		npc.removeFromZone(); | 
				
			||||
		prepareCallable("DELETE FROM `_init_npc` WHERE `ID` = ?"); | 
				
			||||
		setInt(1, npc.getDBID()); | 
				
			||||
		return executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<NPC> GET_ALL_NPCS_FOR_ZONE(Zone zone) { | 
				
			||||
		prepareCallable("SELECT `obj_npc`.*, `object`.`parent` FROM `object` INNER JOIN `obj_npc` ON `obj_npc`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;"); | 
				
			||||
		setLong(1, (long) zone.getObjectUUID()); | 
				
			||||
		return getLargeObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<NPC> GET_ALL_NPCS() { | 
				
			||||
		prepareCallable("SELECT `obj_npc`.*, `object`.`parent` FROM `object` INNER JOIN `obj_npc` ON `obj_npc`.`UID` = `object`.`UID`;"); | 
				
			||||
		 | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<NPC> GET_NPCS_BY_BUILDING(final int buildingID) { | 
				
			||||
		prepareCallable("SELECT `obj_npc`.*, `object`.`parent` FROM `obj_npc` INNER JOIN `object` ON `obj_npc`.`UID` = `object`.`UID` WHERE `npc_buildingID` = ? LIMIT 3"); | 
				
			||||
		setInt(1, buildingID); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public NPC GET_NPC(final int objectUUID) { | 
				
			||||
		prepareCallable("SELECT `obj_npc`.*, `object`.`parent` FROM `object` INNER JOIN `obj_npc` ON `obj_npc`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?;"); | 
				
			||||
		setLong(1, (long) objectUUID); | 
				
			||||
		return (NPC) getObjectSingle(objectUUID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public int MOVE_NPC(long npcID, long parentID, float locX, float locY, float locZ) { | 
				
			||||
		prepareCallable("UPDATE `object` INNER JOIN `obj_npc` On `object`.`UID` = `obj_npc`.`UID` SET `object`.`parent`=?, `obj_npc`.`npc_spawnX`=?, `obj_npc`.`npc_spawnY`=?, `obj_npc`.`npc_spawnZ`=? WHERE `obj_npc`.`UID`=?;"); | 
				
			||||
		setLong(1, parentID); | 
				
			||||
		setFloat(2, locX); | 
				
			||||
		setFloat(3, locY); | 
				
			||||
		setFloat(4, locZ); | 
				
			||||
		setLong(5, npcID); | 
				
			||||
		return executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final NPC n, String name, Object new_value) { | 
				
			||||
		prepareCallable("CALL npc_SETPROP(?,?,?)"); | 
				
			||||
		setLong(1, (long) n.getDBID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final NPC n, String name, Object new_value, Object old_value) { | 
				
			||||
		prepareCallable("CALL npc_GETSETPROP(?,?,?,?)"); | 
				
			||||
		setLong(1, (long) n.getDBID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		setString(4, String.valueOf(old_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void updateDatabase(final NPC npc) { | 
				
			||||
		prepareCallable("UPDATE obj_npc SET npc_name=?, npc_contractID=?, npc_typeID=?, npc_guildID=?," | 
				
			||||
				+ " npc_spawnX=?, npc_spawnY=?, npc_spawnZ=?, npc_level=? ," | 
				
			||||
				+ " npc_buyPercent=?, npc_sellPercent=?, npc_buildingID=? WHERE UID = ?"); | 
				
			||||
		setString(1, npc.getName()); | 
				
			||||
		setInt(2, (npc.getContract() != null) ? npc.getContract().getObjectUUID() : 0); | 
				
			||||
		setInt(3, 0); | 
				
			||||
		setInt(4, (npc.getGuild() != null) ? npc.getGuild().getObjectUUID() : 0); | 
				
			||||
		setFloat(5, npc.getBindLoc().x); | 
				
			||||
		setFloat(6, npc.getBindLoc().y); | 
				
			||||
		setFloat(7, npc.getBindLoc().z); | 
				
			||||
		setShort(8, npc.getLevel()); | 
				
			||||
		setFloat(9, npc.getBuyPercent()); | 
				
			||||
		setFloat(10, npc.getSellPercent()); | 
				
			||||
		setInt(11, (npc.getBuilding() != null) ? npc.getBuilding().getObjectUUID() : 0); | 
				
			||||
		setInt(12, npc.getDBID()); | 
				
			||||
		executeUpdate(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateUpgradeTime(NPC npc, DateTime upgradeDateTime) { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
 | 
				
			||||
			prepareCallable("UPDATE obj_npc SET upgradeDate=? " | 
				
			||||
					+ "WHERE UID = ?"); | 
				
			||||
 | 
				
			||||
			if (upgradeDateTime == null) | 
				
			||||
				setNULL(1, java.sql.Types.DATE); | 
				
			||||
			else | 
				
			||||
				setTimeStamp(1, upgradeDateTime.getMillis()); | 
				
			||||
 | 
				
			||||
			setInt(2, npc.getObjectUUID()); | 
				
			||||
			executeUpdate(); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error("UUID: " + npc.getObjectUUID()); | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
		return true; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_BUY_PROFIT(NPC npc,float percent) { | 
				
			||||
		prepareCallable("UPDATE `obj_npc` SET `npc_buyPercent`=? WHERE `UID`=?"); | 
				
			||||
		setFloat(1, percent); | 
				
			||||
		setLong(2, npc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_SELL_PROFIT(NPC npc,float percent) { | 
				
			||||
		prepareCallable("UPDATE `obj_npc` SET `npc_sellPercent`=? WHERE `UID`=?"); | 
				
			||||
		setFloat(1, percent); | 
				
			||||
		setLong(2, npc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_SLOT(NPC npc,int slot) { | 
				
			||||
		prepareCallable("UPDATE `obj_npc` SET `npc_slot`=? WHERE `UID`=?"); | 
				
			||||
		setFloat(1, slot); | 
				
			||||
		setLong(2, npc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_MOBBASE(NPC npc, int mobBaseID) { | 
				
			||||
		prepareCallable("UPDATE `obj_npc` SET `npc_raceID`=? WHERE `UID`=?"); | 
				
			||||
		setLong(1, mobBaseID); | 
				
			||||
		setLong(2, npc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_EQUIPSET(NPC npc, int equipSetID) { | 
				
			||||
		prepareCallable("UPDATE `obj_npc` SET `equipsetID`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, equipSetID); | 
				
			||||
		setLong(2, npc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean UPDATE_NAME(NPC npc,String name) { | 
				
			||||
		prepareCallable("UPDATE `obj_npc` SET `npc_name`=? WHERE `UID`=?"); | 
				
			||||
		setString(1, name); | 
				
			||||
		setLong(2, npc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_PIRATE_NAMES() { | 
				
			||||
 | 
				
			||||
		String pirateName; | 
				
			||||
		int mobBase; | 
				
			||||
		int recordsRead = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_piratenames"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
				mobBase = rs.getInt("mobbase"); | 
				
			||||
				pirateName = rs.getString("first_name"); | 
				
			||||
 | 
				
			||||
				// Handle new mobbbase entries
 | 
				
			||||
 | 
				
			||||
				if (NPC._pirateNames.get(mobBase) == null) { | 
				
			||||
					NPC._pirateNames.putIfAbsent(mobBase, new ArrayList<>()); | 
				
			||||
					} | 
				
			||||
 | 
				
			||||
				// Insert name into proper arraylist
 | 
				
			||||
 | 
				
			||||
				NPC._pirateNames.get(mobBase).add(pirateName); | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			Logger.info("names read: " + recordsRead + " for " | 
				
			||||
			             + NPC._pirateNames.size() + " mobBases"); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public void LOAD_RUNES_FOR_FIDELITY_NPC(NPC npc) { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT static_zone_npc.npcID,static_zone_npc.loadNum, static_zone_npc.classID, static_zone_npc.professionID, static_zone_npc.extraRune, static_zone_npc.extraRune2 FROM static_zone_npc WHERE static_zone_npc.loadNum = ? AND static_zone_npc.npcID = ?"); | 
				
			||||
		setInt(1,npc.getParentZoneID()); | 
				
			||||
		setInt(2, npc.getFidalityID()); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
 | 
				
			||||
				 | 
				
			||||
				int classID = rs.getInt("classID"); | 
				
			||||
				int professionID = rs.getInt("professionID"); | 
				
			||||
				int extraRune = rs.getInt("extraRune"); | 
				
			||||
				int extraRune2 = rs.getInt("extraRune2"); | 
				
			||||
				 | 
				
			||||
				npc.classID = classID; | 
				
			||||
				npc.professionID = professionID; | 
				
			||||
				npc.extraRune = extraRune; | 
				
			||||
				npc.extraRune2 = extraRune2; | 
				
			||||
 | 
				
			||||
			 | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			rs.close(); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.toString()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
 | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean ADD_TO_PRODUCTION_LIST(final long ID,final long npcUID, final long itemBaseID, DateTime dateTime, String prefix, String suffix, String name, boolean isRandom, int playerID) { | 
				
			||||
		prepareCallable("INSERT INTO `dyn_npc_production` (`ID`,`npcUID`, `itemBaseID`,`dateToUpgrade`, `isRandom`, `prefix`, `suffix`, `name`,`playerID`) VALUES (?,?,?,?,?,?,?,?,?)"); | 
				
			||||
		setLong(1,ID); | 
				
			||||
		setLong(2, npcUID); | 
				
			||||
		setLong(3, itemBaseID); | 
				
			||||
		setTimeStamp(4, dateTime.getMillis()); | 
				
			||||
		setBoolean(5, isRandom); | 
				
			||||
		setString(6, prefix); | 
				
			||||
		setString(7, suffix); | 
				
			||||
		setString(8, name); | 
				
			||||
		setInt(9,playerID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean REMOVE_FROM_PRODUCTION_LIST(final long ID,final long npcUID) { | 
				
			||||
		prepareCallable("DELETE FROM `dyn_npc_production` WHERE `ID`=? AND `npcUID`=?;"); | 
				
			||||
		setLong(1,ID); | 
				
			||||
		setLong(2, npcUID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_ITEM_TO_INVENTORY(final long ID,final long npcUID) { | 
				
			||||
		prepareCallable("UPDATE `dyn_npc_production` SET `inForge`=? WHERE `ID`=? AND `npcUID`=?;"); | 
				
			||||
		setByte(1, (byte)0); | 
				
			||||
		setLong(2, ID); | 
				
			||||
		setLong(3, npcUID); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_ITEM_PRICE(final long ID,final long npcUID, int value) { | 
				
			||||
		prepareCallable("UPDATE `dyn_npc_production` SET `value`=? WHERE `ID`=? AND `npcUID`=?;"); | 
				
			||||
		setInt(1, value); | 
				
			||||
		setLong(2, ID); | 
				
			||||
		setLong(3, npcUID); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_ITEM_ID(final long ID,final long npcUID,final long value) { | 
				
			||||
		prepareCallable("UPDATE `dyn_npc_production` SET `ID`=? WHERE `ID`=? AND `npcUID`=? LIMIT 1;"); | 
				
			||||
		setLong(1, value); | 
				
			||||
		setLong(2, ID); | 
				
			||||
		setLong(3, npcUID); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_ALL_ITEMS_TO_PRODUCE(NPC npc) { | 
				
			||||
 | 
				
			||||
		if (npc == null) | 
				
			||||
			return; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_npc_production` WHERE `npcUID` = ?"); | 
				
			||||
		setInt(1,npc.getObjectUUID()); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				ProducedItem producedItem = new ProducedItem(rs); | 
				
			||||
				npc.forgedItems.add(producedItem); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean UPDATE_PROFITS(NPC npc,ProfitType profitType, float value){ | 
				
			||||
		prepareCallable("UPDATE `dyn_npc_profits` SET `" + profitType.dbField + "` = ? WHERE `npcUID`=?"); | 
				
			||||
		setFloat(1, value); | 
				
			||||
		setInt(2, npc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public void LOAD_NPC_PROFITS() { | 
				
			||||
 | 
				
			||||
		HashMap<Integer, ArrayList<BuildingRegions>> regions; | 
				
			||||
		NPCProfits npcProfit; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM dyn_npc_profits"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				 | 
				
			||||
				npcProfit = new NPCProfits(rs); | 
				
			||||
				NPCProfits.ProfitCache.put(npcProfit.npcUID, npcProfit); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(": " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean CREATE_PROFITS(NPC npc){ | 
				
			||||
			prepareCallable("INSERT INTO `dyn_npc_profits` (`npcUID`) VALUES (?)"); | 
				
			||||
			setLong(1,npc.getObjectUUID()); | 
				
			||||
			return (executeUpdate() > 0); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,402 @@
				@@ -0,0 +1,402 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.AbstractWorldObject; | 
				
			||||
import engine.objects.Heraldry; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.objects.PlayerFriends; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
 | 
				
			||||
public class dbPlayerCharacterHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbPlayerCharacterHandler() { | 
				
			||||
		this.localClass = PlayerCharacter.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public PlayerCharacter ADD_PLAYER_CHARACTER(final PlayerCharacter toAdd) { | 
				
			||||
		if (toAdd.getAccount() == null) { | 
				
			||||
			return null; | 
				
			||||
		} | 
				
			||||
		prepareCallable("CALL `character_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); | 
				
			||||
		setLong(1, toAdd.getAccount().getObjectUUID()); | 
				
			||||
		setString(2, toAdd.getFirstName()); | 
				
			||||
		setString(3, toAdd.getLastName()); | 
				
			||||
		setInt(4, toAdd.getRace().getRaceRuneID()); | 
				
			||||
		setInt(5, toAdd.getBaseClass().getObjectUUID()); | 
				
			||||
		setInt(6, toAdd.getStrMod()); | 
				
			||||
		setInt(7, toAdd.getDexMod()); | 
				
			||||
		setInt(8, toAdd.getConMod()); | 
				
			||||
		setInt(9, toAdd.getIntMod()); | 
				
			||||
		setInt(10, toAdd.getSpiMod()); | 
				
			||||
		setInt(11, toAdd.getExp()); | 
				
			||||
		setInt(12, toAdd.getSkinColor()); | 
				
			||||
		setInt(13, toAdd.getHairColor()); | 
				
			||||
		setByte(14, toAdd.getHairStyle()); | 
				
			||||
		setInt(15, toAdd.getBeardColor()); | 
				
			||||
		setByte(16, toAdd.getBeardStyle()); | 
				
			||||
 | 
				
			||||
		int objectUUID = (int) getUUID(); | 
				
			||||
		if (objectUUID > 0) { | 
				
			||||
			return GET_PLAYER_CHARACTER(objectUUID); | 
				
			||||
		} | 
				
			||||
		return null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean SET_IGNORE_LIST(int sourceID, int targetID, boolean toIgnore, String charName) { | 
				
			||||
		if (toIgnore) { | 
				
			||||
			//Add to ignore list
 | 
				
			||||
			prepareCallable("INSERT INTO `dyn_character_ignore` (`accountUID`, `ignoringUID`, `characterName`) VALUES (?, ?, ?)"); | 
				
			||||
			setLong(1, (long) sourceID); | 
				
			||||
			setLong(2, (long) targetID); | 
				
			||||
			setString(3, charName); | 
				
			||||
			return (executeUpdate() > 0); | 
				
			||||
		} else { | 
				
			||||
			//delete from ignore list
 | 
				
			||||
			prepareCallable("DELETE FROM `dyn_character_ignore` WHERE `accountUID` = ? && `ignoringUID` = ?"); | 
				
			||||
			setLong(1, (long) sourceID); | 
				
			||||
			setLong(2, (long) targetID); | 
				
			||||
			return (executeUpdate() > 0); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public static boolean DELETE_CHARACTER_IGNORE(final PlayerCharacter pc, final ArrayList<Integer> toDelete) { | 
				
			||||
 | 
				
			||||
		return false; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<PlayerCharacter> GET_ALL_PLAYERCHARACTERS() { | 
				
			||||
		prepareCallable("SELECT * FROM `obj_character`"); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<PlayerCharacter> GET_CHARACTERS_FOR_ACCOUNT(final int id, boolean forceFromDB) { | 
				
			||||
		prepareCallable("SELECT `obj_character`.*, `object`.`parent` FROM `object` INNER JOIN `obj_character` ON `obj_character`.`UID` = `object`.`UID` WHERE `object`.`parent`=? && `obj_character`.`char_isActive`='1';"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return getObjectList(10, forceFromDB); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<PlayerCharacter> GET_CHARACTERS_FOR_ACCOUNT(final int id) { | 
				
			||||
		prepareCallable("SELECT `obj_character`.*, `object`.`parent` FROM `object` INNER JOIN `obj_character` ON `obj_character`.`UID` = `object`.`UID` WHERE `object`.`parent`=? && `obj_character`.`char_isActive`='1';"); | 
				
			||||
		setLong(1, (long) id); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<PlayerCharacter> GET_ALL_CHARACTERS() { | 
				
			||||
		prepareCallable("SELECT `obj_character`.*, `object`.`parent` FROM `object` INNER JOIN `obj_character` ON `obj_character`.`UID` = `object`.`UID` WHERE `obj_character`.`char_isActive`='1';"); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	/** | 
				
			||||
	 * | 
				
			||||
	 * <code>getFirstName</code> looks up the first name of a PlayerCharacter by | 
				
			||||
	 * first checking the GOM cache and then querying the database. | 
				
			||||
	 * PlayerCharacter objects that are not already cached won't be instantiated | 
				
			||||
	 * and cached. | 
				
			||||
	 * | 
				
			||||
	 */ | 
				
			||||
	public String GET_FIRST_NAME(final int objectUUID) { | 
				
			||||
		prepareCallable("SELECT `char_firstname` from `obj_character` WHERE `UID` = ? LIMIT 1"); | 
				
			||||
		setLong(1, (long) objectUUID); | 
				
			||||
		String firstName = ""; | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			if (rs.next()) { | 
				
			||||
				firstName = rs.getString("char_firstname"); | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return firstName; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ConcurrentHashMap<Integer, String> GET_IGNORE_LIST(final int objectUUID, final boolean skipActiveCheck) { | 
				
			||||
		ConcurrentHashMap<Integer, String> out = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); | 
				
			||||
		prepareCallable("SELECT * FROM `dyn_character_ignore` WHERE `accountUID` = ?;"); | 
				
			||||
		setLong(1, (long) objectUUID); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				int ignoreCharacterID = rs.getInt("ignoringUID"); | 
				
			||||
				if (ignoreCharacterID == 0) { | 
				
			||||
					continue; | 
				
			||||
				} | 
				
			||||
				String name = rs.getString("characterName"); | 
				
			||||
				out.put(ignoreCharacterID, name); | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
			return out; // null to explicitly indicate a problem and prevent data loss
 | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return out; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public PlayerCharacter GET_PLAYER_CHARACTER(final int objectUUID) { | 
				
			||||
 | 
				
			||||
		if (objectUUID == 0) | 
				
			||||
			return null; | 
				
			||||
 | 
				
			||||
		PlayerCharacter pc = (PlayerCharacter) DbManager.getFromCache(Enum.GameObjectType.PlayerCharacter, objectUUID); | 
				
			||||
		if (pc != null) | 
				
			||||
			return pc; | 
				
			||||
		prepareCallable("SELECT `obj_character`.*, `object`.`parent` FROM `object` INNER JOIN `obj_character` ON `obj_character`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?"); | 
				
			||||
		setLong(1, (long) objectUUID); | 
				
			||||
		return (PlayerCharacter) getObjectSingle(objectUUID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean INSERT_CHARACTER_IGNORE(final PlayerCharacter pc, final ArrayList<Integer> toAdd) { | 
				
			||||
		boolean allWorked = true; | 
				
			||||
		prepareCallable("INSERT INTO `dyn_character_ignore` (`characterUID`, `ignoringUID`) VALUES (?, ?)"); | 
				
			||||
		setLong(1, (long) pc.getObjectUUID()); | 
				
			||||
		for (int id : toAdd) { | 
				
			||||
			setLong(2, (long) id); | 
				
			||||
			if (executeUpdate(false) == 0) { | 
				
			||||
				allWorked = false; | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
		closeCallable(); | 
				
			||||
		return allWorked; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean IS_CHARACTER_NAME_UNIQUE(final String firstName) { | 
				
			||||
		boolean unique = true; | 
				
			||||
		prepareCallable("SELECT `char_firstname` FROM `obj_character` WHERE `char_isActive`=1 && `char_firstname`=?"); | 
				
			||||
		setString(1, firstName); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			if (rs.next()) { | 
				
			||||
				unique = false; | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getMessage()); | 
				
			||||
			unique = false; | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return unique; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_NAME(String oldFirstName, String newFirstName, String newLastName) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `char_firstname`=?, `char_lastname`=? WHERE `char_firstname`=? AND `char_isActive`='1'"); | 
				
			||||
		setString(1, newFirstName); | 
				
			||||
		setString(2, newLastName); | 
				
			||||
		setString(3, oldFirstName); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean SET_DELETED(final PlayerCharacter pc) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `char_isActive`=? WHERE `UID` = ?"); | 
				
			||||
		setBoolean(1, !pc.isDeleted()); | 
				
			||||
		setLong(2, (long) pc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	public boolean SET_ACTIVE(final PlayerCharacter pc, boolean status) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `char_isActive`=? WHERE `UID` = ?"); | 
				
			||||
		setBoolean(1, status); | 
				
			||||
		setLong(2, (long) pc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	public boolean SET_BIND_BUILDING(final PlayerCharacter pc, int bindBuildingID) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `char_bindBuilding`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, bindBuildingID); | 
				
			||||
		setLong(2, (long) pc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean SET_ANNIVERSERY(final PlayerCharacter pc, boolean flag) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `anniversery`=? WHERE `UID` = ?"); | 
				
			||||
		setBoolean(1, flag); | 
				
			||||
		setLong(2, (long) pc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_CHARACTER_EXPERIENCE(final PlayerCharacter pc) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `char_experience`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, pc.getExp()); | 
				
			||||
		setLong(2, (long) pc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean UPDATE_GUILD(final PlayerCharacter pc, int guildUUID) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `guildUID`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, guildUUID); | 
				
			||||
		setLong(2, (long) pc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_CHARACTER_STAT(final PlayerCharacter pc, String stat, short amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `" + stat + "`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, pc.getExp()); | 
				
			||||
		setLong(2, (long) pc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean UPDATE_CHARACTER_STATS(final PlayerCharacter pc) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `char_strMod`=?, `char_dexMod`=?, `char_conMod`=?, `char_intMod`=?, `char_spiMod`=? WHERE `UID`=?"); | 
				
			||||
		setInt(1, pc.getStrMod()); | 
				
			||||
		setInt(2, pc.getDexMod()); | 
				
			||||
		setInt(3, pc.getConMod()); | 
				
			||||
		setInt(4, pc.getIntMod()); | 
				
			||||
		setInt(5, pc.getSpiMod()); | 
				
			||||
		setLong(6, (long) pc.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final PlayerCharacter c, String name, Object new_value) { | 
				
			||||
		prepareCallable("CALL character_SETPROP(?,?,?)"); | 
				
			||||
		setLong(1, (long) c.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final PlayerCharacter c, String name, Object new_value, Object old_value) { | 
				
			||||
		prepareCallable("CALL character_GETSETPROP(?,?,?,?)"); | 
				
			||||
		setLong(1, (long) c.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		setString(4, String.valueOf(old_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean SET_PROMOTION_CLASS(PlayerCharacter player, int promotionClassID) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `char_promotionClassID`=?  WHERE `UID`=?;"); | 
				
			||||
		setInt(1,promotionClassID); | 
				
			||||
		setInt(2, player.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean SET_INNERCOUNCIL(PlayerCharacter player, boolean isInnerCouncil) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `guild_isInnerCouncil`=?  WHERE `UID`=?;"); | 
				
			||||
		setBoolean(1,isInnerCouncil); | 
				
			||||
		setInt(2, player.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean SET_FULL_MEMBER(PlayerCharacter player, boolean isFullMember) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `guild_isFullMember`=?  WHERE `UID`=?;"); | 
				
			||||
		setBoolean(1,isFullMember); | 
				
			||||
		setInt(2, player.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean SET_TAX_COLLECTOR(PlayerCharacter player, boolean isTaxCollector) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `guild_isTaxCollector`=?  WHERE `UID`=?;"); | 
				
			||||
		setBoolean(1,isTaxCollector); | 
				
			||||
		setInt(2, player.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean SET_RECRUITER(PlayerCharacter player, boolean isRecruiter) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `guild_isRecruiter`=?  WHERE `UID`=?;"); | 
				
			||||
		setBoolean(1,isRecruiter); | 
				
			||||
		setInt(2, player.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean SET_GUILD_TITLE(PlayerCharacter player, int title) { | 
				
			||||
		prepareCallable("UPDATE `obj_character` SET `guild_title`=?  WHERE `UID`=?;"); | 
				
			||||
		setInt(1,title); | 
				
			||||
		setInt(2, player.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	 | 
				
			||||
	public boolean ADD_FRIEND(int source, long friend){ | 
				
			||||
		prepareCallable("INSERT INTO `dyn_character_friends` (`playerUID`, `friendUID`) VALUES (?, ?)"); | 
				
			||||
		setLong(1, (long) source); | 
				
			||||
		setLong(2, (long)friend); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean REMOVE_FRIEND(int source, int friend){ | 
				
			||||
		prepareCallable("DELETE FROM `dyn_character_friends` WHERE (`playerUID`=?) AND (`friendUID`=?)"); | 
				
			||||
		setLong(1, (long) source); | 
				
			||||
		setLong(2, (long)friend); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public void LOAD_PLAYER_FRIENDS() { | 
				
			||||
 | 
				
			||||
		PlayerFriends playerFriend; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM dyn_character_friends"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				playerFriend = new PlayerFriends(rs); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("LoadMeshBounds: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean ADD_HERALDY(int source, AbstractWorldObject character){ | 
				
			||||
		prepareCallable("INSERT INTO `dyn_character_heraldy` (`playerUID`, `characterUID`,`characterType`) VALUES (?, ?,?)"); | 
				
			||||
		setLong(1, (long) source); | 
				
			||||
		setLong(2, (long)character.getObjectUUID()); | 
				
			||||
		setInt(3, character.getObjectType().ordinal()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public boolean REMOVE_HERALDY(int source, int characterUID){ | 
				
			||||
		prepareCallable("DELETE FROM `dyn_character_heraldy` WHERE (`playerUID`=?) AND (`characterUID`=?)"); | 
				
			||||
		setLong(1, (long) source); | 
				
			||||
		setLong(2, (long)characterUID); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public void LOAD_HERALDY() { | 
				
			||||
 | 
				
			||||
		Heraldry heraldy; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM dyn_character_heraldy"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				heraldy = new Heraldry(rs); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("LoadHeraldy: " + e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,54 @@
				@@ -0,0 +1,54 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.PromotionClass; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbPromotionClassHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
    public dbPromotionClassHandler() { | 
				
			||||
        this.localClass = PromotionClass.class; | 
				
			||||
        this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public ArrayList<Integer> GET_ALLOWED_RUNES(final PromotionClass pc) { | 
				
			||||
        ArrayList<Integer> runes = new ArrayList<>(); | 
				
			||||
        prepareCallable("SELECT * FROM `static_rune_promotionrunereq` WHERE `promoID`=?"); | 
				
			||||
        setInt(1, pc.getObjectUUID()); | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
            while (rs.next()) { | 
				
			||||
                runes.add(rs.getInt("runereqID")); | 
				
			||||
            } | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error("Failed to retrieve Allowed Runes for PromotionClass " + pc.getObjectUUID() + ". Error number: " + e.getErrorCode(), e); | 
				
			||||
            return null; | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
        return runes; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public PromotionClass GET_PROMOTION_CLASS(final int objectUUID) { | 
				
			||||
        prepareCallable("SELECT * FROM `static_rune_promotion` WHERE `ID` = ?"); | 
				
			||||
        setInt(1, objectUUID); | 
				
			||||
        return (PromotionClass) getObjectSingle(objectUUID); | 
				
			||||
    } | 
				
			||||
     | 
				
			||||
    public ArrayList<PromotionClass> GET_ALL_PROMOTIONS() { | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_promotion`"); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,85 @@
				@@ -0,0 +1,85 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.Race; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.HashSet; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
 | 
				
			||||
public class dbRaceHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
    public dbRaceHandler() { | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public HashSet<Integer> BEARD_COLORS_FOR_RACE(final int id) { | 
				
			||||
        prepareCallable("SELECT `color` FROM `static_rune_racebeardcolor` WHERE `RaceID` = ?"); | 
				
			||||
        setInt(1, id); | 
				
			||||
        return getIntegerList(1); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public HashSet<Integer> BEARD_STYLES_FOR_RACE(final int id) { | 
				
			||||
        prepareCallable("SELECT `beardStyle` FROM `static_rune_racebeardstyle` WHERE `RaceID` = ?"); | 
				
			||||
        setInt(1, id); | 
				
			||||
        return getIntegerList(1); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public HashSet<Integer> HAIR_COLORS_FOR_RACE(final int id) { | 
				
			||||
        prepareCallable("SELECT `color` FROM `static_rune_racehaircolor` WHERE `RaceID` = ?"); | 
				
			||||
        setInt(1, id); | 
				
			||||
        return getIntegerList(1); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public HashSet<Integer> HAIR_STYLES_FOR_RACE(final int id) { | 
				
			||||
        prepareCallable("SELECT `hairStyle` FROM `static_rune_racehairstyle` WHERE `RaceID` = ?"); | 
				
			||||
        setInt(1, id); | 
				
			||||
        return getIntegerList(1); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public HashSet<Integer> SKIN_COLOR_FOR_RACE(final int id) { | 
				
			||||
        prepareCallable("SELECT `color` FROM `static_rune_raceskincolor` WHERE `RaceID` = ?"); | 
				
			||||
        setInt(1, id); | 
				
			||||
        return getIntegerList(1); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public ConcurrentHashMap<Integer, Race> LOAD_ALL_RACES() { | 
				
			||||
 | 
				
			||||
        ConcurrentHashMap<Integer, Race> races; | 
				
			||||
        Race thisRace; | 
				
			||||
 | 
				
			||||
        races = new ConcurrentHashMap<>(); | 
				
			||||
        int recordsRead = 0; | 
				
			||||
 | 
				
			||||
        prepareCallable("SELECT * FROM static_rune_race"); | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
 | 
				
			||||
                recordsRead++; | 
				
			||||
                thisRace = new Race(rs); | 
				
			||||
 | 
				
			||||
                races.put(thisRace.getRaceRuneID(), thisRace); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
            Logger.info("read: " + recordsRead + " cached: " + races.size()); | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error( e.toString()); | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
        return races; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,73 @@
				@@ -0,0 +1,73 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.Realm; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.net.UnknownHostException; | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
import java.util.logging.Level; | 
				
			||||
 | 
				
			||||
public class dbRealmHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
    public dbRealmHandler() { | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
        public ConcurrentHashMap<Integer, Realm> LOAD_ALL_REALMS() { | 
				
			||||
         | 
				
			||||
            ConcurrentHashMap<Integer, Realm> realmList; | 
				
			||||
            Realm thisRealm; | 
				
			||||
                     | 
				
			||||
            realmList = new ConcurrentHashMap<>(); | 
				
			||||
            int recordsRead = 0; | 
				
			||||
             | 
				
			||||
		prepareCallable("SELECT * FROM obj_realm"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
                         | 
				
			||||
			while (rs.next()) { | 
				
			||||
                             | 
				
			||||
                          recordsRead++; | 
				
			||||
                          thisRealm = new Realm(rs); | 
				
			||||
                          realmList.put(thisRealm.getRealmID(), thisRealm); | 
				
			||||
			} | 
				
			||||
                         | 
				
			||||
                        Logger.info( "read: " + recordsRead + " cached: " + realmList.size()); | 
				
			||||
                                 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} catch (UnknownHostException ex) { | 
				
			||||
            java.util.logging.Logger.getLogger(dbRealmHandler.class.getName()).log(Level.SEVERE, null, ex); | 
				
			||||
        } finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return realmList; | 
				
			||||
	} | 
				
			||||
         | 
				
			||||
    public void REALM_UPDATE(Realm realm) { | 
				
			||||
 | 
				
			||||
            prepareCallable("CALL realm_UPDATE(?,?,?,?)"); | 
				
			||||
             | 
				
			||||
            setInt(1, realm.getRealmID()); | 
				
			||||
            setInt(2, (realm.getRulingCity() == null) ? 0 : realm.getRulingCity().getObjectUUID()); | 
				
			||||
            setInt(3, realm.getCharterType()); | 
				
			||||
        if (realm.ruledSince != null) | 
				
			||||
            setLocalDateTime(4, realm.ruledSince); | 
				
			||||
            else | 
				
			||||
                setNULL(4, java.sql.Types.DATE); | 
				
			||||
             | 
				
			||||
            executeUpdate(); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,37 @@
				@@ -0,0 +1,37 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.Resists; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
 | 
				
			||||
public class dbResistHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
    public dbResistHandler() { | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public Resists GET_RESISTS_FOR_MOB(int resistID) { | 
				
			||||
        prepareCallable("SELECT * FROM `static_npc_mob_resists` WHERE `ID` = ?;"); | 
				
			||||
        setInt(1, resistID); | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
            if (rs.next()) { | 
				
			||||
                return new Resists(rs); | 
				
			||||
            } | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
        return null; | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,35 @@
				@@ -0,0 +1,35 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.RuneBaseAttribute; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbRuneBaseAttributeHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbRuneBaseAttributeHandler() { | 
				
			||||
		this.localClass = RuneBaseAttribute.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<RuneBaseAttribute> GET_ATTRIBUTES_FOR_RUNEBASE(int id) { | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_runebaseattribute` WHERE `RuneBaseID`=?"); | 
				
			||||
		setInt(1, id); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<RuneBaseAttribute> GET_ATTRIBUTES_FOR_RUNEBASE() { | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_runebaseattribute`"); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,73 @@
				@@ -0,0 +1,73 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.RuneBaseEffect; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashMap; | 
				
			||||
 | 
				
			||||
public class dbRuneBaseEffectHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbRuneBaseEffectHandler() { | 
				
			||||
		this.localClass = RuneBaseEffect.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<RuneBaseEffect> GET_EFFECTS_FOR_RUNEBASE(int id) { | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_baseeffect` WHERE `runeID`=?"); | 
				
			||||
		setInt(1, id); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public RuneBaseEffect GET_RUNEBASE_EFFECT(int id) { | 
				
			||||
 | 
				
			||||
		if (id == 0) | 
				
			||||
			return null; | 
				
			||||
		RuneBaseEffect runeBaseEffect = (RuneBaseEffect) DbManager.getFromCache(GameObjectType.RuneBaseEffect, id); | 
				
			||||
		if (runeBaseEffect != null) | 
				
			||||
			return runeBaseEffect; | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_baseeffect` WHERE `ID` = ?"); | 
				
			||||
		setInt(1, id); | 
				
			||||
		return (RuneBaseEffect) getObjectSingle(id); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<RuneBaseEffect> GET_ALL_RUNEBASE_EFFECTS(){ | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_baseeffect`;"); | 
				
			||||
		return  getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	//This calls from cache only. Call this AFTER caching all runebase effects;
 | 
				
			||||
	public HashMap<Integer, ArrayList<RuneBaseEffect>> LOAD_BASEEFFECTS_FOR_RUNEBASE() { | 
				
			||||
		HashMap<Integer, ArrayList<RuneBaseEffect>> runeBaseEffectSet; | 
				
			||||
		runeBaseEffectSet = new HashMap<>(); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		for (AbstractGameObject runeBaseEffect:DbManager.getList(GameObjectType.RuneBaseEffect)){ | 
				
			||||
 | 
				
			||||
			int runeBaseID = ((RuneBaseEffect)runeBaseEffect).getRuneBaseID(); | 
				
			||||
			if (runeBaseEffectSet.get(runeBaseID) == null){ | 
				
			||||
				ArrayList<RuneBaseEffect> runeBaseEffectList = new ArrayList<>(); | 
				
			||||
				runeBaseEffectList.add((RuneBaseEffect)runeBaseEffect); | 
				
			||||
				runeBaseEffectSet.put(runeBaseID, runeBaseEffectList); | 
				
			||||
			} | 
				
			||||
			else{ | 
				
			||||
				ArrayList<RuneBaseEffect>runeBaseEffectList = runeBaseEffectSet.get(runeBaseID); | 
				
			||||
				runeBaseEffectList.add((RuneBaseEffect)runeBaseEffect); | 
				
			||||
				runeBaseEffectSet.put(runeBaseID, runeBaseEffectList); | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
		return runeBaseEffectSet; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,173 @@
				@@ -0,0 +1,173 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.RuneBase; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashMap; | 
				
			||||
import java.util.HashSet; | 
				
			||||
 | 
				
			||||
public class dbRuneBaseHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbRuneBaseHandler() { | 
				
			||||
		this.localClass = RuneBase.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void GET_RUNE_REQS(final RuneBase rb) { | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_runereq` WHERE `runeID` = ?"); | 
				
			||||
		setInt(1, rb.getObjectUUID()); | 
				
			||||
		try { | 
				
			||||
 | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				int type = rs.getInt("type"); | 
				
			||||
 | 
				
			||||
				switch (type) { | 
				
			||||
				case 1: | 
				
			||||
					rb.getRace().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed")); | 
				
			||||
					break; | 
				
			||||
				case 2: | 
				
			||||
					rb.getBaseClass().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed")); | 
				
			||||
					break; | 
				
			||||
				case 3: | 
				
			||||
					rb.getPromotionClass().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed")); | 
				
			||||
					break; | 
				
			||||
				case 4: | 
				
			||||
					rb.getDiscipline().put(rs.getInt("requiredRuneID"), rs.getBoolean("isAllowed")); | 
				
			||||
					break; | 
				
			||||
				case 5: | 
				
			||||
					rb.getOverwrite().add(rs.getInt("requiredRuneID")); | 
				
			||||
					break; | 
				
			||||
				case 6: | 
				
			||||
					rb.setLevelRequired(rs.getInt("requiredRuneID")); | 
				
			||||
					break; | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
			rs.close(); | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error("SQL Error number: " + e.getErrorCode()); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public RuneBase GET_RUNEBASE(final int id) { | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_runebase` WHERE `ID` = ?"); | 
				
			||||
		setInt(1, id); | 
				
			||||
		return (RuneBase) getObjectSingle(id); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<RuneBase> LOAD_ALL_RUNEBASES() { | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_runebase`;"); | 
				
			||||
		return  getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public HashMap<Integer, ArrayList<Integer>> LOAD_ALLOWED_STARTING_RUNES_FOR_BASECLASS() { | 
				
			||||
 | 
				
			||||
		HashMap<Integer, ArrayList<Integer>> runeSets; | 
				
			||||
 | 
				
			||||
		runeSets = new HashMap<>(); | 
				
			||||
		int recordsRead = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_rune_baseclassrune"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
 | 
				
			||||
				int baseClassID = rs.getInt("BaseClassesID"); | 
				
			||||
				int runeBaseID = rs.getInt("RuneBaseID"); | 
				
			||||
 | 
				
			||||
				if (runeSets.get(baseClassID) == null){ | 
				
			||||
					ArrayList<Integer> runeList = new ArrayList<>(); | 
				
			||||
					runeList.add(runeBaseID); | 
				
			||||
					runeSets.put(baseClassID, runeList); | 
				
			||||
				} | 
				
			||||
				else{ | 
				
			||||
					ArrayList<Integer>runeList = runeSets.get(baseClassID); | 
				
			||||
					runeList.add(runeBaseID); | 
				
			||||
					runeSets.put(baseClassID, runeList); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			Logger.info("read: " + recordsRead + " cached: " + runeSets.size()); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return runeSets; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public HashMap<Integer, ArrayList<Integer>> LOAD_ALLOWED_STARTING_RUNES_FOR_RACE() { | 
				
			||||
 | 
				
			||||
		HashMap<Integer, ArrayList<Integer>> runeSets; | 
				
			||||
 | 
				
			||||
		runeSets = new HashMap<>(); | 
				
			||||
		int recordsRead = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_rune_racerune"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
 | 
				
			||||
				int raceID = rs.getInt("RaceID"); | 
				
			||||
				int runeBaseID = rs.getInt("RuneBaseID"); | 
				
			||||
 | 
				
			||||
				if (runeSets.get(raceID) == null){ | 
				
			||||
					ArrayList<Integer> runeList = new ArrayList<>(); | 
				
			||||
					runeList.add(runeBaseID); | 
				
			||||
					runeSets.put(raceID, runeList); | 
				
			||||
				} | 
				
			||||
				else{ | 
				
			||||
					ArrayList<Integer>runeList = runeSets.get(raceID); | 
				
			||||
					runeList.add(runeBaseID); | 
				
			||||
					runeSets.put(raceID, runeList); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			Logger.info( "read: " + recordsRead + " cached: " + runeSets.size()); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return runeSets; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<RuneBase> GET_RUNEBASE_FOR_BASECLASS(final int id) { | 
				
			||||
		prepareCallable("SELECT rb.* FROM static_rune_baseclassrune bcr, static_rune_runebase rb WHERE bcr.RuneBaseID = rb.ID " | 
				
			||||
				+ "&& ( bcr.BaseClassesID = 111111 || bcr.BaseClassesID = ? )"); | 
				
			||||
		setInt(1, id); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public HashSet<RuneBase> GET_RUNEBASE_FOR_RACE(final int id) { | 
				
			||||
		prepareCallable("SELECT rb.* FROM static_rune_racerune rr, static_rune_runebase rb" | 
				
			||||
				+ " WHERE rr.RuneBaseID = rb.ID && ( rr.RaceID = 111111 || rr.RaceID = ?)"); | 
				
			||||
		setInt(1, id); | 
				
			||||
		return new HashSet<>(getObjectList()); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,147 @@
				@@ -0,0 +1,147 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum.ProtectionState; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.Building; | 
				
			||||
import engine.objects.Shrine; | 
				
			||||
import org.joda.time.DateTime; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.net.UnknownHostException; | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbShrineHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
    public dbShrineHandler() { | 
				
			||||
        this.localClass = Shrine.class; | 
				
			||||
        this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public ArrayList<AbstractGameObject> CREATE_SHRINE( int parentZoneID, int OwnerUUID, String name, int meshUUID, | 
				
			||||
            Vector3fImmutable location, float meshScale, int currentHP, | 
				
			||||
            ProtectionState protectionState, int currentGold, int rank, | 
				
			||||
            DateTime upgradeDate, int blueprintUUID, float w, float rotY, String shrineType) { | 
				
			||||
 | 
				
			||||
        prepareCallable("CALL `shrine_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,? ,? ,?, ?,?);"); | 
				
			||||
 | 
				
			||||
       | 
				
			||||
        setInt(1, parentZoneID); | 
				
			||||
        setInt(2, OwnerUUID); | 
				
			||||
        setString(3, name); | 
				
			||||
        setInt(4, meshUUID); | 
				
			||||
        setFloat(5, location.x); | 
				
			||||
        setFloat(6, location.y); | 
				
			||||
        setFloat(7, location.z); | 
				
			||||
        setFloat(8, meshScale); | 
				
			||||
        setInt(9, currentHP); | 
				
			||||
        setString(10, protectionState.name()); | 
				
			||||
        setInt(11, currentGold); | 
				
			||||
        setInt(12, rank); | 
				
			||||
 | 
				
			||||
        if (upgradeDate != null) { | 
				
			||||
            setTimeStamp(13, upgradeDate.getMillis()); | 
				
			||||
        } else { | 
				
			||||
            setNULL(13, java.sql.Types.DATE); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        setInt(14, blueprintUUID); | 
				
			||||
        setFloat(15, w); | 
				
			||||
        setFloat(16, rotY); | 
				
			||||
        setString(17, shrineType); | 
				
			||||
 | 
				
			||||
        ArrayList<AbstractGameObject> list = new ArrayList<>(); | 
				
			||||
        //System.out.println(this.cs.get().toString());
 | 
				
			||||
        try { | 
				
			||||
            boolean work = execute(); | 
				
			||||
            if (work) { | 
				
			||||
                ResultSet rs = this.cs.get().getResultSet(); | 
				
			||||
                while (rs.next()) { | 
				
			||||
                    addObject(list, rs); | 
				
			||||
                } | 
				
			||||
                rs.close(); | 
				
			||||
            } else { | 
				
			||||
                Logger.info("Shrine Creation Failed: " + this.cs.get().toString()); | 
				
			||||
                return list; //city creation failure
 | 
				
			||||
            } | 
				
			||||
            while (this.cs.get().getMoreResults()) { | 
				
			||||
                ResultSet rs = this.cs.get().getResultSet(); | 
				
			||||
                while (rs.next()) { | 
				
			||||
                    addObject(list, rs); | 
				
			||||
                } | 
				
			||||
                rs.close(); | 
				
			||||
            } | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.info("Shrine Creation Failed, SQLException: " + this.cs.get().toString() + e.toString()); | 
				
			||||
            return list; //city creation failure
 | 
				
			||||
        } catch (UnknownHostException e) { | 
				
			||||
            Logger.info("Shrine Creation Failed, UnknownHostException: " + this.cs.get().toString()); | 
				
			||||
            return list; //city creation failure
 | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
        return list; | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public boolean updateFavors(Shrine shrine, int amount, int oldAmount) { | 
				
			||||
 | 
				
			||||
        prepareCallable("UPDATE `obj_shrine` SET `shrine_favors`=? WHERE `UID` = ? AND `shrine_favors` = ?"); | 
				
			||||
        setInt(1, amount); | 
				
			||||
        setLong(2, (long) shrine.getObjectUUID()); | 
				
			||||
        setInt(3, oldAmount); | 
				
			||||
        return (executeUpdate() != 0); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public static void addObject(ArrayList<AbstractGameObject> list, ResultSet rs) throws SQLException, UnknownHostException { | 
				
			||||
        String type = rs.getString("type"); | 
				
			||||
        switch (type) { | 
				
			||||
            case "building": | 
				
			||||
                Building building = new Building(rs); | 
				
			||||
                DbManager.addToCache(building); | 
				
			||||
                list.add(building); | 
				
			||||
                break; | 
				
			||||
            case "shrine": | 
				
			||||
                Shrine shrine = new Shrine(rs); | 
				
			||||
                DbManager.addToCache(shrine); | 
				
			||||
                list.add(shrine); | 
				
			||||
                break; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void LOAD_ALL_SHRINES() { | 
				
			||||
 | 
				
			||||
        Shrine thisShrine; | 
				
			||||
 | 
				
			||||
        prepareCallable("SELECT `obj_shrine`.*, `object`.`parent`, `object`.`type` FROM `object` LEFT JOIN `obj_shrine` ON `object`.`UID` = `obj_shrine`.`UID` WHERE `object`.`type` = 'shrine';"); | 
				
			||||
 | 
				
			||||
        try { | 
				
			||||
            ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
            //shrines cached in rs for easy cache on creation.
 | 
				
			||||
            while (rs.next()) { | 
				
			||||
                thisShrine = new Shrine(rs); | 
				
			||||
                thisShrine.getShrineType().addShrineToServerList(thisShrine); | 
				
			||||
            } | 
				
			||||
 | 
				
			||||
        } catch (SQLException e) { | 
				
			||||
            Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
        } finally { | 
				
			||||
            closeCallable(); | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,143 @@
				@@ -0,0 +1,143 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.MaxSkills; | 
				
			||||
import engine.objects.SkillsBase; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashMap; | 
				
			||||
 | 
				
			||||
public class dbSkillBaseHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbSkillBaseHandler() { | 
				
			||||
		this.localClass = SkillsBase.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public SkillsBase GET_BASE(final int objectUUID) { | 
				
			||||
 | 
				
			||||
		SkillsBase skillsBase = (SkillsBase) DbManager.getFromCache(GameObjectType.SkillsBase, objectUUID); | 
				
			||||
		if (skillsBase != null) | 
				
			||||
			return skillsBase; | 
				
			||||
		prepareCallable("SELECT * FROM static_skill_skillsbase WHERE ID = ?"); | 
				
			||||
		setInt(1, objectUUID); | 
				
			||||
		SkillsBase sb; | 
				
			||||
		sb = (SkillsBase) getObjectSingle(objectUUID); | 
				
			||||
		SkillsBase.putInCache(sb); | 
				
			||||
		return sb; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public SkillsBase GET_BASE_BY_NAME(String name) { | 
				
			||||
		SkillsBase sb = SkillsBase.getFromCache(name); | 
				
			||||
		if (sb != null) { | 
				
			||||
			return sb; | 
				
			||||
		} | 
				
			||||
		prepareCallable("SELECT * FROM static_skill_skillsbase WHERE name = ?"); | 
				
			||||
		setString(1, name); | 
				
			||||
		ArrayList<AbstractGameObject> result = getObjectList(); | 
				
			||||
		if (result.size() > 0) { | 
				
			||||
			sb = (SkillsBase) result.get(0); | 
				
			||||
			SkillsBase.putInCache(sb); | 
				
			||||
			return sb; | 
				
			||||
		} else { | 
				
			||||
			return null; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public SkillsBase GET_BASE_BY_TOKEN(final int token) { | 
				
			||||
		SkillsBase sb = SkillsBase.getFromCache(token); | 
				
			||||
		if (sb != null) { | 
				
			||||
			return sb; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_skill_skillsbase WHERE token = ?"); | 
				
			||||
		setInt(1, token); | 
				
			||||
		ArrayList<AbstractGameObject> result = getObjectList(); | 
				
			||||
		if (result.size() > 0) { | 
				
			||||
			sb = (SkillsBase) result.get(0); | 
				
			||||
			SkillsBase.putInCache(sb); | 
				
			||||
			return sb; | 
				
			||||
		} else { | 
				
			||||
			return null; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_ALL_MAX_SKILLS_FOR_CONTRACT() { | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `static_rune_maxskills`"); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				MaxSkills maxSKills = new MaxSkills(rs); | 
				
			||||
				if (MaxSkills.MaxSkillsSet.get(maxSKills.getRuneID()) == null){ | 
				
			||||
					ArrayList<MaxSkills> newMaxSkillsList = new ArrayList<>(); | 
				
			||||
					newMaxSkillsList.add(maxSKills); | 
				
			||||
					MaxSkills.MaxSkillsSet.put(maxSKills.getRuneID(), newMaxSkillsList); | 
				
			||||
				}else | 
				
			||||
					MaxSkills.MaxSkillsSet.get(maxSKills.getRuneID()).add(maxSKills); | 
				
			||||
 | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	public void LOAD_ALL_RUNE_SKILLS() { | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `static_skill_skillsgranted`"); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				int runeID = rs.getInt("runeID"); | 
				
			||||
				int token = rs.getInt("token"); | 
				
			||||
				int amount = rs.getInt("amount"); | 
				
			||||
				 | 
				
			||||
				if (SkillsBase.runeSkillsCache.get(runeID) == null) | 
				
			||||
					SkillsBase.runeSkillsCache.put(runeID, new HashMap<>()); | 
				
			||||
				 | 
				
			||||
				SkillsBase.runeSkillsCache.get(runeID).put(token, amount); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,35 @@
				@@ -0,0 +1,35 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.SkillReq; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbSkillReqHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
    public dbSkillReqHandler() { | 
				
			||||
        this.localClass = SkillReq.class; | 
				
			||||
        this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public ArrayList<SkillReq> GET_REQS_FOR_RUNE(final int objectUUID) { | 
				
			||||
        prepareCallable("SELECT * FROM `static_skill_skillreq` WHERE `runeID`=?"); | 
				
			||||
        setInt(1, objectUUID); | 
				
			||||
        return getObjectList(); | 
				
			||||
    } | 
				
			||||
     | 
				
			||||
    public SkillReq GET_REQS_BY_SKILLID(int skillID) { | 
				
			||||
        prepareCallable("SELECT * FROM `static_skill_skillreq` WHERE `skillID` = ?"); | 
				
			||||
        setInt(1,skillID); | 
				
			||||
        int objectUUID = (int) getUUID(); | 
				
			||||
        return (SkillReq) this.getObjectSingle(objectUUID); | 
				
			||||
    } | 
				
			||||
} | 
				
			||||
@ -0,0 +1,75 @@
				@@ -0,0 +1,75 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.objects.SpecialLoot; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.HashMap; | 
				
			||||
 | 
				
			||||
public class dbSpecialLootHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbSpecialLootHandler() { | 
				
			||||
		this.localClass = SpecialLoot.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<SpecialLoot> GET_SPECIALLOOT(int mobbaseID) { | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_mob_specialloot` WHERE `mobbaseID`=?"); | 
				
			||||
		setInt(1, mobbaseID); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void GenerateSpecialLoot(){ | 
				
			||||
		HashMap<Integer, ArrayList<SpecialLoot>> lootSets; | 
				
			||||
		SpecialLoot lootSetEntry; | 
				
			||||
		int	lootSetID; | 
				
			||||
 | 
				
			||||
		lootSets = new HashMap<>(); | 
				
			||||
		int recordsRead = 0; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT * FROM static_zone_npc_specialloot"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
 | 
				
			||||
				recordsRead++; | 
				
			||||
 | 
				
			||||
				lootSetID = rs.getInt("lootSet"); | 
				
			||||
				lootSetEntry = new SpecialLoot(rs,true); | 
				
			||||
 | 
				
			||||
				if (lootSets.get(lootSetID) == null){ | 
				
			||||
					ArrayList<SpecialLoot> lootList = new ArrayList<>(); | 
				
			||||
					lootList.add(lootSetEntry); | 
				
			||||
					lootSets.put(lootSetID, lootList); | 
				
			||||
				} | 
				
			||||
				else{ | 
				
			||||
					ArrayList<SpecialLoot>lootList = lootSets.get(lootSetID); | 
				
			||||
					lootList.add(lootSetEntry); | 
				
			||||
					lootSets.put(lootSetID, lootList); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
			Logger.info( "read: " + recordsRead + " cached: " + lootSets.size()); | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		SpecialLoot.LootMap = lootSets; | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,31 @@
				@@ -0,0 +1,31 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.VendorDialog; | 
				
			||||
 | 
				
			||||
public class dbVendorDialogHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbVendorDialogHandler() { | 
				
			||||
		this.localClass = VendorDialog.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public VendorDialog GET_VENDORDIALOG(final int objectUUID) { | 
				
			||||
		VendorDialog vd = (VendorDialog) DbManager.getFromCache(Enum.GameObjectType.VendorDialog, objectUUID); | 
				
			||||
		if (vd != null) | 
				
			||||
			return vd; | 
				
			||||
		prepareCallable("SELECT * FROM `static_npc_vendordialog` WHERE `ID`=?"); | 
				
			||||
		setInt(1, objectUUID); | 
				
			||||
		return (VendorDialog) getObjectSingle(objectUUID); | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,449 @@
				@@ -0,0 +1,449 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.Enum.ProtectionState; | 
				
			||||
import engine.Enum.TransactionType; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
import org.joda.time.DateTime; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.net.UnknownHostException; | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.sql.SQLException; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
import java.util.concurrent.ConcurrentHashMap; | 
				
			||||
 | 
				
			||||
public class dbWarehouseHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	private static final ConcurrentHashMap<Integer, String> columns = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); | 
				
			||||
 | 
				
			||||
	public dbWarehouseHandler() { | 
				
			||||
		this.localClass = Warehouse.class; | 
				
			||||
		this.localObjectType = engine.Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
 | 
				
			||||
		if (columns.isEmpty()) { | 
				
			||||
			createColumns(); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Warehouse CREATE_WAREHOUSE(Warehouse wh) { | 
				
			||||
		try { | 
				
			||||
			wh = this.addWarehouse(wh); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			Logger.error(e); | 
				
			||||
			wh = null; | 
				
			||||
			 | 
				
			||||
		} | 
				
			||||
		return wh; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<AbstractGameObject> CREATE_WAREHOUSE( int parentZoneID, int OwnerUUID, String name, int meshUUID, | 
				
			||||
			Vector3fImmutable location, float meshScale, int currentHP, | 
				
			||||
			ProtectionState protectionState, int currentGold, int rank, | 
				
			||||
			DateTime upgradeDate, int blueprintUUID, float w, float rotY) { | 
				
			||||
 | 
				
			||||
		prepareCallable("CALL `WAREHOUSE_CREATE`(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,? ,? ,?, ?);"); | 
				
			||||
 | 
				
			||||
		setInt(1, parentZoneID); | 
				
			||||
		setInt(2, OwnerUUID); | 
				
			||||
		setString(3, name); | 
				
			||||
		setInt(4, meshUUID); | 
				
			||||
		setFloat(5, location.x); | 
				
			||||
		setFloat(6, location.y); | 
				
			||||
		setFloat(7, location.z); | 
				
			||||
		setFloat(8, meshScale); | 
				
			||||
		setInt(9, currentHP); | 
				
			||||
		setString(10, protectionState.name()); | 
				
			||||
		setInt(11, currentGold); | 
				
			||||
		setInt(12, rank); | 
				
			||||
 | 
				
			||||
		if (upgradeDate != null) { | 
				
			||||
			setTimeStamp(13, upgradeDate.getMillis()); | 
				
			||||
		} else { | 
				
			||||
			setNULL(13, java.sql.Types.DATE); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		setInt(14, blueprintUUID); | 
				
			||||
		setFloat(15, w); | 
				
			||||
		setFloat(16, rotY); | 
				
			||||
 | 
				
			||||
		ArrayList<AbstractGameObject> list = new ArrayList<>(); | 
				
			||||
		//System.out.println(this.cs.get().toString());
 | 
				
			||||
		try { | 
				
			||||
			boolean work = execute(); | 
				
			||||
			if (work) { | 
				
			||||
				ResultSet rs = this.cs.get().getResultSet(); | 
				
			||||
				while (rs.next()) { | 
				
			||||
					addObject(list, rs); | 
				
			||||
				} | 
				
			||||
				rs.close(); | 
				
			||||
			} else { | 
				
			||||
				Logger.info("Warehouse Creation Failed: " + this.cs.get().toString()); | 
				
			||||
				return list; //city creation failure
 | 
				
			||||
			} | 
				
			||||
			while (this.cs.get().getMoreResults()) { | 
				
			||||
				ResultSet rs = this.cs.get().getResultSet(); | 
				
			||||
				while (rs.next()) { | 
				
			||||
					addObject(list, rs); | 
				
			||||
				} | 
				
			||||
				rs.close(); | 
				
			||||
			} | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.info("Warehouse Creation Failed, SQLException: " + this.cs.get().toString() + e.toString()); | 
				
			||||
			return list; //city creation failure
 | 
				
			||||
		} catch (UnknownHostException e) { | 
				
			||||
			Logger.info("Warehouse Creation Failed, UnknownHostException: " + this.cs.get().toString()); | 
				
			||||
			return list; //city creation failure
 | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return list; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	//Don't call yet, not ready in DB. -
 | 
				
			||||
	public boolean WAREHOUSE_ADD(Item item, Warehouse warehouse, ItemBase ib, int amount) { | 
				
			||||
		if (item == null || warehouse == null || ib == null || !(dbWarehouseHandler.columns.containsKey(ib.getUUID()))) { | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
		if ((item.getNumOfItems() - amount) < 0) { | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
		if (!warehouse.getResources().containsKey(ib)) { | 
				
			||||
			return false; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		prepareCallable("CALL `warehouse_ADD`(?,?,?,?,?,?,?);"); | 
				
			||||
		setLong(1, (long) warehouse.getObjectUUID()); | 
				
			||||
		setInt(2, warehouse.getResources().get(ib)); | 
				
			||||
		setLong(3, (long) item.getObjectUUID()); | 
				
			||||
		setInt(4, item.getNumOfItems()); | 
				
			||||
		setInt(5, amount); | 
				
			||||
		setString(6, dbWarehouseHandler.columns.get(ib.getUUID())); | 
				
			||||
		setInt(7, ib.getUUID()); | 
				
			||||
		String result = getResult(); | 
				
			||||
 | 
				
			||||
		return (result != null && result.equals("success")); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private Warehouse addWarehouse(Warehouse toAdd) { | 
				
			||||
		prepareCallable("CALL `warehouse_CREATE`(?);"); | 
				
			||||
		setInt(1, toAdd.getUID()); | 
				
			||||
		int objectUUID = (int) getUUID(); | 
				
			||||
		if (objectUUID > 0) { | 
				
			||||
			return GET_WAREHOUSE(objectUUID); | 
				
			||||
		} | 
				
			||||
		return null; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Warehouse GET_WAREHOUSE(int objectUUID) { | 
				
			||||
		Warehouse warehouse = (Warehouse) DbManager.getFromCache(GameObjectType.Warehouse, objectUUID); | 
				
			||||
		if (warehouse != null) | 
				
			||||
			return warehouse; | 
				
			||||
		prepareCallable("SELECT * FROM `obj_warehouse` WHERE `UID` = ?"); | 
				
			||||
		setInt(1, objectUUID); | 
				
			||||
		return (Warehouse) getObjectSingle(objectUUID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateLocks(final Warehouse wh, long locks) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_locks`=? WHERE `UID` = ?"); | 
				
			||||
		setLong(1, locks); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateGold(final Warehouse wh, int amount ) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_gold`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateStone(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_stone`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateTruesteel(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_truesteel`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateIron(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_iron`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateAdamant(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_adamant`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateLumber(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_lumber`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateOak(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_oak`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateBronzewood(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_bronzewood`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateMandrake(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_mandrake`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateCoal(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_coal`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateAgate(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_agate`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateDiamond(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_diamond`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateOnyx(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_onyx`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateAzoth(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_azoth`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateOrichalk(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_orichalk`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateAntimony(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_antimony`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateSulfur(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_sulfur`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateQuicksilver(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_quicksilver`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateGalvor(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_galvor`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateWormwood(final Warehouse wh, int amount ) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_wormwood`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateObsidian(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_obsidian`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateBloodstone(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_bloodstone`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean updateMithril(final Warehouse wh, int amount) { | 
				
			||||
		prepareCallable("UPDATE `obj_warehouse` SET `warehouse_mithril`=? WHERE `UID` = ?"); | 
				
			||||
		setInt(1, amount); | 
				
			||||
		setInt(2, wh.getUID()); | 
				
			||||
 | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	private static void createColumns() { | 
				
			||||
		columns.put(1580000, "warehouse_stone"); | 
				
			||||
		columns.put(1580001, "warehouse_truesteel"); | 
				
			||||
		columns.put(1580002, "warehouse_iron"); | 
				
			||||
		columns.put(1580003, "warehouse_adamant"); | 
				
			||||
		columns.put(1580004, "warehouse_lumber"); | 
				
			||||
		columns.put(1580005, "warehouse_oak"); | 
				
			||||
		columns.put(1580006, "warehouse_bronzewood"); | 
				
			||||
		columns.put(1580007, "warehouse_mandrake"); | 
				
			||||
		columns.put(1580008, "warehouse_coal"); | 
				
			||||
		columns.put(1580009, "warehouse_agate"); | 
				
			||||
		columns.put(1580010, "warehouse_diamond"); | 
				
			||||
		columns.put(1580011, "warehouse_onyx"); | 
				
			||||
		columns.put(1580012, "warehouse_azoth"); | 
				
			||||
		columns.put(1580013, "warehouse_orichalk"); | 
				
			||||
		columns.put(1580014, "warehouse_antimony"); | 
				
			||||
		columns.put(1580015, "warehouse_sulfur"); | 
				
			||||
		columns.put(1580016, "warehouse_quicksilver"); | 
				
			||||
		columns.put(1580017, "warehouse_galvor"); | 
				
			||||
		columns.put(1580018, "warehouse_wormwood"); | 
				
			||||
		columns.put(1580019, "warehouse_obsidian"); | 
				
			||||
		columns.put(1580020, "warehouse_bloodstone"); | 
				
			||||
		columns.put(1580021, "warehouse_mithril"); | 
				
			||||
		columns.put(7, "warehouse_gold"); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean CREATE_TRANSACTION(int warehouseBuildingID, GameObjectType targetType, int targetUUID, TransactionType transactionType,Resource resource, int amount,DateTime date){ | 
				
			||||
		Transaction transactions = null; | 
				
			||||
		prepareCallable("INSERT INTO `dyn_warehouse_transactions` (`warehouseUID`, `targetType`,`targetUID`, `type`,`resource`,`amount`,`date` ) VALUES (?,?,?,?,?,?,?)"); | 
				
			||||
		setLong(1, warehouseBuildingID); | 
				
			||||
		setString(2, targetType.name()); | 
				
			||||
		setLong(3, targetUUID); | 
				
			||||
		setString(4, transactionType.name()); | 
				
			||||
		setString(5, resource.name()); | 
				
			||||
		setInt(6,amount); | 
				
			||||
		setTimeStamp(7,date.getMillis()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	public static void addObject(ArrayList<AbstractGameObject> list, ResultSet rs) throws SQLException, UnknownHostException { | 
				
			||||
		String type = rs.getString("type"); | 
				
			||||
		switch (type) { | 
				
			||||
		case "building": | 
				
			||||
			Building building = new Building(rs); | 
				
			||||
			DbManager.addToCache(building); | 
				
			||||
			list.add(building); | 
				
			||||
			break; | 
				
			||||
		case "warehouse": | 
				
			||||
			Warehouse warehouse = new Warehouse(rs); | 
				
			||||
			DbManager.addToCache(warehouse); | 
				
			||||
			list.add(warehouse); | 
				
			||||
			break; | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Transaction> GET_TRANSACTIONS_FOR_WAREHOUSE(final int warehouseUUID) { | 
				
			||||
		ArrayList<Transaction> transactionsList = new ArrayList<>(); | 
				
			||||
		prepareCallable("SELECT * FROM dyn_warehouse_transactions WHERE `warehouseUID` = ?;"); | 
				
			||||
		setInt(1, warehouseUUID); | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
 | 
				
			||||
			//shrines cached in rs for easy cache on creation.
 | 
				
			||||
			while (rs.next()) { | 
				
			||||
				Transaction transactions = new Transaction(rs); | 
				
			||||
				transactionsList.add(transactions); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error( e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
		return transactionsList; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public void LOAD_ALL_WAREHOUSES() { | 
				
			||||
 | 
				
			||||
		Warehouse thisWarehouse; | 
				
			||||
 | 
				
			||||
		prepareCallable("SELECT `obj_warehouse`.*, `object`.`parent`, `object`.`type` FROM `object` LEFT JOIN `obj_warehouse` ON `object`.`UID` = `obj_warehouse`.`UID` WHERE `object`.`type` = 'warehouse';"); | 
				
			||||
 | 
				
			||||
		try { | 
				
			||||
			ResultSet rs = executeQuery(); | 
				
			||||
			while (rs.next()) { | 
				
			||||
				thisWarehouse = new Warehouse(rs); | 
				
			||||
				thisWarehouse.runAfterLoad(); | 
				
			||||
				thisWarehouse.loadAllTransactions(); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (SQLException e) { | 
				
			||||
			Logger.error(e.getErrorCode() + ' ' + e.getMessage(), e); | 
				
			||||
		} finally { | 
				
			||||
			closeCallable(); | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
} | 
				
			||||
@ -0,0 +1,93 @@
				@@ -0,0 +1,93 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.db.handlers; | 
				
			||||
 | 
				
			||||
import engine.Enum; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.Zone; | 
				
			||||
 | 
				
			||||
import java.sql.ResultSet; | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public class dbZoneHandler extends dbHandlerBase { | 
				
			||||
 | 
				
			||||
	public dbZoneHandler() { | 
				
			||||
		this.localClass = Zone.class; | 
				
			||||
		this.localObjectType = Enum.GameObjectType.valueOf(this.localClass.getSimpleName()); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Zone> GET_ALL_NODES(Zone zone) { | 
				
			||||
		ArrayList<Zone> wsmList = new ArrayList<>(); | 
				
			||||
		wsmList.addAll(zone.getNodes()); | 
				
			||||
		if (zone.absX == 0.0f) { | 
				
			||||
			zone.absX = zone.getXCoord(); | 
				
			||||
		} | 
				
			||||
		if (zone.absY == 0.0f) { | 
				
			||||
			zone.absY = zone.getYCoord(); | 
				
			||||
		} | 
				
			||||
		if (zone.absZ == 0.0f) { | 
				
			||||
			zone.absZ = zone.getZCoord(); | 
				
			||||
		} | 
				
			||||
		for (Zone child : zone.getNodes()) { | 
				
			||||
			child.absX = child.getXCoord() + zone.absX; | 
				
			||||
			child.absY = child.getYCoord() + zone.absY; | 
				
			||||
			child.absZ = child.getZCoord() + zone.absZ; | 
				
			||||
			wsmList.addAll(this.GET_ALL_NODES(child)); | 
				
			||||
		} | 
				
			||||
		return wsmList; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public Zone GET_BY_UID(long ID) { | 
				
			||||
 | 
				
			||||
		Zone zone = (Zone) DbManager.getFromCache(Enum.GameObjectType.Zone, (int)ID); | 
				
			||||
		if (zone != null) | 
				
			||||
			return zone; | 
				
			||||
		prepareCallable("SELECT `obj_zone`.*, `object`.`parent` FROM `object` INNER JOIN `obj_zone` ON `obj_zone`.`UID` = `object`.`UID` WHERE `object`.`UID` = ?;"); | 
				
			||||
		setLong(1, ID); | 
				
			||||
		return (Zone) getObjectSingle((int) ID); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ArrayList<Zone> GET_MAP_NODES(final int objectUUID) { | 
				
			||||
		prepareCallable("SELECT `obj_zone`.*, `object`.`parent` FROM `object` INNER JOIN `obj_zone` ON `obj_zone`.`UID` = `object`.`UID` WHERE `object`.`parent` = ?;"); | 
				
			||||
		setLong(1, (long) objectUUID); | 
				
			||||
		return getObjectList(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public ResultSet GET_ZONE_EXTENTS(final int loadNum) { | 
				
			||||
		prepareCallable("SELECT * FROM `static_zone_size` WHERE `loadNum`=?;"); | 
				
			||||
		setInt(1, loadNum); | 
				
			||||
		return executeQuery(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Zone z, String name, Object new_value) { | 
				
			||||
		prepareCallable("CALL zone_SETPROP(?,?,?)"); | 
				
			||||
		setLong(1, (long) z.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public String SET_PROPERTY(final Zone z, String name, Object new_value, Object old_value) { | 
				
			||||
		prepareCallable("CALL zone_GETSETPROP(?,?,?,?)"); | 
				
			||||
		setLong(1, (long) z.getObjectUUID()); | 
				
			||||
		setString(2, name); | 
				
			||||
		setString(3, String.valueOf(new_value)); | 
				
			||||
		setString(4, String.valueOf(old_value)); | 
				
			||||
		return getResult(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	public boolean DELETE_ZONE(final Zone zone) { | 
				
			||||
 | 
				
			||||
		prepareCallable("DELETE FROM `object` WHERE `UID` = ? AND `type` = 'zone'"); | 
				
			||||
		setInt(1, zone.getObjectUUID()); | 
				
			||||
		return (executeUpdate() != 0); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,181 @@
				@@ -0,0 +1,181 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd; | 
				
			||||
 | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.gameManager.ChatManager; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.*; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
public abstract class AbstractDevCmd { | 
				
			||||
 | 
				
			||||
    protected final ArrayList<String> cmdStrings; | 
				
			||||
    private AbstractGameObject tr; | 
				
			||||
    private String rsult; | 
				
			||||
 | 
				
			||||
    public AbstractDevCmd(String cmdString) { | 
				
			||||
        super(); | 
				
			||||
        this.cmdStrings = new ArrayList<>(); | 
				
			||||
        this.addCmdString(cmdString); | 
				
			||||
        this.rsult = ""; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * This function is called by the DevCmdManager. Method splits argString | 
				
			||||
     * into a String array and then calls the subclass specific _doCmd method. | 
				
			||||
     */ | 
				
			||||
 | 
				
			||||
    public void doCmd(PlayerCharacter pcSender, String argString, | 
				
			||||
            AbstractGameObject target) { | 
				
			||||
        String[] args = argString.split(" "); | 
				
			||||
 | 
				
			||||
        if (pcSender == null) { | 
				
			||||
            return; | 
				
			||||
        } | 
				
			||||
 | 
				
			||||
        if (args.length > 0 && args[0].equalsIgnoreCase("?")) { | 
				
			||||
            this.sendHelp(pcSender); | 
				
			||||
            this.sendUsage(pcSender); | 
				
			||||
        } else { | 
				
			||||
            this.tr = target; | 
				
			||||
            this._doCmd(pcSender, args, target); | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected abstract void _doCmd(PlayerCharacter pcSender, String[] args, | 
				
			||||
            AbstractGameObject target); | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the string sent to the client that displays how to use this | 
				
			||||
     * command. | 
				
			||||
     */ | 
				
			||||
 | 
				
			||||
    public final String getUsageString() { | 
				
			||||
        return "Usage: " + this._getUsageString(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected abstract String _getUsageString(); | 
				
			||||
 | 
				
			||||
    /** | 
				
			||||
     * Returns the string sent to the client that displays what this command | 
				
			||||
     * does. | 
				
			||||
     */ | 
				
			||||
 | 
				
			||||
    public final String getHelpString() { | 
				
			||||
        return this.getMainCmdString() + ": " + this._getHelpString(); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected abstract String _getHelpString(); | 
				
			||||
 | 
				
			||||
    public final ArrayList<String> getCmdStrings() { | 
				
			||||
        return cmdStrings; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public final String getMainCmdString() { | 
				
			||||
        return this.cmdStrings.get(0); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected void addCmdString(String cmdString) { | 
				
			||||
        String lowercase = cmdString.toLowerCase(); | 
				
			||||
        this.cmdStrings.add(lowercase); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void setTarget(AbstractGameObject ago) { | 
				
			||||
        this.tr = ago; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public AbstractGameObject getTarget() { | 
				
			||||
        return this.tr; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public void setResult(String result) { | 
				
			||||
        this.rsult = result; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    public String getResult() { | 
				
			||||
        return this.rsult; | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /* | 
				
			||||
     * Helper functions | 
				
			||||
     */ | 
				
			||||
    protected void sendUsage(PlayerCharacter pc) { | 
				
			||||
        this.throwbackError(pc, this.getUsageString()); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected void sendHelp(PlayerCharacter pc) { | 
				
			||||
        this.throwbackError(pc, this.getHelpString()); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected void throwbackError(PlayerCharacter pc, String msgText) { | 
				
			||||
        ChatManager.chatSystemError(pc, msgText); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected void throwbackInfo(PlayerCharacter pc, String msgText) { | 
				
			||||
        ChatManager.chatSystemInfo(pc, msgText); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    /* | 
				
			||||
     * Misc tools/helpers | 
				
			||||
     */ | 
				
			||||
    protected static Building getTargetAsBuilding(PlayerCharacter pc) { | 
				
			||||
        int targetType = pc.getLastTargetType().ordinal(); | 
				
			||||
        int targetID = pc.getLastTargetID(); | 
				
			||||
        if (targetType == GameObjectType.Building.ordinal()) { | 
				
			||||
            Building b = (Building) DbManager | 
				
			||||
                    .getFromCache(GameObjectType.Building, targetID); | 
				
			||||
            if (b == null) { | 
				
			||||
                ChatManager.chatSystemError( | 
				
			||||
                        pc, | 
				
			||||
                        "Command Failed. Could not find building of ID " | 
				
			||||
                        + targetID); | 
				
			||||
                return null; | 
				
			||||
            } | 
				
			||||
            return b; | 
				
			||||
        } else { | 
				
			||||
            return null; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected static Mob getTargetAsMob(PlayerCharacter pc) { | 
				
			||||
        int targetType = pc.getLastTargetType().ordinal(); | 
				
			||||
        int targetID = pc.getLastTargetID(); | 
				
			||||
        if (targetType == GameObjectType.Mob.ordinal()) { | 
				
			||||
            Mob b = Mob.getMob(targetID); | 
				
			||||
            if (b == null) { | 
				
			||||
                ChatManager.chatSystemError(pc, | 
				
			||||
                        "Command Failed. Could not find Mob of ID " + targetID); | 
				
			||||
                return null; | 
				
			||||
            } | 
				
			||||
            return b; | 
				
			||||
        } else { | 
				
			||||
            return null; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
    protected static NPC getTargetAsNPC(PlayerCharacter pc) { | 
				
			||||
        int targetType = pc.getLastTargetType().ordinal(); | 
				
			||||
        int targetID = pc.getLastTargetID(); | 
				
			||||
        if (targetType == GameObjectType.NPC.ordinal()) { | 
				
			||||
            NPC b = NPC.getFromCache(targetID); | 
				
			||||
            if (b == null) { | 
				
			||||
                ChatManager.chatSystemError(pc, | 
				
			||||
                        "Command Failed. Could not find NPC of ID " + targetID); | 
				
			||||
                return null; | 
				
			||||
            } | 
				
			||||
            return b; | 
				
			||||
        } else { | 
				
			||||
            return null; | 
				
			||||
        } | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,127 @@
				@@ -0,0 +1,127 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.Enum.ProtectionState; | 
				
			||||
import engine.InterestManagement.WorldGrid; | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.ChatManager; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.gameManager.ZoneManager; | 
				
			||||
import engine.math.Vector3f; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.server.MBServerStatics; | 
				
			||||
 | 
				
			||||
public class AddBuildingCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public AddBuildingCmd() { | 
				
			||||
        super("addbuilding"); | 
				
			||||
//		super("addbuilding", MBServerStatics.ACCESS_GROUP_DESIGNER_UP, 0, false, true);
 | 
				
			||||
        this.addCmdString("building"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pc, String[] words, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
 | 
				
			||||
		// Arg Count Check
 | 
				
			||||
		if (words.length != 2) { | 
				
			||||
			this.sendUsage(pc); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		int ID; | 
				
			||||
		int rank; | 
				
			||||
                Blueprint blueprint; | 
				
			||||
                 | 
				
			||||
		try { | 
				
			||||
			ID = Integer.parseInt(words[0]); | 
				
			||||
			rank = Integer.parseInt(words[1]); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			throwbackError(pc, "Invalid addBuilding Command. Need Building ID and rank."); | 
				
			||||
			return; // NaN
 | 
				
			||||
		} | 
				
			||||
		if (ID < 1) { | 
				
			||||
			throwbackError(pc, | 
				
			||||
					"Invalid addBuilding Command. Invalid Building ID."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		Vector3f rot = new Vector3f(0.0f, 0.0f, 0.0f); | 
				
			||||
		float w = 1f; | 
				
			||||
		Zone zone = ZoneManager.findSmallestZone(pc.getLoc()); | 
				
			||||
 | 
				
			||||
		if (zone == null) { | 
				
			||||
			throwbackError(pc, "Failed to find zone to place building in."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
               blueprint = Blueprint.getBlueprint(ID); | 
				
			||||
                | 
				
			||||
               if ((blueprint != null) && (rank > blueprint.getMaxRank())) { | 
				
			||||
                   throwbackError(pc, rank + " is not a valid rank for this building"); | 
				
			||||
			return; | 
				
			||||
               } | 
				
			||||
		 | 
				
			||||
		Building likeBuilding = DbManager.BuildingQueries.GET_BUILDING_BY_MESH(ID); | 
				
			||||
                 | 
				
			||||
		if (likeBuilding != null) { | 
				
			||||
			rot = likeBuilding.getRot(); | 
				
			||||
			w = likeBuilding.getw(); | 
				
			||||
		} | 
				
			||||
                 | 
				
			||||
                String buildingName = ""; | 
				
			||||
                int blueprintUUID = 0; | 
				
			||||
                 | 
				
			||||
                Vector3fImmutable localLoc = ZoneManager.worldToLocal(pc.getLoc(), zone); | 
				
			||||
                 | 
				
			||||
                if (localLoc == null) | 
				
			||||
                	return; | 
				
			||||
                 | 
				
			||||
                if (blueprint != null) { | 
				
			||||
                 buildingName = blueprint.getName(); | 
				
			||||
                 blueprintUUID = blueprint.getBlueprintUUID(); | 
				
			||||
                 } | 
				
			||||
                  | 
				
			||||
                Building building = DbManager.BuildingQueries. | 
				
			||||
                        CREATE_BUILDING( | 
				
			||||
                                   zone.getObjectUUID(), 0, buildingName, ID, | 
				
			||||
                                   localLoc, 1.0f, 0, ProtectionState.PROTECTED, 0, rank, | 
				
			||||
                                   null, blueprintUUID, w, rot.y); | 
				
			||||
          | 
				
			||||
 | 
				
			||||
		if (building == null) { | 
				
			||||
			throwbackError(pc, "Failed to add building."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		building.setRot(rot); | 
				
			||||
		building.setw(w); | 
				
			||||
 | 
				
			||||
		building.setObjectTypeMask(MBServerStatics.MASK_BUILDING); | 
				
			||||
	        WorldGrid.addObject(building, pc); | 
				
			||||
		ChatManager.chatSayInfo(pc, | 
				
			||||
				"Building with ID " + building.getObjectUUID() + " added"); | 
				
			||||
 | 
				
			||||
		this.setResult(String.valueOf(building.getObjectUUID())); | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
		return "Creates a building of type 'buildingID' at the location your character is standing."; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
		return "' /addbuilding buildingID rank' || ' /building buildingID rank'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,77 @@
				@@ -0,0 +1,77 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.ChatManager; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.Item; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * @author Eighty | 
				
			||||
 * | 
				
			||||
 */ | 
				
			||||
public class AddGoldCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public AddGoldCmd() { | 
				
			||||
        super("addgold"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pc, String[] words, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
		if (words.length != 1) { | 
				
			||||
			this.sendUsage(pc); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		Item gold = pc.getCharItemManager().getGoldInventory(); | 
				
			||||
		int curAmt; | 
				
			||||
		if (gold == null) | 
				
			||||
			curAmt = 0; | 
				
			||||
		else | 
				
			||||
			curAmt = gold.getNumOfItems(); | 
				
			||||
 | 
				
			||||
		int amt; | 
				
			||||
		try { | 
				
			||||
			amt = Integer.parseInt(words[0]); | 
				
			||||
		} catch (NumberFormatException e) { | 
				
			||||
			throwbackError(pc, "Quantity must be a number, " + words[0] + " is invalid"); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		if (amt < 1 || amt > 10000000) { | 
				
			||||
			throwbackError(pc, "Quantity must be between 1 and 10000000 (10 million)"); | 
				
			||||
			return; | 
				
			||||
		} else if ((curAmt + amt) > 10000000) { | 
				
			||||
			throwbackError(pc, "This would place your inventory over 10,000,000 gold."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		if (!pc.getCharItemManager().addGoldToInventory(amt, true)) { | 
				
			||||
			throwbackError(pc, "Failed to add gold to inventory"); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		ChatManager.chatSayInfo(pc, amt + " gold added to inventory"); | 
				
			||||
		pc.getCharItemManager().updateInventory(); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
        return "adds gold to inventory"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
        return "' /addGold quantity'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,111 @@
				@@ -0,0 +1,111 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.ChatManager; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.gameManager.ZoneManager; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.objects.*; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * @author Eighty | 
				
			||||
 * | 
				
			||||
 */ | 
				
			||||
public class AddMobCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public AddMobCmd() { | 
				
			||||
        super("mob"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pc, String[] words, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
		if (words.length != 1) { | 
				
			||||
			this.sendUsage(pc); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		Zone zone = ZoneManager.findSmallestZone(pc.getLoc()); | 
				
			||||
 | 
				
			||||
		if (words[0].equals("all")){ | 
				
			||||
 | 
				
			||||
			for (AbstractGameObject mobbaseAGO: DbManager.getList(GameObjectType.MobBase)){ | 
				
			||||
				MobBase mb = (MobBase)mobbaseAGO; | 
				
			||||
				int loadID = mb.getObjectUUID(); | 
				
			||||
				Mob mob = Mob.createMob( loadID, Vector3fImmutable.getRandomPointInCircle(pc.getLoc(), 100), | 
				
			||||
						null, true, zone, null,0); | 
				
			||||
				if (mob != null) { | 
				
			||||
					mob.updateDatabase(); | 
				
			||||
					this.setResult(String.valueOf(mob.getDBID())); | 
				
			||||
				} else { | 
				
			||||
					throwbackError(pc, "Failed to create mob of type " + loadID); | 
				
			||||
					Logger.error( "Failed to create mob of type " | 
				
			||||
							+ loadID); | 
				
			||||
				} | 
				
			||||
			} | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		int loadID; | 
				
			||||
		try { | 
				
			||||
			loadID = Integer.parseInt(words[0]); | 
				
			||||
		} catch (NumberFormatException e) { | 
				
			||||
			throwbackError(pc, "Supplied type " + words[0] | 
				
			||||
					+ " failed to parse to an Integer"); | 
				
			||||
			return; | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			throwbackError(pc, | 
				
			||||
					"An unknown exception occurred when trying to use mob command for type " | 
				
			||||
							+ words[0]); | 
				
			||||
			return; // NaN
 | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		if (zone == null) { | 
				
			||||
			throwbackError(pc, "Failed to find zone to place mob in."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		if (zone.isPlayerCity()) { | 
				
			||||
			throwbackError(pc, "Cannot use ./mob on Player cities. Try ./servermob instead."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		Mob mob = Mob.createMob( loadID, pc.getLoc(), | 
				
			||||
				null, true, zone, null,0); | 
				
			||||
		if (mob != null) { | 
				
			||||
			mob.updateDatabase(); | 
				
			||||
			ChatManager.chatSayInfo(pc, | 
				
			||||
					"Mob with ID " + mob.getDBID() + " added"); | 
				
			||||
			this.setResult(String.valueOf(mob.getDBID())); | 
				
			||||
		} else { | 
				
			||||
			throwbackError(pc, "Failed to create mob of type " + loadID); | 
				
			||||
			Logger.error("Failed to create mob of type " | 
				
			||||
					+ loadID); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
        return "Creates a Mob of type 'mobID' at the location your character is standing"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
        return "' /mob mobID'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,98 @@
				@@ -0,0 +1,98 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.gameManager.PowersManager; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.Mob; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.powers.PowersBase; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 *  | 
				
			||||
 * @author Eighty | 
				
			||||
 *  | 
				
			||||
 */ | 
				
			||||
public class AddMobPowerCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public AddMobPowerCmd() { | 
				
			||||
        super("addmobpower"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pcSender, String[] args, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
		 | 
				
			||||
	 | 
				
			||||
		if(args.length != 2){ | 
				
			||||
			this.sendUsage(pcSender); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
	if (target.getObjectType() != GameObjectType.Mob){ | 
				
			||||
		this.throwbackError(pcSender, "Target is not a valid Mob."); | 
				
			||||
		return; | 
				
			||||
	} | 
				
			||||
	Mob mobTarget = (Mob)target; | 
				
			||||
 | 
				
			||||
		 | 
				
			||||
		int rank = 0; | 
				
			||||
		String idString = args[0]; | 
				
			||||
		 | 
				
			||||
		try{ | 
				
			||||
			rank = Integer.valueOf(args[1]); | 
				
			||||
		}catch(Exception e){ | 
				
			||||
			this.throwbackInfo(pcSender, "Failed to Parse an Integer."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		PowersBase pb = PowersManager.getPowerByIDString(idString); | 
				
			||||
		if (pb == null){ | 
				
			||||
			this.throwbackError(pcSender, "not a valid Effect. IDString is Case Sensitive."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		if (!DbManager.MobBaseQueries.ADD_MOBBASE_POWER(mobTarget.getMobBaseID(), pb.getToken(), rank)){ | 
				
			||||
			this.throwbackError(pcSender, "Failed to update Database"); | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		mobTarget.getMobBase().updatePowers(); | 
				
			||||
		 | 
				
			||||
		this.throwbackInfo(pcSender, "Successfuly added Power " + pb.getIDString() + " to Mobbase with UID " + mobTarget.getMobBaseID()); | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
        return "' /addmobpower poweridstring rank"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
        return "Temporarily add visual effects to Character"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,98 @@
				@@ -0,0 +1,98 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.Mob; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.objects.RuneBase; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 *  | 
				
			||||
 * @author Eighty | 
				
			||||
 *  | 
				
			||||
 */ | 
				
			||||
public class AddMobRuneCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public AddMobRuneCmd() { | 
				
			||||
        super("addmobrune"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pcSender, String[] args, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		if(args.length != 1){ | 
				
			||||
			this.sendUsage(pcSender); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
	if (target.getObjectType() != GameObjectType.Mob){ | 
				
			||||
		this.throwbackError(pcSender, "Target is not a valid Mob."); | 
				
			||||
		return; | 
				
			||||
	} | 
				
			||||
	Mob mobTarget = (Mob)target; | 
				
			||||
 | 
				
			||||
		 | 
				
			||||
		int runeID = 0; | 
				
			||||
		try{ | 
				
			||||
			runeID = Integer.valueOf(args[0]); | 
				
			||||
		}catch(Exception e){ | 
				
			||||
			this.throwbackInfo(pcSender, "Failed to Parse an Integer."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		RuneBase rune = RuneBase.getRuneBase(runeID); | 
				
			||||
		if (rune == null){ | 
				
			||||
			this.throwbackError(pcSender, "Invalid Rune ID"); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		if (!DbManager.MobBaseQueries.ADD_MOBBASE_RUNE(mobTarget.getMobBaseID(), runeID)){ | 
				
			||||
			this.throwbackError(pcSender, "Failed to update Database"); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		mobTarget.getMobBase().updateRunes(); | 
				
			||||
		 | 
				
			||||
		this.throwbackInfo(pcSender, "Successfuly added rune  " + rune.getName() + " to Mobbase with UID " + mobTarget.getMobBaseID()); | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
        return "' /visualeffect visualeffectID"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
        return "Temporarily add visual effects to Character"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,111 @@
				@@ -0,0 +1,111 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.InterestManagement.WorldGrid; | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.BuildingManager; | 
				
			||||
import engine.gameManager.ChatManager; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.gameManager.ZoneManager; | 
				
			||||
import engine.objects.*; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * @author Eighty | 
				
			||||
 * | 
				
			||||
 */ | 
				
			||||
public class AddNPCCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public AddNPCCmd() { | 
				
			||||
        super("npc"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pc, String[] words, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
		int contractID; | 
				
			||||
		String name = ""; | 
				
			||||
		int level = 0; | 
				
			||||
 | 
				
			||||
		if (words.length < 2) { | 
				
			||||
			this.sendUsage(pc); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		try { | 
				
			||||
			contractID = Integer.parseInt(words[0]); | 
				
			||||
			level = Integer.parseInt(words[1]); | 
				
			||||
 | 
				
			||||
			for (int i = 2; i < words.length; i++) { | 
				
			||||
				name += words[i]; | 
				
			||||
				if (i + 1 < words.length) | 
				
			||||
					name += ""; | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} catch (NumberFormatException e) { | 
				
			||||
			throwbackError(pc, | 
				
			||||
					"Failed to parse supplied contractID or level to an Integer."); | 
				
			||||
			return; // NaN
 | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		Contract contract = DbManager.ContractQueries.GET_CONTRACT(contractID); | 
				
			||||
 | 
				
			||||
		if (contract == null || level < 1 || level > 75) { | 
				
			||||
			throwbackError(pc, | 
				
			||||
					"Invalid addNPC Command. Need contract ID, and level"); | 
				
			||||
			return; // NaN
 | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		// Pick a random name
 | 
				
			||||
		if (name.isEmpty()) | 
				
			||||
			name = NPC.getPirateName(contract.getMobbaseID()); | 
				
			||||
 | 
				
			||||
		Zone zone = ZoneManager.findSmallestZone(pc.getLoc()); | 
				
			||||
 | 
				
			||||
		if (zone == null) { | 
				
			||||
			throwbackError(pc, "Failed to find zone to place npc in."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		if (target != null) | 
				
			||||
			if (target.getObjectType() == GameObjectType.Building){ | 
				
			||||
				Building parentBuilding = (Building)target; | 
				
			||||
				BuildingManager.addHirelingForWorld(parentBuilding, pc, parentBuilding.getLoc(), parentBuilding.getParentZone(), contract, level); | 
				
			||||
				return; | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		NPC npc = NPC.createNPC(name, contractID, | 
				
			||||
				pc.getLoc(), null, true, zone, (short)level, true, null); | 
				
			||||
 | 
				
			||||
		if (npc != null) { | 
				
			||||
			WorldGrid.addObject(npc, pc); | 
				
			||||
			ChatManager.chatSayInfo(pc, | 
				
			||||
					"NPC with ID " + npc.getDBID() + " added"); | 
				
			||||
			this.setResult(String.valueOf(npc.getDBID())); | 
				
			||||
		} else { | 
				
			||||
			throwbackError(pc, "Failed to create npc of contract type " | 
				
			||||
					+ contractID); | 
				
			||||
			Logger.error( | 
				
			||||
					"Failed to create npc of contract type " + contractID); | 
				
			||||
		} | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
		return "Creates an NPC of type 'npcID' at the location your character is standing"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
		return "' /npc npcID level name'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,158 @@
				@@ -0,0 +1,158 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.Enum.PowerActionType; | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.ChatManager; | 
				
			||||
import engine.gameManager.PowersManager; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.powers.ActionsBase; | 
				
			||||
import engine.powers.PowersBase; | 
				
			||||
import engine.powers.effectmodifiers.AbstractEffectModifier; | 
				
			||||
import engine.util.ThreadUtils; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
import java.util.HashMap; | 
				
			||||
import java.util.HashSet; | 
				
			||||
 | 
				
			||||
public class ApplyBonusCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public ApplyBonusCmd() { | 
				
			||||
		super("applybonus"); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pcSender, String[] words, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
		 | 
				
			||||
		String action = words[0]; | 
				
			||||
		 | 
				
			||||
		PowerActionType actionType = null; | 
				
			||||
		 | 
				
			||||
		HashMap<String,HashSet<String>> appliedMods = new HashMap<>(); | 
				
			||||
		 | 
				
			||||
		try{ | 
				
			||||
			 | 
				
			||||
			if (action.equals("all") == false) | 
				
			||||
		for (PowerActionType powerActionType : PowerActionType.values()){ | 
				
			||||
			if (powerActionType.name().equalsIgnoreCase(action) == false) | 
				
			||||
				continue; | 
				
			||||
			actionType = powerActionType; | 
				
			||||
			break; | 
				
			||||
		} | 
				
			||||
			 | 
				
			||||
		}catch(Exception e){ | 
				
			||||
			this.throwbackError(pcSender, "Invalid power Action type for " + action); | 
				
			||||
			this.throwbackInfo(pcSender, "Valid Types : " + this.getActionTypes()); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		if (action.equals("all") == false) | 
				
			||||
		if (actionType == null){ | 
				
			||||
			this.throwbackError(pcSender, "Invalid power Action type for " + action); | 
				
			||||
			this.throwbackInfo(pcSender, "Valid Types : " + this.getActionTypes()); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		 | 
				
			||||
		for (PowersBase pb : PowersManager.powersBaseByIDString.values()){ | 
				
			||||
			if (pb.getActions() == null || pb.getActions().isEmpty()) | 
				
			||||
				continue; | 
				
			||||
			 | 
				
			||||
			for (ActionsBase ab: pb.getActions()){ | 
				
			||||
				if (ab.getPowerAction() == null) | 
				
			||||
					continue; | 
				
			||||
				if (action.equals("all") == false) | 
				
			||||
				if (ab.getPowerAction().getType().equalsIgnoreCase(action) == false) | 
				
			||||
					continue; | 
				
			||||
				String effect1 = ""; | 
				
			||||
				String effect2 = ""; | 
				
			||||
				ChatManager.chatSystemInfo(pcSender,"Applying Power " + pb.getName() + " : " +pb.getDescription()); | 
				
			||||
				if (ab.getPowerAction().getEffectsBase() == null){ | 
				
			||||
					 | 
				
			||||
					try { | 
				
			||||
						PowersManager.runPowerAction(pcSender, pcSender, pcSender.getLoc(), ab, 1, pb); | 
				
			||||
					} catch (Exception e) { | 
				
			||||
						// TODO Auto-generated catch block
 | 
				
			||||
						e.printStackTrace(); | 
				
			||||
					} | 
				
			||||
					ThreadUtils.sleep(500); | 
				
			||||
					continue; | 
				
			||||
				} | 
				
			||||
 | 
				
			||||
			 | 
				
			||||
					if (ab.getPowerAction().getEffectsBase().getModifiers() == null || ab.getPowerAction().getEffectsBase().getModifiers().isEmpty()){ | 
				
			||||
						try { | 
				
			||||
							PowersManager.runPowerAction(pcSender, pcSender, pcSender.getLoc(), ab, 1, pb); | 
				
			||||
						} catch (Exception e) { | 
				
			||||
							// TODO Auto-generated catch block
 | 
				
			||||
							e.printStackTrace(); | 
				
			||||
						} | 
				
			||||
						continue; | 
				
			||||
					} | 
				
			||||
						 | 
				
			||||
					boolean run = true; | 
				
			||||
					for (AbstractEffectModifier mod : ab.getPowerAction().getEffectsBase().getModifiers()){ | 
				
			||||
						if (appliedMods.containsKey(mod.modType.name()) == false){ | 
				
			||||
							appliedMods.put(mod.modType.name(), new HashSet<>()); | 
				
			||||
						} | 
				
			||||
						 | 
				
			||||
//						if (appliedMods.get(mod.modType.name()).contains(mod.sourceType.name())){
 | 
				
			||||
//							continue;
 | 
				
			||||
//						}
 | 
				
			||||
						 | 
				
			||||
						appliedMods.get(mod.modType.name()).add(mod.sourceType.name()); | 
				
			||||
						try{ | 
				
			||||
							try { | 
				
			||||
								PowersManager.runPowerAction(pcSender, pcSender, pcSender.getLoc(), ab, 1, pb); | 
				
			||||
							} catch (Exception e) { | 
				
			||||
								// TODO Auto-generated catch block
 | 
				
			||||
								e.printStackTrace(); | 
				
			||||
							} | 
				
			||||
	 | 
				
			||||
						}catch(Exception e){ | 
				
			||||
							Logger.error(e); | 
				
			||||
						} | 
				
			||||
						break; | 
				
			||||
						 | 
				
			||||
							 | 
				
			||||
					 | 
				
			||||
					 | 
				
			||||
				} | 
				
			||||
			 | 
				
			||||
			} | 
				
			||||
		}	 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
		return "' /bounds'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
		return "Audits all the mobs in a zone."; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
	 | 
				
			||||
	private String getActionTypes(){ | 
				
			||||
		String output = ""; | 
				
			||||
		 | 
				
			||||
		for (PowerActionType actionType : PowerActionType.values()){ | 
				
			||||
			output += actionType.name() + " | "; | 
				
			||||
			 | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		return output.substring(0, output.length() -3); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,149 @@
				@@ -0,0 +1,149 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.ChatManager; | 
				
			||||
import engine.gameManager.PowersManager; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.objects.AbstractCharacter; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.powers.PowersBase; | 
				
			||||
 | 
				
			||||
import java.util.ArrayList; | 
				
			||||
 | 
				
			||||
/** | 
				
			||||
 * | 
				
			||||
 * @author Eighty | 
				
			||||
 * | 
				
			||||
 */ | 
				
			||||
public class ApplyStatModCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public ApplyStatModCmd() { | 
				
			||||
        super("applystatmod"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	private static int cnt = 0; | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pcSender, String[] args, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
		if(args.length < 1) { | 
				
			||||
			//		if(args.length < 2) {
 | 
				
			||||
			this.sendUsage(pcSender); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		if(!(target instanceof AbstractCharacter)) { | 
				
			||||
			this.sendHelp(pcSender); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
        this.setTarget(pcSender); //for logging
 | 
				
			||||
 | 
				
			||||
		int spellID; | 
				
			||||
		int powerAction = 0; | 
				
			||||
		if (args[0].toLowerCase().contains("all")){ | 
				
			||||
 | 
				
			||||
			int amount = 0; | 
				
			||||
			if (args.length == 1) { | 
				
			||||
				amount = ApplyStatModCmd.cnt; | 
				
			||||
				ApplyStatModCmd.cnt++; | 
				
			||||
			} else { | 
				
			||||
				amount = Integer.valueOf(args[1]); | 
				
			||||
				ApplyStatModCmd.cnt = amount+1; | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			ArrayList<PowersBase> pbList = new ArrayList<>(); | 
				
			||||
			pbList.add(PowersManager.getPowerByToken(429047968)); | 
				
			||||
			pbList.add(PowersManager.getPowerByToken(429768864)); | 
				
			||||
			pbList.add(PowersManager.getPowerByToken(428458144)); | 
				
			||||
			pbList.add(PowersManager.getPowerByToken(428677994)); | 
				
			||||
			pbList.add(PowersManager.getPowerByToken(431874079)); | 
				
			||||
			pbList.add(PowersManager.getPowerByToken(431081336)); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			for (PowersBase pb:pbList){ | 
				
			||||
				if(amount <= 0) { | 
				
			||||
					if (pb.getToken() ==428677994) | 
				
			||||
						powerAction = 1; | 
				
			||||
					PowersManager.removeEffect(pcSender, pb.getActions().get(powerAction), false, false); | 
				
			||||
					continue; | 
				
			||||
				} else if(amount > 9999 || amount < 21) { | 
				
			||||
					ChatManager.chatSystemInfo(pcSender, "Amount must be between 21 and 9999 inclusive."); | 
				
			||||
					return; | 
				
			||||
				} | 
				
			||||
 | 
				
			||||
				if (pb.getToken() ==428677994){ | 
				
			||||
					PowersManager.removeEffect(pcSender, pb.getActions().get(powerAction), false, false); | 
				
			||||
					PowersManager.runPowerAction(pcSender, pcSender, Vector3fImmutable.ZERO, pb.getActions().get(powerAction), amount - 20, pb); | 
				
			||||
				} | 
				
			||||
				if (pb.getToken() ==428677994) | 
				
			||||
					powerAction = 1; | 
				
			||||
				PowersManager.removeEffect(pcSender, pb.getActions().get(powerAction), false, false); | 
				
			||||
				PowersManager.runPowerAction(pcSender, pcSender, Vector3fImmutable.ZERO, pb.getActions().get(powerAction), amount - 20, pb); | 
				
			||||
			} | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		if(args[0].toLowerCase().contains("con")) { | 
				
			||||
			spellID = 429047968;	//Blessing of Health
 | 
				
			||||
		} else if(args[0].toLowerCase().contains("str")) { | 
				
			||||
			spellID = 429768864;	//Blessing of Might
 | 
				
			||||
		} else if(args[0].toLowerCase().contains("dex")) { | 
				
			||||
			spellID = 428458144;	//Blessing of Dexterity
 | 
				
			||||
		} else if(args[0].toLowerCase().contains("int")) { | 
				
			||||
			spellID = 428677994;	//Bard Spi - TODO
 | 
				
			||||
			powerAction = 1; | 
				
			||||
		} else if(args[0].toLowerCase().contains("spi")) { | 
				
			||||
			spellID = 428677994;	//Bard Spi
 | 
				
			||||
		} else{ | 
				
			||||
			ChatManager.chatSystemInfo(pcSender, "No valid stat found."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		PowersBase pb = PowersManager.getPowerByToken(spellID); | 
				
			||||
 | 
				
			||||
		int amount = 0; | 
				
			||||
		if (args.length == 1) { | 
				
			||||
			amount = ApplyStatModCmd.cnt; | 
				
			||||
			ApplyStatModCmd.cnt++; | 
				
			||||
		} else { | 
				
			||||
			amount = Integer.valueOf(args[1]); | 
				
			||||
			ApplyStatModCmd.cnt = amount+1; | 
				
			||||
		} | 
				
			||||
		//		int amount = Integer.valueOf(args[1]);
 | 
				
			||||
		if(amount <= 0) { | 
				
			||||
			PowersManager.removeEffect(pcSender, pb.getActions().get(powerAction), false, false); | 
				
			||||
			return; | 
				
			||||
		} else if(amount > 9999 || amount < 21) { | 
				
			||||
			ChatManager.chatSystemInfo(pcSender, "Amount must be between 21 and 9999 inclusive."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		PowersManager.removeEffect(pcSender, pb.getActions().get(powerAction), false, false); | 
				
			||||
		PowersManager.runPowerAction(pcSender, pcSender, Vector3fImmutable.ZERO, pb.getActions().get(powerAction), amount - 20, pb); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
        return "' /applystatmod <stat> [trains]'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
        return "You must be targeting a player!"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,130 @@
				@@ -0,0 +1,130 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.Enum.ModType; | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.PowersManager; | 
				
			||||
import engine.net.ItemProductionManager; | 
				
			||||
import engine.objects.*; | 
				
			||||
import engine.powers.effectmodifiers.AbstractEffectModifier; | 
				
			||||
import engine.powers.poweractions.AbstractPowerAction; | 
				
			||||
import org.pmw.tinylog.Logger; | 
				
			||||
 | 
				
			||||
public class AuditFailedItemsCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public AuditFailedItemsCmd() { | 
				
			||||
		super("faileditems"); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pcSender, String[] words, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
	 | 
				
			||||
		 | 
				
			||||
      	    | 
				
			||||
      	   if (ItemProductionManager.FailedItems.isEmpty()) | 
				
			||||
      		   return; | 
				
			||||
      	    | 
				
			||||
      	   Logger.info("Auditing Item production Failed Items"); | 
				
			||||
      	    | 
				
			||||
      	   String newLine = "\r\n"; | 
				
			||||
  		   String auditFailedItem = "Failed Item Name | Prefix | Suffix | NPC | Contract  | Player | "; | 
				
			||||
  		    | 
				
			||||
      	   for (ProducedItem failedItem: ItemProductionManager.FailedItems){ | 
				
			||||
      		    | 
				
			||||
      		   String npcName = ""; | 
				
			||||
      		   String playerName =""; | 
				
			||||
      		   String contractName = ""; | 
				
			||||
      		    | 
				
			||||
      		   String prefix = ""; | 
				
			||||
      		   String suffix = ""; | 
				
			||||
      		   String itemName = ""; | 
				
			||||
      		   NPC npc = NPC.getFromCache(failedItem.getNpcUID()); | 
				
			||||
      		    | 
				
			||||
      		   if (npc == null){ | 
				
			||||
      			   npcName = "null"; | 
				
			||||
      			   contractName = "null"; | 
				
			||||
      		   }else{ | 
				
			||||
      			   npcName = npc.getName(); | 
				
			||||
      			   if (npc.getContract() != null) | 
				
			||||
      				   contractName = npc.getContract().getName(); | 
				
			||||
      		   } | 
				
			||||
      		    | 
				
			||||
      		   PlayerCharacter roller = PlayerCharacter.getFromCache(failedItem.getPlayerID()); | 
				
			||||
      		    | 
				
			||||
      		   if (roller == null) | 
				
			||||
      			   playerName = "null"; | 
				
			||||
      		   else | 
				
			||||
      			   playerName = roller.getName(); | 
				
			||||
      		    | 
				
			||||
      		   ItemBase ib = ItemBase.getItemBase(failedItem.getItemBaseID()); | 
				
			||||
      		    | 
				
			||||
      		   if (ib != null){ | 
				
			||||
      			   itemName = ib.getName(); | 
				
			||||
      		   } | 
				
			||||
      		    | 
				
			||||
      		   if (failedItem.isRandom() == false){ | 
				
			||||
      			   if (failedItem.getPrefix().isEmpty() == false){ | 
				
			||||
       				  AbstractPowerAction pa = PowersManager.getPowerActionByIDString(failedItem.getPrefix()); | 
				
			||||
       				  if (pa != null){ | 
				
			||||
       					  for (AbstractEffectModifier aem : pa.getEffectsBase().getModifiers()){ | 
				
			||||
       						  if (aem.modType.equals(ModType.ItemName)){ | 
				
			||||
       							  prefix = aem.getString1(); | 
				
			||||
       							  break; | 
				
			||||
       						  } | 
				
			||||
       					  } | 
				
			||||
       				  } | 
				
			||||
       				   | 
				
			||||
       			   } | 
				
			||||
      			    | 
				
			||||
      			   if (failedItem.getSuffix().isEmpty() == false){ | 
				
			||||
       				  AbstractPowerAction pa = PowersManager.getPowerActionByIDString(failedItem.getSuffix()); | 
				
			||||
       				  if (pa != null){ | 
				
			||||
       					  for (AbstractEffectModifier aem : pa.getEffectsBase().getModifiers()){ | 
				
			||||
       						  if (aem.modType.equals(ModType.ItemName)){ | 
				
			||||
       							  suffix = aem.getString1(); | 
				
			||||
       							  break; | 
				
			||||
       						  } | 
				
			||||
       					  } | 
				
			||||
       				  } | 
				
			||||
       				   | 
				
			||||
       			   } | 
				
			||||
      			    | 
				
			||||
      		   }else{ | 
				
			||||
      			   prefix = "random"; | 
				
			||||
      		   } | 
				
			||||
      		    | 
				
			||||
      			    | 
				
			||||
      		    | 
				
			||||
      		    | 
				
			||||
      		   auditFailedItem += newLine; | 
				
			||||
      		   auditFailedItem += itemName + " | "+prefix + " | "+suffix + " | "+ failedItem.getNpcUID() + ":" +npcName + " | "+contractName + " | "+failedItem.getPlayerID() + ":" +playerName; | 
				
			||||
 | 
				
			||||
      	   } | 
				
			||||
      	   Logger.info(auditFailedItem); | 
				
			||||
      	 ItemProductionManager.FailedItems.clear(); | 
				
			||||
          | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
		return "' /bounds'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
		return "Audits all the mobs in a zone."; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,71 @@
				@@ -0,0 +1,71 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.InterestManagement.HeightMap; | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.ZoneManager; | 
				
			||||
import engine.math.Vector2f; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.objects.Zone; | 
				
			||||
 | 
				
			||||
public class AuditHeightMapCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public AuditHeightMapCmd() { | 
				
			||||
        super("auditheightmap"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pcSender, String[] words, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
 | 
				
			||||
		int count = Integer.parseInt(words[0]); | 
				
			||||
		long start = System.currentTimeMillis(); | 
				
			||||
		for (int i = 0; i<count;i++){ | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			Zone currentZone = ZoneManager.findSmallestZone(pcSender.getLoc()); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
			Vector3fImmutable currentLoc = Vector3fImmutable.getRandomPointInCircle(currentZone.getLoc(), currentZone.getBounds().getHalfExtents().x < currentZone.getBounds().getHalfExtents().y ? currentZone.getBounds().getHalfExtents().x : currentZone.getBounds().getHalfExtents().y ); | 
				
			||||
 | 
				
			||||
			Vector2f zoneLoc = ZoneManager.worldToZoneSpace(currentLoc, currentZone); | 
				
			||||
 | 
				
			||||
			if (currentZone != null && currentZone.getHeightMap() != null){ | 
				
			||||
				float altitude = currentZone.getHeightMap().getInterpolatedTerrainHeight(zoneLoc); | 
				
			||||
				float outsetAltitude = HeightMap.getOutsetHeight(altitude, currentZone, pcSender.getLoc()); | 
				
			||||
			} | 
				
			||||
 | 
				
			||||
		} | 
				
			||||
		long end = System.currentTimeMillis(); | 
				
			||||
 | 
				
			||||
		long delta = end - start; | 
				
			||||
 | 
				
			||||
		this.throwbackInfo(pcSender, "Audit Heightmap took " + delta + " ms to run " + count + " times!"); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
		return "' /auditmobs [zone.UUID]'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
		return "Audits all the mobs in a zone."; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,106 @@
				@@ -0,0 +1,106 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.ZoneManager; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.objects.Zone; | 
				
			||||
 | 
				
			||||
public class AuditMobsCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public AuditMobsCmd() { | 
				
			||||
        super("auditmobs"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pcSender, String[] words, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
		if (pcSender == null) return; | 
				
			||||
 | 
				
			||||
		//get Zone to check mobs against
 | 
				
			||||
 | 
				
			||||
		Zone zone; | 
				
			||||
 | 
				
			||||
		if (words.length == 2){ | 
				
			||||
			if (words[0].equals("all")){ | 
				
			||||
				int plusplus = 0; | 
				
			||||
				int count = Integer.parseInt(words[1]); | 
				
			||||
				for (Zone zoneMicro: ZoneManager.getAllZones()){ | 
				
			||||
					int size = zoneMicro.zoneMobSet.size(); | 
				
			||||
 | 
				
			||||
					if (size >= count){ | 
				
			||||
						plusplus++; | 
				
			||||
						throwbackInfo(pcSender, zoneMicro.getName() + " at location  " + zoneMicro.getLoc().toString()  + " has " + size + " mobs. "); | 
				
			||||
						System.out.println(zoneMicro.getName() + " at location  " + zoneMicro.getLoc().toString()  + " has " + size + " mobs. "); | 
				
			||||
					} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
				} | 
				
			||||
				throwbackInfo(pcSender," there are " +plusplus + " zones with at least " + count + " mobs in each."); | 
				
			||||
			} | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		if (words.length > 1) { | 
				
			||||
			this.sendUsage(pcSender); | 
				
			||||
			return; | 
				
			||||
		} else if (words.length == 1) { | 
				
			||||
			int uuid; | 
				
			||||
			try { | 
				
			||||
				uuid = Integer.parseInt(words[0]); | 
				
			||||
				zone = ZoneManager.getZoneByUUID(uuid); | 
				
			||||
			} catch (NumberFormatException e) { | 
				
			||||
				zone = ZoneManager.findSmallestZone(pcSender.getLoc()); | 
				
			||||
			} | 
				
			||||
		} else | 
				
			||||
			zone = ZoneManager.findSmallestZone(pcSender.getLoc()); | 
				
			||||
 | 
				
			||||
		if (zone == null) { | 
				
			||||
			throwbackError(pcSender, "Unable to find the zone"); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		//get list of mobs for zone
 | 
				
			||||
 | 
				
			||||
		if (zone.zoneMobSet.isEmpty()) { | 
				
			||||
			throwbackError(pcSender, "No mobs found for this zone."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		//	ConcurrentHashMap<Integer, Mob> spawnMap = Mob.getSpawnMap();
 | 
				
			||||
		//ConcurrentHashMap<Mob, Long> respawnMap = Mob.getRespawnMap();
 | 
				
			||||
		//		ConcurrentHashMap<Mob, Long> despawnMap = Mob.getDespawnMap();
 | 
				
			||||
 | 
				
			||||
		throwbackInfo(pcSender, zone.getName() + ", numMobs: " + zone.zoneMobSet.size()); | 
				
			||||
		throwbackInfo(pcSender, "UUID, dbID, inRespawnMap, isAlive, activeAI, Loc"); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		//mob not found in spawn map, check respawn
 | 
				
			||||
		boolean inRespawn = false; | 
				
			||||
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
		return "' /auditmobs [zone.UUID]'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
		return "Audits all the mobs in a zone."; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,77 @@
				@@ -0,0 +1,77 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.Enum.GameObjectType; | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.Building; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
 | 
				
			||||
public class BoundsCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public BoundsCmd() { | 
				
			||||
        super("bounds"); | 
				
			||||
    } | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pcSender, String[] words, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
		if (target == null || !target.getObjectType().equals(GameObjectType.Building)){ | 
				
			||||
			this.throwbackError(pcSender, "No Building Selected"); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		 | 
				
			||||
		Building building = (Building)target; | 
				
			||||
		 | 
				
			||||
		if (building.getBounds() == null){ | 
				
			||||
			this.throwbackInfo(pcSender, "No valid Bounds for building UUID " + building.getObjectUUID()); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
		float topLeftX = building.getLoc().x - building.getBounds().getHalfExtents().x; | 
				
			||||
		float topLeftY = building.getLoc().z - building.getBounds().getHalfExtents().y; | 
				
			||||
		 | 
				
			||||
		float topRightX = building.getLoc().x + building.getBounds().getHalfExtents().x; | 
				
			||||
		float topRightY = building.getLoc().z - building.getBounds().getHalfExtents().y; | 
				
			||||
		 | 
				
			||||
		float bottomLeftX = building.getLoc().x - building.getBounds().getHalfExtents().x; | 
				
			||||
		float bottomLeftY = building.getLoc().z + building.getBounds().getHalfExtents().y; | 
				
			||||
		 | 
				
			||||
		float bottomRightX = building.getLoc().x + building.getBounds().getHalfExtents().x; | 
				
			||||
		float bottomRightY = building.getLoc().z + building.getBounds().getHalfExtents().y; | 
				
			||||
		 | 
				
			||||
		String newLine = "\r\n "; | 
				
			||||
		 | 
				
			||||
		String output = "Bounds Information for Building UUID " + building.getObjectUUID(); | 
				
			||||
		output += newLine; | 
				
			||||
		 | 
				
			||||
		output+= "Top Left : " + topLeftX + " , " + topLeftY + newLine; | 
				
			||||
		output+= "Top Right : " + topRightX + " , " + topRightY + newLine; | 
				
			||||
		output+= "Bottom Left : " + bottomLeftX + " , " + bottomLeftY + newLine; | 
				
			||||
		output+= "Bottom Right : " + bottomRightX + " , " + bottomRightY + newLine; | 
				
			||||
		 | 
				
			||||
		this.throwbackInfo(pcSender, output); | 
				
			||||
		 | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
		return "' /bounds'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
		return "Audits all the mobs in a zone."; | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
@ -0,0 +1,114 @@
				@@ -0,0 +1,114 @@
					 | 
				
			||||
// • ▌ ▄ ·.  ▄▄▄·  ▄▄ • ▪   ▄▄· ▄▄▄▄·  ▄▄▄·  ▐▄▄▄  ▄▄▄ .
 | 
				
			||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
 | 
				
			||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
 | 
				
			||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
 | 
				
			||||
// ▀▀  █▪▀▀▀ ▀  ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀  ▀  ▀ ▀▀  █▪ ▀▀▀
 | 
				
			||||
//      Magicbane Emulator Project © 2013 - 2022
 | 
				
			||||
//                www.magicbane.com
 | 
				
			||||
 | 
				
			||||
 | 
				
			||||
package engine.devcmd.cmds; | 
				
			||||
 | 
				
			||||
import engine.devcmd.AbstractDevCmd; | 
				
			||||
import engine.gameManager.DbManager; | 
				
			||||
import engine.gameManager.SessionManager; | 
				
			||||
import engine.math.Vector3fImmutable; | 
				
			||||
import engine.objects.AbstractGameObject; | 
				
			||||
import engine.objects.PlayerCharacter; | 
				
			||||
import engine.util.MiscUtils; | 
				
			||||
 | 
				
			||||
public class ChangeNameCmd extends AbstractDevCmd { | 
				
			||||
 | 
				
			||||
	public ChangeNameCmd() { | 
				
			||||
		super("changename"); | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected void _doCmd(PlayerCharacter pc, String[] words, | 
				
			||||
			AbstractGameObject target) { | 
				
			||||
		Vector3fImmutable loc = null; | 
				
			||||
 | 
				
			||||
		// Arg Count Check
 | 
				
			||||
		if (words.length < 2) { | 
				
			||||
			this.sendUsage(pc); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		String oldFirst = words[0]; | 
				
			||||
		String newFirst = words[1]; | 
				
			||||
		String newLast = ""; | 
				
			||||
		if (words.length > 2) { | 
				
			||||
			newLast = words[2]; | 
				
			||||
			for (int i=3; i<words.length; i++) | 
				
			||||
				newLast += ' ' + words[i]; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		//verify new name length
 | 
				
			||||
		if (newFirst.length() < 3) { | 
				
			||||
			this.throwbackError(pc, "Error: First name is incorrect length. Must be between 3 and 15 characters"); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		//verify old name length
 | 
				
			||||
		if (newLast.length() > 50) { | 
				
			||||
			this.throwbackError(pc, "Error: Last name is incorrect length. Must be no more than 50 characters"); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		// Check if firstname is valid
 | 
				
			||||
		if (MiscUtils.checkIfFirstNameInvalid(newFirst)) { | 
				
			||||
			this.throwbackError(pc, "Error: First name is not allowed"); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
 | 
				
			||||
		//get the world ID we're modifying for
 | 
				
			||||
 | 
				
			||||
		//test if first name is unique, unless new and old first name are equal.
 | 
				
			||||
		if (!(oldFirst.equals(newFirst))) { | 
				
			||||
			if (!DbManager.PlayerCharacterQueries.IS_CHARACTER_NAME_UNIQUE(newFirst)) { | 
				
			||||
				this.throwbackError(pc, "Error: First name is not unique."); | 
				
			||||
				return; | 
				
			||||
			} | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		//tests passed, update name in database
 | 
				
			||||
		if (!DbManager.PlayerCharacterQueries.UPDATE_NAME(oldFirst, newFirst, newLast)) { | 
				
			||||
			this.throwbackError(pc, "Error: Database failed to update the name."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		//Finally update player ingame
 | 
				
			||||
		PlayerCharacter pcTar = null; | 
				
			||||
		try { | 
				
			||||
			pcTar = SessionManager | 
				
			||||
					.getPlayerCharacterByLowerCaseName(words[0]); | 
				
			||||
			pcTar.setFirstName(newFirst); | 
				
			||||
			pcTar.setLastName(newLast); | 
				
			||||
			this.setTarget(pcTar); //for logging
 | 
				
			||||
 | 
				
			||||
			//specify if last name is ascii characters only
 | 
				
			||||
			String lastAscii =  newLast.replaceAll("[^\\p{ASCII}]", ""); | 
				
			||||
			pcTar.setAsciiLastName(lastAscii.equals(newLast)); | 
				
			||||
		} catch (Exception e) { | 
				
			||||
			this.throwbackError(pc, "Database was updated but ingame character failed to update."); | 
				
			||||
			return; | 
				
			||||
		} | 
				
			||||
 | 
				
			||||
		String out = oldFirst + " was changed to " + newFirst + (newLast.isEmpty() ? "." : (' ' + newLast + '.')); | 
				
			||||
		this.throwbackInfo(pc, out); | 
				
			||||
 | 
				
			||||
 | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getHelpString() { | 
				
			||||
		return "Changes the name of a player"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
	@Override | 
				
			||||
	protected String _getUsageString() { | 
				
			||||
		return "'./changename oldFirstName newFirstName newLastName'"; | 
				
			||||
	} | 
				
			||||
 | 
				
			||||
} | 
				
			||||
Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue