diff --git a/fix-imager.ts b/fix-imager.ts
new file mode 100644
index 00000000..6dc10b7e
--- /dev/null
+++ b/fix-imager.ts
@@ -0,0 +1,27 @@
+import { eq } from "drizzle-orm";
+import { WebsiteSetting } from "@/db/schema";
+import { db } from "./src/lib/db";
+
+async function main() {
+ const result = await db
+ .select()
+ .from(WebsiteSetting)
+ .where(eq(WebsiteSetting.key, "habbo_imaging_url"));
+ console.log("Current:", result);
+
+ if (result[0]?.value !== "/imaging") {
+ await db
+ .update(WebsiteSetting)
+ .set({ value: "/imaging" })
+ .where(eq(WebsiteSetting.key, "habbo_imaging_url"));
+ console.log("Updated to /imaging");
+ } else {
+ console.log("Already correct");
+ }
+ process.exit(0);
+}
+
+main().catch((e) => {
+ console.error(e);
+ process.exit(1);
+});
diff --git a/src/app/(site)/friends/page.tsx b/src/app/(site)/friends/page.tsx
index f95c68c3..2c6c5293 100644
--- a/src/app/(site)/friends/page.tsx
+++ b/src/app/(site)/friends/page.tsx
@@ -8,7 +8,6 @@ import { ContentCard, EmptyState, OnlineBadge } from "@/components/public/ui";
import { auth } from "@/lib/auth";
import { db, MessengerFriendships, User } from "@/lib/db";
import { avatarImageUrl } from "@/lib/format";
-import { siteSettings } from "@/lib/services/site-settings";
export const metadata = { title: "Friends" };
@@ -66,26 +65,20 @@ export default async function FriendsPage({
),
);
- const [friends, imagerBase] = await Promise.all([
- friendIds.length
- ? db
- .select({
- id: User.id,
- username: User.username,
- look: User.look,
- motto: User.motto,
- online: User.online,
- })
- .from(User)
- .where(inArray(User.id, friendIds))
- .orderBy(asc(User.username))
- .catch(() => [])
- : Promise.resolve([]),
- siteSettings.get(
- "habbo_imaging_url",
- "https://www.habbo.com/habbo-imaging/avatarimage",
- ),
- ]);
+ const friends = friendIds.length
+ ? await db
+ .select({
+ id: User.id,
+ username: User.username,
+ look: User.look,
+ motto: User.motto,
+ online: User.online,
+ })
+ .from(User)
+ .where(inArray(User.id, friendIds))
+ .orderBy(asc(User.username))
+ .catch(() => [])
+ : [];
const errorMessage =
error === "not_found"
@@ -125,7 +118,7 @@ export default async function FriendsPage({
) : (
{friends.map((friend) => {
- const avatar = avatarImageUrl(imagerBase ?? "", friend.look, {
+ const avatar = avatarImageUrl(friend.look, {
size: "s",
headOnly: true,
});
diff --git a/src/app/(site)/guilds/[id]/page.tsx b/src/app/(site)/guilds/[id]/page.tsx
index b5c8a7d6..67fcfb8f 100644
--- a/src/app/(site)/guilds/[id]/page.tsx
+++ b/src/app/(site)/guilds/[id]/page.tsx
@@ -6,7 +6,6 @@ import { ContentCard, EmptyState, StatBlock } from "@/components/public/ui";
import { db, Guilds, GuildsMembers, User } from "@/lib/db";
import { avatarImageUrl } from "@/lib/format";
import { formatDate } from "@/lib/format-date";
-import { siteSettings } from "@/lib/services/site-settings";
type GuildView = {
id: number;
@@ -98,11 +97,6 @@ export default async function GuildPage({
users = [];
}
- const imagerBase = await siteSettings.get(
- "habbo_imaging_url",
- "https://www.habbo.com/habbo-imaging/avatarimage",
- );
-
const usersById = new Map(users.map((u) => [u.id, u]));
const sinceById = new Map(memberRows.map((m) => [m.userId, m.memberSince]));
@@ -211,7 +205,7 @@ export default async function GuildPage({
{/* eslint-disable-next-line @next/next/no-img-element */}

tab.key === active) ?? TABS[0];
- const [rows, imagerBase] = await Promise.all([
- active === "credits"
- ? loadCreditsRows()
- : active === "diamonds" || active === "duckets"
- ? // eslint-disable-next-line security/detect-object-injection -- active validated as "diamonds"|"duckets" in this branch
- loadCurrencyRows(CURRENCY_TYPE[active])
- : loadSettingsRows(
- SETTINGS_FIELD[active as keyof typeof SETTINGS_FIELD],
- ),
- siteSettings.get(
- "habbo_imaging_url",
- "https://www.habbo.com/habbo-imaging/avatarimage",
- ),
- ]);
+ const rows = await (active === "credits"
+ ? loadCreditsRows()
+ : active === "diamonds" || active === "duckets"
+ ? // eslint-disable-next-line security/detect-object-injection -- active validated as "diamonds"|"duckets" in this branch
+ loadCurrencyRows(CURRENCY_TYPE[active])
+ : loadSettingsRows(
+ SETTINGS_FIELD[active as keyof typeof SETTINGS_FIELD],
+ ));
const valueOnly =
active === "achievement" ||
@@ -213,7 +206,7 @@ export default async function LeaderboardPage({
{rows.map((row, i) => {
- const avatar = avatarImageUrl(imagerBase ?? "", row.look, {
+ const avatar = avatarImageUrl(row.look, {
size: "s",
headOnly: true,
});
diff --git a/src/app/(site)/login/page.tsx b/src/app/(site)/login/page.tsx
index 6693af03..ef15e431 100644
--- a/src/app/(site)/login/page.tsx
+++ b/src/app/(site)/login/page.tsx
@@ -18,17 +18,11 @@ import { siteSettings } from "@/lib/services/site-settings";
export default async function LoginPage() {
const t = await getTranslations("pages.login");
const th = await getTranslations("header");
- const [hotelName, imagerRaw, cfg, logo] = await Promise.all([
+ const [hotelName, cfg, logo] = await Promise.all([
resolveHotelName(),
- siteSettings.get(
- "habbo_imaging_url",
- "https://www.habbo.com/habbo-imaging/avatarimage",
- ),
captchaConfig(),
- siteSettings.get("radio_social_discord", ""),
siteSettings.get("cms_logo", ""),
]);
- const imager = imagerRaw ?? "https://www.habbo.com/habbo-imaging/avatarimage";
const nonce = (await headers()).get("x-nonce") ?? undefined;
const [online, recentUsers, latestUsers] = await Promise.all([
@@ -234,7 +228,7 @@ export default async function LoginPage() {
}}
>
{requests.map((req) => {
const from = userById.get(req.userFromId);
- const avatar = avatarImageUrl(imagerBase, from?.look ?? "", {
+ const avatar = avatarImageUrl(from?.look ?? "", {
size: "s",
headOnly: true,
});
@@ -367,7 +360,7 @@ export default async function MessagesPage({
{messages.map((msg) => {
const from = userById.get(msg.userFromId);
- const avatar = avatarImageUrl(imagerBase, from?.look ?? "", {
+ const avatar = avatarImageUrl(from?.look ?? "", {
size: "s",
headOnly: true,
});
diff --git a/src/app/(site)/page.tsx b/src/app/(site)/page.tsx
index 286d9e8d..c1ce808b 100644
--- a/src/app/(site)/page.tsx
+++ b/src/app/(site)/page.tsx
@@ -22,15 +22,10 @@ import { captchaConfig } from "@/lib/services/captcha";
import { siteSettings } from "@/lib/services/site-settings";
async function getHotelData() {
- const [hotelName, imagerRaw, logo] = await Promise.all([
+ const [hotelName, logo] = await Promise.all([
resolveHotelName(),
- siteSettings.get(
- "habbo_imaging_url",
- "https://www.habbo.com/habbo-imaging/avatarimage",
- ),
siteSettings.get("cms_logo", ""),
]);
- const imager = imagerRaw ?? "https://www.habbo.com/habbo-imaging/avatarimage";
const [
online,
@@ -88,7 +83,6 @@ async function getHotelData() {
return {
hotelName,
- imager,
online,
users,
rooms,
@@ -108,7 +102,6 @@ export default async function Home() {
const th = await getTranslations("header");
const {
hotelName,
- imager,
online,
users,
rooms,
@@ -486,7 +479,7 @@ export default async function Home() {
>
@@ -63,7 +56,7 @@ export default async function RadioLeaderboardPage() {
{rows.map((row, i) => {
- const avatar = avatarImageUrl(imagerBase ?? "", row.look, {
+ const avatar = avatarImageUrl(row.look, {
size: "s",
headOnly: true,
});
diff --git a/src/app/(site)/radio/shouts/page.tsx b/src/app/(site)/radio/shouts/page.tsx
index 5871f7ca..882a30b1 100644
--- a/src/app/(site)/radio/shouts/page.tsx
+++ b/src/app/(site)/radio/shouts/page.tsx
@@ -7,7 +7,6 @@ import { auth } from "@/lib/auth";
import { db, RadioShouts, User } from "@/lib/db";
import { avatarImageUrl } from "@/lib/format";
import { formatDate } from "@/lib/format-date";
-import { siteSettings } from "@/lib/services/site-settings";
type SearchParams = Promise<{ posted?: string; error?: string }>;
@@ -35,17 +34,13 @@ export default async function RadioShoutsPage({
const t = await getTranslations("pages.radioShouts");
const { posted, error } = await searchParams;
- const [shouts, imagerBase, session] = await Promise.all([
+ const [shouts, session] = await Promise.all([
db
.select()
.from(RadioShouts)
.orderBy(desc(RadioShouts.createdAt))
.limit(50)
.catch(() => []),
- siteSettings.get(
- "habbo_imaging_url",
- "https://www.habbo.com/habbo-imaging/avatarimage",
- ),
auth(),
]);
@@ -141,7 +136,7 @@ export default async function RadioShoutsPage({
{shouts.map((s) => {
const author = authorById.get(Number(s.userId));
const authorAvatar = author
- ? avatarImageUrl(imagerBase ?? "", author.look, {
+ ? avatarImageUrl(author.look, {
size: "s",
headOnly: true,
})
diff --git a/src/app/(site)/rankings/page.tsx b/src/app/(site)/rankings/page.tsx
index 6626822b..d1b6eccf 100644
--- a/src/app/(site)/rankings/page.tsx
+++ b/src/app/(site)/rankings/page.tsx
@@ -10,7 +10,6 @@ import {
} from "@/components/public/ui";
import { db, User } from "@/lib/db";
import { avatarImageUrl } from "@/lib/format";
-import { siteSettings } from "@/lib/services/site-settings";
export const metadata = { title: "Rankings" };
@@ -41,11 +40,6 @@ export default async function RankingsPage() {
users = [];
}
- const imagerBase = await siteSettings.get(
- "habbo_imaging_url",
- "https://www.habbo.com/habbo-imaging/avatarimage",
- );
-
return (
@@ -56,7 +50,7 @@ export default async function RankingsPage() {
) : (
{users.map((u, i) => {
- const avatar = avatarImageUrl(imagerBase ?? "", u.look, {
+ const avatar = avatarImageUrl(u.look, {
size: "m",
});
return (
diff --git a/src/app/(site)/register/page.tsx b/src/app/(site)/register/page.tsx
index 54e8dccb..5249f642 100644
--- a/src/app/(site)/register/page.tsx
+++ b/src/app/(site)/register/page.tsx
@@ -18,17 +18,11 @@ import { siteSettings } from "@/lib/services/site-settings";
export default async function RegisterPage() {
const th = await getTranslations("header");
const tpr = await getTranslations("pages.register");
- const [hotelName, imagerRaw, cfg, logo] = await Promise.all([
+ const [hotelName, cfg, logo] = await Promise.all([
resolveHotelName(),
- siteSettings.get(
- "habbo_imaging_url",
- "https://www.habbo.com/habbo-imaging/avatarimage",
- ),
captchaConfig(),
- siteSettings.get("radio_social_discord", ""),
siteSettings.get("cms_logo", ""),
]);
- const imager = imagerRaw ?? "https://www.habbo.com/habbo-imaging/avatarimage";
const nonce = (await headers()).get("x-nonce") ?? undefined;
const [online, recentUsers, latestUsers] = await Promise.all([
@@ -231,7 +225,7 @@ export default async function RegisterPage() {
}}
>
diff --git a/src/app/(site)/u/[username]/page.tsx b/src/app/(site)/u/[username]/page.tsx
index af9fd9be..7d8e7afe 100644
--- a/src/app/(site)/u/[username]/page.tsx
+++ b/src/app/(site)/u/[username]/page.tsx
@@ -26,7 +26,6 @@ import {
} from "@/lib/db";
import { avatarImageUrl } from "@/lib/format";
import { formatDate } from "@/lib/format-date";
-import { siteSettings } from "@/lib/services/site-settings";
type SearchParams = Promise<{
friend?: string;
@@ -87,7 +86,7 @@ export default async function ProfilePage({
const { username } = await params;
const { friend, guestbook: guestbookStatus, error } = await searchParams;
- const [userRows, imagerBase, session] = await Promise.all([
+ const [userRows, session] = await Promise.all([
db
.select({
id: User.id,
@@ -102,17 +101,13 @@ export default async function ProfilePage({
.from(User)
.where(eq(User.username, username))
.limit(1),
- siteSettings.get(
- "habbo_imaging_url",
- "https://www.habbo.com/habbo-imaging/avatarimage",
- ),
auth(),
]);
const user = userRows[0] ?? null;
if (!user) notFound();
- const avatar = avatarImageUrl(imagerBase ?? "", user.look, { size: "l" });
+ const avatar = avatarImageUrl(user.look, { size: "l" });
const registered = formatDate(new Date(user.accountCreated * 1000), "date");
const meId = Number(session?.user?.id);
const isLoggedIn = Number.isInteger(meId) && meId > 0;
@@ -484,7 +479,7 @@ export default async function ProfilePage({
>
{/* eslint-disable-next-line @next/next/no-img-element */}
{
const author = authorById.get(g.userId);
const authorAvatar = author
- ? avatarImageUrl(imagerBase ?? "", author.look, {
+ ? avatarImageUrl(author.look, {
size: "s",
headOnly: true,
})
diff --git a/src/app/api/imaging/avatar/route.ts b/src/app/api/imaging/avatar/route.ts
index 5838777d..7327fca4 100644
--- a/src/app/api/imaging/avatar/route.ts
+++ b/src/app/api/imaging/avatar/route.ts
@@ -1,5 +1,5 @@
import { type NextRequest, NextResponse } from "next/server";
-import { resolveUpstreamBase } from "@/lib/imager";
+import { resolveImagerBase } from "@/lib/imager";
const FIGURE_RE = /^([a-z]{2}-\d+)(\.[a-z]{2}-\d+)*$/i;
const FIGURE_MAX_LEN = 512;
@@ -66,7 +66,7 @@ export async function GET(request: NextRequest) {
const imgFormat = searchParams.get("img_format");
if (imgFormat) params.set("img_format", imgFormat);
- const upstream = resolveUpstreamBase();
+ const upstream = resolveImagerBase();
const upstreamUrl = `${upstream}?${params.toString()}`;
try {
diff --git a/src/app/imaging/route.ts b/src/app/imaging/route.ts
index 5798d44b..fa95d54f 100644
--- a/src/app/imaging/route.ts
+++ b/src/app/imaging/route.ts
@@ -1,5 +1,5 @@
import { type NextRequest, NextResponse } from "next/server";
-import { resolveUpstreamBase } from "@/lib/imager";
+import { resolveImagerBase } from "@/lib/imager";
const FIGURE_RE = /^([a-z]{2}-\d+)(\.[a-z]{2}-\d+)*$/i;
const FIGURE_MAX_LEN = 512;
@@ -66,7 +66,7 @@ export async function GET(request: NextRequest) {
const imgFormat = searchParams.get("img_format");
if (imgFormat) params.set("img_format", imgFormat);
- const upstream = resolveUpstreamBase();
+ const upstream = resolveImagerBase();
const upstreamUrl = `${upstream}?${params.toString()}`;
try {
diff --git a/src/components/top-header.tsx b/src/components/top-header.tsx
index b2451dac..569e9bd2 100644
--- a/src/components/top-header.tsx
+++ b/src/components/top-header.tsx
@@ -16,7 +16,6 @@ import {
import { avatarImageUrl } from "@/lib/format";
import { resolveHotelName } from "@/lib/hotel-name";
import { canAccess, getApiAdminContext, PERMS } from "@/lib/permissions";
-import { siteSettings } from "@/lib/services/site-settings";
function Currency({
icon,
@@ -78,12 +77,7 @@ export async function TopHeader({ session }: { session: Session | null }) {
}
} catch {}
- const imager =
- (await siteSettings.get(
- "habbo_imaging_url",
- "https://www.habbo.com/habbo-imaging/avatarimage",
- )) ?? "";
- const avatar = avatarImageUrl(imager, look, { headOnly: true, direction: 2 });
+ const avatar = avatarImageUrl(look, { headOnly: true, direction: 2 });
let showAdmin = false;
let showMod = false;
const ctx = await getApiAdminContext();
@@ -394,7 +388,7 @@ export async function TopHeader({ session }: { session: Session | null }) {
className="flex items-center gap-2 rounded-lg px-2 py-1 text-xs transition-colors hover:bg-white/10"
>