<commit_before>extern alias MySqlConnectorAlias;

using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Threading;

using ACE.Common;

using Newtonsoft.Json;

namespace ACE.Server
{
    partial class Program
    {
        private static void CheckForWorldDatabaseUpdate()
        {
            log.Info($"Automatic World Database Update started...");
            var worldDb = new Database.WorldDatabase();
            var currentVersion = worldDb.GetVersion();
            log.Info($"Current World Database version: Base - {currentVersion.BaseVersion} | Patch - {currentVersion.PatchVersion}");

            var url = "https://api.github.com/repos/ACEmulator/ACE-World-16PY-Patches/releases";
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.UserAgent = "ACE.Server";

            var response = request.GetResponse();
            var reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8);
            var html = reader.ReadToEnd();
            reader.Close();
            response.Close();

            dynamic json = JsonConvert.DeserializeObject(html);
            string tag = json[0].tag_name;
            string dbURL = json[0].assets[0].browser_download_url;
            string dbFileName = json[0].assets[0].name;

            if (currentVersion.PatchVersion != tag)
            {
                log.Info($"Latest patch version is {tag} -- Update Required!");
                UpdateToLatestWorldDatabase(dbURL, dbFileName);
                var newVersion = worldDb.GetVersion();
                log.Info($"Updated World Database version: Base - {newVersion.BaseVersion} | Patch - {newVersion.PatchVersion}");
            }
            else
            {
                log.Info($"Latest patch version is {tag} -- No Update Required!");
            }

            log.Info($"Automatic World Database Update complete.");
        }

        private static void UpdateToLatestWorldDatabase(string dbURL, string dbFileName)
        {
            Console.WriteLine();

            if (IsRunningInContainer)
            {
                Console.WriteLine(" ");
                Console.WriteLine("This process will take a while, depending on many factors, and may look stuck while reading and importing the world database, please be patient! ");
                Console.WriteLine(" ");
            }

            Console.Write($"Downloading {dbFileName} .... ");
            using (var client = new WebClient())
            {
                try
                {
                    client.DownloadFile(dbURL, dbFileName);
                }
                catch
                {
                    Console.Write($"Download for {dbFileName} failed!");
                    return;
                }
            }
            Console.WriteLine("download complete!");

            Console.Write($"Extracting {dbFileName} .... ");
            ZipFile.ExtractToDirectory(dbFileName, ".", true);
            Console.WriteLine("extraction complete!");
            Console.Write($"Deleting {dbFileName} .... ");
            File.Delete(dbFileName);
            Console.WriteLine("Deleted!");

            var sqlFile = dbFileName.Substring(0, dbFileName.Length - 4);
            Console.Write($"Importing {sqlFile} into SQL server at {ConfigManager.Config.MySql.World.Host}:{ConfigManager.Config.MySql.World.Port} (This will take a while, please be patient) .... ");
            using (var sr = File.OpenText(sqlFile))
            {
                var sqlConnect = new MySql.Data.MySqlClient.MySqlConnection($"server={ConfigManager.Config.MySql.World.Host};port={ConfigManager.Config.MySql.World.Port};user={ConfigManager.Config.MySql.World.Username};password={ConfigManager.Config.MySql.World.Password}");

                var line = string.Empty;
                var completeSQLline = string.Empty;
                while ((line = sr.ReadLine()) != null)
                {
                    //do minimal amount of work here
                    if (line.EndsWith(";"))
                    {
                        completeSQLline += line + Environment.NewLine;

                        var script = new MySql.Data.MySqlClient.MySqlScript(sqlConnect, completeSQLline);
                        try
                        {
                            script.StatementExecuted += new MySql.Data.MySqlClient.MySqlStatementExecutedEventHandler(OnStatementExecutedOutputDot);
                            var count = script.Execute();
                        }
                        catch (MySql.Data.MySqlClient.MySqlException)
                        {

                        }
                        completeSQLline = string.Empty;
                    }
                    else
                        completeSQLline += line + Environment.NewLine;
                }
            }
            Console.WriteLine(" complete!");

            Console.Write($"Deleting {sqlFile} .... ");
            File.Delete(sqlFile);
            Console.WriteLine("Deleted!");
        }

        private static string GetContentFolder()
        {
            var sqlConnect = new MySql.Data.MySqlClient.MySqlConnection($"server={ConfigManager.Config.MySql.Shard.Host};port={ConfigManager.Config.MySql.Shard.Port};user={ConfigManager.Config.MySql.Shard.Username};password={ConfigManager.Config.MySql.Shard.Password};database={ConfigManager.Config.MySql.Shard.Database}");
            var sqlQuery = "SELECT `value` FROM config_properties_string WHERE `key` = 'content_folder';";
            var sqlCommand = new MySql.Data.MySqlClient.MySqlCommand(sqlQuery, sqlConnect);

            sqlConnect.Open();
            var sqlReader = sqlCommand.ExecuteReader();

            var content_folder = sqlReader.HasRows ? sqlReader.GetString(0) : @".\Content";

            sqlReader.Close();
            sqlCommand.Connection.Close();

            // handle relative path
            if (content_folder.StartsWith("."))
            {
                var cwd = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar;
                content_folder = cwd + content_folder;
            }

            return content_folder;
        }

        private static void AutoApplyWorldCustomizations()
        {
            var content_folder = GetContentFolder();

            Console.WriteLine($"Searching for World Customization SQL scripts .... ");

            var contentDI = new DirectoryInfo($"{content_folder}{Path.DirectorySeparatorChar}WorldCustomizations");

            if (contentDI.Exists)
            {
                foreach (var file in contentDI.GetFiles("*.sql").OrderBy(f => f.Name))
                {
                    Console.Write($"Found {file.Name} .... ");
                    var sqlDBFile = File.ReadAllText(file.FullName);<commit_msg>Fix read issue with GetContentFolder (#2980)<commit_after>extern alias MySqlConnectorAlias;

using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Threading;

using ACE.Common;

using Newtonsoft.Json;

namespace ACE.Server
{
    partial class Program
    {
        private static void CheckForWorldDatabaseUpdate()
        {
            log.Info($"Automatic World Database Update started...");
            var worldDb = new Database.WorldDatabase();
            var currentVersion = worldDb.GetVersion();
            log.Info($"Current World Database version: Base - {currentVersion.BaseVersion} | Patch - {currentVersion.PatchVersion}");

            var url = "https://api.github.com/repos/ACEmulator/ACE-World-16PY-Patches/releases";
            var request = (HttpWebRequest)WebRequest.Create(url);
            request.UserAgent = "ACE.Server";

            var response = request.GetResponse();
            var reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.UTF8);
            var html = reader.ReadToEnd();
            reader.Close();
            response.Close();

            dynamic json = JsonConvert.DeserializeObject(html);
            string tag = json[0].tag_name;
            string dbURL = json[0].assets[0].browser_download_url;
            string dbFileName = json[0].assets[0].name;

            if (currentVersion.PatchVersion != tag)
            {
                log.Info($"Latest patch version is {tag} -- Update Required!");
                UpdateToLatestWorldDatabase(dbURL, dbFileName);
                var newVersion = worldDb.GetVersion();
                log.Info($"Updated World Database version: Base - {newVersion.BaseVersion} | Patch - {newVersion.PatchVersion}");
            }
            else
            {
                log.Info($"Latest patch version is {tag} -- No Update Required!");
            }

            log.Info($"Automatic World Database Update complete.");
        }

        private static void UpdateToLatestWorldDatabase(string dbURL, string dbFileName)
        {
            Console.WriteLine();

            if (IsRunningInContainer)
            {
                Console.WriteLine(" ");
                Console.WriteLine("This process will take a while, depending on many factors, and may look stuck while reading and importing the world database, please be patient! ");
                Console.WriteLine(" ");
            }

            Console.Write($"Downloading {dbFileName} .... ");
            using (var client = new WebClient())
            {
                try
                {
                    client.DownloadFile(dbURL, dbFileName);
                }
                catch
                {
                    Console.Write($"Download for {dbFileName} failed!");
                    return;
                }
            }
            Console.WriteLine("download complete!");

            Console.Write($"Extracting {dbFileName} .... ");
            ZipFile.ExtractToDirectory(dbFileName, ".", true);
            Console.WriteLine("extraction complete!");
            Console.Write($"Deleting {dbFileName} .... ");
            File.Delete(dbFileName);
            Console.WriteLine("Deleted!");

            var sqlFile = dbFileName.Substring(0, dbFileName.Length - 4);
            Console.Write($"Importing {sqlFile} into SQL server at {ConfigManager.Config.MySql.World.Host}:{ConfigManager.Config.MySql.World.Port} (This will take a while, please be patient) .... ");
            using (var sr = File.OpenText(sqlFile))
            {
                var sqlConnect = new MySql.Data.MySqlClient.MySqlConnection($"server={ConfigManager.Config.MySql.World.Host};port={ConfigManager.Config.MySql.World.Port};user={ConfigManager.Config.MySql.World.Username};password={ConfigManager.Config.MySql.World.Password}");

                var line = string.Empty;
                var completeSQLline = string.Empty;
                while ((line = sr.ReadLine()) != null)
                {
                    //do minimal amount of work here
                    if (line.EndsWith(";"))
                    {
                        completeSQLline += line + Environment.NewLine;

                        var script = new MySql.Data.MySqlClient.MySqlScript(sqlConnect, completeSQLline);
                        try
                        {
                            script.StatementExecuted += new MySql.Data.MySqlClient.MySqlStatementExecutedEventHandler(OnStatementExecutedOutputDot);
                            var count = script.Execute();
                        }
                        catch (MySql.Data.MySqlClient.MySqlException)
                        {

                        }
                        completeSQLline = string.Empty;
                    }
                    else
                        completeSQLline += line + Environment.NewLine;
                }
            }
            Console.WriteLine(" complete!");

            Console.Write($"Deleting {sqlFile} .... ");
            File.Delete(sqlFile);
            Console.WriteLine("Deleted!");
        }

        private static string GetContentFolder()
        {
            var sqlConnect = new MySql.Data.MySqlClient.MySqlConnection($"server={ConfigManager.Config.MySql.Shard.Host};port={ConfigManager.Config.MySql.Shard.Port};user={ConfigManager.Config.MySql.Shard.Username};password={ConfigManager.Config.MySql.Shard.Password};database={ConfigManager.Config.MySql.Shard.Database}");
            var sqlQuery = "SELECT `value` FROM config_properties_string WHERE `key` = 'content_folder';";
            var sqlCommand = new MySql.Data.MySqlClient.MySqlCommand(sqlQuery, sqlConnect);

            sqlConnect.Open();
            var sqlReader = sqlCommand.ExecuteReader();

            var content_folder = "";

            if (sqlReader.HasRows)
            {
                while (sqlReader.Read())
                {
                    content_folder = sqlReader.GetString(0);
                    break;
                }
            }
            else
                content_folder = @".\Content";

            sqlReader.Close();
            sqlCommand.Connection.Close();

            // handle relative path
            if (content_folder.StartsWith("."))
            {
                var cwd = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar;
                content_folder = cwd + content_folder;
            }

            return content_folder;
        }

        private static void AutoApplyWorldCustomizations()
        {
            var content_folder = GetContentFolder();

            Console.WriteLine($"Searching for World Customization SQL scripts .... ");

            var contentDI = new DirectoryInfo($"{content_folder}{Path.DirectorySeparatorChar}WorldCustomizations");

            if (contentDI.Exists)
            {
                foreach (var file in contentDI.GetFiles("*.sql").OrderBy(f => f.Name))
                {
                    Console.Write($"Found {file.Name} .... ");
                    var sqlDBFile = File.ReadAllText(file.FullName);
{'fraction_non_alphanumeric': 0.10679334238159868, 'fraction_numerical': 0.0018572755196799772, 'mean_word_length': 1.7711797307996833, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5985862', 'n_tokens_mistral': 3463, 'n_tokens_neox': 3293, 'n_words': 679}