Decouple the control sign from the gate frame: place then punch to link
Sign creation no longer scans the block it's mounted on. Instead, placing a "[Stargate]" sign starts a pending link (shown as "Punch the gate" on the sign) and the next block the owner left-clicks within gate.link-timeout-seconds and gate.max-link-distance becomes the scan seed. This lets the sign act like a DHD console standing apart from the gate instead of being physically attached to the frame. - Gate now stores the punched link block's coordinates (link_x/y/z) so restarts re-scan from there instead of deriving a seed from the sign's attachment, which no longer applies. - New GateLinkListener handles the punch and reports scan failures via the existing diagnostic messages; also clears pending state on disconnect. - Exit-location facing is now derived from the punched frame block's position relative to the iris, since a WallSign facing is no longer guaranteed to exist or be relevant.
This commit is contained in:
@@ -33,11 +33,18 @@ public class Gate {
|
||||
private UUID owner;
|
||||
private final Set<Flag> flags;
|
||||
private String fixedDestination;
|
||||
// The frame block the owner punched to link this gate's sign to its structure - the sign
|
||||
// itself can sit anywhere (a DHD-style console away from the gate); this is what we re-scan
|
||||
// from on server restart.
|
||||
private int linkX;
|
||||
private int linkY;
|
||||
private int linkZ;
|
||||
|
||||
public Gate(UUID id, String name, String network, String serverId, String world,
|
||||
int exitX, int exitY, int exitZ, float exitYaw,
|
||||
int signX, int signY, int signZ, String signWorld, String facing,
|
||||
UUID owner, Set<Flag> flags, String fixedDestination) {
|
||||
UUID owner, Set<Flag> flags, String fixedDestination,
|
||||
int linkX, int linkY, int linkZ) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
this.network = network;
|
||||
@@ -55,6 +62,9 @@ public class Gate {
|
||||
this.owner = owner;
|
||||
this.flags = flags == null ? EnumSet.noneOf(Flag.class) : flags;
|
||||
this.fixedDestination = fixedDestination;
|
||||
this.linkX = linkX;
|
||||
this.linkY = linkY;
|
||||
this.linkZ = linkZ;
|
||||
}
|
||||
|
||||
public UUID getId() { return id; }
|
||||
@@ -84,6 +94,9 @@ public class Gate {
|
||||
public boolean isFixed() { return flags.contains(Flag.FIXED); }
|
||||
public String getFixedDestination() { return fixedDestination; }
|
||||
public void setFixedDestination(String fixedDestination) { this.fixedDestination = fixedDestination; }
|
||||
public int getLinkX() { return linkX; }
|
||||
public int getLinkY() { return linkY; }
|
||||
public int getLinkZ() { return linkZ; }
|
||||
|
||||
/** Fully-qualified identity used for cross-server lookups: server/network/name */
|
||||
public String qualifiedName() {
|
||||
|
||||
+27
-7
@@ -75,13 +75,28 @@ public class SqlGateStorage implements GateStorage {
|
||||
"facing VARCHAR(16)," +
|
||||
"owner VARCHAR(36)," +
|
||||
"flags VARCHAR(128)," +
|
||||
"fixed_destination VARCHAR(64)" +
|
||||
"fixed_destination VARCHAR(64)," +
|
||||
"link_x INTEGER NOT NULL DEFAULT 0," +
|
||||
"link_y INTEGER NOT NULL DEFAULT 0," +
|
||||
"link_z INTEGER NOT NULL DEFAULT 0" +
|
||||
")");
|
||||
s.executeUpdate("CREATE INDEX IF NOT EXISTS idx_" + tablePrefix + "network ON " + tablePrefix + "gates(network)");
|
||||
migrateColumn(s, "link_x");
|
||||
migrateColumn(s, "link_y");
|
||||
migrateColumn(s, "link_z");
|
||||
}
|
||||
logger.info("[Stargate] Storage initialised (" + driver + ")");
|
||||
}
|
||||
|
||||
/** Best-effort ALTER TABLE for databases created before link_x/y/z existed; ignored if the column is already there. */
|
||||
private void migrateColumn(Statement s, String column) {
|
||||
try {
|
||||
s.executeUpdate("ALTER TABLE " + tablePrefix + "gates ADD COLUMN " + column + " INTEGER NOT NULL DEFAULT 0");
|
||||
} catch (Exception ignored) {
|
||||
// column already exists
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (dataSource != null) dataSource.close();
|
||||
@@ -90,16 +105,17 @@ public class SqlGateStorage implements GateStorage {
|
||||
@Override
|
||||
public void saveGate(Gate gate) {
|
||||
String sql = "REPLACE INTO " + tablePrefix + "gates " +
|
||||
"(id,name,network,server_id,world,exit_x,exit_y,exit_z,exit_yaw,sign_x,sign_y,sign_z,sign_world,facing,owner,flags,fixed_destination) " +
|
||||
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||
"(id,name,network,server_id,world,exit_x,exit_y,exit_z,exit_yaw,sign_x,sign_y,sign_z,sign_world,facing,owner,flags,fixed_destination,link_x,link_y,link_z) " +
|
||||
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
|
||||
if (driver == Driver.MYSQL) {
|
||||
sql = "INSERT INTO " + tablePrefix + "gates " +
|
||||
"(id,name,network,server_id,world,exit_x,exit_y,exit_z,exit_yaw,sign_x,sign_y,sign_z,sign_world,facing,owner,flags,fixed_destination) " +
|
||||
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE " +
|
||||
"(id,name,network,server_id,world,exit_x,exit_y,exit_z,exit_yaw,sign_x,sign_y,sign_z,sign_world,facing,owner,flags,fixed_destination,link_x,link_y,link_z) " +
|
||||
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE " +
|
||||
"name=VALUES(name),network=VALUES(network),server_id=VALUES(server_id),world=VALUES(world)," +
|
||||
"exit_x=VALUES(exit_x),exit_y=VALUES(exit_y),exit_z=VALUES(exit_z),exit_yaw=VALUES(exit_yaw)," +
|
||||
"sign_x=VALUES(sign_x),sign_y=VALUES(sign_y),sign_z=VALUES(sign_z),sign_world=VALUES(sign_world)," +
|
||||
"facing=VALUES(facing),owner=VALUES(owner),flags=VALUES(flags),fixed_destination=VALUES(fixed_destination)";
|
||||
"facing=VALUES(facing),owner=VALUES(owner),flags=VALUES(flags),fixed_destination=VALUES(fixed_destination)," +
|
||||
"link_x=VALUES(link_x),link_y=VALUES(link_y),link_z=VALUES(link_z)";
|
||||
}
|
||||
try (Connection c = dataSource.getConnection(); PreparedStatement ps = c.prepareStatement(sql)) {
|
||||
ps.setString(1, gate.getId().toString());
|
||||
@@ -119,6 +135,9 @@ public class SqlGateStorage implements GateStorage {
|
||||
ps.setString(15, gate.getOwner() == null ? null : gate.getOwner().toString());
|
||||
ps.setString(16, serializeFlags(gate.getFlags()));
|
||||
ps.setString(17, gate.getFixedDestination());
|
||||
ps.setInt(18, gate.getLinkX());
|
||||
ps.setInt(19, gate.getLinkY());
|
||||
ps.setInt(20, gate.getLinkZ());
|
||||
ps.executeUpdate();
|
||||
} catch (Exception e) {
|
||||
logger.severe("[Stargate] Failed to save gate " + gate.getName() + ": " + e.getMessage());
|
||||
@@ -182,7 +201,8 @@ public class SqlGateStorage implements GateStorage {
|
||||
rs.getString("facing"),
|
||||
ownerStr == null ? null : UUID.fromString(ownerStr),
|
||||
deserializeFlags(rs.getString("flags")),
|
||||
fixedDest
|
||||
fixedDest,
|
||||
rs.getInt("link_x"), rs.getInt("link_y"), rs.getInt("link_z")
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user