forked from SoDOff-Project/sodoff-mmo
84 lines
2.1 KiB
C#
84 lines
2.1 KiB
C#
using sodoffmmo.Data;
|
|
using System;
|
|
using System.Net.Sockets;
|
|
|
|
namespace sodoffmmo.Core;
|
|
public class Client {
|
|
static int id;
|
|
static object lck = new();
|
|
|
|
public int ClientID { get; private set; }
|
|
public PlayerData PlayerData { get; set; } = new();
|
|
public Room Room { get; set; }
|
|
|
|
private readonly Socket socket;
|
|
SocketBuffer socketBuffer = new();
|
|
private volatile bool scheduledDisconnect = false;
|
|
|
|
public Client(Socket clientSocket) {
|
|
socket = clientSocket;
|
|
lock (lck) {
|
|
ClientID = ++id;
|
|
}
|
|
}
|
|
|
|
public async Task Receive() {
|
|
byte[] buffer = new byte[2048];
|
|
int len = await socket.ReceiveAsync(buffer, SocketFlags.None);
|
|
if (len == 0)
|
|
throw new SocketException();
|
|
socketBuffer.Write(buffer, len);
|
|
}
|
|
|
|
public bool TryGetNextPacket(out NetworkPacket packet) {
|
|
return socketBuffer.ReadPacket(out packet);
|
|
}
|
|
|
|
public void Send(NetworkPacket packet) {
|
|
try {
|
|
socket.Send(packet.SendData);
|
|
} catch (SocketException) {
|
|
LeaveRoom();
|
|
SheduleDisconnect();
|
|
}
|
|
}
|
|
|
|
public void LeaveRoom() {
|
|
if (Room != null) {
|
|
Console.WriteLine($"Leave room {Room.Name} IID: {ClientID}");
|
|
Room.RemoveClient(this);
|
|
NetworkObject data = new();
|
|
data.Add("r", Room.Id);
|
|
data.Add("u", ClientID);
|
|
|
|
NetworkPacket packet = NetworkObject.WrapObject(0, 1004, data).Serialize();
|
|
foreach (var roomClient in Room.Clients) {
|
|
roomClient.Send(packet);
|
|
}
|
|
Room = null;
|
|
}
|
|
}
|
|
|
|
public void InvalidatePlayerData() {
|
|
PlayerData = new();
|
|
}
|
|
|
|
public void Disconnect() {
|
|
try {
|
|
socket.Shutdown(SocketShutdown.Both);
|
|
} finally {
|
|
socket.Close();
|
|
}
|
|
}
|
|
|
|
public void SheduleDisconnect() {
|
|
scheduledDisconnect = true;
|
|
}
|
|
|
|
public bool Connected {
|
|
get {
|
|
return socket.Connected && !scheduledDisconnect;
|
|
}
|
|
}
|
|
}
|