Giter Club home page Giter Club logo

bcssov / ironymodmanager Goto Github PK

View Code? Open in Web Editor NEW
335.0 20.0 40.0 27.66 MB

Mod Manager for Paradox Games. Official Discord: https://discord.gg/t9JmY8KFrV

Home Page: https://bcssov.github.io/IronyModManager/

License: MIT License

Python 0.01% C# 98.81% Batchfile 0.34% AMPL 0.01% Inno Setup 0.83%
stellaris mod-manager paradox-interactive hearts-of-iron-4 europa-universalis-iv hearts-of-iron-iv europa-universalis-4 imperatorrome paradox crusader-kings-3

ironymodmanager's Introduction

Documentation

Check the Wiki

Building Irony Mod Manager

All instructions are for Windows.

  1. Install Visual Studio 2022 (required for .NET6)
  2. Clone the repo to your local machine
  3. Open the LocalizationResourceGenerator solution file located in \Tools\LocalizationResourceGenerator\src
    • Build the solution and copy the binaries to the Tools\LocalizationResourceGenerator folder
  4. If you don't already have one, create a folder for local NuGet packages and unzip the CWTools.Irony-Private.0.4.0-alpha8 package to it
    • This is just an up to date version of CWTools, the one on the public NuGet is older
    • Example path: C:\Users\username\code\LocalNuGet
    • If you need to set up a local NuGet repo:
      1. If not already registered, register the LocalNuGet folder with VisualStudio by clicking Tools -> NuGet Package Manager -> Package Manager Settings
      2. Select the Package Sources menu item
      3. Hit the '+' plus sign icon to create a new package source
        1. Name it Local
        2. Point it at the folder you created before
  5. In the IronyModManager directory, create a folder called "keys"
    • Example path: C:\Users\username\code\IronyModManager\keys
  6. Open the Visual Studio Terminal and create the following keys in that folder by using the command "sn -k keyPairName.snk"
    • Irony-Main
    • Irony-Plugin
  7. In the terminal, unpack the public keys from the key pairs by using the command "sn -p keyPairName.snk publicKeyName.snk"
    • Irony-Main-Public
    • Irony-Plugin-Public
  8. Copy the public keys to the \src\IronyModManager.DI folder
  9. Right click the IronyModManager.Parser project file and select Manage NuGet Packages
    • CWTools has a dependency on FSharp.Core v4.7.0 that isn't automatically resolved, so add that to the project
  10. Restore NuGet Packages for the solution
  11. Rebuild All
  12. Set IronyModManager as the Startup project and launch it

Special Thanks

Special thanks to tboby from CWTools for extending CWTools API for my needs. And also thanks to all early adopters and testers.

ironymodmanager's People

Contributors

actioninja avatar asketyll avatar bcssov avatar clazex avatar corsairmarks avatar dependabot[bot] avatar erri120 avatar kittycat2002 avatar lunartraveller avatar sanagisa avatar scrangos avatar vitalyudin avatar windmill-city avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ironymodmanager's Issues

[Suggestion][UI] Show a warning when importing a collection

Importing a collection which has the same name than an existing one erases the existing collection by the imported one.

Step to reproduce:

  • Export a collection A
  • Add mod X to collection A (A2)
  • Import previous export
  • Collection A2 is erased and replaced by A

Suggestion:

  • Warning dialog window -> ie "This collection already exists"
  • Choice: "Cancel import", "Import and Replace", "Import to a new name" (user enter a name)

Note:
In Paradox Mod Manager I made the choice to add a unique info in the name (the timestamp) which user would be able to remove when renaming the collection.

Crash when resolving issue

Hello! I am getting a crash when trying to resolve an issue. Here's the log.

2020-04-27 09:36:45.5125 System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. (Additional text encountered after finished reading JSON content: b. Path '', line 1, position 5926.) ---> Newtonsoft.Json.JsonReaderException: Additional text encountered after finished reading JSON content: b. Path '', line 1, position 5926. at Newtonsoft.Json.JsonTextReader.Read() at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value) at IronyModManager.IO.Mods.ModWriter.LoadPdxModelAsync[T](String path) at IronyModManager.IO.Mods.ModWriter.ApplyModsAsync(ModWriterParameters parameters) at IronyModManager.Services.ModService.ExportModPatchDefinitionAsync(IConflictResult conflictResult, IDefinition definition, String collectionName, Boolean resolve) at IronyModManager.ViewModels.MainConflictSolverControlViewModel.ResolveConflictAsync(Boolean resolve) in D:\Working\IronyModManager\src\IronyModManager\ViewModels\MainConflictSolverViewModel.cs:line 575 --- End of inner exception stack trace --- Newtonsoft.Json.JsonReaderException: Additional text encountered after finished reading JSON content: b. Path '', line 1, position 5926. at Newtonsoft.Json.JsonTextReader.Read() at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value) at IronyModManager.IO.Mods.ModWriter.LoadPdxModelAsync[T](String path) at IronyModManager.IO.Mods.ModWriter.ApplyModsAsync(ModWriterParameters parameters) at IronyModManager.Services.ModService.ExportModPatchDefinitionAsync(IConflictResult conflictResult, IDefinition definition, String collectionName, Boolean resolve) at IronyModManager.ViewModels.MainConflictSolverControlViewModel.ResolveConflictAsync(Boolean resolve) in D:\Working\IronyModManager\src\IronyModManager\ViewModels\MainConflictSolverViewModel.cs:line 575

Achievement detection

From Orrie:

Should be as simple as checking of certain folders include files.

If it doesn't modifies the checksum
There are some folders that modifies it, if there are modified files inside
gfx, interface, localisation and music doesn't touch the checksum
don't think flags or fonts do either
and sound

Basically, common and events will break acheivements
Maybe map

"Value cannot be null" crash

starting at v1.0.60-beta and onward on windows 10 x64 (Previous versions work fine), starting the program up and selecting stellaris will not load up any mods and will instead throw a log to the log file about how the value cannot be null. Closing the launcher and then relaunching will result in a crash loop that can only be fixed by deleting the Database.json.
2020-04-30_Error.log

File Validation

After giving it much thought I've decided to change course and have file validation as well due to potential number of false flags and or errors in using dumb parsers. At the moment all existing parser will be present and mapping infrastructure will remain, this will be phased out in a referenced issue in #36.

Feature request : Navigable virtual Stellaris folder

Emulate what Stellaris would see once launched (so what will be overwritten is ommited).

Possibly just create a "Merge" button that creates a new mod for the collection containing all mods of the collection and the patch, without any overwrites.

That would be quite handy when trying to look into errors from error.log or just to find the definitions without having to find which mods add it first.

Create descriptors

Create descriptors for mods that need it, are not installed for example (downloaded from PDX mods or Steam or Local).

Slow Treeview UI

Investigate reports when there are many objects as to what is happening.

Locked file Crash

Mod file

name="32 Real Space - Beautiful Universe v2.0 Patch"
picture="realspace_beautifuluniverse.jpg"
tags={
    "Real Space"
    "Graphics"
    "Patch"
}
supported_version="1.8.*

Log

 ---> System.IO.IOException: The process cannot access the file 'C:\Users\tsimo\Documents\Paradox Interactive\Stellaris\mod\ugc_.mod' because it is being used by another process.
   at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)
   at System.IO.FileStream.CreateFileOpenHandle(FileMode mode, FileShare share, FileOptions options)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at IronyModManager.IO.Mods.ModWriter.WriteDescriptorAsync(ModWriterParameters parameters)
   at IronyModManager.Services.ModService.InstallModsAsync()
   at IronyModManager.ViewModels.Controls.ModHolderControlViewModel.InstallModsAsync() in D:\Working\IronyModManager\src\IronyModManager\ViewModels\Controls\ModHolderControlViewModel.cs:line 212
   --- End of inner exception stack trace --- System.IO.IOException: The process cannot access the file 'C:\Users\tsimo\Documents\Paradox Interactive\Stellaris\mod\ugc_.mod' because it is being used by another process.
   at System.IO.FileStream.ValidateFileHandle(SafeFileHandle fileHandle)
   at System.IO.FileStream.CreateFileOpenHandle(FileMode mode, FileShare share, FileOptions options)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
   at IronyModManager.IO.Mods.ModWriter.WriteDescriptorAsync(ModWriterParameters parameters)
   at IronyModManager.Services.ModService.InstallModsAsync()
   at IronyModManager.ViewModels.Controls.ModHolderControlViewModel.InstallModsAsync() in D:\Working\IronyModManager\src\IronyModManager\ViewModels\Controls\ModHolderControlViewModel.cs:line 212
2020-04-15 15:04:54.6535 System.InvalidOperationException: Call from invalid thread
   at Avalonia.Threading.Dispatcher.VerifyAccess()
   at Avalonia.AvaloniaObject..ctor()
   at Avalonia.StyledElement..ctor()
   at Avalonia.Visual..ctor()
   at Avalonia.Controls.ContentControl..ctor()
   at Avalonia.Controls.TopLevel..ctor(ITopLevelImpl impl, IAvaloniaDependencyResolver dependencyResolver)
   at Avalonia.Controls.WindowBase..ctor(IWindowBaseImpl impl, IAvaloniaDependencyResolver dependencyResolver)
   at Avalonia.Controls.WindowBase..ctor(IWindowBaseImpl impl)
   at Avalonia.Controls.Window..ctor(IWindowImpl impl)
   at Avalonia.Controls.Window..ctor()
   at MessageBox.Avalonia.Views.MsBoxCustomWindow..ctor(Style style)
   at MessageBox.Avalonia.MessageBoxManager.GetMessageBoxCustomWindow(MessageBoxCustomParams params)
   at IronyModManager.MessageBoxes.GetFatalErrorWindow(String title, String header, String message) in D:\Working\IronyModManager\src\IronyModManager\Implementation\MessageBox.cs:line 50
   at IronyModManager.Program.LogError(Exception e) in D:\Working\IronyModManager\src\IronyModManager\Program.cs:line 144
   at IronyModManager.Program.TaskScheduler_UnobservedTaskException(Object sender, UnobservedTaskExceptionEventArgs e) in D:\Working\IronyModManager\src\IronyModManager\Program.cs:line 158
   at System.Threading.Tasks.TaskScheduler.PublishUnobservedTaskException(Object sender, UnobservedTaskExceptionEventArgs ueea)
   at System.Threading.Tasks.TaskExceptionHolder.Finalize() System.InvalidOperationException: Call from invalid thread
   at Avalonia.Threading.Dispatcher.VerifyAccess()
   at Avalonia.AvaloniaObject..ctor()
   at Avalonia.StyledElement..ctor()
   at Avalonia.Visual..ctor()
   at Avalonia.Controls.ContentControl..ctor()
   at Avalonia.Controls.TopLevel..ctor(ITopLevelImpl impl, IAvaloniaDependencyResolver dependencyResolver)
   at Avalonia.Controls.WindowBase..ctor(IWindowBaseImpl impl, IAvaloniaDependencyResolver dependencyResolver)
   at Avalonia.Controls.WindowBase..ctor(IWindowBaseImpl impl)
   at Avalonia.Controls.Window..ctor(IWindowImpl impl)
   at Avalonia.Controls.Window..ctor()
   at MessageBox.Avalonia.Views.MsBoxCustomWindow..ctor(Style style)
   at MessageBox.Avalonia.MessageBoxManager.GetMessageBoxCustomWindow(MessageBoxCustomParams params)
   at IronyModManager.MessageBoxes.GetFatalErrorWindow(String title, String header, String message) in D:\Working\IronyModManager\src\IronyModManager\Implementation\MessageBox.cs:line 50
   at IronyModManager.Program.LogError(Exception e) in D:\Working\IronyModManager\src\IronyModManager\Program.cs:line 144
   at IronyModManager.Program.TaskScheduler_UnobservedTaskException(Object sender, UnobservedTaskExceptionEventArgs e) in D:\Working\IronyModManager\src\IronyModManager\Program.cs:line 158
   at System.Threading.Tasks.TaskScheduler.PublishUnobservedTaskException(Object sender, UnobservedTaskExceptionEventArgs ueea)
   at System.Threading.Tasks.TaskExceptionHolder.Finalize()
˙˙˙

Conflict detector

Todo:

  • Write up the logic to export patches
  • Ensure that patches are in sync when exporting
  • Detect changes in content and remark the exported patches as obsolete

Crash or Hangup

Crashing when applying collection or when pressing conflict solver it just gets stuck in random %

error log

19:27:09.8554 System.AggregateException: A Task's exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. (Object reference not set to an instance of an object.)
---> System.NullReferenceException: Object reference not set to an instance of an object.
at IronyModManager.IO.Mods.ModWriter.MapPdxPath(ModRegistry registry, IMod mod)
at IronyModManager.IO.Mods.ModWriter.SyncData(DLCLoad dLCLoad, GameData gameData, ModRegistryCollection modRegistry, IMod mod, Boolean isEnabled)
at IronyModManager.IO.Mods.ModWriter.ApplyModsAsync(ModWriterParameters parameters)
at IronyModManager.Services.ModService.ExportModsAsync(IReadOnlyCollection1 enabledMods, IReadOnlyCollection1 regularMods, String collectionName)
at IronyModManager.ViewModels.Controls.ModHolderControlViewModel.ApplyCollectionAsync() in D:\Working\IronyModManager\src\IronyModManager\ViewModels\Controls\ModHolderControlViewModel.cs:line 191
--- End of inner exception stack trace --- System.NullReferenceException: Object reference not set to an instance of an object.
at IronyModManager.IO.Mods.ModWriter.MapPdxPath(ModRegistry registry, IMod mod)
at IronyModManager.IO.Mods.ModWriter.SyncData(DLCLoad dLCLoad, GameData gameData, ModRegistryCollection modRegistry, IMod mod, Boolean isEnabled)
at IronyModManager.IO.Mods.ModWriter.ApplyModsAsync(ModWriterParameters parameters)
at IronyModManager.Services.ModService.ExportModsAsync(IReadOnlyCollection1 enabledMods, IReadOnlyCollection1 regularMods, String collectionName)
at IronyModManager.ViewModels.Controls.ModHolderControlViewModel.ApplyCollectionAsync() in D:\Working\IronyModManager\src\IronyModManager\ViewModels\Controls\ModHolderControlViewModel.cs:line 191

A brand-new install of Irony doesn't generate the patch .mod file when importing.

A user of my most recent Steam collection that uses Irony reported the .mod file was missing on import.

Having completely cleared out the Stellaris folder and the AppData folder for Irony, followed by re-importing my collection, I can confirm that, if not for everyone, it does not create the necessary .mod file for the bundled patch.

Everything I expect you'll need to reproduce is on https://steamcommunity.com/sharedfiles/filedetails/?id=2062766262

Automatic conflict resolution for vanilla content

  1. Load vanilla content along side mod content (perhaps use indexing?)
  2. Use the vanilla defs as the common ancestor to handle automatic merge resolution by creating patches using google-match-patch

Crash issues

Try to repro manually.

Is there any error log file to send?
Got some crash :

  • one at first time I created a collection
  • one at first time I used the conflict solver

CWTools full integration

In this phase CWTools will replace most of the existing parsers once the API to utilize community rules is available. We'll need to:

  1. Download community rules
  2. Save when was the last time community rules were downloaded
  3. Provide a path to the game rules to CWTools

Custom Fonts

Currently Avalonia is borked in that regard, moving to unstable build should fix it but it's a daunting task at the moment.

Show mod and vanilla conflicts

From Reddit:

Thanks for the response.

My workflow would be "wanting to predict the intrusiveness of a new mod." I find mods that override a lot of vanilla items are likely to have conflicts or integrate poorly with other mods. It would also help when predicting robustness of the mod against version changes and in updating to new patches. For UI Overhaul it wouldn't be useful, I agree. A good example would be a Civic Pack: these can range from using mostly modifiers to editing most buildings and pop jobs in the vanilla game and it's nice to know this in advance.

It's not an urgent feature of course and even without it there'd be workarounds to do the same thing, but for me it would be nice

Autoupdate Plugins

Plugins need to have their own mechanism which plugs in into the app update to check whether plugin apps are available.

Query: Pair of mods ping-pong between LIOS and Load Order. Is this accurate or is code getting confused?

To illustrate, install Ethics and Civics Alternative https://steamcommunity.com/sharedfiles/filedetails/?id=1790861374
and Relytor's Empire Governance https://steamcommunity.com/sharedfiles/filedetails/?id=1984230854

Run the solver and then scroll down the list in common\governments - you'll see they alternate between ethics having LIOS and Relytor's having Load Order. Is this correct display or is code getting confused?

I'm proceeding as if code is correct and pulling in the Relytor's data when Ethics is listed is LIOS.

Multi drag and drop

Not a high priority at the moment, so putting it in vNext and we'll see from there in which future version we can squeeze it in.

Continuous Integration

Will eventually have to set it up. When I find the time, aside from Jenkins\Team City I've very little experience with azure pipelines and or appveyor. If anyone sees this and volunteers to take this one over I'll be eternally grateful for taking over.

Conflict solver update notifications

From discord:

would the manager detect if there is an update or do you have to check manually and rerun the solver?

Not immediately upon release. Running the solver requires me to load for 100x mods some 50000 objects in memory (at least on my configuration) and that takes some 20-30 seconds (running a lot of things in parallel). I do however have in mind for a future release to give some kind of a notification that the conflict solver needs to be run again if a mod update occurred. Kind of like mini verification and loading only modified mod files to verify their contents and see if there are changes. Should be much lighter on the system. Just one step at a time. Though I gotta write this down on github issue tracker (so that I don't forget :P)

Conflict solver not remembering state (showing conflicts regardless of being patched/changed or not)

For a test case install the following mods:

ACoT https://steamcommunity.com/sharedfiles/filedetails/?id=1419304439
Plentiful Traditions https://steamcommunity.com/sharedfiles/filedetails/?id=1311725711

Patch the armies and Scripted Triggers and flag everything else as ignored. There should be now nothing in the drop-down or list view.

Exit solver.

Enter solver

Everything is back in the drop-down/list view.

It does, however, remember state if you exit Irony and restart the app before re-entering the conflict solver. But if you then enter, exit, re-enter the solver everything is back again.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.