mirror of
https://github.com/rafi1212122/PemukulPaku
synced 2025-12-12 19:44:37 +01:00
153 lines
5.2 KiB
C#
153 lines
5.2 KiB
C#
using System.Net.Sockets;
|
|
using Common;
|
|
using Common.Resources.Proto;
|
|
using Common.Utils;
|
|
using PemukulPaku.GameServer.Game;
|
|
|
|
namespace PemukulPaku.GameServer
|
|
{
|
|
public class Session
|
|
{
|
|
public readonly string Id;
|
|
public readonly TcpClient Client;
|
|
public readonly Logger c;
|
|
public Player Player = default!;
|
|
|
|
public Session(string id, TcpClient client)
|
|
{
|
|
Id = id;
|
|
Client = client;
|
|
c = new Logger(Id);
|
|
Task.Run(() => ClientLoop(client));
|
|
}
|
|
|
|
private void ClientLoop(TcpClient client)
|
|
{
|
|
NetworkStream stream = client.GetStream();
|
|
|
|
byte[] packetMagic = { 0x01, 0x23, 0x45, 0x67 }; // Magic start pattern
|
|
byte[] packetEnd = { 0x89, 0xAB, 0xCD, 0xEF }; // Magic end pattern
|
|
|
|
byte[] buffer = new byte[4096];
|
|
int bytesRead;
|
|
|
|
try
|
|
{
|
|
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) > 0)
|
|
{
|
|
// Process the received bytes
|
|
for (int i = 0; i < bytesRead; i++)
|
|
{
|
|
if (buffer[i] == packetMagic[0])
|
|
{
|
|
bool found = true;
|
|
for (int j = 1; j < packetMagic.Length; j++)
|
|
{
|
|
if (buffer[i + j] != packetMagic[j])
|
|
{
|
|
found = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (found)
|
|
{
|
|
// Magic start pattern found
|
|
int endIndex = Array.IndexOf(buffer, packetEnd[0], i + packetMagic.Length);
|
|
if (endIndex != -1)
|
|
{
|
|
// Magic end pattern found
|
|
int packetLength = endIndex - i + packetEnd.Length;
|
|
byte[] packet = new byte[packetLength];
|
|
Array.Copy(buffer, i, packet, 0, packetLength);
|
|
|
|
// Process the packet
|
|
ProcessPacket(packet);
|
|
|
|
// Update the buffer
|
|
int remainingBytes = bytesRead - (i + packetLength);
|
|
Array.Copy(buffer, i + packetLength, buffer, 0, remainingBytes);
|
|
|
|
// Adjust the bytesRead value accordingly
|
|
bytesRead = remainingBytes;
|
|
i = -1; // Start processing from the beginning of the buffer again
|
|
}
|
|
else
|
|
{
|
|
// End pattern not found, break the loop and wait for more data
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (Client != null)
|
|
{
|
|
c.Warn($"{Id} disconnected");
|
|
Server.GetInstance().Sessions.Remove(Id);
|
|
c.Debug("TCP client disconnect reason: " + ex.Message);
|
|
}
|
|
else
|
|
{
|
|
c.Error("TCP client error: " + ex.Message);
|
|
}
|
|
}
|
|
finally { Server.GetInstance().LogClients(); };
|
|
}
|
|
|
|
public void ProcessPacket(byte[] packet)
|
|
{
|
|
Packet _packet = new(packet);
|
|
string PacketName = Enum.GetName(typeof(CmdId), _packet.CmdId)!;
|
|
try
|
|
{
|
|
CmdId cmdId = (CmdId)Enum.ToObject(typeof(CmdId), _packet.CmdId);
|
|
IPacketHandler? handler = PacketFactory.GetPacketHandler(cmdId);
|
|
|
|
if (handler == null)
|
|
{
|
|
c.Warn($"{PacketName} not handled!");
|
|
return;
|
|
}
|
|
|
|
c.Log(PacketName);
|
|
|
|
handler.Handle(this, _packet);
|
|
}
|
|
catch(Exception ex)
|
|
{
|
|
if ((int)Global.config.VerboseLevel > 0)
|
|
{
|
|
c.Error(ex.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void Send(params Packet[] packets)
|
|
{
|
|
foreach (Packet packet in packets)
|
|
{
|
|
string PacketName = Enum.GetName(typeof(CmdId), packet.CmdId)!;
|
|
|
|
try
|
|
{
|
|
Client.GetStream().Write(packet.Raw, 0, packet.Raw.Length);
|
|
c.Log(PacketName);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
c.Error($"Failed to send {PacketName}:" + ex.Message);
|
|
}
|
|
}
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return Id;
|
|
}
|
|
}
|
|
}
|