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; }
//! 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); }
//! 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); }
/// <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() } )); }
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")); }
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); }
internal static string SerializeAddonInfoToString(AddonInfo addonInfo) { return(JsonSerializer.Serialize <AddonInfo>(addonInfo, SerializerOptions)); }
public void RemoveAddon(AddonInfo addon) { fileSystem.DeleteDirectory(addon.DirectoryPath); }
public void Init() { instance = new AddonInfo(); }
public static string ToJSON(AddonInfo info) { return(JsonUtility.ToJson(info)); }
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!"); } }
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)); }
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)); }
public Addon(AddonInfo info) { Setup(string.Empty, info); }
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); }
public Addon(string path, AddonInfo info) { Setup(path, info); }
public Addon(DirectoryCatalog catalog, AddonInfo info) { _catalog = catalog; _info = info; }
private void Setup(string path, AddonInfo info) { this.path = path; info.Validate(); this.info = info; }
/// <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())); }
internal static void SaveAddonInfo(FileInfo jsonFile, AddonInfo addonInfo) { using var fileStream = jsonFile.OpenWrite(); JsonSerializer.SerializeAsync(fileStream, addonInfo, SerializerOptions); }