import { getPublicUser, prisma, User } from "@repo/db"; import { addRolesToMember, removeRolesFromMember, renameMember } from "modules/discord"; import { getNextDateWithTime } from "@repo/shared-components"; import { DISCORD_ROLES } from "@repo/db"; import { Server, Socket } from "socket.io"; import { getUserPenaltys } from "helper"; export const handleConnectPilot = (socket: Socket, io: Server) => async ({ logoffTime, stationId, debug, }: { logoffTime: string; stationId: string; debug: boolean; }) => { try { console.log("Connecting pilot:", socket.id, "Station ID:", stationId, "Debug mode:", debug); if (!stationId) return Error("Station ID is required"); const user: User = socket.data.user; // User ID aus dem JWT-Token const userId = socket.data.user.id; // User ID aus dem JWT-Token const Station = await prisma.station.findFirst({ where: { id: parseInt(stationId), }, }); if (!user.permissions.includes("PILOT")) { socket.emit("connect-message", { message: "Fehlende Berechtigung", }); socket.disconnect(); return; } const userPenaltys = await getUserPenaltys(userId); if ( userPenaltys.openTimeban.length > 0 || user.isBanned || userPenaltys.openBans.length > 0 ) { socket.emit("connect-message", { message: "Du hast eine aktive Strafe und kannst dich deshalb nicht verbinden.", }); socket.disconnect(); return; } if (!user) return Error("User not found"); const existingConnection = await prisma.connectedAircraft.findFirst({ where: { userId: user.id, logoutTime: null, }, }); if (existingConnection && !debug) { await io.to(`user:${user.id}`).emit("force-disconnect", "double-connection"); await prisma.connectedAircraft.updateMany({ where: { userId: user.id, logoutTime: null, }, data: { logoutTime: new Date().toISOString(), }, }); } // Set "now" to 2 hours in the future const nowPlus2h = new Date(); nowPlus2h.setHours(nowPlus2h.getHours() + 2); // Generate a random position in Germany (approximate bounding box) function getRandomGermanPosition() { const minLat = 47.2701; const maxLat = 55.0581; const minLng = 5.8663; const maxLng = 15.0419; const lat = Math.random() * (maxLat - minLat) + minLat; const lng = Math.random() * (maxLng - minLng) + minLng; return { lat, lng }; } const randomPos = debug ? getRandomGermanPosition() : undefined; const connectedAircraftEntry = await prisma.connectedAircraft.create({ data: { publicUser: getPublicUser(user) as any, esimatedLogoutTime: logoffTime.length > 0 ? logoffTime : null, userId: userId, stationId: parseInt(stationId), lastHeartbeat: debug ? nowPlus2h.toISOString() : undefined, posLat: randomPos?.lat, posLng: randomPos?.lng, }, }); const discordAccount = await prisma.discordAccount.findFirst({ where: { userId: user.id, }, }); if (discordAccount?.id) { await renameMember( discordAccount.discordId.toString(), `${getPublicUser(user).fullName} • ${Station?.bosCallsignShort}`, ); await addRolesToMember(discordAccount.discordId.toString(), [DISCORD_ROLES.ONLINE_PILOT]); } socket.join("pilots"); // Join the pilots room socket.join(`user:${userId}`); // Join the user-specific room socket.join(`station:${stationId}`); // Join the station-specific room io.to("dispatchers").emit("pilots-update"); io.to("pilots").emit("pilots-update"); io.to(`user:${connectedAircraftEntry.userId}`).emit( "aircraft-update", connectedAircraftEntry, ); socket.on("disconnect", async () => { await prisma.connectedAircraft .update({ where: { id: connectedAircraftEntry.id, }, data: { logoutTime: new Date().toISOString(), }, }) .catch(console.error); io.to("dispatchers").emit("update-connectedAircraft"); io.to("pilots").emit("pilots-update"); if (discordAccount?.id) { await renameMember( discordAccount.discordId.toString(), `${getPublicUser(user).fullName} - ${user.publicId}`, ); await removeRolesFromMember(discordAccount.discordId.toString(), [ DISCORD_ROLES.ONLINE_PILOT, ]); } }); } catch (error) { console.error("Error connecting to dispatch server:", error); } };