示例#1
0
        /// <summary>
        /// Deserializes an XML loadout text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        public static ILoadoutInfo DeserializeXmlFormat(string text)
        {
            SerializableXmlFittings fittings = Util.DeserializeXmlFromString <SerializableXmlFittings>(text);

            ILoadoutInfo loadoutInfo = new LoadoutInfo();

            // Nothing to evaluate
            if (fittings == null)
            {
                return(loadoutInfo);
            }

            // Retrieve the ship
            loadoutInfo.Ship = StaticItems.GetItemByName(fittings.Fitting.ShipType.Name);

            if (loadoutInfo.Ship == null)
            {
                return(loadoutInfo);
            }

            // Special case to avoid displaying gzCLF block from Osmium
            if (fittings.Fitting.Description.Text.StartsWith("BEGIN gzCLF BLOCK", StringComparison.InvariantCultureIgnoreCase))
            {
                fittings.Fitting.Description.Text = String.Empty;
            }

            Loadout loadout = new Loadout(fittings.Fitting.Name, fittings.Fitting.Description.Text);

            IEnumerable <Item> listOfItems = fittings.Fitting.FittingHardware
                                             .Where(hardware => hardware != null && hardware.Item != null && hardware.Slot != "drone bay")
                                             .Select(hardware => hardware.Item);

            IEnumerable <SerializableXmlFittingHardware> listOfXmlDrones = fittings.Fitting.FittingHardware
                                                                           .Where(hardware => hardware != null &&
                                                                                  hardware.Item != null &&
                                                                                  hardware.Slot == "drone bay");

            var listOfDrones = new List <Item>();

            foreach (SerializableXmlFittingHardware drone in listOfXmlDrones)
            {
                for (int i = 0; i < drone.Quantity; i++)
                {
                    listOfDrones.Add(drone.Item);
                }
            }

            loadout.Items = listOfItems.Concat(listOfDrones);
            loadoutInfo.Loadouts.Add(loadout);

            return(loadoutInfo);
        }
示例#2
0
        /// <summary>
        /// Exports to clipboard.
        /// </summary>
        /// <param name="loadoutInfo">The loadout information.</param>
        /// <param name="loadout">The loadout.</param>
        public static void ExportToClipboard(ILoadoutInfo loadoutInfo, Loadout loadout)
        {
            Dictionary<string, List<string>> items = GetItemsBySlots(loadout.Items);
            ExtractProperties(loadoutInfo, items);
            string exportText = SerializeToEFTFormat(loadoutInfo, loadout, items);

            // Copy to clipboard
            try
            {
                Clipboard.Clear();
                Clipboard.SetText(exportText);
            }
            catch (ExternalException ex)
            {
                // There is a bug that results in an exception being
                // thrown when the clipboard is in use by another process
                ExceptionHandler.LogException(ex, true);
            }
        }
示例#3
0
        /// <summary>
        /// Exports to clipboard.
        /// </summary>
        /// <param name="loadoutInfo">The loadout information.</param>
        /// <param name="loadout">The loadout.</param>
        public static void ExportToClipboard(ILoadoutInfo loadoutInfo, Loadout loadout)
        {
            Dictionary <string, List <string> > items = GetItemsBySlots(loadout.Items);

            ExtractProperties(loadoutInfo, items);
            string exportText = SerializeToEFTFormat(loadoutInfo, loadout, items);

            // Copy to clipboard
            try
            {
                Clipboard.Clear();
                Clipboard.SetText(exportText);
            }
            catch (ExternalException ex)
            {
                // There is a bug that results in an exception being
                // thrown when the clipboard is in use by another process
                ExceptionHandler.LogException(ex, true);
            }
        }
示例#4
0
        /// <summary>
        /// Serializes to EFT format.
        /// </summary>
        /// <param name="loadoutInfo">The loadout information.</param>
        /// <param name="loadout">The loadout.</param>
        /// <param name="items">The items.</param>
        /// <returns></returns>
        private static string SerializeToEFTFormat(ILoadoutInfo loadoutInfo, Loadout loadout,
                                                   IDictionary <string, List <string> > items)
        {
            string name;
            // Build the output format for EFT
            StringBuilder exportText = new StringBuilder();

            exportText.AppendLine($"[{loadoutInfo.Ship.Name}, {loadout.Name} (EVEMon)]");

            // Slots in order: Low, Medium, High, Rig, Subsystem
            foreach (int index in SLOT_ORDER)
            {
                name = LoadoutHelper.OrderedSlotNames[index];
                if (items.ContainsKey(name))
                {
                    // Same function as appending the joined string, but faster
                    foreach (string slotItem in items[name])
                    {
                        exportText.AppendLine(slotItem);
                    }
                    exportText.AppendLine();
                }
            }

            // Drones need quantity
            name = LoadoutHelper.OrderedSlotNames[6];
            if (items.ContainsKey(name))
            {
                foreach (var itemName in items[name].GroupBy(itemName => itemName))
                {
                    exportText.AppendLine($"{itemName.Key} x{itemName.Count()}");
                }
            }

            return(exportText.ToString());
        }
        /// <summary>
        /// Downloads the given loadout.
        /// </summary>
        /// <param name="loadout"></param>
        private void DownloadLoadout(Loadout loadout)
        {
            // Prevent downloading the same loadout
            if (m_selectedLoadout == loadout)
                return;

            if (Settings.LoadoutsProvider.Provider == null)
                return;

            // Reset controls and set the cursor to wait
            btnPlan.Enabled = false;
            lblTrainTime.Visible = false;
            Cursor = Cursors.WaitCursor;
            throbberFitting.State = ThrobberState.Rotating;
            throbberFitting.BringToFront();
            tvLoadout.Nodes.Clear();

            // Store the selected loadout
            m_selectedLoadout = loadout;

            // Set the headings
            lblLoadoutName.Text = m_selectedLoadout.Name;
            lblAuthor.Text = m_selectedLoadout.Author;
            lblSubmitDate.Text = m_selectedLoadout.SubmissionDate.ToString("G");

            // Download the loadout details
            Settings.LoadoutsProvider.Provider.GetLoadoutByIDAsync(m_selectedLoadout.ID);
        }
示例#6
0
        /// <summary>
        /// Serializes to EFT format.
        /// </summary>
        /// <param name="loadoutInfo">The loadout information.</param>
        /// <param name="loadout">The loadout.</param>
        /// <param name="items">The items.</param>
        /// <returns></returns>
        private static string SerializeToEFTFormat(ILoadoutInfo loadoutInfo, Loadout loadout,
                                                   IDictionary <string, List <string> > items)
        {
            // Build the output format for EFT
            StringBuilder exportText = new StringBuilder();

            exportText
            .AppendLine($"[{loadoutInfo.Ship.Name}, {loadout.Name} (EVEMon)]");

            // Low Slots
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[2]))
            {
                exportText
                .AppendLine(String.Join(Environment.NewLine, items[LoadoutHelper.OrderedSlotNames[2]].ToArray()))
                .AppendLine();
            }

            // Medium Slots
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[1]))
            {
                exportText
                .AppendLine(String.Join(Environment.NewLine, items[LoadoutHelper.OrderedSlotNames[1]].ToArray()))
                .AppendLine();
            }

            // High Slots
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[0]))
            {
                exportText
                .AppendLine(String.Join(Environment.NewLine, items[LoadoutHelper.OrderedSlotNames[0]].ToArray()))
                .AppendLine();
            }

            // Rig Slots
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[3]))
            {
                exportText
                .AppendLine(String.Join(Environment.NewLine, items[LoadoutHelper.OrderedSlotNames[3]].ToArray()))
                .AppendLine();
            }

            // Subsystem Slots
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[4]))
            {
                exportText
                .AppendLine(String.Join(Environment.NewLine, items[LoadoutHelper.OrderedSlotNames[4]].ToArray()))
                .AppendLine();
            }

            // Drones
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[6]))
            {
                foreach (IGrouping <string, string> itemName in items[LoadoutHelper.OrderedSlotNames[6]]
                         .GroupBy(itemName => itemName))
                {
                    exportText
                    .AppendLine($"{itemName.Key} x{itemName.Count()}");
                }
            }

            return(exportText.ToString());
        }
示例#7
0
        /// <summary>
        /// Serializes to EFT format.
        /// </summary>
        /// <param name="loadoutInfo">The loadout information.</param>
        /// <param name="loadout">The loadout.</param>
        /// <param name="items">The items.</param>
        /// <returns></returns>
        private static string SerializeToEFTFormat(ILoadoutInfo loadoutInfo, Loadout loadout,
            IDictionary<string, List<string>> items)
        {
            // Build the output format for EFT
            StringBuilder exportText = new StringBuilder();
            exportText
                .AppendLine($"[{loadoutInfo.Ship.Name}, {loadout.Name} (EVEMon)]");

            // Low Slots
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[2]))
            {
                exportText
                    .AppendLine(String.Join(Environment.NewLine, items[LoadoutHelper.OrderedSlotNames[2]].ToArray()))
                    .AppendLine();
            }

            // Medium Slots
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[1]))
            {
                exportText
                    .AppendLine(String.Join(Environment.NewLine, items[LoadoutHelper.OrderedSlotNames[1]].ToArray()))
                    .AppendLine();
            }

            // High Slots
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[0]))
            {
                exportText
                    .AppendLine(String.Join(Environment.NewLine, items[LoadoutHelper.OrderedSlotNames[0]].ToArray()))
                    .AppendLine();
            }

            // Rig Slots
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[3]))
            {
                exportText
                    .AppendLine(String.Join(Environment.NewLine, items[LoadoutHelper.OrderedSlotNames[3]].ToArray()))
                    .AppendLine();
            }

            // Subsystem Slots
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[4]))
            {
                exportText
                    .AppendLine(String.Join(Environment.NewLine, items[LoadoutHelper.OrderedSlotNames[4]].ToArray()))
                    .AppendLine();
            }

            // Drones
            if (items.ContainsKey(LoadoutHelper.OrderedSlotNames[6]))
            {
                foreach (IGrouping<string, string> itemName in items[LoadoutHelper.OrderedSlotNames[6]]
                    .GroupBy(itemName => itemName))
                {
                    exportText
                        .AppendLine($"{itemName.Key} x{itemName.Count()}");
                }
            }

            return exportText.ToString();
        }
示例#8
0
        /// <summary>
        /// Deserializes a DNA loadout text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        public static ILoadoutInfo DeserializeDnaFormat(string text)
        {
            string[] lines = text.Split(":".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            ILoadoutInfo loadoutInfo = new LoadoutInfo();

            // Nothing to evaluate
            if (lines.Length == 0)
            {
                return(loadoutInfo);
            }

            var     listOfItems = new List <Item>();
            Loadout loadout     = null;

            foreach (string line in lines.Where(line => !String.IsNullOrEmpty(line)))
            {
                // Retrieve the ship
                if (line == lines.First())
                {
                    int shipID;
                    if (line.TryParseInv(out shipID))
                    {
                        loadoutInfo.Ship = StaticItems.GetItemByID(shipID);
                        if (loadoutInfo.Ship == null)
                        {
                            return(loadoutInfo);
                        }
                        loadout = new Loadout(loadoutInfo.Ship.Name, String.Empty);
                        continue;
                    }
                }

                // Retrieve the item
                int  itemID;
                Item item = line.Substring(0, line.LastIndexOf(';')).TryParseInv(out itemID) ?
                            (StaticItems.GetItemByID(itemID) ?? Item.UnknownItem) : Item.UnknownItem;

                // Retrieve the quantity
                int quantity;
                line.Substring(line.LastIndexOf(';') + 1).TryParseInv(out quantity);

                // Trim excess ammo & charges, no need to display more than the max number of modules
                if (item.MarketGroup.BelongsIn(DBConstants.AmmosAndChargesMarketGroupID) && quantity > 8)
                {
                    quantity = 1;
                }

                for (int i = 0; i < quantity; i++)
                {
                    listOfItems.Add(item);
                }
            }

            if (loadout == null)
            {
                return(loadoutInfo);
            }

            loadout.Items = listOfItems;
            loadoutInfo.Loadouts.Add(loadout);

            return(loadoutInfo);
        }
示例#9
0
        /// <summary>
        /// Deserializes a CLF loadout text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        public static ILoadoutInfo DeserializeClfFormat(string text)
        {
            ILoadoutInfo loadoutInfo = new LoadoutInfo();

            // Nothing to evaluate
            if (text.Length == 0)
                return loadoutInfo;

            SerializableClfFitting clfFitting = Util.DeserializeJson<SerializableClfFitting>(text);

            // Nothing to evaluate
            if (clfFitting == null)
                return loadoutInfo;

            // Retrieve the ship
            loadoutInfo.Ship = clfFitting.Ship.Item;

            if (loadoutInfo.Ship == null)
                return loadoutInfo;

            Loadout loadout = new Loadout(clfFitting.MetaData.Title, clfFitting.MetaData.Description);

            IEnumerable<Item> listOfItems = clfFitting.Presets.SelectMany(x => x.Modules)
                .Where(module => module != null && module.Item != null)
                .Select(module => module.Item);

            IEnumerable<Item> listOfCharges = clfFitting.Presets.SelectMany(x => x.Modules)
                .SelectMany(module => module.Charges)
                .Where(module => module != null && module.Item != null)
                .Select(module => module.Item);

            IEnumerable<SerializableClfFittingDroneType> listOfClfDrones = clfFitting.Drones.SelectMany(x => x.InBay)
                .Concat(clfFitting.Drones.SelectMany(x => x.InSpace))
                .Where(drone => drone != null && drone.Item != null)
                .Select(drone => drone);

            var listOfDrones = new List<Item>();
            foreach (SerializableClfFittingDroneType clfDrone in listOfClfDrones)
            {
                for (int i = 0; i < clfDrone.Quantity; i++)
                {
                    listOfDrones.Add(clfDrone.Item);
                }
            }

            loadout.Items = listOfItems.Concat(listOfCharges).Concat(listOfDrones);
            loadoutInfo.Loadouts.Add(loadout);

            return loadoutInfo;
        }
示例#10
0
        /// <summary>
        /// Deserializes an EFT loadout text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">text</exception>
        public static ILoadoutInfo DeserializeEftFormat(string text)
        {
            text.ThrowIfNull(nameof(text));

            string[] lines = text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            ILoadoutInfo loadoutInfo = new LoadoutInfo();

            // Nothing to evaluate
            if (lines.Length == 0)
            {
                return(loadoutInfo);
            }

            var     listOfItems = new List <Item>();
            Loadout loadout     = null;

            foreach (string line in lines.Where(line => !String.IsNullOrEmpty(line) &&
                                                !line.Contains("empty") && !line.Contains("slot")))
            {
                // Retrieve the ship
                if (line == lines.First())
                {
                    // Retrieve the loadout name
                    int commaIndex = line.IndexOf(',');
                    loadoutInfo.Ship = StaticItems.GetItemByName(line.Substring(1,
                                                                                commaIndex - 1));
                    if (loadoutInfo.Ship == null)
                    {
                        return(loadoutInfo);
                    }
                    loadout = new Loadout(line.Substring(commaIndex + 1, line.Length -
                                                         commaIndex - 2).Trim(), String.Empty);
                    continue;
                }

                // Retrieve the item (might be a drone)
                int    lastX     = line.LastIndexOf(" x", StringComparison.CurrentCulture);
                int    lastComma = line.LastIndexOf(',');
                string itemName  = lastComma >= 0 ? line.Substring(0, lastComma) : (lastX >= 0 ?
                                                                                    line.Substring(0, lastX) : line);

                int quantity = lastX >= 0 ? int.Parse(line.Substring(lastX + 2, line.Length -
                                                                     (lastX + 2))) : 1;

                Item item = StaticItems.GetItemByName(itemName) ?? Item.UnknownItem;

                for (int i = 0; i < quantity; i++)
                {
                    listOfItems.Add(item);
                }

                // Retrieve the charge
                string chargeName = lastComma >= 0 ? line.Substring(lastComma + 1).Trim() :
                                    null;

                if (String.IsNullOrEmpty(chargeName))
                {
                    continue;
                }

                Item charge = StaticItems.GetItemByName(chargeName) ?? Item.UnknownItem;

                listOfItems.Add(charge);
            }

            if (loadout == null)
            {
                return(loadoutInfo);
            }

            loadout.Items = listOfItems;
            loadoutInfo.Loadouts.Add(loadout);

            return(loadoutInfo);
        }
示例#11
0
        /// <summary>
        /// Deserializes a DNA loadout text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        public static ILoadoutInfo DeserializeDnaFormat(string text)
        {
            string[] lines = text.Split(":".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            ILoadoutInfo loadoutInfo = new LoadoutInfo();

            // Nothing to evaluate
            if (lines.Length == 0)
                return loadoutInfo;

            var listOfItems = new List<Item>();
            Loadout loadout = null;

            foreach (string line in lines.Where(line => !String.IsNullOrEmpty(line)))
            {
                // Retrieve the ship
                if (line == lines.First())
                {
                    int shipID = Int32.Parse(line, CultureConstants.InvariantCulture);
                    loadoutInfo.Ship = StaticItems.GetItemByID(shipID);

                    if (loadoutInfo.Ship == null)
                        return loadoutInfo;

                    loadout = new Loadout(loadoutInfo.Ship.Name, String.Empty);

                    continue;
                }

                // Retrieve the item
                int itemID;
                Item item = Int32.TryParse(line.Substring(0, line.LastIndexOf(';')), out itemID)
                    ? StaticItems.GetItemByID(itemID) ?? Item.UnknownItem
                    : Item.UnknownItem;

                // Retrieve the quantity
                int quantity = Int32.Parse(line.Substring(line.LastIndexOf(';') + 1), CultureConstants.InvariantCulture);

                // Trim excess ammo & charges, no need to display more than the max number of modules
                if (item.MarketGroup.BelongsIn(DBConstants.AmmosAndChargesMarketGroupID) && quantity > 8)
                    quantity = 1;

                for (int i = 0; i < quantity; i++)
                {
                    listOfItems.Add(item);
                }
            }

            if (loadout == null)
                return loadoutInfo;

            loadout.Items = listOfItems;
            loadoutInfo.Loadouts.Add(loadout);

            return loadoutInfo;
        }
示例#12
0
        /// <summary>
        /// Deserializes an XML loadout text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        public static ILoadoutInfo DeserializeXmlFormat(string text)
        {
            SerializableXmlFittings fittings = Util.DeserializeXmlFromString<SerializableXmlFittings>(text);

            ILoadoutInfo loadoutInfo = new LoadoutInfo();

            // Nothing to evaluate
            if (fittings == null)
                return loadoutInfo;

            // Retrieve the ship
            loadoutInfo.Ship = StaticItems.GetItemByName(fittings.Fitting.ShipType.Name);

            if (loadoutInfo.Ship == null)
                return loadoutInfo;

            // Special case to avoid displaying gzCLF block from Osmium
            if (fittings.Fitting.Description.Text.StartsWith("BEGIN gzCLF BLOCK", StringComparison.InvariantCultureIgnoreCase))
                fittings.Fitting.Description.Text = String.Empty;

            Loadout loadout = new Loadout(fittings.Fitting.Name, fittings.Fitting.Description.Text);

            IEnumerable<Item> listOfItems = fittings.Fitting.FittingHardware
                .Where(hardware => hardware != null && hardware.Item != null && hardware.Slot != "drone bay")
                .Select(hardware => hardware.Item);

            IEnumerable<SerializableXmlFittingHardware> listOfXmlDrones = fittings.Fitting.FittingHardware
                .Where(hardware => hardware != null &&
                                   hardware.Item != null &&
                                   hardware.Slot == "drone bay");

            var listOfDrones = new List<Item>();
            foreach (SerializableXmlFittingHardware drone in listOfXmlDrones)
            {
                for (int i = 0; i < drone.Quantity; i++)
                {
                    listOfDrones.Add(drone.Item);
                }
            }

            loadout.Items = listOfItems.Concat(listOfDrones);
            loadoutInfo.Loadouts.Add(loadout);

            return loadoutInfo;
        }
示例#13
0
        /// <summary>
        /// Deserializes an EFT loadout text.
        /// </summary>
        /// <param name="text">The text.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">text</exception>
        public static ILoadoutInfo DeserializeEftFormat(string text)
        {
            text.ThrowIfNull(nameof(text));

            string[] lines = text.Split(Environment.NewLine.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

            ILoadoutInfo loadoutInfo = new LoadoutInfo();

            // Nothing to evaluate
            if (lines.Length == 0)
                return loadoutInfo;

            var listOfItems = new List<Item>();
            Loadout loadout = null;

            foreach (
                string line in
                    lines.Where(line => !String.IsNullOrEmpty(line) && !line.Contains("empty") && !line.Contains("slot")))
            {
                // Retrieve the ship
                if (line == lines.First())
                {
                    // Retrieve the loadout name
                    int commaIndex = line.IndexOf(',');
                    loadoutInfo.Ship = StaticItems.GetItemByName(line.Substring(1, commaIndex - 1));

                    if (loadoutInfo.Ship == null)
                        return loadoutInfo;

                    loadout = new Loadout(line.Substring(commaIndex + 1, line.Length - commaIndex - 2).Trim(), String.Empty);

                    continue;
                }

                // Retrieve the item (might be a drone)
                string itemName = line.Contains(",")
                    ? line.Substring(0, line.LastIndexOf(','))
                    : line.Contains(" x")
                        ? line.Substring(0, line.LastIndexOf(" x", StringComparison.CurrentCulture))
                        : line;

                int quantity = line.Contains(" x")
                    ? Int32.Parse(line.Substring(line.LastIndexOf(" x", StringComparison.CurrentCulture) + 2,
                        line.Length - (line.LastIndexOf(" x", StringComparison.CurrentCulture) + 2)))
                    : 1;

                Item item = StaticItems.GetItemByName(itemName) ?? Item.UnknownItem;

                for (int i = 0; i < quantity; i++)
                {
                    listOfItems.Add(item);
                }

                // Retrieve the charge
                string chargeName = line.Contains(",") ? line.Substring(line.LastIndexOf(',') + 2) : null;

                if (String.IsNullOrEmpty(chargeName))
                    continue;

                Item charge = StaticItems.GetItemByName(chargeName) ?? Item.UnknownItem;

                listOfItems.Add(charge);
            }

            if (loadout == null)
                return loadoutInfo;

            loadout.Items = listOfItems;
            loadoutInfo.Loadouts.Add(loadout);

            return loadoutInfo;
        }
示例#14
0
        /// <summary>
        /// Deserializes the loadout.
        /// </summary>
        /// <param name="loadout">The loadout.</param>
        /// <param name="feed">The feed.</param>
        /// <exception cref="System.ArgumentNullException">
        /// loadout
        /// or
        /// feed
        /// </exception>
        public override void DeserializeLoadout(Loadout loadout, object feed)
        {
            loadout.ThrowIfNull(nameof(loadout));

            feed.ThrowIfNull(nameof(feed));

            loadout.Items = LoadoutHelper.DeserializeEftFormat(feed as string).Loadouts.First().Items;
        }
示例#15
0
 /// <summary>
 /// Deserializes the loadout.
 /// </summary>
 /// <param name="loadout">The loadout.</param>
 /// <param name="feed">The feed.</param>
 public abstract void DeserializeLoadout(Loadout loadout, object feed);