예제 #1
0
 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;
             }
         }
     }
 }
예제 #2
0
        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);
                }
            }
        }
예제 #3
0
        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;
        }  
예제 #4
0
        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);
                }
            }
        }