Skip to content
This repository has been archived by the owner on Jan 29, 2021. It is now read-only.

Commit

Permalink
Update LiteNetLib
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalPetryka committed Jul 25, 2019
1 parent 1065752 commit ba6bcab
Show file tree
Hide file tree
Showing 22 changed files with 328 additions and 418 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,8 @@ public DateTime RemoteUtcTime
internal double ResendDelay { get { return _resendDelay; } }

/// <summary>
/// Application defined object containing data about the connection
/// </summary>
/// Application defined object containing data about the connection
/// </summary>
public object Tag;

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ internal sealed class NetSocket
private Thread _threadv6;
private volatile bool _running;
private readonly INetSocketListener _listener;
private const int SioUdpConnreset = -1744830452; //SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12
private static readonly IPAddress MulticastAddressV6 = IPAddress.Parse("FF02:0:0:0:0:0:0:1");
internal static readonly bool IPv6Support;

Expand Down Expand Up @@ -161,6 +162,15 @@ private bool BindSocket(Socket socket, IPEndPoint ep, bool reuseAddress)
socket.SendTimeout = 500;
socket.ReceiveBufferSize = NetConstants.SocketBufferSize;
socket.SendBufferSize = NetConstants.SocketBufferSize;
try
{
socket.IOControl(SioUdpConnreset, new byte[] {0}, null);
}
catch
{
//ignored
}

try
{
socket.ExclusiveAddressUse = !reuseAddress;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ public int AvailableBytes
{
get { return _dataSize - _position; }
}

public void SkipBytes(int count)
{
_position += count;
}

public void SetSource(NetDataWriter dataWriter)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ internal void ReadyStatusChanged()
if (item != null)
{
CurrentPlayers++;
if (item.ReadyToBegin)
if (item.readyToBegin)
ReadyPlayers++;
}
}
Expand Down Expand Up @@ -130,7 +130,7 @@ public void CheckReadyToBegin()
{
if (SceneManager.GetActiveScene().name != LobbyScene) return;

if (minPlayers > 0 && NetworkServer.connections.Count(conn => conn.Value != null && conn.Value.playerController.gameObject.GetComponent<NetworkLobbyPlayer>().ReadyToBegin) < minPlayers)
if (minPlayers > 0 && NetworkServer.connections.Count(conn => conn.Value != null && conn.Value.playerController.gameObject.GetComponent<NetworkLobbyPlayer>().readyToBegin) < minPlayers)
{
allPlayersReady = false;
return;
Expand Down Expand Up @@ -197,7 +197,7 @@ public override void OnServerDisconnect(NetworkConnection conn)
foreach (NetworkLobbyPlayer player in lobbySlots)
{
if (player != null)
player.GetComponent<NetworkLobbyPlayer>().ReadyToBegin = false;
player.GetComponent<NetworkLobbyPlayer>().readyToBegin = false;
}

if (SceneManager.GetActiveScene().name == LobbyScene)
Expand Down Expand Up @@ -236,7 +236,7 @@ void RecalculateLobbyPlayerIndices()
{
for (int i = 0; i < lobbySlots.Count; i++)
{
lobbySlots[i].Index = i;
lobbySlots[i].index = i;
}
}
}
Expand All @@ -258,7 +258,7 @@ public override void ServerChangeScene(string sceneName)
if (NetworkServer.active)
{
// re-add the lobby object
lobbyPlayer.GetComponent<NetworkLobbyPlayer>().ReadyToBegin = false;
lobbyPlayer.GetComponent<NetworkLobbyPlayer>().readyToBegin = false;
NetworkServer.ReplacePlayerForConnection(identity.connectionToClient, lobbyPlayer.gameObject);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ namespace Mirror
[HelpURL("https://vis2k.github.io/Mirror/Components/NetworkLobbyPlayer")]
public class NetworkLobbyPlayer : NetworkBehaviour
{
public bool ShowLobbyGUI = true;
public bool showLobbyGUI = true;

[SyncVar(hook=nameof(ReadyStateChanged))]
public bool ReadyToBegin;
public bool readyToBegin;

[SyncVar]
public int Index;
public int index;

#region Unity Callbacks

Expand All @@ -34,9 +34,9 @@ public void Start()
#region Commands

[Command]
public void CmdChangeReadyState(bool ReadyState)
public void CmdChangeReadyState(bool readyState)
{
ReadyToBegin = ReadyState;
readyToBegin = readyState;
NetworkLobbyManager lobby = NetworkManager.singleton as NetworkLobbyManager;
if (lobby != null)
{
Expand All @@ -48,9 +48,9 @@ public void CmdChangeReadyState(bool ReadyState)

#region SyncVar Hooks

void ReadyStateChanged(bool NewReadyState)
void ReadyStateChanged(bool newReadyState)
{
OnClientReady(ReadyToBegin);
OnClientReady(readyToBegin);
}

#endregion
Expand All @@ -69,7 +69,7 @@ public virtual void OnClientReady(bool readyState) {}

public virtual void OnGUI()
{
if (!ShowLobbyGUI)
if (!showLobbyGUI)
return;

NetworkLobbyManager lobby = NetworkManager.singleton as NetworkLobbyManager;
Expand All @@ -81,16 +81,16 @@ public virtual void OnGUI()
if (SceneManager.GetActiveScene().name != lobby.LobbyScene)
return;

GUILayout.BeginArea(new Rect(20f + (Index * 100), 200f, 90f, 130f));
GUILayout.BeginArea(new Rect(20f + (index * 100), 200f, 90f, 130f));

GUILayout.Label($"Player [{Index + 1}]");
GUILayout.Label($"Player [{index + 1}]");

if (ReadyToBegin)
if (readyToBegin)
GUILayout.Label("Ready");
else
GUILayout.Label("Not Ready");

if (((isServer && Index > 0) || isServerOnly) && GUILayout.Button("REMOVE"))
if (((isServer && index > 0) || isServerOnly) && GUILayout.Button("REMOVE"))
{
// This button only shows on the Host for all players other than the Host
// Host and Players can't remove themselves (stop the client instead)
Expand All @@ -104,7 +104,7 @@ public virtual void OnGUI()
{
GUILayout.BeginArea(new Rect(20f, 300f, 120f, 20f));

if (ReadyToBegin)
if (readyToBegin)
{
if (GUILayout.Button("Cancel"))
CmdChangeReadyState(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ public abstract class NetworkTransformBase : NetworkBehaviour
// to save bandwidth in the first place.
// -> can still be modified in the Inspector while the game is running,
// but would cause errors immediately and be pretty obvious.
[Tooltip("Compresses 16 Byte Quaternion into None=12, Much=3, Lots=2 Byte")]
[Tooltip("Compresses 16 Byte Quaternion into None=12, Much=3, Lots=2 Bytes")]
[SerializeField] Compression compressRotation = Compression.Much;
public enum Compression { None, Much, Lots , NoRotation }; // easily understandable and funny
public enum Compression { None, Much, Lots, NoRotation }; // easily understandable and funny

// server
Vector3 lastPosition;
Expand Down Expand Up @@ -69,24 +69,24 @@ static void SerializeIntoWriter(NetworkWriter writer, Vector3 position, Quaterni
// -> quaternion->euler->quaternion always works.
// -> gimbal lock only occurs when adding.
Vector3 euler = rotation.eulerAngles;
if (compressRotation == Compression.None)
{
// write 3 floats = 12 byte
writer.Write(euler.x);
writer.Write(euler.y);
writer.Write(euler.z);
}
else if (compressRotation == Compression.Much)
{
// write 3 byte. scaling [0,360] to [0,255]
writer.Write(FloatBytePacker.ScaleFloatToByte(euler.x, 0, 360, byte.MinValue, byte.MaxValue));
writer.Write(FloatBytePacker.ScaleFloatToByte(euler.y, 0, 360, byte.MinValue, byte.MaxValue));
writer.Write(FloatBytePacker.ScaleFloatToByte(euler.z, 0, 360, byte.MinValue, byte.MaxValue));
}
else if (compressRotation == Compression.Lots)
switch (compressRotation)
{
// write 2 byte, 5 bits for each float
writer.Write(FloatBytePacker.PackThreeFloatsIntoUShort(euler.x, euler.y, euler.z, 0, 360));
case Compression.None:
// write 3 floats = 12 byte
writer.Write(euler.x);
writer.Write(euler.y);
writer.Write(euler.z);
break;
case Compression.Much:
// write 3 byte. scaling [0,360] to [0,255]
writer.Write(FloatBytePacker.ScaleFloatToByte(euler.x, 0, 360, byte.MinValue, byte.MaxValue));
writer.Write(FloatBytePacker.ScaleFloatToByte(euler.y, 0, 360, byte.MinValue, byte.MaxValue));
writer.Write(FloatBytePacker.ScaleFloatToByte(euler.z, 0, 360, byte.MinValue, byte.MaxValue));
break;
case Compression.Lots:
// write 2 byte, 5 bits for each float
writer.Write(FloatBytePacker.PackThreeFloatsIntoUShort(euler.x, euler.y, euler.z, 0, 360));
break;
}
}

Expand All @@ -102,22 +102,21 @@ public override bool OnSerialize(NetworkWriter writer, bool initialState)
// => if this is the first time ever then we use our best guess:
// -> delta based on transform.localPosition
// -> elapsed based on send interval hoping that it roughly matches
static float EstimateMovementSpeed(DataPoint from, DataPoint to, Transform transform, float sendInterval)
static float EstimateMovementSpeed(DataPoint from, Vector3 toPosition, float toTimestap, Transform transform, float sendInterval)
{
Vector3 delta = to.localPosition - (from != null ? from.localPosition : transform.localPosition);
float elapsed = from != null ? to.timeStamp - from.timeStamp : sendInterval;
Vector3 delta = toPosition - (from != null ? from.localPosition : transform.localPosition);
float elapsed = from != null ? toTimestap - from.timeStamp : sendInterval;
return elapsed > 0 ? delta.magnitude / elapsed : 0; // avoid NaN
}

private DataPoint temp = new DataPoint();

// serialization is needed by OnSerialize and by manual sending from authority
void DeserializeFromReader(NetworkReader reader)
{
// put it into a data point immediately
// deserialize position
temp.localPosition = reader.ReadVector3();
Vector3 localPosition = reader.ReadVector3();

Quaternion localRotation = default;
switch (compressRotation)
{
// deserialize rotation
Expand All @@ -127,7 +126,7 @@ void DeserializeFromReader(NetworkReader reader)
float x = reader.ReadSingle();
float y = reader.ReadSingle();
float z = reader.ReadSingle();
temp.localRotation = Quaternion.Euler(x, y, z);
localRotation = Quaternion.Euler(x, y, z);
break;
}

Expand All @@ -137,36 +136,41 @@ void DeserializeFromReader(NetworkReader reader)
float x = FloatBytePacker.ScaleByteToFloat(reader.ReadByte(), byte.MinValue, byte.MaxValue, 0, 360);
float y = FloatBytePacker.ScaleByteToFloat(reader.ReadByte(), byte.MinValue, byte.MaxValue, 0, 360);
float z = FloatBytePacker.ScaleByteToFloat(reader.ReadByte(), byte.MinValue, byte.MaxValue, 0, 360);
temp.localRotation = Quaternion.Euler(x, y, z);
localRotation = Quaternion.Euler(x, y, z);
break;
}

case Compression.Lots:
{
// read 2 byte, 5 bits per float
float[] xyz = FloatBytePacker.UnpackUShortIntoThreeFloats(reader.ReadUInt16(), 0, 360);
temp.localRotation = Quaternion.Euler(xyz[0], xyz[1], xyz[2]);
ushort combined = reader.ReadUInt16();
// note: we have to use 4 bits per float, so between 0x00 and 0x0F
float x = FloatBytePacker.ScaleByteToFloat((byte)(combined & 0x1F), 0x00, 0x1F, 0, 360);
float y = FloatBytePacker.ScaleByteToFloat((byte)((combined >> 5) & 0x1F), 0x00, 0x1F, 0, 360);
float z = FloatBytePacker.ScaleByteToFloat((byte)(combined >> 10), 0x00, 0x1F, 0, 360);
localRotation = Quaternion.Euler(x, y, z);
break;
}
}

temp.timeStamp = Time.time;
float timeStamp = Time.time;

// movement speed: based on how far it moved since last time
// has to be calculated before 'start' is overwritten
temp.movementSpeed = EstimateMovementSpeed(goal, temp, targetComponent.transform, syncInterval);
float movementSpeed = EstimateMovementSpeed(goal, localPosition, timeStamp, targetComponent.transform, syncInterval);

// reassign start wisely
// -> first ever data point? then make something up for previous one
// so that we can start interpolation without waiting for next.
if (start == null)
{
start = new DataPoint{
start = new DataPoint
{
timeStamp = Time.time - syncInterval,
// local position/rotation for VR support
localPosition = targetComponent.transform.localPosition,
localRotation = targetComponent.transform.localRotation,
movementSpeed = temp.movementSpeed
movementSpeed = movementSpeed
};
}
// -> second or nth data point? then update previous, but:
Expand Down Expand Up @@ -201,23 +205,35 @@ void DeserializeFromReader(NetworkReader reader)
else
{
float oldDistance = Vector3.Distance(start.localPosition, goal.localPosition);
float newDistance = Vector3.Distance(goal.localPosition, temp.localPosition);
float newDistance = Vector3.Distance(goal.localPosition, localPosition);

start = goal;
start.localPosition = goal.localPosition;
start.localRotation = goal.localRotation;
start.movementSpeed = goal.movementSpeed;
start.timeStamp = goal.timeStamp;

// teleport / lag / obstacle detection: only continue at current
// position if we aren't too far away
//
// // local position/rotation for VR support
if (Vector3.Distance(targetComponent.transform.localPosition, start.localPosition) < oldDistance + newDistance)
Transform pos = targetComponent.transform;
if (Vector3.Distance(pos.localPosition, start.localPosition) < oldDistance + newDistance)
{
start.localPosition = targetComponent.transform.localPosition;
start.localRotation = targetComponent.transform.localRotation;
start.localPosition = pos.localPosition;
start.localRotation = pos.localRotation;
}
}

// set new destination in any case. new data is best data.
goal = temp;
if (goal == null)
{
goal = new DataPoint();
}

goal.localPosition = localPosition;
goal.localRotation = localRotation;
goal.movementSpeed = movementSpeed;
goal.timeStamp = timeStamp;
}

public override void OnDeserialize(NetworkReader reader, bool initialState)
Expand Down
Loading

0 comments on commit ba6bcab

Please sign in to comment.