code import
This commit is contained in:
16
.gitignore
vendored
Normal file
16
.gitignore
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Ignore node modules.
|
||||
/node_modules
|
||||
|
||||
# Ignore Java version tracker.
|
||||
/java.json
|
||||
|
||||
# Ignore cape cache/override.
|
||||
/c_cache
|
||||
/c_override
|
||||
|
||||
# Ignore skin cache/override.
|
||||
/s_cache
|
||||
/s_override
|
||||
|
||||
# Ignore MinecraftResources.
|
||||
/resources.xml
|
||||
BIN
defaults/.DS_Store
vendored
Normal file
BIN
defaults/.DS_Store
vendored
Normal file
Binary file not shown.
BIN
defaults/default_skin.png
Executable file
BIN
defaults/default_skin.png
Executable file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
560
index.js
Normal file
560
index.js
Normal file
@@ -0,0 +1,560 @@
|
||||
'use strict';
|
||||
|
||||
// ActionMC legacy skins server.
|
||||
// Virtue 2021
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const request = require('sync-request');
|
||||
|
||||
function downloadFileSync(url) {
|
||||
return require('child_process')
|
||||
.execFileSync('curl', ['--silent', '-L', url]); // remove options {encoding: 'utf8'}
|
||||
}
|
||||
|
||||
// Variables.
|
||||
|
||||
// This is where the server stores caches of Mojang requests.
|
||||
const Skin_CacheLocation = path.join(__dirname, "s_cache");
|
||||
const Cape_CacheLocation = path.join(__dirname, "c_cache");
|
||||
|
||||
// This defines the amount of time an item should be cached for.
|
||||
const Skin_CacheTime = 24; // 24 hours by default.
|
||||
const Cape_CacheTime = 48; // 48 hours by default (capes don't change as much)
|
||||
|
||||
// This is where the server stores overrides - if a user has an entry in
|
||||
// these folders, their Mojang request will be overriden with the contents
|
||||
// of the file present in the override location.
|
||||
const Skin_OverrideLocation = path.join(__dirname, "s_override");
|
||||
const Cape_OverrideLocation = path.join(__dirname, "c_override");
|
||||
|
||||
// This is where the resource.xml file is stored - this tells a client
|
||||
// where to find certain resources - may fix some sounds in-game.
|
||||
const Resources_XML_Location = path.join(__dirname, "resources.xml")
|
||||
|
||||
// This is where the server stores default skins - if a user has no
|
||||
// skin, their Mojang request will be overridden with the contents
|
||||
// of the default file.
|
||||
|
||||
const Skin_DefaultFile = path.join(__dirname, 'defaults', 'default_skin.png')
|
||||
const Cape_DefaultFile = path.join(__dirname, 'defaults', 'default_cape.png')
|
||||
|
||||
// This is where the information for the Java poll is stored. This
|
||||
// must be a JSON file.
|
||||
|
||||
const Java_JSON = path.join(__dirname, "java.json");
|
||||
|
||||
// ACTUAL CODE BEYOND THIS POINT \\
|
||||
|
||||
// Initialise variables
|
||||
// Time until cache clear for stats api.
|
||||
var Skin_CacheWipeTime = Date.now() + (3600000 * Skin_CacheTime);
|
||||
var Cape_CacheWipeTime = Date.now() + (3600000 * Cape_CacheTime);
|
||||
|
||||
// Actual distance between cache clear.
|
||||
var Skin_CacheWipeDis = 3600000 * Skin_CacheTime;
|
||||
var Cape_CacheWipeDis = 3600000 * Cape_CacheTime;
|
||||
|
||||
// Previous.
|
||||
|
||||
var Skin_PreviousCacheWipeTime = Date.now();
|
||||
var Cape_PreviousCacheWipeTime = Date.now();
|
||||
|
||||
// Do pre-initialisation folder checks.
|
||||
if (!fs.existsSync(Skin_CacheLocation)) {
|
||||
console.log('[WARN] Skin cache directory does not exist, creating...');
|
||||
try {
|
||||
fs.mkdirSync(Skin_CacheLocation);
|
||||
console.log('[INFO] Skin cache directory created successfully.')
|
||||
} catch (exc) {
|
||||
console.log(exc)
|
||||
console.log('[ERR] Failure creating skin cache directory.')
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs.existsSync(Cape_CacheLocation)) {
|
||||
console.log('[WARN] Cape cache directory does not exist, creating...');
|
||||
try {
|
||||
fs.mkdirSync(Cape_CacheLocation);
|
||||
console.log('[INFO] Cape cache directory created successfully.')
|
||||
} catch (exc) {
|
||||
console.log(exc)
|
||||
console.log('[ERR] Failure creating Cape cache directory.')
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs.existsSync(Skin_OverrideLocation)) {
|
||||
console.log('[WARN] Skin override directory does not exist, creating...');
|
||||
try {
|
||||
fs.mkdirSync(Skin_OverrideLocation);
|
||||
console.log('[INFO] Skin override directory created successfully.')
|
||||
} catch (exc) {
|
||||
console.log(exc)
|
||||
console.log('[ERR] Failure creating skin override directory.')
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs.existsSync(Cape_OverrideLocation)) {
|
||||
console.log('[WARN] Cape override directory does not exist, creating...');
|
||||
try {
|
||||
fs.mkdirSync(Cape_OverrideLocation);
|
||||
console.log('[INFO] Cape override directory created successfully.')
|
||||
} catch {
|
||||
console.log('[ERR] Failure creating cape override directory.')
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fs.existsSync(Resources_XML_Location)) {
|
||||
console.log('[WARN] Resources XML does not exist. Obtaining...');
|
||||
try {
|
||||
let dl = downloadFileSync('http://s3.amazonaws.com/MinecraftResources');
|
||||
fs.writeFileSync(Resources_XML_Location, dl);
|
||||
console.log('[INFO] Resources XML created successfully!')
|
||||
} catch {
|
||||
console.log('[ERR] Failure creating resources XML.');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Initialise functions.
|
||||
|
||||
// add_to_java_poll
|
||||
// Purpose: Adds a new entry into the Java version data.
|
||||
// Returns: nothing.
|
||||
|
||||
function add_to_java_poll(java_useragent) {
|
||||
var tmp_json;
|
||||
|
||||
if (fs.existsSync(Java_JSON)) {
|
||||
tmp_json = require(Java_JSON);
|
||||
} else {
|
||||
tmp_json = {};
|
||||
}
|
||||
|
||||
if (tmp_json[java_useragent]) {
|
||||
tmp_json[java_useragent] += 1;
|
||||
} else {
|
||||
tmp_json[java_useragent] = 1;
|
||||
}
|
||||
|
||||
try {
|
||||
fs.writeFileSync(Java_JSON, JSON.stringify(tmp_json));
|
||||
} catch (exc) {
|
||||
// oh poop.
|
||||
}
|
||||
}
|
||||
|
||||
// get_uuid
|
||||
// Purpose: Gets a UUID of a player.
|
||||
// Returns: UUID of player if they exist, false if error occured.
|
||||
|
||||
function get_uuid(username) {
|
||||
let reqBody = '["' + username + '"]';
|
||||
let req = request('POST', 'https://api.mojang.com/profiles/minecraft', {body: reqBody});
|
||||
|
||||
// Have response now.
|
||||
let response = JSON.parse(req.getBody('utf8'));
|
||||
if (response.error) {
|
||||
// error obtaining user.
|
||||
return false;
|
||||
}
|
||||
|
||||
// we have the user, get their UUID.
|
||||
return response[0]["id"];
|
||||
}
|
||||
|
||||
// check_cache_override
|
||||
// Purpose: Checks the cache and override directories for the user.
|
||||
// Returns: 0 for not cached, 1 for cached and 2 for override.
|
||||
|
||||
function check_cache_override(type, name) {
|
||||
// type can either be skin or cape.
|
||||
if (type == "skin") {
|
||||
if (fs.existsSync(path.join(Skin_OverrideLocation, name + '.png'))) {
|
||||
// user has an entry in the override location.
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.join(Skin_CacheLocation, name + '.png'))) {
|
||||
// user has an entry in the cache location.
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if execution of subroutine continues, no cache entry exists.
|
||||
return 0;
|
||||
} else if (type == "cape") {
|
||||
if (fs.existsSync(path.join(Cape_OverrideLocation, name + '.png'))) {
|
||||
// user has an entry in the override location.
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (fs.existsSync(path.join(Cape_CacheLocation, name + '.png'))) {
|
||||
// user has an entry in the cache location.
|
||||
return 1;
|
||||
}
|
||||
|
||||
// if execution of subroutine continues, no cache entry exists.
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// get_skin_from_mojang
|
||||
// Purpose: Get a skin from Mojang.
|
||||
// Returns: true if skin obtained, false if skin failed.
|
||||
|
||||
function get_skin_from_mojang(uuid, name) {
|
||||
let req = request('GET', 'https://sessionserver.mojang.com/session/minecraft/profile/' + uuid);
|
||||
|
||||
// have response now.
|
||||
let response = JSON.parse(req.getBody('utf8'));
|
||||
|
||||
if (response.error) {
|
||||
// error obtaining profile.
|
||||
return false;
|
||||
}
|
||||
|
||||
// now parse for the base64 encoded json.
|
||||
let b64json = response["properties"][0]["value"];
|
||||
let b64buffer = new Buffer(b64json, 'base64');
|
||||
b64json = b64buffer.toString('ascii');
|
||||
b64json = JSON.parse(b64json);
|
||||
|
||||
// now we have a download link.
|
||||
let download_url = b64json["textures"]["SKIN"]['url'];
|
||||
let skin_file = downloadFileSync(download_url);
|
||||
|
||||
|
||||
|
||||
// write to file.
|
||||
try {
|
||||
let write_time = Date.now();
|
||||
let writing = fs.writeFileSync(path.join(Skin_CacheLocation, name + '.png'), skin_file);
|
||||
|
||||
return true;
|
||||
} catch (exc) {
|
||||
console.error(exc);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// get_cape_from_mojang
|
||||
// Purpose: Get a cape from Mojang.
|
||||
// Returns: true if cape obtained, false if cape failed.
|
||||
|
||||
function get_cape_from_mojang(uuid, name) {
|
||||
let req = request('GET', 'https://sessionserver.mojang.com/session/minecraft/profile/' + uuid);
|
||||
|
||||
// have response now.
|
||||
let response = JSON.parse(req.getBody('utf8'));
|
||||
|
||||
if (response.error) {
|
||||
// error obtaining profile.
|
||||
return false;
|
||||
}
|
||||
|
||||
// now parse for the base64 encoded json.
|
||||
let b64json = response["properties"][0]["value"];
|
||||
let b64buffer = new Buffer(b64json, 'base64');
|
||||
b64json = b64buffer.toString('ascii');
|
||||
b64json = JSON.parse(b64json);
|
||||
|
||||
// now we have a download link.
|
||||
let download_url = b64json["textures"]["CAPE"]['url'];
|
||||
let skin_file = downloadFileSync(download_url);
|
||||
|
||||
|
||||
|
||||
// write to file.
|
||||
try {
|
||||
let write_time = Date.now();
|
||||
let writing = fs.writeFileSync(path.join(Cape_CacheLocation, name + ".png"), skin_file);
|
||||
|
||||
return true;
|
||||
} catch (exc) {
|
||||
console.error(exc);
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// get_skin
|
||||
// Purpose: Get the skin location of the user to serve.
|
||||
// Returns: location to skin file if exists, location to default skin if not.
|
||||
|
||||
function get_skin(uname) {
|
||||
let cache = check_cache_override('skin', uname);
|
||||
|
||||
if (cache == 1) {
|
||||
// present in cache - serve user from there
|
||||
return path.join(Skin_CacheLocation, uname + '.png')
|
||||
} else if (cache == 2) {
|
||||
// present in OVERRIDE - serve user from there.
|
||||
return path.join(Skin_OverrideLocation, uname + '.png')
|
||||
} else {
|
||||
// presume user does not exist in cache. try to fetch beforehand though.
|
||||
try {
|
||||
// get uuid
|
||||
let uuid = get_uuid(uname);
|
||||
// get skin from mojang.
|
||||
let skin_get = get_skin_from_mojang(uuid, uname);
|
||||
if (!skin_get) {
|
||||
// failed. return default skin path.
|
||||
return Skin_DefaultFile;
|
||||
} else {
|
||||
// user is now in cache.
|
||||
return path.join(Skin_CacheLocation, uname + '.png')
|
||||
}
|
||||
} catch {
|
||||
// error occured somewhere.
|
||||
return Skin_DefaultFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get_cape
|
||||
// Purpose: Get the cape location of the user to serve.
|
||||
// Returns: location to cape file if exists, location to default cape if not.
|
||||
|
||||
function get_cape(uname) {
|
||||
let cache = check_cache_override('cape', uname);
|
||||
|
||||
if (cache == 1) {
|
||||
// present in cache - serve user from there
|
||||
return path.join(Cape_CacheLocation, uname + '.png')
|
||||
} else if (cache == 2) {
|
||||
// present in OVERRIDE - serve user from there.
|
||||
return path.join(Cape_OverrideLocation, uname + '.png')
|
||||
} else {
|
||||
// presume user does not exist in cache. try to fetch beforehand though.
|
||||
try {
|
||||
// get uuid
|
||||
let uuid = get_uuid(uname);
|
||||
// get skin from mojang.
|
||||
let skin_get = get_cape_from_mojang(uuid, uname);
|
||||
if (!skin_get) {
|
||||
// failed. return default skin path.
|
||||
return Cape_DefaultFile;
|
||||
} else {
|
||||
// user is now in cache.
|
||||
return path.join(Cape_CacheLocation, uname + '.png')
|
||||
}
|
||||
} catch {
|
||||
// error occured somewhere.
|
||||
return Cape_DefaultFile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rm_dir
|
||||
// Purpose: removes all files in a directory.
|
||||
// Returns: nothing.
|
||||
|
||||
function rm_dir(dirPath) {
|
||||
try { var files = fs.readdirSync(dirPath); }
|
||||
catch(e) { return; }
|
||||
if (files.length > 0)
|
||||
for (var i = 0; i < files.length; i++) {
|
||||
var filePath = dirPath + '/' + files[i];
|
||||
if (fs.statSync(filePath).isFile())
|
||||
fs.unlinkSync(filePath);
|
||||
else
|
||||
rmDir(filePath);
|
||||
}
|
||||
};
|
||||
|
||||
// Initialise cache-wiping functions.
|
||||
|
||||
// Skin.
|
||||
setInterval(() => {
|
||||
console.log('[CACHE] Wiping skins cache...');
|
||||
rm_dir(Skin_CacheLocation);
|
||||
Skin_PreviousCacheWipeTime = Skin_CacheWipeTime
|
||||
Skin_CacheWipeTime = Date.now() + (3600000 * Skin_CacheTime);
|
||||
console.log('[CACHE] Skin cache wipe completed.');
|
||||
}, Skin_CacheWipeDis)
|
||||
|
||||
// Cape.
|
||||
setInterval(() => {
|
||||
console.log('[CACHE] Wiping capes cache...');
|
||||
rm_dir(Cape_CacheLocation);
|
||||
Cape_PreviousCacheWipeTime = Cape_CacheWipeTime
|
||||
Cape_CacheWipeTime = Date.now() + (3600000 * Cape_CacheTime);
|
||||
console.log('[CACHE] Cape cache wipe completed.');
|
||||
}, Cape_CacheWipeDis)
|
||||
|
||||
// Do server initial cache wipe.
|
||||
console.log('[CACHE] Server startup - wiping skin cache...');
|
||||
rm_dir(Skin_CacheLocation);
|
||||
console.log('[CACHE] Skin cache wipe completed.');
|
||||
console.log('[CACHE] Server startup - wiping cape cache...');
|
||||
rm_dir(Cape_CacheLocation);
|
||||
console.log('[CACHE] Cape cache wipe completed.')
|
||||
|
||||
// Initialise express.
|
||||
const express = require('express')
|
||||
const app = express()
|
||||
const port = 80
|
||||
|
||||
// Initialise static folders.
|
||||
app.use(express.static('static'))
|
||||
app.use('/MinecraftResources', express.static('resources'))
|
||||
|
||||
// Initialise routers.
|
||||
|
||||
// GET /MinecraftSkins/:username
|
||||
// Paramters:
|
||||
// username: username of character to get skin for
|
||||
// Returns:
|
||||
// skin.png
|
||||
|
||||
app.get('/MinecraftSkins/:username', async (req,res) => {
|
||||
let parsed_username = req.params.username.slice(0,-4);
|
||||
console.log('[GET] Cape: ' + parsed_username);
|
||||
console.log(parsed_username)
|
||||
let location = get_skin(parsed_username);
|
||||
res.sendFile(location);
|
||||
})
|
||||
|
||||
// GET /MinecraftCloaks/:username
|
||||
// Paramters:
|
||||
// username: username of character to get cape for
|
||||
// Returns:
|
||||
// cape.png
|
||||
|
||||
app.get('/MinecraftCloaks/:username', async (req,res) => {
|
||||
let parsed_username = req.params.username.slice(0,-4);
|
||||
console.log('[GET] Cloak: ' + parsed_username);
|
||||
let location = get_cape(parsed_username);
|
||||
res.sendFile(location);
|
||||
})
|
||||
|
||||
// GET /statistics
|
||||
// No parameters.
|
||||
// Returns:
|
||||
// - information from the stats API but neater and user-friendly.
|
||||
|
||||
app.get('/statistics', async (req,res) => {
|
||||
let skin_cacheCount = fs.readdirSync(Skin_CacheLocation).length;
|
||||
let skin_overrideCount = fs.readdirSync(Skin_OverrideLocation).length;
|
||||
let cape_cacheCount = fs.readdirSync(Cape_CacheLocation).length;
|
||||
let cape_overrideCount = fs.readdirSync(Cape_OverrideLocation).length;
|
||||
|
||||
let skin_wipeTime = new Date(Skin_CacheWipeTime);
|
||||
let skin_prevWipeTime = new Date(Skin_PreviousCacheWipeTime);
|
||||
let cape_wipeTime = new Date(Cape_CacheWipeTime);
|
||||
let cape_prevWipeTime = new Date(Cape_PreviousCacheWipeTime);
|
||||
let result = `<h1>Statistics</h1>
|
||||
<h4>Skins</h4>
|
||||
<p>Skins currently cached: ${skin_cacheCount}</p>
|
||||
<p>Skins currently overriden: ${skin_overrideCount}</p>
|
||||
<p>Time of next skin cache wipe: ${skin_wipeTime.toUTCString()}</p>
|
||||
<p>Time of previous skin cache wipe: ${skin_prevWipeTime.toUTCString()}</p>
|
||||
<h4>Capes</h4>
|
||||
<p>Capes currently cached: ${cape_cacheCount}</p>
|
||||
<p>Capes currently overridden: ${cape_overrideCount}</p>
|
||||
<p>Time of next cape cache wipe: ${cape_wipeTime.toUTCString()}</p>
|
||||
<p>Time of previous cape cache wipe: ${cape_prevWipeTime.toUTCString()}</p><hr />
|
||||
<p><i>For Java statistics, see <a href="/statistics/java">the Java statistics page</a>.</i></p>`
|
||||
|
||||
res.send(result)
|
||||
|
||||
})
|
||||
|
||||
// GET /statistics/java
|
||||
// No parameters
|
||||
// Returns:
|
||||
// - Java version info from the stats API but neater and user-friendly.
|
||||
|
||||
app.get('/statistics/java', async (req,res) => {
|
||||
let result = '<h1>Versions of Java that have used this skin server:</h1>'
|
||||
var javajson;
|
||||
if (fs.existsSync(Java_JSON)) {
|
||||
javajson = require(Java_JSON)
|
||||
} else {
|
||||
javajson = {}
|
||||
}
|
||||
for (const i in javajson) {
|
||||
result += `<p><strong>${i}:</strong> ${javajson[i]}</p>`
|
||||
}
|
||||
result += '<hr /><p><i>To see other statistics, see <a href="/statistics">the main statistics page</a>.</i></p>'
|
||||
res.send(result)
|
||||
})
|
||||
|
||||
// GET /statistics/api/java
|
||||
// No parameters.
|
||||
// Returns:
|
||||
// - Java versions that have "phoned home" on MC client startup.
|
||||
|
||||
app.get('/statisticss/api/java', async (req,res) => {
|
||||
var javajson;
|
||||
if (fs.existsSync(Java_JSON)) {
|
||||
javajson = require(Java_JSON)
|
||||
} else {
|
||||
javajson = {}
|
||||
}
|
||||
|
||||
res.json(javajson)
|
||||
});
|
||||
|
||||
|
||||
|
||||
// GET /statistics/api/skins
|
||||
// No parameteers
|
||||
// Returns:
|
||||
// - amount of skins cached
|
||||
// - amount of skins with overrides
|
||||
// - epoch timestamp of cache wipe time
|
||||
// - epoch timestamp of previous cache wipe time
|
||||
|
||||
app.get('/statistics/api/skins', async (req,res) => {
|
||||
let skin_CacheCount = fs.readdirSync(Skin_CacheLocation).length;
|
||||
let skin_OverrideCount = fs.readdirSync(Skin_OverrideLocation).length;
|
||||
res.contentType('application/json')
|
||||
res.json({cached: skin_CacheCount, overridden: skin_OverrideCount, cache_wipe_time: Skin_CacheWipeTime, previous_cache_wipe_time: Skin_PreviousCacheWipeTime});
|
||||
})
|
||||
|
||||
// GET /statistics/api/capes
|
||||
// No parameteers
|
||||
// Returns:
|
||||
// - amount of capes cached
|
||||
// - amount of capes with overrides
|
||||
// - epoch timestamp of cache wipe time
|
||||
// - epoch timestamp of previous cache wipe time
|
||||
|
||||
app.get('/statistics/api/capes', async (req,res) => {
|
||||
let skin_CacheCount = fs.readdirSync(Cape_CacheLocation).length;
|
||||
let skin_OverrideCount = fs.readdirSync(Cape_OverrideLocation).length;
|
||||
res.contentType('application/json')
|
||||
res.json({cached: skin_CacheCount, overridden: skin_OverrideCount, cache_wipe_time: Cape_CacheWipeTime, previous_cache_wipe_time: Cape_PreviousCacheWipeTime});
|
||||
})
|
||||
|
||||
// GET /MinecraftResources
|
||||
// No parameters
|
||||
// Returns:
|
||||
// - XML file containing location of resources.
|
||||
// This can be also used to track amount of clients using skin server,
|
||||
// but this shouldn't be relied upon.
|
||||
|
||||
// Client can be tracked by User Agent.
|
||||
// If the first four characters of their user agent are "Java", then
|
||||
// it is likely that they are a MC client.
|
||||
|
||||
app.get('/MinecraftResources', async (req,res) => {
|
||||
if (req.headers['user-agent'].slice(0,4) == "Java") {
|
||||
console.log('[INFO] New client made connection to server!');
|
||||
add_to_java_poll(req.headers['user-agent']);
|
||||
}
|
||||
res.sendFile(Resources_XML_Location);
|
||||
})
|
||||
|
||||
// Listen on defined port.
|
||||
app.listen(port, () => {
|
||||
console.log(`[HTTP] ActionMC skin server listening on port ${port}.`)
|
||||
})
|
||||
|
||||
// EOF
|
||||
586
package-lock.json
generated
Normal file
586
package-lock.json
generated
Normal file
@@ -0,0 +1,586 @@
|
||||
{
|
||||
"name": "amc-skins",
|
||||
"version": "2.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@types/concat-stream": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.0.tgz",
|
||||
"integrity": "sha1-OU2+C7X+5Gs42JZzXoto7yOQ0A0=",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/form-data": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz",
|
||||
"integrity": "sha1-yayFsqX9GENbjIXZ7LUObWyJP/g=",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "10.17.50",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.50.tgz",
|
||||
"integrity": "sha512-vwX+/ija9xKc/z9VqMCdbf4WYcMTGsI0I/L/6shIF3qXURxZOhPQlPRHtjTpiNhAwn0paMJzlOQqw6mAGEQnTA=="
|
||||
},
|
||||
"@types/qs": {
|
||||
"version": "6.9.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.5.tgz",
|
||||
"integrity": "sha512-/JHkVHtx/REVG0VVToGRGH2+23hsYLHdyG+GrvoUGlGAd0ErauXDyvHtRI/7H7mzLm+tBCKA7pfcpkQ1lf58iQ=="
|
||||
},
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||
"requires": {
|
||||
"mime-types": "~2.1.24",
|
||||
"negotiator": "0.6.2"
|
||||
}
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"asap": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
|
||||
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.7.0",
|
||||
"raw-body": "2.4.0",
|
||||
"type-is": "~1.6.17"
|
||||
}
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"concat-stream": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"inherits": "^2.0.3",
|
||||
"readable-stream": "^2.2.2",
|
||||
"typedarray": "^0.0.6"
|
||||
}
|
||||
},
|
||||
"content-disposition": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.2"
|
||||
}
|
||||
},
|
||||
"content-type": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||
},
|
||||
"cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
|
||||
},
|
||||
"depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||
},
|
||||
"destroy": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"download-file-sync": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/download-file-sync/-/download-file-sync-1.0.4.tgz",
|
||||
"integrity": "sha1-0+PFQ/g29BA5RVuQNMcuNVsDYBk="
|
||||
},
|
||||
"ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||
},
|
||||
"escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||
},
|
||||
"etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||
},
|
||||
"express": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.7",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.19.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"cookie-signature": "1.0.6",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"finalhandler": "~1.1.2",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.5",
|
||||
"qs": "6.7.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.1.2",
|
||||
"send": "0.17.1",
|
||||
"serve-static": "1.14.1",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": "~1.5.0",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"statuses": "~1.5.0",
|
||||
"unpipe": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
|
||||
"integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||
},
|
||||
"fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||
},
|
||||
"get-port": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz",
|
||||
"integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw="
|
||||
},
|
||||
"http-basic": {
|
||||
"version": "8.1.3",
|
||||
"resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz",
|
||||
"integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==",
|
||||
"requires": {
|
||||
"caseless": "^0.12.0",
|
||||
"concat-stream": "^1.6.2",
|
||||
"http-response-object": "^3.0.1",
|
||||
"parse-cache-control": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"http-errors": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||
"requires": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.0"
|
||||
}
|
||||
},
|
||||
"http-response-object": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz",
|
||||
"integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==",
|
||||
"requires": {
|
||||
"@types/node": "^10.0.3"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
|
||||
},
|
||||
"isarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||
},
|
||||
"merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.45.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
|
||||
"integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.28",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
|
||||
"integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
|
||||
"requires": {
|
||||
"mime-db": "1.45.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||
"requires": {
|
||||
"ee-first": "1.1.1"
|
||||
}
|
||||
},
|
||||
"parse-cache-control": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz",
|
||||
"integrity": "sha1-juqz5U+laSD+Fro493+iGqzC104="
|
||||
},
|
||||
"parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
|
||||
},
|
||||
"path-to-regexp": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"promise": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/promise/-/promise-8.1.0.tgz",
|
||||
"integrity": "sha512-W04AqnILOL/sPRXziNicCjSNRruLAuIHEOVBazepu0545DDNGYHz7ar9ZgZ1fMU8/MA4mVxp5rkBWRi6OXIy3Q==",
|
||||
"requires": {
|
||||
"asap": "~2.0.6"
|
||||
}
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
||||
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
||||
"requires": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.9.1"
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
|
||||
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
|
||||
"integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
|
||||
"requires": {
|
||||
"core-util-is": "~1.0.0",
|
||||
"inherits": "~2.0.3",
|
||||
"isarray": "~1.0.0",
|
||||
"process-nextick-args": "~2.0.0",
|
||||
"safe-buffer": "~5.1.1",
|
||||
"string_decoder": "~1.1.1",
|
||||
"util-deprecate": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
|
||||
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"destroy": "~1.0.4",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"etag": "~1.8.1",
|
||||
"fresh": "0.5.2",
|
||||
"http-errors": "~1.7.2",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.1",
|
||||
"on-finished": "~2.3.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "~1.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
|
||||
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
|
||||
"requires": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.17.1"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
},
|
||||
"sync-request": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz",
|
||||
"integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==",
|
||||
"requires": {
|
||||
"http-response-object": "^3.0.1",
|
||||
"sync-rpc": "^1.2.1",
|
||||
"then-request": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"sync-rpc": {
|
||||
"version": "1.3.6",
|
||||
"resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz",
|
||||
"integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==",
|
||||
"requires": {
|
||||
"get-port": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"then-request": {
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz",
|
||||
"integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==",
|
||||
"requires": {
|
||||
"@types/concat-stream": "^1.6.0",
|
||||
"@types/form-data": "0.0.33",
|
||||
"@types/node": "^8.0.0",
|
||||
"@types/qs": "^6.2.31",
|
||||
"caseless": "~0.12.0",
|
||||
"concat-stream": "^1.6.0",
|
||||
"form-data": "^2.2.0",
|
||||
"http-basic": "^8.1.1",
|
||||
"http-response-object": "^3.0.1",
|
||||
"promise": "^8.0.0",
|
||||
"qs": "^6.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/node": {
|
||||
"version": "8.10.66",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz",
|
||||
"integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"typedarray": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
}
|
||||
}
|
||||
}
|
||||
16
package.json
Normal file
16
package.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "amc-skins",
|
||||
"version": "2.0.1",
|
||||
"description": "Legacy skins server for ActionMC.",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "node ."
|
||||
},
|
||||
"author": "Virtue <virtue@actionmc.ml>",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"download-file-sync": "^1.0.4",
|
||||
"express": "^4.17.1",
|
||||
"sync-request": "^6.1.0"
|
||||
}
|
||||
}
|
||||
8
resources/README_VERY_IMPORTANT.txt
Normal file
8
resources/README_VERY_IMPORTANT.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Place contents of resources folder in .minecraft here.
|
||||
This is required for some older versions of Minecraft.
|
||||
|
||||
Location of .minecraft:
|
||||
|
||||
Windows: %appdata%\.minecraft
|
||||
Linux: ~/.minecraft
|
||||
macOS: ~/Libary/Application Support/minecraft
|
||||
19
static/README.md
Normal file
19
static/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Theta Skins Server
|
||||
A replacement for the now-removed legacy Minecraft Skins API, as well as providing a few fixes for older versions.
|
||||
|
||||
# Run Instructions
|
||||
- Clone the repository.
|
||||
- Run ``npm install``
|
||||
- Populate the "resources" folder with the contents of `.minecraft/resources` (follow the readme file in the folder for more information)
|
||||
- Start the program with ``npm run test``
|
||||
|
||||
The program will automatically make directories and XML files.
|
||||
|
||||
# How to Access
|
||||
|
||||
Append the following string to your hosts file:
|
||||
```
|
||||
<your-server-ip> s3.amazonaws.com
|
||||
```
|
||||
|
||||
Be sure to disable this after playing though, as a lot of the internet relies on Amazon S3 services and this server cannot provide all of them.
|
||||
2
static/index.html
Normal file
2
static/index.html
Normal file
@@ -0,0 +1,2 @@
|
||||
<h1>Theta Skin Server</h1>
|
||||
<p>Your website goes here!</p>
|
||||
Reference in New Issue
Block a user