mirror of
https://gitlab.com/Syroot/Worms.git
synced 2025-03-04 17:35:22 +03:00
Add common server logging.
This commit is contained in:
parent
bb7d633f21
commit
30c1454522
@ -26,14 +26,27 @@ namespace Syroot.Worms.OnlineWorms.Server
|
|||||||
_server = server;
|
_server = server;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- METHODS (PROTECTED) ------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
protected override void OnPrePacketHandle(Packet packet)
|
||||||
|
{
|
||||||
|
_server.Log.Write(LogCategory.Client, $"{TcpClient.Client.RemoteEndPoint} >> {packet}");
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnPrePacketSend(Packet packet)
|
||||||
|
{
|
||||||
|
_server.Log.Write(LogCategory.Server, $"{TcpClient.Client.RemoteEndPoint} << {packet}");
|
||||||
|
}
|
||||||
|
|
||||||
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
private Packet HandleConnect(ConnectQueryPacket connectPacket)
|
private Packet HandleConnect(ConnectQueryPacket connectPacket)
|
||||||
{
|
{
|
||||||
return new ConnectReplyPacket
|
return new ConnectReplyPacket
|
||||||
{
|
{
|
||||||
Unknown = "Online Worms Private Server",
|
Unknown = _server.Name,
|
||||||
Version = "114"
|
Unknown2 = _server.RegionName,
|
||||||
|
Version = _server.Version
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
src/Syroot.OnlineWorms.Server/Log.cs
Normal file
40
src/Syroot.OnlineWorms.Server/Log.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Syroot.Worms.OnlineWorms.Server
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents simplistic textual logging.
|
||||||
|
/// </summary>
|
||||||
|
internal class Log
|
||||||
|
{
|
||||||
|
// ---- FIELDS -------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private readonly object _lock = new object();
|
||||||
|
|
||||||
|
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
internal void Write(LogCategory category, string text) => Write((ConsoleColor)category, text);
|
||||||
|
|
||||||
|
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
private void Write(ConsoleColor color, string text)
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
ConsoleColor prevColor = Console.ForegroundColor;
|
||||||
|
Console.ForegroundColor = color;
|
||||||
|
Console.WriteLine(text);
|
||||||
|
Console.ForegroundColor = prevColor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum LogCategory
|
||||||
|
{
|
||||||
|
Info = ConsoleColor.White,
|
||||||
|
Connect = ConsoleColor.Cyan,
|
||||||
|
Disconnect = ConsoleColor.Magenta,
|
||||||
|
Client = ConsoleColor.DarkCyan,
|
||||||
|
Server = ConsoleColor.DarkMagenta
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,6 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
= new Dictionary<Type, Dictionary<Type, MethodInfo>>();
|
= new Dictionary<Type, Dictionary<Type, MethodInfo>>();
|
||||||
|
|
||||||
private readonly Dictionary<Type, MethodInfo> _handlers;
|
private readonly Dictionary<Type, MethodInfo> _handlers;
|
||||||
private readonly TcpClient _tcpClient;
|
|
||||||
private readonly byte[] _receiveBuffer;
|
private readonly byte[] _receiveBuffer;
|
||||||
private readonly byte[] _sendDataBuffer;
|
private readonly byte[] _sendDataBuffer;
|
||||||
private readonly PacketStream _receiveStream;
|
private readonly PacketStream _receiveStream;
|
||||||
@ -36,19 +35,25 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
/// Initializes a new instance of the <see cref="GameConnection"/> class, handling the given
|
/// Initializes a new instance of the <see cref="GameConnection"/> class, handling the given
|
||||||
/// <paramref name="tcpClient"/>.
|
/// <paramref name="tcpClient"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tcpClient">The <see cref="TcpClient"/> to communicate with.</param>
|
/// <param name="tcpClient">The <see cref="System.Net.Sockets.TcpClient"/> to communicate with.</param>
|
||||||
internal GameConnection(TcpClient tcpClient)
|
internal GameConnection(TcpClient tcpClient)
|
||||||
{
|
{
|
||||||
_tcpClient = tcpClient;
|
TcpClient = tcpClient;
|
||||||
Console.WriteLine($"{_tcpClient.Client.RemoteEndPoint} connected");
|
|
||||||
|
|
||||||
_handlers = GetHandlers();
|
_handlers = GetHandlers();
|
||||||
_receiveBuffer = new byte[_maxDataSize];
|
_receiveBuffer = new byte[_maxDataSize];
|
||||||
_receiveBuffer = new byte[_maxDataSize];
|
_sendDataBuffer = new byte[_maxDataSize];
|
||||||
_receiveStream = new PacketStream(_tcpClient.GetStream());
|
_receiveStream = new PacketStream(TcpClient.GetStream());
|
||||||
_sendStream = new PacketStream(new MemoryStream(_sendDataBuffer, 0, _maxDataSize, true));
|
_sendStream = new PacketStream(new MemoryStream(_sendDataBuffer, 0, _maxDataSize, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the <see cref="TcpClient"/> with which the connection communicates.
|
||||||
|
/// </summary>
|
||||||
|
internal TcpClient TcpClient { get; }
|
||||||
|
|
||||||
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
@ -77,7 +82,7 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
_tcpClient.Dispose();
|
TcpClient.Dispose();
|
||||||
_sendStream.Dispose();
|
_sendStream.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,6 +90,10 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected virtual void OnPrePacketHandle(Packet packet) { }
|
||||||
|
|
||||||
|
protected virtual void OnPrePacketSend(Packet packet) { }
|
||||||
|
|
||||||
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
private Dictionary<Type, MethodInfo> GetHandlers()
|
private Dictionary<Type, MethodInfo> GetHandlers()
|
||||||
@ -107,13 +116,13 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
|
|
||||||
private void HandlePacket(Packet inPacket)
|
private void HandlePacket(Packet inPacket)
|
||||||
{
|
{
|
||||||
|
OnPrePacketHandle(inPacket);
|
||||||
Type packetType = inPacket.GetType();
|
Type packetType = inPacket.GetType();
|
||||||
Console.WriteLine($"{_tcpClient.Client.RemoteEndPoint} >> {packetType.Name}");
|
|
||||||
|
|
||||||
// Invoke the handler and send back any packet resulting from it.
|
// Invoke the handler and send back any packet resulting from it.
|
||||||
if (_handlers[packetType].Invoke(this, new[] { inPacket }) is Packet outPacket)
|
if (_handlers[packetType].Invoke(this, new[] { inPacket }) is Packet outPacket)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{_tcpClient.Client.RemoteEndPoint} << {outPacket.GetType().Name}");
|
OnPrePacketSend(outPacket);
|
||||||
SendPacket(outPacket);
|
SendPacket(outPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
namespace Syroot.Worms.OnlineWorms.Server.Net
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Syroot.Worms.OnlineWorms.Server.Net
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents a packet with an ID specifying its contents. To allow the server to instantiate child packet classes,
|
/// Represents a packet with an ID specifying its contents. To allow the server to instantiate child packet classes,
|
||||||
@ -6,6 +12,93 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal abstract class Packet
|
internal abstract class Packet
|
||||||
{
|
{
|
||||||
|
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
#if DEBUG
|
||||||
|
string dump(object obj, int indentLevel)
|
||||||
|
{
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
string indent = new string(' ', indentLevel * 4);
|
||||||
|
switch (obj)
|
||||||
|
{
|
||||||
|
case null:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append("null");
|
||||||
|
break;
|
||||||
|
case String stringValue:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append('"');
|
||||||
|
sb.Append(stringValue);
|
||||||
|
sb.Append('"');
|
||||||
|
break;
|
||||||
|
case Byte[] byteArrayValue:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append(String.Join(" ", byteArrayValue.Select(x => x.ToString("X2"))));
|
||||||
|
break;
|
||||||
|
case IEnumerable iEnumerableValue:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append("[ ");
|
||||||
|
foreach (object element in iEnumerableValue)
|
||||||
|
sb.Append(dump(element, indentLevel)).Append(" ");
|
||||||
|
sb.Append("]");
|
||||||
|
break;
|
||||||
|
case Byte byteValue:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append("0x" + byteValue.ToString("X2"));
|
||||||
|
break;
|
||||||
|
case Int16 int16Value:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append("0x" + int16Value.ToString("X4"));
|
||||||
|
break;
|
||||||
|
case Int32 int32Value:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append("0x" + int32Value.ToString("X8"));
|
||||||
|
break;
|
||||||
|
case Int64 int64Value:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append("0x" + int64Value.ToString("X16"));
|
||||||
|
break;
|
||||||
|
case UInt16 uint16Value:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append("0x" + uint16Value.ToString("X4"));
|
||||||
|
break;
|
||||||
|
case UInt32 uint32Value:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append("0x" + uint32Value.ToString("X8"));
|
||||||
|
break;
|
||||||
|
case UInt64 uint64Value:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append("0x" + uint64Value.ToString("X16"));
|
||||||
|
break;
|
||||||
|
case Enum enumValue:
|
||||||
|
sb.Append(indent);
|
||||||
|
sb.Append(enumValue.ToString());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
foreach (PropertyInfo property in obj.GetType().GetProperties(
|
||||||
|
BindingFlags.Instance | BindingFlags.NonPublic))
|
||||||
|
{
|
||||||
|
// Ignore indexers.
|
||||||
|
if (property.GetIndexParameters().Length > 0)
|
||||||
|
continue;
|
||||||
|
sb.AppendLine();
|
||||||
|
sb.Append((indent + property.Name).PadRight(20));
|
||||||
|
sb.Append(" ");
|
||||||
|
sb.Append(dump(property.GetValue(obj), indentLevel + 1));
|
||||||
|
}
|
||||||
|
sb.AppendLine();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return sb.ToString().TrimEnd();
|
||||||
|
}
|
||||||
|
return String.Concat(GetType().Name, dump(this, 1));
|
||||||
|
#else
|
||||||
|
return GetType().Name;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
internal abstract void Deserialize(PacketStream stream);
|
internal abstract void Deserialize(PacketStream stream);
|
||||||
|
@ -2,11 +2,19 @@
|
|||||||
|
|
||||||
namespace Syroot.Worms.OnlineWorms.Server.Net
|
namespace Syroot.Worms.OnlineWorms.Server.Net
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Decorates a <see cref="Packet"/> child class with the ID of the packet it represents.
|
||||||
|
/// </summary>
|
||||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
|
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
|
||||||
internal class PacketAttribute : Attribute
|
internal class PacketAttribute : Attribute
|
||||||
{
|
{
|
||||||
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="PacketAttribute"/> class, decorating a class with the ID of the
|
||||||
|
/// packet it represents.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="id">The ID of the packet which the decorated class represents.</param>
|
||||||
public PacketAttribute(ushort id)
|
public PacketAttribute(ushort id)
|
||||||
{
|
{
|
||||||
ID = id;
|
ID = id;
|
||||||
@ -14,6 +22,9 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
|
|
||||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the ID of the packet the decorated class represents.
|
||||||
|
/// </summary>
|
||||||
public ushort ID { get; }
|
public ushort ID { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
{
|
{
|
||||||
// ---- FIELDS -------------------------------------------------------------------------------------------------
|
// ---- FIELDS -------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
private static readonly Dictionary<ushort, Type> _packetTypeMap = new Dictionary<ushort, Type>();
|
private static readonly Dictionary<ushort, Type> _packetTypes = new Dictionary<ushort, Type>();
|
||||||
|
|
||||||
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
// ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -23,9 +23,9 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
{
|
{
|
||||||
foreach (PacketAttribute packetAttribute in type.GetCustomAttributes<PacketAttribute>())
|
foreach (PacketAttribute packetAttribute in type.GetCustomAttributes<PacketAttribute>())
|
||||||
{
|
{
|
||||||
if (_packetTypeMap.ContainsKey(packetAttribute.ID))
|
if (_packetTypes.ContainsKey(packetAttribute.ID))
|
||||||
throw new InvalidOperationException($"Packet {packetAttribute.ID} mapped to multiple classes.");
|
throw new InvalidOperationException($"Packet {packetAttribute.ID} mapped to multiple classes.");
|
||||||
_packetTypeMap.Add(packetAttribute.ID, type);
|
_packetTypes.Add(packetAttribute.ID, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,27 +41,27 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
internal static Packet Create(ushort id)
|
internal static Packet Create(ushort id)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
return _packetTypeMap.TryGetValue(id, out Type type)
|
return _packetTypes.TryGetValue(id, out Type type)
|
||||||
? (Packet)Activator.CreateInstance(type, true)
|
? (Packet)Activator.CreateInstance(type, true)
|
||||||
: new RawQueryPacket(id);
|
: new RawQueryPacket(id);
|
||||||
#else
|
#else
|
||||||
return (Packet)Activator.CreateInstance(_packetTypeMap[id], true);
|
return (Packet)Activator.CreateInstance(_packetTypes[id], true);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the ID for the class of the given <paramref name="packet"/>.
|
/// Gets the ID for the class of the given <paramref name="packet"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T">The type of the <see cref="Packet"/>.</typeparam>
|
|
||||||
/// <param name="packet">The packet, whose class ID will be returned.</param>
|
/// <param name="packet">The packet, whose class ID will be returned.</param>
|
||||||
/// <returns>The ID of the <see cref="Packet"/> class.</returns>
|
/// <returns>The ID of the <see cref="Packet"/> class.</returns>
|
||||||
internal static ushort GetID<T>(T packet) where T : Packet
|
internal static ushort GetID(Packet packet)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if (packet is RawQueryPacket rawPacket)
|
if (packet is RawQueryPacket rawPacket)
|
||||||
return rawPacket.ID;
|
return rawPacket.ID;
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
return _packetTypeMap.Where(x => x.Value == packet.GetType()).First().Key;
|
return _packetTypes.Where(x => x.Value == packet.GetType()).First().Key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,17 +90,12 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
|
|
||||||
internal string ReadString()
|
internal string ReadString()
|
||||||
{
|
{
|
||||||
// Strings are word prefixed and 0 termianted.
|
return _baseStream.ReadString(StringCoding.Int16CharCount);
|
||||||
string value = _baseStream.ReadString(StringCoding.Int16CharCount);
|
|
||||||
_baseStream.Seek(1);
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void WriteString(string value)
|
internal void WriteString(string value)
|
||||||
{
|
{
|
||||||
// Strings are word prefixed and 0 termianted.
|
|
||||||
_baseStream.WriteString(value, StringCoding.Int16CharCount, _win949Encoding);
|
_baseStream.WriteString(value, StringCoding.Int16CharCount, _win949Encoding);
|
||||||
_baseStream.WriteByte(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using Syroot.BinaryData;
|
||||||
|
|
||||||
namespace Syroot.Worms.OnlineWorms.Server.Net
|
namespace Syroot.Worms.OnlineWorms.Server.Net
|
||||||
{
|
{
|
||||||
@ -10,9 +11,11 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
{
|
{
|
||||||
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
public string Unknown { get; set; }
|
internal string Unknown { get; set; }
|
||||||
|
|
||||||
public string Version { get; set; }
|
internal string Unknown2 { get; set; }
|
||||||
|
|
||||||
|
internal ushort Version { get; set; }
|
||||||
|
|
||||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -21,7 +24,9 @@ namespace Syroot.Worms.OnlineWorms.Server.Net
|
|||||||
internal override void Serialize(PacketStream stream)
|
internal override void Serialize(PacketStream stream)
|
||||||
{
|
{
|
||||||
stream.WriteString(Unknown);
|
stream.WriteString(Unknown);
|
||||||
stream.WriteString(Version);
|
stream.WriteByte(0);
|
||||||
|
stream.WriteString(Unknown2);
|
||||||
|
stream.WriteUInt16(Version);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|
||||||
namespace Syroot.Worms.OnlineWorms.Server.Net
|
namespace Syroot.Worms.OnlineWorms.Server.Net
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -10,12 +9,20 @@ namespace Syroot.Worms.OnlineWorms.Server
|
|||||||
/// Represents a server listening for incoming client connections and dispatching them into <see cref="Client"/>
|
/// Represents a server listening for incoming client connections and dispatching them into <see cref="Client"/>
|
||||||
/// instances.
|
/// instances.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class Server
|
internal class Server
|
||||||
{
|
{
|
||||||
// ---- FIELDS -------------------------------------------------------------------------------------------------
|
// ---- FIELDS -------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
private readonly List<Client> _clients = new List<Client>();
|
private readonly List<Client> _clients = new List<Client>();
|
||||||
|
|
||||||
|
// ---- PROPERTIES ---------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
internal string Name => "Online Worms Private Server";
|
||||||
|
internal string RegionName => "Global";
|
||||||
|
internal ushort Version => 114;
|
||||||
|
|
||||||
|
internal Log Log { get; } = new Log();
|
||||||
|
|
||||||
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -27,16 +34,20 @@ namespace Syroot.Worms.OnlineWorms.Server
|
|||||||
{
|
{
|
||||||
TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
|
TcpListener tcpListener = new TcpListener(IPAddress.Any, port);
|
||||||
tcpListener.Start();
|
tcpListener.Start();
|
||||||
Console.WriteLine($"Listening on port {port}...");
|
Log.Write(LogCategory.Server, $"Listening on port {port}...");
|
||||||
|
|
||||||
// Continually accept clients and dispatch them to their listening thread.
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
Client client = new Client(tcpListener.AcceptTcpClient(), this);
|
// Continually accept clients.
|
||||||
|
TcpClient tcpClient = tcpListener.AcceptTcpClient();
|
||||||
|
Log.Write(LogCategory.Connect, $"{tcpClient.Client.RemoteEndPoint} connected");
|
||||||
|
Client client = new Client(tcpClient, this);
|
||||||
_clients.Add(client);
|
_clients.Add(client);
|
||||||
|
|
||||||
|
// Dispatch the client into its listening thread and remove it when listening aborts.
|
||||||
Task.Run(client.Listen).ContinueWith(_ =>
|
Task.Run(client.Listen).ContinueWith(_ =>
|
||||||
{
|
{
|
||||||
|
Log.Write(LogCategory.Disconnect, $"{client.TcpClient.Client.RemoteEndPoint} disconnected");
|
||||||
_clients.Remove(client);
|
_clients.Remove(client);
|
||||||
client.Dispose();
|
client.Dispose();
|
||||||
});
|
});
|
||||||
|
@ -4,9 +4,6 @@
|
|||||||
<TargetFramework>netcoreapp2.1</TargetFramework>
|
<TargetFramework>netcoreapp2.1</TargetFramework>
|
||||||
<LangVersion>latest</LangVersion>
|
<LangVersion>latest</LangVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Syroot.BinaryData" Version="5.0.0" />
|
<PackageReference Include="Syroot.BinaryData" Version="5.0.0" />
|
||||||
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
|
<PackageReference Include="System.Text.Encoding.CodePages" Version="4.5.0" />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user