import { getPublicUser, prisma, User } from "@repo/db"; import { addRolesToMember, removeRolesFromMember, renameMember } from "modules/discord"; import { DISCORD_ROLES } from "@repo/db"; import { Server, Socket } from "socket.io"; export const handleConnectPilot = (socket: Socket, io: Server) => async ({ logoffTime, stationId }: { logoffTime: string; stationId: string }) => { try { 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) return Error("User not found"); const existingConnection = await prisma.connectedAircraft.findFirst({ where: { userId: user.id, logoutTime: null, }, }); if (existingConnection) { 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(), }, }); } let parsedLogoffDate = null; if (logoffTime.length > 0) { const now = new Date(); const [hours, minutes] = logoffTime.split(":").map(Number); if (!hours || !minutes) { throw new Error("Invalid logoffTime format"); } parsedLogoffDate = new Date(now); parsedLogoffDate.setHours(hours, minutes, 0, 0); // If the calculated time is earlier than now, add one day to make it tomorrow if (parsedLogoffDate <= now) { parsedLogoffDate.setDate(parsedLogoffDate.getDate() + 1); } } const connectedAircraftEntry = await prisma.connectedAircraft.create({ data: { publicUser: getPublicUser(user) as any, esimatedLogoutTime: parsedLogoffDate?.toISOString() || null, lastHeartbeat: new Date().toISOString(), userId: userId, loginTime: new Date().toISOString(), stationId: parseInt(stationId), }, }); 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("dispatchers"); // Join the dispatchers 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, ); // Add a listener for station-specific events socket.on("ptt", async ({ shouldTransmit, channel }) => { if (shouldTransmit) { io.to("dispatchers").emit("other-ptt", { publicUser: getPublicUser(user), channel, source: Station?.bosCallsignShort, }); io.to("piots").emit("other-ptt", { publicUser: getPublicUser(user), channel, source: Station?.bosCallsignShort, }); } }); 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); } };