@tf2pickup-org/mumble-client

中文文档
0.15.2发布于 2026/11/02MITTypeScriptES Module构建来源已验证

一个简单的机器人,用于管理mumble服务器

中文使用文档
文档目录25 节
  1. 功能
  2. 安装
  3. 快速启动
  4. 示例
  5. 使用密码和访问令牌进行连接
  6. 列出所有频道
  7. 找一个频道
  8. 创建和管理渠道
  9. 在不同渠道之间移动用户
  10. 使自己静音/耳聋
  11. 注册和管理用户
  12. 短信、证书哈希和地址
  13. 检查通道权限
  14. 听事件
  15. 错误处理
  16. API概述
  17. Client
  18. ChannelManager
  19. Channel
  20. UserManager
  21. User
  22. Permissions
  23. 事件
  24. ClientOptions
  25. 许可证

mumble-客户端

一个简单的模糊客户端,用于管理模糊服务器

Latest release Test status MIT license

功能

  • 通过TLS连接到任何Mumble服务器
  • 管理通道:创建、删除、链接/解除链接、获取acl
  • 管理用户: 移动,静音/耳聋,注册/注销,重命名
  • 发送和接收私人短信;读取证书哈希值和客户端IP地址
  • 渠道权限查询
  • 具有完整TypeScript支持的事件驱动架构
  • 自动保持活ping

安装

npm i @tf2pickup-org/mumble-client

快速启动

import { Client } from '@tf2pickup-org/mumble-client';

const client = new Client({
  host: 'mumble.example.com',
  port: 64738,
  username: 'my-bot',
  rejectUnauthorized: false,
});

await client.connect();
console.log(`Connected! Welcome message: ${client.welcomeText}`);
console.log(`Logged in as ${client.self?.name}`);

// ... do work ...

client.disconnect();

示例

使用密码和访问令牌进行连接

const client = new Client({
  host: 'mumble.example.com',
  port: 64738,
  username: 'my-bot',
  password: 'server-password',
  tokens: ['token-for-acl-group'],
  clientName: 'my-awesome-bot',
  rejectUnauthorized: false,
});

await client.connect();

列出所有频道

import { type Channel } from '@tf2pickup-org/mumble-client';

function printChannel(channel: Channel, level = 0) {
  if (channel.name) {
    console.log(' '.repeat(level * 2) + channel.name);
  }

  for (const subChannel of channel.subChannels) {
    printChannel(subChannel, level + 1);
  }
}

printChannel(client.channels.root);

找一个频道

// by name
const lobby = client.channels.byName('Lobby');

// by path (from root)
const redTeam = client.channels.byPath('Match 1', 'RED');

// by custom predicate
const tempChannels = client.channels.findAll(ch => ch.temporary);

创建和管理渠道

const root = client.channels.root;

// create a sub-channel under root
const matchChannel = await root.createSubChannel('Match 1');

// create team channels
const red = await matchChannel.createSubChannel('RED');
const blu = await matchChannel.createSubChannel('BLU');

// link two channels together
await red.link(blu);

// unlink them
await red.unlink(blu);

// remove a channel (and all its sub-channels)
await matchChannel.remove();

在不同渠道之间移动用户

const user = client.users.byName('PlayerOne');
const targetChannel = client.channels.byName('RED');

if (user && targetChannel) {
  await user.moveToChannel(targetChannel.id);
}

使自己静音/耳聋

// self-mute
await client.self.setSelfMute(true);

// self-deafen
await client.self.setSelfDeaf(true);

// unmute
await client.self.setSelfMute(false);

注册和管理用户

// register the currently logged-in user
await client.self.register();

// fetch all registered users from the server
const registeredUsers = await client.fetchRegisteredUsers();
for (const user of registeredUsers) {
  console.log(`${user.userId}: ${user.name}`);
}

// rename a registered user (does not need to be online)
await client.renameRegisteredUser(userId, 'NewName');

// deregister a user (does not need to be online)
await client.deregisterUser(userId);

短信、证书哈希和地址

client.on('textMessage', async ({ sender, message, isPrivate }) => {
  if (sender && isPrivate) {
    await sender.sendMessage(`you said: ${message}`);
  }
});

// message everyone in a channel
await client.channels.byName('Lobby')?.sendMessage('hello');

// SHA1 hash of the user's certificate, sent for every user
console.log(user.hash);

// IP address; needs the Ban permission on the root channel
console.log(await user.fetchAddress());

检查通道权限

const channel = client.channels.byName('Lobby');
if (channel) {
  const permissions = await channel.getPermissions();
  console.log('Can join:', permissions.canJoinChannel);
  console.log('Can create sub-channels:', permissions.canCreateChannel);
  console.log('Can remove:', permissions.canRemoveChannel);
  console.log('Can link:', permissions.canLinkChannel);
}

听事件

// user connected
client.on('userCreate', user => {
  console.log(`${user.name} connected`);
});

// user disconnected
client.on('userRemove', user => {
  console.log(`${user.name} disconnected`);
});

// user state changed (e.g. moved channel, muted, etc.)
client.on('userUpdate', (user, changes) => {
  if (changes.channelId) {
    const from = client.channels.byId(changes.channelId.previousValue);
    const to = client.channels.byId(changes.channelId.currentValue);
    console.log(`${user.name} moved from ${from?.name} to ${to?.name}`);
  }
});

// channel created
client.on('channelCreate', channel => {
  console.log(`Channel created: ${channel.name}`);
});

// channel removed
client.on('channelRemove', channel => {
  console.log(`Channel removed: ${channel.name}`);
});

// speaking state changes
client.on('speakingStateChange', ({ user, speaking }) => {
  console.log(`${user.name} ${speaking ? 'started' : 'stopped'} speaking`);
});

// disconnected from server
client.on('disconnect', payload => {
  console.log(`Disconnected: ${payload?.reason ?? 'unknown reason'}`);
});

错误处理

import {
  Client,
  ClientDisconnectedError,
  ConnectionRejectedError,
  PermissionDeniedError,
} from '@tf2pickup-org/mumble-client';

try {
  await client.connect();
} catch (error) {
  if (error instanceof ConnectionRejectedError) {
    console.error('Connection rejected by server');
  } else if (error instanceof ClientDisconnectedError) {
    // the server dropped the connection during the handshake,
    // or another connect() call superseded this one
    console.error('Connection lost');
  }
}

// background errors, e.g. a failed keep-alive ping; without a listener
// Node.js throws on an 'error' event
client.on('error', error => {
  console.error('Client error:', error);
});

try {
  await client.channels.root.createSubChannel('test');
} catch (error) {
  if (error instanceof PermissionDeniedError) {
    console.error('Insufficient permissions to create channel');
  }
}

API概述

Client

主要入口点。连接到服务器并提供对通道、用户和事件的访问。

属性/方法描述
channelsChannelManager 用于查找频道的实例
usersUserManager 查找用户的实例
self当前登录的 User
session当前登录用户的会话ID
welcomeText服务器欢迎信息
serverVersion服务器版本信息
serverConfig服务器配置 (最大用户数、消息长度…)
socket底层套接字,for 音频; undefined 当断开连接
connect()连接到Mumble服务器; 如果已连接,请先断开连接
disconnect()断开与服务器的连接;不连接时什么都不做
isConnected()返回 true 如果已连接
fetchRegisteredUsers()获取所有注册用户
deregisterUser(userId)按ID取消注册用户
renameRegisteredUser(userId, name)重命名已注册用户

ChannelManager

方法描述
root根通道
byId(channelId)按ID查找频道
byName(name)按名称查找频道
byPath(...path)按路径段查找通道
find(predicate)找到第一个匹配通道
findAll(predicate)找到所有匹配的频道

Channel

属性/方法描述
id通道标识
name频道名称
temporary通道是否为临时通道
users当前在此通道中的用户
subChannels直接子信道
linkedChannels链接渠道
createSubChannel(name)创建子通道
remove()删除此通道
link(channel)与另一个频道连接
unlink(channel)从另一个通道取消链接
getPermissions()获取该通道的权限
fetchAcl()获取通道ACL
saveAcl(acl)保存通道ACL

UserManager

方法描述
bySession(session)根据会话ID查找用户
byName(name)按名称查找用户
findAll(predicate)查找所有匹配的用户

User

属性/方法描述
session会话ID
name用户名
channel当前频道
channelId当前通道ID
isRegistered用户是否已注册
mute / deaf / suppress服务器静音/聋哑/抑制状态
selfMute / selfDeafSelf-mute /聋状态
moveToChannel(channelId)将用户移动到频道
setSelfMute(mute)设置自静音状态
setSelfDeaf(deaf)设置自聋状态
register()注册用户
deregister()注销用户
rename(name)重命名已注册用户

Permissions

属性/方法描述
canJoinChannel可以加入/进入频道吗
canCreateChannel可以创建子通道
canRemoveChannel可以去除通道
canLinkChannel可以链接频道
canSelfRegister可以自行注册
canRegister可以注册其他用户

事件

事件有效载荷描述
connect- - - - - -客户端连接成功
disconnect{ reason: string }?客户端已断开连接; 每个连接发出一次。 reason 是服务器的(例如,当踢)或 'connection closed' 当服务器断开连接时;之后没有有效载荷 disconnect() 或者重新连接
errorunknown后台错误,例如keepalive ping失败
channelCreateChannel创建了一个频道
channelUpdateChannel, ChannelChanges一个频道被更新
channelRemoveChannel一个通道已被删除
userCreateUser已连接的用户
userUpdateUser, UserChanges用户的状态已更改
userRemoveUser用户已断开连接
speakingStateChange{ user: User, speaking: boolean }用户开始/停止说话

ClientOptions

扩展Node.js tls.ConnectionOptions.

选项类型默认的描述
hoststring- - - - - -服务器主机名
portnumber64738服务器端口
usernamestring- - - - - -用于身份验证的用户名
passwordstring?- - - - - -服务器或用户密码
tokensstring[]?[]服务器ACL组的访问令牌
clientNamestring?'simple mumble bot'发送到服务器的客户端名称
pingIntervalnumber?10000保持活动ping间隔 (毫秒)

自 ClientOptions 扩展 tls.ConnectionOptions,您可以传递任何TLS选项,例如 rejectUnauthorized, cert, key, ca等。

许可证

麻省理工学院

版本与发布记录

@tf2pickup-org/mumble-client 共发布 24 个版本,首次发布于 2022/06/07;过去 12 个月发布了 8 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.15.2latest2026/11/02今天
0.15.12026/11/021 天前
0.15.02026/11/012 天前
0.14.02026/10/313 天前
0.13.12026/10/313 天前
0.13.02026/03/047 个月前

关于 @tf2pickup-org/mumble-client 的常见问题

@tf2pickup-org/mumble-client 是什么?

一个简单的机器人,用于管理mumble服务器

如何安装 @tf2pickup-org/mumble-client?

在项目目录运行 npm install @tf2pickup-org/mumble-client,或使用 pnpm add / yarn add / bun add。

@tf2pickup-org/mumble-client 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@tf2pickup-org/mumble-client 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@tf2pickup-org/mumble-client 可以商用吗?

@tf2pickup-org/mumble-client 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@tf2pickup-org/mumble-client 还在维护吗?

最新版本 0.15.2 发布于 2026/11/02(今天);至今共发布 24 个版本,其中过去 12 个月发布了 8 个;首次发布于 2022/06/07。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。