Early version of multiplayer
This commit is contained in:
4 files changed
+491
-9
No files matched your search
@@ -3,7 +3,7 @@
|
|||||||
-- https://www.phpmyadmin.net/
|
-- https://www.phpmyadmin.net/
|
||||||
--
|
--
|
||||||
-- Host: localhost
|
-- Host: localhost
|
||||||
-- Generation Time: Feb 21, 2026 at 09:07 PM
|
-- Generation Time: Mar 05, 2026 at 05:31 AM
|
||||||
-- Server version: 11.8.6-MariaDB-log
|
-- Server version: 11.8.6-MariaDB-log
|
||||||
-- PHP Version: 8.5.3
|
-- PHP Version: 8.5.3
|
||||||
|
|
||||||
@@ -70,6 +70,20 @@ CREATE TABLE `marketplaceicons` (
|
|||||||
|
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Table structure for table `multiplayer_player_joins_and_leaves`
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE `multiplayer_player_joins_and_leaves` (
|
||||||
|
`id` bigint(20) NOT NULL,
|
||||||
|
`wsId` varchar(32) NOT NULL,
|
||||||
|
`pubId` varchar(32) NOT NULL,
|
||||||
|
`type` enum('Join','Leave') NOT NULL,
|
||||||
|
`timestamp` bigint(20) NOT NULL
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=COMPRESSED;
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Table structure for table `splashtexts`
|
-- Table structure for table `splashtexts`
|
||||||
--
|
--
|
||||||
@@ -119,7 +133,7 @@ CREATE TABLE `userposts` (
|
|||||||
--
|
--
|
||||||
ALTER TABLE `chatroom_reports`
|
ALTER TABLE `chatroom_reports`
|
||||||
ADD PRIMARY KEY (`id`),
|
ADD PRIMARY KEY (`id`),
|
||||||
ADD KEY `chatId` (`chatId`);
|
ADD KEY `chatroom_reports?chatId` (`chatId`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `chats`
|
-- Indexes for table `chats`
|
||||||
@@ -133,6 +147,12 @@ ALTER TABLE `chats`
|
|||||||
ALTER TABLE `marketplaceicons`
|
ALTER TABLE `marketplaceicons`
|
||||||
ADD PRIMARY KEY (`place`);
|
ADD PRIMARY KEY (`place`);
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Indexes for table `multiplayer_player_joins_and_leaves`
|
||||||
|
--
|
||||||
|
ALTER TABLE `multiplayer_player_joins_and_leaves`
|
||||||
|
ADD PRIMARY KEY (`id`);
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Indexes for table `splashtexts`
|
-- Indexes for table `splashtexts`
|
||||||
--
|
--
|
||||||
@@ -173,6 +193,12 @@ ALTER TABLE `chats`
|
|||||||
ALTER TABLE `marketplaceicons`
|
ALTER TABLE `marketplaceicons`
|
||||||
MODIFY `place` bigint(20) NOT NULL AUTO_INCREMENT;
|
MODIFY `place` bigint(20) NOT NULL AUTO_INCREMENT;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- AUTO_INCREMENT for table `multiplayer_player_joins_and_leaves`
|
||||||
|
--
|
||||||
|
ALTER TABLE `multiplayer_player_joins_and_leaves`
|
||||||
|
MODIFY `id` bigint(20) NOT NULL AUTO_INCREMENT;
|
||||||
|
|
||||||
--
|
--
|
||||||
-- AUTO_INCREMENT for table `splashtexts`
|
-- AUTO_INCREMENT for table `splashtexts`
|
||||||
--
|
--
|
||||||
@@ -199,7 +225,7 @@ ALTER TABLE `userposts`
|
|||||||
-- Constraints for table `chatroom_reports`
|
-- Constraints for table `chatroom_reports`
|
||||||
--
|
--
|
||||||
ALTER TABLE `chatroom_reports`
|
ALTER TABLE `chatroom_reports`
|
||||||
ADD CONSTRAINT `chatId` FOREIGN KEY (`chatId`) REFERENCES `chats` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
ADD CONSTRAINT `chatroom_reports?chatId` FOREIGN KEY (`chatId`) REFERENCES `chats` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
|
||||||
COMMIT;
|
COMMIT;
|
||||||
|
|
||||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||||
|
|||||||
+356
-6
@@ -7,6 +7,7 @@ import swagger from '@elysiajs/swagger'
|
|||||||
import { berryDashChats, berryDashUserData, users } from './lib/tables'
|
import { berryDashChats, berryDashUserData, users } from './lib/tables'
|
||||||
import { and, desc, eq } from 'drizzle-orm'
|
import { and, desc, eq } from 'drizzle-orm'
|
||||||
import { checkAuthorization } from './lib/auth'
|
import { checkAuthorization } from './lib/auth'
|
||||||
|
import { randomBytes } from 'crypto'
|
||||||
|
|
||||||
import { handler as getVerifyCodeHandler } from './routes/get-verify-code'
|
import { handler as getVerifyCodeHandler } from './routes/get-verify-code'
|
||||||
|
|
||||||
@@ -52,6 +53,9 @@ import { handler as berryDashSplashTextPostHandler } from './routes/berrydash/sp
|
|||||||
|
|
||||||
import { handler as berryDashRenderIconGetHandler } from './routes/berrydash/render-icon/get'
|
import { handler as berryDashRenderIconGetHandler } from './routes/berrydash/render-icon/get'
|
||||||
|
|
||||||
|
import { handler as websiteLauncherGamesGetHandler } from './routes/website/launcher/games/get'
|
||||||
|
import { handler as websiteLauncherGameGetHandler } from './routes/website/launcher/game/get'
|
||||||
|
|
||||||
dotenv.config({ quiet: true })
|
dotenv.config({ quiet: true })
|
||||||
|
|
||||||
const intNotStr = (name: string) => {
|
const intNotStr = (name: string) => {
|
||||||
@@ -106,19 +110,315 @@ interface ClientInfoData {
|
|||||||
ClientPlatform: string
|
ClientPlatform: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface MultiplayerClient {
|
||||||
|
Id: string
|
||||||
|
Key: string
|
||||||
|
PosX: number
|
||||||
|
PosY: number
|
||||||
|
Flipped: boolean
|
||||||
|
Paused: boolean
|
||||||
|
FlaggedReason: string | null
|
||||||
|
Token: string
|
||||||
|
Username: string
|
||||||
|
UserID: number
|
||||||
|
Admin: boolean
|
||||||
|
Platform: number | null
|
||||||
|
JoinTimestamp: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MultiplayerBerry {
|
||||||
|
Id: string
|
||||||
|
Type: string
|
||||||
|
Timestamp: number
|
||||||
|
PosX: number
|
||||||
|
}
|
||||||
|
|
||||||
const clients = new Set<ElysiaWS>()
|
const clients = new Set<ElysiaWS>()
|
||||||
const clientInfo: ClientInfoData[] = []
|
let clientInfo: ClientInfoData[] = []
|
||||||
|
let multiplayerClients: MultiplayerClient[] = []
|
||||||
|
let multiplayerBerries: MultiplayerBerry[] = []
|
||||||
|
|
||||||
|
setInterval(async () => {
|
||||||
|
if (multiplayerClients.length == 0) return
|
||||||
|
let berry = ''
|
||||||
|
const spawnProbability = Math.random()
|
||||||
|
const id = randomBytes(16).toString('hex')
|
||||||
|
if (spawnProbability <= 0.575) {
|
||||||
|
berry = 'NormalBerry'
|
||||||
|
} else if (spawnProbability <= 0.75) {
|
||||||
|
berry = 'PoisonBerry'
|
||||||
|
} else if (spawnProbability <= 0.85) {
|
||||||
|
berry = 'SlowBerry'
|
||||||
|
} else if (spawnProbability <= 0.95) {
|
||||||
|
berry = 'UltraBerry'
|
||||||
|
} else {
|
||||||
|
berry = 'RandomBerry'
|
||||||
|
}
|
||||||
|
const time = Date.now()
|
||||||
|
const posX = Math.random()
|
||||||
|
const data: MultiplayerBerry = {
|
||||||
|
Id: id,
|
||||||
|
Type: berry,
|
||||||
|
Timestamp: time,
|
||||||
|
PosX: posX
|
||||||
|
}
|
||||||
|
multiplayerBerries.push(data)
|
||||||
|
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_berry_spawn',
|
||||||
|
id,
|
||||||
|
berryType: berry,
|
||||||
|
posX,
|
||||||
|
timestamp: time
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
app.ws('/ws', {
|
app.ws('/ws', {
|
||||||
maxPayloadLength: 10 * 1024 * 1024,
|
maxPayloadLength: 10 * 1024 * 1024,
|
||||||
open (ws) {
|
open (ws) {
|
||||||
clients.add(ws)
|
clients.add(ws)
|
||||||
console.log(ws.id, 'connected')
|
// console.log(ws.id, 'connected')
|
||||||
},
|
},
|
||||||
async message (ws, message: any) {
|
async message (ws, message: any) {
|
||||||
// console.log('received:', message, 'from', ws.id)
|
console.log('received:', message, 'from', ws.id)
|
||||||
|
if (message == 'ping') ws.send('ping')
|
||||||
if (message.type) {
|
if (message.type) {
|
||||||
if (message.type == 'connected_with_current_scene') {
|
if (
|
||||||
|
message.type == 'multiplayer_player_move' &&
|
||||||
|
message.x !== undefined &&
|
||||||
|
message.y !== undefined &&
|
||||||
|
message.f !== undefined
|
||||||
|
) {
|
||||||
|
const multiplayerInfo = multiplayerClients.find(
|
||||||
|
client => client.Id == ws.id
|
||||||
|
)
|
||||||
|
if (!multiplayerInfo) return
|
||||||
|
multiplayerInfo.PosX = Number(message.x)
|
||||||
|
multiplayerInfo.PosY = Number(message.y)
|
||||||
|
multiplayerInfo.Flipped = Boolean(message.f)
|
||||||
|
const index = multiplayerClients.findIndex(client => client.Id == ws.id)
|
||||||
|
if (index === -1) return
|
||||||
|
multiplayerClients[index] = multiplayerInfo
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
if (ws.id == multiplayerClientInfo.Id) continue
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_player_move',
|
||||||
|
id: multiplayerInfo.UserID,
|
||||||
|
x: Number(message.x),
|
||||||
|
y: Number(message.y),
|
||||||
|
f: Boolean(message.f)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (message.type == 'multiplayer_leave') {
|
||||||
|
const multiplayerInfo = multiplayerClients.find(
|
||||||
|
client => client.Id == ws.id
|
||||||
|
)
|
||||||
|
if (!multiplayerInfo) return
|
||||||
|
multiplayerClients = multiplayerClients.filter(
|
||||||
|
client => client.Id !== ws.id
|
||||||
|
)
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
if (ws.id == multiplayerClientInfo.Id) continue
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_player_leave',
|
||||||
|
id: multiplayerInfo.UserID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if (message.type == 'multiplayer_join_request' && message.auth) {
|
||||||
|
const dbInfo0 = getDatabaseConnection(0)
|
||||||
|
const dbInfo1 = getDatabaseConnection(1)
|
||||||
|
|
||||||
|
if (!dbInfo0 || !dbInfo1) {
|
||||||
|
ws.send({
|
||||||
|
type: 'multiplayer_join_response',
|
||||||
|
accepted: false,
|
||||||
|
denyReason: 'Unable to authenticate',
|
||||||
|
key: null,
|
||||||
|
players: []
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const { connection: connection0, db: db0 } = dbInfo0
|
||||||
|
const { connection: connection1, db: db1 } = dbInfo1
|
||||||
|
|
||||||
|
const ip = ws.remoteAddress
|
||||||
|
const authResult = await checkAuthorization(
|
||||||
|
message.auth as string,
|
||||||
|
db0,
|
||||||
|
ip
|
||||||
|
)
|
||||||
|
if (!authResult.valid) {
|
||||||
|
connection0.end()
|
||||||
|
connection1.end()
|
||||||
|
ws.send({
|
||||||
|
type: 'multiplayer_join_response',
|
||||||
|
accepted: false,
|
||||||
|
denyReason: 'Unable to authenticate',
|
||||||
|
id: null,
|
||||||
|
players: []
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const userId = authResult.id
|
||||||
|
|
||||||
|
const result = await db0
|
||||||
|
.select({
|
||||||
|
username: users.username,
|
||||||
|
admin: users.admin,
|
||||||
|
token: users.token
|
||||||
|
})
|
||||||
|
.from(users)
|
||||||
|
.where(eq(users.id, userId))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
if (result.length != 1) {
|
||||||
|
connection0.end()
|
||||||
|
connection1.end()
|
||||||
|
ws.send({
|
||||||
|
type: 'multiplayer_join_response',
|
||||||
|
accepted: false,
|
||||||
|
denyReason: 'Unable to authenticate',
|
||||||
|
id: null,
|
||||||
|
players: null
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const players: any = []
|
||||||
|
for (const marketplaceInfo of multiplayerClients) {
|
||||||
|
const userData = await db1
|
||||||
|
.select({
|
||||||
|
saveData: berryDashUserData.saveData
|
||||||
|
})
|
||||||
|
.from(berryDashUserData)
|
||||||
|
.where(and(eq(berryDashUserData.id, marketplaceInfo.UserID)))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
const savedata = userData[0].saveData
|
||||||
|
? JSON.parse(userData[0].saveData)
|
||||||
|
: null
|
||||||
|
if (!savedata) {
|
||||||
|
connection0.end()
|
||||||
|
connection1.end()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const customIcon = savedata.bird?.customIcon?.selected ?? null
|
||||||
|
const icon = customIcon ? 0 : savedata?.icon ?? 1
|
||||||
|
const overlay = customIcon ? 1 : savedata?.overlay ?? 0
|
||||||
|
const iconColor = customIcon
|
||||||
|
? [255, 255, 255]
|
||||||
|
: savedata?.settings?.colors?.icon ?? [255, 255, 255]
|
||||||
|
const overlayColor = customIcon
|
||||||
|
? [255, 255, 255]
|
||||||
|
: savedata?.settings?.colors?.overlay ?? [255, 255, 255]
|
||||||
|
|
||||||
|
players.push({
|
||||||
|
id: marketplaceInfo.UserID,
|
||||||
|
username: result[0].username,
|
||||||
|
admin: result[0].admin,
|
||||||
|
timestamp: marketplaceInfo.JoinTimestamp,
|
||||||
|
iconData: {
|
||||||
|
icon,
|
||||||
|
overlay,
|
||||||
|
iconColor,
|
||||||
|
overlayColor,
|
||||||
|
customIcon: customIcon ?? ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const key = randomBytes(16).toString('hex')
|
||||||
|
const time = Date.now()
|
||||||
|
const data: MultiplayerClient = {
|
||||||
|
Id: ws.id,
|
||||||
|
Key: key,
|
||||||
|
PosX: 0,
|
||||||
|
PosY: -1,
|
||||||
|
Flipped: false,
|
||||||
|
Paused: false,
|
||||||
|
FlaggedReason: null,
|
||||||
|
Token: result[0].token, //Just to be safe
|
||||||
|
Username: result[0].username,
|
||||||
|
UserID: userId,
|
||||||
|
Admin: result[0].admin,
|
||||||
|
Platform: null,
|
||||||
|
JoinTimestamp: time
|
||||||
|
}
|
||||||
|
multiplayerClients.push(data)
|
||||||
|
ws.send({
|
||||||
|
type: 'multiplayer_join_response',
|
||||||
|
accepted: true,
|
||||||
|
denyReason: null,
|
||||||
|
players
|
||||||
|
})
|
||||||
|
|
||||||
|
const userData = await db1
|
||||||
|
.select({
|
||||||
|
saveData: berryDashUserData.saveData
|
||||||
|
})
|
||||||
|
.from(berryDashUserData)
|
||||||
|
.where(and(eq(berryDashUserData.id, userId)))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
const savedata = userData[0].saveData
|
||||||
|
? JSON.parse(userData[0].saveData)
|
||||||
|
: null
|
||||||
|
if (!savedata) {
|
||||||
|
connection0.end()
|
||||||
|
connection1.end()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const customIcon = savedata.bird?.customIcon?.selected ?? null
|
||||||
|
const icon = customIcon ? 0 : savedata?.icon ?? 1
|
||||||
|
const overlay = customIcon ? 1 : savedata?.overlay ?? 0
|
||||||
|
const iconColor = customIcon
|
||||||
|
? [255, 255, 255]
|
||||||
|
: savedata?.settings?.colors?.icon ?? [255, 255, 255]
|
||||||
|
const overlayColor = customIcon
|
||||||
|
? [255, 255, 255]
|
||||||
|
: savedata?.settings?.colors?.overlay ?? [255, 255, 255]
|
||||||
|
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
if (ws.id == multiplayerClientInfo.Id) continue
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_player_join',
|
||||||
|
id: userId,
|
||||||
|
username: result[0].username,
|
||||||
|
admin: result[0].admin,
|
||||||
|
timestamp: time,
|
||||||
|
iconData: {
|
||||||
|
icon,
|
||||||
|
overlay,
|
||||||
|
iconColor,
|
||||||
|
overlayColor,
|
||||||
|
customIcon: customIcon ?? ''
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
connection0.end()
|
||||||
|
connection1.end()
|
||||||
|
} else if (message.type == 'connected_with_current_scene') {
|
||||||
if (
|
if (
|
||||||
!message.sceneName ||
|
!message.sceneName ||
|
||||||
!message.Requester ||
|
!message.Requester ||
|
||||||
@@ -535,12 +835,33 @@ app.ws('/ws', {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
close (ws) {
|
async close (ws) {
|
||||||
clients.forEach(client => {
|
clients.forEach(client => {
|
||||||
if (client.id === ws.id) clients.delete(client)
|
if (client.id === ws.id) clients.delete(client)
|
||||||
})
|
})
|
||||||
|
clientInfo = clientInfo.filter(client => client.Id !== ws.id)
|
||||||
|
|
||||||
console.log(ws.id, 'disconnected')
|
const multiplayerInfo = multiplayerClients.find(
|
||||||
|
client => client.Id == ws.id
|
||||||
|
)
|
||||||
|
if (multiplayerInfo) {
|
||||||
|
multiplayerClients = multiplayerClients.filter(
|
||||||
|
client => client.Id !== ws.id
|
||||||
|
)
|
||||||
|
for (const multiplayerClientInfo of multiplayerClients) {
|
||||||
|
if (ws.id == multiplayerClientInfo.Id) continue
|
||||||
|
const client = Array.from(clients).find(
|
||||||
|
client => client.id === multiplayerClientInfo.Id
|
||||||
|
)
|
||||||
|
if (!client) continue
|
||||||
|
client.send({
|
||||||
|
type: 'multiplayer_player_leave',
|
||||||
|
id: multiplayerInfo.UserID
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log(ws.id, 'disconnected')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -1397,6 +1718,35 @@ app.get('/berrydash/render-icon', berryDashRenderIconGetHandler, {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
app.get('/website/launcher/games', websiteLauncherGamesGetHandler, {
|
||||||
|
detail: {
|
||||||
|
hide: true
|
||||||
|
},
|
||||||
|
headers: t.Object({
|
||||||
|
authorization: t.String(),
|
||||||
|
'x-forwarded-for': t.Optional(
|
||||||
|
t.String({
|
||||||
|
hide: true
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
app.get('/website/launcher/game', websiteLauncherGameGetHandler, {
|
||||||
|
detail: {
|
||||||
|
hide: true
|
||||||
|
},
|
||||||
|
query: t.Object({
|
||||||
|
id: t.String()
|
||||||
|
}),
|
||||||
|
headers: t.Object({
|
||||||
|
authorization: t.String(),
|
||||||
|
'x-forwarded-for': t.Optional(
|
||||||
|
t.String({
|
||||||
|
hide: true
|
||||||
|
})
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
app.all(
|
app.all(
|
||||||
'*',
|
'*',
|
||||||
() =>
|
() =>
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import { desc, eq } from 'drizzle-orm'
|
||||||
|
import { games, launcherVersionManifest } from '../../../../lib/tables'
|
||||||
|
import {
|
||||||
|
getClientIp,
|
||||||
|
getDatabaseConnection,
|
||||||
|
jsonResponse
|
||||||
|
} from '../../../../lib/util'
|
||||||
|
import { Context } from 'elysia'
|
||||||
|
import { checkAuthorization } from '../../../../lib/auth'
|
||||||
|
|
||||||
|
export const handler = async (context: Context) => {
|
||||||
|
const dbResult = getDatabaseConnection(0)
|
||||||
|
if (!dbResult) return
|
||||||
|
const { connection, db } = dbResult
|
||||||
|
|
||||||
|
const gameId = Number(context.query.id)
|
||||||
|
const ip = getClientIp(context)
|
||||||
|
const authorizationToken = context.headers.authorization
|
||||||
|
const authResult = await checkAuthorization(
|
||||||
|
authorizationToken as string,
|
||||||
|
db,
|
||||||
|
ip
|
||||||
|
)
|
||||||
|
if (!authResult.valid) {
|
||||||
|
connection.end()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (![1, 2].includes(authResult.id)) {
|
||||||
|
connection.end()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const gameInfo = await db
|
||||||
|
.select({ name: games.name, categoryNames: games.categoryNames })
|
||||||
|
.from(games)
|
||||||
|
.where(eq(games.id, gameId))
|
||||||
|
.execute()
|
||||||
|
if (gameInfo.length != 1) {
|
||||||
|
connection.end()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const versions = await db
|
||||||
|
.select()
|
||||||
|
.from(launcherVersionManifest)
|
||||||
|
.where(eq(launcherVersionManifest.game, gameId))
|
||||||
|
.orderBy(desc(launcherVersionManifest.place))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
connection.end()
|
||||||
|
|
||||||
|
return jsonResponse(
|
||||||
|
{
|
||||||
|
name: gameInfo[0].name,
|
||||||
|
categories: JSON.parse(gameInfo[0].categoryNames),
|
||||||
|
versions
|
||||||
|
},
|
||||||
|
200,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { checkAuthorization } from '../../../../lib/auth'
|
||||||
|
import { games } from '../../../../lib/tables'
|
||||||
|
import {
|
||||||
|
getClientIp,
|
||||||
|
getDatabaseConnection,
|
||||||
|
jsonResponse
|
||||||
|
} from '../../../../lib/util'
|
||||||
|
import { Context } from 'elysia'
|
||||||
|
|
||||||
|
export const handler = async (context: Context) => {
|
||||||
|
const dbResult = getDatabaseConnection(0)
|
||||||
|
if (!dbResult) return jsonResponse([], 500, false)
|
||||||
|
const { connection, db } = dbResult
|
||||||
|
|
||||||
|
const ip = getClientIp(context)
|
||||||
|
const authorizationToken = context.headers.authorization
|
||||||
|
const authResult = await checkAuthorization(
|
||||||
|
authorizationToken as string,
|
||||||
|
db,
|
||||||
|
ip
|
||||||
|
)
|
||||||
|
if (!authResult.valid) {
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse(
|
||||||
|
{ success: false, message: 'Unauthorized', data: null },
|
||||||
|
401
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (![1, 2].includes(authResult.id)) {
|
||||||
|
connection.end()
|
||||||
|
return jsonResponse(
|
||||||
|
{ success: false, message: 'Unauthorized', data: null },
|
||||||
|
401
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const gamesList = await db
|
||||||
|
.select({ id: games.id, name: games.name })
|
||||||
|
.from(games)
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
connection.end()
|
||||||
|
|
||||||
|
return jsonResponse(gamesList, 200, false)
|
||||||
|
}
|
||||||
Reference in new issue
Block a user