Browse Source

Initial Repository Push

master
MagicBot 3 years ago
parent
commit
bbfdde57a3
  1. 41
      src/discord/ChatChannel.java
  2. 380
      src/discord/Database.java
  3. 25
      src/discord/DiscordAccount.java
  4. 372
      src/discord/MagicBot.java
  5. 106
      src/discord/RobotSpeak.java
  6. 78
      src/discord/handlers/AccountInfoRequest.java
  7. 55
      src/discord/handlers/AnnounceChannelHandler.java
  8. 102
      src/discord/handlers/BanToggleHandler.java
  9. 44
      src/discord/handlers/ChangeLogHandler.java
  10. 51
      src/discord/handlers/FlashHandler.java
  11. 56
      src/discord/handlers/ForToFixChannelHandler.java
  12. 56
      src/discord/handlers/GeneralChannelHandler.java
  13. 62
      src/discord/handlers/LogsRequestHandler.java
  14. 77
      src/discord/handlers/LookupRequestHandler.java
  15. 113
      src/discord/handlers/PasswordChangeHandler.java
  16. 55
      src/discord/handlers/PoliticalChannelHandler.java
  17. 56
      src/discord/handlers/RecruitChannelHandler.java
  18. 126
      src/discord/handlers/RegisterAccountHandler.java
  19. 30
      src/discord/handlers/RulesRequestHandler.java
  20. 63
      src/discord/handlers/ServerRequestHandler.java
  21. 51
      src/discord/handlers/SetAvailHandler.java
  22. 42
      src/discord/handlers/StatusRequestHandler.java
  23. 75
      src/discord/handlers/TrashRequestHandler.java
  24. 2943
      src/engine/Enum.java
  25. 1099
      src/engine/InterestManagement/HeightMap.java
  26. 554
      src/engine/InterestManagement/InterestManager.java
  27. 102
      src/engine/InterestManagement/RealmMap.java
  28. 312
      src/engine/InterestManagement/WorldGrid.java
  29. 1769
      src/engine/ai/MobileFSM.java
  30. 104
      src/engine/ai/MobileFSMManager.java
  31. 413
      src/engine/ai/utilities/CombatUtilities.java
  32. 303
      src/engine/ai/utilities/MovementUtilities.java
  33. 15
      src/engine/ai/utilities/PowerUtilities.java
  34. 174
      src/engine/core/ControlledRunnable.java
  35. 383
      src/engine/db/archive/BaneRecord.java
  36. 284
      src/engine/db/archive/CharacterRecord.java
  37. 161
      src/engine/db/archive/CityRecord.java
  38. 23
      src/engine/db/archive/DataRecord.java
  39. 324
      src/engine/db/archive/DataWarehouse.java
  40. 215
      src/engine/db/archive/GuildRecord.java
  41. 166
      src/engine/db/archive/MineRecord.java
  42. 312
      src/engine/db/archive/PvpRecord.java
  43. 142
      src/engine/db/archive/RealmRecord.java
  44. 202
      src/engine/db/handlers/dbAccountHandler.java
  45. 115
      src/engine/db/handlers/dbBaneHandler.java
  46. 50
      src/engine/db/handlers/dbBaseClassHandler.java
  47. 86
      src/engine/db/handlers/dbBlueprintHandler.java
  48. 51
      src/engine/db/handlers/dbBoonHandler.java
  49. 809
      src/engine/db/handlers/dbBuildingHandler.java
  50. 27
      src/engine/db/handlers/dbBuildingLocationHandler.java
  51. 100
      src/engine/db/handlers/dbCSSessionHandler.java
  52. 113
      src/engine/db/handlers/dbCharacterPowerHandler.java
  53. 63
      src/engine/db/handlers/dbCharacterRuneHandler.java
  54. 116
      src/engine/db/handlers/dbCharacterSkillHandler.java
  55. 196
      src/engine/db/handlers/dbCityHandler.java
  56. 157
      src/engine/db/handlers/dbContractHandler.java
  57. 181
      src/engine/db/handlers/dbEffectsBaseHandler.java
  58. 30
      src/engine/db/handlers/dbEffectsResourceCostHandler.java
  59. 51
      src/engine/db/handlers/dbEnchantmentHandler.java
  60. 486
      src/engine/db/handlers/dbGuildHandler.java
  61. 470
      src/engine/db/handlers/dbHandlerBase.java
  62. 47
      src/engine/db/handlers/dbHeightMapHandler.java
  63. 152
      src/engine/db/handlers/dbItemBaseHandler.java
  64. 430
      src/engine/db/handlers/dbItemHandler.java
  65. 36
      src/engine/db/handlers/dbKitHandler.java
  66. 233
      src/engine/db/handlers/dbLootTableHandler.java
  67. 28
      src/engine/db/handlers/dbMenuHandler.java
  68. 117
      src/engine/db/handlers/dbMineHandler.java
  69. 351
      src/engine/db/handlers/dbMobBaseHandler.java
  70. 316
      src/engine/db/handlers/dbMobHandler.java
  71. 397
      src/engine/db/handlers/dbNPCHandler.java
  72. 402
      src/engine/db/handlers/dbPlayerCharacterHandler.java
  73. 54
      src/engine/db/handlers/dbPromotionClassHandler.java
  74. 85
      src/engine/db/handlers/dbRaceHandler.java
  75. 73
      src/engine/db/handlers/dbRealmHandler.java
  76. 37
      src/engine/db/handlers/dbResistHandler.java
  77. 35
      src/engine/db/handlers/dbRuneBaseAttributeHandler.java
  78. 73
      src/engine/db/handlers/dbRuneBaseEffectHandler.java
  79. 173
      src/engine/db/handlers/dbRuneBaseHandler.java
  80. 147
      src/engine/db/handlers/dbShrineHandler.java
  81. 143
      src/engine/db/handlers/dbSkillBaseHandler.java
  82. 35
      src/engine/db/handlers/dbSkillReqHandler.java
  83. 75
      src/engine/db/handlers/dbSpecialLootHandler.java
  84. 31
      src/engine/db/handlers/dbVendorDialogHandler.java
  85. 449
      src/engine/db/handlers/dbWarehouseHandler.java
  86. 93
      src/engine/db/handlers/dbZoneHandler.java
  87. 181
      src/engine/devcmd/AbstractDevCmd.java
  88. 127
      src/engine/devcmd/cmds/AddBuildingCmd.java
  89. 77
      src/engine/devcmd/cmds/AddGoldCmd.java
  90. 111
      src/engine/devcmd/cmds/AddMobCmd.java
  91. 98
      src/engine/devcmd/cmds/AddMobPowerCmd.java
  92. 98
      src/engine/devcmd/cmds/AddMobRuneCmd.java
  93. 111
      src/engine/devcmd/cmds/AddNPCCmd.java
  94. 158
      src/engine/devcmd/cmds/ApplyBonusCmd.java
  95. 149
      src/engine/devcmd/cmds/ApplyStatModCmd.java
  96. 130
      src/engine/devcmd/cmds/AuditFailedItemsCmd.java
  97. 71
      src/engine/devcmd/cmds/AuditHeightMapCmd.java
  98. 106
      src/engine/devcmd/cmds/AuditMobsCmd.java
  99. 77
      src/engine/devcmd/cmds/BoundsCmd.java
  100. 114
      src/engine/devcmd/cmds/ChangeNameCmd.java
  101. Some files were not shown because too many files have changed in this diff Show More

41
src/discord/ChatChannel.java

@ -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);
}
}
}

380
src/discord/Database.java

@ -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;
}
}
}

25
src/discord/DiscordAccount.java

@ -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() {
}
}

372
src/discord/MagicBot.java

@ -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();
}
}
}

106
src/discord/RobotSpeak.java

@ -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;
}
}

78
src/discord/handlers/AccountInfoRequest.java

@ -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);
}
}

55
src/discord/handlers/AnnounceChannelHandler.java

@ -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);
}
}

102
src/discord/handlers/BanToggleHandler.java

@ -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();
}
}

44
src/discord/handlers/ChangeLogHandler.java

@ -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);
}
}

51
src/discord/handlers/FlashHandler.java

@ -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);
}
}

56
src/discord/handlers/ForToFixChannelHandler.java

@ -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);
}
}

56
src/discord/handlers/GeneralChannelHandler.java

@ -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);
}
}

62
src/discord/handlers/LogsRequestHandler.java

@ -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);
}
}

77
src/discord/handlers/LookupRequestHandler.java

@ -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);
}
}

113
src/discord/handlers/PasswordChangeHandler.java

@ -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");
}
}

55
src/discord/handlers/PoliticalChannelHandler.java

@ -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);
}
}

56
src/discord/handlers/RecruitChannelHandler.java

@ -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);
}
}

126
src/discord/handlers/RegisterAccountHandler.java

@ -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!");
}
}

30
src/discord/handlers/RulesRequestHandler.java

@ -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);
}
}

63
src/discord/handlers/ServerRequestHandler.java

@ -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);
}
}
}

51
src/discord/handlers/SetAvailHandler.java

@ -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);
}
}

42
src/discord/handlers/StatusRequestHandler.java

@ -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);
}
}

75
src/discord/handlers/TrashRequestHandler.java

@ -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;
}
}
}

2943
src/engine/Enum.java

File diff suppressed because it is too large Load Diff

1099
src/engine/InterestManagement/HeightMap.java

File diff suppressed because it is too large Load Diff

554
src/engine/InterestManagement/InterestManager.java

@ -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");
}
}
}
}
}

102
src/engine/InterestManagement/RealmMap.java

@ -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();
}
}

312
src/engine/InterestManagement/WorldGrid.java

@ -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);
}
}

1769
src/engine/ai/MobileFSM.java

File diff suppressed because it is too large Load Diff

104
src/engine/ai/MobileFSMManager.java

@ -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;
}
}
}
}

413
src/engine/ai/utilities/CombatUtilities.java

@ -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;
}
}

303
src/engine/ai/utilities/MovementUtilities.java

@ -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;
}
}

15
src/engine/ai/utilities/PowerUtilities.java

@ -0,0 +1,15 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.ai.utilities;
public class PowerUtilities {
}

174
src/engine/core/ControlledRunnable.java

@ -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();
}
}
}

383
src/engine/db/archive/BaneRecord.java

@ -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

284
src/engine/db/archive/CharacterRecord.java

@ -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());
}
}
}

161
src/engine/db/archive/CityRecord.java

@ -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;
}
}

23
src/engine/db/archive/DataRecord.java

@ -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() {
}
}

324
src/engine/db/archive/DataWarehouse.java

@ -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");
}
}

215
src/engine/db/archive/GuildRecord.java

@ -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();
// }
}

166
src/engine/db/archive/MineRecord.java

@ -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;
}
}

312
src/engine/db/archive/PvpRecord.java

@ -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);
}
}

142
src/engine/db/archive/RealmRecord.java

@ -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();
}
}
}

202
src/engine/db/handlers/dbAccountHandler.java

@ -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();
}
}

115
src/engine/db/handlers/dbBaneHandler.java

@ -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);
}
}

50
src/engine/db/handlers/dbBaseClassHandler.java

@ -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();
}
}

86
src/engine/db/handlers/dbBlueprintHandler.java

@ -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;
}
}

51
src/engine/db/handlers/dbBoonHandler.java

@ -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;
}
}

809
src/engine/db/handlers/dbBuildingHandler.java

@ -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);
}
}

27
src/engine/db/handlers/dbBuildingLocationHandler.java

@ -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();
}
}

100
src/engine/db/handlers/dbCSSessionHandler.java

@ -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;
}
}

113
src/engine/db/handlers/dbCharacterPowerHandler.java

@ -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);
}
}

63
src/engine/db/handlers/dbCharacterRuneHandler.java

@ -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();
}
}

116
src/engine/db/handlers/dbCharacterSkillHandler.java

@ -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();
}
}

196
src/engine/db/handlers/dbCityHandler.java

@ -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);
}
}

157
src/engine/db/handlers/dbContractHandler.java

@ -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);
}
}

181
src/engine/db/handlers/dbEffectsBaseHandler.java

@ -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;
}
}

30
src/engine/db/handlers/dbEffectsResourceCostHandler.java

@ -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();
}
}

51
src/engine/db/handlers/dbEnchantmentHandler.java

@ -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);
}
}

486
src/engine/db/handlers/dbGuildHandler.java

@ -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;
//
// }
}

470
src/engine/db/handlers/dbHandlerBase.java

@ -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;
}
}

47
src/engine/db/handlers/dbHeightMapHandler.java

@ -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();
}
}
}

152
src/engine/db/handlers/dbItemBaseHandler.java

@ -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;
}
}

430
src/engine/db/handlers/dbItemHandler.java

@ -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);
}
}

36
src/engine/db/handlers/dbKitHandler.java

@ -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();
}
}

233
src/engine/db/handlers/dbLootTableHandler.java

@ -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();
}
}
}

28
src/engine/db/handlers/dbMenuHandler.java

@ -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();
}
}

117
src/engine/db/handlers/dbMineHandler.java

@ -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();
}
}

351
src/engine/db/handlers/dbMobBaseHandler.java

@ -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;
}
}

316
src/engine/db/handlers/dbMobHandler.java

@ -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();
}
}
}

397
src/engine/db/handlers/dbNPCHandler.java

@ -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);
}
}

402
src/engine/db/handlers/dbPlayerCharacterHandler.java

@ -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();
}
}
}

54
src/engine/db/handlers/dbPromotionClassHandler.java

@ -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();
}
}

85
src/engine/db/handlers/dbRaceHandler.java

@ -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;
}
}

73
src/engine/db/handlers/dbRealmHandler.java

@ -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();
}
}

37
src/engine/db/handlers/dbResistHandler.java

@ -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;
}
}

35
src/engine/db/handlers/dbRuneBaseAttributeHandler.java

@ -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();
}
}

73
src/engine/db/handlers/dbRuneBaseEffectHandler.java

@ -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;
}
}

173
src/engine/db/handlers/dbRuneBaseHandler.java

@ -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());
}
}

147
src/engine/db/handlers/dbShrineHandler.java

@ -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();
}
}
}

143
src/engine/db/handlers/dbSkillBaseHandler.java

@ -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();
}
}
}

35
src/engine/db/handlers/dbSkillReqHandler.java

@ -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);
}
}

75
src/engine/db/handlers/dbSpecialLootHandler.java

@ -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;
}
}

31
src/engine/db/handlers/dbVendorDialogHandler.java

@ -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);
}
}

449
src/engine/db/handlers/dbWarehouseHandler.java

@ -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();
}
}
}

93
src/engine/db/handlers/dbZoneHandler.java

@ -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);
}
}

181
src/engine/devcmd/AbstractDevCmd.java

@ -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;
}
}
}

127
src/engine/devcmd/cmds/AddBuildingCmd.java

@ -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'";
}
}

77
src/engine/devcmd/cmds/AddGoldCmd.java

@ -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'";
}
}

111
src/engine/devcmd/cmds/AddMobCmd.java

@ -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'";
}
}

98
src/engine/devcmd/cmds/AddMobPowerCmd.java

@ -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";
}
}

98
src/engine/devcmd/cmds/AddMobRuneCmd.java

@ -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";
}
}

111
src/engine/devcmd/cmds/AddNPCCmd.java

@ -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'";
}
}

158
src/engine/devcmd/cmds/ApplyBonusCmd.java

@ -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);
}
}

149
src/engine/devcmd/cmds/ApplyStatModCmd.java

@ -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!";
}
}

130
src/engine/devcmd/cmds/AuditFailedItemsCmd.java

@ -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.";
}
}

71
src/engine/devcmd/cmds/AuditHeightMapCmd.java

@ -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.";
}
}

106
src/engine/devcmd/cmds/AuditMobsCmd.java

@ -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.";
}
}

77
src/engine/devcmd/cmds/BoundsCmd.java

@ -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.";
}
}

114
src/engine/devcmd/cmds/ChangeNameCmd.java

@ -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…
Cancel
Save