-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathWire.cs
More file actions
143 lines (131 loc) · 5.33 KB
/
Copy pathWire.cs
File metadata and controls
143 lines (131 loc) · 5.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace PhotonServer
{
// ── Photon reliable-UDP command types (ENet-derived) ─────────────────────
public enum CommandType : byte
{
Ack = 1,
Connect = 2,
VerifyConnect = 3,
Disconnect = 4,
Ping = 5,
SendReliable = 6,
SendUnreliable = 7,
SendFragment = 8,
}
// ── Photon message types (the byte after the 0xF3 magic) ─────────────────
// High bit 0x80 = encrypted payload.
public enum MsgType : byte
{
Init = 0,
InitResponse = 1,
OperationRequest = 2,
OperationResponse = 3,
Event = 4,
InternalOpRequest = 6,
InternalOpResponse = 7,
Message = 5,
}
// ── A parsed inbound command ─────────────────────────────────────────────
public sealed class PhotonCommand
{
public CommandType Type;
public byte Channel;
public byte Flags;
public byte Reserved;
public int Size;
public int ReliableSeq;
public int UnreliableSeq; // only for SendUnreliable
// Fragment fields (only for SendFragment, command type 8).
public int FragStartSeq;
public int FragCount;
public int FragNumber;
public int FragTotalLength;
public int FragOffset;
public byte[] Payload = Array.Empty<byte>();
public bool IsReliable => (Flags & 1) != 0;
}
// ── A parsed inbound packet (header + commands) ──────────────────────────
public sealed class PhotonPacket
{
public ushort PeerId;
public byte CrcEnabled;
public byte CommandCount;
public uint Timestamp;
public int Challenge;
public List<PhotonCommand> Commands = new();
}
public static class Wire
{
public const byte Magic = 0xF3;
// ── Big-endian primitive helpers ─────────────────────────────────────
public static void WriteU16(Stream s, ushort v) { s.WriteByte((byte)(v >> 8)); s.WriteByte((byte)v); }
public static void WriteU32(Stream s, uint v)
{
s.WriteByte((byte)(v >> 24)); s.WriteByte((byte)(v >> 16));
s.WriteByte((byte)(v >> 8)); s.WriteByte((byte)v);
}
public static void WriteI32(Stream s, int v) => WriteU32(s, (uint)v);
public static ushort ReadU16(byte[] b, int o) => (ushort)((b[o] << 8) | b[o + 1]);
public static uint ReadU32(byte[] b, int o) => (uint)((b[o] << 24) | (b[o + 1] << 16) | (b[o + 2] << 8) | b[o + 3]);
public static int ReadI32(byte[] b, int o) => (int)ReadU32(b, o);
// ── Packet parsing ───────────────────────────────────────────────────
public static PhotonPacket? Parse(byte[] b, int len)
{
if (len < 12) return null;
var p = new PhotonPacket
{
PeerId = ReadU16(b, 0),
CrcEnabled = b[2],
CommandCount = b[3],
Timestamp = ReadU32(b, 4),
Challenge = ReadI32(b, 8),
};
int o = 12;
for (int i = 0; i < p.CommandCount; i++)
{
if (o + 12 > len) break;
var c = new PhotonCommand
{
Type = (CommandType)b[o],
Channel = b[o + 1],
Flags = b[o + 2],
Reserved = b[o + 3],
Size = ReadI32(b, o + 4),
ReliableSeq = ReadI32(b, o + 8),
};
int payloadStart = o + 12;
if (c.Type == CommandType.SendUnreliable)
{
if (o + 16 > len) break;
c.UnreliableSeq = ReadI32(b, o + 12);
payloadStart = o + 16;
}
else if (c.Type == CommandType.SendFragment)
{
if (o + 32 > len) break;
c.FragStartSeq = ReadI32(b, o + 12);
c.FragCount = ReadI32(b, o + 16);
c.FragNumber = ReadI32(b, o + 20);
c.FragTotalLength = ReadI32(b, o + 24);
c.FragOffset = ReadI32(b, o + 28);
payloadStart = o + 32;
}
int end = o + c.Size;
if (c.Size < 12 || end > len) break;
int payLen = end - payloadStart;
if (payLen > 0)
{
c.Payload = new byte[payLen];
Array.Copy(b, payloadStart, c.Payload, 0, payLen);
}
p.Commands.Add(c);
o = end;
}
return p;
}
}
}