mirror of
https://github.com/azures04/crafatar.git
synced 2026-03-22 07:51:17 +01:00
Fix README merge
This commit is contained in:
commit
8d73f50dd4
1
.gitignore
vendored
1
.gitignore
vendored
@ -3,3 +3,4 @@ skins/*/*.png
|
|||||||
node_modules/
|
node_modules/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.rdb
|
*.rdb
|
||||||
|
coverage/
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
# Crafatar [](https://travis-ci.org/Jake0oo0/Crafatar/)
|
# Crafatar [](https://travis-ci.org/Jake0oo0/crafatar/) [](https://coveralls.io/r/Jake0oo0/crafatar)
|
||||||
|
|
||||||
https://crafatar.com
|
https://crafatar.com
|
||||||
|
|
||||||
|
|||||||
2
app.js
2
app.js
@ -1,6 +1,5 @@
|
|||||||
var express = require('express');
|
var express = require('express');
|
||||||
var path = require('path');
|
var path = require('path');
|
||||||
var favicon = require('serve-favicon');
|
|
||||||
var logger = require('morgan');
|
var logger = require('morgan');
|
||||||
var cookieParser = require('cookie-parser');
|
var cookieParser = require('cookie-parser');
|
||||||
var bodyParser = require('body-parser');
|
var bodyParser = require('body-parser');
|
||||||
@ -14,7 +13,6 @@ var app = express();
|
|||||||
app.set('views', path.join(__dirname, 'views'));
|
app.set('views', path.join(__dirname, 'views'));
|
||||||
app.set('view engine', 'jade');
|
app.set('view engine', 'jade');
|
||||||
|
|
||||||
app.use(favicon(__dirname + '/public/favicon.ico'));
|
|
||||||
app.use(logger('dev'));
|
app.use(logger('dev'));
|
||||||
app.use(bodyParser.json());
|
app.use(bodyParser.json());
|
||||||
app.use(bodyParser.urlencoded({ extended: false }));
|
app.use(bodyParser.urlencoded({ extended: false }));
|
||||||
|
|||||||
24
clean_images.sh
Executable file
24
clean_images.sh
Executable file
@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# deletes old images on heroku
|
||||||
|
# heroku provides only 300 MB available disk space
|
||||||
|
|
||||||
|
# number of files to delete (2 files ~ 400B)
|
||||||
|
amount="50000" # about 20MB
|
||||||
|
|
||||||
|
# max free MB (on /) to trigger deletion
|
||||||
|
trigger="50"
|
||||||
|
|
||||||
|
available=`df -m / | awk 'NR==2 { print $4 }'` # MB available on /
|
||||||
|
if [ "$available" -le "$trigger" ]; then
|
||||||
|
echo "Deleting old images"
|
||||||
|
for file in `ls -1tr "/app/skins/faces" | head -n $amount`; do
|
||||||
|
rm -rf "/app/skins/faces/$file"
|
||||||
|
done
|
||||||
|
for file in `ls -1tr "/app/skins/helms" | head -n $amount`; do
|
||||||
|
rm -rf "/app/skins/helms/$file"
|
||||||
|
done
|
||||||
|
echo "done."
|
||||||
|
else
|
||||||
|
echo "More than $trigger MB are available ($available MB), not deleting!"
|
||||||
|
fi
|
||||||
@ -2,7 +2,7 @@ var config = require("./config");
|
|||||||
var redis = null;
|
var redis = null;
|
||||||
var fs = require("fs");
|
var fs = require("fs");
|
||||||
|
|
||||||
|
// sets up redis connection, calls clear_cache
|
||||||
function connect_redis() {
|
function connect_redis() {
|
||||||
console.log("connecting to redis...");
|
console.log("connecting to redis...");
|
||||||
if (process.env.REDISCLOUD_URL) {
|
if (process.env.REDISCLOUD_URL) {
|
||||||
@ -13,8 +13,8 @@ function connect_redis() {
|
|||||||
redis = require("redis").createClient();
|
redis = require("redis").createClient();
|
||||||
}
|
}
|
||||||
redis.on("ready", function() {
|
redis.on("ready", function() {
|
||||||
console.log("Redis connection established. Flushing all data.");
|
console.log("Redis connection established.");
|
||||||
redis.flushall();
|
clear_cache();
|
||||||
});
|
});
|
||||||
redis.on("error", function (err) {
|
redis.on("error", function (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
@ -24,7 +24,39 @@ function connect_redis() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// flushes redis, deletes faces + helms
|
||||||
|
function clear_cache() {
|
||||||
|
console.log("Flushing redis");
|
||||||
|
redis.flushall();
|
||||||
|
console.log("Deleting all faces + helms...");
|
||||||
|
fs.readdir(config.faces_dir, function(err, files) {
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
} else {
|
||||||
|
for (var i in files) {
|
||||||
|
var file = files[i];
|
||||||
|
if (file[0] != ".") {
|
||||||
|
// delete face file
|
||||||
|
fs.unlink(config.faces_dir + file, function(err){
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// delete helm file, we assume this exists as well
|
||||||
|
fs.unlink(config.helms_dir + file, function(err){
|
||||||
|
if (err) {
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// sets the date of the face file belonging to +hash+ to now
|
// sets the date of the face file belonging to +hash+ to now
|
||||||
|
// the helms file is ignored because we only need 1 file to read/write from
|
||||||
function update_file_date(hash) {
|
function update_file_date(hash) {
|
||||||
if (hash) {
|
if (hash) {
|
||||||
var path = config.faces_dir + hash + ".png";
|
var path = config.faces_dir + hash + ".png";
|
||||||
|
|||||||
@ -57,6 +57,7 @@ function store_images(uuid, details, callback) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// profile found, but has no skin
|
// profile found, but has no skin
|
||||||
|
cache.save_hash(uuid, null);
|
||||||
callback(null, null);
|
callback(null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,9 +84,10 @@ function skin_url(profile) {
|
|||||||
// callback contains error, status, hash
|
// callback contains error, status, hash
|
||||||
// the status gives information about how the image was received
|
// the status gives information about how the image was received
|
||||||
// -1: error
|
// -1: error
|
||||||
|
// 0: cached as null
|
||||||
// 1: found on disk
|
// 1: found on disk
|
||||||
// 2: profile requested/found, skin downloaded from mojang servers
|
// 2: profile requested/found, skin downloaded from mojang servers
|
||||||
// 3: profile requested/found, but it has no skin
|
// 3: profile requested/found, but it has not changed or no skin
|
||||||
function get_image_hash(uuid, callback) {
|
function get_image_hash(uuid, callback) {
|
||||||
cache.get_details(uuid, function(err, details) {
|
cache.get_details(uuid, function(err, details) {
|
||||||
if (err) {
|
if (err) {
|
||||||
@ -102,7 +104,7 @@ function get_image_hash(uuid, callback) {
|
|||||||
callback(err, -1, details && details.hash);
|
callback(err, -1, details && details.hash);
|
||||||
} else {
|
} else {
|
||||||
console.log(uuid + " hash: " + hash);
|
console.log(uuid + " hash: " + hash);
|
||||||
callback(null, (hash ? 2 : 3), hash);
|
callback(null, (hash != (details && details.hash) ? 2 : 3), hash);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -36,7 +36,7 @@ exp.extract_helm = function(facefile, buffer, outname, callback) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
skin.crop(42, 8, 49, 15, function(err, helm_img) {
|
skin.crop(40, 8, 47, 15, function(err, helm_img) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
20
package.json
20
package.json
@ -4,9 +4,11 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"author": "Jake0oo0",
|
"author": "Jake0oo0",
|
||||||
"description": "A NodeJS application to server Minecraft avatars.",
|
"description": "A NodeJS application to server Minecraft avatars.",
|
||||||
"contributors": [{
|
"contributors": [
|
||||||
|
{
|
||||||
"name": "Jomo"
|
"name": "Jomo"
|
||||||
}],
|
}
|
||||||
|
],
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/Jake0oo0/crafatar"
|
"url": "https://github.com/Jake0oo0/crafatar"
|
||||||
@ -20,19 +22,21 @@
|
|||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node server.js",
|
"start": "node server.js",
|
||||||
"test": "node_modules/.bin/mocha"
|
"test": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "~4.9.0",
|
|
||||||
"body-parser": "~1.8.1",
|
"body-parser": "~1.8.1",
|
||||||
"cookie-parser": "~1.3.3",
|
"cookie-parser": "~1.3.3",
|
||||||
"morgan": "~1.3.0",
|
"coveralls": "^2.11.2",
|
||||||
"serve-favicon": "~2.1.3",
|
|
||||||
"debug": "~2.0.0",
|
"debug": "~2.0.0",
|
||||||
|
"express": "~4.9.0",
|
||||||
|
"istanbul": "^0.3.2",
|
||||||
"jade": "~1.6.0",
|
"jade": "~1.6.0",
|
||||||
"lwip": "0.0.5",
|
"lwip": "0.0.5",
|
||||||
"request": "2.45.0",
|
"mocha": "2.0.1",
|
||||||
|
"mocha-lcov-reporter": "0.0.1",
|
||||||
|
"morgan": "~1.3.0",
|
||||||
"redis": "0.12.1",
|
"redis": "0.12.1",
|
||||||
"mocha": "2.0.1"
|
"request": "2.45.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
public/favicon.png
Normal file
BIN
public/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 581 B |
@ -1,5 +1,8 @@
|
|||||||
body {
|
body {
|
||||||
font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;
|
font-size: 14px;
|
||||||
|
font-family: "Helvetica Neue", Arial, sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #666;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
@ -37,14 +40,42 @@ mark.green {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
color: #333;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.code {
|
.code {
|
||||||
|
display: block;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
min-height: 20px;
|
||||||
|
padding: 10px 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
background: #fafafa;
|
||||||
|
border-left: 3px solid;
|
||||||
|
border-radius: 0px 4px 4px 0px;
|
||||||
|
box-shadow: 0 0 1px inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sideface {
|
.sideface {
|
||||||
width: 160px;
|
width: 160px;
|
||||||
height: 160px;
|
height: 160px;
|
||||||
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sideface.Jake0oo0 {
|
.sideface.Jake0oo0 {
|
||||||
background:url("/avatars/2d5aa9cdaeb049189930461fc9b91cc5?size=160");
|
background:url("/avatars/2d5aa9cdaeb049189930461fc9b91cc5?size=160");
|
||||||
}
|
}
|
||||||
@ -60,9 +91,10 @@ mark.green {
|
|||||||
.sideface.Notch {
|
.sideface.Notch {
|
||||||
background:url("/avatars/069a79f444e94726a5befca90e38aaf5?size=160");
|
background:url("/avatars/069a79f444e94726a5befca90e38aaf5?size=160");
|
||||||
}
|
}
|
||||||
|
/* Notch please fid your skin -_-
|
||||||
.sideface.Notch:hover {
|
.sideface.Notch:hover {
|
||||||
background:url("/avatars/069a79f444e94726a5befca90e38aaf5?size=160&helm=true");
|
background:url("/avatars/069a79f444e94726a5befca90e38aaf5?size=160&helm=true");
|
||||||
}
|
}*/
|
||||||
.sideface.sk89q {
|
.sideface.sk89q {
|
||||||
background:url("/avatars/0ea8eca3dbf647cc9d1ac64551ca975c?size=160");
|
background:url("/avatars/0ea8eca3dbf647cc9d1ac64551ca975c?size=160");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,14 @@ var config = require('../modules/config');
|
|||||||
var skins = require('../modules/skins');
|
var skins = require('../modules/skins');
|
||||||
var networking = require('../modules/networking')
|
var networking = require('../modules/networking')
|
||||||
|
|
||||||
|
var human_status = {
|
||||||
|
0: "none",
|
||||||
|
1: "cached",
|
||||||
|
2: "checked",
|
||||||
|
3: "downloaded",
|
||||||
|
"-1": "error"
|
||||||
|
};
|
||||||
|
|
||||||
/* GET avatar request. */
|
/* GET avatar request. */
|
||||||
router.get('/:uuid.:ext?', function(req, res) {
|
router.get('/:uuid.:ext?', function(req, res) {
|
||||||
var uuid = req.params.uuid;
|
var uuid = req.params.uuid;
|
||||||
@ -25,47 +33,37 @@ router.get('/:uuid.:ext?', function(req, res) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
helpers.get_avatar(uuid, helm, size, function(err, status, image) {
|
helpers.get_avatar(uuid, helm, size, function(err, status, image) {
|
||||||
console.log(uuid + " - " + status);
|
console.log(uuid + " - " + human_status[status]);
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
if (image) {
|
|
||||||
console.warn("error occured, image found anyway");
|
|
||||||
sendimage(503, true, image);
|
|
||||||
} else {
|
|
||||||
handle_default(404);
|
|
||||||
}
|
}
|
||||||
} else if (status == 1 || status == 2) {
|
if (image) {
|
||||||
sendimage(200, status == 1, image);
|
sendimage(err ? 503 : 200, status, image);
|
||||||
} else if (status === 0 || status == 3) {
|
|
||||||
handle_default(404);
|
|
||||||
} else {
|
} else {
|
||||||
console.error("unexpected error/status");
|
handle_default(404, status);
|
||||||
console.error("error: " + err);
|
|
||||||
console.error("status: " + status);
|
|
||||||
handle_default(404);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
console.error("Error!");
|
console.error("Error!");
|
||||||
console.error(e);
|
console.error(e);
|
||||||
handle_default(500);
|
handle_default(500, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handle_default(status) {
|
function handle_default(http_status, img_status) {
|
||||||
if (def != "steve" && def != "alex") {
|
if (def != "steve" && def != "alex") {
|
||||||
def = skins.default_skin(uuid);
|
def = skins.default_skin(uuid);
|
||||||
}
|
}
|
||||||
skins.resize_img("public/images/" + def + ".png", size, function(err, image) {
|
skins.resize_img("public/images/" + def + ".png", size, function(err, image) {
|
||||||
sendimage(status, true, image);
|
sendimage(http_status, img_status, image);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendimage(status, local, image) {
|
function sendimage(http_status, img_status, image) {
|
||||||
res.writeHead(status, {
|
res.writeHead(http_status, {
|
||||||
'Content-Type': 'image/png',
|
'Content-Type': 'image/png',
|
||||||
'Cache-Control': 'max-age=' + config.browser_cache_time + ', public',
|
'Cache-Control': 'max-age=' + config.browser_cache_time + ', public',
|
||||||
'Response-Time': new Date() - start,
|
'Response-Time': new Date() - start,
|
||||||
'X-Storage-Type': local ? 'local' : 'downloaded'
|
'X-Storage-Type': human_status[img_status]
|
||||||
});
|
});
|
||||||
res.end(image);
|
res.end(image);
|
||||||
}
|
}
|
||||||
|
|||||||
25
test/test.js
25
test/test.js
@ -7,7 +7,7 @@ var config = require('../modules/config');
|
|||||||
var skins = require('../modules/skins');
|
var skins = require('../modules/skins');
|
||||||
var cache = require("../modules/cache");
|
var cache = require("../modules/cache");
|
||||||
|
|
||||||
var uuids = fs.readFileSync('test/uuids.txt').toString().split("\r\n");
|
var uuids = fs.readFileSync('test/uuids.txt').toString().split("\n");
|
||||||
// Get a random UUID in order to prevent rate limiting
|
// Get a random UUID in order to prevent rate limiting
|
||||||
var uuid = uuids[Math.floor((Math.random() * 200) + 1)];
|
var uuid = uuids[Math.floor((Math.random() * 200) + 1)];
|
||||||
|
|
||||||
@ -17,24 +17,37 @@ describe('Avatar Serving', function(){
|
|||||||
});
|
});
|
||||||
describe('UUID', function(){
|
describe('UUID', function(){
|
||||||
it("should be an invalid uuid", function(done){
|
it("should be an invalid uuid", function(done){
|
||||||
assert.equal(helpers.uuid_valid("invaliduuid"), false);
|
assert.strictEqual(helpers.uuid_valid("invaliduuid"), false);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
it("should be a valid uuid", function(done){
|
it("should be a valid uuid", function(done){
|
||||||
assert.equal(helpers.uuid_valid("0098cb60fa8e427cb299793cbd302c9a"), true);
|
assert.strictEqual(helpers.uuid_valid("0098cb60fa8e427cb299793cbd302c9a"), true);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
it("should not exist", function(done){
|
||||||
|
networking.get_profile("00000000000000000000000000000000", function(err, profile) {
|
||||||
|
assert.strictEqual(err, 0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
it("should exist without skin", function(done) {
|
||||||
|
// profile 'Alex'
|
||||||
|
helpers.get_avatar("ec561538f3fd461daff5086b22154bce", false, 160, function(err, status, image) {
|
||||||
|
assert.strictEqual(status, 3);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
describe('Avatar', function(){
|
describe('Avatar', function(){
|
||||||
it("should be downloaded", function(done) {
|
it("should be downloaded", function(done) {
|
||||||
helpers.get_avatar(uuid, false, 160, function(err, status, image) {
|
helpers.get_avatar(uuid, false, 160, function(err, status, image) {
|
||||||
assert.equal(status, 2);
|
assert.strictEqual(status, 2);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
it("should be local", function(done) {
|
it("should be local", function(done) {
|
||||||
helpers.get_avatar(uuid, false, 160, function(err, status, image) {
|
helpers.get_avatar(uuid, false, 160, function(err, status, image) {
|
||||||
assert.equal(status, 1);
|
assert.strictEqual(status, 1);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -45,7 +58,7 @@ describe('Avatar Serving', function(){
|
|||||||
});
|
});
|
||||||
it("should be rate limited", function(done) {
|
it("should be rate limited", function(done) {
|
||||||
helpers.get_avatar(uuid, false, 160, function(err, status, image) {
|
helpers.get_avatar(uuid, false, 160, function(err, status, image) {
|
||||||
assert.equal(err, null);
|
assert.strictEqual(err, null);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,22 +1,22 @@
|
|||||||
extends layout
|
extends layout
|
||||||
|
|
||||||
block content
|
block content
|
||||||
.container(style= "margin-top: 30px;")
|
.container(style= "margin-top: 70px;")
|
||||||
.row
|
.row
|
||||||
.col-md-10
|
.col-md-10
|
||||||
h1 Crafatar
|
h1 Crafatar
|
||||||
hr
|
hr
|
||||||
p Welcome to Crafatar, an API for Minecraft's faces!
|
p Welcome to Crafatar, an API for Minecraft's faces!
|
||||||
|
|
||||||
h2 API
|
|
||||||
hr
|
hr
|
||||||
|
h2 Documentation
|
||||||
|
|
||||||
h3 Endpoint
|
h3 Endpoint
|
||||||
p
|
p
|
||||||
| Replace
|
| Replace
|
||||||
mark.green uuid
|
mark.green uuid
|
||||||
| with a Mojang UUID to get the related head. All images are PNGs.
|
| with a Mojang UUID to get the related head. All images are PNGs.
|
||||||
.well.code
|
.code
|
||||||
| <img src="#{domain}/avatars/
|
| <img src="#{domain}/avatars/
|
||||||
mark.green uuid
|
mark.green uuid
|
||||||
| ">
|
| ">
|
||||||
@ -25,11 +25,11 @@ block content
|
|||||||
h4 size
|
h4 size
|
||||||
p The size of the image in pixels, 1 - 512. <br> Default is 160.
|
p The size of the image in pixels, 1 - 512. <br> Default is 160.
|
||||||
h4 default
|
h4 default
|
||||||
p The image to be returned when the uuid has no skin. <br> Valid options are
|
p The image to be returned when the uuid has no skin (404). <br> Valid options are
|
||||||
a(href="/avatars/00000000000000000000000000000000?default=steve") steve
|
a(href="/avatars/00000000000000000000000000000000?default=steve") steve
|
||||||
| or
|
| or
|
||||||
a(href="/avatars/00000000000000000000000000000000?default=alex") alex
|
a(href="/avatars/00000000000000000000000000000000?default=alex") alex
|
||||||
| .<br> The default is calculated based on the UUID (even = alex, odd = steve)
|
| .<br> The standard value is calculated based on the UUID (even = alex, odd = steve)
|
||||||
h4 helm
|
h4 helm
|
||||||
p Get an avatar with the second (helmet) layer applied. <br> The content of this parameter is ignored
|
p Get an avatar with the second (helmet) layer applied. <br> The content of this parameter is ignored
|
||||||
|
|
||||||
@ -38,22 +38,22 @@ block content
|
|||||||
h4 Response-Time
|
h4 Response-Time
|
||||||
p The time, in milliseconds, it took Crafatar to process the request.
|
p The time, in milliseconds, it took Crafatar to process the request.
|
||||||
h4 X-Storage-Type
|
h4 X-Storage-Type
|
||||||
p Either 'local' or 'downloaded'. Local means that Crafatar already had the image on disk, while downloaded means that it was retrieved from Mojang's skin servers.
|
ul
|
||||||
|
li <b>none</b>: No external requests. Cached: User has no skin.
|
||||||
|
li <b>cached</b>: No external requests. Skin cached and stored locally.
|
||||||
|
li <b>checked</b>: 1 external request. Skin cached, checked for updates, no skin downloaded.<br>
|
||||||
|
| This happens either when the user has no skin or it didn't change.
|
||||||
|
li <b>downloaded</b>: 2 external requests. Skin changed or unknown, downloaded.
|
||||||
|
li <b>error</b>: This can happen, for example, when Mojang's servers are down. If possible, an outdated image will be served instead.
|
||||||
|
|
||||||
h3 Examples
|
h3 Examples
|
||||||
p Get jeb_'s avatar, 160 × 160 pixels
|
p Get jeb_'s avatar, 160 × 160 pixels
|
||||||
img(src="/avatars/853c80ef3c3749fdaa49938b674adae6")
|
.code <img src="#{domain}/avatars/853c80ef3c3749fdaa49938b674adae6">
|
||||||
.well.code <img src="#{domain}/avatars/853c80ef3c3749fdaa49938b674adae6">
|
|
||||||
p Get jeb_'s avatar, 64 × 64 pixels
|
p Get jeb_'s avatar, 64 × 64 pixels
|
||||||
img(src="/avatars/853c80ef3c3749fdaa49938b674adae6?size=64")
|
.code <img src="#{domain}/avatars/853c80ef3c3749fdaa49938b674adae6?size=64">
|
||||||
.well.code <img src="#{domain}/avatars/853c80ef3c3749fdaa49938b674adae6?size=64">
|
|
||||||
p Get jeb_'s helmet avatar, 64 × 64 pixels
|
p Get jeb_'s helmet avatar, 64 × 64 pixels
|
||||||
img(src="/avatars/853c80ef3c3749fdaa49938b674adae6?size=64&helm")
|
.code <img src="#{domain}/avatars/853c80ef3c3749fdaa49938b674adae6?size=64&helm">
|
||||||
.well.code <img src="#{domain}/avatars/853c80ef3c3749fdaa49938b674adae6?size=64&helm">
|
.col-md-2.center
|
||||||
p Get jeb_'s avatar, 64 × 64 pixels, or fall back to steve if his avatar is not found
|
|
||||||
img(src="/avatars/00000000000000000000000000000000?default=steve&size=64")
|
|
||||||
.well.code <img src="#{domain}/avatars/853c80ef3c3749fdaa49938b674adae6?default=steve&size=64">
|
|
||||||
.col-md-2
|
|
||||||
.sideface.redstone_sheep(title="redstone_sheep")
|
.sideface.redstone_sheep(title="redstone_sheep")
|
||||||
.sideface.Jake0oo0(title="Jake0oo0")
|
.sideface.Jake0oo0(title="Jake0oo0")
|
||||||
.sideface.Notch(title="Notch")
|
.sideface.Notch(title="Notch")
|
||||||
|
|||||||
@ -2,15 +2,16 @@ doctype html
|
|||||||
html
|
html
|
||||||
head
|
head
|
||||||
title= title
|
title= title
|
||||||
link(rel='stylesheet', href='/stylesheets/style.css')
|
link(rel="icon", sizes="16x16", type="image/png", href="/favicon.png")
|
||||||
link(rel="icon", type="image/x-icon", href="/favicon.ico")
|
|
||||||
link(href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.0/css/bootstrap.min.css", rel="stylesheet")
|
link(href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.0/css/bootstrap.min.css", rel="stylesheet")
|
||||||
meta(name="viewport" content="initial-scale=1,maximum-scale=1")
|
link(rel='stylesheet', href='/stylesheets/style.css')
|
||||||
//script(src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.0/js/bootstrap.min.js")
|
meta(name="description", content="A Minecraft avatar service with UUID support")
|
||||||
|
meta(name="keywords", content="minecraft, avatar, uuid")
|
||||||
|
meta(name="viewport", content="initial-scale=1,maximum-scale=1")
|
||||||
body
|
body
|
||||||
a.forkme(href="https://github.com/Jake0oo0/crafatar", target="_blank") Fork me on GitHub
|
a.forkme(href="https://github.com/Jake0oo0/crafatar", target="_blank") Fork me on GitHub
|
||||||
.navbar.navbar-default.navbar-fixed-top
|
.navbar.navbar-default.navbar-fixed-top
|
||||||
.container
|
.container
|
||||||
.navbar-header
|
.navbar-header
|
||||||
a.navbar-brand(href='/') Crafatar
|
a.navbar-brand(href="#") Crafatar
|
||||||
block content
|
block content
|
||||||
Loading…
x
Reference in New Issue
Block a user