oh fuck i forgot
This commit is contained in:
167
bot.js
Normal file
167
bot.js
Normal file
@@ -0,0 +1,167 @@
|
||||
|
||||
const WebSocket = require('ws');
|
||||
const logger = require('./logger');
|
||||
const protocol = require('./protocol');
|
||||
const readline = require('readline');
|
||||
|
||||
// In a real app, these would come from env or arguments
|
||||
const CONFIG = {
|
||||
URL: 'wss://magicgarden.gg/version/436ff68/api/rooms/NJMF/connect?surface=%22web%22&platform=%22desktop%22&playerId=%22p_WU9ea4LiMfR9AZsq%22&version=%22436ff68%22&source=%22router%22&capabilities=%22fbo_mipmap_unsupported%22',
|
||||
HEADERS: {
|
||||
'Host': 'magicgarden.gg',
|
||||
'Origin': 'https://magicgarden.gg',
|
||||
'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36',
|
||||
'Cookie': 'mc_jwt=eyJhbGciOiJIUzI1NiJ9.eyJwcm92aWRlciI6ImRpc2NvcmQiLCJ1c2VySWQiOiI0MTk2Mjk0MDU5MDA2MzYxNzAiLCJ0b2tlblJlc3BvbnNlIjp7ImFjY2Vzc190b2tlbiI6Ik1USXlOemN4T1RZd05qSXlNemMyTlRZNE53LlpwRjdpMFRFN2xIQ05MRUgxN0MzTmpqTGFvbTNySCIsInRva2VuX3R5cGUiOiJCZWFyZXIiLCJleHBpcmVzX2luIjo2MDQ4MDAsInJlZnJlc2hfdG9rZW4iOiJMSGRKNXhTblQweGl6Y1l3anhZQzhOYW5pV0dWMUkiLCJzY29wZSI6Imd1aWxkcy5tZW1iZXJzLnJlYWQgZ3VpbGRzIGFwcGxpY2F0aW9ucy5jb21tYW5kcyBycGMudm9pY2UucmVhZCBpZGVudGlmeSJ9LCJkaXNjb3JkVXNlckZsYWdzIjowLCJvYnRhaW5lZEF0IjoxNzY0OTU5NjU3MjU0LCJpYXQiOjE3NjQ5NjQxNTAsImV4cCI6MTc5NjUyMTc1MH0.D2O3tdQRWL2LODjahK1B4MUJGAAaYjCxQzE1-eg_680; ph_phc_5NQnL0ALxa7n1xjFEeSAe3lMsL8gYu8c8F2RhgSiIkN_posthog=%7B%22distinct_id%22%3A%22419629405900636170%22%2C%22%24sesid%22%3A%5B1764964150683%2C%22019af00f-a521-78c9-976c-ae566391ae37%22%2C1764964148513%5D%2C%22%24epp%22%3Atrue%2C%22%24initial_person_info%22%3A%7B%22r%22%3A%22https%3A%2F%2Fwww.google.com%2F%22%2C%22u%22%3A%22https%3A%2F%2Fmagicgarden.gg%2Fr%2FQMQC%22%7D%7D'
|
||||
}
|
||||
};
|
||||
|
||||
class MagicGardenBot {
|
||||
constructor() {
|
||||
this.ws = null;
|
||||
this.pingInterval = null;
|
||||
this.rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
}
|
||||
|
||||
connect() {
|
||||
logger.info('Connecting to Magic Garden server...');
|
||||
this.ws = new WebSocket(CONFIG.URL, { headers: CONFIG.HEADERS });
|
||||
|
||||
this.ws.on('open', () => this.onOpen());
|
||||
this.ws.on('message', (data) => this.onMessage(data));
|
||||
this.ws.on('close', () => this.onClose());
|
||||
this.ws.on('error', (err) => logger.error('WebSocket error', err));
|
||||
}
|
||||
|
||||
onOpen() {
|
||||
logger.info('WebSocket connection established!');
|
||||
|
||||
// 1. Send Handshake
|
||||
const handshakes = protocol.createHandshakeMessages();
|
||||
handshakes.forEach(msg => {
|
||||
// logger.info('Sending handshake:', msg.type);
|
||||
this.send(msg);
|
||||
});
|
||||
|
||||
// 2. Start Heartbeat
|
||||
this.pingInterval = setInterval(() => {
|
||||
const ping = protocol.createPing();
|
||||
this.send(ping);
|
||||
}, 2000);
|
||||
|
||||
// 3. Start CLI
|
||||
this.startCLI();
|
||||
}
|
||||
|
||||
startCLI() {
|
||||
console.log('--- CLI COMMANDS ---');
|
||||
console.log('move <x> <y>');
|
||||
console.log('plant <slot> <species>');
|
||||
console.log('harvest <slot>');
|
||||
console.log('sell');
|
||||
console.log('buy <species>');
|
||||
console.log('--------------------');
|
||||
|
||||
this.rl.on('line', (line) => {
|
||||
const args = line.trim().split(' ');
|
||||
const command = args[0].toLowerCase();
|
||||
|
||||
try {
|
||||
switch (command) {
|
||||
case 'move':
|
||||
if (args.length < 3) throw new Error('Usage: move <x> <y>');
|
||||
this.send(protocol.createTeleport(parseInt(args[1]), parseInt(args[2])));
|
||||
logger.info(`Moving to ${ args[1] }, ${ args[2] } `);
|
||||
break;
|
||||
case 'plant':
|
||||
if (args.length < 3) throw new Error('Usage: plant <slot> <species>');
|
||||
this.send(protocol.createPlant(args[1], args[2]));
|
||||
logger.info(`Planting ${ args[2] } in slot ${ args[1] } `);
|
||||
break;
|
||||
case 'harvest':
|
||||
if (args.length < 2) throw new Error('Usage: harvest <slot>');
|
||||
this.send(protocol.createHarvest(args[1]));
|
||||
logger.info(`Harvesting slot ${ args[1] } `);
|
||||
break;
|
||||
case 'sell':
|
||||
this.send(protocol.createSellAll());
|
||||
logger.info('Selling all crops');
|
||||
break;
|
||||
case 'buy':
|
||||
if (args.length < 2) throw new Error('Usage: buy <species>');
|
||||
this.send(protocol.createPurchase(args[1]));
|
||||
logger.info(`Buying ${ args[1] } `);
|
||||
break;
|
||||
default:
|
||||
console.log('Unknown command');
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error('Command error:', e.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
send(msg) {
|
||||
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
||||
this.ws.send(JSON.stringify(msg));
|
||||
}
|
||||
}
|
||||
|
||||
onMessage(data) {
|
||||
const str = data.toString();
|
||||
|
||||
// Handle server heartbeat
|
||||
if (str === 'ping') {
|
||||
// logger.info('Server ping -> Client pong');
|
||||
this.ws.send('pong');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const msg = JSON.parse(str);
|
||||
this.handleGameMessage(msg);
|
||||
} catch (e) {
|
||||
// logger.warn('Non-JSON message received', str);
|
||||
}
|
||||
}
|
||||
|
||||
handleGameMessage(msg) {
|
||||
if (msg.type === protocol.TYPES.WELCOME) {
|
||||
logger.info('WELCOME received!', {
|
||||
roomId: msg.fullState.roomId,
|
||||
playerId: msg.fullState.hostPlayerId
|
||||
});
|
||||
}
|
||||
else if (msg.type === protocol.TYPES.PARTIAL_STATE) {
|
||||
// Can be spammy
|
||||
// logger.info('State update received');
|
||||
}
|
||||
else if (msg.type === protocol.TYPES.PONG) {
|
||||
// ignore
|
||||
}
|
||||
else {
|
||||
logger.info('Received Message:', msg.type);
|
||||
}
|
||||
}
|
||||
|
||||
onClose() {
|
||||
logger.warn('Disconnected from server.');
|
||||
clearInterval(this.pingInterval);
|
||||
|
||||
// Simple reconnect after 5s
|
||||
logger.info('Reconnecting in 5 seconds...');
|
||||
setTimeout(() => this.connect(), 5000);
|
||||
}
|
||||
}
|
||||
|
||||
// Start the bot
|
||||
const bot = new MagicGardenBot();
|
||||
bot.connect();
|
||||
|
||||
// Handle graceful shutdown
|
||||
process.on('SIGINT', () => {
|
||||
logger.info('Stopping bot...');
|
||||
process.exit(0);
|
||||
});
|
||||
Reference in New Issue
Block a user