tm-essentials
Version:
A lightweight library in Node.js that provides formatting features and little additions for any development related to Trackmania.
239 lines (202 loc) • 7.44 kB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.TMEssentials = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
class Accounts {
/**
* Transform a player login to its account uuid. Returns null if the login is invalid.
* @param {string} login
* @returns {string|null}
*/
static toAccountId(login) {
if (login.length != 22) return null;
var bytes = atob(login
.replace(/-/g, '+')
.replace(/_/g, '/')
);
var ret = '';
for (var i = 0; i < bytes.length; i++) {
if (i == 4 || i == 6 || i == 8 || i == 10) {
ret += '-';
}
ret += bytes.charCodeAt(i).toString(16);
}
return ret;
}
/**
* Transform a player account uuid to its login.
* @param {string} accountId
* @returns {string}
*/
static toLogin(accountId) {
var chars = accountId.replace(/-/g, '');
var bytes = '';
for (var i = 0; i < chars.length; i += 2) {
var hex = chars.substr(i, 2);
var dec = parseInt(hex, 16);
var byte = String.fromCharCode(dec);
bytes += byte;
}
return btoa(bytes)
.replace(/\+/g, '-')
.replace(/\//g, '_')
.replace(/=/g, '');
}
}
module.exports = Accounts;
},{}],2:[function(require,module,exports){
class TextFormatter {
// Credits to @ThaumicTom for the deformat regex
/**
* Regex to match all the formatting codes
* @type {RegExp}
* @private
*/
static deformatRegex = /(\$(?:(\$)|[0-9a-f]{2,3}|[lh]\[.*?\]|.))/gi;
/**
* Regex to match all the color formatting codes
* @type {RegExp}
* @private
*/
static colorRegex = /\$[0-9a-f]{1,3}/gi;
/**
* Ansi default color
* @type {string}
* @private
*/
static AnsiDefault = "\x1B[39m\x1B[22m";
/**
* Deformat the text
* @param {string} input
* @returns {string}
*/
static deformat(input) {
return input.replace(this.deformatRegex, "$2");
}
/**
* Format the text color with ANSI escape codes
* @param {string} input
* @returns {string}
*/
static formatAnsi(input) {
let output = "";
let split = input.split(this.deformatRegex).filter((i) => i && i != "$");
split.forEach((part) => {
output += this.colorToAnsi(part);
});
output += this.AnsiDefault;
return output;
}
/**
* Convert a color string to ANSI escape codes
* @param {string} input
* @returns {string}
* @private
*/
static colorToAnsi(input) {
if (!input.startsWith("$")) return input;
if (input.endsWith("z")) return this.AnsiDefault;
if (input.match(this.colorRegex)) {
let colorInt16 = parseInt(input.split("$").join(""), 16),
r = 0x11 * ((colorInt16 & 0xF00) >> 8),
g = 0x11 * ((colorInt16 & 0x0F0) >> 4),
b = 0x11 * ((colorInt16 & 0x00F) >> 0);
return "\x1B[38;2;" + r + ";" + g + ";" + b + "m";
}
return input;
}
}
module.exports = TextFormatter;
},{}],3:[function(require,module,exports){
class Time {
/**
* Trackmania Time formatters.
* @param {number|null} time Time in milliseconds
*/
constructor(time) {
/**
* Time in milliseconds
* @type {number|null}
*/
this.time = time;
}
/**
* Output the time in the format "hh:mm:ss.ms"
* @param {boolean} useHundreds If true, return the time in the hundreds of milliseconds
* @returns {string}
*/
toTmString(useHundreds = false) {
let output = "";
if (this.time == null) {
output = "-:--.---";
} else {
if (Math.sign(this.time) == -1) output += "-";
this.time = Math.abs(this.time);
let ms = this.time % 1000,
s = Math.floor(this.time / 1000) % 60,
m = Math.floor(this.time / 60000) % 60,
h = Math.floor(this.time / 3600000);
if (ms < 10) ms = "00" + ms;
else if (ms < 100) ms = "0" + ms;
if (h > 0) output += Math.floor(h) + ":";
output += Math.floor(m).toString().padStart(m < 10 ? 1 : 2, '0') + ":";
output += Math.floor(s).toString().padStart(2, '0') + ".";
output += Math.floor(ms).toString().padStart(3, '0');
}
if (useHundreds) output = output.substring(0, output.length - 1);
return output;
}
}
class TimeSpan {
/**
* Returns the {@link Time} class with a null value.
* @returns {Time} {@link Time}
*/
static noTime = new Time(null);
/**
* Returns the {@link Time} class with a value in milliseconds.
* @param {number} ms
* @returns {Time} {@link Time}
*/
static fromMilliseconds(ms) {
return new Time(ms);
}
/**
* Returns the {@link Time} class with a value in seconds. All numbers after the decimal point are parsed as milliseconds.
* @param {number} s
* @returns {Time} {@link Time}
*/
static fromSeconds(s) {
return new Time(s * 1000);
}
/**
* Returns the {@link Time} class with a value in minutes. All numbers after the decimal point are parsed as seconds.
* @param {Number} m
* @returns {Time} {@link Time}
*/
static fromMinutes(m) {
let numberAfterDecimal = 0;
if (!Number.isInteger(m)) numberAfterDecimal = m.toString().split('.')[1].length;
let minutes = Math.floor(m),
seconds = Number(((m - minutes) * Math.pow(10, numberAfterDecimal)).toFixed(0));
return new Time(seconds * 1000 + minutes * 60000);
}
/**
* Returns the {@link Time} class with a value in hours. All numbers after the decimal point are parsed as minutes.
* @param {Number} h
* @returns {Time} {@link Time}
*/
static fromHours(h) {
let numberAfterDecimal = 0;
if (!Number.isInteger(h)) numberAfterDecimal = h.toString().split('.')[1].length;
let hours = Math.floor(h),
minutes = Number(((h - hours) * Math.pow(10, numberAfterDecimal)).toFixed(0));
return new Time(minutes * 60000 + hours * 3600000);
}
}
module.exports = TimeSpan;
},{}],4:[function(require,module,exports){
module.exports = {
TextFormatter: require('./TextFormatter'),
Accounts: require('./Accounts'),
Time: require('./Time'),
};
},{"./Accounts":1,"./TextFormatter":2,"./Time":3}]},{},[4])(4)
});