add gradle

This commit is contained in:
Sen 2025-05-26 17:09:08 +02:00
parent bb6ebb0be8
commit 4e51e18bdc
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
3033 changed files with 470 additions and 0 deletions

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,22 @@
package server.biome;
import common.biome.Biome;
import common.init.Blocks;
import common.rng.WeightedList;
public class BiomeBeach extends GenBiome
{
public BiomeBeach(boolean cold)
{
super(cold ? Biome.COLDBEACH : Biome.BEACH);
this.topBlock = Blocks.sand.getState();
this.fillerBlock = Blocks.sand.getState();
this.treesPerChunk = -999;
this.deadBushPerChunk = 0;
this.reedsPerChunk = 0;
this.cactiPerChunk = 0;
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
}
}

View file

@ -0,0 +1,35 @@
package server.biome;
import common.biome.Biome;
import common.block.foliage.BlockFlower;
import common.entity.npc.EntityMetalhead;
import common.init.Blocks;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.worldgen.tree.WorldGenBaseTree;
import server.worldgen.tree.WorldGenTree;
public class BiomeBlackened extends GenBiome {
protected final WorldGenTree treeGen = new WorldGenBaseTree(false, Blocks.blackwood_log.getState(), Blocks.blackwood_leaves.getState());
public BiomeBlackened() {
super(Biome.BLACKENED);
this.topBlock = Blocks.blackened_soil.getState();
this.fillerBlock = Blocks.blackened_dirt.getState();
this.treesPerChunk = 3;
this.generateLakes = false;
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
mobs.add(new RngSpawn(EntityMetalhead.class, 50, 1, 1));
}
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos) {
return BlockFlower.EnumFlowerType.BLACK_LOTUS;
}
public WorldGenTree genBigTreeChance(Random rand) {
return this.treeGen;
}
}

View file

@ -0,0 +1,45 @@
package server.biome;
import common.biome.Biome;
import common.entity.Entity;
import common.entity.types.EntityLiving;
import common.init.Blocks;
import common.init.EntityRegistry;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.FeatureGenerator;
import server.worldgen.foliage.WorldGenMushroom;
public class BiomeChaos extends GenBiome
{
protected FeatureGenerator mushroomBlueGen = new WorldGenMushroom(Blocks.blue_mushroom);
public BiomeChaos()
{
super(Biome.CHAOS);
this.topBlock = Blocks.obsidian.getState();
this.fillerBlock = Blocks.obsidian.getState();
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
for(Class<? extends Entity> clazz : EntityRegistry.getAllClasses()) {
if(EntityLiving.class.isAssignableFrom(clazz))
mobs.add(new RngSpawn((Class<? extends EntityLiving>)clazz, 1, 1, 8));
}
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
if (rand.chance(10))
{
int i8 = rand.chOffset();
int l11 = rand.chOffset();
BlockPos blockpos2 = worldIn.getHeight(pos.add(i8, 0, l11));
this.mushroomBlueGen.generate(worldIn, rand, blockpos2);
}
}
}

View file

@ -0,0 +1,40 @@
package server.biome;
import common.biome.Biome;
import common.init.Blocks;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.feature.WorldGenDesertWells;
public class BiomeDesert extends GenBiome
{
public BiomeDesert(boolean hills)
{
super(hills ? Biome.DESERTHILLS : Biome.DESERT);
this.topBlock = Blocks.sand.getState();
this.fillerBlock = Blocks.sand.getState();
this.treesPerChunk = -999;
this.deadBushPerChunk = 2;
this.reedsPerChunk = 50;
this.cactiPerChunk = 10;
this.generateLakes = false;
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
if (rand.chance(1000))
{
int i = rand.chOffset();
int j = rand.chOffset();
BlockPos blockpos = worldIn.getHeight(pos.add(i, 0, j)).up();
(new WorldGenDesertWells()).generate(worldIn, rand, blockpos);
}
}
}

View file

@ -0,0 +1,22 @@
package server.biome;
import common.biome.Biome;
import common.init.Blocks;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.world.WorldServer;
public class BiomeExterminated extends GenBiome {
public BiomeExterminated() {
super(Biome.EXTERMINATED);
this.topBlock = Blocks.air.getState();
this.fillerBlock = Blocks.air.getState();
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos) {
}
}

View file

@ -0,0 +1,223 @@
package server.biome;
import common.biome.Biome;
import common.block.foliage.BlockDoublePlant;
import common.block.foliage.BlockFlower;
import common.entity.animal.EntityWolf;
import common.entity.npc.EntityElf;
import common.entity.npc.EntityWoodElf;
import common.init.Blocks;
import common.rng.Random;
import common.util.BlockPos;
import common.util.ExtMath;
import server.world.WorldServer;
import server.worldgen.foliage.WorldGenBigMushroom;
import server.worldgen.tree.WorldGenBaseTree;
import server.worldgen.tree.WorldGenBigTree;
import server.worldgen.tree.WorldGenBirch;
import server.worldgen.tree.WorldGenDarkOak;
import server.worldgen.tree.WorldGenTree;
public class BiomeForest extends GenBiome
{
private static final BlockDoublePlant.EnumPlantType[] FLOWER_TYPES = new BlockDoublePlant.EnumPlantType[] {
BlockDoublePlant.EnumPlantType.SYRINGA, BlockDoublePlant.EnumPlantType.ROSE, BlockDoublePlant.EnumPlantType.PAEONIA
};
protected static final WorldGenBirch tallBirch = new WorldGenBirch(false, true);
protected static final WorldGenBirch normalBirch = new WorldGenBirch(false, false);
protected static final WorldGenDarkOak darkOak = new WorldGenDarkOak(false);
private final int subType;
// protected LeavesType leavesType = null;
// protected WorldGenBaseTree cherry;
// protected WorldGenBaseTree maple;
// protected WorldGenBigTree cherryBig;
// protected WorldGenBigTree mapleBig;
protected WorldGenBaseTree cherry = new WorldGenBaseTree(false, Blocks.cherry_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
Blocks.cherry_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
protected WorldGenBaseTree maple = new WorldGenBaseTree(false, Blocks.maple_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
Blocks.maple_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
protected WorldGenBigTree cherryBig = new WorldGenBigTree(false, Blocks.cherry_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
Blocks.cherry_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
protected WorldGenBigTree mapleBig = new WorldGenBigTree(false, Blocks.maple_log.getState(), // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
Blocks.maple_leaves.getState()); // .withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
public BiomeForest(Biome base, int type)
{
super(base);
this.subType = type;
this.treesPerChunk = 10;
this.grassPerChunk = 2;
if (this.subType == 1)
{
this.treesPerChunk = 6;
this.flowersPerChunk = 100;
this.grassPerChunk = 1;
}
if (this.subType == 4)
{
this.treesPerChunk = 20;
this.flowersPerChunk = 20;
this.grassPerChunk = 1;
this.reedsPerChunk = 50;
this.waterlilyPerChunk = 4;
}
if (this.subType == 0)
{
this.mobs.add(new RngSpawn(EntityWolf.class, 5, 4, 4));
}
if (this.subType == 3)
{
this.treesPerChunk = -999;
}
if(this.subType != 4) {
this.mobs.add(new RngSpawn(EntityWoodElf.class, 3, 2, 6));
}
else {
this.mobs.add(new RngSpawn(EntityWoodElf.class, 100, 4, 16));
this.mobs.add(new RngSpawn(EntityElf.class, 12, 4, 16));
}
}
public WorldGenTree genBigTreeChance(Random rand)
{
return (WorldGenTree)
(this.subType == 3 && rand.rarity(3) ? darkOak :
(this.subType != 2 && rand.rarity(5) ? (this.subType != 3 && this.subType != 4 && rand.chance(this.subType == 1 ? 2 : 30) ? (rand.chance(25) ? this.cherryBig : this.cherry) :
this.subType == 4 && rand.chance(42) ? this.worldGeneratorBigTree : this.worldGeneratorTrees) :
(this.subType == 4 || rand.chance(this.subType == 2 ? 30 : 2) ? (rand.chance(this.subType == 4 ? 32 : 5) ? this.mapleBig : this.maple) : normalBirch)));
}
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
{
if (this.subType == 1)
{
double d0 = ExtMath.clampd((1.0D + GRASS_NOISE.generate((double)pos.getX() / 48.0D, (double)pos.getZ() / 48.0D)) / 2.0D, 0.0D, 0.9999D);
BlockFlower.EnumFlowerType blockflower$enumflowertype = BlockFlower.EnumFlowerType.values()[(int)(d0 * (double)BlockFlower.EnumFlowerType.values().length)];
return blockflower$enumflowertype == BlockFlower.EnumFlowerType.BLUE_ORCHID ? BlockFlower.EnumFlowerType.ROSE : blockflower$enumflowertype;
}
else if (this.subType == 4)
{
double d0 = ExtMath.clampd((1.0D + GRASS_NOISE.generate((double)pos.getX() / 48.0D, (double)pos.getZ() / 48.0D)) / 2.0D, 0.0D, 0.9999D);
return BlockFlower.EnumFlowerType.values()[(int)(d0 * (double)BlockFlower.EnumFlowerType.values().length)];
}
else
{
return super.pickRandomFlower(rand, pos);
}
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
// if(worldIn.getLeavesGen() != this.leavesType) {
// this.leavesType = worldIn.getLeavesGen();
// this.cherry = new WorldGenBaseTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
// Blocks.cherry_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
// this.maple = new WorldGenBaseTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
// Blocks.maple_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
// this.cherryBig = new WorldGenBigTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY),
// Blocks.cherry_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
// this.mapleBig = new WorldGenBigTree(false, Blocks.log2.getDefaultState().withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE),
// Blocks.maple_leaves.getDefaultState().withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen()));
// }
if (this.subType == 3)
{
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
int k = i * 4 + rand.range(9, 11);
int l = j * 4 + rand.range(9, 11);
BlockPos blockpos = worldIn.getHeight(pos.add(k, 0, l));
if (rand.chance(20))
{
WorldGenBigMushroom worldgenbigmushroom = new WorldGenBigMushroom();
worldgenbigmushroom.generate(worldIn, rand, blockpos);
}
else
{
WorldGenTree worldgenabstracttree = this.genBigTreeChance(rand);
worldgenabstracttree.prepare();
if (worldgenabstracttree.generate(worldIn, rand, blockpos))
{
worldgenabstracttree.finish(worldIn, rand, blockpos);
}
}
}
}
}
int j1 = rand.range(-3, 1);
if (this.subType == 1)
{
j1 += 2;
}
for (int k1 = 0; k1 < j1; ++k1)
{
// int l1 = rand.nextInt(3);
// if (l1 == 0)
// {
DOUBLE_PLANT_GEN.setPlantType(rand.pick(FLOWER_TYPES));
// }
// else if (l1 == 1)
// {
// DOUBLE_PLANT_GENERATOR.setPlantType();
// }
// else if (l1 == 2)
// {
// DOUBLE_PLANT_GENERATOR.setPlantType();
// }
for (int i2 = 0; i2 < 5; ++i2)
{
int j2 = rand.chOffset();
int k2 = rand.chOffset();
int i1 = rand.zrange(worldIn.getHeight(pos.add(j2, 0, k2)).getY() + 32);
if (DOUBLE_PLANT_GEN.generate(worldIn, rand, new BlockPos(pos.getX() + j2, i1, pos.getZ() + k2)))
{
break;
}
}
}
super.decorate(worldIn, rand, pos);
}
protected GenBiome createMutatedBiome(Biome base)
{
if (this.base == Biome.FOREST)
{
BiomeForest biomegenforest = new BiomeForest(base, 1);
biomegenforest.setScaling(this.depth, this.scale + 0.2F);
return biomegenforest;
}
else
{
return this.base != Biome.BIRCHFOREST && this.base != Biome.BIRCHFORESTHILLS ? new BiomeMutated(base, this)
{
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
this.baseBiome.decorate(worldIn, rand, pos);
}
}: new BiomeMutated(base, this)
{
public WorldGenTree genBigTreeChance(Random rand)
{
return rand.chance() ? BiomeForest.tallBirch : BiomeForest.normalBirch;
}
};
}
}
}

View file

@ -0,0 +1,129 @@
package server.biome;
import common.biome.Biome;
import common.entity.npc.EntityBloodElf;
import common.entity.npc.EntityCultivator;
import common.entity.npc.EntityFireDemon;
import common.entity.npc.EntityMagma;
import common.entity.npc.EntityMetalhead;
import common.entity.npc.EntityTiefling;
import common.init.Blocks;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.FeatureOres;
import server.worldgen.feature.WorldGenFire;
import server.worldgen.feature.WorldGenGlowStone;
import server.worldgen.feature.WorldGenHellLava;
import server.worldgen.foliage.WorldGenMushroom;
public class BiomeHell extends GenBiome
{
private final int subtype;
private final WorldGenFire fireGen;
private final WorldGenGlowStone glowStoneGen1;
private final WorldGenGlowStone glowStoneGen2;
private final FeatureOres quartzGen;
private final WorldGenHellLava lavaGen1;
private final WorldGenHellLava lavaGen2;
private final WorldGenMushroom brownMushroomGen;
private final WorldGenMushroom redMushroomGen;
public BiomeHell(Biome base, int subtype)
{
super(base);
this.subtype = subtype;
if(this.subtype == 0) {
this.mobs.add(new RngSpawn(EntityBloodElf.class, 10, 1, 2));
this.mobs.add(new RngSpawn(EntityMetalhead.class, 1, 1, 1));
this.fireGen = new WorldGenFire();
this.glowStoneGen1 = new WorldGenGlowStone();
this.glowStoneGen2 = new WorldGenGlowStone();
this.quartzGen = new FeatureOres(Blocks.quartz_ore.getState(), 16, 0, 14, 10, 118, false);
this.lavaGen1 = new WorldGenHellLava(Blocks.flowing_lava, true);
this.lavaGen2 = new WorldGenHellLava(Blocks.flowing_lava, false);
this.brownMushroomGen = new WorldGenMushroom(Blocks.brown_mushroom);
this.redMushroomGen = new WorldGenMushroom(Blocks.red_mushroom);
}
else {
this.mobs.add(new RngSpawn(EntityBloodElf.class, 50, 2, 10));
this.mobs.add(new RngSpawn(EntityCultivator.class, 10, 1, 1));
this.fireGen = null;
this.glowStoneGen1 = null;
this.glowStoneGen2 = null;
this.quartzGen = null;
this.lavaGen1 = null;
this.lavaGen2 = null;
this.brownMushroomGen = null;
this.redMushroomGen = null;
}
if(this.subtype == 2) {
this.topBlock = Blocks.ash.getState();
this.fillerBlock = Blocks.rock.getState();
}
else {
this.topBlock = Blocks.hellrock.getState();
this.fillerBlock = Blocks.hellrock.getState();
}
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
mobs.add(new RngSpawn(EntityFireDemon.class, 50, 4, 4));
mobs.add(new RngSpawn(EntityTiefling.class, 100, 4, 4));
mobs.add(new RngSpawn(EntityMagma.class, 1, 4, 4));
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
if(this.subtype == 0) {
for (int i = 0; i < 8; ++i)
{
this.lavaGen2.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(120) + 4, rand.zrange(16) + 8));
}
for (int j = 0; j < rand.zrange(rand.zrange(10) + 1) + 1; ++j)
{
this.fireGen.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(120) + 4, rand.zrange(16) + 8));
}
for (int k = 0; k < rand.zrange(rand.zrange(10) + 1); ++k)
{
this.glowStoneGen1.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(120) + 4, rand.zrange(16) + 8));
}
for (int l = 0; l < 10; ++l)
{
this.glowStoneGen2.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(128), rand.zrange(16) + 8));
}
if (rand.chance())
{
this.brownMushroomGen.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(128), rand.zrange(16) + 8));
}
if (rand.chance())
{
this.redMushroomGen.generate(worldIn, rand, pos.add(rand.zrange(16) + 8, rand.zrange(128), rand.zrange(16) + 8));
}
// for (int i1 = 0; i1 < 16; ++i1)
// {
this.quartzGen.generate(worldIn, rand, pos); // .add(rand.nextInt(16), rand.nextInt(108) + 10, rand.nextInt(16)));
// }
for (int j1 = 0; j1 < 16; ++j1)
{
this.lavaGen1.generate(worldIn, rand, pos.add(rand.zrange(16), rand.zrange(108) + 10, rand.zrange(16)));
}
}
else {
super.decorate(worldIn, rand, pos);
}
}
// protected Decorator createBiomeDecorator()
// {
// return this.subtype == 0 ? new DecoratorHell() : super.createBiomeDecorator();
// }
}

View file

@ -0,0 +1,101 @@
package server.biome;
import common.biome.Biome;
import common.init.Blocks;
import common.rng.Random;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.ChunkPrimer;
import server.worldgen.FeatureOres;
import server.worldgen.tree.WorldGenTaiga2;
import server.worldgen.tree.WorldGenTree;
public class BiomeHills extends GenBiome
{
// private FeatureGenerator theWorldGenerator = new FeatureOres(Blocks.monster_egg.getDefaultState().withProperty(BlockSilverfish.VARIANT, BlockSilverfish.EnumType.STONE), false, 7, 9, 0, 64);
private FeatureOres theEmeraldGenerator = new FeatureOres(Blocks.emerald_ore.getState(), 3, 5, 1, 4, 32, false);
private WorldGenTaiga2 field_150634_aD = new WorldGenTaiga2(false);
private int field_150635_aE = 0;
private int field_150636_aF = 1;
private int field_150637_aG = 2;
private int field_150638_aH;
protected BiomeHills(Biome base, boolean large)
{
super(base);
this.field_150638_aH = this.field_150635_aE;
if (large)
{
this.treesPerChunk = 3;
this.field_150638_aH = this.field_150636_aF;
}
}
public WorldGenTree genBigTreeChance(Random rand)
{
return (WorldGenTree)(rand.rarity(3) ? this.field_150634_aD : super.genBigTreeChance(rand));
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
// int i = 3 + rand.nextInt(6);
//
// for (int j = 0; j < i; ++j)
// {
// int k = rand.nextInt(16);
// int l = rand.nextInt(28) + 4;
// int i1 = rand.nextInt(16);
// BlockPos blockpos = pos.add(k, l, i1);
//
// if (worldIn.getBlockState(blockpos).getBlock() == Blocks.stone)
// {
// worldIn.setBlockState(blockpos, Blocks.emerald_ore.getDefaultState(), 2);
// }
// }
this.theEmeraldGenerator.generate(worldIn, rand, pos);
// for (i = 0; i < 7; ++i)
// {
// int j1 = rand.nextInt(16);
// int k1 = rand.nextInt(64);
// int l1 = rand.nextInt(16);
// this.theWorldGenerator.generate(worldIn, rand, pos); // .add(j1, k1, l1));
// }
}
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
this.topBlock = Blocks.grass.getState();
this.fillerBlock = Blocks.dirt.getState();
if ((noiseVal < -1.0D || noiseVal > 2.0D) && this.field_150638_aH == this.field_150637_aG)
{
this.topBlock = Blocks.gravel.getState();
this.fillerBlock = Blocks.gravel.getState();
}
else if (noiseVal > 1.0D && this.field_150638_aH != this.field_150636_aF)
{
this.topBlock = Blocks.stone.getState();
this.fillerBlock = Blocks.stone.getState();
}
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
/**
* this creates a mutation specific to Hills biomes
*/
private BiomeHills mutateHills(GenBiome p_150633_1_)
{
this.field_150638_aH = this.field_150637_aG;
this.setScaling(p_150633_1_.depth, p_150633_1_.scale);
return this;
}
protected GenBiome createMutatedBiome(Biome base)
{
return (new BiomeHills(base, false)).mutateHills(this);
}
}

View file

@ -0,0 +1,84 @@
package server.biome;
import common.biome.Biome;
import common.block.foliage.BlockTallGrass;
import common.entity.animal.EntityChicken;
import common.entity.animal.EntityOcelot;
import common.init.Blocks;
import common.rng.Random;
import common.util.BlockPos;
import common.world.State;
import server.world.WorldServer;
import server.worldgen.FeatureGenerator;
import server.worldgen.foliage.WorldGenMelon;
import server.worldgen.foliage.WorldGenShrub;
import server.worldgen.foliage.WorldGenTallGrass;
import server.worldgen.foliage.WorldGenVines;
import server.worldgen.tree.WorldGenBaseTree;
import server.worldgen.tree.WorldGenJungle;
import server.worldgen.tree.WorldGenTree;
public class BiomeJungle extends GenBiome
{
private static final State LOG = Blocks.jungle_log.getState(); // .withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE);
private static final State LEAVES = Blocks.jungle_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
private static final State BUSH = Blocks.oak_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.OAK); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
private final boolean edge;
public BiomeJungle(Biome base, boolean edge)
{
super(base);
this.edge = edge;
if (edge)
{
this.treesPerChunk = 2;
}
else
{
this.treesPerChunk = 50;
}
this.grassPerChunk = 25;
this.flowersPerChunk = 4;
if (!edge)
{
this.mobs.add(new RngSpawn(EntityOcelot.class, 2, 1, 1));
}
this.mobs.add(new RngSpawn(EntityChicken.class, 10, 4, 4));
}
public WorldGenTree genBigTreeChance(Random rand)
{
return (WorldGenTree)(rand.chance(10) ? this.worldGeneratorBigTree : (rand.chance(2) ? new WorldGenShrub(LOG, BUSH) : (!this.edge && rand.chance(3) ? new WorldGenJungle(false, 10, 20, LOG, LEAVES) : new WorldGenBaseTree(false, rand.range(4, 10), LOG, LEAVES, true))));
}
/**
* Gets a WorldGen appropriate for this biome.
*/
public FeatureGenerator getRandomWorldGenForGrass(Random rand)
{
return rand.chance(4) ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
int i = rand.chOffset();
int j = rand.chOffset();
int k = rand.zrange(worldIn.getHeight(pos.add(i, 0, j)).getY() * 2);
(new WorldGenMelon()).generate(worldIn, rand, pos.add(i, k, j));
WorldGenVines worldgenvines = new WorldGenVines();
for (j = 0; j < 50; ++j)
{
k = rand.chOffset();
int l = 128;
int i1 = rand.chOffset();
worldgenvines.generate(worldIn, rand, pos.add(k, 128, i1));
}
}
}

View file

@ -0,0 +1,331 @@
package server.biome;
import java.util.Arrays;
import common.biome.Biome;
import common.block.Block;
import common.block.BlockColored;
import common.block.natural.BlockDirt;
import common.block.natural.BlockSand;
import common.color.DyeColor;
import common.init.Blocks;
import common.rng.PerlinGen;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import common.world.State;
import server.world.WorldServer;
import server.worldgen.ChunkPrimer;
import server.worldgen.tree.WorldGenTree;
public class BiomeMesa extends GenBiome
{
private final boolean bryce;
private final boolean soil;
private State[] layers;
private long layerSeed;
private PerlinGen baseBryceGen;
private PerlinGen highBryceGen;
private PerlinGen clayColorGen;
public BiomeMesa(Biome base, boolean bryce, boolean soil)
{
super(base);
this.bryce = bryce;
this.soil = soil;
// this.setDisableRain();
// this.setTemperatureLegacy(2.0F).setHumidity(0.0F);
// this.mobs.clear();
this.topBlock = Blocks.sand.getState().withProperty(BlockSand.VARIANT, BlockSand.EnumType.RED_SAND);
this.fillerBlock = Blocks.stained_hardened_clay.getState();
this.treesPerChunk = -999;
this.deadBushPerChunk = 20;
this.reedsPerChunk = 3;
this.cactiPerChunk = 5;
this.flowersPerChunk = 0;
// this.mobs.clear();
if (soil)
{
this.treesPerChunk = 5;
}
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
}
public WorldGenTree genBigTreeChance(Random rand)
{
return this.worldGeneratorTrees;
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
}
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
if (this.layers == null || this.layerSeed != worldIn.getSeed())
{
this.setupLayers(worldIn.getSeed());
}
if (this.baseBryceGen == null || this.highBryceGen == null || this.layerSeed != worldIn.getSeed())
{
Random random = new Random(this.layerSeed);
this.baseBryceGen = new PerlinGen(random, 4);
this.highBryceGen = new PerlinGen(random, 1);
}
this.layerSeed = worldIn.getSeed();
double d4 = 0.0D;
if (this.bryce)
{
int i = (x & -16) + (z & 15);
int j = (z & -16) + (x & 15);
double d0 = Math.min(Math.abs(noiseVal), this.baseBryceGen.generate((double)i * 0.25D, (double)j * 0.25D));
if (d0 > 0.0D)
{
double d1 = 0.001953125D;
double d2 = Math.abs(this.highBryceGen.generate((double)i * d1, (double)j * d1));
d4 = d0 * d0 * 2.5D;
double d3 = Math.ceil(d2 * 50.0D) + 14.0D;
if (d4 > d3)
{
d4 = d3;
}
d4 = d4 + 64.0D;
}
}
int j1 = x & 15;
int k1 = z & 15;
int l1 = worldIn.getSeaLevel();
State iblockstate = Blocks.stained_hardened_clay.getState();
State iblockstate3 = this.fillerBlock;
int k = (int)(noiseVal / 3.0D + 3.0D + rand.doublev() * 0.25D);
boolean flag = Math.cos(noiseVal / 3.0D * Math.PI) > 0.0D;
int l = -1;
boolean flag1 = false;
State worldState = worldIn.dimension.getFiller();
Block worldBlock = worldState.getBlock();
State worldAlt = worldIn.dimension.getAltFiller1();
State liquid = worldIn.getSurfaceLiquid();
// IBlockState bottom = worldIn.dimension.hasBedrock() ? Blocks.bedrock.getDefaultState() : Blocks.air.getDefaultState();
for (int i1 = chunkPrimerIn.height - 1; i1 >= 0; --i1)
{
if (chunkPrimerIn.get(k1, i1, j1).getBlock() == Blocks.air && i1 < (int)d4)
{
chunkPrimerIn.set(k1, i1, j1, worldState);
}
// if (i1 <= rand.zrange(5) && bedrock)
// {
// chunkPrimerIn.set(k1, i1, j1, bottom);
// }
// else
// {
State iblockstate1 = chunkPrimerIn.get(k1, i1, j1);
if (iblockstate1.getBlock() == Blocks.air)
{
l = -1;
}
else if (iblockstate1.getBlock() == worldBlock)
{
if (l == -1)
{
flag1 = false;
if (k <= 0)
{
iblockstate = null;
iblockstate3 = worldState;
}
else if (i1 >= l1 - 4 && i1 <= l1 + 1)
{
iblockstate = Blocks.stained_hardened_clay.getState();
iblockstate3 = this.fillerBlock;
}
if (i1 < l1 && (iblockstate == null || iblockstate.getBlock() == Blocks.air))
{
iblockstate = liquid;
}
l = k + Math.max(0, i1 - l1);
if (i1 < l1 - 1)
{
chunkPrimerIn.set(k1, i1, j1, iblockstate3);
if (iblockstate3.getBlock() == Blocks.stained_hardened_clay)
{
chunkPrimerIn.set(k1, i1, j1, iblockstate3.getBlock().getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE));
}
}
else if (this.soil && i1 > 86 + k * 2)
{
if (flag)
{
chunkPrimerIn.set(k1, i1, j1, Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT));
}
else
{
chunkPrimerIn.set(k1, i1, j1, Blocks.grass.getState());
}
}
else if (i1 <= l1 + 3 + k)
{
chunkPrimerIn.set(k1, i1, j1, this.topBlock);
flag1 = true;
}
else
{
State iblockstate4;
if (i1 >= 64 && i1 <= 127)
{
if (flag)
{
iblockstate4 = Blocks.hardened_clay.getState();
}
else
{
iblockstate4 = this.getBlockAt(x, i1, z);
}
}
else
{
iblockstate4 = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE);
}
chunkPrimerIn.set(k1, i1, j1, iblockstate4);
}
}
else if (l > 0)
{
--l;
if (flag1)
{
chunkPrimerIn.set(k1, i1, j1, Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE));
}
else
{
State iblockstate2 = this.getBlockAt(x, i1, z);
chunkPrimerIn.set(k1, i1, j1, iblockstate2);
}
}
}
}
// }
}
private void setupLayers(long seed)
{
this.layers = new State[64];
Arrays.fill(this.layers, Blocks.hardened_clay.getState());
Random random = new Random(seed);
this.clayColorGen = new PerlinGen(random, 1);
for (int l1 = 0; l1 < 64; ++l1)
{
l1 += random.roll(5);
if (l1 < 64)
{
this.layers[l1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE);
}
}
int i2 = random.range(2, 5);
for (int i = 0; i < i2; ++i)
{
int j = random.roll(3);
int k = random.zrange(64);
for (int l = 0; k + l < 64 && l < j; ++l)
{
this.layers[k + l] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.YELLOW);
}
}
int j2 = random.range(2, 5);
for (int k2 = 0; k2 < j2; ++k2)
{
int i3 = random.range(2, 4);
int l3 = random.zrange(64);
for (int i1 = 0; l3 + i1 < 64 && i1 < i3; ++i1)
{
this.layers[l3 + i1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.BROWN);
}
}
int l2 = random.range(2, 5);
for (int j3 = 0; j3 < l2; ++j3)
{
int i4 = random.roll(3);
int k4 = random.zrange(64);
for (int j1 = 0; k4 + j1 < 64 && j1 < i4; ++j1)
{
this.layers[k4 + j1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.RED);
}
}
int k3 = random.range(3, 5);
int j4 = 0;
for (int l4 = 0; l4 < k3; ++l4)
{
int i5 = 1;
j4 += random.range(4, 19);
for (int k1 = 0; j4 + k1 < 64 && k1 < i5; ++k1)
{
this.layers[j4 + k1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.WHITE);
if (j4 + k1 > 1 && random.chance())
{
this.layers[j4 + k1 - 1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.SILVER);
}
if (j4 + k1 < 63 && random.chance())
{
this.layers[j4 + k1 + 1] = Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.SILVER);
}
}
}
}
private State getBlockAt(int x, int y, int z)
{
int i = (int)Math.round(this.clayColorGen.generate((double)x * 1.0D / 512.0D, (double)x * 1.0D / 512.0D) * 2.0D);
return this.layers[(y + i + 64) % 64];
}
protected GenBiome createMutatedBiome(Biome base)
{
boolean bryce = this.base == Biome.MESA;
BiomeMesa mesa = new BiomeMesa(base, bryce, this.soil);
if (!bryce)
{
mesa.setScaling(Scaling.HILLS_LOW);
}
return mesa;
}
}

View file

@ -0,0 +1,26 @@
package server.biome;
import common.biome.Biome;
import common.init.Blocks;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.FeatureOres;
public class BiomeMoon extends GenBiome {
private FeatureOres cheeseGenerator = new FeatureOres(Blocks.moon_cheese.getState(), 8, 8, 12, 24, 52, false);
public BiomeMoon() {
super(Biome.MOON);
this.topBlock = Blocks.moon_rock.getState();
this.fillerBlock = Blocks.moon_rock.getState();
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos) {
this.cheeseGenerator.generate(worldIn, rand, pos);
}
}

View file

@ -0,0 +1,24 @@
package server.biome;
import common.biome.Biome;
import common.entity.animal.EntityMooshroom;
import common.init.Blocks;
import common.rng.WeightedList;
public class BiomeMushroom extends GenBiome
{
public BiomeMushroom()
{
super(Biome.MUSHROOMPLAINS);
this.treesPerChunk = -100;
this.flowersPerChunk = -100;
this.grassPerChunk = -100;
this.mushroomsPerChunk = 1;
this.bigMushroomsPerChunk = 1;
this.topBlock = Blocks.mycelium.getState();
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
mobs.add(new RngSpawn(EntityMooshroom.class, 8, 4, 8));
}
}

View file

@ -0,0 +1,83 @@
package server.biome;
import common.biome.Biome;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.ChunkPrimer;
import server.worldgen.tree.WorldGenTree;
public class BiomeMutated extends GenBiome
{
protected GenBiome baseBiome;
public BiomeMutated(Biome base, GenBiome biome)
{
super(base);
this.baseBiome = biome;
this.topBlock = biome.topBlock;
this.fillerBlock = biome.fillerBlock;
// this.minHeight = biome.minHeight;
// this.maxHeight = biome.maxHeight;
this.allowColdBeach = biome.allowColdBeach;
// this.enableRain = biome.enableRain;
// this.mobs.clear();
this.mobs.addAll(biome.mobs);
// this.mobs = new WeightedList(biome.mobs);
// this.monsters = new WeightedList(biome.monsters);
// this.caveMobs = new WeightedList(biome.caveMobs);
// this.waterMobs = new WeightedList(biome.waterMobs);
// this.npcs = new WeightedList(biome.npcs);
// this.temperature = biome.temperature;
// this.humidity = biome.humidity;
this.depth = biome.depth + 0.1F;
this.scale = biome.scale + 0.2F;
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
this.baseBiome.decorate(worldIn, rand, pos); // TODO: check
}
public void decorateNormal(WorldServer worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
}
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
this.baseBiome.genTerrainBlocks(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
public float getMobGenChance()
{
return this.baseBiome.getMobGenChance();
}
public WorldGenTree genBigTreeChance(Random rand)
{
return this.baseBiome.genBigTreeChance(rand);
}
public Class <? extends GenBiome > getBiomeClass()
{
return this.baseBiome.getBiomeClass();
}
/**
* returns true if the biome specified is equal to this biome
*/
public boolean isEqualTo(GenBiome biome)
{
return this.baseBiome.isEqualTo(biome);
}
public Temperature getTempCategory()
{
return this.baseBiome.getTempCategory();
}
}

View file

@ -0,0 +1,30 @@
package server.biome;
import common.biome.Biome;
import common.init.Blocks;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.ChunkPrimer;
public class BiomeNone extends GenBiome {
public BiomeNone() {
super(Biome.NONE);
this.topBlock = Blocks.air.getState();
this.fillerBlock = Blocks.air.getState();
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
}
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal) {
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos) {
}
public Temperature getTempCategory() {
return Temperature.SEA;
}
}

View file

@ -0,0 +1,120 @@
package server.biome;
import common.biome.Biome;
import common.block.foliage.BlockDoublePlant;
import common.block.foliage.BlockFlower;
import common.entity.animal.EntityHorse;
import common.rng.Random;
import common.util.BlockPos;
import server.world.WorldServer;
public class BiomePlains extends GenBiome
{
private static final BlockFlower.EnumFlowerType[] TULIP_TYPES = new BlockFlower.EnumFlowerType[] {
BlockFlower.EnumFlowerType.ORANGE_TULIP, BlockFlower.EnumFlowerType.RED_TULIP,
BlockFlower.EnumFlowerType.PINK_TULIP, BlockFlower.EnumFlowerType.WHITE_TULIP
};
private static final BlockFlower.EnumFlowerType[] FLOWER_TYPES = new BlockFlower.EnumFlowerType[] {
BlockFlower.EnumFlowerType.POPPY, BlockFlower.EnumFlowerType.HOUSTONIA, BlockFlower.EnumFlowerType.OXEYE_DAISY
};
// protected boolean field_150628_aC;
protected BiomePlains()
{
super(Biome.PLAINS);
this.setScaling(Scaling.PLAINS_LOW);
this.mobs.add(new RngSpawn(EntityHorse.class, 5, 2, 6));
this.treesPerChunk = -999;
this.flowersPerChunk = 4;
this.grassPerChunk = 10;
}
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
{
double d0 = GRASS_NOISE.generate((double)pos.getX() / 200.0D, (double)pos.getZ() / 200.0D);
if (d0 < -0.8D)
{
return rand.pick(TULIP_TYPES);
// int j = rand.nextInt(4);
//
// switch (j)
// {
// case 0:
// return BlockFlower.EnumFlowerType.ORANGE_TULIP;
//
// case 1:
// return BlockFlower.EnumFlowerType.RED_TULIP;
//
// case 2:
// return BlockFlower.EnumFlowerType.PINK_TULIP;
//
// case 3:
// default:
// return BlockFlower.EnumFlowerType.WHITE_TULIP;
// }
}
else if (rand.rarity(3))
{
return rand.pick(FLOWER_TYPES);
// int i = rand.nextInt(3);
// return i == 0 ? BlockFlower.EnumFlowerType.POPPY : (i == 1 ? BlockFlower.EnumFlowerType.HOUSTONIA : BlockFlower.EnumFlowerType.OXEYE_DAISY);
}
else
{
return BlockFlower.EnumFlowerType.DANDELION;
}
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
double d0 = GRASS_NOISE.generate((double)(pos.getX() + 8) / 200.0D, (double)(pos.getZ() + 8) / 200.0D);
if (d0 < -0.8D)
{
this.flowersPerChunk = 15;
this.grassPerChunk = 5;
}
else
{
this.flowersPerChunk = 4;
this.grassPerChunk = 10;
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.GRASS);
for (int i = 0; i < 7; ++i)
{
int j = rand.chOffset();
int k = rand.chOffset();
int l = rand.zrange(worldIn.getHeight(pos.add(j, 0, k)).getY() + 32);
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j, l, k));
}
}
// int n = rand.range(0, 2);
if (rand.chance())
{
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.SUNFLOWER);
// for (int i1 = 0; i1 < 10; ++i1)
// {
int j1 = rand.chOffset();
int k1 = rand.chOffset();
int l1 = rand.zrange(worldIn.getHeight(pos.add(j1, 0, k1)).getY() + 32);
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j1, l1, k1));
// }
}
super.decorate(worldIn, rand, pos);
}
// protected Biome createMutatedBiome(int p_180277_1_)
// {
// BiomePlains biomegenplains = new BiomePlains(p_180277_1_);
// biomegenplains.setBiomeName("sunflowerPlains");
// biomegenplains.field_150628_aC = true;
// biomegenplains.setColor(9286496);
// return biomegenplains;
// }
}

View file

@ -0,0 +1,89 @@
package server.biome;
import common.biome.Biome;
import common.block.foliage.BlockDoublePlant;
import common.block.natural.BlockDirt;
import common.entity.animal.EntityHorse;
import common.init.Blocks;
import common.rng.Random;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.ChunkPrimer;
import server.worldgen.tree.WorldGenSavanna;
import server.worldgen.tree.WorldGenTree;
public class BiomeSavanna extends GenBiome
{
private static final WorldGenSavanna field_150627_aC = new WorldGenSavanna(false);
protected BiomeSavanna(boolean plateau)
{
super(plateau ? Biome.SAVANNAPLATEAU : Biome.SAVANNA);
this.mobs.add(new RngSpawn(EntityHorse.class, 1, 2, 6));
this.treesPerChunk = 1;
this.flowersPerChunk = 4;
this.grassPerChunk = 20;
}
public WorldGenTree genBigTreeChance(Random rand)
{
return (WorldGenTree)(rand.rarity(5) ? field_150627_aC : this.worldGeneratorTrees);
}
protected GenBiome createMutatedBiome(Biome base)
{
GenBiome biomegenbase = new BiomeSavanna.Mutated(base, this);
biomegenbase.depth = this.depth * 0.5F + 0.3F;
biomegenbase.scale = this.scale * 0.5F + 1.2F;
return biomegenbase;
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.GRASS);
for (int i = 0; i < 7; ++i)
{
int j = rand.chOffset();
int k = rand.chOffset();
int l = rand.zrange(worldIn.getHeight(pos.add(j, 0, k)).getY() + 32);
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j, l, k));
}
super.decorate(worldIn, rand, pos);
}
public static class Mutated extends BiomeMutated
{
public Mutated(Biome base, GenBiome p_i45382_2_)
{
super(base, p_i45382_2_);
this.treesPerChunk = 2;
this.flowersPerChunk = 2;
this.grassPerChunk = 5;
}
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
this.topBlock = Blocks.grass.getState();
this.fillerBlock = Blocks.dirt.getState();
if (noiseVal > 1.75D)
{
this.topBlock = Blocks.stone.getState();
this.fillerBlock = Blocks.stone.getState();
}
else if (noiseVal > -0.5D)
{
this.topBlock = Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT);
}
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
this.decorateNormal(worldIn, rand, pos);
}
}
}

View file

@ -0,0 +1,65 @@
package server.biome;
import common.biome.Biome;
import common.init.Blocks;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.feature.WorldGenIcePath;
import server.worldgen.feature.WorldGenIceSpike;
import server.worldgen.tree.WorldGenTaiga2;
import server.worldgen.tree.WorldGenTree;
public class BiomeSnow extends GenBiome
{
private final WorldGenIceSpike spikeGen = new WorldGenIceSpike();
private final WorldGenIcePath pathGen = new WorldGenIcePath(4);
private final boolean spiky;
public BiomeSnow(Biome base, boolean spiky)
{
super(base);
this.spiky = spiky;
if(spiky)
this.topBlock = Blocks.snow.getState();
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
if (this.spiky)
{
for (int i = 0; i < 3; ++i)
{
int j = rand.chOffset();
int k = rand.chOffset();
this.spikeGen.generate(worldIn, rand, worldIn.getHeight(pos.add(j, 0, k)));
}
for (int l = 0; l < 2; ++l)
{
int i1 = rand.chOffset();
int j1 = rand.chOffset();
this.pathGen.generate(worldIn, rand, worldIn.getHeight(pos.add(i1, 0, j1)));
}
}
super.decorate(worldIn, rand, pos);
}
public WorldGenTree genBigTreeChance(Random rand)
{
return new WorldGenTaiga2(false);
}
protected GenBiome createMutatedBiome(Biome base)
{
GenBiome biomegenbase = (new BiomeSnow(base, true)).enableColdBeach().setScaling(this.depth + 0.1F, this.scale + 0.1F);
biomegenbase.depth = this.depth + 0.3F;
biomegenbase.scale = this.scale + 0.4F;
return biomegenbase;
}
}

View file

@ -0,0 +1,23 @@
package server.biome;
import common.biome.Biome;
import common.entity.animal.EntitySheep;
import common.entity.npc.EntitySpirit;
import common.init.Blocks;
import common.rng.WeightedList;
public class BiomeSnowLand extends GenBiome
{
public BiomeSnowLand()
{
super(Biome.SNOWLAND);
this.topBlock = Blocks.snow.getState();
this.fillerBlock = Blocks.snow.getState();
this.mushroomsPerChunk = -1;
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
mobs.add(new RngSpawn(EntitySheep.class, 50, 4, 4));
mobs.add(new RngSpawn(EntitySpirit.class, 10, 1, 1));
}
}

View file

@ -0,0 +1,39 @@
package server.biome;
import common.biome.Biome;
import common.block.natural.BlockDirt;
import common.init.Blocks;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.FeatureGenerator;
import server.worldgen.feature.WorldGenAsteroid;
public class BiomeSpace extends GenBiome
{
protected FeatureGenerator asteroidGen1 = new WorldGenAsteroid(Blocks.stone.getState(),
Blocks.rock.getState());
protected FeatureGenerator asteroidGen2 = new WorldGenAsteroid(Blocks.dirt.getState(),
Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT));
public BiomeSpace()
{
super(Biome.SPACE);
this.topBlock = Blocks.air.getState();
this.fillerBlock = Blocks.air.getState();
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
if(rand.chance(5)) {
int x = rand.chOffset();
int z = rand.chOffset();
rand.chance(this.asteroidGen1, this.asteroidGen2, 100).generate(worldIn, rand,
pos.add(x, rand.range(16, 495), z));
}
}
}

View file

@ -0,0 +1,23 @@
package server.biome;
import common.biome.Biome;
import common.init.Blocks;
import common.rng.WeightedList;
public class BiomeStoneBeach extends GenBiome
{
public BiomeStoneBeach()
{
super(Biome.STONEBEACH);
// this.mobs.clear();
this.topBlock = Blocks.stone.getState();
this.fillerBlock = Blocks.stone.getState();
this.treesPerChunk = -999;
this.deadBushPerChunk = 0;
this.reedsPerChunk = 0;
this.cactiPerChunk = 0;
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
}
}

View file

@ -0,0 +1,74 @@
package server.biome;
import common.biome.Biome;
import common.block.BlockDirectional;
import common.block.foliage.BlockFlower;
import common.entity.npc.EntitySlime;
import common.init.Blocks;
import common.rng.Random;
import common.util.BlockPos;
import common.util.Facing;
import server.world.WorldServer;
import server.worldgen.ChunkPrimer;
import server.worldgen.tree.WorldGenTree;
public class BiomeSwamp extends GenBiome
{
protected BiomeSwamp()
{
super(Biome.SWAMPLAND);
this.treesPerChunk = 2;
this.flowersPerChunk = 1;
this.deadBushPerChunk = 1;
this.mushroomsPerChunk = 8;
this.reedsPerChunk = 10;
this.clayPerChunk = 1;
this.waterlilyPerChunk = 4;
this.sandPerChunk2 = 0;
this.sandPerChunk = 0;
this.grassPerChunk = 5;
this.mobs.add(new RngSpawn(EntitySlime.class, 1, 1, 1));
this.disableBeach();
}
public WorldGenTree genBigTreeChance(Random rand)
{
return this.worldGeneratorSwamp;
}
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
{
return BlockFlower.EnumFlowerType.BLUE_ORCHID;
}
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
double d0 = GRASS_NOISE.generate((double)x * 0.25D, (double)z * 0.25D);
if (d0 > 0.0D)
{
int i = x & 15;
int j = z & 15;
for (int k = chunkPrimerIn.height - 1; k >= 0; --k)
{
if (chunkPrimerIn.get(j, k, i).getBlock() != Blocks.air)
{
if (k == 62 && chunkPrimerIn.get(j, k, i).getBlock() != Blocks.water)
{
chunkPrimerIn.set(j, k, i, Blocks.water.getState());
if (d0 < 0.12D)
{
chunkPrimerIn.set(j, k + 1, i, Blocks.waterlily.getState().withProperty(BlockDirectional.FACING, Facing.randHorizontal(rand)));
}
}
break;
}
}
}
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
}

View file

@ -0,0 +1,115 @@
package server.biome;
import common.biome.Biome;
import common.block.foliage.BlockDoublePlant;
import common.block.foliage.BlockTallGrass;
import common.block.natural.BlockDirt;
import common.entity.animal.EntityWolf;
import common.init.Blocks;
import common.rng.Random;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.ChunkPrimer;
import server.worldgen.FeatureGenerator;
import server.worldgen.feature.WorldGenBlockBlob;
import server.worldgen.foliage.WorldGenTallGrass;
import server.worldgen.tree.WorldGenPine;
import server.worldgen.tree.WorldGenTaiga1;
import server.worldgen.tree.WorldGenTaiga2;
import server.worldgen.tree.WorldGenTree;
public class BiomeTaiga extends GenBiome
{
private static final WorldGenTaiga1 field_150639_aC = new WorldGenTaiga1();
private static final WorldGenTaiga2 field_150640_aD = new WorldGenTaiga2(false);
private static final WorldGenPine field_150641_aE = new WorldGenPine(false, false);
private static final WorldGenPine field_150642_aF = new WorldGenPine(false, true);
private static final WorldGenBlockBlob field_150643_aG = new WorldGenBlockBlob(Blocks.mossy_cobblestone, 0);
private int field_150644_aH;
public BiomeTaiga(Biome base, int p_i45385_2_)
{
super(base);
this.field_150644_aH = p_i45385_2_;
this.mobs.add(new RngSpawn(EntityWolf.class, 8, 4, 4));
this.treesPerChunk = 10;
if (p_i45385_2_ != 1 && p_i45385_2_ != 2)
{
this.grassPerChunk = 1;
this.mushroomsPerChunk = 1;
}
else
{
this.grassPerChunk = 7;
this.deadBushPerChunk = 1;
this.mushroomsPerChunk = 3;
}
}
public WorldGenTree genBigTreeChance(Random rand)
{
return (WorldGenTree)((this.field_150644_aH == 1 || this.field_150644_aH == 2) && rand.chance(3) ? (this.field_150644_aH != 2 && rand.rarity(13) ? field_150641_aE : field_150642_aF) : (rand.chance(3) ? field_150639_aC : field_150640_aD));
}
/**
* Gets a WorldGen appropriate for this biome.
*/
public FeatureGenerator getRandomWorldGenForGrass(Random rand)
{
return rand.rarity(5) ? new WorldGenTallGrass(BlockTallGrass.EnumType.FERN) : new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
if (this.field_150644_aH == 1 || this.field_150644_aH == 2)
{
int i = rand.zrange(3);
for (int j = 0; j < i; ++j)
{
int k = rand.chOffset();
int l = rand.chOffset();
BlockPos blockpos = worldIn.getHeight(pos.add(k, 0, l));
field_150643_aG.generate(worldIn, rand, blockpos);
}
}
DOUBLE_PLANT_GEN.setPlantType(BlockDoublePlant.EnumPlantType.FERN);
for (int i1 = 0; i1 < 7; ++i1)
{
int j1 = rand.chOffset();
int k1 = rand.chOffset();
int l1 = rand.zrange(worldIn.getHeight(pos.add(j1, 0, k1)).getY() + 32);
DOUBLE_PLANT_GEN.generate(worldIn, rand, pos.add(j1, l1, k1));
}
super.decorate(worldIn, rand, pos);
}
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
if (this.field_150644_aH == 1 || this.field_150644_aH == 2)
{
this.topBlock = Blocks.grass.getState();
this.fillerBlock = Blocks.dirt.getState();
if (noiseVal > 1.75D)
{
this.topBlock = Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.COARSE_DIRT);
}
else if (noiseVal > -0.95D)
{
this.topBlock = Blocks.dirt.getState().withProperty(BlockDirt.VARIANT, BlockDirt.DirtType.PODZOL);
}
}
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
protected GenBiome createMutatedBiome(Biome base)
{
return this.base == Biome.MEGATAIGA ? (new BiomeTaiga(base, 2)).setScaling(this.depth, this.scale) : super.createMutatedBiome(base);
}
}

View file

@ -0,0 +1,83 @@
package server.biome;
import common.biome.Biome;
import common.block.foliage.BlockFlower;
import common.entity.animal.EntityBat;
import common.entity.animal.EntityMouse;
import common.entity.animal.EntityRabbit;
import common.entity.npc.EntityCultivator;
import common.init.Blocks;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import server.world.WorldServer;
import server.worldgen.FeatureGenerator;
import server.worldgen.feature.WorldGenSpikes;
import server.worldgen.foliage.WorldGenMushroom;
import server.worldgen.tree.WorldGenBaseTree;
import server.worldgen.tree.WorldGenBigTree;
import server.worldgen.tree.WorldGenTree;
public class BiomeTian extends GenBiome
{
protected FeatureGenerator spikeGen = new WorldGenSpikes(Blocks.tian_soil, 128, 2, 3, Blocks.obsidian.getState(), true);
protected FeatureGenerator mushroomBlueGen = new WorldGenMushroom(Blocks.blue_mushroom);
protected WorldGenTree treeGen1 = new WorldGenBigTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
.setHeightLimit(6, 8);
protected WorldGenTree treeGen2 = new WorldGenBigTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
.setHeightLimit(14, 20);
protected WorldGenTree treeGen3 = new WorldGenBaseTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState());
protected WorldGenTree treeGen4 = new WorldGenBigTree(false, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
.setHeightLimit(12, 15);
public BiomeTian()
{
super(Biome.TIAN);
this.topBlock = Blocks.tian_soil.getState();
this.fillerBlock = Blocks.tian.getState();
this.mushroomsPerChunk = -1;
this.grassPerChunk = 0;
this.treesPerChunk = 1;
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
// mobs.add(new Biome.RngSpawn(EntityHaunter.class, 50, 4, 4));
mobs.add(new RngSpawn(EntityCultivator.class, 50, 1, 1));
mobs.add(new RngSpawn(EntityRabbit.class, 10, 3, 10));
mobs.add(new RngSpawn(EntityBat.class, 10, 8, 8));
mobs.add(new RngSpawn(EntityMouse.class, 10, 8, 8));
}
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
{
return BlockFlower.EnumFlowerType.BLACK_LOTUS;
}
public WorldGenTree genBigTreeChance(Random rand)
{
return rand.pick(rand.chance(this.treeGen2, this.treeGen1, 4), rand.chance(this.treeGen3, this.treeGen4, 15));
}
public void decorate(WorldServer worldIn, Random rand, BlockPos pos)
{
super.decorate(worldIn, rand, pos);
for (int l3 = 0; l3 < 2; ++l3)
{
if (rand.chance(4))
{
int i8 = rand.chOffset();
int l11 = rand.chOffset();
BlockPos blockpos2 = worldIn.getHeight(pos.add(i8, 0, l11));
this.mushroomBlueGen.generate(worldIn, rand, blockpos2);
}
}
if (rand.chance(4))
{
int i = rand.chOffset();
int j = rand.chOffset();
this.spikeGen.generate(worldIn, rand, worldIn.getTopSolidOrLiquidBlock(pos.add(i, 0, j)));
}
}
}

View file

@ -0,0 +1,23 @@
package server.biome;
import common.biome.Biome;
import common.entity.animal.EntitySquid;
import common.rng.WeightedList;
public class BiomeWater extends GenBiome {
private final boolean river;
public BiomeWater(Biome base, boolean river) {
super(base);
this.river = river;
this.disableBeach();
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
mobs.add(new RngSpawn(EntitySquid.class, 10, 4, 4));
}
public Temperature getTempCategory() {
return this.river ? super.getTempCategory() : Temperature.SEA;
}
}

View file

@ -0,0 +1,874 @@
package server.biome;
import common.biome.Biome;
import common.biome.IBiome;
import common.block.Block;
import common.block.BlockColored;
import common.block.Material;
import common.block.foliage.BlockFlower;
import common.block.foliage.BlockSapling;
import common.block.foliage.BlockTallGrass;
import common.block.natural.BlockSand;
import common.color.DyeColor;
import common.entity.animal.EntityBat;
import common.entity.animal.EntityChicken;
import common.entity.animal.EntityCow;
import common.entity.animal.EntityMouse;
import common.entity.animal.EntityPig;
import common.entity.animal.EntityRabbit;
import common.entity.animal.EntitySheep;
import common.entity.animal.EntitySquid;
import common.entity.npc.EntityArachnoid;
import common.entity.npc.EntityHaunter;
import common.entity.npc.EntityMage;
import common.entity.npc.EntitySlime;
import common.entity.npc.EntityUndead;
import common.entity.npc.EntityZombie;
import common.init.Blocks;
import common.init.WoodType;
import common.log.Log;
import common.rng.PerlinGen;
import common.rng.Random;
import common.rng.WeightedList;
import common.util.BlockPos;
import common.world.AWorldServer;
import common.world.State;
import common.world.World;
import server.world.WorldServer;
import server.worldgen.ChunkPrimer;
import server.worldgen.FeatureGenerator;
import server.worldgen.feature.WorldGenClay;
import server.worldgen.feature.WorldGenClayExt;
import server.worldgen.feature.WorldGenSand;
import server.worldgen.foliage.FeatureDoublePlant;
import server.worldgen.foliage.WorldGenBigMushroom;
import server.worldgen.foliage.WorldGenCactus;
import server.worldgen.foliage.WorldGenDeadBush;
import server.worldgen.foliage.WorldGenFlowers;
import server.worldgen.foliage.WorldGenMushroom;
import server.worldgen.foliage.WorldGenPumpkin;
import server.worldgen.foliage.WorldGenReed;
import server.worldgen.foliage.WorldGenTallGrass;
import server.worldgen.foliage.WorldGenWaterlily;
import server.worldgen.tree.WorldGenBaseTree;
import server.worldgen.tree.WorldGenBigTree;
import server.worldgen.tree.WorldGenBirch;
import server.worldgen.tree.WorldGenDarkOak;
import server.worldgen.tree.WorldGenJungle;
import server.worldgen.tree.WorldGenPine;
import server.worldgen.tree.WorldGenSavanna;
import server.worldgen.tree.WorldGenSwamp;
import server.worldgen.tree.WorldGenTaiga2;
import server.worldgen.tree.WorldGenTree;
public abstract class GenBiome implements IBiome {
public static final GenBiome[] BIOMES = new GenBiome[256];
public static final GenBiome none = (new BiomeNone());
public static final GenBiome plains = (new BiomePlains());
public static final GenBiome desert = (new BiomeDesert(false)).setScaling(Scaling.PLAINS_LOW);
public static final GenBiome extremeHills = (new BiomeHills(Biome.EXTREMEHILLS, false)).setScaling(Scaling.HILLS_LARGE);
public static final GenBiome forest = (new BiomeForest(Biome.FOREST, 0));
public static final GenBiome taiga = (new BiomeTaiga(Biome.TAIGA, 0)).setScaling(Scaling.PLAINS_MEDIUM);
public static final GenBiome swampland = (new BiomeSwamp()).setScaling(Scaling.SEA_POND);
public static final GenBiome river = (new BiomeWater(Biome.RIVER, true)).setScaling(Scaling.SEA_SHALLOW);
public static final GenBiome exterminated = (new BiomeExterminated());
public static final GenBiome space = (new BiomeSpace());
public static final GenBiome frozenSea = (new BiomeWater(Biome.FROZENSEA, false)).enableColdBeach().setScaling(Scaling.SEA_MEDIUM);
public static final GenBiome frozenRiver = (new BiomeWater(Biome.FROZENRIVER, true)).enableColdBeach().setScaling(Scaling.SEA_SHALLOW);
public static final GenBiome icePlains = (new BiomeSnow(Biome.ICEPLAINS, false)).enableColdBeach().setScaling(Scaling.PLAINS_LOW);
public static final GenBiome iceMountains = (new BiomeSnow(Biome.ICEMOUNTAINS, false)).enableColdBeach().setScaling(Scaling.HILLS_LOW);
public static final GenBiome mushroomPlains = (new BiomeMushroom()).setScaling(Scaling.PLAINS_VARYING);
public static final GenBiome blackened = (new BiomeBlackened());
public static final GenBiome beach = (new BiomeBeach(false)).setScaling(Scaling.SEA_SHORE);
public static final GenBiome desertHills = (new BiomeDesert(true)).setScaling(Scaling.HILLS_LOW);
public static final GenBiome forestHills = (new BiomeForest(Biome.FORESTHILLS, 0)).setScaling(Scaling.HILLS_LOW);
public static final GenBiome taigaHills = (new BiomeTaiga(Biome.TAIGAHILLS, 0)).setScaling(Scaling.HILLS_LOW);
public static final GenBiome extremeHillsEdge = (new BiomeHills(Biome.EXTREMEHILLSEDGE, true)).setScaling(Scaling.HILLS_MEDIUM);
public static final GenBiome jungle = (new BiomeJungle(Biome.JUNGLE, false));
public static final GenBiome jungleHills = (new BiomeJungle(Biome.JUNGLEHILLS, false)).setScaling(Scaling.HILLS_LOW);
public static final GenBiome jungleEdge = (new BiomeJungle(Biome.JUNGLEEDGE, true));
public static final GenBiome sea = (new BiomeWater(Biome.SEA, false)).setScaling(Scaling.SEA_MEDIUM);
public static final GenBiome stoneBeach = (new BiomeStoneBeach()).setScaling(Scaling.SEA_VARYING);
public static final GenBiome coldBeach = (new BiomeBeach(true)).setScaling(Scaling.SEA_SHORE).enableColdBeach();
public static final GenBiome birchForest = (new BiomeForest(Biome.BIRCHFOREST, 2));
public static final GenBiome birchForestHills = (new BiomeForest(Biome.BIRCHFORESTHILLS, 2)).setScaling(Scaling.HILLS_LOW);
public static final GenBiome roofedForest = (new BiomeForest(Biome.ROOFEDFOREST, 3));
public static final GenBiome coldTaiga = (new BiomeTaiga(Biome.COLDTAIGA, 0)).enableColdBeach().setScaling(Scaling.PLAINS_MEDIUM);
public static final GenBiome coldTaigaHills = (new BiomeTaiga(Biome.COLDTAIGAHILLS, 0)).enableColdBeach().setScaling(Scaling.HILLS_LOW);
public static final GenBiome megaTaiga = (new BiomeTaiga(Biome.MEGATAIGA, 1)).setScaling(Scaling.PLAINS_MEDIUM);
public static final GenBiome megaTaigaHills = (new BiomeTaiga(Biome.MEGATAIGAHILLS, 1)).setScaling(Scaling.HILLS_LOW);
public static final GenBiome extremeHillsPlus = (new BiomeHills(Biome.EXTREMEHILLSPLUS, true)).setScaling(Scaling.HILLS_LARGE);
public static final GenBiome savanna = (new BiomeSavanna(false)).setScaling(Scaling.PLAINS_LOW);
public static final GenBiome savannaPlateau = (new BiomeSavanna(true)).setScaling(Scaling.HILLS_PLATEAU);
public static final GenBiome mesa = (new BiomeMesa(Biome.MESA, false, false));
public static final GenBiome mesaPlateau_F = (new BiomeMesa(Biome.MESAPLATEAUF, false, true)).setScaling(Scaling.HILLS_PLATEAU);
public static final GenBiome mesaPlateau = (new BiomeMesa(Biome.MESAPLATEAU, false, false)).setScaling(Scaling.HILLS_PLATEAU);
public static final GenBiome snowLand = (new BiomeSnowLand()).enableColdBeach();
public static final GenBiome tian = (new BiomeTian()).setScaling(Scaling.VARYING_MEDIUM);
public static final GenBiome elvenForest = (new BiomeForest(Biome.ELVENFOREST, 4));
public static final GenBiome upperHell = (new BiomeHell(Biome.UPPERHELL, 0));
public static final GenBiome lowerHell = (new BiomeHell(Biome.LOWERHELL, 1));
public static final GenBiome hellHills = (new BiomeHell(Biome.HELLHILLS, 1)).setScaling(Scaling.HILLS_LARGE);
public static final GenBiome soulPlains = (new BiomeHell(Biome.SOULPLAINS, 1)).setScaling(Scaling.SEA_POND);
public static final GenBiome ashLand = (new BiomeHell(Biome.ASHLAND, 2)).setScaling(Scaling.PLAINS_LOW);
public static final GenBiome moon = (new BiomeMoon()).setScaling(Scaling.PLAINS_LOW);
public static final GenBiome chaos = (new BiomeChaos()).setScaling(Scaling.VARYING_CHAOTIC);
protected static final PerlinGen TREE_NOISE = new PerlinGen(new Random(726528729282625L), 8);
protected static final PerlinGen GRASS_NOISE = new PerlinGen(new Random(297363826225L), 1);
protected static final FeatureDoublePlant DOUBLE_PLANT_GEN = new FeatureDoublePlant();
public final Biome base;
protected final WeightedList<RngSpawn> mobs = new WeightedList<RngSpawn>();
protected final WorldGenBaseTree worldGeneratorTrees = new WorldGenBaseTree(false);
protected final WorldGenBigTree worldGeneratorBigTree = new WorldGenBigTree(false);
protected final WorldGenSwamp worldGeneratorSwamp = new WorldGenSwamp();
private final FeatureGenerator clayGen = new WorldGenClay(4);
private final FeatureGenerator sandGen = new WorldGenSand(Blocks.sand, 7);
private final FeatureGenerator gravelAsSandGen = new WorldGenSand(Blocks.gravel, 6);
private final WorldGenFlowers yellowFlowerGen = new WorldGenFlowers(Blocks.flower, BlockFlower.EnumFlowerType.DANDELION);
private final FeatureGenerator mushroomBrownGen = new WorldGenMushroom(Blocks.brown_mushroom);
private final FeatureGenerator mushroomRedGen = new WorldGenMushroom(Blocks.red_mushroom);
private final FeatureGenerator bigMushroomGen = new WorldGenBigMushroom();
private final FeatureGenerator reedGen = new WorldGenReed();
private final FeatureGenerator cactusGen = new WorldGenCactus();
private final FeatureGenerator waterlilyGen = new WorldGenWaterlily();
private final FeatureGenerator clayGenExt = new WorldGenClayExt(32);
public State topBlock = Blocks.grass.getState();
public State fillerBlock = Blocks.dirt.getState();
public float depth = Scaling.VARYING_LOW.depth;
public float scale = Scaling.VARYING_LOW.scale;
public boolean generateLakes = true;
public boolean generateLiquids = true;
public boolean allowColdBeach = false;
public boolean disallowBeach = false;
protected int waterlilyPerChunk = 0;
protected int treesPerChunk = 0;
protected int flowersPerChunk = 2;
protected int grassPerChunk = 1;
protected int deadBushPerChunk = 0;
protected int mushroomsPerChunk = 0;
protected int reedsPerChunk = 0;
protected int cactiPerChunk = 0;
protected int sandPerChunk = 1;
protected int sandPerChunk2 = 3;
protected int clayPerChunk = 1;
protected int clayExtPerChunk = 0; // 10
protected int bigMushroomsPerChunk = 0;
public static GenBiome getBiome(int id)
{
if (id >= 0 && id < BIOMES.length)
{
return BIOMES[id];
}
else
{
Log.TICK.warn("Biom-ID ist nicht im Bereich: " + id + ", verwende " + Biome.DEF_BIOME.id + " (" + Biome.DEF_BIOME.name + ")");
return BIOMES[Biome.DEF_BIOME.id];
}
}
public static void setAsProvider() {
IBiome.setProvider(new IBiome.BiomeProvider() {
public final IBiome getBiome(Biome base) {
return BIOMES[base.id];
}
});
}
static {
desert.createMutatedBiome(Biome.DESERTM);
forest.createMutatedBiome(Biome.FLOWERFOREST);
taiga.createMutatedBiome(Biome.TAIGAM);
swampland.createMutatedBiome(Biome.SWAMPLANDM);
icePlains.createMutatedBiome(Biome.ICEPLAINSSPIKES);
jungle.createMutatedBiome(Biome.JUNGLEM);
jungleEdge.createMutatedBiome(Biome.JUNGLEEDGEM);
coldTaiga.createMutatedBiome(Biome.COLDTAIGAM);
savanna.createMutatedBiome(Biome.SAVANNAM);
savannaPlateau.createMutatedBiome(Biome.SAVANNAPLATEAUM);
mesa.createMutatedBiome(Biome.MESABRYCE);
mesaPlateau_F.createMutatedBiome(Biome.MESAPLATEAUFM);
mesaPlateau.createMutatedBiome(Biome.MESAPLATEAUM);
birchForest.createMutatedBiome(Biome.BIRCHFORESTM);
birchForestHills.createMutatedBiome(Biome.BIRCHFORESTHILLSM);
roofedForest.createMutatedBiome(Biome.ROOFEDFORESTM);
megaTaiga.createMutatedBiome(Biome.MEGASPRUCETAIGA);
extremeHills.createMutatedBiome(Biome.EXTREMEHILLSM);
extremeHillsPlus.createMutatedBiome(Biome.EXTREMEHILLSPLUSM);
megaTaiga.createMutatedBiome(Biome.REDWOODTAIGAHILLSM);
}
protected GenBiome(Biome base) {
BIOMES[base.id] = this;
this.base = base;
this.addMobs(this.mobs);
}
protected void addMobs(WeightedList<RngSpawn> mobs) {
mobs.add(new RngSpawn(EntitySheep.class, 12, 4, 4));
mobs.add(new RngSpawn(EntityRabbit.class, 10, 3, 10));
mobs.add(new RngSpawn(EntityPig.class, 10, 4, 4));
mobs.add(new RngSpawn(EntityChicken.class, 10, 4, 4));
mobs.add(new RngSpawn(EntityCow.class, 8, 4, 4));
mobs.add(new RngSpawn(EntityArachnoid.class, 100, 4, 4));
mobs.add(new RngSpawn(EntityZombie.class, 100, 4, 4));
mobs.add(new RngSpawn(EntityUndead.class, 100, 4, 4));
mobs.add(new RngSpawn(EntityHaunter.class, 100, 4, 4));
mobs.add(new RngSpawn(EntitySlime.class, 100, 4, 4));
// mobs.add(new Biome.RngSpawn(EntityEnder....class, 10, 1, 4));
mobs.add(new RngSpawn(EntityMage.class, 5, 1, 1));
mobs.add(new RngSpawn(EntitySquid.class, 10, 4, 4));
mobs.add(new RngSpawn(EntityBat.class, 10, 8, 8));
mobs.add(new RngSpawn(EntityMouse.class, 10, 8, 8));
}
protected final GenBiome setScaling(Scaling scaling)
{
return this.setScaling(scaling.depth, scaling.scale);
}
protected final GenBiome setScaling(float depth, float scale)
{
this.depth = depth;
this.scale = scale;
return this;
}
public WorldGenTree genBigTreeChance(Random rand)
{
return rand.chance(10) ? this.worldGeneratorBigTree : this.worldGeneratorTrees;
}
public WorldGenTree genBigTreeLegacy(Random rand, BlockPos pos)
{
int noise = (int)((TREE_NOISE.generate((double)pos.getX() * 0.5D, (double)pos.getZ() * 0.5D) / 8D + rand.doublev() * 4D + 4D) / 3D);
return (noise > 0 && rand.chance(noise)) || (this.base.isHighHumidity() && rand.chance(3)) ? this.worldGeneratorBigTree :
this.worldGeneratorTrees;
}
public FeatureGenerator getRandomWorldGenForGrass(Random rand)
{
return new WorldGenTallGrass(BlockTallGrass.EnumType.GRASS);
}
public BlockFlower.EnumFlowerType pickRandomFlower(Random rand, BlockPos pos)
{
return rand.rarity(3) ? BlockFlower.EnumFlowerType.DANDELION : BlockFlower.EnumFlowerType.ROSE;
}
public State getFiller() {
return this.fillerBlock;
}
public State getTop() {
return this.topBlock;
}
protected GenBiome enableColdBeach()
{
this.allowColdBeach = true;
return this;
}
protected GenBiome disableBeach()
{
this.disallowBeach = true;
return this;
}
public WeightedList<RngSpawn> getMobs()
{
return this.mobs;
}
public float getMobGenChance()
{
return 0.1F;
}
public void decorate(WorldServer world, Random rand, BlockPos pos)
{
for (int i = 0; i < this.sandPerChunk2; ++i)
{
int j = rand.chOffset();
int k = rand.chOffset();
this.sandGen.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(j, 0, k)));
}
for (int i1 = 0; i1 < this.clayPerChunk; ++i1)
{
int l1 = rand.chOffset();
int i6 = rand.chOffset();
this.clayGen.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(l1, 0, i6)));
}
for (int j1 = 0; j1 < this.sandPerChunk; ++j1)
{
int i2 = rand.chOffset();
int j6 = rand.chOffset();
this.gravelAsSandGen.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(i2, 0, j6)));
}
for (int i1 = 0; i1 < this.clayExtPerChunk; ++i1)
{
int l1 = rand.chOffset();
int i6 = rand.chOffset();
this.clayGenExt.generate(world, rand, world.getTopSolidOrLiquidBlock(pos.add(l1, 0, i6)));
}
int k1 = this.treesPerChunk;
if (rand.chance(10))
{
++k1;
}
for (int j2 = 0; j2 < k1; ++j2)
{
int k6 = rand.chOffset();
int l = rand.chOffset();
WorldGenTree treeGen = this.genBigTreeChance(rand);
treeGen.prepare();
BlockPos blockpos = world.getHeight(pos.add(k6, 0, l));
if (treeGen.generate(world, rand, blockpos))
{
treeGen.finish(world, rand, blockpos);
}
}
for (int k2 = 0; k2 < this.bigMushroomsPerChunk; ++k2)
{
int l6 = rand.chOffset();
int k10 = rand.chOffset();
this.bigMushroomGen.generate(world, rand, world.getHeight(pos.add(l6, 0, k10)));
}
for (int l2 = 0; l2 < this.flowersPerChunk; ++l2)
{
int i7 = rand.chOffset();
int l10 = rand.chOffset();
int j14 = world.getHeight(pos.add(i7, 0, l10)).getY() + 32;
if (j14 > 0)
{
int k17 = rand.zrange(j14);
BlockPos blockpos1 = pos.add(i7, k17, l10);
BlockFlower.EnumFlowerType blockflower$enumflowertype = this.pickRandomFlower(rand, blockpos1);
BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock();
if (blockflower != Blocks.air)
{
this.yellowFlowerGen.setGeneratedBlock(blockflower, blockflower$enumflowertype);
this.yellowFlowerGen.generate(world, rand, blockpos1);
}
}
}
for (int i3 = 0; i3 < this.grassPerChunk; ++i3)
{
int j7 = rand.chOffset();
int i11 = rand.chOffset();
int k14 = world.getHeight(pos.add(j7, 0, i11)).getY() * 2;
if (k14 > 0)
{
int l17 = rand.zrange(k14);
this.getRandomWorldGenForGrass(rand).generate(world, rand, pos.add(j7, l17, i11));
}
}
for (int j3 = 0; j3 < this.deadBushPerChunk; ++j3)
{
int k7 = rand.chOffset();
int j11 = rand.chOffset();
int l14 = world.getHeight(pos.add(k7, 0, j11)).getY() * 2;
if (l14 > 0)
{
int i18 = rand.zrange(l14);
(new WorldGenDeadBush()).generate(world, rand, pos.add(k7, i18, j11));
}
}
for (int k3 = 0; k3 < this.waterlilyPerChunk; ++k3)
{
int l7 = rand.chOffset();
int k11 = rand.chOffset();
int i15 = world.getHeight(pos.add(l7, 0, k11)).getY() * 2;
if (i15 > 0)
{
int j18 = rand.zrange(i15);
BlockPos blockpos4;
BlockPos blockpos7;
for (blockpos4 = pos.add(l7, j18, k11); blockpos4.getY() > 0; blockpos4 = blockpos7)
{
blockpos7 = blockpos4.down();
if (!world.isAirBlock(blockpos7))
{
break;
}
}
this.waterlilyGen.generate(world, rand, blockpos4);
}
}
for (int l3 = 0; l3 < this.mushroomsPerChunk; ++l3)
{
if (rand.chance(4))
{
int i8 = rand.chOffset();
int l11 = rand.chOffset();
BlockPos blockpos2 = world.getHeight(pos.add(i8, 0, l11));
this.mushroomBrownGen.generate(world, rand, blockpos2);
}
if (rand.chance(8))
{
int j8 = rand.chOffset();
int i12 = rand.chOffset();
int j15 = world.getHeight(pos.add(j8, 0, i12)).getY() * 2;
if (j15 > 0)
{
int k18 = rand.zrange(j15);
BlockPos blockpos5 = pos.add(j8, k18, i12);
this.mushroomRedGen.generate(world, rand, blockpos5);
}
}
}
if (this.mushroomsPerChunk != -1 && rand.chance(4))
{
int i4 = rand.chOffset();
int k8 = rand.chOffset();
int j12 = world.getHeight(pos.add(i4, 0, k8)).getY() * 2;
if (j12 > 0)
{
int k15 = rand.zrange(j12);
this.mushroomBrownGen.generate(world, rand, pos.add(i4, k15, k8));
}
}
if (this.mushroomsPerChunk != -1 && rand.chance(8))
{
int j4 = rand.chOffset();
int l8 = rand.chOffset();
int k12 = world.getHeight(pos.add(j4, 0, l8)).getY() * 2;
if (k12 > 0)
{
int l15 = rand.zrange(k12);
this.mushroomRedGen.generate(world, rand, pos.add(j4, l15, l8));
}
}
for (int k4 = 0; k4 < this.reedsPerChunk; ++k4)
{
int i9 = rand.chOffset();
int l12 = rand.chOffset();
int i16 = world.getHeight(pos.add(i9, 0, l12)).getY() * 2;
if (i16 > 0)
{
int l18 = rand.zrange(i16);
this.reedGen.generate(world, rand, pos.add(i9, l18, l12));
}
}
for (int l4 = 0; l4 < 10; ++l4)
{
int j9 = rand.chOffset();
int i13 = rand.chOffset();
int j16 = world.getHeight(pos.add(j9, 0, i13)).getY() * 2;
if (j16 > 0)
{
int i19 = rand.zrange(j16);
this.reedGen.generate(world, rand, pos.add(j9, i19, i13));
}
}
if (rand.chance(32))
{
int i5 = rand.chOffset();
int k9 = rand.chOffset();
int j13 = world.getHeight(pos.add(i5, 0, k9)).getY() * 2;
if (j13 > 0)
{
int k16 = rand.zrange(j13);
(new WorldGenPumpkin()).generate(world, rand, pos.add(i5, k16, k9));
}
}
for (int j5 = 0; j5 < this.cactiPerChunk; ++j5)
{
int l9 = rand.chOffset();
int k13 = rand.chOffset();
int l16 = world.getHeight(pos.add(l9, 0, k13)).getY() * 2;
if (l16 > 0)
{
int j19 = rand.zrange(l16);
this.cactusGen.generate(world, rand, pos.add(l9, j19, k13));
}
}
}
public void genTerrainBlocks(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
this.generateBiomeTerrain(worldIn, rand, chunkPrimerIn, x, z, noiseVal);
}
/**
* Given x, z coordinates, we count down all the y positions starting at height - 1 and working our way down. When we hit a
* non-air block, we replace it with this.topBlock (default grass, descendants may set otherwise), and then a
* relatively shallow layer of blocks of type this.fillerBlock (default dirt). A random set of blocks below y == 5
* (but always including y == 0) is replaced with bedrock in Chunk(...).
*
* If we don't hit non-air until somewhat below sea level, we top with gravel and fill down with stone.
*
* If this.fillerBlock is red sand, we replace some of that with red sandstone.
*/
public final void generateBiomeTerrain(WorldServer worldIn, Random rand, ChunkPrimer chunkPrimerIn, int x, int z, double noiseVal)
{
int i = worldIn.getSeaLevel();
State worldState = worldIn.dimension.getFiller();
Block worldBlock = worldState.getBlock();
State worldAlt = worldIn.dimension.getAltFiller1();
State liquid = worldIn.getSurfaceLiquid();
boolean freeze = liquid.getBlock().getMaterial() == Material.WATER;
State iblockstate = this.topBlock;
State iblockstate1 = this.fillerBlock;
int j = -1;
int k = (int)(noiseVal / 3.0D + 3.0D + rand.doublev() * 0.25D);
int l = x & 15;
int i1 = z & 15;
BlockPos.MutableBlockPos blockpos$mutableblockpos = new BlockPos.MutableBlockPos();
for (int j1 = chunkPrimerIn.height - 1; j1 >= 0; --j1)
{
State iblockstate2 = chunkPrimerIn.get(i1, j1, l);
if (iblockstate2.getBlock() == Blocks.air)
{
j = -1;
}
else if (iblockstate2.getBlock() == worldBlock)
{
if (j == -1)
{
if (k <= 0)
{
iblockstate = null;
iblockstate1 = worldState;
}
else if (j1 >= i - 4 && j1 <= i + 1)
{
iblockstate = this.topBlock;
iblockstate1 = this.fillerBlock;
}
if (j1 < i && (iblockstate == null || iblockstate.getBlock() == Blocks.air))
{
if (freeze && World.ABSOLUTE_ZERO + worldIn.getTempOffset() + this.base.getTemperature(blockpos$mutableblockpos.set(x, j1, z)) <= 0.0F)
{
iblockstate = Blocks.ice.getState();
}
else
{
iblockstate = liquid;
}
}
j = k;
if (j1 >= i - 1)
{
chunkPrimerIn.set(i1, j1, l, iblockstate);
}
else if (j1 < i - 7 - k)
{
iblockstate = null;
iblockstate1 = worldState;
chunkPrimerIn.set(i1, j1, l, worldAlt);
}
else
{
chunkPrimerIn.set(i1, j1, l, iblockstate1);
}
}
else if (j > 0)
{
--j;
chunkPrimerIn.set(i1, j1, l, iblockstate1);
if (j == 0 && iblockstate1.getBlock() == Blocks.sand)
{
j = rand.zrange(4) + Math.max(0, j1 - 63);
iblockstate1 = iblockstate1.getValue(BlockSand.VARIANT) == BlockSand.EnumType.RED_SAND ? Blocks.stained_hardened_clay.getState().withProperty(BlockColored.COLOR, DyeColor.ORANGE) : Blocks.sandstone.getState(); //TODO: check!
}
}
}
}
}
public boolean generateBigMushroom(AWorldServer worldIn, BlockPos pos, State state, Random rand)
{
worldIn.setBlockToAir(pos);
FeatureGenerator worldgenerator = null;
if (state.getBlock() == Blocks.brown_mushroom)
{
worldgenerator = new WorldGenBigMushroom(Blocks.brown_mushroom_block);
}
else if (state.getBlock() == Blocks.red_mushroom)
{
worldgenerator = new WorldGenBigMushroom(Blocks.red_mushroom_block);
}
if (worldgenerator != null && worldgenerator.generate((WorldServer)worldIn, rand, pos))
{
return true;
}
else
{
worldIn.setState(pos, state, 3);
return false;
}
}
private boolean isTypeAt(World worldIn, BlockPos pos, WoodType type)
{
State iblockstate = worldIn.getState(pos);
return iblockstate.getBlock() instanceof BlockSapling && ((BlockSapling)iblockstate.getBlock()).getWoodType() == type;
}
private boolean isSameSaplingTypeIn(World worldIn, BlockPos pos, int xOff, int yOff, WoodType type)
{
return this.isTypeAt(worldIn, pos.add(xOff, 0, yOff), type) && this.isTypeAt(worldIn, pos.add(xOff + 1, 0, yOff), type) && this.isTypeAt(worldIn, pos.add(xOff, 0, yOff + 1), type) && this.isTypeAt(worldIn, pos.add(xOff + 1, 0, yOff + 1), type);
}
public void generateTree(AWorldServer worldIn, BlockPos pos, State state, Random rand)
{
WoodType type = state.getBlock() instanceof BlockSapling ? ((BlockSapling)state.getBlock()).getWoodType() : WoodType.OAK;
State log = type == WoodType.CHERRY ? Blocks.cherry_log.getState() : // .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.CHERRY) :
(type == WoodType.MAPLE ? Blocks.maple_log.getState() /* .withProperty(BlockNewLog.VARIANT, BlockPlanks.EnumType.MAPLE) */ : Blocks.oak_log.getState());
State leaves = type == WoodType.CHERRY ? Blocks.cherry_leaves.getState() :
(type == WoodType.MAPLE ? Blocks.maple_leaves.getState() : Blocks.oak_leaves.getState());
FeatureGenerator worldgenerator = (FeatureGenerator)(rand.chance(10) ? new WorldGenBigTree(true, log, leaves) : new WorldGenBaseTree(true, log, leaves));
int i = 0;
int j = 0;
boolean flag = false;
// leaves = leaves.withProperty(BlockLeaves.TYPE, worldIn.getLeavesGen());
switch (type)
{
case SPRUCE:
label114:
for (i = 0; i >= -1; --i)
{
for (j = 0; j >= -1; --j)
{
if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.SPRUCE))
{
worldgenerator = new WorldGenPine(false, rand.chance());
flag = true;
break label114;
}
}
}
if (!flag)
{
j = 0;
i = 0;
worldgenerator = new WorldGenTaiga2(true);
}
break;
case BIRCH:
worldgenerator = new WorldGenBirch(true, false);
break;
case TIAN:
worldgenerator = new WorldGenBigTree(true, Blocks.tian_log.getState(), Blocks.tian_leaves.getState())
.setHeightLimit(6, 20);
break;
case JUNGLE:
State iblockstate = Blocks.jungle_log.getState(); // .withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE);
State iblockstate1 = Blocks.jungle_leaves.getState(); // .withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE); // .withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false));
label269:
for (i = 0; i >= -1; --i)
{
for (j = 0; j >= -1; --j)
{
if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.JUNGLE))
{
worldgenerator = new WorldGenJungle(true, 10, 20, iblockstate, iblockstate1);
flag = true;
break label269;
}
}
}
if (!flag)
{
j = 0;
i = 0;
worldgenerator = new WorldGenBaseTree(true, rand.range(4, 10), iblockstate, iblockstate1, false);
}
break;
case ACACIA:
worldgenerator = new WorldGenSavanna(true);
break;
case DARK_OAK:
label390:
for (i = 0; i >= -1; --i)
{
for (j = 0; j >= -1; --j)
{
if (this.isSameSaplingTypeIn(worldIn, pos, i, j, WoodType.DARK_OAK))
{
worldgenerator = new WorldGenDarkOak(true);
flag = true;
break label390;
}
}
}
if (!flag)
{
return;
}
case OAK:
case CHERRY:
case MAPLE:
}
State iblockstate2 = Blocks.air.getState();
if (flag)
{
worldIn.setState(pos.add(i, 0, j), iblockstate2, 4);
worldIn.setState(pos.add(i + 1, 0, j), iblockstate2, 4);
worldIn.setState(pos.add(i, 0, j + 1), iblockstate2, 4);
worldIn.setState(pos.add(i + 1, 0, j + 1), iblockstate2, 4);
}
else
{
worldIn.setState(pos, iblockstate2, 4);
}
if (!worldgenerator.generate((WorldServer)worldIn, rand, pos.add(i, 0, j)))
{
if (flag)
{
worldIn.setState(pos.add(i, 0, j), state, 4);
worldIn.setState(pos.add(i + 1, 0, j), state, 4);
worldIn.setState(pos.add(i, 0, j + 1), state, 4);
worldIn.setState(pos.add(i + 1, 0, j + 1), state, 4);
}
else
{
worldIn.setState(pos, state, 4);
}
}
}
public void growGrass(AWorldServer worldIn, BlockPos pos, State state, Random rand)
{
BlockPos blockpos = pos.up();
for (int i = 0; i < 128; ++i)
{
BlockPos blockpos1 = blockpos;
int j = 0;
while (true)
{
if (j >= i / 16)
{
if (worldIn.getState(blockpos1).getBlock() == Blocks.air)
{
if (rand.chance(8))
{
BlockFlower.EnumFlowerType blockflower$enumflowertype = BIOMES[worldIn.getBiomeGenForCoords(blockpos1).id].pickRandomFlower(rand, blockpos1);
BlockFlower blockflower = blockflower$enumflowertype.getBlockType().getBlock();
State iblockstate = blockflower.getState().withProperty(blockflower.getTypeProperty(), blockflower$enumflowertype);
if (blockflower.canBlockStay(worldIn, blockpos1, iblockstate))
{
worldIn.setState(blockpos1, iblockstate, 3);
}
}
else
{
State iblockstate1 = Blocks.tallgrass.getState().withProperty(BlockTallGrass.TYPE, BlockTallGrass.EnumType.GRASS);
if (Blocks.tallgrass.canBlockStay(worldIn, blockpos1, iblockstate1))
{
worldIn.setState(blockpos1, iblockstate1, 3);
}
}
}
break;
}
blockpos1 = blockpos1.add(rand.zrange(3) - 1, (rand.zrange(3) - 1) * rand.zrange(3) / 2, rand.zrange(3) - 1);
if (worldIn.getState(blockpos1.down()).getBlock() != Blocks.grass || worldIn.getState(blockpos1).getBlock().isNormalCube())
{
break;
}
++j;
}
}
}
protected GenBiome createMutatedBiome(Biome base)
{
return new BiomeMutated(base, this);
}
public Class <? extends GenBiome > getBiomeClass()
{
return this.getClass();
}
public boolean isEqualTo(GenBiome biome)
{
return biome == this ? true : (biome == null ? false : this.getBiomeClass() == biome.getBiomeClass());
}
public Temperature getTempCategory()
{
return this.base.temperature < -12.0f ? Temperature.COLD : (this.base.temperature < 20.0f ? Temperature.MEDIUM : Temperature.WARM);
}
}

View file

@ -0,0 +1,17 @@
package server.biome;
import common.entity.types.EntityLiving;
import common.rng.RngItem;
public class RngSpawn extends RngItem {
public final Class<? extends EntityLiving> type;
public final int min;
public final int max;
public RngSpawn(Class<? extends EntityLiving> type, int weight, int min, int max) {
super(weight);
this.type = type;
this.min = min;
this.max = max;
}
}

View file

@ -0,0 +1,28 @@
package server.biome;
public enum Scaling {
VARYING_LOW(0.1F, 0.2F),
VARYING_MEDIUM(0.1F, 1.0F),
VARYING_CHAOTIC(1.0F, 2.0F),
SEA_VARYING(0.1F, 0.8F),
SEA_SHORE(0.0F, 0.025F),
SEA_POND(-0.2F, 0.1F),
SEA_SHALLOW(-0.5F, 0.0F),
SEA_MEDIUM(-1.0F, 0.1F),
SEA_DEEP(-1.8F, 0.1F),
PLAINS_LOW(0.125F, 0.05F),
PLAINS_MEDIUM(0.2F, 0.2F),
PLAINS_VARYING(0.2F, 0.3F),
HILLS_LOW(0.45F, 0.3F),
HILLS_MEDIUM(0.8F, 0.3F),
HILLS_LARGE(1.0F, 0.5F),
HILLS_PLATEAU(1.5F, 0.025F);
public final float depth;
public final float scale;
private Scaling(float depth, float scale) {
this.depth = depth;
this.scale = scale;
}
}

View file

@ -0,0 +1,5 @@
package server.biome;
public enum Temperature {
SEA, COLD, MEDIUM, WARM;
}

View file

@ -0,0 +1,111 @@
package server.clipboard;
public class BlockTransform {
private double m00, m01, m02, m03;
private double m10, m11, m12, m13;
private double m20, m21, m22, m23;
public BlockTransform() {
m00 = m11 = m22 = 1;
m01 = m02 = m03 = 0;
m10 = m12 = m13 = 0;
m20 = m21 = m23 = 0;
}
private BlockTransform(double xx, double yx, double zx, double tx,
double xy, double yy, double zy, double ty, double xz, double yz,
double zz, double tz) {
m00 = xx;
m01 = yx;
m02 = zx;
m03 = tx;
m10 = xy;
m11 = yy;
m12 = zy;
m13 = ty;
m20 = xz;
m21 = yz;
m22 = zz;
m23 = tz;
}
private BlockTransform concatenate(BlockTransform that) {
double n00 = m00 * that.m00 + m01 * that.m10 + m02 * that.m20;
double n01 = m00 * that.m01 + m01 * that.m11 + m02 * that.m21;
double n02 = m00 * that.m02 + m01 * that.m12 + m02 * that.m22;
double n03 = m00 * that.m03 + m01 * that.m13 + m02 * that.m23 + m03;
double n10 = m10 * that.m00 + m11 * that.m10 + m12 * that.m20;
double n11 = m10 * that.m01 + m11 * that.m11 + m12 * that.m21;
double n12 = m10 * that.m02 + m11 * that.m12 + m12 * that.m22;
double n13 = m10 * that.m03 + m11 * that.m13 + m12 * that.m23 + m13;
double n20 = m20 * that.m00 + m21 * that.m10 + m22 * that.m20;
double n21 = m20 * that.m01 + m21 * that.m11 + m22 * that.m21;
double n22 = m20 * that.m02 + m21 * that.m12 + m22 * that.m22;
double n23 = m20 * that.m03 + m21 * that.m13 + m22 * that.m23 + m23;
return new BlockTransform(
n00, n01, n02, n03,
n10, n11, n12, n13,
n20, n21, n22, n23);
}
public BlockTransform rotateY(int theta) {
double cot = dCos(theta);
double sit = dSin(theta);
return concatenate(
new BlockTransform(
cot, 0, sit, 0,
0, 1, 0, 0,
-sit, 0, cot, 0));
}
public BlockTransform scale(Vector vec) {
return concatenate(new BlockTransform(vec.getX(), 0, 0, 0, 0, vec.getY(), 0, 0, 0, 0, vec.getZ(), 0));
}
public Vector apply(Vector vector) {
return new Vector(
vector.getX() * m00 + vector.getY() * m01 + vector.getZ() * m02 + m03,
vector.getX() * m10 + vector.getY() * m11 + vector.getZ() * m12 + m13,
vector.getX() * m20 + vector.getY() * m21 + vector.getZ() * m22 + m23);
}
private static double dSin(int degrees) {
if (degrees % 90 == 0) {
degrees %= 360;
if (degrees < 0) {
degrees += 360;
}
switch (degrees) {
case 0:
return 0.0;
case 90:
return 1.0;
case 180:
return 0.0;
case 270:
return -1.0;
}
}
return Math.cos(Math.toRadians(degrees));
}
private static double dCos(int degrees) {
if (degrees % 90 == 0) {
degrees %= 360;
if (degrees < 0) {
degrees += 360;
}
switch (degrees) {
case 0:
return 1.0;
case 90:
return 0.0;
case 180:
return -1.0;
case 270:
return 0.0;
}
}
return Math.cos(Math.toRadians(degrees));
}
}

View file

@ -0,0 +1,33 @@
package server.clipboard;
import common.nbt.NBTTagCompound;
import common.tileentity.TileEntity;
import common.world.State;
public class ClipboardBlock {
private State state;
private NBTTagCompound nbt;
public ClipboardBlock(State state) {
this.state = state;
}
public ClipboardBlock(State data, TileEntity tile) {
this(data);
NBTTagCompound tag = new NBTTagCompound();
tile.writeToNBT(tag);
this.nbt = tag;
}
public State getState() {
return this.state;
}
public void setState(State state) {
this.state = state;
}
public NBTTagCompound getNbtData() {
return this.nbt;
}
}

View file

@ -0,0 +1,163 @@
package server.clipboard;
import java.util.Deque;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import common.block.Block;
import common.block.ITileEntityProvider;
import common.block.artificial.BlockDoor;
import common.block.tech.BlockRailBase;
import common.collect.Lists;
import common.init.Blocks;
import common.inventory.IInventory;
import common.tileentity.TileEntity;
import common.util.BlockPos;
import common.util.Vec3i;
import server.world.WorldServer;
public class ClipboardPlacer {
private static class BlockEntry {
private final BlockPos pos;
private final ClipboardBlock block;
private BlockEntry(BlockPos pos, ClipboardBlock block) {
this.pos = pos;
this.block = block;
}
}
private final WorldServer world;
private final List<BlockEntry> stage1 = Lists.newArrayList();
private final List<BlockEntry> stage2 = Lists.newArrayList();
private final List<BlockEntry> stage3 = Lists.newArrayList();
public ClipboardPlacer(WorldServer world) {
this.world = world;
}
public void setBlock(BlockPos location, ClipboardBlock block) {
Block type = block.getState().getBlock();
if (ReorderRegistry.shouldPlaceLast(type)) {
// Place torches, etc. last
this.stage2.add(new BlockEntry(location, block));
} else if (ReorderRegistry.shouldPlaceFinal(type)) {
// Place signs, reed, etc even later
this.stage3.add(new BlockEntry(location, block));
} else if (ReorderRegistry.shouldPlaceLast(this.world.getState(location).getBlock())) {
// Destroy torches, etc. first
this.setBlockQuirk(location, new ClipboardBlock(Blocks.air.getState()));
this.setBlockQuirk(location, block);
} else {
this.stage1.add(new BlockEntry(location, block));
}
}
private boolean setBlockQuirk(BlockPos location, ClipboardBlock block) {
Block existing = this.world.getState(location).getBlock();
if (existing instanceof ITileEntityProvider) {
TileEntity tile = this.world.getTileEntity(location);
if ((tile instanceof IInventory)) {
IInventory inv = (IInventory) tile;
int size = inv.getSizeInventory();
for (int i = 0; i < size; i++) {
inv.setInventorySlotContents(i, null);
}
}
}
else if (existing == Blocks.ice) {
this.world.setBlock(location, new ClipboardBlock(Blocks.air.getState())); // Ice turns until water so this has to be done first
}
return this.world.setBlock(location, block);
}
public void commit() {
// Iterator<Entry<BlockEntry>> iterator = Iterators.concat(this.stage1.iterator(), this.stage2.iterator());
// while (iterator.hasNext()) {
// Map.Entry<BlockPos, EditBlock> entry = iterator.next();
//
// }
for(BlockEntry entry : this.stage1) {
this.setBlockQuirk(entry.pos, entry.block);
}
this.stage1.clear();
for(BlockEntry entry : this.stage2) {
this.setBlockQuirk(entry.pos, entry.block);
}
this.stage2.clear();
final Set<BlockPos> blocks = new HashSet<BlockPos>();
final Map<BlockPos, ClipboardBlock> blockTypes = new HashMap<BlockPos, ClipboardBlock>();
for(BlockEntry entry : this.stage3) {
// final BlockPos pt = entry.getKey();
blocks.add(entry.pos);
blockTypes.put(entry.pos, entry.block);
}
this.stage3.clear();
while (!blocks.isEmpty()) {
BlockPos current = blocks.iterator().next();
if (!blocks.contains(current)) {
continue;
}
final Deque<BlockPos> walked = new LinkedList<BlockPos>();
while (true) {
walked.addFirst(current);
assert (blockTypes.containsKey(current));
final ClipboardBlock baseBlock = blockTypes.get(current);
final Block type = baseBlock.getState().getBlock();
if(type instanceof BlockDoor) {
if (baseBlock.getState().getValue(BlockDoor.HALF) == BlockDoor.EnumDoorHalf.LOWER) {
// Deal with lower door halves being attached to the floor AND the upper half
BlockPos upperBlock = current.add(0, 1, 0);
if (blocks.contains(upperBlock) && !walked.contains(upperBlock)) {
walked.addFirst(upperBlock);
}
}
}
else if(type instanceof BlockRailBase) {
// Here, rails are hardcoded to be attached to the block below them.
// They're also attached to the block they're ascending towards via BlockType.getAttachment.
BlockPos lowerBlock = current.add(0, -1, 0);
if (blocks.contains(lowerBlock) && !walked.contains(lowerBlock)) {
walked.addFirst(lowerBlock);
}
break;
}
final Vec3i attachment = ReorderRegistry.getAttachment(baseBlock.getState());
if (attachment == null) {
// Block is not attached to anything => we can place it
break;
}
current = current.add(attachment);
if (!blocks.contains(current)) {
// We ran outside the remaining set => assume we can place blocks on this
break;
}
if (walked.contains(current)) {
// Cycle detected => This will most likely go wrong, but there's nothing we can do about it.
break;
}
}
for(BlockPos pt : walked) {
this.setBlockQuirk(pt, blockTypes.get(pt));
blocks.remove(pt);
}
}
}
}

View file

@ -0,0 +1,230 @@
package server.clipboard;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import common.block.Block;
import common.block.artificial.BlockBed;
import common.block.artificial.BlockDoor;
import common.color.DyeColor;
import common.init.BlockRegistry;
import common.init.Blocks;
import common.init.WoodType;
import common.util.Facing;
import common.util.Vec3i;
import common.world.State;
public abstract class ReorderRegistry {
private static final Set<Block> PLACE_LAST = new HashSet<Block>();
private static final Set<Block> PLACE_FINAL = new HashSet<Block>();
private static final Map<State, Vec3i> STATE_ATTACH = new HashMap<State, Vec3i>();
private static final Map<Block, Vec3i> BLOCK_ATTACH = new HashMap<Block, Vec3i>();
public static boolean shouldPlaceLast(Block id) {
return PLACE_LAST.contains(id);
}
public static boolean shouldPlaceFinal(Block id) {
return PLACE_FINAL.contains(id) || id instanceof BlockDoor;
}
public static Vec3i getAttachment(State state) {
Vec3i direction = BLOCK_ATTACH.get(state.getBlock());
if (direction != null) return direction;
return STATE_ATTACH.get(state);
}
public static void register() {
for(WoodType wood : WoodType.values()) {
PLACE_LAST.add(BlockRegistry.getRegisteredBlock(wood.getName() + "_sapling"));
}
// PLACE_LAST.add(Blocks.bed);
for(DyeColor color : BlockBed.COLORS) {
PLACE_LAST.add(BlockRegistry.getRegisteredBlock(color.getName() + "_bed"));
}
PLACE_LAST.add(Blocks.golden_rail);
PLACE_LAST.add(Blocks.detector_rail);
PLACE_LAST.add(Blocks.tallgrass);
PLACE_LAST.add(Blocks.deadbush);
PLACE_LAST.add(Blocks.piston_head);
PLACE_LAST.add(Blocks.flower);
PLACE_LAST.add(Blocks.brown_mushroom);
PLACE_LAST.add(Blocks.red_mushroom_block);
PLACE_LAST.add(Blocks.torch);
PLACE_LAST.add(Blocks.fire);
PLACE_LAST.add(Blocks.soul_fire);
PLACE_LAST.add(Blocks.black_fire);
PLACE_LAST.add(Blocks.redstone);
PLACE_LAST.add(Blocks.wheat);
PLACE_LAST.add(Blocks.ladder);
PLACE_LAST.add(Blocks.rail);
PLACE_LAST.add(Blocks.lever);
PLACE_LAST.add(Blocks.stone_pressure_plate);
PLACE_LAST.add(Blocks.wooden_pressure_plate);
PLACE_LAST.add(Blocks.unlit_redstone_torch);
PLACE_LAST.add(Blocks.redstone_torch);
PLACE_LAST.add(Blocks.stone_button);
PLACE_LAST.add(Blocks.snow_layer);
PLACE_LAST.add(Blocks.portal);
PLACE_LAST.add(Blocks.repeater);
PLACE_LAST.add(Blocks.powered_repeater);
PLACE_LAST.add(Blocks.trapdoor);
PLACE_LAST.add(Blocks.vine);
PLACE_LAST.add(Blocks.waterlily);
PLACE_LAST.add(Blocks.soul_wart);
PLACE_LAST.add(Blocks.piston);
PLACE_LAST.add(Blocks.sticky_piston);
PLACE_LAST.add(Blocks.piston_head);
PLACE_LAST.add(Blocks.piston_extension);
PLACE_LAST.add(Blocks.cocoa);
PLACE_LAST.add(Blocks.tripwire_hook);
PLACE_LAST.add(Blocks.string);
PLACE_LAST.add(Blocks.flower_pot);
PLACE_LAST.add(Blocks.carrot);
PLACE_LAST.add(Blocks.potato);
PLACE_LAST.add(Blocks.wooden_button);
PLACE_LAST.add(Blocks.anvil); // becomes relevant with asynchronous placement
PLACE_LAST.add(Blocks.light_weighted_pressure_plate);
PLACE_LAST.add(Blocks.heavy_weighted_pressure_plate);
PLACE_LAST.add(Blocks.comparator);
PLACE_LAST.add(Blocks.powered_comparator);
PLACE_LAST.add(Blocks.activator_rail);
PLACE_LAST.add(Blocks.iron_trapdoor);
PLACE_LAST.add(Blocks.carpet);
PLACE_LAST.add(Blocks.double_plant);
PLACE_LAST.add(Blocks.daylight_detector_inverted);
// shouldPlaceLast.add(Blocks.daylight_detector);
PLACE_LAST.add(Blocks.blue_mushroom);
PLACE_LAST.add(Blocks.red_button);
}
static {
PLACE_FINAL.add(Blocks.sign);
PLACE_FINAL.add(Blocks.wall_sign);
PLACE_FINAL.add(Blocks.cactus);
PLACE_FINAL.add(Blocks.reeds);
PLACE_FINAL.add(Blocks.cake);
PLACE_FINAL.add(Blocks.piston_head);
PLACE_FINAL.add(Blocks.piston_extension);
PLACE_FINAL.add(Blocks.banner);
PLACE_FINAL.add(Blocks.wall_banner);
}
private static void addAttach(State state, Facing dir) {
STATE_ATTACH.put(state, dir.getDirectionVec());
}
private static void addAttach(Block block, Facing dir) {
BLOCK_ATTACH.put(block, dir.getDirectionVec());
}
private static void addCardinals(Block type, int west, int north, int east, int south) {
addAttach(type.getStateFromMeta(west), Facing.WEST);
addAttach(type.getStateFromMeta(north), Facing.NORTH);
addAttach(type.getStateFromMeta(east), Facing.EAST);
addAttach(type.getStateFromMeta(south), Facing.SOUTH);
}
static {
for(WoodType wood : WoodType.values()) {
addAttach(BlockRegistry.getRegisteredBlock(wood.getName() + "_sapling"), Facing.DOWN);
}
addAttach(Blocks.tallgrass, Facing.DOWN);
addAttach(Blocks.deadbush, Facing.DOWN);
for (int offset = 0; offset < 16; offset += 8) {
addAttach(Blocks.piston_head.getStateFromMeta(offset + 0), Facing.UP);
addAttach(Blocks.piston_head.getStateFromMeta(offset + 1), Facing.DOWN);
addCardinals(Blocks.piston_head, offset + 2, offset + 5, offset + 3, offset + 4);
}
addAttach(Blocks.flower, Facing.DOWN);
addAttach(Blocks.brown_mushroom, Facing.DOWN);
addAttach(Blocks.red_mushroom, Facing.DOWN);
for (Block blockId : new Block[] { Blocks.torch, Blocks.redstone_torch, Blocks.unlit_redstone_torch }) {
addAttach(blockId.getStateFromMeta(0), Facing.DOWN);
addAttach(blockId.getStateFromMeta(5), Facing.DOWN); // According to the wiki, this one is history. Keeping both, for now...
addCardinals(blockId, 4, 1, 3, 2);
}
addAttach(Blocks.redstone, Facing.DOWN);
addAttach(Blocks.wheat, Facing.DOWN);
addAttach(Blocks.sign, Facing.DOWN);
addCardinals(Blocks.ladder, 2, 5, 3, 4);
addCardinals(Blocks.wall_sign, 2, 5, 3, 4);
for (int offset = 0; offset < 16; offset += 8) {
addCardinals(Blocks.lever, offset + 4, offset + 1, offset + 3, offset + 2);
addAttach(Blocks.lever.getStateFromMeta(offset + 5), Facing.DOWN);
addAttach(Blocks.lever.getStateFromMeta(offset + 6), Facing.DOWN);
addAttach(Blocks.lever.getStateFromMeta(offset + 7), Facing.UP);
addAttach(Blocks.lever.getStateFromMeta(offset + 0), Facing.UP);
}
addAttach(Blocks.stone_pressure_plate, Facing.DOWN);
addAttach(Blocks.iron_door, Facing.DOWN);
addAttach(Blocks.wooden_pressure_plate, Facing.DOWN);
// redstone torches: see torches
for (int offset = 0; offset < 16; offset += 8) {
addCardinals(Blocks.stone_button, offset + 4, offset + 1, offset + 3, offset + 2);
addCardinals(Blocks.wooden_button, offset + 4, offset + 1, offset + 3, offset + 2);
addCardinals(Blocks.red_button, offset + 4, offset + 1, offset + 3, offset + 2);
}
addAttach(Blocks.stone_button.getStateFromMeta(0), Facing.UP);
addAttach(Blocks.stone_button.getStateFromMeta(5), Facing.DOWN);
addAttach(Blocks.wooden_button.getStateFromMeta(0), Facing.UP);
addAttach(Blocks.wooden_button.getStateFromMeta(5), Facing.DOWN);
addAttach(Blocks.red_button.getStateFromMeta(0), Facing.UP);
addAttach(Blocks.red_button.getStateFromMeta(5), Facing.DOWN);
addAttach(Blocks.cactus, Facing.DOWN);
addAttach(Blocks.reeds, Facing.DOWN);
addAttach(Blocks.cake, Facing.DOWN);
addAttach(Blocks.repeater, Facing.DOWN);
addAttach(Blocks.powered_repeater, Facing.DOWN);
for (int offset = 0; offset < 16; offset += 4) {
addCardinals(Blocks.trapdoor, offset + 0, offset + 3, offset + 1, offset + 2);
addCardinals(Blocks.iron_trapdoor, offset + 0, offset + 3, offset + 1, offset + 2);
}
addAttach(Blocks.pumpkin_stem, Facing.DOWN);
addAttach(Blocks.melon_stem, Facing.DOWN);
// vines are complicated, but I'll list the single-attachment variants anyway
addAttach(Blocks.vine.getStateFromMeta(0), Facing.UP);
addCardinals(Blocks.vine, 1, 2, 4, 8);
addAttach(Blocks.soul_wart, Facing.DOWN);
for (int offset = 0; offset < 16; offset += 4) {
addCardinals(Blocks.cocoa, offset + 0, offset + 1, offset + 2, offset + 3);
}
for (int offset = 0; offset < 16; offset += 4) {
addCardinals(Blocks.tripwire_hook, offset + 2, offset + 3, offset + 0, offset + 1);
}
addAttach(Blocks.string, Facing.DOWN);
addAttach(Blocks.flower_pot, Facing.DOWN);
addAttach(Blocks.carrot, Facing.DOWN);
addAttach(Blocks.potato, Facing.DOWN);
addAttach(Blocks.anvil, Facing.DOWN);
addAttach(Blocks.light_weighted_pressure_plate, Facing.DOWN);
addAttach(Blocks.heavy_weighted_pressure_plate, Facing.DOWN);
addAttach(Blocks.comparator, Facing.DOWN);
addAttach(Blocks.powered_comparator, Facing.DOWN);
addAttach(Blocks.carpet, Facing.DOWN);
addAttach(Blocks.double_plant, Facing.DOWN);
addAttach(Blocks.banner, Facing.DOWN);
addCardinals(Blocks.wall_banner, 4, 2, 5, 3);
addAttach(Blocks.oak_door, Facing.DOWN);
addAttach(Blocks.spruce_door, Facing.DOWN);
addAttach(Blocks.birch_door, Facing.DOWN);
addAttach(Blocks.jungle_door, Facing.DOWN);
addAttach(Blocks.acacia_door, Facing.DOWN);
addAttach(Blocks.dark_oak_door, Facing.DOWN);
addAttach(Blocks.cherry_door, Facing.DOWN);
addAttach(Blocks.maple_door, Facing.DOWN);
// Rails are hardcoded to be attached to the block below them.
// In addition to that, let's attach ascending rails to the block they're ascending towards.
for (int offset = 0; offset < 16; offset += 8) {
addCardinals(Blocks.golden_rail, offset + 3, offset + 4, offset + 2, offset + 5);
addCardinals(Blocks.detector_rail, offset + 3, offset + 4, offset + 2, offset + 5);
addCardinals(Blocks.rail, offset + 3, offset + 4, offset + 2, offset + 5);
addCardinals(Blocks.activator_rail, offset + 3, offset + 4, offset + 2, offset + 5);
}
addAttach(Blocks.blue_mushroom, Facing.DOWN);
}
}

View file

@ -0,0 +1,43 @@
package server.clipboard;
import java.util.function.Predicate;
public class Rotation {
private final RotationValue[] values;
private final boolean[] dirFlags = new boolean[16];
public Rotation(RotationValue[] values, Predicate<Integer> predicate) {
this.values = values;
for(int z = 0; z < 16; z++) {
if(predicate != null && !predicate.test(z)) {
this.dirFlags[z] = false;
continue;
}
boolean flag = false;
for(RotationValue value : values) {
if(value.getDirection() != null) {
flag = true;
break;
}
}
this.dirFlags[z] = flag;
}
}
public RotationValue[] getValues() {
return this.values;
}
public RotationValue getValue(int meta) {
for (RotationValue value : this.values) {
if (value.isSet(meta)) {
return value;
}
}
return null;
}
public boolean hasDirection(int meta) {
return this.dirFlags[meta & 15];
}
}

View file

@ -0,0 +1,129 @@
package server.clipboard;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import common.block.Block;
import common.block.BlockRotatedPillar;
import common.block.artificial.BlockDoor;
import common.block.artificial.BlockPortal;
import common.block.artificial.BlockQuartz;
import common.block.foliage.BlockLog;
import common.block.tech.BlockLever;
import common.block.tech.BlockRail;
import common.block.tech.BlockRailBase;
import common.block.tech.BlockRailDetector;
import common.block.tech.BlockRailPowered;
import common.collect.Lists;
import common.collect.Maps;
import common.properties.IProperty;
import common.properties.PropertyDirection;
import common.util.Facing;
import common.util.Vec3i;
import common.world.State;
public abstract class RotationRegistry {
private static final Map<Block, Rotation> MAP = new HashMap<Block, Rotation>();
public static void register() {
for(Block block : common.init.BlockRegistry.REGISTRY) {
for(IProperty<?> prop : block.getPropertyMap()) {
Predicate<Integer> predicate = null;
if(prop == BlockDoor.FACING) {
predicate = new Predicate<Integer>() {
@Override
public boolean test(Integer meta) {
return (meta & 8) == 0;
}
};
}
List<RotationValue> values = Lists.newArrayList();
Map<Object, Byte> map = Maps.newHashMap();
for(int z = 15; z >= 0; z--) {
State st = block.getStateFromMeta(z);
if(st.getProperties().containsKey(prop)) {
map.put(st.getProperties().get(prop), (byte)z);
}
}
byte mask = 0;
for(Object v : prop.getAllowedValues()) {
if(map.get(v) == null) {
continue;
}
mask |= map.get(v);
}
if(mask == 0) {
continue;
}
for(Object v : prop.getAllowedValues()) {
if(map.get(v) == null) {
continue;
}
Vec3i dv = null;
Facing.Axis axis = null;
if(prop instanceof PropertyDirection) {
dv = ((Facing)v).getDirectionVec();
}
else if(prop == BlockRotatedPillar.AXIS) {
axis = ((Facing.Axis)v);
}
else if(prop == BlockPortal.AXIS) {
axis = ((Facing.Axis)v);
}
else if(prop == BlockLog.LOG_AXIS) {
axis = ((BlockLog.EnumAxis)v).getAxis();
}
else if(prop == BlockQuartz.VARIANT) {
axis = ((BlockQuartz.EnumType)v).getAxis();
}
else if(prop == BlockLever.FACING) {
dv = ((BlockLever.EnumOrientation)v).getFacing().getDirectionVec();
}
else if(prop == BlockRail.SHAPE || prop == BlockRailDetector.SHAPE || prop == BlockRailPowered.SHAPE) {
dv = ((BlockRailBase.EnumRailDirection)v).getFacing().getDirectionVec();
}
// else if(prop == BlockDoor.HINGE) {
// dv = ((BlockDoor.EnumHingePosition)v) == BlockDoor.EnumHingePosition.LEFT ? new Vec3i(-1, 0, 0) : new Vec3i(1, 0, 0);
// }
if(axis != null) {
switch(axis) {
case X:
dv = new Vec3i(1, 0, 0);
break;
case Y:
dv = new Vec3i(0, 1, 0);
break;
case Z:
dv = new Vec3i(0, 0, 1);
break;
}
}
if(dv == null) {
continue;
}
values.add(new RotationValue(mask, (byte)(map.get(v) & mask), new Vector(dv.getX(), dv.getY(), dv.getZ())));
if(axis != null) {
values.add(new RotationValue(mask, (byte)(map.get(v) & mask), new Vector(-dv.getX(), -dv.getY(), -dv.getZ())));
}
}
if(!values.isEmpty()) {
int legacyId = common.init.BlockRegistry.getIdFromBlock(block);
Rotation state = new Rotation(values.toArray(new RotationValue[values.size()]), predicate);
// Log.CONFIG.debug("Block " + game.init.BlockRegistry.REGISTRY.getNameForObject(block) + "/" + legacyId + " mask = " + String.format("0x%x", mask));
// for(RotationValue value : values) {
// Log.CONFIG.debug(" meta " + value.data + " -> " + value.direction.toString());
// }
MAP.put(block, state);
}
}
}
}
public static Rotation getRotation(Block block) {
return MAP.get(block);
}
}

View file

@ -0,0 +1,25 @@
package server.clipboard;
public class RotationValue {
public final byte mask;
public final byte data;
public final Vector direction;
public RotationValue(byte mask, byte data, Vector direction) {
this.mask = mask;
this.data = data;
this.direction = direction;
}
public boolean isSet(int meta) {
return (meta & mask) == data;
}
public int set(int meta) {
return ((meta & ~mask) | data);
}
public Vector getDirection() {
return direction;
}
}

View file

@ -0,0 +1,802 @@
package server.clipboard;
public class Vector implements Comparable<Vector> {
public static final Vector ZERO = new Vector(0, 0, 0);
protected final double x, y, z;
public Vector(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
// /**
// * Construct an instance.
// *
// * @param x the X coordinate
// * @param y the Y coordinate
// * @param z the Z coordinate
// */
// public Vector(int x, int y, int z) {
// this.x = (double) x;
// this.y = (double) y;
// this.z = (double) z;
// }
// /**
// * Construct an instance.
// *
// * @param x the X coordinate
// * @param y the Y coordinate
// * @param z the Z coordinate
// */
// public Vector(float x, float y, float z) {
// this.x = (double) x;
// this.y = (double) y;
// this.z = (double) z;
// }
// /**
// * Copy another vector.
// *
// * @param other another vector to make a copy of
// */
// public Vector(Vector other) {
// this.x = other.x;
// this.y = other.y;
// this.z = other.z;
// }
/**
* Construct a new instance with X, Y, and Z coordinates set to 0.
*
* <p>One can also refer to a static {@link #ZERO}.</p>
*/
public Vector() {
this.x = 0;
this.y = 0;
this.z = 0;
}
/**
* Get the X coordinate.
*
* @return the x coordinate
*/
public double getX() {
return x;
}
/**
* Get the X coordinate rounded.
*
* @return the x coordinate
*/
public int getBlockX() {
return (int) Math.round(x);
}
// /**
// * Set the X coordinate.
// *
// * @param x the new X
// * @return a new vector
// */
// public Vector setX(double x) {
// return new Vector(x, y, z);
// }
// /**
// * Set the X coordinate.
// *
// * @param x the X coordinate
// * @return new vector
// */
// public Vector setX(int x) {
// return new Vector(x, y, z);
// }
/**
* Get the Y coordinate.
*
* @return the y coordinate
*/
public double getY() {
return y;
}
/**
* Get the Y coordinate rounded.
*
* @return the y coordinate
*/
public int getBlockY() {
return (int) Math.round(y);
}
// /**
// * Set the Y coordinate.
// *
// * @param y the new Y
// * @return a new vector
// */
// public Vector setY(double y) {
// return new Vector(x, y, z);
// }
// /**
// * Set the Y coordinate.
// *
// * @param y the new Y
// * @return a new vector
// */
// public Vector setY(int y) {
// return new Vector(x, y, z);
// }
/**
* Get the Z coordinate.
*
* @return the z coordinate
*/
public double getZ() {
return z;
}
/**
* Get the Z coordinate rounded.
*
* @return the z coordinate
*/
public int getBlockZ() {
return (int) Math.round(z);
}
// /**
// * Set the Z coordinate.
// *
// * @param z the new Z
// * @return a new vector
// */
// public Vector setZ(double z) {
// return new Vector(x, y, z);
// }
// /**
// * Set the Z coordinate.
// *
// * @param z the new Z
// * @return a new vector
// */
// public Vector setZ(int z) {
// return new Vector(x, y, z);
// }
// /**
// * Add another vector to this vector and return the result as a new vector.
// *
// * @param other the other vector
// * @return a new vector
// */
// public Vector add(Vector other) {
// return new Vector(x + other.x, y + other.y, z + other.z);
// }
// /**
// * Add another vector to this vector and return the result as a new vector.
// *
// * @param x the value to add
// * @param y the value to add
// * @param z the value to add
// * @return a new vector
// */
// public Vector add(double x, double y, double z) {
// return new Vector(this.x + x, this.y + y, this.z + z);
// }
// /**
// * Add another vector to this vector and return the result as a new vector.
// *
// * @param x the value to add
// * @param y the value to add
// * @param z the value to add
// * @return a new vector
// */
// public Vector add(int x, int y, int z) {
// return new Vector(this.x + x, this.y + y, this.z + z);
// }
// /**
// * Add a list of vectors to this vector and return the
// * result as a new vector.
// *
// * @param others an array of vectors
// * @return a new vector
// */
// public Vector add(Vector... others) {
// double newX = x, newY = y, newZ = z;
//
// for (Vector other : others) {
// newX += other.x;
// newY += other.y;
// newZ += other.z;
// }
//
// return new Vector(newX, newY, newZ);
// }
/**
* Subtract another vector from this vector and return the result
* as a new vector.
*
* @param other the other vector
* @return a new vector
*/
public Vector subtract(Vector other) {
return new Vector(x - other.x, y - other.y, z - other.z);
}
// /**
// * Subtract another vector from this vector and return the result
// * as a new vector.
// *
// * @param x the value to subtract
// * @param y the value to subtract
// * @param z the value to subtract
// * @return a new vector
// */
// public Vector subtract(double x, double y, double z) {
// return new Vector(this.x - x, this.y - y, this.z - z);
// }
// /**
// * Subtract another vector from this vector and return the result
// * as a new vector.
// *
// * @param x the value to subtract
// * @param y the value to subtract
// * @param z the value to subtract
// * @return a new vector
// */
// public Vector subtract(int x, int y, int z) {
// return new Vector(this.x - x, this.y - y, this.z - z);
// }
//
// /**
// * Subtract a list of vectors from this vector and return the result
// * as a new vector.
// *
// * @param others an array of vectors
// * @return a new vector
// */
// public Vector subtract(Vector... others) {
// double newX = x, newY = y, newZ = z;
//
// for (Vector other : others) {
// newX -= other.x;
// newY -= other.y;
// newZ -= other.z;
// }
//
// return new Vector(newX, newY, newZ);
// }
// /**
// * Multiply this vector by another vector on each component.
// *
// * @param other the other vector
// * @return a new vector
// */
// public Vector multiply(Vector other) {
// return new Vector(x * other.x, y * other.y, z * other.z);
// }
// /**
// * Multiply this vector by another vector on each component.
// *
// * @param x the value to multiply
// * @param y the value to multiply
// * @param z the value to multiply
// * @return a new vector
// */
// public Vector multiply(double x, double y, double z) {
// return new Vector(this.x * x, this.y * y, this.z * z);
// }
//
// /**
// * Multiply this vector by another vector on each component.
// *
// * @param x the value to multiply
// * @param y the value to multiply
// * @param z the value to multiply
// * @return a new vector
// */
// public Vector multiply(int x, int y, int z) {
// return new Vector(this.x * x, this.y * y, this.z * z);
// }
//
// /**
// * Multiply this vector by zero or more vectors on each component.
// *
// * @param others an array of vectors
// * @return a new vector
// */
// public Vector multiply(Vector... others) {
// double newX = x, newY = y, newZ = z;
//
// for (Vector other : others) {
// newX *= other.x;
// newY *= other.y;
// newZ *= other.z;
// }
//
// return new Vector(newX, newY, newZ);
// }
// /**
// * Perform scalar multiplication and return a new vector.
// *
// * @param n the value to multiply
// * @return a new vector
// */
// public Vector multiply(double n) {
// return new Vector(this.x * n, this.y * n, this.z * n);
// }
// /**
// * Perform scalar multiplication and return a new vector.
// *
// * @param n the value to multiply
// * @return a new vector
// */
// public Vector multiply(float n) {
// return new Vector(this.x * n, this.y * n, this.z * n);
// }
// /**
// * Perform scalar multiplication and return a new vector.
// *
// * @param n the value to multiply
// * @return a new vector
// */
// public Vector multiply(int n) {
// return new Vector(this.x * n, this.y * n, this.z * n);
// }
//
// /**
// * Divide this vector by another vector on each component.
// *
// * @param other the other vector
// * @return a new vector
// */
// public Vector divide(Vector other) {
// return new Vector(x / other.x, y / other.y, z / other.z);
// }
// /**
// * Divide this vector by another vector on each component.
// *
// * @param x the value to divide by
// * @param y the value to divide by
// * @param z the value to divide by
// * @return a new vector
// */
// public Vector divide(double x, double y, double z) {
// return new Vector(this.x / x, this.y / y, this.z / z);
// }
//
// /**
// * Divide this vector by another vector on each component.
// *
// * @param x the value to divide by
// * @param y the value to divide by
// * @param z the value to divide by
// * @return a new vector
// */
// public Vector divide(int x, int y, int z) {
// return new Vector(this.x / x, this.y / y, this.z / z);
// }
// /**
// * Perform scalar division and return a new vector.
// *
// * @param n the value to divide by
// * @return a new vector
// */
// public Vector divide(int n) {
// return new Vector(x / n, y / n, z / n);
// }
/**
* Perform scalar division and return a new vector.
*
* @param n the value to divide by
* @return a new vector
*/
public Vector divide(double n) {
return new Vector(x / n, y / n, z / n);
}
// /**
// * Perform scalar division and return a new vector.
// *
// * @param n the value to divide by
// * @return a new vector
// */
// public Vector divide(float n) {
// return new Vector(x / n, y / n, z / n);
// }
/**
* Get the length of the vector.
*
* @return length
*/
public double length() {
return Math.sqrt(x * x + y * y + z * z);
}
// /**
// * Get the length, squared, of the vector.
// *
// * @return length, squared
// */
// public double lengthSq() {
// return x * x + y * y + z * z;
// }
// /**
// * Get the distance between this vector and another vector.
// *
// * @param other the other vector
// * @return distance
// */
// public double distance(Vector other) {
// return Math.sqrt(Math.pow(other.x - x, 2) +
// Math.pow(other.y - y, 2) +
// Math.pow(other.z - z, 2));
// }
// /**
// * Get the distance between this vector and another vector, squared.
// *
// * @param other the other vector
// * @return distance
// */
// public double distanceSq(Vector other) {
// return Math.pow(other.x - x, 2) +
// Math.pow(other.y - y, 2) +
// Math.pow(other.z - z, 2);
// }
/**
* Get the normalized vector, which is the vector divided by its
* length, as a new vector.
*
* @return a new vector
*/
public Vector normalize() {
return divide(length());
}
/**
* Gets the dot product of this and another vector.
*
* @param other the other vector
* @return the dot product of this and the other vector
*/
public double dot(Vector other) {
return x * other.x + y * other.y + z * other.z;
}
// /**
// * Gets the cross product of this and another vector.
// *
// * @param other the other vector
// * @return the cross product of this and the other vector
// */
// public Vector cross(Vector other) {
// return new Vector(
// y * other.z - z * other.y,
// z * other.x - x * other.z,
// x * other.y - y * other.x
// );
// }
//
// /**
// * Checks to see if a vector is contained with another.
// *
// * @param min the minimum point (X, Y, and Z are the lowest)
// * @param max the maximum point (X, Y, and Z are the lowest)
// * @return true if the vector is contained
// */
// public boolean containedWithin(Vector min, Vector max) {
// return x >= min.x && x <= max.x && y >= min.y && y <= max.y && z >= min.z && z <= max.z;
// }
//
// /**
// * Checks to see if a vector is contained with another, comparing
// * using discrete comparisons, inclusively.
// *
// * @param min the minimum point (X, Y, and Z are the lowest)
// * @param max the maximum point (X, Y, and Z are the lowest)
// * @return true if the vector is contained
// */
// public boolean containedWithinBlock(Vector min, Vector max) {
// return getBlockX() >= min.getBlockX() && getBlockX() <= max.getBlockX()
// && getBlockY() >= min.getBlockY() && getBlockY() <= max.getBlockY()
// && getBlockZ() >= min.getBlockZ() && getBlockZ() <= max.getBlockZ();
// }
/**
* Clamp the Y component.
*
* @param min the minimum value
* @param max the maximum value
* @return a new vector
*/
public Vector clampY(int min, int max) {
return new Vector(x, Math.max(min, Math.min(max, y)), z);
}
// /**
// * Floors the values of all components.
// *
// * @return a new vector
// */
// public Vector floor() {
// return new Vector(Math.floor(x), Math.floor(y), Math.floor(z));
// }
//
// /**
// * Rounds all components up.
// *
// * @return a new vector
// */
// public Vector ceil() {
// return new Vector(Math.ceil(x), Math.ceil(y), Math.ceil(z));
// }
//
// /**
// * Rounds all components to the closest integer.
// *
// * <p>Components &lt; 0.5 are rounded down, otherwise up.</p>
// *
// * @return a new vector
// */
// public Vector round() {
// return new Vector(Math.floor(x + 0.5), Math.floor(y + 0.5), Math.floor(z + 0.5));
// }
// /**
// * Returns a vector with the absolute values of the components of
// * this vector.
// *
// * @return a new vector
// */
// public Vector positive() {
// return new Vector(Math.abs(x), Math.abs(y), Math.abs(z));
// }
// /**
// * Perform a 2D transformation on this vector and return a new one.
// *
// * @param angle in degrees
// * @param aboutX about which x coordinate to rotate
// * @param aboutZ about which z coordinate to rotate
// * @param translateX what to add after rotation
// * @param translateZ what to add after rotation
// * @return a new vector
// * @see AffineTransform another method to transform vectors
// */
// public Vector transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
// angle = Math.toRadians(angle);
// double x = this.x - aboutX;
// double z = this.z - aboutZ;
// double x2 = x * Math.cos(angle) - z * Math.sin(angle);
// double z2 = x * Math.sin(angle) + z * Math.cos(angle);
//
// return new Vector(
// x2 + aboutX + translateX,
// y,
// z2 + aboutZ + translateZ
// );
// }
//
// /**
// * Returns whether this vector is collinear with another vector.
// *
// * @param other the other vector
// * @return true if collinear
// */
// public boolean isCollinearWith(Vector other) {
// if (x == 0 && y == 0 && z == 0) {
// // this is a zero vector
// return true;
// }
//
// final double otherX = other.x;
// final double otherY = other.y;
// final double otherZ = other.z;
//
// if (otherX == 0 && otherY == 0 && otherZ == 0) {
// // other is a zero vector
// return true;
// }
//
// if ((x == 0) != (otherX == 0)) return false;
// if ((y == 0) != (otherY == 0)) return false;
// if ((z == 0) != (otherZ == 0)) return false;
//
// final double quotientX = otherX / x;
// if (!Double.isNaN(quotientX)) {
// return other.equals(multiply(quotientX));
// }
//
// final double quotientY = otherY / y;
// if (!Double.isNaN(quotientY)) {
// return other.equals(multiply(quotientY));
// }
//
// final double quotientZ = otherZ / z;
// if (!Double.isNaN(quotientZ)) {
// return other.equals(multiply(quotientZ));
// }
//
// throw new RuntimeException("This should not happen");
// }
// /**
// * Get this vector's pitch as used within the game.
// *
// * @return pitch in radians
// */
// public float toPitch() {
// double x = getX();
// double z = getZ();
//
// if (x == 0 && z == 0) {
// return getY() > 0 ? -90 : 90;
// } else {
// double x2 = x * x;
// double z2 = z * z;
// double xz = Math.sqrt(x2 + z2);
// return (float) Math.toDegrees(Math.atan(-getY() / xz));
// }
// }
// /**
// * Get this vector's yaw as used within the game.
// *
// * @return yaw in radians
// */
// public float toYaw() {
// double x = getX();
// double z = getZ();
//
// double t = Math.atan2(-x, z);
// double _2pi = 2 * Math.PI;
//
// return (float) Math.toDegrees(((t + _2pi) % _2pi));
// }
// /**
// * Create a new {@code BlockVector} using the given components.
// *
// * @param x the X coordinate
// * @param y the Y coordinate
// * @param z the Z coordinate
// * @return a new {@code BlockVector}
// */
// public static BlockVector toBlockPoint(double x, double y, double z) {
// return new BlockVector(
// Math.floor(x),
// Math.floor(y),
// Math.floor(z)
// );
// }
// /**
// * Create a new {@code BlockVector} from this vector.
// *
// * @return a new {@code BlockVector}
// */
// public BlockVector toBlockVector() {
// return new BlockVector(this);
// }
// /**
// * Creates a 2D vector by dropping the Y component from this vector.
// *
// * @return a new {@code Vector2D}
// */
// public Vector2D toVector2D() {
// return new Vector2D(x, z);
// }
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Vector)) {
return false;
}
Vector other = (Vector) obj;
return other.x == this.x && other.y == this.y && other.z == this.z;
}
@Override
public int compareTo(Vector other) {
if (other == null) {
throw new IllegalArgumentException("null not supported");
}
if (y != other.y) return Double.compare(y, other.y);
if (z != other.z) return Double.compare(z, other.z);
if (x != other.x) return Double.compare(x, other.x);
return 0;
}
@Override
public int hashCode() {
int hash = 7;
hash = 79 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32));
hash = 79 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32));
hash = 79 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32));
return hash;
}
@Override
public String toString() {
return x + ", " + y + ", " + z;
}
// /**
// * Gets the minimum components of two vectors.
// *
// * @param v1 the first vector
// * @param v2 the second vector
// * @return minimum
// */
// public static Vector getMinimum(Vector v1, Vector v2) {
// return new Vector(
// Math.min(v1.x, v2.x),
// Math.min(v1.y, v2.y),
// Math.min(v1.z, v2.z)
// );
// }
//
// /**
// * Gets the maximum components of two vectors.
// *
// * @param v1 the first vector
// * @param v2 the second vector
// * @return maximum
// */
// public static Vector getMaximum(Vector v1, Vector v2) {
// return new Vector(
// Math.max(v1.x, v2.x),
// Math.max(v1.y, v2.y),
// Math.max(v1.z, v2.z)
// );
// }
// /**
// * Gets the midpoint of two vectors.
// *
// * @param v1 the first vector
// * @param v2 the second vector
// * @return maximum
// */
// public static Vector getMidpoint(Vector v1, Vector v2) {
// return new Vector(
// (v1.x + v2.x) / 2,
// (v1.y + v2.y) / 2,
// (v1.z + v2.z) / 2
// );
// }
// public BlockPos toBlockPos() {
// return new BlockPos(x, y, z);
// }
}

View file

@ -0,0 +1,7 @@
package server.command;
public interface ArgCombiner<T> {
Object combine(T[] values);
Class<?> getTypeClass();
Class<T> getInputClass();
}

View file

@ -0,0 +1,33 @@
package server.command;
import java.util.Map;
public class Argument {
private final Parameter parameter;
private final int position;
private final String[] inputs;
private final Map<String, Object> values;
public Argument(Parameter parameter, int position, String[] inputs, Map<String, Object> values) {
this.parameter = parameter;
this.position = position;
this.inputs = inputs;
this.values = values;
}
public Parameter getParameter() {
return this.parameter;
}
public int getPosition() {
return this.position;
}
public String[] getInputs() {
return this.inputs;
}
public Map<String, Object> getValues() {
return this.values;
}
}

View file

@ -0,0 +1,100 @@
package server.command;
import java.util.Collection;
import java.util.List;
import common.collect.Lists;
public abstract class ArgumentParser {
public static String[][] splitString(String str) {
// if(str.isEmpty()) {
// return new String[0];
// }
int pos;
int last = 0;
boolean space = true;
boolean quote = false;
boolean escape = false;
char c;
String arg = "";
List<String> args = Lists.<String>newArrayList();
List<String[]> cmds = Lists.<String[]>newArrayList();
for(pos = 0; pos < str.length(); pos++) {
c = str.charAt(pos);
if(escape) {
escape = false;
switch(c) {
case '\\':
case ' ':
case '"':
case ';':
arg += c;
break;
default:
throw new RunException("Unbekannte Sequenz bei Zeichen %d: '\\%c'", pos + 1, c);
}
}
else if(c == '\\') {
space = false;
escape = true;
}
else if(c == '"') {
space = false;
quote = !quote;
last = pos;
}
else if(c == ' ' && !quote) {
if(!space) {
args.add(arg);
arg = "";
}
space = true;
}
else if(c == ';' && !quote) {
if(!space) {
args.add(arg);
arg = "";
}
space = true;
if(!args.isEmpty()) {
cmds.add(args.toArray(new String[args.size()]));
args.clear();
}
}
else {
space = false;
arg += c;
}
}
if(escape)
throw new RunException("Unvollständige Sequenz bei Zeichen %d", pos + 1);
if(quote)
throw new RunException("Nicht geschlossenes Anführungszeichen bei %d", last + 1);
if(!space)
args.add(arg);
if(!args.isEmpty()) {
cmds.add(args.toArray(new String[args.size()]));
args.clear();
}
return cmds.toArray(new String[cmds.size()][]);
}
private final String name;
public ArgumentParser(String name) {
this.name = name;
}
public abstract Object parse(CommandEnvironment env, String input);
public abstract Object getDefault(CommandEnvironment env);
public abstract Collection<String> getCompletions(CommandEnvironment env);
public abstract Class<?> getTypeClass(boolean required);
public final String getName() {
return this.name;
}
public final String toString() {
return this.name;
}
}

View file

@ -0,0 +1,411 @@
package server.command;
import java.util.List;
import java.util.Map;
import java.util.Set;
import common.collect.Lists;
import common.collect.Maps;
import common.collect.Sets;
public class ArgumentSplitter {
private final String command;
private final Map<String, Argument> arguments;
private final CommandEnvironment env;
protected ArgumentSplitter(Map<String, Argument> arguments, String command, CommandEnvironment env) {
this.arguments = arguments;
this.command = command;
this.env = env;
}
private static <T> String joinArgs(Iterable<T> iter) {
StringBuilder sb = new StringBuilder("'");
for(T obj : iter) {
if(sb.length() > 1)
sb.append("', '");
sb.append(String.valueOf(obj));
}
return sb.append("'").toString();
}
public static ArgumentSplitter parseArgs(CommandEnvironment env, String str, String[] argv, CachedExecutable cached) {
Map<String, Parameter> parameters = cached.getParameters();
List<Parameter> positionals = Lists.newArrayList(cached.getPositionals());
// String[] argv = ArgumentParser.splitString(str);
Map<String, Argument> args = Maps.newHashMap();
int ppos = 0;
boolean parse = true;
for(int z = 1; z < argv.length; z++) {
String arg = argv[z];
Parameter param = null;
boolean pos = false;
if(parse && arg.equals("--")) {
parse = false;
continue;
}
else if(parse && (arg.startsWith("--") || (arg.startsWith("-") && arg.length() == 2))) {
param = parameters.get(arg.substring(arg.startsWith("--") ? 2 : 1));
if(param != null && param.isPositional() && !args.containsKey(param.getName())) {
for(int n = 0; n < positionals.size(); n++) {
if(param == positionals.get(n)) {
positionals.remove(n);
break;
}
}
}
}
else if(ppos < positionals.size()) {
param = positionals.get(ppos++);
pos = true;
}
else {
throw new RunException("Position %d: Parameter '%s' ist überflüssig", z, arg);
}
if(param == null)
throw new RunException("Position %d: Argument '%s' ist unbekannt", z, arg);
if(args.containsKey(param.getName()))
throw new RunException("Position %d: Parameter '%s' mehrfach angegeben", z, param.getName());
int nargs = param.getParsers().size();
// if(!pos)
// z += 1;
if(z + (pos ? 0 : 1) + nargs > argv.length)
if(nargs == 1 && param.getName().equals(param.getParsers().get(0).getName()))
throw new RunException("Position %d: Argument '%s' benötigt einen Parameter", z, param.getName());
else
throw new RunException("Position %d: Argument '%s' benötigt %d Parameter (%s)", z, param.getName(), nargs,
joinArgs(param.getParsers()));
Map<String, Object> params = Maps.newHashMapWithExpectedSize(nargs);
String[] inputs = new String[nargs + (pos ? 0 : 1)];
int apos = 0;
for(int n = pos ? 0 : 1; n < nargs + (pos ? 0 : 1); n++) {
String par = inputs[n] = argv[z + n];
ArgumentParser parser = param.getParsers().get(apos);
if(parse && (par.startsWith("--") || (par.startsWith("-") && par.length() == 2)))
if(nargs == 1 && param.getName().equals(parser.getName()))
throw new RunException("Position %d: Argument '%s': '%s' als Parameter verwendet", z + n, param.getName(), par);
else
throw new RunException("Position %d: Argument '%s': '%s' als Parameter '%s' (#%d) verwendet", z + n,
param.getName(), par, parser.getName(), apos + 1);
try {
params.put(parser.getName(), parser.parse(env, par));
}
catch(Throwable e) {
if(nargs == 1 && param.getName().equals(parser.getName()))
throw new RunException(e, "Position %d: Argument '%s': Parameter konnte nicht interpretiert werden", z + n,
param.getName());
else
throw new RunException(e, "Position %d: Argument '%s': Parameter '%s' (#%d) konnte nicht interpretiert werden", z + n,
param.getName(), parser.getName(), apos + 1);
}
apos += 1;
}
if(!pos)
inputs[0] = arg;
args.put(param.getName(), new Argument(param, z, inputs, params));
z += nargs - (pos ? 1 : 0);
}
for(Parameter param : parameters.values()) {
if(!args.containsKey(param.getName())) {
if(param.isRequired()) {
for(ArgumentParser parser : param.getParsers()) {
if(parser.getDefault(env) == null)
throw new RunException("Argument '%s' muss angegeben werden", param.getName());
}
}
else if(param.getParsers().isEmpty()) {
continue;
}
Map<String, Object> params = Maps.newHashMapWithExpectedSize(param.getParsers().size());
for(ArgumentParser parser : param.getParsers()) {
params.put(parser.getName(), parser.getDefault(env));
}
args.put(param.getName(), new Argument(param, -1, null, params));
}
}
return new ArgumentSplitter(args, str, env);
}
private static Iterable<String> getParam(CommandEnvironment env, String[] argv, CachedExecutable cached) {
Map<String, Parameter> parameters = cached.getParameters();
List<Parameter> positionals = Lists.newArrayList(cached.getPositionals());
Set<String> args = Sets.newHashSet();
int ppos = 0;
boolean parse = true;
for(int z = 1; z < argv.length; z++) {
String arg = argv[z];
Parameter param = null;
boolean pos = false;
if(z == argv.length - 1) {
if(ppos < positionals.size()) {
param = positionals.get(ppos);
if(param.getParsers().isEmpty()) // np
return null;
return param.getParsers().get(0).getCompletions(env);
}
else {
return null;
}
}
else if(parse && arg.equals("--")) {
parse = false;
continue;
}
else if(parse && (arg.startsWith("--") || (arg.startsWith("-") && arg.length() == 2))) {
param = parameters.get(arg.substring(arg.startsWith("--") ? 2 : 1));
if(param != null && param.isPositional() && !args.contains(param.getName())) {
for(int n = 0; n < positionals.size(); n++) {
if(param == positionals.get(n)) {
positionals.remove(n);
break;
}
}
}
}
else if(ppos < positionals.size()) {
param = positionals.get(ppos++);
pos = true;
}
else {
return null;
}
if(param == null || args.contains(param.getName()))
return null;
int nargs = param.getParsers().size();
// if(z + (pos ? 0 : 1) + nargs > argv.length - 1) {
// return param.getParsers().get(argv.length - z).getCompletions(env);
// }
int apos = 0;
for(int n = pos ? 0 : 1; n < nargs + (pos ? 0 : 1); n++) {
if(z + n == argv.length - 1)
return param.getParsers().get(apos).getCompletions(env);
String par = argv[z + n];
if(parse && (par.startsWith("--") || (par.startsWith("-") && par.length() == 2)))
return null;
apos += 1;
}
args.add(param.getName());
z += nargs - (pos ? 1 : 0);
}
return null;
}
public static Iterable<String> parseComplete(CommandEnvironment env, String[] argv, CachedExecutable cached, String last) {
Iterable<String> comp = getParam(env, argv, cached);
if(comp == null /* || comp.length == 0 */ ) {
Set<String> params = Sets.newTreeSet();
boolean all = last.startsWith("--");
for(String param : cached.getParameters().keySet()) {
if(all || param.length() == 1)
params.add(param.length() == 1 ? "-" + param : ("--" + param));
}
return params;
}
return comp;
}
// public ScriptArg getArg(String name) {
// return this.arguments.get(name);
// }
public boolean hasArg(String name) {
return this.arguments.containsKey(name);
}
// public boolean has(String name, String par) {
// return this.arguments.containsKey(name) && this.arguments.get(name).getValues().containsKey(par);
// }
// public boolean has(String name) {
// return this.has(name, name);
// }
// public <T> T getDefault(String name, String par, T def) {
// ScriptArg arg = this.arguments.get(name);
// if(arg == null)
// return def;
// Object value = arg.getValues().get(par);
// return value == null ? def : (T)value;
// }
//
// public <T> T getDefault(String name, T def) {
// return this.getDefault(name, name, def);
// }
//
// public <T> T getUnchecked(String name, String par) {
// return this.getDefault(name, par, null);
// }
public <T> T getUnchecked(String name, String par) {
Argument arg = this.arguments.get(name);
if(arg == null)
return null;
Object value = arg.getValues().get(par);
return value == null ? null : (T)value;
}
// public <T> T getUnchecked(String name) {
// return this.getDefault(name, null);
// }
//
// public boolean getBool(String name, boolean def) {
// return this.getDefault(name, def);
// }
//
// public boolean getBool(String name) {
// return this.getUnchecked(name);
// }
//
// public <T extends Enum<?>> T getEnum(String name, T def) {
// return this.getDefault(name, def);
// }
//
// public <T extends Enum<?>> T getEnum(String name) {
// return this.getUnchecked(name);
// }
//
// public int getInt(String name, int def) {
// return this.getDefault(name, def);
// }
//
// public int getInt(String name) {
// return this.getUnchecked(name);
// }
//
// public long getLong(String name, long def) {
// return this.getDefault(name, def);
// }
//
// public long getLong(String name) {
// return this.getUnchecked(name);
// }
//
// public double getDouble(String name, double def) {
// return this.getDefault(name, def);
// }
//
// public double getDouble(String name) {
// return this.getUnchecked(name);
// }
//
// public String getString(String name, String def) {
// return this.getDefault(name, def);
// }
//
// public String getString(String name) {
// return this.getUnchecked(name);
// }
//
// public String[] getStrings(String name, String[] def) {
// return this.getDefault(name, def);
// }
//
// public String[] getStrings(String name) {
// return this.getUnchecked(name);
// }
//
// public Entity getEntity(String name, Entity def) {
// return this.getDefault(name, def);
// }
//
// public Entity getEntity(String name) {
// return this.getUnchecked(name);
// }
//
// public EntityLiving getLiving(String name, EntityLiving def) {
// return this.getDefault(name, def);
// }
//
// public EntityLiving getLiving(String name) {
// return this.getUnchecked(name);
// }
//
// public EntityNPC getNpc(String name, EntityNPC def) {
// return this.getDefault(name, def);
// }
//
// public EntityNPC getNpc(String name) {
// return this.getUnchecked(name);
// }
//
// public Block getBlock(String name, Block def) {
// return this.getDefault(name, def);
// }
//
// public Block getBlock(String name) {
// return this.getUnchecked(name);
// }
//
// public State getState(String name, State def) {
// return this.getDefault(name, def);
// }
//
// public State getState(String name) {
// return this.getUnchecked(name);
// }
//
// public Item getItem(String name, Item def) {
// return this.getDefault(name, def);
// }
//
// public Item getItem(String name) {
// return this.getUnchecked(name);
// }
//
// public ItemStack getStack(String name, ItemStack def) {
// return this.getDefault(name, def);
// }
//
// public ItemStack getStack(String name) {
// return this.getUnchecked(name);
// }
//
// public BlockPos getColumnPos(String name, BlockPos def) {
// return this.hasArg(name) ? this.getColumnPos(name) : def;
// }
//
// public BlockPos getColumnPos(String name) {
// return new BlockPos(this.getUnchecked(name, "x"), 0, this.getUnchecked(name, "z"));
// }
//
// public BlockPos getBlockPos(String name, BlockPos def) {
// return this.hasArg(name) ? this.getBlockPos(name) : def;
// }
//
// public BlockPos getBlockPos(String name) {
// return new BlockPos(this.getUnchecked(name, "x"), this.getUnchecked(name, "y"), this.getUnchecked(name, "z"));
// }
//
// public WorldPos getWorldPos(String name, WorldPos def) {
// return this.hasArg(name) ? this.getWorldPos(name) : def;
// }
//
// public WorldPos getWorldPos(String name) {
// return new WorldPos(this.getUnchecked(name, "x"), this.getUnchecked(name, "y"), this.getUnchecked(name, "z"),
// this.getUnchecked(name, "dim"));
// }
//
// public Vec3 getVector2D(String name, Vec3 def) {
// return this.hasArg(name) ? this.getVector2D(name) : def;
// }
//
// public Vec3 getVector2D(String name) {
// return new Vec3(this.getUnchecked(name, "x"), 0.0, this.getUnchecked(name, "z"));
// }
//
// public Vec3 getVector(String name, Vec3 def) {
// return this.hasArg(name) ? this.getVector(name) : def;
// }
//
// public Vec3 getVector(String name) {
// return new Vec3(this.getUnchecked(name, "x"), this.getUnchecked(name, "y"), this.getUnchecked(name, "z"));
// }
//
// public WorldServer getWorld(String name) {
// return this.getUnchecked(name);
// }
//
// public NBTTagCompound getTag(String name) {
// return this.getUnchecked(name);
// }
}

View file

@ -0,0 +1,11 @@
package server.command;
public class BooleanParser extends EnumParser<Boolean> {
public BooleanParser(String name, Boolean def) {
super(name, Boolean.class, def, true, false);
}
public Class<?> getTypeClass(boolean required) {
return this.hasDefault() || required ? boolean.class : Boolean.class;
}
}

View file

@ -0,0 +1,93 @@
package server.command;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import common.collect.Lists;
import common.collect.Maps;
public class CachedExecutable {
private final Executable executable;
private final String name;
private final Map<String, Parameter> parameters;
private final List<Parameter> positionals;
private final Method method;
protected CachedExecutable(Executable executable, Map<String, Parameter> parameters, List<Parameter> positionals, Method method) {
this.executable = executable;
this.parameters = parameters;
this.positionals = positionals;
this.name = executable.getName();
this.method = method;
}
public static CachedExecutable cacheExecutable(Executable executable) {
Map<String, Parameter> parameters = Maps.newTreeMap();
Map<String, Parameter> params = executable.getParameters();
parameters.putAll(params);
Parameter[] positions = new Parameter[parameters.size()];
int pos = -1;
for(Parameter param : params.values()) {
if(param.isPositional()) {
positions[param.getPosition()] = param;
pos = param.getPosition() > pos ? param.getPosition() : pos;
}
if(param.hasShortName())
parameters.put("" + param.getShortName(), param);
}
List<Parameter> positionals = Lists.newArrayList();
for(int z = 0; z <= pos; z++) {
if(positions[z] == null)
throw new NullPointerException("positions[" + z + "]");
positionals.add(positions[z]);
}
List<Class<?>> classes = Lists.newArrayList(CommandEnvironment.class, Executor.class);
for(Parameter param : executable.getParamList()) {
ArgCombiner<?> combiner = param.getCombiner();
if(combiner != null) {
classes.add(combiner.getTypeClass());
continue;
}
if(param.getParsers().isEmpty()) {
classes.add(boolean.class);
continue;
}
for(ArgumentParser parser : param.getParsers()) {
classes.add(parser.getTypeClass(param.isRequired()));
}
}
Method method;
try {
method = executable.getClass().getDeclaredMethod("exec", classes.toArray(new Class<?>[classes.size()]));
}
catch(NoSuchMethodException e) {
throw new RuntimeException(e);
}
return new CachedExecutable(executable, parameters, positionals, method);
}
public Executable getExecutable() {
return this.executable;
}
public Method getMethod() {
return this.method;
}
public Map<String, Parameter> getParameters() {
return this.parameters;
}
public List<Parameter> getPositionals() {
return this.positionals;
}
public String getName() {
return this.name;
}
public String toString() {
return this.name;
}
}

View file

@ -0,0 +1,27 @@
package server.command;
import common.color.DyeColor;
public class ColorParser extends IntParser {
public ColorParser(String name, Integer def, Object ... completions) {
super(name, true, def, null, null, completions);
}
public ColorParser(String name, Integer def) {
this(name, def, (Object[])DyeColor.values());
}
public Integer parse(CommandEnvironment env, String input) {
if(input.startsWith("#")) {
input = input.substring(1);
}
else {
DyeColor color = DyeColor.getByString(input);
if(color != null)
return color.getColor();
}
if(input.length() != 6)
throw new RunException("Der Farbcode muss 6 Stellen haben, habe %d ('%s')", input.length(), input);
return super.parse(env, input);
}
}

View file

@ -0,0 +1,220 @@
package server.command;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import common.collect.Lists;
import common.collect.Maps;
import common.util.CharValidator;
import common.util.Vec3;
import common.world.World;
import server.command.DoubleParser.DefType;
public abstract class Command implements Executable {
private final String name;
private final Map<String, Parameter> parameters = Maps.newHashMap();
private final List<Parameter> argList = Lists.newArrayList();
private int parPos = 0;
private boolean parReq = true;
protected Command(String name) {
this.name = name;
}
protected Command setParamsOptional() {
this.parReq = false;
return this;
}
protected Command addParameter(String name, ArgCombiner<?> combiner, ArgumentParser ... parsers) {
Parameter param = new Parameter(name, (char)0, this.parPos++, this.parReq, Lists.newArrayList(parsers), combiner);
this.parameters.put(name, param);
this.argList.add(param);
return this;
}
protected Command addParameter(String name, char shortName, ArgCombiner<?> combiner, ArgumentParser ... parsers) {
Parameter param = new Parameter(name, shortName, -1, false, Lists.newArrayList(parsers), combiner);
this.parameters.put(name, param);
this.argList.add(param);
return this;
}
protected Command addParameter(String name, ArgumentParser ... parsers) {
return this.addParameter(name, null, parsers);
}
protected Command addParameter(String name, char shortName, ArgumentParser ... parsers) {
return this.addParameter(name, shortName, null, parsers);
}
protected Command addParameter(ArgumentParser parser) {
return this.addParameter(parser.getName(), parser);
}
protected Command addParameter(char shortName, ArgumentParser parser) {
return this.addParameter(parser.getName(), shortName, parser);
}
protected Command addVector(String name, boolean defaulted, boolean centered) {
return this.addParameter(name, new ArgCombiner<Double>() {
public Vec3 combine(Double[] values) {
return new Vec3(values[0], values[1], values[2]);
}
public Class<?> getTypeClass() {
return Vec3.class;
}
public Class<Double> getInputClass() {
return Double.class;
}
},
new DoubleParser("x", defaulted ? DefType.X : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered),
new DoubleParser("y", defaulted ? DefType.Y : null, (double)(-World.MAX_SIZE_Y), (double)World.MAX_SIZE_Y, false),
new DoubleParser("z", defaulted ? DefType.Z : null, (double)(-World.MAX_SIZE), (double)World.MAX_SIZE, centered));
}
protected Command addWorld(String name, boolean defaulted) {
return this.addParameter(new WorldParser(name, false, defaulted));
}
protected Command addDimension(String name, boolean defaulted) {
return this.addParameter(new DimensionParser(name, defaulted));
}
protected Command addInt(String name, char shortName, int min, int max, int def) {
return this.addParameter(shortName, new IntParser(name, false, def, min, max, def));
}
protected Command addInt(String name, int min, int max, int def) {
return this.addParameter(new IntParser(name, false, def, min, max, def));
}
protected Command addDouble(String name, char shortName, double min, double max, double def) {
return this.addParameter(shortName, new DoubleParser(name, def, min, max, false, def));
}
protected Command addDouble(String name, double min, double max, double def) {
return this.addParameter(new DoubleParser(name, def, min, max, false, def));
}
protected Command addInt(String name, char shortName, int min, int max) {
return this.addParameter(shortName, new IntParser(name, false, null, min, max));
}
protected Command addInt(String name, int min, int max) {
return this.addParameter(new IntParser(name, false, null, min, max));
}
protected Command addDouble(String name, char shortName, double min, double max) {
return this.addParameter(shortName, new DoubleParser(name, null, min, max, false));
}
protected Command addDouble(String name, double min, double max) {
return this.addParameter(new DoubleParser(name, null, min, max, false));
}
protected Command addFlag(String name, char shortName) {
return this.addParameter(name, shortName);
}
// protected ScriptExecutable addFlag(String name) {
// return this.addParameter(name, name.charAt(0));
// }
protected <T> Command addEnum(String name, T def, Class<T> clazz, T ... values) {
return this.addParameter(new EnumParser<T>(name, clazz, def, values));
}
protected <T> Command addEnum(String name, Class<T> clazz, T ... values) {
return this.addEnum(name, null, clazz, values);
}
protected <T> Command addEnum(String name, T def, Class<T> clazz, Collection<T> values) {
return this.addEnum(name, def, clazz, values.toArray((T[])Array.newInstance(clazz, values.size())));
}
protected <T> Command addEnum(String name, Class<T> clazz, Collection<T> values) {
return this.addEnum(name, null, clazz, values);
}
protected <T> Command addEnum(String name, char shortName, T def, Class<T> clazz, T ... values) {
return this.addParameter(shortName, new EnumParser<T>(name, clazz, def, values));
}
protected Command addTag(String name) {
return this.addParameter(new TagParser(name, null));
}
protected Command addTag(String name, char shortName) {
return this.addParameter(shortName, new TagParser(name, null));
}
protected Command addPlayer(String name, boolean defaulted) {
return this.addParameter(new PlayerParser(name, defaulted));
}
protected Command addPlayerEntity(String name, boolean defaulted) {
return this.addParameter(new PlayerEntityParser(name, defaulted));
}
protected Command addEntity(String name, boolean defaulted) {
return this.addParameter(new EntityParser(name, defaulted, false));
}
protected Command addEntity(String name, char shortName, boolean defaulted) {
return this.addParameter(shortName, new EntityParser(name, defaulted, false));
}
protected Command addEntityList(String name, boolean defaulted) {
return this.addParameter(new EntityListParser(name, defaulted, false));
}
protected Command addEntityList(String name, char shortName, boolean defaulted) {
return this.addParameter(shortName, new EntityListParser(name, defaulted, false));
}
protected Command addLivingEntity(String name, boolean defaulted) {
return this.addParameter(new EntityParser(name, defaulted, true));
}
protected Command addLivingEntityList(String name, boolean defaulted) {
return this.addParameter(new EntityListParser(name, defaulted, true));
}
protected Command addString(String name, boolean allowEmpty, Object ... completions) {
return this.addParameter(new StringParser(name, null, allowEmpty, null, null, null, completions));
}
protected Command addString(String name, boolean allowEmpty, StringCompleter completer) {
return this.addParameter(new StringParser(name, null, allowEmpty, null, null, null, completer));
}
protected Command addString(String name, String def, boolean allowEmpty, Object ... completions) {
return this.addParameter(new StringParser(name, def, allowEmpty, null, null, null, completions));
}
protected Command addString(String name, String def, boolean allowEmpty, StringCompleter completer) {
return this.addParameter(new StringParser(name, def, allowEmpty, null, null, null, completer));
}
protected Command addString(String name, boolean allowEmpty, Integer min, Integer max, CharValidator validator) {
return this.addParameter(new StringParser(name, null, allowEmpty, min, max, validator));
}
public Map<String, Parameter> getParameters() {
return this.parameters;
}
public List<Parameter> getParamList() {
return this.argList;
}
public String getName() {
return this.name;
}
}

View file

@ -0,0 +1,285 @@
package server.command;
import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import common.collect.Lists;
import common.collect.Maps;
import common.collect.Sets;
import common.color.TextColor;
import common.log.Log;
import server.Server;
import server.command.commands.CommandAdmin;
import server.command.commands.CommandHelp;
import server.command.commands.CommandKick;
import server.command.commands.CommandMessage;
import server.command.commands.CommandMilk;
import server.command.commands.CommandOfflinetp;
import server.command.commands.CommandPasswd;
import server.command.commands.CommandPlayers;
import server.command.commands.CommandPotion;
import server.command.commands.CommandRegister;
import server.command.commands.CommandRemove;
import server.command.commands.CommandRevoke;
import server.command.commands.CommandSave;
import server.command.commands.CommandShutdown;
import server.command.commands.CommandSpawn;
import server.command.commands.CommandTele;
import server.command.commands.CommandTime;
import server.command.commands.CommandTp;
import server.command.commands.CommandWarp;
import server.command.commands.CommandWeather;
import server.command.commands.CommandWorld;
public class CommandEnvironment {
private final Server server;
private final Map<String, CachedExecutable> executables = Maps.newTreeMap();
private final List<PatternReplacer> replacers = Lists.newArrayList();
private final Set<String> builtins = Sets.newHashSet();
private final Map<String, String> variables = Maps.newHashMap();
private Executor currentExecutor;
private Object previousOutput;
public CommandEnvironment(Server server) {
this.server = server;
this.registerDefaults();
}
public void registerExecutable(Executable executable) {
CachedExecutable cached = CachedExecutable.cacheExecutable(executable);
if(this.executables.containsKey(cached.getName()))
throw new IllegalStateException("Befehl " + cached.getName() + " ist bereits registriert");
this.executables.put(cached.getName(), cached);
this.registerReplacer(cached.getName(), new Function<String, String>() {
public String apply(String str) {
Object o;
try {
o = CommandEnvironment.this.execute(str, false);
}
catch(Throwable e) {
throw new RunException(e, "Variable konnte nicht ersetzt werden: '%s' konnte nicht ausgeführt werden", str);
}
if(o == null)
throw new RunException("Variable konnte nicht ersetzt werden: null von '%s' zurückgegeben", str);
return o.toString();
}
});
}
public void registerReplacer(String var, Function<String, String> function) {
if(this.builtins.contains(var))
throw new IllegalStateException("Variable " + var + " ist bereits registriert");
this.replacers.add(new PatternReplacer(var, true, function));
this.builtins.add(var);
}
public void registerVariable(String var, Variable variable) {
if(this.builtins.contains(var))
throw new IllegalStateException("Variable " + var + " ist bereits registriert");
this.replacers.add(new PatternReplacer(var, false, new Function<String, String>() {
public String apply(String ign) {
return variable.get();
}
}));
this.builtins.add(var);
}
public Server getServer() {
return this.server;
}
public Map<String, CachedExecutable> getExecutables() {
return this.executables;
}
public Executor getExecutor() {
return this.currentExecutor;
}
private String substitute(String str) {
StringBuffer sb = new StringBuffer(str);
for(PatternReplacer replacer : this.replacers) {
replacer.replaceVar(sb);
}
return sb.toString();
}
private Object execute(String cmd, boolean setPrev) {
String line = this.substitute(cmd);
String[][] cmds = ArgumentParser.splitString(line);
Object o = null;
for(String[] argv : cmds) {
String exec = argv[0];
String var = null;
int eq = exec.indexOf('=');
if(eq >= 0) {
var = exec.substring(0, eq);
exec = exec.substring(eq + 1);
}
CachedExecutable cached = this.executables.get(exec);
if(cached == null)
throw new RunException("Befehl '%s' existiert nicht", exec);
for(int z = 0; z < argv.length; z++) {
String arg = argv[z];
if(arg.startsWith("$(") && arg.endsWith(")")) {
String resolve = this.variables.get(arg.substring(2, arg.length() - 1));
if(resolve != null)
argv[z] = resolve;
}
}
ArgumentSplitter args = ArgumentSplitter.parseArgs(this, cmd, argv, cached);
List<Object> params = Lists.newArrayList(this, this.currentExecutor);
for(Parameter param : cached.getExecutable().getParamList()) {
ArgCombiner combiner = param.getCombiner();
if(combiner != null) {
Object[] data = (Object[])Array.newInstance(combiner.getInputClass(), param.getParsers().size());
for(int z = 0; z < data.length; z++) {
data[z] = args.getUnchecked(param.getName(), param.getParsers().get(z).getName());
if(data[z] == null) {
data = null;
break;
}
}
params.add(data == null ? null : combiner.combine(data));
continue;
}
if(param.getParsers().isEmpty()) {
params.add(args.hasArg(param.getName()));
continue;
}
for(ArgumentParser parser : param.getParsers()) {
params.add(args.getUnchecked(param.getName(), parser.getName()));
}
}
try {
o = cached.getMethod().invoke(cached.getExecutable(), params.toArray(new Object[params.size()]));
}
catch(InvocationTargetException e) {
if(e.getCause() instanceof RuntimeException)
throw ((RuntimeException)e.getCause());
else
throw new RuntimeException(e.getCause());
}
catch(IllegalAccessException | IllegalArgumentException e) {
throw new RuntimeException(e);
}
// o = cached.getExecutable().exec(this, args);
if(setPrev)
this.previousOutput = o;
if(var != null && !var.isEmpty() && !this.builtins.contains(var)) {
if(o != null)
this.variables.put(var, String.valueOf(o));
else
this.variables.remove(var);
}
}
return o;
}
public void execute(String cmd, Executor exec) {
this.currentExecutor = exec;
try {
this.execute(cmd, true);
}
catch(RunException e) {
Throwable cause = e;
do {
exec.logConsole(TextColor.RED + cause.getMessage());
cause = cause.getCause();
}
while(cause != null);
}
catch(Throwable t) {
exec.logConsole(TextColor.RED + "Fehler: %s", t.getMessage());
Log.CONSOLE.error(t, "Fehler beim Ausführen von Befehl '%s'", cmd);
}
finally {
this.currentExecutor = null;
this.previousOutput = null;
this.variables.clear();
}
}
public List<String> complete(String cmd, Executor exec) {
this.currentExecutor = exec;
List<String> list = Lists.newArrayList();
try {
String[][] cmds = ArgumentParser.splitString(cmd.endsWith(" ") ? cmd + "END" : cmd);
if(cmds.length == 0)
return list;
String[] argv = cmds[cmds.length - 1];
if(argv.length == 0)
return list;
String param = cmd.endsWith(" ") ? "" : argv[argv.length - 1];
Iterable<String> comp;
if(argv.length > 1) {
int eq = argv[0].indexOf('=');
CachedExecutable cached = this.executables.get(eq >= 0 ? argv[0].substring(eq + 1) : argv[0]);
if(cached == null)
return list;
comp = ArgumentSplitter.parseComplete(this, argv, cached, param);
}
else {
comp = this.executables.keySet();
}
for(String cmp : comp) {
if(cmp.regionMatches(true, 0, param, 0, param.length()))
list.add(cmp);
}
}
catch(Throwable t) {
list.clear();
Log.CONSOLE.error(t, "Konnte Befehl '%s' nicht vervollständigen", cmd);
}
finally {
this.currentExecutor = null;
}
return list;
}
public void registerDefaults() {
this.registerVariable("*", new Variable() {
public String get() {
return CommandEnvironment.this.currentExecutor.getExecId();
}
});
this.registerVariable("name", new Variable() {
public String get() {
return CommandEnvironment.this.currentExecutor.getExecName();
}
});
this.registerVariable("!", new Variable() {
public String get() {
return CommandEnvironment.this.previousOutput == null ? null : CommandEnvironment.this.previousOutput.toString();
}
});
this.registerExecutable(new CommandSpawn());
this.registerExecutable(new CommandPotion());
this.registerExecutable(new CommandMilk());
this.registerExecutable(new CommandAdmin());
this.registerExecutable(new CommandRevoke());
this.registerExecutable(new CommandTp());
this.registerExecutable(new CommandTele());
this.registerExecutable(new CommandWorld());
this.registerExecutable(new CommandOfflinetp());
this.registerExecutable(new CommandWarp());
this.registerExecutable(new CommandTime());
this.registerExecutable(new CommandRemove());
this.registerExecutable(new CommandWeather());
this.registerExecutable(new CommandKick());
this.registerExecutable(new CommandMessage());
this.registerExecutable(new CommandShutdown());
this.registerExecutable(new CommandPasswd());
this.registerExecutable(new CommandPlayers());
this.registerExecutable(new CommandSave());
this.registerExecutable(new CommandRegister());
this.registerExecutable(new CommandHelp(this));
}
}

View file

@ -0,0 +1,7 @@
package server.command;
import java.util.List;
public interface Completer {
void complete(List<String> comp, CommandEnvironment env, ArgumentSplitter args, Argument arg);
}

View file

@ -0,0 +1,21 @@
package server.command;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public abstract class CompletingParser extends ArgumentParser {
private final List<String> defCompletions;
public CompletingParser(String name, Object ... completions) {
super(name);
this.defCompletions = new ArrayList<String>(completions.length);
for(Object comp : completions) {
this.defCompletions.add(String.valueOf(comp));
}
}
public Collection<String> getCompletions(CommandEnvironment env) {
return this.defCompletions;
}
}

View file

@ -0,0 +1,18 @@
package server.command;
public abstract class DefaultingParser extends CompletingParser {
private final Object def;
public DefaultingParser(String name, Object def, Object ... completions) {
super(name, completions);
this.def = def;
}
public Object getDefault(CommandEnvironment env) {
return this.def;
}
protected final boolean hasDefault() {
return this.def != null;
}
}

View file

@ -0,0 +1,49 @@
package server.command;
import java.util.Collection;
import common.dimension.Dimension;
import common.init.UniverseRegistry;
import common.util.Position;
public class DimensionParser extends CompletingParser {
private final boolean useSender;
public DimensionParser(String name, boolean useSender) {
super(name);
this.useSender = useSender;
}
public Object parse(CommandEnvironment env, String input) {
Dimension dim = UniverseRegistry.getDimension(input);
if(dim != null)
return dim;
int id = Integer.MIN_VALUE;
try {
id = Integer.parseInt(input);
}
catch(NumberFormatException e) {
}
dim = UniverseRegistry.getDimension(id);
if(dim == null)
throw new RunException("Unbekannte Dimension '%s'", input);
return dim;
}
public Object getDefault(CommandEnvironment env) {
if(!this.useSender)
return null;
Position pos = env.getExecutor().getExecPos();
return pos == null ? null : UniverseRegistry.getDimension(pos.dim);
// if(dim == null)
// throw new ScriptException("Unbekannte Dimension '%s'");
}
public Collection<String> getCompletions(CommandEnvironment env) {
return UniverseRegistry.getWorldNames();
}
public Class<?> getTypeClass(boolean required) {
return Dimension.class;
}
}

View file

@ -0,0 +1,95 @@
package server.command;
import java.util.Collection;
import common.collect.Lists;
import common.util.BlockPos;
import common.util.Position;
public class DoubleParser extends DefaultingParser {
public static enum DefType {
X, Y, Z, YAW, PITCH;
}
private final DefType defType;
private final Double min;
private final Double max;
private final boolean center;
public DoubleParser(String name, Double def, Double min, Double max, boolean center, Object ... completions) {
super(name, def, completions);
this.defType = null;
this.min = min;
this.max = max;
this.center = center;
}
public DoubleParser(String name, DefType type, Double min, Double max, boolean center) {
super(name, null);
this.defType = type;
this.min = min;
this.max = max;
this.center = center;
}
public Double parse(CommandEnvironment env, String input) {
Double pre = this.defType != null && input.startsWith("~") ? this.getDefault(env) : null;
input = pre != null ? input.substring(1) : input;
double value;
try {
value = Double.parseDouble(input);
}
catch(NumberFormatException e) {
throw new RunException("Ungültige Gleitkommazahl '%s'", input);
}
if(this.center && pre == null && input.indexOf('.') < 0)
value += 0.5;
if(this.min != null && value < this.min)
if(this.max != null)
throw new RunException("Die Zahl muss im Bereich %f .. %f liegen, habe %f", this.min, this.max, value);
else
throw new RunException("Die Zahl muss mindestens %f betragen, habe %f", this.min, value);
if(this.max != null && value > this.max)
if(this.min != null)
throw new RunException("Die Zahl muss im Bereich %f .. %f liegen, habe %f", this.min, this.max, value);
else
throw new RunException("Die Zahl darf höchstens %f betragen, habe %f", this.max, value);
return value;
}
public Double getDefault(CommandEnvironment env) {
Position pos = this.defType == null ? null : env.getExecutor().getExecPos();
if(this.defType != null)
switch(this.defType) {
case X:
return pos == null ? null : pos.x;
case Y:
return pos == null ? null : pos.y;
case Z:
return pos == null ? null : pos.z;
case YAW:
return pos == null ? null : (double)pos.yaw;
case PITCH:
return pos == null ? null : (double)pos.pitch;
}
return (Double)super.getDefault(env);
}
public Class<?> getTypeClass(boolean required) {
return this.hasDefault() || required ? double.class : Double.class;
}
public Collection<String> getCompletions(CommandEnvironment env) {
BlockPos pos = this.defType == null ? null : env.getExecutor().getPointedPosition();
if(this.defType != null)
switch(this.defType) {
case X:
return pos == null ? null : Lists.newArrayList("" + pos.getX());
case Y:
return pos == null ? null : Lists.newArrayList("" + pos.getY());
case Z:
return pos == null ? null : Lists.newArrayList("" + pos.getZ());
}
return super.getCompletions(env);
}
}

View file

@ -0,0 +1,135 @@
package server.command;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import common.collect.Lists;
import common.collect.Sets;
import common.entity.Entity;
import common.entity.EntityType;
import common.entity.types.EntityLiving;
import common.init.EntityRegistry;
import server.network.Player;
import server.world.WorldServer;
public class EntityListParser extends EntityParser {
public EntityListParser(String name, boolean useSender, boolean livingOnly) {
super(name, useSender, livingOnly);
}
public Object parse(CommandEnvironment env, String input) {
if(input.equals("**")) {
List<Entity> list = Lists.newArrayList();
for(WorldServer world : env.getServer().getWorlds()) {
if(this.livingOnly) {
for(Entity ent : world.getEntities()) {
if(ent instanceof EntityLiving)
list.add(ent);
}
}
else {
list.addAll(world.getEntities());
}
}
if(list.isEmpty())
throw new RunException(this.livingOnly ? "Keine lebendigen Objekte gefunden" : "Keine Objekte gefunden");
return list;
}
else if(input.equals("*")) {
List<Entity> list = Lists.newArrayList();
for(Player plr : env.getServer().getPlayers()) {
if(plr.getPresentEntity() != null)
list.add(plr.getPresentEntity());
}
if(list.isEmpty())
throw new RunException("Keine Spieler gefunden");
return list;
}
Set<Class<? extends Entity>> classes = Sets.newHashSet();
Set<EntityType> types = Sets.newHashSet();
Set<Entity> entities = Sets.newHashSet();
Set<Class<? extends Entity>> nclasses = Sets.newHashSet();
Set<EntityType> ntypes = Sets.newHashSet();
Set<Entity> nentities = Sets.newHashSet();
Boolean living = null;
Boolean player = null;
for(String tok : input.split(",", -1)) {
boolean negate = tok.startsWith("!");
tok = negate ? tok.substring(1) : tok;
Class<? extends Entity> clazz = EntityRegistry.getEntityClass(tok);
if(clazz != null) {
if(classes.contains(clazz) || nclasses.contains(clazz))
throw new RunException("Objekttyp %s mehrfach angegeben", EntityRegistry.getEntityName(EntityRegistry.getEntityString(clazz)));
if(this.livingOnly && !EntityLiving.class.isAssignableFrom(clazz))
throw new RunException("Objekttyp %s ist nicht lebendig", EntityRegistry.getEntityName(EntityRegistry.getEntityString(clazz)));
(negate ? nclasses : classes).add(clazz);
}
else if(tok.equals("Player")) {
if(player != null)
throw new RunException("'Player' mehrfach angegeben");
player = !negate;
}
else if(tok.equals("Living")) {
if(living != null)
throw new RunException("'Living' mehrfach angegeben");
if(this.livingOnly)
throw new RunException("Kann nicht 'Living' als Objekttypen angeben");
living = !negate;
}
else {
EntityType type = EntityType.getByName(tok);
if(type != null) {
if(types.contains(type) || ntypes.contains(type))
throw new RunException("Objekttyp %s mehrfach angegeben", type.getDisplay());
(negate ? ntypes : types).add(type);
}
else {
Entity ent = (Entity)super.parse(env, tok);
if(entities.contains(ent) || nentities.contains(ent))
throw new RunException("Objekt '%s' mehrfach angegeben", tok);
(negate ? nentities : entities).add(ent);
}
}
}
List<Entity> filtered = Lists.newArrayList(entities);
boolean negateOnly = (living == null && player == null && types.isEmpty() && classes.isEmpty() && entities.isEmpty());
for(WorldServer world : env.getServer().getWorlds()) {
for(Entity ent : world.getEntities()) {
if((!this.livingOnly || ent instanceof EntityLiving) &&
(negateOnly || (living != null && types.isEmpty() && classes.isEmpty() && living == (ent instanceof EntityLiving)) || (player != null && types.isEmpty() && classes.isEmpty() && player == ent.isPlayer()) || types.contains(ent.getType()) ||
classes.contains(ent.getClass())) &&
(living == null || living == (ent instanceof EntityLiving)) && (player == null || player == ent.isPlayer()) &&
!ntypes.contains(ent.getType()) && !nclasses.contains(ent.getClass()) && !nentities.contains(ent) && !entities.contains(ent))
filtered.add(ent);
}
}
if(filtered.isEmpty())
throw new RunException("Keine Objekte gefunden");
return filtered;
}
public Object getDefault(CommandEnvironment env) {
Entity entity = (Entity)super.getDefault(env);
return entity == null ? null : Lists.newArrayList(entity);
}
public Collection<String> getCompletions(CommandEnvironment env) {
Collection<String> comp = super.getCompletions(env);
comp.add("*");
for(Class<? extends Entity> clazz : EntityRegistry.getAllClasses()) {
if(!this.livingOnly || EntityLiving.class.isAssignableFrom(clazz))
comp.add(EntityRegistry.getEntityString(clazz));
}
for(EntityType type : EntityType.values()) {
comp.add(type.getName());
}
Collections.addAll(comp, "Player", "Living", "**");
return comp;
}
public Class<?> getTypeClass(boolean required) {
return List.class;
}
}

View file

@ -0,0 +1,60 @@
package server.command;
import java.util.Collection;
import java.util.List;
import common.collect.Lists;
import common.entity.Entity;
import common.entity.types.EntityLiving;
import server.world.WorldServer;
public class EntityParser extends PlayerEntityParser {
protected final boolean livingOnly;
public EntityParser(String name, boolean useSender, boolean livingOnly) {
super(name, useSender);
this.livingOnly = livingOnly;
}
public Object parse(CommandEnvironment env, String input) {
Entity entity = null;
if(input.startsWith("#")) {
int id = -1;
try {
id = Integer.parseInt(input.substring(1));
}
catch(NumberFormatException e) {
}
if(id != -1) {
for(WorldServer world : env.getServer().getWorlds()) {
entity = world.getEntityByID(id);
if(entity != null)
break;
}
}
}
else {
entity = (Entity)super.parse(env, input);
}
if(entity == null)
throw new RunException("Objekt '%s' wurde nicht gefunden", input);
else if(this.livingOnly && !(entity instanceof EntityLiving))
throw new RunException("Objekt '%s' muss lebendig sein", input);
return entity;
}
public Object getDefault(CommandEnvironment env) {
return this.useSender && (this.livingOnly ? (env.getExecutor() instanceof EntityLiving) : (env.getExecutor() instanceof Entity)) ? env.getExecutor() : super.getDefault(env);
}
public Collection<String> getCompletions(CommandEnvironment env) {
Entity target = env.getExecutor().getPointedEntity();
List<String> comp = target == null || (this.livingOnly && !(target instanceof EntityLiving)) ? Lists.newArrayList() : Lists.newArrayList("#" + target.getId());
comp.addAll(super.getCompletions(env));
return comp;
}
public Class<?> getTypeClass(boolean required) {
return this.livingOnly ? EntityLiving.class : Entity.class;
}
}

View file

@ -0,0 +1,50 @@
package server.command;
import java.util.Map;
import common.collect.Maps;
public class EnumParser<T> extends DefaultingParser {
private final Class<T> clazz;
private final Map<String, T> lookup = Maps.newHashMap();
private final T[] selections;
private static <T> String joinArgs(T[] iter) {
StringBuilder sb = new StringBuilder("'");
for(T obj : iter) {
if(sb.length() > 1)
sb.append("', '");
sb.append(String.valueOf(obj));
}
return sb.append("'").toString();
}
public EnumParser(String name, Class<T> clazz, T def, T ... selections) {
super(name, def, selections);
this.clazz = clazz;
this.selections = selections;
for(T o : selections) {
this.lookup.put(o.toString().toLowerCase(), o);
}
}
public T parse(CommandEnvironment env, String input) {
T value = this.lookup.get(input.toLowerCase());
if(value != null)
return value;
int id = -1;
try {
id = Integer.parseInt(input);
}
catch(NumberFormatException e) {
}
if(id < 0 || id >= this.selections.length)
throw new RunException("Ungültige Auswahl '%s', muss eine von diesen Optionen sein: %s", input,
joinArgs(this.selections));
return this.selections[id];
}
public Class<?> getTypeClass(boolean required) {
return this.clazz;
}
}

View file

@ -0,0 +1,11 @@
package server.command;
import java.util.List;
import java.util.Map;
public interface Executable {
// Object exec(ScriptEnvironment env, ScriptArgs args);
Map<String, Parameter> getParameters();
List<Parameter> getParamList();
String getName();
}

View file

@ -0,0 +1,27 @@
package server.command;
import common.entity.Entity;
import common.util.BlockPos;
import common.util.Position;
import server.network.Player;
public interface Executor {
void logConsole(String msg);
String getExecId();
String getExecName();
Position getExecPos();
Entity getPointedEntity();
BlockPos getPointedPosition();
default boolean isConsole() {
return false;
}
default boolean isPlayer() {
return this instanceof Player;
}
default void logConsole(String fmt, Object ... args) {
this.logConsole(String.format(fmt, args));
}
}

View file

@ -0,0 +1,57 @@
package server.command;
import common.entity.Entity;
import common.util.BlockPos;
import common.util.Position;
import server.Server;
public class FixedExecutor implements Executor {
private final Server server;
private final String id;
private String name;
private Position position;
public FixedExecutor(Server server, String id, String name, Position pos) {
this.server = server;
this.id = id;
this.name = name;
this.position = pos;
}
public void setName(String name) {
this.name = name;
}
public void setPosition(Position pos) {
this.position = pos;
}
public void logConsole(String msg) {
this.server.logConsole(msg);
}
public String getExecId() {
return this.id;
}
public String getExecName() {
return this.name;
}
public Position getExecPos() {
return this.position;
}
public Entity getPointedEntity() {
return null;
}
public BlockPos getPointedPosition() {
return null;
}
public boolean isConsole() {
return true;
}
}

View file

@ -0,0 +1,39 @@
package server.command;
public class IntParser extends DefaultingParser {
private final Integer min;
private final Integer max;
private final boolean hex;
public IntParser(String name, boolean hex, Integer def, Integer min, Integer max, Object ... completions) {
super(name, def, completions);
this.min = min;
this.max = max;
this.hex = hex;
}
public Integer parse(CommandEnvironment env, String input) {
int value;
try {
value = Integer.parseInt(input, this.hex ? 16 : 10);
}
catch(NumberFormatException e) {
throw new RunException("Ungültige " + (this.hex ? "Hexadezimalzahl" : "Ganzzahl") + " '%s'", input);
}
if(this.min != null && value < this.min)
if(this.max != null)
throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value);
else
throw new RunException("Die Zahl muss mindestens %d betragen, habe %d", this.min, value);
if(this.max != null && value > this.max)
if(this.min != null)
throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value);
else
throw new RunException("Die Zahl darf höchstens %d betragen, habe %d", this.max, value);
return value;
}
public Class<?> getTypeClass(boolean required) {
return this.hasDefault() || required ? int.class : Integer.class;
}
}

View file

@ -0,0 +1,37 @@
package server.command;
public class LongParser extends DefaultingParser {
private final Long min;
private final Long max;
public LongParser(String name, Long def, Long min, Long max, Object ... completions) {
super(name, def, completions);
this.min = min;
this.max = max;
}
public Long parse(CommandEnvironment env, String input) {
long value;
try {
value = Long.parseLong(input);
}
catch(NumberFormatException e) {
throw new RunException("Ungültige Ganzzahl '%s'", input);
}
if(this.min != null && value < this.min)
if(this.max != null)
throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value);
else
throw new RunException("Die Zahl muss mindestens %d betragen, habe %d", this.min, value);
if(this.max != null && value > this.max)
if(this.min != null)
throw new RunException("Die Zahl muss im Bereich %d .. %d liegen, habe %d", this.min, this.max, value);
else
throw new RunException("Die Zahl darf höchstens %d betragen, habe %d", this.max, value);
return value;
}
public Class<?> getTypeClass(boolean required) {
return this.hasDefault() || required ? long.class : Long.class;
}
}

View file

@ -0,0 +1,11 @@
package server.command;
public abstract class NonDefaultingParser extends CompletingParser {
public NonDefaultingParser(String name, Object ... completions) {
super(name, completions);
}
public Object getDefault(CommandEnvironment env) {
return null;
}
}

View file

@ -0,0 +1,53 @@
package server.command;
import java.util.List;
public class Parameter {
private final String name;
private final char shortName;
private final boolean required;
private final int position;
private final List<ArgumentParser> parsers;
private final ArgCombiner<?> combiner;
public Parameter(String name, char shortName, int position, boolean required, List<ArgumentParser> parsers, ArgCombiner<?> combiner) {
this.name = name;
this.shortName = shortName;
this.position = position;
this.required = required;
this.parsers = parsers;
this.combiner = combiner;
}
public boolean isPositional() {
return this.position >= 0;
}
public int getPosition() {
return this.position;
}
public List<ArgumentParser> getParsers() {
return this.parsers;
}
public ArgCombiner<?> getCombiner() {
return this.combiner;
}
public boolean isRequired() {
return this.required;
}
public String getName() {
return this.name;
}
public boolean hasShortName() {
return this.shortName != 0;
}
public char getShortName() {
return this.shortName;
}
}

View file

@ -0,0 +1,49 @@
package server.command;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PatternReplacer {
private final String variable;
private final boolean matchAll;
private final Pattern pattern;
private final Function<String, String> function;
public PatternReplacer(String variable, boolean matchAll, Function<String, String> function) {
this.variable = variable;
this.matchAll = matchAll;
this.pattern = Pattern.compile("\\$\\((" + Pattern.quote(variable) + (matchAll ? "[^\\)]*" : "") + ")\\)");
this.function = function;
}
public void replaceVar(StringBuffer sb) {
String str = sb.toString();
sb.delete(0, sb.length());
Matcher matcher = this.pattern.matcher(str);
while(matcher.find()) {
String orig = matcher.group(1);
String rep = this.function.apply(orig);
if(rep == null)
throw new RunException("Variable '%s' konnte in diesem Kontext nicht ersetzt werden", orig);
matcher.appendReplacement(sb, rep);
}
matcher.appendTail(sb);
}
public String getVariable() {
return this.variable;
}
public boolean matchesAll() {
return this.matchAll;
}
public Pattern getPattern() {
return this.pattern;
}
public Function<String, String> getFunction() {
return this.function;
}
}

View file

@ -0,0 +1,52 @@
package server.command;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import common.collect.Lists;
import common.collect.Sets;
import common.entity.Entity;
import common.entity.npc.EntityNPC;
import server.network.Player;
public class PlayerEntityListParser extends PlayerEntityParser {
public PlayerEntityListParser(String name, boolean useSender) {
super(name, useSender);
}
public Object parse(CommandEnvironment env, String input) {
if(input.equals("*")) {
List<Entity> list = Lists.newArrayList();
for(Player plr : env.getServer().getPlayers()) {
if(plr.getPresentEntity() != null)
list.add(plr.getPresentEntity());
}
if(list.isEmpty())
throw new RunException("Keine Spieler gefunden");
return list;
}
Set<EntityNPC> set = Sets.newHashSet();
for(String tok : input.split(",", -1)) {
set.add((EntityNPC)super.parse(env, tok));
}
if(set.isEmpty())
throw new RunException("Keine Spieler gefunden");
return Lists.newArrayList(set);
}
public Object getDefault(CommandEnvironment env) {
EntityNPC entity = (EntityNPC)super.getDefault(env);
return entity == null ? null : Lists.newArrayList(entity);
}
public Collection<String> getCompletions(CommandEnvironment env) {
Collection<String> comp = super.getCompletions(env);
comp.add("*");
return comp;
}
public Class<?> getTypeClass(boolean required) {
return List.class;
}
}

View file

@ -0,0 +1,27 @@
package server.command;
import common.entity.npc.EntityNPC;
import server.network.Player;
public class PlayerEntityParser extends PlayerParser {
public PlayerEntityParser(String name, boolean useSender) {
super(name, useSender);
}
public Object parse(CommandEnvironment env, String input) {
Player net = (Player)super.parse(env, input);
EntityNPC entity = net.getPresentEntity();
if(entity == null)
throw new RunException("Spieler-Objekt von '%s' wurde nicht gefunden", input);
return entity;
}
public Object getDefault(CommandEnvironment env) {
Player net = (Player)super.getDefault(env);
return net == null ? null : net.getPresentEntity();
}
public Class<?> getTypeClass(boolean required) {
return EntityNPC.class;
}
}

View file

@ -0,0 +1,45 @@
package server.command;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import common.collect.Lists;
import common.collect.Sets;
import server.network.Player;
public class PlayerListParser extends PlayerParser {
public PlayerListParser(String name, boolean useSender) {
super(name, useSender);
}
public Object parse(CommandEnvironment env, String input) {
if(input.equals("*")) {
if(env.getServer().getPlayers().isEmpty())
throw new RunException("Keine Spieler gefunden");
return Lists.newArrayList(env.getServer().getPlayers());
}
Set<Player> set = Sets.newHashSet();
for(String tok : input.split(",", -1)) {
set.add((Player)super.parse(env, tok));
}
if(set.isEmpty())
throw new RunException("Keine Spieler gefunden");
return Lists.newArrayList(set);
}
public Object getDefault(CommandEnvironment env) {
Player net = (Player)super.getDefault(env);
return net == null ? null : Lists.newArrayList(net);
}
public Collection<String> getCompletions(CommandEnvironment env) {
Collection<String> comp = super.getCompletions(env);
comp.add("*");
return comp;
}
public Class<?> getTypeClass(boolean required) {
return List.class;
}
}

View file

@ -0,0 +1,33 @@
package server.command;
import java.util.Collection;
import server.network.Player;
public class PlayerParser extends CompletingParser {
protected final boolean useSender;
public PlayerParser(String name, boolean useSender) {
super(name);
this.useSender = useSender;
}
public Object parse(CommandEnvironment env, String input) {
Player net = env.getServer().getPlayer(input);
if(net == null)
throw new RunException("Spieler '%s' wurde nicht gefunden", input);
return net;
}
public Object getDefault(CommandEnvironment env) {
return this.useSender && env.getExecutor().isPlayer() ? (Player)env.getExecutor() : null;
}
public Collection<String> getCompletions(CommandEnvironment env) {
return env.getServer().getAllUsernames();
}
public Class<?> getTypeClass(boolean required) {
return Player.class;
}
}

View file

@ -0,0 +1,28 @@
package server.command;
public class RunException extends RuntimeException {
public RunException(String desc) {
super(desc);
this.setStackTrace(new StackTraceElement[0]);
}
public RunException(String fmt, Object ... args) {
super(String.format(fmt, args));
this.setStackTrace(new StackTraceElement[0]);
}
public RunException(Throwable cause, String desc) {
super(desc, cause);
this.setStackTrace(new StackTraceElement[0]);
}
public RunException(Throwable cause, String fmt, Object ... args) {
super(String.format(fmt, args), cause);
this.setStackTrace(new StackTraceElement[0]);
}
public synchronized Throwable fillInStackTrace() {
this.setStackTrace(new StackTraceElement[0]);
return this;
}
}

View file

@ -0,0 +1,7 @@
package server.command;
import java.util.Collection;
public interface StringCompleter {
Collection<String> complete(CommandEnvironment env);
}

View file

@ -0,0 +1,63 @@
package server.command;
import java.util.Collection;
import common.util.CharValidator;
public class StringParser extends DefaultingParser {
private final boolean allowEmpty;
private final Integer minLength;
private final Integer maxLength;
private final CharValidator validator;
private final StringCompleter completer;
public StringParser(String name, String def, boolean allowEmpty, Integer minLength, Integer maxLength, CharValidator validator,
Object ... completions) {
super(name, def, completions);
this.allowEmpty = allowEmpty;
this.minLength = minLength;
this.maxLength = maxLength;
this.validator = validator;
this.completer = null;
}
public StringParser(String name, String def, boolean allowEmpty, Integer minLength, Integer maxLength, CharValidator validator,
StringCompleter completer) {
super(name, def);
this.allowEmpty = allowEmpty;
this.minLength = minLength;
this.maxLength = maxLength;
this.validator = validator;
this.completer = completer;
}
public String parse(CommandEnvironment env, String input) {
if(!this.allowEmpty && input.isEmpty())
throw new RunException("Die Zeichenkette darf nicht leer sein");
if(this.minLength != null && input.length() < this.minLength)
if(this.maxLength != null)
throw new RunException("Die Zeichenkette muss zwischen %d .. %d Zeichen lang sein, habe %d ('%s')",
this.minLength, this.maxLength, input.length(), input);
else
throw new RunException("Die Zeichenkette muss mindestens %d Zeichen lang sein, habe %d ('%s')",
this.minLength, input.length(), input);
if(this.maxLength != null && input.length() > this.maxLength)
if(this.minLength != null)
throw new RunException("Die Zeichenkette muss zwischen %d .. %d Zeichen lang sein, habe %d ('%s')",
this.minLength, this.maxLength, input.length(), input);
else
throw new RunException("Die Zeichenkette darf höchstens %d Zeichen lang sein, habe %d ('%s')",
this.maxLength, input.length(), input);
if(this.validator != null && !this.validator.valid(input))
throw new RunException("Die Zeichenkette '%s' enthält ungültige Zeichen", input);
return input;
}
public Class<?> getTypeClass(boolean required) {
return String.class;
}
public Collection<String> getCompletions(CommandEnvironment env) {
return this.completer != null ? this.completer.complete(env) : super.getCompletions(env);
}
}

View file

@ -0,0 +1,26 @@
package server.command;
import common.nbt.NBTException;
import common.nbt.NBTParser;
import common.nbt.NBTTagCompound;
public class TagParser extends DefaultingParser {
public TagParser(String name, NBTTagCompound def, Object ... completions) {
super(name, def, completions);
}
public NBTTagCompound parse(CommandEnvironment env, String input) {
NBTTagCompound value;
try {
value = NBTParser.parseTag(input);
}
catch(NBTException e) {
throw new RunException(e, "Ungültiger NBT-Tag '%s'", input);
}
return value;
}
public Class<?> getTypeClass(boolean required) {
return NBTTagCompound.class;
}
}

View file

@ -0,0 +1,5 @@
package server.command;
public interface Variable {
public String get();
}

View file

@ -0,0 +1,48 @@
package server.command;
import java.util.Collection;
import java.util.List;
import common.collect.Lists;
import common.dimension.Dimension;
import server.world.WorldServer;
public class WorldParser extends DimensionParser {
private final boolean loadedOnly;
public WorldParser(String name, boolean loadedOnly, boolean useSender) {
super(name, useSender);
this.loadedOnly = loadedOnly;
}
public WorldServer parse(CommandEnvironment env, String input) {
Dimension dim = (Dimension)super.parse(env, input);
WorldServer world = this.loadedOnly ? env.getServer().getWorldNoLoad(dim.getDimensionId()) : env.getServer().getWorld(dim.getDimensionId());
if(world == null)
throw new RunException("Dimension '%s' ist nicht geladen", dim.getFormattedName(false));
return world;
}
public WorldServer getDefault(CommandEnvironment env) {
Dimension dim = (Dimension)super.getDefault(env);
return this.loadedOnly ? env.getServer().getWorldNoLoad(dim.getDimensionId()) : env.getServer().getWorld(dim.getDimensionId());
// if(world == null)
// throw new ScriptException("Dimension '%s' ist nicht geladen", dim.getFormattedName(false));
// return world;
}
public Collection<String> getCompletions(CommandEnvironment env) {
if(this.loadedOnly) {
List<String> loaded = Lists.newArrayList();
for(WorldServer world : env.getServer().getWorlds()) {
loaded.add(world.dimension.getDimensionName());
}
return loaded;
}
return super.getCompletions(env);
}
public Class<?> getTypeClass(boolean required) {
return WorldServer.class;
}
}

View file

@ -0,0 +1,25 @@
package server.command.commands;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.network.Player;
public class CommandAdmin extends Command {
public CommandAdmin() {
super("admin");
this.addPlayer("player", false);
}
public void exec(CommandEnvironment env, Executor exec, Player player) {
if(player == exec)
throw new RunException("Du kannst nicht deinen eigenen Admin-Status erneut setzen");
else if(player.getAdmin())
throw new RunException("%s ist bereits ein Admin", player.getUser());
player.setAdmin(true);
player.logConsole("Du hast Administatorrechte von %s bekommen", exec.getExecId());
exec.logConsole("%s ist jetzt ein Admin", player.getUser());
}
}

View file

@ -0,0 +1,55 @@
package server.command.commands;
import java.util.List;
import java.util.Map.Entry;
import java.util.function.Function;
import common.collect.Lists;
import common.util.Util;
import server.command.ArgumentParser;
import server.command.CachedExecutable;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.Parameter;
public class CommandHelp extends Command {
public CommandHelp(CommandEnvironment env) {
super("help");
this.setParamsOptional();
this.addEnum("command", CachedExecutable.class, env.getExecutables().values());
}
public void exec(CommandEnvironment env, Executor exec, CachedExecutable command) {
if(command == null) {
for(CachedExecutable cmd : env.getExecutables().values()) {
this.exec(env, exec, cmd);
}
return;
}
List<String> list = Lists.newArrayList();
for(Entry<String, Parameter> entry : command.getParameters().entrySet()) {
Parameter param = entry.getValue();
if(entry.getKey().length() == 1 && !param.isPositional() && param.hasShortName()) {
list.add("-" + param.getShortName() + (param.getParsers().isEmpty() ? " (" + param.getName() + ")" : (param.getParsers().size() == 1 &&
param.getParsers().get(0).getName().equals(param.getName()) ? " <" + param.getName() + ">" :
" (" + param.getName() + ")" + Util.buildLines(" ", new Function<ArgumentParser, String>() {
public String apply(ArgumentParser parser) {
return "<" + parser.getName() + ">";
}
}, param.getParsers()))));
}
}
for(Parameter param : command.getPositionals()) {
list.add((param.isRequired() ? "<" : "[") + (param.getParsers().size() == 1 &&
param.getParsers().get(0).getName().equals(param.getName()) ? param.getName() :
"(" + param.getName() + ") " + Util.buildLines(" ", new Function<ArgumentParser, String>() {
public String apply(ArgumentParser parser) {
return "<" + parser.getName() + ">";
}
}, param.getParsers())) + (param.isRequired() ? ">" : "]"));
}
exec.logConsole("%s %s", command.getName(), Util.buildLines(" ", list));
}
}

View file

@ -0,0 +1,26 @@
package server.command.commands;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.network.Player;
public class CommandKick extends Command {
public CommandKick() {
super("kick");
this.addPlayer("player", false);
this.setParamsOptional();
this.addString("message", "Du wurdest vom Server geworfen", false);
}
public void exec(CommandEnvironment env, Executor exec, Player player, String message) {
if(player == exec)
throw new RunException("Du kannst nicht dich nicht selbst vom Server werfen");
else if(player.getAdmin())
throw new RunException("%s ist ein Admin", player.getUser());
player.disconnect(message);
exec.logConsole("%s wurde vom Server geworfen", player.getUser());
}
}

View file

@ -0,0 +1,20 @@
package server.command.commands;
import common.packet.SPacketMessage;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
public class CommandMessage extends Command {
public CommandMessage() {
super("message");
this.addString("message", false);
this.addEnum("type", 't', SPacketMessage.Type.CHAT, SPacketMessage.Type.class, SPacketMessage.Type.values());
}
public void exec(CommandEnvironment env, Executor exec, String message, SPacketMessage.Type type) {
env.getServer().sendPacket(new SPacketMessage(message, type));
}
}

View file

@ -0,0 +1,46 @@
package server.command.commands;
import java.util.List;
import common.collect.Lists;
import common.entity.types.EntityLiving;
import common.potion.Potion;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
public class CommandMilk extends Command {
public CommandMilk() {
super("milk");
this.addLivingEntityList("entities", true);
this.setParamsOptional();
List<Potion> potions = Lists.newArrayList();
for(Potion potion : Potion.values()) {
if(!potion.isInstant())
potions.add(potion);
}
this.addEnum("type", Potion.class, potions);
this.addFlag("negative", 'n');
}
public Object exec(CommandEnvironment env, Executor exec, List<EntityLiving> entities, Potion type, boolean negative) {
int done = 0;
for(EntityLiving entity : entities) {
if(type != null && entity.hasEffect(type)) {
entity.removeEffect(type);
exec.logConsole("%s von %s entfernt", type.getDisplay(), entity.getCommandName());
done++;
}
else if(type == null && !entity.getEffects().isEmpty()) {
entity.clearEffects(negative);
exec.logConsole("Alle Effekte von %s entfernt", entity.getCommandName());
done++;
}
}
if(done > 1)
exec.logConsole(type == null ? "Alle Effekte von %d Objekten entfernt" : "%d Effekte entfernt", entities.size());
return done;
}
}

View file

@ -0,0 +1,41 @@
package server.command.commands;
import java.util.Collection;
import java.util.List;
import common.collect.Lists;
import common.entity.Entity;
import common.init.UniverseRegistry;
import common.util.Position;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.command.StringCompleter;
import server.network.Player;
public class CommandOfflinetp extends Command {
public CommandOfflinetp() {
super("offlinetp");
this.addString("user", false, new StringCompleter() {
public Collection<String> complete(CommandEnvironment env) {
return Lists.newArrayList(env.getServer().getUsers());
}
});
this.addEntityList("entities", 'e', true);
}
public Object exec(CommandEnvironment env, Executor exec, String user, List<Entity> entities) {
Player player = env.getServer().getPlayer(user);
Position pos = player != null ? (player.getPresentEntity() != null ? player.getPresentEntity().getPos() : null) : env.getServer().getOfflinePosition(user);
if(pos == null)
throw new RunException("Spieler '%s' konnte nicht gefunden werden", user);
for(Entity entity : entities) {
entity.teleport(pos);
exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)pos.x, (int)pos.y, (int)pos.z, UniverseRegistry.getDimension(pos.dim).getFormattedName(false));
}
return entities.size();
}
}

View file

@ -0,0 +1,69 @@
package server.command.commands;
import common.color.TextColor;
import common.init.Config;
import common.network.IPlayer;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.network.Player;
import server.util.Form;
public class CommandPasswd extends Command {
public CommandPasswd() {
super("passwd");
this.addPlayer("player", true);
this.setParamsOptional();
this.addString("password", false);
}
public void exec(CommandEnvironment env, Executor exec, Player player, String password) {
if(exec.isPlayer()) {
if(password != null)
throw new RunException("Bei Verwendung als Spieler darf kein Passwort angegeben werden");
if(player.getAdmin() && player != exec)
throw new RunException("%s ist ein Admin", player.getUser());
((Player)exec).displayForm(new Form() {
private Field checkField;
private Field passwordField;
private Field confirmField;
protected void init() {
this.checkField = player != exec ? null : this.addPassword("Aktuelles Passwort", 0, IPlayer.MAX_PASS_LENGTH, "");
this.passwordField = this.addPassword("Neues Passwort", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, "");
this.confirmField = this.addPassword("Passwort bestätigen", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, "");
}
public String getTitle() {
return "Passwort für " + player.getUser() + " ändern";
}
protected void accept() {
Player plr = env.getServer().getPlayer(player.getUser());
if(!((Player)exec).isAdmin() || plr == null || (plr.isAdmin() && plr != exec)) {
exec.logConsole(TextColor.DRED + "Ein Fehler ist aufgetreten");
return;
}
if(this.checkField != null && !this.checkField.get().equals(plr.getPassword())) {
exec.logConsole(TextColor.RED + "Falsches Passwort eingegeben");
return;
}
if(!this.passwordField.get().equals(this.confirmField.get())) {
exec.logConsole(TextColor.RED + "Passwörter stimmen nicht überein");
return;
}
plr.setPassword(this.passwordField.get());
exec.logConsole(TextColor.GREEN + "Passwort" + (plr != exec ? " für %s" : "") + " gesetzt", plr.getUser());
}
});
}
else if(exec.isConsole()) {
if(password == null)
throw new RunException("Bei Verwendung in der Konsole muss ein Passwort angegeben werden");
player.setPassword(password);
exec.logConsole(TextColor.GREEN + "Passwort für %s gesetzt", player.getUser());
}
}
}

View file

@ -0,0 +1,32 @@
package server.command.commands;
import java.util.List;
import common.color.TextColor;
import common.entity.npc.EntityNPC;
import common.util.ExtMath;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.network.Player;
public class CommandPlayers extends Command {
public CommandPlayers() {
super("players");
this.addFlag("coords", 'c');
}
public void exec(CommandEnvironment env, Executor exec, boolean coords) {
List<Player> players = env.getServer().getPlayers();
if(players.isEmpty()) {
exec.logConsole(TextColor.DGRAY + "Es sind keine Spieler online");
return;
}
exec.logConsole(TextColor.GREEN + "Es " + (players.size() == 1 ? "ist" : "sind") + " " + TextColor.YELLOW + "%d" + TextColor.GREEN + " Spieler online", players.size());
for(Player player : players) {
EntityNPC entity = player.getPresentEntity();
exec.logConsole("%s%s" + TextColor.GRAY + ": '%s" + TextColor.GRAY + "'" + (coords ? " [" + TextColor.ORANGE + "%s @ %d, %d, %d" + TextColor.GRAY + "]" : ""), player.isAdmin() ? TextColor.RED : TextColor.NEON, player.getUser(), entity == null ? TextColor.DGRAY + "<->" : TextColor.ACID + entity.getCommandName(), entity == null ? null : entity.worldObj.dimension.getFormattedName(false), entity == null ? null : ExtMath.floord(entity.posX), entity == null ? null : ExtMath.floord(entity.posY), entity == null ? null : ExtMath.floord(entity.posZ));
}
}
}

View file

@ -0,0 +1,51 @@
package server.command.commands;
import java.util.List;
import common.entity.types.EntityLiving;
import common.potion.Potion;
import common.potion.PotionEffect;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
public class CommandPotion extends Command {
public CommandPotion() {
super("potion");
this.addLivingEntityList("entities", true);
this.addEnum("type", Potion.class, Potion.values());
this.setParamsOptional();
this.addInt("duration", 0, 1000000, 1000000);
this.addInt("strength", 1, 256, 1);
this.addFlag("particles", 'p');
this.addFlag("ambient", 'a');
this.addFlag("keep", 'k');
}
public Object exec(CommandEnvironment env, Executor exec, List<EntityLiving> entities, Potion type, int duration, int strength, boolean particles, boolean ambient, boolean keep) {
int done = 0;
for(EntityLiving entity : entities) {
if(entity.isPotionApplicable(type)) {
if(type.isInstant()) {
type.onImpact(null, null, entity, strength - 1, 1.0);
}
else {
PotionEffect effect = new PotionEffect(type, duration == 0 ? Integer.MAX_VALUE : (duration * 20), strength - 1, ambient, particles);
if(!keep && entity.hasEffect(type))
entity.removeEffect(type);
entity.addEffect(effect);
}
if(type.isInstant() || duration == 0)
exec.logConsole("%d * %s an %s gegeben", strength, type.getDisplay(), entity.getCommandName());
else
exec.logConsole("%d * %s für %d Sekunden an %s gegeben", strength, type.getDisplay(), duration, entity.getCommandName());
done++;
}
}
if(done > 1)
exec.logConsole("%d Effekte vergeben", done);
return done;
}
}

View file

@ -0,0 +1,72 @@
package server.command.commands;
import common.color.TextColor;
import common.init.Config;
import common.nbt.NBTTagCompound;
import common.network.IPlayer;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.network.Player;
import server.util.Form;
public class CommandRegister extends Command {
public CommandRegister() {
super("register");
this.addString("username", false, null, IPlayer.MAX_USER_LENGTH, IPlayer.VALID_USER);
this.setParamsOptional();
this.addString("password", false);
this.addFlag("admin", 'a');
}
public void exec(CommandEnvironment env, Executor exec, String username, String password, boolean admin) {
Player player = env.getServer().getPlayer(username);
if(player != null)
throw new RunException("Ein Spieler mit diesem Nutzernamen ist bereits online");
NBTTagCompound tag = env.getServer().loadPlayerData(username);
if(tag != null)
throw new RunException("Ein Spieler mit diesem Nutzernamen ist bereits registriert");
if(exec.isPlayer()) {
if(password != null)
throw new RunException("Bei Verwendung als Spieler darf kein Passwort angegeben werden");
((Player)exec).displayForm(new Form() {
private Field passwordField;
private Field confirmField;
protected void init() {
this.passwordField = this.addPassword("Passwort", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, "");
this.confirmField = this.addPassword("Passwort bestätigen", Config.minPassLength, IPlayer.MAX_PASS_LENGTH, "");
}
public String getTitle() {
return "Spieler " + username + " registrieren";
}
protected void accept() {
if(!((Player)exec).isAdmin() || env.getServer().getPlayer(username) != null || env.getServer().loadPlayerData(username) != null) {
exec.logConsole(TextColor.DRED + "Ein Fehler ist aufgetreten");
return;
}
if(!this.passwordField.get().equals(this.confirmField.get())) {
exec.logConsole(TextColor.RED + "Passwörter stimmen nicht überein");
return;
}
NBTTagCompound user = new NBTTagCompound();
user.setString("password", this.passwordField.get());
env.getServer().writePlayerData(username, user);
exec.logConsole(TextColor.GREEN + "Spieler %s registriert", username);
}
});
}
else if(exec.isConsole()) {
if(password == null)
throw new RunException("Bei Verwendung in der Konsole muss ein Passwort angegeben werden");
NBTTagCompound user = new NBTTagCompound();
user.setString("password", password);
env.getServer().writePlayerData(username, user);
exec.logConsole(TextColor.GREEN + "Spieler %s registriert", username);
}
}
}

View file

@ -0,0 +1,35 @@
package server.command.commands;
import java.util.List;
import common.entity.Entity;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
public class CommandRemove extends Command {
public CommandRemove() {
super("remove");
this.addEntityList("entities", true);
this.addFlag("kill", 'k');
}
public Object exec(CommandEnvironment env, Executor exec, List<Entity> entities, boolean kill) {
int done = 0;
for(Entity entity : entities) {
if(entity.isEntityAlive()) {
if(kill || entity.isPlayer())
entity.kill();
else
entity.setDead();
exec.logConsole(kill ? "%s getötet" : "%s entfernt", entity.getCommandName());
done++;
}
}
if(done > 1)
exec.logConsole(kill ? "%d Objekte getötet" : "%d Objekte entfernt", done);
return done;
}
}

View file

@ -0,0 +1,27 @@
package server.command.commands;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.network.Player;
public class CommandRevoke extends Command {
public CommandRevoke() {
super("revoke");
this.addPlayer("player", false);
}
public void exec(CommandEnvironment env, Executor exec, Player player) {
if(!exec.isConsole())
throw new RunException("Dieser Befehl kann nur der Konsole ausgeführt werden");
// else if(player == exec)
// throw new RunException("Du kannst nicht deinen eigenen Admin-Status entfernen");
else if(!player.getAdmin())
throw new RunException("%s ist kein Admin", player.getUser());
player.setAdmin(false);
player.logConsole("Der Host hat deine Administatorrechte entfernt");
exec.logConsole("%s ist jetzt kein Admin mehr", player.getUser());
}
}

View file

@ -0,0 +1,35 @@
package server.command.commands;
import common.color.TextColor;
import common.packet.SPacketMessage;
import common.packet.SPacketMessage.Type;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.world.Region;
public class CommandSave extends Command {
public CommandSave() {
super("save");
this.addFlag("message", 'm');
this.addFlag("flush", 'f');
}
public void exec(CommandEnvironment env, Executor exec, boolean message, boolean flush) {
if(message)
env.getServer().sendPacket(new SPacketMessage(TextColor.RED + "Speichere Serverdaten, der Server könnte kurz einfrieren", Type.FEED));
exec.logConsole(TextColor.ORANGE + "Speichere Spielerdaten ...");
env.getServer().saveAllPlayerData(true);
exec.logConsole(TextColor.ORANGE + "Speichere Weltdaten ...");
env.getServer().saveAllWorlds(true);
env.getServer().resetSaveTimer();
if(flush) {
exec.logConsole(TextColor.ORANGE + "Beende E/A ...");
Region.finishWrite();
}
exec.logConsole(TextColor.DGREEN + "Alle Serverdaten wurden gespeichert");
if(message)
env.getServer().sendPacket(new SPacketMessage(TextColor.GREEN + "Die Serverdaten wurden gespeichert", Type.FEED));
}
}

View file

@ -0,0 +1,18 @@
package server.command.commands;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
public class CommandShutdown extends Command {
public CommandShutdown() {
super("shutdown");
this.setParamsOptional();
this.addString("message", "Server beendet", false);
}
public void exec(CommandEnvironment env, Executor exec, String message) {
env.getServer().shutdown(message);
}
}

View file

@ -0,0 +1,89 @@
package server.command.commands;
import java.util.List;
import java.util.Set;
import common.collect.Lists;
import common.collect.Sets;
import common.entity.Entity;
import common.entity.types.EntityLiving;
import common.init.EntityRegistry;
import common.nbt.NBTTagCompound;
import common.util.Util;
import common.util.Vec3;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.network.Player;
import server.world.WorldServer;
public class CommandSpawn extends Command {
public CommandSpawn() {
super("spawn");
Set<String> names = Sets.newTreeSet();
for(Class<? extends Entity> clazz : EntityRegistry.getAllClasses()) {
names.add(EntityRegistry.getEntityString(clazz));
}
names.add("Lightning");
this.addEnum("type", String.class, names);
this.setParamsOptional();
this.addVector("position", true, true);
this.addWorld("dim", true);
this.addTag("tag");
this.addFlag("noinit", 'n');
this.addInt("count", 'c', 1, 1024, 1);
this.addTag("postTag", 'p');
}
public Object exec(CommandEnvironment env, Executor exec, String type, Vec3 pos, WorldServer world, NBTTagCompound tag, boolean noinit, int count, NBTTagCompound postTag) {
if(type.equalsIgnoreCase("Lightning")) {
for(int z = 0; z < count; z++) {
int color = 0xffffff;
if(tag != null && tag.hasKey("color", 3))
color = tag.getInteger("color");
else if(tag != null && tag.hasKey("color", 8)) {
try {
color = Integer.parseUnsignedInt(tag.getString("color"), 16);
}
catch(NumberFormatException e) {
}
}
world.strikeLightning(pos.xCoord, pos.yCoord, pos.zCoord, color,
tag != null && tag.hasKey("damage", 3) ? tag.getInteger("damage") : 0, tag != null && tag.hasKey("fire", 1) && tag.getBoolean("fire"),
exec.isPlayer() && tag != null && tag.hasKey("summoned", 1) && tag.getBoolean("summoned") ? ((Player)exec).getPresentEntity() : null);
}
exec.logConsole("%sBlitz bei %d, %d, %d in %s erschaffen", count == 1 ? "" : (count + "x "), (int)pos.xCoord, (int)pos.yCoord, (int)pos.zCoord, world.dimension.getFormattedName(false));
return null;
}
else {
List<String> spawned = Lists.newArrayList();
for(int z = 0; z < count; z++) {
Entity entity = EntityRegistry.createEntityByName(type, world);
if(entity == null)
throw new RunException("Objekt konnte nicht erzeugt werden");
entity.setLocationAndAngles(pos.xCoord, pos.yCoord, pos.zCoord, world.rand.floatv() * 360.0f, 0.0f);
if(tag != null) {
NBTTagCompound ent = new NBTTagCompound();
entity.writeToNBT(ent);
ent.merge(tag);
entity.readFromNBT(ent);
}
if(!noinit && (entity instanceof EntityLiving))
((EntityLiving)entity).onInitialSpawn(null);
world.spawnEntityInWorld(entity);
if(postTag != null) {
NBTTagCompound ent = new NBTTagCompound();
entity.writeToNBT(ent);
ent.merge(postTag);
entity.readFromNBT(ent);
}
spawned.add("#" + entity.getId());
}
exec.logConsole("%s%s bei %d, %d, %d in %s erschaffen", count == 1 ? "" : (count + "x "), EntityRegistry.getEntityName(type), (int)pos.xCoord, (int)pos.yCoord, (int)pos.zCoord, world.dimension.getFormattedName(false));
return Util.buildLines(",", spawned);
}
}
}

View file

@ -0,0 +1,32 @@
package server.command.commands;
import java.util.List;
import common.dimension.Dimension;
import common.entity.Entity;
import common.util.Vec3;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
public class CommandTele extends Command {
public CommandTele() {
super("tele");
this.addVector("position", false, true);
this.setParamsOptional();
this.addDimension("dim", true);
this.addDouble("yaw", -180.0, 180.0);
this.addDouble("pitch", -89.0, 89.0);
this.addEntityList("entities", 'e', true);
}
public Object exec(CommandEnvironment env, Executor exec, Vec3 position, Dimension dim, Double yaw, Double pitch, List<Entity> entities) {
for(Entity entity : entities) {
entity.teleport(position.xCoord, position.yCoord, position.zCoord, yaw == null ? entity.rotYaw : yaw.floatValue(), pitch == null ? entity.rotPitch : pitch.floatValue(), dim.getDimensionId());
exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)position.xCoord, (int)position.yCoord, (int)position.zCoord, dim.getFormattedName(false));
}
return entities.size();
}
}

View file

@ -0,0 +1,95 @@
package server.command.commands;
import common.dimension.Dimension;
import common.item.ItemSpaceNavigator;
import common.util.Position;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.world.WorldServer;
public class CommandTime extends Command {
public CommandTime() {
super("time");
this.addString("time", false, "day", "night", "noon", "midnight", "sunrise", "sunset");
this.addFlag("absolute", 'a');
}
private long parseInt(String input, long max) {
long num;
try {
num = Long.parseLong(input);
}
catch(NumberFormatException e) {
throw new RunException("'%s' ist keine gültige Zahl", input);
}
if(num < 0)
throw new RunException("Die Zeit muss mindestens 0 betragen", num);
else if(num > max)
throw new RunException("Die Zeit darf höchstens %d betragen", num, max);
return num;
}
private long parseDayTime(Dimension dim, String arg) {
if(arg.equalsIgnoreCase("sunrise"))
return dim.getRotationalPeriod() / 6L;
else if(arg.equalsIgnoreCase("day"))
return dim.getRotationalPeriod() * 5L / 24L;
else if(arg.equalsIgnoreCase("noon"))
return dim.getRotationalPeriod() / 2L;
else if(arg.equalsIgnoreCase("sunset"))
return dim.getRotationalPeriod() * 5L / 6L;
else if(arg.equalsIgnoreCase("night"))
return dim.getRotationalPeriod() * 21L / 24L;
else if(arg.equalsIgnoreCase("midnight"))
return 0L;
else if(arg.startsWith("@"))
return this.parseInt(arg.substring(1), dim.getRotationalPeriod() - 1);
else
return -1L;
}
private long parseTime(Dimension dim, String arg) {
long t;
if(arg.toLowerCase().endsWith("y"))
t = dim.getOrbitalPeriod();
else if(arg.toLowerCase().endsWith("d"))
t = dim.getRotationalPeriod();
else if(arg.toLowerCase().endsWith("h"))
t = 1000L;
else
t = -1L;
arg = t == -1L ? arg : arg.substring(0, arg.length() - 1);
t = t < 1L ? 1L : t;
return t * this.parseInt(arg, Long.MAX_VALUE);
}
public Object exec(CommandEnvironment env, Executor exec, String timeStr, boolean absolute) {
Position pos = exec.getExecPos();
WorldServer world = pos == null ? env.getServer().getSpace() : env.getServer().getWorld(pos.dim);
long time = absolute ? 0L : world.getDayTime();
long fwd = parseDayTime(world.dimension, timeStr);
if(fwd >= 0L) {
if(absolute) {
time += fwd;
}
else {
time -= world.getDayTime() % world.dimension.getRotationalPeriod();
time += fwd;
time += time <= world.getDayTime() ? world.dimension.getRotationalPeriod() : 0L;
}
}
else {
time += parseTime(world.dimension, timeStr);
}
for(WorldServer dim : env.getServer().getWorlds()) {
dim.setDayTime(time);
dim.resetWeather();
}
exec.logConsole("Zeit auf %s gesetzt", ItemSpaceNavigator.formatImperialTime(world, false));
return time;
}
}

View file

@ -0,0 +1,29 @@
package server.command.commands;
import java.util.List;
import common.entity.Entity;
import common.init.UniverseRegistry;
import common.util.Position;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
public class CommandTp extends Command {
public CommandTp() {
super("tp");
this.addEntity("target", false);
this.addEntityList("entities", 'e', true);
}
public Object exec(CommandEnvironment env, Executor exec, Entity target, List<Entity> entities) {
Position pos = target.getPos();
for(Entity entity : entities) {
entity.teleport(pos);
exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)pos.x, (int)pos.y, (int)pos.z, UniverseRegistry.getDimension(pos.dim).getFormattedName(false));
}
return entities.size();
}
}

View file

@ -0,0 +1,54 @@
package server.command.commands;
import java.util.Collection;
import java.util.List;
import common.entity.Entity;
import common.init.UniverseRegistry;
import common.util.Position;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.command.StringCompleter;
public class CommandWarp extends Command {
public CommandWarp() {
super("warp");
this.addString("warp", true, new StringCompleter() {
public Collection<String> complete(CommandEnvironment env) {
// List<String> warps = Lists.newArrayList("spawn");
// warps.addAll(env.getServer().getWarps().keySet());
return env.getServer().getWarps().keySet();
}
});
this.addEntityList("entities", 'e', true);
}
public Object exec(CommandEnvironment env, Executor exec, String warp, List<Entity> entities) {
Position // pos;
// if(warp.equals("spawn")) {
// WorldServer world = env.getServer().getWorld(Config.spawnDim);
// world = world == null ? env.getServer().getSpace() : world;
// int y = Config.spawnY;
// while(world.getState(new BlockPos(Config.spawnX, y, Config.spawnZ)).getBlock().getMaterial().blocksMovement() && y < 511)
// y++;
// pos = new Position(Config.spawnX + 0.5d, (double)y, Config.spawnZ + 0.5d,
// Config.spawnYaw, Config.spawnPitch, world.dimension.getDimensionId());
// }
// else {
pos = env.getServer().getWarps().get(warp);
if(pos == null)
throw new RunException("Warp '%s' existiert nicht", warp);
else if(env.getServer().getWorld(pos.dim) == null)
throw new RunException("Warp '%s' hat kein Level (%s)", warp, pos.dim);
// }
for(Entity entity : entities) {
entity.teleport(pos);
exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), (int)pos.x, (int)pos.y, (int)pos.z, UniverseRegistry.getDimension(pos.dim).getFormattedName(false));
}
return entities.size();
}
}

View file

@ -0,0 +1,31 @@
package server.command.commands;
import common.world.Weather;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.command.RunException;
import server.world.WorldServer;
public class CommandWeather extends Command {
public CommandWeather() {
super("weather");
this.addEnum("weather", Weather.class, Weather.values());
this.setParamsOptional();
this.addWorld("dim", true);
this.addFlag("transition", 't');
}
public void exec(CommandEnvironment env, Executor exec, Weather weather, WorldServer world, boolean transition) {
if(!world.dimension.getType().weather)
throw new RunException("Welt %s hat kein Wetter", world.dimension.getFormattedName(false));
else if(world.isExterminated())
throw new RunException("Welt %s ist zerstört", world.dimension.getFormattedName(false));
world.setWeather(weather);
if(!transition)
world.resetWeather();
exec.logConsole("Wetter in %s zu %s geändert", world.dimension.getFormattedName(false), weather.getDisplay());
}
}

View file

@ -0,0 +1,39 @@
package server.command.commands;
import java.util.List;
import common.entity.Entity;
import common.util.BlockPos;
import server.command.Command;
import server.command.CommandEnvironment;
import server.command.Executor;
import server.world.WorldServer;
public class CommandWorld extends Command {
public CommandWorld() {
super("world");
this.addWorld("dim", true);
this.addEntityList("entities", 'e', true);
}
public Object exec(CommandEnvironment env, Executor exec, WorldServer world, List<Entity> entities) {
for(Entity entity : entities) {
BlockPos pos = entity.getPosition();
pos = pos.getY() < 0 ? new BlockPos(pos.getX(), 0, pos.getZ()) : pos;
if(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) {
while((world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() < 511)
pos = pos.up();
}
else {
while(!(world.getState(pos).getBlock().getMaterial().blocksMovement() || world.getState(pos).getBlock().getMaterial().isLiquid()) && pos.getY() > 0)
pos = pos.down();
pos = pos.up();
}
entity.teleport(pos, world.dimension.getDimensionId());
exec.logConsole("%s nach %d, %d, %d in %s teleportiert", entity.getCommandName(), pos.getX(), pos.getY(), pos.getZ(), world.dimension.getFormattedName(false));
}
return entities.size();
}
}

View file

@ -0,0 +1,51 @@
package server.network;
import common.network.IHandshakeHandler;
import common.network.NetConnection;
import common.network.NetHandler;
import common.network.PacketRegistry;
import common.packet.HPacketHandshake;
import common.packet.RPacketDisconnect;
import common.util.Util;
import server.Server;
public class HandshakeHandler extends NetHandler implements IHandshakeHandler
{
private final Server server;
private final NetConnection networkManager;
public HandshakeHandler(Server serverIn, NetConnection netManager)
{
this.server = serverIn;
this.networkManager = netManager;
}
public void onDisconnect(String reason)
{
}
public void processHandshake(HPacketHandshake packetIn)
{
if(packetIn.getProtocolVersion() == 0) {
this.networkManager.closeChannel("Inkompatibel!");
return;
}
this.networkManager.setConnectionState(PacketRegistry.LOGIN);
if (packetIn.getProtocolVersion() != Util.PROTOCOL)
{
String comp;
if(packetIn.getProtocolVersion() < Util.PROTOCOL)
comp = "Der Server nutzt eine neuere Version: " + Util.VERSION;
else
comp = "Der Server nutzt eine ältere Version: " + Util.VERSION;
this.networkManager.sendPacket(new RPacketDisconnect(comp));
this.networkManager.closeChannel(comp);
}
else
{
LoginHandler handler = new LoginHandler(this.server, this.networkManager);
this.networkManager.setNetHandler(handler);
handler.sendLoginPacket();
}
}
}

View file

@ -0,0 +1,142 @@
package server.network;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.util.Arrays;
import javax.crypto.SecretKey;
import common.color.TextColor;
import common.init.Config;
import common.log.Log;
import common.network.ILoginHandler;
import common.network.IPlayer;
import common.network.NetConnection;
import common.network.NetHandler;
import common.packet.LPacketPasswordResponse;
import common.packet.LPacketStartEncrypt;
import common.packet.RPacketDisconnect;
import common.packet.RPacketRequestEncrypt;
import server.Server;
public class LoginHandler extends NetHandler implements ILoginHandler
{
private static enum LoginState {
INIT, ENCRYPT, PASSWORD, AUTHENTICATED, ACCEPTED;
}
private static final SecureRandom TOKEN_RNG = new SecureRandom();
private final Server server;
public final NetConnection netManager;
private LoginState state = LoginState.INIT;
private int timer;
private String loginUser;
private String loginPass;
private byte[] loginToken;
public LoginHandler(Server server, NetConnection netManager)
{
this.netManager = netManager;
this.server = server;
}
public void closeConnection(String reason)
{
try
{
Log.NETWORK.info("Trenne " + this.getConnectionInfo());
this.netManager.sendPacket(new RPacketDisconnect(reason));
this.netManager.closeChannel(reason);
}
catch (Exception exception)
{
Log.NETWORK.error(exception, "Fehler beim Trennen des Spielers beim Login");
}
}
public void onDisconnect(String reason)
{
Log.NETWORK.info(this.getConnectionInfo() + " wurde beim Login getrennt: " + TextColor.stripCodes(reason));
}
public String getConnectionInfo()
{
return this.loginUser != null ? (this.loginUser + " (" + this.netManager.getCutAddress()
+ ")") : this.netManager.getCutAddress();
}
public void update()
{
if(this.state == LoginState.AUTHENTICATED)
this.tryAcceptPlayer();
// else if (this.currentLoginState == LoginState.DELAY_ACCEPT)
// {
// if (this.server.getPlayer(this.loginUser) == null)
// {
// this.currentLoginState = LoginState.ACCEPTED;
// this.server.addPlayer(this.networkManager, this.loginUser);
// }
// }
if(this.timer++ == 600)
this.closeConnection("Anmeldung dauerte zu lange");
}
private void tryAcceptPlayer()
{
if(this.server.getPlayer(this.loginUser) != null) {
this.closeConnection("Nutzername '" + this.loginUser + "' ist bereits vergeben.");
return;
}
// if (this.server.getPlayer(this.loginUser) != null)
// {
// this.closeConnection("Nutzername '" + this.loginUser + "' ist bereits vergeben.");
// return;
//// this.currentLoginState = LoginState.DELAY_ACCEPT;
//// player.netHandler.kick("Du hast dich von einen anderen Ort verbunden");
// }
// this.networkManager.sendPacket(new RPacketLoginSuccess());
String kick = this.server.addPlayer(this.netManager, this.loginUser, this.loginPass);
if(kick != null)
this.closeConnection(kick);
else
this.state = LoginState.ACCEPTED;
}
public void sendLoginPacket() {
if(this.state != LoginState.INIT)
throw new IllegalStateException("Unerwartetes Handshake-Paket");
this.state = LoginState.ENCRYPT;
this.loginToken = new byte[4];
TOKEN_RNG.nextBytes(this.loginToken);
this.netManager.sendPacket(new RPacketRequestEncrypt(this.server.getPublicKey(), this.loginToken));
}
public void processEncryption(LPacketStartEncrypt packet) {
if(this.state != LoginState.ENCRYPT)
throw new IllegalStateException("Unerwartetes Verschlüsselungs-Paket");
PrivateKey pkey = this.server.getPrivateKey();
if(!Arrays.equals(this.loginToken, packet.getToken(pkey)))
throw new IllegalStateException("Fehlerhaftes Token");
SecretKey key = packet.getKey(pkey);
this.netManager.startEncryption(key);
this.state = LoginState.PASSWORD;
}
public void processPasswordResponse(LPacketPasswordResponse packetIn) {
if(this.state != LoginState.PASSWORD)
throw new IllegalStateException("Unerwartetes Passwort-Paket");
this.loginUser = packetIn.getUser();
this.loginPass = packetIn.getPassword();
if(this.loginUser.isEmpty() || !IPlayer.isValidUser(this.loginUser))
throw new IllegalStateException("Ungültiger Nutzername!");
// if(!this.checkConnect(packetIn.getAccess()))
// return;
if(!Config.password.isEmpty() && !Config.password.equals(packetIn.getAccess())) {
this.closeConnection("Falsches Zugangspasswort");
return;
}
this.state = LoginState.AUTHENTICATED;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,185 @@
package server.util;
import java.util.List;
import common.collect.Lists;
import common.util.Displayable;
import common.util.Triplet;
public abstract class Form {
private abstract class FormElement {
protected final String name;
protected FormElement(String name) {
this.name = name;
}
protected abstract Object getInputData();
protected abstract int getInputParameter();
protected abstract boolean acceptValue(Object obj);
}
protected class Toggle extends FormElement {
private boolean value;
protected Toggle(String name, boolean value) {
super(name);
this.value = value;
}
protected Object getInputData() {
return this.value;
}
protected int getInputParameter() {
return 0;
}
protected boolean acceptValue(Object obj) {
if(obj instanceof Boolean)
this.value = (Boolean)obj;
return obj instanceof Boolean;
}
public boolean get() {
return this.value;
}
}
protected class Switch<T> extends FormElement {
private final T[] values;
private final int def;
private T value;
protected Switch(String name, T[] values, T value) {
super(name);
this.values = values;
this.value = value;
int def = 0;
for(int z = 0; z < values.length; z++) {
if(values[z] == value) {
def = z;
break;
}
}
this.def = def;
}
protected Object getInputData() {
String[] strs = new String[this.values.length];
for(int z = 0; z < strs.length; z++) {
strs[z] = this.values[z] instanceof Displayable ? ((Displayable)this.values[z]).getDisplay() : String.valueOf(this.values[z]);
}
return strs;
}
protected int getInputParameter() {
return this.def;
}
protected boolean acceptValue(Object obj) {
if(obj instanceof Integer && (Integer)obj >= 0 && (Integer)obj < this.values.length) {
this.value = this.values[(Integer)obj];
return true;
}
return false;
}
public T get() {
return this.value;
}
}
protected class Field extends FormElement {
private final int minLength;
private final int maxLength;
private final boolean password;
private String value;
protected Field(String name, String value, int min, int max, boolean password) {
super(name);
this.value = value;
this.minLength = min;
this.maxLength = max;
this.password = password;
}
protected Object getInputData() {
return this.value;
}
protected int getInputParameter() {
return (this.password ? 0x80000000 : 0) | (this.minLength << 16) | this.maxLength;
}
protected boolean acceptValue(Object obj) {
if(obj instanceof String && ((String)obj).length() >= this.minLength && ((String)obj).length() <= this.maxLength) {
this.value = (String)obj;
return true;
}
return false;
}
public String get() {
return this.value;
}
}
private final List<FormElement> inputs = Lists.newArrayList();
public Form() {
this.init();
}
private <T extends FormElement> T add(T elem) {
this.inputs.add(elem);
return elem;
}
protected Toggle addToggle(String name, boolean def) {
return this.add(new Toggle(name, def));
}
protected <T> Switch<T> addSwitch(String name, T def, T ... values) {
return this.add(new Switch<T>(name, values, def));
}
protected Field addField(String name, int minLength, int maxLength, String def) {
return this.add(new Field(name, def, minLength, maxLength, false));
}
protected Field addPassword(String name, int minLength, int maxLength, String def) {
return this.add(new Field(name, def, minLength, maxLength, true));
}
public abstract String getTitle();
protected abstract void init();
protected abstract void accept();
protected void cancel() {
}
public final Triplet<String, Object, Integer>[] getInputList() {
Triplet<String, Object, Integer>[] data = new Triplet[this.inputs.size()];
for(int z = 0; z < data.length; z++) {
data[z] = new Triplet<String, Object, Integer>(this.inputs.get(z).name, this.inputs.get(z).getInputData(), this.inputs.get(z).getInputParameter());
}
return data;
}
public final void accept(Object[] data) {
if(data == null || data.length != this.inputs.size()) {
this.cancel();
return;
}
for(int z = 0; z < data.length; z++) {
if(!this.inputs.get(z).acceptValue(data[z])) {
this.cancel();
return;
}
}
this.accept();
}
}

View file

@ -0,0 +1,273 @@
package server.village;
import java.util.Iterator;
import java.util.List;
import common.block.Block;
import common.block.Material;
import common.block.artificial.BlockDoor;
import common.collect.Lists;
import common.nbt.NBTTagCompound;
import common.nbt.NBTTagList;
import common.util.BlockPos;
import common.util.Facing;
import common.village.Village;
import common.village.VillageDoorInfo;
import server.world.WorldServer;
public class VillageCollection
{
private final List<BlockPos> villagerPositionsList = Lists.<BlockPos>newArrayList();
private final List<VillageDoorInfo> newDoors = Lists.<VillageDoorInfo>newArrayList();
private final List<Village> villageList = Lists.<Village>newArrayList();
private int tickCounter;
private boolean dirty;
public VillageCollection(NBTTagCompound nbt) {
if(nbt != null) {
this.tickCounter = nbt.getInteger("Tick");
NBTTagList nbttaglist = nbt.getTagList("Villages", 10);
for (int i = 0; i < nbttaglist.tagCount(); ++i)
{
NBTTagCompound nbttagcompound = nbttaglist.getCompoundTagAt(i);
Village village = new Village();
village.readVillageDataFromNBT(nbttagcompound);
this.villageList.add(village);
}
}
}
public void addToVillagerPositionList(BlockPos pos)
{
if (this.villagerPositionsList.size() <= 64)
{
if (!this.positionInList(pos))
{
this.villagerPositionsList.add(pos);
}
}
}
public void tick(WorldServer world)
{
++this.tickCounter;
for (Village village : this.villageList)
{
village.tick(world, this.tickCounter);
}
this.removeAnnihilatedVillages();
this.dropOldestVillagerPosition(world);
this.addNewDoorsToVillageOrCreateVillage();
if (this.tickCounter % 400 == 0)
{
this.dirty = true;
}
}
private void removeAnnihilatedVillages()
{
Iterator<Village> iterator = this.villageList.iterator();
while (iterator.hasNext())
{
Village village = (Village)iterator.next();
if (village.isAnnihilated())
{
iterator.remove();
this.dirty = true;
}
}
}
public List<Village> getVillageList()
{
return this.villageList;
}
public Village getNearestVillage(BlockPos doorBlock, int radius)
{
Village village = null;
double d0 = 3.4028234663852886E38D;
for (Village village1 : this.villageList)
{
double d1 = village1.getCenter().distanceSq(doorBlock);
if (d1 < d0)
{
float f = (float)(radius + village1.getRadius());
if (d1 <= (double)(f * f))
{
village = village1;
d0 = d1;
}
}
}
return village;
}
private void dropOldestVillagerPosition(WorldServer world)
{
if (!this.villagerPositionsList.isEmpty())
{
this.addDoorsAround(world, this.villagerPositionsList.remove(0));
}
}
private void addNewDoorsToVillageOrCreateVillage()
{
for (int i = 0; i < this.newDoors.size(); ++i)
{
VillageDoorInfo villagedoorinfo = (VillageDoorInfo)this.newDoors.get(i);
Village village = this.getNearestVillage(villagedoorinfo.getDoorBlockPos(), 32);
if (village == null)
{
village = new Village();
this.villageList.add(village);
this.dirty = true;
}
village.addDoor(villagedoorinfo);
}
this.newDoors.clear();
}
private void addDoorsAround(WorldServer world, BlockPos central)
{
int i = 16;
int j = 4;
int k = 16;
for (int l = -i; l < i; ++l)
{
for (int i1 = -j; i1 < j; ++i1)
{
for (int j1 = -k; j1 < k; ++j1)
{
BlockPos blockpos = central.add(l, i1, j1);
if (this.isWoodDoor(world, blockpos))
{
VillageDoorInfo villagedoorinfo = this.checkDoorExistence(blockpos);
if (villagedoorinfo == null)
{
this.addToNewDoorsList(world, blockpos);
}
else
{
villagedoorinfo.func_179849_a(this.tickCounter);
}
}
}
}
}
}
private VillageDoorInfo checkDoorExistence(BlockPos doorBlock)
{
for (VillageDoorInfo villagedoorinfo : this.newDoors)
{
if (villagedoorinfo.getDoorBlockPos().getX() == doorBlock.getX() && villagedoorinfo.getDoorBlockPos().getZ() == doorBlock.getZ() && Math.abs(villagedoorinfo.getDoorBlockPos().getY() - doorBlock.getY()) <= 1)
{
return villagedoorinfo;
}
}
for (Village village : this.villageList)
{
VillageDoorInfo villagedoorinfo1 = village.getExistedDoor(doorBlock);
if (villagedoorinfo1 != null)
{
return villagedoorinfo1;
}
}
return null;
}
private void addToNewDoorsList(WorldServer world, BlockPos doorBlock)
{
Facing enumfacing = BlockDoor.getFacing(world, doorBlock);
Facing enumfacing1 = enumfacing.getOpposite();
int i = this.countBlocksCanSeeSky(world, doorBlock, enumfacing, 5);
int j = this.countBlocksCanSeeSky(world, doorBlock, enumfacing1, i + 1);
if (i != j)
{
this.newDoors.add(new VillageDoorInfo(doorBlock, i < j ? enumfacing : enumfacing1, this.tickCounter));
}
}
private int countBlocksCanSeeSky(WorldServer world, BlockPos centerPos, Facing direction, int limitation)
{
int i = 0;
for (int j = 1; j <= 5; ++j)
{
if (world.canSeeSky(centerPos.offset(direction, j)))
{
++i;
if (i >= limitation)
{
return i;
}
}
}
return i;
}
private boolean positionInList(BlockPos pos)
{
for (BlockPos blockpos : this.villagerPositionsList)
{
if (blockpos.equals(pos))
{
return true;
}
}
return false;
}
private boolean isWoodDoor(WorldServer world, BlockPos doorPos)
{
Block block = world.getState(doorPos).getBlock();
return block instanceof BlockDoor ? block.getMaterial() == Material.WOOD : false;
}
public NBTTagCompound writeToNBT()
{
NBTTagCompound nbt = new NBTTagCompound();
nbt.setInteger("Tick", this.tickCounter);
NBTTagList nbttaglist = new NBTTagList();
for (Village village : this.villageList)
{
NBTTagCompound nbttagcompound = new NBTTagCompound();
village.writeVillageDataToNBT(nbttagcompound);
nbttaglist.appendTag(nbttagcompound);
}
nbt.setTag("Villages", nbttaglist);
this.dirty = false;
return nbt;
}
public boolean isDirty()
{
return this.dirty;
}
}

View file

@ -0,0 +1,63 @@
package server.world;
import common.block.Block;
import common.util.BlockPos;
public class BlockEventData
{
private BlockPos position;
private Block blockType;
/** Different for each blockID */
private int eventID;
private int eventParameter;
public BlockEventData(BlockPos pos, Block blockType, int eventId, int p_i45756_4_)
{
this.position = pos;
this.eventID = eventId;
this.eventParameter = p_i45756_4_;
this.blockType = blockType;
}
public BlockPos getPosition()
{
return this.position;
}
/**
* Get the Event ID (different for each BlockID)
*/
public int getEventID()
{
return this.eventID;
}
public int getEventParameter()
{
return this.eventParameter;
}
public Block getBlock()
{
return this.blockType;
}
public boolean equals(Object p_equals_1_)
{
if (!(p_equals_1_ instanceof BlockEventData))
{
return false;
}
else
{
BlockEventData blockeventdata = (BlockEventData)p_equals_1_;
return this.position.equals(blockeventdata.position) && this.eventID == blockeventdata.eventID && this.eventParameter == blockeventdata.eventParameter && this.blockType == blockeventdata.blockType;
}
}
public String toString()
{
return "TE(" + this.position + ")," + this.eventID + "," + this.eventParameter + "," + this.blockType;
}
}

View file

@ -0,0 +1,226 @@
package server.world;
import java.util.Map;
import java.util.Set;
import common.biome.Biome;
import common.block.Block;
import common.entity.Entity;
import common.init.BlockRegistry;
import common.init.Blocks;
import common.log.Log;
import common.rng.Random;
import common.tileentity.TileEntity;
import common.util.BlockPos;
import common.world.BlockArray;
import common.world.Chunk;
import common.world.State;
import common.world.World;
import server.worldgen.BiomeGenerator;
public class ChunkServer extends Chunk {
private long lastSave;
private long inhabited;
public ChunkServer(World world, int x, int z) {
super(world, x, z);
}
public ChunkServer(World world, short[] data, int height, boolean base, boolean ceil, Random rand, Biome[] biomes, int x, int z) {
this(world, x, z);
boolean sky = !world.dimension.hasNoLight();
for(int bx = 0; bx < 16; ++bx) {
for(int bz = 0; bz < 16; ++bz) {
for(int by = 0; by < height; ++by) {
State state = BlockRegistry.STATEMAP.getByValue(data[bx << 4 | bz | by << 8]);
if(state != null && state.getBlock() != Blocks.air) {
int y = by >> 4;
BlockArray arr = this.getArray(y);
if(arr == null) {
arr = new BlockArray(y << 4, sky, null);
this.setArray(arr);
}
arr.set(bx, by & 15, bz, state);
}
}
}
}
if(base) {
Block caves = world.dimension.getCaveFiller().getBlock();
BlockArray arr = this.getArray(0);
if(arr == null) {
arr = new BlockArray(0, sky, null);
this.setArray(arr);
}
for(int bx = 0; bx < 16; ++bx) {
for(int bz = 0; bz < 16; ++bz) {
for(int by = 0; by < 5; ++by) {
if(by <= rand.zrange(5)) {
Block block = arr.get(bx, by, bz).getBlock();
if(block == Blocks.air || block.getMaterial().isLiquid() || block == caves)
arr.set(bx, by, bz, this.filler);
}
}
}
}
}
if(ceil) {
int y = (height - 1) >> 4;
BlockArray arr = this.getArray(y);
if(arr == null) {
arr = new BlockArray(y << 4, sky, null);
this.setArray(arr);
}
y = (height - 5) >> 4;
arr = this.getArray(y);
if(arr == null) {
arr = new BlockArray(y << 4, sky, null);
this.setArray(arr);
}
for(int bx = 0; bx < 16; ++bx) {
for(int bz = 0; bz < 16; ++bz) {
for(int by = height - 1; by >= height - 5; --by) {
if(by >= (height - 1) - rand.zrange(5))
this.getArray(by >> 4).set(bx, by & 15, bz, Blocks.air.getState());
}
}
}
}
for(int n = 0; n < this.biomes.length; ++n) {
this.biomes[n] = (byte)biomes[n].id;
}
if(ceil)
this.resetRelight();
else
this.genSkyLight();
}
public int getTopSegment() {
return this.top;
}
public int getBottomSegment() {
return this.bottom;
}
public Set<BlockArray> getStorage() {
return this.blockList;
}
public void addTileEntity(TileEntity tile) {
this.addTileEntity(tile.getPos(), tile);
if(this.loaded) {
this.world.addTileEntity(tile);
}
}
public void onChunkLoad() {
this.loaded = true;
this.world.addTileEntities(this.tiles.values());
for(int n = 0; n < this.entities.length; ++n) {
for(Entity entity : this.entities[n]) {
entity.onChunkLoad();
}
this.world.loadEntities(this.entities[n]);
}
}
public boolean isDirty(long time) {
if(this.hasEntity && time != this.lastSave || this.modified) {
return true;
}
return this.modified;
}
public void setStorage(BlockArray[] data) {
for(BlockArray arr : data) {
this.setArray(arr);
}
}
public Biome getBiome(BlockPos pos, BiomeGenerator gen) {
int x = pos.getX() & 15;
int z = pos.getZ() & 15;
int o = this.biomes[z << 4 | x] & 255;
if(o == 255) {
Biome biome = gen == null ? Biome.DEF_BIOME : gen.getBiomeGenerator(pos, Biome.DEF_BIOME);
o = biome.id;
this.biomes[z << 4 | x] = (byte)(o & 255);
}
return Biome.getBiomeDef(o);
}
public byte[] getBiomes() {
return this.biomes;
}
public void setBiomes(byte[] biomes) {
if(this.biomes.length != biomes.length) {
Log.IO.warn("Konnte Biome des Chunks nicht setzen, Länge des Arrays ist " + biomes.length + " statt " + this.biomes.length);
}
else {
for(int n = 0; n < this.biomes.length; ++n) {
this.biomes[n] = biomes[n];
}
}
}
public int[] getHeights() {
return this.height;
}
public void setHeights(int[] map) {
if(this.height.length != map.length) {
Log.IO.warn("Konnte Höhen des Chunks nicht setzen, Länge des Arrays ist " + map.length + " statt " + this.height.length);
}
else {
for(int n = 0; n < this.height.length; ++n) {
this.height[n] = map[n];
}
}
}
public Map<BlockPos, TileEntity> getTiles() {
return this.tiles;
}
public boolean isTerrainPopulated() {
return this.populated;
}
public void setTerrainPopulated(boolean populated) {
this.populated = populated;
}
public boolean isLightPopulated() {
return this.lightInit;
}
public void setLightPopulated(boolean populated) {
this.lightInit = populated;
}
public void setModified(boolean modified) {
this.modified = modified;
}
public void setHasEntities(boolean entities) {
this.hasEntity = entities;
}
public void setSaved(long time) {
this.lastSave = time;
}
public long getInhabited() {
return this.inhabited;
}
public void setInhabited(long time) {
this.inhabited = time;
}
}

Some files were not shown because too many files have changed in this diff Show more