diff --git a/src/intents/network/InboundUdpPacketIntent.java b/src/intents/network/InboundUdpPacketIntent.java deleted file mode 100644 index a40121d9..00000000 --- a/src/intents/network/InboundUdpPacketIntent.java +++ /dev/null @@ -1,63 +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 intents.network; - -import resources.control.Intent; -import resources.network.ServerType; -import resources.network.UDPServer.UDPPacket; - -public class InboundUdpPacketIntent extends Intent { - - public static final String TYPE = "InboundUdpPacketIntent"; - - private UDPPacket packet; - private ServerType type; - - public InboundUdpPacketIntent(ServerType type, UDPPacket p) { - super(TYPE); - setPacket(p); - setServerType(type); - } - - public void setPacket(UDPPacket p) { - this.packet = p; - } - - public void setServerType(ServerType type) { - this.type = type; - } - - public UDPPacket getPacket() { - return packet; - } - - public ServerType getServerType() { - return type; - } - -} diff --git a/src/intents/network/OutboundUdpPacketIntent.java b/src/intents/network/OutboundUdpPacketIntent.java deleted file mode 100644 index d1a68377..00000000 --- a/src/intents/network/OutboundUdpPacketIntent.java +++ /dev/null @@ -1,63 +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 intents.network; - -import resources.control.Intent; -import resources.network.ServerType; -import resources.network.UDPServer.UDPPacket; - -public class OutboundUdpPacketIntent extends Intent { - - public static final String TYPE = "OutboundUdpPacketIntent"; - - private UDPPacket packet; - private ServerType type; - - public OutboundUdpPacketIntent(ServerType type, UDPPacket p) { - super(TYPE); - setPacket(p); - setServerType(type); - } - - public void setPacket(UDPPacket p) { - this.packet = p; - } - - public void setServerType(ServerType type) { - this.type = type; - } - - public UDPPacket getPacket() { - return packet; - } - - public ServerType getServerType() { - return type; - } - -} diff --git a/src/main/ProjectSWG.java b/src/main/ProjectSWG.java index 2510a3b0..e0ae16ea 100644 --- a/src/main/ProjectSWG.java +++ b/src/main/ProjectSWG.java @@ -31,10 +31,13 @@ import intents.server.ServerStatusIntent; import resources.Galaxy.GalaxyStatus; import resources.control.IntentManager; import resources.control.ServerStatus; +import resources.server_info.Log; import services.CoreManager; public class ProjectSWG { + private static final String [] ENDINGS = {"B", "KB", "MB", "GB"}; + private static ProjectSWG server; private final Thread mainThread; private CoreManager manager; @@ -132,6 +135,7 @@ public class ProjectSWG { private void loop() { setStatus((manager.getGalaxyStatus() == GalaxyStatus.UP) ? ServerStatus.OPEN : ServerStatus.LOCKED); + long iter = 0; while (!shutdownRequested && !manager.isShutdownRequested() && manager.isOperational()) { manager.flushPackets(); // Sends any packets that weren't sent try { @@ -139,9 +143,25 @@ public class ProjectSWG { } catch (InterruptedException e) { throw new CoreException("Main Thread Interrupted."); } + iter++; + if (iter % 20 == 0) { + final Runtime r = Runtime.getRuntime(); + Log.i("ProjectSWG", "Memory Consumption: %s", getMemory((r.totalMemory()-r.freeMemory()))); + } } } + private String getMemory(long bytes) { + double val = bytes; + int iters = 0; + while (val >= 1024) { + val /= 1024; + iters++; + } + val = ((int) (val * 1E5)) / 1E5; + return val + ENDINGS[iters]; + } + private void stop() { if (manager == null || status == ServerStatus.OFFLINE) return; diff --git a/src/network/FragmentedHandler.java b/src/network/FragmentedHandler.java index 712b505c..f164215b 100644 --- a/src/network/FragmentedHandler.java +++ b/src/network/FragmentedHandler.java @@ -28,17 +28,18 @@ package network; import java.nio.ByteOrder; +import java.util.ArrayList; +import java.util.List; import network.packets.soe.Fragmented; -import resources.SortedLinkedList; public class FragmentedHandler { - private SortedLinkedList fragPackets; + private List fragPackets; private int fragSize; public FragmentedHandler() { - fragPackets = new SortedLinkedList(); + fragPackets = new ArrayList(); fragSize = 0; } @@ -52,8 +53,8 @@ public class FragmentedHandler { if (insertIfNew(f) && getBufferedSize() == fragSize) { byte [] data = new byte[fragSize]; int offset = 0; - while (fragPackets.size() > 0 && offset < fragSize) { - offset = spliceFragmentedIntoBuffer(fragPackets.removeFirst(), data, offset); + for (Fragmented frag : fragPackets) { + offset = spliceFragmentedIntoBuffer(frag, data, offset); } updateMetadata(); return data; @@ -85,14 +86,14 @@ public class FragmentedHandler { if (fragPackets.isEmpty()) fragSize = 0; else - fragSize = fragPackets.getFirst().encode().order(ByteOrder.BIG_ENDIAN).getInt(4); + fragSize = fragPackets.get(0).encode().order(ByteOrder.BIG_ENDIAN).getInt(4); } } private int getBufferedSize() { int curSize = 0; int i = 0; - short prevSeq = (short) (fragPackets.getFirst().getSequence()-1); + short prevSeq = (short) (fragPackets.get(0).getSequence()-1); for (Fragmented frag : fragPackets) { // Update previous sequence and verify all in-order if (prevSeq+1 != frag.getSequence()) diff --git a/src/network/InboundNetworkHandler.java b/src/network/InboundNetworkHandler.java index 72074d0f..c8aa7261 100644 --- a/src/network/InboundNetworkHandler.java +++ b/src/network/InboundNetworkHandler.java @@ -64,6 +64,7 @@ public class InboundNetworkHandler { public synchronized void reset() { fragStream.reset(); + inboundQueue.clear(); recvSequence = -1; crc = 0; } diff --git a/src/network/NetworkClient.java b/src/network/NetworkClient.java index e95c7e0a..7102e85f 100644 --- a/src/network/NetworkClient.java +++ b/src/network/NetworkClient.java @@ -47,10 +47,10 @@ public class NetworkClient { private int port; private int connId; - public NetworkClient(ServerType type, InetAddress addr, int port, long networkId) { + public NetworkClient(ServerType type, InetAddress addr, int port, long networkId, PacketSender packetSender) { this.serverType = type; this.networkId = networkId; - protocol = new NetworkProtocol(type, addr, port); + protocol = new NetworkProtocol(type, addr, port, packetSender); prevPacketIntent = null; connId = 0; updateNetworkInfo(addr, port); diff --git a/src/network/NetworkProtocol.java b/src/network/NetworkProtocol.java index 7d2d88d7..afdcd2c3 100644 --- a/src/network/NetworkProtocol.java +++ b/src/network/NetworkProtocol.java @@ -27,15 +27,13 @@ ***********************************************************************************/ package network; -import intents.network.OutboundUdpPacketIntent; - import java.net.InetAddress; import java.util.LinkedList; import java.util.List; -import resources.control.Intent; import resources.network.ServerType; import resources.network.UDPServer.UDPPacket; +import resources.server_info.Log; import network.InboundNetworkHandler.InboundEventCallback; import network.packets.Packet; import network.packets.soe.Acknowledge; @@ -45,21 +43,20 @@ import network.packets.soe.ServerNetworkStatusUpdate; public class NetworkProtocol implements InboundEventCallback { - private final Object prevOutboundIntentMutex = new Object(); private final InboundNetworkHandler inbound; private final OutboundNetworkHandler outbound; private final ServerType serverType; + private final PacketSender packetSender; - private Intent prevOutboundIntent; private InetAddress address; private int port; private int crc; - public NetworkProtocol(ServerType type, InetAddress address, int port) { + public NetworkProtocol(ServerType type, InetAddress address, int port, PacketSender packetSender) { this.inbound = new InboundNetworkHandler(this); this.outbound = new OutboundNetworkHandler(); this.serverType = type; - prevOutboundIntent = null; + this.packetSender = packetSender; crc = 0; updateNetworkInfo(address, port); } @@ -92,7 +89,6 @@ public class NetworkProtocol implements InboundEventCallback { public void resetNetwork() { inbound.reset(); outbound.reset(); - prevOutboundIntent = null; } public List process(byte [] data) { @@ -105,7 +101,7 @@ public class NetworkProtocol implements InboundEventCallback { private void process(List packets, Packet packet) { if (packet == null) - return; + throw new NullPointerException("Inbound packet cannot be null!"); packets.add(packet); if (packet instanceof Acknowledge) outbound.onAcknowledge(((Acknowledge) packet).getSequence()); @@ -117,21 +113,18 @@ public class NetworkProtocol implements InboundEventCallback { } public void sendPacket(Packet packet) { - if (address == null) + if (address == null) { + Log.w("NetworkProtocol", "Address is null! Cannot send packet"); return; + } outbound.assemble(packet); flushAssembled(); } private void send(byte [] data) { if (data == null) - return; - UDPPacket packet = new UDPPacket(address, port, data); - OutboundUdpPacketIntent intent = new OutboundUdpPacketIntent(serverType, packet); - synchronized (prevOutboundIntentMutex) { - intent.broadcastAfterIntent(prevOutboundIntent); - prevOutboundIntent = intent; - } + throw new NullPointerException("Outbound data cannot be null!"); + packetSender.sendPacket(serverType, new UDPPacket(address, port, data)); } private void processClientNetworkUpdate(ClientNetworkStatusUpdate update) { diff --git a/src/network/OutboundNetworkHandler.java b/src/network/OutboundNetworkHandler.java index 8e962e5d..97788d1d 100644 --- a/src/network/OutboundNetworkHandler.java +++ b/src/network/OutboundNetworkHandler.java @@ -74,7 +74,7 @@ public class OutboundNetworkHandler { public synchronized void onAcknowledge(short sequence) { synchronized (sequenced) { - Iterator it = sequenced.iterator(); + Iterator it = sequenced.listIterator(); while (it.hasNext()) { SequencedPacket sp = it.next(); if (sp.getSequence() <= sequence) @@ -87,7 +87,7 @@ public class OutboundNetworkHandler { public synchronized void onOutOfOrder(short sequence) { synchronized (sequenced) { - Iterator it = sequenced.iterator(); + Iterator it = sequenced.listIterator(); while (it.hasNext()) { SequencedPacket sp = it.next(); if (sp.getSequence() <= sequence) diff --git a/src/network/PacketReceiver.java b/src/network/PacketReceiver.java new file mode 100644 index 00000000..f0d8852f --- /dev/null +++ b/src/network/PacketReceiver.java @@ -0,0 +1,10 @@ +package network; + +import resources.network.ServerType; +import resources.network.UDPServer.UDPPacket; + +public interface PacketReceiver { + + void receivePacket(ServerType type, UDPPacket packet); + +} diff --git a/src/network/PacketSender.java b/src/network/PacketSender.java new file mode 100644 index 00000000..8fc8dac2 --- /dev/null +++ b/src/network/PacketSender.java @@ -0,0 +1,10 @@ +package network; + +import resources.network.ServerType; +import resources.network.UDPServer.UDPPacket; + +public interface PacketSender { + + void sendPacket(ServerType type, UDPPacket packet); + +} diff --git a/src/resources/control/Intent.java b/src/resources/control/Intent.java index 7703333a..6b8152dd 100644 --- a/src/resources/control/Intent.java +++ b/src/resources/control/Intent.java @@ -51,6 +51,7 @@ public abstract class Intent { this.complete = true; if (sequential != null) sequential.broadcast(); + sequential = null; } /** @@ -124,6 +125,7 @@ public abstract class Intent { IntentManager.getInstance().broadcastIntent(this); if (parallel != null) parallel.broadcast(); + parallel = null; } @Override diff --git a/src/services/network/NetworkClientManager.java b/src/services/network/NetworkClientManager.java index a35bc654..548ef21d 100644 --- a/src/services/network/NetworkClientManager.java +++ b/src/services/network/NetworkClientManager.java @@ -29,7 +29,6 @@ package services.network; import intents.network.CloseConnectionIntent; import intents.network.InboundPacketIntent; -import intents.network.InboundUdpPacketIntent; import intents.network.OutboundPacketIntent; import java.net.InetAddress; @@ -41,6 +40,8 @@ import java.util.Map; import java.util.Random; import network.NetworkClient; +import network.PacketReceiver; +import network.PacketSender; import network.packets.Packet; import network.packets.soe.Disconnect; import network.packets.soe.SessionRequest; @@ -52,14 +53,16 @@ import resources.control.Manager; import resources.network.ServerType; import resources.network.UDPServer.UDPPacket; -public class NetworkClientManager extends Manager { +public class NetworkClientManager extends Manager implements PacketReceiver { private final Map > clients; private final Map networkClients; private final Random crcGenerator; + private final PacketSender packetSender; private long networkId; - public NetworkClientManager() { + public NetworkClientManager(PacketSender packetSender) { + this.packetSender = packetSender; clients = new HashMap>(); networkClients = new HashMap(); crcGenerator = new Random(); @@ -68,7 +71,6 @@ public class NetworkClientManager extends Manager { @Override public boolean initialize() { - registerForIntent(InboundUdpPacketIntent.TYPE); registerForIntent(InboundPacketIntent.TYPE); registerForIntent(OutboundPacketIntent.TYPE); registerForIntent(CloseConnectionIntent.TYPE); @@ -83,14 +85,14 @@ public class NetworkClientManager extends Manager { return super.stop(); } + @Override + public void receivePacket(ServerType type, UDPPacket packet) { + handlePacket(type, packet); + } + + @Override public void onIntentReceived(Intent i) { - if (i instanceof InboundUdpPacketIntent) { - InboundUdpPacketIntent inbound = (InboundUdpPacketIntent) i; - UDPPacket p = inbound.getPacket(); - if (p != null) { - handlePacket(inbound.getServerType(), p); - } - } else if (i instanceof OutboundPacketIntent) { + if (i instanceof OutboundPacketIntent) { Packet p = ((OutboundPacketIntent)i).getPacket(); if (p != null) handleOutboundPacket(((OutboundPacketIntent) i).getNetworkId(), p); @@ -204,7 +206,7 @@ public class NetworkClientManager extends Manager { private NetworkClient createClient(ServerType type, InetAddress addr, int port) { synchronized (clients) { - NetworkClient client = new NetworkClient(type, addr, port, networkId++); + NetworkClient client = new NetworkClient(type, addr, port, networkId++, packetSender); List ipList = clients.get(addr); if (ipList == null) { ipList = new ArrayList(); @@ -250,6 +252,7 @@ public class NetworkClientManager extends Manager { } } } + client.resetNetwork(); } } return false; diff --git a/src/services/network/NetworkListenerService.java b/src/services/network/NetworkListenerService.java index 7b28ad5f..0a8cd5c8 100644 --- a/src/services/network/NetworkListenerService.java +++ b/src/services/network/NetworkListenerService.java @@ -27,14 +27,13 @@ ***********************************************************************************/ package services.network; -import intents.network.InboundUdpPacketIntent; - import java.net.InetAddress; import java.net.UnknownHostException; +import network.PacketReceiver; +import network.PacketSender; import resources.Galaxy; import resources.config.ConfigFile; -import resources.control.Intent; import resources.control.Service; import resources.network.ServerType; import resources.network.UDPServer; @@ -42,7 +41,7 @@ import resources.network.UDPServer.UDPCallback; import resources.network.UDPServer.UDPPacket; import resources.server_info.Config; -public class NetworkListenerService extends Service { +public class NetworkListenerService extends Service implements PacketSender { private Server login; private Server zone; @@ -56,6 +55,12 @@ public class NetworkListenerService extends Service { ping = new Server(ServerType.PING); } + public void setPacketReceiver(PacketReceiver packetReceiver) { + login.setPacketReceiver(packetReceiver); + zone.setPacketReceiver(packetReceiver); + ping.setPacketReceiver(packetReceiver); + } + private InetAddress getBindAddr(Config c, String firstTry, String secondTry) { String t = firstTry; try { @@ -113,6 +118,11 @@ public class NetworkListenerService extends Service { return true; } + @Override + public void sendPacket(ServerType type, UDPPacket packet) { + send(type, packet.getAddress(), packet.getPort(), packet.getData()); + } + public void send(ServerType type, InetAddress addr, int port, byte [] data) { switch (type) { case LOGIN: @@ -128,14 +138,17 @@ public class NetworkListenerService extends Service { } private class Server implements UDPCallback { - + private final ServerType type; + private PacketReceiver packetReceiver; private UDPServer server; - private Intent prevIntent; public Server(ServerType type) { this.type = type; - this.prevIntent = null; + } + + public void setPacketReceiver(PacketReceiver packetReceiver) { + this.packetReceiver = packetReceiver; } public boolean initialize(InetAddress bindAddr, int port, int maxPacket) { @@ -178,11 +191,8 @@ public class NetworkListenerService extends Service { public void onReceivedPacket(UDPPacket packet) { if (type == ServerType.PING) send(packet.getAddress(), packet.getPort(), packet.getData()); - else { - InboundUdpPacketIntent i = new InboundUdpPacketIntent(type, packet); - i.broadcastAfterIntent(prevIntent); - prevIntent = i; - } + else + packetReceiver.receivePacket(type, packet); } } diff --git a/src/services/network/NetworkManager.java b/src/services/network/NetworkManager.java index d722cdea..160a0fa4 100644 --- a/src/services/network/NetworkManager.java +++ b/src/services/network/NetworkManager.java @@ -27,12 +27,8 @@ ***********************************************************************************/ package services.network; -import intents.network.OutboundUdpPacketIntent; import resources.Galaxy; -import resources.control.Intent; import resources.control.Manager; -import resources.network.ServerType; -import resources.network.UDPServer.UDPPacket; public class NetworkManager extends Manager { @@ -41,25 +37,11 @@ public class NetworkManager extends Manager { public NetworkManager(Galaxy galaxy) { netListenerService = new NetworkListenerService(galaxy); - netClientManager = new NetworkClientManager(); + netClientManager = new NetworkClientManager(netListenerService); + netListenerService.setPacketReceiver(netClientManager); addChildService(netClientManager); addChildService(netListenerService); } - @Override - public boolean initialize() { - registerForIntent(OutboundUdpPacketIntent.TYPE); - return super.initialize(); - } - - @Override - public void onIntentReceived(Intent i) { - if (i instanceof OutboundUdpPacketIntent) { - UDPPacket packet = ((OutboundUdpPacketIntent) i).getPacket(); - ServerType type = ((OutboundUdpPacketIntent) i).getServerType(); - netListenerService.send(type, packet.getAddress(), packet.getPort(), packet.getData()); - } - } - } diff --git a/src/services/player/LoginService.java b/src/services/player/LoginService.java index e378dbc9..a3cbf9f3 100644 --- a/src/services/player/LoginService.java +++ b/src/services/player/LoginService.java @@ -328,7 +328,7 @@ public class LoginService extends Service { g.setName(set.getString("name")); g.setAddress(set.getString("address")); g.setPopulation(population); - g.setTimeZone(set.getInt("timezone")); + g.setTimeZone(set.getInt("timezone") * 3600); g.setZonePort(set.getInt("zone_port")); g.setPingPort(set.getInt("ping_port")); g.setStatus(set.getInt("status"));