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; } }
private void Handle_CheckPassword(WvsLoginClient c, CInPacket p) { var szPassword = p.DecodeString(); var szUsername = p.DecodeString(); try { byte nLoginRet = TryDoClientLogin(c, szUsername, szPassword); if (nLoginRet == 0) { c.LoggedIn = true; var storage = ServerApp.Container.Resolve <CenterStorage>(); storage.AddAccountOnline(c.Account.ID); byte nGradeCode = 0; short nSubGradeCode = 0; //TODO: Adjust gradecode based on admin level if (c.Account.AccountData.Admin > 0) { //nGradeCode = 0x01; //Admin //nSubGradeCode ^= 0x0001; //PS_PrimaryTrace //nSubGradeCode ^= 0x0002; //PS_SecondaryTrace //nSubGradeCode ^= 0x0004; //PS_AdminClient //nSubGradeCode ^= 0x0008; //PS_MobMoveObserve //nSubGradeCode ^= 0x0010; //PS_ManagerAccount //nSubGradeCode ^= 0x0020; //PS_OutSourceSuperGM //nSubGradeCode ^= 0x0040; //PS_OutSourceGM //nSubGradeCode ^= 0x0080; //PS_UserGM //nSubGradeCode ^= 0x0100; //PS_TesterAccount } c.SendPacket(CPacket.CLogin.CheckPasswordResult(c.Account.ID, (byte)c.Account.Gender, nGradeCode, nSubGradeCode, szUsername)); } else if (nLoginRet == 9) { c.Disconnect(); //Too many login attempts } else { c.SendPacket(CPacket.CLogin.CheckPasswordResult(nLoginRet)); } } catch (Exception ex) { Log.ErrorFormat("[CheckPassword] Exception: {0}", ex); c.SendPacket(CPacket.CLogin.CheckPasswordResult(6)); // salt error } }
private void Handle_UserTransferFieldRequest(WvsGameClient c, CInPacket p) { if (p.Available == 0) { //Cash Shop Related return; } //TODO: Portal count checks //TODO: XY rect checks //TODO: Keep track if player spawns when entering a field var portalCount = p.Decode1(); //CField::GetFieldKey(v20); var destination = p.Decode4(); // var portalName = p.DecodeString(); var x = p.Decode2(); var y = p.Decode2(); //var extra = p.DecodeBuffer(3); idk | prem | chase var portal = c.GetCharField() .Portals .GetByName(portalName); if (portal == null) { Logger.Write(LogLevel.Warning, "Client tried to enter non existant portal {0}", portalName); } else { c.UsePortal(portal); } }
public static void UserChat(WvsGameClient c, CInPacket p) { p.Decode4(); var sText = p.DecodeString(); var bOnlyBalloon = p.Decode1() != 0; if (sText.Length >= sbyte.MaxValue) { return; } var handle = ServerApp.Container.Resolve <CommandHandle>(); if (!handle.Execute(c.Character, sText)) { var bAdmin = c.Account.AccountData.Admin > 0; CCurseProcess.ProcessString(sText, out var output); if (output.Length <= 0) { return; } c.Character.Field.Broadcast(CPacket.UserChat(c.Character.dwId, output, bAdmin, bOnlyBalloon)); } }
private void Handle_CheckDuplicatedID(WvsLoginClient c, CInPacket p) { var charName = p.DecodeString(); bool nameTaken = IsUsernameTaken(charName); c.SendPacket(CPacket.CheckDuplicatedIDResult(charName, nameTaken)); }
public static void DeleteCharacter(WvsLoginClient c, CInPacket p) { var szSPW = p.DecodeString(); var dwCharID = p.Decode4(); // TODO check for guild ownership and family membership byte nRetCode = 0x09; //Error var aCharList = c.Account.LoadCharIdList(); if (aCharList.Contains(dwCharID)) { using (var conn = new NpgsqlConnection(Constants.DB_World0_ConString)) { conn.Open(); using (var cmd = new NpgsqlCommand($"DELETE FROM {Constants.DB_All_World_Schema_Name}.characters WHERE id = {dwCharID}", conn)) { cmd.ExecuteNonQuery(); } } nRetCode = 0; //Success } c.SendPacket(CPacket.CLogin.DeleteCharacter(dwCharID, nRetCode)); }
public static void CharacterNameInUse(WvsLoginClient c, CInPacket p) { bool retVal = false; var charName = p.DecodeString(); using (var conn = new NpgsqlConnection(Constants.DB_World0_ConString)) { conn.Open(); using (var cmd = new NpgsqlCommand($"SELECT * FROM {Constants.DB_All_World_Schema_Name}.characters WHERE name = (@name)", conn)) { cmd.Parameters.AddWithValue("name", charName); using (var r = cmd.ExecuteReader()) { while (r.Read()) { retVal = true; // values to read means entry exists break; } } } } c.SendPacket(CheckDuplicatedIDResult(charName, retVal)); }
public void DeleteBlackList(CInPacket p) { var sNameToRemove = p.DecodeString(); pBlackList.Remove(sNameToRemove); // do we respond with anything??? }
private void Handle_CheckPassword(WvsLoginClient c, CInPacket p) { var pwd = p.DecodeString(); var user = p.DecodeString(); var result = c.Login(user, pwd); if (result == 0) { var acc = c.Account; c.SendPacket(CPacket.CheckPasswordResult(acc.AccId, acc.Gender, 0, user)); } else { c.SendPacket(CPacket.CheckPasswordResult(result)); } }
public void OnPetPacket(RecvOps opCode, CInPacket p) { switch (opCode) { case RecvOps.CP_PetDropPickUpRequest: break; case RecvOps.CP_PetInteractionRequest: break; case RecvOps.CP_UserActivatePetRequest: break; case RecvOps.CP_UserDestroyPetItemRequest: break; default: var liPetLockerSN = p.Decode8(); var item = Pets.FirstOrDefault(pet => pet.liPetLockerSN == liPetLockerSN); if (item is null) { return; } switch (opCode) { case RecvOps.CP_PetMove: item.Move(p); break; case RecvOps.CP_PetStatChangeItemUseRequest: // CPet::OnNameChanged(v4, iPacket); break; case RecvOps.CP_PetUpdateExceptionListRequest: break; case RecvOps.CP_PetAction: case RecvOps.CP_PetActionCommand: var tick = p.Decode4(); var nType = p.Decode1(); var nAction = p.Decode1(); var sMsg = p.DecodeString(); // rebroadcasting this is bad practice Parent.Field.Broadcast(item.PetActionCommand((PetActType)nType, nAction, true, true), Parent); break; } break; } }
private void Handle_SelectCharacter(WvsLoginClient c, CInPacket p) { var dwUserId = p.Decode4(); var szLocalMacAddress = p.DecodeString(); var szLocalMacAddressWithHDDSerialNo = p.DecodeString(); //TODO: Character CCKey Redis var aCharList = c.Account.LoadCharIdList(); if (aCharList.Contains(dwUserId)) { c.SelectedUser = dwUserId; var pStorage = ServerApp.Container.Resolve <CenterStorage>(); pStorage.AddCharacterMigrate(dwUserId); var pCenter = ServerApp.Container.Resolve <WvsCenter>(); var usPort = (short)pCenter.WvsGames[c.ChannelId].Port; c.SendPacket(CPacket.CLogin.SelectCharacterResult(dwUserId, Constants.ServerAddress, usPort)); } }
public void AddBlackList(CInPacket p) { var sNameToAdd = p.DecodeString(); for (int i = 0; i < nMaxUsers; i++) { var pVisitor = MasterManager.CharacterPool.Get(aCurVisitors[i]); if (pVisitor?.Stats.sCharacterName.EqualsIgnoreCase(sNameToAdd) ?? false) { HandlePlayerExit(pVisitor, MR_LeaveResult.Kicked); break; } } pBlackList.Add(sNameToAdd); }
private void Handle_CashShopCheckCouponRequest(WvsShopClient c, CInPacket p) { p.Decode2(); // something var code = p.DecodeString(); var coupon = new CouponCode(code, c); if (coupon.Invalid) { c.SendPacket(CPacket.CCashShop.CouponFail(CashItemFailed.InvalidCoupon)); } else if (coupon.Used) { c.SendPacket(CPacket.CCashShop.CouponFail(CashItemFailed.UsedCoupon)); } else if (coupon.IncorrectAccount) { c.SendPacket(CPacket.CCashShop.CouponFail(CashItemFailed.NotAvailableCoupon)); } else if (coupon.Expired) { c.SendPacket(CPacket.CCashShop.CouponFail(CashItemFailed.ExpiredCoupon)); } else if (coupon.Items != null && !InventoryManipulator.HasSpace(c.Character, coupon.Items)) { c.SendPacket(CPacket.CCashShop.CouponFail(CashItemFailed.NoEmptyPos)); // TODO fix this } else { if (coupon.Items != null) { foreach (var item in coupon.Items) { InventoryManipulator.InsertInto(c.Character, MasterManager.CreateItem(item, false)); CPacket.CCashShop.CouponAddItem(item); } } c.Account.AccountData.NX_Prepaid += coupon.NX; coupon.Dispose(); c.Account.Save(); } c.EnableActions(); }
/** * Die packet: * Recv [CP_UserTransferFieldRequest] [29 00] [01] [00 00 00 00] 00 00 00 01 00 // last bytes possibly related to death-items * Portal to other map packet: * Recv [CP_UserTransferFieldRequest] [29 00] [01] [FF FF FF FF] [06 00] [65 61 73 74 30 30] [4D 06] [C7 01] 00 00 00 */ public static void Field(WvsGameClient c, CInPacket p) { //void __thiscall CUser::OnTransferFieldRequest(CUser *this, int bLoopback, CInPacket *iPacket) //Exit Cash Shop -> Not used in WvsGame if (p.Available == 0) { return; } //TODO: Portal count checks //TODO: XY rect checks to ensure player is on portal when activating it //TODO: Keep track if player spawns when entering a field var bFieldKey = p.Decode1(); //CField::GetFieldKey(v20); var dwField = p.Decode4(); var sPortalName = p.DecodeString(); if (c.Character.Stats.nHP <= 0) { c.Character.Field.OnUserWarpDie(c.Character); } else if (sPortalName.Length > 0) // not death { var x = p.Decode2(); var y = p.Decode2(); p.Decode1(); // used to be bTownPortal var bPremium = p.Decode1(); var bChase = p.Decode1(); if (bChase > 0) { var nTargetPosition_X = p.Decode4(); var nTargetPosition_Y = p.Decode4(); } c.Character.Field.OnUserEnterPortal(c.Character, sPortalName); } else // gm warp command { // TODO admin checks // tp to desired field } }
private void Handle_UserChat(WvsGameClient c, CInPacket p) { var tick = p.Decode4(); var msg = p.DecodeString(); var show = p.Decode1() != 0; if (msg.StartsWith("!")) { var split = msg.Split(' '); split[0] = split[0].Remove(0, 1); c.HandleCommand(split); } else { c.GetCharField().Broadcast(CPacket.UserChat(c.Character.CharId, msg, true, show)); } }
public static void Handle_GroupMessage(WvsGameClient c, CInPacket p) { // : [8C 00] [5B BE 87 0F] [01] [01] [69 04 00 00] [03 00] [61 73 64] var get_update_time = p.Decode4(); var nChatTarget = p.Decode1(); var nMemberCnt = p.Decode1(); var aMemberList = p.DecodeIntArray(nMemberCnt); var sText = p.DecodeString(); // [INFO] Recv [CP_GroupMessage] 8C 00 30 9F 4F 0F 01 01 69 04 00 00 05 00 61 73 64 77 64 if (sText.Length >= sbyte.MaxValue) { c.Character.SendMessage("Chat message exceeded allowed length."); return; } MasterManager.Log.Debug("Text: " + sText); switch ((GroupMessageType)nChatTarget) { case GroupMessageType.BuddyChat: c.Character.Friends.HandleBuddyChat(sText, aMemberList); break; case GroupMessageType.PartyChat: c.Character.Party?.HandlePartyChat(c.Character.dwId, c.Character.Stats.sCharacterName, sText); break; case GroupMessageType.ExpeditionChat: // todo break; case GroupMessageType.GuildChat: // todo break; case GroupMessageType.AllianceChat: // todo break; } }
public void Decode(CInPacket p) { var name = p.DecodeString(); if (name.Length != 0 && (name.Length < 4 || name.Length > 13)) { name = "Invalid"; } sName = name; bMute = p.Decode1() != 0; for (int i = 0; i < SkillLength; i++) { aSkill[i] = p.Decode4(); } }
// Recv [CP_PartyRequest] [91 00] [04] [06 00] [70 6F 6F 6D 61 6E] private void Invite(Character c, CInPacket p) { var inviteName = p.DecodeString(); var invitePlayer = MasterManager.CharacterPool.Get(inviteName); if (invitePlayer is null) { c.SendPacket(CPacket.CPartyMan.Party_Error(PartyOps.PartyRes_JoinParty_UnknownUser)); } else if (invitePlayer.Party != null) { c.SendPacket(CPacket.CPartyMan.Party_Error(PartyOps.PartyRes_JoinParty_AlreadyJoined)); } else if (GetParty(c)?.dwOwnerId != c.dwId && GetParty(c) != null) { c.SendPacket(CPacket.CPartyMan.Party_Error(PartyOps.PartyRes_JoinParty_Unknown)); } else { if (GetParty(c) is null) { Create(c, p); } if (GetParty(c).Count >= 6) { c.SendPacket(CPacket.CPartyMan.Party_Error(PartyOps.PartyRes_JoinParty_AlreadyFull)); } else if (GetParty(c).Contains(invitePlayer.dwId)) { c.SendPacket(CPacket.CPartyMan.Party_Error(PartyOps.PartyRes_JoinParty_AlreadyJoined)); } else { GetParty(c).AddInvite(invitePlayer.dwId); invitePlayer?.SendPacket(CPacket.CPartyMan.InviteParty(c, GetParty(c))); c.SendPacket(CPacket.CPartyMan.InviteParty_Sent(inviteName)); } } }
public bool OnUseRequest(int nItemID, CInPacket p) { var bWarpToPlayer = p.Decode1(); var nMapID = 0; var bExt = false; //Set by nItemID //TODO: ERROR LOGIC //SENDING THE CORRECT RESP if (bWarpToPlayer != 0) { var sPlayer = p.DecodeString(); //cant find remote player ? DifficultToLocate var remote = MasterManager.CharacterPool.Get(sPlayer, false); if (remote?.ChannelID != Parent.ChannelID || remote.Field.IsInstanced || Parent.Field.IsInstanced) { Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.TargetNotExist, bExt)); return(false); } if (remote.Stats.nHP <= 0 || Parent.Stats.nHP <= 0) { Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.TargetDied, bExt)); return(false); } nMapID = remote.Field.MapId; } else { nMapID = p.Decode4(); } if (Parent.Field.MapId == nMapID) { Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.AlreadyInMap, bExt)); return(false); } if (Parent.Field.Template.HasTeleportItemLimit() || (Parent.Field.ParentInstance.CFieldMan.GetField(nMapID)?.Template.HasTeleportItemLimit() ?? true)) { Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.TargetNotExist, bExt)); return(false); } if (!adwMapTransfer.Contains(nMapID)) { Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.TargetNotExist, bExt)); return(false); } Parent.SendPacket(CPacket.MapTransferResult(MapTransferRes.Use, bExt)); Parent.Action.SetField(nMapID, 0, 0); return(true); }
public static void CreateCharacter(WvsLoginClient c, CInPacket p) { var newChar = Default(); // create explorer: Recv [CP_CreateNewCharacter] 16 00 06 00 70 6F 6F 70 69 65 01 00 00 00 00 00 24 4E 00 00 [4E 75 00 00] [03 00 00 00] [03 00 00 00] [86 DE 0F 00] [2F 2D 10 00] [85 5B 10 00] [8B DE 13 00] [00] // create resistance: Recv [CP_CreateNewCharacter] 16 00 06 00 64 6F 6F 64 6F 6F 00 00 00 00 00 00 84 4E 00 00 [30 75 00 00] [07 00 00 00] [01 00 00 00] [47 06 10 00] [00 00 00 00] [74 5D 10 00] [8C DE 13 00] [00] newChar.Stats.sCharacterName = p.DecodeString(); var job = (short)p.Decode4(); newChar.Stats.nJob = GameConstants.GetRealJobFromCreation(job); bool subJob = p.Decode2() > 0; //whether dual blade = 1 or adventurer = 0 newChar.Stats.nSubJob = (short)(subJob ? 1 : 0); // doing it this way to reduce potential packet editing fuckery newChar.Stats.nFace = p.Decode4(); var hairColor = p.Decode4(); newChar.Stats.nHair = p.Decode4() + hairColor; newChar.Stats.nSkin = (byte)p.Decode4(); var top = p.Decode4(); var bottom = p.Decode4(); var shoes = p.Decode4(); var weapon = p.Decode4(); newChar.Stats.nGender = p.Decode1(); if (newChar.Stats.nSubJob == 1) { newChar.Stats.nJob = 400; // thief job } newChar.Stats.dwPosMap = GameConstants.GetStartingMap(newChar.Stats.nJob, newChar.Stats.nSubJob); newChar.Look.CopyStats(newChar.Stats); // TODO validate these against wz files newChar.Look.aEquip[5] = top; newChar.Look.aEquip[6] = bottom; newChar.Look.aEquip[7] = shoes; newChar.Look.aEquip[11] = weapon; newChar.Insert(c.Account.ID); // create empty entries in mapping tables InitDefaultMappings(newChar.Stats.dwCharacterID); if (newChar.Stats.dwCharacterID < 0) { c.SendPacket(CreateCharacterPacket(false, null)); } else { // add equips // todo figure out if overalls have their own slot ID MasterManager.CreateNormalStatEquip(top) .SaveToDB(newChar.Stats.dwCharacterID, (short)(bottom > 0 ? -5 : -5)); if (bottom > 0) // will be zero if its a champ that starts with an overall { MasterManager.CreateNormalStatEquip(bottom) .SaveToDB(newChar.Stats.dwCharacterID, -6); } MasterManager.CreateNormalStatEquip(shoes) .SaveToDB(newChar.Stats.dwCharacterID, -7); MasterManager.CreateNormalStatEquip(weapon) .SaveToDB(newChar.Stats.dwCharacterID, -11); var nWhitePot = 2000002; var nManaPot = 2000006; var nPotQuantity = (short)100; var item1 = MasterManager.CreateItem(nWhitePot) as GW_ItemSlotBundle; item1.nNumber = nPotQuantity; item1.SaveToDB(newChar.Stats.dwCharacterID, 1); var item2 = MasterManager.CreateItem(nManaPot) as GW_ItemSlotBundle; item2.nNumber = nPotQuantity; item2.SaveToDB(newChar.Stats.dwCharacterID, 2); c.SendPacket(CreateCharacterPacket(true, newChar)); } }
private void Handle_UserScriptMessageAnswer(WvsGameClient c, CInPacket p) { //CScriptSysFunc::OnScriptMessageAnswer var npc = c.NpcScript; if (npc == null) { Logger.Write(LogLevel.Warning, "UserScriptMessageAnswer with NO CONTEXT"); return; } //Previous send dialog type var type = (NpcDialogOptions)p.Decode1(); //if (type != npc->get_sent_dialog()) //{ // // Hacking // return; //} switch (type) { case NpcDialogOptions.quiz: case NpcDialogOptions.question: { var txt = p.DecodeString(); npc.proceed_text(txt); npc.check_end(); return; } } var choice = p.Decode1(); switch (type) { case NpcDialogOptions.normal: { switch (choice) { case 0: npc.proceed_back(); break; case 1: npc.proceed_next(); break; default: npc.end(); break; } break; } case NpcDialogOptions.yes_no: case NpcDialogOptions.accept_decline: case NpcDialogOptions.accept_decline_no_exit: { switch (choice) { case 0: npc.proceed_selection(0); break; case 1: npc.proceed_selection(1); break; default: npc.end(); break; } break; } case NpcDialogOptions.get_text: { if (choice != 0) { var txt = p.DecodeString(); npc.proceed_text(txt); } else { npc.end(); } break; } case NpcDialogOptions.get_number: { if (choice == 1) { var num = p.Decode4(); npc.proceed_number(num); } else { npc.end(); } break; } case NpcDialogOptions.simple: { if (choice == 0) { npc.end(); } else { var selection = p.Decode1(); npc.proceed_selection(selection); } break; } case NpcDialogOptions.style: { if (choice == 1) { var selection = p.Decode1(); npc.proceed_selection(selection); } else { npc.end(); } break; } default: { npc.end(); break; } } npc.check_end(); }
public void CreateMiniRoom(Character c, MR_Type nType, CInPacket p) { switch (nType) { case MR_Type.Omok: // todo break; case MR_Type.MemoryGame: // todo break; case MR_Type.TradingRoom: if (c.CurMiniRoom != null) { c.SendPacket(CPacket.SystemMessage("You are already in a trade.")); } else { Log.Debug($"Adding trade mini room to field minirooms."); Add(new CTradingRoom(c)); } break; // Recv [CP_MiniRoom] 90 00 00 05 07 00 70 65 65 66 61 63 65 00 01 00 76 C0 4C 00 case MR_Type.PersonalShop: c.SendMessage("no"); break; case MR_Type.EntrustedShop: { // TODO check closeness to other shops var sTitle = p.DecodeString(); p.Skip(3); // TODO what is this var nShopTemplateId = p.Decode4(); var(nItemSlot, pItem) = InventoryManipulator.GetAnyItem(c, InventoryType.Cash, nShopTemplateId); Log.Info($"Player [{c.Stats.sCharacterName}] attempting to create a shop with ItemID [{nShopTemplateId}] and Title [{sTitle}]"); if (pItem == null || nItemSlot == 0) { c.SendPacket(CPacket.SystemMessage("Invalid item or item slot.")); // packet editing? } else if (!c.Field.MapId.InRange(910000000, 910000023)) { c.SendPacket(CPacket.SystemMessage("Item does not work in this map.")); } else if (!ItemConstants.is_entrusted_shop_item(pItem.nItemID)) { c.SendPacket(CPacket.SystemMessage("Invalid shop item.")); // packet editing?? } else { var pMiniRoom = new CEntrustedShop(c, nShopTemplateId, sTitle); if (pMiniRoom.HasItems()) { c.SendMessage("Please retrieve items from fredrick before opening a shop."); } else { //Add(pMiniRoom); // packet is sent in here } } break; } case MR_Type.CashTradingRoom: // todo break; default: break; } }
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(); }
public void OnPacket(WvsGameClient c, CInPacket p) { var MSMP = p.Decode1(); switch ((MSMPType)MSMP) { case MSMPType.MSMP_Enter: var id = p.Decode4(); if (Contains(id)) { if (!this[id].TryJoin(c.Character)) { c.Character.SendMessage("The room is full."); } } else { Add(new CUIMessenger(c.Character)); } break; case MSMPType.MSMP_SelfEnterResult: break; case MSMPType.MSMP_Leave: GetByCharId(c.Character.dwId)?.Leave(c.Character.dwId); break; case MSMPType.MSMP_Invite: // same in/out GetByCharId(c.Character.dwId)?.TrySendInvite(c.Character, p.DecodeString()); break; case MSMPType.MSMP_InviteResult: break; case MSMPType.MSMP_Blocked: var sInviter = p.DecodeString(); if (sInviter.Length > Constants.MaxCharNameLength) { return; } var pInviter = MasterManager.CharacterPool.Get(sInviter); if (pInviter is null) { return; } GetByCharId(pInviter.dwId)?.Blocked(c.Character.dwId, c.Character.Stats.sCharacterName); break; case MSMPType.MSMP_Chat: GetByCharId(c.Character.dwId)?.DoChat(c.Character, p.DecodeString()); break; case MSMPType.MSMP_Avatar: break; case MSMPType.MSMP_Migrated: break; } }
private void Handle_CreateNewCharacter(WvsLoginClient c, CInPacket p) { var name = p.DecodeString(); var job = (short)p.Decode4(); var subJob = p.Decode2();//whether dual blade = 1 or adventurer = 0 var face = p.Decode4(); var hairColor = p.Decode4(); var hair = p.Decode4() + hairColor; var skinColor = (byte)p.Decode4(); var top = p.Decode4(); var bottom = p.Decode4(); var shoes = p.Decode4(); var weapon = p.Decode4(); var gender = p.Decode1(); var realJob = Constants.GetRealJobFromCreation(job); var charId = c.ParentServer.FetchNewCharId(); var newChar = new CharacterData(charId, c.AccId); newChar.Stats.dwCharacterID = charId; newChar.Stats.sCharacterName = name; newChar.Stats.nGender = gender; newChar.Stats.nSkin = skinColor; newChar.Stats.nFace = face; newChar.Stats.nHair = hair; newChar.Stats.nLevel = 10; newChar.Stats.nJob = realJob; newChar.Stats.nSTR = 10; newChar.Stats.nDEX = 10; newChar.Stats.nINT = 10; newChar.Stats.nLUK = 10; newChar.Stats.nHP = 50; newChar.Stats.nMHP = 50; newChar.Stats.nMP = 50; newChar.Stats.nMMP = 50; newChar.Stats.nAP = 1; newChar.Stats.nSP = 1; newChar.Stats.nEXP = 0; newChar.Stats.nPOP = 0; newChar.Stats.dwPosMap = 100000000; newChar.Stats.nPortal = 0; newChar.Stats.nPlaytime = 0; newChar.Stats.nSubJob = subJob; newChar.Look.nGender = gender; newChar.Look.nSkin = skinColor; newChar.Look.nFace = face; newChar.Look.nWeaponStickerID = 0; newChar.Look.anHairEquip[0] = hair; newChar.Look.anHairEquip[5] = top; newChar.Look.anHairEquip[6] = bottom; newChar.Look.anHairEquip[7] = shoes; newChar.Look.anHairEquip[11] = weapon; newChar.aInvEquippedNormal.Add(-5, new GW_ItemSlotEquip { nItemID = top }); newChar.aInvEquippedNormal.Add(-6, new GW_ItemSlotEquip { nItemID = bottom }); newChar.aInvEquippedNormal.Add(-7, new GW_ItemSlotEquip { nItemID = shoes }); newChar.aInvEquippedNormal.Add(-11, new GW_ItemSlotEquip { nItemID = weapon, niPAD = 20 }); newChar.aInvEquip.Add(1, new GW_ItemSlotEquip { nItemID = 1302016 }); newChar.aInvConsume.Add(1, new GW_ItemSlotBundle { nItemID = 2000007, nNumber = 100 }); c.ParentServer.AddNewChar(newChar); c.SendPacket(CPacket.CreateNewCharacter(name, true, newChar)); }
public static void Handle_CoupleMessage(WvsGameClient c, CInPacket p) { var sMarriedMsg = p.DecodeString(); // todo }
public void OnPacket(CInPacket p) { var opCode = (FriendOps)p.Decode1(); switch (opCode) { case FriendOps.FriendReq_SetFriend: { var sTarget = p.DecodeString(); var sFriendGroup = p.DecodeString(); if (sTarget.ToLower().Equals(Parent.Stats.sCharacterName.ToLower())) { // packet? return; // no imaginary friends } if (sTarget.Length > Constants.MaxCharNameLength || sFriendGroup.Length > 17) { // packet? return; // no hax } if (MasterManager.CharacterPool.Get(sTarget, false) is Character pTarget) // online user { if (TryGetValue(pTarget.dwId, out GW_Friend pFriend)) // already in friend list { if (pFriend.nFlag == 10) { Parent.SendPacket(GenericFriendResPacket(FriendOps.FriendRes_PleaseWait)); // "You've already made the Friend Request. Please try again later." } else if (pFriend.sFriendGroup.ToLower().Equals(sFriendGroup.ToLower())) { Parent.SendPacket(GenericFriendResPacket(FriendOps.FriendRes_SetFriend_AlreadySet)); } else { pFriend.sFriendGroup = sFriendGroup; return; } } else if (FriendListFull()) // FFF { Parent.SendPacket(GenericFriendResPacket(FriendOps.FriendRes_SetFriend_FullMe)); } else if (pTarget.Friends.FriendListFull()) { Parent.SendPacket(GenericFriendResPacket(FriendOps.FriendRes_SetFriend_FullOther)); } else { Add(new GW_Friend() // adding them to me { dwFriendID = pTarget.dwId, sFriendName = pTarget.Stats.sCharacterName, nFlag = 10, nChannelID = pTarget.ChannelID, sFriendGroup = sFriendGroup }); pTarget.Friends.Add(new GW_Friend() // adding myself to them { dwFriendID = Parent.dwId, sFriendName = Parent.Stats.sCharacterName, nFlag = 1, nChannelID = Parent.ChannelID, sFriendGroup = "Group Unknown" }); pTarget.SendPacket(GenericFriendResPacket(FriendOps.FriendRes_Invite)); //pTarget.Friends.SendLoad(); Parent.SendPacket(GenericFriendResPacket(FriendOps.FriendRes_SetFriend_Done)); } } else { Parent.SendPacket(GenericFriendResPacket(FriendOps.FriendRes_SetFriend_Unknown, "Unable to find user or user is not online.")); } } break; case FriendOps.FriendReq_AcceptFriend: { var dwCharId = p.Decode4(); if (GetOrDefault(dwCharId) is GW_Friend pFriend && pFriend.nFlag == 1) { pFriend.nFlag = 0; Parent.SendPacket(GenericFriendResPacket(FriendOps.FriendRes_LoadFriend_Done)); if (MasterManager.CharacterPool.Get(dwCharId) is Character pTarget) // character is online { pTarget.Friends.NotifyChangeFriendInfo(SocialNotiflag.LogIn); NotifyChangeFriendInfo(SocialNotiflag.LogIn); } else { UpdateFlagInDB(dwCharId, Parent.dwId, 0); } }