LWM_ProgressBars

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

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

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name        LWM_ProgressBars
// @description Insert level & skill progress bars to home page & player info page.
// @namespace   saturn_hwm
// @author		saturn573 ([email protected])
// @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.1
// @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],
	[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],
	[100, 240, 480, 800, 1200, 1680, 2400, 4000, 6000, 8600],
	[50, 120, 300, 600, 1000, 1500, 2200, 3000, 4000, 5500, 7800, 11000],
	[150, 350, 750, 1400, 2200, 4000],
	[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; width:135px; height:16px; background:white; border:2px solid; border-radius: 7px/3px; cursor: pointer; }\
	.pb div { height: 100%; border-radius: 2px/1px; background: lightblue; background: linear-gradient(to top, #af9f39, #fffbca); }\
	.pb div:hover .mf { opacity: 1; }\
	.pb div:hover .sf { opacity: 0; }\
	.pbc { display:block; position: relative; width: 135px; text-align: center; color: darkgreen;\
		font-size: 12px; font-weight: bold; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }\
	.mf { opacity:0; top: 1px; }\
	.sf { opacity:1; top: -14px; }\
    .sc1 { text-align: left; width: 100%; font-variant: small-caps; }\
	.sc1 b { font-size: 15px; }\
	.bf { color: #af9f39; font-size: 20px; font-weight: bold; font-family: "Comic Sans MS", cursive, sans-serif;  }\
	.bi { font-weight: normal; }\
 	.sc2 { text-align: center; width: 135px; }\
	.sch { text-align: left; font-weight: bold; padding: 3px; }\
	.bfr { color: blue; }\
	.cdi { 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; }\
	.levelpb { display: inline-flex; margin-left: 10px; width: 180px; } \
	.levelpb div .mf { width: 180px; }\
	.levelpb div .sf { width: 180px; }';

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';
var pointsLeftPrefixString = '\u041E\u0441\u0442\u0430\u043B\u043E\u0441\u044C';

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+)?)\)/gm;
	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 border = document.createElement('div');
	border.className = 'pb';
	//border.title  = percentage.toFixed(3) + '%';	
	
	var scale = document.createElement('div');
	scale.style.width = percentage.toFixed(0) + '%';
	
	var mainFont = document.createElement('font');
	mainFont.className = 'pbc mf';
	mainFont.appendChild(document.createTextNode(points));
	
	var l = document.createElement('small');
	l.appendChild(document.createTextNode('+' + left));	
	mainFont.appendChild(l);
	
	scale.appendChild(mainFont);
	
	var sideFont = document.createElement('font');
	sideFont.className = 'pbc sf';	
	sideFont.appendChild(document.createTextNode(scale.style.width));	
	scale.appendChild(sideFont);
	
	border.appendChild(scale);
	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 getScoreLost(range, score)
{
	return Math.round((range.Final - score)*100)/100;
}

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 = 'sc1';	
	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.innerHTML = value.Level;
	if (value.Score >= range.Final)
	{
		lb.className = 'bf';
	}
	else if (!value.Score)
	{
		lb.className = 'bi';
	}
	c1.appendChild(lb);
	row.appendChild(c1);	
	var c2 = document.createElement('td');
	c2.className = 'sc2';
	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 = 'bfr';
			c1.appendChild(rl);
		}
		var pb = createProgressBar(points, left, percentage);
		c2.appendChild(pb);		
	}	
	row.appendChild(c2);	
	return row;	
}

function createHeadRow(title)
{
	var result = document.createElement('tr');
	var cell = document.createElement('td');
	cell.colSpan = 2;
	cell.appendChild(document.createTextNode(title));
	cell.className = 'sch';
	result.appendChild(cell);
	return result;
}

function createExpanderButton()
{
	var cb = document.createElement('input');
	cb.type = 'button';
	cb.value = expandCaption;
	cb.className = 'cdi';
	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 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 = document.createElement('table');
		
		t.appendChild(createHeadRow(isEn() ? 'Factions' : factionsGroupTitleRU));
		t.style.width = "100%";
		var excludeCaption;
		var ii = 0;
		do
		{
			t.appendChild(createRow(items[ii], getScaleIndex(ii), excludeCaption));
			ii++;
			if (ii == factionCount)
			{
				t.appendChild(createHeadRow(isEn() ? 'Guilds' : factionsGroupTitleRU));
				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], Left: m[2] }
	}
}

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==