FurryPlace

This commit is contained in:
2025-10-04 01:52:54 -07:00
parent b87f2397d9
commit 342fc3955a
31 changed files with 365 additions and 92 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ PORT=3000
DATABASE_URL="mysql://root:password@localhost/FurryPlace"
# Only required for development
SHADOW_DATABASE_URL="mysql://root:password@localhost/openplace_shadow"
SHADOW_DATABASE_URL="mysql://root:password@localhost/FurryPlace_shadow"
JWT_SECRET="your-secret-key"
+1 -1
View File
@@ -26,5 +26,5 @@
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents"><!--[--><!--[--><!----><span class="hidden">Version: 1759353996237</span> <!--[!--><!----><div class="flex h-full flex-col items-center justify-center gap-6"><a href="/"><div class="flex items-center gap-1.5 "><img class="pixelated size-20" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAABJQTFRFAQEBAAAAHGHnRcxVStlbMXLnk8SHtQAAAAF0Uk5TAEDm2GYAAABMSURBVHjadc9JCgAhDERRa7r/lZs0ikawdv+tkvEYALS07U2QawmOTo1oQBKr8/cUMLY7JLEPYLW0oISSNLtgiojRBfv0AuB67vH3B+FjAY/0rrGiAAAAAElFTkSuQmCC" alt="Wplace logo"/> <!--[--><span class="text-base-content font-pixel text-5xl">openplace</span><!--]--></div><!----></a> <p class="max-w-3xl text-center font-medium sm:text-xl">Not found</p> <a class="btn btn-primary btn-lg" href="/">Go to map</a></div><!----><!--]--><!----> <section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false" class="svelte-tppj9g"><!--[!--><!--]--></section><!----><!----><!--]--> <!--[!--><!--]--><!--]-->
<div style="display: contents"><!--[--><!--[--><!----><span class="hidden">Version: 1759353996237</span> <!--[!--><!----><div class="flex h-full flex-col items-center justify-center gap-6"><a href="/"><div class="flex items-center gap-1.5 "><img class="pixelated size-20" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAABJQTFRFAQEBAAAAHGHnRcxVStlbMXLnk8SHtQAAAAF0Uk5TAEDm2GYAAABMSURBVHjadc9JCgAhDERRa7r/lZs0ikawdv+tkvEYALS07U2QawmOTo1oQBKr8/cUMLY7JLEPYLW0oISSNLtgiojRBfv0AuB67vH3B+FjAY/0rrGiAAAAAElFTkSuQmCC" alt="Wplace logo"/> <!--[--><span class="text-base-content font-pixel text-5xl">FurryPlace</span><!--]--></div><!----></a> <p class="max-w-3xl text-center font-medium sm:text-xl">Not found</p> <a class="btn btn-primary btn-lg" href="/">Go to map</a></div><!----><!--]--><!----> <section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false" class="svelte-tppj9g"><!--[!--><!--]--></section><!----><!----><!--]--> <!--[!--><!--]--><!--]-->
</html>
@@ -48,7 +48,7 @@ try {
} catch {}
const B =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAABJQTFRFAQEBAAAAHGHnRcxVStlbMXLnk8SHtQAAAAF0Uk5TAEDm2GYAAABMSURBVHjadc9JCgAhDERRa7r/lZs0ikawdv+tkvEYALS07U2QawmOTo1oQBKr8/cUMLY7JLEPYLW0oISSNLtgiojRBfv0AuB67vH3B+FjAY/0rrGiAAAAAElFTkSuQmCC";
var L = c("<span>openplace</span>"),
var L = c("<span>FurryPlace</span>"),
R = c('<div><img alt="Wplace logo"/> <!></div>');
function z(e, a) {
m(a, !0);
@@ -262,7 +262,7 @@ function Oa(u, v) {
}
var P = fa();
Ce((r) => {
Oe.title = "openplace - Admin - Mods - Leaderboard";
Oe.title = "FurryPlace - Admin - Mods - Leaderboard";
});
var F = t(P),
V = t(F),
@@ -266,7 +266,7 @@ function Or(v, u) {
}
var F = xr();
Ce((a) => {
Oe.title = "openplace - Admin - Reports - Leaderboard";
Oe.title = "FurryPlace - Admin - Reports - Leaderboard";
});
var P = t(F),
V = t(P),
@@ -565,7 +565,7 @@ function Oi(u, o) {
}
var Kt = bi();
js((n) => {
Ss.title = "openplace - Admin - Users";
Ss.title = "FurryPlace - Admin - Users";
});
var Qt = a(Kt),
Wt = a(Qt),
@@ -146,7 +146,7 @@ function aa(a, e) {
var I = Me();
fe((r) => {
var d = Ve();
ue(4), w((L) => (ce.title = `openplace - ${L ?? ""}`), [() => ke()]), l(r, d);
ue(4), w((L) => (ce.title = `FurryPlace - ${L ?? ""}`), [() => ke()]), l(r, d);
});
var W = s(I);
{
@@ -400,7 +400,7 @@ function Vr(p, c) {
Z = B(void 0);
var va = Ur();
vs((n) => {
ns.title = "openplace - Moderation";
ns.title = "FurryPlace - Moderation";
});
var Ie = K(va),
ze = t(Ie),
@@ -68,7 +68,7 @@ function M(e, t) {
y(t, !1), E();
var n = j();
$((p) => {
u((f) => (T.title = `openplace - ${f ?? ""}`), [() => b()]);
u((f) => (T.title = `FurryPlace - ${f ?? ""}`), [() => b()]);
});
var s = a(n),
_ = a(s);
@@ -98,7 +98,7 @@ function ge(e, t) {
});
var l = ae();
O((r) => {
w((s) => (N.title = `openplace - ${s ?? ""}`), [() => T()]);
w((s) => (N.title = `FurryPlace - ${s ?? ""}`), [() => T()]);
});
var c = a(l),
q = a(c);
@@ -1086,7 +1086,7 @@ var r =
function g(s) {
var e = r();
d((b) => {
c.title = "openplace - Privacy Policy";
c.title = "FurryPlace - Privacy Policy";
});
var l = t(e),
n = t(l);
@@ -55,7 +55,7 @@ var h =
function w(e) {
var a = h();
u((f) => {
n.title = "openplace - Refund Policy";
n.title = "FurryPlace - Refund Policy";
});
var i = s(a),
r = s(i);
@@ -76,7 +76,7 @@ function re(e, d) {
}
var n = H();
U((r) => {
S.title = "openplace - Admin";
S.title = "FurryPlace - Admin";
});
var l = t(n),
c = t(l),
@@ -50,7 +50,7 @@ var u =
function y(o) {
var e = u();
c((p) => {
t.title = "openplace - Política de Reembolso";
t.title = "FurryPlace - Política de Reembolso";
});
var a = s(e),
i = s(a);
@@ -472,7 +472,7 @@ Calibri;color:#595959;mso-themecolor:text1;mso-themetint:166;" class="svelte-11v
function u(t) {
var e = p();
v((b) => {
r.title = "openplace - Terms of Service";
r.title = "FurryPlace - Terms of Service";
});
var s = l(e),
o = l(s);
@@ -80,7 +80,7 @@ function X(e, d) {
}
var n = B();
j((t) => {
D.title = "openplace - Admin - Mods";
D.title = "FurryPlace - Admin - Mods";
});
var l = o(n),
m = v(o(l), 2),
@@ -417,9 +417,9 @@ const Xx = Q1,
Uw = () => "Importante",
$w = (m = {}, a = {}) => ((a.locale ?? Ne()) === "en" ? Zw() : Uw()),
Gw = () =>
"🚫 No inappropriate content (+18, hate speech, inappropriate links, highly suggestive material, ...)",
" NSFW content is allowed to a reasonable extent(No Cub, Loli, Guro, Bathroom fetishes, ...)",
Hw = () =>
"🚫 Conteúdo inapropriado não permitido (+18, discurso de ódio, links inapropriados, conteúdo altamente sugestivo, ...)",
" Conteúdo NSFW é permitido até certo ponto razoável (Sem Cub, Loli, Guro, fetiches de banheiro, ...)",
Ww = (m = {}, a = {}) => ((a.locale ?? Ne()) === "en" ? Gw() : Hw()),
Xw = () =>
"😈 Do not paint over other artworks using random colors or patterns just to mess things up",
@@ -70094,7 +70094,7 @@ function R9(m, a) {
return Math.round(m * p) / p;
}
var B9 = Te(
'<meta property="og:title" content="openplace - A massive real-time pixel art canvas on the world map!"/> <meta name="twitter:title" content="openplace - A massive real-time pixel art canvas on the world map!"/> <meta name="robots" content="index, follow, max-image-preview:large"/> <meta name="color-scheme" content="light only"/>',
'<meta property="og:title" content="FurryPlace - A massive real-time pixel art canvas on the world map!"/> <meta name="twitter:title" content="FurryPlace - A massive real-time pixel art canvas on the world map!"/> <meta name="robots" content="index, follow, max-image-preview:large"/> <meta name="color-scheme" content="light only"/>',
1
),
F9 = (m, a) => {
@@ -70700,7 +70700,7 @@ function uF(m, a) {
var qr = wB();
nx((bt) => {
var Xt = B9();
(rx.title = "openplace - Paint the world"), yn(6), $(bt, Xt);
(rx.title = "FurryPlace - Paint the world"), yn(6), $(bt, Xt);
});
var ue = Ct(qr);
{
@@ -66,7 +66,7 @@ function M(e, o) {
y();
var t = E();
g((n) => {
m.title = "openplace - Admin Dashboard";
m.title = "FurryPlace - Admin Dashboard";
});
var a = u(s(t), 2),
r = s(a, !0);
@@ -484,7 +484,7 @@ function Ro(d, r) {
}
var Se = no();
tr((n) => {
Za.title = "openplace - Admin - Alliances";
Za.title = "FurryPlace - Admin - Alliances";
});
var De = a(Se),
Re = a(De),
@@ -170,7 +170,7 @@ function Et(f, p) {
}
var P = vt();
Ge((a) => {
Me.title = "openplace - Admin Dashboard";
Me.title = "FurryPlace - Admin Dashboard";
});
var Q = t(P),
U = t(Q),
@@ -41,7 +41,7 @@ try {
} catch {}
function s(e) {
o((d) => {
n.title = "openplace - Admin - Mods Dashboard";
n.title = "FurryPlace - Admin - Mods Dashboard";
});
}
export { s as component };
+9 -9
View File
@@ -32,7 +32,7 @@
<link rel="modulepreload" href="/_app/immutable/chunks/D3yDgRbd.js">
<link rel="modulepreload" href="/_app/immutable/chunks/wZ7b5CwQ.js">
<link rel="modulepreload" href="/_app/immutable/nodes/6.WPRvZASS.js">
<link rel="modulepreload" href="/_app/immutable/chunks/Z_72d8Vp.js"><!--[--><!--]--><!--[--><!--]--><title>openplace - Admin Dashboard</title>
<link rel="modulepreload" href="/_app/immutable/chunks/Z_72d8Vp.js"><!--[--><!--]--><!--[--><!--]--><title>FurryPlace - Admin Dashboard</title>
<meta property="og:image" content="/img/og-image.png" />
<meta property="og:image:width" content="1200" />
@@ -41,24 +41,24 @@
<meta property="og:type" content="website" />
<meta
name="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
itemprop="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
property="og:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
name="twitter:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta name="twitter:image" content="/img/og-image.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="keywords" content="openplace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="openplace" />
<meta name="keywords" content="FurryPlace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="FurryPlace" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="mobile-web-app-capable" content="yes" />
<meta
@@ -70,8 +70,8 @@
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "openplace",
"url": "https://github.com/openplaceteam/openplace"
"name": "FurryPlace",
"url": "https://github.com/FurryPlaceteam/FurryPlace"
}
</script>
File diff suppressed because one or more lines are too long
+9 -9
View File
@@ -31,7 +31,7 @@
<link rel="modulepreload" href="/_app/immutable/chunks/B6ZK_HZO.js">
<link rel="modulepreload" href="/_app/immutable/chunks/Bn0Xcwmn.js">
<link rel="modulepreload" href="/_app/immutable/chunks/D3yDgRbd.js">
<link rel="modulepreload" href="/_app/immutable/chunks/BSXXHLQ0.js"><!--[--><meta property="og:title" content="Join the alliance"/> <meta name="twitter:title" content="Join the allince"/> <meta name="robots" content="noindex"/><!--]--><title>openplace - Alliance invite</title>
<link rel="modulepreload" href="/_app/immutable/chunks/BSXXHLQ0.js"><!--[--><meta property="og:title" content="Join the alliance"/> <meta name="twitter:title" content="Join the allince"/> <meta name="robots" content="noindex"/><!--]--><title>FurryPlace - Alliance invite</title>
<meta property="og:image" content="/img/og-image.png" />
<meta property="og:image:width" content="1200" />
@@ -40,24 +40,24 @@
<meta property="og:type" content="website" />
<meta
name="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
itemprop="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
property="og:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
name="twitter:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta name="twitter:image" content="/img/og-image.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="keywords" content="openplace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="openplace" />
<meta name="keywords" content="FurryPlace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="FurryPlace" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="mobile-web-app-capable" content="yes" />
<meta
@@ -69,8 +69,8 @@
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "openplace",
"url": "https://github.com/openplaceteam/openplace"
"name": "FurryPlace",
"url": "https://github.com/FurryPlaceteam/FurryPlace"
}
</script>
+9 -9
View File
@@ -39,7 +39,7 @@
<link rel="modulepreload" href="/_app/immutable/chunks/C3E1P42D.js">
<link rel="modulepreload" href="/_app/immutable/chunks/DBSOMMI_.js">
<link rel="modulepreload" href="/_app/immutable/chunks/BpoSU4rb.js">
<link rel="modulepreload" href="/_app/immutable/chunks/lE0oaQc5.js"><!--[--><!--]--><title>openplace - Moderation</title>
<link rel="modulepreload" href="/_app/immutable/chunks/lE0oaQc5.js"><!--[--><!--]--><title>FurryPlace - Moderation</title>
<meta property="og:image" content="/img/og-image.png" />
<meta property="og:image:width" content="1200" />
@@ -48,24 +48,24 @@
<meta property="og:type" content="website" />
<meta
name="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
itemprop="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
property="og:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
name="twitter:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta name="twitter:image" content="/img/og-image.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="keywords" content="openplace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="openplace" />
<meta name="keywords" content="FurryPlace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="FurryPlace" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="mobile-web-app-capable" content="yes" />
<meta
@@ -77,8 +77,8 @@
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "openplace",
"url": "https://github.com/openplaceteam/openplace"
"name": "FurryPlace",
"url": "https://github.com/FurryPlaceteam/FurryPlace"
}
</script>
+10 -10
View File
@@ -31,7 +31,7 @@
<link rel="modulepreload" href="/_app/immutable/chunks/D3yDgRbd.js">
<link rel="modulepreload" href="/_app/immutable/chunks/m3o6lEf1.js">
<link rel="modulepreload" href="/_app/immutable/chunks/DCynssDD.js">
<link rel="modulepreload" href="/_app/immutable/chunks/C3E1P42D.js"><!--[--><!--]--><title>openplace - No internet connection</title>
<link rel="modulepreload" href="/_app/immutable/chunks/C3E1P42D.js"><!--[--><!--]--><title>FurryPlace - No internet connection</title>
<meta property="og:image" content="/img/og-image.png" />
<meta property="og:image:width" content="1200" />
@@ -40,24 +40,24 @@
<meta property="og:type" content="website" />
<meta
name="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
itemprop="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
property="og:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
name="twitter:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta name="twitter:image" content="/img/og-image.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="keywords" content="openplace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="openplace" />
<meta name="keywords" content="FurryPlace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="FurryPlace" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="mobile-web-app-capable" content="yes" />
<meta
@@ -69,8 +69,8 @@
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "openplace",
"url": "https://github.com/openplaceteam/openplace"
"name": "FurryPlace",
"url": "https://github.com/FurryPlaceteam/FurryPlace"
}
</script>
@@ -90,7 +90,7 @@
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents"><!--[--><!--[--><!----><span class="hidden">Version: 1759353996237</span> <!--[!--><!----><div class="relative flex h-full flex-col items-center justify-center gap-2"><a href="/"><div class="flex items-center gap-1.5 absolute left-1/2 top-10 -translate-x-1/2"><img class="pixelated size-20" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAABJQTFRFAQEBAAAAHGHnRcxVStlbMXLnk8SHtQAAAAF0Uk5TAEDm2GYAAABMSURBVHjadc9JCgAhDERRa7r/lZs0ikawdv+tkvEYALS07U2QawmOTo1oQBKr8/cUMLY7JLEPYLW0oISSNLtgiojRBfv0AuB67vH3B+FjAY/0rrGiAAAAAElFTkSuQmCC" alt="Wplace logo"/> <!--[--><span class="text-base-content font-pixel text-5xl">openplace</span><!--]--></div><!----></a> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="text-base-content/80 w-40"><path d="M790-56 414-434q-47 11-87.5 33T254-346l-84-86q32-32 69-56t79-42l-90-90q-41 21-76.5 46.5T84-516L0-602q32-32 66.5-57.5T140-708l-84-84 56-56 736 736-58 56Zm-310-64q-42 0-71-29.5T380-220q0-42 29-71t71-29q42 0 71 29t29 71q0 41-29 70.5T480-120Zm236-238-29-29-29-29-144-144q81 8 151.5 41T790-432l-74 74Zm160-158q-77-77-178.5-120.5T480-680q-21 0-40.5 1.5T400-674L298-776q44-12 89.5-18t92.5-6q142 0 265 53t215 145l-84 86Z"></path></svg><!----> <p class="text-lg">No internet connection</p> <button class="btn btn-lg mt-4"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="size-5"><path d="M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z"></path></svg><!----> Refresh</button></div><!----><!--]--><!----> <section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false" class="svelte-tppj9g"><!--[!--><!--]--></section><!----><!----><!--]--> <!--[!--><!--]--><!--]-->
<div style="display: contents"><!--[--><!--[--><!----><span class="hidden">Version: 1759353996237</span> <!--[!--><!----><div class="relative flex h-full flex-col items-center justify-center gap-2"><a href="/"><div class="flex items-center gap-1.5 absolute left-1/2 top-10 -translate-x-1/2"><img class="pixelated size-20" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAABJQTFRFAQEBAAAAHGHnRcxVStlbMXLnk8SHtQAAAAF0Uk5TAEDm2GYAAABMSURBVHjadc9JCgAhDERRa7r/lZs0ikawdv+tkvEYALS07U2QawmOTo1oQBKr8/cUMLY7JLEPYLW0oISSNLtgiojRBfv0AuB67vH3B+FjAY/0rrGiAAAAAElFTkSuQmCC" alt="Wplace logo"/> <!--[--><span class="text-base-content font-pixel text-5xl">FurryPlace</span><!--]--></div><!----></a> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="text-base-content/80 w-40"><path d="M790-56 414-434q-47 11-87.5 33T254-346l-84-86q32-32 69-56t79-42l-90-90q-41 21-76.5 46.5T84-516L0-602q32-32 66.5-57.5T140-708l-84-84 56-56 736 736-58 56Zm-310-64q-42 0-71-29.5T380-220q0-42 29-71t71-29q42 0 71 29t29 71q0 41-29 70.5T480-120Zm236-238-29-29-29-29-144-144q81 8 151.5 41T790-432l-74 74Zm160-158q-77-77-178.5-120.5T480-680q-21 0-40.5 1.5T400-674L298-776q44-12 89.5-18t92.5-6q142 0 265 53t215 145l-84 86Z"></path></svg><!----> <p class="text-lg">No internet connection</p> <button class="btn btn-lg mt-4"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="size-5"><path d="M480-160q-134 0-227-93t-93-227q0-134 93-227t227-93q69 0 132 28.5T720-690v-110h80v280H520v-80h168q-32-56-87.5-88T480-720q-100 0-170 70t-70 170q0 100 70 170t170 70q77 0 139-44t87-116h84q-28 106-114 173t-196 67Z"></path></svg><!----> Refresh</button></div><!----><!--]--><!----> <section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false" class="svelte-tppj9g"><!--[!--><!--]--></section><!----><!----><!--]--> <!--[!--><!--]--><!--]-->
<script>
{
+10 -10
View File
@@ -30,7 +30,7 @@
<link rel="modulepreload" href="/_app/immutable/chunks/DueIxFLX.js">
<link rel="modulepreload" href="/_app/immutable/chunks/B6ZK_HZO.js">
<link rel="modulepreload" href="/_app/immutable/chunks/D3yDgRbd.js">
<link rel="modulepreload" href="/_app/immutable/chunks/BSXXHLQ0.js"><!--[--><!--]--><title>openplace - Payment succeeded</title>
<link rel="modulepreload" href="/_app/immutable/chunks/BSXXHLQ0.js"><!--[--><!--]--><title>FurryPlace - Payment succeeded</title>
<meta property="og:image" content="/img/og-image.png" />
<meta property="og:image:width" content="1200" />
@@ -39,24 +39,24 @@
<meta property="og:type" content="website" />
<meta
name="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
itemprop="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
property="og:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
name="twitter:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta name="twitter:image" content="/img/og-image.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="keywords" content="openplace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="openplace" />
<meta name="keywords" content="FurryPlace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="FurryPlace" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="mobile-web-app-capable" content="yes" />
<meta
@@ -68,8 +68,8 @@
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "openplace",
"url": "https://github.com/openplaceteam/openplace"
"name": "FurryPlace",
"url": "https://github.com/FurryPlaceteam/FurryPlace"
}
</script>
@@ -89,7 +89,7 @@
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents"><!--[--><!--[--><!----><span class="hidden">Version: 1759353996237</span> <!--[!--><!----><div class="relative flex h-full flex-col items-center justify-center px-4"><div class="absolute top-8"><div class="flex items-center gap-1.5 "><img class="pixelated size-20" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAABJQTFRFAQEBAAAAHGHnRcxVStlbMXLnk8SHtQAAAAF0Uk5TAEDm2GYAAABMSURBVHjadc9JCgAhDERRa7r/lZs0ikawdv+tkvEYALS07U2QawmOTo1oQBKr8/cUMLY7JLEPYLW0oISSNLtgiojRBfv0AuB67vH3B+FjAY/0rrGiAAAAAElFTkSuQmCC" alt="Wplace logo"/> <!--[--><span class="text-base-content font-pixel text-5xl">openplace</span><!--]--></div><!----></div> <div class="card border-base-content/10 w-full max-w-xl border shadow-sm"><div class="card-body gap-3"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="size-16 text-emerald-500"><path d="m424-296 282-282-56-56-226 226-114-114-56 56 170 170Zm56 216q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Z"></path></svg><!----> <h2 class="text-4xl font-medium sm:text-5xl">Payment succeeded!</h2> <p class="text-lg"><!--[!--><!--]--> Thank you for your support!</p> <a class="btn btn-primary btn-lg mt-2 w-max" href="/">Go to map</a></div></div></div><!----><!--]--><!----> <section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false" class="svelte-tppj9g"><!--[!--><!--]--></section><!----><!----><!--]--> <!--[!--><!--]--><!--]-->
<div style="display: contents"><!--[--><!--[--><!----><span class="hidden">Version: 1759353996237</span> <!--[!--><!----><div class="relative flex h-full flex-col items-center justify-center px-4"><div class="absolute top-8"><div class="flex items-center gap-1.5 "><img class="pixelated size-20" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAAXNSR0IArs4c6QAAABJQTFRFAQEBAAAAHGHnRcxVStlbMXLnk8SHtQAAAAF0Uk5TAEDm2GYAAABMSURBVHjadc9JCgAhDERRa7r/lZs0ikawdv+tkvEYALS07U2QawmOTo1oQBKr8/cUMLY7JLEPYLW0oISSNLtgiojRBfv0AuB67vH3B+FjAY/0rrGiAAAAAElFTkSuQmCC" alt="Wplace logo"/> <!--[--><span class="text-base-content font-pixel text-5xl">FurryPlace</span><!--]--></div><!----></div> <div class="card border-base-content/10 w-full max-w-xl border shadow-sm"><div class="card-body gap-3"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="currentColor" class="size-16 text-emerald-500"><path d="m424-296 282-282-56-56-226 226-114-114-56 56 170 170Zm56 216q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Z"></path></svg><!----> <h2 class="text-4xl font-medium sm:text-5xl">Payment succeeded!</h2> <p class="text-lg"><!--[!--><!--]--> Thank you for your support!</p> <a class="btn btn-primary btn-lg mt-2 w-max" href="/">Go to map</a></div></div></div><!----><!--]--><!----> <section aria-label="Notifications alt+T" tabindex="-1" aria-live="polite" aria-relevant="additions text" aria-atomic="false" class="svelte-tppj9g"><!--[!--><!--]--></section><!----><!----><!--]--> <!--[!--><!--]--><!--]-->
<script>
{
+8 -8
View File
@@ -46,24 +46,24 @@
<meta property="og:type" content="website" />
<meta
name="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
itemprop="description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
property="og:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta
name="twitter:description"
content="openplace is a free unofficial open source backend for wplace."
content="FurryPlace is a free unofficial open source backend for wplace."
/>
<meta name="twitter:image" content="/img/og-image.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="keywords" content="openplace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="openplace" />
<meta name="keywords" content="FurryPlace, pixel art, real-time, game, world map, art" />
<meta name="apple-mobile-web-app-title" content="FurryPlace" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="mobile-web-app-capable" content="yes" />
<meta
@@ -75,8 +75,8 @@
{
"@context": "https://schema.org",
"@type": "WebApplication",
"name": "openplace",
"url": "https://github.com/openplaceteam/openplace"
"name": "FurryPlace",
"url": "https://github.com/FurryPlaceteam/FurryPlace"
}
</script>
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "openplace",
"short_name": "openplace",
"description": "openplace is a free unofficial open source backend for wplace.",
"name": "FurryPlace",
"short_name": "FurryPlace",
"description": "FurryPlace is a free unofficial open source backend for wplace.",
"start_url": "/",
"theme_color": "#f8f4f0",
"background_color": "#ffffff",
+12
View File
@@ -191,3 +191,15 @@ model City {
updatedAt DateTime @updatedAt @default(now())
regions Region[]
}
model Rule {
id Int @id @default(autoincrement())
text String @db.Text
locale String @default("en")
order Int
enabled Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([locale, enabled, order])
}
+261
View File
@@ -0,0 +1,261 @@
import type { App, Response, NextFunction } from '@tinyhttp/app';
import { prisma } from '../config/database.js';
import { authMiddleware } from '../middleware/auth.js';
import { AuthenticatedRequest, UserRole } from '../types/index.js';
const adminMiddleware = async (req: AuthenticatedRequest, res: Response, next?: NextFunction) => {
try {
const user = await prisma.user.findUnique({
where: { id: req.user!.id }
});
if (!user || user.role !== UserRole.Admin) {
return res.status(403).json({ error: 'Forbidden', status: 403 });
}
return next?.();
} catch (error) {
console.error('Error fetching user:', error);
return res.status(500).json({ error: 'Internal Server Error', status: 500 });
}
};
export function setupRulesRoutes(app: App) {
// Public endpoint - Get rules for display
app.get('/api/rules', async (req, res) => {
try {
const locale = (req.query['locale'] as string) || 'en';
const rules = await prisma.rule.findMany({
where: {
locale: locale,
enabled: true,
},
orderBy: {
order: 'asc',
},
select: {
id: true,
text: true,
order: true,
},
});
return res.json({ rules });
} catch (error) {
console.error('Error fetching rules:', error);
return res.status(500).json({ error: 'Failed to fetch rules', status: 500 });
}
});
// Admin endpoint - Get all rules for editing
app.get(
'/api/admin/rules',
authMiddleware,
adminMiddleware,
async (_req, res) => {
try {
const rules = await prisma.rule.findMany({
orderBy: [{ locale: 'asc' }, { order: 'asc' }],
});
return res.json({ rules });
} catch (error) {
console.error('Error fetching rules:', error);
return res.status(500).json({ error: 'Failed to fetch rules', status: 500 });
}
}
);
// Admin endpoint - Create or update a rule
app.post(
'/api/admin/rules',
authMiddleware,
adminMiddleware,
async (req: AuthenticatedRequest, res) => {
try {
const { id, text, locale = 'en', order, enabled = true } = req.body;
if (!text || order === undefined) {
return res.status(400).json({ error: 'Text and order are required', status: 400 });
}
let rule;
if (id) {
// Update existing rule
rule = await prisma.rule.update({
where: { id },
data: {
text,
locale,
order,
enabled,
},
});
} else {
// Create new rule
rule = await prisma.rule.create({
data: {
text,
locale,
order,
enabled,
},
});
}
return res.json({ rule });
} catch (error) {
console.error('Error saving rule:', error);
return res.status(500).json({ error: 'Failed to save rule', status: 500 });
}
}
);
// Admin endpoint - Delete a rule
app.delete(
'/api/admin/rules/:id',
authMiddleware,
adminMiddleware,
async (req, res) => {
try {
const id = parseInt(req.params['id'] || '');
if (isNaN(id)) {
return res.status(400).json({ error: 'Invalid rule ID', status: 400 });
}
await prisma.rule.delete({
where: { id },
});
return res.json({ success: true });
} catch (error) {
console.error('Error deleting rule:', error);
return res.status(500).json({ error: 'Failed to delete rule', status: 500 });
}
}
);
// Admin endpoint - Initialize default rules
app.post(
'/api/admin/rules/initialize',
authMiddleware,
adminMiddleware,
async (_req, res) => {
try {
const defaultRules = [
// English rules
{
text: '📜 All users are responsible for the content they post. The platform reserves the right of final interpretation.',
locale: 'en',
order: 0,
enabled: true,
},
{
text: '🛑 Any violation may result in immediate removal of content and permanent ban of the account',
locale: 'en',
order: 1,
enabled: true,
},
{
text: '😈 Do not paint over other artworks using random colors or patterns just to mess things up',
locale: 'en',
order: 2,
enabled: true,
},
{
text: "🙅 Disclosing other's personal information is not allowed",
locale: 'en',
order: 3,
enabled: true,
},
{
text: '✅ NSFW content is allowed to a reasonable extent(No Cub, Loli, Guro, Bathroom fetishes, ...)',
locale: 'en',
order: 4,
enabled: true,
},
{
text: '🧑‍🤝‍🧑 Do not paint with more than one account',
locale: 'en',
order: 5,
enabled: true,
},
{
text: '✅ Painting over other artworks to complement them or create a new drawing is allowed',
locale: 'en',
order: 6,
enabled: true,
},
{
text: '✅ Griefing political party flags or portraits of politicians is allowed',
locale: 'en',
order: 7,
enabled: true,
},
// Portuguese rules
{
text: '📜 Todos os utilizadores são responsáveis pelo conteúdo que publicam. A plataforma reserva-se o direito de interpretação final.',
locale: 'pt',
order: 0,
enabled: true,
},
{
text: '🛑 Qualquer violação pode resultar na remoção imediata do conteúdo e banimento permanente da conta',
locale: 'pt',
order: 1,
enabled: true,
},
{
text: '😈 Não desenhe sobre outras obras usando cores ou padrões aleatórios apenas para estragar as coisas',
locale: 'pt',
order: 2,
enabled: true,
},
{
text: '🙅 A divulgação de informações pessoais de terceiros não é permitida',
locale: 'pt',
order: 3,
enabled: true,
},
{
text: '✅ Conteúdo NSFW é permitido até certo ponto razoável (Sem Cub, Loli, Guro, fetiches de banheiro, ...)',
locale: 'pt',
order: 4,
enabled: true,
},
{
text: '🧑‍🤝‍🧑 Não desenhe com mais de uma conta',
locale: 'pt',
order: 5,
enabled: true,
},
{
text: '✅ Desenhar sobre outras artes para complementar ou criar novas artes é permitido',
locale: 'pt',
order: 6,
enabled: true,
},
{
text: '✅ Desenhar sobre bandeiras de partidos e retratos de políticos é permitido',
locale: 'pt',
order: 7,
enabled: true,
},
];
const results = await Promise.all(
defaultRules.map((rule) =>
prisma.rule.create({
data: rule,
})
)
);
return res.json({ initialized: results.length, rules: results });
} catch (error) {
console.error('Error initializing rules:', error);
return res.status(500).json({ error: 'Failed to initialize rules', status: 500 });
}
}
);
}