diff --git a/.gitignore b/.gitignore index 7bc91e4b..a1292091 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ pt_sword_glint *.0 cachedir/ appearance/ +clientdata/ *.class # SWG Client Folders diff --git a/ngengine_public.jar b/ngengine_public.jar index 1ef9aa2a..3842feae 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/scripts/demo.py b/scripts/demo.py index 9fe03c33..0176ca1e 100644 --- a/scripts/demo.py +++ b/scripts/demo.py @@ -5,6 +5,7 @@ def CreateStartingCharacter(core, object): testObject = core.objectService.createObject('object/weapon/ranged/rifle/shared_rifle_t21.iff', object.getPlanet()) testObject.setCustomName('This is a Jython Rifle') testObject.setStringAttribute('crafter', 'Light') + inventory = object.getSlottedObject('inventory') inventory.add(testObject) diff --git a/scripts/static_map_locations.py b/scripts/static_map_locations.py new file mode 100644 index 00000000..36a776d7 --- /dev/null +++ b/scripts/static_map_locations.py @@ -0,0 +1,21 @@ +import sys + +def addLocations(core, planet): + + if planet.getName() == 'tatooine': + tatooineLocations(core, planet) + +def tatooineLocations(core, planet): + + mapService = core.mapService + + # Cities + + mapService.addLocation(planet, 'Bestine', -1290, -3590, 17, 0, 0) + mapService.addLocation(planet, 'Mos Espa', -2902, 2130, 17, 0, 0) + mapService.addLocation(planet, 'Mos Entha', 1291, 3138, 17, 0, 0) + mapService.addLocation(planet, 'Wayfar', -5124, -6530, 17, 0, 0) + mapService.addLocation(planet, 'Mos Eisley', 3528, -4804, 17, 0, 0) + mapService.addLocation(planet, 'Anchorhead', 40, -5348, 17, 0, 0) + + \ No newline at end of file diff --git a/src/protocol/swg/AttributeListMessage.java b/src/protocol/swg/AttributeListMessage.java index d6ebedd9..eb3f4f57 100644 --- a/src/protocol/swg/AttributeListMessage.java +++ b/src/protocol/swg/AttributeListMessage.java @@ -28,18 +28,19 @@ import java.util.Map.Entry; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.buffer.SimpleBufferAllocator; +import engine.resources.objects.SWGObject; + public class AttributeListMessage extends SWGMessage { - private Map attributes; - private long objectId; private SimpleBufferAllocator bufferPool; + private SWGObject target; - public AttributeListMessage(Map attributes, long objectId, SimpleBufferAllocator bufferPool) { - this.attributes = attributes; - this.objectId = objectId; + public AttributeListMessage(SWGObject target, SimpleBufferAllocator bufferPool) { + this.target = target; this.bufferPool = bufferPool; } + @Override public void deserialize(IoBuffer data) { @@ -53,14 +54,16 @@ public class AttributeListMessage extends SWGMessage { result.putShort((short) 5); result.putInt(0xF3F12F2A); - result.putLong(objectId); + result.putLong(target.getObjectID()); result.putShort((short) 0); - result.putInt(attributes.size()); - - for(Entry e : attributes.entrySet()) { - result.put(getAsciiString(e.getKey())); - result.put(getUnicodeString(e.getValue())); + synchronized(target.getMutex()) { + result.putInt(target.getAttributes().size()); + + for(Entry e : target.getAttributes().entrySet()) { + result.put(getAsciiString(e.getKey())); + result.put(getUnicodeString(e.getValue())); + } } result.putInt(0); int size = result.position(); diff --git a/src/protocol/swg/CmdSceneReady.java b/src/protocol/swg/CmdSceneReady.java index f8763cfa..348ff92d 100644 --- a/src/protocol/swg/CmdSceneReady.java +++ b/src/protocol/swg/CmdSceneReady.java @@ -21,6 +21,8 @@ ******************************************************************************/ package protocol.swg; +import java.nio.ByteOrder; + import org.apache.mina.core.buffer.IoBuffer; @@ -35,6 +37,6 @@ public class CmdSceneReady extends SWGMessage { } public IoBuffer serialize() { - return IoBuffer.wrap(data); + return IoBuffer.allocate(6).order(ByteOrder.LITTLE_ENDIAN).put(data).flip(); } } diff --git a/src/protocol/swg/UnkByteFlag.java b/src/protocol/swg/UnkByteFlag.java index 2dc0da15..55710bf9 100644 --- a/src/protocol/swg/UnkByteFlag.java +++ b/src/protocol/swg/UnkByteFlag.java @@ -37,7 +37,7 @@ public class UnkByteFlag extends SWGMessage { @Override public IoBuffer serialize() { IoBuffer result = IoBuffer.allocate(7).order(ByteOrder.LITTLE_ENDIAN); - + System.out.println("test"); result.putShort((short) 2); result.putInt(0x7102B15F); result.put((byte) 1); diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index 7f8daad4..cc39f1b3 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -115,11 +115,8 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.put((byte) 1); buffer.putLong(creature.getOwnerId()); - float height = creature.getHeight(); - if (height < 0.7 || height > 1.5) { - height = 1; - } - buffer.putFloat(height); + + buffer.putFloat(creature.getHeight()); buffer.putInt(0); // battle fatigue buffer.putLong(creature.getStateBitmask()); int size = buffer.position(); @@ -439,6 +436,54 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { } + public IoBuffer buildFactionDelta(String faction) { + + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(CRC.StringtoCRC(faction)); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 3, (short) 1, (short) 0x04, buffer, size + 4); + + return buffer; + + } + + public IoBuffer buildFactionStatusDelta(int factionStatus) { + + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(factionStatus); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 3, (short) 1, (short) 0x05, buffer, size + 4); + + return buffer; + + } + + public IoBuffer buildOptionMaskDelta(int optionMask) { + + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(optionMask); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 3, (short) 1, (short) 0x08, buffer, size + 4); + + return buffer; + + } + + public IoBuffer buildHeightDelta(float height) { + + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putFloat(height); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 3, (short) 1, (short) 0x10, buffer, size + 4); + + return buffer; + + } + public IoBuffer buildStateDelta(long state) { IoBuffer buffer = bufferPool.allocate(8, false).order(ByteOrder.LITTLE_ENDIAN); @@ -475,6 +520,68 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { } + public IoBuffer buildCombatFlagDelta(byte combatFlag) { + + IoBuffer buffer = bufferPool.allocate(1, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.put(combatFlag); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 6, (short) 1, (short) 0x02, buffer, size + 4); + + return buffer; + + } + + public IoBuffer buildLevelDelta(short level) { + + IoBuffer buffer = bufferPool.allocate(2, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putShort(level); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 6, (short) 1, (short) 0x08, buffer, size + 4); + + return buffer; + + } + + public IoBuffer buildWeaponIdDelta(long weaponId) { + + IoBuffer buffer = bufferPool.allocate(8, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putLong(weaponId); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 6, (short) 1, (short) 0x0C, buffer, size + 4); + + return buffer; + + } + + public IoBuffer buildGroupIdDelta(long groupId) { + + IoBuffer buffer = bufferPool.allocate(8, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putLong(groupId); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 6, (short) 1, (short) 0x0D, buffer, size + 4); + + return buffer; + + } + + public IoBuffer buildGroupInviteDelta(long inviteSenderId, String inviteSenderName, long inviteCounter) { + + IoBuffer buffer = bufferPool.allocate(18 + inviteSenderName.length(), false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putLong(inviteSenderId); + buffer.put(getAsciiString(inviteSenderName)); + buffer.putLong(inviteCounter); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 6, (short) 1, (short) 0x0E, buffer, size + 4); + + return buffer; + + } + public IoBuffer buildTargetDelta(long targetId) { IoBuffer buffer = bufferPool.allocate(8, false).order(ByteOrder.LITTLE_ENDIAN); diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 2b33fe5b..479d2e76 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -217,6 +217,11 @@ public class CreatureObject extends SWGObject implements IPersistent { synchronized(objectMutex) { this.optionBitmask = optionBitmask; } + + IoBuffer optionDelta = messageBuilder.buildOptionMaskDelta(optionBitmask); + + notifyObservers(optionDelta, true); + } public int getIncapTimer() { @@ -259,6 +264,11 @@ public class CreatureObject extends SWGObject implements IPersistent { synchronized(objectMutex) { this.faction = faction; } + + IoBuffer factionDelta = messageBuilder.buildFactionDelta(faction); + + notifyObservers(factionDelta, true); + } public int getFactionStatus() { @@ -271,6 +281,11 @@ public class CreatureObject extends SWGObject implements IPersistent { synchronized(objectMutex) { this.factionStatus = factionStatus; } + + IoBuffer factionStatusDelta = messageBuilder.buildFactionStatusDelta(factionStatus); + + notifyObservers(factionStatusDelta, true); + } public float getHeight() { @@ -283,6 +298,11 @@ public class CreatureObject extends SWGObject implements IPersistent { synchronized(objectMutex) { this.height = height; } + + IoBuffer heightDelta = messageBuilder.buildHeightDelta(height); + + notifyObservers(heightDelta, true); + } public int getBattleFatigue() { @@ -529,6 +549,11 @@ public class CreatureObject extends SWGObject implements IPersistent { synchronized(objectMutex) { this.level = level; } + + IoBuffer levelDelta = messageBuilder.buildLevelDelta(level); + + notifyObservers(levelDelta, true); + } public String getCurrentAnimation() { @@ -565,6 +590,11 @@ public class CreatureObject extends SWGObject implements IPersistent { synchronized(objectMutex) { this.weaponId = weaponId; } + + IoBuffer weaponIdDelta = messageBuilder.buildWeaponIdDelta(weaponId); + + notifyObservers(weaponIdDelta, true); + } public long getGroupId() { @@ -577,6 +607,11 @@ public class CreatureObject extends SWGObject implements IPersistent { synchronized(objectMutex) { this.groupId = groupId; } + + IoBuffer groupIdDelta = messageBuilder.buildGroupIdDelta(groupId); + + notifyObservers(groupIdDelta, true); + } public long getInviteSenderId() { @@ -732,10 +767,10 @@ public class CreatureObject extends SWGObject implements IPersistent { destination.getSession().write(messageBuilder.buildBaseline1()); destination.getSession().write(messageBuilder.buildBaseline4()); } - //destination.getSession().write(messageBuilder.buildBaseline8()); - //destination.getSession().write(messageBuilder.buildBaseline9()); + destination.getSession().write(messageBuilder.buildBaseline8()); + destination.getSession().write(messageBuilder.buildBaseline9()); - UpdatePostureMessage upm = new UpdatePostureMessage(getObjectID(), getPosture()); + UpdatePostureMessage upm = new UpdatePostureMessage(getObjectID(), (byte) 0); destination.getSession().write(upm.serialize()); if(destination != getClient()) { UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID(), 55); diff --git a/src/services/AttributeService.java b/src/services/AttributeService.java index 74cadf7f..54904917 100644 --- a/src/services/AttributeService.java +++ b/src/services/AttributeService.java @@ -23,6 +23,7 @@ package services; import java.util.HashMap; import java.util.Map; +import java.util.TreeMap; import org.apache.mina.core.buffer.SimpleBufferAllocator; @@ -64,7 +65,7 @@ public class AttributeService implements INetworkDispatch { if(requester.getClient() == null || requester.getClient().getSession() == null) return; - AttributeListMessage message = new AttributeListMessage(new HashMap(target.getAttributes()), target.getObjectID(), bufferPool); + AttributeListMessage message = new AttributeListMessage(target, bufferPool); requester.getClient().getSession().write(message.serialize()); } diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 27438623..13b96a25 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -429,10 +429,6 @@ public class SimulationService implements INetworkDispatch { Quaternion orientation = object.getOrientation(); Point3D position = object.getPosition(); - if(object.getParentId() != 0) { - SWGObject parent = core.objectService.getObject(object.getParentId()); - parent._add(object); - } Point3D pos = object.getWorldPosition(); @@ -447,11 +443,7 @@ public class SimulationService implements INetworkDispatch { if(object.getParentId() == 0) add(object, pos.x, pos.z); - - //teleport(object, position, orientation); - - //core.chatService.loadMailHeaders(client); // moved to beginning of zone-in like live - + } public void openContainer(SWGObject requester, SWGObject container) { @@ -468,19 +460,14 @@ public class SimulationService implements INetworkDispatch { if(position.x >= -8192 && position.x <= 8192 && position.z >= -8192 && position.z <= 8192) { - if(obj.getParentId() == 0) { - DataTransform dataTransform = new DataTransform(new Point3D(position.x, 0, position.z), orientation, obj.getMovementCounter(), obj.getObjectID()); - ObjControllerMessage objController = new ObjControllerMessage(0x1B, dataTransform); - obj.notifyObservers(objController, true); - } else { - DataTransformWithParent dataTransform = new DataTransformWithParent(new Point3D(position.x, 0, position.z), orientation, obj.getMovementCounter(), obj.getObjectID(), obj.getParentId()); - ObjControllerMessage objController = new ObjControllerMessage(0x1B, dataTransform); - obj.notifyObservers(objController, true); - } + DataTransform dataTransform = new DataTransform(new Point3D(position.x, position.y, position.z), orientation, obj.getMovementCounter(), obj.getObjectID()); + ObjControllerMessage objController = new ObjControllerMessage(0x1B, dataTransform); + obj.notifyObservers(objController, true); } - + } + // not fully working yet(rotation of meshes wrong) public boolean checkLineOfSight(SWGObject obj1, SWGObject obj2) { diff --git a/src/services/map/MapService.java b/src/services/map/MapService.java index a3002dac..029a4f31 100644 --- a/src/services/map/MapService.java +++ b/src/services/map/MapService.java @@ -103,6 +103,8 @@ public class MapService implements INetworkDispatch { public void addPlanet(Planet planet) { locationMap.put(planet, new Vector()); + + core.scriptService.callScript("scripts/", "addLocations", "static_map_locations", core, planet); } public void addLocation(Planet planet, String name, float x, float y, byte category, byte subcategory, byte active) { diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index fb810551..5d225367 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -50,6 +50,7 @@ import org.python.core.PyObject; import com.sleepycat.persist.EntityCursor; +import protocol.swg.CmdSceneReady; import protocol.swg.CmdStartScene; import protocol.swg.CreateCharacterFailed; import protocol.swg.HeartBeatMessage; @@ -196,11 +197,11 @@ public class ObjectService implements INetworkDispatch { } public SWGObject createObject(String Template, Planet planet) { - return createObject(Template, 0, planet, new Point3D(0, 0, 0), new Quaternion(0, 0, 0, 0)); + return createObject(Template, 0, planet, new Point3D(0, 0, 0), new Quaternion(1, 0, 0, 0)); } public SWGObject createObject(String Template, Planet planet, float x, float z, float y) { - return createObject(Template, 0, planet, new Point3D(x, y, z), new Quaternion(0, 0, 0, 0)); + return createObject(Template, 0, planet, new Point3D(x, y, z), new Quaternion(1, 0, 0, 0)); } public void addObjectToScene(SWGObject object) { @@ -354,7 +355,6 @@ public class ObjectService implements INetworkDispatch { } creature.setClient(client); - Point3D position = creature.getPosition(); Planet planet = core.terrainService.getPlanetByID(creature.getPlanetId()); creature.setPlanet(planet); client.setParent(creature); @@ -380,25 +380,34 @@ public class ObjectService implements INetworkDispatch { } }); + if(creature.getParentId() != 0) { + SWGObject parent = getObject(creature.getParentId()); + parent._add(creature); + } + + Point3D position = creature.getWorldPosition(); + + //UnkByteFlag unkByteFlag = new UnkByteFlag(); + //session.write(unkByteFlag.serialize()); - HeartBeatMessage heartBeat = new HeartBeatMessage(); - session.write(heartBeat.serialize()); - - UnkByteFlag unkByteFlag = new UnkByteFlag(); - session.write(unkByteFlag.serialize()); - - ParametersMessage parameters = new ParametersMessage(); - session.write(parameters.serialize()); + //ParametersMessage parameters = new ParametersMessage(); + //session.write(parameters.serialize()); core.chatService.loadMailHeaders(client); - CmdStartScene startScene = new CmdStartScene((byte) 0, objectId, creature.getPlanet().getPath(), creature.getTemplate(), position.x, 0, position.z, System.currentTimeMillis() / 1000, creature.getRadians()); + HeartBeatMessage heartBeat = new HeartBeatMessage(); + session.write(heartBeat.serialize()); + + CmdStartScene startScene = new CmdStartScene((byte) 0, objectId, creature.getPlanet().getPath(), creature.getTemplate(), position.x, position.y, position.z, System.currentTimeMillis() / 1000, creature.getRadians()); session.write(startScene.serialize()); core.simulationService.handleZoneIn(client); creature.makeAware(creature); + //CmdSceneReady cmdSceneReady = new CmdSceneReady(); + //session.write(cmdSceneReady.serialize()); + //core.simulationService.teleport(creature, new Point3D(position.x, core.terrainService.getHeight(creature.getPlanetId(), position.x, position.z), position.z), creature.getOrientation()); } }); diff --git a/src/services/sui/SUIService.java b/src/services/sui/SUIService.java index 2bfa9da4..14a7407a 100644 --- a/src/services/sui/SUIService.java +++ b/src/services/sui/SUIService.java @@ -267,23 +267,23 @@ public class SUIService implements INetworkDispatch { switch(type) { - case MessageBoxType.MESSAGE_BOX_OK: - window.setProperty("btnOk:visible", "True"); - window.setProperty("btnOk:Text", "@ok"); - window.setProperty("btnCancel:visible", "False"); - break; - case MessageBoxType.MESSAGE_BOX_OK_CANCEL: - window.setProperty("btnOk:visible", "True"); - window.setProperty("btnCancel:visible", "True"); - window.setProperty("btnOk:Text", "@ok"); - window.setProperty("btnCancel:Text", "@cancel"); - break; - case MessageBoxType.MESSAGE_BOX_YES_NO: - window.setProperty("btnOk:visible", "True"); - window.setProperty("btnCancel:visible", "True"); - window.setProperty("btnOk:Text", "@yes"); - window.setProperty("btnCancel:Text", "@no"); - break; + case MessageBoxType.MESSAGE_BOX_OK: + window.setProperty("btnOk:visible", "True"); + window.setProperty("btnOk:Text", "@ok"); + window.setProperty("btnCancel:visible", "False"); + break; + case MessageBoxType.MESSAGE_BOX_OK_CANCEL: + window.setProperty("btnOk:visible", "True"); + window.setProperty("btnCancel:visible", "True"); + window.setProperty("btnOk:Text", "@ok"); + window.setProperty("btnCancel:Text", "@cancel"); + break; + case MessageBoxType.MESSAGE_BOX_YES_NO: + window.setProperty("btnOk:visible", "True"); + window.setProperty("btnCancel:visible", "True"); + window.setProperty("btnOk:Text", "@yes"); + window.setProperty("btnCancel:Text", "@no"); + break; }