Example #1
0
        internal void AddExtension(string extName, int version)
        {
            Player p   = player;
            CpeExt ext = p.FindExtension(extName);

            if (ext == null)
            {
                return;
            }
            ext.ClientVersion = (byte)version;

            if (ext.Name == CpeExt.CustomBlocks)
            {
                if (version == 1)
                {
                    Send(Packet.CustomBlockSupportLevel(1));
                }
                p.hasCustomBlocks = true;

                p.UpdateFallbackTable();
                if (p.MaxRawBlock < Block.CPE_MAX_BLOCK)
                {
                    p.MaxRawBlock = Block.CPE_MAX_BLOCK;
                }
            }
            else if (ext.Name == CpeExt.ChangeModel)
            {
                p.hasChangeModel = true;
            }
            else if (ext.Name == CpeExt.EmoteFix)
            {
                hasEmoteFix = true;
            }
            else if (ext.Name == CpeExt.FullCP437)
            {
                p.hasCP437 = true;
            }
            else if (ext.Name == CpeExt.ExtPlayerList)
            {
                p.hasExtList = true;
            }
            else if (ext.Name == CpeExt.BlockDefinitions)
            {
                p.hasBlockDefs = true;
                if (p.MaxRawBlock < 255)
                {
                    p.MaxRawBlock = 255;
                }
            }
            else if (ext.Name == CpeExt.TextColors)
            {
                p.hasTextColors = true;
                for (int i = 0; i < Colors.List.Length; i++)
                {
                    if (!Colors.List[i].IsModified())
                    {
                        continue;
                    }
                    Send(Packet.SetTextColor(Colors.List[i]));
                }
            }
            else if (ext.Name == CpeExt.ExtEntityPositions)
            {
                p.hasExtPositions = true;
            }
            else if (ext.Name == CpeExt.TwoWayPing)
            {
                hasTwoWayPing = true;
            }
            else if (ext.Name == CpeExt.BulkBlockUpdate)
            {
                p.hasBulkBlockUpdate = true;
            }
            else if (ext.Name == CpeExt.ExtTextures)
            {
                hasExtTexs = true;
            }
            #if TEN_BIT_BLOCKS
            else if (ext.Name == CpeExt.ExtBlocks)
            {
                p.hasExtBlocks = true;
                if (p.MaxRawBlock < 767)
                {
                    p.MaxRawBlock = 767;
                }
            }
            #endif
        }
Example #2
0
        bool NegotiateProtocolExtension()
        {
            // write our ExtInfo and ExtEntry packets
            writer.Write(Packet.MakeExtInfo("ProCraft", 30).Bytes);

            writer.Write(Packet.MakeExtEntry(ClickDistanceExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(CustomBlocksExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(HeldBlockExtName, 1).Bytes);

            writer.Write(Packet.MakeExtEntry(TextHotKeyExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(ExtPlayerListExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(EnvColorsExtName, 1).Bytes);

            writer.Write(Packet.MakeExtEntry(SelectionCuboidExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(BlockPermissionsExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(ChangeModelExtName, 1).Bytes);

            writer.Write(Packet.MakeExtEntry(EnvMapAppearanceExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(EnvWeatherTypeExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(HackControlExtName, 1).Bytes);

            writer.Write(Packet.MakeExtEntry(ExtPlayerListExtName, 2).Bytes);
            writer.Write(Packet.MakeExtEntry(PlayerClickExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(MessageTypesExtName, 1).Bytes);

            writer.Write(Packet.MakeExtEntry(EmoteFixExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(LongerMessagesExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(FullCP437ExtName, 1).Bytes);

            writer.Write(Packet.MakeExtEntry(BlockDefinitionsExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(BlockDefinitionsExtExtName, 2).Bytes);
            writer.Write(Packet.MakeExtEntry(BulkBlockUpdateExtName, 1).Bytes);

            writer.Write(Packet.MakeExtEntry(TextColorsExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(EnvMapAspectExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(ExtPlayerPositionsExtName, 1).Bytes);

            writer.Write(Packet.MakeExtEntry(EntityPropertyExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(TwoWayPingExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(InventoryOrderExtName, 1).Bytes);

            writer.Write(Packet.MakeExtEntry(InstantMOTDExtName, 1).Bytes);
            writer.Write(Packet.MakeExtEntry(FastMapExtName, 1).Bytes);

            // Fix for ClassiCube Client which violates the spec -
            // If server supports version > 1 but client version 1, client should reply with version 1.
            // ClassiCube just doesn't reply at all in that case.
            writer.Write(Packet.MakeExtEntry(EnvMapAppearanceExtName, 2).Bytes);

            // Expect ExtInfo reply from the client
            OpCode extInfoReply = reader.ReadOpCode();

            //Logger.Log(LogType.Debug, "Expected: {0} / Received: {1}", OpCode.ExtInfo, extInfoReply );
            if (extInfoReply != OpCode.ExtInfo)
            {
                Logger.Log(LogType.Debug, "Player {0}: Unexpected ExtInfo reply ({1})", Info.Name, extInfoReply);
                return(false);
            }
            ClientName = reader.ReadString();
            int expectedEntries = reader.ReadInt16();

            // wait for client to send its ExtEntries
            for (int i = 0; i < expectedEntries; i++)
            {
                // Expect ExtEntry replies (0 or more)
                OpCode extEntryReply = reader.ReadOpCode();
                if (extEntryReply != OpCode.ExtEntry)
                {
                    Logger.Log(LogType.Warning, "Player {0} from {1}: Unexpected ExtEntry reply ({2})", Name, IP,
                               extInfoReply);
                    return(false);
                }
                string extName = reader.ReadString();
                int    version = reader.ReadInt32();
                CpeExt ext     = CpeExt.None;

                switch (extName)
                {
                case CustomBlocksExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.CustomBlocks;
                    }
                    break;

                case BlockPermissionsExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.BlockPermissions;
                    }
                    break;

                case ClickDistanceExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.ClickDistance;
                    }
                    break;

                case EnvColorsExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.EnvColors;
                    }
                    break;

                case ChangeModelExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.ChangeModel;
                    }
                    break;

                case EnvMapAppearanceExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.EnvMapAppearance;
                    }
                    if (version == 2)
                    {
                        ext = CpeExt.EnvMapAppearance2;
                    }
                    break;

                case EnvWeatherTypeExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.EnvWeatherType;
                    }
                    break;

                case HeldBlockExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.HeldBlock;
                    }
                    break;

                case ExtPlayerListExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.ExtPlayerList;
                        if (Supports(CpeExt.ExtPlayerList2))
                        {
                            ext = CpeExt.ExtPlayerList2;
                        }
                    }
                    else if (version == 2)
                    {
                        ext = CpeExt.ExtPlayerList2;
                        if (Supports(CpeExt.ExtPlayerList))
                        {
                            supportedExts.Remove(CpeExt.ExtPlayerList);
                        }
                    }
                    break;

                case SelectionCuboidExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.SelectionCuboid;
                    }
                    break;

                case MessageTypesExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.MessageType;
                    }
                    break;

                case HackControlExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.HackControl;
                    }
                    break;

                case EmoteFixExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.EmoteFix;
                    }
                    break;

                case TextHotKeyExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.TextHotKey;
                    }
                    break;

                case PlayerClickExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.PlayerClick;
                    }
                    break;

                case LongerMessagesExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.LongerMessages;
                    }
                    break;

                case FullCP437ExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.FullCP437;
                    }
                    break;

                case BlockDefinitionsExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.BlockDefinitions;
                    }
                    break;

                case BlockDefinitionsExtExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.BlockDefinitionsExt;
                    }
                    if (version == 2)
                    {
                        ext = CpeExt.BlockDefinitionsExt2;
                    }
                    break;

                case BulkBlockUpdateExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.BulkBlockUpdate;
                    }
                    break;

                case TextColorsExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.TextColors;
                    }
                    break;

                case EnvMapAspectExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.EnvMapAspect;
                    }
                    break;

                case ExtPlayerPositionsExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.ExtPlayerPositions;
                    }
                    supportsExtPositions = true;
                    break;

                case EntityPropertyExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.EntityProperty;
                    }
                    break;

                case TwoWayPingExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.TwoWayPing;
                    }
                    break;

                case InventoryOrderExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.InventoryOrder;
                    }
                    break;

                case InstantMOTDExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.InstantMOTD;
                    }
                    break;

                case FastMapExtName:
                    if (version == 1)
                    {
                        ext = CpeExt.FastMap;
                    }
                    break;
                }
                if (ext != CpeExt.None)
                {
                    supportedExts.Add(ext);
                }
            }
            supportsCustomBlocks = Supports(CpeExt.CustomBlocks);
            supportsBlockDefs    = Supports(CpeExt.BlockDefinitions);

            // log client's capabilities
            if (supportedExts.Count > 0)
            {
                Logger.Log(LogType.Debug, "Player {0} is using \"{1}\", supporting: {2}",
                           Info.Name, ClientName, supportedExts.JoinToString(", "));
            }
            else if (supportedExts.Count == 0)
            {
                Kick("Please use the ClassicalSharp client", LeaveReason.InvalidOpcodeKick);
            }

            // if client also supports CustomBlockSupportLevel, figure out what level to use

            // Send CustomBlockSupportLevel
            writer.Write(Packet.MakeCustomBlockSupportLevel(CustomBlocksLevel).Bytes);

            if (Supports(CpeExt.TextColors))
            {
                for (int i = 0; i < Color.ExtColors.Length; i++)
                {
                    if (Color.ExtColors[i].Undefined)
                    {
                        continue;
                    }
                    writer.Write(Packet.MakeSetTextColor(Color.ExtColors[i]).Bytes);
                }
            }

            return(true);
        }
Example #3
0
        public override bool Supports(string extName, int version = 1)
        {
            CpeExt ext = FindExtension(extName);

            return(ext != null && ext.ClientVersion == version);
        }