Skip to content

Instantly share code, notes, and snippets.

@benolee
Created April 26, 2022 02:05
Show Gist options
  • Save benolee/284f66415f85c54528fa9f95a0e20f7b to your computer and use it in GitHub Desktop.
Save benolee/284f66415f85c54528fa9f95a0e20f7b to your computer and use it in GitHub Desktop.
using System;
using System.IO;
using ICSharpCode.SharpZipLib.NotThreadSafe.Zip;
using Sang.Common;
using Sang.Utility;
using Sang.Voxel;
namespace Sang.Map
{
// Token: 0x02000271 RID: 625
internal class VoxelMapData
{
// Token: 0x06000D38 RID: 3384 RVA: 0x000B05D7 File Offset: 0x000AE7D7
private static void InitialzeSaving()
{
VoxelMapData._isSavingInitialized = true;
VoxelMapData._savingMemoryStream = new MemoryStream(4096);
VoxelMapData._savingBinaryWriter = new BinaryWriter(VoxelMapData._savingMemoryStream);
VoxelMapData._savingStaticDataSource = new CustomStaticDataSource();
VoxelMapData._savingStaticDataSource.SetStream(VoxelMapData._savingMemoryStream, false);
}
// Token: 0x06000D39 RID: 3385 RVA: 0x000B0618 File Offset: 0x000AE818
public VoxelMapData(int id)
{
this.ID = id;
this.Data = new VoxelMapCoord[0, 0];
this.OriginX = 0;
this.OriginY = 0;
this.LengthX = 0;
this.LengthY = 0;
this.IsHeaderLoaded = false;
this.IsDataLoaded = false;
this._regionSizeX = 0;
this._regionSizeY = 0;
this._regionCountX = 0;
this._regionCountY = 0;
this._isRegionDirty = new bool[0, 0];
this._isHeaderDirty = false;
this._isRegionCountDecreased = false;
this._isDirty = false;
}
// Token: 0x06000D3A RID: 3386 RVA: 0x000B06A8 File Offset: 0x000AE8A8
public void Clear()
{
if (this.LengthX != 0 || this.LengthY != 0)
{
this.Data = new VoxelMapCoord[0, 0];
}
this.OriginX = 0;
this.OriginY = 0;
this.LengthX = 0;
this.LengthY = 0;
this.IsHeaderLoaded = false;
this.IsDataLoaded = false;
if (this._regionCountX != 0 || this._regionCountY != 0)
{
this._isRegionDirty = new bool[0, 0];
}
this._regionSizeX = 0;
this._regionSizeY = 0;
this._regionCountX = 0;
this._regionCountY = 0;
this._isHeaderDirty = false;
this._isRegionCountDecreased = false;
this._isDirty = false;
}
// Token: 0x06000D3B RID: 3387 RVA: 0x000B074C File Offset: 0x000AE94C
public void SetCoord(int coordX, int coordY, byte typeID, byte height, byte variantIndex, bool isUnderwater)
{
int num = coordX - this.OriginX;
int num2 = coordY - this.OriginY;
this.Data[num, num2].TypeID = typeID;
this.Data[num, num2].Height = height;
this.Data[num, num2].SetVariant(variantIndex);
this.Data[num, num2].SetIsUnderwater(isUnderwater);
this._isRegionDirty[num / this._regionSizeX, num2 / this._regionSizeY] = true;
this._isDirty = true;
}
// Token: 0x06000D3C RID: 3388 RVA: 0x000B07E0 File Offset: 0x000AE9E0
public void ClearCoord(int coordX, int coordY)
{
int num = coordX - this.OriginX;
int num2 = coordY - this.OriginY;
this.Data[num, num2].TypeID = byte.MaxValue;
this.Data[num, num2].Height = 0;
this.Data[num, num2].Params = 0;
this._isRegionDirty[num / this._regionSizeX, num2 / this._regionSizeY] = true;
this._isDirty = true;
}
// Token: 0x06000D3D RID: 3389 RVA: 0x000B0860 File Offset: 0x000AEA60
public void ClearRect(Rect rect)
{
if (rect.Right < this.OriginX || rect.Left >= this.OriginX + this.LengthX || rect.Bottom < this.OriginY || rect.Top >= this.OriginY + this.LengthY)
{
return;
}
for (int i = rect.Left; i <= rect.Right; i++)
{
for (int j = rect.Top; j <= rect.Bottom; j++)
{
if (i - this.OriginX >= 0 && i - this.OriginX < this.LengthX && j - this.OriginY >= 0 && j - this.OriginY < this.LengthY)
{
this.ClearCoord(i, j);
}
}
}
}
// Token: 0x06000D3E RID: 3390 RVA: 0x000B0920 File Offset: 0x000AEB20
public void Resize(int newOriginX, int newOriginY, int newLengthX, int newLengthY)
{
if (this.OriginX != newOriginX || this.OriginY != newOriginY || this.LengthX != newLengthX || this.LengthY != newLengthY)
{
VoxelMapCoord[,] array = new VoxelMapCoord[newLengthX, newLengthY];
for (int i = 0; i < newLengthX; i++)
{
for (int j = 0; j < newLengthY; j++)
{
array[i, j].TypeID = byte.MaxValue;
array[i, j].Height = 0;
array[i, j].Params = 0;
}
}
for (int k = this.OriginX; k < this.OriginX + this.LengthX; k++)
{
for (int l = this.OriginY; l < this.OriginY + this.LengthY; l++)
{
if (k - newOriginX >= 0 && k - newOriginX < newLengthX && l - newOriginY >= 0 && l - newOriginY < newLengthY)
{
array[k - newOriginX, l - newOriginY].TypeID = this.Data[k - this.OriginX, l - this.OriginY].TypeID;
array[k - newOriginX, l - newOriginY].Height = this.Data[k - this.OriginX, l - this.OriginY].Height;
array[k - newOriginX, l - newOriginY].Params = this.Data[k - this.OriginX, l - this.OriginY].Params;
}
}
}
this.Data = array;
this.OriginX = newOriginX;
this.OriginY = newOriginY;
this.LengthX = newLengthX;
this.LengthY = newLengthY;
int region_SIZE_X = CMap.REGION_SIZE_X;
int region_SIZE_Y = CMap.REGION_SIZE_Y;
int num = CMap.ToRegionCount(newLengthX, region_SIZE_X);
int num2 = CMap.ToRegionCount(newLengthY, region_SIZE_Y);
if (this._regionSizeX != region_SIZE_X || this._regionSizeY != region_SIZE_Y || this._regionCountX != num || this._regionCountY != num2)
{
if (num < this._regionCountX || num2 < this._regionCountY)
{
this._isRegionCountDecreased = true;
}
this._regionSizeX = region_SIZE_X;
this._regionSizeY = region_SIZE_Y;
this._regionCountX = num;
this._regionCountY = num2;
this._isRegionDirty = new bool[this._regionCountX, this._regionCountY];
}
for (int m = 0; m < this._regionCountX; m++)
{
for (int n = 0; n < this._regionCountY; n++)
{
this._isRegionDirty[m, n] = true;
}
}
this._isHeaderDirty = true;
this._isDirty = true;
}
}
// Token: 0x06000D3F RID: 3391 RVA: 0x000B0BC8 File Offset: 0x000AEDC8
public void ResizeToFit(int newCoordX, int newCoordY)
{
if (this.LengthX == 0 || this.LengthY == 0)
{
this.OriginX = newCoordX;
this.OriginY = newCoordY;
if (this.OriginX % 8 > 0)
{
this.OriginX = this.OriginX / 8 * 8;
if (newCoordX < 0)
{
this.OriginX -= 8;
}
}
if (this.OriginY % 8 > 0)
{
this.OriginY = this.OriginY / 8 * 8;
if (newCoordY < 0)
{
this.OriginY -= 8;
}
}
this.LengthX = 8;
this.LengthY = 8;
this.Data = new VoxelMapCoord[this.LengthX, this.LengthY];
for (int i = 0; i < this.LengthX; i++)
{
for (int j = 0; j < this.LengthY; j++)
{
this.Data[i, j].TypeID = byte.MaxValue;
this.Data[i, j].Height = 0;
this.Data[i, j].Params = 0;
}
}
this._regionSizeX = CMap.REGION_SIZE_X;
this._regionSizeY = CMap.REGION_SIZE_Y;
this._regionCountX = CMap.ToRegionCount(this.LengthX, this._regionSizeX);
this._regionCountY = CMap.ToRegionCount(this.LengthY, this._regionSizeY);
this._isRegionDirty = new bool[this._regionCountX, this._regionCountY];
for (int k = 0; k < this._regionCountX; k++)
{
for (int l = 0; l < this._regionCountY; l++)
{
this._isRegionDirty[k, l] = true;
}
}
this._isHeaderDirty = true;
this._isDirty = true;
return;
}
int num = this.OriginX;
int num2 = this.OriginY;
int num3 = this.LengthX;
int num4 = this.LengthY;
if (newCoordX < this.OriginX)
{
int num5 = this.OriginX - newCoordX;
if (num5 % 8 > 0)
{
num5 = (num5 / 8 + 1) * 8;
}
num -= num5;
num3 += num5;
}
else if (newCoordX >= this.OriginX + this.LengthX)
{
int num6 = newCoordX - this.OriginX - this.LengthX + 1;
if (num6 % 8 > 0)
{
num6 = (num6 / 8 + 1) * 8;
}
num3 += num6;
}
if (newCoordY < this.OriginY)
{
int num7 = this.OriginY - newCoordY;
if (num7 % 8 > 0)
{
num7 = (num7 / 8 + 1) * 8;
}
num2 -= num7;
num4 += num7;
}
else if (newCoordY >= this.OriginY + this.LengthY)
{
int num8 = newCoordY - this.OriginY - this.LengthY + 1;
if (num8 % 8 > 0)
{
num8 = (num8 / 8 + 1) * 8;
}
num4 += num8;
}
this.Resize(num, num2, num3, num4);
}
// Token: 0x06000D40 RID: 3392 RVA: 0x000B0E7C File Offset: 0x000AF07C
public void Trim(Rect rect)
{
if (this.OriginX >= rect.Left && this.OriginX <= rect.Right)
{
this.TrimLeft();
}
if (this.OriginX + this.LengthX - 1 >= rect.Left && this.OriginX + this.LengthX - 1 <= rect.Right)
{
this.TrimRight();
}
if (this.OriginY >= rect.Top && this.OriginY <= rect.Bottom)
{
this.TrimTop();
}
if (this.OriginY + this.LengthY - 1 >= rect.Top && this.OriginY + this.LengthY - 1 <= rect.Bottom)
{
this.TrimBot();
}
}
// Token: 0x06000D41 RID: 3393 RVA: 0x000B0F38 File Offset: 0x000AF138
public void TrimLeft()
{
bool flag = false;
int num = 0;
for (int i = this.OriginX; i < this.OriginX + this.LengthX; i++)
{
for (int j = this.OriginY; j < this.OriginY + this.LengthY; j++)
{
if (this.Data[i - this.OriginX, j - this.OriginY].TypeID != 255)
{
flag = true;
break;
}
}
if (flag)
{
break;
}
num++;
}
if (num > 0)
{
this.Resize(this.OriginX + num, this.OriginY, this.LengthX - num, this.LengthY);
}
}
// Token: 0x06000D42 RID: 3394 RVA: 0x000B0FDC File Offset: 0x000AF1DC
public void TrimRight()
{
bool flag = false;
int num = 0;
for (int i = this.OriginX + this.LengthX - 1; i >= this.OriginX; i--)
{
for (int j = this.OriginY; j < this.OriginY + this.LengthY; j++)
{
if (this.Data[i - this.OriginX, j - this.OriginY].TypeID != 255)
{
flag = true;
break;
}
}
if (flag)
{
break;
}
num++;
}
if (num > 0)
{
this.Resize(this.OriginX, this.OriginY, this.LengthX - num, this.LengthY);
}
}
// Token: 0x06000D43 RID: 3395 RVA: 0x000B1080 File Offset: 0x000AF280
public void TrimTop()
{
bool flag = false;
int num = 0;
for (int i = this.OriginY; i < this.OriginY + this.LengthY; i++)
{
for (int j = this.OriginX; j < this.OriginX + this.LengthX; j++)
{
if (this.Data[j - this.OriginX, i - this.OriginY].TypeID != 255)
{
flag = true;
break;
}
}
if (flag)
{
break;
}
num++;
}
if (num > 0)
{
this.Resize(this.OriginX, this.OriginY + num, this.LengthX, this.LengthY - num);
}
}
// Token: 0x06000D44 RID: 3396 RVA: 0x000B1124 File Offset: 0x000AF324
public void TrimBot()
{
bool flag = false;
int num = 0;
for (int i = this.OriginY + this.LengthY - 1; i >= this.OriginY; i--)
{
for (int j = this.OriginX; j < this.OriginX + this.LengthX; j++)
{
if (this.Data[j - this.OriginX, i - this.OriginY].TypeID != 255)
{
flag = true;
break;
}
}
if (flag)
{
break;
}
num++;
}
if (num > 0)
{
this.Resize(this.OriginX, this.OriginY, this.LengthX, this.LengthY - num);
}
}
// Token: 0x06000D45 RID: 3397 RVA: 0x000B11C8 File Offset: 0x000AF3C8
public void TrimOutOfBounds(Rect bounds)
{
int num = 0;
int num2 = 0;
int num3 = 0;
int num4 = 0;
if (bounds.Left > this.OriginX)
{
num = bounds.Left - this.OriginX;
}
if (bounds.Right < this.OriginX + this.LengthX)
{
num2 = this.OriginX + this.LengthX - bounds.Right;
}
if (bounds.Top > this.OriginY)
{
num3 = bounds.Top - this.OriginY;
}
if (bounds.Bottom < this.OriginY + this.LengthY)
{
num4 = this.OriginY + this.LengthY - bounds.Bottom;
}
if (num != 0 || num2 != 0 || num3 != 0 || num4 != 0)
{
this.Resize(this.OriginX + num, this.OriginY + num3, this.LengthX - num - num2, this.LengthY - num3 - num4);
}
}
// Token: 0x06000D46 RID: 3398 RVA: 0x000B12A0 File Offset: 0x000AF4A0
public bool Load(int zCacheIndex)
{
if (SangServices.StartupFlags.EnableLoadBinaryWorldData && this.LoadBinary(zCacheIndex))
{
return true;
}
string mapDirectoryPath = VoxelMapData.GetMapDirectoryPath(this.ID, zCacheIndex);
if (Directory.Exists(mapDirectoryPath))
{
string metaDataPath = VoxelMapData.GetMetaDataPath(mapDirectoryPath);
if (File.Exists(metaDataPath))
{
using (BinaryReader binaryReader = new BinaryReader(File.Open(metaDataPath, FileMode.Open, FileAccess.Read)))
{
this.LoadHeaderStream(binaryReader);
goto IL_67;
}
goto IL_5F;
IL_67:
if (this.Data.GetLength(0) != this.LengthX || this.Data.GetLength(1) != this.LengthY)
{
this.Data = new VoxelMapCoord[this.LengthX, this.LengthY];
}
if (this._isRegionDirty.GetLength(0) != this._regionCountX || this._isRegionDirty.GetLength(1) != this._regionCountY)
{
this._isRegionDirty = new bool[this._regionCountX, this._regionCountY];
}
for (int i = 0; i < this._regionCountX; i++)
{
for (int j = 0; j < this._regionCountY; j++)
{
string regionDataPath = VoxelMapData.GetRegionDataPath(mapDirectoryPath, i, j);
if (File.Exists(regionDataPath))
{
using (ZipFile zipFile = new ZipFile(File.Open(regionDataPath, FileMode.Open, FileAccess.Read, FileShare.Read)))
{
ZipEntry entry = zipFile.GetEntry(Path.GetFileName(regionDataPath));
if (entry != null)
{
using (BinaryReader binaryReader2 = new BinaryReader(zipFile.GetInputStream(entry)))
{
this.LoadRegionStream(binaryReader2, i, j);
}
}
}
}
}
}
for (int k = 0; k < this._regionCountX; k++)
{
for (int l = 0; l < this._regionCountY; l++)
{
this._isRegionDirty[k, l] = false;
}
}
this.IsHeaderLoaded = true;
this.IsDataLoaded = true;
this._isHeaderDirty = false;
this._isRegionCountDecreased = false;
this._isDirty = false;
return true;
}
IL_5F:
this.Clear();
return false;
}
this.Clear();
return false;
}
// Token: 0x06000D47 RID: 3399 RVA: 0x000B14BC File Offset: 0x000AF6BC
public bool LoadHeader(int zCacheIndex)
{
if (SangServices.StartupFlags.EnableLoadBinaryWorldData && this.LoadHeaderBinary(zCacheIndex))
{
return true;
}
string mapDirectoryPath = VoxelMapData.GetMapDirectoryPath(this.ID, zCacheIndex);
if (Directory.Exists(mapDirectoryPath))
{
string metaDataPath = VoxelMapData.GetMetaDataPath(mapDirectoryPath);
if (File.Exists(metaDataPath))
{
using (BinaryReader binaryReader = new BinaryReader(File.Open(metaDataPath, FileMode.Open, FileAccess.Read)))
{
this.LoadHeaderStream(binaryReader);
this.IsHeaderLoaded = true;
return true;
}
}
this.Clear();
return false;
}
this.Clear();
return false;
}
// Token: 0x06000D48 RID: 3400 RVA: 0x000B1550 File Offset: 0x000AF750
private bool LoadBinary(int zCacheIndex)
{
string worldBinaryPath = VoxelMapData.GetWorldBinaryPath(zCacheIndex);
if (File.Exists(worldBinaryPath))
{
using (ZipFile zipFile = new ZipFile(File.Open(worldBinaryPath, FileMode.Open, FileAccess.Read, FileShare.Read)))
{
ZipEntry entry = zipFile.GetEntry(VoxelMapData.GetMetaDataZipEntry(this.ID));
if (entry != null)
{
using (BinaryReader binaryReader = new BinaryReader(zipFile.GetInputStream(entry)))
{
this.LoadHeaderStream(binaryReader);
goto IL_64;
}
goto IL_56;
IL_64:
if (this.Data.GetLength(0) != this.LengthX || this.Data.GetLength(1) != this.LengthY)
{
this.Data = new VoxelMapCoord[this.LengthX, this.LengthY];
}
if (this._isRegionDirty.GetLength(0) != this._regionCountX || this._isRegionDirty.GetLength(1) != this._regionCountY)
{
this._isRegionDirty = new bool[this._regionCountX, this._regionCountY];
}
for (int i = 0; i < this._regionCountX; i++)
{
for (int j = 0; j < this._regionCountY; j++)
{
entry = zipFile.GetEntry(VoxelMapData.GetRegionDataZipEntry(this.ID, i, j));
if (entry != null)
{
using (BinaryReader binaryReader2 = new BinaryReader(zipFile.GetInputStream(entry)))
{
this.LoadRegionStream(binaryReader2, i, j);
}
}
}
}
for (int k = 0; k < this._regionCountX; k++)
{
for (int l = 0; l < this._regionCountY; l++)
{
this._isRegionDirty[k, l] = false;
}
}
this.IsHeaderLoaded = true;
this.IsDataLoaded = true;
this._isHeaderDirty = false;
this._isRegionCountDecreased = false;
this._isDirty = false;
return true;
}
IL_56:
this.Clear();
return false;
}
}
this.Clear();
return false;
}
// Token: 0x06000D49 RID: 3401 RVA: 0x000B176C File Offset: 0x000AF96C
private bool LoadHeaderBinary(int zCacheIndex)
{
string worldBinaryPath = VoxelMapData.GetWorldBinaryPath(zCacheIndex);
if (File.Exists(worldBinaryPath))
{
using (ZipFile zipFile = new ZipFile(File.Open(worldBinaryPath, FileMode.Open, FileAccess.Read, FileShare.Read)))
{
ZipEntry entry = zipFile.GetEntry(VoxelMapData.GetMetaDataZipEntry(this.ID));
if (entry != null)
{
using (BinaryReader binaryReader = new BinaryReader(zipFile.GetInputStream(entry)))
{
this.LoadHeaderStream(binaryReader);
this.IsHeaderLoaded = true;
return true;
}
}
this.Clear();
return false;
}
}
this.Clear();
return false;
}
// Token: 0x06000D4A RID: 3402 RVA: 0x000B1814 File Offset: 0x000AFA14
private void LoadHeaderStream(BinaryReader binaryReader)
{
if (binaryReader.ReadByte() > 2)
{
throw new InvalidDataException("Error reading map data: map data is not forwards compatible.");
}
binaryReader.ReadInt32();
this.OriginX = binaryReader.ReadInt32();
this.OriginY = binaryReader.ReadInt32();
this.LengthX = binaryReader.ReadInt32();
this.LengthY = binaryReader.ReadInt32();
this._regionSizeX = binaryReader.ReadInt32();
this._regionSizeY = binaryReader.ReadInt32();
this._regionCountX = binaryReader.ReadInt32();
this._regionCountY = binaryReader.ReadInt32();
}
// Token: 0x06000D4B RID: 3403 RVA: 0x000B189C File Offset: 0x000AFA9C
private void LoadRegionStream(BinaryReader binaryReader, int regionX, int regionY)
{
if (binaryReader.ReadByte() > 2)
{
throw new InvalidDataException("Error reading map data: map data is not forwards compatible.");
}
int num = regionX * this._regionSizeX;
int num2 = (regionX + 1) * this._regionSizeX;
if (num2 > this.LengthX)
{
num2 = this.LengthX;
}
int num3 = regionY * this._regionSizeY;
int num4 = (regionY + 1) * this._regionSizeY;
if (num4 > this.LengthY)
{
num4 = this.LengthY;
}
for (int i = num; i < num2; i++)
{
for (int j = num3; j < num4; j++)
{
this.Data[i, j].TypeID = binaryReader.ReadByte();
this.Data[i, j].Height = binaryReader.ReadByte();
this.Data[i, j].Params = binaryReader.ReadByte();
}
}
}
// Token: 0x06000D4C RID: 3404 RVA: 0x000B196C File Offset: 0x000AFB6C
public bool Save(int zCacheIndex, bool returnAfterOneRegion)
{
if (!this._isDirty)
{
return false;
}
if (!VoxelMapData._isSavingInitialized)
{
VoxelMapData.InitialzeSaving();
}
string mapDirectoryPath = VoxelMapData.GetMapDirectoryPath(this.ID, zCacheIndex);
if (!Directory.Exists(mapDirectoryPath))
{
Directory.CreateDirectory(mapDirectoryPath);
}
if (this._isHeaderDirty)
{
using (BinaryWriter binaryWriter = new BinaryWriter(File.Open(VoxelMapData.GetMetaDataPath(mapDirectoryPath), FileMode.Create, FileAccess.Write)))
{
this.SaveHeaderStream(binaryWriter);
}
this._isHeaderDirty = false;
}
for (int i = 0; i < this._regionCountX; i++)
{
for (int j = 0; j < this._regionCountY; j++)
{
if (this._isRegionDirty[i, j])
{
string regionDataPath = VoxelMapData.GetRegionDataPath(mapDirectoryPath, i, j);
using (ZipFile orCreateZipFile = VoxelMapData.GetOrCreateZipFile(regionDataPath))
{
orCreateZipFile.BeginUpdate(new DiskArchiveStorage(orCreateZipFile, FileUpdateMode.Direct), new DynamicDiskDataSource());
VoxelMapData._savingMemoryStream.Position = 0L;
VoxelMapData._savingMemoryStream.SetLength(0L);
this.SaveRegionStream(VoxelMapData._savingBinaryWriter, i, j);
VoxelMapData._savingBinaryWriter.Flush();
VoxelMapData._savingMemoryStream.Position = 0L;
orCreateZipFile.Add(VoxelMapData._savingStaticDataSource, Path.GetFileName(regionDataPath));
orCreateZipFile.CommitUpdate();
}
this._isRegionDirty[i, j] = false;
if (returnAfterOneRegion)
{
return true;
}
}
}
}
if (this._isRegionCountDecreased)
{
this.DeleteOutOfBoundsRegions(zCacheIndex);
this._isRegionCountDecreased = false;
}
this._isDirty = false;
return false;
}
// Token: 0x06000D4D RID: 3405 RVA: 0x000B1AF8 File Offset: 0x000AFCF8
private void SaveHeaderStream(BinaryWriter binaryWriter)
{
binaryWriter.Write(2);
binaryWriter.Write(this.ID);
binaryWriter.Write(this.OriginX);
binaryWriter.Write(this.OriginY);
binaryWriter.Write(this.LengthX);
binaryWriter.Write(this.LengthY);
binaryWriter.Write(this._regionSizeX);
binaryWriter.Write(this._regionSizeY);
binaryWriter.Write(this._regionCountX);
binaryWriter.Write(this._regionCountY);
}
// Token: 0x06000D4E RID: 3406 RVA: 0x000B1B78 File Offset: 0x000AFD78
private void SaveRegionStream(BinaryWriter binaryWriter, int regionX, int regionY)
{
binaryWriter.Write(2);
int num = regionX * this._regionSizeX;
int num2 = (regionX + 1) * this._regionSizeX;
if (num2 > this.LengthX)
{
num2 = this.LengthX;
}
int num3 = regionY * this._regionSizeY;
int num4 = (regionY + 1) * this._regionSizeY;
if (num4 > this.LengthY)
{
num4 = this.LengthY;
}
for (int i = num; i < num2; i++)
{
for (int j = num3; j < num4; j++)
{
binaryWriter.Write(this.Data[i, j].TypeID);
binaryWriter.Write(this.Data[i, j].Height);
binaryWriter.Write(this.Data[i, j].Params);
}
}
}
// Token: 0x06000D4F RID: 3407 RVA: 0x000B1C3C File Offset: 0x000AFE3C
private void DeleteOutOfBoundsRegions(int zCacheIndex)
{
string[] files = Directory.GetFiles(VoxelMapData.GetMapDirectoryPath(this.ID, zCacheIndex), "region*");
for (int i = 0; i < files.Length; i++)
{
string[] array = Path.GetFileNameWithoutExtension(files[i]).Substring(7).Split(new char[]
{
'_'
});
int num = int.Parse(array[0]);
int num2 = int.Parse(array[1]);
if (num >= this._regionCountX || num2 >= this._regionCountY)
{
File.Delete(files[i]);
}
}
}
// Token: 0x06000D50 RID: 3408 RVA: 0x000B1CB8 File Offset: 0x000AFEB8
private static string GetMapDirectoryPath(int id, int zCacheIndex)
{
if (id == -1)
{
return "Content/Worlds/" + ZCache.Inst[zCacheIndex].GetWorldName() + "/map/map_world/";
}
return string.Concat(new string[]
{
"Content/Worlds/",
ZCache.Inst[zCacheIndex].GetWorldName(),
"/map/map_biome",
id.ToString(),
"/"
});
}
// Token: 0x06000D51 RID: 3409 RVA: 0x000B1D21 File Offset: 0x000AFF21
private static string GetMetaDataPath(string mapDirectoryPath)
{
return mapDirectoryPath + "meta.dat";
}
// Token: 0x06000D52 RID: 3410 RVA: 0x000B1D2E File Offset: 0x000AFF2E
private static string GetRegionDataPath(string mapDirectoryPath, int regionX, int regionY)
{
return string.Concat(new string[]
{
mapDirectoryPath,
"region_",
regionX.ToString(),
"_",
regionY.ToString(),
".dat"
});
}
// Token: 0x06000D53 RID: 3411 RVA: 0x000B1D6B File Offset: 0x000AFF6B
private static ZipFile GetOrCreateZipFile(string path)
{
if (!File.Exists(path))
{
return ZipFile.Create(path);
}
return new ZipFile(File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
}
// Token: 0x06000D54 RID: 3412 RVA: 0x000B1D8A File Offset: 0x000AFF8A
private static string GetWorldBinaryPath(int zCacheIndex)
{
return "Content/Worlds/" + ZCache.Inst[zCacheIndex].GetWorldName() + ".dat";
}
// Token: 0x06000D55 RID: 3413 RVA: 0x000B1DA7 File Offset: 0x000AFFA7
private static string GetMetaDataZipEntry(int id)
{
if (id == -1)
{
return "map/map_world/meta.dat";
}
return "map/map_biome" + id.ToString() + "/meta.dat";
}
// Token: 0x06000D56 RID: 3414 RVA: 0x000B1DCC File Offset: 0x000AFFCC
private static string GetRegionDataZipEntry(int id, int regionX, int regionY)
{
if (id == -1)
{
return string.Concat(new string[]
{
"map/map_world/region_",
regionX.ToString(),
"_",
regionY.ToString(),
".dat"
});
}
return string.Concat(new string[]
{
"map/map_biome",
id.ToString(),
"/region_",
regionX.ToString(),
"_",
regionY.ToString(),
".dat"
});
}
// Token: 0x04002146 RID: 8518
private static bool _isSavingInitialized;
// Token: 0x04002147 RID: 8519
private static MemoryStream _savingMemoryStream;
// Token: 0x04002148 RID: 8520
private static BinaryWriter _savingBinaryWriter;
// Token: 0x04002149 RID: 8521
private static CustomStaticDataSource _savingStaticDataSource;
// Token: 0x0400214A RID: 8522
public readonly int ID;
// Token: 0x0400214B RID: 8523
public VoxelMapCoord[,] Data;
// Token: 0x0400214C RID: 8524
public int OriginX;
// Token: 0x0400214D RID: 8525
public int OriginY;
// Token: 0x0400214E RID: 8526
public int LengthX;
// Token: 0x0400214F RID: 8527
public int LengthY;
// Token: 0x04002150 RID: 8528
public bool IsHeaderLoaded;
// Token: 0x04002151 RID: 8529
public bool IsDataLoaded;
// Token: 0x04002152 RID: 8530
private int _regionSizeX;
// Token: 0x04002153 RID: 8531
private int _regionSizeY;
// Token: 0x04002154 RID: 8532
private int _regionCountX;
// Token: 0x04002155 RID: 8533
private int _regionCountY;
// Token: 0x04002156 RID: 8534
private bool[,] _isRegionDirty;
// Token: 0x04002157 RID: 8535
private bool _isHeaderDirty;
// Token: 0x04002158 RID: 8536
private bool _isRegionCountDecreased;
// Token: 0x04002159 RID: 8537
private bool _isDirty;
}
}
using System;
using System.IO;
using ICSharpCode.SharpZipLib.NotThreadSafe.Zip;
using Microsoft.Xna.Framework;
using Sang.Utility;
namespace Sang.Voxel
{
// Token: 0x02000106 RID: 262
internal class ZCache
{
// Token: 0x06000909 RID: 2313 RVA: 0x0006CDD8 File Offset: 0x0006AFD8
public static void Register(int index, string worldName)
{
if (ZCache.Inst == null)
{
ZCache.Inst = new ZCache[index + 1];
}
else if (ZCache.Inst.Length <= index)
{
ZCache[] inst = ZCache.Inst;
ZCache.Inst = new ZCache[index + 1];
for (int i = 0; i < inst.Length; i++)
{
ZCache.Inst[i] = inst[i];
}
}
ZCache.Inst[index] = new ZCache(worldName);
}
// Token: 0x0600090A RID: 2314 RVA: 0x0006CE40 File Offset: 0x0006B040
public static void ClearAll()
{
for (int i = 0; i < ZCache.Inst.Length; i++)
{
ZCache.Inst[i].Clear();
}
}
// Token: 0x0600090B RID: 2315 RVA: 0x0006CE6B File Offset: 0x0006B06B
private ZCache(string worldName)
{
this._worldName = worldName;
}
// Token: 0x0600090C RID: 2316 RVA: 0x0006CE7A File Offset: 0x0006B07A
public string GetWorldName()
{
return this._worldName;
}
// Token: 0x0600090D RID: 2317 RVA: 0x0006CE84 File Offset: 0x0006B084
public void Reserve()
{
FileInfo[] files = new DirectoryInfo("Content/Worlds/" + this._worldName + "/voxel").GetFiles("*.*", SearchOption.AllDirectories);
int num = 0;
int num2 = 0;
for (int i = 0; i < files.Length; i++)
{
num += (int)files[i].Length;
num2++;
}
this.Reserve(num, num2);
}
// Token: 0x0600090E RID: 2318 RVA: 0x0006CEE1 File Offset: 0x0006B0E1
public void Reserve(int maxByteCount, int maxEntryCount)
{
if (this._zLookup == null)
{
this._zLookup = new ZLookup();
}
this._zLookup.Reserve(maxByteCount, maxEntryCount);
}
// Token: 0x0600090F RID: 2319 RVA: 0x0006CF03 File Offset: 0x0006B103
public void Clear()
{
if (this._zLookup != null)
{
this._zLookup.Clear();
}
}
// Token: 0x06000910 RID: 2320 RVA: 0x0006CF18 File Offset: 0x0006B118
public bool TryLoadBinary()
{
if (!SangServices.StartupFlags.EnableLoadBinaryWorldData)
{
return false;
}
string path = "Content/Worlds/" + this._worldName + ".dat";
if (!File.Exists(path))
{
return false;
}
if (this._zLookup == null)
{
this._zLookup = new ZLookup();
}
else
{
this.Clear();
}
using (FileStream fileStream = File.Open(path, FileMode.Open, FileAccess.Read))
{
BinaryReader binaryReader = new BinaryReader(fileStream);
byte b = binaryReader.ReadByte();
bool flag = binaryReader.ReadBoolean();
if (b != 1 || flag)
{
throw new InvalidDataException("Error reading world data: incompatible version.");
}
using (ZipFile zipFile = new ZipFile(new PartialStream(fileStream, (long)((int)fileStream.Position), (long)((int)(fileStream.Length - fileStream.Position)))))
{
ZipEntry entry = zipFile.GetEntry(Path.GetFileName(path));
using (BinaryReader binaryReader2 = new BinaryReader(zipFile.GetInputStream(entry)))
{
this._zLookup.LoadBinary(binaryReader2);
}
}
}
return true;
}
// Token: 0x06000911 RID: 2321 RVA: 0x0006D03C File Offset: 0x0006B23C
public ZipFile GetCachedZipFile(int globalIndexX, int globalIndexZ)
{
if (this._cachedZipFile == null || this._cachedZipFileX != globalIndexX || this._cachedZipFileZ != globalIndexZ)
{
if (this._cachedZipFile != null)
{
this._cachedZipFile.Close();
this._cachedZipFile = null;
}
MemoryStream cachedStream = this.GetCachedStream(globalIndexX, globalIndexZ);
if (cachedStream != null)
{
this._cachedZipFile = new ZipFile(cachedStream);
this._cachedZipFile.IsStreamOwner = false;
this._cachedZipFileX = globalIndexX;
this._cachedZipFileZ = globalIndexZ;
}
}
return this._cachedZipFile;
}
// Token: 0x06000912 RID: 2322 RVA: 0x0006D0B8 File Offset: 0x0006B2B8
public ZipFile GetOrCreatePhysicalZipFile(int globalIndexX, int globalIndexZ)
{
this.ClearCachedZipFile(globalIndexX, globalIndexZ);
string zipFilePath = this.GetZipFilePath(globalIndexX, globalIndexZ);
ZipFile result;
if (!File.Exists(zipFilePath))
{
result = ZipFile.Create(zipFilePath);
}
else
{
result = new ZipFile(File.Open(zipFilePath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite));
}
return result;
}
// Token: 0x06000913 RID: 2323 RVA: 0x0006D0F8 File Offset: 0x0006B2F8
public void ClearCachedZipFile(int globalIndexX, int globalIndexZ)
{
if (this._cachedZipFile != null && this._cachedZipFileX == globalIndexX && this._cachedZipFileZ == globalIndexZ)
{
this._cachedZipFile.Close();
this._cachedZipFile = null;
}
Point point;
point.X = globalIndexX;
point.Y = globalIndexZ;
if (this._zLookup.Dict.ContainsKey(point))
{
this._zLookup.Free(point);
}
}
// Token: 0x06000914 RID: 2324 RVA: 0x0006D164 File Offset: 0x0006B364
public MemoryStream GetCachedStream(int globalIndexX, int globalIndexZ)
{
Point point;
point.X = globalIndexX;
point.Y = globalIndexZ;
if (!this._zLookup.Dict.ContainsKey(point) && !this.StoreZipFileBytes(globalIndexX, globalIndexZ))
{
return null;
}
return this._zLookup.Read(point);
}
// Token: 0x06000915 RID: 2325 RVA: 0x0006D1AC File Offset: 0x0006B3AC
private bool StoreZipFileBytes(int globalIndexX, int globalIndexZ)
{
string zipFilePath = this.GetZipFilePath(globalIndexX, globalIndexZ);
if (!File.Exists(zipFilePath))
{
return false;
}
using (FileStream fileStream = File.Open(zipFilePath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
Point zIndex;
zIndex.X = globalIndexX;
zIndex.Y = globalIndexZ;
int num = (int)fileStream.Length;
int num2 = this._zLookup.Reserve(zIndex, num);
if (num2 == -1)
{
throw new InvalidOperationException("Fatal error: Unable to store zip file bytes.");
}
fileStream.Read(this._zLookup.Data, num2, num);
}
return true;
}
// Token: 0x06000916 RID: 2326 RVA: 0x0006D240 File Offset: 0x0006B440
private string GetZipFilePath(int globalIndexX, int globalIndexZ)
{
string text = "Content/Worlds/";
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
text = text + this._worldName + "/";
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
text += "voxel/";
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
text = text + "x" + globalIndexX.ToString() + "/";
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
return text + "z" + globalIndexZ.ToString() + ".zip";
}
// Token: 0x04000AD8 RID: 2776
public const int ZCACHE_INDEX_FIELD = 0;
// Token: 0x04000AD9 RID: 2777
public const int ZCACHE_INDEX_ARENA = 1;
// Token: 0x04000ADA RID: 2778
public const int ZCACHE_INDEX_TITLE = 2;
// Token: 0x04000ADB RID: 2779
public static ZCache[] Inst;
// Token: 0x04000ADC RID: 2780
private string _worldName;
// Token: 0x04000ADD RID: 2781
private ZLookup _zLookup;
// Token: 0x04000ADE RID: 2782
private ZipFile _cachedZipFile;
// Token: 0x04000ADF RID: 2783
private int _cachedZipFileX;
// Token: 0x04000AE0 RID: 2784
private int _cachedZipFileZ;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment