-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReplayFile.cs
More file actions
130 lines (113 loc) · 3.7 KB
/
ReplayFile.cs
File metadata and controls
130 lines (113 loc) · 3.7 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
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GS_ReplayBrowser
{
class FileFormatException : Exception
{
public FileFormatException(string msg)
: base(msg)
{
}
}
class ReplayFile
{
private static UInt32 Magic = 0x50525347;
public int BaseLap;
public UInt16[] InputData;
public ChatMessage[] ChatMessages;
public int FileSize;
public class ChatMessage
{
public UInt32 Time;
public UInt32 Player;
public string Message;
}
public ReplayFile(string filename)
{
var data = File.ReadAllBytes(filename);
if (BitConverter.ToUInt32(data, 0) != Magic)
{
throw new FileFormatException("not a replay file");
}
var baseLap = BitConverter.ToUInt32(data, 4);
var length = BitConverter.ToUInt32(data, 8);
var chat = BitConverter.ToUInt32(data, 12);
if ((length % 3) != 0)
{
throw new FileFormatException("invalid file length");
}
BaseLap = (int)baseLap;
InputData = new UInt16[length];
Buffer.BlockCopy(data, 16, InputData, 0, (int)length * 2);
int chatOffset = 16 + (int)length * 2;
ChatMessages = new ChatMessage[chat];
for (int i = 0; i < chat; ++i)
{
try
{
ChatMessages[i] = ReadChat(data, ref chatOffset);
}
catch
{
throw new FileFormatException("chat message reading error");
}
}
FileSize = data.Length;
}
public ReplayFile(int lap, int time)
{
BaseLap = lap;
InputData = new UInt16[time * 3];
ChatMessages = new ChatMessage[0];
}
private static ChatMessage ReadChat(byte[] data, ref int offset)
{
var t = BitConverter.ToUInt32(data, offset);
var p = BitConverter.ToUInt32(data, offset + 4);
var l = BitConverter.ToUInt32(data, offset + 8);
char[] str = new char[l];
Buffer.BlockCopy(data, offset + 12, str, 0, (int)l * 2);
offset += (int)(12 + ((l + 1) * 2));
return new ChatMessage
{
Time = t,
Player = p,
Message = new string(str),
};
}
public void Save(string filename)
{
if (File.Exists(filename))
{
File.Delete(filename);
}
using (var file = File.OpenWrite(filename))
{
using (var w = new BinaryWriter(file))
{
w.Write(Magic);
w.Write(BaseLap);
w.Write(InputData.Length);
w.Write(ChatMessages.Length);
foreach (var input in InputData)
{
w.Write(input);
}
foreach (var msg in ChatMessages)
{
w.Write(msg.Time);
w.Write(msg.Player);
w.Write(msg.Message.Length);
var buffer = new byte[(msg.Message.Length + 1) * 2];
Buffer.BlockCopy(msg.Message.ToCharArray(), 0, buffer, 0, msg.Message.Length * 2);
w.Write(buffer);
}
}
}
}
}
}