diff --git a/nge.backup b/nge.backup index 164ef16a..1a761380 100644 Binary files a/nge.backup and b/nge.backup differ 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/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/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/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 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/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/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/CharacterService.java b/src/services/CharacterService.java index 2d52802d..fa0c8463 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/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/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); 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..2ffe4e83 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -149,6 +149,12 @@ 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"); + core.commandService.registerCommand("toggledisplayingfactionrank"); } @@ -536,9 +542,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 +568,13 @@ 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"); + ghost.toggleFlag(PlayerFlags.LD); - //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) { 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) { diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 1e0ca7c8..dafed099 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 { @@ -600,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(" ")) { 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){