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);
            }
        }
Beispiel #2
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);
        }
Beispiel #3
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);
        }
Beispiel #4
0
		public BlockPalette ReadAlternateBlockPalette()
		{
			var  result = new BlockPalette();
			uint count  = ReadUnsignedVarInt();
			
			//Log.Info($"Block count startgame: {count}");
			for (int runtimeId = 0; runtimeId < count; runtimeId++)
			{
				var record = new BlockStateContainer();
				record.RuntimeId = runtimeId;
				record.Id = record.RuntimeId;
				record.Name = ReadString();
				record.States = new List<IBlockState>();
				
				
				var nbt     = NetworkUtils.ReadNewNbt(_reader);
				var rootTag = nbt.NbtFile.RootTag;

				if (rootTag is NbtList nbtList)
				{
					foreach (NbtTag tag in nbtList)
					{
						var s = tag["states"];

						if (s is NbtCompound compound)
						{
							foreach (NbtTag stateTag in compound)
							{
								IBlockState state = null;

								switch (stateTag.TagType)
								{
									case NbtTagType.Byte:
										state = new BlockStateByte() {Name = stateTag.Name, Value = stateTag.ByteValue};

										break;

									case NbtTagType.Int:
										state = new BlockStateInt() {Name = stateTag.Name, Value = stateTag.IntValue};

										break;

									case NbtTagType.String:
										state = new BlockStateString()
										{
											Name = stateTag.Name, Value = stateTag.StringValue
										};

										break;

									default:
										throw new ArgumentOutOfRangeException();
								}

								record.States.Add(state);
							}
						}
						else if (s is NbtList list)
						{
							foreach (NbtTag stateTag in list)
							{
								IBlockState state = null;

								switch (stateTag.TagType)
								{
									case NbtTagType.Byte:
										state = new BlockStateByte() {Name = stateTag.Name, Value = stateTag.ByteValue};

										break;

									case NbtTagType.Int:
										state = new BlockStateInt() {Name = stateTag.Name, Value = stateTag.IntValue};

										break;

									case NbtTagType.String:
										state = new BlockStateString()
										{
											Name = stateTag.Name, Value = stateTag.StringValue
										};

										break;

									default:
										throw new ArgumentOutOfRangeException();
								}

								record.States.Add(state);
							}
						}

						result.Add(record);
					}
				}
				else if (rootTag is NbtCompound c)
				{
					foreach (NbtTag tag in c)
					{
						var s = tag["states"];

						if (s is NbtCompound compound)
						{
							foreach (NbtTag stateTag in compound)
							{
								IBlockState state = null;
								switch (stateTag.TagType)
								{
									case NbtTagType.Byte:
										state = new BlockStateByte()
										{
											Name = stateTag.Name,
											Value = stateTag.ByteValue
										};
										break;
									case NbtTagType.Int:
										state = new BlockStateInt()
										{
											Name = stateTag.Name,
											Value = stateTag.IntValue
										};
										break;
									case NbtTagType.String:
										state = new BlockStateString()
										{
											Name = stateTag.Name,
											Value = stateTag.StringValue
										};
										break;
									default:
										throw new ArgumentOutOfRangeException();
								}
								record.States.Add(state);
							}
						}
						else if (s is NbtList list)
						{
							foreach (NbtTag stateTag in list)
							{
								IBlockState state = null;
								switch (stateTag.TagType)
								{
									case NbtTagType.Byte:
										state = new BlockStateByte()
										{
											Name = stateTag.Name,
											Value = stateTag.ByteValue
										};
										break;
									case NbtTagType.Int:
										state = new BlockStateInt()
										{
											Name = stateTag.Name,
											Value = stateTag.IntValue
										};
										break;
									case NbtTagType.String:
										state = new BlockStateString()
										{
											Name = stateTag.Name,
											Value = stateTag.StringValue
										};
										break;
									default:
										throw new ArgumentOutOfRangeException();
								}
								record.States.Add(state);
							}
						}

						result.Add(record);
					}
				}
			}
			return result;
		}