this repo has no description
at main 3.1 kB view raw
1import mc from "minecraft-protocol"; 2 3type Player = { 4 uuid: string; 5 name: string; 6 properties?: Record<string, unknown>; 7 listed?: boolean; 8 latency?: number; 9 gameMode?: number; 10}; 11 12const TARGET_HOST = "localhost"; 13const TARGET_PORT = 25566; 14const MINECRAFT_VERSION = "1.20.4"; 15 16const roster = new Map<string, Player>(); 17 18const client = mc.createClient({ 19 host: TARGET_HOST, 20 port: TARGET_PORT, 21 username: "hepticWarbler", 22 version: MINECRAFT_VERSION, 23 keepAlive: true, 24 auth: "offline", 25}); 26 27client.on("login", () => { 28 console.log("✅ Joined server, tracking player list…"); 29}); 30 31client.on("packet", (data, meta) => { 32 if (meta.state !== "play") return; 33 34 switch (meta.name) { 35 case "player_info": { 36 const action = data.action; 37 for (const item of data.data) { 38 const uuid = item.UUID ?? item.uuid; 39 const name = item.name ?? item.username ?? ""; 40 const entry = roster.get(uuid) ?? { uuid, name }; 41 42 if (action === 0) { 43 roster.set(uuid, { ...entry, name }); 44 console.log(`➕ join: ${name} (${uuid})`); 45 } else if (action === 1) { 46 roster.set(uuid, { ...entry, gameMode: item.gamemode }); 47 } else if (action === 2) { 48 roster.set(uuid, { ...entry, latency: item.ping }); 49 } else if (action === 4) { 50 roster.delete(uuid); 51 console.log(`➖ leave: ${name} (${uuid})`); 52 } 53 } 54 break; 55 } 56 case "player_info_update": { 57 const actions: string[] = data.actions; 58 for (const v of data.values) { 59 const uuid: string = v.uuid; 60 const prev = roster.get(uuid); 61 let name = prev?.name ?? v.name ?? v.profile?.name ?? ""; 62 let listed = prev?.listed; 63 64 if (actions.includes("add_player")) { 65 name = v.name ?? name; 66 listed = true; 67 roster.set(uuid, { 68 uuid, 69 name, 70 listed, 71 properties: v.properties, 72 latency: v.latency, 73 gameMode: v.gamemode, 74 }); 75 console.log(`➕ join: ${name} (${uuid})`); 76 } 77 if (actions.includes("update_latency")) { 78 roster.set(uuid, { ...(prev ?? { uuid, name }), latency: v.latency }); 79 } 80 if (actions.includes("update_gamemode")) { 81 roster.set(uuid, { 82 ...(prev ?? { uuid, name }), 83 gameMode: v.gamemode, 84 }); 85 } 86 if (actions.includes("remove_player")) { 87 roster.delete(uuid); 88 console.log(`➖ leave: ${name} (${uuid})`); 89 } 90 } 91 break; 92 } 93 } 94}); 95 96setInterval(() => { 97 const players = Array.from(roster.values()); 98 console.log("\n📋 Current players:", players.length); 99 players.forEach((p) => { 100 console.log( 101 ` - ${p.name} (${p.uuid}) | ping: ${p.latency}ms | mode: ${p.gameMode}`, 102 ); 103 }); 104 console.log(""); 105}, 10000); 106 107client.on("error", (err) => { 108 console.error("❌ client error:", err); 109}); 110 111client.on("end", (reason) => { 112 console.log("🔌 Disconnected:", reason); 113});