public void Handle(Character character, InteractionCode code, Packet iPacket) { switch (code) { case InteractionCode.OpenStore: { this.Owner.Map.PlayerShops.Add(this); this.Opened = true; } break; case InteractionCode.AddItem: { ItemType type = (ItemType)iPacket.ReadByte(); short slot = iPacket.ReadShort(); short bundles = iPacket.ReadShort(); short perBundle = iPacket.ReadShort(); int price = iPacket.ReadInt(); short quantity = (short)(bundles * perBundle); Item item = character.Items[type, slot]; if (item == null) { return; } if (perBundle < 0 || perBundle * bundles > 2000 || bundles < 0 || price < 0) { return; } if (quantity > item.Quantity) { return; } if (quantity < item.Quantity) { item.Quantity -= quantity; item.Update(); } else { character.Items.Remove(item, true); } PlayerShopItem shopItem = new PlayerShopItem(item.MapleID, bundles, quantity, price); this.Items.Add(shopItem); this.UpdateItems(); } break; case InteractionCode.RemoveItem: { if (character == this.Owner) { short slot = iPacket.ReadShort(); PlayerShopItem shopItem = this.Items[slot]; if (shopItem == null) { return; } if (shopItem.Quantity > 0) { this.Owner.Items.Add(new Item(shopItem.MapleID, shopItem.Quantity)); } this.Items.Remove(shopItem); this.UpdateItems(); } } break; case InteractionCode.Exit: { if (character == this.Owner) { this.Close(); } else { this.RemoveVisitor(character); } } break; case InteractionCode.Buy: { short slot = iPacket.ReadByte(); short quantity = iPacket.ReadShort(); PlayerShopItem shopItem = this.Items[slot]; if (shopItem == null) { return; } if (character == this.Owner) { return; } if (quantity > shopItem.Quantity) { return; } if (character.Meso < shopItem.MerchantPrice * quantity) { return; } shopItem.Quantity -= quantity; character.Meso -= shopItem.MerchantPrice * quantity; this.Owner.Meso += shopItem.MerchantPrice * quantity; character.Items.Add(new Item(shopItem.MapleID, quantity)); this.UpdateItems(); // TODO: This doesn't mark the item as sold. bool noItemLeft = true; foreach (PlayerShopItem loopShopItem in this.Items) { if (loopShopItem.Quantity > 0) { noItemLeft = false; break; } } if (noItemLeft) { // TODO: Close the owner's shop. // TODO: Notify the owner the shop has been closed due to items being sold out. this.Close(); } } break; case InteractionCode.Chat: { string text = iPacket.ReadString(); using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Chat) .WriteByte(8); byte sender = 0; for (int i = 0; i < this.Visitors.Length; i++) { if (this.Visitors[i] == character) { sender = (byte)(i + 1); } } oPacket .WriteByte(sender) .WriteString("{0} : {1}", character.Name, text); this.Broadcast(oPacket); } } break; } }
public void Handle(Character player, InteractionCode action, Packet inPacket) { switch (action) { case InteractionCode.Start: if (this.IsReady) { this.IsStarted = true; this.IsReady = false; using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte((byte)InteractionCode.Start); outPacket.WriteByte((byte)this.Loser); this.Owner.Client.Send(outPacket); this.Visitor.Client.Send(outPacket); } } break; case InteractionCode.Exit: if (this.Owner == player) { this.Close(); } else { this.Visitor.Omok = null; this.Visitor = null; } break; case InteractionCode.Chat: string chat = inPacket.ReadString(); using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(0x06, 0x08); outPacket.WriteBool(player != this.Owner); outPacket.WriteString(player.Name + " : " + chat); this.Owner.Client.Send(outPacket); this.Visitor.Client.Send(outPacket); } break; case InteractionCode.Skip: using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte((byte)InteractionCode.Skip); outPacket.WriteBool(player == this.Owner); this.Owner.Client.Send(outPacket); this.Visitor.Client.Send(outPacket); } break; case InteractionCode.MoveOmok: int x = inPacket.ReadInt(); int y = inPacket.ReadInt(); int type = inPacket.ReadByte(); // piece ( 1 or 2; Owner has one piece, visitor has another, it switches every game.) //TODO: Check to see if its their turn this.Pieces[x, y] = type; using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte((byte)InteractionCode.MoveOmok); outPacket.WriteInt(x); outPacket.WriteInt(y); outPacket.WriteByte((byte)type); this.Owner.Client.Send(outPacket); this.Visitor.Client.Send(outPacket); } this.CheckForCombo(player, type); break; case InteractionCode.Ready: this.IsReady = true; using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte((byte)InteractionCode.Ready); this.Owner.Client.Send(outPacket); this.Visitor.Client.Send(outPacket); } break; case InteractionCode.UnReady: this.IsReady = false; using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte((byte)InteractionCode.UnReady); this.Owner.Client.Send(outPacket); this.Visitor.Client.Send(outPacket); } break; case InteractionCode.RequestTie: using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte(0x2C); if (player == this.Owner) { this.Visitor.Client.Send(outPacket); } else { this.Owner.Client.Send(outPacket); } } break; case InteractionCode.AnswerTie: int status = inPacket.ReadByte(); using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte(0x2C); if (player == this.Owner) { this.Visitor.Client.Send(outPacket); } else { this.Owner.Client.Send(outPacket); } } break; case InteractionCode.GiveUp: if (player == this.Owner) { this.EndGame(this.Visitor, false, true); } else { this.EndGame(this.Owner, false, true); } break; } }
public void Handle(Character character, InteractionCode code, Packet iPacket) { switch (code) { case InteractionCode.Invite: { int characterID = iPacket.ReadInt(); if (!this.Owner.Map.Characters.Contains(characterID)) { // TODO: What does happen in case the invitee left? return; } Character invitee = this.Owner.Map.Characters[characterID]; if (invitee.Trade != null) { using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Decline) .WriteByte(2) .WriteString(invitee.Name); this.Owner.Client.Send(oPacket); } } else { invitee.Trade = this; this.Visitor = invitee; using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Invite) .WriteByte(3) .WriteString(this.Owner.Name) .WriteBytes(new byte[4] { 0xB7, 0x50, 0x00, 0x00 }); this.Visitor.Client.Send(oPacket); } } } break; case InteractionCode.Decline: { using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Decline) .WriteByte(3) .WriteString(character.Name); this.Owner.Client.Send(oPacket); } this.Owner.Trade = null; this.Visitor.Trade = null; this.Owner = null; this.Visitor = null; } break; case InteractionCode.Visit: { if (this.Owner == null) { this.Visitor = null; character.Trade = null; Character.Notify(character, "Trade has been closed.", NoticeType.Popup); } else { this.Started = true; using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Visit) .WriteByte(1) .WriteBytes(this.Visitor.AppearanceToByteArray()) .WriteString(this.Visitor.Name); this.Owner.Client.Send(oPacket); } using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Room) .WriteByte(3) .WriteByte(2) .WriteByte(1) .WriteByte(0) .WriteBytes(this.Owner.AppearanceToByteArray()) .WriteString(this.Owner.Name) .WriteByte(1) .WriteBytes(this.Visitor.AppearanceToByteArray()) .WriteString(this.Visitor.Name) .WriteByte(byte.MaxValue); this.Visitor.Client.Send(oPacket); } } } break; case InteractionCode.SetItems: { ItemConstants.ItemType type = (ItemConstants.ItemType)iPacket.ReadByte(); short slot = iPacket.ReadShort(); short quantity = iPacket.ReadShort(); byte targetSlot = iPacket.ReadByte(); Item item = character.Items[type, slot]; if (item.IsBlocked) { return; } if (quantity > item.Quantity) { return; } if (quantity < item.Quantity) { item.Quantity -= quantity; item.Update(); item = new Item(item.MapleID, quantity); } else { character.Items.Remove(item, true); } item.Slot = 0; using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.SetItems) .WriteByte(0) .WriteByte(targetSlot) .WriteBytes(item.ToByteArray(true)); if (character == this.Owner) { this.OwnerItems.Add(item); this.Owner.Client.Send(oPacket); } else { this.VisitorItems.Add(item); this.Visitor.Client.Send(oPacket); } } using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.SetItems) .WriteByte(1) .WriteByte(targetSlot) .WriteBytes(item.ToByteArray(true)); if (character == this.Owner) { this.Visitor.Client.Send(oPacket); } else { this.Owner.Client.Send(oPacket); } } } break; case InteractionCode.SetMeso: { int meso = iPacket.ReadInt(); if (meso < 0 || meso > character.Meso) { return; } // TODO: The meso written in this packet is the added meso amount. // The amount that should be written is the total amount. using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.SetMeso) .WriteByte(0) .WriteInt(meso); if (character == this.Owner) { if (this.OwnerLocked) { return; } this.OwnerMeso += meso; this.Owner.Meso -= meso; this.Owner.Client.Send(oPacket); } else { if (this.VisitorLocked) { return; } this.VisitorMeso += meso; this.Visitor.Meso -= meso; this.Visitor.Client.Send(oPacket); } } using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.SetMeso) .WriteByte(1) .WriteInt(meso); if (this.Owner == character) { this.Visitor.Client.Send(oPacket); } else { oPacket.WriteInt(this.OwnerMeso); this.Owner.Client.Send(oPacket); } } } break; case InteractionCode.Exit: { if (this.Started) { this.Cancel(); using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Exit) .WriteByte(0) .WriteByte(2); this.Owner.Client.Send(oPacket); this.Visitor.Client.Send(oPacket); } this.Owner.Trade = null; this.Visitor.Trade = null; this.Owner = null; this.Visitor = null; } else { using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Exit) .WriteByte(0) .WriteByte(2); this.Owner.Client.Send(oPacket); } this.Owner.Trade = null; this.Owner = null; } } break; case InteractionCode.Confirm: { using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket.WriteByte((byte)InteractionCode.Confirm); if (character == this.Owner) { this.OwnerLocked = true; this.Visitor.Client.Send(oPacket); } else { this.VisitorLocked = true; this.Owner.Client.Send(oPacket); } } if (this.OwnerLocked && this.VisitorLocked) { this.Complete(); using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Exit) .WriteByte(0) .WriteByte(6); this.Owner.Client.Send(oPacket); this.Visitor.Client.Send(oPacket); } this.Owner.Trade = null; this.Visitor.Trade = null; this.Owner = null; this.Visitor = null; } } break; case InteractionCode.Chat: { string text = iPacket.ReadString(); using (Packet oPacket = new Packet(ServerOperationCode.PlayerInteraction)) { oPacket .WriteByte((byte)InteractionCode.Chat) .WriteByte(8) .WriteBool(this.Owner != character) .WriteString("{0} : {1}", character.Name, text); this.Owner.Client.Send(oPacket); this.Visitor.Client.Send(oPacket); } } break; } }
public void Handle(Character player, InteractionCode action, Packet inPacket) { switch (action) { case InteractionCode.Open: if (player.ID != this.OwnerID) { throw new HackException("Opening foreign hired merchant."); } else if (!this.Opened) { this.Opened = true; this.Position = player.Position; player.Map.HiredMerchants.Add(this); } break; case InteractionCode.AddItem: case InteractionCode.PutItem: { Item item = player.Items[inPacket.ReadByte(), inPacket.ReadSByte()]; short bundles = inPacket.ReadShort(); short perBundle = inPacket.ReadShort(); int price = inPacket.ReadInt(); short quantity = (short)(bundles * perBundle); if (perBundle < 0 || perBundle * bundles > 2000 || bundles < 0 || price < 0) { throw new HackException("Illegal quantity of items in hired merchant."); } if (quantity > item.Quantity) { return; } else if (quantity < item.Quantity) { item.Quantity -= quantity; item.Update(); } else if (quantity == item.Quantity) { player.Items.Remove(item, true); } this.Items.Add(new PlayerShopItem(item.MapleID, perBundle, quantity, price)); this.Update(); } break; case InteractionCode.RemoveItem: case InteractionCode.TakeItemBack: if (this.OwnerID == player.ID) { PlayerShopItem item = this.Items[inPacket.ReadShort()]; if (item.Quantity > 0) { player.Items.Add(new Item(item.MapleID, item.Quantity)); } this.Items.Remove(item); this.Update(); } else { throw new HackException("Removing items from a foreign hired merchant."); } break; case InteractionCode.Exit: if (this.Visitors[0] == player || this.Visitors[1] == player || this.Visitors[2] == player) { for (int i = 0; i < 3; i++) { if (this.Visitors[i] == player) { this.Visitors[i] = null; player.HiredMerchant = null; using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte(0x0A); if (i > 0) { outPacket.WriteByte((byte)(i + 1)); } this.Broadcast(outPacket); } break; } } } break; case InteractionCode.MaintenanceOff: if (this.OwnerID == player.ID) { this.InMaintenance = false; } else { throw new HackException("Turning off maintenance from a foreign hired merchant."); } break; case InteractionCode.Buy: { PlayerShopItem item = this.Items[inPacket.ReadByte()]; short quantity = inPacket.ReadShort(); if (this.OwnerID == player.ID) { throw new HackException("Buying items from own hired merchant."); } if (quantity > item.Quantity || player.Meso < item.MerchantPrice * quantity) { return; } item.Quantity -= quantity; this.Meso += item.MerchantPrice * quantity; this.Update(); player.Meso -= item.MerchantPrice * quantity; player.Items.Add(new Item(item.MapleID, item.Quantity)); } break; case InteractionCode.Chat: string chat = inPacket.ReadString(); using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(6, 8); for (int i = 0; i < 3; i++) { if (this.Visitors[i] == player) { outPacket.WriteByte((byte)(i + 1)); break; } } outPacket.WriteString(player.Name + " : " + chat); this.Broadcast(outPacket); } break; case InteractionCode.MerchantClose: if (this.OwnerID == player.ID) { this.Close(player, true); } else { throw new HackException("Closing a foreign hired merchant."); } break; } }
public void Handle(Character player, InteractionCode action, Packet inPacket) { switch (action) { case InteractionCode.Open: { this.Owner.Map.PlayerShops.Add(this); this.Opened = true; } break; case InteractionCode.AddItem: { byte type = inPacket.ReadByte(); sbyte slot = (sbyte)inPacket.ReadShort(); short bundles = inPacket.ReadShort(); short perBundle = inPacket.ReadShort(); int price = inPacket.ReadInt(); short quantity = (short)(bundles * perBundle); Item item = player.Items[type, slot]; if (perBundle < 0 || perBundle * bundles > 2000 || bundles < 0 || price < 0) { throw new HackException("Illegal quantity of items in player shop."); } if (quantity > item.Quantity) { throw new HackException("Trading more items than available."); } if (quantity < item.Quantity) { item.Quantity -= quantity; item.Update(); } else { player.Items.Remove(item, true); } PlayerShopItem shopItem = new PlayerShopItem(item.MapleID, bundles, quantity, price); this.Items.Add(shopItem); this.UpdateItems(); } break; case InteractionCode.RemoveItem: if (this.Owner == player) { PlayerShopItem targetItem = this.Items[inPacket.ReadShort()]; if (targetItem.Quantity > 0) { this.Owner.Items.Add(new Item(targetItem.MapleID, targetItem.Quantity)); } this.Items.Remove(targetItem); this.UpdateItems(); } else { throw new HackException("Removing items from a foreign shop."); } break; case InteractionCode.Exit: if (this.Owner == player) { this.Close(); } else { this.RemoveVisitor(player); } break; case InteractionCode.Buy: { PlayerShopItem purchase = this.Items[inPacket.ReadByte()]; short quantity = inPacket.ReadShort(); if (this.Owner == player) { throw new HackException("Buying items from own shop."); } if (quantity > purchase.Quantity) { throw new HackException("Buying a higher ammount of items than allowed."); } if (player.Meso < purchase.MerchantPrice * quantity) { throw new HackException("Buying items without enough mesos."); } purchase.Quantity -= quantity; player.Meso -= purchase.MerchantPrice * quantity; this.Owner.Meso += purchase.MerchantPrice * quantity; player.Items.Add(new Item(purchase.MapleID, quantity)); this.UpdateItems(); bool noItemLeft = true; foreach (PlayerShopItem shopItem in this.Items) { if (shopItem.Quantity > 0) { noItemLeft = false; break; } } if (noItemLeft) { this.Close(); } } break; case InteractionCode.Chat: { string chat = inPacket.ReadString(); using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(6, 8); byte sender = 0; for (int i = 0; i < 3; i++) { if (this.Visitors[i] == player) { sender = (byte)(i + 1); } } outPacket.WriteByte(sender); outPacket.WriteString(player.Name + " : " + chat); this.Broadcast(outPacket); } } break; } }
public void Handle(GameCharacter gameCharacter, InteractionCode code, PacketReader packet) { switch (code) { case InteractionCode.Invite: Invite(packet); break; case InteractionCode.Decline: Decline(gameCharacter); break; case InteractionCode.Visit: Visit(gameCharacter); break; case InteractionCode.SetItems: SetItems(packet, gameCharacter); break; case InteractionCode.SetMeso: { var meso = packet.ReadInt(); if (meso < 0 || meso > gameCharacter.PrimaryStats.Meso) { return; } // TODO: The meso written in this packet is the added meso amount. // The amount that should be written is the total amount. using var pw = new PacketWriter(ServerOperationCode.PlayerInteraction); pw.WriteByte(InteractionCode.SetMeso); pw.WriteByte(0); pw.WriteInt(meso); if (gameCharacter == Owner) { if (OwnerLocked) { return; } OwnerMeso += meso; Owner.PrimaryStats.Meso -= meso; Owner.Send(pw); } else { if (VisitorLocked) { return; } VisitorMeso += meso; Visitor.PrimaryStats.Meso -= meso; Visitor.Send(pw); } using var pw2 = new PacketWriter(ServerOperationCode.PlayerInteraction); pw2.WriteByte(InteractionCode.SetMeso); pw2.WriteByte(1); pw2.WriteInt(meso); if (Owner == gameCharacter) { Visitor.Send(pw2); } else { pw2.WriteInt(OwnerMeso); Owner.Send(pw2); } } break; case InteractionCode.Exit: { if (Started) { Cancel(); using var pw = new PacketWriter(ServerOperationCode.PlayerInteraction); pw.WriteByte(InteractionCode.Exit); pw.WriteByte(0); pw.WriteByte(2); Owner.Send(pw); Visitor.Send(pw); Owner.Trade = null; Visitor.Trade = null; Owner = null; Visitor = null; } else { using var pw = new PacketWriter(ServerOperationCode.PlayerInteraction); pw.WriteByte(InteractionCode.Exit); pw.WriteByte(0); pw.WriteByte(2); Owner.Send(pw); Owner.Trade = null; Owner = null; } } break; case InteractionCode.Confirm: { using var pwConfirm = new PacketWriter(ServerOperationCode.PlayerInteraction); pwConfirm.WriteByte(InteractionCode.Confirm); if (gameCharacter == Owner) { OwnerLocked = true; Visitor.Send(pwConfirm); } else { VisitorLocked = true; Owner.Send(pwConfirm); } if (OwnerLocked && VisitorLocked) { Complete(); using var pw = new PacketWriter(ServerOperationCode.PlayerInteraction); pw.WriteByte(InteractionCode.Exit); pw.WriteByte(0); pw.WriteByte(6); Owner.Send(pw); Visitor.Send(pw); Owner.Trade = null; Visitor.Trade = null; Owner = null; Visitor = null; } } break; case InteractionCode.Chat: { var text = packet.ReadString(); using var pw = new PacketWriter(ServerOperationCode.PlayerInteraction); pw.WriteByte(InteractionCode.Chat); pw.WriteByte(8); pw.WriteBool(Owner != gameCharacter); pw.WriteString($"{gameCharacter.Name} : {text}"); Owner.Send(pw); Visitor.Send(pw); } break; } }
public void Handle(GameCharacter gameCharacter, InteractionCode code, PacketReader iPacket) { switch (code) { case InteractionCode.OpenStore: { Owner.Map.PlayerShops.Add(this); Opened = true; } break; case InteractionCode.AddItem: { var type = (ItemType)iPacket.ReadByte(); var slot = iPacket.ReadShort(); var bundles = iPacket.ReadShort(); var perBundle = iPacket.ReadShort(); var price = iPacket.ReadInt(); var quantity = (short)(bundles * perBundle); var item = gameCharacter.Items[type, slot]; if (item == null) { return; } if (perBundle < 0 || perBundle * bundles > 2000 || bundles < 0 || price < 0) { return; } if (quantity > item.Quantity) { return; } if (quantity < item.Quantity) { item.Quantity -= quantity; item.Update(); } else { gameCharacter.Items.Remove(item, true); } var shopItem = new PlayerShopItem(item.MapleId, bundles, quantity, price); Items.Add(shopItem); UpdateItems(); } break; case InteractionCode.RemoveItem: { if (gameCharacter == Owner) { var slot = iPacket.ReadShort(); var shopItem = Items[slot]; if (shopItem == null) { return; } if (shopItem.Quantity > 0) { Owner.Items.Add(new Item(shopItem.MapleId, shopItem.Quantity)); } Items.Remove(shopItem); UpdateItems(); } } break; case InteractionCode.Exit: { if (gameCharacter == Owner) { Close(); } else { RemoveVisitor(gameCharacter); } } break; case InteractionCode.Buy: { short slot = iPacket.ReadByte(); var quantity = iPacket.ReadShort(); var shopItem = Items[slot]; if (shopItem == null) { return; } if (gameCharacter == Owner) { return; } if (quantity > shopItem.Quantity) { return; } if (gameCharacter.PrimaryStats.Meso < shopItem.MerchantPrice * quantity) { return; } shopItem.Quantity -= quantity; gameCharacter.PrimaryStats.Meso -= shopItem.MerchantPrice * quantity; Owner.PrimaryStats.Meso += shopItem.MerchantPrice * quantity; gameCharacter.Items.Add(new Item(shopItem.MapleId, quantity)); UpdateItems(); // TODO: This doesn't mark the item as sold. var noItemLeft = true; foreach (var loopShopItem in Items) { if (loopShopItem.Quantity > 0) { noItemLeft = false; break; } } if (noItemLeft) { // TODO: Close the owner's shop. // TODO: Notify the owner the shop has been closed due to items being sold out. Close(); } } break; case InteractionCode.Chat: { var text = iPacket.ReadString(); using var pw = new PacketWriter(ServerOperationCode.PlayerInteraction); pw.WriteByte(InteractionCode.Chat); pw.WriteByte(8); byte sender = 0; for (var i = 0; i < Visitors.Length; i++) { if (Visitors[i] == gameCharacter) { sender = (byte)(i + 1); } } pw.WriteByte(sender); pw.WriteString($"{gameCharacter.Name} : {text}"); Broadcast(pw); } break; } }
public void Handle(Character player, InteractionCode action, Packet inPacket) { switch (action) { case InteractionCode.Invite: Character invitee = this.Owner.Map.Characters[inPacket.ReadInt()]; if (invitee.Trade != null) { using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte(0xA); outPacket.WriteByte(); outPacket.WriteBytes(PacketConstants.Trade); outPacket.WriteByte(2); this.Owner.Client.Send(outPacket); } player.Notify("This player is already in a trade.", NoticeType.Pink); } else { invitee.Trade = this; this.Visitor = invitee; using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(2, 3); outPacket.WriteString(this.Owner.Name); outPacket.WriteBytes(PacketConstants.Trade); this.Visitor.Client.Send(outPacket); } } break; case InteractionCode.Decline: this.Visitor.Trade = null; this.Owner.Trade = null; using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte(0xA); outPacket.WriteByte(); outPacket.WriteBytes(PacketConstants.Trade); outPacket.WriteByte(2); this.Owner.Client.Send(outPacket); } this.Owner.Notify("The trade has been declined.", NoticeType.Popup); this.Owner = null; this.Visitor = null; break; case InteractionCode.Visit: if (this.Owner == null) { this.Visitor = null; player.Trade = null; player.Notify("The trade has already been closed.", NoticeType.Popup); } else { this.Started = true; using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(4, 1); outPacket.WriteBytes(this.Visitor.AppearanceToByteArray()); outPacket.WriteString(this.Visitor.Name); this.Owner.Client.Send(outPacket); } using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(5, 3, 2, 1, 0); outPacket.WriteBytes(this.Owner.AppearanceToByteArray()); outPacket.WriteString(this.Owner.Name); outPacket.WriteByte(1); outPacket.WriteBytes(this.Visitor.AppearanceToByteArray()); outPacket.WriteString(this.Visitor.Name); outPacket.WriteByte(0xFF); this.Visitor.Client.Send(outPacket); } } break; case InteractionCode.SetItems: ItemType type = (ItemType)inPacket.ReadByte(); sbyte slot = (sbyte)inPacket.ReadShort(); short quantity = inPacket.ReadShort(); byte targetSlot = inPacket.ReadByte(); Item item = player.Items[type, slot]; if (item.IsBlocked) { throw new HackException("Trading blocked item."); } else if (quantity > item.Quantity) { throw new HackException("Trading more items than available."); } else { if (quantity < item.Quantity) { item.Quantity -= quantity; item.Update(); item = new Item(item.MapleID, quantity); } else { player.Items.Remove(item, true); } item.Slot = (sbyte)targetSlot; using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(0xE, 0); outPacket.WriteBytes(item.ToByteArray()); if (player == this.Owner) { this.OwnerItems.Add(item); this.Owner.Client.Send(outPacket); } else { this.VisitorItems.Add(item); this.Visitor.Client.Send(outPacket); } } using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(0xE, 1); outPacket.WriteBytes(item.ToByteArray()); if (player == this.Owner) { this.Visitor.Client.Send(outPacket); } else { this.Owner.Client.Send(outPacket); } } } break; case InteractionCode.SetMeso: int meso = inPacket.ReadInt(); if (meso < 0 || meso > player.Meso) { throw new HackException("Invalid amount of meso in trade."); } else { using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(0xF, 0); outPacket.WriteInt(meso); if (this.Owner == player) { if (this.OwnerLocked) { throw new InvalidOperationException("Adding mesos to locked trade."); } this.Owner.Client.Send(outPacket); this.OwnerMeso += meso; this.Owner.Meso -= meso; } else { if (this.VisitorLocked) { throw new InvalidOperationException("Adding mesos to locked trade."); } this.Visitor.Client.Send(outPacket); this.VisitorMeso += meso; this.Visitor.Meso -= meso; } } using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(0x0F, 0x01); outPacket.WriteInt(meso); if (this.Owner == player) { this.Visitor.Client.Send(outPacket); } else { this.Owner.Client.Send(outPacket); } } } break; case InteractionCode.Exit: if (this.Started) { this.Cancel(); using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(0x0A, 0x00); outPacket.WriteByte(2); this.Owner.Client.Send(outPacket); this.Visitor.Client.Send(outPacket); } this.Owner.Trade = null; this.Visitor.Trade = null; this.Owner = null; this.Visitor = null; } else { using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(0x0A, 0x00); outPacket.WriteBytes(PacketConstants.Trade); outPacket.WriteByte(2); this.Owner.Client.Send(outPacket); } this.Owner.Trade = null; this.Owner = null; } break; case InteractionCode.Confirm: using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteByte(0x10); if (this.Owner == player) { this.OwnerLocked = true; this.Visitor.Client.Send(outPacket); } else { this.VisitorLocked = true; this.Owner.Client.Send(outPacket); } } if (this.OwnerLocked && this.VisitorLocked) { this.Complete(); using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(0x0A, 0x00); outPacket.WriteByte(6); this.Owner.Client.Send(outPacket); this.Visitor.Client.Send(outPacket); } this.Owner.Trade = null; this.Visitor.Trade = null; this.Owner = null; this.Visitor = null; } break; case InteractionCode.Chat: string chat = inPacket.ReadString(); using (Packet outPacket = new Packet(MapleServerOperationCode.PlayerInteraction)) { outPacket.WriteBytes(6, 8); outPacket.WriteBool(this.Owner != player); outPacket.WriteString(player.Name + " : " + chat); this.Owner.Client.Send(outPacket); this.Visitor.Client.Send(outPacket); } break; } }