Skip to content

Commit

Permalink
- Adds a new "search radius" option that controls the range at which …
Browse files Browse the repository at this point in the history
…players can see ores

- Adds nether ores to the default config, closes #2
- Switches to a thread pool, closes #3
- Slight performance improvements
  • Loading branch information
Haven-King committed Dec 15, 2020
1 parent 7cc2d18 commit e2b0b49
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 52 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/run/
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ repositories {
}

minecraft {
accessWidener "src/main/resources/sax.accesswidener"
}

dependencies {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ yarn_mappings = 1.16.4+build.1
loader_version = 0.10.6+build.214

# Mod Properties
mod_version = 0.1.0
mod_version = 0.2.0
maven_group = dev.hephaestus
archives_base_name = sax

Expand Down
55 changes: 43 additions & 12 deletions src/main/java/dev/hephaestus/sax/server/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public class Config {
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public static final HashMap<Block, Block> HIDDEN = new HashMap<>();

public static byte SEARCH_RADIUS = 30;

static {
HIDDEN.put(Blocks.DIAMOND_ORE, Blocks.STONE);
HIDDEN.put(Blocks.IRON_ORE, Blocks.STONE);
Expand All @@ -32,35 +34,64 @@ public class Config {
HIDDEN.put(Blocks.LAPIS_ORE, Blocks.STONE);
HIDDEN.put(Blocks.MOSSY_COBBLESTONE, Blocks.STONE);
HIDDEN.put(Blocks.SPAWNER, Blocks.CAVE_AIR);
HIDDEN.put(Blocks.NETHER_GOLD_ORE, Blocks.NETHERRACK);
HIDDEN.put(Blocks.NETHER_QUARTZ_ORE, Blocks.NETHERRACK);
HIDDEN.put(Blocks.ANCIENT_DEBRIS, Blocks.NETHERRACK);
}

public static void load() {
Path configDir = FabricLoader.getInstance().getConfigDir().normalize().resolve("sax");
Path configFile = configDir.resolve("blocks.json");
loadOptions(configDir, configDir.resolve("options.json"));
loadBlocks(configDir, configDir.resolve("blocks.json"));
}

private static void loadOptions(Path dir, Path file) {
try {
if (!Files.exists(file)) {
Files.createDirectories(dir);

JsonObject options = new JsonObject();

options.addProperty("search_radius", SEARCH_RADIUS);

Writer writer = Files.newBufferedWriter(file);
writer.write(GSON.toJson(options));
writer.close();
} else {
JsonObject options = JsonHelper.deserialize(Files.newBufferedReader(file));
SEARCH_RADIUS = options.get("search_radius").getAsByte();

}
} catch (IOException e) {
e.printStackTrace();
}

}

private static void loadBlocks(Path dir, Path file) {
try {
if (!Files.exists(configFile)) {
Files.createDirectories(configDir);
if (!Files.exists(file)) {
Files.createDirectories(dir);

JsonObject jsonObject = new JsonObject();
JsonObject blocks = new JsonObject();

for (Map.Entry<Block, Block> entry : HIDDEN.entrySet()) {
jsonObject.addProperty(
Registry.BLOCK.getId(entry.getKey()).toString(),
Registry.BLOCK.getId(entry.getValue()).toString()
blocks.addProperty(
Registry.BLOCK.getId(entry.getKey()).toString(),
Registry.BLOCK.getId(entry.getValue()).toString()
);
}

Writer writer = Files.newBufferedWriter(configFile);
writer.write(GSON.toJson(jsonObject));
Writer writer = Files.newBufferedWriter(file);
writer.write(GSON.toJson(blocks));
writer.close();
} else {
HIDDEN.clear();

for (Map.Entry<String, JsonElement> element : JsonHelper.deserialize(Files.newBufferedReader(configFile)).entrySet()) {
for (Map.Entry<String, JsonElement> element : JsonHelper.deserialize(Files.newBufferedReader(file)).entrySet()) {
HIDDEN.put(
Registry.BLOCK.get(new Identifier(element.getKey())),
Registry.BLOCK.get(new Identifier(element.getValue().getAsString()))
Registry.BLOCK.get(new Identifier(element.getKey())),
Registry.BLOCK.get(new Identifier(element.getValue().getAsString()))
);
}
}
Expand Down
88 changes: 49 additions & 39 deletions src/main/java/dev/hephaestus/sax/server/DeObfuscator.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,61 +11,68 @@
import net.minecraft.util.shape.VoxelShape;
import net.minecraft.world.BlockView;
import net.minecraft.world.RaycastContext;
import org.apache.commons.lang3.mutable.MutableBoolean;

import java.util.HashSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.function.Consumer;

public class DeObfuscator {
private static final byte SEARCH_RADIUS = 30;
import static dev.hephaestus.sax.server.Config.SEARCH_RADIUS;

public class DeObfuscator {
private final ServerPlayerEntity player;
private final HashSet<Vec3i> revealed = new HashSet<>();
private final HashSet<BlockPos> revealed = new HashSet<>();
private final BlockPos.Mutable mutable = new BlockPos.Mutable();

private Thread thread = null;
private final RaycastContext raycastContext;
private final ExecutorService executor;
private final MutableBoolean finished = new MutableBoolean(true);

public DeObfuscator(ServerPlayerEntity player) {
this.player = player;
this.raycastContext = new RaycastContext(
Vec3d.ZERO, Vec3d.ZERO, RaycastContext.ShapeType.VISUAL, RaycastContext.FluidHandling.NONE, player
);

executor = Executors.newSingleThreadExecutor((runnable) -> {
Thread thread = new Thread(runnable);
thread.setDaemon(true);
return thread;
});
}

public void tick() {
if (thread == null || !thread.isAlive()) {
thread = new Thread(() -> {
Vec3d origin = this.player.getCameraPosVec(1F);

for (Vec3i pos : this.revealed) {
if (!pos.isWithinDistance(origin, SEARCH_RADIUS)) {
this.sendBlockUpdate(new BlockPos(pos), this.player.networkHandler::sendPacket);
}
}
if (finished.booleanValue()) {
executor.submit(() -> {
finished.setFalse();
Vec3d origin = this.raycastContext.start = this.player.getCameraPosVec(1F);

this.revealed.removeIf(pos -> !pos.isWithinDistance(origin, SEARCH_RADIUS));

for (byte x = -SEARCH_RADIUS; x <= SEARCH_RADIUS; ++x) {
for (byte y = -SEARCH_RADIUS; y <= SEARCH_RADIUS; ++y) {
for (byte z = -SEARCH_RADIUS; z <= SEARCH_RADIUS; ++z) {
for (byte x = (byte) -SEARCH_RADIUS; x <= SEARCH_RADIUS; ++x) {
for (byte y = (byte) -SEARCH_RADIUS; y <= SEARCH_RADIUS; ++y) {
for (byte z = (byte) -SEARCH_RADIUS; z <= SEARCH_RADIUS; ++z) {
if (x * x + y * y + z * z <= SEARCH_RADIUS * SEARCH_RADIUS) {
mutable.set(origin.x, origin.y, origin.z);
mutable.move(x, y, z);

if (Config.HIDDEN.containsKey(this.player.world.getBlockState(mutable).getBlock())) {
Vec3i pos = mutable.toImmutable();

if (!this.revealed.contains(pos)) {
if (this.traceForBlock(this.player, pos)) {
if (!this.revealed.contains(mutable)) {
if (this.traceForBlock(origin, mutable)) {
BlockPos pos = mutable.toImmutable();
this.revealed.add(pos);
this.sendBlockUpdate(new BlockPos(pos), this.player.networkHandler.connection::send);
this.sendBlockUpdate(pos, this.player.networkHandler.connection::send);
}
}
}
}
}
}
}
});

thread.setDaemon(true);
thread.start();
finished.setTrue();
});
}
}

Expand All @@ -75,22 +82,25 @@ private void sendBlockUpdate(BlockPos pos, Consumer<BlockUpdateS2CPacket> consum
}
}

private boolean traceForBlock(ServerPlayerEntity player, Vec3i target) {
private boolean traceForBlock(Vec3d origin, Vec3i target) {
Vec3d pos = new Vec3d(origin.x, origin.y, origin.z);

for (byte dX = 0; dX <= 1; ++dX) {
for (byte dY = 0; dY <= 1; ++dY) {
for (byte dZ = 0; dZ <= 1; ++dZ) {
Vec3d pos = new Vec3d(target.getX() + dX, target.getY() + dY, target.getZ() + dZ);
RaycastContext context = new RaycastContext(
player.getCameraPosVec(1F),
pos,
RaycastContext.ShapeType.VISUAL, RaycastContext.FluidHandling.NONE, player
);
// We want to avoid creating a ton of new vectors.
pos.x = target.getX() + dX;
pos.y = target.getY() + dY;
pos.z = target.getZ() + dZ;

BlockHitResult hitResult = rayTrace(context);
// Also avoiding making new RaycastContext's.
this.raycastContext.end = pos;

if (hitResult.getPos().isInRange(pos, 0.5F)) {
return true;
}
BlockHitResult hitResult = rayTrace(this.raycastContext);

if (hitResult.getPos().isInRange(pos, 0.5F)) {
return true;
}
}
}
}
Expand All @@ -102,10 +112,10 @@ private BlockHitResult rayTrace(RaycastContext context) {
BlockView blockView = this.player.world;
return BlockView.raycast(context, (rayTraceContext, blockPos) -> {
BlockState blockState = blockView.getBlockState(blockPos);
Vec3d vec3d = rayTraceContext.getStart();
Vec3d vec3d2 = rayTraceContext.getEnd();
Vec3d start = rayTraceContext.getStart();
Vec3d end = rayTraceContext.getEnd();
VoxelShape voxelShape = rayTraceContext.getBlockShape(blockState, blockView, blockPos);
return blockView.raycastBlock(vec3d, vec3d2, blockPos, voxelShape, blockState);
return blockView.raycastBlock(start, end, blockPos, voxelShape, blockState);
}, (rayTraceContext) -> {
Vec3d vec3d = rayTraceContext.getStart().subtract(rayTraceContext.getEnd());
return BlockHitResult.createMissed(rayTraceContext.getEnd(), Direction.getFacing(vec3d.x, vec3d.y, vec3d.z), new BlockPos(rayTraceContext.getEnd()));
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/fabric.mod.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"mixins": [
"sax.mixins.json"
],
"accessWidener": "sax.accesswidener",
"depends": {
"fabricloader": ">=0.8.9+build.203",
"fabric": "*",
Expand Down
8 changes: 8 additions & 0 deletions src/main/resources/sax.accesswidener
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
accessWidener v1 named
mutable field net/minecraft/util/math/Vec3d x D
mutable field net/minecraft/util/math/Vec3d y D
mutable field net/minecraft/util/math/Vec3d z D
mutable field net/minecraft/world/RaycastContext end Lnet/minecraft/util/math/Vec3d;
accessible field net/minecraft/world/RaycastContext end Lnet/minecraft/util/math/Vec3d;
mutable field net/minecraft/world/RaycastContext start Lnet/minecraft/util/math/Vec3d;
accessible field net/minecraft/world/RaycastContext start Lnet/minecraft/util/math/Vec3d;

0 comments on commit e2b0b49

Please sign in to comment.