add max structure recursion depth

This commit is contained in:
dfsek
2021-01-07 16:38:07 -07:00
parent 64391f3abc
commit d2a1901f44
5 changed files with 31 additions and 8 deletions
@@ -45,6 +45,7 @@ public class StructureScript {
private final String id; private final String id;
String tempID; String tempID;
private final Map<Location, StructureBuffer> cache; private final Map<Location, StructureBuffer> cache;
private final TerraPlugin main;
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, SamplerCache cache) throws ParseException { public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, SamplerCache cache) throws ParseException {
Parser parser; Parser parser;
@@ -81,6 +82,7 @@ public class StructureScript {
block = parser.parse(); block = parser.parse();
this.id = parser.getID(); this.id = parser.getID();
tempID = id; tempID = id;
this.main = main;
this.cache = Collections.synchronizedMap(new LinkedHashMap<Location, StructureBuffer>() { this.cache = Collections.synchronizedMap(new LinkedHashMap<Location, StructureBuffer>() {
@Override @Override
protected boolean removeEldestEntry(Map.Entry<Location, StructureBuffer> eldest) { protected boolean removeEldestEntry(Map.Entry<Location, StructureBuffer> eldest) {
@@ -98,9 +100,9 @@ public class StructureScript {
*/ */
public boolean execute(Location location, Random random, Rotation rotation) { public boolean execute(Location location, Random random, Rotation rotation) {
StructureBuffer buffer = new StructureBuffer(location); StructureBuffer buffer = new StructureBuffer(location);
Block.ReturnInfo<?> level = block.apply(new TerraImplementationArguments(buffer, rotation, random, 0)); boolean level = applyBlock(new TerraImplementationArguments(buffer, rotation, random, 0));
buffer.paste(); buffer.paste();
return !level.getLevel().equals(Block.ReturnLevel.FAIL); return level;
} }
public boolean execute(Location location, Chunk chunk, Random random, Rotation rotation) { public boolean execute(Location location, Chunk chunk, Random random, Rotation rotation) {
@@ -118,23 +120,31 @@ public class StructureScript {
synchronized(cache) { synchronized(cache) {
return cache.computeIfAbsent(location, loc -> { return cache.computeIfAbsent(location, loc -> {
StructureBuffer buf = new StructureBuffer(loc); StructureBuffer buf = new StructureBuffer(loc);
Block.ReturnInfo<?> level = block.apply(new TerraImplementationArguments(buf, rotation, random, 0)); buf.setSucceeded(applyBlock(new TerraImplementationArguments(buf, rotation, random, 0)));
buf.setSucceeded(!level.getLevel().equals(Block.ReturnLevel.FAIL));
return buf; return buf;
}); });
} }
} }
public boolean executeInBuffer(Buffer buffer, Random random, Rotation rotation, int recursions) { public boolean executeInBuffer(Buffer buffer, Random random, Rotation rotation, int recursions) {
return !block.apply(new TerraImplementationArguments(buffer, rotation, random, recursions)).getLevel().equals(Block.ReturnLevel.FAIL); return applyBlock(new TerraImplementationArguments(buffer, rotation, random, recursions));
} }
public boolean executeDirect(Location location, Random random, Rotation rotation) { public boolean executeDirect(Location location, Random random, Rotation rotation) {
DirectBuffer buffer = new DirectBuffer(location); DirectBuffer buffer = new DirectBuffer(location);
return !block.apply(new TerraImplementationArguments(buffer, rotation, random, 0)).getLevel().equals(Block.ReturnLevel.FAIL); return applyBlock(new TerraImplementationArguments(buffer, rotation, random, 0));
} }
public String getId() { public String getId() {
return id; return id;
} }
private boolean applyBlock(TerraImplementationArguments arguments) {
try {
return !block.apply(arguments).getLevel().equals(Block.ReturnLevel.FAIL);
} catch(RuntimeException e) {
main.getLogger().severe("Failed to generate structure at " + arguments.getBuffer().getOrigin() + ": " + e.getMessage());
return false;
}
}
} }
@@ -45,6 +45,9 @@ public class StructureFunction implements Function<Boolean> {
public Boolean apply(ImplementationArguments implementationArguments) { public Boolean apply(ImplementationArguments implementationArguments) {
TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments; TerraImplementationArguments arguments = (TerraImplementationArguments) implementationArguments;
if(arguments.getRecursions() > main.getTerraConfig().getMaxRecursion())
throw new RuntimeException("Structure recursion too deep: " + arguments.getRecursions());
Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue()); Vector2 xz = new Vector2(x.apply(implementationArguments).doubleValue(), z.apply(implementationArguments).doubleValue());
RotationUtil.rotateVector(xz, arguments.getRotation()); RotationUtil.rotateVector(xz, arguments.getRotation());
@@ -20,7 +20,7 @@ public class BufferedLootApplication implements BufferedItem {
public void paste(Location origin) { public void paste(Location origin) {
BlockState data = origin.getBlock().getState(); BlockState data = origin.getBlock().getState();
if(!(data instanceof Container)) { if(!(data instanceof Container)) {
main.getLogger().severe("Failed to place loot at " + origin + "; block " + data.toString() + " is not container."); main.getLogger().severe("Failed to place loot at " + origin + "; block " + data + " is not container.");
return; return;
} }
Container container = (Container) data; Container container = (Container) data;
@@ -51,6 +51,10 @@ public class PluginConfig implements ConfigTemplate {
@Default @Default
private boolean dumpDefaultConfig = true; private boolean dumpDefaultConfig = true;
@Value("script.max-recursion")
@Default
private int maxRecursion = 1000;
public void load(TerraPlugin main) { public void load(TerraPlugin main) {
Logger logger = main.getLogger(); Logger logger = main.getLogger();
logger.info("Loading config values"); logger.info("Loading config values");
@@ -99,4 +103,8 @@ public class PluginConfig implements ConfigTemplate {
public int getSamplerCache() { public int getSamplerCache() {
return samplerCache; return samplerCache;
} }
public int getMaxRecursion() {
return maxRecursion;
}
} }
@@ -8,4 +8,6 @@ cache:
structure: 32 structure: 32
sampler: 128 sampler: 128
master-disable: master-disable:
caves: false caves: false
script:
max-recursion: 1000