<commit_before>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

using NLua;
using NLua.Exceptions;

namespace Oxide
{
    /// <summary>
    /// Represents a plugin that modifies server behaviour in some way
    /// </summary>
    public class Plugin
    {
        public string Name { get; private set; }
        public string Title { get; private set; }
        public string Description { get; private set; }
        public string Author { get; private set; }
        public string Version { get; private set; }
        public string Filename { get; private set; }
        public string ShortFilename { get; private set; }
        public Lua LuaInstance { get; private set; }

        private LuaTable table;
        private Dictionary<string, LuaFunction> functionmap;
        private bool incall;

        /// <summary>
        /// Gets the currently active plugin (NOT THREADSAFE)
        /// </summary>
        public static Plugin CurrentPlugin { get; private set; }

        /// <summary>
        /// Returns the Lua table associated with this plugin
        /// </summary>
        public LuaTable Table
        {
            get
            {
                return table;
            }
        }

        public Plugin(Lua lua)
        {
            // Store the lua instance
            LuaInstance = lua;
        }

        /// <summary>
        /// Loads this plugin from file
        /// </summary>
        /// <param name="filename"></param>
        public bool Load(string filename)
        {
            // Store filename
            Filename = filename;
            ShortFilename = Path.GetFileName(filename);
            Name = Path.GetFileNameWithoutExtension(filename);

            // Check it exists
            if (!File.Exists(filename))
            {
                Logger.Error(string.Format("Failed to load plugin {0} (file not found)", Name));
                return false;
            }

            // Load it
            string script = File.ReadAllText(filename);

            // Attempt to compile
            LuaFunction func;
            try
            {
                func = LuaInstance.LoadString(script, ShortFilename);
            }
            catch (LuaScriptException ex)
            {
                Logger.Error(string.Format("Failed to load plugin {0}", Name), ex);
                return false;
            }

            // Create the plugin table
            LuaFunction createplugin = LuaInstance["createplugin"] as LuaFunction;
            if (createplugin == null) return false;
            table = createplugin.Call()[0] as LuaTable;
            table["Name"] = Name;
            table["Filename"] = filename;
            LuaInstance["PLUGIN"] = table;

            // Attempt to call
            try
            {
                func.Call();
            }
            catch (LuaScriptException ex)
            {
                Logger.Error(string.Format("Failed to load plugin {0}", Name), ex);
                return false;
            }
            LuaInstance["PLUGIN"] = null;

            // Get all functions
            functionmap = new Dictionary<string, LuaFunction>();
            foreach (var key in table.Keys)
            {
                if (key is string)
                {
                    var value = table[key];
                    if (value is LuaFunction)
                        functionmap.Add((string)key, value as LuaFunction);
                }
            }

            // Get base functions
            LuaTable metatable = (LuaInstance["getmetatable"] as LuaFunction).Call(table)[0] as LuaTable;
            if (metatable != null)
            {
                LuaTable basetable = metatable["__index"] as LuaTable;
                foreach (var key in basetable.Keys)
                {
                    if (key is string)
                    {
                        var value = basetable[key];
                        if (value is LuaFunction)
                            functionmap.Add((string)key, value as LuaFunction);
                    }
                }
            }

            // Check plugin descriptors
            if (!(table["Title"] is string))
            {
                Logger.Error(string.Format("Failed to load plugin {0} (invalid 'Title')", Name));
                return false;
            }
            if (!(table["Description"] is string))
            {
                Logger.Error(string.Format("Failed to load plugin {0} (invalid 'Description')", Name));
                return false;
            }
            if (!(table["Version"] is string))
            {
                Logger.Error(string.Format("Failed to load plugin {0} (invalid 'Version')", Name));
                return false;
            }
            if (!(table["Author"] is string))<commit_msg>Stops http://forum.rustoxide.com/threads/an-element-with-the-same-key-already-exists-in-the-dictionary.2073/ error from not loading plugin.<commit_after>﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

using NLua;
using NLua.Exceptions;

namespace Oxide
{
    /// <summary>
    /// Represents a plugin that modifies server behaviour in some way
    /// </summary>
    public class Plugin
    {
        public string Name { get; private set; }
        public string Title { get; private set; }
        public string Description { get; private set; }
        public string Author { get; private set; }
        public string Version { get; private set; }
        public string Filename { get; private set; }
        public string ShortFilename { get; private set; }
        public Lua LuaInstance { get; private set; }

        private LuaTable table;
        private Dictionary<string, LuaFunction> functionmap;
        private bool incall;

        /// <summary>
        /// Gets the currently active plugin (NOT THREADSAFE)
        /// </summary>
        public static Plugin CurrentPlugin { get; private set; }

        /// <summary>
        /// Returns the Lua table associated with this plugin
        /// </summary>
        public LuaTable Table
        {
            get
            {
                return table;
            }
        }

        public Plugin(Lua lua)
        {
            // Store the lua instance
            LuaInstance = lua;
        }

        /// <summary>
        /// Loads this plugin from file
        /// </summary>
        /// <param name="filename"></param>
        public bool Load(string filename)
        {
            // Store filename
            Filename = filename;
            ShortFilename = Path.GetFileName(filename);
            Name = Path.GetFileNameWithoutExtension(filename);

            // Check it exists
            if (!File.Exists(filename))
            {
                Logger.Error(string.Format("Failed to load plugin {0} (file not found)", Name));
                return false;
            }

            // Load it
            string script = File.ReadAllText(filename);

            // Attempt to compile
            LuaFunction func;
            try
            {
                func = LuaInstance.LoadString(script, ShortFilename);
            }
            catch (LuaScriptException ex)
            {
                Logger.Error(string.Format("Failed to load plugin {0}", Name), ex);
                return false;
            }

            // Create the plugin table
            LuaFunction createplugin = LuaInstance["createplugin"] as LuaFunction;
            if (createplugin == null) return false;
            table = createplugin.Call()[0] as LuaTable;
            table["Name"] = Name;
            table["Filename"] = filename;
            LuaInstance["PLUGIN"] = table;

            // Attempt to call
            try
            {
                func.Call();
            }
            catch (LuaScriptException ex)
            {
                Logger.Error(string.Format("Failed to load plugin {0}", Name), ex);
                return false;
            }
            LuaInstance["PLUGIN"] = null;

            // Get all functions
            functionmap = new Dictionary<string, LuaFunction>();
            foreach (var key in table.Keys)
            {
                if (key is string)
                {
                    var value = table[key];
                    if (value is LuaFunction)
                    {
                        try
                        {
                            
                            functionmap.Add((string)key, value as LuaFunction);
                        }
                        catch (Exception e)
                        {
                            Logger.Error(string.Format("Failed to map function {0} in {1} table.Keys", (string)key, Name));
                        }
                    }
                    
                }
            }

            // Get base functions
            LuaTable metatable = (LuaInstance["getmetatable"] as LuaFunction).Call(table)[0] as LuaTable;
            if (metatable != null)
            {
                LuaTable basetable = metatable["__index"] as LuaTable;
                foreach (var key in basetable.Keys)
                {
                    if (key is string)
                    {
                        var value = basetable[key];
                        if (value is LuaFunction)
                        {
                            try
                            {
                                
                                functionmap.Add((string)key, value as LuaFunction);
                            }
                            catch (Exception e)
                            {
                                Logger.Error(string.Format("Failed to map function {0} in {1} metatable", (string)key, Name));
                            }
                        }
                    }
                }
            }

            // Check plugin descriptors
            if (!(table["Title"] is string))
            {
                Logger.Error(string.Format("Failed to load plugin {0} (invalid 'Title')", Name));
                return false;
            }
            if (!(table["Description"] is string))
            {
                Logger.Error(string.Format("Failed to load plugin {0} (invalid 'Description')", Name));
                return false;
            }
            if (!(table["Version"] is string))
            {
                Logger.Error(string.Format("Failed to load plugin {0} (invalid 'Version')", Name));
                return false;
            }
            if (!(table["Author"] is string))
{'fraction_non_alphanumeric': 0.09410324039186134, 'fraction_numerical': 0.002260738507912585, 'mean_word_length': 1.2295254094918102, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6448687', 'n_tokens_mistral': 2547, 'n_tokens_neox': 2416, 'n_words': 729}