LWM_ProgressBars

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

目前為 2014-06-30 提交的版本,檢視 最新版本

  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 (saturn573@gmail.com)
  6. // @include http://178.248.235.15/home.php
  7. // @include http://*.lordswm.com/home.php
  8. // @include http://*.heroeswm.ru/home.php
  9. // @include http://178.248.235.15/pl_info.php?id=*
  10. // @include http://*.lordswm.com/pl_info.php?id=*
  11. // @include http://*.heroeswm.ru/pl_info.php?id=*
  12. // @version 0.1
  13. // @grant none
  14.  
  15. var Scales = [
  16. [0, 1500, 4500, 15000, 32000, 90000, 190000, 400000, 860000, 1650000, 3000000, 5000000, 8500000, 14500000, 25000000, 43000000, 70000000, 108000000, 160000000, 230000000, 325000000],
  17. [20, 50, 90, 160, 280, 500, 900, 1600, 2900, 5300, 9600, 17300],
  18. [16, 60, 180, 400, 700, 1200, 2000, 3000, 4300, 6000, 8000, 10500],
  19. [90, 180, 360, 720, 1500, 3000, 5000, 8000, 12000, 17000, 23000, 30000, 38000, 47000],
  20. [10, 30, 60, 100, 150, 210, 280, 360, 450, 550, 660, 800, 1000, 1300, 2000],
  21. [50, 120, 240, 400, 600, 840, 1200, 2000, 3000, 4300, 6000, 8000, 10800, 14000],
  22. [100, 240, 480, 800, 1200, 1680, 2400, 4000, 6000, 8600],
  23. [50, 120, 300, 600, 1000, 1500, 2200, 3000, 4000, 5500, 7800, 11000],
  24. [150, 350, 750, 1400, 2200, 4000],
  25. [30, 80, 165, 310, 555, 970, 1680, 2885, 5770],
  26. [104, 588, 2200, 7000, 10000],
  27. [8, 29, 71, 155, 295, 505, 799, 1191, 1695, 6000, 12000]
  28. ];
  29.  
  30. var factionCount = 9;
  31.  
  32. var Styles = '.pb{ display:inline-block; width:135px; height:16px; background:white; border:2px solid; border-radius: 7px/3px; cursor: pointer; }\
  33. .pb div { height: 100%; border-radius: 2px/1px; background: lightblue; background: linear-gradient(to top, #af9f39, #fffbca); }\
  34. .pb div:hover .mf { opacity: 1; }\
  35. .pb div:hover .sf { opacity: 0; }\
  36. .pbc { display:block; position: relative; width: 135px; text-align: center; color: darkgreen;\
  37. font-size: 12px; font-weight: bold; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }\
  38. .mf { opacity:0; top: 1px; }\
  39. .sf { opacity:1; top: -14px; }\
  40. .sc1 { text-align: left; width: 100%; font-variant: small-caps; }\
  41. .sc1 b { font-size: 15px; }\
  42. .bf { color: #af9f39; font-size: 20px; font-weight: bold; font-family: "Comic Sans MS", cursive, sans-serif; }\
  43. .bi { font-weight: normal; }\
  44. .sc2 { text-align: center; width: 135px; }\
  45. .sch { text-align: left; font-weight: bold; padding: 3px; }\
  46. .bfr { color: blue; }\
  47. .cdi { margin-left: 5px; border-radius: 8px; height: 16px; width: 16px; font-size: 8px;\
  48. font-weight:bold; background: gold; background: linear-gradient(to top, #af9f39, #fffbca);\
  49. border: #af9f39; border-style: outset; border-width: 1px; position: relative; top: -3px; }\
  50. .levelpb { display: inline-flex; margin-left: 10px; width: 180px; } \
  51. .levelpb div .mf { width: 180px; }\
  52. .levelpb div .sf { width: 180px; }';
  53.  
  54. var expandCaption = '>';
  55. var collapseCaption = '<';
  56. var levelStringRU = '\u0411\u043E\u0435\u0432\u043E\u0439 \u0443\u0440\u043E\u0432\u0435\u043D\u044C';
  57. var factionsGroupTitleRU = '\u0424\u0440\u0430\u043A\u0446\u0438\u044F';
  58. var guildsGroupTitleRU = '\u0413\u0438\u043B\u044C\u0434\u0438\u044F';
  59. var pointsLeftPrefixString = '\u041E\u0441\u0442\u0430\u043B\u043E\u0441\u044C';
  60.  
  61. function round(value, precision)
  62. {
  63. if (precision > 0)
  64. {
  65. var b = precision * 10;
  66. return Math.round(value * b) / b;
  67. }
  68. else
  69. {
  70. return Math.floor(value);
  71. }
  72. }
  73.  
  74. function parseSourceCode(source)
  75. {
  76. var captions = [];
  77. var match;
  78. var cr = /((?:[a-z'\u0430-\u044F\u0451]+\s)?[a-z\u0430-\u044F\u0451]+):\s/gi;
  79. while ((match = cr.exec(source)) != null)
  80. {
  81. captions.push({ Index: cr.lastIndex, Value: match[0].toString() });
  82. }
  83. var getCaption = function(index)
  84. {
  85. for (var ii = captions.length - 1; ii>= 0; ii--)
  86. {
  87. if (captions[ii].Index < index)
  88. {
  89. return captions[ii].Value;
  90. }
  91. }
  92. return null;
  93. }
  94. var result = [];
  95. var sr = /(?:\s|>)(\d+)(<\/b>|<\/a>)?\s\((\d+(?:\.\d+)?)\)/gm;
  96. while((match = sr.exec(source)) != null)
  97. {
  98. result.push({
  99. Caption: getCaption(sr.lastIndex),
  100. Level: +match[1].toString(),
  101. Score: +match[3].toString(),
  102. Sign: match[2]
  103. });
  104. }
  105. return result;
  106. }
  107. function addStyles()
  108. {
  109. var style = document.createElement('style');
  110. style.type = 'text/css';
  111. style.appendChild(document.createTextNode(Styles));
  112. document.head.appendChild(style);
  113. }
  114.  
  115. function checkScale(scale)
  116. {
  117. if (scale && scale.length > 0)
  118. {
  119. if (scale.length > 1)
  120. {
  121. for (var ii = 1; ii < scale.length; ii++)
  122. {
  123. if (scale[ii] <= scale[ii - 1])
  124. {
  125. return false;
  126. }
  127. }
  128. }
  129. return true;
  130. }
  131. }
  132.  
  133. function createProgressBar(points, left, percentage)
  134. {
  135. var border = document.createElement('div');
  136. border.className = 'pb';
  137. //border.title = percentage.toFixed(3) + '%';
  138. var scale = document.createElement('div');
  139. scale.style.width = percentage.toFixed(0) + '%';
  140. var mainFont = document.createElement('font');
  141. mainFont.className = 'pbc mf';
  142. mainFont.appendChild(document.createTextNode(points));
  143. var l = document.createElement('small');
  144. l.appendChild(document.createTextNode('+' + left));
  145. mainFont.appendChild(l);
  146. scale.appendChild(mainFont);
  147. var sideFont = document.createElement('font');
  148. sideFont.className = 'pbc sf';
  149. sideFont.appendChild(document.createTextNode(scale.style.width));
  150. scale.appendChild(sideFont);
  151. border.appendChild(scale);
  152. return border;
  153. }
  154.  
  155. function getScoreRange(score, scale)
  156. {
  157. if (!checkScale(scale))
  158. {
  159. return;
  160. }
  161. var initialValue = 0;
  162. var finalValue = score;
  163. var level = 0;
  164. for (var ii = 0; ii < scale.length; ii++)
  165. {
  166. if (score >= scale[ii])
  167. {
  168. initialValue = scale[ii];
  169. }
  170. else
  171. {
  172. finalValue = scale[ii];
  173. level = ii;
  174. break;
  175. }
  176. }
  177. return { Initial: initialValue, Final: finalValue, Level: level };
  178. }
  179.  
  180. function getScoreLost(range, score)
  181. {
  182. return Math.round((range.Final - score)*100)/100;
  183. }
  184.  
  185. function getProgressPercentage(range, score)
  186. {
  187. if (range)
  188. {
  189. return (score - range.Initial) * 100 / (range.Final - range.Initial);
  190. }
  191. return 0;
  192. }
  193.  
  194. function getScale(index)
  195. {
  196. return Scales[index];
  197. }
  198.  
  199. function getCaption(value, exclude)
  200. {
  201. if (exclude)
  202. {
  203. var r = new RegExp(exclude, 'i');
  204. return value.Caption.replace(r, '');
  205. }
  206. return value.Caption;
  207. }
  208.  
  209. function createRow(value, scaleIndex, excludeCaption)
  210. {
  211. var scale = getScale(scaleIndex);
  212. var range = getScoreRange(value.Score, scale);
  213. var row = document.createElement('tr');
  214. var c1 = document.createElement('td');
  215. c1.className = 'sc1';
  216. if (scaleIndex == 1 && value.Sign)
  217. {
  218. c1.style = 'font-weight: bold; text-decoration:underline; ';
  219. }
  220. c1.appendChild(document.createTextNode(getCaption(value, excludeCaption)));
  221. var lb = document.createElement('b');
  222. lb.innerHTML = value.Level;
  223. if (value.Score >= range.Final)
  224. {
  225. lb.className = 'bf';
  226. }
  227. else if (!value.Score)
  228. {
  229. lb.className = 'bi';
  230. }
  231. c1.appendChild(lb);
  232. row.appendChild(c1);
  233. var c2 = document.createElement('td');
  234. c2.className = 'sc2';
  235. if (value.Score == 0)
  236. {
  237. c2.appendChild(document.createTextNode('-'));
  238. }
  239. else if (value.Score >= range.Final)
  240. {
  241. c2.appendChild(document.createTextNode(value.Score));
  242. }
  243. else
  244. {
  245. var percentage = getProgressPercentage(range, value.Score);
  246. var points = value.Score;
  247. var left = round(range.Final - value.Score, 1);
  248. if (range.Level > value.Level)
  249. {
  250. percentage = 100;
  251. left = '0.1';
  252. var rl = document.createElement('small');
  253. rl.innerHTML = - (range.Level - value.Level);
  254. lb.className = 'bfr';
  255. c1.appendChild(rl);
  256. }
  257. var pb = createProgressBar(points, left, percentage);
  258. c2.appendChild(pb);
  259. }
  260. row.appendChild(c2);
  261. return row;
  262. }
  263.  
  264. function createHeadRow(title)
  265. {
  266. var result = document.createElement('tr');
  267. var cell = document.createElement('td');
  268. cell.colSpan = 2;
  269. cell.appendChild(document.createTextNode(title));
  270. cell.className = 'sch';
  271. result.appendChild(cell);
  272. return result;
  273. }
  274.  
  275. function createExpanderButton()
  276. {
  277. var cb = document.createElement('input');
  278. cb.type = 'button';
  279. cb.value = expandCaption;
  280. cb.className = 'cdi';
  281. cb.collapsed = true;
  282. cb.onclick = function(event)
  283. {
  284. var r = this.parentNode.parentNode;
  285. var display = this.collapsed ? '' : 'none';
  286. r.nextSibling.style.display = display;
  287. r.nextSibling.nextSibling.style.display = display;
  288. r.nextSibling.nextSibling.nextSibling.style.display = display;
  289. this.collapsed = !this.collapsed;
  290. this.value = this.collapsed ? expandCaption : collapseCaption;
  291. };
  292. return cb;
  293. }
  294.  
  295. function insertExpander(table)
  296. {
  297. var row = table.lastChild;
  298. for (var ii = 0; ii < 3; ii++)
  299. {
  300. row.firstChild.style = 'padding-left: 15px;';
  301. row.style.display = 'none';
  302. row = row.previousSibling;
  303. }
  304. row.firstChild.appendChild(createExpanderButton());
  305. }
  306.  
  307. function getScaleIndex(index)
  308. {
  309. if (index < factionCount)
  310. {
  311. return 1;
  312. }
  313. var result = index - factionCount + 2;
  314. if (result >= Scales.length)
  315. {
  316. result = Scales.length - 1;
  317. }
  318. return result;
  319. }
  320.  
  321. function isEn()
  322. {
  323. return /^www\.lordswm\.com/.test(location.host);
  324. }
  325.  
  326. function replaceSkills()
  327. {
  328. var home = document.getElementById('home_2');
  329. if (home)
  330. {
  331. var mainNode = home.parentNode;
  332. var items = parseSourceCode(mainNode.innerHTML.toString());
  333. var range = document.createRange();
  334. range.selectNodeContents(mainNode);
  335. range.deleteContents();
  336. range.detach();
  337. var t = document.createElement('table');
  338. t.appendChild(createHeadRow(isEn() ? 'Factions' : factionsGroupTitleRU));
  339. t.style.width = "100%";
  340. var excludeCaption;
  341. var ii = 0;
  342. do
  343. {
  344. t.appendChild(createRow(items[ii], getScaleIndex(ii), excludeCaption));
  345. ii++;
  346. if (ii == factionCount)
  347. {
  348. t.appendChild(createHeadRow(isEn() ? 'Guilds' : factionsGroupTitleRU));
  349. excludeCaption = "('\\sguild)|(" + guildsGroupTitleRU + ')';
  350. }
  351. }
  352. while (ii < items.length - 2);
  353. insertExpander(t);
  354. mainNode.appendChild(t);
  355. }
  356. }
  357.  
  358. function getLevelPoints(points)
  359. {
  360. var r = /\(([\d\.]+)\)(?:\s\+(-?[\d\.]+))?/;
  361. var m = r.exec(points)
  362. if (m)
  363. {
  364. return { Points: m[1], Left: m[2] }
  365. }
  366. }
  367.  
  368. function insertLevelUpProgressBar()
  369. {
  370. var bs= document.getElementsByTagName('b');
  371. var lbReg = new RegExp('(?:Combat\\slevel|' + levelStringRU + '):\\s(\\d+)');
  372. for (var ii = 0; ii < bs.length; ii++)
  373. {
  374. var b = bs[ii];
  375. var m = lbReg.exec(b.innerHTML);
  376. if (m)
  377. {
  378. var start = b.nextSibling;
  379. var end = start;
  380. do
  381. {
  382. end = end.nextSibling;
  383. }
  384. while (end && (!end.tagName || end.tagName.toLowerCase() != 'br'));
  385. var next = end.nextSibling;
  386. if (end)
  387. {
  388. var pointsText;
  389. var range = document.createRange();
  390. range.setStart(start, 0);
  391. range.setEnd(end, 0);
  392. pointsText = range.toString();
  393. var lvl = getLevelPoints(range.toString());
  394. if (lvl)
  395. {
  396. var r = getScoreRange(lvl.Points, getScale(0));
  397. if (r && r.Final > lvl.Points)
  398. {
  399. var percentage = getProgressPercentage(r, lvl.Points);
  400. if (r.Level > m[1])
  401. {
  402. b.appendChild(document.createTextNode('+'));
  403. percentage = 100;
  404. }
  405. var pb = createProgressBar(lvl.Points, lvl.Left, percentage);
  406. pb.className += ' levelpb';
  407. b.parentNode.insertBefore(pb, b.nextSibling);
  408. range.deleteContents();
  409. }
  410. }
  411. range.detach();
  412. break;
  413. }
  414. }
  415. }
  416. }
  417.  
  418. function main()
  419. {
  420. addStyles();
  421. insertLevelUpProgressBar();
  422. replaceSkills();
  423. }
  424.  
  425. main();
  426.  
  427. // ==/UserScript==