public static void Read(byte[] packet, Client cli) { PacketReader pr = new PacketReader(packet); Header header = pr.PopHeader(); pr.PopByte(); pr.PopShort(); Identity id = pr.PopIdentity(); NonPlayerCharacterClass npc = (NonPlayerCharacterClass)FindDynel.FindDynelById(id.Type, id.Instance); if (npc != null) { npc.KnuBotStartTrade(cli.Character); } }
/// <summary> /// /// </summary> /// <param name="packet"></param> /// <param name="client"></param> public static void Read(byte[] packet, Client client) { #region Bytes / Strings / Ints setup PacketReader packetReader = new PacketReader(packet); packetReader.PopHeader(); packetReader.PopByte(); packetReader.PopInt(); Identity target = packetReader.PopIdentity(); int commandLength = packetReader.PopInt(); string fullArgs = packetReader.PopString(commandLength).TrimEnd(char.MinValue); string temp = string.Empty; do { temp = fullArgs; fullArgs = fullArgs.Replace(" ", " "); } while (temp != fullArgs); string[] cmdArgs = fullArgs.Trim().Split(' '); packetReader.Finish(); #endregion Program.csc.CallChatCommand(cmdArgs[0].ToLower(), client, target, cmdArgs); }
public static void Read(byte[] packet, Client client) { PacketReader packetReader = new PacketReader(packet); Header header = packetReader.PopHeader(); packetReader.PopByte(); packetReader.PopShort(); Identity identity = packetReader.PopIdentity(); NonPlayerCharacterClass npc = (NonPlayerCharacterClass)FindDynel.FindDynelById(identity.Type, identity.Instance); Character character = FindClient.FindClientById(header.Sender).Character; packetReader.PopInt(); packetReader.PopInt(); packetReader.PopInt(); int container = packetReader.PopInt(); int place = packetReader.PopInt(); InventoryEntries ie = character.GetInventoryAt(place); AOItem aoi = ie.Item.ShallowCopy(); character.Inventory.Remove(ie); // Silent remove, no message given to client. Client handles this on its own npc.KnuBotTrade(character, aoi); }
/// <summary> /// /// </summary> /// <param name="packet"></param> /// <param name="client"></param> public void Read(ref byte[] packet, Client client) { PacketReader reader = new PacketReader(ref packet); Header header = reader.PopHeader(); reader.PopByte(); byte cmd = reader.PopByte(); Identity target = reader.PopIdentity(); int unknown = reader.PopInt(); string CmdStr = ""; byte CmdByte = 0; #region cmd args switch (cmd) { case 1: case 7: case 9: case 13: case 17: case 19: case 20: case 21: case 23: case 24: case 25: case 26: case 27: case 28: short CmdStrLen = reader.PopShort(); CmdStr = reader.PopString((int)CmdStrLen); break; case 10: CmdByte = reader.PopByte(); break; default: break; } reader.Finish(); #endregion DataTable dt; #region cmd handlers switch (cmd) { #region /org create <name> case 1: { // org create /* client wants to create organization * name of org is CmdStr */ string SqlQuery = "SELECT * FROM organizations WHERE Name='" + CmdStr + "'"; string guild_name = null; uint orgID = 0; dt = ms.ReadDT(SqlQuery); if (dt.Rows.Count > 0) { guild_name = (string)dt.Rows[0]["Name"]; } if (guild_name == null) { client.SendChatText("You have created the guild: " + CmdStr); string CurrDate = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); string SqlQuery2 = "INSERT INTO organizations (Name, creation, LeaderID, GovernmentForm) VALUES ('" + CmdStr + "', '" + CurrDate + "', '" + client.Character.ID + "', '0')"; ms.SqlInsert(SqlQuery2); string SqlQuery3 = "SELECT * FROM organizations WHERE Name='" + CmdStr + "'"; dt = ms.ReadDT(SqlQuery3); if (dt.Rows.Count > 0) { orgID = (UInt32)dt.Rows[0]["ID"]; } // Make sure the order of these next two lines is not swapped -NV client.Character.Stats.ClanLevel.Set(0); client.Character.orgId = orgID; break; } else { client.SendChatText("This guild already <font color=#DC143C>exists</font>"); break; } } #endregion #region /org ranks case 2: // org ranks //Displays Org Rank Structure. /* Select governingform from DB, Roll through display from GovForm */ if (client.Character.orgId == 0) { client.SendChatText("You're not in an organization!"); break; } string ranksSql = "SELECT GovernmentForm FROM organizations WHERE ID = " + client.Character.orgId; int govForm = -1; dt = ms.ReadDT(ranksSql); if (dt.Rows.Count > 0) { govForm = (Int32)dt.Rows[0]["GovernmentForm"]; } client.SendChatText("Current Rank Structure: " + GetRankList(govForm)); break; #endregion #region /org contract case 3: // org contract break; #endregion #region unknown org command 4 case 4: Console.WriteLine("Case 4 Started"); break; #endregion #region /org info case 5: { Client tPlayer = null; if (Misc.FindClient.FindClientByID(target.Instance, out tPlayer)) { string orgDescription = "", orgObjective = "", orgHistory = "", orgLeaderName = ""; int orgGoverningForm = 0, orgLeaderID = 0; dt = ms.ReadDT("SELECT * FROM organizations WHERE ID=" + tPlayer.Character.orgId); if (dt.Rows.Count > 0) { orgDescription = (string)dt.Rows[0]["Description"]; orgObjective = (string)dt.Rows[0]["Objective"]; orgHistory = (string)dt.Rows[0]["History"]; orgGoverningForm = (Int32)dt.Rows[0]["GovernmentForm"]; orgLeaderID = (Int32)dt.Rows[0]["LeaderID"]; } dt = ms.ReadDT("SELECT Name FROM characters WHERE ID=" + orgLeaderID); if (dt.Rows.Count > 0) { orgLeaderName = (string)dt.Rows[0][0]; } string TextGovForm = null; if (orgGoverningForm == 0) { TextGovForm = "Department"; } else if (orgGoverningForm == 1) { TextGovForm = "Faction"; } else if (orgGoverningForm == 2) { TextGovForm = "Republic"; } else if (orgGoverningForm == 3) { TextGovForm = "Monarchy"; } else if (orgGoverningForm == 4) { TextGovForm = "Anarchism"; } else if (orgGoverningForm == 5) { TextGovForm = "Feudalism"; } else { TextGovForm = "Department"; } string orgRank = GetRank(orgGoverningForm, tPlayer.Character.Stats.ClanLevel.StatBaseValue); PacketWriter writer = new PacketWriter(); writer.PushBytes(new byte[] { 0xDF, 0xDF }); writer.PushShort(10); writer.PushShort(1); writer.PushShort(0); writer.PushInt(3086); writer.PushInt(client.Character.ID); writer.PushInt(0x64582A07); writer.PushIdentity(50000, tPlayer.Character.ID); writer.PushByte(0); writer.PushByte(2); // OrgServer case 0x02 (Org Info) writer.PushInt(0); writer.PushInt(0); writer.PushInt(0xDEAA); // Type (org) writer.PushUInt(tPlayer.Character.orgId); // org ID writer.PushShort((short)tPlayer.Character.orgName.Length); writer.PushBytes(Encoding.ASCII.GetBytes(tPlayer.Character.orgName)); writer.PushShort((short)orgDescription.Length); writer.PushBytes(Encoding.ASCII.GetBytes(orgDescription)); writer.PushShort((short)orgObjective.Length); writer.PushBytes(Encoding.ASCII.GetBytes(orgObjective)); writer.PushShort((short)orgHistory.Length); writer.PushBytes(Encoding.ASCII.GetBytes(orgHistory)); writer.PushShort((short)TextGovForm.Length); writer.PushBytes(Encoding.ASCII.GetBytes(TextGovForm)); writer.PushShort((short)orgLeaderName.Length); writer.PushBytes(Encoding.ASCII.GetBytes(orgLeaderName)); writer.PushShort((short)orgRank.Length); writer.PushBytes(Encoding.ASCII.GetBytes(orgRank)); writer.Push3F1Count(0); byte[] reply = writer.Finish(); client.SendCompressed(reply); } } break; #endregion #region /org disband case 6: break; #endregion #region /org startvote <text> <duration> <entries> case 7: // org startvote <"text"> <duration(minutes)> <entries> // arguments (<text> <duration> and <entries>) are in CmdStr break; #endregion #region /org vote info case 8: // org vote info break; #endregion #region /org vote <entry> case 9: // <entry> is CmdStr break; #endregion #region /org promote case 10: { // some arg in CmdByte. No idea what it is //create the target namespace t_promote Client t_promote = null; string promoteSql = ""; int targetOldRank = -1; int targetNewRank = -1; int newPresRank = -1; int oldPresRank = 0; if (Misc.FindClient.FindClientByID(target.Instance, out t_promote)) { //First we check if target is in the same org as you if (t_promote.Character.orgId != client.Character.orgId) { //not in same org client.SendChatText("Target is not in your organization!"); break; } //Target is in same org, are you eligible to promote? Promoter Rank has to be TargetRank-2 or == 0 if ((client.Character.Stats.ClanLevel.Value == (t_promote.Character.Stats.ClanLevel.Value - 2)) || (client.Character.Stats.ClanLevel.Value == 0)) { //Promoter is eligible. Start the process //First we get the details about the org itself promoteSql = "SELECT * FROM organizations WHERE ID = " + client.Character.orgId; dt = ms.ReadDT(promoteSql); int promoteGovForm = -1; string promotedToRank = ""; string demotedFromRank = ""; if (dt.Rows.Count > 0) { promoteGovForm = (Int32)dt.Rows[0]["GovernmentForm"]; } //Check if new rank == 0, if so, demote promoter if ((targetOldRank - 1) == 0) { /* This is a bit more complex. Here we need to promote new president first * then we go about demoting old president * finally we set the new leader in SQL * Reset OrgName to set changes */ // Set new President's Rank targetOldRank = t_promote.Character.Stats.ClanLevel.Value; targetNewRank = targetOldRank - 1; promotedToRank = GetRank(promoteGovForm, (uint)targetNewRank); t_promote.Character.Stats.ClanLevel.Set(targetNewRank); // Demote the old president oldPresRank = client.Character.Stats.ClanLevel.Value; newPresRank = oldPresRank + 1; demotedFromRank = GetRank(promoteGovForm, (uint)newPresRank); client.Character.Stats.ClanLevel.Set(newPresRank); //Change the leader id in SQL string newLeadSql = "UPDATE organizations SET LeaderID = " + t_promote.Character.ID + " WHERE ID = " + t_promote.Character.orgId; ms.SqlUpdate(newLeadSql); client.SendChatText("You've passed leadership of the organization to: " + t_promote.Character.Name); t_promote.SendChatText("You've been promoted to the rank of " + promotedToRank + " by " + client.Character.Name); break; } else { //Just Promote targetOldRank = t_promote.Character.Stats.ClanLevel.Value; targetNewRank = targetOldRank - 1; promotedToRank = GetRank(promoteGovForm, (uint)targetNewRank); t_promote.Character.Stats.ClanLevel.Set(targetNewRank); client.SendChatText("You've promoted " + t_promote.Character.Name + " to " + promotedToRank); t_promote.SendChatText("You've been promoted to the rank of " + promotedToRank + " by " + client.Character.Name); } } else { //Promoter not eligible to promote client.SendChatText("Your Rank is not high enough to promote " + t_promote.Character.Name); break; } } break; } #endregion #region /org demote case 11: // demote target player //create the target namespace t_demote Client t_demote = null; string demoteSql = ""; int targetCurRank = -1; int targetNewerRank = -1; if (Misc.FindClient.FindClientByID(target.Instance, out t_demote)) { //First we check if target is in the same org as you if (t_demote.Character.orgId != client.Character.orgId) { //not in same org client.SendChatText("Target is not in your organization!"); break; } //Target is in same org, are you eligible to demote? Promoter Rank has to be TargetRank-2 or == 0 if ((client.Character.Stats.GmLevel.Value == (t_demote.Character.Stats.ClanLevel.Value - 2)) || (client.Character.Stats.ClanLevel.Value == 0)) { //Promoter is eligible. Start the process //First we get the details about the org itself demoteSql = "SELECT GovernmentForm FROM organizations WHERE ID = " + client.Character.orgId; dt = ms.ReadDT(demoteSql); int demoteGovForm = -1; string demotedToRank = ""; if (dt.Rows.Count > 0) { demoteGovForm = (Int32)dt.Rows[0]["GovernmentForm"]; } //Check whether new rank would be lower than lowest for current govform if ((targetCurRank + 1) > GetLowestRank(demoteGovForm)) { client.SendChatText("You can't demote character any lower!"); break; } targetCurRank = t_demote.Character.Stats.GmLevel.Value; targetNewerRank = targetCurRank + 1; demotedToRank = GetRank(demoteGovForm, (uint)targetNewerRank); t_demote.Character.Stats.ClanLevel.Set(targetNewerRank); client.SendChatText("You've demoted " + t_demote.Character.Name + " to " + demotedToRank); t_demote.SendChatText("You've been demoted to the rank of " + demotedToRank + " by " + client.Character.Name); break; } else { //Promoter not eligible to promote client.SendChatText("Your Rank is not high enough to demote " + t_demote.Character.Name); break; } } break; #endregion #region unknown org command 12 case 12: Console.WriteLine("Case 12 Started"); break; #endregion #region /org kick <name> case 13: // kick <name> from org // <name> is CmdStr //create the t_player Client namespace, using CmdStr to find character id, in replacement of target.Instance uint kickedFrom = client.Character.orgId; string kickeeSql = "SELECT * FROM characters WHERE Name = '" + CmdStr + "'"; int kickeeId = 0; dt = ms.ReadDT(kickeeSql); if (dt.Rows.Count > 0) { kickeeId = (Int32)dt.Rows[0]["ID"]; } Client target_player = null; if (Misc.FindClient.FindClientByID(kickeeId, out target_player)) { //Check if CmdStr is actually part of the org uint kickeeOrgId = target_player.Character.orgId; if (kickeeOrgId != client.Character.orgId) { //Not part of Org. break out. client.SendChatText(CmdStr + "is not a member of your organization!"); break; } //They are part of the org, so begin the processing... //First we check if the player is online... string onlineSql = "SELECT online FROM characters WHERE ID = " + client.Character.ID; dt = ms.ReadDT(onlineSql); int onlineStatus = 0; if (dt.Rows.Count > 0) { onlineStatus = (Int32)dt.Rows[0][0]; } if (onlineStatus == 0) { //Player isn't online. Org Kicks are processed in a different method break; } //Player is online. Start the kick. target_player.Character.Stats.ClanLevel.Set(0); target_player.Character.orgId = 0; string kickedFromSql = "SELECT Name FROM organizations WHERE ID = " + client.Character.orgId; dt = ms.ReadDT(kickedFromSql); string KickedFromName = ""; if (dt.Rows.Count > 0) { KickedFromName = (string)dt.Rows[0][0]; } target_player.SendChatText("You've been kicked from the organization " + KickedFromName); } break; #endregion #region /org invite case 14: { Client t_player = null; if (Misc.FindClient.FindClientByID(target.Instance, out t_player)) { PacketWriter writer = new PacketWriter(); writer.PushBytes(new byte[] { 0xDF, 0xDF }); writer.PushShort(10); writer.PushShort(1); writer.PushShort(0); writer.PushInt(3086); //Sender writer.PushInt(t_player.Character.ID); //Receiver writer.PushInt(0x64582A07); //Packet ID writer.PushIdentity(50000, t_player.Character.ID); //Target Identity writer.PushByte(0); writer.PushByte(5); //OrgServer Case 0x05 (Invite) writer.PushInt(0); writer.PushInt(0); writer.PushIdentity(0xDEAA, (int)client.Character.orgId); // Type (org) writer.PushShort((short)client.Character.orgName.Length); writer.PushBytes(Encoding.ASCII.GetBytes(client.Character.orgName)); writer.PushInt(0); byte[] reply = writer.Finish(); t_player.SendCompressed(reply); } } break; #endregion #region Org Join case 15: { //target.Instance holds the OrgID of the Org wishing to be joined. int orgIdtoJoin = target.Instance; string JoinSql = "SELECT * FROM organizations WHERE ID = '" + orgIdtoJoin + "' LIMIT 1"; int gov_form = 0; dt = ms.ReadDT(JoinSql); if (dt.Rows.Count > 0) { gov_form = (Int32)dt.Rows[0]["GovernmentForm"]; } // Make sure the order of these next two lines is not swapped -NV client.Character.Stats.ClanLevel.Set(GetLowestRank(gov_form)); client.Character.orgId = (uint)orgIdtoJoin; } break; #endregion #region /org leave case 16: // org leave // TODO: Disband org if it was leader that left org. -Suiv- // I don't think a Disband happens if leader leaves. I don't think leader -can- leave without passing lead to another // Something worth testing on Testlive perhaps ~Chaz // Just because something happens on TL, doesnt mean its a good idea. Really tbh id prefer it if you had to explicitly type /org disband to disband rather than /org leave doing it... -NV // Agreeing with NV. Org Leader can't leave without passing lead on. org disband requires /org disband to specifically be issued, with a Yes/No box. string LeaveSql = "SELECT * FROM organizations WHERE ID = " + client.Character.orgId; int govern_form = 0; dt = ms.ReadDT(LeaveSql); if (dt.Rows.Count > 0) { govern_form = (Int32)dt.Rows[0]["GovernmentForm"]; } if ((client.Character.Stats.ClanLevel.Value == 0) && (govern_form != 4)) { client.SendChatText("Organization Leader cannot leave organization without Disbanding or Passing Leadership!"); } else { client.Character.orgId = 0; client.SendChatText("You left the guild"); } break; #endregion #region /org tax | /org tax <tax> case 17: // gets or sets org tax // <tax> is CmdStr // if no <tax>, then just send chat text with current tax info if (CmdStr == null) { client.SendChatText("The current organization tax rate is: "); break; } else { break; } #endregion #region /org bank case 18: { // org bank dt = ms.ReadDT("SELECT * FROM organizations WHERE ID=" + client.Character.orgId); if (dt.Rows.Count > 0) { UInt64 bank_credits = (UInt64)dt.Rows[0]["Bank"]; client.SendChatText("Your bank has " + bank_credits + " credits in its account"); } } break; #endregion #region /org bank add <cash> case 19: { if (client.Character.orgId == 0) { client.SendChatText("You are not in an organisation."); break; } // org bank add <cash> int minuscredits_fromplayer = Convert.ToInt32(CmdStr); int characters_credits = client.Character.Stats.Cash.Value; if (characters_credits < minuscredits_fromplayer) { client.SendChatText("You do not have enough Credits"); } else { int total_Creditsspent = characters_credits - minuscredits_fromplayer; client.Character.Stats.Cash.Set(total_Creditsspent); ms.SqlUpdate("UPDATE `organizations` SET `Bank` = `Bank` + " + minuscredits_fromplayer + " WHERE `ID` = " + client.Character.orgId); client.SendChatText("You have donated " + minuscredits_fromplayer + " to the organization"); } } break; #endregion #region /org bank remove <cash> case 20: // org bank remove <cash> // <cash> is CmdStr // player wants to take credits from org bank // only leader can do that if ((client.Character.Stats.ClanLevel.Value != 0) || (client.Character.orgId == 0)) { client.SendChatText("You're not the leader of an Organization"); break; } int remove_credits = Convert.ToInt32(CmdStr); long org_bank = 0; dt = ms.ReadDT("SELECT Bank FROM organizations WHERE ID = " + client.Character.orgId); if (dt.Rows.Count > 0) { org_bank = (Int64)dt.Rows[0][0]; } if (remove_credits > org_bank) { client.SendChatText("Not enough credits in Organization Bank!"); break; } else { long neworgbank = org_bank - remove_credits; int existingcreds = 0; existingcreds = client.Character.Stats.Cash.Value; int newcreds = existingcreds + remove_credits; ms.SqlUpdate("UPDATE organizations SET Bank = " + neworgbank + " WHERE ID = " + client.Character.orgId); client.Character.Stats.Cash.Set(newcreds); client.SendChatText("You've removed " + remove_credits + " credits from the organization bank"); } break; #endregion #region /org bank paymembers <cash> case 21: // <cash> is CmdStr // give <cash> credits to every org member // credits are taken from org bank // only leader can do it break; #endregion #region /org debt case 22: // send player text about how big is his/her tax debt to org break; #endregion #region /org history <text> case 23: { if (client.Character.Stats.ClanLevel.Value == 0) { // org history <history text> ms.SqlUpdate("UPDATE organizations SET history = '" + CmdStr + "' WHERE ID = '" + client.Character.orgId + "'"); client.SendChatText("History Updated"); } else { client.SendChatText("You must be the Organization Leader to perform this command!"); } } break; #endregion #region /org objective <text> case 24: { if (client.Character.Stats.ClanLevel.Value == 0) { // org objective <objective text> ms.SqlUpdate("UPDATE organizations SET objective = '" + CmdStr + "' WHERE ID = '" + client.Character.orgId + "'"); client.SendChatText("Objective Updated"); } else { client.SendChatText("You must be the Organization Leader to perform this command!"); } } break; #endregion #region /org description <text> case 25: { if (client.Character.Stats.ClanLevel.Value == 0) { // org description <description text> ms.SqlUpdate("UPDATE organizations SET description = '" + CmdStr + "' WHERE ID = '" + client.Character.orgId + "'"); client.SendChatText("Description Updated"); } else { client.SendChatText("You must be the Organization Leader to perform this command!"); } } break; #endregion #region /org name <text> case 26: { // org name <name> /* Renames Organization * Checks for Existing Orgs with similar name to stop crash * Chaz */ if (client.Character.Stats.ClanLevel.Value == 0) { string SqlQuery26 = "SELECT * FROM organizations WHERE Name LIKE '" + CmdStr + "' LIMIT 1"; string CurrentOrg = null; dt = ms.ReadDT(SqlQuery26); if (dt.Rows.Count > 0) { CurrentOrg = (string)dt.Rows[0]["Name"]; } if (CurrentOrg == null) { string SqlQuery27 = "UPDATE organizations SET Name = '" + CmdStr + "' WHERE ID = '" + client.Character.orgId + "'"; ms.SqlUpdate(SqlQuery27); client.SendChatText("Organization Name Changed to: " + CmdStr); // Forces reloading of org name and the like // XXXX TODO: Make it reload for all other members in the org client.Character.orgId = client.Character.orgId; break; } else { client.SendChatText("An Organization already exists with that name"); break; } } else { client.SendChatText("You must be the organization leader to perform this command!"); } break; } #endregion #region /org governingform <text> case 27: { // org governingform <form> /* Current Governing Forms: * Department, Faction, Republic, Monarchy, Anarchism, Feudalism */ //Check on whether your President or not if (client.Character.Stats.ClanLevel.Value == 0) { //first we drop the case on the input, just to be sure. Int32 GovFormNum = -1; if (CmdStr == null) { //list gov forms client.SendChatText("List of Accepted Governing Forms is: department, faction, republic, monarchy, anarchism, feudalism"); break; } //was correct input passed? switch (CmdStr.ToLower()) { case "department": GovFormNum = 0; break; case "faction": GovFormNum = 1; break; case "republic": GovFormNum = 2; break; case "monarchy": GovFormNum = 3; break; case "anarchism": GovFormNum = 4; break; case "feudalism": GovFormNum = 5; break; default: client.SendChatText(CmdStr + " Is an invalid Governing Form!"); client.SendChatText("Accepted Governing Forms are: department, faction, republic, monarchy, anarchism, feudalism"); break; } if (GovFormNum != -1) { ms.SqlUpdate("UPDATE organizations SET GovernmentForm = '" + GovFormNum + "' WHERE ID = '" + client.Character.orgId + "'"); foreach (int currentCharId in OrgMisc.GetOrgMembers(client.Character.orgId, true)) { client.Character.Stats.ClanLevel.Set(GetLowestRank(GovFormNum)); } client.SendChatText("Governing Form is now: " + CmdStr); break; } } else { //Haha! You're not the org leader! client.SendChatText("You must be the Org Leader to perform this command"); break; } } break; #endregion #region /org stopvote <text> case 28: // <text> is CmdStr break; #endregion #region unknown command default: break; #endregion } #endregion reader.Finish(); }
/// <summary> /// Set target /// </summary> /// <param name="packet">ref to datapacket</param> public void setTarget(ref byte[] packet) { lock (this) { PacketReader pr = new PacketReader(ref packet); Header head = pr.PopHeader(); pr.PopByte(); Target = pr.PopIdentity(); pr.Finish(); } }
public static void Read(byte[] packet, Client client) { SqlWrapper mys = new SqlWrapper(); // Packet Reader Unknown Values are Returning 0 Integers, Unable to Store Needed Packet data To Reply. #region PacketReader PacketReader packetReader = new PacketReader(packet); Header m_header = packetReader.PopHeader(); // 0 - 28 byte unknown = packetReader.PopByte(); // 29 int actionNum = packetReader.PopInt(); // 30 - 33 int unknown1 = packetReader.PopInt(); // 34 - 37 Identity m_ident = packetReader.PopIdentity(); // 38 - 35 int unknown2 = packetReader.PopInt(); // 36 - 39 int unknown3 = packetReader.PopInt(); // 40 - 43 short unknown4 = packetReader.PopShort(); // 44 - 45 #endregion switch (actionNum) { #region Cast nano case 19: // Cast nano { // CastNanoSpell PacketWriter castNanoSpell = new PacketWriter(); castNanoSpell.PushByte(0xDF); castNanoSpell.PushByte(0xDF); castNanoSpell.PushShort(10); castNanoSpell.PushShort(1); castNanoSpell.PushShort(0); castNanoSpell.PushInt(3086); castNanoSpell.PushInt(client.Character.Id); castNanoSpell.PushInt(0x25314D6D); castNanoSpell.PushIdentity(50000, client.Character.Id); castNanoSpell.PushByte(0); castNanoSpell.PushInt(unknown3); // Nano ID castNanoSpell.PushIdentity(m_ident); // Target castNanoSpell.PushInt(0); castNanoSpell.PushIdentity(50000, client.Character.Id); // Caster byte[] castNanoSpellA = castNanoSpell.Finish(); Announce.Playfield(client.Character.PlayField, castNanoSpellA); // CharacterAction 107 PacketWriter characterAction107 = new PacketWriter(); characterAction107.PushByte(0xDF); characterAction107.PushByte(0xDF); characterAction107.PushShort(10); characterAction107.PushShort(1); characterAction107.PushShort(0); characterAction107.PushInt(3086); characterAction107.PushInt(client.Character.Id); characterAction107.PushInt(0x5E477770); characterAction107.PushIdentity(50000, client.Character.Id); characterAction107.PushByte(0); characterAction107.PushInt(107); characterAction107.PushInt(0); characterAction107.PushInt(0); characterAction107.PushInt(0); characterAction107.PushInt(1); characterAction107.PushInt(unknown3); characterAction107.PushShort(0); byte[] characterAction107A = characterAction107.Finish(); Announce.Playfield(client.Character.PlayField, characterAction107A); // CharacterAction 98 PacketWriter characterAction98 = new PacketWriter(); characterAction98.PushByte(0xDF); characterAction98.PushByte(0xDF); characterAction98.PushShort(10); characterAction98.PushShort(1); characterAction98.PushShort(0); characterAction98.PushInt(3086); characterAction98.PushInt(client.Character.Id); characterAction98.PushInt(0x5E477770); characterAction98.PushIdentity(m_ident); characterAction98.PushByte(0); characterAction98.PushInt(98); characterAction98.PushInt(0); characterAction98.PushInt(0xCF1B); characterAction98.PushInt(unknown3); characterAction98.PushInt(client.Character.Id); characterAction98.PushInt(0x249F0); // duration? characterAction98.PushShort(0); byte[] characterAction98A = characterAction98.Finish(); Announce.Playfield(client.Character.PlayField, characterAction98A); } break; #endregion #region search /* this is here to prevent server crash that is caused by * search action if server doesn't reply if something is * found or not */ case 66: // If action == search { /* Msg 110:136744723 = "No hidden objects found." */ client.SendFeedback(110, 136744723); } break; #endregion #region info case 105: // If action == Info Request { Client tPlayer = null; if ((tPlayer = FindClient.FindClientById(m_ident.Instance)) != null) { #region Titles uint LegacyScore = tPlayer.Character.Stats.PvpRating.StatBaseValue; string LegacyTitle = null; if (LegacyScore < 1400) { LegacyTitle = ""; } else if (LegacyScore < 1500) { LegacyTitle = "Freshman"; } else if (LegacyScore < 1600) { LegacyTitle = "Rookie"; } else if (LegacyScore < 1700) { LegacyTitle = "Apprentice"; } else if (LegacyScore < 1800) { LegacyTitle = "Novice"; } else if (LegacyScore < 1900) { LegacyTitle = "Neophyte"; } else if (LegacyScore < 2000) { LegacyTitle = "Experienced"; } else if (LegacyScore < 2100) { LegacyTitle = "Expert"; } else if (LegacyScore < 2300) { LegacyTitle = "Master"; } else if (LegacyScore < 2500) { LegacyTitle = "Champion"; } else { LegacyTitle = "Grand Master"; } #endregion int orgGoverningForm = 0; SqlWrapper ms = new SqlWrapper(); DataTable dt = ms.ReadDatatable( "SELECT `GovernmentForm` FROM organizations WHERE ID=" + tPlayer.Character.OrgId); if (dt.Rows.Count > 0) { orgGoverningForm = (Int32)dt.Rows[0][0]; } string orgRank = OrgClient.GetRank( orgGoverningForm, tPlayer.Character.Stats.ClanLevel.StatBaseValue); // Uses methods in ZoneEngine\PacketHandlers\OrgClient.cs /* Known packetFlags-- * 0x40 - No org | 0x41 - Org | 0x43 - Org and towers | 0x47 - Org, towers, player has personal towers | 0x50 - No pvp data shown * Bitflags-- * Bit0 = hasOrg, Bit1 = orgTowers, Bit2 = personalTowers, Bit3 = (Int32) time until supression changes (Byte) type of supression level?, Bit4 = noPvpDataShown, Bit5 = hasFaction, Bit6 = ?, Bit 7 = null. */ byte packetFlags = 0x40; // Player has no Org if (tPlayer.Character.OrgId != 0) { packetFlags = 0x41; // Player has Org, no towers } PacketWriter infoPacket = new PacketWriter(); // Start packet header infoPacket.PushByte(0xDF); infoPacket.PushByte(0xDF); infoPacket.PushShort(10); infoPacket.PushShort(1); infoPacket.PushShort(0); infoPacket.PushInt(3086); // sender (server ID) infoPacket.PushInt(client.Character.Id); // receiver infoPacket.PushInt(0x4D38242E); // packet ID infoPacket.PushIdentity(50000, tPlayer.Character.Id); // affected identity infoPacket.PushByte(0); // ? // End packet header infoPacket.PushByte(packetFlags); // Based on flags above infoPacket.PushByte(1); // esi_001? infoPacket.PushByte((byte)tPlayer.Character.Stats.Profession.Value); // Profession infoPacket.PushByte((byte)tPlayer.Character.Stats.Level.Value); // Level infoPacket.PushByte((byte)tPlayer.Character.Stats.TitleLevel.Value); // Titlelevel infoPacket.PushByte((byte)tPlayer.Character.Stats.VisualProfession.Value); // Visual Profession infoPacket.PushShort(0); // Side XP Bonus infoPacket.PushUInt(tPlayer.Character.Stats.Health.Value); // Current Health (Health) infoPacket.PushUInt(tPlayer.Character.Stats.Life.Value); // Max Health (Life) infoPacket.PushInt(0); // BreedHostility? infoPacket.PushUInt(tPlayer.Character.OrgId); // org ID infoPacket.PushShort((short)tPlayer.Character.FirstName.Length); infoPacket.PushBytes(Encoding.ASCII.GetBytes(tPlayer.Character.FirstName)); infoPacket.PushShort((short)tPlayer.Character.LastName.Length); infoPacket.PushBytes(Encoding.ASCII.GetBytes(tPlayer.Character.LastName)); infoPacket.PushShort((short)LegacyTitle.Length); infoPacket.PushBytes(Encoding.ASCII.GetBytes(LegacyTitle)); infoPacket.PushShort(0); // Title 2 // If receiver is in the same org as affected identity, whom is not orgless, send org rank and city playfield if ((client.Character.OrgId == tPlayer.Character.OrgId) && (tPlayer.Character.OrgId != 0)) { infoPacket.PushShort((short)orgRank.Length); infoPacket.PushBytes(Encoding.ASCII.GetBytes(orgRank)); infoPacket.PushInt(0); //infoPacket.PushIdentity(0, 0); // City (50201, Playfield) // Pushed 1 zero to much and screwed info for characters in orgs, but I´ll leave it for later just incase. } infoPacket.PushUInt(tPlayer.Character.Stats.InvadersKilled.Value); // Invaders Killed infoPacket.PushUInt(tPlayer.Character.Stats.KilledByInvaders.Value); // Killed by Invaders infoPacket.PushUInt(tPlayer.Character.Stats.AlienLevel.Value); // Alien Level infoPacket.PushUInt(tPlayer.Character.Stats.PvpDuelKills.Value); // Pvp Duel Kills infoPacket.PushUInt(tPlayer.Character.Stats.PvpDuelDeaths.Value); // Pvp Duel Deaths infoPacket.PushUInt(tPlayer.Character.Stats.PvpProfessionDuelDeaths.Value); // Pvp Profession Duel Kills infoPacket.PushUInt(tPlayer.Character.Stats.PvpRankedSoloKills.Value); // Pvp Solo Kills infoPacket.PushUInt(tPlayer.Character.Stats.PvpRankedSoloDeaths.Value); // Pvp Team Kills infoPacket.PushUInt(tPlayer.Character.Stats.PvpSoloScore.Value); // Pvp Solo Score infoPacket.PushUInt(tPlayer.Character.Stats.PvpTeamScore.Value); // Pvp Team Score infoPacket.PushUInt(tPlayer.Character.Stats.PvpDuelScore.Value); // Pvp Duel Score byte[] infoPacketA = infoPacket.Finish(); client.SendCompressed(infoPacketA); } else { NonPlayerCharacterClass npc = (NonPlayerCharacterClass)FindDynel.FindDynelById(m_ident.Type, m_ident.Instance); if (npc != null) { PacketWriter infoPacket = new PacketWriter(); // Start packet header infoPacket.PushByte(0xDF); infoPacket.PushByte(0xDF); infoPacket.PushShort(10); infoPacket.PushShort(1); infoPacket.PushShort(0); infoPacket.PushInt(3086); // sender (server ID) infoPacket.PushInt(client.Character.Id); // receiver infoPacket.PushInt(0x4D38242E); // packet ID infoPacket.PushIdentity(50000, npc.Id); // affected identity infoPacket.PushByte(0); // ? // End packet header infoPacket.PushByte(0x50); // npc's just have 0x50 infoPacket.PushByte(1); // esi_001? infoPacket.PushByte((byte)npc.Stats.Profession.Value); // Profession infoPacket.PushByte((byte)npc.Stats.Level.Value); // Level infoPacket.PushByte((byte)npc.Stats.TitleLevel.Value); // Titlelevel infoPacket.PushByte((byte)npc.Stats.VisualProfession.Value); // Visual Profession infoPacket.PushShort(0); // no idea for npc's infoPacket.PushUInt(npc.Stats.Health.Value); // Current Health (Health) infoPacket.PushUInt(npc.Stats.Life.Value); // Max Health (Life) infoPacket.PushInt(0); // BreedHostility? infoPacket.PushUInt(0); // org ID infoPacket.PushShort(0); infoPacket.PushShort(0); infoPacket.PushShort(0); infoPacket.PushShort(0); infoPacket.PushInt(0x499602d2); infoPacket.PushInt(0x499602d2); infoPacket.PushInt(0x499602d2); byte[] infoPacketA = infoPacket.Finish(); client.SendCompressed(infoPacketA); } } } break; #endregion #region logout case 120: // If action == Logout { //Start 30 second logout timer if client is not a GM (statid 215) if (client.Character.Stats.GMLevel.Value == 0) { client.startLogoutTimer(); } else // If client is a GM, disconnect without timer { client.Server.DisconnectClient(client); } } break; case 121: // If action == Stop Logout { //Stop current logout timer and send stop logout packet client.Character.UpdateMoveType((byte)client.Character.PreviousMoveMode); client.CancelLogOut(); } break; #endregion #region stand case 87: // If action == Stand { client.Character.UpdateMoveType(37); //Send stand up packet, and cancel timer/send stop logout packet if timer is enabled client.StandCancelLogout(); } break; #endregion #region Team case 22: //Kick Team Member { } break; case 24: //Leave Team { TeamClass team = new TeamClass(); team.LeaveTeam(client); } break; case 25: //Transfer Team Leadership { } break; case 26: //Team Join Request { // Send Team Invite Request To Target Player TeamClass team = new TeamClass(); team.SendTeamRequest(client, m_ident); } break; case 28: //Request Reply { // Check if positive or negative response // if positive TeamClass team = new TeamClass(); uint teamID = TeamClass.GenerateNewTeamId(client, m_ident); // Destination Client 0 = Sender, 1 = Reciever // Reciever Packets /////////////////// // CharAction 15 team.TeamRequestReply(client, m_ident); // CharAction 23 team.TeamRequestReplyCharacterAction23(client, m_ident); // TeamMember Packet team.TeamReplyPacketTeamMember(1, client, m_ident, "Member1"); // TeamMemberInfo Packet team.TeamReplyPacketTeamMemberInfo(1, client, m_ident); // TeamMember Packet team.TeamReplyPacketTeamMember(1, client, m_ident, "Member2"); // Sender Packets ///////////////// // TeamMember Packet team.TeamReplyPacketTeamMember(0, client, m_ident, "Member1"); // TeamMemberInfo Packet team.TeamReplyPacketTeamMemberInfo(0, client, m_ident); // TeamMember Packet team.TeamReplyPacketTeamMember(0, client, m_ident, "Member2"); } break; #endregion #region Delete Item case 0x70: mys.SqlDelete( "DELETE FROM " + client.Character.GetSqlTablefromDynelType() + "inventory WHERE placement=" + m_ident.Instance.ToString() + " AND container=" + m_ident.Type.ToString()); InventoryEntries i_del = client.Character.GetInventoryAt(m_ident.Instance); client.Character.Inventory.Remove(i_del); byte[] action2 = new byte[0x37]; Array.Copy(packet, action2, 0x37); action2[8] = 0x00; action2[9] = 0x00; action2[10] = 0x0C; action2[11] = 0x0E; client.SendCompressed(action2); break; #endregion #region Split item case 0x34: int nextid = client.Character.GetNextFreeInventory(m_ident.Type); InventoryEntries i = client.Character.GetInventoryAt(m_ident.Instance); i.Item.MultipleCount -= unknown3; InventoryEntries i2 = new InventoryEntries(); i2.Item = i.Item.ShallowCopy(); i2.Item.MultipleCount = unknown3; i2.Placement = nextid; client.Character.Inventory.Add(i2); client.Character.WriteInventoryToSql(); break; #endregion #region Join item case 0x35: InventoryEntries j1 = client.Character.GetInventoryAt(m_ident.Instance); InventoryEntries j2 = client.Character.GetInventoryAt(unknown3); j1.Item.MultipleCount += j2.Item.MultipleCount; client.Character.Inventory.Remove(j2); client.Character.WriteInventoryToSql(); byte[] joined = new byte[0x37]; Array.Copy(packet, joined, 0x37); joined[8] = 0x00; joined[9] = 0x00; joined[10] = 0x0C; joined[11] = 0x0E; client.SendCompressed(joined); break; #endregion #region Sneak Action // ################################################################################### // Spandexpants: This is all i have done so far as to make sneak turn on and off, // currently i cannot find a missing packet or link which tells the server the player // has stopped sneaking, hidden packet or something, will come back to later. // ################################################################################### // Sneak Packet Received case 163: { PacketWriter Sneak = new PacketWriter(); // TODO: IF SNEAKING IS ALLOWED RUN THIS CODE. // Send Action 162 : Enable Sneak Sneak.PushByte(0xDF); Sneak.PushByte(0xDF); Sneak.PushShort(0xA); Sneak.PushShort(1); Sneak.PushShort(0); Sneak.PushInt(3086); // Send Sneak.PushInt(client.Character.Id); // Reciever Sneak.PushInt(0x5e477770); // Packet ID Sneak.PushIdentity(50000, client.Character.Id); // TYPE / ID Sneak.PushInt(0); Sneak.PushByte(0xA2); // Action ID Sneak.PushInt(0); Sneak.PushInt(0); Sneak.PushInt(0); Sneak.PushInt(0); Sneak.PushInt(0); Sneak.PushShort(0); byte[] sneakpacket = Sneak.Finish(); client.SendCompressed(sneakpacket); // End of Enable sneak // TODO: IF SNEAKING IS NOT ALLOWED SEND REJECTION PACKET } break; #endregion #region Use Item on Item case 81: { Identity item1 = new Identity(); Identity item2 = new Identity(); item1.Type = m_ident.Type; item1.Instance = m_ident.Instance; item2.Type = unknown2; item2.Instance = unknown3; Tradeskill cts = new Tradeskill(client, item1.Instance, item2.Instance); cts.ClickBuild(); break; } #endregion #region Change Visual Flag case 166: { client.Character.Stats.VisualFlags.Set(unknown3); // client.SendChatText("Setting Visual Flag to "+unknown3.ToString()); AppearanceUpdate.AnnounceAppearanceUpdate(client.Character); break; } #endregion #region Tradeskill Source Changed case 0xdc: TradeSkillReceiver.TradeSkillSourceChanged(client, unknown2, unknown3); break; #endregion #region Tradeskill Target Changed case 0xdd: TradeSkillReceiver.TradeSkillTargetChanged(client, unknown2, unknown3); break; #endregion #region Tradeskill Build Pressed case 0xde: TradeSkillReceiver.TradeSkillBuildPressed(client, m_ident.Instance); break; #endregion #region default default: { byte[] action = new byte[0x37]; Array.Copy(packet, action, 0x37); action[8] = 0x00; action[9] = 0x00; action[10] = 0x0C; action[11] = 0x0E; Announce.Playfield(client.Character.PlayField, action); } break; #endregion } packetReader.Finish(); }
/// <summary> /// The read. /// </summary> /// <param name="packet"> /// The packet. /// </param> /// <param name="client"> /// The client. /// </param> /// <param name="dynel"> /// The dynel. /// </param> public static void Read(byte[] packet, Client client, Dynel dynel) { sender = client; PacketReader packetReader = new PacketReader(packet); packetReader.PopHeader(); packetReader.PopByte(); temp1 = packetReader.PopInt(); count = packetReader.PopInt(); // Count of commands sent action = packetReader.PopInt(); temp4 = packetReader.PopInt(); user = packetReader.PopIdentity(); target = packetReader.PopIdentity(); packetReader.Finish(); bool feedback = true; switch (action) { case 1: // Get break; case 2: // Drop break; case 3: // Use OnUse(); AOCoord newcoord = client.Character.Coordinates; feedback = false; if (Statels.StatelppfonUse.ContainsKey(client.Character.PlayField)) { foreach (Statels.Statel s in Statels.StatelppfonUse[client.Character.PlayField]) { if (s.onUse(client, target)) { return; } } } bool teleport = false; int playfield = 152; switch (target.Instance) { // Need to add feedback to the character // Are the Newer Grid points in this list??? // No newer Grid points in list, will be replaced by a check against a list of statels read from rdb anyway // - Algorithman case -1073605919: // Teleport Tower(noobisland)(right) if (client.Character.Stats.Side.Value != 2) { client.SendChatText("You need to be omni to use this teleporter!"); teleport = false; } else { newcoord.x = 202; newcoord.z = 878; newcoord.y = 16; playfield = 687; } break; case -1073736991: // Teleport Tower(noobisland)(left) if (client.Character.Stats.Side.Value != 1) { client.SendChatText("You need to be clan to use this teleporter!"); teleport = false; } else { newcoord.x = 390; newcoord.z = 340; newcoord.y = 0; playfield = 545; } break; case -1073671455: // Teleport Tower(noobisland)(middle) if (client.Character.Stats.Side.Value != 0) { client.SendChatText("You need to be neutral to use this teleporter!"); teleport = false; } else { newcoord.x = 685; newcoord.z = 480; newcoord.y = 73; playfield = 800; } break; case -1073741189: // 2ho -> Stret west if (client.Character.Stats.Cash.Value < 50) { // check if you got enough credits to use the ferry client.SendChatText("You need atleast 50 credits to board this ferry!"); teleport = false; } else { client.Character.Stats.Cash.Set(client.Character.Stats.Cash.Value - 50); newcoord.x = 1143; newcoord.z = 541; newcoord.y = 8; playfield = 790; } break; case -1073478890: // Stret West -> 2ho if (client.Character.Stats.Cash.Value < 50) { // check if you got enough credits to use the ferry client.SendChatText("You need atleast 50 credits to board this ferry!"); teleport = false; } else { client.Character.Stats.Cash.Set(client.Character.Stats.Cash.Value - 50); newcoord.x = 760; newcoord.z = 1982; newcoord.y = 7; playfield = 635; } break; case -1073216841: // Harry's -> Plesant Meadows if (client.Character.Stats.Cash.Value < 50) { // check if you got enough credits to use the ferry client.SendChatText("You need atleast 50 credits to board this ferry!"); teleport = false; } else { client.Character.Stats.Cash.Set(client.Character.Stats.Cash.Value - 50); newcoord.x = 370; newcoord.z = 1564; newcoord.y = 7; playfield = 630; } break; case -1073216906: // Plesant Meadows -> Harry's if (client.Character.Stats.Cash.Value < 50) { // check if you got enough credits to use the ferry client.SendChatText("You need atleast 50 credits to board this ferry!"); teleport = false; } else { client.Character.Stats.Cash.Set(client.Character.Stats.Cash.Value - 50); newcoord.x = 3196; newcoord.z = 3172; newcoord.y = 7; playfield = 695; } break; case -1073282442: // Pleasant Meadows -> Omni-Tek outpost in Lush Fields if (client.Character.Stats.Cash.Value < 50) { // check if you got enough credits to use the ferry client.SendChatText("You need atleast 50 credits to board this ferry!"); teleport = false; } else { client.Character.Stats.Cash.Set(client.Character.Stats.Cash.Value - 50); newcoord.x = 3389; newcoord.z = 800; newcoord.y = 8; playfield = 695; } break; case -1073413449: // Omni-Tek outpost in Lush Fields -> Pleasant Meadows if (client.Character.Stats.Cash.Value < 50) { // check if you got enough credits to use the ferry client.SendChatText("You need atleast 50 credits to board this ferry!"); teleport = false; } else { client.Character.Stats.Cash.Set(client.Character.Stats.Cash.Value - 50); newcoord.x = 370; newcoord.z = 1562; newcoord.y = 7; playfield = 630; } break; case -1073347913: // Harry's trading outpost -> Omni-1 Trade (free) newcoord.x = 3569; newcoord.z = 912; newcoord.y = 9; playfield = 695; break; case -1073282377: // Omni-1 Trade -> Harry's trading outpost (free) newcoord.x = 3290; newcoord.z = 2922; newcoord.y = 7; playfield = 695; break; default: feedback = true; teleport = false; break; } if (teleport) { client.Teleport(newcoord, client.Character.Heading, playfield); } // Use item in inventory if (target.Type == 104) { InventoryEntries ie = client.Character.GetInventoryAt(target.Instance); AOItem mi = ItemHandler.GetItemTemplate(ie.Item.LowID); // TODO mi.applyon(client.Character, ItemHandler.eventtype_onuse, true, false, ie.Placement); TemplateAction.Send(client.Character, ie); if (mi.isConsumable()) { ie.Item.MultipleCount--; if (ie.Item.MultipleCount <= 0) { client.Character.Inventory.Remove(ie); DeleteItem.Send(client.Character, ie.Container, ie.Placement); // Packets.Stat.Set(client, 0, client.Character.Stats.GetStat(0),false); } } foreach (AOEvents aoe in mi.Events) { if (aoe.EventType == Constants.EventtypeOnUse) { sender.Character.ExecuteEvent( sender.Character, sender.Character, aoe, true, false, 0, CheckReqs.doCheckReqs); SkillUpdate.SendStat(client, 0x209, client.Character.Stats.SocialStatus.Value, false); // Social Status return; } } int le = packet[7] + packet[6] * 256; byte[] reply = new byte[le]; Array.Copy(packet, reply, le); reply[0] = 0xdf; reply[1] = 0xdf; reply[8] = 0x00; reply[9] = 0x00; reply[10] = 0x0C; reply[11] = 0x0E; reply[12] = (byte)(client.Character.Id >> 24); reply[13] = (byte)(client.Character.Id >> 16); reply[14] = (byte)(client.Character.Id >> 8); reply[15] = (byte)client.Character.Id; reply[0x1c] = 0; reply[32] = 1; reply[36] = 3; PacketWriter pw = new PacketWriter(); pw.PushBytes(reply); byte[] rep = pw.Finish(); client.SendCompressed(rep); SkillUpdate.SendStat(client, 0x209, client.Character.Stats.SocialStatus.Value, false); // Social Status return; } else if (target.Type == 51035) { // Shops VendingMachine vm = VendorHandler.GetVendorById(target.Instance); ShopInventory.Send(client, vm); Trade.Send(client, client.Character, vm); Trade.Send(client, vm, client.Character); Trade.Send(client, vm, client.Character); int le = packet[7] + packet[6] * 256; byte[] reply = new byte[le]; Array.Copy(packet, reply, le); reply[0] = 0xdf; reply[1] = 0xdf; reply[8] = 0x00; reply[9] = 0x00; reply[10] = 0x0C; reply[11] = 0x0E; reply[12] = (byte)(client.Character.Id >> 24); reply[13] = (byte)(client.Character.Id >> 16); reply[14] = (byte)(client.Character.Id >> 8); reply[15] = (byte)client.Character.Id; reply[0x1c] = 0; reply[0x20] = 1; client.Character.LastTrade = target; PacketWriter pw = new PacketWriter(); pw.PushBytes(reply); byte[] rep = pw.Finish(); client.SendCompressed(rep); } else if (target.Type == 51050) { // Open corpse } break; case 4: // Repair break; case 5: // UseItemOnItem #if DEBUG Console.WriteLine("Use Item on Item not defined yet"); Console.WriteLine("Packet data:"); string line = string.Empty; int count2 = 0; foreach (byte packbyte in packet) { if ((count2 % 16) == 0) { Console.WriteLine(line); line = string.Empty; } line = line + packbyte.ToString("X2") + " "; count2++; } if (line != string.Empty) { Console.WriteLine(); } Console.WriteLine(line); #endif break; default: break; } if (feedback) { #if DEBUG string Feedback1 = string.Format("T1 {0}, Count {1}, Action {2}, T4 {3}", temp1, count, action, temp4); string Feedback2 = string.Format( "User {0}:{1}, Target {2}:{3} ({4}:{5})", user.Type, user.Instance, target.Type, (uint)target.Instance, target.Type.ToString("X4"), ((uint)target.Instance).ToString("X8")); Statels.Statel b = null; if (Statels.Statelppf.ContainsKey(client.Character.PlayField)) { foreach (Statels.Statel z in Statels.Statelppf[client.Character.PlayField]) { if ((z.Type == target.Type) && ((Int32)z.Instance == target.Instance)) { b = z; break; } } } if (b != null) { foreach (Statels.StatelEvent e in b.Events) { Console.WriteLine("DebugOutput: \r\n" + e); } Console.WriteLine(b.Coordinates.ToString()); } else { Console.WriteLine( "No Statel defined in database for #" + target.Type + ":" + (UInt32)target.Instance + " (" + target.Type.ToString("X4") + ":" + target.Instance.ToString("X8") + ")"); } client.SendChatText(Feedback1); client.SendChatText(Feedback2); #endif } }
/// <summary> /// Set target /// </summary> /// <param name="packet">data packet</param> public void SetTarget(byte[] packet) { lock (this) { PacketReader packetReader = new PacketReader(packet); packetReader.PopHeader(); packetReader.PopByte(); this.Target = packetReader.PopIdentity(); packetReader.Finish(); } }
public static void AddItemToContainer(byte[] packet, Client cli) { PacketReader packetReader = new PacketReader(packet); bool noAppearanceUpdate = false; /* Container ID's: * 0065 Weaponpage * 0066 Armorpage * 0067 Implantpage * 0068 Inventory (places 64-93) * 0069 Bank * 006B Backpack * 006C KnuBot Trade Window * 006E Overflow window * 006F Trade Window * 0073 Socialpage * 0767 Shop Inventory * 0790 Playershop Inventory * DEAD Trade Window (incoming) */ packetReader.PopInt(); packetReader.PopInt(); int sender = packetReader.PopInt(); packetReader.PopInt(); packetReader.PopInt(); Identity fromIdentity = packetReader.PopIdentity(); byte flag = packetReader.PopByte(); int c350 = fromIdentity.Type; int fromId = fromIdentity.Instance; int fromContainerID = packetReader.PopInt(); int fromPlacement = packetReader.PopInt(); Identity toIdentity = packetReader.PopIdentity(); int toid = toIdentity.Instance; c350 = toIdentity.Type; int toPlacement = packetReader.PopInt(); int counterFrom = 0; if ((fromContainerID <= 0x68) || (fromContainerID == 0x73)) // Inventory or Equipmentpages? { for (counterFrom = 0; (counterFrom < cli.Character.Inventory.Count) && (fromPlacement != cli.Character.Inventory[counterFrom].Placement); counterFrom++) { ; } } else { if (fromContainerID == 0x69) { for (counterFrom = 0; (counterFrom < cli.Character.Bank.Count) && (fromPlacement != cli.Character.Bank[counterFrom].Flags); counterFrom++) { ; } } else { counterFrom = -1; } } // TODO: Add check for instanced items (fromcontainerid:fromplacement) if (counterFrom == -1) { return; } int counterTo; if (toIdentity.Type == 0xdead) // Transferring to a trade window??? (only bank trade window yet) { counterTo = cli.Character.Bank.Count; } else { for (counterTo = 0; (counterTo < cli.Character.Inventory.Count) && (toPlacement != cli.Character.Inventory[counterTo].Placement); counterTo++) { ; } } AOItem itemFrom = null; if (counterFrom < cli.Character.Inventory.Count) { itemFrom = ItemHandler.interpolate( cli.Character.Inventory[counterFrom].Item.LowID, cli.Character.Inventory[counterFrom].Item.HighID, cli.Character.Inventory[counterFrom].Item.Quality); } AOItem itemTo = null; if (counterTo < cli.Character.Inventory.Count) { itemTo = ItemHandler.interpolate( cli.Character.Inventory[counterTo].Item.LowID, cli.Character.Inventory[counterTo].Item.HighID, cli.Character.Inventory[counterTo].Item.Quality); } // Calculating delay for equip/unequip/switch gear int delay = 0; if (itemFrom != null) { delay += itemFrom.getItemAttribute(211); } if (itemTo != null) { delay += itemTo.getItemAttribute(211); } if (delay == 0) { delay = 200; } int counter; if (toPlacement == 0x6f) // 0x6f = next free inventory place, we need to send back the actual spot where the item goes // something has to be free, client checks for full inventory { counter = 0; int counter2 = 0; int counter3 = 0; if (toIdentity.Type == 0xdead) { while (counter3 == 0) { counter3 = 1; for (counter2 = 0; counter2 < cli.Character.Bank.Count; counter2++) { if (cli.Character.Bank[counter2].Flags == counter) // using flags for placement { counter++; counter3 = 0; continue; } } } } else { counter = 64; while (counter3 == 0) { counter3 = 1; for (counter2 = 0; counter2 < cli.Character.Inventory.Count; counter2++) { if (cli.Character.Inventory[counter2].Placement == counter) { counter++; counter3 = 0; continue; } } } } toPlacement = counter; } cli.Character.DoNotDoTimers = true; if (toIdentity.Type == 0xdead) // 0xdead only stays for bank at the moment { cli.Character.TransferItemtoBank(fromPlacement, toPlacement); noAppearanceUpdate = true; } else { switch (fromContainerID) { case 0x68: // from Inventory if (toPlacement <= 30) { // to Weaponspage or Armorpage // TODO: Send some animation if (itemTo != null) { cli.Character.UnequipItem(itemTo, cli.Character, false, fromPlacement); // send interpolated item Unequip.Send(cli, itemTo, InventoryPage(toPlacement), toPlacement); // client takes care of hotswap cli.Character.EquipItem(itemFrom, cli.Character, false, toPlacement); Equip.Send(cli, itemFrom, InventoryPage(toPlacement), toPlacement); } else { cli.Character.EquipItem(itemFrom, cli.Character, false, toPlacement); Equip.Send(cli, itemFrom, InventoryPage(toPlacement), toPlacement); } } else { if (toPlacement < 46) { if (itemTo == null) { cli.Character.EquipItem(itemFrom, cli.Character, false, toPlacement); Equip.Send(cli, itemFrom, InventoryPage(toPlacement), toPlacement); } } // Equiping to social page if ((toPlacement >= 49) && (toPlacement <= 63)) { if (itemTo != null) { cli.Character.UnequipItem(itemTo, cli.Character, true, fromPlacement); // send interpolated item cli.Character.EquipItem(itemFrom, cli.Character, true, toPlacement); } else { cli.Character.EquipItem(itemFrom, cli.Character, true, toPlacement); } //cli.Character.switchItems(cli, fromplacement, toplacement); } } cli.Character.SwitchItems(fromPlacement, toPlacement); cli.Character.CalculateSkills(); noAppearanceUpdate = false; break; case 0x66: // from Armorpage cli.Character.UnequipItem(itemFrom, cli.Character, false, fromPlacement); // send interpolated item Unequip.Send(cli, itemFrom, InventoryPage(fromPlacement), fromPlacement); cli.Character.SwitchItems(fromPlacement, toPlacement); cli.Character.CalculateSkills(); noAppearanceUpdate = false; break; case 0x65: // from Weaponspage cli.Character.UnequipItem(itemFrom, cli.Character, false, fromPlacement); // send interpolated item Unequip.Send(cli, itemFrom, InventoryPage(fromPlacement), fromPlacement); cli.Character.SwitchItems(fromPlacement, toPlacement); cli.Character.CalculateSkills(); noAppearanceUpdate = false; break; case 0x67: // from Implantpage cli.Character.UnequipItem(itemFrom, cli.Character, false, fromPlacement); // send interpolated item Unequip.Send(cli, itemFrom, InventoryPage(fromPlacement), fromPlacement); cli.Character.SwitchItems(fromPlacement, toPlacement); cli.Character.CalculateSkills(); noAppearanceUpdate = true; break; case 0x73: cli.Character.UnequipItem(itemFrom, cli.Character, true, fromPlacement); cli.Character.SwitchItems(fromPlacement, toPlacement); cli.Character.CalculateSkills(); break; case 0x69: cli.Character.TransferItemfromBank(fromPlacement, toPlacement); toPlacement = 0x6f; // setting back to 0x6f for packet reply noAppearanceUpdate = true; break; case 0x6c: // KnuBot Trade Window cli.Character.TransferItemfromKnuBotTrade(fromPlacement, toPlacement); break; default: break; } } cli.Character.DoNotDoTimers = false; if ((fromPlacement < 0x30) || (toPlacement < 0x30)) // Equipmentpages need delays { // Delay when equipping/unequipping // has to be redone, jumping breaks the equiping/unequiping // and other messages have to be done too // like heartbeat timer, damage from environment and such Thread.Sleep(delay); } else { Thread.Sleep(200); //social has to wait for 0.2 secs too (for helmet update) } SwitchItem.Send(cli, fromContainerID, fromPlacement, toIdentity, toPlacement); cli.Character.Stats.ClearChangedFlags(); if (!noAppearanceUpdate) { cli.Character.AppearanceUpdate(); } itemFrom = null; itemTo = null; }
public static void Read(byte[] packet, Client client, Dynel dynel) { PacketReader reader = new PacketReader(packet); PacketWriter packetWriter = new PacketWriter(); Header header = reader.PopHeader(); reader.PopByte(); reader.PopInt(); // unknown byte action = reader.PopByte(); // unknown Identity ident = reader.PopIdentity(); int container = reader.PopInt(); int place = reader.PopInt(); Character character = (Character)FindDynel.FindDynelById(ident.Type, ident.Instance); Character chaffected = (Character)FindDynel.FindDynelById(header.AffectedId.Type, header.AffectedId.Instance); // If target is a NPC, call its Action 0 if ((character is NonPlayerCharacterClass) && (action == 0)) { if (((NonPlayerCharacterClass)character).KnuBot != null) { character.KnuBotTarget = character; ((NonPlayerCharacterClass)character).KnuBot.TalkingTo = chaffected; ((NonPlayerCharacterClass)character).KnuBot.Action(0); } return; } int cashDeduct = 0; int inventoryCounter; InventoryEntries inventoryEntry; switch (action) { case 1: // end trade inventoryCounter = client.Character.Inventory.Count - 1; while (inventoryCounter >= 0) { inventoryEntry = client.Character.Inventory[inventoryCounter]; AOItem aoItem; if (inventoryEntry.Container == -1) { int nextFree = client.Character.GetNextFreeInventory(104); aoItem = ItemHandler.GetItemTemplate(inventoryEntry.Item.LowID); int price = aoItem.getItemAttribute(74); int mult = aoItem.getItemAttribute(212); // original multiplecount if (mult == 0) { mult = 1; inventoryEntry.Item.MultipleCount = 1; } // Deduct Cash (ie.item.multiplecount) div mult * price cashDeduct += Convert.ToInt32( mult * price * (100 - Math.Floor(Math.Min(1500, client.Character.Stats.ComputerLiteracy.Value) / 40.0)) / 2500); // Add the Shop modificator and exchange the CompLit for skill form vendortemplate table inventoryEntry.Placement = nextFree; inventoryEntry.Container = 104; if (!aoItem.isStackable()) { int multiplicator = inventoryEntry.Item.MultipleCount; inventoryEntry.Item.MultipleCount = 0; while (multiplicator > 0) { AddTemplate.Send(client, inventoryEntry); multiplicator--; } } else { AddTemplate.Send(client, inventoryEntry); } } if (inventoryEntry.Container == -2) { aoItem = ItemHandler.interpolate( inventoryEntry.Item.LowID, inventoryEntry.Item.HighID, inventoryEntry.Item.Quality); double multipleCount = aoItem.getItemAttribute(212); // original multiplecount int price = aoItem.getItemAttribute(74); if (multipleCount == 0.0) { multipleCount = 1.0; } else { multipleCount = inventoryEntry.Item.MultipleCount / multipleCount; } cashDeduct -= Convert.ToInt32( multipleCount * price * (100 + Math.Floor(Math.Min(1500, client.Character.Stats.ComputerLiteracy.Value) / 40.0)) / 2500); // Add the Shop modificator and exchange the CompLit for skill form vendortemplate table client.Character.Inventory.Remove(inventoryEntry); } inventoryCounter--; } client.Character.Stats.Cash.Set((uint)(client.Character.Stats.Cash.Value - cashDeduct)); // Packets.Stat.Set(client, 61, client.Character.Stats.Cash.StatValue - cashdeduct, false); byte[] reply0 = new byte[32]; Array.Copy(packet, reply0, 32); // pushing in server ID reply0[8] = 0; reply0[9] = 0; reply0[10] = 12; reply0[11] = 14; // pushing in Client ID reply0[12] = (byte)(client.Character.Id >> 24); reply0[13] = (byte)(client.Character.Id >> 16); reply0[14] = (byte)(client.Character.Id >> 8); reply0[15] = (byte)(client.Character.Id); packetWriter.PushBytes(reply0); packetWriter.PushByte(1); packetWriter.PushByte(4); packetWriter.PushIdentity(client.Character.LastTrade); packetWriter.PushIdentity(client.Character.LastTrade); client.Character.LastTrade = new Identity { Instance = 0, Type = 0 }; byte[] reply2 = packetWriter.Finish(); client.SendCompressed(reply2); break; case 2: // Decline trade inventoryCounter = client.Character.Inventory.Count - 1; while (inventoryCounter >= 0) { inventoryEntry = client.Character.Inventory[inventoryCounter]; if (inventoryEntry.Container == -1) { client.Character.Inventory.Remove(inventoryEntry); } else { if (inventoryEntry.Container == -2) { inventoryEntry.Placement = client.Character.GetNextFreeInventory(104); inventoryEntry.Container = 104; } } inventoryCounter--; } byte[] replyCopy = new byte[50]; Array.Copy(packet, replyCopy, 50); // pushing in server ID replyCopy[8] = 0; replyCopy[9] = 0; replyCopy[10] = 12; replyCopy[11] = 14; // pushing in Client ID replyCopy[12] = (byte)(client.Character.Id >> 24); replyCopy[13] = (byte)(client.Character.Id >> 16); replyCopy[14] = (byte)(client.Character.Id >> 8); replyCopy[15] = (byte)(client.Character.Id); packetWriter.PushBytes(replyCopy); byte[] rep1 = packetWriter.Finish(); client.SendCompressed(rep1); break; case 3: break; case 4: break; case 5: // add item to trade window case 6: // remove item from trade window byte[] reply = new byte[50]; Array.Copy(packet, reply, 50); if (character.Inventory.Count == 0) { ((VendingMachine)character).LoadTemplate(((VendingMachine)character).TemplateId); } // pushing in server ID reply[8] = 0; reply[9] = 0; reply[10] = 12; reply[11] = 14; // pushing in Client ID reply[12] = (byte)(client.Character.Id >> 24); reply[13] = (byte)(client.Character.Id >> 16); reply[14] = (byte)(client.Character.Id >> 8); reply[15] = (byte)(client.Character.Id); //PacketWriter pw = new PacketWriter(); packetWriter.PushBytes(reply); byte[] replyRemoveItemFromTradeWindow = packetWriter.Finish(); client.SendCompressed(replyRemoveItemFromTradeWindow); if (client.Character == character) { if (action == 5) { inventoryEntry = character.GetInventoryAt(place); inventoryEntry.Placement = character.GetNextFreeInventory(-2); inventoryEntry.Container = -2; } if (action == 6) { inventoryEntry = character.GetInventoryAt(place, -2); inventoryEntry.Placement = character.GetNextFreeInventory(104); inventoryEntry.Container = 104; } } else { InventoryEntries inew = new InventoryEntries { Container = -1, Placement = character.GetNextFreeInventory(-1) }; int oldPlacement = ((packet[46] >> 24) + (packet[47] >> 16) + (packet[48] >> 8) + packet[49]); InventoryEntries totrade = character.GetInventoryAt(oldPlacement); inew.Item.LowID = totrade.Item.LowID; inew.Item.HighID = totrade.Item.HighID; inew.Item.MultipleCount = totrade.Item.MultipleCount; if (action == 6) // Remove item from trade window { inew.Item.MultipleCount = -inew.Item.MultipleCount; } inew.Item.Quality = totrade.Item.Quality; chaffected.InventoryReplaceAdd(inew); } break; } }