Unity-Technologies / multiplayer-community-contributions

Community contributions to Unity Multiplayer Networking products and services.
MIT License
448 stars 164 forks source link

Number of errors when implementing new transport #77

Open fghl opened 3 years ago

fghl commented 3 years ago

Hi there, I'm getting a number of MLAPI errors while building a SteamNetworkingSockets transport and I'd love some help.

The transport appears to be partially working. The host sometimes doesn't display one or the other player, and sometimes players lag badly. Seems to be luck of the draw.

I have a feeling I'm doing something like leaving old data in the send and receive buffers between events but I don't know enough about buffers in c# to intuit the answer.

Buffers are created like so, taken verbatim from https://github.com/rlabrecque/Steamworks.NET/issues/411#issuecomment-826115503:

     IntPtr sendBuffer = Marshal.AllocHGlobal(65536);
     IntPtr[] receiveBuffers = new IntPtr[1]; // given PollEvent returns a single NetworkEvent, it seems we can only handle one message at a time.

The relevant Send code:

    public override void Send(ulong clientId, ArraySegment<byte> data, NetworkChannel channel)
    {
      int nSendFlags = ChannelSendFlags[channel];
      HSteamNetConnection sendToHConn = isServer ? steamIdToHConn[clientId] : serverHConn;

      Debug.Log($"Send(clientId {clientId}, data {data}, channel {channel});");

      try
      {
        Marshal.Copy(data.Array, 0, sendBuffer, data.Array.Length);
        SteamNetworkingSockets.SendMessageToConnection(sendToHConn, sendBuffer, (uint)data.Array.Length, nSendFlags, out _);
      }
      catch
      {
        Marshal.FreeHGlobal(sendBuffer);
      }
    }

The relevant PollEvent code:

      // if there are no messages, return
      if (messageCount > 0)
      {
        Debug.Log($"PollEvent(); // messageCount is {messageCount}");
        try
        {
          SteamNetworkingMessage_t netMessage = Marshal.PtrToStructure<SteamNetworkingMessage_t>(receiveBuffers[0]);
          byte[] message = new byte[netMessage.m_cbSize];
          Marshal.Copy(netMessage.m_pData, message, 0, message.Length);

          payload = new ArraySegment<byte>(message);
          clientId = netMessage.m_identityPeer.GetSteamID64();

          Debug.Log($"PollEvent(); // message received at {receiveTime} from {clientId}");

          SteamAPI_SteamNetworkingMessage_t_Release(receiveBuffers[0]);
        }
        finally
        {
          Marshal.DestroyStructure<SteamNetworkingMessage_t>(receiveBuffers[0]);
        }
        return NetworkEvent.Data;
      }

Any guidance on how to fix this would be appreciated.

These errors are occasionally appearing in both consoles:

OSXPlayer(Alices-MacBook-Air.local) RpcQueueContainer 65 update type does not exist!
UnityEngine.StackTraceUtility:ExtractStackTrace () (at /Users/bokken/buildslave/unity/build/Runtime/Export/Scripting/StackTrace.cs:37)
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object)
UnityEngine.Debug:LogError (object)
MLAPI.Messaging.RpcQueueContainer:GetQueueHistoryFrame (MLAPI.Messaging.RpcQueueHistoryFrame/QueueFrameType,MLAPI.NetworkUpdateStage,bool) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs:567)
MLAPI.Messaging.RpcQueueContainer:AddQueueItemToInboundFrame (MLAPI.Messaging.RpcQueueContainer/QueueItemType,single,ulong,MLAPI.Serialization.NetworkBuffer) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs:284)
MLAPI.Messaging.InternalMessageHandler:RpcReceiveQueueItem (ulong,System.IO.Stream,single,MLAPI.Messaging.RpcQueueContainer/QueueItemType) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/InternalMessageHandler.cs:568)
MLAPI.NetworkManager:ReceiveCallback (MLAPI.Serialization.NetworkBuffer,MLAPI.Messaging.RpcQueueContainer/QueueItemType,ulong,single) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:1094)
MLAPI.Messaging.RpcBatcher:ReceiveItems (MLAPI.Serialization.NetworkBuffer&,MLAPI.Messaging.RpcBatcher/ReceiveCallbackType,MLAPI.Messaging.RpcQueueContainer/QueueItemType,ulong,single) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcBatcher.cs:216)
MLAPI.NetworkManager:HandleIncomingData (ulong,MLAPI.Transports.NetworkChannel,System.ArraySegment`1<byte>,single,bool) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:1060)
MLAPI.NetworkManager:HandleRawTransportPoll (MLAPI.Transports.NetworkEvent,ulong,MLAPI.Transports.NetworkChannel,System.ArraySegment`1<byte>,single) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:875)
MLAPI.NetworkManager:OnNetworkEarlyUpdate () (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:683)
MLAPI.NetworkManager:NetworkUpdate (MLAPI.NetworkUpdateStage) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:641)
MLAPI.NetworkUpdateLoop:RunNetworkUpdateStage (MLAPI.NetworkUpdateStage) (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkUpdateLoop.cs:148)
MLAPI.NetworkUpdateLoop/NetworkEarlyUpdate/<>c:<CreateLoopSystem>b__0_0 () (at /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkUpdateLoop.cs:171)

(Filename: /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs Line: 567)

The number 65 is different every time. Always a uint8, so seems to be a byte out of place.

This one is caused by the last one:

OSXPlayer(Alices-MacBook-Air.local) NullReferenceException: Object reference not set to an instance of an object
  at MLAPI.Messaging.RpcQueueContainer.AddQueueItemToInboundFrame (MLAPI.Messaging.RpcQueueContainer+QueueItemType qItemType, System.Single timeStamp, System.UInt64 sourceNetworkId, MLAPI.Serialization.NetworkBuffer message) [0x00050] in /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcQueue/RpcQueueContainer.cs:285 
  at MLAPI.Messaging.InternalMessageHandler.RpcReceiveQueueItem (System.UInt64 clientId, System.IO.Stream stream, System.Single receiveTime, MLAPI.Messaging.RpcQueueContainer+QueueItemType queueItemType) [0x00073] in /Users/wgodfrey/code/unity/learning/MLAPI 03/Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/InternalMessageHandler.cs:568 

And finally

ArgumentException: Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.
System.Buffer.BlockCopy (System.Array src, System.Int32 srcOffset, System.Array dst, System.Int32 dstOffset, System.Int32 count) (at <695d1cc93cca45069c528c15c9fdd749>:0)
MLAPI.Messaging.RpcBatcher.ReceiveItems (MLAPI.Serialization.NetworkBuffer& messageBuffer, MLAPI.Messaging.RpcBatcher+ReceiveCallbackType receiveCallback, MLAPI.Messaging.RpcQueueContainer+QueueItemType messageType, System.UInt64 clientId, System.Single receiveTime) (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Messaging/RpcBatcher.cs:214)
MLAPI.NetworkManager.HandleIncomingData (System.UInt64 clientId, MLAPI.Transports.NetworkChannel networkChannel, System.ArraySegment`1[T] data, System.Single receiveTime, System.Boolean allowBuffer) (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:1042)
MLAPI.NetworkManager.HandleRawTransportPoll (MLAPI.Transports.NetworkEvent networkEvent, System.UInt64 clientId, MLAPI.Transports.NetworkChannel networkChannel, System.ArraySegment`1[T] payload, System.Single receiveTime) (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:875)
MLAPI.NetworkManager.OnNetworkEarlyUpdate () (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:683)
MLAPI.NetworkManager.NetworkUpdate (MLAPI.NetworkUpdateStage updateStage) (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkManager.cs:641)
MLAPI.NetworkUpdateLoop.RunNetworkUpdateStage (MLAPI.NetworkUpdateStage updateStage) (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkUpdateLoop.cs:148)
MLAPI.NetworkUpdateLoop+NetworkEarlyUpdate+<>c.<CreateLoopSystem>b__0_0 () (at Library/PackageCache/com.unity.multiplayer.mlapi@3e3aef6aa0/Runtime/Core/NetworkUpdateLoop.cs:171)
LukeStampfli commented 2 years ago

Sorry we currently don't have the bandwidth to help with custom transport implementation. I'd suggest asking on Forums or Discord if there are other community members who are interested in helping out.