[Help] C# plugins and attributes menu

Shout-Out

User Tag List

Results 1 to 6 of 6
  1. #1
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    [Help] C# plugins and attributes

    Okay, so I'm making a generic bot frame for WoW. I decided that I would try using Reflection to load assemblies and have the actual 'bot'. Here's the code I'm using to try to load the assembly.

    Code:
                Assembly a = null;
                try
                {
                    a = Assembly.LoadFrom("Test.dll");
                }
                catch (Exception ex)
                { MessageBox.Show("Error" + ex.Message); }
                if (a == null)
                    return false;
    
                Type[] aType = a.GetTypes();
    
                foreach (Type t in aType)
                {
                    mf.textBox1.AppendText(t.Name + "\n");
                    if (t.IsClass && t.IsSubclassOf(typeof(Bot)))
                    {
                        MessageBox.Show(t.Name);
                        _bot = (Bot)Activator.CreateInstance(t);
                    }
                }
    
                return true;
    I've simplified it a bit and removed attributes and just have overriding functions in each bot. It's not seeing that my class inherits from the base Bot class though. It enumerates through the classes fine, just not seeing that the bot is inheriting. Any tips?
    Last edited by lanman92; 09-27-2009 at 03:36 PM.

    [Help] C# plugins and attributes
  2. #2
    MaiN's Avatar Elite User
    Reputation
    335
    Join Date
    Sep 2006
    Posts
    1,047
    Thanks G/R
    0/10
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Try having the "Bot" class/interface in a seperate dll from your project, and reference the same dll from your Test.dll and your main project.
    [16:15:41] Cypher: caus the CPU is a dick
    [16:16:07] kynox: CPU is mad
    [16:16:15] Cypher: CPU is all like
    [16:16:16] Cypher: whatever, i do what i want

  3. #3
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks a ton! That was a dumb mistake on my part :P +rep

  4. #4
    xzidez's Avatar Member
    Reputation
    12
    Join Date
    Dec 2007
    Posts
    135
    Thanks G/R
    1/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If the interface is in your Main app and the Test.dll is referenced to that I cant se why it shouldnt work?
    I dont know any plugin solution that uses a standalone DLL for interfaces.

    However. If you are trying to use plugins. Read some about System.AddIn. Works quite nice really

  5. #5
    Apoc's Avatar Angry Penguin
    Reputation
    1387
    Join Date
    Jan 2008
    Posts
    2,750
    Thanks G/R
    0/12
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
        /// <summary>
        /// This is a collection to hold class instances. It dynamically loads any classes found within DLLs
        /// in the base application directory.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        internal class ClassCollection<T> : List<T> where T : class
        {
            /// <summary>
            /// Initializes a new instance of the <see cref="ClassCollection&lt;T&gt;"/> class.
            /// </summary>
            public ClassCollection()
                : this(null, false)
            {
            }
    
            /// <summary>
            /// Initializes a new instance of the <see cref="ClassCollection&lt;T&gt;"/> class.
            /// </summary>
            /// <param name="path">The directory path to search for valid .NET assemblies.</param>
            /// <param name="loadRecursive">if set to <c>true</c> this class collection should recursively
            /// load dlls found in the current folder, and any subfolders.</param>
            public ClassCollection(string path, bool loadRecursive)
                : this(null, path, loadRecursive)
            {
            }
    
            /// <summary>
            /// Initializes a new instance of the <see cref="ClassCollection&lt;T&gt;"/> class.
            /// </summary>
            /// <param name="ignoreAttribute">The type of an 'ignore' attribute to be used. If a type is decorated with
            /// this attribute, it will not be loaded into the collection.</param>
            public ClassCollection(Type ignoreAttribute)
                : this(ignoreAttribute, null, false)
            {
            }
    
            /// <summary>
            /// Initializes a new instance of the <see cref="ClassCollection&lt;T&gt;"/> class.
            /// </summary>
            /// <param name="ignoreAttribute">The type of an 'ignore' attribute to be used. If a type is decorated with
            /// this attribute, it will not be loaded into the collection.</param>
            /// <param name="path">The directory path to search for valid .NET assemblies.</param>
            /// <param name="loadRecursive">>if set to <c>true</c> this class collection should recursively
            /// load dlls found in the current folder, and any subfolders.</param>
            public ClassCollection(Type ignoreAttribute, string path, bool loadRecursive)
            {
                IgnoreAttribute = ignoreAttribute;
                if (!string.IsNullOrEmpty(path))
                {
                    var files = new List<string>();
    
                    // Figure out which directory search we should do, this just makes life easier below.
                    SearchOption option = loadRecursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly;
    
                    // Unfortunately; it requires 2 calls to do this. As the GetFiles method doesn't support
                    // multiple search patterns.
                    files.AddRange(Directory.GetFiles(path, "*.dll", option));
                    //files.AddRange(Directory.GetFiles(path, "*.exe", option));
    
                    foreach (string s in files)
                    {
                        LoadClasses(s);
                    }
                }
            }
    
            /// <summary>
            /// The type of ignore attribute being used with this collection.
            /// </summary>
            public Type IgnoreAttribute { get; private set; }
    
            /// <summary>
            /// Loads any classes found that are a descendant of T in the specified assembly path.
            /// </summary>
            /// <param name="assemblyPath">The DLL or EXE path.</param>
            /// <returns>The number of classes loaded.</returns>
            public int LoadClasses(string assemblyPath)
            {
                int ret = 0;
    
                // Make sure the path is valid.
                if (!File.Exists(assemblyPath))
                {
                    throw new FileNotFoundException("Could not find the specified file", assemblyPath);
                }
    
                try
                {
                    Assembly asm = Assembly.LoadFrom(assemblyPath);
                    Type[] types = asm.GetTypes();
    
                    foreach (Type type in types)
                    {
                        // Check to make sure the type is even a class
                        // and also a descendant of T
                        if (!type.IsClass || !type.IsSubclassOf(typeof(T)))
                        {
                            continue;
                        }
                        // If we set the ignore attribute, make sure we take that into account here.
                        if (IgnoreAttribute != null && type.GetCustomAttributes(IgnoreAttribute, true).Length != 0)
                        {
                            continue;
                        }
    
                        var loaded = (T)Activator.CreateInstance(type);
    
                        // Note: Contains uses the .Equals under the hood. It's best that you implement your own
                        // equality methods for this to have the best results.
                        if (Contains(loaded))
                        {
                            continue;
                        }
                        Add(loaded);
                        ret++;
                    }
                }
                catch (BadImageFormatException)
                {
                    // We eat this one on purpose. If the assembly isn't a valid .NET assembly, this exception is thrown.
                    // Feel free to do extra work with it.
                }
                return ret;
            }
        }
    There ya go. A pretty much full Plugin class. (Can easily be ported to use an Interface instead of class!)

    Keep in mind; it checks the full inheritance chain, so if, for instance, you do something like the following;

    Bot <- GrindBot <- GrindingPvPBot

    Where each of the above are derivatives of their parent; GrindingPvPBot will obviously keep the inheritance from GrindBot and Bot (and it will be loaded!)

    That class supports full directory traversal searches for binaries (eg; it can search the entire 'Plugins' directory for available derivatives of whatever class you pass it), or loading of specific binaries, or even a specific class (by FQN and binary).

    Also note; that it's a descendant of List<T>, so you get all the goodies from that. (Full LINQ support, etc)

    Lastly; it also supports the usage of an ignore attribute. (If you wanted to tell the framework 'don't load my stuff' you could decorate it with an attribute such as [DoNotLoad] or whatever you may choose) Which is really nice for testing and development purposes.
    Last edited by Apoc; 10-05-2009 at 02:21 PM.

  6. #6
    lanman92's Avatar Active Member
    Reputation
    50
    Join Date
    Mar 2007
    Posts
    1,033
    Thanks G/R
    0/1
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the code, but I already got it workin'.

Similar Threads

  1. Need help with website and server
    By Ukrajinc in forum World of Warcraft Emulator Servers
    Replies: 0
    Last Post: 12-26-2007, 08:41 PM
  2. [Request + Help] Adding malls and teleports to there
    By frostyblade in forum World of Warcraft Emulator Servers
    Replies: 4
    Last Post: 12-26-2007, 01:37 PM
  3. Need help GM levels And changing commands will +rep
    By crazyc in forum World of Warcraft Emulator Servers
    Replies: 12
    Last Post: 11-30-2007, 01:11 PM
  4. Need help finding shrubs and bushes
    By blah7 in forum WoW ME Questions and Requests
    Replies: 3
    Last Post: 07-27-2007, 03:41 AM
  5. Few model changes. please help :) , tryed self and failed
    By luddo9 in forum WoW ME Questions and Requests
    Replies: 12
    Last Post: 07-04-2007, 12:32 PM
All times are GMT -5. The time now is 10:38 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2024 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search