mirror of
https://bitbucket.org/projectswg/forwarder.git
synced 2026-01-16 23:04:26 -05:00
Added wait for client to acknowledge, for sending final packets
This commit is contained in:
@@ -6,6 +6,8 @@ import com.projectswg.control.Manager;
|
||||
import com.projectswg.networking.NetInterceptor;
|
||||
import com.projectswg.networking.Packet;
|
||||
import com.projectswg.networking.NetInterceptor.InterceptorProperties;
|
||||
import com.projectswg.networking.soe.Disconnect;
|
||||
import com.projectswg.networking.soe.Disconnect.DisconnectReason;
|
||||
|
||||
public class ClientConnection extends Manager {
|
||||
|
||||
@@ -36,6 +38,16 @@ public class ClientConnection extends Manager {
|
||||
return true;
|
||||
}
|
||||
|
||||
public void disconnect(DisconnectReason reason) {
|
||||
sender.send(new Disconnect(sender.getConnectionId(), reason));
|
||||
}
|
||||
|
||||
public void waitForClientAcknowledge() throws InterruptedException {
|
||||
while (sender.getTransmittedSequence()-1 > receiver.getAckSequence()) {
|
||||
Thread.sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void hardReset() {
|
||||
sender.hardReset();
|
||||
receiver.hardReset();
|
||||
|
||||
@@ -55,6 +55,7 @@ public class ClientReceiver extends Service {
|
||||
private ClientSender sender;
|
||||
private ClientConnectionStatus status;
|
||||
private short rxSequence;
|
||||
private short ackSequence;
|
||||
private int port;
|
||||
private boolean zone;
|
||||
|
||||
@@ -66,6 +67,8 @@ public class ClientReceiver extends Service {
|
||||
this.stateIntentChain = new IntentChain();
|
||||
this.timeout = timeout;
|
||||
this.status = ClientConnectionStatus.DISCONNECTED;
|
||||
this.rxSequence = -1;
|
||||
this.ackSequence = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -120,6 +123,8 @@ public class ClientReceiver extends Service {
|
||||
onDataChannel((DataChannelA) p);
|
||||
else if (p instanceof Fragmented)
|
||||
onFragmented((Fragmented) p);
|
||||
else if (p instanceof Acknowledge)
|
||||
onAcknowledge((Acknowledge) p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,6 +132,10 @@ public class ClientReceiver extends Service {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public short getAckSequence() {
|
||||
return ackSequence;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
rxSequence = -1;
|
||||
}
|
||||
@@ -301,6 +310,10 @@ public class ClientReceiver extends Service {
|
||||
process(combined);
|
||||
}
|
||||
|
||||
private void onAcknowledge(Acknowledge ack) {
|
||||
this.ackSequence = ack.getSequence();
|
||||
}
|
||||
|
||||
private void onSWGPacket(byte [] data) {
|
||||
data = interceptor.interceptClient(data);
|
||||
recvIntentChain.broadcastAfter(new ClientToServerPacketIntent(data), getIntentManager());
|
||||
|
||||
@@ -102,6 +102,10 @@ public class ClientSender extends Service {
|
||||
return super.stop();
|
||||
}
|
||||
|
||||
public short getTransmittedSequence() {
|
||||
return packager.getSequence();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onIntentReceived(Intent i) {
|
||||
if (i instanceof ServerToClientPacketIntent) {
|
||||
|
||||
@@ -13,6 +13,7 @@ import com.projectswg.intents.ClientToServerPacketIntent;
|
||||
import com.projectswg.intents.ServerConnectionChangedIntent;
|
||||
import com.projectswg.intents.ServerToClientPacketIntent;
|
||||
import com.projectswg.networking.NetInterceptor.InterceptorProperties;
|
||||
import com.projectswg.networking.soe.Disconnect.DisconnectReason;
|
||||
import com.projectswg.resources.ClientConnectionStatus;
|
||||
import com.projectswg.resources.ServerConnectionStatus;
|
||||
import com.projectswg.services.PacketRecordingService;
|
||||
@@ -140,6 +141,12 @@ public class Connections extends Manager {
|
||||
error += "\nInstalled Version: " + VERSION;
|
||||
client.send(new ErrorMessage("Network", error, false));
|
||||
}
|
||||
try {
|
||||
client.waitForClientAcknowledge();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
client.disconnect(DisconnectReason.OTHER_SIDE_TERMINATED);
|
||||
client.hardReset();
|
||||
}
|
||||
}
|
||||
|
||||
101
src/com/projectswg/control/Assert.java
Normal file
101
src/com/projectswg/control/Assert.java
Normal file
@@ -0,0 +1,101 @@
|
||||
/***********************************************************************************
|
||||
* 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 <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.control;
|
||||
|
||||
import resources.server_info.Log;
|
||||
|
||||
public class Assert {
|
||||
|
||||
private static volatile AssertLevel level = AssertLevel.ASSERT;
|
||||
|
||||
public static void setLevel(AssertLevel level) {
|
||||
Assert.level = level;
|
||||
}
|
||||
|
||||
public static boolean debug() {
|
||||
return level != AssertLevel.IGNORE;
|
||||
}
|
||||
|
||||
public static void notNull(Object o) {
|
||||
if (debug() && o == null)
|
||||
handle(new NullPointerException());
|
||||
}
|
||||
|
||||
public static void isNull(Object o) {
|
||||
if (debug() && o != null)
|
||||
handle(new AssertionException());
|
||||
}
|
||||
|
||||
public static void test(boolean expr) {
|
||||
if (debug() && !expr)
|
||||
handle(new AssertionException());
|
||||
}
|
||||
|
||||
public static void fail() {
|
||||
if (debug())
|
||||
handle(new AssertionException());
|
||||
}
|
||||
|
||||
private static void handle(RuntimeException e) {
|
||||
AssertLevel level = Assert.level;
|
||||
switch (level) {
|
||||
case WARN:
|
||||
warn(e);
|
||||
break;
|
||||
case ASSERT:
|
||||
throw e;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void warn(Exception e) {
|
||||
StackTraceElement [] elements = e.getStackTrace();
|
||||
if (elements.length <= 1)
|
||||
Log.e("Assert", e);
|
||||
else
|
||||
Log.e(elements[elements.length-2].getClassName(), e);
|
||||
}
|
||||
|
||||
private static class AssertionException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public AssertionException() {
|
||||
super("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public enum AssertLevel {
|
||||
IGNORE,
|
||||
WARN,
|
||||
ASSERT
|
||||
}
|
||||
|
||||
}
|
||||
@@ -52,7 +52,6 @@ public class IntentManager {
|
||||
public IntentManager() {
|
||||
intentRegistrations = new HashMap<String, Set<IntentReceiver>>();
|
||||
intentQueue = new IntentQueue();
|
||||
initialize();
|
||||
broadcastRunnable = () -> {
|
||||
Intent i;
|
||||
synchronized (intentQueue) {
|
||||
@@ -82,8 +81,7 @@ public class IntentManager {
|
||||
protected void broadcastIntent(Intent i) {
|
||||
if (i == null)
|
||||
throw new NullPointerException("Intent cannot be null!");
|
||||
if (!initialized)
|
||||
return;
|
||||
Assert.test(initialized);
|
||||
synchronized (intentQueue) {
|
||||
intentQueue.add(i);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,6 @@ public class NetInterceptor {
|
||||
g.setAddress("127.0.0.1");
|
||||
g.setZonePort((short) properties.getPort());
|
||||
g.setPingPort((short) properties.getPort());
|
||||
g.setPopulation(-1);
|
||||
}
|
||||
return cluster.encode().array();
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ package com.projectswg.networking.soe;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import resources.control.Assert;
|
||||
|
||||
import com.projectswg.networking.Packet;
|
||||
|
||||
public class Acknowledge extends Packet {
|
||||
@@ -48,8 +50,7 @@ public class Acknowledge extends Packet {
|
||||
}
|
||||
|
||||
public void decode(ByteBuffer data) {
|
||||
if (data.array().length < 4)
|
||||
return;
|
||||
Assert.test(data.array().length == 4);
|
||||
data.position(2);
|
||||
sequence = getNetShort(data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user