示例#1
0
        /// <inheritdoc/>
        public override object ConvertFrom(ref ObjectContext objectContext, Scalar fromScalar)
        {
            var idIndex   = fromScalar.Value.IndexOf('~');
            var id        = ItemId.Empty;
            var keyString = fromScalar.Value;

            if (idIndex >= 0)
            {
                var idString = fromScalar.Value.Substring(0, idIndex);
                keyString = fromScalar.Value.Substring(idIndex + 1);
                id        = ItemId.Parse(idString);
            }
            var keyType             = objectContext.Descriptor.Type.GetGenericArguments()[0];
            var keyDescriptor       = objectContext.SerializerContext.FindTypeDescriptor(keyType);
            var keySerializer       = objectContext.SerializerContext.Serializer.GetSerializer(objectContext.SerializerContext, keyDescriptor);
            var scalarKeySerializer = keySerializer as ScalarSerializerBase;

            // TODO: deserialize non-scalar keys!
            if (scalarKeySerializer == null)
            {
                throw new InvalidOperationException("Non-scalar key not yet supported!");
            }

            var context = new ObjectContext(objectContext.SerializerContext, null, keyDescriptor);
            var key     = scalarKeySerializer.ConvertFrom(ref context, new Scalar(keyString));
            var result  = Activator.CreateInstance(typeof(KeyWithId <>).MakeGenericType(keyType), id, key);

            return(result);
        }
示例#2
0
        /// <summary>
        /// This method executes on the bidder's partition.
        /// Called by web: priority 0
        /// </summary>
        public async Task <ItemInfo> CreateItemAsync(String sellerEmail, String itemName, String imageUrl, DateTime expiration, Decimal startAmount, CancellationToken cancellationToken)
        {
            // NOTE: If items gets large, old item value (but not key) can move to warm storage

            // If user exists, create item & transactionally and it to user's items dictionary & unexpired items dictionary
            Email _sellerEmail = Email.Parse(sellerEmail);

            using (var tx = CreateTransaction()) {
                var cr = await m_users.TryGetValueAsync(tx, _sellerEmail);

                if (!cr.HasValue)
                {
                    throw new InvalidOperationException($"Seller '{_sellerEmail}' doesn't exist.");
                }

                // Look up user's (seller's) auction item dictionary & add the new item to it:
                IReliableDictionary <ItemId, ItemInfo> userItems = await GetSellerItemsAsync(_sellerEmail);

                ItemId   itemId = ItemId.Parse(_sellerEmail, itemName);
                ItemInfo item   = new ItemInfo(itemId, imageUrl, expiration, new[] { new Bid(_sellerEmail, startAmount) }); // Seller places first bid
                try {
                    await userItems.AddAsync(tx, itemId, item);                                                             // TODO: If already exists
                }
                catch (Exception ex) {
                    throw new InvalidOperationException($"Seller '{itemId.Seller}' is already selling '{itemId.ItemName}'.", ex);
                }
                await m_unexpiredItems.AddAsync(tx, itemId);

                await tx.CommitAsync();

                return(item);
            }
        }
示例#3
0
        /// <summary>
        /// This method executes on the bidder's partition.
        /// Called by web: priority 0
        /// </summary>
        public async Task <Bid[]> PlaceBidAsync(String bidderEmail, String sellerEmail, String itemName, Decimal bidAmount, CancellationToken ct)
        {
            Email _sellerEmail = Email.Parse(sellerEmail);

            using (var tx = CreateTransaction()) {
                Email  _bidderEmail = Email.Parse(bidderEmail);
                ItemId itemId       = ItemId.Parse(_sellerEmail, itemName);

                var cr = await m_users.TryGetValueAsync(tx, _bidderEmail);

                if (!cr.HasValue)
                {
                    throw new InvalidOperationException($"Bidder '{_bidderEmail}' doesn't exist.");
                }

                // Create new User object identical to current with new itemId added to it (if not already in collection [idempotent])
                UserInfo userInfo = cr.Value;
                if (!userInfo.ItemsBidding.Contains(itemId))
                {
                    userInfo = userInfo.AddItemBidding(itemId);
                    await m_users.SetAsync(tx, _bidderEmail, userInfo);

                    await tx.CommitAsync();
                }
                // NOTE: If we fail here, the bidder thinks they're bidding on an item but the
                // item doesn't know about the bidder. If so, the bidder will not see their latest bid.
                // The bidder could bid again (which is why adding the item is idempotent).
            }
            // Tell seller's partition to place a bid
            var proxy = (IInternalOperations) new ServiceOperations(s_partitionEndpointResolver, AuctionServiceNameUri);

            return(await proxy.PlaceBid2Async(bidderEmail, sellerEmail, itemName, bidAmount, ct));
        }
示例#4
0
        /// <summary>
        /// This method executes on the seller's partition. This method is only ever called by PlaceBidAsync; not via Internet
        /// Not called by web at all
        /// </summary>
        public async Task <Bid[]> PlaceBid2Async(String bidderEmail, String sellerEmail, String itemName, Decimal bidAmount, CancellationToken ct)
        {
            // This method executes on the seller's partition
            Email _sellerEmail = Email.Parse(sellerEmail);

            using (var tx = CreateTransaction()) {
                Email   _bidderEmail    = Email.Parse(bidderEmail);
                ItemId  itemId          = ItemId.Parse(_sellerEmail, itemName);
                Boolean isUnexpiredItem = await m_unexpiredItems.ContainsAsync(tx, itemId);

                if (!isUnexpiredItem)
                {
                    throw new InvalidOperationException("Item's auction expired or item doesn't exist.");
                }

                var sellersItems = await GetSellerItemsAsync(itemId.Seller);

                var conditionalItemInfo = await sellersItems.TryGetValueAsync(tx, itemId);

                if (!conditionalItemInfo.HasValue)
                {
                    throw new InvalidOperationException("Item doesn't exist.");                             // We should never get here
                }
                var itemInfo = conditionalItemInfo.Value;
                var bids     = itemInfo.Bids;
                var lastBid  = bids.Last(); // Get current last bid

                //var cr = await m_users.TryGetValueAsync(tx2, itemId.Seller);
                if (DateTime.UtcNow > itemInfo.Expiration)
                {
                    throw new InvalidOperationException("The action for this item has expired.");
                }
                if (_bidderEmail == lastBid.Bidder)
                {
                    throw new InvalidOperationException("You cannot outbid yourself.");
                }
                if (bidAmount <= lastBid.Amount)
                {
                    throw new InvalidOperationException("Your bid must be greater than the highest bid.");
                }

                // Create a new item copied from the original with the new bid
                itemInfo = itemInfo.AddBid(new Bid(_bidderEmail, bidAmount));
                await sellersItems.SetAsync(tx, itemId, itemInfo);

                await tx.CommitAsync();

                return(itemInfo.Bids.ToArray());
            }
        }
示例#5
0
 public static ChestEvent Parse(string[] args)
 {
     if (args == null)
     {
         throw new ArgumentNullException(nameof(args));
     }
     return(new ChestEvent(TextId.None)
     {
         ChestId = ChestId.Parse(args[1]),
         PickDifficulty = args.Length > 2 ? byte.Parse(args[2], CultureInfo.InvariantCulture) : (byte)0,
         InitialTextId = args.Length > 3 ? byte.Parse(args[3], CultureInfo.InvariantCulture) : (byte)255,
         UnlockedTextId = args.Length > 4 ? byte.Parse(args[4], CultureInfo.InvariantCulture) : (byte)255,
         KeyItemId = args.Length > 5 ? ItemId.Parse(args[5]) : ItemId.None,
     });
 }
 public void Parse(GameBitBuffer buffer)
 {
     Field0 = new RequiredMessageHeader();
     Field0.Parse(buffer);
     Field1 = new ItemId();
     Field1.Parse(buffer);
 }