예제 #1
0
        private static void GetScripts(Config.Library libConfig,
                                       Hashtable list, string path, string type)
        {
            foreach (string dir in Directory.GetDirectories(path))
            {
                string baseName = Path.GetFileName(dir).ToLower();
                if (baseName == ".svn" || baseName == "_svn" ||
                    baseName == "_darcs" || baseName == ".git" ||
                    baseName == ".hg" || baseName == "cvs")
                {
                    continue;
                }

                GetScripts(libConfig, list, dir, type);
            }

            foreach (string filename in Directory.GetFiles(path, type))
            {
                /* XXX: pass relative filename only */
                if (libConfig == null || !libConfig.GetIgnoreSource(filename))
                {
                    list[filename] = File.GetLastWriteTime(filename);
                }
            }
        }
예제 #2
0
        private static Hashtable GetScripts(Config.Library libConfig,
                                            string type)
        {
            Hashtable list = new Hashtable();

            GetScripts(libConfig, list, libConfig.SourcePath.FullName, type);

            return(list);
        }
예제 #3
0
        private static CompilerResults CompileVBScripts(ICollection fileColl,
                                                        string assemblyFile,
                                                        Config.Library libConfig,
                                                        bool debug)
        {
            VBCodeProvider provider = new VBCodeProvider();
            ICodeCompiler  compiler = provider.CreateCompiler();

            string[] files = new string[fileColl.Count];
            fileColl.CopyTo(files, 0);

            Console.Write("{0}[VB,{1}", libConfig.Name, files.Length);

            CompilerResults results = compiler.CompileAssemblyFromFileBatch(new CompilerParameters(GetReferenceAssemblies(), assemblyFile, true), files);

            m_AdditionalReferences.Add(assemblyFile);

            if (results.Errors.Count > 0)
            {
                int errorCount = 0, warningCount = 0;

                foreach (CompilerError e in results.Errors)
                {
                    if (e.IsWarning)
                    {
                        ++warningCount;
                    }
                    else
                    {
                        ++errorCount;
                    }
                }

                Console.WriteLine();
                if (errorCount > 0)
                {
                    Console.WriteLine("failed ({0} errors, {1} warnings)", errorCount, warningCount);
                }
                else
                {
                    Console.WriteLine("done ({0} errors, {1} warnings)", errorCount, warningCount);
                }

                foreach (CompilerError e in results.Errors)
                {
                    Console.WriteLine(" - {0}: {1}: {2}: (line {3}, column {4}) {5}", e.IsWarning ? "Warning" : "Error", e.FileName, e.ErrorNumber, e.Line, e.Column, e.ErrorText);
                }
            }
            else
            {
                Console.Write("] ");
            }

            return(results);
        }
예제 #4
0
        private static void GetScripts(Config.Library libConfig,
                                       Hashtable list, string path, string type)
        {
            foreach (string dir in Directory.GetDirectories(path))
            {
                GetScripts(libConfig, list, dir, type);
            }

            foreach (string filename in Directory.GetFiles(path, type))
            {
                /* XXX: pass relative filename only */
                if (libConfig == null || !libConfig.GetIgnoreSource(filename))
                {
                    list[filename] = File.GetLastWriteTime(filename);
                }
            }
        }
예제 #5
0
        private static Hashtable GetScripts(Config.Library libConfig, IEnumerable overlays,
                                            string type)
        {
            Hashtable files = GetScripts(libConfig, type);

            if (overlays != null)
            {
                foreach (Config.Library overlay in overlays)
                {
                    Hashtable files2 = GetScripts(overlay, type);

                    Overlay(libConfig.SourcePath.FullName, files,
                            overlay.SourcePath.FullName, files2);
                }
            }

            return(files);
        }
예제 #6
0
        public Library(Config.Library libConfig, Assembly _assembly)
        {
            name     = libConfig.Name;
            assembly = _assembly;

            ArrayList typeList = new ArrayList();

            assembly.GetTypes();
            foreach (Type type in assembly.GetTypes())
            {
                if (libConfig == null || !libConfig.GetIgnoreType(type))
                {
                    typeList.Add(type);
                }
            }
            types = (Type[])typeList.ToArray(typeof(Type));

            typesByName     = new TypeTable(types.Length);
            typesByFullName = new TypeTable(types.Length);

            Type typeofTypeAliasAttribute = typeof(TypeAliasAttribute);

            foreach (Type type in types)
            {
                typesByName.Add(type.Name, type);
                typesByFullName.Add(type.FullName, type);

                if (type.IsDefined(typeofTypeAliasAttribute, false))
                {
                    object[] attrs = type.GetCustomAttributes(typeofTypeAliasAttribute, false);

                    if (attrs != null && attrs.Length > 0 && attrs[0] != null)
                    {
                        TypeAliasAttribute attr = attrs[0] as TypeAliasAttribute;
                        foreach (string alias in attr.Aliases)
                        {
                            typesByFullName.Add(alias, type);
                        }
                    }
                }
            }

            typeCache = new TypeCache(types, typesByName, typesByFullName);
        }
예제 #7
0
        private static ArrayList SortLibrariesByDepends()
        {
            ArrayList libs  = new ArrayList(Core.Config.Libraries);
            Hashtable queue = new Hashtable();
            ArrayList dst   = new ArrayList();

            /* handle "./Scripts/" first, for most compatibility */
            Config.Library libConfig = Core.Config.GetLibrary("legacy");
            if (libConfig != null)
            {
                EnqueueLibrary(dst, libs, queue, libConfig);
            }

            while (libs.Count > 0)
            {
                EnqueueLibrary(dst, libs, queue, (Config.Library)libs[0]);
            }

            return(dst);
        }
예제 #8
0
        private void Load()
        {
            document = new XmlDocument();
            m_DataDirectories = new ArrayList();

            if (Exists) {
                XmlTextReader reader = new XmlTextReader(filename);
                try {
                    document.Load(reader);
                } finally {
                    reader.Close();
                }
            } else {
                document.AppendChild(document.CreateElement("sunuo-config"));
            }

            // section "global"
            XmlElement global = GetConfiguration("global");
            if (global != null) {
                foreach (XmlNode node in global.ChildNodes) {
                    if (node.NodeType != XmlNodeType.Element)
                        continue;

                    XmlElement el = (XmlElement)node;

                    switch (node.Name) {
                    case "server-name":
                        serverName = el.InnerText;
                        break;

                    case "multi-threading":
                        m_Features[node.Name]
                            = Parser.ParseBool(el.GetAttribute("value"), true);
                        break;

                    case "feature":
                        m_Features[el.GetAttribute("name")]
                            = Parser.ParseBool(el.GetAttribute("value"), true);
                        break;

                    default:
                        log.WarnFormat("Invalid element global/{0}", node.Name);
                        break;
                    }
                }
            }

            // section "locations"
            XmlElement locations = GetConfiguration("locations");
            foreach (XmlNode node in locations.ChildNodes) {
                XmlElement el = node as XmlElement;
                if (el != null) {
                    string path = el.InnerText;
                    switch (el.Name) {
                    case "config-dir":
                        m_ConfigDirectory = path;
                        break;

                    case "save-dir":
                        m_SaveDirectory = path;
                        break;

                    case "backup-dir":
                        m_BackupDirectory = path;
                        break;

                    case "data-path":
                        if (Directory.Exists(path))
                            m_DataDirectories.Add(path);
                        break;

                    case "log-dir":
                        m_LogDirectory = path;
                        break;

                    case "cache-dir":
                        m_CacheDirectory = path;
                        break;

                    default:
                        log.WarnFormat("Ignoring unknown location tag in {0}: {1}",
                                       filename, el.Name);
                        break;
                    }
                }
            }

            // section "libraries"
            XmlElement librariesEl = GetConfiguration("libraries");
            foreach (XmlElement el in librariesEl.GetElementsByTagName("library")) {
                string name = el.GetAttribute("name");
                if (name == null || name == "") {
                    log.Warn("library element without name attribute");
                    continue;
                }

                name = name.ToLower();

                Library libConfig = (Library)libraryConfig[name];
                if (libConfig == null)
                    libraryConfig[name] = libConfig = new Library(name);

                libConfig.Load(el);
            }

            if (!libraryConfig.ContainsKey("legacy"))
                libraryConfig["legacy"] = new Library("legacy");

            // section "network"
            XmlElement networkEl = GetConfiguration("network");
            m_Network = networkEl == null
                ? new Network()
                : new Network(networkEl);

            // section "login"
            XmlElement loginEl = GetConfiguration("login");
            loginConfig = loginEl == null
                ? new Login()
                : new Login(loginEl);

            // section "server-list"
            XmlElement serverListEl = GetConfiguration("server-list");
            if (serverListEl != null)
                gameServers = new GameServerList(serverListEl);
        }
예제 #9
0
        private void Defaults()
        {
            Library coreConfig = new Library("core");
            libraryConfig["core"] = coreConfig;

            DirectoryInfo local = new DirectoryInfo(BaseDirectory)
                .CreateSubdirectory("local");

            /* find source libraries in ./local/src/ */
            DirectoryInfo src = local
                .CreateSubdirectory("src");
            foreach (DirectoryInfo sub in src.GetDirectories()) {
                string libName = sub.Name.ToLower();
                if (libraryConfig.ContainsKey(libName)) {
                    log.WarnFormat("duplicate library '{0}' in '{1}'",
                                   libName, sub.FullName);
                    continue;
                }

                libraryConfig[libName] = new Library(libName, sub);
            }

            /* find binary libraries in ./local/lib/ */
            DirectoryInfo lib = local
                .CreateSubdirectory("lib");
            foreach (FileInfo libFile in lib.GetFiles("*.dll")) {
                string fileName = libFile.Name;
                string libName = fileName.Substring(0, fileName.Length - 4).ToLower();
                if (libraryConfig.ContainsKey(libName)) {
                    log.WarnFormat("duplicate library '{0}' in '{1}'",
                                   libName, libFile);
                    continue;
                }

                libraryConfig[libName] = new Library(libName, libFile);
            }

            /* if the 'legacy' library was not found until now, load
               the legacy scripts from ./Scripts/ */
            if (!libraryConfig.ContainsKey("legacy")) {
                DirectoryInfo legacy = new DirectoryInfo(Path.Combine(BaseDirectory,
                                                                      "Scripts"));
                if (legacy.Exists) {
                    Library legacyConfig = new Library("legacy", legacy);
                    libraryConfig[legacyConfig.Name] = legacyConfig;
                }
            }
        }
예제 #10
0
        public static bool Compile(bool debug)
        {
            if (m_AdditionalReferences != null)
            {
                throw new ApplicationException("already compiled");
            }

            m_AdditionalReferences = new ArrayList();

            libraries = new ArrayList();
            libraries.Add(new Library(Core.Config.GetLibrary("core"),
                                      Core.Assembly));
            m_AdditionalReferences.Add(Core.ExePath);

            /* prepare overlays */
            foreach (Config.Library libConfig in Core.Config.Libraries)
            {
                if (libConfig.Overlays == null || !libConfig.Exists ||
                    libConfig.Name == "core")
                {
                    continue;
                }

                if (libConfig.SourcePath == null)
                {
                    log.Error(String.Format("Can't overlay the binary library {0}",
                                            libConfig.Name));
                    throw new ApplicationException();
                }

                foreach (string name in libConfig.Overlays)
                {
                    Config.Library overlay = Core.Config.GetLibrary(name);
                    if (overlay == null || !overlay.Exists)
                    {
                        log.Error(String.Format("Can't overlay {0} with {1}, because it does not exist",
                                                libConfig.Name, name));
                        throw new ApplicationException();
                    }

                    if (overlay.SourcePath == null)
                    {
                        log.Error(String.Format("Can't overlay {0} with {1}, because it is binary only",
                                                libConfig.Name, overlay.Name));
                        throw new ApplicationException();
                    }

                    overlay.Disabled = true;
                }
            }

            foreach (Config.Library libConfig in Core.Config.Libraries)
            {
                if (libConfig.Overlays != null && libConfig.Exists &&
                    libConfig.Name != "core" && libConfig.Disabled)
                {
                    log.Error(String.Format("Can't overlay library {0} which is already used as overlay for another library",
                                            libConfig.Name));
                    throw new ApplicationException();
                }
            }

            /* collect Config.Library objects, sort them and compile */
            ArrayList libConfigs = SortLibrariesByDepends();

            foreach (Config.Library libConfig in libConfigs)
            {
                bool result = Compile(libConfig, debug);
                if (!result)
                {
                    return(false);
                }
            }

            /* delete unused cache directories */
            DirectoryInfo cacheDir = Core.CacheDirectoryInfo
                                     .CreateSubdirectory("lib");

            foreach (DirectoryInfo sub in cacheDir.GetDirectories())
            {
                string libName = sub.Name.ToLower();
                if (GetLibrary(libName) == null)
                {
                    sub.Delete(true);
                }
            }

            /* done */
            return(true);
        }
예제 #11
0
        /**
         * enqueue a library for compilation, resolving all
         * dependencies first
         *
         * @param dst this array will receive the libraries in the correct order
         * @param libs source libraries
         * @param queue somewhat like a stack of libraries currently waiting
         * @param libConfig the library to be added
         */
        private static void EnqueueLibrary(ArrayList dst, ArrayList libs,
                                           Hashtable queue, Config.Library libConfig)
        {
            string[] depends = libConfig.Depends;

            if (libConfig.Name == "core" || libConfig.Disabled)
            {
                libs.Remove(libConfig);
                return;
            }

            if (!libConfig.Exists)
            {
                libs.Remove(libConfig);
                log.Warn(String.Format("library {0} does not exist", libConfig.Name));
                return;
            }

            /* first resolve dependencies */
            if (depends != null)
            {
                queue[libConfig.Name] = 1;

                foreach (string depend in depends)
                {
                    /* if the depended library is already in the
                     * queue, there is a circular dependency */
                    if (queue.ContainsKey(depend))
                    {
                        log.Error(String.Format("Circular library dependency {0} on {1}",
                                                libConfig.Name, depend));
                        throw new ApplicationException();
                    }

                    Config.Library next = Core.Config.GetLibrary(depend);
                    if (next == null || !next.Exists)
                    {
                        log.Error(String.Format("Unresolved library dependency: {0} depends on {1}, which does not exist",
                                                libConfig.Name, depend));
                        throw new ApplicationException();
                    }

                    if (next.Disabled)
                    {
                        log.Error(String.Format("Unresolved library dependency: {0} depends on {1}, which is disabled",
                                                libConfig.Name, depend));
                        throw new ApplicationException();
                    }

                    if (!dst.Contains(next))
                    {
                        EnqueueLibrary(dst, libs, queue, next);
                    }
                }

                queue.Remove(libConfig.Name);
            }

            /* then add it to 'dst' */
            dst.Add(libConfig);
            libs.Remove(libConfig);
        }
예제 #12
0
        private static bool Compile(Config.Library libConfig,
                                    bool debug)
        {
            /* check if there is source code for this library */
            if (libConfig.SourcePath == null)
            {
                if (libConfig.BinaryPath == null)
                {
                    log.Warn(String.Format("library {0} does not exist",
                                           libConfig.Name));
                    return(true);
                }
                else if (!libConfig.BinaryPath.Exists)
                {
                    log.Warn(String.Format("library {0} does not exist: {1}",
                                           libConfig.Name, libConfig.BinaryPath));
                    return(false);
                }

                log.Info(String.Format("Loading library {0}", libConfig.Name));
                libraries.Add(new Library(libConfig,
                                          Assembly.LoadFrom(libConfig.BinaryPath.FullName)));
                m_AdditionalReferences.Add(libConfig.BinaryPath.FullName);
                return(true);
            }
            else if (!libConfig.SourcePath.Exists)
            {
                log.Warn(String.Format("library {0} does not exist",
                                       libConfig.Name));
                return(true);
            }

            DirectoryInfo cache = Core.CacheDirectoryInfo
                                  .CreateSubdirectory("lib")
                                  .CreateSubdirectory(libConfig.Name);

            if (!cache.Exists)
            {
                log.Error(String.Format("Failed to create directory {0}", cache.FullName));
                return(false);
            }

            ArrayList overlays = null;

            if (libConfig.Overlays != null)
            {
                overlays = new ArrayList();
                foreach (string name in libConfig.Overlays)
                {
                    overlays.Add(Core.Config.GetLibrary(name));
                }
            }

            string    csFile = Path.Combine(cache.FullName, libConfig.Name + ".dll");
            Hashtable files  = GetScripts(libConfig, overlays, "*.cs");

            if (files.Count > 0)
            {
                string stampFile = Path.Combine(cache.FullName, libConfig.Name + ".stm");
                if (File.Exists(csFile) && CheckStamps(files, stampFile))
                {
                    libraries.Add(new Library(libConfig, Assembly.LoadFrom(csFile)));
                    m_AdditionalReferences.Add(csFile);
                    log.Info(String.Format("Loaded binary library {0}", libConfig.Name));
                }
                else
                {
                    /* work around a serious faction bug: the factions
                     * code (Reflector.cs) assumes alphabetical
                     * directory entry order; simulate this by sorting
                     * the array. See my bug report:
                     * http://www.runuo.com/forum/showthread.php?p=373540 */
                    ArrayList sorted = new ArrayList(files.Keys);
                    sorted.Sort();

                    CompilerResults results = CompileCSScripts(sorted,
                                                               csFile,
                                                               libConfig,
                                                               debug);
                    if (results != null)
                    {
                        if (results.Errors.HasErrors)
                        {
                            return(false);
                        }
                        libraries.Add(new Library(libConfig, results.CompiledAssembly));
                        WriteStampFile(stampFile, files);
                    }
                }
            }

            string vbFile = Path.Combine(cache.FullName, libConfig.Name + "-vb.dll");

            files = GetScripts(libConfig, overlays, "*.vb");
            if (files.Count > 0)
            {
                string stampFile = Path.Combine(cache.FullName, libConfig.Name + "-vb.stm");
                if (File.Exists(vbFile) && CheckStamps(files, stampFile))
                {
                    libraries.Add(new Library(libConfig,
                                              Assembly.LoadFrom(vbFile)));
                    m_AdditionalReferences.Add(vbFile);
                    Console.Write("{0}/VB. ", libConfig.Name);
                }
                else
                {
                    /* workaround again */
                    ArrayList sorted = new ArrayList(files.Keys);
                    sorted.Sort();

                    CompilerResults results = CompileVBScripts(sorted, vbFile,
                                                               libConfig,
                                                               debug);
                    if (results != null)
                    {
                        if (results.Errors.HasErrors)
                        {
                            return(false);
                        }
                        libraries.Add(new Library(libConfig,
                                                  results.CompiledAssembly));
                    }
                }
            }

            return(true);
        }
예제 #13
0
        private static CompilerResults CompileCSScripts(ICollection fileColl,
                                                        string assemblyFile,
                                                        Config.Library libConfig,
                                                        bool debug)
        {
            CSharpCodeProvider provider = new CSharpCodeProvider();
            ICodeCompiler      compiler = provider.CreateCompiler();

            string[] files;

            log.Info(String.Format("Compiling library {0}, {1} C# sources",
                                   libConfig.Name, fileColl.Count));

            string tempFile = compiler.GetType().FullName == "Mono.CSharp.CSharpCodeCompiler"
                                ? Path.GetTempFileName() : null;

            if (tempFile == String.Empty)
            {
                tempFile = null;
            }
            if (tempFile == null)
            {
                files = new string[fileColl.Count];
                fileColl.CopyTo(files, 0);
            }
            else
            {
                /* to prevent an "argument list too long" error, we
                 * write a list of file names to a temporary file
                 * and add them with @filename */
                StreamWriter w = new StreamWriter(tempFile, false);
                foreach (string file in fileColl)
                {
                    w.Write("\"" + file + "\" ");
                }
                w.Close();

                files = new string[0];
            }

            CompilerParameters parms = new CompilerParameters(GetReferenceAssemblies(), assemblyFile, debug);

            if (tempFile != null)
            {
                parms.CompilerOptions += "@" + tempFile;
            }

            if (libConfig.WarningLevel >= 0)
            {
                parms.WarningLevel = libConfig.WarningLevel;
            }

            CompilerResults results = null;

            try {
                results = compiler.CompileAssemblyFromFileBatch(parms, files);
            } catch (System.ComponentModel.Win32Exception e) {
                /* from WinError.h:
                 * #define ERROR_FILE_NOT_FOUND 2L
                 * #define ERROR_PATH_NOT_FOUND 3L
                 */
                if (e.NativeErrorCode == 2 || e.NativeErrorCode == 3)
                {
                    log.Fatal("Could not find the compiler - are you sure MCS is installed?");
                    log.Info("On Debian, try: apt-get install mono-mcs");
                    Environment.Exit(2);
                }
                else
                {
                    throw e;
                }
            }

            if (tempFile != null)
            {
                File.Delete(tempFile);
            }

            m_AdditionalReferences.Add(assemblyFile);

            if (results.Errors.Count > 0)
            {
                int errorCount = 0, warningCount = 0;

                foreach (CompilerError e in results.Errors)
                {
                    if (e.IsWarning)
                    {
                        ++warningCount;
                    }
                    else
                    {
                        ++errorCount;
                    }
                }

                if (errorCount > 0)
                {
                    log.Error(String.Format("Compilation failed ({0} errors, {1} warnings)", errorCount, warningCount));
                }
                else
                {
                    log.Info(String.Format("Compilation complete ({0} warnings)", warningCount));
                }

                foreach (CompilerError e in results.Errors)
                {
                    String msg = String.Format("{0}: {1}: (line {2}, column {3}) {4}",
                                               e.FileName, e.ErrorNumber, e.Line, e.Column, e.ErrorText);
                    if (e.IsWarning)
                    {
                        log.Warn(msg);
                    }
                    else
                    {
                        log.Error(msg);
                    }
                }
            }
            else
            {
                log.Info("Compilation complete");
            }

            return(results);
        }
예제 #14
0
        private static CompilerResults CompileVBScripts(ICollection fileColl,
                                                        string assemblyFile,
                                                        Config.Library libConfig,
                                                        bool debug)
        {
            VBCodeProvider provider = new VBCodeProvider();
            ICodeCompiler  compiler = provider.CreateCompiler();

            string[] files = new string[fileColl.Count];
            fileColl.CopyTo(files, 0);

            log.InfoFormat("Compiling library {0}, {1} C# sources",
                           libConfig.Name, files.Length);

            CompilerResults results = compiler.CompileAssemblyFromFileBatch(new CompilerParameters(GetReferenceAssemblies(), assemblyFile, true), files);

            m_AdditionalReferences.Add(assemblyFile);

            if (results.Errors.Count > 0)
            {
                int errorCount = 0, warningCount = 0;

                foreach (CompilerError e in results.Errors)
                {
                    if (e.IsWarning)
                    {
                        ++warningCount;
                    }
                    else
                    {
                        ++errorCount;
                    }
                }

                if (errorCount > 0)
                {
                    log.ErrorFormat("Compilation failed ({0} errors, {1} warnings)",
                                    errorCount, warningCount);
                }
                else
                {
                    log.InfoFormat("Compilation complete ({0} warnings)", warningCount);
                }

                foreach (CompilerError e in results.Errors)
                {
                    String msg = String.Format("{0}: {1}: (line {2}, column {3}) {4}",
                                               e.FileName, e.ErrorNumber, e.Line, e.Column, e.ErrorText);
                    if (e.IsWarning)
                    {
                        log.Warn(msg);
                    }
                    else
                    {
                        log.Error(msg);
                    }
                }
            }
            else
            {
                log.Info("Compilation complete");
            }

            return(results);
        }