Facepunch / Facepunch.Steamworks

Another fucking c# Steamworks implementation
MIT License
2.92k stars 349 forks source link

First 8 bytes on receiving SteamNetworkingSockets messages are mangled #534

Open AJNielsen opened 3 years ago

AJNielsen commented 3 years ago

Describe the bug I'm attempting to use the Steam Networking Sockets. When I receive a message from the client, the first 8 bytes are being filled. This is causing the data in the IntPtr to be mangled and not valid. I am trying some different work arounds for now to allow me to continue, but ideally want to avoid this. These 8 bytes stay the same for a minute or more and then change. I'm a bit green on unmanaged code and having a hard time figuring out where it would be coming from. I even tried upgrading to Steamworks SDK 151 (am using 150) and that didn't help.

To Reproduce Steps to reproduce the behavior:

  1. Create a normal or relay socket on server.
  2. Connect to normal/relay socket from client.
  3. Accept connection on server in OnConnecting
  4. On Server, have an async process like Task.Run continuously calling recieve()
  5. On Client, Use connectionManager.Connection.SendMessage(). (Reliable and Unreliable tested - IntPtr and various methods tested.)
  6. On Server, the message should show up in the class implementing ISocketManager.
  7. Observe IntPtr data.

Calling Code - CLIENT

//Connecting to Server Relay
connectionManager = SteamNetworkingSockets.ConnectRelay(server.SteamId, 0, connManInterface);
//Sending a message to the server using the above connection manager.
//NOTE: Packet class prepends 8 bytes to protect against mangled data for testing.
using (var packet = new Packet(1))
{
    packet.Write("This is a string that is way to long to get the thing to do a lot of cool stuff! Yay!");
    byte[] packetData = packet.ToArray();
    IntPtr unmanagedPointer = Marshal.AllocHGlobal(packetData.Length);
    Marshal.Copy(packetData, 0, unmanagedPointer, packetData.Length);
    connectionManager.Connection.SendMessage(unmanagedPointer, packetData.Length, SendType.Unreliable);
    Marshal.FreeHGlobal(unmanagedPointer);
}

Calling Code - SERVER

//Create a relay socket for clients to connect to.
steamSocketManager = SteamNetworkingSockets.CreateRelaySocket(0, new MySocketManager());
public unsafe void OnMessage(Connection connection, NetIdentity identity, IntPtr data, int size, long messageNum, long recvTime, int channel)
{
    var bytes = new byte[size];
    int offset = 0;
    for (int i = 0; i < size; ++i)
    {
        bytes[i] = Marshal.ReadByte(data, offset++);
    }

    using (Packet packet = new Packet(bytes))
    {
        int mangledData = packet.ReadLong();
        int packetNum = packet.ReadInt();
        string strData = packet.ReadString();
    }

    //TODO: Use packet data once mangledData is figured out
}

Expected behavior The same data specified in IntPtr on the client to be retrieved on the server with no additional data.

Desktop (please complete the following information):

Additional context Steamworks Discussion Link where I first posted this issue: https://steamcommunity.com/groups/steamworks/discussions/0/3106891514118368098/

I thought this was my problem when I posted on the steam community due to my lack of unmanaged experience, the deeper I dig, the more I am fairly confident this isn't an issue with my code and something either with Facepunch or Steamworks SDK itself. It could be intended and be a timestamp or some other intended info, but I can't find anything in the documentation about it and maybe I am just missing something explaining how this is to work. I do hope I provided enough information to allow an easy repro of the issue. Let me know if I can provide any additional data.

Milk-Drinker01 commented 3 years ago

i have it setup and working great. if you still need help you can add my discord: milk_drinker01#5765