// ==UserScript==
// @name LWM_ProgressBars
// @description Insert level & skill progress bars to home page & player info page.
// @namespace saturn_hwm
// @author saturn573
// @homepage http://gf.qytechs.cn/scripts/2892-lwm-progressbars
// @include http://178.248.235.15/home.php
// @include http://*.lordswm.com/home.php
// @include http://*.heroeswm.ru/home.php
// @include http://178.248.235.15/pl_info.php?id=*
// @include http://*.lordswm.com/pl_info.php?id=*
// @include http://*.heroeswm.ru/pl_info.php?id=*
// @version 0.19
// @grant none
var Scales = [
[0, 1500, 4500, 15000, 32000, 90000, 190000, 400000, 860000, 1650000, 3000000, 5000000, 8500000, 14500000, 25000000, 43000000, 70000000, 108000000, 160000000, 230000000, 325000000],
[20, 50, 90, 160, 280, 500, 900, 1600, 2900, 5300, 9600, 17300],
[16, 60, 180, 400, 700, 1200, 2000, 3000, 4300, 6000, 8000, 10500],
[90, 180, 360, 720, 1500, 3000, 5000, 8000, 12000, 17000, 23000, 30000, 38000, 47000, 57000],
[10, 30, 60, 100, 150, 210, 280, 360, 450, 550, 660, 800, 1000, 1300, 2000],
[50, 120, 240, 400, 600, 840, 1200, 2000, 3000, 4300, 6000, 8000, 10800, 14000, 17600],
[100, 240, 480, 800, 1200, 1680, 2400, 4000, 6000, 8600],
[50, 120, 300, 600, 1000, 1500, 2200, 3000, 4000, 5500, 7800, 11000, 14500, 18200, 22200],
[150, 350, 750, 1400, 2200, 4000, 6000],
[30, 80, 165, 310, 555, 970, 1680, 2885, 5770],
[104, 588, 2200, 7000, 10000],
[8, 29, 71, 155, 295, 505, 799, 1191, 1695, 6000, 12000]
];
var factionCount = 9;
var Styles = '.pb{ display:inline-block; position: relative; width:135px; background:white; border:2px solid; border-radius: 7px/3px; cursor: pointer; }\
.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); }\
.pb:hover .pb-side-text { display: inline; }\
.pb:hover .pb-front-text { display: none; }\
.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; }\
.pb-side-text { display:none; }\
.pb-front-text { display: inline; }\
.left { font-size: smaller; }\
.levelpb { display: inline-flex; margin-left: 10px; width: 180px; } \
.skill-table { width: 100%; margin-bottom: 10px; }\
.skill-table caption { text-align: left; }\
.skill-table caption span { float: right; font-size: small; margin-right: 10; }\
.key-column { text-align: left; width: 100%; font-variant: small-caps; }\
.skill-value { font-size: 15px; }\
.skill-value-complete { color: #af9f39; font-size: 20px; font-weight: bold; font-family: "Comic Sans MS", cursive, sans-serif; }\
.skill-value-none { font-weight: normal; }\
.skill-value-low { color: blue; }\
.progress-column { text-align: center; width: 135px; }\
.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; }';
var expandCaption = '>';
var collapseCaption = '<';
var levelStringRU = '\u0411\u043E\u0435\u0432\u043E\u0439 \u0443\u0440\u043E\u0432\u0435\u043D\u044C';
var factionsGroupTitleRU = '\u0424\u0440\u0430\u043A\u0446\u0438\u044F';
var guildsGroupTitleRU = '\u0413\u0438\u043B\u044C\u0434\u0438\u044F';
function round(value, precision)
{
if (precision > 0)
{
var b = precision * 10;
return Math.round(value * b) / b;
}
else
{
return Math.floor(value);
}
}
function parseSourceCode(source)
{
var captions = [];
var match;
var cr = /((?:[a-z'\u0430-\u044F\u0451]+\s)?[a-z\u0430-\u044F\u0451]+):\s/gi;
while ((match = cr.exec(source)) != null)
{
captions.push({ Index: cr.lastIndex, Value: match[0].toString() });
}
var getCaption = function(index)
{
for (var ii = captions.length - 1; ii>= 0; ii--)
{
if (captions[ii].Index < index)
{
return captions[ii].Value;
}
}
return null;
}
var result = [];
var sr = /(?:\s|>)(\d+)(<\/b>|<\/a>)?\s\((\d+(?:\.\d+)?)\)/g;
while((match = sr.exec(source)) != null)
{
result.push({
Caption: getCaption(sr.lastIndex),
Level: +match[1].toString(),
Score: +match[3].toString(),
Sign: match[2]
});
}
return result;
}
function addStyles()
{
var style = document.createElement('style');
style.type = 'text/css';
style.appendChild(document.createTextNode(Styles));
document.head.appendChild(style);
}
function checkScale(scale)
{
if (scale && scale.length > 0)
{
if (scale.length > 1)
{
for (var ii = 1; ii < scale.length; ii++)
{
if (scale[ii] <= scale[ii - 1])
{
return false;
}
}
}
return true;
}
}
function createProgressBar(points, left, percentage)
{
var percentageString= percentage.toFixed(0) + '%';
var border = document.createElement('div');
border.className = 'pb';
var scale = document.createElement('div');
scale.className = 'scale';
scale.style.width = percentageString;
border.appendChild(scale);
var textBox = document.createElement('div');
textBox.className = 'pb-text';
var frontText = document.createElement('span');
frontText.className = 'pb-front-text';
frontText.appendChild(document.createTextNode(percentageString));
textBox.appendChild(frontText);
var sideText = document.createElement('span');
sideText.className = 'pb-side-text';
sideText.appendChild(document.createTextNode(points));
var l = document.createElement('span');
l.className= 'left';
l.appendChild(document.createTextNode('+' + left));
sideText.appendChild(l);
textBox.appendChild(sideText);
border.appendChild(textBox);
return border;
}
function getScoreRange(score, scale)
{
if (!checkScale(scale))
{
return;
}
var initialValue = 0;
var finalValue = score;
var level = 0;
for (var ii = 0; ii < scale.length; ii++)
{
if (score >= scale[ii])
{
initialValue = scale[ii];
}
else
{
finalValue = scale[ii];
level = ii;
break;
}
}
return { Initial: initialValue, Final: finalValue, Level: level };
}
function getProgressPercentage(range, score)
{
if (range)
{
return (score - range.Initial) * 100 / (range.Final - range.Initial);
}
return 0;
}
function getScale(index)
{
return Scales[index];
}
function getCaption(value, exclude)
{
if (exclude)
{
var r = new RegExp(exclude, 'i');
return value.Caption.replace(r, '');
}
return value.Caption;
}
function createRow(value, scaleIndex, excludeCaption)
{
var scale = getScale(scaleIndex);
var range = getScoreRange(value.Score, scale);
var row = document.createElement('tr');
var c1 = document.createElement('td');
c1.className = 'key-column';
if (scaleIndex == 1 && value.Sign)
{
c1.style = 'font-weight: bold; text-decoration:underline; ';
}
c1.appendChild(document.createTextNode(getCaption(value, excludeCaption)));
var lb = document.createElement('b');
lb.className = 'skill-value';
lb.appendChild(document.createTextNode(value.Level));
if (value.Score >= range.Final)
{
lb.className = 'skill-value-complete';
}
else if (!value.Score)
{
lb.className = 'skill-value-none';
}
c1.appendChild(lb);
row.appendChild(c1);
var c2 = document.createElement('td');
c2.className = 'progress-column';
if (value.Score == 0)
{
c2.appendChild(document.createTextNode('-'));
}
else if (value.Score >= range.Final)
{
c2.appendChild(document.createTextNode(value.Score));
}
else
{
var percentage = getProgressPercentage(range, value.Score);
var points = value.Score;
var left = round(range.Final - value.Score, 1);
if (range.Level > value.Level)
{
percentage = 100;
left = '0.1';
var rl = document.createElement('small');
rl.innerHTML = - (range.Level - value.Level);
lb.className = 'skill-value-low';
c1.appendChild(rl);
}
var pb = createProgressBar(points, left, percentage);
c2.appendChild(pb);
}
row.appendChild(c2);
return row;
}
function createExpanderButton()
{
var cb = document.createElement('input');
cb.type = 'button';
cb.value = expandCaption;
cb.className = 'expander';
cb.collapsed = true;
cb.onclick = function(event)
{
var r = this.parentNode.parentNode;
var display = this.collapsed ? '' : 'none';
r.nextSibling.style.display = display;
r.nextSibling.nextSibling.style.display = display;
r.nextSibling.nextSibling.nextSibling.style.display = display;
this.collapsed = !this.collapsed;
this.value = this.collapsed ? expandCaption : collapseCaption;
};
return cb;
}
function insertExpander(table)
{
var row = table.lastChild;
for (var ii = 0; ii < 3; ii++)
{
row.firstChild.style = 'padding-left: 15px;';
row.style.display = 'none';
row = row.previousSibling;
}
row.firstChild.appendChild(createExpanderButton());
}
function getScaleIndex(index)
{
if (index < factionCount)
{
return 1;
}
var result = index - factionCount + 2;
if (result >= Scales.length)
{
result = Scales.length - 1;
}
return result;
}
function isEn()
{
return /^www\.lordswm\.com/.test(location.host);
}
function createSkillTable(caption)
{
var result = document.createElement('table');
result.className = 'skill-table';
var cpt = document.createElement('caption');
cpt.appendChild(document.createTextNode(caption));
result.appendChild(cpt);
return result;
}
function replaceSkills()
{
var home = document.getElementById('home_2');
if (home)
{
var mainNode = home.parentNode;
var items = parseSourceCode(mainNode.innerHTML.toString());
var range = document.createRange();
range.selectNodeContents(mainNode);
range.deleteContents();
range.detach();
var t = createSkillTable(isEn() ? 'Factions' : factionsGroupTitleRU);
var excludeCaption;
var ii = 0;
var factionPoints = 0;
do
{
if (ii < factionCount)
{
factionPoints += items[ii].Score
}
t.appendChild(createRow(items[ii], getScaleIndex(ii), excludeCaption));
ii++;
if (ii == factionCount)
{
var sum = document.createElement('span');
sum.appendChild(document.createTextNode(' \u03A3'));
var sub = document.createElement('sub');
sub.appendChild(document.createTextNode(isEn() ? 'all' : 'общ.'));
sum.appendChild(sub);
sum.appendChild(document.createTextNode('= ' + round(factionPoints, 2)));
t.firstChild.appendChild(sum);
mainNode.appendChild(t);
t = createSkillTable(isEn() ? 'Guilds' : guildsGroupTitleRU);
excludeCaption = "('\\sguild)|(" + guildsGroupTitleRU + ')';
}
}
while (ii < items.length - 2);
insertExpander(t);
mainNode.appendChild(t);
}
}
function getLevelPoints(points)
{
var r = /\(([\d\,]+)\)(?:\s\+(-?[\d\,]+))?/;
var m = r.exec(points)
if (m)
{
return { Points: m[1].replace(/,/g, ''), Left: m[2].replace(/,/g, '') }
}
}
function insertLevelUpProgressBar()
{
var bs= document.getElementsByTagName('b');
var lbReg = new RegExp('(?:Combat\\slevel|' + levelStringRU + '):\\s(\\d+)');
for (var ii = 0; ii < bs.length; ii++)
{
var b = bs[ii];
var m = lbReg.exec(b.innerHTML);
if (m)
{
var start = b.nextSibling;
var end = start;
do
{
end = end.nextSibling;
}
while (end && (!end.tagName || end.tagName.toLowerCase() != 'br'));
var next = end.nextSibling;
if (end)
{
var pointsText;
var range = document.createRange();
range.setStart(start, 0);
range.setEnd(end, 0);
pointsText = range.toString();
var lvl = getLevelPoints(range.toString());
if (lvl)
{
var r = getScoreRange(lvl.Points, getScale(0));
if (r && r.Final > lvl.Points)
{
var percentage = getProgressPercentage(r, lvl.Points);
if (r.Level > m[1])
{
b.appendChild(document.createTextNode('+'));
percentage = 100;
}
var pb = createProgressBar(lvl.Points, lvl.Left, percentage);
pb.className += ' levelpb';
b.parentNode.insertBefore(pb, b.nextSibling);
range.deleteContents();
}
}
range.detach();
break;
}
}
}
}
function main()
{
addStyles();
insertLevelUpProgressBar();
replaceSkills();
}
main();
// ==/UserScript==