-
Notifications
You must be signed in to change notification settings - Fork 20
/
RobloxFile.cs
153 lines (134 loc) · 5.24 KB
/
RobloxFile.cs
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
144
145
146
147
148
149
150
151
152
153
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace RobloxFiles
{
/// <summary>
/// Represents a loaded Roblox place/model file.
/// RobloxFile is an Instance and its children are the contents of the file.
/// </summary>
public abstract class RobloxFile : Instance
{
public static bool LogErrors = false;
protected abstract void ReadFile(byte[] buffer);
/// <summary>
/// Saves this RobloxFile to the provided stream.
/// </summary>
/// <param name="stream">The stream to save to.</param>
public abstract void Save(Stream stream);
/// <summary>
/// Opens a RobloxFile using the provided buffer.
/// </summary>
/// <returns>The opened RobloxFile.</returns>
public static RobloxFile Open(byte[] buffer)
{
if (buffer.Length > 14)
{
string header = Encoding.UTF7.GetString(buffer, 0, 14);
RobloxFile file = null;
if (header == BinaryRobloxFile.MagicHeader)
file = new BinaryRobloxFile();
else if (header.StartsWith("<roblox"))
file = new XmlRobloxFile();
if (file != null)
{
file.ReadFile(buffer);
return file;
}
}
throw new Exception("Unrecognized header!");
}
/// <summary>
/// Opens a Roblox file by reading from a provided Stream.
/// </summary>
/// <param name="stream">The stream to read the Roblox file from.</param>
/// <returns>The opened RobloxFile.</returns>
public static RobloxFile Open(Stream stream)
{
byte[] buffer;
using (MemoryStream memoryStream = new MemoryStream())
{
stream.CopyTo(memoryStream);
buffer = memoryStream.ToArray();
}
return Open(buffer);
}
/// <summary>
/// Opens a Roblox file from a provided file path.
/// </summary>
/// <param name="filePath">A path to a Roblox file to be opened.</param>
/// <returns>The opened RobloxFile.</returns>
public static RobloxFile Open(string filePath)
{
byte[] buffer = File.ReadAllBytes(filePath);
return Open(buffer);
}
/// <summary>
/// Creates and runs a Task to open a Roblox file from a byte sequence that represents the file.
/// </summary>
/// <param name="buffer">A byte sequence that represents the file.</param>
/// <returns>A task which will complete once the file is opened with the resulting RobloxFile.</returns>
public static Task<RobloxFile> OpenAsync(byte[] buffer)
{
return Task.Run(() => Open(buffer));
}
/// <summary>
/// Creates and runs a Task to open a Roblox file using a provided Stream.
/// </summary>
/// <param name="stream">The stream to read the Roblox file from.</param>
/// <returns>A task which will complete once the file is opened with the resulting RobloxFile.</returns>
public static Task<RobloxFile> OpenAsync(Stream stream)
{
return Task.Run(() => Open(stream));
}
/// <summary>
/// Opens a Roblox file from a provided file path.
/// </summary>
/// <param name="filePath">A path to a Roblox file to be opened.</param>
/// <returns>A task which will complete once the file is opened with the resulting RobloxFile.</returns>
public static Task<RobloxFile> OpenAsync(string filePath)
{
return Task.Run(() => Open(filePath));
}
/// <summary>
/// Saves this RobloxFile to the provided file path.
/// </summary>
/// <param name="filePath">A path to where the file should be saved.</param>
public void Save(string filePath)
{
using (FileStream stream = File.OpenWrite(filePath))
{
Save(stream);
}
}
/// <summary>
/// Asynchronously saves this RobloxFile to the provided stream.
/// </summary>
/// <param name="stream">The stream to save to.</param>
/// <returns>A task which will complete upon the save's completion.</returns>
public Task SaveAsync(Stream stream)
{
return Task.Run(() => Save(stream));
}
/// <summary>
/// Asynchronously saves this RobloxFile to the provided file path.
/// </summary>
/// <param name="filePath">A path to where the file should be saved.</param>
/// <returns>A task which will complete upon the save's completion.</returns>
public Task SaveAsync(string filePath)
{
return Task.Run(() => Save(filePath));
}
/// <summary>
/// Logs an error that occurred while opening a RobloxFile if logs are enabled.
/// </summary>
/// <param name="message"></param>
internal static void LogError(string message)
{
if (!LogErrors)
return;
Console.Error.WriteLine(message);
}
}
}