diff --git a/scripts/object/building/tatooine/cantina_tatooine.py b/scripts/object/building/tatooine/cantina_tatooine.py index ccad8904..c1f6984a 100644 --- a/scripts/object/building/tatooine/cantina_tatooine.py +++ b/scripts/object/building/tatooine/cantina_tatooine.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Cantina', object.getPosition().x, object.getPosition().z, 3, 0, 0) + return + \ No newline at end of file diff --git a/scripts/object/building/tatooine/cloning_facility_tatooine.py b/scripts/object/building/tatooine/cloning_facility_tatooine.py index ccad8904..10c20b1b 100644 --- a/scripts/object/building/tatooine/cloning_facility_tatooine.py +++ b/scripts/object/building/tatooine/cloning_facility_tatooine.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Cloning Facility', object.getPosition().x, object.getPosition().z, 5, 0, 0) + return + \ No newline at end of file diff --git a/scripts/object/building/tatooine/hospital_tatooine.py b/scripts/object/building/tatooine/hospital_tatooine.py index ccad8904..e9fa1054 100644 --- a/scripts/object/building/tatooine/hospital_tatooine.py +++ b/scripts/object/building/tatooine/hospital_tatooine.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Medical Center', object.getPosition().x, object.getPosition().z, 13, 0, 0) + return + \ No newline at end of file diff --git a/scripts/object/building/tatooine/hospital_tatooine_s02.py b/scripts/object/building/tatooine/hospital_tatooine_s02.py index ccad8904..669ecae4 100644 --- a/scripts/object/building/tatooine/hospital_tatooine_s02.py +++ b/scripts/object/building/tatooine/hospital_tatooine_s02.py @@ -1,4 +1,6 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Medical Center', object.getPosition().x, object.getPosition().z, 13, 0, 0) + return diff --git a/scripts/object/building/tatooine/parking_garage_tatooine_style_1.py b/scripts/object/building/tatooine/parking_garage_tatooine_style_1.py index ccad8904..4e9adfbe 100644 --- a/scripts/object/building/tatooine/parking_garage_tatooine_style_1.py +++ b/scripts/object/building/tatooine/parking_garage_tatooine_style_1.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Parking Garage', object.getPosition().x, object.getPosition().z, 6, 0, 0) + return + \ No newline at end of file diff --git a/scripts/object/building/tatooine/shuttleport_tatooine.py b/scripts/object/building/tatooine/shuttleport_tatooine.py index ccad8904..c5cf71c2 100644 --- a/scripts/object/building/tatooine/shuttleport_tatooine.py +++ b/scripts/object/building/tatooine/shuttleport_tatooine.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Shuttleport', object.getPosition().x, object.getPosition().z, 14, 0, 0) + return + \ No newline at end of file diff --git a/scripts/object/building/tatooine/starport_tatooine.py b/scripts/object/building/tatooine/starport_tatooine.py index ccad8904..6235a453 100644 --- a/scripts/object/building/tatooine/starport_tatooine.py +++ b/scripts/object/building/tatooine/starport_tatooine.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + 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/tangible/terminal/terminal_bank.py b/scripts/object/tangible/terminal/terminal_bank.py index 4f4e89ae..4f068472 100644 --- a/scripts/object/tangible/terminal/terminal_bank.py +++ b/scripts/object/tangible/terminal/terminal_bank.py @@ -2,5 +2,6 @@ import sys def setup(core, object): object.setAttachment('radial_filename', 'bank') + core.mapService.addLocation(object.getPlanet(), 'Bank Terminal', object.getPosition().x, object.getPosition().z, 41, 42, 0) return \ No newline at end of file diff --git a/scripts/object/tangible/terminal/terminal_bazaar.py b/scripts/object/tangible/terminal/terminal_bazaar.py index ccad8904..e94866f0 100644 --- a/scripts/object/tangible/terminal/terminal_bazaar.py +++ b/scripts/object/tangible/terminal/terminal_bazaar.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Bazaar Terminal', object.getPosition().x, object.getPosition().z, 41, 43, 0) + return + \ No newline at end of file diff --git a/scripts/object/tangible/terminal/terminal_mission.py b/scripts/object/tangible/terminal/terminal_mission.py index ccad8904..4884aa67 100644 --- a/scripts/object/tangible/terminal/terminal_mission.py +++ b/scripts/object/tangible/terminal/terminal_mission.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Mission Terminal', object.getPosition().x, object.getPosition().z, 41, 44, 0) + return + \ No newline at end of file diff --git a/scripts/object/tangible/terminal/terminal_mission_artisan.py b/scripts/object/tangible/terminal/terminal_mission_artisan.py index ccad8904..911010d8 100644 --- a/scripts/object/tangible/terminal/terminal_mission_artisan.py +++ b/scripts/object/tangible/terminal/terminal_mission_artisan.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Artisan Mission Terminal', object.getPosition().x, object.getPosition().z, 41, 21, 0) + return + \ No newline at end of file diff --git a/scripts/object/tangible/terminal/terminal_mission_entertainer.py b/scripts/object/tangible/terminal/terminal_mission_entertainer.py index ccad8904..433b5f91 100644 --- a/scripts/object/tangible/terminal/terminal_mission_entertainer.py +++ b/scripts/object/tangible/terminal/terminal_mission_entertainer.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Entertainer Mission Terminal', object.getPosition().x, object.getPosition().z, 41, 24, 0) + return + \ No newline at end of file diff --git a/scripts/object/tangible/terminal/terminal_mission_imperial.py b/scripts/object/tangible/terminal/terminal_mission_imperial.py index ccad8904..8e4773b5 100644 --- a/scripts/object/tangible/terminal/terminal_mission_imperial.py +++ b/scripts/object/tangible/terminal/terminal_mission_imperial.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Imperial Mission Terminal', object.getPosition().x, object.getPosition().z, 41, 46, 0) + return + \ No newline at end of file diff --git a/scripts/object/tangible/terminal/terminal_mission_rebel.py b/scripts/object/tangible/terminal/terminal_mission_rebel.py index ccad8904..0bb50bbe 100644 --- a/scripts/object/tangible/terminal/terminal_mission_rebel.py +++ b/scripts/object/tangible/terminal/terminal_mission_rebel.py @@ -1,4 +1,7 @@ import sys def setup(core, object): - return \ No newline at end of file + + core.mapService.addLocation(object.getPlanet(), 'Rebel Mission Terminal', object.getPosition().x, object.getPosition().z, 41, 45, 0) + return + \ No newline at end of file diff --git a/scripts/radial/bank.py b/scripts/radial/bank.py index 96f528e1..db6a08a1 100644 --- a/scripts/radial/bank.py +++ b/scripts/radial/bank.py @@ -20,12 +20,12 @@ def createRadial(core, owner, target, radials): return def handleSelection(core, owner, target, option): - + if option == RadialOptions.bankitems: bank = owner.getSlottedObject('bank') if bank: core.simulationService.openContainer(owner, bank) - if option == RadialOptions.bankTransfer: + if option == RadialOptions.bankTransfer or option == 21: suiSvc = core.suiService suiWindow = suiSvc.createSUIWindow('Script.transfer', owner, target, 10) suiWindow.setProperty('transaction.txtInputFrom:Text', 'From') diff --git a/src/main/NGECore.java b/src/main/NGECore.java index 0a395ead..1cfb4f58 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -34,12 +34,12 @@ import services.AttributeService; import services.CharacterService; import services.ConnectionService; import services.LoginService; -import services.MapService; import services.ScriptService; import services.SimulationService; import services.TerrainService; import services.chat.ChatService; import services.command.CommandService; +import services.map.MapService; import services.object.ObjectService; import services.object.UpdateService; import services.sui.SUIService; @@ -134,11 +134,11 @@ public class NGECore { loginService = new LoginService(this); connectionService = new ConnectionService(this); characterService = new CharacterService(this); - + mapService = new MapService(this); + objectService = new ObjectService(this); terrainService = new TerrainService(this); updateService = new UpdateService(this); - mapService = new MapService(this); scriptService = new ScriptService(this); commandService = new CommandService(this); chatService = new ChatService(this); @@ -165,6 +165,7 @@ public class NGECore { zoneDispatch.addService(commandService); zoneDispatch.addService(chatService); zoneDispatch.addService(suiService); + zoneDispatch.addService(mapService); zoneServer = new MINAServer(zoneDispatch, config.getInt("ZONE.PORT")); zoneServer.start(); diff --git a/src/protocol/swg/GetMapLocationsMessage.java b/src/protocol/swg/GetMapLocationsMessage.java index 710094a2..095a88b0 100644 --- a/src/protocol/swg/GetMapLocationsMessage.java +++ b/src/protocol/swg/GetMapLocationsMessage.java @@ -21,6 +21,9 @@ ******************************************************************************/ package protocol.swg; +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; + import org.apache.mina.core.buffer.IoBuffer; @@ -37,7 +40,16 @@ public class GetMapLocationsMessage extends SWGMessage{ } public void deserialize(IoBuffer buffer) { - planet = getAsciiString(buffer); + buffer.getShort(); + buffer.getInt(); + short size = buffer.getShort(); + try { + planet = new String(ByteBuffer.allocate(size).put(buffer.array(), buffer.position(), size).array(), "US-ASCII"); + buffer.position(buffer.position() + size); + } + catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } x = buffer.getFloat(); y = buffer.getFloat(); category = buffer.get(); diff --git a/src/protocol/swg/GetMapLocationsResponseMessage.java b/src/protocol/swg/GetMapLocationsResponseMessage.java index a9142880..7366a034 100644 --- a/src/protocol/swg/GetMapLocationsResponseMessage.java +++ b/src/protocol/swg/GetMapLocationsResponseMessage.java @@ -23,38 +23,23 @@ package protocol.swg; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.util.Vector; import org.apache.mina.core.buffer.IoBuffer; +import services.map.MapLocation; + public class GetMapLocationsResponseMessage extends SWGMessage { - public GetMapLocationsResponseMessage(String planet, String name) { - ByteBuffer result = ByteBuffer.allocate(496).order(ByteOrder.LITTLE_ENDIAN); - - result.putShort((short) 8); - result.putInt(0x9F80464C); - result.put(getAsciiString(planet)); - - // List - for (int i = 0; i < 3; i++) { - // blank list 1 + 2, no idea why they are needed - result.putInt(23 + name.length() * 2); + private String planet; + private Vector locations; - result.putLong(100); // ID - result.put(getUnicodeString(name)); - result.putFloat(0); // x - result.putFloat(0); // y - result.put((byte) 2); // category - result.put((byte) 0); // sub category - result.put((byte) 0); // is active - } + public GetMapLocationsResponseMessage(String planet, Vector locations) { - result.putInt(0); - result.putInt(0); // 3 unks - result.putInt(0); + this.planet = planet; + this.locations = locations; - data = result.array(); } public void deserialize(IoBuffer data) { @@ -62,6 +47,41 @@ public class GetMapLocationsResponseMessage extends SWGMessage { } public IoBuffer serialize() { - return IoBuffer.wrap(data); + + IoBuffer result = IoBuffer.allocate(100).order(ByteOrder.LITTLE_ENDIAN); + result.setAutoExpand(true); + + result.putShort((short) 8); + result.putInt(0x9F80464C); + result.put(getAsciiString(planet)); + + result.putInt(locations.size()); + + for(MapLocation location : locations) { + + result.putLong(location.getLocationId()); + result.put(getUnicodeString(location.getName())); + result.putFloat(location.getX()); + result.putFloat(location.getY()); + result.put(location.getCategory()); + result.put(location.getSubcategory()); + result.put(location.getActive()); + + } + + // blank list 1 + 2, no idea why they are needed + result.putInt(0); + + result.putInt(0); + + result.putInt(0x480); + result.putInt(0x48D); // 3 unks + result.putInt(1); + + int size = result.position(); + result = IoBuffer.allocate(size).put(result.array(), 0, size); + + return result.flip(); + } } diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index bcddfa46..27438623 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -94,13 +94,13 @@ public class SimulationService implements INetworkDispatch { } List objectList = core.objectService.getObjectList(); - - for(SWGObject obj : objectList) { - if(obj.getParentId() == 0) { - add(obj, obj.getPosition().x, obj.getPosition().z); + synchronized(objectList) { + for(SWGObject obj : objectList) { + if(obj.getParentId() == 0) { + add(obj, obj.getPosition().x, obj.getPosition().z); + } } } - core.commandService.registerCommand("opencontainer"); core.commandService.registerCommand("transferitem"); core.commandService.registerCommand("transferitemarmor"); diff --git a/src/services/TerrainService.java b/src/services/TerrainService.java index 69009fa3..a7a28a48 100644 --- a/src/services/TerrainService.java +++ b/src/services/TerrainService.java @@ -89,7 +89,7 @@ public class TerrainService { public Planet getPlanetByName(String name) { for (int i = 0; i < planets.size(); i++) { - if (planets.get(i).getName() == name) { + if (planets.get(i).getName().equals(name)) { return planets.get(i); } } @@ -99,7 +99,7 @@ public class TerrainService { public Planet getPlanetByPath(String path) { for (int i = 0; i < planets.size(); i++) { - if (planets.get(i).getPath() == path) { + if (planets.get(i).getPath().equals(path)) { return planets.get(i); } } @@ -110,6 +110,7 @@ public class TerrainService { public void addPlanet(int ID, String name, String path, boolean loadSnapshot) { Planet planet = new Planet(ID, name, path, loadSnapshot); planets.add(planet); + core.mapService.addPlanet(planet); } diff --git a/src/services/map/MapLocation.java b/src/services/map/MapLocation.java new file mode 100644 index 00000000..c1574cb1 --- /dev/null +++ b/src/services/map/MapLocation.java @@ -0,0 +1,115 @@ +/******************************************************************************* + * 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 services.map; + +import engine.resources.scene.Planet; + +public class MapLocation { + + private long locationId; + private String name; + private float x, y; + private byte category, subcategory, active; + private Planet planet; + + public MapLocation() { + + } + + public MapLocation(Planet planet, long locationId, String name, float x, float y, byte category, byte subcategory, byte active) { + + this.setLocationId(locationId); + this.setName(name); + this.setX(x); + this.setY(y); + this.setCategory(category); + this.setSubcategory(subcategory); + this.setActive(active); + + } + + public long getLocationId() { + return locationId; + } + + public void setLocationId(long locationId) { + this.locationId = locationId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public float getX() { + return x; + } + + public void setX(float x) { + this.x = x; + } + + public float getY() { + return y; + } + + public void setY(float y) { + this.y = y; + } + + public byte getCategory() { + return category; + } + + public void setCategory(byte category) { + this.category = category; + } + + public byte getSubcategory() { + return subcategory; + } + + public void setSubcategory(byte subcategory) { + this.subcategory = subcategory; + } + + public byte getActive() { + return active; + } + + public void setActive(byte active) { + this.active = active; + } + + public Planet getPlanet() { + return planet; + } + + public void setPlanet(Planet planet) { + this.planet = planet; + } + + +} diff --git a/src/services/MapService.java b/src/services/map/MapService.java similarity index 50% rename from src/services/MapService.java rename to src/services/map/MapService.java index cb1ae4e5..a3002dac 100644 --- a/src/services/MapService.java +++ b/src/services/map/MapService.java @@ -19,14 +19,25 @@ * 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 services; +package services.map; +import java.nio.ByteOrder; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.atomic.AtomicLong; +import org.apache.mina.core.session.IoSession; +import org.apache.mina.core.buffer.IoBuffer; + +import protocol.swg.GetMapLocationsMessage; +import protocol.swg.GetMapLocationsResponseMessage; +import resources.common.Opcodes; + +import engine.clients.Client; import engine.resources.objects.SWGObject; import engine.resources.scene.Grid2D; import engine.resources.scene.Planet; @@ -41,7 +52,8 @@ import main.NGECore; public class MapService implements INetworkDispatch { private NGECore core; - + private Map> locationMap = new ConcurrentHashMap>(); + private AtomicLong nextId = new AtomicLong(0); public MapService(NGECore core) { this.core = core; @@ -49,10 +61,54 @@ public class MapService implements INetworkDispatch { public void insertOpcodes(Map swgOpcodes, Map objControllerOpcodes) { + swgOpcodes.put(Opcodes.GetMapLocationsMessage, new INetworkRemoteEvent() { + + @Override + public void handlePacket(IoSession session, IoBuffer data) throws Exception { + + data.order(ByteOrder.LITTLE_ENDIAN); + data.position(0); + + GetMapLocationsMessage getMapLocations = new GetMapLocationsMessage(); + getMapLocations.deserialize(data); + + /*Planet planet = core.terrainService.getPlanetByName(getMapLocations.getPlanet()); + + if(planet == null) + return;*/ + + Client client = core.getClient((Integer) session.getAttribute("connectionId")); + + if(client == null || client.getSession() == null) + return; + + SWGObject object = client.getParent(); + + if(object == null) + return; + + + GetMapLocationsResponseMessage response = new GetMapLocationsResponseMessage(getMapLocations.getPlanet(), locationMap.get(object.getPlanet())); + session.write(response.serialize()); + + } + + }); + } public void shutdown() { } - + + public void addPlanet(Planet planet) { + locationMap.put(planet, new Vector()); + } + + public void addLocation(Planet planet, String name, float x, float y, byte category, byte subcategory, byte active) { + + MapLocation location = new MapLocation(planet, nextId.incrementAndGet(), name, x, y, category, subcategory, active); + locationMap.get(planet).add(location); + } + } diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index e14c7255..fb810551 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -166,6 +166,7 @@ public class ObjectService implements INetworkDispatch { return null; } + object.setPlanetId(planet.getID()); String serverTemplate = Template.replace(".iff", ""); // check if template is empty(4 default lines) to reduce RAM usage(saves about 500 MB of RAM) @@ -189,7 +190,6 @@ public class ObjectService implements INetworkDispatch { //core.scriptService.callScript("scripts/" + serverTemplate.split("shared_" , 2)[0].replace("shared_", ""), "setup", serverTemplate.split("shared_" , 2)[1], core, object); - object.setPlanetId(planet.getID()); objectList.add(object); return object; @@ -396,8 +396,8 @@ public class ObjectService implements INetworkDispatch { CmdStartScene startScene = new CmdStartScene((byte) 0, objectId, creature.getPlanet().getPath(), creature.getTemplate(), position.x, 0, position.z, System.currentTimeMillis() / 1000, creature.getRadians()); session.write(startScene.serialize()); - creature.makeAware(creature); core.simulationService.handleZoneIn(client); + creature.makeAware(creature); }