LWM_ProgressBars

Insert level & skill progress bars to home page & player info page.

目前為 2016-10-25 提交的版本,檢視 最新版本

  1. // ==UserScript==
  2. // @name LWM_ProgressBars
  3. // @description Insert level & skill progress bars to home page & player info page.
  4. // @namespace saturn_hwm
  5. // @author saturn573
  6. // @homepage http://greasyfork.org/scripts/2892-lwm-progressbars
  7. // @include http://178.248.235.15/home.php
  8. // @include http://*.lordswm.com/home.php
  9. // @include http://*.heroeswm.ru/home.php
  10. // @include http://178.248.235.15/pl_info.php?id=*
  11. // @include http://*.lordswm.com/pl_info.php?id=*
  12. // @include http://*.heroeswm.ru/pl_info.php?id=*
  13. // @version 0.25
  14. // @grant none
  15. // ==/UserScript==
  16.  
  17. var Scales = [[0, 1500, 4500, 15E3, 32E3, 9E4, 19E4, 4E5, 86E4, 165E4, 3E6, 5E6, 85E5, 145E5, 25E6, 43E6, 7E7, 108E6, 16E7, 23E7, 325E6], [20, 50, 90, 160, 280, 500, 900, 1600, 2900, 5300, 9600, 17300], [16, 60, 180, 400, 700, 1200, 2E3, 3E3, 4300, 6E3, 8E3, 10500], [90, 180, 360, 720, 1500, 3E3, 5E3, 8E3, 12E3, 17E3, 23E3, 3E4, 38E3, 47E3, 57E3, 7E4], [10, 30, 60, 100, 150, 210, 280, 360, 450, 550, 660, 800, 1E3, 1300, 2E3], [50, 120, 240, 400, 600, 840, 1200, 2E3, 3E3, 4300, 6E3, 8E3, 10800, 14E3, 17600, 21600, 26E3], [100, 240, 480, 800, 1200, 1680, 2400, 4E3, 6E3, 8600, 12E3], [50, 120, 300, 600, 1E3, 1500,
  18. 2200, 3E3, 4E3, 5500, 7800, 11E3, 14500, 18200, 22200], [150, 350, 750, 1400, 2200, 3200, 4300, 5600, 7E3, 8500], [60, 200, 450, 850, 1500], [1600, 3600], [30, 80, 165, 310, 555, 970, 1680, 2885, 5770], [104, 588, 2200, 7E3, 1E4], [8, 29, 71, 155, 295, 505, 799, 1191, 1695, 6E3, 12E3]];
  19.  
  20. var Styles = '.pb{ display:inline-block; position: relative; width:135px; background:white; border:2px solid; border-radius: 7px/3px; cursor: pointer; }\
  21. .pb .scale { display: inline; position: absolute; top: 0px; left: 0px; height: 100%; border-radius: 2px/1px; background:#af9f39; background: linear-gradient(to top, #af9f39, #fffbca); }\
  22. .pb:hover .pb-side-text { display: inline; }\
  23. .pb:hover .pb-front-text { display: none; }\
  24. .pb-text { position: relative; width: 100%; height: 100%; color: darkgreen; text-align: center; font-weight: bold; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }\
  25. .pb-side-text { display:none; }\
  26. .pb-front-text { display: inline; }\
  27. .left { font-size: smaller; }\
  28. .levelpb { display: inline-flex; margin-left: 10px; width: 180px; } \
  29. .skill-table { width: 100%; margin-bottom: 10px; }\
  30. .skill-table caption { text-align: left; }\
  31. .skill-table caption span { float: right; font-size: small; margin-right: 10; }\
  32. .key-column { text-align: left; width: 100%; font-variant: small-caps; }\
  33. .skill-value { font-size: 15px; }\
  34. .skill-value-complete { color: #af9f39; font-size: 20px; font-weight: bold; font-family: "Comic Sans MS", cursive, sans-serif; }\
  35. .skill-value-none { font-weight: normal; }\
  36. .skill-value-low { color: blue; }\
  37. .progress-column { text-align: center; width: 135px; }\
  38. .expander { margin-left: 5px; border-radius: 8px; height: 16px; width: 16px; font-size: 8px; font-weight:bold; background: gold; background: linear-gradient(to top, #af9f39, #fffbca); border: #af9f39; border-style: outset; border-width: 1px; position: relative; top: -3px; }';
  39.  
  40. var expandCaption = '>';
  41. var collapseCaption = '<';
  42. var levelStringRU = '\u0411\u043E\u0435\u0432\u043E\u0439 \u0443\u0440\u043E\u0432\u0435\u043D\u044C';
  43. var factionsGroupTitleRU = '\u0424\u0440\u0430\u043A\u0446\u0438\u044F';
  44. var guildsGroupTitleRU = '\u0413\u0438\u043B\u044C\u0434\u0438\u044F';
  45. var allRu = '\u043E\u0431\u0449.';
  46.  
  47. function round(value, precision) {
  48. if (precision > 0) {
  49. var b = precision * 10;
  50. return Math.round(value * b) / b;
  51. }
  52. else {
  53. return Math.floor(value);
  54. }
  55. }
  56.  
  57. function parseSourceCode(source) {
  58. var captions = [];
  59. var match;
  60. var cr = /((?:[a-z'\u0430-\u044F\u0451]+\s)?[a-z\u0430-\u044F\u0451]+):\s/gi;
  61. while ((match = cr.exec(source)) != null) {
  62. captions.push({ Index: cr.lastIndex, Value: match[0].toString() });
  63. }
  64. var getCaption = function (index) {
  65. for (var ii = captions.length - 1; ii >= 0; ii--) {
  66. if (captions[ii].Index < index) {
  67. return captions[ii].Value;
  68. }
  69. }
  70. return null;
  71. }
  72.  
  73. var result = [];
  74. var sr = /(?:\s|>)(\d+)(<\/b>|<\/a>)?\s\((\d+(?:\.\d+)?)\)/g;
  75. while ((match = sr.exec(source)) != null) {
  76. result.push({
  77. Caption: getCaption(sr.lastIndex),
  78. Level: +match[1].toString(),
  79. Score: +match[3].toString(),
  80. Sign: match[2]
  81. });
  82. }
  83. return result;
  84. }
  85.  
  86. function addStyles() {
  87. var style = document.createElement('style');
  88. style.type = 'text/css';
  89. style.appendChild(document.createTextNode(Styles));
  90. document.head.appendChild(style);
  91. }
  92.  
  93. function checkScale(scale) {
  94. if (scale && scale.length > 0) {
  95. if (scale.length > 1) {
  96. for (var ii = 1; ii < scale.length; ii++) {
  97. if (scale[ii] <= scale[ii - 1]) {
  98. return false;
  99. }
  100. }
  101. }
  102. return true;
  103. }
  104. }
  105.  
  106. function createProgressBar(points, left, percentage) {
  107. var percentageString = Math.floor(percentage) + '%';
  108.  
  109. var border = document.createElement('div');
  110. border.className = 'pb';
  111.  
  112. var scale = document.createElement('div');
  113. scale.className = 'scale';
  114. scale.style.width = percentageString;
  115. border.appendChild(scale);
  116.  
  117. var textBox = document.createElement('div');
  118. textBox.className = 'pb-text';
  119.  
  120. var frontText = document.createElement('span');
  121. frontText.className = 'pb-front-text';
  122. frontText.appendChild(document.createTextNode(percentageString));
  123. textBox.appendChild(frontText);
  124.  
  125. var sideText = document.createElement('span');
  126. sideText.className = 'pb-side-text';
  127. sideText.appendChild(document.createTextNode(points));
  128.  
  129. var l = document.createElement('span');
  130. l.className = 'left';
  131. l.appendChild(document.createTextNode('+' + left));
  132. sideText.appendChild(l);
  133. textBox.appendChild(sideText);
  134.  
  135. border.appendChild(textBox);
  136. return border;
  137. }
  138.  
  139. function getScoreRange(score, scale) {
  140. if (!checkScale(scale)) {
  141. return;
  142. }
  143.  
  144. var initialValue = 0;
  145. var finalValue = score;
  146. var level = 0;
  147. for (var ii = 0; ii < scale.length; ii++) {
  148. if (score >= scale[ii]) {
  149. initialValue = scale[ii];
  150. }
  151. else {
  152. finalValue = scale[ii];
  153. level = ii;
  154. break;
  155. }
  156. }
  157. return { Initial: initialValue, Final: finalValue, Level: level };
  158. }
  159.  
  160. function getProgressPercentage(range, score) {
  161. if (range) {
  162. return (score - range.Initial) * 100 / (range.Final - range.Initial);
  163. }
  164. return 0;
  165. }
  166.  
  167. function getScale(index) {
  168. return Scales[index];
  169. }
  170.  
  171. function getCaption(value, exclude) {
  172. if (exclude) {
  173. var r = new RegExp(exclude, 'i');
  174. return value.Caption.replace(r, '');
  175. }
  176. return value.Caption;
  177. }
  178.  
  179. function createRow(value, scaleIndex, excludeCaption) {
  180. var scale = getScale(scaleIndex);
  181. var range = getScoreRange(value.Score, scale);
  182. if (!range) {
  183. alert(JSON.stringify(value) + ' : ' + scaleIndex + ' - ' + excludeCaption);
  184. }
  185.  
  186. var row = document.createElement('tr');
  187. var c1 = document.createElement('td');
  188. c1.className = 'key-column';
  189. if (scaleIndex == 1 && value.Sign) {
  190. c1.style = 'font-weight: bold; text-decoration:underline; ';
  191. }
  192. c1.appendChild(document.createTextNode(getCaption(value, excludeCaption)));
  193. var lb = document.createElement('b');
  194. lb.className = 'skill-value';
  195. lb.appendChild(document.createTextNode(value.Level));
  196. if (value.Score >= range.Final) {
  197. lb.className = 'skill-value-complete';
  198. }
  199. else if (!value.Score) {
  200. lb.className = 'skill-value-none';
  201. }
  202. c1.appendChild(lb);
  203. row.appendChild(c1);
  204. var c2 = document.createElement('td');
  205. c2.className = 'progress-column';
  206. if (value.Score == 0) {
  207. c2.appendChild(document.createTextNode('-'));
  208. }
  209. else if (value.Score >= range.Final) {
  210. c2.appendChild(document.createTextNode(value.Score));
  211. }
  212. else {
  213. var percentage = getProgressPercentage(range, value.Score);
  214.  
  215. var points = value.Score;
  216. var left = round(range.Final - value.Score, 1);
  217.  
  218. if (range.Level > value.Level) {
  219. percentage = 100;
  220. left = '0.1';
  221. var rl = document.createElement('small');
  222. rl.innerHTML = -(range.Level - value.Level);
  223. lb.className = 'skill-value-low';
  224. c1.appendChild(rl);
  225. }
  226. var pb = createProgressBar(points, left, percentage);
  227. c2.appendChild(pb);
  228. }
  229. row.appendChild(c2);
  230. return row;
  231. }
  232.  
  233. function createExpanderButton() {
  234. var cb = document.createElement('input');
  235. cb.type = 'button';
  236. cb.value = expandCaption;
  237. cb.className = 'expander';
  238. cb.collapsed = true;
  239. cb.onclick = function (event) {
  240. var r = this.parentNode.parentNode;
  241. var display = this.collapsed ? '' : 'none';
  242. r.nextSibling.style.display = display;
  243. r.nextSibling.nextSibling.style.display = display;
  244. r.nextSibling.nextSibling.nextSibling.style.display = display;
  245. this.collapsed = !this.collapsed;
  246. this.value = this.collapsed ? expandCaption : collapseCaption;
  247. };
  248. return cb;
  249. }
  250.  
  251. function insertExpander(table) {
  252. var row = table.lastChild;
  253. for (var ii = 0; ii < 3; ii++) {
  254. row.firstChild.style = 'padding-left: 15px;';
  255. row.style.display = 'none';
  256. row = row.previousSibling;
  257. }
  258. row.firstChild.appendChild(createExpanderButton());
  259. }
  260.  
  261. function isEn() {
  262. return /^www\.lordswm\.com/.test(location.host);
  263. }
  264.  
  265. function replaceSkills() {
  266. var home = document.getElementById('home_2');
  267. if (home) {
  268. var createSkillTable = function(caption) {
  269. var result = document.createElement('table');
  270. result.className = 'skill-table';
  271. var cpt = document.createElement('caption');
  272. cpt.appendChild(document.createTextNode(caption));
  273. result.appendChild(cpt);
  274. return result;
  275. }
  276.  
  277. var mainNode = home.parentNode;
  278. var items = parseSourceCode(mainNode.innerHTML.toString());
  279.  
  280. var range = document.createRange();
  281. range.selectNodeContents(mainNode);
  282. range.deleteContents();
  283.  
  284. var t = createSkillTable(isEn() ? 'Factions' : factionsGroupTitleRU);
  285. var excludeCaption;
  286. var ii = 0;
  287. var gi = 0;
  288. var faction = true;
  289. var factionPoints = 0;
  290. do {
  291. if (faction && (~items[ii].Caption.indexOf(isEn() ? 'guild' : '\u0413\u0438\u043B\u044C\u0434\u0438\u044F'))) {
  292. faction = false;
  293. gi = ii;
  294. var sum = document.createElement('span');
  295. sum.appendChild(document.createTextNode(' \u03A3'));
  296. var sub = document.createElement('sub');
  297. sub.appendChild(document.createTextNode(isEn() ? 'all' : allRu));
  298. sum.appendChild(sub);
  299. sum.appendChild(document.createTextNode('= ' + round(factionPoints, 2)));
  300. t.firstChild.appendChild(sum);
  301. mainNode.appendChild(t);
  302. t = createSkillTable(isEn() ? 'Guilds' : guildsGroupTitleRU);
  303. excludeCaption = "('\\sguild)|(" + guildsGroupTitleRU + ')';
  304. mainNode.appendChild(t);
  305. }
  306. if (faction) {
  307. factionPoints += items[ii].Score;
  308. }
  309. t.appendChild(createRow(items[ii], (faction ? 1 : Math.min(Scales.length - 1, (ii - gi) + 2)), excludeCaption));
  310. ii++;
  311. }
  312. while (ii < items.length - 2);
  313. insertExpander(t);
  314. mainNode.appendChild(t);
  315. }
  316. }
  317.  
  318. function getLevelPoints(points) {
  319. var r = /\(([\d\,]+)\)(?:\s\+(-?[\d\,]+))?/;
  320. var m = r.exec(points)
  321. if (m) {
  322. return { Points: m[1].replace(/,/g, ''), Left: (m[2] ? m[2].replace(/,/g, '') : 0) }
  323. }
  324. }
  325.  
  326. function insertLevelUpProgressBar() {
  327. var bs = document.getElementsByTagName('b');
  328. var lbReg = new RegExp('(?:Combat\\slevel|' + levelStringRU + '):\\s(\\d+)');
  329. for (var ii = 0; ii < bs.length; ii++) {
  330. var b = bs[ii];
  331. var m = lbReg.exec(b.innerHTML);
  332. if (m) {
  333. var start = b.nextSibling;
  334. var end = start;
  335. do {
  336. end = end.nextSibling;
  337. }
  338. while (end && (!end.tagName || end.tagName.toLowerCase() != 'br'));
  339. var next = end.nextSibling;
  340. if (end) {
  341. var pointsText;
  342. var range = document.createRange();
  343. range.setStart(start, 0);
  344. range.setEnd(end, 0);
  345. pointsText = range.toString();
  346. var lvl = getLevelPoints(range.toString());
  347. if (lvl) {
  348. var r = getScoreRange(lvl.Points, getScale(0));
  349. if (r && r.Final > lvl.Points) {
  350. var percentage = getProgressPercentage(r, lvl.Points);
  351. if (r.Level > m[1]) {
  352. b.appendChild(document.createTextNode('+'));
  353. percentage = 100;
  354. }
  355. var pb = createProgressBar(lvl.Points, lvl.Left, percentage);
  356. pb.className += ' levelpb';
  357. b.parentNode.insertBefore(pb, b.nextSibling);
  358. range.deleteContents();
  359. }
  360. }
  361. range.detach();
  362. break;
  363. }
  364. }
  365. }
  366. }
  367.  
  368. addStyles(); insertLevelUpProgressBar(); replaceSkills();