public override void Perform(ushort x1, ushort y1, ushort z1, ushort x2, ushort y2, ushort z2, Player p, Level lvl, Brush brush) { ReplaceBlock[] toReplace = ToReplace; ReplaceBlock target = Target; for (ushort y = y1; y <= y2; y++) for (ushort z = z1; z <= z2; z++) for (ushort x = x1; x <= x2; x++) { byte tile = lvl.GetTile(x, y, z), extTile = 0; if (tile == Block.custom_block) extTile = lvl.GetExtTile(x, y, z); for (int i = 0; i < toReplace.Length; i++) { ReplaceBlock block = toReplace[i]; if (tile != block.Type || (tile == Block.custom_block && extTile != block.ExtType)) { PlaceBlock(p, lvl, x, y, z, target.Type, target.ExtType); break; } } } }
internal static void LoadMessages(Level level, string name) { level.hasMessageBlocks = Database.TableExists("Messages" + name); if (!level.hasMessageBlocks) { return; } using (DataTable table = Database.Backend.GetRows("Messages" + name, "*")) { foreach (DataRow row in table.Rows) { ushort x = ushort.Parse(row["X"].ToString()); ushort y = ushort.Parse(row["Y"].ToString()); ushort z = ushort.Parse(row["Z"].ToString()); byte block = level.GetTile(x, y, z); if (block == Block.custom_block) { block = level.GetExtTile(x, y, z); if (level.CustomBlockProps[block].IsMessageBlock) { continue; } } else { if (Block.Props[block].IsMessageBlock) { continue; } } Database.Backend.DeleteRows("Messages" + name, "WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z); } } }
public bool SendRawMap(Level level) { if ( level.blocks == null ) return false; bool success = true; bool hasBlockDefinitions = HasCpeExt(CpeExt.BlockDefinitions); try { byte[] buffer = new byte[level.blocks.Length + 4]; NetUtils.WriteI32(level.blocks.Length, buffer, 0); if (hasCpe) { for (int i = 0; i < level.blocks.Length; ++i) { byte block = level.blocks[i]; if (block == Block.custom_block) { if (hasBlockDefinitions) buffer[i + 4] = level.GetExtTile(i); else buffer[i + 4] = BlockDefinition.Fallback(level.GetExtTile(i)); } else { buffer[i + 4] = Block.Convert(block); } } } else { for (int i = 0; i < level.blocks.Length; ++i) { byte block = level.blocks[i]; if (block == Block.custom_block) { if (hasBlockDefinitions) buffer[i + 4] = Block.ConvertCPE(level.GetExtTile(i)); else buffer[i + 4] = Block.ConvertCPE( BlockDefinition.Fallback(level.GetExtTile(i))); } else { buffer[i + 4] = Block.Convert(Block.ConvertCPE(level.blocks[i])); } } } SendRaw(Opcode.LevelInitialise); buffer = buffer.GZip(); int totalRead = 0; while (totalRead < buffer.Length) { byte[] packet = new byte[1028]; // need each packet separate for Mono packet[0] = Opcode.LevelDataChunk; short length = (short)Math.Min(buffer.Length - totalRead, 1024); NetUtils.WriteI16(length, packet, 1); Buffer.BlockCopy(buffer, totalRead, packet, 3, length); packet[1027] = (byte)(100 * (float)totalRead / buffer.Length); SendRaw(packet); if (ip != "127.0.0.1") { Thread.Sleep(Server.updateTimer.Interval > 1000 ? 100 : 10); } totalRead += length; } buffer = new byte[7]; buffer[0] = Opcode.LevelFinalise; NetUtils.WriteI16((short)level.Width, buffer, 1); NetUtils.WriteI16((short)level.Height, buffer, 3); NetUtils.WriteI16((short)level.Length, buffer, 5); SendRaw(buffer); Loading = false; if (HasCpeExt(CpeExt.EnvWeatherType)) SendSetMapWeather(level.weather); if (HasCpeExt(CpeExt.EnvColors)) SendCurrentEnvColors(); if (HasCpeExt(CpeExt.EnvMapAppearance)) SendCurrentMapAppearance(); if ( OnSendMap != null ) OnSendMap(this, buffer); if (!level.guns) aiming = false; } catch( Exception ex ) { success = false; Command.all.Find("goto").Use(this, Server.mainLevel.name); SendMessage("There was an error sending the map data, you have been sent to the main level."); Server.ErrorLog(ex); } finally { GC.Collect(); GC.WaitForPendingFinalizers(); } return success; }
public unsafe static void CompressMap(Player p, LevelChunkStream dst) { const int bufferSize = 64 * 1024; byte[] buffer = new byte[bufferSize]; int bIndex = 0; // Store on stack instead of performing function call for every block in map byte *conv = stackalloc byte[256]; byte *convCPE = stackalloc byte[256]; for (int i = 0; i < 256; i++) { conv[i] = Block.Convert((byte)i); } if (!p.hasCustomBlocks) { for (int i = 0; i < 256; i++) { convCPE[i] = Block.ConvertCPE((byte)i); conv[i] = Block.ConvertCPE(conv[i]); } } Level lvl = p.level; bool hasBlockDefs = p.hasBlockDefs; using (GZipStream gs = new GZipStream(dst, CompressionMode.Compress, true)) { byte[] blocks = lvl.blocks; NetUtils.WriteI32(blocks.Length, buffer, 0); gs.Write(buffer, 0, sizeof(int)); dst.length = blocks.Length; // compress the map data in 64 kb chunks if (p.hasCustomBlocks) { for (int i = 0; i < blocks.Length; ++i) { byte block = blocks[i]; if (block == Block.custom_block) { buffer[bIndex] = hasBlockDefs ? lvl.GetExtTile(i) : lvl.GetFallbackExtTile(i); } else { buffer[bIndex] = conv[block]; } bIndex++; if (bIndex == bufferSize) { dst.position = i; gs.Write(buffer, 0, bufferSize); bIndex = 0; } } } else { for (int i = 0; i < blocks.Length; ++i) { byte block = blocks[i]; if (block == Block.custom_block) { block = hasBlockDefs ? lvl.GetExtTile(i) : lvl.GetFallbackExtTile(i); buffer[bIndex] = convCPE[block]; } else { buffer[bIndex] = conv[block]; } bIndex++; if (bIndex == bufferSize) { dst.position = i; gs.Write(buffer, 0, bufferSize); bIndex = 0; } } } if (bIndex > 0) { gs.Write(buffer, 0, bIndex); } } }