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); }
/// <summary> /// /// </summary> /// <param name="client"></param> public static void Send(Client client) { PacketWriter packetWriter = new PacketWriter(); packetWriter.PushBytes(new byte[] { 0xDF, 0xDF }); packetWriter.PushShort(10); packetWriter.PushShort(1); packetWriter.PushShort(0); packetWriter.PushInt(3086); packetWriter.PushInt(client.Character.Id); packetWriter.PushInt(0x5F4B1A39); packetWriter.PushIdentity(40016, client.Character.PlayField); packetWriter.PushByte(0); packetWriter.PushInt(4); packetWriter.PushCoord(client.Character.Coordinates); packetWriter.PushByte(97); packetWriter.PushIdentity(51100, client.Character.PlayField); packetWriter.PushInt(0); packetWriter.PushInt(0); packetWriter.PushIdentity(40016, client.Character.PlayField); packetWriter.PushInt(0); packetWriter.PushInt(0); int vendorcount = VendorHandler.GetNumberofVendorsinPlayfield(client.Character.PlayField); if (vendorcount > 0) { packetWriter.PushInt(51035); packetWriter.PushInt(1); packetWriter.PushInt(1); packetWriter.PushInt(vendorcount); packetWriter.PushInt(VendorHandler.GetFirstVendor(client.Character.PlayField)); } // TODO: Use correct World Position for each "outdoors" playfield -Suiv- // Playfield WorldPos X packetWriter.PushInt(Playfields.GetPlayfieldX(client.Character.PlayField)); // Playfield WorldPos Z packetWriter.PushInt(Playfields.GetPlayfieldZ(client.Character.PlayField)); byte[] packet = packetWriter.Finish(); client.SendCompressed(packet); }
/// <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> /// Write Coordinates to packet /// </summary> /// <param name="packet">Packet writer</param> public void WriteCoordinatesToPacket(PacketWriter packet) { packet.PushCoord(this.Coordinates); }
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); } }
/// <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; }
/// <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; }