From b0f8434ca84a538c37305b0d928d4e933a295153 Mon Sep 17 00:00:00 2001 From: Joost Boomkamp Date: Mon, 28 Nov 2022 12:49:31 +0100 Subject: [PATCH 1/9] add developer setup app --- SetupDevEnvironment/IO/AssemblyPublicizer.cs | 113 +++++++++++++ SetupDevEnvironment/IO/Downloader.cs | 17 ++ .../IO/ExtensionsToDirectionary.cs | 13 ++ SetupDevEnvironment/IO/FileMover.cs | 25 +++ SetupDevEnvironment/IO/Links.cs | 16 ++ SetupDevEnvironment/IO/LogEvent.cs | 11 ++ SetupDevEnvironment/IO/Unzipper.cs | 29 ++++ SetupDevEnvironment/InstallScript.cs | 96 +++++++++++ SetupDevEnvironment/Program.cs | 17 ++ .../Properties/Resources.Designer.cs | 73 ++++++++ SetupDevEnvironment/Properties/Resources.resx | 124 ++++++++++++++ .../Resources/Valheim-Wallpaper.jpeg | Bin 0 -> 228166 bytes .../SetupDevEnvironment.csproj | 32 ++++ SetupDevEnvironment/SetupForm.Designer.cs | 156 ++++++++++++++++++ SetupDevEnvironment/SetupForm.cs | 110 ++++++++++++ SetupDevEnvironment/SetupForm.resx | 60 +++++++ SetupDevEnvironment/app.manifest | 79 +++++++++ ValheimPlus.sln | 6 + 18 files changed, 977 insertions(+) create mode 100644 SetupDevEnvironment/IO/AssemblyPublicizer.cs create mode 100644 SetupDevEnvironment/IO/Downloader.cs create mode 100644 SetupDevEnvironment/IO/ExtensionsToDirectionary.cs create mode 100644 SetupDevEnvironment/IO/FileMover.cs create mode 100644 SetupDevEnvironment/IO/Links.cs create mode 100644 SetupDevEnvironment/IO/LogEvent.cs create mode 100644 SetupDevEnvironment/IO/Unzipper.cs create mode 100644 SetupDevEnvironment/InstallScript.cs create mode 100644 SetupDevEnvironment/Program.cs create mode 100644 SetupDevEnvironment/Properties/Resources.Designer.cs create mode 100644 SetupDevEnvironment/Properties/Resources.resx create mode 100644 SetupDevEnvironment/Resources/Valheim-Wallpaper.jpeg create mode 100644 SetupDevEnvironment/SetupDevEnvironment.csproj create mode 100644 SetupDevEnvironment/SetupForm.Designer.cs create mode 100644 SetupDevEnvironment/SetupForm.cs create mode 100644 SetupDevEnvironment/SetupForm.resx create mode 100644 SetupDevEnvironment/app.manifest diff --git a/SetupDevEnvironment/IO/AssemblyPublicizer.cs b/SetupDevEnvironment/IO/AssemblyPublicizer.cs new file mode 100644 index 00000000..800aa48a --- /dev/null +++ b/SetupDevEnvironment/IO/AssemblyPublicizer.cs @@ -0,0 +1,113 @@ +//elliotttate/Bepinex-Tools + +using dnlib.DotNet; +using System.ComponentModel; +using System.Reflection; +using FieldAttributes = dnlib.DotNet.FieldAttributes; +using MethodAttributes = dnlib.DotNet.MethodAttributes; +using TypeAttributes = dnlib.DotNet.TypeAttributes; + +namespace SetupDevEnvironment.IO; + +internal class AssemblyPublicizer +{ + public const string + MODNAME = "Bepinex_Publicizer", + AUTHOR = "MrPurple6411", + GUID = AUTHOR + "_" + MODNAME, + VERSION = "1.0.0.0"; + + public event ProgressChangedEventHandler? OnLogMessage; + + private void Log(string msg) + { + if (OnLogMessage != null) + { + OnLogMessage(this, new ProgressChangedEventArgs(0, msg)); + } + } + + public void ProcessAssemblies(string valheimPlusInstallDir) + { + var managedFolder = Path.Combine(valheimPlusInstallDir, "valheim_Data\\Managed\\"); + var files = Directory.GetFiles( + managedFolder, "assembly*.dll", SearchOption.TopDirectoryOnly); + + foreach (var file in files) + { + try + { + var assembly = Assembly.LoadFile(file); + ProcessAssembly(assembly); + } catch(Exception ex) + { + Log(ex.Message); + } + } + } + + void ProcessAssembly(Assembly assembly) + { + string assemblyPath = assembly.Location; + string filename = assembly.GetName().Name; + string outputPath = Path.Combine(Path.GetDirectoryName(assemblyPath), "publicized_assemblies"); + string outputSuffix = "_publicized"; + + Directory.CreateDirectory(outputPath); + + string curHash = ComputeHash(assembly); + + string hashPath = Path.Combine(outputPath, $"{filename}{outputSuffix}.hash"); + string lastHash = null; + + if (File.Exists(hashPath)) + lastHash = File.ReadAllText(hashPath); + + if (curHash == lastHash) + return; + + Log($"Making a public assembly from {filename}"); + RewriteAssembly(assemblyPath).Write($"{Path.Combine(outputPath, filename)}{outputSuffix}.dll"); + File.WriteAllText(hashPath, curHash); + } + + static string ComputeHash(Assembly assembly) + { + return assembly.ManifestModule.ModuleVersionId.ToString(); + } + + static ModuleDef RewriteAssembly(string assemblyPath) + { + ModuleDef assembly = ModuleDefMD.Load(assemblyPath); + + foreach (var type in assembly.GetTypes()) + { + type.Attributes &= ~TypeAttributes.VisibilityMask; + + if (type.IsNested) + type.Attributes |= TypeAttributes.NestedPublic; + else + type.Attributes |= TypeAttributes.Public; + + foreach (MethodDef method in type.Methods) + { + method.Attributes &= ~MethodAttributes.MemberAccessMask; + method.Attributes |= MethodAttributes.Public; + } + + List eventNames = new List(); + foreach (EventDef ev in type.Events) + eventNames.Add(ev.Name); + + foreach (FieldDef field in type.Fields) + { + if (!eventNames.Contains(field.Name)) + { + field.Attributes &= ~FieldAttributes.FieldAccessMask; + field.Attributes |= FieldAttributes.Public; + } + } + } + return assembly; + } +} diff --git a/SetupDevEnvironment/IO/Downloader.cs b/SetupDevEnvironment/IO/Downloader.cs new file mode 100644 index 00000000..eaae7754 --- /dev/null +++ b/SetupDevEnvironment/IO/Downloader.cs @@ -0,0 +1,17 @@ +namespace SetupDevEnvironment.IO; + +internal partial class Downloader +{ + + public static async Task Download(string url, string? fileName = null) + { + var tempFile = fileName ?? Path.GetTempFileName(); + + using (var client = new HttpClient()) + { + var data = await client.GetByteArrayAsync(url); + await File.WriteAllBytesAsync(tempFile, data); + return tempFile; + } + } +} diff --git a/SetupDevEnvironment/IO/ExtensionsToDirectionary.cs b/SetupDevEnvironment/IO/ExtensionsToDirectionary.cs new file mode 100644 index 00000000..3106b0a8 --- /dev/null +++ b/SetupDevEnvironment/IO/ExtensionsToDirectionary.cs @@ -0,0 +1,13 @@ +namespace SetupDevEnvironment.IO +{ + public static class DirectoryHelper + { + public static string CreateTempFolder() + { + var tempFolder = Path.GetTempPath(); + var folder = Path.Combine(tempFolder, Path.GetRandomFileName()); + Directory.CreateDirectory(folder); + return folder; + } + } +} diff --git a/SetupDevEnvironment/IO/FileMover.cs b/SetupDevEnvironment/IO/FileMover.cs new file mode 100644 index 00000000..83aae1bf --- /dev/null +++ b/SetupDevEnvironment/IO/FileMover.cs @@ -0,0 +1,25 @@ +namespace SetupDevEnvironment.IO +{ + internal class FileMover + { + public static void CopyFiles(string sourceFolder, string destinationFolder) + { + Directory.CreateDirectory(destinationFolder); + + var sourceFiles = + Directory.GetFiles(sourceFolder, "*.*", SearchOption.AllDirectories); + + foreach (string file in sourceFiles) + { + var relativeFile = file.Replace(sourceFolder, ""); + var destFile = Path.Combine(destinationFolder, relativeFile); + + // we may need new subfolders + var folder = Path.GetDirectoryName(destFile); + Directory.CreateDirectory(folder); + + File.Copy(file, destFile, true); + } + } + } +} diff --git a/SetupDevEnvironment/IO/Links.cs b/SetupDevEnvironment/IO/Links.cs new file mode 100644 index 00000000..252f0de5 --- /dev/null +++ b/SetupDevEnvironment/IO/Links.cs @@ -0,0 +1,16 @@ +namespace SetupDevEnvironment.IO; + +internal static class Links +{ + public static string DefaultValheimInstallFolder = + @"C:\Program Files (x86)\Steam\steamapps\common\Valheim"; + + public static string DefaultValheimPlusDevInstallFolder = + @"C:\Program Files (x86)\Steam\steamapps\common\Valheim Plus Development"; + + public static readonly string BepInEx = + @"https://valheim.thunderstore.io/package/download/denikson/BepInExPack_Valheim/5.4.1900/"; + + public static readonly string AssemblyPublicizer = + @"https://github.com/elliotttate/Bepinex-Tools/releases/download/1.0.0-Publicizer/Bepinex-Publicizer.zip"; +} diff --git a/SetupDevEnvironment/IO/LogEvent.cs b/SetupDevEnvironment/IO/LogEvent.cs new file mode 100644 index 00000000..1c9d1535 --- /dev/null +++ b/SetupDevEnvironment/IO/LogEvent.cs @@ -0,0 +1,11 @@ +namespace SetupDevEnvironment.IO; + +internal class LogEvent : EventArgs +{ + public string Message { get; private set; } + + public LogEvent(string message) + { + Message = message; + } +} diff --git a/SetupDevEnvironment/IO/Unzipper.cs b/SetupDevEnvironment/IO/Unzipper.cs new file mode 100644 index 00000000..247fcf27 --- /dev/null +++ b/SetupDevEnvironment/IO/Unzipper.cs @@ -0,0 +1,29 @@ +using System.IO.Compression; + +namespace SetupDevEnvironment.IO +{ + internal static class Unzipper + { + /// + /// returns all entries relative to the target folder + /// + /// + /// + /// + public static string[] Unzip(string filename, string? targetFolder = null) + { + targetFolder = targetFolder ?? DirectoryHelper.CreateTempFolder(); + Directory.CreateDirectory(targetFolder); + + using (var zipFileStream = new FileStream(filename, FileMode.Open)) + using (var zipfile = new ZipArchive(zipFileStream)) + { + zipfile.ExtractToDirectory(targetFolder, true); + + return zipfile.Entries + .Select(entry => Path.Combine(targetFolder, entry.FullName)) + .ToArray(); + } + } + } +} diff --git a/SetupDevEnvironment/InstallScript.cs b/SetupDevEnvironment/InstallScript.cs new file mode 100644 index 00000000..35bbd4ad --- /dev/null +++ b/SetupDevEnvironment/InstallScript.cs @@ -0,0 +1,96 @@ +using SetupDevEnvironment.IO; +using System.ComponentModel; + +namespace SetupDevEnvironment +{ + internal class InstallScript + { + readonly string _installFolder; + + public event ProgressChangedEventHandler? OnLogMessage; + + private void Log(string msg) + { + if (OnLogMessage != null) + { + OnLogMessage(this, new ProgressChangedEventArgs(0, msg )); + } + } + + public InstallScript(string? installFolder) + { + _installFolder = installFolder; + } + + public async Task Install() + { + await InstallBepInEx(); + //await PublicizeAssemblies(); + PublicizeAssembliesDirectly(); + await ConfigureEnvironment(); + } + + private async Task ConfigureEnvironment() + { + Log("Configuring environment..."); + Environment.SetEnvironmentVariable("VALHEIM_INSTALL", _installFolder, EnvironmentVariableTarget.Machine); + await Task.CompletedTask; + Log("Done!"); + } + + public async Task InstallBepInEx() + { + Log("Installing BepInEx..."); + var tempFolder = DirectoryHelper.CreateTempFolder(); + var bepInExZip = await Downloader.Download(Links.BepInEx, Path.Combine(tempFolder, "bepInExPack.zip")); + var bepInExFiles = Unzipper.Unzip(bepInExZip); + File.Delete(bepInExZip); + + var sourceFolder = bepInExFiles.Single(file => file.EndsWith("BepInExPack_Valheim/")); + FileMover.CopyFiles(sourceFolder, _installFolder); + + var unstripped_corlibFiles = bepInExFiles + .Where(path => path.Contains("unstripped_corlib")); + + foreach(var source in unstripped_corlibFiles) + { + var file = Path.GetFileName(source); + if (string.IsNullOrEmpty(file)) + { + continue; + } + + var destination = Path.Combine(_installFolder, $"valheim_Data\\Managed\\{file}"); + File.Copy(source, destination, true); + } + Log("Done!"); + } + + /// + /// Install a plugin that automatically reads any file that matches "assembly_*.dll" and + /// creates a new dll where all properties, classes and fields are made public. + /// This allows devs to include these publicized dlls and use the correct consts, methods, etc. + /// + /// + public async Task PublicizeAssemblies() + { + var publicizerZip = await Downloader.Download(Links.AssemblyPublicizer); + var publicizerFiles = Unzipper.Unzip(publicizerZip); + + var file = "BepInEx-Publicizer.dll"; + var pluginDll = publicizerFiles.Single(file => file.EndsWith( + @"plugins/Bepinex-Publicizer/Bepinex-Publicizer.dll", StringComparison.InvariantCultureIgnoreCase)); + + File.Copy(pluginDll, Path.Combine(_installFolder, $"BepInEx\\plugins\\{file}"), true); + } + + public void PublicizeAssembliesDirectly() + { + Log("Publicizing assemblies..."); + var pubber = new AssemblyPublicizer(); + pubber.OnLogMessage += this.OnLogMessage; + pubber.ProcessAssemblies(_installFolder); + Log("Done!"); + } + } +} diff --git a/SetupDevEnvironment/Program.cs b/SetupDevEnvironment/Program.cs new file mode 100644 index 00000000..15186ed4 --- /dev/null +++ b/SetupDevEnvironment/Program.cs @@ -0,0 +1,17 @@ +namespace SetupDevEnvironment +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + Application.Run(new SetupForm()); + } + } +} \ No newline at end of file diff --git a/SetupDevEnvironment/Properties/Resources.Designer.cs b/SetupDevEnvironment/Properties/Resources.Designer.cs new file mode 100644 index 00000000..87a4bf29 --- /dev/null +++ b/SetupDevEnvironment/Properties/Resources.Designer.cs @@ -0,0 +1,73 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SetupDevEnvironment.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SetupDevEnvironment.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap Valheim_Wallpaper { + get { + object obj = ResourceManager.GetObject("Valheim_Wallpaper", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/SetupDevEnvironment/Properties/Resources.resx b/SetupDevEnvironment/Properties/Resources.resx new file mode 100644 index 00000000..9cadb021 --- /dev/null +++ b/SetupDevEnvironment/Properties/Resources.resx @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Valheim-Wallpaper.jpeg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + \ No newline at end of file diff --git a/SetupDevEnvironment/Resources/Valheim-Wallpaper.jpeg b/SetupDevEnvironment/Resources/Valheim-Wallpaper.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..ca69e791113a88dfd79d50167c875d7c986de984 GIT binary patch literal 228166 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

vg&Q3CE$F3SOeSs4-7fZkN+fzV<3 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�&Pf8jUC{{W>= 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 z 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 + + + WinExe + net6.0-windows + enable + true + enable + app.manifest + + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + \ No newline at end of file diff --git a/SetupDevEnvironment/SetupForm.Designer.cs b/SetupDevEnvironment/SetupForm.Designer.cs new file mode 100644 index 00000000..95ef20e9 --- /dev/null +++ b/SetupDevEnvironment/SetupForm.Designer.cs @@ -0,0 +1,156 @@ +namespace SetupDevEnvironment +{ + partial class SetupForm + { + ///

+ /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + this.tbValheimPlusInstallDir = new System.Windows.Forms.TextBox(); + this.label1 = new System.Windows.Forms.Label(); + this.btBrowseVPlusInstallDir = new System.Windows.Forms.Button(); + this.btStartInstallation = new System.Windows.Forms.Button(); + this.btBrowseValheimInstallDir = new System.Windows.Forms.Button(); + this.label2 = new System.Windows.Forms.Label(); + this.tbValheimInstallDir = new System.Windows.Forms.TextBox(); + this.tbLog = new System.Windows.Forms.TextBox(); + this.SuspendLayout(); + // + // tbValheimPlusInstallDir + // + this.tbValheimPlusInstallDir.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbValheimPlusInstallDir.Location = new System.Drawing.Point(12, 84); + this.tbValheimPlusInstallDir.Name = "tbValheimPlusInstallDir"; + this.tbValheimPlusInstallDir.Size = new System.Drawing.Size(848, 23); + this.tbValheimPlusInstallDir.TabIndex = 0; + // + // label1 + // + this.label1.AutoSize = true; + this.label1.Location = new System.Drawing.Point(18, 63); + this.label1.Name = "label1"; + this.label1.Size = new System.Drawing.Size(174, 15); + this.label1.TabIndex = 1; + this.label1.Text = "Valheim Plus Installation Folder:"; + // + // btBrowseVPlusInstallDir + // + this.btBrowseVPlusInstallDir.Location = new System.Drawing.Point(198, 59); + this.btBrowseVPlusInstallDir.Name = "btBrowseVPlusInstallDir"; + this.btBrowseVPlusInstallDir.Size = new System.Drawing.Size(75, 23); + this.btBrowseVPlusInstallDir.TabIndex = 2; + this.btBrowseVPlusInstallDir.Text = "Browse..."; + this.btBrowseVPlusInstallDir.UseVisualStyleBackColor = true; + this.btBrowseVPlusInstallDir.Click += new System.EventHandler(this.btBrowseVPlusInstallDir_Click); + // + // btStartInstallation + // + this.btStartInstallation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btStartInstallation.Enabled = false; + this.btStartInstallation.Location = new System.Drawing.Point(208, 488); + this.btStartInstallation.Name = "btStartInstallation"; + this.btStartInstallation.Size = new System.Drawing.Size(161, 62); + this.btStartInstallation.TabIndex = 3; + this.btStartInstallation.Text = "Setup Dev Environment"; + this.btStartInstallation.UseVisualStyleBackColor = true; + this.btStartInstallation.Click += new System.EventHandler(this.btStartInstallation_Click); + // + // btBrowseValheimInstallDir + // + this.btBrowseValheimInstallDir.Location = new System.Drawing.Point(198, 5); + this.btBrowseValheimInstallDir.Name = "btBrowseValheimInstallDir"; + this.btBrowseValheimInstallDir.Size = new System.Drawing.Size(75, 23); + this.btBrowseValheimInstallDir.TabIndex = 6; + this.btBrowseValheimInstallDir.Text = "Browse..."; + this.btBrowseValheimInstallDir.UseVisualStyleBackColor = true; + this.btBrowseValheimInstallDir.Click += new System.EventHandler(this.btBrowseValheimInstallDir_Click); + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(18, 9); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(149, 15); + this.label2.TabIndex = 5; + this.label2.Text = "Valheim Installation Folder:"; + // + // tbValheimInstallDir + // + this.tbValheimInstallDir.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbValheimInstallDir.Location = new System.Drawing.Point(12, 30); + this.tbValheimInstallDir.Name = "tbValheimInstallDir"; + this.tbValheimInstallDir.Size = new System.Drawing.Size(848, 23); + this.tbValheimInstallDir.TabIndex = 4; + // + // tbLog + // + this.tbLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) + | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.tbLog.Location = new System.Drawing.Point(18, 165); + this.tbLog.Multiline = true; + this.tbLog.Name = "tbLog"; + this.tbLog.Size = new System.Drawing.Size(842, 317); + this.tbLog.TabIndex = 7; + this.tbLog.Visible = false; + // + // SetupForm + // + this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); + this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + this.BackgroundImage = global::SetupDevEnvironment.Properties.Resources.Valheim_Wallpaper; + this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; + this.ClientSize = new System.Drawing.Size(872, 562); + this.Controls.Add(this.tbLog); + this.Controls.Add(this.btBrowseValheimInstallDir); + this.Controls.Add(this.label2); + this.Controls.Add(this.tbValheimInstallDir); + this.Controls.Add(this.btStartInstallation); + this.Controls.Add(this.btBrowseVPlusInstallDir); + this.Controls.Add(this.label1); + this.Controls.Add(this.tbValheimPlusInstallDir); + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; + this.Name = "SetupForm"; + this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; + this.Text = "Form1"; + this.ResumeLayout(false); + this.PerformLayout(); + + } + + #endregion + + private TextBox tbValheimPlusInstallDir; + private Label label1; + private Button btBrowseVPlusInstallDir; + private Button btStartInstallation; + private Button btBrowseValheimInstallDir; + private Label label2; + private TextBox tbValheimInstallDir; + private TextBox tbLog; + } +} \ No newline at end of file diff --git a/SetupDevEnvironment/SetupForm.cs b/SetupDevEnvironment/SetupForm.cs new file mode 100644 index 00000000..126fd561 --- /dev/null +++ b/SetupDevEnvironment/SetupForm.cs @@ -0,0 +1,110 @@ +using SetupDevEnvironment.IO; +using System.ComponentModel; +using static System.Net.Mime.MediaTypeNames; + +namespace SetupDevEnvironment +{ + public partial class SetupForm : Form + { + private string? ValheimInstallPath { get; set; } = null; + private string? ValheimPlusInstallPath { get; set; } = null; + private Task _installTask = Task.CompletedTask; + + public SetupForm() + { + InitializeComponent(); + } + + private void EnableStartButton() + { + if (Directory.Exists(tbValheimInstallDir.Text) && + Directory.Exists(tbValheimPlusInstallDir.Text)) + { + btStartInstallation.Enabled = true; + } else + { + btStartInstallation.Enabled = false; + } + } + + private void btBrowseValheimInstallDir_Click(object sender, EventArgs e) + { + var path = GetFolder(Links.DefaultValheimInstallFolder); + if (path == string.Empty) + return; + + ValheimInstallPath = path; + tbValheimInstallDir.Text = ValheimInstallPath; + tbValheimInstallDir.Invalidate(); + + if (string.IsNullOrEmpty(ValheimPlusInstallPath)) + { + var steamRoot = Directory.GetParent(path); + ValheimPlusInstallPath = Path.Combine(steamRoot.FullName, "Valheim Plus Development"); + tbValheimPlusInstallDir.Text = ValheimPlusInstallPath; + tbValheimPlusInstallDir.Invalidate(); + } + + EnableStartButton(); + } + + private void btBrowseVPlusInstallDir_Click(object sender, EventArgs e) + { + var path = GetFolder(Links.DefaultValheimPlusDevInstallFolder); + if (path == string.Empty) + return; + + ValheimPlusInstallPath = path; + tbValheimPlusInstallDir.Text = ValheimPlusInstallPath; + tbValheimPlusInstallDir.Invalidate(); + + EnableStartButton(); + } + + private async void btStartInstallation_Click(object sender, EventArgs e) + { + btStartInstallation.Enabled = false; + tbLog.Enabled = false; + tbLog.Visible = true; + + var script = new InstallScript(ValheimPlusInstallPath); + script.OnLogMessage += OnLogMessage; + await script.Install(); + + EnableStartButton(); + } + + private static string GetFolder(string initialPath) + { + var odd = new FolderBrowserDialog + { + InitialDirectory = initialPath, + }; + + var result = odd.ShowDialog(); + + if (result != DialogResult.OK) + { + return string.Empty; + } + + return odd.SelectedPath; + } + + + private void OnLogMessage(object? sender, ProgressChangedEventArgs e) + { + if (InvokeRequired) + { + Invoke((Action)UpdateLog, (string)e.UserState); + return; + } + UpdateLog((string)e.UserState); + } + + private void UpdateLog(string text) + { + tbLog.AppendText(text + Environment.NewLine); + } + } +} \ No newline at end of file diff --git a/SetupDevEnvironment/SetupForm.resx b/SetupDevEnvironment/SetupForm.resx new file mode 100644 index 00000000..f298a7be --- /dev/null +++ b/SetupDevEnvironment/SetupForm.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/SetupDevEnvironment/app.manifest b/SetupDevEnvironment/app.manifest new file mode 100644 index 00000000..4fc1d1d5 --- /dev/null +++ b/SetupDevEnvironment/app.manifest @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ValheimPlus.sln b/ValheimPlus.sln index 99a3ffa1..874a0a19 100644 --- a/ValheimPlus.sln +++ b/ValheimPlus.sln @@ -20,6 +20,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unix", "unix", "{7FBDF646-C resources\unix\start_server_bepinex.sh = resources\unix\start_server_bepinex.sh EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SetupDevEnvironment", "SetupDevEnvironment\SetupDevEnvironment.csproj", "{70D1B8BE-D049-4155-8D48-9B01EF38A6AC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -30,6 +32,10 @@ Global {2A837100-A030-4D0C-BFFB-B38356118D9A}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A837100-A030-4D0C-BFFB-B38356118D9A}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A837100-A030-4D0C-BFFB-B38356118D9A}.Release|Any CPU.Build.0 = Release|Any CPU + {70D1B8BE-D049-4155-8D48-9B01EF38A6AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70D1B8BE-D049-4155-8D48-9B01EF38A6AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70D1B8BE-D049-4155-8D48-9B01EF38A6AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70D1B8BE-D049-4155-8D48-9B01EF38A6AC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From eefb064e6beb670e6fcbf7a1c3dd299761f2afb1 Mon Sep 17 00:00:00 2001 From: Joost Boomkamp Date: Mon, 28 Nov 2022 22:10:07 +0100 Subject: [PATCH 2/9] tweaks --- SetupDevEnvironment/IO/FileMover.cs | 2 +- SetupDevEnvironment/InstallScript.cs | 34 +++++++++++++++-------- SetupDevEnvironment/SetupForm.Designer.cs | 21 ++++++++++++-- SetupDevEnvironment/SetupForm.cs | 18 +++++++++++- 4 files changed, 59 insertions(+), 16 deletions(-) diff --git a/SetupDevEnvironment/IO/FileMover.cs b/SetupDevEnvironment/IO/FileMover.cs index 83aae1bf..8016f381 100644 --- a/SetupDevEnvironment/IO/FileMover.cs +++ b/SetupDevEnvironment/IO/FileMover.cs @@ -11,7 +11,7 @@ public static void CopyFiles(string sourceFolder, string destinationFolder) foreach (string file in sourceFiles) { - var relativeFile = file.Replace(sourceFolder, ""); + var relativeFile = file.Replace(sourceFolder, "").Substring(1); var destFile = Path.Combine(destinationFolder, relativeFile); // we may need new subfolders diff --git a/SetupDevEnvironment/InstallScript.cs b/SetupDevEnvironment/InstallScript.cs index 35bbd4ad..cd014f6e 100644 --- a/SetupDevEnvironment/InstallScript.cs +++ b/SetupDevEnvironment/InstallScript.cs @@ -1,11 +1,13 @@ using SetupDevEnvironment.IO; using System.ComponentModel; +using System.Diagnostics; namespace SetupDevEnvironment { internal class InstallScript { - readonly string _installFolder; + private readonly string _valheimInstallFolder; + private readonly string _devInstallFolder; public event ProgressChangedEventHandler? OnLogMessage; @@ -17,23 +19,31 @@ private void Log(string msg) } } - public InstallScript(string? installFolder) + public InstallScript(string valheimFolder, string valheimPlusFolder) { - _installFolder = installFolder; + _valheimInstallFolder = valheimFolder; + _devInstallFolder = valheimPlusFolder; } public async Task Install() { + CopyValheimFiles(); await InstallBepInEx(); - //await PublicizeAssemblies(); PublicizeAssembliesDirectly(); await ConfigureEnvironment(); } + private void CopyValheimFiles() + { + Log("Copying existing Valheim files to Dev Environment..."); + FileMover.CopyFiles(_valheimInstallFolder, _devInstallFolder); + Log("Done!"); + } + private async Task ConfigureEnvironment() { Log("Configuring environment..."); - Environment.SetEnvironmentVariable("VALHEIM_INSTALL", _installFolder, EnvironmentVariableTarget.Machine); + Environment.SetEnvironmentVariable("VALHEIM_INSTALL", _devInstallFolder, EnvironmentVariableTarget.Machine); await Task.CompletedTask; Log("Done!"); } @@ -47,12 +57,14 @@ public async Task InstallBepInEx() File.Delete(bepInExZip); var sourceFolder = bepInExFiles.Single(file => file.EndsWith("BepInExPack_Valheim/")); - FileMover.CopyFiles(sourceFolder, _installFolder); + FileMover.CopyFiles(sourceFolder, _devInstallFolder); var unstripped_corlibFiles = bepInExFiles .Where(path => path.Contains("unstripped_corlib")); - - foreach(var source in unstripped_corlibFiles) + + var managedFolder = Path.Combine(_devInstallFolder, $"valheim_Data\\Managed\\"); + Directory.CreateDirectory(managedFolder); + foreach (var source in unstripped_corlibFiles) { var file = Path.GetFileName(source); if (string.IsNullOrEmpty(file)) @@ -60,7 +72,7 @@ public async Task InstallBepInEx() continue; } - var destination = Path.Combine(_installFolder, $"valheim_Data\\Managed\\{file}"); + var destination = Path.Combine($"{managedFolder}{file}"); File.Copy(source, destination, true); } Log("Done!"); @@ -81,7 +93,7 @@ public async Task PublicizeAssemblies() var pluginDll = publicizerFiles.Single(file => file.EndsWith( @"plugins/Bepinex-Publicizer/Bepinex-Publicizer.dll", StringComparison.InvariantCultureIgnoreCase)); - File.Copy(pluginDll, Path.Combine(_installFolder, $"BepInEx\\plugins\\{file}"), true); + File.Copy(pluginDll, Path.Combine(_devInstallFolder, $"BepInEx\\plugins\\{file}"), true); } public void PublicizeAssembliesDirectly() @@ -89,7 +101,7 @@ public void PublicizeAssembliesDirectly() Log("Publicizing assemblies..."); var pubber = new AssemblyPublicizer(); pubber.OnLogMessage += this.OnLogMessage; - pubber.ProcessAssemblies(_installFolder); + pubber.ProcessAssemblies(_devInstallFolder); Log("Done!"); } } diff --git a/SetupDevEnvironment/SetupForm.Designer.cs b/SetupDevEnvironment/SetupForm.Designer.cs index 95ef20e9..0122dd3c 100644 --- a/SetupDevEnvironment/SetupForm.Designer.cs +++ b/SetupDevEnvironment/SetupForm.Designer.cs @@ -36,6 +36,7 @@ private void InitializeComponent() this.label2 = new System.Windows.Forms.Label(); this.tbValheimInstallDir = new System.Windows.Forms.TextBox(); this.tbLog = new System.Windows.Forms.TextBox(); + this.btEditConfig = new System.Windows.Forms.Button(); this.SuspendLayout(); // // tbValheimPlusInstallDir @@ -70,7 +71,7 @@ private void InitializeComponent() // this.btStartInstallation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btStartInstallation.Enabled = false; - this.btStartInstallation.Location = new System.Drawing.Point(208, 488); + this.btStartInstallation.Location = new System.Drawing.Point(12, 488); this.btStartInstallation.Name = "btStartInstallation"; this.btStartInstallation.Size = new System.Drawing.Size(161, 62); this.btStartInstallation.TabIndex = 3; @@ -111,13 +112,25 @@ private void InitializeComponent() this.tbLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.tbLog.Location = new System.Drawing.Point(18, 165); + this.tbLog.Location = new System.Drawing.Point(12, 165); this.tbLog.Multiline = true; this.tbLog.Name = "tbLog"; - this.tbLog.Size = new System.Drawing.Size(842, 317); + this.tbLog.Size = new System.Drawing.Size(848, 317); this.tbLog.TabIndex = 7; this.tbLog.Visible = false; // + // btEditConfig + // + this.btEditConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btEditConfig.Enabled = false; + this.btEditConfig.Location = new System.Drawing.Point(699, 488); + this.btEditConfig.Name = "btEditConfig"; + this.btEditConfig.Size = new System.Drawing.Size(161, 62); + this.btEditConfig.TabIndex = 8; + this.btEditConfig.Text = "Edit Valheim+ config"; + this.btEditConfig.UseVisualStyleBackColor = true; + this.btEditConfig.Click += new System.EventHandler(this.btEditConfig_Click); + // // SetupForm // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); @@ -125,6 +138,7 @@ private void InitializeComponent() this.BackgroundImage = global::SetupDevEnvironment.Properties.Resources.Valheim_Wallpaper; this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; this.ClientSize = new System.Drawing.Size(872, 562); + this.Controls.Add(this.btEditConfig); this.Controls.Add(this.tbLog); this.Controls.Add(this.btBrowseValheimInstallDir); this.Controls.Add(this.label2); @@ -152,5 +166,6 @@ private void InitializeComponent() private Label label2; private TextBox tbValheimInstallDir; private TextBox tbLog; + private Button btEditConfig; } } \ No newline at end of file diff --git a/SetupDevEnvironment/SetupForm.cs b/SetupDevEnvironment/SetupForm.cs index 126fd561..74f90abf 100644 --- a/SetupDevEnvironment/SetupForm.cs +++ b/SetupDevEnvironment/SetupForm.cs @@ -1,5 +1,6 @@ using SetupDevEnvironment.IO; using System.ComponentModel; +using System.Diagnostics; using static System.Net.Mime.MediaTypeNames; namespace SetupDevEnvironment @@ -67,10 +68,12 @@ private async void btStartInstallation_Click(object sender, EventArgs e) tbLog.Enabled = false; tbLog.Visible = true; - var script = new InstallScript(ValheimPlusInstallPath); + var script = new InstallScript(ValheimInstallPath, ValheimPlusInstallPath); script.OnLogMessage += OnLogMessage; await script.Install(); + btEditConfig.Enabled = true; + EnableStartButton(); } @@ -106,5 +109,18 @@ private void UpdateLog(string text) { tbLog.AppendText(text + Environment.NewLine); } + + private void btEditConfig_Click(object sender, EventArgs e) + { + var process = new Process(); + process.StartInfo = new ProcessStartInfo() + { + UseShellExecute = true, + FileName = Path.Combine(ValheimPlusInstallPath, "BepInEx\\config\\BepInEx.cfg") + }; + + process.Start(); + process.WaitForExit(); + } } } \ No newline at end of file From 14db2bfe9481db6860aad7d442aa36641593ca86 Mon Sep 17 00:00:00 2001 From: Joost Boomkamp Date: Wed, 30 Nov 2022 10:36:30 +0100 Subject: [PATCH 3/9] enable dnSpy configuration --- SetupDevEnvironment/IO/AssemblyPublicizer.cs | 6 - ...nsToDirectionary.cs => DirectoryHelper.cs} | 0 SetupDevEnvironment/IO/FileMover.cs | 7 +- SetupDevEnvironment/IO/Links.cs | 16 +- SetupDevEnvironment/IO/ProcessRunner.cs | 20 ++ SetupDevEnvironment/IO/ResourceHelper.cs | 17 ++ SetupDevEnvironment/InstallScript.cs | 56 +++-- .../Resources/DnSpyConfiguration.xml | 209 ++++++++++++++++++ .../SetupDevEnvironment.csproj | 8 + SetupDevEnvironment/SetupForm.Designer.cs | 39 +++- SetupDevEnvironment/SetupForm.cs | 34 +-- 11 files changed, 350 insertions(+), 62 deletions(-) rename SetupDevEnvironment/IO/{ExtensionsToDirectionary.cs => DirectoryHelper.cs} (100%) create mode 100644 SetupDevEnvironment/IO/ProcessRunner.cs create mode 100644 SetupDevEnvironment/IO/ResourceHelper.cs create mode 100644 SetupDevEnvironment/Resources/DnSpyConfiguration.xml diff --git a/SetupDevEnvironment/IO/AssemblyPublicizer.cs b/SetupDevEnvironment/IO/AssemblyPublicizer.cs index 800aa48a..dcc02636 100644 --- a/SetupDevEnvironment/IO/AssemblyPublicizer.cs +++ b/SetupDevEnvironment/IO/AssemblyPublicizer.cs @@ -11,12 +11,6 @@ namespace SetupDevEnvironment.IO; internal class AssemblyPublicizer { - public const string - MODNAME = "Bepinex_Publicizer", - AUTHOR = "MrPurple6411", - GUID = AUTHOR + "_" + MODNAME, - VERSION = "1.0.0.0"; - public event ProgressChangedEventHandler? OnLogMessage; private void Log(string msg) diff --git a/SetupDevEnvironment/IO/ExtensionsToDirectionary.cs b/SetupDevEnvironment/IO/DirectoryHelper.cs similarity index 100% rename from SetupDevEnvironment/IO/ExtensionsToDirectionary.cs rename to SetupDevEnvironment/IO/DirectoryHelper.cs diff --git a/SetupDevEnvironment/IO/FileMover.cs b/SetupDevEnvironment/IO/FileMover.cs index 8016f381..dd6990fa 100644 --- a/SetupDevEnvironment/IO/FileMover.cs +++ b/SetupDevEnvironment/IO/FileMover.cs @@ -1,17 +1,16 @@ namespace SetupDevEnvironment.IO { - internal class FileMover + internal class FileCopier { public static void CopyFiles(string sourceFolder, string destinationFolder) { Directory.CreateDirectory(destinationFolder); - var sourceFiles = - Directory.GetFiles(sourceFolder, "*.*", SearchOption.AllDirectories); + var sourceFiles = Directory.GetFiles(sourceFolder, "*.*", SearchOption.AllDirectories); foreach (string file in sourceFiles) { - var relativeFile = file.Replace(sourceFolder, "").Substring(1); + var relativeFile = Path.GetRelativePath(sourceFolder, file);//.Substring(sourceFolder.Length + 1); var destFile = Path.Combine(destinationFolder, relativeFile); // we may need new subfolders diff --git a/SetupDevEnvironment/IO/Links.cs b/SetupDevEnvironment/IO/Links.cs index 252f0de5..5a6bf09f 100644 --- a/SetupDevEnvironment/IO/Links.cs +++ b/SetupDevEnvironment/IO/Links.cs @@ -2,15 +2,21 @@ internal static class Links { - public static string DefaultValheimInstallFolder = + internal static string DefaultValheimInstallFolder = @"C:\Program Files (x86)\Steam\steamapps\common\Valheim"; - public static string DefaultValheimPlusDevInstallFolder = + internal static string DefaultValheimPlusDevInstallFolder = @"C:\Program Files (x86)\Steam\steamapps\common\Valheim Plus Development"; - public static readonly string BepInEx = + internal static readonly string BepInEx = @"https://valheim.thunderstore.io/package/download/denikson/BepInExPack_Valheim/5.4.1900/"; - public static readonly string AssemblyPublicizer = - @"https://github.com/elliotttate/Bepinex-Tools/releases/download/1.0.0-Publicizer/Bepinex-Publicizer.zip"; + internal static readonly string Assemblyinternalizer = + @"https://github.com/elliotttate/Bepinex-Tools/releases/download/1.0.0-internalizer/Bepinex-internalizer.zip"; + + internal static readonly string DnSpy64 = + @"https://github.com/dnSpy/dnSpy/releases/download/v6.1.8/dnSpy-net-win64.zip"; + + internal static readonly string DnSpy64TargetFolder = + @"C:\Program Files\dnSpy64"; } diff --git a/SetupDevEnvironment/IO/ProcessRunner.cs b/SetupDevEnvironment/IO/ProcessRunner.cs new file mode 100644 index 00000000..fb658168 --- /dev/null +++ b/SetupDevEnvironment/IO/ProcessRunner.cs @@ -0,0 +1,20 @@ +using System.Diagnostics; + +namespace SetupDevEnvironment.IO +{ + internal class ProcessRunner + { + internal static void Run(string path) + { + var process = new Process(); + process.StartInfo = new ProcessStartInfo() + { + UseShellExecute = true, + FileName = path + }; + + process.Start(); + process.WaitForExit(); + } + } +} diff --git a/SetupDevEnvironment/IO/ResourceHelper.cs b/SetupDevEnvironment/IO/ResourceHelper.cs new file mode 100644 index 00000000..d1c69510 --- /dev/null +++ b/SetupDevEnvironment/IO/ResourceHelper.cs @@ -0,0 +1,17 @@ +namespace SetupDevEnvironment.IO +{ + internal class ResourceHelper + { + public static string GetResource(string name) + { + var assembly = typeof(ResourceHelper).Assembly; + var resourceName = assembly.GetManifestResourceNames().Single(x => x.Contains(name)); + + using (Stream stream = assembly.GetManifestResourceStream(resourceName)) + using (StreamReader reader = new StreamReader(stream)) + { + return reader.ReadToEnd(); + } + } + } +} diff --git a/SetupDevEnvironment/InstallScript.cs b/SetupDevEnvironment/InstallScript.cs index cd014f6e..f302cefa 100644 --- a/SetupDevEnvironment/InstallScript.cs +++ b/SetupDevEnvironment/InstallScript.cs @@ -1,6 +1,8 @@ using SetupDevEnvironment.IO; +using SetupDevEnvironment.Properties; using System.ComponentModel; using System.Diagnostics; +using System.Reflection; namespace SetupDevEnvironment { @@ -30,21 +32,44 @@ public async Task Install() CopyValheimFiles(); await InstallBepInEx(); PublicizeAssembliesDirectly(); - await ConfigureEnvironment(); + ConfigureEnvironment(); + await SetupDnSpy(); } private void CopyValheimFiles() { Log("Copying existing Valheim files to Dev Environment..."); - FileMover.CopyFiles(_valheimInstallFolder, _devInstallFolder); + FileCopier.CopyFiles(_valheimInstallFolder, _devInstallFolder); Log("Done!"); } - private async Task ConfigureEnvironment() + private void ConfigureEnvironment() { Log("Configuring environment..."); Environment.SetEnvironmentVariable("VALHEIM_INSTALL", _devInstallFolder, EnvironmentVariableTarget.Machine); - await Task.CompletedTask; + Log("Done!"); + } + + private async Task SetupDnSpy() + { + Log("Installing Debug helper DnSpy..."); + var tempFolder = DirectoryHelper.CreateTempFolder(); + var dnSpyZip = await Downloader.Download(Links.DnSpy64, Path.Combine(tempFolder, "dnSpy.zip")); + var dnSpyFiles = Unzipper.Unzip(dnSpyZip, Links.DnSpy64TargetFolder); + var dnSpyExecutable = dnSpyFiles.Single(file => file.EndsWith("dnSpy.exe")); + + Log("* * * * * * * * * * * *"); + Log($"DnSpy installed to '{dnSpyExecutable}'"); + Log("* * * * * * * * * * * *"); + + Log("Creating DnSpy configuration..."); + var template = ResourceHelper.GetResource("DnSpyConfiguration.xml"); + template.Replace(@"%%DNSPYDIR%%", Links.DnSpy64TargetFolder); + template.Replace(@"%%VALHEIMPLUSINSTALLDIR%%", _devInstallFolder); + + var configurationFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "dnSpy", "dnSpy.xml"); + File.WriteAllText(configurationFile, template); + Log("Done!"); } @@ -57,7 +82,7 @@ public async Task InstallBepInEx() File.Delete(bepInExZip); var sourceFolder = bepInExFiles.Single(file => file.EndsWith("BepInExPack_Valheim/")); - FileMover.CopyFiles(sourceFolder, _devInstallFolder); + FileCopier.CopyFiles(sourceFolder, _devInstallFolder); var unstripped_corlibFiles = bepInExFiles .Where(path => path.Contains("unstripped_corlib")); @@ -69,33 +94,16 @@ public async Task InstallBepInEx() var file = Path.GetFileName(source); if (string.IsNullOrEmpty(file)) { + // ignore folders continue; } - var destination = Path.Combine($"{managedFolder}{file}"); + var destination = Path.Combine(managedFolder, file); File.Copy(source, destination, true); } Log("Done!"); } - /// - /// Install a plugin that automatically reads any file that matches "assembly_*.dll" and - /// creates a new dll where all properties, classes and fields are made public. - /// This allows devs to include these publicized dlls and use the correct consts, methods, etc. - /// - /// - public async Task PublicizeAssemblies() - { - var publicizerZip = await Downloader.Download(Links.AssemblyPublicizer); - var publicizerFiles = Unzipper.Unzip(publicizerZip); - - var file = "BepInEx-Publicizer.dll"; - var pluginDll = publicizerFiles.Single(file => file.EndsWith( - @"plugins/Bepinex-Publicizer/Bepinex-Publicizer.dll", StringComparison.InvariantCultureIgnoreCase)); - - File.Copy(pluginDll, Path.Combine(_devInstallFolder, $"BepInEx\\plugins\\{file}"), true); - } - public void PublicizeAssembliesDirectly() { Log("Publicizing assemblies..."); diff --git a/SetupDevEnvironment/Resources/DnSpyConfiguration.xml b/SetupDevEnvironment/Resources/DnSpyConfiguration.xml new file mode 100644 index 00000000..181ae1ed --- /dev/null +++ b/SetupDevEnvironment/Resources/DnSpyConfiguration.xml @@ -0,0 +1,209 @@ + + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ \ No newline at end of file diff --git a/SetupDevEnvironment/SetupDevEnvironment.csproj b/SetupDevEnvironment/SetupDevEnvironment.csproj index 4a019f57..6aa84da4 100644 --- a/SetupDevEnvironment/SetupDevEnvironment.csproj +++ b/SetupDevEnvironment/SetupDevEnvironment.csproj @@ -9,11 +9,19 @@ app.manifest + + + + + + + + True diff --git a/SetupDevEnvironment/SetupForm.Designer.cs b/SetupDevEnvironment/SetupForm.Designer.cs index 0122dd3c..29fb558a 100644 --- a/SetupDevEnvironment/SetupForm.Designer.cs +++ b/SetupDevEnvironment/SetupForm.Designer.cs @@ -37,20 +37,24 @@ private void InitializeComponent() this.tbValheimInstallDir = new System.Windows.Forms.TextBox(); this.tbLog = new System.Windows.Forms.TextBox(); this.btEditConfig = new System.Windows.Forms.Button(); + this.btStartDnSpy = new System.Windows.Forms.Button(); this.SuspendLayout(); // // tbValheimPlusInstallDir // this.tbValheimPlusInstallDir.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.tbValheimPlusInstallDir.Enabled = false; this.tbValheimPlusInstallDir.Location = new System.Drawing.Point(12, 84); this.tbValheimPlusInstallDir.Name = "tbValheimPlusInstallDir"; - this.tbValheimPlusInstallDir.Size = new System.Drawing.Size(848, 23); + this.tbValheimPlusInstallDir.PlaceholderText = "Where would you like to create the Valheim Plus folder?"; + this.tbValheimPlusInstallDir.Size = new System.Drawing.Size(739, 23); this.tbValheimPlusInstallDir.TabIndex = 0; // // label1 // this.label1.AutoSize = true; + this.label1.BackColor = System.Drawing.Color.Transparent; this.label1.Location = new System.Drawing.Point(18, 63); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(174, 15); @@ -71,7 +75,7 @@ private void InitializeComponent() // this.btStartInstallation.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); this.btStartInstallation.Enabled = false; - this.btStartInstallation.Location = new System.Drawing.Point(12, 488); + this.btStartInstallation.Location = new System.Drawing.Point(12, 460); this.btStartInstallation.Name = "btStartInstallation"; this.btStartInstallation.Size = new System.Drawing.Size(161, 62); this.btStartInstallation.TabIndex = 3; @@ -92,6 +96,7 @@ private void InitializeComponent() // label2 // this.label2.AutoSize = true; + this.label2.BackColor = System.Drawing.Color.Transparent; this.label2.Location = new System.Drawing.Point(18, 9); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(149, 15); @@ -102,9 +107,11 @@ private void InitializeComponent() // this.tbValheimInstallDir.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.tbValheimInstallDir.Enabled = false; this.tbValheimInstallDir.Location = new System.Drawing.Point(12, 30); this.tbValheimInstallDir.Name = "tbValheimInstallDir"; - this.tbValheimInstallDir.Size = new System.Drawing.Size(848, 23); + this.tbValheimInstallDir.PlaceholderText = "Where has Steam installed Valheim?"; + this.tbValheimInstallDir.Size = new System.Drawing.Size(739, 23); this.tbValheimInstallDir.TabIndex = 4; // // tbLog @@ -112,18 +119,18 @@ private void InitializeComponent() this.tbLog.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); - this.tbLog.Location = new System.Drawing.Point(12, 165); + this.tbLog.Location = new System.Drawing.Point(12, 113); this.tbLog.Multiline = true; this.tbLog.Name = "tbLog"; - this.tbLog.Size = new System.Drawing.Size(848, 317); + this.tbLog.Size = new System.Drawing.Size(739, 341); this.tbLog.TabIndex = 7; this.tbLog.Visible = false; // // btEditConfig // - this.btEditConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); + this.btEditConfig.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); this.btEditConfig.Enabled = false; - this.btEditConfig.Location = new System.Drawing.Point(699, 488); + this.btEditConfig.Location = new System.Drawing.Point(590, 460); this.btEditConfig.Name = "btEditConfig"; this.btEditConfig.Size = new System.Drawing.Size(161, 62); this.btEditConfig.TabIndex = 8; @@ -131,13 +138,26 @@ private void InitializeComponent() this.btEditConfig.UseVisualStyleBackColor = true; this.btEditConfig.Click += new System.EventHandler(this.btEditConfig_Click); // + // btStartDnSpy + // + this.btStartDnSpy.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); + this.btStartDnSpy.Enabled = false; + this.btStartDnSpy.Location = new System.Drawing.Point(423, 460); + this.btStartDnSpy.Name = "btStartDnSpy"; + this.btStartDnSpy.Size = new System.Drawing.Size(161, 62); + this.btStartDnSpy.TabIndex = 9; + this.btStartDnSpy.Text = "Start DnSpy"; + this.btStartDnSpy.UseVisualStyleBackColor = true; + this.btStartDnSpy.Click += new System.EventHandler(this.btStartDnSpy_Click); + // // SetupForm // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackgroundImage = global::SetupDevEnvironment.Properties.Resources.Valheim_Wallpaper; this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; - this.ClientSize = new System.Drawing.Size(872, 562); + this.ClientSize = new System.Drawing.Size(763, 534); + this.Controls.Add(this.btStartDnSpy); this.Controls.Add(this.btEditConfig); this.Controls.Add(this.tbLog); this.Controls.Add(this.btBrowseValheimInstallDir); @@ -150,7 +170,7 @@ private void InitializeComponent() this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog; this.Name = "SetupForm"; this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide; - this.Text = "Form1"; + this.Text = "Valheim Plus Development Plus Setup"; this.ResumeLayout(false); this.PerformLayout(); @@ -167,5 +187,6 @@ private void InitializeComponent() private TextBox tbValheimInstallDir; private TextBox tbLog; private Button btEditConfig; + private Button btStartDnSpy; } } \ No newline at end of file diff --git a/SetupDevEnvironment/SetupForm.cs b/SetupDevEnvironment/SetupForm.cs index 74f90abf..c3f54b1f 100644 --- a/SetupDevEnvironment/SetupForm.cs +++ b/SetupDevEnvironment/SetupForm.cs @@ -1,7 +1,5 @@ using SetupDevEnvironment.IO; using System.ComponentModel; -using System.Diagnostics; -using static System.Net.Mime.MediaTypeNames; namespace SetupDevEnvironment { @@ -9,7 +7,6 @@ public partial class SetupForm : Form { private string? ValheimInstallPath { get; set; } = null; private string? ValheimPlusInstallPath { get; set; } = null; - private Task _installTask = Task.CompletedTask; public SetupForm() { @@ -19,7 +16,8 @@ public SetupForm() private void EnableStartButton() { if (Directory.Exists(tbValheimInstallDir.Text) && - Directory.Exists(tbValheimPlusInstallDir.Text)) + Directory.Exists(tbValheimPlusInstallDir.Text) && + tbValheimInstallDir.Text != tbValheimPlusInstallDir.Text) { btStartInstallation.Enabled = true; } else @@ -55,6 +53,12 @@ private void btBrowseVPlusInstallDir_Click(object sender, EventArgs e) if (path == string.Empty) return; + if (path == ValheimInstallPath) + { + MessageBox.Show("Folders can't be the same. Let's try that again."); + return; + } + ValheimPlusInstallPath = path; tbValheimPlusInstallDir.Text = ValheimPlusInstallPath; tbValheimPlusInstallDir.Invalidate(); @@ -73,6 +77,7 @@ private async void btStartInstallation_Click(object sender, EventArgs e) await script.Install(); btEditConfig.Enabled = true; + btStartDnSpy.Enabled = true; EnableStartButton(); } @@ -94,12 +99,16 @@ private static string GetFolder(string initialPath) return odd.SelectedPath; } - + /// + /// yes, old school. but it works. + /// + /// + /// private void OnLogMessage(object? sender, ProgressChangedEventArgs e) { if (InvokeRequired) { - Invoke((Action)UpdateLog, (string)e.UserState); + Invoke(UpdateLog, (string)e.UserState); return; } UpdateLog((string)e.UserState); @@ -112,15 +121,12 @@ private void UpdateLog(string text) private void btEditConfig_Click(object sender, EventArgs e) { - var process = new Process(); - process.StartInfo = new ProcessStartInfo() - { - UseShellExecute = true, - FileName = Path.Combine(ValheimPlusInstallPath, "BepInEx\\config\\BepInEx.cfg") - }; + ProcessRunner.Run(Path.Combine(ValheimPlusInstallPath, "BepInEx\\config\\BepInEx.cfg")); + } - process.Start(); - process.WaitForExit(); + private void btStartDnSpy_Click(object sender, EventArgs e) + { + ProcessRunner.Run(Path.Combine(Links.DnSpy64TargetFolder, "dnSpy.exe")); } } } \ No newline at end of file From 7a8bffff65d65475f03944b3dbe6c52765bfefbc Mon Sep 17 00:00:00 2001 From: Joost Boomkamp Date: Wed, 30 Nov 2022 11:44:08 +0100 Subject: [PATCH 4/9] preconfigure dnSpy --- SetupDevEnvironment/App.config | 18 +++++++ SetupDevEnvironment/IO/ProcessRunner.cs | 5 +- SetupDevEnvironment/InstallScript.cs | 36 ++++++------- .../Properties/Settings.Designer.cs | 50 +++++++++++++++++++ .../Properties/Settings.settings | 12 +++++ SetupDevEnvironment/Settings.cs | 36 +++++++++++++ .../SetupDevEnvironment.csproj | 12 +++++ SetupDevEnvironment/SetupForm.cs | 21 ++++++-- ValheimPlus.sln | 2 +- 9 files changed, 163 insertions(+), 29 deletions(-) create mode 100644 SetupDevEnvironment/App.config create mode 100644 SetupDevEnvironment/Properties/Settings.Designer.cs create mode 100644 SetupDevEnvironment/Properties/Settings.settings create mode 100644 SetupDevEnvironment/Settings.cs diff --git a/SetupDevEnvironment/App.config b/SetupDevEnvironment/App.config new file mode 100644 index 00000000..514b2e92 --- /dev/null +++ b/SetupDevEnvironment/App.config @@ -0,0 +1,18 @@ + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/SetupDevEnvironment/IO/ProcessRunner.cs b/SetupDevEnvironment/IO/ProcessRunner.cs index fb658168..99484e30 100644 --- a/SetupDevEnvironment/IO/ProcessRunner.cs +++ b/SetupDevEnvironment/IO/ProcessRunner.cs @@ -10,11 +10,10 @@ internal static void Run(string path) process.StartInfo = new ProcessStartInfo() { UseShellExecute = true, - FileName = path - }; + FileName = path, + }; process.Start(); - process.WaitForExit(); } } } diff --git a/SetupDevEnvironment/InstallScript.cs b/SetupDevEnvironment/InstallScript.cs index f302cefa..81e5be81 100644 --- a/SetupDevEnvironment/InstallScript.cs +++ b/SetupDevEnvironment/InstallScript.cs @@ -1,15 +1,11 @@ using SetupDevEnvironment.IO; -using SetupDevEnvironment.Properties; using System.ComponentModel; -using System.Diagnostics; using System.Reflection; namespace SetupDevEnvironment { internal class InstallScript { - private readonly string _valheimInstallFolder; - private readonly string _devInstallFolder; public event ProgressChangedEventHandler? OnLogMessage; @@ -21,12 +17,6 @@ private void Log(string msg) } } - public InstallScript(string valheimFolder, string valheimPlusFolder) - { - _valheimInstallFolder = valheimFolder; - _devInstallFolder = valheimPlusFolder; - } - public async Task Install() { CopyValheimFiles(); @@ -39,14 +29,14 @@ public async Task Install() private void CopyValheimFiles() { Log("Copying existing Valheim files to Dev Environment..."); - FileCopier.CopyFiles(_valheimInstallFolder, _devInstallFolder); + FileCopier.CopyFiles(Settings.ValheimInstallDir, Settings.ValheimPlusDevInstallDir); Log("Done!"); } private void ConfigureEnvironment() { Log("Configuring environment..."); - Environment.SetEnvironmentVariable("VALHEIM_INSTALL", _devInstallFolder, EnvironmentVariableTarget.Machine); + Environment.SetEnvironmentVariable("VALHEIM_INSTALL", Settings.ValheimPlusDevInstallDir, EnvironmentVariableTarget.Machine); Log("Done!"); } @@ -58,18 +48,24 @@ private async Task SetupDnSpy() var dnSpyFiles = Unzipper.Unzip(dnSpyZip, Links.DnSpy64TargetFolder); var dnSpyExecutable = dnSpyFiles.Single(file => file.EndsWith("dnSpy.exe")); - Log("* * * * * * * * * * * *"); Log($"DnSpy installed to '{dnSpyExecutable}'"); - Log("* * * * * * * * * * * *"); - + Log("Done!"); + Log("Creating DnSpy configuration..."); var template = ResourceHelper.GetResource("DnSpyConfiguration.xml"); - template.Replace(@"%%DNSPYDIR%%", Links.DnSpy64TargetFolder); - template.Replace(@"%%VALHEIMPLUSINSTALLDIR%%", _devInstallFolder); + template = template.Replace(@"%%DNSPYDIR%%", Links.DnSpy64TargetFolder); + template = template.Replace(@"%%VALHEIMPLUSINSTALLDIR%%", Settings.ValheimPlusDevInstallDir); var configurationFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "dnSpy", "dnSpy.xml"); File.WriteAllText(configurationFile, template); + Log("Done!"); + Log("Installing patched mono dll..."); + var executablePath = Assembly.GetEntryAssembly().Location; + var libPath = Path.Combine(executablePath, "../../../../../libraries/Debug/mono-2.0-bdwgc.dll"); + var destinationPath = Path.Combine(Settings.ValheimPlusDevInstallDir, "MonoBleedingEdge\\EmbedRuntime\\mono-2.0-bdwgc.dll"); + File.Copy(destinationPath, destinationPath + ".bak", true); + File.Copy(libPath, destinationPath, true); Log("Done!"); } @@ -82,12 +78,12 @@ public async Task InstallBepInEx() File.Delete(bepInExZip); var sourceFolder = bepInExFiles.Single(file => file.EndsWith("BepInExPack_Valheim/")); - FileCopier.CopyFiles(sourceFolder, _devInstallFolder); + FileCopier.CopyFiles(sourceFolder, Settings.ValheimPlusDevInstallDir); var unstripped_corlibFiles = bepInExFiles .Where(path => path.Contains("unstripped_corlib")); - var managedFolder = Path.Combine(_devInstallFolder, $"valheim_Data\\Managed\\"); + var managedFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"valheim_Data\\Managed\\"); Directory.CreateDirectory(managedFolder); foreach (var source in unstripped_corlibFiles) { @@ -109,7 +105,7 @@ public void PublicizeAssembliesDirectly() Log("Publicizing assemblies..."); var pubber = new AssemblyPublicizer(); pubber.OnLogMessage += this.OnLogMessage; - pubber.ProcessAssemblies(_devInstallFolder); + pubber.ProcessAssemblies(Settings.ValheimPlusDevInstallDir); Log("Done!"); } } diff --git a/SetupDevEnvironment/Properties/Settings.Designer.cs b/SetupDevEnvironment/Properties/Settings.Designer.cs new file mode 100644 index 00000000..0b3b4e9a --- /dev/null +++ b/SetupDevEnvironment/Properties/Settings.Designer.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace SetupDevEnvironment.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ValheimInstallDir { + get { + return ((string)(this["ValheimInstallDir"])); + } + set { + this["ValheimInstallDir"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string ValheimPlusDevInstallDir { + get { + return ((string)(this["ValheimPlusDevInstallDir"])); + } + set { + this["ValheimPlusDevInstallDir"] = value; + } + } + } +} diff --git a/SetupDevEnvironment/Properties/Settings.settings b/SetupDevEnvironment/Properties/Settings.settings new file mode 100644 index 00000000..f24a61a8 --- /dev/null +++ b/SetupDevEnvironment/Properties/Settings.settings @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/SetupDevEnvironment/Settings.cs b/SetupDevEnvironment/Settings.cs new file mode 100644 index 00000000..2b878ea3 --- /dev/null +++ b/SetupDevEnvironment/Settings.cs @@ -0,0 +1,36 @@ +using SetupDevEnvironment.IO; + +namespace SetupDevEnvironment +{ + internal static class Settings + { + public static string ValheimInstallDir + { + get + { + return + string.IsNullOrEmpty(Properties.Settings.Default.ValheimInstallDir) + ? Links.DefaultValheimInstallFolder + : Properties.Settings.Default.ValheimInstallDir; + } + set + { + Properties.Settings.Default.ValheimInstallDir = value; + } + } + public static string ValheimPlusDevInstallDir + { + get + { + return + string.IsNullOrEmpty(Properties.Settings.Default.ValheimPlusDevInstallDir) + ? Links.DefaultValheimInstallFolder + : Properties.Settings.Default.ValheimPlusDevInstallDir; + } + set + { + Properties.Settings.Default.ValheimPlusDevInstallDir = value; + } + } + } +} \ No newline at end of file diff --git a/SetupDevEnvironment/SetupDevEnvironment.csproj b/SetupDevEnvironment/SetupDevEnvironment.csproj index 6aa84da4..9a5b3ce4 100644 --- a/SetupDevEnvironment/SetupDevEnvironment.csproj +++ b/SetupDevEnvironment/SetupDevEnvironment.csproj @@ -28,6 +28,11 @@ True Resources.resx + + True + True + Settings.settings + @@ -37,4 +42,11 @@ + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + \ No newline at end of file diff --git a/SetupDevEnvironment/SetupForm.cs b/SetupDevEnvironment/SetupForm.cs index c3f54b1f..6b34f161 100644 --- a/SetupDevEnvironment/SetupForm.cs +++ b/SetupDevEnvironment/SetupForm.cs @@ -1,16 +1,26 @@ using SetupDevEnvironment.IO; using System.ComponentModel; +#nullable disable namespace SetupDevEnvironment { public partial class SetupForm : Form { - private string? ValheimInstallPath { get; set; } = null; - private string? ValheimPlusInstallPath { get; set; } = null; + private string ValheimInstallPath + { + get => Settings.ValheimInstallDir; + set { Settings.ValheimInstallDir = value; } + } + private string ValheimPlusInstallPath + { + get => Settings.ValheimPlusDevInstallDir; + set { Settings.ValheimPlusDevInstallDir = value; } + } public SetupForm() { InitializeComponent(); + EnableStartButton(); } private void EnableStartButton() @@ -20,7 +30,8 @@ private void EnableStartButton() tbValheimInstallDir.Text != tbValheimPlusInstallDir.Text) { btStartInstallation.Enabled = true; - } else + } + else { btStartInstallation.Enabled = false; } @@ -36,7 +47,7 @@ private void btBrowseValheimInstallDir_Click(object sender, EventArgs e) tbValheimInstallDir.Text = ValheimInstallPath; tbValheimInstallDir.Invalidate(); - if (string.IsNullOrEmpty(ValheimPlusInstallPath)) + if (ValheimPlusInstallPath == Links.DefaultValheimPlusDevInstallFolder) { var steamRoot = Directory.GetParent(path); ValheimPlusInstallPath = Path.Combine(steamRoot.FullName, "Valheim Plus Development"); @@ -72,7 +83,7 @@ private async void btStartInstallation_Click(object sender, EventArgs e) tbLog.Enabled = false; tbLog.Visible = true; - var script = new InstallScript(ValheimInstallPath, ValheimPlusInstallPath); + var script = new InstallScript(); script.OnLogMessage += OnLogMessage; await script.Install(); diff --git a/ValheimPlus.sln b/ValheimPlus.sln index 874a0a19..547e7531 100644 --- a/ValheimPlus.sln +++ b/ValheimPlus.sln @@ -20,7 +20,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "unix", "unix", "{7FBDF646-C resources\unix\start_server_bepinex.sh = resources\unix\start_server_bepinex.sh EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SetupDevEnvironment", "SetupDevEnvironment\SetupDevEnvironment.csproj", "{70D1B8BE-D049-4155-8D48-9B01EF38A6AC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SetupDevEnvironment", "SetupDevEnvironment\SetupDevEnvironment.csproj", "{70D1B8BE-D049-4155-8D48-9B01EF38A6AC}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution From 7911f494bcf8092aa464c16c85de585c93d3a4d2 Mon Sep 17 00:00:00 2001 From: Joost Boomkamp Date: Sun, 4 Dec 2022 12:06:38 +0100 Subject: [PATCH 5/9] easier logging, config file as resource --- SetupDevEnvironment/IO/AssemblyPublicizer.cs | 90 +- SetupDevEnvironment/IO/FileMover.cs | 4 +- SetupDevEnvironment/IO/Links.cs | 14 +- SetupDevEnvironment/IO/Unzipper.cs | 50 +- SetupDevEnvironment/InstallScript.cs | 209 ++-- SetupDevEnvironment/Logger.cs | 29 + .../Resources/valheim_plus.cfg | 1106 +++++++++++++++++ SetupDevEnvironment/Settings.cs | 2 +- .../SetupDevEnvironment.csproj | 4 +- SetupDevEnvironment/SetupForm.Designer.cs | 1 + SetupDevEnvironment/SetupForm.cs | 25 +- 11 files changed, 1375 insertions(+), 159 deletions(-) create mode 100644 SetupDevEnvironment/Logger.cs create mode 100644 SetupDevEnvironment/Resources/valheim_plus.cfg diff --git a/SetupDevEnvironment/IO/AssemblyPublicizer.cs b/SetupDevEnvironment/IO/AssemblyPublicizer.cs index dcc02636..fd9d1943 100644 --- a/SetupDevEnvironment/IO/AssemblyPublicizer.cs +++ b/SetupDevEnvironment/IO/AssemblyPublicizer.cs @@ -1,7 +1,6 @@ //elliotttate/Bepinex-Tools using dnlib.DotNet; -using System.ComponentModel; using System.Reflection; using FieldAttributes = dnlib.DotNet.FieldAttributes; using MethodAttributes = dnlib.DotNet.MethodAttributes; @@ -11,14 +10,9 @@ namespace SetupDevEnvironment.IO; internal class AssemblyPublicizer { - public event ProgressChangedEventHandler? OnLogMessage; - - private void Log(string msg) + public AssemblyPublicizer() { - if (OnLogMessage != null) - { - OnLogMessage(this, new ProgressChangedEventArgs(0, msg)); - } + Logger.Start(); } public void ProcessAssemblies(string valheimPlusInstallDir) @@ -35,16 +29,16 @@ public void ProcessAssemblies(string valheimPlusInstallDir) ProcessAssembly(assembly); } catch(Exception ex) { - Log(ex.Message); + Logger.Log(ex.Message); } } } - void ProcessAssembly(Assembly assembly) + static void ProcessAssembly(Assembly assembly) { string assemblyPath = assembly.Location; - string filename = assembly.GetName().Name; - string outputPath = Path.Combine(Path.GetDirectoryName(assemblyPath), "publicized_assemblies"); + string filename = assembly.GetName().Name!; + string outputPath = Path.Combine(Path.GetDirectoryName(assemblyPath)!, "publicized_assemblies"); string outputSuffix = "_publicized"; Directory.CreateDirectory(outputPath); @@ -52,7 +46,7 @@ void ProcessAssembly(Assembly assembly) string curHash = ComputeHash(assembly); string hashPath = Path.Combine(outputPath, $"{filename}{outputSuffix}.hash"); - string lastHash = null; + string lastHash = string.Empty; if (File.Exists(hashPath)) lastHash = File.ReadAllText(hashPath); @@ -60,7 +54,7 @@ void ProcessAssembly(Assembly assembly) if (curHash == lastHash) return; - Log($"Making a public assembly from {filename}"); + Logger.Log($"Making a public assembly from {filename}"); RewriteAssembly(assemblyPath).Write($"{Path.Combine(outputPath, filename)}{outputSuffix}.dll"); File.WriteAllText(hashPath, curHash); } @@ -72,36 +66,54 @@ static string ComputeHash(Assembly assembly) static ModuleDef RewriteAssembly(string assemblyPath) { - ModuleDef assembly = ModuleDefMD.Load(assemblyPath); - - foreach (var type in assembly.GetTypes()) + var assembly = ModuleDefMD.Load(assemblyPath); + var types = assembly.GetTypes(); + Logger.Log($"{assembly.Name}: {types.Count()} types"); + foreach (var type in types) { - type.Attributes &= ~TypeAttributes.VisibilityMask; + MakeTypePublic(assembly, type); + MakeMethodsPublic(assembly, type); + MakeFieldsPublic(assembly, type); + } - if (type.IsNested) - type.Attributes |= TypeAttributes.NestedPublic; - else - type.Attributes |= TypeAttributes.Public; + return assembly; + } - foreach (MethodDef method in type.Methods) - { - method.Attributes &= ~MethodAttributes.MemberAccessMask; - method.Attributes |= MethodAttributes.Public; - } + private static void MakeFieldsPublic(ModuleDef assembly, TypeDef type) + { + var eventNames = type.Events + .Select(ev => ev.Name.ToString()).ToList(); - List eventNames = new List(); - foreach (EventDef ev in type.Events) - eventNames.Add(ev.Name); + var fields = type.Fields + .Where(x => !eventNames.Contains(x.Name)).ToArray(); - foreach (FieldDef field in type.Fields) - { - if (!eventNames.Contains(field.Name)) - { - field.Attributes &= ~FieldAttributes.FieldAccessMask; - field.Attributes |= FieldAttributes.Public; - } - } + Logger.Log($"{assembly.Name}\\{type.Name}: {fields.Length} fields"); + + foreach (FieldDef field in fields) + { + field.Attributes &= ~FieldAttributes.FieldAccessMask; + field.Attributes |= FieldAttributes.Public; + } + } + + private static void MakeTypePublic(ModuleDef assembly, TypeDef type) + { + Logger.Log($"{assembly.Name}\\{type.Name}"); + + type.Attributes &= ~TypeAttributes.VisibilityMask; + if (type.IsNested) + type.Attributes |= TypeAttributes.NestedPublic; + else + type.Attributes |= TypeAttributes.Public; + } + + private static void MakeMethodsPublic(ModuleDef assembly, TypeDef type) + { + Logger.Log($"{assembly.Name}\\{type.Name}: {type.Methods.Count} Methods"); + foreach (MethodDef method in type.Methods) + { + method.Attributes &= ~MethodAttributes.MemberAccessMask; + method.Attributes |= MethodAttributes.Public; } - return assembly; } } diff --git a/SetupDevEnvironment/IO/FileMover.cs b/SetupDevEnvironment/IO/FileMover.cs index dd6990fa..551e4147 100644 --- a/SetupDevEnvironment/IO/FileMover.cs +++ b/SetupDevEnvironment/IO/FileMover.cs @@ -10,12 +10,12 @@ public static void CopyFiles(string sourceFolder, string destinationFolder) foreach (string file in sourceFiles) { - var relativeFile = Path.GetRelativePath(sourceFolder, file);//.Substring(sourceFolder.Length + 1); + var relativeFile = Path.GetRelativePath(sourceFolder, file); var destFile = Path.Combine(destinationFolder, relativeFile); // we may need new subfolders var folder = Path.GetDirectoryName(destFile); - Directory.CreateDirectory(folder); + Directory.CreateDirectory(folder!); File.Copy(file, destFile, true); } diff --git a/SetupDevEnvironment/IO/Links.cs b/SetupDevEnvironment/IO/Links.cs index 5a6bf09f..87c2c056 100644 --- a/SetupDevEnvironment/IO/Links.cs +++ b/SetupDevEnvironment/IO/Links.cs @@ -4,19 +4,23 @@ internal static class Links { internal static string DefaultValheimInstallFolder = @"C:\Program Files (x86)\Steam\steamapps\common\Valheim"; - internal static string DefaultValheimPlusDevInstallFolder = @"C:\Program Files (x86)\Steam\steamapps\common\Valheim Plus Development"; + internal static readonly string DnSpy64TargetFolder = + @"C:\Program Files\dnSpy64"; internal static readonly string BepInEx = @"https://valheim.thunderstore.io/package/download/denikson/BepInExPack_Valheim/5.4.1900/"; + internal static readonly string BepInEx21 = + @"https://github.com/BepInEx/BepInEx/releases/download/v5.4.21/BepInEx_x64_5.4.21.0.zip"; - internal static readonly string Assemblyinternalizer = - @"https://github.com/elliotttate/Bepinex-Tools/releases/download/1.0.0-internalizer/Bepinex-internalizer.zip"; + internal static readonly string Unstripped_Corlib = + @"https://cdn.discordapp.com/attachments/624272422295568435/841990037935882250/unstripped_corlib.7z"; internal static readonly string DnSpy64 = @"https://github.com/dnSpy/dnSpy/releases/download/v6.1.8/dnSpy-net-win64.zip"; - internal static readonly string DnSpy64TargetFolder = - @"C:\Program Files\dnSpy64"; + [Obsolete("we're doing this ourselves now", true)] + internal static readonly string Assemblyinternalizer = + @"https://github.com/elliotttate/Bepinex-Tools/releases/download/1.0.0-internalizer/Bepinex-internalizer.zip"; } diff --git a/SetupDevEnvironment/IO/Unzipper.cs b/SetupDevEnvironment/IO/Unzipper.cs index 247fcf27..d765e089 100644 --- a/SetupDevEnvironment/IO/Unzipper.cs +++ b/SetupDevEnvironment/IO/Unzipper.cs @@ -1,4 +1,6 @@ -using System.IO.Compression; +using SharpCompress.Common; +using SharpCompress.Readers; +using System.IO.Compression; namespace SetupDevEnvironment.IO { @@ -10,20 +12,50 @@ internal static class Unzipper /// /// /// - public static string[] Unzip(string filename, string? targetFolder = null) + public static string[] Unzip(string filename, string? targetFolder = null) { targetFolder = targetFolder ?? DirectoryHelper.CreateTempFolder(); Directory.CreateDirectory(targetFolder); - using (var zipFileStream = new FileStream(filename, FileMode.Open)) - using (var zipfile = new ZipArchive(zipFileStream)) + var archive = SharpCompress.Archives.ArchiveFactory.Open(filename); + using (var reader = archive.ExtractAllEntries()) { - zipfile.ExtractToDirectory(targetFolder, true); - - return zipfile.Entries - .Select(entry => Path.Combine(targetFolder, entry.FullName)) - .ToArray(); + reader.WriteAllToDirectory(targetFolder, new ExtractionOptions { ExtractFullPath = true, Overwrite = true, PreserveFileTime = true }); } + return archive.Entries.Select(e => Path.Combine(targetFolder, e.Key)).ToArray(); } + // switch (Path.GetExtension(filename).ToLower()) + // { + // case ".zip": + // return UnzipZip(filename, targetFolder); + // case ".7z": + // return Unzip7z(filename, targetFolder); + // } + //} + + //private static string[] Unzip7z(string filename, string? targetFolder) + //{ + // using (var zipFileStream = new SharpCompress.Archives.SevenZip.(filename)) + // using (var zipfile = new ZipArchive(zipFileStream)) + // { + // zipfile.ExtractToDirectory(targetFolder, true); + + // return zipfile.Entries + // .Select(entry => Path.Combine(targetFolder, entry.FullName)) + // .ToArray(); + // } + //} + + //public static string[] UnzipZip(string filename, string? targetFolder = null) + //{ + // using (var zipFileStream = new FileStream(filename, FileMode.Open)) + // using (var zipfile = new ZipArchive(zipFileStream)) + // { + // zipfile.ExtractToDirectory(targetFolder, true); + + // return zipfile.Entries + // .Select(entry => Path.Combine(targetFolder, entry.FullName)) + // .ToArray(); + // } } } diff --git a/SetupDevEnvironment/InstallScript.cs b/SetupDevEnvironment/InstallScript.cs index 81e5be81..d9cb318f 100644 --- a/SetupDevEnvironment/InstallScript.cs +++ b/SetupDevEnvironment/InstallScript.cs @@ -1,112 +1,141 @@ using SetupDevEnvironment.IO; -using System.ComponentModel; using System.Reflection; -namespace SetupDevEnvironment +namespace SetupDevEnvironment; +internal class InstallScript { - internal class InstallScript + public InstallScript() { + Logger.Start(); + } - public event ProgressChangedEventHandler? OnLogMessage; + public async Task Install() + { + //1.Download the[BepInEx for Valheim package](https://valheim.thunderstore.io/package/download/denikson/BepInExPack_Valheim/5.4.1901/). + //1.Extract zip contents and copy the contents inside `/ BepInExPack_Valheim /` and paste them in your Valheim root folder and overwrite every file when asked. + //1.Copy over all the DLLs from Valheim/ unstripped_corlib to Valheim / valheim_Data / Managed * (overwrite when asked) * + //1.Download the[AssemblyPublicizer package](https://mega.nz/file/oQxEjCJI#_XPXEjwLfv9zpcF2HRakYzepMwaUXflA9txxhx4tACA). + //1.Drag and drop all `assembly_ *.dll` files from "\Valheim\valheim_Data\Managed\" folder onto "AssemblyPublicizer.exe". + //1.Define Environment Variable `VALHEIM_INSTALL` with path to Valheim Install Directory + + CopyValheimFiles(); + await InstallBepInEx542100(); + await InstallUnstrippedFiles(); + PublicizeAssembliesDirectly(); + await SetupDnSpy(); + ConfigureEnvironment(); + Logger.Log("All Done, have a nice dev."); + } - private void Log(string msg) - { - if (OnLogMessage != null) - { - OnLogMessage(this, new ProgressChangedEventArgs(0, msg )); - } - } + private static void CopyValheimFiles() + { + Logger.Log("Copying existing Valheim files to Dev Environment..."); + FileCopier.CopyFiles(Settings.ValheimInstallDir, Settings.ValheimPlusDevInstallDir); + Logger.Log("Done!"); + } - public async Task Install() + private static void ConfigureEnvironment() + { + Logger.Log("Configuring environment..."); + Environment.SetEnvironmentVariable("VALHEIM_INSTALL", Settings.ValheimPlusDevInstallDir, EnvironmentVariableTarget.Machine); + var configPath = Path.Combine(Settings.ValheimPlusDevInstallDir, "BepInEx\\config\\"); + + Directory.CreateDirectory(configPath); + var configFile = Path.Combine(configPath, "valheim_plus.cfg"); + if (!File.Exists(configFile)) { - CopyValheimFiles(); - await InstallBepInEx(); - PublicizeAssembliesDirectly(); - ConfigureEnvironment(); - await SetupDnSpy(); + var defaultConfig = ResourceHelper.GetResource("valheim_plus.cfg"); + File.WriteAllText(configFile, defaultConfig); } + Logger.Log("Done!"); + } - private void CopyValheimFiles() + private static async Task SetupDnSpy() + { + Logger.Log("Installing Debug helper DnSpy..."); + var tempFolder = DirectoryHelper.CreateTempFolder(); + var dnSpyZip = await Downloader.Download(Links.DnSpy64, Path.Combine(tempFolder, "dnSpy.zip")); + var dnSpyFiles = Unzipper.Unzip(dnSpyZip, Links.DnSpy64TargetFolder); + var dnSpyExecutable = dnSpyFiles.Single(file => file.EndsWith("dnSpy.exe")); + + Logger.Log($"DnSpy installed to '{dnSpyExecutable}'"); + Logger.Log("Done!"); + + Logger.Log("Creating DnSpy configuration..."); + var template = ResourceHelper.GetResource("DnSpyConfiguration.xml"); + template = template.Replace(@"%%DNSPYDIR%%", Links.DnSpy64TargetFolder); + template = template.Replace(@"%%VALHEIMPLUSINSTALLDIR%%", Settings.ValheimPlusDevInstallDir); + + var configurationFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "dnSpy", "dnSpy.xml"); + if (File.Exists(configurationFile)) { - Log("Copying existing Valheim files to Dev Environment..."); - FileCopier.CopyFiles(Settings.ValheimInstallDir, Settings.ValheimPlusDevInstallDir); - Log("Done!"); + Logger.Log("backing up existing dnSpy config"); + File.Copy(configurationFile, configurationFile + ".ValheimPlus.bak", true); } + File.WriteAllText(configurationFile, template); + Logger.Log("Done!"); + + Logger.Log("Installing patched mono dll..."); + var executablePath = Path.GetDirectoryName(Assembly.GetEntryAssembly()!.Location); + var libPath = Path.Combine(executablePath!, "../../../../libraries/Debug/mono-2.0-bdwgc.dll"); + var destinationPath = Path.Combine(Settings.ValheimPlusDevInstallDir, "MonoBleedingEdge\\EmbedRuntime\\mono-2.0-bdwgc.dll"); + File.Copy(destinationPath, destinationPath + ".bak", true); + File.Copy(libPath, destinationPath, true); + Logger.Log("Done!"); + } - private void ConfigureEnvironment() - { - Log("Configuring environment..."); - Environment.SetEnvironmentVariable("VALHEIM_INSTALL", Settings.ValheimPlusDevInstallDir, EnvironmentVariableTarget.Machine); - Log("Done!"); - } + public static async Task InstallBepInEx541900() + { + Logger.Log("Installing BepInEx..."); + var tempFolder = DirectoryHelper.CreateTempFolder(); + var bepInExZip = await Downloader.Download(Links.BepInEx, Path.Combine(tempFolder, "bepInExPack.zip")); + var bepInExFiles = Unzipper.Unzip(bepInExZip); + File.Delete(bepInExZip); + + var sourceFolder = bepInExFiles.Single(file => file.EndsWith("BepInExPack_Valheim/")); + FileCopier.CopyFiles(sourceFolder, Settings.ValheimPlusDevInstallDir); + } - private async Task SetupDnSpy() + public static async Task InstallUnstrippedFiles() + { + var tempFolder = DirectoryHelper.CreateTempFolder(); + var unstrippedZip = await Downloader.Download(Links.Unstripped_Corlib, Path.Combine(tempFolder, "unstripped.zip")); + var unstripped_corlibFiles = Unzipper.Unzip(unstrippedZip); + + var managedFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"valheim_Data\\Managed\\"); + //var coreLibFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"valheim_Data\\unstripped_corlib\\"); + Directory.CreateDirectory(managedFolder); + foreach (var source in unstripped_corlibFiles) { - Log("Installing Debug helper DnSpy..."); - var tempFolder = DirectoryHelper.CreateTempFolder(); - var dnSpyZip = await Downloader.Download(Links.DnSpy64, Path.Combine(tempFolder, "dnSpy.zip")); - var dnSpyFiles = Unzipper.Unzip(dnSpyZip, Links.DnSpy64TargetFolder); - var dnSpyExecutable = dnSpyFiles.Single(file => file.EndsWith("dnSpy.exe")); - - Log($"DnSpy installed to '{dnSpyExecutable}'"); - Log("Done!"); - - Log("Creating DnSpy configuration..."); - var template = ResourceHelper.GetResource("DnSpyConfiguration.xml"); - template = template.Replace(@"%%DNSPYDIR%%", Links.DnSpy64TargetFolder); - template = template.Replace(@"%%VALHEIMPLUSINSTALLDIR%%", Settings.ValheimPlusDevInstallDir); + if (File.GetAttributes(source).HasFlag(FileAttributes.Directory)) { continue; } - var configurationFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "dnSpy", "dnSpy.xml"); - File.WriteAllText(configurationFile, template); - Log("Done!"); - - Log("Installing patched mono dll..."); - var executablePath = Assembly.GetEntryAssembly().Location; - var libPath = Path.Combine(executablePath, "../../../../../libraries/Debug/mono-2.0-bdwgc.dll"); - var destinationPath = Path.Combine(Settings.ValheimPlusDevInstallDir, "MonoBleedingEdge\\EmbedRuntime\\mono-2.0-bdwgc.dll"); - File.Copy(destinationPath, destinationPath + ".bak", true); - File.Copy(libPath, destinationPath, true); - Log("Done!"); - } + var filename = Path.GetFileName(source); - public async Task InstallBepInEx() - { - Log("Installing BepInEx..."); - var tempFolder = DirectoryHelper.CreateTempFolder(); - var bepInExZip = await Downloader.Download(Links.BepInEx, Path.Combine(tempFolder, "bepInExPack.zip")); - var bepInExFiles = Unzipper.Unzip(bepInExZip); - File.Delete(bepInExZip); - - var sourceFolder = bepInExFiles.Single(file => file.EndsWith("BepInExPack_Valheim/")); - FileCopier.CopyFiles(sourceFolder, Settings.ValheimPlusDevInstallDir); - - var unstripped_corlibFiles = bepInExFiles - .Where(path => path.Contains("unstripped_corlib")); - - var managedFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"valheim_Data\\Managed\\"); - Directory.CreateDirectory(managedFolder); - foreach (var source in unstripped_corlibFiles) - { - var file = Path.GetFileName(source); - if (string.IsNullOrEmpty(file)) - { - // ignore folders - continue; - } - - var destination = Path.Combine(managedFolder, file); - File.Copy(source, destination, true); - } - Log("Done!"); + var managedDestination = Path.Combine(managedFolder, filename); + File.Copy(source, managedDestination, true); } - public void PublicizeAssembliesDirectly() - { - Log("Publicizing assemblies..."); - var pubber = new AssemblyPublicizer(); - pubber.OnLogMessage += this.OnLogMessage; - pubber.ProcessAssemblies(Settings.ValheimPlusDevInstallDir); - Log("Done!"); - } + Logger.Log("Done!"); + } + + public static async Task InstallBepInEx542100() + { + Logger.Log("Installing BepInEx..."); + var tempFolder = DirectoryHelper.CreateTempFolder(); + var bepInExZip = await Downloader.Download(Links.BepInEx21, Path.Combine(tempFolder, "bepInExPack.zip")); + var bepInExFiles = Unzipper.Unzip(bepInExZip); + File.Delete(bepInExZip); + + var sourceFolder = Path.GetDirectoryName(bepInExFiles.First()); + FileCopier.CopyFiles(sourceFolder!, Settings.ValheimPlusDevInstallDir); + Logger.Log("Done!"); + } + + public static void PublicizeAssembliesDirectly() + { + Logger.Log("Publicizing assemblies..."); + var pubber = new AssemblyPublicizer(); + pubber.ProcessAssemblies(Settings.ValheimPlusDevInstallDir); + Logger.Log("Done!"); } } diff --git a/SetupDevEnvironment/Logger.cs b/SetupDevEnvironment/Logger.cs new file mode 100644 index 00000000..331707fc --- /dev/null +++ b/SetupDevEnvironment/Logger.cs @@ -0,0 +1,29 @@ +using System.ComponentModel; + +namespace SetupDevEnvironment +{ + internal class Logger + { + public event ProgressChangedEventHandler? OnLogMessage; + public static Logger Instance { get; private set; } + + public static void Log(string msg, int progressPct = 0) + { + if (Instance.OnLogMessage != null) + { + Instance.OnLogMessage(Instance, new ProgressChangedEventArgs(progressPct, msg)); + } + } + + private Logger() { } + + public static Logger Start() + { + if (Instance == null) + { + Instance = new Logger(); + } + return Instance; + } + } +} diff --git a/SetupDevEnvironment/Resources/valheim_plus.cfg b/SetupDevEnvironment/Resources/valheim_plus.cfg new file mode 100644 index 00000000..0d08acc3 --- /dev/null +++ b/SetupDevEnvironment/Resources/valheim_plus.cfg @@ -0,0 +1,1106 @@ +[ValheimPlus] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#ValheimPlus +enabled=true + +; Display the Valheim Plus logo in the main menu +mainMenuLogo=true + +; Display the advertisement of our server hosting partner on the server browser menu +serverBrowserAdvertisement=true + +[AdvancedBuildingMode] + +; https://docs.unity3d.com/ScriptReference/KeyCode.html <- a list of keycodes +; Change false to true to enable this section, if you set this to false the mode will not be accessible. https://valheim.plus/documentation/list#AdvancedBuildingMode +enabled=false + +; Enter the advanced building mode with this key when building +enterAdvancedBuildingMode=F1 + +; Exit the advanced building mode with this key when building +exitAdvancedBuildingMode=F3 + +; Copy the object rotation of the currently selected object in ABM +copyObjectRotation=Keypad7 + +; Apply the copied object rotation to the currently selected object in ABM +pasteObjectRotation=Keypad8 + +; Increases the amount an object rotates and moves. Holding Shift will increase in increments of 10 instead of 1. +increaseScrollSpeed=KeypadPlus + +; Decreases the amount an object rotates and moves. Holding Shift will decrease in increments of 10 instead of 1. +decreaseScrollSpeed=KeypadMinus + +[AdvancedEditingMode] + +; https://docs.unity3d.com/ScriptReference/KeyCode.html <- a list of keycodes +; Change false to true to enable this section, if you set this to false the mode will not be accessible. https://valheim.plus/documentation/list#AdvancedEditingMode +enabled=false + +; Enter the advanced editing mode with this key +enterAdvancedEditingMode=Keypad0 + +; Reset the object to its original position and rotation +resetAdvancedEditingMode=F7 + +; Exit the advanced editing mode with this key and reset the object +abortAndExitAdvancedEditingMode=F8 + +; Confirm the placement of the object and place it +confirmPlacementOfAdvancedEditingMode=KeypadEnter + +; Copy the object rotation of the currently selected object in AEM +copyObjectRotation=Keypad7 + +; Apply the copied object rotation to the currently selected object in AEM +pasteObjectRotation=Keypad8 + +; Increases the amount an object rotates and moves. Holding Shift will increase in increments of 10 instead of 1. +increaseScrollSpeed=KeypadPlus + +; Decreases the amount an object rotates and moves. Holding Shift will decrease in increments of 10 instead of 1. +decreaseScrollSpeed=KeypadMinus + +[Bed] + +; Change false to true to enable this section +enabled=false + +; Change false to true to enable sleeping without setting bed as spawn. +; When hovering over a bed you will be presented with a Hot-Key 'LShift+E'. This Hot-Key will allow for you to sleep on any bed without having to set a spawn-point. +sleepWithoutSpawn=false + +; Change false to true to enable sleeping on only unclaimed beds without setting bed as spawn. +; With this option enabled only beds that are not claimed by other players can be slept on without setting spawn-point using 'Shift+E' +unclaimedBedsOnly=false + +[Beehive] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Beehive +enabled=false + +; Configure the speed at which the bees produce honey in seconds, 1200 seconds are 24 ingame hours. +honeyProductionSpeed=1200 + +; Configure the maximum amount of honey in beehives. +maximumHoneyPerBeehive=4 + +; Instead of dropping the items, they will be placed inside the nearest nearby chests. +autoDeposit=false + +; The range of the chest detection for the auto deposit feature. +; Maximum is 50 +autoDepositRange=10 + +; Display the minutes and seconds until the beehive produces honey on crosshair hover. +showDuration=false + +[Building] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Building +enabled=false + +; Remove some of the Invalid placement messages, most notably provides the ability to place objects into other objects +noInvalidPlacementRestriction=false + +; Removes the "Mystical forces" building prevention and allows destruction of build objects in those areas with the hammer. +noMysticalForcesPreventPlacementRestriction=false + +; Removes the weather damage from rain and water erosion. +noWeatherDamage=false + +; The maximum range in meters that you can place build objects at inside the hammer build mode. +maximumPlacementDistance=8 + +; The radius, in meters, in which a piece must be to contribute to the comfort level. +pieceComfortRadius=10 + +; When destroying a building piece, setting this to true will ensure it always drops full resources. +; We recommend to enable this if you use this section. +alwaysDropResources=false + +; When destroying a building piece, setting this to true will ensure it always drops pieces that the devs have marked as "do not drop". +; We recommend to enable this if you use this section. +alwaysDropExcludedResources=false + +; Setting this to true will cause repairing with the hammer to repair in a radius instead of a single piece. +enableAreaRepair=false + +; Sets the area repair radius of enableAreaRepair. A value of 7.5 would mean your repair radius is 7.5 meters. +; Requires enableAreaRepair=true +areaRepairRadius=7.5 + +[Camera] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Camera +enabled=false + +; The maximum zoom distance to your character in-game. +; Default is 6 +cameraMaximumZoomDistance=6 + +; The maximum zoom distance to your character when in a boat. +; Default is 6 +cameraBoatMaximumZoomDistance=6 + +; The in-game camera FOV. +; Default is 65 +cameraFOV=65 + +[Experience] + +; Change false to true to enable this section. This section contains modifiers. https://valheim.plus/documentation/list#Experience +; Modifiers are increases and reduction in percent declared by 50, or -50. The value 50 will increase experience gained by 50%, -50 will reduce experience gained by 50%. +enabled=false + +; The modifier value for the experience gained of swords. +swords=0 + +; The modifier value for the experience gained of knives. +knives=0 + +; The modifier value for the experience gained of clubs. +clubs=0 + +; The modifier value for the experience gained of polearms. +polearms=0 + +; The modifier value for the experience gained of spears. +spears=0 + +; The modifier value for the experience gained of blocking. +blocking=0 + +; The modifier value for the experience gained of axes. +axes=0 + +; The modifier value for the experience gained of bows. +bows=0 + +; The modifier value for the experience gained of fire magic. +fireMagic=0 + +; The modifier value for the experience gained of frost magic. +frostMagic=0 + +; The modifier value for the experience gained of unarmed. +unarmed=0 + +; The modifier value for the experience gained of mining. +pickaxes=0 + +; The modifier value for the experience gained of wood cutting. +woodCutting=0 + +; The modifier value for the experience gained of jumping. +jump=0 + +; The modifier value for the experience gained of sneaking. +sneak=0 + +; The modifier value for the experience gained of running. +run=0 + +; The modifier value for the experience gained of swimming. +swim=0 + +; The modifier value for the experience gained of riding. +ride=0 + +[Fermenter] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Fermenter +enabled=false + +; Configure the time that the fermenter takes to produce its product, 2400 seconds are 48 ingame hours. +fermenterDuration=2400 + +; Configure the total amount of produced items from a fermenter. +fermenterItemsProduced=6 + +; Display the minutes and seconds until the fermenter is done on crosshair hover. +showDuration=false + +; Instead of dropping the items, they will be placed inside the nearest nearby chests. +autoDeposit=false + +; Automatically pull meads from nearby chests to be placed inside the Fermenter as soon as its empty. +autoFuel=false + +; This option prevents the fermenter to pull items from warded areas if it isn't placed inside of it. +; For convenience, we recommend this to be set to true. +ignorePrivateAreaCheck=true + +; The range of the chest detection for the auto deposit and auto fuel features +; Maximum is 50 +autoRange=10 + +[FireSource] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#FireSource +enabled=false + +; If set to true, torch-type fire sources will stay at max fuel level once filled. +; Applies to: wood torches, iron torches, green torches, sconces and brazier. +torches=false + +; If set to true, non torch-type fire sources will stay at max fuel level once filled. +fires=false + +; Automatically pull wood from nearby chests to be placed inside the Fire as soon as its empty. +autoFuel=false + +; This option prevents the Fire to pull items from warded areas if it isn't placed inside of it. +; For convenience, we recommend this to be set to true. +ignorePrivateAreaCheck=true + +; The range of the chest detection for the auto fuel features. +; Maximum is 50 +autoRange=10 + +[Food] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Food +enabled=false + +; Increase or reduce the time that food lasts by %. +; The value 50 would cause food to run out 50% slower, -50% would cause the food to run out 50% faster. +foodDurationMultiplier=0 + +; This option prevents food degrading over time - in other words, it retains its maximum benefit until it runs out instead of reducing its effect over time. +disableFoodDegradation=false + +[Smelter] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Smelter +enabled=false + +; Maximum amount of ore in a Smelter. +maximumOre=10 + +; Maximum amount of coal in a Smelter. +maximumCoal=20 + +; The total amount of coal used to produce a single smelted ingot. +coalUsedPerProduct=2 + +; The time it takes for the Smelter to produce a single ingot in seconds. +productionSpeed=30 + +; Instead of dropping the items, they will be placed inside the nearest nearby chests. +autoDeposit=false + +; The Smelter will pull coal and raw materials from nearby chests to be automatically added to it when its empty. +autoFuel=false + +; This option prevents the Smelter to pull items from warded areas if it isn't placed inside of it. +; For convenience, we recommend this to be set to true. +ignorePrivateAreaCheck=true + +; The range of the chest detection for the auto deposit and auto fuel features. +; Maximum is 50 +autoRange=10 + +[Furnace] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Furnace +enabled=false + +; Maximum amount of ore in a Furnace. +maximumOre=10 + +; Maximum amount of coal in a Furnace. +maximumCoal=20 + +; The total amount of coal used to produce a single smelted ingot. +coalUsedPerProduct=2 + +; The time it takes for the Furnace to produce a single ingot in seconds. +productionSpeed=30 + +; Instead of dropping the items, they will be placed inside the nearest nearby chests. +autoDeposit=false + +; The Furnace will pull coal and raw materials from nearby chests to be automatically added to it when its empty. +autoFuel=false + +; This option prevents the Furnace to pull items from warded areas if it isn't placed inside of it. +; For convenience, we recommend this to be set to true. +ignorePrivateAreaCheck=true + +; The range of the chest detection for the auto deposit and auto fuel features. +; Maximum is 50 +autoRange=10 + +; This option allows all ores inside the Furnace. +allowAllOres=false + +[Game] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Game +enabled=false + +; The games damage multiplier per person nearby in difficultyScaleRange(m) radius. +; Default is 4% monster damage increase per player in radius. +gameDifficultyDamageScale=4 + +; The games health multiplier per person nearby in difficultyScaleRange(m) radius. +; Default is 40% monster health increase per player in radius. +gameDifficultyHealthScale=40 + +; Adds additional players to the difficulty calculation in multiplayer unrelated to the actual amount. +; This option is disabled if its set to 0. +extraPlayerCountNearby=0 + +; Sets the nearby player count always to this value + extraPlayerCountNearby. +; This option is disabled if its set to 0. +setFixedPlayerCountTo=0 + +; The range in meters at which other players count towards nearby players for the difficulty scale. +difficultyScaleRange=200 + +; If you set this to true, all portals will be disabled. +disablePortals=false + +; If you set this to true the console will be force disabled in-game. +disableConsole=false + +;If you set this to true, portal names will be displayed in big text in center of screen. +bigPortalNames=false + +;Remove dense fog from the game. +disableFog=false + +[Hotkeys] + +; https://docs.unity3d.com/ScriptReference/KeyCode.html <- a list of keycodes +; Change false to true to enable this section. https://valheim.plus/documentation/list#Hotkeys +enabled=false + +; Roll forwards on hot key pressed. +rollForwards=F9 + +; Roll backwards on hot key pressed. +rollBackwards=F10 + +[Items] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Items +enabled=false + +; Enables you to teleport with ores and other usually teleport restricted objects. +noTeleportPrevention=false + +; Increase or reduce item weight by a modifier in percent. +; The value -50 will reduce item weight of every object by 50%, 50 will increase the weight of every item by 50%. +baseItemWeightReduction=0 + +; Increase or reduce the size of all maximum item stacks by a modifier in percent. +; The value 50 would set a usual item stack of 100 to be 150. +; The value -50 would set a usual item stack of 100 to be 50. +itemStackMultiplier=0 + +; Set duration that dropped items stay on the ground before they are despawning. Game default is 3600 seconds. +droppedItemOnGroundDurationInSeconds=3600 + +; Items dropped always float in water. +itemsFloatInWater=false + +[Hud] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#HUD +enabled=false + +; Shows the required amount of items AND the amount of items in your inventory in build mode and while crafting. +; This is enabled when the CraftFromChest section is enabled. +showRequiredItems=false + +; Shows small notifications about all skill experienced gained in the top left corner. +experienceGainedNotifications=false + +; Set to true to remove the red screen flash overlay when the player takes damage. +removeDamageFlash=false + +; If bow is in hotbar, display current ammo & total ammo under hotbar icon - never (0), when equipped (1), or always (2). +displayBowAmmoCounts=0 + +[Gathering] + +; Change false to true to enable this section. This section contains modifiers. Modifiers are increases and reduction in percent declared by 50, or -50. https://valheim.plus/documentation/list#Gathering +enabled=false + +; Modify the chance to drop resources from resource nodes affected by this category. This only works on resource nodes that do not have guaranteed drops. +; As example by default scrap piles in dungeons have a 20% chance to drop a item, if you set this option to 200, you will then have a 60% chance to drop iron. +dropChance=0 + +; Each of these values increase or reduce the dropped items from destroyed objects with tools (Stones, Trees, Resource nodes, etc.) by %. +; The value 50 will increase the dropped wood from trees from 10 to 15. The value -50 will reduce the amount of dropped wood from 10 to 5. +wood=0 +stone=0 +fineWood=0 +coreWood=0 +elderBark=0 +ironScrap=0 +tinOre=0 +copperOre=0 +silverOre=0 +chitin=0 + +[Pickable] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Pickable +; Each value below (in percent) will modify the yield when "picking" items (default key E) such as berries and flowers. +; A value of 100 will double drops, 200 will triple and so on. +enabled=false + +; All berries, all mushrooms, onions and carrots +edibles=0 + +; Barley, Flax, Dandelion, Thistle, Carrot Seeds, Turnip Seeds, Turnip, Onion Seeds +flowersAndIngredients=0 + +; Bone Fragments, Flint, Stone, Wood (branches on the ground) +materials=0 + +; Amber, Amber Pearl, Coins, Ruby +valuables=0 + +; Surtling Core only +surtlingCores=0 + +[Durability] + +; Change false to true to enable this section. This section contains modifiers. https://valheim.plus/documentation/list#Durability +; Modifiers are increases and reduction in percent declared by 50, or -50. +enabled=false + +; Each of these values increase or reduce the durability of the specific item type by %. +; The value 50 will increase the durability from 100 to 150. The value -50 will reduce the durability from 100 to 50. +axes=0 +pickaxes=0 +hammer=0 +cultivator=0 +hoe=0 +weapons=0 +armor=0 +bows=0 +shields=0 +torch=0 + +[Armor] + +; Change false to true to enable this section. This section contains modifiers. https://valheim.plus/documentation/list#Armor +; Modifiers are increases and reduction in percent declared by 50, or -50. +enabled=false + +; Each of these values increase or reduce the armor of the specific item type by %. +; The value 50 will increase the armor from 14 to 21. The value -50 will reduce the armor from 14 to 7. +helmets=0 +chests=0 +legs=0 +capes=0 + + +[Kiln] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Kiln +enabled=false + +; Maximum amount of wood in a Kiln. +maximumWood=25 + +; Change false to true to disable Fine Wood processing. +dontProcessFineWood=false + +; Change false to true to disabled Round Log processing. +dontProcessRoundLog=false + +; The time it takes for the Kiln to produce a single piece of coal in seconds. +productionSpeed=15 + +; Instead of dropping the items, they will be placed inside the nearest nearby chests. +autoDeposit=false + +; The Kiln will pull wood from nearby chests to be automatically added to it when its empty. +; This option respects the dontProcessFineWood and dontProcessRoundLog settings. +autoFuel=false + +; Stops autoFuel (looking for fuel) when there is at leasts this quantity of Coal in nearby chests +; (ignored if set to 0) +stopAutoFuelThreshold=0 + +; This option prevents the Kiln to pull items from warded areas if it isn't placed inside of it. +; For convenience, we recommend this to be set to true. +ignorePrivateAreaCheck=true + +; The range of the chest detection for the auto deposit and fuel features. +; Maximum is 50 +autoRange=10 + +[Map] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Map +enabled=false + +; With this enabled you will receive the same exploration progression as other players on the server. +; This will also enable the option for the server to sync everyones exploration progression on connecting to the server. +shareMapProgression=false + +; The radius of the map that you explore when moving. +exploreRadius=100 + +; Prevents you and other people on the server to turn off their map sharing option. +preventPlayerFromTurningOffPublicPosition=false + +; This option automatically shares created pins with everyone playing on the server. +shareAllPins=false + +; Display carts and boats on the map +displayCartsAndBoats=false + +[Player] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Player +enabled=false + +; The base amount of carry weight of your character. +baseMaximumWeight=300 + +; Increase the buff you receive to your carry weight from Megingjord's girdle. +baseMegingjordBuff=150 + +; Increase auto pickup range of all items. +baseAutoPickUpRange=2 + +; Disable all types of camera shake. +disableCameraShake=false + +; The base unarmed damage multiplied by your skill level. 120 will result in a maximum of up to 12 damage when you have a skill level of 10. +baseUnarmedDamage=70 + +; When changed to true, you will not be permitted to place a crop within the grow radius of another crop. +cropNotifier=false + +; How many seconds each comfort level contributes to the rested bonus. +restSecondsPerComfortLevel=60 + +; Change the death penalty in percentage, where higher will increase the death penalty and lower will reduce it. +; This is a modifier value. 50 will increase it by 50%, -50 will reduce it by 50%. +deathPenaltyMultiplier=0 + +; If set to true, this option will automatically repair your equipment when you interact with the appropriate workbench. +autoRepair=false + +; Boss buff duration (seconds) +guardianBuffDuration=300 + +; Boss buff cooldown (seconds) +guardianBuffCooldown=1200 + +; Disable the Guardian Buff animation +disableGuardianBuffAnimation=false + +; If set to true, when equipping a one-handed weapon, the best shield from your inventory is automatically equipped. +; (Best is determined by highest block power) +autoEquipShield=false + +; When unequipping a one-handed weapon also unequip shield from inventory. +autoUnequipShield=false + +; If set to true, weapon switches requested mid-attack will be carried out when the current attack is finished instead of being ignored. +queueWeaponChanges=false + +; If set to true, you will always skip the intro of the game. +skipIntro=false + +; If set to false, disables the "I have arrived!" message on player spawn. +iHaveArrivedOnSpawn=true + +; If set to true, you will not put away / unequip your items when swimming. +dontUnequipItemsWhenSwimming=false + +; If set to true, items will be re-equipped when you exit water after swimming (if they were hidden automatically) +reequipItemsAfterSwimming=false + +; This value represents how much the fall damage should be scaled in +/- %. This is a modifier value. +; The value 50 would result in 50% increased fall damage. The value -50 would result in 50% reduced fall damage. +fallDamageScalePercent=0 + +; Max fall damage. Game default is 100 (so with enough health, falls can't kill). +maxFallDamage=100 + +; If set to true, all tutorials will skip from now on. You can turn this config off and reset the tutorial (in the settings) at any time. +skipTutorials=false + +; Disable the encumbered state when you carry too many items (overweight) +disableEncumbered=false + +; Allow auto pickup of items when encumbered (overweight) +autoPickUpWhenEncumbered=false + +[Server] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Server +enabled=true + +; Modify the maximum amount of players on your Server. +maxPlayers=10 + +; Removes the requirement to have a server password. +disableServerPassword=false + +; This settings add a version control check to make sure that people that try to join your game or the server you try to join has V+ installed +; WE HEAVILY RECOMMEND TO NEVER DISABLE THIS! +enforceMod=true + +; Changes whether the server will force it's config on clients that connect. Only affects servers. +; WE HEAVILY RECOMMEND TO NEVER DISABLE THIS! +serverSyncsConfig=true + +; If false allows you to keep your own defined hotkeys instead of synchronising the ones declared for the server. +; Sections need to be enabled in your local configuration to load hotkeys. +; This is a client side setting and not affected by server settings. +serverSyncHotkeys=false + + +[Stamina] + +; Change false to true to enable this section. This section contains modifiers. https://valheim.plus/documentation/list#Stamina +; Modifiers are increases and reduction in percent declared by 50, or -50. +enabled=false + +; Changes the amount of stamina cost of using the dodge roll by % +dodgeStaminaUsage=0 + +; Changes the stamina drain of being overweight by % +encumberedStaminaDrain=0 + +; Changes the stamina cost of jumping by % +jumpStaminaDrain=0 + +; Changes the stamina cost of running by % +runStaminaDrain=0 + +; Changes the stamina drain by sneaking by % +sneakStaminaDrain=0 + +; Changes the total amount of stamina recovered per second by % +staminaRegen=0 + +; Changes the delay until stamina regeneration sets in by % +staminaRegenDelay=0 + +; Changes the stamina drain of swimming by % +swimStaminaDrain=0 + + +[StaminaUsage] + +; Change false to true to enable this section. This section contains modifiers. https://valheim.plus/documentation/list#StaminaUsage +; Modifiers are increases and reduction in percent declared by 50, or -50. +enabled=false + +; Each of these values change the respective tool in stamina usage by increases and reduction in percent declared by 50, or -50. +axes=0 +blocking=0 +bows=0 +clubs=0 +knives=0 +pickaxes=0 +polearms=0 +spears=0 +swords=0 +unarmed=0 +hammer=0 +hoe=0 +cultivator=0 +fishing=0 + +[StructuralIntegrity] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#StructuralIntegrity +enabled=false + +; Disables the entire structural integrity system and allows for placement in free air, does not prevent building damage. +disableStructuralIntegrity=false + +; Disables any damage from anything to all player built structures. Does not prevent damage from structural integrity. +disableDamageToPlayerStructures=false + +; Disables any damage from anything to all player built boats. +disableDamageToPlayerBoats=false + +; Disables water force damage to all player built boats. +disableWaterDamageToPlayerBoats=false + +; Each of these values reduce the loss of structural integrity by distance by % less. +; The value 100 would result in disabled structural integrity over distance, does not allow for placement in free air without disableStructuralIntegrity. +wood=0 +stone=0 +iron=0 +hardWood=0 + + +[Ward] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Ward +enabled=false + +; The range of wards by meters. +wardRange=20 + +; Set the enemy spawn radius around wards in meters +; This value equals wardRange if its set to 0. +wardEnemySpawnRange=0 + +[Workbench] +; Change false to true to enable this section. https://valheim.plus/documentation/list#Workbench +enabled=false + +; Set the workbench radius in meters. +workbenchRange=20 + +; Set the enemy spawn radius around workbenches in meters +; This value equals workbenchRange if its set to 0. +workbenchEnemySpawnRange=0 + +; Sets the workbench attachment (e.g. anvil) radius. +workbenchAttachmentRange=5 + +; Disables the roof and exposure requirement to use a workbench. +disableRoofCheck=false + +[Wagon] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Wagon +enabled=false + +; Change the base wagon physical mass of the wagon object. +; This is essentially the base weight of a cart. +wagonBaseMass=20 + +; This value changes the physical weight of wagons by +/- more/less from item weight inside. +; The value 50 would increase the weight by 50% more. The value -100 would remove the entire extra weight. +wagonExtraMassFromItems=0 + +[Inventory] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Inventory +enabled=false + +; Player inventory number of rows (inventory is resized up to 6 rows, higher values will add a scrollbar). default 4, min 4, max 20 +playerInventoryRows=4 + +; Wood chest number of columns +; (default 5, 3 min, 8 max) +woodChestColumns=5 + +; Wood chest number of rows (more than 4 rows will add a scrollbar). +; (default 2, min 2, 10 max) +woodChestRows=2 + +; Personal chest number of columns. +; (default 3, 3 min, 8 max) +personalChestColumns=3 + +; Personal chest number of rows +; (default 2, 2 min, 20 max) +personalChestRows=2 + +; Iron chest number of columns. +; (default 6, min 3, max 8) +ironChestColumns=6 + +; Iron chest number of rows (more than 4 rows will add a scrollbar) +; (default 4, min 3, max 20) +ironChestRows=4 + +; Blackmetal chests already have 8 columns by default but now you can lower it +; (default 8, min 3, max 8) +blackmetalChestColumns=8 + +; Blackmetal number of rows (more than 4 rows will add a scrollbar) +; (default 4, min 3, max 20) +blackmetalChestRows=4 + +; Cart (Wagon) inventory number of columns +; (default 8, min 6, max 8) +cartInventoryColumns=8 + +; Cart (Wagon) inventory number of rows (more than 4 rows will add a scrollbar) +; (default 3, min 3, max 30) +cartInventoryRows=3 + +; Karve (small boat) inventory number of columns +; (default 2, min 2, max 8) +karveInventoryColumns=2 + +; Karve (small boat) inventory number of rows (more than 4 rows will add a scrollbar) +; (default 2, min 2, max 30) +karveInventoryRows=2 + +; Longboat (large boat) inventory number of columns +; (default 8, min 6, max 8) +longboatInventoryColumns=8 + +; Longboat (large boat) inventory number of rows (more than 4 rows will add a scrollbar) +; (default 3, min 3, max 30) +longboatInventoryRows=3 + +; By default tools and weapons go into inventories top to bottom and other materials bottom to top. +; Set to true to make all items go into the inventory top to bottom. +inventoryFillTopToBottom=false + +; By default items go to their original position when picking up your tombstone. +; Set to true to make all stacks try to merge with an existing stack first. +mergeWithExistingStacks=false + +[FreePlacementRotation] + +; Change false to true to enable this section, if you set this to false the mode will not be accessible. https://valheim.plus/documentation/list#FreePlacementRotation +enabled=false + +; Rotates placement marker by 1 degree with keep ability to attach to nearly pieces. +rotateY=LeftAlt +rotateX=C +rotateZ=V + +; Copy rotation of placement marker from target piece in front of you. +copyRotationParallel=F + +; Set rotation to be perpendicular to piece in front of you. +copyRotationPerpendicular=G + +[Shields] + +; Change false to true to enable this section, if you set this to false the mode will not be accessible. https://valheim.plus/documentation/list#Shields +enabled=false + +; Increase or decrease the block value on all shields in %. -50 would be 50% less block rating, 50 would be 50% more block rating. +blockRating=0 + +[FirstPerson] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#FirstPerson +enabled=false + +; Hotkey to enable First Person. +hotkey=F10 + +; Default Field Of View to use. +defaultFOV=65.0 + +; Hotkey to raise Field Of View. +raiseFOVHotkey=PageUp + +; Hotkey to lower Field Of View. +lowerFOVHotkey=PageDown + +[GridAlignment] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#GridAlignment +; This offers a global fixed grid system to make precise placements. +enabled=false + +; Key to enable grid alignment. +align=LeftAlt + +; Key to toggle grid alignment. +alignToggle=F7 + +; Key to change the default alignment. +changeDefaultAlignment=F6 + +[CraftFromChest] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#CraftFromChest +; This feature allows you to craft from nearby chests when in range. +enabled=false + +; Change false to true to disable this feature when using a Cooking Station. +disableCookingStation=false + +; If in a workbench area, uses it as reference point when scanning for chests. +checkFromWorkbench=true + +; This option prevents crafting to pull items from warded areas if the player doesnt have access to it. +ignorePrivateAreaCheck=false + +; The range of the chest detection in meters. +range=20 + +; The interval in seconds that the feature scans your nearby chests. +; We recommend not going below 3 seconds. +lookupInterval=3 + +; Allows the system to use and see contents of carts for crafting. Might also allow use of other modded containers or vehicles not accessible otherwise. +allowCraftingFromCarts=false + +; Allows the system to use and see contents of ships for crafting. Might also allow use of other modded containers or vehicles not accessible otherwise. +allowCraftingFromShips=false + +[Windmill] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Windmill +enabled=false + +; Maximum amount of barley in a windmill. +maximumBarley=50 + +; The time it takes for the windmill to produce a single ingot in seconds. +productionSpeed=10 + +; Ignore wind intensity so it always takes the production speed value to process one barley. +ignoreWindIntensity=false + +; Instead of dropping the items, they will be placed inside the nearest nearby chests. +autoDeposit=false + +; The Windmill will pull barley from nearby chests to be automatically added to it when its empty. +autoFuel=false + +; This option prevents the Windmill to pull items from warded areas if it isn't placed inside of it. +; For convenience, we recommend this to be set to true. +ignorePrivateAreaCheck=true + +; The range of the chest detection for the auto deposit and auto fuel features. +; Maximum is 50 +autoRange=10 + +[SpinningWheel] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#SpinningWheel +enabled=false + +; Maximum amount of flax in a spinning wheel. +maximumFlax=50 + +; The time it takes for the spinning wheel to produce linen thread. +productionSpeed=30 + +; Instead of dropping the items, they will be placed inside the nearest nearby chests. +autoDeposit=false + +; The Spinning Wheel will pull flax from nearby chests to be automatically added to it when its empty. +autoFuel=false + +; This option prevents the Spinning Wheel to pull items from warded areas if it isn't placed inside of it. +; For convenience, we recommend this to be set to true. +ignorePrivateAreaCheck=true + +; The range of the chest detection for the auto deposit and auto fuel features +; Maximum is 50 +autoRange=10 + + +[PlayerProjectile] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#PlayerProjectile +enabled=false + +; Value of 50 would increase the minimum charge velocity from 2 to 3. +playerMinChargeVelocityMultiplier=0 + +; Value of 50 would increase the maximum charge velocity (of Finwood bow) from 50 to 75. +playerMaxChargeVelocityMultiplier=0 + +; Value of (+)50 increase in accuracy will change the variance of arrows 20 degree to 10 degree at the point of minimum charge release. +playerMinChargeAccuracyMultiplier=0 + +; Value of (+)50 increase in accuracy will change the variance of arrows 1 degree to 0.5 degree at the point of maximum charge release. +playerMaxChargeAccuracyMultiplier=0 + +; Enabling this option will linearly scale by skill level from the base values of the weapon to the modified values (according to multipliers above). +enableScaleWithSkillLevel=false + + +[MonsterProjectile] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#MonsterProjectile +enabled=false + +; Value of 10 would increase the projectile velocity from 50 to 55. +monsterMaxChargeVelocityMultiplier=0 + +; Value of (+)10 increase in accuracy will change the variance of projectile 1 degree to 0.9 degree at the point of projectile release. +monsterMaxChargeAccuracyMultiplier=0 + + +[Tameable] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Tameable +enabled=false + +; Modify what happens when a tamed creature is attacked. +; 0 = normal, 1 = essential(deadly attacks stun instead of kill, tamed creatures can still die rarely), 2 = immortal. +mortality=0 + +; This will circumvent the mortality setting, so even if tamed creatures are immortal, players can still kill them with a butcher knife. +; For this option to work you need to have mortality to set to either essential or immortal. +ownerDamageOverride=true + +; How long it takes for a tamed creature to recover if mortality is set to 1(essential) and they are stunned. +stunRecoveryTime=10 + +; If the tamed creature is recovering from a stun, then add Stunned to the hover text on mouse over. +stunInformation=false + +[GameClock] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#GameClock +enabled=false + +; Change time formatting from 24hr to AM-PM. +useAMPM=false + +; Change font size of time text. +textFontSize=34 + +; Change how red the time text is (51/255). +textRedChannel=248 + +; Change how green the time text is (51/255). +textGreenChannel=105 + +; Change how blue the time text is (51/255). +textBlueChannel=0 + +; Change how transparent the time text is (255 is solid with no transparency). +textTransparencyChannel=255 + + +[Brightness] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Brightness +enabled=false + +; Changes how bright it looks at night. A value between 5 and 10 will result in nearly double in brightness at night. +nightBrightnessMultiplier=0 + +[Chat] + +; Change false to true to enable this section. https://valheim.plus/documentation/list#Chat +enabled = false + +; If the player is outside of this range in meters in comparison to the creator of the shout you will not see the message on the map or in the chat. If this is set to 0, its disabled. +shoutDistance = 0 + +; With this option enabled you will see the shout message in your chat window even if you are outside of shoutDistance. +outOfRangeShoutsDisplayInChatWindow = true + +; If the player is outside of this range in meters in comparison to the creator of the ping on the map you will not see the ping on the map. If this is set to 0, its disabled. +pingDistance = 0 + +; Disable the forced upper and lower case conversions for in-game text messages of all types. +forcedCase = true + +; This value determines the range in meters that you can see whisper text messages by default. +defaultWhisperDistance = 4 + +; This value determines the range in meters that you can see normal text messages by default. +defaultNormalDistance = 15 + +; This value determines the range in meters that you can see shout text messages by default. +defaultShoutDistance = 70 diff --git a/SetupDevEnvironment/Settings.cs b/SetupDevEnvironment/Settings.cs index 2b878ea3..ae2fafc8 100644 --- a/SetupDevEnvironment/Settings.cs +++ b/SetupDevEnvironment/Settings.cs @@ -24,7 +24,7 @@ public static string ValheimPlusDevInstallDir { return string.IsNullOrEmpty(Properties.Settings.Default.ValheimPlusDevInstallDir) - ? Links.DefaultValheimInstallFolder + ? Links.DefaultValheimPlusDevInstallFolder : Properties.Settings.Default.ValheimPlusDevInstallDir; } set diff --git a/SetupDevEnvironment/SetupDevEnvironment.csproj b/SetupDevEnvironment/SetupDevEnvironment.csproj index 9a5b3ce4..e9811ba8 100644 --- a/SetupDevEnvironment/SetupDevEnvironment.csproj +++ b/SetupDevEnvironment/SetupDevEnvironment.csproj @@ -11,15 +11,17 @@ + - + + diff --git a/SetupDevEnvironment/SetupForm.Designer.cs b/SetupDevEnvironment/SetupForm.Designer.cs index 29fb558a..607269f7 100644 --- a/SetupDevEnvironment/SetupForm.Designer.cs +++ b/SetupDevEnvironment/SetupForm.Designer.cs @@ -122,6 +122,7 @@ private void InitializeComponent() this.tbLog.Location = new System.Drawing.Point(12, 113); this.tbLog.Multiline = true; this.tbLog.Name = "tbLog"; + this.tbLog.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.tbLog.Size = new System.Drawing.Size(739, 341); this.tbLog.TabIndex = 7; this.tbLog.Visible = false; diff --git a/SetupDevEnvironment/SetupForm.cs b/SetupDevEnvironment/SetupForm.cs index 6b34f161..a7bc6619 100644 --- a/SetupDevEnvironment/SetupForm.cs +++ b/SetupDevEnvironment/SetupForm.cs @@ -6,12 +6,12 @@ namespace SetupDevEnvironment { public partial class SetupForm : Form { - private string ValheimInstallPath + private static string ValheimInstallPath { get => Settings.ValheimInstallDir; set { Settings.ValheimInstallDir = value; } } - private string ValheimPlusInstallPath + private static string ValheimPlusInstallPath { get => Settings.ValheimPlusDevInstallDir; set { Settings.ValheimPlusDevInstallDir = value; } @@ -20,6 +20,11 @@ private string ValheimPlusInstallPath public SetupForm() { InitializeComponent(); + Logger.Start().OnLogMessage += this.OnLogMessage; + + tbValheimInstallDir.Text = Settings.ValheimInstallDir; + tbValheimPlusInstallDir.Text = Settings.ValheimPlusDevInstallDir; + EnableStartButton(); } @@ -47,13 +52,10 @@ private void btBrowseValheimInstallDir_Click(object sender, EventArgs e) tbValheimInstallDir.Text = ValheimInstallPath; tbValheimInstallDir.Invalidate(); - if (ValheimPlusInstallPath == Links.DefaultValheimPlusDevInstallFolder) - { - var steamRoot = Directory.GetParent(path); - ValheimPlusInstallPath = Path.Combine(steamRoot.FullName, "Valheim Plus Development"); - tbValheimPlusInstallDir.Text = ValheimPlusInstallPath; - tbValheimPlusInstallDir.Invalidate(); - } + var steamRoot = Directory.GetParent(path); + ValheimPlusInstallPath = Path.Combine(steamRoot.FullName, "Valheim Plus Development"); + tbValheimPlusInstallDir.Text = ValheimPlusInstallPath; + tbValheimPlusInstallDir.Invalidate(); EnableStartButton(); } @@ -84,7 +86,6 @@ private async void btStartInstallation_Click(object sender, EventArgs e) tbLog.Visible = true; var script = new InstallScript(); - script.OnLogMessage += OnLogMessage; await script.Install(); btEditConfig.Enabled = true; @@ -115,7 +116,7 @@ private static string GetFolder(string initialPath) /// /// /// - private void OnLogMessage(object? sender, ProgressChangedEventArgs e) + private void OnLogMessage(object sender, ProgressChangedEventArgs e) { if (InvokeRequired) { @@ -132,7 +133,7 @@ private void UpdateLog(string text) private void btEditConfig_Click(object sender, EventArgs e) { - ProcessRunner.Run(Path.Combine(ValheimPlusInstallPath, "BepInEx\\config\\BepInEx.cfg")); + ProcessRunner.Run(Path.Combine(ValheimPlusInstallPath, "BepInEx\\config\\ValheimPlus.cfg")); } private void btStartDnSpy_Click(object sender, EventArgs e) From e9296eae4a51f2abee87c3fe2051c3f36f52b4e1 Mon Sep 17 00:00:00 2001 From: Joost Boomkamp Date: Sun, 4 Dec 2022 12:56:22 +0100 Subject: [PATCH 6/9] reference single set of unstripped_corlibs in \valheim_data\managed --- SetupDevEnvironment/IO/AssemblyPublicizer.cs | 19 +- SetupDevEnvironment/IO/ResourceHelper.cs | 5 +- SetupDevEnvironment/InstallScript.cs | 2 + SetupDevEnvironment/Logger.cs | 25 +- .../Resources/DnSpyConfiguration.xml | 220 +++++++++--------- SetupDevEnvironment/SetupForm.cs | 46 +++- ValheimPlus/ValheimPlus.csproj | 122 +++++----- 7 files changed, 243 insertions(+), 196 deletions(-) diff --git a/SetupDevEnvironment/IO/AssemblyPublicizer.cs b/SetupDevEnvironment/IO/AssemblyPublicizer.cs index fd9d1943..c7613eed 100644 --- a/SetupDevEnvironment/IO/AssemblyPublicizer.cs +++ b/SetupDevEnvironment/IO/AssemblyPublicizer.cs @@ -67,19 +67,21 @@ static string ComputeHash(Assembly assembly) static ModuleDef RewriteAssembly(string assemblyPath) { var assembly = ModuleDefMD.Load(assemblyPath); + var types = assembly.GetTypes(); Logger.Log($"{assembly.Name}: {types.Count()} types"); + foreach (var type in types) { - MakeTypePublic(assembly, type); - MakeMethodsPublic(assembly, type); - MakeFieldsPublic(assembly, type); + MakeTypePublic(type); + MakeMethodsPublic(type); + MakeFieldsPublic(type); } return assembly; } - private static void MakeFieldsPublic(ModuleDef assembly, TypeDef type) + private static void MakeFieldsPublic(TypeDef type) { var eventNames = type.Events .Select(ev => ev.Name.ToString()).ToList(); @@ -87,8 +89,6 @@ private static void MakeFieldsPublic(ModuleDef assembly, TypeDef type) var fields = type.Fields .Where(x => !eventNames.Contains(x.Name)).ToArray(); - Logger.Log($"{assembly.Name}\\{type.Name}: {fields.Length} fields"); - foreach (FieldDef field in fields) { field.Attributes &= ~FieldAttributes.FieldAccessMask; @@ -96,10 +96,8 @@ private static void MakeFieldsPublic(ModuleDef assembly, TypeDef type) } } - private static void MakeTypePublic(ModuleDef assembly, TypeDef type) + private static void MakeTypePublic(TypeDef type) { - Logger.Log($"{assembly.Name}\\{type.Name}"); - type.Attributes &= ~TypeAttributes.VisibilityMask; if (type.IsNested) type.Attributes |= TypeAttributes.NestedPublic; @@ -107,9 +105,8 @@ private static void MakeTypePublic(ModuleDef assembly, TypeDef type) type.Attributes |= TypeAttributes.Public; } - private static void MakeMethodsPublic(ModuleDef assembly, TypeDef type) + private static void MakeMethodsPublic(TypeDef type) { - Logger.Log($"{assembly.Name}\\{type.Name}: {type.Methods.Count} Methods"); foreach (MethodDef method in type.Methods) { method.Attributes &= ~MethodAttributes.MemberAccessMask; diff --git a/SetupDevEnvironment/IO/ResourceHelper.cs b/SetupDevEnvironment/IO/ResourceHelper.cs index d1c69510..786e4a84 100644 --- a/SetupDevEnvironment/IO/ResourceHelper.cs +++ b/SetupDevEnvironment/IO/ResourceHelper.cs @@ -1,5 +1,6 @@ namespace SetupDevEnvironment.IO { + #nullable disable internal class ResourceHelper { public static string GetResource(string name) @@ -7,8 +8,8 @@ public static string GetResource(string name) var assembly = typeof(ResourceHelper).Assembly; var resourceName = assembly.GetManifestResourceNames().Single(x => x.Contains(name)); - using (Stream stream = assembly.GetManifestResourceStream(resourceName)) - using (StreamReader reader = new StreamReader(stream)) + using (var stream = assembly.GetManifestResourceStream(resourceName)) + using (var reader = new StreamReader(stream)) { return reader.ReadToEnd(); } diff --git a/SetupDevEnvironment/InstallScript.cs b/SetupDevEnvironment/InstallScript.cs index d9cb318f..7c3d556a 100644 --- a/SetupDevEnvironment/InstallScript.cs +++ b/SetupDevEnvironment/InstallScript.cs @@ -25,6 +25,7 @@ public async Task Install() await SetupDnSpy(); ConfigureEnvironment(); Logger.Log("All Done, have a nice dev."); + Logger.Stop(); } private static void CopyValheimFiles() @@ -98,6 +99,7 @@ public static async Task InstallBepInEx541900() public static async Task InstallUnstrippedFiles() { + Logger.Log("Installing Unstripped Unity Dlls..."); var tempFolder = DirectoryHelper.CreateTempFolder(); var unstrippedZip = await Downloader.Download(Links.Unstripped_Corlib, Path.Combine(tempFolder, "unstripped.zip")); var unstripped_corlibFiles = Unzipper.Unzip(unstrippedZip); diff --git a/SetupDevEnvironment/Logger.cs b/SetupDevEnvironment/Logger.cs index 331707fc..2c61be69 100644 --- a/SetupDevEnvironment/Logger.cs +++ b/SetupDevEnvironment/Logger.cs @@ -5,14 +5,19 @@ namespace SetupDevEnvironment internal class Logger { public event ProgressChangedEventHandler? OnLogMessage; - public static Logger Instance { get; private set; } + public static Logger? Instance { get; private set; } + private static StreamWriter? _logFile = null; public static void Log(string msg, int progressPct = 0) { - if (Instance.OnLogMessage != null) + if (Instance?.OnLogMessage != null) { Instance.OnLogMessage(Instance, new ProgressChangedEventArgs(progressPct, msg)); } + if (_logFile != null) + { + _logFile.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + " " + msg); + } } private Logger() { } @@ -25,5 +30,21 @@ public static Logger Start() } return Instance; } + + public static void ToDisk(string path) + { + Start(); + _logFile = new StreamWriter(File.Create(path)); + _logFile.AutoFlush = true; + } + + internal static void Stop() + { + if (_logFile is null) return; + + _logFile.Flush(); + _logFile.Close(); + _logFile.Dispose(); + } } } diff --git a/SetupDevEnvironment/Resources/DnSpyConfiguration.xml b/SetupDevEnvironment/Resources/DnSpyConfiguration.xml index 181ae1ed..13af61be 100644 --- a/SetupDevEnvironment/Resources/DnSpyConfiguration.xml +++ b/SetupDevEnvironment/Resources/DnSpyConfiguration.xml @@ -65,87 +65,87 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -155,35 +155,35 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/SetupDevEnvironment/SetupForm.cs b/SetupDevEnvironment/SetupForm.cs index a7bc6619..16f3ca26 100644 --- a/SetupDevEnvironment/SetupForm.cs +++ b/SetupDevEnvironment/SetupForm.cs @@ -6,15 +6,25 @@ namespace SetupDevEnvironment { public partial class SetupForm : Form { - private static string ValheimInstallPath + private string ValheimInstallPath { get => Settings.ValheimInstallDir; - set { Settings.ValheimInstallDir = value; } + set + { + Settings.ValheimInstallDir = value; + EnableStartButton(); + } } - private static string ValheimPlusInstallPath + + private string ValheimPlusInstallPath { get => Settings.ValheimPlusDevInstallDir; - set { Settings.ValheimPlusDevInstallDir = value; } + set + { + Settings.ValheimPlusDevInstallDir = value; + EnableDevButtons(); + EnableStartButton(); + } } public SetupForm() @@ -26,6 +36,7 @@ public SetupForm() tbValheimPlusInstallDir.Text = Settings.ValheimPlusDevInstallDir; EnableStartButton(); + EnableDevButtons(); } private void EnableStartButton() @@ -42,6 +53,15 @@ private void EnableStartButton() } } + private void EnableDevButtons() + { + if (File.Exists(Path.Combine(Settings.ValheimPlusDevInstallDir, "devsetup.log"))) + { + btEditConfig.Enabled = true; + btStartDnSpy.Enabled = true; + } + } + private void btBrowseValheimInstallDir_Click(object sender, EventArgs e) { var path = GetFolder(Links.DefaultValheimInstallFolder); @@ -82,18 +102,24 @@ private void btBrowseVPlusInstallDir_Click(object sender, EventArgs e) private async void btStartInstallation_Click(object sender, EventArgs e) { btStartInstallation.Enabled = false; - tbLog.Enabled = false; - tbLog.Visible = true; + + SetupLogging(); var script = new InstallScript(); await script.Install(); - btEditConfig.Enabled = true; - btStartDnSpy.Enabled = true; - + EnableDevButtons(); EnableStartButton(); } + private void SetupLogging() + { + Logger.ToDisk(Path.Combine(Settings.ValheimPlusDevInstallDir, "devsetup.log")); + + tbLog.Enabled = false; + tbLog.Visible = true; + } + private static string GetFolder(string initialPath) { var odd = new FolderBrowserDialog @@ -133,7 +159,7 @@ private void UpdateLog(string text) private void btEditConfig_Click(object sender, EventArgs e) { - ProcessRunner.Run(Path.Combine(ValheimPlusInstallPath, "BepInEx\\config\\ValheimPlus.cfg")); + ProcessRunner.Run(Path.Combine(ValheimPlusInstallPath, "BepInEx\\config\\valheim_plus.cfg")); } private void btStartDnSpy_Click(object sender, EventArgs e) diff --git a/ValheimPlus/ValheimPlus.csproj b/ValheimPlus/ValheimPlus.csproj index deb23f64..978e3ac5 100644 --- a/ValheimPlus/ValheimPlus.csproj +++ b/ValheimPlus/ValheimPlus.csproj @@ -120,218 +120,218 @@ False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AccessibilityModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AccessibilityModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AIModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AIModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AndroidJNIModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AndroidJNIModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AnimationModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AnimationModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ARModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ARModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AssetBundleModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AssetBundleModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AudioModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AudioModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ClothModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ClothModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ClusterInputModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ClusterInputModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ClusterRendererModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ClusterRendererModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.CoreModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.CoreModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.CrashReportingModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.CrashReportingModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.DirectorModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.DirectorModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.DSPGraphModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.DSPGraphModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.GameCenterModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.GameCenterModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.GridModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.GridModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.HotReloadModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.HotReloadModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ImageConversionModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ImageConversionModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.IMGUIModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.IMGUIModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.InputLegacyModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.InputLegacyModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.InputModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.InputModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.JSONSerializeModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.JSONSerializeModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.LocalizationModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.LocalizationModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ParticleSystemModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ParticleSystemModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.PerformanceReportingModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.PerformanceReportingModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.Physics2DModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.Physics2DModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.PhysicsModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.PhysicsModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ProfilerModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ProfilerModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ScreenCaptureModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ScreenCaptureModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.SharedInternalsModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.SharedInternalsModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.SpriteMaskModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.SpriteMaskModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.SpriteShapeModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.SpriteShapeModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.StreamingModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.StreamingModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.SubstanceModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.SubstanceModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.SubsystemsModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.SubsystemsModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TerrainModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TerrainModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TerrainPhysicsModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TextCoreModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TextCoreModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TextRenderingModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TextRenderingModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TilemapModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TilemapModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TLSModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TLSModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UI.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UI.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UIElementsModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UIElementsModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UIModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UIModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UmbraModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UmbraModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UNETModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UNETModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityAnalyticsModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityConnectModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityConnectModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityTestProtocolModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityWebRequestAssetBundleModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityWebRequestAudioModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityWebRequestModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityWebRequestModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityWebRequestTextureModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityWebRequestWWWModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.VehiclesModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.VehiclesModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.VFXModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.VFXModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.VideoModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.VideoModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.VRModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.VRModule.dll - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.WindModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.WindModule.dll False - $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.XRModule.dll + $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.XRModule.dll ..\packages\YamlDotNet.11.2.1\lib\net45\YamlDotNet.dll From e7a14c2a8d5997ba6bcd17fbb51122a5421798ff Mon Sep 17 00:00:00 2001 From: Joost Boomkamp Date: Mon, 5 Dec 2022 16:59:37 +0100 Subject: [PATCH 7/9] fix unstripped files version --- SetupDevEnvironment/IO/AssemblyPublicizer.cs | 12 +++---- SetupDevEnvironment/IO/FileMover.cs | 18 +++++++--- SetupDevEnvironment/IO/Links.cs | 3 ++ SetupDevEnvironment/InstallScript.cs | 38 ++++++++++++-------- 4 files changed, 45 insertions(+), 26 deletions(-) diff --git a/SetupDevEnvironment/IO/AssemblyPublicizer.cs b/SetupDevEnvironment/IO/AssemblyPublicizer.cs index c7613eed..c70bbfc9 100644 --- a/SetupDevEnvironment/IO/AssemblyPublicizer.cs +++ b/SetupDevEnvironment/IO/AssemblyPublicizer.cs @@ -15,12 +15,8 @@ public AssemblyPublicizer() Logger.Start(); } - public void ProcessAssemblies(string valheimPlusInstallDir) + public static void ProcessAssemblies(string[] files) { - var managedFolder = Path.Combine(valheimPlusInstallDir, "valheim_Data\\Managed\\"); - var files = Directory.GetFiles( - managedFolder, "assembly*.dll", SearchOption.TopDirectoryOnly); - foreach (var file in files) { try @@ -34,7 +30,7 @@ public void ProcessAssemblies(string valheimPlusInstallDir) } } - static void ProcessAssembly(Assembly assembly) + private static void ProcessAssembly(Assembly assembly) { string assemblyPath = assembly.Location; string filename = assembly.GetName().Name!; @@ -59,12 +55,12 @@ static void ProcessAssembly(Assembly assembly) File.WriteAllText(hashPath, curHash); } - static string ComputeHash(Assembly assembly) + private static string ComputeHash(Assembly assembly) { return assembly.ManifestModule.ModuleVersionId.ToString(); } - static ModuleDef RewriteAssembly(string assemblyPath) + private static ModuleDef RewriteAssembly(string assemblyPath) { var assembly = ModuleDefMD.Load(assemblyPath); diff --git a/SetupDevEnvironment/IO/FileMover.cs b/SetupDevEnvironment/IO/FileMover.cs index 551e4147..2447cb60 100644 --- a/SetupDevEnvironment/IO/FileMover.cs +++ b/SetupDevEnvironment/IO/FileMover.cs @@ -1,13 +1,18 @@ -namespace SetupDevEnvironment.IO +using dnlib.DotNet; + +namespace SetupDevEnvironment.IO { internal class FileCopier { - public static void CopyFiles(string sourceFolder, string destinationFolder) + public static void CopyFiles(string sourceFolder, string destinationFolder) { - Directory.CreateDirectory(destinationFolder); - var sourceFiles = Directory.GetFiles(sourceFolder, "*.*", SearchOption.AllDirectories); + CopyFiles(sourceFolder, sourceFiles, destinationFolder); + } + public static void CopyFiles(string sourceFolder, string[] sourceFiles, string destinationFolder) + { + Directory.CreateDirectory(destinationFolder); foreach (string file in sourceFiles) { var relativeFile = Path.GetRelativePath(sourceFolder, file); @@ -17,6 +22,11 @@ public static void CopyFiles(string sourceFolder, string destinationFolder) var folder = Path.GetDirectoryName(destFile); Directory.CreateDirectory(folder!); + if (File.GetAttributes(file).HasFlag(System.IO.FileAttributes.Directory)) + { + continue; + } + File.Copy(file, destFile, true); } } diff --git a/SetupDevEnvironment/IO/Links.cs b/SetupDevEnvironment/IO/Links.cs index 87c2c056..215bfd5e 100644 --- a/SetupDevEnvironment/IO/Links.cs +++ b/SetupDevEnvironment/IO/Links.cs @@ -14,8 +14,11 @@ internal static class Links internal static readonly string BepInEx21 = @"https://github.com/BepInEx/BepInEx/releases/download/v5.4.21/BepInEx_x64_5.4.21.0.zip"; + [Obsolete("This should be the correct source, but you can't run valheim with it", true)] internal static readonly string Unstripped_Corlib = @"https://cdn.discordapp.com/attachments/624272422295568435/841990037935882250/unstripped_corlib.7z"; + internal static readonly string Unstripped_Corlib_ValheimPlusSource = + @"https://github.com/valheimPlus/ValheimPlus/releases/download/0.9.9.9/WindowsClient.zip"; internal static readonly string DnSpy64 = @"https://github.com/dnSpy/dnSpy/releases/download/v6.1.8/dnSpy-net-win64.zip"; diff --git a/SetupDevEnvironment/InstallScript.cs b/SetupDevEnvironment/InstallScript.cs index 7c3d556a..c3e0097a 100644 --- a/SetupDevEnvironment/InstallScript.cs +++ b/SetupDevEnvironment/InstallScript.cs @@ -19,7 +19,7 @@ public async Task Install() //1.Define Environment Variable `VALHEIM_INSTALL` with path to Valheim Install Directory CopyValheimFiles(); - await InstallBepInEx542100(); + await InstallBepInEx541900(); await InstallUnstrippedFiles(); PublicizeAssembliesDirectly(); await SetupDnSpy(); @@ -48,6 +48,9 @@ private static void ConfigureEnvironment() var defaultConfig = ResourceHelper.GetResource("valheim_plus.cfg"); File.WriteAllText(configFile, defaultConfig); } + + Directory.CreateDirectory(Path.Combine(Settings.ValheimPlusDevInstallDir, "BepInEx\\plugins\\")); + Logger.Log("Done!"); } @@ -101,21 +104,27 @@ public static async Task InstallUnstrippedFiles() { Logger.Log("Installing Unstripped Unity Dlls..."); var tempFolder = DirectoryHelper.CreateTempFolder(); - var unstrippedZip = await Downloader.Download(Links.Unstripped_Corlib, Path.Combine(tempFolder, "unstripped.zip")); - var unstripped_corlibFiles = Unzipper.Unzip(unstrippedZip); + var unstrippedZip = await Downloader.Download(Links.Unstripped_Corlib_ValheimPlusSource, Path.Combine(tempFolder, "unstripped.zip")); + var unstripped_corlibFiles = Unzipper.Unzip(unstrippedZip) + .Where(x => x.Contains("unstripped", StringComparison.CurrentCultureIgnoreCase)) + .ToArray(); var managedFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"valheim_Data\\Managed\\"); - //var coreLibFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"valheim_Data\\unstripped_corlib\\"); - Directory.CreateDirectory(managedFolder); - foreach (var source in unstripped_corlibFiles) - { - if (File.GetAttributes(source).HasFlag(FileAttributes.Directory)) { continue; } + var coreLibFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"valheim_Data\\unstripped_corlib\\"); + + FileCopier.CopyFiles(tempFolder, unstripped_corlibFiles, managedFolder); + FileCopier.CopyFiles(tempFolder, unstripped_corlibFiles, coreLibFolder); + + //Directory.CreateDirectory(managedFolder); + //foreach (var source in unstripped_corlibFiles) + //{ + // if (File.GetAttributes(source).HasFlag(FileAttributes.Directory)) { continue; } - var filename = Path.GetFileName(source); + // var filename = Path.GetFileName(source); - var managedDestination = Path.Combine(managedFolder, filename); - File.Copy(source, managedDestination, true); - } + // var managedDestination = Path.Combine(managedFolder, filename); + // File.Copy(source, managedDestination, true); + //} Logger.Log("Done!"); } @@ -136,8 +145,9 @@ public static async Task InstallBepInEx542100() public static void PublicizeAssembliesDirectly() { Logger.Log("Publicizing assemblies..."); - var pubber = new AssemblyPublicizer(); - pubber.ProcessAssemblies(Settings.ValheimPlusDevInstallDir); + var managedFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, "valheim_Data\\Managed\\"); + var files = Directory.GetFiles(managedFolder, "assembly*.dll", SearchOption.TopDirectoryOnly); + AssemblyPublicizer.ProcessAssemblies(files); Logger.Log("Done!"); } } From d006648cf9ca3dac2b65c05b31db778deaa720f7 Mon Sep 17 00:00:00 2001 From: Joost Boomkamp Date: Mon, 5 Dec 2022 17:02:34 +0100 Subject: [PATCH 8/9] ValheimPlus to 4.5.2. --- ValheimPlus/ValheimPlus.csproj | 966 +++++++++++++++++---------------- ValheimPlus/app.config | 2 +- ValheimPlus/packages.config | 2 +- 3 files changed, 486 insertions(+), 484 deletions(-) diff --git a/ValheimPlus/ValheimPlus.csproj b/ValheimPlus/ValheimPlus.csproj index 978e3ac5..bdba7f78 100644 --- a/ValheimPlus/ValheimPlus.csproj +++ b/ValheimPlus/ValheimPlus.csproj @@ -1,488 +1,490 @@  - - - - Debug - AnyCPU - {2A837100-A030-4D0C-BFFB-B38356118D9A} - Library - Properties - ValheimPlus - ValheimPlus - v4.5 - 512 - true - - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true - false - - - - - ..\packages\HarmonyX.2.10.0\lib\net45\0Harmony.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_googleanalytics_publicized.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_guiutils_publicized.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_lux_publicized.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_postprocessing_publicized.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_simplemeshcombine_publicized.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_steamworks_publicized.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_sunshafts_publicized.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_utils_publicized.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_valheim_publicized.dll - - - False - $(VALHEIM_INSTALL)\BepInEx\core\BepInEx.dll - - - False - $(VALHEIM_INSTALL)\BepInEx\core\BepInEx.Harmony.dll - - - False - $(VALHEIM_INSTALL)\BepInEx\core\BepInEx.Preloader.dll - - - ..\packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll - - - False - $(VALHEIM_INSTALL)\BepInEx\core\HarmonyXInterop.dll - - - ..\packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll - - - ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.dll - - - ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Mdb.dll - - - ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Pdb.dll - - - ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Rocks.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\Mono.Security.dll - + + + + Debug + AnyCPU + {2A837100-A030-4D0C-BFFB-B38356118D9A} + Library + Properties + ValheimPlus + ValheimPlus + v4.5.2 + 512 + true + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + true + false + + - ..\packages\MonoMod.RuntimeDetour.22.5.1.1\lib\net35\MonoMod.RuntimeDetour.dll + ..\packages\MonoMod.RuntimeDetour.22.5.1.1\lib\net452\MonoMod.RuntimeDetour.dll - ..\packages\MonoMod.Utils.22.5.1.1\lib\net35\MonoMod.Utils.dll - - - - - ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AccessibilityModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AIModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AndroidJNIModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AnimationModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ARModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AssetBundleModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.AudioModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ClothModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ClusterInputModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ClusterRendererModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.CoreModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.CrashReportingModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.DirectorModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.DSPGraphModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.GameCenterModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.GridModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.HotReloadModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ImageConversionModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.IMGUIModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.InputLegacyModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.InputModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.JSONSerializeModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.LocalizationModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ParticleSystemModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.PerformanceReportingModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.Physics2DModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.PhysicsModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ProfilerModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.ScreenCaptureModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.SharedInternalsModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.SpriteMaskModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.SpriteShapeModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.StreamingModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.SubstanceModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.SubsystemsModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TerrainModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TerrainPhysicsModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TextCoreModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TextRenderingModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TilemapModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.TLSModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UI.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UIElementsModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UIModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UmbraModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UNETModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityAnalyticsModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityConnectModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityTestProtocolModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityWebRequestAssetBundleModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityWebRequestAudioModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityWebRequestModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityWebRequestTextureModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.UnityWebRequestWWWModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.VehiclesModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.VFXModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.VideoModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.VRModule.dll - - - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.WindModule.dll - - - False - $(VALHEIM_INSTALL)\valheim_Data\Managed\UnityEngine.XRModule.dll - - - ..\packages\YamlDotNet.11.2.1\lib\net45\YamlDotNet.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - copy "$(TargetDir)ValheimPlus.dll" "$(VALHEIM_INSTALL)\BepInEx\plugins\ValheimPlus.dll" -copy "$(TargetDir)ValheimPlus.pdb" "$(VALHEIM_INSTALL)\BepInEx\plugins\ValheimPlus.pdb" -copy "$(TargetDir)ValheimPlus.dll.config" "$(VALHEIM_INSTALL)\BepInEx\plugins\ValheimPlus.dll.config" -$(SolutionDir)resources\tools\pdb2mdb.exe "$(TargetPath)" -copy "$(TargetDir)\ValheimPlus.dll.mdb" "$(VALHEIM_INSTALL)\BepInEx\plugins\ValheimPlus.dll.mdb" - - - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - + ..\packages\MonoMod.Utils.22.5.1.1\lib\net452\MonoMod.Utils.dll + + + + ..\packages\HarmonyX.2.10.0\lib\net45\0Harmony.dll + + + $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_googleanalytics_publicized.dll + + + $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_guiutils_publicized.dll + + + $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_lux_publicized.dll + + + $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_postprocessing_publicized.dll + + + $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_simplemeshcombine_publicized.dll + + + $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_steamworks_publicized.dll + + + $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_sunshafts_publicized.dll + + + $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_utils_publicized.dll + + + $(VALHEIM_INSTALL)\valheim_Data\Managed\publicized_assemblies\assembly_valheim_publicized.dll + + + False + $(VALHEIM_INSTALL)\BepInEx\core\BepInEx.dll + + + False + $(VALHEIM_INSTALL)\BepInEx\core\BepInEx.Harmony.dll + + + False + $(VALHEIM_INSTALL)\BepInEx\core\BepInEx.Preloader.dll + + + ..\packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll + + + False + $(VALHEIM_INSTALL)\BepInEx\core\HarmonyXInterop.dll + + + ..\packages\ini-parser.2.5.2\lib\net20\INIFileParser.dll + + + ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.dll + + + ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Mdb.dll + + + ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Pdb.dll + + + ..\packages\Mono.Cecil.0.11.4\lib\net40\Mono.Cecil.Rocks.dll + + + $(VALHEIM_INSTALL)\valheim_Data\Managed\Mono.Security.dll + + + + + ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AccessibilityModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AIModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AndroidJNIModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AnimationModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ARModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AssetBundleModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.AudioModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ClothModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ClusterInputModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ClusterRendererModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.CoreModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.CrashReportingModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.DirectorModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.DSPGraphModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.GameCenterModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.GridModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.HotReloadModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ImageConversionModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.IMGUIModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.InputLegacyModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.InputModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.JSONSerializeModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.LocalizationModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ParticleSystemModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.PerformanceReportingModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.Physics2DModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.PhysicsModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ProfilerModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.ScreenCaptureModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.SharedInternalsModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.SpriteMaskModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.SpriteShapeModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.StreamingModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.SubstanceModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.SubsystemsModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TerrainModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TerrainPhysicsModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TextCoreModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TextRenderingModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TilemapModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.TLSModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UI.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UIElementsModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UIModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UmbraModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UNETModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityAnalyticsModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityConnectModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityTestProtocolModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityWebRequestAssetBundleModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityWebRequestAudioModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityWebRequestModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityWebRequestTextureModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.UnityWebRequestWWWModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.VehiclesModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.VFXModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.VideoModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.VRModule.dll + + + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.WindModule.dll + + + False + $(VALHEIM_INSTALL)\unstripped_corlib\UnityEngine.XRModule.dll + + + ..\packages\YamlDotNet.11.2.1\lib\net45\YamlDotNet.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + copy "$(TargetDir)ValheimPlus.dll" "$(VALHEIM_INSTALL)\BepInEx\plugins\ValheimPlus.dll" + copy "$(TargetDir)ValheimPlus.pdb" "$(VALHEIM_INSTALL)\BepInEx\plugins\ValheimPlus.pdb" + copy "$(TargetDir)ValheimPlus.dll.config" "$(VALHEIM_INSTALL)\BepInEx\plugins\ValheimPlus.dll.config" + $(SolutionDir)resources\tools\pdb2mdb.exe "$(TargetPath)" + copy "$(TargetDir)\ValheimPlus.dll.mdb" "$(VALHEIM_INSTALL)\BepInEx\plugins\ValheimPlus.dll.mdb" + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + \ No newline at end of file diff --git a/ValheimPlus/app.config b/ValheimPlus/app.config index df013594..83ea8bfd 100644 --- a/ValheimPlus/app.config +++ b/ValheimPlus/app.config @@ -8,4 +8,4 @@ - + diff --git a/ValheimPlus/packages.config b/ValheimPlus/packages.config index b08b1456..1414f7c8 100644 --- a/ValheimPlus/packages.config +++ b/ValheimPlus/packages.config @@ -3,7 +3,7 @@ - + From 76d0ba968c5d33043248e5a0e0c695d0d180a8ae Mon Sep 17 00:00:00 2001 From: Joost Boomkamp Date: Wed, 7 Dec 2022 09:13:02 +0100 Subject: [PATCH 9/9] I don't know where the unstripped corlib files go. It's not working --- SetupDevEnvironment/InstallScript.cs | 37 +++++++++++++++------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/SetupDevEnvironment/InstallScript.cs b/SetupDevEnvironment/InstallScript.cs index c3e0097a..52f7e2da 100644 --- a/SetupDevEnvironment/InstallScript.cs +++ b/SetupDevEnvironment/InstallScript.cs @@ -20,7 +20,7 @@ public async Task Install() CopyValheimFiles(); await InstallBepInEx541900(); - await InstallUnstrippedFiles(); + //await InstallUnstrippedFiles(); PublicizeAssembliesDirectly(); await SetupDnSpy(); ConfigureEnvironment(); @@ -88,7 +88,7 @@ private static async Task SetupDnSpy() Logger.Log("Done!"); } - public static async Task InstallBepInEx541900() + public static async Task InstallBepInEx541900(bool includeCoreLib = false) { Logger.Log("Installing BepInEx..."); var tempFolder = DirectoryHelper.CreateTempFolder(); @@ -98,6 +98,17 @@ public static async Task InstallBepInEx541900() var sourceFolder = bepInExFiles.Single(file => file.EndsWith("BepInExPack_Valheim/")); FileCopier.CopyFiles(sourceFolder, Settings.ValheimPlusDevInstallDir); + + if (includeCoreLib) + { + var coreLibFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"unstripped_corlib\\"); + var managedFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"valheim_Data\\Managed\\"); + + FileCopier.CopyFiles(coreLibFolder, managedFolder); + } else + { + await InstallUnstrippedFiles(); + } } public static async Task InstallUnstrippedFiles() @@ -105,27 +116,19 @@ public static async Task InstallUnstrippedFiles() Logger.Log("Installing Unstripped Unity Dlls..."); var tempFolder = DirectoryHelper.CreateTempFolder(); var unstrippedZip = await Downloader.Download(Links.Unstripped_Corlib_ValheimPlusSource, Path.Combine(tempFolder, "unstripped.zip")); - var unstripped_corlibFiles = Unzipper.Unzip(unstrippedZip) + tempFolder = DirectoryHelper.CreateTempFolder(); + var unstripped_corlibFiles = Unzipper.Unzip(unstrippedZip, tempFolder) .Where(x => x.Contains("unstripped", StringComparison.CurrentCultureIgnoreCase)) .ToArray(); var managedFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"valheim_Data\\Managed\\"); - var coreLibFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"valheim_Data\\unstripped_corlib\\"); - + var coreLibFolder = Path.Combine(Settings.ValheimPlusDevInstallDir, $"unstripped_corlib\\"); + + Logger.Log("\\valheim_Data\\Managed\\"); FileCopier.CopyFiles(tempFolder, unstripped_corlibFiles, managedFolder); + Logger.Log("\\unstripped_corlib"); FileCopier.CopyFiles(tempFolder, unstripped_corlibFiles, coreLibFolder); - //Directory.CreateDirectory(managedFolder); - //foreach (var source in unstripped_corlibFiles) - //{ - // if (File.GetAttributes(source).HasFlag(FileAttributes.Directory)) { continue; } - - // var filename = Path.GetFileName(source); - - // var managedDestination = Path.Combine(managedFolder, filename); - // File.Copy(source, managedDestination, true); - //} - Logger.Log("Done!"); } @@ -138,7 +141,7 @@ public static async Task InstallBepInEx542100() File.Delete(bepInExZip); var sourceFolder = Path.GetDirectoryName(bepInExFiles.First()); - FileCopier.CopyFiles(sourceFolder!, Settings.ValheimPlusDevInstallDir); + FileCopier.CopyFiles(sourceFolder!, bepInExFiles, Settings.ValheimPlusDevInstallDir); Logger.Log("Done!"); }