fix(transfer): use transferPlayer() beta API and enable experiments in level.dat
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>
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
"name": "Hub Return Transfer",
|
||||
"description": "Transfers players back to lobby when they step on the return portal",
|
||||
"uuid": "b2c3d4e5-1111-2222-3333-fedcba654321",
|
||||
"version": [1, 0, 1],
|
||||
"version": [1, 0, 3],
|
||||
"min_engine_version": [1, 21, 0]
|
||||
},
|
||||
"modules": [
|
||||
@@ -12,14 +12,18 @@
|
||||
"type": "script",
|
||||
"language": "javascript",
|
||||
"uuid": "b2c3d4e5-4444-5555-6666-fedcba987654",
|
||||
"version": [1, 0, 1],
|
||||
"version": [1, 0, 3],
|
||||
"entry": "scripts/main.js"
|
||||
}
|
||||
],
|
||||
"dependencies": [
|
||||
{
|
||||
"module_name": "@minecraft/server",
|
||||
"version": "2.0.0"
|
||||
"version": "1.17.0"
|
||||
},
|
||||
{
|
||||
"module_name": "@minecraft/server-admin",
|
||||
"version": "1.0.0-beta"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { world, system, ItemStack } from "@minecraft/server";
|
||||
import { transferPlayer } from "@minecraft/server-admin";
|
||||
|
||||
const LOBBY_HOST = "10.0.0.247";
|
||||
const LOBBY_PORT = 19132;
|
||||
@@ -6,9 +7,12 @@ const COMPASS_ID = "minecraft:recovery_compass";
|
||||
const PORTAL_PROP = "hub_portal_location";
|
||||
const PORTAL_RADIUS = 3;
|
||||
const TRANSFER_COOLDOWN = 5000; // 5 seconds
|
||||
const SPAWN_PROTECTION = 10000; // 10 seconds — ignore portal detection after spawn
|
||||
|
||||
// Track recently transferred players
|
||||
const recentTransfers = new Map();
|
||||
// Track when players spawned (to prevent transfer loop on arrival)
|
||||
const spawnTimes = new Map();
|
||||
|
||||
function doTransfer(player) {
|
||||
const now = Date.now();
|
||||
@@ -21,7 +25,7 @@ function doTransfer(player) {
|
||||
world.sendMessage(`§a${player.name} is returning to the Hub...`);
|
||||
|
||||
try {
|
||||
player.runCommand(`transfer ${player.name} ${LOBBY_HOST} ${LOBBY_PORT}`);
|
||||
transferPlayer(player, { hostname: LOBBY_HOST, port: LOBBY_PORT });
|
||||
} catch (e) {
|
||||
player.sendMessage(`§cTransfer failed: ${e.message}`);
|
||||
}
|
||||
@@ -45,6 +49,8 @@ function giveCompassIfMissing(player) {
|
||||
|
||||
world.afterEvents.playerSpawn.subscribe((event) => {
|
||||
const player = event.player;
|
||||
// Mark spawn time for portal protection (prevents transfer loop on arrival)
|
||||
spawnTimes.set(player.name, Date.now());
|
||||
// Small delay to let inventory load
|
||||
system.runTimeout(() => {
|
||||
try {
|
||||
@@ -82,9 +88,14 @@ system.runInterval(() => {
|
||||
const players = world.getAllPlayers();
|
||||
|
||||
for (const player of players) {
|
||||
// Skip if recently transferred (cooldown)
|
||||
if (recentTransfers.has(player.name) && now - recentTransfers.get(player.name) < TRANSFER_COOLDOWN) {
|
||||
continue;
|
||||
}
|
||||
// Skip if player just spawned (prevents loop when arriving from lobby)
|
||||
if (spawnTimes.has(player.name) && now - spawnTimes.get(player.name) < SPAWN_PROTECTION) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const pos = player.location;
|
||||
const dx = Math.abs(pos.x - portal.x);
|
||||
@@ -131,7 +142,7 @@ function handleChatCommand(player, msg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Try beforeEvents.chatSend (pre-release in some BDS versions)
|
||||
// Listen for chat commands — try beforeEvents first (beta API), fall back gracefully
|
||||
try {
|
||||
world.beforeEvents.chatSend.subscribe((event) => {
|
||||
const msg = event.message.trim().toLowerCase();
|
||||
@@ -141,11 +152,13 @@ try {
|
||||
system.run(() => handleChatCommand(player, msg));
|
||||
}
|
||||
});
|
||||
} catch {
|
||||
// chatSend not available — fall back to polling player chat via scriptEvent
|
||||
} catch (e) {
|
||||
// beforeEvents.chatSend requires beta API — chat commands won't work via chat,
|
||||
// but compass and portal transfers still function
|
||||
world.sendMessage("§e[Hub] §fChat commands (!hub, !lobby) unavailable — use compass or portal instead.");
|
||||
}
|
||||
|
||||
// Fallback: listen for scriptevent commands (players run: /scriptevent hub:cmd <command>)
|
||||
// scriptEvent fallback — players can use: /scriptevent hub:cmd hub
|
||||
system.afterEvents.scriptEventReceive.subscribe((event) => {
|
||||
if (event.id !== "hub:cmd") return;
|
||||
const player = event.sourceEntity;
|
||||
|
||||
Reference in New Issue
Block a user