tangled
alpha
login
or
join now
dunkirk.sh
/
paper-crown
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
feat: add the thing
dunkirk.sh
3 months ago
427867f5
7161b61e
verified
This commit was signed with the committer's
known signature
.
dunkirk.sh
SSH Key Fingerprint:
SHA256:DqcG0RXYExE26KiWo3VxJnsxswN1QNfTBvB+bdSpk80=
+215
-76
3 changed files
expand all
collapse all
unified
split
proxy
index.ts
roster-client.ts
server
docker-compose.yml
+100
-74
proxy/index.ts
···
1
1
-
import mc from 'minecraft-protocol';
1
1
+
import mc from "minecraft-protocol";
2
2
3
3
const PROXY_PORT = 25565;
4
4
-
const TARGET_HOST = 'localhost';
5
5
-
const TARGET_PORT = 25566;
4
4
+
const TARGET_HOST = "one.strongcraft.org";
5
5
+
const TARGET_PORT = 25565;
6
6
+
const MINECRAFT_VERSION = "1.20.4";
6
7
7
7
-
const SPOOFED_USERNAME = 'admin';
8
8
-
const SPOOFED_UUID = '36881d51-7477-3eb6-91a1-dfc11065590d';
8
8
+
const SPOOFED_USERNAME = "BobTheBomber917";
9
9
+
const SPOOFED_UUID = "4b5db0b0-3165-3ef2-956f-2ee9f25479aa";
9
10
10
11
const server = mc.createServer({
11
11
-
'online-mode': false,
12
12
-
port: PROXY_PORT,
13
13
-
keepAlive: false,
14
14
-
version: '1.20.4'
12
12
+
"online-mode": false,
13
13
+
port: PROXY_PORT,
14
14
+
keepAlive: false,
15
15
+
version: MINECRAFT_VERSION,
15
16
});
16
17
17
18
console.log(`Minecraft proxy listening on port ${PROXY_PORT}`);
18
19
console.log(`Forwarding to ${TARGET_HOST}:${TARGET_PORT}`);
19
20
20
20
-
server.on('login', (client) => {
21
21
-
console.log('\n=== NEW CLIENT CONNECTION ===');
22
22
-
console.log(`Original Player: ${client.username}`);
23
23
-
console.log(`Original UUID: ${client.uuid}`);
24
24
-
console.log(`IP: ${client.socket.remoteAddress}`);
25
25
-
console.log(`Spoofing as: ${SPOOFED_USERNAME} (${SPOOFED_UUID})`);
26
26
-
27
27
-
const target = mc.createClient({
28
28
-
host: TARGET_HOST,
29
29
-
port: TARGET_PORT,
30
30
-
username: SPOOFED_USERNAME,
31
31
-
keepAlive: false,
32
32
-
version: '1.20.4',
33
33
-
auth: 'offline'
34
34
-
});
21
21
+
mc.ping({
22
22
+
host: TARGET_HOST,
23
23
+
port: TARGET_PORT,
24
24
+
version: MINECRAFT_VERSION,
25
25
+
})
26
26
+
.then((res) => {
27
27
+
return res as mc.NewPingResult;
28
28
+
})
29
29
+
.then((res) => {
30
30
+
console.log("description:", res.description);
31
31
+
console.log("players:", res.players);
32
32
+
console.log("version:", res.version);
33
33
+
console.log("latency:", res.latency);
34
34
+
})
35
35
+
.catch((err) => {
36
36
+
console.error("Ping failed:", err);
37
37
+
});
35
38
36
36
-
target.on('connect', () => {
37
37
-
console.log(`Connected to target server for ${client.username}`);
38
38
-
});
39
39
+
server.on("login", (client) => {
40
40
+
console.log("\n=== NEW CLIENT CONNECTION ===");
41
41
+
console.log(`Original Player: ${client.username}`);
42
42
+
console.log(`Original UUID: ${client.uuid}`);
43
43
+
console.log(`IP: ${client.socket.remoteAddress}`);
44
44
+
console.log(`Spoofing as: ${SPOOFED_USERNAME} (${SPOOFED_UUID})`);
39
45
40
40
-
target.on('error', (err) => {
41
41
-
console.error(`Target error for ${client.username}:`, err.message);
42
42
-
client.end('Connection to server failed');
43
43
-
});
46
46
+
console.log("\n=== CONNECTED USERS ===");
47
47
+
console.log("=======================\n");
44
48
45
45
-
client.on('packet', (data, meta) => {
46
46
-
if (meta.name.includes('auth') ||
47
47
-
meta.name.includes('login') ||
48
48
-
meta.name.includes('encryption') ||
49
49
-
meta.name.includes('session')) {
50
50
-
console.log('\n--- AUTH PACKET (Client -> Server) ---');
51
51
-
console.log(`Packet: ${meta.name}`);
52
52
-
console.log(`State: ${meta.state}`);
53
53
-
console.log('Data:', JSON.stringify(data, null, 2));
54
54
-
console.log('--------------------------------------');
55
55
-
}
49
49
+
const target = mc.createClient({
50
50
+
host: TARGET_HOST,
51
51
+
port: TARGET_PORT,
52
52
+
username: SPOOFED_USERNAME,
53
53
+
keepAlive: false,
54
54
+
version: MINECRAFT_VERSION,
55
55
+
auth: "offline",
56
56
+
});
56
57
57
57
-
if (target.state === mc.states.PLAY && meta.state === mc.states.PLAY) {
58
58
-
target.write(meta.name, data);
59
59
-
}
60
60
-
});
58
58
+
target.on("connect", () => {
59
59
+
console.log(`Connected to target server for ${client.username}`);
60
60
+
});
61
61
+
62
62
+
target.on("error", (err) => {
63
63
+
console.error(`Target error for ${client.username}:`, err.message);
64
64
+
client.end("Connection to server failed");
65
65
+
});
61
66
62
62
-
target.on('packet', (data, meta) => {
63
63
-
if (meta.name.includes('auth') ||
64
64
-
meta.name.includes('login') ||
65
65
-
meta.name.includes('encryption') ||
66
66
-
meta.name.includes('session') ||
67
67
-
meta.name.includes('compress')) {
68
68
-
console.log('\n--- AUTH PACKET (Server -> Client) ---');
69
69
-
console.log(`Packet: ${meta.name}`);
70
70
-
console.log(`State: ${meta.state}`);
71
71
-
console.log('Data:', JSON.stringify(data, null, 2));
72
72
-
console.log('--------------------------------------');
73
73
-
}
67
67
+
client.on("packet", (data, meta) => {
68
68
+
if (
69
69
+
meta.name.includes("auth") ||
70
70
+
meta.name.includes("login") ||
71
71
+
meta.name.includes("encryption") ||
72
72
+
meta.name.includes("session")
73
73
+
) {
74
74
+
console.log("\n--- AUTH PACKET (Client -> Server) ---");
75
75
+
console.log(`Packet: ${meta.name}`);
76
76
+
console.log(`State: ${meta.state}`);
77
77
+
console.log("Data:", JSON.stringify(data, null, 2));
78
78
+
console.log("--------------------------------------");
79
79
+
}
80
80
+
81
81
+
if (target.state === mc.states.PLAY && meta.state === mc.states.PLAY) {
82
82
+
target.write(meta.name, data);
83
83
+
}
84
84
+
});
85
85
+
86
86
+
target.on("packet", (data, meta) => {
87
87
+
if (
88
88
+
meta.name.includes("auth") ||
89
89
+
meta.name.includes("login") ||
90
90
+
meta.name.includes("encryption") ||
91
91
+
meta.name.includes("session") ||
92
92
+
meta.name.includes("compress")
93
93
+
) {
94
94
+
console.log("\n--- AUTH PACKET (Server -> Client) ---");
95
95
+
console.log(`Packet: ${meta.name}`);
96
96
+
console.log(`State: ${meta.state}`);
97
97
+
console.log("Data:", JSON.stringify(data, null, 2));
98
98
+
console.log("--------------------------------------");
99
99
+
}
74
100
75
75
-
if (client.state === mc.states.PLAY && meta.state === mc.states.PLAY) {
76
76
-
client.write(meta.name, data);
77
77
-
}
78
78
-
});
101
101
+
if (client.state === mc.states.PLAY && meta.state === mc.states.PLAY) {
102
102
+
client.write(meta.name, data);
103
103
+
}
104
104
+
});
79
105
80
80
-
client.on('end', () => {
81
81
-
console.log(`Client ${client.username} disconnected`);
82
82
-
target.end();
83
83
-
});
106
106
+
client.on("end", () => {
107
107
+
console.log(`Client ${client.username} disconnected`);
108
108
+
target.end();
109
109
+
});
84
110
85
85
-
target.on('end', () => {
86
86
-
console.log(`Target server disconnected for ${client.username}`);
87
87
-
client.end('Server connection closed');
88
88
-
});
111
111
+
target.on("end", () => {
112
112
+
console.log(`Target server disconnected for ${client.username}`);
113
113
+
client.end("Server connection closed");
114
114
+
});
89
115
});
90
116
91
91
-
server.on('error', (err) => {
92
92
-
console.error('Server error:', err);
117
117
+
server.on("error", (err) => {
118
118
+
console.error("Server error:", err);
93
119
});
94
120
95
95
-
server.on('listening', () => {
96
96
-
console.log('Server ready for connections');
121
121
+
server.on("listening", () => {
122
122
+
console.log("Server ready for connections");
97
123
});
+113
proxy/roster-client.ts
···
1
1
+
import mc from "minecraft-protocol";
2
2
+
3
3
+
type Player = {
4
4
+
uuid: string;
5
5
+
name: string;
6
6
+
properties?: Record<string, unknown>;
7
7
+
listed?: boolean;
8
8
+
latency?: number;
9
9
+
gameMode?: number;
10
10
+
};
11
11
+
12
12
+
const TARGET_HOST = "localhost";
13
13
+
const TARGET_PORT = 25566;
14
14
+
const MINECRAFT_VERSION = "1.20.4";
15
15
+
16
16
+
const roster = new Map<string, Player>();
17
17
+
18
18
+
const client = mc.createClient({
19
19
+
host: TARGET_HOST,
20
20
+
port: TARGET_PORT,
21
21
+
username: "hepticWarbler",
22
22
+
version: MINECRAFT_VERSION,
23
23
+
keepAlive: true,
24
24
+
auth: "offline",
25
25
+
});
26
26
+
27
27
+
client.on("login", () => {
28
28
+
console.log("✅ Joined server, tracking player list…");
29
29
+
});
30
30
+
31
31
+
client.on("packet", (data, meta) => {
32
32
+
if (meta.state !== "play") return;
33
33
+
34
34
+
switch (meta.name) {
35
35
+
case "player_info": {
36
36
+
const action = data.action;
37
37
+
for (const item of data.data) {
38
38
+
const uuid = item.UUID ?? item.uuid;
39
39
+
const name = item.name ?? item.username ?? "";
40
40
+
const entry = roster.get(uuid) ?? { uuid, name };
41
41
+
42
42
+
if (action === 0) {
43
43
+
roster.set(uuid, { ...entry, name });
44
44
+
console.log(`➕ join: ${name} (${uuid})`);
45
45
+
} else if (action === 1) {
46
46
+
roster.set(uuid, { ...entry, gameMode: item.gamemode });
47
47
+
} else if (action === 2) {
48
48
+
roster.set(uuid, { ...entry, latency: item.ping });
49
49
+
} else if (action === 4) {
50
50
+
roster.delete(uuid);
51
51
+
console.log(`➖ leave: ${name} (${uuid})`);
52
52
+
}
53
53
+
}
54
54
+
break;
55
55
+
}
56
56
+
case "player_info_update": {
57
57
+
const actions: string[] = data.actions;
58
58
+
for (const v of data.values) {
59
59
+
const uuid: string = v.uuid;
60
60
+
const prev = roster.get(uuid);
61
61
+
let name = prev?.name ?? v.name ?? v.profile?.name ?? "";
62
62
+
let listed = prev?.listed;
63
63
+
64
64
+
if (actions.includes("add_player")) {
65
65
+
name = v.name ?? name;
66
66
+
listed = true;
67
67
+
roster.set(uuid, {
68
68
+
uuid,
69
69
+
name,
70
70
+
listed,
71
71
+
properties: v.properties,
72
72
+
latency: v.latency,
73
73
+
gameMode: v.gamemode,
74
74
+
});
75
75
+
console.log(`➕ join: ${name} (${uuid})`);
76
76
+
}
77
77
+
if (actions.includes("update_latency")) {
78
78
+
roster.set(uuid, { ...(prev ?? { uuid, name }), latency: v.latency });
79
79
+
}
80
80
+
if (actions.includes("update_gamemode")) {
81
81
+
roster.set(uuid, {
82
82
+
...(prev ?? { uuid, name }),
83
83
+
gameMode: v.gamemode,
84
84
+
});
85
85
+
}
86
86
+
if (actions.includes("remove_player")) {
87
87
+
roster.delete(uuid);
88
88
+
console.log(`➖ leave: ${name} (${uuid})`);
89
89
+
}
90
90
+
}
91
91
+
break;
92
92
+
}
93
93
+
}
94
94
+
});
95
95
+
96
96
+
setInterval(() => {
97
97
+
const players = Array.from(roster.values());
98
98
+
console.log("\n📋 Current players:", players.length);
99
99
+
players.forEach((p) => {
100
100
+
console.log(
101
101
+
` - ${p.name} (${p.uuid}) | ping: ${p.latency}ms | mode: ${p.gameMode}`,
102
102
+
);
103
103
+
});
104
104
+
console.log("");
105
105
+
}, 10000);
106
106
+
107
107
+
client.on("error", (err) => {
108
108
+
console.error("❌ client error:", err);
109
109
+
});
110
110
+
111
111
+
client.on("end", (reason) => {
112
112
+
console.log("🔌 Disconnected:", reason);
113
113
+
});
+2
-2
server/docker-compose.yml
···
1
1
-
version: '3.8'
1
1
+
version: "3.8"
2
2
3
3
services:
4
4
minecraft:
···
12
12
VERSION: "1.20.4"
13
13
ONLINE_MODE: "FALSE"
14
14
ALLOW_FLIGHT: "TRUE"
15
15
-
MOTD: "Offline Minecraft Server"
15
15
+
MOTD: "where we do haxcy things"
16
16
DIFFICULTY: "easy"
17
17
MAX_PLAYERS: 20
18
18
VIEW_DISTANCE: 10