Hi, it’s me again and I’m having another problem but this time its networking. I implemented networking from a tutorial from a German dude that was making an MMORPG with monogame. I’m using TCP and NetworkStream.
Player:
async Task HandleUserInput(ClientTCP ctcp, Lily[] lilies)
{
if (Keyboard.GetState().IsKeyDown(Keys.Up) || Keyboard.GetState().IsKeyDown(Keys.W))
{
await Task.Run(async () =>
{
positionRectangle.Y -= speed;
await ctcp.SendMove("Y", -speed);
Main.moveCount++;
});
}....
public async Task SendMove(string direction, int signed)
{
Main.logger.Info("SendMove was called");
PacketBuffer buffer = new PacketBuffer();
buffer.AddInteger((int)ClientPackets.CMove);
buffer.AddString(direction);
buffer.AddInteger(signed);
await SendData(buffer.ToArray());
buffer.Dispose();
}
public static async Task SendData(byte[] data, int index)
{
try
{
if (Clients[index].myStream != null)
{
PacketBuffer buffer = new PacketBuffer();
buffer.AddBytes(data);
await Clients[index].myStream.WriteAsync(buffer.ToArray(), 0, buffer.ToArray().Length);
await Clients[index].myStream.FlushAsync();
buffer.Dispose();
Program.moveCount++;
Console.WriteLine(Program.moveCount);
}
}
catch (Exception)
{
throw;
}
}
After the data is sent to the server, the server then transfers to all other connected players.
void HandleMove(int index, byte[] data)
{
//Console.WriteLine($"{index} HandleMove");
PacketBuffer buffer = new PacketBuffer();
buffer.AddBytes(data);
buffer.GetInteger();
//Console.WriteLine($"Player #{index} did:{buffer.GetString()} {buffer.GetInteger()}");
buffer.AddInteger(index);
for (int i = 0; i < ServerTCP.Clients.Length; i++)
{
if (ServerTCP.Clients[i].IP == null || ServerTCP.Clients[i].Index == index)
continue;
_ = ServerTCP.Clients[i].SendMove(buffer, i);
}
buffer.Dispose();
}
Don’t know exactly what I was thinking when writing this method but I’ll just leave it as is for now…(will delete asap)
public async Task SendMove(PacketBuffer buffer, int clientIndex)
{
await ServerTCP.SendData(buffer.ToArray(), clientIndex);
}
public static async Task SendData(byte[] data, int index)
{
try
{
if (Clients[index].myStream != null)
{
PacketBuffer buffer = new PacketBuffer();
buffer.AddBytes(data);
await Clients[index].myStream.WriteAsync(buffer.ToArray(), 0, buffer.ToArray().Length);
await Clients[index].myStream.FlushAsync();
buffer.Dispose();
Program.moveCount++;
Console.WriteLine(Program.moveCount);
}
}
catch (Exception)
{
throw;
}
}
Now the connected clients handle movement data
async void HandleMove(byte[] data)
{
await Task.Run(() =>
{
Main.logger.Info("HandleMove was called");
PacketBuffer buffer = new PacketBuffer();
buffer.AddBytes(data);
buffer.GetInteger();
string direction = buffer.GetString();
int signed = buffer.GetInteger();
int playerId = buffer.GetInteger();
Main.moveCount++;
if (direction == "X")
{
MainGame.players[playerId].cursor.positionRectangle.X += signed;
}
else if (direction == "Y")
{
MainGame.players[playerId].cursor.positionRectangle.Y += signed;
}
buffer.Dispose();
});
}
In the code, I log how many times movement occurred with the Main.moveCount variable.
The problem then arises that if the host made 100 move calls the joined player will only receive a small percentage (15- 30 calls) whilst if the joined player moves, the host will receive most of all calls (99.9%). What gives?
When I playtest, I use my home PC and my laptop, which is tethered to my phone for 4G internet (just to make the networking that more realistic).
Can anyone help me with this dilemma?