Advertisement
24001

hkg map

Dec 4th, 2015
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 44.85 KB | None | 0 0
  1. // ==UserScript==
  2. // @name MINIMAP PARA HKG AGAR TOOL. Tamanho reduzido.
  3. // @namespace http://github.com/dimotsai/
  4. // @version 1.2.0
  5. // @description Minimap para qualquer extensão. obs: Ela mostra a localização dos amigos. Tamanho do Minimap reduzido.
  6. // @author dimotsai
  7. // @license MIT
  8. // @match http://agar.io/*
  9. // @require http://cdn.jsdelivr.net/msgpack/1.05/msgpack.js
  10. // @require https://cdn.bootcss.com/jquery/1.11.3/jquery.min.js
  11. // @require https://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js
  12. // @grant none
  13. // @run-at document-body
  14. // ==/UserScript==
  15.  
  16. window.msgpack = this.msgpack;
  17.  
  18. (function() {
  19. var _WebSocket = window._WebSocket = window.WebSocket;
  20. var $ = window.jQuery;
  21. var msgpack = window.msgpack;
  22. var options = {
  23. enableMultiCells: true,
  24. enablePosition: true,
  25. enableCross: false,
  26. showMemberOnly: true,
  27. showPlayerNameInsteadOfId: true,
  28. };
  29.  
  30. /* Configuration for porting */
  31. var Config_poker = {
  32. fieldName : {
  33. region : "#o-region",
  34. gamemode : "#o-gamemode",
  35. room : '#roomIdOrIp'
  36. },
  37. injectOnMessage : false,
  38. };
  39.  
  40. var Config_DaChong = {
  41. fieldName : {
  42. region : "#region",
  43. gamemode : "#gamemode",
  44. room : '#srv-ip'
  45. },
  46. injectOnMessage : true,
  47. };
  48.  
  49. var currentConfig = Config_DaChong;
  50.  
  51. var fieldName = currentConfig.fieldName;
  52. var injectOnMessage = currentConfig.injectOnMessage;
  53. var defaultServer = "ws://eddy.zone.be:8000";
  54.  
  55. // game states
  56. var agarServerAddress = null;
  57. var map_server = null;
  58. var player_name = [];
  59. var players = [];
  60. var id_players = [];
  61. var cells = [];
  62. var current_cell_ids = [];
  63. var start_x = -7000,
  64. start_y = -7000,
  65. end_x = 7000,
  66. end_y = 7000,
  67. length_x = 14000,
  68. length_y = 14000;
  69. var minimapHeight = 300;
  70. var minimapWidth = 300;
  71. var render_timer = null;
  72. var update_server_list_timer = null;
  73. var mini_map_tokens = [];
  74. var mapEvent = [];
  75.  
  76. /* Map Event Object */
  77. function Event(data){
  78. this.x = data.x;
  79. this.y = data.y;
  80. this.type = data.type;
  81. this.origin = data.origin;
  82. this.time = Date.now();
  83. }
  84.  
  85. Event.TYPE_NORMAL = 0;
  86. Event.TYPE_FEED = 1;
  87. Event.TYPE_FAKESPACE = 2;
  88. Event.TYPE_RUN = 3;
  89.  
  90. Event.prototype = {
  91. toSendObject: function(){
  92. return {
  93. x: this.x,
  94. y: this.y,
  95. type: this.type,
  96. message: this.message
  97. };
  98. },
  99. isTimeout : function(){
  100. return Date.now() - this.time > 500;
  101. },
  102. render: function(ctx, xyTransform, maxsize){
  103. var elapsedTime = Date.now() - this.time;
  104. if(elapsedTime > 500){
  105. /* TODO: delete */
  106. return;
  107. }
  108.  
  109. var position = xyTransform(this.x, this.y);
  110. var size = maxsize * elapsedTime / 500;
  111. var color;
  112.  
  113. switch(this.type){
  114. case Event.TYPE_NORMAL: color = "#55FF55"; break;
  115. case Event.TYPE_FEED: color = "#CCCCFF"; break;
  116. case Event.TYPE_FAKESPACE: color = "#FFFFFF"; break;
  117. case Event.TYPE_RUN: color = "#FF0000"; break;
  118. }
  119.  
  120. ctx.save();
  121. ctx.strokeStyle = color;
  122. ctx.globalAlpha = Math.min(2 * (500 - elapsedTime) / 500, 1);
  123. ctx.lineCap = "round";
  124. ctx.lineJoin = "round";
  125. ctx.lineWidth = size * 0.05;
  126. ctx.beginPath();
  127. ctx.arc(position.x,
  128. position.y,
  129. size,
  130. 0,
  131. 2 * Math.PI,
  132. false);
  133. ctx.closePath();
  134. ctx.stroke();
  135. },
  136. };
  137.  
  138. function miniMapSendRawData(data) {
  139. if (map_server !== null && map_server.readyState === window._WebSocket.OPEN) {
  140. var array = new Uint8Array(data);
  141. map_server.send(array.buffer);
  142. }
  143. }
  144.  
  145. function getAgarServerInfo(){
  146. return {
  147. address : agarServerAddress,
  148. region: $(fieldName.region).val(),
  149. gamemode: $(fieldName.gamemode).val() === '' ? ':ffa' : $(fieldName.gamemode).val(),
  150. party: $(fieldName.room).val(),
  151. };
  152. }
  153.  
  154. function miniMapConnectToServer(address, onOpen, onClose) {
  155. if(map_server !== null)return;
  156. var ws = null;
  157. try {
  158. ws = new window._WebSocket(address);
  159. } catch (ex) {
  160. onClose();
  161. console.error(ex);
  162. return false;
  163. }
  164. ws.binaryType = "arraybuffer";
  165.  
  166. ws.onopen = onOpen;
  167.  
  168. ws.onmessage = function(event) {
  169. var buffer = new Uint8Array(event.data);
  170. var packet = msgpack.unpack(buffer);
  171. switch(packet.type) {
  172. case 128: /* Update map */
  173. for (var i=0; i < packet.data.addition.length; ++i) {
  174. var cell = packet.data.addition[i];
  175. if (! miniMapIsRegisteredToken(cell.id))
  176. {
  177. miniMapRegisterToken(
  178. cell.id,
  179. miniMapCreateToken(cell.id, cell.color)
  180. );
  181. }
  182.  
  183. var size_n = cell.size/length_x;
  184. miniMapUpdateToken(cell.id, (cell.x - start_x)/length_x, (cell.y - start_y)/length_y, size_n);
  185. }
  186.  
  187. for (i = 0; i < packet.data.deletion.length; ++i) {
  188. var id = packet.data.deletion[i];
  189. miniMapUnregisterToken(id);
  190. }
  191. break;
  192. case 129: /* Update player */
  193. players = packet.data;
  194. for (var p in players) {
  195. var player = players[p];
  196. var ids = player.ids;
  197. for (i in ids) {
  198. id_players[ids[i]] = player.no;
  199. }
  200. }
  201. console.log('update-list');
  202. window.mini_map_party.trigger('update-list');
  203. break;
  204. case 131: /* Update server list */
  205. $('#server-list').empty();
  206. packet.data.forEach(function(server){
  207. var uid = server.uid;
  208. var info = server.info;
  209. var playerCount = server.playerCount;
  210. var item = $('<a>')
  211. .text(info.address + ' ' + info.gamemode + ' : ' + playerCount)
  212. .click({ token: info.party, uid: uid },function(e){
  213. e.preventDefault();
  214. var target = $(e.currentTarget);
  215. if(e.data.token !== ''){
  216. window.connectJ(e.data.token);
  217. $(fieldName.room).val(e.data.token);
  218. setTimeout(function(){
  219. miniMapSendRawData(msgpack.pack({
  220. type: 51,
  221. data: e.data.uid
  222. }));
  223. }, 1000);
  224.  
  225. }
  226. });
  227.  
  228. var item2 = $('<li>');
  229. item.appendTo(item2);
  230. item2.appendTo($('#server-list'));
  231. });
  232. break;
  233. case 33: /* Add event */
  234. mapEvent.push(new Event(packet.data));
  235. }
  236. };
  237.  
  238. ws.onerror = function() {
  239. onClose();
  240. console.error('failed to connect to map server');
  241. };
  242.  
  243. ws.onclose = onClose;
  244.  
  245. map_server = ws;
  246. }
  247.  
  248. function miniMapRender() {
  249. var canvas = window.mini_map;
  250. var ctx = canvas.getContext('2d');
  251.  
  252. // Background
  253. ctx.clearRect(0, 0, canvas.width, canvas.height);
  254. ctx.globalAlpha = 0.3;
  255. ctx.fillStyle = '#000000';
  256. ctx.fillRect(0, 0, canvas.width, canvas.height);
  257. // Draw coordinate
  258. var yAxis = ['A', 'B', 'C', 'D', 'E'];
  259. var xSize = canvas.width;
  260. var ySize = canvas.height;
  261. ctx.beginPath();
  262. ctx.lineWidth = 2;
  263. ctx.textAlign = 'center';
  264. ctx.textBaseline = 'middle';
  265. ctx.font = (0.6 * xSize / 5) + 'px Arial';
  266. ctx.fillStyle = ctx.strokeStyle = '#AAAAAA';
  267. for (var j = 0; j < 5; ++j) {
  268. for (var i = 0; i < 5; ++i) {
  269. ctx.strokeRect((xSize / 5 * i), (ySize / 5 * j), (xSize / 5), (ySize / 5));
  270. ctx.fillText(yAxis[j] + (i + 1), (xSize / 5 * i) + (xSize / 5 / 2), (ySize / 5 * j) + (ySize / 5 / 2));
  271. }
  272. }
  273. ctx.stroke();
  274. ctx.globalAlpha = 1.0; // restore alpha
  275.  
  276. var rendered_player = [];
  277.  
  278. for (var id in mini_map_tokens) {
  279. var token = mini_map_tokens[id];
  280. var x = token.x * canvas.width;
  281. var y = token.y * canvas.height;
  282. var size = token.size * canvas.width;
  283.  
  284. if (!options.showMemberOnly || id_players[id] !== undefined || current_cell_ids.indexOf(token.id) !== -1) {
  285. if(options.showMemberOnly && size < 7){ /* add an translucent, bigger cell to make it clear*/
  286. ctx.globalAlpha = 0.5;
  287. ctx.beginPath();
  288. ctx.arc(
  289. x,
  290. y,
  291. 7,
  292. 0,
  293. 2 * Math.PI,
  294. false
  295. );
  296. ctx.closePath();
  297. ctx.fillStyle = token.color;
  298. ctx.fill();
  299. ctx.globalAlpha = 1.0;
  300. }
  301. ctx.beginPath();
  302. ctx.arc(
  303. x,
  304. y,
  305. size,
  306. 0,
  307. 2 * Math.PI,
  308. false
  309. );
  310. ctx.closePath();
  311. ctx.fillStyle = token.color;
  312. ctx.fill();
  313. }
  314.  
  315. if (options.enableCross && -1 != current_cell_ids.indexOf(token.id)){
  316. miniMapDrawCross(token.x, token.y, token.color);
  317. }
  318.  
  319. if (id_players[id] !== undefined) {
  320. // Draw you party member's crosshair
  321. if (options.enableCross) {
  322. miniMapDrawCross(token.x, token.y, token.color);
  323. }
  324.  
  325. if(rendered_player.indexOf(id_players[id]) == -1){
  326. if(options.showPlayerNameInsteadOfId){
  327. if(players[id_players[id]].name){
  328. /* draw name only once */
  329. ctx.font = '14px Arial';
  330. ctx.textAlign = 'center';
  331. ctx.textBaseline = 'middle';
  332. ctx.fillStyle = 'white';
  333. ctx.fillText(String.fromCharCode.apply(null, players[id_players[id]].name), x, y + ((size < 10) ? 10 : size * 1.3));
  334. rendered_player.push(id_players[id]);
  335. }
  336. }else{
  337. ctx.font = size * 2 + 'px Arial';
  338. ctx.textAlign = 'center';
  339. ctx.textBaseline = 'middle';
  340. ctx.fillStyle = 'white';
  341. ctx.fillText(id_players[id] + 1, x, y);
  342. }
  343. }
  344. }
  345. }
  346.  
  347. for(var e = 0;e < mapEvent.length; ++e){
  348. if(mapEvent[e]){
  349. mapEvent[e].render(ctx,
  350. function(x,y){
  351. var nx = (x - start_x) / length_x * minimapWidth;
  352. var ny = (y - start_y) / length_y * minimapHeight;
  353. return {x:nx, y:ny};
  354. } ,
  355. 60/* size */);
  356. if(mapEvent[e].isTimeout()){
  357. mapEvent.splice(e, 1);
  358. }
  359. }
  360. }
  361. }
  362.  
  363. function miniMapDrawCross(x, y, color) {
  364. var canvas = window.mini_map;
  365. var ctx = canvas.getContext('2d');
  366. ctx.lineWidth = 0.5;
  367. ctx.beginPath();
  368. ctx.moveTo(0, y * canvas.height);
  369. ctx.lineTo(canvas.width, y * canvas.height);
  370. ctx.moveTo(x * canvas.width, 0);
  371. ctx.lineTo(x * canvas.width, canvas.height);
  372. ctx.closePath();
  373. ctx.strokeStyle = color || '#FFFFFF';
  374. ctx.stroke();
  375. }
  376.  
  377. function miniMapCreateToken(id, color) {
  378. var mini_map_token = {
  379. id: id,
  380. color: color,
  381. x: 0,
  382. y: 0,
  383. size: 0
  384. };
  385. return mini_map_token;
  386. }
  387.  
  388. function miniMapRegisterToken(id, token) {
  389. if (mini_map_tokens[id] === undefined) {
  390. // window.mini_map.append(token);
  391. mini_map_tokens[id] = token;
  392. }
  393. }
  394.  
  395. function miniMapUnregisterToken(id) {
  396. if (mini_map_tokens[id] !== undefined) {
  397. // mini_map_tokens[id].detach();
  398. delete mini_map_tokens[id];
  399. }
  400. }
  401.  
  402. function miniMapIsRegisteredToken(id) {
  403. return mini_map_tokens[id] !== undefined;
  404. }
  405.  
  406. function miniMapUpdateToken(id, x, y, size) {
  407. if (mini_map_tokens[id] !== undefined) {
  408.  
  409. mini_map_tokens[id].x = x;
  410. mini_map_tokens[id].y = y;
  411. mini_map_tokens[id].size = size;
  412.  
  413. return true;
  414. } else {
  415. return false;
  416. }
  417. }
  418.  
  419. function miniMapUpdatePos(x, y) {
  420. window.mini_map_pos.text('x: ' + x.toFixed(0) + ', y: ' + y.toFixed(0));
  421. }
  422.  
  423. function miniMapReset() {
  424. cells = [];
  425. mini_map_tokens = [];
  426. }
  427.  
  428. function miniMapInit() {
  429. mini_map_tokens = [];
  430.  
  431. cells = [];
  432. current_cell_ids = [];
  433. start_x = -7000;
  434. start_y = -7000;
  435. end_x = 7000;
  436. end_y = 7000;
  437. length_x = 14000;
  438. length_y = 14000;
  439.  
  440. /* Right Panel */
  441. if ($('#sidebar-wrapper').length === 0) {
  442. jQuery('body').append(
  443. '<style>' +
  444. '.nav .open > a, ' +
  445. '.nav .open > a:hover, ' +
  446. '.nav .open > a:focus {background-color: transparent;} ' +
  447. ' ' +
  448. '/*-------------------------------*/ ' +
  449. '/* Wrappers */ ' +
  450. '/*-------------------------------*/ ' +
  451. ' ' +
  452. '#sidebar-wrapper { ' +
  453. ' position: absolute; ' +
  454. ' z-index: 1000; ' +
  455. ' margin-right: -310px; ' +
  456. ' left: auto; ' +
  457. ' height: 100%; ' +
  458. ' overflow-y: auto; ' +
  459. ' overflow-x: hidden; ' +
  460. ' background: rgba(26,26,26,0.8); ' +
  461. ' width: 310px; ' +
  462. '} ' +
  463. '#sidebar-wrapper.toggled {' +
  464. ' margin-right: 0px; ' +
  465. '}' +
  466. '/*-------------------------------*/ ' +
  467. '/* Sidebar nav styles */ ' +
  468. '/*-------------------------------*/ ' +
  469. ' ' +
  470. '.sidebar-nav { ' +
  471. ' position: absolute; ' +
  472. ' top: 0; ' +
  473. ' width: 310px; ' +
  474. ' margin: 0; ' +
  475. ' padding: 0; ' +
  476. ' list-style: none; ' +
  477. '} ' +
  478. ' ' +
  479. '.sidebar-nav li { ' +
  480. ' position: relative; ' +
  481. ' line-height: 20px; ' +
  482. ' display: inline-block; ' +
  483. ' width: 100%; ' +
  484. ' background: rgba(40, 40, 40, 0.8);' +
  485. '} ' +
  486. ' ' +
  487. '.sidebar-nav li:before { ' +
  488. ' content: \'\'; ' +
  489. ' position: absolute; ' +
  490. ' top: 0; ' +
  491. ' left: 0; ' +
  492. ' z-index: -1; ' +
  493. ' height: 100%; ' +
  494. ' width: 5px; ' +
  495. ' background-color: #1c1c1c; ' +
  496. ' ' +
  497. '} ' +
  498. '.sidebar-nav li:nth-child(1):before { ' +
  499. ' background-color: #ec122a; ' +
  500. '} ' +
  501. '.sidebar-nav li:nth-child(2):before { ' +
  502. ' background-color: #ec1b5a; ' +
  503. '} ' +
  504. '.sidebar-nav li:nth-child(3):before { ' +
  505. ' background-color: #79aefe; ' +
  506. '} ' +
  507. '.sidebar-nav li:nth-child(4):before { ' +
  508. ' background-color: #314190; ' +
  509. '} ' +
  510. '.sidebar-nav li:nth-child(5):before { ' +
  511. ' background-color: #314120; ' +
  512. '} ' +
  513. '.sidebar-nav li:hover:before, ' +
  514. '.sidebar-nav li.open:hover:before { ' +
  515. ' width: 100%; ' +
  516. ' ' +
  517. '} ' +
  518. ' ' +
  519. '.sidebar-nav li a { ' +
  520. ' display: block; ' +
  521. ' color: #ddd; ' +
  522. ' text-decoration: none; ' +
  523. ' padding: 10px 15px 10px 30px; ' +
  524. '} ' +
  525. ' ' +
  526. '.sidebar-nav li a:hover, ' +
  527. '.sidebar-nav li a:active, ' +
  528. '.sidebar-nav li a:focus, ' +
  529. '.sidebar-nav li.open a:hover, ' +
  530. '.sidebar-nav li.open a:active, ' +
  531. '.sidebar-nav li.open a:focus{ ' +
  532. ' color: #fff; ' +
  533. ' text-decoration: none; ' +
  534. ' background-color: transparent; ' +
  535. '} ' +
  536. ' ' +
  537. '.sidebar-nav > .sidebar-brand { ' +
  538. ' height: 65px; ' +
  539. ' font-size: 20px; ' +
  540. ' line-height: 44px; ' +
  541. ' background-color: #3c3c3c; ' +
  542. '} ' +
  543. '.dropdown-label{ ' +
  544. ' display: block;' +
  545. ' color: #ffffff; ' +
  546. ' padding: 10px 15px 10px 30px;' +
  547. '} ' +
  548. '.dropdown-label:visited, ' +
  549. '.dropdown-label:hover, ' +
  550. '.dropdown-label:active{ ' +
  551. ' color: #cecece; ' +
  552. ' text-decoration: none;' +
  553. '} ' +
  554. '.dropdown-label:after{ ' +
  555. ' content: \' ▶\';' +
  556. ' text-align: right; ' +
  557. ' float:right;' +
  558. '} ' +
  559. '.dropdown-label:hover:after{' +
  560. ' content:\'▼\';' +
  561. ' text-align: right; ' +
  562. ' float:right;' +
  563. '}' +
  564. '.dropdown ul{' +
  565. ' float: left;' +
  566. ' opacity: 0;'+
  567. ' width: 100%; ' +
  568. ' padding: 0px;' +
  569. ' top : 0px;'+
  570. ' visibility: hidden;'+
  571. ' z-index: 1;' +
  572. ' position: absolute;' +
  573. ' border: #555555 1px;' +
  574. ' border-style: solid;' +
  575. '}' +
  576. '.dropdown ul li{' +
  577. ' float: none;' +
  578. ' width: 100%;' +
  579. '}' +
  580. '.dropdown li:before{' +
  581. ' width: 0px;'+
  582. '}' +
  583. '.dropdown:hover ul{' +
  584. ' opacity: 1;'+
  585. ' background: #3c3c3c;'+
  586. ' top : 65px;'+
  587. ' visibility: visible;'+
  588. '}' +
  589. '</style>' +
  590. '<nav class="navbar navbar-inverse navbar-fixed-top" id="sidebar-wrapper" role="navigation">' +
  591. ' <ul class="nav sidebar-nav">' +
  592. ' <div class="sidebar-brand dropdown">' +
  593. ' <a id="tabtitle" class="dropdown-label" href="#">' +
  594. ' Menu' +
  595. ' </a>' +
  596. ' <ul>' +
  597. ' <li><a data-toggle="tab" href="#tab-chat">Chat</a></li>' +
  598. ' <li><a data-toggle="tab" href="#tab-serverselect">Server Select</a></li>' +
  599. ' <li><a data-toggle="tab" href="#tab-settings">settings</a></li>' +
  600. ' </ul>' +
  601. ' </div>' +
  602. ' <div class="tab-content">' +
  603. ' <div id="tab-chat" class="tab-pane fade in active">' +
  604. ' <li>' +
  605. ' <a href="#">' +
  606. ' Player' +
  607. ' </a>' +
  608. ' </li>' +
  609. ' <div id="playerlist"><!-- place holder --></div>' +
  610. ' <li>' +
  611. ' <a href="#">' +
  612. ' Chat' +
  613. ' </a>' +
  614. ' </li>' +
  615. ' <div id="chat"><p>Not yet implemented :P</p></div>' +
  616. ' </div>' +
  617. ' <div id="tab-serverselect" class="tab-pane fade">' +
  618. ' <li>' +
  619. ' <a href="#">' +
  620. ' Server Select' +
  621. ' </a>' +
  622. ' </li>' +
  623. ' <div id="server-list"><!-- place holder --></div>' +
  624. ' </div>' +
  625. ' <div id="tab-settings" class="tab-pane fade">' +
  626. ' <li>' +
  627. ' <a href="#">' +
  628. ' Minimap Server connection' +
  629. ' </a>' +
  630. ' </li>' +
  631. ' <div id="minimap-server-connection"><!-- place holder --></div>' +
  632. ' <li>' +
  633. ' <a href="#">' +
  634. ' Minimap Settings' +
  635. ' </a>' +
  636. ' </li>' +
  637. ' <div id="minimap-setting"><!-- place holder --></div>' +
  638. ' </div>' +
  639. ' </div>' +
  640. ' </ul>' +
  641. '</nav>'
  642. );
  643. }
  644. // '<li>' +
  645. // ' <iframe src="https://discordapp.com/widget?id=103557585675763712&theme=dark" width="350" height="500" allowtransparency="true" frameborder="0"></iframe>' +
  646. // '</li>' +
  647.  
  648. // Minimap
  649. if ($('#mini-map-wrapper').length === 0) {
  650. var wrapper = $('<div>').attr('id', 'mini-map-wrapper').css({
  651. position: 'fixed',
  652. bottom: 5,
  653. right: 5,
  654. width: minimapWidth,
  655. height: minimapHeight,
  656. background: 'rgba(128, 128, 128, 0.58)',
  657. "z-index": '1001'
  658. });
  659.  
  660. var mini_map = $('<canvas>').attr({
  661. id: 'mini-map',
  662. width: minimapWidth,
  663. height: minimapHeight,
  664. }).css({
  665. width: '100%',
  666. height: '100%',
  667. position: 'relative',
  668. cursor: 'cell',
  669. }).on("mousedown",function(e){
  670. if(e.button === 0){
  671. var posX = e.pageX - $(this).offset().left,
  672. posY = e.pageY - $(this).offset().top;
  673. var mapPosX = posX / minimapWidth * length_x + start_x;
  674. var mapPosY = posY / minimapHeight * length_y + start_y;
  675. var event = new Event({
  676. x : mapPosX,
  677. y : mapPosY,
  678. type : Event.TYPE_NORMAL,
  679. origin : -1,
  680. });
  681. miniMapSendRawData(msgpack.pack({
  682. type : 33,
  683. data: event.toSendObject()
  684. }));
  685. }else if(e.button === 2){
  686. window.Minimap.ToggleSidebar();
  687. }
  688. }).on('contextmenu',function(e){
  689. return false;
  690. });
  691.  
  692. wrapper.append(mini_map).appendTo(document.body);
  693.  
  694. window.mini_map = mini_map[0];
  695. }
  696.  
  697. // minimap renderer
  698. if (render_timer === null)
  699. render_timer = setInterval(miniMapRender, 1000 / 30);
  700.  
  701. // update server list every 10 seconds
  702. if (update_server_list_timer === null)
  703. update_server_list_timer = setInterval(function(){
  704. miniMapSendRawData(msgpack.pack({type: 50}));
  705. }, 1000 * 10);
  706.  
  707. // minimap location
  708. if ($('#mini-map-pos').length === 0) {
  709. window.mini_map_pos = $('<div>').attr('id', 'mini-map-pos').css({
  710. bottom: 10,
  711. right: 10,
  712. color: 'white',
  713. fontSize: 15,
  714. fontWeight: 800,
  715. position: 'fixed'
  716. }).appendTo(document.body);
  717. }
  718.  
  719. // minimap options
  720. if ($('#mini-map-options').length === 0) {
  721. window.mini_map_options = $('<div>').attr('id', 'mini-map-options').css({
  722. color: '#EEEEEE',
  723. fontWeight: 400,
  724. padding: '10px 15px 10px 30px'
  725. }).appendTo($('#minimap-setting'));
  726.  
  727. for (var name in options) {
  728.  
  729. var label = $('<label>').css({
  730. display: 'block'
  731. });
  732.  
  733. var checkbox = $('<input>').attr({
  734. type: 'checkbox'
  735. }).prop({
  736. checked: options[name]
  737. });
  738.  
  739. label.append(checkbox);
  740. label.append(' ' + camel2cap(name));
  741.  
  742. checkbox.click( function(options, name) {
  743. return function(evt) {
  744. options[name] = evt.target.checked;
  745. console.log(name, evt.target.checked);
  746. };
  747. }(options, name));
  748.  
  749. label.appendTo(window.mini_map_options);
  750. }
  751.  
  752. var form = $('<div>')
  753. .addClass('form-inline')
  754. .css({
  755. opacity: 0.7,
  756. marginTop: 2
  757. })
  758. .appendTo(window.mini_map_options);
  759.  
  760. var form_group = $('<div>')
  761. .addClass('form-group')
  762. .css({
  763. padding: '10px 15px 10px 30px',
  764. 'margin-bottom': '0px'
  765. })
  766. .appendTo($('#minimap-server-connection'));
  767.  
  768. var addressInput = $('<input>')
  769. .attr('placeholder', defaultServer)
  770. .attr('type', 'text')
  771. .css({
  772. 'background-color':'#3c3c3c',
  773. color: '#FFF',
  774. border: 'none',
  775. 'margin-bottom': '3px'
  776. })
  777. .addClass('form-control')
  778. .val(defaultServer)
  779. .appendTo(form_group);
  780.  
  781. var connect = function (evt) {
  782. var address = addressInput.val();
  783.  
  784. connectBtn.popover('destroy');
  785. connectBtn.text('Disconnect');
  786. miniMapConnectToServer(address, function onOpen() {
  787. miniMapSendRawData(msgpack.pack({
  788. type: 100,
  789. data: getAgarServerInfo(),
  790. }));
  791. miniMapSendRawData(msgpack.pack({
  792. type: 0,
  793. data: player_name
  794. }));
  795. for (var i in current_cell_ids) {
  796. miniMapSendRawData(msgpack.pack({
  797. type: 32,
  798. data: current_cell_ids[i]
  799. }));
  800. }
  801. miniMapSendRawData(msgpack.pack({type: 50}));
  802. console.log(address + ' connected');
  803. }, function onClose() {
  804. map_server = null;
  805. players = [];
  806. id_players = [];
  807. disconnect();
  808. console.log('map server disconnected');
  809. });
  810.  
  811. connectBtn.off('click');
  812. connectBtn.on('click', disconnect);
  813.  
  814. miniMapReset();
  815.  
  816. connectBtn.blur();
  817. };
  818.  
  819. var disconnect = function() {
  820. connectBtn.text('Connect');
  821. connectBtn.off('click');
  822. connectBtn.on('click', connect);
  823. connectBtn.blur();
  824. if (map_server)
  825. map_server.close();
  826.  
  827. miniMapReset();
  828. };
  829.  
  830. var connectBtn = $('<button>')
  831. .attr('id', 'mini-map-connect-btn')
  832. .text('Connect')
  833. .click(connect)
  834. .addClass('btn btn-block btn-primary')
  835. .appendTo(form_group);
  836.  
  837. connectBtn.trigger('click');
  838. }
  839.  
  840. // minimap party
  841. if ($('#mini-map-party').length === 0) {
  842. var mini_map_party = window.mini_map_party = $('<div>')
  843. .css({
  844. color: '#FFF',
  845. fontSize: 20,
  846. fontWeight: 600,
  847. textAlign: 'center',
  848. padding: 10
  849. })
  850. .attr('id', 'mini-map-party')
  851. .appendTo($('#playerlist'));
  852.  
  853. var mini_map_party_list = $('<ol>')
  854. .attr('id', 'mini-map-party-list')
  855. .css({
  856. listStyle: 'none',
  857. padding: 0,
  858. margin: 0
  859. })
  860. .appendTo(mini_map_party);
  861.  
  862. mini_map_party.on('update-list', function(e) {
  863. mini_map_party_list.empty();
  864.  
  865. for (var p in players) {
  866. var player = players[p];
  867. var name = String.fromCharCode.apply(null, player.name);
  868. name = (name === '' ? 'anonymous' : name);
  869. $('<p>')
  870. .text(player.no + 1 + '. ' + name)
  871. .css({
  872. margin: 0
  873. })
  874. .appendTo(mini_map_party_list);
  875. }
  876. });
  877. }
  878. }
  879.  
  880. // cell constructor
  881. function Cell(id, x, y, size, color, name) {
  882. cells[id] = this;
  883. this.id = id;
  884. this.ox = this.x = x;
  885. this.oy = this.y = y;
  886. this.oSize = this.size = size;
  887. this.color = color;
  888. this.points = [];
  889. this.pointsAcc = [];
  890. this.setName(name);
  891. }
  892.  
  893. Cell.prototype = {
  894. id: 0,
  895. points: null,
  896. pointsAcc: null,
  897. name: null,
  898. nameCache: null,
  899. sizeCache: null,
  900. x: 0,
  901. y: 0,
  902. size: 0,
  903. ox: 0,
  904. oy: 0,
  905. oSize: 0,
  906. nx: 0,
  907. ny: 0,
  908. nSize: 0,
  909. updateTime: 0,
  910. updateCode: 0,
  911. drawTime: 0,
  912. destroyed: false,
  913. isVirus: false,
  914. isAgitated: false,
  915. wasSimpleDrawing: true,
  916.  
  917. destroy: function() {
  918. delete cells[this.id];
  919. id = current_cell_ids.indexOf(this.id);
  920. if(-1 != id){
  921. current_cell_ids.splice(id, 1);
  922. }
  923. this.destroyed = true;
  924. if (map_server === null || map_server.readyState !== window._WebSocket.OPEN) {
  925. miniMapUnregisterToken(this.id);
  926. }
  927. },
  928. setName: function(name) {
  929. this.name = name;
  930. },
  931. updatePos: function() {
  932. if (map_server === null || map_server.readyState !== window._WebSocket.OPEN) {
  933. if (options.enableMultiCells || -1 != current_cell_ids.indexOf(this.id)) {
  934. if (! miniMapIsRegisteredToken(this.id))
  935. {
  936. miniMapRegisterToken(
  937. this.id,
  938. miniMapCreateToken(this.id, this.color)
  939. );
  940. }
  941.  
  942. var size_n = this.nSize/length_x;
  943. miniMapUpdateToken(this.id, (this.nx - start_x)/length_x, (this.ny - start_y)/length_y, size_n);
  944. }
  945. }
  946.  
  947. if (options.enablePosition && -1 != current_cell_ids.indexOf(this.id)) {
  948. window.mini_map_pos.show();
  949. miniMapUpdatePos(this.nx, this.ny);
  950. } else {
  951. window.mini_map_pos.hide();
  952. }
  953.  
  954. }
  955. };
  956.  
  957. String.prototype.capitalize = function() {
  958. return this.charAt(0).toUpperCase() + this.slice(1);
  959. };
  960.  
  961. function camel2cap(str) {
  962. return str.replace(/([A-Z])/g, function(s){return ' ' + s.toLowerCase();}).capitalize();
  963. }
  964.  
  965. // create a linked property from slave object
  966. // whenever master[prop] update, slave[prop] update
  967. function refer(master, slave, prop) {
  968. Object.defineProperty(master, prop, {
  969. get: function(){
  970. return slave[prop];
  971. },
  972. set: function(val) {
  973. slave[prop] = val;
  974. },
  975. enumerable: true,
  976. configurable: true
  977. });
  978. }
  979.  
  980. // extract a websocket packet which contains the information of cells
  981. function extractCellPacket(data, offset) {
  982. ////
  983. var dataToSend = {
  984. destroyQueue : [],
  985. nodes : [],
  986. nonVisibleNodes : []
  987. };
  988. ////
  989.  
  990. var I = +new Date();
  991. var qa = false;
  992. var b = Math.random(), c = offset;
  993. var size = data.getUint16(c, true);
  994. c = c + 2;
  995.  
  996. // Nodes to be destroyed (killed)
  997. for (var e = 0; e < size; ++e) {
  998. var p = cells[data.getUint32(c, true)],
  999. f = cells[data.getUint32(c + 4, true)];
  1000. c = c + 8;
  1001. if(p && f){
  1002. f.destroy();
  1003. f.ox = f.x;
  1004. f.oy = f.y;
  1005. f.oSize = f.size;
  1006. f.nx = p.x;
  1007. f.ny = p.y;
  1008. f.nSize = f.size;
  1009. f.updateTime = I;
  1010. dataToSend.destroyQueue.push(f.id);
  1011. }
  1012. }
  1013.  
  1014. // Nodes to be updated
  1015. for (e = 0; ; ) {
  1016. var id = data.getUint32(c, true); /* playerID */
  1017. c += 4;
  1018. if (0 === id) {
  1019. break;
  1020. }
  1021. ++e;
  1022. var p = data.getInt32(c, true); /* x */
  1023. c = c + 4;
  1024.  
  1025. var f = data.getInt32(c, true); /* y */
  1026. c = c + 4;
  1027.  
  1028. g = data.getInt16(c, true); /* radius */
  1029. c = c + 2;
  1030. for (var h = data.getUint8(c++), m = data.getUint8(c++), q = data.getUint8(c++), h = (h << 16 | m << 8 | q).toString(16); 6 > h.length; )
  1031. h = "0" + h; /* color */
  1032.  
  1033. var h = "#" + h, /* color */
  1034. k = data.getUint8(c++), /* some flags */
  1035. m = !!(k & 1), /* isVirus */
  1036. q = !!(k & 16);/* isAgitated */
  1037.  
  1038. if(k & 2){
  1039. c += 4 + data.getUint32(c, true);
  1040. }
  1041. if(k & 4){
  1042. var ch, mcskin = "";
  1043. for(;;){
  1044. ch = data.getUint8(c++);
  1045. if(0 == ch)
  1046. break;
  1047. mcskin += String.fromCharCode(ch);
  1048. }
  1049. }
  1050.  
  1051. for (var n, k = ""; ; ) {
  1052. n = data.getUint16(c, true);
  1053. c += 2;
  1054. if (0 == n)
  1055. break;
  1056. k += String.fromCharCode(n); /* name */
  1057. }
  1058.  
  1059. n = k;
  1060. k = null;
  1061.  
  1062. var updated = false;
  1063. // if id in cells then modify it, otherwise create a new cell
  1064. if(cells.hasOwnProperty(id)){
  1065. k = cells[id];
  1066. k.updatePos();
  1067. k.ox = k.x;
  1068. k.oy = k.y;
  1069. k.oSize = k.size;
  1070. k.color = h;
  1071. updated = true;
  1072. }else{
  1073. k = new Cell(id, p, f, g, h, n);
  1074. k.pX = p;
  1075. k.pY = f;
  1076. }
  1077.  
  1078. k.isVirus = m;
  1079. k.isAgitated = q;
  1080. k.nx = p;
  1081. k.ny = f;
  1082. k.updateCode = b;
  1083. k.updateTime = I;
  1084. k.nSize = g;
  1085. if(n) k.setName(n);
  1086.  
  1087. // ignore food creation
  1088. if (updated) {
  1089. dataToSend.nodes.push({
  1090. id: k.id,
  1091. x: k.nx,
  1092. y: k.ny,
  1093. size: k.nSize,
  1094. color: k.color
  1095. });
  1096. }
  1097. }
  1098.  
  1099. // Destroy queue + nonvisible nodes
  1100. b = data.getUint32(c, true);
  1101. c += 4;
  1102. for (e = 0; e < b; e++) {
  1103. var d = data.getUint32(c, true);
  1104. c += 4;
  1105. var k = cells[d];
  1106. if(null != k) k.destroy();
  1107. dataToSend.nonVisibleNodes.push(d);
  1108. }
  1109.  
  1110. var packet = {
  1111. type: 16,
  1112. data: dataToSend
  1113. };
  1114.  
  1115. miniMapSendRawData(msgpack.pack(packet));
  1116. }
  1117.  
  1118. // extract the type of packet and dispatch it to a corresponding extractor
  1119. function extractPacket(event) {
  1120. var c = 0;
  1121. var data = new DataView(event.data);
  1122. if(240 == data.getUint8(c)) c += 5;
  1123. var opcode = data.getUint8(c);
  1124. c++;
  1125. switch (opcode) {
  1126. case 16: // cells data
  1127. extractCellPacket(data, c);
  1128. break;
  1129. case 20: // cleanup ids
  1130. current_cell_ids = [];
  1131. break;
  1132. case 32: // cell id belongs me
  1133. var id = data.getUint32(c, true);
  1134.  
  1135. if (current_cell_ids.indexOf(id) === -1)
  1136. current_cell_ids.push(id);
  1137.  
  1138. miniMapSendRawData(msgpack.pack({
  1139. type: 32,
  1140. data: id
  1141. }));
  1142. break;
  1143. case 64: // get borders
  1144. start_x = data.getFloat64(c, !0);
  1145. c += 8;
  1146. start_y = data.getFloat64(c, !0);
  1147. c += 8;
  1148. end_x = data.getFloat64(c, !0);
  1149. c += 8;
  1150. end_y = data.getFloat64(c, !0);
  1151. c += 8;
  1152. center_x = (start_x + end_x) / 2;
  1153. center_y = (start_y + end_y) / 2;
  1154. length_x = Math.abs(start_x - end_x);
  1155. length_y = Math.abs(start_y - end_y);
  1156. }
  1157. }
  1158.  
  1159. function extractSendPacket(data) {
  1160. var view = new DataView(data);
  1161. switch (view.getUint8(0, true)) {
  1162. case 0:
  1163. player_name = [];
  1164. for (var i=1; i < data.byteLength; i+=2) {
  1165. player_name.push(view.getUint16(i, true));
  1166. }
  1167.  
  1168. miniMapSendRawData(msgpack.pack({
  1169. type: 0,
  1170. data: player_name
  1171. }));
  1172. break;
  1173. }
  1174. }
  1175.  
  1176. // the injected point, overwriting the WebSocket constructor
  1177. window.WebSocket = function(url, protocols) {
  1178. console.log('Listen');
  1179.  
  1180. if (protocols === undefined) {
  1181. protocols = [];
  1182. }
  1183.  
  1184. var ws = new _WebSocket(url, protocols);
  1185.  
  1186. refer(this, ws, 'binaryType');
  1187. refer(this, ws, 'bufferedAmount');
  1188. refer(this, ws, 'extensions');
  1189. refer(this, ws, 'protocol');
  1190. refer(this, ws, 'readyState');
  1191. refer(this, ws, 'url');
  1192.  
  1193. this.send = function(data){
  1194. extractSendPacket(data);
  1195. return ws.send.call(ws, data);
  1196. };
  1197.  
  1198. this.close = function(){
  1199. return ws.close.call(ws);
  1200. };
  1201.  
  1202. this.onopen = function(event){};
  1203. this.onclose = function(event){};
  1204. this.onerror = function(event){};
  1205. this.onmessage = function(event){};
  1206.  
  1207. ws.onopen = function(event) {
  1208. var ret;
  1209. if (this.onopen)
  1210. ret = this.onopen.call(ws, event);
  1211. miniMapInit();
  1212. agarServerAddress = this.url;
  1213. miniMapSendRawData(msgpack.pack({
  1214. type: 100,
  1215. data: getAgarServerInfo(),
  1216. }));
  1217. miniMapSendRawData(msgpack.pack({type: 50}));
  1218. return ret;
  1219. }.bind(this);
  1220.  
  1221. ws.onmessage = function(event) {
  1222. var ret;
  1223. if (this.onmessage)
  1224. ret = this.onmessage.call(ws, event);
  1225. if(injectOnMessage){
  1226. extractPacket(event);
  1227. }
  1228. return ret;
  1229. }.bind(this);
  1230.  
  1231. ws.onclose = function(event) {
  1232. if (this.onclose)
  1233. return this.onclose.call(ws, event);
  1234. }.bind(this);
  1235.  
  1236. ws.onerror = function(event) {
  1237. if (this.onerror)
  1238. return this.onerror.call(ws, event);
  1239. }.bind(this);
  1240. };
  1241.  
  1242. window.WebSocket.prototype = _WebSocket;
  1243.  
  1244. $(window.document).ready(function() {
  1245. miniMapInit();
  1246. });
  1247.  
  1248. window.Minimap = {
  1249. /* official server message */
  1250. Clear : function(){
  1251. current_cell_ids = [];
  1252. },
  1253. UpdateData : function(data){
  1254. var packet = {
  1255. type: 16,
  1256. data: data
  1257. };
  1258. miniMapSendRawData(msgpack.pack(packet));
  1259. },
  1260. OwnCell : function(id){
  1261. if (current_cell_ids.indexOf(id) === -1)
  1262. current_cell_ids.push(id);
  1263.  
  1264. miniMapSendRawData(msgpack.pack({
  1265. type: 32,
  1266. data: id
  1267. }));
  1268. },
  1269. SetGameAreaSize : function(mapLeft, mapTop, mapRight, mapBottom){
  1270. start_x = mapLeft;
  1271. start_y = mapTop;
  1272. end_x = mapRight;
  1273. end_y = mapBottom;
  1274. center_x = (start_x + end_x) / 2;
  1275. center_y = (start_y + end_y) / 2;
  1276. length_x = Math.abs(start_x - end_x);
  1277. length_y = Math.abs(start_y - end_y);
  1278. },
  1279.  
  1280. /* Map operation */
  1281. MiniMapUnregisterTokenLocal : function(id){
  1282. if (map_server === null || map_server.readyState !== window._WebSocket.OPEN) {
  1283. miniMapUnregisterToken(id);
  1284. }
  1285. },
  1286. MiniMapUpdateToken : function (id, color, x, y, size) {
  1287. if (map_server === null || map_server.readyState !== window._WebSocket.OPEN) {
  1288. if (!miniMapIsRegisteredToken(id)) {
  1289. miniMapRegisterToken(
  1290. id,
  1291. miniMapCreateToken(id, color)
  1292. );
  1293. }
  1294. miniMapUpdateToken(id,
  1295. (x - start_x)/length_x,
  1296. (y - start_y)/length_y,
  1297. size / length_x);
  1298. }
  1299. },
  1300. MiniMapUpdatePos : function(x, y) {
  1301. miniMapUpdatePos(x, y);
  1302. },
  1303.  
  1304. /* API */
  1305. ToggleSidebar : function(){
  1306. $('#sidebar-wrapper').toggleClass('toggled');
  1307. },
  1308.  
  1309. /* Data Object */
  1310. MapEvent : mapEvent,
  1311. };
  1312.  
  1313. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement