A small companion library to Mixin, designed to help you write your Mixins in a more expressive and compatible way.

Overview

MixinExtras

A small companion library to Mixin, designed to help you write your Mixins in a more expressive and compatible way.

More information about each feature offered can be found at the Wiki.

Setup

For the time being, I recommend depending on this library via JitPack. After adding its repository to your build script, you can depend on it like so

dependencies {
    implementation("com.github.LlamaLad7:MixinExtras:0.0.3")
    annotationProcessor("com.github.LlamaLad7:MixinExtras:0.0.3")
}

It is essential that you register MixinExtras as an annotation processor if you want remapping of custom features to work. If you are registering Mixin as an annotation processor too, you must register the MixinExtras annotation processor before the Mixin one.

Bundling MixinExtras

If you intend to use this library in your mod, you will probably need to bundle it in your jar.

If you are on Fabric, I recommend using the include configuration in your dependencies block.

If you are on another platform, I recommend the Shadow Gradle Plugin. I also highly recommend you relocate MixinExtras to avoid conflicts with different versions of the library.

Initialization

The final step after setting up your build script is to initialize MixinExtras. To do this, simply call

MixinExtrasBootstrap.init();

somewhere suitably early in your program. On Fabric, this would be a PreLaunch entrypoint. If you cannot find a suitable place for your platform, you might like to use an IMixinConfigPlugin . Initializing MixinExtras in your plugin's onLoad method should work fine on any platform.

You're good to go!

Enjoy using the library, and don't hesitate to open an issue if you have any feedback, questions or suggestions.

Comments
  • [Suggestion] Skipping execution if possible in ModifyExpressionValue

    [Suggestion] Skipping execution if possible in ModifyExpressionValue

    In a regular Java conditional, if you do something like this:

    if (cheapCheck() && expensiveCheck())
    

    expensiveCheck() will only run if cheapCheck() evaluates to true (and with || only if false).

    However, with ModifyExpressionValue, as specified in the wiki, an injector like this turns into the following:

        @ModifyExpressionValue(method = "someMethod", at = @At(
                value = "INVOKE",
                target =  "LFoo;expensiveCheck(LParameters;)Z"
        ))
        private boolean cancelIfPossible(boolean original)
        {
            return cheapCheck() && original;
        }
    
    if (cancelIfPossible(expensiveCheck()))
    

    This forces expensiveCheck() to run every time, given it is passed as a parameter and therefore can't ever be skipped (unless it has no side effects or something, I'm not an expert on this).

    Would it be possible for MixinExtras to inline those in order to allow such checks to be skipped? (note that I have no idea if this is actually possible or feasible, just asking) Or would it cause the same incompatibilities as Redirect?

    An equivalent Redirect that would do the job would be something like this:

        @Redirect(method = "someMethod", at = @At(
                value = "INVOKE",
                target =  "LFoo;expensiveCheck(LParameters;)Z"
        ))
        private boolean cancelIfPossible(Foo object, Parameters params)
        {
            return cheapCheck() && object.expensiveCheck(params);
        }
    
    enhancement 
    opened by altrisi 8
  • Java 8+

    Java 8+

    Is it possible to make this compatible with java 8+

    I currently cannot use this because I get the following error:

    gamebuster@gamebuster-Ryzen9-3900X-RTX-3080:~/Desktop/Modding/WildermythGameProvider$ ./gradlew build --info
    Initialized native services in: /home/gamebuster/.gradle/native
    The client will now receive all logging from the daemon (pid: 1159260). The daemon log file: /home/gamebuster/.gradle/daemon/7.1.1/daemon-1159260.out.log
    Starting 24th build in daemon [uptime: 57 mins 53.899 secs, performance: 99%, non-heap usage: 51% of 256 MiB]
    Using 24 worker leases.
    Now considering [/home/gamebuster/Desktop/Modding/WildermythGameProvider] as hierarchies to watch
    Watching the file system is enabled if available
    Starting Build
    Settings evaluated using settings file '/home/gamebuster/Desktop/Modding/WildermythGameProvider/settings.gradle'.
    Projects loaded. Root project using build file '/home/gamebuster/Desktop/Modding/WildermythGameProvider/build.gradle'.
    Included projects: [root project 'WildermythGameProvider']
    
    > Configure project :
    Evaluating root project 'WildermythGameProvider' using build file '/home/gamebuster/Desktop/Modding/WildermythGameProvider/build.gradle'.
    All projects evaluated.
    Selected primary task 'build' from project :
    Populating VCS workingDir MixinExtra_ekvol5eg59rv8qezjbdvgjak4/MixinExtras with ref 0.0.6: c948689427146f57d5bfb80eedc6efd62bdbcb7d
    Now considering [/home/gamebuster/Desktop/Modding/WildermythGameProvider/.gradle/vcs-1/MixinExtra_ekvol5eg59rv8qezjbdvgjak4/MixinExtras, /home/gamebuster/Desktop/Modding/WildermythGameProvider] as hierarchies to watch
    
    > Configure project :MixinExtras
    Evaluating project ':MixinExtras' using build file '/home/gamebuster/Desktop/Modding/WildermythGameProvider/.gradle/vcs-1/MixinExtra_ekvol5eg59rv8qezjbdvgjak4/MixinExtras/build.gradle.kts'.
    Caching disabled for Kotlin DSL accessors for project ':MixinExtras' because:
      Build cache is disabled
    Skipping Kotlin DSL accessors for project ':MixinExtras' as it is up-to-date.
    Registering project ':MixinExtras' in composite build. Will substitute for module 'com.llamalad7:MixinExtras'.
    
    FAILURE: Build failed with an exception.
    
    * What went wrong:
    Could not determine the dependencies of task ':compileJava'.
    > Could not resolve all task dependencies for configuration ':compileClasspath'.
       > Could not resolve com.llamalad7:MixinExtras:0.0.6.
         Required by:
             project :
          > No matching variant of project :MixinExtras was found. The consumer was configured to find an API of a library compatible with Java 9, preferably in the form of class files, preferably optimized for standard JVMs, and its dependencies declared externally but:
              - Variant 'apiElements' capability com.llamalad7:MixinExtras:0.0.6 declares an API of a library, packaged as a jar, and its dependencies declared externally:
                  - Incompatible because this component declares a component compatible with Java 16 and the consumer needed a component compatible with Java 9
                  - Other compatible attribute:
                      - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
              - Variant 'runtimeElements' capability com.llamalad7:MixinExtras:0.0.6 declares a runtime of a library, packaged as a jar, and its dependencies declared externally:
                  - Incompatible because this component declares a component compatible with Java 16 and the consumer needed a component compatible with Java 9
                  - Other compatible attribute:
                      - Doesn't say anything about its target Java environment (preferred optimized for standard JVMs)
    
    * Try:
    Run with --stacktrace option to get the stack trace. Run with --debug option to get more log output. Run with --scan to get full insights.
    
    * Get more help at https://help.gradle.org
    
    BUILD FAILED in 775ms
    
    

    I also tried altering the build script myself to make it compatible with java 8, but I don't really know Kotlin, and it didn't work.

    opened by Gamebuster19901 5
  • JiJ-able fabric mod version

    JiJ-able fabric mod version

    Hi!

    Amazing library first of all, looks really useful!

    Do you think it'd be a good idea to have a JiJ-able fabric mod (maybe as a sub project/module so the main code doesn't depend on it) so if other mods can directly JiJ it, there's no need to load the same library multiple times in different locations (via shadow) and the initialization is also handled by it? That'd also make it more easily version-able and have a proper entry as a mod.

    Just a suggestion that crossed my mind, what do you think?

    enhancement 
    opened by altrisi 4
  • [Request] Be able to get a reference to the caller of non static methods in ModifyExpressionValue

    [Request] Be able to get a reference to the caller of non static methods in ModifyExpressionValue

    If targeting a non static method call with ModifyExpressionValue, it would be great if it was possible to get a reference to the object the method being called belongs to, similar to Redirect. A reference to the method arguments would also be nice if that is possible.

    enhancement 
    opened by ShaksterNano 3
  • [Suggestion] be able to use 'Object... args' for @WrapOperation

    [Suggestion] be able to use 'Object... args' for @WrapOperation

    Hi,

    sometimes you just want to wrap the method without really worrying about any of the args, in which case just having the method parameters be Object... args, Operation<?> original could be useful. I know that this alone doesnt seem like a big benefit but it can allow for more compatibility between different mc versions (where you may want to wrap the same method but it has different args) by using different this + multiple @At's.

    Similar would also be useful for @WrapWithCondition (although in that case just having no args would also do the job, especially if you want to wrap multiple @At's with the same condition.

    This isn't something super necessary but could be neat for making mods that work for lots of different versions.

    opened by KingContaria 1
  • Missing classes at runtime with forgegradle

    Missing classes at runtime with forgegradle

    Hello, I am sure I am doing something dumb, but I am having trouble getting Mixinextras setup in forge gradle. Ive used normal implementation, implementation with fg.deobf, and shade extending implementation. Unfortunately with all of these, the jar files are missing at runtime, particularly the MixinExtrasBootstrap.init() during the mixinPlugin load, as well as mod constructor.

    My branch for adding this project is here: https://github.com/baileyholl/Ars-Nouveau/pull/664/files Does anything look particularly out of place here?

    Thank you!

    opened by baileyholl 1
  • Ability to inject super class and inject new constructors

    Ability to inject super class and inject new constructors

    currently I have found mixins really lack in 2 areas: you can't make a class extend another class, and you can't add new constructors to a class. would also be preferable if those features could also do something like interface injection does, though that part should maybe be in a different lib.

    wontfix 
    opened by Trinsdar 1
  • [Request] Include binaries in github releases

    [Request] Include binaries in github releases

    Can you include the built binaries in the github releases? I don't use Jitpack because of https://github.com/jitpack/jitpack.io/issues/3973.

    I also need to download the dependencies at runtime, and I've set up a system for myself to do download artifacts from github releases.

    enhancement 
    opened by Gamebuster19901 1
  • [Suggestion] `@ModifyComparisonArg`

    [Suggestion] `@ModifyComparisonArg`

    This would wrap the entire left-hand or right-hand side of a comparison, which could be chained by multiple mixins.

    Example:

    @ModifyComparisonArg(
        method = "targetMethod", 
        comparison = "LESS_THAN_OR_EQUAL",
        argument = "SECOND" //or maybe side = "RIGHT_SIDE"?
    )
    private TargetType wrapExpression(TargetType expression){
        //TargetType is either int, long, float, double, boolean(?)
        return expression + 5;
    }
    

    Code diff:

    - if(x * i <= foo.get() * 4){
    + if(x * i <= wrapExpression(foo.get() * 4)){
        // stuff
    }
    

    Note: in this example code diff, there is no way to add 5 to either side. If you used a @ModifyExpressionValue on foo.get(), then any value you add gets multiplied by 4 (which will not be the same result). And if you used a @ModifyConstant or @Redirect on the field access, then (in this example) any change you make will also get multiplied by the other values in the expression (again, not the same result), while also not being compatible with any other mixins using the same target.

    opened by xanderstuff 2
  • Docs in javadocs?

    Docs in javadocs?

    It's kind of annoying to have to open up this github page whenever I want to check the syntax of one of your injectors. Copying the docs or at least the most important parts into javadocs would make usage a lot smoother.

    opened by MattiDragon 0
  • Adds more support for changing 'return'  and 'throw' statements

    Adds more support for changing 'return' and 'throw' statements

    • @WrapWithCondition is now able to wrap method exiting instructions, if they are safe to remove. Method exiting instructions are safe to remove, if they're always followed by another method exiting instruction and all variables, that are later used and not set, are initialized.
    • Added the @InitVariable injector, which can set variables, but, unlike @ModifyVariable, it doesn't provide the previous value and only variables from the next frame instead of the current frame are available.
    • Added the BeforeThrow (@At("MIXINEXTRAS:THROW")) injection point that targets ATHROW instructions and also can optionally accept an ordinal.
    • Added @RedirectExit injector, which can replace ATHROW and return instructions.
    • Changed @ModifyReturnValue to support replacement of the target instruction by checking the opcode of the original target instead of the current target
    • Added @ModifyThrowValue to change Throwables about to be thrown.

    Methods for the required bytecode validation are in InjectorUtils. My fork contains possible wiki entries representing the changes.

    opened by Papierkorb2292 5
  • [Suggestion] @ModifyVariables

    [Suggestion] @ModifyVariables

    What it does Like a @ModifyArgs is for multiple @ModifyArgs, a @ModifyVariables should be for multiple @ModifyVariables. Quite simple (unless you need to do hacks with the LVT) and should probably be in mixin, but this is the next best thing.

    Why it's a good idea You often need to modify parts of a vector of color that have been split up into multiple locals, and it's annoying to have to write three of them (even if they are similar).

    enhancement 
    opened by MattiDragon 3
Releases(0.1.1)
Owner
null
Excel utility for Java to read and write data in declarative way.

Data Excel Exporter A Java wrapper using Apache POI to read and write Excel file in declarative fashion. Installation ExcelUtil is using Apache POI ve

null 27 Oct 16, 2022
@FengG0d 's Client, but he leave, I am the new owner, but, I don't know how to write Java, I need your help.

IKUN Client Help me I need help! The original Author was leave, but I don't know how to write a good client, I need Your help! to make a good IKun Cli

Chenken520 2 Sep 4, 2022
A boilerplate project designed to work as a template for new microservices and help you get in touch with various useful concepts.

Microservice Reference Project This project is inspired by the idea to quickly create a production ready project with all the required infrastructure

Innovation & Tech 4 Dec 17, 2022
A fun way to learn Camunda and win a small price

Camunda-Coding-Challenge A fun way to learn about Camunda and win a small prize. The coding challenge is designed for the Camunda Code Studio. Results

null 3 Oct 2, 2021
A Mixin framework for Spigot/Bukkit that allows you to hook custom event anywhere

A Mixin framework for Spigot/Bukkit that allows you to hook custom event anywhere. Start coding your advanced plugins today!

DragonCommissions 14 Nov 30, 2022
A minecraft minigame where you have to defend your bed and destroy the others. Once your bed is destroyed, you cannot respawn.

As from November 1st 2021 BedWars1058 by Andrei Dascălu becomes open source under GNU GPL 3.0 license. If you are a developer I would really appreciat

Andrei Dascălu 182 Dec 26, 2022
This is a Maven plugin designed to help developers automatizing the creation of code classes from YML files based on AsyncApi and OpenAPI.

SCS MultiApi Maven Plugin This is a Maven plugin designed to help developers automatizing the creation of code classes from YML files based on AsyncAp

Corunet 0 Dec 20, 2022
Library that makes it possible to read, edit and write CSV files

AdaptiveTableLayout Welcome the new CSV Library AdaptiveTableLayout for Android by Cleveroad Pay your attention to our new library that makes it possi

Cleveroad 1.9k Jan 6, 2023
An Android library for member secretGFX group, This can be used to growing your apps and get more install via a simple banner view & native view and interstitial dialog.

GFX-AdPromote An Android library for member secretGFX group, This can be used to growing your apps and get more install via a simple banner view & nat

SAID MOTYA 10 Dec 25, 2022
WordleCompanion - A tool to help you determine those hard-to-guess words while doing your daily Wordle puzzles.

A tool to help you determine those hard-to-guess words while doing your daily Wordle puzzles. How it works Enter the 5-letter word you

Ken Vaczi 1 Jan 22, 2022
This application will help you to generate Elasticsearch template based on your data

Welcome to templates generator application for Elasticsearch This application will help you to generate the template and/or test index, based on your

DBeast 2 Jan 2, 2023
Java-Programs---For-Practice is one of the Java Programming Practice Series By Shaikh Minhaj ( minhaj-313 ). This Series will help you to level up your Programming Skills. This Java Programs are very much helpful for Beginners.

Java-Programs---For-Practice is one of the Java Programming Practice Series By Shaikh Minhaj ( minhaj-313 ). This Series will help you to level up your Programming Skills. This Java Programs are very much helpful for Beginners. If You Have any doubt or query you can ask me here or you can also ask me on My LinkedIn Profile

Shaikh Minhaj 3 Nov 8, 2022
The Mixin re-mapper for Lunar Client.

LunarRemapper The Mixin re-mapper for Lunar Client. I have little time to work on this project, if you know what you're doing and have familiarized yo

null 45 Nov 28, 2022
A lightweight, mixin like injection lib using ASM

ClassTransform A lightweight, mixin like injection lib using ASM. The usage is like Mixins. You can almost copy-paste mixins code and it works. Why? I

Lenni0451 15 Dec 22, 2022
Some anti afk bot which prevents you from getting punished for going afk in games. Way of stopping the bot is slightly flawed but we'll ignore that.

AntiAFK Some anti afk bot which prevents you from getting punished for going afk in games. Gui mode coming soon... Installation Install Java 17. Downl

flasky 1 Jan 13, 2022
A simple live streaming mobile app with cool functionalities and time extension, and live chat. With a payment system integrated. Server is designed with socket.io to give you full flexibility.

Video Live Streaming Platform Android A simple live streaming mobile app with cool functionalities and time extension, and live chat. With a payment s

Dev-Geek 2 Dec 16, 2022
Harvest your animals in the most cursed way possible.

Reaping Harvest your animals in the most cursed way possible. By using the Reaper you can harvest food from animals as if you had killed them, but wit

Jam Core 4 Oct 23, 2022
An Auction website. Users can Put up items for sale, bid on currently active auctions and write reviews for items that they have won in the auctions.

Auction-Project An Auction website. Users can Put up items for sale, bid on currently active auctions and write reviews for items that they have won i

Nika Salia 3 Sep 7, 2021
Facsimile - Copy Your Most Used Text to Clipboard Easily with Facsimile!. It Helps You to Store You Most Used Text as a Key, Value Pair and Copy it to Clipboard with a Shortcut.

Facsimile An exact copy of Your Information ! Report Bug · Request Feature Table of Contents About The Project Built With Getting Started Installation

Sri lakshmi kanthan P 1 Sep 12, 2022