csharp/ACEmulator/ACE/Source/ACE.Server/Factories/Entity/LootSwap.cs

LootSwap.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;

using ACE.Server.Factories.Enum;

namespace ACE.Server.Factories.Ensaty
{
    public static clast LootSwap
    {
        public static void UpdateTables(string path)
        {
            var timer = Stopwatch.StartNew();

            var types = Reflection.GetTypes("ACE.Server.Factories.Tables");

            var files = new Dictionary();

            ParseFolder(path, files);

            UpdateTables(types, files);

            timer.Stop();

            // ~0.2s
            Console.WriteLine();
            Console.WriteLine($"Updated loot tables in {timer.Elapsed.TotalSeconds}s");
            Console.WriteLine();
        }

        private static HashSet excludeList = new HashSet()
        {
            "GemMaterialChance.cs",         // todo
            "TreasureItemTypeChances.cs"
        };

        private static void ParseFolder(string folder, Dictionary files)
        {
            var di = new DirectoryInfo(folder);

            if (!di.Exists)
            {
                Console.WriteLine($"{folder} not found");
                return;
            }

            var _files = di.GetFiles();

            foreach (var file in _files)
            {
                if (!file.Name.EndsWith(".cs"))
                    continue;

                if (excludeList.Contains(file.Name))
                    continue;

                var clastName = file.Name.Replace(".cs", "");
                var result = LootParser.ParseFile(file.FullName);
                files.Add(clastName, result);
            }

            var subfolders = di.GetDirectories();

            foreach (var subfolder in subfolders)
                ParseFolder(subfolder.FullName, files);
        }

        private static void UpdateTables(Dictionary types, Dictionary files)
        {
            foreach (var kvp in types)
            {
                var clastName = kvp.Key;
                var type = kvp.Value;

                if (!files.TryGetValue(clastName, out var newTables))
                {
                    //Console.WriteLine($"Couldn't find {clastName} in files");
                    continue;
                }

                var fields = Reflection.GetFields(type);

                Console.WriteLine($"Updated {clastName}");

                foreach (var field in fields)
                {
                    if (!newTables.TryGetValue(field.field.Name, out var newTable))
                    {
                        //Console.WriteLine($"Couldn't find {field.field.Name} in {clastName}.cs");
                        continue;
                    }
                    //Console.WriteLine($" - {field.field.Name}");
                    UpdateTable(field.field, newTable);
                }
            }
        }

        private static void UpdateTable(FieldInfo field, object newTable)
        {
            //Console.WriteLine($"Updating {field.Name}");

            field.SetValue(null, newTable);
        }

        public static clast Reflection
        {
            public static Dictionary GetTypes(string prefix)
            {
                var astembly = astembly.GetExecutingastembly();

                var types = astembly.GetTypes();

                return types.Where(i => i.FullName.StartsWith(prefix)).ToDictionary(i => i.FullName.Substring(i.FullName.LastIndexOf('.') + 1), i => i);
            }

            public static List GetFields(Type type)
            {
                var fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Static);

                var filtered = new List();

                foreach (var field in fields)
                {
                    var fieldName = field.FieldType.FullName;

                    if (!fieldName.Contains("ChanceTable"))
                        continue;

                    if (fieldName.Contains("System.Collections.Generic.List"))
                        continue;

                    if (fieldName.Contains("System.Int32"))
                        filtered.Add((TreasureTableType.ChanceInt, field));
                    else if (fieldName.Contains("SpellId"))
                        filtered.Add((TreasureTableType.ChanceSpell, field));
                    else if (fieldName.Contains("WeenieClastName"))
                        filtered.Add((TreasureTableType.ChanceWcid, field));
                    else if (fieldName.Contains("Boolean"))
                        filtered.Add((TreasureTableType.ChanceBool, field));
                    else if (fieldName.Contains("TreasureItemType_Orig"))
                        filtered.Add((TreasureTableType.ChanceItemType, field));
                    else if (fieldName.Contains("TreasureHeritageGroup"))
                        filtered.Add((TreasureTableType.ChanceHeritage, field));
                    else if (fieldName.Contains("TreasureArmorType"))
                        filtered.Add((TreasureTableType.ChanceArmorType, field));
                    else if (fieldName.Contains("TreasureWeaponType"))
                        filtered.Add((TreasureTableType.ChanceWeaponType, field));
                }
                return filtered;
            }
        }
    }
}