public virtual async Task <ICollection <Assembly> > LoadPluginAssembliesAsync() { var assemblyList = new List <Assembly>(); foreach (var file in Directory.GetFiles(m_PluginsDirectory, "*.dll")) { try { using var stream = File.Open(file, FileMode.Open); var data = new byte[stream.Length]; await stream.ReadAsync(data, 0, (int)stream.Length); var pluginAssembly = Hotloader.LoadAssembly(data); var pluginMetadata = pluginAssembly.GetCustomAttribute <PluginMetadataAttribute>(); if (pluginMetadata == null) { // not a plugin, but could be a library continue; } assemblyList.Add(pluginAssembly); } catch (Exception ex) { m_Logger.LogWarning(ex, $"Failed to load plugin metadata from file: {file}"); } } return(assemblyList); }
public virtual async Task <ICollection <Assembly> > LoadPluginAssembliesAsync() { var assemblyList = new List <Assembly>(); foreach (var assemblyPath in Directory.GetFiles(m_PluginsDirectory, "*.dll")) { try { var assemblyData = await FileHelper.ReadAllBytesAsync(assemblyPath); var assemblySymbolsPath = Path.ChangeExtension(assemblyPath, "pdb"); var assemblySymbols = File.Exists(assemblySymbolsPath) ? await FileHelper.ReadAllBytesAsync(assemblySymbolsPath) : null; var pluginAssembly = Hotloader.LoadAssembly(assemblyData, assemblySymbols); var pluginMetadata = pluginAssembly.GetCustomAttribute <PluginMetadataAttribute>(); if (pluginMetadata == null) { // not a plugin, but could be a library continue; } assemblyList.Add(pluginAssembly); } catch (Exception ex) { m_Logger.LogWarning(ex, "Failed to load plugin metadata from file: {File}", assemblyPath); } } return(assemblyList); }
public PomeloMySqlConnectorResolver(NuGetPackageManager nuGetPackageManager, ILogger <PomeloMySqlConnectorResolver> logger) { if (!Hotloader.Enabled) { logger.LogCritical( "Hotloader is not enabled and MySqlConnector v0.69 will not be able to load. Some plugins may not work as intended."); return; } using var stream = GetType().Assembly .GetManifestResourceStream("OpenMod.EntityFrameworkCore.MySql.libs.MySqlConnector.dll"); if (stream == null) { logger.LogCritical( "Could not retrieve MySqlConnector assembly stream. Some plugins may not work as intended."); return; } using var memStream = new MemoryStream(); stream.CopyTo(memStream); var assemblyBytes = memStream.ToArray(); Hotloader.LoadAssembly(assemblyBytes); logger.LogDebug("Loaded MySqlConnector v0.69 into Hotloader"); var nuGetResolverInstalled = AccessTools.FieldRefAccess <NuGetPackageManager, bool>("m_AssemblyResolverInstalled")( nuGetPackageManager); if (nuGetResolverInstalled) { var assemblyResolveMethod = typeof(NuGetPackageManager).GetMethod("OnAssemblyResolve", BindingFlags.NonPublic | BindingFlags.Instance); if (assemblyResolveMethod == null) { logger.LogCritical($"Couldn't find OnAssemblyResolve method for {nameof(NuGetPackageManager)}!"); } else { var @delegate = (ResolveEventHandler)assemblyResolveMethod.CreateDelegate(typeof(ResolveEventHandler), nuGetPackageManager); AppDomain.CurrentDomain.AssemblyResolve -= @delegate; AppDomain.CurrentDomain.AssemblyResolve += @delegate; } } }
protected override async Task OnExecuteAsync() { var modulesDirectory = Path.Combine(ReadWrite.PATH, "Modules"); var openModDirPath = Path.GetDirectoryName(Directory .GetFiles(modulesDirectory, "OpenMod.Unturned.Module.dll", SearchOption.AllDirectories) .FirstOrDefault() ?? throw new Exception("Failed to find OpenMod directory")) !; using var client = new HttpClient(); client.DefaultRequestHeaders.Add("User-Agent", "request"); var releaseData = await client.GetStringAsync("https://api.github.com/repos/openmod/openmod/releases/latest"); var release = JsonConvert.DeserializeObject <LatestRelease>(releaseData); var isPre = Context.Parameters.Contains("--pre"); var anyUpdated = false; var moduleAsset = release.Assets.Find(x => x.BrowserDownloadUrl.Contains("OpenMod.Unturned.Module")); if (moduleAsset != null && m_HostInformation.HostVersion.CompareTo(release.TagName) < 0) { BackupFiles(openModDirPath); try { await PrintAsync($"Downloading {moduleAsset.AssetName}..."); var stream = await client.GetStreamAsync(moduleAsset.BrowserDownloadUrl); await PrintAsync("Extracting update..."); await ExtractArchiveAsync(stream, openModDirPath !); } catch (Exception) { RestoreFiles(openModDirPath); throw; } DeleteBackup(openModDirPath); anyUpdated = true; } foreach (var assembly in m_Runtime.HostAssemblies) { var ident = await m_PackageManager.QueryPackageExactAsync(assembly.GetName().Name, null, isPre); if (ident == null) { m_Logger.LogWarning("No package found for assembly: {AssemblyName}", assembly.FullName); continue; } var installed = await m_PackageManager.GetLatestPackageIdentityAsync(ident.Identity.Id); if (installed != null && installed.Version >= ident.Identity.Version) { continue; } await PrintAsync($"Updating package \"{ident.Identity.Id}\" to {ident.Identity.Version}"); await m_PackageManager.InstallAsync(ident.Identity, isPre); anyUpdated = true; } if (!anyUpdated) { await PrintAsync("No update found."); return; } if (Hotloader.Enabled) { var modulePath = Path.Combine(openModDirPath, "OpenMod.Unturned.Module.dll"); var moduleAssembly = Hotloader.LoadAssembly(File.ReadAllBytes(modulePath)); var moduleNexusType = moduleAssembly.GetType("OpenMod.Unturned.Module.OpenModUnturnedModule"); if (moduleNexusType == null) { await PrintAsync("Failed to dynamically reload OpenMod. Please restart your server.", Color.Red); return; } await PrintAsync("Reloading OpenMod..."); try { await m_Runtime.ShutdownAsync(); var nexus = (IModuleNexus)Activator.CreateInstance(moduleNexusType); // set OpenModUnturnedModule.IsDynamicLoad to true var isDynamicPropertySetter = moduleNexusType.GetProperty("IsDynamicLoad")?.GetSetMethod(true); isDynamicPropertySetter?.Invoke(nexus, new object[] { true }); nexus.initialize(); } catch { await PrintAsync( "Reloading OpenMod has failed! Please restart your server and report this error.", Color.Red); throw; } await PrintAsync("Update has been installed and loaded."); } else { await PrintAsync("Update has been installed. Restart to apply it."); } }
protected override async Task OnExecuteAsync() { var modulesDirectory = Path.Combine(ReadWrite.PATH, "Modules"); var openModDirPath = Path.GetDirectoryName(Directory .GetFiles(modulesDirectory, "OpenMod.Unturned.dll", SearchOption.AllDirectories) .FirstOrDefault() ?? throw new Exception("Failed to find OpenMod directory")); using var client = new HttpClient(); client.DefaultRequestHeaders.Add("User-Agent", "request"); var releaseData = await client.GetStringAsync("https://api.github.com/repos/openmod/openmod/releases/latest"); var release = JsonConvert.DeserializeObject <LatestRelease>(releaseData); var moduleAsset = release.Assets.Find(x => x.BrowserDownloadUrl.Contains("OpenMod.Unturned.Module")); if (moduleAsset == null || m_HostInformation.HostVersion.CompareTo(release.TagName) >= 0) { await PrintAsync("No update found..."); return; } await PrintAsync($"Downloading {moduleAsset.AssetName}..."); var stream = await client.GetStreamAsync(moduleAsset.BrowserDownloadUrl); await PrintAsync("Extracting update..."); await ExtractArchiveAsync(stream, openModDirPath !); if (Hotloader.Enabled) { var modulePath = Path.Combine(openModDirPath, "OpenMod.Unturned.Module.dll"); var moduleAssembly = Hotloader.LoadAssembly(File.ReadAllBytes(modulePath)); var moduleNexusType = moduleAssembly.GetType("OpenMod.Unturned.Module.OpenModUnturnedModule"); if (moduleNexusType == null) { await PrintAsync("Failed to dynamically reload OpenMod. Please restart your server.", Color.Red); return; } await PrintAsync("Reloading OpenMod..."); try { await m_Runtime.ShutdownAsync(); var nexus = (IModuleNexus)Activator.CreateInstance(moduleNexusType); // set OpenModUnturnedModule.IsDynamicLoad to true var isDynamicPropertySetter = moduleNexusType.GetProperty("IsDynamicLoad")?.GetSetMethod(true); isDynamicPropertySetter?.Invoke(nexus, new object[] { true }); nexus.initialize(); } catch { await PrintAsync("Reloading OpenMod has failed! Please restart your server and report this error.", Color.Red); throw; } await PrintAsync("Update has been installed and loaded."); } else { await PrintAsync("Update has been installed. Restart to apply it."); } }
protected override async Task OnExecuteAsync() { var modulesDirectory = Path.Combine(ReadWrite.PATH, "Modules"); using var client = new HttpClient(); var releaseData = await client.GetStringAsync("https://api.github.com/repos/openmod/openmod/releases/latest"); var release = JsonConvert.DeserializeObject <LatestRelease>(releaseData); var moduleAsset = release.Assets.Find(x => x.BrowserDownloadUrl.Contains("OpenMod.Unturned.Module")); if (moduleAsset == null) { // todo: enumerator other releases until it finds OpenMod.Unturned.Module await PrintAsync($"No update found..."); return; } await PrintAsync($"Downloading {moduleAsset.AssetName}..."); var stream = await client.GetStreamAsync(moduleAsset.BrowserDownloadUrl); await PrintAsync("Extracting update..."); await ExtractArchiveAsync(stream, modulesDirectory); if (Hotloader.Enabled) { var modulePath = Path.Combine(modulesDirectory, "OpenMod.Unturned", "OpenMod.Unturned.Module.dll"); var moduleAssembly = Hotloader.LoadAssembly(File.ReadAllBytes(modulePath)); var moduleNexusType = moduleAssembly.GetType("OpenMod.Unturned.Module.OpenModUnturnedModule"); if (moduleNexusType == null) { await PrintAsync("Failed to dynamically reload OpenMod. Please restart your server.", Color.Red); return; } await PrintAsync("Reloading OpenMod..."); try { await m_Runtime.ShutdownAsync(); var nexus = (IModuleNexus)Activator.CreateInstance(moduleNexusType); // set OpenModUnturnedModule.IsDynamicLoad to true var isDynamicPropertySetter = moduleNexusType.GetProperty("IsDynamicLoad")?.GetSetMethod(true); if (isDynamicPropertySetter != null) { isDynamicPropertySetter.Invoke(nexus, new object[] { true }); } nexus.initialize(); } catch { await PrintAsync("Reloading OpenMod has failed! Please restart your server and report this error.", Color.Red); throw; } await PrintAsync("Update has been installed and loaded."); } else { await PrintAsync("Update has been installed. Restart to apply it."); } }