BRDTS_AutoKeyboardScript

新版BR大逃杀全键盘操作脚本

  1. // ==UserScript==
  2. // @name BRDTS_AutoKeyboardScript
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.01
  5. // @description 新版BR大逃杀全键盘操作脚本
  6. // @author f1stSea
  7. // @compatible chrome
  8. // @compatible firefox
  9. // @license GNU
  10. // @match http://s2.dtsgame.com/game.php
  11. // @match http://s1.dtsgame.com/game.php
  12. // @require http://code.jquery.com/jquery-1.11.0.min.js
  13. // @grant none
  14. // ==/UserScript==
  15. (function() {
  16. 'use strict';
  17. // 全局变量
  18. // 脚本整体开启/关闭
  19. var isScriptEnabled = true;
  20. // 自动搜刮战利品
  21. var autoSpoil = false;
  22.  
  23. // 初始化
  24. var run = function() {
  25. initSettingsBox();
  26. }
  27.  
  28. function initSettingsBox() {
  29. // 寻找主界面
  30. var mainBox;
  31. if ($("td[rowspan='2']").length > 0) {
  32. mainBox = $("td[rowspan='2']").parent();
  33. }
  34.  
  35. // 创建脚本展示框
  36. var content = $('<td>').attr('rowspan', '2').appendTo(mainBox);
  37. var table = $('<table>')
  38. .attr('border', '1')
  39. .attr('width', '250')
  40. .attr('height', '550')
  41. .attr('cellspacing', '0')
  42. .attr('cellpadding', '0')
  43. .appendTo(content);
  44. var tbody = $('<tbody>').appendTo(table);
  45. var tr = $('<tr>').appendTo(tbody);
  46. var td = $('<td>')
  47. .attr('valign', 'top')
  48. .addClass('b3')
  49. .css('text-align', 'left')
  50. .appendTo(tr);
  51. var div = $('<div>').attr('id', 'log').appendTo(td);
  52. var span = $('<span>')
  53. .addClass('yellow b')
  54. .css('letter-spacing', '2px')
  55. .appendTo(div);
  56.  
  57. // 主按钮及描述
  58. appendBaseCheckBox(span);
  59.  
  60. // 自动搜刮
  61. appendAutoSpoilCheckBox(span);
  62.  
  63. }
  64.  
  65. function appendBaseCheckBox(span) {
  66. // 添加描述文本到 span 中
  67. span.append('启用脚本: ');
  68.  
  69. // 添加勾选框到 span 中
  70. var checkbox = $('<input>')
  71. .attr('type', 'checkbox')
  72. .appendTo(span);
  73. checkbox.prop('checked', isScriptEnabled);
  74.  
  75. // 键盘监控器
  76. var handleKeyDown;
  77. // 定时器
  78. var timer;
  79. if (isScriptEnabled) {
  80. handleKeyDown = startListenKeyboard();
  81. timer = updateTimer(timer, 100);
  82. }
  83.  
  84. // 监听勾选框的改变事件
  85. checkbox.on('change', function() {
  86. if ($(this).prop('checked')) {
  87. // 开始监听键盘事件
  88. handleKeyDown = startListenKeyboard();
  89. timer = updateTimer(timer, 100);
  90. } else if (handleKeyDown) {
  91. // 停止监听键盘事件
  92. window.removeEventListener('keydown', handleKeyDown);
  93. timer = updateTimer(timer, 0);
  94. }
  95. });
  96.  
  97. // 添加描述文本到 span 中
  98. span.append(
  99. '<br/><br/>' +
  100. '基础功能快捷键:<br/>' +
  101. '确认--空格<br/>' +
  102. '探索--q<br/>' +
  103. '自动拾取开启/关闭--TAB<br/><br/>' +
  104. '移动:<br/>' +
  105. '灯塔--1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;源二郎池--2<br/>' +
  106. '消防署--3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;观音堂--4<br/>' +
  107. '清水池--5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;森林地带--6<br/>' +
  108. '诊所--7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;隧道--8<br/><br/>'
  109. );
  110. }
  111.  
  112. // 更新定时器
  113. function updateTimer(timer, interval) {
  114. if (timer !== null) {
  115. clearInterval(timer);
  116. timer = null;
  117. }
  118. if (interval > 0) {
  119. timer = setInterval(confirm, interval);
  120. }
  121. return timer;
  122. }
  123.  
  124. function startListenKeyboard() {
  125. var handleKeyDown = function(e) {
  126. if (document.activeElement.type == 'text' || document.activeElement.type == 'password' || e.metaKey || e.ctrlKey || e.target.isContentEditable || document.designMode === "on") {
  127. console.log('block key:' + e.e.keyCode);
  128. return;
  129. }
  130. if (listenKeyboardMap[e.keyCode]) {
  131. console.log('active key:' + e.keyCode);
  132. //触发映射
  133. listenKeyboardMap[e.keyCode]();
  134. //无效化按键原来的效果
  135. e.preventDefault();
  136. e.stopPropagation();
  137. } else {
  138. console.log('useless key:' + e.keyCode);
  139. return;
  140. }
  141. };
  142. window.addEventListener('keydown', handleKeyDown, false);
  143. return handleKeyDown;
  144. }
  145. var listenKeyboardMap = {
  146. // 空格:32 确认
  147. '32': function() {
  148. confirm();
  149. },
  150. // 1:49 移动到灯塔
  151. '49': function() {
  152. moveTo(20);
  153. },
  154. // 2:50 移动到源二郎池
  155. '50': function() {
  156. moveTo(17);
  157. },
  158. // 3:51 移动到消防署
  159. '51': function() {
  160. moveTo(5);
  161. },
  162. // 4:52 移动到观音堂
  163. '52': function() {
  164. moveTo(6);
  165. },
  166. // 5:53 移动到清水池
  167. '53': function() {
  168. moveTo(7);
  169. },
  170. // 6:54 移动到森林地带
  171. '54': function() {
  172. moveTo(16);
  173. },
  174. // 7:55 移动到诊所
  175. '55': function() {
  176. moveTo(19);
  177. },
  178. // 8:56 移动到隧道
  179. '56': function() {
  180. moveTo(11);
  181. },
  182. // q:81 探索
  183. '81': function() {
  184. pressButtonIfExist("探索");
  185. },
  186. // TAB:9 开启/关闭自动拾取
  187. '9': function() {
  188. dontSpoil = !dontSpoil;
  189. },
  190. };
  191.  
  192. function appendAutoSpoilCheckBox(span) {
  193. // 添加描述文本到 span 中
  194. span.append('自动搜刮战利品: ');
  195.  
  196. // 添加勾选框到 span 中
  197. var checkbox = $('<input>')
  198. .attr('type', 'checkbox')
  199. .appendTo(span);
  200. checkbox.prop('checked', autoSpoil);
  201.  
  202. // 监听勾选框的改变事件
  203. checkbox.on('change', function() {
  204. autoSpoil = $(this).prop('checked');
  205. });
  206.  
  207. // 添加描述文本到 span 中
  208. span.append(
  209. '<br/>搜刮且仅搜刮金钱、罐头与徽章<br/>'
  210. );
  211. };
  212.  
  213. function confirm() {
  214. // 合并
  215. if (checkMerge()) {
  216. return;
  217. }
  218. // 无需额外判断直接确认的按钮
  219. if (pressButtonIfExist()) {
  220. return;
  221. }
  222.  
  223. // 拾取按钮
  224. if (checkPickup()) {
  225. return;
  226. }
  227. // 搜刮尸体有价值部分,无价值部分可自行搜刮,或者快速移动直接离开
  228. if (checkSpoil()) {
  229. return;
  230. }
  231. }
  232.  
  233. function checkMerge() {
  234. // 可拾取物品
  235. var $inputElement = $('input[type="button"].postbutton[value="确定"]');
  236. var pageText = $("#cmd").text();
  237. if ($inputElement.length > 0 && pageText.includes("合并")) {
  238. sl("itm0");
  239. sl("itm1");
  240. sl("itm2");
  241. sl("itm3");
  242. sl("itm4");
  243. $inputElement.click();
  244. return true;
  245. }
  246. // 不存在该标签
  247. return false;
  248. }
  249.  
  250. function pressButtonIfExist(value) {
  251. var directConfirmList = ["确定", "提交", "斩刺\\(斩\\)", "投掷\\(投\\)", "射击\\(射\\)"];
  252. if (value) {
  253. directConfirmList = [value];
  254. }
  255. for (var i = 0; i < directConfirmList.length; i++) {
  256. var $inputElement = $('input[type="button"].postbutton[value=' + directConfirmList[i] + ']');
  257. if ($inputElement.length > 0) {
  258. // 存在该标签,触发点击事件
  259. $inputElement.click();
  260. return true;
  261. }
  262. }
  263. // 不存在该标签
  264. return false;
  265. }
  266.  
  267. function checkPickup() {
  268. // 可拾取物品
  269. var pickupItemSet = new Set([
  270. "杂炊", "松茸", "香菇", "蘑菇", "树枝", "面", "炖肉", " 冰",
  271. "水", "牛奶", "苹果", "清涼饮料", "蔬菜汁",
  272. "强壮剂", "中药", "特效药", "疗伤药", "针筒", "牛奶",
  273. "瑞士刀", "力场", "之盾", "RoseMystica", "胴具足", "针线包",
  274. // "磨刀石", "废金属",
  275. // "手机","电脑",
  276. // "投","绷带",
  277. // "子弹","废金属","钢琴线","铁管",
  278. ]);
  279. needArmor(pickupItemSet);
  280. var $pickupElement = $('input[type="button"].postbutton[value="拾取"]');
  281. var $drupElement = $('input[type="button"].postbutton[value="丢弃"]');
  282. if ($pickupElement.length > 0 && $drupElement.length > 0) {
  283. // 存在该标签,判断是否是目标物品
  284. var pageText = $("#cmd").text();
  285. // 遍历目标字,判断是否存在
  286. var have = false;
  287. pickupItemSet.forEach(function(item) {
  288. if (pageText.includes(item)) {
  289. have = true;
  290. return true;
  291. }
  292. });
  293. have ? $pickupElement.click() : $drupElement.click();
  294. return true;
  295. } else {
  296. return false;
  297. }
  298. }
  299. // 没有防具会拾取对应防具,有的话就不拾取了,高价值防具在默认拾取列表,不在此列
  300. function needArmor(pickupItemSet) {
  301. var need = false;
  302. var targetTdElement = $("#main");
  303. if (!pickupItemSet) {
  304. pickupItemSet = new Set();
  305. }
  306. if (targetTdElement.text().includes("【防具(体)】\n无")) {
  307. // console.log("没有【防具(体)】");
  308. need = true;
  309. pickupItemSet.add("体");
  310. }
  311. if (targetTdElement.text().includes("【防具(头)】\n无")) {
  312. // console.log("没有【防具(头)】");
  313. need = true;
  314. pickupItemSet.add("头");
  315. }
  316. if (targetTdElement.text().includes("【防具(腕)】\n无")) {
  317. // console.log("没有【防具(腕)】");
  318. need = true;
  319. pickupItemSet.add("腕");
  320. }
  321. if (targetTdElement.text().includes("【防具(足)】\n无")) {
  322. // console.log("没有【防具(足)】");
  323. need = true;
  324. pickupItemSet.add("足");
  325. }
  326. return need;
  327. }
  328.  
  329. function checkSpoil() {
  330. // 可拾取尸体
  331. var pageText = $("#cmd").text();
  332. if (autoSpoil && pageText.includes("尸体") && pageText.includes("军")) {
  333. if (pageText.includes("罐头") || pageText.includes("元") || pageText.includes("碎片")) {
  334. sl("itm0");
  335. sl("itm1");
  336. sl("itm2");
  337. sl("itm3");
  338. sl("itm4");
  339. sl("money");
  340. postCommand();
  341. return true;
  342. } else {
  343. postCommand();
  344. return true;
  345. }
  346. }
  347. return false;
  348. }
  349.  
  350. function moveTo(id) {
  351. var locationMap = {
  352. "1": "北海岸(A-2)",
  353. "2": "北村住宅区(B-4)",
  354. "3": "北村公所(C-3)",
  355. "4": "邮电局(C-4)",
  356. "5": "消防署(C-5)",
  357. "6": "观音堂(C-6)",
  358. "7": "清水池(D-4)",
  359. "8": "西村神社(E-2)",
  360. "9": "墓地(E-4)",
  361. "10": "山丘地带(F-6)",
  362. "11": "隧道(E-8)",
  363. "12": "西村住宅区(F-2)",
  364. "13": "寺庙(F-9)",
  365. "14": "废校(G-3)",
  366. "15": "南村神社(G-6)",
  367. "16": "森林地带(H-4)",
  368. "17": "源二郎池(H-6)",
  369. "18": "南村住宅区(I-6)",
  370. "19": "诊所(I-7)",
  371. "20": "灯塔(I-10)",
  372. "21": "南海岸(J-6)",
  373. "22": "神秘研究所(H-8)"
  374. }
  375. $('#moveto').val(id);
  376. postCommand("command", "move");
  377. }
  378. // hack
  379.  
  380. //update time
  381. function updateTime(timing, mode) {
  382. if (timing) {
  383. t = timing;
  384. tm = mode;
  385. h = Math.floor(t / 3600);
  386. m = Math.floor((t % 3600) / 60);
  387. s = t % 60;
  388. // add a zero in front of numbers<10
  389. h = checkTime(h);
  390. m = checkTime(m);
  391. s = checkTime(s);
  392. $('#timing').html(h + ':' + m + ':' + s);
  393. tm ? t++ : t--;
  394. setTimeout("updateTime(t,tm)", 1000);
  395. } else {
  396. window.location.href = 'index.php';
  397. }
  398. }
  399. //icon select
  400. function iconMover() {
  401. var gd = document.valid.gender[0].checked ? 'm' : 'f';
  402. var index = document.valid.icon.selectedIndex;
  403. var inum = document.valid.icon[index].value;
  404. ''
  405. $('#iconImg').html('<img src="' + pic_root + gd + '_' + inum + '.gif" alt="' + inum + '">');
  406. }
  407.  
  408. function dniconMover() {
  409. dngd = document.cmd.dngender[0].checked ? 'm' : 'f';
  410. dninum = document.cmd.dnicon.selectedIndex;
  411. $('#dniconImg').html('<img src="' + pic_root + dngd + '_' + dninum + '.gif" alt="' + dninum + '">');
  412. }
  413.  
  414. function postCommand(mode, command, other) {
  415. for (var id in other) {
  416. if (id != 'toJSONString') {
  417. $('#cmd').append('<input type="hidden" name="' + id + '" value="' + other[id] + '">');
  418. }
  419. }
  420. if (mode != undefined) {
  421. $('#cmd').append('<input type="hidden" name="mode" value="' + mode + '">');
  422. }
  423. if (command != undefined) {
  424. $('#cmd').append('<input type="hidden" name="command" value="' + command + '">');
  425. }
  426. $('#submit').attr("disabled", true);
  427. var oXmlHttp = zXmlHttp.createRequest();
  428. var sBody = getRequestBody(document.forms['cmd']);
  429. oXmlHttp.open("post", "command.php", true);
  430. oXmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  431. oXmlHttp.onreadystatechange = function() {
  432. if (oXmlHttp.readyState == 4) {
  433. if (oXmlHttp.status == 200) {
  434. showGamedata(oXmlHttp.responseText);
  435. $('#submit').attr("disabled", false);
  436. } else {
  437. showNotice(oXmlHttp.statusText);
  438. }
  439. }
  440. };
  441. oXmlHttp.send(sBody);
  442. }
  443.  
  444. function transformMoveList() {
  445. var options = $('#moveto option');
  446. var html = "<div id='moveto_trans' class='select'><div class='options'>"
  447. if (options.length > 0) {
  448. options.each(function() {
  449. var title = $(this).html();
  450. var value = $(this).attr('value');
  451. html += "<div value='" + value + "'>" + title + "</div>";
  452. $(this).html();
  453. });
  454. }
  455. html += "</div></div>";
  456. $('#moveto').remove();
  457. $('#cmd').prepend(html);
  458. $('#moveto_trans').css('position', 'absolute');
  459. $('#moveto_trans').css('left', $('.postbutton').position().left + 10);
  460. $('#moveto_trans').css('top', $('.postbutton').position().top - 25);
  461. $('.select .options div').each(function() {
  462. var type = $(this).attr('value');
  463. if (type != 'main') {
  464. $(this).hide();
  465. }
  466. $(this).click(function() {
  467. var value = $(this).attr('value');
  468. if (value == 'main') {
  469. $(this).siblings().toggle();
  470. } else {
  471. postCommand('command', 'move', {
  472. moveto: value
  473. });
  474. }
  475. })
  476. })
  477. }
  478.  
  479. function showGamedata(sGamedata) {
  480. gamedata = sGamedata.parseJSON();
  481. if (gamedata['url']) {
  482. window.location.href = gamedata['url'];
  483. } else if (!gamedata['main']) {
  484. window.location.href = 'index.php';
  485. }
  486. if (gamedata['team']) {
  487. $('#team').val(gamedata['team']);
  488. gamedata['team'] = '';
  489. }
  490. for (var id in gamedata) {
  491. if ((id == 'toJSONString') || (!gamedata[id])) {
  492. continue;
  493. }
  494. $('#' + id).html(gamedata[id]);
  495. console.log(id);
  496. }
  497. if (DEBUGMODE == 99) {
  498. transformMoveList();
  499. }
  500. }
  501.  
  502. function showNotice(sNotice) {
  503. $('#notice').html(sNotice);
  504. }
  505.  
  506. function sl(id) {
  507. checkbox = $('#' + id);
  508. // if (checkbox.is(':checked')){$('#submit').click();}
  509. checkbox.click();
  510. }
  511.  
  512. function showNews(n) {
  513. var oXmlHttp = zXmlHttp.createRequest();
  514. oXmlHttp.open("post", "news.php", true);
  515. oXmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  516. oXmlHttp.onreadystatechange = function() {
  517. if (oXmlHttp.readyState == 4) {
  518. if (oXmlHttp.status == 200) {
  519. showNewsdata(oXmlHttp.responseText);
  520. } else {
  521. showNotice(oXmlHttp.statusText);
  522. }
  523. }
  524. };
  525. oXmlHttp.send('newsmode=' + n);
  526. }
  527.  
  528. function showNewsdata(newsdata) {
  529. news = newsdata.parseJSON();
  530. if (news['msg']) {
  531. newchat = '';
  532. for (var nid in news['msg']) {
  533. if (nid == 'toJSONString') {
  534. continue;
  535. }
  536. newchat += news['msg'][nid];
  537. }
  538. $('#newsinfo').html(newchat);
  539. } else {
  540. $('#newsinfo').html(news);
  541. }
  542. }
  543.  
  544. function showAlive(mode) {
  545. window.location.href = 'alive.php?alivemode=' + mode;
  546. }
  547. var refchat = null;
  548.  
  549. function chat(mode, reftime) {
  550. clearTimeout(refchat);
  551. var oXmlHttp = zXmlHttp.createRequest();
  552. var s = document.forms['sendchat'];
  553. if (mode == 'send') {
  554. s['sendmode'].value = 'send';
  555. } //
  556. sBody = getRequestBody(s);
  557. //alert(sBody);
  558. oXmlHttp.open("post", "chat.php", true);
  559. oXmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  560. oXmlHttp.onreadystatechange = function() {
  561. if (oXmlHttp.readyState == 4) {
  562. if (oXmlHttp.status == 200) {
  563. showChatdata(oXmlHttp.responseText);
  564. } else {
  565. showNotice(oXmlHttp.statusText);
  566. }
  567. }
  568. };
  569. oXmlHttp.send(sBody);
  570. if (mode == 'send') {
  571. $('#chatmsg').val("");
  572. $("#sendmode").val('ref');
  573. }
  574. rtime = reftime;
  575. refchat = setTimeout("chat('ref',rtime)", rtime);
  576. }
  577.  
  578. function showChatdata(jsonchat) {
  579. chatdata = jsonchat.parseJSON();
  580. if (chatdata['msg']) {
  581. $('#lastcid').val(chatdata['lastcid']);
  582. newchat = '';
  583. for (var cid in chatdata['msg']) {
  584. if (cid == 'toJSONString' || cid == 'parseJSON') {
  585. continue;
  586. }
  587. newchat += chatdata['msg'][cid];
  588. }
  589. /*Code For At*/
  590. Reg = new RegExp("@[\u4E00-\u9FA5A-Za-z0-9_]*", "g");
  591. result = Reg.test(newchat);
  592. if (result == true) {
  593. newchat = newchat.replace(Reg, "<a class='aite' onclick=AiteOther('$&') href='javascript:void(0)'>$&</a>");
  594. }
  595. $('#chatlist').html(newchat + $('#chatlist').html());
  596. if (result == true) {
  597. UpdataAite();
  598. }
  599. }
  600. }
  601.  
  602. function UpdataAite() {
  603. nickname = $("#nickname").html();
  604. var i = 0;
  605. $("a.aite").each(function() {
  606. if (i < 10) {
  607. var name = $(this).html();
  608. if ("@" + nickname == name) {
  609. $(this).removeClass('aite').addClass('aiteme');
  610. }
  611. }
  612. i++;
  613. });
  614. }
  615.  
  616. function AiteOther(name) {
  617. if (name != "@" + nickname) {
  618. $("#chatmsg").val(name + ",");
  619. }
  620. }
  621.  
  622. run();
  623. })();