PSO2SERVER/Server/QueryServer.cs
Longfeng Qin 37106641a7 物品读取修正
移除部分DEBUG信息
2024-12-11 02:24:51 +08:00

119 lines
3.8 KiB
C#

using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using PSO2SERVER.Models;
using PSO2SERVER.Protocol;
using System.Threading.Tasks;
using PSO2SERVER.Protocol.Packets;
namespace PSO2SERVER
{
public enum QueryMode
{
ShipList,/*12100 - 12900*/
AuthList
}
public class QueryServer
{
public static List<Task> RunningServers = new List<Task>();
private readonly QueryMode _mode;
private readonly int _port;
public QueryServer(QueryMode mode, string desc, int port)
{
_mode = mode;
_port = port;
var queryTask = Task.Run(() => RunAsync());
RunningServers.Add(queryTask);
//Logger.WriteInternal("[监听] 监听" + desc + "端口 " + port);
}
private async Task RunAsync()
{
Func<Socket, Task> connectionHandler;
switch (_mode)
{
case QueryMode.AuthList:
connectionHandler = DoBlockBalanceAsync;
break;
case QueryMode.ShipList:
connectionHandler = DoShipListAsync;
break;
default:
connectionHandler = DoShipListAsync;
break;
}
var serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
{
Blocking = true
};
var ep = new IPEndPoint(IPAddress.Any, _port);
serverSocket.Bind(ep); // TODO: Custom bind address.
serverSocket.Listen(5);
while (true)
{
var newConnection = await Task.Factory.FromAsync(serverSocket.BeginAccept, serverSocket.EndAccept, null);
_ = connectionHandler(newConnection); // Fire-and-forget pattern for handling connections
}
}
public ShipStatus CheckShipStatus(int port)
{
//TODO 还有其他状态要判断
if (PortChecker.IsPortListening(port))
{
return ShipStatus.Online;
}
return ShipStatus.Offline;
}
private async Task DoShipListAsync(Socket socket)
{
var entries = new List<ShipEntry>();
for (var i = 1; i <= 10; i++)
{
var entry = new ShipEntry
{
order = (ushort)i,
number = (uint)i,
//status = i == 2 ? ShipStatus.Online : ShipStatus.Full, // Maybe move to Config?
status = CheckShipStatus(ServerApp.ServerShipProt + (100 * (i - 1))), // Maybe move to Config?
name = String.Format("Ship{0:0#}", i),
ip = ServerApp.BindAddress.GetAddressBytes()
};
entries.Add(entry);
}
var shiplistpacket = new ShipListPacket(entries, (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds, 1).GetPacketBytes();
await Task.Factory.FromAsync(
(cb, state) => socket.BeginSend(shiplistpacket, 0, shiplistpacket.Length, SocketFlags.None, cb, state),
socket.EndSend,
null);
socket.Close();
}
private async Task DoBlockBalanceAsync(Socket socket)
{
var balancepacket = new BlockBalancePacket("test", 12205).GetPacketBytes();
await Task.Factory.FromAsync(
(cb, state) => socket.BeginSend(balancepacket, 0, balancepacket.Length, SocketFlags.None, cb, state),
socket.EndSend,
null);
socket.Close();
}
}
}