fix image preview and add option for automatically stop auto screenshoting when idle

This commit is contained in:
iceBear67
2026-08-07 19:00:20 +00:00
parent 014b18f1ba
commit 30d124fd8b
22 changed files with 641 additions and 32 deletions
@@ -1,13 +1,16 @@
package dev.photosync.platform.impl;
import dev.photosync.core.capture.CameraPose;
import dev.photosync.mcapi.GameContext;
import lombok.extern.slf4j.Slf4j;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
/** Ambient client state, the render thread, and the way out of the game. */
@Slf4j
@@ -34,6 +37,20 @@ public final class GameAdapter implements GameContext {
return Minecraft.getInstance().screen != null;
}
/**
* The camera entity rather than the player, so that a spectator following
* someone else is judged on what the screenshot will actually show. It falls
* back to the player, and is null until one exists.
*/
@Override
public Optional<CameraPose> cameraPose() {
Entity camera = Minecraft.getInstance().getCameraEntity();
return camera == null
? Optional.empty()
: Optional.of(new CameraPose(camera.getX(), camera.getY(), camera.getZ(),
camera.getYRot(), camera.getXRot()));
}
@Override
public Path configDirectory() {
return configDirectory;
@@ -1,13 +1,16 @@
package dev.photosync.platform.impl;
import dev.photosync.core.capture.CameraPose;
import dev.photosync.mcapi.GameContext;
import lombok.extern.slf4j.Slf4j;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
/** Ambient client state, the render thread, and the way out of the game. */
@Slf4j
@@ -34,6 +37,20 @@ public final class GameAdapter implements GameContext {
return Minecraft.getInstance().screen != null;
}
/**
* The camera entity rather than the player, so that a spectator following
* someone else is judged on what the screenshot will actually show. It falls
* back to the player, and is null until one exists.
*/
@Override
public Optional<CameraPose> cameraPose() {
Entity camera = Minecraft.getInstance().getCameraEntity();
return camera == null
? Optional.empty()
: Optional.of(new CameraPose(camera.getX(), camera.getY(), camera.getZ(),
camera.getYRot(), camera.getXRot()));
}
@Override
public Path configDirectory() {
return configDirectory;
@@ -1,13 +1,16 @@
package dev.photosync.platform.impl;
import dev.photosync.core.capture.CameraPose;
import dev.photosync.mcapi.GameContext;
import lombok.extern.slf4j.Slf4j;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
/** Ambient client state, the render thread, and the way out of the game. */
@Slf4j
@@ -34,6 +37,20 @@ public final class GameAdapter implements GameContext {
return Minecraft.getInstance().screen != null;
}
/**
* The camera entity rather than the player, so that a spectator following
* someone else is judged on what the screenshot will actually show. It falls
* back to the player, and is null until one exists.
*/
@Override
public Optional<CameraPose> cameraPose() {
Entity camera = Minecraft.getInstance().getCameraEntity();
return camera == null
? Optional.empty()
: Optional.of(new CameraPose(camera.getX(), camera.getY(), camera.getZ(),
camera.getYRot(), camera.getXRot()));
}
@Override
public Path configDirectory() {
return configDirectory;
@@ -1,13 +1,16 @@
package dev.photosync.platform.impl;
import dev.photosync.core.capture.CameraPose;
import dev.photosync.mcapi.GameContext;
import lombok.extern.slf4j.Slf4j;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
/** Ambient client state, the render thread, and the way out of the game. */
@Slf4j
@@ -34,6 +37,20 @@ public final class GameAdapter implements GameContext {
return Minecraft.getInstance().screen != null;
}
/**
* The camera entity rather than the player, so that a spectator following
* someone else is judged on what the screenshot will actually show. It falls
* back to the player, and is null until one exists.
*/
@Override
public Optional<CameraPose> cameraPose() {
Entity camera = Minecraft.getInstance().getCameraEntity();
return camera == null
? Optional.empty()
: Optional.of(new CameraPose(camera.getX(), camera.getY(), camera.getZ(),
camera.getYRot(), camera.getXRot()));
}
@Override
public Path configDirectory() {
return configDirectory;
@@ -1,13 +1,16 @@
package dev.photosync.platform.impl;
import dev.photosync.core.capture.CameraPose;
import dev.photosync.mcapi.GameContext;
import lombok.extern.slf4j.Slf4j;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.util.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
/** Ambient client state, the render thread, and the way out of the game. */
@Slf4j
@@ -34,6 +37,20 @@ public final class GameAdapter implements GameContext {
return Minecraft.getInstance().screen != null;
}
/**
* The camera entity rather than the player, so that a spectator following
* someone else is judged on what the screenshot will actually show. It falls
* back to the player, and is null until one exists.
*/
@Override
public Optional<CameraPose> cameraPose() {
Entity camera = Minecraft.getInstance().getCameraEntity();
return camera == null
? Optional.empty()
: Optional.of(new CameraPose(camera.getX(), camera.getY(), camera.getZ(),
camera.getYRot(), camera.getXRot()));
}
@Override
public Path configDirectory() {
return configDirectory;
@@ -1,13 +1,16 @@
package dev.photosync.platform.impl;
import dev.photosync.core.capture.CameraPose;
import dev.photosync.mcapi.GameContext;
import lombok.extern.slf4j.Slf4j;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
/** Ambient client state, the render thread, and the way out of the game. */
@Slf4j
@@ -34,6 +37,20 @@ public final class GameAdapter implements GameContext {
return Minecraft.getInstance().screen != null;
}
/**
* The camera entity rather than the player, so that a spectator following
* someone else is judged on what the screenshot will actually show. It falls
* back to the player, and is null until one exists.
*/
@Override
public Optional<CameraPose> cameraPose() {
Entity camera = Minecraft.getInstance().getCameraEntity();
return camera == null
? Optional.empty()
: Optional.of(new CameraPose(camera.getX(), camera.getY(), camera.getZ(),
camera.getYRot(), camera.getXRot()));
}
@Override
public Path configDirectory() {
return configDirectory;
@@ -1,13 +1,16 @@
package dev.photosync.platform.impl;
import dev.photosync.core.capture.CameraPose;
import dev.photosync.mcapi.GameContext;
import lombok.extern.slf4j.Slf4j;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
/** Ambient client state, the render thread, and the way out of the game. */
@Slf4j
@@ -34,6 +37,20 @@ public final class GameAdapter implements GameContext {
return Minecraft.getInstance().screen != null;
}
/**
* The camera entity rather than the player, so that a spectator following
* someone else is judged on what the screenshot will actually show. It falls
* back to the player, and is null until one exists.
*/
@Override
public Optional<CameraPose> cameraPose() {
Entity camera = Minecraft.getInstance().getCameraEntity();
return camera == null
? Optional.empty()
: Optional.of(new CameraPose(camera.getX(), camera.getY(), camera.getZ(),
camera.getYRot(), camera.getXRot()));
}
@Override
public Path configDirectory() {
return configDirectory;
@@ -1,13 +1,16 @@
package dev.photosync.platform.impl;
import dev.photosync.core.capture.CameraPose;
import dev.photosync.mcapi.GameContext;
import lombok.extern.slf4j.Slf4j;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
/** Ambient client state, the render thread, and the way out of the game. */
@Slf4j
@@ -34,6 +37,20 @@ public final class GameAdapter implements GameContext {
return Minecraft.getInstance().screen != null;
}
/**
* The camera entity rather than the player, so that a spectator following
* someone else is judged on what the screenshot will actually show. It falls
* back to the player, and is null until one exists.
*/
@Override
public Optional<CameraPose> cameraPose() {
Entity camera = Minecraft.getInstance().getCameraEntity();
return camera == null
? Optional.empty()
: Optional.of(new CameraPose(camera.getX(), camera.getY(), camera.getZ(),
camera.getYRot(), camera.getXRot()));
}
@Override
public Path configDirectory() {
return configDirectory;
@@ -1,13 +1,16 @@
package dev.photosync.platform.impl;
import dev.photosync.core.capture.CameraPose;
import dev.photosync.mcapi.GameContext;
import lombok.extern.slf4j.Slf4j;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.util.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.Entity;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
/** Ambient client state, the render thread, and the way out of the game. */
@Slf4j
@@ -35,6 +38,20 @@ public final class GameAdapter implements GameContext {
return Minecraft.getInstance().gui.screen() != null;
}
/**
* The camera entity rather than the player, so that a spectator following
* someone else is judged on what the screenshot will actually show. It falls
* back to the player, and is null until one exists.
*/
@Override
public Optional<CameraPose> cameraPose() {
Entity camera = Minecraft.getInstance().getCameraEntity();
return camera == null
? Optional.empty()
: Optional.of(new CameraPose(camera.getX(), camera.getY(), camera.getZ(),
camera.getYRot(), camera.getXRot()));
}
@Override
public Path configDirectory() {
return configDirectory;