UNPKG

@tf2pickup-org/mumble-client

Version:
176 lines 6.54 kB
import { ACL, ChannelRemove, ChannelState, PermissionQuery, } from '@tf2pickup-org/mumble-protocol'; import { InsufficientPermissionsError, NoSuchChannelError } from './errors/index.js'; import { Permissions } from './permissions.js'; import { syncProperty } from './sync-property.js'; export class Channel { client; id; name; parent; temporary; links = []; constructor(client, channelState) { this.client = client; this.id = channelState.channelId; this.name = channelState.name ?? ''; this.parent = channelState.parent ?? 0; this.links = [...channelState.links]; this.temporary = channelState.temporary ?? false; } syncState(channelState) { const changes = { ...syncProperty(this, 'name', channelState.name), ...syncProperty(this, 'parent', channelState.parent), ...syncProperty(this, 'temporary', channelState.temporary), }; if (channelState.linksAdd.length + channelState.linksRemove.length > 0) { changes.linkedChannels = { previousValue: [...this.linkedChannels], currentValue: [], }; this.links = [ ...new Set([ ...this.links, ...channelState.links, ...channelState.linksAdd, ]), ].filter(l => !channelState.linksRemove.includes(l)); changes.linkedChannels.currentValue = this.linkedChannels; } return changes; } get users() { return this.client.users.findAll(user => user.channelId === this.id); } get subChannels() { return this.client.channels.findAll(channel => channel.parent === this.id); } get linkedChannels() { return this.links .map(ch => this.client.channels.byId(ch)) .filter(ch => ch !== undefined); } async createSubChannel(name) { const permissions = await this.getPermissions(); if (!permissions.canCreateChannel) { throw new InsufficientPermissionsError(); } const ret = await this.client.command('createChannel', { sendPacket: [ ChannelState, ChannelState.create({ parent: this.id, name }), ], expectPacket: [ ChannelState, channelState => channelState.parent === this.id && channelState.name === name, ], }); return this.client.channels.byId(ret.channelId); } async remove() { const permissions = await this.getPermissions(); if (!permissions.canRemoveChannel) { throw new InsufficientPermissionsError(); } await this.client.command('removeChannel', { sendPacket: [ChannelRemove, ChannelRemove.create({ channelId: this.id })], expectPacket: [ChannelRemove, ({ channelId }) => channelId === this.id], }); return this; } async getPermissions() { if (this.client.self?.userId === 0) { return Permissions.superUser(); } if (this.client.permissions.has(this.id)) { return this.client.permissions.get(this.id); } const ret = await this.client.command('fetchChannelPermissions', { sendPacket: [ PermissionQuery, PermissionQuery.create({ channelId: this.id }), ], expectPacket: [PermissionQuery, ({ channelId }) => channelId === this.id], }); return new Permissions(ret.permissions ?? 0); } async link(otherChannel) { if (!(await this.getPermissions()).canLinkChannel) { throw new InsufficientPermissionsError(); } const targetChannel = typeof otherChannel === 'number' ? this.client.channels.byId(otherChannel) : otherChannel; if (targetChannel === undefined) { throw new NoSuchChannelError(typeof otherChannel === 'number' ? otherChannel : otherChannel.id); } if (!(await targetChannel.getPermissions()).canLinkChannel) { throw new InsufficientPermissionsError(); } await this.client.command('linkChannels', { sendPacket: [ ChannelState, ChannelState.create({ channelId: this.id, linksAdd: [targetChannel.id], }), ], expectPacket: [ChannelState, ({ channelId }) => channelId === this.id], }); return this; } async unlink(otherChannel) { if (!(await this.getPermissions()).canLinkChannel) { throw new InsufficientPermissionsError(); } const targetChannel = typeof otherChannel === 'number' ? this.client.channels.byId(otherChannel) : otherChannel; if (targetChannel === undefined) { throw new NoSuchChannelError(typeof otherChannel === 'number' ? otherChannel : otherChannel.id); } if (!(await targetChannel.getPermissions()).canLinkChannel) { throw new InsufficientPermissionsError(); } await this.client.command('unlinkChannels', { sendPacket: [ ChannelState, ChannelState.create({ channelId: this.id, linksRemove: [targetChannel.id], }), ], expectPacket: [ChannelState, ({ channelId }) => channelId === this.id], }); return this; } async fetchAcl() { const acl = await this.client.command('fetchAcl', { sendPacket: [ ACL, ACL.create({ channelId: this.id, query: true, }), ], expectPacket: [ACL, ({ channelId }) => channelId === this.id], }); return acl; } async saveAcl(acl) { await this.client.command('saveAcl', { sendPackets: [ [ACL, ACL.create({ ...acl, channelId: this.id })], [ ACL, ACL.create({ channelId: this.id, query: true, }), ], ], expectPacket: [ACL, ({ channelId }) => channelId === this.id], }); } } //# sourceMappingURL=channel.js.map