Advertisement
Guest User

Untitled

a guest
Jan 26th, 2020
340
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.19 KB | None | 0 0
  1. /**
  2. * @filename D2BotMule.js
  3. * @author kolton, IMBA
  4. * @desc Starter for automule profile *continuous muling*
  5. */
  6.  
  7. var StarterConfig = {
  8. MinGameTime: 30, // Minimum game length in seconds.
  9. MaxGameTime: 60, // Maximum game length in minutes, only for continuous muling
  10.  
  11. SwitchKeyDelay: 300, // Seconds to wait before switching a used/banned key or after realm down
  12. FTJDelay: 180, // Seconds to wait after failing to create/join a game
  13. RealmDownDelay: 3, // Minutes to wait after getting Realm Down message
  14. UnableToConnectDelay: 1, // Minutes to wait after Unable To Connect message
  15. CDKeyInUseDelay: 1, // Minutes to wait before connecting again if CD-Key is in use.
  16. ConnectingTimeout: 20, // Seconds to wait before cancelling the 'Connecting...' screen
  17. PleaseWaitTimeout: 10, // Seconds to wait before cancelling the 'Please Wait...' screen
  18. WaitInLineTimeout: 600, // Seconds to wait before cancelling the 'Waiting in Line...' screen
  19. ExitToMenu: false, // Set to true to wait out restriction in main menu or false to wait in lobby.
  20. };
  21.  
  22.  
  23. var master, gameInfo, connectFail, makeAcc, joinInfo,
  24. muleMode, muleFilename, muleObj, handle, maxCharCount,
  25. continuousMule = false,
  26. firstLogin = true,
  27. inGame = false,
  28. makeNext = false,
  29. status = "loading",
  30. masterStatus = {
  31. status: ""
  32. };
  33.  
  34. // Mule Data object manipulates external mule datafile
  35. var MuleData = {
  36. // create a new mule datafile
  37. create: function () {
  38. var obj, string;
  39.  
  40. obj = {
  41. account: "",
  42. accNum: 0,
  43. character: "",
  44. charNum: 0,
  45. fullChars: [],
  46. torchChars: []
  47. };
  48.  
  49. string = JSON.stringify(obj);
  50.  
  51. FileTools.writeText(muleFilename, string);
  52. },
  53.  
  54. // read data from the mule datafile and return the data object
  55. read: function () {
  56. var obj, string;
  57.  
  58. string = FileTools.readText(muleFilename);
  59. obj = JSON.parse(string);
  60.  
  61. return obj;
  62. },
  63.  
  64. // write a data object to the mule datafile
  65. write: function (obj) {
  66. var string;
  67.  
  68. string = JSON.stringify(obj);
  69.  
  70. FileTools.writeText(muleFilename, string);
  71. }
  72. };
  73.  
  74. function cursorCheck() {
  75. if (getUnit(100)) {
  76. if (!isIncluded("common/Prototypes.js")) include("common/Prototypes.js");
  77. if (!isIncluded("common/Storage.js")) include("common/Storage.js");
  78.  
  79. Storage.Init();
  80.  
  81. if (!Storage.Inventory.CanFit(getUnit(100)) || !Storage.Inventory.MoveTo(getUnit(100))) {
  82. getUnit(100).drop();
  83. }
  84. }
  85.  
  86. return true;
  87. }
  88.  
  89. // stash picked items
  90. function stashItems() {
  91. var i,
  92. items = me.findItems(-1, 0, 3);
  93.  
  94. // stash large items first by sorting items by size in descending order
  95. items.sort(function(a, b) {return (b.sizex * b.sizey - a.sizex * a.sizey);});
  96.  
  97. for (i = 0; i < items.length; i += 1) {
  98. Storage.Stash.MoveTo(items[i]);
  99. }
  100.  
  101. return true;
  102. }
  103.  
  104. // pick items from ground
  105. function pickItems() {
  106. var i, items, canFit, item,
  107. rval = "fail",
  108. list = [];
  109.  
  110. while (!me.name || !me.gameReady) {
  111. if (!me.ingame) {
  112. return rval;
  113. }
  114.  
  115. delay(100);
  116. }
  117.  
  118. //delay(1000);
  119.  
  120. for (i = 0; i < 3; i += 1) {
  121. items = me.findItems(-1, 0, 3);
  122.  
  123. if (items) {
  124. break;
  125. }
  126.  
  127. delay(100);
  128. }
  129.  
  130. if (items) {
  131. for (i = 0; i < items.length; i += 1) {
  132. if (items[i].mode === 0 && items[i].location === 3 && Town.ignoredItemTypes.indexOf(items[i].itemType) > -1 // drop trash (id/tp scroll primarily)
  133. && (muleMode === 0 || items[i].classid !== 530)) { // don't drop ID scroll with torch/anni mules
  134. try {
  135. items[i].drop();
  136. } catch (dropError) {
  137. print("Failed to drop an item.");
  138. }
  139. }
  140. }
  141. }
  142.  
  143. while (me.gameReady) {
  144. if (masterStatus.status === "done" || continuousMule) {
  145. item = getUnit(4);
  146.  
  147. if (item) {
  148. do {
  149. if (getDistance(me, item) < 20 && [3, 5].indexOf(item.mode) > -1 && Town.ignoredItemTypes.indexOf(item.itemType) === -1) { // don't pick up trash
  150. list.push(copyUnit(item));
  151. }
  152. } while (item.getNext());
  153. }
  154.  
  155. // If and only if there is nothing left are we "done"
  156. if (!continuousMule && list.length === 0) {
  157. rval = "done";
  158.  
  159. break;
  160. }
  161.  
  162. // pick large items first by sorting items by size in descending order and move gheed's charm to the end of the list
  163. list.sort(function(a, b) {
  164. if (a.classid === 605 && a.quality === 7 && !Pickit.canPick(a)) {
  165. return 1;
  166. }
  167.  
  168. if (b.classid === 605 && b.quality === 7 && !Pickit.canPick(b)) {
  169. return -1;
  170. }
  171.  
  172. return (b.sizex * b.sizey - a.sizex * a.sizey);
  173. });
  174.  
  175. while (list.length > 0) {
  176. item = list.shift();
  177. canFit = Storage.Inventory.CanFit(item);
  178.  
  179. // Torch handling
  180. if (muleMode > 0 && item.classid === 604 && item.quality === 7 && !Pickit.canPick(item)) {
  181. D2Bot.printToConsole("Mule already has a Torch.", 7);
  182.  
  183. rval = "next";
  184. }
  185.  
  186. // Anni handling
  187. if (muleMode > 0 && item.classid === 603 && item.quality === 7 && !Pickit.canPick(item)) {
  188. D2Bot.printToConsole("Mule already has an Anni.", 7);
  189.  
  190. rval = "next";
  191. }
  192.  
  193. // Gheed's Fortune handling
  194. if (item.classid === 605 && item.quality === 7 && !Pickit.canPick(item)) {
  195. D2Bot.printToConsole("Mule already has Gheed's.", 7);
  196. rval = "next";
  197. }
  198.  
  199. if (!canFit) {
  200. stashItems();
  201.  
  202. canFit = Storage.Inventory.CanFit(item);
  203. }
  204.  
  205. if (canFit) {
  206. Pickit.pickItem(item);
  207.  
  208. if (muleMode > 0 && continuousMule && (item.classid === 604 || item.classid === 603)) {
  209. rval = "next";
  210. }
  211.  
  212. //if (continuousMule && list.length === 0) { // log char on last item pickup (rval done will already trigger logging, this would do it twice in a row)
  213. // MuleLogger.logChar();
  214. //}
  215. } else {
  216. rval = "next";
  217. }
  218. }
  219.  
  220. if (rval === "next" || continuousMule) {
  221. break;
  222. }
  223. } else {
  224. if (!continuousMule) {
  225. sendCopyData(null, master, 10, JSON.stringify({status: "report"}));
  226. //D2Bot.shoutGlobal("report", 0);
  227. }
  228. }
  229.  
  230. delay(500);
  231. }
  232.  
  233. return rval;
  234. }
  235.  
  236. // master/mule communication function
  237. function ReceiveCopyData(mode, msg) {
  238. var obj, masterInfo;
  239.  
  240. switch (msg) {
  241. case "Handle":
  242. handle = mode;
  243.  
  244. break;
  245. }
  246.  
  247. // mode check instead of msg check because of crashes
  248. switch (mode) {
  249. case 1: // JoinInfo
  250. //print("Got Join Info");
  251.  
  252. joinInfo = JSON.parse(msg);
  253.  
  254. break;
  255. case 2: // game info
  256. print("Recieved Game Info");
  257.  
  258. gameInfo = JSON.parse(msg);
  259.  
  260. break;
  261. case 3: // request game
  262. break;
  263. case 4:
  264. // Heartbeat ping
  265. if (msg === "pingreq") {
  266. sendCopyData(null, me.windowtitle, 4, "pingrep");
  267. }
  268.  
  269. break;
  270. // automule specific
  271. case 10: // mule request
  272. obj = JSON.parse(msg);
  273.  
  274. if (continuousMule) {
  275. if (me.ingame) {
  276. sendCopyData(null, obj.profile, 10, JSON.stringify({status: "ready"}));
  277. }
  278. } else {
  279. if (!master) {
  280. masterInfo = AutoMule.getMaster(obj);
  281.  
  282. if (masterInfo) {
  283. master = masterInfo.profile;
  284. muleMode = masterInfo.mode;
  285. }
  286. } else {
  287. if (obj.profile === master) {
  288. sendCopyData(null, master, 10, JSON.stringify({status: status}));
  289. } else {
  290. sendCopyData(null, obj.profile, 10, JSON.stringify({status: "busy"}));
  291. }
  292. }
  293. }
  294.  
  295. break;
  296. case 11: // begin item pickup
  297. status = "begin";
  298.  
  299. break;
  300. case 12: // get master's status
  301. masterStatus = JSON.parse(msg);
  302.  
  303. break;
  304. }
  305. }
  306.  
  307. // set next account - increase account number in mule datafile
  308. function nextAccount() {
  309. var obj = MuleData.read();
  310.  
  311. obj.accNum = obj.accNum + 1;
  312. obj.account = muleObj.accountPrefix + obj.accNum;
  313. obj.character = "";
  314. obj.charNum = 0;
  315. obj.fullChars = [];
  316. obj.torchChars = [];
  317.  
  318. MuleData.write(obj);
  319.  
  320. return obj.account;
  321. }
  322.  
  323. // set next character - increase character number in mule datafile
  324. function nextChar() {
  325. var i, num,
  326. charSuffix = "",
  327. charNumbers = "abcdefghijklmnopqrstuvwxyz",
  328. obj = MuleData.read();
  329.  
  330. /*if (getLocation() === 12) {
  331. obj.charNum = ControlAction.getCharacters().length;
  332. }*/
  333.  
  334. // dirty
  335. if (obj.charNum > 25) {
  336. obj.charNum = 0;
  337. }
  338.  
  339. num = obj.accNum.toString();
  340.  
  341. for (i = 0; i < num.length; i += 1) {
  342. charSuffix += charNumbers[parseInt(num[i], 10)];
  343. }
  344.  
  345. charSuffix += charNumbers[obj.charNum];
  346. obj.charNum = obj.charNum + 1;
  347. obj.character = muleObj.charPrefix + charSuffix;
  348.  
  349. MuleData.write(obj);
  350.  
  351. return obj.character;
  352. }
  353.  
  354. function locationTimeout(time, location) {
  355. var endtime = getTickCount() + time;
  356.  
  357. while (getLocation() === location && endtime > getTickCount()) {
  358. delay(500);
  359. }
  360.  
  361. return (getLocation() !== location);
  362. }
  363.  
  364. function ingameTimeout(time) {
  365. var tick = getTickCount();
  366.  
  367. while (getTickCount() - tick < time) {
  368. if (me.ingame && me.gameReady) {
  369. return true;
  370. }
  371.  
  372. if (getLocation() === 28) { // game doesn't exist, might need more locs
  373. break;
  374. }
  375.  
  376. delay(100);
  377. }
  378.  
  379. return me.ingame && me.gameReady;
  380. }
  381.  
  382. function timeoutDelay(text, time) {
  383. var endTime = getTickCount() + time;
  384.  
  385. while (getTickCount() < endTime) {
  386. D2Bot.updateStatus(text + " (" + Math.floor((endTime - getTickCount()) / 1000) + "s)");
  387. delay(500);
  388. }
  389. }
  390.  
  391. function updateCount() {
  392. D2Bot.updateCount();
  393. delay(1000);
  394. ControlAction.click(6, 264, 366, 272, 35);
  395.  
  396. var info,
  397. obj = MuleData.read();
  398.  
  399. info = {
  400. realm: muleObj.realm,
  401. account: obj.account,
  402. password: muleObj.accountPassword
  403. };
  404.  
  405. MuleLogger.save(md5(info.realm.toLowerCase() + info.account.toLowerCase()), info.password);
  406. ControlAction.loginAccount(info);
  407. delay(1000);
  408. ControlAction.click(6, 33, 572, 128, 35);
  409. }
  410.  
  411. function checkAnniTorch() {
  412. while (!me.gameReady) {
  413. delay(500);
  414. }
  415.  
  416. return me.findItem(603, 0, -1, 7) || me.findItem(604, 0, -1, 7);
  417. }
  418.  
  419. function foreverAlone() {
  420. var party = getParty();
  421.  
  422. if (party) {
  423. do {
  424. if (party.name !== me.name) {
  425. return false;
  426. }
  427. } while (party.getNext());
  428. }
  429.  
  430. return true;
  431. }
  432.  
  433. include("json2.js");
  434. include("oog.js");
  435. include("automule.js");
  436. include("mulelogger.js");
  437. include("torchsystem.js");
  438. include("NTItemParser.dbl");
  439. include("common/attack.js");
  440. include("common/storage.js");
  441. include("common/pickit.js");
  442. include("common/town.js");
  443. include("common/pather.js");
  444. include("common/misc.js");
  445. include("common/config.js");
  446. include("common/prototypes.js");
  447. include("common/collmap.js");
  448.  
  449. addEventListener("copydata", ReceiveCopyData);
  450.  
  451. function main() {
  452. while (!handle) {
  453. delay(100);
  454. }
  455.  
  456. DataFile.updateStats("handle", handle);
  457. D2Bot.init();
  458. load("tools/heartbeat.js");
  459.  
  460. while (!gameInfo) {
  461. D2Bot.requestGameInfo();
  462. delay(500);
  463. }
  464.  
  465. if (gameInfo.rdBlocker) {
  466. D2Bot.printToConsole("You must disable RD Blocker for Mule Logger to work properly. Stopping.");
  467. D2Bot.stop(me.profile, true);
  468.  
  469. return;
  470. }
  471.  
  472. D2Bot.updateRuns(); // we need the mule to swap keys somehow after all
  473. delay(1000);
  474.  
  475. continuousMule = AutoMule.isContinousMule();
  476.  
  477. if (continuousMule) {
  478. muleMode = AutoMule.getMuleMode();
  479. muleObj = AutoMule.getMuleObject(muleMode, "", true);
  480. muleFilename = AutoMule.getMuleFilename(muleMode, "", true);
  481. } else {
  482. // Wait for master before login = give room to determine muling mode (normal or torch)
  483. while (!master) {
  484. delay(100);
  485. }
  486.  
  487. print("Master found: " + master);
  488.  
  489. muleObj = AutoMule.getMuleObject(muleMode, master);
  490. muleFilename = AutoMule.getMuleFilename(muleMode, master);
  491. }
  492.  
  493. print("Mule filename: " + muleFilename);
  494.  
  495. var obj, tick, idleTick,
  496. error = 0;
  497.  
  498. try {
  499. // ugly solution to uglier problem - pickItem area update
  500. if (!FileTools.exists("data/" + me.profile + ".json")) {
  501. DataFile.create();
  502. }
  503.  
  504. // create mule datafile if it doesn't exist
  505. if (!FileTools.exists(muleFilename)) {
  506. MuleData.create();
  507. }
  508.  
  509. obj = MuleData.read();
  510.  
  511. if (obj.account && obj.account.indexOf(muleObj.accountPrefix) < 0) {
  512. MuleData.create();
  513. }
  514. } catch (e) {
  515. print("Caught exception creating data files.");
  516. print(e);
  517. D2Bot.printToConsole("DataFileException: " + e.message + " (" + e.fileName.substring(e.fileName.lastIndexOf("\\") + 1, e.fileName.length) + " #" + e.lineNumber + ")");
  518. }
  519.  
  520. while (true) {
  521. try {
  522. if (me.ingame && me.gameReady && me.inTown) {
  523. if (!inGame) {
  524. if (firstLogin) {
  525. firstLogin = false;
  526. } else {
  527. status = "begin";
  528. }
  529.  
  530. if (status !== "begin") {
  531. status = "ready";
  532. }
  533.  
  534. D2Bot.updateStatus("In " + (muleMode === 2 ? "anni " : muleMode === 1 ? "torch " : "") + "mule game.");
  535. D2Bot.printToConsole("In " + (muleMode === 2 ? "anni " : muleMode === 1 ? "torch " : "") + "mule game.", 7);
  536. tick = getTickCount();
  537. idleTick = getTickCount() + rand(1200, 1500) * 1000;
  538.  
  539. while ((getLocation() !== null || !me.area) && getTickCount() - tick < 5000) {
  540. delay(200);
  541. }
  542.  
  543. if (!me.ingame || !me.gameReady || !me.inTown) {
  544. continue;
  545. }
  546.  
  547. Town.goToTown(1);
  548. Town.move("stash");
  549. Storage.Init();
  550.  
  551. inGame = true;
  552.  
  553. if (continuousMule && !muleObj.onlyLogWhenFull) {
  554. MuleLogger.logChar();
  555. }
  556. }
  557.  
  558. while (getTickCount() - tick < 60000) {
  559. if (continuousMule) {
  560. status = "begin";
  561. }
  562.  
  563. if (status === "begin") {
  564. break;
  565. }
  566.  
  567. delay(100);
  568. }
  569.  
  570. //print("Delay: " + (getTickCount() - tick));
  571.  
  572. if (status !== "begin") {
  573. D2Bot.printToConsole("Nobody joined - stopping.", 9);
  574. D2Bot.stop(me.profile, true);
  575. }
  576.  
  577. if (!continuousMule) {
  578. me.overhead("begin");
  579. }
  580.  
  581. switch (pickItems()) {
  582. // done picking, tell the master to leave game and kill mule profile
  583. case "done":
  584. if (!muleObj.onlyLogWhenFull) MuleLogger.logChar();
  585.  
  586. obj = MuleData.read();
  587.  
  588. if (checkAnniTorch() && obj.torchChars.indexOf(me.name) === -1) {
  589. obj.torchChars.push(me.name);
  590. }
  591.  
  592. MuleData.write(obj);
  593. D2Bot.printToConsole("Done muling.", 7);
  594. sendCopyData(null, master, 10, JSON.stringify({status: "quit"}));
  595. //delay(500);
  596. D2Bot.stop(me.profile, true);
  597.  
  598. return;
  599. // can't fit more items, get to next character or account
  600. case "next":
  601. MuleLogger.logChar();
  602. delay(500);
  603.  
  604. makeNext = true;
  605. obj = MuleData.read();
  606.  
  607. if (checkAnniTorch() && obj.torchChars.indexOf(me.name) === -1) {
  608. obj.torchChars.push(me.name);
  609. }
  610.  
  611. obj.fullChars.push(me.name);
  612. MuleData.write(obj);
  613. nextChar();
  614. D2Bot.printToConsole("Mule full, getting next character.", 7);
  615.  
  616. if (StarterConfig.MinGameTime && getTickCount() - tick < StarterConfig.MinGameTime * 1000) {
  617. while (getTickCount() - tick < StarterConfig.MinGameTime * 1000) {
  618. me.overhead("Stalling for " + Math.round(((tick + (StarterConfig.MinGameTime * 1000)) - getTickCount()) / 1000) + " Seconds");
  619. delay(1000);
  620. }
  621. }
  622.  
  623. cursorCheck();
  624. D2Bot.restart();
  625. //quit();
  626.  
  627. // TODO: see whether a for loop is better
  628. while (me.ingame) {
  629. delay(100);
  630. }
  631.  
  632. break;
  633. case "fail":
  634. // Try again
  635. break;
  636. }
  637.  
  638. if (continuousMule) {
  639. delay(5000); // pick items every 5s
  640.  
  641. if (StarterConfig.MaxGameTime && getTickCount() - tick > StarterConfig.MaxGameTime * 1000 * 60 && foreverAlone()) {
  642. cursorCheck();
  643. quit();
  644.  
  645. while (me.ingame) {
  646. delay(100);
  647. }
  648.  
  649. firstLogin = true;
  650. print("updating runs");
  651. D2Bot.updateRuns();
  652. status = "ready";
  653. inGame = false;
  654.  
  655. delay(1000);
  656. ControlAction.click(6, 693, 490, 80, 20); // Quit from Lobby
  657. timeoutDelay("Refresh game", 330 * 1000); // 5.5 minutes
  658.  
  659. continue;
  660. }
  661. }
  662.  
  663. if (getTickCount() - idleTick > 0) { // anti-idle
  664. sendPacket(1, 0x40);
  665. idleTick += rand(1200, 1500) * 1000;
  666. }
  667. }
  668.  
  669. if (!me.ingame) {
  670. delay(1000);
  671. locationAction(getLocation());
  672. }
  673. } catch (e2) {
  674. showConsole();
  675. error++;
  676. print("Caught an exception in the main loop.");
  677. print(e2);
  678. D2Bot.printToConsole("MainLoopException: " + e2.message + " (" + e2.fileName.substring(e2.fileName.lastIndexOf("\\") + 1, e2.fileName.length) + " #" + e2.lineNumber + ")");
  679.  
  680. var scripts = "Scripts : ";
  681. var script = getScript();
  682.  
  683. if (script) {
  684. do {
  685. scripts += script.name + " ";
  686. } while (script.getNext())
  687. }
  688.  
  689. D2Bot.printToConsole(scripts);
  690. takeScreenshot();
  691.  
  692. if (error > 3) {
  693. print("Too many errors, restarting...");
  694. D2Bot.restart();
  695. }
  696.  
  697. delay(5000);
  698. }
  699.  
  700. delay(100);
  701. }
  702. }
  703.  
  704. function locationAction(location) {
  705. var i, obj, info, control, string, text, queue;
  706.  
  707. MainSwitch:
  708. switch (location) {
  709. case 0:
  710. ControlAction.click();
  711.  
  712. break;
  713. case 1:
  714. case 3:
  715. D2Bot.updateStatus("Lobby");
  716.  
  717. if (inGame) {
  718. print("updating runs");
  719. D2Bot.updateRuns();
  720. status = "ready";
  721. inGame = false;
  722. }
  723.  
  724. if (makeNext) {
  725. ControlAction.click(6, 693, 490, 80, 20);
  726.  
  727. break;
  728. }
  729.  
  730. if (!ControlAction.click(6, 652, 469, 120, 20)) { // Join
  731. break;
  732. }
  733.  
  734. if (!locationTimeout(5000, location)) { // in case join button gets bugged
  735. if (!ControlAction.click(6, 533, 469, 120, 20)) { // Create
  736. break;
  737. }
  738.  
  739. if (!ControlAction.click(6, 652, 469, 120, 20)) { // Join
  740. break;
  741. }
  742. }
  743.  
  744. break;
  745. case 4: // Create Game
  746. D2Bot.updateStatus("Creating Game");
  747.  
  748. control = getControl(1, 657, 342, 27, 20);
  749.  
  750. if (control && control.disabled === 5) {
  751. ControlAction.click(6, 431, 341, 15, 16); // remove level restriction
  752. }
  753.  
  754. delay(2000);
  755.  
  756. // FTJ handler
  757. if (status === "pending") {
  758. D2Bot.printToConsole("Failed to create game");
  759. ControlAction.timeoutDelay("FTJ delay", StarterConfig.FTJDelay * 1e3);
  760. D2Bot.updateRuns();
  761. }
  762.  
  763. createGame(muleObj.muleGameName[0], muleObj.muleGameName[1]);
  764. ingameTimeout(5000);
  765.  
  766. status = "pending";
  767.  
  768. break;
  769. case 2: // Waiting In Line
  770. string = "";
  771. text = ControlAction.getText(4, 427, 234, 300, 100);
  772.  
  773. if (text) {
  774. string = text[3].split("c0")[1].replace(/\s+/g, '');
  775. queue = parseInt(string);
  776.  
  777. if (queue > 0) {
  778. if (queue < 2000) { // Wait out short queue
  779. D2Bot.updateStatus("Waiting line... Queue: " + queue);
  780.  
  781. if (queue < 10) { // If stuck here for too long, game creation likely failed. Exit to char selection and try again.
  782. if (!locationTimeout(StarterConfig.WaitInLineTimeout * 1e3, location)) {
  783. print("Failed to create game");
  784. ControlAction.click(6, 433, 433, 96, 32); // Cancel creategame
  785. ControlAction.click(6, 693, 490, 80, 20); // Quit from Lobby
  786. delay(1000);
  787. }
  788. }
  789. } else if (queue > 20000) { // stop bot if queue is too long
  790. D2Bot.printToConsole("Restricted... Stopping bot. Queue: " + queue, 9);
  791. D2Bot.stop(me.profile, true);
  792. } else {
  793. print("Restricted... Queue: " + queue);
  794. D2Bot.printToConsole("Restricted... Queue: " + queue, 9);
  795. ControlAction.click(6, 433, 433, 96, 32); // Cancel creategame
  796.  
  797. if (StarterConfig.ExitToMenu) { // Exit to menu
  798. ControlAction.click(6, 693, 490, 80, 20); // Quit from Lobby
  799. delay(1000);
  800. ControlAction.click(6, 33, 572, 128, 35); // Quit from char selection
  801. }
  802.  
  803. ControlAction.timeoutDelay("Restricted", (queue + 600) * 1000); // Wait out each queue as 1 sec and add extra 10 min
  804. }
  805. }
  806. }
  807.  
  808. break;
  809. case 5: // Join Game
  810. D2Bot.updateStatus("Join Game");
  811.  
  812. if (status === "pending") {
  813. D2Bot.printToConsole("Failed to join game");
  814. ControlAction.timeoutDelay("Join Delay", StarterConfig.FTJDelay * 1000);
  815. D2Bot.updateRuns();
  816. }
  817.  
  818. if (!continuousMule) {
  819. D2Bot.requestGame(master);
  820. delay(100);
  821. }
  822.  
  823. delay(2000);
  824.  
  825. if (joinInfo && joinInfo.gameName !== "" && joinInfo.inGame) {
  826. joinGame(joinInfo.gameName, joinInfo.gamePass);
  827. } else {
  828. joinGame(muleObj.muleGameName[0], muleObj.muleGameName[1]);
  829. }
  830.  
  831. if (!firstLogin) {
  832. status = "pending";
  833. }
  834.  
  835. ingameTimeout(5000);
  836. print("Ingame timeout done.");
  837.  
  838. if (getLocation() === 1 && !me.ingame) { // could not join game
  839. ControlAction.click(6, 533, 469, 120, 20); // create game
  840. }
  841.  
  842. break;
  843. case 6: // Ladder
  844. break;
  845. case 7: // Channel List
  846. break;
  847. case 8: // menu
  848. case 9: // login
  849. if (makeNext) {
  850. makeNext = false;
  851. }
  852.  
  853. obj = MuleData.read();
  854.  
  855. if (!obj.account || obj.account.indexOf(muleObj.accountPrefix) < 0) {
  856. nextAccount();
  857.  
  858. obj = MuleData.read();
  859. }
  860.  
  861. info = {
  862. realm: muleObj.realm,
  863. account: obj.account,
  864. password: muleObj.accountPassword
  865. };
  866.  
  867. if (makeAcc) {
  868. ControlAction.makeAccount(info);
  869. //FileTools.writeText("mules/" + info.account + ".txt", "");
  870. D2Bot.printToConsole("Made account: " + info.account, 7);
  871.  
  872. makeAcc = false;
  873.  
  874. break;
  875. }
  876.  
  877. MuleLogger.save(md5(info.realm.toLowerCase() + info.account.toLowerCase()), info.password);
  878. ControlAction.loginAccount(info);
  879.  
  880. break;
  881. case 10: // Login Error
  882. string = "";
  883. text = ControlAction.getText(4, 199, 377, 402, 140);
  884.  
  885. if (text) {
  886. for (i = 0; i < text.length; i += 1) {
  887. string += text[i];
  888.  
  889. if (i !== text.length - 1) {
  890. string += " ";
  891. }
  892. }
  893.  
  894. switch (string) {
  895. case getLocaleString(5207):
  896. D2Bot.updateStatus("Invalid Password");
  897. D2Bot.printToConsole("Invalid Password");
  898.  
  899. break;
  900. case getLocaleString(5208):
  901. ControlAction.click(6, 335, 412, 128, 35);
  902.  
  903. makeAcc = true;
  904.  
  905. break MainSwitch;
  906. case getLocaleString(5202): // cd key intended for another product
  907. case getLocaleString(10915): // lod key intended for another product
  908. D2Bot.updateStatus("Invalid CDKey");
  909. D2Bot.printToConsole("Invalid CDKey: " + gameInfo.mpq, 6);
  910. D2Bot.CDKeyDisabled();
  911.  
  912. if (gameInfo.switchKeys) {
  913. ControlAction.timeoutDelay("Key switch delay", StarterConfig.SwitchKeyDelay * 1000);
  914. D2Bot.restart(true);
  915. } else {
  916. D2Bot.stop(me.profile, true);
  917. }
  918.  
  919. break;
  920. case getLocaleString(5199):
  921. D2Bot.updateStatus("Disabled CDKey");
  922. D2Bot.printToConsole("Disabled CDKey: " + gameInfo.mpq, 6);
  923. D2Bot.CDKeyDisabled();
  924.  
  925. if (gameInfo.switchKeys) {
  926. ControlAction.timeoutDelay("Key switch delay", StarterConfig.SwitchKeyDelay * 1000);
  927. D2Bot.restart(true);
  928. } else {
  929. D2Bot.stop(me.profile, true);
  930. }
  931.  
  932. break;
  933. case getLocaleString(10913):
  934. D2Bot.updateStatus("Disabled LoD CDKey");
  935. D2Bot.printToConsole("Disabled LoD CDKey: " + gameInfo.mpq, 6);
  936. D2Bot.CDKeyDisabled();
  937.  
  938. if (gameInfo.switchKeys) {
  939. ControlAction.timeoutDelay("Key switch delay", StarterConfig.SwitchKeyDelay * 1000);
  940. D2Bot.restart(true);
  941. } else {
  942. D2Bot.stop(me.profile, true);
  943. }
  944.  
  945. break;
  946. case getLocaleString(5347):
  947. D2Bot.updateStatus("Disconnected");
  948. D2Bot.printToConsole("Disconnected");
  949. ControlAction.click(6, 335, 412, 128, 35);
  950.  
  951. break MainSwitch;
  952. default:
  953. D2Bot.updateStatus("Login Error");
  954. D2Bot.printToConsole("Login Error - " + string);
  955.  
  956. if (gameInfo.switchKeys) {
  957. ControlAction.timeoutDelay("Key switch delay", StarterConfig.SwitchKeyDelay * 1000);
  958. D2Bot.restart(true);
  959. } else {
  960. D2Bot.stop(me.profile, true);
  961. }
  962.  
  963. break;
  964. }
  965. }
  966.  
  967. ControlAction.click(6, 335, 412, 128, 35);
  968.  
  969. while (true) {
  970. delay(1000);
  971. }
  972.  
  973. break;
  974. case 11: // Unable To Connect
  975. D2Bot.updateStatus("Unable To Connect");
  976.  
  977. if (connectFail) {
  978. timeoutDelay("Unable to Connect", StarterConfig.UnableToConnectDelay * 6e4);
  979.  
  980. connectFail = false;
  981. }
  982.  
  983. if (!ControlAction.click(6, 335, 450, 128, 35)) {
  984. break;
  985. }
  986.  
  987. connectFail = true;
  988.  
  989. break;
  990. case 13: // Realm Down - Character Select screen
  991. D2Bot.updateStatus("Realm Down");
  992. delay(1000);
  993.  
  994. if (!ControlAction.click(6, 33, 572, 128, 35)) {
  995. break;
  996. }
  997.  
  998. updateCount();
  999. timeoutDelay("Realm Down", StarterConfig.RealmDownDelay * 6e4);
  1000. D2Bot.CDKeyRD();
  1001.  
  1002. if (gameInfo.switchKeys) {
  1003. D2Bot.printToConsole("Realm Down - Changing CD-Key");
  1004. timeoutDelay("Key switch delay", StarterConfig.SwitchKeyDelay * 1000);
  1005. D2Bot.restart(true);
  1006. } else {
  1007. D2Bot.restart();
  1008. }
  1009.  
  1010. break;
  1011. case 14: // Character Select / Main Menu - Disconnected
  1012. D2Bot.updateStatus("Disconnected");
  1013. delay(500);
  1014. ControlAction.click(6, 351, 337, 96, 32);
  1015.  
  1016. break;
  1017. case 18: // splash
  1018. case 12: // char select
  1019. case 15: // new character (selected)
  1020. case 29: // new character (list)
  1021. case 42: // empty char screen
  1022. // Single Player screen fix
  1023. if (getLocation() === 12 && !getControl(4, 626, 100, 151, 44)) {
  1024. ControlAction.click(6, 33, 572, 128, 35);
  1025.  
  1026. break;
  1027. }
  1028.  
  1029. string = "";
  1030. text = ControlAction.getText(4, 45, 318, 531, 140);
  1031.  
  1032. if (text) {
  1033. for (i = 0; i < text.length; i += 1) {
  1034. string += text[i];
  1035.  
  1036. if (i !== text.length - 1) {
  1037. string += " ";
  1038. }
  1039. }
  1040.  
  1041. if (string === getLocaleString(11161)) { // CDKey disabled from realm play
  1042. D2Bot.updateStatus("Realm Disabled CDKey");
  1043. D2Bot.printToConsole("Realm Disabled CDKey: " + gameInfo.mpq, 6);
  1044. D2Bot.CDKeyDisabled();
  1045.  
  1046. if (gameInfo.switchKeys) {
  1047. ControlAction.timeoutDelay("Key switch delay", StarterConfig.SwitchKeyDelay * 1000);
  1048. D2Bot.restart(true);
  1049. } else {
  1050. D2Bot.stop(me.profile, true);
  1051. }
  1052. }
  1053. }
  1054.  
  1055. // Single Player screen fix
  1056. // TODO: see if this is still needed. d2bs doesn't load scripts twice anymore
  1057. if (getLocation() === 12 && !getControl(4, 626, 100, 151, 44)) {
  1058. ControlAction.click(6, 33, 572, 128, 35);
  1059.  
  1060. break;
  1061. }
  1062.  
  1063. // Can't create character, button greyed out = high likelyhood of realm down
  1064. if (getLocation() === 42 && getControl(6, 33, 528, 168, 60).disabled === 4) {
  1065. D2Bot.updateStatus("Realm Down");
  1066. delay(1000);
  1067.  
  1068. if (!ControlAction.click(6, 33, 572, 128, 35)) {
  1069. break;
  1070. }
  1071.  
  1072. updateCount();
  1073. timeoutDelay("Realm Down", StarterConfig.RealmDownDelay * 6e4);
  1074. D2Bot.CDKeyRD();
  1075.  
  1076. if (gameInfo.switchKeys) {
  1077. D2Bot.printToConsole("Realm Down - Changing CD-Key");
  1078. timeoutDelay("Key switch delay", StarterConfig.SwitchKeyDelay * 1000);
  1079. D2Bot.restart(true);
  1080. } else {
  1081. D2Bot.restart();
  1082. }
  1083. }
  1084.  
  1085. obj = MuleData.read();
  1086. maxCharCount = (muleObj.charsPerAcc > 0 ? Math.min(muleObj.charsPerAcc, 18) : 8);
  1087.  
  1088. if (makeNext) {
  1089. if (obj.fullChars.length >= maxCharCount || (muleMode > 0 && obj.torchChars.length >= maxCharCount)) {
  1090.  
  1091. try{
  1092. obj = MuleData.read();
  1093. info = {
  1094. realm: muleObj.realm,
  1095. account: obj.account,
  1096. password: muleObj.accountPassword
  1097. };
  1098. if (!FileTools.exists("PermIt/AddedAccounts.txt")) {
  1099. DataFile.create();
  1100. }
  1101. FileTools.appendText("PermIt/Accounts.txt", me.realm.toLowerCase() + "/" + info.account.toLowerCase() + "/" + muleObj.accountPassword + "\n");
  1102. FileTools.appendText("PermIt/AddedAccounts.txt", me.realm.toLowerCase() + "/" + info.account.toLowerCase() + "/" + muleObj.accountPassword + "\n");
  1103. FileTools.appendText("PermIt/AccountsToLog.txt", me.realm.toLowerCase() + "/" + info.account.toLowerCase() + "/" + muleObj.accountPassword + "\n");
  1104. D2Bot.printToConsole("Added Mule Account: " + info.account.toLowerCase() + " to PermIt", 7);
  1105. }catch(e){
  1106. if (!FileTools.exists("PermIt/FailedAccounts.txt")) {
  1107. DataFile.create();
  1108. }
  1109. FileTools.appendText("PermIt/FailedAccounts.txt", info.account.toLowerCase() + "\n");
  1110. D2Bot.printToConsole("Failed to add mule account: " + info.account.toLowerCase() + "to PermIt", 9);
  1111. }
  1112.  
  1113. ControlAction.click(6, 33, 572, 128, 35);
  1114. nextAccount();
  1115.  
  1116. break;
  1117. }
  1118.  
  1119. makeNext = false;
  1120. }
  1121.  
  1122. if (!obj.character || obj.character.indexOf(muleObj.charPrefix) < 0) {
  1123. nextChar();
  1124.  
  1125. obj = MuleData.read();
  1126. }
  1127.  
  1128. info = {
  1129. account: obj.account,
  1130. charName: obj.character,
  1131. ladder: muleObj.ladder,
  1132. hardcore: muleObj.hardcore,
  1133. expansion: muleObj.expansion,
  1134. charClass: "amazon"
  1135. };
  1136.  
  1137. if (muleMode > 0 && obj.torchChars.indexOf(info.charName) > -1) {
  1138. nextChar();
  1139.  
  1140. break;
  1141. }
  1142.  
  1143. if (me.realm.toLowerCase() !== muleObj.realm) {
  1144. D2Bot.restart();
  1145. }
  1146.  
  1147. if (ControlAction.findCharacter(info)) {
  1148. ControlAction.loginCharacter(info, false);
  1149. } else {
  1150. if (ControlAction.getCharacters().length >= maxCharCount) { // premade account that's already full
  1151.  
  1152. try{
  1153. obj = MuleData.read();
  1154. info = {
  1155. realm: muleObj.realm,
  1156. account: obj.account,
  1157. password: muleObj.accountPassword
  1158. };
  1159. if (!FileTools.exists("PermIt/AddedAccounts.txt")) {
  1160. DataFile.create();
  1161. }
  1162. FileTools.appendText("PermIt/Accounts.txt", me.realm.toLowerCase() + "/" + info.account.toLowerCase() + "/" + muleObj.accountPassword + "\n");
  1163. FileTools.appendText("PermIt/AddedAccounts.txt", me.realm.toLowerCase() + "/" + info.account.toLowerCase() + "/" + muleObj.accountPassword + "\n");
  1164. D2Bot.printToConsole("Added Mule Account: " + info.account.toLowerCase() + " to PermIt", 7);
  1165. }catch(e){
  1166. if (!FileTools.exists("PermIt/FailedAccounts.txt")) {
  1167. DataFile.create();
  1168. }
  1169. FileTools.appendText("PermIt/FailedAccounts.txt", info.account.toLowerCase() + "\n");
  1170. D2Bot.printToConsole("Failed to add Mule Account: " + info.account.toLowerCase() + "to PermIt", 9);
  1171. }
  1172.  
  1173. ControlAction.click(6, 33, 572, 128, 35);
  1174. nextAccount();
  1175.  
  1176. break;
  1177. }
  1178.  
  1179. if (!ControlAction.makeCharacter(info)) {
  1180. // TODO: check if acc is full and cancel location 15 and 29 if true
  1181. nextChar();
  1182.  
  1183. break;
  1184. }
  1185.  
  1186. FileTools.appendText("logs/" + me.profile + ".charlist.txt", info.account + "/" + info.charName + '\n');
  1187. D2Bot.printToConsole("Made character: " + info.charName, 7);
  1188. }
  1189.  
  1190. break;
  1191. case 16: // Character Select - Please Wait popup
  1192. if (!locationTimeout(StarterConfig.PleaseWaitTimeout * 1e3, location)) {
  1193. ControlAction.click(6, 351, 337, 96, 32);
  1194. }
  1195.  
  1196. break;
  1197. case 17: // Lobby - Lost Connection - just click okay, since we're toast anyway
  1198. delay(1000);
  1199. ControlAction.click(6, 351, 337, 96, 32);
  1200.  
  1201. break;
  1202. case 19: // Login - Cdkey In Use
  1203. D2Bot.printToConsole(gameInfo.mpq + " is in use by " + ControlAction.getText(4, 158, 310, 485, 40), 6);
  1204. D2Bot.CDKeyInUse();
  1205.  
  1206. if (gameInfo.switchKeys) {
  1207. ControlAction.timeoutDelay("Key switch delay", StarterConfig.SwitchKeyDelay * 1000);
  1208. D2Bot.restart(true);
  1209. } else {
  1210. ControlAction.click(6, 335, 450, 128, 35);
  1211. ControlAction.timeoutDelay("CD-Key in use", StarterConfig.CDKeyInUseDelay * 6e4);
  1212. }
  1213.  
  1214. break;
  1215. case 20: // Single Player - Select Difficulty
  1216. break;
  1217. case 21: // Main Menu - Connecting
  1218. if (!locationTimeout(StarterConfig.ConnectingTimeout * 1e3, location)) {
  1219. ControlAction.click(6, 330, 416, 128, 35);
  1220. }
  1221.  
  1222. break;
  1223. case 22: // Login - Invalid Cdkey (classic or xpac)
  1224. text = ControlAction.getText(4, 162, 270, 477, 50);
  1225. string = "";
  1226.  
  1227. if (text) {
  1228. for (i = 0; i < text.length; i += 1) {
  1229. string += text[i];
  1230.  
  1231. if (i !== text.length - 1) {
  1232. string += " ";
  1233. }
  1234. }
  1235. }
  1236.  
  1237. switch (string) {
  1238. case getLocaleString(10914):
  1239. D2Bot.printToConsole(gameInfo.mpq + " LoD key in use by " + ControlAction.getText(4, 158, 310, 485, 40), 6);
  1240. D2Bot.CDKeyInUse();
  1241.  
  1242. if (gameInfo.switchKeys) {
  1243. ControlAction.timeoutDelay("Key switch delay", StarterConfig.SwitchKeyDelay * 1000);
  1244. D2Bot.restart(true);
  1245. } else {
  1246. ControlAction.click(6, 335, 450, 128, 35);
  1247. ControlAction.timeoutDelay("LoD key in use", StarterConfig.CDKeyInUseDelay * 6e4);
  1248. }
  1249.  
  1250. break;
  1251. default:
  1252. if (gameInfo.switchKeys) {
  1253. D2Bot.printToConsole("Invalid CD-Key");
  1254. ControlAction.timeoutDelay("Key switch delay", StarterConfig.SwitchKeyDelay * 1000);
  1255. D2Bot.restart(true);
  1256. } else {
  1257. ControlAction.click(6, 335, 450, 128, 35);
  1258. ControlAction.timeoutDelay("Invalid CD-Key", StarterConfig.CDKeyInUseDelay * 6e4);
  1259. }
  1260.  
  1261. break;
  1262. }
  1263.  
  1264. break;
  1265. case 23: // Character Select - Connecting
  1266. if (!locationTimeout(StarterConfig.ConnectingTimeout * 1e3, location)) {
  1267. ControlAction.click(6, 33, 528, 168, 60); //Click create char button on infinite "connecting" screen
  1268. delay(1000);
  1269.  
  1270. ControlAction.click(6, 33, 572, 128, 35); //Click exit
  1271. delay(1000);
  1272.  
  1273. if (getLocation() !== 23) {
  1274. break;
  1275. }
  1276.  
  1277. ControlAction.click(6, 33, 572, 128, 35);
  1278. }
  1279.  
  1280. break;
  1281. case 24: // Server Down - not much to do but wait..
  1282. break;
  1283. case 25: // Lobby - Please Wait
  1284. if (!locationTimeout(StarterConfig.PleaseWaitTimeout * 1e3, location)) {
  1285. ControlAction.click(6, 351, 337, 96, 32);
  1286. }
  1287.  
  1288. break;
  1289. case 26: // game already exists
  1290. ControlAction.click(6, 652, 469, 120, 20); // Join
  1291.  
  1292. break;
  1293. case 27: // Gateway Select
  1294. ControlAction.click(6, 436, 538, 96, 32);
  1295.  
  1296. break;
  1297. case 28: // Lobby - Game Does Not Exist
  1298. ControlAction.click(6, 533, 469, 120, 20);
  1299.  
  1300. break;
  1301. case 30: // charname already exists
  1302. ControlAction.click(6, 351, 337, 96, 32);
  1303. ControlAction.click(6, 33, 572, 128, 35);
  1304.  
  1305. break;
  1306. case 34: // Email registration
  1307. if (getControl(6, 415, 412, 128, 35)) {
  1308. ControlAction.click(6, 415, 412, 128, 35);
  1309. } else {
  1310. ControlAction.click(6, 265, 572, 272, 35);
  1311. }
  1312. break;
  1313. case 38: // Game is full
  1314. break; // not sure how/if to handle
  1315. }
  1316. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement