Mydayyy / Valheim-ServerSideMap

This plugin completely moves the explored map and created pins to the server. As clients explore, they will send their explored areas to the server who will then distribute it to all connected clients. When a client joins, the server will synchronize the currently explored areas to the client. Pins are shared as well but default to false and need to be enabled. When pin sharing is used, all newly created pins are send to the server who saves them along with the explored area.
38 stars 1 forks source link

Valheim Update: Mod crashes due to newly introduced network requirements #12

Closed Mydayyy closed 3 years ago

Mydayyy commented 3 years ago

The latest Valheim update fixed a new things, one of which is switching to another method of sending data via steam.

Prior to the update:

private void SendQueuedPackages()
{
if (!this.IsConnected())
return;
while (this.m_sendQueue.Count > 0)
{
byte[] numArray = this.m_sendQueue.Peek();
EP2PSend ep2Psend = (EP2PSend) 2;
if (!SteamNetworking.SendP2PPacket(this.m_peerID, numArray, (uint) numArray.Length, ep2Psend, 0))
break;
this.m_totalSent += numArray.Length;
this.m_sendQueue.Dequeue();
}
}

After the update:

private void SendQueuedPackages()
{
if (!this.IsConnected())
return;
while (this.m_sendQueue.Count > 0)
{
byte[] source = this.m_sendQueue.Peek();
IntPtr num1 = Marshal.AllocHGlobal(source.Length);
Marshal.Copy(source, 0, num1, source.Length);
long num2;
EResult connection = SteamNetworkingSockets.SendMessageToConnection(this.m_con, num1, (uint) source.Length, 9, ref num2);
Marshal.FreeHGlobal(num1);
if (connection == 1)
{
this.m_totalSent += source.Length;
this.m_sendQueue.Dequeue();
}
else
{
ZLog.Log((object) ("Failed to send data " + (object) connection));
break;
}
}
}

The main change is switching from SendP2PPacket to SendMessageToConnection. SendMessageToConnection has a limit on package size which we slighty exceed:

Reliable message send. Can send up to k_cbMaxSteamNetworkingSocketsMessageSizeSend bytes in a single message. Does fragmentation/re-assembly of messages under the hood, as well as a sliding window for efficient sends of large chunks of data.

Where k_cbMaxSteamNetworkingSocketsMessageSizeSend is defined as: const int k_cbMaxSteamNetworkingSocketsMessageSizeSend = 512 * 1024;

The fix for this is to implement chunking for sending the map data