diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..c8397c9
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/com/captainalm/lib/calmnet/packet/FragmentReceiver.java b/src/com/captainalm/lib/calmnet/packet/FragmentReceiver.java
index b8a2476..f914194 100644
--- a/src/com/captainalm/lib/calmnet/packet/FragmentReceiver.java
+++ b/src/com/captainalm/lib/calmnet/packet/FragmentReceiver.java
@@ -25,6 +25,7 @@ public final class FragmentReceiver {
private PacketLoader packetLoader;
private IPacketFactory packetFactory;
private boolean verifyResponses = false;
+ private boolean makeSureSendDataVerified = false;
/**
* Constructs a new FragmentReceiver with the specified {@link PacketLoader} and {@link IPacketFactory}.
@@ -262,12 +263,36 @@ public final class FragmentReceiver {
/**
* Sets whether responses should be verified.
+ * If set to false, {@link #setSentDataWillBeAllVerified(boolean)} will be set to false too.
*
* @param state If responses should be verified.
*/
public void setResponseVerification(boolean state) {
synchronized (slock) {
verifyResponses = state;
+ if (makeSureSendDataVerified && !state) makeSureSendDataVerified = false;
+ }
+ }
+
+ /**
+ * Gets whether all sent fragments are verified to be equal.
+ *
+ * @return If all sent fragments will be verified to be equal.
+ */
+ public boolean shouldSentDataBeAllVerified() {
+ return makeSureSendDataVerified;
+ }
+
+ /**
+ * Gets whether all sent fragments are verified to be equal.
+ * Requires {@link #setResponseVerification(boolean)} set to true.
+ *
+ * @param state If all sent fragments will be verified to be equal.
+ */
+ public void setSentDataWillBeAllVerified(boolean state) {
+ synchronized (slock) {
+ if (!verifyResponses) return;
+ makeSureSendDataVerified = state;
}
}
@@ -276,6 +301,7 @@ public final class FragmentReceiver {
* the {@link FragmentSendCompletePacket} or {@link FragmentRetrySendPacket} packets are sent.
* A {@link FragmentSendCompletePacket} is sent if completely received and a
* {@link FragmentRetrySendPacket} is sent if not completely received.
+ * This excludes empty packets due to {@link #shouldSentDataBeAllVerified()}.
*
* @return The number of send packet calls before a completion or restart is forced.
*/
@@ -288,6 +314,7 @@ public final class FragmentReceiver {
* the {@link FragmentSendCompletePacket} or {@link FragmentRetrySendPacket} packets are sent.
* A {@link FragmentSendCompletePacket} is sent if completely received and a
* {@link FragmentRetrySendPacket} is sent if not completely received.
+ * This excludes empty packets due to {@link #shouldSentDataBeAllVerified()}.
*
* @param numberOfEmptySends The number of empty sends to allow.
* @throws IllegalArgumentException numberOfEmptySends is less than 1.
@@ -297,6 +324,28 @@ public final class FragmentReceiver {
numberOfEmptySendsTillForced = numberOfEmptySends;
}
+ /**
+ * Stops data verification for the specified Packet ID when {@link #shouldSentDataBeAllVerified()} is true.
+ *
+ * @param id The PacketID to act on.
+ */
+ public void stopDataVerificationAndCompleteReceive(int id) {
+ synchronized (slock) {
+ if (!makeSureSendDataVerified) return;
+ FragmentInput input = registry.get(id);
+ if (input != null) input.verifyReceived = true;
+ }
+ }
+
+ /**
+ * Stops data verification for all packets being received when {@link #shouldSentDataBeAllVerified()} is true.
+ */
+ public void stopAllDataVerificationAndCompleteReceive() {
+ synchronized (slock) {
+ for (int c : registry.keySet()) registry.get(c).verifyReceived = true;
+ }
+ }
+
/**
* This class provides the ability to store allocated responses to be sent back.
*
@@ -334,6 +383,7 @@ public final class FragmentReceiver {
private int sendsTillCompleteForced;
private boolean fsendActive = false;
private final FragmentMessagePacket[] messagePackets;
+ public boolean verifyReceived = false;
public FragmentInput(int id, int count, UUID aid) {
packetID = id;
@@ -355,12 +405,16 @@ public final class FragmentReceiver {
if (fsendActive) {
if (sendsTillCompleteForced > 0) sendsTillCompleteForced--;
} else fsendActive = true;
- if (sendsTillCompleteForced == 0) return (idsToReceive.size() < 1) ? new FragmentSendCompletePacket(packetID, true) : new FragmentRetrySendPacket(packetID, false);
+ if (sendsTillCompleteForced == 0 && !(makeSureSendDataVerified && !verifyReceived)) return (idsToReceive.size() < 1) ? new FragmentSendCompletePacket(packetID, true) : new FragmentRetrySendPacket(packetID, false);
return null;
}
public void receivePacket(IPacket packetIn) {
if ((packetIn instanceof FragmentSendCompletePacket && !((FragmentSendCompletePacket) packetIn).isAcknowledgement())) sendsTillCompleteForced = 0;
+ if (packetIn instanceof FragmentSendVerifyCompletePacket) {
+ sendsTillCompleteForced = 0;
+ verifyReceived = true;
+ }
if ((packetIn instanceof FragmentRetrySendPacket && ((FragmentRetrySendPacket) packetIn).isAcknowledgement())) sendsTillCompleteForced = numberOfEmptySendsTillForced + 1;
if (packetIn instanceof FragmentMessagePacket) {
FragmentMessagePacket messagePacket = (FragmentMessagePacket) packetIn;
@@ -371,7 +425,7 @@ public final class FragmentReceiver {
}
public IPacket consume() throws PacketException {
- if (consumeDone || idsToReceive.size() > 0 || messagePackets.length < 1) return null;
+ if (consumeDone || idsToReceive.size() > 0 || messagePackets.length < 1 || (makeSureSendDataVerified && !verifyReceived)) return null;
ByteArrayOutputStream packetStream = new ByteArrayOutputStream(messagePackets[0].getFragmentMessage().length);
for (FragmentMessagePacket messagePacket : messagePackets) {
try {
diff --git a/src/com/captainalm/lib/calmnet/packet/FragmentSender.java b/src/com/captainalm/lib/calmnet/packet/FragmentSender.java
index 9a29518..d529254 100644
--- a/src/com/captainalm/lib/calmnet/packet/FragmentSender.java
+++ b/src/com/captainalm/lib/calmnet/packet/FragmentSender.java
@@ -19,6 +19,7 @@ public final class FragmentSender {
private int splitSize = 496;
private PacketLoader packetLoader;
private boolean verifyResponses = false;
+ private boolean makeSureSendDataVerified = false;
/**
* Constructs a new FragmentSender with the specified {@link PacketLoader}.
@@ -241,12 +242,58 @@ public final class FragmentSender {
/**
* Sets whether responses should be verified.
+ * If set to false, {@link #setSentDataWillBeAllVerified(boolean)} will be set to false too.
*
* @param state If responses should be verified.
*/
public void setResponseVerification(boolean state) {
synchronized (slock) {
verifyResponses = state;
+ if (makeSureSendDataVerified && !state) makeSureSendDataVerified = false;
+ }
+ }
+
+ /**
+ * Gets whether all sent fragments are verified to be equal.
+ *
+ * @return If all sent fragments will be verified to be equal.
+ */
+ public boolean shouldSentDataBeAllVerified() {
+ return makeSureSendDataVerified;
+ }
+
+ /**
+ * Gets whether all sent fragments are verified to be equal.
+ * Requires {@link #setResponseVerification(boolean)} set to true.
+ *
+ * @param state If all sent fragments will be verified to be equal.
+ */
+ public void setSentDataWillBeAllVerified(boolean state) {
+ synchronized (slock) {
+ if (!verifyResponses) return;
+ makeSureSendDataVerified = state;
+ }
+ }
+
+ /**
+ * Stops data verification for the specified Packet ID when {@link #shouldSentDataBeAllVerified()} is true.
+ *
+ * @param id The PacketID to act on.
+ */
+ public void stopDataVerificationAndCompleteSend(int id) {
+ synchronized (slock) {
+ if (!makeSureSendDataVerified) return;
+ FragmentOutput output = registry.get(id);
+ if (output != null) output.forceDataVerifiedSendStop = true;
+ }
+ }
+
+ /**
+ * Stops data verification for all packets being sent when {@link #shouldSentDataBeAllVerified()} is true.
+ */
+ public void stopAllDataVerificationAndCompleteSend() {
+ synchronized (slock) {
+ for (int c : registry.keySet()) registry.get(c).forceDataVerifiedSendStop = true;
}
}
@@ -263,6 +310,7 @@ public final class FragmentSender {
private final ArrayList msgToResendCurrent = new ArrayList<>();
private int msgPacketIndex = 0;
public boolean isResending = false;
+ public boolean forceDataVerifiedSendStop = false;
public FragmentOutput(int id, byte[] toSplit) {
packetID = id;
@@ -282,12 +330,14 @@ public final class FragmentSender {
msgPacketIndex = 0;
return new FragmentRetrySendPacket(packetID, true);
}
+ if (!isResending && makeSureSendDataVerified && msgPacketIndex >= messagePackets.length && !forceDataVerifiedSendStop) setResendingOn(true);
if (isResending) {
+ if (makeSureSendDataVerified && msgPacketIndex >= msgToResendCurrent.size() && !forceDataVerifiedSendStop) setResendingOn(true);
if (msgPacketIndex < msgToResendCurrent.size()) return messagePackets[msgToResendCurrent.get(msgPacketIndex++)];
} else {
if (msgPacketIndex < messagePackets.length) return messagePackets[msgPacketIndex++];
}
- return new FragmentSendCompletePacket(packetID, false);
+ return (makeSureSendDataVerified && (msgToResend.size() < 1 || forceDataVerifiedSendStop)) ? new FragmentSendVerifyCompletePacket(packetID) : new FragmentSendCompletePacket(packetID, false);
}
public boolean shouldBeRemovedReceivePacket(IPacket packetIn) {
@@ -300,15 +350,17 @@ public final class FragmentSender {
if (!verifyResponses || compareData(responsePacket.getFragmentMessage(), messagePackets[responsePacket.getFragmentID()].getFragmentMessage()))
msgToResend.remove(responsePacket.getFragmentID());
}
- if (packetIn instanceof FragmentRetrySendPacket && !((FragmentRetrySendPacket) packetIn).isAcknowledgement()) {
- msgPacketIndex = -1;
- isResending = true;
- msgToResendCurrent.clear();
- msgToResendCurrent.addAll(msgToResend);
- }
+ if (packetIn instanceof FragmentRetrySendPacket && !((FragmentRetrySendPacket) packetIn).isAcknowledgement()) setResendingOn(false);
return false;
}
+ private void setResendingOn(boolean zeroIndex) {
+ msgPacketIndex = (zeroIndex) ? 0 : -1;
+ isResending = true;
+ msgToResendCurrent.clear();
+ msgToResendCurrent.addAll(msgToResend);
+ }
+
private boolean compareData(byte[] data1, byte[] data2) {
if ((data1 == null && data2 != null) || (data1 != null && data2 == null)) return false;
if (data1 == data2) return true;