Beispiel #1
0
        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;
            }
        }
Beispiel #2
0
        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;
            }
        }
Beispiel #3
0
        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;
            }
        }
Beispiel #4
0
        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;
            }
        }
Beispiel #5
0
        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;
            }
        }
Beispiel #6
0
        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;
            }
        }
Beispiel #7
0
        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;
            }
        }
Beispiel #8
0
        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;
            }
        }