Пример #1
0
 /// <summary>
 /// Adds another LoaderInfo to the current result set.
 /// </summary>
 /// <param name="info">Additional LoaderInfo</param>
 public void AddRange(LoaderInfo info)
 {
     Campaigns.AddRange(info.Campaigns);
     Errors.AddRange(info.Errors);
     Levels.AddRange(info.Levels);
     Players.AddRange(info.Players);
 }
Пример #2
0
        /// <summary>
        /// Searches in the given Assembly for the requested Player Type within a closed AppDomain.
        /// </summary>
        /// <param name="extensionPaths">List of pathes to search for Extensions</param>
        /// <param name="file">Filedump of the Assembly</param>
        /// <param name="typeName">Name of the Type</param>
        /// <returns>PlayerInfo of the fitting Player or null in case of no result</returns>
        public static PlayerInfo SecureFindPlayer(string[] extensionPaths, byte[] file, string typeName)
        {
            LoaderInfo info = SecureAnalyseExtension(extensionPaths, file, false, true);

            foreach (var player in info.Players)
            {
                if (player.Type.TypeName.Equals(typeName))
                {
                    return(player);
                }
            }
            return(null);
        }
Пример #3
0
        /// <summary>
        /// Searches in the given Assembly for the requested Level Type within a closed AppDomain.
        /// </summary>
        /// <param name="extensionPaths">List of pathes to search for Extensions</param>
        /// <param name="file">Filedump of the Assembly</param>
        /// <param name="typeName">Name of the Type</param>
        /// <returns>LevelInfo of the fitting Level or null in case of no result</returns>
        public static LevelInfo SecureFindLevel(string[] extensionPaths, byte[] file, string typeName)
        {
            LoaderInfo info = SecureAnalyseExtension(extensionPaths, file, true, false);

            foreach (var level in info.Levels)
            {
                if (level.Type.TypeName.Equals(typeName))
                {
                    return(level);
                }
            }
            return(null);
        }
Пример #4
0
        /// <summary>
        /// Scans the given Assembly for additional Level-, Campaign- and Player-Elements within a closed AppDomain.
        /// </summary>
        /// <param name="extensionPaths">List of pathes to search for Extensions</param>
        /// <param name="file">Filedump</param>
        /// <param name="level">Search for Levels and Campagins</param>
        /// <param name="player">Search for Players</param>
        /// <returns>Collection of found Elements and occured Errors</returns>
        public static LoaderInfo SecureAnalyseExtension(string[] extensionPaths, byte[] file, bool level, bool player)
        {
            AppDomainSetup setup = new AppDomainSetup();

            setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
            Evidence  evidence  = new Evidence();
            AppDomain appDomain = AppDomain.CreateDomain("AntMe! Analyzer", evidence, setup);

            Type hostType = typeof(ExtensionLoaderHost);

            ExtensionLoaderHost host = appDomain.CreateInstanceAndUnwrap(hostType.Assembly.FullName, hostType.FullName) as ExtensionLoaderHost;
            LoaderInfo          info = host.AnalyseExtension(extensionPaths, file, level, level, player);

            foreach (var item in info.Players)
            {
                item.Source = PlayerSource.Imported;
            }

            AppDomain.Unload(appDomain);

            return(info);
        }
Пример #5
0
        /// <summary>
        /// Scans the given Assembly for potential stuff like Campaigns, Levels and Players.
        /// </summary>
        /// <param name="assembly">Assembly to search in</param>
        /// <param name="campaign">Scan for new Campaigns</param>
        /// <param name="level">Scan for new Levels</param>
        /// <param name="player">Scan for new Players</param>
        /// <returns>Scan Results</returns>
        internal static LoaderInfo AnalyseAssembly(Assembly assembly, bool level, bool campaign, bool player)
        {
            LoaderInfo loaderInfo = new LoaderInfo();
            bool       isStatic   = false;

            foreach (var type in assembly.GetTypes())
            {
                // Static-Flag abfragen
                // TODO: Abhängigkeiten in andere Assemblies müssen hier auch aufgegriffen werden
                var members = type.GetMembers(BindingFlags.Static);
                isStatic |= members.Length > 0;

                if (type.IsClass &&
                    type.IsPublic &&
                    !type.IsAbstract)
                {
                    // Found Level
                    if (level && type.IsSubclassOf(typeof(Level)))
                    {
                        try
                        {
                            LevelInfo levelInfo = AnalyseLevelType(type);
                            loaderInfo.Levels.Add(levelInfo);
                        }
                        catch (Exception ex)
                        {
                            loaderInfo.Errors.Add(ex);
                        }
                    }

                    // Found Campaign
                    if (campaign && type.IsSubclassOf(typeof(Campaign)))
                    {
                        try
                        {
                            CampaignInfo campaignInfo = AnalyseCampaignType(type);
                            loaderInfo.Campaigns.Add(campaignInfo);
                        }
                        catch (Exception ex)
                        {
                            loaderInfo.Errors.Add(ex);
                        }
                    }

                    // Found Player (Ignorieren, falls Faction-Liste null)
                    if (player && type.GetCustomAttributes(typeof(FactoryAttribute), true).Length > 0)
                    {
                        try
                        {
                            PlayerInfo playerInfo = AnalysePlayerType(type);
                            loaderInfo.Players.Add(playerInfo);
                        }
                        catch (Exception ex)
                        {
                            loaderInfo.Errors.Add(ex);
                        }
                    }

                    // Found Extender
                    if (type.GetInterface("IExtender") != null)
                    {
                        Type[] interfaces = type.GetInterfaces();
                    }
                }
            }

            // Static Flag nachtragen
            foreach (var item in loaderInfo.Players)
            {
                item.IsStatic = isStatic;
            }

            return(loaderInfo);
        }
Пример #6
0
        /// <summary>
        /// Tries to Loads all available Extensions within the valid extension pathes.
        ///
        /// The method searchs for Extensions in the following pathes:
        /// - Application Path (e.g. "C:\Program Files\AntMe!\")
        /// - Extension Folder of the Application Path (e.g. "C:\Program Files\AntMe!\Extensions")
        /// - App Data Folder ("C:\Users\[username]\AppData\Local\AntMe\Extensions")
        ///
        /// The method loads the following fragments:
        /// - Factions (always)
        /// - GameItems (always)
        /// - Extenders (always)
        /// - Campaigns (only full)
        /// - Players (only full)
        /// - Levels (only full)
        /// </summary>
        /// <param name="extensionPaths">List of pathes to search for Extensions</param>
        /// <param name="token">Optional Reference to a Progress Token</param>
        /// <param name="full">Switch between basic Extension Loader or full Content Load.</param>
        public static void LoadExtensions(string[] extensionPaths, ProgressToken token, bool full)
        {
            if (extensionsLoaded)
            {
                return;
            }

            List <string>    files      = new List <string>();
            List <Exception> errors     = new List <Exception>();
            List <Assembly>  assemblies = new List <Assembly>();

            foreach (var path in extensionPaths)
            {
                // Check if Path exists
                if (!Directory.Exists(path))
                {
                    continue;
                }

                // Enumerate all dll-Files
                files.AddRange(Directory.EnumerateFiles(path, "*.dll"));
            }

            // Calculation of total Tasks (based on the number of files)
            int currentTask = 0;

            if (token != null)
            {
                token.TotalTasks  = (full ? files.Count * 2 : files.Count) + 1;
                token.CurrentTask = currentTask;
            }

            // Try to load all files from list
            foreach (var file in files)
            {
                try
                {
                    // Try to load and add to list
                    assemblies.Add(Assembly.LoadFile(file));
                }
                catch (Exception ex)
                {
                    // Add Loading Error to List
                    if (token != null && token.Errors != null)
                    {
                        token.Errors.Add(ex);
                    }
                    errors.Add(ex);
                }

                // Cancel
                if (token != null && token.Cancel)
                {
                    return;
                }
            }

            // Recalculation of total Tasks (based on the number of loaded assemblies)
            currentTask = 1;
            if (token != null)
            {
                token.TotalTasks  = (full ? assemblies.Count * 2 : assemblies.Count) + 1;
                token.CurrentTask = currentTask;
            }

            // Cancel
            if (token != null && token.Cancel)
            {
                return;
            }

            // Pass 1 Load Extension Packs
            List <IExtensionPack> extensionPacks = new List <IExtensionPack>();
            KeyValueStore         settings       = new KeyValueStore();

            foreach (var assembly in assemblies)
            {
                foreach (var type in assembly.GetExportedTypes())
                {
                    if (type.IsClass &&
                        !type.IsAbstract &&
                        typeof(IExtensionPack).IsAssignableFrom(type))
                    {
                        IExtensionPack extensionPack = null;
                        try
                        {
                            // Instanz erzeugen & Laden
                            extensionPack = Activator.CreateInstance(type) as IExtensionPack;
                            extensionPack.Load(DefaultTypeMapper, settings);
                            extensionPacks.Add(extensionPack);
                        }
                        catch (Exception ex)
                        {
                            // Error dokumentieren
                            if (token != null && token.Errors != null)
                            {
                                token.Errors.Add(ex);
                            }
                            errors.Add(ex);

                            // Remove all Type Mapper elements
                            if (extensionPack != null)
                            {
                                DefaultTypeMapper.RemoveExtensionPack(extensionPack);
                            }
                        }
                    }

                    if (token != null)
                    {
                        token.CurrentTask = currentTask;
                        if (token.Cancel)
                        {
                            return;
                        }
                    }
                }

                currentTask++;
            }

            extensionPackCache = extensionPacks;
            extensionSettings  = settings;

            // Fill Caches
            if (full)
            {
                List <CampaignInfo> campaigns = new List <CampaignInfo>();
                List <LevelInfo>    levels    = new List <LevelInfo>();
                List <PlayerInfo>   players   = new List <PlayerInfo>();

                // Pass 2 (Levels & Players) [campaigns, levels, players]
                foreach (var assembly in assemblies)
                {
                    LoaderInfo loader = AnalyseAssembly(assembly, true, true, true);

                    // Types mit File Dump
                    if (loader.Campaigns.Count > 0 ||
                        loader.Levels.Count > 0 ||
                        loader.Players.Count > 0)
                    {
                        // File dump
                        Stream stream = assembly.GetFiles()[0];
                        byte[] file   = new byte[stream.Length];
                        stream.Read(file, 0, file.Length);

                        // Campaigns laden
                        foreach (var campaign in loader.Campaigns)
                        {
                            foreach (var level in campaign.Levels)
                            {
                                level.Type.AssemblyFile = file;
                            }

                            campaigns.Add(campaign);
                        }

                        // Levels laden
                        foreach (var level in loader.Levels)
                        {
                            level.Type.AssemblyFile = file;
                            levels.Add(level);
                        }

                        // Player laden
                        foreach (var player in loader.Players)
                        {
                            player.Type.AssemblyFile = file;
                            player.Source            = PlayerSource.Native;
                            players.Add(player);
                        }
                    }

                    currentTask++;

                    errors.AddRange(loader.Errors);
                    if (token != null)
                    {
                        token.Errors.AddRange(loader.Errors);
                        token.CurrentTask = currentTask;
                        if (token.Cancel)
                        {
                            return;
                        }
                    }
                }

                campaignCache = campaigns;
                levelCache    = levels;
                playerCache   = players;
            }

            extensionsLoaded = true;

            if (errors.Count > 0)
            {
                throw new AggregateException("Extension Loader had some Exceptions", errors);
            }
        }