Example #1
0
        public IBlockState GetBlock(int x, int y, int z)
        {
            var index = Index(x, y, z);
            var id    = _nBitsArray[index];

            return(id == Nil ? null : BlockPalette.GetBlockState(id));
        }
Example #2
0
        public virtual void HandleMcpeStartGame(McpeStartGame message)
        {
            var client = Client;

            client.EntityId        = message.runtimeEntityId;
            client.NetworkEntityId = message.entityIdSelf;
            client.SpawnPoint      = message.spawn;
            client.CurrentLocation = new PlayerLocation(client.SpawnPoint, message.rotation.X, message.rotation.X, message.rotation.Y);

            BlockPalette blockPalette = message.blockPalette;

            client.BlockPalette        = blockPalette;
            client.LevelInfo.LevelName = message.worldName;
            client.LevelInfo.Version   = 19133;
            client.LevelInfo.GameType  = message.gamemode;

            var packet = McpeRequestChunkRadius.CreateObject();

            client.ChunkRadius = 5;
            packet.chunkRadius = client.ChunkRadius;

            if (Client.IsEmulator)
            {
                Client.HasSpawned = true;
                Client.PlayerStatusChangedWaitHandle.Set();
                Client.SendMcpeMovePlayer();
            }

            client.SendPacket(packet);
        }
Example #3
0
        // ** Initialization and control
        public void Configure(RenderConfiguration Configuration)
        {
            _Config = Configuration;

            _ColourPalette = _Config.Palette;
            _Metrics       = _Config.Metrics;

            _Chunks = Configuration.Chunks;

            if (_Config.AdvancedRenderOptions.Exists(x => x.Key.ToLower() == "mode"))
            {
                switch (_Config.AdvancedRenderOptions.Find(x => x.Key.ToLower() == "mode").Value)
                {
                case "c":
                    _RenderStartY = GetStartRenderYCave;
                    break;

                case "C":
                    _RenderStartY = GetStartRenderYCaveAlternate;
                    break;

                default:
                    _RenderStartY = GetStartRenderYNormal;
                    break;
                }
            }
            else
            {
                _RenderStartY = GetStartRenderYNormal;
            }
        }
        public override void HandleMcpeStartGame(McpeStartGame message)
        {
            Client.EntityId        = message.runtimeEntityId;
            Client.NetworkEntityId = message.entityIdSelf;
            Client.SpawnPoint      = message.spawn;
            Client.CurrentLocation = new PlayerLocation(Client.SpawnPoint, message.rotation.X, message.rotation.X, message.rotation.Y);

            Client.LevelInfo.LevelName = message.levelId;
            Client.LevelInfo.Version   = 19133;
            Client.LevelInfo.GameType  = message.gamemode;

            BlockPalette = message.blockPalette;

            _internalStates = new HashSet <BlockStateContainer>(BlockFactory.BlockPalette);

            {
                int viewDistance = Config.GetProperty("ViewDistance", 11);

                var packet = McpeRequestChunkRadius.CreateObject();
                Client.ChunkRadius = viewDistance;
                packet.chunkRadius = Client.ChunkRadius;

                Client.SendPacket(packet);
            }
        }
        private void Start()
        {
            m_World = Locator <IWorld> .GetService();

            m_Picker = MonoSingleton <GameSystem> .Instance.InputMngIns.PickerIns;

            BlockPalette Palette = m_World.BlkPalette;

            var buttons = GetComponentsInChildren <BlockSlot_Bar>();

            byte i = 1;

            foreach (var bt in buttons)
            {
                if (i >= Palette.Count)
                {
                    break;
                }

                bt.SetBlock(Palette[i]);
                ++i;
            }

            //set default selected
            DefaultSlot.OnSelect();
        }
        private void ExecuteWritePallet(BedrockTraceHandler caller)
        {
            var          client  = caller.Client;
            BlockPalette palette = client.BlockPalette;

            _runningBlockMetadataDiscovery = false;

            WritePaletteToJson(palette);
        }
Example #7
0
    public void SetPreviewPalette(string toSet)     //called on buttonpress calls from methods in MainMenu.cs; updates the preview
    {
        BlockPalette blockPalette = new BlockPalette(toSet);

        for (int i = 0; i < 8; i++)
        {
            previewBlocks[i].GetComponent <SpriteRenderer>().color = blockPalette.palette[i];
        }
    }
Example #8
0
        static BlockFactory()
        {
            for (int i = 0; i < byte.MaxValue * 2; i++)
            {
                var block = GetBlockById(i);
                if (block != null)
                {
                    if (block.IsTransparent)
                    {
                        TransparentBlocks[block.Id] = 1;
                    }
                    if (block.LightLevel > 0)
                    {
                        LuminousBlocks[block.Id] = (byte)block.LightLevel;
                    }
                }
            }

            NameToId = BuildNameToId();

            for (int i = 0; i < LegacyToRuntimeId.Length; ++i)
            {
                LegacyToRuntimeId[i] = -1;
            }

            var assembly = Assembly.GetAssembly(typeof(Block));

            lock (lockObj)
            {
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".blockstates.json"))
                    using (var reader = new StreamReader(stream))
                    {
                        BlockPalette = BlockPalette.FromJson(reader.ReadToEnd());
                    }
            }
            int palletSize = BlockPalette.Count;

            for (int i = 0; i < palletSize; i++)
            {
                if (BlockPalette[i].Data > 15)
                {
                    continue;                                            // TODO: figure out why palette contains blocks with meta more than 15
                }
                if (BlockPalette[i].Data == -1)
                {
                    continue;                                             // These are blockstates that does not have a metadata mapping
                }
                LegacyToRuntimeId[(BlockPalette[i].Id << 4) | (byte)BlockPalette[i].Data] = i;
            }

            BlockStates = new HashSet <BlockStateContainer>(BlockPalette);
        }
        public void FillBlock(BlockState block)
        {
            _blocks.Fill(BlockPalette.IdForBlock(block));

            if (block == AirBlock)
            {
                IsEmpty = true;
            }
            else
            {
                IsEmpty = false;
            }
        }
Example #10
0
        private static void PopulateBlockPalette()
        {
            BlockPalette.Add("Air", new Block("Air", BlockTypes.Air, Textures["Air"], dummyPosition));
            BlockPalette.Add("FuelCell", new FuelCell("FuelCell", Textures["FuelCell"], dummyPosition));

            foreach (Cooler cooler in coolers)
            {
                BlockPalette.Add(cooler.CoolerType.ToString(), cooler);
            }
            foreach (Moderator moderator in moderators)
            {
                BlockPalette.Add(moderator.ModeratorType.ToString(), moderator);
            }
        }
Example #11
0
 /* Set Default Settings
  * Returns all settings to their defaults for the normal gamemode.
  * Called my MainMenu before applying other modifiers here and loading the game
  */
 public void SetDefaultSettings()
 {
     currentModeName     = GameMode.Normal;
     fireMode            = "tetromino";
     rotate45            = false;
     minWaitTime         = 0.4f;
     maxWaitTime         = 2.5f;
     flipCamera          = false;
     makeScoreNegative   = false;
     settingPalette      = new BlockPalette(); //default constructor
     slipperyJumpAllowed = false;              //TODO maybe remove?
     boostCooldown       = 10.0f;
     impossibleMode      = false;
     immuneToCrush       = false;
 }
Example #12
0
        private static BlockStateContainer GetServerRuntimeId(BlockPalette bedrockPalette, HashSet <BlockStateContainer> internalBlockPallet, int runtimeId)
        {
            if (runtimeId < 0 || runtimeId >= bedrockPalette.Count)
            {
                Log.Error($"RuntimeId = {runtimeId}");
            }

            var record = bedrockPalette[runtimeId];

            if (!internalBlockPallet.TryGetValue(record, out BlockStateContainer internalRecord))
            {
                Log.Error($"Did not find {record.Id}");
                return(null);
            }

            return(internalRecord);
        }
Example #13
0
 internal RenderConfiguration(BlockPalette UsePalette, WorldMetrics UseMetrics)
 {
     MinLightLevel        = 15;
     WorldPath            = "";
     SaveFilename         = "";
     ScanFilename         = "";
     MetricsFilename      = "";
     Dimension            = "";
     EnableMultithreading = false;
     Palette               = UsePalette;
     Metrics               = UseMetrics;
     RendererName          = "Standard";
     MaxThreads            = Environment.ProcessorCount;
     AdvancedRenderOptions = new List <KeyValuePair <string, string> >();
     SubregionChunks       = new Rectangle();
     RenderSubregion       = false;
 }
Example #14
0
        public void SetBlock(int x, int y, int z, IBlockState blockState)
        {
            var id = blockState != null?BlockPalette.GetId(blockState) : Nil;

            if (id == -1) // block not registered
            {
                Resize((byte)(BlockPalette.BitsPerBlock + 1));
                id = BlockPalette.GetId(blockState);
                if (id == -1)
                {
                    throw new InvalidOperationException("Invalid block state palette id");
                }
            }

            var index = Index(x, y, z);

            _nBitsArray[index] = id;
            _blockCount        = ushort.MaxValue;
        }
Example #15
0
        //Unity function
        //-----------------------------------------------------------

        public void Start()
        {
            BlockPalette palette = Locator <IWorld> .GetService().BlkPalette;

            var Slots = GetComponentsInChildren <BlockSlot_Menu>();

            byte i = 1;

            foreach (var slot in Slots)
            {
                if (i >= palette.Count)
                {
                    break;
                }

                slot.SetBlock(palette[i]);
                ++i;
            }
        }
Example #16
0
        private static void WritePaletteToJson(BlockPalette palette)
        {
            var jsonSerializerSettings = new JsonSerializerSettings
            {
                PreserveReferencesHandling = PreserveReferencesHandling.None,
                Formatting = Formatting.None,
            };

            jsonSerializerSettings.Converters.Add(new StringEnumConverter());
            jsonSerializerSettings.Converters.Add(new NbtIntConverter());
            jsonSerializerSettings.Converters.Add(new NbtStringConverter());
            jsonSerializerSettings.Converters.Add(new IPAddressConverter());
            jsonSerializerSettings.Converters.Add(new IPEndPointConverter());


            var records = palette.OrderBy(bs => bs.Id).ThenBy(bs => bs.Data).ToArray();

            string fileName = Path.GetTempPath() + "blockstates_" + Guid.NewGuid() + ".json";
            var    writer   = File.AppendText(fileName);
            bool   isFirst  = true;

            writer.WriteLine("[");
            foreach (var record in records)
            {
                string result = JsonConvert.SerializeObject(record, jsonSerializerSettings);

                writer.Write($"{(isFirst ? "" : ",\n")}{result}");
                isFirst = false;
            }
            writer.WriteLine("\n]");

            var stringRecords = records.Where(r => r.States.Any(s => s is BlockStateString));

            foreach (BlockStateContainer stringRecord in stringRecords)
            {
                writer.WriteLine($"Item {stringRecord.Name}");
            }

            writer.Close();
        }
Example #17
0
        /// <summary>
        /// Resize the storage to match the bitsPerBlock
        /// </summary>
        /// <param name="bitsPerBlock">The number of bits used to store a block state</param>
        private void Resize(byte bitsPerBlock)
        {
            var previousDataBits     = _nBitsArray;
            var previousBlockPalette = BlockPalette;

            if (!UpdatePalette(bitsPerBlock))
            {
                return;
            }

            for (var i = 0; i < previousDataBits.Capacity; i++)
            {
                var blockStateId = previousDataBits[i];
                if (blockStateId == 0)
                {
                    continue;
                }

                var blockState = previousBlockPalette.GetBlockState(blockStateId);
                _nBitsArray[i] = BlockPalette.GetId(blockState);
            }
        }
        public void BlcoksWithBlockstates()
        {
            List <string> blocksWithStates = new List <string>();
            BlockPalette  blockPalette     = BlockFactory.BlockPalette;

            foreach (BlockStateContainer stateContainer in blockPalette)
            {
                if (stateContainer.States.Count > 0)
                {
                    if (stateContainer.States.Count(s => s.Name.Contains("direction")) > 0)
                    {
                        blocksWithStates.Add(stateContainer.Name);
                    }
                    if (stateContainer.States.Count(s => s.Name.Contains("face")) > 0)
                    {
                        blocksWithStates.Add(stateContainer.Name);
                    }
                }
            }

            foreach (string name in blocksWithStates.OrderBy(n => n).Distinct())
            {
                Console.WriteLine($"{name}");
                foreach (var state in BlockFactory.GetBlockByName(name).GetState().States)
                {
                    if (state.Name.Contains("direction"))
                    {
                        Console.WriteLine($"\t{state.Name}");
                    }
                    if (state.Name.Contains("face"))
                    {
                        Console.WriteLine($"\t{state.Name}");
                    }
                }
            }
        }
Example #19
0
        public override void HandleMcpeStartGame(McpeStartGame message)
        {
            Client.EntityId        = message.runtimeEntityId;
            Client.NetworkEntityId = message.entityIdSelf;
            Client.SpawnPoint      = message.spawn;
            Client.CurrentLocation = new PlayerLocation(Client.SpawnPoint, message.rotation.X, message.rotation.X, message.rotation.Y);

            BlockPalette blockPalette = message.blockPalette;

            Client.BlockPalette = blockPalette;

            Log.Warn($"Got position from startgame packet: {Client.CurrentLocation}");

            var settings = new JsonSerializerSettings
            {
                PreserveReferencesHandling = PreserveReferencesHandling.Arrays,
                TypeNameHandling           = TypeNameHandling.Auto,
                Formatting           = Formatting.Indented,
                DefaultValueHandling = DefaultValueHandling.Include
            };

            var fileNameItemstates = Path.GetTempPath() + "itemstates_" + Guid.NewGuid() + ".json";

            File.WriteAllText(fileNameItemstates, JsonConvert.SerializeObject(message.itemstates, settings));

            string fileName = Path.GetTempPath() + "MissingBlocks_" + Guid.NewGuid() + ".txt";

            using (FileStream file = File.OpenWrite(fileName))
            {
                var writer = new IndentedTextWriter(new StreamWriter(file));

                Log.Warn($"Directory:\n{Path.GetTempPath()}");
                Log.Warn($"Filename:\n{fileName}");

                writer.WriteLine($"namespace MiNET.Blocks");
                writer.WriteLine($"{{");
                writer.Indent++;

                var blocks = new List <(int, string)>();

                foreach (IGrouping <string, BlockStateContainer> blockstateGrouping in blockPalette.OrderBy(record => record.Name).ThenBy(record => record.Data).ThenBy(record => record.RuntimeId).GroupBy(record => record.Name))
                {
                    BlockStateContainer currentBlockState = blockstateGrouping.First();
                    Log.Debug($"{currentBlockState.Name}, Id={currentBlockState.Id}");
                    BlockStateContainer defaultBlockState = BlockFactory.GetBlockById(currentBlockState.Id, 0)?.GetGlobalState();
                    if (defaultBlockState == null)
                    {
                        defaultBlockState = blockstateGrouping.FirstOrDefault(bs => bs.Data == 0);
                    }

                    Log.Debug($"{currentBlockState.RuntimeId}, {currentBlockState.Name}, {currentBlockState.Data}");
                    Block blockById     = BlockFactory.GetBlockById(currentBlockState.Id);
                    bool  existingBlock = blockById.GetType() != typeof(Block) && !blockById.IsGenerated;
                    int   id            = existingBlock ? currentBlockState.Id : -1;

                    string blockClassName = CodeName(currentBlockState.Name.Replace("minecraft:", ""), true);

                    blocks.Add((blockById.Id, blockClassName));
                    writer.WriteLineNoTabs($"");

                    writer.WriteLine($"public partial class {blockClassName} // {blockById.Id} typeof={blockById.GetType().Name}");
                    writer.WriteLine($"{{");
                    writer.Indent++;

                    writer.WriteLine($"public override string Name => \"{currentBlockState.Name}\";");
                    writer.WriteLineNoTabs("");

                    var bits = new List <BlockStateByte>();
                    foreach (var state in blockstateGrouping.First().States)
                    {
                        var q = blockstateGrouping.SelectMany(c => c.States);

                        // If this is on base, skip this property. We need this to implement common functionality.
                        Type baseType     = blockById.GetType().BaseType;
                        bool propOverride = baseType != null &&
                                            ("Block" != baseType.Name &&
                                             baseType.GetProperty(CodeName(state.Name, true)) != null);

                        switch (state)
                        {
                        case BlockStateByte blockStateByte:
                        {
                            var  values     = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateByte)d).Value).Distinct().OrderBy(s => s).ToList();
                            byte defaultVal = ((BlockStateByte)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? 0;
                            if (values.Min() == 0 && values.Max() == 1)
                            {
                                bits.Add(blockStateByte);
                                writer.Write($"[StateBit] ");
                                writer.WriteLine($"public{(propOverride ? " override" : "")} bool {CodeName(state.Name, true)} {{ get; set; }} = {(defaultVal == 1 ? "true" : "false")};");
                            }
                            else
                            {
                                writer.Write($"[StateRange({values.Min()}, {values.Max()})] ");
                                writer.WriteLine($"public{(propOverride ? " override" : "")} byte {CodeName(state.Name, true)} {{ get; set; }} = {defaultVal};");
                            }
                            break;
                        }

                        case BlockStateInt blockStateInt:
                        {
                            var values     = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateInt)d).Value).Distinct().OrderBy(s => s).ToList();
                            int defaultVal = ((BlockStateInt)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? 0;
                            writer.Write($"[StateRange({values.Min()}, {values.Max()})] ");
                            writer.WriteLine($"public{(propOverride ? " override" : "")} int {CodeName(state.Name, true)} {{ get; set; }} = {defaultVal};");
                            break;
                        }

                        case BlockStateString blockStateString:
                        {
                            var    values     = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateString)d).Value).Distinct().ToList();
                            string defaultVal = ((BlockStateString)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? "";
                            if (values.Count > 1)
                            {
                                writer.WriteLine($"[StateEnum({string.Join(',', values.Select(v => $"\"{v}\""))})]");
                            }
                            writer.WriteLine($"public{(propOverride ? " override" : "")} string {CodeName(state.Name, true)} {{ get; set; }} = \"{defaultVal}\";");
                            break;
                        }

                        default:
                            throw new ArgumentOutOfRangeException(nameof(state));
                        }
                    }

                    // Constructor

                    //if (id == -1 || blockById.IsGenerated)
                    //{
                    //	writer.WriteLine($"");

                    //	writer.WriteLine($"public {blockClassName}() : base({currentBlockState.Id})");
                    //	writer.WriteLine($"{{");
                    //	writer.Indent++;
                    //	writer.WriteLine($"IsGenerated = true;");
                    //	writer.WriteLine($"SetGenerated();");
                    //	writer.Indent--;
                    //	writer.WriteLine($"}}");
                    //}

                    writer.WriteLineNoTabs($"");
                    writer.WriteLine($"public override void SetState(List<IBlockState> states)");
                    writer.WriteLine($"{{");
                    writer.Indent++;
                    writer.WriteLine($"foreach (var state in states)");
                    writer.WriteLine($"{{");
                    writer.Indent++;
                    writer.WriteLine($"switch(state)");
                    writer.WriteLine($"{{");
                    writer.Indent++;

                    foreach (var state in blockstateGrouping.First().States)
                    {
                        writer.WriteLine($"case {state.GetType().Name} s when s.Name == \"{state.Name}\":");
                        writer.Indent++;
                        writer.WriteLine($"{CodeName(state.Name, true)} = {(bits.Contains(state) ? "Convert.ToBoolean(s.Value)" : "s.Value")};");
                        writer.WriteLine($"break;");
                        writer.Indent--;
                    }

                    writer.Indent--;
                    writer.WriteLine($"}} // switch");
                    writer.Indent--;
                    writer.WriteLine($"}} // foreach");
                    writer.Indent--;
                    writer.WriteLine($"}} // method");

                    writer.WriteLineNoTabs($"");
                    writer.WriteLine($"public override BlockStateContainer GetState()");
                    writer.WriteLine($"{{");
                    writer.Indent++;
                    writer.WriteLine($"var record = new BlockStateContainer();");
                    writer.WriteLine($"record.Name = \"{blockstateGrouping.First().Name}\";");
                    writer.WriteLine($"record.Id = {blockstateGrouping.First().Id};");
                    foreach (var state in blockstateGrouping.First().States)
                    {
                        string propName = CodeName(state.Name, true);
                        writer.WriteLine($"record.States.Add(new {state.GetType().Name} {{Name = \"{state.Name}\", Value = {(bits.Contains(state) ? $"Convert.ToByte({propName})" : propName)}}});");
                    }
                    writer.WriteLine($"return record;");
                    writer.Indent--;
                    writer.WriteLine($"}} // method");
                    writer.Indent--;
                    writer.WriteLine($"}} // class");
                }

                writer.WriteLine();

                foreach (var block in blocks.OrderBy(tuple => tuple.Item1))
                {
                    int clazzId = block.Item1;

                    Block blockById     = BlockFactory.GetBlockById(clazzId);
                    bool  existingBlock = blockById.GetType() != typeof(Block) && !blockById.IsGenerated;
                    if (existingBlock)
                    {
                        continue;
                    }

                    string clazzName = block.Item2;
                    string baseClazz = clazzName.EndsWith("Stairs") ? "BlockStairs" : "Block";
                    baseClazz = clazzName.EndsWith("Slab") && !clazzName.EndsWith("DoubleSlab")? "SlabBase" : baseClazz;
                    writer.WriteLine($"public partial class {clazzName} : {baseClazz} {{ " +
                                     $"public {clazzName}() : base({clazzId}) {{ IsGenerated = true; }} " +
                                     $"}}");
                }

                writer.Indent--;
                writer.WriteLine($"}}");                 // namespace

                //foreach (var block in blocks.OrderBy(tuple => tuple.Item1))
                //{
                //	// 495 => new StrippedCrimsonStem(),
                //	writer.WriteLine($"\t\t\t\t{block.Item1} => new {block.Item2}(),");
                //}

                writer.Flush();
            }

            LogGamerules(message.gamerules);

            Client.LevelInfo.LevelName = "Default";
            Client.LevelInfo.Version   = 19133;
            Client.LevelInfo.GameType  = message.gamemode;

            //ClientUtils.SaveLevel(_level);

            {
                var packet = McpeRequestChunkRadius.CreateObject();
                Client.ChunkRadius = 5;
                packet.chunkRadius = Client.ChunkRadius;

                Client.SendPacket(packet);
            }
        }
Example #20
0
        public static ChunkColumn DecodeChunkColumn(int subChunkCount, byte[] buffer, BlockPalette bedrockPalette = null, HashSet <BlockStateContainer> internalBlockPallet = null)
        {
            //lock (_chunkRead)
            {
                var stream = new MemoryStream(buffer);
                {
                    var defStream = new BinaryReader(stream);

                    if (subChunkCount < 1)
                    {
                        Log.Warn("Nothing to read");
                        return(null);
                    }

                    //if (Log.IsTraceEnabled()) Log.Trace($"Reading {subChunkCount} sections");

                    var chunkColumn = new ChunkColumn(false);

                    for (int chunkIndex = 0; chunkIndex < subChunkCount; chunkIndex++)
                    {
                        int version     = stream.ReadByte();
                        int storageSize = stream.ReadByte();

                        var subChunk = chunkColumn[chunkIndex];

                        for (int storageIndex = 0; storageIndex < storageSize; storageIndex++)
                        {
                            int  flags         = stream.ReadByte();
                            bool isRuntime     = (flags & 1) != 0;
                            int  bitsPerBlock  = flags >> 1;
                            int  blocksPerWord = (int)Math.Floor(32f / bitsPerBlock);
                            int  wordsPerChunk = (int)Math.Ceiling(4096f / blocksPerWord);
                            if (Log.IsTraceEnabled())
                            {
                                Log.Trace($"New section {chunkIndex}, " +
                                          $"version={version}, " +
                                          $"storageSize={storageSize}, " +
                                          $"storageIndex={storageIndex}, " +
                                          $"bitsPerBlock={bitsPerBlock}, " +
                                          $"isRuntime={isRuntime}, " +
                                          $"noBlocksPerWord={blocksPerWord}, " +
                                          $"wordCount={wordsPerChunk}, " +
                                          $"");
                            }

                            long jumpPos = stream.Position;
                            stream.Seek(wordsPerChunk * 4, SeekOrigin.Current);

                            int paletteCount = VarInt.ReadSInt32(stream);
                            var palette      = new int[paletteCount];
                            for (int j = 0; j < paletteCount; j++)
                            {
                                if (!isRuntime)
                                {
                                    var file = new NbtFile
                                    {
                                        BigEndian = false,
                                        UseVarInt = true
                                    };
                                    file.LoadFromStream(stream, NbtCompression.None);
                                    var tag = (NbtCompound)file.RootTag;

                                    Block block = BlockFactory.GetBlockByName(tag["name"].StringValue);
                                    if (block != null && block.GetType() != typeof(Block) && !(block is Air))
                                    {
                                        List <IBlockState> blockState = ReadBlockState(tag);
                                        block.SetState(blockState);
                                    }
                                    else
                                    {
                                        block = new Air();
                                    }

                                    palette[j] = block.GetRuntimeId();
                                }
                                else
                                {
                                    int runtimeId = VarInt.ReadSInt32(stream);
                                    if (bedrockPalette == null || internalBlockPallet == null)
                                    {
                                        continue;
                                    }

                                    palette[j] = GetServerRuntimeId(bedrockPalette, internalBlockPallet, runtimeId);
                                }
                            }

                            long afterPos = stream.Position;
                            stream.Position = jumpPos;
                            int position = 0;
                            for (int w = 0; w < wordsPerChunk; w++)
                            {
                                uint word = defStream.ReadUInt32();
                                for (int block = 0; block < blocksPerWord; block++)
                                {
                                    if (position >= 4096)
                                    {
                                        continue;
                                    }

                                    uint state = (uint)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1));

                                    int x = (position >> 8) & 0xF;
                                    int y = position & 0xF;
                                    int z = (position >> 4) & 0xF;

                                    int runtimeId = palette[state];

                                    if (storageIndex == 0)
                                    {
                                        subChunk.SetBlockByRuntimeId(x, y, z, (int)runtimeId);
                                    }
                                    else
                                    {
                                        subChunk.SetLoggedBlockByRuntimeId(x, y, z, (int)runtimeId);
                                    }

                                    position++;
                                }
                            }
                            stream.Position = afterPos;
                        }
                    }

                    if (stream.Read(chunkColumn.biomeId, 0, 256) != 256)
                    {
                        return(chunkColumn);
                    }
                    //Log.Debug($"biomeId:\n{Package.HexDump(chunk.biomeId)}");

                    if (stream.Position >= stream.Length - 1)
                    {
                        return(chunkColumn);
                    }

                    int borderBlock = VarInt.ReadSInt32(stream);
                    if (borderBlock != 0)
                    {
                        Log.Warn($"??? Got borderblock with value {borderBlock}.");

                        int len   = (int)(stream.Length - stream.Position);
                        var bytes = new byte[len];
                        stream.Read(bytes, 0, len);
                        Log.Warn($"Data to read for border blocks\n{Packet.HexDump(new ReadOnlyMemory<byte>(bytes))}");

                        //byte[] buf = new byte[borderBlock];
                        //int len = stream.Read(buf, 0, borderBlock);
                        //Log.Warn($"??? Got borderblock {borderBlock}. Read {len} bytes");
                        //Log.Debug($"{Packet.HexDump(buf)}");
                        //for (int i = 0; i < borderBlock; i++)
                        //{
                        //	int x = (buf[i] & 0xf0) >> 4;
                        //	int z = buf[i] & 0x0f;
                        //	Log.Debug($"x={x}, z={z}");
                        //}
                    }

                    if (stream.Position < stream.Length - 1)
                    {
                        while (stream.Position < stream.Length)
                        {
                            NbtFile file = new NbtFile()
                            {
                                BigEndian = false,
                                UseVarInt = true
                            };

                            file.LoadFromStream(stream, NbtCompression.None);
                            var blockEntityTag = file.RootTag;
                            if (blockEntityTag.Name != "alex")
                            {
                                int x = blockEntityTag["x"].IntValue;
                                int y = blockEntityTag["y"].IntValue;
                                int z = blockEntityTag["z"].IntValue;

                                chunkColumn.SetBlockEntity(new BlockCoordinates(x, y, z), (NbtCompound)file.RootTag);

                                if (Log.IsTraceEnabled())
                                {
                                    Log.Trace($"Blockentity:\n{file.RootTag}");
                                }
                            }
                        }
                    }

                    if (stream.Position < stream.Length - 1)
                    {
                        int len   = (int)(stream.Length - stream.Position);
                        var bytes = new byte[len];
                        stream.Read(bytes, 0, len);
                        Log.Warn($"Still have data to read\n{Packet.HexDump(new ReadOnlyMemory<byte>(bytes))}");
                    }

                    return(chunkColumn);
                }
            }
        }
Example #21
0
        static BlockFactory()
        {
            for (int i = 0; i < byte.MaxValue * 2; i++)
            {
                var block = GetBlockById(i);
                if (block != null)
                {
                    if (block.IsTransparent)
                    {
                        TransparentBlocks[block.Id] = 1;
                    }
                    if (block.LightLevel > 0)
                    {
                        LuminousBlocks[block.Id] = (byte)block.LightLevel;
                    }
                }
            }

            NameToId = BuildNameToId();

            for (int i = 0; i < LegacyToRuntimeId.Length; ++i)
            {
                LegacyToRuntimeId[i] = -1;
            }

            var assembly = Assembly.GetAssembly(typeof(Block));

            lock (lockObj)
            {
                Dictionary <string, int> idMapping;
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".block_id_map.json"))
                    using (var reader = new StreamReader(stream))
                    {
                        idMapping = JsonConvert.DeserializeObject <Dictionary <string, int> >(reader.ReadToEnd());
                    }

                Dictionary <string, short> itemIdMapping;
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".item_id_map.json"))
                    using (var reader = new StreamReader(stream))
                    {
                        itemIdMapping = JsonConvert.DeserializeObject <Dictionary <string, short> >(reader.ReadToEnd());
                    }

                int runtimeId = 0;
                BlockPalette = new BlockPalette();
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".canonical_block_states.nbt"))
                {
                    var reader = new NbtFile();
                    reader.UseVarInt = true;
                    reader.AllowAlternativeRootTag = true;

                    do
                    {
                        reader.LoadFromStream(stream, NbtCompression.AutoDetect);
                        var record = new BlockStateContainer();

                        var    tag  = reader.RootTag;
                        string name = tag["name"].StringValue;
                        record.Name   = name;
                        record.States = new List <IBlockState>();

                        if (idMapping.TryGetValue(name, out var id))
                        {
                            record.Id = id;
                        }

                        var states = tag["states"];
                        if (states != null && states is NbtCompound compound)
                        {
                            foreach (var stateEntry in compound)
                            {
                                switch (stateEntry)
                                {
                                case NbtInt nbtInt:
                                    record.States.Add(new BlockStateInt()
                                    {
                                        Name  = nbtInt.Name,
                                        Value = nbtInt.Value
                                    });
                                    break;

                                case NbtByte nbtByte:
                                    record.States.Add(new BlockStateByte()
                                    {
                                        Name  = nbtByte.Name,
                                        Value = nbtByte.Value
                                    });
                                    break;

                                case NbtString nbtString:
                                    record.States.Add(new BlockStateString()
                                    {
                                        Name  = nbtString.Name,
                                        Value = nbtString.Value
                                    });
                                    break;
                                }
                            }
                        }

                        if (itemIdMapping.TryGetValue(name, out var itemId))
                        {
                            record.ItemInstance = new ItemPickInstance()
                            {
                                Id       = itemId,
                                WantNbt  = false,
                                Metadata = 0
                            };
                        }

                        record.RuntimeId = runtimeId++;
                        BlockPalette.Add(record);
                    } while (stream.Position < stream.Length);
                }

                /*using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".blockstates.json"))
                 * using (var reader = new StreamReader(stream))
                 * {
                 *      BlockPalette = BlockPalette.FromJson(reader.ReadToEnd());
                 * }*/

                foreach (var record in BlockPalette)
                {
                    var states = new List <NbtTag>();
                    foreach (IBlockState state in record.States)
                    {
                        NbtTag stateTag = null;
                        switch (state)
                        {
                        case BlockStateByte blockStateByte:
                            stateTag = new NbtByte(state.Name, blockStateByte.Value);
                            break;

                        case BlockStateInt blockStateInt:
                            stateTag = new NbtInt(state.Name, blockStateInt.Value);
                            break;

                        case BlockStateString blockStateString:
                            stateTag = new NbtString(state.Name, blockStateString.Value);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(nameof(state));
                        }
                        states.Add(stateTag);
                    }

                    var nbt = new NbtFile()
                    {
                        BigEndian = false,
                        UseVarInt = true,
                        RootTag   = new NbtCompound("states", states)
                    };

                    byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None);

                    record.StatesCacheNbt = nbtBinary;
                }
            }
            int palletSize = BlockPalette.Count;

            for (int i = 0; i < palletSize; i++)
            {
                if (BlockPalette[i].Data > 15)
                {
                    continue;                                            // TODO: figure out why palette contains blocks with meta more than 15
                }
                if (BlockPalette[i].Data == -1)
                {
                    continue;                                             // These are blockstates that does not have a metadata mapping
                }
                LegacyToRuntimeId[(BlockPalette[i].Id << 4) | (byte)BlockPalette[i].Data] = i;
            }

            BlockStates = new HashSet <BlockStateContainer>(BlockPalette);
        }
Example #22
0
        private void ExecutePickBlocks(BedrockTraceHandler caller)
        {
            var client = caller.Client;
            int count  = 500;
            int yStart = 100;
            int x      = 0;
            int z      = 0;


            string fileName = Path.GetTempPath() + "pick_items_" + Guid.NewGuid() + ".json";
            var    writer   = File.AppendText(fileName);

            var jsonSerializerSettings = new JsonSerializerSettings
            {
                PreserveReferencesHandling = PreserveReferencesHandling.None,
                Formatting = Formatting.None,
            };

            jsonSerializerSettings.Converters.Add(new NbtIntConverter());
            jsonSerializerSettings.Converters.Add(new NbtStringConverter());

            //BlockPalette palette = client.BlockPalette;
            BlockPalette palette = BlockFactory.BlockPalette;             // only if we have updated it

            _resetEventPlayerHotbar.Reset();

            for (int id = 0; id < count; id++)
            {
                try
                {
                    {
                        var request = new McpeCommandRequest();
                        request.command     = $"/tp TheGrey {x} {150} {z}";
                        request.unknownUuid = new UUID(Guid.NewGuid().ToString());
                        client.SendPacket(request);
                    }

                    var block = BlockFactory.GetBlockById(id);
                    if (block.GetType() == typeof(Block))
                    {
                        continue;
                    }

                    if (block is Cocoa)
                    {
                        continue;                         // crashes on meta=15
                    }
                    int y = yStart;
                    for (int meta = 0; meta <= 15; meta++)
                    {
                        var blockstate = palette.FirstOrDefault(b => b.Id == id && b.Data == meta);
                        if (blockstate == null)
                        {
                            continue;
                        }
                        blockstate.ItemInstance = null;                         // reset to nothing

                        string name = blockstate.Name.Replace("minecraft:", "");
                        if (name == "double_plant" || name == "air" || name.StartsWith("element"))
                        {
                            break;
                        }

                        var pick = McpeBlockPickRequest.CreateObject();
                        pick.x = x;
                        pick.y = y;
                        pick.z = z;
                        client.SendPacket(pick);

                        //Thread.Sleep(100);
                        if (!_resetEventPlayerHotbar.WaitOne(300))
                        {
                            Log.Error($"No picked item for {id}, {meta}, {name}");
                            _lastSelectedItem = new ItemAir();
                            continue;
                            //break;
                        }

                        // Investigate last selected item. This should be the one we picked
                        Item item;
                        lock (_lastSelectedItem)
                        {
                            item = _lastSelectedItem;
                            _lastSelectedItem = new ItemAir();
                        }
                        Log.Warn($"For {id}, {meta} we picked {item}");
                        blockstate.ItemInstance = new ItemPickInstance()
                        {
                            Id       = item.Id,
                            Metadata = item.Metadata,
                            WantNbt  = item.ExtraData != null
                        };
                        string result = JsonConvert.SerializeObject(blockstate, jsonSerializerSettings);
                        writer.WriteLine($"{item}; {result}");
                        writer.Flush();

                        if (blockstate.States.Count == 0)
                        {
                            break;
                        }

                        y += 2;
                    }
                }
                finally
                {
                    x += 2;
                }
            }

            writer.Close();

            WritePaletteToJson(palette);
            Log.Warn("Finished!");
        }
 public BlockState GetBlock(int index)
 {
     return(BlockPalette.BlockForId(_blocks[index]));
 }
Example #24
0
        public static ChunkColumn DecodeChunkColumn(int subChunkCount, byte[] buffer, BlockPalette bedrockPalette = null, HashSet <BlockStateContainer> internalBlockPallet = null)
        {
            lock (_chunkRead)
            {
                var stream = new MemoryStream(buffer);
                {
                    var defStream = new NbtBinaryReader(stream, true);

                    if (subChunkCount < 1)
                    {
                        Log.Warn("Nothing to read");
                        return(null);
                    }

                    Log.Debug($"Reading {subChunkCount} sections");

                    var chunkColumn = new ChunkColumn(false);

                    for (int chunkIndex = 0; chunkIndex < subChunkCount; chunkIndex++)
                    {
                        int version     = defStream.ReadByte();
                        int storageSize = defStream.ReadByte();

                        var subChunk = chunkColumn[chunkIndex];

                        for (int storageIndex = 0; storageIndex < storageSize; storageIndex++)
                        {
                            int bitsPerBlock  = defStream.ReadByte() >> 1;
                            int blocksPerWord = (int)Math.Floor(32f / bitsPerBlock);
                            int wordsPerChunk = (int)Math.Ceiling(4096f / blocksPerWord);
                            Log.Debug($"New section {chunkIndex}, " +
                                      $"version={version}, " +
                                      $"storageSize={storageSize}, " +
                                      $"storageIndex={storageIndex}, " +
                                      $"bitsPerBlock={bitsPerBlock}, " +
                                      $"noBlocksPerWord={blocksPerWord}, " +
                                      $"wordCount={wordsPerChunk}, " +
                                      $"");


                            long jumpPos = stream.Position;
                            stream.Seek(wordsPerChunk * 4, SeekOrigin.Current);

                            int paletteCount = VarInt.ReadSInt32(stream);
                            var palette      = new int[paletteCount];
                            for (int j = 0; j < paletteCount; j++)
                            {
                                int runtimeId = VarInt.ReadSInt32(stream);
                                if (bedrockPalette == null || internalBlockPallet == null)
                                {
                                    continue;
                                }

                                palette[j] = GetServerRuntimeId(bedrockPalette, internalBlockPallet, runtimeId);
                            }

                            long afterPos = stream.Position;
                            stream.Position = jumpPos;
                            int position = 0;
                            for (int w = 0; w < wordsPerChunk; w++)
                            {
                                uint word = defStream.ReadUInt32();
                                for (int block = 0; block < blocksPerWord; block++)
                                {
                                    if (position >= 4096)
                                    {
                                        continue;
                                    }

                                    uint state = (uint)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1));

                                    int x = (position >> 8) & 0xF;
                                    int y = position & 0xF;
                                    int z = (position >> 4) & 0xF;

                                    int runtimeId = palette[state];

                                    if (storageIndex == 0)
                                    {
                                        subChunk.SetBlockByRuntimeId(x, y, z, (int)runtimeId);
                                    }
                                    else
                                    {
                                        subChunk.SetLoggedBlockByRuntimeId(x, y, z, (int)runtimeId);
                                    }

                                    position++;
                                }
                            }
                            stream.Position = afterPos;
                        }
                    }

                    if (defStream.Read(chunkColumn.biomeId, 0, 256) != 256)
                    {
                        Log.Error($"Out of data biomeId");
                    }
                    //Log.Debug($"biomeId:\n{Package.HexDump(chunk.biomeId)}");

                    //if (stream.Position >= stream.Length - 1) return chunkColumn;

                    int borderBlock = VarInt.ReadSInt32(stream);
                    if (borderBlock != 0)
                    {
                        byte[] buf = new byte[borderBlock];
                        int    len = defStream.Read(buf, 0, borderBlock);
                        Log.Warn($"??? Got borderblock {borderBlock}. Read {len} bytes");
                        Log.Debug($"{Packet.HexDump(buf)}");
                        for (int i = 0; i < borderBlock; i++)
                        {
                            int x = (buf[i] & 0xf0) >> 4;
                            int z = buf[i] & 0x0f;
                            Log.Debug($"x={x}, z={z}");
                        }
                    }

                    if (stream.Position < stream.Length - 1)
                    {
                        while (stream.Position < stream.Length)
                        {
                            NbtFile file = new NbtFile()
                            {
                                BigEndian = false,
                                UseVarInt = true
                            };

                            file.LoadFromStream(stream, NbtCompression.None);
                            var blockEntityTag = file.RootTag;
                            if (blockEntityTag.Name != "alex")
                            {
                                int x = blockEntityTag["x"].IntValue;
                                int y = blockEntityTag["y"].IntValue;
                                int z = blockEntityTag["z"].IntValue;

                                chunkColumn.SetBlockEntity(new BlockCoordinates(x, y, z), (NbtCompound)file.RootTag);

                                Log.Debug($"Blockentity:\n{file.RootTag}");
                            }
                        }
                    }
                    if (stream.Position < stream.Length - 1)
                    {
                        Log.Warn($"Still have data to read\n{Packet.HexDump(defStream.ReadBytes((int) (stream.Length - stream.Position)))}");
                    }

                    return(chunkColumn);
                }
            }
        }
 public void FillBlockLevel(BlockState block, int y)
 {
     _blocks.Slice(y * LevelBlockCount, LevelBlockCount).Fill(BlockPalette.IdForBlock(block));
     IsEmpty = false;
 }
Example #26
0
    private static void CreateBlock(Vector3 position, SubChunk chunk)
    {
        // subChunk index in the Chunk itself. [0, 15]
        int subChunkId = chunk.SubChunkId;

        // Position as integer.
        int x = (int)position.x;
        int y = (int)position.y;
        int z = (int)position.z;


        // False if there is a block next to those faces.
        bool left, right, top, bottom, front, back;

        top    = y != 15 ? chunk.GetBlock(x, y + 1, z) == -1 : true;
        bottom = y != 0  ? chunk.GetBlock(x, y - 1, z) == -1 : true;
        left   = x != 0  ? chunk.GetBlock(x - 1, y, z) == -1 : true;
        right  = x != 15 ? chunk.GetBlock(x + 1, y, z) == -1 : true;
        front  = z != 15 ? chunk.GetBlock(x, y, z + 1) == -1 : true;
        back   = z != 0  ? chunk.GetBlock(x, y, z - 1) == -1 : true;

        // If the block is completly surrounded(not seen).
        if (left && right && top && bottom && front && back)
        {
            return;
        }

        // Should draw faces? except chunk borders.
        bool leftChunk  = true;
        bool rightChunk = true;
        bool backChunk  = true;
        bool frontChunk = true;

        if (x == 0)
        {
            leftChunk = chunk.Chunk.ChunkLeft.GetSubChunk(subChunkId).GetBlock(15, y, z) == -1;
        }
        if (x == 15)
        {
            rightChunk = chunk.Chunk.ChunkRight.GetSubChunk(subChunkId).GetBlock(0, y, z) == -1;
        }
        if (z == 0)
        {
            backChunk = chunk.Chunk.ChunkBack.GetSubChunk(subChunkId).GetBlock(x, y, 15) == -1;
        }
        if (z == 15)
        {
            frontChunk = chunk.Chunk.ChunkFront.GetSubChunk(subChunkId).GetBlock(x, y, 0) == -1;
        }

        // Check if there is a block in the above subchunk.
        // Dont check if the subchunk is the bottom or top one.
        bool topChunk    = true;
        bool bottomChunk = true;

        if (subChunkId != 15)
        {
            SubChunk topSubChunk = chunk.Chunk.GetSubChunk(subChunkId + 1);
            if (topSubChunk.isFull())
            {
                topChunk = true;
            }
            else
            {
                topChunk = topSubChunk.GetBlock(x, 0, z) == -1;
            }
        }
        if (subChunkId != 0)
        {
            SubChunk botSubChunk = chunk.Chunk.GetSubChunk(subChunkId - 1);
            if (botSubChunk.isFull())
            {
                bottomChunk = false;
            }
            else
            {
                bottomChunk = botSubChunk.GetBlock(x, 15, z) == -1;
            }
        }

        // False if should not render chunk border faces.
        bool topBorder    = y == 15 ? chunk.RenderTop && topChunk    : top;
        bool bottomBorder = y == 0  ? chunk.RenderBottom && bottomChunk : bottom;
        bool leftBorder   = x == 0  ? chunk.RenderLeft && leftChunk   : left;
        bool rightBorder  = x == 15 ? chunk.RenderRight && rightChunk  : right;
        bool frontBorder  = z == 15 ? chunk.RenderFront && frontChunk  : front;
        bool backBorder   = z == 0  ? chunk.RenderBack && backChunk   : back;

        // Display the chunk in green if chunk is surrounded.
        int gx = (int)(chunk.Chunk.Position.x * 16) + x;
        int gz = (int)(chunk.Chunk.Position.y * 16) + z;

        CurrentColor = BlockPalette.GetColor((BLOCK_TYPE)chunk.GetBlock(x, y, z), gx, gz);

        // Represent each faces of a cube and if it should place
        // each faces. Placed in the same order in CUBE_FACES enum.
        bool[] lutFaces =
        {
            topBorder,   bottomBorder,
            leftBorder,  rightBorder,
            frontBorder, backBorder
        };

        for (int i = 0; i < 6; i++)
        {
            if (lutFaces[i] == true)
            {
                CreateFace(i, position);
            }
        }
    }
Example #27
0
        static BlockFactory()
        {
            for (int i = 0; i < byte.MaxValue * 2; i++)
            {
                var block = GetBlockById(i);
                if (block != null)
                {
                    if (block.IsTransparent)
                    {
                        TransparentBlocks[block.Id] = 1;
                    }
                    if (block.LightLevel > 0)
                    {
                        LuminousBlocks[block.Id] = (byte)block.LightLevel;
                    }
                }
            }

            NameToId = BuildNameToId();

            for (int i = 0; i < LegacyToRuntimeId.Length; ++i)
            {
                LegacyToRuntimeId[i] = -1;
            }

            var assembly = Assembly.GetAssembly(typeof(Block));

            lock (lockObj)
            {
                Dictionary <string, int> idMapping = new Dictionary <string, int>(ResourceUtil.ReadResource <Dictionary <string, int> >("block_id_map.json", typeof(Block), "Data"), StringComparer.OrdinalIgnoreCase);

                int runtimeId = 0;
                BlockPalette = new BlockPalette();

                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".Data.canonical_block_states.nbt"))
                {
                    do
                    {
                        var compound  = Packet.ReadNbtCompound(stream, true);
                        var container = GetBlockStateContainer(compound);

                        container.RuntimeId = runtimeId++;
                        BlockPalette.Add(container);
                    } while (stream.Position < stream.Length);
                }

                List <R12ToCurrentBlockMapEntry> legacyStateMap = new List <R12ToCurrentBlockMapEntry>();
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".Data.r12_to_current_block_map.bin"))
                {
                    while (stream.Position < stream.Length)
                    {
                        var    length = VarInt.ReadUInt32(stream);
                        byte[] bytes  = new byte[length];
                        stream.Read(bytes, 0, bytes.Length);

                        string stringId = Encoding.UTF8.GetString(bytes);

                        bytes = new byte[2];
                        stream.Read(bytes, 0, bytes.Length);
                        var meta = BitConverter.ToInt16(bytes);

                        var compound = Packet.ReadNbtCompound(stream, true);

                        legacyStateMap.Add(new R12ToCurrentBlockMapEntry(stringId, meta, GetBlockStateContainer(compound)));
                    }
                }

                Dictionary <string, List <int> > idToStatesMap = new Dictionary <string, List <int> >(StringComparer.OrdinalIgnoreCase);

                for (var index = 0; index < BlockPalette.Count; index++)
                {
                    var        state = BlockPalette[index];
                    List <int> candidates;

                    if (!idToStatesMap.TryGetValue(state.Name, out candidates))
                    {
                        candidates = new List <int>();
                    }

                    candidates.Add(index);

                    idToStatesMap[state.Name] = candidates;
                }

                foreach (var pair in legacyStateMap)
                {
                    if (!idMapping.TryGetValue(pair.StringId, out int id))
                    {
                        continue;
                    }

                    var data = pair.Meta;

                    if (data > 15)
                    {
                        continue;
                    }

                    var mappedState = pair.State;
                    var mappedName  = pair.State.Name;

                    if (!idToStatesMap.TryGetValue(mappedName, out var matching))
                    {
                        continue;
                    }

                    foreach (var match in matching)
                    {
                        var networkState = BlockPalette[match];

                        var thisStates  = new HashSet <IBlockState>(mappedState.States);
                        var otherStates = new HashSet <IBlockState>(networkState.States);

                        otherStates.IntersectWith(thisStates);

                        if (otherStates.Count == thisStates.Count)
                        {
                            BlockPalette[match].Id   = id;
                            BlockPalette[match].Data = data;

                            BlockPalette[match].ItemInstance = new ItemPickInstance()
                            {
                                Id       = (short)id,
                                Metadata = data,
                                WantNbt  = false
                            };

                            LegacyToRuntimeId[(id << 4) | (byte)data] = match;

                            break;
                        }
                    }
                }

                foreach (var record in BlockPalette)
                {
                    var states = new List <NbtTag>();
                    foreach (IBlockState state in record.States)
                    {
                        NbtTag stateTag = null;
                        switch (state)
                        {
                        case BlockStateByte blockStateByte:
                            stateTag = new NbtByte(state.Name, blockStateByte.Value);
                            break;

                        case BlockStateInt blockStateInt:
                            stateTag = new NbtInt(state.Name, blockStateInt.Value);
                            break;

                        case BlockStateString blockStateString:
                            stateTag = new NbtString(state.Name, blockStateString.Value);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(nameof(state));
                        }
                        states.Add(stateTag);
                    }

                    var nbt = new NbtFile()
                    {
                        BigEndian = false,
                        UseVarInt = true,
                        RootTag   = new NbtCompound("states", states)
                    };

                    byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None);

                    record.StatesCacheNbt = nbtBinary;
                }
            }

            BlockStates = new HashSet <BlockStateContainer>(BlockPalette);
        }
Example #28
0
    public void Throw(string fireMode, bool rotate45, BlockPalette blockPalette)
    {
        if (fireMode.Equals("tetromino"))
        {
            toSpawn = tetrominoObjects[Random.Range(0, 7)];
        }
        else if (fireMode.Equals("tromino"))
        {
            toSpawn = trominoObjects[Random.Range(0, 2)];
        }
        else if (fireMode.Equals("pentomino"))
        {
            toSpawn = pentominoObjects[Random.Range(0, 18)];
        }
        else if (fireMode.Equals("tiny"))
        {
            toSpawn = tinyBlockObjects[Random.Range(0, 2)];
        }
        else if (fireMode.Equals("all"))
        {
            int set = Random.Range(0, 3);
            if (set == 0)
            {
                toSpawn = tetrominoObjects[Random.Range(0, 7)];
            }
            else if (set == 1)
            {
                toSpawn = trominoObjects[Random.Range(0, 2)];
            }
            else if (set == 2)
            {
                toSpawn = pentominoObjects[Random.Range(0, 18)];
            }
        }
        else if (fireMode.Equals("warped"))
        {
            toSpawn = warpedObjects[Random.Range(0, 17)];
        }
        else if (fireMode.Equals("university"))
        {
            toSpawn = octominoF;
        }

        //how fast?
        float   xtraj      = Random.Range(-trajectoryRandomFactor, trajectoryRandomFactor);
        float   ytraj      = Random.Range(-trajectoryRandomFactor, trajectoryRandomFactor);
        Vector3 trajectory = new Vector3(baseTrajectory.x + xtraj, baseTrajectory.y + ytraj, 0);

        //what color?
        Color colour = blockPalette.palette[Random.Range(0, 8)];

        //how much rotation?
        float rotation = 90f * (Mathf.Floor(Random.Range(0, 4)));

        // optional mode modifier
        if (rotate45)
        {
            rotation += 45f;
        }

        chuckerBlocked = AmIBlocked();  //check the surroundings to ensure you can fire without overlapping somethign else

        if (!chuckerBlocked)
        {
            GameObject tetrominoClone = (GameObject)Instantiate(toSpawn, transform.position, transform.rotation);
            tetrominoClone.GetComponent <Rigidbody2D>().AddForce(trajectory, ForceMode2D.Impulse);
            //tetrominoClone.GetComponent<Rigidbody2D>().AddTorque(rot);
            tetrominoClone.GetComponent <SpriteRenderer>().color = colour;

            Quaternion finalRotation = Quaternion.Euler(0, 0, rotation);
            //finalRotation.z = rotation;
            tetrominoClone.transform.rotation = finalRotation;
        }
        else
        {
            Debug.Log(gameObject.name + " was blocked from throwing.");
        }
    }
        public void GeneratePartialBlocksFromBlockstates()
        {
            BlockPalette blockPalette = BlockFactory.BlockPalette;

            string fileName = Path.GetTempPath() + "MissingBlocks_" + Guid.NewGuid() + ".txt";

            using (FileStream file = File.OpenWrite(fileName))
            {
                var blocks = new List <(int, string)>();

                var writer = new IndentedTextWriter(new StreamWriter(file));

                Console.WriteLine($"Directory:\n{Path.GetTempPath()}");
                Console.WriteLine($"Filename:\n{fileName}");
                Log.Warn($"Writing blocks to filename:\n{fileName}");

                writer.WriteLine($"namespace MiNET.Blocks");
                writer.WriteLine($"{{");
                writer.Indent++;

                foreach (IGrouping <string, BlockStateContainer> blockstateGrouping in blockPalette.OrderBy(record => record.Name).ThenBy(record => record.Data).GroupBy(record => record.Name))
                {
                    var currentBlockState = blockstateGrouping.First();
                    var defaultBlockState = blockstateGrouping.FirstOrDefault(bs => bs.Data == 0);

                    Log.Debug($"{currentBlockState.RuntimeId}, {currentBlockState.Name}, {currentBlockState.Data}");
                    Block blockById     = BlockFactory.GetBlockById(currentBlockState.Id);
                    bool  existingBlock = blockById.GetType() != typeof(Block) && !blockById.IsGenerated;
                    int   id            = existingBlock ? currentBlockState.Id : -1;

                    string blockClassName = CodeName(currentBlockState.Name.Replace("minecraft:", ""), true);

                    blocks.Add((blockById.Id, blockClassName));

                    writer.WriteLineNoTabs($"");

                    writer.WriteLine($"public partial class {blockClassName} {(existingBlock ? "" : ": Block")} // {blockById.Id} typeof={blockById.GetType().Name}");
                    writer.WriteLine($"{{");
                    writer.Indent++;

                    var bits = new List <BlockStateByte>();
                    foreach (var state in blockstateGrouping.First().States)
                    {
                        var q = blockstateGrouping.SelectMany(c => c.States);

                        // If this is on base, skip this property. We need this to implement common functionality.
                        Type baseType     = blockById.GetType().BaseType;
                        bool propOverride = baseType != null &&
                                            ("Block" != baseType.Name &&
                                             baseType.GetProperty(CodeName(state.Name, true)) != null);

                        switch (state)
                        {
                        case BlockStateByte blockStateByte:
                        {
                            var  values     = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateByte)d).Value).Distinct().OrderBy(s => s).ToList();
                            byte defaultVal = ((BlockStateByte)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? 0;
                            if (values.Min() == 0 && values.Max() == 1)
                            {
                                bits.Add(blockStateByte);
                                writer.Write($"[StateBit] ");
                                writer.WriteLine($"public {(propOverride ? "override" : "")} bool {CodeName(state.Name, true)} {{ get; set; }} = {(defaultVal == 1 ? "true" : "false")};");
                            }
                            else
                            {
                                writer.Write($"[StateRange({values.Min()}, {values.Max()})] ");
                                writer.WriteLine($"public {(propOverride ? "override" : "")} byte {CodeName(state.Name, true)} {{ get; set; }} = {defaultVal};");
                            }
                            break;
                        }

                        case BlockStateInt blockStateInt:
                        {
                            var values     = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateInt)d).Value).Distinct().OrderBy(s => s).ToList();
                            int defaultVal = ((BlockStateInt)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? 0;
                            writer.Write($"[StateRange({values.Min()}, {values.Max()})] ");
                            writer.WriteLine($"public {(propOverride ? "override" : "")} int {CodeName(state.Name, true)} {{ get; set; }} = {defaultVal};");
                            break;
                        }

                        case BlockStateString blockStateString:
                        {
                            var    values     = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateString)d).Value).Distinct().ToList();
                            string defaultVal = ((BlockStateString)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? "";
                            if (values.Count > 1)
                            {
                                writer.WriteLine($"[StateEnum({string.Join(',', values.Select(v => $"\"{v}\""))})]");
                            }
                            writer.WriteLine($"public {(propOverride ? "override" : "")} string {CodeName(state.Name, true)} {{ get; set; }} = \"{defaultVal}\";");
                            break;
                        }

                        default:
                            throw new ArgumentOutOfRangeException(nameof(state));
                        }
                    }

                    if (id == -1 || blockById.IsGenerated)
                    {
                        writer.WriteLine($"");

                        writer.WriteLine($"public {blockClassName}() : base({currentBlockState.Id})");
                        writer.WriteLine($"{{");
                        writer.Indent++;
                        writer.WriteLine($"IsGenerated = true;");
                        writer.Indent--;
                        writer.WriteLine($"}}");
                    }

                    writer.WriteLineNoTabs($"");
                    writer.WriteLine($"public override void SetState(List<IBlockState> states)");
                    writer.WriteLine($"{{");
                    writer.Indent++;
                    writer.WriteLine($"foreach (var state in states)");
                    writer.WriteLine($"{{");
                    writer.Indent++;
                    writer.WriteLine($"switch(state)");
                    writer.WriteLine($"{{");
                    writer.Indent++;

                    foreach (var state in blockstateGrouping.First().States)
                    {
                        writer.WriteLine($"case {state.GetType().Name} s when s.Name == \"{state.Name}\":");
                        writer.Indent++;
                        writer.WriteLine($"{CodeName(state.Name, true)} = {(bits.Contains(state) ? "Convert.ToBoolean(s.Value)" : "s.Value")};");
                        writer.WriteLine($"break;");
                        writer.Indent--;
                    }

                    writer.Indent--;
                    writer.WriteLine($"}} // switch");
                    writer.Indent--;
                    writer.WriteLine($"}} // foreach");
                    writer.Indent--;
                    writer.WriteLine($"}} // method");

                    writer.WriteLineNoTabs($"");
                    writer.WriteLine($"public override BlockStateContainer GetState()");
                    writer.WriteLine($"{{");
                    writer.Indent++;
                    writer.WriteLine($"var record = new BlockStateContainer();");
                    writer.WriteLine($"record.Name = \"{blockstateGrouping.First().Name}\";");
                    writer.WriteLine($"record.Id = {blockstateGrouping.First().Id};");
                    foreach (var state in blockstateGrouping.First().States)
                    {
                        string propName = CodeName(state.Name, true);
                        writer.WriteLine($"record.States.Add(new {state.GetType().Name} {{Name = \"{state.Name}\", Value = {(bits.Contains(state) ? $"Convert.ToByte({propName})" : propName)}}});");
                    }
                    writer.WriteLine($"return record;");
                    writer.Indent--;
                    writer.WriteLine($"}} // method");

                    //writer.WriteLine($"");

                    //writer.WriteLine($"public byte GetMetadataFromState()");
                    //writer.WriteLine($"{{");
                    //writer.Indent++;

                    //writer.WriteLine($"switch(this)");
                    //writer.WriteLine($"{{");
                    //writer.Indent++;


                    //i = 0;
                    //foreach (var record in message.BlockPalette.Where(b => b.Id == enumerator.Current.Id).OrderBy(b => b.Data))
                    //{
                    //	//case { } b when b.ButtonPressedBit == 0 && b.FacingDirection == 0:
                    //	//	return 0;

                    //	writer.Write($"case {{ }} b when true");
                    //	string retVal = "";
                    //	foreach (var state in record.States.OrderBy(s => s.Name).ThenBy(s => s.Value))
                    //	{
                    //		if (state.Type == (byte) NbtTagType.Byte)
                    //		{
                    //			writer.Write($" && b.{Client.CodeName(state.Name, true)} == {state.Value}");
                    //		}
                    //		else if (state.Type == (byte) NbtTagType.Int)
                    //		{
                    //			writer.Write($" && b.{Client.CodeName(state.Name, true)} == {state.Value}");
                    //		}
                    //		else if (state.Type == (byte) NbtTagType.String)
                    //		{
                    //			writer.Write($" && b.{Client.CodeName(state.Name, true)} == \"{state.Value}\"");
                    //		}
                    //	}
                    //	writer.WriteLine($":");

                    //	writer.Indent++;
                    //	writer.WriteLine($"return { i++ };");
                    //	writer.Indent--;
                    //}

                    //writer.Indent--;
                    //writer.WriteLine($"}} // switch");

                    //writer.WriteLine($"throw new ArithmeticException(\"Invalid state. Unable to convert state to valid metadata\");");

                    //writer.Indent--;
                    //writer.WriteLine($"}} // method");

                    writer.Indent--;
                    writer.WriteLine($"}} // class");
                }

                writer.Indent--;
                writer.WriteLine($"}}");

                foreach (var block in blocks.OrderBy(tuple => tuple.Item1))
                {
                    writer.WriteLine($"else if (blockId == {block.Item1}) block = new {block.Item2}();");
                }

                writer.Flush();
            }
        }
 public void SetBlock(BlockState block, int index)
 {
     _blocks[index] = BlockPalette.IdForBlock(block);
     IsEmpty        = false;
 }