mirror of
https://github.com/kolbytn/mindcraft.git
synced 2025-09-08 11:03:00 +02:00
finished context commands
This commit is contained in:
parent
9682255f71
commit
a6b1f4cb81
6 changed files with 163 additions and 63 deletions
10
act.js
10
act.js
|
@ -86,9 +86,11 @@ export async function executeCode(bot) {
|
||||||
await (await import('./temp.js')).main(bot);
|
await (await import('./temp.js')).main(bot);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log(err);
|
console.log(err);
|
||||||
|
currentCode = '';
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentCode = '';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,13 +120,13 @@ export async function writeCode(bot, username, messages) {
|
||||||
|
|
||||||
let code = actResponse.split('\`\`\`');
|
let code = actResponse.split('\`\`\`');
|
||||||
if (code.length <= 1)
|
if (code.length <= 1)
|
||||||
return false;
|
return code;
|
||||||
if (!code[1].trim())
|
if (!code[1].trim())
|
||||||
return false;
|
return code;
|
||||||
|
|
||||||
currentCode = code[1].trim();
|
currentCode = code[1].trim();
|
||||||
if (currentCode.slice(0, 10) == 'javascript')
|
if (currentCode.slice(0, 10) == 'javascript')
|
||||||
currentCode = currentCode.slice(10).trim();
|
currentCode = currentCode.slice(10).trim();
|
||||||
|
|
||||||
return true;
|
return currentCode;
|
||||||
}
|
}
|
||||||
|
|
41
chat.js
41
chat.js
|
@ -1,22 +1,22 @@
|
||||||
import { sendRequest } from './utils/gpt.js';
|
import { sendRequest } from './utils/gpt.js';
|
||||||
import { getHistory, addEvent } from './utils/history.js';
|
import { getHistory, addEvent } from './utils/history.js';
|
||||||
import { getStats, getInventory, getBlocks, getNearbyPlayers, getNearbyEntities, getCraftable } from './utils/context.js';
|
import { getStats, getInventory, getBlocks, getNearbyEntities, getCraftable } from './utils/context.js';
|
||||||
import { currentCode, executeCode, writeCode } from './act.js';
|
import { currentCode, writeCode } from './act.js';
|
||||||
|
|
||||||
|
|
||||||
function buildSystemMessage(bot) {
|
function buildSystemMessage() {
|
||||||
let message = 'You are a playful Minecraft bot that can communicate with players and move within and interact with the world.';
|
let message = 'You are a playful Minecraft bot that can communicate with players and move within and interact with the world.';
|
||||||
message += ' Act human-like as if you were a typical Minecraft player, rather than an AI.';
|
message += ' Act human-like as if you were a typical Minecraft player, rather than an AI.';
|
||||||
message += ' Do not give instructions unless asked, and always be brief in your responses.';
|
message += ' Do not give instructions unless asked, and always be brief in your responses.';
|
||||||
message += '\n\nYou can use the following commands followed by to query for information about the world.';
|
message += '\n\nYou can use the following commands followed by to query for information about the world.';
|
||||||
message += ' The query response will be returned between sets of "\`\`\`":';
|
message += ' The query response will be returned between sets of "\`\`\`":';
|
||||||
message += '\n!stats - get your current health and other player stats';
|
message += '\n!stats - get player and world stats (e.g. current health and time of day)';
|
||||||
message += '\n!inventory - get your current inventory';
|
message += '\n!inventory - get your current inventory';
|
||||||
message += '\n!blocks - get a list of nearby blocks';
|
message += '\n!blocks - get a list of nearby blocks';
|
||||||
message += '\n!craftable - get a list of craftable items with your current inventory';
|
message += '\n!craftable - get a list of craftable items with your current inventory';
|
||||||
message += '\n!entities - get a list of nearby players and entities';
|
message += '\n!entities - get a list of nearby players and entities';
|
||||||
message += '\n!action - prints the currently executing code';
|
message += '\n!action - get the currently executing code';
|
||||||
message += '\n\nYou can also execute actions in Minecraft by writing javascript code.';
|
message += '\n\nYou can also execute actions such as moving and mining in Minecraft by writing javascript code.';
|
||||||
message += ' To do so, simply begin a codeblock with the "!execute" command. For example:';
|
message += ' To do so, simply begin a codeblock with the "!execute" command. For example:';
|
||||||
message += '\n!execute\n\`\`\`\nCODE\n\`\`\`';
|
message += '\n!execute\n\`\`\`\nCODE\n\`\`\`';
|
||||||
return message;
|
return message;
|
||||||
|
@ -26,7 +26,7 @@ function buildSystemMessage(bot) {
|
||||||
export async function getChatResponse(bot, user, message) {
|
export async function getChatResponse(bot, user, message) {
|
||||||
addEvent(user, message);
|
addEvent(user, message);
|
||||||
let turns = getHistory(user);
|
let turns = getHistory(user);
|
||||||
let systemMessage = buildSystemMessage(bot);
|
let systemMessage = buildSystemMessage();
|
||||||
|
|
||||||
let botResponse = '';
|
let botResponse = '';
|
||||||
let botEvent = '';
|
let botEvent = '';
|
||||||
|
@ -37,36 +37,31 @@ export async function getChatResponse(bot, user, message) {
|
||||||
console.log('received chat:', res);
|
console.log('received chat:', res);
|
||||||
|
|
||||||
let queryRes = null;
|
let queryRes = null;
|
||||||
if (res.trim().slice(res.length - 7) == '!stats') {
|
if (res.includes('!stats')) {
|
||||||
botResponse += '\n' + res.trim().slice(0, res.length - 7).trim();
|
|
||||||
queryRes = '\n\n!stats\n\`\`\`\n' + getStats(bot) + '\n\`\`\`';
|
queryRes = '\n\n!stats\n\`\`\`\n' + getStats(bot) + '\n\`\`\`';
|
||||||
} else if (res.trim().slice(res.length - 11) == '!inventory') {
|
} else if (res.includes('!inventory')) {
|
||||||
botResponse += '\n' + res.trim().slice(0, res.length - 11).trim();
|
|
||||||
queryRes = '\n\n!inventory\n\`\`\`\n' + getInventory(bot) + '\n\`\`\`';
|
queryRes = '\n\n!inventory\n\`\`\`\n' + getInventory(bot) + '\n\`\`\`';
|
||||||
} else if (res.trim().slice(res.length - 8) == '!blocks') {
|
} else if (res.includes('!blocks')) {
|
||||||
botResponse += '\n' + res.trim().slice(0, res.length - 8).trim();
|
|
||||||
queryRes = '\n\n!blocks\n\`\`\`\n' + getBlocks(bot) + '\n\`\`\`';
|
queryRes = '\n\n!blocks\n\`\`\`\n' + getBlocks(bot) + '\n\`\`\`';
|
||||||
} else if (res.trim().slice(res.length - 11) == '!craftable') {
|
} else if (res.includes('!craftable')) {
|
||||||
botResponse += '\n' + res.trim().slice(0, res.length - 11).trim();
|
|
||||||
queryRes = '\n\n!craftable\n\`\`\`\n' + getCraftable(bot) + '\n\`\`\`';
|
queryRes = '\n\n!craftable\n\`\`\`\n' + getCraftable(bot) + '\n\`\`\`';
|
||||||
} else if (res.trim().slice(res.length - 10) == '!entities') {
|
} else if (res.includes('!entities')) {
|
||||||
botResponse += '\n' + res.trim().slice(0, res.length - 10).trim();
|
queryRes = '\n\n!entities\n\`\`\`\n' + getNearbyEntities(bot) + '\n\`\`\`';
|
||||||
queryRes = '\n\n!entities\n\`\`\`\n' + getNearbyPlayers(bot) + '\n' + getNearbyEntities(bot) + '\n\`\`\`';
|
} else if (res.includes('!action')) {
|
||||||
} else if (res.trim().slice(res.length - 8) == '!action') {
|
|
||||||
botResponse += '\n' + res.trim().slice(0, res.length - 8).trim();
|
|
||||||
queryRes = '\n\n!action\n\`\`\`\n' + currentCode + '\n\`\`\`';
|
queryRes = '\n\n!action\n\`\`\`\n' + currentCode + '\n\`\`\`';
|
||||||
} else if (res.trim().slice(res.length - 9) == '!execute') {
|
} else if (res.includes('!execute')) {
|
||||||
botResponse += '\n' + res.trim().slice(0, res.length - 9).trim();
|
|
||||||
queryRes = '\n\n!execute\n\`\`\`\n' + await writeCode(bot, user, turns.concat(botResponse), botResponse) + '\n\`\`\`';
|
queryRes = '\n\n!execute\n\`\`\`\n' + await writeCode(bot, user, turns.concat(botResponse), botResponse) + '\n\`\`\`';
|
||||||
} else {
|
} else {
|
||||||
|
botResponse += '\n' + res.trim();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('query response:', queryRes);
|
||||||
botEvent += queryRes;
|
botEvent += queryRes;
|
||||||
turns[turns.length - 1] += queryRes
|
turns[turns.length - 1] += queryRes
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('sending chat:', botResponse);
|
console.log('sending chat:', botResponse.trim());
|
||||||
addEvent('bot', botEvent);
|
addEvent('bot', botEvent);
|
||||||
return botResponse.trim();
|
return botResponse.trim();
|
||||||
}
|
}
|
||||||
|
|
8
main.js
8
main.js
|
@ -3,13 +3,13 @@ import { pathfinder } from 'mineflayer-pathfinder';
|
||||||
import { plugin } from 'mineflayer-collectblock';
|
import { plugin } from 'mineflayer-collectblock';
|
||||||
|
|
||||||
import { getChatResponse } from './chat.js';
|
import { getChatResponse } from './chat.js';
|
||||||
import { executeCode, writeCode } from './act.js';
|
import { executeCode } from './act.js';
|
||||||
|
|
||||||
|
|
||||||
async function handleMessage(username, message) {
|
async function handleMessage(username, message) {
|
||||||
if (username === bot.username) return;
|
if (username === bot.username) return;
|
||||||
console.log('received message from', username, ':', message);
|
console.log('received message from', username, ':', message);
|
||||||
|
|
||||||
let chat = await getChatResponse(bot, username, message);
|
let chat = await getChatResponse(bot, username, message);
|
||||||
bot.chat(chat);
|
bot.chat(chat);
|
||||||
|
|
||||||
|
@ -23,13 +23,11 @@ async function handleMessage(username, message) {
|
||||||
const bot = createBot({
|
const bot = createBot({
|
||||||
host: '127.0.0.1',
|
host: '127.0.0.1',
|
||||||
port: 55916,
|
port: 55916,
|
||||||
username: 'andy'
|
username: 'andi'
|
||||||
})
|
})
|
||||||
bot.loadPlugin(pathfinder)
|
bot.loadPlugin(pathfinder)
|
||||||
bot.loadPlugin(plugin)
|
bot.loadPlugin(plugin)
|
||||||
|
|
||||||
// await writeCode(bot, 'all', ['all: Now, you should set your own personal goal.']);
|
|
||||||
// executeCode(bot);
|
|
||||||
console.log('bot created')
|
console.log('bot created')
|
||||||
|
|
||||||
bot.on('chat', handleMessage);
|
bot.on('chat', handleMessage);
|
||||||
|
|
|
@ -1,40 +1,97 @@
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
|
|
||||||
import { getNearbyBlocks } from './world.js';
|
import { getNearbyBlocks, getNearbyBlockTypes } from './world.js';
|
||||||
|
import { getAllItems } from './mcdata.js';
|
||||||
|
|
||||||
|
|
||||||
export function getStats(bot) {
|
export function getStats(bot) {
|
||||||
return null;
|
let res = 'STATS';
|
||||||
|
res += `\n- position: x:${bot.entity.position.x}, y:${bot.entity.position.y}, z:${bot.entity.position.z}`;
|
||||||
|
res += `\n- health: ${bot.health} / 20`;
|
||||||
|
if (bot.time.timeOfDay < 6000) {
|
||||||
|
res += '\n- time: Morning';
|
||||||
|
} else if (bot.time.timeOfDay < 12000) {
|
||||||
|
res += '\n- time: Afternoon';
|
||||||
|
} else {
|
||||||
|
res += '\n- time: Night';
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function getInventory(bot) {
|
export function getInventory(bot) {
|
||||||
return null;
|
let res = 'INVENTORY';
|
||||||
|
let allItems = new Map();
|
||||||
|
for (const item of bot.inventory.slots.values()) {
|
||||||
|
if (item != null) {
|
||||||
|
if (allItems.has(item.name)) {
|
||||||
|
allItems.set(item.name, allItems.get(item.name) + item.count);
|
||||||
|
} else {
|
||||||
|
allItems.set(item.name, item.count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const [item, count] of allItems.entries()) {
|
||||||
|
res += `\n- ${item}: ${count}`;
|
||||||
|
}
|
||||||
|
if (allItems.size == 0) {
|
||||||
|
res += ': empty';
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function getBlocks(bot) {
|
export function getBlocks(bot) {
|
||||||
let res = 'NEARBY_BLOCKS\n';
|
let res = 'NEARBY_BLOCKS';
|
||||||
let blocks = getNearbyBlocks(bot);
|
let blocks = getNearbyBlockTypes(bot);
|
||||||
for (let i = 0; i < blocks.length; i++) {
|
for (let i = 0; i < blocks.length; i++) {
|
||||||
res += `- ${blocks[i]}\n`;
|
res += `\n- ${blocks[i]}`;
|
||||||
}
|
}
|
||||||
return res.trim();
|
if (blocks.length == 0) {
|
||||||
|
res += ': none';
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function getNearbyEntities(bot) {
|
export function getNearbyEntities(bot) {
|
||||||
return null;
|
let res = 'NEARBY_ENTITIES';
|
||||||
}
|
for (const entity of Object.values(bot.entities)) {
|
||||||
|
const distance = entity.position.distanceTo(bot.entity.position);
|
||||||
|
if (distance > 50) continue;
|
||||||
export function getNearbyPlayers(bot) {
|
if (entity.type == 'mob') {
|
||||||
return null;
|
res += `\n- mob: ${entity.mobType}`;
|
||||||
|
} else if (entity.type == 'player' && entity.username != bot.username) {
|
||||||
|
res += `\n- player: ${entity.username}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res == 'NEARBY_ENTITIES') {
|
||||||
|
res += ': none';
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function getCraftable(bot) {
|
export function getCraftable(bot) {
|
||||||
return null;
|
const blocks = getNearbyBlocks(bot, 50);
|
||||||
|
let table = null;
|
||||||
|
for (const block of blocks) {
|
||||||
|
if (block.name == 'crafting_table') {
|
||||||
|
table = block;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let res = 'CRAFTABLE_ITEMS';
|
||||||
|
for (const item of getAllItems()) {
|
||||||
|
let recipes = bot.recipesFor(item.id, null, 1, table);
|
||||||
|
if (recipes.length > 0) {
|
||||||
|
res += `\n- ${item.name}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (res == 'CRAFTABLE_ITEMS') {
|
||||||
|
res += ': none';
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,57 @@
|
||||||
import minecraftData from 'minecraft-data';
|
import minecraftData from 'minecraft-data';
|
||||||
var mcdata = minecraftData("1.19.3");
|
var mcdata = minecraftData('1.19.3');
|
||||||
|
|
||||||
|
|
||||||
export function getItemId(item) {
|
export function getItemId(item) {
|
||||||
return mcdata.itemsByName[item_type].id;
|
return mcdata.itemsByName[item].id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function getAllBlockIds(ignore) {
|
export function getAllItems(ignore) {
|
||||||
|
if (!ignore) {
|
||||||
|
ignore = [];
|
||||||
|
}
|
||||||
|
let items = []
|
||||||
|
for (const itemId in mcdata.items) {
|
||||||
|
const item = mcdata.items[itemId];
|
||||||
|
if (!ignore.includes(item.name)) {
|
||||||
|
items.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getAllItemIds(ignore) {
|
||||||
|
const items = getAllItems(ignore);
|
||||||
|
let itemIds = [];
|
||||||
|
for (const item of items) {
|
||||||
|
itemIds.push(item.id);
|
||||||
|
}
|
||||||
|
return itemIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getAllBlocks(ignore) {
|
||||||
|
if (!ignore) {
|
||||||
|
ignore = [];
|
||||||
|
}
|
||||||
let blocks = []
|
let blocks = []
|
||||||
for (let i = 0; i < mcdata.blocks.length; i++) {
|
for (const blockId in mcdata.blocks) {
|
||||||
if (!ignore.includes(mcdata.blocks[i].name)) {
|
const block = mcdata.blocks[blockId];
|
||||||
blocks.push(mcdata.blocks[i].id);
|
if (!ignore.includes(block.name)) {
|
||||||
|
blocks.push(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getAllBlockIds(ignore) {
|
||||||
|
const blocks = getAllBlocks(ignore);
|
||||||
|
let blockIds = [];
|
||||||
|
for (const block of blocks) {
|
||||||
|
blockIds.push(block.id);
|
||||||
|
}
|
||||||
|
return blockIds;
|
||||||
|
}
|
||||||
|
|
|
@ -1,20 +1,30 @@
|
||||||
import { getAllBlockIds } from './mcdata.js';
|
import { getAllBlockIds } from './mcdata.js';
|
||||||
|
|
||||||
|
|
||||||
/**
|
export function getNearbyBlocks(bot, distance) {
|
||||||
* Get a list of all nearby blocks.
|
let positions = bot.findBlocks({matching: getAllBlockIds(['air']), maxDistance: distance, count: 10000});
|
||||||
* @param {Bot} bot - The bot to get nearby blocks for.
|
|
||||||
* @returns {string[]} - A list of all nearby blocks.
|
|
||||||
* @example
|
|
||||||
* let blocks = world.getNearbyBlocks(bot);
|
|
||||||
**/
|
|
||||||
export function getNearbyBlocks(bot) {
|
|
||||||
let positions = bot.findBlocks({'matching': getAllBlockIds(['air']), 'maxDistance': 16, 'count': 4096});
|
|
||||||
let found = [];
|
let found = [];
|
||||||
for (let i = 0; i < positions.length; i++) {
|
for (let i = 0; i < positions.length; i++) {
|
||||||
let block = bot.blockAt(positions[i]);
|
let block = bot.blockAt(positions[i]);
|
||||||
if (!found.includes(block.name)) {
|
found.push(block);
|
||||||
found.push(block.name);
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a list of all nearby block names.
|
||||||
|
* @param {Bot} bot - The bot to get nearby blocks for.
|
||||||
|
* @returns {string[]} - A list of all nearby blocks.
|
||||||
|
* @example
|
||||||
|
* let blocks = world.getNearbyBlockTypes(bot);
|
||||||
|
**/
|
||||||
|
export function getNearbyBlockTypes(bot) {
|
||||||
|
let blocks = getNearbyBlocks(bot, 16);
|
||||||
|
let found = [];
|
||||||
|
for (let i = 0; i < blocks.length; i++) {
|
||||||
|
if (!found.includes(blocks[i].name)) {
|
||||||
|
found.push(blocks[i].name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return found;
|
return found;
|
||||||
|
|
Loading…
Add table
Reference in a new issue