diff --git a/cfg/features.cfg b/cfg/features.cfg index e1a6df7d5..f4439dedf 100644 --- a/cfg/features.cfg +++ b/cfg/features.cfg @@ -1 +1 @@ -# 26/07/2015 10:34:39 CDT +# 12/08/2015 21:56:03 CDT diff --git a/cfg/network.cfg b/cfg/network.cfg index 1739f7292..4989a3ff9 100644 --- a/cfg/network.cfg +++ b/cfg/network.cfg @@ -1,4 +1,4 @@ -# 26/07/2015 10:34:39 CDT +# 12/08/2015 21:56:03 CDT AUTO-LOGIN=0 LOGIN-PORT=44453 LOGIN-SERVER-ID=1 diff --git a/cfg/nge.cfg b/cfg/nge.cfg index 9837e863f..8d3531624 100644 --- a/cfg/nge.cfg +++ b/cfg/nge.cfg @@ -1,4 +1,4 @@ -# 26/07/2015 10:34:39 CDT +# 12/08/2015 21:56:03 CDT CLEAN-CHARACTER-DATA=0 ENABLE-LOGGING=true GALAXY-MAX-CHARACTERS=5 diff --git a/scripts/commands/generic/dumpZoneInformation.js b/scripts/commands/generic/dumpZoneInformation.js new file mode 100644 index 000000000..48dc03b52 --- /dev/null +++ b/scripts/commands/generic/dumpZoneInformation.js @@ -0,0 +1,23 @@ +var execute = function(galManager, player, target, args) { + creature = player.getCreatureObject(); + worldLocation = creature.getWorldLocation(); + cellLocation = creature.getLocation(); + parent = creature.getParent(); + intentFactory.sendSystemMessage(player, "Position: " + worldLocation.getPosition()); + intentFactory.sendSystemMessage(player, "Orientation: " + worldLocation.getOrientation()); + if (parent != null) { + intentFactory.sendSystemMessage(player, " Cell Position: " + cellLocation.getPosition()); + intentFactory.sendSystemMessage(player, " Cell Orientation: " + cellLocation.getOrientation()); + if (parent instanceof Java.type('resources.objects.cell.CellObject')) { + intentFactory.sendSystemMessage(player, " Cell ID/Name: " + parent.getNumber() + " / " + parent.getCellName()); + } else { + intentFactory.sendSystemMessage(player, " Parent ID/Type: " + parent.getObjectId() + " / " + parent.getClass().getSimpleName()); + intentFactory.sendSystemMessage(player, " Parent Template: " + parent.getTemplate()); + } + grandparent = parent.getParent(); + if (grandparent != null) { + intentFactory.sendSystemMessage(player, " Grandparent ID/Type: " + grandparent.getObjectId() + " / " + grandparent.getClass().getSimpleName()); + intentFactory.sendSystemMessage(player, " Grandparent Template: " + grandparent.getTemplate()); + } + } +}; \ No newline at end of file diff --git a/scripts/radial/terminal/bank.js b/scripts/radial/terminal/bank.js index 312e8d5b1..1df0008f8 100644 --- a/scripts/radial/terminal/bank.js +++ b/scripts/radial/terminal/bank.js @@ -1,22 +1,26 @@ var getOptions = function(options, player, target) { - use = new RadialOption(RadialItem.ITEM_USE); - use.addChild(new RadialOption(RadialItem.BANK_TRANSFER)); - use.addChild(new RadialOption(RadialItem.BANK_ITEMS)); + var use = new RadialOption(RadialItem.ITEM_USE); + var reserve = new RadialOption(RadialItem.BANK_RESERVE); + var creature = player.getCreatureObject(); options.add(use); options.add(new RadialOption(RadialItem.EXAMINE)); - creature = player.getCreatureObject(); - if (creature.getBankBalance() > 0) - use.addChild(new RadialOption(RadialItem.BANK_WITHDRAW_ALL)); - if (creature.getCashBalance() > 0) - use.addChild(new RadialOption(RadialItem.BANK_DEPOSIT_ALL)); - if (creature.getBankBalance() >= 1E9 || creature.getCashBalance() >= 1E9 || creature.getReserveBalance() > 0) { - reserve = new RadialOption(RadialItem.BANK_RESERVE); - if (creature.getBankBalance() >= 1E9 || creature.getCashBalance() >= 1E9) - reserve.addChild(new RadialOption(RadialItem.BANK_RESERVE_DEPOSIT)); - if (creature.getReserveBalance() > 0) - reserve.addChild(new RadialOption(RadialItem.BANK_RESERVE_WITHDRAW)); + if (creature.getCurrentCity().equals("@corellia_region_names:coronet") || + creature.getCurrentCity().equals("@naboo_region_names:theed") || + creature.getCurrentCity().equals("@tatooine_region_names:mos_eisley")) options.add(reserve); - } + // Bank Transfer/Safety Deposit + use.addChild(RadialItem.BANK_TRANSFER); + use.addChild(RadialItem.BANK_ITEMS); + // Withdraw/Deposit + if (creature.getBankBalance() > 0) + use.addChild(RadialItem.BANK_WITHDRAW_ALL); + if (creature.getCashBalance() > 0) + use.addChild(RadialItem.BANK_DEPOSIT_ALL); + // Galactic Reserve + if (creature.getBankBalance() >= 1E9 || creature.getCashBalance() >= 1E9) + reserve.addChild(RadialItem.BANK_RESERVE_DEPOSIT); + if (creature.getReserveBalance() > 0) + reserve.addChild(RadialItem.BANK_RESERVE_WITHDRAW); }; var handleSelection = function(player, target, selection) { switch (selection) { @@ -50,7 +54,7 @@ var handleSelection = function(player, target, selection) { creature.setCashBalance(creature.getCashBalance() + amount); creature.setBankBalance(0); if (amount > 0) - intentFactory.sendSystemMessage(player, "You successfully withdraw " + amount + " credits from your account."); + intentFactory.sendSystemMessage(player, "@base_player:prose_withdraw_success", "DI", new java.lang.Integer(amount)); else intentFactory.sendSystemMessage(player, '@error_message:bank_withdraw'); break; @@ -61,13 +65,17 @@ var handleSelection = function(player, target, selection) { creature.setBankBalance(amount + creature.getBankBalance()); creature.setCashBalance(0); if (amount > 0) - intentFactory.sendSystemMessage(player, "You successfully deposit " + amount + " credits to your account."); + intentFactory.sendSystemMessage(player, "@base_player:prose_deposit_success", "DI", new java.lang.Integer(amount)); else intentFactory.sendSystemMessage(player, '@error_message:bank_deposit'); break; } case RadialItem.BANK_RESERVE_DEPOSIT: { creature = player.getCreatureObject(); + if (!creature.canPerformGalacticReserveTransaction()) { + intentFactory.sendSystemMessage(player, "You have to wait to perform another Galactic Reserve transaction"); + break; + } amount = creature.getBankBalance(); if (amount > 1E9) amount = 1E9; @@ -77,10 +85,15 @@ var handleSelection = function(player, target, selection) { } creature.setBankBalance(creature.getBankBalance() - amount); creature.setReserveBalance(creature.getReserveBalance() + amount); + creature.updateLastGalacticReserveTime(); break; } case RadialItem.BANK_RESERVE_WITHDRAW: { creature = player.getCreatureObject(); + if (!creature.canPerformGalacticReserveTransaction()) { + intentFactory.sendSystemMessage(player, "You have to wait to perform another Galactic Reserve transaction"); + break; + } amount = creature.getReserveBalance(); if (amount > 1E9) amount = 1E9; @@ -90,6 +103,7 @@ var handleSelection = function(player, target, selection) { } creature.setBankBalance(creature.getBankBalance() + amount); creature.setReserveBalance(creature.getReserveBalance() - amount); + creature.updateLastGalacticReserveTime(); break; } } diff --git a/serverdata/map/cities.sdb b/serverdata/map/cities.sdb new file mode 100644 index 000000000..6873b6856 --- /dev/null +++ b/serverdata/map/cities.sdb @@ -0,0 +1,45 @@ +id city terrain x z radius +INTEGER PRIMARY KEY AUTOINCREMENT TEXT NOT NULL TEXT NOT NULL INTEGER NOT NULL INTEGER NOT NULL INTEGER NOT NULL +1 @corellia_region_names:coronet corellia -178 -4504 581 +2 @corellia_region_names:tyrena corellia -5282 -2526 622 +3 @dantooine_region_names:dantari_village_1 dantooine -3843 -5713 70 +4 @dantooine_region_names:dantari_village_2 dantooine -7202 -859 90 +5 @dantooine_region_names:dantari_village_3 dantooine 5550 -654 65 +6 @dantooine_region_names:imperial_outpost dantooine -4224 -2400 350 +7 @dantooine_region_names:dantooine_mining_outpost dantooine -622 2488 400 +8 @dantooine_region_names:dantooine_pirate_outpost dantooine 1588 -6390 400 +9 @dathomir_region_names:dathomir_trade_outpost dathomir 599 3071 400 +10 @dathomir_region_names:dathomir_survey_outpost dathomir -85 -1600 400 +11 @endor_region_names:ewok_village_tree_1 endor 84 39 80 +12 @endor_region_names:ewok_village_tree_2 endor 4545 -2395 128 +13 @endor_region_names:ewok_lake_village_1 endor 1435 -3190 150 +14 @endor_region_names:ewok_lake_village_2 endor -573 -5040 175 +15 @endor_region_names:dulok_village_1 endor 6068 -2475 100 +16 @endor_region_names:dulok_village_2 endor -1211 2952 128 +17 @endor_region_names:endor_smuggler_outpost endor -898 1587 400 +18 @endor_region_names:endor_neutral_outpost endor 3222 -3467 400 +19 @kashyyyk_region_names:kachirho kashyyyk -530 -90 225 +20 @lok_region_names:lok_nyms_stronghold lok 436 5120 429 +21 @lok_region_names:lok_imperial_outpost lok -1920 -3084 201 +22 @naboo_region_names:kaadara circle 5168 6704 320 +23 @naboo_region_names:keren naboo 336 2140 2512 +24 @naboo_region_names:moenia naboo 4800 -4784 336 +25 @naboo_region_names:theed naboo -6160 3920 -4480 +26 @rori_region_names:narmle rori -5200 -2288 392 +27 @rori_region_names:restuss rori 5318 5680 700 +28 @rori_region_names:sdungeon_rebel_outpost rori 3677 -6447 150 +29 @talus_region_names:dearic talus 425 -3000 400 +30 @talus_region_names:nashal talus 4360 5251 350 +31 @talus_region_names:talus_imperial_outpost talus -2178 2300 240 +32 @tatooine_region_names:bestine tatooine -1218 -3688 336 +33 @tatooine_region_names:fort_tusken tatooine -3900 6260 250 +34 @tatooine_region_names:jabbas_palace tatooine -5983 -6267 500 +35 @tatooine_region_names:mos_eisley tatooine 3460 -4768 456 +36 @tatooine_region_names:mos_entha tatooine 1488 3256 424 +37 @tatooine_region_names:mos_espa tatooine -2940 2190 533 +38 @tatooine_region_names:mos_teike tatooine 3832 2360 264 +39 @tatooine_region_names:wayfar tatooine -5174 -6582 230 +40 @tatooine_region_names:anchorhead tatooine 102 -5360 125 +41 @yavin4_region_names:yavin4_labor_outpost yavin4 -6925 -5707 200 +42 @yavin4_region_names:yavin4_mining_outpost yavin4 -307 4861 200 +43 @yavin4_region_names:yavin4_imperial_fort yavin4 4030 -6215 200 diff --git a/serverdata/map/static_city_points.sdf b/serverdata/map/static_city_points.sdf index 8b293e0a1..f80d06a2d 100644 --- a/serverdata/map/static_city_points.sdf +++ b/serverdata/map/static_city_points.sdf @@ -1,10 +1,10 @@ planet city x z s s f f -tatooine Mos Eisley 3528 -4804 tatooine Bestine -1290 -3590 tatooine Mos Espa -2902 2130 tatooine Mos Entha 1291 3138 tatooine Wayfar -5124 -6530 +tatooine Mos Eisley 3528 -4804 tatooine Anchorhead 40 -5348 tatooine Mos Taike 3813 2354 corellia Coronet -178 -4504 @@ -31,7 +31,7 @@ dantooine Mining Outpost -640 2486 dantooine Pirate Outpost 1588 -6399 dantooine Imperial Outpost -4224 -2400 dathomir Trade Outpost 599 3071 -dathomir Quarentine Zone -6358 930 +dathomir Quarentine Zone -5780 -6550 dathomir Science Outpost -85 -1600 lok Nym's Stronghold 440 5029 lok Imperial Outpost -1920 -3084 diff --git a/serverdata/static/travel.sdb b/serverdata/static/travel.sdb new file mode 100644 index 000000000..57078737a --- /dev/null +++ b/serverdata/static/travel.sdb @@ -0,0 +1,65 @@ +planet type name x y z +TEXT NOT NULL TEXT NOT NULL TEXT NOT NULL REAL REAL REAL +corellia shuttleport Coronet Shuttle A -25 28 -4410 +corellia shuttleport Coronet Shuttle B -329 28 -4641 +corellia shuttleport Vreni Island Shuttle -5551 15 -6059 +corellia shuttleport Tyrena Shuttle A -5005 21 -2386 +corellia shuttleport Tyrena Shuttle B -5600 21 -2790 +corellia shuttleport Doaba Guerfel Shuttleport 3081 280 4994 +corellia shuttleport Kor Vella Shuttleport -3775 86 3234 +corellia shuttleport Bela Vistal Shuttleport A 6644 330 -5922 +corellia shuttleport Bela Vistal Shuttleport B 6930 330 -5534 +corellia starport Coronet Starport -75 28 -4723 +corellia starport Tyrena Starport -4998 21 -2246 +corellia starport Kor Vella Starport -3141 31 2864 +corellia starport Doaba Guerfel Starport 3358 308 5581 +dantooine starport Mining Outpost -636 3 2505 +dantooine starport Imperial Outpost -4208 3 -2350 +dantooine starport Agro Outpost 1569 4 -6415 +dathomir starport Science Outpost -49 18 -1584 +dathomir starport Trade Outpost 618 6 3092 +dathomir shuttleport Quarantine Zone -5688 511 -6468 +endor starport Smuggler Outpost -950 73 1553 +endor starport Research Outpost 3201 24 -3500 +lok starport Nym's Stronghold 479 8 5511 +naboo starport Kaadara Starport 5295 -192 6675 +naboo shuttleport Kaadara Shuttleport 5123 -192 6616 +naboo shuttleport Dee'ja Peak Shuttleport 5331 326 -1576 +naboo shuttleport Moenia Shuttleport 4961 3 -4892 +naboo shuttleport Lake Retreat Shuttleport -5494 -150 -21 +naboo shuttleport Keren Shuttleport 2021 19 2525 +naboo shuttleport Keren Shuttleport South 1567 25 2837 +naboo starport Keren Starport 1377 13 2760 +naboo starport Moenia Starport 4745 4 -4672 +naboo shuttleport Theed Shuttle A -5856 6 4172 +naboo shuttleport Theed Shuttle B -5005 6 4072 +naboo shuttleport Theed Shuttle C -5411 6 4321 +naboo starport Theed Spaceport -4866 6 4155 +rori starport Narmle Starport -5359 80 -2188 +rori shuttleport Narmle Shuttleport -5255 80 -2161 +rori starport Rebel Outpost 3693 96 -6403 +rori starport Restuss Starport 5301 80 6190 +rori shuttleport Restuss Shuttleport 5221 80 6203 +talus starport Dearic Starport 274 6 -2933 +talus shuttleport Dearic Shuttleport 699 6 -3042 +talus starport Nashal Starport 4461 2 5342 +talus shuttleport Nashal Shuttleport 4334 9 5431 +talus starport Imperial Outpost -2227 20 2322 +tatooine starport Bestine Starport -1350 12 -3586 +tatooine starport Mos Eisley Starport 3592 5 -4793 +tatooine starport Mos Espa Starport -2844 5 2097 +tatooine starport Mos Entha Starport 1257 7 3079 +tatooine shuttleport Anchorhead Shuttle 46 52 -5338 +tatooine shuttleport Mos Entha Shuttleport A 1730 7 3184 +tatooine shuttleport Mos Entha Shuttleport B 1394 7 3468 +tatooine shuttleport Mos Espa Shuttle West -3112 5 2174 +tatooine shuttleport Mos Espa Shuttle East -2801 5 2182 +tatooine shuttleport Mos Espa Shuttle South -2896 5 1932 +tatooine shuttleport Mos Eisley Shuttleport 3418 4 -4647 +tatooine shuttleport Bestine Shuttleport -1098 12 -3562 +tatooine shuttleport Wayfar Shuttleport -5089 75 -6611 +yavin4 starport Imperial Base 4054 37 -6216 +yavin4 starport Labor Outpost -6922 73 -5727 +yavin4 starport Mining Outpost -267 35 4896 +kashyyyk_main starport Kachirho Starport -689 21 -170 +mustafar starport Mensix Mining Facility 407 230 -1355 \ No newline at end of file diff --git a/src/network/packets/swg/zone/chat/ChatOnLeaveRoom.java b/src/network/packets/swg/zone/chat/ChatOnLeaveRoom.java index 322c72264..25d192506 100644 --- a/src/network/packets/swg/zone/chat/ChatOnLeaveRoom.java +++ b/src/network/packets/swg/zone/chat/ChatOnLeaveRoom.java @@ -39,7 +39,11 @@ public class ChatOnLeaveRoom extends SWGPacket { private int result; private int chatRoomId; private int sequence; - + + public ChatOnLeaveRoom() { + + } + public ChatOnLeaveRoom(ChatAvatar avatar, int result, int chatRoomId, int sequence) { this.avatar = avatar; this.result = result; diff --git a/src/network/packets/swg/zone/spatial/GetMapLocationsResponseMessage.java b/src/network/packets/swg/zone/spatial/GetMapLocationsResponseMessage.java index 966be2a5d..618721ba1 100644 --- a/src/network/packets/swg/zone/spatial/GetMapLocationsResponseMessage.java +++ b/src/network/packets/swg/zone/spatial/GetMapLocationsResponseMessage.java @@ -44,7 +44,11 @@ public class GetMapLocationsResponseMessage extends SWGPacket { private int staticLocVersion; private int dynamicLocVersion; private int persistentLocVersion; - + + public GetMapLocationsResponseMessage() { + + } + public GetMapLocationsResponseMessage(String planet, List staticLocs, List dynamicLocs, List persistLocs, int staticLocVersion, int dynamicLocVersion, int persistLocVersion) { diff --git a/src/resources/commands/Command.java b/src/resources/commands/Command.java index 483711d11..ba5dee02a 100644 --- a/src/resources/commands/Command.java +++ b/src/resources/commands/Command.java @@ -33,8 +33,10 @@ public class Command { private String name; // defaultPriority - private String scriptCallback; + private String scriptHook; + // fail + private String cppHook; private Class javaCallback; // fail private float defaultTime; @@ -72,8 +74,10 @@ public class Command { public void setCrc(int crc) { this.crc = crc; } public String getName() { return name; } public void setName(String name) { this.name = name; } - public String getScriptCallback() { return scriptCallback; } - public void setScriptCallback(String scriptCallback) { this.scriptCallback = scriptCallback; } + public String getScriptHook() { return scriptHook; } + public void setScriptHook(String scriptHook) { this.scriptHook = scriptHook; } + public String getCppHook() { return cppHook; } + public void setCppHook(String cppHook) { this.cppHook = cppHook; } public Class getJavaCallback() { return javaCallback; } public void setJavaCallback(Class javaCallback) { this.javaCallback = javaCallback; } public boolean hasJavaCallback() { return javaCallback != null; } @@ -109,6 +113,8 @@ public class Command { public void setCooldownTime2(int cooldownTime2) { this.cooldownTime2 = cooldownTime2; } public boolean isAutoAddToToolbar() { return autoAddToToolbar; } public void setAutoAddToToolbar(boolean autoAddToToolbar) { this.autoAddToToolbar = autoAddToToolbar; } + + public String getDefaultScriptCallback(){ return (scriptHook == null || scriptHook.isEmpty()) ? cppHook : scriptHook; } @Override public String toString() { diff --git a/src/resources/encodables/ProsePackage.java b/src/resources/encodables/ProsePackage.java index c0b0ee2bd..c231bd38d 100644 --- a/src/resources/encodables/ProsePackage.java +++ b/src/resources/encodables/ProsePackage.java @@ -86,10 +86,7 @@ public class ProsePackage implements OutOfBandData, Serializable { */ public ProsePackage(Object ... objects) { int length = objects.length; - for (int i = 0; i < length; i++) { - if (i == length-1) - return; - + for (int i = 0; i < length-1; i++) { if (!(objects[i] instanceof String)) // Make sure that it's a key, chance of it being a customString though continue; @@ -113,6 +110,7 @@ public class ProsePackage implements OutOfBandData, Serializable { setTO(prose); break; case "DI": + System.out.println(prose.getClass().getSimpleName()); if (prose instanceof Integer) setDI((Integer) prose); else { System.err.println("DI can only be a Integer!"); } diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 3b2e0974e..233323596 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -50,6 +50,8 @@ public class CreatureObject extends TangibleObject { private static final long serialVersionUID = 1L; + private transient long lastReserveOperation = 0; + private Posture posture = Posture.UPRIGHT; private Race race = Race.HUMAN; private double movementScale = 1; @@ -90,6 +92,7 @@ public class CreatureObject extends TangibleObject { private long ownerId = 0; private int battleFatigue = 0; private long statesBitmask = 0; + private String currentCity = ""; private HologramColour hologramColour = HologramColour.DEFAULT; private SWGList baseAttributes = new SWGList(BaselineType.CREO, 1, 2); @@ -254,6 +257,10 @@ public class CreatureObject extends TangibleObject { return difficulty; } + public String getCurrentCity() { + return currentCity; + } + public PlayerObject getPlayerObject() { return (PlayerObject) (hasSlot("ghost") ? getSlottedObject("ghost") : null); } @@ -322,6 +329,14 @@ public class CreatureObject extends TangibleObject { this.reserveBalance = reserveBalance; } + public boolean canPerformGalacticReserveTransaction() { + return (System.nanoTime() - lastReserveOperation) / 1E9 >= 15*60; + } + + public void updateLastGalacticReserveTime() { + lastReserveOperation = System.nanoTime(); + } + public void setMovementScale(double movementScale) { this.movementScale = movementScale; sendDelta(4, 5, movementScale); @@ -407,6 +422,10 @@ public class CreatureObject extends TangibleObject { sendDelta(6, 26, difficulty.getDifficulty()); } + public void setCurrentCity(String currentCity) { + this.currentCity = currentCity; + } + public String getMoodAnimation() { return moodAnimation; } diff --git a/src/resources/radial/RadialOption.java b/src/resources/radial/RadialOption.java index 4f73f5e01..7d7c3e65d 100644 --- a/src/resources/radial/RadialOption.java +++ b/src/resources/radial/RadialOption.java @@ -46,6 +46,7 @@ public class RadialOption { public void setItem(RadialItem item) { this.item = item; } public void addChild(RadialOption option) { this.children.add(option); } + public void addChild(RadialItem item) { addChild(new RadialOption(item)); } public int getId() { return item.getId(); } public int getOptionType() { return item.getOptionType(); } diff --git a/src/services/commands/CommandService.java b/src/services/commands/CommandService.java index 740df2f3e..6b6b0cc01 100644 --- a/src/services/commands/CommandService.java +++ b/src/services/commands/CommandService.java @@ -30,9 +30,6 @@ package services.commands; import intents.chat.ChatCommandIntent; import intents.network.GalacticPacketIntent; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; import network.packets.Packet; import network.packets.swg.zone.object_controller.CommandQueueEnqueue; @@ -51,14 +48,23 @@ import resources.server_info.Log; import utilities.Scripts; import services.galaxy.GalacticManager; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.Map; + + public class CommandService extends Service { - private final Map commands; // NOTE: CRC's are all lowercased for commands! - private final Map commandCrcLookup; + private final Map commands; // NOTE: CRC's are all lowercased for commands! + private final Map commandCrcLookup; + private final Map > commandByScript; public CommandService() { commands = new HashMap<>(); commandCrcLookup = new HashMap<>(); + commandByScript = new HashMap<>(); } @Override @@ -128,7 +134,7 @@ public class CommandService extends Service { } } else - Scripts.invoke("commands/generic/" + command.getScriptCallback(), "execute", galacticManager, player, target, args); + Scripts.invoke("commands/generic/" + command.getDefaultScriptCallback(), "execute", galacticManager, player, target, args); } private void loadBaseCommands() { @@ -145,13 +151,11 @@ public class CommandService extends Service { for (int row = 0; row < baseCommands.getRowCount(); row++) { Object [] cmdRow = baseCommands.getRow(row); - String callback = (String) cmdRow[2]; - if (callback.isEmpty()) - callback = (String) cmdRow[4]; - + Command command = new Command((String) cmdRow[0]); command.setCrc(CRC.getCrc(command.getName().toLowerCase(Locale.ENGLISH))); - command.setScriptCallback(callback); + command.setScriptHook((String) cmdRow[2]); + command.setCppHook((String)cmdRow[4]); command.setDefaultTime((float) cmdRow[6]); command.setCharacterAbility((String) cmdRow[7]); @@ -159,17 +163,32 @@ public class CommandService extends Service { } } - private void registerCallback(String command, Class callback) { + private Command registerCallback(String command, Class callback) { + Command comand = getCommand(command); + registerCallback(comand, callback); + return comand; + } + + private void registerCallback(Command command, Class callback) { try { if (callback.getConstructor() == null) throw new IllegalArgumentException("Incorrectly registered callback class. Class must extend ICmdCallback and have an empty constructor: " + callback.getName()); } catch (NoSuchMethodException e) { e.printStackTrace(); } - getCommand(command).setJavaCallback(callback); + command.setJavaCallback(callback); + + List scriptCommands = getCommandsByScript(command.getDefaultScriptCallback()); + for(Command unregistered : scriptCommands){ + if(unregistered != command && !unregistered.hasJavaCallback()){ + registerCallback(unregistered, command.getJavaCallback()); + } + } + } private void registerCallbacks() { + registerCallback("waypoint", WaypointCmdCallback.class); registerCallback("requestWaypointAtPosition", RequestWaypointCmdCallback.class); registerCallback("server", ServerCmdCallback.class); @@ -201,6 +220,12 @@ public class CommandService extends Service { return getCommand(commandCrcLookup.get(name)); } } + + private List getCommandsByScript(String script) { + synchronized (commandByScript){ + return commandByScript.get(script); + } + } private Command getCommand(int crc) { synchronized (commands) { @@ -221,6 +246,16 @@ public class CommandService extends Service { synchronized (commandCrcLookup) { commandCrcLookup.put(command.getName(), command.getCrc()); } + synchronized (commandByScript){ + String script = command.getDefaultScriptCallback(); + List commands = commandByScript.get(script); + + if(commands == null){ + commands = new LinkedList(); + commandByScript.put(script, commands); + } + commands.add(command); + } } } diff --git a/src/services/galaxy/ConnectionService.java b/src/services/galaxy/ConnectionService.java index 22948cb63..4e3c25d29 100644 --- a/src/services/galaxy/ConnectionService.java +++ b/src/services/galaxy/ConnectionService.java @@ -184,7 +184,8 @@ public class ConnectionService extends Service { CreatureObject creature = zpsi.getCreature(); removeFromLists(before); updatePlayTime(before); - creature.getPlayerObject().clearFlagBitmask(PlayerFlags.LD); + if (creature.getPlayerObject() != null) + creature.getPlayerObject().clearFlagBitmask(PlayerFlags.LD); Log.i("ConnectionService", "Logged out %s with character %s", before.getUsername(), before.getCharacterName()); new PlayerEventIntent(before, before.getGalaxyName(), PlayerEvent.PE_LOGGED_OUT).broadcast(); Log.i("ConnectionService", "Disconnected %s with character %s and reason: %s", before.getUsername(), before.getCharacterName(), DisconnectReason.NEW_CONNECTION_ATTEMPT); diff --git a/src/services/map/CityService.java b/src/services/map/CityService.java new file mode 100644 index 000000000..8eee5543b --- /dev/null +++ b/src/services/map/CityService.java @@ -0,0 +1,114 @@ +package services.map; + +import java.io.FileNotFoundException; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Locale; + +import intents.PlayerEventIntent; +import intents.network.GalacticPacketIntent; +import network.packets.swg.zone.object_controller.DataTransform; +import resources.Location; +import resources.control.Intent; +import resources.control.Service; +import resources.objects.creature.CreatureObject; +import resources.player.Player; +import resources.player.PlayerEvent; +import resources.server_info.Log; +import resources.server_info.RelationalServerData; + +public class CityService extends Service { + + private static final String GET_ALL_CITIES_FROM_TERRAIN = "SELECT * FROM cities WHERE terrain = ?"; + + private final RelationalServerData spawnDatabase; + private final PreparedStatement getAllCitiesStatement; + + public CityService() { + spawnDatabase = new RelationalServerData("serverdata/map/cities.db"); + try { + spawnDatabase.linkTableWithSdb("cities", "serverdata/map/cities.sdb"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + throw new main.ProjectSWG.CoreException("Unable to load sdb files for StaticService"); + } + getAllCitiesStatement = spawnDatabase.prepareStatement(GET_ALL_CITIES_FROM_TERRAIN); + } + + @Override + public boolean initialize() { + registerForIntent(GalacticPacketIntent.TYPE); + registerForIntent(PlayerEventIntent.TYPE); + return super.initialize(); + } + + @Override + public void onIntentReceived(Intent i) { + if (i instanceof GalacticPacketIntent) { + GalacticPacketIntent gpi = (GalacticPacketIntent) i; + if (gpi.getPacket() instanceof DataTransform) { + Player player = gpi.getPlayerManager().getPlayerFromNetworkId(gpi.getNetworkId()); + if (player == null) { + Log.e("CityService", "Player is null in GalacticPacketIntent:DataTransform!"); + return; + } + CreatureObject creature = player.getCreatureObject(); + if (creature == null) { + Log.e("CityService", "Creature is null in GalacticPacketIntent:DataTransform!"); + return; + } + DataTransform transform = (DataTransform) gpi.getPacket(); + Location loc = transform.getLocation(); + performLocationUpdate(creature, loc); + } + } else if (i instanceof PlayerEventIntent) { + Player player = ((PlayerEventIntent) i).getPlayer(); + CreatureObject creature = player.getCreatureObject(); + if (((PlayerEventIntent) i).getEvent() == PlayerEvent.PE_ZONE_IN) { + performLocationUpdate(creature, creature.getLocation()); + } + } + } + + private void performLocationUpdate(CreatureObject object, Location loc) { + String terrain = loc.getTerrain().getName().toLowerCase(Locale.US); + int locX = (int) (loc.getX() + 0.5); + int locZ = (int) (loc.getZ() + 0.5); + synchronized (spawnDatabase) { + ResultSet set = null; + try { + getAllCitiesStatement.setString(1, terrain); + set = getAllCitiesStatement.executeQuery(); + while (set.next()) { + int x = set.getInt("x"); + int z = set.getInt("z"); + int radius = set.getInt("radius"); + if (distance(locX, locZ, x, z) <= radius) { + object.setCurrentCity(set.getString("city")); + return; + } + } + } catch (SQLException e) { + e.printStackTrace(); + } finally { + try { + if (set != null) + set.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } + object.setCurrentCity(""); + } + + private double distance(int x1, int z1, int x2, int z2) { + return Math.sqrt(square(x1-x2) + square(z1-z2)); + } + + private int square(int x) { + return x * x; + } + +} diff --git a/src/services/map/MapService.java b/src/services/map/MapManager.java similarity index 97% rename from src/services/map/MapService.java rename to src/services/map/MapManager.java index 6c6683de0..8b0243e27 100644 --- a/src/services/map/MapService.java +++ b/src/services/map/MapManager.java @@ -36,7 +36,7 @@ import resources.client_info.ClientFactory; import resources.client_info.ServerFactory; import resources.client_info.visitors.DatatableData; import resources.control.Intent; -import resources.control.Service; +import resources.control.Manager; import resources.objects.SWGObject; import resources.player.Player; @@ -47,7 +47,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -public class MapService extends Service { +public class MapManager extends Manager { + private final Map mapCategories; private final Map mappingTemplates; @@ -60,9 +61,11 @@ public class MapService extends Service { private final AtomicInteger staticMapVersion = new AtomicInteger(1); private final AtomicInteger dynamicMapVersion = new AtomicInteger(1); private final AtomicInteger persistMapVersion = new AtomicInteger(1); + + private final CityService cityService; - - public MapService() { + public MapManager() { + cityService = new CityService(); mapCategories = new HashMap<>(); mappingTemplates = new HashMap<>(); @@ -73,6 +76,8 @@ public class MapService extends Service { // for objects loaded from the databases, snapshots, buildouts. loadMapCategories(); loadMappingTemplates(); + + addChildService(cityService); } @Override diff --git a/src/services/objects/ObjectManager.java b/src/services/objects/ObjectManager.java index 9da299655..8c81d2cd5 100644 --- a/src/services/objects/ObjectManager.java +++ b/src/services/objects/ObjectManager.java @@ -63,13 +63,13 @@ import resources.server_info.Config; import resources.server_info.Log; import resources.server_info.ObjectDatabase; import resources.server_info.ObjectDatabase.Traverser; -import services.map.MapService; +import services.map.MapManager; import services.player.PlayerManager; import services.spawn.StaticService; public class ObjectManager extends Manager { - private final MapService mapService; + private final MapManager mapService; private final StaticService staticService; private final RadialService radialService; @@ -79,7 +79,7 @@ public class ObjectManager extends Manager { private long maxObjectId; public ObjectManager() { - mapService = new MapService(); + mapService = new MapManager(); staticService = new StaticService(this); radialService = new RadialService(); database = new CachedObjectDatabase("odb/objects.db"); @@ -190,7 +190,7 @@ public class ObjectManager extends Manager { if (obj.getObjectId() >= maxObjectId) { maxObjectId = obj.getObjectId() + 1; } - mapService.addMapLocation(obj, MapService.MapType.STATIC); + mapService.addMapLocation(obj, MapManager.MapType.STATIC); } private void loadSnapshot(SWGObject obj) { @@ -200,7 +200,7 @@ public class ObjectManager extends Manager { if (obj.getObjectId() >= maxObjectId) { maxObjectId = obj.getObjectId() + 1; } - mapService.addMapLocation(obj, MapService.MapType.STATIC); + mapService.addMapLocation(obj, MapManager.MapType.STATIC); } private void loadObject(SWGObject obj) { diff --git a/src/utilities/ByteUtilities.java b/src/utilities/ByteUtilities.java index aeadc278c..e9159dc2e 100644 --- a/src/utilities/ByteUtilities.java +++ b/src/utilities/ByteUtilities.java @@ -38,11 +38,12 @@ public class ByteUtilities { public static String getHexString(byte [] bytes) { char [] data = new char[bytes.length*2+(bytes.length>0?bytes.length-1:0)]; byte b; - for (int i = 0; i < bytes.length; i+=3) { + for (int i = 0; i < bytes.length; i++) { b = bytes[i]; - data[i+0] = HEX[(b&0xFF) >>> 4]; - data[i+1] = HEX[b & 0x0F]; - data[i+2] = ' '; + data[i*3+0] = HEX[(b&0xFF) >>> 4]; + data[i*3+1] = HEX[b & 0x0F]; + if (i*3+2 < data.length) + data[i*3+2] = ' '; } return new String(data); } diff --git a/src/utilities/IntentFactory.java b/src/utilities/IntentFactory.java index d2abf1122..4a809a9e6 100644 --- a/src/utilities/IntentFactory.java +++ b/src/utilities/IntentFactory.java @@ -60,16 +60,6 @@ public final class IntentFactory { broadcast(message, target, BroadcastType.PERSONAL); } - /** - * Sends a system message to the target as a ProsePackage. - * @param target Player receiving the message. - * @param table Table for the StringId - * @param key Key to use within the StringId - */ - public void sendSystemMessage(Player target, String table, String key) { - new ChatBroadcastIntent(target, new ProsePackage(table, key)).broadcast(); - } - /** * Sends a system message to the target as a ProsePackage which allows prose keys to be used. *

@@ -79,14 +69,18 @@ public final class IntentFactory { * Using this method is the same as:
*   new ChatBroadcastIntent(target, new ProsePackage("StringId", new StringId(table, key), objects)).broadcast(); * @param target Player receiving the system message. - * @param table Table for the StringId. - * @param key Key to use within the StringId. + * @param stf The string stf table to use for this system message. It should be formatted as such:

+ * example_key where @example refers to the stf example.stf in string/en folder and example_key is the key to use for the stf. * @param objects Collection of prose keys followed by with the value for the prose key.
As an example, ("DI", 500) would * set the %DI to the value of 500 for the StringId. * Note that the prose key must always come first and the value for that key must always come second. */ - public void sendSystemMessage(Player target, String table, String key, Object... objects) { - new ChatBroadcastIntent(target, new ProsePackage("StringId", new StringId(table, key), objects)).broadcast(); + public void sendSystemMessage(Player target, String stf, Object ... objects) { + Object [] prose = new Object[objects.length + 2]; + prose[0] = "StringId"; + prose[1] = new StringId(stf); + System.arraycopy(objects, 0, prose, 2, objects.length); + new ChatBroadcastIntent(target, new ProsePackage(prose)).broadcast(); } /**