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