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
|
// process incoming in early update
|
||||||
public override void ClientEarlyUpdate()
|
public override void ClientEarlyUpdate()
|
||||||
{
|
{
|
||||||
// scene change messages disable transports to stop them from
|
// only process messages while transport is enabled.
|
||||||
// processing while changing the scene.
|
// scene change messsages disable it to stop processing.
|
||||||
// -> we need to check enabled here
|
|
||||||
// -> and in kcp's internal loops, see Awake() OnCheckEnabled setup!
|
|
||||||
// (see also: https://github.com/vis2k/Mirror/pull/379)
|
// (see also: https://github.com/vis2k/Mirror/pull/379)
|
||||||
if (enabled) client.TickIncoming();
|
if (enabled) client.TickIncoming();
|
||||||
}
|
}
|
||||||
// process outgoing in late update
|
// process outgoing in late update
|
||||||
public override void ClientLateUpdate() => client.TickOutgoing();
|
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
|
// server
|
||||||
public override Uri ServerUri()
|
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 ServerStop() => server.Stop();
|
||||||
public override void ServerEarlyUpdate()
|
public override void ServerEarlyUpdate()
|
||||||
{
|
{
|
||||||
// scene change messages disable transports to stop them from
|
// only process messages while transport is enabled.
|
||||||
// processing while changing the scene.
|
// scene change messsages disable it to stop processing.
|
||||||
// -> we need to check enabled here
|
|
||||||
// -> and in kcp's internal loops, see Awake() OnCheckEnabled setup!
|
|
||||||
// (see also: https://github.com/vis2k/Mirror/pull/379)
|
// (see also: https://github.com/vis2k/Mirror/pull/379)
|
||||||
if (enabled) server.TickIncoming();
|
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]
|
V1.15 [2021-12-11]
|
||||||
- feature: feature: MaxRetransmits aka dead_link now configurable
|
- feature: feature: MaxRetransmits aka dead_link now configurable
|
||||||
- dead_link disconnect message improved to show exact retransmit count
|
- dead_link disconnect message improved to show exact retransmit count
|
||||||
|
@ -111,10 +111,5 @@ public void Tick()
|
|||||||
TickIncoming();
|
TickIncoming();
|
||||||
TickOutgoing();
|
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
|
try
|
||||||
{
|
{
|
||||||
|
// NOTE: dns lookup is blocking. this can take a second.
|
||||||
addresses = Dns.GetHostAddresses(hostname);
|
addresses = Dns.GetHostAddresses(hostname);
|
||||||
return addresses.Length >= 1;
|
return addresses.Length >= 1;
|
||||||
}
|
}
|
||||||
|
@ -20,12 +20,6 @@ public abstract class KcpConnection
|
|||||||
public Action<ArraySegment<byte>, KcpChannel> OnData;
|
public Action<ArraySegment<byte>, KcpChannel> OnData;
|
||||||
public Action OnDisconnected;
|
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
|
// If we don't receive anything these many milliseconds
|
||||||
// then consider us disconnected
|
// then consider us disconnected
|
||||||
public const int DEFAULT_TIMEOUT = 10000;
|
public const int DEFAULT_TIMEOUT = 10000;
|
||||||
@ -315,19 +309,7 @@ void TickIncoming_Authenticated(uint time)
|
|||||||
HandleChoked();
|
HandleChoked();
|
||||||
|
|
||||||
// process all received messages
|
// process all received messages
|
||||||
//
|
while (ReceiveNextReliable(out KcpHeader header, out ArraySegment<byte> message))
|
||||||
// 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))
|
|
||||||
{
|
{
|
||||||
// message type FSM. no default so we never miss a case.
|
// message type FSM. no default so we never miss a case.
|
||||||
switch (header)
|
switch (header)
|
||||||
@ -499,15 +481,8 @@ public void RawInput(byte[] buffer, int msgLength)
|
|||||||
// the current state allows it.
|
// the current state allows it.
|
||||||
if (state == KcpState.Authenticated)
|
if (state == KcpState.Authenticated)
|
||||||
{
|
{
|
||||||
// only process messages while not paused for Mirror
|
ArraySegment<byte> message = new ArraySegment<byte>(buffer, 1, msgLength - 1);
|
||||||
// scene switching etc.
|
OnData?.Invoke(message, KcpChannel.Unreliable);
|
||||||
// -> 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set last receive time to avoid timeout.
|
// set last receive time to avoid timeout.
|
||||||
// -> we do this in ANY case even if not enabled.
|
// -> 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
|
// copy channel header, data into raw send buffer, then send
|
||||||
rawSendBuffer[0] = (byte)KcpChannel.Unreliable;
|
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);
|
RawSend(rawSendBuffer, message.Count + 1);
|
||||||
}
|
}
|
||||||
// otherwise content is larger than MaxMessageSize. let user know!
|
// otherwise content is larger than MaxMessageSize. let user know!
|
||||||
@ -668,24 +643,5 @@ public void Disconnect()
|
|||||||
|
|
||||||
// get remote endpoint
|
// get remote endpoint
|
||||||
public EndPoint GetRemoteEndPoint() => remoteEndPoint;
|
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?.Close();
|
||||||
socket = null;
|
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 INTERVAL = 100;
|
||||||
public const int OVERHEAD = 24;
|
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 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_INIT = 2;
|
||||||
public const int THRESH_MIN = 2;
|
public const int THRESH_MIN = 2;
|
||||||
public const int PROBE_INIT = 7000; // 7 secs to probe window size
|
public const int PROBE_INIT = 7000; // 7 secs to probe window size
|
||||||
@ -65,7 +65,7 @@ internal struct AckItem
|
|||||||
internal bool updated;
|
internal bool updated;
|
||||||
internal uint ts_probe; // timestamp probe
|
internal uint ts_probe; // timestamp probe
|
||||||
internal uint probe_wait;
|
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 incr;
|
||||||
internal uint current; // current time (milliseconds). set by Update.
|
internal uint current; // current time (milliseconds). set by Update.
|
||||||
|
|
||||||
@ -535,7 +535,8 @@ public int Input(byte[] data, int offset, int size)
|
|||||||
size -= OVERHEAD;
|
size -= OVERHEAD;
|
||||||
|
|
||||||
// enough remaining to read 'len' bytes of the actual payload?
|
// 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 &&
|
if (cmd != CMD_PUSH && cmd != CMD_ACK &&
|
||||||
cmd != CMD_WASK && cmd != CMD_WINS)
|
cmd != CMD_WASK && cmd != CMD_WINS)
|
||||||
|
Loading…
Reference in New Issue
Block a user