public static EncounterLayer_MDD InsertOrUpdateEncounterLayer(this MetadataDatabase mdd, EncounterLayer encounterLayer)
 {
     mdd.Execute("INSERT OR REPLACE INTO EncounterLayer (EncounterLayerID, MapID, Name, FriendlyName, Description, BattleValue, ContractTypeID, EncounterLayerGUID, TagSetID, IncludeInBuild) values(@EncounterLayerID, @MapID, @Name, @FriendlyName, @Description, @BattleValue, @ContractTypeID, @EncounterLayerGUID, @TagSetID, @IncludeInBuild)", new {
         EncounterLayerID   = encounterLayer.EncounterLayerId,
         MapID              = encounterLayer.MapId,
         Name               = encounterLayer.Name,
         FriendlyName       = encounterLayer.FriendlyName,
         Description        = encounterLayer.Description,
         BattleValue        = encounterLayer.BattleValue,
         ContractTypeID     = encounterLayer.ContractTypeId,
         EncounterLayerGUID = encounterLayer.EncounterLayerGuid,
         TagSetID           = encounterLayer.TagSetId,
         IncludeInBuild     = encounterLayer.IncludeInBuild
     }, null, null, null);
     return(mdd.SelectEncounterLayerByID(encounterLayer.EncounterLayerId));
 }
Пример #2
0
        private static int CreateMetadata(bool Update = false)
        {
            ConsoleColor c = Console.ForegroundColor;

            try
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Connecting to " + ConnectionString);
                SqlMetadataDatabase db = SqlMetadataDatabase.FromConnection(ConnectionString, Update, File.Exists(OutputFile) ? OutputFile : null);
                Console.WriteLine("{0} metadata for {1} tables and views...", Update ? "Updating" : "Building", Tables == null ? "all" : Tables.Length.ToString());
                if (Update)
                {
                    db.FileName = OutputFile;
                }
                db.MetadataUpdateEvent += db_MetadataUpdateEvent;
                if (Update && !File.Exists(OutputFile))
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("'Update' was specified but the file {0} does not exist. 'Create' will be used in stead", OutputFile);
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Update      = false;
                    db.FileName = null;
                }
                MetadataDatabase mdb = db.BuildMetadata(true, Tables, Update);
                Console.WriteLine("Done. Metadata contains {0} tables", mdb.Tables.Count);
                Console.WriteLine("Saving metadata in the file {0}", OutputFile);
                ClassCreationOptions.MetadataEvent = new MetadataUpdateDelegate(db_MetadataUpdateEvent);
                ClassGenerator.CreateClasses(mdb);
                mdb.ToFile(OutputFile);
                return(0);
            }
            catch (Exception ex)
            {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(ex.Message);
                return(1);
            }
            finally
            {
                Console.ForegroundColor = c;
                if (PromptUser)
                {
                    Console.Write("Finished. Press any key to exit");
                    Console.ReadKey(true);
                }
            }
        }
Пример #3
0
        private static bool AddModEntryToDB(MetadataDatabase db, string absolutePath, string typeStr)
        {
            if (Path.GetExtension(absolutePath)?.ToLower() != ".json")
            {
                return(false);
            }

            var type         = (BattleTechResourceType)Enum.Parse(typeof(BattleTechResourceType), typeStr);
            var relativePath = GetRelativePath(absolutePath, GameDirectory);

            switch (type) // switch is to avoid poisoning the output_log.txt with known types that don't use MDD
            {
            case BattleTechResourceType.TurretDef:
            case BattleTechResourceType.UpgradeDef:
            case BattleTechResourceType.VehicleDef:
            case BattleTechResourceType.ContractOverride:
            case BattleTechResourceType.SimGameEventDef:
            case BattleTechResourceType.LanceDef:
            case BattleTechResourceType.MechDef:
            case BattleTechResourceType.PilotDef:
            case BattleTechResourceType.WeaponDef:
                var writeTime = File.GetLastWriteTimeUtc(absolutePath);
                if (!dbCache.ContainsKey(relativePath) || dbCache[relativePath] != writeTime)
                {
                    try
                    {
                        VersionManifestHotReload.InstantiateResourceAndUpdateMDDB(type, absolutePath, db);
                        dbCache[relativePath] = writeTime;
                        return(true);
                    }
                    catch (Exception e)
                    {
                        Log($"\tAdd to DB failed for {Path.GetFileName(absolutePath)}, exception caught:");
                        Log($"\t\t{e.Message}");
                        return(false);
                    }
                }
                break;
            }

            return(false);
        }
Пример #4
0
 public static void CreateClasses(MetadataDatabase mdb)
 {
     if (!Directory.Exists(ClassCreationOptions.OutputPath))
     {
         Directory.CreateDirectory(ClassCreationOptions.OutputPath);
     }
     double total = mdb.Tables.Count;
     double done = 0;
     foreach (MetadataTable mt in mdb.Tables.Values)
     {
         StringBuilder sb = CreateTable(mt);
         string file = Path.Combine(ClassCreationOptions.OutputPath, mt.Name + ".cs");
         File.WriteAllText(file, sb.ToString());
         if (ClassCreationOptions.MetadataEvent != null)
         {
             done++;
             ClassCreationOptions.MetadataEvent.Invoke(Convert.ToInt32((done / total) * 100), mt.Name + ".cs created", DateTime.Now);
         }
     }
 }
Пример #5
0
        public static void CreateClasses(MetadataDatabase mdb)
        {
            if (!Directory.Exists(ClassCreationOptions.OutputPath))
            {
                Directory.CreateDirectory(ClassCreationOptions.OutputPath);
            }
            double total = mdb.Tables.Count;
            double done  = 0;

            foreach (MetadataTable mt in mdb.Tables.Values)
            {
                StringBuilder sb   = CreateTable(mt);
                string        file = Path.Combine(ClassCreationOptions.OutputPath, mt.Name + ".cs");
                File.WriteAllText(file, sb.ToString());
                if (ClassCreationOptions.MetadataEvent != null)
                {
                    done++;
                    ClassCreationOptions.MetadataEvent.Invoke(Convert.ToInt32((done / total) * 100), mt.Name + ".cs created", DateTime.Now);
                }
            }
        }
 public static void ToFile(this MetadataDatabase Metadata, string FileName, bool CreateDirectory = true)
 {
     if (CreateDirectory)
     {
         if (!Directory.Exists(Path.GetDirectoryName(FileName)))
         {
             Directory.CreateDirectory(Path.GetDirectoryName(FileName));
         }
     }
     if (!Path.GetExtension(FileName).ToLower().EndsWith(".json"))
     {
         FileName += ".json";
     }
     using (FileStream fs = File.OpenWrite(FileName))
         using (StreamWriter sw = new StreamWriter(fs))
             using (JsonWriter jw = new JsonTextWriter(sw))
             {
                 jw.Formatting = Formatting.None;
                 JsonSerializer serializer = JsonSerializer.Create(settings);
                 serializer.Serialize(jw, Metadata);
             }
 }
        public static MetadataHelper WithMetadata(this Table table)
        {
            MetadataDatabase mdb = table.Builder.Metadata;

            if (mdb != null)
            {
                MetadataTable mt = mdb.FindTable(table.FullName);
                if (mt != null)
                {
                    return(new MetadataHelper()
                    {
                        Table = table, Model = mt
                    });
                }
                else
                {
                    throw new InvalidOperationException(string.Format("The Table '{0}' was not found in metadata", table.FullName));
                }
            }
            else
            {
                throw new InvalidOperationException("The SqlBuilder does not contain metadata");
            }
        }
 public static List <Mood_MDD> GetMoods(this MetadataDatabase mdd)
 {
     return(mdd.Query <Mood_MDD>("SELECT * FROM Mood").ToList <Mood_MDD>());
 }
 public static EncounterLayer_MDD SelectEncounterLayerByGuid(this MetadataDatabase mdd, string encounterLayerGuid)
 {
     return(mdd.Query <EncounterLayer_MDD>("SELECT * FROM EncounterLayer WHERE EncounterLayerGUID=@encounterLayerGuid", new {
         EncounterLayerGUID = encounterLayerGuid
     }, null, true, null, null).FirstOrDefault <EncounterLayer_MDD>());
 }
Пример #10
0
 public static List <ContractType_MDD> GetStoryContractTypes(this MetadataDatabase mdd)
 {
     return(mdd.Query <ContractType_MDD>("SELECT * FROM ContractType WHERE IsStory = 1 OR IsRestoration = 1").ToList <ContractType_MDD>());
 }
 public static List <ContractType_MDD> GetCustomContractTypes(this MetadataDatabase mdd)
 {
     return(mdd.Query <ContractType_MDD>("SELECT * FROM ContractType WHERE ContractTypeID >= 10000").ToList <ContractType_MDD>());
 }
Пример #12
0
        public static Contract GetNewWarContract(SimGameState Sim, int Difficulty, Faction emp, Faction targ, StarSystem system)
        {
            if (Difficulty <= 1)
            {
                Difficulty = 2;
            }
            else if (Difficulty > 9)
            {
                Difficulty = 9;
            }

            ContractDifficulty minDiffClamped = (ContractDifficulty)AccessTools.Method(typeof(SimGameState), "GetDifficultyEnumFromValue").Invoke(Sim, new object[] { Difficulty });
            ContractDifficulty maxDiffClamped = (ContractDifficulty)AccessTools.Method(typeof(SimGameState), "GetDifficultyEnumFromValue").Invoke(Sim, new object[] { Difficulty });
            List <Contract>    contractList   = new List <Contract>();
            int maxContracts = 1;
            int debugCount   = 0;

            while (contractList.Count < maxContracts && debugCount < 1000)
            {
                WeightedList <MapAndEncounters> contractMaps  = new WeightedList <MapAndEncounters>(WeightedListType.SimpleRandom, null, null, 0);
                List <ContractType>             contractTypes = new List <ContractType>();
                Dictionary <ContractType, List <ContractOverride> > potentialOverrides = new Dictionary <ContractType, List <ContractOverride> >();
                AccessTools.Field(typeof(SimGameState), "singlePlayerTypes");
                ContractType[] singlePlayerTypes = (ContractType[])AccessTools.Field(typeof(SimGameState), "singlePlayerTypes").GetValue(Sim);
                using (MetadataDatabase metadataDatabase = new MetadataDatabase()) {
                    foreach (Contract_MDD contract_MDD in metadataDatabase.GetContractsByDifficultyRange(Difficulty - 1, Difficulty + 1))
                    {
                        ContractType contractType = contract_MDD.ContractTypeEntry.ContractType;
                        if (singlePlayerTypes.Contains(contractType))
                        {
                            if (!contractTypes.Contains(contractType))
                            {
                                contractTypes.Add(contractType);
                            }
                            if (!potentialOverrides.ContainsKey(contractType))
                            {
                                potentialOverrides.Add(contractType, new List <ContractOverride>());
                            }
                            ContractOverride item = Sim.DataManager.ContractOverrides.Get(contract_MDD.ContractID);
                            potentialOverrides[contractType].Add(item);
                        }
                    }
                    foreach (MapAndEncounters element in metadataDatabase.GetReleasedMapsAndEncountersByContractTypeAndTags(singlePlayerTypes, system.Def.MapRequiredTags, system.Def.MapExcludedTags, system.Def.SupportedBiomes))
                    {
                        if (!contractMaps.Contains(element))
                        {
                            contractMaps.Add(element, 0);
                        }
                    }
                }
                if (contractMaps.Count == 0)
                {
                    Logger.LogLine("Maps0 break");
                    break;
                }
                if (potentialOverrides.Count == 0)
                {
                    Logger.LogLine("Overrides0 break");
                    break;
                }
                contractMaps.Reset(false);
                WeightedList <Faction> validEmployers = new WeightedList <Faction>(WeightedListType.SimpleRandom, null, null, 0);
                Dictionary <Faction, WeightedList <Faction> > validTargets = new Dictionary <Faction, WeightedList <Faction> >();

                int i = debugCount;
                debugCount = i + 1;
                WeightedList <MapAndEncounters> activeMaps    = new WeightedList <MapAndEncounters>(WeightedListType.SimpleRandom, contractMaps.ToList(), null, 0);
                List <MapAndEncounters>         discardedMaps = new List <MapAndEncounters>();


                List <string> mapDiscardPile = (List <string>)AccessTools.Field(typeof(SimGameState), "mapDiscardPile").GetValue(Sim);

                for (int j = activeMaps.Count - 1; j >= 0; j--)
                {
                    if (mapDiscardPile.Contains(activeMaps[j].Map.MapID))
                    {
                        discardedMaps.Add(activeMaps[j]);
                        activeMaps.RemoveAt(j);
                    }
                }
                if (activeMaps.Count == 0)
                {
                    mapDiscardPile.Clear();
                    foreach (MapAndEncounters element2 in discardedMaps)
                    {
                        activeMaps.Add(element2, 0);
                    }
                }
                activeMaps.Reset(false);
                MapAndEncounters          level           = null;
                List <EncounterLayer_MDD> validEncounters = new List <EncounterLayer_MDD>();


                Dictionary <ContractType, WeightedList <PotentialContract> > validContracts = new Dictionary <ContractType, WeightedList <PotentialContract> >();
                WeightedList <PotentialContract> flatValidContracts = null;
                do
                {
                    level = activeMaps.GetNext(false);
                    if (level == null)
                    {
                        break;
                    }
                    validEncounters.Clear();
                    validContracts.Clear();
                    flatValidContracts = new WeightedList <PotentialContract>(WeightedListType.WeightedRandom, null, null, 0);
                    foreach (EncounterLayer_MDD encounterLayer_MDD in level.Encounters)
                    {
                        ContractType contractType2 = encounterLayer_MDD.ContractTypeEntry.ContractType;
                        if (contractTypes.Contains(contractType2))
                        {
                            if (validContracts.ContainsKey(contractType2))
                            {
                                validEncounters.Add(encounterLayer_MDD);
                            }
                            else
                            {
                                foreach (ContractOverride contractOverride2 in potentialOverrides[contractType2])
                                {
                                    bool flag = true;
                                    ContractDifficulty difficultyEnumFromValue = (ContractDifficulty)AccessTools.Method(typeof(SimGameState), "GetDifficultyEnumFromValue").Invoke(Sim, new object[] { contractOverride2.difficulty });
                                    Faction            employer2 = Faction.INVALID_UNSET;
                                    Faction            target2   = Faction.INVALID_UNSET;
                                    if (difficultyEnumFromValue >= minDiffClamped && difficultyEnumFromValue <= maxDiffClamped)
                                    {
                                        employer2 = emp;
                                        target2   = targ;
                                        int difficulty = Sim.NetworkRandom.Int(Difficulty, Difficulty + 1);
                                        system.SetCurrentContractFactions(employer2, target2);
                                        int k = 0;
                                        while (k < contractOverride2.requirementList.Count)
                                        {
                                            RequirementDef requirementDef = new RequirementDef(contractOverride2.requirementList[k]);
                                            EventScope     scope          = requirementDef.Scope;
                                            TagSet         curTags;
                                            StatCollection stats;
                                            switch (scope)
                                            {
                                            case EventScope.Company:
                                                curTags = Sim.CompanyTags;
                                                stats   = Sim.CompanyStats;
                                                break;

                                            case EventScope.MechWarrior:
                                            case EventScope.Mech:
                                                goto IL_88B;

                                            case EventScope.Commander:
                                                goto IL_8E9;

                                            case EventScope.StarSystem:
                                                curTags = system.Tags;
                                                stats   = system.Stats;
                                                break;

                                            default:
                                                goto IL_88B;
                                            }
IL_803:
                                            for (int l = requirementDef.RequirementComparisons.Count - 1; l >= 0; l--)
                                            {
                                                ComparisonDef item2 = requirementDef.RequirementComparisons[l];
                                                if (item2.obj.StartsWith("Target") || item2.obj.StartsWith("Employer"))
                                                {
                                                    requirementDef.RequirementComparisons.Remove(item2);
                                                }
                                            }
                                            if (!SimGameState.MeetsRequirements(requirementDef, curTags, stats, null))
                                            {
                                                flag = false;
                                                break;
                                            }
                                            k++;
                                            continue;
IL_88B:
                                            if (scope != EventScope.Map)
                                            {
                                                throw new Exception("Contracts cannot use the scope of: " + requirementDef.Scope);
                                            }
                                            using (MetadataDatabase metadataDatabase2 = new MetadataDatabase()) {
                                                curTags = metadataDatabase2.GetTagSetForTagSetEntry(level.Map.TagSetID);
                                                stats   = new StatCollection();
                                                goto IL_803;
                                            }
IL_8E9:
                                            curTags = Sim.CommanderTags;
                                            stats   = Sim.CommanderStats;
                                            goto IL_803;
                                        }
                                        if (flag)
                                        {
                                            PotentialContract element3 = default(PotentialContract);
                                            element3.contractOverride = contractOverride2;
                                            element3.difficulty       = difficulty;
                                            element3.employer         = employer2;
                                            element3.target           = target2;
                                            validEncounters.Add(encounterLayer_MDD);
                                            if (!validContracts.ContainsKey(contractType2))
                                            {
                                                validContracts.Add(contractType2, new WeightedList <PotentialContract>(WeightedListType.WeightedRandom, null, null, 0));
                                            }
                                            validContracts[contractType2].Add(element3, contractOverride2.weight);
                                            flatValidContracts.Add(element3, contractOverride2.weight);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }while (validContracts.Count == 0 && level != null);
                system.SetCurrentContractFactions(Faction.INVALID_UNSET, Faction.INVALID_UNSET);
                if (validContracts.Count == 0)
                {
                    if (mapDiscardPile.Count > 0)
                    {
                        mapDiscardPile.Clear();
                    }
                    else
                    {
                        debugCount = 1000;
                        Logger.LogLine(string.Format("[CONTRACT] Unable to find any valid contracts for available map pool. Alert designers.", new object[0]));
                    }
                }
                else
                {
                    GameContext gameContext = new GameContext(Sim.Context);
                    gameContext.SetObject(GameContextObjectTagEnum.TargetStarSystem, system);
                    Dictionary <ContractType, List <EncounterLayer_MDD> > finalEncounters = new Dictionary <ContractType, List <EncounterLayer_MDD> >();
                    foreach (EncounterLayer_MDD encounterLayer_MDD2 in validEncounters)
                    {
                        ContractType contractType3 = encounterLayer_MDD2.ContractTypeEntry.ContractType;
                        if (!finalEncounters.ContainsKey(contractType3))
                        {
                            finalEncounters.Add(contractType3, new List <EncounterLayer_MDD>());
                        }
                        finalEncounters[contractType3].Add(encounterLayer_MDD2);
                    }
                    List <PotentialContract> discardedContracts = new List <PotentialContract>();

                    List <string> contractDiscardPile = (List <string>)AccessTools.Field(typeof(SimGameState), "contractDiscardPile").GetValue(Sim);
                    for (int m = flatValidContracts.Count - 1; m >= 0; m--)
                    {
                        if (contractDiscardPile.Contains(flatValidContracts[m].contractOverride.ID))
                        {
                            discardedContracts.Add(flatValidContracts[m]);
                            flatValidContracts.RemoveAt(m);
                        }
                    }
                    if ((float)discardedContracts.Count >= (float)flatValidContracts.Count * Sim.Constants.Story.DiscardPileToActiveRatio || flatValidContracts.Count == 0)
                    {
                        contractDiscardPile.Clear();
                        foreach (PotentialContract element4 in discardedContracts)
                        {
                            flatValidContracts.Add(element4, 0);
                        }
                    }
                    PotentialContract next = flatValidContracts.GetNext(true);
                    ContractType      finalContractType = next.contractOverride.contractType;
                    finalEncounters[finalContractType].Shuffle <EncounterLayer_MDD>();
                    string           encounterGuid     = finalEncounters[finalContractType][0].EncounterLayerGUID;
                    ContractOverride contractOverride3 = next.contractOverride;
                    Faction          employer3         = next.employer;
                    Faction          target3           = next.target;
                    int targetDifficulty = next.difficulty;

                    Contract con = (Contract)AccessTools.Method(typeof(SimGameState), "CreateTravelContract").Invoke(Sim, new object[] { level.Map.MapName, level.Map.MapPath, encounterGuid, finalContractType, contractOverride3, gameContext, employer3, target3, employer3, false, targetDifficulty });
                    mapDiscardPile.Add(level.Map.MapID);
                    contractDiscardPile.Add(contractOverride3.ID);
                    Sim.PrepContract(con, employer3, target3, target3, level.Map.BiomeSkinEntry.BiomeSkin, con.Override.travelSeed, system);
                    contractList.Add(con);
                }
            }
            if (debugCount >= 1000)
            {
                Logger.LogLine("Unable to fill contract list. Please inform AJ Immediately");
            }
            return(contractList[0]);
        }
Пример #13
0
        public void CloseDatabase()
        {
            DatabaseInfo.Save(DatabaseInfoPath, SerializationMode.Xml);

            _fileStorage.Stop();
            _metadata.Stop();
            _fileStorage = null;
            _metadata = null;
            _rootPath = null;
            _info = null;

            RaisePropertyChanged(string.Empty);
        }
Пример #14
0
        static bool Prefix(UnitSpawnPointOverride __instance, ref LoadRequest request, MetadataDatabase mdd, string lanceName, int unitIndex)
        {
            if (UnityGameInstance.BattleTechGame.Simulation != null && Core.Settings.UpgradePilots)
            {
                try
                {
                    DataManager dataManager = Traverse.Create(__instance).Field("dataManager").GetValue <DataManager>();

                    if (__instance.pilotDefId == UnitSpawnPointGameLogic.PilotDef_Tagged &&
                        __instance.selectedUnitType == UnitType.Mech &&
                        __instance.selectedUnitDefId != UnitSpawnPointGameLogic.MechDef_None &&
                        dataManager != null &&
                        __instance.pilotTagSet.IsEmpty &&
                        __instance.pilotExcludedTagSet.IsEmpty)
                    {
                        //Logger.Log($"Adding Exclusions to pilot: {__instance.pilotDefId}, for lance: {lanceName}, unit index: {unitIndex}, in Mech: {__instance.selectedUnitDefId}");

                        /*
                         * Skill	    -	            Gunnery 8	    Piloting 8	    Guts 8	        Tactics 8
                         * Gunnery 5	Gunner		    -               Flanker	        Gladiator	    Striker
                         * Piloting 5	Pilot	        Skirmisher	    -               Brawler	        Scout
                         * Guts 5      Defender	    Lancer	        Outrider	    -               Vanguard
                         * Tactics 5	Tactician	    Sharpshooter	Recon	        Sentinel        -
                         */

                        // Add the Tags we want
                        MechDef mechDef     = dataManager.MechDefs.Get(__instance.selectedUnitDefId);
                        TagSet  excludeTags = new TagSet();


                        if (mechDef.Chassis.ChassisTags.Contains("mech_quirk_multitrac"))
                        {
                            // Excluding tier 2 skilled pilots that don't have Multi Target for Multi-Trac quirk
                            excludeTags.Add("pilot_npc_outrider");
                            excludeTags.Add("pilot_npc_recon");
                            excludeTags.Add("pilot_npc_brawler");
                            excludeTags.Add("pilot_npc_sentinel");
                            excludeTags.Add("pilot_npc_scout");
                            excludeTags.Add("pilot_npc_vanguard");
                        }

                        // Brawlers
                        if (mechDef.MechTags.Contains("unit_role_brawler"))
                        {
                            // Excluding tier 2 pilots that have no or next to no survivability skills in brawlers
                            excludeTags.Add("pilot_npc_sharpshooter");
                            excludeTags.Add("pilot_npc_skirmisher");

                            if (!mechDef.MechTags.Contains("unit_speed_high"))
                            {
                                // We aren't fast, get rid of shoot and move with no additional survivability
                                excludeTags.Add("pilot_npc_striker");
                            }

                            if (mechDef.MechTags.Contains("unit_speed_low") &&
                                !mechDef.MechTags.Contains("unit_jumpOK"))
                            {
                                // We are slow, can't jump and want to brawl, tactics 8 with Piloting 5 will not be enough for us to live on
                                excludeTags.Add("pilot_npc_scout");
                            }
                        }

                        // Snipers
                        if (mechDef.MechTags.Contains("unit_role_sniper"))
                        {
                            if (mechDef.MechTags.Contains("unit_speed_low") ||
                                (!mechDef.MechTags.Contains("unit_speed_high") && !mechDef.MechTags.Contains("unit_jumpOK")))
                            {
                                // Excluding all piloting 8 if a sniper in medium speed or less mech
                                excludeTags.Add("pilot_npc_flanker");
                                excludeTags.Add("pilot_npc_outrider");
                                excludeTags.Add("pilot_npc_recon");
                            }
                        }

                        // Scouts
                        if (mechDef.MechTags.Contains("unit_role_scout"))
                        {
                            // Let's throw away Coolant Vent in scouts
                            excludeTags.Add("pilot_npc_gladiator");
                            excludeTags.Add("pilot_npc_brawler");
                            excludeTags.Add("pilot_npc_sentinel");

                            if (mechDef.MechTags.Contains("unit_light") ||
                                mechDef.MechTags.Contains("unit_medium"))
                            {
                                // Excluding Gunnery 8 on light and medium scouts
                                excludeTags.Add("pilot_npc_skirmisher");
                                excludeTags.Add("pilot_npc_lancer");
                                excludeTags.Add("pilot_npc_sharpshooter");
                            }
                        }

                        // Slow ass Mechs
                        if (mechDef.MechTags.Contains("unit_speed_low"))
                        {
                            if (!mechDef.MechTags.Contains("unit_jumpOK"))
                            {
                                // Excluding non Outrider, piloting 8 in slow, non JJ Mechs
                                // Leaving Outrider as a brawler might want it even if slow
                                excludeTags.Add("pilot_npc_flanker");
                                excludeTags.Add("pilot_npc_recon");
                            }
                        }

                        // Fast fuckers
                        if (mechDef.MechTags.Contains("unit_speed_high"))
                        {
                            if (mechDef.MechTags.Contains("unit_armor_low") &&
                                !mechDef.MechTags.Contains("unit_role_sniper"))
                            {
                                // We are protected by paper but fast, we are not a sniper, let's use certain combos if we have a tier 2 skill
                                // Excluding Gunnery 8
                                excludeTags.Add("pilot_npc_skirmisher");
                                excludeTags.Add("pilot_npc_lancer");
                                excludeTags.Add("pilot_npc_sharpshooter");

                                // Excluding Gunnery 5 if we don't have Piloting 8
                                excludeTags.Add("pilot_npc_striker");
                                excludeTags.Add("pilot_npc_gladiator");
                            }

                            if (!mechDef.MechTags.Contains("unit_armor_high"))
                            {
                                if (!mechDef.MechTags.Contains("unit_hot"))
                                {
                                    // We aren't high armour, we are fast, and we aren't hot
                                    // Let's throw away Coolant Vent in non hot mechs to improve chances of more appropriate skills
                                    excludeTags.Add("pilot_npc_brawler");
                                    excludeTags.Add("pilot_npc_sentinel");
                                }
                            }
                        }

                        /*
                         * Logger.Log($"Exclusions:");
                         * foreach (string anExclude in excludeTags)
                         * {
                         *  Logger.Log("   " + anExclude);
                         * }*/

                        // TagSet should remove duplicates so no need to do that
                        __instance.pilotExcludedTagSet.AddRange(excludeTags);

                        /*Logger.Log($"Final Exclusions:");
                         * foreach (string anExclude in __instance.pilotExcludedTagSet)
                         * {
                         *  Logger.Log("   " + anExclude);
                         * }*/

                        // Now do the same as the method would and don't call original method
                        PilotDef_MDD pilotDef_MDD = UnitSpawnPointOverride.SelectTaggedPilotDef(mdd, __instance.pilotTagSet, __instance.pilotExcludedTagSet, lanceName, unitIndex);
                        __instance.selectedPilotDefId = pilotDef_MDD.PilotDefID;

                        request.AddBlindLoadRequest(BattleTechResourceType.PilotDef, __instance.selectedPilotDefId, new bool?(false));

                        return(false);
                    }
                }
                catch (Exception e)
                {
                    Logger.Error(e);
                }
            }
            return(true);
        }
Пример #15
0
 public MetadataTable BuildMetadata(MetadataDatabase mdb, string TableName, string Schema = "dbo", bool PrimaryKeyIndexOnly = true, bool SelfJoin = false)
 {
     MetadataTable mt = null;
     if (mdb.Tables.TryGetValue(TableName, out mt))
     {
         return mt;
     }
     Microsoft.SqlServer.Management.Smo.Table t = new Microsoft.SqlServer.Management.Smo.Table(SqlDatabase, TableName, Schema);
     t.Refresh();
     return BuildMetadata(mdb, t, PrimaryKeyIndexOnly, SelfJoin);
 }
Пример #16
0
        private MetadataTable BuildMetadata(MetadataDatabase mdb, Microsoft.SqlServer.Management.Smo.Table table, bool PrimaryKeyIndexOnly = true, bool SelfJoin = false)
        {
            MetadataTable mt = null;
            List<VirtualForeignKey> VirtualKeys = new List<VirtualForeignKey>();
            table.Refresh();
            if (mdb.Tables.TryGetValue(table.Name, out mt))
            {
                return mt;
            }

            mt = new MetadataTable()
            {
                ID = table.ID,
                Schema = table.Schema,
                Name = table.Name,
                //Parent = mdb
            };
            mt.TitleColumn = GetExtendedProperty("TitleColumn", table.ExtendedProperties);
            string[] values = GetExtendedProperty("DisplayName", table.ExtendedProperties, new char[] { '\r', '\n' });
            if (values != null)
            {
                foreach (string value in values)
                {
                    string[] v = value.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                    mt.DisplayNames.TryAdd(Convert.ToInt32(v[0]), v[1]);
                }
            }

            values = GetExtendedProperty("Lists", table.ExtendedProperties, new char[] { '\r', '\n' });
            if (values != null)
            {
                foreach (string value in values)
                {
                    string[] v = value.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                    List<string> v2 = v[1].Split(',').ToList();
                    if (!mt.ListDefinitions.TryAdd(v[0].Trim(), v2))
                    {
                        throw new InvalidOperationException(string.Format("The TinySql.Lists extended property is invalid for the table '{0}'", table.Name));
                    }
                }
            }






            foreach (Microsoft.SqlServer.Management.Smo.Column column in table.Columns)
            {
                try
                {
                    MetadataColumn col = new MetadataColumn()
                    {
                        ID = column.ID,
                        Parent = mt,
                        //Database = mdb,
                        Name = column.Name,
                        Collation = column.Collation,
                        Default = column.Default,
                        IsComputed = column.Computed,
                        ComputedText = column.ComputedText,
                        IsPrimaryKey = column.InPrimaryKey,
                        IsIdentity = column.Identity,
                        IsForeignKey = column.IsForeignKey,
                        IdentityIncrement = column.IdentityIncrement,
                        IdentitySeed = column.IdentitySeed,
                        Nullable = column.Nullable,
                        IsRowGuid = column.RowGuidCol
                    };
                    BuildColumnDataType(col, column);

                    values = GetExtendedProperty("DisplayName", column.ExtendedProperties, new char[] { '\r', '\n' });
                    if (values != null)
                    {
                        foreach (string value in values)
                        {
                            if (!value.Contains("="))
                            {
                                col.DisplayNames.TryAdd(SqlBuilder.DefaultCulture.LCID, value);
                            }
                            else
                            {
                                string[] v = value.Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries);
                                col.DisplayNames.TryAdd(Convert.ToInt32(v[0]), v[1]);
                            }

                        }
                    }





                    col.IncludeColumns = GetExtendedProperty("IncludeColumns", column.ExtendedProperties, new char[] { ',' });

                    values = GetExtendedProperty("FK", column.ExtendedProperties, new char[] { '\r', '\n' });
                    if (values != null)
                    {
                        VirtualKeys.Add(new VirtualForeignKey() { Column = col, values = values });
                        col.IsForeignKey = true;
                    }



                    mt.Columns.AddOrUpdate(col.Name, col, (k, v) => { return col; });


                }
                catch (Exception exColumn)
                {
                    throw new InvalidOperationException(string.Format("Unable to generate the column {0}", column.Name), exColumn);
                }
            }



            foreach (Index idx in table.Indexes)
            {
                if (!PrimaryKeyIndexOnly || idx.IndexKeyType == IndexKeyType.DriPrimaryKey)
                {
                    Key key = new Key()
                    {
                        ID = idx.ID,
                        Parent = mt,
                        Database = mdb,
                        Name = idx.Name,
                        IsUnique = idx.IsUnique,
                        IsPrimaryKey = idx.IndexKeyType == IndexKeyType.DriPrimaryKey
                    };
                    foreach (IndexedColumn c in idx.IndexedColumns)
                    {
                        key.Columns.Add(mt[c.Name]);
                    }
                    mt.Indexes.AddOrUpdate(key.Name, key, (k, v) => { return key; });
                }
            }
            if (!SelfJoin)
            {
                foreach (ForeignKey FK in table.ForeignKeys)
                {
                    MetadataForeignKey mfk = new MetadataForeignKey()
                    {
                        ID = FK.ID,
                        Parent = mt,
                        Database = mdb,
                        Name = FK.Name,
                        ReferencedKey = FK.ReferencedKey,
                        ReferencedSchema = FK.ReferencedTableSchema,
                        ReferencedTable = FK.ReferencedTable
                    };
                    MetadataTable mtref = null;
                    if (!mdb.Tables.TryGetValue(mfk.ReferencedSchema + "." + mfk.ReferencedTable, out mtref))
                    {
                        bool self = false;
                        if ((mfk.ReferencedSchema == mt.Schema && mfk.ReferencedTable == mt.Name) || TablesInProgress.Contains(mfk.ReferencedSchema + "." + mfk.ReferencedTable))
                        {
                            self = true;
                        }
                        TablesInProgress.Add(mfk.ReferencedSchema + "." + mfk.ReferencedTable);
                        mtref = BuildMetadata(mdb, mfk.ReferencedTable, mfk.ReferencedSchema, PrimaryKeyIndexOnly, self);
                    }
                    foreach (ForeignKeyColumn cc in FK.Columns)
                    {
                        mfk.ColumnReferences.Add(new MetadataColumnReference()
                        {
                            Name = cc.Name,
                            Column = mt[cc.Name],
                            ReferencedColumn = mtref[cc.ReferencedColumn]
                        });
                    }
                    mt.ForeignKeys.AddOrUpdate(mfk.Name, mfk, (key, existing) =>
                    {
                        return mfk;
                    });
                }
            }

            if (VirtualKeys.Count > 0)
            {
                BuildVirtualKeys(VirtualKeys, mt, mdb, PrimaryKeyIndexOnly);
            }

            mdb.Tables.AddOrUpdate(mt.Schema + "." + mt.Name, mt, (key, existing) =>
            {
                return mt;
            });
            return mt;
        }
Пример #17
0
        internal static void AddModEntries(VersionManifest manifest)
        {
            if (!hasLoadedMods)
            {
                LoadMods();
            }

            stopwatch.Start();

            // there are no mods loaded, just return
            if (modLoadOrder == null || modLoadOrder.Count == 0)
            {
                return;
            }

            if (modEntries != null)
            {
                LogWithDate("Loading another manifest with already setup mod manifests.");
                foreach (var modEntry in modEntries)
                {
                    AddModEntry(manifest, modEntry);
                }

                stopwatch.Stop();
                Log("");
                LogWithDate($"Done. Elapsed running time: {stopwatch.Elapsed.TotalSeconds} seconds\n");
                return;
            }

            LogWithDate("Setting up mod manifests...");

            var jsonMerges = new Dictionary <string, List <string> >();

            modEntries = new List <ModDef.ManifestEntry>();
            foreach (var modName in modLoadOrder)
            {
                if (!modManifest.ContainsKey(modName))
                {
                    continue;
                }

                Log($"\t{modName}:");
                foreach (var modEntry in modManifest[modName])
                {
                    // type being null means we have to figure out the type from the path (StreamingAssets)
                    if (modEntry.Type == null)
                    {
                        // TODO: + 16 is a little bizzare looking, it's the length of the substring + 1 because we want to get rid of it and the \
                        var relPath = modEntry.Path.Substring(modEntry.Path.LastIndexOf("StreamingAssets", StringComparison.Ordinal) + 16);
                        var fakeStreamingAssetsPath = Path.GetFullPath(Path.Combine(StreamingAssetsDirectory, relPath));

                        List <string> types;

                        if (typeCache.ContainsKey(fakeStreamingAssetsPath))
                        {
                            types = typeCache[fakeStreamingAssetsPath];
                        }
                        else
                        {
                            // get the type from the manifest
                            var matchingEntries = manifest.FindAll(x => Path.GetFullPath(x.FilePath) == fakeStreamingAssetsPath);
                            if (matchingEntries == null || matchingEntries.Count == 0)
                            {
                                Log($"\t\tCould not find an existing VersionManifest entry for {modEntry.Id}. Is this supposed to be a new entry? Don't put new entries in StreamingAssets!");
                                continue;
                            }

                            types = new List <string>();

                            foreach (var existingEntry in matchingEntries)
                            {
                                types.Add(existingEntry.Type);
                            }

                            typeCache[fakeStreamingAssetsPath] = types;
                        }

                        if (Path.GetExtension(modEntry.Path).ToLower() == ".json" && modEntry.ShouldMergeJSON)
                        {
                            if (!typeCache.ContainsKey(fakeStreamingAssetsPath))
                            {
                                Log($"\t\tUnable to determine type of {modEntry.Id}. Is there someone screwy with your this mod.json?");
                                continue;
                            }

                            if (!jsonMerges.ContainsKey(fakeStreamingAssetsPath))
                            {
                                jsonMerges[fakeStreamingAssetsPath] = new List <string>();
                            }

                            if (jsonMerges[fakeStreamingAssetsPath].Contains(modEntry.Path))
                            {
                                continue;
                            }

                            // this assumes that .json can only have a single type
                            modEntry.Type = typeCache[fakeStreamingAssetsPath][0];

                            Log($"\t\tMerge => {modEntry.Id} ({modEntry.Type})");

                            jsonMerges[fakeStreamingAssetsPath].Add(modEntry.Path);
                            continue;
                        }

                        foreach (var type in types)
                        {
                            var subModEntry = new ModDef.ManifestEntry(modEntry, modEntry.Path, modEntry.Id);
                            subModEntry.Type = type;

                            if (AddModEntry(manifest, subModEntry))
                            {
                                modEntries.Add(subModEntry);
                            }
                        }

                        continue;
                    }

                    // get "fake" entries that don't actually go into the game's VersionManifest
                    // add videos to be loaded from an external path
                    if (modEntry.Type == "Video")
                    {
                        var fileName = Path.GetFileName(modEntry.Path);
                        if (fileName != null && File.Exists(modEntry.Path))
                        {
                            Log($"\t\tVideo => {fileName}");
                            ModVideos.Add(fileName, modEntry.Path);
                        }

                        continue;
                    }

                    // non-streamingassets json merges
                    if (Path.GetExtension(modEntry.Path)?.ToLower() == ".json" && modEntry.ShouldMergeJSON)
                    {
                        // have to find the original path for the manifest entry that we're merging onto
                        var matchingEntry = manifest.Find(x => x.Id == modEntry.Id);

                        if (matchingEntry == null)
                        {
                            Log($"\t\tCould not find an existing VersionManifest entry for {modEntry.Id}!");
                            continue;
                        }

                        if (!jsonMerges.ContainsKey(matchingEntry.FilePath))
                        {
                            jsonMerges[matchingEntry.FilePath] = new List <string>();
                        }

                        if (jsonMerges[matchingEntry.FilePath].Contains(modEntry.Path))
                        {
                            continue;
                        }

                        // this assumes that .json can only have a single type
                        modEntry.Type = matchingEntry.Type;

                        if (!typeCache.ContainsKey(matchingEntry.FilePath))
                        {
                            typeCache[matchingEntry.FilePath] = new List <string>();
                            typeCache[matchingEntry.FilePath].Add(modEntry.Type);
                        }

                        Log($"\t\tMerge => {modEntry.Id} ({modEntry.Type})");

                        jsonMerges[matchingEntry.FilePath].Add(modEntry.Path);
                        continue;
                    }

                    if (AddModEntry(manifest, modEntry))
                    {
                        modEntries.Add(modEntry);
                    }
                }
            }

            // write type cache to disk
            WriteJsonFile(TypeCachePath, typeCache);

            // perform merges into cache
            LogWithDate("Doing merges...");
            foreach (var jsonMerge in jsonMerges)
            {
                var cachePath = jsonMergeCache.GetOrCreateCachedEntry(jsonMerge.Key, jsonMerge.Value);

                // something went wrong (the parent json prob had errors)
                if (cachePath == null)
                {
                    continue;
                }

                var cacheEntry = new ModDef.ManifestEntry(cachePath);

                cacheEntry.ShouldMergeJSON = false;
                cacheEntry.Type            = typeCache[jsonMerge.Key][0];
                cacheEntry.Id = InferIDFromFile(cachePath);

                if (AddModEntry(manifest, cacheEntry))
                {
                    modEntries.Add(cacheEntry);
                }
            }

            // write merge cache to disk
            jsonMergeCache.WriteCacheToDisk(Path.Combine(CacheDirectory, MERGE_CACHE_FILE_NAME));

            LogWithDate("Adding to DB...");

            // check if files removed from DB cache
            var rebuildDB          = false;
            var replacementEntries = new List <VersionManifestEntry>();
            var removeEntries      = new List <string>();

            foreach (var kvp in dbCache)
            {
                var path = kvp.Key;

                if (File.Exists(path))
                {
                    continue;
                }

                Log($"\tNeed to remove DB entry from file in path: {path}");

                // file is missing, check if another entry exists with same filename in manifest
                var fileName      = Path.GetFileName(path);
                var existingEntry = manifest.Find(x => Path.GetFileName(x.FilePath) == fileName);

                if (existingEntry == null)
                {
                    Log("\t\tHave to rebuild DB, no existing entry in VersionManifest matches removed entry");
                    rebuildDB = true;
                    break;
                }

                replacementEntries.Add(existingEntry);
                removeEntries.Add(path);
            }

            // add removed entries replacements to db
            if (!rebuildDB)
            {
                // remove old entries
                foreach (var removeEntry in removeEntries)
                {
                    dbCache.Remove(removeEntry);
                }

                using (var metadataDatabase = new MetadataDatabase())
                {
                    foreach (var replacementEntry in replacementEntries)
                    {
                        if (AddModEntryToDB(metadataDatabase, Path.GetFullPath(replacementEntry.FilePath), replacementEntry.Type))
                        {
                            Log($"\t\tReplaced DB entry with an existing entry in path: {Path.GetFullPath(replacementEntry.FilePath)}");
                        }
                    }
                }
            }

            // if an entry has been removed and we cannot find a replacement, have to rebuild the mod db
            if (rebuildDB)
            {
                if (File.Exists(ModDBPath))
                {
                    File.Delete(ModDBPath);
                }

                File.Copy(Path.Combine(Path.Combine(StreamingAssetsDirectory, "MDD"), MDD_FILE_NAME), ModDBPath);
                dbCache = new Dictionary <string, DateTime>();
            }

            // add needed files to db
            using (var metadataDatabase = new MetadataDatabase())
            {
                foreach (var modEntry in modEntries)
                {
                    if (modEntry.AddToDB && AddModEntryToDB(metadataDatabase, modEntry.Path, modEntry.Type))
                    {
                        Log($"\tAdded/Updated {modEntry.Id} ({modEntry.Type})");
                    }
                }
            }

            // write db/type cache to disk
            WriteJsonFile(DBCachePath, dbCache);

            stopwatch.Stop();
            Log("");
            LogWithDate($"Done. Elapsed running time: {stopwatch.Elapsed.TotalSeconds} seconds\n");
        }
Пример #18
0
        private static JoinConditionGroup To(SqlBuilder Builder, Table FromSqlTable, MetadataTable FromTable, MetadataColumn FromField, MetadataTable ToTable, Join.JoinTypes JoinType, bool PreferForeignKeyOverPrimaryKey = true)
        {
            MetadataDatabase          mdb = Builder.Metadata;
            List <MetadataForeignKey> Fks = null;
            MetadataForeignKey        FK  = null;
            Join j = null;
            MetadataColumnReference mcr = null;
            JoinConditionGroup      jcg = null;

            if (FromField.IsPrimaryKey)
            {
                if (!FromField.IsForeignKey || !PreferForeignKeyOverPrimaryKey)
                {
                    Fks = ToTable.ForeignKeys.Values.Where(x => x.ReferencedTable.Equals(FromTable.Name) && x.ReferencedSchema.Equals(FromTable.Schema) && x.ColumnReferences.Any(y => y.ReferencedColumn.Equals(FromField))).ToList();
                    if (Fks.Count != 1)
                    {
                        throw new InvalidOperationException(string.Format("The column '{0}' is referenced by {1} keys in the table {2}. Expected 1. Make the join manually",
                                                                          FromField.Name, Fks.Count, ToTable.Fullname));
                    }
                    FK = Fks.First();
                    j  = SqlStatementExtensions.MakeJoin(JoinType, FromSqlTable, ToTable.Name, null, ToTable.Schema.Equals("dbo") ? null : ToTable.Schema);

                    mcr = FK.ColumnReferences.First();
                    jcg = j.On(FromField.Name, SqlOperators.Equal, mcr.Name);
                    return(jcg);
                }
            }
            if (FromField.IsForeignKey)
            {
                Fks = new List <MetadataForeignKey>(FromTable.FindForeignKeys(FromField, ToTable.Name));
                if (Fks.Count != 1)
                {
                    throw new InvalidOperationException(string.Format("The column '{0}' resolves to {1} keys in the table {2}. Expected 1. Make the join manually",
                                                                      FromField.Name, Fks.Count, ToTable.Fullname));
                }
                FK  = Fks.First();
                j   = SqlStatementExtensions.MakeJoin(JoinType, FromSqlTable, ToTable.Name, null, ToTable.Schema.Equals("dbo") ? null : ToTable.Schema);
                mcr = FK.ColumnReferences.First();
                jcg = j.On(FromField.Name, SqlOperators.Equal, mcr.ReferencedColumn.Name);

                if (FK.ColumnReferences.Count > 1)
                {
                    foreach (MetadataColumnReference mcr2 in FK.ColumnReferences.Skip(1))
                    {
                        if (mcr2.Name.StartsWith("\""))
                        {
                            // its a value reference
                            // jcg.And(FK.ReferencedTable, mcr2.ReferencedColumn.Name, SqlOperators.Equal, mcr2.Name.Trim('\"'),null);

                            decimal d;
                            object  o;
                            if (decimal.TryParse(mcr2.Name.Trim('\"'), out d))
                            {
                                o = d;
                            }
                            else
                            {
                                o = (object)mcr2.Name.Trim('\"');
                            }

                            jcg.And(mcr2.ReferencedColumn.Name, SqlOperators.Equal, o, null);
                        }
                        else
                        {
                            jcg.And(mcr2.Column.Name, SqlOperators.Equal, mcr2.ReferencedColumn.Name);
                        }
                    }
                }
                return(jcg);
            }
            throw new ArgumentException(string.Format("The Column '{0}' in the table '{1}' must be a foreign key or primary key", FromField.Name, FromTable.Fullname), "FromField");
        }
Пример #19
0
        public static void Postfix(UnitSpawnPointOverride __instance, UnitDef_MDD __result, MetadataDatabase mdd, TagSet unitTagSet, TagSet unitExcludedTagSet, string lanceName, TagSet companyTags)
        {
            try
            {
                Logger.Debug("----------------------------------------------------------------------------------------------------");
                Logger.Debug("[UnitSpawnPointOverride_SelectTaggedUnitDef_POSTFIX] lanceName: " + lanceName);
                Logger.Debug("[UnitSpawnPointOverride_SelectTaggedUnitDef_POSTFIX] __result.UnitDefID: " + __result.UnitDefID);

                /*
                 * Logger.Debug($"[UnitSpawnPointOverride_SelectTaggedUnitDef_POSTFIX] __result.GetRequiredToSpawnCompanyTagSet(): { String.Join(", ", __result.GetRequiredToSpawnCompanyTagSet().ToArray())}");
                 * Logger.Debug($"[UnitSpawnPointOverride_SelectTaggedUnitDef_POSTFIX] companyTags: { String.Join(", ", companyTags.ToArray())}");
                 * if (companyTags != null && !companyTags.ContainsAll(__result.GetRequiredToSpawnCompanyTagSet()))
                 * {
                 *  Logger.Debug($"[UnitSpawnPointOverride_SelectTaggedUnitDef_POSTFIX] WARNING: {__result.UnitDefID} should NOT spawn yet!");
                 * }
                 */
            }
            catch (Exception e)
            {
                Logger.Error(e);
            }
        }
Пример #20
0
        public static void TagSetQueryExtensions_GetMatchingUnitDefs_Postfix(MetadataDatabase __instance, TagSet requiredTags, DateTime?currentDate, ref List <UnitDef_MDD> __result)
        {
            Logger.Debug($"Executing [{nameof(TagSetQueryExtensions_GetMatchingUnitDefs_Postfix)}],\r\n" +
                         $"RequiredTags = [{string.Join(", ", requiredTags)}]\r\n" +
                         $"MatchingDataByTagSet = [{string.Join("\r\n", __result.Select(defMdd => defMdd.UnitDefID))}]...");

            if (requiredTags.Contains("unit_vehicle") || requiredTags.Contains("unit_turret"))
            {
                Logger.Debug($"Bypassing lance spawn morph as required tags are not looking for mechs...");
                return;
            }
            else if (__result.Count == 0)
            {
                Logger.Debug($"Bypassing lance spawn morph as initial result is empty...");
                return;
            }

            // Alias the keywords for readability...
            var mdd = __instance;
            var matchingDataByTagSet = __result;

            var simGameState = UnityGameInstance.BattleTechGame.Simulation;
            var filteredList = new List <UnitDef_MDD>();

            // Group matching unitDef_MDD records by their associated prefabIdentifier
            var unitsGroupedByPrefab = matchingDataByTagSet
                                       .Select(defMdd => new { unitDefMdd = defMdd, mechDef = simGameState.DataManager.MechDefs.First(pair => pair.Key == defMdd.UnitDefID).Value })
                                       .GroupBy(arg => arg.mechDef.Chassis.PrefabIdentifier, arg => arg, (s, enumerable) => new { Base = s, Units = enumerable })
                                       .ToList();

            Logger.Debug($"Grouped result list into [\r\n" +
                         $"{string.Join("\r\n", unitsGroupedByPrefab.Select(arg => $"[{arg.Base}] -> {string.Join(", ", arg.Units.Select(arg1 => arg1.unitDefMdd.UnitDefID))}"))}]");

            // var prefabVariantsOccuringOnce = unitsGroupedByPrefab.Where(arg => arg.Units.Count() == 1).SelectMany(arg => arg.Units).ToList();
            foreach (var prefabGroup in unitsGroupedByPrefab)
            {
                Logger.Debug($"Processing units for prefab [{prefabGroup.Base}]...");
                var prefabSelectionList = new List <UnitDef_MDD>();
                foreach (var unit in prefabGroup.Units)
                {
                    Logger.Trace($"Processing unit [{unit.mechDef.Description.Id}], CurrentDate = [{currentDate}], MinAppearanceDate = [{unit.mechDef.MinAppearanceDate}]...");
                    // For mechs with an appearance date (and current date is set, which it should always be)
                    // 1. Each entry gets a rarityWeighting + 1 per 30 days since appearance date has passed
                    // 2. To a maximum of 6 (so mechs that appeared at least 180 days prior to the current date receive the maximum rarity weighting)
                    // These following two variables ought to be set via [Settings] in the mod.json...
                    var rarityWeighting = Myself.Settings.MaxRarityWeighting;
                    if (currentDate != null && unit.mechDef.MinAppearanceDate != null)
                    {
                        // Could do this in only one statement, but that ended up being a little kludgy and hard to read...
                        var rawDays     = (currentDate - unit.mechDef.MinAppearanceDate).Value.TotalDays + 1;
                        var roundedDays = Math.Round(rawDays / Myself.Settings.RarityWeightingDaysDivisor, 0);
                        var rawRarity   = Convert.ToInt32(roundedDays);
                        rarityWeighting = Math.Min(rawRarity, Myself.Settings.MaxRarityWeighting);
                        if (rarityWeighting <= 0)
                        {
                            Logger.Trace($"Rarity negative for [{unit.unitDefMdd.UnitDefID}], fixing to 1...");
                            rarityWeighting = 1;
                        }
                        Logger.Trace($"Raw Days = [{rawDays}], " +
                                     $"Rounded Days = [{roundedDays}], " +
                                     $"Raw Rarity = [{rawRarity}], " +
                                     $"Final Rarity Rating = [{rarityWeighting}]");
                    }

                    // Insert multiple copies of unitDefMdd to influence the RNG selection weighted by rarity, appropriately...
                    for (var i = 0; i < rarityWeighting; i++)
                    {
                        Logger.Trace($"Adding [{unit.unitDefMdd.UnitDefID}] to prefabSelectionList...");
                        prefabSelectionList.Add(unit.unitDefMdd);
                    }
                }

                Logger.Trace($"PrefabSelectionList count = [{prefabSelectionList.Count}]");
                var prefabSelectionListGroupByPrefab = prefabSelectionList
                                                       .Select(defMdd => new { unitDefMdd = defMdd, mechDef = simGameState.DataManager.MechDefs.First(pair => pair.Key == defMdd.UnitDefID).Value })
                                                       .GroupBy(arg => arg.unitDefMdd.UnitDefID, arg => arg, (s, enumerable) => new { Base = s, units = enumerable });

                Logger.Debug($"Final Prefab Selection List = [\r\n" +
                             $"{string.Join("\r\n", prefabSelectionListGroupByPrefab.Select(arg => $"[{arg.Base}] - Count [{arg.units.Count()}]"))}" +
                             $"]");

                // Select one variant of the prefab base to include as an option in the filtered list...
                Logger.Trace($"Shuffling prefab selection list...");
                prefabSelectionList.Shuffle();
                var selectedPrefabVariant = prefabSelectionList[0];
                Logger.Debug($"Selected [{selectedPrefabVariant.UnitDefID} for inclusion in final filtered list...]");
                filteredList.Add(selectedPrefabVariant);
            }

            Logger.Debug($"Final filtered list = [\r\n" +
                         $"{string.Join("\r\n", filteredList.Select(defMdd => defMdd.UnitDefID))}" +
                         $"]");

            __result = filteredList;
        }
Пример #21
0
        internal static IEnumerator <ProgressReport> BuildCachedManifestLoop(VersionManifest manifest)
        {
            stopwatch.Start();

            // there are no mods loaded, just return
            if (modLoadOrder == null || modLoadOrder.Count == 0)
            {
                yield break;
            }

            string loadingModText = "Loading Mod Manifests";

            yield return(new ProgressReport(0.0f, loadingModText, "Setting up mod manifests..."));

            LogWithDate("Setting up mod manifests...");

            var jsonMerges = new Dictionary <string, List <string> >();

            modEntries = new List <ModDef.ManifestEntry>();
            int modCount = 0;

            var manifestMods = modLoadOrder.Where(name => modManifest.ContainsKey(name)).ToList();

            foreach (var modName in manifestMods)
            {
                Log($"\t{modName}:");
                yield return(new ProgressReport((float)modCount++ / (float)manifestMods.Count, loadingModText, string.Format("Loading manifest for {0}", modName)));

                foreach (var modEntry in modManifest[modName])
                {
                    // type being null means we have to figure out the type from the path (StreamingAssets)
                    if (modEntry.Type == null)
                    {
                        // TODO: + 16 is a little bizzare looking, it's the length of the substring + 1 because we want to get rid of it and the \
                        var relPath = modEntry.Path.Substring(modEntry.Path.LastIndexOf("StreamingAssets", StringComparison.Ordinal) + 16);
                        var fakeStreamingAssetsPath = Path.GetFullPath(Path.Combine(StreamingAssetsDirectory, relPath));

                        var types = GetTypesFromCacheOrManifest(manifest, fakeStreamingAssetsPath);

                        if (types == null)
                        {
                            Log($"\t\tCould not find an existing VersionManifest entry for {modEntry.Id}. Is this supposed to be a new entry? Don't put new entries in StreamingAssets!");
                            continue;
                        }

                        if (Path.GetExtension(modEntry.Path).ToLower() == ".json" && modEntry.ShouldMergeJSON)
                        {
                            if (!jsonMerges.ContainsKey(fakeStreamingAssetsPath))
                            {
                                jsonMerges[fakeStreamingAssetsPath] = new List <string>();
                            }

                            if (jsonMerges[fakeStreamingAssetsPath].Contains(modEntry.Path))
                            {
                                continue;
                            }

                            // this assumes that .json can only have a single type
                            // typeCache will always contain this path
                            modEntry.Type = typeCache[fakeStreamingAssetsPath][0];

                            Log($"\t\tMerge => {modEntry.Id} ({modEntry.Type})");

                            jsonMerges[fakeStreamingAssetsPath].Add(modEntry.Path);
                            continue;
                        }

                        foreach (var type in types)
                        {
                            var subModEntry = new ModDef.ManifestEntry(modEntry, modEntry.Path, modEntry.Id);
                            subModEntry.Type = type;

                            if (AddModEntry(manifest, subModEntry))
                            {
                                modEntries.Add(subModEntry);
                            }
                        }

                        continue;
                    }

                    // get "fake" entries that don't actually go into the game's VersionManifest
                    // add videos to be loaded from an external path
                    switch (modEntry.Type)
                    {
                    case "Video":
                        var fileName = Path.GetFileName(modEntry.Path);
                        if (fileName != null && File.Exists(modEntry.Path))
                        {
                            Log($"\t\tVideo => {fileName}");
                            ModVideos.Add(fileName, modEntry.Path);
                        }
                        continue;

                    case "AdvancedJSONMerge":
                        var targetFileRelative = AdvancedJSONMerger.GetTargetFile(modEntry.Path);
                        var targetFile         = ResolvePath(targetFileRelative);

                        // need to add the types of the file to the typeCache, so that they can be used later
                        // this actually returns the type, but we don't actually care about that right now
                        GetTypesFromCacheOrManifest(manifest, targetFile);

                        if (!jsonMerges.ContainsKey(targetFile))
                        {
                            jsonMerges[targetFile] = new List <string>();
                        }

                        if (jsonMerges[targetFile].Contains(modEntry.Path))
                        {
                            continue;
                        }

                        Log($"\t\tAdvancedJSONMerge => {modEntry.Id} ({modEntry.Type})");
                        jsonMerges[targetFile].Add(modEntry.Path);
                        continue;
                    }

                    // non-streamingassets json merges
                    if (Path.GetExtension(modEntry.Path)?.ToLower() == ".json" && modEntry.ShouldMergeJSON)
                    {
                        // have to find the original path for the manifest entry that we're merging onto
                        var matchingEntry = manifest.Find(x => x.Id == modEntry.Id);

                        if (matchingEntry == null)
                        {
                            Log($"\t\tCould not find an existing VersionManifest entry for {modEntry.Id}!");
                            continue;
                        }

                        if (!jsonMerges.ContainsKey(matchingEntry.FilePath))
                        {
                            jsonMerges[matchingEntry.FilePath] = new List <string>();
                        }

                        if (jsonMerges[matchingEntry.FilePath].Contains(modEntry.Path))
                        {
                            continue;
                        }

                        // this assumes that .json can only have a single type
                        modEntry.Type = matchingEntry.Type;

                        if (!typeCache.ContainsKey(matchingEntry.FilePath))
                        {
                            typeCache[matchingEntry.FilePath] = new List <string>();
                            typeCache[matchingEntry.FilePath].Add(modEntry.Type);
                        }

                        Log($"\t\tMerge => {modEntry.Id} ({modEntry.Type})");

                        jsonMerges[matchingEntry.FilePath].Add(modEntry.Path);
                        continue;
                    }

                    if (AddModEntry(manifest, modEntry))
                    {
                        modEntries.Add(modEntry);
                    }
                }
            }

            yield return(new ProgressReport(100.0f, "JSON", "Writing JSON file to disk"));

            // write type cache to disk
            WriteJsonFile(TypeCachePath, typeCache);

            // perform merges into cache
            LogWithDate("Doing merges...");
            yield return(new ProgressReport(0.0f, "Merges", "Doing Merges..."));

            int mergeCount = 0;

            foreach (var jsonMerge in jsonMerges)
            {
                yield return(new ProgressReport((float)mergeCount++ / jsonMerges.Count, "Merges", string.Format("Merging {0}", jsonMerge.Key)));

                var cachePath = jsonMergeCache.GetOrCreateCachedEntry(jsonMerge.Key, jsonMerge.Value);

                // something went wrong (the parent json prob had errors)
                if (cachePath == null)
                {
                    continue;
                }

                var cacheEntry = new ModDef.ManifestEntry(cachePath);

                cacheEntry.ShouldMergeJSON = false;
                cacheEntry.Type            = typeCache[jsonMerge.Key][0]; // this assumes only one type for each json file
                cacheEntry.Id = InferIDFromFile(cachePath);

                if (AddModEntry(manifest, cacheEntry))
                {
                    modEntries.Add(cacheEntry);
                }
            }

            yield return(new ProgressReport(100.0f, "Merge Cache", "Writing Merge Cache to disk"));

            // write merge cache to disk
            jsonMergeCache.WriteCacheToDisk(Path.Combine(CacheDirectory, MERGE_CACHE_FILE_NAME));

            LogWithDate("Adding to DB...");

            // check if files removed from DB cache
            var rebuildDB          = false;
            var replacementEntries = new List <VersionManifestEntry>();
            var removeEntries      = new List <string>();

            string dbText = "Syncing Database";

            yield return(new ProgressReport(0.0f, dbText, ""));

            foreach (var kvp in dbCache)
            {
                var path = kvp.Key;

                if (File.Exists(path))
                {
                    continue;
                }

                Log($"\tNeed to remove DB entry from file in path: {path}");

                // file is missing, check if another entry exists with same filename in manifest
                var fileName      = Path.GetFileName(path);
                var existingEntry = manifest.Find(x => Path.GetFileName(x.FilePath) == fileName);

                if (existingEntry == null)
                {
                    Log("\t\tHave to rebuild DB, no existing entry in VersionManifest matches removed entry");
                    rebuildDB = true;
                    break;
                }

                replacementEntries.Add(existingEntry);
                removeEntries.Add(path);
            }

            // add removed entries replacements to db
            dbText = "Cleaning Database";
            yield return(new ProgressReport(100.0f, dbText, ""));

            if (!rebuildDB)
            {
                // remove old entries
                foreach (var removeEntry in removeEntries)
                {
                    dbCache.Remove(removeEntry);
                }

                using (var metadataDatabase = new MetadataDatabase())
                {
                    foreach (var replacementEntry in replacementEntries)
                    {
                        if (AddModEntryToDB(metadataDatabase, Path.GetFullPath(replacementEntry.FilePath), replacementEntry.Type))
                        {
                            Log($"\t\tReplaced DB entry with an existing entry in path: {Path.GetFullPath(replacementEntry.FilePath)}");
                        }
                    }
                }
            }

            // if an entry has been removed and we cannot find a replacement, have to rebuild the mod db
            if (rebuildDB)
            {
                if (File.Exists(ModMDDBPath))
                {
                    File.Delete(ModMDDBPath);
                }

                File.Copy(MDDBPath, ModMDDBPath);
                dbCache = new Dictionary <string, DateTime>();
            }

            // add needed files to db
            dbText = "Populating Database";
            int addCount = 0;

            yield return(new ProgressReport(0.0f, dbText, ""));

            using (var metadataDatabase = new MetadataDatabase())
            {
                foreach (var modEntry in modEntries)
                {
                    if (modEntry.AddToDB && AddModEntryToDB(metadataDatabase, modEntry.Path, modEntry.Type))
                    {
                        yield return(new ProgressReport((float)addCount / (float)modEntries.Count, dbText, string.Format("Added {0}", modEntry.Path)));

                        Log($"\tAdded/Updated {modEntry.Id} ({modEntry.Type})");
                    }
                    addCount++;
                }
            }

            // write db/type cache to disk
            WriteJsonFile(DBCachePath, dbCache);

            stopwatch.Stop();
            Log("");
            LogWithDate($"Done. Elapsed running time: {stopwatch.Elapsed.TotalSeconds} seconds\n");

            // Cache the completed manifest
            ModTek.cachedManifest = manifest;

            try
            {
                if (manifest != null && ModTek.modEntries != null)
                {
                    ModTek.modtekOverrides = manifest.Entries.Where(e => ModTek.modEntries.Any(m => e.Id == m.Id))
                                             // ToDictionary expects distinct keys, so take the last entry of each Id
                                             .GroupBy(ks => ks.Id)
                                             .Select(v => v.Last())
                                             .ToDictionary(ks => ks.Id);
                }
                Logger.Log("Built {0} modtek overrides", ModTek.modtekOverrides.Count());
            }
            catch (Exception e)
            {
                Logger.Log("Failed to build overrides {0}", e);
            }

            yield break;
        }
Пример #22
0
 public static bool CacheMetadata(string MetadataKey, MetadataDatabase mdb, CacheItemPolicy Policy = null)
 {
     if (MemoryCache.Default.Contains(MetadataKey))
     {
         return true;
     }
     CacheItem item = MemoryCache.Default.AddOrGetExisting(new CacheItem(MetadataKey, SerializationExtensions.ToJson<MetadataDatabase>(mdb)), (Policy ?? CachePolicy));
     return item.Value == null;
 }
Пример #23
0
        internal static void TryAddToVersionManifest(VersionManifest manifest)
        {
            if (!hasLoadedMods)
            {
                LoadMods();
            }

            var breakMyGame = File.Exists(Path.Combine(ModDirectory, "break.my.game"));

            LogWithDate("Adding in mod manifests!");

            if (breakMyGame)
            {
                var mddPath       = Path.Combine(Path.Combine(StreamingAssetsDirectory, "MDD"), "MetadataDatabase.db");
                var mddBackupPath = mddPath + ".orig";

                Log($"\tBreak my game mode enabled! All new modded content (doesn't currently support merges) will be added to the DB.");

                if (!File.Exists(mddBackupPath))
                {
                    Log($"\t\tBacking up metadata database to {Path.GetFileName(mddBackupPath)}");
                    File.Copy(mddPath, mddBackupPath);
                }
            }

            foreach (var modName in modLoadOrder)
            {
                if (!ModManifest.ContainsKey(modName))
                {
                    continue;
                }

                Log($"\t{modName}:");
                foreach (var modEntry in ModManifest[modName])
                {
                    var existingEntry = manifest.Find(x => x.Id == modEntry.Id);
                    VersionManifestAddendum addendum = null;

                    if (!string.IsNullOrEmpty(modEntry.AddToAddendum))
                    {
                        addendum = manifest.GetAddendumByName(modEntry.AddToAddendum);

                        // create the addendum if it doesn't exist
                        if (addendum == null)
                        {
                            Log($"\t\tCreated addendum {modEntry.AddToAddendum}:");
                            addendum = new VersionManifestAddendum(modEntry.AddToAddendum);
                            manifest.ApplyAddendum(addendum);
                        }
                    }

                    if (modEntry.Type == null)
                    {
                        // null type means that we have to find existing entry with the same rel path to fill in the entry
                        // TODO: + 16 is a little bizzare looking, it's the length of the substring + 1 because we want to get rid of it and the \
                        var relPath = modEntry.Path.Substring(modEntry.Path.LastIndexOf("StreamingAssets", StringComparison.Ordinal) + 16);
                        var fakeStreamingAssetsPath = Path.Combine(StreamingAssetsDirectory, relPath);

                        existingEntry = manifest.Find(x => Path.GetFullPath(x.FilePath) == Path.GetFullPath(fakeStreamingAssetsPath));

                        if (existingEntry == null)
                        {
                            continue;
                        }

                        modEntry.Id   = existingEntry.Id;
                        modEntry.Type = existingEntry.Type;
                    }

                    if (Path.GetExtension(modEntry.Path).ToLower() == ".json" && modEntry.ShouldMergeJSON && existingEntry != null)
                    {
                        // read the manifest pointed entry and hash the contents
                        JsonHashToId[File.ReadAllText(existingEntry.FilePath).GetHashCode()] = modEntry.Id;

                        // The manifest already contains this information, so we need to queue it to be merged
                        var partialJson = File.ReadAllText(modEntry.Path);

                        if (!JsonMerges.ContainsKey(modEntry.Id))
                        {
                            JsonMerges.Add(modEntry.Id, new List <string>());
                        }

                        if (JsonMerges[modEntry.Id].Contains(partialJson))
                        {
                            Log($"\t\tAlready added {modEntry.Id} to JsonMerges");
                            continue;
                        }

                        Log($"\t\tAdding {modEntry.Id} to JsonMerges");
                        JsonMerges[modEntry.Id].Add(partialJson);
                        continue;
                    }

                    if (breakMyGame && Path.GetExtension(modEntry.Path).ToLower() == ".json")
                    {
                        var type = (BattleTechResourceType)Enum.Parse(typeof(BattleTechResourceType), modEntry.Type);
                        using (var metadataDatabase = new MetadataDatabase())
                        {
                            VersionManifestHotReload.InstantiateResourceAndUpdateMDDB(type, modEntry.Path, metadataDatabase);
                            Log($"\t\tAdding to MDDB! {type} {modEntry.Path}");
                        }
                    }

                    if (!string.IsNullOrEmpty(modEntry.AddToAddendum))
                    {
                        Log($"\t\tAddOrUpdate {modEntry.Type} {modEntry.Id} to addendum {addendum.Name}");
                        addendum.AddOrUpdate(modEntry.Id, modEntry.Path, modEntry.Type, DateTime.Now, modEntry.AssetBundleName, modEntry.AssetBundlePersistent);
                        continue;
                    }

                    // This is a new definition or a replacement that doesn't get merged, so add or update the manifest
                    Log($"\t\tAddOrUpdate {modEntry.Type} {modEntry.Id}");
                    manifest.AddOrUpdate(modEntry.Id, modEntry.Path, modEntry.Type, DateTime.Now, modEntry.AssetBundleName, modEntry.AssetBundlePersistent);
                }
            }

            Log("");
        }
Пример #24
0
        internal static IEnumerator <ProgressReport> BuildModManifestEntriesLoop()
        {
            stopwatch.Start();

            // there are no mods loaded, just return
            if (modLoadOrder == null || modLoadOrder.Count == 0)
            {
                yield break;
            }

            Log("");

            var jsonMerges   = new Dictionary <string, List <string> >();
            var manifestMods = modLoadOrder.Where(name => entriesByMod.ContainsKey(name)).ToList();

            var entryCount = 0;
            var numEntries = 0;

            entriesByMod.Do(entries => numEntries += entries.Value.Count);

            foreach (var modName in manifestMods)
            {
                Log($"{modName}:");

                foreach (var modEntry in entriesByMod[modName])
                {
                    yield return(new ProgressReport(entryCount++ / ((float)numEntries), $"Loading {modName}", modEntry.Id));

                    // type being null means we have to figure out the type from the path (StreamingAssets)
                    if (modEntry.Type == null)
                    {
                        // TODO: + 16 is a little bizzare looking, it's the length of the substring + 1 because we want to get rid of it and the \
                        var relPath = modEntry.Path.Substring(modEntry.Path.LastIndexOf("StreamingAssets", StringComparison.Ordinal) + 16);
                        var fakeStreamingAssetsPath = Path.GetFullPath(Path.Combine(StreamingAssetsDirectory, relPath));
                        if (!File.Exists(fakeStreamingAssetsPath))
                        {
                            Log($"\tCould not find a file at {fakeStreamingAssetsPath} for {modName} {modEntry.Id}. NOT LOADING THIS FILE");
                            continue;
                        }

                        var types = GetTypesFromCacheOrManifest(CachedVersionManifest, modEntry.Id);
                        if (types == null)
                        {
                            Log($"\tCould not find an existing VersionManifest entry for {modEntry.Id}. Is this supposed to be a new entry? Don't put new entries in StreamingAssets!");
                            continue;
                        }

                        // this is getting merged later and then added to the BTRL entries then
                        if (Path.GetExtension(modEntry.Path).ToLower() == ".json" && modEntry.ShouldMergeJSON)
                        {
                            if (!jsonMerges.ContainsKey(modEntry.Id))
                            {
                                jsonMerges[modEntry.Id] = new List <string>();
                            }

                            if (jsonMerges[modEntry.Id].Contains(modEntry.Path)) // TODO: is this necessary?
                            {
                                continue;
                            }

                            // this assumes that .json can only have a single type
                            // typeCache will always contain this path
                            modEntry.Type = GetTypesFromCache(modEntry.Id)[0];

                            Log($"\tMerge: \"{GetRelativePath(modEntry.Path, ModsDirectory)}\" ({modEntry.Type})");

                            jsonMerges[modEntry.Id].Add(modEntry.Path);
                            continue;
                        }

                        foreach (var type in types)
                        {
                            var subModEntry = new ModDef.ManifestEntry(modEntry, modEntry.Path, modEntry.Id);
                            subModEntry.Type = type;
                            AddModEntry(CachedVersionManifest, subModEntry);

                            // clear json merges for this entry, mod is overwriting the original file, previous mods merges are tossed
                            if (jsonMerges.ContainsKey(modEntry.Id))
                            {
                                jsonMerges.Remove(modEntry.Id);
                                Log($"\t\tHad merges for {modEntry.Id} but had to toss, since original file is being replaced");
                            }
                        }

                        continue;
                    }

                    // get "fake" entries that don't actually go into the game's VersionManifest
                    // add videos to be loaded from an external path
                    switch (modEntry.Type)
                    {
                    case "Video":
                        var fileName = Path.GetFileName(modEntry.Path);
                        if (fileName != null && File.Exists(modEntry.Path))
                        {
                            Log($"\tVideo: \"{GetRelativePath(modEntry.Path, ModsDirectory)}\"");
                            ModVideos.Add(fileName, modEntry.Path);
                        }
                        continue;

                    case "AdvancedJSONMerge":
                        var id = AdvancedJSONMerger.GetTargetID(modEntry.Path);

                        // need to add the types of the file to the typeCache, so that they can be used later
                        // if merging onto a file added by another mod, the type is already in the cache
                        var types = GetTypesFromCacheOrManifest(CachedVersionManifest, id);

                        if (!jsonMerges.ContainsKey(id))
                        {
                            jsonMerges[id] = new List <string>();
                        }

                        if (jsonMerges[id].Contains(modEntry.Path))     // TODO: is this necessary?
                        {
                            continue;
                        }

                        Log($"\tAdvancedJSONMerge: \"{GetRelativePath(modEntry.Path, ModsDirectory)}\" ({types[0]})");
                        jsonMerges[id].Add(modEntry.Path);
                        continue;
                    }

                    // non-streamingassets json merges
                    if (Path.GetExtension(modEntry.Path)?.ToLower() == ".json" && modEntry.ShouldMergeJSON)
                    {
                        // have to find the original path for the manifest entry that we're merging onto
                        var matchingEntry = GetEntryFromCachedOrBTRLEntries(modEntry.Id);

                        if (matchingEntry == null)
                        {
                            Log($"\tCould not find an existing VersionManifest entry for {modEntry.Id}!");
                            continue;
                        }

                        var matchingPath = Path.GetFullPath(matchingEntry.FilePath);

                        if (!jsonMerges.ContainsKey(modEntry.Id))
                        {
                            jsonMerges[modEntry.Id] = new List <string>();
                        }

                        if (jsonMerges[modEntry.Id].Contains(modEntry.Path)) // TODO: is this necessary?
                        {
                            continue;
                        }

                        Log($"\tMerge: \"{GetRelativePath(modEntry.Path, ModsDirectory)}\" ({modEntry.Type})");

                        // this assumes that .json can only have a single type
                        modEntry.Type = matchingEntry.Type;
                        TryAddTypeToCache(modEntry.Id, modEntry.Type);
                        jsonMerges[modEntry.Id].Add(modEntry.Path);
                        continue;
                    }

                    AddModEntry(CachedVersionManifest, modEntry);
                    TryAddTypeToCache(modEntry.Id, modEntry.Type);

                    // clear json merges for this entry, mod is overwriting the original file, previous mods merges are tossed
                    if (jsonMerges.ContainsKey(modEntry.Id))
                    {
                        jsonMerges.Remove(modEntry.Id);
                        Log($"\t\tHad merges for {modEntry.Id} but had to toss, since original file is being replaced");
                    }
                }
            }

            WriteJsonFile(TypeCachePath, typeCache);

            // perform merges into cache
            Log("");
            LogWithDate("Doing merges...");
            yield return(new ProgressReport(1, "Merging", ""));

            var mergeCount = 0;

            foreach (var id in jsonMerges.Keys)
            {
                var existingEntry = GetEntryFromCachedOrBTRLEntries(id);
                if (existingEntry == null)
                {
                    Log($"\tHave merges for {id} but cannot find an original file! Skipping.");
                    continue;
                }

                var originalPath = Path.GetFullPath(existingEntry.FilePath);
                var mergePaths   = jsonMerges[id];

                if (!jsonMergeCache.HasCachedEntry(originalPath, mergePaths))
                {
                    yield return(new ProgressReport(mergeCount++ / ((float)jsonMerges.Count), "Merging", id));
                }

                var cachePath = jsonMergeCache.GetOrCreateCachedEntry(originalPath, mergePaths);

                // something went wrong (the parent json prob had errors)
                if (cachePath == null)
                {
                    continue;
                }

                var cacheEntry = new ModDef.ManifestEntry(cachePath)
                {
                    ShouldMergeJSON = false,
                    Type            = GetTypesFromCache(id)[0], // this assumes only one type for each json file
                    Id = id
                };

                AddModEntry(CachedVersionManifest, cacheEntry);
            }

            jsonMergeCache.WriteCacheToDisk(Path.Combine(CacheDirectory, MERGE_CACHE_FILE_NAME));

            Log("");
            Log("Syncing Database");
            yield return(new ProgressReport(1, "Syncing Database", ""));

            // check if files removed from DB cache
            var rebuildDB          = false;
            var replacementEntries = new List <VersionManifestEntry>();
            var removeEntries      = new List <string>();

            foreach (var path in dbCache.Keys)
            {
                var absolutePath = ResolvePath(path, GameDirectory);

                // check if the file in the db cache is still used
                if (BTRLEntries.Exists(x => x.Path == absolutePath))
                {
                    continue;
                }

                Log($"\tNeed to remove DB entry from file in path: {path}");

                // file is missing, check if another entry exists with same filename in manifest or in BTRL entries
                var fileName      = Path.GetFileName(path);
                var existingEntry = BTRLEntries.FindLast(x => Path.GetFileName(x.Path) == fileName)?.GetVersionManifestEntry()
                                    ?? CachedVersionManifest.Find(x => Path.GetFileName(x.FilePath) == fileName);

                if (existingEntry == null)
                {
                    Log("\t\tHave to rebuild DB, no existing entry in VersionManifest matches removed entry");
                    rebuildDB = true;
                    break;
                }

                replacementEntries.Add(existingEntry);
                removeEntries.Add(path);
            }

            // add removed entries replacements to db
            if (!rebuildDB)
            {
                // remove old entries
                foreach (var removeEntry in removeEntries)
                {
                    dbCache.Remove(removeEntry);
                }

                using (var metadataDatabase = new MetadataDatabase())
                {
                    foreach (var replacementEntry in replacementEntries)
                    {
                        if (AddModEntryToDB(metadataDatabase, Path.GetFullPath(replacementEntry.FilePath), replacementEntry.Type))
                        {
                            Log($"\t\tReplaced DB entry with an existing entry in path: {Path.GetFullPath(replacementEntry.FilePath)}");
                        }
                    }
                }
            }

            // if an entry has been removed and we cannot find a replacement, have to rebuild the mod db
            if (rebuildDB)
            {
                if (File.Exists(ModMDDBPath))
                {
                    File.Delete(ModMDDBPath);
                }

                File.Copy(MDDBPath, ModMDDBPath);
                dbCache = new Dictionary <string, DateTime>();
            }

            // add needed files to db
            var addCount = 0;

            using (var metadataDatabase = new MetadataDatabase())
            {
                foreach (var modEntry in BTRLEntries)
                {
                    if (modEntry.AddToDB && AddModEntryToDB(metadataDatabase, modEntry.Path, modEntry.Type))
                    {
                        yield return(new ProgressReport(addCount / ((float)BTRLEntries.Count), "Populating Database", modEntry.Id));

                        Log($"\tAdded/Updated {modEntry.Id} ({modEntry.Type})");
                    }
                    addCount++;
                }
            }

            // write db/type cache to disk
            WriteJsonFile(DBCachePath, dbCache);

            stopwatch.Stop();
            Log("");
            LogWithDate($"Done. Elapsed running time: {stopwatch.Elapsed.TotalSeconds} seconds\n");
            CloseLogStream();

            yield break;
        }
Пример #25
0
        public MetadataDatabase BuildMetadata(bool PrimaryKeyIndexOnly = true, string[] Tables = null, bool UpdateExisting = false)
        {
            MetadataDatabase mdb = FromCache();
            string[] Changes = null;
            if (mdb != null && !UpdateExisting)
            {
                // mdb.Builder = builder;
                return mdb;
            }
            Guid g = Guid.NewGuid();
            try
            {
                g = SqlDatabase.DatabaseGuid;
            }
            catch (Exception)
            {
            }

            if (UpdateExisting)
            {
                if (mdb == null)
                {
                    throw new ArgumentException("Update was specified but the metadata was not found in cache or file", "UpdateExisting");
                }
                long v = GetVersion();
                if (v <= mdb.Version)
                {
                    RaiseUpdateEvent(100, "The database is up to date");
                    return mdb;
                }
                else
                {
                    Changes = GetChanges(new DateTime(mdb.Version));
                    RaiseUpdateEvent(0, string.Format("{0} Changed tables identified", Changes.Length));
                    foreach (string change in Changes)
                    {
                        MetadataTable mt = null;

                        if (mdb.Tables.TryRemove(change, out mt))
                        {
                            RaiseUpdateEvent(0, string.Format("{0} removed from Metadata pending update", change));
                        }
                        else
                        {
                            throw new InvalidOperationException("Could not remove the table " + change + " pending update");
                        }
                    }
                    mdb.Version = v;
                }

            }
            else
            {
                mdb = new MetadataDatabase()
                {
                    ID = g,
                    Name = SqlDatabase.Name,
                    Server = SqlServer.Name + (!string.IsNullOrEmpty(SqlServer.InstanceName) && SqlServer.Name.IndexOf('\\') == -1 ? "" : ""),
                    Builder = builder,
                    Version = GetVersion()
                };
            }

            double t = 0;
            double total = Changes != null ? Changes.Length : Tables != null ? Tables.Length : SqlDatabase.Tables.Count + SqlDatabase.Views.Count;
            foreach (Microsoft.SqlServer.Management.Smo.Table table in SqlDatabase.Tables)
            {
                if (Tables == null || Tables.Contains(table.Name))
                {
                    if (Changes == null || Changes.Contains(table.Schema + "." + table.Name))
                    {
                        table.Refresh();
                        BuildMetadata(mdb, table);
                        if (MetadataUpdateEvent != null)
                        {
                            t++;
                            RaiseUpdateEvent(Convert.ToInt32((t / total) * 100), table.Schema + "." + table.Name + " built");
                        }
                        if (t == total)
                        {
                            break;
                        }
                    }
                }
            }

            foreach (Microsoft.SqlServer.Management.Smo.View view in SqlDatabase.Views)
            {
                if (view.IsSystemObject)
                {
                    t++;
                    continue;
                }
                if (Tables == null || Tables.Contains(view.Name))
                {
                    if (Changes == null ||Changes.Contains(view.Schema + "." + view.Name))
                    {
                        view.Refresh();
                        BuildMetadataView(mdb, view);
                        if (MetadataUpdateEvent != null)
                        {
                            t++;
                            RaiseUpdateEvent(Convert.ToInt32((t / total) * 100), view.Schema + "." + view.Name + " built");
                        }
                        if (t == total)
                        {
                            break;
                        }
                    }
                }
            }


            ToCache(mdb);
            return mdb;

        }
Пример #26
0
        private void CommonCreationOpening(String pathToMongod, String path)
        {
            _info = DatabaseInfo.Load(File.OpenRead(DatabaseInfoPath), SerializationMode.Xml);

            // create the file database
            _fileStorage = new FileDatabase(path);
            _fileStorage.Start();

            // create the mongodb
            _metadata = new MetadataDatabase(pathToMongod, path);
            _metadata.Start();

            RaisePropertyChanged(String.Empty);
        }
Пример #27
0
 private void BuildVirtualKeys(List<VirtualForeignKey> keys, MetadataTable mt, MetadataDatabase mdb, bool PrimaryKeyIndexOnly)
 {
     foreach (VirtualForeignKey vfk in keys)
     {
         MetadataForeignKey mfk = new MetadataForeignKey()
         {
             ID = 0,
             Name = vfk.values[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[0],
             ReferencedKey = "",
             ReferencedTable = vfk.values[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[1],
             ReferencedSchema = vfk.values[0].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)[2],
             Parent = mt,
             IsVirtual = true
         };
         MetadataTable mtref = null;
         if (!mdb.Tables.TryGetValue(mfk.ReferencedSchema + "." + mfk.ReferencedTable, out mtref))
         {
             bool self = false;
             if (mfk.ReferencedSchema == mt.Schema && mfk.ReferencedTable == mt.Name)
             {
                 self = true;
             }
             mtref = BuildMetadata(mdb, mfk.ReferencedTable, mfk.ReferencedSchema, PrimaryKeyIndexOnly, self);
         }
         for (int i = 1; i < vfk.values.Length; i++)
         {
             MetadataColumnReference mcf = new MetadataColumnReference()
             {
                 ReferencedColumn = mtref[vfk.values[i].Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[1]],
             };
             string from = vfk.values[i].Split(new char[] { '=' }, StringSplitOptions.RemoveEmptyEntries)[0];
             if (from.StartsWith("\""))
             {
                 MetadataColumn mcVirtual = new MetadataColumn()
                 {
                     Name = from,
                     IsForeignKey = true,
                     ID = 0,
                     SqlDataType = SqlDbType.NVarChar,
                     Nullable = false,
                     Length = 0,
                     IsComputed = true,
                     DataType = typeof(string),
                 };
                 mcf.Column = mcVirtual;
                 mcf.Name = from;
             }
             else
             {
                 mcf.Column = mt[from];
                 mcf.Name = mcf.Column.Name;
             }
             mfk.ColumnReferences.Add(mcf);
         }
         mt.ForeignKeys.AddOrUpdate(mfk.Name, mfk, (k, v) => { return mfk; });
     }
 }
Пример #28
0
 public static bool MetadataDatabase_GetMatchingUnitDefs_Prefix(MetadataDatabase __instance)
 {
     return(true);
 }
Пример #29
0
 private bool ToCache(MetadataDatabase mdb)
 {
     if (!UseCache)
     {
         return true;
     }
     return CacheMetadata(MetadataKey, mdb);
 }
Пример #30
0
 public static void MetadataDatabase_GetMatchingUnitDefs_Postfix(MetadataDatabase __instance, DateTime?currentDate, ref List <UnitDef_MDD> __result)
 {
 }
Пример #31
0
            static bool Prefix(UnitSpawnPointOverride __instance, LoadRequest request, MetadataDatabase mdd, string lanceName, string lanceDefId, string unitName, int unitIndex, DateTime?currentDate, TagSet companyTags)
            {
                if (__instance.IsUnitDefTagged &&
                    __instance.unitTagSet.Contains("unit_mech") &&
                    currentDate != null)
                {
                    __instance.selectedUnitDefId = Core.xotlTables.RequestUnit(currentDate.Value, __instance.unitTagSet, __instance.unitExcludedTagSet, companyTags);
                    __instance.selectedUnitType  = UnitType.Mech;

                    request.AddBlindLoadRequest(BattleTechResourceType.MechDef, __instance.selectedUnitDefId, new bool?(false));
                    return(false);
                }
                else
                {
                    return(true);
                }
            }
Пример #32
0
        private static IEnumerator StartGeneratePotentialContractsRoutine(SimGameState instance, bool clearExistingContracts, Action onContractGenComplete, StarSystem systemOverride, bool useCoroutine)
        {
            if (useCoroutine)
            {
                yield return(new WaitForSeconds(0.2f));
            }
            bool            usingBreadcrumbs = systemOverride != null;
            StarSystem      system;
            List <Contract> contractList;

            if (systemOverride != null)
            {
                system       = systemOverride;
                contractList = instance.CurSystem.SystemBreadcrumbs;
            }
            else
            {
                system       = instance.CurSystem;
                contractList = instance.CurSystem.SystemContracts;
            }
            if (clearExistingContracts)
            {
                contractList.Clear();
            }
            int maxContracts;

            if (systemOverride != null)
            {
                maxContracts = instance.CurSystem.CurMaxBreadcrumbs;
            }
            else
            {
                maxContracts = Mathf.CeilToInt(system.CurMaxContracts);
            }

            int debugCount = 0;

            while (contractList.Count < maxContracts && debugCount < 1000)
            {
                if (usingBreadcrumbs)
                {
                    List <StarSystem> listsys = instance.StarSystems;
                    listsys.Shuffle <StarSystem>();
                    system = listsys[0];
                }
                int globalDifficulty = system.Def.Difficulty + Mathf.FloorToInt(instance.GlobalDifficulty);
                int minDiff;
                int maxDiff;

                int contractDifficultyVariance = instance.Constants.Story.ContractDifficultyVariance;
                minDiff = Mathf.Max(1, globalDifficulty - contractDifficultyVariance);
                maxDiff = Mathf.Max(1, globalDifficulty + contractDifficultyVariance);

                ContractDifficulty minDiffClamped             = (ContractDifficulty)ReflectionHelper.InvokePrivateMethode(instance, "GetDifficultyEnumFromValue", new object[] { minDiff });
                ContractDifficulty maxDiffClamped             = (ContractDifficulty)ReflectionHelper.InvokePrivateMethode(instance, "GetDifficultyEnumFromValue", new object[] { maxDiff });
                WeightedList <MapAndEncounters> contractMaps  = new WeightedList <MapAndEncounters>(WeightedListType.SimpleRandom, null, null, 0);
                List <ContractType>             contractTypes = new List <ContractType>();
                Dictionary <ContractType, List <ContractOverride> > potentialOverrides = new Dictionary <ContractType, List <ContractOverride> >();
                ContractType[] singlePlayerTypes = (ContractType[])ReflectionHelper.GetPrivateStaticField(typeof(SimGameState), "singlePlayerTypes");
                using (MetadataDatabase metadataDatabase = new MetadataDatabase()) {
                    foreach (Contract_MDD contract_MDD in metadataDatabase.GetContractsByDifficultyRangeAndScope((int)minDiffClamped, (int)maxDiffClamped, instance.ContractScope))
                    {
                        ContractType contractType = contract_MDD.ContractTypeEntry.ContractType;

                        if (singlePlayerTypes.Contains(contractType))
                        {
                            if (!contractTypes.Contains(contractType))
                            {
                                contractTypes.Add(contractType);
                            }
                            if (!potentialOverrides.ContainsKey(contractType))
                            {
                                potentialOverrides.Add(contractType, new List <ContractOverride>());
                            }
                            ContractOverride item = instance.DataManager.ContractOverrides.Get(contract_MDD.ContractID);
                            potentialOverrides[contractType].Add(item);
                        }
                    }
                    foreach (MapAndEncounters element in metadataDatabase.GetReleasedMapsAndEncountersByContractTypeAndTags(singlePlayerTypes, system.Def.MapRequiredTags, system.Def.MapExcludedTags, system.Def.SupportedBiomes))
                    {
                        if (!contractMaps.Contains(element))
                        {
                            contractMaps.Add(element, 0);
                        }
                    }
                }
                if (contractMaps.Count == 0)
                {
                    Debug.LogError(string.Format("No valid map for System {0}", system.Name));
                    if (onContractGenComplete != null)
                    {
                        onContractGenComplete();
                    }
                    yield break;
                }
                if (potentialOverrides.Count == 0)
                {
                    Debug.LogError(string.Format("No valid contracts queried for difficulties between {0} and {1}, with a SCOPE of {2}", minDiffClamped, maxDiffClamped, instance.ContractScope));
                    if (onContractGenComplete != null)
                    {
                        onContractGenComplete();
                    }
                    yield break;
                }
                contractMaps.Reset(false);
                WeightedList <Faction> validEmployers = new WeightedList <Faction>(WeightedListType.SimpleRandom, null, null, 0);
                Dictionary <Faction, WeightedList <Faction> > validTargets = new Dictionary <Faction, WeightedList <Faction> >();

                Dictionary <Faction, FactionDef> factions = (Dictionary <Faction, FactionDef>)ReflectionHelper.GetPrivateField(instance, "factions");

                foreach (Faction faction in system.Def.ContractEmployers)
                {
                    foreach (Faction faction2 in factions[faction].Enemies)
                    {
                        if (system.Def.ContractTargets.Contains(faction2))
                        {
                            if (!validTargets.ContainsKey(faction))
                            {
                                validTargets.Add(faction, new WeightedList <Faction>(WeightedListType.PureRandom, null, null, 0));
                            }
                            validTargets[faction].Add(faction2, 0);
                        }
                    }
                    if (validTargets.ContainsKey(faction))
                    {
                        validTargets[faction].Reset(false);
                        validEmployers.Add(faction, 0);
                    }
                }
                validEmployers.Reset(false);

                if (validEmployers.Count <= 0 || validTargets.Count <= 0)
                {
                    Debug.LogError(string.Format("Cannot find any valid employers or targets for system {0}", system));
                }
                if (validTargets.Count == 0 || validEmployers.Count == 0)
                {
                    SimGameState.logger.LogError(string.Format("There are no valid employers or employers for the system of {0}. Num valid employers: {1}", system.Name, validEmployers.Count));
                    foreach (Faction faction3 in validTargets.Keys)
                    {
                        SimGameState.logger.LogError(string.Format("--- Targets for {0}: {1}", faction3, validTargets[faction3].Count));
                    }
                    if (onContractGenComplete != null)
                    {
                        onContractGenComplete();
                    }
                    yield break;
                }

                int i = debugCount;
                debugCount = i + 1;
                WeightedList <MapAndEncounters> activeMaps    = new WeightedList <MapAndEncounters>(WeightedListType.SimpleRandom, contractMaps.ToList(), null, 0);
                List <MapAndEncounters>         discardedMaps = new List <MapAndEncounters>();

                List <string> mapDiscardPile = (List <string>)ReflectionHelper.GetPrivateField(instance, "mapDiscardPile");

                for (int j = activeMaps.Count - 1; j >= 0; j--)
                {
                    if (mapDiscardPile.Contains(activeMaps[j].Map.MapID))
                    {
                        discardedMaps.Add(activeMaps[j]);
                        activeMaps.RemoveAt(j);
                    }
                }
                if (activeMaps.Count == 0)
                {
                    mapDiscardPile.Clear();
                    foreach (MapAndEncounters element2 in discardedMaps)
                    {
                        activeMaps.Add(element2, 0);
                    }
                }
                activeMaps.Reset(false);
                MapAndEncounters          level           = null;
                List <EncounterLayer_MDD> validEncounters = new List <EncounterLayer_MDD>();


                Dictionary <ContractType, WeightedList <PotentialContract> > validContracts = new Dictionary <ContractType, WeightedList <PotentialContract> >();
                WeightedList <PotentialContract> flatValidContracts = null;
                do
                {
                    level = activeMaps.GetNext(false);
                    if (level == null)
                    {
                        break;
                    }
                    validEncounters.Clear();
                    validContracts.Clear();
                    flatValidContracts = new WeightedList <PotentialContract>(WeightedListType.WeightedRandom, null, null, 0);
                    foreach (EncounterLayer_MDD encounterLayer_MDD in level.Encounters)
                    {
                        ContractType contractType2 = encounterLayer_MDD.ContractTypeEntry.ContractType;
                        if (contractTypes.Contains(contractType2))
                        {
                            if (validContracts.ContainsKey(contractType2))
                            {
                                validEncounters.Add(encounterLayer_MDD);
                            }
                            else
                            {
                                foreach (ContractOverride contractOverride2 in potentialOverrides[contractType2])
                                {
                                    bool flag = true;
                                    ContractDifficulty difficultyEnumFromValue = (ContractDifficulty)ReflectionHelper.InvokePrivateMethode(instance, "GetDifficultyEnumFromValue", new object[] { contractOverride2.difficulty });
                                    Faction            employer2 = Faction.INVALID_UNSET;
                                    Faction            target2   = Faction.INVALID_UNSET;
                                    object[]           args      = new object[] { system, validEmployers, validTargets, contractOverride2.requirementList, employer2, target2 };
                                    if (difficultyEnumFromValue >= minDiffClamped && difficultyEnumFromValue <= maxDiffClamped && (bool)ReflectionHelper.InvokePrivateMethode(instance, "GetValidFaction", args))
                                    {
                                        employer2 = (Faction)args[4];
                                        target2   = (Faction)args[5];
                                        int difficulty = instance.NetworkRandom.Int(minDiff, maxDiff + 1);
                                        system.SetCurrentContractFactions(employer2, target2);
                                        int k = 0;
                                        while (k < contractOverride2.requirementList.Count)
                                        {
                                            RequirementDef requirementDef = new RequirementDef(contractOverride2.requirementList[k]);
                                            EventScope     scope          = requirementDef.Scope;
                                            TagSet         curTags;
                                            StatCollection stats;
                                            switch (scope)
                                            {
                                            case EventScope.Company:
                                                curTags = instance.CompanyTags;
                                                stats   = instance.CompanyStats;
                                                break;

                                            case EventScope.MechWarrior:
                                            case EventScope.Mech:
                                                goto IL_88B;

                                            case EventScope.Commander:
                                                goto IL_8E9;

                                            case EventScope.StarSystem:
                                                curTags = system.Tags;
                                                stats   = system.Stats;
                                                break;

                                            default:
                                                goto IL_88B;
                                            }
IL_803:
                                            for (int l = requirementDef.RequirementComparisons.Count - 1; l >= 0; l--)
                                            {
                                                ComparisonDef item2 = requirementDef.RequirementComparisons[l];
                                                if (item2.obj.StartsWith("Target") || item2.obj.StartsWith("Employer"))
                                                {
                                                    requirementDef.RequirementComparisons.Remove(item2);
                                                }
                                            }
                                            if (!SimGameState.MeetsRequirements(requirementDef, curTags, stats, null))
                                            {
                                                flag = false;
                                                break;
                                            }
                                            k++;
                                            continue;
IL_88B:
                                            if (scope != EventScope.Map)
                                            {
                                                throw new Exception("Contracts cannot use the scope of: " + requirementDef.Scope);
                                            }
                                            using (MetadataDatabase metadataDatabase2 = new MetadataDatabase()) {
                                                curTags = metadataDatabase2.GetTagSetForTagSetEntry(level.Map.TagSetID);
                                                stats   = new StatCollection();
                                                goto IL_803;
                                            }
IL_8E9:
                                            curTags = instance.CommanderTags;
                                            stats   = instance.CommanderStats;
                                            goto IL_803;
                                        }
                                        if (flag)
                                        {
                                            PotentialContract element3 = default(PotentialContract);
                                            element3.contractOverride = contractOverride2;
                                            element3.difficulty       = difficulty;
                                            element3.employer         = employer2;
                                            element3.target           = target2;
                                            validEncounters.Add(encounterLayer_MDD);
                                            if (!validContracts.ContainsKey(contractType2))
                                            {
                                                validContracts.Add(contractType2, new WeightedList <PotentialContract>(WeightedListType.WeightedRandom, null, null, 0));
                                            }
                                            validContracts[contractType2].Add(element3, contractOverride2.weight);
                                            flatValidContracts.Add(element3, contractOverride2.weight);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }while (validContracts.Count == 0 && level != null);
                system.SetCurrentContractFactions(Faction.INVALID_UNSET, Faction.INVALID_UNSET);
                if (validContracts.Count == 0)
                {
                    if (mapDiscardPile.Count > 0)
                    {
                        mapDiscardPile.Clear();
                    }
                    else
                    {
                        debugCount = 1000;
                        SimGameState.logger.LogError(string.Format("[CONTRACT] Unable to find any valid contracts for available map pool. Alert designers.", new object[0]));
                    }
                }
                else
                {
                    GameContext gameContext = new GameContext(instance.Context);
                    gameContext.SetObject(GameContextObjectTagEnum.TargetStarSystem, system);
                    Dictionary <ContractType, List <EncounterLayer_MDD> > finalEncounters = new Dictionary <ContractType, List <EncounterLayer_MDD> >();
                    foreach (EncounterLayer_MDD encounterLayer_MDD2 in validEncounters)
                    {
                        ContractType contractType3 = encounterLayer_MDD2.ContractTypeEntry.ContractType;
                        if (!finalEncounters.ContainsKey(contractType3))
                        {
                            finalEncounters.Add(contractType3, new List <EncounterLayer_MDD>());
                        }
                        finalEncounters[contractType3].Add(encounterLayer_MDD2);
                    }
                    List <PotentialContract> discardedContracts  = new List <PotentialContract>();
                    List <string>            contractDiscardPile = (List <string>)ReflectionHelper.GetPrivateField(instance, "contractDiscardPile");
                    for (int m = flatValidContracts.Count - 1; m >= 0; m--)
                    {
                        if (contractDiscardPile.Contains(flatValidContracts[m].contractOverride.ID))
                        {
                            discardedContracts.Add(flatValidContracts[m]);
                            flatValidContracts.RemoveAt(m);
                        }
                    }
                    if ((float)discardedContracts.Count >= (float)flatValidContracts.Count * instance.Constants.Story.DiscardPileToActiveRatio || flatValidContracts.Count == 0)
                    {
                        contractDiscardPile.Clear();
                        foreach (PotentialContract element4 in discardedContracts)
                        {
                            flatValidContracts.Add(element4, 0);
                        }
                    }
                    PotentialContract next = flatValidContracts.GetNext(true);
                    ContractType      finalContractType = next.contractOverride.contractType;
                    finalEncounters[finalContractType].Shuffle <EncounterLayer_MDD>();
                    string           encounterGuid     = finalEncounters[finalContractType][0].EncounterLayerGUID;
                    ContractOverride contractOverride3 = next.contractOverride;
                    Faction          employer3         = next.employer;
                    Faction          target3           = next.target;
                    int      targetDifficulty          = next.difficulty;
                    Contract con;
                    if (usingBreadcrumbs)
                    {
                        con = (Contract)ReflectionHelper.InvokePrivateMethode(instance, "CreateTravelContract", new object[] { level.Map.MapName, level.Map.MapPath, encounterGuid, finalContractType, contractOverride3, gameContext, employer3, target3, employer3, false, targetDifficulty });
                    }
                    else
                    {
                        con = new Contract(level.Map.MapName, level.Map.MapPath, encounterGuid, finalContractType, instance.BattleTechGame, contractOverride3, gameContext, true, targetDifficulty, 0, null);
                    }
                    mapDiscardPile.Add(level.Map.MapID);
                    contractDiscardPile.Add(contractOverride3.ID);
                    instance.PrepContract(con, employer3, target3, target3, level.Map.BiomeSkinEntry.BiomeSkin, con.Override.travelSeed, system);
                    contractList.Add(con);
                    if (useCoroutine)
                    {
                        yield return(new WaitForSeconds(0.2f));
                    }
                }
            }
            if (debugCount >= 1000)
            {
                SimGameState.logger.LogError("Unable to fill contract list. Please inform AJ Immediately");
            }
            if (onContractGenComplete != null)
            {
                onContractGenComplete();
            }
            yield break;
        }