-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
335 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
src/main/java/com/github/soniex2/notebetter/NoteBetterClassTransformer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package com.github.soniex2.notebetter; | ||
|
||
import net.minecraft.launchwrapper.IClassTransformer; | ||
import org.objectweb.asm.ClassReader; | ||
import org.objectweb.asm.ClassWriter; | ||
import org.objectweb.asm.Opcodes; | ||
import org.objectweb.asm.tree.*; | ||
|
||
import java.util.HashMap; | ||
import java.util.ListIterator; | ||
import java.util.Map; | ||
|
||
/** | ||
* @author soniex2 | ||
*/ | ||
public class NoteBetterClassTransformer implements IClassTransformer { | ||
private Map<String, String> maps; | ||
private boolean isObfuscated; | ||
|
||
private void setupDeobfMaps() { | ||
maps = new HashMap<String, String>(); | ||
maps.put("te_mname", "triggerNote"); | ||
maps.put("te_mdesc", "(Lnet/minecraft/world/World;Lnet/minecraft/util/BlockPos;)V"); | ||
maps.put("nm_te_hndlr_desc", "(Lnet/minecraft/world/World;Lnet/minecraft/util/BlockPos;)Z"); | ||
} | ||
|
||
private void setupObfMaps() { | ||
maps = new HashMap<String, String>(); | ||
maps.put("te_mname", "func_175108_a"); | ||
maps.put("te_mdesc", "(Lnet/minecraft/world/World;Lnet/minecraft/util/BlockPos;)V"); | ||
maps.put("nm_te_hndlr_desc", "(Lnet/minecraft/world/World;Lnet/minecraft/util/BlockPos;)Z"); | ||
} | ||
|
||
@Override | ||
public byte[] transform(String name, String transformedName, byte[] basicClass) { | ||
isObfuscated = !name.equals(transformedName); | ||
if (transformedName.equals("net.minecraft.tileentity.TileEntityNote")) | ||
return transformTileEntityNote(basicClass); | ||
return basicClass; | ||
} | ||
|
||
private byte[] transformTileEntityNote(byte[] basicClass) { | ||
if (isObfuscated) setupObfMaps(); | ||
else setupDeobfMaps(); | ||
|
||
System.out.println("Transforming TileEntityNote"); | ||
|
||
try { | ||
ClassNode classNode = new ClassNode(); | ||
ClassReader classReader = new ClassReader(basicClass); | ||
classReader.accept(classNode, 0); | ||
|
||
boolean transformed = false; | ||
|
||
for (MethodNode m : classNode.methods) { | ||
if (m.name.equals(maps.get("te_mname")) && m.desc.equals(maps.get("te_mdesc"))) { | ||
ListIterator<AbstractInsnNode> it = m.instructions.iterator(); | ||
System.out.println("Transforming TileEntityNote.triggerNote"); | ||
VarInsnNode vigetWorld = new VarInsnNode(Opcodes.ALOAD, 1); | ||
it.add(vigetWorld); | ||
VarInsnNode vigetPos = new VarInsnNode(Opcodes.ALOAD, 2); | ||
it.add(vigetPos); | ||
MethodInsnNode call = new MethodInsnNode(Opcodes.INVOKESTATIC, | ||
"com/github/soniex2/notebetter/NoteMethods", | ||
"handleTileEntity", | ||
maps.get("nm_te_hndlr_desc"), | ||
false); | ||
it.add(call); | ||
LabelNode cont = new LabelNode(); | ||
JumpInsnNode test = new JumpInsnNode(Opcodes.IFEQ, cont); | ||
it.add(test); | ||
InsnNode ret = new InsnNode(Opcodes.RETURN); | ||
it.add(ret); | ||
it.add(cont); | ||
System.out.println("Done!"); | ||
transformed = true; | ||
} | ||
} | ||
if (!transformed) | ||
System.out.println("Failed to transform TileEntityNote.triggerNote"); | ||
|
||
ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); | ||
classNode.accept(writer); | ||
|
||
if (transformed) | ||
System.out.println("Transforming TileEntityNote - Success!"); | ||
else | ||
System.out.println("Transforming TileEntityNote - Failed!"); | ||
return writer.toByteArray(); | ||
} catch (Exception e) { | ||
System.out.println("Transforming TileEntityNote - Failed!"); | ||
e.printStackTrace(); | ||
} | ||
|
||
return basicClass; | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
src/main/java/com/github/soniex2/notebetter/NoteBetterCore.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package com.github.soniex2.notebetter; | ||
|
||
import net.minecraftforge.fml.common.DummyModContainer; | ||
import net.minecraftforge.fml.common.ModMetadata; | ||
import net.minecraftforge.fml.relauncher.IFMLLoadingPlugin; | ||
|
||
import java.util.Map; | ||
|
||
/** | ||
* @author soniex2 | ||
*/ | ||
@IFMLLoadingPlugin.MCVersion("1.8") | ||
@IFMLLoadingPlugin.TransformerExclusions("com.github.soniex2.notebetter") | ||
@IFMLLoadingPlugin.SortingIndex(Integer.MAX_VALUE) | ||
public class NoteBetterCore implements IFMLLoadingPlugin { | ||
public static class NoteBetterCoreModContainer extends DummyModContainer { | ||
public NoteBetterCoreModContainer(){ | ||
super(new ModMetadata()); | ||
} | ||
} | ||
/** | ||
* @inheritDoc | ||
*/ | ||
@Override | ||
public String[] getASMTransformerClass() { | ||
return new String[] { | ||
"com.github.soniex2.notebetter.NoteBetterClassTransformer" | ||
}; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
@Override | ||
public String getModContainerClass() { | ||
return null;//"com.github.soniex2.notebetter.NoteBetterCore$NoteBetterCoreModContainer"; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
@Override | ||
public String getSetupClass() { | ||
return null; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
@Override | ||
public void injectData(Map<String, Object> data) { | ||
|
||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
@Override | ||
public String getAccessTransformerClass() { | ||
return null; | ||
} | ||
} |
106 changes: 106 additions & 0 deletions
106
src/main/java/com/github/soniex2/notebetter/NoteMethods.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package com.github.soniex2.notebetter; | ||
|
||
import com.github.soniex2.notebetter.config.NoteBetterNoteConfig; | ||
import net.minecraft.block.Block; | ||
import net.minecraft.block.material.Material; | ||
import net.minecraft.block.state.IBlockState; | ||
import net.minecraft.tileentity.TileEntityNote; | ||
import net.minecraft.util.BlockPos; | ||
import net.minecraft.util.EnumParticleTypes; | ||
import net.minecraft.util.ResourceLocation; | ||
import net.minecraft.world.World; | ||
import net.minecraft.world.WorldServer; | ||
import net.minecraftforge.common.MinecraftForge; | ||
import net.minecraftforge.event.world.NoteBlockEvent; | ||
|
||
/** | ||
* @author soniex2 | ||
*/ | ||
public class NoteMethods { | ||
private static NoteBlockEvent.Instrument instrumentFromString(String instrument) { | ||
if (instrument.startsWith("minecraft:note.")) { | ||
String name = instrument.substring(15); // skip above prefix | ||
switch (name.charAt(0)) { | ||
case 'h': | ||
if (name.equals("harp")) | ||
return NoteBlockEvent.Instrument.PIANO; | ||
else if (name.equals("hat")) | ||
return NoteBlockEvent.Instrument.CLICKS; | ||
break; | ||
case 'b': | ||
if (name.equals("bd")) | ||
return NoteBlockEvent.Instrument.BASSDRUM; | ||
else if (name.equals("bassattack")) | ||
return NoteBlockEvent.Instrument.BASSGUITAR; | ||
break; | ||
case 's': | ||
if (name.equals("snare")) | ||
return NoteBlockEvent.Instrument.SNARE; | ||
break; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
private static String instrumentToString(NoteBlockEvent.Instrument instrument) { | ||
switch (instrument) { | ||
default: | ||
return "minecraft:note.harp"; | ||
case BASSDRUM: | ||
return "minecraft:note.bd"; | ||
case SNARE: | ||
return "minecraft:note.snare"; | ||
case CLICKS: | ||
return "minecraft:note.hat"; | ||
case BASSGUITAR: | ||
return "minecraft:note.bassattack"; | ||
} | ||
} | ||
|
||
private static void playNote(World world, BlockPos pos, String instrument, int note) { | ||
NoteBlockEvent.Instrument vanillaInstrument = instrumentFromString(instrument); | ||
if (vanillaInstrument != null) { | ||
NoteBlockEvent.Play e = new NoteBlockEvent.Play(world, pos, world.getBlockState(pos), note, vanillaInstrument.ordinal()); | ||
if (MinecraftForge.EVENT_BUS.post(e)) return; | ||
vanillaInstrument = e.instrument; | ||
instrument = instrumentToString(vanillaInstrument); | ||
note = e.getVanillaNoteId(); | ||
} | ||
float pitch = (float) Math.pow(2.0D, (note - 12) / 12.0D); | ||
world.playSoundEffect(pos.getX() + 0.5D, pos.getY() + 0.5D, pos.getZ() + 0.5D, instrument, 3.0F, pitch); | ||
if (world instanceof WorldServer) // just in case it *isn't* being called from a WorldServer | ||
((WorldServer) world).spawnParticle(EnumParticleTypes.NOTE, false, pos.getX() + 0.5D, pos.getY() + 1.2D, pos.getZ() + 0.5D, 0, ((double) note) / 24.0D, 0.0D, 0.0D, 1.0D); | ||
} | ||
|
||
public static boolean handleTileEntity(World world, BlockPos pos) { | ||
if (world.getBlockState(pos.up()).getBlock().getMaterial() == Material.air) { | ||
if (!(world.getTileEntity(pos) instanceof TileEntityNote)) return false; | ||
TileEntityNote te = ((TileEntityNote) world.getTileEntity(pos)); | ||
/* First we do blocks */ | ||
IBlockState bs = world.getBlockState(pos.down()); | ||
ResourceLocation rl = (ResourceLocation) Block.blockRegistry.getNameForObject(bs.getBlock()); | ||
if (NoteBetter.instance.defaultConfig.blocks.containsKey(rl.toString())) { | ||
String sound = NoteBetter.instance.defaultConfig.blocks.get(rl.toString()); | ||
if (sound == null) return true; // don't play anything | ||
playNote(world, pos, sound, te.note); | ||
return true; | ||
} | ||
/* Then we do materials */ | ||
Material m = world.getBlockState(pos.down()).getBlock().getMaterial(); | ||
for (NoteBetterNoteConfig.MaterialSound ms : NoteBetter.instance.defaultConfig.materials) { | ||
if (ms.material_of == null) continue; | ||
if (Block.getBlockFromName(ms.material_of).getMaterial() == m) { | ||
if (ms.sound == null) return true; // don't play anything | ||
playNote(world, pos, ms.sound, te.note); | ||
return true; | ||
} | ||
} | ||
/* Fallback to default */ | ||
if (NoteBetter.instance.defaultConfig.base != null) { | ||
playNote(world, pos, NoteBetter.instance.defaultConfig.base, te.note); | ||
return true; | ||
} | ||
} | ||
return false; | ||
} | ||
} |
Oops, something went wrong.