public bool LevelUp() { if (!ExpMetadataStorage.LevelExist((short)(Level + 1))) { return(false); } Level++; Player.Stats.AddBaseStats(Player); Player.FieldPlayer.RecoverHp(FieldPlayer.Stats[StatId.Hp].Bonus); Session.FieldManager.BroadcastPacket(RevivalConfirmPacket.Send(FieldPlayer.ObjectId, 0)); Session.FieldManager.BroadcastPacket(LevelUpPacket.LevelUp(FieldPlayer.ObjectId, Level)); Session.FieldManager.BroadcastPacket(FieldObjectPacket.UpdateCharacterLevel(Player)); Session.FieldManager.BroadcastPacket(JobPacket.SendJob(FieldPlayer)); Session.Send(StatPacket.SetStats(FieldPlayer)); Session.FieldManager.BroadcastPacket(StatPacket.UpdateFieldStats(FieldPlayer), Session); Session.Send(KeyTablePacket.SendFullOptions(Player.GameOptions)); TrophyManager.OnLevelUp(Player); QuestHelper.GetNewQuests(Player); return(true); }
private static void HandleResetStatDistribution(GameSession session) { session.Player.StatPointDistribution.ResetPoints(); session.Player.FieldPlayer.ComputeStats(); session.Send(StatPointPacket.WriteStatPointDistribution(session.Player)); session.Send(StatPacket.SetStats(session.Player.FieldPlayer)); }
private static void HandleFirstSent(GameSession session, PacketReader packet) { long skillSN = packet.ReadLong(); int unkValue = packet.ReadInt(); int skillId = packet.ReadInt(); short skillLevel = packet.ReadShort(); packet.ReadByte(); CoordF coords = packet.Read <CoordF>(); packet.ReadShort(); SkillCast skillCast = new SkillCast(skillId, skillLevel, skillSN, unkValue); int spiritCost = skillCast.GetSpCost(); int staminaCost = skillCast.GetStaCost(); if (session.Player.Stats[PlayerStatId.Spirit].Current >= spiritCost && session.Player.Stats[PlayerStatId.Stamina].Current >= staminaCost) { session.Player.ConsumeSp(spiritCost); session.Player.ConsumeStamina(staminaCost); // TODO: Add SP recovery session.FieldPlayer.Value.SkillCast = skillCast; session.Send(SkillUsePacket.SkillUse(skillCast, coords)); session.Send(StatPacket.SetStats(session.FieldPlayer)); } }
private static void HandleCast(GameSession session, PacketReader packet) { long skillSN = packet.ReadLong(); int serverTick = packet.ReadInt(); int skillId = packet.ReadInt(); short skillLevel = packet.ReadShort(); byte attackPoint = packet.ReadByte(); CoordF position = packet.Read <CoordF>(); CoordF direction = packet.Read <CoordF>(); CoordF rotation = packet.Read <CoordF>(); packet.ReadFloat(); int clientTick = packet.ReadInt(); packet.ReadBool(); packet.ReadLong(); bool flag = packet.ReadBool(); if (flag) { packet.ReadInt(); string unkString = packet.ReadUnicodeString(); } SkillCast skillCast = new SkillCast(skillId, skillLevel, skillSN, serverTick, session.FieldPlayer.ObjectId, clientTick, attackPoint); session.FieldPlayer.Value.Cast(skillCast); if (skillCast != null) { session.FieldManager.BroadcastPacket(SkillUsePacket.SkillUse(skillCast, position, direction, rotation)); session.Send(StatPacket.SetStats(session.FieldPlayer)); } }
public override void Cast(SkillCast skillCast) { int spiritCost = skillCast.GetSpCost(); int staminaCost = skillCast.GetStaCost(); if (Value.Stats[StatId.Spirit].Total < spiritCost || Value.Stats[StatId.Stamina].Total < staminaCost) { return; } SkillCast = skillCast; ConsumeSp(spiritCost); ConsumeStamina(staminaCost); Value.Session.SendNotice(skillCast.SkillId.ToString()); // TODO: Move this and all others combat cases like recover sp to its own class. // Since the cast is always sent by the skill, we have to check buffs even when not doing damage. if (skillCast.IsBuffToOwner() || skillCast.IsBuffToEntity() || skillCast.IsBuffShield() || skillCast.IsDebuffToOwner()) { Status status = new(skillCast, ObjectId, ObjectId, 1); StatusHandler.Handle(Value.Session, status); } Value.Session.FieldManager.BroadcastPacket(SkillUsePacket.SkillUse(skillCast)); Value.Session.Send(StatPacket.SetStats(this)); StartCombatStance(); }
public void GainExp(long amount) { if (amount <= 0 || !ExpMetadataStorage.LevelExist((short)(Level + 1))) { return; } long newExp = Exp + amount + RestExp; if (RestExp > 0) { RestExp -= amount; } else { RestExp = 0; } bool hasLeveledUp = false; while (newExp >= ExpMetadataStorage.GetExpToLevel(Level)) { newExp -= ExpMetadataStorage.GetExpToLevel(Level); if (LevelUp()) { hasLeveledUp = true; continue; } newExp = 0; break; } Exp = newExp; Session.Send(ExperiencePacket.ExpUp(amount, newExp, RestExp)); if (!hasLeveledUp) { return; } Session.FieldManager.BroadcastPacket(RevivalConfirmPacket.Send(FieldPlayer.ObjectId, 0)); Session.FieldManager.BroadcastPacket(LevelUpPacket.LevelUp(FieldPlayer.ObjectId, Level)); Session.FieldManager.BroadcastPacket(FieldObjectPacket.UpdateCharacterLevel(Player)); // Find all new skills for current level HashSet <int> newSkillIds = SkillMetadataStorage.GetJobSkills(Player.Job) .Where(x => x.SkillLevels.First().SkillUpgrade.LevelRequired == Level) .Select(x => x.SkillId).ToHashSet(); Session.FieldManager.BroadcastPacket(JobPacket.UpdateSkillTab(FieldPlayer, newSkillIds)); Session.Send(StatPacket.SetStats(FieldPlayer)); Session.FieldManager.BroadcastPacket(StatPacket.SetStats(FieldPlayer), Session); Session.Send(KeyTablePacket.SendFullOptions(Player.GameOptions)); DatabaseManager.Characters.Update(Player); }
private static void HandleStatIncrement(GameSession session, PacketReader packet) { byte statTypeIndex = packet.ReadByte(); session.Player.StatPointDistribution.AddPoint(statTypeIndex); // Deprecate? session.Player.Stats.Allocate((PlayerStatId)statTypeIndex); session.Send(StatPointPacket.WriteStatPointDistribution(session.Player)); session.Send(StatPacket.SetStats(session.FieldPlayer)); }
private static void HandleStatIncrement(GameSession session, PacketReader packet) { StatAttribute statTypeIndex = (StatAttribute)packet.ReadByte(); session.Player.StatPointDistribution.AddPoint(statTypeIndex); session.Player.FieldPlayer.ComputeStats(); session.Send(StatPointPacket.WriteStatPointDistribution(session.Player)); session.Send(StatPacket.SetStats(session.Player.FieldPlayer)); }
public override void Handle(GameSession session, PacketReader packet) { packet.ReadInt(); // ? // Liftable: 00 00 00 00 00 // SendBreakable // Self Player player = session.Player; Account account = player.Account; session.EnterField(player); session.Send(StatPacket.SetStats(player.FieldPlayer)); session.Send(StatPointPacket.WriteTotalStatPoints(player)); session.Send(StatPointPacket.WriteTotalStatPoints(player)); // This packet is sent twice on GMS, not sure why session.Send(StatPointPacket.WriteStatPointDistribution(player)); if (account.IsVip()) { session.Send(BuffPacket.SendBuff(0, new(100000014, player.FieldPlayer.ObjectId, player.FieldPlayer.ObjectId, 1, (int)account.VIPExpiration, 1))); session.Send(PremiumClubPacket.ActivatePremium(player.FieldPlayer, account.VIPExpiration)); } session.Send(EmotePacket.LoadEmotes(player)); session.Send(ChatStickerPacket.LoadChatSticker(player)); session.Send(HomeCommandPacket.LoadHome(player)); session.Send(ResponseCubePacket.DecorationScore(account.Home)); session.Send(ResponseCubePacket.LoadHome(player.FieldPlayer.ObjectId, player.Account.Home)); session.Send(ResponseCubePacket.ReturnMap(player.ReturnMapId)); session.Send(LapenshardPacket.Load(player.Inventory.LapenshardStorage)); IEnumerable <Cube> cubes = session.FieldManager.State.Cubes.Values .Where(x => x.Value.PlotNumber == 1 && x.Value.Item.HousingCategory is ItemHousingCategory.Farming or ItemHousingCategory.Ranching) .Select(x => x.Value); foreach (Cube cube in cubes) { session.Send(FunctionCubePacket.UpdateFunctionCube(cube.CoordF.ToByte(), 2, 1)); } if (player.Party is not null) { session.Send(PartyPacket.UpdatePlayer(player)); } session.Send(KeyTablePacket.SendHotbars(player.GameOptions)); List <GameEvent> gameEvents = DatabaseManager.Events.FindAll(); session.Send(GameEventPacket.Load(gameEvents)); TrophyManager.OnMapEntered(player, player.MapId); }
public bool LevelUp() { if (!ExpMetadataStorage.LevelExist((short)(Level + 1))) { return(false); } Level++; TrophyManager.OnLevelUp(Player); Player.Stats.AddBaseStats(Player); Player.FieldPlayer.RecoverHp(FieldPlayer.Stats[StatId.Hp].Bonus); Session.FieldManager.BroadcastPacket(ExperiencePacket.LevelUp(FieldPlayer.ObjectId, Level)); Session.Send(StatPacket.SetStats(FieldPlayer)); QuestHelper.GetNewQuests(Player); return(true); }
private static void HandleCast(GameSession session, PacketReader packet) { long skillSN = packet.ReadLong(); int unkValue = packet.ReadInt(); int skillId = packet.ReadInt(); short skillLevel = packet.ReadShort(); packet.ReadByte(); CoordF coords = packet.Read <CoordF>(); packet.ReadShort(); SkillCast skillCast = session.Player.Cast(skillId, skillLevel, skillSN, unkValue); if (skillCast != null) { session.Send(SkillUsePacket.SkillUse(skillCast, coords)); session.Send(StatPacket.SetStats(session.FieldPlayer)); } }
private static void IncreaseStats(GameSession session, Item item) { if (item.Stats.BasicStats.Count != 0) { foreach (NormalStat stat in item.Stats.BasicStats.OfType <NormalStat>()) { session.Player.Stats[stat.ItemAttribute].IncreaseBonus(stat.Flat); } } if (item.Stats.BonusStats.Count != 0) { foreach (NormalStat stat in item.Stats.BonusStats.OfType <NormalStat>()) { session.Player.Stats[stat.ItemAttribute].IncreaseBonus(stat.Flat); } } session.Send(StatPacket.SetStats(session.Player.FieldPlayer)); }
private static void IncreaseStats(GameSession session, Item item) { if (item.Stats.BasicStats.Count != 0) { foreach (NormalStat stat in item.Stats.BasicStats.Where(x => x.GetType() == typeof(NormalStat))) { session.Player.Stats.IncreaseMax((PlayerStatId)stat.Id, stat.Flat); } } if (item.Stats.BonusStats.Count != 0) { foreach (NormalStat stat in item.Stats.BonusStats.Where(x => x.GetType() == typeof(NormalStat))) { session.Player.Stats.IncreaseMax((PlayerStatId)stat.Id, stat.Flat); } } session.Send(StatPacket.SetStats(session.FieldPlayer)); }
public override void Handle(GameSession session, PacketReader packet) { packet.ReadInt(); // ? // Liftable: 00 00 00 00 00 // SendBreakable // Self session.EnterField(session.Player.MapId); session.Send(StatPacket.SetStats(session.FieldPlayer)); session.Send(StatPointPacket.WriteTotalStatPoints(session.Player)); foreach (MasteryExp mastery in session.Player.Levels.MasteryExp) { session.Send(MasteryPacket.SetExp(mastery.Type, mastery.CurrentExp)); } if (session.Player.IsVip()) { session.Send(PremiumClubPacket.ActivatePremium(session.FieldPlayer, session.Player.VIPExpiration)); } session.Send(EmotePacket.LoadEmotes(session.Player)); session.Send(ChatStickerPacket.LoadChatSticker(session.Player)); session.Send(ResponseCubePacket.LoadHome(session.FieldPlayer)); // Normally skill layout would be loaded from a database QuickSlot arrowStream = QuickSlot.From(10500001); QuickSlot arrowBarrage = QuickSlot.From(10500011); QuickSlot eagleGlide = QuickSlot.From(10500151); QuickSlot testSkill = QuickSlot.From(10500153); if (session.Player.GameOptions.TryGetHotbar(0, out Hotbar mainHotbar)) { /* * mainHotbar.MoveQuickSlot(4, arrowStream); * mainHotbar.MoveQuickSlot(5, arrowBarrage); * mainHotbar.MoveQuickSlot(6, eagleGlide); * mainHotbar.MoveQuickSlot(7, testSkill); */ session.Send(KeyTablePacket.SendHotbars(session.Player.GameOptions)); } session.Send(GameEventPacket.Load()); }
private void HandleEquipItem(GameSession session, PacketReader packet) { long itemUid = packet.ReadLong(); string equipSlotStr = packet.ReadUnicodeString(); if (!Enum.TryParse(equipSlotStr, out ItemSlot equipSlot)) { logger.Warning("Unknown equip slot: " + equipSlotStr); return; } // Remove the item from the users inventory InventoryController.Remove(session, itemUid, out Item item); // TODO: Move unequipped item into the correct slot // Move previously equipped item back to inventory if (session.Player.Equips.Remove(equipSlot, out Item prevItem)) { InventoryController.Add(session, prevItem, false); session.FieldManager.BroadcastPacket(EquipmentPacket.UnequipItem(session.FieldPlayer, prevItem)); } // Equip new item session.Player.Equips[equipSlot] = item; session.FieldManager.BroadcastPacket(EquipmentPacket.EquipItem(session.FieldPlayer, item, equipSlot)); // TODO - Increase stats based on the item stats itself session.Player.Stats.CritRate.Max += 12; session.Player.Stats.CritRate.Total += 12; session.Player.Stats.MinAtk.Max += 15; session.Player.Stats.MinAtk.Total += 15; session.Player.Stats.MaxAtk.Max += 17; session.Player.Stats.MaxAtk.Total += 17; session.Player.Stats.MagAtk.Max += 15; session.Player.Stats.MagAtk.Total += 15; session.Send(StatPacket.SetStats(session.FieldPlayer)); }
public override void Execute(GameCommandTrigger trigger) { short level = trigger.Get <short>("level"); if (level <= 0) { trigger.Session.SendNotice("Level must be a number or more than 0."); return; } Player player = trigger.Session.Player; // Reset stats to default player.Stats = new(player.Job); player.Stats.AddBaseStats(player, level); trigger.Session.Send(StatPacket.SetStats(player.FieldPlayer)); trigger.Session.FieldManager.BroadcastPacket(StatPacket.SetStats(player.FieldPlayer), trigger.Session); player.Levels.SetLevel(level); }
public override void Handle(GameSession session, PacketReader packet) { packet.ReadInt(); // ? // Liftable: 00 00 00 00 00 // SendBreakable // Self Player player = session.Player; Account account = player.Account; session.EnterField(player); session.Send(StatPacket.SetStats(session.FieldPlayer)); session.Send(StatPointPacket.WriteTotalStatPoints(player)); if (account.IsVip()) { session.Send(BuffPacket.SendBuff(0, new Status(100000014, session.FieldPlayer.ObjectId, session.FieldPlayer.ObjectId, 1, (int)account.VIPExpiration, 1))); session.Send(PremiumClubPacket.ActivatePremium(session.FieldPlayer, account.VIPExpiration)); } session.Send(EmotePacket.LoadEmotes(player)); session.Send(ChatStickerPacket.LoadChatSticker(player)); session.Send(HomeCommandPacket.LoadHome(player)); session.Send(ResponseCubePacket.DecorationScore(account.Home)); session.Send(ResponseCubePacket.LoadHome(session.FieldPlayer)); session.Send(ResponseCubePacket.ReturnMap(player.ReturnMapId)); if (player.Party != null) { session.Send(PartyPacket.UpdatePlayer(player)); } session.Send(KeyTablePacket.SendHotbars(player.GameOptions)); List <GameEvent> gameEvents = DatabaseManager.Events.FindAll(); session.Send(GameEventPacket.Load(gameEvents)); }
public override void Handle(GameSession session, PacketReader packet) { long accountId = packet.ReadLong(); AuthData authData = AuthStorage.GetData(accountId); // Backwards seeking because we read accountId here packet.Skip(-8); HandleCommon(session, packet); Player player = DatabaseManager.GetCharacter(authData.CharacterId); if (player == default) { throw new ArgumentException("Character not found!"); } player.Session = session; session.InitPlayer(player); //session.Send(0x27, 0x01); // Meret market related...? session.Send(BuddyPacket.Initialize()); session.Send(LoginPacket.LoginRequired(accountId)); if (session.Player.Guild != null) { Guild guild = DatabaseManager.GetGuild(session.Player.Guild.Id); session.Send(GuildPacket.UpdateGuild(guild)); session.Send(GuildPacket.MemberJoin(player)); } session.Send(BuddyPacket.LoadList(player)); session.Send(BuddyPacket.EndList(player.BuddyList.Count)); // Meret market //session.Send("6E 00 0B 00 00 00 00 00 00 00 00 00 00 00 00".ToByteArray()); //session.Send("6E 00 0C 00 00 00 00".ToByteArray()); // UserConditionEvent //session.Send("BF 00 00 00 00 00 00".ToByteArray()); // PCBangBonus //session.Send("A7 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00".ToByteArray()); TimeSyncPacket.SetInitial1(); TimeSyncPacket.SetInitial2(); TimeSyncPacket.Request(); session.Send(StatPacket.SetStats(session.FieldPlayer)); // TODO: Grab Hp/Spirit/Stam from last login player.Stats.InitializePools(player.Stats[PlayerStatId.Hp].Max, player.Stats[PlayerStatId.Spirit].Max, player.Stats[PlayerStatId.Stamina].Max); session.SyncTicks(); session.Send(DynamicChannelPacket.DynamicChannel()); session.Send(ServerEnterPacket.Enter(session)); // SendUgc f(0x16), SendCash f(0x09), SendContentShutdown f(0x01, 0x04), SendPvp f(0x0C) PacketWriter pWriter = PacketWriter.Of(SendOp.SYNC_NUMBER); pWriter.WriteByte(); session.Send(pWriter); // 0x112, Prestige f(0x00, 0x07) session.Send(PrestigePacket.Prestige(session.Player)); // Load inventory tabs foreach (InventoryTab tab in Enum.GetValues(typeof(InventoryTab))) { InventoryController.LoadInventoryTab(session, tab); } List <QuestMetadata> questList = QuestMetadataStorage.GetAvailableQuests(player.Levels.Level); // TODO: This logic needs to be refactored when DB is implemented questList.Add(QuestMetadataStorage.GetMetadata(60100000)); // Manually adding "the caravan" for testing purposes foreach (QuestMetadata quest in questList) { session.Player.QuestList.Add(new QuestStatus(quest)); } IEnumerable <List <QuestStatus> > packetCount = SplitList(session.Player.QuestList, 200); // Split the quest list in 200 quests per packet, same way kms do foreach (List <QuestStatus> item in packetCount) { session.Send(QuestPacket.SendQuests(item)); } session.Send(TrophyPacket.WriteTableStart()); List <Trophy> trophyList = new List <Trophy>(session.Player.TrophyData.Values); IEnumerable <List <Trophy> > trophyListPackets = SplitList(trophyList, 60); foreach (List <Trophy> trophy in trophyListPackets) { session.Send(TrophyPacket.WriteTableContent(trophy)); } session.Send(WarehouseInventoryPacket.Count()); // Typically sent after buddylist session.Send(WarehouseInventoryPacket.StartList()); session.Send(WarehouseInventoryPacket.EndList()); session.Send(FurnishingInventoryPacket.StartList()); session.Send(FurnishingInventoryPacket.EndList()); // SendQuest, SendAchieve, SendManufacturer, SendUserMaid session.Send(UserEnvPacket.SetTitles(player)); session.Send(UserEnvPacket.Send04()); session.Send(UserEnvPacket.Send05()); session.Send(UserEnvPacket.Send08()); session.Send(UserEnvPacket.Send09()); session.Send(UserEnvPacket.Send10()); session.Send(UserEnvPacket.Send12()); // SendMeretMarket f(0xC9) session.Send(FishingPacket.LoadAlbum(player)); // SendPvp f(0x16,0x17), ResponsePet f(0x07), 0xF6 // CharacterAbility // E1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Normally, options are only requested for a new character. Since we don't have a database, we'll always requests the users bindings session.Send(KeyTablePacket.RequestDefault()); // TODO - Ask for mouse or kb controls on new character creation. // Commented out since its annoying to click every time //session.Send(KeyTablePacket.AskKeyboardOrMouse()); // Key bindings and skill slots would normally be loaded from a database // If the character is not a new character, this is what we would send // session.Send(KeyTablePacket.SendFullOptions(session.Player.Options)); // SendKeyTable f(0x00), SendGuideRecord f(0x03), GameEvent f(0x00) // SendBannerList f(0x19), SendRoomDungeon f(0x05, 0x14, 0x17) // FieldEntrance session.Send("19 00 00 65 00 00 00 29 7C 7D 01 0C 4D A1 6F 01 0C D3 1A 5F 01 0C EF 03 00 00 01 A2 3C 31 01 0C 3F 0C B7 0D 01 6B 55 5F 01 0C 3A 77 31 01 0C B1 98 BA 01 0C 03 90 5F 01 0C F9 7A 40 01 0C 91 B5 40 01 0C F9 57 31 01 0C 2F C7 BB 0D 01 81 97 7D 01 0C C2 70 5F 01 0C 51 96 40 01 0C B9 38 31 01 0C 41 78 7D 01 0C 65 9D 6F 01 0C 83 51 5F 01 0C 52 73 31 01 0C FF E0 B8 0D 01 11 77 40 01 0C A9 B1 40 01 0C 11 54 31 01 0C DA 6C 5F 01 0C 69 92 40 01 0C D1 34 31 01 0C 7D 99 6F 01 0C 03 13 5F 01 0C 69 6F 31 01 0C 32 88 5F 01 0C 9B 4D 5F 01 0C FF 6F B6 0D 01 29 73 40 01 0C C1 AD 40 01 0C 29 50 31 01 0C 81 8E 40 01 0C E9 30 31 01 0C 09 CE 8C 01 0C 95 95 6F 01 0C 1B 0F 5F 01 0C 4A 84 5F 01 0C B3 49 5F 01 0C 82 6B 31 01 0C 4F 15 BC 0D 01 F9 8C BA 01 00 D9 A9 40 01 0C 41 4C 31 01 0C EF B9 B8 0D 01 99 8A 40 01 0C 21 CA 8C 01 0C 01 AD 6F 01 0C 33 0B 5F 01 0C 99 67 31 01 0C 62 80 5F 01 0C CB 45 5F 01 0C 79 08 9C 01 0C F1 A5 40 01 0C E1 87 7D 01 0C BB 9B 5F 01 0C B1 86 40 01 0C 39 C6 8C 01 0C 7A 7C 5F 01 0C B2 63 31 01 0C 29 85 BA 01 0E 91 04 9C 01 0C 09 A2 40 01 0C 71 44 31 01 0C F9 83 7D 01 0C 1D A9 6F 01 0C D3 97 5F 01 0C C9 82 40 01 0C 51 C2 8C 01 0C 61 BD 40 01 0C C9 5F 31 01 0C 51 9F 7D 01 0C 92 78 5F 01 0C 0F 08 B9 0D 01 A9 00 9C 01 0C 89 40 31 01 0C 11 80 7D 01 0C 35 A5 6F 01 0C BB 1E 5F 01 0C 53 59 5F 01 0C E9 03 00 00 01 22 7B 31 01 0C EB 93 5F 01 0C EA 03 00 00 01 E1 7E 40 01 0C 69 BE 8C 01 0C 79 B9 40 01 0C E1 5B 31 01 0C EB 03 00 00 01 69 9B 7D 01 0C AA 74 5F 01 0C EC 03 00 00 01 ED 03 00 00 01 C1 FC 9B 01 0C EE 03 00 00 01".ToByteArray()); // 0xF0, ResponsePet P(0F 01) // RequestFieldEnter //session.Send("16 00 00 41 75 19 03 00 01 8A 42 0F 00 00 00 00 00 00 C0 28 C4 00 40 03 44 00 00 16 44 00 00 00 00 00 00 00 00 55 FF 33 42 E8 49 01 00".ToByteArray()); session.Send(FieldPacket.RequestEnter(session.FieldPlayer)); // SendUgc: 15 01 00 00 00 00 00 00 00 00 00 00 00 4B 00 00 00 // SendHomeCommand: 00 E1 0F 26 89 7F 98 3C 26 00 00 00 00 00 00 00 00 //session.Send("B9 00 00 E1 0F 26 89 7F 98 3C 26 00 00 00 00 00 00 00 00".ToByteArray()); //session.Send(ServerEnterPacket.Confirm()); //session.Send(0xF0, 0x00, 0x1F, 0x78, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00); //session.Send(0x28, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); //session.Send(ServerEnterPacket.Confirm()); }
private void HandleEquipItem(GameSession session, PacketReader packet) { long itemUid = packet.ReadLong(); string equipSlotStr = packet.ReadUnicodeString(); if (!Enum.TryParse(equipSlotStr, out ItemSlot equipSlot)) { logger.Warning("Unknown equip slot: " + equipSlotStr); return; } // Remove the item from the users inventory InventoryController.Remove(session, itemUid, out Item item); // Equip cosmetic if (item.InventoryTab == InventoryTab.Outfit) { // Move previously equipped item back to inventory if (session.Player.Cosmetics.Remove(equipSlot, out Item prevItem)) { prevItem.Slot = item.Slot; InventoryController.Add(session, prevItem, false); session.FieldManager.BroadcastPacket(EquipmentPacket.UnequipItem(session.FieldPlayer, prevItem)); } // Handle unequipping off-hand when equipping two-handed weapons if (item.IsTwoHand) { if (session.Player.Cosmetics.Remove(ItemSlot.LH, out Item prevItem2)) { prevItem2.Slot = -1; if (prevItem == null) { prevItem2.Slot = item.Slot; } InventoryController.Add(session, prevItem2, false); session.FieldManager.BroadcastPacket(EquipmentPacket.UnequipItem(session.FieldPlayer, prevItem2)); } } // Handle unequipping two-handed main-hands when equipping off-hand weapons if (item.ItemSlot == ItemSlot.LH && session.Player.Cosmetics[ItemSlot.RH] != null && session.Player.Cosmetics[ItemSlot.RH].IsTwoHand) { if (session.Player.Cosmetics.Remove(ItemSlot.RH, out Item prevItem2)) { prevItem2.Slot = item.Slot; InventoryController.Add(session, prevItem2, false); session.FieldManager.BroadcastPacket(EquipmentPacket.UnequipItem(session.FieldPlayer, prevItem2)); } } // Equip new item session.Player.Cosmetics[equipSlot] = item; session.FieldManager.BroadcastPacket(EquipmentPacket.EquipItem(session.FieldPlayer, item, equipSlot)); } // Equip gear else { // Move previously equipped item back to inventory if (session.Player.Equips.Remove(equipSlot, out Item prevItem)) { prevItem.Slot = item.Slot; InventoryController.Add(session, prevItem, false); session.FieldManager.BroadcastPacket(EquipmentPacket.UnequipItem(session.FieldPlayer, prevItem)); } // Handle unequipping off-hand when equipping two-handed weapons if (item.IsTwoHand) { if (session.Player.Equips.Remove(ItemSlot.LH, out Item prevItem2)) { prevItem2.Slot = -1; if (prevItem == null) { prevItem2.Slot = item.Slot; } InventoryController.Add(session, prevItem2, false); session.FieldManager.BroadcastPacket(EquipmentPacket.UnequipItem(session.FieldPlayer, prevItem2)); } } // Handle unequipping two-handed main-hands when equipping off-hand weapons if (item.ItemSlot == ItemSlot.LH && session.Player.Equips[ItemSlot.RH] != null && session.Player.Equips[ItemSlot.RH].IsTwoHand) { if (session.Player.Equips.Remove(ItemSlot.RH, out Item prevItem2)) { prevItem2.Slot = item.Slot; InventoryController.Add(session, prevItem2, false); session.FieldManager.BroadcastPacket(EquipmentPacket.UnequipItem(session.FieldPlayer, prevItem2)); } } // Equip new item session.Player.Equips[equipSlot] = item; session.FieldManager.BroadcastPacket(EquipmentPacket.EquipItem(session.FieldPlayer, item, equipSlot)); // TODO - Increase stats based on the item stats itself session.Player.Stats.CritRate.Max += 12; session.Player.Stats.CritRate.Total += 12; session.Player.Stats.MinAtk.Max += 15; session.Player.Stats.MinAtk.Total += 15; session.Player.Stats.MaxAtk.Max += 17; session.Player.Stats.MaxAtk.Total += 17; session.Player.Stats.MagAtk.Max += 15; session.Player.Stats.MagAtk.Total += 15; session.Send(StatPacket.SetStats(session.FieldPlayer)); } }
public override void Handle(GameSession session, PacketReader packet) { packet.ReadInt(); // ? // Liftable: 00 00 00 00 00 // SendBreakable // Self session.EnterField(session.Player.MapId); session.Send(StatPacket.SetStats(session.FieldPlayer)); session.Send(StatPointPacket.WriteTotalStatPoints(session.Player)); session.Send(EmotePacket.LoadEmotes(session.Player)); session.Send(ChatStickerPacket.LoadChatSticker(session.Player)); // Normally skill layout would be loaded from a database QuickSlot arrowStream = QuickSlot.From(10500001); QuickSlot arrowBarrage = QuickSlot.From(10500011); QuickSlot eagleGlide = QuickSlot.From(10500151); QuickSlot testSkill = QuickSlot.From(10500153); if (session.Player.GameOptions.TryGetHotbar(0, out Hotbar mainHotbar)) { /* * mainHotbar.MoveQuickSlot(4, arrowStream); * mainHotbar.MoveQuickSlot(5, arrowBarrage); * mainHotbar.MoveQuickSlot(6, eagleGlide); * mainHotbar.MoveQuickSlot(7, testSkill); */ session.Send(KeyTablePacket.SendHotbars(session.Player.GameOptions)); } // Add catalysts for testing Item item = new Item(40100001) { Amount = 99999 }; Item item2 = new Item(40100001) { Amount = 90000 }; Item item3 = new Item(20302228) { Amount = 1 }; InventoryController.Add(session, item, true); InventoryController.Add(session, item2, true); InventoryController.Add(session, item3, true); //Add mail for testing //System mail without any item Mail sysMail = new Mail ( 101, session.Player.CharacterId, "50000002", "", "", 0, DateTimeOffset.UtcNow.ToUnixTimeSeconds(), null ); // System mail with an item List <Item> items = new List <Item> { new Item(40100001) // 20302228 { CreationTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), Owner = session.Player, Amount = 10000 } }; Mail sysItemMail = new Mail ( 101, session.Player.CharacterId, "53000042", "", "", 0, DateTimeOffset.UtcNow.ToUnixTimeSeconds(), items ); // Regular mail Mail regMail = new Mail ( 1, session.Player.CharacterId, session.Player.Name, "Test Title", "Test Body", 0, DateTimeOffset.UtcNow.ToUnixTimeSeconds(), null ); session.Player.Mailbox.AddOrUpdate(sysItemMail); session.Player.Mailbox.AddOrUpdate(sysMail); session.Player.Mailbox.AddOrUpdate(regMail); }
public override void Handle(GameSession session, PacketReader packet) { long accountId = packet.ReadLong(); AuthData authData = DatabaseManager.AuthData.GetByAccountId(accountId); Player dbPlayer = DatabaseManager.Characters.FindPlayerById(authData.OnlineCharacterId); // Backwards seeking because we read accountId here packet.Skip(-8); HandleCommon(session, packet); session.InitPlayer(dbPlayer); Player player = session.Player; player.Session = session; player.Wallet.Meso.Session = session; player.Wallet.ValorToken.Session = session; player.Wallet.Treva.Session = session; player.Wallet.Rue.Session = session; player.Wallet.HaviFruit.Session = session; player.Account.Meret.Session = session; player.Account.GameMeret.Session = session; player.Account.EventMeret.Session = session; player.Account.MesoToken.Session = session; player.Account.BankInventory.Mesos.Session = session; player.Levels.Player = player; player.BuddyList = GameServer.BuddyManager.GetBuddies(player.CharacterId); player.Mailbox = GameServer.MailManager.GetMails(player.CharacterId); GameServer.PlayerManager.AddPlayer(player); GameServer.BuddyManager.SetFriendSessions(player); // Only send buddy login notification if player is not changing channels if (!player.IsMigrating) { player.UpdateBuddies(); } if (player.GuildId != 0) { Guild guild = GameServer.GuildManager.GetGuildById(player.GuildId); player.Guild = guild; GuildMember guildMember = guild.Members.First(x => x.Id == player.CharacterId); guildMember.Player.Session = session; player.GuildMember = guildMember; session.Send(GuildPacket.UpdateGuild(guild)); guild.BroadcastPacketGuild(GuildPacket.MemberJoin(player)); guild.BroadcastPacketGuild(GuildPacket.MemberLoggedIn(player), session); } player.IsMigrating = false; //session.Send(0x27, 0x01); // Meret market related...? session.Send(MushkingRoyaleSystemPacket.LoadStats(session.Player.Account.MushkingRoyaleStats)); session.Send(MushkingRoyaleSystemPacket.LoadMedals(session.Player.Account)); player.GetUnreadMailCount(); session.Send(BuddyPacket.Initialize()); session.Send(BuddyPacket.LoadList(player.BuddyList)); session.Send(BuddyPacket.EndList(player.BuddyList.Count)); // Meret market //session.Send("6E 00 0B 00 00 00 00 00 00 00 00 00 00 00 00".ToByteArray()); //session.Send("6E 00 0C 00 00 00 00".ToByteArray()); // UserConditionEvent //session.Send("BF 00 00 00 00 00 00".ToByteArray()); // PCBangBonus //session.Send("A7 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00".ToByteArray()); TimeSyncPacket.SetInitial1(); TimeSyncPacket.SetInitial2(); TimeSyncPacket.Request(); session.Send(StatPacket.SetStats(session.Player.FieldPlayer)); session.Player.ClientTickSyncLoop(); session.Send(DynamicChannelPacket.DynamicChannel()); session.Send(ServerEnterPacket.Enter(session)); // SendUgc f(0x16), SendCash f(0x09), SendContentShutdown f(0x01, 0x04), SendPvp f(0x0C) session.Send(SyncNumberPacket.Send()); // 0x112, Prestige f(0x00, 0x07) session.Send(PrestigePacket.Prestige(player)); // Load inventory tabs foreach (InventoryTab tab in Enum.GetValues(typeof(InventoryTab))) { player.Inventory.LoadInventoryTab(session, tab); } if (player.Account.HomeId != 0) { Home home = GameServer.HomeManager.GetHomeById(player.Account.HomeId); player.Account.Home = home; session.Send(WarehouseInventoryPacket.StartList()); int counter = 0; foreach (KeyValuePair <long, Item> kvp in home.WarehouseInventory) { session.Send(WarehouseInventoryPacket.Load(kvp.Value, ++counter)); } session.Send(WarehouseInventoryPacket.EndList()); session.Send(FurnishingInventoryPacket.StartList()); foreach (Cube cube in home.FurnishingInventory.Values.Where(x => x.Item != null)) { session.Send(FurnishingInventoryPacket.Load(cube)); } session.Send(FurnishingInventoryPacket.EndList()); } session.Send(QuestPacket.StartList()); session.Send(QuestPacket.Packet1F()); session.Send(QuestPacket.Packet20()); IEnumerable <List <QuestStatus> > packetCount = player.QuestData.Values.ToList().SplitList(200); // Split the quest list in 200 quests per packet foreach (List <QuestStatus> item in packetCount) { session.Send(QuestPacket.SendQuests(item)); } session.Send(QuestPacket.EndList()); session.Send(TrophyPacket.WriteTableStart()); List <Trophy> trophyList = new(player.TrophyData.Values); IEnumerable <List <Trophy> > trophyListPackets = trophyList.SplitList(60); foreach (List <Trophy> trophy in trophyListPackets) { session.Send(TrophyPacket.WriteTableContent(trophy)); } // SendQuest, SendAchieve, SendManufacturer, SendUserMaid session.Send(UserEnvPacket.SetTitles(player)); session.Send(UserEnvPacket.Send04()); session.Send(UserEnvPacket.Send05()); session.Send(UserEnvPacket.UpdateLifeSkills(player.GatheringCount)); session.Send(UserEnvPacket.Send09()); session.Send(UserEnvPacket.Send10()); session.Send(UserEnvPacket.Send12()); // SendMeretMarket f(0xC9) session.Send(FishingPacket.LoadAlbum(player)); // SendPvp f(0x16,0x17), ResponsePet f(0x07), 0xF6 // CharacterAbility // E1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Key bindings and skill slots would normally be loaded from a database // If the character is not a new character, this is what we would send session.Send(KeyTablePacket.SendFullOptions(player.GameOptions)); if (player.MapId == (int)Map.UnknownLocation) // tutorial map { session.Send(KeyTablePacket.AskKeyboardOrMouse()); } // SendKeyTable f(0x00), SendGuideRecord f(0x03), GameEvent f(0x00) // SendBannerList f(0x19), SendRoomDungeon f(0x05, 0x14, 0x17) // FieldEntrance session.Send("19 00 00 65 00 00 00 29 7C 7D 01 0C 4D A1 6F 01 0C D3 1A 5F 01 0C EF 03 00 00 01 A2 3C 31 01 0C 3F 0C B7 0D 01 6B 55 5F 01 0C 3A 77 31 01 0C B1 98 BA 01 0C 03 90 5F 01 0C F9 7A 40 01 0C 91 B5 40 01 0C F9 57 31 01 0C 2F C7 BB 0D 01 81 97 7D 01 0C C2 70 5F 01 0C 51 96 40 01 0C B9 38 31 01 0C 41 78 7D 01 0C 65 9D 6F 01 0C 83 51 5F 01 0C 52 73 31 01 0C FF E0 B8 0D 01 11 77 40 01 0C A9 B1 40 01 0C 11 54 31 01 0C DA 6C 5F 01 0C 69 92 40 01 0C D1 34 31 01 0C 7D 99 6F 01 0C 03 13 5F 01 0C 69 6F 31 01 0C 32 88 5F 01 0C 9B 4D 5F 01 0C FF 6F B6 0D 01 29 73 40 01 0C C1 AD 40 01 0C 29 50 31 01 0C 81 8E 40 01 0C E9 30 31 01 0C 09 CE 8C 01 0C 95 95 6F 01 0C 1B 0F 5F 01 0C 4A 84 5F 01 0C B3 49 5F 01 0C 82 6B 31 01 0C 4F 15 BC 0D 01 F9 8C BA 01 00 D9 A9 40 01 0C 41 4C 31 01 0C EF B9 B8 0D 01 99 8A 40 01 0C 21 CA 8C 01 0C 01 AD 6F 01 0C 33 0B 5F 01 0C 99 67 31 01 0C 62 80 5F 01 0C CB 45 5F 01 0C 79 08 9C 01 0C F1 A5 40 01 0C E1 87 7D 01 0C BB 9B 5F 01 0C B1 86 40 01 0C 39 C6 8C 01 0C 7A 7C 5F 01 0C B2 63 31 01 0C 29 85 BA 01 0E 91 04 9C 01 0C 09 A2 40 01 0C 71 44 31 01 0C F9 83 7D 01 0C 1D A9 6F 01 0C D3 97 5F 01 0C C9 82 40 01 0C 51 C2 8C 01 0C 61 BD 40 01 0C C9 5F 31 01 0C 51 9F 7D 01 0C 92 78 5F 01 0C 0F 08 B9 0D 01 A9 00 9C 01 0C 89 40 31 01 0C 11 80 7D 01 0C 35 A5 6F 01 0C BB 1E 5F 01 0C 53 59 5F 01 0C E9 03 00 00 01 22 7B 31 01 0C EB 93 5F 01 0C EA 03 00 00 01 E1 7E 40 01 0C 69 BE 8C 01 0C 79 B9 40 01 0C E1 5B 31 01 0C EB 03 00 00 01 69 9B 7D 01 0C AA 74 5F 01 0C EC 03 00 00 01 ED 03 00 00 01 C1 FC 9B 01 0C EE 03 00 00 01".ToByteArray()); // 0xF0, ResponsePet P(0F 01) // RequestFieldEnter //session.Send("16 00 00 41 75 19 03 00 01 8A 42 0F 00 00 00 00 00 00 C0 28 C4 00 40 03 44 00 00 16 44 00 00 00 00 00 00 00 00 55 FF 33 42 E8 49 01 00".ToByteArray()); session.Send(RequestFieldEnterPacket.RequestEnter(session.Player.FieldPlayer)); Party party = GameServer.PartyManager.GetPartyByMember(player.CharacterId); if (party != null) { player.Party = party; party.BroadcastPacketParty(PartyPacket.LoginNotice(player), session); session.Send(PartyPacket.Create(party, false)); } // SendUgc: 15 01 00 00 00 00 00 00 00 00 00 00 00 4B 00 00 00 // SendHomeCommand: 00 E1 0F 26 89 7F 98 3C 26 00 00 00 00 00 00 00 00 session.Player.TimeSyncLoop(); session.Send(TimeSyncPacket.SetSessionServerTick(0)); //session.Send("B9 00 00 E1 0F 26 89 7F 98 3C 26 00 00 00 00 00 00 00 00".ToByteArray()); session.Send(ServerEnterPacket.Confirm()); //session.Send(0xF0, 0x00, 0x1F, 0x78, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00); //session.Send(0x28, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); //session.Send(ServerEnterPacket.Confirm()); }
public override void Handle(GameSession session, PacketReader packet) { packet.ReadInt(); // ? // Liftable: 00 00 00 00 00 // SendBreakable // Self Player player = session.Player; Account account = player.Account; session.EnterField(player); session.Send(StatPacket.SetStats(player.FieldPlayer)); session.Send(StatPointPacket.WriteTotalStatPoints(player)); session.Send(StatPointPacket.WriteTotalStatPoints(player)); // This packet is sent twice on GMS, not sure why session.Send(StatPointPacket.WriteStatPointDistribution(player)); session.Send(SkillPointPacket.ExtraSkillPoints(player)); if (player.ActivePet is not null) { player.ActivePet.SetMetadataValues(); Pet pet = session.FieldManager.RequestPet(player.ActivePet, player.FieldPlayer); if (pet is not null) { player.FieldPlayer.ActivePet = pet; session.Send(ResponsePetPacket.LoadPetSettings(pet)); session.Send(NoticePacket.Notice(SystemNotice.PetSummonOn, NoticeType.Chat | NoticeType.FastText)); } } if (account.IsVip()) { session.Send(BuffPacket.SendBuff(0, new(100000014, player.FieldPlayer.ObjectId, player.FieldPlayer.ObjectId, 1, (int)account.VIPExpiration, 1))); session.Send(PremiumClubPacket.ActivatePremium(player.FieldPlayer, account.VIPExpiration)); } session.Send(EmotePacket.LoadEmotes(player)); session.Send(MacroPacket.LoadControls(player.Macros)); session.Send(ChatStickerPacket.LoadChatSticker(player)); session.Send(ResponseCubePacket.DecorationScore(account.Home)); session.Send(ResponseCubePacket.LoadHome(player.FieldPlayer.ObjectId, player.Account.Home)); session.Send(ResponseCubePacket.ReturnMap(player.ReturnMapId)); session.Send(LapenshardPacket.Load(player.Inventory.LapenshardStorage)); IEnumerable <Cube> cubes = session.FieldManager.State.Cubes.Values .Where(x => x.Value.PlotNumber == 1 && x.Value.Item.HousingCategory is ItemHousingCategory.Farming or ItemHousingCategory.Ranching) .Select(x => x.Value); foreach (Cube cube in cubes) { session.Send(FunctionCubePacket.UpdateFunctionCube(cube.CoordF.ToByte(), 2, 1)); } if (player.Party is not null) { session.Send(PartyPacket.UpdatePlayer(player)); } GlobalEvent globalEvent = GameServer.GlobalEventManager.GetCurrentEvent(); if (globalEvent is not null && !MapMetadataStorage.MapIsInstancedOnly(player.MapId)) { session.Send(GlobalPortalPacket.Notice(globalEvent)); } FieldWar fieldWar = GameServer.FieldWarManager.CurrentFieldWar; if (fieldWar is not null && !MapMetadataStorage.MapIsInstancedOnly(player.MapId) && fieldWar.MapId != player.MapId) { session.Send(FieldWarPacket.LegionPopup(fieldWar.Id, fieldWar.EntryClosureTime.ToUnixTimeSeconds())); } session.Send(KeyTablePacket.SendHotbars(player.GameOptions)); TrophyManager.OnMapEntered(player, player.MapId); QuestManager.OnMapEnter(player, player.MapId); player.InitializeEffects(); }
public override void Handle(GameSession session, PacketReader packet) { long accountId = packet.ReadLong(); AuthData authData = DatabaseManager.AuthData.GetByAccountId(accountId); Player dbPlayer = DatabaseManager.Characters.FindPlayerById(authData.OnlineCharacterId, session); // Backwards seeking because we read accountId here packet.Skip(-8); HandleCommon(session, packet); session.InitPlayer(dbPlayer); Player player = session.Player; player.BuddyList = GameServer.BuddyManager.GetBuddies(player.CharacterId); player.Mailbox = GameServer.MailManager.GetMails(player.CharacterId); GameServer.PlayerManager.AddPlayer(player); GameServer.BuddyManager.SetFriendSessions(player); // Only send buddy login notification if player is not changing channels if (!player.IsMigrating) { player.UpdateBuddies(); } if (player.GuildId != 0) { Guild guild = GameServer.GuildManager.GetGuildById(player.GuildId); player.Guild = guild; GuildMember guildMember = guild.Members.First(x => x.Id == player.CharacterId); guildMember.Player.Session = session; player.GuildMember = guildMember; session.Send(GuildPacket.UpdateGuild(guild)); guild.BroadcastPacketGuild(GuildPacket.MemberJoin(player)); guild.BroadcastPacketGuild(GuildPacket.MemberLoggedIn(player), session); } player.IsMigrating = false; //session.Send(0x27, 0x01); // Meret market related...? session.Send(MushkingRoyaleSystemPacket.LoadStats(player.Account.MushkingRoyaleStats)); session.Send(MushkingRoyaleSystemPacket.LoadMedals(player.Account)); player.GetUnreadMailCount(); session.Send(BuddyPacket.Initialize()); session.Send(BuddyPacket.LoadList(player.BuddyList)); session.Send(BuddyPacket.EndList(player.BuddyList.Count)); // Meret market //session.Send("6E 00 0B 00 00 00 00 00 00 00 00 00 00 00 00".ToByteArray()); //session.Send("6E 00 0C 00 00 00 00".ToByteArray()); // UserConditionEvent //session.Send("BF 00 00 00 00 00 00".ToByteArray()); // PCBangBonus //session.Send("A7 00 03 00 00 00 00 00 00 00 00 00 00 00 00 00".ToByteArray()); session.Send(TimeSyncPacket.SetInitial1()); session.Send(TimeSyncPacket.SetInitial2()); session.Send(StatPacket.SetStats(session.Player.FieldPlayer)); // session.Send(StatPacket.SetStats(session.Player.FieldPlayer)); // Second packet is meant to send the stats initialized, for now we'll just send the first one session.Player.ClientTickSyncLoop(); session.Send(DynamicChannelPacket.DynamicChannel(short.Parse(ConstantsMetadataStorage.GetConstant("ChannelCount")))); session.Send(ServerEnterPacket.Enter(session)); session.Send(UgcPacket.Unknown22()); session.Send(CashPacket.Unknown09()); // SendContentShutdown f(0x01, 0x04) session.Send(PvpPacket.Mode0C()); session.Send(SyncNumberPacket.Send()); session.Send(SyncValuePacket.SetSyncValue(120000)); // unknown what this value means session.Send(PrestigePacket.SetLevels(player)); session.Send(PrestigePacket.WeeklyMissions()); // Load inventory tabs foreach (InventoryTab tab in Enum.GetValues(typeof(InventoryTab))) { player.Inventory.LoadInventoryTab(session, tab); } if (player.Account.HomeId != 0) { Home home = GameServer.HomeManager.GetHomeById(player.Account.HomeId); player.Account.Home = home; session.Send(WarehouseInventoryPacket.StartList()); int counter = 0; foreach (KeyValuePair <long, Item> kvp in home.WarehouseInventory) { session.Send(WarehouseInventoryPacket.Load(kvp.Value, ++counter)); } session.Send(WarehouseInventoryPacket.EndList()); session.Send(FurnishingInventoryPacket.StartList()); foreach (Cube cube in home.FurnishingInventory.Values.Where(x => x.Item != null)) { session.Send(FurnishingInventoryPacket.Load(cube)); } session.Send(FurnishingInventoryPacket.EndList()); } session.Send(QuestPacket.StartList()); session.Send(QuestPacket.Packet1F()); session.Send(QuestPacket.Packet20()); IEnumerable <List <QuestStatus> > packetCount = player.QuestData.Values.ToList().SplitList(200); // Split the quest list in 200 quests per packet foreach (List <QuestStatus> item in packetCount) { session.Send(QuestPacket.SendQuests(item)); } session.Send(QuestPacket.EndList()); session.Send(TrophyPacket.WriteTableStart()); List <Trophy> trophyList = new(player.TrophyData.Values); IEnumerable <List <Trophy> > trophyListPackets = trophyList.SplitList(60); foreach (List <Trophy> trophy in trophyListPackets) { session.Send(TrophyPacket.WriteTableContent(trophy)); } // SendQuest, SendAchieve, SendManufacturer, SendUserMaid session.Send(UserEnvPacket.SetTitles(player)); session.Send(UserEnvPacket.Send04()); session.Send(UserEnvPacket.Send05()); session.Send(UserEnvPacket.UpdateLifeSkills(player.GatheringCount)); session.Send(UserEnvPacket.Send09()); session.Send(UserEnvPacket.Send10()); session.Send(UserEnvPacket.Send12()); session.Send(MeretMarketPacket.ModeC9()); session.Send(FishingPacket.LoadAlbum(player)); session.Send(PvpPacket.Mode16()); session.Send(PvpPacket.Mode17()); session.Send(ResponsePetPacket.Mode07()); // LegionBattle (0xF6) // CharacterAbility // E1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 // Key bindings and skill slots would normally be loaded from a database // If the character is not a new character, this is what we would send session.Send(KeyTablePacket.SendFullOptions(player.GameOptions)); if (player.MapId == (int)Map.UnknownLocation) // tutorial map { session.Send(KeyTablePacket.AskKeyboardOrMouse()); } // SendKeyTable f(0x00), SendGuideRecord f(0x03), GameEvent f(0x00) // SendBannerList f(0x19), SendRoomDungeon f(0x05, 0x14, 0x17) session.Send(DungeonListPacket.DungeonList()); // 0xF0, ResponsePet P(0F 01) // RequestFieldEnter //session.Send("16 00 00 41 75 19 03 00 01 8A 42 0F 00 00 00 00 00 00 C0 28 C4 00 40 03 44 00 00 16 44 00 00 00 00 00 00 00 00 55 FF 33 42 E8 49 01 00".ToByteArray()); session.Send(RequestFieldEnterPacket.RequestEnter(player.FieldPlayer)); Party party = GameServer.PartyManager.GetPartyByMember(player.CharacterId); if (party != null) { player.Party = party; party.BroadcastPacketParty(PartyPacket.LoginNotice(player), session); session.Send(PartyPacket.Create(party, false)); } // SendUgc: 15 01 00 00 00 00 00 00 00 00 00 00 00 4B 00 00 00 // SendHomeCommand: 00 E1 0F 26 89 7F 98 3C 26 00 00 00 00 00 00 00 00 player.TimeSyncLoop(); session.Send(TimeSyncPacket.SetSessionServerTick(0)); //session.Send("B9 00 00 E1 0F 26 89 7F 98 3C 26 00 00 00 00 00 00 00 00".ToByteArray()); session.Send(ServerEnterPacket.Confirm()); //session.Send(0xF0, 0x00, 0x1F, 0x78, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00); //session.Send(0x28, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00); }
public override void Execute(GameCommandTrigger trigger) { Player player = trigger.Session.Player; // Reset stats to default player.Stats = new(player.Job); player.Stats.AddBaseStats(player, 90); trigger.Session.Send(StatPacket.SetStats(player.FieldPlayer)); trigger.Session.FieldManager.BroadcastPacket(StatPacket.SetStats(player.FieldPlayer), trigger.Session); player.Levels.SetLevel(90); player.Levels.SetPrestigeLevel(100); player.Wallet.Meso.SetAmount(10_000_000_000); // 10B player.Account.Meret.SetAmount(10_000_000_000); // 10B PremiumClubHandler.ActivatePremium(trigger.Session, 2592000); // 30 days in seconds // Stickers for (int i = 1; i < 7; i++) { if (player.ChatSticker.Any(x => x.GroupId == i)) { continue; } trigger.Session.Send(ChatStickerPacket.AddSticker(21100000 + i, i, long.MaxValue)); player.ChatSticker.Add(new((byte)i, long.MaxValue)); } List <int> emotes = SkillMetadataStorage.GetEmotes(); foreach (int emoteId in emotes) { // Broken emotes if (emoteId is >= 90200032 and <= 90200036) { continue; } if (player.Emotes.Contains(emoteId)) { continue; } player.Emotes.Add(emoteId); trigger.Session.Send(EmotePacket.LearnEmote(emoteId)); } List <TitleMetadata> titles = TitleMetadataStorage.GetAll(); foreach (TitleMetadata title in titles) { int titleId = title.Id; if (player.Titles.Contains(titleId)) { continue; } player.Titles.Add(titleId); trigger.Session.Send(UserEnvPacket.AddTitle(titleId)); } DatabaseManager.Characters.Update(player); trigger.Session.Send(NoticePacket.Notice("Done!", NoticeType.Chat)); }
private void HandleEquipItem(GameSession session, PacketReader packet) { long itemUid = packet.ReadLong(); string equipSlotStr = packet.ReadUnicodeString(); if (!Enum.TryParse(equipSlotStr, out ItemSlot equipSlot)) { Logger.Warning("Unknown equip slot: " + equipSlotStr); return; } // Remove the item from the users inventory InventoryController.Remove(session, itemUid, out Item item); // Get correct equipped inventory Dictionary <ItemSlot, Item> equippedInventory = session.Player.GetEquippedInventory(item.InventoryTab); if (equippedInventory == null) { Logger.Warning("equippedInventory was null: " + item.InventoryTab); return; } // Move previously equipped item back to inventory if (equippedInventory.Remove(equipSlot, out Item prevItem)) { prevItem.Slot = item.Slot; InventoryController.Add(session, prevItem, false); session.FieldManager.BroadcastPacket(EquipmentPacket.UnequipItem(session.FieldPlayer, prevItem)); } // Handle unequipping pants when equipping dresses // Handle unequipping off-hand when equipping two-handed weapons if (item.IsDress || item.IsTwoHand) { if (equippedInventory.Remove(item.IsDress ? ItemSlot.PA : ItemSlot.LH, out Item prevItem2)) { prevItem2.Slot = -1; if (prevItem == null) { prevItem2.Slot = item.Slot; } InventoryController.Add(session, prevItem2, false); session.FieldManager.BroadcastPacket(EquipmentPacket.UnequipItem(session.FieldPlayer, prevItem2)); } } // Handle unequipping dresses when equipping pants // Handle unequipping two-handed main-hands when equipping off-hand weapons if (item.ItemSlot == ItemSlot.PA || item.ItemSlot == ItemSlot.LH) { ItemSlot prevItemSlot = item.ItemSlot == ItemSlot.PA ? ItemSlot.CL : ItemSlot.RH; if (equippedInventory.ContainsKey(prevItemSlot)) { if (equippedInventory[prevItemSlot] != null && equippedInventory[prevItemSlot].IsDress) { if (equippedInventory.Remove(prevItemSlot, out Item prevItem2)) { prevItem2.Slot = item.Slot; InventoryController.Add(session, prevItem2, false); session.FieldManager.BroadcastPacket(EquipmentPacket.UnequipItem(session.FieldPlayer, prevItem2)); } } } } // Equip new item equippedInventory[equipSlot] = item; session.FieldManager.BroadcastPacket(EquipmentPacket.EquipItem(session.FieldPlayer, item, equipSlot)); if (item.InventoryTab == InventoryTab.Gear) { // TODO - Increase stats based on the item stats itself session.Player.Stats.CritRate.Max += 12; session.Player.Stats.CritRate.Total += 12; session.Player.Stats.MinAtk.Max += 15; session.Player.Stats.MinAtk.Total += 15; session.Player.Stats.MaxAtk.Max += 17; session.Player.Stats.MaxAtk.Total += 17; session.Player.Stats.MagAtk.Max += 15; session.Player.Stats.MagAtk.Total += 15; session.Send(StatPacket.SetStats(session.FieldPlayer)); } }
private static void HandleResetStatDistribution(GameSession session) { session.Player.Stats.ResetAllocations(session.Player.StatPointDistribution); session.Send(StatPointPacket.WriteStatPointDistribution(session.Player)); // Deprecate? session.Send(StatPacket.SetStats(session.FieldPlayer)); }