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