From 3550c7ff4b148e93a341ad7c9a2a1a51d9931efb Mon Sep 17 00:00:00 2001 From: Treeku Date: Sun, 15 Dec 2013 02:15:57 +0000 Subject: [PATCH 01/10] Lifeday gifts fix --- scripts/radial/lifeday_gift.py | 2 +- scripts/radial/main_lifeday_tree.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/radial/lifeday_gift.py b/scripts/radial/lifeday_gift.py index 568a6971..55b2d057 100644 --- a/scripts/radial/lifeday_gift.py +++ b/scripts/radial/lifeday_gift.py @@ -1,6 +1,6 @@ from resources.common import RadialOptions import sys -from java.util import Random +import java.util.Random def createRadial(core, owner, target, radials): radials.clear() diff --git a/scripts/radial/main_lifeday_tree.py b/scripts/radial/main_lifeday_tree.py index 5e1f6654..6082489f 100644 --- a/scripts/radial/main_lifeday_tree.py +++ b/scripts/radial/main_lifeday_tree.py @@ -5,9 +5,9 @@ def createRadial(core, owner, target, radials): radials.clear() player = owner.getSlottedObject('ghost') radials.add(RadialOptions(0, 7, 1, '')) - if player and core.collectionService.isComplete(owner, 'col_lifeday_tree_tracking_2010'): + if player and core.collectionService.isComplete(owner, 'col_lifeday_tree_tracking_2010') == False: radials.add(RadialOptions(0, 21, 3, '@spam:tree_use')) - if player and core.collectionService.isComplete(owner, 'lifeday_badge_08'): + if player and core.collectionService.isComplete(owner, 'lifeday_badge_08') == False: radials.add(RadialOptions(0, 115, 3, '@spam:tree_badge')) return From 0c93b74f1e38cc3b2897d14b302c3298a68a8ae7 Mon Sep 17 00:00:00 2001 From: Treeku Date: Sun, 15 Dec 2013 08:53:07 +0000 Subject: [PATCH 02/10] Synchronized objectId generation Not sure if it helps, but a few of the problems seemed to look like lack of synchronization. Easy to reverse later. --- src/services/object/ObjectService.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 1e0ca7c8..5ffdd889 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -106,6 +106,8 @@ public class ObjectService implements INetworkDispatch { private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + protected final Object objectMutex = new Object(); + public ObjectService(final NGECore core) { this.core = core; databaseConnection = core.getDatabase1(); @@ -458,7 +460,12 @@ public class ObjectService implements INetworkDispatch { return objectID;*/ - long newId = highestId.incrementAndGet(); + long newId; + + synchronized(objectMutex) { + newId = highestId.incrementAndGet(); + } + PreparedStatement ps2; try { From fac5422198654df8412672840f60568fcf34eeab Mon Sep 17 00:00:00 2001 From: Treeku Date: Sun, 15 Dec 2013 08:53:50 +0000 Subject: [PATCH 03/10] ServerFirsts now award a badge --- src/resources/objects/guild/GuildObject.java | 5 ++++- src/services/collections/CollectionService.java | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/resources/objects/guild/GuildObject.java b/src/resources/objects/guild/GuildObject.java index bce71b15..a1fe7edb 100644 --- a/src/resources/objects/guild/GuildObject.java +++ b/src/resources/objects/guild/GuildObject.java @@ -270,11 +270,14 @@ public class GuildObject extends UniverseObject implements IPersistent { } } - public void addServerFirst(String collectionName, ServerFirst player) { + public boolean addServerFirst(String collectionName, ServerFirst player) { synchronized(objectMutex) { if (!serverFirst.containsKey(collectionName)) { serverFirst.put(collectionName, player); + return true; } + + return false; } } diff --git a/src/services/collections/CollectionService.java b/src/services/collections/CollectionService.java index d86ee7ad..809687f0 100644 --- a/src/services/collections/CollectionService.java +++ b/src/services/collections/CollectionService.java @@ -359,7 +359,9 @@ public class CollectionService implements INetworkDispatch { } if (trackServerFirst) { - core.guildService.getGuildObject().addServerFirst(collectionName, new ServerFirst(creature.getCustomName(), System.currentTimeMillis())); + if (core.guildService.getGuildObject().addServerFirst(collectionName, new ServerFirst(creature.getCustomName(), System.currentTimeMillis()))) { + addCollection(creature, "bdg_server_first_01"); + } } if (clearOnComplete) { From 95e372fb82e110a88c7e95d815e53c981d54120d Mon Sep 17 00:00:00 2001 From: darkk1138 Date: Sun, 15 Dec 2013 10:07:08 +0100 Subject: [PATCH 04/10] Add a factor for dance XP. Note, this implementation is not yet 100% accurate, but it should match XP values from Entertainer FAQ for all dances. --- src/services/EntertainmentService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/services/EntertainmentService.java b/src/services/EntertainmentService.java index bc564664..ee40e874 100644 --- a/src/services/EntertainmentService.java +++ b/src/services/EntertainmentService.java @@ -327,7 +327,8 @@ public class EntertainmentService implements INetworkDispatch { int floXP = p.getFlourishXpMod(); int floCount = entertainer.getFlourishCount(); - int XP = ((floCount > 2) ? 2 : floCount) * floXP; + //FIXME: this is not an accurate implementation yet. It needs group bonuses and other things. + int XP = (int) Math.round( ((floCount > 2) ? 2 : floCount) * floXP * 3.8 ); entertainer.setFlourishCount(0); core.playerService.giveExperience(entertainer, XP); From 27ca83caef72aa3eda65c8a83dc11dd12433bd0c Mon Sep 17 00:00:00 2001 From: Waverunner Date: Sun, 15 Dec 2013 07:50:56 -0500 Subject: [PATCH 05/10] Fixed nge.backup for pgadmin3 restore's --- nge.backup | Bin 31451 -> 26015 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/nge.backup b/nge.backup index 164ef16a2b5c0824ffaec926a9b8802a26623362..af82ea0786011b5b3252e20e7c444d80addfd8a9 100644 GIT binary patch literal 26015 zcmcIs2|SeD_aFOSB>OgzEFtUIcanV_B4RL>>;@HS)1p#|B(jx4V~Y^Vn>_peG{K)72v=&?_i308q#k z6&4EoKw%UM3j9xMeOOhC8t6w(9)?9w4yK^02*IO^LC8SYPFGLY)(`?Jl?Z&IZ)2!y zX9&d?Kmj{I9gOXELG299t;{e*n$R$0K(Id|3@Ho6!@UY3)J)%1-_i_MQOq#V+us-E z;|dS-4MTcDZNmU5l#HCblDrsL)6UTf)8Kmb0JE@TG_|p``b{f!#x)~>zkwzX4nl=_ zhaypAEk+Bpg?%v4$iw86AmA_Zva%3NS#Y?!zpn@QtF8VnLvvj$G@L*Y4jSyoP;5m& zyUjoms2xGUe^PIL)pEajHVe?jZ>@ve(YG`=H?*(=y&t3%?gOZ$1@yPtP-9!D7~a!x zibGKzKF9zBIrqXi2QijlS1!OH)Iru9+FJsyl5g z&7oFsJu_o{b;iG~h*wda(a1*E!j5#4c9zh8S`Xhbpd|53@Gmf_0UN-)FwUhQtE>t- zq@0|xk}PPuVE0Vp=yZD(j_SwR<&`x`5)%9FPPFVG5s9ag3Or6m?fS^_gQuHm}cHnAKGtg`HdhWBn_`s1O(i4XA>B zFopqw0gfCnC1n^mi6cBbg2DsCu#-3tpv-XbsS&7-vkCYq6kic4&Ikn_Ur(rSU>MRH z848lc0&Zp|1r`X0qmZG(P!AtOD8eHQD2_mc9t2{nxExG^plUDzg(6W=L6NW`FnRj= zld36CSkpVe%OBwlbq@;iM;Z%10w~T#v>4~e=z~&g94Zr z5yqHSZOnQMAM$VotAOLAKyYpCbZzXg6p#ZyFtz~1 zFp&wW=Lp4qWMK(4H@2|XHG><1RWN_+?q2&_Ul)kAP&ojZZ9uQsXo~NX032M`#2A5I zMrIL!og$R6D@DQpwn&m$n1v}JNSJvK4-(YU!NSl07$SDoRsxE2&Flrhq|=z@T_bFbRjl=c0t1m?5Vl2zMj%6p*xL<=|HfWnU@!T*i0~SXNe4)Trzfy!A{F=)WeLMs za8PI%o;QTk!M~>_j`hJnG`0d7UL`#kCdGiE5wnlP_=uegi|N0hVKG($coP~zRUTYV z6QN3;jfa3%2-!%iHBMgme?Ut)Kmn4pB(DWAgzNGX6L{p56-n+0Ka=DqW=}#E!*ytC z3dj-Al>8{x_)1(y_>YLIL_pj-fLhpx$X^sefAR7KS&Q)ZKL~IO!(GonAW#zV*9&On zH~x|n{5uk_8;n6dNda9E^NC!4#2$ei@4p~b304Al6MzH*(k(*3$K?7Z&#hyC6d||% zrj`Ez!7y1&k_7u3RfsWNmu0_3LBeJ07m_UdC!nrFHaIXY0QtW_-j zc27qjz2^M*f|<2s2O!`9fk=|E(g`U4jl{oJUK<(dMeg6nM<~!d z@#uf;0jcV z3Sold8%auI5}+jdU60n9fCxd1BhkVdwSO)A6MCxASL=g@P+L_*Cc&`RR83h0W*=~&wIgBR+3ZtGD-VmPTxrN1*Q(xJ9WaR7fA_2 z*E@y!dqH3iW+!L|O0NMf1zX&*0SP9@w1PKhn1AI)}D|xC#0rkmI zZ4FYK{QrP&vOxdq@{LFdVgŚI17_Ff^$!1WAI-^x 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 Date: Sun, 15 Dec 2013 08:08:31 -0500 Subject: [PATCH 06/10] Change nge.backup Encoding to UTF-8 and compress to tar for console compatibility (tested on pgadmin3 and psql console and it works) --- nge.backup | Bin 26015 -> 59392 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/nge.backup b/nge.backup index af82ea0786011b5b3252e20e7c444d80addfd8a9..1a761380f87a73eae814d2f3906a127c788c71a3 100644 GIT binary patch literal 59392 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 Date: Sun, 15 Dec 2013 17:01:26 +0000 Subject: [PATCH 07/10] Fixed disconnect bluffs deleting client objects ~experimental --- src/services/ConnectionService.java | 96 ++++++++++++++++++++++++++++- src/services/SimulationService.java | 58 +++-------------- 2 files changed, 105 insertions(+), 49 deletions(-) diff --git a/src/services/ConnectionService.java b/src/services/ConnectionService.java index 8619f799..ef84dbc0 100644 --- a/src/services/ConnectionService.java +++ b/src/services/ConnectionService.java @@ -25,7 +25,13 @@ import java.nio.ByteOrder; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import main.NGECore; @@ -42,9 +48,13 @@ import protocol.swg.HeartBeatMessage; import engine.clients.Client; import engine.resources.database.DatabaseConnection; +import engine.resources.scene.Point3D; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; import resources.common.*; +import resources.common.collidables.AbstractCollidable; +import resources.objects.creature.CreatureObject; +import resources.objects.player.PlayerObject; @SuppressWarnings("unused") @@ -53,12 +63,96 @@ public class ConnectionService implements INetworkDispatch { private NGECore core; private DatabaseConnection databaseConnection; private DatabaseConnection databaseConnection2; + + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - public ConnectionService(NGECore core) { + public ConnectionService(final NGECore core) { this.core = core; this.databaseConnection = core.getDatabase1(); this.databaseConnection2 = core.getDatabase2(); + + scheduler.scheduleAtFixedRate(new Runnable() { + + public void run() { + synchronized(core.getActiveConnectionsMap()) { + for(Client c : core.getActiveConnectionsMap().values()) { + if(c.getParent() != null) { + if ((System.currentTimeMillis() - c.getSession().getLastReadTime()) > 300000) { + disconnect(c.getSession()); + } + } + } + } + } + + public void disconnect(IoSession session) { + Client client = core.getClient((Integer) session.getAttribute("connectionId")); + + if(client == null) + return; + + if(client.getParent() == null) + return; + + CreatureObject object = (CreatureObject) client.getParent(); + object.setInviteCounter(0); + object.setInviteSenderId(0); + object.setInviteSenderName(""); + object.setClient(null); + PlayerObject ghost = (PlayerObject) object.getSlottedObject("ghost"); + + if(object.getGroupId() != 0) + core.groupService.handleGroupDisband(object); + + Point3D objectPos = object.getWorldPosition(); + + List collidables = core.simulationService.getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 512); + + for(AbstractCollidable collidable : collidables) { + collidables.remove(object); + } + + + if (ghost != null) { + String objectShortName = object.getCustomName(); + + if (object.getCustomName().contains(" ")) { + String[] splitName = object.getCustomName().toLowerCase().split(" "); + objectShortName = splitName[0]; + } + + core.chatService.playerStatusChange(objectShortName, (byte) 0); + } + + session.suspendWrite(); + + boolean remove = core.simulationService.remove(object, object.getPosition().x, object.getPosition().z); + if(remove) + System.out.println("Successful quadtree remove"); + + //if(object.getContainer() == null) { + HashSet oldObservers = new HashSet(object.getObservers()); + for(Iterator it = oldObservers.iterator(); it.hasNext();) { + Client observerClient = it.next(); + if(observerClient.getParent() != null && !(observerClient.getSession() == session)) { + observerClient.getParent().makeUnaware(object); + } + } + //} else { + // object.getContainer().remove(object); + //} + + + object.createTransaction(core.getCreatureODB().getEnvironment()); + core.getCreatureODB().put(object, Long.class, CreatureObject.class, object.getTransaction()); + object.getTransaction().commitSync(); + core.objectService.destroyObject(object); + + core.getActiveConnectionsMap().remove((Integer) session.getAttribute("connectionId")); + } + + }, 15, 15, TimeUnit.MINUTES); } diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index b671f380..2de96612 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -536,9 +536,17 @@ public class SimulationService implements INetworkDispatch { } - + /* + * Moved this to ConnectionService which will disconnect them + * from the server if they don't send packets for 5 minutes or more + * like on live. + * + * We had significant issues with client nulls due to us taking + * client disconnect requests too seriously. It has a weird tendency + * to bluff and send a disconnect packet when it's not disconnecting + * and continues sending packets. + */ public void handleDisconnect(IoSession session) { - Client client = core.getClient((Integer) session.getAttribute("connectionId")); if(client == null) @@ -554,55 +562,9 @@ public class SimulationService implements INetworkDispatch { object.setClient(null); PlayerObject ghost = (PlayerObject) object.getSlottedObject("ghost"); - if(object.getGroupId() != 0) - core.groupService.handleGroupDisband(object); - - Point3D objectPos = object.getWorldPosition(); - - List collidables = getCollidables(object.getPlanet(), objectPos.x, objectPos.z, 512); - - for(AbstractCollidable collidable : collidables) { - collidables.remove(object); - } - - - if (ghost != null) { - String objectShortName = object.getCustomName(); - - if (object.getCustomName().contains(" ")) { - String[] splitName = object.getCustomName().toLowerCase().split(" "); - objectShortName = splitName[0]; - } - - core.chatService.playerStatusChange(objectShortName, (byte) 0); - } - - session.suspendWrite(); - - boolean remove = remove(object, object.getPosition().x, object.getPosition().z); - if(remove) - System.out.println("Successful quadtree remove"); - - //if(object.getContainer() == null) { - HashSet oldObservers = new HashSet(object.getObservers()); - for(Iterator it = oldObservers.iterator(); it.hasNext();) { - Client observerClient = it.next(); - if(observerClient.getParent() != null && !(observerClient.getSession() == session)) { - observerClient.getParent().makeUnaware(object); - } - } - //} else { - // object.getContainer().remove(object); - //} - - object.createTransaction(core.getCreatureODB().getEnvironment()); core.getCreatureODB().put(object, Long.class, CreatureObject.class, object.getTransaction()); object.getTransaction().commitSync(); - core.objectService.destroyObject(object); - - core.getActiveConnectionsMap().remove((Integer) session.getAttribute("connectionId")); - } public void handleZoneIn(Client client) { From 1508bbe37bc366215349d8318d09233dde679a39 Mon Sep 17 00:00:00 2001 From: Treeku Date: Sun, 15 Dec 2013 17:55:30 +0000 Subject: [PATCH 08/10] Client null checks --- src/services/CharacterService.java | 6 +++++- src/services/SimulationService.java | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index 40e7ded9..bf123127 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -145,6 +145,10 @@ public class CharacterService implements INetworkDispatch { int length = firstName.length(); try { + if (client == null) { + System.out.println("NULL client in ClientVerifyAndLockNameRequest, something is still bust"); + return; + } if (checkForDuplicateName(firstName, client.getAccountId())) { approved_flag = "name_declined_in_use"; @@ -208,7 +212,7 @@ public class CharacterService implements INetworkDispatch { Client client = core.getClient((Integer) session.getAttribute("connectionId")); try { - if (checkForDuplicateName(getfirstName(clientCreateCharacter.getName(), clientCreateCharacter.getRaceTemplate()), client.getAccountId())) { + if (client == null || checkForDuplicateName(getfirstName(clientCreateCharacter.getName(), clientCreateCharacter.getRaceTemplate()), client.getAccountId())) { return; } } catch (SQLException e2) { diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 2de96612..a6549f9d 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -562,6 +562,8 @@ public class SimulationService implements INetworkDispatch { object.setClient(null); PlayerObject ghost = (PlayerObject) object.getSlottedObject("ghost"); + session.suspendWrite(); + object.createTransaction(core.getCreatureODB().getEnvironment()); core.getCreatureODB().put(object, Long.class, CreatureObject.class, object.getTransaction()); object.getTransaction().commitSync(); From 6fc258a8f8326694169e6cf3ced44945268f3c46 Mon Sep 17 00:00:00 2001 From: Waverunner Date: Sun, 15 Dec 2013 13:14:36 -0500 Subject: [PATCH 09/10] Waypoint color can be changed now, added missing starports to planet map, player flags now work --- scripts/commands/setgodmode.py | 1 + scripts/commands/waypoint.py | 14 ++-- .../building/military/outpost_starport.py | 3 +- .../creature/npc/theme_park/player_shuttle.py | 4 +- .../npc/theme_park/player_transport.py | 4 +- .../player_transport_theed_hangar.py | 7 +- src/protocol/swg/ChatOnGetFriendsList.java | 11 +-- src/protocol/swg/SetWaypointColor.java | 75 +++++++++++++++++++ src/resources/common/Opcodes.java | 1 + .../objects/player/PlayerMessageBuilder.java | 2 +- .../objects/player/PlayerObject.java | 5 ++ src/services/PlayerService.java | 60 +++++++++++++++ src/services/SimulationService.java | 5 ++ src/services/travel/TravelPoint.java | 1 + src/services/travel/TravelService.java | 40 +++++----- 15 files changed, 194 insertions(+), 39 deletions(-) create mode 100644 src/protocol/swg/SetWaypointColor.java diff --git a/scripts/commands/setgodmode.py b/scripts/commands/setgodmode.py index b53ea067..785de8d0 100644 --- a/scripts/commands/setgodmode.py +++ b/scripts/commands/setgodmode.py @@ -44,4 +44,5 @@ def run(core, actor, target, commandString): elif command == 'addability' and arg1: actor.addAbility(str(arg1)) actor.sendSystemMessage('You have learned ' + arg1 + '') + return diff --git a/scripts/commands/waypoint.py b/scripts/commands/waypoint.py index fddb0508..e0d3827c 100644 --- a/scripts/commands/waypoint.py +++ b/scripts/commands/waypoint.py @@ -26,7 +26,7 @@ def run(core, actor, target, commandString): name = commandString.split(" ", 5) waypoint.setName(name[5]) waypoint.setPlanetCRC(crc.StringtoCRC(planet.getName())) - actorPlayer.getWaypoints().add(waypoint) + waypoint.setStringAttribute('', '') # This simply allows the attributes to display (nothing else has to be done) actorPlayer.waypointAdd(waypoint) actor.sendSystemMessage('A waypoint has been created in your datapad at the location.', 0) return @@ -40,7 +40,7 @@ def run(core, actor, target, commandString): name = commandString.split(" ", 3) waypoint.setName(name[3]) waypoint.setPlanetCRC(crc.StringtoCRC(actor.getPlanet().getName())) - actorPlayer.getWaypoints().add(waypoint) + waypoint.setStringAttribute('', '') # This simply allows the attributes to display (nothing else has to be done) actorPlayer.waypointAdd(waypoint) actor.sendSystemMessage('A waypoint has been created in your datapad at the location.', 0) return @@ -52,7 +52,7 @@ def run(core, actor, target, commandString): name = commandString.split(" ", 2) waypoint.setName(name[2]) waypoint.setPlanetCRC(crc.StringtoCRC(actor.getPlanet().getName())) - actorPlayer.getWaypoints().add(waypoint) + waypoint.setStringAttribute('', '') # This simply allows the attributes to display (nothing else has to be done) actorPlayer.waypointAdd(waypoint) actor.sendSystemMessage('A waypoint has been created in your datapad at the location.', 0) return @@ -63,7 +63,7 @@ def run(core, actor, target, commandString): waypoint.setColor(WaypointObject.BLUE) waypoint.setName("Waypoint") waypoint.setPlanetCRC(crc.StringtoCRC(actor.getPlanet().getName())) - actorPlayer.getWaypoints().add(waypoint) + waypoint.setStringAttribute('', '') # This simply allows the attributes to display (nothing else has to be done) actorPlayer.waypointAdd(waypoint) actor.sendSystemMessage('A waypoint has been created in your datapad at the location.', 0) return @@ -79,19 +79,19 @@ def run(core, actor, target, commandString): waypoint.setName(name[5]) waypoint.setPlanetCRC(crc.StringtoCRC(actor.getPlanet().getName())) - actorPlayer.getWaypoints().add(waypoint) + waypoint.setStringAttribute('', '') # This simply allows the attributes to display (nothing else has to be done) actorPlayer.waypointAdd(waypoint) actor.sendSystemMessage('A waypoint has been created in your datapad at the location.', 0) return - #/wp NAME + #/wp else: waypoint = core.objectService.createObject('object/waypoint/shared_waypoint.iff', actor.getPlanet(), actor.getWorldPosition().x, actor.getWorldPosition().z, actor.getWorldPosition().y) waypoint.setActive(True) waypoint.setColor(WaypointObject.BLUE) waypoint.setName(commandString) waypoint.setPlanetCRC(crc.StringtoCRC(actor.getPlanet().getName())) - actorPlayer.getWaypoints().add(waypoint) + waypoint.setStringAttribute('', '') # This simply allows the attributes to display (nothing else has to be done) actorPlayer.waypointAdd(waypoint) actor.sendSystemMessage('A waypoint has been created in your datapad at your location.', 0) return diff --git a/scripts/object/building/military/outpost_starport.py b/scripts/object/building/military/outpost_starport.py index e2756165..22ca3e75 100644 --- a/scripts/object/building/military/outpost_starport.py +++ b/scripts/object/building/military/outpost_starport.py @@ -4,6 +4,7 @@ def setup(core, object): objSvc = core.objectService objSvc.createChildObject(object, 'object/creature/npc/theme_park/shared_player_transport.iff', 0, 7, 0, 0.707107, 0.707107) objSvc.createChildObject(object, 'object/tangible/travel/ticket_collector/shared_ticket_collector.iff', 1, 0, -10, 0, 1) - objSvc.createChildObject(object, 'object/tangible/terminal/shared_terminal_travel.iff', float(-3.12), float(0.14659503), float(-17.57), float(0.707107), float(-0.707107), 1) + objSvc.createChildObject(object, 'object/tangible/terminal/shared_terminal_travel.iff', float(-3.12), float(0.14659503), float(-17.57), float(0.707107), float(-0.707107), 1) + core.mapService.addLocation(object.getPlanet(), 'Starport', object.getPosition().x, object.getPosition().z, 15, 0, 0) return \ No newline at end of file diff --git a/scripts/object/creature/npc/theme_park/player_shuttle.py b/scripts/object/creature/npc/theme_park/player_shuttle.py index c2c5b2af..2fc11f63 100644 --- a/scripts/object/creature/npc/theme_park/player_shuttle.py +++ b/scripts/object/creature/npc/theme_park/player_shuttle.py @@ -3,10 +3,12 @@ import sys def setup(core, object): object.setPosture(0) # land = 0 : away = 2 object.setOptionsBitmask(256) - tp = core.travelService.getNearestTravelPoint(object) + + tp = core.travelService.getNearestTravelPoint(object, 300) if tp and tp is not None: tp.setShuttle(object) tp.setShuttleAvailable(True) tp.setShuttleLanding(False) + return return \ No newline at end of file diff --git a/scripts/object/creature/npc/theme_park/player_transport.py b/scripts/object/creature/npc/theme_park/player_transport.py index c2c5b2af..42849403 100644 --- a/scripts/object/creature/npc/theme_park/player_transport.py +++ b/scripts/object/creature/npc/theme_park/player_transport.py @@ -3,10 +3,12 @@ import sys def setup(core, object): object.setPosture(0) # land = 0 : away = 2 object.setOptionsBitmask(256) - tp = core.travelService.getNearestTravelPoint(object) + + tp = core.travelService.getNearestTravelPoint(object, 300) if tp and tp is not None: tp.setShuttle(object) tp.setShuttleAvailable(True) tp.setShuttleLanding(False) + return return \ No newline at end of file diff --git a/scripts/object/creature/npc/theme_park/player_transport_theed_hangar.py b/scripts/object/creature/npc/theme_park/player_transport_theed_hangar.py index 57a5dcc3..277d62b1 100644 --- a/scripts/object/creature/npc/theme_park/player_transport_theed_hangar.py +++ b/scripts/object/creature/npc/theme_park/player_transport_theed_hangar.py @@ -3,9 +3,12 @@ import sys def setup(core, object): object.setPosture(0) # land = 0 : away = 2 object.setOptionsBitmask(256) - tp = core.travelService.getNearestTravelPoint(object) - if tp: + + tp = core.travelService.getNearestTravelPoint(object, 500) + + if tp and tp is not None: tp.setShuttle(object) tp.setShuttleAvailable(True) tp.setShuttleLanding(False) + return return \ No newline at end of file diff --git a/src/protocol/swg/ChatOnGetFriendsList.java b/src/protocol/swg/ChatOnGetFriendsList.java index 6ee5fea6..ae0d52df 100644 --- a/src/protocol/swg/ChatOnGetFriendsList.java +++ b/src/protocol/swg/ChatOnGetFriendsList.java @@ -3,10 +3,10 @@ package protocol.swg; import java.nio.ByteOrder; import java.util.List; +import main.NGECore; + import org.apache.mina.core.buffer.IoBuffer; -import engine.resources.config.Config; -import engine.resources.config.DefaultConfig; import resources.objects.player.PlayerObject; public class ChatOnGetFriendsList extends SWGMessage { @@ -30,11 +30,6 @@ public class ChatOnGetFriendsList extends SWGMessage { @Override public IoBuffer serialize() { - Config config = new Config(); - config.setFilePath("nge.cfg"); - if (!(config.loadConfigFile())) { - config = DefaultConfig.getConfig(); - } IoBuffer buffer = IoBuffer.allocate(200).order(ByteOrder.LITTLE_ENDIAN); @@ -47,7 +42,7 @@ public class ChatOnGetFriendsList extends SWGMessage { for (String friend : player.getFriendList()) { buffer.put(getAsciiString("SWG")); - buffer.put(getAsciiString(config.getString("GALAXY_NAME"))); + buffer.put(getAsciiString(NGECore.getInstance().getConfig().getString("GALAXY_NAME"))); int friendIndex = friendList.indexOf(friend); diff --git a/src/protocol/swg/SetWaypointColor.java b/src/protocol/swg/SetWaypointColor.java new file mode 100644 index 00000000..bb53cd75 --- /dev/null +++ b/src/protocol/swg/SetWaypointColor.java @@ -0,0 +1,75 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package protocol.swg; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; + +import org.apache.mina.core.buffer.IoBuffer; + +import resources.common.StringUtilities; + +public class SetWaypointColor extends SWGMessage { + + private long objectId; + private String color; + + public SetWaypointColor() { + + } + + @Override + public void deserialize(IoBuffer data) { + //data.getShort(); + //data.getInt(); + objectId = data.getLong(); + short size = data.getShort(); + try { + color = new String(ByteBuffer.allocate(size).put(data.array(), data.position(), size).array(), "US-ASCII"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + + @Override + public IoBuffer serialize() { + + return null; + } + + public long getObjectId() { + return objectId; + } + + public void setObjectId(long objectId) { + this.objectId = objectId; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } + +} diff --git a/src/resources/common/Opcodes.java b/src/resources/common/Opcodes.java index fce03203..b9284791 100644 --- a/src/resources/common/Opcodes.java +++ b/src/resources/common/Opcodes.java @@ -58,5 +58,6 @@ public class Opcodes { public static int PlanetTravelPointListRequest = 0x96405D4D; public static int FactionRequestMessage = CRC.StringtoCRC("FactionRequestMessage"); public static int FactionResponseMessage = CRC.StringtoCRC("FactionResponseMessage"); + public static int SetWaypointColor = CRC.StringtoCRC("SetWaypointColor"); } diff --git a/src/resources/objects/player/PlayerMessageBuilder.java b/src/resources/objects/player/PlayerMessageBuilder.java index 7689f90d..c0d7a740 100644 --- a/src/resources/objects/player/PlayerMessageBuilder.java +++ b/src/resources/objects/player/PlayerMessageBuilder.java @@ -54,7 +54,7 @@ public class PlayerMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); // generic int buffer.putInt(4); // flag bitmask list size - buffer.putInt(0); + buffer.putInt(player.getFlagBitmask()); buffer.putInt(0); buffer.putInt(0); buffer.putInt(0); diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java index ecdc69bf..e55b3445 100644 --- a/src/resources/objects/player/PlayerObject.java +++ b/src/resources/objects/player/PlayerObject.java @@ -271,16 +271,21 @@ public class PlayerObject extends IntangibleObject { public void waypointRemove(WaypointObject waypoint) { synchronized(objectMutex) { getContainer().getClient().getSession().write(messageBuilder.buildWaypointRemoveDelta(waypoint)); + getWaypoints().remove(waypoint); } } public void waypointAdd(WaypointObject waypoint) { synchronized(objectMutex) { getContainer().getClient().getSession().write(messageBuilder.buildWaypointAddDelta(waypoint)); + getWaypoints().add(waypoint); } } public WaypointObject getWaypointFromList(WaypointObject waypoint) { + if (waypoint == null) + return null; + synchronized(objectMutex) { for(WaypointObject wp : waypoints) { if(wp.getObjectID() == waypoint.getObjectID()) diff --git a/src/services/PlayerService.java b/src/services/PlayerService.java index e0d001a2..edd4a958 100644 --- a/src/services/PlayerService.java +++ b/src/services/PlayerService.java @@ -41,6 +41,7 @@ import protocol.swg.ClientIdMsg; import protocol.swg.ClientMfdStatusUpdateMessage; import protocol.swg.ExpertiseRequestMessage; import protocol.swg.ServerTimeMessage; +import protocol.swg.SetWaypointColor; import protocol.swg.objectControllerObjects.ChangeRoleIconChoice; import protocol.swg.objectControllerObjects.ShowFlyText; import resources.common.Console; @@ -55,6 +56,7 @@ import resources.objects.cell.CellObject; import resources.objects.creature.CreatureObject; import resources.objects.player.PlayerMessageBuilder; import resources.objects.player.PlayerObject; +import resources.objects.waypoint.WaypointObject; import services.sui.SUIService.ListBoxType; import services.sui.SUIWindow; import services.sui.SUIWindow.Trigger; @@ -177,6 +179,64 @@ public class PlayerService implements INetworkDispatch { }); + swgOpcodes.put(Opcodes.SetWaypointColor, new INetworkRemoteEvent() { + + @Override + public void handlePacket(IoSession session, IoBuffer data) throws Exception { + data.order(ByteOrder.LITTLE_ENDIAN); + + Client client = core.getClient((Integer) session.getAttribute("connectionId")); + + if (client == null) + return; + + SWGObject player = client.getParent(); + + if (player == null) + return; + + PlayerObject ghost = (PlayerObject) player.getSlottedObject("ghost"); + + if (ghost == null) + return; + + SetWaypointColor packet = new SetWaypointColor(); + packet.deserialize(data); + + WaypointObject packetWay = (WaypointObject) core.objectService.getObject(packet.getObjectId()); + WaypointObject obj = (WaypointObject) ghost.getWaypointFromList(packetWay); + + if (obj == null || packetWay != obj) + return; + + String color = packet.getColor(); + switch(color) { + case "purple": + obj.setColor(WaypointObject.PURPLE); + break; + case "green": + obj.setColor(WaypointObject.GREEN); + break; + case "blue": + obj.setColor(WaypointObject.BLUE); + break; + case "yellow": + obj.setColor(WaypointObject.YELLOW); + break; + case "white": + obj.setColor(WaypointObject.WHITE); + break; + case "orange": + obj.setColor(WaypointObject.ORANGE); + break; + } + + ghost.waypointUpdate(obj); + + } + + }); + swgOpcodes.put(Opcodes.CmdSceneReady, new INetworkRemoteEvent() { @Override diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index b671f380..12dda5e1 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -149,6 +149,11 @@ public class SimulationService implements INetworkDispatch { core.commandService.registerCommand("requestwaypointatposition"); core.commandService.registerCommand("meditate"); core.commandService.registerGmCommand("server"); + core.commandService.registerCommand("toggleawayfromkeyboard"); + core.commandService.registerCommand("lfg"); + core.commandService.registerCommand("newbiehelper"); + core.commandService.registerCommand("roleplay"); + core.commandService.registerAlias("afk", "toggleawayfromkeyboard"); } diff --git a/src/services/travel/TravelPoint.java b/src/services/travel/TravelPoint.java index b1d0596c..2d76137c 100644 --- a/src/services/travel/TravelPoint.java +++ b/src/services/travel/TravelPoint.java @@ -106,6 +106,7 @@ public class TravelPoint { if (shuttleObj == null) { Console.println("NULL SHUTTLE SET FOR: " + getName()); } + //System.out.println("Shuttle obj " + shuttleObj.getTemplate() + " set for travelpoint " + getName()); startShuttleSchedule(); } diff --git a/src/services/travel/TravelService.java b/src/services/travel/TravelService.java index b62dd29e..606becba 100644 --- a/src/services/travel/TravelService.java +++ b/src/services/travel/TravelService.java @@ -107,7 +107,6 @@ public class TravelService implements INetworkDispatch { for(TravelPoint tp : travelMap.get(planet)) { if(tp.isStarport() || tp.getPlanetName().equalsIgnoreCase(object.getPlanet().getName())) { correctTravelPoints.add(tp); - //Console.println(tp.getName()); } } PlanetTravelPointListResponse response = new PlanetTravelPointListResponse(planetString, correctTravelPoints); @@ -132,14 +131,14 @@ public class TravelService implements INetworkDispatch { } - public TravelPoint getNearestTravelPoint(SWGObject obj) { + public TravelPoint getNearestTravelPoint(SWGObject obj, int distance) { TravelPoint returnedPoint = null; Vector planetTp = travelMap.get(obj.getPlanet()); synchronized(travelMap) { for (TravelPoint tp : planetTp) { //System.out.println("Distance for point " + tp.getName() + " is " + tp.getLocation().getDistance2D(obj.getWorldPosition())); - if (tp.getLocation().getDistance2D(obj.getWorldPosition()) <= 125) { + if (tp.getLocation().getDistance2D(obj.getWorldPosition()) <= distance) { if (returnedPoint != null) { float returnPointDistance = returnedPoint.getLocation().getDistance2D(obj.getWorldPosition()); float tpDistance = tp.getLocation().getDistance2D(obj.getWorldPosition()); @@ -155,16 +154,19 @@ public class TravelService implements INetworkDispatch { } } } - // Some transport obj's were used as deco (ex: ACLO bunker on Talus shared_player_transport). A null check should be performed before tp is used. /*if (returnedPoint == null) { - System.out.println("Could not find travel point for " + obj.getTemplate() + " at " + obj.getPlanet().name + " Position: " + obj.getPosition().x + " " + obj.getPosition().z); + //System.out.println("Could not find travel point for " + obj.getTemplate() + " at " + obj.getPlanet().name + " Position: " + obj.getPosition().x + " " + obj.getPosition().z); //Console.println("Travel Point NULL: " + returnedPoint.getName()); }*/ - + return returnedPoint; } + public TravelPoint getNearestTravelPoint(SWGObject obj) { + return getNearestTravelPoint(obj, 125); + } + public TravelPoint getTravelPointByName(String planet, String tpName) { Planet planetObj = core.terrainService.getPlanetByName(planet.toLowerCase()); @@ -195,19 +197,21 @@ public class TravelService implements INetworkDispatch { TravelPoint travelPoint = new TravelPoint(name, x, y, z, 150); travelPoint.setPlanetName(WordUtils.capitalize(planet.getName())); - if (travelMap.containsKey(planet)) { - - travelMap.get(planet).add(travelPoint); - System.out.println("Added travel point " + travelPoint.getName()); - - } else { - Vector travelPointVector = new Vector(); - travelMap.put(planet, travelPointVector); - travelMap.get(planet).add(travelPoint); - System.out.println("Added planet " + planet.getName() + " to TravelMap."); - System.out.println("Added travel point " + travelPoint.getName()); - } + synchronized(travelMap) { + if (travelMap.containsKey(planet)) { + + travelMap.get(planet).add(travelPoint); + System.out.println("Added travel point " + travelPoint.getName()); + + } else { + Vector travelPointVector = new Vector(); + travelMap.put(planet, travelPointVector); + travelMap.get(planet).add(travelPoint); + System.out.println("Added planet " + planet.getName() + " to TravelMap."); + System.out.println("Added travel point " + travelPoint.getName()); + } + } } public void removeTravelPointByName(Planet planet, String name){ From 71d48111e0869658460fe5f1625c8f5c675340a6 Mon Sep 17 00:00:00 2001 From: Waverunner Date: Sun, 15 Dec 2013 15:19:56 -0500 Subject: [PATCH 10/10] LinkDead status will now show on logged out characters, added factionrank flag bitmask --- scripts/commands/toggledisplayingfactionrank.py | 10 ++++++++++ src/services/SimulationService.java | 3 +++ src/services/object/ObjectService.java | 2 +- 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 scripts/commands/toggledisplayingfactionrank.py diff --git a/scripts/commands/toggledisplayingfactionrank.py b/scripts/commands/toggledisplayingfactionrank.py new file mode 100644 index 00000000..bf4ae34f --- /dev/null +++ b/scripts/commands/toggledisplayingfactionrank.py @@ -0,0 +1,10 @@ +from resources.common import PlayerFlags +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + ghost = actor.getSlottedObject('ghost') + ghost.toggleFlag(PlayerFlags.FACTIONRANK) + return \ No newline at end of file diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 3abd55b8..2ffe4e83 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -154,6 +154,7 @@ public class SimulationService implements INetworkDispatch { core.commandService.registerCommand("newbiehelper"); core.commandService.registerCommand("roleplay"); core.commandService.registerAlias("afk", "toggleawayfromkeyboard"); + core.commandService.registerCommand("toggledisplayingfactionrank"); } @@ -569,6 +570,8 @@ public class SimulationService implements INetworkDispatch { session.suspendWrite(); + ghost.toggleFlag(PlayerFlags.LD); + object.createTransaction(core.getCreatureODB().getEnvironment()); core.getCreatureODB().put(object, Long.class, CreatureObject.class, object.getTransaction()); object.getTransaction().commitSync(); diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 5ffdd889..dafed099 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -607,7 +607,7 @@ public class ObjectService implements INetworkDispatch { client.getSession().write(friendsListMessage.serialize()); if (ghost != null) { - + ghost.clearFlagBitmask(PlayerFlags.LD); String objectShortName = creature.getCustomName().toLowerCase(); if (creature.getCustomName().contains(" ")) {