レシピの仕様変更でクラスの書き換えに失敗する

MOD・プラグイン・ツールなどの開発に関する質問はこちら
アバター
おがさくら
初心者
記事: 10
登録日時: 2020年11月15日(日) 20:49
お住まい: 愛知県
ウェブサイト: https://drive.google.com/drive/folders/ ... sp=sharing

レシピの仕様変更でクラスの書き換えに失敗する

投稿記事 by おがさくら »

バニラの修繕レシピ(耐久値の減ったアイテム同士をクラフトすると耐久値が回復するレシピ)を削除するためにクラスを書き換えようとしているのですが、エラーでうまく行きません。何がいけないのか教えて欲しいです。

環境

Minecraft:1.7.10
Forge:10.13.4.1558
Java:1.8.0_311

Transformer:

コード: 全て選択

public class TransformerCraftingManager implements IClassTransformer{
	@Override
	public byte[] transform(final String name,final String transformedName,byte[] bytes){
		if(!"net.minecraft.item.crafting.CraftingManager".equals(transformedName))
			return bytes;
		ClassReader cr=new ClassReader(bytes);
		ClassWriter cw=new ClassWriter(1);
		ClassVisitor cv=new ClassVisitor(ASM4,cw){
			@Override
			public MethodVisitor visitMethod(int access,String methodName,String desc,String signature,String[] exceptions){
				MethodVisitor mv=super.visitMethod(access,methodName,desc,signature,exceptions);
				String s1=FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(name,methodName,desc);
				if(s1.equals("findMatchingRecipe")||s1.equals("func_82787_a")||methodName.equals("findMatchingRecipe")||methodName.equals("func_82787_a")){
					mv=new MethodVisitor(ASM4,mv){
						@Override
						public void visitMethodInsn(int opcode,String owner,String methodName,String desc,boolean itf){
							mv.visitVarInsn(ALOAD,1);
							mv.visitVarInsn(ALOAD,2);

						super.visitMethodInsn(INVOKESTATIC,"com/OgaMod/ASM/Recipe/TransformerCraftingManager","RemoveRepairRecipe",
								OgaModCorePlugin.toDesc("net.minecraft.item.ItemStack","net.minecraft.inventory.InventoryCrafting","net.minecraft.world.World"),false);

					}
				};
			}
			return mv;
		}
	};
	cr.accept(cv,ClassReader.EXPAND_FRAMES);
	return cw.toByteArray();
}

public static ItemStack RemoveRepairRecipe(InventoryCrafting crafting,World world){
	int i=0;
	ItemStack itemstack=null;
	ItemStack itemstack1=null;
	int j;

	for(j=0;j<crafting.getSizeInventory();++j){
		ItemStack itemstack2=crafting.getStackInSlot(j);

		if(itemstack2!=null){
			if(i==0){
				itemstack=itemstack2;
			}

			if(i==1){
				itemstack1=itemstack2;
			}

			++i;
		}
	}
	if(!(i==2&&itemstack!=null&&itemstack1!=null&&itemstack.getItem()==itemstack1.getItem()&&itemstack.stackSize==1&&itemstack1.stackSize==1&&itemstack.getItem().isRepairable())){
		for(j=0;j<CraftingManager.getInstance().getRecipeList().size();++j){
			IRecipe irecipe=(IRecipe)CraftingManager.getInstance().getRecipeList().get(j);

			if(irecipe.matches(crafting,world)){
				return irecipe.getCraftingResult(crafting);
			}
		}
		return null;
	}
	return null;
}

OgaModCorePlugin.toDesc:

コード: 全て選択

public static String toDesc(Object returnType,Object...rawDesc){
		StringBuilder sb=new StringBuilder("(");
		for(Object o:rawDesc){
			sb.append(toDesc(o));
		}
		sb.append(')');
		sb.append(toDesc(returnType));
		return sb.toString();
	}

public static String toDesc(Object raw){
	if(raw instanceof Class){
		Class<?> clazz=(Class<?>)raw;
		return Type.getDescriptor(clazz);
	}else if(raw instanceof String){
		String desc=(String)raw;
		desc=desc.replace('.','/');
		desc=desc.matches("L.+;") ? desc : "L"+desc+";";
		return desc;
	}else{
		throw new IllegalArgumentException();
	}
}
エラーの内容

[17:38:08] [main/INFO] [GradleStart]: Extra: []
[17:38:08] [main/INFO] [GradleStart]: Found and added coremod: ic2.core.coremod.IC2core
[17:38:08] [main/INFO] [GradleStart]: Running with arguments: [--userProperties, {}, --assetsDir, C:/Users/*****/.gradle/caches/minecraft/assets, --assetIndex, 1.7.10, --accessToken, {REDACTED}, --version, 1.7.10, --tweakClass, cpw.mods.fml.common.launcher.FMLTweaker, --tweakClass, net.minecraftforge.gradle.tweakers.CoremodTweaker]
[17:38:08] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLTweaker
[17:38:08] [main/INFO] [LaunchWrapper]: Using primary tweak class name cpw.mods.fml.common.launcher.FMLTweaker
[17:38:08] [main/INFO] [LaunchWrapper]: Loading tweak class name net.minecraftforge.gradle.tweakers.CoremodTweaker
[17:38:08] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLTweaker
[17:38:08] [main/INFO] [FML]: Forge Mod Loader version 7.99.36.1558 for Minecraft 1.7.10 loading
[17:38:08] [main/INFO] [FML]: Java is Java HotSpot(TM) 64-Bit Server VM, version 1.8.0_172, running on Windows 10:amd64:10.0, installed at C:\Program Files\eclipse\java\8\jre
[17:38:08] [main/INFO] [FML]: Managed to load a deobfuscated Minecraft name- we are in a deobfuscated environment. Skipping runtime deobfuscation
[17:38:08] [main/INFO] [FML]: Found a command line coremod : com.OgaMod.ASM.OgaModCorePlugin
[17:38:08] [main/WARN] [FML]: The coremod com.OgaMod.ASM.OgaModCorePlugin does not have a MCVersion annotation, it may cause issues with this version of Minecraft
[17:38:08] [main/INFO] [FML]: Found a command line coremod : ic2.core.coremod.IC2core
[17:38:08] [main/WARN] [FML]: The coremod ic2.core.coremod.IC2core does not have a MCVersion annotation, it may cause issues with this version of Minecraft
[17:38:08] [main/INFO] [LaunchWrapper]: Calling tweak class net.minecraftforge.gradle.tweakers.CoremodTweaker
[17:38:08] [main/INFO] [GradleStart]: Injecting location in coremod cpw.mods.fml.relauncher.FMLCorePlugin
[17:38:08] [main/INFO] [GradleStart]: Injecting location in coremod net.minecraftforge.classloading.FMLForgePlugin
[17:38:08] [main/INFO] [GradleStart]: Injecting location in coremod com.OgaMod.ASM.OgaModCorePlugin
[17:38:08] [main/INFO] [GradleStart]: Injecting location in coremod ic2.core.coremod.IC2core
[17:38:08] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
[17:38:08] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.FMLDeobfTweaker
[17:38:08] [main/INFO] [LaunchWrapper]: Loading tweak class name net.minecraftforge.gradle.tweakers.AccessTransformerTweaker
[17:38:08] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
[17:38:08] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLInjectionAndSortingTweaker
[17:38:08] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper
[17:38:08] [main/ERROR] [FML]: The binary patch set is missing. Either you are in a development environment, or things are not going to work!
[17:38:09] [main/ERROR] [FML]: FML appears to be missing any signature data. This is not a good thing
[17:38:09] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper
[17:38:09] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper
[17:38:09] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.relauncher.CoreModManager$FMLPluginWrapper
[17:38:09] [main/INFO] [IC2-core]: Loaded library EJML-core-0.26.jar.
[17:38:09] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.FMLDeobfTweaker
[17:38:10] [main/INFO] [LaunchWrapper]: Calling tweak class net.minecraftforge.gradle.tweakers.AccessTransformerTweaker
[17:38:10] [main/INFO] [LaunchWrapper]: Loading tweak class name cpw.mods.fml.common.launcher.TerminalTweaker
[17:38:10] [main/INFO] [LaunchWrapper]: Calling tweak class cpw.mods.fml.common.launcher.TerminalTweaker
[17:38:10] [main/INFO] [LaunchWrapper]: Launching wrapped minecraft {net.minecraft.client.main.Main}
[17:38:10] [main/INFO]: Setting user: Player88
[17:38:11] [main/ERROR] [LaunchWrapper]: Unable to launch
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_172]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_172]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_172]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_172]
at net.minecraft.launchwrapper.Launch.launch(Launch.java:135) [launchwrapper-1.12.jar:?]
at net.minecraft.launchwrapper.Launch.main(Launch.java:28) [launchwrapper-1.12.jar:?]
at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source) [start/:?]
at GradleStart.main(Unknown Source) [start/:?]
Caused by: java.lang.VerifyError: Bad type on operand stack
Exception Details:
Location:
net/minecraft/item/crafting/CraftingManager.findMatchingRecipe(Lnet/minecraft/inventory/InventoryCrafting;Lnet/minecraft/world/World;)Lnet/minecraft/item/ItemStack; @19: if_icmpge
Reason:
Type 'net/minecraft/item/ItemStack' (current frame, stack[2]) is not assignable to integer
Current Frame:
bci: @19
flags: { }
locals: { 'net/minecraft/item/crafting/CraftingManager', 'net/minecraft/inventory/InventoryCrafting', 'net/minecraft/world/World', integer, 'net/minecraft/item/ItemStack', 'net/minecraft/item/ItemStack', integer }
stack: { integer, 'net/minecraft/inventory/InventoryCrafting', 'net/minecraft/item/ItemStack' }
Bytecode:
0x0000000: 033e 013a 0401 3a05 0336 0615 062b 2b2c
0x0000010: b802 f7a2 002c 2b15 062b 2cb8 02f7 3a07
0x0000020: 1907 c600 171d 9a00 0719 073a 041d 04a0
0x0000030: 0007 1907 3a05 8403 0184 0601 a7ff cf1d
0x0000040: 05a0 009c 1904 2b2c b802 f719 052b 2cb8
0x0000050: 02f7 a600 8b19 04b4 02fa 04a0 0082 1905
0x0000060: b402 fa04 a000 7919 042b 2cb8 02f7 2b2c
0x0000070: b802 f799 006a 1904 2b2c b802 f73a 0719
0x0000080: 072b 2cb8 02f7 1904 2b2c b802 f764 3608
0x0000090: 1907 2b2c b802 f719 052b 2cb8 02f7 6436
0x00000a0: 0915 0815 0960 1907 2b2c b802 f708 6810
0x00000b0: 646c 6036 0a19 072b 2cb8 02f7 150a 6436
0x00000c0: 0b15 0b9c 0006 0336 0bbb 0052 5919 042b
0x00000d0: 2cb8 02f7 0415 0b2b 2cb8 02f7 b003 3606
0x00000e0: 1506 2ab4 001c 2b2c b802 f7a2 002e 2ab4
0x00000f0: 001c 1506 2b2c b802 f7c0 02fc 3a07 1907
0x0000100: 2b2c 2b2c b802 f799 000c 1907 2b2b 2cb8
0x0000110: 02f7 b084 0601 a7ff ca01 b0
Stackmap Table:
full_frame(@11,{Object[#2],Object[#752],Object[#754],Integer,Object[#82],Object[#82],Integer},{})
append_frame(@45,Object[#82])
same_frame(@54)
chop_frame(@57,1)
same_frame(@63)
full_frame(@201,{Object[#2],Object[#752],Object[#754],Integer,Object[#82],Object[#82],Integer,Object[#677],Integer,Integer,Integer,Integer},{})
full_frame(@221,{Object[#2],Object[#752],Object[#754],Integer,Object[#82],Object[#82],Integer},{})
same_frame(@224)
same_frame(@275)
same_frame(@281)

コード: 全て選択

at net.minecraft.stats.StatList.initCraftableStats(StatList.java:96) ~[StatList.class:?]
at net.minecraft.stats.StatList.func_151178_a(StatList.java:84) ~[StatList.class:?]
at net.minecraft.init.Bootstrap.func_151354_b(Bootstrap.java:460) ~[Bootstrap.class:?]
at net.minecraft.client.Minecraft.<init>(Minecraft.java:323) ~[Minecraft.class:?]
at net.minecraft.client.main.Main.main(Main.java:141) ~[Main.class:?]
... 8 more

Exception in thread "main" [17:38:11] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: cpw.mods.fml.relauncher.FMLSecurityManager$ExitTrappedException
[17:38:11] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at cpw.mods.fml.relauncher.FMLSecurityManager.checkPermission(FMLSecurityManager.java:25)
[17:38:11] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at java.lang.SecurityManager.checkExit(SecurityManager.java:761)
[17:38:11] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at java.lang.Runtime.exit(Runtime.java:107)
[17:38:11] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at java.lang.System.exit(System.java:971)
[17:38:11] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at net.minecraft.launchwrapper.Launch.launch(Launch.java:138)
[17:38:11] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at net.minecraft.launchwrapper.Launch.main(Launch.java:28)
[17:38:11] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at net.minecraftforge.gradle.GradleStartCommon.launch(Unknown Source)
[17:38:11] [main/INFO] [STDERR]: [java.lang.Throwable$WrappedPrintStream:println:748]: at GradleStart.main(Unknown Source)
Java HotSpot(TM) 64-Bit Server VM warning: Using incremental CMS is deprecated and will likely be removed in a future release

最後に編集したユーザー おがさくら [ 2021年11月15日(月) 10:26 ], 累計 1 回

1.2.5&1.7.10Modder
鉄ヲタ、東方好き
使用の際にはこちらをお読みください↓
https://docs.google.com/document/d/18oV ... sp=sharing

penM
サーバー管理者
記事: 150
登録日時: 2019年7月23日(火) 02:14

Re: レシピの仕様変更でクラスの書き換えに失敗する

投稿記事 by penM »

多分で申し訳ないですが下記のように「ItemStackをintに変換できない」というエラーだと思います。
InventoryCraftingでintへのキャスティング、もしくはif文などに突っ込んで暗黙的にbool?変換が起きているのではないでしょうか?

コード: 全て選択

Type 'net/minecraft/item/ItemStack' (current frame, stack[2]) is not assignable to integer
アバター
おがさくら
初心者
記事: 10
登録日時: 2020年11月15日(日) 20:49
お住まい: 愛知県
ウェブサイト: https://drive.google.com/drive/folders/ ... sp=sharing

Re: レシピの仕様変更でクラスの書き換えに失敗する

投稿記事 by おがさくら »

ありがとうございます
キャストはしていないですし、InventoryCrafingでもそのようなコードは無いと思われますね...
それにintegerは使っていないはずなのになぜかエラーの方に出て来てます
stack: { integer, 'net/minecraft/inventory/InventoryCrafting', 'net/minecraft/item/ItemStack' }

1.2.5&1.7.10Modder
鉄ヲタ、東方好き
使用の際にはこちらをお読みください↓
https://docs.google.com/document/d/18oV ... sp=sharing

penM
サーバー管理者
記事: 150
登録日時: 2019年7月23日(火) 02:14

Re: レシピの仕様変更でクラスの書き換えに失敗する

投稿記事 by penM »

ItemStackのクラス構造を持つインスタンスを、引数としてintを受け付ける関数などに渡したりとかはしていませんか?
RemoveRepairRecipeはnullを返しているように見えますが、ItemStackのインスタンスを返さなくてはいけないのでは?(あまり良くわかっていない)

アバター
おがさくら
初心者
記事: 10
登録日時: 2020年11月15日(日) 20:49
お住まい: 愛知県
ウェブサイト: https://drive.google.com/drive/folders/ ... sp=sharing

Re: レシピの仕様変更でクラスの書き換えに失敗する

投稿記事 by おがさくら »

RemoveRepairRecipeはバニラのCraftingManager.findMatchingRecipeからクラフトによるアイテム修理の部分を削除したもので、findMatchingRecipeを書き換えるようにしているのでreturn nullはもともとのコードの中に入っています。なので多分違うと思いますが...

1.2.5&1.7.10Modder
鉄ヲタ、東方好き
使用の際にはこちらをお読みください↓
https://docs.google.com/document/d/18oV ... sp=sharing

penM
サーバー管理者
記事: 150
登録日時: 2019年7月23日(火) 02:14

Re: レシピの仕様変更でクラスの書き換えに失敗する

投稿記事 by penM »

findMatchingRecipeを見る限り、こいつだけ@Nullableがついているようですが、どうでしょうか?

コード: 全て選択

@Nullable
public ItemStack findMatchingRecipe(InventoryCrafting craftMatrix,
                                               World worldIn)
アバター
おがさくら
初心者
記事: 10
登録日時: 2020年11月15日(日) 20:49
お住まい: 愛知県
ウェブサイト: https://drive.google.com/drive/folders/ ... sp=sharing

Re: レシピの仕様変更でクラスの書き換えに失敗する

投稿記事 by おがさくら »

付けてみましたが駄目ですね
同じエラーが出てしまいます

1.2.5&1.7.10Modder
鉄ヲタ、東方好き
使用の際にはこちらをお読みください↓
https://docs.google.com/document/d/18oV ... sp=sharing

アバター
おがさくら
初心者
記事: 10
登録日時: 2020年11月15日(日) 20:49
お住まい: 愛知県
ウェブサイト: https://drive.google.com/drive/folders/ ... sp=sharing

Re: レシピの仕様変更でクラスの書き換えに失敗する

投稿記事 by おがさくら »

スーパークラスのvisitMethodInsnに引数をそのまま入れて実行するのはできます
Type.getObjectType("net/minecraft/item/ItemStack")をType.VOID_TYPEにして呼び出すメソッドもvoid型にするのもできました。
しかし、getMethodDescriptorの第一引数にType.getObjectType("net/minecraft/item/ItemStack")を入れると起動できなくなってしまいます。

1.2.5&1.7.10Modder
鉄ヲタ、東方好き
使用の際にはこちらをお読みください↓
https://docs.google.com/document/d/18oV ... sp=sharing

アバター
おがさくら
初心者
記事: 10
登録日時: 2020年11月15日(日) 20:49
お住まい: 愛知県
ウェブサイト: https://drive.google.com/drive/folders/ ... sp=sharing

Re: レシピの仕様変更でクラスの書き換えに失敗する

投稿記事 by おがさくら »

ちなみに似たようなこちらのプログラムはちゃんと作動します

コード: 全て選択

	@Override
	public byte[] transform(final String name,final String transformedName,byte[] bytes){
		if(!"net.minecraft.enchantment.Enchantment".equals(transformedName))
			return bytes;
		ClassReader cr=new ClassReader(bytes);
		ClassWriter cw=new ClassWriter(1);
		ClassVisitor cv=new ClassVisitor(ASM4,cw){
			@Override
			public MethodVisitor visitMethod(int access,String methodName,String desc,String signature,String[] exceptions){
				MethodVisitor mv=super.visitMethod(access,methodName,desc,signature,exceptions);
				String s1=FMLDeobfuscatingRemapper.INSTANCE.mapMethodName(name,methodName,desc);
				if(s1.equals("getTranslatedName")||s1.equals("func_77316_c")||methodName.equals("getTranslatedName")||methodName.equals("func_77316_c")){
					mv=new MethodVisitor(ASM4,mv){
						@Override
						public void visitMethodInsn(int opcode,String owner,String methodName,String desc,boolean itf){
							mv.visitVarInsn(ALOAD,0);
							mv.visitVarInsn(ILOAD,1);

						super.visitMethodInsn(INVOKESTATIC,"com/OgaMod/ASM/Enchantment/TransformerEnchantment","newEnchantname",
								OgaModCorePlugin.toDesc(String.class,"net.minecraft.enchantment.Enchantment",int.class),false);

					}
				};
			}
			return mv;
		}
	};
	cr.accept(cv,ClassReader.EXPAND_FRAMES);
	return cw.toByteArray();
}

public static String newEnchantname(Enchantment enchant,int level){
	String s=StatCollector.translateToLocal(enchant.getName());
	return enchant.getMaxLevel()==1 ? s :level>127?s+" "+level: s+" "+StatCollector.translateToLocal("enchantment.level."+level);

}

1.2.5&1.7.10Modder
鉄ヲタ、東方好き
使用の際にはこちらをお読みください↓
https://docs.google.com/document/d/18oV ... sp=sharing

penM
サーバー管理者
記事: 150
登録日時: 2019年7月23日(火) 02:14

Re: レシピの仕様変更でクラスの書き換えに失敗する

投稿記事 by penM »

getObjectTypeの返り値がTypeでその際にint参照するんですかね?

返信する