2019-01-06 23:16:13 +01:00

112 lines
4.2 KiB
C#

using System;
using System.Collections;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
namespace Syroot.Worms.OnlineWorms.Server.Net
{
/// <summary>
/// Represents a packet with an ID specifying its contents. To allow the server to instantiate child packet classes,
/// decorate it with the <see cref="PacketAttribute"/>.
/// </summary>
internal abstract class Packet
{
// ---- METHODS (PUBLIC) ---------------------------------------------------------------------------------------
public override string ToString()
{
#if DEBUG
return String.Concat(GetType().Name, DumpClass(this, 1));
#else
return GetType().Name;
#endif
}
// ---- METHODS (INTERNAL) -------------------------------------------------------------------------------------
internal abstract void Deserialize(PacketStream stream);
internal abstract void Serialize(PacketStream stream);
// ---- METHODS (PRIVATE) --------------------------------------------------------------------------------------
#if DEBUG
private string DumpClass(object obj, int indentLevel)
{
StringBuilder sb = new StringBuilder();
string indent = new string(' ', indentLevel * 4);
switch (obj)
{
case null:
sb.Append($"{indent}null");
break;
case String stringValue:
sb.Append($"{indent}\"{stringValue}\"");
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(DumpClass(element, indentLevel)).Append(" ");
sb.Append("]");
break;
case Byte byteValue:
sb.Append($"{indent}0x{byteValue:X2}");
break;
case Int16 int16Value:
sb.Append($"{indent}0x{int16Value:X4}");
break;
case Int32 int32Value:
sb.Append($"{indent}0x{int32Value:X8}");
break;
case Int64 int64Value:
sb.Append($"{indent}0x{int64Value:X16}");
break;
case UInt16 uint16Value:
sb.Append($"{indent}0x{uint16Value:X4}");
break;
case UInt32 uint32Value:
sb.Append($"{indent}0x{uint32Value:X8}");
break;
case UInt64 uint64Value:
sb.Append($"{indent}0x{uint64Value:X16}");
break;
case IPEndPoint ipEndPoint:
sb.Append($"{indent}{ipEndPoint.Address}:{ipEndPoint.Port}");
break;
default:
Type objType = obj.GetType();
if (objType == typeof(Boolean) || objType.IsEnum || objType == typeof(Color)
|| objType == typeof(IPAddress))
{
sb.Append($"{indent}{obj}");
}
else
{
foreach (PropertyInfo property in objType.GetProperties(
BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public))
{
if (property.GetIndexParameters().Length > 0)
continue;
sb.AppendLine();
sb.Append((indent + property.Name).PadRight(20));
sb.Append(" ");
sb.Append(DumpClass(property.GetValue(obj), indentLevel + 1));
}
sb.AppendLine();
}
break;
}
return sb.ToString().TrimEnd();
}
#endif
}
}