Skip to content

Commit

Permalink
cleanup, reverted caching (should reduce RAM usage)
Browse files Browse the repository at this point in the history
  • Loading branch information
trichner committed Nov 20, 2014
1 parent ede5dd4 commit a21a230
Show file tree
Hide file tree
Showing 6 changed files with 356 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ out
.metadata
.idea
.idea/
Metropolis.iml
*.iml
metropolis.properties
bin
.vagrant
Expand Down
Binary file added lib/spigot1649.jar
Binary file not shown.
13 changes: 13 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,19 @@
-->

<!-- Local Libraries-->
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot</artifactId>
<version>1649</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/spigot1649.jar</systemPath>
</dependency>

<dependency>
<groupId>org.jboss.weld.se</groupId>
<artifactId>weld-se</artifactId>
<version>2.2.1.Final</version>
</dependency>

<dependency>
<groupId>org.worldedit</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
package ch.k42.metropolis.grid.urbanGrid.clipboard;


import ch.k42.metropolis.grid.urbanGrid.config.GlobalSchematicConfig;
import ch.k42.metropolis.grid.urbanGrid.config.SchematicConfig;
import ch.k42.metropolis.grid.urbanGrid.enums.ContextType;
import ch.k42.metropolis.grid.urbanGrid.enums.Direction;
import ch.k42.metropolis.minions.Cartesian2D;
import ch.k42.metropolis.minions.Minions;
import com.sk89q.worldedit.CuboidClipboard;
import com.sk89q.worldedit.data.DataException;
import com.sk89q.worldedit.schematic.SchematicFormat;
import org.bukkit.Bukkit;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
Expand All @@ -14,18 +25,6 @@
import java.util.Map;
import java.util.Set;

import org.bukkit.Bukkit;

import ch.k42.metropolis.grid.urbanGrid.config.GlobalSchematicConfig;
import ch.k42.metropolis.grid.urbanGrid.config.SchematicConfig;
import ch.k42.metropolis.grid.urbanGrid.enums.ContextType;
import ch.k42.metropolis.grid.urbanGrid.enums.Direction;
import ch.k42.metropolis.minions.Cartesian2D;
import ch.k42.metropolis.minions.Minions;
import com.sk89q.worldedit.CuboidClipboard;
import com.sk89q.worldedit.data.DataException;
import com.sk89q.worldedit.schematic.SchematicFormat;

/**
* Created by Thomas on 07.03.14.
*/
Expand Down Expand Up @@ -102,7 +101,7 @@ public Map<String,Clipboard> loadSchematics(File schematicsFolder,File cacheFold

Set<String> cachedHashes = getCachedHashes(cacheFolder);

for(int i=0;i<length;i++){ // TODO use threads http://www.javapractices.com/topic/TopicAction.do?Id=247, maybe even load async in Clipboard
for(int i=0;i<length;i++){
File file = schematicFiles.get(i);

Minions.i("Loading schematic %4d of %d (%.2f%%) : %s" ,i,length,(i/(double) length)*100,file.getName());
Expand Down Expand Up @@ -193,13 +192,7 @@ public Map<String,Clipboard> loadSchematics(File schematicsFolder,File cacheFold
cachedHashes.remove(hash); // caching it now, take it out, we wan't to delete unused caches
}
}
} catch (IOException e) {
Minions.e(e);
continue;
} catch (DataException e) {
Minions.e(e);
continue;
} catch (NoSuchAlgorithmException e) {
} catch (IOException | DataException | NoSuchAlgorithmException e) {
Minions.e(e);
continue;
}
Expand Down Expand Up @@ -253,7 +246,11 @@ private boolean loadFromCache(File file,String hash,Direction direction,Schemati
try {
SchematicFormat format = SchematicFormat.getFormat(file);
CuboidClipboard cuboid = format.load(file);
Clipboard clip = new ClipboardWE(cuboid,config,globalConfig,hash);

Clipboard clip = new FileClipboard(file,config,globalConfig,hash);//new ClipboardWE(cuboid,config,
// globalConfig,
// hash);

String thash = hash + "." + direction.name();
clipstore.put(thash,clip);

Expand All @@ -271,9 +268,7 @@ private boolean loadFromCache(File file,String hash,Direction direction,Schemati
System.gc();

return true;
} catch (IOException e) {
Minions.e(e);
} catch (DataException e) {
} catch (IOException | DataException e) {
Minions.e(e);
}
return false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
package ch.k42.metropolis.grid.urbanGrid.clipboard;


import ch.k42.metropolis.generator.MetropolisGenerator;
import ch.k42.metropolis.grid.urbanGrid.config.GlobalSchematicConfig;
import ch.k42.metropolis.grid.urbanGrid.config.SchematicConfig;
import ch.k42.metropolis.grid.urbanGrid.provider.EnvironmentProvider;
import ch.k42.metropolis.minions.Cartesian2D;
import ch.k42.metropolis.minions.Cartesian3D;
import ch.k42.metropolis.minions.DirtyHacks;
import ch.k42.metropolis.minions.GridRandom;
import ch.k42.metropolis.minions.Minions;
import ch.k42.metropolis.plugin.PluginConfig;
import com.sk89q.worldedit.CuboidClipboard;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.data.DataException;
import com.sk89q.worldedit.schematic.SchematicFormat;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.Chest;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.entity.EntityType;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* Created by Thomas on 07.03.14.
*/
public class FileClipboard implements Clipboard{
private File file;
private SchematicConfig config;
private GlobalSchematicConfig globalConfig;
private List<Cartesian3D> chests = new ArrayList<>();
private List<Cartesian3D> spawners = new ArrayList<>();
private int blockCount;
private String groupId;

public FileClipboard(File file, SchematicConfig config, GlobalSchematicConfig globalConfig,
String groupId) {
this.file = file;
this.config = config;
this.globalConfig = globalConfig;

CuboidClipboard cuboid = loadCuboid();

this.blockCount = cuboid.getHeight()*cuboid.getLength()*cuboid.getWidth();
this.groupId = groupId;
if(config.getGroundLevelY()==0){
config.setGroundLevelY(estimateStreetLevel());
}
}

public CuboidClipboard loadCuboid(){
SchematicFormat format = SchematicFormat.getFormat(file);
try {
return format.load(file);
} catch (IOException | DataException e) {
Minions.e(e);
throw new RuntimeException("Failed to reload clipboard, possible corrupted cache.",e);
}
}

@Override
public void paste(MetropolisGenerator generator, Cartesian2D base, int streetLevel) {
int blockY = getBottom(streetLevel);
Vector at = new Vector(base.X << 4, blockY , base.Y << 4);
try {
EditSession editSession = getEditSession(generator);
editSession.setFastMode(true);

//place Schematic
place(generator, editSession, at);

//fill chests
World world = generator.getWorld();
GridRandom rand = generator.getGridProvider().getGrid(base.X,base.Y).getRandom();
Cartesian3D base3 = new Cartesian3D(base.X<< 4, blockY, base.Y<< 4);

if (PluginConfig.isChestRenaming()) { //do we really want to name them all?
for (Cartesian3D c : chests) {
Cartesian3D temp = base3.add(c);
Block block = world.getBlockAt(temp.X, temp.Y, temp.Z);
if (block.getType() == Material.CHEST) {
if (!rand.getChance(config.getChestOdds())) { //we were unlucky, chest doesn't get placed{
block.setType(Material.AIR);
} else { //rename chest


try {
Chest chest = (Chest) block.getState(); //block has to be a chest
String name = DirtyHacks.getChestName(chest);
name = validateChestName(rand, name);
nameChest(chest, name);
}catch (NullPointerException e){
Minions.d("NPE while naming chest.");
}
}
} else {
Minions.d("Chest coordinates were wrong! (" + block + ")");
}
}
}

//set spawners

if (PluginConfig.isSpawnerPlacing()) { // do we even place any?
for (Cartesian3D c : spawners) {
Cartesian3D temp = base3.add(c);
Block block = world.getBlockAt(temp.X, temp.Y, temp.Z);

if (block.getType() == Material.SPONGE) {
if (!rand.getChance(config.getSpawnerOdds())) { //we were unlucky, chest doesn't get placed{
block.setType(Material.AIR);
} else { //set spawn type
block.setType(Material.MOB_SPAWNER);
if (block.getState() instanceof CreatureSpawner) {
CreatureSpawner spawner = (CreatureSpawner) block.getState(); //block has to be a chest
spawner.setSpawnedType(getSpawnedEntity(rand));
//generator.reportDebug("Placed a spawner!");
} else {
//generator.reportDebug("Unable to place Spawner.");
}
}
} else {
Minions.w("Spawner coordinates were wrong!");
}
}
}
} catch (MaxChangedBlocksException e) { //FIXME don't catch generic Exception!!!!
Minions.w("Placing schematic failed. WorldEdit fucked up.");
Minions.e(e);
}
}

@Override
public Cartesian3D getSize() {
CuboidClipboard cuboid = loadCuboid();
return new Cartesian3D(cuboid.getWidth(),cuboid.getHeight(),cuboid.getLength());
}


private void place(MetropolisGenerator generator, EditSession editSession, Vector pos) throws MaxChangedBlocksException {
CuboidClipboard cuboid = loadCuboid();
EnvironmentProvider natureDecay = generator.getNatureDecayProvider();
chests.clear();
spawners.clear();
for (int x = 0; x < cuboid.getWidth(); x++) {
for (int y = 0; y < cuboid.getHeight(); y++) {
for (int z = 0; z < cuboid.getLength(); z++) {

BaseBlock block = cuboid.getBlock(new Vector(x, y, z));
Vector vec = new Vector(x, y, z).add(pos);
Material decay = natureDecay.checkBlock(generator.getWorld(), (int) vec.getX(), (int) vec.getY(), (int) vec.getZ());

if (decay != null) {
block.setType(decay.getId());
continue;
}

if (block.getId() == Material.CHEST.getId()) {
chests.add(new Cartesian3D(x, y, z));
} else if (block.getId() == Material.SPONGE.getId()) {
spawners.add(new Cartesian3D(x, y, z));
}
editSession.setBlock(vec, block);
}
}
}

}

public int getBottom(int streetLevel) {
return streetLevel - config.getGroundLevelY();
}

@Override
public SchematicConfig getConfig() {
return config;
}

@Override
public String getGroupId() {
return groupId;
}

private EditSession getEditSession(MetropolisGenerator generator) {
return new EditSession(new BukkitWorld(generator.getWorld()), blockCount);
}

private EntityType getSpawnedEntity(GridRandom random) {
if (config.getSpawners() == null) {
if (globalConfig.getSpawners() == null) {
return EntityType.ZOMBIE; // All settings failed
} else {
config.setSpawners(globalConfig.getSpawners());
}
}
return config.getRandomSpawnerEntity(random);
}

private void nameChest(Chest chest, String name) { //there might be no better way...
DirtyHacks.setChestName(chest, name);
}

private static final char COLOR = ChatColor.GREEN.getChar();

private String validateChestName(GridRandom rand, String name) {

//chest has level? -> Assumption: Chest fully named

char lastchar = name.charAt(name.length() - 1);
boolean fail;
try {

int level = Integer.parseInt(String.valueOf(lastchar));
fail = level > 5 || level < 1;
} catch (NumberFormatException e) {
fail = true;
}

if (fail) {
if (lastchar == '_') { //append only level
name += Integer.toString(randomChestLevel(rand)); //add a random chest level
} else { // set name and level
name = getNameAndLevel(rand);
}
}
return name;
}

private String getNameAndLevel(GridRandom rand) {
StringBuffer buf = new StringBuffer();
if (config.getLootCollections().length > 0) {
buf.append('§')
.append(COLOR)
.append(config.getRandomLootCollection(rand).name)
.append('_')
.append(Integer.toString(randomChestLevel(rand)));
return buf.toString();
} else {
return "";
}
}

private int randomChestLevel(GridRandom random) {
int min = config.getLootMinLevel();
int max = config.getLootMaxLevel();
return globalConfig.getRandomChestLevel(random, min, max);
}

/**
* estimates the street level of a schematic, useful for bootstrapping settings
*
* @return
*/
private int estimateStreetLevel() {
CuboidClipboard cuboid = loadCuboid();
if (cuboid.getHeight() - 2 < 0) return 1;

for (int y = cuboid.getHeight() - 2; y >= 0; y--) {
int b = cuboid.getPoint(new Vector(0, y, 0)).getType();
if (b != Material.AIR.getId() && b != Material.LONG_GRASS.getId() && b != Material.YELLOW_FLOWER.getId())
return y + 1;
}
return 1;
}

@Override
public String toString() {
return "Clipboard: " + config.getPath();
}
}
Loading

0 comments on commit a21a230

Please sign in to comment.