This commit is contained in:
Albin Corén 2018-03-09 15:36:10 +01:00
commit 06774ea531
7 changed files with 92 additions and 70 deletions

View File

@ -15,7 +15,10 @@ namespace MLAPI
internal HashSet<ushort> RegisteredPassthroughMessageTypes = new HashSet<ushort>(); internal HashSet<ushort> RegisteredPassthroughMessageTypes = new HashSet<ushort>();
public List<string> RegisteredScenes = new List<string>(); public List<string> RegisteredScenes = new List<string>();
public int MessageBufferSize = 65535; public int MessageBufferSize = 65535;
public int Tickrate = 64; public int ReceiveTickrate = 64;
public int MaxReceiveEventsPerTickRate = 500;
public int SendTickrate = 64;
public int EventTickrate = 64;
public int MaxConnections = 100; public int MaxConnections = 100;
public int Port = 7777; public int Port = 7777;
public string Address = "127.0.0.1"; public string Address = "127.0.0.1";

View File

@ -333,7 +333,7 @@ namespace MLAPI
} }
} }
} }
NetworkingManager.singleton.Send(clientId, "MLAPI_SYNC_VAR_UPDATE", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.ToArray()); NetworkingManager.singleton.Send(clientId, "MLAPI_SYNC_VAR_UPDATE", "MLAPI_INTERNAL", stream.ToArray());
} }
} }
@ -426,7 +426,7 @@ namespace MLAPI
} }
} }
} }
NetworkingManager.singleton.Send("MLAPI_SYNC_VAR_UPDATE", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.ToArray()); NetworkingManager.singleton.Send("MLAPI_SYNC_VAR_UPDATE", "MLAPI_INTERNAL", stream.ToArray());
} }
lastSyncTime = Time.time; lastSyncTime = Time.time;
} }

View File

@ -73,7 +73,9 @@ namespace MLAPI
private ConnectionConfig Init(NetworkingConfiguration netConfig) private ConnectionConfig Init(NetworkingConfiguration netConfig)
{ {
NetworkConfig = netConfig; NetworkConfig = netConfig;
lastSendTickTime = 0;
lastEventTickTime = 0;
lastReceiveTickTime = 0;
pendingClients = new HashSet<int>(); pendingClients = new HashSet<int>();
connectedClients = new Dictionary<int, NetworkedClient>(); connectedClients = new Dictionary<int, NetworkedClient>();
messageBuffer = new byte[NetworkConfig.MessageBufferSize]; messageBuffer = new byte[NetworkConfig.MessageBufferSize];
@ -109,7 +111,7 @@ namespace MLAPI
}; };
//MLAPI channels and messageTypes //MLAPI channels and messageTypes
NetworkConfig.Channels.Add("MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", QosType.ReliableFragmentedSequenced); NetworkConfig.Channels.Add("MLAPI_INTERNAL", QosType.ReliableFragmentedSequenced);
NetworkConfig.Channels.Add("MLAPI_POSITION_UPDATE", QosType.StateUpdate); NetworkConfig.Channels.Add("MLAPI_POSITION_UPDATE", QosType.StateUpdate);
NetworkConfig.Channels.Add("MLAPI_ANIMATION_UPDATE", QosType.ReliableSequenced); NetworkConfig.Channels.Add("MLAPI_ANIMATION_UPDATE", QosType.ReliableSequenced);
MessageManager.messageTypes.Add("MLAPI_CONNECTION_REQUEST", 0); MessageManager.messageTypes.Add("MLAPI_CONNECTION_REQUEST", 0);
@ -295,75 +297,92 @@ namespace MLAPI
private int channelId; private int channelId;
private int receivedSize; private int receivedSize;
private byte error; private byte error;
private float lastTickTime; private float lastReceiveTickTime;
private float lastSendTickTime;
private float lastEventTickTime;
private void Update() private void Update()
{ {
if(isListening && (Time.time - lastTickTime >= (1f / NetworkConfig.Tickrate))) if(isListening)
{ {
foreach (KeyValuePair<int, NetworkedClient> pair in connectedClients) if((Time.time - lastSendTickTime >= (1f / NetworkConfig.SendTickrate)) || NetworkConfig.SendTickrate <= 0)
{ {
NetworkTransport.SendQueuedMessages(hostId, pair.Key, out error); foreach (KeyValuePair<int, NetworkedClient> pair in connectedClients)
}
NetworkEventType eventType = NetworkTransport.Receive(out hostId, out clientId, out channelId, messageBuffer, messageBuffer.Length, out receivedSize, out error);
NetworkError networkError = (NetworkError)error;
if (networkError == NetworkError.Timeout)
{
//Client timed out.
if (isServer)
{ {
OnClientDisconnect(clientId); NetworkTransport.SendQueuedMessages(hostId, pair.Key, out error);
return;
} }
lastSendTickTime = Time.time;
} }
else if (networkError != NetworkError.Ok) if((Time.time - lastReceiveTickTime >= (1f / NetworkConfig.ReceiveTickrate)) || NetworkConfig.ReceiveTickrate <= 0)
{ {
Debug.LogWarning("MLAPI: NetworkTransport receive error: " + networkError.ToString()); NetworkEventType eventType;
return; int processedEvents = 0;
} do
{
switch (eventType) processedEvents++;
{ eventType = NetworkTransport.Receive(out hostId, out clientId, out channelId, messageBuffer, messageBuffer.Length, out receivedSize, out error);
case NetworkEventType.ConnectEvent: NetworkError networkError = (NetworkError)error;
if (isServer) if (networkError == NetworkError.Timeout)
{ {
pendingClients.Add(clientId); //Client timed out.
StartCoroutine(ApprovalTimeout(clientId)); if (isServer)
}
else
{
int sizeOfStream = 32;
if (NetworkConfig.ConnectionApproval)
sizeOfStream += 2 + NetworkConfig.ConnectionData.Length;
using (MemoryStream writeStream = new MemoryStream(sizeOfStream))
{ {
using (BinaryWriter writer = new BinaryWriter(writeStream)) OnClientDisconnect(clientId);
{ return;
writer.Write(NetworkConfig.GetConfig());
if (NetworkConfig.ConnectionApproval)
{
writer.Write((ushort)NetworkConfig.ConnectionData.Length);
writer.Write(NetworkConfig.ConnectionData);
}
}
Send(clientId, "MLAPI_CONNECTION_REQUEST", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", writeStream.GetBuffer());
} }
} }
break; else if (networkError != NetworkError.Ok)
case NetworkEventType.DataEvent: {
HandleIncomingData(clientId, messageBuffer, channelId); Debug.LogWarning("MLAPI: NetworkTransport receive error: " + networkError.ToString());
break; return;
case NetworkEventType.DisconnectEvent: }
if (isServer)
OnClientDisconnect(clientId); switch (eventType)
break; {
case NetworkEventType.ConnectEvent:
if (isServer)
{
pendingClients.Add(clientId);
StartCoroutine(ApprovalTimeout(clientId));
}
else
{
int sizeOfStream = 32;
if (NetworkConfig.ConnectionApproval)
sizeOfStream += 2 + NetworkConfig.ConnectionData.Length;
using (MemoryStream writeStream = new MemoryStream(sizeOfStream))
{
using (BinaryWriter writer = new BinaryWriter(writeStream))
{
writer.Write(NetworkConfig.GetConfig());
if (NetworkConfig.ConnectionApproval)
{
writer.Write((ushort)NetworkConfig.ConnectionData.Length);
writer.Write(NetworkConfig.ConnectionData);
}
}
Send(clientId, "MLAPI_CONNECTION_REQUEST", "MLAPI_INTERNAL", writeStream.GetBuffer());
}
}
break;
case NetworkEventType.DataEvent:
HandleIncomingData(clientId, messageBuffer, channelId);
break;
case NetworkEventType.DisconnectEvent:
if (isServer)
OnClientDisconnect(clientId);
break;
}
// Only do another iteration if: there are no more messages AND (there is no limit to max events or we have processed less than the maximum)
} while (eventType != NetworkEventType.Nothing && (NetworkConfig.MaxReceiveEventsPerTickRate <= 0 || processedEvents < NetworkConfig.MaxReceiveEventsPerTickRate));
lastReceiveTickTime = Time.time;
} }
if (isServer) if (isServer && ((Time.time - lastEventTickTime >= (1f / NetworkConfig.EventTickrate)) || NetworkConfig.EventTickrate <= 0))
{ {
LagCompensationManager.AddFrames(); LagCompensationManager.AddFrames();
NetworkedObject.InvokeSyncvarUpdate(); NetworkedObject.InvokeSyncvarUpdate();
lastEventTickTime = Time.time;
} }
lastTickTime = Time.time;
} }
} }
@ -1074,7 +1093,7 @@ namespace MLAPI
{ {
writer.Write(clientId); writer.Write(clientId);
} }
Send("MLAPI_CLIENT_DISCONNECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer(), clientId); Send("MLAPI_CLIENT_DISCONNECT", "MLAPI_INTERNAL", stream.GetBuffer(), clientId);
} }
} }
} }
@ -1153,7 +1172,7 @@ namespace MLAPI
} }
} }
} }
Send(clientId, "MLAPI_CONNECTION_APPROVED", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", writeStream.GetBuffer()); Send(clientId, "MLAPI_CONNECTION_APPROVED", "MLAPI_INTERNAL", writeStream.GetBuffer());
} }
//Inform old clients of the new player //Inform old clients of the new player
@ -1179,7 +1198,7 @@ namespace MLAPI
writer.Write(clientId); writer.Write(clientId);
} }
} }
Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer(), clientId); Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer(), clientId);
} }
//Flush syncvars: //Flush syncvars:
foreach (KeyValuePair<uint, NetworkedObject> networkedObject in SpawnManager.spawnedObjects) foreach (KeyValuePair<uint, NetworkedObject> networkedObject in SpawnManager.spawnedObjects)

View File

@ -58,7 +58,7 @@ namespace MLAPI.NetworkingManagerComponents
writer.Write(rotation.eulerAngles.y); writer.Write(rotation.eulerAngles.y);
writer.Write(rotation.eulerAngles.z); writer.Write(rotation.eulerAngles.z);
} }
NetworkingManager.singleton.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); NetworkingManager.singleton.Send("MLAPI_SPAWN_POOL_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer());
} }
return go; return go;
} }
@ -77,7 +77,7 @@ namespace MLAPI.NetworkingManagerComponents
{ {
writer.Write(netObject.NetworkId); writer.Write(netObject.NetworkId);
} }
NetworkingManager.singleton.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); NetworkingManager.singleton.Send("MLAPI_DESTROY_POOL_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer());
} }
} }
} }

View File

@ -55,7 +55,7 @@ namespace MLAPI.NetworkingManagerComponents
{ {
writer.Write(sceneNameToIndex[sceneName]); writer.Write(sceneNameToIndex[sceneName]);
} }
NetworkingManager.singleton.Send("MLAPI_SWITCH_SCENE", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); NetworkingManager.singleton.Send("MLAPI_SWITCH_SCENE", "MLAPI_INTERNAL", stream.GetBuffer());
} }
} }

View File

@ -42,7 +42,7 @@ namespace MLAPI.NetworkingManagerComponents
writer.Write(netId); writer.Write(netId);
writer.Write(-2); writer.Write(-2);
} }
netManager.Send("MLAPI_CHANGE_OWNER", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); netManager.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", stream.GetBuffer());
} }
} }
@ -59,7 +59,7 @@ namespace MLAPI.NetworkingManagerComponents
writer.Write(netId); writer.Write(netId);
writer.Write(clientId); writer.Write(clientId);
} }
netManager.Send("MLAPI_CHANGE_OWNER", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); netManager.Send("MLAPI_CHANGE_OWNER", "MLAPI_INTERNAL", stream.GetBuffer());
} }
} }
@ -136,9 +136,9 @@ namespace MLAPI.NetworkingManagerComponents
} }
//If we are host, send to everyone except ourselves. Otherwise, send to all //If we are host, send to everyone except ourselves. Otherwise, send to all
if (netManager != null && netManager.isHost) if (netManager != null && netManager.isHost)
netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer(), -1); netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer(), -1);
else else
netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); netManager.Send("MLAPI_DESTROY_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer());
} }
} }
} }
@ -193,9 +193,9 @@ namespace MLAPI.NetworkingManagerComponents
} }
//If we are host, send to everyone except ourselves. Otherwise, send to all //If we are host, send to everyone except ourselves. Otherwise, send to all
if (netManager.isHost) if (netManager.isHost)
netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer(), -1); netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer(), -1);
else else
netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_RELIABLE_FRAGMENTED_SEQUENCED", stream.GetBuffer()); netManager.Send("MLAPI_ADD_OBJECT", "MLAPI_INTERNAL", stream.GetBuffer());
} }
} }
} }

View File

@ -13,7 +13,7 @@ MLAPI (Mid level API) is a framework that hopefully simplifies building networke
* Replace the integer QOS with names. When you setup the networking you specify names that are associated with a channel. This makes it easier to manage. You can thus specify that a message should be sent on the "damage" channel which handles all damage related logic and is running on the AllCostDelivery channel. * Replace the integer QOS with names. When you setup the networking you specify names that are associated with a channel. This makes it easier to manage. You can thus specify that a message should be sent on the "damage" channel which handles all damage related logic and is running on the AllCostDelivery channel.
* ProtocolVersion to allow making different versions not talk to each other. * ProtocolVersion to allow making different versions not talk to each other.
* NetworkedBehaviours does not have to be on the root, it's simply just a class that implements the send methods etc. * NetworkedBehaviours does not have to be on the root, it's simply just a class that implements the send methods etc.
* Multiple messages processed every frame with the ability to specify a maximum to prevent freezes in the normal game logic * Custom tickrate
* Supports separate Unity projects crosstalking * Supports separate Unity projects crosstalking
* Passthrough messages \[[Wiki page](https://github.com/TwoTenPvP/MLAPI/wiki/Passthrough-messages)\] * Passthrough messages \[[Wiki page](https://github.com/TwoTenPvP/MLAPI/wiki/Passthrough-messages)\]
* Scene Management \[[Wiki page](https://github.com/TwoTenPvP/MLAPI/wiki/Scene-Management)\] * Scene Management \[[Wiki page](https://github.com/TwoTenPvP/MLAPI/wiki/Scene-Management)\]