Skip to content

Instantly share code, notes, and snippets.

@marysaka
Created March 1, 2016 12:27
Show Gist options
  • Save marysaka/84180a2cfa63a6ae3ca3 to your computer and use it in GitHub Desktop.
Save marysaka/84180a2cfa63a6ae3ca3 to your computer and use it in GitHub Desktop.
[Spigot 1.9 NMS] Biome Registry Hack
package eu.thog.base.utils.v1_9_R1;
import eu.thog.base.utils.IDRegistry;
import eu.thog.base.utils.IRegistry;
import eu.thog.base.utils.ReflectionUtils;
import net.minecraft.server.v1_9_R1.BiomeBase;
import net.minecraft.server.v1_9_R1.MinecraftKey;
import net.minecraft.server.v1_9_R1.RegistryID;
import net.minecraft.server.v1_9_R1.RegistryMaterials;
import org.apache.commons.lang3.Validate;
import org.bukkit.Bukkit;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
/**
* BiomeRegistry Wrapper
* Created by Thog the 01/03/2016 at 13:10
*/
public class BiomeRegistry extends RegistryMaterials<net.minecraft.server.v1_9_R1.MinecraftKey, BiomeBase> implements IRegistry<net.minecraft.server.v1_9_R1.MinecraftKey, BiomeBase>
{
protected final Map<MinecraftKey, BiomeBase> registry = new HashMap<>();
protected final IDRegistry<BiomeBase> idRegistry = new IDRegistry(256);
public static BiomeRegistry getInstance()
{
if (!(BiomeBase.REGISTRY_ID instanceof BiomeRegistry))
init();
return (BiomeRegistry) BiomeBase.REGISTRY_ID;
}
@Override
public void a(int id, MinecraftKey entry, BiomeBase value)
{
this.register(id, entry, value);
}
@Override
public void a(MinecraftKey entry, BiomeBase value)
{
Validate.notNull(entry);
Validate.notNull(value);
if(this.registry.containsKey(entry))
Bukkit.getLogger().log(Level.FINE, "Adding duplicate key \'" + entry + "\' to registry");
this.registry.put(entry, value);
}
@Override
public void register(int id, MinecraftKey entry, BiomeBase value)
{
this.idRegistry.put(value, id);
this.a(entry, value);
}
@Override
public BiomeBase get(MinecraftKey var1)
{
return this.getObject(var1);
}
@Override
public MinecraftKey b(BiomeBase var1)
{
return this.getNameForObject(var1);
}
@Override
public boolean d(MinecraftKey var1)
{
return this.containsKey(var1);
}
@Override
public int a(BiomeBase var1)
{
return this.getIDForObject(var1);
}
@Override
public BiomeBase getId(int var1)
{
return this.getObjectById(var1);
}
@Override
public BiomeBase getObject(MinecraftKey name)
{
return registry.get(name);
}
@Override
public MinecraftKey getNameForObject(BiomeBase obj)
{
MinecraftKey result = null;
for (Map.Entry<MinecraftKey, BiomeBase> entryset : registry.entrySet())
{
if (entryset.getValue() != null && entryset.getValue().equals(obj))
{
if (result != null)
{
Bukkit.getLogger().warning("DUPLICATE ENTRY FOR BIOME " + obj.getClass().getName());
break;
}
result = entryset.getKey();
}
}
return result;
}
@Override
public boolean containsKey(MinecraftKey key)
{
return registry.containsKey(key);
}
@Override
public int getIDForObject(BiomeBase obj)
{
return this.idRegistry.get(obj);
}
@Override
public BiomeBase getObjectById(int id)
{
return this.idRegistry.getByValue(id);
}
@Override
public Iterator<BiomeBase> iterator()
{
return this.idRegistry.iterator();
}
public static boolean init()
{
try
{
BiomeRegistry registry = new BiomeRegistry();
RegistryMaterials<MinecraftKey, BiomeBase> oldRegistry = BiomeBase.REGISTRY_ID;
RegistryID<BiomeBase> oldIDRegistry = (RegistryID<BiomeBase>) ReflectionUtils.getValue(RegistryMaterials.class, oldRegistry, "a");;
Map<BiomeBase, MinecraftKey> oldDataRegistry = (Map<BiomeBase, MinecraftKey>) ReflectionUtils.getValue(RegistryMaterials.class, oldRegistry, "b");
for (Map.Entry<BiomeBase, MinecraftKey> entry : oldDataRegistry.entrySet())
{
int id = oldIDRegistry.getId(entry.getKey());
if (id == -1 || entry.getKey() == null)
continue;
registry.register(id, entry.getValue(), entry.getKey());
}
ReflectionUtils.setFinalStatic(BiomeBase.class.getDeclaredField("REGISTRY_ID"), registry);
} catch (ReflectiveOperationException e)
{
e.printStackTrace();
return false;
}
return true;
}
}
package eu.thog.base.utils;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
/**
* ID Registry Utility Class
* Created by Thog the 01/03/2016 at 13:12
*/
public class IDRegistry<T> implements Iterable<T>
{
private final IdentityHashMap<T, Integer> identityMap;
private final List<T> objectList = Lists.newArrayList();
public IDRegistry(int size)
{
this.identityMap = new IdentityHashMap(size);
}
public void put(T key, Integer value)
{
this.identityMap.put(key, value);
while (this.objectList.size() <= value)
{
this.objectList.add(null);
}
this.objectList.set(value, key);
}
public void remove(T key)
{
this.put(key, null);
}
public int get(T key)
{
Integer integer = this.identityMap.get(key);
return integer == null ? -1 : integer.intValue();
}
public final T getByValue(int value)
{
return (T)(value >= 0 && value < this.objectList.size() ? this.objectList.get(value) : null);
}
public Iterator<T> iterator()
{
return Iterators.filter(this.objectList.iterator(), Predicates.notNull());
}
}
package eu.thog.base.utils;
public interface IRegistry<K, V> extends Iterable<V>
{
void register(int id, K entry, V value);
V getObject(K name);
/**
* Gets the name we use to identify the given object.
*/
K getNameForObject(V obj);
/**
* Does this registry contain an entry for the given key?
*/
boolean containsKey(K key);
/**
* Gets the integer ID we use to identify the given object.
*/
int getIDForObject(V obj);
/**
* Gets the object identified by the given ID.
*/
V getObjectById(int id);
}
package eu.thog.base.utils;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
* Reflection Utils
* Created by Thog the 01/03/2016 at 13:13
*/
public class ReflectionUtils
{
public static void setFinalStatic(Field field, Object value) throws ReflectiveOperationException
{
field.setAccessible(true);
Field mf = Field.class.getDeclaredField("modifiers");
mf.setAccessible(true);
mf.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, value);
}
public static Object getValue(Class source, Object val, String target) throws NoSuchFieldException, IllegalAccessException
{
Field f = source.getDeclaredField(target);
f.setAccessible(true);
return f.get(val);
}
}
package eu.thog;
import eu.thog.base.utils.v1_9_R1.BiomeRegistry;
import net.minecraft.server.v1_9_R1.MinecraftKey;
import org.bukkit.plugin.java.JavaPlugin;
/**
* Basic Usage to replace Ocean biomes
* Created by Thog the 01/03/2016 at 13:20
*/
public class Usage extends JavaPlugin
{
@Override
public void onEnable()
{
BiomeRegistry registry = BiomeRegistry.getInstance();
registry.register(0, new MinecraftKey("ocean"), registry.getObject(new MinecraftKey("forest")));
registry.register(10, new MinecraftKey("frozen_ocean"), registry.getObject(new MinecraftKey("forest")));
registry.register(24, new MinecraftKey("deep_ocean"), registry.getObject(new MinecraftKey("forest")));
}
}
@ConnorLinfoot
Copy link

Not sure if you'll see this but I've found this and attempted to use it but it seems to just replace the biomes with a mushroom biome? If you have any idea why or any help at all that'd be awesome! :)

@detobel36
Copy link

@ConnorLinfoot The new update of TerrainControl could remove ocean but it's to big... I don't find the code who remove ocean 😞
@Thog Do you have find a solution ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment