Advertisement
hossem147

minimap

May 3rd, 2016
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.28 KB | None | 0 0
  1. $.getScript( "https://cdn.socket.io/socket.io-1.3.5.js" );
  2. $.getScript( "http://cdn.jsdelivr.net/msgpack/1.05/msgpack.js" );
  3. setTimeout(function()
  4. {
  5. window.msgpack = this.msgpack;
  6.  
  7. (function() {
  8. var _WebSocket = window._WebSocket = window.WebSocket;
  9. var $ = window.jQuery;
  10. var msgpack = window.msgpack;
  11. var options = {
  12. enableMultiCells: true,
  13. enableCross: true
  14. };
  15.  
  16. // game states
  17. var agar_server = null;
  18. var map_server = null;
  19. var map_party = null;
  20. var map_room_id = null;
  21. var player_name = [];
  22. var players = [];
  23. var id_players = [];
  24. var user_players = [];
  25. var cells = [];
  26. var current_cell_ids = [];
  27. var start_x = -7000,
  28. start_y = -7000,
  29. end_x = 7000,
  30. end_y = 7000,
  31. length_x = 14000,
  32. length_y = 14000;
  33. var render_timer = null;
  34.  
  35. function miniMapConnectToServer() {
  36. try {
  37. //var host = 'http://localhost:5001';
  38. var host = '5.175.193.30:5001';
  39. map_server = io(host);
  40. } catch (e) {
  41. alert('Minimap not supported :(');
  42. }
  43.  
  44. map_server.on('connect', function(event) {
  45. if (map_party != null)
  46. map_server.send({type: 'restore_connection', agar_url: agar_server, party: map_party, room_id: map_room_id});
  47. //console.log(address + ' connected');
  48. });
  49.  
  50. map_server.on('message', function(event) {
  51. if (event.type == 'room_confirm')
  52. {
  53. if (event.room_id != '')
  54. {
  55. map_room_id = event.room_id;
  56. map_party = event.party;
  57. joinParty(event.party);
  58. }
  59. else
  60. {
  61. $('#input_party').val('')
  62. disconnect();
  63. }
  64. }
  65. else if (event.type == 'room_data')
  66. {
  67. id_players = event.data.my_tokens;
  68. user_players = event.data.user_tokens;
  69. }
  70.  
  71. });
  72.  
  73. map_server.on('error', function(event) {
  74. map_server = null;
  75. console.error('failed to connect to map server');
  76. });
  77.  
  78. map_server.on('close', function(event) {
  79. console.log('map server disconnected');
  80. });
  81. }
  82.  
  83. function miniMapRender() {
  84. var canvas = window.mini_map;
  85. var ctx = canvas.getContext('2d');
  86. ctx.clearRect(0, 0, canvas.width, canvas.height);
  87. if (map_server != null && map_party != null)
  88. {
  89. var default_color = 'rgba(132, 132, 132, 1)';
  90.  
  91. var id, token = null;
  92.  
  93. for (id in id_players)
  94. {
  95. token = id_players[id];
  96. draw(token, token.color);
  97. if (options.enableCross && current_cell_ids.indexOf(token.id) != -1)
  98. miniMapDrawCross(token.x, token.y, token.color);
  99. }
  100.  
  101. if (options.enableMultiCells)
  102. {
  103. for (id in user_players)
  104. draw(user_players[id], default_color);
  105. }
  106.  
  107. function draw(token, color)
  108. {
  109. var x = token.x * canvas.width;
  110. var y = token.y * canvas.height;
  111. var size = token.size * canvas.width;
  112. ctx.beginPath();
  113. ctx.arc(
  114. x,
  115. y,
  116. size,
  117. 0,
  118. 2 * Math.PI,
  119. false
  120. );
  121. ctx.closePath();
  122. ctx.fillStyle = color;
  123. ctx.fill();
  124. }
  125.  
  126. }
  127. }
  128.  
  129. function miniMapDrawCross(x, y, color) {
  130. var canvas = window.mini_map;
  131. var ctx = canvas.getContext('2d');
  132. ctx.lineWidth = 0.5;
  133. ctx.beginPath();
  134. ctx.moveTo(0, y * canvas.height);
  135. ctx.lineTo(canvas.width, y * canvas.height);
  136. ctx.moveTo(x * canvas.width, 0);
  137. ctx.lineTo(x * canvas.width, canvas.height);
  138. ctx.closePath();
  139. ctx.strokeStyle = color || '#FFFFFF';
  140. ctx.stroke();
  141. }
  142.  
  143. function miniMapDrawMiddleCross() {
  144. var canvas = window.mini_map;
  145. var ctx = canvas.getContext('2d');
  146. ctx.lineWidth = 0.5;
  147. ctx.beginPath();
  148. ctx.moveTo(0, canvas.height/2);
  149. ctx.lineTo(canvas.width, canvas.height/2);
  150. ctx.moveTo(canvas.width/2, 0);
  151. ctx.lineTo(canvas.width/2, canvas.height);
  152. ctx.closePath();
  153. ctx.strokeStyle = '#000000';
  154. ctx.stroke();
  155. }
  156.  
  157. function miniMapCreateToken(id, color) {
  158. var mini_map_token = {
  159. id: id,
  160. color: color,
  161. x: 0,
  162. y: 0,
  163. size: 0
  164. };
  165. return mini_map_token;
  166. }
  167.  
  168. function miniMapRegisterToken(id, token) {
  169. if (window.mini_map_tokens[id] === undefined) {
  170. window.mini_map_tokens[id] = token;
  171. }
  172. }
  173.  
  174. function miniMapUnregisterToken(id) {
  175. if (window.mini_map_tokens[id] !== undefined) {
  176. delete window.mini_map_tokens[id];
  177. }
  178. }
  179.  
  180. function miniMapIsRegisteredToken(id) {
  181. return window.mini_map_tokens[id] !== undefined;
  182. }
  183.  
  184. function miniMapUpdateToken(id, x, y, size) {
  185. if (window.mini_map_tokens[id] !== undefined) {
  186.  
  187. window.mini_map_tokens[id].x = x;
  188. window.mini_map_tokens[id].y = y;
  189. window.mini_map_tokens[id].size = size;
  190.  
  191. return true;
  192. } else {
  193. return false;
  194. }
  195. }
  196.  
  197. function miniMapUpdatePos(x, y) {
  198. window.mini_map_pos.text('x: ' + x.toFixed(0) + ', y: ' + y.toFixed(0));
  199. }
  200.  
  201. function miniMapReset() {
  202. cells = [];
  203. window.mini_map_tokens = [];
  204. }
  205.  
  206. function miniMapInit() {
  207. miniMapConnectToServer();
  208. window.mini_map_tokens = [];
  209.  
  210. cells = [];
  211. current_cell_ids = [];
  212. start_x = -7000;
  213. start_y = -7000;
  214. end_x = 7000;
  215. end_y = 7000;
  216. length_x = 14000;
  217. length_y = 14000;
  218.  
  219. // minimap dom
  220. if ($('#mini-map-wrapper').length === 0) {
  221. var wrapper = $('<div>').attr('id', 'mini-map-wrapper').css({
  222. position: 'fixed',
  223. bottom: 10,
  224. right: 10,
  225. width: 300,
  226. height: 300,
  227. background: 'rgba(128, 128, 128, 0.58)'
  228. });
  229.  
  230. var mini_map = $('<canvas>').attr({
  231. id: 'mini-map',
  232. width: 300,
  233. height: 300
  234. }).css({
  235. width: '100%',
  236. height: '100%',
  237. position: 'relative'
  238. });
  239.  
  240. wrapper.append(mini_map).appendTo(document.body);
  241.  
  242. window.mini_map = mini_map[0];
  243. }
  244.  
  245. // minimap renderer
  246. if (render_timer === null)
  247. render_timer = setInterval(miniMapRender, 1000 / 30);
  248.  
  249. // minimap location
  250. if ($('#mini-map-pos').length === 0) {
  251. window.mini_map_pos = $('<div>').attr('id', 'mini-map-pos').css({
  252. bottom: 10,
  253. right: 10,
  254. color: 'white',
  255. fontSize: 15,
  256. fontWeight: 800,
  257. position: 'fixed'
  258. }).appendTo(document.body);
  259. }
  260.  
  261. // minimap options
  262. if ($('#mini-map-options').length === 0) {
  263. window.mini_map_options = $('<div>').attr('id', 'mini-map-options').css({
  264. bottom: 315,
  265. right: 10,
  266. color: '#666',
  267. fontSize: 14,
  268. position: 'fixed',
  269. fontWeight: 400,
  270. zIndex: 1000
  271. }).appendTo(document.body);
  272.  
  273. var container = $('<div>')
  274. .css({
  275. background: 'rgba(200, 200, 200, 0.58)',
  276. padding: 5,
  277. borderRadius: 5
  278. })
  279. .hide();
  280.  
  281. for (var name in options) {
  282.  
  283. var label = $('<label>').css({
  284. display: 'block'
  285. });
  286.  
  287. var checkbox = $('<input>').attr({
  288. type: 'checkbox'
  289. }).prop({
  290. checked: options[name]
  291. });
  292.  
  293. label.append(checkbox);
  294. label.append(' ' + camel2cap(name));
  295.  
  296. checkbox.click(function(options, name) { return function(evt) {
  297. options[name] = evt.target.checked;
  298. console.log(name, evt.target.checked);
  299. }}(options, name));
  300.  
  301. label.appendTo(container);
  302. }
  303.  
  304. container.appendTo(window.mini_map_options);
  305. var form = $('<div>')
  306. .addClass('form-inline')
  307. .css({
  308. opacity: 0.7,
  309. marginTop: 2
  310. })
  311. .appendTo(window.mini_map_options);
  312.  
  313. var form_group = $('<div>')
  314. .addClass('form-group')
  315. .appendTo(form);
  316.  
  317. var setting_btn = $('<button>')
  318. .addClass('btn')
  319. .css({
  320. float: 'right',
  321. fontWeight: 800,
  322. marginLeft: 2
  323. })
  324. .on('click', function() {
  325. container.toggle();
  326. setting_btn.blur();
  327. return false;
  328. })
  329. .append($('<i>').addClass('glyphicon glyphicon-cog'))
  330. .appendTo(form_group);
  331.  
  332. //var help_btn = $('<button>')
  333. // .addClass('btn')
  334. // .text('?')
  335. // .on('click', function(e) {
  336. // window.open('https://github.com/dimotsai/agar-mini-map/#minimap-server');
  337. // help_btn.blur();
  338. // return false;
  339. // })
  340. // .appendTo(form_group);
  341.  
  342. var addressInput = $('<input>')
  343. .css({
  344. marginLeft: 2
  345. })
  346. .attr('id', 'input_party')
  347. .attr('placeholder', 'agarmap.com code')
  348. .attr('type', 'text')
  349. .addClass('form-control')
  350. .appendTo(form_group);
  351.  
  352.  
  353. var connectBtn = $('<button>')
  354. .attr('id', 'mini-map-connect-btn')
  355. .css({
  356. marginLeft: 2
  357. })
  358. .text('Connect')
  359. .click(connect)
  360. .addClass('btn')
  361. .appendTo(form_group);
  362. }
  363. }
  364.  
  365. var connect = function () {
  366. var connectBtn = $('#mini-map-connect-btn');
  367. map_server.send({type: 'room_connect', agar_url: agar_server, room_id: $('#input_party').val()});
  368.  
  369. connectBtn.popover('destroy');
  370. connectBtn.text('Disconnect');
  371.  
  372.  
  373. connectBtn.off('click');
  374. connectBtn.on('click', disconnect);
  375. connectBtn.blur();
  376. };
  377.  
  378. var disconnect = function() {
  379. var connectBtn = $('#mini-map-connect-btn')
  380. //players = id_players = user_players = [];
  381. connectBtn.text('Connect');
  382. connectBtn.off('click');
  383. connectBtn.on('click', connect);
  384. connectBtn.blur();
  385. //map_server.send({type: 'room_disconnect', agar_url: agar_server, room_id: map_room});
  386. //map_server.send({type: 'room_disconnect', agar_url: agar_server, room_id: map_room});
  387. map_server.emit('room_disconnect', {});
  388. map_party = map_room_id = null;
  389.  
  390. //if (map_server)
  391. // map_server.disconnect();
  392. //map_server = null;
  393. //miniMapReset();
  394. };
  395.  
  396. // cell constructor
  397. function Cell(id, x, y, size, color, name) {
  398. cells[id] = this;
  399. this.id = id;
  400. this.ox = this.x = x;
  401. this.oy = this.y = y;
  402. this.oSize = this.size = size;
  403. this.color = color;
  404. this.points = [];
  405. this.pointsAcc = [];
  406. this.setName(name);
  407. }
  408.  
  409. Cell.prototype = {
  410. id: 0,
  411. points: null,
  412. pointsAcc: null,
  413. name: null,
  414. nameCache: null,
  415. sizeCache: null,
  416. x: 0,
  417. y: 0,
  418. size: 0,
  419. ox: 0,
  420. oy: 0,
  421. oSize: 0,
  422. nx: 0,
  423. ny: 0,
  424. nSize: 0,
  425. updateTime: 0,
  426. updateCode: 0,
  427. drawTime: 0,
  428. destroyed: false,
  429. isVirus: false,
  430. isAgitated: false,
  431. wasSimpleDrawing: true,
  432.  
  433. destroy: function() {
  434. delete cells[this.id];
  435. id = current_cell_ids.indexOf(this.id);
  436. -1 != id && current_cell_ids.splice(id, 1);
  437. this.destroyed = true;
  438. miniMapUnregisterToken(this.id);
  439. },
  440. setName: function(name) {
  441. this.name = name;
  442. },
  443. updatePos: function() {
  444. if (options.enableMultiCells || -1 != current_cell_ids.indexOf(this.id)) {
  445. if (! miniMapIsRegisteredToken(this.id))
  446. {
  447. miniMapRegisterToken(
  448. this.id,
  449. miniMapCreateToken(this.id, this.color)
  450. );
  451. }
  452.  
  453. var size_n = this.nSize/length_x;
  454. miniMapUpdateToken(this.id, (this.nx - start_x)/length_x, (this.ny - start_y)/length_y, size_n);
  455. }
  456. }
  457. };
  458.  
  459. String.prototype.capitalize = function() {
  460. return this.charAt(0).toUpperCase() + this.slice(1);
  461. };
  462.  
  463. function camel2cap(str) {
  464. return str.replace(/([A-Z])/g, function(s){return ' ' + s.toLowerCase();}).capitalize();
  465. };
  466.  
  467. // create a linked property from slave object
  468. // whenever master[prop] update, slave[prop] update
  469. function refer(master, slave, prop) {
  470. Object.defineProperty(master, prop, {
  471. get: function(){
  472. return slave[prop];
  473. },
  474. set: function(val) {
  475. slave[prop] = val;
  476. },
  477. enumerable: true,
  478. configurable: true
  479. });
  480. };
  481.  
  482. // extract a websocket packet which contains the information of cells
  483. function extractCellPacket(data, offset) {
  484. ////
  485. var dataToSend = {
  486. destroyQueue : [],
  487. nodes : [],
  488. nonVisibleNodes : []
  489. };
  490. ////
  491.  
  492. var I = +new Date;
  493. var qa = false;
  494. var b = Math.random(), c = offset;
  495. var size = data.getUint16(c, true);
  496. c = c + 2;
  497.  
  498. // Nodes to be destroyed (killed)
  499. for (var e = 0; e < size; ++e) {
  500. var p = cells[data.getUint32(c, true)],
  501. f = cells[data.getUint32(c + 4, true)],
  502. c = c + 8;
  503. p && f && (
  504. f.destroy(),
  505. f.ox = f.x,
  506. f.oy = f.y,
  507. f.oSize = f.size,
  508. f.nx = p.x,
  509. f.ny = p.y,
  510. f.nSize = f.size,
  511. f.updateTime = I,
  512. dataToSend.destroyQueue.push(f.id));
  513.  
  514. }
  515.  
  516. // Nodes to be updated
  517. for (e = 0; ; ) {
  518. var d = data.getUint32(c, true);
  519. c += 4;
  520. if (0 == d) {
  521. break;
  522. }
  523. ++e;
  524. var p = data.getInt32(c, true),
  525. c = c + 4,
  526. f = data.getInt32(c, true),
  527. c = c + 4;
  528. g = data.getInt16(c, true);
  529. c = c + 2;
  530. 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; )
  531. h = "0" + h;
  532.  
  533. var h = "#" + h,
  534. k = data.getUint8(c++),
  535. m = !!(k & 1),
  536. q = !!(k & 16);
  537.  
  538. k & 2 && (c += 4);
  539. k & 4 && (c += 8);
  540. k & 8 && (c += 16);
  541.  
  542. for (var n, k = ""; ; ) {
  543. n = data.getUint16(c, true);
  544. c += 2;
  545. if (0 == n)
  546. break;
  547. k += String.fromCharCode(n)
  548. }
  549.  
  550. n = k;
  551. k = null;
  552.  
  553. var updated = false;
  554. // if d in cells then modify it, otherwise create a new cell
  555. cells.hasOwnProperty(d)
  556. ? (k = cells[d],
  557. k.updatePos(),
  558. k.ox = k.x,
  559. k.oy = k.y,
  560. k.oSize = k.size,
  561. k.color = h,
  562. updated = true)
  563. : (k = new Cell(d, p, f, g, h, n),
  564. k.pX = p,
  565. k.pY = f);
  566.  
  567. k.isVirus = m;
  568. k.isAgitated = q;
  569. k.nx = p;
  570. k.ny = f;
  571. k.nSize = g;
  572. k.updateCode = b;
  573. k.updateTime = I;
  574. n && k.setName(n);
  575.  
  576. // ignore food creation
  577. if (updated) {
  578. dataToSend.nodes.push({
  579. id: k.id,
  580. x: k.nx,
  581. y: k.ny,
  582. size: k.nSize,
  583. color: k.color
  584. });
  585. }
  586. }
  587.  
  588. // Destroy queue + nonvisible nodes
  589. b = data.getUint32(c, true);
  590. c += 4;
  591. for (e = 0; e < b; e++) {
  592. d = data.getUint32(c, true);
  593. c += 4, k = cells[d];
  594. null != k && k.destroy();
  595. dataToSend.nonVisibleNodes.push(d);
  596. }
  597.  
  598. var packet = {
  599. type: 16,
  600. data: dataToSend
  601. }
  602.  
  603. //miniMapSendRawData(msgpack.pack(packet));
  604. }
  605.  
  606. // extract the type of packet and dispatch it to a corresponding extractor
  607. function extractPacket(event) {
  608. var c = 0;
  609. var data = new DataView(event.data);
  610. 240 == data.getUint8(c) && (c += 5);
  611. var opcode = data.getUint8(c);
  612. c++;
  613. switch (opcode) {
  614. case 16: // cells data
  615. extractCellPacket(data, c);
  616. break;
  617. case 20: // cleanup ids
  618. current_cell_ids = [];
  619. break;
  620. case 32: // cell id belongs me
  621. var id = data.getUint32(c, true);
  622.  
  623. if (current_cell_ids.indexOf(id) === -1)
  624. current_cell_ids.push(id);
  625.  
  626. break;
  627. case 64: // get borders
  628. start_x = data.getFloat64(c, !0), c += 8,
  629. start_y = data.getFloat64(c, !0), c += 8,
  630. end_x = data.getFloat64(c, !0), c += 8,
  631. end_y = data.getFloat64(c, !0), c += 8,
  632. center_x = (start_x + end_x) / 2,
  633. center_y = (start_y + end_y) / 2,
  634. length_x = Math.abs(start_x - end_x),
  635. length_y = Math.abs(start_y - end_y);
  636. }
  637. }
  638.  
  639. window.my_tokens = function()
  640. {
  641. var tt = [];
  642. var user_tokens = [];
  643. if (current_cell_ids.length > 0)
  644. {
  645. for (var id in window.mini_map_tokens) {
  646. var t = window.mini_map_tokens[id];
  647. if (-1 != current_cell_ids.indexOf(t.id))
  648. tt.push(t);
  649. else if (options.enableMultiCells && t.size > 0.005)
  650. user_tokens.push(t);
  651. }
  652. }
  653. return {my_tokens: tt, user_tokens: user_tokens}
  654. };
  655.  
  656. // the injected point, overwriting the WebSocket constructor
  657. window.WebSocket = function(url, protocols) {
  658. console.log('Listen');
  659.  
  660. if (protocols === undefined) {
  661. protocols = [];
  662. }
  663.  
  664. var ws = new _WebSocket(url, protocols);
  665.  
  666. refer(this, ws, 'binaryType');
  667. refer(this, ws, 'bufferedAmount');
  668. refer(this, ws, 'extensions');
  669. refer(this, ws, 'protocol');
  670. refer(this, ws, 'readyState');
  671. refer(this, ws, 'url');
  672.  
  673. this.send = function(data){
  674. return ws.send.call(ws, data);
  675. };
  676.  
  677. this.close = function(){
  678. return ws.close.call(ws);
  679. };
  680.  
  681. this.onopen = function(event){};
  682. this.onclose = function(event){};
  683. this.onerror = function(event){};
  684. this.onmessage = function(event){};
  685.  
  686. ws.onopen = function(event) {
  687. miniMapInit();
  688. agar_server = url;
  689. if (this.onopen)
  690. return this.onopen.call(ws, event);
  691. }.bind(this);
  692.  
  693. ws.onmessage = function(event) {
  694. extractPacket(event);
  695. if (map_server != null && map_server.connected && map_party != null)
  696. map_server.emit('game_message', window.my_tokens());
  697. if (this.onmessage)
  698. return this.onmessage.call(ws, event);
  699. }.bind(this);
  700.  
  701. ws.onclose = function(event) {
  702. if (this.onclose)
  703. return this.onclose.call(ws, event);
  704. }.bind(this);
  705.  
  706. ws.onerror = function(event) {
  707. if (this.onerror)
  708. return this.onerror.call(ws, event);
  709. }.bind(this);
  710. };
  711.  
  712. window.WebSocket.prototype = _WebSocket;
  713.  
  714. $(window.document).ready(function() {
  715. miniMapInit();
  716. });
  717.  
  718. $(window).load(function() {
  719. var main_canvas = document.getElementById('canvas');
  720. if (main_canvas && main_canvas.onmousemove) {
  721. document.onmousemove = main_canvas.onmousemove;
  722. main_canvas.onmousemove = null;
  723. }
  724. });
  725. })();
  726. },1500);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement