package game.init; import static java.lang.annotation.ElementType.FIELD; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.util.Map; import java.util.TreeMap; import game.Server; import game.packet.SPacketWorld; import game.util.ExtMath; import game.world.World; import game.world.WorldServer; public abstract class Config { public static enum ValueType { STRING, BOOLEAN, INTEGER, FLOAT; } private static interface Callback { void run(Server server); } @Target(FIELD) @Retention(value = RetentionPolicy.RUNTIME) private static @interface Var { String name(); Class callback() default Callback.class; float min() default (float)Integer.MIN_VALUE; float max() default (float)Integer.MAX_VALUE; } public static class Value { public final ValueType type; public final String def; private final Field field; private final float min; private final float max; private final Callback callback; private Value(Field field, Var value) { this.type = field.getType() == int.class ? ValueType.INTEGER : (field.getType() == boolean.class ? ValueType.BOOLEAN : (field.getType() == String.class ? ValueType.STRING : (field.getType() == float.class ? ValueType.FLOAT : null))); if(this.type == null) throw new IllegalArgumentException(value.name() + ": Unbekannter Variablen-Typ - " + field.getType()); this.field = field; this.def = this.getValue(); // Clamped clamp = this.field.getAnnotation(Clamped.class); this.min = (this.type == ValueType.INTEGER || this.type == ValueType.FLOAT) ? value.min() : 0; this.max = (this.type == ValueType.INTEGER || this.type == ValueType.FLOAT) ? value.max() : (this.type == ValueType.BOOLEAN ? 1 : 0); // Update update = this.field.getAnnotation(Update.class); if(value.callback() == Callback.class) { this.callback = null; } else { try { this.callback = value.callback().getConstructor().newInstance(); } catch(InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException e) { throw new RuntimeException(e); } } this.setValue(this.def); } public String getValue() { try { return "" + this.field.get(null); // switch(this.type) { // case STRING: // default: // return (String)this.field.get(null); // case BOOLEAN: // return "" + this.field.getBoolean(null); // case INTEGER: // return "" + this.field.getInt(null); // case FLOAT: // return "" + this.field.getFloat(null); // } } catch(IllegalArgumentException | IllegalAccessException e) { throw new RuntimeException(e); } } private void setValue(String value) { try { switch(this.type) { case STRING: this.field.set(null, value); break; case BOOLEAN: this.field.setBoolean(null, Boolean.parseBoolean(value)); break; case INTEGER: int inum = 0; try { inum = Integer.parseInt(value); } catch(NumberFormatException e) { } this.field.setInt(null, ExtMath.clampi(inum, (int)this.min, (int)this.max)); break; case FLOAT: float fnum = 0.0f; try { fnum = Float.parseFloat(value); } catch(NumberFormatException e) { } fnum = ExtMath.clampf(fnum, this.min, this.max); int round = (int)(fnum * 1000.0f); this.field.setFloat(null, (float)round / 1000.0f); break; } } catch(IllegalArgumentException | IllegalAccessException e) { throw new RuntimeException(e); } } } public static final int PROTOCOL = 666; public static final int PORT = 26666; public static final String VERSION = "v2.2.1-alpha"; public static final Map VARS = new TreeMap(); @Var(name = "fireTick") public static boolean fire = true; @Var(name = "mobGriefing") public static boolean mobGrief = true; @Var(name = "mobSpawning") public static boolean mobs = true; @Var(name = "tickSpawning") public static boolean tickSpawn = true; @Var(name = "genSpawning") public static boolean genSpawn = true; @Var(name = "spawners") public static boolean spawners = true; @Var(name = "spawnVillagers") public static boolean spawnVillager = true; @Var(name = "spawnCagedVillagers") public static boolean spawnCagedVillager = true; @Var(name = "spawnHutMages") public static boolean spawnHutMage = true; @Var(name = "spawnEggChickens") public static boolean spawnEggChicken = true; @Var(name = "spawnMoreZombies") public static boolean spawnMoreZombie = true; @Var(name = "spawnSplitSlimes") public static boolean spawnSplitSlime = true; @Var(name = "chargeHaunter") public static boolean chargeHaunter = true; @Var(name = "convertVillageZombie") public static boolean convertZombie = true; @Var(name = "dropLoot") public static boolean dropLoot = true; @Var(name = "dropBlockXP") public static boolean blockXP = true; @Var(name = "dropBreedingXP") public static boolean breedingXP = true; @Var(name = "dropSmeltingXP") public static boolean smeltingXP = true; @Var(name = "dropFishingXP") public static boolean fishingXP = true; @Var(name = "dropMobXP") public static boolean mobXP = true; @Var(name = "dropBlocks") public static boolean blockDrop = true; @Var(name = "dropObjects") public static boolean objectDrop = true; @Var(name = "naturalRegeneration") public static boolean regeneration = true; @Var(name = "daylightCycle", callback = WorldCallback.class) public static boolean dayCycle = true; @Var(name = "weatherChanges") public static boolean weather = true; @Var(name = "seasonLeafUpdate") public static boolean seasonLeaves = true; @Var(name = "leavesDecay") public static boolean leavesDecay = true; @Var(name = "repairExperience") public static boolean repairXP = true; @Var(name = "mobTick") public static boolean mobTick = true; @Var(name = "mobAttacks") public static boolean mobAttacks = true; @Var(name = "portals") public static boolean portals = true; @Var(name = "portalVoid") public static boolean voidPortal = true; @Var(name = "dropPlayerSkulls") public static boolean skullDrop = true; @Var(name = "dropPlayerItems") public static boolean playerDrop = true; @Var(name = "blockGravity") public static boolean blockGravity = true; @Var(name = "liquidPhysics") public static boolean liquidPhysics = true; @Var(name = "lavaFire") public static boolean lavaFire = true; @Var(name = "mergeWater") public static boolean mergeWater = true; @Var(name = "mergeInfinite") public static boolean mergeInfinite = true; @Var(name = "infighting") public static boolean infight = true; // @Var(name = "infightSameType") // public static boolean infightSame = true; @Var(name = "damageFall") public static boolean damageFall = true; @Var(name = "damageFire") public static boolean damageFire = true; @Var(name = "damageLava") public static boolean damageLava = true; @Var(name = "damageMolten") public static boolean damageMolten = true; @Var(name = "damageLightning") public static boolean damageLightning = true; @Var(name = "damageSquish") public static boolean damageSquish = true; @Var(name = "damageAcme") public static boolean damageAcme = true; @Var(name = "damageRadiation") public static boolean damageRadiation = true; @Var(name = "damagePoison") public static boolean damagePoison = true; @Var(name = "damagePotion") public static boolean damagePotion = true; @Var(name = "damageFlyingBox") public static boolean damageFlyingBox = true; @Var(name = "damageVoid") public static boolean damageVoid = true; @Var(name = "damageThorns") public static boolean damageThorns = true; @Var(name = "damageFireball") public static boolean damageFireball = true; @Var(name = "damageArrow") public static boolean damageArrow = true; @Var(name = "damageBullet") public static boolean damageBullet = true; @Var(name = "damageMobs") public static boolean damageMobs = true; @Var(name = "damageExplosion") public static boolean damageExplosion = true; @Var(name = "damageWall") public static boolean damageWall = true; @Var(name = "radiation") public static boolean radiation = true; @Var(name = "anvilFallDecay") public static boolean anvilFallDecay = true; @Var(name = "anvilRepairDecay") public static boolean anvilRepairDecay = true; @Var(name = "attacking") public static boolean attack = true; @Var(name = "cactusPrickly") public static boolean cactusDamage = true; @Var(name = "waterMobDrying") public static boolean waterMobDry = true; @Var(name = "itemBurning") public static boolean itemBurn = true; @Var(name = "xpOrbBurning") public static boolean xpOrbBurn = true; @Var(name = "smackingOrb") public static boolean knockOrb = true; @Var(name = "smackingDynamite") public static boolean knockDynamite = true; @Var(name = "smackingEgg") public static boolean knockEgg = true; @Var(name = "smackingSnowball") public static boolean knockSnowball = true; @Var(name = "smackingFishHook") public static boolean knockHook = true; @Var(name = "entityFishing") public static boolean hookEntity = true; @Var(name = "hookingRequiresDamage") public static boolean hookCheckDamage = true; @Var(name = "grassSpread") public static boolean grassSpread = true; @Var(name = "grassDecay") public static boolean grassDecay = true; @Var(name = "grassDrying") public static boolean grassDry = true; @Var(name = "tallgrassDrying") public static boolean tallgrassDry = true; @Var(name = "flowerDrying") public static boolean flowerDry = true; @Var(name = "plantDrying") public static boolean plantDry = true; @Var(name = "leafDrying") public static boolean leafDry = true; @Var(name = "saplingDrying") public static boolean saplingDry = true; @Var(name = "reedDrying") public static boolean reedDry = true; @Var(name = "vineDrying") public static boolean vineDry = true; @Var(name = "myceliumSpread") public static boolean mycelSpread = true; @Var(name = "myceliumDecay") public static boolean mycelDecay = true; @Var(name = "farmlandDecay") public static boolean cropDecay = true; @Var(name = "farmlandDrying") public static boolean cropDrying = true; @Var(name = "farmlandSoaking") public static boolean cropSoaking = true; @Var(name = "farmlandTrampling") public static boolean cropTrampling = true; @Var(name = "iceMelting") public static boolean iceMelt = true; @Var(name = "snowMelting") public static boolean snowMelt = true; @Var(name = "snowBlockMelting") public static boolean snowFullMelt = true; @Var(name = "chestLocking") public static boolean locking = true; @Var(name = "teleFragging") public static boolean telefrag = true; @Var(name = "checkRespawn") public static boolean checkBed = true; @Var(name = "chunkLoaders") public static boolean loaders = true; @Var(name = "fragileItems") public static boolean itemFallDamage = true; @Var(name = "registration") public static boolean register = true; @Var(name = "preload_chunks_local") public static boolean preloadLocal = true; @Var(name = "keepInventory") public static boolean keepInventory = false; @Var(name = "cleanCut") public static boolean cleanCut = false; @Var(name = "mergeLava") public static boolean mergeLava = false; @Var(name = "mergeFinite") public static boolean mergeFinite = false; @Var(name = "veryHungryRabbits") public static boolean rabidRabbits = false; @Var(name = "snowStacking") public static boolean snowStack = false; @Var(name = "authentication") public static boolean auth = false; @Var(name = "teleportForAll") public static boolean teleportAllowed = false; @Var(name = "preload_chunks_all") // Vorsicht Lag!! public static boolean preloadAll = false; // @Var(name = "maxPolygonalPoints") // public static int polygonalPoints = -1; // @Var(name = "maxPolyhedronPoints") // public static int polyhedronPoints = -1; // @Var(name = "maxEditRadius") // public static int editRadius = -1; // @Var(name = "maxBrushRadius") // public static int brushRadius = 500; // @Var(name = "historySize") // public static int history = 300; @Var(name = "randomTickSpeed") public static int randomTick = 3; @Var(name = "weatherTickSpeed") public static int weatherTick = 1; @Var(name = "lightningChance") public static int boltChance = 100000; @Var(name = "igniteChance") public static int igniteChance = 100; @Var(name = "spawnRadius") public static int spawnRadius = 10; @Var(name = "respawnTime") public static int respawnTime = 0; @Var(name = "hurtCooldown") public static int hurtDelay = 20; @Var(name = "attackCooldown") public static int attackDelay = 0; @Var(name = "spawnGroupCount") public static int spawnGroups = 3; @Var(name = "spawnGroupDistance") public static int spawnGroupDist = 6; @Var(name = "mobSpawnRadius") public static int mobSpawnDist = 8; @Var(name = "mobPlayerDistance") public static int mobPlayerDist = 24; @Var(name = "saveInterval") public static int saveInterval = 900; @Var(name = "maxPlayers") public static int playerLimit = 0; @Var(name = "compressAbove") public static int compression = 256; @Var(name = "pistonPushLimit") public static int pistonLimit = 16; @Var(name = "gravelFlintChance") public static int flintChance = 10; @Var(name = "timeFlow", callback = WorldCallback.class) public static int timeFlow = 1; @Var(name = "emptyTicks") public static int unloadTicks = 1200; @Var(name = "rabbitMateChance") public static int rabbitMateChance = 10; @Var(name = "killerBunnyChance") public static int killerBunnyChance = 1000; @Var(name = "fallPortalHeight") public static int portalHeight = 256; @Var(name = "damageOrb") public static int orbDamageSelf = 5; @Var(name = "vineGrowthChance") public static int vineGrowth = 4; @Var(name = "blueShroomChance") public static int blueShroomGrowth = 25; @Var(name = "mushroomChance") public static int shroomGrowth = 25; @Var(name = "cropGrowthChance") public static int cropGrowth = 26; @Var(name = "stemGrowthChance") public static int stemGrowth = 26; @Var(name = "treeGrowthChance") public static int treeGrowth = 7; @Var(name = "wartGrowthChance") public static int wartGrowth = 10; @Var(name = "cocoaGrowthChance") public static int cocoaGrowth = 5; @Var(name = "reedGrowthHeight") public static int reedHeight = 3; @Var(name = "cactusGrowthHeight") public static int cactusHeight = 3; @Var(name = "orbThorns") public static int orbDamageOther = 0; @Var(name = "weatherChance") public static int weatherChance = 48000; @Var(name = "viewDistance", min = 2, max = 128, callback = DistanceCallback.class) public static int distance = 10; @Var(name = "healChance") public static int healChance = 5; @Var(name = "hopperCooldown", min = 0, max = 160) public static int hopperDelay = 2; @Var(name = "hopperCartCooldown", min = 0, max = 160) public static int hopperCartDelay = 1; @Var(name = "xpCooldown", min = 0, max = 10) public static int xpDelay = 0; // 2 @Var(name = "maxSpawns") public static int maxMobs = 120; @Var(name = "eggLayTime") public static int eggTimer = 6000; @Var(name = "spawnX", min = -World.MAX_SIZE + 1, max = World.MAX_SIZE - 1) public static int spawnX = 0; @Var(name = "spawnY", min = -1, max = 511) public static int spawnY = 64; @Var(name = "spawnZ", min = -World.MAX_SIZE + 1, max = World.MAX_SIZE - 1) public static int spawnZ = 0; @Var(name = "spawnDim") public static int spawnDim = 0; @Var(name = "gravity", callback = WorldCallback.class) public static float gravity = 1.0f; @Var(name = "knockback") public static float knockback = 1.0f; @Var(name = "spawnYaw", min = -180.0f, max = 180.0f) public static float spawnYaw = -90.0f; @Var(name = "spawnPitch", min = -89.0f, max = 89.0f) public static float spawnPitch = 0.0f; @Var(name = "password") public static String password = ""; static { for(Field field : Config.class.getDeclaredFields()) { if(field.isAnnotationPresent(Var.class)) { if(!Modifier.isStatic(field.getModifiers()) || Modifier.isFinal(field.getModifiers())) throw new IllegalArgumentException("Feld für Variable " + field + " muss statisch und änderbar sein!"); Var value = field.getAnnotation(Var.class); if(value.name().isEmpty()) throw new IllegalArgumentException("Variablenname von " + field + " kann nicht leer sein!"); if(VARS.containsKey(value.name())) throw new IllegalArgumentException("Variable " + value.name() + " existiert bereits!"); VARS.put(value.name(), new Config.Value(field, value)); } } } public static void clear() { for(Config.Value value : VARS.values()) { value.setValue(value.def); } } public static void set(String key, String value, Server server) { Config.Value vl = VARS.get(key); if(vl != null) { vl.setValue(value); if(server != null && vl.callback != null) vl.callback.run(server); } } public static class WorldCallback implements Callback { public void run(Server server) { for(WorldServer world : server.getWorlds()) { world.updatePhysics(); } server.sendPacket(new SPacketWorld(WorldServer.clampGravity(), Config.dayCycle, Config.timeFlow)); } } public static class DistanceCallback implements Callback { public void run(Server server) { for(WorldServer world : server.getWorlds()) { world.updateViewRadius(); } } } }