diff --git a/src/discord/handlers/StatusRequestHandler.java b/src/discord/handlers/StatusRequestHandler.java index 7f173d9d..473ca172 100644 --- a/src/discord/handlers/StatusRequestHandler.java +++ b/src/discord/handlers/StatusRequestHandler.java @@ -20,12 +20,8 @@ public class StatusRequestHandler { 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: "; + outString = "Server Status: "; if (LoginServer.isPortInUse(Integer.parseInt(ConfigManager.MB_WORLD_PORT.getValue()))) outString += "ONLINE\n"; diff --git a/src/engine/Enum.java b/src/engine/Enum.java index 7bfa1d5f..d2718ab9 100644 --- a/src/engine/Enum.java +++ b/src/engine/Enum.java @@ -9,7 +9,7 @@ package engine; import ch.claude_martin.enumbitset.EnumBitSetHelper; -import engine.gameManager.BuildingManager; +import engine.gameManager.ConfigManager; import engine.gameManager.PowersManager; import engine.gameManager.ZoneManager; import engine.math.Vector2f; @@ -18,7 +18,6 @@ import engine.objects.*; import engine.powers.EffectsBase; import org.pmw.tinylog.Logger; -import java.awt.*; import java.util.ArrayList; import java.util.Collections; import java.util.EnumSet; @@ -441,77 +440,6 @@ public class Enum { CAPTURE; } - public enum RealmType { - - SEAFLOOR(0, 0x000000), - JOTUNHEIM(131, 0x006cff), - BOGLANDS(184, 0x00b4ff), - ESTRAGOTH(213, 0x00ff90), - RENNONVALE(232, 0X00ffea), - VOLGAARD(56, 0x1e00ff), - VOSTRAGOTH(108, 0x245fae), - NARROWS(61, 0x2f20a0), - FENMARCH(170, 0x3fb5ab), - MAELSTROM(63, 0x503e3e), - FARRICH(185, 0x52cd98), - TYRRANTHMINOR(96, 0x606060), - GREYSWATHE(88, 0x6c419d), - SUNSANVIL(64, 0x7800ff), - THERRONMARCH(206, 0x7bcdef), - DYVRENGISLE(119, 0x826b9c), - KINGSLUND(60, 0x871a94), - OUTERISLES(29, 0xa01313), - KAELENSFJORD(165, 0xa0c04a), - VARMADAI(95, 0xa16d1b), - WESTERMOORE(73, 0xaa3374), - OBLIVION(171, 0xababab), - SUDRAGOTH(196, 0xbaff00), - SKAARTHOL(183, 0xcfc57f), - KHALURAM(71, 0xe400ff), - VARSHADDUR(132, 0xf2845d), - FORBIDDENISLE(18, 0xff0000), - PIRATEISLES(48, 0xff008a), - SWATHMOORE(66, 0xff4200), - ESSENGLUND(130, 0xff9c00), - RELGOTH(177, 0xffde00); - - private final int realmID; - private final Color color; - private static final HashMap _rgbToIDMap = new HashMap<>(); - - RealmType(int realmID, int colorRGB) { - - this.realmID = realmID; - this.color = new Color(colorRGB); - - } - - public void addToColorMap() { - _rgbToIDMap.put(this.color.getRGB(), this.realmID); - } - - public static int getRealmIDByRGB(int realmRGB) { - - return _rgbToIDMap.get(realmRGB); - - } - - public int getRealmID() { - return realmID; - } - - public static RealmType getRealmTypeByUUID(int realmUUID) { - RealmType returnType = RealmType.SEAFLOOR; - - for (RealmType realmType : RealmType.values()) { - - if (realmType.realmID == realmUUID) - returnType = realmType; - } - return returnType; - } - } - public enum TaxType { PROFIT, WEEKLY, @@ -619,65 +547,30 @@ public class Enum { } } - public enum RunegateType { + public enum PortalType { - EARTH(6f, 19.5f, 128, 33213), - AIR(-6f, 19.5f, 256, 33170), - FIRE(15f, 7.5f, 512, 49612), - WATER(-15f, 8.5f, 1024, 53073), - SPIRIT(0, 10.5f, 2048, 33127), - CHAOS(22f, 3.5f, 8192, 58093), - OBLIV(0f, 42f, 16384, 60198), - MERCHANT(-22f, 4.5f, 4096, 60245), - FORBID(0.0f, 0.0f, 0, 54617); + EARTH(6f, 19.5f, 128), + AIR(-6f, 19.5f, 256), + FIRE(15f, 7.5f, 512), + WATER(-15f, 8.5f, 1024), + SPIRIT(0, 10.5f, 2048), + CHAOS(22f, 3.5f, 8192), + OBLIV(0f, 42f, 16384), + MERCHANT(-22f, 4.5f, 4096), + FORBID(0.0f, 0.0f, 0); - private final Vector2f offset; - private final int bitFlag; - private final int buildingUUID; + public final Vector2f offset; + public final int effectFlag; - RunegateType(float offsetX, float offsetY, int bitFlag, - int buildingUUID) { + PortalType(float offsetX, float offsetY, int effectFlag) { this.offset = new Vector2f(offsetX, offsetY); - this.bitFlag = bitFlag; - this.buildingUUID = buildingUUID; - } + this.effectFlag = effectFlag; - public Vector2f getOffset() { - return this.offset; } - - public int getEffectFlag() { - return this.bitFlag; - } - - public int getGateUUID() { - return this.buildingUUID; - } - - public Building getGateBuilding() { - - return BuildingManager.getBuilding(this.buildingUUID); - } - - public static RunegateType getGateTypeFromUUID(int uuid) { - - RunegateType outType = RunegateType.AIR; - - for (RunegateType gateType : RunegateType.values()) { - - if (gateType.buildingUUID == uuid) { - outType = gateType; - return outType; - } - - } - - return outType; - } - } + // Enum for ItemBase flags public enum ItemType { @@ -2749,7 +2642,7 @@ public class Enum { ARCHER, MAGE; } - + public enum MinionType { AELFBORNGUARD(951,1637, MinionClass.MELEE, "Guard","Aelfborn"), AELFBORNMAGE(952, 1635, MinionClass.MAGE,"Adept","Aelfborn"), diff --git a/src/engine/InterestManagement/RealmMap.java b/src/engine/InterestManagement/RealmMap.java index b5604526..eda74ef8 100644 --- a/src/engine/InterestManagement/RealmMap.java +++ b/src/engine/InterestManagement/RealmMap.java @@ -9,8 +9,8 @@ package engine.InterestManagement; /* This class is the main interface for Magicbane's -* Interest management facilities. -*/ + * Interest management facilities. + */ import engine.Enum; import engine.math.Vector3fImmutable; @@ -24,15 +24,26 @@ import engine.server.MBServerStatics; import engine.util.MapLoader; import org.pmw.tinylog.Logger; +import java.awt.*; +import java.util.HashMap; + import static engine.objects.Realm.getRealm; -public class RealmMap { +public enum RealmMap { + + REALM_MAP; + + // Spatial hashmap. Used for determining which Realm + // a player is currently located within. - // Spatial hashmap. Used for detecting which Realm - // a player is currently in.. - public static int[][] _realmImageMap; + private static final HashMap _rgbToIDMap = new HashMap<>(); + public static int getRealmIDByRGB(int realmRGB) { + + return _rgbToIDMap.get(realmRGB); + + } public static int getRealmIDAtLocation(Vector3fImmutable pos) { @@ -41,14 +52,17 @@ public class RealmMap { 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); + Logger.error("Invalid range; Z: " + yBuckets + ", X: " + xBuckets); return 255; } return RealmMap._realmImageMap[xBuckets][yBuckets]; } + public static void addToColorMap(Color color, int realmID) { + _rgbToIDMap.put(color.getRGB(), realmID); + } + public static Realm getRealmForCity(City city) { Realm outRealm = null; outRealm = city.getRealm(); @@ -61,28 +75,28 @@ public class RealmMap { } - public static void updateRealm(PlayerCharacter player){ + public static void updateRealm(PlayerCharacter player) { int realmID = RealmMap.getRealmIDAtLocation(player.getLoc()); - if (realmID != player.getLastRealmID()){ + if (realmID != player.getLastRealmID()) { player.setLastRealmID(realmID); Realm realm = Realm.getRealm(realmID); - if (realm != null){ - if (realm.isRuled()){ + if (realm != null) { + if (realm.isRuled()) { City city = realm.getRulingCity(); - if (city != null){ - TerritoryChangeMessage tcm = new TerritoryChangeMessage((PlayerCharacter)realm.getRulingCity().getOwner(),realm); + 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); + } 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); + } else { + TerritoryChangeMessage tcm = new TerritoryChangeMessage(null, realm); Dispatch dispatch = Dispatch.borrow(player, tcm); DispatchMessage.dispatchMsgDispatch(dispatch, Enum.DispatchChannel.PRIMARY); } @@ -95,6 +109,12 @@ public class RealmMap { public static void loadRealmImageMap() { + // Build color lookup map for realms from database + + for (Realm realm : Realm._realms.values()) { + RealmMap.addToColorMap(realm.mapColor, realm.realmID); + } + RealmMap._realmImageMap = MapLoader.loadMap(); } diff --git a/src/engine/db/handlers/dbRunegateHandler.java b/src/engine/db/handlers/dbRunegateHandler.java new file mode 100644 index 00000000..32ec6324 --- /dev/null +++ b/src/engine/db/handlers/dbRunegateHandler.java @@ -0,0 +1,73 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + + +package engine.db.handlers; + +import engine.Enum; +import engine.gameManager.DbManager; +import engine.objects.Building; +import engine.objects.Portal; +import engine.objects.Resists; + +import java.sql.Array; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class dbRunegateHandler extends dbHandlerBase { + + public dbRunegateHandler() { + + } + + public ArrayList GET_RUNEGATE_LIST() { + + ArrayList gateList = new ArrayList<>(); + + prepareCallable("SELECT DISTINCT `sourceBuilding` FROM `static_runegate_portals`;"); + + try { + ResultSet rs = executeQuery(); + while (rs.next()) { + gateList.add(rs.getInt("sourceBuilding")); + } + } catch (SQLException e) { + } finally { + closeCallable(); + } + return gateList; + } + + public ArrayList GET_PORTAL_LIST(int gateUID) { + + ArrayList portalList = new ArrayList<>(); + Building sourceBuilding = (Building) DbManager.getObject(Enum.GameObjectType.Building, gateUID); + + prepareCallable("SELECT * FROM `static_runegate_portals` WHERE `sourceBuilding` = ?;"); + setInt(1, gateUID); + + try { + ResultSet rs = executeQuery(); + + while (rs.next()) { + int targetBuildingID = rs.getInt("targetBuilding"); + Building targetBuilding = (Building) DbManager.getObject(Enum.GameObjectType.Building, targetBuildingID); + Enum.PortalType portalType = Enum.PortalType.valueOf(rs.getString("portalType")); + Portal portal = new Portal(sourceBuilding, portalType, targetBuilding); + portalList.add(portal); + } + + } catch (SQLException e) { + } finally { + closeCallable(); + } + return portalList; + } +} diff --git a/src/engine/devcmd/cmds/GateInfoCmd.java b/src/engine/devcmd/cmds/GateInfoCmd.java index 44bfcf76..bba5164d 100644 --- a/src/engine/devcmd/cmds/GateInfoCmd.java +++ b/src/engine/devcmd/cmds/GateInfoCmd.java @@ -2,7 +2,6 @@ package engine.devcmd.cmds; import engine.Enum.BuildingGroup; import engine.Enum.GameObjectType; -import engine.Enum.RunegateType; import engine.devcmd.AbstractDevCmd; import engine.math.Vector3fImmutable; import engine.objects.*; @@ -21,7 +20,6 @@ public class GateInfoCmd extends AbstractDevCmd { Building targetBuilding; String outString; - RunegateType runegateType; Runegate runeGate; Blueprint blueprint; String newline = "\r\n "; @@ -41,10 +39,10 @@ public class GateInfoCmd extends AbstractDevCmd { return; } - runegateType = RunegateType.getGateTypeFromUUID(targetBuilding.getObjectUUID()); - runeGate = Runegate.getRunegates()[runegateType.ordinal()]; + + runeGate = Runegate._runegates.get(targetBuilding.getObjectUUID()); - outString = "RungateType: " + runegateType.name(); + outString = "RungateType: " + runeGate.gateBuilding.getName(); outString += newline; outString += "Portal State:"; @@ -52,9 +50,9 @@ public class GateInfoCmd extends AbstractDevCmd { for (Portal portal : runeGate.getPortals()) { - outString += "Portal: " + portal.getPortalType().name(); + outString += "Portal: " + portal.portalType.name(); outString += " Active: " + portal.isActive(); - outString += " Dest: " + portal.getDestinationGateType().name(); + outString += " Dest: " + portal.targetGate.getName(); outString += newline; outString += " Origin: " + portal.getPortalLocation().x + 'x'; outString += " " + portal.getPortalLocation().y + 'y'; diff --git a/src/engine/devcmd/cmds/HotzoneCmd.java b/src/engine/devcmd/cmds/HotzoneCmd.java index ff206fe0..d3389750 100644 --- a/src/engine/devcmd/cmds/HotzoneCmd.java +++ b/src/engine/devcmd/cmds/HotzoneCmd.java @@ -22,9 +22,8 @@ import engine.server.world.WorldServer; /** * ./hotzone <- display the current hotzone & time remaining * ./hotzone random <- change hotzone to random new zone - * ./hotzone name of a macrozone <- change hotzone to the zone name provided - * */ + public class HotzoneCmd extends AbstractDevCmd { public HotzoneCmd() { @@ -32,83 +31,51 @@ public class HotzoneCmd extends AbstractDevCmd { } @Override - protected void _doCmd(PlayerCharacter pc, String[] words, + protected void _doCmd(PlayerCharacter playerCharacter, String[] words, AbstractGameObject target) { StringBuilder data = new StringBuilder(); + String outString; + for (String s : words) { data.append(s); data.append(' '); } + String input = data.toString().trim(); if (input.length() == 0) { - throwbackInfo(pc, "Current hotzone: " + hotzoneInfo()); + outString = "Current hotZone: " + ZoneManager.hotZone.getName() + "\r\n"; + outString += "Available hotZones: " + ZoneManager.availableHotZones(); + throwbackInfo(playerCharacter, outString); return; } - Zone zone; - if (input.equalsIgnoreCase("random")) { - throwbackInfo(pc, "Previous hotzone: " + hotzoneInfo()); ZoneManager.generateAndSetRandomHotzone(); - zone = ZoneManager.getHotZone(); - } else { - zone = ZoneManager.findMacroZoneByName(input); - - if (zone == null) { - throwbackError(pc, "Cannot find a macrozone with that name."); - return; - } - - if (zone == ZoneManager.getHotZone()) { - throwbackInfo(pc, "That macrozone is already the Hotzone."); - return; - } - - if (ZoneManager.validHotZone(zone) == false) { - throwbackError(pc, "That macrozone cannot be set as the Hotzone."); - return; - } - - throwbackInfo(pc, "Previous hotzone: " + hotzoneInfo()); - ZoneManager.setHotZone(zone); + outString = "New hotZone: " + ZoneManager.hotZone.getName() + "\r\n"; + outString += "Available hotZones: " + ZoneManager.availableHotZones(); + throwbackInfo(playerCharacter, outString); + return; } - throwbackInfo(pc, "New hotzone: " + hotzoneInfo()); - HotzoneChangeMsg hcm = new HotzoneChangeMsg(zone.getObjectType().ordinal(), zone.getObjectUUID()); - WorldServer.setLastHZChange(System.currentTimeMillis()); - } + if (input.equalsIgnoreCase("reset")) { + ZoneManager.resetHotZones(); + throwbackInfo(playerCharacter, "Available hotZones: " + ZoneManager.availableHotZones()); + return; + } + return; + } @Override protected String _getHelpString() { - return "Use no arguments to see the current hotzone. Specify a macrozone name to change the hotzone, or \"random\" to change it randomly."; + return "Use no arguments to see the current hotzone or \"random\" to change it randomly."; } @Override protected String _getUsageString() { - return "'./hotzone [random | ]"; + return "'./hotzone [random]"; } - private static String hotzoneInfo() { - final int hotzoneTimeLeft = FastMath.secondsUntilNextHour(); - final Zone hotzone = ZoneManager.getHotZone(); - String hotzoneInfo; - - if (hotzone == null) { - hotzoneInfo = "none"; - } else { - int hr = hotzoneTimeLeft/3600; - int rem = hotzoneTimeLeft%3600; - int mn = rem/60; - int sec = rem%60; - hotzoneInfo = hotzone.getName() + - " (" + (hr<10 ? "0" : "") + hr + ':' + - (mn<10 ? "0" : "") + mn + ':' + - (sec<10 ? "0" : "") + sec + - " remaining)"; - } - return hotzoneInfo; - } } diff --git a/src/engine/devcmd/cmds/MineActiveCmd.java b/src/engine/devcmd/cmds/MineActiveCmd.java index 2263128c..6f36030a 100644 --- a/src/engine/devcmd/cmds/MineActiveCmd.java +++ b/src/engine/devcmd/cmds/MineActiveCmd.java @@ -23,46 +23,44 @@ import engine.workthreads.HourlyJobThread; */ public class MineActiveCmd extends AbstractDevCmd { - public MineActiveCmd() { + public MineActiveCmd() { super("mineactive"); } - @Override - protected void _doCmd(PlayerCharacter pcSender, String[] args, - AbstractGameObject target) { - Building mineBuilding = BuildingManager.getBuilding(target.getObjectUUID()); - if (mineBuilding == null) - return; + @Override + protected void _doCmd(PlayerCharacter pcSender, String[] args, + AbstractGameObject target) { + Building mineBuilding = BuildingManager.getBuilding(target.getObjectUUID()); + if (mineBuilding == null) + return; - Mine mine = Mine.getMineFromTower(mineBuilding.getObjectUUID()); - if (mine == null) - return; + Mine mine = Mine.getMineFromTower(mineBuilding.getObjectUUID()); + if (mine == null) + return; - String trigger = args[0]; - switch (trigger){ - case "true": - HourlyJobThread.mineWindowOpen(mine); - Mine.setLastChange(System.currentTimeMillis()); - break; - case "false": - HourlyJobThread.mineWindowClose(mine); - Mine.setLastChange(System.currentTimeMillis()); - break; - default: - this.sendUsage(pcSender); - break; + String trigger = args[0]; + switch (trigger) { + case "true": + HourlyJobThread.mineWindowOpen(mine); + break; + case "false": + HourlyJobThread.mineWindowClose(mine); + break; + default: + this.sendUsage(pcSender); + break; - } - } + } + } - @Override - protected String _getUsageString() { + @Override + protected String _getUsageString() { return "' /mineactive true|false"; - } + } - @Override - protected String _getHelpString() { + @Override + protected String _getHelpString() { return "Temporarily add visual effects to Character"; - } + } } diff --git a/src/engine/devcmd/cmds/RealmInfoCmd.java b/src/engine/devcmd/cmds/RealmInfoCmd.java index 9ee6b695..5c22d4a2 100644 --- a/src/engine/devcmd/cmds/RealmInfoCmd.java +++ b/src/engine/devcmd/cmds/RealmInfoCmd.java @@ -26,43 +26,39 @@ public class RealmInfoCmd extends AbstractDevCmd { } @Override - protected void _doCmd(PlayerCharacter pc, String[] words, + protected void _doCmd(PlayerCharacter playerCharacter, String[] words, AbstractGameObject target) { Zone serverZone; - Zone parentZone; Realm serverRealm; int realmID; String outString = ""; - if (pc == null) { - throwbackError(pc, "Unable to find the pc making the request."); + if (playerCharacter == null) return; - } - serverZone = ZoneManager.findSmallestZone(pc.getLoc()); + serverZone = ZoneManager.findSmallestZone(playerCharacter.getLoc()); if (serverZone == null) { - throwbackError(pc, "Zone not found"); + throwbackError(playerCharacter, "Zone not found"); return; } - parentZone = serverZone.getParent(); - - realmID = RealmMap.getRealmIDAtLocation(pc.getLoc()); + realmID = RealmMap.getRealmIDAtLocation(playerCharacter.getLoc()); String newline = "\r\n "; outString = newline; - outString += "RealmID: " + realmID; + outString += "Realm: " + realmID + "("; serverRealm = Realm.getRealm(realmID); if (serverRealm == null) - outString += " Name: SeaFloor"; + outString += "SeaFloor"; else outString += serverRealm.getRealmName(); + outString += ")"; outString += newline; outString += " Zone: " + serverZone.getName(); @@ -76,7 +72,7 @@ public class RealmInfoCmd extends AbstractDevCmd { outString += newline; - throwbackInfo(pc, outString); + throwbackInfo(playerCharacter, outString); } @Override diff --git a/src/engine/devcmd/cmds/SetMineExpansion.java b/src/engine/devcmd/cmds/SetMineExpansion.java index 0bffe902..192329d5 100644 --- a/src/engine/devcmd/cmds/SetMineExpansion.java +++ b/src/engine/devcmd/cmds/SetMineExpansion.java @@ -21,67 +21,60 @@ import engine.objects.Mine; import engine.objects.PlayerCharacter; /** - * * @author Eighty - * */ public class SetMineExpansion extends AbstractDevCmd { - public SetMineExpansion() { + public SetMineExpansion() { super("setexpansion"); this.addCmdString("setexpansion"); } - @Override - protected void _doCmd(PlayerCharacter pcSender, String[] args, - AbstractGameObject target) { - - - if (target.getObjectType() != GameObjectType.Building) - return; - Building mineBuilding = BuildingManager.getBuilding(target.getObjectUUID()); - if (mineBuilding == null) - return; - Mine mine = Mine.getMineFromTower(mineBuilding.getObjectUUID()); - if (mine == null) - return; - int bit = 2; - switch (args[0].toUpperCase()) { - case "ON": - - bit |= mine.getFlags(); - if (!DbManager.MineQueries.SET_FLAGS(mine, bit)) - return; - mine.setFlags(bit); - ChatManager.chatSystemInfo(pcSender, mine.getZoneName() + "'s " + mine.getMineType().name + " is now an expansion mine."); - Mine.setLastChange(System.currentTimeMillis()); - break; - - case "OFF": - bit &= ~mine.getFlags(); - if (!DbManager.MineQueries.SET_FLAGS(mine, bit)) - return; - mine.setFlags(bit); - ChatManager.chatSystemInfo(pcSender, mine.getZoneName() + "'s " + mine.getMineType().name + " is no longer an expansion mine."); - Mine.setLastChange(System.currentTimeMillis()); - break; - - } - - - - - - } - - @Override - protected String _getUsageString() { + @Override + protected void _doCmd(PlayerCharacter pcSender, String[] args, + AbstractGameObject target) { + + + if (target.getObjectType() != GameObjectType.Building) + return; + Building mineBuilding = BuildingManager.getBuilding(target.getObjectUUID()); + if (mineBuilding == null) + return; + Mine mine = Mine.getMineFromTower(mineBuilding.getObjectUUID()); + if (mine == null) + return; + int bit = 2; + switch (args[0].toUpperCase()) { + case "ON": + + bit |= mine.getFlags(); + if (!DbManager.MineQueries.SET_FLAGS(mine, bit)) + return; + mine.setFlags(bit); + ChatManager.chatSystemInfo(pcSender, mine.getZoneName() + "'s " + mine.getMineType().name + " is now an expansion mine."); + break; + + case "OFF": + bit &= ~mine.getFlags(); + if (!DbManager.MineQueries.SET_FLAGS(mine, bit)) + return; + mine.setFlags(bit); + ChatManager.chatSystemInfo(pcSender, mine.getZoneName() + "'s " + mine.getMineType().name + " is no longer an expansion mine."); + break; + + } + + + } + + @Override + protected String _getUsageString() { return "' /setmineexpansion on|off"; - } + } - @Override - protected String _getHelpString() { + @Override + protected String _getHelpString() { return "enables or disables an expansion type for a mine."; - } + } } diff --git a/src/engine/devcmd/cmds/SetMineTypeCmd.java b/src/engine/devcmd/cmds/SetMineTypeCmd.java index c932923e..a469fe07 100644 --- a/src/engine/devcmd/cmds/SetMineTypeCmd.java +++ b/src/engine/devcmd/cmds/SetMineTypeCmd.java @@ -18,48 +18,45 @@ import engine.gameManager.DbManager; import engine.objects.*; /** - * * @author Eighty - * */ public class SetMineTypeCmd extends AbstractDevCmd { - public SetMineTypeCmd() { + public SetMineTypeCmd() { super("setminetype"); this.addCmdString("setminetype"); } - @Override - protected void _doCmd(PlayerCharacter pcSender, String[] args, - AbstractGameObject target) { - - MineProduction mineType = MineProduction.valueOf(args[0].toUpperCase()); - if (mineType == null) - return; - - if (target.getObjectType() != GameObjectType.Building) - return; - Building mineBuilding = BuildingManager.getBuilding(target.getObjectUUID()); - if (mineBuilding == null) - return; - Mine mine = Mine.getMineFromTower(mineBuilding.getObjectUUID()); - if (mine == null) - return; - if (!DbManager.MineQueries.CHANGE_TYPE(mine, mineType)) - return; - mine.setMineType(mineType.name()); - ChatManager.chatSystemInfo(pcSender, "The mine in " + mine.getZoneName() + " is now a(n) " + mine.getMineType().name); - Mine.setLastChange(System.currentTimeMillis()); - } + @Override + protected void _doCmd(PlayerCharacter pcSender, String[] args, + AbstractGameObject target) { + + MineProduction mineType = MineProduction.valueOf(args[0].toUpperCase()); + if (mineType == null) + return; + + if (target.getObjectType() != GameObjectType.Building) + return; + Building mineBuilding = BuildingManager.getBuilding(target.getObjectUUID()); + if (mineBuilding == null) + return; + Mine mine = Mine.getMineFromTower(mineBuilding.getObjectUUID()); + if (mine == null) + return; + if (!DbManager.MineQueries.CHANGE_TYPE(mine, mineType)) + return; + mine.setMineType(mineType.name()); + ChatManager.chatSystemInfo(pcSender, "The mine in " + mine.getZoneName() + " is now a(n) " + mine.getMineType().name); + } - @Override - protected String _getUsageString() { + @Override + protected String _getUsageString() { return "' /setminetype gold|ore|magic|lumber"; - } + } - @Override - protected String _getHelpString() { + @Override + protected String _getHelpString() { return "Changes the mine type of the current mine."; - } + } } diff --git a/src/engine/devcmd/cmds/SetRateCmd.java b/src/engine/devcmd/cmds/SetRateCmd.java deleted file mode 100644 index b73c0d92..00000000 --- a/src/engine/devcmd/cmds/SetRateCmd.java +++ /dev/null @@ -1,98 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2022 -// www.magicbane.com - - -package engine.devcmd.cmds; - -import engine.devcmd.AbstractDevCmd; -import engine.objects.AbstractGameObject; -import engine.objects.PlayerCharacter; -import engine.server.MBServerStatics; - - -/** - * - * @author Murray - * - */ -public class SetRateCmd extends AbstractDevCmd { - - public SetRateCmd() { - super("setrate"); - } - - @Override - protected void _doCmd(PlayerCharacter pc, String[] args, AbstractGameObject target) { - - if (args.length != 2) { - this.sendUsage(pc); - return; - } - - float mod = 0f; - - try { - mod = Float.parseFloat(args[1]); - } catch (NumberFormatException e) { - throwbackError(pc, "Supplied data failed to parse to Float."); - return; - } - - - if (args[0].equals("exp")){ - - MBServerStatics.EXP_RATE_MOD = mod; - throwbackInfo(pc, "Experience Rate set to: " + mod); - - } else if (args[0].equals("gold")){ - - MBServerStatics.GOLD_RATE_MOD = mod; - throwbackInfo(pc, "Gold Rate set to: " + mod); - - } else if (args[0].equals("drop")){ - - MBServerStatics.DROP_RATE_MOD = mod; - throwbackInfo(pc, "Drop Multiplier Rate set to: " + mod); - - } else if (args[0].equals("hotexp")){ - - MBServerStatics.HOT_EXP_RATE_MOD = mod; - throwbackInfo(pc, "HOTZONE Experience Rate set to: " + mod); - - } else if (args[0].equals("hotgold")){ - - MBServerStatics.HOT_GOLD_RATE_MOD = mod; - throwbackInfo(pc, "HOTZONE Gold Rate set to: " + mod); - - } else if (args[0].equals("hotdrop")){ - - MBServerStatics.HOT_DROP_RATE_MOD = mod; - throwbackInfo(pc, "HOTZONE Drop Multiplier Rate set to: " + mod); - - } else if (args[0].equals("production")){ - - MBServerStatics.PRODUCTION_TIME_MULTIPLIER = mod; - throwbackInfo(pc, "Production Time Multiplier Rate set to: " + mod); - - } else { - this.sendUsage(pc); - } - - } - - @Override - protected String _getUsageString() { - return "' /setrate {exp|gold|drop|hotexp|hotgold|hotdrop} rate'"; - } - - @Override - protected String _getHelpString() { - return "Sets the rates for exp, gold or drops. Accepts a float, defaults to 1.0"; - } - -} \ No newline at end of file diff --git a/src/engine/gameManager/ConfigManager.java b/src/engine/gameManager/ConfigManager.java index ec745dd7..b23ca660 100644 --- a/src/engine/gameManager/ConfigManager.java +++ b/src/engine/gameManager/ConfigManager.java @@ -62,10 +62,20 @@ public enum ConfigManager { MB_WORLD_UUID, MB_WORLD_WAREHOUSE_PUSH, MB_WORLD_MAINTENANCE, - MB_WORLD_MAINTENANCE_HOUR, MB_WORLD_GREETING, MB_WORLD_KEYCLONE_MAX, + //drop rates + MB_NORMAL_EXP_RATE, + MB_NORMAL_DROP_RATE, + MB_HOTZONE_EXP_RATE, + MB_HOTZONE_DROP_RATE, + MB_HOTZONE_DURATION, + + MB_HOTZONE_MIN_LEVEL, + + MB_PRODUCTION_RATE, + // MagicBot configuration. MB_MAGICBOT_SERVERID, @@ -78,10 +88,8 @@ public enum ConfigManager { MB_MAGICBOT_GENERAL, MB_MAGICBOT_FORTOFIX, MB_MAGICBOT_RECRUIT, - MB_MAGICBOT_ADMINLOG, - MB_MAGICBOT_BOTVERSION, - MB_MAGICBOT_GAMEVERSION; - + MB_MAGICBOT_ADMINLOG; + // Map to hold our config pulled in from the environment // We also use the config to point to the current message pump // and determine the server type at runtime. @@ -95,9 +103,10 @@ public enum ConfigManager { // Called at bootstrap: ensures that all config values are loaded. + public static boolean init() { - Logger.info("ConfigManager: init()"); + Logger.info("Loading config from environment..."); for (ConfigManager configSetting : ConfigManager.values()) if (configMap.containsKey(configSetting.name())) @@ -109,11 +118,12 @@ public enum ConfigManager { return false; } - // compile regex here + // compile regex here - regex.put(MB_LOGIN_FNAME_REGEX, Pattern.compile(MB_LOGIN_FNAME_REGEX.getValue())); + Logger.info("Compiling regex"); - return true; + regex.put(MB_LOGIN_FNAME_REGEX, Pattern.compile(MB_LOGIN_FNAME_REGEX.getValue())); + return true; } // Get the value associated with this enumeration diff --git a/src/engine/gameManager/DbManager.java b/src/engine/gameManager/DbManager.java index d99bbbc9..e172f333 100644 --- a/src/engine/gameManager/DbManager.java +++ b/src/engine/gameManager/DbManager.java @@ -311,4 +311,6 @@ public enum DbManager { public static final dbBoonHandler BoonQueries = new dbBoonHandler(); public static final dbShrineHandler ShrineQueries = new dbShrineHandler(); public static final dbHeightMapHandler HeightMapQueries = new dbHeightMapHandler(); + + public static final dbRunegateHandler RunegateQueries = new dbRunegateHandler(); } diff --git a/src/engine/gameManager/DevCmdManager.java b/src/engine/gameManager/DevCmdManager.java index 8f6d8ea8..f51157d2 100644 --- a/src/engine/gameManager/DevCmdManager.java +++ b/src/engine/gameManager/DevCmdManager.java @@ -109,7 +109,6 @@ public enum DevCmdManager { DevCmdManager.registerDevCmd(new GetCacheCountCmd()); DevCmdManager.registerDevCmd(new GetRuneDropRateCmd()); DevCmdManager.registerDevCmd(new DecachePlayerCmd()); - DevCmdManager.registerDevCmd(new SetRateCmd()); DevCmdManager.registerDevCmd(new AuditMobsCmd()); DevCmdManager.registerDevCmd(new ChangeNameCmd()); DevCmdManager.registerDevCmd(new GuildListCmd()); diff --git a/src/engine/gameManager/MaintenanceManager.java b/src/engine/gameManager/MaintenanceManager.java index cecc5035..f54a904b 100644 --- a/src/engine/gameManager/MaintenanceManager.java +++ b/src/engine/gameManager/MaintenanceManager.java @@ -13,9 +13,12 @@ package engine.gameManager; import engine.Enum; import engine.objects.*; +import org.joda.time.DateTime; import org.pmw.tinylog.Logger; +import java.time.DayOfWeek; import java.time.LocalDateTime; +import java.time.temporal.TemporalAdjusters; import java.util.ArrayList; public enum MaintenanceManager { @@ -50,12 +53,12 @@ public enum MaintenanceManager { if (chargeUpkeep(building) == false) derankList.add(building); } - // Reset maintenance dates for these buildings - for (Building building : maintList) - setMaintDateTime(building, building.maintDateTime.plusDays(7)); + for (Building building : maintList) { + setMaintDateTime(building, LocalDateTime.now().plusDays(7)); + } // Derak or destroy buildings that did not // have funds available. @@ -120,6 +123,11 @@ public enum MaintenanceManager { if (building.maintDateTime.isAfter(LocalDateTime.now())) continue; + + //no maintenance if day of week doesnt match + if(LocalDateTime.now().getDayOfWeek().ordinal() != building.maintDateTime.getDayOfWeek().ordinal()){ + continue; + } // Add building to maintenance queue maintList.add(building); diff --git a/src/engine/gameManager/SimulationManager.java b/src/engine/gameManager/SimulationManager.java index 6905c099..088e4cba 100644 --- a/src/engine/gameManager/SimulationManager.java +++ b/src/engine/gameManager/SimulationManager.java @@ -206,7 +206,7 @@ public enum SimulationManager { */ private void pulseRunegates() { - for (Runegate runegate : Runegate.getRunegates()) { + for (Runegate runegate : Runegate._runegates.values()) { runegate.collidePortals(); } diff --git a/src/engine/gameManager/ZoneManager.java b/src/engine/gameManager/ZoneManager.java index ef8c1c61..5ac8a055 100644 --- a/src/engine/gameManager/ZoneManager.java +++ b/src/engine/gameManager/ZoneManager.java @@ -17,9 +17,11 @@ import engine.objects.Building; import engine.objects.City; import engine.objects.Zone; import engine.server.MBServerStatics; -import engine.server.world.WorldServer; import org.pmw.tinylog.Logger; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -33,405 +35,435 @@ import java.util.concurrent.ThreadLocalRandom; */ public enum ZoneManager { - ZONEMANAGER; + ZONEMANAGER; + + public static Instant hotZoneLastUpdate; + /* Instance variables */ + private static Zone seaFloor = null; + public static Zone hotZone = null; + public static int hotZoneCycle = 0; // Used with HOTZONE_DURATION from config. + private static final ConcurrentHashMap zonesByID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD); + private static final ConcurrentHashMap zonesByUUID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD); + private static final ConcurrentHashMap zonesByName = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD); + public static final Set macroZones = Collections.newSetFromMap(new ConcurrentHashMap<>()); + private static final Set npcCityZones = Collections.newSetFromMap(new ConcurrentHashMap<>()); + private static final Set playerCityZones = Collections.newSetFromMap(new ConcurrentHashMap<>()); + + // Find all zones coordinates fit into, starting with Sea Floor + + public static ArrayList getAllZonesIn(final Vector3fImmutable loc) { + + ArrayList allIn = new ArrayList<>(); + Zone zone; + + zone = ZoneManager.findSmallestZone(loc); + + if (zone != null) { + allIn.add(zone); + while (zone.getParent() != null) { + zone = zone.getParent(); + allIn.add(zone); + } + } + return allIn; + } - /* Instance variables */ - private static Zone seaFloor = null; - private static Zone hotzone = null; - private static ConcurrentHashMap zonesByID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD); - private static ConcurrentHashMap zonesByUUID = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD); - private static ConcurrentHashMap zonesByName = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD); - private static Set macroZones = Collections.newSetFromMap(new ConcurrentHashMap<>()); - private static Set npcCityZones = Collections.newSetFromMap(new ConcurrentHashMap<>()); - private static Set playerCityZones = Collections.newSetFromMap(new ConcurrentHashMap<>()); + // Find smallest zone coordinates fit into. - // Find all zones coordinates fit into, starting with Sea Floor + public static final Zone findSmallestZone(final Vector3fImmutable loc) { - public static ArrayList getAllZonesIn(final Vector3fImmutable loc) { + Zone zone = ZoneManager.seaFloor; - ArrayList allIn = new ArrayList<>(); - Zone zone; + if (zone == null) + return null; - zone = ZoneManager.findSmallestZone(loc); + boolean childFound = true; - if (zone != null) { - allIn.add(zone); - while (zone.getParent() != null) { - zone = zone.getParent(); - allIn.add(zone); - } - } - return allIn; - } + while (childFound) { - // Find smallest zone coordinates fit into. + childFound = false; - public static final Zone findSmallestZone(final Vector3fImmutable loc) { + ArrayList nodes = zone.getNodes(); - Zone zone = ZoneManager.seaFloor; + // Logger.info("soze", "" + nodes.size()); + if (nodes != null) + for (Zone child : nodes) { - if (zone == null) - return null; + if (Bounds.collide(loc, child.getBounds()) == true) { + zone = child; + childFound = true; + break; + } + } + } + return zone; + } - boolean childFound = true; + public static void addZone(final int zoneID, final Zone zone) { - while (childFound) { + ZoneManager.zonesByID.put(zoneID, zone); - childFound = false; + if (zone != null) + ZoneManager.zonesByUUID.put(zone.getObjectUUID(), zone); - ArrayList nodes = zone.getNodes(); + ZoneManager.zonesByName.put(zone.getName().toLowerCase(), zone); - // Logger.info("soze", "" + nodes.size()); - if (nodes != null) - for (Zone child : nodes) { + } - if (Bounds.collide(loc, child.getBounds()) == true) { - zone = child; - childFound = true; - break; - } - } - } - return zone; - } + // Returns the number of available hotZones + // remaining in this cycle (1am) - public static void addZone(final int zoneID, final Zone zone) { + public static int availableHotZones() { - ZoneManager.zonesByID.put(zoneID, zone); + int count = 0; - if (zone != null) - ZoneManager.zonesByUUID.put(zone.getObjectUUID(), zone); + for (Zone zone : ZoneManager.macroZones) + if (ZoneManager.validHotZone(zone)) + count = count + 1; - ZoneManager.zonesByName.put(zone.getName().toLowerCase(), zone); + return count; + } - } + // Resets the availability of hotZones + // for this cycle - public static Zone getZoneByUUID(final int zoneUUID) { - return ZoneManager.zonesByUUID.get(zoneUUID); - } + public static void resetHotZones() { - public static Zone getZoneByZoneID(final int zoneID) { + for (Zone zone : ZoneManager.macroZones) + if (zone.hasBeenHotzone) + zone.hasBeenHotzone = false; - return ZoneManager.zonesByID.get(zoneID); - } + } - public static final Collection getAllZones() { - return ZoneManager.zonesByUUID.values(); - } + public static Zone getZoneByUUID(final int zoneUUID) { + return ZoneManager.zonesByUUID.get(zoneUUID); + } - public static final Zone getHotZone() { - return ZoneManager.hotzone; - } + public static Zone getZoneByZoneID(final int zoneID) { - public static final void setHotZone(final Zone zone) { - if (!zone.isMacroZone()) - return; - ZoneManager.hotzone = zone; - } + return ZoneManager.zonesByID.get(zoneID); + } - public static boolean inHotZone(final Vector3fImmutable loc) { + public static final Collection getAllZones() { + return ZoneManager.zonesByUUID.values(); + } - if (ZoneManager.hotzone == null) - return false; + public static final void setHotZone(final Zone zone) { - return (Bounds.collide(loc, ZoneManager.hotzone.getBounds()) == true); - } + if (!zone.isMacroZone()) + return; - public static void setSeaFloor(final Zone value) { - ZoneManager.seaFloor = value; - } + ZoneManager.hotZone = zone; + ZoneManager.hotZoneCycle = 1; // Used with HOTZONE_DURATION from config. + zone.hasBeenHotzone = true; + ZoneManager.hotZoneLastUpdate = LocalDateTime.now().withMinute(0).withSecond(0).atZone(ZoneId.systemDefault()).toInstant(); - public static Zone getSeaFloor() { - return ZoneManager.seaFloor; - } + } - public static final void populateWorldZones(final Zone zone) { + public static boolean inHotZone(final Vector3fImmutable loc) { - int loadNum = zone.getLoadNum(); + if (ZoneManager.hotZone == null) + return false; - // Zones are added to separate - // collections for quick access - // based upon their type. + return (Bounds.collide(loc, ZoneManager.hotZone.getBounds()) == true); + } - if (zone.isMacroZone()) { - addMacroZone(zone); - return; - } + public static void setSeaFloor(final Zone value) { + ZoneManager.seaFloor = value; + } + public static Zone getSeaFloor() { + return ZoneManager.seaFloor; + } - if (zone.isPlayerCity()) { - addPlayerCityZone(zone); - return; - } + public static final void populateWorldZones(final Zone zone) { - if (zone.isNPCCity()) - addNPCCityZone(zone); + int loadNum = zone.getLoadNum(); - } + // Zones are added to separate + // collections for quick access + // based upon their type. - private static void addMacroZone(final Zone zone) { - ZoneManager.macroZones.add(zone); - } + if (zone.isMacroZone()) { + addMacroZone(zone); + return; + } - private static void addNPCCityZone(final Zone zone) { - zone.setNPCCity(true); - ZoneManager.npcCityZones.add(zone); - } - public static final void addPlayerCityZone(final Zone zone) { - zone.setPlayerCity(true); - ZoneManager.playerCityZones.add(zone); - } + if (zone.isPlayerCity()) { + addPlayerCityZone(zone); + return; + } - public static final void generateAndSetRandomHotzone() { + if (zone.isNPCCity()) + addNPCCityZone(zone); - Zone hotzone; - ArrayList zoneArray = new ArrayList<>(); + } - if (ZoneManager.macroZones.isEmpty()) - return; + private static void addMacroZone(final Zone zone) { + ZoneManager.macroZones.add(zone); + } - for (Zone zone : ZoneManager.macroZones) { + private static void addNPCCityZone(final Zone zone) { + zone.setNPCCity(true); + ZoneManager.npcCityZones.add(zone); + } - if (validHotZone(zone)) - zoneArray.add(zone.getObjectUUID()); + public static final void addPlayerCityZone(final Zone zone) { + zone.setPlayerCity(true); + ZoneManager.playerCityZones.add(zone); + } - } + public static final void generateAndSetRandomHotzone() { - int entryIndex = ThreadLocalRandom.current().nextInt(zoneArray.size()); + Zone hotZone; + ArrayList zoneArray = new ArrayList<>(); - hotzone = ZoneManager.getZoneByUUID(zoneArray.get(entryIndex)); + if (ZoneManager.macroZones.isEmpty()) + return; + // Reset hotZone availability if none are left. - if (hotzone == null){ - Logger.error( "Hotzone is null"); - return; - } + if (ZoneManager.availableHotZones() == 0) + ZoneManager.resetHotZones(); + for (Zone zone : ZoneManager.macroZones) + if (validHotZone(zone)) + zoneArray.add(zone.getObjectUUID()); - ZoneManager.setHotZone(hotzone); - WorldServer.setLastHZChange(System.currentTimeMillis()); + int entryIndex = ThreadLocalRandom.current().nextInt(zoneArray.size()); - } + hotZone = ZoneManager.getZoneByUUID(zoneArray.get(entryIndex)); - public static final boolean validHotZone(Zone zone) { + if (hotZone == null) { + Logger.error("Hotzone is null"); + return; + } - if (zone.getSafeZone() == (byte) 1) - return false; // no safe zone hotzones// if (this.hotzone == null) + ZoneManager.setHotZone(hotZone); - if (zone.getNodes().isEmpty()) - return false; + } - if (zone.equals(ZoneManager.seaFloor)) - return false; + public static final boolean validHotZone(Zone zone) { - // return false; //first time setting, accept it - // if (this.hotzone.getUUID() == zone.getUUID()) - // return true; //no same hotzone + if (zone.getSafeZone() == (byte) 1) + return false; // no safe zone hotzones// if (this.hotzone == null) - if (ZoneManager.hotzone != null) - return ZoneManager.hotzone.getObjectUUID() != zone.getObjectUUID(); + if (zone.getNodes().isEmpty()) + return false; - return true; - } + if (zone.equals(ZoneManager.seaFloor)) + return false; - /** - * Gets a MacroZone by name. - * - * @param inputName - * MacroZone name to search for - * @return Zone of the MacroZone, or Null - */ + //no duplicate hotZones - public static Zone findMacroZoneByName(String inputName) { - synchronized (ZoneManager.macroZones) { - for (Zone zone : ZoneManager.macroZones) { - String zoneName = zone.getName(); - if (zoneName.equalsIgnoreCase(inputName)) - return zone; - } - } - return null; - } + if (zone.hasBeenHotzone == true) + return false; - // Converts world coordinates to coordinates local to a given zone. + // Enforce min level - public static Vector3fImmutable worldToLocal(Vector3fImmutable worldVector, - Zone serverZone) { + if (zone.minLvl < Integer.parseInt(ConfigManager.MB_HOTZONE_MIN_LEVEL.getValue())) + return false; - Vector3fImmutable localCoords; + if (ZoneManager.hotZone != null) + return ZoneManager.hotZone.getObjectUUID() != zone.getObjectUUID(); - localCoords = new Vector3fImmutable(worldVector.x - serverZone.absX, - worldVector.y - serverZone.absY, worldVector.z - - serverZone.absZ); + return true; + } - return localCoords; - } + /** + * Gets a MacroZone by name. + * + * @param inputName MacroZone name to search for + * @return Zone of the MacroZone, or Null + */ + + public static Zone findMacroZoneByName(String inputName) { + synchronized (ZoneManager.macroZones) { + for (Zone zone : ZoneManager.macroZones) { + String zoneName = zone.getName(); + if (zoneName.equalsIgnoreCase(inputName)) + return zone; + } + } + return null; + } - public static Vector2f worldToZoneSpace(Vector3fImmutable worldVector, - Zone serverZone) { + // Converts world coordinates to coordinates local to a given zone. - Vector2f localCoords; - Vector2f zoneOrigin; + public static Vector3fImmutable worldToLocal(Vector3fImmutable worldVector, + Zone serverZone) { - // Top left corner of zone is calculated in world space by the center and it's extents. + Vector3fImmutable localCoords; - zoneOrigin = new Vector2f(serverZone.getLoc().x, serverZone.getLoc().z); - zoneOrigin = zoneOrigin.subtract(new Vector2f(serverZone.getBounds().getHalfExtents().x, serverZone.getBounds().getHalfExtents().y)); + localCoords = new Vector3fImmutable(worldVector.x - serverZone.absX, + worldVector.y - serverZone.absY, worldVector.z + - serverZone.absZ); - // Local coordinate in world space translated to an offset from the calculated zone origin. + return localCoords; + } - localCoords = new Vector2f(worldVector.x, worldVector.z); - localCoords = localCoords.subtract(zoneOrigin); + public static Vector2f worldToZoneSpace(Vector3fImmutable worldVector, + Zone serverZone) { - localCoords.setY((serverZone.getBounds().getHalfExtents().y * 2) - localCoords.y); + Vector2f localCoords; + Vector2f zoneOrigin; + // Top left corner of zone is calculated in world space by the center and it's extents. + zoneOrigin = new Vector2f(serverZone.getLoc().x, serverZone.getLoc().z); + zoneOrigin = zoneOrigin.subtract(new Vector2f(serverZone.getBounds().getHalfExtents().x, serverZone.getBounds().getHalfExtents().y)); + // Local coordinate in world space translated to an offset from the calculated zone origin. - // TODO : Make sure this value does not go outside the zone's bounds. + localCoords = new Vector2f(worldVector.x, worldVector.z); + localCoords = localCoords.subtract(zoneOrigin); - return localCoords; - } + localCoords.setY((serverZone.getBounds().getHalfExtents().y * 2) - localCoords.y); - // Converts local zone coordinates to world coordinates - public static Vector3fImmutable localToWorld(Vector3fImmutable worldVector, - Zone serverZone) { + // TODO : Make sure this value does not go outside the zone's bounds. - Vector3fImmutable worldCoords; + return localCoords; + } - worldCoords = new Vector3fImmutable(worldVector.x + serverZone.absX, - worldVector.y + serverZone.absY, worldVector.z - + serverZone.absZ); + // Converts local zone coordinates to world coordinates - return worldCoords; - } + public static Vector3fImmutable localToWorld(Vector3fImmutable worldVector, + Zone serverZone) { + Vector3fImmutable worldCoords; - /** - * Converts from local (relative to this building) to world. - * - * @param localPos position in local reference (relative to this building) - * @return position relative to world - */ + worldCoords = new Vector3fImmutable(worldVector.x + serverZone.absX, + worldVector.y + serverZone.absY, worldVector.z + + serverZone.absZ); - public static Vector3fImmutable convertLocalToWorld(Building building, Vector3fImmutable localPos) { + return worldCoords; + } - // convert from SB rotation value to radians - - - if (building.getBounds().getQuaternion() == null) - return building.getLoc(); - Vector3fImmutable rotatedLocal = Vector3fImmutable.rotateAroundPoint(Vector3fImmutable.ZERO, localPos, building.getBounds().getQuaternion()); - // handle building rotation - // handle building translation - return building.getLoc().add(rotatedLocal.x, rotatedLocal.y,rotatedLocal.z); - } - - - //used for regions, Building bounds not set yet. - public static Vector3f convertLocalToWorld(Building building, Vector3f localPos, Bounds bounds) { + /** + * Converts from local (relative to this building) to world. + * + * @param localPos position in local reference (relative to this building) + * @return position relative to world + */ - // convert from SB rotation value to radians - - - Vector3f rotatedLocal = Vector3f.rotateAroundPoint(Vector3f.ZERO, localPos, bounds.getQuaternion()); - // handle building rotation - // handle building translation + public static Vector3fImmutable convertLocalToWorld(Building building, Vector3fImmutable localPos) { - return new Vector3f(building.getLoc().add(rotatedLocal.x, rotatedLocal.y,rotatedLocal.z)); - } + // convert from SB rotation value to radians - public static Vector3fImmutable convertWorldToLocal(Building building, Vector3fImmutable WorldPos) { - Vector3fImmutable convertLoc = Vector3fImmutable.rotateAroundPoint(building.getLoc(),WorldPos,-building.getBounds().getQuaternion().angleY); - - - convertLoc = convertLoc.subtract(building.getLoc()); - // convert from SB rotation value to radians - - return convertLoc; + if (building.getBounds().getQuaternion() == null) + return building.getLoc(); + Vector3fImmutable rotatedLocal = Vector3fImmutable.rotateAroundPoint(Vector3fImmutable.ZERO, localPos, building.getBounds().getQuaternion()); + // handle building rotation + // handle building translation - } + return building.getLoc().add(rotatedLocal.x, rotatedLocal.y, rotatedLocal.z); + } + + + //used for regions, Building bounds not set yet. + public static Vector3f convertLocalToWorld(Building building, Vector3f localPos, Bounds bounds) { - public static Vector3fImmutable convertNPCLoc(Building building, Vector3fImmutable npcLoc) { + // convert from SB rotation value to radians - return Vector3fImmutable.rotateAroundPoint(Vector3fImmutable.ZERO, npcLoc, -building.getBounds().getQuaternion().angleY); - } + Vector3f rotatedLocal = Vector3f.rotateAroundPoint(Vector3f.ZERO, localPos, bounds.getQuaternion()); + // handle building rotation + // handle building translation + + return new Vector3f(building.getLoc().add(rotatedLocal.x, rotatedLocal.y, rotatedLocal.z)); + } + + public static Vector3fImmutable convertWorldToLocal(Building building, Vector3fImmutable WorldPos) { + Vector3fImmutable convertLoc = Vector3fImmutable.rotateAroundPoint(building.getLoc(), WorldPos, -building.getBounds().getQuaternion().angleY); - // Method returns a city if the given location is within - // a city siege radius. - public static City getCityAtLocation(Vector3fImmutable worldLoc) { + convertLoc = convertLoc.subtract(building.getLoc()); - Zone currentZone; - ArrayList zoneList; - City city; + // convert from SB rotation value to radians - currentZone = ZoneManager.findSmallestZone(worldLoc); + return convertLoc; - if (currentZone.isPlayerCity()) - return City.getCity(currentZone.getPlayerCityUUID()); + } + + public static Vector3fImmutable convertNPCLoc(Building building, Vector3fImmutable npcLoc) { + + return Vector3fImmutable.rotateAroundPoint(Vector3fImmutable.ZERO, npcLoc, -building.getBounds().getQuaternion().angleY); + + } - // Not currently on a city grid. Test nearby cities - // to see if we are on one of their seige bounds. + // Method returns a city if the given location is within + // a city siege radius. - zoneList = currentZone.getNodes(); + public static City getCityAtLocation(Vector3fImmutable worldLoc) { - for (Zone zone : zoneList) { + Zone currentZone; + ArrayList zoneList; + City city; - if (zone == currentZone) - continue; + currentZone = ZoneManager.findSmallestZone(worldLoc); + + if (currentZone.isPlayerCity()) + return City.getCity(currentZone.getPlayerCityUUID()); + + // Not currently on a city grid. Test nearby cities + // to see if we are on one of their seige bounds. + + zoneList = currentZone.getNodes(); + + for (Zone zone : zoneList) { + + if (zone == currentZone) + continue; + + if (zone.isPlayerCity() == false) + continue; + + city = City.getCity(zone.getPlayerCityUUID()); + + if (worldLoc.isInsideCircle(city.getLoc(), Enum.CityBoundsType.SIEGE.extents)) + return city; + } + + return null; + } - if (zone.isPlayerCity() == false) - continue; + /* Method is called when creating a new player city to + * validate that the new zone does not overlap any other + * zone that might currently exist + */ - city = City.getCity(zone.getPlayerCityUUID()); + public static boolean validTreePlacementLoc(Zone currentZone, float positionX, float positionZ) { - if (worldLoc.isInsideCircle(city.getLoc(), Enum.CityBoundsType.SIEGE.extents)) - return city; - } + // Member Variable declaration - return null; - } + ArrayList zoneList; + boolean validLocation = true; + Bounds treeBounds; - /* Method is called when creating a new player city to - * validate that the new zone does not overlap any other - * zone that might currently exist - */ + if (currentZone.isContininent() == false) + return false; - public static boolean validTreePlacementLoc(Zone currentZone, float positionX, float positionZ) { - // Member Variable declaration + treeBounds = Bounds.borrow(); + treeBounds.setBounds(new Vector2f(positionX, positionZ), new Vector2f(Enum.CityBoundsType.SIEGE.extents, Enum.CityBoundsType.SIEGE.extents), 0.0f); - ArrayList zoneList; - boolean validLocation = true; - Bounds treeBounds; - - if (currentZone.isContininent() == false) - return false; - - - treeBounds = Bounds.borrow(); - treeBounds.setBounds(new Vector2f(positionX, positionZ), new Vector2f(Enum.CityBoundsType.SIEGE.extents, Enum.CityBoundsType.SIEGE.extents), 0.0f); + zoneList = currentZone.getNodes(); - zoneList = currentZone.getNodes(); - - - for (Zone zone : zoneList) { + for (Zone zone : zoneList) { - if (zone.isContininent()) - continue; + if (zone.isContininent()) + continue; - if (Bounds.collide(treeBounds, zone.getBounds(), 0.0f)) - validLocation = false; - } + if (Bounds.collide(treeBounds, zone.getBounds(), 0.0f)) + validLocation = false; + } - treeBounds.release(); - return validLocation; + treeBounds.release(); + return validLocation; } } diff --git a/src/engine/jobs/CloseGateJob.java b/src/engine/jobs/CloseGateJob.java index 591a4d0a..2418835e 100644 --- a/src/engine/jobs/CloseGateJob.java +++ b/src/engine/jobs/CloseGateJob.java @@ -9,7 +9,8 @@ package engine.jobs; -import engine.Enum.RunegateType; +import engine.Enum; +import engine.Enum.PortalType; import engine.job.AbstractScheduleJob; import engine.objects.Building; import engine.objects.Runegate; @@ -18,9 +19,10 @@ import org.pmw.tinylog.Logger; public class CloseGateJob extends AbstractScheduleJob { private final Building building; - private final RunegateType portalType; + private final Enum.PortalType portalType; + + public CloseGateJob(Building building, PortalType portalType) { - public CloseGateJob(Building building, RunegateType portalType) { super(); this.building = building; this.portalType = portalType; @@ -34,7 +36,7 @@ public class CloseGateJob extends AbstractScheduleJob { return; } - Runegate.getRunegates()[RunegateType.getGateTypeFromUUID(building.getObjectUUID()).ordinal()].deactivatePortal(portalType); + Runegate._runegates.get(building.getObjectUUID()).deactivatePortal(portalType); } @Override diff --git a/src/engine/net/client/ClientMessagePump.java b/src/engine/net/client/ClientMessagePump.java index 70177a74..adbe76ee 100644 --- a/src/engine/net/client/ClientMessagePump.java +++ b/src/engine/net/client/ClientMessagePump.java @@ -97,9 +97,6 @@ public class ClientMessagePump implements NetMsgHandler { case SETSELECTEDOBECT: ClientMessagePump.targetObject((TargetObjectMsg) msg, origin); break; - case CITYDATA: - ClientMessagePump.MapData(s, origin); - break; /* * Chat @@ -351,62 +348,6 @@ public class ClientMessagePump implements NetMsgHandler { } - private static void MapData(Session s, ClientConnection origin) { - - Dispatch dispatch; -try{ - - - if (s == null || origin == null) - return; - - PlayerCharacter pc = s.getPlayerCharacter(); - - if (pc == null) - return; -boolean updateMine = false; -boolean updateCity = false; - -//do not update Cities and mines everytime you open map. only update them to client when something's changed. - long lastRefresh = pc.getTimeStamp("mineupdate"); - if (lastRefresh <= Mine.getLastChange()){ - pc.setTimeStamp("mineupdate", System.currentTimeMillis()); - updateMine = true; - } - long lastCityRefresh = pc.getTimeStamp("cityUpdate"); - if (lastCityRefresh <= City.lastCityUpdate){ - pc.setTimeStamp("cityUpdate", System.currentTimeMillis()); - updateCity = true; - } - - - - WorldObjectMsg wom = new WorldObjectMsg(s, false); - wom.updateMines(true); - wom.updateCities(updateCity); - dispatch = Dispatch.borrow(pc, wom); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - // } - - lastRefresh = pc.getTimeStamp("hotzoneupdate"); - if (lastRefresh <= WorldServer.getLastHZChange()) { - Zone hotzone = ZoneManager.getHotZone(); - if (hotzone != null) { - HotzoneChangeMsg hcm = new HotzoneChangeMsg(hotzone.getObjectType().ordinal(), hotzone.getObjectUUID()); - dispatch = Dispatch.borrow(pc, hcm); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - pc.setTimeStamp("hotzoneupdate", System.currentTimeMillis() - 100); - } - } - - WorldRealmMsg wrm = new WorldRealmMsg(); - dispatch = Dispatch.borrow(pc, wrm); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); -}catch(Exception e){ - e.printStackTrace(); -} - } - private static void WhoRequest(WhoRequestMsg msg, ClientConnection origin) { // Handle /who request @@ -2183,23 +2124,17 @@ boolean updateCity = false; Building rg = null; Vector3fImmutable rgLoc; - for (Runegate runegate : Runegate.getRunegates()) { - - if ((runegate.getGateType() == RunegateType.OBLIV) || - (runegate.getGateType() == RunegateType.CHAOS)) - continue; + for (Runegate runegate : Runegate._runegates.values()) { - for (Runegate thisGate : Runegate.getRunegates()) { - - rgLoc = thisGate.getGateType().getGateBuilding().getLoc(); + rgLoc = runegate.gateBuilding.getLoc(); float distanceSquaredToRunegate = player.getLoc().distanceSquared2D(rgLoc); if (distanceSquaredToRunegate < sqr(dist)) - rg = thisGate.getGateType().getGateBuilding(); + rg = runegate.gateBuilding; } - } + //nearest runegate found. teleport characterTarget if (rg != null) { diff --git a/src/engine/net/client/Protocol.java b/src/engine/net/client/Protocol.java index 6eee1d13..19cc0e4e 100644 --- a/src/engine/net/client/Protocol.java +++ b/src/engine/net/client/Protocol.java @@ -26,14 +26,14 @@ public enum Protocol { ACTIVATECHARTER(0x296C0B22, UseCharterMsg.class, null),// Use Guild Charter ACTIVATENPC(0xC9AAE81E, ActivateNPCMessage.class, ActivateNPCMsgHandler.class), ACTIVATEPLEDGE(0x5A694DC0, SwearInMsg.class, SwearInHandler.class), // Swear In - ADDFRIEND(0xCFA1C787,AddFriendMessage.class,null), - ALLIANCECHANGE(0x0E7D0B57, AllianceChangeMsg.class, AllianceChangeMsgHandler.class), // Remove From Allies/Enemies List + ADDFRIEND(0xCFA1C787, AddFriendMessage.class, null), + ALLIANCECHANGE(0x0E7D0B57, AllianceChangeMsg.class, AllianceChangeMsgHandler.class), // Remove From Allies/Enemies List ALLYENEMYLIST(0xAEA443FD, AllyEnemyListMsg.class, AllyEnemyListMsgHandler.class), - ARCCOMBATMODEATTACKING(0xD8B10579, SetCombatModeMsg.class, null), // Attack From Outside Combat Mode + ARCCOMBATMODEATTACKING(0xD8B10579, SetCombatModeMsg.class, null), // Attack From Outside Combat Mode ARCHOTZONECHANGE(0xDCFF196F, null, null), //change hotzone ARCIGNORELISTUPDATE(0x4B1B17C2, IgnoreListMsg.class, null), //req/show ignore list ARCLOGINNOTIFY(0x010FED87, ArcLoginNotifyMsg.class, ArcLoginNotifyMsgHandler.class), //Client Confirms entering world - ARCMINECHANGEPRODUCTION(0x1EAA993F, ArcMineChangeProductionMsg.class, ArcMineChangeProductionMsgHandler.class), + ARCMINECHANGEPRODUCTION(0x1EAA993F, ArcMineChangeProductionMsg.class, ArcMineChangeProductionMsgHandler.class), ARCMINETOWERCRESTUPDATE(0x34164D0D, null, null), ARCMINEWINDOWAVAILABLETIME(0x6C909DE7, ArcMineWindowAvailableTimeMsg.class, ArcMineWindowAvailableTimeHandler.class), ARCMINEWINDOWCHANGE(0x92B2148A, ArcMineWindowChangeMsg.class, MineWindowChangeHandler.class), @@ -62,7 +62,7 @@ public enum Protocol { CHANNELMUTE(0xC1BDC53A, ChatFilterMsg.class, ChannelMuteMsgHandler.class), //Chat Channels that are turned on CHARSELECTSCREEN(0x682C935D, null, null), // Character Selection Screen CHATCITY(0x9D402901, ChatCityMsg.class, null), // Chat Channel: /City - CHATCSR(0x14EBA1C3, ChatCSRMsg.class, null), //Chat Channel: CSR + CHATCSR(0x14EBA1C3, ChatCSRMsg.class, null), //Chat Channel: CSR CHATGROUP(0xA895B634, ChatGroupMsg.class, null), // Chat Channel: /group CHATGUILD(0xA9D92ED4, ChatGuildMsg.class, null), // Chat Channel: /guild CHATIC(0x00A75F35, ChatICMsg.class, null), // Chat Channel: /IC @@ -74,17 +74,17 @@ public enum Protocol { CHECKUNIQUEGUILD(0x689097D7, GuildCreationOptionsMsg.class, GuildCreationOptionsHandler.class), // Set Guild Name/Motto in Use Guild Charter CITYASSET(0x7cae1678, CityAssetMsg.class, null), CITYCHOICE(0x406610BB, CityChoiceMsg.class, CityChoiceMsgHandler.class), - CITYDATA(0xB8A947D4, WorldObjectMsg.class, null), //Realm Data - Optional(?) + CITYDATA(0xB8A947D4, CityDataMsg.class, CityDataHandler.class), CITYZONE(0x254947F2, CityZoneMsg.class, null), //For Creating City Object Clientside(Terraform)/Rename City. CLAIMASSET(0x948C62CC, ClaimAssetMsg.class, ClaimAssetMsgHandler.class), // ClaimAsset CLAIMGUILDTREE(0xFD1C6442, ClaimGuildTreeMsg.class, ClaimGuildTreeMsgHandler.class), - CLIENTADMINCOMMAND(0x624EAB5F, ClientAdminCommandMsg.class, null), //Admin Command - CLIENTUPDATEVAULT( 0x66EDBECD, UpdateVaultMsg.class, null), + CLIENTADMINCOMMAND(0x624EAB5F, ClientAdminCommandMsg.class, null), //Admin Command + CLIENTUPDATEVAULT(0x66EDBECD, UpdateVaultMsg.class, null), COMBATMODE(0xFE4BF353, ToggleCombatMsg.class, null), //Toggle Combat mode CONFIRMPROMOTE(0x153BB5F9, ConfirmPromoteMsg.class, null), COSTTOOPENBANK(0x135BE5E8, AckBankWindowOpenedMsg.class, null), // ACK Bank Window Opened CREATECHAR(0x5D18B5C8, CommitNewCharacterMsg.class, null), // Commit New Character, - CREATEPETITION(0xD489CFED, GuildCreationFinalizeMsg.class, GuildCreationFinalizeHandler.class), //Confirm guild creation + CREATEPETITION(0xD489CFED, GuildCreationFinalizeMsg.class, GuildCreationFinalizeHandler.class), //Confirm guild creation CUSTOMERPETITION(0x7F9D7D6D, PetitionReceivedMsg.class, null), DELETEOBJECT(0x57F069D8, DeleteItemMsg.class, null), //Delete Item from Inventory DESTROYBUILDING(0x3CB6FAD3, DestroyBuildingMsg.class, DestroyBuildingHandler.class), // Destroy Building @@ -95,8 +95,8 @@ public enum Protocol { EQUIP(0x3CB1AF8C, TransferItemFromInventoryToEquipMsg.class, null), // Transfer Item from Inventory to Equip EXPERIENCE(0xC57802A7, GrantExperienceMsg.class, null), //TODO rename once identified FORGETOBJECTS(0xE307A0E1, UnloadObjectsMsg.class, null), // Unload Objects - FRIENDACCEPT(0xCA297870,AcceptFriendMsg.class,FriendAcceptHandler.class), - FRIENDDECLINE(0xF08FC279,DeclineFriendMsg.class,FriendDeclineHandler.class), + FRIENDACCEPT(0xCA297870, AcceptFriendMsg.class, FriendAcceptHandler.class), + FRIENDDECLINE(0xF08FC279, DeclineFriendMsg.class, FriendDeclineHandler.class), FURNITURE(0xCE7FA503, FurnitureMsg.class, FurnitureHandler.class), GAMESERVERIPRESPONSE(0x6C95CF87, GameServerIPResponseMsg.class, null), // Game Server IP Response GLOBALCHANNELMESSAGE(0x2bf03fd2, null, null), @@ -109,7 +109,7 @@ public enum Protocol { GUILDMEMBERONLINE(0x7B79EB3A, GuildEnterWorldMsg.class, null), // Send Enter World Message to Guild GUILDRANKCHANGE(0x0DEFB21F, ChangeRankMsg.class, ChangeRankHandler.class), // Change Rank GUILDTREESTATUS(0x4B95FB85, GuildTreeStatusMsg.class, null), - HIRELINGSERVICE(0xD3D93322,HirelingServiceMsg.class,HirelingServiceMsgHandler.class), + HIRELINGSERVICE(0xD3D93322, HirelingServiceMsg.class, HirelingServiceMsgHandler.class), IGNORE(0xBD8881EE, IgnoreMsg.class, null), //client sent /ignore command INITIATETRADEHUDS(0x667D29D8, OpenTradeWindowMsg.class, null), // Open Trade Window INVITEGROUP(0x004A2012, GroupInviteMsg.class, GroupInviteHandler.class), // Send/Receive/Deny Group Invite @@ -164,11 +164,11 @@ public enum Protocol { RAISEATTR(0x5EEB65E0, ModifyStatMsg.class, null), // Modify Stat RANDOM(0xAC5D0135, RandomMsg.class, null), //RequestSend random roll READYTOENTER(0x490E4FE0, EnterWorldReceivedMsg.class, null), //Client Ack Receive Enter World - REALMDATA(0x2399B775, null, null), //Realm Data - Optional(?) + REALMDATA(0x2399B775, null, null), //Realm Data - Optional(?) RECOMMENDNATION(0x6D4579E9, RecommendNationMsg.class, RecommendNationMsgHandler.class), // Recommend as Ally/Enemy, error RECYCLEPOWER(0x24033B67, RecyclePowerMsg.class, null), //Unlock power for reUse REMOVECHAR(0x5D3F9739, DeleteCharacterMsg.class, null), // Delete Character - REMOVEFRIEND(0xE0D5DB42,RemoveFriendMessage.class,RemoveFriendHandler.class), + REMOVEFRIEND(0xE0D5DB42, RemoveFriendMessage.class, RemoveFriendHandler.class), REPAIRBUILDING(0xAF8C2560, RepairBuildingMsg.class, RepairBuildingMsgHandler.class), REPAIROBJECT(0x782219CE, RepairMsg.class, null), //Repair Window Req/Ack, RepairObject item Req/Ack REQUESTCONTENTS(0xA786B0A2, LootWindowRequestMsg.class, null), // MoveObjectToContainer Window Request @@ -179,7 +179,7 @@ public enum Protocol { REQUESTTOTRADE(0x4D84259B, TradeRequestMsg.class, null), // Trade Request REQUESTTRADECANCEL(0xCB0C5735, RejectTradeRequestMsg.class, null), // Reject RequestToTrade REQUESTTRADEOK(0xFFD29841, AcceptTradeRequestMsg.class, null), // Accept Trade Request - RESETAFTERDEATH(0xFDCBB98F,RespawnMsg.class, null), //Respawn Request/Response + RESETAFTERDEATH(0xFDCBB98F, RespawnMsg.class, null), //Respawn Request/Response ROTATEMSG(0x57F2088E, RotateObjectMsg.class, null), SAFEMODE(0x9CF3922A, SafeModeMsg.class, null), //Tell client they're in safe mode SCALEOBJECT(0xE2B392D9, null, null), // Adjust scale of object @@ -210,7 +210,7 @@ public enum Protocol { TAXCITY(0xCD41EAA6, TaxCityMsg.class, TaxCityMsgHandler.class), TAXRESOURCES(0x4AD458AF, TaxResourcesMsg.class, TaxResourcesMsgHandler.class), TELEPORT(0x23E726EA, TeleportToPointMsg.class, null), // Teleport to point - TERRITORYCHANGE(0x6B388C8C,TerritoryChangeMessage.class, null), //Hey rich, look what I found? :) + TERRITORYCHANGE(0x6B388C8C, TerritoryChangeMessage.class, null), //Hey rich, look what I found? :) TOGGLESITSTAND(0x624F3C0F, ToggleSitStandMsg.class, null), //Toggle Sit/Stand TRADEADDGOLD(0x654ACB45, AddGoldToTradeWindowMsg.class, null), // Add Gold to Trade Window TRADEADDOBJECT(0x55D363E9, AddItemToTradeWindowMsg.class, null), // Add an Item to the Trade Window @@ -227,7 +227,7 @@ public enum Protocol { TRANSFERITEMFROMVAULTTOINVENTORY(0x0119A64D, TransferItemFromVaultToInventoryMsg.class, null), // Transfer Item from Vault to Inventory TRANSFERITEMTOBANK(0xD48C46FA, TransferItemFromInventoryToBankMsg.class, null), // Transfer Item from Inventory to Bank UNEQUIP(0xC6BFB907, TransferItemFromEquipToInventoryMsg.class, null), // Transfer Item from Equip to Inventory - UNKNOWN(0x238C9259, UnknownMsg.class,null), + UNKNOWN(0x238C9259, UnknownMsg.class, null), UPDATECHARORMOB(0xB6D78961, null, null), UPDATECLIENTALLIANCES(0xF3FEB5D4, null, GuildUnknownHandler.class), //AlliancesMsg UPDATECLIENTINVENTORIES(0xE66F533D, UpdateInventoryMsg.class, null), //Update player inventory @@ -247,14 +247,14 @@ public enum Protocol { WEIGHTINVENTORY(0xF1B6A85C, LootWindowResponseMsg.class, null), // MoveObjectToContainer Window Response WHOREQUEST(0xF431CCE9, WhoRequestMsg.class, null), // Request /who WHORESPONSE(0xD7C36568, WhoResponseMsg.class, null), // Response /who - REQUESTBALLLIST(0xE366FF64,RequestBallListMessage.class,RequestBallListHandler.class), - SENDBALLENTRY(0xAC2B5EDC,SendBallEntryMessage.class,SendBallEntryHandler.class), - UNKNOWN1(-263523523, Unknown1Msg.class,null), - DROPGOLD(1461654160,DropGoldMsg.class,null); + REQUESTBALLLIST(0xE366FF64, RequestBallListMessage.class, RequestBallListHandler.class), + SENDBALLENTRY(0xAC2B5EDC, SendBallEntryMessage.class, SendBallEntryHandler.class), + UNKNOWN1(-263523523, Unknown1Msg.class, null), + DROPGOLD(1461654160, DropGoldMsg.class, null); public int opcode; - private Class message; - private Class handlerClass; + private final Class message; + private final Class handlerClass; public Constructor constructor; public AbstractClientMsgHandler handler; @@ -275,7 +275,7 @@ public enum Protocol { } } - // Create instance of message handler for incoming protocol messages + // Create instance of message handler for incoming protocol messages if (this.handlerClass != null) { try { @@ -286,7 +286,7 @@ public enum Protocol { } } - private static HashMap _protocolMsgByOpcode = new HashMap<>(); + private static final HashMap _protocolMsgByOpcode = new HashMap<>(); public static Protocol getByOpcode(int opcode) { @@ -302,37 +302,37 @@ public enum Protocol { for (Protocol protocol : Protocol.values()) { - if (_protocolMsgByOpcode.containsKey(protocol.opcode)){ - Logger.error("Duplicate opcodes for " + protocol.name() + " and " + _protocolMsgByOpcode.get(protocol.opcode).name()); - } + if (_protocolMsgByOpcode.containsKey(protocol.opcode)) { + Logger.error("Duplicate opcodes for " + protocol.name() + " and " + _protocolMsgByOpcode.get(protocol.opcode).name()); + } _protocolMsgByOpcode.put(protocol.opcode, protocol); } } -public static int FindNextValidOpcode(ByteBufferReader reader){ - int startPos = reader.position(); - int bytesLeft = reader.remaining(); + public static int FindNextValidOpcode(ByteBufferReader reader) { + int startPos = reader.position(); + int bytesLeft = reader.remaining(); - if (bytesLeft < 4) - return startPos; - int nextPos = startPos; - for (int i = 1; i< bytesLeft; i++ ){ - reader.position(nextPos); - if (reader.remaining() < 4) - return reader.position(); - int newOpcode = reader.getInt(); + if (bytesLeft < 4) + return startPos; + int nextPos = startPos; + for (int i = 1; i < bytesLeft; i++) { + reader.position(nextPos); + if (reader.remaining() < 4) + return reader.position(); + int newOpcode = reader.getInt(); - Protocol foundProtocol = Protocol.getByOpcode(newOpcode); - if (foundProtocol.equals(Protocol.NONE)){ - nextPos += 1; - continue; - } + Protocol foundProtocol = Protocol.getByOpcode(newOpcode); + if (foundProtocol.equals(Protocol.NONE)) { + nextPos += 1; + continue; + } - //found opcode. return position - 4 to rewind back to start of opcode, so we can handle it. - return reader.position() - 4; - } + //found opcode. return position - 4 to rewind back to start of opcode, so we can handle it. + return reader.position() - 4; + } - return startPos; -} + return startPos; + } } diff --git a/src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java b/src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java index 63d4ac49..c72b5cb8 100644 --- a/src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java +++ b/src/engine/net/client/handlers/ArcLoginNotifyMsgHandler.java @@ -1,5 +1,6 @@ package engine.net.client.handlers; +import engine.Enum; import engine.Enum.DispatchChannel; import engine.exception.MsgSendException; import engine.gameManager.*; @@ -125,10 +126,9 @@ public class ArcLoginNotifyMsgHandler extends AbstractClientMsgHandler { } //Send current hotzone - Zone hotzone = ZoneManager.getHotZone(); - if (hotzone != null) { - HotzoneChangeMsg hcm = new HotzoneChangeMsg(hotzone.getObjectType().ordinal(), hotzone.getObjectUUID()); + if (ZoneManager.hotZone != null) { + HotzoneChangeMsg hcm = new HotzoneChangeMsg(Enum.GameObjectType.Zone.ordinal(), ZoneManager.hotZone.getObjectUUID()); Dispatch dispatch = Dispatch.borrow(player, hcm); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); } diff --git a/src/engine/net/client/handlers/ArcMineChangeProductionMsgHandler.java b/src/engine/net/client/handlers/ArcMineChangeProductionMsgHandler.java index c2198b7e..67e42527 100644 --- a/src/engine/net/client/handlers/ArcMineChangeProductionMsgHandler.java +++ b/src/engine/net/client/handlers/ArcMineChangeProductionMsgHandler.java @@ -7,7 +7,6 @@ import engine.net.DispatchMessage; import engine.net.client.ClientConnection; import engine.net.client.msg.ArcMineChangeProductionMsg; import engine.net.client.msg.ClientNetMsg; -import engine.net.client.msg.KeepAliveServerClientMsg; import engine.objects.GuildStatusController; import engine.objects.Mine; import engine.objects.PlayerCharacter; @@ -21,49 +20,48 @@ import engine.objects.Resource; public class ArcMineChangeProductionMsgHandler extends AbstractClientMsgHandler { - public ArcMineChangeProductionMsgHandler() { - super(ArcMineChangeProductionMsg.class); - } + public ArcMineChangeProductionMsgHandler() { + super(ArcMineChangeProductionMsg.class); + } - @Override - protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { - - PlayerCharacter playerCharacter = origin.getPlayerCharacter(); - ArcMineChangeProductionMsg changeProductionMsg = (ArcMineChangeProductionMsg) baseMsg; + @Override + protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { - if (playerCharacter == null) - return true; + PlayerCharacter playerCharacter = origin.getPlayerCharacter(); + ArcMineChangeProductionMsg changeProductionMsg = (ArcMineChangeProductionMsg) baseMsg; - //TODO verify this against the warehouse? + if (playerCharacter == null) + return true; - if (GuildStatusController.isInnerCouncil(playerCharacter.getGuildStatus()) == false) // is this only GL? - return true; + //TODO verify this against the warehouse? - Mine mine = Mine.getMine(changeProductionMsg.getMineID()); + if (GuildStatusController.isInnerCouncil(playerCharacter.getGuildStatus()) == false) // is this only GL? + return true; - if (mine == null) - return true; + Mine mine = Mine.getMine(changeProductionMsg.getMineID()); - //make sure mine belongs to guild + if (mine == null) + return true; - if (mine.getOwningGuild().isEmptyGuild() || - mine.getOwningGuild().getObjectUUID() != playerCharacter.getGuild().getObjectUUID()) - return true; + //make sure mine belongs to guild - //make sure valid resource + if (mine.getOwningGuild().isEmptyGuild() || + mine.getOwningGuild().getObjectUUID() != playerCharacter.getGuild().getObjectUUID()) + return true; - Resource resource = Resource.resourceByHash.get(changeProductionMsg.getResourceHash()); + //make sure valid resource - if (resource == null) - return true; + Resource resource = Resource.resourceByHash.get(changeProductionMsg.getResourceHash()); - //update resource + if (resource == null) + return true; - mine.changeProductionType(resource); - Mine.setLastChange(System.currentTimeMillis()); - Dispatch dispatch = Dispatch.borrow(playerCharacter, changeProductionMsg); - DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); - return true; - } + //update resource + + mine.changeProductionType(resource); + Dispatch dispatch = Dispatch.borrow(playerCharacter, changeProductionMsg); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + return true; + } } \ No newline at end of file diff --git a/src/engine/net/client/handlers/CityDataHandler.java b/src/engine/net/client/handlers/CityDataHandler.java new file mode 100644 index 00000000..928a6964 --- /dev/null +++ b/src/engine/net/client/handlers/CityDataHandler.java @@ -0,0 +1,82 @@ +package engine.net.client.handlers; + +import engine.Enum; +import engine.Enum.DispatchChannel; +import engine.exception.MsgSendException; +import engine.gameManager.SessionManager; +import engine.gameManager.ZoneManager; +import engine.net.Dispatch; +import engine.net.DispatchMessage; +import engine.net.client.ClientConnection; +import engine.net.client.msg.*; +import engine.objects.City; +import engine.objects.PlayerCharacter; +import engine.session.Session; + +/* + * @Author: + * @Summary: Processes application protocol message which displays + * the map interface. (Zones, Cities, Realms, Hot-zones) + */ + +public class CityDataHandler extends AbstractClientMsgHandler { + + public CityDataHandler() { + super(KeepAliveServerClientMsg.class); + } + + @Override + protected boolean _handleNetMsg(ClientNetMsg baseMsg, ClientConnection origin) throws MsgSendException { + + boolean updateCities = false; + Session playerSession; + PlayerCharacter playerCharacter; + Dispatch dispatch; + + playerCharacter = origin.getPlayerCharacter(); + + if (playerCharacter == null) + return true; + + // Session is needed as param for worldObjectMsg. + + playerSession = SessionManager.getSession(playerCharacter); + + if (playerSession == null) + return true; + + // No reason to serialize cities everytime map is + // opened. Wait until something has changed. + // This does not work for mines. + + if (playerCharacter.getTimeStamp("cityUpdate") <= City.lastCityUpdate) { + playerCharacter.setTimeStamp("cityUpdate", System.currentTimeMillis()); + updateCities = true; + } + + CityDataMsg cityDataMsg = new CityDataMsg(SessionManager.getSession(playerCharacter), false); + cityDataMsg.updateMines(true); + cityDataMsg.updateCities(updateCities); + + dispatch = Dispatch.borrow(playerCharacter, cityDataMsg); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + + // If the hotZone has changed then update the client's map accordingly. + + if (playerCharacter.getTimeStamp("hotzoneupdate") <= ZoneManager.hotZoneLastUpdate.toEpochMilli() && ZoneManager.hotZone != null) { + HotzoneChangeMsg hotzoneChangeMsg = new HotzoneChangeMsg(Enum.GameObjectType.Zone.ordinal(), ZoneManager.hotZone.getObjectUUID()); + dispatch = Dispatch.borrow(playerCharacter, hotzoneChangeMsg); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + playerCharacter.setTimeStamp("hotzoneupdate", System.currentTimeMillis() - 100); + } + + // Serialize the realms for this map + + WorldRealmMsg worldRealmMsg = new WorldRealmMsg(); + dispatch = Dispatch.borrow(playerCharacter, worldRealmMsg); + DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.SECONDARY); + + return true; + } + +} \ No newline at end of file diff --git a/src/engine/net/client/handlers/GuildCreationFinalizeHandler.java b/src/engine/net/client/handlers/GuildCreationFinalizeHandler.java index 57295aa1..29b4e055 100644 --- a/src/engine/net/client/handlers/GuildCreationFinalizeHandler.java +++ b/src/engine/net/client/handlers/GuildCreationFinalizeHandler.java @@ -54,6 +54,7 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler { GuildCreationFinalizeMsg msg; Enum.GuildType charterType; Guild newGuild; + Guild playerGuild; ItemBase itemBase; Item charter; Dispatch dispatch; @@ -61,9 +62,9 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler { msg = (GuildCreationFinalizeMsg) baseMsg; player = SessionManager.getPlayerCharacter(origin); + playerGuild = player.getGuild(); - boolean isGuildLeader = GuildStatusController.isGuildLeader(player.getGuildStatus()); - if (GuildStatusController.isGuildLeader(player.getGuildStatus()) || player.getGuild() != null && player.getGuild().getGuildLeaderUUID() == player.getObjectUUID()) { + if (playerGuild.isEmptyGuild() == false && player.getGuild().getGuildLeaderUUID() == player.getObjectUUID()) { ErrorPopupMsg.sendErrorPopup(player, GuildManager.MUST_LEAVE_GUILD); return true; } @@ -77,30 +78,22 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler { return true; } - - itemBase = charter.getItemBase(); - // Item must be a valid charterType (type 10 in db) if (itemBase == null || (itemBase.getType().equals(ItemType.GUILDCHARTER) == false)) { ErrorPopupMsg.sendErrorPopup(player, GuildManager.NO_CHARTER_FOUND); return true; } - charterType = Enum.GuildType.getGuildTypeFromCharter(itemBase); - + charterType = Enum.GuildType.getGuildTypeFromCharter(itemBase); if (charterType == null){ ErrorPopupMsg.sendErrorPopup(player, GuildManager.NO_CHARTER_FOUND); return true; } - - - - //Validate Guild Tags if (!msg.getGuildTag().isValid()) { @@ -110,11 +103,9 @@ public class GuildCreationFinalizeHandler extends AbstractClientMsgHandler { // Validation passes. Leave current guild and create new one. - if (player.getGuild() != null && player.getGuild().getObjectUUID() != 0) + if (player.getGuild() != null && player.getGuild().isEmptyGuild() == false) player.getGuild().removePlayer(player,GuildHistoryType.LEAVE); - - int leadershipType = ((msg.getICVoteFlag() << 1) | msg.getMemberVoteFlag()); newGuild = new Guild( msg.getName(),null, charterType.ordinal(), diff --git a/src/engine/net/client/handlers/PlaceAssetMsgHandler.java b/src/engine/net/client/handlers/PlaceAssetMsgHandler.java index 98e225d1..9ea4bf12 100644 --- a/src/engine/net/client/handlers/PlaceAssetMsgHandler.java +++ b/src/engine/net/client/handlers/PlaceAssetMsgHandler.java @@ -436,7 +436,9 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { if (!building.getGuild().equals(serverCity.getGuild()) && !building.getGuild().equals(serverCity.getBane().getOwner().getGuild())) continue; - + if (building.getRank() < 0) { + continue; + } if (building.getGuild().equals(serverCity.getGuild())) defenderBuildings.add(building); @@ -982,11 +984,7 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { return false; } - RealmType realmType = RealmType.getRealmTypeByUUID(serverRealm.getRealmID()); - - if ( - (realmType.equals(RealmType.MAELSTROM)) || - (realmType.equals(RealmType.OBLIVION))) { + if (serverRealm == null || serverRealm.getCanPlaceCities() == false) { PlaceAssetMsg.sendPlaceAssetError(origin, 57, playerCharacter.getName()); // No building may be placed within this territory return false; } @@ -1238,8 +1236,6 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { private static boolean validateBuildingPlacement(Zone serverZone, PlaceAssetMsg msg, ClientConnection origin, PlayerCharacter player, PlacementInfo placementInfo) { - RealmType currentRealm; - if (serverZone.isPlayerCity() == false) { PlaceAssetMsg.sendPlaceAssetError(origin, 52, player.getName()); return false; @@ -1293,11 +1289,11 @@ public class PlaceAssetMsgHandler extends AbstractClientMsgHandler { return false; } - currentRealm = RealmType.getRealmTypeByUUID(RealmMap.getRealmIDAtLocation(player.getLoc())); + Realm serverRealm = RealmMap.getRealmAtLocation(player.getLoc()); + + // Cannot place buildings on seafloor or other restricted realms - if ( - (currentRealm.equals(RealmType.MAELSTROM)) || - (currentRealm.equals(RealmType.OBLIVION))) { + if (serverRealm == null || serverRealm.getCanPlaceCities() == false) { PlaceAssetMsg.sendPlaceAssetError(origin, 57, player.getName()); // No building may be placed within this territory return false; } diff --git a/src/engine/net/client/handlers/RequestEnterWorldHandler.java b/src/engine/net/client/handlers/RequestEnterWorldHandler.java index 4724439f..ddd017c5 100644 --- a/src/engine/net/client/handlers/RequestEnterWorldHandler.java +++ b/src/engine/net/client/handlers/RequestEnterWorldHandler.java @@ -99,7 +99,7 @@ public class RequestEnterWorldHandler extends AbstractClientMsgHandler { } // Object Data - WorldObjectMsg wom = new WorldObjectMsg(session, true); + CityDataMsg wom = new CityDataMsg(session, true); dispatch = Dispatch.borrow(player, wom); DispatchMessage.dispatchMsgDispatch(dispatch, DispatchChannel.PRIMARY); diff --git a/src/engine/net/client/msg/CityDataMsg.java b/src/engine/net/client/msg/CityDataMsg.java new file mode 100644 index 00000000..c70ca624 --- /dev/null +++ b/src/engine/net/client/msg/CityDataMsg.java @@ -0,0 +1,274 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// Magicbane Emulator Project © 2013 - 2022 +// www.magicbane.com + + +package engine.net.client.msg; + +import engine.Enum; +import engine.gameManager.DbManager; +import engine.net.AbstractConnection; +import engine.net.ByteBufferReader; +import engine.net.ByteBufferWriter; +import engine.net.Network; +import engine.net.client.Protocol; +import engine.objects.AbstractGameObject; +import engine.objects.City; +import engine.objects.Mine; +import engine.objects.Runegate; +import engine.session.Session; +import org.pmw.tinylog.Logger; + +import java.nio.ByteBuffer; +import java.util.ArrayList; +import java.util.concurrent.ConcurrentHashMap; + +public class CityDataMsg extends ClientNetMsg { + + private Session s; + private final boolean forEnterWorld; + private static ByteBuffer cachedEnterWorld; + private static long cachedExpireTime; + + public static final long wdComp = 0xFF00FF0000000003L; + private static final byte ver = 1; + + private boolean updateCities = false; + private boolean updateRunegates = false; + private boolean updateMines = false; + + /** + * This is the general purpose constructor. + * + * @param s Session + * @param forEnterWorld boolean flag + */ + public CityDataMsg(Session s, boolean forEnterWorld) { + super(Protocol.CITYDATA); + this.s = s; + this.forEnterWorld = forEnterWorld; + } + + public CityDataMsg(boolean updateCities, boolean updateRunegates, boolean updateMines) { + super(Protocol.CITYDATA); + this.s = null; + this.forEnterWorld = false; + this.updateCities = updateCities; + this.updateRunegates = updateRunegates; + this.updateMines = updateMines; + } + + /** + * This constructor is used by NetMsgFactory. It attempts to deserialize the + * ByteBuffer into a message. If a BufferUnderflow occurs (based on reading + * past the limit) then this constructor Throws that Exception to the + * caller. + */ + public CityDataMsg(AbstractConnection origin, ByteBufferReader reader) { + super(Protocol.CITYDATA, origin, reader); + this.forEnterWorld = false; + } + + @Override + protected int getPowerOfTwoBufferSize() { + return (18); // 2^14 == 16384 + } + + /** + * Serializes the subclass specific items to the supplied NetMsgWriter. + */ + @Override + protected void _serialize(ByteBufferWriter writer) { + if (this.forEnterWorld) + serializeForEnterWorld(writer); + else + serializeForMapUpdate(writer); + } + + /** + * Specific use serializer + * + * @param writer + */ + private void serializeForMapUpdate(ByteBufferWriter writer) { + + //Handle City updates + + if (this.updateCities) { + writer.put((byte) 0); + ArrayList cityList = new ArrayList<>(); + ConcurrentHashMap map = DbManager.getMap(Enum.GameObjectType.City); + if (map != null) { + for (AbstractGameObject ago : map.values()) + if (ago.getObjectType().equals(Enum.GameObjectType.City)) + cityList.add((City) ago); + + writer.putInt(cityList.size()); + for (City city : cityList) { + City.serializeForClientMsg(city, writer); + } + + } else { + Logger.error("missing city map"); + writer.putInt(0); + } + } else + writer.put((byte) 1); + + + //Handle Runegate updates + if (this.updateRunegates) { + + writer.put((byte) 0); + writer.putInt(Runegate._runegates.values().size()); + + for (Runegate runegate : Runegate._runegates.values()) { + runegate._serializeForEnterWorld(writer); + } + } else + writer.put((byte) 1); + + + //Handle Mine updates + try { + if (this.updateMines) { + ArrayList mineList = new ArrayList<>(); + for (Mine toAdd : Mine.mineMap.keySet()) { + mineList.add(toAdd); + } + + writer.putInt(mineList.size()); + for (Mine mine : mineList) + Mine.serializeForClientMsg(mine, writer); + } else + writer.putInt(0); + } catch (Exception e) { + Logger.error(e); + } + + + writer.put((byte) 0); // PAD + } + + /** + * Specific use serializer + * + * @param writer + */ + private void serializeForEnterWorld(ByteBufferWriter writer) { + if (s == null || s.getPlayerCharacter() == null) + return; + + long startT = System.currentTimeMillis(); + + if (cachedEnterWorld == null) { + // Never before been cached, so init stuff + cachedEnterWorld = Network.byteBufferPool.getBuffer(19); + cachedExpireTime = 0L; + } + + //Check to see if its time to renew cache. + if (cachedExpireTime < System.currentTimeMillis()) { + synchronized (cachedEnterWorld) { + CityDataMsg.attemptSerializeForEnterWorld(cachedEnterWorld); + } + cachedExpireTime = startT + 60000; + } + + writer.putBB(cachedEnterWorld); + + } + + private static void attemptSerializeForEnterWorld(ByteBuffer bb) { + bb.clear(); + ByteBufferWriter temp = new ByteBufferWriter(bb); + temp.put((byte) 0); // PAD + + + ArrayList cityList = new ArrayList<>(); + ConcurrentHashMap map = DbManager.getMap(Enum.GameObjectType.City); + for (AbstractGameObject ago : map.values()) + + if (ago.getObjectType().equals(Enum.GameObjectType.City)) + cityList.add((City) ago); + + temp.putInt(cityList.size()); + + for (City city : cityList) + City.serializeForClientMsg(city, temp); + temp.put((byte) 0); // PAD + + // Serialize runegates + + temp.putInt(Runegate._runegates.values().size()); + + for (Runegate runegate : Runegate._runegates.values()) { + runegate._serializeForEnterWorld(temp); + } + + ArrayList mineList = new ArrayList<>(); + for (Mine toAdd : Mine.mineMap.keySet()) { + mineList.add(toAdd); + } + + temp.putInt(mineList.size()); + for (Mine mine : mineList) + Mine.serializeForClientMsg(mine, temp); + temp.put((byte) 0); // PAD + } + + /** + * Deserializes the subclass specific items from the supplied NetMsgReader. + */ + @Override + protected void _deserialize(ByteBufferReader reader) { + // Client only sends 11 bytes. + + byte type = reader.get(); + + if (type == 1) { + reader.get(); + reader.get(); + reader.getInt(); + + } else { + reader.get(); + reader.getInt(); + reader.get(); + reader.getInt(); + } + + } + + /** + * @return the s + */ + public Session getS() { + return s; + } + + /** + * @return the forEnterWorld + */ + public boolean isForEnterWorld() { + return forEnterWorld; + } + + public void updateCities(boolean value) { + this.updateCities = value; + } + + public void updateRunegates(boolean value) { + this.updateRunegates = value; + } + + public void updateMines(boolean value) { + this.updateMines = value; + } + + +} diff --git a/src/engine/net/client/msg/HotzoneChangeMsg.java b/src/engine/net/client/msg/HotzoneChangeMsg.java index c39f218d..9fc1a665 100644 --- a/src/engine/net/client/msg/HotzoneChangeMsg.java +++ b/src/engine/net/client/msg/HotzoneChangeMsg.java @@ -10,17 +10,24 @@ package engine.net.client.msg; -import engine.math.FastMath; +import engine.gameManager.ConfigManager; +import engine.gameManager.ZoneManager; import engine.net.AbstractConnection; import engine.net.ByteBufferReader; import engine.net.ByteBufferWriter; import engine.net.client.Protocol; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; + public class HotzoneChangeMsg extends ClientNetMsg { private int zoneType; private int zoneID; + private int secondsRemaining; /** * This is the general purpose constructor. @@ -29,6 +36,11 @@ public class HotzoneChangeMsg extends ClientNetMsg { super(Protocol.ARCHOTZONECHANGE); this.zoneType = zoneType; this.zoneID = zoneID; + + int hotZoneDuration = Integer.parseInt(ConfigManager.MB_HOTZONE_DURATION.getValue()); + Instant currentInstant = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant(); + secondsRemaining = (int) Duration.between(currentInstant, ZoneManager.hotZoneLastUpdate.plusSeconds(hotZoneDuration * 3600)).getSeconds(); + } /** @@ -49,7 +61,7 @@ public class HotzoneChangeMsg extends ClientNetMsg { protected void _serialize(ByteBufferWriter writer) { writer.putInt(this.zoneType); writer.putInt(this.zoneID); - writer.putInt(FastMath.secondsUntilNextHour()); + writer.putInt(secondsRemaining); } /** diff --git a/src/engine/net/client/msg/WorldDataMsg.java b/src/engine/net/client/msg/WorldDataMsg.java index 119163c5..c9391d84 100644 --- a/src/engine/net/client/msg/WorldDataMsg.java +++ b/src/engine/net/client/msg/WorldDataMsg.java @@ -80,7 +80,7 @@ public class WorldDataMsg extends ClientNetMsg { writer.putInt(getTotalMapSize(root) + 1); Zone.serializeForClientMsg(root,writer); - Zone hotzone = ZoneManager.getHotZone(); + Zone hotzone = ZoneManager.hotZone;; if (hotzone == null) writer.putLong(0L); diff --git a/src/engine/net/client/msg/WorldObjectMsg.java b/src/engine/net/client/msg/WorldObjectMsg.java deleted file mode 100644 index 403563e5..00000000 --- a/src/engine/net/client/msg/WorldObjectMsg.java +++ /dev/null @@ -1,282 +0,0 @@ -// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . -// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· -// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ -// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ -// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ -// Magicbane Emulator Project © 2013 - 2022 -// www.magicbane.com - - -package engine.net.client.msg; - -import engine.Enum; -import engine.Enum.RunegateType; -import engine.gameManager.DbManager; -import engine.net.AbstractConnection; -import engine.net.ByteBufferReader; -import engine.net.ByteBufferWriter; -import engine.net.Network; -import engine.net.client.Protocol; -import engine.objects.AbstractGameObject; -import engine.objects.City; -import engine.objects.Mine; -import engine.objects.Runegate; -import engine.session.Session; -import org.pmw.tinylog.Logger; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.concurrent.ConcurrentHashMap; - -public class WorldObjectMsg extends ClientNetMsg { - - private Session s; - private boolean forEnterWorld; - private static ByteBuffer cachedEnterWorld; - private static long cachedExpireTime; - - public static final long wdComp = 0xFF00FF0000000003L; - private static byte ver = 1; - - private boolean updateCities = false; - private boolean updateRunegates = false; - private boolean updateMines = false; - - /** - * This is the general purpose constructor. - * - * @param s - * Session - * @param forEnterWorld - * boolean flag - */ - public WorldObjectMsg(Session s, boolean forEnterWorld) { - super(Protocol.CITYDATA); - this.s = s; - this.forEnterWorld = forEnterWorld; - } - - public WorldObjectMsg(boolean updateCities, boolean updateRunegates, boolean updateMines) { - super(Protocol.CITYDATA); - this.s = null; - this.forEnterWorld = false; - this.updateCities = updateCities; - this.updateRunegates = updateRunegates; - this.updateMines = updateMines; - } - - /** - * This constructor is used by NetMsgFactory. It attempts to deserialize the - * ByteBuffer into a message. If a BufferUnderflow occurs (based on reading - * past the limit) then this constructor Throws that Exception to the - * caller. - */ - public WorldObjectMsg(AbstractConnection origin, ByteBufferReader reader) - { - super(Protocol.CITYDATA, origin, reader); - this.forEnterWorld = false; - } - - @Override - protected int getPowerOfTwoBufferSize() { - return (18); // 2^14 == 16384 - } - - /** - * Serializes the subclass specific items to the supplied NetMsgWriter. - */ - @Override - protected void _serialize(ByteBufferWriter writer) { - if (this.forEnterWorld) - serializeForEnterWorld(writer); - else - serializeForMapUpdate(writer); - } - - /** - * Specific use serializer - * - * @param writer - */ - private void serializeForMapUpdate(ByteBufferWriter writer) { - - //Handle City updates - - if (this.updateCities) { - writer.put((byte) 0); - ArrayList cityList = new ArrayList<>(); - ConcurrentHashMap map = DbManager.getMap(Enum.GameObjectType.City); - if (map != null) { - for (AbstractGameObject ago : map.values()) - if (ago.getObjectType().equals(Enum.GameObjectType.City)) - cityList.add((City)ago); - - writer.putInt(cityList.size()); - for (City city: cityList){ - City.serializeForClientMsg(city, writer); - } - - } else { - Logger.error("missing city map"); - writer.putInt(0); - } - } else - writer.put((byte) 1); - - - //Handle Runegate updates - if (this.updateRunegates) { - - writer.put((byte) 0); - writer.putInt(RunegateType.values().length); - - for(RunegateType gateType : engine.Enum.RunegateType.values()) { - - Runegate.getRunegates()[gateType.ordinal()]._serializeForEnterWorld(writer); - } - } else - writer.put((byte) 1); - - - //Handle Mine updates - try{ - if (this.updateMines) { - ArrayList mineList = new ArrayList<>(); - for (Mine toAdd: Mine.mineMap.keySet()){ - mineList.add(toAdd); - } - - writer.putInt(mineList.size()); - for (Mine mine: mineList) - Mine.serializeForClientMsg(mine, writer); - } else - writer.putInt(0); - }catch(Exception e){ - Logger.error(e); - } - - - - writer.put((byte) 0); // PAD - } - - /** - * Specific use serializer - * - * @param writer - */ - private void serializeForEnterWorld(ByteBufferWriter writer) { - if (s == null || s.getPlayerCharacter() == null) - return; - - long startT = System.currentTimeMillis(); - - if (cachedEnterWorld == null) { - // Never before been cached, so init stuff - cachedEnterWorld = Network.byteBufferPool.getBuffer(19); - cachedExpireTime = 0L; - } - - //Check to see if its time to renew cache. - if (cachedExpireTime < System.currentTimeMillis()) { - synchronized (cachedEnterWorld) { - WorldObjectMsg.attemptSerializeForEnterWorld(cachedEnterWorld); - } - cachedExpireTime = startT + 60000; - } - - writer.putBB(cachedEnterWorld); - - } - - private static void attemptSerializeForEnterWorld(ByteBuffer bb) { - bb.clear(); - ByteBufferWriter temp = new ByteBufferWriter(bb); - temp.put((byte) 0); // PAD - - - ArrayList cityList = new ArrayList<>(); - ConcurrentHashMap map = DbManager.getMap(Enum.GameObjectType.City); - for (AbstractGameObject ago : map.values()) - - if (ago.getObjectType().equals(Enum.GameObjectType.City)) - cityList.add((City)ago); - - temp.putInt(cityList.size()); - - for (City city: cityList) - City.serializeForClientMsg(city, temp); - temp.put((byte) 0); // PAD - - // Serialize runegates - - temp.putInt(RunegateType.values().length); - - for(RunegateType gateType : engine.Enum.RunegateType.values()) { - - Runegate.getRunegates()[gateType.ordinal()]._serializeForEnterWorld(temp); - } - - ArrayList mineList = new ArrayList<>(); - for (Mine toAdd : Mine.mineMap.keySet()){ - mineList.add(toAdd); - } - - temp.putInt(mineList.size()); - for (Mine mine: mineList) - Mine.serializeForClientMsg(mine, temp); - temp.put((byte) 0); // PAD - } - - /** - * Deserializes the subclass specific items from the supplied NetMsgReader. - */ - @Override - protected void _deserialize(ByteBufferReader reader) - { - // Client only sends 11 bytes. - - byte type = reader.get(); - - if (type == 1){ - reader.get(); - reader.get(); - reader.getInt(); - - }else{ - reader.get(); - reader.getInt(); - reader.get(); - reader.getInt(); - } - - } - - /** - * @return the s - */ - public Session getS() { - return s; - } - - /** - * @return the forEnterWorld - */ - public boolean isForEnterWorld() { - return forEnterWorld; - } - - public void updateCities(boolean value) { - this.updateCities = value; - } - - public void updateRunegates(boolean value) { - this.updateRunegates = value; - } - - public void updateMines(boolean value) { - this.updateMines = value; - } - - -} diff --git a/src/engine/net/client/msg/WorldRealmMsg.java b/src/engine/net/client/msg/WorldRealmMsg.java index f2f05b0a..57abbb36 100644 --- a/src/engine/net/client/msg/WorldRealmMsg.java +++ b/src/engine/net/client/msg/WorldRealmMsg.java @@ -21,7 +21,6 @@ package engine.net.client.msg; -import engine.Enum.RealmType; import engine.net.AbstractConnection; import engine.net.ByteBufferReader; import engine.net.ByteBufferWriter; @@ -67,23 +66,12 @@ public class WorldRealmMsg extends ClientNetMsg { Realm serverRealm; - realmCount = RealmType.values().length - 1; - // Realm count without seafloor + realmCount = Realm._realms.size(); writer.putInt(realmCount); - for (RealmType realmType : RealmType.values()) { - - realmID = realmType.getRealmID(); - // Don't serialize seafloor - - if (realmID == 0) - continue; - - serverRealm = Realm.getRealm(realmID); - serverRealm.serializeForClientMsg(writer); - - } + for (Realm realm : Realm._realms.values()) + realm.serializeForClientMsg(writer); writer.putInt(0x0); writer.putInt(3000000); diff --git a/src/engine/objects/City.java b/src/engine/objects/City.java index 8dbe69aa..6919b137 100644 --- a/src/engine/objects/City.java +++ b/src/engine/objects/City.java @@ -872,7 +872,7 @@ public class City extends AbstractWorldObject { if (playerObject == null) continue; - if (!this.isLocationOnCityZone(playerObject.getLoc())) + if (!this.isLocationWithinSiegeBounds(playerObject.getLoc())) continue; player = (PlayerCharacter) playerObject; diff --git a/src/engine/objects/Experience.java b/src/engine/objects/Experience.java index ab5c2789..32653186 100644 --- a/src/engine/objects/Experience.java +++ b/src/engine/objects/Experience.java @@ -9,10 +9,13 @@ package engine.objects; +import engine.Enum; import engine.Enum.TargetColor; +import engine.gameManager.ConfigManager; import engine.gameManager.ZoneManager; import engine.math.Vector3fImmutable; import engine.server.MBServerStatics; +import engine.server.world.WorldServer; import java.util.ArrayList; import java.util.TreeMap; @@ -330,12 +333,7 @@ public class Experience { if (killer == null || mob == null) return; - double xp = 0.0; - - //Get the xp modifier for the world - float xpMod = MBServerStatics.EXP_RATE_MOD; - - + double grantedExperience = 0.0; if (g != null) { // Do group EXP stuff @@ -372,18 +370,18 @@ public class Experience { } // Process every player in the group getting XP - for (PlayerCharacter pc : giveEXPTo) { - if (pc.getLevel() >= MBServerStatics.LEVELCAP) + for (PlayerCharacter playerCharacter : giveEXPTo) { + if (playerCharacter.getLevel() >= MBServerStatics.LEVELCAP) continue; // Sets Max XP with server exp mod taken into account. - xp = (double) xpMod * maxXPPerKill(pc.getLevel()); + grantedExperience = (double) Float.parseFloat(ConfigManager.MB_NORMAL_EXP_RATE.getValue()) * maxXPPerKill(playerCharacter.getLevel()); // Adjust XP for Mob Level - xp *= getConMod(pc, mob); + grantedExperience *= getConMod(playerCharacter, mob); // Process XP for this member - penalty = getGroupMemberPenalty(leadership, pc, giveEXPTo, + penalty = getGroupMemberPenalty(leadership, playerCharacter, giveEXPTo, highestLevel); // Leadership Penalty Reduction @@ -391,27 +389,27 @@ public class Experience { penalty -= ((leadership) * 0.01) * penalty; // Modify for hotzone - if (xp != 0) + if (grantedExperience != 0) if (ZoneManager.inHotZone(mob.getLoc())) - xp *= MBServerStatics.HOT_EXP_RATE_MOD; + grantedExperience *= Float.parseFloat(ConfigManager.MB_HOTZONE_EXP_RATE.getValue()); // Check for 0 XP due to white mob, otherwise subtract penalty // xp - if (xp == 0) { - xp = 1; + if (grantedExperience == 0) { + grantedExperience = 1; } else { - xp -= (penalty * 0.01) * xp; + grantedExperience -= (penalty * 0.01) * grantedExperience; // Errant Penalty Calculation - if (pc.getGuild().isEmptyGuild()) - xp *= 0.6; + if (playerCharacter.getGuild().isEmptyGuild()) + grantedExperience *= 0.6; } - if (xp == 0) - xp = 1; + if (grantedExperience == 0) + grantedExperience = 1; // Grant the player the EXP - pc.grantXP((int) Math.floor(xp)); + playerCharacter.grantXP((int) Math.floor(grantedExperience)); } } else { // Give EXP to a single character @@ -422,20 +420,20 @@ public class Experience { return; // Get XP and adjust for Mob Level with world xp modifier taken into account - xp = (double) xpMod * maxXPPerKill(killer.getLevel()); - xp *= getConMod(killer, mob); + grantedExperience = (double) Float.parseFloat(ConfigManager.MB_NORMAL_EXP_RATE.getValue()) * maxXPPerKill(killer.getLevel()); + grantedExperience *= getConMod(killer, mob); // Modify for hotzone if (ZoneManager.inHotZone(mob.getLoc())) - xp *= MBServerStatics.HOT_EXP_RATE_MOD; + grantedExperience *= Float.parseFloat(ConfigManager.MB_HOTZONE_EXP_RATE.getValue()); // Errant penalty - if (xp != 1) + if (grantedExperience != 1) if (killer.getGuild().isEmptyGuild()) - xp *= .6; + grantedExperience *= .6; // Grant XP - killer.grantXP((int) Math.floor(xp)); + killer.grantXP((int) Math.floor(grantedExperience)); } } } diff --git a/src/engine/objects/ItemFactory.java b/src/engine/objects/ItemFactory.java index 92491684..33d93d8c 100644 --- a/src/engine/objects/ItemFactory.java +++ b/src/engine/objects/ItemFactory.java @@ -13,10 +13,7 @@ import engine.Enum; import engine.Enum.ItemContainerType; import engine.Enum.ItemType; import engine.Enum.OwnerType; -import engine.gameManager.BuildingManager; -import engine.gameManager.ChatManager; -import engine.gameManager.DbManager; -import engine.gameManager.PowersManager; +import engine.gameManager.*; import engine.net.ItemProductionManager; import engine.net.ItemQueue; import engine.net.client.ClientConnection; @@ -202,7 +199,7 @@ public class ItemFactory { // is used to determin whether or not an object has // compelted rolling. The game object exists previously // to this, not when 'compelte' is pressed. - long upgradeTime = System.currentTimeMillis() + (long)(time * MBServerStatics.PRODUCTION_TIME_MULTIPLIER) ; + long upgradeTime = System.currentTimeMillis() + (long)(time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue())); DateTime dateTime = new DateTime(); dateTime = dateTime.withMillis(upgradeTime); @@ -220,7 +217,7 @@ public class ItemFactory { pi.setAmount(itemsToRoll); pi.setRandom(false); - ItemQueue produced = ItemQueue.borrow(pi, (long) (time * MBServerStatics.PRODUCTION_TIME_MULTIPLIER)); + ItemQueue produced = ItemQueue.borrow(pi, (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()))); ItemProductionManager.send(produced); return ml; @@ -620,7 +617,7 @@ public class ItemFactory { // is used to determin whether or not an object has // compelted rolling. The game object exists previously // to this, not when 'compelte' is pressed. - long upgradeTime = System.currentTimeMillis() + (long)(time * MBServerStatics.PRODUCTION_TIME_MULTIPLIER) ; + long upgradeTime = System.currentTimeMillis() + (long)(time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue())) ; DateTime dateTime = new DateTime(); dateTime = dateTime.withMillis(upgradeTime); @@ -637,7 +634,7 @@ public class ItemFactory { pi.setProducedItemID(ml.getObjectUUID()); pi.setAmount(itemsToRoll); - ItemQueue produced = ItemQueue.borrow(pi, (long) (time * MBServerStatics.PRODUCTION_TIME_MULTIPLIER)); + ItemQueue produced = ItemQueue.borrow(pi, (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()))); ItemProductionManager.send(produced); }catch(Exception e){ Logger.error(e); @@ -906,7 +903,7 @@ public class ItemFactory { // is used to determin whether or not an object has // compelted rolling. The game object exists previously // to this, not when 'compelte' is pressed. - long upgradeTime = System.currentTimeMillis() + (long)(time * MBServerStatics.PRODUCTION_TIME_MULTIPLIER) ; + long upgradeTime = System.currentTimeMillis() + (long)(time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue())) ; DateTime dateTime = new DateTime(); dateTime = dateTime.withMillis(upgradeTime); @@ -920,7 +917,7 @@ public class ItemFactory { ProducedItem pi = new ProducedItem(toRoll.getObjectUUID(),vendor.getObjectUUID(),toRoll.getItemBaseID(),dateTime,true,prefix, suffix, toRoll.getCustomName(),playerID); pi.setProducedItemID(toRoll.getObjectUUID()); pi.setAmount(itemsToRoll); - ItemQueue produced = ItemQueue.borrow(pi, (long) (time * MBServerStatics.PRODUCTION_TIME_MULTIPLIER)); + ItemQueue produced = ItemQueue.borrow(pi, (long) (time * Float.parseFloat(ConfigManager.MB_PRODUCTION_RATE.getValue()))); ItemProductionManager.send(produced); return toRoll; } diff --git a/src/engine/objects/LootTable.java b/src/engine/objects/LootTable.java index 16a9523a..c9c5fb9d 100644 --- a/src/engine/objects/LootTable.java +++ b/src/engine/objects/LootTable.java @@ -9,12 +9,15 @@ package engine.objects; +import engine.Enum; import engine.Enum.ItemContainerType; import engine.Enum.ItemType; import engine.Enum.OwnerType; +import engine.gameManager.ConfigManager; import engine.gameManager.DbManager; import engine.gameManager.ZoneManager; import engine.server.MBServerStatics; +import engine.server.world.WorldServer; import org.pmw.tinylog.Logger; import java.util.ArrayList; @@ -208,7 +211,7 @@ public class LootTable { float chance = mlb.getChance() *.01f; - chance *= MBServerStatics.DROP_RATE_MOD; + chance *= Float.parseFloat(ConfigManager.MB_NORMAL_DROP_RATE.getValue()); calculatedLootTable = mlb.getLootTableID(); diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index b43bf21e..d58b46ad 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -20,7 +20,10 @@ package engine.objects; import engine.Enum; import engine.InterestManagement.WorldGrid; -import engine.gameManager.*; +import engine.gameManager.BuildingManager; +import engine.gameManager.ChatManager; +import engine.gameManager.DbManager; +import engine.gameManager.ZoneManager; import engine.net.ByteBufferWriter; import engine.net.client.msg.ErrorPopupMsg; import engine.server.MBServerStatics; @@ -33,38 +36,34 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; -import static engine.gameManager.DbManager.*; +import static engine.gameManager.DbManager.MineQueries; +import static engine.gameManager.DbManager.getObject; import static engine.math.FastMath.sqr; public class Mine extends AbstractGameObject { - private String zoneName; - private Resource production; + public static ConcurrentHashMap mineMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); + public static ConcurrentHashMap towerMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); public boolean isActive = false; - - private float latitude; - private float longitude; - private float altitude; - private Guild owningGuild; public PlayerCharacter lastClaimer; public boolean wasClaimed = false; - private int flags; - private int buildingID; - private Zone parentZone; - private MineProduction mineType; - - //flags 1: never been claimed (make active). - - // Not persisted to DB public String guildName; public GuildTag guildTag; public String nationName; public GuildTag nationTag; - public static ConcurrentHashMap mineMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); - public static ConcurrentHashMap towerMap = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); + private final String zoneName; + private Resource production; + private final float latitude; + private final float longitude; - private static long lastChange = System.currentTimeMillis(); + //flags 1: never been claimed (make active). + private final float altitude; + private Guild owningGuild; + private int flags; + private int buildingID; + private final Zone parentZone; + private MineProduction mineType; /** * ResultSet Constructor @@ -139,6 +138,7 @@ public class Mine extends AbstractGameObject { } } + public static void SendMineAttackMessage(Building mine) { if (mine.getBlueprint() == null) @@ -186,90 +186,10 @@ public class Mine extends AbstractGameObject { * Getters */ - public boolean changeProductionType(Resource resource) { - if (!this.validForMine(resource)) - return false; - //update resource in database; - if (!MineQueries.CHANGE_RESOURCE(this, resource)) - return false; - - this.production = resource; - return true; - } - - public MineProduction getMineType() { - return this.mineType; - } - - public String getZoneName() { - return this.zoneName; - } - - public Resource getProduction() { - return this.production; - } - - public boolean getIsActive() { - return this.isActive; - } - - public float getAltitude() { - return this.altitude; - } - - public Guild getOwningGuild() { - if (this.owningGuild == null) - return Guild.getErrantGuild(); - else - return this.owningGuild; - } - - public int getFlags() { - return flags; - } - - public void setFlags(int flags) { - this.flags = flags; - } - - public Zone getParentZone() { - return parentZone; - } - - public GuildTag getGuildTag() { - return guildTag; - } - - public void setMineType(String type) { - this.mineType = MineProduction.getByName(type); - } - - public void setActive(boolean isAc) { - - this.isActive = isAc; - Building building = BuildingManager.getBuildingFromCache(this.buildingID); - if (building != null && !this.isActive) - building.isDeranking.compareAndSet(true, false); - } - - public void setOwningGuild(Guild owningGuild) { - this.owningGuild = owningGuild; - } - public static Mine getMineFromTower(int towerID) { return Mine.towerMap.get(towerID); } - public boolean validForMine(Resource r) { - if (this.mineType == null) - return false; - return this.mineType.validForMine(r, this.isExpansion()); - } - - /* - * Serialization - */ - public static void serializeForClientMsg(Mine mine, ByteBufferWriter writer) { writer.putInt(mine.getObjectType().ordinal()); writer.putInt(mine.getObjectUUID()); @@ -284,15 +204,15 @@ public class Mine extends AbstractGameObject { // Errant mines are currently open. Set time to now. LocalDateTime mineOpenTime = LocalDateTime.now().withMinute(0).withSecond(0).withNano(0); - + // Mine times are those of the nation not individual guild. - + Guild mineNatonGuild = mine.getOwningGuild().getNation(); // Adjust the serialized mine time based upon whether // the Guild's mine window has passed or not and if it was claimed. - // If a mine is active serialize current datetime irrespective - // of any claim. + // If a mine is active serialize current datetime irrespective + // of any claim. if (mineNatonGuild.isEmptyGuild() == false && mine.isActive == false) { @@ -321,20 +241,6 @@ public class Mine extends AbstractGameObject { GuildTag._serializeForDisplay(mine.nationTag, writer); } - public void serializeForMineProduction(ByteBufferWriter writer) { - writer.putInt(this.getObjectType().ordinal()); - writer.putInt(this.getObjectUUID()); - writer.putInt(this.getObjectUUID()); //actually a hash of mine - // writer.putInt(0x215C92BB); //this.unknown1); - writer.putString(this.mineType.name); - writer.putString(this.zoneName); - writer.putInt(this.production.hash); - writer.putInt(this.production.baseProduction); - writer.putInt(this.getModifiedProductionAmount()); //TODO calculate range penalty here - writer.putInt(3600); //window in seconds - writer.putInt(this.isExpansion() ? this.mineType.xpacHash : this.mineType.hash); - } - public static ArrayList getMinesForGuild(int guildID) { ArrayList mineList = new ArrayList<>(); @@ -343,20 +249,12 @@ public class Mine extends AbstractGameObject { for (Mine mine : Mine.mineMap.keySet()) { if (mine.owningGuild.getObjectUUID() == guildID && - mine.isActive == false) + mine.isActive == false) mineList.add(mine); } return mineList; } - public static long getLastChange() { - return lastChange; - } - - public static void setLastChange(long lastChange) { - Mine.lastChange = lastChange; - } - /* * Database */ @@ -369,19 +267,6 @@ public class Mine extends AbstractGameObject { return new ArrayList<>(mineMap.keySet()); } - @Override - public void updateDatabase() { - // TODO Create update logic. - } - - public int getBuildingID() { - return buildingID; - } - - public void setBuildingID(int buildingID) { - this.buildingID = buildingID; - } - public static boolean validateClaimer(PlayerCharacter playerCharacter) { // Method validates that the claimer meets @@ -407,7 +292,7 @@ public class Mine extends AbstractGameObject { if (playerGuild.getNation().isEmptyGuild()) return false; - // Guild must own a city to hold a mine. + // Guild must own a city to hold a mine. City guildCity = playerGuild.getOwnedCity(); @@ -433,7 +318,7 @@ public class Mine extends AbstractGameObject { if (treeRank < 1) return false; - if (guildUnderMineLimit(playerGuild.getNation(), treeRank) == false){ + if (guildUnderMineLimit(playerGuild.getNation(), treeRank) == false) { ErrorPopupMsg.sendErrorMsg(playerCharacter, "Your nation cannot support another mine."); return false; } @@ -450,11 +335,116 @@ public class Mine extends AbstractGameObject { for (Guild guild : playerGuild.getSubGuildList()) mineCnt += Mine.getMinesForGuild(guild.getObjectUUID()).size(); - if (mineCnt > tolRank) + return mineCnt <= tolRank; + } + + public boolean changeProductionType(Resource resource) { + if (!this.validForMine(resource)) + return false; + //update resource in database; + if (!MineQueries.CHANGE_RESOURCE(this, resource)) return false; + this.production = resource; return true; } + + public MineProduction getMineType() { + return this.mineType; + } + + public void setMineType(String type) { + this.mineType = MineProduction.getByName(type); + } + + public String getZoneName() { + return this.zoneName; + } + + public Resource getProduction() { + return this.production; + } + + public boolean getIsActive() { + return this.isActive; + } + + public float getAltitude() { + return this.altitude; + } + + public Guild getOwningGuild() { + if (this.owningGuild == null) + return Guild.getErrantGuild(); + else + return this.owningGuild; + } + + public void setOwningGuild(Guild owningGuild) { + this.owningGuild = owningGuild; + } + + /* + * Serialization + */ + + public int getFlags() { + return flags; + } + + public void setFlags(int flags) { + this.flags = flags; + } + + public Zone getParentZone() { + return parentZone; + } + + public GuildTag getGuildTag() { + return guildTag; + } + + public void setActive(boolean isAc) { + + this.isActive = isAc; + Building building = BuildingManager.getBuildingFromCache(this.buildingID); + if (building != null && !this.isActive) + building.isDeranking.compareAndSet(true, false); + } + + public boolean validForMine(Resource r) { + if (this.mineType == null) + return false; + return this.mineType.validForMine(r, this.isExpansion()); + } + + public void serializeForMineProduction(ByteBufferWriter writer) { + writer.putInt(this.getObjectType().ordinal()); + writer.putInt(this.getObjectUUID()); + writer.putInt(this.getObjectUUID()); //actually a hash of mine + // writer.putInt(0x215C92BB); //this.unknown1); + writer.putString(this.mineType.name); + writer.putString(this.zoneName); + writer.putInt(this.production.hash); + writer.putInt(this.production.baseProduction); + writer.putInt(this.getModifiedProductionAmount()); //TODO calculate range penalty here + writer.putInt(3600); //window in seconds + writer.putInt(this.isExpansion() ? this.mineType.xpacHash : this.mineType.hash); + } + + @Override + public void updateDatabase() { + // TODO Create update logic. + } + + public int getBuildingID() { + return buildingID; + } + + public void setBuildingID(int buildingID) { + this.buildingID = buildingID; + } + public void handleDestroyMine() { if (!this.isActive) @@ -465,7 +455,6 @@ public class Mine extends AbstractGameObject { this.guildName = ""; this.nationName = ""; this.owningGuild = Guild.getErrantGuild(); - Mine.setLastChange(System.currentTimeMillis()); this.lastClaimer = null; this.wasClaimed = false; @@ -513,6 +502,7 @@ public class Mine extends AbstractGameObject { return true; } + public boolean depositMineResources() { if (this.owningGuild.isEmptyGuild()) diff --git a/src/engine/objects/Mob.java b/src/engine/objects/Mob.java index 9dfcca5c..996d9ab4 100644 --- a/src/engine/objects/Mob.java +++ b/src/engine/objects/Mob.java @@ -1508,17 +1508,14 @@ public class Mob extends AbstractIntelligenceAgent { double gold = (ThreadLocalRandom.current().nextDouble() * (maxGold - minGold) + minGold); - //server specific gold multiplier - double goldMod = MBServerStatics.GOLD_RATE_MOD; - gold *= goldMod; + + gold *= Float.parseFloat(ConfigManager.MB_NORMAL_DROP_RATE.getValue()); //modify for hotzone if (ZoneManager.inHotZone(mob.getLoc())) - gold *= MBServerStatics.HOT_GOLD_RATE_MOD; - - gold *= MBServerStatics.GOLD_RATE_MOD; + gold *= Float.parseFloat(ConfigManager.MB_HOTZONE_DROP_RATE.getValue()); return (int) gold; } diff --git a/src/engine/objects/PlayerCharacter.java b/src/engine/objects/PlayerCharacter.java index 1fcbd66c..a7ceb19e 100644 --- a/src/engine/objects/PlayerCharacter.java +++ b/src/engine/objects/PlayerCharacter.java @@ -2213,7 +2213,7 @@ public void dismissNecroPets() { for (Effect eff : playerCharacter.getEffects().values()) { if (eff.getPower() == null && otherPlayer) continue; - if (eff.getPower().token == 429506619) // Oblivion's Caress + if (eff.getPower() != null && eff.getPower().token == 429506619) // Oblivion's Caress continue; if ( !eff.serializeForLoad(writer)) continue; diff --git a/src/engine/objects/Portal.java b/src/engine/objects/Portal.java index 498e0921..666d0d2d 100644 --- a/src/engine/objects/Portal.java +++ b/src/engine/objects/Portal.java @@ -1,13 +1,13 @@ package engine.objects; -import engine.Enum.RunegateType; +import engine.Enum; +import engine.Enum.PortalType; import engine.InterestManagement.WorldGrid; import engine.gameManager.ConfigManager; import engine.job.JobScheduler; import engine.jobs.CloseGateJob; import engine.math.Vector3fImmutable; import engine.server.MBServerStatics; -import org.pmw.tinylog.Logger; import java.util.HashSet; @@ -19,28 +19,20 @@ import java.util.HashSet; public class Portal { private boolean active; - private RunegateType sourceGateType; - private RunegateType portalType; - private RunegateType destinationGateType; - private final Vector3fImmutable portalLocation; + public Enum.PortalType portalType; + public Building sourceGate; + public Building targetGate; + public final Vector3fImmutable portalLocation; private long lastActive = 0; - public Portal(RunegateType gateType, RunegateType portalType, RunegateType destinationGate) { - - Building gateBuilding; + public Portal(Building sourceGate, PortalType portalType, Building targetGate) { this.active = false; - this.sourceGateType = gateType; - this.destinationGateType = destinationGate; + this.sourceGate = sourceGate; + this.targetGate = targetGate; this.portalType = portalType; - gateBuilding = this.sourceGateType.getGateBuilding(); - - if (gateBuilding == null) { - Logger.error("Gate building " + this.sourceGateType.getGateUUID() + " for " + this.sourceGateType.name() + " missing"); - } - - this.portalLocation = gateBuilding.getLoc().add(new Vector3fImmutable(portalType.getOffset().x, 6, portalType.getOffset().y)); + this.portalLocation = sourceGate.getLoc().add(new Vector3fImmutable(portalType.offset.x, 6, portalType.offset.y)); } public boolean isActive() { @@ -51,15 +43,12 @@ public class Portal { public void deactivate() { - Building sourceBuilding; - // Remove effect bit from the runegate building, which turns off this // portal type's particle effect - sourceBuilding = this.sourceGateType.getGateBuilding(); - sourceBuilding.removeEffectBit(portalType.getEffectFlag()); + sourceGate.removeEffectBit(portalType.effectFlag); this.active = false; - sourceBuilding.updateEffects(); + sourceGate.updateEffects(); } public void activate(boolean autoClose) { @@ -70,8 +59,8 @@ public class Portal { // Apply effect bit to the runegate building, which turns on this // portal type's particle effect - sourceBuilding = this.sourceGateType.getGateBuilding(); - sourceBuilding.addEffectBit(portalType.getEffectFlag()); + + sourceGate.addEffectBit(portalType.effectFlag); this.lastActive = System.currentTimeMillis(); this.active = true; @@ -79,10 +68,10 @@ public class Portal { // tries to send a dispatch. if (ConfigManager.worldServer.isRunning == true) - sourceBuilding.updateEffects(); + sourceGate.updateEffects(); if (autoClose == true) { - CloseGateJob cgj = new CloseGateJob(sourceBuilding, portalType); + CloseGateJob cgj = new CloseGateJob(sourceGate, portalType); JobScheduler.getInstance().scheduleJob(cgj, MBServerStatics.RUNEGATE_CLOSE_TIME); } } @@ -107,59 +96,12 @@ public class Portal { if (player.getTimeStamp("lastMoveGate") < this.lastActive) return; - Building gateBuilding; - gateBuilding = destinationGateType.getGateBuilding(); - - if (gateBuilding != null){ - player.teleport(gateBuilding.getLoc()); + player.teleport(targetGate.getLoc()); player.setSafeMode(); - } } - /** - * @return the sourceGateType - */ - public RunegateType getSourceGateType() { - return sourceGateType; - } - - /** - * @param sourceGateType the sourceGateType to set - */ - public void setSourceGateType(RunegateType sourceGateType) { - this.sourceGateType = sourceGateType; - } - - /** - * @return the portalType - */ - public RunegateType getPortalType() { - return portalType; - } - - /** - * @param portalType the portalType to set - */ - public void setPortalType(RunegateType portalType) { - this.portalType = portalType; - } - - /** - * @return the destinationGateType - */ - public RunegateType getDestinationGateType() { - return destinationGateType; - } - - /** - * @param destinationGateType the destinationGateType to set - */ - public void setDestinationGateType(RunegateType destinationGateType) { - this.destinationGateType = destinationGateType; - } - /** * @return the portalLocation */ diff --git a/src/engine/objects/Realm.java b/src/engine/objects/Realm.java index 3936d85a..b2f7e22b 100644 --- a/src/engine/objects/Realm.java +++ b/src/engine/objects/Realm.java @@ -21,6 +21,7 @@ import engine.powers.PowersBase; import engine.server.MBServerStatics; import org.pmw.tinylog.Logger; +import java.awt.*; import java.net.UnknownHostException; import java.sql.ResultSet; import java.sql.SQLException; @@ -36,8 +37,9 @@ public class Realm { // Internal class cache - private static ConcurrentHashMap _realms = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); + public static ConcurrentHashMap _realms = new ConcurrentHashMap<>(MBServerStatics.CHM_INIT_CAP, MBServerStatics.CHM_LOAD, MBServerStatics.CHM_THREAD_LOW); + public Color mapColor; private final float mapR; //Red color private final float mapG; //Green color private final float mapB; //Blue color @@ -63,7 +65,7 @@ public class Realm { private final int stretchY; private final int locX; private final int locY; - private final int realmID; + public final int realmID; private final HashSet cities = new HashSet<>(); private String hash; @@ -72,6 +74,7 @@ public class Realm { */ public Realm(ResultSet rs) throws SQLException, UnknownHostException { + this.mapColor = new Color(rs.getInt("mapColor")); this.mapR = rs.getFloat("mapR"); this.mapG = rs.getFloat("mapG"); this.mapB = rs.getFloat("mapB"); @@ -200,20 +203,8 @@ public class Realm { public static void configureAllRealms() { - Realm serverRealm; - int realmID; - - for (Enum.RealmType realmType : Enum.RealmType.values()) { - - realmID = realmType.getRealmID(); - // Don't serialize seafloor - - if (realmID == 0) - continue; - - serverRealm = Realm.getRealm(realmID); - serverRealm.configure(); - + for (Realm realm : Realm._realms.values()) { + realm.configure(); } } diff --git a/src/engine/objects/Runegate.java b/src/engine/objects/Runegate.java index ad67bbaf..59da6d10 100644 --- a/src/engine/objects/Runegate.java +++ b/src/engine/objects/Runegate.java @@ -1,61 +1,56 @@ package engine.objects; -import engine.Enum.RunegateType; -import engine.gameManager.BuildingManager; +import engine.Enum; +import engine.Enum.PortalType; +import engine.gameManager.DbManager; import engine.net.ByteBufferWriter; import java.util.ArrayList; +import java.util.HashMap; /* Runegates are tied to particular buildings at - * bootstrap. They aren't tighly coupled, with - * the Runegate merely toggling effect bits on it's - * parent building. + * bootstrap derived from the Portal creation. + * This is only to enable the toggling of effect + * bits when traveler is used. */ public class Runegate { // Runegate class Instance variables - private static final Runegate[] _runegates = new Runegate[9]; + public static HashMap _runegates = new HashMap<>(); - private final Portal[] _portals; - private final RunegateType gateType; + public Portal[] _portals; + public Building gateBuilding; - private Runegate(RunegateType gateType) { + private Runegate(Building gateBuilding) { this._portals = new Portal[8]; - this.gateType = gateType; + this.gateBuilding = gateBuilding; - // Each Runegate has a different destination - // for each portal opened. - configureGatePortals(); + // Load portals for this runegate portals from the database + + configurePortals(); // Chaos, Khar and Oblivion are on by default - _portals[RunegateType.CHAOS.ordinal()].activate(false); - _portals[RunegateType.OBLIV.ordinal()].activate(false); - _portals[RunegateType.MERCHANT.ordinal()].activate(false); + _portals[Enum.PortalType.CHAOS.ordinal()].activate(false); + _portals[Enum.PortalType.OBLIV.ordinal()].activate(false); + _portals[Enum.PortalType.MERCHANT.ordinal()].activate(false); } - public void activatePortal(RunegateType gateType) { + public void activatePortal(Enum.PortalType portalType) { - this._portals[gateType.ordinal()].activate(true); + this._portals[portalType.ordinal()].activate(true); } - public void deactivatePortal(RunegateType gateType) { + public void deactivatePortal(Enum.PortalType portalType) { - this._portals[gateType.ordinal()].deactivate(); + this._portals[portalType.ordinal()].deactivate(); } - public RunegateType getGateType() { - return this.gateType; - } - - public static Runegate[] getRunegates() { - return Runegate._runegates; - } public Portal[] getPortals() { @@ -74,17 +69,30 @@ public class Runegate { public static void loadAllRunegates() { - for (RunegateType runegateType : RunegateType.values()) { - _runegates[runegateType.ordinal()] = new Runegate(runegateType); - } + ArrayList gateList; + gateList = DbManager.RunegateQueries.GET_RUNEGATE_LIST(); + + for (int gateID : gateList) { + + Building gateBuilding = (Building) DbManager.getObject(Enum.GameObjectType.Building, gateID); + + Runegate runegate = new Runegate(gateBuilding); + _runegates.put(gateID, runegate); } - public void _serializeForEnterWorld(ByteBufferWriter writer) { + } - Building gateBuilding; + public void configurePortals() { - gateBuilding = BuildingManager.getBuilding(this.gateType.getGateUUID()); + ArrayList portalList = DbManager.RunegateQueries.GET_PORTAL_LIST(this.gateBuilding.getObjectUUID()); + + for (Portal portal : portalList) { + this._portals[portal.portalType.ordinal()] = portal; + } + } + + public void _serializeForEnterWorld(ByteBufferWriter writer) { writer.putInt(gateBuilding.getObjectType().ordinal()); writer.putInt(gateBuilding.getObjectUUID()); @@ -94,114 +102,6 @@ public class Runegate { writer.putFloat(gateBuilding.getLoc().getLong()); } - private void configureGatePortals() { - - // Source gate type, portal type and destination gate type; - switch (this.gateType) { - - case EARTH: - _portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.EARTH, RunegateType.EARTH); - _portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.AIR, RunegateType.AIR); - _portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.FIRE, RunegateType.FORBID); - _portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.WATER, RunegateType.WATER); - _portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.SPIRIT, RunegateType.SPIRIT); - _portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.CHAOS, RunegateType.CHAOS); - _portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.OBLIV, RunegateType.OBLIV); - _portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.EARTH, RunegateType.MERCHANT, RunegateType.MERCHANT); - break; - - case AIR: - _portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.AIR, RunegateType.EARTH, RunegateType.EARTH); - _portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.AIR, RunegateType.AIR, RunegateType.FORBID); - _portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.AIR, RunegateType.FIRE, RunegateType.FIRE); - _portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.AIR, RunegateType.WATER, RunegateType.WATER); - _portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.AIR, RunegateType.SPIRIT, RunegateType.SPIRIT); - _portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.AIR, RunegateType.CHAOS, RunegateType.CHAOS); - _portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.AIR, RunegateType.OBLIV, RunegateType.OBLIV); - _portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.AIR, RunegateType.MERCHANT, RunegateType.MERCHANT); - - break; - - case FIRE: - _portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.EARTH, RunegateType.EARTH); - _portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.AIR, RunegateType.AIR); - _portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.FIRE, RunegateType.FORBID); - _portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.WATER, RunegateType.WATER); - _portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.SPIRIT, RunegateType.SPIRIT); - _portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.CHAOS, RunegateType.CHAOS); - _portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.OBLIV, RunegateType.OBLIV); - _portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.FIRE, RunegateType.MERCHANT, RunegateType.MERCHANT); - break; - - case WATER: - _portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.WATER, RunegateType.EARTH, RunegateType.EARTH); - _portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.WATER, RunegateType.AIR, RunegateType.AIR); - _portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.WATER, RunegateType.FIRE, RunegateType.FIRE); - _portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.WATER, RunegateType.WATER, RunegateType.FORBID); - _portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.WATER, RunegateType.SPIRIT, RunegateType.SPIRIT); - _portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.WATER, RunegateType.CHAOS, RunegateType.CHAOS); - _portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.WATER, RunegateType.OBLIV, RunegateType.OBLIV); - _portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.WATER, RunegateType.MERCHANT, RunegateType.MERCHANT); - break; - - case SPIRIT: - _portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.EARTH, RunegateType.EARTH); - _portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.AIR, RunegateType.AIR); - _portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.FIRE, RunegateType.FIRE); - _portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.WATER, RunegateType.WATER); - _portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.SPIRIT, RunegateType.FORBID); - _portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.CHAOS, RunegateType.CHAOS); - _portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.OBLIV, RunegateType.OBLIV); - _portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.SPIRIT, RunegateType.MERCHANT, RunegateType.MERCHANT); - break; - - case CHAOS: - _portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.EARTH, RunegateType.EARTH); - _portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.AIR, RunegateType.AIR); - _portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.FIRE, RunegateType.FIRE); - _portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.WATER, RunegateType.WATER); - _portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.SPIRIT, RunegateType.SPIRIT); - _portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.CHAOS, RunegateType.MERCHANT); - _portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.OBLIV, RunegateType.OBLIV); - _portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.CHAOS, RunegateType.MERCHANT, RunegateType.MERCHANT); - break; - - case OBLIV: - _portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.EARTH, RunegateType.EARTH); - _portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.AIR, RunegateType.AIR); - _portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.FIRE, RunegateType.FIRE); - _portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.WATER, RunegateType.WATER); - _portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.SPIRIT, RunegateType.SPIRIT); - _portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.CHAOS, RunegateType.CHAOS); - _portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.OBLIV, RunegateType.MERCHANT); - _portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.OBLIV, RunegateType.MERCHANT, RunegateType.MERCHANT); - break; - - case MERCHANT: - _portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.EARTH, RunegateType.EARTH); - _portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.AIR, RunegateType.AIR); - _portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.FIRE, RunegateType.FIRE); - _portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.WATER, RunegateType.WATER); - _portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.SPIRIT, RunegateType.SPIRIT); - _portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.CHAOS, RunegateType.CHAOS); - _portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.OBLIV, RunegateType.OBLIV); - _portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.MERCHANT, RunegateType.MERCHANT, RunegateType.FORBID); - break; - - case FORBID: - _portals[RunegateType.EARTH.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.EARTH, RunegateType.EARTH); - _portals[RunegateType.AIR.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.AIR, RunegateType.AIR); - _portals[RunegateType.FIRE.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.FIRE, RunegateType.FIRE); - _portals[RunegateType.WATER.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.WATER, RunegateType.WATER); - _portals[RunegateType.SPIRIT.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.SPIRIT, RunegateType.SPIRIT); - _portals[RunegateType.CHAOS.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.CHAOS, RunegateType.CHAOS); - _portals[RunegateType.OBLIV.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.OBLIV, RunegateType.OBLIV); - _portals[RunegateType.MERCHANT.ordinal()] = new Portal(RunegateType.FORBID, RunegateType.MERCHANT, RunegateType.MERCHANT); - break; - - } - - } public static ArrayList GetAllOpenGateIDStrings(){ ArrayList openGateIDStrings = new ArrayList<>(); diff --git a/src/engine/objects/Zone.java b/src/engine/objects/Zone.java index 18cccae9..10ca5136 100644 --- a/src/engine/objects/Zone.java +++ b/src/engine/objects/Zone.java @@ -23,6 +23,7 @@ import org.pmw.tinylog.Logger; import java.sql.ResultSet; import java.sql.SQLException; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; import java.util.Set; @@ -50,8 +51,8 @@ public class Zone extends AbstractGameObject { private boolean isNPCCity = false; private boolean isPlayerCity = false; private String hash; - private int minLvl; - private int maxLvl; + public int minLvl; + public int maxLvl; private float worldAltitude = 0; @@ -59,7 +60,7 @@ public class Zone extends AbstractGameObject { public final Set zoneBuildingSet = Collections.newSetFromMap(new ConcurrentHashMap<>()); public final Set zoneNPCSet = Collections.newSetFromMap(new ConcurrentHashMap<>()); public final Set zoneMobSet = Collections.newSetFromMap(new ConcurrentHashMap<>()); - + public boolean hasBeenHotzone = false; /** * ResultSet Constructor */ diff --git a/src/engine/powers/poweractions/ClaimMinePowerAction.java b/src/engine/powers/poweractions/ClaimMinePowerAction.java index 20929f6e..c43b5d00 100644 --- a/src/engine/powers/poweractions/ClaimMinePowerAction.java +++ b/src/engine/powers/poweractions/ClaimMinePowerAction.java @@ -50,10 +50,6 @@ public class ClaimMinePowerAction extends AbstractPowerAction { if (mine == null) return; - // Release prior claims - - Mine.releaseMineClaims(playerCharacter); - if (mine.claimMine(playerCharacter) == true) ChatManager.sendSystemMessage( (PlayerCharacter) source, "You successfully claimed this mine.."); } diff --git a/src/engine/powers/poweractions/OpenGatePowerAction.java b/src/engine/powers/poweractions/OpenGatePowerAction.java index 84032829..809bed5a 100644 --- a/src/engine/powers/poweractions/OpenGatePowerAction.java +++ b/src/engine/powers/poweractions/OpenGatePowerAction.java @@ -12,7 +12,7 @@ package engine.powers.poweractions; import engine.Enum; import engine.Enum.BuildingGroup; import engine.Enum.GameObjectType; -import engine.Enum.RunegateType; +import engine.Enum.PortalType; import engine.math.Vector3fImmutable; import engine.objects.AbstractCharacter; import engine.objects.AbstractWorldObject; @@ -44,11 +44,8 @@ public class OpenGatePowerAction extends AbstractPowerAction { if (awo.getObjectType().equals(GameObjectType.Building) == false) return; - + Building targetBuilding = (Building) awo; - Runegate runeGate; - RunegateType runegateType; - RunegateType portalType; int token; // Sanity check. @@ -69,39 +66,39 @@ public class OpenGatePowerAction extends AbstractPowerAction { // Which portal was opened? token = pb.getToken(); - portalType = RunegateType.AIR; + PortalType portalType = PortalType.AIR; switch (token) { case 428937084: //Death Gate - portalType = RunegateType.OBLIV; + portalType = PortalType.OBLIV; break; case 429756284: //Chaos Gate - portalType = RunegateType.CHAOS; + portalType = PortalType.CHAOS; break; case 429723516: //Khar Gate - portalType = RunegateType.MERCHANT; + portalType = PortalType.MERCHANT; break; case 429559676: //Spirit Gate - portalType = RunegateType.SPIRIT; + portalType = PortalType.SPIRIT; break; case 429592444: //Water Gate - portalType = RunegateType.WATER; + portalType = PortalType.WATER; break; case 429428604: //Fire Gate - portalType = RunegateType.FIRE; + portalType = PortalType.FIRE; break; case 429526908: //Air Gate - portalType = RunegateType.AIR; + portalType = PortalType.AIR; break; case 429625212: //Earth Gate - portalType = RunegateType.EARTH; + portalType = PortalType.EARTH; break; default: @@ -109,12 +106,9 @@ public class OpenGatePowerAction extends AbstractPowerAction { // Which runegate was clicked on? - runegateType = RunegateType.getGateTypeFromUUID(targetBuilding.getObjectUUID()); - runeGate = Runegate.getRunegates()[runegateType.ordinal()]; - + Runegate runeGate = Runegate._runegates.get(targetBuilding.getObjectUUID()); runeGate.activatePortal(portalType); - } @Override diff --git a/src/engine/powers/poweractions/RunegateTeleportPowerAction.java b/src/engine/powers/poweractions/RunegateTeleportPowerAction.java index 559df3f9..c41db745 100644 --- a/src/engine/powers/poweractions/RunegateTeleportPowerAction.java +++ b/src/engine/powers/poweractions/RunegateTeleportPowerAction.java @@ -10,7 +10,7 @@ package engine.powers.poweractions; import engine.Enum; -import engine.Enum.RunegateType; +import engine.Enum.PortalType; import engine.math.Vector3fImmutable; import engine.net.Dispatch; import engine.net.DispatchMessage; @@ -45,24 +45,17 @@ public class RunegateTeleportPowerAction extends AbstractPowerAction { Building rg = null; Vector3fImmutable rgLoc; - for (Runegate runegate: Runegate.getRunegates()) { + for (Runegate runegate: Runegate._runegates.values()) { - if ((runegate.getGateType() == RunegateType.OBLIV) || - (runegate.getGateType() == RunegateType.CHAOS)) - continue; - - for (Runegate thisGate : Runegate.getRunegates()) { - - rgLoc = thisGate.getGateType().getGateBuilding().getLoc(); + rgLoc = runegate.gateBuilding.getLoc(); float distanceToRunegateSquared = source.getLoc().distanceSquared2D(rgLoc); if (distanceToRunegateSquared < sqr(dist)) { dist = sqrt(distanceToRunegateSquared); - rg = thisGate.getGateType().getGateBuilding(); + rg = runegate.gateBuilding; } } - } if(source.getObjectUUID() != pc.getObjectUUID()) { pc.setTimeStampNow("PromptRecall"); diff --git a/src/engine/server/MBServerStatics.java b/src/engine/server/MBServerStatics.java index 03f83b2a..0e1ccc12 100644 --- a/src/engine/server/MBServerStatics.java +++ b/src/engine/server/MBServerStatics.java @@ -406,26 +406,6 @@ public class MBServerStatics { public static int SPATIAL_HASH_BUCKETSY = 12288; public static float MAX_PLAYER_X_LOC = 129999; public static float MAX_PLAYER_Y_LOC = -97000; - public static String NO_DELETE_COMBAT = "Can't delete items when in Combat with another player."; - - /* - * Rates - */ - - public static float EXP_RATE_MOD = 2f; // Probably don't want to declare - // as final. - public static float GOLD_RATE_MOD = 1.0f; // Probably don't want to declare - // as final. - public static float DROP_RATE_MOD = 1.0f; // Probably don't want to declare - // as final. - - // Hotzones - public static float HOT_EXP_RATE_MOD = 2.0f; // Probably don't want to - // declare as final. - public static float HOT_GOLD_RATE_MOD = 1.5f; // Probably don't want to - // declare as final. - public static float HOT_DROP_RATE_MOD = 1.8f; // Probably don't want to - // declare as final. /* * Ranges @@ -703,7 +683,6 @@ public class MBServerStatics { public static final int DESPAWN_TIMER_ONCE_LOOTED = 5 * 1000; public static final int MAX_COMBAT_HITBOX_RADIUS = 80; public static final int PROC_CHANCE = 5; // %chance to proc - public static float PRODUCTION_TIME_MULTIPLIER = .5f; /* * Mob loot -- gold calculations diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index 8e287c10..20bb7f1d 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -70,7 +70,6 @@ import static java.lang.System.exit; public class WorldServer { private static LocalDateTime bootTime = LocalDateTime.now(); - private static long lastHZChange = System.currentTimeMillis(); public boolean isRunning = false; // Member variable declaration @@ -121,14 +120,6 @@ public class WorldServer { } } - public static long getLastHZChange() { - return lastHZChange; - } - - public static void setLastHZChange(long lastChange) { - lastHZChange = lastChange; - } - public static void trainerInfo(TrainerInfoMsg msg, ClientConnection origin) { NPC npc = NPC.getFromCache(msg.getObjectID()); @@ -326,6 +317,9 @@ public class WorldServer { Logger.info("Loading Realms"); Realm.loadAllRealms(); + Logger.info("Loading RealmMap"); + RealmMap.loadRealmImageMap(); + Logger.info("Loading Kits"); DbManager.KitQueries.GET_ALL_KITS(); @@ -334,10 +328,6 @@ public class WorldServer { Logger.info("Starting InterestManager."); WorldGrid.startLoadJob(); - - - Logger.info("Loading Spaital Hash"); - RealmMap.loadRealmImageMap(); DbManager.MobBaseQueries.SET_AI_DEFAULTS(); @@ -431,13 +421,9 @@ public class WorldServer { Logger.info("Running Heraldry Audit for Deleted Players"); Heraldry.AuditHeraldry(); - if (ZoneManager.getHotZone() != null) - WorldServer.setLastHZChange(System.currentTimeMillis()); - Logger.info("Starting Mobile AI FSM"); MobileFSMManager.getInstance(); - for (Zone zone : ZoneManager.getAllZones()) { if (zone.getHeightMap() != null) { if (zone.getHeightMap().getBucketWidthX() == 0) { @@ -483,6 +469,7 @@ public class WorldServer { Logger.info("Running garbage collection..."); System.gc(); + return true; } diff --git a/src/engine/util/MapLoader.java b/src/engine/util/MapLoader.java index b2ac6849..cdc1b503 100644 --- a/src/engine/util/MapLoader.java +++ b/src/engine/util/MapLoader.java @@ -4,7 +4,7 @@ package engine.util; -import engine.Enum.RealmType; +import engine.InterestManagement.RealmMap; import engine.server.MBServerStatics; import engine.server.world.WorldServer; import org.pmw.tinylog.Logger; @@ -26,8 +26,7 @@ public enum MapLoader { long timeToLoad = System.currentTimeMillis(); long bytesRead = 0; long realmsWritten = 0; - - Integer realmUUID = null; + int realmUUID; // Load image from disk @@ -46,12 +45,6 @@ public enum MapLoader { // Flip image on the y axis image = flipImage(image); - - // Initialize color lookup table - - for (RealmType realm : RealmType.values()) { - realm.addToColorMap(); - } // Load spatial imageMap with color data from file @@ -59,21 +52,15 @@ public enum MapLoader { for (int j = 0; j < MBServerStatics.SPATIAL_HASH_BUCKETSX; j++) { try { int rgb = image.getRGB(j, i); - realmUUID = RealmType.getRealmIDByRGB(rgb); - - if (realmUUID == null) { - Logger.error("Corrupted png: unknown color " + rgb); - WorldServer.shutdown(); - } + realmUUID = RealmMap.getRealmIDByRGB(rgb); - realmMap[j][i] = realmUUID.intValue(); + realmMap[j][i] = realmUUID; bytesRead++; - if (realmUUID.intValue() != 0) + if (realmUUID != 0) realmsWritten++; }catch (Exception e){ - // Logger.error("REALMEDIT ERROR", e.getMessage()); continue; } @@ -82,9 +69,7 @@ public enum MapLoader { } timeToLoad = System.currentTimeMillis() - timeToLoad; - Logger.info( bytesRead + " pixels processed in " + timeToLoad / 1000 + " seconds"); - Logger.info("Realm pixels written : " + realmsWritten); - image = null; + Logger.info( bytesRead + "Realm imageMNap pixels processed in " + timeToLoad / 1000 + " seconds"); return realmMap; } diff --git a/src/engine/workthreads/HourlyJobThread.java b/src/engine/workthreads/HourlyJobThread.java index 059072e0..dbf17e0c 100644 --- a/src/engine/workthreads/HourlyJobThread.java +++ b/src/engine/workthreads/HourlyJobThread.java @@ -29,111 +29,10 @@ import static engine.server.MBServerStatics.MINE_LATE_WINDOW; public class HourlyJobThread implements Runnable { - private static final int hotzoneCount = 0; - public HourlyJobThread() { } - public void run() { - - // *** REFACTOR: TRY TRY TRY TRY {{{{{{{{{{{ OMG - - Logger.info("Hourly job is now running."); - - try { - - ZoneManager.generateAndSetRandomHotzone(); - Zone hotzone = ZoneManager.getHotZone(); - - if (hotzone == null) { - Logger.error("Null hotzone returned from mapmanager"); - } else { - Logger.info("new hotzone: " + hotzone.getName()); - WorldServer.setLastHZChange(System.currentTimeMillis()); - } - - } catch (Exception e) { - Logger.error(e.toString()); - } - - // Open or Close mines for the current mine window. - - processMineWindow(); - - // Deposit mine resources to Guilds - - for (Mine mine : Mine.getMines()) { - - try { - mine.depositMineResources(); - } catch (Exception e) { - Logger.info(e.getMessage() + " for Mine " + mine.getObjectUUID()); - } - } - - // Reset time-gated access to WOO slider. - // *** Do this after the mines open/close! - - if (LocalDateTime.now().getHour() == MINE_LATE_WINDOW) { - Guild guild; - - for (AbstractGameObject dbObject : DbManager.getList(Enum.GameObjectType.Guild)) { - guild = (Guild) dbObject; - - if (guild != null) - guild.wooWasModified = false; - } - } - - - // Mines can only be claimed once per cycle. - // This will reset at 1am after the last mine - // window closes. - - if (LocalDateTime.now().getHour() == MINE_LATE_WINDOW + 1) { - - for (Mine mine : Mine.getMines()) { - - if (mine.wasClaimed == true) - mine.wasClaimed = false; - } - } - - // Decay Shrines at midnight every day - - if (LocalDateTime.now().getHour() == MINE_LATE_WINDOW) - decayShrines(); - - // Update city population values - - ConcurrentHashMap map = DbManager.getMap(Enum.GameObjectType.City); - - if (map != null) { - - for (AbstractGameObject ago : map.values()) { - - City city = (City) ago; - - if (city != null) - if (city.getGuild() != null) { - ArrayList guildList = Guild.GuildRoster(city.getGuild()); - city.setPopulation(guildList.size()); - } - } - City.lastCityUpdate = System.currentTimeMillis(); - } else { - Logger.error("missing city map"); - } - - // Log metrics to console - Logger.info(WorldServer.getUptimeString()); - Logger.info(SimulationManager.getPopulationString()); - Logger.info(MessageDispatcher.getNetstatString()); - Logger.info(PurgeOprhans.recordsDeleted.toString() + "orphaned items deleted"); - } - - public static void decayShrines() { ArrayList shrineList = new ArrayList<>(); @@ -181,14 +80,15 @@ public class HourlyJobThread implements Runnable { ArrayList mines = Mine.getMines(); for (Mine mine : mines) { - + if (LocalDateTime.now().getHour() == 1400) { + mine.wasClaimed = false; + } try { // Open Errant Mines if (mine.getOwningGuild().isEmptyGuild()) { HourlyJobThread.mineWindowOpen(mine); - Mine.setLastChange(System.currentTimeMillis()); continue; } @@ -198,14 +98,12 @@ public class HourlyJobThread implements Runnable { if (mine.getOwningGuild().getNation().getMineTime() == LocalDateTime.now().getHour() && mine.wasClaimed == false) { HourlyJobThread.mineWindowOpen(mine); - Mine.setLastChange(System.currentTimeMillis()); continue; } - // Close all the remaining mines + // Close the mine if it reaches this far - if (mineWindowClose(mine)) - Mine.setLastChange(System.currentTimeMillis()); + mineWindowClose(mine); } catch (Exception e) { Logger.error("mineID: " + mine.getObjectUUID(), e.toString()); @@ -265,8 +163,6 @@ public class HourlyJobThread implements Runnable { mine.nationName = nation.getName(); mine.nationTag = nation.getGuildTag(); - Mine.setLastChange(System.currentTimeMillis()); - mineBuilding.rebuildMine(); WorldGrid.updateObject(mineBuilding); @@ -286,4 +182,108 @@ public class HourlyJobThread implements Runnable { mine.wasClaimed = true; return true; } + + public void run() { + + // *** REFACTOR: TRY TRY TRY TRY {{{{{{{{{{{ OMG + + Logger.info("Hourly job is now running."); + + try { + + // Use the same hotZone this hour up and until + // the HotZone_Duration from the ConfigManager + + if (ZoneManager.hotZone == null) + ZoneManager.generateAndSetRandomHotzone(); + else + ZoneManager.hotZoneCycle = ZoneManager.hotZoneCycle + 1; + + if (ZoneManager.hotZoneCycle > Integer.parseInt(ConfigManager.MB_HOTZONE_DURATION.getValue())) + ZoneManager.generateAndSetRandomHotzone(); + + if (ZoneManager.hotZone == null) { + Logger.error("Null HotZone returned from ZoneManager"); + } else { + Logger.info("HotZone switched to: " + ZoneManager.hotZone.getName()); + } + + } catch (Exception e) { + Logger.error(e.toString()); + } + + // Open or Close mines for the current mine window. + + processMineWindow(); + + // Deposit mine resources to Guilds + + for (Mine mine : Mine.getMines()) { + + try { + mine.depositMineResources(); + } catch (Exception e) { + Logger.info(e.getMessage() + " for Mine " + mine.getObjectUUID()); + } + } + + // Reset time-gated access to WOO slider. + // *** Do this after the mines open/close! + + if (LocalDateTime.now().getHour() == MINE_LATE_WINDOW) { + Guild guild; + + for (AbstractGameObject dbObject : DbManager.getList(Enum.GameObjectType.Guild)) { + guild = (Guild) dbObject; + + if (guild != null) + guild.wooWasModified = false; + } + } + + // Mines can only be claimed once per cycle. + // This will reset at 1am after the last mine + // window closes. + + if (LocalDateTime.now().getHour() == MINE_LATE_WINDOW + 1) { + + for (Mine mine : Mine.getMines()) { + + if (mine.wasClaimed == true) + mine.wasClaimed = false; + } + } + + // Decay Shrines at midnight every day + + if (LocalDateTime.now().getHour() == MINE_LATE_WINDOW) + decayShrines(); + + // Update city population values + + ConcurrentHashMap map = DbManager.getMap(Enum.GameObjectType.City); + + if (map != null) { + + for (AbstractGameObject ago : map.values()) { + + City city = (City) ago; + + if (city != null) + if (city.getGuild() != null) { + ArrayList guildList = Guild.GuildRoster(city.getGuild()); + city.setPopulation(guildList.size()); + } + } + City.lastCityUpdate = System.currentTimeMillis(); + } else { + Logger.error("missing city map"); + } + + // Log metrics to console + Logger.info(WorldServer.getUptimeString()); + Logger.info(SimulationManager.getPopulationString()); + Logger.info(MessageDispatcher.getNetstatString()); + Logger.info(PurgeOprhans.recordsDeleted.toString() + "orphaned items deleted"); + } }