diff --git a/.classpath b/.classpath
index 16ca8f86e..05e69b75e 100644
--- a/.classpath
+++ b/.classpath
@@ -6,7 +6,6 @@
-
@@ -18,15 +17,13 @@
-
-
-
-
-
+
+
+
diff --git a/.project b/.project
index 0dca9e05c..2a27ec28f 100644
--- a/.project
+++ b/.project
@@ -5,24 +5,13 @@
-
- org.python.pydev.PyDevBuilder
-
-
-
org.eclipse.jdt.core.javabuilder
-
- org.eclipse.m2e.core.maven2Builder
-
-
-
- org.eclipse.m2e.core.maven2Nature
org.eclipse.jdt.core.javanature
org.python.pydev.pythonNature
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
index 672496e10..13b3428ac 100644
--- a/.settings/org.eclipse.jdt.core.prefs
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -1,5 +1,6 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
diff --git a/lib/PSWGCommon.jar b/lib/PSWGCommon.jar
index efa0304bc..296b9c56c 100644
Binary files a/lib/PSWGCommon.jar and b/lib/PSWGCommon.jar differ
diff --git a/src/network/packets/swg/SWGPacket.java b/src/network/packets/swg/SWGPacket.java
index fe80574e5..507d018d5 100644
--- a/src/network/packets/swg/SWGPacket.java
+++ b/src/network/packets/swg/SWGPacket.java
@@ -54,7 +54,7 @@ public abstract class SWGPacket extends Packet {
}
public boolean checkDecode(NetBuffer data, int crc) {
- data.position(2);
+ data.getShort();
this.crc = data.getInt();
this.type = PacketType.fromCrc(crc);
if (this.crc == crc)
diff --git a/src/network/packets/swg/zone/PlayClientEffectObjectMessage.java b/src/network/packets/swg/zone/PlayClientEffectObjectMessage.java
index 454b505fd..540879b2b 100644
--- a/src/network/packets/swg/zone/PlayClientEffectObjectMessage.java
+++ b/src/network/packets/swg/zone/PlayClientEffectObjectMessage.java
@@ -37,7 +37,11 @@ public class PlayClientEffectObjectMessage extends SWGPacket {
private String effectFile;
private String effectLocation;
private long objectId;
-
+
+ public PlayClientEffectObjectMessage() {
+
+ }
+
public PlayClientEffectObjectMessage(String effectFile, String effectLocation, long objectId) {
this.effectFile = effectFile;
this.effectLocation = effectLocation;
diff --git a/src/network/packets/swg/zone/SceneCreateObjectByCrc.java b/src/network/packets/swg/zone/SceneCreateObjectByCrc.java
index da872ef6f..bc479c62d 100644
--- a/src/network/packets/swg/zone/SceneCreateObjectByCrc.java
+++ b/src/network/packets/swg/zone/SceneCreateObjectByCrc.java
@@ -51,6 +51,7 @@ public class SceneCreateObjectByCrc extends SWGPacket {
this.hyperspace = hyperspace;
}
+ @Override
public void decode(NetBuffer data) {
if (!super.checkDecode(data, CRC))
return;
@@ -60,6 +61,7 @@ public class SceneCreateObjectByCrc extends SWGPacket {
hyperspace = data.getBoolean();
}
+ @Override
public NetBuffer encode() {
NetBuffer data = NetBuffer.allocate(47);
data.addShort(5);
diff --git a/src/network/packets/swg/zone/UpdatePostureMessage.java b/src/network/packets/swg/zone/UpdatePostureMessage.java
index 136aba0cd..2944cbed7 100644
--- a/src/network/packets/swg/zone/UpdatePostureMessage.java
+++ b/src/network/packets/swg/zone/UpdatePostureMessage.java
@@ -52,6 +52,7 @@ public class UpdatePostureMessage extends SWGPacket {
this.objId = objId;
}
+ @Override
public void decode(NetBuffer data) {
if (!super.checkDecode(data, CRC))
return;
@@ -59,9 +60,9 @@ public class UpdatePostureMessage extends SWGPacket {
objId = data.getLong();
}
+ @Override
public NetBuffer encode() {
- int length = 16;
- NetBuffer data = NetBuffer.allocate(length);
+ NetBuffer data = NetBuffer.allocate(15);
data.addShort(3);
data.addInt(CRC);
data.addByte(posture);
diff --git a/src/network/packets/swg/zone/chat/ChatOnEnteredRoom.java b/src/network/packets/swg/zone/chat/ChatOnEnteredRoom.java
index e0696b420..29feafd36 100644
--- a/src/network/packets/swg/zone/chat/ChatOnEnteredRoom.java
+++ b/src/network/packets/swg/zone/chat/ChatOnEnteredRoom.java
@@ -42,6 +42,10 @@ public class ChatOnEnteredRoom extends SWGPacket {
private int chatRoomId;
private int sequence;
+ public ChatOnEnteredRoom() {
+
+ }
+
public ChatOnEnteredRoom(ChatAvatar avatar, int chatRoomId, int sequence) {
this(avatar, ChatResult.NONE, chatRoomId, sequence);
}
@@ -57,6 +61,7 @@ public class ChatOnEnteredRoom extends SWGPacket {
decode(data);
}
+ @Override
public void decode(NetBuffer data) {
if (!super.checkDecode(data, CRC))
return;
@@ -66,6 +71,7 @@ public class ChatOnEnteredRoom extends SWGPacket {
sequence = data.getInt();
}
+ @Override
public NetBuffer encode() {
NetBuffer data = NetBuffer.allocate(avatar.getLength() + 18);
data.addShort(5);
diff --git a/src/network/packets/swg/zone/chat/ChatSystemMessage.java b/src/network/packets/swg/zone/chat/ChatSystemMessage.java
index c48fe796f..d1ad04d09 100644
--- a/src/network/packets/swg/zone/chat/ChatSystemMessage.java
+++ b/src/network/packets/swg/zone/chat/ChatSystemMessage.java
@@ -33,14 +33,15 @@ import network.packets.swg.SWGPacket;
import resources.encodables.OutOfBandPackage;
public class ChatSystemMessage extends SWGPacket {
+
public static final int CRC = getCrc("ChatSystemMessage");
-
- private int type = 0;
- private String message = "";
+
private OutOfBandPackage oob;
+ private String message;
+ private int type;
public ChatSystemMessage() {
-
+ this(0, "");
}
public ChatSystemMessage(int type, String message) {
@@ -54,11 +55,11 @@ public class ChatSystemMessage extends SWGPacket {
}
public ChatSystemMessage(SystemChatType type, String message) {
- this(type.ordinal(), message);
+ this(type.getType(), message);
}
public ChatSystemMessage(SystemChatType type, OutOfBandPackage oob) {
- this(type.ordinal(), oob);
+ this(type.getType(), oob);
}
@Override
@@ -78,7 +79,7 @@ public class ChatSystemMessage extends SWGPacket {
if (oobExists)
length += 4 + oob.getLength();
else
- length += 15 + message.length() * 2;
+ length += 8 + message.length() * 2;
NetBuffer data = NetBuffer.allocate(length);
data.addShort(4);
@@ -96,16 +97,35 @@ public class ChatSystemMessage extends SWGPacket {
}
public SystemChatType getType() {
- for (SystemChatType t : SystemChatType.values()) {
- if (type == t.ordinal()) return t;
+ switch (type) {
+ case 0:
+ default:
+ return SystemChatType.SCREEN_AND_CHAT;
+ case 1:
+ return SystemChatType.SCREEN;
+ case 2:
+ return SystemChatType.CHAT;
}
- return SystemChatType.SCREEN_AND_CHAT;
}
- public String getMessage() { return message; }
+
+ public String getMessage() {
+ return message;
+ }
public enum SystemChatType {
- SCREEN_AND_CHAT,
- SCREEN,
- CHAT
+ SCREEN_AND_CHAT (0x00),
+ SCREEN (0x01),
+ CHAT (0x02);
+
+ int type;
+
+ SystemChatType(int type) {
+ this.type = type;
+ }
+
+ public int getType() {
+ return type;
+ }
}
+
}
diff --git a/src/network/packets/swg/zone/deltas/DeltasMessage.java b/src/network/packets/swg/zone/deltas/DeltasMessage.java
index d4e8281e6..4961c2d8b 100644
--- a/src/network/packets/swg/zone/deltas/DeltasMessage.java
+++ b/src/network/packets/swg/zone/deltas/DeltasMessage.java
@@ -42,9 +42,14 @@ public class DeltasMessage extends SWGPacket {
private byte[] deltaData;
private int update;
+ public DeltasMessage() {
+
+ }
+
public DeltasMessage(long objId, BaselineType type, int typeNumber, int update, byte[] data) {
this.objId = objId;
this.type = type;
+ this.update = update;
this.num = typeNumber;
this.deltaData = data;
}
@@ -58,12 +63,12 @@ public class DeltasMessage extends SWGPacket {
if (!super.checkDecode(data, CRC))
return;
objId = data.getLong();
- type = BaselineType.valueOf(new StringBuffer(new String(data.getArray(4), ascii)).reverse().toString());
+ type = BaselineType.valueOf(reverse(new String(data.getArray(4), ascii)));
num = data.getByte();
NetBuffer deltaDataBuffer = NetBuffer.wrap(data.getArrayLarge());
deltaDataBuffer.getShort();
update = deltaDataBuffer.getShort();
- deltaData = data.getArray(deltaDataBuffer.remaining());
+ deltaData = deltaDataBuffer.getArray(deltaDataBuffer.remaining());
}
@Override
@@ -72,7 +77,7 @@ public class DeltasMessage extends SWGPacket {
data.addShort(5);
data.addInt(CRC);
data.addLong(objId);
- data.addRawArray(new StringBuffer(type.toString()).reverse().toString().getBytes(ascii));
+ data.addRawArray(reverse(type.toString()).getBytes(ascii));
data.addByte(num);
data.addInt(deltaData.length + 4);
data.addShort(1); // updates - only 1 cause we're boring
@@ -120,4 +125,8 @@ public class DeltasMessage extends SWGPacket {
public void setUpdate(int update) {
this.update = update;
}
+
+ private String reverse(String str) {
+ return new StringBuffer(str).reverse().toString();
+ }
}
diff --git a/src/network/packets/swg/zone/insertion/ChatRoomList.java b/src/network/packets/swg/zone/insertion/ChatRoomList.java
index 36fb1af5b..ef836d9f2 100644
--- a/src/network/packets/swg/zone/insertion/ChatRoomList.java
+++ b/src/network/packets/swg/zone/insertion/ChatRoomList.java
@@ -27,6 +27,7 @@
***********************************************************************************/
package network.packets.swg.zone.insertion;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -41,6 +42,10 @@ public class ChatRoomList extends SWGPacket {
private Collection rooms;
+ public ChatRoomList() {
+ this.rooms = new ArrayList<>();
+ }
+
public ChatRoomList(ChatRoom... rooms) {
this.rooms = Arrays.asList(rooms);
}
diff --git a/src/network/packets/swg/zone/object_controller/ObjectController.java b/src/network/packets/swg/zone/object_controller/ObjectController.java
index dd12e956c..f806ec47b 100644
--- a/src/network/packets/swg/zone/object_controller/ObjectController.java
+++ b/src/network/packets/swg/zone/object_controller/ObjectController.java
@@ -91,8 +91,10 @@ public abstract class ObjectController extends SWGPacket {
public static final ObjectController decodeController(NetBuffer data) {
if (data.array().length < 14)
return null;
- data.position(10);
+ int pos = data.position();
+ data.position(pos+10);
int crc = data.getInt();
+ data.position(pos);
switch (crc) {
case 0x0071: return new DataTransform(data);
case 0x00CC: return new CombatAction(data);
diff --git a/src/resources/config/ConfigFile.java b/src/resources/config/ConfigFile.java
index 483201674..df1850ea5 100644
--- a/src/resources/config/ConfigFile.java
+++ b/src/resources/config/ConfigFile.java
@@ -36,7 +36,9 @@ public enum ConfigFile {
/** Meant for networking-related configuration. Includes Login and Zone configuration */
NETWORK ("cfg/network.cfg"),
/** Meant for specific in-game features that may be better disabled or tweaked */
- FEATURES("cfg/features.cfg");
+ FEATURES("cfg/features.cfg"),
+ /** Meant for debug features to help fix problems in-game */
+ DEBUG("cfg/debug.cfg");
private static final Map NAMEMAP = new HashMap<>();
private String filename;
diff --git a/src/resources/network/BaselineObject.java b/src/resources/network/BaselineObject.java
index 84903a2bd..5273530cf 100644
--- a/src/resources/network/BaselineObject.java
+++ b/src/resources/network/BaselineObject.java
@@ -33,13 +33,17 @@ import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.List;
+import com.projectswg.common.debug.Log;
import com.projectswg.common.encoding.StringType;
import com.projectswg.common.network.NetBuffer;
+import com.projectswg.common.utilities.ByteUtilities;
import network.packets.swg.zone.baselines.Baseline;
import network.packets.swg.zone.baselines.Baseline.BaselineType;
+import resources.config.ConfigFile;
import resources.objects.SWGObject;
import resources.player.Player;
+import resources.server_info.DataManager;
public class BaselineObject {
@@ -182,7 +186,9 @@ public class BaselineObject {
baselineData.set(type-1, null);
}
DeltaBuilder builder = new DeltaBuilder((SWGObject) this, this.type, type, update, value);
- builder.send();
+ boolean sent = builder.send();
+ if (sent && isDeltaLogging())
+ Log.v("Delta [type=%d, update=%d, value=%s] = %s", type, update, value, ByteUtilities.getHexString(builder.getEncodedData()));
}
public final void sendDelta(int type, int update, Object value, StringType strType) {
@@ -191,7 +197,13 @@ public class BaselineObject {
baselineData.set(type-1, null);
}
DeltaBuilder builder = new DeltaBuilder((SWGObject) this, this.type, type, update, value, strType);
- builder.send();
+ boolean sent = builder.send();
+ if (sent && isDeltaLogging())
+ Log.v("Delta %s: [type=%d, update=%d, value=%s, strType=%s] = %s", this, type, update, value, strType, ByteUtilities.getHexString(builder.getEncodedData()));
+ }
+
+ private boolean isDeltaLogging() {
+ return DataManager.getConfig(ConfigFile.DEBUG).getBoolean("DEBUG-DELTA-LOGGING", false);
}
private Baseline createBaseline(Player target, int num, BaselineCreator bc) {
diff --git a/src/resources/network/DeltaBuilder.java b/src/resources/network/DeltaBuilder.java
index 57ce29afa..c23ba6d05 100644
--- a/src/resources/network/DeltaBuilder.java
+++ b/src/resources/network/DeltaBuilder.java
@@ -60,17 +60,26 @@ public class DeltaBuilder {
this.updateType = updateType;
}
- public void send() {
+ public boolean send() {
DeltasMessage message = getBuiltMessage();
Player owner = object.getOwner();
- if (owner != null && owner.getPlayerState() == PlayerState.ZONED_IN)
+ boolean sent = false;
+ if (owner != null && owner.getPlayerState() == PlayerState.ZONED_IN) {
owner.sendPacket(message);
- if (num == 3 || num == 6) // Shared Objects
- object.sendObservers(message);
+ sent = true;
+ }
+ if (num == 3 || num == 6) { // Shared Objects
+ sent = object.sendObservers(message) > 0 || sent;
+ }
+ return sent;
}
public DeltasMessage getBuiltMessage() {
return new DeltasMessage(object.getObjectId(), type, num, updateType, data);
}
+ public byte [] getEncodedData() {
+ return data;
+ }
+
}
diff --git a/src/resources/network/TCPServer.java b/src/resources/network/TCPServer.java
deleted file mode 100644
index 282d5655c..000000000
--- a/src/resources/network/TCPServer.java
+++ /dev/null
@@ -1,294 +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.network;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.nio.channels.AsynchronousCloseException;
-import java.nio.channels.ClosedByInterruptException;
-import java.nio.channels.ClosedChannelException;
-import java.nio.channels.SelectableChannel;
-import java.nio.channels.SelectionKey;
-import java.nio.channels.Selector;
-import java.nio.channels.ServerSocketChannel;
-import java.nio.channels.SocketChannel;
-import java.util.HashMap;
-import java.util.Locale;
-import java.util.Map;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import com.projectswg.common.debug.Log;
-
-import utilities.ThreadUtilities;
-
-
-public class TCPServer {
-
- private final ExecutorService callbackExecutor;
- private final Map sockets;
- private final InetAddress addr;
- private final int port;
- private final int bufferSize;
- private final TCPListener listener;
- private ServerSocketChannel channel;
- private NetworkCallback callback;
-
- public TCPServer(int port, int bufferSize) {
- this(null, port, bufferSize);
- }
-
- public TCPServer(InetAddress addr, int port, int bufferSize) {
- this.callbackExecutor = Executors.newSingleThreadExecutor(ThreadUtilities.newThreadFactory("tcp-server-callback-executor"));
- this.sockets = new HashMap<>();
- this.addr = addr;
- this.port = port;
- this.bufferSize = bufferSize;
- this.listener = new TCPListener();
- this.channel = null;
- }
-
- public void bind() throws IOException {
- channel = ServerSocketChannel.open();
- channel.socket().bind(new InetSocketAddress(addr, port));
- channel.configureBlocking(false);
- listener.start();
- }
-
- public SocketChannel connectTo(InetAddress addr, int port) throws IOException {
- return connectTo(new InetSocketAddress(addr, port));
- }
-
- public SocketChannel connectTo(InetSocketAddress sock) throws IOException {
- synchronized (sockets) {
- SocketChannel sc = sockets.get(sock);
- if (sc == null || (!sc.isConnected() && !sc.isConnectionPending())) {
- sc = SocketChannel.open(sock);
- sc.configureBlocking(false);
- sockets.put(sock, sc);
- }
- return sc;
- }
- }
-
- public boolean disconnect(SocketAddress sock) {
- synchronized (sockets) {
- SocketChannel sc = sockets.get(sock);
- if (sc == null)
- return false;
- sockets.remove(sock);
- try {
- Socket s = sc.socket();
- sc.close();
- if (callback != null)
- callbackExecutor.execute(() -> callback.onConnectionDisconnect(s, sock));
- return true;
- } catch (IOException e) {
- Log.e(e);
- return false;
- }
- }
- }
-
- private boolean disconnect(SocketChannel sc) {
- try {
- return disconnect(sc.getRemoteAddress());
- } catch (IOException e) {
- return false;
- }
- }
-
- public boolean close() {
- listener.stop();
- callbackExecutor.shutdown();
- try {
- if (channel != null)
- channel.close();
- return true;
- } catch (IOException e) {
- Log.e(e);
- }
- return false;
- }
-
- public boolean send(InetSocketAddress sock, ByteBuffer data) {
- synchronized (sockets) {
- SocketChannel sc = sockets.get(sock);
- try {
- if (sc != null && sc.isConnected()) {
- while (data.hasRemaining())
- sc.write(data);
- return true;
- }
- } catch (IOException e) {
- Log.e("Terminated connection with %s. Error: %s", sock.toString(), e.getMessage());
- disconnect(sc);
- }
- }
- return false;
- }
-
- public void setCallback(NetworkCallback callback) {
- this.callback = callback;
- }
-
- private class TCPListener implements Runnable {
-
- private final ByteBuffer buffer;
- private Thread thread;
- private boolean running;
-
- public TCPListener() {
- buffer = ByteBuffer.allocateDirect(bufferSize);
- running = false;
- thread = null;
- }
-
- public void start() {
- running = true;
- thread = new Thread(this);
- thread.start();
- }
-
- public void stop() {
- running = false;
- if (thread != null)
- thread.interrupt();
- thread = null;
- }
-
- public void run() {
- try (Selector selector = setupSelector()) {
- while (running) {
- try {
- selector.select();
- processSelectionKeys(selector);
- } catch (Exception e) {
- Log.e(e);
- try {
- Thread.sleep(100);
- } catch (InterruptedException e1) {
- break;
- }
- }
- }
- } catch (IOException e) {
- Log.e(e);
- }
- }
-
- private Selector setupSelector() throws IOException {
- Selector selector = Selector.open();
- channel.register(selector, SelectionKey.OP_ACCEPT);
- return selector;
- }
-
- private void processSelectionKeys(Selector selector) throws ClosedChannelException {
- for (SelectionKey key : selector.selectedKeys()) {
- if (!key.isValid())
- continue;
- if (key.isAcceptable()) {
- accept(selector);
- } else if (key.isReadable()) {
- SelectableChannel selectable = key.channel();
- if (selectable instanceof SocketChannel) {
- boolean canRead = true;
- while (canRead)
- canRead = read(key, (SocketChannel) selectable);
- }
- }
- }
- }
-
- private void accept(Selector selector) {
- try {
- while (channel.isOpen()) {
- SocketChannel sc = channel.accept();
- if (sc == null)
- break;
- sc.socket().setKeepAlive(true);
- sc.socket().setPerformancePreferences(0, 1, 2);
- sc.socket().setTrafficClass(0x10); // Low Delay bit
- SocketChannel old = sockets.get(sc.getRemoteAddress());
- if (old != null)
- disconnect(old);
- sockets.put(sc.getRemoteAddress(), sc);
- sc.configureBlocking(false);
- sc.register(selector, SelectionKey.OP_READ);
- if (callback != null) {
- SocketAddress address = sc.getRemoteAddress();
- callbackExecutor.execute(() -> callback.onIncomingConnection(sc.socket(), address));
- }
- }
- } catch (AsynchronousCloseException e) {
-
- } catch (IOException e) {
- Log.a(e);
- }
- }
-
- private boolean read(SelectionKey key, SocketChannel s) {
- try {
- buffer.position(0);
- buffer.limit(bufferSize);
- int n = s.read(buffer);
- buffer.flip();
- if (n < 0) {
- key.cancel();
- disconnect(s);
- } else if (n > 0) {
- ByteBuffer smaller = ByteBuffer.allocate(n);
- smaller.put(buffer);
- if (callback != null) {
- SocketAddress address = s.getRemoteAddress();
- callbackExecutor.execute(() -> callback.onIncomingData(s.socket(), address, smaller.array()));
- }
- return true;
- }
- } catch (ClosedByInterruptException e) {
- key.cancel();
- disconnect(s);
- stop();
- } catch (IOException e) {
- if (e.getMessage() != null && e.getMessage().toLowerCase(Locale.US).contains("connection reset"))
- Log.e("Connection Reset with %s", s.socket().getRemoteSocketAddress());
- else {
- Log.e(e);
- }
- key.cancel();
- disconnect(s);
- }
- return false;
- }
- }
-
-}
diff --git a/src/resources/objects/SWGObject.java b/src/resources/objects/SWGObject.java
index 6b20c5228..27720d9e8 100644
--- a/src/resources/objects/SWGObject.java
+++ b/src/resources/objects/SWGObject.java
@@ -644,8 +644,6 @@ public abstract class SWGObject extends BaselineObject implements Comparable SWGObjectFactory.save(c, stream));
}
+ @Override
public void read(NetBufferStream stream) {
switch(stream.getByte()) {
case 4:
diff --git a/src/services/chat/ChatManager.java b/src/services/chat/ChatManager.java
index 491b8c94f..762094cae 100644
--- a/src/services/chat/ChatManager.java
+++ b/src/services/chat/ChatManager.java
@@ -310,16 +310,16 @@ public class ChatManager extends Manager {
}
private void broadcastAreaMessage(String message, Player broadcaster) {
- broadcaster.getCreatureObject().sendObserversAndSelf(new ChatSystemMessage(SystemChatType.SCREEN_AND_CHAT.ordinal(), message));
+ broadcaster.getCreatureObject().sendObserversAndSelf(new ChatSystemMessage(SystemChatType.SCREEN_AND_CHAT.getType(), message));
}
private void broadcastPlanetMessage(String message, Terrain terrain) {
- ChatSystemMessage packet = new ChatSystemMessage(SystemChatType.SCREEN_AND_CHAT.ordinal(), message);
+ ChatSystemMessage packet = new ChatSystemMessage(SystemChatType.SCREEN_AND_CHAT.getType(), message);
new NotifyPlayersPacketIntent(packet, terrain).broadcast();
}
private void broadcastGalaxyMessage(String message) {
- ChatSystemMessage packet = new ChatSystemMessage(SystemChatType.SCREEN_AND_CHAT.ordinal(), message);
+ ChatSystemMessage packet = new ChatSystemMessage(SystemChatType.SCREEN_AND_CHAT.getType(), message);
new NotifyPlayersPacketIntent(packet).broadcast();
}
diff --git a/src/services/chat/ChatRoomService.java b/src/services/chat/ChatRoomService.java
index b86e79857..d778929c2 100644
--- a/src/services/chat/ChatRoomService.java
+++ b/src/services/chat/ChatRoomService.java
@@ -374,7 +374,7 @@ public class ChatRoomService extends Service {
}
private void handleChatRoomListRequest(Player player) {
- player.sendPacket(new ChatRoomList(chatRoomHandler.getRoomList(player)));
+ player.sendPacket(new ChatRoomList());
}
}
diff --git a/src/services/network/NetworkClientManager.java b/src/services/network/NetworkClientManager.java
index cc35a04be..f5d2ae5ae 100644
--- a/src/services/network/NetworkClientManager.java
+++ b/src/services/network/NetworkClientManager.java
@@ -30,13 +30,15 @@ package services.network;
import java.io.IOException;
import java.net.BindException;
import java.net.InetAddress;
-import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
+import java.nio.channels.SocketChannel;
import com.projectswg.common.control.Manager;
import com.projectswg.common.debug.Log;
import com.projectswg.common.network.NetBuffer;
+import com.projectswg.common.network.TCPServer;
+import com.projectswg.common.network.TCPServer.TCPCallback;
import intents.network.CloseConnectionIntent;
import main.ProjectSWG.CoreException;
@@ -44,8 +46,6 @@ import network.AdminNetworkClient;
import network.NetworkClient;
import network.packets.swg.holo.HoloConnectionStopped.ConnectionStoppedReason;
import resources.config.ConfigFile;
-import resources.network.NetworkCallback;
-import resources.network.TCPServer;
import resources.network.UDPServer;
import resources.network.UDPServer.UDPPacket;
import resources.server_info.DataManager;
@@ -151,7 +151,7 @@ public class NetworkClientManager extends Manager {
udpServer.send(port, addr, data.array());
}
- private class StandardNetworkCallback implements NetworkCallback {
+ private class StandardNetworkCallback implements TCPCallback {
private final PacketSender sender;
@@ -160,7 +160,7 @@ public class NetworkClientManager extends Manager {
}
@Override
- public void onIncomingConnection(Socket s, SocketAddress addr) {
+ public void onIncomingConnection(SocketChannel s, SocketAddress addr) {
NetworkClient client = clientManager.createSession(addr, sender);
client.onConnected();
inboundManager.onSessionCreated(client);
@@ -168,7 +168,7 @@ public class NetworkClientManager extends Manager {
}
@Override
- public void onConnectionDisconnect(Socket s, SocketAddress addr) {
+ public void onConnectionDisconnect(SocketChannel s, SocketAddress addr) {
NetworkClient client = clientManager.getClient(addr);
if (client != null) {
client.onDisconnected(ConnectionStoppedReason.APPLICATION);
@@ -180,13 +180,13 @@ public class NetworkClientManager extends Manager {
}
@Override
- public void onIncomingData(Socket s, SocketAddress addr, byte [] data) {
+ public void onIncomingData(SocketChannel s, SocketAddress addr, byte [] data) {
inboundManager.onInboundData(addr, data);
}
}
- private class AdminNetworkCallback implements NetworkCallback {
+ private class AdminNetworkCallback implements TCPCallback {
private final PacketSender sender;
@@ -195,7 +195,7 @@ public class NetworkClientManager extends Manager {
}
@Override
- public void onIncomingConnection(Socket s, SocketAddress addr) {
+ public void onIncomingConnection(SocketChannel s, SocketAddress addr) {
NetworkClient client = clientManager.createAdminSession(addr, sender);
client.onConnected();
inboundManager.onSessionCreated(client);
@@ -203,7 +203,7 @@ public class NetworkClientManager extends Manager {
}
@Override
- public void onConnectionDisconnect(Socket s, SocketAddress addr) {
+ public void onConnectionDisconnect(SocketChannel s, SocketAddress addr) {
NetworkClient client = clientManager.getClient(addr);
if (client != null) {
client.onDisconnected(ConnectionStoppedReason.APPLICATION);
@@ -215,7 +215,7 @@ public class NetworkClientManager extends Manager {
}
@Override
- public void onIncomingData(Socket s, SocketAddress addr, byte [] data) {
+ public void onIncomingData(SocketChannel s, SocketAddress addr, byte [] data) {
inboundManager.onInboundData(addr, data);
}
diff --git a/src/services/network/NetworkProtocol.java b/src/services/network/NetworkProtocol.java
index 07e7abec7..60cd52afb 100644
--- a/src/services/network/NetworkProtocol.java
+++ b/src/services/network/NetworkProtocol.java
@@ -30,6 +30,7 @@ package services.network;
import java.io.EOFException;
import com.projectswg.common.debug.Assert;
+import com.projectswg.common.debug.Log;
import com.projectswg.common.network.NetBuffer;
import com.projectswg.common.network.NetBufferStream;
@@ -43,7 +44,9 @@ public class NetworkProtocol {
public NetBuffer encode(Packet p) {
NetBuffer encoded = p.encode();
- encoded.position(0);
+ encoded.flip();
+ if (encoded.remaining() != encoded.capacity())
+ Log.w("Packet %s has invalid array length. Expected: %d Actual: %d", p, encoded.remaining(), encoded.capacity());
int decompressedLength = encoded.remaining();
boolean compressed = false;
if (compressed) {
@@ -106,7 +109,7 @@ public class NetworkProtocol {
data.addByte(bitmask);
data.addShort((short) packet.remaining());
data.addShort((short) rawLength);
- data.addRawArray(packet.array());
+ data.add(packet);
data.flip();
return data;
}
@@ -118,7 +121,7 @@ public class NetworkProtocol {
buffer.getShort();
int crc = buffer.getInt();
buffer.position(0);
- if (crc == 0x80CE5E46) {
+ if (crc == ObjectController.CRC) {
return ObjectController.decodeController(buffer);
} else {
SWGPacket packet = PacketType.getForCrc(crc);
diff --git a/src/services/network/OutboundNetworkManager.java b/src/services/network/OutboundNetworkManager.java
index db2625ed1..233972b55 100644
--- a/src/services/network/OutboundNetworkManager.java
+++ b/src/services/network/OutboundNetworkManager.java
@@ -29,10 +29,10 @@ package services.network;
import com.projectswg.common.control.Service;
import com.projectswg.common.debug.Assert;
+import com.projectswg.common.network.TCPServer;
import intents.network.OutboundPacketIntent;
import network.NetworkClient;
-import resources.network.TCPServer;
public class OutboundNetworkManager extends Service {
diff --git a/src/services/network/PacketSender.java b/src/services/network/PacketSender.java
index 327b9bcbb..b62cf1b00 100644
--- a/src/services/network/PacketSender.java
+++ b/src/services/network/PacketSender.java
@@ -27,13 +27,14 @@
***********************************************************************************/
package services.network;
+import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
+import java.nio.channels.SocketChannel;
import com.projectswg.common.debug.Log;
import com.projectswg.common.network.NetBuffer;
-
-import resources.network.TCPServer;
+import com.projectswg.common.network.TCPServer;
public class PacketSender {
@@ -51,7 +52,18 @@ public class PacketSender {
}
public void sendPacket(InetSocketAddress addr, NetBuffer data) {
- tcpServer.send(addr, data.getBuffer());
+ SocketChannel sc = tcpServer.getChannel(addr);
+ if (sc == null)
+ return;
+ try {
+ while (data.hasRemaining()) {
+ sc.write(data.getBuffer());
+ }
+ } catch (IOException e) {
+ Log.e("Failed to write to channel: %s", addr);
+ Log.e(e);
+ tcpServer.disconnect(addr);
+ }
}
}
diff --git a/src/services/objects/ObjectAwareness.java b/src/services/objects/ObjectAwareness.java
index f329b0c41..9a87421a6 100644
--- a/src/services/objects/ObjectAwareness.java
+++ b/src/services/objects/ObjectAwareness.java
@@ -271,7 +271,7 @@ public class ObjectAwareness extends Service implements TerrainMapCallback {
private void handleDataTransform(DataTransform dt, ObjectManager objectManager) {
SWGObject obj = objectManager.getObjectById(dt.getObjectId());
- Assert.test(obj instanceof CreatureObject);
+ Assert.test(obj instanceof CreatureObject, "DataTransform object not CreatureObject! Was: " + (obj==null?"null":obj.getClass()));
Location requestedLocation = new Location(dt.getLocation());
requestedLocation.setTerrain(obj.getTerrain());
moveObjectWithTransform(obj, null, requestedLocation, dt.getSpeed(), dt.getUpdateCounter());
@@ -280,7 +280,7 @@ public class ObjectAwareness extends Service implements TerrainMapCallback {
private void handleDataTransformWithParent(DataTransformWithParent dt, ObjectManager objectManager) {
SWGObject obj = objectManager.getObjectById(dt.getObjectId());
SWGObject parent = objectManager.getObjectById(dt.getCellId());
- Assert.test(obj instanceof CreatureObject);
+ Assert.test(obj instanceof CreatureObject, "DataTransformWithParent object not CreatureObject! Was: " + (obj==null?"null":obj.getClass()));
if (parent == null) {
Log.w("Unknown data transform parent! Obj: %d/%s Parent: %d", dt.getObjectId(), obj, dt.getCellId());
return;
diff --git a/src/services/objects/ObjectManager.java b/src/services/objects/ObjectManager.java
index 394867a58..6906d5434 100644
--- a/src/services/objects/ObjectManager.java
+++ b/src/services/objects/ObjectManager.java
@@ -29,21 +29,15 @@ package services.objects;
import java.util.Hashtable;
import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import com.projectswg.common.control.Manager;
import com.projectswg.common.debug.Log;
-import intents.RequestZoneInIntent;
import intents.network.GalacticPacketIntent;
import intents.object.DestroyObjectIntent;
import intents.object.ObjectCreatedIntent;
import network.packets.Packet;
-import network.packets.swg.ErrorMessage;
-import network.packets.swg.zone.insertion.SelectCharacter;
import network.packets.swg.zone.object_controller.IntendedTarget;
import resources.objects.SWGObject;
import resources.objects.building.BuildingObject;
@@ -51,12 +45,10 @@ import resources.objects.cell.CellObject;
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.ObjectDatabase;
import resources.server_info.StandardLog;
import services.map.MapManager;
-import services.player.PlayerManager;
import services.spawn.SpawnerService;
import services.spawn.StaticService;
@@ -217,11 +209,7 @@ public class ObjectManager extends Manager {
private void processGalacticPacketIntent(GalacticPacketIntent gpi) {
Packet packet = gpi.getPacket();
- if (packet instanceof SelectCharacter) {
- PlayerManager pm = gpi.getPlayerManager();
- long characterId = ((SelectCharacter) packet).getCharacterId();
- zoneInCharacter(pm, gpi.getPlayer(), characterId);
- } else if (packet instanceof IntendedTarget) {
+ if (packet instanceof IntendedTarget) {
IntendedTarget intendedTarget = (IntendedTarget) packet;
CreatureObject creatureObject = gpi.getPlayer().getCreatureObject();
long targetId = intendedTarget.getTargetId();
@@ -266,36 +254,4 @@ public class ObjectManager extends Manager {
return object;
}
- private void zoneInCharacter(PlayerManager playerManager, Player player, long characterId) {
- SWGObject creatureObj = getObjectById(characterId);
- if (creatureObj == null) {
- Log.e("Failed to start zone - CreatureObject could not be fetched from database [Character: %d User: %s]", characterId, player.getUsername());
- sendClientFatal(player, "Failed to zone", "You were not found in the database\nTry relogging to fix this problem", 10, TimeUnit.SECONDS);
- return;
- }
- if (!(creatureObj instanceof CreatureObject)) {
- Log.e("Failed to start zone - Object is not a CreatureObject [Character: %d User: %s]", characterId, player.getUsername());
- sendClientFatal(player, "Failed to zone", "There has been an internal server error: Not a Creature.\nPlease delete your character and create a new one", 10, TimeUnit.SECONDS);
- return;
- }
- if (((CreatureObject) creatureObj).getPlayerObject() == null) {
- Log.e("Failed to start zone - CreatureObject doesn't have a ghost [Character: %d User: %s", characterId, player.getUsername());
- sendClientFatal(player, "Failed to zone", "There has been an internal server error: Null Ghost.\nPlease delete your character and create a new one", 10, TimeUnit.SECONDS);
- return;
- }
- new RequestZoneInIntent(player, (CreatureObject) creatureObj).broadcast();
- }
-
- private void sendClientFatal(Player player, String title, String message, long timeToRead, TimeUnit time) {
- player.sendPacket(new ErrorMessage(title, message, false));
- ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor();
- service.schedule(new Runnable() {
- @Override
- public void run() {
- player.sendPacket(new ErrorMessage(title, message, true));
- service.shutdownNow();
- }
- }, timeToRead, time);
- }
-
}
diff --git a/src/services/player/ZoneManager.java b/src/services/player/ZoneManager.java
index 9285fc4fa..dcdf955ca 100644
--- a/src/services/player/ZoneManager.java
+++ b/src/services/player/ZoneManager.java
@@ -54,7 +54,9 @@ import network.packets.swg.zone.SetWaypointColor;
import network.packets.swg.zone.ShowBackpack;
import network.packets.swg.zone.ShowHelmet;
import network.packets.swg.zone.chat.ChatSystemMessage;
+import network.packets.swg.zone.insertion.SelectCharacter;
import resources.config.ConfigFile;
+import resources.objects.SWGObject;
import resources.objects.creature.CreatureMood;
import resources.objects.player.PlayerObject;
import resources.objects.waypoint.WaypointObject;
@@ -63,15 +65,19 @@ import resources.player.Player;
import resources.player.Player.PlayerServer;
import resources.player.PlayerEvent;
import resources.server_info.DataManager;
+import services.objects.ObjectManager;
+import services.player.zone.ZoneRequester;
public class ZoneManager extends Manager {
private final CharacterCreationService characterCreationService;
+ private final ZoneRequester zoneRequester;
private String commitHistory;
public ZoneManager() {
characterCreationService = new CharacterCreationService();
+ zoneRequester = new ZoneRequester();
commitHistory = "";
addChildService(characterCreationService);
@@ -113,6 +119,8 @@ public class ZoneManager extends Manager {
handleShowHelmet(player, (ShowHelmet) p);
if (p instanceof LagRequest && player.getPlayerServer() == PlayerServer.ZONE)
handleLagRequest(player);
+ if (p instanceof SelectCharacter)
+ handleSelectCharacter(intent.getObjectManager(), player, ((SelectCharacter) p).getCharacterId());
}
public boolean characterExistsForName(String name) {
@@ -199,4 +207,9 @@ public class ZoneManager extends Manager {
player.sendPacket(new ClientPermissionsMessage());
}
+ private void handleSelectCharacter(ObjectManager objectManager, Player player, long characterId) {
+ SWGObject creatureObj = objectManager.getObjectById(characterId);
+ zoneRequester.onZoneRequested(creatureObj, player, characterId);
+ }
+
}
diff --git a/src/services/player/zone/ZoneRequester.java b/src/services/player/zone/ZoneRequester.java
new file mode 100644
index 000000000..4c9eadd07
--- /dev/null
+++ b/src/services/player/zone/ZoneRequester.java
@@ -0,0 +1,94 @@
+/************************************************************************************
+ * 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 services.player.zone;
+
+import java.util.concurrent.TimeUnit;
+
+import com.projectswg.common.data.location.Location;
+import com.projectswg.common.data.location.Terrain;
+import com.projectswg.common.debug.Log;
+
+import intents.RequestZoneInIntent;
+import intents.chat.ChatBroadcastIntent;
+import network.packets.swg.ErrorMessage;
+import resources.config.ConfigFile;
+import resources.objects.SWGObject;
+import resources.objects.creature.CreatureObject;
+import resources.player.Player;
+import resources.server_info.DataManager;
+import utilities.ScheduledUtilities;
+
+public class ZoneRequester {
+
+ public boolean onZoneRequested(SWGObject creatureObject, Player player, long characterId) {
+ if (!initialChecks(creatureObject, player, characterId))
+ return false;
+ if (!debugChecks(creatureObject, player, characterId))
+ return false;
+ new RequestZoneInIntent(player, (CreatureObject) creatureObject).broadcast();
+ return true;
+ }
+
+ private boolean initialChecks(SWGObject creatureObject, Player player, long characterId) {
+ if (creatureObject == null) {
+ Log.e("Failed to start zone - CreatureObject could not be fetched from database [Character: %d User: %s]", characterId, player.getUsername());
+ sendClientFatal(player, "Failed to zone", "You were not found in the database\nTry relogging to fix this problem", 10, TimeUnit.SECONDS);
+ return false;
+ }
+ if (!(creatureObject instanceof CreatureObject)) {
+ Log.e("Failed to start zone - Object is not a CreatureObject [Character: %d User: %s]", characterId, player.getUsername());
+ sendClientFatal(player, "Failed to zone", "There has been an internal server error: Not a Creature.\nPlease delete your character and create a new one", 10, TimeUnit.SECONDS);
+ return false;
+ }
+ if (((CreatureObject) creatureObject).getPlayerObject() == null) {
+ Log.e("Failed to start zone - CreatureObject doesn't have a ghost [Character: %d User: %s", characterId, player.getUsername());
+ sendClientFatal(player, "Failed to zone", "There has been an internal server error: Null Ghost.\nPlease delete your character and create a new one", 10, TimeUnit.SECONDS);
+ return false;
+ }
+ return true;
+ }
+
+ private boolean debugChecks(SWGObject creatureObject, Player player, long characterId) {
+ if (isSafeZone()) {
+ Location safeLocation = new Location(0, 0, 0, Terrain.DEV_AREA);
+ creatureObject.setLocation(safeLocation);
+ new ChatBroadcastIntent(player, "Safe-zoning into dev terrain at " + safeLocation.getPosition()).broadcast();
+ }
+ return true;
+ }
+
+ private boolean isSafeZone() {
+ return DataManager.getConfig(ConfigFile.DEBUG).getBoolean("DEBUG-ZONE-SAFE", false);
+ }
+
+ private void sendClientFatal(Player player, String title, String message, long timeToRead, TimeUnit time) {
+ player.sendPacket(new ErrorMessage(title, message, false));
+ ScheduledUtilities.run(() -> player.sendPacket(new ErrorMessage(title, message, true)), timeToRead, time);
+ }
+
+}
diff --git a/src/utilities/Scripts.java b/src/utilities/Scripts.java
index 4dde887c0..e8ebb0cb7 100644
--- a/src/utilities/Scripts.java
+++ b/src/utilities/Scripts.java
@@ -40,25 +40,33 @@ import javax.script.ScriptException;
import com.projectswg.common.debug.Log;
-
public class Scripts {
-
- private static final String SCRIPTS = "scripts/";
- private static final String EXTENSION = ".js";
- private static final ScriptEngine ENGINE = new ScriptEngineManager().getEngineByName("nashorn");
- private static final Invocable INVOCABLE = (Invocable) ENGINE;
+
+ private static final String SCRIPTS;
+ private static final String EXTENSION;
+ private static final ScriptEngine ENGINE;
+ private static final Invocable INVOCABLE;
static {
- ENGINE.put("intentFactory", new IntentFactory());
- try {
- ENGINE.eval("var RadialOption = Java.type('resources.radial.RadialOption')");
- ENGINE.eval("var RadialItem = Java.type('resources.radial.RadialItem')");
- ENGINE.eval("var Log = Java.type('resources.server_info.Log')");
- ENGINE.eval("var SuiWindow = Java.type('resources.sui.SuiWindow')");
- ENGINE.eval("var SuiButtons = Java.type('resources.sui.SuiButtons')");
- ENGINE.eval("var SuiEvent = Java.type('resources.sui.SuiEvent')");
- } catch (ScriptException e) {
- Log.e(e);
+ ScriptEngineManager engineManager = new ScriptEngineManager();
+ SCRIPTS = "scripts/";
+ EXTENSION = ".js";
+ ENGINE = engineManager.getEngineByName("nashorn");
+ INVOCABLE = (Invocable) ENGINE;
+ if (ENGINE == null) {
+ Log.e("ScriptEngine is null!");
+ } else {
+ try {
+ ENGINE.put("intentFactory", new IntentFactory());
+ ENGINE.eval("var RadialOption = Java.type('resources.radial.RadialOption')");
+ ENGINE.eval("var RadialItem = Java.type('resources.radial.RadialItem')");
+ ENGINE.eval("var Log = Java.type('com.projectswg.common.debug.Log')");
+ ENGINE.eval("var SuiWindow = Java.type('resources.sui.SuiWindow')");
+ ENGINE.eval("var SuiButtons = Java.type('resources.sui.SuiButtons')");
+ ENGINE.eval("var SuiEvent = Java.type('resources.sui.SuiEvent')");
+ } catch (Throwable t) {
+ Log.e(t);
+ }
}
}
diff --git a/test/resources/objects/awareness/TestAware.java b/test/resources/objects/awareness/TestAware.java
index f4dacab7c..0baebcb61 100644
--- a/test/resources/objects/awareness/TestAware.java
+++ b/test/resources/objects/awareness/TestAware.java
@@ -37,6 +37,7 @@ import org.junit.runners.JUnit4;
import resources.objects.SWGObject;
import resources.objects.cell.CellObject;
import resources.player.Player;
+import test_resources.GenericCreatureObject;
@RunWith(JUnit4.class)
public class TestAware {
diff --git a/test/resources/objects/awareness/TestAwarenessHandler.java b/test/resources/objects/awareness/TestAwarenessHandler.java
index a932baef3..f8ba94ed0 100644
--- a/test/resources/objects/awareness/TestAwarenessHandler.java
+++ b/test/resources/objects/awareness/TestAwarenessHandler.java
@@ -44,6 +44,7 @@ import resources.objects.SWGObject;
import resources.objects.building.BuildingObject;
import resources.objects.creature.CreatureObject;
import services.objects.ClientBuildoutService;
+import test_resources.GenericCreatureObject;
@RunWith(JUnit4.class)
public class TestAwarenessHandler {
diff --git a/test/resources/objects/awareness/TestTerrainMap.java b/test/resources/objects/awareness/TestTerrainMap.java
index 204055ae1..e14ade838 100644
--- a/test/resources/objects/awareness/TestTerrainMap.java
+++ b/test/resources/objects/awareness/TestTerrainMap.java
@@ -46,6 +46,7 @@ import resources.objects.SWGObject;
import resources.objects.cell.CellObject;
import resources.objects.creature.CreatureObject;
import services.objects.ClientBuildoutService;
+import test_resources.GenericCreatureObject;
@RunWith(JUnit4.class)
public class TestTerrainMap {
@@ -121,6 +122,7 @@ public class TestTerrainMap {
AtomicBoolean onlyWithinRange = new AtomicBoolean(true);
GenericCreatureObject creature = new GenericCreatureObject(1);
MapCallback callback = new MapCallback() {
+ @Override
public void onWithinRange(SWGObject obj, SWGObject inRange) {
if (obj.equals(creature) && !withinRange.remove(inRange)) {
Log.e("Not in list: %s", inRange);
diff --git a/test/resources/objects/awareness/TestTerrainMapChunk.java b/test/resources/objects/awareness/TestTerrainMapChunk.java
index 64f672168..9ab4cdebf 100644
--- a/test/resources/objects/awareness/TestTerrainMapChunk.java
+++ b/test/resources/objects/awareness/TestTerrainMapChunk.java
@@ -39,6 +39,7 @@ import com.projectswg.common.data.location.Terrain;
import resources.objects.SWGObject;
import resources.objects.cell.CellObject;
+import test_resources.GenericCreatureObject;
@RunWith(JUnit4.class)
public class TestTerrainMapChunk {
diff --git a/src/resources/network/NetworkCallback.java b/test/services/player/zone/TestZoneRequester.java
similarity index 54%
rename from src/resources/network/NetworkCallback.java
rename to test/services/player/zone/TestZoneRequester.java
index 4f0541d14..b989ae88a 100644
--- a/src/resources/network/NetworkCallback.java
+++ b/test/services/player/zone/TestZoneRequester.java
@@ -25,15 +25,74 @@
* along with Holocore. If not, see . *
* *
***********************************************************************************/
-package resources.network;
+package services.player.zone;
-import java.net.Socket;
-import java.net.SocketAddress;
+import java.util.concurrent.atomic.AtomicBoolean;
-public interface NetworkCallback {
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import network.packets.Packet;
+import network.packets.swg.ErrorMessage;
+import resources.objects.player.PlayerObject;
+import resources.player.Player;
+import test_resources.GenericCreatureObject;
+
+@RunWith(JUnit4.class)
+public class TestZoneRequester {
- void onIncomingConnection(Socket s, SocketAddress addr);
- void onConnectionDisconnect(Socket s, SocketAddress addr);
- void onIncomingData(Socket s, SocketAddress addr, byte [] data);
+ @Test
+ public void testNullCreatureObject() {
+ ZoneRequester zr = new ZoneRequester();
+ TZRPlayer player = new TZRPlayer();
+ Assert.assertFalse(zr.onZoneRequested(null, player, 0));
+ Assert.assertTrue(player.isSentError());
+ }
+
+
+ @Test
+ public void testInvalidCreatureObject() {
+ ZoneRequester zr = new ZoneRequester();
+ TZRPlayer player = new TZRPlayer();
+ Assert.assertFalse(zr.onZoneRequested(new PlayerObject(1), player, 0));
+ Assert.assertTrue(player.isSentError());
+ }
+
+ @Test
+ public void testNullPlayerObject() {
+ ZoneRequester zr = new ZoneRequester();
+ TZRPlayer player = new TZRPlayer();
+ GenericCreatureObject creature = new GenericCreatureObject(5);
+ creature.setSlot("ghost", null);
+ Assert.assertFalse(zr.onZoneRequested(creature, player, 5));
+ Assert.assertTrue(player.isSentError());
+ }
+
+ @Test
+ public void testValidCreatureObject() {
+ ZoneRequester zr = new ZoneRequester();
+ TZRPlayer player = new TZRPlayer();
+ GenericCreatureObject creature = new GenericCreatureObject(5);
+ Assert.assertTrue(zr.onZoneRequested(creature, player, 5));
+ Assert.assertFalse(player.isSentError());
+ }
+
+ private static class TZRPlayer extends Player {
+
+ private final AtomicBoolean sentError = new AtomicBoolean(false);
+
+ @Override
+ public void sendPacket(Packet ... packets) {
+ if (packets.length == 1 && packets[0] instanceof ErrorMessage)
+ sentError.set(true);
+ }
+
+ public boolean isSentError() {
+ return sentError.get();
+ }
+
+ }
}
diff --git a/test/resources/objects/awareness/GenericCreatureObject.java b/test/test_resources/GenericCreatureObject.java
similarity index 96%
rename from test/resources/objects/awareness/GenericCreatureObject.java
rename to test/test_resources/GenericCreatureObject.java
index 96973b460..20109851b 100644
--- a/test/resources/objects/awareness/GenericCreatureObject.java
+++ b/test/test_resources/GenericCreatureObject.java
@@ -25,7 +25,7 @@
* along with Holocore. If not, see . *
* *
***********************************************************************************/
-package resources.objects.awareness;
+package test_resources;
import network.packets.Packet;
import resources.objects.creature.CreatureObject;
@@ -33,13 +33,14 @@ import resources.objects.player.PlayerObject;
import resources.player.Player;
import resources.player.PlayerState;
-class GenericCreatureObject extends CreatureObject {
+public class GenericCreatureObject extends CreatureObject {
private Player player;
public GenericCreatureObject(long objectId) {
super(objectId);
player = new Player() {
+ @Override
public void sendPacket(Packet ... packets) {
// Nah
}