/** * Changes a village to a sandstone village. (Just sets the first * boolean it can find in the WorldGenVillageStartPiece.class to * sandstoneVillage.) * * @param subject The village. * @param sandstoneVillage Whether the village should be a sandstone * village. */ private void changeToSandstoneVillage(WorldGenVillageStartPiece subject, boolean sandstoneVillage) { ReflectionHelper.setValueInFieldOfType(subject, boolean.class, sandstoneVillage); }
/** * Sets the field on the given object of the given field type to the given * value. For example, {@code setValueInFieldOfType(structure, * boolean.class, true)} will set the boolean of the structure object to * true. * * @param on The object to change a field on. * @param fieldType The type of the field that must be changed. * @param newValue The value to set the field to. * @throws NoSuchFieldError When no field of that type exists, or when two * or more fields of that type exist. */ public static <T> void setValueInFieldOfType(Object on, Class<? super T> fieldType, T newValue) { Field field = getOnlyFieldDefOfType(on.getClass(), fieldType); try { field.setAccessible(true); field.set(on, newValue); } catch (IllegalAccessException e) { // Cannot happen, we just made the field accessible throw new AssertionError(e); } }
/** * Dog has two fields of type String. We can't known which one should be * retrieved. */ @Test(expected = NoSuchFieldError.class) public void testAmbiguousGet() { Dog dog = new Dog(); ReflectionHelper.getValueInFieldOfType(dog, String.class); }
/** * Simplest use case: retrieve a field stored in the class itself. */ @Test public void testGet() { Monkey monkey = new Monkey(); String name = ReflectionHelper.getValueInFieldOfType(monkey, String.class); assertEquals(monkey.name, name); }
private void injectInternalChunkGenerator(CustomChunkGenerator chunkGenerator) { ChunkProviderServer chunkProvider = this.world.getChunkProviderServer(); ChunkGenerator oldChunkGenerator = chunkProvider.chunkGenerator; if (oldChunkGenerator instanceof CustomChunkGenerator) { ReflectionHelper.setValueInFieldOfType(chunkProvider, ChunkGenerator.class, chunkGenerator); } }
/** * Monkey has two fields of type boolean. In {@link #testAmbiguousGet()}, * this was a problem. However, in this case one of the booleans in stored * in the parent class, so it is clear which field should be retrieved. */ @Test public void testActuallyNotAmbiguousGet() { Monkey monkey = new Monkey(); boolean isClimbing = ReflectionHelper.getValueInFieldOfType(monkey, boolean.class); assertEquals(monkey.isClimbing, isClimbing); }
/** * Gets the value of the field in the class with the given type. * * @param on The object to retrieve a value from. * @param fieldType The field type. * @param <T> The same field type. * @return The value. * @throws NoSuchFieldError When no field of the given type exists in the * class, or when two or more field of that type * exist. */ public static <T> T getValueInFieldOfType(Object on, Class<T> fieldType) { Field field = getOnlyFieldDefOfType(on.getClass(), fieldType); try { field.setAccessible(true); // We can't use fieldType.cast(...) instead of an unchecked cast to // T: the cast method does not work for primitive types (i.e. // int.class), as field.get always returns a boxed type @SuppressWarnings("unchecked") T fieldValue = (T) field.get(on); return fieldValue; } catch (IllegalAccessException e) { // Cannot happen, we just made the field accessible throw new AssertionError(e); } }
public TXStrongholdGen(ServerConfigProvider configs) { super(ImmutableMap.of( "distance", String.valueOf(configs.getWorldConfig().strongholdDistance), "count", String.valueOf(configs.getWorldConfig().strongholdCount), "spread", String.valueOf(configs.getWorldConfig().strongholdSpread))); // Modify in which biomes the stronghold is allowed to spawn List<BiomeBase> allowedBiomes = Lists.newArrayList(); for (LocalBiome biome : configs.getBiomeArray()) { if (biome == null) continue; if (biome.getBiomeConfig().strongholdsEnabled) { allowedBiomes.add(((BukkitBiome) biome).getHandle()); } } ReflectionHelper.setValueInFieldOfType(this, List.class, allowedBiomes); }
/** * Tests whether the list (stored in a parent class) is found. */ @Test public void testGetInParent() { Monkey monkey = new Monkey(); List<?> friends = ReflectionHelper.getValueInFieldOfType(monkey, List.class); assertEquals(monkey.friends, friends); }
private void injectWorldChunkManager(BiomeGenerator biomeGenerator) { if (biomeGenerator instanceof BukkitVanillaBiomeGenerator) { // Let our biome generator depend on Minecraft's ((BukkitVanillaBiomeGenerator) biomeGenerator).setWorldChunkManager(this.world.worldProvider.k()); } else { // Let Minecraft's biome generator depend on ours ReflectionHelper.setValueInFieldOfType(this.world.worldProvider, WorldChunkManager.class, new TXWorldChunkManager(this, biomeGenerator)); } }
/** * Gets the appropriate BiomeGenerator. For the vanilla biome generator we * have to use BiomeGenerator, for other biome modes TCBiomeProvider is * the right option. * * @param tcWorld ForgeWorld instance, needed to instantiate the * BiomeGenerator. * @param biomeGenerator Biome generator. * @return The most appropriate BiomeGenerator. */ private BiomeProvider createBiomeProvider(ForgeWorld tcWorld, BiomeGenerator biomeGenerator) { final World world = tcWorld.getWorld(); BiomeProvider biomeProvider; if (biomeGenerator instanceof ForgeVanillaBiomeGenerator) { biomeProvider = world.provider.getBiomeProvider(); // Let our biome generator depend on Minecraft's ((ForgeVanillaBiomeGenerator) biomeGenerator).setBiomeProvider(biomeProvider); } else { biomeProvider = new TXBiomeProvider(tcWorld, biomeGenerator); // Let Minecraft's biome generator depend on ours ReflectionHelper.setValueInFieldOfType(world.provider, BiomeProvider.class, biomeProvider); } return biomeProvider; }
/** * Simple use case: change a field. The same (somewhat problematic) field as * in {@link #testActuallyNotAmbiguousGet()} is used. */ @Test public void testSet() { Monkey monkey = new Monkey(); // First change field the normal way monkey.isClimbing = false; assertEquals(false, monkey.isClimbing); // Then set it back using reflection ReflectionHelper.setValueInFieldOfType(monkey, boolean.class, true); assertEquals(true, monkey.isClimbing); } }