diff --git a/assets/openapi.json b/assets/openapi.json index aa965de..769daa6 100644 --- a/assets/openapi.json +++ b/assets/openapi.json @@ -256,6 +256,9 @@ }, "since": { "type": "integer" + }, + "client_status": { + "$ref": "#/components/schemas/ClientStatus" } }, "required": [ @@ -3764,7 +3767,9 @@ "additionalProperties": false }, "intents": { - "type": "number" + "type": "number", + "properties": {}, + "additionalProperties": false }, "presence": { "$ref": "#/components/schemas/ActivitySchema" @@ -3783,7 +3788,9 @@ "maxItems": 2, "type": "array", "items": { - "type": "number" + "type": "number", + "properties": {}, + "additionalProperties": false } }, "guild_subscriptions": { @@ -7796,6 +7803,26 @@ 5 ] }, + "ClientStatus": { + "type": "object", + "properties": { + "desktop": { + "type": "string" + }, + "mobile": { + "type": "string" + }, + "web": { + "type": "string" + }, + "embedded": { + "type": "string" + }, + "vr": { + "type": "string" + } + } + }, "ChannelPermissionOverwriteType": { "type": "number", "enum": [ @@ -9468,7 +9495,7 @@ "$ref": "#/components/schemas/ClientStatus" }, "status": { - "$ref": "#/components/schemas/Status" + "$ref": "#/components/schemas/PrivateStatus" }, "is_admin_session": { "type": "boolean" @@ -9506,25 +9533,15 @@ "user_id" ] }, - "ClientStatus": { - "type": "object", - "properties": { - "desktop": { - "type": "string" - }, - "mobile": { - "type": "string" - }, - "web": { - "type": "string" - }, - "embedded": { - "type": "string" - }, - "vr": { - "type": "string" - } - } + "PrivateStatus": { + "enum": [ + "dnd", + "idle", + "invisible", + "offline", + "online" + ], + "type": "string" }, "ExtendedLocationInfo": { "type": "object", @@ -13402,7 +13419,7 @@ "length": { "type": "integer" }, - "__@unscopables@698": { + "__@unscopables@749": { "type": "object", "additionalProperties": false, "patternProperties": { @@ -13528,17 +13545,17 @@ "with": { "type": "boolean" }, - "__@iterator@696": { + "__@iterator@747": { "type": "boolean" }, - "__@unscopables@698": { + "__@unscopables@749": { "type": "boolean" } } } }, "required": [ - "__@unscopables@698", + "__@unscopables@749", "length" ] }, diff --git a/assets/schemas.json b/assets/schemas.json index e28447e..0ec5ee0 100644 --- a/assets/schemas.json +++ b/assets/schemas.json @@ -241,6 +241,9 @@ }, "since": { "type": "integer" + }, + "client_status": { + "$ref": "#/definitions/ClientStatus" } }, "additionalProperties": false, @@ -3990,7 +3993,9 @@ "additionalProperties": false }, "intents": { - "type": "bigint" + "type": "number", + "properties": {}, + "additionalProperties": false }, "presence": { "$ref": "#/definitions/ActivitySchema" @@ -4009,7 +4014,9 @@ "maxItems": 2, "type": "array", "items": { - "type": "bigint" + "type": "number", + "properties": {}, + "additionalProperties": false } }, "guild_subscriptions": { @@ -8297,6 +8304,28 @@ ], "$schema": "http://json-schema.org/draft-07/schema#" }, + "ClientStatus": { + "type": "object", + "properties": { + "desktop": { + "type": "string" + }, + "mobile": { + "type": "string" + }, + "web": { + "type": "string" + }, + "embedded": { + "type": "string" + }, + "vr": { + "type": "string" + } + }, + "additionalProperties": false, + "$schema": "http://json-schema.org/draft-07/schema#" + }, "ChannelPermissionOverwriteType": { "type": "number", "enum": [ @@ -10073,7 +10102,7 @@ "$ref": "#/definitions/ClientStatus" }, "status": { - "$ref": "#/definitions/Status" + "$ref": "#/definitions/PrivateStatus" }, "is_admin_session": { "type": "boolean" @@ -10113,26 +10142,15 @@ ], "$schema": "http://json-schema.org/draft-07/schema#" }, - "ClientStatus": { - "type": "object", - "properties": { - "desktop": { - "type": "string" - }, - "mobile": { - "type": "string" - }, - "web": { - "type": "string" - }, - "embedded": { - "type": "string" - }, - "vr": { - "type": "string" - } - }, - "additionalProperties": false, + "PrivateStatus": { + "enum": [ + "dnd", + "idle", + "invisible", + "offline", + "online" + ], + "type": "string", "$schema": "http://json-schema.org/draft-07/schema#" }, "ExtendedLocationInfo": { @@ -14319,7 +14337,7 @@ "length": { "type": "integer" }, - "__@unscopables@698": { + "__@unscopables@749": { "type": "object", "additionalProperties": false, "patternProperties": { @@ -14445,17 +14463,17 @@ "with": { "type": "boolean" }, - "__@iterator@696": { + "__@iterator@747": { "type": "boolean" }, - "__@unscopables@698": { + "__@unscopables@749": { "type": "boolean" } } } }, "required": [ - "__@unscopables@698", + "__@unscopables@749", "length" ] }, diff --git a/src/gateway/opcodes/PresenceUpdate.ts b/src/gateway/opcodes/PresenceUpdate.ts index ca52af2..f4d9ffc 100644 --- a/src/gateway/opcodes/PresenceUpdate.ts +++ b/src/gateway/opcodes/PresenceUpdate.ts @@ -17,7 +17,7 @@ */ import { WebSocket, Payload } from "@spacebar/gateway"; -import { emitEvent, PresenceUpdateEvent, Session, User } from "@spacebar/util"; +import { emitEvent, PresenceUpdateEvent, PrivateStatus, PublicStatus, PublicStatusOrder, Session, User } from "@spacebar/util"; import { check } from "./instanceOf"; import { ActivitySchema } from "@spacebar/schemas"; @@ -26,7 +26,12 @@ check.call(this, ActivitySchema, d); const presence = d as ActivitySchema; - await Session.update({ session_id: this.session_id }, { status: presence.status, activities: presence.activities }); + if (d.status === "unknown") { + const sessions = await Session.find({ where: { user_id: this.user_id } }); + d.status = sessions.sort((a, b) => PublicStatusOrder[a.getPublicStatus()] - PublicStatusOrder[b.getPublicStatus()])[0].getPublicStatus(); + } + + await Session.update({ session_id: this.session_id }, { status: presence.status as PrivateStatus, activities: presence.activities }); const session = await Session.findOneOrFail({ select: { client_status: true }, diff --git a/src/schemas/uncategorised/ActivitySchema.ts b/src/schemas/uncategorised/ActivitySchema.ts index 572c28c..f0dfaf8 100644 --- a/src/schemas/uncategorised/ActivitySchema.ts +++ b/src/schemas/uncategorised/ActivitySchema.ts @@ -17,7 +17,7 @@ */ // TODO: remove entity imports -import { Activity, Status } from "@spacebar/util"; +import { Activity, ClientStatus, Status } from "@spacebar/util"; export const ActivitySchema = { $afk: Boolean, @@ -78,4 +78,5 @@ status: Status; activities?: Activity[]; since?: number; // unix time (in milliseconds) of when the client went idle, or null if the client is not idle + client_status?: ClientStatus; } diff --git a/src/util/entities/Session.ts b/src/util/entities/Session.ts index 058961f..1cb77eb 100644 --- a/src/util/entities/Session.ts +++ b/src/util/entities/Session.ts @@ -20,7 +20,7 @@ import { User } from "./User"; import { BaseClassWithoutId } from "./BaseClass"; import { Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, PrimaryColumn, RelationId } from "typeorm"; -import { Activity, ClientStatus, GatewaySession, GatewaySessionClientInfo, Status } from "../interfaces"; +import { Activity, ClientStatus, GatewaySession, GatewaySessionClientInfo, PrivateStatus } from "../interfaces"; import { randomUpperString } from "@spacebar/api"; import { DateBuilder, IpDataClient, TimeSpan } from "../util"; @@ -57,7 +57,7 @@ client_status: ClientStatus; @Column({ nullable: false, type: String }) - status: Status; + status: PrivateStatus; @Column({ default: false }) is_admin_session: boolean; diff --git a/src/util/interfaces/Event.ts b/src/util/interfaces/Event.ts index 96d04a5..087f0a5 100644 --- a/src/util/interfaces/Event.ts +++ b/src/util/interfaces/Event.ts @@ -35,6 +35,7 @@ GuildOrUnavailable, Snowflake, ThreadMember, + PrivateStatus, } from "@spacebar/util"; import { JsonValue } from "@protobuf-ts/runtime"; import { @@ -603,7 +604,7 @@ activities: Activity[]; hidden_activities: Activity[]; client_info: GatewaySessionClientInfo; - status: Status; + status: PrivateStatus; active?: boolean; // How is this even defined? } diff --git a/src/util/interfaces/Status.ts b/src/util/interfaces/Status.ts index 8edd379..93e1b74 100644 --- a/src/util/interfaces/Status.ts +++ b/src/util/interfaces/Status.ts @@ -16,6 +16,20 @@ along with this program. If not, see . */ +export enum PublicStatusOrder { + online = 0, + idle = 1, + dnd = 2, + offline = 3, +} + +console.log(PublicStatusOrder); + +export type PublicStatus = keyof typeof PublicStatusOrder; +export type PrivateStatus = PublicStatus | "invisible"; +export type SetPrivateStatus = PrivateStatus | "unknown"; + +// @deprecated Use PublicStatus, PrivateStatus or SetPrivateStatus instead export type Status = | "idle" | "dnd"