@tf2pickup-org/mumble-client
Version:
A simple bot for managing mumble servers
176 lines • 6.54 kB
JavaScript
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