Example #1
0
    private void LoadAddons()
    {
        isLoading = true;
        Ready     = false;

        string[]     addonFolders = Directory.GetDirectories(addonsPath);
        List <Addon> loadedAddons = new List <Addon>();

        for (int i = 0; i < addonFolders.Length; i++)
        {
            try
            {
                string addonInfoText = File.ReadAllText($"{addonFolders[i]}/{addonInfoFile}");
                loadedAddons.Add(new Addon(addonFolders[i], AddonInfo.FromJSON(addonInfoText)));
            }
            catch (Exception e)
            {
                Debug.LogWarning(e);
                loadedAddons.Add(new Addon(addonFolders[i]));
            }
            finally
            {
                LoadAddon(loadedAddons[i]);
            }
        }

        addons = loadedAddons;
        Ready  = true;
    }
Example #2
0
        //! TODO Implement server side addon & banned addon handling
        public static void HandleAddonInfo(CharacterSession session, byte[] addonData)
        {
            var addonInfo       = new AddonInfo();
            var addonDataReader = new Packet(addonData, 0);

            var addons = addonDataReader.Read <uint>();

            for (var i = 0; i < addons; i++)
            {
                var addonName         = addonDataReader.Read <string>(0, true);
                var addonInfoProvided = addonDataReader.Read <bool>();
                var addonCRC          = addonDataReader.Read <uint>();
                var urlCRC            = addonDataReader.Read <uint>();

                Log.Message(LogType.Debug, "AddonData: Name '{0}', Info Provided '{1}', CRC '0x{2:X}', URL CRC '0x{3:X}'.",
                            addonName, addonInfoProvided, addonCRC, urlCRC);

                addonInfo.Addons.Add(new AddonInfoData
                {
                    InfoProvided = addonInfoProvided,
                    KeyProvided  = true,
                    KeyData      = addonPublicKey
                });
            }

            session.Send(addonInfo);
        }
Example #3
0
        //! TODO Implement server side addon & banned addon handling
        public static async void HandleAddonInfo(CharacterSession session, byte[] addonData)
        {
            var addonInfo       = new AddonInfo();
            var addonDataReader = new Packet(addonData, 0);

            var addons = addonDataReader.Read <uint>();

            for (var i = 0; i < addons; i++)
            {
                var addonName         = addonDataReader.ReadString();
                var addonInfoProvided = addonDataReader.Read <bool>();
                var addonCRC          = addonDataReader.Read <uint>();
                var urlCRC            = addonDataReader.Read <uint>();

                Log.Debug($"AddonData: Name '{addonName}', Info Provided '{addonInfoProvided}', CRC '0x{addonCRC:X}', URL CRC '0x{urlCRC:X}'.");

                addonInfo.Addons.Add(new AddonInfoData
                {
                    InfoProvided = addonInfoProvided,
                    KeyProvided  = true,
                    KeyData      = addonPublicKey
                });
            }

            await session.Send(addonInfo);
        }
Example #4
0
 /// <summary>
 /// Returns the value of an addon property as a string.
 /// </summary>
 /// <param name="info">the property that the module needs to access.</param>
 /// <returns></returns>
 public string GetAddonInfo(AddonInfo info)
 {
     return(Instance.CallFunction(
                new PythonFunction("getAddonInfo"),
                new List <object> {
         info.GetString()
     }
                ));
 }
Example #5
0
        public AddonAboutPageViewModel(AddonInfo addon) : base(DefaultManagementGroupName)
        {
            Glyph  = "\xE946";
            _addon = addon;
            Title  = Properties.Resources.AboutThisAddonText.Replace("{Name}", DisplayName);

            OpenHelpLink = new RelayCommand(() => ProcessHelper.StartNoThrow(_addon.HelpLink));
            Uninstall    = new RelayCommand(() => ProcessHelper.StartNoThrow("ms-settings:appsfeatures"));
        }
Example #6
0
        private void HandleAuthSession(IPacket packet)
        {
            Stream       dataStream  = packet.GetStream();
            BinaryReader r           = packet.CreateReader();
            uint         version     = r.ReadUInt32();
            uint         unk2        = r.ReadUInt32();
            string       accountName = r.ReadCString();
            uint         unk         = r.ReadUInt32();
            uint         clientSeed  = r.ReadUInt32();
            ulong        unk3        = r.ReadUInt64();
            uint         unk4        = r.ReadUInt32();
            ulong        unk5        = r.ReadUInt64();

            byte[] clientDigest = r.ReadBytes(20);

            session.Account = IoC.Resolve <IAccountRepository>().FindByName(accountName);

            cryptor.SetSymmetricAlgorithm(new WowCryptRC4(session.Account.SessionKey));

            if (!ByteArrayExtensions.Equals(clientDigest, ComputeServerDigest(clientSeed)))
            {
                throw new Exception();
            }

            session.Send(GetAuthResponcePkt());

            uint addonInfoBlockSize = r.ReadUInt32();

            dataStream = new InflaterInputStream(dataStream);             //дальше данные запакованы
            r          = new BinaryReader(dataStream);
            try {
                while (true)
                {
                    var addonInfo = new AddonInfo {
                        Name   = r.ReadCString(),
                        Crc    = r.ReadUInt64(),
                        Status = r.ReadByte(),
                    };
                    AddonManager.Instance[addonInfo.Name] = addonInfo;
                }
            }
            catch (Exception e) {
            }
            //_client.Send(GetAddonInfoPkt());
            session.Send(GetTutorialFlagsPkt());
            session.SendAccountDataTimes(0x15);
        }
        public List <AddonInfo> GetAddonInfo(IEnumerable <Dictionary <string, string> > metaData)
        {
            List <AddonInfo> result = new List <AddonInfo>();

            foreach (var addon in metaData)
            {
                AddonInfo newAddonInfo = null;

                //If the supplied data doesn't comply with the currently implementet standard for metadata, we skip the addon.
                try
                {
                    newAddonInfo = ConvertToAddonInfo(addon);
                }
                catch (Exception)
                {
                    continue;
                }

                result.Add(newAddonInfo);
            }

            return(result);
        }
        //Trims, verifies and converts all the data to the correct formats and returns an IAddonInfo.
        private AddonInfo ConvertToAddonInfo(Dictionary <string, string> addon)
        {
            ModelFactory factory = new ModelFactory();

            //potential metadata properties. Some might be null.
            addon.TryGetValue("Title", out string title);
            addon.TryGetValue("Description", out string description);
            addon.TryGetValue("Author", out string author);
            addon.TryGetValue("Interface", out string tmpInterface);
            addon.TryGetValue("Version", out string tmpVersion);
            addon.TryGetValue("DefaultState", out string defaultState);
            addon.TryGetValue("RequiredDeps", out string tmpRequiredDependencies);
            addon.TryGetValue("SavedVariables", out string tmpSavedVariables);
            addon.TryGetValue("X-Website", out string tmpWebsite);
            addon.TryGetValue("X-Email", out string email);
            addon.TryGetValue("X-Category", out string category);
            addon.TryGetValue("DirectoryPath", out string directoryPath);


            //Metadata key for descriptions varies between Notes or Description.
            if (description == null)
            {
                addon.TryGetValue("Notes", out description);
            }

            //make sure the version has the correct format.
            //some versions includes codenames like: "1.1.1 (Kangoroo)". Other are formattet differently, for examble: V1.1.1
            //this regex match would return "1.1.1"
            string @version = tmpVersion;
            //Version @version = null;
            //if (tmpVersion != null)
            //{
            //    string versionString = Regex.Match(tmpVersion, @"\d+(?:\.)\d+(?:\.)\d+").Value;

            //    int missingVersionNumbers = 3 - versionString.Split(',').Length;

            //    for (int i = missingVersionNumbers; i >= 0; i--)
            //        versionString += ".0";

            //    @version = new Version(Convert.ToInt32(versionString.Substring(0, 1)), Convert.ToInt32(versionString.Substring(1, 2)), Convert.ToInt32(versionString.Substring(3, 2))); ;
            //}

            Version @interface = null;

            if (tmpInterface != null)
            {
                for (int i = 0; i < 5 - tmpInterface.Length; i++)
                {
                    tmpInterface += '0';
                }

                @interface = new Version(Convert.ToInt32(tmpInterface.Substring(0, 1)), Convert.ToInt32(tmpInterface.Substring(1, 2)), Convert.ToInt32(tmpInterface.Substring(3, 2)));
            }

            //if there are any required dependencies/saved variables, seperate them by comma and insert into arrays.
            string[] requiredDependencies = null;
            string[] savedVariables       = null;

            if (tmpRequiredDependencies != null)
            {
                requiredDependencies = ReplaceWhitespace(tmpRequiredDependencies, "").Split(',');
            }

            if (tmpSavedVariables != null)
            {
                savedVariables = ReplaceWhitespace(tmpSavedVariables, "").Split(',');
            }

            Uri website;

            Uri.TryCreate(tmpWebsite, UriKind.Absolute, out website);

            AddonInfo newAddonInfo =
                factory.CreateAddonInfo(
                    title,
                    description,
                    author,
                    @interface,
                    version,
                    defaultState,
                    requiredDependencies,
                    savedVariables,
                    website,
                    email,
                    category,
                    directoryPath
                    );

            return(newAddonInfo);
        }
Example #9
0
 internal static string SerializeAddonInfoToString(AddonInfo addonInfo)
 {
     return(JsonSerializer.Serialize <AddonInfo>(addonInfo, SerializerOptions));
 }
 public void RemoveAddon(AddonInfo addon)
 {
     fileSystem.DeleteDirectory(addon.DirectoryPath);
 }
Example #11
0
 public void Init()
 {
     instance = new AddonInfo();
 }
 public static string ToJSON(AddonInfo info)
 {
     return(JsonUtility.ToJson(info));
 }
Example #13
0
        public void ReadAddonsInfo(byte[] data, int size)
        {
            uint Size = BitConverter.ToUInt32(data, 0);

            byte[] Data = new byte[size];
            Array.Copy(data, 4, Data, 0, size);

            if (Size == 0)
            {
                return;
            }

            if (Size > 0xFFFFF)
            {
                Log.outError("ReadAddonsInfo addon info too big, size {0}", size);
                return;
            }
            PacketReader addonInfo = new PacketReader(ZlibStream.UncompressBuffer(Data), false);

            if (addonInfo != null)
            {
                uint addonsCount = addonInfo.ReadUInt32();

                for (uint i = 0; i < addonsCount; ++i)
                {
                    // check next addon data format correctness
                    if ((addonInfo.BaseStream.Position) + 1 > addonInfo.BaseStream.Length)
                    {
                        return;
                    }

                    string addonName = addonInfo.ReadCString();
                    byte   enabled   = addonInfo.ReadByte();
                    uint   crc       = addonInfo.ReadUInt32();
                    uint   unk1      = addonInfo.ReadUInt32();

                    Log.outDebug("ADDON: Name: {0}, Enabled: 0x{1}, CRC: 0x{2}, Unknown2: 0x{3}", addonName, enabled, crc, unk1);

                    AddonInfo addon = new AddonInfo(addonName, enabled, crc, 2, true);

                    SavedAddon savedAddon = Addon.GetAddonInfo(addonName);
                    if (savedAddon != null)
                    {
                        bool match = true;

                        if (addon.CRC != savedAddon.CRC)
                        {
                            match = false;
                        }

                        if (!match)
                        {
                            Log.outWarn("ADDON: {0} was known, but didn't match known CRC (0x{1})!", addon.Name, savedAddon.CRC);
                        }
                    }
                    else
                    {
                        Addon.SaveAddon(addon);

                        Log.outWarn("ADDON: {0} (0x{1}) was not known, saving...", addon.Name, addon.CRC);
                    }

                    // TODO: Find out when to not use CRC/pubkey, and other possible states.
                    addonsList.Add(addon);
                }

                uint currentTime = addonInfo.ReadUInt32();
                Log.outDebug("ADDON: CurrentTime: {0}", currentTime);

                //if (addonInfo.rpos() != addonInfo.size())
                //sLog->outDebug(LOG_FILTER_NETWORKIO, "packet under-read!");
            }
            else
            {
                Log.outError("Addon packet uncompress error!");
            }
        }
Example #14
0
        internal static async Task <int> ExtractAddonFile(FileInfo file, DirectoryInfo folderOutput, bool warninvalid = false)
        {
            if (folderOutput == null)
            {
                folderOutput = new DirectoryInfo(Path.Combine(file.Directory.FullName, Path.GetFileNameWithoutExtension(file.FullName)));
            }

            if (!folderOutput.Exists)
            {
                folderOutput.Create();
            }

            using var gmadFileStream = file.OpenRead();

            Dictionary <string, Stream> files = new Dictionary <string, Stream>();

            var jsonFileInfo = new FileInfo(Path.Combine(folderOutput.FullName, "addon.json"));

            //in case of re-extraction, we don't want to overwrite a manually written json for whatever reason
            AddonInfo addonInfo = await OpenAddonInfo(jsonFileInfo) ?? new AddonInfo();

            bool success = await Addon.Extract(gmadFileStream, (relativeFilePath) =>
            {
                Console.WriteLine($"Extracting {relativeFilePath}");
                var outputFileInfo = new FileInfo(Path.Combine(folderOutput.FullName, relativeFilePath));

                //create the subfolder first

                outputFileInfo.Directory.Create();

                if (!outputFileInfo.FullName.StartsWith(folderOutput.FullName))
                {
                    throw new IOException($"Addon extraction somehow ended up outside main folder {outputFileInfo.FullName}, the relative path was {relativeFilePath}");
                }

                Stream fileStream = null;

                try
                {
                    fileStream = outputFileInfo.OpenWrite();
                    files.Add(relativeFilePath, fileStream);
                }
                catch (Exception)
                {
                    Console.WriteLine($"Could not open {relativeFilePath} for writing");
                }

                return(fileStream);
            }, addonInfo);

            foreach (var kv in files)
            {
                kv.Value.Dispose();
            }

            if (success)
            {
                SaveAddonInfo(jsonFileInfo, addonInfo);
            }

            return(Convert.ToInt32(!success));
        }
Example #15
0
        internal static async Task <int> CreateAddonFile(DirectoryInfo folder, FileInfo fileOutput, bool warninvalid = false)
        {
            if (fileOutput is null)
            {
                fileOutput = new FileInfo(folder.FullName + ".gma");
            }

            var jsonFileInfo = new FileInfo(Path.Combine(folder.FullName, "addon.json"));

            AddonInfo addonInfo = await OpenAddonInfo(jsonFileInfo);

            //open every file in the folder, then feed it as a string:stream dictionary
            Dictionary <string, Stream> files = new Dictionary <string, Stream>();

            foreach (var fileInput in folder.EnumerateFiles("*", SearchOption.AllDirectories))
            {
                //turn the file paths into relatives and also lowercase
                string relativeFilePath = Path.GetRelativePath(folder.FullName, fileInput.FullName).ToLower();

                relativeFilePath = relativeFilePath.Replace("\\", "/");


                //this could PROBABLY be streamlined in a Addon.IsIgnoreMatching function but for now I just want this to work

                if (Addon.IsWildcardMatching(relativeFilePath, Addon.DefaultIgnores))
                {
                    continue;
                }

                if (addonInfo.IgnoreWildcard != null && Addon.IsWildcardMatching(relativeFilePath, addonInfo.IgnoreWildcard))
                {
                    continue;
                }

                //if it's not ignored and still not allowed, throw out an error

                if (!Addon.IsPathAllowed(relativeFilePath))
                {
                    if (warninvalid)
                    {
                        Console.Error.WriteLine($"{relativeFilePath} \t\t[Not allowed by whitelist]");
                    }
                    return(1);
                }

                var fileInputStream = fileInput.OpenRead();

                files.Add(relativeFilePath, fileInputStream);
            }

            if (files.Count == 0)
            {
                Console.Error.WriteLine("No files found, can't continue!");
                return(1);
            }

            //now open the stream for the output
            bool success;

            using (var outputStream = fileOutput.OpenWrite())
            {
                success = await Addon.Create(files, outputStream, addonInfo);
            }

            foreach (var kv in files)
            {
                kv.Value?.Dispose();
            }

            if (success)
            {
                SaveAddonInfo(jsonFileInfo, addonInfo);
                Console.WriteLine($"Successfully saved to {fileOutput.FullName}");
            }

            return(Convert.ToInt32(!success));
        }
Example #16
0
 public Addon(AddonInfo info)
 {
     Setup(string.Empty, info);
 }
Example #17
0
        public static AddonInfo GetAddonInfo(string _AddonName, string _AddonFolderPath)
        {
            AddonInfo addonInfo = new AddonInfo(_AddonName);

            if (System.IO.Directory.Exists(_AddonFolderPath) == false || System.IO.File.Exists(_AddonFolderPath + "\\" + _AddonName + ".toc") == false)
            {
                return(null);
            }
            string[]      tocLines     = System.IO.File.ReadAllLines(_AddonFolderPath + "\\" + _AddonName + ".toc");
            List <string> startupFiles = new List <string>();

            foreach (var tocLine in tocLines)
            {
                try
                {
                    if (tocLine.StartsWith("##"))//SettingsLine
                    {
                        if (tocLine.StartsWith("## Version:"))
                        {
                            addonInfo.m_VersionString    = tocLine.SplitVF("## Version:").Last().Trim();
                            addonInfo.m_TOCVersionString = true;
                        }
                        else if (tocLine.StartsWith("## Dependencies:"))
                        {
                            string[] dependencies = tocLine.SplitVF("## Dependencies:").Last().Split(',');
                            foreach (var dependency in dependencies)
                            {
                                addonInfo.m_Dependencies.Add(dependency.Trim());
                            }
                        }
                        else if (tocLine.StartsWith("## RequiredDeps:"))
                        {
                            string[] dependencies = tocLine.SplitVF("## RequiredDeps:").Last().Split(',');
                            foreach (var dependency in dependencies)
                            {
                                addonInfo.m_Dependencies.Add(dependency.Trim());
                            }
                        }
                        else if (tocLine.StartsWith("## Dep"))
                        {
                            string[] dependencies = tocLine.Substring(tocLine.IndexOf(':') + 1).Split(',');
                            foreach (var dependency in dependencies)
                            {
                                addonInfo.m_Dependencies.Add(dependency.Trim());
                            }
                        }
                        else if (tocLine.StartsWith("## SavedVariables:"))
                        {
                            string[] dependencies = tocLine.SplitVF("## SavedVariables:").Last().Split(',');
                            foreach (var dependency in dependencies)
                            {
                                addonInfo.m_SavedVariables.Add(dependency.Trim());
                            }
                        }
                        else if (tocLine.StartsWith("## SavedVariablesPerCharacter:"))
                        {
                            string[] dependencies = tocLine.SplitVF("## SavedVariablesPerCharacter:").Last().Split(',');
                            foreach (var dependency in dependencies)
                            {
                                addonInfo.m_SavedVariablesPerCharacter.Add(dependency.Trim());
                            }
                        }
                        else if (tocLine.StartsWith("## Title:"))
                        {
                            addonInfo.m_AddonTitle = tocLine.SplitVF("## Title:").Last().Trim();
                            if (addonInfo.m_AddonTitle.Contains(" v") && addonInfo.m_VersionString == "")
                            {
                                string versionSplit = addonInfo.m_AddonTitle.SplitVF(" v").Last();
                                versionSplit = versionSplit.Split(' ').First();
                                if (versionSplit.Contains("."))
                                {
                                    string[] versionNrs      = versionSplit.Split('.');
                                    bool     isVersionString = true;
                                    foreach (string versionNr in versionNrs)
                                    {
                                        int versionInt;
                                        if (int.TryParse(versionNr, out versionInt) == false)
                                        {
                                            isVersionString = false;
                                            break;
                                        }
                                    }
                                    if (isVersionString == true)
                                    {
                                        addonInfo.m_VersionString = "#TocGuess# " + versionSplit;
                                    }
                                }
                            }
                        }
                        else if (tocLine.StartsWith("## Notes:"))
                        {
                            addonInfo.m_Notes = tocLine.Substring(tocLine.IndexOf(':') + 1);
                        }
                        else if (tocLine.StartsWith("## Notes"))
                        {
                            if (addonInfo.m_Notes == "")
                            {
                                addonInfo.m_Notes = tocLine.Substring(tocLine.IndexOf(':') + 1);
                            }
                        }
                        else if (tocLine.StartsWith("## Author:"))
                        {
                            addonInfo.m_Author = tocLine.Substring(tocLine.IndexOf(':') + 1);
                        }
                    }
                    else
                    {
                        startupFiles.Add(tocLine);
                    }
                }
                catch (Exception)
                {}
            }
            if (addonInfo.m_AddonName == "SW_Stats" && addonInfo.m_VersionString == "2.0 Beta")
            {
                if (System.IO.File.Exists(_AddonFolderPath + "\\neutral.lua") == true)
                {
                    var neutralFile = System.IO.File.ReadAllText(_AddonFolderPath + "\\neutral.lua");
                    if (neutralFile.Contains("SW_VERSION = \"2.0 Beta.7\"") == true)
                    {
                        addonInfo.m_VersionString = "2.0 Beta.7";
                    }
                }
            }
            if (addonInfo.m_VersionString == "")
            {
                string        lowerCaseAddonName = _AddonName.ToLower();
                List <string> addonFiles         = Utility.GetFilesInDirectory(_AddonFolderPath, "*.lua");
                var           addonFilesOrdered  = addonFiles.OrderBy((_Value) =>
                {
                    int findIndex = startupFiles.FindIndex((_File) => _File == _Value);
                    if (findIndex != -1)
                    {
                        return(findIndex);
                    }
                    return(startupFiles.Count + lowerCaseAddonName.LevenshteinDistance(_Value.ToLower()));
                });
                foreach (var addonFile in addonFilesOrdered)
                {
                    DateTime currLastWriteTime = System.IO.File.GetLastWriteTimeUtc(addonFile);
                    if (currLastWriteTime > addonInfo.m_NewestModificationDate)
                    {
                        addonInfo.m_NewestModificationDate = currLastWriteTime;
                    }
                    if (addonInfo.m_VersionString == "")
                    {
                        string[] fileLines = System.IO.File.ReadAllLines(_AddonFolderPath + "\\" + addonFile);
                        foreach (var fileLine in fileLines)
                        {
                            try
                            {
                                string currLineLowered = fileLine.ToLower();
                                if (currLineLowered.Contains("version") && currLineLowered.Contains(lowerCaseAddonName))
                                {
                                    string variableVersion = fileLine.Split('=').Last().SplitVF("--").First().Trim();
                                    while (variableVersion.EndsWith(";"))
                                    {
                                        variableVersion = variableVersion.Substring(0, variableVersion.Length - 1).Trim();
                                    }
                                    addonInfo.m_VersionString = "#LuaGuess# " + variableVersion.Replace("\"", "");
                                    break;
                                }
                            }
                            catch (Exception)
                            { }
                        }
                    }
                }
            }
            else
            {
                List <string> addonFiles = Utility.GetFilesInDirectory(_AddonFolderPath, "*.lua");
                foreach (var addonFile in addonFiles)
                {
                    DateTime currLastWriteTime = System.IO.File.GetLastWriteTimeUtc(addonFile);
                    if (currLastWriteTime > addonInfo.m_NewestModificationDate)
                    {
                        addonInfo.m_NewestModificationDate = currLastWriteTime;
                    }
                }
            }
            return(addonInfo);
        }
Example #18
0
 public Addon(string path, AddonInfo info)
 {
     Setup(path, info);
 }
Example #19
0
 public Addon(DirectoryCatalog catalog, AddonInfo info)
 {
     _catalog = catalog;
     _info    = info;
 }
Example #20
0
 private void Setup(string path, AddonInfo info)
 {
     this.path = path;
     info.Validate();
     this.info = info;
 }
Example #21
0
 /// <summary>
 /// Returns the value of an addon property as a string.
 /// </summary>
 /// <param name="info">the property that the module needs to access.</param>
 /// <returns></returns>
 public string GetAddonInfo(AddonInfo info)
 {
     return(Instance.CallFunction(_getAddonInfo, info.GetString()));
 }
Example #22
0
        internal static void SaveAddonInfo(FileInfo jsonFile, AddonInfo addonInfo)
        {
            using var fileStream = jsonFile.OpenWrite();

            JsonSerializer.SerializeAsync(fileStream, addonInfo, SerializerOptions);
        }