feat: signal server tag

This commit is contained in:
2026-06-05 06:16:02 +02:00
parent 6865147e8f
commit bf4e6891d1
69 changed files with 2808 additions and 1269 deletions

View File

@@ -39,6 +39,34 @@ function normalizeProfileUpdatedAt(value: unknown): number | undefined {
return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : undefined;
}
function normalizeHomeSignalServerUrl(value: unknown): string | undefined {
if (typeof value !== 'string') {
return undefined;
}
const normalized = value.trim().replace(/\/+$/, '');
return normalized || undefined;
}
function buildPresenceUserPayload(user: ConnectedUser): {
oderId: string;
displayName: string;
description?: string;
profileUpdatedAt?: number;
homeSignalServerUrl?: string;
status: 'online' | 'away' | 'busy' | 'offline';
} {
return {
oderId: user.oderId,
displayName: normalizeDisplayName(user.displayName),
description: user.description,
profileUpdatedAt: user.profileUpdatedAt,
homeSignalServerUrl: user.homeSignalServerUrl,
status: user.status ?? 'online'
};
}
function readMessageId(value: unknown): string | undefined {
if (typeof value !== 'string') {
return undefined;
@@ -82,13 +110,7 @@ function sendPluginError(user: ConnectedUser, error: unknown, message: WsMessage
/** Sends the current user list for a given server to a single connected user. */
function sendServerUsers(user: ConnectedUser, serverId: string): void {
const users = getUniqueUsersInServer(serverId, user.oderId).map((cu) => ({
oderId: cu.oderId,
displayName: normalizeDisplayName(cu.displayName),
description: cu.description,
profileUpdatedAt: cu.profileUpdatedAt,
status: cu.status ?? 'online'
}));
const users = getUniqueUsersInServer(serverId, user.oderId).map((cu) => buildPresenceUserPayload(cu));
user.ws.send(JSON.stringify({ type: 'server_users', serverId, users }));
}
@@ -115,6 +137,7 @@ function handleIdentify(user: ConnectedUser, message: WsMessage, connectionId: s
const previousDisplayName = normalizeDisplayName(user.displayName);
const previousDescription = user.description;
const previousProfileUpdatedAt = user.profileUpdatedAt;
const previousHomeSignalServerUrl = user.homeSignalServerUrl;
user.oderId = newOderId;
user.displayName = normalizeDisplayName(message['displayName'], normalizeDisplayName(user.displayName));
@@ -127,11 +150,20 @@ function handleIdentify(user: ConnectedUser, message: WsMessage, connectionId: s
user.profileUpdatedAt = normalizeProfileUpdatedAt(message['profileUpdatedAt']);
}
if (Object.prototype.hasOwnProperty.call(message, 'homeSignalServerUrl')) {
user.homeSignalServerUrl = normalizeHomeSignalServerUrl(message['homeSignalServerUrl']);
}
user.connectionScope = newScope;
connectedUsers.set(connectionId, user);
console.log(`User identified: ${user.displayName} (${user.oderId})`);
if (user.displayName === previousDisplayName && user.description === previousDescription && user.profileUpdatedAt === previousProfileUpdatedAt) {
if (
user.displayName === previousDisplayName
&& user.description === previousDescription
&& user.profileUpdatedAt === previousProfileUpdatedAt
&& user.homeSignalServerUrl === previousHomeSignalServerUrl
) {
return;
}
@@ -140,11 +172,7 @@ function handleIdentify(user: ConnectedUser, message: WsMessage, connectionId: s
serverId,
{
type: 'user_joined',
oderId: user.oderId,
displayName: normalizeDisplayName(user.displayName),
description: user.description,
profileUpdatedAt: user.profileUpdatedAt,
status: user.status ?? 'online',
...buildPresenceUserPayload(user),
serverId
},
user.oderId
@@ -191,11 +219,7 @@ async function handleJoinServer(user: ConnectedUser, message: WsMessage, connect
sid,
{
type: 'user_joined',
oderId: user.oderId,
displayName: normalizeDisplayName(user.displayName),
description: user.description,
profileUpdatedAt: user.profileUpdatedAt,
status: user.status ?? 'online',
...buildPresenceUserPayload(user),
serverId: sid
},
user.oderId
@@ -460,6 +484,7 @@ export async function handleWebSocketMessage(connectionId: string, message: WsMe
switch (message.type) {
case 'keepalive':
user.ws.send(JSON.stringify({ type: 'keepalive_ack', serverTime: Date.now() }));
break;
case 'identify':