예제 #1
0
        /// <summary>
        /// Returns null if either ship is already trading.
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        ShipShipTrade TryInitializeTrade(IShip a, IShip b)
        {
            lock (TRADELOCK)
            {
                if (_shipIDToTradeID.ContainsKey(a.Id))
                {
                    return(null);
                }
                if (_shipIDToTradeID.ContainsKey(b.Id))
                {
                    return(null);
                }

                Player aPlayer = a.GetPlayer();
                Player bPlayer = b.GetPlayer();

                if (!aPlayer.IsOnline || !bPlayer.IsOnline)
                {
                    return(null);
                }

                if (_tradingPlayerIDs.Contains(aPlayer.Id) || _tradingPlayerIDs.Contains(bPlayer.Id))
                {
                    return(null);
                }

                ShipShipTrade t = new ShipShipTrade(a, b, _tradeIDManager.PopFreeID(), DateTime.Now, (int)_slaveIDProvider.SlaveID, TimeKeeper.MsSinceInitialization);
                _shipShipTrades.TryAdd(t.Id, t);
                _tradingPlayerIDs.Add(aPlayer.Id);
                _tradingPlayerIDs.Add(bPlayer.Id);
                _shipIDToTradeID.TryAdd(a.Id, t.Id);
                _shipIDToTradeID.TryAdd(b.Id, t.Id);
                return(t);
            }
        }
예제 #2
0
        async Task <TradeResult> _executeTrade(ShipShipTrade t)
        {
            if (t.IsProcessed || !t.Pending)
            {
                return(TradeResult.TradeAlreadyProcessed);
            }
            t.Pending = false;
            CargoHandler_ReadOnlyVM <CargoHandlerModel> cargoA = t.ShipA.GetCargo();
            CargoHandler_ReadOnlyVM <CargoHandlerModel> cargoB = t.ShipB.GetCargo();


            float holdsAfterTrade_A = cargoA.FilledHolds - t.CargoOffered_A.FilledHolds + t.CargoOffered_B.FilledHolds;
            float holdsAfterTrade_B = cargoB.FilledHolds - t.CargoOffered_B.FilledHolds + t.CargoOffered_A.FilledHolds;

            if (holdsAfterTrade_A > cargoA.TotalHolds)
            {
                t.IsProcessed = true;
                return(TradeResult.ShipANotEnoughCargoSpace);
            }

            if (holdsAfterTrade_B > cargoB.TotalHolds)
            {
                t.IsProcessed = true;
                return(TradeResult.ShipBNotEnoughCargoSpace);
            }


            CargoTransactionSequence ts = new CargoTransactionSequence();

            foreach (var v in t.CargoOffered_A.StatefulCargo)
            {
                ts.Add(new TransactionRemoveStatefulCargo(t.ShipA, StatefulCargoTypes.Null, v.Value.Id, true));
                ts.Add(new TransactionAddStatefulCargo(t.ShipB, null, true));
            }

            foreach (var v in t.CargoOffered_B.StatefulCargo)
            {
                ts.Add(new TransactionRemoveStatefulCargo(t.ShipB, StatefulCargoTypes.Null, v.Value.Id, true));
                ts.Add(new TransactionAddStatefulCargo(t.ShipA, null, true));
            }

            foreach (var v in t.CargoOffered_A.StatelessCargo)
            {
                ts.Add(new TransactionRemoveStatelessCargo(t.ShipA, v.Key, v.Value.Quantity));
                ts.Add(new TransactionAddStatelessCargo(t.ShipB, v.Key, v.Value.Quantity, true));
            }

            foreach (var v in t.CargoOffered_B.StatelessCargo)
            {
                ts.Add(new TransactionRemoveStatelessCargo(t.ShipB, v.Key, v.Value.Quantity));
                ts.Add(new TransactionAddStatelessCargo(t.ShipA, v.Key, v.Value.Quantity, true));
            }

            _cargoSynchronizer.RequestAtomicTransactionSequence(ts);

            var res = await ts.ResultTask;


            if (res == CargoResult.Success)
            {
                t.IsProcessed = true;

                //Record the trade in the DB, fire and forget
                t.DateTime = DateTime.Now;
                _databaseManager.SaveAsync(t);
                _databaseManager.SaveAsync((ISerializable)t.ShipA);
                _databaseManager.SaveAsync((ISerializable)t.ShipB);

                return(TradeResult.Success);
            }
            else
            {
                return(TradeResult.FailedReasonUnknown);//TODO: Implement translator
            }
        }