monopoly/Assets/Mirror/Runtime/LocalConnections.cs
2020-11-30 08:12:07 +00:00

142 lines
4.5 KiB
C#

using System;
using UnityEngine;
namespace Mirror
{
// a server's connection TO a LocalClient.
// sending messages on this connection causes the client's handler function to be invoked directly
class ULocalConnectionToClient : NetworkConnectionToClient
{
internal ULocalConnectionToServer connectionToServer;
public ULocalConnectionToClient() : base(LocalConnectionId) { }
public override string address => "localhost";
internal override void Send(ArraySegment<byte> segment, int channelId = Channels.DefaultReliable)
{
connectionToServer.buffer.Write(segment);
}
// true because local connections never timeout
/// <inheritdoc/>
internal override bool IsAlive(float timeout) => true;
internal void DisconnectInternal()
{
// set not ready and handle clientscene disconnect in any case
// (might be client or host mode here)
isReady = false;
RemoveObservers();
}
/// <summary>
/// Disconnects this connection.
/// </summary>
public override void Disconnect()
{
DisconnectInternal();
connectionToServer.DisconnectInternal();
}
}
internal class LocalConnectionBuffer
{
readonly NetworkWriter writer = new NetworkWriter();
readonly NetworkReader reader = new NetworkReader(default(ArraySegment<byte>));
// The buffer is atleast 1500 bytes long. So need to keep track of
// packet count to know how many ArraySegments are in the buffer
int packetCount;
public void Write(ArraySegment<byte> segment)
{
writer.WriteBytesAndSizeSegment(segment);
packetCount++;
// update buffer incase writer's length has changed
reader.buffer = writer.ToArraySegment();
}
public bool HasPackets()
{
return packetCount > 0;
}
public ArraySegment<byte> GetNextPacket()
{
ArraySegment<byte> packet = reader.ReadBytesAndSizeSegment();
packetCount--;
return packet;
}
public void ResetBuffer()
{
writer.Reset();
reader.Position = 0;
}
}
// a localClient's connection TO a server.
// send messages on this connection causes the server's handler function to be invoked directly.
internal class ULocalConnectionToServer : NetworkConnectionToServer
{
static readonly ILogger logger = LogFactory.GetLogger(typeof(ULocalConnectionToClient));
internal ULocalConnectionToClient connectionToClient;
internal readonly LocalConnectionBuffer buffer = new LocalConnectionBuffer();
public override string address => "localhost";
internal override void Send(ArraySegment<byte> segment, int channelId = Channels.DefaultReliable)
{
if (segment.Count == 0)
{
logger.LogError("LocalConnection.SendBytes cannot send zero bytes");
return;
}
// handle the server's message directly
connectionToClient.TransportReceive(segment, channelId);
}
internal void Update()
{
// process internal messages so they are applied at the correct time
while (buffer.HasPackets())
{
ArraySegment<byte> packet = buffer.GetNextPacket();
// Treat host player messages exactly like connected client
// to avoid deceptive / misleading behavior differences
TransportReceive(packet, Channels.DefaultReliable);
}
buffer.ResetBuffer();
}
/// <summary>
/// Disconnects this connection.
/// </summary>
internal void DisconnectInternal()
{
// set not ready and handle clientscene disconnect in any case
// (might be client or host mode here)
isReady = false;
ClientScene.HandleClientDisconnect(this);
}
/// <summary>
/// Disconnects this connection.
/// </summary>
public override void Disconnect()
{
connectionToClient.DisconnectInternal();
DisconnectInternal();
}
// true because local connections never timeout
/// <inheritdoc/>
internal override bool IsAlive(float timeout) => true;
}
}