{"id":17016262,"url":"https://github.com/klotzi111/transformerinterceptor","last_synced_at":"2026-04-17T10:03:49.948Z","repository":{"id":183112515,"uuid":"438775283","full_name":"Klotzi111/TransformerInterceptor","owner":"Klotzi111","description":"Fabric mod library to register raw class transformation/generation listeners","archived":false,"fork":false,"pushed_at":"2022-06-17T19:06:27.000Z","size":87,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-27T14:56:38.053Z","etag":null,"topics":["fabric","fabric-mod","library","minecraft","minecraft-mod","mod","modding"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Klotzi111.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-12-15T21:16:19.000Z","updated_at":"2021-12-19T02:36:40.000Z","dependencies_parsed_at":"2023-07-22T23:28:19.877Z","dependency_job_id":null,"html_url":"https://github.com/Klotzi111/TransformerInterceptor","commit_stats":null,"previous_names":["klotzi111/transformerinterceptor"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Klotzi111%2FTransformerInterceptor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Klotzi111%2FTransformerInterceptor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Klotzi111%2FTransformerInterceptor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Klotzi111%2FTransformerInterceptor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Klotzi111","download_url":"https://codeload.github.com/Klotzi111/TransformerInterceptor/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244973806,"owners_count":20541025,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fabric","fabric-mod","library","minecraft","minecraft-mod","mod","modding"],"created_at":"2024-10-14T06:32:38.093Z","updated_at":"2025-10-30T11:09:03.951Z","avatar_url":"https://github.com/Klotzi111.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TransformerInterceptor\n\nFabric mod library to register raw class transformation/generation listeners.\n\n## Usage\nYou can get it via jitpack or compile it yourself.\n\n### Jitpack\nAdd the following in your build.gradle:\n\n```groovy\nrepositories {\n\tmaven {\n\t\turl \"https://jitpack.io\"\n\t}\n}\n\ndependencies {\n    include(modApi(\"com.github.Klotzi111:TransformerInterceptor:main-SNAPSHOT\"))\n}\n```\n\n### Compile self\nDo the following to use this library mod:\n - Download, build and publish this mod to your local maven repository (use the gradle task `publishToMavenLocal` for that)\n - Add the following in your build.gradle:\n \n```groovy\nrepositories {\n    mavenLocal()\n}\n\ndependencies {\n    include(modApi(\"de.klotzi111:TransformerInterceptor:1+\"))\n}\n```\n\n## Transformation types\nThere are two transformation types (register points): Basic and Raw\n### Basic (Without Mixin classes)\n`ClassTransformer`s registered on `BasicTransformerInterceptor` will be called for classes that are required from execution.\nFor the following kind of classes the transformer will be called:\nClasses of:\n - the game\n - other mods\n - fabric\n - libraries.\n\nBUT NOT classes:\n - who's package starts with `java`\n\n### Raw (With Mixin classes)\n`ClassTransformer`s registered on `RawTransformerInterceptor` will be called for classes loaded by the `MixinTransformer` (SpongepoweredMixin).\nThese transformers will be called:\n - when a mixin class is loaded\n - when a class required for the mixin is loaded\n\nIf you register for both `Basic` and `Raw` then you might get called for the same class twice (for each type). But that is good. So you should transform for both types.\nBecause:\n\n#### Note\nClasses loaded for the `Raw` type are sometimes ONLY loaded for the `MixinTransformer` (SpongepoweredMixin) and the class will be loaded again when it is required from normal execution.\n\n### Priorities\nWhen registering a `ClassTransformer` you need to give it a priority. This priority specifies the order in which the `ClassTransformer` are executed.\nHigher priorities are executed first. The default action has a priority of `0`.\nIf you want to transform after the default load/transformation has happened register your `ClassTransformer` with a priority lower than `0`.\nIf you want to transform the result of other registered `ClassTransformer` or initially load the class then use a priority higher than `0`.\n\n## Example\nBecause classes are loaded almost every time during execution you want to register your class transformer as early as possible.\nIf you register your class transformer after a class has been loaded your transformer will not get called for it, because the class will not be loaded again.\n\nTo register the class transformer very early this library has the `PreMixinLoadEntrypoint`. It does exactly what it says: Gets called before any mixin classes are loaded.\nIn order for the `PreMixinLoadEntrypoint` to get actually called you need to register it in your `fabric.mod.json` within `\"entrypoints\"` like so:\n```js\n\t\"entrypoints\": {\n\t\t\"ti:preMixinLoad\": [\n\t\t\t\"YOUR.FULL.PATH.TO.ENTRYPOINT.CLASS\"\n\t\t]\n\t}\n```\n\n```java\npublic class TransformationEntryPoint implements PreMixinLoadEntrypoint {\n\n\tprivate static class ExampleClassTransformer implements ClassTransformer {\n\n\t\t@Override\n\t\tpublic ClassTransformerResult transform(String className, ClassTransformerResult lastClassTransformerResult) {\n\t\t\tif(!lastClassTransformerResult.runTransformers) {\n\t\t\t\t// do not apply transformer when previous transformer wants no more transformations to happen\n\t\t\t\t// you can ignore that if you need to and transform anyway\n\t\t\t\treturn lastClassTransformerResult;\n\t\t\t}\n\t\t\tif(lastClassTransformerResult.classBytes == null) {\n\t\t\t\t// if the class was not previously loaded we have nothing to transform\n\t\t\t\t// you can \"create\" the class here if you want\n\t\t\t\treturn lastClassTransformerResult;\n\t\t\t}\n\t\t\t\n\t\t\t// here comes the transformation logic\n\t\t\t// IMPORTANT: you should NOT modify values inside the byte[] you get from 'lastClassTransformerResult.classBytes'\n\t\t\t// just make a copy. Or use the asm lib it will create a new byte[]\n\t\t\t\n\t\t\t// + Example\n\t\t\t// only apply transformation for specific class 'TestClass'\n\t\t\tif(!className.equals(\"YOUR.FULL.PATH.TO.CLASS.TestClass\")) {\n\t\t\t\treturn lastClassTransformerResult;\n\t\t\t}\n\t\t\tClassReader reader = new ClassReader(lastClassTransformerResult.classBytes);\n\t\t\tClassNode node = new ClassNode();\n\t\t\treader.accept(node, 0);\n\n\t\t\t// remove all fields from the class called 'REMOVE_ME'\n\t\t\tboolean changesMade = node.fields.removeIf((field) -\u003e field.name.equals(\"REMOVE_ME\"));\n\t\t\tif (changesMade) {\n\t\t\t\t// if we removed fields\n\t\t\t\tClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES);\n\t\t\t\t// accept the node to the writer\n\t\t\t\tnode.accept(writer);\n\n\t\t\t\t// generate the byte[] and set it in the result\n\t\t\t\tlastClassTransformerResult.classBytes = writer.toByteArray();\n\t\t\t}\n\t\t\t// if we did not remove fields/made changes, we do not need to create a new byte[] since it will have the exact same values\n\t\t\t// - Example\n\t\t\t\n\t\t\treturn lastClassTransformerResult;\n\t\t}\n\t}\n\n\t@Override\n\tpublic void preMixinLoad() {\n\t\t// instantiate the class transformer\n\t\tExampleClassTransformer transformer = new ExampleClassTransformer();\n\t\t\n\t\t// register the class transformer listener after default actions: priority \u003c 0\n\t\t// raw for mixin classes themselves\n\t\tPriorityMapHelper.addSafe(RawTransformerInterceptor.CLASS_TRANSFORMERS, /* just some arbitrary priority number \u003c 0 to be after default action */ -1000, transformer);\n\t\t// basic still required for non mixins to be persistent\n\t\tPriorityMapHelper.addSafe(BasicTransformerInterceptor.CLASS_TRANSFORMERS, /* just some arbitrary priority number \u003c 0 to be after default action */ -1000, transformer);\n\t}\n\n}\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklotzi111%2Ftransformerinterceptor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fklotzi111%2Ftransformerinterceptor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fklotzi111%2Ftransformerinterceptor/lists"}