diff --git a/src/resources/Location.java b/src/resources/Location.java
index db0c5e196..b08120bbf 100644
--- a/src/resources/Location.java
+++ b/src/resources/Location.java
@@ -29,15 +29,14 @@ package resources;
import network.packets.Packet;
import resources.encodables.Encodable;
+import resources.network.NetBufferStream;
+import resources.persistable.Persistable;
-import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-public class Location implements Encodable, Serializable {
-
- private static final long serialVersionUID = 1L;
+public class Location implements Encodable, Persistable {
private final Point3D point;
private final Quaternion orientation;
@@ -284,6 +283,25 @@ public class Location implements Encodable, Serializable {
orientation.decode(data);
point.decode(data);
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ orientation.save(stream);
+ point.save(stream);
+ stream.addBoolean(terrain != null);
+ if (terrain != null)
+ stream.addAscii(terrain.name());
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ orientation.read(stream);
+ point.read(stream);
+ if (stream.getBoolean())
+ terrain = Terrain.valueOf(stream.getAscii());
+ }
@Override
public String toString() {
diff --git a/src/resources/Point3D.java b/src/resources/Point3D.java
index 177510436..6455446ea 100644
--- a/src/resources/Point3D.java
+++ b/src/resources/Point3D.java
@@ -29,13 +29,12 @@ package resources;
import network.packets.Packet;
import resources.encodables.Encodable;
+import resources.network.NetBufferStream;
+import resources.persistable.Persistable;
-import java.io.Serializable;
import java.nio.ByteBuffer;
-public class Point3D implements Encodable, Serializable {
-
- private static final long serialVersionUID = 1L;
+public class Point3D implements Encodable, Persistable {
private double x;
private double y;
@@ -111,6 +110,20 @@ public class Point3D implements Encodable, Serializable {
z = Packet.getFloat(data);
}
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addFloat((float) x);
+ stream.addFloat((float) y);
+ stream.addFloat((float) z);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ x = stream.getFloat();
+ y = stream.getFloat();
+ z = stream.getFloat();
+ }
+
public boolean equals(Object o) {
if (!(o instanceof Point3D))
return false;
diff --git a/src/resources/Quaternion.java b/src/resources/Quaternion.java
index f04c390c3..d54e8999d 100644
--- a/src/resources/Quaternion.java
+++ b/src/resources/Quaternion.java
@@ -29,13 +29,12 @@ package resources;
import network.packets.Packet;
import resources.encodables.Encodable;
+import resources.network.NetBufferStream;
+import resources.persistable.Persistable;
-import java.io.Serializable;
import java.nio.ByteBuffer;
-public class Quaternion implements Encodable, Serializable {
-
- private static final long serialVersionUID = 1L;
+public class Quaternion implements Encodable, Persistable {
private double x;
private double y;
@@ -153,6 +152,22 @@ public class Quaternion implements Encodable, Serializable {
z = Packet.getFloat(data);
w = Packet.getFloat(data);
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addFloat((float) x);
+ stream.addFloat((float) y);
+ stream.addFloat((float) z);
+ stream.addFloat((float) w);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ x = stream.getFloat();
+ y = stream.getFloat();
+ z = stream.getFloat();
+ w = stream.getFloat();
+ }
public String toString() {
return String.format("Quaternion[%.3f, %.3f, %.3f, %.3f]", x, y, z, w);
diff --git a/src/resources/SkillMod.java b/src/resources/SkillMod.java
index c8f6fe01f..33db0c4c8 100644
--- a/src/resources/SkillMod.java
+++ b/src/resources/SkillMod.java
@@ -27,16 +27,15 @@
***********************************************************************************/
package resources;
-import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import resources.encodables.Encodable;
+import resources.network.NetBufferStream;
+import resources.persistable.Persistable;
-public class SkillMod implements Encodable, Serializable {
+public class SkillMod implements Encodable, Persistable {
- private static final long serialVersionUID = 1L;
-
private int base, modifier;
public SkillMod() {
@@ -64,6 +63,18 @@ public class SkillMod implements Encodable, Serializable {
modifier = data.getInt();
}
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addInt(base);
+ stream.addInt(modifier);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ base = stream.getInt();
+ modifier = stream.getInt();
+ }
+
public void adjustBase(int adjustment) {
base += adjustment;
}
diff --git a/src/resources/chat/ChatAvatar.java b/src/resources/chat/ChatAvatar.java
index 994fffa06..37ef44fa2 100644
--- a/src/resources/chat/ChatAvatar.java
+++ b/src/resources/chat/ChatAvatar.java
@@ -24,25 +24,24 @@
* You should have received a copy of the GNU Affero General Public License
* along with Holocore. If not, see
******************************************************************************/
-
package resources.chat;
import network.packets.Packet;
import resources.encodables.Encodable;
+import resources.network.NetBufferStream;
+import resources.persistable.Persistable;
import resources.player.Player;
import java.io.IOException;
import java.io.ObjectInputStream;
-import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.Locale;
/**
* @author Waverunner
*/
-public class ChatAvatar implements Encodable, Serializable {
- private static final long serialVersionUID = 1L;
-
+public class ChatAvatar implements Encodable, Persistable {
+
private long networkId;
private String name;
private String game = "SWG";
@@ -133,7 +132,21 @@ public class ChatAvatar implements Encodable, Serializable {
galaxy = Packet.getAscii(data);
name = Packet.getAscii(data).toLowerCase(Locale.US);
}
-
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ stream.addAscii(galaxy);
+ stream.addAscii(name);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ galaxy = stream.getAscii();
+ name = stream.getAscii();
+ }
+
@Override
public String toString() {
return "ChatAvatar[networkId=" + networkId +
diff --git a/src/resources/chat/ChatRoom.java b/src/resources/chat/ChatRoom.java
index d3749e91f..88701afec 100644
--- a/src/resources/chat/ChatRoom.java
+++ b/src/resources/chat/ChatRoom.java
@@ -24,7 +24,6 @@
* You should have received a copy of the GNU Affero General Public License
* along with Holocore. If not, see
******************************************************************************/
-
package resources.chat;
import network.packets.Packet;
@@ -32,13 +31,14 @@ import network.packets.swg.SWGPacket;
import network.packets.swg.zone.chat.ChatRoomMessage;
import resources.encodables.Encodable;
import resources.encodables.OutOfBandPackage;
+import resources.network.NetBufferStream;
import resources.objects.player.PlayerObject;
+import resources.persistable.Persistable;
import resources.player.Player;
import services.player.PlayerManager;
import java.io.IOException;
import java.io.ObjectInputStream;
-import java.io.Serializable;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
@@ -46,9 +46,8 @@ import java.util.List;
/**
* @author Waverunner
*/
-public class ChatRoom implements Encodable, Serializable {
- private static final long serialVersionUID = 1L;
-
+public class ChatRoom implements Encodable, Persistable {
+
private int id;
private int type;
private String path;
@@ -306,10 +305,63 @@ public class ChatRoom implements Encodable, Serializable {
return data;
}
+ /*
+ private int id;
+ private int type;
+ private String path;
+ private ChatAvatar owner;
+ private ChatAvatar creator;
+ private String title;
+ private List moderators;
+ private List invited;
+ private boolean moderated; // No one but moderators can talk
+ private List banned;
+ */
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ owner.save(stream);
+ creator.save(stream);
+ stream.addInt(id);
+ stream.addInt(type);
+ stream.addAscii(path);
+ stream.addUnicode(title);
+ stream.addBoolean(moderated);
+ stream.addList(moderators, (a) -> a.save(stream));
+ stream.addList(invited, (a) -> a.save(stream));
+ stream.addList(banned, (a) -> a.save(stream));
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ owner.read(stream);
+ creator.read(stream);
+ id = stream.getInt();
+ type = stream.getInt();
+ path = stream.getAscii();
+ title = stream.getUnicode();
+ moderated = stream.getBoolean();
+ stream.getList((i) -> moderators.add(inflateAvatar(stream)));
+ stream.getList((i) -> invited.add(inflateAvatar(stream)));
+ stream.getList((i) -> banned.add(inflateAvatar(stream)));
+ }
+
+ private ChatAvatar inflateAvatar(NetBufferStream stream) {
+ ChatAvatar avatar = new ChatAvatar();
+ avatar.read(stream);
+ return avatar;
+ }
@Override
public String toString() {
return "ChatRoom[id=" + id + ", type=" + type + ", path='" + path + "', title='" + title + '\'' +
", creator=" + creator + ", moderated=" + moderated + ", isPublic=" + isPublic() + "]";
}
+
+ public static ChatRoom create(NetBufferStream stream) {
+ ChatRoom room = new ChatRoom();
+ room.read(stream);
+ return room;
+ }
}
diff --git a/src/resources/collections/SWGBitSet.java b/src/resources/collections/SWGBitSet.java
index 0bb195a66..576d42a3b 100644
--- a/src/resources/collections/SWGBitSet.java
+++ b/src/resources/collections/SWGBitSet.java
@@ -28,13 +28,15 @@
package resources.collections;
import resources.encodables.Encodable;
+import resources.network.NetBufferStream;
import resources.objects.SWGObject;
+import resources.persistable.Persistable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.BitSet;
-public class SWGBitSet extends BitSet implements Encodable {
+public class SWGBitSet extends BitSet implements Encodable, Persistable {
private static final long serialVersionUID = 1L;
@@ -64,6 +66,17 @@ public class SWGBitSet extends BitSet implements Encodable {
throw new UnsupportedOperationException("Unable to decode bitset!");
}
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addArray(toByteArray());
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ clear();
+ xor(valueOf(stream.getArray()));
+ }
+
public void sendDeltaMessage(SWGObject target) {
target.sendDelta(view, updateType, encode());
}
diff --git a/src/resources/collections/SWGFlag.java b/src/resources/collections/SWGFlag.java
index 9f9145827..e6fcbbbef 100644
--- a/src/resources/collections/SWGFlag.java
+++ b/src/resources/collections/SWGFlag.java
@@ -29,14 +29,16 @@ package resources.collections;
import network.packets.swg.zone.baselines.Baseline;
import resources.encodables.Encodable;
+import resources.network.NetBufferStream;
import resources.objects.SWGObject;
+import resources.persistable.Persistable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.BitSet;
-public class SWGFlag extends BitSet implements Encodable {
+public class SWGFlag extends BitSet implements Encodable, Persistable {
private static final long serialVersionUID = 2L;
@@ -77,6 +79,17 @@ public class SWGFlag extends BitSet implements Encodable {
throw new UnsupportedOperationException("Unable to decode bitset!");
}
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addArray(toByteArray());
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ clear();
+ xor(valueOf(stream.getArray()));
+ }
+
@Override
public boolean equals(Object o) {
if (!(o instanceof SWGFlag))
diff --git a/src/resources/commands/callbacks/QaToolCmdCallback.java b/src/resources/commands/callbacks/QaToolCmdCallback.java
index 24be2e283..50acfb82c 100644
--- a/src/resources/commands/callbacks/QaToolCmdCallback.java
+++ b/src/resources/commands/callbacks/QaToolCmdCallback.java
@@ -150,7 +150,7 @@ public class QaToolCmdCallback implements ICmdCallback {
private void forceDelete(final ObjectManager objManager, final Player player, final SWGObject target) {
SuiMessageBox inputBox = new SuiMessageBox(SuiButtons.OK_CANCEL, "Force Delete?", "Are you sure you want to delete this object?");
inputBox.addOkButtonCallback("handleDeleteObject", (caller, actor, event, parameters) -> {
- if (target instanceof CreatureObject && ((CreatureObject) target).getPlayerObject() != null) {
+ if (target instanceof CreatureObject && ((CreatureObject) target).isPlayer()) {
Log.i("QA", "[%s] Requested deletion of character: %s", player.getUsername(), target.getName());
new DeleteCharacterIntent((CreatureObject) target).broadcast();
Player owner = target.getOwner();
diff --git a/src/resources/common/CRC.java b/src/resources/common/CRC.java
index f6a82cccd..1611af3d1 100644
--- a/src/resources/common/CRC.java
+++ b/src/resources/common/CRC.java
@@ -27,18 +27,17 @@
***********************************************************************************/
package resources.common;
-import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.StandardCharsets;
import resources.encodables.Encodable;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
+import resources.persistable.Persistable;
import resources.server_info.CrcDatabase;
-public class CRC implements Encodable, Serializable {
-
- private static final long serialVersionUID = 1L;
+public class CRC implements Encodable, Persistable {
private static final int CRC_TABLE[] = {
0x00000000, 0x04C11DB7, 0x09823B6E, 0x0D4326D9, 0x130476DC, 0x17C56B6B, 0x1A864DB2, 0x1E475005,
@@ -117,6 +116,16 @@ public class CRC implements Encodable, Serializable {
this.str = getString(crc);
}
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addInt(crc);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ crc = stream.getInt();
+ }
+
@Override
public String toString() {
return str;
diff --git a/src/resources/containers/ContainerPermissions.java b/src/resources/containers/ContainerPermissions.java
index 312580634..c0cee9bc4 100644
--- a/src/resources/containers/ContainerPermissions.java
+++ b/src/resources/containers/ContainerPermissions.java
@@ -24,21 +24,25 @@
* You should have received a copy of the GNU Affero General Public License
* along with Holocore. If not, see
******************************************************************************/
-
package resources.containers;
-import resources.objects.SWGObject;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
-import java.io.Serializable;
-import java.util.*;
+import resources.network.NetBufferStream;
+import resources.objects.SWGObject;
+import resources.persistable.Persistable;
/**
* Structure for creating permission sets that will allow the object to be viewed/modified/added/removed by a requested
* object depending on the implemented abstract methods.
* @author Waverunner
*/
-public abstract class ContainerPermissions implements Serializable {
- private static final long serialVersionUID = 1L;
+public abstract class ContainerPermissions implements Persistable {
public static final WorldPermissions WORLD = new WorldPermissions();
public static final InventoryPermissions INVENTORY = new InventoryPermissions();
@@ -130,6 +134,27 @@ public abstract class ContainerPermissions implements Serializable {
public void addDefaultWorldPermissions() {
addPermissions("world", Permission.VIEW, Permission.ENTER);
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ synchronized (permissionGroups) {
+ stream.addMap(permissionGroups, (e) -> {
+ stream.addAscii(e.getKey());
+ stream.addInt(e.getValue());
+ });
+ }
+ synchronized (joinedGroups) {
+ stream.addList(joinedGroups, (g) -> stream.addAscii(g));
+ }
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ stream.getList((i) -> permissionGroups.put(stream.getAscii(), stream.getInt()));
+ stream.getList((i) -> joinedGroups.add(stream.getAscii()));
+ }
public abstract boolean canView(SWGObject viewer, SWGObject container);
public abstract boolean canEnter(SWGObject requester, SWGObject container);
diff --git a/src/resources/containers/DefaultPermissions.java b/src/resources/containers/DefaultPermissions.java
index 558b5899f..94e0a85dc 100644
--- a/src/resources/containers/DefaultPermissions.java
+++ b/src/resources/containers/DefaultPermissions.java
@@ -36,8 +36,6 @@ import resources.objects.SWGObject;
*/
public class DefaultPermissions extends ContainerPermissions {
- private static final long serialVersionUID = 200L;
-
@Override
public boolean canView(SWGObject requester, SWGObject container) {
return true;
diff --git a/src/resources/containers/InventoryPermissions.java b/src/resources/containers/InventoryPermissions.java
index 4d4b72c4a..5b039f600 100644
--- a/src/resources/containers/InventoryPermissions.java
+++ b/src/resources/containers/InventoryPermissions.java
@@ -36,8 +36,6 @@ import resources.objects.SWGObject;
*/
public class InventoryPermissions extends DefaultPermissions {
- private static final long serialVersionUID = 200L;
-
@Override
public boolean canView(SWGObject requester, SWGObject container) {
return requester.getOwner() == container.getOwner();
diff --git a/src/resources/containers/WorldPermissions.java b/src/resources/containers/WorldPermissions.java
index 3250b7936..301f9cb68 100644
--- a/src/resources/containers/WorldPermissions.java
+++ b/src/resources/containers/WorldPermissions.java
@@ -48,8 +48,6 @@ import resources.objects.SWGObject;
*/
public class WorldPermissions extends DefaultPermissions {
- private static final long serialVersionUID = 200L;
-
@Override
public boolean canView(SWGObject viewer, SWGObject container) {
if (super.canView(viewer, container))
diff --git a/src/resources/encodables/OutOfBandData.java b/src/resources/encodables/OutOfBandData.java
index e43c43820..272166791 100644
--- a/src/resources/encodables/OutOfBandData.java
+++ b/src/resources/encodables/OutOfBandData.java
@@ -27,10 +27,12 @@
package resources.encodables;
+import resources.persistable.Persistable;
+
/**
* @author Waverunner
*/
-public interface OutOfBandData extends Encodable{
+public interface OutOfBandData extends Encodable, Persistable {
OutOfBandPackage.Type getOobType();
int getOobPosition();
}
diff --git a/src/resources/encodables/OutOfBandFactory.java b/src/resources/encodables/OutOfBandFactory.java
new file mode 100644
index 000000000..aff133d79
--- /dev/null
+++ b/src/resources/encodables/OutOfBandFactory.java
@@ -0,0 +1,70 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.encodables;
+
+import resources.network.NetBufferStream;
+import resources.objects.waypoint.WaypointObject;
+import resources.persistable.SWGObjectFactory;
+
+public class OutOfBandFactory {
+
+ public static void save(OutOfBandData oob, NetBufferStream stream) {
+ if (oob instanceof StringId)
+ stream.addByte(1);
+ else if (oob instanceof ProsePackage)
+ stream.addByte(2);
+ else if (oob instanceof WaypointObject) {
+ stream.addByte(3);
+ SWGObjectFactory.save((WaypointObject) oob, stream);
+ return;
+ } else
+ throw new IllegalArgumentException("Unknown OOB data!");
+ oob.save(stream);
+ }
+
+ public static OutOfBandData create(NetBufferStream stream) {
+ OutOfBandData oob;
+ byte type = stream.getByte();
+ switch (type) {
+ case 1:
+ oob = new StringId();
+ break;
+ case 2:
+ oob = new ProsePackage();
+ break;
+ case 3:
+ oob = (WaypointObject) SWGObjectFactory.create(stream);
+ return oob;
+ default:
+ throw new IllegalStateException("Unknown type byte! Type: " + type);
+ }
+ oob.read(stream);
+ return oob;
+ }
+
+}
diff --git a/src/resources/encodables/OutOfBandPackage.java b/src/resources/encodables/OutOfBandPackage.java
index 815a4ea66..9a016aa83 100644
--- a/src/resources/encodables/OutOfBandPackage.java
+++ b/src/resources/encodables/OutOfBandPackage.java
@@ -28,12 +28,13 @@
package resources.encodables;
import network.packets.Packet;
+import resources.network.NetBufferStream;
import resources.objects.waypoint.WaypointObject;
+import resources.persistable.Persistable;
import resources.server_info.Log;
import java.io.IOException;
import java.io.ObjectInputStream;
-import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
@@ -41,9 +42,8 @@ import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
-public class OutOfBandPackage implements Encodable, Serializable {
- private static final long serialVersionUID = 1L;
-
+public class OutOfBandPackage implements Encodable, Persistable {
+
private List packages;
private transient List data;
private transient int dataSize;
@@ -108,6 +108,16 @@ public class OutOfBandPackage implements Encodable, Serializable {
read += data.position() - start;
}
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addList(packages, (p) -> p.save(stream));
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getList((i) -> packages.add(OutOfBandFactory.create(stream)));
+ }
private void unpackOutOfBandData(ByteBuffer data, Type type) {
// Position doesn't seem to be reflective of it's spot in the package list, not sure if this can be automated
diff --git a/src/resources/encodables/ProsePackage.java b/src/resources/encodables/ProsePackage.java
index 99782430a..9c205dd0b 100644
--- a/src/resources/encodables/ProsePackage.java
+++ b/src/resources/encodables/ProsePackage.java
@@ -29,17 +29,17 @@ package resources.encodables;
import network.packets.Packet;
-import java.io.Serializable;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
+import resources.network.NetBufferStream;
+import resources.persistable.Persistable;
import resources.server_info.Log;
-public class ProsePackage implements OutOfBandData, Serializable {
- private static final long serialVersionUID = 1L;
-
+public class ProsePackage implements OutOfBandData {
+
private StringId base = new StringId("", "");
private Prose actor = new Prose();
@@ -228,6 +228,30 @@ public class ProsePackage implements OutOfBandData, Serializable {
df = Packet.getInt(data);
grammarFlag = Packet.getBoolean(data);
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ base.save(stream);
+ actor.save(stream);
+ target.save(stream);
+ other.save(stream);
+ stream.addBoolean(grammarFlag);
+ stream.addInt(di);
+ stream.addFloat(df);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ base.read(stream);
+ actor.read(stream);
+ target.read(stream);
+ other.read(stream);
+ grammarFlag = stream.getBoolean();
+ di = stream.getInt();
+ df = stream.getFloat();
+ }
@Override
public OutOfBandPackage.Type getOobType() {
@@ -247,10 +271,8 @@ public class ProsePackage implements OutOfBandData, Serializable {
"]";
}
- private static class Prose implements Encodable, Serializable {
-
- private static final long serialVersionUID = 1L;
-
+ private static class Prose implements Encodable, Persistable {
+
private long objectId;
private StringId stringId;
private String text;
@@ -294,6 +316,22 @@ public class ProsePackage implements OutOfBandData, Serializable {
stringId = Packet.getEncodable(data, StringId.class);
text = Packet.getUnicode(data);
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ stringId.save(stream);
+ stream.addLong(objectId);
+ stream.addUnicode(text);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ stringId.read(stream);
+ objectId = stream.getLong();
+ text = stream.getUnicode();
+ }
@Override
public String toString() {
diff --git a/src/resources/encodables/StringId.java b/src/resources/encodables/StringId.java
index 253a5f541..14b6eca57 100644
--- a/src/resources/encodables/StringId.java
+++ b/src/resources/encodables/StringId.java
@@ -29,13 +29,13 @@ package resources.encodables;
import network.packets.Packet;
-import java.io.Serializable;
import java.nio.ByteBuffer;
+import resources.network.NetBufferStream;
+import resources.persistable.Persistable;
import resources.server_info.Log;
-public class StringId implements OutOfBandData, Serializable {
- private static final long serialVersionUID = 1L;
+public class StringId implements OutOfBandData, Persistable {
private String key = "";
private String file = "";
@@ -79,6 +79,18 @@ public class StringId implements OutOfBandData, Serializable {
Packet.getInt(data);
key = Packet.getAscii(data);
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addAscii(file);
+ stream.addAscii(key);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ file = stream.getAscii();
+ key = stream.getAscii();
+ }
@Override
public OutOfBandPackage.Type getOobType() {
diff --git a/src/resources/encodables/player/Equipment.java b/src/resources/encodables/player/Equipment.java
index 86ee0cb8a..3879747c8 100644
--- a/src/resources/encodables/player/Equipment.java
+++ b/src/resources/encodables/player/Equipment.java
@@ -31,18 +31,19 @@ import network.packets.swg.zone.baselines.Baseline;
import resources.common.CRC;
import resources.encodables.Encodable;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
import resources.objects.SWGObject;
import resources.objects.tangible.TangibleObject;
import resources.objects.weapon.WeaponObject;
+import resources.persistable.Persistable;
+import resources.persistable.SWGObjectFactory;
import resources.player.Player;
import resources.server_info.Log;
import services.objects.ObjectCreator;
-import java.io.Serializable;
import java.nio.ByteBuffer;
-public class Equipment implements Encodable, Serializable {
- private static final long serialVersionUID = 1L;
+public class Equipment implements Encodable, Persistable {
private TangibleObject weapon;
private byte [] customizationString;
@@ -96,6 +97,29 @@ public class Equipment implements Encodable, Serializable {
if (data.getBoolean())
this.weapon = createWeaponFromData(data);
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ stream.addLong(objectId);
+ stream.addInt(arrangementId);
+ stream.addInt(template.getCrc());
+ stream.addArray(customizationString);
+ stream.addBoolean(weapon != null);
+ if (weapon != null)
+ SWGObjectFactory.save(weapon, stream);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ objectId = stream.getLong();
+ arrangementId = stream.getInt();
+ template = new CRC(stream.getInt());
+ customizationString = stream.getArray();
+ if (stream.getBoolean())
+ weapon = (TangibleObject) SWGObjectFactory.create(stream);
+ }
public byte[] getCustomizationString() {return customizationString;}
public void setCustomizationString(byte[] customizationString) { this.customizationString = customizationString; }
diff --git a/src/resources/encodables/player/Mail.java b/src/resources/encodables/player/Mail.java
index 92c648128..b1d28d5d4 100644
--- a/src/resources/encodables/player/Mail.java
+++ b/src/resources/encodables/player/Mail.java
@@ -30,15 +30,15 @@ package resources.encodables.player;
import network.packets.Packet;
import resources.encodables.Encodable;
import resources.encodables.OutOfBandPackage;
+import resources.network.NetBufferStream;
+import resources.persistable.Persistable;
import utilities.Encoder;
-import java.io.Serializable;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-public class Mail implements Encodable, Serializable {
- private static final long serialVersionUID = 1L;
-
+public class Mail implements Encodable, Persistable {
+
private int id;
private String sender;
private long receiverId;
@@ -123,6 +123,47 @@ public class Mail implements Encodable, Serializable {
subject = Packet.getUnicode(data);
outOfBandPackage = Packet.getEncodable(data, OutOfBandPackage.class);
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ stream.addByte(status);
+ stream.addInt(id);
+ stream.addInt(timestamp);
+ stream.addLong(receiverId);
+ stream.addUnicode(sender);
+ stream.addUnicode(subject);
+ stream.addUnicode(message);
+ stream.addBoolean(outOfBandPackage != null);
+ if (outOfBandPackage != null)
+ outOfBandPackage.save(stream);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ status = stream.getByte();
+ id = stream.getInt();
+ timestamp = stream.getInt();
+ receiverId = stream.getLong();
+ sender = stream.getUnicode();
+ subject = stream.getUnicode();
+ message = stream.getUnicode();
+ if (stream.getBoolean()) {
+ outOfBandPackage = new OutOfBandPackage();
+ outOfBandPackage.read(stream);
+ }
+ }
+
+ public int hashCode() {
+ return id;
+ }
+
+ public boolean equals(Object o) {
+ if (!(o instanceof Mail))
+ return false;
+ return ((Mail) o).id == id;
+ }
public byte[] encodeHeader() {
ByteBuffer bb = ByteBuffer.allocate(12 + subject.length() * 2).order(ByteOrder.LITTLE_ENDIAN);
@@ -131,4 +172,14 @@ public class Mail implements Encodable, Serializable {
bb.putInt(0);
return bb.array();
}
+
+ public static Mail create(NetBufferStream stream) {
+ Mail m = new Mail("", "", "", 0);
+ m.read(stream);
+ return m;
+ }
+
+ public static void saveMail(Mail m, NetBufferStream stream) {
+ m.save(stream);
+ }
}
diff --git a/src/resources/network/BaselineObject.java b/src/resources/network/BaselineObject.java
index 94c99c426..24a8289a6 100644
--- a/src/resources/network/BaselineObject.java
+++ b/src/resources/network/BaselineObject.java
@@ -29,7 +29,6 @@ package resources.network;
import java.io.IOException;
import java.io.ObjectInputStream;
-import java.io.Serializable;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
@@ -40,9 +39,7 @@ import utilities.Encoder.StringType;
import network.packets.swg.zone.baselines.Baseline;
import network.packets.swg.zone.baselines.Baseline.BaselineType;
-public class BaselineObject implements Serializable {
-
- private static final long serialVersionUID = 1L;
+public class BaselineObject {
private transient List> baselineData;
diff --git a/src/resources/network/NetBufferStream.java b/src/resources/network/NetBufferStream.java
index 62ac229ba..34c255dd5 100644
--- a/src/resources/network/NetBufferStream.java
+++ b/src/resources/network/NetBufferStream.java
@@ -29,6 +29,10 @@ package resources.network;
import java.io.OutputStream;
import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
import resources.collections.SWGList;
import resources.collections.SWGMap;
@@ -279,6 +283,12 @@ public class NetBufferStream extends OutputStream {
}
}
+ public void getList(NumericalIterator ni) {
+ int size = getInt();
+ for (int i = 0; i < size; i++)
+ ni.onItem(i);
+ }
+
public SWGSet getSwgSet(int num, int var, StringType type) {
synchronized (bufferMutex) {
return buffer.getSwgSet(num, var, type);
@@ -321,6 +331,136 @@ public class NetBufferStream extends OutputStream {
}
}
+ public void addBoolean(boolean b) {
+ ensureCapacity(size+1);
+ synchronized (bufferMutex) {
+ buffer.addBoolean(b);
+ size++;
+ }
+ }
+
+ public void addAscii(String s) {
+ ensureCapacity(size+2+s.length());
+ synchronized (bufferMutex) {
+ buffer.addAscii(s);
+ size += 2 + s.length();
+ }
+ }
+
+ public void addAscii(char[] s) {
+ ensureCapacity(size+2+s.length);
+ synchronized (bufferMutex) {
+ buffer.addAscii(s);
+ size += 2 + s.length;
+ }
+ }
+
+ public void addUnicode(String s) {
+ ensureCapacity(size+4+s.length()*2);
+ synchronized (bufferMutex) {
+ buffer.addUnicode(s);
+ size += 4 + s.length()*2;
+ }
+ }
+
+ public void addLong(long l) {
+ ensureCapacity(size+8);
+ synchronized (bufferMutex) {
+ buffer.addLong(l);
+ size += 8;
+ }
+ }
+
+ public void addInt(int i) {
+ ensureCapacity(size+4);
+ synchronized (bufferMutex) {
+ buffer.addInt(i);
+ size += 4;
+ }
+ }
+
+ public void addFloat(float f) {
+ ensureCapacity(size+4);
+ synchronized (bufferMutex) {
+ buffer.addFloat(f);
+ size += 4;
+ }
+ }
+
+ public void addShort(int i) {
+ ensureCapacity(size+2);
+ synchronized (bufferMutex) {
+ buffer.addShort(i);
+ size += 2;
+ }
+ }
+
+ public void addNetLong(long l) {
+ ensureCapacity(size+8);
+ synchronized (bufferMutex) {
+ buffer.addNetLong(l);
+ size += 8;
+ }
+ }
+
+ public void addNetInt(int i) {
+ ensureCapacity(size+4);
+ synchronized (bufferMutex) {
+ buffer.addNetInt(i);
+ size += 4;
+ }
+ }
+
+ public void addNetShort(int i) {
+ ensureCapacity(size+2);
+ synchronized (bufferMutex) {
+ buffer.addNetShort(i);
+ size += 2;
+ }
+ }
+
+ public void addByte(int b) {
+ ensureCapacity(size+1);
+ synchronized (bufferMutex) {
+ buffer.addByte(b);
+ size++;
+ }
+ }
+
+ public void addArray(byte[] b) {
+ ensureCapacity(size+2+b.length);
+ synchronized (bufferMutex) {
+ buffer.addArray(b);
+ size += 2 + b.length;
+ }
+ }
+
+ public void addList(List l, ListIterable r) {
+ addInt(l.size());
+ for (T t : l)
+ r.onItem(t);
+ }
+
+ public void addList(Set s, ListIterable r) {
+ addInt(s.size());
+ for (T t : s)
+ r.onItem(t);
+ }
+
+ public void addMap(Map m, MapIterable r) {
+ addInt(m.size());
+ for (Entry e : m.entrySet())
+ r.onItem(e);
+ }
+
+ public void addRawArray(byte[] b) {
+ write(b);
+ }
+
+ public void addEncodable(Encodable e) {
+ addRawArray(e.encode());
+ }
+
public byte [] array() {
synchronized (bufferMutex) {
return buffer.array();
@@ -350,4 +490,16 @@ public class NetBufferStream extends OutputStream {
}
}
+ public static interface ListIterable {
+ void onItem(T item);
+ }
+
+ public static interface MapIterable {
+ void onItem(Entry item);
+ }
+
+ public static interface NumericalIterator {
+ void onItem(int index);
+ }
+
}
diff --git a/src/resources/objects/SWGObject.java b/src/resources/objects/SWGObject.java
index b3e24e624..91e73de5d 100644
--- a/src/resources/objects/SWGObject.java
+++ b/src/resources/objects/SWGObject.java
@@ -49,18 +49,18 @@ import resources.encodables.StringId;
import resources.network.BaselineBuilder;
import resources.network.BaselineObject;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
import resources.objects.building.BuildingObject;
import resources.objects.creature.CreatureObject;
+import resources.persistable.Persistable;
+import resources.persistable.SWGObjectFactory;
import resources.player.Player;
import resources.player.PlayerState;
import resources.server_info.Log;
import services.CoreManager;
-import java.io.IOException;
-import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
@@ -69,17 +69,14 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-public abstract class SWGObject extends BaselineObject implements Comparable {
+public abstract class SWGObject extends BaselineObject implements Comparable, Persistable {
- private static final long serialVersionUID = 1L;
-
private final Location location;
private final long objectId;
private final HashMap slots; // HashMap used for null value support
- private final Map containedObjects;
+ private final Set containedObjects;
private final Map attributes;
private final Map dataAttributes;
- private ContainerPermissions containerPermissions;
private transient Set objectsAware;
private transient Set customAware;
private transient BuildoutArea buildoutArea;
@@ -88,6 +85,7 @@ public abstract class SWGObject extends BaselineObject implements Comparable();
this.customAware = new HashSet<>();
this.slots = new HashMap<>();
- this.containedObjects = Collections.synchronizedMap(new HashMap());
+ this.containedObjects = new HashSet<>();
this.attributes = new LinkedHashMap<>();
this.dataAttributes = new Hashtable<>();
this.containerPermissions = new DefaultPermissions();
}
-
- private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
- areaId = -1;
- ois.defaultReadObject();
- objectsAware = new HashSet<>();
- customAware = new HashSet<>();
- buildoutArea = null;
- owner = null;
- }
/**
* Adds the specified object to this object and places it in the appropriate slot if needed
@@ -137,7 +126,7 @@ public abstract class SWGObject extends BaselineObject implements Comparable getContainedObjects() {
synchronized (containedObjects) {
- return new ArrayList<>(containedObjects.values());
+ return new ArrayList<>(containedObjects);
}
}
@@ -835,7 +813,7 @@ public abstract class SWGObject extends BaselineObject implements Comparable getObservers(Player owner, SWGObject original, boolean initial) {
Set nearby;
synchronized (containedObjects) {
- nearby = new HashSet<>(containedObjects.values());
+ nearby = new HashSet<>(containedObjects);
}
if (initial) {
nearby.addAll(getObjectsAware());
@@ -1003,7 +981,7 @@ public abstract class SWGObject extends BaselineObject implements Comparable attributes;
+ private ContainerPermissions containerPermissions;
+ private ObjectClassification classification = ObjectClassification.GENERATED;
+ private String objectName = "";
+ private int volume = 0;
+ private float complexity = 1;
+ private int containerType = 0;
+ private double loadRange = 0;
+ private int areaId = -1;
+
+ private final HashMap slots;
+ private final Map containedObjects;
+ */
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ location.save(stream);
+ containerPermissions.save(stream);
+ synchronized (attributes) {
+ stream.addMap(attributes, (e) -> {
+ stream.addAscii(e.getKey());
+ stream.addAscii(e.getValue());
+ });
+ }
+ stream.addAscii(classification.name());
+ stream.addUnicode(objectName);
+ stream.addInt(volume);
+ stream.addFloat(complexity);
+ stream.addFloat((float) loadRange);
+ Set contained;
+ synchronized (containedObjects) {
+ contained = new HashSet<>(containedObjects);
+ }
+ synchronized (slots) {
+ contained.addAll(slots.values());
+ contained.remove(null);
+ }
+ stream.addList(contained, (c) -> SWGObjectFactory.save(c, stream));
+ }
+
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ location.read(stream);
+ containerPermissions.read(stream);
+ stream.getList((i) -> attributes.put(stream.getAscii(), stream.getAscii()));
+ classification = ObjectClassification.valueOf(stream.getAscii());
+ objectName = stream.getUnicode();
+ volume = stream.getInt();
+ complexity = stream.getFloat();
+ loadRange = stream.getFloat();
+ Set contained = new HashSet<>();
+ stream.getList((i) -> contained.add(SWGObjectFactory.create(stream)));
+ for (SWGObject obj : contained)
+ obj.moveToContainer(this);
+ }
+
public enum ObjectClassification {
GENERATED,
BUILDOUT,
diff --git a/src/resources/objects/building/BuildingObject.java b/src/resources/objects/building/BuildingObject.java
index b57d489d7..6cb63dca4 100644
--- a/src/resources/objects/building/BuildingObject.java
+++ b/src/resources/objects/building/BuildingObject.java
@@ -32,6 +32,7 @@ import resources.Location;
import resources.client_info.ClientFactory;
import resources.client_info.visitors.PortalLayoutData;
import resources.client_info.visitors.ObjectData.ObjectDataAttribute;
+import resources.network.NetBufferStream;
import resources.objects.SWGObject;
import resources.objects.cell.CellObject;
import resources.objects.tangible.TangibleObject;
@@ -44,8 +45,6 @@ import java.util.List;
public class BuildingObject extends TangibleObject {
- private static final long serialVersionUID = 1L;
-
public BuildingObject(long objectId) {
super(objectId, BaselineType.BUIO);
}
@@ -121,4 +120,16 @@ public class BuildingObject extends TangibleObject {
cellObject.setCellName(cellData.getName());
// System.out.println(cellObject + " cell name " + cellObject.getCellName());
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ }
}
diff --git a/src/resources/objects/cell/CellObject.java b/src/resources/objects/cell/CellObject.java
index 17c5b87ee..377b0d87d 100644
--- a/src/resources/objects/cell/CellObject.java
+++ b/src/resources/objects/cell/CellObject.java
@@ -31,13 +31,12 @@ import network.packets.swg.zone.baselines.Baseline.BaselineType;
import network.packets.swg.zone.building.UpdateCellPermissionMessage;
import resources.network.BaselineBuilder;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
import resources.objects.SWGObject;
import resources.player.Player;
public class CellObject extends SWGObject {
- private static final long serialVersionUID = 1L;
-
private boolean isPublic = true;
private int number = 0;
private String label = "";
@@ -121,4 +120,24 @@ public class CellObject extends SWGObject {
buffer.getFloat();
labelZ = buffer.getFloat();
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ stream.addBoolean(isPublic);
+ stream.addAscii(label);
+ stream.addFloat((float) labelX);
+ stream.addFloat((float) labelZ);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ isPublic = stream.getBoolean();
+ label = stream.getAscii();
+ labelX = stream.getFloat();
+ labelZ = stream.getFloat();
+ }
}
diff --git a/src/resources/objects/creature/CreatureObject.java b/src/resources/objects/creature/CreatureObject.java
index 7e0489aaf..45fcdec6c 100644
--- a/src/resources/objects/creature/CreatureObject.java
+++ b/src/resources/objects/creature/CreatureObject.java
@@ -30,8 +30,6 @@ package resources.objects.creature;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Set;
-import java.io.IOException;
-import java.io.ObjectInputStream;
import network.packets.swg.zone.UpdatePostureMessage;
import network.packets.swg.zone.UpdatePvpStatusMessage;
@@ -41,104 +39,51 @@ import resources.HologramColour;
import resources.Posture;
import resources.PvpFlag;
import resources.Race;
-import resources.SkillMod;
import resources.collections.SWGList;
-import resources.collections.SWGMap;
import resources.collections.SWGSet;
-import resources.common.CRC;
-import resources.encodables.player.Equipment;
import resources.network.BaselineBuilder;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
import resources.objects.GameObjectType;
import resources.objects.SWGObject;
import resources.objects.player.PlayerObject;
import resources.objects.tangible.TangibleObject;
import resources.objects.weapon.WeaponObject;
+import resources.persistable.SWGObjectFactory;
import resources.player.Player;
import services.group.GroupInviterData;
import utilities.Encoder.StringType;
public class CreatureObject extends TangibleObject {
- private static final long serialVersionUID = 2L;
-
- private transient GroupInviterData inviterData = new GroupInviterData(0, null, "", 0);
private transient long lastReserveOperation = 0;
- private transient long groupId = 0;
+
+ private final CreatureObjectClientServerNP creo4 = new CreatureObjectClientServerNP();
+ private final CreatureObjectSharedNP creo6 = new CreatureObjectSharedNP();
private Posture posture = Posture.UPRIGHT;
private Race race = Race.HUMAN_MALE;
- private double movementScale = 1;
- private double movementPercent = 1;
- private double walkSpeed = 1.549;
- private double runSpeed = 7.3;
- private double accelScale = 1;
- private double accelPercent = 1;
- private double turnScale = 1;
- private double slopeModAngle = 1;
- private double slopeModPercent = 1;
- private double waterModPercent = 0.75;
private double height = 0;
- private long performanceListenTarget = 0;
- private int guildId = 0;
- private short level = 1;
- private int levelHealthGranted = 0;
- private int totalLevelXp = 0;
- private CreatureDifficulty difficulty = CreatureDifficulty.NORMAL;
private int cashBalance = 0;
private int bankBalance = 0;
private long reserveBalance = 0; // Galactic Reserve - capped at 3 billion
- private String moodAnimation = "neutral";
- private String animation = "";
- private WeaponObject equippedWeapon = null;
private WeaponObject defaultWeapon = null;
- private byte moodId = 0;
- private long lookAtTargetId = 0;
- private long intendedTargetId = 0;
- private int performanceCounter = 0;
- private int performanceId = 0;
- private String costume = "";
- private boolean visible = true;
- private boolean performing = false;
- private boolean shownOnRadar = true;
- private boolean beast = false;
private byte factionRank = 0;
private long ownerId = 0;
private int battleFatigue = 0;
private long statesBitmask = 0;
private String currentCity = "";
private long lastTransform = 0;
- private HologramColour hologramColour = HologramColour.DEFAULT;
- private SWGSet missionCriticalObjs = new SWGSet<>(4, 13);
private SWGSet skills = new SWGSet(1, 3, StringType.ASCII);
private SWGList baseAttributes = new SWGList(1, 2);
- private SWGList hamEncumbList = new SWGList(4, 2);
- private SWGList attributes = new SWGList(6, 21);
- private SWGList maxAttributes = new SWGList(6, 22);
- private SWGList equipmentList = new SWGList(6, 23);
- private SWGList appearanceList = new SWGList(6, 33);
-
- private SWGMap skillMods = new SWGMap<>(4, 3, StringType.ASCII); // TODO: SkillMod structure
- private SWGMap abilities = new SWGMap<>(4, 14, StringType.ASCII);
- private SWGMap buffs = new SWGMap<>(6, 26);
public CreatureObject(long objectId) {
super(objectId, BaselineType.CREO);
- initMaxAttributes();
- initCurrentAttributes();
initBaseAttributes();
}
- private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
- ois.defaultReadObject();
- // Transient Variables
- inviterData = new GroupInviterData(0, null, "", 0);
- lastReserveOperation = 0;
- groupId = 0;
- }
-
@Override
public void addObject(SWGObject obj) {
super.addObject(obj);
@@ -177,52 +122,20 @@ public class CreatureObject extends TangibleObject {
}
}
- public void removeEquipment(SWGObject obj) {
- synchronized (equipmentList) {
- for (Equipment equipment : equipmentList) {
- if (equipment.getObjectId() == obj.getObjectId()) {
- equipmentList.remove(equipment);
- equipmentList.sendDeltaMessage(this);
- break;
- }
- }
- }
+ public void addEquipment(SWGObject obj) {
+ creo6.addEquipment(obj, this);
}
- public void addEquipment(SWGObject obj) {
- synchronized(equipmentList) {
- if (obj instanceof WeaponObject)
- equipmentList.add(new Equipment((WeaponObject) obj));
- else
- equipmentList.add(new Equipment(obj.getObjectId(), obj.getTemplate()));
- equipmentList.sendDeltaMessage(this);
- }
+ public void removeEquipment(SWGObject obj) {
+ creo6.removeEquipment(obj, this);
}
public void addAppearanceItem(SWGObject obj) {
- synchronized(appearanceList) {
- appearanceList.add(new Equipment(obj.getObjectId(), obj.getTemplate()));
- appearanceList.sendDeltaMessage(this);
- }
+ creo6.addAppearanceItem(obj, this);
}
public void removeAppearanceItem(SWGObject obj) {
- synchronized (appearanceList) {
- for (Equipment equipment : appearanceList) {
- if (equipment.getObjectId() == obj.getObjectId()) {
- appearanceList.remove(equipment);
- appearanceList.sendDeltaMessage(this);
- }
- }
- }
- }
-
- public SWGList getEquipmentList() {
- return equipmentList;
- }
-
- public SWGList getAppearanceList() {
- return appearanceList;
+ creo6.removeAppearanceItem(obj, this);
}
public void addSkill(String skillName) {
@@ -262,43 +175,43 @@ public class CreatureObject extends TangibleObject {
}
public double getMovementScale() {
- return movementScale;
+ return creo4.getMovementScale();
}
public double getMovementPercent() {
- return movementPercent;
+ return creo4.getMovementPercent();
}
public double getWalkSpeed() {
- return walkSpeed;
+ return creo4.getWalkSpeed();
}
public double getRunSpeed() {
- return runSpeed;
+ return creo4.getRunSpeed();
}
public double getAccelScale() {
- return accelScale;
+ return creo4.getAccelScale();
}
public double getAccelPercent() {
- return accelPercent;
+ return creo4.getAccelPercent();
}
public double getTurnScale() {
- return turnScale;
+ return creo4.getTurnScale();
}
public double getSlopeModAngle() {
- return slopeModAngle;
+ return creo4.getSlopeModAngle();
}
public double getSlopeModPercent() {
- return slopeModPercent;
+ return creo4.getSlopeModPercent();
}
public double getWaterModPercent() {
- return waterModPercent;
+ return creo4.getWaterModPercent();
}
public double getHeight() {
@@ -306,27 +219,27 @@ public class CreatureObject extends TangibleObject {
}
public long getPerformanceListenTarget() {
- return performanceListenTarget;
+ return creo4.getPerformanceListenTarget();
}
public int getGuildId() {
- return guildId;
+ return creo6.getGuildId();
}
public short getLevel() {
- return level;
+ return creo6.getLevel();
}
public int getLevelHealthGranted() {
- return levelHealthGranted;
+ return creo6.getLevelHealthGranted();
}
public int getTotalLevelXp() {
- return totalLevelXp;
+ return creo4.getTotalLevelXp();
}
public CreatureDifficulty getDifficulty() {
- return difficulty;
+ return creo6.getDifficulty();
}
public String getCurrentCity() {
@@ -427,52 +340,52 @@ public class CreatureObject extends TangibleObject {
}
public void setMovementScale(double movementScale) {
- this.movementScale = movementScale;
+ creo4.setMovementScale(movementScale);
sendDelta(4, 5, movementScale);
}
public void setMovementPercent(double movementPercent) {
- this.movementPercent = movementPercent;
+ creo4.setMovementPercent(movementPercent);
sendDelta(4, 4, movementPercent);
}
public void setWalkSpeed(double walkSpeed) {
- this.walkSpeed = walkSpeed;
+ creo4.setWalkSpeed(walkSpeed);
sendDelta(4, 11, walkSpeed);
}
public void setRunSpeed(double runSpeed) {
- this.runSpeed = runSpeed;
+ creo4.setRunSpeed(runSpeed);
sendDelta(4, 7, runSpeed);
}
public void setAccelScale(double accelScale) {
- this.accelScale = accelScale;
+ creo4.setAccelScale(accelScale);
sendDelta(4, 1, accelScale);
}
public void setAccelPercent(double accelPercent) {
- this.accelPercent = accelPercent;
+ creo4.setAccelPercent(accelPercent);
sendDelta(4, 0, accelPercent);
}
public void setTurnScale(double turnScale) {
- this.turnScale = turnScale;
+ creo4.setTurnScale(turnScale);
sendDelta(4, 10, turnScale);
}
public void setSlopeModAngle(double slopeModAngle) {
- this.slopeModAngle = slopeModAngle;
+ creo4.setSlopeModAngle(slopeModAngle);
sendDelta(4, 8, slopeModAngle);
}
public void setSlopeModPercent(double slopeModPercent) {
- this.slopeModPercent = slopeModPercent;
+ creo4.setSlopeModPercent(slopeModPercent);
sendDelta(4, 9, slopeModPercent);
}
public void setWaterModPercent(double waterModPercent) {
- this.waterModPercent = waterModPercent;
+ creo4.setWaterModPercent(waterModPercent);
sendDelta(4, 12, waterModPercent);
}
@@ -482,32 +395,32 @@ public class CreatureObject extends TangibleObject {
}
public void setPerformanceListenTarget(long performanceListenTarget) {
- this.performanceListenTarget = performanceListenTarget;
+ creo4.setPerformanceListenTarget(performanceListenTarget);
sendDelta(4, 6, performanceListenTarget);
}
public void setGuildId(int guildId) {
- this.guildId = guildId;
+ creo6.setGuildId(guildId);
sendDelta(6, 15, guildId);
}
public void setLevel(int level) {
- this.level = (short) level;
+ creo6.setLevel(level);
sendDelta(6, 8, (short) level);
}
public void setLevelHealthGranted(int levelHealthGranted) {
- this.levelHealthGranted = levelHealthGranted;
+ creo6.setLevelHealthGranted(levelHealthGranted);
sendDelta(6, 9, levelHealthGranted);
}
public void setTotalLevelXp(int totalLevelXp) {
- this.totalLevelXp = totalLevelXp;
+ creo4.setTotalLevelXp(totalLevelXp);
sendDelta(4, 15, totalLevelXp);
}
public void setDifficulty(CreatureDifficulty difficulty) {
- this.difficulty = difficulty;
+ creo6.setDifficulty(difficulty);
sendDelta(6, 26, difficulty.getDifficulty());
}
@@ -520,38 +433,38 @@ public class CreatureObject extends TangibleObject {
}
public String getMoodAnimation() {
- return moodAnimation;
+ return creo6.getMoodAnimation();
}
public void setMoodAnimation(String moodAnimation) {
- this.moodAnimation = moodAnimation;
+ creo6.setMoodAnimation(moodAnimation);
sendDelta(6, 11, moodAnimation, StringType.ASCII);
}
public boolean isBeast() {
- return beast;
+ return creo6.isBeast();
}
public void setBeast(boolean beast) {
- this.beast = beast;
+ creo6.setBeast(beast);
sendDelta(6, 31, beast);
}
public String getAnimation() {
- return animation;
+ return creo6.getAnimation();
}
public void setAnimation(String animation) {
- this.animation = animation;
+ creo6.setAnimation(animation);
sendDelta(6, 10, animation, StringType.ASCII);
}
public WeaponObject getEquippedWeapon() {
- return equippedWeapon;
+ return creo6.getEquippedWeapon();
}
public void setEquippedWeapon(WeaponObject weapon) {
- this.equippedWeapon = weapon;
+ creo6.setEquippedWeapon(weapon);
sendDelta(6, 12, weapon.getObjectId());
}
@@ -564,78 +477,74 @@ public class CreatureObject extends TangibleObject {
}
public byte getMoodId() {
- return moodId;
+ return creo6.getMoodId();
}
public void setMoodId(byte moodId) {
- this.moodId = moodId;
+ creo6.setMoodId(moodId);
sendDelta(6, 18, moodId);
}
public long getLookAtTargetId() {
- return lookAtTargetId;
+ return creo6.getLookAtTargetId();
}
public void setLookAtTargetId(long lookAtTargetId) {
- this.lookAtTargetId = lookAtTargetId;
+ creo6.setLookAtTargetId(lookAtTargetId);
sendDelta(6, 16, lookAtTargetId);
}
public long getIntendedTargetId() {
- return intendedTargetId;
+ return creo6.getIntendedTargetId();
}
public void setIntendedTargetId(long intendedTargetId) {
- this.intendedTargetId = intendedTargetId;
+ creo6.setIntendedTargetId(intendedTargetId);
sendDelta(6, 17, intendedTargetId);
}
public int getPerformanceCounter() {
- return performanceCounter;
+ return creo6.getPerformanceCounter();
}
public void setPerformanceCounter(int performanceCounter) {
- this.performanceCounter = performanceCounter;
+ creo6.setPerformanceCounter(performanceCounter);
sendDelta(6, 19, performanceCounter);
}
public int getPerformanceId() {
- return performanceId;
+ return creo6.getPerformanceId();
}
public void setPerformanceId(int performanceId) {
- this.performanceId = performanceId;
+ creo6.setPerformanceId(performanceId);
sendDelta(6, 20, performanceId);
}
public String getCostume() {
- return costume;
+ return creo6.getCostume();
}
public void setCostume(String costume) {
- this.costume = costume;
+ creo6.setCostume(costume);
sendDelta(6, 24, costume, StringType.ASCII);
}
public long getGroupId() {
- return groupId;
+ return creo6.getGroupId();
}
public void updateGroupInviteData(Player sender, long groupId, String name) {
- inviterData.setName(name);
- inviterData.setSender(sender);
- inviterData.setId(groupId);
- inviterData.incrementCounter();
-
- sendDelta(6, 14, inviterData);
+ creo6.updateGroupInviteData(sender, groupId, name);
+ sendDelta(6, 14, creo6.getInviterData());
}
public GroupInviterData getInviterData() {
- return inviterData;
+ return creo6.getInviterData();
}
public void setGroupId(long groupId) {
- this.groupId = groupId;
+ creo6.setGroupId(groupId);
sendDelta(6, 13, groupId);
}
@@ -694,73 +603,51 @@ public class CreatureObject extends TangibleObject {
}
public void adjustSkillmod(String skillModName, int base, int modifier) {
- synchronized(skillMods) {
- SkillMod skillMod = skillMods.get(skillModName);
-
- if(skillMod == null) {
- // They didn't have this SkillMod already.
- // Therefore, we send a full delta.
- skillMods.put(skillModName, new SkillMod(base, modifier));
- skillMods.sendDeltaMessage(this);
- } else {
- // They already had this skillmod.
- // All we need to do is adjust the base and the modifier and send an update from the SWGMap
- skillMod.adjustBase(base);
- skillMod.adjustModifier(modifier);
- skillMods.update(skillModName, this);
- }
- }
+ creo4.adjustSkillmod(skillModName, base, modifier, this);
}
public int getSkillModValue(String skillModName) {
- synchronized(skillMods) {
- SkillMod skillMod = skillMods.get(skillModName);
- return skillMod != null ? skillMod.getValue() : 0;
- }
+ return creo4.getSkillModValue(skillModName);
}
public boolean isVisible() {
- return visible;
+ return creo6.isVisible();
}
public void setVisible(boolean visible) {
- this.visible = visible;
+ creo6.setVisible(visible);
sendDelta(6, 25, visible);
}
public boolean isPerforming() {
- return performing;
+ return creo6.isPerforming();
}
public void setPerforming(boolean performing) {
- this.performing = performing;
+ creo6.setPerforming(performing);
sendDelta(6, 27, performing);
}
public void setHologramColour(HologramColour hologramColour) {
- this.hologramColour = hologramColour;
+ creo6.setHologramColour(hologramColour);
sendDelta(6, 29, hologramColour.getValue());
}
public boolean isShownOnRadar() {
- return shownOnRadar;
+ return creo6.isShownOnRadar();
}
public void setShownOnRadar(boolean shownOnRadar) {
- this.shownOnRadar = shownOnRadar;
+ creo6.setShownOnRadar(shownOnRadar);
sendDelta(6, 30, shownOnRadar);
}
public int getHealth() {
- synchronized (attributes) {
- return attributes.get(0);
- }
+ return creo6.getHealth();
}
public int getMaxHealth() {
- synchronized (maxAttributes) {
- return maxAttributes.get(0);
- }
+ return creo6.getMaxHealth();
}
public int getBaseHealth() {
@@ -770,15 +657,11 @@ public class CreatureObject extends TangibleObject {
}
public int getAction() {
- synchronized (attributes) {
- return attributes.get(2);
- }
+ return creo6.getAction();
}
public int getMaxAction() {
- synchronized (maxAttributes) {
- return maxAttributes.get(2);
- }
+ return creo6.getMaxAction();
}
public int getBaseAction() {
@@ -788,15 +671,11 @@ public class CreatureObject extends TangibleObject {
}
public int getMind() {
- synchronized (attributes) {
- return attributes.get(4);
- }
+ return creo6.getMind();
}
public int getMaxMind() {
- synchronized (maxAttributes) {
- return maxAttributes.get(4);
- }
+ return creo6.getMaxMind();
}
public int getBaseMind() {
@@ -805,19 +684,22 @@ public class CreatureObject extends TangibleObject {
}
}
- public void addAbility(String abilityName){
- synchronized(abilities) {
- abilities.put(abilityName, 1); //TODO: Figure out what the integer value should be for each ability
- abilities.sendDeltaMessage(this);
- }
+ public void addAbility(String abilityName) {
+ creo4.addAbility(abilityName, this);
+ }
+
+ public void removeAbility(String abilityName) {
+ creo4.removeAbility(abilityName);
+ }
+
+ public boolean hasAbility(String abilityName) {
+ return creo4.hasAbility(abilityName);
+ }
+
+ public Set getAbilityNames() {
+ return creo4.getAbilityNames();
}
- public void removeAbility(String abilityName) { abilities.remove(abilityName); }
-
- public boolean hasAbility(String abilityName) { return abilities.get(abilityName) != null; }
-
- public Set getAbilityNames() { return abilities.keySet(); };
-
public void setBaseHealth(int baseHealth) {
synchronized(baseAttributes) {
baseAttributes.set(0, baseHealth);
@@ -826,24 +708,15 @@ public class CreatureObject extends TangibleObject {
}
public void setHealth(int health) {
- synchronized(attributes) {
- attributes.set(0, health);
- attributes.sendDeltaMessage(this);
- }
+ creo6.setHealth(health, this);
}
public void modifyHealth(int mod) {
- synchronized(attributes) {
- attributes.set(0, getHealth() + mod);
- attributes.sendDeltaMessage(this);
- }
+ creo6.modifyHealth(mod, this);
}
public void setMaxHealth(int maxHealth) {
- synchronized(maxAttributes) {
- maxAttributes.set(0, maxHealth);
- maxAttributes.sendDeltaMessage(this);
- }
+ creo6.setMaxHealth(maxHealth, this);
}
public void setBaseAction(int baseAction) {
@@ -854,65 +727,27 @@ public class CreatureObject extends TangibleObject {
}
public void setAction(int action) {
- synchronized(attributes) {
- attributes.set(2, action);
- attributes.sendDeltaMessage(this);
- }
+ creo6.setAction(action, this);
}
public void modifyAction(int mod) {
- synchronized(attributes) {
- attributes.set(2, getAction() + mod);
- attributes.sendDeltaMessage(this);
- }
+ creo6.modifyAction(mod, this);
}
public void setMaxAction(int maxAction) {
- synchronized(maxAttributes) {
- maxAttributes.set(2, maxAction);
- maxAttributes.sendDeltaMessage(this);
- }
+ creo6.setMaxAction(maxAction, this);
}
public void setMind(int mind) {
- synchronized(attributes) {
- attributes.set(4, mind);
- attributes.sendDeltaMessage(this);
- }
+ creo6.setMind(mind, this);
}
public void modifyMind(int mod) {
- synchronized(attributes) {
- attributes.set(4, getMind() + mod);
- attributes.sendDeltaMessage(this);
- }
+ creo6.modifyMind(mod, this);
}
public void setMaxMind(int maxMind) {
- synchronized(maxAttributes) {
- maxAttributes.set(4, maxMind);
- maxAttributes.sendDeltaMessage(this);
- }
- }
-
- private void initMaxAttributes() {
- maxAttributes.add(0, 1000); // Health
- maxAttributes.add(1, 0);
- maxAttributes.add(2, 300); // Action
- maxAttributes.add(3, 0);
- maxAttributes.add(4, 300); // Mind
- maxAttributes.add(5, 0);
- maxAttributes.clearDeltaQueue();
- }
-
- private void initCurrentAttributes() {
- attributes.add(0, 1000); // Health
- attributes.add(1, 0);
- attributes.add(2, 300); // Action
- attributes.add(3, 0);
- attributes.add(4, 300); // Mind
- attributes.add(5, 0);
- attributes.clearDeltaQueue();
+ creo6.setMaxMind(maxMind, this);
}
private void initBaseAttributes() {
@@ -1016,59 +851,14 @@ public class CreatureObject extends TangibleObject {
super.createBaseline4(target, bb); // 0 variables
if (getStringId().toString().equals("@obj_n:unknown_object"))
return;
- bb.addFloat((float) accelPercent); // 0
- bb.addFloat((float) accelScale); // 1
- bb.addObject(hamEncumbList); // Rename to bonusAttributes? 2
- bb.addObject(skillMods); // 3
- bb.addFloat((float) movementPercent); // 4
- bb.addFloat((float) movementScale); // 5
- bb.addLong(performanceListenTarget); // 6
- bb.addFloat((float) runSpeed); // 7
- bb.addFloat((float) slopeModAngle); // 8
- bb.addFloat((float) slopeModPercent); // 9
- bb.addFloat((float) turnScale); // 10
- bb.addFloat((float) walkSpeed); // 11
- bb.addFloat((float) waterModPercent); // 12
- bb.addObject(missionCriticalObjs); // Group Missions? 13
- bb.addObject(abilities); // 14
- bb.addInt(totalLevelXp); // 15
-
- bb.incrementOperandCount(16);
+ creo4.createBaseline4(target, bb);
}
public void createBaseline6(Player target, BaselineBuilder bb) {
super.createBaseline6(target, bb); // 8 variables - TANO6 (6) + BASE6 (2)
if (getStringId().toString().equals("@obj_n:unknown_object"))
return;
- bb.addShort(level); // 8
- bb.addInt(levelHealthGranted); // 9
- bb.addAscii(animation); // 10
- bb.addAscii(moodAnimation); // 11
- bb.addLong(equippedWeapon == null ? 0 : equippedWeapon.getObjectId()); // 12
- bb.addLong(groupId); // 13
- bb.addObject(inviterData); // TODO: Check structure -- 14
- bb.addInt(guildId); // 15
- bb.addLong(lookAtTargetId); // 16
- bb.addLong(intendedTargetId); // 17
- bb.addByte(moodId); // 18
- bb.addInt(performanceCounter); // 19
- bb.addInt(performanceId); // 20
- bb.addObject(attributes); // 21
- bb.addObject(maxAttributes); // 22
- bb.addObject(equipmentList); // 23
- bb.addAscii(costume); // 24
- bb.addBoolean(visible); // 25
- bb.addObject(buffs); // 26
- bb.addBoolean(performing); // 27
- bb.addByte(difficulty.getDifficulty()); // 28
- bb.addInt((hologramColour == null) ? -1 : hologramColour.getValue()); // Hologram Color -- 29
- bb.addBoolean(shownOnRadar); // 30
- bb.addBoolean(beast); // 31
- bb.addByte(0); // forceShowHam? -- 32
- bb.addObject(appearanceList); // 33
- bb.addLong(0); // decoy? -- 34
-
- bb.incrementOperandCount(27);
+ creo6.createBaseline6(target, bb);
}
protected void parseBaseline1(NetBuffer buffer) {
@@ -1097,62 +887,63 @@ public class CreatureObject extends TangibleObject {
super.parseBaseline4(buffer);
if (getStringId().toString().equals("@obj_n:unknown_object"))
return;
- accelPercent = buffer.getFloat();
- accelScale = buffer.getFloat();
- hamEncumbList = buffer.getSwgList(4, 2, Integer.class);
- skillMods = buffer.getSwgMap(4, 3, StringType.ASCII, SkillMod.class);
- movementPercent = buffer.getFloat();
- movementScale = buffer.getFloat();
- performanceListenTarget = buffer.getLong();
- runSpeed = buffer.getFloat();
- slopeModAngle = buffer.getFloat();
- slopeModPercent = buffer.getFloat();
- turnScale = buffer.getFloat();
- walkSpeed = buffer.getFloat();
- waterModPercent = buffer.getFloat();
- missionCriticalObjs = buffer.getSwgSet(4, 13, StringType.ASCII);
- abilities = buffer.getSwgMap(4, 14, StringType.ASCII, Integer.class);
- totalLevelXp = buffer.getInt();
+ creo4.parseBaseline4(buffer);
}
protected void parseBaseline6(NetBuffer buffer) {
super.parseBaseline6(buffer);
if (getStringId().toString().equals("@obj_n:unknown_object"))
return;
- level = buffer.getShort();
- levelHealthGranted = buffer.getInt();
- animation = buffer.getAscii();
- moodAnimation = buffer.getAscii();
- long weaponId = buffer.getLong();
- groupId = buffer.getLong();
- inviterData = buffer.getEncodable(GroupInviterData.class);
- guildId = buffer.getInt();
- lookAtTargetId = buffer.getLong();
- intendedTargetId = buffer.getLong();
- moodId = buffer.getByte();
- performanceCounter = buffer.getInt();
- performanceId = buffer.getInt();
- attributes = buffer.getSwgList(6, 21, Integer.class);
- maxAttributes = buffer.getSwgList(6, 22, Integer.class);
- equipmentList = buffer.getSwgList(6, 23, Equipment.class);
- costume = buffer.getAscii();
- visible = buffer.getBoolean();
- buffs = buffer.getSwgMap(6, 26, CRC.class, Buff.class);
- performing = buffer.getBoolean();
- difficulty = CreatureDifficulty.getForDifficulty(buffer.getByte());
- hologramColour = HologramColour.getForValue(buffer.getInt());
- shownOnRadar = buffer.getBoolean();
- beast = buffer.getBoolean();
- buffer.getBoolean();
- appearanceList = buffer.getSwgList(6, 33, Equipment.class);
- buffer.getLong();
- equippedWeapon = null;
- for (Equipment e : equipmentList) {
- if (e.getObjectId() == weaponId && e.getWeapon() instanceof WeaponObject) {
- equippedWeapon = (WeaponObject) e.getWeapon();
- break;
- }
+ creo6.parseBaseline6(buffer);
+ }
+
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ creo4.save(stream);
+ creo6.save(stream);
+ stream.addAscii(posture.name());
+ stream.addAscii(race.name());
+ stream.addFloat((float) height);
+ stream.addInt(battleFatigue);
+ stream.addInt(cashBalance);
+ stream.addInt(bankBalance);
+ stream.addLong(reserveBalance);
+ stream.addLong(ownerId);
+ stream.addLong(statesBitmask);
+ stream.addByte(factionRank);
+ stream.addBoolean(defaultWeapon != null);
+ if (defaultWeapon != null)
+ SWGObjectFactory.save(defaultWeapon, stream);
+ synchronized (skills) {
+ stream.addList(skills, (s) -> stream.addAscii(s));
+ }
+ synchronized (baseAttributes) {
+ stream.addList(baseAttributes, (s) -> stream.addInt(s));
}
}
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ creo4.read(stream);
+ creo6.read(stream);
+ posture = Posture.valueOf(stream.getAscii());
+ race = Race.valueOf(stream.getAscii());
+ height = stream.getFloat();
+ battleFatigue = stream.getInt();
+ cashBalance = stream.getInt();
+ bankBalance = stream.getInt();
+ reserveBalance = stream.getLong();
+ ownerId = stream.getLong();
+ statesBitmask = stream.getLong();
+ factionRank = stream.getByte();
+ if (stream.getBoolean())
+ defaultWeapon = (WeaponObject) SWGObjectFactory.create(stream);
+ stream.getList((i) -> skills.add(stream.getAscii()));
+ stream.getList((i) -> baseAttributes.set(i, stream.getInt()));
+ }
+
}
diff --git a/src/resources/objects/creature/CreatureObjectClientServerNP.java b/src/resources/objects/creature/CreatureObjectClientServerNP.java
new file mode 100644
index 000000000..5c3020b7a
--- /dev/null
+++ b/src/resources/objects/creature/CreatureObjectClientServerNP.java
@@ -0,0 +1,323 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.objects.creature;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import resources.SkillMod;
+import resources.collections.SWGList;
+import resources.collections.SWGMap;
+import resources.collections.SWGSet;
+import resources.network.BaselineBuilder;
+import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
+import resources.objects.SWGObject;
+import resources.persistable.Persistable;
+import resources.player.Player;
+import utilities.Encoder.StringType;
+
+class CreatureObjectClientServerNP implements Persistable {
+
+ private double movementScale = 1;
+ private double movementPercent = 1;
+ private double walkSpeed = 1.549;
+ private double runSpeed = 7.3;
+ private double accelScale = 1;
+ private double accelPercent = 1;
+ private double turnScale = 1;
+ private double slopeModAngle = 1;
+ private double slopeModPercent = 1;
+ private double waterModPercent = 0.75;
+ private long performanceListenTarget = 0;
+ private int totalLevelXp = 0;
+
+ private SWGSet missionCriticalObjs = new SWGSet<>(4, 13);
+
+ private SWGList hamEncumbList = new SWGList(4, 2);
+
+ private SWGMap skillMods = new SWGMap<>(4, 3, StringType.ASCII);
+ private SWGMap abilities = new SWGMap<>(4, 14, StringType.ASCII);
+
+ public CreatureObjectClientServerNP() {
+
+ }
+
+ public void setMovementScale(double movementScale) {
+ this.movementScale = movementScale;
+ }
+
+ public void setMovementPercent(double movementPercent) {
+ this.movementPercent = movementPercent;
+ }
+
+ public void setWalkSpeed(double walkSpeed) {
+ this.walkSpeed = walkSpeed;
+ }
+
+ public void setRunSpeed(double runSpeed) {
+ this.runSpeed = runSpeed;
+ }
+
+ public void setAccelScale(double accelScale) {
+ this.accelScale = accelScale;
+ }
+
+ public void setAccelPercent(double accelPercent) {
+ this.accelPercent = accelPercent;
+ }
+
+ public void setTurnScale(double turnScale) {
+ this.turnScale = turnScale;
+ }
+
+ public void setSlopeModAngle(double slopeModAngle) {
+ this.slopeModAngle = slopeModAngle;
+ }
+
+ public void setSlopeModPercent(double slopeModPercent) {
+ this.slopeModPercent = slopeModPercent;
+ }
+
+ public void setWaterModPercent(double waterModPercent) {
+ this.waterModPercent = waterModPercent;
+ }
+
+ public void setPerformanceListenTarget(long performanceListenTarget) {
+ this.performanceListenTarget = performanceListenTarget;
+ }
+
+ public void setTotalLevelXp(int totalLevelXp) {
+ this.totalLevelXp = totalLevelXp;
+ }
+
+ public double getMovementScale() {
+ return movementScale;
+ }
+
+ public double getMovementPercent() {
+ return movementPercent;
+ }
+
+ public double getWalkSpeed() {
+ return walkSpeed;
+ }
+
+ public double getRunSpeed() {
+ return runSpeed;
+ }
+
+ public double getAccelScale() {
+ return accelScale;
+ }
+
+ public double getAccelPercent() {
+ return accelPercent;
+ }
+
+ public double getTurnScale() {
+ return turnScale;
+ }
+
+ public double getSlopeModAngle() {
+ return slopeModAngle;
+ }
+
+ public double getSlopeModPercent() {
+ return slopeModPercent;
+ }
+
+ public double getWaterModPercent() {
+ return waterModPercent;
+ }
+
+ public long getPerformanceListenTarget() {
+ return performanceListenTarget;
+ }
+
+ public int getTotalLevelXp() {
+ return totalLevelXp;
+ }
+
+ public void adjustSkillmod(String skillModName, int base, int modifier, SWGObject target) {
+ synchronized (skillMods) {
+ SkillMod skillMod = skillMods.get(skillModName);
+
+ if (skillMod == null) {
+ // They didn't have this SkillMod already.
+ // Therefore, we send a full delta.
+ skillMods.put(skillModName, new SkillMod(base, modifier));
+ skillMods.sendDeltaMessage(target);
+ } else {
+ // They already had this skillmod.
+ // All we need to do is adjust the base and the modifier and send an update from the
+// SWGMap
+ skillMod.adjustBase(base);
+ skillMod.adjustModifier(modifier);
+ skillMods.update(skillModName, target);
+ }
+ }
+ }
+
+ public int getSkillModValue(String skillModName) {
+ synchronized (skillMods) {
+ SkillMod skillMod = skillMods.get(skillModName);
+ return skillMod != null ? skillMod.getValue() : 0;
+ }
+ }
+
+ public void addAbility(String abilityName, SWGObject target) {
+ synchronized (abilities) {
+ if (abilities.containsKey(abilityName))
+ abilities.put(abilityName, abilities.get(abilityName) + 1);
+ else
+ abilities.put(abilityName, 1);
+ abilities.sendDeltaMessage(target);
+ }
+ }
+
+ public void removeAbility(String abilityName) {
+ synchronized (abilities) {
+ Integer i = abilities.remove(abilityName);
+ if (i != null && i > 1)
+ abilities.put(abilityName, i-1);
+ }
+ }
+
+ public boolean hasAbility(String abilityName) {
+ synchronized (abilities) {
+ return abilities.containsKey(abilityName);
+ }
+ }
+
+ public Set getAbilityNames() {
+ synchronized (abilities) {
+ return new HashSet<>(abilities.keySet());
+ }
+ };
+
+ public void createBaseline4(Player target, BaselineBuilder bb) {
+ bb.addFloat((float) accelPercent); // 0
+ bb.addFloat((float) accelScale); // 1
+ bb.addObject(hamEncumbList); // Rename to bonusAttributes? 2
+ bb.addObject(skillMods); // 3
+ bb.addFloat((float) movementPercent); // 4
+ bb.addFloat((float) movementScale); // 5
+ bb.addLong(performanceListenTarget); // 6
+ bb.addFloat((float) runSpeed); // 7
+ bb.addFloat((float) slopeModAngle); // 8
+ bb.addFloat((float) slopeModPercent); // 9
+ bb.addFloat((float) turnScale); // 10
+ bb.addFloat((float) walkSpeed); // 11
+ bb.addFloat((float) waterModPercent); // 12
+ bb.addObject(missionCriticalObjs); // Group Missions? 13
+ bb.addObject(abilities); // 14
+ bb.addInt(totalLevelXp); // 15
+
+ bb.incrementOperandCount(16);
+ }
+
+ public void parseBaseline4(NetBuffer buffer) {
+ accelPercent = buffer.getFloat();
+ accelScale = buffer.getFloat();
+ hamEncumbList = buffer.getSwgList(4, 2, Integer.class);
+ skillMods = buffer.getSwgMap(4, 3, StringType.ASCII, SkillMod.class);
+ movementPercent = buffer.getFloat();
+ movementScale = buffer.getFloat();
+ performanceListenTarget = buffer.getLong();
+ runSpeed = buffer.getFloat();
+ slopeModAngle = buffer.getFloat();
+ slopeModPercent = buffer.getFloat();
+ turnScale = buffer.getFloat();
+ walkSpeed = buffer.getFloat();
+ waterModPercent = buffer.getFloat();
+ missionCriticalObjs = buffer.getSwgSet(4, 13, StringType.ASCII);
+ abilities = buffer.getSwgMap(4, 14, StringType.ASCII, Integer.class);
+ totalLevelXp = buffer.getInt();
+ }
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ stream.addFloat((float) accelPercent);
+ stream.addFloat((float) accelScale);
+ stream.addFloat((float) movementPercent);
+ stream.addFloat((float) movementScale);
+ stream.addFloat((float) runSpeed);
+ stream.addFloat((float) slopeModAngle);
+ stream.addFloat((float) slopeModPercent);
+ stream.addFloat((float) turnScale);
+ stream.addFloat((float) walkSpeed);
+ stream.addFloat((float) waterModPercent);
+ stream.addInt(totalLevelXp);
+ synchronized (hamEncumbList) {
+ stream.addList(hamEncumbList, (i) -> stream.addInt(i));
+ }
+ synchronized (skillMods) {
+ stream.addMap(skillMods, (e) -> {
+ stream.addAscii(e.getKey());
+ e.getValue().save(stream);
+ });
+ }
+ synchronized (missionCriticalObjs) {
+ stream.addList(missionCriticalObjs, (s) -> stream.addAscii(s));
+ }
+ synchronized (abilities) {
+ stream.addMap(abilities, (e) -> {
+ stream.addAscii(e.getKey());
+ stream.addInt(e.getValue());
+ });
+ }
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ accelPercent = stream.getFloat();
+ accelScale = stream.getFloat();
+ movementPercent = stream.getFloat();
+ movementScale = stream.getFloat();
+ runSpeed = stream.getFloat();
+ slopeModAngle = stream.getFloat();
+ slopeModPercent = stream.getFloat();
+ turnScale = stream.getFloat();
+ walkSpeed = stream.getFloat();
+ waterModPercent = stream.getFloat();
+ totalLevelXp = stream.getInt();
+ stream.getList((i) -> hamEncumbList.add(stream.getInt()));
+ stream.getList((i) -> {
+ SkillMod mod = new SkillMod();
+ String key = stream.getAscii();
+ mod.read(stream);
+ skillMods.put(key, mod);
+ });
+ stream.getList((i) -> missionCriticalObjs.add(stream.getAscii()));
+ stream.getList((i) -> abilities.put(stream.getAscii(), stream.getInt()));
+ }
+
+}
diff --git a/src/resources/objects/creature/CreatureObjectSharedNP.java b/src/resources/objects/creature/CreatureObjectSharedNP.java
new file mode 100644
index 000000000..8b7a59170
--- /dev/null
+++ b/src/resources/objects/creature/CreatureObjectSharedNP.java
@@ -0,0 +1,528 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.objects.creature;
+
+import resources.HologramColour;
+import resources.collections.SWGList;
+import resources.collections.SWGMap;
+import resources.common.CRC;
+import resources.encodables.player.Equipment;
+import resources.network.BaselineBuilder;
+import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
+import resources.objects.SWGObject;
+import resources.objects.weapon.WeaponObject;
+import resources.persistable.Persistable;
+import resources.persistable.SWGObjectFactory;
+import resources.player.Player;
+import services.group.GroupInviterData;
+
+class CreatureObjectSharedNP implements Persistable {
+
+ private transient GroupInviterData inviterData = new GroupInviterData(0, null, "", 0);
+ private transient long groupId = 0;
+
+ private short level = 1;
+ private int levelHealthGranted = 0;
+ private String animation = "";
+ private String moodAnimation = "neutral";
+ private WeaponObject equippedWeapon = null;
+ private int guildId = 0;
+ private long lookAtTargetId = 0;
+ private long intendedTargetId = 0;
+ private byte moodId = 0;
+ private int performanceCounter = 0;
+ private int performanceId = 0;
+ private String costume = "";
+ private boolean visible = true;
+ private boolean performing = false;
+ private CreatureDifficulty difficulty = CreatureDifficulty.NORMAL;
+ private HologramColour hologramColour = HologramColour.DEFAULT;
+ private boolean shownOnRadar = true;
+ private boolean beast = false;
+
+ private SWGList attributes = new SWGList(6, 21);
+ private SWGList maxAttributes = new SWGList(6, 22);
+ private SWGList equipmentList = new SWGList(6, 23);
+ private SWGList appearanceList = new SWGList(6, 33);
+
+ private SWGMap buffs = new SWGMap<>(6, 26);
+
+ public CreatureObjectSharedNP() {
+ initCurrentAttributes();
+ initMaxAttributes();
+ }
+
+ public void addEquipment(SWGObject obj, SWGObject target) {
+ synchronized (equipmentList) {
+ if (obj instanceof WeaponObject)
+ equipmentList.add(new Equipment((WeaponObject) obj));
+ else
+ equipmentList.add(new Equipment(obj.getObjectId(), obj.getTemplate()));
+ equipmentList.sendDeltaMessage(target);
+ }
+ }
+
+ public void removeEquipment(SWGObject obj, SWGObject target) {
+ synchronized (equipmentList) {
+ for (Equipment equipment : equipmentList) {
+ if (equipment.getObjectId() == obj.getObjectId()) {
+ equipmentList.remove(equipment);
+ equipmentList.sendDeltaMessage(target);
+ return;
+ }
+ }
+ }
+ }
+
+ public void addAppearanceItem(SWGObject obj, SWGObject target) {
+ synchronized (appearanceList) {
+ appearanceList.add(new Equipment(obj.getObjectId(), obj.getTemplate()));
+ appearanceList.sendDeltaMessage(target);
+ }
+ }
+
+ public void removeAppearanceItem(SWGObject obj, SWGObject target) {
+ synchronized (appearanceList) {
+ for (Equipment equipment : appearanceList) {
+ if (equipment.getObjectId() == obj.getObjectId()) {
+ appearanceList.remove(equipment);
+ appearanceList.sendDeltaMessage(target);
+ return;
+ }
+ }
+ }
+ }
+
+ public SWGList getEquipmentList() {
+ return equipmentList;
+ }
+
+ public SWGList getAppearanceList() {
+ return appearanceList;
+ }
+
+ public void setGuildId(int guildId) {
+ this.guildId = guildId;
+ }
+
+ public void setLevel(int level) {
+ this.level = (short) level;
+ }
+
+ public void setLevelHealthGranted(int levelHealthGranted) {
+ this.levelHealthGranted = levelHealthGranted;
+ }
+
+ public void setDifficulty(CreatureDifficulty difficulty) {
+ this.difficulty = difficulty;
+ }
+
+ public void setMoodAnimation(String moodAnimation) {
+ this.moodAnimation = moodAnimation;
+ }
+
+ public void setBeast(boolean beast) {
+ this.beast = beast;
+ }
+
+ public void setEquippedWeapon(WeaponObject weapon) {
+ this.equippedWeapon = weapon;
+ }
+
+ public void setMoodId(byte moodId) {
+ this.moodId = moodId;
+ }
+
+ public void setLookAtTargetId(long lookAtTargetId) {
+ this.lookAtTargetId = lookAtTargetId;
+ }
+
+ public void setIntendedTargetId(long intendedTargetId) {
+ this.intendedTargetId = intendedTargetId;
+ }
+
+ public void setPerformanceCounter(int performanceCounter) {
+ this.performanceCounter = performanceCounter;
+ }
+
+ public void setPerformanceId(int performanceId) {
+ this.performanceId = performanceId;
+ }
+
+ public int getGuildId() {
+ return guildId;
+ }
+
+ public short getLevel() {
+ return level;
+ }
+
+ public int getLevelHealthGranted() {
+ return levelHealthGranted;
+ }
+
+ public CreatureDifficulty getDifficulty() {
+ return difficulty;
+ }
+
+ public String getCostume() {
+ return costume;
+ }
+
+ public void setCostume(String costume) {
+ this.costume = costume;
+ }
+
+ public void updateGroupInviteData(Player sender, long groupId, String name) {
+ inviterData.setName(name);
+ inviterData.setSender(sender);
+ inviterData.setId(groupId);
+ inviterData.incrementCounter();
+ }
+
+ public long getGroupId() {
+ return groupId;
+ }
+
+ public GroupInviterData getInviterData() {
+ return inviterData;
+ }
+
+ public void setGroupId(long groupId) {
+ this.groupId = groupId;
+ }
+
+ public String getAnimation() {
+ return animation;
+ }
+
+ public byte getMoodId() {
+ return moodId;
+ }
+
+ public long getLookAtTargetId() {
+ return lookAtTargetId;
+ }
+
+ public long getIntendedTargetId() {
+ return intendedTargetId;
+ }
+
+ public int getPerformanceCounter() {
+ return performanceCounter;
+ }
+
+ public int getPerformanceId() {
+ return performanceId;
+ }
+
+ public void setAnimation(String animation) {
+ this.animation = animation;
+ }
+
+ public String getMoodAnimation() {
+ return moodAnimation;
+ }
+
+ public boolean isBeast() {
+ return beast;
+ }
+
+ public WeaponObject getEquippedWeapon() {
+ return equippedWeapon;
+ }
+
+ public boolean isVisible() {
+ return visible;
+ }
+
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ }
+
+ public boolean isPerforming() {
+ return performing;
+ }
+
+ public void setPerforming(boolean performing) {
+ this.performing = performing;
+ }
+
+ public void setHologramColour(HologramColour hologramColour) {
+ this.hologramColour = hologramColour;
+ }
+
+ public boolean isShownOnRadar() {
+ return shownOnRadar;
+ }
+
+ public void setShownOnRadar(boolean shownOnRadar) {
+ this.shownOnRadar = shownOnRadar;
+ }
+
+ public int getHealth() {
+ synchronized (attributes) {
+ return attributes.get(0);
+ }
+ }
+
+ public int getMaxHealth() {
+ synchronized (maxAttributes) {
+ return maxAttributes.get(0);
+ }
+ }
+
+ public int getAction() {
+ synchronized (attributes) {
+ return attributes.get(2);
+ }
+ }
+
+ public int getMaxAction() {
+ synchronized (maxAttributes) {
+ return maxAttributes.get(2);
+ }
+ }
+
+ public int getMind() {
+ synchronized (attributes) {
+ return attributes.get(4);
+ }
+ }
+
+ public int getMaxMind() {
+ synchronized (maxAttributes) {
+ return maxAttributes.get(4);
+ }
+ }
+
+ public void setHealth(int health, SWGObject target) {
+ synchronized(attributes) {
+ attributes.set(0, health);
+ attributes.sendDeltaMessage(target);
+ }
+ }
+
+ public void modifyHealth(int mod, SWGObject target) {
+ synchronized(attributes) {
+ attributes.set(0, getHealth() + mod);
+ attributes.sendDeltaMessage(target);
+ }
+ }
+
+ public void setMaxHealth(int maxHealth, SWGObject target) {
+ synchronized(maxAttributes) {
+ maxAttributes.set(0, maxHealth);
+ maxAttributes.sendDeltaMessage(target);
+ }
+ }
+
+ public void setAction(int action, SWGObject target) {
+ synchronized(attributes) {
+ attributes.set(2, action);
+ attributes.sendDeltaMessage(target);
+ }
+ }
+
+ public void modifyAction(int mod, SWGObject target) {
+ synchronized(attributes) {
+ attributes.set(2, getAction() + mod);
+ attributes.sendDeltaMessage(target);
+ }
+ }
+
+ public void setMaxAction(int maxAction, SWGObject target) {
+ synchronized(maxAttributes) {
+ maxAttributes.set(2, maxAction);
+ maxAttributes.sendDeltaMessage(target);
+ }
+ }
+
+ public void setMind(int mind, SWGObject target) {
+ synchronized(attributes) {
+ attributes.set(4, mind);
+ attributes.sendDeltaMessage(target);
+ }
+ }
+
+ public void modifyMind(int mod, SWGObject target) {
+ synchronized(attributes) {
+ attributes.set(4, getMind() + mod);
+ attributes.sendDeltaMessage(target);
+ }
+ }
+
+ public void setMaxMind(int maxMind, SWGObject target) {
+ synchronized(maxAttributes) {
+ maxAttributes.set(4, maxMind);
+ maxAttributes.sendDeltaMessage(target);
+ }
+ }
+
+ private void initMaxAttributes() {
+ maxAttributes.add(0, 1000); // Health
+ maxAttributes.add(1, 0);
+ maxAttributes.add(2, 300); // Action
+ maxAttributes.add(3, 0);
+ maxAttributes.add(4, 300); // Mind
+ maxAttributes.add(5, 0);
+ maxAttributes.clearDeltaQueue();
+ }
+
+ private void initCurrentAttributes() {
+ attributes.add(0, 1000); // Health
+ attributes.add(1, 0);
+ attributes.add(2, 300); // Action
+ attributes.add(3, 0);
+ attributes.add(4, 300); // Mind
+ attributes.add(5, 0);
+ attributes.clearDeltaQueue();
+ }
+
+ public void createBaseline6(Player target, BaselineBuilder bb) {
+ bb.addShort(level); // 8
+ bb.addInt(levelHealthGranted); // 9
+ bb.addAscii(animation); // 10
+ bb.addAscii(moodAnimation); // 11
+ bb.addLong(equippedWeapon == null ? 0 : equippedWeapon.getObjectId()); // 12
+ bb.addLong(groupId); // 13
+ bb.addObject(inviterData); // 14
+ bb.addInt(guildId); // 15
+ bb.addLong(lookAtTargetId); // 16
+ bb.addLong(intendedTargetId); // 17
+ bb.addByte(moodId); // 18
+ bb.addInt(performanceCounter); // 19
+ bb.addInt(performanceId); // 20
+ bb.addObject(attributes); // 21
+ bb.addObject(maxAttributes); // 22
+ bb.addObject(equipmentList); // 23
+ bb.addAscii(costume); // 24
+ bb.addBoolean(visible); // 25
+ bb.addObject(buffs); // 26
+ bb.addBoolean(performing); // 27
+ bb.addByte(difficulty.getDifficulty()); // 28
+ bb.addInt((hologramColour == null) ? -1 : hologramColour.getValue()); // Hologram Color -- 29
+ bb.addBoolean(shownOnRadar); // 30
+ bb.addBoolean(beast); // 31
+ bb.addByte(0); // forceShowHam? -- 32
+ bb.addObject(appearanceList); // 33
+ bb.addLong(0); // decoy? -- 34
+
+ bb.incrementOperandCount(27);
+ }
+
+ public void parseBaseline6(NetBuffer buffer) {
+ level = buffer.getShort();
+ levelHealthGranted = buffer.getInt();
+ animation = buffer.getAscii();
+ moodAnimation = buffer.getAscii();
+ long weaponId = buffer.getLong();
+ groupId = buffer.getLong();
+ inviterData = buffer.getEncodable(GroupInviterData.class);
+ guildId = buffer.getInt();
+ lookAtTargetId = buffer.getLong();
+ intendedTargetId = buffer.getLong();
+ moodId = buffer.getByte();
+ performanceCounter = buffer.getInt();
+ performanceId = buffer.getInt();
+ attributes = buffer.getSwgList(6, 21, Integer.class);
+ maxAttributes = buffer.getSwgList(6, 22, Integer.class);
+ equipmentList = buffer.getSwgList(6, 23, Equipment.class);
+ costume = buffer.getAscii();
+ visible = buffer.getBoolean();
+ buffs = buffer.getSwgMap(6, 26, CRC.class, Buff.class);
+ performing = buffer.getBoolean();
+ difficulty = CreatureDifficulty.getForDifficulty(buffer.getByte());
+ hologramColour = HologramColour.getForValue(buffer.getInt());
+ shownOnRadar = buffer.getBoolean();
+ beast = buffer.getBoolean();
+ buffer.getBoolean();
+ appearanceList = buffer.getSwgList(6, 33, Equipment.class);
+ buffer.getLong();
+ equippedWeapon = null;
+ for (Equipment e : equipmentList) {
+ if (e.getObjectId() == weaponId && e.getWeapon() instanceof WeaponObject) {
+ equippedWeapon = (WeaponObject) e.getWeapon();
+ break;
+ }
+ }
+ }
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ stream.addShort(level);
+ stream.addInt(levelHealthGranted);
+ stream.addAscii(animation);
+ stream.addAscii(moodAnimation);
+ stream.addInt(guildId);
+ stream.addLong(lookAtTargetId);
+ stream.addLong(intendedTargetId);
+ stream.addByte(moodId);
+ stream.addAscii(costume);
+ stream.addBoolean(visible);
+ stream.addBoolean(shownOnRadar);
+ stream.addBoolean(beast);
+ stream.addAscii(difficulty.name());
+ stream.addAscii(hologramColour.name());
+ stream.addBoolean(equippedWeapon != null);
+ if (equippedWeapon != null)
+ SWGObjectFactory.save(equippedWeapon, stream);
+ synchronized (attributes) {
+ stream.addList(attributes, (i) -> stream.addInt(i));
+ }
+ synchronized (maxAttributes) {
+ stream.addList(maxAttributes, (i) -> stream.addInt(i));
+ }
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ level = stream.getShort();
+ levelHealthGranted = stream.getInt();
+ animation = stream.getAscii();
+ moodAnimation = stream.getAscii();
+ guildId = stream.getInt();
+ lookAtTargetId = stream.getLong();
+ intendedTargetId = stream.getLong();
+ moodId = stream.getByte();
+ costume = stream.getAscii();
+ visible = stream.getBoolean();
+ shownOnRadar = stream.getBoolean();
+ beast = stream.getBoolean();
+ difficulty = CreatureDifficulty.valueOf(stream.getAscii());
+ hologramColour = HologramColour.valueOf(stream.getAscii());
+ if (stream.getBoolean())
+ equippedWeapon = (WeaponObject) SWGObjectFactory.create(stream);
+ stream.getList((i) -> attributes.set(i, stream.getInt()));
+ stream.getList((i) -> maxAttributes.set(i, stream.getInt()));
+ }
+
+}
diff --git a/src/resources/objects/custom/AIObject.java b/src/resources/objects/custom/AIObject.java
index e274cf773..35a5770ba 100644
--- a/src/resources/objects/custom/AIObject.java
+++ b/src/resources/objects/custom/AIObject.java
@@ -35,8 +35,6 @@ import utilities.ScheduledUtilities;
public abstract class AIObject extends CreatureObject {
- private static final long serialVersionUID = 1L;
-
private transient ScheduledFuture> future;
private long initialDelay;
private long delay;
diff --git a/src/resources/objects/custom/DefaultAIObject.java b/src/resources/objects/custom/DefaultAIObject.java
index 3806d541e..d0ea87df0 100644
--- a/src/resources/objects/custom/DefaultAIObject.java
+++ b/src/resources/objects/custom/DefaultAIObject.java
@@ -36,8 +36,6 @@ import resources.Point3D;
public class DefaultAIObject extends AIObject {
- private static final long serialVersionUID = 1L;
-
private Location mainLocation;
private AIBehavior behavior;
private int updateCounter;
diff --git a/src/resources/objects/factory/FactoryObject.java b/src/resources/objects/factory/FactoryObject.java
index 9116f64d0..0d730c9b2 100644
--- a/src/resources/objects/factory/FactoryObject.java
+++ b/src/resources/objects/factory/FactoryObject.java
@@ -28,14 +28,25 @@
package resources.objects.factory;
import network.packets.swg.zone.baselines.Baseline.BaselineType;
+import resources.network.NetBufferStream;
import resources.objects.tangible.TangibleObject;
public class FactoryObject extends TangibleObject {
- private static final long serialVersionUID = 1L;
-
public FactoryObject(long objectId) {
super(objectId, BaselineType.FCYT);
}
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ }
+
}
diff --git a/src/resources/objects/group/GroupObject.java b/src/resources/objects/group/GroupObject.java
index 57ba9a66d..79475dcdd 100644
--- a/src/resources/objects/group/GroupObject.java
+++ b/src/resources/objects/group/GroupObject.java
@@ -45,8 +45,7 @@ import java.util.HashMap;
import java.util.Map;
public class GroupObject extends SWGObject { // Extends INTO or TANO?
- private static final long serialVersionUID = 200L;
-
+
private final SWGList groupMembers = new SWGList<>(6, 2, Encoder.StringType.ASCII);
private long leader;
private short level;
diff --git a/src/resources/objects/guild/GuildObject.java b/src/resources/objects/guild/GuildObject.java
index 755a77ffb..618db8850 100644
--- a/src/resources/objects/guild/GuildObject.java
+++ b/src/resources/objects/guild/GuildObject.java
@@ -41,8 +41,6 @@ import utilities.Encoder.StringType;
public class GuildObject extends SWGObject {
- private static final long serialVersionUID = 1L;
-
private SWGSet abbreviations = new SWGSet(3, 4, StringType.ASCII);
private SWGMap gcwImperialScorePercentileThisGalaxy = new SWGMap<>(6, 2);
private SWGMap gcwGroupImperialScorePercentileThisGalaxy = new SWGMap<>(6, 3);
diff --git a/src/resources/objects/installation/InstallationObject.java b/src/resources/objects/installation/InstallationObject.java
index 3a2589b7d..bb9f4dac2 100644
--- a/src/resources/objects/installation/InstallationObject.java
+++ b/src/resources/objects/installation/InstallationObject.java
@@ -30,13 +30,12 @@ package resources.objects.installation;
import network.packets.swg.zone.baselines.Baseline.BaselineType;
import resources.network.BaselineBuilder;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
import resources.objects.tangible.TangibleObject;
import resources.player.Player;
public class InstallationObject extends TangibleObject {
- private static final long serialVersionUID = 1L;
-
private boolean activated = false;
private double power = 0;
private double powerRate = 0;
@@ -105,4 +104,22 @@ public class InstallationObject extends TangibleObject {
return hash;
}
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ stream.addBoolean(activated);
+ stream.addFloat((float) power);
+ stream.addFloat((float) powerRate);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ activated = stream.getBoolean();
+ power = stream.getFloat();
+ powerRate = stream.getFloat();
+ }
+
}
diff --git a/src/resources/objects/intangible/IntangibleObject.java b/src/resources/objects/intangible/IntangibleObject.java
index 6108518c1..a237ef4cb 100644
--- a/src/resources/objects/intangible/IntangibleObject.java
+++ b/src/resources/objects/intangible/IntangibleObject.java
@@ -30,13 +30,12 @@ package resources.objects.intangible;
import network.packets.swg.zone.baselines.Baseline.BaselineType;
import resources.network.BaselineBuilder;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
import resources.objects.SWGObject;
import resources.player.Player;
public class IntangibleObject extends SWGObject {
- private static final long serialVersionUID = 1L;
-
private int count = 0;
public IntangibleObject(long objectId) {
@@ -76,4 +75,18 @@ public class IntangibleObject extends SWGObject {
public int hashCode() {
return super.hashCode();
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ stream.addInt(count);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ count = stream.getInt();
+ }
}
diff --git a/src/resources/objects/manufacture/ManufactureSchematicObject.java b/src/resources/objects/manufacture/ManufactureSchematicObject.java
index cee7a9905..be3258171 100644
--- a/src/resources/objects/manufacture/ManufactureSchematicObject.java
+++ b/src/resources/objects/manufacture/ManufactureSchematicObject.java
@@ -27,20 +27,21 @@
***********************************************************************************/
package resources.objects.manufacture;
+import java.util.Map.Entry;
+
import network.packets.swg.zone.baselines.Baseline.BaselineType;
import resources.collections.SWGMap;
import resources.common.CRC;
import resources.encodables.StringId;
import resources.network.BaselineBuilder;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
import resources.objects.intangible.IntangibleObject;
import resources.player.Player;
import resources.server_info.CrcDatabase;
public class ManufactureSchematicObject extends IntangibleObject {
- private static final long serialVersionUID = 1L;
-
private SWGMap attributes = new SWGMap<>(3, 5);
private int itemsPerContainer = 0;
private float manufactureTime = 0;
@@ -158,4 +159,42 @@ public class ManufactureSchematicObject extends IntangibleObject {
schematicChangedSignal = buffer.getByte();
}
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ stream.addInt(itemsPerContainer);
+ stream.addFloat(manufactureTime);
+ stream.addArray(appearanceData);
+ stream.addArray(customAppearance);
+ stream.addAscii(draftSchematicTemplate);
+ stream.addBoolean(crafting);
+ stream.addByte(schematicChangedSignal);
+ synchronized (attributes) {
+ stream.addInt(attributes.size());
+ for (Entry e : attributes.entrySet()) {
+ e.getKey().save(stream);
+ stream.addFloat(e.getValue());
+ }
+ }
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ itemsPerContainer = stream.getInt();
+ manufactureTime = stream.getFloat();
+ appearanceData = stream.getArray();
+ customAppearance = stream.getArray();
+ draftSchematicTemplate = stream.getAscii();
+ crafting = stream.getBoolean();
+ schematicChangedSignal = stream.getByte();
+ for (int i = 0; i < stream.getInt(); i++) {
+ StringId id = new StringId();
+ id.read(stream);
+ attributes.put(id, stream.getFloat());
+ }
+ }
+
}
diff --git a/src/resources/objects/mission/MissionObject.java b/src/resources/objects/mission/MissionObject.java
index 03325c7a0..96687807e 100644
--- a/src/resources/objects/mission/MissionObject.java
+++ b/src/resources/objects/mission/MissionObject.java
@@ -37,14 +37,14 @@ import resources.encodables.Encodable;
import resources.encodables.StringId;
import resources.network.BaselineBuilder;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
import resources.objects.intangible.IntangibleObject;
import resources.objects.waypoint.WaypointObject;
+import resources.persistable.Persistable;
import resources.player.Player;
public class MissionObject extends IntangibleObject {
- private static final long serialVersionUID = 1L;
-
private int difficulty = 0;
private MissionLocation location = new MissionLocation();
private String missionCreator = "";
@@ -109,7 +109,43 @@ public class MissionObject extends IntangibleObject {
buffer.getInt();
}
- public static class MissionLocation implements Encodable {
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ stream.addInt(difficulty);
+ stream.addInt(reward);
+ stream.addInt(status);
+ stream.addUnicode(missionCreator);
+ stream.addUnicode(targetName);
+ title.save(stream);
+ description.save(stream);
+ targetAppearance.save(stream);
+ missionType.save(stream);
+ waypoint.save(stream);
+ startLocation.save(stream);
+ location.save(stream);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ difficulty = stream.getInt();
+ reward = stream.getInt();
+ status = stream.getInt();
+ missionCreator = stream.getUnicode();
+ targetName = stream.getUnicode();
+ title.read(stream);
+ description.read(stream);
+ targetAppearance.read(stream);
+ missionType.read(stream);
+ waypoint.read(stream);
+ startLocation.read(stream);
+ location.read(stream);
+ }
+
+ public static class MissionLocation implements Encodable, Persistable {
private Point3D location;
private long objectId;
@@ -138,6 +174,22 @@ public class MissionObject extends IntangibleObject {
terrain = Terrain.getTerrainFromCrc(data.getInt());
}
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addInt(0);
+ stream.addLong(objectId);
+ location.save(stream);
+ stream.addAscii(terrain.name());
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getInt();
+ objectId = stream.getLong();
+ location.read(stream);
+ terrain = Terrain.valueOf(stream.getAscii());
+ }
+
}
}
diff --git a/src/resources/objects/mobile/MobileObject.java b/src/resources/objects/mobile/MobileObject.java
index df604894d..f3ca8f0e9 100644
--- a/src/resources/objects/mobile/MobileObject.java
+++ b/src/resources/objects/mobile/MobileObject.java
@@ -31,8 +31,6 @@ import resources.objects.creature.CreatureObject;
public class MobileObject extends CreatureObject {
- private static final long serialVersionUID = 1L;
-
public MobileObject(long objectId) {
super(objectId);
}
diff --git a/src/resources/objects/player/PlayerObject.java b/src/resources/objects/player/PlayerObject.java
index 499461116..daaa14374 100644
--- a/src/resources/objects/player/PlayerObject.java
+++ b/src/resources/objects/player/PlayerObject.java
@@ -29,12 +29,9 @@ package resources.objects.player;
import network.packets.swg.zone.UpdatePostureMessage;
import network.packets.swg.zone.baselines.Baseline.BaselineType;
-import network.packets.swg.zone.chat.ChatSystemMessage;
-import resources.collections.SWGFlag;
-import resources.collections.SWGBitSet;
-import resources.collections.SWGList;
import resources.collections.SWGMap;
import resources.network.BaselineBuilder;
+import resources.network.NetBufferStream;
import resources.objects.SWGObject;
import resources.objects.creature.CreatureObject;
import resources.objects.intangible.IntangibleObject;
@@ -42,68 +39,22 @@ import resources.objects.waypoint.WaypointObject;
import resources.player.AccessLevel;
import resources.player.Player;
import resources.player.PlayerFlags;
-import utilities.MathUtils;
import utilities.Encoder.StringType;
import java.util.ArrayList;
-import java.util.BitSet;
import java.util.Collections;
import java.util.List;
public class PlayerObject extends IntangibleObject {
- private static final long serialVersionUID = 1L;
+ private PlayerObjectShared play3 = new PlayerObjectShared();
+ private PlayerObjectSharedNP play6 = new PlayerObjectSharedNP();
+ private PlayerObjectPrivate play8 = new PlayerObjectPrivate();
+ private PlayerObjectPrivateNP play9 = new PlayerObjectPrivateNP();
- private String biography = "";
- private List joinedChannels = new ArrayList<>();
-
- // PLAY 03
- private SWGFlag flagsList = new SWGFlag(3, 5);
- private SWGFlag profileFlags = new SWGFlag(3, 6);
- private String title = "";
- private int bornDate = 0;
- private int playTime = 0;
- private int professionIcon = 0;
- private String profession = "";
- private int gcwPoints = 0;
- private int pvpKills = 0;
- private long lifetimeGcwPoints = 0;
- private int lifetimePvpKills = 0;
- private SWGBitSet collectionBadges = new SWGBitSet(3, 16);
- private SWGBitSet collectionBadges2 = new SWGBitSet(3, 17);
- private boolean showHelmet = true;
- private boolean showBackpack = true;
- // PLAY 06
- private int adminTag = 0;
- private int currentRank = 0;
- private float rankProgress = 0;
- private int highestRebelRank = 0;
- private int highestImperialRank = 0;
- private int gcwNextUpdate = 0;
- private String home = "";
- // PLAY 08
- private SWGMap experience = new SWGMap<>(8, 0, StringType.ASCII);
- private SWGMap waypoints = new SWGMap<>(8, 1);
- private boolean citizen = false;
- private int guildRankTitle = 0;
- private int activeQuest = 0;
- private SWGMap quests = new SWGMap<>(8, 7);
- private String profWheelPosition = "";
- // PLAY 09
- private int experimentFlag = 0;
- private int craftingStage = 0;
- private long nearbyCraftStation = 0;
- private SWGList draftSchemList = new SWGList<>(9, 3, StringType.ASCII);
- private int experimentPoints = 0;
- private SWGList friendsList = new SWGList<>(9, 7, StringType.ASCII);
- private SWGList ignoreList = new SWGList<>(9, 8, StringType.ASCII);
- private int languageId = 0;
- private SWGList defenders = new SWGList<>(9, 17); // TODO: Change to set
- private int killMeter = 0;
- private long petId = 0;
- private SWGList petAbilities = new SWGList<>(9, 21);
- private SWGList activePetAbilities = new SWGList<>(9, 22);
- private int startPlayTime;
+ private int startPlayTime = 0;
+ private String biography = "";
+ private List joinedChannels = new ArrayList<>();
public PlayerObject(long objectId) {
super(objectId, BaselineType.PLAY);
@@ -111,129 +62,110 @@ public class PlayerObject extends IntangibleObject {
}
public void addWaypoint(WaypointObject waypoint) {
- synchronized(waypoints) {
- if (waypoints.size() < 250) {
- waypoints.put(waypoint.getObjectId(), waypoint);
- waypoints.sendDeltaMessage(this);
- }
- else {
- sendSelf(new ChatSystemMessage(ChatSystemMessage.SystemChatType.SCREEN_AND_CHAT, "@base_player:too_many_waypoints"));
- }
- }
+ play8.addWaypoint(waypoint, this);
}
public WaypointObject getWaypoint(long objId) {
- synchronized(waypoints) {
- return waypoints.get(objId);
- }
+ return play8.getWaypoint(objId);
}
public SWGMap getWaypoints() {
- synchronized(waypoints) {
- return waypoints;
- }
+ return play8.getWaypoints();
}
public void updateWaypoint(WaypointObject obj) {
- synchronized(waypoints) {
- waypoints.update(obj.getObjectId(), this);
- }
+ play8.updateWaypoint(obj, this);
}
public void removeWaypoint(long objId) {
- synchronized(waypoints) {
- waypoints.remove(objId);
- waypoints.sendDeltaMessage(this);
- }
+ play8.removeWaypoint(objId, this);
}
public String getTitle() {
- return title;
+ return play3.getTitle();
}
public void setTitle(String title) {
- this.title = title;
+ play3.setTitle(title);
sendDelta(3, 7, title, StringType.ASCII);
}
public int getPlayTime() {
- return playTime;
+ return play3.getPlayTime();
}
public void setPlayTime(int playTime) {
- this.playTime = playTime;
+ play3.setPlayTime(playTime);
sendDelta(3, 9, playTime);
}
public int getGcwPoints() {
- return gcwPoints;
+ return play3.getGcwPoints();
}
public void setGcwPoints(int gcwPoints) {
- this.gcwPoints = gcwPoints;
+ play3.setGcwPoints(gcwPoints);
sendDelta(3, 12, gcwPoints);
}
public int getPvpKills() {
- return pvpKills;
+ return play3.getPvpKills();
}
public void setPvpKills(int pvpKills) {
- this.pvpKills = pvpKills;
+ play3.setPvpKills(pvpKills);
sendDelta(3, 13, pvpKills);
}
public long getLifetimeGcwPoints() {
- return lifetimeGcwPoints;
+ return play3.getLifetimeGcwPoints();
}
public void setLifetimeGcwPoints(long lifetimeGcwPoints) {
- this.lifetimeGcwPoints = lifetimeGcwPoints;
+ play3.setLifetimeGcwPoints(lifetimeGcwPoints);
sendDelta(3, 14, lifetimeGcwPoints);
}
public int getLifetimePvpKills() {
- return lifetimePvpKills;
+ return play3.getLifetimePvpKills();
}
public void setLifetimePvpKills(int lifetimePvpKills) {
- this.lifetimePvpKills = lifetimePvpKills;
+ play3.setLifetimePvpKills(lifetimePvpKills);
sendDelta(3, 15, lifetimePvpKills);
}
public byte[] getCollectionBadges() {
- return collectionBadges.toByteArray();
+ return play3.getCollectionBadges();
}
public void setCollectionBadges(byte[] collection) {
- this.collectionBadges.clear();
- this.collectionBadges.or(BitSet.valueOf(collection));
- sendDelta(3, 16, collectionBadges);
+ play3.setCollectionBadges(collection, this);
}
public boolean isShowHelmet() {
- return showHelmet;
+ return play3.isShowHelmet();
}
public void setShowHelmet(boolean showHelmet) {
- this.showHelmet = showHelmet;
+ play3.setShowHelmet(showHelmet);
sendDelta(3, 19, showHelmet);
}
public boolean isShowBackpack() {
- return showBackpack;
+ return play3.isShowBackpack();
}
public void setShowBackpack(boolean showBackpack) {
- this.showBackpack = showBackpack;
+ play3.setShowBackpack(showBackpack);
sendDelta(3, 18, showBackpack);
}
public String getProfession() {
- return profession;
+ return play3.getProfession();
}
public void setProfession(String profession) {
- this.profession = profession;
+ play3.setProfession(profession);
sendDelta(3, 11, profession, StringType.ASCII);
}
@@ -246,183 +178,150 @@ public class PlayerObject extends IntangibleObject {
}
public void setBornDate(int year, int month, int day) {
- this.bornDate = MathUtils.numberDaysSince(year, month, day, 2000, 12, 31);
+ play3.setBornDate(year, month, day);
}
public int getBornDate() {
- return bornDate;
+ return play3.getBornDate();
+ }
+
+ public int getAdminTag() {
+ return play6.getAdminTag();
}
public void setAdminTag(AccessLevel access) {
- switch(access) {
- case PLAYER: break;
- case CSR: adminTag = 1; break;
- case DEV: adminTag = 2; break;
- case WARDEN: adminTag = 3; break;
- case QA: adminTag = 4; break;
- }
- sendDelta(6, 2, adminTag);
- }
-
- public void setAdminTag(int tag) {
- this.adminTag = tag;
- sendDelta(6, 2, tag);
+ play6.setAdminTag(access);
+ sendDelta(6, 2, play6.getAdminTag());
}
public int getCurrentRank() {
- return currentRank;
+ return play6.getCurrentRank();
}
public void setCurrentRank(int currentRank) {
- this.currentRank = currentRank;
+ play6.setCurrentRank(currentRank);
sendDelta(6, 3, currentRank);
}
public float getRankProgress() {
- return rankProgress;
+ return play6.getRankProgress();
}
public void setRankProgress(float rankProgress) {
- this.rankProgress = rankProgress;
+ play6.setRankProgress(rankProgress);
sendDelta(6, 4, rankProgress);
}
public int getHighestRebelRank() {
- return highestRebelRank;
+ return play6.getHighestRebelRank();
}
public void setHighestRebelRank(int highestRebelRank) {
- this.highestRebelRank = highestRebelRank;
+ play6.setHighestRebelRank(highestRebelRank);
sendDelta(6, 5, highestRebelRank);
}
public int getHighestImperialRank() {
- return highestImperialRank;
+ return play6.getHighestImperialRank();
}
public void setHighestImperialRank(int highestImperialRank) {
- this.highestImperialRank = highestImperialRank;
+ play6.setHighestImperialRank(highestImperialRank);
sendDelta(6, 6, highestImperialRank);
}
public int getGcwNextUpdate() {
- return gcwNextUpdate;
+ return play6.getGcwNextUpdate();
}
public void setGcwNextUpdate(int gcwNextUpdate) {
- this.gcwNextUpdate = gcwNextUpdate;
+ play6.setGcwNextUpdate(gcwNextUpdate);
sendDelta(6, 7, gcwNextUpdate);
}
public String getHome() {
- return home;
+ return play6.getHome();
}
public void setHome(String home) {
- this.home = home;
+ play6.setHome(home);
sendDelta(6, 8, home, StringType.ASCII);
}
-
+
public boolean isCitizen() {
- return citizen;
+ return play6.isCitizen();
}
-
+
public void setCitizen(boolean citizen) {
- this.citizen = citizen;
+ play6.setCitizen(citizen);
sendDelta(6, 9, citizen);
}
public int getGuildRankTitle() {
- return guildRankTitle;
+ return play8.getGuildRankTitle();
}
public void setGuildRankTitle(int guildRankTitle) {
- this.guildRankTitle = guildRankTitle;
+ play8.setGuildRankTitle(guildRankTitle);
sendDelta(6, 13, guildRankTitle);
}
public int getActiveQuest() {
- return activeQuest;
+ return play8.getActiveQuest();
}
public void setActiveQuest(int activeQuest) {
- this.activeQuest = activeQuest;
+ play8.setActiveQuest(activeQuest);
sendDelta(8, 6, activeQuest);
}
public void removeFriend(String friend) {
- synchronized (friendsList) {
- friendsList.remove(friend);
- }
- friendsList.sendDeltaMessage(this);
+ play9.removeFriend(friend, this);
}
public void addFriend(String friend) {
- synchronized (friendsList) {
- friendsList.add(friend);
- }
- friendsList.sendDeltaMessage(this);
+ play9.addFriend(friend, this);
}
public List getFriendsList() {
- return friendsList;
+ return play9.getFriendsList();
}
public void addIgnored(String ignored) {
- synchronized (ignoreList) {
- ignoreList.add(ignored);
- }
- ignoreList.sendDeltaMessage(this);
+ play9.addIgnored(ignored, this);
}
public void removeIgnored(String ignored) {
- synchronized (ignoreList) {
- ignoreList.remove(ignored);
- }
- ignoreList.sendDeltaMessage(this);
+ play9.removeIgnored(ignored, this);
}
public boolean isIgnored(String target) {
- return ignoreList.contains(target);
+ return play9.isIgnored(target);
}
public List getIgnoreList() {
- return ignoreList;
+ return play9.getIgnoreList();
}
public String getProfWheelPosition() {
- return profWheelPosition;
+ return play8.getProfWheelPosition();
}
public void setProfWheelPosition(String profWheelPosition) {
- this.profWheelPosition = profWheelPosition;
+ play8.setProfWheelPosition(profWheelPosition);
sendDelta(8, 8, profWheelPosition, StringType.ASCII);
}
public void setFlagBitmask(PlayerFlags ... flags) {
- boolean changed = false;
- for (PlayerFlags flag : flags) {
- changed |= !flagsList.get(flag.getFlag());
- flagsList.set(flag.getFlag());
- }
- if (changed)
- flagsList.sendDeltaMessage(this);
+ play3.setFlagBitmask(this, flags);
}
public void clearFlagBitmask(PlayerFlags ... flags) {
- boolean changed = false;
- for (PlayerFlags flag : flags) {
- changed |= flagsList.get(flag.getFlag());
- flagsList.clear(flag.getFlag());
- }
- if (changed)
- flagsList.sendDeltaMessage(this);
+ play3.clearFlagBitmask(this, flags);
}
public void toggleFlag(PlayerFlags ... flags) {
- for (PlayerFlags flag : flags)
- flagsList.flip(flag.getFlag());
- flagsList.sendDeltaMessage(this);
+ play3.toggleFlag(this, flags);
}
public List getJoinedChannels() {
@@ -448,26 +347,36 @@ public class PlayerObject extends IntangibleObject {
}
public void setProfessionIcon(int professionIcon) {
- this.professionIcon = professionIcon;
+ play3.setProfessionIcon(professionIcon);
sendDelta(3, 10, professionIcon);
}
public int getProfessionIcon() {
- return professionIcon;
+ return play3.getProfessionIcon();
}
public void addDraftSchematic(String schematic) {
- draftSchemList.add(schematic);
- draftSchemList.sendDeltaMessage(this);
+ play9.addDraftSchematic(schematic, this);
}
- public Integer getExperiencePoints(String xpType) {
- return experience.get(xpType);
+ public int getExperiencePoints(String xpType) {
+ return play8.getExperiencePoints(xpType);
}
public void setExperiencePoints(String xpType, int experiencePoints) {
- experience.put(xpType, experiencePoints);
- experience.sendDeltaMessage(this);
+ play8.setExperiencePoints(xpType, experiencePoints, this);
+ }
+
+ public void addExperiencePoints(String xpType, int experiencePoints) {
+ play8.addExperiencePoints(xpType, experiencePoints, this);
+ }
+
+ public int getStartPlayTime() {
+ return startPlayTime;
+ }
+
+ public void setStartPlayTime(int startPlayTime) {
+ this.startPlayTime = startPlayTime;
}
public void createChildrenObjects(Player target) {
@@ -479,113 +388,45 @@ public class PlayerObject extends IntangibleObject {
public void createBaseline3(Player target, BaselineBuilder bb) {
super.createBaseline3(target, bb); // 5 variables
- bb.addObject(flagsList); // 4 flags -- 5
- bb.addObject(profileFlags); // 4 flags -- 6
- bb.addAscii(title); // 7
- bb.addInt(bornDate); // Born Date -- 4001 = 12/15/2011 || Number of days after 12/31/2000 -- 8
- bb.addInt(playTime); // 9
- bb.addInt(professionIcon); // 10
- bb.addAscii(profession); // 11
- bb.addInt(gcwPoints); // 12
- bb.addInt(pvpKills); // 13
- bb.addLong(lifetimeGcwPoints); // 14
- bb.addInt(lifetimePvpKills); // 15
- bb.addObject(collectionBadges); // 16
- bb.addObject(collectionBadges2); // 17
- bb.addBoolean(showBackpack); // 18
- bb.addBoolean(showHelmet); // 19
- for (int i = 0; i < 64; i++)
- bb.addByte(0);
-
- bb.incrementOperandCount(15);
+ play3.createBaseline3(target, bb);
}
public void createBaseline6(Player target, BaselineBuilder bb) {
super.createBaseline6(target, bb); // 2 variables
- bb.addByte(adminTag); // Admin Tag (0 = none, 1 = CSR, 2 = Developer, 3 = Warden, 4 = QA) -- 2
- bb.addInt(currentRank); // 3
- bb.addFloat(rankProgress); // 4
- bb.addInt(highestImperialRank); // 5
- bb.addInt(highestRebelRank); // 6
- bb.addInt(gcwNextUpdate); // 7
- bb.addAscii(home); // 8
- bb.addBoolean(citizen); // 9
- bb.addAscii(""); // City Region Defender 'region' -- 10
- bb.addBoolean(false); // City Region Defender byte #1
- bb.addBoolean(false); // City Region Defender byte #2
- bb.addAscii(""); // Guild Region Defender 'region' -- 11
- bb.addBoolean(false); // Guild Region Defender byte #1
- bb.addBoolean(false); // Guild Region Defender byte #2
- bb.addLong(0); // General? -- 12
- bb.addAscii(""); // 13
- bb.addInt(0); // Citizen Rank Title? 6 bytes -- 14
- bb.addInt(0); // Environment Flags Override -- 15
- bb.addAscii(""); // Vehicle Attack Command -- 16
-
- bb.incrementOperandCount(15);
+ play6.createBaseline6(target, bb);
}
public void createBaseline8(Player target, BaselineBuilder bb) {
super.createBaseline8(target, bb); // 0 variables
- bb.addObject(experience); // 0
- bb.addObject(waypoints); // 1
- bb.addInt(100); // Current Force Power -- 2
- bb.addInt(100); // Max Force Power -- 3
- bb.addInt(0); // Completed Quests (List) -- 4
- bb.addInt(0);
- bb.addInt(0); // Active Quests (List) -- 5
- bb.addInt(0);
- bb.addInt(activeQuest); // Current Quest -- 6
- bb.addObject(quests); // 7
- bb.addAscii(profWheelPosition); // 8
-
- bb.incrementOperandCount(9);
+ play8.createBaseline8(target, bb);
}
public void createBaseline9(Player target, BaselineBuilder bb) {
super.createBaseline9(target, bb); // 0 variables
- bb.addInt(experimentFlag); // 0
- bb.addInt(craftingStage); // 1
- bb.addLong(nearbyCraftStation); // 2
- bb.addObject(draftSchemList); // 3
- bb.addInt(0); // Might or might not be a list, two ints that are part of the same delta -- 4
- bb.addInt(0);
- bb.addInt(experimentPoints); // 5
- bb.addInt(0); // Accomplishment Counter - Pre-NGE? -- 6
- bb.addObject(friendsList); // 7
- bb.addObject(ignoreList); // 8
- bb.addInt(languageId); // 9
- bb.addInt(0); // Current Stomach -- 10
- bb.addInt(100); // Max Stomach -- 11
- bb.addInt(0); // Current Drink -- 12
- bb.addInt(100); // Max Drink -- 13
- bb.addInt(0); // Current Consumable -- 14
- bb.addInt(100); // Max Consumable -- 15
- bb.addInt(0); // Group Waypoints -- 16
- bb.addInt(0);
- bb.addObject(defenders); // 17
- bb.addInt(killMeter); // 18
- bb.addInt(0); // Unk -- 19
- bb.addLong(petId); // 20
- bb.addObject(petAbilities); // 21
- bb.addObject(activePetAbilities); // 22
- bb.addByte(0); // Unk sometimes 0x01 or 0x02 -- 23
- bb.addInt(0); // Unk sometimes 4 -- 24
- bb.addLong(0); // Unk Bitmask starts with 0x20 ends with 0x40 -- 25
- bb.addLong(0); // Unk Changes from 6 bytes to 9 -- 26
- bb.addByte(0); // Unk Changes from 6 bytes to 9 -- 27
- bb.addLong(0); // Unk sometimes 856 -- 28
- bb.addLong(0); // Unk sometimes 8559 -- 29
- bb.addInt(0); // Residence Time? Seen as Saturday 28th May 2011 -- 30
-
- bb.incrementOperandCount(31);
+ play9.createBaseline9(target, bb);
}
- public int getStartPlayTime() {
- return startPlayTime;
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ play3.save(stream);
+ play6.save(stream);
+ play8.save(stream);
+ play9.save(stream);
+ stream.addInt(startPlayTime);
+ stream.addUnicode(biography);
}
-
- public void setStartPlayTime(int startPlayTime) {
- this.startPlayTime = startPlayTime;
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ play3.read(stream);
+ play6.read(stream);
+ play8.read(stream);
+ play9.read(stream);
+ startPlayTime = stream.getInt();
+ biography = stream.getUnicode();
}
}
diff --git a/src/resources/objects/player/PlayerObjectPrivate.java b/src/resources/objects/player/PlayerObjectPrivate.java
new file mode 100644
index 000000000..221c2101f
--- /dev/null
+++ b/src/resources/objects/player/PlayerObjectPrivate.java
@@ -0,0 +1,190 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.objects.player;
+
+import network.packets.swg.zone.chat.ChatSystemMessage;
+import resources.collections.SWGMap;
+import resources.network.BaselineBuilder;
+import resources.network.NetBufferStream;
+import resources.objects.SWGObject;
+import resources.objects.waypoint.WaypointObject;
+import resources.persistable.Persistable;
+import resources.persistable.SWGObjectFactory;
+import resources.player.Player;
+import utilities.Encoder.StringType;
+
+class PlayerObjectPrivate implements Persistable {
+
+ private SWGMap experience = new SWGMap<>(8, 0, StringType.ASCII);
+ private SWGMap waypoints = new SWGMap<>(8, 1);
+ private int guildRankTitle = 0;
+ private int activeQuest = 0;
+ private SWGMap quests = new SWGMap<>(8, 7);
+ private String profWheelPosition = "";
+
+ public PlayerObjectPrivate() {
+
+ }
+
+ public void addWaypoint(WaypointObject waypoint, SWGObject target) {
+ synchronized(waypoints) {
+ if (waypoints.size() < 250) {
+ waypoints.put(waypoint.getObjectId(), waypoint);
+ waypoints.sendDeltaMessage(target);
+ } else {
+ target.sendSelf(new ChatSystemMessage(ChatSystemMessage.SystemChatType.SCREEN_AND_CHAT, "@base_player:too_many_waypoints"));
+ }
+ }
+ }
+
+ public WaypointObject getWaypoint(long objId) {
+ synchronized (waypoints) {
+ return waypoints.get(objId);
+ }
+ }
+
+ public SWGMap getWaypoints() {
+ synchronized (waypoints) {
+ return waypoints;
+ }
+ }
+
+ public void updateWaypoint(WaypointObject obj, SWGObject target) {
+ synchronized (waypoints) {
+ waypoints.update(obj.getObjectId(), target);
+ }
+ }
+
+ public void removeWaypoint(long objId, SWGObject target) {
+ synchronized (waypoints) {
+ waypoints.remove(objId);
+ waypoints.sendDeltaMessage(target);
+ }
+ }
+
+ public int getGuildRankTitle() {
+ return guildRankTitle;
+ }
+
+ public int getActiveQuest() {
+ return activeQuest;
+ }
+
+ public String getProfWheelPosition() {
+ return profWheelPosition;
+ }
+
+ public void setGuildRankTitle(int guildRankTitle) {
+ this.guildRankTitle = guildRankTitle;
+ }
+
+ public void setActiveQuest(int activeQuest) {
+ this.activeQuest = activeQuest;
+ }
+
+ public void setProfWheelPosition(String profWheelPosition) {
+ this.profWheelPosition = profWheelPosition;
+ }
+
+ public int getExperiencePoints(String xpType) {
+ synchronized (experience) {
+ Integer i = experience.get(xpType);
+ if (i == null)
+ return 0;
+ return i;
+ }
+ }
+
+ public void setExperiencePoints(String xpType, int experiencePoints, SWGObject target) {
+ synchronized (experience) {
+ experience.put(xpType, experiencePoints);
+ experience.sendDeltaMessage(target);
+ }
+ }
+
+ public void addExperiencePoints(String xpType, int experiencePoints, SWGObject target) {
+ synchronized (experience) {
+ experience.put(xpType, getExperiencePoints(xpType) + experiencePoints);
+ experience.sendDeltaMessage(target);
+ }
+ }
+
+ public void createBaseline8(Player target, BaselineBuilder bb) {
+ bb.addObject(experience); // 0
+ bb.addObject(waypoints); // 1
+ bb.addInt(100); // Current Force Power -- 2
+ bb.addInt(100); // Max Force Power -- 3
+ bb.addInt(0); // Completed Quests (List) -- 4
+ bb.addInt(0);
+ bb.addInt(0); // Active Quests (List) -- 5
+ bb.addInt(0);
+ bb.addInt(activeQuest); // Current Quest -- 6
+ bb.addObject(quests); // 7
+ bb.addAscii(profWheelPosition); // 8
+
+ bb.incrementOperandCount(9);
+ }
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ stream.addAscii(profWheelPosition);
+ stream.addInt(guildRankTitle);
+ stream.addInt(activeQuest);
+ synchronized (experience) {
+ stream.addMap(experience, (e) -> {
+ stream.addAscii(e.getKey());
+ stream.addInt(e.getValue());
+ });
+ }
+ synchronized (quests) {
+ stream.addMap(quests, (e) -> {
+ stream.addInt(e.getKey());
+ stream.addInt(e.getValue());
+ });
+ }
+ synchronized (waypoints) {
+ stream.addMap(waypoints, (e) -> {
+ stream.addLong(e.getKey());
+ SWGObjectFactory.save(e.getValue(), stream);
+ });
+ }
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ profWheelPosition = stream.getAscii();
+ guildRankTitle = stream.getInt();
+ activeQuest = stream.getInt();
+ stream.getList((i) -> experience.put(stream.getAscii(), stream.getInt()));
+ stream.getList((i) -> quests.put(stream.getInt(), stream.getInt()));
+ stream.getList((i) -> waypoints.put(stream.getLong(), (WaypointObject) SWGObjectFactory.create(stream)));
+ }
+
+}
diff --git a/src/resources/objects/player/PlayerObjectPrivateNP.java b/src/resources/objects/player/PlayerObjectPrivateNP.java
new file mode 100644
index 000000000..b79579968
--- /dev/null
+++ b/src/resources/objects/player/PlayerObjectPrivateNP.java
@@ -0,0 +1,170 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.objects.player;
+
+import java.util.List;
+
+import resources.collections.SWGList;
+import resources.collections.SWGSet;
+import resources.network.BaselineBuilder;
+import resources.network.NetBufferStream;
+import resources.objects.SWGObject;
+import resources.persistable.Persistable;
+import resources.player.Player;
+import utilities.Encoder.StringType;
+
+class PlayerObjectPrivateNP implements Persistable {
+
+ private int experimentFlag = 0;
+ private int craftingStage = 0;
+ private long nearbyCraftStation = 0;
+ private SWGList draftSchemList = new SWGList<>(9, 3, StringType.ASCII);
+ private int experimentPoints = 0;
+ private SWGList friendsList = new SWGList<>(9, 7, StringType.ASCII);
+ private SWGList ignoreList = new SWGList<>(9, 8, StringType.ASCII);
+ private int languageId = 0;
+ private SWGSet defenders = new SWGSet<>(9, 17);
+ private int killMeter = 0;
+ private long petId = 0;
+ private SWGList petAbilities = new SWGList<>(9, 21);
+ private SWGList activePetAbilities = new SWGList<>(9, 22);
+
+ public PlayerObjectPrivateNP() {
+
+ }
+
+ public void removeFriend(String friend, SWGObject target) {
+ synchronized (friendsList) {
+ friendsList.remove(friend);
+ }
+ friendsList.sendDeltaMessage(target);
+ }
+
+ public void addFriend(String friend, SWGObject target) {
+ synchronized (friendsList) {
+ friendsList.add(friend);
+ }
+ friendsList.sendDeltaMessage(target);
+ }
+
+ public List getFriendsList() {
+ return friendsList;
+ }
+
+ public void addIgnored(String ignored, SWGObject target) {
+ synchronized (ignoreList) {
+ ignoreList.add(ignored);
+ }
+ ignoreList.sendDeltaMessage(target);
+ }
+
+ public void removeIgnored(String ignored, SWGObject target) {
+ synchronized (ignoreList) {
+ ignoreList.remove(ignored);
+ }
+ ignoreList.sendDeltaMessage(target);
+ }
+
+ public boolean isIgnored(String target) {
+ return ignoreList.contains(target);
+ }
+
+ public List getIgnoreList() {
+ return ignoreList;
+ }
+
+ public void addDraftSchematic(String schematic, SWGObject target) {
+ draftSchemList.add(schematic);
+ draftSchemList.sendDeltaMessage(target);
+ }
+
+ public void createBaseline9(Player target, BaselineBuilder bb) {
+ bb.addInt(experimentFlag); // 0
+ bb.addInt(craftingStage); // 1
+ bb.addLong(nearbyCraftStation); // 2
+ bb.addObject(draftSchemList); // 3
+ bb.addInt(0); // Might or might not be a list, two ints that are part of the same delta -- 4
+ bb.addInt(0);
+ bb.addInt(experimentPoints); // 5
+ bb.addInt(0); // Accomplishment Counter - Pre-NGE? -- 6
+ bb.addObject(friendsList); // 7
+ bb.addObject(ignoreList); // 8
+ bb.addInt(languageId); // 9
+ bb.addInt(0); // Current Stomach -- 10
+ bb.addInt(100); // Max Stomach -- 11
+ bb.addInt(0); // Current Drink -- 12
+ bb.addInt(100); // Max Drink -- 13
+ bb.addInt(0); // Current Consumable -- 14
+ bb.addInt(100); // Max Consumable -- 15
+ bb.addInt(0); // Group Waypoints -- 16
+ bb.addInt(0);
+ bb.addObject(defenders); // 17
+ bb.addInt(killMeter); // 18
+ bb.addInt(0); // Unk -- 19
+ bb.addLong(petId); // 20
+ bb.addObject(petAbilities); // 21
+ bb.addObject(activePetAbilities); // 22
+ bb.addByte(0); // Unk sometimes 0x01 or 0x02 -- 23
+ bb.addInt(0); // Unk sometimes 4 -- 24
+ bb.addLong(0); // Unk Bitmask starts with 0x20 ends with 0x40 -- 25
+ bb.addLong(0); // Unk Changes from 6 bytes to 9 -- 26
+ bb.addByte(0); // Unk Changes from 6 bytes to 9 -- 27
+ bb.addLong(0); // Unk sometimes 856 -- 28
+ bb.addLong(0); // Unk sometimes 8559 -- 29
+ bb.addInt(0); // Residence Time? Seen as Saturday 28th May 2011 -- 30
+
+ bb.incrementOperandCount(31);
+ }
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ stream.addInt(languageId);
+ stream.addInt(killMeter);
+ stream.addLong(petId);
+ stream.addList(draftSchemList, (s) -> stream.addAscii(s));
+ stream.addList(friendsList, (s) -> stream.addAscii(s));
+ stream.addList(ignoreList, (s) -> stream.addAscii(s));
+ stream.addList(petAbilities, (s) -> stream.addAscii(s));
+ stream.addList(activePetAbilities, (s) -> stream.addAscii(s));
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ languageId = stream.getInt();
+ killMeter = stream.getInt();
+ petId = stream.getLong();
+ stream.getList((i) -> draftSchemList.add(stream.getAscii()));
+ stream.getList((i) -> friendsList.add(stream.getAscii()));
+ stream.getList((i) -> ignoreList.add(stream.getAscii()));
+ stream.getList((i) -> petAbilities.add(stream.getAscii()));
+ stream.getList((i) -> activePetAbilities.add(stream.getAscii()));
+ }
+
+}
diff --git a/src/resources/objects/player/PlayerObjectShared.java b/src/resources/objects/player/PlayerObjectShared.java
new file mode 100644
index 000000000..9a7609548
--- /dev/null
+++ b/src/resources/objects/player/PlayerObjectShared.java
@@ -0,0 +1,266 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.objects.player;
+
+import java.util.BitSet;
+
+import resources.collections.SWGBitSet;
+import resources.collections.SWGFlag;
+import resources.network.BaselineBuilder;
+import resources.network.NetBufferStream;
+import resources.objects.SWGObject;
+import resources.persistable.Persistable;
+import resources.player.Player;
+import resources.player.PlayerFlags;
+import utilities.MathUtils;
+
+class PlayerObjectShared implements Persistable {
+
+ private SWGFlag flagsList = new SWGFlag(3, 5);
+ private SWGFlag profileFlags = new SWGFlag(3, 6);
+ private String title = "";
+ private int bornDate = 0;
+ private int playTime = 0;
+ private int professionIcon = 0;
+ private String profession = "";
+ private int gcwPoints = 0;
+ private int pvpKills = 0;
+ private long lifetimeGcwPoints = 0;
+ private int lifetimePvpKills = 0;
+ private SWGBitSet collectionBadges = new SWGBitSet(3, 16);
+ private SWGBitSet collectionBadges2 = new SWGBitSet(3, 17);
+ private boolean showHelmet = true;
+ private boolean showBackpack = true;
+
+ public PlayerObjectShared() {
+
+ }
+
+ public SWGFlag getFlagsList() {
+ return flagsList;
+ }
+
+ public SWGFlag getProfileFlags() {
+ return profileFlags;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public int getBornDate() {
+ return bornDate;
+ }
+
+ public int getPlayTime() {
+ return playTime;
+ }
+
+ public int getProfessionIcon() {
+ return professionIcon;
+ }
+
+ public String getProfession() {
+ return profession;
+ }
+
+ public int getGcwPoints() {
+ return gcwPoints;
+ }
+
+ public int getPvpKills() {
+ return pvpKills;
+ }
+
+ public long getLifetimeGcwPoints() {
+ return lifetimeGcwPoints;
+ }
+
+ public int getLifetimePvpKills() {
+ return lifetimePvpKills;
+ }
+
+ public byte[] getCollectionBadges() {
+ return collectionBadges.toByteArray();
+ }
+
+ public boolean isShowHelmet() {
+ return showHelmet;
+ }
+
+ public boolean isShowBackpack() {
+ return showBackpack;
+ }
+
+ public void setFlagsList(SWGFlag flagsList) {
+ this.flagsList = flagsList;
+ }
+
+ public void setProfileFlags(SWGFlag profileFlags) {
+ this.profileFlags = profileFlags;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public void setBornDate(int bornDate) {
+ this.bornDate = bornDate;
+ }
+
+ public void setPlayTime(int playTime) {
+ this.playTime = playTime;
+ }
+
+ public void setProfessionIcon(int professionIcon) {
+ this.professionIcon = professionIcon;
+ }
+
+ public void setProfession(String profession) {
+ this.profession = profession;
+ }
+
+ public void setBornDate(int year, int month, int day) {
+ this.bornDate = MathUtils.numberDaysSince(year, month, day, 2000, 12, 31);
+ }
+
+ public void setGcwPoints(int gcwPoints) {
+ this.gcwPoints = gcwPoints;
+ }
+
+ public void setPvpKills(int pvpKills) {
+ this.pvpKills = pvpKills;
+ }
+
+ public void setLifetimeGcwPoints(long lifetimeGcwPoints) {
+ this.lifetimeGcwPoints = lifetimeGcwPoints;
+ }
+
+ public void setLifetimePvpKills(int lifetimePvpKills) {
+ this.lifetimePvpKills = lifetimePvpKills;
+ }
+
+ public void setCollectionBadges(byte [] collection, SWGObject target) {
+ this.collectionBadges.clear();
+ this.collectionBadges.or(BitSet.valueOf(collection));
+ collectionBadges.sendDeltaMessage(target);
+ }
+
+ public void setShowHelmet(boolean showHelmet) {
+ this.showHelmet = showHelmet;
+ }
+
+ public void setShowBackpack(boolean showBackpack) {
+ this.showBackpack = showBackpack;
+ }
+
+ public void setFlagBitmask(SWGObject target, PlayerFlags ... flags) {
+ boolean changed = false;
+ for (PlayerFlags flag : flags) {
+ changed |= !flagsList.get(flag.getFlag());
+ flagsList.set(flag.getFlag());
+ }
+ if (changed)
+ flagsList.sendDeltaMessage(target);
+ }
+
+ public void clearFlagBitmask(SWGObject target, PlayerFlags ... flags) {
+ boolean changed = false;
+ for (PlayerFlags flag : flags) {
+ changed |= flagsList.get(flag.getFlag());
+ flagsList.clear(flag.getFlag());
+ }
+ if (changed)
+ flagsList.sendDeltaMessage(target);
+ }
+
+ public void toggleFlag(SWGObject target, PlayerFlags ... flags) {
+ for (PlayerFlags flag : flags)
+ flagsList.flip(flag.getFlag());
+ flagsList.sendDeltaMessage(target);
+ }
+
+ public void createBaseline3(Player target, BaselineBuilder bb) {
+ bb.addObject(flagsList); // 4 flags -- 5
+ bb.addObject(profileFlags); // 4 flags -- 6
+ bb.addAscii(title); // 7
+ bb.addInt(bornDate); // Born Date -- 4001 = 12/15/2011 || Number of days after 12/31/2000 -- 8
+ bb.addInt(playTime); // 9
+ bb.addInt(professionIcon); // 10
+ bb.addAscii(profession); // 11
+ bb.addInt(gcwPoints); // 12
+ bb.addInt(pvpKills); // 13
+ bb.addLong(lifetimeGcwPoints); // 14
+ bb.addInt(lifetimePvpKills); // 15
+ bb.addObject(collectionBadges); // 16
+ bb.addObject(collectionBadges2); // 17
+ bb.addBoolean(showBackpack); // 18
+ bb.addBoolean(showHelmet); // 19
+
+ bb.incrementOperandCount(15);
+ }
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ flagsList.save(stream);
+ profileFlags.save(stream);
+ collectionBadges.save(stream);
+ stream.addAscii(title);
+ stream.addAscii(profession);
+ stream.addInt(bornDate);
+ stream.addInt(playTime);
+ stream.addInt(professionIcon);
+ stream.addInt(gcwPoints);
+ stream.addInt(pvpKills);
+ stream.addInt(lifetimePvpKills);
+ stream.addLong(lifetimeGcwPoints);
+ stream.addBoolean(showBackpack);
+ stream.addBoolean(showHelmet);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ flagsList.read(stream);
+ profileFlags.read(stream);
+ collectionBadges.read(stream);
+ title = stream.getAscii();
+ profession = stream.getAscii();
+ bornDate = stream.getInt();
+ playTime = stream.getInt();
+ professionIcon = stream.getInt();
+ gcwPoints = stream.getInt();
+ pvpKills = stream.getInt();
+ lifetimePvpKills = stream.getInt();
+ lifetimeGcwPoints = stream.getLong();
+ showBackpack = stream.getBoolean();
+ showHelmet = stream.getBoolean();
+ }
+
+}
diff --git a/src/resources/objects/player/PlayerObjectSharedNP.java b/src/resources/objects/player/PlayerObjectSharedNP.java
new file mode 100644
index 000000000..b48f0ccfc
--- /dev/null
+++ b/src/resources/objects/player/PlayerObjectSharedNP.java
@@ -0,0 +1,175 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.objects.player;
+
+import resources.network.BaselineBuilder;
+import resources.network.NetBufferStream;
+import resources.persistable.Persistable;
+import resources.player.AccessLevel;
+import resources.player.Player;
+
+class PlayerObjectSharedNP implements Persistable {
+
+ private int adminTag = 0;
+ private int currentRank = 0;
+ private float rankProgress = 0;
+ private int highestRebelRank = 0;
+ private int highestImperialRank = 0;
+ private int gcwNextUpdate = 0;
+ private String home = "";
+ private boolean citizen = false;
+
+ public PlayerObjectSharedNP() {
+
+ }
+
+ public int getAdminTag() {
+ return adminTag;
+ }
+
+ public void setAdminTag(AccessLevel access) {
+ switch (access) {
+ case PLAYER: adminTag = 0; break;
+ case CSR: adminTag = 1; break;
+ case DEV: adminTag = 2; break;
+ case WARDEN: adminTag = 3; break;
+ case QA: adminTag = 4; break;
+ }
+ }
+
+ public void setAdminTag(int tag) {
+ this.adminTag = tag;
+ }
+
+ public int getCurrentRank() {
+ return currentRank;
+ }
+
+ public void setCurrentRank(int currentRank) {
+ this.currentRank = currentRank;
+ }
+
+ public float getRankProgress() {
+ return rankProgress;
+ }
+
+ public void setRankProgress(float rankProgress) {
+ this.rankProgress = rankProgress;
+ }
+
+ public int getHighestRebelRank() {
+ return highestRebelRank;
+ }
+
+ public void setHighestRebelRank(int highestRebelRank) {
+ this.highestRebelRank = highestRebelRank;
+ }
+
+ public int getHighestImperialRank() {
+ return highestImperialRank;
+ }
+
+ public void setHighestImperialRank(int highestImperialRank) {
+ this.highestImperialRank = highestImperialRank;
+ }
+
+ public int getGcwNextUpdate() {
+ return gcwNextUpdate;
+ }
+
+ public void setGcwNextUpdate(int gcwNextUpdate) {
+ this.gcwNextUpdate = gcwNextUpdate;
+ }
+
+ public String getHome() {
+ return home;
+ }
+
+ public void setHome(String home) {
+ this.home = home;
+ }
+
+ public boolean isCitizen() {
+ return citizen;
+ }
+
+ public void setCitizen(boolean citizen) {
+ this.citizen = citizen;
+ }
+
+ public void createBaseline6(Player target, BaselineBuilder bb) {
+ bb.addByte(adminTag); // Admin Tag (0 = none, 1 = CSR, 2 = Developer, 3 = Warden, 4 = QA) -- 2
+ bb.addInt(currentRank); // 3
+ bb.addFloat(rankProgress); // 4
+ bb.addInt(highestImperialRank); // 5
+ bb.addInt(highestRebelRank); // 6
+ bb.addInt(gcwNextUpdate); // 7
+ bb.addAscii(home); // 8
+ bb.addBoolean(citizen); // 9
+ bb.addAscii(""); // City Region Defender 'region' -- 10
+ bb.addBoolean(false); // City Region Defender byte #1
+ bb.addBoolean(false); // City Region Defender byte #2
+ bb.addAscii(""); // Guild Region Defender 'region' -- 11
+ bb.addBoolean(false); // Guild Region Defender byte #1
+ bb.addBoolean(false); // Guild Region Defender byte #2
+ bb.addLong(0); // General? -- 12
+ bb.addAscii(""); // 13
+ bb.addInt(0); // Citizen Rank Title? 6 bytes -- 14
+ bb.addInt(0); // Environment Flags Override -- 15
+ bb.addAscii(""); // Vehicle Attack Command -- 16
+
+ bb.incrementOperandCount(15);
+ }
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addByte(0);
+ stream.addInt(adminTag);
+ stream.addInt(currentRank);
+ stream.addFloat(rankProgress);
+ stream.addInt(highestRebelRank);
+ stream.addInt(highestImperialRank);
+ stream.addInt(gcwNextUpdate);
+ stream.addAscii(home);
+ stream.addBoolean(citizen);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ stream.getByte();
+ adminTag = stream.getInt();
+ currentRank = stream.getInt();
+ rankProgress = stream.getFloat();
+ highestRebelRank = stream.getInt();
+ highestImperialRank = stream.getInt();
+ gcwNextUpdate = stream.getInt();
+ home = stream.getAscii();
+ citizen = stream.getBoolean();
+ }
+
+}
diff --git a/src/resources/objects/resource/ResourceContainerObject.java b/src/resources/objects/resource/ResourceContainerObject.java
index aad4b1155..c16475891 100644
--- a/src/resources/objects/resource/ResourceContainerObject.java
+++ b/src/resources/objects/resource/ResourceContainerObject.java
@@ -29,13 +29,12 @@ package resources.objects.resource;
import network.packets.swg.zone.baselines.Baseline.BaselineType;
import resources.network.BaselineBuilder;
+import resources.network.NetBufferStream;
import resources.objects.tangible.TangibleObject;
import resources.player.Player;
public class ResourceContainerObject extends TangibleObject {
- private static final long serialVersionUID = 1L;
-
private long resourceType = 0;
private String resourceName = "";
private int quantity = 0;
@@ -132,4 +131,37 @@ public class ResourceContainerObject extends TangibleObject {
return hash;
}
+ /*
+ private long resourceType = 0;
+ private String resourceName = "";
+ private int quantity = 0;
+ private int maxQuantity = 0;
+ private String parentName = "";
+ private String displayName = "";
+ */
+
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ stream.addInt(quantity);
+ stream.addInt(maxQuantity);
+ stream.addLong(resourceType);
+ stream.addAscii(parentName);
+ stream.addUnicode(resourceName);
+ stream.addUnicode(displayName);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ quantity = stream.getInt();
+ maxQuantity = stream.getInt();
+ resourceType = stream.getLong();
+ parentName = stream.getAscii();
+ resourceName = stream.getUnicode();
+ displayName = stream.getUnicode();
+ }
+
}
diff --git a/src/resources/objects/ship/ShipObject.java b/src/resources/objects/ship/ShipObject.java
index 48f96db92..f8e3c04e7 100644
--- a/src/resources/objects/ship/ShipObject.java
+++ b/src/resources/objects/ship/ShipObject.java
@@ -28,14 +28,25 @@
package resources.objects.ship;
import network.packets.swg.zone.baselines.Baseline.BaselineType;
+import resources.network.NetBufferStream;
import resources.objects.tangible.TangibleObject;
public class ShipObject extends TangibleObject {
- private static final long serialVersionUID = 1L;
-
public ShipObject(long objectId) {
super(objectId, BaselineType.SHIP);
}
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ }
+
}
diff --git a/src/resources/objects/sound/SoundObject.java b/src/resources/objects/sound/SoundObject.java
index 6569a615d..da7ddfc1f 100644
--- a/src/resources/objects/sound/SoundObject.java
+++ b/src/resources/objects/sound/SoundObject.java
@@ -27,14 +27,25 @@
***********************************************************************************/
package resources.objects.sound;
+import resources.network.NetBufferStream;
import resources.objects.staticobject.StaticObject;
public class SoundObject extends StaticObject {
- private static final long serialVersionUID = 1L;
-
public SoundObject(long objectId) {
super(objectId);
}
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ }
+
}
diff --git a/src/resources/objects/staticobject/StaticObject.java b/src/resources/objects/staticobject/StaticObject.java
index a577bc8ca..aac473fba 100644
--- a/src/resources/objects/staticobject/StaticObject.java
+++ b/src/resources/objects/staticobject/StaticObject.java
@@ -27,14 +27,25 @@
***********************************************************************************/
package resources.objects.staticobject;
+import resources.network.NetBufferStream;
import resources.objects.creature.CreatureObject;
public class StaticObject extends CreatureObject {
- private static final long serialVersionUID = 1L;
-
public StaticObject(long objectId) {
super(objectId);
}
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ }
+
}
diff --git a/src/resources/objects/tangible/TangibleObject.java b/src/resources/objects/tangible/TangibleObject.java
index a663cd214..764e2cc2f 100644
--- a/src/resources/objects/tangible/TangibleObject.java
+++ b/src/resources/objects/tangible/TangibleObject.java
@@ -41,6 +41,7 @@ import resources.collections.SWGMap;
import resources.collections.SWGSet;
import resources.network.BaselineBuilder;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
import resources.objects.SWGObject;
import resources.objects.creature.CreatureObject;
import resources.player.Player;
@@ -48,8 +49,6 @@ import utilities.Encoder.StringType;
public class TangibleObject extends SWGObject {
- private static final long serialVersionUID = 1L;
-
private byte [] appearanceData = new byte[0];
private int maxHitPoints = 1000;
private int components = 0;
@@ -315,5 +314,44 @@ public class TangibleObject extends SWGObject {
new FactionIntent(this, FactionIntentType.FLAGUPDATE).broadcast();
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ stream.addArray(appearanceData);
+ stream.addInt(maxHitPoints);
+ stream.addInt(components);
+ stream.addBoolean(inCombat);
+ stream.addInt(condition);
+ stream.addInt(pvpFlags);
+ stream.addAscii(pvpStatus.name());
+ stream.addAscii(pvpFaction.name());
+ stream.addBoolean(visibleGmOnly);
+ stream.addArray(objectEffects);
+ stream.addInt(optionFlags);
+ stream.addMap(effectsMap, (e) -> {
+ stream.addAscii(e.getKey());
+ stream.addAscii(e.getValue());
+ });
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ appearanceData = stream.getArray();
+ maxHitPoints = stream.getInt();
+ components = stream.getInt();
+ inCombat = stream.getBoolean();
+ condition = stream.getInt();
+ pvpFlags = stream.getInt();
+ pvpStatus = PvpStatus.valueOf(stream.getAscii());
+ pvpFaction = PvpFaction.valueOf(stream.getAscii());
+ visibleGmOnly = stream.getBoolean();
+ objectEffects = stream.getArray();
+ optionFlags = stream.getInt();
+ stream.getList((i) -> effectsMap.put(stream.getAscii(), stream.getAscii()));
+ }
}
\ No newline at end of file
diff --git a/src/resources/objects/waypoint/WaypointObject.java b/src/resources/objects/waypoint/WaypointObject.java
index 292d7a9c7..9fee6f3f7 100644
--- a/src/resources/objects/waypoint/WaypointObject.java
+++ b/src/resources/objects/waypoint/WaypointObject.java
@@ -33,14 +33,13 @@ import resources.Location;
import resources.Terrain;
import resources.encodables.OutOfBandData;
import resources.encodables.OutOfBandPackage;
+import resources.network.NetBufferStream;
import resources.objects.intangible.IntangibleObject;
import resources.player.Player;
import java.nio.ByteBuffer;
public class WaypointObject extends IntangibleObject implements OutOfBandData {
-
- private static final long serialVersionUID = 1L;
private long cellId;
private String name = "New Waypoint";
@@ -116,6 +115,26 @@ public class WaypointObject extends IntangibleObject implements OutOfBandData {
active = Packet.getBoolean(data);
setLocation(loc);
}
+
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ stream.addBoolean(active);
+ stream.addLong(cellId);
+ stream.addAscii(name);
+ stream.addAscii(color.name());
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ active = stream.getBoolean();
+ cellId = stream.getLong();
+ name = stream.getAscii();
+ color = WaypointColor.valueOf(stream.getAscii());
+ }
@Override
public OutOfBandPackage.Type getOobType() {
diff --git a/src/resources/objects/weapon/WeaponObject.java b/src/resources/objects/weapon/WeaponObject.java
index bc3c81474..6859790f7 100644
--- a/src/resources/objects/weapon/WeaponObject.java
+++ b/src/resources/objects/weapon/WeaponObject.java
@@ -30,13 +30,12 @@ package resources.objects.weapon;
import network.packets.swg.zone.baselines.Baseline.BaselineType;
import resources.network.BaselineBuilder;
import resources.network.NetBuffer;
+import resources.network.NetBufferStream;
import resources.objects.tangible.TangibleObject;
import resources.player.Player;
public class WeaponObject extends TangibleObject {
- private static final long serialVersionUID = 1L;
-
private float attackSpeed = 0.5f;
private float maxRange = 5f;
private WeaponType type = WeaponType.UNARMED;
@@ -124,4 +123,22 @@ public class WeaponObject extends TangibleObject {
type = WeaponType.getWeaponType(buffer.getInt());
}
+ @Override
+ public void save(NetBufferStream stream) {
+ super.save(stream);
+ stream.addByte(0);
+ stream.addFloat(attackSpeed);
+ stream.addFloat(maxRange);
+ stream.addAscii(type.name());
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+ super.read(stream);
+ stream.getByte();
+ attackSpeed = stream.getFloat();
+ maxRange = stream.getFloat();
+ type = WeaponType.valueOf(stream.getAscii());
+ }
+
}
diff --git a/src/resources/persistable/InputPersistenceStream.java b/src/resources/persistable/InputPersistenceStream.java
new file mode 100644
index 000000000..ef37b6f1b
--- /dev/null
+++ b/src/resources/persistable/InputPersistenceStream.java
@@ -0,0 +1,111 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.persistable;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import resources.network.NetBufferStream;
+
+public class InputPersistenceStream extends InputStream {
+
+ private final InputStream is;
+
+ public InputPersistenceStream(InputStream is) {
+ this.is = is;
+ }
+
+ public int read() {
+ throw new UnsupportedOperationException("Unable to read raw data");
+ }
+
+ public int read(byte[] b) {
+ throw new UnsupportedOperationException("Unable to read raw data");
+ }
+
+ public int read(byte[] b, int off, int len) {
+ throw new UnsupportedOperationException("Unable to read raw data");
+ }
+
+ public T read(PersistableCreator creator) throws IOException {
+ int size = readInt();
+ try (NetBufferStream stream = new NetBufferStream(size)) {
+ byte [] buffer = new byte[Math.min(size, 2048)];
+ int pos = 0;
+ while (pos < size) {
+ int n = is.read(buffer, 0, Math.min(size-pos, buffer.length));
+ if (n == -1)
+ break;
+ stream.write(buffer, 0, n);
+ pos += n;
+ }
+ stream.position(0);
+ return creator.create(stream);
+ }
+ }
+
+ public long skip(long n) throws IOException {
+ return is.skip(n);
+ }
+
+ public int available() throws IOException {
+ return is.available();
+ }
+
+ public void close() throws IOException {
+ is.close();
+ }
+
+ public void mark(int readlimit) {
+ is.mark(readlimit);
+ }
+
+ public void reset() throws IOException {
+ is.reset();
+ }
+
+ public boolean markSupported() {
+ return is.markSupported();
+ }
+
+ private int readInt() throws IOException {
+ int ret = 0;
+ int b;
+ for (int i = 0; i < 4; i++) {
+ b = is.read();
+ if (b != -1)
+ ret |= b << (i * 8);
+ }
+ return ret;
+ }
+
+ public static interface PersistableCreator {
+ T create(NetBufferStream stream);
+ }
+
+}
diff --git a/src/resources/persistable/OutputPersistenceStream.java b/src/resources/persistable/OutputPersistenceStream.java
new file mode 100644
index 000000000..60ad7d1f6
--- /dev/null
+++ b/src/resources/persistable/OutputPersistenceStream.java
@@ -0,0 +1,98 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.persistable;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import resources.network.NetBufferStream;
+
+public class OutputPersistenceStream extends OutputStream implements Closeable {
+
+ private final OutputStream os;
+
+ public OutputPersistenceStream(OutputStream os) {
+ this.os = os;
+ }
+
+ @Override
+ public void write(int b) {
+ throw new UnsupportedOperationException("Unable to write raw data");
+ }
+
+ @Override
+ public void write(byte[] b) {
+ throw new UnsupportedOperationException("Unable to write raw data");
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) {
+ throw new UnsupportedOperationException("Unable to write raw data");
+ }
+
+ public void write(Persistable p) throws IOException {
+ NetBufferStream buffer = new NetBufferStream();
+ p.save(buffer);
+ writeInt(buffer.size());
+ os.write(buffer.array(), 0, buffer.size());
+ flush();
+ buffer.close();
+ }
+
+ public void write(T obj, PersistableSaver saver) throws IOException {
+ NetBufferStream buffer = new NetBufferStream();
+ saver.save(obj, buffer);
+ writeInt(buffer.size());
+ os.write(buffer.array(), 0, buffer.size());
+ flush();
+ buffer.close();
+ }
+
+ @Override
+ public void flush() throws IOException {
+ os.flush();
+ }
+
+ @Override
+ public void close() throws IOException {
+ os.close();
+ }
+
+ private void writeInt(int i) throws IOException {
+ os.write(i >>> 0);
+ os.write(i >>> 8);
+ os.write(i >>> 16);
+ os.write(i >>> 24);
+ }
+
+ public static interface PersistableSaver {
+ void save(T obj, NetBufferStream stream);
+ }
+
+}
diff --git a/src/resources/persistable/Persistable.java b/src/resources/persistable/Persistable.java
new file mode 100644
index 000000000..c4836d0bd
--- /dev/null
+++ b/src/resources/persistable/Persistable.java
@@ -0,0 +1,35 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.persistable;
+
+import resources.network.NetBufferStream;
+
+public interface Persistable {
+ void save(NetBufferStream stream);
+ void read(NetBufferStream stream);
+}
diff --git a/src/resources/persistable/SWGObjectFactory.java b/src/resources/persistable/SWGObjectFactory.java
new file mode 100644
index 000000000..7dabdf502
--- /dev/null
+++ b/src/resources/persistable/SWGObjectFactory.java
@@ -0,0 +1,50 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.persistable;
+
+import resources.network.NetBufferStream;
+import resources.objects.SWGObject;
+import services.objects.ObjectCreator;
+
+public class SWGObjectFactory {
+
+ public static void save(SWGObject obj, NetBufferStream stream) {
+ stream.addLong(obj.getObjectId());
+ stream.addAscii(obj.getTemplate());
+ obj.save(stream);
+ }
+
+ public static SWGObject create(NetBufferStream stream) {
+ long objectId = stream.getLong();
+ String template = stream.getAscii();
+ SWGObject obj = ObjectCreator.createObjectFromTemplate(objectId, template);
+ obj.read(stream);
+ return obj;
+ }
+
+}
diff --git a/src/resources/server_info/CachedObjectDatabase.java b/src/resources/server_info/CachedObjectDatabase.java
index cf1ddb57f..34c743969 100644
--- a/src/resources/server_info/CachedObjectDatabase.java
+++ b/src/resources/server_info/CachedObjectDatabase.java
@@ -27,55 +27,42 @@
***********************************************************************************/
package resources.server_info;
-import java.io.EOFException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
+import java.util.HashSet;
+import java.util.Set;
-public class CachedObjectDatabase extends ObjectDatabase {
+import resources.persistable.InputPersistenceStream;
+import resources.persistable.InputPersistenceStream.PersistableCreator;
+import resources.persistable.OutputPersistenceStream;
+import resources.persistable.OutputPersistenceStream.PersistableSaver;
+import resources.persistable.Persistable;
+
+public class CachedObjectDatabase extends ObjectDatabase {
- private final Map objects;
+ private final PersistableCreator creator;
+ private final PersistableSaver saver;
+ private final Set objects;
private boolean loaded;
- public CachedObjectDatabase(String filename) {
+ public CachedObjectDatabase(String filename, PersistableCreator creator, PersistableSaver saver) {
super(filename);
- objects = new HashMap();
+ this.creator = creator;
+ this.saver = saver;
+ objects = new HashSet<>();
loaded = false;
}
- public synchronized V put(String key, V value) {
- return put(hash(key), value);
- }
-
- public synchronized V put(long key, V value) {
+ public synchronized boolean add(V value) {
synchronized (objects) {
- return objects.put(key, value);
+ return objects.add(value);
}
}
- public synchronized V get(String key) {
- return get(hash(key));
- }
-
- public synchronized V get(long key) {
+ public synchronized boolean remove(V obj) {
synchronized (objects) {
- return objects.get(key);
- }
- }
-
- public synchronized V remove(String key) {
- return get(hash(key));
- }
-
- public synchronized V remove(long key) {
- synchronized (objects) {
- return objects.remove(key);
+ return objects.remove(obj);
}
}
@@ -85,105 +72,70 @@ public class CachedObjectDatabase extends ObjectDatabase
}
}
- public synchronized boolean contains(long key) {
+ public synchronized boolean contains(V obj) {
synchronized (objects) {
- return objects.containsKey(key);
+ return objects.contains(obj);
}
}
- public synchronized boolean contains(String key) {
- return contains(hash(key));
- }
-
public synchronized boolean save() {
if (!loaded) {
Log.e("CachedObjectDatabase", "Not saving '" + getFile() + "', file not loaded yet!");
return false;
}
- ObjectOutputStream oos = null;
- try {
- oos = new ObjectOutputStream(new FileOutputStream(getFile()));
+ try (OutputPersistenceStream os = new OutputPersistenceStream(new FileOutputStream(getFile()))) {
synchronized (objects) {
- for (Entry e : objects.entrySet()) {
- oos.writeLong(e.getKey());
- oos.writeObject(e.getValue());
- }
+ for (V obj : objects)
+ os.write(obj, saver);
}
- oos.close();
} catch (IOException e) {
Log.e("CachedObjectDatabase", "Error while saving file. IOException: " + e.getMessage());
- e.printStackTrace();
+ Log.e("CachedObjectDatabase", e);
return false;
- } finally {
- if (oos != null) {
- try {
- oos.close();
- } catch (Exception e) {
- Log.e("CachedObjectDatabase", "Failed to close stream while saving! " + e.getMessage());
- e.printStackTrace();
- }
- }
}
return true;
}
- public synchronized void clearCache() {
- synchronized (objects) {
- objects.clear();
- loaded = false;
- }
- }
-
public synchronized boolean load() {
if (!fileExists()) {
Log.e("CachedObjectDatabase", "load() - file '%s' does not exist!", getFile());
+ loaded = true;
return false;
}
- ObjectInputStream ois = null;
- try {
- ois = new ObjectInputStream(new FileInputStream(getFile()));
+ try (InputPersistenceStream is = new InputPersistenceStream(new FileInputStream(getFile()))) {
synchronized (objects) {
- while (ois.available() >= 8) {
- long key = ois.readLong();
- @SuppressWarnings("unchecked")
- V val = (V) ois.readObject();
- objects.put(key, val);
- }
+ while (is.available() > 0)
+ objects.add(is.read(creator));
+ loaded = true;
}
- loaded = true;
- } catch (EOFException e) {
- loaded = true;
- } catch (IOException | ClassNotFoundException | ClassCastException e) {
- Log.e("CachedObjectDatabase", "load() - unable to load with error: %s - %s", e.getClass().getSimpleName(), e.getMessage());
+ } catch (IOException e) {
+ Log.e("CachedObjectDatabase", "Error while loading file. IOException: " + e.getMessage());
+ Log.e("CachedObjectDatabase", e);
return false;
- } finally {
- if (ois != null) {
- try {
- ois.close();
- } catch (Exception e) {
- Log.e("CachedObjectDatabase", "Failed to close stream when loading! " + e.getMessage());
- Log.e("CachedObjectDatabase", e);
- }
- }
}
return true;
}
+ public synchronized void clearObjects() {
+ synchronized (objects) {
+ objects.clear();
+ }
+ }
+
public synchronized void traverse(Traverser traverser) {
synchronized (objects) {
- for (V obj : objects.values())
+ for (V obj : objects)
traverser.process(obj);
}
}
- private static final long hash(String string) {
- long h = 1125899906842597L;
- int len = string.length();
-
- for (int i = 0; i < len; i++) {
- h = 31*h + string.charAt(i);
+ public synchronized void traverseInterruptable(InterruptableTraverser traverser) {
+ synchronized (objects) {
+ for (V obj : objects) {
+ if (!traverser.process(obj))
+ return;
+ }
}
- return h;
}
}
diff --git a/src/resources/server_info/ObjectDatabase.java b/src/resources/server_info/ObjectDatabase.java
index 6166de8b8..db336fb46 100644
--- a/src/resources/server_info/ObjectDatabase.java
+++ b/src/resources/server_info/ObjectDatabase.java
@@ -29,14 +29,14 @@ package resources.server_info;
import java.io.File;
import java.io.IOException;
-import java.io.Serializable;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
+import resources.persistable.Persistable;
import utilities.ThreadUtilities;
-public abstract class ObjectDatabase {
+public abstract class ObjectDatabase {
private final File file;
private final ScheduledExecutorService autosaveService;
@@ -103,21 +103,21 @@ public abstract class ObjectDatabase {
return file.isFile();
}
- public abstract V put(String key, V value);
- public abstract V put(long key, V value);
- public abstract V get(String key);
- public abstract V get(long key);
- public abstract V remove(String key);
- public abstract V remove(long key);
+ public abstract boolean add(V obj);
+ public abstract boolean remove(V obj);
public abstract int size();
- public abstract boolean contains(long key);
- public abstract boolean contains(String key);
+ public abstract boolean contains(V obj);
public abstract boolean load();
public abstract boolean save();
public abstract void traverse(Traverser traverser);
+ public abstract void traverseInterruptable(InterruptableTraverser traverser);
public interface Traverser {
public void process(V element);
}
+ public interface InterruptableTraverser {
+ public boolean process(V element);
+ }
+
}
diff --git a/src/resources/server_info/UncachedObjectDatabase.java b/src/resources/server_info/UncachedObjectDatabase.java
deleted file mode 100644
index 1ca1554be..000000000
--- a/src/resources/server_info/UncachedObjectDatabase.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/***********************************************************************************
-* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
-* *
-* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
-* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
-* Our goal is to create an emulator which will provide a server for players to *
-* continue playing a game similar to the one they used to play. We are basing *
-* it on the final publish of the game prior to end-game events. *
-* *
-* This file is part of Holocore. *
-* *
-* -------------------------------------------------------------------------------- *
-* *
-* Holocore is free software: you can redistribute it and/or modify *
-* it under the terms of the GNU Affero General Public License as *
-* published by the Free Software Foundation, either version 3 of the *
-* License, or (at your option) any later version. *
-* *
-* Holocore 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 Affero General Public License for more details. *
-* *
-* You should have received a copy of the GNU Affero General Public License *
-* along with Holocore. If not, see . *
-* *
-***********************************************************************************/
-package resources.server_info;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.EOFException;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-import java.io.OutputStream;
-import java.io.Serializable;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Map.Entry;
-
-public class UncachedObjectDatabase extends ObjectDatabase {
-
- private final Map objectIndex;
- private final Map objects;
- private boolean loaded;
-
- public UncachedObjectDatabase(String filename) {
- super(filename);
- objectIndex = new HashMap();
- objects = new HashMap();
- loaded = false;
- loadPointers();
- }
-
- public synchronized V put(String key, V value) {
- return put(hash(key), value);
- }
-
- public synchronized V put(long key, V value) {
- synchronized (objects) {
- return objects.put(key, value);
- }
- }
-
- public synchronized V get(String key) {
- return get(hash(key));
- }
-
- public synchronized V get(long key) {
- V val = null;
- synchronized (objects) {
- val = objects.get(key);
- }
- if (val == null)
- return getFromDB(key);
- return val;
- }
-
- public synchronized V remove(String key) {
- return get(hash(key));
- }
-
- public synchronized V remove(long key) {
- synchronized (objects) {
- return objects.remove(key);
- }
- }
-
- public synchronized int size() {
- synchronized (objectIndex) {
- return objectIndex.size();
- }
- }
-
- public synchronized boolean contains(long key) {
- synchronized (objectIndex) {
- return objectIndex.containsKey(key);
- }
- }
-
- public synchronized boolean contains(String key) {
- return contains(hash(key));
- }
-
- public synchronized boolean save() {
- if (!loaded) {
- Log.e("UncachedObjectDatabase", "Not saving '" + getFile() + "', file not loaded yet!");
- return false;
- }
- DataOutputStream dos = null;
- try {
- File file = getFile();
- dos = new DataOutputStream(new FileOutputStream(file + ".tmp"));
- loadCachedAndSave(dos, loadUncachedAndSave(dos, 0));
- moveFile(file+".tmp", file.getAbsolutePath());
- } catch (IOException e) {
- Log.e("UncachedObjectDatabase", "Error while saving file. IOException: " + e.getMessage());
- e.printStackTrace();
- return false;
- } finally {
- safeClose(dos);
- }
- return true;
- }
-
- public synchronized void clearCache() {
- synchronized (objects) {
- objects.clear();
- }
- }
-
- public synchronized boolean load() {
- return loadToCache();
- }
-
- public synchronized boolean loadToCache() {
- if (!fileExists())
- return false;
- DataInputStream dis = null;
- try {
- dis = new DataInputStream(new FileInputStream(getFile()));
- synchronized (objects) {
- while (dis.available() >= 12) {
- long key = dis.readLong();
- int length = dis.readInt();
- if (!objects.containsKey(key)) {
- objects.put(key, readObject(dis));
- } else {
- if (dis.skip(length) != length)
- throw new IOException("Failed to skip " + length + " bytes");
- }
- }
- }
- dis.close();
- } catch (IOException | ClassNotFoundException | ClassCastException e) {
- Log.e("UncachedObjectDatabase", "Unable to load cache with error: %s - %s", e.getClass().getSimpleName(), e.getMessage());
- return false;
- } finally {
- safeClose(dis);
- }
- return true;
- }
-
- public synchronized void traverse(Traverser traverser) {
- DataInputStream dis = null;
- try {
- save();
- dis = new DataInputStream(new FileInputStream(getFile()));
- synchronized (objects) {
- while (dis.available() >= 12) {
- V v = objects.get(dis.readLong());
- int length = dis.readInt();
- if (v != null) {
- if (dis.skip(length) != length)
- throw new IOException("Failed to skip " + length + " bytes");
- } else
- v = readObject(dis);
- traverser.process(v);
- }
- }
- } catch (IOException | ClassNotFoundException e) {
- Log.e("UncachedObjectDatabase", "Unable to traverse with error: %s - %s", e.getClass().getSimpleName(), e.getMessage());
- }
- safeClose(dis);
- }
-
- public synchronized void traverseCache(Traverser traverser) {
- synchronized (objects) {
- for (V obj : objects.values())
- traverser.process(obj);
- }
- }
-
- private void moveFile(String source, String destination) throws IOException {
- moveFile(source, destination, 4096);
- }
-
- private void moveFile(String source, String destination, int bufferSize) throws IOException {
- File sFile = new File(source);
- File dFile = new File(destination);
-
- InputStream inStream = null;
- OutputStream outStream = null;
- try {
- inStream = new FileInputStream(sFile);
- outStream = new FileOutputStream(dFile);
-
- byte [] buffer = new byte[bufferSize];
- int length = 0;
- while ((length = inStream.read(buffer)) > 0){
- outStream.write(buffer, 0, length);
- }
- } finally {
- safeClose(inStream);
- safeClose(outStream);
- }
- if (!sFile.delete())
- Log.e("UncachedObjectDatabase", "Failed to delete source file when moving %s -> %s", sFile, dFile);
- }
-
- private V getFromDB(long key) {
- long index = getObjectIndex(key);
- if (index == -1)
- return null;
- V val = readObject(index);
- synchronized (objects) {
- objects.put(key, val);
- }
- return val;
- }
-
- private long getObjectIndex(long key) {
- synchronized (objectIndex) {
- Long index = objectIndex.get(key);
- if (index == null)
- return -1;
- return index;
- }
- }
-
- private V readObject(long index) {
- FileInputStream fis = null;
- V val = null;
- try {
- fis = new FileInputStream(getFile());
- if (fis.skip(index+12) != index+12)
- throw new IOException("Failed to skip " + (index+12) + " bytes");
- val = readObject(fis);
- } catch (IOException | ClassNotFoundException e) {
- val = null;
- } finally {
- safeClose(fis);
- }
- return val;
- }
-
- @SuppressWarnings("unchecked")
- private V readObject(InputStream is) throws ClassNotFoundException, IOException {
- return (V) new ObjectInputStream(is).readObject();
- }
-
- private byte [] writeObject(Object o) throws IOException {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- new ObjectOutputStream(bos).writeObject(o);
- return bos.toByteArray();
- }
-
- private long writeObject(DataOutputStream dos, long key, byte [] data) throws IOException {
- dos.writeLong(key);
- dos.writeInt(data.length);
- dos.write(data);
- return 12 + data.length;
- }
-
- private long loadUncachedAndSave(DataOutputStream dos, long index) {
- DataInputStream dis = null;
- try {
- dis = new DataInputStream(new FileInputStream(getFile()));
- while (dis.available() >= 12) {
- long key = dis.readLong();
- int length = dis.readInt();
- synchronized (objects) {
- if (objects.containsKey(key)) {
- if (dis.skip(length) != length)
- throw new IOException("Failed to skip " + length + " bytes");
- } else {
- byte [] data = new byte[length];
- int len = 0;
- while (len < length) {
- len += dis.read(data, len, length-len);
- }
- index += writeObject(dos, key, data);
- }
- }
- }
- } catch (IOException e) {
-
- } finally {
- safeClose(dis);
- }
- return index;
- }
-
- private long loadCachedAndSave(DataOutputStream dos, long index) throws IOException {
- synchronized (objectIndex) {
- synchronized (objects) {
- for (Entry e : objects.entrySet()) {
- long key = e.getKey().longValue();
- objectIndex.put(key, index);
- index += writeObject(dos, key, writeObject(e.getValue()));
- }
- }
- }
- return index;
- }
-
- private boolean loadPointers() {
- DataInputStream dis = null;
- try {
- dis = new DataInputStream(new FileInputStream(getFile()));
- long index = 0;
- while (index != -1) {
- index = loadObject(dis, index);
- }
- dis.close();
- loaded = true;
- } catch (EOFException e) {
- loaded = true;
- } catch (IOException e) {
- return false;
- } finally {
- safeClose(dis);
- }
- return true;
- }
-
- private long loadObject(DataInputStream dis, long index) throws IOException {
- if (dis.available() < 12)
- return -1;
- long key = dis.readLong();
- int length = dis.readInt();
- if (length < 0)
- return -1;
- if (dis.skip(length) != length)
- throw new IOException("Failed to skip " + length + " bytes");
- synchronized (objectIndex) {
- objectIndex.put(key, index);
- }
- return index + 12 + length;
- }
-
- private boolean safeClose(OutputStream os) {
- if (os == null)
- return false;
- try {
- os.close();
- } catch (IOException e) {
- return false;
- }
- return true;
- }
-
- private boolean safeClose(InputStream is) {
- if (is == null)
- return false;
- try {
- is.close();
- } catch (IOException e) {
- return false;
- }
- return true;
- }
-
- private static final long hash(String string) {
- long h = 1125899906842597L;
- int len = string.length();
-
- for (int i = 0; i < len; i++) {
- h = 31*h + string.charAt(i);
- }
- return h;
- }
-
-}
\ No newline at end of file
diff --git a/src/services/chat/ChatMailService.java b/src/services/chat/ChatMailService.java
index f09fd756a..7dd58654b 100644
--- a/src/services/chat/ChatMailService.java
+++ b/src/services/chat/ChatMailService.java
@@ -37,6 +37,7 @@ import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
+import java.util.concurrent.atomic.AtomicReference;
import network.packets.Packet;
import network.packets.swg.SWGPacket;
@@ -69,7 +70,7 @@ public class ChatMailService extends Service {
private int maxMailId;
public ChatMailService() {
- mails = new CachedObjectDatabase<>("odb/mails.db");
+ mails = new CachedObjectDatabase<>("odb/mails.db", Mail::create, Mail::saveMail);
chatLogs = RelationalServerFactory.getServerDatabase("chat/chat_log.db");
insertChatLog = chatLogs.prepareStatement("INSERT INTO chat_log VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
maxMailId = 1;
@@ -179,7 +180,7 @@ public class ChatMailService extends Service {
mail.setId(maxMailId++);
mail.setTimestamp((int) (new Date().getTime() / 1000));
mail.setOutOfBandPackage(request.getOutOfBandPackage());
- mails.put(mail.getId(), mail);
+ mails.add(mail);
if (recipient != null) {
sendPersistentMessage(recipient, mail, MailFlagType.HEADER_ONLY, galaxy);
@@ -203,14 +204,13 @@ public class ChatMailService extends Service {
maxMailId++;
mail.setTimestamp((int) (new Date().getTime() / 1000));
- mails.put(mail.getId(), mail);
+ mails.add(mail);
sendPersistentMessage(recipient, mail, MailFlagType.HEADER_ONLY, intent.getGalaxy());
}
private void handlePersistentMessageRequest(Player player, String galaxy, ChatRequestPersistentMessage request) {
- Mail mail = mails.get(request.getMailId());
-
+ Mail mail = getMail(request.getMailId());
if (mail == null)
return;
@@ -221,6 +221,18 @@ public class ChatMailService extends Service {
sendPersistentMessage(player, mail, MailFlagType.FULL_MESSAGE, galaxy);
}
+ private Mail getMail(int id) {
+ AtomicReference ref = new AtomicReference<>(null);
+ mails.traverseInterruptable((m) -> {
+ if (m.getId() == id) {
+ ref.set(m);
+ return false;
+ }
+ return true;
+ });
+ return ref.get();
+ }
+
private void sendPersistentMessageHeaders(Player player) {
if (player == null || player.getCreatureObject() == null)
return;
@@ -244,7 +256,7 @@ public class ChatMailService extends Service {
PlayerObject ghost = receiver.getPlayerObject();
if (ghost.isIgnored(mail.getSender())) {
- mails.remove(mail.getId());
+ mails.remove(mail);
return;
}
@@ -263,7 +275,7 @@ public class ChatMailService extends Service {
}
private void deletePersistentMessage(int mailId) {
- mails.remove(mailId);
+ mails.remove(getMail(mailId));
}
private void logChat(long sendId, String sendName, long recvId, String recvName, String subject, String message) {
diff --git a/src/services/chat/ChatRoomService.java b/src/services/chat/ChatRoomService.java
index dba42bd7f..1c5f107e5 100644
--- a/src/services/chat/ChatRoomService.java
+++ b/src/services/chat/ChatRoomService.java
@@ -104,7 +104,7 @@ public class ChatRoomService extends Service {
private int maxChatRoomId;
public ChatRoomService() {
- database = new CachedObjectDatabase<>("odb/chat_rooms.db");
+ database = new CachedObjectDatabase("odb/chat_rooms.db", ChatRoom::create, (r, s)->r.save(s));
roomMap = new ConcurrentHashMap<>();
messages = new ConcurrentHashMap<>();
chatLogs = RelationalServerFactory.getServerDatabase("chat/chat_log.db");
@@ -737,7 +737,7 @@ public class ChatRoomService extends Service {
roomMap.put(id, room);
if (persist)
- database.put(id, room);
+ database.add(room);
return room;
}
diff --git a/src/services/objects/ObjectManager.java b/src/services/objects/ObjectManager.java
index c1a41a3c3..a0514ce81 100644
--- a/src/services/objects/ObjectManager.java
+++ b/src/services/objects/ObjectManager.java
@@ -38,7 +38,6 @@ import java.util.concurrent.atomic.AtomicBoolean;
import intents.object.DestroyObjectIntent;
import intents.object.ObjectCreatedIntent;
import intents.object.ObjectTeleportIntent;
-import intents.player.DeleteCharacterIntent;
import intents.RequestZoneInIntent;
import intents.network.GalacticPacketIntent;
import network.packets.Packet;
@@ -49,6 +48,7 @@ import resources.control.Manager;
import resources.objects.SWGObject;
import resources.objects.creature.CreatureObject;
import resources.objects.custom.AIObject;
+import resources.persistable.SWGObjectFactory;
import resources.player.Player;
import resources.server_info.CachedObjectDatabase;
import resources.server_info.Log;
@@ -80,10 +80,10 @@ public class ObjectManager extends Manager {
radialService = new RadialService();
clientBuildoutService = new ClientBuildoutService();
- database = new CachedObjectDatabase("odb/objects.db");
+ database = new CachedObjectDatabase<>("odb/objects.db", SWGObjectFactory::create, SWGObjectFactory::save);
objectMap = new Hashtable<>(16*1024);
started = new AtomicBoolean(false);
-
+
addChildService(objectAwareness);
addChildService(mapManager);
addChildService(staticService);
@@ -95,7 +95,6 @@ public class ObjectManager extends Manager {
registerForIntent(ObjectTeleportIntent.TYPE);
registerForIntent(ObjectCreatedIntent.TYPE);
registerForIntent(DestroyObjectIntent.TYPE);
- registerForIntent(DeleteCharacterIntent.TYPE);
}
@Override
@@ -110,11 +109,9 @@ public class ObjectManager extends Manager {
long startLoad = System.nanoTime();
Log.i("ObjectManager", "Loading objects from ObjectDatabase...");
synchronized (database) {
- if (database.fileExists()) {
- if (!database.load())
- return false;
- database.traverse((obj) -> loadObject(obj));
- }
+ if (!database.load() && database.fileExists())
+ return false;
+ database.traverse((obj) -> loadObject(obj));
}
double loadTime = (System.nanoTime() - startLoad) / 1E6;
Log.i("ObjectManager", "Finished loading %d objects. Time: %fms", database.size(), loadTime);
@@ -220,8 +217,8 @@ public class ObjectManager extends Manager {
putObject(obj);
if (obj instanceof CreatureObject && ((CreatureObject) obj).isPlayer()) {
synchronized (database) {
- database.put(obj.getObjectId(), obj);
- database.save();
+ if (database.add(obj))
+ database.save();
}
}
if (!(obj instanceof AIObject))
@@ -278,7 +275,7 @@ public class ObjectManager extends Manager {
objectAwareness.remove(object);
object.clearAware();
synchronized (database) {
- if (database.remove(object.getObjectId()) != null)
+ if (database.remove(object))
database.save();
}
synchronized (objectMap) {
diff --git a/src/services/player/LoginService.java b/src/services/player/LoginService.java
index f84cd3617..59d61bef3 100644
--- a/src/services/player/LoginService.java
+++ b/src/services/player/LoginService.java
@@ -82,7 +82,6 @@ public class LoginService extends Service {
private PreparedStatement getCharacter;
private PreparedStatement getCharacters;
private PreparedStatement deleteCharacter;
- private boolean autoLogin;
public LoginService() {
random = new Random();
@@ -98,7 +97,6 @@ public class LoginService extends Service {
getCharacter = local.prepareStatement("SELECT * FROM characters WHERE LOWER(name) = LOWER(?)");
getCharacters = local.prepareStatement("SELECT * FROM characters WHERE userid = ?");
deleteCharacter = local.prepareStatement("DELETE FROM characters WHERE id = ?");
- autoLogin = getConfig(ConfigFile.NETWORK).getInt("AUTO-LOGIN", 0) == 1;
return super.initialize();
}
@@ -154,11 +152,6 @@ public class LoginService extends Service {
onLoginClientVersionError(player, id);
return;
}
- if (autoLogin) {
- String [] sessionHash = id.getPassword().split("-");
- id.setUsername(sessionHash[0]);
- id.setPassword(sessionHash[1]);
- }
synchronized (getUser) {
try {
getUser.setString(1, id.getUsername());
diff --git a/test/resources/TestResources.java b/test/resources/TestResources.java
index 8bf21fabe..8037a5809 100644
--- a/test/resources/TestResources.java
+++ b/test/resources/TestResources.java
@@ -36,7 +36,7 @@ import resources.collections.TestSWGBitSet;
import resources.collections.TestSWGFlag;
import resources.network.TestLittleEndianDataOutputStream;
import resources.objects.quadtree.TestQuadTree;
-import resources.server_info.TestObjectDatabase;
+import resources.persistable.TestPersistable;
import resources.services.TestConfig;
@RunWith(Suite.class)
@@ -46,7 +46,7 @@ import resources.services.TestConfig;
TestSWGBitSet.class,
TestWeatherType.class,
TestQuadTree.class,
- TestObjectDatabase.class,
+ TestPersistable.class,
TestConfig.class,
TestQuaternion.class,
TestLittleEndianDataOutputStream.class
diff --git a/test/resources/persistable/TestPersistable.java b/test/resources/persistable/TestPersistable.java
new file mode 100644
index 000000000..879e7a429
--- /dev/null
+++ b/test/resources/persistable/TestPersistable.java
@@ -0,0 +1,41 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.persistable;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+import org.junit.runners.Suite.SuiteClasses;
+
+@RunWith(Suite.class)
+@SuiteClasses({
+ TestSimplePersistable.class,
+ TestSWGPersistable.class
+})
+public class TestPersistable {
+
+}
diff --git a/test/resources/persistable/TestSWGPersistable.java b/test/resources/persistable/TestSWGPersistable.java
new file mode 100644
index 000000000..933154ca9
--- /dev/null
+++ b/test/resources/persistable/TestSWGPersistable.java
@@ -0,0 +1,146 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.persistable;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import resources.Race;
+import resources.objects.SWGObject;
+import resources.objects.building.BuildingObject;
+import services.objects.ObjectCreator;
+
+@RunWith(JUnit4.class)
+public class TestSWGPersistable {
+
+ @Test
+ public void testCreatureObject() throws IOException {
+ test(Race.HUMAN_MALE.getFilename());
+ }
+
+ @Test
+ public void testPlayerObject() throws IOException {
+ test("object/player/shared_player.iff");
+ }
+
+ @Test
+ public void testTangibleObject() throws IOException {
+ test("object/tangible/inventory/shared_character_inventory.iff");
+ }
+
+ @Test
+ public void testWeaponObject() throws IOException {
+ test("object/weapon/melee/unarmed/shared_unarmed_default_player.iff");
+ }
+
+ @Test
+ public void testResourceObject() throws IOException {
+ test("object/resource_container/shared_resource_container_energy_gas.iff");
+ }
+
+ @Test
+ public void testWaypointObject() throws IOException {
+ test("object/waypoint/shared_world_waypoint_orange.iff");
+ }
+
+ @Test
+ public void testMissionObject() throws IOException {
+ test("object/mission/shared_mission_object.iff");
+ }
+
+ @Test
+ public void testFactoryObject() throws IOException {
+ test("object/factory/shared_factory_crate_weapon.iff");
+ }
+
+ @Test
+ public void testInstallationObject() throws IOException {
+ test("object/installation/generators/shared_power_generator_wind_style_1.iff");
+ }
+
+ @Test
+ public void testShipObject() throws IOException {
+ test("object/ship/shared_grievous_starship.iff");
+ }
+
+ @Test
+ public void testManufactureObject() throws IOException {
+ test("object/manufacture_schematic/shared_generic_schematic.iff");
+ }
+
+ @Test
+ public void testBuildingObject() throws IOException {
+ test("object/building/tatooine/shared_palace_tatooine_jabba.iff");
+ BuildingObject expected = (BuildingObject) ObjectCreator.createObjectFromTemplate("object/building/tatooine/shared_palace_tatooine_jabba.iff");
+ expected.populateCells();
+ byte [] data = write(expected);
+ SWGObject obj = read(data);
+ test(expected, obj);
+ }
+
+ @Test
+ public void testCellObject() throws IOException {
+ test("object/cell/shared_cell.iff");
+ }
+
+ private void test(String template) throws IOException {
+ SWGObject expected = ObjectCreator.createObjectFromTemplate(template);
+ byte [] data = write(expected);
+ SWGObject obj = read(data);
+ test(expected, obj);
+ }
+
+ private void test(SWGObject expected, SWGObject actual) {
+ Assert.assertNotNull(actual);
+ Assert.assertTrue("actual instanceof expected", expected.getClass().isAssignableFrom(actual.getClass()));
+ Assert.assertEquals("expected.equals(actual)", expected, actual);
+ }
+
+ private byte [] write(SWGObject obj) throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ OutputPersistenceStream os = new OutputPersistenceStream(baos);
+ os.write(obj, SWGObjectFactory::save);
+ os.close();
+ return baos.toByteArray();
+ }
+
+ private SWGObject read(byte [] data) throws IOException {
+ try (InputPersistenceStream is = new InputPersistenceStream(new ByteArrayInputStream(data))) {
+ SWGObject obj = is.read(SWGObjectFactory::create);
+ Assert.assertEquals(0, is.available());
+ return obj;
+ }
+ }
+
+}
diff --git a/test/resources/persistable/TestSimplePersistable.java b/test/resources/persistable/TestSimplePersistable.java
new file mode 100644
index 000000000..6a95e7813
--- /dev/null
+++ b/test/resources/persistable/TestSimplePersistable.java
@@ -0,0 +1,130 @@
+/************************************************************************************
+ * Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * -------------------------------------------------------------------------------- *
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore 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 Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ * *
+ ***********************************************************************************/
+package resources.persistable;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import resources.network.NetBufferStream;
+
+@RunWith(JUnit4.class)
+public class TestSimplePersistable {
+
+ @Test
+ public void testInputPersistenceStream() throws IOException {
+ InputPersistenceStream is = new InputPersistenceStream(new ByteArrayInputStream(createBuffer()));
+ PersistableObject po = is.read(PersistableObject::create);
+ Assert.assertEquals(13, po.getSomeInt());
+ is.close();
+ }
+
+ @Test
+ public void testOutputPersistenceStream() throws IOException {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream(8);
+ OutputPersistenceStream os = new OutputPersistenceStream(baos);
+ PersistableObject po = new PersistableObject(13);
+ os.write(po);
+ Assert.assertArrayEquals(createBuffer(), baos.toByteArray());
+ os.close();
+ }
+
+ @Test
+ public void testPersistenceStreams() throws IOException {
+ File tmp = File.createTempFile("PersistableTest", "odb");
+ OutputPersistenceStream os = new OutputPersistenceStream(new FileOutputStream(tmp));
+ PersistableObject original = new PersistableObject(17);
+ os.write(original);
+ os.close();
+ InputPersistenceStream is = new InputPersistenceStream(new FileInputStream(tmp));
+ PersistableObject recreated = is.read(PersistableObject::create);
+ is.close();
+ Assert.assertEquals(original.getSomeInt(), recreated.getSomeInt());
+ }
+
+ @Test
+ public void testPersistenceStreamMultiple() throws IOException {
+ File tmp = File.createTempFile("PersistableTest", "odb");
+ OutputPersistenceStream os = new OutputPersistenceStream(new FileOutputStream(tmp));
+ PersistableObject original = new PersistableObject(17);
+ os.write(original);
+ os.write(original);
+ os.write(original);
+ os.close();
+ InputPersistenceStream is = new InputPersistenceStream(new FileInputStream(tmp));
+ Assert.assertEquals(original.getSomeInt(), is.read(PersistableObject::create).getSomeInt());
+ Assert.assertEquals(original.getSomeInt(), is.read(PersistableObject::create).getSomeInt());
+ Assert.assertEquals(original.getSomeInt(), is.read(PersistableObject::create).getSomeInt());
+ is.close();
+ }
+ private byte [] createBuffer() {
+ NetBufferStream stream = new NetBufferStream(8);
+ stream.addInt(4);
+ stream.addInt(13);
+ byte [] array = stream.array();
+ stream.close();
+ return array;
+ }
+
+ private static class PersistableObject implements Persistable {
+
+ private final int someInt;
+
+ public PersistableObject(int someInt) {
+ this.someInt = someInt;
+ }
+
+ @Override
+ public void save(NetBufferStream stream) {
+ stream.addInt(someInt);
+ }
+
+ @Override
+ public void read(NetBufferStream stream) {
+
+ }
+
+ public static PersistableObject create(NetBufferStream stream) {
+ return new PersistableObject(stream.getInt());
+ }
+
+ public int getSomeInt() {
+ return someInt;
+ }
+
+ }
+
+}
diff --git a/test/resources/server_info/TestObjectDatabase.java b/test/resources/server_info/TestObjectDatabase.java
deleted file mode 100644
index fd159b0a5..000000000
--- a/test/resources/server_info/TestObjectDatabase.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/***********************************************************************************
-* Copyright (c) 2015 /// Project SWG /// www.projectswg.com *
-* *
-* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
-* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
-* Our goal is to create an emulator which will provide a server for players to *
-* continue playing a game similar to the one they used to play. We are basing *
-* it on the final publish of the game prior to end-game events. *
-* *
-* This file is part of Holocore. *
-* *
-* -------------------------------------------------------------------------------- *
-* *
-* Holocore is free software: you can redistribute it and/or modify *
-* it under the terms of the GNU Affero General Public License as *
-* published by the Free Software Foundation, either version 3 of the *
-* License, or (at your option) any later version. *
-* *
-* Holocore 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 Affero General Public License for more details. *
-* *
-* You should have received a copy of the GNU Affero General Public License *
-* along with Holocore. If not, see . *
-* *
-***********************************************************************************/
-package resources.server_info;
-
-import java.io.File;
-
-import org.junit.AfterClass;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import resources.server_info.ObjectDatabase.Traverser;
-
-@RunWith(JUnit4.class)
-public class TestObjectDatabase {
-
- private static final File file = new File("test_odb.db");
-
- @AfterClass
- public static void cleanup() {
- if (file.exists() && !file.delete())
- System.err.println("Failed to delete file: " + file);
- }
-
- @Test
- public void testPutGet() {
- cleanup();
- UncachedObjectDatabase odb = new UncachedObjectDatabase("test_odb.db");
- odb.put(500, 1024);
- Assert.assertEquals(1024, odb.get(500).intValue());
- odb.put("testString", 128);
- Assert.assertEquals(128, odb.get("testString").intValue());
- }
-
- @Test
- public void testClearCache() {
- cleanup();
- UncachedObjectDatabase odb = new UncachedObjectDatabase("test_odb.db");
- odb.put(500, 1024);
- Assert.assertEquals(1024, odb.get(500).intValue());
- odb.clearCache();
- Assert.assertEquals(null, odb.get(500));
- }
-
- @Test
- public void testSaveLoad() {
- cleanup();
- UncachedObjectDatabase odb = new UncachedObjectDatabase("test_odb.db");
- odb.put(500, 1024);
- Assert.assertEquals(1024, odb.get(500).intValue());
- odb.save();
- odb = new UncachedObjectDatabase("test_odb.db");
- Assert.assertEquals(1024, odb.get(500).intValue());
- }
-
- @Test
- public void testSaveClearCache() {
- cleanup();
- UncachedObjectDatabase odb = new UncachedObjectDatabase("test_odb.db");
- odb.put(500, 1024);
- Assert.assertEquals(1024, odb.get(500).intValue());
- odb.save();
- odb.clearCache();
- Assert.assertEquals(1024, odb.get(500).intValue());
- Assert.assertEquals(1024, odb.get(500).intValue());
- }
-
- @Test
- public void testCache() {
- cleanup();
- UncachedObjectDatabase odb = new UncachedObjectDatabase("test_odb.db");
- odb.put(500, 1024);
- Assert.assertEquals(1024, odb.get(500).intValue());
- odb.save();
- odb.clearCache();
- odb.loadToCache();
- Integer get = odb.get(500);
- Assert.assertEquals(1024, get.intValue());
- }
-
- @Test
- public void testTraverser() {
- cleanup();
- UncachedObjectDatabase odb = new UncachedObjectDatabase("test_odb.db");
- odb.put(1024, 301);
- odb.put(2048, 301);
- odb.put(4096, 301);
- final int [] traverseLoops = new int[] {0};
- odb.traverse(new Traverser() {
- public void process(Integer i) {
- traverseLoops[0]++;
- }
- });
- Assert.assertEquals(3, traverseLoops[0]);
- }
-
-}