<commit_before>package valandur.webapi.servlet.block;

import com.fasterxml.jackson.databind.JsonNode;
import com.flowpowered.math.vector.Vector3i;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.block.BlockType;
import org.spongepowered.api.block.trait.BlockTrait;
import org.spongepowered.api.util.Tuple;
import org.spongepowered.api.world.extent.BlockVolume;
import valandur.webapi.WebAPI;
import valandur.webapi.api.annotation.WebAPIRoute;
import valandur.webapi.api.annotation.WebAPIServlet;
import valandur.webapi.api.block.IBlockUpdate;
import valandur.webapi.api.cache.world.CachedWorld;
import valandur.webapi.api.servlet.WebAPIBaseServlet;
import valandur.webapi.services.BlockService;
import valandur.webapi.servlet.ServletData;
import valandur.webapi.util.Util;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@WebAPIServlet(basePath = "block")
public class BlockServlet extends WebAPIBaseServlet {

    @WebAPIRoute(method = "GET", path = "/:world/:x/:y/:z", perm = "one")
    public void getBlock(ServletData data, CachedWorld world, int x, int y, int z) {
        Optional<BlockState> state = blockService.getBlockAt(world, new Vector3i(x, y, z));
        if (!state.isPresent()) {
            data.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not get world " + world.getName());
            return;
        }

        data.addJson("ok", true, false);
        data.addJson("block", state.get(), true);
    }

    @WebAPIRoute(method = "GET", path = "/:world/:minX/:minY/:minZ/:maxX/:maxY/:maxZ", perm = "volume")
    public void getBlockVolume(ServletData data, CachedWorld world, int minX, int minY, int minZ,
                               int maxX, int maxY, int maxZ) {
        // Swap around min & max if needed
        int tmpX = Math.max(minX, maxX);
        minX = Math.min(minX, maxX);
        maxX = tmpX;

        // Swap around min & max if needed
        int tmpY = Math.max(minY, maxY);
        minY = Math.min(minY, maxY);
        maxY = tmpY;

        // Swap around min & max if needed
        int tmpZ = Math.max(minZ, maxZ);
        minZ = Math.min(minZ, maxZ);
        maxZ = tmpZ;

        // Check volume size
        int numBlocks = Math.abs((1 + maxX - minX) * (1 + maxY - minY) * (1 + maxZ - minZ));
        if (BlockService.MAX_BLOCK_GET_SIZE > 0 && numBlocks > BlockService.MAX_BLOCK_GET_SIZE) {
            data.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE, "Size is " + numBlocks +
                    " blocks, which is larger than the maximum of " + BlockService.MAX_BLOCK_GET_SIZE + " blocks");
            return;
        }

        Optional<BlockVolume> vol = blockService.getBlockVolume(world, new Vector3i(minX, minY, minZ), new Vector3i(maxX, maxY, maxZ));
        if (!vol.isPresent()) {
            data.sendError(HttpServletResponse.SC_NOT_FOUND, "Could not get world");
            return;
        }

        data.addJson("ok", true, false);
        data.addJson("volume", vol.get(), true);
    }

    @WebAPIRoute(method = "POST", path = "/", perm = "set")
    public void setBlocks(ServletData data) {
        JsonNode reqJson = data.getRequestBody();

        if (reqJson == null || !reqJson.isArray()) {
            data.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid areas");
            return;
        }

        int blocksSet = 0;

        // Process areas
        for (JsonNode area : reqJson) {
            JsonNode wNode = area.get("world");<commit_msg>fix(block): Return block location when fetching just a single block<commit_after>package valandur.webapi.servlet.block;

import com.fasterxml.jackson.databind.JsonNode;
import com.flowpowered.math.vector.Vector3i;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.block.BlockState;
import org.spongepowered.api.block.BlockType;
import org.spongepowered.api.block.trait.BlockTrait;
import org.spongepowered.api.util.Tuple;
import org.spongepowered.api.world.extent.BlockVolume;
import valandur.webapi.WebAPI;
import valandur.webapi.api.annotation.WebAPIRoute;
import valandur.webapi.api.annotation.WebAPIServlet;
import valandur.webapi.api.block.IBlockUpdate;
import valandur.webapi.api.cache.world.CachedWorld;
import valandur.webapi.api.servlet.WebAPIBaseServlet;
import valandur.webapi.services.BlockService;
import valandur.webapi.servlet.ServletData;
import valandur.webapi.util.Util;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

@WebAPIServlet(basePath = "block")
public class BlockServlet extends WebAPIBaseServlet {

    @WebAPIRoute(method = "GET", path = "/:world/:x/:y/:z", perm = "one")
    public void getBlock(ServletData data, CachedWorld world, int x, int y, int z) {
        Vector3i pos = new Vector3i(x, y, z);
        Optional<BlockState> state = blockService.getBlockAt(world, pos);
        if (!state.isPresent()) {
            data.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Could not get world " + world.getName());
            return;
        }

        data.addJson("ok", true, false);
        data.addJson("position", pos, false);
        data.addJson("block", state.get(), true);
    }

    @WebAPIRoute(method = "GET", path = "/:world/:minX/:minY/:minZ/:maxX/:maxY/:maxZ", perm = "volume")
    public void getBlockVolume(ServletData data, CachedWorld world, int minX, int minY, int minZ,
                               int maxX, int maxY, int maxZ) {
        // Swap around min & max if needed
        int tmpX = Math.max(minX, maxX);
        minX = Math.min(minX, maxX);
        maxX = tmpX;

        // Swap around min & max if needed
        int tmpY = Math.max(minY, maxY);
        minY = Math.min(minY, maxY);
        maxY = tmpY;

        // Swap around min & max if needed
        int tmpZ = Math.max(minZ, maxZ);
        minZ = Math.min(minZ, maxZ);
        maxZ = tmpZ;

        // Check volume size
        int numBlocks = Math.abs((1 + maxX - minX) * (1 + maxY - minY) * (1 + maxZ - minZ));
        if (BlockService.MAX_BLOCK_GET_SIZE > 0 && numBlocks > BlockService.MAX_BLOCK_GET_SIZE) {
            data.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE, "Size is " + numBlocks +
                    " blocks, which is larger than the maximum of " + BlockService.MAX_BLOCK_GET_SIZE + " blocks");
            return;
        }

        Vector3i min = new Vector3i(minX, minY, minZ);
        Vector3i max = new Vector3i(maxX, maxY, maxZ);
        Optional<BlockVolume> vol = blockService.getBlockVolume(world, min, max);
        if (!vol.isPresent()) {
            data.sendError(HttpServletResponse.SC_NOT_FOUND, "Could not get world");
            return;
        }

        data.addJson("ok", true, false);
        data.addJson("volume", vol.get(), true);
    }

    @WebAPIRoute(method = "POST", path = "/", perm = "set")
    public void setBlocks(ServletData data) {
        JsonNode reqJson = data.getRequestBody();

        if (reqJson == null || !reqJson.isArray()) {
            data.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid areas");
            return;
        }

        int blocksSet = 0;

        // Process areas
        for (JsonNode area : reqJson) {
            JsonNode wNode = area.get("world");
{'fraction_non_alphanumeric': 0.12298662298662298, 'fraction_numerical': 0.0028665028665028664, 'mean_word_length': 2.8767195767195766, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3138519', 'n_tokens_mistral': 2354, 'n_tokens_neox': 2335, 'n_words': 518}