Guest User

Untitled

a guest
Nov 11th, 2024
27
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.60 KB | None | 0 0
  1. const mineflayer = require('mineflayer');
  2. const { pathfinder, Movements, goals } = require('mineflayer-pathfinder')
  3. const GoalFollow = goals.GoalFollow
  4. const { OpenAI } = require('openai'); // Убедись, что правильно импортируешь
  5. const Vec3 = require('vec3');
  6.  
  7. const bot = mineflayer.createBot({
  8. host: 'localhost',
  9. port: 54546,
  10. username: 'GPTChel',
  11. auth: 'offline',
  12. });
  13.  
  14. bot.loadPlugin(pathfinder)
  15.  
  16. const client = new OpenAI({
  17. apiKey: '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', // Заменить на свой ключ
  18. });
  19.  
  20. let playerIntervals = {};
  21. let interval; // Объявляем переменную interval в глобальной области видимости
  22.  
  23. let lastMinedHeight = null; // Глобальная переменная для хранения высоты последнего добытого блока
  24.  
  25. let history = [{ role: 'system', content: 'Вы бот задача которого играть в игру майнкрафт на разных серверах. Вас зовут GPTChel. Вы не должны отвечать на сообщения адресованные не вам. Вы написаны на mineflayer и javascript.' }];
  26. let functions = [
  27. {
  28. "name": "chat",
  29. "description": "Выводит в игровой чат сообщение от вашего имени.",
  30. "parameters": {
  31. "type": "object",
  32. "properties": {
  33. "message": {
  34. "type": "string",
  35. "description": "Сообщение."
  36. }
  37. },
  38. "required": ["message"]
  39. }
  40. },
  41. {
  42. "name": "forward",
  43. "description": "Заставляет вашего персонажа идти вперед до того момента как вы используете функцию stop.",
  44. "parameters": {
  45. "type": "object",
  46. "properties": {},
  47. }
  48. },
  49. {
  50. "name": "stop",
  51. "description": "Заставляет вашего персонажа остановится до того момента как вы используете функцию forward. Желательно использовать после CollectBlock",
  52. "parameters": {
  53. "type": "object",
  54. "properties": {},
  55. }
  56. },
  57. {
  58. "name": "toplayer",
  59. "description": "Заставляет вашего персонажа идти к игроку до того момента как расстояние между игроком и персонажем будет меньше или равно 2 блокам после чего персонаж остановится, по этому вы должны отправить функцию toplayer лишь раз.",
  60. "parameters": {
  61. "type": "object",
  62. "properties": {
  63. "user": {
  64. "type": "string",
  65. "description": "Имя игрока."
  66. }
  67. },
  68. "required": ["user"]
  69. }
  70. },
  71. {
  72. "name": "followplayer",
  73. "description": "Заставляет вашего персонажа следовать игроком до того момента как вы отправите функцию stop.",
  74. "parameters": {
  75. "type": "object",
  76. "properties": {
  77. "user": {
  78. "type": "string",
  79. "description": "Имя игрока."
  80. }
  81. },
  82. "required": ["user"]
  83. }
  84. },
  85. {
  86. "name": "none",
  87. "description": "Пустышка, ничего не делает но позволяет просто пропустить интерацию.",
  88. "parameters": {
  89. "type": "object",
  90. "properties": {},
  91. }
  92. },
  93. {
  94. "name": "collectblock",
  95. "description": "Позволяет собрать определенное количество определенного блока. ! Отправляйте новую функцию collectblock только после получения соообщения Вы успешно добыли блоки:... ЕСЛИ ПОСЛЕ collectblock ВЫ НЕ ДОЖИДАЯСЬ ОТВЕТА Вы успешно добыли блоки:... ВВЕДЕТЕ collectblock ТО БОТ НАЧНЕТ КОПАТЬ ЕГО ЗАНОГО И НИКОГДА НЕ ВЫКАПАЕТ БЛОК ! если нужно добыть деревесину пишите не wood а log",
  96. "parameters": {
  97. "type": "object",
  98. "properties": {
  99. "block": {
  100. "type": "string",
  101. "description": "Название блока. Писать по английски!"
  102. },
  103. "amount": {
  104. "type": "number",
  105. "description": "Количество."
  106. }
  107. },
  108. }
  109. },
  110. {
  111. "name": "giveplayer",
  112. "description": "Позволяет кинуть определенный блок в определенном количестве определенному игроку.",
  113. "parameters": {
  114. "type": "object",
  115. "properties": {
  116. "block": {
  117. "type": "string",
  118. "description": "Название блока. Писать по английски!"
  119. },
  120. "amount": {
  121. "type": "number",
  122. "description": "Количество."
  123. },
  124. "user": {
  125. "type": "string",
  126. "description": "Имя игрока."
  127. }
  128. },
  129. }
  130. },
  131. {
  132. "name": "coordinates",
  133. "description": "Позволяет вам узнать свои координаты в мире.",
  134. "parameters": {
  135. "type": "object",
  136. "properties": {},
  137. }
  138. },
  139. {
  140. "name": "placeblock",
  141. "description": "Позволяет заставить бота поставить определенный блок в определенные координаты x y z. ! обязательно перед использованием испольуйте coordinates",
  142. "parameters": {
  143. "type": "object",
  144. "properties": {
  145. "block": {
  146. "type": "string",
  147. "description": "Название блока. Писать по английски!"
  148. },
  149. "x": {
  150. "type": "number",
  151. "description": "Координата x"
  152. },
  153. "y": {
  154. "type": "number",
  155. "description": "Координата y."
  156. },
  157. "z": {
  158. "type": "number",
  159. "description": "Координата z."
  160. }
  161. },
  162. }
  163. },
  164. {
  165. "name": "craft",
  166. "description": "Позволяет скрафтить предмет ! убедитесь что у вас есть необходимые материалы в инвентаре.",
  167. "parameters": {
  168. "type": "object",
  169. "properties": {
  170. "item": {
  171. "type": "string",
  172. "description": "Название предмета. Писать по английски!"
  173. },
  174. "amount": {
  175. "type": "number",
  176. "description": "Количество предмета"
  177. },
  178. }
  179. },
  180. },
  181. {
  182. "name": "inventory",
  183. "description": "Позволяет посмотреть содержимое вашего инвентаря.",
  184. "parameters": {
  185. "type": "object",
  186. "properties": {}
  187. },
  188. },
  189. ];
  190.  
  191. async function gpt () {
  192. try {
  193. const chatCompletion = await client.chat.completions.create({
  194. messages: history,
  195. functions: functions,
  196. function_call: 'auto',
  197. model: 'gpt-4o-mini', // Модель, которая точно существует
  198. });
  199. console.log("Ответ от GPT:", JSON.stringify(chatCompletion, null, 2)); // Логируем весь ответ от GPT
  200. handle_response(chatCompletion);
  201. } catch (e) {
  202. console.error(`Error: ${e}`);
  203. }
  204. }
  205.  
  206. function chat (message) {
  207. bot.chat(message);
  208. }
  209.  
  210. function forward () {
  211. bot.setControlState('forward', true)
  212. }
  213.  
  214. function stop () {
  215. bot.setControlState('forward', false)
  216. bot.pathfinder.setGoal(null); // Останавливаем pathfinder
  217. clearInterval(interval); // Очищаем интервал
  218. history.push({ role: "system", content: "Вы остановились." });
  219. }
  220.  
  221. function toplayer(user) {
  222. const playerCI = bot.players[user];
  223. if (!playerCI || !playerCI.entity) return;
  224.  
  225. const mcData = require('minecraft-data')(bot.version);
  226. const movements = new Movements(bot, mcData);
  227. bot.pathfinder.setMovements(movements);
  228.  
  229. const goal = new GoalFollow(playerCI.entity, 1);
  230. bot.pathfinder.setGoal(goal, true);
  231.  
  232. // Проверка расстояния с помощью уникального идентификатора интервала
  233. if (playerIntervals[user]) {
  234. clearInterval(playerIntervals[user]); // Если уже есть интервал для этого игрока, очистим его
  235. }
  236.  
  237. playerIntervals[user] = setInterval(() => {
  238. const distance = bot.entity.position.distanceTo(playerCI.entity.position);
  239.  
  240. if (distance <= 2) {
  241. bot.pathfinder.setGoal(null); // Останавливаем pathfinder
  242. clearInterval(playerIntervals[user]); // Очищаем интервал для этого игрока
  243. delete playerIntervals[user]; // Удаляем интервал из памяти
  244. }
  245. }, 100); // Проверяем расстояние каждые 100 миллисекунд
  246. }
  247.  
  248. async function safeGoto(x, y, z) {
  249. return new Promise((resolve, reject) => {
  250. const goal = new goals.GoalNear(x, y, z, 1);
  251. bot.pathfinder.setGoal(goal);
  252.  
  253. // Проверяем, что цель достигнута
  254. const checkGoal = setInterval(() => {
  255. if (bot.pathfinder.goal === null) {
  256. clearInterval(checkGoal);
  257. resolve();
  258. }
  259. }, 100);
  260.  
  261. // Если цель изменится, выходим с ошибкой
  262. bot.once('goal_reached', () => {
  263. clearInterval(checkGoal);
  264. resolve();
  265. });
  266.  
  267. bot.once('goal_changed', () => {
  268. clearInterval(checkGoal);
  269. reject(new Error('Goal changed before completion'));
  270. });
  271. });
  272. }
  273.  
  274. function findNearestBlock(blockName, radius, prioritizeSameHeight = false) {
  275. const mcData = require('minecraft-data')(bot.version);
  276. const blockType = mcData.blocksByName[blockName].id;
  277.  
  278. // Сначала ищем блоки на той же высоте, что и предыдущий добытый блок
  279. if (prioritizeSameHeight && lastMinedHeight !== null) {
  280. const sameHeightBlocks = bot.findBlocks({
  281. matching: blockType,
  282. maxDistance: radius,
  283. count: 1,
  284. filter: block => block.y === lastMinedHeight // Ищем только на той же высоте
  285. });
  286.  
  287. if (sameHeightBlocks.length > 0) {
  288. return bot.blockAt(sameHeightBlocks[0]);
  289. }
  290. }
  291.  
  292. // Если не нашли на той же высоте, ищем любые другие блоки
  293. const blocks = bot.findBlocks({
  294. matching: blockType,
  295. maxDistance: radius,
  296. count: 1,
  297. });
  298.  
  299. if (blocks.length === 0) return null;
  300. return bot.blockAt(blocks[0]);
  301. }
  302.  
  303. async function mineBlocks(blockName, count) {
  304. for (let i = 0; i < count; i++) {
  305. const targetBlock = findNearestBlock(blockName, 5, true); // Передаем true для приоритета по высоте
  306.  
  307. if (!targetBlock) {
  308. history.push({ role: "system", content: `Блок ${blockName} не найден в радиусе 5 блоков.` });
  309. break;
  310. }
  311.  
  312. try {
  313. await safeGoto(targetBlock.position.x, targetBlock.position.y, targetBlock.position.z);
  314. } catch (err) {
  315. console.error("Ошибка при установке цели:", err);
  316. continue; // Переход к следующему блоку при ошибке
  317. }
  318.  
  319. // Обновляем высоту последнего добытого блока
  320. lastMinedHeight = targetBlock.position.y;
  321.  
  322. // Добыча блока
  323. try {
  324. history.push({ role: "system", content: `Вы добываете блоки: ${blockName} на высоте ${lastMinedHeight}` });
  325. await bot.dig(targetBlock);
  326. history.push({ role: "system", content: `Вы успешно добыли блоки: ${blockName} на высоте ${lastMinedHeight}` });
  327. } catch (err) {
  328. console.log("Ошибка при добыче блока:", err);
  329. break;
  330. }
  331. }
  332. }
  333.  
  334. function coordinates () {
  335. const position = bot.entity.position;
  336. history.push({ role: "system", content: `Координаты бота: X: ${position.x}, Y: ${position.y}, Z: ${position.z}`});
  337. }
  338.  
  339. async function placeblock(block, target_pos) {
  340. const mcData = require('minecraft-data')(bot.version);
  341. const movements = new Movements(bot, mcData);
  342. bot.pathfinder.setMovements(movements);
  343.  
  344. // Проверяем, есть ли нужный блок в инвентаре
  345. const blockToPlace = bot.inventory.items().find(item => item.name === block);
  346. if (!blockToPlace) {
  347. console.log(`Блок ${block} не найден в инвентаре!`);
  348. return;
  349. }
  350.  
  351. console.log(`Готовимся поставить блок: ${blockToPlace.displayName}`);
  352.  
  353. // Проверка целевой позиции
  354. console.log(`Целевая позиция для установки блока: X: ${target_pos.x}, Y: ${target_pos.y}, Z: ${target_pos.z}`);
  355.  
  356. // Проверяем блок под целевой позицией
  357. const referenceBlock = bot.blockAt(target_pos.offset(0, -1, 0)); // Получаем блок под целевой позицией
  358. if (!referenceBlock) {
  359. console.log('Нет блока под целевой позицией!');
  360. return;
  361. }
  362.  
  363. // Логируем блок, который будет использоваться для установки
  364. console.log('Устанавливаем блок на: ', referenceBlock);
  365.  
  366. // Подготовка к установке
  367. try {
  368. await bot.equip(blockToPlace, 'hand');
  369. await bot.placeBlock(referenceBlock, new Vec3(0, 1, 0)); // Размещение блока
  370. console.log('Блок успешно установлен!');
  371. } catch (err) {
  372. console.error('Ошибка при установке блока:', err);
  373. }
  374. }
  375.  
  376. function followplayer (user) {
  377. const playerCI = bot.players[user]
  378. if (!playerCI || !playerCI.entity) return;
  379.  
  380. const mcData = require('minecraft-data')(bot.version)
  381. const movements = new Movements(bot, mcData)
  382. bot.pathfinder.setMovements(movements)
  383.  
  384. const goal = new GoalFollow(playerCI.entity, 1)
  385. bot.pathfinder.setGoal(goal, true)
  386. }
  387.  
  388. async function giveplayer (block, amount, user) {
  389. const playerCI = bot.players[user];
  390. if (!playerCI || !playerCI.entity) return;
  391.  
  392. await toplayer(user)
  393.  
  394. setTimeout(function() {}, 6000); // 1000 миллисекунд = 1 секунда
  395.  
  396. // Координаты игрока
  397. const targetPos = playerCI.entity.position.offset(0, 1.6, 0); // Смотреть на уровень головы
  398.  
  399. try {
  400. // Повернуться к игроку
  401. await bot.lookAt(targetPos, true);
  402.  
  403. // Проверяем инвентарь и выводим его содержимое
  404. console.log("Текущий инвентарь:", bot.inventory.items());
  405.  
  406. const mcData = require('minecraft-data')(bot.version);
  407. const itemType = mcData.itemsByName[block]?.id; // Используем ID предмета
  408. const item = bot.inventory.items().find(i => i.type === itemType);
  409.  
  410. if (!item) {
  411. console.log(`У вас нет предмета ${block}.`);
  412. history.push({ role: "system", content: `У вас нет предмета ${block}.` });
  413. return;
  414. }
  415.  
  416. if (amount > item.count) {
  417. console.log(`Недостаточно ${block}. Доступно: ${item.count}`);
  418. history.push({ role: "system", content: `Недостаточно ${block}. Доступно: ${item.count}` });
  419. return;
  420. }
  421.  
  422. // Бросаем предмет
  423. await bot.toss(item.type, null, amount);
  424. console.log(`GPTChel кинул ${amount} ${block} игроку ${user}`);
  425. history.push({ role: "system", content: `Вы кинули игроку ${user} блок ${block} в количестве ${amount}` });
  426. } catch (err) {
  427. console.log(`Ошибка при передаче предмета: ${err.message}`);
  428. }
  429. }
  430.  
  431. function craft(recipeName, count) {
  432. const recipes = bot.recipesFor(recipeName); // Получаем рецепт
  433. console.log("Найденные рецепты для крафта:", recipes);
  434.  
  435. if (recipes.length === 0) {
  436. history.push({ role: "system", content: 'Рецепт не найден!' });
  437. console.log("Рецепт не найден!");
  438. return;
  439. }
  440.  
  441. const recipe = recipes[0]; // Получаем первый рецепт
  442. console.log("Требуемые ингредиенты рецепта:", recipe.ingredients);
  443.  
  444. // Проверка, что у бота есть все необходимые материалы
  445. const materialsAvailable = Array.isArray(recipe.ingredients) && recipe.ingredients.every(ingredient => {
  446. const inventoryItem = bot.inventory.items().find(item => item.name === ingredient.name);
  447. return inventoryItem && inventoryItem.count >= ingredient.count;
  448. });
  449.  
  450. if (!materialsAvailable) {
  451. console.log(bot.inventory.items());
  452. console.log('У бота недостаточно материалов для крафта.');
  453. history.push({ role: "system", content: 'У бота недостаточно материалов для крафта.' });
  454. return;
  455. }
  456.  
  457. // Открытие крафтового меню (внутреннего окна бота)
  458. bot.openCraftingTable((err, craftingTable) => {
  459. if (err) {
  460. console.log("Ошибка при открытии крафтового меню:", err);
  461. return;
  462. }
  463. console.log("Крафтовое меню открыто.");
  464.  
  465. // Заполнение крафтовой сетки (4 слота)
  466. const grid = craftingTable.slots.slice(0, 4); // Получаем первые 4 слота для ингредиентов
  467.  
  468. recipe.ingredients.forEach((ingredient, index) => {
  469. const inventoryItem = bot.inventory.items().find(item => item.name === ingredient.name);
  470. if (inventoryItem) {
  471. bot.putInSlot(grid[index], inventoryItem, (err) => {
  472. if (err) {
  473. console.log("Ошибка при размещении ингредиента в сетке:", err);
  474. }
  475. });
  476. }
  477. });
  478.  
  479. // Запуск крафта
  480. craftingTable.craft(recipe, count, (err) => {
  481. if (err) {
  482. console.log("Ошибка при крафте:", err);
  483. history.push({ role: "system", content: 'Ошибка при крафте!' });
  484. } else {
  485. console.log("Крафт завершён успешно.");
  486. history.push({ role: "system", content: 'Крафт завершён успешно.' });
  487. }
  488. });
  489. });
  490. }
  491.  
  492. function inventory () {
  493. // Получаем инвентарь
  494. const inventory = bot.inventory;
  495.  
  496. // Проходим по всем слотам инвентаря
  497. inventory.slots.forEach((item, index) => {
  498. if (item) {
  499. history.push({ role: "system", content: `Слот ${index}: ${item.name}, Количество: ${item.count}`});
  500. }
  501. })
  502. }
  503.  
  504. async function handle_response(response) {
  505. if (response.choices[0].message.function_call) {
  506. const function_name = response.choices[0].message.function_call.name;
  507.  
  508. if (function_name === 'chat') {
  509. const function_call = response.choices[0].message.function_call;
  510. try {
  511. const arguments = JSON.parse(function_call.arguments);
  512. const message = arguments.message;
  513.  
  514. chat(message);
  515. history.push({ role: "system", content: "Вы отправили сообщение: " + message });
  516. console.log("GPTChel отправил сообщение: " + message)
  517. } catch (err) {
  518. console.error('Ошибка при разборе аргументов функции: ', err);
  519. }
  520. }
  521.  
  522. else if (function_name === 'forward') {
  523. forward()
  524. }
  525.  
  526. else if (function_name === 'stop') {
  527. stop()
  528. }
  529.  
  530. else if (function_name === 'coordinates') {
  531. coordinates()
  532. }
  533.  
  534. else if (function_name === 'toplayer') {
  535. const function_call = response.choices[0].message.function_call;
  536. try {
  537. const arguments = JSON.parse(function_call.arguments);
  538. const user = arguments.user;
  539.  
  540. toplayer(user);
  541. history.push({ role: "system", content: "Вы идете к игроку: " + user });
  542. console.log("GPTChel идет к: " + user)
  543. } catch (err) {
  544. console.error('Ошибка при разборе аргументов функции: ', err);
  545. }
  546. }
  547.  
  548. else if (function_name === 'followplayer') {
  549. const function_call = response.choices[0].message.function_call;
  550. try {
  551. const arguments = JSON.parse(function_call.arguments);
  552. const user = arguments.user;
  553.  
  554. followplayer(user);
  555. history.push({ role: "system", content: "Вы следуете за игроком: " + user });
  556. console.log("GPTChel следует за: " + user)
  557. } catch (err) {
  558. console.error('Ошибка при разборе аргументов функции: ', err);
  559. }
  560. }
  561.  
  562. else if (function_name === 'collectblock') {
  563. const function_call = response.choices[0].message.function_call;
  564. try {
  565. const arguments = JSON.parse(function_call.arguments);
  566. const block = arguments.block;
  567. const amount = arguments.amount;
  568.  
  569. await mineBlocks(block, amount);
  570. console.log("GPTChel добывает: " + block)
  571. } catch (err) {
  572. console.error('Ошибка при разборе аргументов функции: ', err);
  573. }
  574. }
  575.  
  576. else if (function_name === 'giveplayer') {
  577. const function_call = response.choices[0].message.function_call;
  578. try {
  579. const arguments = JSON.parse(function_call.arguments);
  580. const block = arguments.block;
  581. const amount = arguments.amount;
  582. const user = arguments.user;
  583.  
  584. giveplayer(block, amount, user);
  585. history.push({ role: "system", content: `Вы кинули игроку ${user} блок ${block} в количестве ${amount}`});
  586. console.log("GPTChel выкидывает: " + block)
  587. } catch (err) {
  588. console.error('Ошибка при разборе аргументов функции: ', err);
  589. }
  590. }
  591.  
  592. else if (function_name === 'placeblock') {
  593. const function_call = response.choices[0].message.function_call;
  594. try {
  595. const arguments = JSON.parse(function_call.arguments);
  596. const block = arguments.block;
  597. const x = arguments.x;
  598. const y = arguments.y;
  599. const z = arguments.z;
  600.  
  601. target_pos = new Vec3(x, y, z);
  602.  
  603. placeblock(block, target_pos);
  604. history.push({ role: "system", content: `Вы поставили блок ${block}.`});
  605. console.log("GPTChel ставит: " + block)
  606. } catch (err) {
  607. console.error('Ошибка при разборе аргументов функции: ', err);
  608. }
  609. }
  610.  
  611. else if (function_name === 'inventory') {
  612. inventory()
  613. }
  614.  
  615. else if (function_name === 'craft') {
  616. const function_call = response.choices[0].message.function_call;
  617. try {
  618. const arguments = JSON.parse(function_call.arguments);
  619. const item = arguments.item;
  620. console.log(item)
  621. const amount = arguments.amount;
  622. console.log(amount)
  623.  
  624. craft(item, amount);
  625. console.log("GPTChel крафтит: " + item)
  626. } catch (err) {
  627. console.error('Ошибка при разборе аргументов функции: ', err);
  628. }
  629. }
  630. }
  631. else {
  632.  
  633. }
  634. }
  635.  
  636. // Функция для постоянных обращений к GPT с задержкой в 1 секунду
  637. async function continuousGPT() {
  638. while (true) {
  639. await gpt(); // Ждем завершения вызова
  640. await new Promise(resolve => setTimeout(resolve, 2000)); // Задержка в 2 секунду
  641. }
  642. }
  643.  
  644. bot.on('spawn', () => {
  645. console.log('Бот запущен!');
  646. continuousGPT(); // Запускаем постоянные обращения к GPT
  647. });
  648.  
  649. bot.on('error', (err) => {
  650. console.log('Ошибка подключения:', err);
  651. });
  652.  
  653. bot.on('end', () => {
  654. console.log('Бот отключен.');
  655. });
  656.  
  657. bot.on('login', () => {
  658. console.log('Бот успешно вошел в игру!');
  659. });
  660.  
  661. bot.on('chat', (user, message) => {
  662. if (user != 'GPTChel') {
  663. history.push({ role: "system", content: `В игровой чат было отправлено сообщение от ${user}: ${message}` });
  664. console.log("Получено сообщение: " + message)
  665. }
  666. });
Add Comment
Please, Sign In to add comment