Survivalcraft API 1.8.2.3 v1.8.2.3
Survivalcraft 2.4
载入中...
搜索中...
未找到
TerrainSerializer22.cs
浏览该文件的文档.
1using Engine;
2
3namespace Game {
4 public class TerrainSerializer22 : IDisposable {
5 public const int MaxChunks = 65536;
6
7 public const int TocEntryBytesCount = 12;
8
9 public const int TocBytesCount = 786444;
10
11 public const int ChunkSizeX = 16;
12
13 public const int ChunkSizeY = 256;
14
15 public const int ChunkSizeZ = 16;
16
17 public const int ChunkBitsX = 4;
18
19 public const int ChunkBitsZ = 4;
20
21 public const int ChunkBytesCount = 263184;
22
23 public const string ChunksFileName = "Chunks32h.dat";
24
26
27 public byte[] m_buffer = new byte[262144];
28
29 public Dictionary<Point2, long> m_chunkOffsets = [];
30
31 public IEnumerable<Point2> Chunks => m_chunkOffsets.Keys;
32
33 public Stream m_stream;
34
35 public TerrainSerializer22(Terrain terrain, string directoryName) {
36 m_terrain = terrain;
37 string path = Storage.CombinePaths(directoryName, "Chunks32h.dat");
38 if (!Storage.FileExists(path)) {
39 using (Stream stream = Storage.OpenFile(path, OpenFileMode.Create)) {
40 for (int i = 0; i < 65537; i++) {
41 WriteTOCEntry(stream, 0, 0, -1);
42 }
43 }
44 }
45 m_stream = Storage.OpenFile(path, OpenFileMode.ReadWrite);
46 while (true) {
47 ReadTOCEntry(m_stream, out int cx, out int cz, out int index);
48 if (index >= 0) {
49 m_chunkOffsets[new Point2(cx, cz)] = 786444 + 263184L * index;
50 continue;
51 }
52 break;
53 }
54 }
55
56 public bool LoadChunk(TerrainChunk chunk) => LoadChunkBlocks(chunk);
57
58 public void SaveChunk(TerrainChunk chunk) {
59 if (chunk.State > TerrainChunkState.InvalidContents4
60 && chunk.ModificationCounter > 0) {
61 SaveChunkBlocks(chunk);
62 chunk.ModificationCounter = 0;
63 }
64 }
65
66 public void Dispose() {
67 Utilities.Dispose(ref m_stream);
68 }
69
70 public static void ReadChunkHeader(Stream stream) {
71 int num = ReadInt(stream);
72 int num2 = ReadInt(stream);
73 ReadInt(stream);
74 ReadInt(stream);
75 if (num != -559038737
76 || num2 != -2) {
77 throw new InvalidOperationException("Invalid chunk header.");
78 }
79 }
80
81 public static void WriteChunkHeader(Stream stream, int cx, int cz) {
82 WriteInt(stream, -559038737);
83 WriteInt(stream, -2);
84 WriteInt(stream, cx);
85 WriteInt(stream, cz);
86 }
87
88 public static void ReadTOCEntry(Stream stream, out int cx, out int cz, out int index) {
89 cx = ReadInt(stream);
90 cz = ReadInt(stream);
91 index = ReadInt(stream);
92 }
93
94 public static void WriteTOCEntry(Stream stream, int cx, int cz, int index) {
95 WriteInt(stream, cx);
96 WriteInt(stream, cz);
97 WriteInt(stream, index);
98 }
99
101 bool result = false;
102 int num = chunk.Origin.X >> 4;
103 int num2 = chunk.Origin.Y >> 4;
104 try {
105 if (m_chunkOffsets.TryGetValue(new Point2(num, num2), out long value)) {
106 _ = Time.RealTime;
107 m_stream.Seek(value, SeekOrigin.Begin);
109 m_stream.ReadExactly(m_buffer, 0, 262144);
110 fixed (byte* ptr = &m_buffer[0]) {
111 int* ptr2 = (int*)ptr;
112 for (int i = 0; i < 16; i++) {
113 for (int j = 0; j < 16; j++) {
114 int num3 = TerrainChunk.CalculateCellIndex(i, 0, j);
115 int num4 = 0;
116 while (num4 < 256) {
117 chunk.SetCellValueFast(num3, *ptr2);
118 num4++;
119 num3++;
120 ptr2++;
121 }
122 }
123 }
124 }
125 m_stream.ReadExactly(m_buffer, 0, 1024);
126 fixed (byte* ptr3 = &m_buffer[0]) {
127 int* ptr4 = (int*)ptr3;
128 for (int k = 0; k < 16; k++) {
129 for (int l = 0; l < 16; l++) {
130 chunk.SetShaftValueFast(k, l, *ptr4);
131 ptr4++;
132 }
133 }
134 }
135 result = true;
136 _ = Time.RealTime;
137 }
138 return result;
139 }
140 catch (Exception e) {
141 Log.Error(ExceptionManager.MakeFullErrorMessage($"Error loading data for chunk ({num},{num2}).", e));
142 return result;
143 }
144 }
145
147 _ = Time.RealTime;
148 int num = chunk.Origin.X >> 4;
149 int num2 = chunk.Origin.Y >> 4;
150 try {
151 bool flag = false;
152 if (m_chunkOffsets.TryGetValue(new Point2(num, num2), out long value)) {
153 m_stream.Seek(value, SeekOrigin.Begin);
154 }
155 else {
156 flag = true;
157 value = m_stream.Length;
158 m_stream.Seek(value, SeekOrigin.Begin);
159 }
160 WriteChunkHeader(m_stream, num, num2);
161 fixed (byte* ptr = &m_buffer[0]) {
162 int* ptr2 = (int*)ptr;
163 for (int i = 0; i < 16; i++) {
164 for (int j = 0; j < 16; j++) {
165 int num3 = TerrainChunk.CalculateCellIndex(i, 0, j);
166 int num4 = 0;
167 while (num4 < 256) {
168 *ptr2 = chunk.GetCellValueFast(num3);
169 num4++;
170 num3++;
171 ptr2++;
172 }
173 }
174 }
175 }
176 m_stream.Write(m_buffer, 0, 262144);
177 fixed (byte* ptr3 = &m_buffer[0]) {
178 int* ptr4 = (int*)ptr3;
179 for (int k = 0; k < 16; k++) {
180 for (int l = 0; l < 16; l++) {
181 *ptr4 = chunk.GetShaftValueFast(k, l);
182 ptr4++;
183 }
184 }
185 }
186 m_stream.Write(m_buffer, 0, 1024);
187 if (flag) {
188 m_stream.Flush();
189 int num5 = m_chunkOffsets.Count % 65536 * 3 * 4;
190 m_stream.Seek(num5, SeekOrigin.Begin);
191 WriteInt(m_stream, num);
192 WriteInt(m_stream, num2);
194 m_chunkOffsets[new Point2(num, num2)] = value;
195 }
196 m_stream.Flush();
197 }
198 catch (Exception e) {
199 Log.Error(ExceptionManager.MakeFullErrorMessage($"Error writing data for chunk ({num},{num2}).", e));
200 }
201 _ = Time.RealTime;
202 }
203
204 public static int ReadInt(Stream stream) =>
205 stream.ReadByte() + (stream.ReadByte() << 8) + (stream.ReadByte() << 16) + (stream.ReadByte() << 24);
206
207 public static void WriteInt(Stream stream, int value) {
208 stream.WriteByte((byte)value);
209 stream.WriteByte((byte)(value >> 8));
210 stream.WriteByte((byte)(value >> 16));
211 stream.WriteByte((byte)(value >> 24));
212 }
213 }
214}
unsafe
定义 Main.cs:15
static void Error(object message)
定义 Log.cs:80
static Stream OpenFile(string path, OpenFileMode openFileMode)
static bool FileExists(string path)
static string CombinePaths(params string[] paths)
static double RealTime
定义 Time.cs:38
static string MakeFullErrorMessage(Exception e)
static int CalculateCellIndex(int x, int y, int z)
virtual void SetShaftValueFast(int x, int z, int value)
TerrainChunkState State
virtual int GetCellValueFast(int index)
virtual void SetCellValueFast(int x, int y, int z, int value)
virtual int GetShaftValueFast(int x, int z)
static void WriteChunkHeader(Stream stream, int cx, int cz)
bool LoadChunk(TerrainChunk chunk)
unsafe bool LoadChunkBlocks(TerrainChunk chunk)
static int ReadInt(Stream stream)
static void WriteInt(Stream stream, int value)
TerrainSerializer22(Terrain terrain, string directoryName)
static void WriteTOCEntry(Stream stream, int cx, int cz, int index)
unsafe void SaveChunkBlocks(TerrainChunk chunk)
void SaveChunk(TerrainChunk chunk)
static void ReadTOCEntry(Stream stream, out int cx, out int cz, out int index)
Dictionary< Point2, long > m_chunkOffsets
static void ReadChunkHeader(Stream stream)