mirror of
https://github.com/Drop-OSS/drop.git
synced 2025-11-13 16:22:39 +10:00
feat: add cloud save backend
This commit is contained in:
@ -21,14 +21,14 @@ export default defineClientEventHandler(async (h3, { clientId }) => {
|
||||
statusMessage: "configuration must be an object",
|
||||
});
|
||||
|
||||
if (!(rawCapability in validCapabilities))
|
||||
const capability = rawCapability as InternalClientCapability;
|
||||
|
||||
if (!validCapabilities.includes(capability))
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "Invalid capability.",
|
||||
});
|
||||
|
||||
const capability = rawCapability as InternalClientCapability;
|
||||
|
||||
const isValid = await capabilityManager.validateCapabilityConfiguration(
|
||||
capability,
|
||||
configuration
|
||||
|
||||
@ -0,0 +1,53 @@
|
||||
import { ClientCapabilities } from "@prisma/client";
|
||||
import { defineClientEventHandler } from "~/server/internal/clients/event-handler";
|
||||
import prisma from "~/server/internal/db/database";
|
||||
|
||||
export default defineClientEventHandler(
|
||||
async (h3, { fetchClient, fetchUser }) => {
|
||||
const client = await fetchClient();
|
||||
if (!client.capabilities.includes(ClientCapabilities.CloudSaves))
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: "Capability not allowed.",
|
||||
});
|
||||
const user = await fetchUser();
|
||||
const gameId = getRouterParam(h3, "gameid");
|
||||
if (!gameId)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "No gameID in route params",
|
||||
});
|
||||
|
||||
const slotIndexString = getRouterParam(h3, "slotindex");
|
||||
if (!slotIndexString)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "No slotIndex in route params",
|
||||
});
|
||||
const slotIndex = parseInt(slotIndexString);
|
||||
if (Number.isNaN(slotIndex))
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "Invalid slotIndex",
|
||||
});
|
||||
|
||||
const game = await prisma.game.findUnique({
|
||||
where: { id: gameId },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!game)
|
||||
throw createError({ statusCode: 400, statusMessage: "Invalid game ID" });
|
||||
|
||||
const save = await prisma.saveSlot.delete({
|
||||
where: {
|
||||
id: {
|
||||
userId: user.id,
|
||||
gameId: gameId,
|
||||
index: slotIndex,
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!save)
|
||||
throw createError({ statusCode: 404, statusMessage: "Save not found" });
|
||||
}
|
||||
);
|
||||
55
server/api/v1/client/saves/[gameid]/[slotindex]/index.get.ts
Normal file
55
server/api/v1/client/saves/[gameid]/[slotindex]/index.get.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { ClientCapabilities } from "@prisma/client";
|
||||
import { defineClientEventHandler } from "~/server/internal/clients/event-handler";
|
||||
import prisma from "~/server/internal/db/database";
|
||||
|
||||
export default defineClientEventHandler(
|
||||
async (h3, { fetchClient, fetchUser }) => {
|
||||
const client = await fetchClient();
|
||||
if (!client.capabilities.includes(ClientCapabilities.CloudSaves))
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: "Capability not allowed.",
|
||||
});
|
||||
const user = await fetchUser();
|
||||
const gameId = getRouterParam(h3, "gameid");
|
||||
if (!gameId)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "No gameID in route params",
|
||||
});
|
||||
|
||||
const slotIndexString = getRouterParam(h3, "slotindex");
|
||||
if (!slotIndexString)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "No slotIndex in route params",
|
||||
});
|
||||
const slotIndex = parseInt(slotIndexString);
|
||||
if (Number.isNaN(slotIndex))
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "Invalid slotIndex",
|
||||
});
|
||||
|
||||
const game = await prisma.game.findUnique({
|
||||
where: { id: gameId },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!game)
|
||||
throw createError({ statusCode: 400, statusMessage: "Invalid game ID" });
|
||||
|
||||
const save = await prisma.saveSlot.findUnique({
|
||||
where: {
|
||||
id: {
|
||||
userId: user.id,
|
||||
gameId: gameId,
|
||||
index: slotIndex,
|
||||
},
|
||||
},
|
||||
});
|
||||
if (!save)
|
||||
throw createError({ statusCode: 404, statusMessage: "Save not found" });
|
||||
|
||||
return save;
|
||||
}
|
||||
);
|
||||
46
server/api/v1/client/saves/[gameid]/[slotindex]/push.post.ts
Normal file
46
server/api/v1/client/saves/[gameid]/[slotindex]/push.post.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { ClientCapabilities } from "@prisma/client";
|
||||
import { defineClientEventHandler } from "~/server/internal/clients/event-handler";
|
||||
import prisma from "~/server/internal/db/database";
|
||||
import saveManager from "~/server/internal/saves";
|
||||
|
||||
export default defineClientEventHandler(
|
||||
async (h3, { fetchClient, fetchUser }) => {
|
||||
const client = await fetchClient();
|
||||
if (!client.capabilities.includes(ClientCapabilities.CloudSaves))
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: "Capability not allowed.",
|
||||
});
|
||||
const user = await fetchUser();
|
||||
const gameId = getRouterParam(h3, "gameid");
|
||||
if (!gameId)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "No gameID in route params",
|
||||
});
|
||||
|
||||
const slotIndexString = getRouterParam(h3, "slotindex");
|
||||
if (!slotIndexString)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "No slotIndex in route params",
|
||||
});
|
||||
const slotIndex = parseInt(slotIndexString);
|
||||
if (Number.isNaN(slotIndex))
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "Invalid slotIndex",
|
||||
});
|
||||
|
||||
const game = await prisma.game.findUnique({
|
||||
where: { id: gameId },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!game)
|
||||
throw createError({ statusCode: 400, statusMessage: "Invalid game ID" });
|
||||
|
||||
await saveManager.pushSave(gameId, user.id, slotIndex, h3.node.req);
|
||||
|
||||
return;
|
||||
}
|
||||
);
|
||||
37
server/api/v1/client/saves/[gameid]/index.get.ts
Normal file
37
server/api/v1/client/saves/[gameid]/index.get.ts
Normal file
@ -0,0 +1,37 @@
|
||||
import { ClientCapabilities } from "@prisma/client";
|
||||
import { defineClientEventHandler } from "~/server/internal/clients/event-handler";
|
||||
import prisma from "~/server/internal/db/database";
|
||||
|
||||
export default defineClientEventHandler(
|
||||
async (h3, { fetchClient, fetchUser }) => {
|
||||
const client = await fetchClient();
|
||||
if (!client.capabilities.includes(ClientCapabilities.CloudSaves))
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: "Capability not allowed.",
|
||||
});
|
||||
const user = await fetchUser();
|
||||
const gameId = getRouterParam(h3, "gameid");
|
||||
if (!gameId)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "No gameID in route params",
|
||||
});
|
||||
|
||||
const game = await prisma.game.findUnique({
|
||||
where: { id: gameId },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!game)
|
||||
throw createError({ statusCode: 400, statusMessage: "Invalid game ID" });
|
||||
|
||||
const saves = await prisma.saveSlot.findMany({
|
||||
where: {
|
||||
userId: user.id,
|
||||
gameId: gameId,
|
||||
},
|
||||
});
|
||||
|
||||
return saves;
|
||||
}
|
||||
);
|
||||
62
server/api/v1/client/saves/[gameid]/index.post.ts
Normal file
62
server/api/v1/client/saves/[gameid]/index.post.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { ClientCapabilities } from "@prisma/client";
|
||||
import { defineClientEventHandler } from "~/server/internal/clients/event-handler";
|
||||
import { applicationSettings } from "~/server/internal/config/application-configuration";
|
||||
import prisma from "~/server/internal/db/database";
|
||||
|
||||
export default defineClientEventHandler(
|
||||
async (h3, { fetchClient, fetchUser }) => {
|
||||
const client = await fetchClient();
|
||||
if (!client.capabilities.includes(ClientCapabilities.CloudSaves))
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: "Capability not allowed.",
|
||||
});
|
||||
const user = await fetchUser();
|
||||
const gameId = getRouterParam(h3, "gameid");
|
||||
if (!gameId)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "No gameID in route params",
|
||||
});
|
||||
|
||||
const game = await prisma.game.findUnique({
|
||||
where: { id: gameId },
|
||||
select: { id: true },
|
||||
});
|
||||
if (!game)
|
||||
throw createError({ statusCode: 400, statusMessage: "Invalid game ID" });
|
||||
|
||||
const saves = await prisma.saveSlot.findMany({
|
||||
where: {
|
||||
userId: user.id,
|
||||
gameId: gameId,
|
||||
},
|
||||
orderBy: {
|
||||
index: "asc",
|
||||
},
|
||||
});
|
||||
|
||||
const limit = await applicationSettings.get("saveSlotCountLimit");
|
||||
if (saves.length + 1 > limit)
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: "Out of save slots",
|
||||
});
|
||||
|
||||
let firstIndex = 0;
|
||||
for (const save of saves) {
|
||||
if (firstIndex == save.index) firstIndex++;
|
||||
}
|
||||
|
||||
const newSlot = await prisma.saveSlot.create({
|
||||
data: {
|
||||
userId: user.id,
|
||||
gameId: gameId,
|
||||
index: firstIndex,
|
||||
lastUsedClientId: client.id,
|
||||
},
|
||||
});
|
||||
|
||||
return newSlot;
|
||||
}
|
||||
);
|
||||
23
server/api/v1/client/saves/index.get.ts
Normal file
23
server/api/v1/client/saves/index.get.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { ClientCapabilities } from "@prisma/client";
|
||||
import { defineClientEventHandler } from "~/server/internal/clients/event-handler";
|
||||
import prisma from "~/server/internal/db/database";
|
||||
|
||||
export default defineClientEventHandler(
|
||||
async (h3, { fetchClient, fetchUser }) => {
|
||||
const client = await fetchClient();
|
||||
if (!client.capabilities.includes(ClientCapabilities.CloudSaves))
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: "Capability not allowed.",
|
||||
});
|
||||
const user = await fetchUser();
|
||||
|
||||
const saves = await prisma.saveSlot.findMany({
|
||||
where: {
|
||||
userId: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
return saves;
|
||||
}
|
||||
);
|
||||
20
server/api/v1/client/saves/settings.get.ts
Normal file
20
server/api/v1/client/saves/settings.get.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { ClientCapabilities } from "@prisma/client";
|
||||
import { defineClientEventHandler } from "~/server/internal/clients/event-handler";
|
||||
import { applicationSettings } from "~/server/internal/config/application-configuration";
|
||||
import prisma from "~/server/internal/db/database";
|
||||
|
||||
export default defineClientEventHandler(
|
||||
async (h3, { fetchClient, fetchUser }) => {
|
||||
const client = await fetchClient();
|
||||
if (!client.capabilities.includes(ClientCapabilities.CloudSaves))
|
||||
throw createError({
|
||||
statusCode: 403,
|
||||
statusMessage: "Capability not allowed.",
|
||||
});
|
||||
|
||||
const slotLimit = await applicationSettings.get("saveSlotCountLimit");
|
||||
const sizeLimit = await applicationSettings.get("saveSlotSizeLimit");
|
||||
const history = await applicationSettings.get("saveSlotHistoryLimit");
|
||||
return { slotLimit, sizeLimit, history };
|
||||
}
|
||||
);
|
||||
Reference in New Issue
Block a user