Skip to content

Commit

Permalink
Updated wildcard icon
Browse files Browse the repository at this point in the history
  • Loading branch information
LatvianModder committed Aug 21, 2024
1 parent 5c89d99 commit b561e36
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import dev.latvian.mods.kubejs.util.CachedComponentObject;
import dev.latvian.mods.kubejs.util.Cast;
import dev.latvian.mods.kubejs.web.KJSHTTPRequest;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
Expand Down Expand Up @@ -75,7 +76,7 @@ public class ImageGenerator {
new Vector3f(0.625F, 0.625F, 0.625F)
);

public static final ResourceLocation STAR_TEXTURE = KubeJS.id("textures/misc/star.png");
public static final ResourceLocation WILDCARD_TEXTURE = KubeJS.id("textures/misc/wildcard.png");

private record RenderImage(Minecraft mc, GuiGraphics graphics, int size) {
}
Expand All @@ -94,27 +95,42 @@ public boolean equals(Object o) {

public static final Int2ObjectMap<TextureTarget> FB_CACHE = new Int2ObjectArrayMap<>();

private static HTTPResponse renderCanvas(KJSHTTPRequest req, int canvasSize, String dir, @Nullable UUID cacheUUID, Consumer<RenderImage> render) {
public static TextureTarget getCanvas(int size) {
var target = FB_CACHE.get(size);

if (target == null) {
target = new TextureTarget(size, size, true, Minecraft.ON_OSX);
target.setClearColor(0.54F, 0.54F, 0.54F, 0F);
FB_CACHE.put(size, target);
}

return target;
}

private static HTTPResponse renderCanvas(KJSHTTPRequest req, int canvasSize, String dir, @Nullable ByteBuf cacheBuf, boolean wildcard, Consumer<RenderImage> render) {
int size = Integer.parseInt(req.variable("size"));

if (size < 1 || size > 1024) {
return HTTPStatus.BAD_REQUEST.text("Invalid size, must be [1, 1024]");
}

var cacheUUIDStr = cacheUUID == null || req.query().containsKey("uncached") ? null : UUIDWrapper.toString(cacheUUID);
if (req.query().containsKey("uncached")) {
cacheBuf = null;
}

if (cacheBuf != null) {
cacheBuf.writeBoolean(wildcard);
}

var cacheUUIDStr = cacheBuf == null ? null : UUIDWrapper.toString(UUID.nameUUIDFromBytes(cacheBuf.array()));
var cachePath = cacheUUIDStr == null ? null : KubeJSPaths.dir(KubeJSPaths.LOCAL.resolve("cache/web/img/" + dir + "/" + cacheUUIDStr.substring(0, 2))).resolve(cacheUUIDStr + "_" + size + ".png");

if (cachePath != null && Files.exists(cachePath)) {
return HTTPResponse.ok().content(cachePath).header("X-KubeJS-Cache-Key", cacheUUIDStr);
}

var bytes = req.supplyInMainThread(() -> {
var target = FB_CACHE.get(size);

if (target == null) {
target = new TextureTarget(size, size, true, Minecraft.ON_OSX);
FB_CACHE.put(size, target);
}
var target = getCanvas(size);

var mc = Minecraft.getInstance();
var bufferSource = mc.renderBuffers().bufferSource();
Expand All @@ -131,6 +147,13 @@ private static HTTPResponse renderCanvas(KJSHTTPRequest req, int canvasSize, Str

GuiGraphics graphics = new GuiGraphics(mc, bufferSource);
render.accept(new RenderImage(mc, graphics, size));

if (wildcard) {
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
graphics.blit(WILDCARD_TEXTURE, 0, 0, 300, 0F, 0F, 16, 16, 16, 16);
}

graphics.flush();

target.bindRead();
Expand All @@ -139,6 +162,20 @@ private static HTTPResponse renderCanvas(KJSHTTPRequest req, int canvasSize, Str
try (var image = new NativeImage(size, size, false)) {
image.downloadTexture(0, false);
image.flipY();

for (int y = 0; y < size; y++) {
for (int x = 0; x < size; x++) {
int color = image.getPixelRGBA(x, y);
int a = (color >> 24) & 0xFF;

if (a == 0) {
image.setPixelRGBA(x, y, 0);
} else if (a < 255) {
image.setPixelRGBA(x, y, (color & 0xFFFFFF) | 0xFF000000);
}
}
}

return image.asByteArray();
} catch (Exception ex) {
ex.printStackTrace();
Expand All @@ -162,14 +199,18 @@ private static HTTPResponse renderCanvas(KJSHTTPRequest req, int canvasSize, Str
return HTTPResponse.ok().content(bytes, "image/png").header("X-KubeJS-Cache-Key", cacheUUIDStr);
}

private static HTTPResponse renderAnimated(KJSHTTPRequest req, String dir, @Nullable UUID cacheUUID, List<HTTPResponse> responses) throws Exception {
private static HTTPResponse renderAnimated(KJSHTTPRequest req, String dir, @Nullable ByteBuf cacheBuf, List<HTTPResponse> responses) throws Exception {
int size = Integer.parseInt(req.variable("size"));

if (size < 1 || size > 1024) {
return HTTPStatus.BAD_REQUEST.text("Invalid size, must be [1, 1024]");
}

var cacheUUIDStr = cacheUUID == null || req.query().containsKey("uncached") ? null : UUIDWrapper.toString(cacheUUID);
if (req.query().containsKey("uncached")) {
cacheBuf = null;
}

var cacheUUIDStr = cacheBuf == null ? null : UUIDWrapper.toString(UUID.nameUUIDFromBytes(cacheBuf.array()));
var cachePath = cacheUUIDStr == null ? null : KubeJSPaths.dir(KubeJSPaths.LOCAL.resolve("cache/web/img/" + dir + "/" + cacheUUIDStr.substring(0, 2))).resolve(cacheUUIDStr + "_" + size + ".gif");

if (cachePath != null && Files.exists(cachePath)) {
Expand All @@ -180,9 +221,8 @@ private static HTTPResponse renderAnimated(KJSHTTPRequest req, String dir, @Null
var encoder = new AnimatedGifEncoder();
encoder.start(outputStream);
encoder.setSize(size, size);
var backgroundColor = new Color(43, 51, 51, 255);
encoder.setBackground(backgroundColor);
encoder.setTransparent(backgroundColor, true);
encoder.setBackground(Color.BLUE);
encoder.setTransparent(Color.BLUE, false);

encoder.setRepeat(0);
encoder.setDelay(1000);
Expand Down Expand Up @@ -220,36 +260,29 @@ private static HTTPResponse renderAnimated(KJSHTTPRequest req, String dir, @Null
public static HTTPResponse item(KJSHTTPRequest req) throws Exception {
var stack = BuiltInRegistries.ITEM.get(req.id()).getDefaultInstance();
stack.applyComponents(req.components(req.registries().nbt()));
return renderItem(req, stack, req.query().containsKey("star"));
return renderItem(req, stack, req.query().containsKey("wildcard"));
}

private static HTTPResponse renderItem(KJSHTTPRequest req, ItemStack stack, boolean star) throws Exception {
public static HTTPResponse renderItem(KJSHTTPRequest req, ItemStack stack, boolean wildcard) {
if (stack.isEmpty()) {
return HTTPStatus.NOT_FOUND;
}

var buf = new FriendlyByteBuf(Unpooled.buffer());
CachedComponentObject.writeCacheKey(buf, stack.getItem(), DataComponentWrapper.visualPatch(stack.getComponentsPatch()));
buf.writeBoolean(star);

return renderCanvas(req, 16, "item", UUID.nameUUIDFromBytes(buf.array()), render -> {
return renderCanvas(req, 16, "item", buf, wildcard, render -> {
render.graphics.renderFakeItem(stack, 0, 0, 0);
render.graphics.renderItemDecorations(render.mc.font, stack, 0, 0);

if (star) {
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
render.graphics.blit(STAR_TEXTURE, 0, 0, 300, 0F, 0F, 6, 6, 6, 6);
}
});
}

public static HTTPResponse block(KJSHTTPRequest req) throws Exception {
var state = BlockWrapper.withProperties(BuiltInRegistries.BLOCK.get(req.id()).defaultBlockState(), req.query());
return renderBlock(req, state, req.query().containsKey("star"));
return renderBlock(req, state, req.query().containsKey("wildcard"));
}

private static HTTPResponse renderBlock(KJSHTTPRequest req, BlockState state, boolean star) throws Exception {
public static HTTPResponse renderBlock(KJSHTTPRequest req, BlockState state, boolean wildcard) {
if (state.isEmpty()) {
return HTTPStatus.NOT_FOUND;
}
Expand All @@ -270,9 +303,7 @@ private static HTTPResponse renderBlock(KJSHTTPRequest req, BlockState state, bo
}
}

buf.writeBoolean(star);

return renderCanvas(req, 16, "block", UUID.nameUUIDFromBytes(buf.array()), render -> {
return renderCanvas(req, 16, "block", buf, wildcard, render -> {
var model = render.mc.getBlockRenderer().getBlockModel(state);
var pose = render.graphics.pose();
pose.pushPose();
Expand Down Expand Up @@ -310,22 +341,16 @@ private static HTTPResponse renderBlock(KJSHTTPRequest req, BlockState state, bo
}

render.graphics.pose().popPose();

if (star) {
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
render.graphics.blit(STAR_TEXTURE, 0, 0, 300, 0F, 0F, 6, 6, 6, 6);
}
});
}

public static HTTPResponse fluid(KJSHTTPRequest req) throws Exception {
var stack = new FluidStack(BuiltInRegistries.FLUID.get(req.id()), FluidType.BUCKET_VOLUME);
stack.applyComponents(req.components(req.registries().nbt()));
return renderFluid(req, stack, req.query().containsKey("star"));
return renderFluid(req, stack, req.query().containsKey("wildcard"));
}

public static HTTPResponse renderFluid(KJSHTTPRequest req, FluidStack stack, boolean star) throws Exception {
public static HTTPResponse renderFluid(KJSHTTPRequest req, FluidStack stack, boolean wildcard) {
if (stack.isEmpty()) {
return HTTPStatus.NOT_FOUND;
}
Expand All @@ -340,9 +365,8 @@ public static HTTPResponse renderFluid(KJSHTTPRequest req, FluidStack stack, boo

var buf = new FriendlyByteBuf(Unpooled.buffer());
CachedComponentObject.writeCacheKey(buf, stack.getFluid(), DataComponentWrapper.visualPatch(stack.getComponentsPatch()));
buf.writeBoolean(star);

return renderCanvas(req, 16, "fluid", UUID.nameUUIDFromBytes(buf.array()), render -> {
return renderCanvas(req, 16, "fluid", buf, wildcard, render -> {
var s = render.mc.getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(still);
RenderSystem.setShaderTexture(0, TextureAtlas.LOCATION_BLOCKS);
RenderSystem.setShader(GameRenderer::getPositionTexColorShader);
Expand All @@ -353,12 +377,6 @@ public static HTTPResponse renderFluid(KJSHTTPRequest req, FluidStack stack, boo
builder.addVertex(m, 16F, 16F, 0F).setUv(s.getU1(), s.getV0()).setColor(r, g, b, a);
builder.addVertex(m, 16F, 0F, 0F).setUv(s.getU1(), s.getV1()).setColor(r, g, b, a);
BufferUploader.drawWithShader(builder.buildOrThrow());

if (star) {
RenderSystem.enableBlend();
RenderSystem.defaultBlendFunc();
render.graphics.blit(STAR_TEXTURE, 0, 0, 300, 0F, 0F, 6, 6, 6, 6);
}
});
}

Expand All @@ -377,7 +395,7 @@ public static HTTPResponse itemTag(KJSHTTPRequest req) throws Exception {
list.add(renderItem(req, holder.value().getDefaultInstance(), true));
}

return renderAnimated(req, "item_tag", UUID.nameUUIDFromBytes(buf.array()), list);
return renderAnimated(req, "item_tag", buf, list);
}

public static HTTPResponse blockTag(KJSHTTPRequest req) throws Exception {
Expand All @@ -402,7 +420,7 @@ public static HTTPResponse blockTag(KJSHTTPRequest req) throws Exception {
}
}

return renderAnimated(req, "block_tag", UUID.nameUUIDFromBytes(buf.array()), list);
return renderAnimated(req, "block_tag", buf, list);
}

public static HTTPResponse fluidTag(KJSHTTPRequest req) throws Exception {
Expand All @@ -420,7 +438,7 @@ public static HTTPResponse fluidTag(KJSHTTPRequest req) throws Exception {
list.add(renderFluid(req, new FluidStack(holder, FluidType.BUCKET_VOLUME), true));
}

return renderAnimated(req, "fluid_tag", UUID.nameUUIDFromBytes(buf.array()), list);
return renderAnimated(req, "fluid_tag", buf, list);
}

private static class ContentGrabber extends HTTPResponseBuilder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,9 @@ public class KubeJSClientWeb {
public static void register(LocalWebServerRegistry registry) {
KubeJSWeb.addScriptTypeEndpoints(registry, ScriptType.CLIENT, KubeJS.getClientScriptManager()::reload);

registry.get("/api/client/search/items", KubeJSClientWeb::getItemsResponse);
registry.get("/api/client/search/blocks", KubeJSClientWeb::getBlocksResponse);
registry.get("/api/client/search/fluids", KubeJSClientWeb::getFluidsResponse);
registry.get("/api/client/search/items", KubeJSClientWeb::getSearchItems);
registry.get("/api/client/search/blocks", KubeJSClientWeb::getSearchBlocks);
registry.get("/api/client/search/fluids", KubeJSClientWeb::getSearchFluids);

registry.get("/api/client/assets/list/<prefix>", KubeJSClientWeb::getAssetList);
registry.get("/api/client/assets/get/{namespace}/<path>", KubeJSClientWeb::getAssetContent);
Expand Down Expand Up @@ -90,7 +90,7 @@ private static HTTPResponse getScreenshot(KJSHTTPRequest req) {
return HTTPResponse.ok().content(bytes, "image/png");
}

private static HTTPResponse getItemsResponse(KJSHTTPRequest req) {
private static HTTPResponse getSearchItems(KJSHTTPRequest req) {
return HTTPResponse.ok().content(JsonContent.object(json -> {
var jsonOps = Minecraft.getInstance().level == null ? req.registries().json() : Minecraft.getInstance().level.registryAccess().createSerializationContext(JsonOps.INSTANCE);
var nbtOps = Minecraft.getInstance().level == null ? req.registries().nbt() : Minecraft.getInstance().level.registryAccess().createSerializationContext(NbtOps.INSTANCE);
Expand Down Expand Up @@ -126,6 +126,16 @@ private static HTTPResponse getItemsResponse(KJSHTTPRequest req) {
}
}

var tags = new JsonArray();

for (var t : item.value().builtInRegistryHolder().tags().toList()) {
tags.add(t.location().toString());
}

if (!tags.isEmpty()) {
o.add("tags", tags);
}

results.add(o);
}

Expand All @@ -134,23 +144,45 @@ private static HTTPResponse getItemsResponse(KJSHTTPRequest req) {
}));
}

private static HTTPResponse getBlocksResponse(KJSHTTPRequest req) {
private static HTTPResponse getSearchBlocks(KJSHTTPRequest req) {
return HTTPResponse.ok().content(JsonContent.array(json -> {
for (var block : BuiltInRegistries.BLOCK) {
var o = new JsonObject();
o.addProperty("id", block.kjs$getId());
o.addProperty("name", Component.translatable(block.getDescriptionId()).getString());

var tags = new JsonArray();

for (var t : block.builtInRegistryHolder().tags().toList()) {
tags.add(t.location().toString());
}

if (!tags.isEmpty()) {
o.add("tags", tags);
}

json.add(o);
}
}));
}

private static HTTPResponse getFluidsResponse(KJSHTTPRequest req) {
private static HTTPResponse getSearchFluids(KJSHTTPRequest req) {
return HTTPResponse.ok().content(JsonContent.array(json -> {
for (var fluid : BuiltInRegistries.FLUID) {
var o = new JsonObject();
o.addProperty("id", fluid.kjs$getId());
o.addProperty("name", fluid.getFluidType().getDescription().getString());

var tags = new JsonArray();

for (var t : fluid.builtInRegistryHolder().tags().toList()) {
tags.add(t.location().toString());
}

if (!tags.isEmpty()) {
o.add("tags", tags);
}

json.add(o);
}
}));
Expand Down
Binary file not shown.

This file was deleted.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit b561e36

Please sign in to comment.