testdeep123 commited on
Commit
41abff7
·
verified ·
1 Parent(s): 9ae000e

Upload 4 files

Browse files
Files changed (4) hide show
  1. Dockerfile +10 -0
  2. index.html +302 -0
  3. index.js +167 -0
  4. package.json +15 -0
Dockerfile ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:18-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY package.json ./
6
+ RUN npm install
7
+
8
+ COPY . .
9
+
10
+ CMD ["node", "index.js"]
index.html ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AFK Bot Control Panel</title>
7
+ <link rel="preconnect" href="https://fonts.googleapis.com">
8
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap" rel="stylesheet">
10
+ <style>
11
+ :root {
12
+ --bg-darkest: #121212;
13
+ --bg-dark: #1e1e1e;
14
+ --bg-card: #2a2a2a;
15
+ --text-primary: #e0e0e0;
16
+ --text-secondary: #b3b3b3;
17
+ --accent-primary: #00aaff;
18
+ --accent-secondary: #0077b3;
19
+ --accent-danger: #ff4d4d;
20
+ --border-color: #444;
21
+ --font-family: 'Inter', sans-serif;
22
+ --border-radius: 8px;
23
+ --shadow: 0 4px 6px rgba(0,0,0,0.1);
24
+ }
25
+ body {
26
+ margin: 0;
27
+ font-family: var(--font-family);
28
+ background: var(--bg-darkest);
29
+ color: var(--text-primary);
30
+ }
31
+ .container {
32
+ max-width: 900px;
33
+ margin: 0 auto;
34
+ padding: 16px;
35
+ }
36
+ header {
37
+ background: var(--bg-dark);
38
+ padding: 24px 16px;
39
+ text-align: center;
40
+ border-bottom: 1px solid var(--border-color);
41
+ margin-bottom: 24px;
42
+ }
43
+ h1 { font-size: 1.75rem; font-weight: 700; margin: 0; }
44
+ #status { font-size: 0.9rem; margin-top: 8px; color: var(--text-secondary); }
45
+ #status.connected { color: #4caf50; }
46
+ #status.disconnected { color: var(--accent-danger); }
47
+ h2 {
48
+ font-size: 1.25rem;
49
+ font-weight: 500;
50
+ color: var(--text-primary);
51
+ border-bottom: 1px solid var(--border-color);
52
+ padding-bottom: 8px;
53
+ margin-top: 0;
54
+ margin-bottom: 17px;
55
+ }
56
+ section {
57
+ background: var(--bg-card);
58
+ border-radius: var(--border-radius);
59
+ padding: 20px;
60
+ margin-bottom: 24px;
61
+ box-shadow: var(--shadow);
62
+ }
63
+ .btn-grid {
64
+ display: grid;
65
+ grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
66
+ gap: 12px;
67
+ }
68
+ button {
69
+ padding: 12px;
70
+ background: var(--bg-dark);
71
+ border: 1px solid var(--border-color);
72
+ border-radius: var(--border-radius);
73
+ color: var(--text-primary);
74
+ font-family: var(--font-family);
75
+ font-size: 0.95rem;
76
+ font-weight: 500;
77
+ cursor: pointer;
78
+ transition: all 0.2s ease-in-out;
79
+ text-align: center;
80
+ }
81
+ button:hover {
82
+ border-color: var(--accent-primary);
83
+ color: var(--accent-primary);
84
+ }
85
+ button.flash {
86
+ animation: flash-animation 0.4s ease;
87
+ }
88
+ @keyframes flash-animation {
89
+ 0% { background: var(--bg-dark); }
90
+ 50% { background: var(--accent-secondary); }
91
+ 100% { background: var(--bg-dark); }
92
+ }
93
+ .btn-danger { color: var(--accent-danger); border-color: var(--accent-danger); }
94
+ .btn-danger:hover { background: var(--accent-danger); color: #fff; }
95
+ .btn-success { color: #4caf50; border-color: #4caf50; }
96
+ .btn-success:hover { background: #4caf50; color: #fff; }
97
+ table { width: 100%; border-collapse: collapse; margin-top: 16px; }
98
+ th, td { border-bottom: 1px solid var(--border-color); padding: 12px; text-align: left; }
99
+ thead th {
100
+ color: var(--text-secondary);
101
+ font-size: 0.85rem;
102
+ text-transform: uppercase;
103
+ font-weight: 500;
104
+ }
105
+ tbody tr:hover { background: var(--bg-dark); }
106
+ td:last-child { text-align: center; }
107
+ td button { padding: 6px 12px; min-width: 70px; }
108
+ .input-group {
109
+ display: flex;
110
+ gap: 8px;
111
+ }
112
+ .input-group input {
113
+ flex: 1;
114
+ padding: 12px;
115
+ border-radius: 8px;
116
+ border: 1px solid var(--border-color);
117
+ background: var(--bg-dark);
118
+ color: var(--text-primary);
119
+ font-size: 0.95rem;
120
+ }
121
+ .input-group button {
122
+ padding: 12px 20px;
123
+ flex-shrink: 0; /* Prevent button from shrinking */
124
+ }
125
+
126
+ @media (max-width: 600px) {
127
+ .container { padding: 8px; }
128
+ header { padding: 16px 8px; margin-bottom: 16px; }
129
+ h1 { font-size: 1.5rem; }
130
+ section { padding: 16px; margin-bottom: 16px; }
131
+ .btn-grid { gap: 8px; grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)); }
132
+ th, td { padding: 8px; }
133
+ .input-group { flex-direction: column; }
134
+ .input-group input, .input-group button { width: 100%; }
135
+ }
136
+ </style>
137
+ </head>
138
+ <body>
139
+ <header>
140
+ <h1>AFK Bot Control</h1>
141
+ <div id="status">Connecting...</div>
142
+ </header>
143
+ <main class="container">
144
+ <section>
145
+ <h2>Send Chat Command</h2>
146
+ <div class="input-group">
147
+ <input type="text" id="chatInput" placeholder="/move galaxysmp">
148
+ <button id="sendChat">Send</button>
149
+ </div>
150
+ </section>
151
+
152
+ <!-- NEW MANUAL COMMAND SECTION -->
153
+ <section>
154
+ <h2>Manual Command</h2>
155
+ <div class="input-group">
156
+ <input type="text" id="cmdInput" placeholder="e.g., disconnect, get_inv, move:forward">
157
+ <button id="sendCmdBtn">Send</button>
158
+ </div>
159
+ </section>
160
+ <!-- END NEW MANUAL COMMAND SECTION -->
161
+
162
+ <section><h2>Movement</h2><div class="btn-grid">
163
+ <button data-command="move:forward" class="move-btn">W</button>
164
+ <button data-command="move:back" class="move-btn">S</button>
165
+ <button data-command="move:left" class="move-btn">A</button>
166
+ <button data-command="move:right" class="move-btn">D</button>
167
+ <button data-command="move:jump" class="move-btn">Jump</button>
168
+ <button data-command="stop">Stop All</button>
169
+ </div></section>
170
+ <section><h2>Actions</h2><div class="btn-grid">
171
+ <button data-command="click_left">Left Click</button>
172
+ <button data-command="click_right">Right Click</button>
173
+ </div></section>
174
+ <section><h2>Toggles</h2><div class="btn-grid">
175
+ <button data-command="toggle_afk">AFK Walk</button>
176
+ <button data-command="toggle_dirt">Dirt Loop</button>
177
+ <button data-command="toggle_follow">Follow DrTurjo</button>
178
+ </div></section>
179
+ <section><h2>Hotbar Slots</h2><div class="btn-grid">
180
+ <button data-command="slot:1">1</button>
181
+ <button data-command="slot:2">2</button>
182
+ <button data-command="slot:3">3</button>
183
+ <button data-command="slot:4">4</button>
184
+ <button data-command="slot:5">5</button>
185
+ <button data-command="slot:6">6</button>
186
+ <button data-command="slot:7">7</button>
187
+ <button data-command="slot:8">8</button>
188
+ <button data-command="slot:9">9</button>
189
+ </div></section>
190
+ <section><h2>Auto-Disconnect Timer</h2><div class="btn-grid">
191
+ <button data-command="timer:60">1 hr</button>
192
+ <button data-command="timer:120">2 hr</button>
193
+ <button data-command="timer:180">3 hr</button>
194
+ <button data-command="timer:240">4 hr</button>
195
+ <button data-command="timer:300">5 hr</button>
196
+ <button data-command="timer:360">6 hr</button>
197
+ <button data-command="timer:420">7 hr</button>
198
+ </div></section>
199
+ <section><h2>Connection</h2><div class="btn-grid">
200
+ <button data-command="reconnect" class="btn-success">Reconnect</button>
201
+ <button data-command="disconnect" class="btn-danger">Disconnect</button>
202
+ </div></section>
203
+ <section><h2>Inventory</h2>
204
+ <button data-command="get_inv">Refresh Inventory</button>
205
+ <table id="invTable"><thead><tr><th>Slot</th><th>Item</th><th>Count</th><th>Equip</th></tr></thead><tbody></tbody></table>
206
+ </section>
207
+ </main>
208
+ <script src="/socket.io/socket.io.js"></script>
209
+ <script>
210
+ const socket = io();
211
+ const statusEl = document.getElementById('status');
212
+ const invTableBody = document.querySelector('#invTable tbody');
213
+
214
+ function sendCommand(command) {
215
+ if (socket.connected) socket.emit('command', command);
216
+ }
217
+
218
+ document.querySelectorAll('button[data-command]').forEach(button => {
219
+ const command = button.dataset.command;
220
+ if (button.classList.contains('move-btn')) {
221
+ button.addEventListener('mousedown', () => sendCommand(command));
222
+ button.addEventListener('touchstart', e => { e.preventDefault(); sendCommand(command); });
223
+ button.addEventListener('mouseup', () => sendCommand('stop'));
224
+ button.addEventListener('mouseleave', () => sendCommand('stop'));
225
+ button.addEventListener('touchend', () => sendCommand('stop'));
226
+ } else {
227
+ button.addEventListener('click', () => {
228
+ sendCommand(command);
229
+ button.classList.add('flash');
230
+ setTimeout(() => button.classList.remove('flash'), 400);
231
+ });
232
+ }
233
+ });
234
+
235
+ invTableBody.addEventListener('click', e => {
236
+ if (e.target.tagName === 'BUTTON' && e.target.dataset.command) {
237
+ const btn = e.target;
238
+ sendCommand(btn.dataset.command);
239
+ btn.classList.add('flash');
240
+ setTimeout(() => btn.classList.remove('flash'), 400);
241
+ }
242
+ });
243
+
244
+ socket.on('connect', () => {
245
+ statusEl.textContent = 'Connected';
246
+ statusEl.className = 'connected';
247
+ sendCommand('get_inv');
248
+ });
249
+
250
+ socket.on('disconnect', () => {
251
+ statusEl.textContent = 'Disconnected';
252
+ statusEl.className = 'disconnected';
253
+ });
254
+
255
+ socket.on('inventory', inv => {
256
+ invTableBody.innerHTML = '';
257
+ if (!inv || inv.length === 0) {
258
+ invTableBody.innerHTML = `<tr><td colspan="4" style="text-align:center; color: var(--text-secondary);">Inventory is empty or not loaded.</td></tr>`;
259
+ return;
260
+ }
261
+ inv.forEach(item => {
262
+ const hotbarSlot = (item.slot >= 0 && item.slot <= 8) ? item.slot + 1 : null;
263
+ const equipButton = hotbarSlot ? `<button data-command="slot:${hotbarSlot}">Equip</button>` : 'N/A';
264
+ const tr = document.createElement('tr');
265
+ tr.innerHTML = `<td>${item.slot}</td><td>${item.name}</td><td>${item.count}</td><td>${equipButton}</td>`;
266
+ invTableBody.appendChild(tr);
267
+ });
268
+ });
269
+
270
+ // Chat Command Logic
271
+ document.getElementById('sendChat').addEventListener('click', () => {
272
+ const input = document.getElementById('chatInput');
273
+ const text = input.value.trim();
274
+ if (text.length > 0) {
275
+ sendCommand(`chat:${text}`);
276
+ input.value = '';
277
+ }
278
+ });
279
+
280
+ document.getElementById('chatInput').addEventListener('keydown', e => {
281
+ if (e.key === 'Enter') document.getElementById('sendChat').click();
282
+ });
283
+
284
+ // Manual Command Logic (New Addition)
285
+ const sendCmdBtn = document.getElementById('sendCmdBtn');
286
+ const cmdInput = document.getElementById('cmdInput');
287
+
288
+ sendCmdBtn.addEventListener('click', () => {
289
+ const val = cmdInput.value.trim();
290
+ if (val.length > 0) {
291
+ sendCommand(val); // Sends the raw input value as a command
292
+ cmdInput.value = '';
293
+ }
294
+ });
295
+
296
+ cmdInput.addEventListener('keydown', e => {
297
+ if (e.key === 'Enter') sendCmdBtn.click();
298
+ });
299
+
300
+ </script>
301
+ </body>
302
+ </html>
index.js ADDED
@@ -0,0 +1,167 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const mineflayer = require('mineflayer');
2
+ const express = require('express');
3
+ const http = require('http');
4
+ const socketIo = require('socket.io');
5
+ const { pathfinder, Movements, goals: { GoalBlock, GoalFollow } } = require('mineflayer-pathfinder');
6
+ const Vec3 = require('vec3').Vec3;
7
+
8
+ const app = express();
9
+ const server = http.createServer(app);
10
+ const io = socketIo(server);
11
+
12
+ let bot = null;
13
+ let states = {
14
+ afkWalk: false,
15
+ dirtLoop: false,
16
+ follow: false,
17
+ manualDisconnect: false,
18
+ timerId: null,
19
+ resourcePackAccepted: false // Track resource pack acceptance
20
+ };
21
+
22
+ function spawnBot() {
23
+ if (states.manualDisconnect) return;
24
+
25
+ bot = mineflayer.createBot({
26
+ host: 'mcgalaxy.space',
27
+ port: 25580,
28
+ username: 'drdalta',
29
+ auth: 'microsoft',
30
+ version: '1.21.4'
31
+ });
32
+
33
+ bot.loadPlugin(pathfinder);
34
+
35
+ bot.once('spawn', () => {
36
+ console.log('Bot has spawned');
37
+ const mcData = require('minecraft-data')(bot.version);
38
+ const mov = new Movements(bot, mcData);
39
+ bot.pathfinder.setMovements(mov);
40
+
41
+ // Handle resource pack prompt with improved logging
42
+ bot.on('resource_pack_send', (url, hash) => {
43
+ console.log('Received resource pack URL:', url, 'Hash:', hash);
44
+ bot.acceptResourcePack();
45
+ console.log('Resource pack accepted');
46
+ states.resourcePackAccepted = true; // Mark as accepted
47
+ });
48
+
49
+ // Detect if resource pack fails to load
50
+ bot.on('resource_pack_deny', () => {
51
+ console.log('Resource pack was denied or failed to load. Attempting to reconnect...');
52
+ states.manualDisconnect = false;
53
+ bot.quit();
54
+ setTimeout(spawnBot, 5000); // Retry after 5 seconds
55
+ });
56
+
57
+ // Log server messages to debug further prompts or issues
58
+ bot.on('message', (message) => {
59
+ const msg = message.toString();
60
+ console.log('Server message:', msg);
61
+ if (msg.includes('resource pack') && !states.resourcePackAccepted) {
62
+ console.log('Resource pack prompt detected, re-attempting acceptance...');
63
+ bot.acceptResourcePack();
64
+ }
65
+ });
66
+
67
+ // Afk walk loop
68
+ setInterval(() => {
69
+ if (states.afkWalk && !states.follow && bot.entity) {
70
+ const { x, y, z } = bot.entity.position;
71
+ const tx = x + (Math.random() - 0.5) * 4;
72
+ const tz = z + (Math.random() - 0.5) * 4;
73
+ bot.pathfinder.setGoal(new GoalBlock(Math.floor(tx), Math.floor(y), Math.floor(tz)));
74
+ }
75
+ }, 10000);
76
+
77
+ // Dirt loop
78
+ setInterval(async () => {
79
+ if (!states.dirtLoop || states.follow || !bot.entity) return;
80
+ try {
81
+ const basePos = bot.entity.position.offset(0, -1, 2);
82
+ const frontPos = bot.entity.position.offset(0, 0, 2);
83
+ const base = bot.blockAt(basePos);
84
+ const front = bot.blockAt(frontPos);
85
+ const dirt = bot.inventory.items().find(i => i.name.includes('dirt'));
86
+ if (!base || !dirt) return;
87
+ await bot.equip(dirt, 'hand');
88
+ if (front && front.name !== 'air') {
89
+ await bot.dig(front);
90
+ await new Promise(res => setTimeout(res, 2001));
91
+ }
92
+ await bot.placeBlock(base, new Vec3(0, 1, 0));
93
+ await new Promise(res => setTimeout(res, 500));
94
+ } catch (err) {
95
+ console.log('DirtLoop error:', err.message);
96
+ }
97
+ }, 2500);
98
+ });
99
+
100
+ bot.on('end', reason => {
101
+ console.log('Disconnected:', reason);
102
+ states.resourcePackAccepted = false; // Reset on disconnect
103
+ if (!states.manualDisconnect) {
104
+ setTimeout(spawnBot, 5000);
105
+ }
106
+ });
107
+
108
+ bot.on('error', e => console.log('Error:', e.message));
109
+ }
110
+
111
+ spawnBot();
112
+
113
+ io.on('connection', socket => {
114
+ console.log('Client connected');
115
+
116
+ socket.on('command', msg => {
117
+ if (!bot || !bot.entity) return;
118
+ const [cmd, param] = msg.split(':');
119
+ switch (cmd) {
120
+ case 'toggle_afk': states.afkWalk = !states.afkWalk; break;
121
+ case 'toggle_dirt': states.dirtLoop = !states.dirtLoop; break;
122
+ case 'toggle_follow':
123
+ states.follow = !states.follow;
124
+ if (states.follow) {
125
+ const target = bot.players['DrTurjo']?.entity;
126
+ if (target) {
127
+ bot.pathfinder.setGoal(new GoalFollow(target, 1), true);
128
+ } else states.follow = false;
129
+ } else bot.pathfinder.stop();
130
+ break;
131
+ case 'move': bot.setControlState(param, true); break;
132
+ case 'stop': bot.clearControlStates(); break;
133
+ case 'click_left': {
134
+ const ent = bot.nearestEntity(); if (ent) bot.attack(ent); break;
135
+ }
136
+ case 'click_right': bot.activateItem(); break;
137
+ case 'slot': {
138
+ const s = parseInt(param, 10) - 1;
139
+ if (s >= 0 && s <= 8) bot.setQuickBarSlot(s);
140
+ break;
141
+ }
142
+ case 'timer': {
143
+ if (states.timerId) clearTimeout(states.timerId);
144
+ const mins = parseInt(param, 10);
145
+ if (isNaN(mins) || mins <= 0) return;
146
+ states.timerId = setTimeout(() => {
147
+ states.manualDisconnect = true;
148
+ bot.quit();
149
+ }, mins * 60 * 1000);
150
+ break;
151
+ }
152
+ case 'disconnect': states.manualDisconnect = true; bot.quit(); break;
153
+ case 'reconnect': states.manualDisconnect = false; bot.quit(); setTimeout(spawnBot, 1000); break;
154
+ case 'chat': bot.chat(param); break;
155
+ }
156
+ });
157
+
158
+ socket.on('get_inv', () => {
159
+ if (!bot) return;
160
+ const inv = bot.inventory.items().map(i => ({ slot: i.slot, name: i.name, count: i.count }));
161
+ socket.emit('inventory', inv);
162
+ });
163
+ });
164
+
165
+ app.use(express.static(__dirname));
166
+ app.get('/', (req, res) => res.sendFile(__dirname + '/index.html'));
167
+ server.listen(process.env.PORT || 7860);
package.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "mineflayer-web-ui-bot",
3
+ "version": "1.0.0",
4
+ "main": "index.js",
5
+ "type": "commonjs",
6
+ "dependencies": {
7
+ "express": "^4.18.2",
8
+ "http": "^0.0.1-security",
9
+ "socket.io": "^4.7.2",
10
+ "mineflayer": "^4.30.0",
11
+ "mineflayer-pathfinder": "^2.4.0",
12
+ "vec3": "^0.1.7",
13
+ "minecraft-data": "^3.35.0"
14
+ }
15
+ }