Add throttled player-position tracking, mod side (Phase 7b)
Adds PlayerPosition (common/protocol) and BackendConnection.sendPlayerPositions(),
wired into MCMapperMod.java: a new playerPositionIntervalTicks-throttled tick timer
(gated by playerTrackingEnabled) sends the full current overworld online-player
roster to the backend each interval, mirroring the "current state, not a diff"
philosophy of columns/sections — a player logging out just stops appearing next
send, no separate leave message needed.
Wire message: {"type":"player_positions","dimension":0,"players":[...]}.
Backend-side receive/relay + admin visibility toggle land in a follow-up commit.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015tKdPZt78zbPUZMXWzKEKt
This commit is contained in:
@@ -5,8 +5,11 @@ import com.octoturge.mcmapper.common.DefaultBackendConnection;
|
||||
import com.octoturge.mcmapper.common.ReconciliationScheduler;
|
||||
import com.octoturge.mcmapper.common.config.MapperConfig;
|
||||
import com.octoturge.mcmapper.common.protocol.DeltaEvent;
|
||||
import com.octoturge.mcmapper.common.protocol.PlayerPosition;
|
||||
import com.octoturge.mcmapper.common.protocol.SectionData;
|
||||
import net.minecraft.entity.player.EntityPlayerMP;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.common.config.Configuration;
|
||||
@@ -33,7 +36,9 @@ import java.util.Set;
|
||||
* 3D mesh rendering. Phase 3 adds `/mcmapper link` and the two-way chat bridge (see LinkCommand,
|
||||
* Forge1122ChatBridge). Phase 7 adds a periodic reconciliation sweep (see {@link
|
||||
* ReconciliationScheduler}) that catches non-event mutations (world-gen, other mods, `/fill`)
|
||||
* the event-driven hooks in {@link Forge1122ChunkAdapter} never see.
|
||||
* the event-driven hooks in {@link Forge1122ChunkAdapter} never see. Phase 7b adds throttled
|
||||
* online-player position tracking (config-gated via {@code playerTrackingEnabled}), overworld
|
||||
* only — see {@link #sendPlayerPositions()}.
|
||||
*/
|
||||
@Mod(modid = MCMapperMod.MOD_ID, name = "MCMapper", version = MCMapperMod.VERSION)
|
||||
public class MCMapperMod {
|
||||
@@ -49,8 +54,10 @@ public class MCMapperMod {
|
||||
private final List<DeltaEvent> pendingDeltas = Collections.synchronizedList(new ArrayList<>());
|
||||
private final Set<Long> pendingSectionChunks = Collections.synchronizedSet(new LinkedHashSet<>());
|
||||
private final ReconciliationScheduler reconciliationScheduler = new ReconciliationScheduler();
|
||||
private MinecraftServer mcServer;
|
||||
private int ticksSinceFlush = 0;
|
||||
private int ticksSinceReconciliation = 0;
|
||||
private int ticksSincePlayerPositions = 0;
|
||||
|
||||
@Mod.EventHandler
|
||||
public void preInit(FMLPreInitializationEvent event) {
|
||||
@@ -75,6 +82,14 @@ public class MCMapperMod {
|
||||
config.reconciliationChunksPerSweep = forgeConfig.getInt("reconciliationChunksPerSweep", "network",
|
||||
config.reconciliationChunksPerSweep, 1, 5000,
|
||||
"Max chunks to re-read and resend per reconciliation sweep");
|
||||
config.playerTrackingEnabled = forgeConfig.getBoolean("playerTrackingEnabled", "network",
|
||||
config.playerTrackingEnabled,
|
||||
"Whether to send throttled online-player positions to the backend at all. The " +
|
||||
"backend also has its own per-server admin toggle deciding whether it " +
|
||||
"relays this on to web viewers — this setting only controls the mod side.");
|
||||
config.playerPositionIntervalTicks = forgeConfig.getInt("playerPositionIntervalTicks", "network",
|
||||
config.playerPositionIntervalTicks, 5, 20 * 60,
|
||||
"How often (in ticks) to send the online-player roster to the backend, when playerTrackingEnabled");
|
||||
if (forgeConfig.hasChanged()) forgeConfig.save();
|
||||
}
|
||||
|
||||
@@ -85,6 +100,7 @@ public class MCMapperMod {
|
||||
return;
|
||||
}
|
||||
|
||||
mcServer = event.getServer();
|
||||
connection = new DefaultBackendConnection(LOGGER::info, LOGGER::warn);
|
||||
connection.connect(config.backendUrl, config.serverToken);
|
||||
LOGGER.info("MCMapper (1.12.2 leaf) connecting to " + config.backendUrl);
|
||||
@@ -130,6 +146,21 @@ public class MCMapperMod {
|
||||
ticksSinceReconciliation = 0;
|
||||
reconcile();
|
||||
}
|
||||
|
||||
if (config.playerTrackingEnabled && ++ticksSincePlayerPositions >= config.playerPositionIntervalTicks) {
|
||||
ticksSincePlayerPositions = 0;
|
||||
sendPlayerPositions();
|
||||
}
|
||||
}
|
||||
|
||||
private void sendPlayerPositions() {
|
||||
List<PlayerPosition> players = new ArrayList<>();
|
||||
for (EntityPlayerMP player : mcServer.getPlayerList().getPlayers()) {
|
||||
if (player.dimension != 0) continue;
|
||||
players.add(new PlayerPosition(player.getUniqueID().toString(), player.getName(),
|
||||
MathHelper.floor(player.posX), MathHelper.floor(player.posY), MathHelper.floor(player.posZ)));
|
||||
}
|
||||
connection.sendPlayerPositions(0, players);
|
||||
}
|
||||
|
||||
private void reconcile() {
|
||||
|
||||
Reference in New Issue
Block a user