sten.wtf / STEN Vault source

In-house snapshot of sten-vault 2.3.2. GPL-3.0-or-later. Isolated from the dashboard.

src/main/java/wtf/sten/vault/Shot.java

package wtf.sten.vault;

import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.NativeImage;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.Minecraft;
import net.minecraft.client.Screenshot;

import java.nio.file.Files;
import java.nio.file.Path;

public final class Shot {
	private static final int MAX_BYTES = 180_000;

	private Shot() {
	}

	public static void capture(Minecraft mc, String kind) {
		try {
			if (mc == null || mc.gameRenderer == null) return;
			RenderTarget target = mc.gameRenderer.mainRenderTarget();
			if (target == null || target.width < 2 || target.height < 2) return;
			int factor = downscale(target.width, target.height);
			Screenshot.takeScreenshot(target, factor, image -> write(image, kind));
		} catch (Exception ignored) {
		}
	}

	static int downscale(int width, int height) {
		for (int factor : new int[]{8, 4, 2}) {
			if (width % factor == 0 && height % factor == 0) return factor;
		}
		return 1;
	}

	private static void write(NativeImage image, String kind) {
		NativeImage current = image;
		try {
			int guard = 0;
			while (true) {
				Path tmp = FabricLoader.getInstance().getGameDir().resolve("sten-vault-shot.png");
				current.writeToFile(tmp);
				byte[] bytes = Files.readAllBytes(tmp);
				Files.deleteIfExists(tmp);
				if (bytes.length <= MAX_BYTES || current.getWidth() <= 160 || guard++ > 4) {
					if (bytes.length <= MAX_BYTES) {
						StenNet.uploadShot(kind == null || kind.isBlank() ? "auto" : kind, bytes);
					}
					return;
				}
				NativeImage next = shrink(current);
				if (next == current) return;
				if (current != image) current.close();
				current = next;
			}
		} catch (Exception ignored) {
		} finally {
			if (current != null && current != image) current.close();
			image.close();
		}
	}

	private static NativeImage shrink(NativeImage src) {
		int width = Math.max(160, src.getWidth() / 2);
		int height = Math.max(1, src.getHeight() * width / src.getWidth());
		if (width >= src.getWidth()) return src;
		NativeImage dst = new NativeImage(width, height, false);
		src.resizeSubRectTo(0, 0, src.getWidth(), src.getHeight(), dst);
		return dst;
	}
}