Skip to content

AssemblyPatcher has some limitations #4

Description

@SurDno

Currently, P2ModLoader can do following modifications to the assemblies:

Namespaces:

  • Adding new types with new namespaces.
  • Changing/removing namespaces of existing types.
  • File-scoped namespace support

Classes:

  • Add new classes to assembly
  • Update existing class attributes
  • Patch existing class members
  • Change base class interface list or inheritance
  • Remove existing classes

Structs:

  • Add new structs to assembly
  • Update existing struct attributes
  • Patch existing struct members
  • Change base struct interface list
  • Remove existing structs

Interfaces:

  • Add new interfaces to assembly
  • Patch existing interface method/property signatures
  • Remove existing interfaces

Enums:

  • Add new enum types to assembly
  • Add new values to existing enums
  • Update existing enum attributes
  • Modify or delete existing enum members
  • Remove existing enum types

Methods:

  • Add new methods to new types
  • Add new methods to existing types
  • Replace existing method bodies
  • Replace existing method attributes
  • Replace modifiers (public, static, virtual, etc.)
  • Patch async methods
  • Preserve in parameters
  • Preserve out parameters
  • Preserve ref parameters
  • Preserve params parameters
  • Delete methods from existing types
  • Patch iterator / yield methods (state machines)
  • Patch methods containing lambdas or compiler‑generated helpers

Constructors:

  • Add new constructors
  • Modify existing constructors

Properties:

  • Add new properties to new types
  • Add new properties to existing types
  • Replace existing getter
  • Replace existing setter
  • Delete properties from existing types
  • Initialize default values for new properties in new types
  • Change default values for existing properties in existing types
  • Initialize default values for new properties in existing types

Fields:

  • Add new fields to new types
  • Add new fields to existing types
  • Update existing field type or attributes
  • Initialize default values for new fields in new types
  • Change default values for existing properties in existing types
  • Initialize default values for new fields in existing types
  • Delete fields from existing types

Events:

  • Add new events to new types
  • Add new events to existing types
  • Update event add/remove accessors
  • Remove events from existing types

Generics:

  • Clone generic type parameters when adding new types
  • Clone generic method calls and their parameters
  • Modify existing generic type definitions in place
  • Add/remove generic parameters on existing types

Nested Types:

  • Clone nested types when adding a new parent type
  • Update nested types within existing types
  • Remove nested types

Constructors:

  • Add new constructors to new types
  • Add new constructors to existing types
  • Replace bodies of existing constructors
  • Replace attributes of existing constructors
  • Replace modifiers of existing constructors

Instructions:

  • Null operand (e.g. nop, ret, ldnull)
  • String operand (e.g. ldstr "hello")
  • Numeric operand (e.g. ldc.i4, ldc.i8, ldc.r4, ldc.r8)
  • Variable operand (e.g. ldloc, stloc)
  • Parameter operand (e.g. ldarg, starg)
  • Single branch target (e.g. br, brtrue, beq)
  • Multi‑target branch (e.g. switch)
  • Generic instance method (e.g. callvirt on a GenericInstanceMethod)
  • Generic instance type (e.g. used in newobj, isinst)
  • Generic parameter (references to a generic parameter)
  • Type reference (e.g. newobj, castclass, ldtoken)
  • Method reference (external & intra‑type calls)
  • Field reference (external & intra‑type fields)
  • Instruction target (operand is another Instruction)
  • Instruction array (e.g. array of targets for ldtoken)
  • CallSite operand (function‑pointer call sites)
  • Lambdas (e.g. in Linq)
  • dynamic types
  • Function pointers
  • Delegates

In addition to aforementioned unsupported changes, AssemblyPatcher will fail to update in any of the following cases:

  • Any sort of yield statements that would result in the creation of internal state machine. This includes any coroutines and other enumerators. In case an IEnumerable is being updated, you can modify the method successfully to return the whole IEnumerable at once instead of using yield.
  • Any types that pass reference to self (even if it happens outside of methods being edited). This happens because of reference clash between the original assembly loaded for references and the working copy with merged original code and patched methods.
  • Any references to nested types within the methods will end up being mapped to the nested copy in the working assembly.
  • Any circular dependencies as classes are added into the assembly one by one

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions