private unsafe int PatchLand( TileMatrix matrix, string dataPath, string indexPath ) { using ( FileStream fsData = new FileStream( dataPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { using ( FileStream fsIndex = new FileStream( indexPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { BinaryReader indexReader = new BinaryReader( fsIndex ); int count = (int)(indexReader.BaseStream.Length / 4); for ( int i = 0; i < count; ++i ) { int blockID = indexReader.ReadInt32(); int x = blockID / matrix.BlockHeight; int y = blockID % matrix.BlockHeight; fsData.Seek( 4, SeekOrigin.Current ); LandTile[] tiles = new LandTile[64]; fixed ( LandTile *pTiles = tiles ) { NativeReader.Read( fsData.SafeFileHandle.DangerousGetHandle(), pTiles, 192 ); } matrix.SetLandBlock( x, y, tiles ); } indexReader.Close(); return count; } } }
public TileMatrixPatch( TileMatrix matrix, int index ) { if ( !m_Enabled ) return; string mapDataPath = Core.FindDataFile( "mapdif{0}.mul", index ); string mapIndexPath = Core.FindDataFile( "mapdifl{0}.mul", index ); if ( File.Exists( mapDataPath ) && File.Exists( mapIndexPath ) ) m_LandBlocks = PatchLand( matrix, mapDataPath, mapIndexPath ); string staDataPath = Core.FindDataFile( "stadif{0}.mul", index ); string staIndexPath = Core.FindDataFile( "stadifl{0}.mul", index ); string staLookupPath = Core.FindDataFile( "stadifi{0}.mul", index ); if ( File.Exists( staDataPath ) && File.Exists( staIndexPath ) && File.Exists( staLookupPath ) ) m_StaticBlocks = PatchStatics( matrix, staDataPath, staIndexPath, staLookupPath ); }
private int PatchLand( TileMatrix matrix, string dataPath, string indexPath ) { using ( FileStream fsData = new FileStream( dataPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { using ( FileStream fsIndex = new FileStream( indexPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { BinaryReader indexReader = new BinaryReader( fsIndex ); int count = (int)(indexReader.BaseStream.Length / 4); for ( int i = 0; i < count; ++i ) { int blockID = indexReader.ReadInt32(); int x = blockID / matrix.BlockHeight; int y = blockID % matrix.BlockHeight; fsData.Seek( 4, SeekOrigin.Current ); Tile[] tiles = new Tile[64]; GCHandle handle = GCHandle.Alloc(tiles, GCHandleType.Pinned); try { if ( m_Buffer == null || 192 > m_Buffer.Length ) m_Buffer = new byte[192]; fsData.Read( m_Buffer, 0, 192 ); Marshal.Copy(m_Buffer, 0, handle.AddrOfPinnedObject(), 192); } finally { handle.Free(); } matrix.SetLandBlock( x, y, tiles ); } indexReader.Close(); return count; } } }
private unsafe int PatchStatics( TileMatrix matrix, string dataPath, string indexPath, string lookupPath ) { using ( FileStream fsData = new FileStream( dataPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { using ( FileStream fsIndex = new FileStream( indexPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { using ( FileStream fsLookup = new FileStream( lookupPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { BinaryReader indexReader = new BinaryReader( fsIndex ); BinaryReader lookupReader = new BinaryReader( fsLookup ); int count = (int)(indexReader.BaseStream.Length / 4); TileList[][] lists = new TileList[8][]; for ( int x = 0; x < 8; ++x ) { lists[x] = new TileList[8]; for ( int y = 0; y < 8; ++y ) lists[x][y] = new TileList(); } for ( int i = 0; i < count; ++i ) { int blockID = indexReader.ReadInt32(); int blockX = blockID / matrix.BlockHeight; int blockY = blockID % matrix.BlockHeight; int offset = lookupReader.ReadInt32(); int length = lookupReader.ReadInt32(); lookupReader.ReadInt32(); // Extra if ( offset < 0 || length <= 0 ) { matrix.SetStaticBlock( blockX, blockY, matrix.EmptyStaticBlock ); continue; } fsData.Seek( offset, SeekOrigin.Begin ); int tileCount = length / 7; if ( m_TileBuffer.Length < tileCount ) m_TileBuffer = new StaticTile[tileCount]; StaticTile[] staTiles = m_TileBuffer; fixed ( StaticTile *pTiles = staTiles ) { #if !MONO NativeReader.Read( fsData.SafeFileHandle.DangerousGetHandle(), pTiles, length ); #else NativeReader.Read( fsData.Handle, pTiles, length ); #endif StaticTile *pCur = pTiles, pEnd = pTiles + tileCount; while ( pCur < pEnd ) { lists[pCur->m_X & 0x7][pCur->m_Y & 0x7].Add( (ushort)pCur->m_ID, pCur->m_Z ); pCur = pCur + 1; } StaticTile[][][] tiles = new StaticTile[8][][]; for ( int x = 0; x < 8; ++x ) { tiles[x] = new StaticTile[8][]; for ( int y = 0; y < 8; ++y ) tiles[x][y] = lists[x][y].ToArray(); } matrix.SetStaticBlock( blockX, blockY, tiles ); } } indexReader.Close(); lookupReader.Close(); return count; } } } }
private int PatchStatics( TileMatrix matrix, string dataPath, string indexPath, string lookupPath ) { using ( FileStream fsData = new FileStream( dataPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { using ( FileStream fsIndex = new FileStream( indexPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { using ( FileStream fsLookup = new FileStream( lookupPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { BinaryReader indexReader = new BinaryReader( fsIndex ); BinaryReader lookupReader = new BinaryReader( fsLookup ); int count = (int)(indexReader.BaseStream.Length / 4); TileList[][] lists = new TileList[8][]; for ( int x = 0; x < 8; ++x ) { lists[x] = new TileList[8]; for ( int y = 0; y < 8; ++y ) lists[x][y] = new TileList(); } for ( int i = 0; i < count; ++i ) { int blockID = indexReader.ReadInt32(); int blockX = blockID / matrix.BlockHeight; int blockY = blockID % matrix.BlockHeight; int offset = lookupReader.ReadInt32(); int length = lookupReader.ReadInt32(); lookupReader.ReadInt32(); // Extra if ( offset < 0 || length <= 0 ) { matrix.SetStaticBlock( blockX, blockY, matrix.EmptyStaticBlock ); continue; } fsData.Seek( offset, SeekOrigin.Begin ); int tileCount = length / 7; if ( m_TileBuffer.Length < tileCount ) m_TileBuffer = new StaticTile[tileCount]; StaticTile[] staTiles = m_TileBuffer;//new StaticTile[tileCount]; GCHandle handle = GCHandle.Alloc(staTiles, GCHandleType.Pinned); try { if ( m_Buffer == null || length > m_Buffer.Length ) m_Buffer = new byte[length]; fsData.Read( m_Buffer, 0, length ); Marshal.Copy(m_Buffer, 0, handle.AddrOfPinnedObject(), length); for (int j = 0; j < tileCount; j++) { StaticTile cur = staTiles[j]; lists[cur.m_X & 0x7][cur.m_Y & 0x7].Add( (short)((cur.m_ID & 0x3FFF) + 0x4000), cur.m_Z ); } Tile[][][] tiles = new Tile[8][][]; for ( int x = 0; x < 8; ++x ) { tiles[x] = new Tile[8][]; for ( int y = 0; y < 8; ++y ) tiles[x][y] = lists[x][y].ToArray(); } matrix.SetStaticBlock( blockX, blockY, tiles ); } finally { handle.Free(); } } indexReader.Close(); lookupReader.Close(); return count; } } } }
private unsafe int PatchLand( TileMatrix matrix, string dataPath, string indexPath ) { using ( FileStream fsData = new FileStream( dataPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { using ( FileStream fsIndex = new FileStream( indexPath, FileMode.Open, FileAccess.Read, FileShare.Read ) ) { BinaryReader indexReader = new BinaryReader( fsIndex ); int count = (int)(indexReader.BaseStream.Length / 4); for ( int i = 0; i < count; ++i ) { int blockID = indexReader.ReadInt32(); int x = blockID / matrix.BlockHeight; int y = blockID % matrix.BlockHeight; fsData.Seek( 4, SeekOrigin.Current ); Tile[] tiles = new Tile[64]; fixed ( Tile *pTiles = tiles ) { if ( m_Buffer == null || 192 > m_Buffer.Length ) m_Buffer = new byte[192]; fsData.Read( m_Buffer, 0, 192 ); Marshal.Copy(m_Buffer, 0, new IntPtr(pTiles), 192); } matrix.SetLandBlock( x, y, tiles ); } indexReader.Close(); return count; } } }
private unsafe int PatchLand(TileMatrix matrix, string dataPath, string indexPath) { using (FileStream fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (FileStream fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReader indexReader = new BinaryReader(fsIndex); int count = (int)(indexReader.BaseStream.Length / 4); for (int i = 0; i < count; ++i) { int blockID = indexReader.ReadInt32(); int x = blockID / matrix.BlockHeight; int y = blockID % matrix.BlockHeight; fsData.Seek(4, SeekOrigin.Current); Tile[] tiles = new Tile[64]; fixed (Tile* pTiles = tiles) { #if !MONO _lread(fsData.Handle, pTiles, 192); #else if ( m_Buffer == null || 192 > m_Buffer.Length ) m_Buffer = new byte[192]; fsData.Read( m_Buffer, 0, 192 ); fixed ( byte *pbBuffer = m_Buffer ) { Tile *pBuffer = (Tile *)pbBuffer; Tile *pEnd = pBuffer + 64; Tile *pCur = pTiles; while ( pBuffer < pEnd ) *pCur++ = *pBuffer++; } #endif } matrix.SetLandBlock(x, y, tiles); } indexReader.Close(); return count; } } }
public TileMatrix(Map owner, int fileIndex, int mapID, int width, int height) { lock (m_Instances) { for (int i = 0; i < m_Instances.Count; ++i) { TileMatrix tm = m_Instances[i]; if (tm.m_FileIndex == fileIndex) { lock (m_FileShare) { lock (tm.m_FileShare) { tm.m_FileShare.Add(this); m_FileShare.Add(tm); } } } } m_Instances.Add(this); } m_FileIndex = fileIndex; m_Width = width; m_Height = height; m_BlockWidth = width >> 3; m_BlockHeight = height >> 3; m_Owner = owner; if (fileIndex != 0x7F) { string mapPath = Core.FindDataFile("map{0}.mul", fileIndex); if (File.Exists(mapPath)) { m_Map = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } else { mapPath = Core.FindDataFile("map{0}LegacyMUL.uop", fileIndex); if (File.Exists(mapPath)) { m_Map = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); m_MapIndex = new UOPIndex(m_Map); } } string indexPath = Core.FindDataFile("staidx{0}.mul", fileIndex); if (File.Exists(indexPath)) { m_Index = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); m_IndexReader = new BinaryReader(m_Index); } string staticsPath = Core.FindDataFile("statics{0}.mul", fileIndex); if (File.Exists(staticsPath)) { m_Statics = new FileStream(staticsPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); } } m_EmptyStaticBlock = new StaticTile[8][][]; for (int i = 0; i < 8; ++i) { m_EmptyStaticBlock[i] = new StaticTile[8][]; for (int j = 0; j < 8; ++j) { m_EmptyStaticBlock[i][j] = new StaticTile[0]; } } m_InvalidLandBlock = new LandTile[196]; m_LandTiles = new LandTile[m_BlockWidth][][]; m_StaticTiles = new StaticTile[m_BlockWidth][][][][]; m_StaticPatches = new int[m_BlockWidth][]; m_LandPatches = new int[m_BlockWidth][]; m_Patch = new TileMatrixPatch(this, mapID); }
public static void Freeze(Mobile from, Map targetMap, Point3D start3d, Point3D end3d) { Hashtable mapTable = new Hashtable(); if (start3d == NullP3D && end3d == NullP3D) { if (targetMap == null) { CommandLogging.WriteLine(from, "{0} {1} invoking freeze for every item in every map", from.AccessLevel, CommandLogging.Format(from)); } else { CommandLogging.WriteLine(from, "{0} {1} invoking freeze for every item in {0}", from.AccessLevel, CommandLogging.Format(from), targetMap); } foreach (Item item in World.Items.Values) { if (targetMap != null && item.Map != targetMap) { continue; } if (item.Parent != null) { continue; } if (item is Static || item is BaseFloor || item is BaseWall) { Map itemMap = item.Map; if (itemMap == null || itemMap == Map.Internal) { continue; } Hashtable table = (Hashtable)mapTable[itemMap]; if (table == null) { mapTable[itemMap] = table = new Hashtable(); } Point2D p = new Point2D(item.X >> 3, item.Y >> 3); DeltaState state = (DeltaState)table[p]; if (state == null) { table[p] = state = new DeltaState(p); } state.m_List.Add(item); } } } else if (targetMap != null) { Point2D start = targetMap.Bound(new Point2D(start3d)), end = targetMap.Bound(new Point2D(end3d)); CommandLogging.WriteLine(from, "{0} {1} invoking freeze from {2} to {3} in {4}", from.AccessLevel, CommandLogging.Format(from), start, end, targetMap); IPooledEnumerable eable = targetMap.GetItemsInBounds(new Rectangle2D(start.X, start.Y, end.X - start.X + 1, end.Y - start.Y + 1)); foreach (Item item in eable) { if (item is Static || item is BaseFloor || item is BaseWall) { Map itemMap = item.Map; if (itemMap == null || itemMap == Map.Internal) { continue; } Hashtable table = (Hashtable)mapTable[itemMap]; if (table == null) { mapTable[itemMap] = table = new Hashtable(); } Point2D p = new Point2D(item.X >> 3, item.Y >> 3); DeltaState state = (DeltaState)table[p]; if (state == null) { table[p] = state = new DeltaState(p); } state.m_List.Add(item); } } eable.Free(); } if (mapTable.Count == 0) { from.SendGump(new NoticeGump(1060637, 30720, "No freezable items were found. Only the following item types are frozen:<br> - Static<br> - BaseFloor<br> - BaseWall", 0xFFC000, 320, 240, null, null)); return; } bool badDataFile = false; int totalFrozen = 0; foreach (DictionaryEntry de in mapTable) { Map map = (Map)de.Key; Hashtable table = (Hashtable)de.Value; TileMatrix matrix = map.Tiles; using (FileStream idxStream = OpenWrite(matrix.IndexStream)) { using (FileStream mulStream = OpenWrite(matrix.DataStream)) { if (idxStream == null || mulStream == null) { badDataFile = true; continue; } BinaryReader idxReader = new BinaryReader(idxStream); BinaryWriter idxWriter = new BinaryWriter(idxStream); BinaryWriter mulWriter = new BinaryWriter(mulStream); foreach (DeltaState state in table.Values) { int oldTileCount; StaticTile[] oldTiles = ReadStaticBlock(idxReader, mulStream, state.m_X, state.m_Y, matrix.BlockWidth, matrix.BlockHeight, out oldTileCount); if (oldTileCount < 0) { continue; } int newTileCount = 0; StaticTile[] newTiles = new StaticTile[state.m_List.Count]; for (int i = 0; i < state.m_List.Count; ++i) { Item item = state.m_List[i]; int xOffset = item.X - (state.m_X * 8); int yOffset = item.Y - (state.m_Y * 8); if (xOffset < 0 || xOffset >= 8 || yOffset < 0 || yOffset >= 8) { continue; } StaticTile newTile = new StaticTile((ushort)item.ItemID, (byte)xOffset, (byte)yOffset, (sbyte)item.Z, (short)item.Hue); newTiles[newTileCount++] = newTile; item.Delete(); ++totalFrozen; } int mulPos = -1; int length = -1; int extra = 0; if ((oldTileCount + newTileCount) > 0) { mulWriter.Seek(0, SeekOrigin.End); mulPos = (int)mulWriter.BaseStream.Position; length = (oldTileCount + newTileCount) * 7; extra = 1; for (int i = 0; i < oldTileCount; ++i) { StaticTile toWrite = oldTiles[i]; mulWriter.Write((ushort)toWrite.ID); mulWriter.Write((byte)toWrite.X); mulWriter.Write((byte)toWrite.Y); mulWriter.Write((sbyte)toWrite.Z); mulWriter.Write((short)toWrite.Hue); } for (int i = 0; i < newTileCount; ++i) { StaticTile toWrite = newTiles[i]; mulWriter.Write((ushort)toWrite.ID); mulWriter.Write((byte)toWrite.X); mulWriter.Write((byte)toWrite.Y); mulWriter.Write((sbyte)toWrite.Z); mulWriter.Write((short)toWrite.Hue); } mulWriter.Flush(); } int idxPos = ((state.m_X * matrix.BlockHeight) + state.m_Y) * 12; idxWriter.Seek(idxPos, SeekOrigin.Begin); idxWriter.Write(mulPos); idxWriter.Write(length); idxWriter.Write(extra); idxWriter.Flush(); matrix.SetStaticBlock(state.m_X, state.m_Y, null); } } } } if (totalFrozen == 0 && badDataFile) { from.SendGump(new NoticeGump(1060637, 30720, "Output data files could not be opened and the freeze operation has been aborted.<br><br>This probably means your server and client are using the same data files. Instructions on how to resolve this can be found in the first warning window.", 0xFFC000, 320, 240, null, null)); } else { from.SendGump(new NoticeGump(1060637, 30720, String.Format("Freeze operation completed successfully.<br><br>{0} item{1} frozen.<br><br>You must restart your client and update it's data files to see the changes.", totalFrozen, totalFrozen != 1 ? "s were" : " was"), 0xFFC000, 320, 240, null, null)); } }
private static void DoUnfreeze(Map map, Point2D start, Point2D end, ref bool badDataFile, ref int totalUnfrozen) { start = map.Bound(start); end = map.Bound(end); int xStartBlock = start.X >> 3; int yStartBlock = start.Y >> 3; int xEndBlock = end.X >> 3; int yEndBlock = end.Y >> 3; int xTileStart = start.X, yTileStart = start.Y; int xTileWidth = end.X - start.X + 1, yTileHeight = end.Y - start.Y + 1; TileMatrix matrix = map.Tiles; using (FileStream idxStream = OpenWrite(matrix.IndexStream)) { using (FileStream mulStream = OpenWrite(matrix.DataStream)) { if (idxStream == null || mulStream == null) { badDataFile = true; return; } BinaryReader idxReader = new BinaryReader(idxStream); BinaryWriter idxWriter = new BinaryWriter(idxStream); BinaryWriter mulWriter = new BinaryWriter(mulStream); for (int x = xStartBlock; x <= xEndBlock; ++x) { for (int y = yStartBlock; y <= yEndBlock; ++y) { int oldTileCount; StaticTile[] oldTiles = ReadStaticBlock(idxReader, mulStream, x, y, matrix.BlockWidth, matrix.BlockHeight, out oldTileCount); if (oldTileCount < 0) { continue; } int newTileCount = 0; StaticTile[] newTiles = new StaticTile[oldTileCount]; int baseX = (x << 3) - xTileStart, baseY = (y << 3) - yTileStart; for (int i = 0; i < oldTileCount; ++i) { StaticTile oldTile = oldTiles[i]; int px = baseX + oldTile.X; int py = baseY + oldTile.Y; if (px < 0 || px >= xTileWidth || py < 0 || py >= yTileHeight) { newTiles[newTileCount++] = oldTile; } else { ++totalUnfrozen; Item item = new Static(oldTile.ID); item.Hue = oldTile.Hue; item.MoveToWorld(new Point3D(px + xTileStart, py + yTileStart, oldTile.Z), map); } } int mulPos = -1; int length = -1; int extra = 0; if (newTileCount > 0) { mulWriter.Seek(0, SeekOrigin.End); mulPos = (int)mulWriter.BaseStream.Position; length = newTileCount * 7; extra = 1; for (int i = 0; i < newTileCount; ++i) { StaticTile toWrite = newTiles[i]; mulWriter.Write((ushort)toWrite.ID); mulWriter.Write((byte)toWrite.X); mulWriter.Write((byte)toWrite.Y); mulWriter.Write((sbyte)toWrite.Z); mulWriter.Write((short)toWrite.Hue); } mulWriter.Flush(); } int idxPos = ((x * matrix.BlockHeight) + y) * 12; idxWriter.Seek(idxPos, SeekOrigin.Begin); idxWriter.Write(mulPos); idxWriter.Write(length); idxWriter.Write(extra); idxWriter.Flush(); matrix.SetStaticBlock(x, y, null); } } } } }
private unsafe int PatchStatics(TileMatrix matrix, string dataPath, string indexPath, string lookupPath) { using (FileStream fsData = new FileStream(dataPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (FileStream fsIndex = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { using (FileStream fsLookup = new FileStream(lookupPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { BinaryReader indexReader = new BinaryReader(fsIndex); BinaryReader lookupReader = new BinaryReader(fsLookup); int count = (int)(indexReader.BaseStream.Length / 4); TileList[][] lists = new TileList[8][]; for (int x = 0; x < 8; ++x) { lists[x] = new TileList[8]; for (int y = 0; y < 8; ++y) { lists[x][y] = new TileList(); } } for (int i = 0; i < count; ++i) { int blockID = indexReader.ReadInt32(); int blockX = blockID / matrix.BlockHeight; int blockY = blockID % matrix.BlockHeight; int offset = lookupReader.ReadInt32(); int length = lookupReader.ReadInt32(); lookupReader.ReadInt32(); // Extra if (offset < 0 || length <= 0) { matrix.SetStaticBlock(blockX, blockY, matrix.EmptyStaticBlock); continue; } fsData.Seek(offset, SeekOrigin.Begin); int tileCount = length / 7; if (m_TileBuffer.Length < tileCount) { m_TileBuffer = new StaticTile[tileCount]; } StaticTile[] staTiles = m_TileBuffer; fixed(StaticTile *pTiles = staTiles) { #if !MONO NativeReader.Read(fsData.SafeFileHandle.DangerousGetHandle(), pTiles, length); #else NativeReader.Read(fsData.Handle, pTiles, length); #endif StaticTile *pCur = pTiles, pEnd = pTiles + tileCount; while (pCur < pEnd) { lists[pCur->m_X & 0x7][pCur->m_Y & 0x7].Add((ushort)pCur->m_ID, pCur->m_Z); pCur = pCur + 1; } StaticTile[][][] tiles = new StaticTile[8][][]; for (int x = 0; x < 8; ++x) { tiles[x] = new StaticTile[8][]; for (int y = 0; y < 8; ++y) { tiles[x][y] = lists[x][y].ToArray(); } } matrix.SetStaticBlock(blockX, blockY, tiles); } } indexReader.Close(); lookupReader.Close(); return(count); } } } }