Remove need for program arguments. Add notice of bStats in readme.
This commit is contained in:
parent
9619fea1cc
commit
89200ae301
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<artifactId>tamablefoxes-parent</artifactId>
|
||||
<groupId>net.seanomik</groupId>
|
||||
<version>2.1.3-SNAPSHOT</version>
|
||||
<version>2.1.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>tamablefoxes_v1_14_R1</artifactId>
|
||||
|
@ -41,5 +41,15 @@
|
|||
<artifactId>anvilgui</artifactId>
|
||||
<version>1.5.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-tree</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -5,32 +5,63 @@ import net.minecraft.server.v1_14_R1.EntityTypes;
|
|||
import net.seanomik.tamablefoxes.util.FieldHelper;
|
||||
import net.seanomik.tamablefoxes.util.NMSInterface;
|
||||
import net.seanomik.tamablefoxes.util.Utils;
|
||||
import net.seanomik.tamablefoxes.util.io.Config;
|
||||
import net.seanomik.tamablefoxes.util.io.LanguageConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
// In IntelliJ, these show up as an error, but it compiles fine.
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class NMSInterface_1_14_R1 implements NMSInterface {
|
||||
@Override
|
||||
public void registerCustomFoxEntity() {
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
// This must be `EntityFox` since after being compiled, the class goes back to `EntityFox` instead of `Fox`
|
||||
ClassReader cr = new ClassReader(EntityFox.class.getResourceAsStream("EntityFox.class"));
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
node.accept(cw);
|
||||
clazz = new ClassDefiner(ClassLoader.getSystemClassLoader()).get(node.name.replace("/", "."), cw.toByteArray());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try { // Replace the fox entity
|
||||
Field field = EntityTypes.FOX.getClass().getDeclaredField("aZ");
|
||||
FieldHelper.setField(field, EntityTypes.FOX, (EntityTypes.b<EntityFox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
Field field = EntityTypes.FOX.getClass().getDeclaredField("aZ"); // aZ = factory
|
||||
Class<?> finalClazz = clazz;
|
||||
FieldHelper.setFieldUsingUnsafe(field, EntityTypes.FOX, (EntityTypes.b<EntityFox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
} catch (Exception e) {
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnTamableFox(Location loc, FoxType type) {
|
||||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle();
|
||||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, org.bukkit.entity.EntityType.FOX)).getHandle();
|
||||
tamableFox.setFoxType((type == FoxType.RED) ? EntityFox.Type.RED : EntityFox.Type.SNOW);
|
||||
}
|
||||
|
||||
static class ClassDefiner extends ClassLoader {
|
||||
public ClassDefiner(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public Class<?> get(String name, byte[] bytes) {
|
||||
Class<?> c = defineClass(name, bytes, 0, bytes.length);
|
||||
resolveClass(c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<artifactId>tamablefoxes-parent</artifactId>
|
||||
<groupId>net.seanomik</groupId>
|
||||
<version>2.1.3-SNAPSHOT</version>
|
||||
<version>2.1.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>tamablefoxes_v1_15_R1</artifactId>
|
||||
|
@ -41,5 +41,15 @@
|
|||
<artifactId>anvilgui</artifactId>
|
||||
<version>1.5.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-tree</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -5,32 +5,63 @@ import net.minecraft.server.v1_15_R1.EntityTypes;
|
|||
import net.seanomik.tamablefoxes.util.FieldHelper;
|
||||
import net.seanomik.tamablefoxes.util.NMSInterface;
|
||||
import net.seanomik.tamablefoxes.util.Utils;
|
||||
import net.seanomik.tamablefoxes.util.io.Config;
|
||||
import net.seanomik.tamablefoxes.util.io.LanguageConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftEntity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
// In IntelliJ, these show up as an error, but it compiles fine.
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class NMSInterface_1_15_R1 implements NMSInterface {
|
||||
@Override
|
||||
public void registerCustomFoxEntity() {
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
// This must be `EntityFox` since after being compiled, the class goes back to `EntityFox` instead of `Fox`
|
||||
ClassReader cr = new ClassReader(EntityFox.class.getResourceAsStream("EntityFox.class"));
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
node.accept(cw);
|
||||
clazz = new ClassDefiner(ClassLoader.getSystemClassLoader()).get(node.name.replace("/", "."), cw.toByteArray());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try { // Replace the fox entity
|
||||
Field field = EntityTypes.FOX.getClass().getDeclaredField("ba");
|
||||
FieldHelper.setField(field, EntityTypes.FOX, (EntityTypes.b<EntityFox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
Field field = EntityTypes.FOX.getClass().getDeclaredField("ba"); // ba = factory
|
||||
Class<?> finalClazz = clazz;
|
||||
FieldHelper.setFieldUsingUnsafe(field, EntityTypes.FOX, (EntityTypes.b<EntityFox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
} catch (Exception e) {
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnTamableFox(Location loc, FoxType type) {
|
||||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle();
|
||||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, org.bukkit.entity.EntityType.FOX)).getHandle();
|
||||
tamableFox.setFoxType((type == FoxType.RED) ? EntityFox.Type.RED : EntityFox.Type.SNOW);
|
||||
}
|
||||
|
||||
static class ClassDefiner extends ClassLoader {
|
||||
public ClassDefiner(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public Class<?> get(String name, byte[] bytes) {
|
||||
Class<?> c = defineClass(name, bytes, 0, bytes.length);
|
||||
resolveClass(c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<artifactId>tamablefoxes-parent</artifactId>
|
||||
<groupId>net.seanomik</groupId>
|
||||
<version>2.1.3-SNAPSHOT</version>
|
||||
<version>2.1.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>tamablefoxes_v1_16_R1</artifactId>
|
||||
|
@ -41,5 +41,15 @@
|
|||
<artifactId>anvilgui</artifactId>
|
||||
<version>1.5.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-tree</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -1,37 +1,67 @@
|
|||
package net.seanomik.tamablefoxes.versions.version_1_16_R1;
|
||||
|
||||
import net.minecraft.server.v1_16_R1.EntityTypes;
|
||||
import net.minecraft.server.v1_16_R1.EntityFox;
|
||||
import net.minecraft.server.v1_16_R1.EntityTypes;
|
||||
import net.seanomik.tamablefoxes.util.FieldHelper;
|
||||
import net.seanomik.tamablefoxes.util.NMSInterface;
|
||||
import net.seanomik.tamablefoxes.util.Utils;
|
||||
import net.seanomik.tamablefoxes.util.io.Config;
|
||||
import net.seanomik.tamablefoxes.util.io.LanguageConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftEntity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
// In IntelliJ, these show up as an error, but it compiles fine.
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class NMSInterface_1_16_R1 implements NMSInterface {
|
||||
|
||||
@Override
|
||||
public void registerCustomFoxEntity() {
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
// This must be `EntityFox` since after being compiled, the class goes back to `EntityFox` instead of `Fox`
|
||||
ClassReader cr = new ClassReader(EntityFox.class.getResourceAsStream("EntityFox.class"));
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
node.accept(cw);
|
||||
clazz = new ClassDefiner(ClassLoader.getSystemClassLoader()).get(node.name.replace("/", "."), cw.toByteArray());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try { // Replace the fox entity
|
||||
Field field = EntityTypes.FOX.getClass().getDeclaredField("be");
|
||||
FieldHelper.setField(field, EntityTypes.FOX, (EntityTypes.b<EntityFox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
Field field = EntityTypes.FOX.getClass().getDeclaredField("be"); // be = factory
|
||||
Class<?> finalClazz = clazz;
|
||||
FieldHelper.setFieldUsingUnsafe(field, EntityTypes.FOX, (EntityTypes.b<EntityFox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
} catch (Exception e) {
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnTamableFox(Location loc, FoxType type) {
|
||||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle();
|
||||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, org.bukkit.entity.EntityType.FOX)).getHandle();
|
||||
tamableFox.setFoxType((type == FoxType.RED) ? EntityFox.Type.RED : EntityFox.Type.SNOW);
|
||||
}
|
||||
|
||||
static class ClassDefiner extends ClassLoader {
|
||||
public ClassDefiner(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public Class<?> get(String name, byte[] bytes) {
|
||||
Class<?> c = defineClass(name, bytes, 0, bytes.length);
|
||||
resolveClass(c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<artifactId>tamablefoxes-parent</artifactId>
|
||||
<groupId>net.seanomik</groupId>
|
||||
<version>2.1.3-SNAPSHOT</version>
|
||||
<version>2.1.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>tamablefoxes_v1_16_R2</artifactId>
|
||||
|
@ -41,5 +41,15 @@
|
|||
<artifactId>anvilgui</artifactId>
|
||||
<version>1.5.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-tree</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -5,33 +5,63 @@ import net.minecraft.server.v1_16_R2.EntityTypes;
|
|||
import net.seanomik.tamablefoxes.util.FieldHelper;
|
||||
import net.seanomik.tamablefoxes.util.NMSInterface;
|
||||
import net.seanomik.tamablefoxes.util.Utils;
|
||||
import net.seanomik.tamablefoxes.util.io.Config;
|
||||
import net.seanomik.tamablefoxes.util.io.LanguageConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftEntity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
// In IntelliJ, these show up as an error, but it compiles fine.
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class NMSInterface_1_16_R2 implements NMSInterface {
|
||||
|
||||
@Override
|
||||
public void registerCustomFoxEntity() {
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
// This must be `EntityFox` since after being compiled, the class goes back to `EntityFox` instead of `Fox`
|
||||
ClassReader cr = new ClassReader(EntityFox.class.getResourceAsStream("EntityFox.class"));
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
node.accept(cw);
|
||||
clazz = new ClassDefiner(ClassLoader.getSystemClassLoader()).get(node.name.replace("/", "."), cw.toByteArray());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try { // Replace the fox entity
|
||||
Field field = EntityTypes.FOX.getClass().getDeclaredField("bf");
|
||||
FieldHelper.setField(field, EntityTypes.FOX, (EntityTypes.b<EntityFox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
Field field = EntityTypes.FOX.getClass().getDeclaredField("bf"); // bm = factory
|
||||
Class<?> finalClazz = clazz;
|
||||
FieldHelper.setFieldUsingUnsafe(field, EntityTypes.FOX, (EntityTypes.b<EntityFox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
} catch (Exception e) {
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnTamableFox(Location loc, FoxType type) {
|
||||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle();
|
||||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, org.bukkit.entity.EntityType.FOX)).getHandle();
|
||||
tamableFox.setFoxType((type == FoxType.RED) ? EntityFox.Type.RED : EntityFox.Type.SNOW);
|
||||
}
|
||||
|
||||
static class ClassDefiner extends ClassLoader {
|
||||
public ClassDefiner(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public Class<?> get(String name, byte[] bytes) {
|
||||
Class<?> c = defineClass(name, bytes, 0, bytes.length);
|
||||
resolveClass(c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>net.seanomik</groupId>
|
||||
<artifactId>tamablefoxes-parent</artifactId>
|
||||
<version>2.1.3-SNAPSHOT</version>
|
||||
<version>2.1.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>tamablefoxes_v1_16_R3</artifactId>
|
||||
|
@ -41,5 +41,15 @@
|
|||
<artifactId>anvilgui</artifactId>
|
||||
<version>1.5.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-tree</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -5,33 +5,63 @@ import net.minecraft.server.v1_16_R3.EntityTypes;
|
|||
import net.seanomik.tamablefoxes.util.FieldHelper;
|
||||
import net.seanomik.tamablefoxes.util.NMSInterface;
|
||||
import net.seanomik.tamablefoxes.util.Utils;
|
||||
import net.seanomik.tamablefoxes.util.io.Config;
|
||||
import net.seanomik.tamablefoxes.util.io.LanguageConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftEntity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
|
||||
// In IntelliJ, these show up as an error, but it compiles fine.
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class NMSInterface_1_16_R3 implements NMSInterface {
|
||||
|
||||
@Override
|
||||
public void registerCustomFoxEntity() {
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
// This must be `EntityFox` since after being compiled, the class goes back to `EntityFox` instead of `Fox`
|
||||
ClassReader cr = new ClassReader(EntityFox.class.getResourceAsStream("EntityFox.class"));
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
node.accept(cw);
|
||||
clazz = new ClassDefiner(ClassLoader.getSystemClassLoader()).get(node.name.replace("/", "."), cw.toByteArray());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try { // Replace the fox entity
|
||||
Field field = EntityTypes.FOX.getClass().getDeclaredField("bf");
|
||||
FieldHelper.setField(field, EntityTypes.FOX, (EntityTypes.b<EntityFox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
Field field = EntityTypes.FOX.getClass().getDeclaredField("bf"); // bm = factory
|
||||
Class<?> finalClazz = clazz;
|
||||
FieldHelper.setFieldUsingUnsafe(field, EntityTypes.FOX, (EntityTypes.b<EntityFox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
} catch (Exception e) {
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void spawnTamableFox(Location loc, FoxType type) {
|
||||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, EntityType.FOX)).getHandle();
|
||||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, org.bukkit.entity.EntityType.FOX)).getHandle();
|
||||
tamableFox.setFoxType((type == FoxType.RED) ? EntityFox.Type.RED : EntityFox.Type.SNOW);
|
||||
}
|
||||
|
||||
static class ClassDefiner extends ClassLoader {
|
||||
public ClassDefiner(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public Class<?> get(String name, byte[] bytes) {
|
||||
Class<?> c = defineClass(name, bytes, 0, bytes.length);
|
||||
resolveClass(c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>net.seanomik</groupId>
|
||||
<artifactId>tamablefoxes-parent</artifactId>
|
||||
<version>2.1.3-SNAPSHOT</version>
|
||||
<version>2.1.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -80,5 +80,15 @@
|
|||
<artifactId>anvilgui</artifactId>
|
||||
<version>1.5.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-tree</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -4,24 +4,45 @@ import net.minecraft.world.entity.EntityType;
|
|||
import net.minecraft.world.entity.animal.Fox;
|
||||
import net.seanomik.tamablefoxes.util.FieldHelper;
|
||||
import net.seanomik.tamablefoxes.util.NMSInterface;
|
||||
import net.seanomik.tamablefoxes.util.io.Config;
|
||||
import net.seanomik.tamablefoxes.util.Utils;
|
||||
import net.seanomik.tamablefoxes.util.io.LanguageConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity;
|
||||
|
||||
// In IntelliJ, these show up as an error, but it compiles fine.
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class NMSInterface_1_17_1_R1 implements NMSInterface {
|
||||
@Override
|
||||
public void registerCustomFoxEntity() {
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
// This must be `EntityFox` since after being compiled, the class goes back to `EntityFox` instead of `Fox`
|
||||
ClassReader cr = new ClassReader(Fox.class.getResourceAsStream("EntityFox.class"));
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
node.accept(cw);
|
||||
clazz = new ClassDefiner(ClassLoader.getSystemClassLoader()).get(node.name.replace("/", "."), cw.toByteArray());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try { // Replace the fox entity
|
||||
Field field = EntityType.FOX.getClass().getDeclaredField("bm"); // bm = factory
|
||||
FieldHelper.setField(field, EntityType.FOX, (EntityType.EntityFactory<Fox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
Class<?> finalClazz = clazz;
|
||||
FieldHelper.setFieldUsingUnsafe(field, EntityType.FOX, (EntityType.EntityFactory<Fox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
} catch (Exception e) {
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -31,4 +52,16 @@ public class NMSInterface_1_17_1_R1 implements NMSInterface {
|
|||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, org.bukkit.entity.EntityType.FOX)).getHandle();
|
||||
tamableFox.setFoxType((type == FoxType.RED) ? Fox.Type.RED : Fox.Type.SNOW);
|
||||
}
|
||||
|
||||
static class ClassDefiner extends ClassLoader {
|
||||
public ClassDefiner(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public Class<?> get(String name, byte[] bytes) {
|
||||
Class<?> c = defineClass(name, bytes, 0, bytes.length);
|
||||
resolveClass(c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>net.seanomik</groupId>
|
||||
<artifactId>tamablefoxes-parent</artifactId>
|
||||
<version>2.1.3-SNAPSHOT</version>
|
||||
<version>2.1.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@ -80,5 +80,15 @@
|
|||
<artifactId>anvilgui</artifactId>
|
||||
<version>1.5.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.ow2.asm</groupId>
|
||||
<artifactId>asm-tree</artifactId>
|
||||
<version>9.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -4,24 +4,45 @@ import net.minecraft.world.entity.EntityType;
|
|||
import net.minecraft.world.entity.animal.Fox;
|
||||
import net.seanomik.tamablefoxes.util.FieldHelper;
|
||||
import net.seanomik.tamablefoxes.util.NMSInterface;
|
||||
import net.seanomik.tamablefoxes.util.io.Config;
|
||||
import net.seanomik.tamablefoxes.util.Utils;
|
||||
import net.seanomik.tamablefoxes.util.io.LanguageConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftEntity;
|
||||
|
||||
// In IntelliJ, these show up as an error, but it compiles fine.
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class NMSInterface_1_17_R1 implements NMSInterface {
|
||||
@Override
|
||||
public void registerCustomFoxEntity() {
|
||||
Class<?> clazz = null;
|
||||
try {
|
||||
// This must be `EntityFox` since after being compiled, the class goes back to `EntityFox` instead of `Fox`
|
||||
ClassReader cr = new ClassReader(Fox.class.getResourceAsStream("EntityFox.class"));
|
||||
ClassNode node = new ClassNode();
|
||||
cr.accept(node, 0);
|
||||
|
||||
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
|
||||
node.accept(cw);
|
||||
clazz = new ClassDefiner(ClassLoader.getSystemClassLoader()).get(node.name.replace("/", "."), cw.toByteArray());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try { // Replace the fox entity
|
||||
Field field = EntityType.FOX.getClass().getDeclaredField("bm"); // bm = factory
|
||||
FieldHelper.setField(field, EntityType.FOX, (EntityType.EntityFactory<Fox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
Class<?> finalClazz = clazz;
|
||||
FieldHelper.setFieldUsingUnsafe(field, EntityType.FOX, (EntityType.EntityFactory<Fox>) EntityTamableFox::new);
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.GREEN + LanguageConfig.getSuccessReplaced());
|
||||
} catch (Exception e) {
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Utils.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
@ -31,4 +52,16 @@ public class NMSInterface_1_17_R1 implements NMSInterface {
|
|||
EntityTamableFox tamableFox = (EntityTamableFox) ((CraftEntity) loc.getWorld().spawnEntity(loc, org.bukkit.entity.EntityType.FOX)).getHandle();
|
||||
tamableFox.setFoxType((type == FoxType.RED) ? Fox.Type.RED : Fox.Type.SNOW);
|
||||
}
|
||||
|
||||
static class ClassDefiner extends ClassLoader {
|
||||
public ClassDefiner(ClassLoader parent) {
|
||||
super(parent);
|
||||
}
|
||||
|
||||
public Class<?> get(String name, byte[] bytes) {
|
||||
Class<?> c = defineClass(name, bytes, 0, bytes.length);
|
||||
resolveClass(c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>net.seanomik</groupId>
|
||||
<artifactId>tamablefoxes-parent</artifactId>
|
||||
<version>2.1.3-SNAPSHOT</version>
|
||||
<version>2.1.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>tamablefoxes</artifactId>
|
||||
|
|
|
@ -26,7 +26,7 @@ public final class TamableFoxes extends JavaPlugin implements Listener {
|
|||
|
||||
public NMSInterface nmsInterface;
|
||||
|
||||
public boolean equalOrBetween(double num, double min, double max) {
|
||||
private boolean equalOrBetween(double num, double min, double max) {
|
||||
return num >= min && num <= max;
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,6 @@ public final class TamableFoxes extends JavaPlugin implements Listener {
|
|||
|
||||
double versionDouble = Double.parseDouble(specificVersion.substring(2));
|
||||
|
||||
System.out.println("MC Version: " + versionDouble);
|
||||
if (equalOrBetween(versionDouble, 14D, 14.4D)) {
|
||||
nmsInterface = new NMSInterface_1_14_R1();
|
||||
} else if (equalOrBetween(versionDouble, 15D, 15.2D)) {
|
||||
|
@ -75,7 +74,6 @@ public final class TamableFoxes extends JavaPlugin implements Listener {
|
|||
}
|
||||
|
||||
Metrics metrics = new Metrics(this, BSTATS_PLUGIN_ID);
|
||||
//metrics.addCustomChart(new SingleLineChart("servers", () -> 1));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,10 +4,7 @@ SpigotMC Plugin that gives you the ability to tame foxes!
|
|||
</p>
|
||||
|
||||
### WARNING: Do not reload the plugin, you may loose foxes!!
|
||||
#### NOTE: IF YOU ARE RUNNING JAVA 16, YOU NEED TO ADD SOME STUFF TO YOUR JVM ARGUMENTS (make sure it's before the -jar argument) IN YOUR SERVER START SCRIPT:
|
||||
```bash
|
||||
--add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED
|
||||
```
|
||||
#### NOTE: You no longer need to add the program arguments to your start file. If you previously had them, you can delete them, but I don't think it would harm if you leave them in.
|
||||
|
||||
### Default configuration files:
|
||||
* <a href="https://github.com/SeanOMik/TamableFoxes/blob/master/Plugin/src/main/resources/config.yml">config.yml</a>
|
||||
|
@ -51,3 +48,6 @@ Have you ever wanted to tame foxes? Well, now you can! <b>Use chicken to tame</b
|
|||
![foxes with baby looking at player](https://www.spigotmc.org/attachments/2019-07-18_23-24-24-png.441399/)
|
||||
![giving fox totem](https://proxy.spigotmc.org/3c5f51d25b3fbb2e6bdacaa995c4e87538c13c62?url=https%3A%2F%2Fi.gyazo.com%2F34f94804beb17ffa68b73874c8c8d1d5.gif)
|
||||
![fox leaping towards chicken](https://proxy.spigotmc.org/4527d9b156ae8ad83f4b67a1407c67376eabcc52?url=https%3A%2F%2Fi.gyazo.com%2F367b397a86f31b0ba27fba228c295347.gif)
|
||||
|
||||
|
||||
<small>The plugin by default submits anonymous stats about your server (player count, plugin/server version and type) to a public statistics websites (bstats.org) in order to provide the developers with usage information. If you wish to opt out, you can do so in the `bstats/config.yml` file.
|
|
@ -7,7 +7,7 @@
|
|||
<parent>
|
||||
<groupId>net.seanomik</groupId>
|
||||
<artifactId>tamablefoxes-parent</artifactId>
|
||||
<version>2.1.3-SNAPSHOT</version>
|
||||
<version>2.1.4-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>tamablefoxes-util</artifactId>
|
||||
|
|
|
@ -4,57 +4,69 @@ import net.seanomik.tamablefoxes.util.io.Config;
|
|||
import net.seanomik.tamablefoxes.util.io.LanguageConfig;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.VarHandle;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
public final class FieldHelper {
|
||||
|
||||
private static final VarHandle MODIFIERS;
|
||||
|
||||
static {
|
||||
String version = System.getProperty("java.version");
|
||||
if (!version.startsWith("1.8")) {
|
||||
public static void setFieldUsingUnsafe(final Field field, final Object object, final Object newValue) {
|
||||
try {
|
||||
MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup());
|
||||
MODIFIERS = lookup.findVarHandle(Field.class, "modifiers", int.class);
|
||||
} catch (IllegalAccessException | NoSuchFieldException ex) {
|
||||
field.setAccessible(true);
|
||||
int fieldModifiersMask = field.getModifiers();
|
||||
boolean isFinalModifierPresent = (fieldModifiersMask & Modifier.FINAL) == Modifier.FINAL;
|
||||
if (isFinalModifierPresent) {
|
||||
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
|
||||
try {
|
||||
sun.misc.Unsafe unsafe = getUnsafe();
|
||||
long offset = unsafe.objectFieldOffset(field);
|
||||
setFieldUsingUnsafe(object, field.getType(), offset, newValue, unsafe);
|
||||
return null;
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
field.set(object, newValue);
|
||||
} catch (IllegalAccessException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
} else {
|
||||
MODIFIERS = null;
|
||||
}
|
||||
} catch (SecurityException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void makeNonFinal(Field field) {
|
||||
// Check if we're running a supported java version for this new method.
|
||||
if (MODIFIERS == null) {
|
||||
try {
|
||||
if ((field.getModifiers() & Modifier.FINAL) == Modifier.FINAL) {
|
||||
Field fieldMutable = field.getClass().getDeclaredField("modifiers");
|
||||
fieldMutable.setAccessible(true);
|
||||
fieldMutable.set(field, fieldMutable.getInt(field) & ~Modifier.FINAL);
|
||||
fieldMutable.setAccessible(false);
|
||||
}
|
||||
} catch (NoSuchFieldException | IllegalAccessException e) {
|
||||
Bukkit.getServer().getConsoleSender().sendMessage(Config.getPrefix() + ChatColor.RED + LanguageConfig.getFailureReplace());
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
int mods = field.getModifiers();
|
||||
if (Modifier.isFinal(mods)) {
|
||||
MODIFIERS.set(field, mods & ~Modifier.FINAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setField(Field field, Object obj, Object value) throws IllegalAccessException {
|
||||
makeNonFinal(field);
|
||||
private static sun.misc.Unsafe getUnsafe() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
|
||||
Field field = sun.misc.Unsafe.class.getDeclaredField("theUnsafe");
|
||||
field.setAccessible(true);
|
||||
field.set(obj, value);
|
||||
field.setAccessible(false);
|
||||
return (sun.misc.Unsafe) field.get(null);
|
||||
}
|
||||
|
||||
private static void setFieldUsingUnsafe(Object base, Class type, long offset, Object newValue, Unsafe unsafe) {
|
||||
if (type == Integer.TYPE) {
|
||||
unsafe.putInt(base, offset, ((Integer) newValue));
|
||||
} else if (type == Short.TYPE) {
|
||||
unsafe.putShort(base, offset, ((Short) newValue));
|
||||
} else if (type == Long.TYPE) {
|
||||
unsafe.putLong(base, offset, ((Long) newValue));
|
||||
} else if (type == Byte.TYPE) {
|
||||
unsafe.putByte(base, offset, ((Byte) newValue));
|
||||
} else if (type == Boolean.TYPE) {
|
||||
unsafe.putBoolean(base, offset, ((Boolean) newValue));
|
||||
} else if (type == Float.TYPE) {
|
||||
unsafe.putFloat(base, offset, ((Float) newValue));
|
||||
} else if (type == Double.TYPE) {
|
||||
unsafe.putDouble(base, offset, ((Double) newValue));
|
||||
} else if (type == Character.TYPE) {
|
||||
unsafe.putChar(base, offset, ((Character) newValue));
|
||||
} else {
|
||||
unsafe.putObject(base, offset, newValue);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue