public static void Send(Client client, VendingMachine vendingMachine)
        {
            PacketWriter packetWriter = new PacketWriter();

            packetWriter.PushByte(0xdf);
            packetWriter.PushByte(0xdf);
            packetWriter.PushShort(0xa);
            packetWriter.PushShort(1);
            packetWriter.PushShort(0);
            packetWriter.PushInt(3086);
            packetWriter.PushInt(client.Character.Id);
            packetWriter.PushInt(0x7f544905); // 20
            packetWriter.PushIdentity(vendingMachine.Type, vendingMachine.Id);
            packetWriter.PushByte(0);
            packetWriter.PushInt(0xb); // Counter??
            packetWriter.PushInt(0);
            packetWriter.PushInt(0); // 41
            packetWriter.PushCoord(vendingMachine.Coordinates);
            packetWriter.PushQuat(vendingMachine.Heading); // 69
            packetWriter.PushInt(vendingMachine.PlayField);
            packetWriter.PushInt(1000015);
            packetWriter.PushInt(0);
            packetWriter.PushShort(0x6f);
            packetWriter.PushInt(0x2379);
            packetWriter.PushInt(0); // 91
            packetWriter.PushByte(0x80);
            packetWriter.PushByte(2);
            packetWriter.PushShort(0x3603);
            packetWriter.PushInt(0x17);
            packetWriter.PushInt(vendingMachine.TemplateId);
            packetWriter.PushInt(0x2bd);
            packetWriter.PushInt(0); // 111
            packetWriter.PushInt(0x2be);
            packetWriter.PushInt(0);
            packetWriter.PushInt(0x2bf);
            packetWriter.PushInt(0);
            packetWriter.PushInt(0x19c); // 131
            packetWriter.PushInt(1);
            packetWriter.PushInt(0x1f5);
            packetWriter.PushInt(2);
            packetWriter.PushInt(0x1f4);
            packetWriter.PushInt(0);
            packetWriter.PushInt(0);
            packetWriter.PushInt(2);
            packetWriter.PushInt(0x32); // 147
            packetWriter.Push3F1Count(0);
            packetWriter.PushInt(3); // 155<

            byte[] packet = packetWriter.Finish();
            client.SendCompressed(packet);
        }
예제 #2
0
파일: Client.cs 프로젝트: semirs/CellAO
        /// <summary>
        /// 
        /// </summary>
        /// <param name="destination"></param>
        /// <param name="heading"></param>
        /// <param name="playfield"></param>
        /// <returns></returns>
        public bool TeleportProxy(
            AOCoord destination,
            Quaternion heading,
            int playfield,
            Identity pfinstance,
            int GS,
            int SG,
            Identity R,
            Identity dest)
        {
            PacketWriter writer = new PacketWriter();
            // header starts
            writer.PushByte(0xDF);
            writer.PushByte(0xDF);
            writer.PushShort(10);
            writer.PushShort(1);
            writer.PushShort(0);
            writer.PushInt(3086);
            writer.PushInt(this.Character.Id);
            writer.PushInt(0x43197D22);
            writer.PushIdentity(50000, this.Character.Id);
            writer.PushByte(0);
            // Header ends
            writer.PushCoord(this.Character.RawCoord);
            writer.PushQuat(this.Character.RawHeading);
            writer.PushByte(97);
            writer.PushIdentity(pfinstance.Type, pfinstance.Instance);
            writer.PushInt(GS);
            writer.PushInt(SG);
            writer.PushIdentity(40016, playfield);
            // Dont know for sure if its correct to only transfer the playfield here
            writer.PushInt(0);
            writer.PushInt(0);
            writer.PushIdentity(dest.Type, dest.Instance);
            writer.PushInt(0);
            byte[] tpreply = writer.Finish();
            this.Character.DoNotDoTimers = true;
            Despawn.DespawnPacket(this.Character.Id);
            this.SendCompressed(tpreply);
            this.Character.DoNotDoTimers = true;
            this.Character.Stats.LastConcretePlayfieldInstance.Value = this.Character.PlayField;
            this.Character.Stats.ExtenalDoorInstance.Value = SG;

            this.Character.StopMovement();
            this.Character.RawCoord = destination;
            this.Character.RawHeading = heading;
            this.Character.PlayField = playfield;
            this.Character.Resource = 0x3c000;
            this.Character.Purge(); // Purge character information to DB before client reconnect

            IPAddress tempIP;
            if (IPAddress.TryParse(Config.Instance.CurrentConfig.ZoneIP, out tempIP) == false)
            {
                IPHostEntry zoneHost = Dns.GetHostEntry(Config.Instance.CurrentConfig.ZoneIP);
                foreach (IPAddress ip in zoneHost.AddressList)
                {
                    if (ip.AddressFamily == AddressFamily.InterNetwork)
                    {
                        tempIP = ip;
                        break;
                    }
                }
            }
            int zoneIP = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(tempIP.GetAddressBytes(), 0));
            short zonePort = Convert.ToInt16(Config.Instance.CurrentConfig.ZonePort);

            Thread.Sleep(1000);

            PacketWriter writer2 = new PacketWriter();
            writer2.PushByte(0xDF);
            writer2.PushByte(0xDF);
            writer2.PushShort(1);
            writer2.PushShort(1);
            writer2.PushShort(0);
            writer2.PushInt(3086);
            writer2.PushInt(this.Character.Id);
            writer2.PushInt(60);
            writer2.PushInt(zoneIP);
            writer2.PushShort(zonePort);
            byte[] connect = writer2.Finish();
            this.SendCompressed(connect);
            return true;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="character"></param>
        /// <param name="receiver"></param>
        /// <returns></returns>
        public static Byte[] WritePacket(Character character, int receiver)
        {
            /*
             * To set a packetFlag use       packetFlags |= <flagHere>;
             * To unset a packetFlag use     packetFlags &= ~<flagHere>;
             * 
             * Wherever you set a flag conditionally, be sure to unset the same flag if the reverse
             * condition is true 'just in case'.
             */
            int packetFlags = 0; // Try setting to 0x042062C8 if you have problems (old value)

            //
            // Character Variables

            bool socialonly;
            bool showsocial;
            /*
            bool showhelmet;
            bool LeftPadVisible;
            bool RightPadVisible;
            bool DoubleLeftPad;
            bool DoubleRightPad;
            */

            int charPlayfield;
            AOCoord charCoord;
            int charId;
            Quaternion charHeading;

            uint sideValue;
            uint fatValue;
            uint breedValue;
            uint sexValue;
            uint raceValue;

            int nameLength;
            string charName;
            int charFlagsValue;
            int accFlagsValue;

            int expansionValue;
            int currentNano;
            int currentHealth;

            uint strengthBaseValue;
            uint staminaBaseValue;
            uint agilityBaseValue;
            uint senseBaseValue;
            uint intelligenceBaseValue;
            uint psychicBaseValue;

            int firstNameLength;
            int lastNameLength;
            string firstName;
            string lastName;
            int orgNameLength;
            string orgName;
            int levelValue;
            int healthValue;
            int losHeight;

            int monsterData;
            int monsterScale;
            int visualFlags;

            int currentMovementMode;
            uint runSpeedBaseValue;

            int texturesCount;
            /*
            int HairMeshValue;
            int WeaponMeshRightValue;
            int WeaponMeshLeftValue;

            uint HeadMeshBaseValue;
             */
            int headMeshValue;
            /*
            int BackMeshValue;
            int ShoulderMeshRightValue;
             */
            //int ShoulderMeshLeftValue;

            /*
            int OverrideTextureHead;
            int OverrideTextureWeaponRight;
            int OverrideTextureWeaponLeft;
            int OverrideTextureShoulderpadRight;
            int OverrideTextureShoulderpadLeft;
            int OverrideTextureBack;
            int OverrideTextureAttractor;
            */
            //NPC Values

            int NPCFamily;

            Dictionary<int, int> socialTab = new Dictionary<int, int>();

            List<AOTextures> textures = new List<AOTextures>();

            List<AOMeshs> meshs;

            List<AONano> nanos = new List<AONano>();

            lock (character)
            {
                socialonly = ((character.Stats.VisualFlags.Value & 0x40) > 0);
                showsocial = ((character.Stats.VisualFlags.Value & 0x20) > 0);
                /*
                showhelmet = ((character.Stats.VisualFlags.Value & 0x4) > 0);
                LeftPadVisible = ((character.Stats.VisualFlags.Value & 0x1) > 0);
                RightPadVisible = ((character.Stats.VisualFlags.Value & 0x2) > 0);
                DoubleLeftPad = ((character.Stats.VisualFlags.Value & 0x8) > 0);
                DoubleRightPad = ((character.Stats.VisualFlags.Value & 0x10) > 0);
                */

                charPlayfield = character.PlayField;
                charCoord = character.Coordinates;
                charId = character.Id;
                charHeading = character.Heading;

                sideValue = character.Stats.Side.StatBaseValue;
                fatValue = character.Stats.Fatness.StatBaseValue;
                breedValue = character.Stats.Breed.StatBaseValue;
                sexValue = character.Stats.Sex.StatBaseValue;
                raceValue = character.Stats.Race.StatBaseValue;

                nameLength = character.Name.Length;
                charName = character.Name;
                charFlagsValue = character.Stats.Flags.Value;
                accFlagsValue = character.Stats.AccountFlags.Value;

                expansionValue = character.Stats.Expansion.Value;
                currentNano = character.Stats.CurrentNano.Value;

                strengthBaseValue = character.Stats.Strength.StatBaseValue;
                staminaBaseValue = character.Stats.Strength.StatBaseValue;
                agilityBaseValue = character.Stats.Strength.StatBaseValue;
                senseBaseValue = character.Stats.Strength.StatBaseValue;
                intelligenceBaseValue = character.Stats.Strength.StatBaseValue;
                psychicBaseValue = character.Stats.Strength.StatBaseValue;

                firstNameLength = character.FirstName.Length;
                lastNameLength = character.LastName.Length;
                firstName = character.FirstName;
                lastName = character.LastName;
                orgNameLength = character.OrgName.Length;
                orgName = character.OrgName;
                levelValue = character.Stats.Level.Value;
                healthValue = character.Stats.Life.Value;

                monsterData = character.Stats.MonsterData.Value;
                monsterScale = character.Stats.MonsterScale.Value;
                visualFlags = character.Stats.VisualFlags.Value;

                currentMovementMode = character.Stats.CurrentMovementMode.Value;
                runSpeedBaseValue = character.Stats.RunSpeed.StatBaseValue;

                texturesCount = character.Textures.Count;
                /*
                HairMeshValue = character.Stats.HairMesh.Value;
                WeaponMeshRightValue = character.Stats.WeaponMeshRight.Value;
                WeaponMeshLeftValue = character.Stats.WeaponMeshLeft.Value;

                HeadMeshBaseValue = character.Stats.HeadMesh.StatBaseValue;
                 */
                headMeshValue = character.Stats.HeadMesh.Value;
                /*
                BackMeshValue = character.Stats.BackMesh.Value;
                ShoulderMeshRightValue = character.Stats.ShoulderMeshRight.Value;
                 */
                //ShoulderMeshLeftValue = character.Stats.ShoulderMeshLeft.Value;
                /*
                OverrideTextureHead = character.Stats.OverrideTextureHead.Value;
                OverrideTextureWeaponRight = character.Stats.OverrideTextureWeaponRight.Value;
                OverrideTextureWeaponLeft = character.Stats.OverrideTextureWeaponLeft.Value;
                OverrideTextureShoulderpadRight = character.Stats.OverrideTextureShoulderpadRight.Value;
                OverrideTextureShoulderpadLeft = character.Stats.OverrideTextureShoulderpadLeft.Value;
                OverrideTextureBack = character.Stats.OverrideTextureBack.Value;
                OverrideTextureAttractor = character.Stats.OverrideTextureAttractor.Value;
                 */
                foreach (int num in character.SocialTab.Keys)
                {
                    socialTab.Add(num, character.SocialTab[num]);
                }

                foreach (AOTextures at in character.Textures)
                {
                    textures.Add(new AOTextures(at.place, at.Texture));
                }

                meshs = MeshLayers.GetMeshs(character, showsocial, socialonly);

                foreach (AONano nano in character.ActiveNanos)
                {
                    AONano tempNano = new AONano();
                    tempNano.ID = nano.ID;
                    tempNano.Instance = nano.Instance;
                    tempNano.NanoStrain = nano.NanoStrain;
                    tempNano.Nanotype = nano.Nanotype;
                    tempNano.Time1 = nano.Time1;
                    tempNano.Time2 = nano.Time2;
                    tempNano.Value3 = nano.Value3;

                    nanos.Add(tempNano);
                }

                losHeight = character.Stats.LosHeight.Value;
                NPCFamily = character.Stats.NpcFamily.Value;
                currentHealth = character.Stats.Health.Value;
            }
            PacketWriter packetWriter = new PacketWriter();

            // Packet Header
            packetWriter.PushByte(0xDF);
            packetWriter.PushByte(0xDF);
            packetWriter.PushShort(10);
            packetWriter.PushShort(1);
            packetWriter.PushShort(0); // length. writer will take care of this
            packetWriter.PushInt(3086); // sender. our server ID
            packetWriter.PushInt(receiver); // receiver
            packetWriter.PushInt(0x271B3A6B); // packet ID
            packetWriter.PushIdentity(50000, charId); // affected identity
            packetWriter.PushByte(0); // Unknown?
            // End Packet Header

            packetWriter.PushByte(57); // SCFU packet version (57/0x39)
            packetWriter.PushInt(0); // packet flags (this is set later based on packetFlags variable above)

            packetFlags |= 0x40; // Has Playfield ID
            packetWriter.PushInt(charPlayfield); // playfield

            if (character.FightingTarget.Instance != 0)
            {
                packetFlags |= 20;
                packetWriter.PushIdentity(character.FightingTarget);
            }

            // Coordinates
            packetWriter.PushCoord(charCoord);

            // Heading Data
            packetFlags |= 0x200; // Has Heading Data Flag
            packetWriter.PushQuat(charHeading);

            uint appearance = sideValue + (fatValue * 8) + (breedValue * 32) + (sexValue * 256) + (raceValue * 1024);
            // Race
            packetWriter.PushUInt(appearance); // appearance

            // Name
            packetWriter.PushByte((byte)(nameLength + 1));
            packetWriter.PushBytes(Encoding.ASCII.GetBytes(charName));
            packetWriter.PushByte(0); // 0 terminator for name

            packetWriter.PushUInt(charFlagsValue); // Flags
            packetWriter.PushShort((short)accFlagsValue);
            packetWriter.PushShort((short)expansionValue);

            if (character is NonPlayerCharacterClass)
            {
                packetFlags |= 1;
            }

            packetFlags &= ~0x01; // We are a player
            if ((packetFlags & 0x01) != 0)
            {
                // Are we a NPC (i think anyway)? So far this is _NOT_ used at all

                if (NPCFamily < 256)
                {
                    packetWriter.PushByte((byte)NPCFamily);
                }
                else
                {
                    packetFlags |= 0x20000;
                    packetWriter.PushShort((Int16)NPCFamily);
                }

                if (losHeight < 256)
                {
                    packetWriter.PushByte((byte)losHeight);
                }
                else
                {
                    packetFlags |= 0x80000;
                    packetWriter.PushShort((Int16)losHeight);
                }

                //if (packetFlags & 0x2000000)
                //{
                //    char PetType;
                //}
                //else
                //{
                //    short PetType;
                //}

                //short TowerType;

                //if (TowerType > 0)
                //{
                //    char unknown;
                //}
            }
            else
            {
                // Are we a player?
                packetWriter.PushUInt(currentNano); // CurrentNano
                packetWriter.PushInt(0); // team?
                packetWriter.PushShort(5); // swim?

                // The checks here are to prevent the client doing weird things if the character has really large or small base attributes
                if (strengthBaseValue > 32767) // Strength
                {
                    packetWriter.PushShort(32767);
                }
                else
                {
                    packetWriter.PushShort((short)strengthBaseValue);
                }
                if (agilityBaseValue > 32767) // Agility
                {
                    packetWriter.PushShort(32767);
                }
                else
                {
                    packetWriter.PushShort((short)agilityBaseValue);
                }
                if (staminaBaseValue > 32767) //  Stamina
                {
                    packetWriter.PushShort(32767);
                }
                else
                {
                    packetWriter.PushShort((short)staminaBaseValue);
                }
                if (intelligenceBaseValue > 32767) // Intelligence
                {
                    packetWriter.PushShort(32767);
                }
                else
                {
                    packetWriter.PushShort((short)intelligenceBaseValue);
                }
                if (senseBaseValue > 32767) // Sense
                {
                    packetWriter.PushShort(32767);
                }
                else
                {
                    packetWriter.PushShort((short)senseBaseValue);
                }
                if (psychicBaseValue > 32767) // Psychic
                {
                    packetWriter.PushShort(32767);
                }
                else
                {
                    packetWriter.PushShort((short)psychicBaseValue);
                }

                if ((charFlagsValue & 0x400000) != 0) // has visible names? (Flags)
                {
                    packetWriter.PushShort((short)firstNameLength);
                    packetWriter.PushBytes(Encoding.ASCII.GetBytes(firstName));
                    packetWriter.PushShort((short)lastNameLength);
                    packetWriter.PushBytes(Encoding.ASCII.GetBytes(lastName));
                }

                if (orgNameLength != 0)
                {
                    packetFlags |= 0x4000000; // Has org name data

                    packetWriter.PushShort((short)orgNameLength);
                    packetWriter.PushBytes(Encoding.ASCII.GetBytes(orgName));
                }
                else
                {
                    packetFlags &= ~0x4000000; // Does not have org name data
                }
            }

            if (levelValue > 127) // Level
            {
                packetFlags |= 0x1000; // Has Extended Level
                packetWriter.PushShort((short)levelValue);
            }
            else
            {
                packetFlags &= ~0x1000; // Has Small Level
                packetWriter.PushByte((byte)levelValue);
            }

            if (healthValue > 32767) // Health
            {
                packetFlags &= ~0x800; // Has Extended Health
                packetWriter.PushUInt(healthValue);
            }
            else
            {
                packetFlags |= 0x800; // Has Small Health
                packetWriter.PushShort((short)healthValue);
            }
            int healthdamage = healthValue - currentHealth;
            if (healthdamage < 256)
            {
                packetFlags |= 0x4000;
                packetWriter.PushByte((byte)healthdamage);
            }
            else
            {
                packetFlags &= ~0x4000;
                if ((packetFlags & 0x800) == 0x800)
                {
                    packetWriter.PushShort((Int16)healthdamage);
                }
                else
                {
                    packetWriter.PushInt(healthdamage);
                }
            }

            // If player is in grid or fixer grid
            // make him/her/it a nice upside down pyramid
            if ((charPlayfield == 152) || (charPlayfield == 4107))
            {
                packetWriter.PushInt(99902);
            }
            else
            {
                packetWriter.PushUInt(monsterData); // Monsterdata
            }
            packetWriter.PushShort((short)monsterScale); // Monsterscale
            packetWriter.PushShort((short)visualFlags); // VisualFlags
            packetWriter.PushByte(0); // visible title?

            packetWriter.PushInt(42); // 'skipdata' length
            // Start 'skipdata'
            packetWriter.PushBytes(
                new Byte[] { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00 });
            packetWriter.PushByte((byte)currentMovementMode); // CurrentMovementMode
            packetWriter.PushByte(1); // don't change
            packetWriter.PushShort(1); // ?
            packetWriter.PushShort(1); // ?
            packetWriter.PushShort(1); // ?
            packetWriter.PushShort(1); // ?
            packetWriter.PushShort(0); // ?
            packetWriter.PushShort(3); // ?
            packetWriter.PushInt(0); //?
            packetWriter.PushInt(0); //?
            packetWriter.PushInt(0); //?
            packetWriter.PushInt(0); //?
            // End 'skipdata'

            if (headMeshValue != 0)
            {
                packetFlags |= 0x80; // Has HeadMesh Flag
                packetWriter.PushUInt(headMeshValue); // Headmesh
            }

            if ((runSpeedBaseValue > 127)) // Runspeed
            {
                packetFlags |= 0x2000;
                packetWriter.PushShort((short)runSpeedBaseValue);
            }
            else
            {
                packetFlags &= ~0x2000;
                packetWriter.PushByte((byte)runSpeedBaseValue);
            }

            //if (packetFlags & 0x400)
            //{
            //    // Pop2Long
            //    /*
            //     * Is this a Type:Instance pair?
            //     * Suspect so as it uses Pop2Long
            //     * which is used for Type:Instance
            //     * pairs. Perhaps pet master?
            //     * (Just a wild guess though that its pet master)
            //     */
            //    long unknown;
            //    long unknown;
            //}

            //if (packetFlags & 0x10)
            //{
            //    long counter;
            //    repeat (counter / 0x3F1 - 1) times
            //        char texturepositionname[32]; // Null padded at the end
            //        long textureid; // Or is this mesh id?
            //        long unknown;
            //        long unknown;
            //    end repeat
            //}

            // Is char/NPC in hide mode?
            //if (packetFlags & 0x100000)
            //{
            //    short Concealment;
            //}

            //if (packetFlags & 0x800000)
            //{
            //    char unknown;
            //}

            //if (packetFlags & 0x1000000)
            //{
            //    char unknown;
            //}

            packetWriter.Push3F1Count(nanos.Count); // running nanos count
            foreach (AONano nano in nanos)
            {
                packetWriter.PushInt(nano.ID);
                packetWriter.PushInt(nano.Instance);
                packetWriter.PushInt(nano.Time1);
                packetWriter.PushInt(nano.Time2);
            }
            // longx5: aoid, instance, unknown(0?), timer1, timer2

            //if (flags & 0x10000)
            //{
            //    // Waypoint Info
            //    // Pop2Long (1010E2D3)
            //    long type;
            //    long instance;
            //    // Waypoint Counter - 3x float per entry
            //    long counter;
            //    repeat counter times
            //        float x;
            //        float y;
            //        float z;
            //    end repeat
            //    // End Waypoint Counter
            //}

            // Texture/Cloth Data
            int c;
            packetWriter.Push3F1Count(5); // textures count

            AOTextures aotemp = new AOTextures(0, 0);
            for (c = 0; c < 5; c++)
            {
                aotemp.Texture = 0;
                aotemp.place = c;
                int c2;
                for (c2 = 0; c2 < texturesCount; c2++)
                {
                    if (textures[c2].place == c)
                    {
                        aotemp.Texture = textures[c2].Texture;
                        break;
                    }
                }
                if (showsocial)
                {
                    if (socialonly)
                    {
                        aotemp.Texture = socialTab[c];
                    }
                    else
                    {
                        if (socialTab[c] != 0)
                        {
                            aotemp.Texture = socialTab[c];
                        }
                    }
                }

                packetWriter.PushInt(aotemp.place);
                packetWriter.PushInt(aotemp.Texture);
                packetWriter.PushInt(0);
            }
            // End Textures

            // ############
            // # Meshs
            // ############

            c = meshs.Count;

            packetWriter.Push3F1Count(c);
            foreach (AOMeshs aoMeshs in meshs)
            {
                packetWriter.PushByte((byte)aoMeshs.Position);
                packetWriter.PushUInt(aoMeshs.Mesh);
                packetWriter.PushInt(aoMeshs.OverrideTexture); // Override Texture!!!!!!
                packetWriter.PushByte((byte)aoMeshs.Layer);
            }
            // End Meshs

            //if (packetFlags & 0x100)
            //{
            //    // 0x3F1 Unknown Counter - 4x long per entry
            //    long counter;
            //    repeat (counter / 0x3F1 - 1) times
            //        long unknown;
            //        long unknown;
            //        long unknown;
            //        long unknown;
            //    end repeat
            //}

            //if (packetFlags & 0x20000000)
            //{
            //    char ShadowBreed;
            //}

            //if (packetFlags & 0x40000000)
            //{
            //    // 0x3F1 Unknown Counter - 4x long per entry
            //    long counter;
            //    repeat (counter / 0x3F1 - 1) times
            //        Pop2Long (Type:Instance pair maybe?)
            //        long unknown;
            //        long unknown;
            //    end repeat
            //}

            packetWriter.PushInt(0); // packetFlags2

            // Some mech stuff
            //if (packetFlags2 & 0x01)
            //{
            //    long counter;
            //    repeat (counter) times
            //        long unknown;
            //        long unknown;
            //    end repeat

            //    long MechData;
            //    // Pop2Long (Type:Instance pair maybe?)
            //    long unknown;
            //    long unknown;
            //}

            // maybe check if we are in battlestation
            //if (packetFlags2 & 0x02)
            //{
            //    char BattleStationSide;
            //}

            // Are we a pet?
            //if (packetFlags2 & 0x04)
            //{
            //    long PetMaster;
            //}

            packetWriter.PushByte(0);

            Byte[] reply = packetWriter.Finish();

            // Set Packet Flags
            Byte[] packetFlagBytes;
            packetFlagBytes = BitConverter.GetBytes(packetFlags);
            Array.Reverse(packetFlagBytes);
            reply[30] = packetFlagBytes[0];
            reply[31] = packetFlagBytes[1];
            reply[32] = packetFlagBytes[2];
            reply[33] = packetFlagBytes[3];

            return reply;
        }
        public static void SpawnNpcToClient(
            NonPlayerCharacterClass nonPlayerCharacter, Client targetClient, bool wholePlayfield)
        {
            int unknown1 = 0;
            int unknown2 = 0;
            int unknown3 = 0;
            PacketWriter spawn = new PacketWriter();
            int counter;
            int packetflags = 0x0001; // We want to spawn a NPC
            packetflags |= 0x0200; // Heading flag
            packetflags |= 0x0040; // packet has playfield
            packetflags |= 0x1000; // push level as 2 byte
            //            if (mob.Stats.GetStat(466) <= 255)
            {
                packetflags |= 0x80000; // LOS Height 1 byte
            }

            if (nonPlayerCharacter.Attacking != 0)
            {
                packetflags |= 0x400;
            }

            packetflags |= 0x2000000;
            packetflags |= 0x0200000;
            packetflags |= 0x0000002;

            spawn.PushByte(0xDF);
            spawn.PushByte(0xDF);
            spawn.PushShort(10);
            spawn.PushShort(1);
            spawn.PushShort(0); // Length, packetwriter will take care of this
            spawn.PushInt(3086);
            if (targetClient == null)
            {
                spawn.PushInt(0); // will be sent to whole playfield
            }
            else
            {
                spawn.PushInt(targetClient.Character.Id);
            }
            spawn.PushInt(0x271B3A6B);
            spawn.PushIdentity(50000, nonPlayerCharacter.Id);
            spawn.PushByte(0);
            spawn.PushByte(0x39); // version 0x39
            spawn.PushInt(packetflags); // packetflags
            spawn.PushInt(nonPlayerCharacter.PlayField);
            spawn.PushCoord(nonPlayerCharacter.Coordinates);
            spawn.PushQuat(nonPlayerCharacter.Heading);
            // Side, Fatness, Breed, Sex, Race
            //   33,      47,     4,  59,    89
            spawn.PushUInt(
                nonPlayerCharacter.Stats.Side.Value + (nonPlayerCharacter.Stats.Fatness.Value * 8)
                + (nonPlayerCharacter.Stats.Breed.Value * 32) + (nonPlayerCharacter.Stats.Sex.Value * 256)
                + (nonPlayerCharacter.Stats.Race.Value * 1024));
            spawn.PushByte((byte)(nonPlayerCharacter.Name.Length + 1));
            spawn.PushBytes(Encoding.ASCII.GetBytes(nonPlayerCharacter.Name));
            spawn.PushByte(0);
            spawn.PushUInt(nonPlayerCharacter.Stats.Flags.Value);
            spawn.PushShort(0); // AccountFlags
            spawn.PushShort(0); // Expansion
            if (nonPlayerCharacter.Stats.NpcFamily.Value <= 255) // NPCFamily
            {
                packetflags |= 0x20000; // NPC Family 1 byte
                spawn.PushByte((byte)nonPlayerCharacter.Stats.NpcFamily.Value);
            }
            else
            {
                packetflags &= ~0x20000; // NPC Family 2 byte
                spawn.PushShort((short)nonPlayerCharacter.Stats.NpcFamily.Value);
            }

            spawn.PushByte(0);
            spawn.PushByte(0);
            spawn.PushShort(0);

            // TODO: set packetflag for levelsize
            spawn.PushShort((short)nonPlayerCharacter.Stats.Level.Value); // 54 = Level

            // TODO: set packetflag for Healthsize/damagesize
            spawn.PushUInt(nonPlayerCharacter.Stats.Life.Value); // 1 = Life (max HP)
            spawn.PushUInt(nonPlayerCharacter.Stats.Health.Value);
                // 27 = Health left?? (same Size as Health, flag for 1byte not set)

            // If NPC is in grid or fixer grid
            // make him look like nice upside down pyramid
            if ((nonPlayerCharacter.PlayField == 152) || (nonPlayerCharacter.PlayField == 4107))
            {
                spawn.PushInt(99902);
            }
            else
            {
                spawn.PushUInt(nonPlayerCharacter.Stats.MonsterData.Value); // 359=Monsterdata
            }

            spawn.PushShort((short)nonPlayerCharacter.Stats.MonsterScale.Value); // 360 = monsterscale
            spawn.PushShort(0x1F); // VisualFlags
            spawn.PushByte(0); // Visible title?
            spawn.PushInt(0x1C);
            spawn.PushInt(unknown1); // KnuBot values?
            spawn.PushInt(unknown2);
            spawn.PushInt(unknown3);

            // TODO: Movement Modes
            spawn.PushByte(1); // CurrentMovementMode
            spawn.PushByte(1); // Don't change
            spawn.PushShort(1);
            spawn.PushShort(1);
            spawn.PushShort(1);
            spawn.PushShort(1);
            spawn.PushShort(0);
            spawn.PushShort(2);
            spawn.PushShort(0);

            if (nonPlayerCharacter.Stats.HeadMesh.Value != 0) // 64 = headmesh
            {
                packetflags |= 0x80;
                spawn.PushUInt(nonPlayerCharacter.Stats.HeadMesh.Value);
            }

            // TODO: runspeedsize+flag
            if (nonPlayerCharacter.Stats.RunSpeed.Value > 255)
            {
                packetflags |= 0x2000;
                spawn.PushShort((short)nonPlayerCharacter.Stats.RunSpeed.Value); // 156 = RunSpeed
            }
            else
            {
                spawn.PushByte((byte)nonPlayerCharacter.Stats.RunSpeed.Value); // 156 = RunSpeed
            }

            if (nonPlayerCharacter.Attacking != 0)
            {
                spawn.PushInt(0xc350);
                spawn.PushInt(nonPlayerCharacter.Attacking);
            }

            if (nonPlayerCharacter.Meshs.Count > 0)
            {
                packetflags |= 0x10; // Meshs on mob
                spawn.Push3F1Count(nonPlayerCharacter.Meshs.Count);
                for (counter = 0; counter < nonPlayerCharacter.Meshs.Count; counter++)
                {
                    // Name for meshtemplate not needed, sending 32byte 00 instead, thx to Suiv
                    int counter2;
                    for (counter2 = 0; counter2 < 8; counter2++)
                    {
                        spawn.PushInt(0);
                    }
                    spawn.PushInt(nonPlayerCharacter.Meshs[counter].Position);
                    spawn.PushInt(nonPlayerCharacter.Meshs[counter].Mesh);
                    spawn.PushInt(nonPlayerCharacter.Meshs[counter].OverrideTexture);
                }
            }

            // Running Nanos/Nano Effects
            spawn.Push3F1Count(nonPlayerCharacter.ActiveNanos.Count);
            for (counter = 0; counter < nonPlayerCharacter.ActiveNanos.Count; counter++)
            {
                spawn.PushInt(nonPlayerCharacter.ActiveNanos[counter].Nanotype);
                spawn.PushInt(nonPlayerCharacter.ActiveNanos[counter].Instance);
                spawn.PushInt(nonPlayerCharacter.ActiveNanos[counter].Value3);
                spawn.PushInt(nonPlayerCharacter.ActiveNanos[counter].Time1);
                spawn.PushInt(nonPlayerCharacter.ActiveNanos[counter].Time2);
            }

            // Waypoints
            if (nonPlayerCharacter.Waypoints.Count > 0)
            {
                packetflags |= 0x10000; // Waypoints
                spawn.PushInt(0xc350);
                spawn.PushInt(nonPlayerCharacter.Id);
                spawn.Push3F1Count(nonPlayerCharacter.Waypoints.Count); // Waypoints
                for (counter = 0; counter < nonPlayerCharacter.Waypoints.Count; counter++)
                {
                    spawn.PushCoord(nonPlayerCharacter.Waypoints[counter]);
                }
            }

            // Textures have to be rewritten too
            // mobs should get a equip table
            // and get the textures from the equipped items

            spawn.Push3F1Count(nonPlayerCharacter.Textures.Count); // Texture count (should be 5 at all times iirc)
            int c;
            for (c = 0; c < nonPlayerCharacter.Textures.Count; c++)
            {
                spawn.PushInt(nonPlayerCharacter.Textures[c].place);
                spawn.PushInt(nonPlayerCharacter.Textures[c].Texture);
                spawn.PushInt(0);
            }

            // same as texture part, equip table should define the additional meshs
            // data could be stored with the item entries

            int addmeshs = 0;
            if (nonPlayerCharacter.Stats.WeaponMeshRight.Value != 0)
            {
                addmeshs++;
            }
            if (nonPlayerCharacter.Stats.WeaponMeshLeft.Value != 0)
            {
                addmeshs++;
            }
            if (nonPlayerCharacter.Stats.HeadMesh.Value != 0)
            {
                addmeshs++;
            }
            if (nonPlayerCharacter.Stats.BackMesh.Value != 0)
            {
                addmeshs++;
            }
            if (nonPlayerCharacter.Stats.ShoulderMeshRight.Value != 0)
            {
                addmeshs++;
            }
            if (nonPlayerCharacter.Stats.ShoulderMeshLeft.Value != 0)
            {
                addmeshs++;
            }
            if (nonPlayerCharacter.Stats.HairMesh.Value != 0)
            {
                addmeshs++;
            }
            //            if (mob.Stats.GetStat(42) != 0) // 42 = CATMesh, what is this?
            //                addmeshs++;
            if (nonPlayerCharacter.Stats.HairMesh.Value != 0)
            {
                addmeshs++;
            }

            spawn.Push3F1Count(addmeshs);
            if (addmeshs > 0)
            {
                // 0 head, 1 r_hand, 2 l_hand, 3 r_shoulder, 4 l_shoulder, 5 back, 6 hip, 7 r_thigh, 8 l_thigh, 9 r_crus, 10 l_crus, 11 r_arm, 12 l_arm, 13 r_forearm, 14 l_forearm
                if (nonPlayerCharacter.Stats.HeadMesh.Value != 0)
                {
                    spawn.PushByte(0);
                    spawn.PushUInt(nonPlayerCharacter.Stats.HeadMesh.Value);
                    spawn.PushInt(0);
                    spawn.PushByte(4);
                }
                if (nonPlayerCharacter.Stats.WeaponMeshRight.Value != 0)
                {
                    spawn.PushByte(1); // Position
                    spawn.PushUInt(nonPlayerCharacter.Stats.WeaponMeshRight.Value); // Mesh ID
                    spawn.PushInt(0); // Unknown
                    spawn.PushByte(4); // Priority
                }
                if (nonPlayerCharacter.Stats.WeaponMeshLeft.Value != 0)
                {
                    spawn.PushByte(2); // Position
                    spawn.PushUInt(nonPlayerCharacter.Stats.WeaponMeshLeft.Value); // Mesh ID
                    spawn.PushInt(0); // Unknown
                    spawn.PushByte(4); // Priority
                }
                if (nonPlayerCharacter.Stats.ShoulderMeshRight.Value != 0)
                {
                    spawn.PushByte(3);
                    spawn.PushUInt(nonPlayerCharacter.Stats.ShoulderMeshRight.Value);
                    spawn.PushInt(0);
                    spawn.PushByte(4);
                }
                if (nonPlayerCharacter.Stats.ShoulderMeshLeft.Value != 0)
                {
                    spawn.PushByte(4);
                    spawn.PushUInt(nonPlayerCharacter.Stats.ShoulderMeshLeft.Value);
                    spawn.PushInt(0);
                    spawn.PushByte(4);
                }
                if (nonPlayerCharacter.Stats.BackMesh.Value != 0)
                {
                    spawn.PushByte(5);
                    spawn.PushUInt(nonPlayerCharacter.Stats.BackMesh.Value);
                    spawn.PushInt(0);
                    spawn.PushByte(4);
                }
                if (nonPlayerCharacter.Stats.HairMesh.Value != 0)
                {
                    spawn.PushByte(0);
                    spawn.PushUInt(nonPlayerCharacter.Stats.HairMesh.Value);
                    spawn.PushInt(0);
                    spawn.PushByte(2); // Hairmesh is prio 2?
                }
                /*                if (mob.Stats.GetStat(20001) != 0)
                {
                    spawn.PushByte(0);
                    spawn.PushUInt(mob.Stats.GetStat(20001));
                    spawn.PushInt(0);
                    spawn.PushByte(0); // Attractor Mesh prio = 0
                }
 */
            }

            if (nonPlayerCharacter.Weaponpairs.Count > 0)
            {
                spawn.Push3F1Count(nonPlayerCharacter.Weaponpairs.Count);
                for (counter = 0; counter < nonPlayerCharacter.Weaponpairs.Count; counter++)
                {
                    spawn.PushInt(nonPlayerCharacter.Weaponpairs[counter].value1);
                    spawn.PushInt(nonPlayerCharacter.Weaponpairs[counter].value2);
                    spawn.PushInt(nonPlayerCharacter.Weaponpairs[counter].value3);
                    spawn.PushInt(nonPlayerCharacter.Weaponpairs[counter].value4);
                }
            }
            // Finishing output with 5byte 00
            spawn.PushInt(0);
            spawn.PushByte(0);

            byte[] spawnReply = spawn.Finish();

            // setting the packetflags
            spawnReply[30] = (byte)((packetflags >> 24) & 0xff);
            spawnReply[31] = (byte)((packetflags >> 16) & 0xff);
            spawnReply[32] = (byte)((packetflags >> 8) & 0xff);
            spawnReply[33] = (byte)(packetflags & 0xff);

            if (wholePlayfield)
            {
                Announce.Playfield(nonPlayerCharacter.PlayField, spawnReply);
            }
            else
            {
                targetClient.SendCompressed(spawnReply);
            }
        }
예제 #5
0
파일: Client.cs 프로젝트: semirs/CellAO
        /// <summary>
        /// 
        /// </summary>
        /// <param name="destination"></param>
        /// <param name="heading"></param>
        /// <param name="playfield"></param>
        /// <returns></returns>
        public bool Teleport(AOCoord destination, Quaternion heading, int playfield)
        {
            PacketWriter writer = new PacketWriter();
            // header starts
            writer.PushByte(0xDF); writer.PushByte(0xDF);
            writer.PushShort(10);
            writer.PushShort(1);
            writer.PushShort(0);
            writer.PushInt(3086);
            writer.PushInt(Character.ID);
            writer.PushInt(0x43197D22);
            writer.PushIdentity(50000, Character.ID);
            writer.PushByte(0);
            // Header ends
            writer.PushCoord(destination);
            writer.PushQuat(heading);
            writer.PushByte(97);
            writer.PushIdentity(51100, playfield);
            writer.PushInt(0);
            writer.PushInt(0);
            writer.PushIdentity(40016, playfield);
            writer.PushInt(0);
            writer.PushInt(0);
            writer.PushIdentity(100001, playfield);
            writer.PushInt(0);
            writer.PushInt(0);
            writer.PushInt(0);
            byte[] tpreply = writer.Finish();
            Misc.Announce.Playfield(this.Character.PlayField, ref tpreply);

            Character.stopMovement();
            Character.rawCoord = destination;
            Character.rawHeading = heading;
            Character.PlayField = playfield;
            Character.Purge(); // Purge character information to DB before client reconnect

            IPAddress tempIP;
            if (IPAddress.TryParse(ConfigReadWrite.Instance.CurrentConfig.ZoneIP, out tempIP) == false)
            {
                IPHostEntry zoneHost = Dns.GetHostEntry(ConfigReadWrite.Instance.CurrentConfig.ZoneIP);
                foreach (IPAddress ip in zoneHost.AddressList)
                {
                    if (ip.AddressFamily == AddressFamily.InterNetwork)
                    {
                        tempIP = ip;
                        break;
                    }
                }
            }
            int zoneIP = IPAddress.HostToNetworkOrder(BitConverter.ToInt32(tempIP.GetAddressBytes(), 0));
            short zonePort = Convert.ToInt16(ConfigReadWrite.Instance.CurrentConfig.ZonePort);

            Thread.Sleep(1000);
            PacketWriter writer2 = new PacketWriter();
            writer2.PushByte(0xDF); writer2.PushByte(0xDF);
            writer2.PushShort(1);
            writer2.PushShort(1);
            writer2.PushShort(0);
            writer2.PushInt(3086);
            writer2.PushInt(Character.ID);
            writer2.PushInt(60);
            writer2.PushInt(zoneIP);
            writer2.PushShort(zonePort);
            byte[] connect = writer2.Finish();
            SendCompressed(connect);
            return true;
        }