mirror of
https://github.com/MirrorNetworking/Mirror.git
synced 2024-11-18 02:50:32 +00:00
breaking: fix: kcp2k V1.16
- fix: SendUnreliable respects ArraySegment.Offset - fix: potential bug with negative length (see PR #2) - breaking: removed pause handling because it's not necessary for Mirror anymore
This commit is contained in:
parent
7e0f649f59
commit
2cacb89fae
@ -162,35 +162,14 @@ public override void ClientSend(ArraySegment<byte> segment, int channelId)
|
||||
// process incoming in early update
|
||||
public override void ClientEarlyUpdate()
|
||||
{
|
||||
// scene change messages disable transports to stop them from
|
||||
// processing while changing the scene.
|
||||
// -> we need to check enabled here
|
||||
// -> and in kcp's internal loops, see Awake() OnCheckEnabled setup!
|
||||
// only process messages while transport is enabled.
|
||||
// scene change messsages disable it to stop processing.
|
||||
// (see also: https://github.com/vis2k/Mirror/pull/379)
|
||||
if (enabled) client.TickIncoming();
|
||||
}
|
||||
// process outgoing in late update
|
||||
public override void ClientLateUpdate() => client.TickOutgoing();
|
||||
|
||||
// scene change message will disable transports.
|
||||
// kcp processes messages in an internal loop which should be
|
||||
// stopped immediately after scene change (= after disabled)
|
||||
// => kcp has tests to guaranteed that calling .Pause() during the
|
||||
// receive loop stops the receive loop immediately, not after.
|
||||
void OnEnable()
|
||||
{
|
||||
// unpause when enabled again
|
||||
client?.Unpause();
|
||||
server?.Unpause();
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
// pause immediately when not enabled anymore
|
||||
client?.Pause();
|
||||
server?.Pause();
|
||||
}
|
||||
|
||||
// server
|
||||
public override Uri ServerUri()
|
||||
{
|
||||
@ -211,10 +190,8 @@ public override void ServerSend(int connectionId, ArraySegment<byte> segment, in
|
||||
public override void ServerStop() => server.Stop();
|
||||
public override void ServerEarlyUpdate()
|
||||
{
|
||||
// scene change messages disable transports to stop them from
|
||||
// processing while changing the scene.
|
||||
// -> we need to check enabled here
|
||||
// -> and in kcp's internal loops, see Awake() OnCheckEnabled setup!
|
||||
// only process messages while transport is enabled.
|
||||
// scene change messsages disable it to stop processing.
|
||||
// (see also: https://github.com/vis2k/Mirror/pull/379)
|
||||
if (enabled) server.TickIncoming();
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
V1.16 [2022-01-06]
|
||||
- fix: SendUnreliable respects ArraySegment.Offset
|
||||
- fix: potential bug with negative length (see PR #2)
|
||||
- breaking: removed pause handling because it's not necessary for Mirror anymore
|
||||
|
||||
V1.15 [2021-12-11]
|
||||
- feature: feature: MaxRetransmits aka dead_link now configurable
|
||||
- dead_link disconnect message improved to show exact retransmit count
|
||||
|
@ -111,10 +111,5 @@ public void Tick()
|
||||
TickIncoming();
|
||||
TickOutgoing();
|
||||
}
|
||||
|
||||
// pause/unpause to safely support mirror scene handling and to
|
||||
// immediately pause the receive while loop if needed.
|
||||
public void Pause() => connection?.Pause();
|
||||
public void Unpause() => connection?.Unpause();
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ public static bool ResolveHostname(string hostname, out IPAddress[] addresses)
|
||||
{
|
||||
try
|
||||
{
|
||||
// NOTE: dns lookup is blocking. this can take a second.
|
||||
addresses = Dns.GetHostAddresses(hostname);
|
||||
return addresses.Length >= 1;
|
||||
}
|
||||
|
@ -20,12 +20,6 @@ public abstract class KcpConnection
|
||||
public Action<ArraySegment<byte>, KcpChannel> OnData;
|
||||
public Action OnDisconnected;
|
||||
|
||||
// Mirror needs a way to stop the kcp message processing while loop
|
||||
// immediately after a scene change message. Mirror can't process any
|
||||
// other messages during a scene change.
|
||||
// (could be useful for others too)
|
||||
bool paused;
|
||||
|
||||
// If we don't receive anything these many milliseconds
|
||||
// then consider us disconnected
|
||||
public const int DEFAULT_TIMEOUT = 10000;
|
||||
@ -315,19 +309,7 @@ void TickIncoming_Authenticated(uint time)
|
||||
HandleChoked();
|
||||
|
||||
// process all received messages
|
||||
//
|
||||
// Mirror scene changing requires transports to immediately stop
|
||||
// processing any more messages after a scene message was
|
||||
// received. and since we are in a while loop here, we need this
|
||||
// extra check.
|
||||
//
|
||||
// note while that this is mainly for Mirror, but might be
|
||||
// useful in other applications too.
|
||||
//
|
||||
// note that we check it BEFORE ever calling ReceiveNext. otherwise
|
||||
// we would silently eat the received message and never process it.
|
||||
while (!paused &&
|
||||
ReceiveNextReliable(out KcpHeader header, out ArraySegment<byte> message))
|
||||
while (ReceiveNextReliable(out KcpHeader header, out ArraySegment<byte> message))
|
||||
{
|
||||
// message type FSM. no default so we never miss a case.
|
||||
switch (header)
|
||||
@ -499,15 +481,8 @@ public void RawInput(byte[] buffer, int msgLength)
|
||||
// the current state allows it.
|
||||
if (state == KcpState.Authenticated)
|
||||
{
|
||||
// only process messages while not paused for Mirror
|
||||
// scene switching etc.
|
||||
// -> if an unreliable message comes in while
|
||||
// paused, simply drop it. it's unreliable!
|
||||
if (!paused)
|
||||
{
|
||||
ArraySegment<byte> message = new ArraySegment<byte>(buffer, 1, msgLength - 1);
|
||||
OnData?.Invoke(message, KcpChannel.Unreliable);
|
||||
}
|
||||
ArraySegment<byte> message = new ArraySegment<byte>(buffer, 1, msgLength - 1);
|
||||
OnData?.Invoke(message, KcpChannel.Unreliable);
|
||||
|
||||
// set last receive time to avoid timeout.
|
||||
// -> we do this in ANY case even if not enabled.
|
||||
@ -578,7 +553,7 @@ void SendUnreliable(ArraySegment<byte> message)
|
||||
{
|
||||
// copy channel header, data into raw send buffer, then send
|
||||
rawSendBuffer[0] = (byte)KcpChannel.Unreliable;
|
||||
Buffer.BlockCopy(message.Array, 0, rawSendBuffer, 1, message.Count);
|
||||
Buffer.BlockCopy(message.Array, message.Offset, rawSendBuffer, 1, message.Count);
|
||||
RawSend(rawSendBuffer, message.Count + 1);
|
||||
}
|
||||
// otherwise content is larger than MaxMessageSize. let user know!
|
||||
@ -668,24 +643,5 @@ public void Disconnect()
|
||||
|
||||
// get remote endpoint
|
||||
public EndPoint GetRemoteEndPoint() => remoteEndPoint;
|
||||
|
||||
// pause/unpause to safely support mirror scene handling and to
|
||||
// immediately pause the receive while loop if needed.
|
||||
public void Pause() => paused = true;
|
||||
public void Unpause()
|
||||
{
|
||||
// unpause
|
||||
paused = false;
|
||||
|
||||
// reset the timeout.
|
||||
// we have likely been paused for > timeout seconds, but that
|
||||
// doesn't mean we should disconnect. for example, Mirror pauses
|
||||
// kcp during scene changes which could easily take > 10s timeout:
|
||||
// see also: https://github.com/vis2k/kcp2k/issues/8
|
||||
// => Unpause completely resets the timeout instead of restoring the
|
||||
// time difference when we started pausing. it's more simple and
|
||||
// it's a good idea to start counting from 0 after we unpaused!
|
||||
lastReceiveTime = (uint)refTime.ElapsedMilliseconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -323,19 +323,5 @@ public void Stop()
|
||||
socket?.Close();
|
||||
socket = null;
|
||||
}
|
||||
|
||||
// pause/unpause to safely support mirror scene handling and to
|
||||
// immediately pause the receive while loop if needed.
|
||||
public void Pause()
|
||||
{
|
||||
foreach (KcpServerConnection connection in connections.Values)
|
||||
connection.Pause();
|
||||
}
|
||||
|
||||
public void Unpause()
|
||||
{
|
||||
foreach (KcpServerConnection connection in connections.Values)
|
||||
connection.Unpause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public class Kcp
|
||||
public const int INTERVAL = 100;
|
||||
public const int OVERHEAD = 24;
|
||||
public const int FRG_MAX = byte.MaxValue; // kcp encodes 'frg' as byte. so we can only ever send up to 255 fragments.
|
||||
public const int DEADLINK = 20; // default maximum amount of 'xmit' retransmissions until a message is considered lost
|
||||
public const int DEADLINK = 20; // default maximum amount of 'xmit' retransmissions until a segment is considered lost
|
||||
public const int THRESH_INIT = 2;
|
||||
public const int THRESH_MIN = 2;
|
||||
public const int PROBE_INIT = 7000; // 7 secs to probe window size
|
||||
@ -65,7 +65,7 @@ internal struct AckItem
|
||||
internal bool updated;
|
||||
internal uint ts_probe; // timestamp probe
|
||||
internal uint probe_wait;
|
||||
internal uint dead_link; // maximum amount of 'xmit' retransmissions until a message is considered lost
|
||||
internal uint dead_link; // maximum amount of 'xmit' retransmissions until a segment is considered lost
|
||||
internal uint incr;
|
||||
internal uint current; // current time (milliseconds). set by Update.
|
||||
|
||||
@ -535,7 +535,8 @@ public int Input(byte[] data, int offset, int size)
|
||||
size -= OVERHEAD;
|
||||
|
||||
// enough remaining to read 'len' bytes of the actual payload?
|
||||
if (size < len || len < 0) return -2;
|
||||
// note: original kcp casts uint len to int for <0 check.
|
||||
if (size < len || (int)len < 0) return -2;
|
||||
|
||||
if (cmd != CMD_PUSH && cmd != CMD_ACK &&
|
||||
cmd != CMD_WASK && cmd != CMD_WINS)
|
||||
|
Loading…
Reference in New Issue
Block a user