forked from SoDOff-Project/sodoff-mmo
packet buffering and fixes
This commit is contained in:
parent
3b93594c8b
commit
d162ce80aa
@ -9,6 +9,12 @@ class SetPositionVariablesHandler : ICommandHandler {
|
||||
Client client;
|
||||
NetworkObject spvData;
|
||||
public void Handle(Client client, NetworkObject receivedObject) {
|
||||
if (client.Room == null) {
|
||||
Console.WriteLine($"SPV Missing Room IID: {client.ClientID}");
|
||||
client.Send(NetworkObject.WrapObject(0, 1006, new NetworkObject()).Serialize());
|
||||
client.SheduleDisconnect();
|
||||
return;
|
||||
}
|
||||
this.client = client;
|
||||
spvData = receivedObject;
|
||||
UpdatePositionVariables();
|
||||
@ -52,11 +58,9 @@ class SetPositionVariablesHandler : ICommandHandler {
|
||||
|
||||
|
||||
NetworkPacket packet = NetworkObject.WrapObject(1, 13, cmd).Serialize();
|
||||
lock (client.Room.roomLock) {
|
||||
foreach (var roomClient in client.Room.Clients) {
|
||||
if (roomClient != client)
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
foreach (var roomClient in client.Room.Clients) {
|
||||
if (roomClient != client)
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -81,10 +81,8 @@ class SetUserVariablesHandler : ICommandHandler {
|
||||
data.Add("vl", vl);
|
||||
|
||||
NetworkPacket packet = NetworkObject.WrapObject(0, 12, data).Serialize();
|
||||
lock (client.Room.roomLock) {
|
||||
foreach (var roomClient in client.Room.Clients)
|
||||
roomClient.Send(packet);
|
||||
}
|
||||
foreach (var roomClient in client.Room.Clients)
|
||||
roomClient.Send(packet);
|
||||
|
||||
NetworkObject cmd = new();
|
||||
cmd.Add("c", "SUV");
|
||||
|
@ -10,12 +10,10 @@ public class Client {
|
||||
public int ClientID { get; private set; }
|
||||
public PlayerData PlayerData { get; set; } = new();
|
||||
public Room Room { get; set; }
|
||||
public object ClientLock = new();
|
||||
|
||||
private readonly Socket socket;
|
||||
private NetworkData? lastData;
|
||||
private NetworkPacket? incompleteData;
|
||||
private bool hasIncompletePakcet = false;
|
||||
SocketBuffer socketBuffer = new();
|
||||
private volatile bool scheduledDisconnect = false;
|
||||
|
||||
public Client(Socket clientSocket) {
|
||||
socket = clientSocket;
|
||||
@ -29,21 +27,11 @@ public class Client {
|
||||
int len = await socket.ReceiveAsync(buffer, SocketFlags.None);
|
||||
if (len == 0)
|
||||
throw new SocketException();
|
||||
lastData = new NetworkData(buffer);
|
||||
socketBuffer.Write(buffer, len);
|
||||
}
|
||||
|
||||
public bool TryGetNextPacket(out NetworkPacket packet) {
|
||||
packet = new();
|
||||
if (hasIncompletePakcet) {
|
||||
// TODO
|
||||
}
|
||||
byte header = lastData!.ReadByte();
|
||||
if (header != 0x80 && header != 0xa0)
|
||||
return false;
|
||||
short length = lastData.ReadShort();
|
||||
byte[] data = lastData.ReadChunk(length);
|
||||
packet = new NetworkPacket(header, data);
|
||||
return true;
|
||||
return socketBuffer.ReadPacket(out packet);
|
||||
}
|
||||
|
||||
public void Send(NetworkPacket packet) {
|
||||
@ -78,9 +66,13 @@ public class Client {
|
||||
}
|
||||
}
|
||||
|
||||
public void SheduleDisconnect() {
|
||||
scheduledDisconnect = true;
|
||||
}
|
||||
|
||||
public bool Connected {
|
||||
get {
|
||||
return socket.Connected;
|
||||
return socket.Connected && !scheduledDisconnect;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,11 @@ public class Room {
|
||||
|
||||
public IEnumerable<Client> Clients {
|
||||
get {
|
||||
return new List<Client>(clients);
|
||||
List<Client> list;
|
||||
lock (roomLock) {
|
||||
list = new List<Client>(clients);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,12 @@ public class NetworkData {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public int RemainingLength {
|
||||
get {
|
||||
return data.Length - offset;
|
||||
}
|
||||
}
|
||||
|
||||
public void Seek(int offset) {
|
||||
int newOffset = this.offset + offset;
|
||||
if (newOffset >= 0 && newOffset < data.Length)
|
||||
|
@ -33,12 +33,14 @@ public class NetworkPacket {
|
||||
header = 0xa0;
|
||||
this.compressed = true;
|
||||
}
|
||||
this.data = data.Data;
|
||||
this.data = new byte[data.Data.Length];
|
||||
Buffer.BlockCopy(data.Data, 0, this.data, 0, data.Data.Length);
|
||||
}
|
||||
|
||||
public NetworkPacket(byte header, byte[] data) {
|
||||
this.header = header;
|
||||
this.data = data;
|
||||
this.data = new byte[data.Length];
|
||||
Buffer.BlockCopy(data, 0, this.data, 0, data.Length);
|
||||
if (header == 0xa0)
|
||||
compressed = true;
|
||||
}
|
||||
|
54
src/Data/SocketBuffer.cs
Normal file
54
src/Data/SocketBuffer.cs
Normal file
@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace sodoffmmo.Data;
|
||||
internal class SocketBuffer {
|
||||
NetworkData data = new();
|
||||
Status status = Status.Header;
|
||||
byte header;
|
||||
short length;
|
||||
byte[] value = new byte[0];
|
||||
public void Write(byte[] buffer, int length) {
|
||||
data.WriteChunk(buffer, 0, length);
|
||||
}
|
||||
|
||||
public bool ReadPacket(out NetworkPacket packet) {
|
||||
packet = new();
|
||||
if (status == Status.Header)
|
||||
ReadHeader();
|
||||
|
||||
if (status == Status.Value) {
|
||||
ReadValue();
|
||||
if (status == Status.Header) {
|
||||
packet = new(header, value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void ReadHeader() {
|
||||
if (data.RemainingLength < 3)
|
||||
return;
|
||||
header = data.ReadByte();
|
||||
length = data.ReadShort();
|
||||
status = Status.Value;
|
||||
}
|
||||
|
||||
private void ReadValue() {
|
||||
if (data.RemainingLength < length)
|
||||
return;
|
||||
value = data.ReadChunk(length);
|
||||
data = new(data.ReadChunk(data.RemainingLength));
|
||||
status = Status.Header;
|
||||
}
|
||||
|
||||
enum Status {
|
||||
Header,
|
||||
Value
|
||||
}
|
||||
}
|
@ -47,12 +47,11 @@ public class Server {
|
||||
|
||||
_ = Task.Run(() => HandleObjects(networkObjects, client));
|
||||
}
|
||||
} catch (SocketException) {
|
||||
client.Disconnect();
|
||||
} finally {
|
||||
try {
|
||||
client.LeaveRoom();
|
||||
} catch (Exception) { }
|
||||
client.Disconnect();
|
||||
Console.WriteLine("Socket disconnected IID: " + client.ClientID);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user