Hi guys! As we all know, to patch any classes in Minecraft we need to destroy META-INF and make it not regeneble and paste obfuscated classes into jar file, Minecraft will read them and do what we need. BUT: I am looking for a way to paste NEW classes into jar (For example, when I register an Item, I type "...new ItemMagic()..."). I can create new class in the project and MCP will obfuscate it as well, but it won't be readable my Minecraft as it is not registered. Well, is there any way to create my own list of registered classes readable by Minecraft in their obfuscated var and make Minecraft use it? Thank you in advance.
P.S. I have been looking in version_name.json, but found nothing. I know that in newer versions there is a direct link in json file, but that is not my case.
I'm not sure what your issue is but I've never had any issues adding new classes to the jar; does the game crash with a "NoClassDefFoundError" or "NoSuchMethodError"? Otherwise, it sounds like you are only including your new classes, not the classes you modified to add in the references to them (for example, in my own mod I modified the "Block", "Item", etc classes to add in entries for my custom items*). MCP should reobfuscate all modified classes though, unless you ran "updateMD5.bat", which will mark all classes, including any new ones, as unmodified (usually you only run this file if you had to fix decompile errors so those classes are not seen as modified).
*For example, part of my "Block" class has entries like this, where the classes ending in "TMCW" are my own classes which replace the original vanilla classes (in the case of grass I had to extend the original class as otherwise every reference to "Block.grass" would be seen to be modified, and lead to otherwise unmodified classes being reobfuscated, due to the reference no longer being of type "BlockGrass"):
public static final Block stone = new BlockStoneTMCW(BlockStates.stone);
public static final Block biomeStone = new BlockStoneTMCW(BlockStates.biomeStone);
public static final BlockGrass grass = (BlockGrass)(new BlockGrassTMCW(BlockStates.grass));
public static final Block dirt = new BlockDirtTMCW(BlockStates.dirt);
These are the only references from vanilla code to most of my new classes, other than references from my own code or static methods (in this example BlockGrassTMCW is only directly referenced in the "Block" class) - remove the entries in the "Block" class and none of them will be seen by the game, same for any other new classes (I've forgotten to change a vanilla reference before it and may not be immediately apparent when my custom class simply modifies the behavior of a block/item. Actual new blocks/etc will normally cause a compile-time error if their declaration is missing):
Also, are you using plain vanilla MCP or a Forge-patched version/Forge MDK? I don't know about newer versions but it is possible that Forge-MCP no longer includes vanilla classes, only new ones (back in 1.6.2 I used Forge for some other mods and I made my own jar mods compatible by modifying the Forge-patched source in MCP and it did reobfuscate everything just like a vanilla MCP instance, but I know that Forge significantly changed how the MDK works; e.g. they started using "gradle". I also assume you are using an IDE which was likely set up to assume normal Forge modding, so again it may only be reobfuscating new classes (I actually don't use an IDE, just Windows Notepad and tools like the Windows Grep tool shown above, with MCP used by directly executing its batch files; TMCWv5 currently has 523 new and modified source files totaling 7.29 MB with 84% of classes being new ones and many of the vanilla classes being extensively modified so it is hardly a trivial mod, the only issue I've had with reobfuscation is the aforementioned issue of changing field references and having to extend or directly modify vanilla classes in those cases).
That said, I did have an issue with reobfuscating a mod for 1.8 that modified the world customization classes but I didn't add any new classes, only modified existing ones, and the issue was some sort of corruption in a class which crashed the game outside of MCP (the issue seems rare enough that the thread I made on the issue is the first Google search result for "minecraft mcp malformed class name" with no other relevant results):
public static final Enchantment fairMending = new EnchantmentMending(63, new ResourceLocation("mending"), 4, BREAKABLE);
(I created class EnchantmentMending)
I use 100% vanilla code (just MCP 9.18)
The main stone under water that after addind obfuscated class and modifying Enchantment.java Minecraft launches with no problems, but it crashes after I join/create a world or just refuses to load or create a world. If you know, how to patch vanilla classes in a Forge mod, send me link to a tutorial. I found this in crash log:
java.lang.IllegalAccessError: tried to access method net.minecraft.enchantment.EnchantmentMending.<init>(ILjy;ILacj;)V from class aci at aci.<clinit>(Enchantment.java:83) at ack.a(SourceFile:243) at pr.j(SourceFile:299) at pr.K(SourceFile:200) at ps.K(EntityLiving.java:217) at pk.t_(SourceFile:266) at pr.t_(SourceFile:1265) at ps.t_(EntityLiving.java:300) at adm.a(World.java:1898) at le.a(SourceFile:597) at adm.g(World.java:1867) at adm.i(World.java:1719) at le.i(SourceFile:478) at net.minecraft.server.MinecraftServer.B(MinecraftServer.java:780) at net.minecraft.server.MinecraftServer.A(MinecraftServer.java:690) at bpo.A(IntegratedServer.java:246) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:569) at java.lang.Thread.run(Thread.java:745)
MCP seems to be retaining the "package" after obfuscation and you can only access classes in another package if you import them, but the regular Minecraft classes are not in a package inside the jar (except for client\main\Main.class and server\MinecraftServer.class); MCP for 1.6.4 doesn't organize anything into packages except for these two classes (almost everything is in net.minecraft.src and the only imports I've had to do are those referencing net.minecraft.server.MinecraftServer and vice-versa). This is also supported by similar issues that others had with MCP for 1.8 (example), unfortunately, with so solutions.
As far as fixing this goes, I only have experience with MCP and 1.6.4, which as mentioned above retains the class hierarchy of the jar when decompiling. Maybe placing your new classes into "mcp\src\minecraft\net\minecraft\src" will work (IDK if this location actually exists, or it is the root of the "src" folder in MCP); otherwise, it is very hard to find any information on making mods with MCP given that virtually all mods have been made for a modloader of some sort for over a decade (I'd expect MCP to work though as its primary purpose was making mods and it is also used by e.g. Forge to decompile/compile/reobfuscate mods; I do see plenty of crash reports of "IllegalAccessError" with Forge mods but they seem to have different causes as they occur with modpacks, not individual mods).
I also tried to put the class just into jar (not to net.minecraft.enchantment), the result after trying to connect to a world is:
java.lang.NoClassDefFoundError: net/minecraft/enchantment/EnchantmentMendingjava.lang.NoClassDefFoundError: net/minecraft/enchantment/EnchantmentMending at ack.a(SourceFile:243) at pr.j(SourceFile:299) at pr.K(SourceFile:200) at ps.K(EntityLiving.java:217) at pk.t_(SourceFile:266) at pr.t_(SourceFile:1265) at ps.t_(EntityLiving.java:300) at adm.a(World.java:1898) at le.a(SourceFile:597) at adm.g(World.java:1867) at adm.i(World.java:1719) at le.i(SourceFile:478) at net.minecraft.server.MinecraftServer.B(MinecraftServer.java:780) at net.minecraft.server.MinecraftServer.A(MinecraftServer.java:690) at bpo.A(IntegratedServer.java:246) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:569) at java.lang.Thread.run(Thread.java:745)Caused by: java.lang.ClassNotFoundException: net.minecraft.enchantment.EnchantmentMending at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 17 more
I feel so much pain looking at my code building and working perfectly from IDE or starting with startclient.bat and refusing to run anywhere else... of course, I can change or add what I want and play it myself, but I can't share it able to be launched conveniently. I would use 1.6.4 or 1.7.10 unless a lot of useful commands was added only in 1.8.
Btw, "really interesting" fact: I completely added mending to 1.8, but made it more fair. If an item is enchanted as well (mending of course), it is damageble, is damaged and is being clicked in inventory with the item that can repair it using anvil, it will be repaired with an awesome logic. For example, I have damaged diamond chestplate in my inventory. It's max damage is 528, to craft it you need 8 diamonds. After cliking it with a diamond 1 diamond will disappear, but the chestplate will get 1/8 of 528 to it's durability. 528 % 8 = 0, but if it was not, it would be rounded up. So, to repair an item w mending, you need it's material, not xp.
I remembered that I'd made a mod that modified the anvil to work like in 1.7.10 and before (renaming an item stopped the prior work penalty from increasing and repair costs depended on the enchantments and durability), which modified Enchantment and ContainerRepair, and worked without any issues outside of MCP, though I did not add any new classes. In the event that something is wrong with your MCP installation I've provided the source code so you could see if it works; the mod was created in early 2015 and I don't know if MCP was ever updated since then; note that it was for 1.8, not any minor release, e.g. 1.8.1, but might work on any version of 1.8 if the classes weren't changed (the Wiki only shows MCP versions for 1.8 and 1.8.8):
As for your specific issue, it appears to be due to the fact that the constructor for Enchantment is protected (only visible from its package) and MCP is not correctly placing it in the root of the jar when reobfuscating (I looked at some other mods I'd made for 1.7-1.8 and all the class files were in the same location, i.e. the zips only contained class files, no folders).
That said, there is a possible solution if a bit ugly - instead of making your own EnchantmentMending class assign a vanilla enchantment class to the field, modifying it if necessary so the ID you used controls the enchantability/levels/etc (that is, add a new field called "isMending" and set it to true if the ID passed into the constructor is the right one, then use this field in the methods to return the appropriate values. You may not have to modify the class at all if there is one with the correct properties, e.g. if you want the enchantment table to be able to apply Mending you could use the EnchantmentDurability (Unbreaking) class, as it is applicable to any item that can be damaged). The only issue is that if you plan to add a lot of new features it will become necessary to add your own classes.
For comparison, this is what my own mod's Enchantment (partial) and EnchantmentMending classes look like; note that the package is "net.minecraft.src" and as mentioned before everything is in "mcp\src\minecraft\net\minecraft\src", except for the main/server classes. Also, the only code that references Enchantment.mending is in my own classes but I don't see that mattering (I have other enchantments which are referenced from vanilla classes, including EntityLiving, which is mentioned in your crash reports):
package net.minecraft.src;
import java.util.ArrayList;
public abstract class Enchantment
{
// omitted vanilla enchantments
// New enchantments; note the second value is weight, which also affects anvil costs unless
// overridden with getAnvilCost; 1 gives a cost of 8 per level, 2 gives 4, 5 gives 2, and 10 gives 1
public static final Enchantment mending = new EnchantmentMending(22, 1);
public static final Enchantment smelting = new EnchantmentSmelting(23, 1);
public static final Enchantment veinMiner = new EnchantmentVeinMiner(24, 2);
public static final Enchantment depthStrider = new EnchantmentDepthStrider(25, 1);
public static final Enchantment luckOfTheSea = new EnchantmentLuckOfTheSea(26, 2);
public static final Enchantment longFall = new EnchantmentLongFall(27, 1);
public static final Enchantment swiftSneak = new EnchantmentSwiftSneak(28, 1);
// constructor is protected, as it also is in 1.8, but this causes no issues
protected Enchantment(int par1, int par2, EnumEnchantmentType par3EnumEnchantmentType)
// omitted code
}
package net.minecraft.src;
public class EnchantmentMending extends Enchantment
{
protected EnchantmentMending(int par1, int par2)
{
super(par1, par2, EnumEnchantmentType.digger);
this.setName("mending");
}
// Prevents enchantment tables from applying Mending (min must be less than max for it to work)
public int getMinEnchantability(int par1)
{
return 1000;
}
public int getMaxEnchantability(int par1)
{
return 0;
}
public int getMaxLevel()
{
return 1;
}
public boolean canApply(ItemStack par1ItemStack)
{
return par1ItemStack.isItemStackDamageable() || super.canApply(par1ItemStack);
}
}
(my own Mending enchantment is a direct replacement for the pre-1.8 mechanic of renaming an item to keep the cost from increasing, allowing infinite anvil repairs but at a cost dependent on enchantments and durability, making it much more balanced; e.g. a maxed-out Fortune pickaxe is much more expensive to maintain than one without Fortune, same for diamond vs iron)
Yeah! I also thought about registering mending in an existing class and add some parameters (for example, isMenidng), but if I try to continue adding new content from newer versions, it will be too complicated. I think I will do it for a while, until I find a better way.
Another question: if modifyed MC client will work perfectly, will it be possible to create a custom Forge and Spigot (not together) versions?
Bro... everything was extremely easy... I just needed to make constructor EnchantmentMending public as in other Ench classes! I even don't need to put the class into my own directory.
I want to scream. I am extremely excited. I am almost crying. It works. I... I... I do not know what to say else.
The dream of my childhood always was ability to add or change whatever I want in Minecraft.
Hi guys! As we all know, to patch any classes in Minecraft we need to destroy META-INF and make it not regeneble and paste obfuscated classes into jar file, Minecraft will read them and do what we need. BUT: I am looking for a way to paste NEW classes into jar (For example, when I register an Item, I type "...new ItemMagic()..."). I can create new class in the project and MCP will obfuscate it as well, but it won't be readable my Minecraft as it is not registered. Well, is there any way to create my own list of registered classes readable by Minecraft in their obfuscated var and make Minecraft use it? Thank you in advance.
P.S. I have been looking in version_name.json, but found nothing. I know that in newer versions there is a direct link in json file, but that is not my case.
I'm not sure what your issue is but I've never had any issues adding new classes to the jar; does the game crash with a "NoClassDefFoundError" or "NoSuchMethodError"? Otherwise, it sounds like you are only including your new classes, not the classes you modified to add in the references to them (for example, in my own mod I modified the "Block", "Item", etc classes to add in entries for my custom items*). MCP should reobfuscate all modified classes though, unless you ran "updateMD5.bat", which will mark all classes, including any new ones, as unmodified (usually you only run this file if you had to fix decompile errors so those classes are not seen as modified).
*For example, part of my "Block" class has entries like this, where the classes ending in "TMCW" are my own classes which replace the original vanilla classes (in the case of grass I had to extend the original class as otherwise every reference to "Block.grass" would be seen to be modified, and lead to otherwise unmodified classes being reobfuscated, due to the reference no longer being of type "BlockGrass"):
These are the only references from vanilla code to most of my new classes, other than references from my own code or static methods (in this example BlockGrassTMCW is only directly referenced in the "Block" class) - remove the entries in the "Block" class and none of them will be seen by the game, same for any other new classes (I've forgotten to change a vanilla reference before it and may not be immediately apparent when my custom class simply modifies the behavior of a block/item. Actual new blocks/etc will normally cause a compile-time error if their declaration is missing):
Also, are you using plain vanilla MCP or a Forge-patched version/Forge MDK? I don't know about newer versions but it is possible that Forge-MCP no longer includes vanilla classes, only new ones (back in 1.6.2 I used Forge for some other mods and I made my own jar mods compatible by modifying the Forge-patched source in MCP and it did reobfuscate everything just like a vanilla MCP instance, but I know that Forge significantly changed how the MDK works; e.g. they started using "gradle". I also assume you are using an IDE which was likely set up to assume normal Forge modding, so again it may only be reobfuscating new classes (I actually don't use an IDE, just Windows Notepad and tools like the Windows Grep tool shown above, with MCP used by directly executing its batch files; TMCWv5 currently has 523 new and modified source files totaling 7.29 MB with 84% of classes being new ones and many of the vanilla classes being extensively modified so it is hardly a trivial mod, the only issue I've had with reobfuscation is the aforementioned issue of changing field references and having to extend or directly modify vanilla classes in those cases).
That said, I did have an issue with reobfuscating a mod for 1.8 that modified the world customization classes but I didn't add any new classes, only modified existing ones, and the issue was some sort of corruption in a class which crashed the game outside of MCP (the issue seems rare enough that the thread I made on the issue is the first Google search result for "minecraft mcp malformed class name" with no other relevant results):
https://www.minecraftforum.net/forums/mapping-and-modding-java-edition/minecraft-mods/modification-development/2348663-mod-works-fine-in-mcp-but-crashes-outside
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
java.lang.IllegalAccessError: tried to access method net.minecraft.enchantment.EnchantmentMending.<init>(ILjy;ILacj;)V from class aci at aci.<clinit>(Enchantment.java:83) at ack.a(SourceFile:243) at pr.j(SourceFile:299) at pr.K(SourceFile:200) at ps.K(EntityLiving.java:217) at pk.t_(SourceFile:266) at pr.t_(SourceFile:1265) at ps.t_(EntityLiving.java:300) at adm.a(World.java:1898) at le.a(SourceFile:597) at adm.g(World.java:1867) at adm.i(World.java:1719) at le.i(SourceFile:478) at net.minecraft.server.MinecraftServer.B(MinecraftServer.java:780) at net.minecraft.server.MinecraftServer.A(MinecraftServer.java:690) at bpo.A(IntegratedServer.java:246) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:569) at java.lang.Thread.run(Thread.java:745)
Thank you in advance.
I think the issue is this:
MCP seems to be retaining the "package" after obfuscation and you can only access classes in another package if you import them, but the regular Minecraft classes are not in a package inside the jar (except for client\main\Main.class and server\MinecraftServer.class); MCP for 1.6.4 doesn't organize anything into packages except for these two classes (almost everything is in net.minecraft.src and the only imports I've had to do are those referencing net.minecraft.server.MinecraftServer and vice-versa). This is also supported by similar issues that others had with MCP for 1.8 (example), unfortunately, with so solutions.
As far as fixing this goes, I only have experience with MCP and 1.6.4, which as mentioned above retains the class hierarchy of the jar when decompiling. Maybe placing your new classes into "mcp\src\minecraft\net\minecraft\src" will work (IDK if this location actually exists, or it is the root of the "src" folder in MCP); otherwise, it is very hard to find any information on making mods with MCP given that virtually all mods have been made for a modloader of some sort for over a decade (I'd expect MCP to work though as its primary purpose was making mods and it is also used by e.g. Forge to decompile/compile/reobfuscate mods; I do see plenty of crash reports of "IllegalAccessError" with Forge mods but they seem to have different causes as they occur with modpacks, not individual mods).
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
I also tried to put the class just into jar (not to net.minecraft.enchantment), the result after trying to connect to a world is:
java.lang.NoClassDefFoundError: net/minecraft/enchantment/EnchantmentMendingjava.lang.NoClassDefFoundError: net/minecraft/enchantment/EnchantmentMending at ack.a(SourceFile:243) at pr.j(SourceFile:299) at pr.K(SourceFile:200) at ps.K(EntityLiving.java:217) at pk.t_(SourceFile:266) at pr.t_(SourceFile:1265) at ps.t_(EntityLiving.java:300) at adm.a(World.java:1898) at le.a(SourceFile:597) at adm.g(World.java:1867) at adm.i(World.java:1719) at le.i(SourceFile:478) at net.minecraft.server.MinecraftServer.B(MinecraftServer.java:780) at net.minecraft.server.MinecraftServer.A(MinecraftServer.java:690) at bpo.A(IntegratedServer.java:246) at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:569) at java.lang.Thread.run(Thread.java:745)Caused by: java.lang.ClassNotFoundException: net.minecraft.enchantment.EnchantmentMending at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at java.lang.ClassLoader.loadClass(ClassLoader.java:424) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 17 more
I feel so much pain looking at my code building and working perfectly from IDE or starting with startclient.bat and refusing to run anywhere else... of course, I can change or add what I want and play it myself, but I can't share it able to be launched conveniently. I would use 1.6.4 or 1.7.10 unless a lot of useful commands was added only in 1.8.
Btw, "really interesting" fact: I completely added mending to 1.8, but made it more fair. If an item is enchanted as well (mending of course), it is damageble, is damaged and is being clicked in inventory with the item that can repair it using anvil, it will be repaired with an awesome logic. For example, I have damaged diamond chestplate in my inventory. It's max damage is 528, to craft it you need 8 diamonds. After cliking it with a diamond 1 diamond will disappear, but the chestplate will get 1/8 of 528 to it's durability. 528 % 8 = 0, but if it was not, it would be rounded up. So, to repair an item w mending, you need it's material, not xp.
https://www.dropbox.com/s/thath7jprwnc31f/OldAnvilRepairModSource.zip?dl=0
As for your specific issue, it appears to be due to the fact that the constructor for Enchantment is protected (only visible from its package) and MCP is not correctly placing it in the root of the jar when reobfuscating (I looked at some other mods I'd made for 1.7-1.8 and all the class files were in the same location, i.e. the zips only contained class files, no folders).
That said, there is a possible solution if a bit ugly - instead of making your own EnchantmentMending class assign a vanilla enchantment class to the field, modifying it if necessary so the ID you used controls the enchantability/levels/etc (that is, add a new field called "isMending" and set it to true if the ID passed into the constructor is the right one, then use this field in the methods to return the appropriate values. You may not have to modify the class at all if there is one with the correct properties, e.g. if you want the enchantment table to be able to apply Mending you could use the EnchantmentDurability (Unbreaking) class, as it is applicable to any item that can be damaged). The only issue is that if you plan to add a lot of new features it will become necessary to add your own classes.
For comparison, this is what my own mod's Enchantment (partial) and EnchantmentMending classes look like; note that the package is "net.minecraft.src" and as mentioned before everything is in "mcp\src\minecraft\net\minecraft\src", except for the main/server classes. Also, the only code that references Enchantment.mending is in my own classes but I don't see that mattering (I have other enchantments which are referenced from vanilla classes, including EntityLiving, which is mentioned in your crash reports):
(my own Mending enchantment is a direct replacement for the pre-1.8 mechanic of renaming an item to keep the cost from increasing, allowing infinite anvil repairs but at a cost dependent on enchantments and durability, making it much more balanced; e.g. a maxed-out Fortune pickaxe is much more expensive to maintain than one without Fortune, same for diamond vs iron)
TheMasterCaver's First World - possibly the most caved-out world in Minecraft history - includes world download.
TheMasterCaver's World - my own version of Minecraft largely based on my views of how the game should have evolved since 1.6.4.
Why do I still play in 1.6.4?
Yeah! I also thought about registering mending in an existing class and add some parameters (for example, isMenidng), but if I try to continue adding new content from newer versions, it will be too complicated. I think I will do it for a while, until I find a better way.
Another question: if modifyed MC client will work perfectly, will it be possible to create a custom Forge and Spigot (not together) versions?
Bro... everything was extremely easy... I just needed to make constructor EnchantmentMending public as in other Ench classes! I even don't need to put the class into my own directory.
I want to scream. I am extremely excited. I am almost crying. It works. I... I... I do not know what to say else.
The dream of my childhood always was ability to add or change whatever I want in Minecraft.