public static void HandleWorldSelect(MapleClient client, InPacket iPacket) { iPacket.Skip(1); client.World = iPacket.ReadByte(); client.Channel = iPacket.ReadByte(); byte characterCount = (byte)(long)Database.Scalar("SELECT COUNT(*) FROM `characters` WHERE `account_id` = @account_id", new MySqlParameter("@account_id", client.Account.ID)); using (OutPacket oPacket = new OutPacket(SendOps.SelectWorldResult)) { oPacket .WriteBool(false) .WriteByte(characterCount); if (characterCount > 0) { using (DatabaseQuery query = Database.Query("SELECT * FROM `characters` WHERE `account_id` = @account_id AND `world_id` = @world_id", new MySqlParameter("@account_id", client.Account.ID), new MySqlParameter("world_id", client.World))) { while (query.NextRow()) { LoginHandler.AddCharacterEntry(oPacket, query); } } } oPacket .WriteByte(2) .WriteInt(3); // TODO: Account specific character creation slots. For now, use default 3. client.Send(oPacket); } }
public static void ViewInventory(MartialClient c, InPacket p) { if (c.getAccount().activeCharacter == null) { Logger.LogCheat(Logger.HackTypes.NullActive, c, "Hooked viewInventory with null of activeCharacter"); c.Close(); return; } Character chr = c.getAccount().activeCharacter; OutPacket op = new OutPacket(28); op.WriteInt(28); op.WriteShort(0x04); op.WriteShort(0x1e); op.WriteInt(0x01); op.WriteInt(chr.getuID()); op.WriteShort(0x01); op.WriteByte(0xf8); op.WriteByte(0x01); p.Skip(4); op.WriteBytes(p.ReadBytes(4)); op.WriteByte(0x9e); op.WriteByte(0x0f); op.WriteByte(0xbf); c.WriteRawPacket(op.ToArray()); }
protected override void OnPacket(byte[] packet) { Console.WriteLine(BitConverter.ToString(packet)); using (InPacket p = new InPacket(packet)) { short opcode = 0; if (packet.Length >= 4) { opcode = (short)((int)((packet[0] & 0xFF) * 666) + (int)(packet[2] & 0xFF)); if (packet[3] != 0x00) { opcode = 1; } } if (m_processor == null) { return; } PacketHandler handler = null; handler = m_processor[opcode]; if (handler != null) { p.Skip(4); handler(this, p); } else { Logger.WriteLog(Logger.LogTypes.Warning, "[{0}] Unhandled packet from {1}: {2}.", m_processor.Label, Label, opcode); } } }
public static void UseItem(MartialClient c, InPacket p) { if (c.getAccount().activeCharacter == null) { Logger.LogCheat(Logger.HackTypes.NullActive, c, "Attempted to hook useItem while not being ingame."); c.Close(); return; } Character chr = c.getAccount().activeCharacter; p.Skip(1); byte usingIndex = p.ReadByte(); Item item = chr.getInventory().getItemBySeqIndexing(usingIndex); if (item == null) { Logger.LogCheat(Logger.HackTypes.Items, c, "Tried to use not existing item."); return; } ItemData itemData = ItemDataCache.Instance.getItemData(item.getItemID()); if (!itemData.getClassUsable()[chr.getcClass() - 1]) { Console.WriteLine("not for teh class.."); return; } if (itemData.getMinLvl() > chr.getLevel() || itemData.getMaxLvl() < chr.getLevel()) { Console.WriteLine("not for yar level.."); return; } if (itemData.getFaction() != 0 && chr.getFaction() != itemData.getFaction()) { Console.WriteLine("not for yah faction.."); return; } p.Skip(2); MainItemUsage.useItem(chr, item, usingIndex, p); }
public static void Movement(MartialClient c, InPacket p) { if (c.getAccount().activeCharacter == null) { Logger.LogCheat(Logger.HackTypes.NullActive, c, "Hooked Movement with null of activeCharacter"); c.Close(); return; } Character chr = c.getAccount().activeCharacter; p.Skip(4); byte[] locationToX = p.ReadBytes(4); byte[] locationToY = p.ReadBytes(4); p.Skip(1); byte movingMode = p.ReadByte(); MoveCharacterPacket.HandleMovement(chr, locationToX, locationToY, movingMode); }
public static void ShortcutBar(MartialClient c, InPacket p) { if (c.getAccount().activeCharacter == null) { Logger.LogCheat(Logger.HackTypes.NullActive, c, "Attempted to hook bar skill while not being ingame."); c.Close(); return; } Character chr = c.getAccount().activeCharacter; byte barIndex = p.ReadByte(); byte actionID = p.ReadByte(); p.Skip(2); int thingID = p.ReadInt(); OutPacket op = new OutPacket(24); op.WriteInt(24); op.WriteShort(4); op.WriteShort(17); op.WriteInt(135595521); op.WriteInt(chr.getuID()); op.WriteShort(1); op.WriteByte(barIndex); op.WriteByte(actionID); op.WriteInt(thingID); if (actionID >= 1 && actionID <= 4) { chr.getSkillBar().addToSkillBar(barIndex, thingID); } else if (actionID == 6) { chr.getSkillBar().addToSkillBar(barIndex, thingID + 256); } else if (actionID == 0) { chr.getSkillBar().removeFromSkillBar(barIndex); } else if (actionID == 5) { chr.getSkillBar().addToSkillBar(barIndex, thingID + 512); } c.WriteRawPacket(op.ToArray()); }
public static void OnSelectWorld(MapleClient c, InPacket p) { p.Skip(1); // world id c.Channel = p.ReadByte(); using (OutPacket packet = new OutPacket(SendOps.SelectWorldResult)) { packet.WriteByte(); //some error packet.WriteByte((byte)c.Characters.Count); foreach (var character in c.Characters) { PacketCreator.Helper.AddCharacterData(packet, character); PacketCreator.Helper.AddCharaterLook(packet, character); packet.WriteBool(false); //rank } packet.WriteZero(64); //padding c.Send(packet); } }
public static void HandleItemMove(MapleClient client, InPacket iPacket) { iPacket.Skip(4); // NOTE: tRequestTime (ticks). InventoryType inventory = (InventoryType)iPacket.ReadByte(); short slot1 = iPacket.ReadShort(); short slot2 = iPacket.ReadShort(); short quantity = iPacket.ReadShort(); bool dropped = slot2 == 0; bool equippedSlot1 = slot1 < 0; bool equippedSlot2 = slot2 < 0; if (dropped) { } else { client.Character.Items.Swap(inventory, slot1, slot2); } if (equippedSlot1 || equippedSlot2) { } }
public static void OnDeleteCharacter(MapleClient c, InPacket p) { p.Skip(4); int charId = p.ReadInt(); Character target = c.Characters.FindOne((chr) => chr.CharId == charId); if (target != default(Character)) { Database.Instance.DeleteCharacter(target); c.Characters.Remove(target); using (OutPacket packet = new OutPacket(SendOps.DeleteCharacterResult)) { packet.WriteInt(charId); packet.WriteByte(); c.Send(packet); } } else { c.Close(); } }
// Holy Grail ftw public static void useItem(Character chr, Item item, byte usingIndex, InPacket p) { MartialClient c = chr.getAccount().mClient; ItemData itemData = ItemDataCache.Instance.getItemData(item.getItemID()); Boolean shouldDecrease = false; string determined = null; int determiner = 0; if (itemData.getIsStackable()) { shouldDecrease = true; } else { if (itemData.getTimeToExpire() == 0) { shouldDecrease = true; } } // well.. we don't care if it's handled by server.. let's just remove them & f**k haterz! qq if (shouldDecrease) { if (!chr.getInventory().decrementItem(usingIndex)) { Console.WriteLine("something went wrong with decrement.."); return; } } switch (itemData.getCategory()) { case 1001: // healingz { if (itemData.getHealHP() > 0 || itemData.getHealMana() > 0 || itemData.getHealStamina() > 0) { StaticPackets.releaseHealPacket(chr, (int)(chr.getCurHP() + itemData.getHealHP()), (short)(chr.getCurMP() + itemData.getHealMana()), (short)(chr.getCurSP() + itemData.getHealStamina())); } break; } case 1002: // skillz o.o { StaticPackets.sendSystemMessageToClient(chr.getAccount().mClient, 1, "If you'd like to learn any skill, go to skills list and press CTRL+LMB."); break; } case 1003: // teleport { if (chr.getMap() == itemData.getTeleportMap() || chr.getMap() != itemData.getTeleportMap() && itemData.getSpecialEffect() != 0) { CharacterFunctions.setPlayerPosition(chr, itemData.getTeleportX(), itemData.getTeleportY(), (short)itemData.getTeleportMap()); } break; } case 1007: // reset skills { chr.getSkills().resetAll(); chr.getSkillBar().getSkillBar().Clear(); break; } case 1011: // effect potions { chr.setEffect((byte)itemData.getSpecialEffect()); break; } case 1012: // tae potion { break; } case 1013: // faction change { if (chr.getFaction() == 0) { return; } chr.setFaction(chr.getFaction() == 1 ? (byte)2 : (byte)1); break; } case 1015: // chuk amulet { determiner = BitConverter.ToInt32(p.ReadBytes(4), 0); if (determiner == 0) { return; } ItemData determinedItem = ItemDataCache.Instance.getItemData(determiner); if (determinedItem == null || determinedItem.getCategory() != 1003 || (determiner < 212100146 && determiner > 212100164 && determiner != 212100185 && determiner != 212100187)) { Console.WriteLine("I CAN'T TURN 10 INTO 20 CHICKENZ"); return; } CharacterFunctions.setPlayerPosition(chr, determinedItem.getTeleportX(), determinedItem.getTeleportY(), (short)determinedItem.getTeleportMap()); break; } case 1016: // karma amulet { chr.setKarmaMessagingTimes((short)(chr.getKarmaMessagingTimes() + 1)); break; } case 1020: // name changer { p.Skip(4); string charName = MiscFunctions.obscureString(p.ReadString(16)); if (charName.Length < 3 || Regex.Replace(charName, "[^A-Za-z0-9]+", "") != charName || MySQLTool.NameTaken(charName)) { StaticPackets.sendSystemMessageToClient(chr.getAccount().mClient, 1, "Wrong input " + charName + "."); return; } chr.setName(charName); determined = charName; CharacterFunctions.refreshCharacterForTheWorld(chr); break; } case 1021: // face changer { chr.setFace((byte)itemData.getSpecialEffect()); break; } case 1024: { // yy..? break; } case 1031: // red castle { determiner = BitConverter.ToInt32(p.ReadBytes(4), 0); if (determiner == 0) { return; } ItemData determinedItem = ItemDataCache.Instance.getItemData(determiner); if (determinedItem == null || determinedItem.getCategory() != 56 || ((determiner < 273001255 && determiner > 273001257) && determiner != 283000472 && determiner != 283000543 && determiner != 283000575 && determiner != 283000614 && determiner != 283000934 && determiner != 283001078 && determiner != 283001373 && determiner != 283001376)) { Console.WriteLine("I CAN'T TURN 10 INTO 20 CHICKENZ"); return; } CharacterFunctions.setPlayerPosition(chr, determinedItem.getTeleportX(), determinedItem.getTeleportY(), (short)determinedItem.getTeleportMap()); break; } default: { StaticPackets.sendSystemMessageToClient(chr.getAccount().mClient, 1, "Feature not implemented yet"); return; } } OutPacket op = new OutPacket(52); op.WriteInt(52); op.WriteShort(0x04); op.WriteShort(0x05); op.WriteInt(140328705); op.WriteInt(chr.getuID()); op.WriteShort(0x01); op.WriteByte(0x01); op.WriteByte(usingIndex); op.WriteInt(item.getQuantity()); op.WriteInt(793149441); op.WriteInt(/*determiner > 0 ? determiner : 0*/); op.WritePaddedString(determined, 17); op.WriteByte(0x90); op.WriteByte(0xd2); op.WriteByte(0x2a); c.WriteRawPacket(op.ToArray()); OutPacket ops = new OutPacket(40); ops.WriteInt(40); ops.WriteShort(0x05); ops.WriteShort(0x05); ops.WriteInt(779458561); ops.WriteInt(chr.getuID()); ops.WriteInt(item.getItemID()); ops.WritePaddedString(determined, 17); ops.WriteByte(0x9e); ops.WriteByte(0x0f); ops.WriteByte(0xbf); WMap.Instance.getGrid(chr.getMap()).sendTo3x3Area(chr, chr.getArea(), ops.ToArray()); }
public void OnEquipItem(ClientSession cs, InPacket ip) { int LoginIDLen = ip.ReadInt(); string LoginID = ip.ReadUnicodeString(LoginIDLen); ip.ReadInt(); // 00 00 00 00 byte CharNum = ip.ReadByte(); for (byte i = 0; i < CharNum; i++) { byte TargetChar = ip.ReadByte(); int EquipCount = ip.ReadInt(); int MyCharPos = -1; for (int t = 0; t < cs.MyCharacter.MyChar.Length; t++) { if (cs.MyCharacter.MyChar[t].CharType == TargetChar) { MyCharPos = t; } } // 내가 가진 캐릭터 목록에 없다 if (MyCharPos == -1) { continue; } //Array.Resize(ref cs.MyCharacter.MyChar[MyCharPos].Equip, EquipCount); int len = cs.MyCharacter.MyChar[MyCharPos].Equip.Length; for (int j = 0; j < EquipCount; j++) { int kind = 0; int ItemID = ip.ReadInt(); ip.ReadInt(); // 00 00 00 01 int ItemUID = ip.ReadInt(); ip.ReadInt(); // 00 00 00 00 ip.ReadInt(); // 00 00 00 00 ip.ReadInt(); // 00 00 00 00 ip.ReadInt(); // 00 00 00 00 ip.ReadByte(); // 00 00 00 ip.ReadByte(); // ip.ReadByte(); // /* * helm 0 * upper 1 * lower 2 * Weapon 3 * gloves 8 * shoes 9 * Circlet 10 * Wings 12 * Mask 11 * cloak 13 * Stompers 14 * Shields 15 */ DataSet ds3 = new DataSet(); Database.Query(ref ds3, "SELECT `Kind` FROM `gc`.`goodsinfolist` WHERE `GoodsID` = '{0}'", ItemID); if (ds3.Tables[0].Rows.Count == 0) { LogFactory.GetLog("EQUIPS").LogWarning("ITEM NAO EXISTE!"); kind = 0; } else { kind = Convert.ToInt32(ds3.Tables[0].Rows[0]["Kind"].ToString()); } int type = 0; if (kind == 0) { type = 0; } if (kind == 1) { type = 1; } if (kind == 2) { type = 2; } if (kind == 3) { type = 3; } if (kind == 8) { type = 4; } if (kind == 9) { type = 5; } if (kind == 13) { type = 6; } //cs.MyCharacter.MyChar[MyCharPos].Equip[j].ItemID = ItemID; DataSet ds2 = new DataSet(); Database.Query(ref ds2, "SELECT itemID FROM gc.equipment WHERE LoginUID = '{0}' AND CharType = '{1}' AND ItemUID = '{2}'", cs.LoginUID, MyChar[MyCharPos].CharType, ItemUID); if (ds2.Tables[0].Rows.Count == 0) { DataSet ds = new DataSet(); Database.Query(ref ds, "INSERT INTO gc.equipment ( LoginUID, CharType, ItemType, ItemID,ItemUID) VALUES ( '{0}', '{1}', '{2}', '{3}' ,'{4}')", cs.LoginUID, MyChar[MyCharPos].CharType, type, ItemID, ItemUID); } else { DataSet ds = new DataSet(); Database.Query(ref ds, "UPDATE `gc`.`equipment` SET `ItemID` = '{0}' WHERE `LoginUID` = '{1}' AND `CharType` = '{2}' AND `ItemType` = '{3}'", ItemID, cs.LoginUID, MyChar[MyCharPos].CharType, type); } if (EquipCount > len) { for (int k = 0; k < EquipCount; k++) { len++; } } LogFactory.GetLog("EQUIPAMENTOS").LogInfo("ATUAL TYPE: " + type); if (type > len) { for (int h = 0; h < type; h++) { type--; LogFactory.GetLog("EQUIPAMENTOS").LogInfo("ATUAL TYPE: " + type); } } Array.Resize(ref cs.MyCharacter.MyChar[MyCharPos].Equip, len); cs.MyCharacter.MyChar[MyCharPos].TotalEquips++; LogFactory.GetLog("EQUIPS").LogInfo("TOTAL: " + cs.MyCharacter.MyChar[MyCharPos].TotalEquips); cs.MyCharacter.MyChar[MyCharPos].Equip[type].ItemID = ItemID; cs.MyCharacter.MyChar[MyCharPos].Equip[type].ItemUID = ItemUID; //Array.Resize(ref cs.MyCharacter.MyChar[MyCharPos].Equip, EquipCount++); /*cs.MyCharacter.MyChar[MyCharPos].Equip[type].ItemID = ItemID; * cs.MyCharacter.MyChar[MyCharPos].Equip[type].ItemUID = ItemUID;*/ } // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ip.Skip(99); } // 패킷 구조 똑같이 보내면 된다. using (OutPacket oPacket = new OutPacket(GameOpcodes.EVENT_EQUIP_ITEM_BROAD)) { oPacket.WriteInt(cs.Login.Length * 2); oPacket.WriteUnicodeString(cs.Login); oPacket.WriteInt(0); oPacket.WriteByte((byte)cs.MyCharacter.MyChar.Length); for (int i = 0; i < cs.MyCharacter.MyChar.Length; i++) { oPacket.WriteByte((byte)cs.MyCharacter.MyChar[i].CharType); oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip.Length); for (int j = 0; j < cs.MyCharacter.MyChar[i].Equip.Length; j++) { oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip[j].ItemID); oPacket.WriteInt(1); oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip[j].ItemUID); oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteByte(); // 00 00 00 oPacket.WriteByte(); // oPacket.WriteByte(); // } // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 oPacket.Skip(99); } oPacket.WriteInt(0); // 그냥 oPacket.CompressAndAssemble(cs.CRYPT_KEY, cs.CRYPT_HMAC, cs.CRYPT_PREFIX, ++cs.CRYPT_COUNT); cs.Send(oPacket); } if (cs.CurrentRoom == null) { return; } using (OutPacket oPacket = new OutPacket(GameOpcodes.EVENT_EQUIP_ITEM_BROAD)) { oPacket.WriteInt(cs.Login.Length); oPacket.WriteUnicodeString(cs.Login); oPacket.WriteByte(2); // ??? oPacket.WriteInt(cs.MyCharacter.MyChar.Length); for (int i = 0; i < cs.MyCharacter.MyChar.Length; i++) { oPacket.WriteByte((byte)cs.MyCharacter.MyChar[i].CharType); oPacket.WriteInt(0); // 00 00 00 00 oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip.Length); for (int j = 0; j < cs.MyCharacter.MyChar[i].Equip.Length; j++) { oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip[j].ItemID); oPacket.WriteInt(1); oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip[j].ItemUID); oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteByte(); // 00 00 00 oPacket.WriteByte(); // oPacket.WriteByte(); // } oPacket.Skip(61); oPacket.WriteHexString("FF FF"); oPacket.Skip(32); oPacket.WriteInt(cs.LoginUID); } for (int i = 0; i < 6; i++) { if (cs.CurrentRoom.Slot[i].Active == true) { oPacket.CompressAndAssemble(cs.CurrentRoom.Slot[i].cs.CRYPT_KEY, cs.CurrentRoom.Slot[i].cs.CRYPT_HMAC, cs.CurrentRoom.Slot[i].cs.CRYPT_PREFIX, cs.CurrentRoom.Slot[i].cs.CRYPT_COUNT); cs.CurrentRoom.Slot[i].cs.Send(oPacket); oPacket.CancelAssemble(); } } } }
public void OnEquipItem(ClientSession cs, InPacket ip) { int LoginIDLen = ip.ReadInt(); string LoginID = ip.ReadUnicodeString(LoginIDLen); ip.ReadInt(); // 00 00 00 00 byte CharNum = ip.ReadByte(); for (byte i = 0; i < CharNum; i++) { byte TargetChar = ip.ReadByte(); int EquipCount = ip.ReadInt(); int MyCharPos = -1; for (int t = 0; t < cs.MyCharacter.MyChar.Length; t++) { if (cs.MyCharacter.MyChar[t].CharType == TargetChar) { MyCharPos = t; } } // 내가 가진 캐릭터 목록에 없다 if (MyCharPos == -1) { continue; } Array.Resize(ref cs.MyCharacter.MyChar[MyCharPos].Equip, EquipCount); for (int j = 0; j < EquipCount; j++) { int ItemID = ip.ReadInt(); ip.ReadInt(); // 00 00 00 01 int ItemUID = ip.ReadInt(); ip.ReadInt(); // 00 00 00 00 ip.ReadInt(); // 00 00 00 00 ip.ReadInt(); // 00 00 00 00 ip.ReadInt(); // 00 00 00 00 ip.ReadByte(); // 00 00 00 ip.ReadByte(); // ip.ReadByte(); // cs.MyCharacter.MyChar[MyCharPos].Equip[j].ItemID = ItemID; cs.MyCharacter.MyChar[MyCharPos].Equip[j].ItemUID = ItemUID; } // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ip.Skip(99); } // 패킷 구조 똑같이 보내면 된다. using (OutPacket oPacket = new OutPacket(GameOpcodes.EVENT_EQUIP_ITEM_BROAD)) { oPacket.WriteInt(cs.Login.Length * 2); oPacket.WriteUnicodeString(cs.Login); oPacket.WriteInt(0); oPacket.WriteByte((byte)cs.MyCharacter.MyChar.Length); for (int i = 0; i < cs.MyCharacter.MyChar.Length; i++) { oPacket.WriteByte((byte)cs.MyCharacter.MyChar[i].CharType); oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip.Length); for (int j = 0; j < cs.MyCharacter.MyChar[i].Equip.Length; j++) { oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip[j].ItemID); oPacket.WriteInt(1); oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip[j].ItemUID); oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteByte(); // 00 00 00 oPacket.WriteByte(); // oPacket.WriteByte(); // } // 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 oPacket.Skip(99); } oPacket.WriteInt(0); // 그냥 oPacket.CompressAndAssemble(cs.CRYPT_KEY, cs.CRYPT_HMAC, cs.CRYPT_PREFIX, ++cs.CRYPT_COUNT); cs.Send(oPacket); } // 내가 지금 방에 입장하고 있으면 방 인원한테 장비가 바뀌었다고 알려준다. if (cs.CurrentRoom == null) { return; } using (OutPacket oPacket = new OutPacket(GameOpcodes.EVENT_EQUIP_ITEM_BROAD)) { oPacket.WriteInt(cs.Login.Length); oPacket.WriteUnicodeString(cs.Login); oPacket.WriteByte(2); // ??? oPacket.WriteInt(cs.MyCharacter.MyChar.Length); for (int i = 0; i < cs.MyCharacter.MyChar.Length; i++) { oPacket.WriteByte((byte)cs.MyCharacter.MyChar[i].CharType); oPacket.WriteInt(0); // 00 00 00 00 oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip.Length); for (int j = 0; j < cs.MyCharacter.MyChar[i].Equip.Length; j++) { oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip[j].ItemID); oPacket.WriteInt(1); oPacket.WriteInt(cs.MyCharacter.MyChar[i].Equip[j].ItemUID); oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteInt(); // 00 00 00 00 oPacket.WriteByte(); // 00 00 00 oPacket.WriteByte(); // oPacket.WriteByte(); // } oPacket.Skip(61); oPacket.WriteHexString("FF FF"); oPacket.Skip(32); oPacket.WriteInt(cs.LoginUID); } // 방에 있는 모든 유저에게 전송해야함. for (int i = 0; i < 6; i++) { if (cs.CurrentRoom.Slot[i].Active == true) { oPacket.CompressAndAssemble(cs.CurrentRoom.Slot[i].cs.CRYPT_KEY, cs.CurrentRoom.Slot[i].cs.CRYPT_HMAC, cs.CurrentRoom.Slot[i].cs.CRYPT_PREFIX, cs.CurrentRoom.Slot[i].cs.CRYPT_COUNT); cs.CurrentRoom.Slot[i].cs.Send(oPacket); // 패킷 보내고 oPacket.CancelAssemble(); // 다시 패킷 복구 } } } }
public Movements(InPacket iPacket) : base() { this.Position = iPacket.ReadPoint(); this.Velocity = iPacket.ReadPoint(); iPacket.Skip(1); // NOTE: Unknown. byte count = iPacket.ReadByte(); while (count-- > 0) { Movement movement = new Movement(); movement.Type = (MovementType)iPacket.ReadByte(); switch (movement.Type) { case MovementType.Normal: case MovementType.Unknown5: case MovementType.Unknown15: case MovementType.Unknown17: { movement.Position = iPacket.ReadPoint(); movement.Velocity = iPacket.ReadPoint(); movement.Foothold = iPacket.ReadShort(); this.LastFoothold = movement.Foothold; if (movement.Type != MovementType.Unknown15) { movement.Stance = iPacket.ReadByte(); movement.Duration = iPacket.ReadShort(); } } break; case MovementType.Unknown1: case MovementType.Unknown2: case MovementType.Unknown6: case MovementType.Unknown12: case MovementType.Unknown13: case MovementType.Unknown16: case MovementType.Unknown18: case MovementType.Unknown19: case MovementType.Unknown20: case MovementType.Unknown22: { movement.Velocity = iPacket.ReadPoint(); movement.Stance = iPacket.ReadByte(); movement.Duration = iPacket.ReadShort(); } break; case MovementType.Unknown3: case MovementType.Unknown4: case MovementType.Unknown7: case MovementType.Unknown8: case MovementType.Unknown9: case MovementType.Unknown11: { movement.Position = iPacket.ReadPoint(); movement.Foothold = iPacket.ReadShort(); this.LastFoothold = movement.Foothold; movement.Stance = iPacket.ReadByte(); movement.Duration = iPacket.ReadShort(); } break; case MovementType.Unknown14: { // TODO: Jump down or equipment, not sure. } break; case MovementType.Unknown10: { movement.Statistic = iPacket.ReadByte(); } break; } this.Add(movement); } }
public void OnLogin(ClientSession cs, InPacket ip) { int IDLength = ip.ReadInt(); string ID = ip.ReadString(IDLength); int PWLength = ip.ReadInt(); string PW = ip.ReadString(PWLength); ip.Skip(21); int crc32len = ip.ReadInt(); string crc32 = ip.ReadString(crc32len); LogFactory.GetLog("CRC").LogInfo("LENGTH: " + crc32len + " CRC: " + crc32); DataSet ds = new DataSet(); Database.Query(ref ds, "SELECT * FROM account WHERE Login = '******' AND Passwd = '{1}'", ID, PW); if (ds.Tables[0].Rows.Count == 0) { // 로그인 실패 LogFactory.GetLog("MAIN").LogInfo("{0}의 로그인이 실패하였습니다.", ID); using (OutPacket oPacket = new OutPacket(CenterOpcodes.ENU_VERIFY_ACCOUNT_ACK)) { oPacket.WriteHexString("00 00 00 14"); oPacket.WriteInt(IDLength * 2); oPacket.WriteUnicodeString(ID); oPacket.WriteHexString("00 00 00 00 00"); oPacket.CompressAndAssemble(cs.CRYPT_KEY, cs.CRYPT_HMAC, cs.CRYPT_PREFIX, ++cs.CRYPT_COUNT); cs.Send(oPacket); } } else { SendServerList(cs); SendChannelNews(cs); //SendShop(cs); SendClientContentOpen(cs); SendSocketTableInfo(cs); SendCashbackRatio(cs); using (OutPacket oPacket = new OutPacket(CenterOpcodes.ENU_VERIFY_ACCOUNT_ACK)) { oPacket.WriteHexString("00 00 00 00"); oPacket.WriteInt(IDLength * 2); oPacket.WriteUnicodeString(ID); oPacket.WriteInt(PWLength); oPacket.WriteString(PW); oPacket.WriteHexString("00 00 00 00 14 00 8E A7 C5 01 00 00 00 00 00 00 02 4B 52 00 05 A3 BD 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 00"); oPacket.WriteInt(cs.MyLoading.GuildMarkURL.Length * 2); oPacket.WriteUnicodeString(cs.MyLoading.GuildMarkURL); oPacket.WriteHexString("00 00 00 00 00 00 00 00"); //checklist int SHAi = cs.MyLoading.checklist.Length; oPacket.WriteInt(SHAi); for (int i = 0; i <= cs.MyLoading.checklist.Length - 1; i++) { oPacket.WriteInt(cs.MyLoading.checklist[i].nFile.Length * 2); oPacket.WriteUnicodeString(cs.MyLoading.checklist[i].nFile); oPacket.WriteBool(true); } oPacket.WriteHexString("00 00 00 01 00 00 00 03 00 00 00 00 00 00 00 00 64 01 00 00 00 00 00 00 00 64 02 00 00 00 00 00 00 00 64 01 BF 80 00 00 FC 04 97 FF 00 00 00 00 00 00 00 00 00 00 00 00"); oPacket.CompressAndAssemble(cs.CRYPT_KEY, cs.CRYPT_HMAC, cs.CRYPT_PREFIX, ++cs.CRYPT_COUNT); cs.Send(oPacket); } } }
public static void CastSkill(MartialClient c, InPacket p) { if (c.getAccount().activeCharacter == null) { Logger.LogCheat(Logger.HackTypes.NullActive, c, "Attempted to hook cast skill while not being ingame."); c.Close(); return; } Character chr = c.getAccount().activeCharacter; byte skillBarNumber = p.ReadByte(); byte skillActivationType = p.ReadByte(); p.Skip(14); byte chartargets = p.ReadByte(); p.Skip(1); byte mobtargets = p.ReadByte(); if ((chartargets + mobtargets) > 8) { return; } p.Skip(1); int[] targetIds = new int[chartargets + mobtargets]; for (int i = 0; i < targetIds.Length; i++) { targetIds[i] = p.ReadInt(); } System.Console.WriteLine("{0} | {1} | {2} | {3} | {4}", skillBarNumber, skillActivationType, chartargets, mobtargets, string.Join(",", targetIds)); //skillpckt1 is a packet of skilleffects e.g. buffs byte[] skillpckt1 = SkillPackets.getSkillEffectOnCharPacket(chr); //skillpckt2 is a packet of skill activation, different IDs and DMG byte[] skillpckt2 = new byte[52]; //just for medi and turbo byte[] skillpckt3 = new byte[28]; //SkillID byte[] skillid; int skillIDInt = SkillDataCache.Instance.getSkillIDFromCast(chr, (byte)(skillBarNumber)); int skillidNoFake = skillIDInt; skillid = BitTools.intToByteArray(skillIDInt); //SkillMaster.canCastSkill(cur, skillidInt); SkillData skill = SkillDataCache.Instance.getSkill(skillIDInt); if (skill == null) { System.Console.WriteLine("Skill was null"); return; } if (skill.getTargets() < chartargets + mobtargets) { System.Console.WriteLine("tried to hit moar than poss"); return; } //TURBO AND MEDI if (skill.getTypeSpecific() == 6 || skill.getTypeSpecific() == 7) { if (skill.getTypeSpecific() == 6) { skillpckt3 = SkillPackets.getMediPacket(chr, skillIDInt, skillActivationType); } else { skillpckt3 = SkillPackets.getTurboPacket(chr, skillIDInt, skillActivationType == (byte)0xc8); //if(skillActivationType == (byte)0xc8) chr.setTurboSpeed(((CastableSkill)skill).getSpeed()); //else chr.setTurboSpeed(0); } c.WriteRawPacket(skillpckt3); WMap.Instance.getGrid(chr.getMap()).sendTo3x3Area(chr, chr.getArea(), skillpckt3); return; } //TARGETS int targets = chartargets + mobtargets; //COSTS chr.setCurHP(chr.getCurHP() - skill.getHealCost()); chr.setCurMP((short)(chr.getCurMP() - skill.getManaCost())); chr.setCurSP((short)(chr.getCurSP() - skill.getStaminaCost())); Fightable target; //GET MAXIMUM CASTERS DMG int dmgInt = SkillDataCache.Instance.skillCastDmgCalculations(chr, skillIDInt); int totalDmg; int dmgType; //GET MAIN SKILL PACKET skillpckt2 = SkillPackets.getCastSkillPacket(chr, targets, skillidNoFake, skillActivationType); //ADD TARGET STUFF TO THE PACKET for (int aoe = 0; aoe < targets; aoe++) { //GET TARGET byte[] targetByteB = BitTools.intToByteArray(targetIds[aoe]); target = WMap.Instance.getGrid(chr.getMap()).getFightableNear(chr.getArea(), BitTools.byteArrayToInt(targetByteB)); if (target == null) { continue; } //check for distance //canCastToTarget((Location)chr, (Location)target); totalDmg = dmgInt; //DECREASE DMG BY DEF dmgType = SkillDataCache.Instance.skillCastDmgTypeCalculations(chr, target, skill.getTypeSpecific() == 2); totalDmg -= target.getDef(); //CRIT if (dmgType == 2 || dmgType == 5) { totalDmg += chr.getCritDmg(); } //DMG TYPE FACTOR totalDmg *= (int)(SkillDataCache.Instance.getDmgFactorByType(dmgType) * SkillDataCache.Instance.getDmgFactorByClass(chr)); if (totalDmg < 0) { totalDmg = 0; } //ATK THE TARGET FINALLY target.recDamage(chr.getuID(), totalDmg); int targetId = BitTools.byteArrayToInt(targetByteB); //COMPLETE THE TARGET IN THE PACKAGE skillpckt2 = SkillPackets.completeCastSkillPacket(skillpckt2, aoe, targetId, target.getCurHP(), target.getCurMP(), -totalDmg, chartargets, dmgType); if (chartargets > 0) { chartargets--; } } //send skill packet to other players WMap.Instance.getGrid(chr.getMap()).sendTo3x3Area(chr, chr.getArea(), skillpckt2); //send skill packet to client c.WriteRawPacket(skillpckt2); //effects on char c.WriteRawPacket(skillpckt1); return; }
public static AttackInfo ParseDamage(MapleCharacter c, InPacket p, bool ranged) { var ret = new AttackInfo(); p.ReadByte(); p.Skip(8); ret.NumAttackedAndDamage = p.ReadByte(); p.Skip(8); ret.NumAttacked = RightMove(ret.NumAttackedAndDamage, 4) & 0xF; ret.NumDamage = ret.NumAttackedAndDamage & 0xF; ret.AllDamage = new List <Tuple <int, List <int> > >(); ret.Skill = p.ReadInt(); p.Skip(8); if ((ret.Skill == 2121001) || (ret.Skill == 2221001) || (ret.Skill == 2321001) || (ret.Skill == 5201002) || (ret.Skill == 14111006) || (ret.Skill == 5101004) || (ret.Skill == 15101003)) { ret.Charge = p.ReadInt(); } else { ret.Charge = 0; } if (ret.Skill == 1221011) { ret.IsHh = true; } p.ReadInt(); ret.AresCombo = p.ReadByte(); //记录目前的Combo点数 var sourceid = ret.Skill; //以下�?能为Combo专用�?�? if ((sourceid == 21100004) || (sourceid == 21100005) || (sourceid == 21110003) || (sourceid == 21110004) || (sourceid == 21120006) || (sourceid == 21120007)) { //c.setCombo(1); } ret.Pos = p.ReadByte(); //动作 ret.Stance = p.ReadByte(); //姿势 if (ret.Skill == 4211006) { //return parseMesoExplosion(lea, ret); } if (ranged) { p.ReadByte(); ret.Speed = p.ReadByte(); p.ReadByte(); ret.Direction = p.ReadByte(); p.Skip(7); if ((ret.Skill == 3121004) || (ret.Skill == 3221001) || (ret.Skill == 5221004) || (ret.Skill == 13111002)) { p.Skip(4); } } else { p.ReadByte(); ret.Speed = p.ReadByte(); p.Skip(4); } for (var i = 0; i < ret.NumAttacked; ++i) { var oid = p.ReadInt(); p.Skip(14); var allDamageNumbers = new List <int>(); for (var j = 0; j < ret.NumDamage; ++j) { var damage = p.ReadInt(); MapleStatEffect effect = null; if (ret.Skill != 0) { effect = SkillFactory.GetSkill(ret.Skill) .GetEffect(c.GetSkillLevel(SkillFactory.GetSkill(ret.Skill))); } if ((damage != 0) && (effect != null) && (effect.GetFixedDamage() != 0)) { damage = effect.GetFixedDamage(); } allDamageNumbers.Add(damage); } if (ret.Skill != 5221004) { p.Skip(4); } ret.AllDamage.Add(Tuple.Create(oid, allDamageNumbers)); } return(ret); }