示例#1
0
        private void HandleOnItemUpdate(Notifications.Nodes.Inventory.OnItemChange change)
        {
            foreach ((PyInteger itemID, PyDictionary _changes) in change.Updates)
            {
                PyDictionary <PyString, PyTuple> changes = _changes.GetEnumerable <PyString, PyTuple>();

                ItemEntity item = this.ItemFactory.LoadItem(itemID, out bool loadRequired);

                // if the item was just loaded there's extra things to take into account
                // as the item might not even need a notification to the character it belongs to
                if (loadRequired == true)
                {
                    // trust that the notification got to the correct node
                    // load the item and check the owner, if it's logged in and the locationID is loaded by us
                    // that means the item should be kept here
                    if (this.ItemFactory.TryGetItem(item.LocationID, out ItemEntity location) == false || this.CharacterManager.IsCharacterConnected(item.OwnerID) == false)
                    {
                        // this item should not be loaded, so unload and return
                        this.ItemFactory.UnloadItem(item);
                        return;
                    }

                    bool locationBelongsToUs = true;

                    switch (location)
                    {
                    case Station _:
                        locationBelongsToUs = this.SystemManager.StationBelongsToUs(location.ID);
                        break;

                    case SolarSystem _:
                        locationBelongsToUs = this.SystemManager.SolarSystemBelongsToUs(location.ID);
                        break;
                    }

                    if (locationBelongsToUs == false)
                    {
                        this.ItemFactory.UnloadItem(item);
                        return;
                    }
                }

                OnItemChange itemChange = new OnItemChange(item);

                // update item and build change notification
                if (changes.TryGetValue("locationID", out PyTuple locationChange) == true)
                {
                    PyInteger oldValue = locationChange[0] as PyInteger;
                    PyInteger newValue = locationChange[1] as PyInteger;

                    itemChange.AddChange(ItemChange.LocationID, oldValue);
                    item.LocationID = newValue;
                }

                if (changes.TryGetValue("quantity", out PyTuple quantityChange) == true)
                {
                    PyInteger oldValue = quantityChange[0] as PyInteger;
                    PyInteger newValue = quantityChange[1] as PyInteger;

                    itemChange.AddChange(ItemChange.Quantity, oldValue);
                    item.Quantity = newValue;
                }

                if (changes.TryGetValue("ownerID", out PyTuple ownerChange) == true)
                {
                    PyInteger oldValue = ownerChange[0] as PyInteger;
                    PyInteger newValue = ownerChange[1] as PyInteger;

                    itemChange.AddChange(ItemChange.OwnerID, oldValue);
                    item.OwnerID = newValue;
                }

                if (changes.TryGetValue("singleton", out PyTuple singletonChange) == true)
                {
                    PyBool oldValue = singletonChange[0] as PyBool;
                    PyBool newValue = singletonChange[1] as PyBool;

                    itemChange.AddChange(ItemChange.Singleton, oldValue);
                    item.Singleton = newValue;
                }

                // TODO: IDEALLY THIS WOULD BE ENQUEUED SO ALL OF THEM ARE SENT AT THE SAME TIME
                // TODO: BUT FOR NOW THIS SHOULD SUFFICE
                // send the notification
                this.NotificationManager.NotifyCharacter(item.OwnerID, "OnMultiEvent",
                                                         new PyTuple(1)
                {
                    [0] = new PyList(1)
                    {
                        [0] = itemChange
                    }
                });

                if (item.LocationID == this.ItemFactory.LocationRecycler.ID)
                {
                    // the item is removed off the database if the new location is the recycler
                    item.Destroy();
                }
                else if (item.LocationID == this.ItemFactory.LocationMarket.ID)
                {
                    // items that are moved to the market can be unloaded
                    this.ItemFactory.UnloadItem(item);
                }
                else
                {
                    // save the item if the new location is not removal
                    item.Persist();
                }
            }
        }
示例#2
0
        public PyDataType UnasembleItems(PyDictionary validIDsByStationID, PyList skipChecks, CallInformation call)
        {
            int characterID = call.Client.EnsureCharacterIsSelected();
            List <RepairDB.ItemRepackageEntry> entries = new List <RepairDB.ItemRepackageEntry>();

            bool ignoreContractVoiding       = false;
            bool ignoreRepackageWithUpgrades = false;

            foreach (PyString check in skipChecks.GetEnumerable <PyString>())
            {
                if (check == "RepairUnassembleVoidsContract")
                {
                    ignoreContractVoiding = true;
                }
                if (check == "ConfirmRepackageSomethingWithUpgrades")
                {
                    ignoreRepackageWithUpgrades = true;
                }
            }

            foreach ((PyInteger stationID, PyList itemIDs) in validIDsByStationID.GetEnumerable <PyInteger, PyList>())
            {
                foreach (PyInteger itemID in itemIDs.GetEnumerable <PyInteger>())
                {
                    RepairDB.ItemRepackageEntry entry = this.RepairDB.GetItemToRepackage(itemID, characterID, stationID);

                    if (entry.HasContract == true && ignoreContractVoiding == false)
                    {
                        throw new RepairUnassembleVoidsContract(itemID);
                    }
                    if (entry.HasUpgrades == true && ignoreRepackageWithUpgrades == false)
                    {
                        throw new ConfirmRepackageSomethingWithUpgrades();
                    }
                    if (entry.Damage != 0.0)
                    {
                        throw new CantRepackageDamagedItem();
                    }

                    entries.Add(entry);
                }
            }

            foreach (RepairDB.ItemRepackageEntry entry in entries)
            {
                if (entry.Singleton == false)
                {
                    continue;
                }

                // extra situation, the repair is happening on a item in our node, the client must know immediately
                if (entry.NodeID == this.Container.NodeID || this.SystemManager.StationBelongsToUs(entry.LocationID) == true)
                {
                    ItemEntity item = this.ItemFactory.LoadItem(entry.ItemID, out bool loadRequired);

                    // the item is an inventory, take everything out!
                    if (item is ItemInventory inventory)
                    {
                        foreach ((int _, ItemEntity itemInInventory) in inventory.Items)
                        {
                            // if the item is in a rig slot, destroy it
                            if (itemInInventory.IsInRigSlot() == true)
                            {
                                Flags oldFlag = itemInInventory.Flag;
                                this.ItemFactory.DestroyItem(itemInInventory);
                                // notify the client about the change
                                call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(itemInInventory, oldFlag, entry.ItemID));
                            }
                            else
                            {
                                Flags oldFlag = itemInInventory.Flag;
                                // update item's location
                                itemInInventory.LocationID = entry.LocationID;
                                itemInInventory.Flag       = Flags.Hangar;

                                // notify the client about the change
                                call.Client.NotifyMultiEvent(OnItemChange.BuildLocationChange(itemInInventory, oldFlag, entry.ItemID));
                                // save the item
                                itemInInventory.Persist();
                            }
                        }
                    }

                    // update the singleton flag too
                    item.Singleton = false;
                    call.Client.NotifyMultiEvent(OnItemChange.BuildSingletonChange(item, true));

                    // load was required, the item is not needed anymore
                    if (loadRequired == true)
                    {
                        this.ItemFactory.UnloadItem(item);
                    }
                }
                else
                {
                    long nodeID = this.SystemManager.GetNodeStationBelongsTo(entry.LocationID);

                    if (nodeID > 0)
                    {
                        Notifications.Nodes.Inventory.OnItemChange change = new Notifications.Nodes.Inventory.OnItemChange();

                        change.AddChange(entry.ItemID, "singleton", true, false);

                        this.NotificationManager.NotifyNode(nodeID, change);
                    }
                }

                // finally repackage the item
                this.RepairDB.RepackageItem(entry.ItemID, entry.LocationID);
                // remove any insurance contract for the ship
                this.InsuranceDB.UnInsureShip(entry.ItemID);
            }

            return(null);
        }