public void Add(WvsGameClient c) { var character = c.Character; if (c.SentCharData) { c.SendPacket(CPacket.SetField(character, false, c.ChannelId)); } else { c.SentCharData = true; #if DEBUG //So me myself and i all spawn close to eachother <3 character.Stats.nPortal = 0; #else character.Stats.nPortal = Portals.GetRandomSpawn(); #endif c.SendPacket(CPacket.SetField(character, true, c.ChannelId)); } //Send client being added all the existing characters in the map Characters.ForEach(x => c.SendPacket(CPacket.UserEnterField(x))); SendSpawnMobs(c); SendSpawnNpcs(c); Characters.Add(c.Character); Sockets.Add(c.Character, c); //Broadcast everyone already in the map that you have arrived Broadcast(CPacket.UserEnterField(character), c); }
public static void Handle_Whisper(WvsGameClient c, CInPacket p) { // Recv [CP_Whisper] [8D 00] [05] [7C 9E D7 14] [05 00] [70 65 6E 69 73] var flag = p.Decode1(); // COutPacket::Encode1((COutPacket *)&oPacket, ((v44 == 0) + 1) | 4); p.Decode4(); // tick var name = p.DecodeString(); if (name.Length > 13) { return; } var pTargetUser = MasterManager.CharacterPool.Get(name, false); if (pTargetUser is null) // will not be null if char is in itc or cs { c.SendPacket(WhisperResult(name, false)); return; } switch (flag) // todo make this an enumerator { case 5: // /find command { var nTargetChannel = pTargetUser.ChannelID; if (MasterManager.CharacterPool.CharInCashShop(pTargetUser.dwId)) { c.SendPacket(FindResult(pTargetUser.Stats.sCharacterName, Actions.FindResult.CS)); } else if (nTargetChannel == c.ChannelId) { c.SendPacket(FindResult(pTargetUser.Stats.sCharacterName, Actions.FindResult.SameChannel, pTargetUser.Field.MapId)); } else { c.SendPacket(FindResult(pTargetUser.Stats.sCharacterName, Actions.FindResult.DifferentChannel, pTargetUser.ChannelID)); } } break; case 6: // whisper { var msg = p.DecodeString(); if (msg.Length > 75) { return; // PE or trying to find player } pTargetUser.SendPacket(WhisperMessage(c.Character.Stats.sCharacterName, c.Character.ChannelID, c.Character.Account?.AccountData.Admin > 0, msg)); c.SendPacket(WhisperResult(c.Character.Stats.sCharacterName, true)); } break; } }
public void SendSpawnMobs(WvsGameClient c) { foreach (var mob in Mobs) { if (mob.Controller == 0 || mob.Controller == c.Character.CharId) { mob.Controller = c.Character.CharId; c.SendPacket(CPacket.MobChangeController(mob, 1)); } c.SendPacket(CPacket.MobEnterField(mob)); } }
public static void Equip(WvsGameClient c, short src, short dst) { var character = c.Character; var source = character.aInvEquip.GetKvp(src); // in equip var target = character.aInvEquippedNormal.GetKvp(dst); //EQUIPPED bool r1 = character.aInvEquippedNormal.Remove(dst); bool r2 = character.aInvEquip.Remove(src); if (r1) { character.aInvEquip.Add(src, target.Value); character.Look.anHairEquip[Math.Abs(dst)] = 0; } if (r2) { character.aInvEquippedNormal.Add(dst, source.Value); character.Look.anHairEquip[Math.Abs(dst)] = source.Value.nItemID; } c.SendPacket(CPacket.InventoryMoveItem((byte)InventoryType.EQUIP, src, dst, 2)); Broadcast_UserAvatarModified(c); }
public void SendSpawnNpcs(WvsGameClient c) { foreach (var npc in Npcs) { c.SendPacket(CPacket.NpcEnterField(npc)); } }
public static void Drop(WvsGameClient c, byte type, short src, short qty) { var ret = GetInventory(type, c.Character); if (ret is CInventory <short, GW_ItemSlotEquip> v1) { var source = v1.Get(src); if (source == null) { return; } v1.Remove(src); //This pocket is not working :( c.SendPacket(CPacket.InventoryDropItem(type, src, qty)); c.SendPacket(CPacket.BroadcastPinkMsg("Deleted item, doesnt drop yet")); } else if (ret is CInventory <byte, GW_ItemSlotBundle> v2) { var source = v2.Get((byte)src); if (source == null) { return; } source.nNumber -= qty; if (source.nNumber <= 0) { v2.Remove((byte)src); c.SendPacket(CPacket.BroadcastPinkMsg("Deleted item")); } //This pocket is not working :( c.SendPacket(CPacket.InventoryDropItem(type, src, qty)); } else { Logger.Write(LogLevel.Error, "What the f**k have you done?"); } }
public static void EntrustedShopRequest(WvsGameClient c, CInPacket p) { var opCode = p.Decode1(); if (opCode == 0) { var outP = new COutPacket(SendOps.LP_EntrustedShopCheckResult); outP.Encode1(0x07); c.SendPacket(outP); } }
public static void OnPacket(WvsGameClient c, CInPacket p) { var chr = c.Character; var targetId = p.Decode4(); short type = p.Decode1(); var targetChar = chr.Field.Users[targetId]; if (targetChar is null || chr.dwId == targetId) { c.SendPacket(GivePopularityResult_Error(GivePopularityRes.InvalidCharacterID)); return; }
// --------------------------------------------------- Handlers public override void HandleVisit(CInPacket p, WvsGameClient c) // 0x04 { if (c.Character.dwId == OwnerID) { c.Character.SendMessage("Handle maintenance"); HandleMaintenance(); } else if (InBlackList(c.Character)) { c.SendPacket(CPacket.SystemMessage("The owner of this room has blocked you.")); } else if (!ShopOpen) { c.SendPacket(CPacket.SystemMessage("The shop is currently undergoing maintenance.")); } else if (!HasSpace) { c.SendPacket(CPacket.SystemMessage("The shop is currently at max capacity. Please try again later.")); } else { VisitorAdd(c.Character); } }
public static void OnPacket(WvsGameClient c, CInPacket p) { var nRecipeClass = p.Decode4(); var nItemID = p.Decode4(); switch (nRecipeClass) { case 1: case 2: // create var bMounted = p.Decode1(); var nNumGem_Mounted = p.Decode4(); var aGemSlot_pItemp = new List <int>(); for (int i = 0; i < nNumGem_Mounted; i++) { aGemSlot_pItemp.Add(p.Decode4()); } HandleCreateItemOp(c.Character, nItemID, bMounted > 0, aGemSlot_pItemp); break; case 3: // build monster crystal HandleBuildMonsterCrystalOp(c.Character, nItemID); break; case 4: // disassemble var nInvType = (InventoryType)p.Decode4(); var nSlotPosition = p.Decode4(); HandleDisassembleOp(c.Character, nInvType, nItemID, nSlotPosition); break; default: Log.Info("Found unhandled ItemMakeRequest opcode : " + nRecipeClass); break; } c.SendPacket(MakerRelease()); }
public static void UnEquip(WvsGameClient c, short src, short dst) { var character = c.Character; var source = character.aInvEquippedNormal.GetKvp(src); //var target = character.aInvEquip.GetKvp(dst); if (character.aInvEquippedNormal.Remove(src)) { character.aInvEquip.Add(dst, source.Value); character.Look.anHairEquip[Math.Abs(src)] = 0; } c.SendPacket(CPacket.InventoryMoveItem(1, src, dst, 1)); Broadcast_UserAvatarModified(c); }
public static void Move(WvsGameClient c, byte type, short src, short dst) { var ret = GetInventory(type, c.Character); if (ret is CInventory <short, GW_ItemSlotEquip> v1) { var source = v1.GetKvp(src); var target = v1.GetKvp(dst); if (v1.Remove(target.Key)) { v1.Add(src, target.Value); } if (v1.Remove(source.Key)) { v1.Add(dst, source.Value); } } else if (ret is CInventory <byte, GW_ItemSlotBundle> v2) { var source = v2.GetKvp((byte)src); var target = v2.GetKvp((byte)dst); if (v2.Remove(target.Key)) { v2.Add((byte)src, target.Value); } if (v2.Remove(source.Key)) { v2.Add((byte)dst, source.Value); } } else { Logger.Write(LogLevel.Error, "What the f**k have you done?"); } c.SendPacket(CPacket.InventoryMoveItem(type, src, dst, 0xFF)); }
public static void OnPacket(WvsGameClient c, CInPacket p) { var pChar = c.Character; var pMiniRoom = pChar.CurMiniRoom; Log.Debug($"Begin Handle_MiniRoom"); var opcode = p.Decode1(); Log.Debug($"Operation: {opcode}"); switch ((MR_Action)opcode) { case MR_Action.MRP_Create: { var type = p.Decode1(); Log.Debug($"Create Type: {type}"); c.Character.Field.MiniRooms.CreateMiniRoom(c.Character, (MR_Type)type, p); break; } case MR_Action.MRP_Invite: // occurs in some but not all rooms (games, messenger, trade, not shops) { var dwTargetCharId = p.Decode4(); Log.Debug($"Processing trade invite request to char ID {dwTargetCharId}"); if (pMiniRoom is CTradingRoom room) { room.HandleSendInvite(dwTargetCharId); } break; } case MR_Action.MRP_InviteResult: { if (pMiniRoom is CTradingRoom ctr) { ctr.HandleDecline(); } break; } case MR_Action.MRP_Enter: { var targetRoomId = p.Decode4(); // theres two more bytes after this which im curious to know what they do... // the extra bytes might be fm room?? for remote merchants?? Log.Info($"DWID: {targetRoomId}"); var room = pChar.Field.MiniRooms.FirstOrDefault(r => r.dwId == targetRoomId); // if remote merchant operations use this same packet process then it will not work because we're searching by field.. we'd need to search by a range of fields in the channel instead if (room is null) { c.SendPacket(FailedEnterPacket()); } else { room?.HandleVisit(p, c); } break; } case MR_Action.MRP_Chat: { p.Skip(4); // timestamp pChar.CurMiniRoom?.HandleChat(pChar, p.DecodeString()); break; } case MR_Action.MRP_Leave: { pChar.CurMiniRoom?.HandlePlayerExit(pChar, MR_LeaveResult.UserRequest); break; } case MR_Action.ESP_WithdrawAll: // owner close { if (pChar.CurMiniRoom is CEntrustedShop ces && ces.OwnerID == pChar.dwId) { ces.WithdrawAll(); ces.HandlePlayerExit(pChar, MR_LeaveResult.UserRequest); ces.Destroy(); } break; } case MR_Action.MRP_Balloon: // ?? these names lmao { if (pChar.CurMiniRoom is CEntrustedShop ces && pChar.CurMiniRoom.OwnerID == pChar.dwId) { // pChar.Field.Broadcast(r.MakeEnterFieldPacket()); // gms spawns the shop after owner fills it with items ces.ShopOpen = true; pChar.CurMiniRoom = null; } break; } case MR_Action.TRP_PutItem: { if (pChar.CurMiniRoom is CTradingRoom ctr) { ctr.HandleAddItem(p, pChar); } break; } case MR_Action.TRP_PutMoney: { if (pChar.CurMiniRoom is CTradingRoom ctr) { ctr.HandleSetMeso(pChar, p.Decode4()); } break; } case MR_Action.TRP_Trade: { if (pChar.CurMiniRoom is CTradingRoom ctr) { ctr.HandleConfirmTrade(pChar); } break; } case MR_Action.PSP_PutItem: case MR_Action.ESP_PutItem: { if (pChar.CurMiniRoom is CEntrustedShop ces && pChar.CurMiniRoom.OwnerID == pChar.dwId) { ces.AddItem(p); } break; } case MR_Action.ESP_BuyItem: case MR_Action.PSP_BuyItem: { if (pChar.CurMiniRoom is CEntrustedShop ces) { ces.SellItem(c.Character, p); } break; } case MR_Action.ESP_Refresh: case MR_Action.PSP_Refresh: { if (pChar.CurMiniRoom is CEntrustedShop ces) { ces.Refresh(pChar); } break; } case MR_Action.ESP_MoveItemToInventory: case MR_Action.PSP_MoveItemToInventory: { if (pChar.CurMiniRoom is CEntrustedShop ces) { ces.RemoveItem(p); } break; } case MR_Action.PSP_Ban: case MR_Action.MGRP_Ban: { if (pChar.CurMiniRoom is CEntrustedShop ces && pChar.CurMiniRoom.OwnerID == pChar.dwId) { //ces.BanPlayer(p.DecodeString()); } break; } case MR_Action.ESP_ArrangeItem: { if (pChar.CurMiniRoom is CEntrustedShop ces && pChar.CurMiniRoom.OwnerID == pChar.dwId) { ces.ArrangeItems(); } break; } case MR_Action.ESP_DeliverVisitList: { if (pChar.CurMiniRoom is CEntrustedShop ces && pChar.CurMiniRoom.OwnerID == pChar.dwId) { ces.DeliverVisitList(); } break; } case MR_Action.ESP_DeliverBlackList: case MR_Action.PSP_DeliverBlackList: { if (pChar.CurMiniRoom is CEntrustedShop ces && pChar.CurMiniRoom.OwnerID == pChar.dwId) { ces.DeliverBlackList(); } break; } case MR_Action.ESP_AddBlackList: case MR_Action.PSP_AddBlackList: { if (pChar.CurMiniRoom is CEntrustedShop ces && pChar.CurMiniRoom.OwnerID == pChar.dwId) { ces.AddBlackList(p); } break; } case MR_Action.PSP_DeleteBlackList: case MR_Action.ESP_DeleteBlackList: { if (pChar.CurMiniRoom is CEntrustedShop ces && pChar.CurMiniRoom.OwnerID == pChar.dwId) { ces.DeleteBlackList(p); } break; } default: Log.Info($"Unhandled MiniRoom packet. OpCode: {opcode}."); Log.Info($"Full packet: {BitConverter.ToString(p.ToArray()).Replace("-", " ")}"); break; } pChar.Action.Enable(); }
protected void SendOk(string text) { m_client.SendPacket(CPacket.NpcScriptMessage(m_npcId, 0, text, "00 00", 0, 0)); }
/// <summary> /// Sends migratein packet depending on character migration status. /// Triggers OnUserEnter() for child classes /// Notifies proper social channels /// </summary> /// <param name="c"></param> public void AddClient(WvsGameClient c) { var character = c.Character; var bSendPartyMapChangeUpdate = c.MigratedIn; if (Template.HasNoPetLimit()) { character.Stats.aliPetLockerSN = new long[3]; // clear pets character.Pets.Dispose(); } if (Template.HasSummonLimit()) { MasterManager.SummonStorage.Retrieve(character.dwId); // clear incoming summons } if (c.MigratedIn) { var p = CPacket.SetField(character, c.ChannelId, c.WorldID); c.SendPacket(p); } else { c.MigratedIn = true; #if DEBUG character.Stats.nPortal = 0; //Spawn everyone in same place #else var sp = Portals.GetRandStartPoint(); if (sp != null) { var foothold = Footholds.FindBelow(sp.nX, sp.nY); if (foothold != null) { character.Stats.nPortal = (byte)sp.nIdx; character.Position.X = foothold.X1; character.Position.Y = foothold.Y1; character.Position.Foothold = foothold.Id; } } #endif //TODO: Refine our flags for production var dbFlag = (DbCharFlags)0; //dbFlag |= DbCharFlags.ALL; dbFlag |= DbCharFlags.CHARACTER; dbFlag |= DbCharFlags.MONEY; dbFlag |= DbCharFlags.INVENTORYSIZE; dbFlag |= DbCharFlags.ITEMSLOTEQUIP; dbFlag |= DbCharFlags.ITEMSLOTCONSUME; dbFlag |= DbCharFlags.ITEMSLOTINSTALL; dbFlag |= DbCharFlags.ITEMSLOTETC; dbFlag |= DbCharFlags.ITEMSLOTCASH; dbFlag |= DbCharFlags.SKILLRECORD; dbFlag |= DbCharFlags.SKILLCOOLTIME; dbFlag |= DbCharFlags.QUESTRECORD; dbFlag |= DbCharFlags.QUESTCOMPLETE; //dbFlag |= DbCharFlags.MINIGAMERECORD; dbFlag |= DbCharFlags.COUPLERECORD; dbFlag |= DbCharFlags.MONSTERBOOKCOVER; dbFlag |= DbCharFlags.MONSTERBOOKCARD; dbFlag |= DbCharFlags.QUESTRECORDEX; if (JobLogic.IsWildhunterJob(character.Stats.nJob)) { dbFlag |= DbCharFlags.WILDHUNTERINFO; } dbFlag |= DbCharFlags.MAPTRANSFER; c.SendPacket(CPacket.SetField(character, c.ChannelId, c.WorldID, Constants.LogoutGift, dbFlag)); } OnUserEnter(c.Character); if (bSendPartyMapChangeUpdate) { c.Character.NotifySocialChannels(SocialNotiflag.ChangeMap); } }