Switch from runCommand("transfer ...") to the @minecraft/server-admin
transferPlayer() function for reliable server-to-server transfers.
Enable Beta APIs experiment (gametest flag) in all 4 world level.dat files.
Add spawn protection to prevent transfer loops on arrival.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
67 lines
2.3 KiB
JavaScript
67 lines
2.3 KiB
JavaScript
import { world, system } from "@minecraft/server";
|
|
import { transferPlayer } from "@minecraft/server-admin";
|
|
|
|
// Portal definitions: name, center position, and direct transfer target
|
|
const portals = [
|
|
{ name: "Jamie's World", x: -15, y: 65, z: -24, host: "10.0.0.247", port: 19133 },
|
|
{ name: "Lyla's World", x: 0, y: 65, z: -24, host: "10.0.0.247", port: 19134 },
|
|
{ name: "Mya's World", x: 15, y: 65, z: -24, host: "10.0.0.247", port: 19135 },
|
|
];
|
|
|
|
const PORTAL_RADIUS_X = 2.5;
|
|
const PORTAL_RADIUS_Z = 2.0;
|
|
const PORTAL_RADIUS_Y = 2.0;
|
|
const COOLDOWN_TICKS = 100; // 5 seconds cooldown
|
|
const SPAWN_PROTECTION_TICKS = 200; // 10 seconds — ignore portal detection after spawn
|
|
|
|
// Track cooldowns per player
|
|
const cooldowns = new Map();
|
|
// Track when players spawned (to prevent transfer loop on arrival)
|
|
const spawnTicks = new Map();
|
|
|
|
world.afterEvents.playerSpawn.subscribe((event) => {
|
|
spawnTicks.set(event.player.id, system.currentTick);
|
|
});
|
|
|
|
system.runInterval(() => {
|
|
for (const player of world.getAllPlayers()) {
|
|
const pos = player.location;
|
|
const playerId = player.id;
|
|
|
|
// Check cooldown
|
|
const lastTransfer = cooldowns.get(playerId) || 0;
|
|
if (system.currentTick - lastTransfer < COOLDOWN_TICKS) continue;
|
|
|
|
// Skip if player just spawned (prevents loop when arriving from child world)
|
|
const spawnedAt = spawnTicks.get(playerId) || 0;
|
|
if (system.currentTick - spawnedAt < SPAWN_PROTECTION_TICKS) continue;
|
|
|
|
for (const portal of portals) {
|
|
const dx = Math.abs(pos.x - portal.x);
|
|
const dy = Math.abs(pos.y - portal.y);
|
|
const dz = Math.abs(pos.z - portal.z);
|
|
|
|
if (dx < PORTAL_RADIUS_X && dy < PORTAL_RADIUS_Y && dz < PORTAL_RADIUS_Z) {
|
|
cooldowns.set(playerId, system.currentTick);
|
|
player.sendMessage(`§6Transferring to ${portal.name}...`);
|
|
try {
|
|
transferPlayer(player, { hostname: portal.host, port: portal.port });
|
|
} catch (e) {
|
|
player.sendMessage(`§cTransfer failed: ${e.message}`);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}, 10); // Check every half second
|
|
|
|
// Clean up tracking when players leave
|
|
world.afterEvents.playerLeave.subscribe((event) => {
|
|
cooldowns.delete(event.playerId);
|
|
spawnTicks.delete(event.playerId);
|
|
});
|
|
|
|
system.run(() => {
|
|
world.sendMessage("§6[Hub] §7Portal transfer system loaded!");
|
|
});
|