diff --git a/ngengine_public.jar b/ngengine_public.jar index e6a8d961..7c2fd4e0 100644 Binary files a/ngengine_public.jar and b/ngengine_public.jar differ diff --git a/scripts/buffs/me_buff_strength_3.py b/scripts/buffs/me_buff_strength_3.py new file mode 100644 index 00000000..e09c02e5 --- /dev/null +++ b/scripts/buffs/me_buff_strength_3.py @@ -0,0 +1,8 @@ +import sys + +def setup(core, actor, buff): + return + +def removeBuff(core, actor, buff): + return + \ No newline at end of file diff --git a/scripts/demo.py b/scripts/demo.py index 011c9670..adb7e3df 100644 --- a/scripts/demo.py +++ b/scripts/demo.py @@ -31,6 +31,8 @@ def CreateStartingCharacter(core, object): object.addSkillMod('combat_block_value' , 0) inventory = object.getSlottedObject('inventory') + if not inventory: + return inventory.add(testObject) testClothing = core.objectService.createObject('object/tangible/wearables/cape/shared_cape_rebel_01.iff', object.getPlanet()) diff --git a/src/main/NGECore.java b/src/main/NGECore.java index b0376f0e..c2cc998d 100644 --- a/src/main/NGECore.java +++ b/src/main/NGECore.java @@ -33,6 +33,7 @@ import java.util.concurrent.ConcurrentHashMap; import resources.common.RadialOptions; import resources.objects.creature.CreatureObject; import services.AttributeService; +import services.BuffService; import services.CharacterService; import services.ConnectionService; import services.LoginService; @@ -108,6 +109,7 @@ public class NGECore { public TradeService tradeService; public CombatService combatService; public PlayerService playerService; + public BuffService buffService; // Login Server public NetworkDispatch loginDispatch; @@ -156,6 +158,7 @@ public class NGECore { suiService = new SUIService(this); combatService = new CombatService(this); playerService = new PlayerService(this); + buffService = new BuffService(this); // Ping Server try { PingServer pingServer = new PingServer(config.getInt("PING.PORT")); @@ -180,6 +183,7 @@ public class NGECore { zoneDispatch.addService(chatService); zoneDispatch.addService(suiService); zoneDispatch.addService(mapService); + zoneDispatch.addService(playerService); zoneServer = new MINAServer(zoneDispatch, config.getInt("ZONE.PORT")); zoneServer.start(); diff --git a/src/protocol/swg/ChatPersistentMessageToClient.java b/src/protocol/swg/ChatPersistentMessageToClient.java index 249d30e6..3db681b6 100644 --- a/src/protocol/swg/ChatPersistentMessageToClient.java +++ b/src/protocol/swg/ChatPersistentMessageToClient.java @@ -23,10 +23,7 @@ package protocol.swg; import java.nio.ByteOrder; import java.util.List; -import java.util.Vector; - import org.apache.mina.core.buffer.IoBuffer; - import services.chat.WaypointAttachment; diff --git a/src/protocol/swg/ChatPersistentMessageToServer.java b/src/protocol/swg/ChatPersistentMessageToServer.java index 42d1dfd2..23be8a29 100644 --- a/src/protocol/swg/ChatPersistentMessageToServer.java +++ b/src/protocol/swg/ChatPersistentMessageToServer.java @@ -25,14 +25,9 @@ import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; -import java.util.Vector; - import org.apache.mina.core.buffer.IoBuffer; - import services.chat.WaypointAttachment; -import com.sleepycat.persist.model.Persistent; - public class ChatPersistentMessageToServer extends SWGMessage { diff --git a/src/protocol/swg/ClientCreateCharacter.java b/src/protocol/swg/ClientCreateCharacter.java index 3acde5b6..c11204f4 100644 --- a/src/protocol/swg/ClientCreateCharacter.java +++ b/src/protocol/swg/ClientCreateCharacter.java @@ -79,7 +79,6 @@ public class ClientCreateCharacter extends SWGMessage { hairObject = new String(ByteBuffer.allocate(size).put(buffer.array(), buffer.position(), size).array(), "US-ASCII"); buffer.position(buffer.position() + size); length = buffer.getShort(); - System.out.println("Position: " + buffer.position()); hairCustomization = new byte[length]; buffer.get(hairCustomization); size = buffer.getShort(); diff --git a/src/protocol/swg/CmdStartScene.java b/src/protocol/swg/CmdStartScene.java index 0e8ec8b5..52d1eb36 100644 --- a/src/protocol/swg/CmdStartScene.java +++ b/src/protocol/swg/CmdStartScene.java @@ -71,7 +71,7 @@ public class CmdStartScene extends SWGMessage { result.put(getAsciiString(sharedRaceTemplate)); result.putLong(time); - result.put(new byte[] { (byte)0x8B, (byte)0xC0, (byte)0xEA, (byte)0x4E }); + result.put(new byte[] { (byte)0x8E, (byte)0xB5, (byte)0xEA, (byte)0x4E }); return result.flip(); } diff --git a/src/protocol/swg/SceneCreateObjectByCrc.java b/src/protocol/swg/SceneCreateObjectByCrc.java index 5b3921a0..f5429415 100644 --- a/src/protocol/swg/SceneCreateObjectByCrc.java +++ b/src/protocol/swg/SceneCreateObjectByCrc.java @@ -74,7 +74,6 @@ public class SceneCreateObjectByCrc extends SWGMessage { result.putFloat(pZ); result.putInt(crc); result.put(flags); - result.flip(); - return result; + return result.flip(); } } diff --git a/src/protocol/swg/SceneDestroyObject.java b/src/protocol/swg/SceneDestroyObject.java index 75edc1d5..f0716d84 100644 --- a/src/protocol/swg/SceneDestroyObject.java +++ b/src/protocol/swg/SceneDestroyObject.java @@ -39,12 +39,12 @@ public class SceneDestroyObject extends SWGMessage { } public IoBuffer serialize() { - IoBuffer result = IoBuffer.allocate(15).order(ByteOrder.LITTLE_ENDIAN); + IoBuffer result = IoBuffer.allocate(14).order(ByteOrder.LITTLE_ENDIAN); result.putShort((short)3); result.putInt(0x4D45D504); result.putLong(objectId); - return result; + return result.flip(); } } diff --git a/src/protocol/swg/UnkByteFlag.java b/src/protocol/swg/UnkByteFlag.java index 55710bf9..ddaa565f 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/protocol/swg/UpdateTransformMessage.java b/src/protocol/swg/UpdateTransformMessage.java index b5d1b0ee..8ed53713 100644 --- a/src/protocol/swg/UpdateTransformMessage.java +++ b/src/protocol/swg/UpdateTransformMessage.java @@ -36,7 +36,6 @@ public class UpdateTransformMessage extends SWGMessage { private int movementCounter; private byte direction; private float speed; - private byte combatFlag; public UpdateTransformMessage(long objectId, short x, short y, short z, int movementCounter, byte direction, float speed) { this.objectId = objectId; diff --git a/src/protocol/swg/UpdateTransformWithParentMessage.java b/src/protocol/swg/UpdateTransformWithParentMessage.java index 249e26a3..c490fa73 100644 --- a/src/protocol/swg/UpdateTransformWithParentMessage.java +++ b/src/protocol/swg/UpdateTransformWithParentMessage.java @@ -37,7 +37,6 @@ public class UpdateTransformWithParentMessage extends SWGMessage { private int movementCounter; private byte direction; private float speed; - private byte combatFlag; public UpdateTransformWithParentMessage(long objectId, long cellId, short x, short y, short z, int movementCounter, byte direction, float speed) { this.objectId = objectId; diff --git a/src/protocol/swg/objectControllerObjects/DataTransform.java b/src/protocol/swg/objectControllerObjects/DataTransform.java index a86fccc0..3b8381e5 100644 --- a/src/protocol/swg/objectControllerObjects/DataTransform.java +++ b/src/protocol/swg/objectControllerObjects/DataTransform.java @@ -118,7 +118,7 @@ public class DataTransform extends ObjControllerObject { result.putInt(0); result.putInt(0); - result.putInt(movementIndex+1); + result.putInt(movementIndex); result.putFloat(0); result.putFloat(yOrientation); //xRot @@ -131,7 +131,7 @@ public class DataTransform extends ObjControllerObject { result.putFloat(speed); //unk result.putFloat(0); //unk - result.put((byte)0x01); + result.put((byte)0x00); return result.flip(); } diff --git a/src/resources/common/FileUtilities.java b/src/resources/common/FileUtilities.java index 86904bc7..b9fa36d8 100644 --- a/src/resources/common/FileUtilities.java +++ b/src/resources/common/FileUtilities.java @@ -21,6 +21,7 @@ ******************************************************************************/ package resources.common; +import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.LineNumberReader; @@ -36,6 +37,13 @@ public class FileUtilities { lnr.close(); return numberOfLines; + } + + public static boolean doesFileExist(String filePath) { + + File file = new File(filePath); + + return file.exists(); } diff --git a/src/resources/objects/Buff.java b/src/resources/objects/Buff.java index 8b81ba9a..f66d61a3 100644 --- a/src/resources/objects/Buff.java +++ b/src/resources/objects/Buff.java @@ -34,12 +34,12 @@ import engine.clientdata.ClientFileManager; import engine.clientdata.visitors.DatatableVisitor; import engine.resources.common.CRC; -@Persistent +@Persistent(version=3) public class Buff implements IListObject { @NotPersistent private SimpleBufferAllocator bufferPool = new SimpleBufferAllocator(); - private int duration; + private float duration; private String buffName; private long ownerId; private String effect1Name, effect2Name, effect3Name, effect4Name, effect5Name; @@ -53,6 +53,8 @@ public class Buff implements IListObject { private boolean removeOnRespec; private boolean aiRemoveOnEndCombat; private boolean decayOnPvPDeath; + private long startTime; + private int totalPlayTime; public Buff(String buffName, long ownerId) { @@ -69,7 +71,7 @@ public class Buff implements IListObject { if(visitor.getObject(i, 0) != null) if(((String) visitor.getObject(i, 0)).equalsIgnoreCase(buffName)) { - duration = (Integer) visitor.getObject(i, 6); + duration = (Float) visitor.getObject(i, 6); effect1Name = (String) visitor.getObject(i, 7); effect1Value = (Float) visitor.getObject(i, 8); effect2Name = (String) visitor.getObject(i, 9); @@ -81,14 +83,14 @@ public class Buff implements IListObject { effect5Name = (String) visitor.getObject(i, 15); effect5Value = (Float) visitor.getObject(i, 16); particleEffect = (String) visitor.getObject(i, 19); - isDebuff = (Boolean) visitor.getObject(i, 21); - removeOnDeath = (Integer) visitor.getObject(i, 24) != 0; - isRemovableByPlayer = (Integer) visitor.getObject(i, 25) != 0; - maxStacks = (Integer) visitor.getObject(i, 27); - isPersistent = (Integer) visitor.getObject(i, 28) != 0; - removeOnRespec = (Integer) visitor.getObject(i, 30) != 0; - aiRemoveOnEndCombat = (Integer) visitor.getObject(i, 31) != 0; - decayOnPvPDeath = (Integer) visitor.getObject(i, 32) != 0; + isDebuff = (Boolean) visitor.getObject(i, 22); + removeOnDeath = (Integer) visitor.getObject(i, 25) != 0; + isRemovableByPlayer = (Integer) visitor.getObject(i, 26) != 0; + maxStacks = (Integer) visitor.getObject(i, 28); + isPersistent = (Integer) visitor.getObject(i, 29) != 0; + removeOnRespec = (Integer) visitor.getObject(i, 31) != 0; + aiRemoveOnEndCombat = (Integer) visitor.getObject(i, 32) != 0; + decayOnPvPDeath = (Integer) visitor.getObject(i, 33) != 0; } @@ -111,11 +113,15 @@ public class Buff implements IListObject { IoBuffer buffer = bufferPool.allocate(28, false).order(ByteOrder.LITTLE_ENDIAN); buffer.putInt(CRC.StringtoCRC(buffName)); - - buffer.putInt(duration); - buffer.putInt(0); - buffer.putInt(0); // remaining duration ??? - + if(duration > 0) { + buffer.putInt((int) (totalPlayTime + getRemainingDuration())); + buffer.putInt(0); + buffer.putInt((int) duration); + } else { + buffer.putInt(-1); + buffer.putInt(0); + buffer.putInt(-1); + } buffer.putLong(ownerId); buffer.putInt(1); // unk @@ -125,11 +131,11 @@ public class Buff implements IListObject { } - public int getDuration() { + public float getDuration() { return duration; } - public void setDuration(int duration) { + public void setDuration(float duration) { this.duration = duration; } @@ -301,4 +307,26 @@ public class Buff implements IListObject { this.decayOnPvPDeath = decayOnPvPDeath; } + public void setStartTime() { + this.startTime = System.currentTimeMillis(); + } + + public int getRemainingDuration() { + + long currentTime = System.currentTimeMillis(); + long timeDiff = (currentTime - startTime) / 1000; + int remaining = (int) (duration - timeDiff); + System.out.println("Buff remaining: " + remaining); + return remaining; + + } + + public int getTotalPlayTime() { + return totalPlayTime; + } + + public void setTotalPlayTime(int totalPlayTime) { + this.totalPlayTime = totalPlayTime; + } + } diff --git a/src/resources/objects/ListObject.java b/src/resources/objects/ListObject.java index 8a6eb47f..efea9b1e 100644 --- a/src/resources/objects/ListObject.java +++ b/src/resources/objects/ListObject.java @@ -25,7 +25,6 @@ import java.nio.ByteBuffer; import org.apache.mina.core.buffer.SimpleBufferAllocator; -import com.sleepycat.persist.model.Persistent; import resources.common.StringUtilities; diff --git a/src/resources/objects/SWGList.java b/src/resources/objects/SWGList.java index 38747749..57a09ae2 100644 --- a/src/resources/objects/SWGList.java +++ b/src/resources/objects/SWGList.java @@ -149,11 +149,8 @@ public class SWGList implements List { return list.get(index); } } - public List get() { - synchronized(objectMutex) { - return list; - } + return list; } @Override public int indexOf(Object o) { diff --git a/src/resources/objects/creature/CreatureMessageBuilder.java b/src/resources/objects/creature/CreatureMessageBuilder.java index bfc78a7b..d7608031 100644 --- a/src/resources/objects/creature/CreatureMessageBuilder.java +++ b/src/resources/objects/creature/CreatureMessageBuilder.java @@ -29,10 +29,12 @@ import org.apache.mina.core.buffer.IoBuffer; import com.sleepycat.persist.model.Persistent; import engine.resources.common.CRC; +import resources.objects.Buff; import resources.objects.ObjectMessageBuilder; import engine.resources.objects.SWGObject; import engine.resources.objects.SkillMod; +import resources.objects.player.PlayerObject; import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; @@ -79,7 +81,7 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { public IoBuffer buildBaseline3() { CreatureObject creature = (CreatureObject) object; - IoBuffer buffer = bufferPool.allocate(300, false).order(ByteOrder.LITTLE_ENDIAN); + IoBuffer buffer = bufferPool.allocate(100, false).order(ByteOrder.LITTLE_ENDIAN); buffer.setAutoExpand(true); buffer.putShort((short) 19); // Object Count @@ -120,8 +122,11 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.put((byte) 1); buffer.putLong(creature.getOwnerId()); - - buffer.putFloat(creature.getHeight()); + + float height = creature.getHeight(); + if (height < 0.7 || height > 1.5) + height = 1; + buffer.putFloat(height); buffer.putInt(0); // battle fatigue buffer.putLong(creature.getStateBitmask()); int size = buffer.position(); @@ -318,9 +323,47 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putShort((short) 0); buffer.put((byte) 1); - buffer.putInt(0); // Buff List todo later - buffer.putInt(0); - + if(creature.getBuffList().isEmpty()) { + buffer.putInt(0); + buffer.putInt(creature.getBuffListCounter()); + } else { + buffer.putInt(creature.getBuffList().size() + 1); + buffer.putInt(creature.getBuffListCounter()); + + buffer.put((byte) 0); + //buffer.putInt(0x2098793D); + buffer.putInt(0); + buffer.putInt(-1); + buffer.putInt(0); + buffer.putInt(0); + buffer.putLong(creature.getObjectID()); + + PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); + + for(Buff buff : creature.getBuffList().get()) { + + buff.setTotalPlayTime((int) (player.getTotalPlayTime() + (System.currentTimeMillis() - player.getLastPlayTimeUpdate()) / 1000)); + buffer.put((byte) 1); + buffer.putInt(0); + buffer.putInt(CRC.StringtoCRC(buff.getBuffName())); + if(buff.getDuration() > 0) { + buffer.putInt((int) (buff.getTotalPlayTime() + buff.getRemainingDuration())); + buffer.putInt(0); + buffer.putInt((int) buff.getDuration()); + } else { + buffer.putInt(-1); + buffer.putInt(0); + buffer.putInt(0); + } + + buffer.putLong(creature.getObjectID()); + + } + + buffer.putInt(1); + + } + buffer.putShort((short) 0); buffer.putInt(0xFFFFFFFF); buffer.put((byte) 1); @@ -356,19 +399,6 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); buffer.putInt(0); - //buffer.put((byte) 0); - - - - /*buffer.putShort((short) 1); - buffer.putInt(0); - buffer.putInt(0xFFFFFFFF); - buffer.putInt(1); - buffer.putInt(0); - buffer.putInt(0); - buffer.putInt(0); - buffer.putShort((short) 0); - buffer.put((byte)0);*/ int size = buffer.position(); buffer = bufferPool.allocate(size, false).put(buffer.array(), 0, size); @@ -671,6 +701,43 @@ public class CreatureMessageBuilder extends ObjectMessageBuilder { return buffer; } + + public IoBuffer buildAddBuffDelta(Buff buff) { + + CreatureObject creature = (CreatureObject) object; + PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); + + IoBuffer buffer = bufferPool.allocate(37, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(1); + buffer.putInt(creature.getBuffListCounter()); + buff.setTotalPlayTime((int) (player.getTotalPlayTime() + (System.currentTimeMillis() - player.getLastPlayTimeUpdate()) / 1000)); + buffer.put((byte) 0); + buffer.put(buff.getBytes()); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 6, (short) 1, (short) 0x1A, buffer, size + 4); + + return buffer; + + } + + public IoBuffer buildRemoveBuffDelta(Buff buff) { + + CreatureObject creature = (CreatureObject) object; + + IoBuffer buffer = bufferPool.allocate(37, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(1); + buffer.putInt(creature.getBuffListCounter()); + buffer.put((byte) 1); + buffer.put(buff.getBytes()); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("CREO", (byte) 6, (short) 1, (short) 0x1A, buffer, size + 4); + + return buffer; + + } + @Override diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java index 9194784d..52df5b26 100644 --- a/src/resources/objects/creature/CreatureObject.java +++ b/src/resources/objects/creature/CreatureObject.java @@ -761,11 +761,11 @@ public class CreatureObject extends TangibleObject 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(), (byte) 0); - destination.getSession().write(upm.serialize()); + //destination.getSession().write(upm.serialize()); if(destination != getClient()) { UpdatePVPStatusMessage upvpm = new UpdatePVPStatusMessage(getObjectID()); @@ -795,7 +795,7 @@ public class CreatureObject extends TangibleObject implements IPersistent { upvpm.setFaction(UpdatePVPStatusMessage.factionCRC.Neutral); upvpm.setStatus(16); } - destination.getSession().write(upvpm.serialize()); + //destination.getSession().write(upvpm.serialize()); } } @@ -895,5 +895,46 @@ public class CreatureObject extends TangibleObject implements IPersistent { this.maxHAMListCounter = maxHAMListCounter; } } + + public void addBuff(Buff buff) { + synchronized(objectMutex) { + buffList.get().add(buff); + setBuffListCounter(getBuffListCounter() + 1); + + } + buff.setStartTime(); + notifyObservers(messageBuilder.buildAddBuffDelta(buff), true); + } + + public void removeBuff(Buff buff) { + synchronized(objectMutex) { + buffList.get().remove(buff); + setBuffListCounter(getBuffListCounter() + 1); + } + notifyObservers(messageBuilder.buildRemoveBuffDelta(buff), true); + } + + public int getBuffListCounter() { + synchronized(objectMutex) { + return buffListUpdateCounter; + } + } + + public void setBuffListCounter(int buffListCounter) { + synchronized(objectMutex) { + this.buffListUpdateCounter = buffListCounter; + } + } + + public Buff getBuffByName(String buffName) { + synchronized(objectMutex) { + for(Buff buff : buffList.get()) { + if(buff.getBuffName().equals(buffName)) + return buff; + } + } + return null; + } + } diff --git a/src/resources/objects/player/PlayerMessageBuilder.java b/src/resources/objects/player/PlayerMessageBuilder.java index e97869bb..82761dcc 100644 --- a/src/resources/objects/player/PlayerMessageBuilder.java +++ b/src/resources/objects/player/PlayerMessageBuilder.java @@ -80,7 +80,7 @@ public class PlayerMessageBuilder extends ObjectMessageBuilder { buffer.putInt(0); // born date? - buffer.putInt(0); // total play time? + buffer.putInt(player.getTotalPlayTime()); // total play time? buffer.putInt(getProfData(player.getProfession())); // prof icon @@ -172,6 +172,7 @@ public class PlayerMessageBuilder extends ObjectMessageBuilder { int size = buffer.position(); + buffer = bufferPool.allocate(size, false).put(buffer.array(), 0, size); buffer.flip(); @@ -495,6 +496,18 @@ public class PlayerMessageBuilder extends ObjectMessageBuilder { } + public IoBuffer buildTotalPlayTimeDelta(int totalPlayTime) { + + IoBuffer buffer = bufferPool.allocate(4, false).order(ByteOrder.LITTLE_ENDIAN); + buffer.putInt(totalPlayTime); + int size = buffer.position(); + buffer.flip(); + buffer = createDelta("PLAY", (byte) 3, (short) 1, (short) 0x09, buffer, size + 4); + + return buffer; + + } + public int getProfData(String profession) { switch (profession) { diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java index 0736145a..00d644fb 100644 --- a/src/resources/objects/player/PlayerObject.java +++ b/src/resources/objects/player/PlayerObject.java @@ -112,6 +112,9 @@ public class PlayerObject extends SWGObject { @NotPersistent private PlayerMessageBuilder messageBuilder; + @NotPersistent + private long lastPlayTimeUpdate = System.currentTimeMillis(); + public PlayerObject() { @@ -120,7 +123,7 @@ public class PlayerObject extends SWGObject { } public PlayerObject(long objectID, Planet planet) { - super(objectID, planet, new Point3D(0, 0, 0), new Quaternion(1, 0, 1, 0), "object/player/shared_player.iff"); + super(objectID, planet, new Point3D(0, 0, 0), new Quaternion(1, 0, 0, 0), "object/player/shared_player.iff"); messageBuilder = new PlayerMessageBuilder(this); } @@ -180,6 +183,7 @@ public class PlayerObject extends SWGObject { synchronized(objectMutex) { this.totalPlayTime = totalPlayTime; } + getContainer().notifyObservers(messageBuilder.buildTotalPlayTimeDelta(totalPlayTime), true); } public String getHome() { @@ -489,14 +493,26 @@ public class PlayerObject extends SWGObject { if(destination == null || destination.getSession() == null) return; - if(destination.getParent().getObjectID() == getParentId()) { // only send to self + //if(destination.getParent().getObjectID() == getParentId()) { // only send to self destination.getSession().write(messageBuilder.buildBaseline3()); destination.getSession().write(messageBuilder.buildBaseline6()); destination.getSession().write(messageBuilder.buildBaseline8()); destination.getSession().write(messageBuilder.buildBaseline9()); - } + //} } + + public long getLastPlayTimeUpdate() { + synchronized(objectMutex) { + return lastPlayTimeUpdate; + } + } + + public void setLastPlayTimeUpdate(long lastPlayTimeUpdate) { + synchronized(objectMutex) { + this.lastPlayTimeUpdate = lastPlayTimeUpdate; + } + } } diff --git a/src/resources/objects/weapon/WeaponObject.java b/src/resources/objects/weapon/WeaponObject.java index bbbf6409..90319eac 100644 --- a/src/resources/objects/weapon/WeaponObject.java +++ b/src/resources/objects/weapon/WeaponObject.java @@ -181,6 +181,7 @@ public class WeaponObject extends SWGObject { @Override public void sendBaselines(Client destination) { + if(destination == null || destination.getSession() == null) return; diff --git a/src/services/AttributeService.java b/src/services/AttributeService.java index 60c4cffd..f5da7e71 100644 --- a/src/services/AttributeService.java +++ b/src/services/AttributeService.java @@ -47,9 +47,7 @@ public class AttributeService implements INetworkDispatch { } @Override - public void insertOpcodes(Map arg0, - Map arg1) { - // TODO Auto-generated method stub + public void insertOpcodes(Map arg0, Map arg1) { } diff --git a/src/services/BuffService.java b/src/services/BuffService.java new file mode 100644 index 00000000..aab4120d --- /dev/null +++ b/src/services/BuffService.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * 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; + +import java.util.Map; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + + +import resources.common.FileUtilities; +import resources.objects.Buff; +import resources.objects.creature.CreatureObject; +import resources.objects.player.PlayerObject; + +import main.NGECore; + +import engine.resources.service.INetworkDispatch; +import engine.resources.service.INetworkRemoteEvent; + +public class BuffService implements INetworkDispatch { + + private NGECore core; + private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); + + public BuffService(NGECore core) { + this.core = core; + } + + @Override + public void insertOpcodes(Map arg0, Map arg1) { + + } + + @Override + public void shutdown() { + + } + + public void addBuffToCreature(final CreatureObject creature, String buffName) { + + if(!FileUtilities.doesFileExist("scripts/buffs/" + buffName + ".py")) { + System.out.println("Buff script doesnt exist for: " + buffName); + return; + } + + final Buff buff = new Buff(buffName, creature.getObjectID()); + buff.setTotalPlayTime(((PlayerObject) creature.getSlottedObject("ghost")).getTotalPlayTime()); + if(creature.getBuffByName(buffName) != null) { + + Buff otherBuff = creature.getBuffByName(buffName); + if(otherBuff.getRemainingDuration() > buff.getDuration()) { + return; + } else { + removeBuffFromCreature(creature, otherBuff); + } + + } + + core.scriptService.callScript("scripts/buffs", "setup", buffName, core, creature, buff); + + creature.addBuff(buff); + scheduler.schedule(new Runnable() { + + @Override + public void run() { + + removeBuffFromCreature(creature, buff); + + } + + }, (long) buff.getDuration(), TimeUnit.SECONDS); + + } + + public void removeBuffFromCreature(CreatureObject creature, Buff buff) { + + if(!creature.getBuffList().contains(buff)) + return; + + core.scriptService.callScript("scripts/buffs", "removeBuff", buff.getBuffName(), core, creature, buff); + creature.removeBuff(buff); + + } + + public void clearBuffs(final CreatureObject creature) { + + // copy to array for thread safety + + for(final Buff buff : creature.getBuffList().get().toArray(new Buff[] { })) { + + if(buff.getRemainingDuration() > 0) { + scheduler.schedule(new Runnable() { + + @Override + public void run() { + + removeBuffFromCreature(creature, buff); + + } + + }, (long) buff.getRemainingDuration(), TimeUnit.SECONDS); + continue; + } else { + removeBuffFromCreature(creature, buff); + } + + } + + } + + + +} diff --git a/src/services/CharacterService.java b/src/services/CharacterService.java index 087573d4..5efad7b3 100644 --- a/src/services/CharacterService.java +++ b/src/services/CharacterService.java @@ -50,6 +50,7 @@ import protocol.swg.ClientRandomNameResponse; import protocol.swg.ClientVerifyAndLockNameRequest; import protocol.swg.ClientVerifyAndLockNameResponse; import protocol.swg.CreateCharacterSuccess; +import protocol.swg.HeartBeatMessage; import resources.objects.creature.CreatureObject; import resources.objects.player.PlayerObject; @@ -212,13 +213,15 @@ public class CharacterService implements INetworkDispatch { object.setCustomName(clientCreateCharacter.getName()); object.setHeight(clientCreateCharacter.getScale()); object.setPersistent(true); - object.setPosition(new Point3D(3608, 5, -4753)); + object.setPosition(new Point3D(-1294, 12, -3590)); + object.setCashCredits(100); + object.setBankCredits(1000); //object.setPosition(new Point3D(0, 0, 0)); - object.setOrientation(new Quaternion(1, 0, 1, 0)); + object.setOrientation(new Quaternion(1, 0, 0, 0)); object.createTransaction(core.getCreatureODB().getEnvironment()); PlayerObject player = (PlayerObject) core.objectService.createObject("object/player/shared_player.iff", object.getPlanet()); - object.add(player); + object._add(player); player.setProfession(clientCreateCharacter.getProfession()); player.setProfessionWheelPosition(clientCreateCharacter.getProfessionWheelPosition()); if(clientCreateCharacter.getHairObject().length() > 0) { @@ -226,7 +229,7 @@ public class CharacterService implements INetworkDispatch { TangibleObject hair = (TangibleObject) core.objectService.createObject(sharedHairTemplate, object.getPlanet()); if(clientCreateCharacter.getHairCustomization().length > 0) hair.setCustomization(clientCreateCharacter.getHairCustomization()); - object.add(hair); + object._add(hair); } TangibleObject inventory = (TangibleObject) core.objectService.createObject("object/tangible/inventory/shared_character_inventory.iff", object.getPlanet()); @@ -240,25 +243,25 @@ public class CharacterService implements INetworkDispatch { TangibleObject missionBag = (TangibleObject) core.objectService.createObject("object/tangible/mission_bag/shared_mission_bag.iff", object.getPlanet()); missionBag.setContainerPermissions(CreatureContainerPermissions.CREATURE_CONTAINER_PERMISSIONS); - object.add(inventory); - object.add(appInventory); - object.add(datapad); - object.add(bank); - object.add(missionBag); + object._add(inventory); + object._add(appInventory); + object._add(datapad); + object._add(bank); + object._add(missionBag); TangibleObject backpack = (TangibleObject) core.objectService.createObject("object/tangible/wearables/backpack/shared_backpack_galactic_marine.iff", object.getPlanet()); - inventory.add(backpack); - object.addObjectToEquipList(datapad); - object.addObjectToEquipList(inventory); + inventory._add(backpack); + //object.addObjectToEquipList(datapad); + //object.addObjectToEquipList(inventory); WeaponObject weapon = (WeaponObject) core.objectService.createObject("object/weapon/ranged/rifle/shared_rifle_a280.iff", object.getPlanet()); WeaponObject defaultWeapon = (WeaponObject) core.objectService.createObject("object/weapon/creature/shared_creature_default_weapon.iff", object.getPlanet()); - object.addObjectToEquipList(defaultWeapon); + //object.addObjectToEquipList(defaultWeapon); - object.add(defaultWeapon); + object._add(defaultWeapon); - object.addObjectToEquipList(weapon); + //object.addObjectToEquipList(weapon); - object.add(weapon); + object._add(weapon); object.setWeaponId(weapon.getObjectID()); core.scriptService.callScript("scripts/", "demo", "CreateStartingCharacter", object); @@ -281,7 +284,7 @@ public class CharacterService implements INetworkDispatch { ps.executeUpdate(); ps.close(); CreateCharacterSuccess success = new CreateCharacterSuccess(object.getObjectID()); - + session.write(new HeartBeatMessage().serialize()); session.write(core.loginService.getLoginCluster().serialize()); session.write(core.loginService.getLoginClusterStatus().serialize()); diff --git a/src/services/PlayerService.java b/src/services/PlayerService.java index 53980f93..2a916b75 100644 --- a/src/services/PlayerService.java +++ b/src/services/PlayerService.java @@ -27,9 +27,12 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.apache.mina.core.buffer.IoBuffer; +import org.apache.mina.core.session.IoSession; import protocol.swg.ServerTimeMessage; +import resources.common.Opcodes; import resources.objects.creature.CreatureObject; +import resources.objects.player.PlayerObject; import main.NGECore; @@ -61,11 +64,24 @@ public class PlayerService implements INetworkDispatch { } } - }, 1, 1, TimeUnit.MINUTES); + }, 1, 1, TimeUnit.SECONDS); } public void postZoneIn(final CreatureObject creature) { + scheduler.scheduleAtFixedRate(new Runnable() { + + @Override + public void run() { + + PlayerObject player = (PlayerObject) creature.getSlottedObject("ghost"); + player.setTotalPlayTime(player.getTotalPlayTime() + 30); + player.setLastPlayTimeUpdate(System.currentTimeMillis()); + + } + + }, 30, 30, TimeUnit.SECONDS); + scheduler.scheduleAtFixedRate(new Runnable() { @Override @@ -93,9 +109,17 @@ public class PlayerService implements INetworkDispatch { } @Override - public void insertOpcodes(Map arg0, - Map arg1) { - // TODO Auto-generated method stub + public void insertOpcodes(Map swgOpcodes, Map objControllerOpcodes) { + + swgOpcodes.put(Opcodes.CmdSceneReady, new INetworkRemoteEvent() { + + @Override + public void handlePacket(IoSession session, IoBuffer buffer) throws Exception { + + + } + + }); } diff --git a/src/services/SimulationService.java b/src/services/SimulationService.java index 985c302d..d1bb145c 100644 --- a/src/services/SimulationService.java +++ b/src/services/SimulationService.java @@ -439,17 +439,23 @@ public class SimulationService implements INetworkDispatch { if(client.getParent() == null) return; + session.suspendWrite(); + CreatureObject object = (CreatureObject) client.getParent(); boolean remove = remove(object, object.getPosition().x, object.getPosition().z); if(remove) System.out.println("Successful quadtree remove"); - HashSet oldObservers = new HashSet(object.getObservers()); - for(Iterator it = oldObservers.iterator(); it.hasNext();) { - Client observerClient = it.next(); - if(observerClient.getParent() != null) { - observerClient.getParent().makeUnaware(object); + 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); } @@ -457,8 +463,6 @@ public class SimulationService implements INetworkDispatch { core.getCreatureODB().put(object, Long.class, CreatureObject.class, object.getTransaction()); object.getTransaction().commitSync(); - session.suspendRead(); - session.suspendWrite(); core.objectService.destroyObject(object); core.getActiveConnectionsMap().remove((Integer) session.getAttribute("connectionId")); @@ -540,7 +544,7 @@ public class SimulationService implements INetworkDispatch { CmdStartScene startScene = new CmdStartScene((byte) 0, object.getObjectID(), object.getPlanet().getPath(), object.getTemplate(), newPos.x, newPos.y, newPos.z, System.currentTimeMillis() / 1000, object.getRadians()); session.write(startScene.serialize()); - core.simulationService.handleZoneIn(client); + handleZoneIn(client); object.makeAware(object); @@ -560,7 +564,7 @@ public class SimulationService implements INetworkDispatch { if(position.x >= -8192 && position.x <= 8192 && position.z >= -8192 && position.z <= 8192) { - DataTransform dataTransform = new DataTransform(new Point3D(position.x, position.y, position.z), orientation, obj.getMovementCounter(), obj.getObjectID()); + DataTransform dataTransform = new DataTransform(new Point3D(position.x, position.y, position.z), orientation, 1, obj.getObjectID()); ObjControllerMessage objController = new ObjControllerMessage(0x1B, dataTransform); obj.notifyObservers(objController, true); diff --git a/src/services/StaticService.java b/src/services/StaticService.java index 42019b6b..c06a70ce 100644 --- a/src/services/StaticService.java +++ b/src/services/StaticService.java @@ -21,6 +21,62 @@ ******************************************************************************/ package services; -public class StaticService { +import java.util.Map; + +import main.NGECore; + +import engine.resources.objects.SWGObject; +import engine.resources.scene.Planet; +import engine.resources.scene.Point3D; +import engine.resources.scene.Quaternion; +import engine.resources.service.INetworkDispatch; +import engine.resources.service.INetworkRemoteEvent; + +public class StaticService implements INetworkDispatch { + + private NGECore core; + + public StaticService(NGECore core) { + this.core = core; + } + + @Override + public void insertOpcodes(Map arg0, Map arg1) { + + } + + @Override + public void shutdown() { + + } + + public void spawnObject(String template, String planetName, long cellId, float x, float y, float z, float qY, float qW) { + + Planet planet = core.terrainService.getPlanetByName(planetName); + + if(planet == null) { + System.out.println("Cant spawn static object because planet is null"); + return; + } + + SWGObject object = core.objectService.createObject(template, 0, planet, new Point3D(x, y, z), new Quaternion(qW, 0, qY, 0)); + + if(object == null) { + System.out.println("Static object is null"); + return; + } + + if(cellId == 0) + core.simulationService.add(object, x, z); + else { + SWGObject parent = core.objectService.getObject(cellId); + if(parent == null) { + System.out.println("Cell not found"); + return; + } + parent.add(object); + } + + } } diff --git a/src/services/chat/Mail.java b/src/services/chat/Mail.java index 3b6ad439..5709a059 100644 --- a/src/services/chat/Mail.java +++ b/src/services/chat/Mail.java @@ -22,9 +22,6 @@ package services.chat; import java.util.List; -import java.util.Vector; - - import com.sleepycat.persist.model.Entity; import com.sleepycat.persist.model.PrimaryKey; diff --git a/src/services/combat/CombatService.java b/src/services/combat/CombatService.java index 39cf70d7..64da30c8 100644 --- a/src/services/combat/CombatService.java +++ b/src/services/combat/CombatService.java @@ -23,23 +23,16 @@ package services.combat; import java.util.Map; import java.util.Random; - -import org.python.modules.math; - import protocol.swg.ObjControllerMessage; import protocol.swg.objectControllerObjects.CombatAction; import protocol.swg.objectControllerObjects.CommandEnqueueRemove; import protocol.swg.objectControllerObjects.StartTask; - import resources.objects.creature.CreatureObject; import resources.objects.tangible.TangibleObject; import resources.objects.weapon.WeaponObject; import services.command.CombatCommand; - import main.NGECore; - import engine.resources.common.CRC; -import engine.resources.objects.SWGObject; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; diff --git a/src/services/guild/GuildService.java b/src/services/guild/GuildService.java index 7666a6eb..a3be40bf 100644 --- a/src/services/guild/GuildService.java +++ b/src/services/guild/GuildService.java @@ -26,15 +26,19 @@ import java.util.Map; import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.session.IoSession; +import protocol.swg.CmdSceneReady; + import resources.common.Opcodes; import resources.objects.Guild; import resources.objects.SWGList; +import resources.objects.creature.CreatureObject; import resources.objects.guild.GuildObject; import main.NGECore; import engine.clients.Client; import engine.resources.objects.SWGObject; +import engine.resources.scene.Point3D; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; @@ -126,10 +130,10 @@ public class GuildService implements INetworkDispatch { @Override public void handlePacket(IoSession session, IoBuffer data) throws Exception { Client client = core.getClient((Integer) session.getAttribute("connectionId")); - - object.sendCreate(client); - object.sendBaselines(client); - object.sendSceneEndBaselines(client); + + // CmdSceneReady sceneReady = new CmdSceneReady(); + // client.getSession().write(sceneReady.serialize()); + } }); diff --git a/src/services/object/ObjectService.java b/src/services/object/ObjectService.java index 9b337588..434688a5 100644 --- a/src/services/object/ObjectService.java +++ b/src/services/object/ObjectService.java @@ -384,31 +384,35 @@ public class ObjectService implements INetworkDispatch { parent._add(creature); } - Point3D position = creature.getWorldPosition(); + Point3D position = creature.getPosition(); - //UnkByteFlag unkByteFlag = new UnkByteFlag(); + UnkByteFlag unkByteFlag = new UnkByteFlag(); //session.write(unkByteFlag.serialize()); - //ParametersMessage parameters = new ParametersMessage(); + ParametersMessage parameters = new ParametersMessage(); //session.write(parameters.serialize()); - + + core.buffService.clearBuffs(creature); + core.chatService.loadMailHeaders(client); 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()); + CmdStartScene startScene = new CmdStartScene((byte) 0, objectId, creature.getPlanet().getPath(), creature.getTemplate(), position.x, position.y, position.z, System.currentTimeMillis() / 1000, 0); session.write(startScene.serialize()); - - core.simulationService.handleZoneIn(client); creature.makeAware(creature); + creature.makeAware(core.guildService.getGuildObject()); + + core.simulationService.handleZoneIn(client); + + CmdSceneReady sceneReady = new CmdSceneReady(); + client.getSession().write(sceneReady.serialize()); + core.playerService.postZoneIn(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()); } });