Created
September 9, 2014 02:40
-
-
Save anonymous/6d31635dc259b326b3bd to your computer and use it in GitHub Desktop.
A way to lock chests in Vanilla Minecraft SMP 1.8
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
package mod; | |
import java.io.ByteArrayInputStream; | |
import java.lang.instrument.ClassFileTransformer; | |
import java.lang.instrument.IllegalClassFormatException; | |
import java.lang.instrument.Instrumentation; | |
import java.security.ProtectionDomain; | |
import javassist.CannotCompileException; | |
import javassist.ClassPool; | |
import javassist.CtBehavior; | |
import javassist.CtClass; | |
import javassist.expr.ExprEditor; | |
import javassist.expr.MethodCall; | |
import javassist.runtime.Desc; | |
public class LockableChests implements ClassFileTransformer { | |
public static void premain(final String arguments, final Instrumentation instrumentation) throws ClassNotFoundException { | |
Desc.useContextClassLoader = true; | |
instrumentation.addTransformer(new LockableChests()); | |
} | |
private final ClassPool classPool; | |
private LockableChests() { | |
classPool = ClassPool.getDefault(); | |
} | |
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { | |
if (className != null) { | |
try { | |
switch (className) { | |
case "rj": | |
case "qx": | |
case "aqo": | |
case "bde": | |
case "ahb": | |
case "la": | |
case "kx": | |
final CtClass clazz = classPool.makeClass(new ByteArrayInputStream(classfileBuffer)); | |
for (final CtBehavior behavior : clazz.getDeclaredBehaviors()) { | |
switch (behavior.getLongName()) { | |
// Using a named item while sneaking on a container will set/unset the lock | |
case "qx.a(ahd,aqu,amj,dt,ej,float,float,float)": | |
behavior.insertBefore("{ if ($1.aw()) { amj item = $1.bY(); if (item != null && item.s()) { bcm blockEntity = $2.s($4); vy inventory = null; if (blockEntity instanceof bcr) { inventory = aty.ae.d($2, $4); } else if (blockEntity instanceof vy) { inventory = (vy) blockEntity; } if (inventory != null) { vx lock = inventory.i(); if (lock.a()) { inventory.a(new vx(item.q())); } else if (lock.b().equals(item.q())) { inventory.a(vx.a); } } } } }"); | |
break; | |
// Locked containers cannot be broken | |
case "rj.a(ml)": | |
behavior.instrument(new ExprEditor() { | |
public void edit(MethodCall m) throws CannotCompileException { | |
try { | |
if ("net.minecraft.server.MinecraftServer.a(aqu,dt,ahd)".equals(m.getMethod().getLongName())) { | |
m.replace("{ bcm blockEntity = $1.s($2); if (blockEntity instanceof vy && !((vy)blockEntity).i().a()) { $_ = true; } else { $_ = $proceed($$); } }"); | |
} | |
} catch (Exception ex) { | |
throw new RuntimeException(ex); | |
} | |
} | |
}); | |
break; | |
// Locked containers are not affected by explosions | |
case "aqo.a()": | |
behavior.insertAfter("{ java.util.Iterator iterator = j.iterator(); while (iterator.hasNext()) { bcm blockEntity = d.s((dt)iterator.next()); if (blockEntity instanceof vy && !((vy)blockEntity).i().a()) iterator.remove(); } }"); | |
break; | |
// Locked containers don't interact with hoppers that do not share the same lock | |
case "bde.b(bdd)": | |
behavior.insertAfter("{ if ($_ instanceof vy) { vx lock = ((vy)$_).i(); if (!lock.a()) { return $1 instanceof vy && lock.b().equals(((vy)$1).i().b()) ? $_ : null; } } }"); | |
break; | |
// On death, named items dropped by the player can only be picked up by the original owner (and don't despawn) | |
case "ahb.n()": | |
behavior.instrument(new ExprEditor() { | |
public void edit(MethodCall m) throws CannotCompileException { | |
try { | |
if ("ahd.a(amj,boolean,boolean)".equals(m.getMethod().getLongName())) { | |
m.replace("{ $_ = $proceed($$); if ($1.s()) { fn data = new fn(); $_.b(data); data.a(\"Owner\", $0.cc().getName()); data.a(\"Age\", -32768); $_.a(data); } }"); | |
} | |
} catch (Exception ex) { | |
throw new RuntimeException(ex); | |
} | |
} | |
}); | |
break; | |
// Do not broadcast the name of items equipped by entities (players included) | |
case "la(int,int,amj)": | |
behavior.insertAfter("{ if (c != null && c.s()) { c.r(); } }"); | |
break; | |
// Do not broadcast the name of items when they are entities in the world (eg: dropped on the ground) | |
case "kx(int,xv,boolean)": | |
behavior.insertAfter("{ if (b != null) { java.util.ListIterator iterator = b.listIterator(); while (iterator.hasNext()) { xw object = (xw) iterator.next(); if (object.b() instanceof amj) { amj item = (amj) object.b(); if (item.s()) { item = item.k(); item.r(); iterator.set(new xw(object.c(), object.a(), item)); } } } } }"); | |
break; | |
} | |
} | |
return clazz.toBytecode(); | |
} | |
} catch (final Exception ex) { | |
ex.printStackTrace(); | |
throw new RuntimeException(ex); | |
} | |
} | |
return classfileBuffer; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment