diff --git a/ngengine_public.jar b/ngengine_public.jar index 8bba1a3f..47c74e59 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/scripts/commands/equip.py b/scripts/commands/equip.py index 514fbb92..461ac779 100644 --- a/scripts/commands/equip.py +++ b/scripts/commands/equip.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/getattributesbatch.py b/scripts/commands/getattributesbatch.py new file mode 100644 index 00000000..e4c2ba12 --- /dev/null +++ b/scripts/commands/getattributesbatch.py @@ -0,0 +1,24 @@ +import sys + +def setup(): + return + +def run(core, actor, target, commandString): + + parsedMsg = commandString.split(' ') + for i in parsedMsg: + if len(i) == 0 or i == '-255': + continue + object = core.objectService.getObject(long(i)) + if object: + core.attributeService.handleGetAttributes(object, actor) + + return + +def isLong(a): + try: + long(a) + return True + except: + return False + \ No newline at end of file diff --git a/scripts/commands/giveitem.py b/scripts/commands/giveitem.py index 5065d818..d0e7995b 100644 --- a/scripts/commands/giveitem.py +++ b/scripts/commands/giveitem.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/kneel.py b/scripts/commands/kneel.py index 50a1d471..b02ab55b 100644 --- a/scripts/commands/kneel.py +++ b/scripts/commands/kneel.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/object.py b/scripts/commands/object.py index f41424ea..c5e11a58 100644 --- a/scripts/commands/object.py +++ b/scripts/commands/object.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/opencontainer.py b/scripts/commands/opencontainer.py index 52d33449..1f3575f6 100644 --- a/scripts/commands/opencontainer.py +++ b/scripts/commands/opencontainer.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/prone.py b/scripts/commands/prone.py index e84832f5..e8bc20f0 100644 --- a/scripts/commands/prone.py +++ b/scripts/commands/prone.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/serverdestroyobject.py b/scripts/commands/serverdestroyobject.py index 6c55f9b1..ee1725b7 100644 --- a/scripts/commands/serverdestroyobject.py +++ b/scripts/commands/serverdestroyobject.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/sitserver.py b/scripts/commands/sitserver.py index 5fbfce54..73b7c77a 100644 --- a/scripts/commands/sitserver.py +++ b/scripts/commands/sitserver.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore from protocol.swg.objectControllerObjects import SitOnObject from protocol.swg import ObjControllerMessage diff --git a/scripts/commands/socialinternal.py b/scripts/commands/socialinternal.py index 24657d1b..a91ea386 100644 --- a/scripts/commands/socialinternal.py +++ b/scripts/commands/socialinternal.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/spatialchatinternal.py b/scripts/commands/spatialchatinternal.py index 1cb74f83..451f6318 100644 --- a/scripts/commands/spatialchatinternal.py +++ b/scripts/commands/spatialchatinternal.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/stand.py b/scripts/commands/stand.py index 3ef5a78c..6add2453 100644 --- a/scripts/commands/stand.py +++ b/scripts/commands/stand.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/transferitem.py b/scripts/commands/transferitem.py index 8b548eba..56b3d848 100644 --- a/scripts/commands/transferitem.py +++ b/scripts/commands/transferitem.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/transferitemarmor.py b/scripts/commands/transferitemarmor.py index d3ea91cd..931dc47d 100644 --- a/scripts/commands/transferitemarmor.py +++ b/scripts/commands/transferitemarmor.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/transferitemmisc.py b/scripts/commands/transferitemmisc.py index eda077fa..d1dedf7b 100644 --- a/scripts/commands/transferitemmisc.py +++ b/scripts/commands/transferitemmisc.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/commands/transferitemweapon.py b/scripts/commands/transferitemweapon.py index b0b4027d..bd1efcd3 100644 --- a/scripts/commands/transferitemweapon.py +++ b/scripts/commands/transferitemweapon.py @@ -1,6 +1,4 @@ import sys -from resources.objects import SWGObject -from main import NGECore def setup(): return diff --git a/scripts/demo.py b/scripts/demo.py index d51148fd..9fe03c33 100644 --- a/scripts/demo.py +++ b/scripts/demo.py @@ -1,11 +1,10 @@ import sys -from resources.objects import SWGObject -from main import NGECore 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/src/main/NGECore.java b/src/main/NGECore.java index 4730e624..02e3b539 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -30,6 +30,7 @@ import java.util.concurrent.ConcurrentHashMap; import resources.objects.creature.CreatureObject; +import services.AttributeService; import services.CharacterService; import services.ConnectionService; import services.LoginService; @@ -91,7 +92,8 @@ public class NGECore { public SimulationService simulationService; public ScriptService scriptService; public ChatService chatService; - + public AttributeService attributeService; + // Login Server public NetworkDispatch loginDispatch; @@ -138,6 +140,7 @@ public class NGECore { scriptService = new ScriptService(this); commandService = new CommandService(this); chatService = new ChatService(this); + attributeService = new AttributeService(this); // Ping Server try { diff --git a/src/protocol/swg/AttributeListMessage.java b/src/protocol/swg/AttributeListMessage.java new file mode 100644 index 00000000..d6ebedd9 --- /dev/null +++ b/src/protocol/swg/AttributeListMessage.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * 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.nio.ByteOrder; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.mina.core.buffer.IoBuffer; +import org.apache.mina.core.buffer.SimpleBufferAllocator; + +public class AttributeListMessage extends SWGMessage { + + private Map attributes; + private long objectId; + private SimpleBufferAllocator bufferPool; + + public AttributeListMessage(Map attributes, long objectId, SimpleBufferAllocator bufferPool) { + this.attributes = attributes; + this.objectId = objectId; + this.bufferPool = bufferPool; + } + + @Override + public void deserialize(IoBuffer data) { + + } + + @Override + public IoBuffer serialize() { + IoBuffer result = bufferPool.allocate(100, false).order(ByteOrder.LITTLE_ENDIAN); + result.setAutoExpand(true); + + result.putShort((short) 5); + result.putInt(0xF3F12F2A); + + result.putLong(objectId); + result.putShort((short) 0); + + result.putInt(attributes.size()); + + for(Entry e : attributes.entrySet()) { + result.put(getAsciiString(e.getKey())); + result.put(getUnicodeString(e.getValue())); + } + result.putInt(0); + int size = result.position(); + result = bufferPool.allocate(size, false).put(result.array(), 0, size); + + return result.flip(); + + } + +} diff --git a/src/resources/objects/ObjectMessageBuilder.java b/src/resources/objects/ObjectMessageBuilder.java new file mode 100644 index 00000000..ffc12f18 --- /dev/null +++ b/src/resources/objects/ObjectMessageBuilder.java @@ -0,0 +1,140 @@ +/******************************************************************************* + * 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 resources.objects; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.apache.mina.core.buffer.CachedBufferAllocator; +import org.apache.mina.core.buffer.IoBuffer; +import org.apache.mina.core.buffer.SimpleBufferAllocator; + +import engine.resources.common.Utilities; +import engine.resources.objects.SWGObject; + +import protocol.swg.SceneEndBaselines; + +public abstract class ObjectMessageBuilder { + + public SWGObject object; + public SimpleBufferAllocator bufferPool = new SimpleBufferAllocator(); + + public IoBuffer createBaseline(String objectType, byte viewType, IoBuffer data, int size) { + + IoBuffer buf = bufferPool.allocate(23 + size, false).order(ByteOrder.LITTLE_ENDIAN); + buf.putShort((short) 5); + buf.putInt(0x68A75F0C); + buf.putLong(object.getObjectID()); + try { + buf.put(reverse(objectType).getBytes("US-ASCII")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + buf.put(viewType); + buf.putInt(size); // size + buf.put(data); + buf.flip(); + return buf; + } + + public IoBuffer createDelta(String objectType, byte viewType, short updateCount, short updateType, IoBuffer data, int size) { + + IoBuffer buf = bufferPool.allocate(27 + size, false).order(ByteOrder.LITTLE_ENDIAN); + buf.putShort((short) 5); + buf.putInt(0x12862153); + buf.putLong(object.getObjectID()); + try { + buf.put(reverse(objectType).getBytes("US-ASCII")); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + buf.put(viewType); + buf.putInt(size); // size + buf.putShort(updateCount); + buf.putShort(updateType); + buf.put(data); + + buf.flip(); + return buf; + + + } + + public SWGObject getObject() { return object; } + public void setObject(SWGObject object) { this.object = object; } + + public abstract void sendBaselines(); + + private String reverse(String reverseString) { + + if (reverseString.length() <= 1) return reverseString; + return reverse(reverseString.substring(1, reverseString.length())) + reverseString.charAt(0); + + } + + protected String getAsciiString(ByteBuffer buffer) { return getString(buffer, "US-ASCII"); } + protected String getUnicodeString(ByteBuffer buffer) { return getString(buffer, "UTF-16LE"); } + protected byte[] getAsciiString(String string) { return getString(string, "US-ASCII"); } + protected byte[] getUnicodeString(String string) { return getString(string, "UTF-16LE"); } + + private String getString(ByteBuffer buffer, String charFormat) { + String result; + int length; + if (charFormat == "UTF-16LE") + length = buffer.order(ByteOrder.LITTLE_ENDIAN).getInt(); + else + length = buffer.order(ByteOrder.LITTLE_ENDIAN).getShort(); + + int bufferPosition = buffer.position(); + try { + result = new String(buffer.array(), bufferPosition, length, charFormat); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return ""; + } + buffer.position(bufferPosition + length); + + return result; + } + private byte[] getString(String string, String charFormat) { + ByteBuffer result; + int length = 2 + string.length(); + if (charFormat == "UTF-16LE") { + result = ByteBuffer.allocate(length * 2).order(ByteOrder.LITTLE_ENDIAN); + result.putInt(string.length()); + } + else { + result = ByteBuffer.allocate(length).order(ByteOrder.LITTLE_ENDIAN); + result.putShort((short)string.length()); + } + try { + result.put(string.getBytes(charFormat)); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + return new byte[] { }; + } + return result.array(); + } + + +} diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index 08fb99f7..0fa477a8 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -26,7 +26,7 @@ import java.nio.ByteOrder; import org.apache.mina.core.buffer.IoBuffer; import engine.resources.common.CRC; -import engine.resources.objects.ObjectMessageBuilder; +import resources.objects.ObjectMessageBuilder; import engine.resources.objects.SWGObject; import engine.resources.objects.SkillMod; @@ -75,6 +75,8 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { CreatureObject creature = (CreatureObject) object; IoBuffer buffer = bufferPool.allocate(300, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.setAutoExpand(true); + buffer.putShort((short) 19); // Object Count buffer.putFloat(1); buffer.put(getAsciiString(creature.getStfFilename())); @@ -121,6 +123,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); // battle fatigue buffer.putLong(creature.getStateBitmask()); int size = buffer.position(); + buffer = bufferPool.allocate(size, false).put(buffer.array(), 0, size); buffer.flip(); buffer = createBaseline("CREO", (byte) 3, buffer, size); diff --git a/src/resources/objects/player/PlayerMessageBuilder.java b/src/resources/objects/player/PlayerMessageBuilder.java index ac288553..6d3fbf72 100644 --- a/src/resources/objects/player/PlayerMessageBuilder.java +++ b/src/resources/objects/player/PlayerMessageBuilder.java @@ -26,7 +26,7 @@ import java.util.Map.Entry; import org.apache.mina.core.buffer.IoBuffer; -import engine.resources.objects.ObjectMessageBuilder; +import resources.objects.ObjectMessageBuilder; import resources.objects.waypoint.WaypointObject; diff --git a/src/resources/objects/tangible/TangibleMessageBuilder.java b/src/resources/objects/tangible/TangibleMessageBuilder.java index 1c1fee9c..09bb2270 100644 --- a/src/resources/objects/tangible/TangibleMessageBuilder.java +++ b/src/resources/objects/tangible/TangibleMessageBuilder.java @@ -25,7 +25,7 @@ import java.nio.ByteOrder; import org.apache.mina.core.buffer.IoBuffer; -import engine.resources.objects.ObjectMessageBuilder; +import resources.objects.ObjectMessageBuilder; public class TangibleMessageBuilder extends ObjectMessageBuilder { diff --git a/src/resources/objects/weapon/WeaponMessageBuilder.java b/src/resources/objects/weapon/WeaponMessageBuilder.java index f59e3d43..fc1de3cb 100644 --- a/src/resources/objects/weapon/WeaponMessageBuilder.java +++ b/src/resources/objects/weapon/WeaponMessageBuilder.java @@ -25,7 +25,7 @@ import java.nio.ByteOrder; import org.apache.mina.core.buffer.IoBuffer; -import engine.resources.objects.ObjectMessageBuilder; +import resources.objects.ObjectMessageBuilder; public class WeaponMessageBuilder extends ObjectMessageBuilder { diff --git a/src/services/AttributeService.java b/src/services/AttributeService.java index 83c6eeba..74cadf7f 100644 --- a/src/services/AttributeService.java +++ b/src/services/AttributeService.java @@ -21,6 +21,51 @@ ******************************************************************************/ package services; -public class AttributeService { +import java.util.HashMap; +import java.util.Map; + +import org.apache.mina.core.buffer.SimpleBufferAllocator; + +import main.NGECore; + +import protocol.swg.AttributeListMessage; + +import engine.resources.objects.SWGObject; +import engine.resources.service.INetworkDispatch; +import engine.resources.service.INetworkRemoteEvent; + +public class AttributeService implements INetworkDispatch { + + private NGECore core; + public SimpleBufferAllocator bufferPool = new SimpleBufferAllocator(); + + public AttributeService(NGECore core) { + this.core = core; + } + + @Override + public void insertOpcodes(Map arg0, + Map arg1) { + // TODO Auto-generated method stub + + } + + @Override + public void shutdown() { + // TODO Auto-generated method stub + + } + + public void handleGetAttributes(SWGObject target, SWGObject requester) { + + if(target.getAttributes().size() == 0) + return; + + if(requester.getClient() == null || requester.getClient().getSession() == null) + return; + + AttributeListMessage message = new AttributeListMessage(new HashMap(target.getAttributes()), target.getObjectID(), bufferPool); + requester.getClient().getSession().write(message.serialize()); + } } diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 0c298bd6..7a88f237 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -114,7 +114,8 @@ public class SimulationService implements INetworkDispatch { core.commandService.registerCommand("serverdestroyobject"); core.commandService.registerCommand("giveitem"); core.commandService.registerCommand("object"); - + core.commandService.registerCommand("getattributesbatch"); + } public void add(SWGObject object, int x, int y) {