/// <summary> /// Shows the bank interface. /// </summary> /// <param name="character">The character to show interface for.</param> public static void Show(Character character) { character.Session.SendData(new StringPacketComposer("Bank of " + GameEngine.World.Name, 762, 24).Serialize()); character.Session.SendData(new ConfigPacketComposer(563, 4194304).Serialize()); character.Session.SendData(new ConfigPacketComposer(1248, -2013265920).Serialize()); character.Session.SendData(new ConfigPacketComposer(115, character.Bank.Noting ? 1 : 0).Serialize()); character.Session.SendData(new ConfigPacketComposer(305, character.Bank.Inserting ? 1 : 0).Serialize()); GenericPacketComposer gpc = new GenericPacketComposer(); gpc.SetOpcode(223); gpc.AppendShort(496); gpc.AppendLEShortA(0); gpc.AppendLEShort(73); gpc.AppendLEShort(762); gpc.AppendLEShort(1278); gpc.AppendLEShort(20); character.Session.SendData(gpc.Serialize()); gpc = new GenericPacketComposer(); gpc.SetOpcode(223); gpc.AppendShort(27); gpc.AppendLEShortA(0); gpc.AppendLEShort(0); gpc.AppendLEShort(763); gpc.AppendLEShort(1150); gpc.AppendLEShort(18); character.Session.SendData(gpc.Serialize()); character.Bank.Refresh(); Frames.SendInterface(character, 762, true); Frames.SendInventoryInterface(character, 763); Frames.SendHideTabs(character); }
/// <summary> /// Loads an account from the database. /// </summary> /// <param name="details">The character details to look at when loading.</param> public void LoadAccount(Details details, LoginConnectionType loginType) { StringBuilder sbQuery = new StringBuilder(); AccountLoadResult result = this.accountLoader.Load(details, loginType); // Try to load the account. GenericPacketComposer composer = new GenericPacketComposer(); // The packet going to be sent. // Try registering the user if return code is successful so far. if (result.ReturnCode == LoginReturnCode.Successful) { // The world is full. if (!Register(result.Character)) { result.ReturnCode = LoginReturnCode.WorldFull; } } composer.AppendByte((byte)result.ReturnCode); // We only need to send this if the login was successful. if (result.ReturnCode == LoginReturnCode.Successful) { composer.AppendByte((byte)result.Character.ClientRights); composer.AppendByte((byte)0); composer.AppendByte((byte)0); composer.AppendByte((byte)0); composer.AppendByte((byte)1); composer.AppendShort((short)result.Character.Index); composer.AppendByte((byte)1); if (this.logSessions) { sbQuery.Append("UPDATE characters SET last_ip=@ip, last_signin=NOW() WHERE id = @id;"); } } if (this.logAttempts) { sbQuery.Append("INSERT INTO login_attempts (username,date,ip,attempt) VALUES (@name, NOW(), @ip, @attempt);"); } if (!result.Active) { sbQuery.Append("UPDATE characters SET active = '1' WHERE id = @id;"); } if (sbQuery.Length != 0) { // Log the user's login attempt. This is useful for tracking hacking, ddos, etc. using (SqlDatabaseClient client = GameServer.Database.GetClient()) { client.AddParameter("id", result.Character.MasterId); client.AddParameter("name", details.Username); client.AddParameter("ip", details.Session.Connection.IPAddress); client.AddParameter("attempt", result.ReturnCode.ToString()); client.ExecuteUpdate(sbQuery.ToString()); } } // Send results to the client. result.Character.Session.SendData(composer.SerializeBuffer()); // We can now welcome the player and send nessesary packets. if (result.ReturnCode == LoginReturnCode.Successful) { result.Character.Session.StartConnection(); if (!result.Active) { result.Character.Preferences.Add("just_started", true); } Frames.SendLoginWelcome(result.Character); result.Character.Contacts.OnLogin(); } Program.Logger.WriteDebug(result.Character.Name + " returned " + result.ReturnCode + " at login attempt."); }
/// <summary> /// Appends any needed update masks. /// </summary> /// <param name="character">The character to update.</param> /// <param name="updateBlock">The update block to add generated data to.</param> /// <param name="forceAppearance">Whether to force the appearance update.</param> public static void AppendMasks(Character character, GenericPacketComposer updateBlock, bool forceAppearance) { int mask = 0x0; if (character.UpdateFlags.Damage2UpdateRequired) { mask |= 0x200; } if (character.UpdateFlags.FaceToUpdateRequired) { mask |= 0x20; } if (character.UpdateFlags.GraphicsUpdateRequired) { mask |= 0x400; } if (character.UpdateFlags.ChatUpdateRequired) { mask |= 0x8; } if (character.UpdateFlags.AnimationUpdateRequired) { mask |= 0x1; } if (character.UpdateFlags.AppearanceUpdateRequired || forceAppearance) { mask |= 0x80; } if (character.UpdateFlags.DamageUpdateRequired) { mask |= 0x2; } if (mask >= 0x100) { mask |= 0x10; updateBlock.AppendByte((byte)(mask & 0xFF)); updateBlock.AppendByte((byte)(mask >> 8)); } else { updateBlock.AppendByte((byte)(mask & 0xFF)); } if (character.UpdateFlags.Damage2UpdateRequired) { //AppendDamage2Update(p, updateBlock); } if (character.UpdateFlags.FaceToUpdateRequired) { updateBlock.AppendShort(character.UpdateFlags.FaceTo); } if (character.UpdateFlags.GraphicsUpdateRequired) { updateBlock.AppendShort(character.CurrentGraphic.Id); updateBlock.AppendIntSecondary(character.CurrentGraphic.Delay); } if (character.UpdateFlags.ChatUpdateRequired) { updateBlock.AppendShortA((short)character.CurrentChatMessage.Effects); updateBlock.AppendByteC((byte)character.ClientRights); byte[] chatStr = new byte[256]; chatStr[0] = (byte)character.CurrentChatMessage.Text.Length; byte offset = (byte)(1 + ChatUtilities.EncryptChat(chatStr, 0, 1, character.CurrentChatMessage.Text.Length, Encoding.ASCII.GetBytes(character.CurrentChatMessage.Text))); updateBlock.AppendByteC(offset); updateBlock.AppendBytes(chatStr, 0, offset); } if (character.UpdateFlags.AnimationUpdateRequired) { updateBlock.AppendShort(character.CurrentAnimation.Id); updateBlock.AppendByteS(character.CurrentAnimation.Delay); } if (character.UpdateFlags.AppearanceUpdateRequired || forceAppearance) { AppendAppearanceUpdate(character, updateBlock); } if (character.UpdateFlags.DamageUpdateRequired) { //AppendDamageUpdate(p, updateBlock); } }
/// <summary> /// Appends the character's current appearance. /// </summary> /// <param name="character">The character to append updates for.</param> /// <param name="updateBlock">The character's update block.</param> private static void AppendAppearanceUpdate(Character character, GenericPacketComposer updateBlock) { GenericPacketComposer properties = new GenericPacketComposer(75); // Gender. properties.AppendByte((byte)character.Appearance.Gender); // Head icons. properties.AppendByte(unchecked ((byte)character.HeadIcon.DeathIcon)); properties.AppendByte(unchecked ((byte)character.HeadIcon.DeathIcon)); if (!character.Appearance.IsNpc) { for (int i = 0; i < 4; i++) { if (character.Equipment[i] != null) { properties.AppendShort((short)(32768 + character.Equipment[i].Definition.EquipId)); } else { properties.AppendByte((byte)0);//I'll check this out later } } Item chest = character.Equipment[EquipmentSlot.Chest]; Item shield = character.Equipment[EquipmentSlot.Shield]; Item legs = character.Equipment[EquipmentSlot.Legs]; Item hat = character.Equipment[EquipmentSlot.Hat]; Item hands = character.Equipment[EquipmentSlot.Hands]; Item feet = character.Equipment[EquipmentSlot.Feet]; // Physical appearance. if (chest != null) { properties.AppendShort((short)(32768 + chest.Definition.EquipId)); } else { properties.AppendShort((short)(0x100 + character.Appearance.Torso)); } if (shield != null) { properties.AppendShort((short)(32768 + shield.Definition.EquipId)); } else { properties.AppendByte((byte)0); } if (chest != null) { if (!EquipmentItems.IsFullBody(chest.Id)) { properties.AppendShort((short)(0x100 + character.Appearance.Arms)); } else { properties.AppendByte((byte)0); } } else { properties.AppendShort((short)(0x100 + character.Appearance.Arms)); } if (legs != null) { properties.AppendShort((short)(32768 + legs.Definition.EquipId)); } else { properties.AppendShort((short)(0x100 + character.Appearance.Legs)); } if (hat != null) { if (!EquipmentItems.IsFullHat(hat.Id) && !EquipmentItems.IsFullMask(hat.Id)) { properties.AppendShort((short)(0x100 + character.Appearance.Head)); } else { properties.AppendByte((byte)0); } } else { properties.AppendShort((short)(0x100 + character.Appearance.Head)); } if (hands != null) { properties.AppendShort((short)(32768 + hands.Definition.EquipId)); } else { properties.AppendShort((short)(0x100 + character.Appearance.Wrist)); } if (feet != null) { properties.AppendShort((short)(32768 + feet.Definition.EquipId)); } else { properties.AppendShort((short)(0x100 + character.Appearance.Feet)); } if (hat != null) { if (!EquipmentItems.IsFullMask(hat.Id)) { properties.AppendShort((short)(0x100 + character.Appearance.Beard)); } else { properties.AppendByte((byte)0); } } else { properties.AppendShort((short)(0x100 + character.Appearance.Beard)); } } else { properties.AppendShort(-1); properties.AppendShort(character.Appearance.NpcId); } // Hair colors. properties.AppendByte(character.Appearance.HairColor); //Hair Color properties.AppendByte(character.Appearance.TorsoColor); //Torso color properties.AppendByte(character.Appearance.LegColor); //Legs color properties.AppendByte(character.Appearance.FeetColor); //Feet color properties.AppendByte(character.Appearance.SkinColor); //Skin color // Emotions. properties.AppendShort(character.Equipment.StandAnimation); // stand properties.AppendShort(0x337); // stand turn properties.AppendShort(character.Equipment.WalkAnimation); // walk properties.AppendShort(0x334); // turn 180 properties.AppendShort(0x335); // turn 90 cw properties.AppendShort(0x336); // turn 90 ccw properties.AppendShort(character.Equipment.RunAnimation); // run properties.AppendLong(character.LongName); // character's name properties.AppendByte((byte)character.Skills.CombatLevel); // combat level properties.AppendShort(0); updateBlock.AppendByte((byte)(properties.Position & 0xFF)); updateBlock.AppendBytes(properties.SerializeBuffer()); }