Files
AIC-Project/Client/Assets/Framework/Shared/Protocol/DevDiscovery.cs
T
2026-07-10 10:24:29 +08:00

114 lines
3.4 KiB
C#

using System;
namespace XWorld.Framework.Protocol
{
public static class DevDiscovery
{
public const int Port = 48923;
public const uint ProtoVersion = 1;
public static readonly byte[] Magic = { 0x58, 0x57, 0x44, 0x4C };
public const byte TypeQuery = 1;
public const byte TypeReply = 2;
}
public struct DevDiscoveryQuery
{
public uint ProtoVersion;
public uint Nonce;
public string Token;
}
public struct DevDiscoveryReply
{
public uint ProtoVersion;
public uint Nonce;
public string ServerName;
public string GatewayUrl;
public string ResourceBaseUrl;
public string Token;
}
public static class DevDiscoveryCodec
{
public static byte[] EncodeQuery(DevDiscoveryQuery q)
{
var w = new PacketWriter(32);
WriteHeader(w, DevDiscovery.TypeQuery);
w.WriteVarUInt(q.ProtoVersion);
w.WriteVarUInt(q.Nonce);
w.WriteString(q.Token);
return w.ToArray();
}
public static byte[] EncodeReply(DevDiscoveryReply r)
{
var w = new PacketWriter(96);
WriteHeader(w, DevDiscovery.TypeReply);
w.WriteVarUInt(r.ProtoVersion);
w.WriteVarUInt(r.Nonce);
w.WriteString(r.ServerName);
w.WriteString(r.GatewayUrl);
w.WriteString(r.ResourceBaseUrl);
w.WriteString(r.Token);
return w.ToArray();
}
public static bool TryDecodeQuery(byte[] data, out DevDiscoveryQuery q)
{
q = default;
try
{
var r = new PacketReader(data);
if (!ReadAndCheckHeader(r, DevDiscovery.TypeQuery)) return false;
q.ProtoVersion = r.ReadVarUInt();
q.Nonce = r.ReadVarUInt();
q.Token = r.ReadString();
return true;
}
catch (FormatException)
{
return false;
}
}
public static bool TryDecodeReply(byte[] data, out DevDiscoveryReply reply)
{
reply = default;
try
{
var r = new PacketReader(data);
if (!ReadAndCheckHeader(r, DevDiscovery.TypeReply)) return false;
reply.ProtoVersion = r.ReadVarUInt();
reply.Nonce = r.ReadVarUInt();
reply.ServerName = r.ReadString();
reply.GatewayUrl = r.ReadString();
reply.ResourceBaseUrl = r.ReadString();
reply.Token = r.ReadString();
return true;
}
catch (FormatException)
{
return false;
}
}
private static void WriteHeader(PacketWriter w, byte type)
{
for (int i = 0; i < DevDiscovery.Magic.Length; i++)
{
w.WriteByte(DevDiscovery.Magic[i]);
}
w.WriteByte(type);
}
private static bool ReadAndCheckHeader(PacketReader r, byte expectedType)
{
for (int i = 0; i < DevDiscovery.Magic.Length; i++)
{
if (r.ReadByte() != DevDiscovery.Magic[i]) return false;
}
return r.ReadByte() == expectedType;
}
}
}