init
This commit is contained in:
commit
d8de108153
|
@ -0,0 +1,2 @@
|
||||||
|
/result
|
||||||
|
/node_modules/
|
|
@ -0,0 +1,81 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="1012"
|
||||||
|
height="1404"
|
||||||
|
viewBox="0 0 1012 1404"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
||||||
|
sodipodi:docname="error.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showborder="false"
|
||||||
|
shape-rendering="auto"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="0.96390292"
|
||||||
|
inkscape:cx="282.70482"
|
||||||
|
inkscape:cy="283.74227"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1046"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="-2"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="svg1"><inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="px"
|
||||||
|
originx="506"
|
||||||
|
originy="702"
|
||||||
|
spacingx="1"
|
||||||
|
spacingy="1"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="10"
|
||||||
|
dotted="true"
|
||||||
|
gridanglex="30"
|
||||||
|
gridanglez="30"
|
||||||
|
visible="true"
|
||||||
|
snapvisiblegridlinesonly="false"
|
||||||
|
enabled="false" /></sodipodi:namedview><defs
|
||||||
|
id="defs1"><rect
|
||||||
|
x="20.555475"
|
||||||
|
y="21.720669"
|
||||||
|
width="947.26782"
|
||||||
|
height="1339.3308"
|
||||||
|
id="rect1" /></defs><g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"><path
|
||||||
|
style="display:inline;fill:#000000;fill-opacity:1;stroke:#343434;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||||
|
id="rect1-2"
|
||||||
|
width="1003.9467"
|
||||||
|
height="1395.9467"
|
||||||
|
x="4.0266695"
|
||||||
|
y="4.0266695"
|
||||||
|
sodipodi:type="rect"
|
||||||
|
ry="58.536545"
|
||||||
|
mask="none"
|
||||||
|
inkscape:label="bg back" /><text
|
||||||
|
xml:space="preserve"
|
||||||
|
id="text1"
|
||||||
|
style="font-size:40px;line-height:1;font-family:Alatsi;-inkscape-font-specification:Alatsi;letter-spacing:0px;white-space:pre;shape-inside:url(#rect1);display:inline"><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="57.276259"
|
||||||
|
id="tspan4"><tspan
|
||||||
|
style="font-family:Minecraft;-inkscape-font-specification:Minecraft;fill:#ffffff"
|
||||||
|
id="tspan1">$error$</tspan></tspan></text></g></svg>
|
After Width: | Height: | Size: 2.7 KiB |
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 876 KiB |
|
@ -0,0 +1,150 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="1012"
|
||||||
|
height="1404"
|
||||||
|
viewBox="0 0 1012 1404"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
xml:space="preserve"
|
||||||
|
inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)"
|
||||||
|
sodipodi:docname="player-help.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"><sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showborder="false"
|
||||||
|
shape-rendering="auto"
|
||||||
|
showgrid="true"
|
||||||
|
inkscape:zoom="0.48195146"
|
||||||
|
inkscape:cx="401.49271"
|
||||||
|
inkscape:cy="606.90759"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1046"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="-2"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="layer1"><inkscape:grid
|
||||||
|
id="grid1"
|
||||||
|
units="px"
|
||||||
|
originx="506"
|
||||||
|
originy="702"
|
||||||
|
spacingx="1"
|
||||||
|
spacingy="1"
|
||||||
|
empcolor="#0099e5"
|
||||||
|
empopacity="0.30196078"
|
||||||
|
color="#0099e5"
|
||||||
|
opacity="0.14901961"
|
||||||
|
empspacing="10"
|
||||||
|
dotted="true"
|
||||||
|
gridanglex="30"
|
||||||
|
gridanglez="30"
|
||||||
|
visible="true"
|
||||||
|
snapvisiblegridlinesonly="false"
|
||||||
|
enabled="false" /></sodipodi:namedview><defs
|
||||||
|
id="defs1"><rect
|
||||||
|
x="20.555475"
|
||||||
|
y="21.720669"
|
||||||
|
width="947.26782"
|
||||||
|
height="1339.3308"
|
||||||
|
id="rect1" /></defs><g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"><path
|
||||||
|
style="display:inline;fill:#000000;fill-opacity:1;stroke:#343434;stroke-width:8;stroke-linecap:butt;stroke-linejoin:round;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke"
|
||||||
|
id="rect1-2"
|
||||||
|
width="1003.9467"
|
||||||
|
height="1395.9467"
|
||||||
|
x="4.0266695"
|
||||||
|
y="4.0266695"
|
||||||
|
sodipodi:type="rect"
|
||||||
|
ry="58.536545"
|
||||||
|
mask="none"
|
||||||
|
inkscape:label="bg back" /><text
|
||||||
|
xml:space="preserve"
|
||||||
|
id="text1"
|
||||||
|
style="font-size:40px;line-height:1;font-family:Minecraft;-inkscape-font-specification:Minecraft;fill:#ffffff;letter-spacing:0px;white-space:pre;shape-inside:url(#rect1);display:inline"
|
||||||
|
transform="translate(18.038217,310.07099)"><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="57.276259"
|
||||||
|
id="tspan5"><tspan
|
||||||
|
id="tspan1">Get your player's name, a link to their </tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="101.58182"
|
||||||
|
id="tspan7"><tspan
|
||||||
|
id="tspan6">profile picture (PNG preferred), and </tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="145.88737"
|
||||||
|
id="tspan9"><tspan
|
||||||
|
id="tspan8">the previously calculated damage and </tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="190.19293"
|
||||||
|
id="tspan11"><tspan
|
||||||
|
id="tspan10">health.
|
||||||
|
</tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="234.49849"
|
||||||
|
id="tspan13"><tspan
|
||||||
|
id="tspan12">
|
||||||
|
</tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="278.80404"
|
||||||
|
id="tspan15"><tspan
|
||||||
|
id="tspan14">Got all that? Apply it to the end of the </tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="323.1096"
|
||||||
|
id="tspan17"><tspan
|
||||||
|
id="tspan16">URL as so:
|
||||||
|
</tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="367.41517"
|
||||||
|
id="tspan19"><tspan
|
||||||
|
id="tspan18">
|
||||||
|
</tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="407.41516"
|
||||||
|
id="tspan21"><tspan
|
||||||
|
style="font-size:26.6667px"
|
||||||
|
id="tspan20">/front.png?name=player&image=https://example.com/</tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="447.41516"
|
||||||
|
id="tspan23"><tspan
|
||||||
|
style="font-size:26.6667px"
|
||||||
|
id="tspan22">image.png&dmg=0&hp=0
|
||||||
|
</tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="487.41516"
|
||||||
|
id="tspan25"><tspan
|
||||||
|
style="font-size:26.6667px"
|
||||||
|
id="tspan24">
|
||||||
|
</tspan></tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="531.72072"
|
||||||
|
id="tspan26">If you're happy with how that looks, </tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="576.02626"
|
||||||
|
id="tspan27">create a new custom card. Set its </tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="620.3318"
|
||||||
|
id="tspan28">front texture URL to this, and its back </tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="664.63734"
|
||||||
|
id="tspan29">texture URL to /back.png.
|
||||||
|
</tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="708.94288"
|
||||||
|
id="tspan30">
|
||||||
|
</tspan><tspan
|
||||||
|
x="20.554688"
|
||||||
|
y="753.24843"
|
||||||
|
id="tspan31">After you're done, continue as normal.</tspan></text></g></svg>
|
After Width: | Height: | Size: 4.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.4 MiB |
|
@ -0,0 +1,61 @@
|
||||||
|
{
|
||||||
|
"nodes": {
|
||||||
|
"flake-utils": {
|
||||||
|
"inputs": {
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1709126324,
|
||||||
|
"narHash": "sha256-q6EQdSeUZOG26WelxqkmR7kArjgWCdw5sfJVHPH/7j8=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "d465f4819400de7c8d874d50b982301f28a84605",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1709569716,
|
||||||
|
"narHash": "sha256-iOR44RU4jQ+YPGrn+uQeYAp7Xo7Z/+gT+wXJoGxxLTY=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "617579a787259b9a6419492eaac670a5f7663917",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-23.11",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils",
|
||||||
|
"nixpkgs": "nixpkgs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"systems": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"root": "root",
|
||||||
|
"version": 7
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
{
|
||||||
|
description = "cardgen";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.11";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let
|
||||||
|
pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
package = builtins.fromJSON (builtins.readFile ./package.json);
|
||||||
|
in
|
||||||
|
rec {
|
||||||
|
packages = flake-utils.lib.flattenTree rec {
|
||||||
|
cardgen = pkgs.buildNpmPackage rec {
|
||||||
|
pname = "cardgen";
|
||||||
|
inherit (package) version;
|
||||||
|
|
||||||
|
npmDepsHash = "sha256-1gQydlNbMBwCWj8++d79aBy5QaIIwiLMpsdurRz8FDA=";
|
||||||
|
|
||||||
|
doCheck = false;
|
||||||
|
|
||||||
|
nativeBuildInputs = with pkgs; [ makeWrapper ];
|
||||||
|
|
||||||
|
dontNpmBuild = true;
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out
|
||||||
|
mv ./* $out/
|
||||||
|
makeWrapper ${pkgs.nodejs-slim}/bin/node $out/bin/cardgen \
|
||||||
|
--add-flags $out/index.js \
|
||||||
|
--chdir $out/
|
||||||
|
'';
|
||||||
|
|
||||||
|
src = ./.;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultPackage = packages.cardgen;
|
||||||
|
}) // {
|
||||||
|
nixosModules = {
|
||||||
|
cardgen = { config, lib, pkgs, ... }:
|
||||||
|
with lib;
|
||||||
|
let
|
||||||
|
cfg = config.services.cardgen;
|
||||||
|
in {
|
||||||
|
options.services.cardgen = {
|
||||||
|
enable = mkEnableOption "Enables the cardgen server";
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.port;
|
||||||
|
default = 3500;
|
||||||
|
};
|
||||||
|
package = mkOption {
|
||||||
|
type = types.package;
|
||||||
|
default = self.defaultPackage.${pkgs.system};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf cfg.enable {
|
||||||
|
systemd.services."cardgen" = {
|
||||||
|
wantedBy = [ "multi-user.target" ];
|
||||||
|
|
||||||
|
environment = {
|
||||||
|
PORT = toString cfg.port;
|
||||||
|
};
|
||||||
|
|
||||||
|
serviceConfig = {
|
||||||
|
Restart = "on-failure";
|
||||||
|
ExecStart = "${getExe cfg.package}";
|
||||||
|
DynamicUser = "yes";
|
||||||
|
StateDirectory = "cardgen";
|
||||||
|
StateDirectoryMode = "0755";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,3 @@
|
||||||
|
uses the following fonts:
|
||||||
|
- [Minecraft](https://github.com/IdreesInc/Minecraft-Font/releases/tag/v1.0)
|
||||||
|
- [Atkinson Hyperlegible](https://brailleinstitute.org/freefont)
|
|
@ -0,0 +1,174 @@
|
||||||
|
import express from 'express';
|
||||||
|
import { Resvg } from '@resvg/resvg-js';
|
||||||
|
import * as fs from 'fs/promises';
|
||||||
|
import { escape } from 'html-escaper';
|
||||||
|
import { request } from 'undici';
|
||||||
|
import { lookup as mimeLookup } from 'mime-types';
|
||||||
|
|
||||||
|
const errorSVG = 'cards/error.svg';
|
||||||
|
|
||||||
|
const cards = {
|
||||||
|
player: {
|
||||||
|
cards: {
|
||||||
|
front: {
|
||||||
|
name: 'cards/player-front.svg',
|
||||||
|
parameters: [
|
||||||
|
{ name: 'name', type: 'string' },
|
||||||
|
{ name: 'dmg', type: 'number' },
|
||||||
|
{ name: 'hp', type: 'number' },
|
||||||
|
{ name: 'image', type: 'image', optional: true },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
back: {
|
||||||
|
name: 'cards/skilled-back.png',
|
||||||
|
ignoreParameters: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
special: {
|
||||||
|
help: 'cards/player-help.svg',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function svg(filename, params) {
|
||||||
|
let svg = await fs.readFile(filename, 'utf8');
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(params)) {
|
||||||
|
svg = svg.replaceAll('$' + key + '$', escape(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
return svg;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function render(svg) {
|
||||||
|
const opts = {
|
||||||
|
font: {
|
||||||
|
fontFiles: [
|
||||||
|
'fonts/Atkinson-Hyperlegible-Bold.otf',
|
||||||
|
'fonts/Atkinson-Hyperlegible-BoldItalic.otf',
|
||||||
|
'fonts/Atkinson-Hyperlegible-Italic.otf',
|
||||||
|
'fonts/Atkinson-Hyperlegible-Regular.otf',
|
||||||
|
'fonts/Minecraft.otf',
|
||||||
|
'fonts/Minecraft-Bold.otf',
|
||||||
|
],
|
||||||
|
loadSystemFonts: false, // It will be faster to disable loading system fonts.
|
||||||
|
defaultFontFamily: 'Atkinson Hyperlegible',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const resvg = new Resvg(svg, opts);
|
||||||
|
const pngData = resvg.render();
|
||||||
|
const pngBuffer = pngData.asPng();
|
||||||
|
|
||||||
|
return pngBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const server = express();
|
||||||
|
|
||||||
|
async function returns(req, res, filename, params) {
|
||||||
|
const ext = req.params.ext;
|
||||||
|
|
||||||
|
const s = await svg(filename, params);
|
||||||
|
if (ext === 'png') {
|
||||||
|
const r = await render(s);
|
||||||
|
res.type('png');
|
||||||
|
res.setHeader('Content-Length', r.byteLength);
|
||||||
|
res.send(r);
|
||||||
|
} else if (ext === 'svg') {
|
||||||
|
res.type('svg');
|
||||||
|
res.setHeader('Content-Length', s.length);
|
||||||
|
res.send(s);
|
||||||
|
} else {
|
||||||
|
res.status(400).send(`Unknown filetype '${ext}'`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function err(req, res, error) {
|
||||||
|
returns(req, res, errorSVG, { error });
|
||||||
|
}
|
||||||
|
|
||||||
|
const userAgent = 'cardgen/0.0.0 (https://oat.zone/)';
|
||||||
|
|
||||||
|
async function resolveImg(url) {
|
||||||
|
const { body, statusCode } = await request(url, {
|
||||||
|
headers: { 'user-agent': userAgent },
|
||||||
|
});
|
||||||
|
if (statusCode !== 200) throw `Image returned non-200 error code`;
|
||||||
|
|
||||||
|
const blob = await body.blob();
|
||||||
|
const arrayBuffer = await blob.arrayBuffer();
|
||||||
|
const b64 = Buffer.from(arrayBuffer).toString('base64');
|
||||||
|
|
||||||
|
const mime = mimeLookup(url) || 'image/png';
|
||||||
|
|
||||||
|
return 'data:' + mime + ';base64,' + b64;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveNumber(str) {
|
||||||
|
const int = parseInt(str);
|
||||||
|
if (isNaN(int)) throw 'Invalid number provided';
|
||||||
|
return int;
|
||||||
|
}
|
||||||
|
|
||||||
|
server.get('/:type/:name.:ext', async (req, res) => {
|
||||||
|
if (req.headers['user-agent'] === userAgent) return err(req, res, 'Stop that.');
|
||||||
|
|
||||||
|
const type = req.params.type;
|
||||||
|
const name = req.params.name;
|
||||||
|
const ext = req.params.ext;
|
||||||
|
|
||||||
|
const card = cards[type];
|
||||||
|
|
||||||
|
if (!card) return err(req, res, `No card named ${type} found!`);
|
||||||
|
|
||||||
|
const tex = card.cards[name];
|
||||||
|
|
||||||
|
if (!tex) return err(req, res, `Card ${type} does not have ${name}`);
|
||||||
|
|
||||||
|
let params = {};
|
||||||
|
|
||||||
|
if (card.special.help && Object.entries(req.query).length === 0 && tex.parameters)
|
||||||
|
return returns(req, res, card.special.help, {});
|
||||||
|
|
||||||
|
if (tex.name.endsWith('.png')) {
|
||||||
|
if (ext !== 'png') {
|
||||||
|
res.status(400).send(`Cannot offer ${ext}; only a png of this texture xists`);
|
||||||
|
}
|
||||||
|
return res.sendFile(tex.name, { root: './' });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const param of (tex.parameters || [])) {
|
||||||
|
const name = param.name;
|
||||||
|
const type = param.type;
|
||||||
|
const isOptional = param.optional;
|
||||||
|
|
||||||
|
const value = req.query[name];
|
||||||
|
|
||||||
|
if (!isOptional && (value === undefined || value === null || value === '')) {
|
||||||
|
return err(req, res, `Required argument ${name} missing`);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (type) {
|
||||||
|
case 'string':
|
||||||
|
params[name] = value || '';
|
||||||
|
break;
|
||||||
|
case 'number':
|
||||||
|
params[name] = value ? resolveNumber(value) : 0;
|
||||||
|
break;
|
||||||
|
case 'image':
|
||||||
|
params[name] = value ? await resolveImg(value) : '';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} catch(e) {
|
||||||
|
return err(req, res, `${name}: ${e}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await returns(req, res, tex.name, params);
|
||||||
|
});
|
||||||
|
|
||||||
|
const port = process.env.PORT || 8080;
|
||||||
|
server.listen(port);
|
||||||
|
console.log(`listening on port ${port}`);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "cardgen",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"main": "index.js",
|
||||||
|
"author": "oatmealine",
|
||||||
|
"license": "GPL-3.0-only",
|
||||||
|
"type": "module",
|
||||||
|
"dependencies": {
|
||||||
|
"@resvg/resvg-js": "^2.6.0",
|
||||||
|
"express": "^4.18.3",
|
||||||
|
"html-escaper": "^3.0.3",
|
||||||
|
"mime-types": "^2.1.35",
|
||||||
|
"undici": "^6.7.0"
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue