servuo/Server/TileMatrixPatch.cs
VitaNex f840e50340 Updated .editorconfig file with advanced configuration settings that will help maintain user code style and best practices with most IDE's.
Complete core housekeeping operation using "Profile 1" with new .editorconfig settings.
2021-01-15 12:51:10 -08:00

188 lines
4.7 KiB
C#

#region References
using System.IO;
using System.Runtime.CompilerServices;
#endregion
namespace Server
{
public class TileMatrixPatch
{
private readonly int m_LandBlocks;
private readonly int m_StaticBlocks;
private static bool m_Enabled = true;
public static bool Enabled { get => m_Enabled; set => m_Enabled = value; }
public int LandBlocks
{
get
{
lock (this)
return m_LandBlocks;
}
}
public int StaticBlocks
{
get
{
lock (this)
return m_StaticBlocks;
}
}
public TileMatrixPatch(TileMatrix matrix, int index)
{
if (!m_Enabled)
{
return;
}
var mapDataPath = Core.FindDataFile("mapdif{0}.mul", index);
var mapIndexPath = Core.FindDataFile("mapdifl{0}.mul", index);
if (File.Exists(mapDataPath) && File.Exists(mapIndexPath))
{
m_LandBlocks = PatchLand(matrix, mapDataPath, mapIndexPath);
}
var staDataPath = Core.FindDataFile("stadif{0}.mul", index);
var staIndexPath = Core.FindDataFile("stadifl{0}.mul", index);
var staLookupPath = Core.FindDataFile("stadifi{0}.mul", index);
if (File.Exists(staDataPath) && File.Exists(staIndexPath) && File.Exists(staLookupPath))
{
m_StaticBlocks = PatchStatics(matrix, staDataPath, staIndexPath, staLookupPath);
}
}
[MethodImpl(MethodImplOptions.Synchronized)]
private unsafe int PatchLand(TileMatrix matrix, string dataPath, string indexPath)
{
using (var fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var indexReader = new BinaryReader(fsIndex);
var count = (int)(indexReader.BaseStream.Length / 4);
for (var i = 0; i < count; ++i)
{
var blockID = indexReader.ReadInt32();
var x = blockID / matrix.BlockHeight;
var y = blockID % matrix.BlockHeight;
fsData.Seek(4, SeekOrigin.Current);
var tiles = new LandTile[64];
fixed (LandTile* pTiles = tiles)
{
NativeReader.Read(fsData, pTiles, 192);
}
matrix.SetLandBlock(x, y, tiles);
}
indexReader.Close();
return count;
}
}
}
private StaticTile[] m_TileBuffer = new StaticTile[128];
[MethodImpl(MethodImplOptions.Synchronized)]
private unsafe int PatchStatics(TileMatrix matrix, string dataPath, string indexPath, string lookupPath)
{
using (var fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (var fsLookup = new FileStream(lookupPath, FileMode.Open, FileAccess.Read, FileShare.Read))
{
var indexReader = new BinaryReader(fsIndex);
var lookupReader = new BinaryReader(fsLookup);
var count = (int)(indexReader.BaseStream.Length / 4);
var lists = new TileList[8][];
for (var x = 0; x < 8; ++x)
{
lists[x] = new TileList[8];
for (var y = 0; y < 8; ++y)
{
lists[x][y] = new TileList();
}
}
for (var i = 0; i < count; ++i)
{
var blockID = indexReader.ReadInt32();
var blockX = blockID / matrix.BlockHeight;
var blockY = blockID % matrix.BlockHeight;
var offset = lookupReader.ReadInt32();
var length = lookupReader.ReadInt32();
lookupReader.ReadInt32(); // Extra
if (offset < 0 || length <= 0)
{
matrix.SetStaticBlock(blockX, blockY, matrix.EmptyStaticBlock);
continue;
}
fsData.Seek(offset, SeekOrigin.Begin);
var tileCount = length / 7;
if (m_TileBuffer.Length < tileCount)
{
m_TileBuffer = new StaticTile[tileCount];
}
var staTiles = m_TileBuffer;
fixed (StaticTile* pTiles = staTiles)
{
NativeReader.Read(fsData, pTiles, length);
StaticTile* pCur = pTiles, pEnd = pTiles + tileCount;
while (pCur < pEnd)
{
lists[pCur->m_X & 0x7][pCur->m_Y & 0x7].Add(pCur->m_ID, pCur->m_Z);
pCur = pCur + 1;
}
var tiles = new StaticTile[8][][];
for (var x = 0; x < 8; ++x)
{
tiles[x] = new StaticTile[8][];
for (var y = 0; y < 8; ++y)
{
tiles[x][y] = lists[x][y].ToArray();
}
}
matrix.SetStaticBlock(blockX, blockY, tiles);
}
}
indexReader.Close();
lookupReader.Close();
return count;
}
}
}
}
}
}