Battler-Generator/index.ts
2024-06-17 19:25:55 +01:00

952 lines
27 KiB
TypeScript

import { createCanvas, loadImage, GlobalFonts } from "@napi-rs/canvas";
import {
GenerateBattlerOptions,
GenerateBattleImageOptions,
PlayerActionOptions,
Opponents,
CustomActionOptions
} from "./types";
import {
generateBattler, drawText, applyText,
validOpponents, validPlayerActions
} from "./utils";
import { createServer } from "node:http";
import GenerateParty from "./party"
GlobalFonts
.registerFromPath(import.meta.dirname + "/LilitaOne.ttf", "Lilita One");
const opponents = {
[Opponents.BattleBeginner]: {
text: "Battle Beginner",
colour: ["#007500", "#FFFFFF"]
},
[Opponents.BattleBeginner2024]: {
text: "Battle Beginner",
colour: ["#007500", "#FFFFFF"]
},
[Opponents.BattleCasual]: {
text: "Battle Casual",
colour: ["#757500", "#FFFFFF"]
},
[Opponents.BattleMaster]: {
text: "Battle Master",
colour: ["#750000", "#FFFFFF"]
},
[Opponents.BattlePro]: {
text: "Battle Pro",
colour: ["#753000", "#FFFFFF"]
},
[Opponents.Battler]: {
text: "Battler",
colour: ["#FFFFFF", "#000000"]
},
[Opponents.BattlerElite]: {
text: "Battler Elite",
colour: ["#FFFFFF", "#FF0000"]
},
[Opponents.None]: {
text: "",
colour: ["#FFFFFF", "#FFFFFF"]
},
[Opponents.RapStar]: {
text: "Rap Star",
colour: ["#FF0000", "#FFFFFF"]
},
[Opponents.ArtMaster]: {
text: "Art Master",
colour: ["#000000", "#FFFFFF"]
},
[Opponents.TheInterrogator]: {
text: "The Interrogator",
colour: ["#FFFFFF", "#000000"]
},
[Opponents.CommonOverseer]: {
text: "Common Overseer",
colour: ["#000000", "#32CD32"]
},
[Opponents.Moonlite]: {
text: "Moonlite",
colour: ["#000000", "#FFFFFF"]
},
[Opponents.Dicey]: {
text: "Dicey",
colour: ["#000000", "#FFFFFF"]
},
[Opponents.Kacey]: {
text: "Kacey",
colour: ["#000000", "#FFFFFF"]
},
[Opponents.Lexa]: {
text: "Lexa",
colour: ["#FFFFFF", "#FF00FF"]
},
[Opponents.Delta]: {
text: "Delta",
colour: ["#000000", "#FFFFFF"]
},
[Opponents.DoodlePro]: {
text: "Doodle Pro",
colour: ["#000000", "#FFFFFF"]
},
[Opponents.GuitarHero]: {
text: "Guitar Hero",
colour: ["#FFFFFF", "#FF8000"]
},
[Opponents.SmallKeyMaster]: {
text: "Small KeyMaster",
colour: ["#FFFFFF", "#32CD32"]
},
[Opponents.RareOverseer]: {
text: "Rare Overseer",
colour: ["#000000", "#00FFFF"]
},
[Opponents.DEMUL]: {
text: "DEMUL",
colour: ["#FFFFFF", "#000000"]
},
[Opponents.AgentZ]: {
text: "Agent Z",
colour: ["#FFFFFF", "#000000"]
},
[Opponents.MediumKeyMaster]: {
text: "Medium KeyMaster",
colour: ["#000000", "#00FFFF"]
},
[Opponents.IncomingSword]: {
text: "Incoming Sword",
colour: ["#FF0000", "#FFFFFF"]
},
[Opponents.Eda]: {
text: "Eda",
colour: ["#9000FF", "#FFFFFF"]
},
[Opponents.TheFirewall]: {
text: "The Firewall",
colour: ["#FFFFFF", "#FFAA00"]
},
[Opponents.HouseannorSupport]: {
text: "Houseannor Support",
colour: ["#FF00FF", "#FFFFFF"]
},
[Opponents.Dicey2024]: {
text: "Dicey",
colour: ["#000000", "#FFFFFF"]
},
[Opponents.CakeDay]: {
text: "Cake Day",
colour: ["#FA61FF", "#FFFFFF"]
},
[Opponents.MasterOG]: {
text: "Master OG",
colour: ["#FF0000", "#FFFFFF"]
}
}
// const _server = Bun.serve({
// port: 41399,
// async fetch(req: Request) {
// if (req.method == "OPTIONS") {
// return new Response(null, {
// headers: {
// "access-control-allow-origin": "*",
// },
// });
// }
// const url = new URL(req.url);
// if (req.method == "GET" && url.pathname == "/") {
// return new Response(null, {
// status: 204
// });
// }
// if (req.method == "GET" && url.pathname == "/party.png") {
// return GenerateParty(req, url)
// }
// if (req.method == "GET" && url.pathname == "/battler.png") {
// const opts = Object.fromEntries(
// Array.from(url.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as GenerateBattlerOptions;
// const battler = await generateBattler(opts);
// return new Response(battler.toBuffer("image/png"), {
// headers: {
// "content-type": "image/png",
// },
// });
// }
// if (req.method == "GET" && url.pathname == "/profilebattler.png") {
// const opts = Object.fromEntries(
// Array.from(url.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as GenerateBattlerOptions & { username: string };
// const canvas = createCanvas(1280, 1280);
// const ctx = canvas.getContext("2d");
// const battler = await generateBattler(opts)
// ctx.drawImage(battler, 0, 0);
// ctx.textAlign = "center"
// ctx.font = applyText(canvas, opts.username, canvas.width - 20)
// drawText([640, 1100], opts.username, opts.username == "homeannor" ? "#AA00FF" : "#000000", { colour: "#FFFFFF", width: 20 }, ctx)
// return new Response(canvas.toBuffer("image/png"), {
// headers: {
// "content-type": "image/png",
// },
// });
// }
// if (
// req.method == "GET" &&
// (url.pathname == "/battlesquadfight.png" ||
// url.pathname == "/battlestart.png")
// ) {
// const opts = Object.fromEntries(
// Array.from(url.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as GenerateBattlerOptions & GenerateBattleImageOptions;
// if (!opts.opponent) {
// return new Response(
// JSON.stringify({
// error: '"opponent" query parameter not specified',
// }),
// {
// status: 400,
// headers: {
// "content-type": "application/json",
// },
// },
// );
// }
// // Image dimensions
// const canvas = createCanvas(1920, 1080);
// const context = canvas.getContext("2d");
// if (!validOpponents.includes(opts.opponent)) opts.opponent = Opponents.None
// const SquadBackground = await loadImage(
// `./assets/battlebgs/${opts.opponent}.png`,
// );
// context.drawImage(SquadBackground, 0, 0, canvas.width, canvas.height);
// const battler = await generateBattler(opts);
// context.drawImage(battler, -140, -100, battler.width, battler.height);
// context.textAlign = "center"
// context.font = applyText(canvas, opponents[opts.opponent].text, 875)
// drawText([1450, 1000], opponents[opts.opponent].text, opponents[opts.opponent].colour[1], { colour: opponents[opts.opponent].colour[0], width: 20 }, context);
// context.font = applyText(canvas, opts.username, 675)
// drawText([470, 1000], opts.username, opts.username == "homeannor" ? "#AA00FF" : "#000000", { colour: "#FFFFFF", width: 20 }, context)
// return new Response(canvas.toBuffer("image/png"), {
// headers: {
// "content-type": "image/png",
// },
// });
// }
// if (
// req.method == "GET" &&
// url.pathname == "/playeraction.png"
// ) {
// const opts = Object.fromEntries(
// Array.from(url.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as PlayerActionOptions;
// if (!opts.action) {
// return new Response(
// JSON.stringify({
// error: '"action" query parameter not specified',
// }),
// {
// status: 400,
// headers: {
// "content-type": "application/json",
// },
// },
// );
// }
// if (!validPlayerActions.includes(opts.action)) {
// return new Response(
// JSON.stringify({
// error:
// '"action" query parameter not formatted correctly. Got "' +
// opts.action +
// '".',
// }),
// {
// status: 400,
// headers: {
// "content-type": "application/json",
// },
// },
// );
// }
// // Image dimensions
// const canvas = createCanvas(1920, 1080);
// const context = canvas.getContext("2d");
// const actionBackground = await loadImage(
// `./assets/actionbgs/${opts.action}.png`,
// );
// context.drawImage(actionBackground, 0, 0, canvas.width, canvas.height);
// const pUrl = new URL(encodeURI(opts.player))
// const player = Object.fromEntries(
// Array.from(pUrl.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as GenerateBattlerOptions
// if (opts.action.endsWith("Left")) {
// const battler = await generateBattler(player);
// context.drawImage(battler, -50, -100, battler.width, battler.height);
// } else if (opts.action.endsWith("Right")) {
// const battler = await generateBattler({ ...player, direction: "left" });
// context.drawImage(battler, (canvas.width / 2) - 300, -100, battler.width, battler.height);
// }
// return new Response(canvas.toBuffer("image/png"), {
// headers: {
// "content-type": "image/png",
// },
// });
// }
// if (
// req.method == "GET" &&
// url.pathname == "/customaction.png"
// ) {
// const opts = Object.fromEntries(
// Array.from(url.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as CustomActionOptions;
// if (!opts.background) {
// return new Response(
// JSON.stringify({
// error: '"background" query parameter not specified',
// }),
// {
// status: 400,
// headers: {
// "content-type": "application/json",
// },
// },
// );
// }
// // Image dimensions
// const canvas = createCanvas(1920, 1080);
// const context = canvas.getContext("2d");
// const actionBackground = await loadImage(
// opts.background,
// );
// context.drawImage(actionBackground, 0, 0, canvas.width, canvas.height);
// const pUrl = new URL(encodeURI(opts.player))
// const player = Object.fromEntries(
// Array.from(pUrl.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as GenerateBattlerOptions
// const battler = await generateBattler(player);
// if (opts.position == "middle") {
// context.drawImage(battler, (1920 / 2) - 640, -100, battler.width, battler.height);
// } else {
// context.drawImage(battler, -50, -100, battler.width, battler.height);
// }
// return new Response(canvas.toBuffer("image/png"), {
// headers: {
// "content-type": "image/png",
// },
// });
// }
// if (
// req.method == "GET" &&
// url.pathname == "/playermap.png"
// ) {
// const opts = Object.fromEntries(
// Array.from(url.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as { player1: string, player2: string, map: string };
// if (!opts.player1 || !opts.player2 || !opts.map) {
// return new Response(
// JSON.stringify({
// error: 'Did not pass all parameters',
// }),
// {
// status: 400,
// headers: {
// "content-type": "application/json",
// },
// },
// );
// }
// const p1URL = new URL(encodeURI(opts.player1))
// const p2URL = new URL(encodeURI(opts.player2))
// const p1Opts = Object.fromEntries(
// Array.from(p1URL.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as GenerateBattlerOptions
// const p2Opts = Object.fromEntries(
// Array.from(p2URL.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as GenerateBattlerOptions
// const p1 = await generateBattler(p1Opts);
// const p2 = await generateBattler({ ...p2Opts, direction: "left" })
// // Image dimensions
// const canvas = createCanvas(1920, 1080);
// const context = canvas.getContext("2d");
// const Background = await loadImage(
// `./assets/locations/${opts.map}.png`,
// );
// context.drawImage(Background, 0, 0, canvas.width, canvas.height);
// context.drawImage(p1, 140, 313, p1.width / 2, p1.height / 2);
// context.drawImage(p2, (canvas.width / 2) + 177, 313, p2.width / 2, p2.height / 2);
// return new Response(canvas.toBuffer("image/png"), {
// headers: {
// "content-type": "image/png",
// },
// });
// }
// if (
// req.method == "GET" &&
// url.pathname == "/map.png"
// ) {
// const opts = Object.fromEntries(
// Array.from(url.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as { player: string, map: string };
// if (!opts.player || !opts.map) {
// return new Response(
// JSON.stringify({
// error: 'Did not pass all parameters',
// }),
// {
// status: 400,
// headers: {
// "content-type": "application/json",
// },
// },
// );
// }
// const p1URL = new URL(encodeURI(opts.player))
// const p1Opts = Object.fromEntries(
// Array.from(p1URL.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as GenerateBattlerOptions
// const p1 = await generateBattler(p1Opts);
// // Image dimensions
// const canvas = createCanvas(1920, 1080);
// const context = canvas.getContext("2d");
// const Background = await loadImage(
// `./assets/locations/${opts.map}.png`,
// );
// context.drawImage(Background, 0, 0, canvas.width, canvas.height);
// context.drawImage(p1, 140, 313, p1.width / 2, p1.height / 2);
// return new Response(canvas.toBuffer("image/png"), {
// headers: {
// "content-type": "image/png",
// },
// });
// }
// if (
// req.method == "GET" &&
// url.pathname == "/pvp.png"
// ) {
// const opts = Object.fromEntries(
// Array.from(url.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as { player1: string, player2: string, username1: string, username2: string };
// if (!opts.player1 || !opts.player2 || !opts.username1 || !opts.username2) {
// return new Response(
// JSON.stringify({
// error: 'Did not pass all parameters',
// }),
// {
// status: 400,
// headers: {
// "content-type": "application/json",
// },
// },
// );
// }
// const p1URL = new URL(encodeURI(opts.player1))
// const p2URL = new URL(encodeURI(opts.player2))
// const p1Opts = Object.fromEntries(
// Array.from(p1URL.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as GenerateBattlerOptions
// const p2Opts = Object.fromEntries(
// Array.from(p2URL.searchParams.entries())
// .map(([key, value]) => [key, value.replaceAll('+', ' ')]),
// ) as GenerateBattlerOptions
// const p1 = await generateBattler(p1Opts);
// const p2 = await generateBattler({ ...p2Opts, direction: "left" })
// // Image dimensions
// const canvas = createCanvas(1920, 1080);
// const context = canvas.getContext("2d");
// const Background = await loadImage(
// `./assets/battlebgs/PvP.png`,
// );
// context.drawImage(Background, 0, 0, canvas.width, canvas.height);
// context.drawImage(p1, -140, -100, p1.width, p1.height);
// context.drawImage(p2, (canvas.width / 2) - 180, -100, p2.width, p2.height);
// context.textAlign = "center"
// context.font = applyText(canvas, opts.username2, 675)
// drawText([1450, 1000], opts.username2, opts.username2 == "homeannor" ? "#AA00FF" : "#000000", { colour: "#FFFFFF", width: 20 }, context)
// context.font = applyText(canvas, opts.username1, 675)
// drawText([470, 1000], opts.username1, opts.username1 == "homeannor" ? "#AA00FF" : "#000000", { colour: "#FFFFFF", width: 20 }, context)
// return new Response(canvas.toBuffer("image/png"), {
// headers: {
// "content-type": "image/png",
// },
// });
// }
// return new Response(`Cannot ${req.method} ${url.pathname}`, {
// status: 404,
// });
// },
// });
const server = createServer(async (req, res) => {
if (req.method === "OPTIONS") {
res.setHeader("access-control-allow-origin", "*")
return res.end();
}
const url = new URL(req.url!, "https://loc.al");
console.log(req.method, url.pathname)
if (req.method == "GET" && url.pathname == "/battler.png") {
const opts = Object.fromEntries(
Array.from(url.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as GenerateBattlerOptions;
const battler = await generateBattler(opts);
res.setHeader('content-type', 'image/png');
return res.end(battler.toBuffer("image/png"), 'binary')
}
if (req.method == "GET" && url.pathname == "/profilebattler.png") {
const opts = Object.fromEntries(
Array.from(url.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as GenerateBattlerOptions & { username: string };
const canvas = createCanvas(1280, 1280);
const ctx = canvas.getContext("2d");
const battler = await generateBattler(opts)
ctx.drawImage(battler, 0, 0);
ctx.textAlign = "center"
ctx.font = applyText(canvas, opts.username, canvas.width - 20)
drawText([640, 1100], opts.username, opts.username == "homeannor" ? "#AA00FF" : "#000000", { colour: "#FFFFFF", width: 20 }, ctx)
res.setHeader('content-type', 'image/png');
return res.end(canvas.toBuffer("image/png"), 'binary')
}
if (
req.method == "GET" &&
(url.pathname == "/battlesquadfight.png" ||
url.pathname == "/battlestart.png")
) {
const opts = Object.fromEntries(
Array.from(url.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as GenerateBattlerOptions & GenerateBattleImageOptions;
if (!opts.opponent) {
res.writeHead(400, { 'content-type': "application/json" })
return res.end(
JSON.stringify({
error: '"opponent" query parameter not specified',
})
);
}
// Image dimensions
const canvas = createCanvas(1920, 1080);
const context = canvas.getContext("2d");
if (!validOpponents.includes(opts.opponent)) opts.opponent = Opponents.None
const SquadBackground = await loadImage(
`./assets/battlebgs/${opts.opponent}.png`,
);
context.drawImage(SquadBackground, 0, 0, canvas.width, canvas.height);
const battler = await generateBattler(opts);
context.drawImage(battler, -140, -100, battler.width, battler.height);
context.textAlign = "center"
context.font = applyText(canvas, opponents[opts.opponent].text, 875)
drawText([1450, 1000], opponents[opts.opponent].text, opponents[opts.opponent].colour[1], { colour: opponents[opts.opponent].colour[0], width: 20 }, context);
context.font = applyText(canvas, opts.username, 675)
drawText([470, 1000], opts.username, opts.username == "homeannor" ? "#AA00FF" : "#000000", { colour: "#FFFFFF", width: 20 }, context)
res.setHeader('content-type', 'image/png');
return res.end(canvas.toBuffer("image/png"), 'binary')
}
if (
req.method == "GET" &&
url.pathname == "/playeraction.png"
) {
const opts = Object.fromEntries(
Array.from(url.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as PlayerActionOptions;
if (!opts.action) {
res.writeHead(400, { 'content-type': "application/json" })
return res.end(
JSON.stringify({
error: '"action" query parameter not specified',
})
);
}
if (!validPlayerActions.includes(opts.action)) {
res.writeHead(400, { 'content-type': "application/json" })
return res.end(
JSON.stringify({
error:
'"action" query parameter not formatted correctly. Got "' +
opts.action +
'".',
})
);
}
// Image dimensions
const canvas = createCanvas(1920, 1080);
const context = canvas.getContext("2d");
const actionBackground = await loadImage(
`./assets/actionbgs/${opts.action}.png`,
);
context.drawImage(actionBackground, 0, 0, canvas.width, canvas.height);
const pUrl = new URL(encodeURI(opts.player))
const player = Object.fromEntries(
Array.from(pUrl.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as GenerateBattlerOptions
if (opts.action.endsWith("Left")) {
const battler = await generateBattler(player);
context.drawImage(battler, -50, -100, battler.width, battler.height);
} else if (opts.action.endsWith("Right")) {
const battler = await generateBattler({ ...player, direction: "left" });
context.drawImage(battler, (canvas.width / 2) - 300, -100, battler.width, battler.height);
}
res.setHeader('content-type', 'image/png');
return res.end(canvas.toBuffer("image/png"), 'binary')
}
if (
req.method == "GET" &&
url.pathname == "/customaction.png"
) {
const opts = Object.fromEntries(
Array.from(url.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as CustomActionOptions;
if (!opts.background) {
res.writeHead(400, { 'content-type': "application/json" })
return res.end(
JSON.stringify({
error:
'"background" query parameter not found',
})
);
}
// Image dimensions
const canvas = createCanvas(1920, 1080);
const context = canvas.getContext("2d");
const actionBackground = await loadImage(
opts.background,
);
context.drawImage(actionBackground, 0, 0, canvas.width, canvas.height);
const pUrl = new URL(encodeURI(opts.player))
const player = Object.fromEntries(
Array.from(pUrl.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as GenerateBattlerOptions
const battler = await generateBattler(player);
if (opts.position == "middle") {
context.drawImage(battler, (1920 / 2) - 640, -100, battler.width, battler.height);
} else {
context.drawImage(battler, -50, -100, battler.width, battler.height);
}
res.setHeader('content-type', 'image/png');
return res.end(canvas.toBuffer("image/png"), 'binary')
}
if (
req.method == "GET" &&
url.pathname == "/playermap.png"
) {
const opts = Object.fromEntries(
Array.from(url.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as { player1: string, player2: string, map: string };
if (!opts.player1 || !opts.player2 || !opts.map) {
res.writeHead(400, { 'content-type': "application/json" })
return res.end(
JSON.stringify({
error:
'Did not pass all parameters',
})
);
}
const p1URL = new URL(encodeURI(opts.player1))
const p2URL = new URL(encodeURI(opts.player2))
const p1Opts = Object.fromEntries(
Array.from(p1URL.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as GenerateBattlerOptions
const p2Opts = Object.fromEntries(
Array.from(p2URL.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as GenerateBattlerOptions
const p1 = await generateBattler(p1Opts);
const p2 = await generateBattler({ ...p2Opts, direction: "left" })
// Image dimensions
const canvas = createCanvas(1920, 1080);
const context = canvas.getContext("2d");
const Background = await loadImage(
`./assets/locations/${opts.map}.png`,
);
context.drawImage(Background, 0, 0, canvas.width, canvas.height);
context.drawImage(p1, 140, 313, p1.width / 2, p1.height / 2);
context.drawImage(p2, (canvas.width / 2) + 177, 313, p2.width / 2, p2.height / 2);
res.setHeader('content-type', 'image/png');
return res.end(canvas.toBuffer("image/png"), 'binary')
}
if (
req.method == "GET" &&
url.pathname == "/map.png"
) {
const opts = Object.fromEntries(
Array.from(url.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as { player: string, map: string };
if (!opts.player || !opts.map) {
res.writeHead(400, { 'content-type': "application/json" })
return res.end(
JSON.stringify({
error:
'Did not pass all parameters',
})
);
}
const p1URL = new URL(encodeURI(opts.player))
const p1Opts = Object.fromEntries(
Array.from(p1URL.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as GenerateBattlerOptions
const p1 = await generateBattler(p1Opts);
// Image dimensions
const canvas = createCanvas(1920, 1080);
const context = canvas.getContext("2d");
const Background = await loadImage(
`./assets/locations/${opts.map}.png`,
);
context.drawImage(Background, 0, 0, canvas.width, canvas.height);
context.drawImage(p1, 140, 313, p1.width / 2, p1.height / 2);
res.setHeader('content-type', 'image/png');
return res.end(canvas.toBuffer("image/png"), 'binary')
}
if (
req.method == "GET" &&
url.pathname == "/pvp.png"
) {
const opts = Object.fromEntries(
Array.from(url.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as { player1: string, player2: string, username1: string, username2: string };
if (!opts.player1 || !opts.player2 || !opts.username1 || !opts.username2) {
res.writeHead(400, { 'content-type': "application/json" })
return res.end(
JSON.stringify({
error:
'Did not pass all parameters',
})
);
}
const p1URL = new URL(encodeURI(opts.player1))
const p2URL = new URL(encodeURI(opts.player2))
const p1Opts = Object.fromEntries(
Array.from(p1URL.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as GenerateBattlerOptions
const p2Opts = Object.fromEntries(
Array.from(p2URL.searchParams.entries())
.map(([key, value]) => [key, value.replaceAll('+', ' ')]),
) as GenerateBattlerOptions
const p1 = await generateBattler(p1Opts);
const p2 = await generateBattler({ ...p2Opts, direction: "left" })
// Image dimensions
const canvas = createCanvas(1920, 1080);
const context = canvas.getContext("2d");
const Background = await loadImage(
`./assets/battlebgs/PvP.png`,
);
context.drawImage(Background, 0, 0, canvas.width, canvas.height);
context.drawImage(p1, -140, -100, p1.width, p1.height);
context.drawImage(p2, (canvas.width / 2) - 180, -100, p2.width, p2.height);
context.textAlign = "center"
context.font = applyText(canvas, opts.username2, 675)
drawText([1450, 1000], opts.username2, opts.username2 == "homeannor" ? "#AA00FF" : "#000000", { colour: "#FFFFFF", width: 20 }, context)
context.font = applyText(canvas, opts.username1, 675)
drawText([470, 1000], opts.username1, opts.username1 == "homeannor" ? "#AA00FF" : "#000000", { colour: "#FFFFFF", width: 20 }, context)
res.setHeader('content-type', 'image/png');
return res.end(canvas.toBuffer("image/png"), 'binary')
}
res.writeHead(404)
return res.end("404 Not Found")
})
server.listen(60125, () => {
console.log(`Listening on localhost:60125`)
})