Phase 0: scaffold Gradle multi-project mod skeleton
common/ (shared source) plus three leaf modules: forge-1_12_2 (primary, Enigmatica 2 target) and forge-1_7_10 both build via anatawa12's Gradle-7-compatible ForgeGradle 1.2/2.3 forks (verified: both leaves build clean on Gradle 7.6 / JDK 8). neoforge-26_1 is structurally scaffolded but excluded from the default build pending its own toolchain in Phase 10.
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package com.octoturge.mcmapper.common;
|
||||
|
||||
import com.octoturge.mcmapper.common.protocol.DeltaEvent;
|
||||
import com.octoturge.mcmapper.common.protocol.LinkRequest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Outbound WS client to the backend `api` service. One implementation shared by all leaf
|
||||
* modules (pure Java, no Minecraft API usage) — a docker-network hostname, LAN IP, or public
|
||||
* domain in {@code MapperConfig#backendUrl} all work identically.
|
||||
*
|
||||
* Left as an interface with a no-op stub for Phase 0 scaffolding; the real WS client
|
||||
* (handshake, reconnect/backoff, batching) lands in Phase 1.
|
||||
*/
|
||||
public interface BackendConnection {
|
||||
void connect(String url, String serverToken);
|
||||
|
||||
void sendDeltas(List<DeltaEvent> deltas);
|
||||
|
||||
void sendLinkRequest(LinkRequest request);
|
||||
|
||||
void disconnect();
|
||||
|
||||
final class NoOp implements BackendConnection {
|
||||
@Override
|
||||
public void connect(String url, String serverToken) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendDeltas(List<DeltaEvent> deltas) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendLinkRequest(LinkRequest request) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void disconnect() {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.octoturge.mcmapper.common;
|
||||
|
||||
import com.octoturge.mcmapper.common.protocol.WaypointShare;
|
||||
|
||||
/**
|
||||
* Loader-specific chat integration. Implementations inject web-originated chat into real
|
||||
* in-game chat, and build the clickable waypoint chat component for whichever
|
||||
* {@link WaypointShare.Format} is configured — that's text-component API and is different
|
||||
* per Minecraft era, so it can't live in {@code common}.
|
||||
*/
|
||||
public interface ChatBridge {
|
||||
void injectWebChatMessage(String displayName, String message);
|
||||
|
||||
void injectWaypointShare(WaypointShare waypoint);
|
||||
|
||||
/** Called by the loader's own chat event hook; forwards to the backend over the WS connection. */
|
||||
interface OutboundSink {
|
||||
void onInGameChatMessage(String uuid, String username, String message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.octoturge.mcmapper.common;
|
||||
|
||||
import com.octoturge.mcmapper.common.protocol.DeltaEvent;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The seam between a specific Minecraft/Forge API generation and the shared delta-capture and
|
||||
* networking logic. Each leaf module (forge-1_7_10, forge-1_12_2, neoforge-26_1) provides one
|
||||
* implementation, adapting its own era's block-id/block-state representation into the
|
||||
* {@code blockStateId} carried by {@link DeltaEvent}.
|
||||
*/
|
||||
public interface ChunkAdapter {
|
||||
/** Bulk-read a chunk's current state for initial sync / reconciliation, as delta events. */
|
||||
List<DeltaEvent> readChunk(String dimension, int chunkX, int chunkZ);
|
||||
|
||||
/** Register the loader-specific hooks (block place/break, chunk load/unload) that feed the dirty buffer. */
|
||||
void registerEventHooks(DeltaSink sink);
|
||||
|
||||
interface DeltaSink {
|
||||
void onDelta(DeltaEvent event);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.octoturge.mcmapper.common.config;
|
||||
|
||||
/**
|
||||
* Loader-agnostic config model. Each leaf module owns loading/saving these values through
|
||||
* its own loader's config system (Forge Config API for the legacy leaves, NeoForge's config
|
||||
* system for neoforge-26_1) and constructs one of these to hand to the common connection code.
|
||||
*/
|
||||
public class MapperConfig {
|
||||
public String backendUrl = "ws://localhost:3000/ws";
|
||||
public String serverToken = "";
|
||||
|
||||
public boolean playerTrackingEnabled = true;
|
||||
public int deltaFlushIntervalTicks = 20;
|
||||
public int reconciliationIntervalTicks = 20 * 60 * 5;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.octoturge.mcmapper.common.protocol;
|
||||
|
||||
/**
|
||||
* A single block change, produced by either the event-driven capture path or the periodic
|
||||
* reconciliation sweep. {@code blockStateId} is a palette index into whatever block/state
|
||||
* palette the leaf module's {@code ChunkAdapter} maintains — the common module never
|
||||
* interprets it, it just carries it to the backend.
|
||||
*/
|
||||
public class DeltaEvent {
|
||||
public final String dimension;
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int z;
|
||||
public final int blockStateId;
|
||||
public final long timestamp;
|
||||
public final Source source;
|
||||
|
||||
public DeltaEvent(String dimension, int x, int y, int z, int blockStateId, long timestamp, Source source) {
|
||||
this.dimension = dimension;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.blockStateId = blockStateId;
|
||||
this.timestamp = timestamp;
|
||||
this.source = source;
|
||||
}
|
||||
|
||||
public enum Source {
|
||||
EVENT,
|
||||
RECONCILIATION
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.octoturge.mcmapper.common.protocol;
|
||||
|
||||
/**
|
||||
* Sent when a player runs the link command in-game. {@code authMode} mirrors the MC server's
|
||||
* own online-mode setting and tells the backend whether {@code uuid} is a real Mojang UUID
|
||||
* (safe to merge across servers) or an offline-mode hash (scoped to this server only).
|
||||
*/
|
||||
public class LinkRequest {
|
||||
public final String uuid;
|
||||
public final String username;
|
||||
public final String code;
|
||||
public final AuthMode authMode;
|
||||
|
||||
public LinkRequest(String uuid, String username, String code, AuthMode authMode) {
|
||||
this.uuid = uuid;
|
||||
this.username = username;
|
||||
this.code = code;
|
||||
this.authMode = authMode;
|
||||
}
|
||||
|
||||
public enum AuthMode {
|
||||
ONLINE,
|
||||
OFFLINE
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.octoturge.mcmapper.common.protocol;
|
||||
|
||||
/**
|
||||
* Structured payload pushed from the backend when a web visitor shares a marker to chat.
|
||||
* {@code x, y, z} are all populated by the backend (y auto-derived from its heightmap at
|
||||
* placement time) — the mod's only job is to render this as a clickable chat component in
|
||||
* whichever {@link Format} the server admin configured.
|
||||
*/
|
||||
public class WaypointShare {
|
||||
public final String name;
|
||||
public final int x;
|
||||
public final int y;
|
||||
public final int z;
|
||||
public final String dimension;
|
||||
public final String color;
|
||||
public final Format format;
|
||||
|
||||
public WaypointShare(String name, int x, int y, int z, String dimension, String color, Format format) {
|
||||
this.name = name;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.dimension = dimension;
|
||||
this.color = color;
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public enum Format {
|
||||
JOURNEYMAP,
|
||||
XAERO
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user