Hi, I have wrangled grok for a few hours to produce a parser for HV's default image-based font for Persistent. It also handles custom font as a simple fallback.
Live_Percentile_Ranges_1.1.0.s3_hvfont.user.js.txt ( 86.44k )
Number of downloads: 3
Live_Percentile_Ranges_1.1.0.s3.user.js.txt ( 86.23k )
Number of downloads: 2
lpr_hvfont.patch.txt ( 2.09k )
Number of downloads: 0(archived original and diff provided for quick reference)
(
Updated to fix one missed spot that caused the 'Z' key player level lookup to fail.)
Manual editing and instructional text:
Put the following code near the beginning of the script (for simplicity). It's messier than it should be because HV font doesn't communicate uppercase but LPR wants it and is case sensitive in places. We came up with two versions; use the smart one since it works fine.
CODE
function parseHVFont(el) {
return el.innerHTML.match(/c\d\w/g)?.map(m => ({'c59':' ','c4a':'.','c4b':','}[m] || m.slice(2))).join('').replace(/\b\w/g, l => l.toUpperCase()) || el.textContent;
}
Smart version ^
CODE
function parseHVFont(el) {
return el.innerHTML.match(/c\d\w/g)?.map(m => Object.entries({'c59':' ','c4a':'.','c4b':',','c5':'','c4':''}).reduce((s, [k, v]) => s.replace(k, v), m)).join('').replace(/\b\w/g, l => l.toUpperCase()) || el.textContent;
}
More crude and direct version ^
Then three places need to be patched: PercentileRanges.getName(), PercentileRanges.transformations.showScaledMylevel(), and some optional stuff in DocumentInteractor() that sets the window title. Those last 3 lines in the diff can be commented out if you don't want the fancy display name to be replaced with small regular text.
CODE
@@ -732,4 +735,4 @@ function getName(equipDocument){
const name = nameDiv.children.length === 3 ?
- parseHVFont(nameDiv.children[0]) + ' ' + parseHVFont(nameDiv.children[2]) :
- parseHVFont(nameDiv.children[0]);
+ nameDiv.children[0].textContent + ' ' + nameDiv.children[2].textContent :
+ nameDiv.children[0].textContent;
return name;
@@ -1408,4 +1411,4 @@ transformations.showScaledMylevel = function(){
try {
- level = parseInt(response.querySelector('#level_readout').children[0].children[0].textContent.match(/\d+/)[0]);
+ level = parseInt(parseHVFont(response.querySelector('#level_readout').children[0]).match(/\d+/)[0]);
} catch (e){
formatDiv.textContent = "Couldn't parse the response";
@@ -1589,7 +1592,7 @@ function DocumentInteractor(){
const nameDiv = showequip.children.length === 3 ? showequip.children[0].children[0] : showequip.children[1].children[0];
- let name = parseHVFont(nameDiv.children[0]);
+ let name = nameDiv.children[0].textContent;
if(nameDiv.children.length === 3) {
- name += ' ' + parseHVFont(nameDiv.children[2]).replace(/^(Of|The)\b/,s=>s.toLowerCase());
+ name += ' ' + nameDiv.children[2].textContent.replace(/^(Of|The)\b/,s=>s.toLowerCase());
nameDiv.children[2].remove();
nameDiv.children[1].remove();
nameDiv.children[0].textContent = name;
This post has been edited by ultramage: Nov 21 2025, 09:26