示例#1
0
 public Contract(long ownerID, short statusID)
 {
     _ownerID = ownerID;
     _statusID = statusID;
     _pickupStationID = 0;
     _destinationStationID = 0;
     _collateral = 0;
     _reward = 0;
     _expectedProfit = 0;
     _totalVolume = 0;
     _issueDate = DateTime.Now;
     _items = new ContractItemList();
     _type = ContractType.Courier;
 }
示例#2
0
 public Contract(long ownerID, short statusID, long pickupStationID, long destinationStationID,
     decimal collateral, decimal reward, decimal expectedProfit, DateTime issueDate, ContractItemList items,
     ContractType type)
 {
     _ownerID = ownerID;
     _statusID = statusID;
     _pickupStationID = pickupStationID;
     _destinationStationID = destinationStationID;
     _collateral = collateral;
     _reward = reward;
     _expectedProfit = expectedProfit;
     _issueDate = issueDate;
     _items = items;
     _type = type;
 }
 public static ContractItemList GetContractItems(Contract contract)
 {
     ContractItemList retVal = new ContractItemList();
     EMMADataSet.ContractItemDataTable table = new EMMADataSet.ContractItemDataTable();
     contractItemsTableAdapter.FillByContractID(table, contract.ID);
     foreach (EMMADataSet.ContractItemRow item in table)
     {
         retVal.Add(new ContractItem(item, contract));
     }
     return retVal;
 }
        public ContractList GenerateContracts(long ownerID, long pickupStation, long destinationStation, bool autoCon)
        {
            ContractList retVal = new ContractList();
            ContractItemList items = new ContractItemList();
            Dictionary<int, long> assetsUsed = new Dictionary<int, long>();
            decimal totVolume = 0, totCollateral = 0, totProfit = 0;
            ReportGroupSettings settings = UserAccount.CurrentGroup.Settings;
            decimal maxVolume = settings.AutoCon_MaxVolume;
            decimal maxCollateral = settings.AutoCon_MaxCollateral;
            bool allowStackSpliting = settings.AutoCon_AllowStackSplitting;
            string collateralBasedOn = settings.CollateralBasedOn;
            decimal collateralPerc = settings.CollateralPercentage;
            string rewardBasedOn = settings.RewardBasedOn;
            decimal minReward = settings.MinReward;
            decimal minRewardPerc = settings.MinRewardPercentage;
            decimal minAllowedCollateral = settings.AutoCon_MinCollateral;
            decimal minAllowedReward = settings.AutoCon_MinReward;
            decimal minAllowedVolume = settings.AutoCon_MinVolume;
            decimal maxReward = settings.MaxReward;
            decimal maxRewardPerc = settings.MaxRewardPercentage;
            decimal lowSecRewardBonus = settings.LowSecPickupBonusPerc;
            decimal rewardPerJump = settings.RewardPercPerJump;
            decimal rewardPerVol = settings.VolumeBasedRewardPerc;
            decimal flatRewardPerJump = settings.RewardPerJump;
            decimal flatRewardPerVol = settings.RewardPerVolume;
            decimal baseReward = settings.PickupReward;

            EveDataSet.mapSolarSystemsRow pickupSystemData = SolarSystems.GetSystem(
                Stations.GetStation(pickupStation).solarSystemID);

            int diag_contracts = 0;

            //bool corp = false;
            bool complete = true;
            bool relax = false;
            //APICharacter character = UserAccount.CurrentGroup.GetCharacter(ownerID, ref corp);
            // Get the list of assets available for auto-contracting at this station.
            Diagnostics.StartTimer("GenerateContract");
            Diagnostics.StartTimer("GenerateContract.Part1");
            EMMADataSet.AssetsDataTable assets = Assets.GetAutoConAssets(
                ownerID, pickupStation, true);
            Diagnostics.StopTimer("GenerateContract.Part1");
            int lastAssetCount = -1;

            // Had to remove this condition.
            // Consider the case where 9 mil units of trit are sat at a station.
            // Max volume limit is set to 30k m3 so the autocontractor wants to create
            // 3 contracts for 3 mil units each.
            // However, this condition will cause the system to drop into the infinite loop
            // diagnostics after the first contract.
            while (assets.Count > 0) // && lastAssetCount != assets.Count)
            {
                complete = true;
                relax = false;
                totVolume = 0;
                totProfit = 0;
                totCollateral = 0;
                assetsUsed = new Dictionary<int, long>();
                items = new ContractItemList();
                Contract contract = new Contract(ownerID, 5, pickupStation, destinationStation, 0,
                    0, 0, DateTime.UtcNow, new ContractItemList(), ContractType.Courier);
                lastAssetCount = assets.Count;

                foreach (EMMADataSet.AssetsRow asset in assets)
                {
                    decimal buyPrice = 0, sellPrice = 0, unitCollateral = 0;
                    int itemID = asset.ItemID;
                    decimal itemVolume = (decimal)Items.GetItemVolume(itemID);
                    long quantity = asset.Quantity;

                    // Check if we can use the full volume of these items without breaching the max volume
                    // limit.
                    if (autoCon && totVolume + (decimal)(quantity * itemVolume) > maxVolume &&
                        totVolume < maxVolume)
                    {
                        // Reduce the quantity of items being addded if they would exceed the
                        // volume limit
                        quantity = (int)Math.Round((maxVolume - totVolume) / (decimal)itemVolume,
                            0, MidpointRounding.AwayFromZero) - 1;
                        // This check will prevent infinite loops when the volume of a single item is greater
                        // than the max allowed contract volume.
                        if (maxVolume < itemVolume && totVolume == 0) { relax = true; quantity = 1; }
                        complete = false;
                    }
                    else if (totVolume >= maxVolume) { complete = false; }

                    Diagnostics.StartTimer("GenerateContract.Part2");
                    // Get estimated sell price for the items being added to the contract.
                    sellPrice = GetSellPrice(itemID, destinationStation);
                    Diagnostics.StopTimer("GenerateContract.Part2");
                    Diagnostics.StartTimer("GenerateContract.Part6");
                    // Get average buy price for the items being added to the contract.
                    buyPrice = GetBuyPrice(ownerID, itemID, pickupStation, quantity, asset.Quantity - quantity);
                    Diagnostics.StopTimer("GenerateContract.Part6");
                    Diagnostics.StartTimer("GenerateContract.Part3");
                    // calculate the collateral value of the items being added.
                    unitCollateral = CalcCollateral(collateralBasedOn, collateralPerc, buyPrice, sellPrice);

                    long lastQuantity = quantity;
                    while (autoCon && totCollateral + (unitCollateral * quantity) > maxCollateral && !relax &&
                        totCollateral < maxCollateral)
                    {
                        // Reduce the quantity of items being addded if they would exceed the
                        // collateral limit
                        quantity = (int)Math.Round((maxCollateral - totCollateral) / (decimal)unitCollateral,
                            MidpointRounding.AwayFromZero) - 1;
                        // This check will prevent infinite loops when the collateral for a single item is greater
                        // than the max allowed collateral.
                        if (maxCollateral < unitCollateral && totCollateral == 0) { relax = true; quantity = 1; }
                        complete = false;

                        // Catch a possible infinite loop.
                        if (lastQuantity == quantity) { relax = true; quantity = 1; }

                        lastQuantity = quantity;
                        // Recalculate buy price and collateral.
                        //buyPrice = GetBuyPrice(ownerID, itemID, pickupStation, quantity, asset.Quantity - quantity);
                        //unitCollateral = CalcCollateral(collateralBasedOn, collateralPerc, buyPrice, sellPrice);
                    }
                    if (totCollateral >= maxCollateral) { complete = false; }
                    Diagnostics.StopTimer("GenerateContract.Part3");

                    if ((quantity == asset.Quantity || allowStackSpliting || relax) && quantity > 0)
                    {
                        // Get up the values for the items being added and add them to the contract totals.
                        totVolume += (decimal)(quantity * itemVolume);
                        totCollateral += quantity * unitCollateral;
                        totProfit += quantity * sellPrice - quantity * buyPrice;
                        if (assetsUsed.ContainsKey(itemID))
                        {
                            // If we've already added an item with this id then just add the new quantity
                            // to the old contract item object...
                            assetsUsed[itemID] += quantity;
                            for (int i = 0; i < items.Count;i++ )
                            {
                                ContractItem itemData = items[i];
                                if (itemData.ItemID == itemID)
                                {
                                    itemData.Quantity += (int)quantity;
                                    i = items.Count;
                                }
                            }
                        }
                        else
                        {
                            // ...Otherwise create a new contract item and add it to the list.
                            assetsUsed.Add(itemID, quantity);
                            items.Add(new ContractItem(itemID, (int)quantity, sellPrice, buyPrice, contract));
                        }
                    }
                }

                Diagnostics.StartTimer("GenerateContract.Part4");
                // Get the distance between the pickup and destination stations
                int numJumps = SolarSystemDistances.GetDistanceBetweenStations(pickupStation, destinationStation);
                Diagnostics.StopTimer("GenerateContract.Part4");
                // Calculate the reward that will be given from completing the contract.
                decimal reward = CalcReward(rewardBasedOn, totCollateral, totProfit, minReward, maxReward,
                    minRewardPerc, maxRewardPerc, rewardPerJump, rewardPerVol, lowSecRewardBonus,
                    numJumps, totVolume, Stations.IsLowSec(pickupStation), flatRewardPerJump, flatRewardPerVol,
                    baseReward);

                contract.Items = items;
                contract.Reward = reward;
                contract.Collateral = totCollateral;
                contract.ExpectedProfit = totProfit;
                diag_contracts++;
                // Add the contract to the list
                if (!autoCon || (reward > minAllowedReward && totCollateral > minAllowedCollateral &&
                    totVolume > minAllowedVolume))
                {
                    retVal.Add(contract);
                }
                //else
                //{
                //    UpdateStatus(0, 0, "",
                //        "A contract (" + diag_contracts +  ") has been generated that does not meet the minimum " +
                //        "requirements." +
                //        (reward <= minAllowedReward ? " The reward (" + reward + ") is less than " +
                //        minAllowedReward + "." : "") +
                //        (totCollateral <= minAllowedCollateral ? " The collateral (" + totCollateral +
                //        ") is less than " + minAllowedCollateral + "." : "") +
                //        (totVolume <= minAllowedVolume ? " The volume (" + totVolume + ") is less than " +
                //        minAllowedVolume + "." : ""),
                //        false);
                //}

                Diagnostics.StartTimer("GenerateContract.Part5");
                if (!complete)
                {
                    // If we have not used all items at this location then
                    // remove the items  we have used from the list of current assets.
                    Dictionary<int, long>.Enumerator enumerator = assetsUsed.GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        DataRow[] rows = assets.Select("ItemID = " + enumerator.Current.Key);
                        if (rows.Length > 0)
                        {
                            long q_remain = enumerator.Current.Value;
                            for (int i = 0; i < rows.Length; i++)
                            {
                                if (q_remain > 0)
                                {
                                    EMMADataSet.AssetsRow assetData = rows[i] as EMMADataSet.AssetsRow;
                                    long diff = q_remain - assetData.Quantity;
                                    if (diff >= 0)
                                    {
                                        q_remain -= assetData.Quantity;
                                        assets.RemoveAssetsRow(assetData);
                                    }
                                    else
                                    {
                                        assetData.Quantity -= (int)q_remain;
                                        q_remain = 0;
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    // otherwise, just clear the list of assets.
                    assets.Clear();
                }
                Diagnostics.StopTimer("GenerateContract.Part5");
            }

            #region Diagnostic dump if we've caught an infinite loop.
            if (assets.Count != 0)
            {
                UpdateStatus(0, 0, "Error: Infinite loop detected",
                    "Please send your 'logging/exceptionlog.txt' file to [email protected]. " +
                    "Warning, this file will contain information about your in-game assets.", true);
                StringBuilder errorText = new StringBuilder(
                    "Infinite loop detected during auto-contrator execution, diagnostics to follow:");
                errorText.Append("\r\n\t");
                errorText.Append("Assets Remaining:");
                foreach (EMMADataSet.AssetsRow asset in assets)
                {
                    errorText.Append("\r\n\t\t");
                    errorText.Append(Items.GetItemName(asset.ItemID).Replace(",", " "));
                    errorText.Append(",");
                    errorText.Append(asset.Quantity);
                    errorText.Append(",");
                    errorText.Append(Items.GetItemVolume(asset.ItemID));
                }
                errorText.Append("\r\n\t");
                errorText.Append("Contracts created:");
                if (retVal.Count == 0) { errorText.Append("\r\n\t\t"); errorText.Append("NONE"); }
                foreach (Contract contract in retVal)
                {
                    errorText.Append("\r\n\t\t");
                    errorText.Append("ID: ");
                    errorText.Append(contract.ID);
                    errorText.Append("\r\n\t\t\t");
                    errorText.Append("Collateral: ");
                    errorText.Append(contract.Collateral);
                    errorText.Append("\r\n\t\t\t");
                    errorText.Append("Reward: ");
                    errorText.Append(contract.Reward);
                    errorText.Append("\r\n\t\t\t");
                    errorText.Append("Total Volume: ");
                    errorText.Append(contract.TotalVolume);
                    errorText.Append("\r\n\t\t\t");
                    errorText.Append("Profit: ");
                    errorText.Append(contract.ExpectedProfit);
                    errorText.Append("\r\n\t\t\t");
                    errorText.Append("Contract Items:");
                    foreach (ContractItem item in contract.Items)
                    {
                        errorText.Append("\r\n\t\t\t\t");
                        errorText.Append(item.Item);
                        errorText.Append(",");
                        errorText.Append(item.Quantity);
                        errorText.Append(",");
                        errorText.Append(item.ItemVolume);
                    }
                }
                errorText.Append("\r\n\t");
                errorText.Append("Max Volume: ");
                errorText.Append(maxVolume);
                errorText.Append("\r\n\t");
                errorText.Append("Max Collateral: ");
                errorText.Append(maxCollateral);
                errorText.Append("\r\n\t");
                errorText.Append("Max Reward: ");
                errorText.Append(maxReward);
                errorText.Append("\r\n\t");
                errorText.Append("Max Reward Percentage: ");
                errorText.Append(maxRewardPerc);
                errorText.Append("\r\n\t");
                errorText.Append("Min Allowed Collateral: ");
                errorText.Append(minAllowedCollateral);
                errorText.Append("\r\n\t");
                errorText.Append("Min Allowed Reward: ");
                errorText.Append(minAllowedReward);
                errorText.Append("\r\n\t");
                errorText.Append("Min Allowed Volume: ");
                errorText.Append(minAllowedVolume);
                errorText.Append("\r\n\t");
                errorText.Append("Min Reward: ");
                errorText.Append(minReward);
                errorText.Append("\r\n\t");
                errorText.Append("Min Reward Percentage: ");
                errorText.Append(minRewardPerc);
                errorText.Append("\r\n\t");
                errorText.Append("Allow stack splitting: ");
                errorText.Append(allowStackSpliting);

                throw new EMMAException(ExceptionSeverity.Error, errorText.ToString());
            }
            #endregion

            DiagnosticUpdate("", "Complete time: " + Diagnostics.GetRunningTime("GenerateContract").ToString());
            DiagnosticUpdate("", "Time loading assets: " +
                Diagnostics.GetRunningTime("GenerateContract.Part1").ToString());
            DiagnosticUpdate("", "Get item sell prices: " +
                Diagnostics.GetRunningTime("GenerateContract.Part2").ToString());
            DiagnosticUpdate("", "Get item buy prices: " +
                Diagnostics.GetRunningTime("GenerateContract.Part6").ToString());
            DiagnosticUpdate("", "Calc and restrict collateral: " +
                Diagnostics.GetRunningTime("GenerateContract.Part3").ToString());
            DiagnosticUpdate("", "Get route length: " +
                Diagnostics.GetRunningTime("GenerateContract.Part4").ToString());
            DiagnosticUpdate("", "Remove used assets: " +
                Diagnostics.GetRunningTime("GenerateContract.Part5").ToString());
            DiagnosticUpdate("", "Total contracts generated: " + diag_contracts);

            return retVal;
            }