首次推送

This commit is contained in:
sansen
2026-07-20 19:01:03 +08:00
parent ea01b9cf99
commit ef1bf61f9f
4484 changed files with 937163 additions and 1 deletions
+629
View File
@@ -0,0 +1,629 @@
# UI 架构设计
> 依据:`docs/流程/00_总览.md` 及 `docs/流程/01~08` 各流程文件
> 范围:页面布局、卡片设计、全局交互、状态处理、流程映射
---
## 一、架构总览
### 1.1 整体结构:3 页 3 卡
```
页面(Page) 卡片(Card
┌─────────────────────┐ ┌─────────────────────┐
│ 服务器配置页 │ │ 服务器详情卡 │
│ ServerConfigPage │ │ ServerDetailCard │
├─────────────────────┤ │ (底部弹出) │
│ 频道列表页 │ ├─────────────────────┤
│ ChannelListPage │ │ 频道详情卡 │
├─────────────────────┤ │ ChannelDetailCard │
│ 聊天页 │ │ (底部弹出) │
│ ChatPage │ ├─────────────────────┤
└─────────────────────┘ │ 语音卡 │
│ VoiceCard │
│ (底部弹出) │
└─────────────────────┘
```
### 1.2 页面导航关系
```
┌──────────────────────┐
│ 服务器配置页 │
│ (应用启动首屏) │
└──────────┬───────────┘
│ 连接成功
┌──────────────────────┐
┌────→│ 频道列表页 │──────┐
│ │ (主页面) │ │
│ └──────────────────────┘ │
│ │ │
│ │ 点击"中部-底部"当前频道 │
│ ▼ │
│ ┌──────────────────────┐ │
│ │ 聊天页 │ │
│ │ (当前频道消息) │ │
│ └──────────┬───────────┘ │
│ │ 返回按钮 │
└────────────────┘ │
┌───────────────────────────────────┘
│ 头部左侧按钮
服务器详情卡(弹出)
频道列表页 / 聊天页
│ 头部右侧按钮
频道详情卡(弹出)
任意页面(服务器配置页除外)
│ 底部语音控制区 "展开" 按钮
语音卡(弹出)
```
### 1.3 卡片弹出规则
| 卡片 | 可弹出页面 | 弹出方式 | 关闭方式 |
| --- | --- | --- | --- |
| 服务器详情卡 | 频道列表页 | 底部弹出(BottomSheet) | 点击外部 / 下滑 / 断开后自动关闭 |
| 频道详情卡 | 频道列表页、聊天页 | 底部弹出(BottomSheet | 点击外部 / 下滑 |
| 语音卡 | 频道列表页、聊天页 | 底部弹出(BottomSheet),可拖拽为半屏 | 点击外部 / 下滑 / 点击展开按钮 |
---
## 二、页面详细设计
### 2.1 服务器配置页
> 对应流程:01 连接服务器
#### 布局
```
┌──────────────────────────────┐
│ 上:品牌区 │
│ [Logo] │
│ TeamSpeak Mobile │
│ 连接到你的 TeamSpeak 服务器 │
│ [🌙 主题] │ ← 右上角主题切换图标
├──────────────────────────────┤
│ 中:输入区 │
│ │
│ 服务器地址 │
│ ┌──────────────────────────┐│
│ │ ts.example.com ││
│ └──────────────────────────┘│
│ │
│ 昵称 │
│ ┌──────────────────────────┐│
│ │ 我的昵称 ││
│ └──────────────────────────┘│
│ │
│ 密码(可选) │
│ ┌──────────────────────────┐│
│ │ •••••• ││
│ └──────────────────────────┘│
│ │
│ ┌──────────────────────────┐│
│ │ 连接服务器 ││ ← 按钮状态见 5.1
│ └──────────────────────────┘│
├──────────────────────────────┤
│ 下:最近连接 │
│ │
│ 最近连接 │
│ ┌──────────────────────────┐│
│ │ 🟢 ts.myserver.com ││ ← 点击快速连接
│ │ 上次连接:2小时前 ││
│ ├──────────────────────────┤│
│ │ 🔴 ts.other.com ││
│ │ 上次连接:昨天 ││
│ └──────────────────────────┘│
│ │
│ [清空最近记录] │ ← 长按或编辑模式删除单条
└──────────────────────────────┘
```
#### 三段式结构说明
| 段落 | 内容 | 说明 |
| --- | --- | --- |
| 上(品牌区) | Logo + 描述文本 + 主题切换 | 仅展示,不可交互(主题图标除外) |
| 中(输入区) | 地址/昵称/密码输入 + 连接按钮 | 核心交互区,连接成功跳转频道列表页 |
| 下(最近连接) | 历史服务器列表 | 点击直接快速连接(复用已保存的昵称和密码) |
#### 输入验证规则
| 字段 | 必填 | 验证规则 | 错误提示 |
| --- | --- | --- | --- |
| 服务器地址 | 是 | 非空,格式合法(域名/IP/TSDNS) | "请输入有效的服务器地址" |
| 昵称 | 是 | 非空,满足服务器命名规则 | "请输入昵称" |
| 密码 | 否 | 仅当服务器需要密码时必填 | "该服务器需要密码" |
#### 最近连接列表
- 点击列表项 → 自动填充地址/昵称/密码 → 触发连接
- 最多保存 10 条历史记录
- 按最近连接时间倒序排列
- 连接成功的服务器标记为绿色,失败的标记为红色(短暂)
- 长按可删除单条记录
---
### 2.2 频道列表页
> 对应流程:02 浏览频道 + 03 切换频道 + 08 状态同步
#### 布局
```
┌──────────────────────────────────────┐
│ 头部(三段) │
│ ┌────┐ ┌──────────────────┐ ┌─────┐ │
│ │ ☰ │ │ MyServer │ │ 🟢 │ │
│ │服务│ │ 192.168.1.1:9987 │ │连接 │ │ ← 连接状态指示
│ │器卡│ │ 42人在线 │ │状态 │ │
│ └────┘ └──────────────────┘ └─────┘ │
├──────────────────────────────────────┤
│ 中部:频道树 + 成员 │
│ │
│ ▼ 📁 默认频道 │ ← 展开/折叠
│ ▼ 📁 大厅 │
│ 👤 Alice │ ← 点击弹出成员操作菜单
│ 👤 Bob 🔇 │ ← 🔇 = 正在发言
│ 👤 Charlie 🎤 │ ← 🎤 = 正在发言
│ ▶ 📁 游戏区 🔒 │ ← 🔒 = 有密码
│ (3人) │ ← 折叠时显示人数
│ ▶ 📁 音乐区 │
│ (1人) │
│ ▼ 📁 VIP 频道 🔒 │
│ 👤 Admin │
│ │
│ (频道列表支持滚动) │
├──────────────────────────────────────┤
│ 中部-底部:当前频道栏 │
│ ┌──────────────────────────────────┐ │
│ │ 💬 大厅 (5人) Alice🎤 Bob │ │ ← 点击跳转到聊天页
│ └──────────────────────────────────┘ │
├──────────────────────────────────────┤
│ 底部:语音控制 │
│ ┌──────┐ ┌────────────────┐ ┌─────┐ │
│ │ 🎤 │ │ PTT 按住发言 │ │ ⬆ │ │
│ │静音 │ │ │ │语音 │ │ ← 展开语音卡
│ └──────┘ └────────────────┘ └─────┘ │
└──────────────────────────────────────┘
```
#### 频道树交互
| 操作 | 行为 |
| --- | --- |
| 点击频道名 | 无密码 → 直接切换(发送 ClientMove |
| 点击有密码频道 🔒 | 弹出频道密码对话框(见 4.2) |
| 点击折叠频道 ▶ | 展开显示子频道 |
| 点击展开频道 ▼ | 折叠子频道 |
| 长按频道 | 弹出频道操作菜单(频道信息) |
| 点击成员 👤 | 弹出成员操作菜单(见 4.3) |
| 点击当前频道栏 | 跳转到聊天页 |
#### 未读消息指示
| 状态 | 显示 | 说明 |
| --- | --- | --- |
| 无未读 | 正常显示 | — |
| 有未读消息 | 频道名右侧显示红点 ● | 弱未读提示 |
| 有未读 @提及 | 频道名右侧显示数字 badge | 强未读提示 |
| 当前所在频道 | 不显示未读标记 | 已在该频道 |
#### 初始同步加载态
连接成功进入频道列表页时,如果首次同步尚未完成:
```
┌──────────────────────────────┐
│ 头部(正常) │
├──────────────────────────────┤
│ │
│ ⟳ 正在同步服务器数据... │ ← 居中加载指示器
│ │
├──────────────────────────────┤
│ 底部(正常) │
└──────────────────────────────┘
```
同步完成后自动切换为正常频道树视图。
---
### 2.3 聊天页
> 对应流程:04 文本消息
#### 布局
```
┌──────────────────────────────────────┐
│ 头部 │
│ ┌────┐ ┌──────────────────┐ ┌─────┐ │
│ │ ← │ │ 大厅 │ │ ⋮ │ │
│ │返回│ │ 5人 │ │频道 │ │ ← 右侧弹出频道详情卡
│ │ │ │ │ │详情 │ │
│ └────┘ └──────────────────┘ └─────┘ │
├──────────────────────────────────────┤
│ 中部:消息列表 │
│ │
│ ┌──────────────────────────────────┐ │
│ │ Alice 14:30 │ │
│ │ 大家好! │ │
│ ├──────────────────────────────────┤ │
│ │ Bob 14:31 │ │
│ │ 你好 Alice! │ │
│ ├──────────────────────────────────┤ │
│ │ Charlie 14:32 │ │
│ │ 有人一起打游戏吗? │ │
│ ├──────────────────────────────────┤ │
│ │ 我 14:33 │ │
│ │ 我来! │ │ ← 自己的消息靠右 / 不同颜色
│ └──────────────────────────────────┘ │
│ │
│ (消息列表支持滚动,新消息自动滚到底) │
├──────────────────────────────────────┤
│ 中部-底部:消息输入区 │
│ ┌──────────────────────────┐ ┌────┐ │
│ │ 输入消息... │ │ 发送│ │ ← 随输入法上抬
│ └──────────────────────────┘ └────┘ │
├──────────────────────────────────────┤
│ 底部:语音控制 │
│ ┌──────┐ ┌────────────────┐ ┌─────┐ │
│ │ 🎤 │ │ PTT 按住发言 │ │ ⬆ │ │
│ │静音 │ │ │ │语音 │ │
│ └──────┘ └────────────────┘ └─────┘ │
└──────────────────────────────────────┘
```
#### 消息显示格式
```
发送者名称 发送时间
消息内容
```
- 自己的消息靠右对齐或使用不同背景色区分
- 支持长按消息弹出操作菜单(复制 / Poke 发送者)
- 新消息到达时自动滚动到底部
- 如果用户正在查看历史消息,新消息到达时显示 "↓ 新消息" 提示条
#### 消息输入区与键盘联动
- 点击输入框 → 唤起输入法 → 输入区 + 发送按钮随键盘上抬
- 语音控制栏保持固定在底部,不受键盘影响
- 发送消息后输入框清空,保持键盘打开状态
- 输入框为空时发送按钮置灰不可点击
---
## 三、卡片详细设计
### 3.1 服务器详情卡
> 弹出方式:频道列表页头部左侧按钮触发,底部弹出 BottomSheet
```
┌──────────────────────────────┐
│ 服务器详情 ✕ │
├──────────────────────────────┤
│ │
│ 服务器名 │
│ My TeamSpeak Server │
│ │
│ 服务器地址 │
│ 192.168.1.1:9987 │
│ │
│ 在线人数 │
│ 42 / 100 │
│ │
│ ┌──────────────────────────┐│
│ │ 断开服务器 ││ ← 确认弹窗后执行 Disconnect
│ └──────────────────────────┘│
│ │
└──────────────────────────────┘
```
#### 行为
- 断开服务器 → 弹出确认对话框 "确定要断开连接吗?" → 确认后执行断开 → 关闭卡片 → 返回服务器配置页
- 卡片数据来自首次同步结果和实时事件更新
---
### 3.2 频道详情卡
> 弹出方式:聊天页头部右侧按钮触发,底部弹出 BottomSheet
```
┌──────────────────────────────┐
│ 频道详情 ✕ │
├──────────────────────────────┤
│ │
│ 频道名 │
│ 大厅 │
│ │
│ 频道描述 │
│ 欢迎来到大厅频道,请遵守规则 │
│ │
│ 频道人数 │
│ 5人 │
│ │
└──────────────────────────────┘
```
#### 行为
- 如果频道无描述,显示 "暂无描述"
- 有密码频道在频道名旁显示 🔒 图标
---
### 3.3 语音卡
> 弹出方式:频道列表页 / 聊天页底部语音控制区 "展开" 按钮
> 激活时机:进入频道后即激活,除服务器配置页外任意页面可弹出
```
┌──────────────────────────────┐
│ 语音控制 ✕ │
├──────────────────────────────┤
│ │
│ 正在发言 │
│ ┌──────────────────────────┐│
│ │ 🎤 Charlie ▓▓▓▓░░ -12dB││ ← 音量波形指示
│ │ 🎤 Alice ▓▓░░░░ -24dB││
│ └──────────────────────────┘│
│ (无人在发言时显示 "暂无发言")│
│ │
├──────────────────────────────┤
│ │
│ 频道内人员 (5) │
│ ┌──────────────────────────┐│
│ │ 👤 Alice ││ ← 长按弹出操作菜单(Poke)
│ │ 👤 Bob ││
│ │ 👤 Charlie 🎤 发言中 ││ ← 发言中高亮
│ │ 👤 David ││
│ │ 👤 Eve ││
│ └──────────────────────────┘│
│ (人员超出时可滚动) │
│ │
├──────────────────────────────┤
│ 控制 │
│ ┌──────────┐ ┌──────────────┐│
│ │ 🔊 扬声器 │ │ 🎙️ 降噪 ││
│ │ 开 / 关 │ │ 开 / 关 ││
│ └──────────┘ └──────────────┘│
│ │
└──────────────────────────────┘
```
#### 行为
- 发言人栏实时显示正在发送语音帧的成员,附带音量波形指示
- 频道内人员列表支持滚动
- 长按成员 → 弹出操作菜单(Poke)
- 扬声器控制:切换本地音频输出开/关
- 降噪控制:切换本地降噪算法开/关
---
## 四、全局交互
### 4.1 Poke 交互
> 对应流程:02 浏览频道中的 "poke 服务器内成员" 和 "被 poke"
#### 发送 Poke
| 入口 | 操作 |
| --- | --- |
| 频道列表页成员列表 | 长按成员 → 弹出菜单 → Poke |
| 语音卡成员列表 | 长按成员 → 弹出菜单 → Poke |
| 聊天页消息列表 | 长按消息 → 弹出菜单 → Poke 发送者 |
发送后调用 SDK 的 Poke 方法,无需等待服务端确认。
#### 接收 Poke 通知
收到 `OnPoked` 事件时:
```
┌──────────────────────────────┐
│ ┌──────────────────────────┐ │
│ │ 🫴 Alice poke 了你 │ │ ← 顶部 Toast,3秒自动消失
│ │ "起床啦!" │ │
│ └──────────────────────────┘ │
└──────────────────────────────┘
```
- Toast 从顶部滑入,3 秒后自动消失
- 如果在聊天页收到 Poke,同样显示 Toast(不自动跳转)
---
### 4.2 频道密码弹窗
> 对应流程:03 切换频道中的密码检查分支
点击有密码频道 🔒 时弹出:
```
┌──────────────────────────────┐
│ │
│ 该频道需要密码 │
│ │
│ ┌────────────────────────┐ │
│ │ 输入频道密码 │ │
│ └────────────────────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ 取消 │ │ 进入 │ │
│ └──────────┘ └──────────┘ │
│ │
└──────────────────────────────┘
```
- 密码错误 → 按钮变为 "密码错误,重试" → 清空输入框 → 允许重新输入
- 点击取消 → 关闭弹窗,不发送 ClientMove
- 点击进入 → 发送 `ClientMove(selfID, targetID, password)`
---
### 4.3 成员点击行为
在频道列表页和语音卡中,点击/长按成员时弹出操作菜单:
```
┌──────────────────────────────┐
│ 👤 Alice │
│ 频道:大厅 │
├──────────────────────────────┤
│ 🫴 Poke │ → 发送 Poke
│ 📋 复制昵称 │ → 复制到剪贴板
└──────────────────────────────┘
```
---
### 4.4 主题切换
- 入口位置:服务器配置页右上角 🌙 图标
- 切换方式:点击在亮色/暗色主题间切换
- 持久化:选择保存到本地配置,下次启动自动应用
- 影响范围:全局所有页面和卡片
---
## 五、状态处理
### 5.1 连接状态
> 对应流程:01 连接服务器
#### 服务器配置页按钮状态
| 状态 | 按钮外观 | 说明 |
| --- | --- | --- |
| 空闲 | "连接服务器"(正常样式) | 等待用户输入并点击 |
| 连接中 | ⟳ "连接中..."(加载动画 + 禁用) | Connect + WaitConnected 进行中 |
| 连接失败 | "连接失败,点击重试"(红色 + 错误信息) | 显示具体失败原因(密码错误/超时/网络不可达) |
| 超时 | "连接超时,点击重试"(橙色) | WaitConnected 超时 |
#### 错误信息分类
| 错误类型 | 提示信息 | 建议操作 |
| --- | --- | --- |
| 密码错误 | "服务器密码错误" | 重新输入密码 |
| 昵称冲突 | "昵称已被使用,请更换" | 修改昵称 |
| 网络不可达 | "无法连接到服务器,请检查网络" | 检查网络后重试 |
| 地址无效 | "服务器地址无法解析" | 检查地址格式 |
| 超时 | "连接超时" | 检查网络后重试 |
| 服务器满 | "服务器已满" | 稍后重试 |
---
### 5.2 初始同步加载态
> 对应流程:08 状态同步 ① 首次同步
连接成功后进入频道列表页,首次同步期间:
- 频道树区域显示居中加载指示器 + "正在同步服务器数据..."
- 头部正常显示(但在线人数可能显示为 "--"
- 底部语音控制区正常显示
- 同步完成后自动切换到正常频道树视图
- 同步失败 → 显示 "同步失败" + 重试按钮
---
### 5.3 被踢处理
> 对应流程:07 断开连接
被服务器踢出时(`OnKicked` 触发):
```
┌──────────────────────────────┐
│ │
│ 你已被踢出 │
│ │
│ 原因:违反服务器规则 │ ← 显示踢出原因
│ │
│ ┌────────────────────┐ │
│ │ 重新连接 │ │
│ └────────────────────┘ │
│ │
│ ┌────────────────────┐ │
│ │ 返回主页 │ │
│ └────────────────────┘ │
│ │
└──────────────────────────────┘
```
- 全屏覆盖提示,不可通过点击外部关闭
- "重新连接" → 使用相同参数重新连接
- "返回主页" → 回到服务器配置页
- 清理当前会话状态(频道、成员、消息)
---
### 5.4 断线重连
> 对应流程:07 断开连接
网络异常断开时(`OnDisconnected(error)` 触发):
```
┌──────────────────────────────────────┐
│ ┌──────────────────────────────────┐ │
│ │ ⚠️ 连接已断开 │ │ ← 顶部横幅
│ │ 正在尝试重连... (3/5) │ │ ← 自动重连尝试计数
│ │ [手动重连] [放弃] │ │
│ └──────────────────────────────────┘ │
└──────────────────────────────────────┘
```
- 顶部横幅提示,不阻塞底层页面(页面数据冻结)
- 自动重连:最多尝试 5 次,间隔递增(2s → 4s → 8s → 16s → 30s
- 手动重连:用户主动触发立即重连
- 放弃:停止重连 → 显示完整断线提示(类似被踢处理) → 返回主页
- 重连成功 → 执行全量同步(08 状态同步 ⑥)→ 横幅消失 → 恢复正常
---
### 5.5 未读消息指示
> 对应流程:04 文本消息
#### 频道列表页
| 场景 | 显示 | 说明 |
| --- | --- | --- |
| 频道有新消息 | 频道名右侧显示红点 ● | 弱未读(用户不在该频道时) |
| 频道有 @提及 | 频道名右侧显示数字(如 3) | 强未读 |
| 当前所在频道 | 不显示 | 已在该频道,消息直接可见 |
| 用户进入频道后 | 清除该频道的未读标记 | 已读即清 |
---
## 六、页面与流程的对应关系
| 流程文件 | 主要承载页面 | 承载卡片 | 关键交互 |
| --- | --- | --- | --- |
| 01 连接服务器 | 服务器配置页 | — | 输入验证、连接按钮状态、最近连接快速连接 |
| 02 浏览频道 | 频道列表页 | 语音卡 | 频道树展开/折叠、成员列表、Poke、未读指示 |
| 03 切换频道 | 频道列表页 | — | 点击频道切换、密码弹窗、ClientMove 等待确认 |
| 04 文本消息 | 聊天页 | — | 消息列表、发送消息、未读归档 |
| 05 语音通信 | 频道列表页 + 聊天页 | 语音卡 | PTT 按钮、静音控制、发言人指示 |
| 06 文件传输 | — | — | 本应用不实现 |
| 07 断开连接 | 全屏覆盖 | 服务器详情卡 | 断开确认、被踢提示、断线重连横幅 |
| 08 状态同步 | 所有页面 | — | 首次同步加载、增量更新、补偿同步、重连全量同步 |
+111
View File
@@ -0,0 +1,111 @@
# 实施总览
> 本文档是 TeamSpeak Android 客户端实施计划的主索引,将设计文档拆分为可执行的实施步骤。
> 依据:`docs/sdk-bridge-api.md`、`docs/UI架构设计.md`、`docs/流程/`
---
## 〇、已完成工作
| 阶段 | 状态 | 说明 |
| --- | --- | --- |
| Go 层能力封装 | ✅ 完成 | `go/teamspeak/bridge.go` 已封装全部 SDK 能力,gomobile 编译为 AAR |
| Bridge 层实现 | ✅ 完成 | `TSBridge.kt` 单例直接包装 gomobile 导出的 `TSClient`,提供 Kotlin 友好 API |
**当前架构**
```
Go SDK (teamspeak-go) → gomobile → AAR → TSBridge.kt (应用层桥接,单例)
```
**事件流**Go goroutine → JNI callbackGo goroutine 线程)→ TSBridge → ViewModel → StateFlow → UI
详见 [sdk-bridge-api.md](../sdk-bridge-api.md)。
---
## 一、实施步骤索引
| 步骤 | 文档 | 主要内容 | 对应流程 | 依赖步骤 | 状态 |
| --- | --- | --- | --- | --- | --- |
| 01 | [项目基础设施](01_项目基础设施.md) | 项目结构、构建系统、依赖配置 | — | — | ✅ |
| 02 | [Bridge 层实现](02_Bridge层实现.md) | TSBridge → TsClient 桥接、事件监听 | — | 01 | ✅ |
| 03 | [服务器配置页](03_服务器配置页.md) | 连接 UI、输入验证、最近连接 | 01 连接服务器 | 02 | ⬚ |
| 04 | [连接与首次同步](04_连接与首次同步.md) | 连接流程、Identity、首次同步 | 01 + 08① | 03 | ⬚ |
| 05 | [频道列表页](05_频道列表页.md) | 频道树渲染、成员列表、未读指示 | 02 浏览频道 | 04 | ⬚ |
| 06 | [频道切换](06_频道切换.md) | 频道切换流程、密码弹窗、ClientMove | 03 切换频道 | 05 | ⬚ |
| 07 | [聊天页](07_聊天页.md) | 消息列表、发送消息、消息归档 | 04 文本消息 | 06 | ⬚ |
| 08 | [语音通信](08_语音通信.md) | PTT 按钮、Opus 编码、语音发送/接收 | 05 语音通信 | 06 | ⬚ |
| 09 | [断开连接](09_断开连接.md) | 主动断开、被动断开、被踢处理 | 07 断开连接 | 08 | ⬚ |
| 10 | [状态同步进阶](10_状态同步进阶.md) | 增量同步、补偿同步、重连全量同步 | 08 状态同步 ②③⑥ | 09 | ⬚ |
| 11 | [卡片与全局交互](11_卡片与全局交互.md) | 服务器详情卡、频道详情卡、语音卡、Poke | UI架构 三、四 | 10 | ⬚ |
| 12 | [主题与收尾](12_主题与收尾.md) | 暗色主题、边缘情况、稳定性 | — | 11 | ⬚ |
| 13 | [EventBus 架构](../流程/09_EventBus架构.md) | TS 事件与渲染线程分离、事件合并/节流 | — | 02 | ⬚ |
---
## 二、实施原则
1. **先跑通最小闭环**:连接 → 同步 → 显示频道 → 切换频道 → 发消息 → 断开
2. **每步可验证**:每个步骤完成后应能在真机或模拟器上运行并验证核心功能
3. **Bridge 层已完成**Go ↔ Kotlin 通信已通过 `TsClient` 封装,后续步骤直接调用
4. **状态管理清晰**:严格遵循流程文档中的状态树和事件依赖
5. **UI 后于逻辑**:先确保数据流正确,再打磨 UI 细节
---
## 三、技术栈确认
| 层级 | 技术 | 说明 |
| --- | --- | --- |
| 协议层 | Go + teamspeak-go | 编译为 AAR,通过 gomobile 绑定 |
| Kotlin 封装层 | TSBridge (单例) | 直接包装 gomobile TSClientJSON 传递复杂数据 |
| 桥接层 | TSBridge (单例) | 直接包装 gomobile TSClientJNI 回调转 EventBus 事件 |
| 事件总线 | EventBus (单例) | 事件收集、合并、节流,TS 线程与渲染线程分离 |
| UI 层 | Kotlin + Jetpack Compose | Material Design 3 主题 |
| 状态管理 | ViewModel + StateFlow | 单向数据流,通过 EventBus 接收 TS 事件 |
| 音频 | Opus 编解码 | Android MediaCodec 或第三方库 |
| 网络 | UDP (SDK) + TCP (文件传输) | SDK 内部处理 |
---
## 四、文件结构预期
```
android/app/src/main/java/com/tsmobile/app/
├── MainActivity.kt # 入口
├── TSBridge.kt # 应用层桥接(直接包装 gomobile TSClient
├── EventBus.kt # 事件总线(TS 事件收集、合并、分发)
├── data/ # 数据模型
│ ├── Models.kt # 频道、成员、消息等数据类
│ └── Repository.kt # 状态仓库
├── voice/ # 语音服务
│ ├── VoiceService.kt # 音频管线(采集、编码、解码、播放)
│ ├── OpusEncoder.kt # Opus 编码器
│ └── OpusDecoder.kt # Opus 解码器
├── ui/
│ ├── theme/ # Material 3 主题
│ ├── components/ # 可复用组件
│ └── screens/
│ ├── ServerConfigScreen.kt
│ ├── ChannelListScreen.kt
│ └── ChatScreen.kt
└── viewmodel/
├── ServerViewModel.kt # 连接生命周期(监听 Connected/Disconnected/Kicked
├── ChannelViewModel.kt # 频道列表(监听 ClientEnter/Leave/Moveddebounce 刷新)
├── ChatViewModel.kt # 消息归档(监听 TextMessage
└── VoiceViewModel.kt # 语音控制(VoiceService 直接处理,不经 EventBus
```
---
## 五、风险与注意事项
1. **gomobile 限制已解决**`TSBridge.kt` 直接包装 gomobile 导出的 `TSClient`,通过 JSON 字符串传递复杂数据
2. **线程安全**Go JNI 回调在 Go goroutine 线程上执行(非 Android 主线程),通过 `EventBus.emit()` 统一投递,ViewModel 在 `Dispatchers.Main` 上消费事件
3. **事件合并**:高频成员变化事件(ClientEnter/Leave/Moved)通过 debounce 合并,避免事件风暴导致频繁 refreshClientList
4. **Opus 编解码**SDK 不内置,需应用层集成(`voice/OpusEncoder.kt``voice/OpusDecoder.kt`
5. **语音延迟敏感**VoiceData 不经过 EventBus,由 VoiceService 在 Dispatchers.IO 上直接处理
6. **文件传输**:本文档范围暂不实现(见流程 06 说明)
7. **Identity 管理**:首次生成后需持久化存储
8. **TSBridge 是全局单例**:同一时间只能有一个活跃连接
@@ -0,0 +1,248 @@
# 步骤 01:项目基础设施
> 搭建项目骨架、构建系统、依赖配置,确保能编译运行空白应用。
---
## 一、目标
- [x] 建立 Android 项目基本结构
- [x] 配置 Go + gomobile 构建流程
- [x] 集成 teamspeak-go SDK
- [x] 确保能编译生成空白 APK
---
## 二、任务清单
### 2.1 Android 项目结构
**根目录**`android/`(在 IDE 中打开此目录,非仓库根目录)
```
android/
├── build.gradle.kts # 根构建脚本(插件声明)
├── settings.gradle.kts # 项目设置(仓库、模块)
├── gradle.properties # Gradle 属性
├── gradlew / gradlew.bat # Gradle Wrapper
└── app/
├── build.gradle.kts # 应用构建脚本(依赖、SDK 版本)
├── libs/ # gomobile AAR 产物存放处
│ └── teamspeak.aar # Go 编译产物(git ignore
└── src/main/
├── AndroidManifest.xml # 清单文件
└── java/com/tsmobile/app/
├── MainActivity.kt # 入口 Activity
├── TSBridge.kt # Go 桥接封装
└── voice/ # 语音模块(后续步骤扩展)
├── OpusEncoder.kt
├── OpusDecoder.kt
└── VoiceService.kt
```
**关键配置项**
| 配置 | 值 | 说明 |
| --- | --- | --- |
| `namespace` | `com.tsmobile.app` | 包名 |
| `compileSdk` | 35 | Android 15 |
| `minSdk` | 26 | Android 8.0gomobile 要求最低 API 26 |
| `targetSdk` | 35 | 目标 Android 15 |
| `jvmTarget` | 17 | Java 17 |
| `compose` | true | 启用 Jetpack Compose |
**AndroidManifest.xml 权限声明**
```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
```
- `INTERNET` / `ACCESS_NETWORK_STATE`:连接 TeamSpeak 服务器
- `RECORD_AUDIO`:语音功能(运行时动态申请)
---
### 2.2 Go 模块配置
**目录**`go/`
```
go/
├── go.mod # Go 模块定义
├── go.sum # 依赖校验
├── teamspeak/ # gomobile 导出包(bridge.go 所在)
└── _patches/ # 上游补丁(不可删除)
└── github.com/honeybbq/teamspeak-go/
```
**go.mod 关键内容**
```go
module tsmobile
go 1.26.0
require github.com/honeybbq/teamspeak-go v0.2.0
// 本地补丁替换(必须保留)
replace github.com/honeybbq/teamspeak-go => ./_patches/github.com/honeybbq/teamspeak-go
```
**gomobile 工具声明**go.mod 中):
```go
tool golang.org/x/mobile/cmd/gobind
```
**关键依赖**
| 依赖 | 用途 |
| --- | --- |
| `github.com/honeybbq/teamspeak-go` | TeamSpeak 协议实现 |
| `golang.org/x/mobile` | gomobile 工具链 |
| `golang.org/x/crypto` | 加密支持 |
**本地补丁说明**
`go/_patches/github.com/honeybbq/teamspeak-go/` 包含修改后的上游代码:
- 修复 32 位整数溢出问题(`math.MaxUint32` → 平台相关限制)
- 通过 `go.mod``replace` 指令应用
> ⚠️ **不可删除**此目录或移除 replace 指令,否则编译或运行时会出错。
---
### 2.3 构建脚本
项目提供两个构建脚本,位于仓库根目录:
| 脚本 | 平台 | 说明 |
| --- | --- | --- |
| `build.bat` | Windows | 批处理脚本 |
| `build.sh` | Linux/macOS | Shell 脚本 |
**构建流程分 4 步**
```
[1/4] 检查依赖 → [2/4] 下载 Go 依赖 → [3/4] Go → AAR → [4/4] Android → APK
```
**Step 1:检查依赖**
- 检查 `go` 命令是否可用
- 检查 `gomobile` 是否安装(不存在则自动安装并 init)
- 检查 `ANDROID_HOME` 环境变量
**Step 2:下载 Go 依赖**
```bash
cd go && go mod tidy
```
**Step 3Go → AAR**(核心步骤)
```bash
# Windows 需先设置编码
set JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF-8 -Dsun.jnu.encoding=UTF-8
gomobile bind \
-target=android \
-androidapi=26 \
-ldflags="-linkmode=external -extldflags=-Wl,--hash-style=both" \
-o android/app/libs/teamspeak.aar \
./teamspeak
```
**必须的 ldflags**
- `-linkmode=external`:使用 NDK 外部链接器,防止 Go 运行时与 Android 信号处理冲突导致 SIGSEGV
- `-extldflags=-Wl,--hash-style=both`:生成兼容的 ELF 哈希表,防止 `dlopen failed: empty/missing DT_HASH`
**Step 4Android → APK**
```bash
cd android && ./gradlew assembleDebug
```
**输出**`android/app/build/outputs/apk/debug/app-debug.apk`
---
### 2.4 依赖管理
#### Kotlin/Android 依赖(app/build.gradle.kts
**Compose 相关**
| 依赖 | 版本 | 用途 |
| --- | --- | --- |
| `compose-bom` | 2024.12.01 | Compose 版本目录 |
| `material3` | BOM 管理 | Material Design 3 |
| `material-icons-extended` | BOM 管理 | 扩展图标库 |
| `ui-tooling` | BOM 管理 | 调试工具 |
**架构组件**
| 依赖 | 版本 | 用途 |
| --- | --- | --- |
| `activity-compose` | 1.9.3 | Compose Activity 集成 |
| `navigation-compose` | 2.8.5 | 导航框架 |
| `lifecycle-runtime-compose` | 2.8.7 | 生命周期感知 |
| `lifecycle-viewmodel-compose` | 2.8.7 | ViewModel 集成 |
**工具库**
| 依赖 | 版本 | 用途 |
| --- | --- | --- |
| `datastore-preferences` | 1.1.1 | 持久化键值存储(替代 SharedPreferences |
| `kotlinx-coroutines-android` | 1.9.0 | 协程支持 |
| `kotlinx-serialization-json` | 1.7.3 | JSON 序列化 |
**gomobile AAR 引入方式**
```kotlin
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.aar"))))
```
`teamspeak.aar` 放入 `app/libs/` 目录即可自动引入。
#### Gradle 插件(根 build.gradle.kts
| 插件 | 版本 | 用途 |
| --- | --- | --- |
| `com.android.application` | 8.7.3 | Android 构建 |
| `org.jetbrains.kotlin.android` | 2.1.0 | Kotlin Android 支持 |
| `org.jetbrains.kotlin.plugin.compose` | 2.1.0 | Compose 编译器插件 |
| `org.jetbrains.kotlin.plugin.serialization` | 2.1.0 | 序列化插件 |
---
## 三、验收标准
| # | 验证项 | 验证方法 |
| --- | --- | --- |
| 1 | Go 模块可正常编译 | `cd go && go build ./teamspeak` 无报错 |
| 2 | gomobile 生成 AAR | 运行 `build.bat` / `build.sh` 第 3 步,`app/libs/teamspeak.aar` 存在且大小 > 0 |
| 3 | Android 项目可编译 | `cd android && gradlew.bat assembleDebug` 成功 |
| 4 | 空白 APK 可安装 | 安装 `app-debug.apk` 到设备/模拟器,启动无崩溃 |
| 5 | TSBridge 可调用 | 在 MainActivity 中添加 `TSBridge.isConnected()` 调用,编译通过 |
---
## 四、已完成清单
| 项目 | 状态 | 文件 |
| --- | --- | --- |
| Android 项目结构 | ✅ | `android/` 目录 |
| Gradle 构建配置 | ✅ | `android/build.gradle.kts`, `android/app/build.gradle.kts` |
| AndroidManifest | ✅ | `android/app/src/main/AndroidManifest.xml` |
| Go 模块配置 | ✅ | `go/go.mod` |
| 本地补丁 | ✅ | `go/_patches/` |
| 构建脚本 | ✅ | `build.bat`, `build.sh` |
| TSBridge 封装 | ✅ | `android/app/src/main/java/com/tsmobile/app/TSBridge.kt` |
| VoiceService 骨架 | ✅ | `android/app/src/main/java/com/tsmobile/app/voice/` |
---
## 五、参考文档
- `CLAUDE.md` — 构建命令、关键 flags 说明
- `docs/sdk文档-go.md` — SDK 依赖与 API
- `docs/UI架构设计.md` — 整体架构设计
+424
View File
@@ -0,0 +1,424 @@
# 步骤 02:Bridge 层实现(✅ 已完成)
> 实现 Go ↔ Kotlin 桥接层,包括 Go 侧 TSClient 导出、Kotlin 友好封装(TsClient.kt + TsModels.kt)、应用层桥接(TSBridge.kt)。
---
## 一、目标
- [x] Go 侧 TSClient 结构体及方法导出(`go/teamspeak/bridge.go`
- [x] gomobile 编译为 AAR`android/app/libs/teamspeak.aar`
- [x] Kotlin 友好封装层(`TsClient.kt` + `TsModels.kt`
- [x] 应用层桥接(`TSBridge.kt`
---
## 二、架构总览
```
┌─────────────────────────────────────────────────────────────┐
│ Kotlin 应用层 │
│ │
│ ViewModel ──→ TSBridge (object) ──→ TsClient (object) │
│ │ │ │
│ │ TsListener 回调 │ Kotlin 友好 API │
│ ↑ │ │
│ └── TsListener ─────────┘ │
│ │
├─────────────────────────────────────────────────────────────┤
│ gomobile 自动生成层 │
│ │
│ teamspeak.TSClient (Java) ← Go TSClient struct │
│ teamspeak.EventCallback (Java) ← Go EventCallback interface│
│ teamspeak.* 数据类 (Java) ← Go 导出结构体 │
│ │
├─────────────────────────────────────────────────────────────┤
│ Go 层 │
│ │
│ bridge.go (TSClient + EventCallback) ──→ teamspeak-go SDK │
│ │ │ │
│ │ 事件队列 + 单消费者 goroutine │ On* 回调 │
│ └──→ JNI 回调 ──→ EventCallback │ │
│ │
└─────────────────────────────────────────────────────────────┘
```
**数据流**
| 方向 | 路径 | 说明 |
| --- | --- | --- |
| Kotlin → Go | `TSBridge``TsClient` → gomobile `TSClient` → Go `Client` | 用户操作 |
| Go → Kotlin | Go `On*` → 事件队列 → JNI → `EventCallback``TsClient` 转换 → `TsListener``TSBridge` | 事件推送 |
---
## 三、三层架构详解
### 3.1 Go 层(bridge.go
**文件**`go/teamspeak/bridge.go`
Go 侧 Bridge 是 gomobile 导出的核心,将 teamspeak-go SDK 封装为可供 Kotlin 调用的 `TSClient` 类。
#### 导出的接口与结构
```go
// EventCallback — gomobile 导出的回调接口
type EventCallback interface {
OnConnected()
OnDisconnected(message string)
OnTextMessage(msg *TextMsg)
OnClientEnter(client *ServerClientView)
OnClientLeave(client *ServerClientView)
OnClientMoved(client *ClientMoved)
OnKicked(reason *ServerError)
OnTalkStatusChanged(talker *TalkStatusChange)
OnClientIDsDone()
OnServerError(error *ServerError)
}
// TSClient — gomobile 导出的桥接客户端
type TSClient struct {
client *teamspeak.Client
callback EventCallback
}
// 导出的数据结构(适配 gomobile 限制)
type ServerClientView struct { ... } // 频道成员视图
type ClientInfo struct { ... } // 完整客户端信息
type ChannelListItem struct { ... } // 频道列表项
type TextMsg struct { ... } // 文本消息
type ClientMoved struct { ... } // 客户端移动事件
type ServerError struct { ... } // 服务器错误
type TalkStatusChange struct { ... } // 说话状态变化
type ChannelListResult struct { ... } // 频道列表结果(含数组)
```
#### 关键设计决策
1. **字符串传递 ID**gomobile 不支持 `uint64` → Kotlin Long 的安全映射,统一用 `string`
2. **结构体包装**gomobile 不支持 `[]*T`,用 `ChannelListResult` 包装 `ChannelListItem[]`
3. **错误用字符串**gomobile 不支持 `error` 返回值,用空串=成功
4. **事件队列**SDK 内部 `evtQueue` + 单消费者 goroutine 串行分发,JNI 回调线程安全
### 3.2 Kotlin 友好封装层(TsClient.kt + TsModels.kt
**文件**`android/app/src/main/java/com/tsmobile/app/TsClient.kt``TsModels.kt`
这一层将 gomobile 生成的 Java 对象转为 Kotlin 友好接口,解决:
- 所有 API 为 getter/setter 而非属性
- `ChannelListItem[]` 需要手动转 `List<TsChannel>`
- 事件回调参数是 `Object` 类型需要强转
- group 类型是 `Int` 需要映射为 `ChanGroupType` 枚举
#### TsClient 对象
```kotlin
object TsClient {
// 连接
fun connect(identity, host, nickname, password, defaultChannel): Boolean
fun disconnect()
// 事件监听
fun setListener(listener: TsListener?)
// 查询(返回 Kotlin 友好类型)
fun getChannelList(): List<TsChannel>
fun getClientList(): List<TsClientInfo>
fun getClientId(): Long
fun getClientInfo(clientId: Long): TsClientInfo?
fun getChannelInfo(channelId: Long): TsChannel?
fun getSelf(): TsSelf
fun getChannelIdsByUid(uid: String, maxDepth: Int): List<Long>
// 属性
val serverVersion: String
val serverIp: String
val serverPlatform: String
val serverName: String
val serverCreated: Long
val serverUptime: Long
val maxClients: Int
val clientsOnline: Int
val channelsOnline: Int
// 操作
fun sendTextMessage(targetMode: Int, targetId: Long, msg: String): Boolean
fun clientMove(clientId: Long, channelId: Long, password: String): Boolean
fun clientPoke(clientId: Long, msg: String): Boolean
fun kickClient(clientId: Long, reasonId: Int, reasonMsg: String): Boolean
fun banClient(uid: String, timeInSeconds: Long, reasonMsg: String): Boolean
fun channelCreate(name: String, properties: Map<String, String>, permissions: List<TSPermission>): Long
fun channelUpdate(channelId: Long, properties: Map<String, String>): Boolean
fun channelDelete(channelId: Long, force: Boolean): Boolean
fun sendVoice(clientId: Long, codec: Int, data: ByteArray): Boolean
}
```
#### TsListener 接口
```kotlin
interface TsListener {
fun onConnected()
fun onDisconnected(error: String?)
fun onClientEnter(client: TsClientInfo)
fun onClientMoved(moved: TsClientMoved)
fun onClientLeave(client: ServerClientView)
fun onTalkStatusChanged(talker: TsTalker)
fun onClientIDsDone()
fun onTextMessage(msg: TsTextMessage)
fun onPoked(msg: TsTextMessage)
fun onKicked(reason: ServerError?)
fun onServerError(error: ServerError)
fun onChannelListChanged()
}
```
#### TsModels 数据类
```kotlin
// 频道
data class TsChannel(val channelListItem: ChannelListItem) {
val channelId get() = channelListItem.getChannelID()
val parentId get() = channelListItem.getParentChannelID()
val name get() = channelListItem.getName()
val order get() = channelListItem.getOrder()
val isPermanent get() = channelListItem.getIsPermanent()
val totalClients get() = channelListItem.getTotalClients()
// ... 更多属性
}
// 客户端
data class TsClientInfo(val serverClientView: ServerClientView) {
val clientId get() = serverClientView.getID()
val channelId get() = serverClientView.getChannelID()
val nickname get() = serverClientView.getNickname()
val uid get() = serverClientView.getUid()
val isTalker get() = serverClientView.getIsTalker()
// ... 更多属性
}
// 自身信息(可写)
class TsSelf internal constructor(
private val view: ServerClientView,
private val info: ClientInfo?
) {
var nickname
get() = view.getNickname()
set(value) { info?.setNickname(value) }
var isTalker
get() = view.getIsTalker()
set(value) { info?.setIsTalker(value) }
var inputMuted
get() = info?.getInputMuted() ?: false
set(value) { info?.setInputMuted(value) }
var outputMuted
get() = info?.getOutputMuted() ?: false
set(value) { info?.setOutputMuted(value) }
// ... 更多可写属性
}
// 移动事件
data class TsClientMoved(
val theClient: ServerClientView?,
val oldChannel: ChannelListItem?,
val newChannel: ChannelListItem?,
val visibility: Int
)
// 说话状态
data class TsTalker(
val client: ServerClientView?,
val isTalking: Boolean
)
// 文本消息
data class TsTextMessage(
val message: String,
val invokerUid: String,
val invokerName: String,
val invokerId: Long,
val targetMode: Int,
val targetClientId: Long,
val targetChannelId: Long
)
// 频道组/服务器组类型
enum class ChanGroupType(val value: Int) { ... }
enum class ChannelGroupType(val value: Int) { ... }
```
### 3.3 应用层桥接(TSBridge.kt
**文件**`android/app/src/main/java/com/tsmobile/app/TSBridge.kt`
TSBridge 是 ViewModel 层访问 Go 桥接的唯一入口,采用 `object` 单例模式。
#### 核心职责
1. **连接管理**:封装 `TsClient.connect()` / `disconnect()`
2. **监听注册**:在 `connect()` 时自动设置 `TsListener`
3. **查询转发**:所有查询方法委托给 `TsClient`
4. **操作转发**:所有操作方法委托给 `TsClient`
#### 完整 API
```kotlin
object TSBridge {
// === 连接管理 ===
fun connect(identity: Any, host: String, nickname: String,
password: String = "", defaultChannel: String = "",
listener: TSBridgeListener? = null): Boolean
fun disconnect()
// === 查询 ===
fun getChannelList(): List<TsChannel>
fun getClientList(): List<TsClientInfo>
fun getClientId(): Long
fun getSelf(): TsSelf
fun getChannelInfo(channelId: Long): TsChannel?
fun getClientInfo(clientId: Long): TsClientInfo?
fun getChannelIdsByUid(uid: String): List<Long>
// === 操作 ===
fun sendTextMessage(targetMode: Int, targetId: Long, msg: String): Boolean
fun clientMove(clientId: Long, channelId: Long, password: String = ""): Boolean
fun clientPoke(clientId: Long, msg: String): Boolean
fun kickClient(clientId: Long, reasonId: Int, reasonMsg: String): Boolean
fun banClient(uid: String, timeInSeconds: Long, reasonMsg: String): Boolean
fun channelCreate(name: String, properties: Map<String, String> = emptyMap(),
permissions: List<TSPermission> = emptyList()): Long
fun channelUpdate(channelId: Long, properties: Map<String, String>): Boolean
fun channelDelete(channelId: Long, force: Boolean = false): Boolean
fun sendVoice(clientId: Long, codec: Int, data: ByteArray): Boolean
// === 服务器属性 ===
val serverVersion: String
val serverIp: String
val serverPlatform: String
val serverName: String
// ...
}
// 回调接口(简化版,供 ViewModel 使用)
interface TSBridgeListener {
fun onConnected()
fun onDisconnected(error: String?)
fun onClientEnter(client: TsClientInfo)
fun onClientMoved(moved: TsClientMoved)
fun onClientLeave(client: ServerClientView)
fun onTalkStatusChanged(talker: TsTalker)
fun onClientIDsDone()
fun onTextMessage(msg: TsTextMessage)
fun onPoked(msg: TsTextMessage)
fun onKicked(reason: ServerError?)
fun onServerError(error: ServerError)
}
```
---
## 四、数据流转详解
### 4.1 连接流程
```
ViewModel: TSBridge.connect(identity, host, nickname, password)
TSBridge: TsClient.connect(identity, host, nickname, password)
TsClient: TSClient.connect(...) // gomobile Java 对象
Go: TSClient.Connect() → NewClient → registerHandlers → Connect → WaitConnected
Go SDK: 收到 welcome → 触发 OnConnected
Go Bridge: EventCallback.OnConnected() // JNI
TsClient: listener?.onConnected() // Kotlin 友好回调
TSBridge: listener?.onConnected()
ViewModel: _state.update { it.copy(connected = true) }
```
### 4.2 查询流程
```
ViewModel: TSBridge.getChannelList()
TSBridge: TsClient.getChannelList()
TsClient: TSClient.requestChannelList() // gomobile
TsClient: result.getChannels().map { TsChannel(it) } // 转为 Kotlin 类型
TSBridge: 返回 List<TsChannel>
ViewModel: _state.update { it.copy(channels = list) }
```
### 4.3 事件推送流程
```
TeamSpeak 服务器: notifyclientmoved
Go SDK: handleNotification → evtQueue → startEventLoop
Go Bridge: EventCallback.OnClientMoved(clientMoved)
↓ JNI
TsClient: TsListener.onClientMoved(TsClientMoved(view, old, new, vis))
TSBridge: listener?.onClientMoved(moved)
ViewModel: 处理移动事件,更新状态
```
---
## 五、gomobile 约束与应对
| 约束 | 影响 | 应对方案 |
| --- | --- | --- |
| 不能导出 `[]string` | 服务器组列表无法直接传递 | `TsClientInfo` 封装为逗号分隔字符串 |
| 不能导出 `[]*T` | 频道/客户端列表无法返回切片 | `ChannelListResult` 包装 + `TsClient``List` |
| 不能导出 `map[string]string` | 属性列表无法传递 | `channelCreate`/`channelUpdate` 接受 `Map`,内部转 gomobile 类型 |
| 不能导出 `error` | 方法无法返回错误 | `Boolean` 返回值(true=成功) |
| `uint64` 映射为 `long` | 频道 ID 可能溢出 | 统一用 `string` 传递 ID |
| 回调在 JNI 线程 | 不能直接操作 UI | `TsListener` 回调 → ViewModel + StateFlow 中转 |
| 所有字段为 getter/setter | Kotlin 不友好 | `TsModels` 包装为 `val`/`var` 属性 |
---
## 六、文件清单
| 文件 | 说明 |
| --- | --- |
| `go/teamspeak/bridge.go` | Go 侧桥接,导出 TSClient + EventCallback |
| `android/app/libs/teamspeak.aar` | gomobile 编译产物 |
| `android/app/src/main/java/com/tsmobile/app/TsClient.kt` | Kotlin 友好封装(TsClient 对象) |
| `android/app/src/main/java/com/tsmobile/app/TsModels.kt` | Kotlin 数据类(TsChannel, TsClientInfo 等) |
| `android/app/src/main/java/com/tsmobile/app/TSBridge.kt` | 应用层桥接(单例) |
---
## 七、验收标准
| # | 验证项 | 验证方法 |
| --- | --- | --- |
| 1 | bridge.go 可编译 | `cd go && go build ./teamspeak` 无报错 |
| 2 | gomobile 生成 AAR | `gomobile bind ...` 成功 |
| 3 | TsClient.connect() 可调用 | 编译通过,连接测试服务器成功 |
| 4 | TsListener 回调正常 | 连接后收到 `onConnected``onClientEnter` 等 |
| 5 | 查询返回 Kotlin 类型 | `getChannelList()` 返回 `List<TsChannel>` |
| 6 | 操作方法正常 | `sendTextMessage``clientMove` 等返回 true |
| 7 | 断开连接无崩溃 | `disconnect()` 后应用正常退出 |
---
## 八、参考文档
- `docs/sdk-bridge-api.md` — TsClient API 完整参考
- `docs/流程/00_总览.md` — 运行架构、三条核心通道
- `docs/流程/01_连接服务器.md` — 连接时序、事件依赖
- `CLAUDE.md` — gomobile 限制说明、JNI 线程注意事项
@@ -0,0 +1,871 @@
# 步骤 03:服务器配置页
> 实现服务器配置页 UI,包括输入验证、连接按钮状态机、最近连接列表。
> 对应流程:01 连接服务器(初始化配置部分)
> 依赖步骤:02Bridge 层)
---
## 一、目标
- [ ] ServerConfigScreen 三段式页面布局(品牌区 / 输入区 / 最近连接)
- [ ] 输入框组件(地址、昵称、密码)
- [ ] 输入验证逻辑(必填校验、格式校验)
- [ ] 连接按钮状态机(空闲 → 连接中 → 成功/失败/超时)
- [ ] 最近连接列表(DataStore 持久化,快速连接)
- [ ] ServerViewModel 状态管理
---
## 二、任务清单
### 3.1 数据模型
**文件**`android/app/src/main/java/com/tsmobile/app/data/Models.kt`
```kotlin
import kotlinx.serialization.Serializable
/**
* 服务器连接配置。
* 用于 ViewModel 状态和最近连接列表持久化。
*/
@Serializable
data class ServerConfig(
val address: String = "", // 服务器地址(域名/IP/TSDNS
val nickname: String = "", // 昵称
val password: String = "", // 服务器密码(可选)
val defaultChannel: String = "", // 默认频道(可选)
val defaultChannelPassword: String = "", // 默认频道密码(可选)
)
/**
* 最近连接记录。
* 点击可快速连接(复用 address/nickname/password)。
*/
@Serializable
data class RecentConnection(
val address: String,
val nickname: String,
val password: String = "",
val lastConnectedAt: Long = 0L, // 最后连接时间戳(epoch ms
val lastSucceeded: Boolean = false, // 上次连接是否成功
)
```
### 3.2 最近连接存储
**文件**`android/app/src/main/java/com/tsmobile/app/data/RecentConnectionsStore.kt`
使用 Jetpack DataStore Preferences 持久化最近连接列表。
```kotlin
import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.*
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
// Context 扩展属性
private val Context.recentConnectionsDataStore: DataStore<Preferences>
by preferencesDataStore(name = "recent_connections")
class RecentConnectionsStore(private val context: Context) {
companion object {
private const val MAX_RECENT = 10
private val RECENTS_KEY = stringPreferencesKey("recents_json")
}
/**
* 观察最近连接列表(按 lastConnectedAt 倒序)。
*/
fun observeRecents(): Flow<List<RecentConnection>> {
return context.recentConnectionsDataStore.data.map { prefs ->
val json = prefs[RECENTS_KEY] ?: return@map emptyList()
try {
Json.decodeFromString<List<RecentConnection>>(json)
.sortedByDescending { it.lastConnectedAt }
} catch (_: Exception) {
emptyList()
}
}
}
/**
* 记录一次连接(成功或失败)。
* 相同 address + nickname 去重,保留最新记录。
*/
suspend fun addRecent(recent: RecentConnection) {
context.recentConnectionsDataStore.edit { prefs ->
val current = try {
Json.decodeFromString<List<RecentConnection>>(prefs[RECENTS_KEY] ?: "[]")
} catch (_: Exception) {
emptyList()
}.toMutableList()
// 去重:移除相同 address + nickname 的旧记录
current.removeAll { it.address == recent.address && it.nickname == recent.nickname }
current.add(0, recent) // 插入到头部
// 限制最多 MAX_RECENT 条
val trimmed = current.take(MAX_RECENT)
prefs[RECENTS_KEY] = Json.encodeToString(trimmed)
}
}
/**
* 删除单条记录。
*/
suspend fun removeRecent(address: String, nickname: String) {
context.recentConnectionsDataStore.edit { prefs ->
val current = try {
Json.decodeFromString<List<RecentConnection>>(prefs[RECENTS_KEY] ?: "[]")
} catch (_: Exception) {
emptyList()
}.toMutableList()
current.removeAll { it.address == address && it.nickname == nickname }
prefs[RECENTS_KEY] = Json.encodeToString(current)
}
}
/**
* 清空所有记录。
*/
suspend fun clearAll() {
context.recentConnectionsDataStore.edit { prefs ->
prefs.remove(RECENTS_KEY)
}
}
}
```
**存储方案选择**
| 方案 | 优缺点 | 结论 |
| --- | --- | --- |
| SharedPreferences | 简单,但已弃用 | ❌ |
| DataStore Preferences | 现代、协程友好、类型安全 | ✅ 采用 |
| Room DB | 过重,数据量小(最多 10 条) | ❌ |
### 3.3 页面布局
**文件**`android/app/src/main/java/com/tsmobile/app/ui/screens/ServerConfigScreen.kt`
#### 三段式结构
```
┌──────────────────────────────┐
│ 上:品牌区 │
│ [Logo] │
│ TeamSpeak Mobile │
│ 连接到你的 TeamSpeak 服务器 │
│ [🌙 主题] │ ← 右上角主题切换
├──────────────────────────────┤
│ 中:输入区 │
│ 服务器地址 │
│ ┌──────────────────────────┐│
│ │ ts.example.com ││
│ └──────────────────────────┘│
│ 昵称 │
│ ┌──────────────────────────┐│
│ │ 我的昵称 ││
│ └──────────────────────────┘│
│ 密码(可选) │
│ ┌──────────────────────────┐│
│ │ •••••• ││
│ └──────────────────────────┘│
│ ┌──────────────────────────┐│
│ │ 连接服务器 ││ ← 按钮状态见 3.5
│ └──────────────────────────┘│
├──────────────────────────────┤
│ 下:最近连接 │
│ 最近连接 │
│ ┌──────────────────────────┐│
│ │ 🟢 ts.myserver.com ││ ← 点击快速连接
│ │ MyNickname · 2小时前 ││
│ ├──────────────────────────┤│
│ │ 🔴 ts.other.com ││
│ │ Bob · 昨天 ││
│ └──────────────────────────┘│
│ [清空最近记录] │ ← 长按删除单条
└──────────────────────────────┘
```
#### Compose 结构
```kotlin
@Composable
fun ServerConfigScreen(
viewModel: ServerViewModel,
onNavigateToChannelList: () -> Unit, // 连接成功后跳转
) {
val state by viewModel.state.collectAsState()
val recents by viewModel.recents.collectAsState()
Column(modifier = Modifier.fillMaxSize()) {
// 上:品牌区
BrandSection(
onToggleTheme = { viewModel.toggleTheme() }
)
// 中:输入区
InputSection(
address = state.address,
nickname = state.nickname,
password = state.password,
onAddressChange = viewModel::updateAddress,
onNicknameChange = viewModel::updateNickname,
onPasswordChange = viewModel::updatePassword,
connectState = state.connectState,
errorMessage = state.errorMessage,
onConnect = { viewModel.connect() },
)
// 下:最近连接
RecentConnectionsSection(
recents = recents,
onConnectRecent = { recent -> viewModel.quickConnect(recent) },
onRemoveRecent = { recent -> viewModel.removeRecent(recent) },
onClearAll = { viewModel.clearRecents() },
)
}
// 连接成功后自动跳转
LaunchedEffect(state.connectState) {
if (state.connectState == ConnectState.SUCCESS) {
onNavigateToChannelList()
}
}
}
```
#### 品牌区组件
```kotlin
@Composable
private fun BrandSection(onToggleTheme: () -> Unit) {
Box(modifier = Modifier.fillMaxWidth().padding(top = 48.dp)) {
Column(
modifier = Modifier.align(Alignment.Center),
horizontalAlignment = Alignment.CenterHorizontally,
) {
// Logo(使用 drawable 资源或 placeholder
Icon(
imageVector = Icons.Default.Dns, // 临时图标
contentDescription = "TeamSpeak",
modifier = Modifier.size(72.dp),
tint = MaterialTheme.colorScheme.primary,
)
Spacer(Modifier.height(12.dp))
Text(
text = "TeamSpeak Mobile",
style = MaterialTheme.typography.headlineMedium,
fontWeight = FontWeight.Bold,
)
Text(
text = "连接到你的 TeamSpeak 服务器",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
// 主题切换按钮(右上角)
IconButton(
onClick = onToggleTheme,
modifier = Modifier.align(Alignment.TopEnd).padding(end = 8.dp),
) {
Icon(Icons.Default.DarkMode, contentDescription = "切换主题")
}
}
}
```
#### 输入区组件
```kotlin
@Composable
private fun InputSection(
address: String,
nickname: String,
password: String,
onAddressChange: (String) -> Unit,
onNicknameChange: (String) -> Unit,
onPasswordChange: (String) -> Unit,
connectState: ConnectState,
errorMessage: String?,
onConnect: () -> Unit,
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 16.dp),
) {
// 服务器地址
OutlinedTextField(
value = address,
onValueChange = onAddressChange,
label = { Text("服务器地址") },
placeholder = { Text("ts.example.com") },
singleLine = true,
isError = connectState == ConnectState.FAILED && address.isBlank(),
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
)
Spacer(Modifier.height(12.dp))
// 昵称
OutlinedTextField(
value = nickname,
onValueChange = onNicknameChange,
label = { Text("昵称") },
placeholder = { Text("我的昵称") },
singleLine = true,
isError = connectState == ConnectState.FAILED && nickname.isBlank(),
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
)
Spacer(Modifier.height(12.dp))
// 密码(可选)
OutlinedTextField(
value = password,
onValueChange = onPasswordChange,
label = { Text("密码(可选)") },
placeholder = { Text("••••••") },
singleLine = true,
visualTransformation = PasswordVisualTransformation(),
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
)
Spacer(Modifier.height(24.dp))
// 连接按钮(状态机驱动)
ConnectButton(
state = connectState,
errorMessage = errorMessage,
onClick = onConnect,
)
}
}
```
#### 最近连接组件
```kotlin
@Composable
private fun RecentConnectionsSection(
recents: List<RecentConnection>,
onConnectRecent: (RecentConnection) -> Unit,
onRemoveRecent: (RecentConnection) -> Unit,
onClearAll: () -> Unit,
) {
if (recents.isEmpty()) return
Column(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 24.dp, vertical = 8.dp),
) {
Text(
text = "最近连接",
style = MaterialTheme.typography.titleSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
Spacer(Modifier.height(8.dp))
recents.forEach { recent ->
RecentConnectionItem(
recent = recent,
onClick = { onConnectRecent(recent) },
onLongClick = { onRemoveRecent(recent) },
)
Spacer(Modifier.height(4.dp))
}
Spacer(Modifier.height(8.dp))
TextButton(
onClick = onClearAll,
modifier = Modifier.align(Alignment.CenterHorizontally),
) {
Text("清空最近记录")
}
}
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun RecentConnectionItem(
recent: RecentConnection,
onClick: () -> Unit,
onLongClick: () -> Unit,
) {
Card(
modifier = Modifier
.fillMaxWidth()
.combinedClickable(onClick = onClick, onLongClick = onLongClick),
) {
Row(
modifier = Modifier.padding(12.dp),
verticalAlignment = Alignment.CenterVertically,
) {
// 状态指示灯
Box(
modifier = Modifier
.size(8.dp)
.background(
color = if (recent.lastSucceeded)
MaterialTheme.colorScheme.primary
else
MaterialTheme.colorScheme.error,
shape = CircleShape,
),
)
Spacer(Modifier.width(12.dp))
Column {
Text(
text = recent.address,
style = MaterialTheme.typography.bodyMedium,
fontWeight = FontWeight.Medium,
)
Text(
text = "${recent.nickname} · ${formatRelativeTime(recent.lastConnectedAt)}",
style = MaterialTheme.typography.bodySmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
}
}
}
```
### 3.4 输入验证逻辑
**验证规则**(依据 UI 架构设计 2.1 节):
| 字段 | 必填 | 验证规则 | 错误提示 |
| --- | --- | --- | --- |
| 服务器地址 | 是 | 非空,格式合法(域名/IP/TSDNS) | "请输入有效的服务器地址" |
| 昵称 | 是 | 非空,满足服务器命名规则 | "请输入昵称" |
| 密码 | 否 | 仅当服务器需要密码时必填 | "该服务器需要密码"(连接时由服务端返回) |
**验证时机**:用户点击"连接"时一次性校验,不实时校验(避免打断输入流)。
```kotlin
data class ValidationErrors(
val address: String? = null,
val nickname: String? = null,
)
fun validate(config: ServerConfig): ValidationErrors {
val errors = ValidationErrors()
// 地址验证:非空 + 基本格式(包含字母或数字,含可选端口)
if (config.address.isBlank()) {
errors.copy(address = "请输入服务器地址")
} else if (!isValidServerAddress(config.address)) {
errors.copy(address = "请输入有效的服务器地址")
}
// 昵称验证:非空
if (config.nickname.isBlank()) {
errors.copy(nickname = "请输入昵称")
}
return errors
}
/**
* 服务器地址格式验证。
* 支持:域名、IP(v4/v6)、TSDNS、带端口号。
*/
private fun isValidServerAddress(address: String): Boolean {
val trimmed = address.trim()
if (trimmed.isBlank()) return false
// 允许格式:
// - example.com
// - example.com:9987
// - 192.168.1.1
// - 192.168.1.1:9987
// - [::1]:9987
// - _ts3._udp.example.com (TSDNS SRV)
val ip4Pattern = Regex("""^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(:\d+)?$""")
val domainPattern = Regex("""^[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?)*(:\d+)?$""")
val ip6Pattern = Regex("""^\[?[a-fA-F0-9:]+\]?(:\d+)?$""")
return ip4Pattern.matches(trimmed) ||
domainPattern.matches(trimmed) ||
ip6Pattern.matches(trimmed)
}
```
### 3.5 连接按钮状态机
**状态定义**(依据 UI 架构设计 5.1 节):
```kotlin
enum class ConnectState {
IDLE, // 空闲:等待用户输入并点击
CONNECTING, // 连接中:Connect + WaitConnected 进行中
SUCCESS, // 连接成功:跳转频道列表页
FAILED, // 连接失败:显示错误信息和重试
TIMEOUT, // 连接超时:显示超时提示
}
```
**按钮外观对应**
| 状态 | 按钮文本 | 样式 | 可点击 |
| --- | --- | --- | --- |
| `IDLE` | "连接服务器" | Primary Filled | ✅ |
| `CONNECTING` | "连接中..." | Outlined + loading indicator | ❌ |
| `SUCCESS` | — | 自动跳转,按钮不显示 | — |
| `FAILED` | "连接失败,点击重试" | Error container 色 | ✅ |
| `TIMEOUT` | "连接超时,点击重试" | Orange container 色 | ✅ |
**错误信息分类**
| 错误类型 | 判断方式 | 提示信息 |
| --- | --- | --- |
| 密码错误 | 含 "password" 或 "密码" | "服务器密码错误" |
| 昵称冲突 | 含 "nickname" 或 "昵称" | "昵称已被使用,请更换" |
| 网络不可达 | 含 "timeout"、"unreachable"、"network" | "无法连接到服务器,请检查网络" |
| 地址无效 | 含 "resolve"、"dns"、"lookup" | "服务器地址无法解析" |
| 服务器满 | 含 "full"、"limit" | "服务器已满" |
| 其他 | 默认 | 原始错误信息 |
```kotlin
@Composable
fun ConnectButton(
state: ConnectState,
errorMessage: String?,
onClick: () -> Unit,
) {
Button(
onClick = onClick,
enabled = state != ConnectState.CONNECTING,
modifier = Modifier.fillMaxWidth().height(48.dp),
colors = when (state) {
ConnectState.FAILED -> ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.errorContainer,
contentColor = MaterialTheme.colorScheme.onErrorContainer,
)
ConnectState.TIMEOUT -> ButtonDefaults.buttonColors(
containerColor = Color(0xFFFFF3E0), // 橙色背景
contentColor = Color(0xFFE65100),
)
else -> ButtonDefaults.buttonColors()
},
) {
when (state) {
ConnectState.IDLE -> Text("连接服务器")
ConnectState.CONNECTING -> {
CircularProgressIndicator(
modifier = Modifier.size(20.dp),
strokeWidth = 2.dp,
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f),
)
Spacer(Modifier.width(8.dp))
Text("连接中...")
}
ConnectState.SUCCESS -> { /* 不会到达,自动跳转 */ }
ConnectState.FAILED -> {
Text(errorMessage ?: "连接失败,点击重试")
}
ConnectState.TIMEOUT -> Text("连接超时,点击重试")
}
}
}
```
### 3.6 ViewModel 状态管理
**文件**`android/app/src/main/java/com/tsmobile/app/viewmodel/ServerViewModel.kt`
```kotlin
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
data class ServerScreenState(
val address: String = "",
val nickname: String = "",
val password: String = "",
val connectState: ConnectState = ConnectState.IDLE,
val errorMessage: String? = null,
val validationErrors: ValidationErrors = ValidationErrors(),
)
class ServerViewModel(application: Application) : AndroidViewModel(application) {
private val recentStore = RecentConnectionsStore(application)
// 页面状态
private val _state = MutableStateFlow(ServerScreenState())
val state: StateFlow<ServerScreenState> = _state.asStateFlow()
// 最近连接列表
val recents: StateFlow<List<RecentConnection>> =
recentStore.observeRecents()
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList())
// --- 输入更新 ---
fun updateAddress(value: String) {
_state.update { it.copy(address = value, errorMessage = null) }
}
fun updateNickname(value: String) {
_state.update { it.copy(nickname = value, errorMessage = null) }
}
fun updatePassword(value: String) {
_state.update { it.copy(password = value) }
}
// --- 连接 ---
fun connect() {
val current = _state.value
if (current.connectState == ConnectState.CONNECTING) return
// 输入验证
val config = ServerConfig(
address = current.address.trim(),
nickname = current.nickname.trim(),
password = current.password,
)
val errors = validate(config)
if (errors.address != null || errors.nickname != null) {
_state.update { it.copy(
validationErrors = errors,
connectState = ConnectState.IDLE,
errorMessage = errors.address ?: errors.nickname,
)}
return
}
// 进入连接中状态
_state.update { it.copy(
connectState = ConnectState.CONNECTING,
errorMessage = null,
validationErrors = ValidationErrors(),
)}
// 异步连接(调用 TSBridge
viewModelScope.launch {
val result = TSBridge.connect(
host = config.address,
nickname = config.nickname,
password = config.password,
callbacks = createBridgeCallbacks(),
)
if (result.isEmpty()) {
// 连接成功(实际成功由 onConnected 回调确认)
// 此处 Connect 已成功启动,等待 WaitConnected
} else {
// 连接失败
val errorMsg = classifyError(result)
_state.update { it.copy(
connectState = ConnectState.FAILED,
errorMessage = errorMsg,
)}
// 记录到最近连接(标记失败)
recentStore.addRecent(RecentConnection(
address = config.address,
nickname = config.nickname,
password = config.password,
lastConnectedAt = System.currentTimeMillis(),
lastSucceeded = false,
))
}
}
}
/**
* 最近连接快速连接。
* 自动填充所有字段并触发连接。
*/
fun quickConnect(recent: RecentConnection) {
_state.update { it.copy(
address = recent.address,
nickname = recent.nickname,
password = recent.password,
)}
connect()
}
fun removeRecent(recent: RecentConnection) {
viewModelScope.launch {
recentStore.removeRecent(recent.address, recent.nickname)
}
}
fun clearRecents() {
viewModelScope.launch {
recentStore.clearAll()
}
}
// --- Bridge 回调 ---
private fun createBridgeCallbacks(): TSBridge.Callbacks = object : TSBridge.Callbacks {
override fun onConnected() {
_state.update { it.copy(connectState = ConnectState.SUCCESS) }
// 记录到最近连接(标记成功)
viewModelScope.launch {
recentStore.addRecent(RecentConnection(
address = _state.value.address.trim(),
nickname = _state.value.nickname.trim(),
password = _state.value.password,
lastConnectedAt = System.currentTimeMillis(),
lastSucceeded = true,
))
}
}
override fun onDisconnected(message: String) {
// 连接阶段断开视为失败
if (_state.value.connectState == ConnectState.CONNECTING) {
_state.update { it.copy(
connectState = ConnectState.FAILED,
errorMessage = classifyError(message),
)}
}
}
override fun onTextMessage(msg: TextMsg) { /* 此阶段不处理 */ }
override fun onClientEnter(client: Client) { /* 此阶段不处理 */ }
override fun onClientLeave(id: Int, reasonMsg: String) { /* 此阶段不处理 */ }
override fun onClientMoved(id: Int, targetChannelID: String) { /* 此阶段不处理 */ }
override fun onKicked(reason: String) { /* 此阶段不处理 */ }
override fun onVoiceData(clientID: Int, data: ByteArray, codec: Int) { /* 此阶段不处理 */ }
}
// --- 错误分类 ---
private fun classifyError(raw: String): String {
val lower = raw.lowercase()
return when {
"password" in lower || "密码" in lower -> "服务器密码错误"
"nickname" in lower || "昵称" in lower -> "昵称已被使用,请更换"
"timeout" in lower || "unreachable" in lower || "network" in lower ->
"无法连接到服务器,请检查网络"
"resolve" in lower || "dns" in lower || "lookup" in lower ->
"服务器地址无法解析"
"full" in lower || "limit" in lower -> "服务器已满"
else -> raw
}
}
}
```
### 3.7 相对时间格式化
```kotlin
/**
* 格式化时间戳为相对时间描述。
* 例:刚刚、5分钟前、2小时前、昨天、3天前、2024-01-15
*/
fun formatRelativeTime(timestamp: Long): String {
if (timestamp <= 0) return ""
val now = System.currentTimeMillis()
val diff = now - timestamp
return when {
diff < 60_000L -> "刚刚"
diff < 3_600_000L -> "${diff / 60_000}分钟前"
diff < 86_400_000L -> "${diff / 3_600_000}小时前"
diff < 172_800_000L -> "昨天"
diff < 604_800_000L -> "${diff / 86_400_000}天前"
else -> {
val sdf = java.text.SimpleDateFormat("yyyy-MM-dd", java.util.Locale.getDefault())
sdf.format(java.util.Date(timestamp))
}
}
}
```
---
## 三、连接流程数据流
```
用户点击 "连接服务器"
ServerViewModel.connect()
├─ validate(config)
│ ├─ 失败 → 显示验证错误,状态保持 IDLE
│ └─ 通过 ↓
├─ state → CONNECTING(按钮显示 "连接中...",禁用)
├─ TSBridge.connect(host, nickname, password, callbacks)
│ │
│ ▼
│ Go: TSClient.Connect(...)
│ │
│ ├─ 返回 ""(启动成功)→ 等待回调
│ │ ├─ callbacks.onConnected() → state → SUCCESS → 跳转频道列表页
│ │ └─ callbacks.onDisconnected(msg) → state → FAILED → 显示错误
│ │
│ └─ 返回 "error msg"(启动失败)→ state → FAILED → 显示错误
├─ 记录到 RecentConnectionsStore
│ └─ 成功:lastSucceeded = true(绿色)
│ └─ 失败:lastSucceeded = false(红色)
└─ 用户可重试(点击按钮,state 回到 IDLE → 重新走连接流程)
```
---
## 四、文件清单
| 文件 | 说明 |
| --- | --- |
| `data/Models.kt` | ServerConfig、RecentConnection 数据类 |
| `data/RecentConnectionsStore.kt` | DataStore 持久化最近连接 |
| `ui/screens/ServerConfigScreen.kt` | 页面 Composable(品牌区 + 输入区 + 最近连接) |
| `ui/components/ConnectButton.kt` | 连接按钮状态机组件 |
| `viewmodel/ServerViewModel.kt` | 状态管理、验证、连接、错误分类 |
| `ui/navigation/NavGraph.kt` | 导航路由(步骤 01 已建,此处补充配置页路由) |
---
## 五、验收标准
| # | 验证项 | 验证方法 |
| --- | --- | --- |
| 1 | 页面布局正确 | 启动应用,确认三段式布局(品牌/输入/最近连接) |
| 2 | 输入验证生效 | 地址为空点击连接 → 提示 "请输入服务器地址";昵称为空 → 提示 "请输入昵称" |
| 3 | 按钮状态机正确 | 点击连接 → 按钮变为 "连接中..." 并禁用 → 成功跳转 / 失败显示错误 |
| 4 | 错误信息分类正确 | 输入错误密码连接 → 显示 "服务器密码错误" |
| 5 | 最近连接记录 | 连接成功/失败后返回配置页,列表显示对应记录 |
| 6 | 最近连接快速连接 | 点击最近连接条目 → 自动填充并触发连接 |
| 7 | 最近连接删除 | 长按条目 → 删除;点击 "清空" → 全部清空 |
| 8 | 最多 10 条记录 | 连接超过 10 个不同服务器,列表只保留最新 10 条 |
| 9 | 状态灯颜色 | 成功的记录显示绿色,失败的显示红色 |
| 10 | 主题切换 | 点击右上角 🌙 → 主题切换,状态持久化 |
---
## 六、参考文档
- `docs/UI架构设计.md` — 2.1 服务器配置页(布局、验证规则、最近连接)
- `docs/流程/01_连接服务器.md` — 初始化配置、状态树、连接时序
- `docs/implementation/02_Bridge层实现.md` — TSBridge API 接口
@@ -0,0 +1,552 @@
# 步骤 04:连接与首次同步
> 实现完整的连接流程:Identity 管理、Connect、WaitConnected、首次同步。
---
## 一、目标
- [ ] Identity 生成与持久化
- [ ] ClientOption 组装
- [ ] 事件处理器注册
- [ ] Connect + WaitConnected 流程
- [ ] 首次同步(ListChannels + ListClients + ClientID
- [ ] 连接状态与错误处理
---
## 二、任务清单
### 4.1 Identity 管理
**目标**:实现 TeamSpeak 加密身份的生成与持久化存储。
**任务**
1. **生成 Identity**
```kotlin
// Go 侧通过 Bridge 暴露生成接口
// Kotlin 侧调用生成并获取 Identity 字符串
val identity = TSBridge.generateIdentity()
```
2. **持久化存储**
- 使用 `SharedPreferences` 或 `DataStore` 存储 Identity
- Key 建议:`ts_identity`
- 首次启动时生成,后续启动时读取
3. **读取与恢复**
```kotlin
fun loadOrCreateIdentity(context: Context): String {
val prefs = context.getSharedPreferences("ts_config", Context.MODE_PRIVATE)
return prefs.getString("ts_identity", null)
?: TSBridge.generateIdentity().also {
prefs.edit().putString("ts_identity", it).apply()
}
}
```
**注意事项**
- Identity 是客户端加密身份,必须持久化,否则每次连接会被服务器视为新用户
- 生成后不可更改,丢失需重新生成(会丢失服务器端的权限关联)
### 4.2 连接流程实现
**目标**:实现完整的连接流程,从配置组装到连接成功。
**任务**
1. **连接参数数据类**
```kotlin
data class ConnectionConfig(
val address: String, // 服务器地址(IP/域名/TSDNS
val nickname: String, // 显示昵称
val password: String? = null, // 服务器密码(可选)
val defaultChannel: String? = null, // 默认频道(可选)
val defaultChannelPassword: String? = null // 默认频道密码(可选)
)
```
2. **Bridge 层连接接口封装**
```kotlin
// TSBridge.kt 中新增
fun connect(config: ConnectionConfig): Result<Unit> {
return try {
val identity = loadOrCreateIdentity(context)
// 调用 Go 侧 NewClient + Connect
tsClient.newClient(identity, config.address, config.nickname)
if (config.password != null) {
tsClient.setServerPassword(config.password)
}
if (config.defaultChannel != null) {
tsClient.setDefaultChannel(config.defaultChannel)
if (config.defaultChannelPassword != null) {
tsClient.setDefaultChannelPassword(config.defaultChannelPassword)
}
}
tsClient.connect()
Result.success(Unit)
} catch (e: Exception) {
Result.failure(e)
}
}
```
3. **WaitConnected 实现**
```kotlin
suspend fun waitConnected(timeout: Duration = 30.seconds): Result<Unit> {
return withContext(Dispatchers.IO) {
try {
// Go 侧阻塞等待,支持 context 取消
tsClient.waitConnected(timeout.inWholeMilliseconds)
Result.success(Unit)
} catch (e: Exception) {
Result.failure(e)
}
}
}
```
4. **完整连接流程**
```kotlin
// ServerViewModel.kt
suspend fun connect(config: ConnectionConfig) {
_connectionState.value = ConnectionState.Connecting
// 1. 注册事件处理器(Connect 前必须完成)
registerEventHandlers()
// 2. 发起连接
val connectResult = TSBridge.connect(config)
if (connectResult.isFailure) {
_connectionState.value = ConnectionState.Failed(connectResult.exceptionOrNull()!!)
return
}
// 3. 等待连接就绪
val waitResult = TSBridge.waitConnected()
if (waitResult.isFailure) {
_connectionState.value = ConnectionState.Failed(waitResult.exceptionOrNull()!!)
return
}
// 4. 连接成功,等待 OnConnected 事件触发首次同步
}
```
**连接状态枚举**
```kotlin
sealed class ConnectionState {
object Disconnected : ConnectionState()
object Connecting : ConnectionState()
object Connected : ConnectionState() // WaitConnected 成功
object Syncing : ConnectionState() // 首次同步中
object Ready : ConnectionState() // 业务就绪
data class Failed(val error: Throwable) : ConnectionState()
}
```
**时序约束**
- `Connect()` 成功只表示连接流程已启动
- 发送业务命令前必须等待 `WaitConnected()` 成功
- 事件处理器必须在 `Connect()` 前注册,避免早期事件丢失
### 4.3 事件注册
**目标**:在 Connect 前注册所有必要的事件处理器,确保不遗漏早期服务端推送。
**任务**
1. **事件处理器注册(Go Bridge 侧)**
```go
// bridge.go 中暴露注册接口
func (b *Bridge) RegisterEventHandlers() {
b.client.OnConnected(func() {
b.notifyEvent("connected", nil)
})
b.client.OnDisconnected(func(err error) {
b.notifyEvent("disconnected", map[string]interface{}{
"error": err.Error(),
})
})
b.client.OnClientEnter(func(info ClientInfo) {
data, _ := json.Marshal(info)
b.notifyEvent("client_enter", string(data))
})
b.client.OnClientLeave(func(event ClientLeftViewEvent) {
data, _ := json.Marshal(event)
b.notifyEvent("client_leave", string(data))
})
b.client.OnClientMoved(func(event ClientMovedEvent) {
data, _ := json.Marshal(event)
b.notifyEvent("client_moved", string(data))
})
b.client.OnTextMessage(func(msg TextMessage) {
data, _ := json.Marshal(msg)
b.notifyEvent("text_message", string(data))
})
b.client.OnPoked(func(event PokeEvent) {
data, _ := json.Marshal(event)
b.notifyEvent("poked", string(data))
})
b.client.OnKicked(func(reason string) {
b.notifyEvent("kicked", reason)
})
}
```
2. **Kotlin 侧事件监听**
```kotlin
// TSBridge.kt
fun setEventListener(listener: (String, String) -> Unit) {
// 接收 Go 侧通过 JNI 回调的事件
eventCallback = listener
}
// ServerViewModel.kt
fun registerEventHandlers() {
TSBridge.setEventListener { event, data ->
when (event) {
"connected" -> handleConnected()
"disconnected" -> handleDisconnected(data)
"client_enter" -> handleClientEnter(data)
"client_leave" -> handleClientLeave(data)
"client_moved" -> handleClientMoved(data)
"text_message" -> handleTextMessage(data)
"poked" -> handlePoked(data)
"kicked" -> handleKicked(data)
}
}
}
```
3. **事件处理器职责**
| 事件 | 处理器 | 职责 |
|------|--------|------|
| `connected` | `handleConnected()` | 触发首次同步流程 |
| `disconnected` | `handleDisconnected()` | 清理会话状态,更新 UI |
| `client_enter` | `handleClientEnter()` | 增量同步:添加成员到基线 |
| `client_leave` | `handleClientLeave()` | 增量同步:从基线移除成员 |
| `client_moved` | `handleClientMoved()` | 增量同步:更新成员频道位置 |
| `text_message` | `handleTextMessage()` | 消息归档:按 TargetMode 存储 |
| `poked` | `handlePoked()` | 显示 Poke 通知 |
| `kicked` | `handleKicked()` | 处理踢出,清理状态 |
**注意事项**
- 事件处理器必须在 `Connect()` 之前注册
- 事件回调在 Go 的事件循环 goroutine 中串行执行,不要做耗时操作
- 需要通过事件队列串行化 JNI 回调,避免并发问题
### 4.4 首次同步逻辑
**目标**:连接成功后,建立完整的频道基线和成员基线。
**触发时机**:收到 `OnConnected` 事件后立即执行。
**任务**
1. **并行请求三个数据源**
```kotlin
// ServerViewModel.kt
private suspend fun performInitialSync() {
_connectionState.value = ConnectionState.Syncing
try {
// 并行请求频道列表、成员列表、自身 ID
val channelsDeferred = async { TSBridge.listChannels() }
val clientsDeferred = async { TSBridge.listClients() }
val selfIdDeferred = async { TSBridge.getClientId() }
val channels = channelsDeferred.await()
val clients = clientsDeferred.await()
val selfId = selfIdDeferred.await()
// 原子提交到状态仓库
repository.updateBaseline(
channels = channels,
clients = clients,
selfClientId = selfId
)
_connectionState.value = ConnectionState.Ready
} catch (e: Exception) {
_connectionState.value = ConnectionState.SyncFailed(e)
// 允许重试,不进入业务就绪
}
}
```
2. **数据模型定义**
```kotlin
// data/Models.kt
data class ChannelInfo(
val id: Long,
val parentId: Long,
val name: String,
val order: Long = 0,
val isPassword: Boolean = false,
val isPermanent: Boolean = false,
val maxClients: Int = -1
)
data class ClientInfo(
val id: Int,
val nickname: String,
val channelId: Long,
val uid: String,
val type: Int = 0,
val serverGroups: List<String> = emptyList()
)
```
3. **状态仓库实现**
```kotlin
// data/Repository.kt
class ChannelRepository {
private val _channels = MutableStateFlow<List<ChannelInfo>>(emptyList())
val channels: StateFlow<List<ChannelInfo>> = _channels
private val _clients = MutableStateFlow<List<ClientInfo>>(emptyList())
val clients: StateFlow<List<ClientInfo>> = _clients
private val _selfClientId = MutableStateFlow<Int?>(null)
val selfClientId: StateFlow<Int?> = _selfClientId
// 按频道 ID 索引的成员列表
private val _channelClients = MutableStateFlow<Map<Long, List<ClientInfo>>>(emptyMap())
val channelClients: StateFlow<Map<Long, List<ClientInfo>>> = _channelClients
fun updateBaseline(channels: List<ChannelInfo>, clients: List<ClientInfo>, selfClientId: Int) {
_channels.value = channels
_clients.value = clients
_selfClientId.value = selfClientId
// 建立频道-成员索引
_channelClients.value = clients.groupBy { it.channelId }
}
}
```
4. **Bridge 层查询**(通过 TsClient 封装)
```kotlin
// TSBridge.kt — 直接返回 Kotlin 友好类型,无需 JSON 解析
fun getChannelList(): List<TsChannel> = TsClient.getChannelList()
fun getClientList(): List<TsClientInfo> = TsClient.getClientList()
fun getClientId(): Long = TsClient.getClientId()
```
**同步状态机**
```kotlin
sealed class SyncState {
object Unsynced : SyncState() // 已连接但尚无完整数据
object Syncing : SyncState() // 调用 ListChannels 和 ListClients
object Synchronized : SyncState() // 列表基线可供 UI 使用
data class SyncFailed(val error: Throwable) : SyncState() // 同步失败
}
```
**原子提交原则**
- 频道列表、成员列表、自身 ID 必须全部成功才能提交
- 任一失败则不进入业务就绪状态
- 允许重试,避免在不完整数据上执行业务操作
### 4.5 错误处理与状态反馈
**目标**:实现完整的错误处理机制,确保用户能获得清晰的状态反馈。
**任务**
1. **连接错误分类**
```kotlin
sealed class ConnectionError : Exception() {
object InvalidAddress : ConnectionError() // 地址解析失败
object AuthenticationFailed : ConnectionError() // 密码错误
object ServerFull : ConnectionError() // 服务器满员
object Banned : ConnectionError() // 被封禁
object NetworkError : ConnectionError() // 网络问题
object Timeout : ConnectionError() // 连接超时
data class Other(val message: String) : ConnectionError()
}
```
2. **错误映射与处理**
```kotlin
fun mapConnectionError(error: Exception): ConnectionError {
val message = error.message?.lowercase() ?: ""
return when {
message.contains("resolve") || message.contains("address") ->
ConnectionError.InvalidAddress
message.contains("password") || message.contains("auth") ->
ConnectionError.AuthenticationFailed
message.contains("full") || message.contains("limit") ->
ConnectionError.ServerFull
message.contains("ban") ->
ConnectionError.Banned
message.contains("timeout") ->
ConnectionError.Timeout
message.contains("network") || message.contains("connection") ->
ConnectionError.NetworkError
else -> ConnectionError.Other(error.message ?: "Unknown error")
}
}
```
3. **状态反馈 UI**
```kotlin
@Composable
fun ConnectionStatusIndicator(state: ConnectionState) {
when (state) {
ConnectionState.Disconnected -> {
Text("未连接", color = MaterialTheme.colorScheme.onSurfaceVariant)
}
ConnectionState.Connecting -> {
CircularProgressIndicator(modifier = Modifier.size(24.dp))
Text("正在连接...")
}
ConnectionState.Connected -> {
CircularProgressIndicator(modifier = Modifier.size(24.dp))
Text("已连接,正在同步...")
}
ConnectionState.Syncing -> {
CircularProgressIndicator(modifier = Modifier.size(24.dp))
Text("正在同步数据...")
}
ConnectionState.Ready -> {
Icon(Icons.Default.CheckCircle, tint = Color.Green)
Text("就绪")
}
is ConnectionState.Failed -> {
Icon(Icons.Default.Error, tint = Color.Red)
Text("连接失败: ${state.error.getLocalizedMessage()}",
color = MaterialTheme.colorScheme.error)
Button(onClick = { /* 重试 */ }) {
Text("重试")
}
}
}
}
```
4. **同步失败重试机制**
```kotlin
// ServerViewModel.kt
private suspend fun performInitialSyncWithRetry(maxRetries: Int = 3) {
var retryCount = 0
while (retryCount < maxRetries) {
try {
performInitialSync()
return // 成功则退出
} catch (e: Exception) {
retryCount++
if (retryCount >= maxRetries) {
_connectionState.value = ConnectionState.SyncFailed(e)
return
}
// 等待后重试
delay(1000L * retryCount)
}
}
}
```
5. **断开连接清理**
```kotlin
fun disconnect() {
// 1. 停止语音(如有)
voiceViewModel.stopVoice()
// 2. 清理会话状态
repository.clearSession()
// 3. 调用 SDK 断开
TSBridge.disconnect()
// 4. 更新状态
_connectionState.value = ConnectionState.Disconnected
}
```
**错误日志记录**
```kotlin
private fun logConnectionError(error: ConnectionError) {
Log.e(TAG, "Connection error: ${error::class.simpleName}", error)
// 可选:上报到崩溃分析服务
}
```
---
## 三、验收标准
### 功能验收
- [ ] **Identity 持久化**
- 首次启动自动生成 Identity 并存储
- 后续启动读取已有 Identity,不重复生成
- 清除应用数据后能重新生成
- [ ] **连接流程**
- 输入有效地址、昵称后能成功连接服务器
- 输入错误密码时显示明确错误提示
- 连接超时时(30秒)显示超时错误
- 无网络时显示网络错误
- [ ] **首次同步**
- 连接成功后自动执行首次同步
- 频道列表正确显示(包含所有频道)
- 成员列表正确显示(包含所有在线用户)
- 自己的客户端 ID 正确识别
- [ ] **状态反馈**
- 连接过程中显示加载状态
- 同步过程中显示同步状态
- 就绪后显示就绪状态
- 错误时显示错误信息和重试按钮
- [ ] **断开连接**
- 主动断开后状态正确重置
- 被动断开(网络中断)能检测并提示
- 被踢出时显示踢出原因
### 性能验收
- [ ] 首次同步在 3 秒内完成(标准服务器,< 100 频道,< 500 用户)
- [ ] 连接建立时间 < 5 秒(正常网络环境)
### 代码质量验收
- [ ] 所有网络操作在 IO 线程执行
- [ ] 事件回调通过事件队列串行化
- [ ] 无内存泄漏(正确取消协程)
- [ ] 错误处理覆盖所有已知异常场景
### 测试用例
| 场景 | 输入 | 预期结果 |
|------|------|----------|
| 正常连接 | 有效地址、昵称、无密码 | 连接成功,频道列表显示 |
| 密码保护服务器 | 有效地址、昵称、正确密码 | 连接成功 |
| 错误密码 | 有效地址、昵称、错误密码 | 显示"密码错误"提示 |
| 无效地址 | 无效地址 | 显示"地址解析失败"提示 |
| 网络断开 | 断开网络后连接 | 显示"网络错误"提示 |
| 服务器满员 | 满员服务器 | 显示"服务器已满"提示 |
| 被封禁 | 被封禁的 UID | 显示"已被封禁"提示 |
| 连接超时 | 阻断 UDP 30 秒 | 显示"连接超时"提示 |
| 断开重连 | 断开后重新连接 | 状态正确重置,可重新连接 |
---
## 四、参考文档
- `docs/流程/01_连接服务器.md` - 完整生命周期、时序图
- `docs/流程/08_状态同步.md` - ① 首次同步
- `docs/sdk文档-go.md` - 连接管理 API
File diff suppressed because it is too large Load Diff
+711
View File
@@ -0,0 +1,711 @@
# 步骤 06:频道切换
> 实现频道切换流程:频道点击处理、密码弹窗、ClientMove 命令发送、等待 OnClientMoved 服务端确认、自身频道状态更新。
> 对应流程:`docs/流程/03_切换频道.md`
> 依赖步骤:05(频道列表页)
---
## 一、目标
- [ ] 频道点击事件处理(区分有密码/无密码频道)
- [ ] 密码输入弹窗组件
- [ ] ChannelSwitchState 状态机(idle → requesting → waitingServerEvent → idle/failed
- [ ] ClientMove 命令发送(通过 TSBridge.MoveToChannel
- [ ] 等待 OnClientMoved 服务端事实确认
- [ ] 自身频道状态更新(④ 自身状态同步)
- [ ] 错误处理与用户反馈
---
## 二、任务清单
### 6.1 频道点击处理
**目标**:在频道列表页中处理频道点击事件,区分有密码和无密码频道。
**前置条件**
- 步骤 05 的 ChannelListScreen 已实现
- ChannelRow 组件已支持点击事件
**任务**
1. **频道点击入口**
```kotlin
// ChannelListScreen.kt - ChannelTreeContent 中的 onChannelClick 回调
@Composable
fun ChannelTreeContent(
channelViewModel: ChannelViewModel,
onChannelClick: (ChannelInfo) -> Unit,
onClientClick: (ClientInfo) -> Unit,
onNavigateToChat: () -> Unit
) {
// ... 已有实现 ...
}
```
2. **频道点击逻辑(ChannelViewModel**
```kotlin
// ChannelViewModel.kt
// 密码弹窗状态
private val _showPasswordDialog = MutableStateFlow(false)
val showPasswordDialog: StateFlow<Boolean> = _showPasswordDialog
// 待切换的目标频道
private val _pendingSwitchChannel = MutableStateFlow<ChannelInfo?>(null)
val pendingSwitchChannel: StateFlow<ChannelInfo?> = _pendingSwitchChannel
/**
* 处理频道点击事件
* 对应 UI架构设计.md 频道树交互规则
*/
fun onChannelClicked(channel: ChannelInfo) {
// 如果是当前频道,忽略
if (channel.id == repository.selfChannelId.value) {
Log.d(TAG, "Already in channel ${channel.id}, ignoring click")
return
}
// 检查是否正在切换中
if (_switchState.value != ChannelSwitchState.Idle) {
Log.w(TAG, "Channel switch already in progress, ignoring click")
return
}
if (channel.isPassword) {
// 有密码频道:弹出密码输入框
_pendingSwitchChannel.value = channel
_showPasswordDialog.value = true
} else {
// 无密码频道:直接发起切换
viewModelScope.launch {
performChannelSwitch(channel.id, "")
}
}
}
```
### 6.2 密码弹窗组件
**目标**:实现频道密码输入弹窗,支持密码错误重试。
**任务**
1. **密码弹窗 Composable**
```kotlin
// ui/components/ChannelPasswordDialog.kt
@Composable
fun ChannelPasswordDialog(
channelName: String,
onConfirm: (password: String) -> Unit,
onDismiss: () -> Unit,
isError: Boolean = false,
errorMessage: String = "密码错误,请重试"
) {
var password by remember { mutableStateOf("") }
var showError by remember { mutableStateOf(isError) }
// 当 isError 变化时更新本地状态
LaunchedEffect(isError) {
showError = isError
if (isError) {
password = "" // 清空输入框
}
}
AlertDialog(
onDismissRequest = onDismiss,
title = {
Text(
text = "该频道需要密码",
style = MaterialTheme.typography.titleMedium
)
},
text = {
Column {
Text(
text = "频道:$channelName",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(modifier = Modifier.height(16.dp))
OutlinedTextField(
value = password,
onValueChange = {
password = it
showError = false
},
label = { Text("输入频道密码") },
singleLine = true,
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password),
isError = showError,
supportingText = if (showError) {
{ Text(errorMessage, color = MaterialTheme.colorScheme.error) }
} else null,
modifier = Modifier.fillMaxWidth()
)
}
},
confirmButton = {
TextButton(
onClick = { onConfirm(password) },
enabled = password.isNotEmpty()
) {
Text("进入")
}
},
dismissButton = {
TextButton(onClick = onDismiss) {
Text("取消")
}
}
)
}
```
2. **在 ChannelListScreen 中集成密码弹窗**
```kotlin
// ChannelListScreen.kt
@Composable
fun ChannelListScreen(
channelViewModel: ChannelViewModel,
serverViewModel: ServerViewModel,
voiceViewModel: VoiceViewModel,
onNavigateToChat: () -> Unit,
onNavigateToServerConfig: () -> Unit,
onOpenServerDetail: () -> Unit,
onOpenChannelDetail: (channelId: Long) -> Unit,
onOpenVoiceCard: () -> Unit
) {
val showPasswordDialog by channelViewModel.showPasswordDialog.collectAsState()
val pendingChannel by channelViewModel.pendingSwitchChannel.collectAsState()
val switchState by channelViewModel.switchState.collectAsState()
Column(modifier = Modifier.fillMaxSize()) {
// ... 已有布局 ...
}
// 密码弹窗
if (showPasswordDialog && pendingChannel != null) {
ChannelPasswordDialog(
channelName = pendingChannel!!.name,
onConfirm = { password ->
channelViewModel.confirmPasswordAndSwitch(password)
},
onDismiss = {
channelViewModel.dismissPasswordDialog()
},
isError = switchState is ChannelSwitchState.Failed,
errorMessage = (switchState as? ChannelSwitchState.Failed)?.error ?: "密码错误,请重试"
)
}
}
```
3. **密码确认与取消逻辑**
```kotlin
// ChannelViewModel.kt
/**
* 用户确认密码,发起切换
*/
fun confirmPasswordAndSwitch(password: String) {
val channel = _pendingSwitchChannel.value ?: return
_showPasswordDialog.value = false
viewModelScope.launch {
performChannelSwitch(channel.id, password)
}
}
/**
* 用户取消密码输入
*/
fun dismissPasswordDialog() {
_showPasswordDialog.value = false
_pendingSwitchChannel.value = null
_switchState.value = ChannelSwitchState.Idle
}
```
### 6.3 ChannelSwitchState 状态机
**目标**:实现频道切换的状态管理,确保命令响应与事件事实分离。
**状态定义**
```kotlin
// data/Models.kt 或 ChannelViewModel.kt
/**
* 频道切换状态机
* 对应 docs/流程/03_切换频道.md 中的状态转换
*
* 状态转换:
* Idle → Requesting:用户发起切换请求
* Requesting → WaitingServerEventClientMove 命令成功
* Requesting → FailedClientMove 命令失败
* WaitingServerEvent → Idle:收到自己的 OnClientMoved 事件
* Failed → Idle:用户重试或取消
*/
sealed class ChannelSwitchState {
/** 空闲状态,可以发起新的切换 */
object Idle : ChannelSwitchState()
/** 正在发送 ClientMove 命令 */
object Requesting : ChannelSwitchState()
/** ClientMove 命令成功,等待服务端 OnClientMoved 事件确认 */
data class WaitingServerEvent(val targetChannelId: Long) : ChannelSwitchState()
/** 切换失败(命令被拒绝或超时) */
data class Failed(val error: String) : ChannelSwitchState()
}
```
**状态机实现**
```kotlin
// ChannelViewModel.kt
// 切换状态
private val _switchState = MutableStateFlow<ChannelSwitchState>(ChannelSwitchState.Idle)
val switchState: StateFlow<ChannelSwitchState> = _switchState
// 等待服务端确认的超时 Job
private var switchTimeoutJob: Job? = null
/**
* 执行频道切换
* 对应 docs/流程/03_切换频道.md 时序图
*/
private suspend fun performChannelSwitch(targetChannelId: Long, password: String) {
Log.d(TAG, "Requesting channel switch to $targetChannelId")
// 状态改为 requesting
_switchState.value = ChannelSwitchState.Requesting
try {
// 发送 ClientMove 命令
// TSBridge.MoveToChannel 返回空串表示成功,否则返回错误信息
val error = TSBridge.moveSelfToChannel(targetChannelId.toString(), password)
if (error.isEmpty()) {
// 命令成功,等待服务端事件确认
_switchState.value = ChannelSwitchState.WaitingServerEvent(targetChannelId)
// 启动超时检测(10秒)
switchTimeoutJob?.cancel()
switchTimeoutJob = viewModelScope.launch {
delay(10_000)
// 超时:如果还在等待状态,视为失败
if (_switchState.value is ChannelSwitchState.WaitingServerEvent) {
Log.w(TAG, "Channel switch timeout waiting for server event")
_switchState.value = ChannelSwitchState.Failed("等待服务端确认超时")
}
}
Log.d(TAG, "ClientMove command accepted, waiting for server event")
} else {
// 命令被拒绝
Log.w(TAG, "ClientMove command rejected: $error")
_switchState.value = ChannelSwitchState.Failed(mapMoveError(error))
}
} catch (e: Exception) {
Log.e(TAG, "ClientMove command failed", e)
_switchState.value = ChannelSwitchState.Failed("切换失败:${e.message}")
}
}
/**
* 映射 MoveToChannel 错误信息为用户友好的提示
*/
private fun mapMoveError(error: String): String {
return when {
error.contains("password", ignoreCase = true) -> "密码错误"
error.contains("permission", ignoreCase = true) -> "权限不足"
error.contains("full", ignoreCase = true) -> "频道已满"
error.contains("banned", ignoreCase = true) -> "你已被该频道封禁"
else -> "切换失败:$error"
}
}
```
### 6.4 自身状态同步(④)
**目标**:处理自己的 OnClientMoved 事件,确认频道切换完成。
**关键原则**
- 命令响应(ClientMove nil)不等于状态已提交
- 必须等待服务端推送的 OnClientMoved 事件才能更新本地频道事实
- 通过比对 ClientID == selfID 识别自己的移动事件
**任务**
1. **处理 OnClientMoved 事件(区分自己和他人)**
```kotlin
// ChannelViewModel.kt
/**
* 处理客户端移动事件
* 对应 docs/流程/08_状态同步.md ② 增量同步 + ④ 自身状态同步
*
* @param clientId 移动的客户端 ID
* @param targetChannelId 目标频道 ID(字符串形式)
*/
fun handleClientMoved(clientId: Int, targetChannelId: Long) {
Log.d(TAG, "Client moved: $clientId -> channel $targetChannelId")
val selfId = repository.selfClientId.value
if (clientId == selfId) {
// ④ 自身状态同步:这是自己的移动事件
handleSelfMoved(targetChannelId)
} else {
// ② 增量同步:这是其他用户的移动事件
handleOtherClientMoved(clientId, targetChannelId)
}
}
/**
* 处理自己的移动事件
* 对应 docs/流程/03_切换频道.md 中等待 OnClientMoved 确认的分支
*/
private fun handleSelfMoved(targetChannelId: Long) {
val currentState = _switchState.value
// 更新自身频道事实
repository.updateSelfChannel(targetChannelId)
// 清除目标频道的未读标记
clearUnread(targetChannelId)
when (currentState) {
is ChannelSwitchState.WaitingServerEvent -> {
// 正常流程:确认切换完成
Log.d(TAG, "Channel switch confirmed by server: target=$targetChannelId")
switchTimeoutJob?.cancel()
_switchState.value = ChannelSwitchState.Idle
_pendingSwitchChannel.value = null
}
is ChannelSwitchState.Requesting -> {
// 罕见情况:事件先于命令响应到达
Log.d(TAG, "Server event arrived before command response")
switchTimeoutJob?.cancel()
_switchState.value = ChannelSwitchState.Idle
_pendingSwitchChannel.value = null
}
else -> {
// 非切换流程中的移动(例如被管理员移动)
Log.d(TAG, "Self moved by external action to channel $targetChannelId")
_switchState.value = ChannelSwitchState.Idle
}
}
}
/**
* 处理其他用户的移动事件(增量同步)
*/
private fun handleOtherClientMoved(clientId: Int, targetChannelId: Long) {
val existingClient = repository.getClientById(clientId)
if (existingClient != null) {
// 成员存在:更新频道位置
repository.updateClientChannel(clientId, targetChannelId)
} else {
// 成员不存在:触发补偿同步
Log.w(TAG, "Unknown client $clientId, triggering compensation sync")
viewModelScope.launch { compensateClientList() }
}
}
```
2. **切换超时处理**
```kotlin
// ChannelViewModel.kt
/**
* 重试频道切换(失败后)
*/
fun retryChannelSwitch() {
val channel = _pendingSwitchChannel.value ?: return
_switchState.value = ChannelSwitchState.Idle
viewModelScope.launch {
performChannelSwitch(channel.id, "")
}
}
/**
* 取消频道切换
*/
fun cancelChannelSwitch() {
switchTimeoutJob?.cancel()
_switchState.value = ChannelSwitchState.Idle
_pendingSwitchChannel.value = null
_showPasswordDialog.value = false
}
```
### 6.5 切换状态 UI 反馈
**目标**:在频道列表页显示切换状态,提供用户反馈。
**任务**
1. **切换中指示器**
```kotlin
// ui/components/SwitchingIndicator.kt
@Composable
fun ChannelSwitchingIndicator(
state: ChannelSwitchState,
onRetry: () -> Unit,
onCancel: () -> Unit
) {
when (state) {
is ChannelSwitchState.Requesting -> {
LinearProgressIndicator(
modifier = Modifier.fillMaxWidth()
)
}
is ChannelSwitchState.WaitingServerEvent -> {
LinearProgressIndicator(
modifier = Modifier.fillMaxWidth()
)
}
is ChannelSwitchState.Failed -> {
Snackbar(
action = {
TextButton(onClick = onRetry) {
Text("重试")
}
TextButton(onClick = onCancel) {
Text("取消")
}
}
) {
Text(state.error)
}
}
else -> { /* Idle: 不显示任何指示 */ }
}
}
```
2. **在 ChannelListScreen 中集成**
```kotlin
// ChannelListScreen.kt
@Composable
fun ChannelListScreen(
// ... 参数 ...
) {
val switchState by channelViewModel.switchState.collectAsState()
Column(modifier = Modifier.fillMaxSize()) {
// 头部
ChannelListHeader(/* ... */)
// 切换状态指示器
if (switchState != ChannelSwitchState.Idle) {
ChannelSwitchingIndicator(
state = switchState,
onRetry = { channelViewModel.retryChannelSwitch() },
onCancel = { channelViewModel.cancelChannelSwitch() }
)
}
// 中部:频道树
Box(modifier = Modifier.weight(1f)) {
// ... 已有实现 ...
}
// ... 其余布局 ...
}
}
```
### 6.6 事件处理器注册
**目标**:确保 ChannelViewModel 的事件处理方法被 ServerViewModel 正确调用。
**任务**
```kotlin
// ServerViewModel.kt - 在 registerEventHandlers 中添加
fun registerEventHandlers() {
TSBridge.setCallbacks(object : TSBridge.Callbacks {
// ... 已有回调 ...
override fun onClientMoved(id: Int, targetChannelID: String) {
val targetId = targetChannelID.toLongOrNull() ?: return
channelViewModel.handleClientMoved(id, targetId)
}
// ... 其他回调 ...
})
}
```
---
## 三、状态与数据流
### 3.1 频道切换状态机
```
┌──────────────────────────────────────┐
│ │
▼ │
┌─────────┐ │
│ Idle │◄───────────────────────────────┤
└────┬────┘ │
│ 用户点击频道 │
▼ │
┌─────────────┐ │
│ Requesting │ │
└──────┬──────┘ │
│ │
┌───────────┴───────────┐ │
│ │ │
▼ ▼ │
┌───────────┐ ┌──────────┐ │
│ Failed │ │ Waiting │ │
│ │ │ Server │ │
└─────┬─────┘ │ Event │ │
│ └────┬─────┘ │
│ │ │
│ ┌─────────────────┤ │
│ │ │ │
│ ▼ ▼ │
│ 超时 OnClientMoved │
│ │ (selfID match) │
│ │ │ │
└───┴─────────────────┴─────────────────────────┘
```
### 3.2 数据流向
```
用户操作 ChannelViewModel TSBridge/Go 服务端
│ │ │ │
│ 点击频道 │ │ │
├───────────────────→│ │ │
│ │ │ │
│ │ 有密码? │ │
│ ├─→ 显示密码弹窗 │ │
│ 输入密码 │ │ │
├───────────────────→│ │ │
│ │ │ │
│ │ MoveToChannel(id, pwd) │ │
│ ├──────────────────────────→│ clientmove │
│ │ ├─────────────────→│
│ │ │ │
│ │ │ 命令响应 │
│ │ │←─────────────────┤
│ │ error == "" ? │ │
│ │←──────────────────────────┤ │
│ │ │ │
│ │ 状态 → WaitingServerEvent │ │
│ │ │ │
│ │ │ notifyclientmoved│
│ │ │←─────────────────┤
│ │ OnClientMoved(selfID) │ │
│ │←──────────────────────────┤ │
│ │ │ │
│ │ 更新自身频道 │ │
│ │ 状态 → Idle │ │
│ │ │ │
```
### 3.3 命令响应与事件事实的区分
**关键原则**(对应 `docs/流程/03_切换频道.md`):
| 概念 | 含义 | 处理方式 |
|------|------|----------|
| ClientMove 返回 error | 命令被服务器拒绝 | 立即显示错误,状态 → Failed |
| ClientMove 返回 nil | 命令被服务器接受 | 状态 → WaitingServerEvent,继续等待 |
| OnClientMoved(selfID) | 服务器确认移动完成 | 更新本地频道事实,状态 → Idle |
**为什么不能用命令响应直接更新频道?**
- 命令响应只表示服务器接受了请求
- 实际移动可能因权限、密码、容量等原因被延迟拒绝
- 只有服务端推送的 `notifyclientmoved` 事件才是最终事实
---
## 四、验收标准
### 功能验收
- [ ] **无密码频道切换**
- 点击无密码频道 → 直接发送 ClientMove
- 显示切换中进度指示
- 收到 OnClientMoved 后切换完成
- 当前频道栏更新为目标频道
- [ ] **有密码频道切换**
- 点击有密码频道 → 弹出密码输入框
- 输入密码后发送 ClientMove
- 密码错误 → 显示错误提示,清空输入框,允许重试
- 点击取消 → 关闭弹窗,不发送命令
- [ ] **切换状态管理**
- 切换中禁止发起新的切换
- 切换超时(10秒)显示失败提示
- 失败后可重试或取消
- 被管理员移动时正确更新状态
- [ ] **自身状态同步**
- 只有匹配 selfID 的 OnClientMoved 才更新自身频道
- 命令响应不直接提交频道事实
- 切换完成后清除目标频道的未读标记
### 错误处理验收
| 错误场景 | 预期行为 |
|----------|----------|
| 密码错误 | 弹窗显示错误,清空输入框 |
| 频道已满 | Snackbar 提示"频道已满" |
| 权限不足 | Snackbar 提示"权限不足" |
| 网络超时 | 10秒后显示超时提示,可重试 |
| 被管理员移动 | 静默更新当前频道 |
### 性能验收
- [ ] 切换响应时间 < 100msUI 反馈)
- [ ] 服务端确认时间 < 3s(正常网络)
- [ ] 密码弹窗弹出/关闭动画流畅
### 测试用例
| 场景 | 操作 | 预期结果 |
|------|------|----------|
| 无密码切换 | 点击无密码频道 | 进度条 → 切换完成 → 当前频道更新 |
| 有密码切换 | 点击有密码频道 → 输入密码 → 点击进入 | 密码弹窗 → 进度条 → 切换完成 |
| 密码错误 | 输入错误密码 | 弹窗显示错误,清空输入框 |
| 取消密码 | 点击取消 | 弹窗关闭,无网络请求 |
| 切换超时 | 断网后切换 | 10秒后显示超时提示 |
| 重试切换 | 失败后点击重试 | 重新发送 ClientMove |
| 被管理员移动 | 管理员移动你到其他频道 | 当前频道静默更新 |
| 重复点击 | 快速点击多个频道 | 只处理第一次点击 |
| 切换中点击 | 切换进行中点击其他频道 | 忽略点击 |
---
## 五、参考文档
- `docs/流程/03_切换频道.md` - 时序图、状态机、事件依赖
- `docs/流程/08_状态同步.md` - ④ 自身状态同步
- `docs/UI架构设计.md` - 2.2 频道列表页交互、4.2 密码弹窗
- `docs/sdk文档-go.md` - ClientMove API、OnClientMoved 事件
- `docs/implementation/02_Bridge层实现.md` - MoveToChannel、onClientMoved 回调
- `docs/implementation/05_频道列表页.md` - ChannelViewModel、ChannelListScreen
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,701 @@
# 步骤 10:状态同步进阶
> 实现高级状态同步:增量同步完善、补偿同步触发、重连全量同步、同步失败处理、数据一致性校验。
> 依赖:步骤 09(断开连接)已完成,首次同步(①)已在步骤 04 实现。
---
## 一、目标
- [ ] 增量同步(②)完善 — OnClientEnter / OnClientMoved / OnClientLeave 幂等归并
- [ ] 补偿同步(③)触发机制 — 未知实体引用时自动修复基线
- [ ] 重连全量同步(⑥) — 清理旧状态 → 重新执行首次同步
- [ ] 同步失败处理(⑦) — 状态机流转、重试、降级
- [ ] 数据一致性校验 — 周期性校验与频道列表刷新
---
## 二、任务清单
### 10.1 增量同步完善
**目标**:将步骤 04 中注册的事件处理器补全为完整的幂等归并逻辑,确保成员实体表在持续事件流中保持一致。
**前置条件**
- 步骤 04 已实现首次同步(ListChannels + ListClients + ClientID
- 步骤 04 已注册 OnClientEnter / OnClientLeave / OnClientMoved 事件处理器
- `ChannelRepository` 已有 `_clients: MutableStateFlow<List<ClientInfo>>``_channelClients: MutableStateFlow<Map<Long, List<ClientInfo>>>`
**任务**
1. **成员实体表改造为 Map 结构**
将成员存储从 `List<ClientInfo>` 改为 `Map<Int, ClientInfo>`,以 ClientID 为 key 实现 O(1) 查询和幂等更新。
```kotlin
// data/Repository.kt
class ChannelRepository {
// 成员实体表:ClientID → ClientInfo
private val _clientMap = MutableStateFlow<Map<Int, ClientInfo>>(emptyMap())
val clientMap: StateFlow<Map<Int, ClientInfo>> = _clientMap
// 派生:按频道 ID 索引的成员列表(由 clientMap 自动计算)
val channelClients: StateFlow<Map<Long, List<ClientInfo>>> =
_clientMap.map { map ->
map.values.groupBy { it.channelId }
}.stateIn(scope, SharingStarted.WhileSubscribed(), emptyMap())
// 派生:成员列表(兼容旧接口)
val clients: StateFlow<List<ClientInfo>> =
_clientMap.map { it.values.toList() }
.stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
/** 首次同步:原子替换整个成员表 */
fun setClientBaseline(clients: List<ClientInfo>) {
_clientMap.value = clients.associateBy { it.id }
}
/** 增量更新:按 ID 幂等插入或覆盖 */
fun upsertClient(client: ClientInfo) {
_clientMap.update { it + (client.id to client) }
}
/** 增量更新:按 ID 幂等删除(重复删除为 no-op) */
fun removeClient(clientId: Int) {
_clientMap.update { it - clientId }
}
/** 增量更新:移动成员到目标频道 */
fun moveClient(clientId: Int, targetChannelId: Long) {
_clientMap.update { map ->
val existing = map[clientId] ?: return@update map // 不存在则 no-op
if (existing.channelId == targetChannelId) return@update map // 相同频道则 no-op
map + (clientId to existing.copy(channelId = targetChannelId))
}
}
/** 查询成员是否存在 */
fun hasClient(clientId: Int): Boolean = _clientMap.value.containsKey(clientId)
/** 查询频道是否存在 */
fun hasChannel(channelId: Long): Boolean = _channels.value.any { it.id == channelId }
/** 清理会话数据 */
fun clearSession() {
_clientMap.value = emptyMap()
_channels.value = emptyList()
_selfClientId.value = null
}
}
```
2. **OnClientEnter 归并逻辑**
```kotlin
// ChannelViewModel.kt
fun handleClientEnter(data: String) {
val client = Json.decodeFromString<ClientInfo>(data)
// 按 ID 覆盖,重复事件不会重复计数
repository.upsertClient(client)
}
```
**关键约束**
- 按 ClientInfo.ID 覆盖,**禁止**使用 `+1` 增量累加频道人数
- 频道人数由 `channelClients[channelId].size` 实时派生
- 已有基线时,进入事件覆盖旧数据;无基线时,插入新条目
3. **OnClientMoved 归并逻辑**
```kotlin
// ChannelViewModel.kt
fun handleClientMoved(data: String) {
val event = Json.decodeFromString<ClientMovedEvent>(data)
// 判断是否为自己
if (event.clientId == repository.selfClientId.value) {
repository.updateSelfChannel(event.targetChannelId)
}
// 更新成员位置
if (repository.hasClient(event.clientId)) {
repository.moveClient(event.clientId, event.targetChannelId)
} else {
// 成员不存在 → 触发补偿同步(见 10.2)
triggerClientCompensationSync()
}
}
```
**关键约束**
- 目标频道 ID 是移动后的服务器事实,直接覆盖旧的 ChannelID
- 相同目标频道视为 no-op
- 未知成员**不得**静默忽略,必须触发补偿同步
4. **OnClientLeave 归并逻辑**
```kotlin
// ChannelViewModel.kt
fun handleClientLeave(data: String) {
val event = Json.decodeFromString<ClientLeftViewEvent>(data)
if (event.isSelf) {
// 自己被踢出或离开 → 由步骤 09 处理
handleKicked(event.reasonMessage)
return
}
// 按 ID 删除,重复删除安全地保持 no-op
repository.removeClient(event.clientId)
}
```
**关键约束**
- 重复删除必须为 no-opMap.remove 天然满足)
- 不使用 `-1` 减量维护频道人数
- `IsSelf` 为 true 时走踢出/断开流程,不从成员表删除
5. **ClientMovedEvent / ClientLeftViewEvent 数据类**
```kotlin
// data/Models.kt
data class ClientMovedEvent(
val clientId: Int,
val targetChannelId: Long,
val reasonId: Int = 0,
val invokerId: Int = 0,
val invokerName: String = "",
val invokerUid: String = ""
)
data class ClientLeftViewEvent(
val clientId: Int,
val reasonId: Int = 0, // 0=正常离开, 4=频道踢, 5=服务器踢
val reasonMessage: String = "",
val isSelf: Boolean = false
)
```
### 10.2 补偿同步机制
**目标**:当增量事件引用了本地不存在的实体(ClientID 或 ChannelID),自动触发完整列表请求修复基线。
**触发条件**
| 场景 | 检测方式 | 补偿动作 |
|------|----------|----------|
| OnClientMoved 引用未知 ClientID | `!repository.hasClient(event.clientId)` | 重新调用 ListClients |
| OnClientLeave 引用未知 ClientID | `!repository.hasClient(event.clientId)` | 重新调用 ListClients(可选,删除本身是 no-op |
| 成员引用未知 ChannelID | `!repository.hasChannel(member.channelId)` | 重新调用 ListChannels |
**任务**
1. **补偿同步触发器**
```kotlin
// ChannelViewModel.kt
private var compensationSyncJob: Job? = null
/**
* 触发成员基线补偿同步。
* 使用防抖:连续多个未知实体事件只触发一次 ListClients。
*/
private fun triggerClientCompensationSync() {
compensationSyncJob?.cancel()
compensationSyncJob = viewModelScope.launch {
delay(300) // 防抖 300ms
performCompensationSync()
}
}
private suspend fun performCompensationSync() {
try {
Log.w(TAG, "Compensation sync: rebuilding client baseline")
val clients = TSBridge.listClients()
repository.setClientBaseline(clients)
Log.i(TAG, "Compensation sync completed: ${clients.size} clients")
} catch (e: Exception) {
Log.e(TAG, "Compensation sync failed", e)
// 补偿同步失败不阻塞业务,等待下次触发
}
}
```
2. **频道基线补偿同步**
```kotlin
// ChannelViewModel.kt
private fun triggerChannelCompensationSync() {
viewModelScope.launch {
try {
Log.w(TAG, "Compensation sync: rebuilding channel baseline")
val channels = TSBridge.listChannels()
repository.setChannelBaseline(channels)
Log.i(TAG, "Compensation sync completed: ${channels.size} channels")
} catch (e: Exception) {
Log.e(TAG, "Channel compensation sync failed", e)
}
}
}
```
3. **补偿同步与增量事件的协调**
```kotlin
// 在 handleClientMoved 中集成
fun handleClientMoved(data: String) {
val event = Json.decodeFromString<ClientMovedEvent>(data)
if (event.clientId == repository.selfClientId.value) {
repository.updateSelfChannel(event.targetChannelId)
}
if (repository.hasClient(event.clientId)) {
repository.moveClient(event.clientId, event.targetChannelId)
} else {
// 检测到未知成员,触发补偿同步
Log.w(TAG, "Unknown client ${event.clientId} in move event, triggering compensation")
triggerClientCompensationSync()
}
}
```
**关键约束**
- 补偿同步使用**完整列表替换**,不是增量合并
- 使用防抖避免事件风暴时重复调用 ListClients
- 补偿同步失败不阻塞业务,等待下次事件触发重试
- 补偿同步完成后,UI 通过 StateFlow 自动刷新
**时序**(对应流程文档 §六):
```
OnClientMoved(未知 ClientID)
→ 检测到不一致
→ 调用 ListClients()
→ 完整成员列表返回
→ 替换成员基线(setClientBaseline
→ UI 自动刷新
```
### 10.3 重连流程
**目标**:断开重连后,清空旧会话状态,重新执行完整首次同步,确保数据与服务器完全一致。
**触发条件**
- 网络恢复后自动重连
- 用户手动触发重连
- 被踢出后重新连接
**任务**
1. **重连状态机**
```kotlin
// ServerViewModel.kt
sealed class ReconnectState {
object Idle : ReconnectState()
object Detecting : ReconnectState() // 检测到断开
object Cleaning : ReconnectState() // 清理旧会话
object Reconnecting : ReconnectState() // 重新连接中
object Syncing : ReconnectState() // 首次同步中
object Ready : ReconnectState() // 恢复就绪
data class Failed(val error: Throwable) : ReconnectState()
}
```
2. **重连流程实现**
```kotlin
// ServerViewModel.kt
private suspend fun performReconnect(config: ConnectionConfig) {
_reconnectState.value = ReconnectState.Cleaning
// 1. 清理旧会话数据(频道、成员、Pending 全部移除)
repository.clearSession()
_connectionState.value = ConnectionState.Disconnected
// 2. 断开旧连接(确保资源释放)
try { TSBridge.disconnect() } catch (_: Exception) {}
_reconnectState.value = ReconnectState.Reconnecting
// 3. 重新执行连接流程(参见步骤 04)
registerEventHandlers()
val connectResult = TSBridge.connect(config)
if (connectResult.isFailure) {
_reconnectState.value = ReconnectState.Failed(connectResult.exceptionOrNull()!!)
return
}
val waitResult = TSBridge.waitConnected()
if (waitResult.isFailure) {
_reconnectState.value = ReconnectState.Failed(waitResult.exceptionOrNull()!!)
return
}
// 4. OnConnected 事件将自动触发首次同步(步骤 04 已实现)
_reconnectState.value = ReconnectState.Syncing
}
```
3. **断开事件处理中的重连触发**
```kotlin
// ServerViewModel.kt
fun handleDisconnected(data: String) {
val error = Json.decodeFromString<DisconnectedEvent>(data)
when {
error.isKicked -> {
// 被踢出:显示原因,不自动重连
_kickReason.value = error.reasonMessage
repository.clearSession()
_connectionState.value = ConnectionState.Disconnected
}
isAutoReconnectEnabled -> {
// 网络断开:尝试自动重连
viewModelScope.launch {
delay(RECONNECT_DELAY) // 等待网络恢复
performReconnect(lastConfig)
}
}
else -> {
// 手动断开或不自动重连
repository.clearSession()
_connectionState.value = ConnectionState.Disconnected
}
}
}
```
4. **清理会话数据的完整性**
```kotlin
// data/Repository.kt
fun clearSession() {
_clientMap.value = emptyMap()
_channels.value = emptyList()
_selfClientId.value = null
_currentChannelId.value = null
// 清除所有待确认状态
_pendingChannelMove.value = null
}
```
**关键约束**
- 重连前**必须**清空旧会话状态,防止旧成员、频道和 Pending 污染新连接
- 清理操作在连接断开后执行,避免竞态
- 重连后的首次同步复用步骤 04 的 `performInitialSync()` 逻辑
- 被踢出不自动重连,由用户决定
**时序**(对应流程文档 §七):
```
检测到断开
→ 状态改为 Cleaning
→ 清理旧会话数据(频道、成员、Pending)
→ 断开旧连接
→ 重新 Connect + WaitConnected
→ OnConnected 触发首次同步
→ ListChannels + ListClients + ClientID
→ 原子提交新基线
→ 恢复业务就绪
```
### 10.4 同步失败处理
**目标**:当 ListChannels 或 ListClients 请求失败时,正确流转同步状态,允许重试,防止在不完整数据上执行业务操作。
**任务**
1. **同步状态机完善**
```kotlin
// data/Models.kt
sealed class SyncState {
object Unsynced : SyncState() // 已连接但尚无完整数据
object Syncing : SyncState() // 调用 ListChannels 和 ListClients
object Synchronized : SyncState() // 列表基线可供 UI 使用
data class SyncFailed(val error: Throwable) : SyncState() // 同步失败
}
```
**状态流转**
```
Unsynced → Syncing → Synchronized(正常路径)
Syncing → SyncFailed → Syncing(重试路径)
Synchronized → Syncing(补偿同步或重连)
```
2. **首次同步失败处理**
```kotlin
// ServerViewModel.kt
private suspend fun performInitialSync() {
_syncState.value = SyncState.Syncing
try {
// 并行请求
val channelsDeferred = async { TSBridge.listChannels() }
val clientsDeferred = async { TSBridge.listClients() }
val selfIdDeferred = async { TSBridge.getClientId() }
val channels = channelsDeferred.await()
val clients = clientsDeferred.await()
val selfId = selfIdDeferred.await()
// 原子提交
repository.setChannelBaseline(channels)
repository.setClientBaseline(clients)
repository.setSelfClientId(selfId)
_syncState.value = SyncState.Synchronized
_connectionState.value = ConnectionState.Ready
} catch (e: Exception) {
Log.e(TAG, "Initial sync failed", e)
_syncState.value = SyncState.SyncFailed(e)
// 不进入业务就绪,允许重试
}
}
```
3. **重试机制**
```kotlin
// ServerViewModel.kt
private suspend fun performSyncWithRetry(maxRetries: Int = 3) {
var retryCount = 0
while (retryCount < maxRetries) {
performInitialSync()
if (_syncState.value is SyncState.Synchronized) {
return // 成功
}
retryCount++
if (retryCount < maxRetries) {
Log.w(TAG, "Sync retry $retryCount/$maxRetries")
delay(1000L * retryCount) // 递增延迟
}
}
Log.e(TAG, "Sync failed after $maxRetries retries")
// 保持 SyncFailed 状态,UI 显示重试按钮
}
```
4. **手动重试入口**
```kotlin
// ServerViewModel.kt
fun retrySync() {
viewModelScope.launch {
performSyncWithRetry()
}
}
```
5. **同步失败时的 UI 保护**
```kotlin
// 在业务操作前检查同步状态
fun switchChannel(channelId: Long, password: String? = null) {
if (_syncState.value !is SyncState.Synchronized) {
_error.value = "数据未同步,请等待同步完成或点击重试"
return
}
// 执行频道切换...
}
```
**关键约束**
- 任一核心请求(ListChannels / ListClients / ClientID)失败则不标记业务就绪
- 允许重试,避免在不完整数据上执行业务操作
- 同步失败期间,业务操作(切换频道、发消息等)应被阻止
- 补偿同步失败不进入 SyncFailed,仅记录日志等待下次触发
### 10.5 数据一致性
**目标**:在长期运行中,检测并修复可能的数据不一致(如频道列表过期、成员数据漂移)。
**任务**
1. **频道列表过期检测**
SDK 不提供频道创建/更新/删除事件,因此频道列表可能随时间过期。
```kotlin
// ChannelViewModel.kt
private var lastChannelRefreshTime: Long = 0
/** 检查频道列表是否需要刷新 */
private fun isChannelListStale(): Boolean {
val elapsed = System.currentTimeMillis() - lastChannelRefreshTime
return elapsed > CHANNEL_LIST_STALE_THRESHOLD // 建议 5 分钟
}
companion object {
const val CHANNEL_LIST_STALE_THRESHOLD = 5 * 60 * 1000L // 5 分钟
}
```
2. **被动刷新策略**
在用户执行关键操作时,检查并刷新过期数据:
```kotlin
// ChannelViewModel.kt
suspend fun refreshChannelsIfNeeded() {
if (isChannelListStale()) {
try {
val channels = TSBridge.listChannels()
repository.setChannelBaseline(channels)
lastChannelRefreshTime = System.currentTimeMillis()
} catch (e: Exception) {
Log.e(TAG, "Channel refresh failed", e)
// 不阻塞业务,使用旧数据
}
}
}
/** 浏览频道时刷新 */
fun onChannelListVisible() {
viewModelScope.launch { refreshChannelsIfNeeded() }
}
/** 切换频道前刷新 */
suspend fun beforeChannelSwitch() {
refreshChannelsIfNeeded()
}
```
3. **成员数据校验**
当成员引用了本地不存在的频道时,触发频道基线刷新:
```kotlin
// ChannelViewModel.kt
fun validateMemberData() {
val channels = repository.channels.value.map { it.id }.toSet()
val clients = repository.clientMap.value.values
val unknownChannelIds = clients
.map { it.channelId }
.filter { it !in channels }
.toSet()
if (unknownChannelIds.isNotEmpty()) {
Log.w(TAG, "Found clients referencing unknown channels: $unknownChannelIds")
triggerChannelCompensationSync()
}
}
```
4. **后台一致性检查(可选)**
```kotlin
// ServerViewModel.kt
private var consistencyCheckJob: Job? = null
fun startConsistencyCheck() {
consistencyCheckJob = viewModelScope.launch {
while (isActive) {
delay(CONSISTENCY_CHECK_INTERVAL)
if (_syncState.value is SyncState.Synchronized) {
channelViewModel.validateMemberData()
}
}
}
}
fun stopConsistencyCheck() {
consistencyCheckJob?.cancel()
consistencyCheckJob = null
}
companion object {
const val CONSISTENCY_CHECK_INTERVAL = 60 * 1000L // 1 分钟
}
```
**关键约束**
- `ListChannels` 是频道目录的**唯一权威来源**(SDK 无频道变更事件)
- 不能假设频道列表依靠 `On*` 事件永久保持最新
- 刷新失败时使用旧数据,不阻塞业务操作
- 一致性检查为低优先级,不影响正常事件流的实时性
---
## 三、验收标准
### 功能验收
- [ ] **增量同步**
- OnClientEnter 事件正确添加成员到基线,重复事件不重复计数
- OnClientMoved 事件正确更新成员频道位置,相同目标频道为 no-op
- OnClientLeave 事件正确删除成员,重复删除为 no-op
- 自己的移动事件正确更新自身频道位置
- 频道人数由成员实体表实时派生,不使用独立计数器
- [ ] **补偿同步**
- OnClientMoved 引用未知 ClientID 时自动触发 ListClients
- 补偿同步使用完整列表替换成员基线
- 连续多个未知实体事件只触发一次补偿同步(防抖)
- 补偿同步失败不阻塞业务
- [ ] **重连全量同步**
- 重连前清空旧会话数据(频道、成员、Pending)
- 重连后自动执行首次同步
- 同步完成后恢复业务就绪
- 被踢出不自动重连
- [ ] **同步失败处理**
- 首次同步失败进入 SyncFailed 状态
- 同步失败期间业务操作被阻止
- 提供手动重试入口
- 重试最多 3 次,递增延迟
- [ ] **数据一致性**
- 频道列表超过 5 分钟未刷新时,关键操作前自动刷新
- 成员引用未知频道时触发频道基线补偿同步
- 刷新失败时使用旧数据,不阻塞业务
### 性能验收
- [ ] 增量同步单次事件处理 < 10ms
- [ ] 补偿同步(ListClients)在 3 秒内完成
- [ ] 重连全量同步在 5 秒内完成
- [ ] 防抖机制避免事件风暴时的重复请求
### 代码质量验收
- [ ] 成员实体表操作线程安全(StateFlow + immutable Map
- [ ] 补偿同步防抖使用协程取消,无泄漏
- [ ] 所有网络操作在 IO 线程执行
- [ ] 日志覆盖关键状态转换和异常
### 测试用例
| 场景 | 操作 | 预期结果 |
|------|------|----------|
| 正常增量流 | 其他用户进入/移动/离开 | 成员表实时更新,频道人数正确 |
| 重复进入事件 | 同一用户连续两次 OnClientEnter | 成员表只有一条记录,无重复计数 |
| 未知成员移动 | OnClientMoved 引用不存在的 ClientID | 自动触发 ListClients 补偿同步 |
| 补偿同步防抖 | 连续 5 个未知实体事件 | 只触发 1 次 ListClients |
| 正常重连 | 网络断开后恢复 | 清理旧数据 → 重连 → 同步 → 就绪 |
| 被踢后重连 | 被服务器踢出后手动重连 | 显示踢出原因 → 清理 → 重连 → 同步 |
| 同步失败重试 | 首次同步网络超时 | 进入 SyncFailed → 点击重试 → 成功 |
| 同步失败阻塞 | 同步失败时切换频道 | 显示"数据未同步"提示 |
| 频道列表过期 | 5 分钟后切换频道 | 自动刷新频道列表再切换 |
| 成员引用未知频道 | 成员的 ChannelID 在本地不存在 | 触发频道基线补偿同步 |
---
## 四、参考文档
- `docs/流程/08_状态同步.md` - 完整同步机制(②③⑥⑦)
- `docs/流程/02_浏览频道.md` - 成员实体状态树、事件依赖矩阵
- `docs/sdk文档-go.md` - OnClientEnter / OnClientLeave / OnClientMoved 事件处理器、ListClients / ListChannels API
- `docs/implementation/04_连接与首次同步.md` - 首次同步实现、SyncState 状态机
- `docs/implementation/09_断开连接.md` - 断开连接清理逻辑
File diff suppressed because it is too large Load Diff
+998
View File
@@ -0,0 +1,998 @@
# 步骤 12:主题与收尾
> 实现暗色主题、边缘情况处理、稳定性优化。
> 对应设计:`docs/UI架构设计.md` - 4.4 主题切换
> 依赖步骤:11(卡片与全局交互)
---
## 一、目标
- [ ] 暗色/亮色主题切换 — 全局 Material 3 动态主题
- [ ] 主题持久化 — DataStore 保存用户选择,启动时自动应用
- [ ] 边缘情况处理 — 空状态、异常输入、极端场景覆盖
- [ ] 内存泄漏检查 — ViewModel / 协程 / 回调 / 音频资源释放
- [ ] 性能优化 — 列表滚动、重组范围、图片/动画优化
- [ ] 最终集成验证 — 全链路冒烟测试
---
## 二、任务清单
### 12.1 主题系统
**目标**:实现 Material 3 暗色/亮色主题切换,全局生效并持久化用户选择。
**对应设计**`docs/UI架构设计.md` 4.4 主题切换:
- 入口位置:服务器配置页右上角 🌙 图标
- 切换方式:点击在亮色/暗色主题间切换
- 持久化:选择保存到本地配置,下次启动自动应用
- 影响范围:全局所有页面和卡片
**任务**
1. **ThemeMode 枚举与 DataStore 持久化**
```kotlin
// ui/theme/ThemeMode.kt
enum class ThemeMode {
LIGHT, // 亮色
DARK, // 暗色
SYSTEM // 跟随系统(默认)
}
```
```kotlin
// data/ThemePreferences.kt
import android.content.Context
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.core.stringPreferencesKey
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
private val Context.dataStore by preferencesDataStore(name = "settings")
class ThemePreferences(private val context: Context) {
companion object {
private val THEME_MODE_KEY = stringPreferencesKey("theme_mode")
}
/**
* 读取主题模式(默认跟随系统)
*/
val themeMode: Flow<ThemeMode> = context.dataStore.data.map { prefs ->
when (prefs[THEME_MODE_KEY]) {
ThemeMode.LIGHT.name -> ThemeMode.LIGHT
ThemeMode.DARK.name -> ThemeMode.DARK
else -> ThemeMode.SYSTEM
}
}
/**
* 保存主题模式
*/
suspend fun setThemeMode(mode: ThemeMode) {
context.dataStore.edit { prefs ->
prefs[THEME_MODE_KEY] = mode.name
}
}
}
```
2. **ThemeViewModel — 主题状态管理**
```kotlin
// viewmodel/ThemeViewModel.kt
class ThemeViewModel(application: Application) : AndroidViewModel(application) {
private val themePreferences = ThemePreferences(application)
val themeMode: StateFlow<ThemeMode> = themePreferences.themeMode
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = ThemeMode.SYSTEM
)
/**
* 切换主题模式
*
* 对应 docs/UI架构设计.md 4.4
* "点击在亮色/暗色主题间切换"
* "选择保存到本地配置"
*/
fun toggleTheme() {
viewModelScope.launch {
val next = when (themeMode.value) {
ThemeMode.SYSTEM -> ThemeMode.LIGHT
ThemeMode.LIGHT -> ThemeMode.DARK
ThemeMode.DARK -> ThemeMode.SYSTEM
}
themePreferences.setThemeMode(next)
}
}
}
```
3. **Material 3 主题配置**
```kotlin
// ui/theme/Theme.kt
@Composable
fun TSMobileTheme(
themeMode: ThemeMode = ThemeMode.SYSTEM,
content: @Composable () -> Unit
) {
val darkTheme = when (themeMode) {
ThemeMode.LIGHT -> false
ThemeMode.DARK -> true
ThemeMode.SYSTEM -> isSystemInDarkTheme()
}
val colorScheme = if (darkTheme) {
darkColorScheme(
primary = Color(0xFF90CAF9),
onPrimary = Color(0xFF003258),
primaryContainer = Color(0xFF00497D),
onPrimaryContainer = Color(0xFFD1E4FF),
secondary = Color(0xFFBBC7DB),
onSecondary = Color(0xFF263141),
surface = Color(0xFF1A1C1E),
onSurface = Color(0xFFE3E2E6),
surfaceVariant = Color(0xFF43474E),
onSurfaceVariant = Color(0xFFC3C6CF),
error = Color(0xFFFFB4AB),
onError = Color(0xFF690005)
)
} else {
lightColorScheme(
primary = Color(0xFF1565C0),
onPrimary = Color(0xFFFFFFFF),
primaryContainer = Color(0xFFD1E4FF),
onPrimaryContainer = Color(0xFF001D36),
secondary = Color(0xFF535F70),
onSecondary = Color(0xFFFFFFFF),
surface = Color(0xFFFDFBFF),
onSurface = Color(0xFF1A1C1E),
surfaceVariant = Color(0xFFE0E3EC),
onSurfaceVariant = Color(0xFF43474E),
error = Color(0xFFBA1A1A),
onError = Color(0xFFFFFFFF)
)
}
MaterialTheme(
colorScheme = colorScheme,
typography = Typography,
content = content
)
}
```
4. **MainActivity 集成**
```kotlin
// MainActivity.kt
class MainActivity : ComponentActivity() {
private val themeViewModel: ThemeViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
val themeMode by themeViewModel.themeMode.collectAsState()
TSMobileTheme(themeMode = themeMode) {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
MainApp(
themeViewModel = themeViewModel
)
}
}
}
}
}
```
5. **服务器配置页主题切换按钮**
对应 `docs/UI架构设计.md` 2.1 布局 — 右上角主题图标:
```kotlin
// ui/screens/ServerConfigScreen.kt
@Composable
fun ServerConfigScreen(
serverViewModel: ServerViewModel,
themeViewModel: ThemeViewModel
) {
val themeMode by themeViewModel.themeMode.collectAsState()
Column(modifier = Modifier.fillMaxSize()) {
// 品牌区
Box(modifier = Modifier.fillMaxWidth()) {
// Logo + 描述
Column(
modifier = Modifier
.align(Alignment.Center)
.padding(top = 48.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
// Logo
Icon(
imageVector = Icons.Default.Headset,
contentDescription = null,
modifier = Modifier.size(64.dp),
tint = MaterialTheme.colorScheme.primary
)
Spacer(Modifier.height(12.dp))
Text(
text = "TeamSpeak Mobile",
style = MaterialTheme.typography.headlineMedium
)
Text(
text = "连接到你的 TeamSpeak 服务器",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
// 主题切换按钮(右上角)
IconButton(
onClick = { themeViewModel.toggleTheme() },
modifier = Modifier
.align(Alignment.TopEnd)
.padding(16.dp)
) {
Icon(
imageVector = when (themeMode) {
ThemeMode.LIGHT -> Icons.Default.LightMode
ThemeMode.DARK -> Icons.Default.DarkMode
ThemeMode.SYSTEM -> Icons.Default.SettingsBrightness
},
contentDescription = "切换主题",
tint = MaterialTheme.colorScheme.onSurfaceVariant
)
}
}
// ... 输入区 + 最近连接 ...
}
}
```
### 12.2 边缘情况
**目标**:覆盖各种边缘场景,确保应用在异常输入、极端数据、特殊字符等情况下不崩溃。
**任务**
1. **空状态处理**
为所有列表和数据展示区域提供空状态 UI:
```kotlin
// ui/components/EmptyStateView.kt
@Composable
fun EmptyStateView(
icon: ImageVector,
title: String,
subtitle: String = "",
actionText: String? = null,
onAction: (() -> Unit)? = null
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(32.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
Icon(
imageVector = icon,
contentDescription = null,
modifier = Modifier.size(64.dp),
tint = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f)
)
Spacer(Modifier.height(16.dp))
Text(
text = title,
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
if (subtitle.isNotEmpty()) {
Spacer(Modifier.height(8.dp))
Text(
text = subtitle,
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f)
)
}
if (actionText != null && onAction != null) {
Spacer(Modifier.height(16.dp))
TextButton(onClick = onAction) {
Text(actionText)
}
}
}
}
```
各场景空状态:
| 场景 | 图标 | 标题 | 副标题 |
|------|------|------|--------|
| 频道列表为空 | FolderOpen | 暂无频道 | 服务器没有任何频道 |
| 当前频道无成员 | PersonOutline | 频道内无人 | 你是第一个进入的 |
| 消息列表为空 | ChatBubbleOutline | 暂无消息 | 发送第一条消息吧 |
| 最近连接为空 | History | 暂无记录 | 连接服务器后会在这里显示 |
| 语音卡无人发言 | VolumeOff | 暂无发言 | — |
2. **输入验证加固**
```kotlin
// data/InputValidator.kt
object InputValidator {
/**
* 服务器地址验证
* 支持:域名、IPv4/v6)、TSDNS、带端口
*/
fun validateServerAddress(input: String): ValidationResult {
val trimmed = input.trim()
if (trimmed.isEmpty()) {
return ValidationResult(false, "请输入服务器地址")
}
// 去除协议前缀
val addr = trimmed
.removePrefix("ts3server://")
.removePrefix("ts3://")
.trimEnd('/')
// 基本格式检查:不能包含空格、必须有合法字符
if (addr.contains(' ') || addr.length > 256) {
return ValidationResult(false, "地址格式不正确")
}
// 端口检查(如果有)
val parts = addr.split(":")
if (parts.size == 2) {
val port = parts[1].toIntOrNull()
if (port == null || port !in 1..65535) {
return ValidationResult(false, "端口范围 1-65535")
}
} else if (parts.size > 2) {
// IPv6 地址 — 必须包含在 [] 中
if (!addr.startsWith("[")) {
return ValidationResult(false, "IPv6 地址需要用 [] 包裹")
}
}
return ValidationResult(true)
}
/**
* 昵称验证
*/
fun validateNickname(input: String): ValidationResult {
val trimmed = input.trim()
if (trimmed.isEmpty()) {
return ValidationResult(false, "请输入昵称")
}
if (trimmed.length > 30) {
return ValidationResult(false, "昵称最长 30 个字符")
}
// 检查非法字符(TeamSpeak 限制)
val illegalChars = listOf("\\", "/", "|", "\n", "\r", "\t")
for (ch in illegalChars) {
if (trimmed.contains(ch)) {
return ValidationResult(false, "昵称包含非法字符: '$ch'")
}
}
return ValidationResult(true)
}
/**
* 频道密码验证
*/
fun validateChannelPassword(input: String): ValidationResult {
if (input.isEmpty()) {
return ValidationResult(false, "请输入频道密码")
}
if (input.length > 100) {
return ValidationResult(false, "密码过长")
}
return ValidationResult(true)
}
/**
* 聊天消息验证
*/
fun validateMessage(input: String): ValidationResult {
val trimmed = input.trim()
if (trimmed.isEmpty()) {
return ValidationResult(false, "消息不能为空")
}
if (trimmed.length > 1024) {
return ValidationResult(false, "消息最长 1024 个字符")
}
return ValidationResult(true)
}
}
data class ValidationResult(
val isValid: Boolean,
val errorMessage: String = ""
)
```
3. **频道名/成员名特殊字符处理**
```kotlin
// ui/components/TextExtensions.kt
/**
* 安全显示频道名/成员名
* 处理:空名称、超长名称、特殊字符
*/
@Composable
fun SafeDisplayName(
name: String,
fallback: String = "未知",
maxLength: Int = 50,
style: TextStyle = MaterialTheme.typography.bodyMedium,
maxLines: Int = 1
) {
val displayName = when {
name.isBlank() -> fallback
name.length > maxLength -> name.take(maxLength) + "…"
else -> name
}
Text(
text = displayName,
style = style,
maxLines = maxLines,
overflow = TextOverflow.Ellipsis
)
}
```
4. **极端数据场景处理**
| 场景 | 处理方式 |
|------|----------|
| 频道数 > 100 | 使用 LazyColumn 虚拟化,避免一次性渲染 |
| 成员数 > 500 | LazyColumn 虚拟化 + 分页加载 |
| 消息数 > 1000 | 限制内存中保留最近 200 条,其余从归档加载 |
| 频道名为空 | 显示 "(未命名频道)" |
| 成员昵称为空 | 显示 "未知用户" |
| 消息内容为空 | 不显示该消息,记录日志 |
| 服务器返回异常 JSON | try-catch + 默认值,不崩溃 |
| SDK 方法调用超时 | 设置 5 秒超时,超时后显示错误提示 |
| 服务器满/密码错/被封禁 | 显示对应错误信息,不自动重连 |
5. **全局异常捕获**
```kotlin
// App.kt
class App : Application() {
override fun onCreate() {
super.onCreate()
// 全局未捕获异常处理
val defaultHandler = Thread.getDefaultUncaughtExceptionHandler()
Thread.setDefaultUncaughtExceptionHandler { thread, throwable ->
Log.e("App", "Uncaught exception in ${thread.name}", throwable)
// 写入崩溃日志文件(可用于后续分析)
writeCrashLog(throwable)
// 交给默认处理器(系统弹窗)
defaultHandler?.uncaughtException(thread, throwable)
}
}
private fun writeCrashLog(throwable: Throwable) {
try {
val file = File(getExternalFilesDir(null), "crash.log")
file.appendText(
buildString {
appendLine("=== ${java.util.Date()} ===")
appendLine(throwable.stackTraceToString())
appendLine()
}
)
} catch (e: Exception) {
Log.e("App", "Failed to write crash log", e)
}
}
}
```
### 12.3 稳定性优化
**目标**:确保资源正确释放、协程不泄漏、音频设备正确管理,提升应用稳定性。
**任务**
1. **ViewModel 生命周期管理**
```kotlin
// viewmodel/VoiceViewModel.kt — 资源释放示例
class VoiceViewModel : ViewModel() {
private var audioTrack: AudioTrack? = null
private var audioRecord: AudioRecord? = null
private var voiceJob: Job? = null
/**
* ViewModel 销毁时释放所有资源
*/
override fun onCleared() {
super.onCleared()
Log.d(TAG, "onCleared: releasing voice resources")
// 停止语音
stopVoice()
// 释放音频资源
audioTrack?.release()
audioTrack = null
audioRecord?.release()
audioRecord = null
// 取消协程
voiceJob?.cancel()
voiceJob = null
}
}
```
2. **TSBridge 回调生命周期管理**
```kotlin
// viewmodel/ServerViewModel.kt
class ServerViewModel : ViewModel() {
/**
* 注册回调(连接时调用)
*/
fun registerCallbacks() {
TSBridge.setCallbacks(createCallbacks())
}
/**
* 注销回调(断开时调用)
*
* 防止断开后仍然收到回调导致状态混乱
*/
fun unregisterCallbacks() {
TSBridge.setCallbacks(null)
}
override fun onCleared() {
super.onCleared()
unregisterCallbacks()
reconnectJob?.cancel()
}
}
```
3. **协程作用域安全**
```kotlin
// 所有 ViewModel 中的协程调用
// ✅ 正确:使用 viewModelScope,自动在 ViewModel 销毁时取消
fun fetchServerInfo() {
viewModelScope.launch {
try {
val json = TSBridge.getServerInfoJSON()
_serverInfo.value = Json.decodeFromString(json)
} catch (e: CancellationException) {
throw e // 不要吞掉 CancellationException
} catch (e: Exception) {
Log.e(TAG, "fetchServerInfo failed", e)
}
}
}
// ❌ 错误:使用 GlobalScope,不会随 ViewModel 销毁取消
// GlobalScope.launch { ... }
```
4. **音频设备切换与焦点管理**
```kotlin
// viewmodel/VoiceViewModel.kt
/**
* 请求音频焦点
* 进入语音频道时调用
*/
private fun requestAudioFocus() {
val audioManager = application.getSystemService(AudioManager::class.java)
val focusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
.setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build()
)
.setOnAudioFocusChangeListener { focusChange ->
when (focusChange) {
AudioManager.AUDIOFOCUS_LOSS -> {
// 永久丢失焦点 → 停止语音
stopVoice()
}
AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
// 暂时丢失 → 暂停发送
pauseTransmit()
}
AudioManager.AUDIOFOCUS_GAIN -> {
// 重新获得焦点 → 恢复
resumeTransmit()
}
}
}
.build()
audioManager.requestAudioFocus(focusRequest)
}
/**
* 释放音频焦点
* 离开语音频道时调用
*/
private fun abandonAudioFocus() {
val audioManager = application.getSystemService(AudioManager::class.java)
audioManager.abandonAudioFocusRequest(focusRequest)
}
```
5. **音频录制/播放设备异常处理**
```kotlin
// viewmodel/VoiceViewModel.kt
/**
* 安全初始化音频录制
*/
private fun initAudioRecord(): Boolean {
return try {
val bufferSize = AudioRecord.getMinBufferSize(
SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT
)
audioRecord = AudioRecord(
MediaRecorder.AudioSource.MIC,
SAMPLE_RATE,
AudioFormat.CHANNEL_IN_MONO,
AudioFormat.ENCODING_PCM_16BIT,
bufferSize * 2
)
if (audioRecord?.state != AudioRecord.STATE_INITIALIZED) {
Log.e(TAG, "AudioRecord failed to initialize")
audioRecord?.release()
audioRecord = null
false
} else {
true
}
} catch (e: SecurityException) {
Log.e(TAG, "Microphone permission denied", e)
false
} catch (e: Exception) {
Log.e(TAG, "AudioRecord init failed", e)
false
}
}
/**
* 安全初始化音频播放
*/
private fun initAudioTrack(): Boolean {
return try {
val bufferSize = AudioTrack.getMinBufferSize(
SAMPLE_RATE,
AudioFormat.CHANNEL_OUT_MONO,
AudioFormat.ENCODING_PCM_16BIT
)
audioTrack = AudioTrack.Builder()
.setAudioAttributes(
AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
.build()
)
.setAudioFormat(
AudioFormat.Builder()
.setSampleRate(SAMPLE_RATE)
.setChannelMask(AudioFormat.CHANNEL_OUT_MONO)
.setEncoding(AudioFormat.ENCODING_PCM_16BIT)
.build()
)
.setBufferSizeInBytes(bufferSize * 2)
.setTransferMode(AudioTrack.MODE_STREAM)
.build()
true
} catch (e: Exception) {
Log.e(TAG, "AudioTrack init failed", e)
false
}
}
```
6. **列表性能优化**
```kotlin
// ui/screens/ChannelListScreen.kt
@Composable
fun ChannelTreeList(
channelTree: List<ChannelNode>,
currentChannelId: Long,
onChannelClick: (ChannelInfo) -> Unit,
onChannelLongClick: (ChannelInfo) -> Unit
) {
// 使用 key 优化重组
LazyColumn {
items(
items = channelTree,
key = { node -> "channel_${node.channel.id}_${node.depth}" }
) { node ->
ChannelTreeItem(
node = node,
isCurrentChannel = node.channel.id == currentChannelId,
onClick = { onChannelClick(node.channel) },
onLongClick = { onChannelLongClick(node.channel) }
)
}
}
}
@Composable
fun MessageList(
messages: List<TextMsg>,
selfClientId: Int
) {
LazyColumn(
state = rememberLazyListState(),
reverseLayout = true // 新消息在底部
) {
items(
items = messages,
key = { msg -> "${msg.senderID}_${msg.timestamp}" }
) { msg ->
MessageItem(
message = msg,
isSelf = msg.senderID == selfClientId
)
}
}
}
```
### 12.4 测试与验证
**目标**:对全部功能进行端到端冒烟测试,确保各流程正常工作。
**冒烟测试清单**
| 编号 | 测试场景 | 操作步骤 | 预期结果 |
|------|----------|----------|----------|
| T01 | 首次连接 | 输入地址/昵称 → 点击连接 | 连接成功,频道列表显示 |
| T02 | 快速连接 | 点击最近连接记录 | 自动填充并连接 |
| T03 | 频道树浏览 | 展开/折叠子频道 | 频道树正确展开/折叠 |
| T04 | 频道切换 | 点击无密码频道 | 切换成功,当前频道栏更新 |
| T05 | 密码频道 | 点击有密码频道 → 输入密码 | 密码正确则进入,错误则提示 |
| T06 | 发送消息 | 输入消息 → 点击发送 | 消息显示在列表中 |
| T07 | 接收消息 | 其他成员发送消息 | 消息实时显示,未读指示更新 |
| T08 | PTT 发言 | 按住 PTT 按钮 → 松开 | 发言指示出现/消失 |
| T09 | 静音切换 | 点击静音按钮 | 图标切换,语音停止/恢复 |
| T10 | 服务器卡 | 点击头部左侧按钮 | 卡片弹出,信息正确 |
| T11 | 断开连接 | 服务器卡 → 断开 → 确认 | 断开成功,返回配置页 |
| T12 | 被踢处理 | 被管理员踢出 | 全屏提示,可重连/返回 |
| T13 | 网络断开 | 断开网络 | 重连横幅,自动重连 |
| T14 | 主题切换 | 点击右上角主题图标 | 主题切换,重启后保持 |
| T15 | Poke | 长按成员 → Poke → 发送 | 对方收到通知 |
| T16 | 语音卡 | 点击展开按钮 | 卡片显示,控制正常 |
| T17 | 长时间运行 | 连接后静置 30 分钟 | 无崩溃、无内存持续增长 |
**性能指标**
| 指标 | 目标 | 测量方法 |
|------|------|----------|
| 首次启动到可交互 | < 2 秒 | 手动计时 |
| 连接建立 | < 5 秒 | Logcat 时间戳 |
| 首次同步完成 | < 3 秒 | Logcat 时间戳 |
| 频道列表滚动 FPS | ≥ 55 FPS | GPU 过度绘制 / Profiler |
| 消息列表滚动 FPS | ≥ 55 FPS | GPU 过度绘制 / Profiler |
| 内存占用(空闲) | < 80 MB | Android Profiler |
| 内存占用(语音中) | < 120 MB | Android Profiler |
| APK 大小 | < 30 MB | 构建产物大小 |
| ANR 发生率 | 0 | Monkey 测试 / 手动测试 |
---
## 三、状态与数据流
### 3.1 主题状态流
```
用户点击主题按钮 ThemeViewModel ThemePreferences (DataStore) UI
│ │ │ │
│ toggleTheme() │ │ │
├───────────────────→│ │ │
│ │ setThemeMode(next) │ │
│ ├───────────────────────→│ │
│ │ │ 持久化到磁盘 │
│ │ │ │
│ │ themeMode Flow 发出新值 │ │
│ │←───────────────────────┤ │
│ │ │ │
│ │ │ TSMobileTheme 重组 │
│ │ │ 全局颜色方案切换 │
│ │ │ │
│ 界面切换主题 │ │ │
│←───────────────────────────────────────────────────────────────────→│
```
### 3.2 主题模式循环
```
┌─────────┐ 点击 ┌─────────┐ 点击 ┌─────────┐
│ SYSTEM │ ──────────→ │ LIGHT │ ──────────→ │ DARK │
│ 跟随系统 │ │ 亮色 │ │ 暗色 │
└─────────┘ └─────────┘ └─────────┘
↑ │
│ 点击 │
└──────────────────────────────────────────────┘
```
---
## 四、与其他步骤的集成
### 4.1 与服务器配置页集成(步骤 03)
- 主题切换按钮在品牌区右上角
- 主题模式变更实时反映在输入框、按钮、最近连接列表样式上
### 4.2 与频道列表页集成(步骤 05)
- 频道树的图标、文字、背景跟随主题色
- 未读指示的红点/数字 badge 在暗色主题下可见
### 4.3 与聊天页集成(步骤 07)
- 消息气泡颜色区分:自己 vs 他人,亮/暗色方案不同
- 时间戳、发送者名称的颜色适配
### 4.4 与卡片集成(步骤 11)
- 所有 BottomSheet 卡片的背景、文字、按钮跟随主题
- Poke 通知的容器颜色适配
### 4.5 与断开连接集成(步骤 09)
- 重连横幅的颜色使用 errorContainer / onErrorContainer
- 被踢全屏提示的颜色适配
---
## 五、验收标准
### 功能验收
- [ ] **主题切换**
- 服务器配置页右上角图标可切换主题
- 切换后全局所有页面/卡片立即生效
- 切换模式循环:跟随系统 → 亮色 → 暗色 → 跟随系统
- 图标随模式变化(LightMode / DarkMode / SettingsBrightness
- [ ] **主题持久化**
- 选择的主题模式保存到 DataStore
- 关闭应用后重新启动,主题模式保持
- 首次安装默认跟随系统
- [ ] **边缘情况 — 空状态**
- 频道列表为空时显示空状态提示
- 消息列表为空时显示空状态提示
- 最近连接为空时显示空状态提示
- [ ] **边缘情况 — 输入验证**
- 服务器地址为空 → 提示 "请输入服务器地址"
- 服务器地址格式错误 → 提示 "地址格式不正确"
- 昵称为空 → 提示 "请输入昵称"
- 昵称包含非法字符 → 提示包含非法字符
- 消息为空 → 发送按钮置灰
- 消息超长 → 提示 "消息最长 1024 个字符"
- [ ] **边缘情况 — 极端数据**
- 100+ 频道时列表滚动流畅
- 500+ 成员时列表滚动流畅
- 频道名/成员名为空时显示兜底文本
- 服务器返回异常 JSON 时不崩溃
- [ ] **稳定性 — 资源释放**
- 断开连接后音频资源释放
- ViewModel 销毁后协程取消
- 断开后回调注销,不收到旧事件
- 音频焦点正确请求/释放
- [ ] **稳定性 — 异常处理**
- 全局未捕获异常写入日志
- SDK 方法调用超时不导致 ANR
- 权限拒绝(麦克风)不崩溃,显示提示
### 性能验收
- [ ] 首次启动到可交互 < 2 秒
- [ ] 连接建立 < 5 秒
- [ ] 频道列表滚动 FPS ≥ 55
- [ ] 消息列表滚动 FPS ≥ 55
- [ ] 内存占用(空闲) < 80 MB
- [ ] 内存占用(语音中) < 120 MB
- [ ] 无 ANR 发生
- [ ] 无内存泄漏(LeakCanary 或 Profiler 检测)
### 代码质量验收
- [ ] 所有 ViewModel 在 onCleared 中释放资源
- [ ] 所有协程使用 viewModelScope
- [ ] 所有 SDK 调用有 try-catch 保护
- [ ] 所有 JSON 解析有异常处理和默认值
- [ ] 无硬编码的字符串资源(使用 strings.xml
- [ ] 无硬编码的颜色值(使用主题色)
### 测试用例
| 场景 | 操作 | 预期结果 |
|------|------|----------|
| 亮色主题 | 切换到亮色 | 全局亮色,图标为太阳 |
| 暗色主题 | 切换到暗色 | 全局暗色,图标为月亮 |
| 跟随系统 | 切换到跟随系统 | 跟随系统设置,图标为亮度自动 |
| 主题持久化 | 切换主题 → 杀掉应用 → 重启 | 主题保持上次选择 |
| 空频道 | 连接无频道服务器 | 显示空状态提示 |
| 长消息 | 输入 1000 字符发送 | 发送成功,正常显示 |
| 特殊字符名 | 昵称含 emoji/特殊符号 | 正常显示,不崩溃 |
| 快速切换频道 | 连续快速点击频道 | 无崩溃,最终停留在正确频道 |
| 快速发送消息 | 连续快速点击发送 | 消息按序发送,无丢失 |
| 语音中切换主题 | 发言中切换暗色/亮色 | 主题切换,语音不中断 |
| 内存检查 | 连接 → 断开 → 重复 10 次 | 内存无持续增长 |
| 崩溃日志 | 触发未捕获异常 | crash.log 文件生成 |
---
## 六、参考文档
- `docs/UI架构设计.md` - 2.1 服务器配置页(主题切换按钮)、4.4 主题切换
- `docs/implementation/03_服务器配置页.md` - ServerConfigScreen 集成点
- `docs/implementation/05_频道列表页.md` - ChannelTreeList 性能优化
- `docs/implementation/07_聊天页.md` - MessageList 性能优化
- `docs/implementation/09_断开连接.md` - 资源释放、回调注销
- `docs/implementation/11_卡片与全局交互.md` - 卡片主题适配
- `CLAUDE.md` - 测试说明
+798
View File
@@ -0,0 +1,798 @@
# Bridge 层 API 文档
> 本文档是 `go/teamspeak/bridge.go` + `go/teamspeak/kotlin_api.go` 的完整 API 参考。
> 两个文件共同构成 gomobile 导出的 `teamspeak` 包,供 Kotlin 侧通过 `TSBridge` 调用。
>
> **gomobile 导出约定**
> - 返回 `string`:空字符串 `""` = 成功,非空 = 错误信息
> - 返回 JSON `string`:查询结果以 JSON 编码,`"[]"` / `"{}"` 表示空或错误
> - 不支持 `[]string`、`[]*T`、`error` 等 Go 类型,复杂数据一律通过 JSON 传递
> - 回调通过 `EventCallback` 接口定义,所有 JNI 回调在同一线程顺序执行
---
## 一、客户端构造
### NewClient
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `NewClient` | 本地调用 | `NewClient() *TSClient` | 创建客户端实例 | 创建一个空的 TSClient 实例。不建立网络连接,不生成 Identity。需要随后调用 `Connect``ConnectWithIdentity` 发起连接。 |
---
## 二、Identity 管理
### GenerateIdentity
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `GenerateIdentity` | 本地调用 | `GenerateIdentity(securityLevel int) string` | 生成加密身份 | 生成 TeamSpeak 加密身份(ECDSA P-256 密钥对),返回序列化字符串 `"base64PrivateKey:offset"``securityLevel` 推荐值 82048-bit RSA challenge),值越大生成越慢。Kotlin 侧应将返回值持久化到 SharedPreferences / DataStore,后续通过 `ConnectWithIdentity` 复用。返回空字符串表示生成失败。 |
### ConnectWithIdentity
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `ConnectWithIdentity` | 客户端请求 | `(c *TSClient) ConnectWithIdentity(identityStr, host, nickname, password, defaultChannel, defaultChannelPassword string, cb EventCallback) string` | 用已有身份连接 | 使用 `GenerateIdentity` 生成并持久化的 identity 字符串连接服务器。与 `Connect` 行为相同(注册事件 → 发起 UDP 连接 → 等待握手完成,30 秒超时),但复用已有身份而非每次生成新的。`password``defaultChannel``defaultChannelPassword` 为空时忽略。返回空字符串表示连接成功。 |
---
## 三、连接管理
### Connect
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `Connect` | 客户端请求 | `(c *TSClient) Connect(host, nickname, password, defaultChannel, defaultChannelPassword string, cb EventCallback) string` | 连接服务器 | 每次生成新 Identity,注册全部事件回调,发起 UDP 连接并等待握手完成(30 秒超时)。`host` 支持域名/IP/TSDNS,可带端口号(默认 9987)。`password` 为服务器密码(可选)。`defaultChannel` 为连接后自动加入的频道名(可选)。`defaultChannelPassword` 为默认频道密码(可选)。返回空字符串表示连接成功。 |
### Disconnect
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `Disconnect` | 客户端请求 | `(c *TSClient) Disconnect()` | 断开连接 | 停止事件消费协程,发送 disconnect 命令通知服务器,清理客户端状态。断开后触发 `OnDisconnected` 回调。可安全重复调用。 |
### IsConnected
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `IsConnected` | 本地调用 | `(c *TSClient) IsConnected() bool` | 查询连接状态 | 返回当前是否已连接且客户端实例有效。线程安全。 |
### GetClientID
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `GetClientID` | 本地调用 | `(c *TSClient) GetClientID() int` | 获取自身客户端 ID | 返回服务器分配的当前客户端 ID(clid)。未连接时返回 0。ID 由 SDK 本地缓存,不产生网络请求。 |
### GetChannelID
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `GetChannelID` | 客户端请求 | `(c *TSClient) GetChannelID() string` | 获取自身所在频道 ID | 通过 `clientinfo clid=self` 查询当前客户端所在频道 ID。返回频道 ID 字符串,未连接或查询失败返回 `"0"`。 |
---
## 四、频道查询
### GetChannelsJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `GetChannelsJSON` | 客户端请求 | `(c *TSClient) GetChannelsJSON() string` | 获取基础频道列表 | 调用 `channellist` 协议命令,返回 JSON 数组。每个元素包含 `id``name``parentId``description` 四个字段。ID 和 ParentID 均为字符串格式的 uint64。未连接返回 `"[]"`。 |
**返回示例**
```json
[{"id":"1","name":"Lobby","parentId":"0","description":""}]
```
### GetChannelsDetailedJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `GetChannelsDetailedJSON` | 客户端请求 | `(c *TSClient) GetChannelsDetailedJSON() string` | 获取详细频道列表 | 调用 `channellist -topic -flags -voice -limits -icon` 协议命令,返回 JSON 数组。比 `GetChannelsJSON` 多出 14 个字段:`topic``order``codec``codecQuality``neededTalkPower``maxClients``maxFamilyClients``isMaxClientsUnlimited``isMaxFamilyClientsUnlimited``isPermanent``isSemiPermanent``isDefault``isPassword``isOrdered``iconId``neededModifyPower`。用于频道列表页 UI 渲染(密码图标🔒、永久标记📌、人数限制👥等)。未连接返回 `"[]"`。 |
**返回示例**
```json
[{
"id": "1", "name": "Lobby", "parentId": "0", "topic": "欢迎",
"order": "0", "codec": 4, "codecQuality": 7, "neededTalkPower": 0,
"maxClients": -1, "maxFamilyClients": -1,
"isMaxClientsUnlimited": true, "isMaxFamilyClientsUnlimited": true,
"isPermanent": true, "isSemiPermanent": false, "isDefault": true,
"isPassword": false, "isOrdered": false, "iconId": "0", "neededModifyPower": 75
}]
```
### ListChannelsSortedJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `ListChannelsSortedJSON` | 客户端请求 | `(c *TSClient) ListChannelsSortedJSON() string` | 获取去重+排序的详细频道列表 | 底层同样调用 `channellist -topic -flags -voice -limits -icon`,但额外处理:①按 ID 去重(保留最后出现的条目);②按 `channel_order` 排序,先顶层频道再子频道(树形扁平化:顶层频道按 order 排序,每个频道的子频道紧跟其后并按 order 排序)。返回 JSON 数组,字段与 `GetChannelsDetailedJSON` 完全一致。适合频道列表页直接展示,无需客户端侧再做排序和去重。未连接返回 `"[]"`。 |
### GetChannelDetailInfoJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `GetChannelDetailInfoJSON` | 客户端请求 | `(c *TSClient) GetChannelDetailInfoJSON(channelIDStr string) string` | 获取单频道详情 | 调用 `channelinfo cid=X` 协议命令,返回 JSON 对象。与 `GetChannelsDetailedJSON` 的区别:本方法返回单个频道的完整信息(含 `description` 完整描述和 `bannerGfxUrl`),适合频道详情面板展示。`channelIDStr` 为频道 ID 字符串。未连接或无效 ID 返回 `"{}"`。 |
**返回示例**
```json
{
"id": "1", "parentId": "0", "name": "Lobby", "topic": "欢迎",
"description": "这是频道的完整描述...", "codec": 4, "codecQuality": 7,
"maxClients": -1, "maxFamilyClients": -1, "neededTalkPower": 0,
"iconId": "0", "isPermanent": true, "isSemiPermanent": false,
"isDefault": true, "isPassword": false, "order": "0", "bannerGfxUrl": ""
}
```
### FindChannelsJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `FindChannelsJSON` | 客户端请求 | `(c *TSClient) FindChannelsJSON(pattern string) string` | 按名称搜索频道 | 调用 `channelfind pattern=X` 协议命令,返回 JSON 数组。每个元素包含 `id``name``pattern` 支持通配符。用于频道搜索/快速跳转功能。未连接或无匹配返回 `"[]"`。 |
**返回示例**
```json
[{"id":"5","name":"Gaming Room"},{"id":"12","name":"Gaming Lounge"}]
```
---
## 五、客户端查询
### GetClientsJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `GetClientsJSON` | 客户端请求 | `(c *TSClient) GetClientsJSON() string` | 获取在线客户端列表 | 调用 `clientlist -uid -away -voice -groups` 协议命令,返回 JSON 数组。每个元素包含 `id`clid)、`nickname``uid``channelId``serverGroups`(字符串数组)、`isSelf`(是否是当前用户)。自动比对 `ClientID()` 标记 `isSelf` 字段。未连接返回 `"[]"`。 |
**返回示例**
```json
[
{"id":1,"nickname":"Admin","uid":"abc123","channelId":"1","serverGroups":["6","9"],"isSelf":true},
{"id":2,"nickname":"User","uid":"def456","channelId":"2","serverGroups":[],"isSelf":false}
]
```
### GetClientDetailInfoJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `GetClientDetailInfoJSON` | 客户端请求 | `(c *TSClient) GetClientDetailInfoJSON(clid int) string` | 获取单客户端详情 | 调用 `clientinfo clid=X` 协议命令,返回 JSON 对象。比 `GetClientsJSON` 的列表项多出 `away``awayMessage``inputMuted``outputMuted``platform``version``ip``created``lastConnected``totalConnections``description``iconId` 等字段。用于点击客户端后的详情弹窗。`clid` 为客户端 ID。未连接返回 `"{}"`。 |
**返回示例**
```json
{
"id": "1", "nickname": "Admin", "uid": "abc123", "channelId": "1",
"type": 0, "serverGroups": ["6","9"],
"away": false, "awayMessage": "", "inputMuted": false, "outputMuted": false,
"platform": "Windows", "version": "3.x.x", "ip": "192.168.1.1",
"created": "1700000000", "lastConnected": "1710000000", "totalConnections": 42,
"description": "", "iconId": "0"
}
```
### FindClientByNameJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `FindClientByNameJSON` | 客户端请求 | `(c *TSClient) FindClientByNameJSON(nickname string) string` | 按昵称搜索数据库客户端 | 调用 `clientdbfind pattern=X -uid` 协议命令,返回 JSON 对象 `{"uid":"xxx","dbid":"123"}`。搜索服务器数据库中注册过的客户端(不要求在线)。未连接或无匹配返回 `"{}"`。 |
### FindClientByDBIDJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `FindClientByDBIDJSON` | 客户端请求 | `(c *TSClient) FindClientByDBIDJSON(dbidStr string) string` | 按 DBID 查找客户端 UID | 调用 `clientdbfind -uid cldbid=X` 协议命令,返回 JSON 对象 `{"uid":"xxx"}`。通过数据库 ID 反查唯一标识。`dbidStr` 为数据库 ID 字符串。未连接或无匹配返回 `"{}"`。 |
### ListDBClientsJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `ListDBClientsJSON` | 客户端请求 | `(c *TSClient) ListDBClientsJSON(start, duration int) string` | 获取数据库客户端列表 | 调用 `clientdblist start=X duration=X` 协议命令,返回 JSON 数组。每个元素包含 `dbid``uid``nickname``created``lastConnected``totalConnections``description``start` 为起始位置,`duration` 为返回数量(0=全部)。用于管理功能中的用户数据库浏览。未连接返回 `"[]"`。 |
---
## 六、服务器信息
### GetServerInfoJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `GetServerInfoJSON` | 客户端请求 | `(c *TSClient) GetServerInfoJSON() string` | 获取服务器信息 | 调用 `serverinfo` 协议命令,返回 JSON 对象。包含 `name`(服务器名)、`welcomeMessage``maxClients``clientsOnline``channelsOnline``uptime`(运行秒数)、`version``platform``created`(创建时间戳)、`iconId``defaultServerGroup``defaultChannelGroup`。用于服务器详情展示。未连接返回 `"{}"`。 |
**返回示例**
```json
{
"name": "My TeamSpeak Server", "welcomeMessage": "Welcome!",
"maxClients": 100, "clientsOnline": 5, "channelsOnline": 3,
"uptime": "86400", "version": "3.13.7", "platform": "Linux",
"created": "1700000000", "iconId": "0",
"defaultServerGroup": 8, "defaultChannelGroup": 1
}
```
---
## 七、文本消息与 Poke
### SendTextMessage
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `SendTextMessage` | 客户端请求 | `(c *TSClient) SendTextMessage(targetMode int, targetIDStr string, message string) string` | 发送文字消息 | 发送文本消息到指定目标。`targetMode`: 1=私聊(target 为客户端 ID)、2=频道消息(target 为频道 ID)、3=服务器消息(target 忽略)。`targetIDStr` 为目标 ID 字符串。`message` 为消息内容。返回空字符串表示发送成功。 |
### SendChannelMessage
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `SendChannelMessage` | 客户端请求 | `(c *TSClient) SendChannelMessage(channelIDStr, message string) string` | 发送频道消息 | `SendTextMessage(targetMode=2, ...)` 的快捷方式。`channelIDStr` 为频道 ID 字符串。返回空字符串表示发送成功。 |
### Poke
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `Poke` | 客户端请求 | `(c *TSClient) Poke(clidStr string, message string) string` | 发送 Poke | 向指定客户端发送 Poke(戳一戳)消息。`clidStr` 为目标客户端 ID 字符串。`message` 为 Poke 文本。对方会收到弹窗通知。返回空字符串表示发送成功。 |
---
## 八、频道切换与客户端移动
### MoveToChannel
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `MoveToChannel` | 客户端请求 | `(c *TSClient) MoveToChannel(channelIDStr, password string) string` | 移动自己到目标频道 | 将当前客户端移动到指定频道。`channelIDStr` 为目标频道 ID 字符串。`password` 为频道密码(无密码传空字符串)。调用 `ClientMove(selfID, channelID, password)`。返回空字符串表示命令已发送,实际移动需等待 `OnClientMoved` 事件确认。 |
### MoveClient
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `MoveClient` | 客户端请求 | `(c *TSClient) MoveClient(clientID int, channelIDStr, password string) string` | 移动指定客户端到目标频道 | 将任意客户端移动到指定频道(需要权限)。`clientID` 为要移动的客户端 IDclid)。`channelIDStr` 为目标频道 ID 字符串。`password` 为频道密码(可选)。返回空字符串表示命令已发送。 |
### MoveChannel
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `MoveChannel` | 客户端请求 | `(c *TSClient) MoveChannel(channelIDStr, parentIDStr, orderStr string) string` | 移动频道位置 | 移动频道到新的父频道下或调整排序。`channelIDStr` 为要移动的频道 ID。`parentIDStr` 为新的父频道 ID`"0"` = 顶层)。`orderStr` 为排序位置(`"0"` = 最顶部)。返回空字符串表示成功。 |
---
## 九、频道管理
### CreateChannelJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `CreateChannelJSON` | 客户端请求 | `(c *TSClient) CreateChannelJSON(name, propertiesJSON string) string` | 创建频道 | 调用 `channelcreate channel_name=X [params...]``name` 为频道名。`propertiesJSON` 为 JSON 对象,包含可选属性如 `{"channel_topic":"主题","channel_flag_permanent":"1","cpid":"父频道ID","channel_password":"密码","channel_maxclients":"10","channel_codec":"4"}`。返回新频道 ID 字符串,空字符串表示失败。 |
### EditChannelJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `EditChannelJSON` | 客户端请求 | `(c *TSClient) EditChannelJSON(channelIDStr, propertiesJSON string) string` | 编辑频道属性 | 调用 `channeledit cid=X [params...]``channelIDStr` 为频道 ID 字符串。`propertiesJSON` 为 JSON 对象,包含要修改的属性。返回空字符串表示成功。 |
### DeleteChannel
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `DeleteChannel` | 客户端请求 | `(c *TSClient) DeleteChannel(channelIDStr string, force bool) string` | 删除频道 | 调用 `channeldelete cid=X force=X``channelIDStr` 为频道 ID 字符串。`force=true` 强制删除(含子频道),`false` 仅在频道为空时删除。返回空字符串表示成功。 |
---
## 十、客户端管理
### UpdateSelfJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `UpdateSelfJSON` | 客户端请求 | `(c *TSClient) UpdateSelfJSON(propertiesJSON string) string` | 更新自身属性 | 调用 `clientupdate [params...]``propertiesJSON` 为 JSON 对象。常用参数:`client_nickname`(新昵称)、`client_away``"1"`/`"0"` 离开状态)、`client_away_message`(离开消息)、`client_input_muted``"1"`/`"0"` 输入静音)、`client_output_muted``"1"`/`"0"` 输出静音)、`client_phonetic_nickname`(语音昵称)。返回空字符串表示成功。 |
**用法示例**
```
UpdateSelfJSON('{"client_nickname":"NewName","client_away":"1","client_away_message":"AFK"}')
```
### KickClient
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `KickClient` | 客户端请求 | `(c *TSClient) KickClient(clid int, reasonID int, reasonMsg string) string` | 踢出客户端 | 调用 `clientkick clid=X reasonid=X reasonmsg=X``clid` 为客户端 ID。`reasonID`: 4=从频道踢出,5=从服务器踢出。`reasonMsg` 为踢出原因文本。返回空字符串表示成功。 |
---
## 十一、语音
### SendVoice
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `SendVoice` | 客户端请求 | `(c *TSClient) SendVoice(data []byte, codec int64) string` | 发送语音帧 | 发送原始 Opus 编码的语音帧到当前频道。`data` 为 Opus 编码的音频数据(20ms 帧)。`codec`: 4=Opus Voice(语音通话,默认),5=Opus Music(高保真音频)。通过 UDP 传输。返回空字符串表示发送成功。 |
---
## 十二、Ban 管理
### ListBansJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `ListBansJSON` | 客户端请求 | `(c *TSClient) ListBansJSON() string` | 获取封禁列表 | 调用 `banlist` 协议命令,返回 JSON 数组。每个元素包含 `banId``ip``name``uid``created`(时间戳)、`invokerName`(操作者)、`invokerUid``reason``enforcement`(是否立即执行)。未连接返回 `"[]"`。 |
### AddBan
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `AddBan` | 客户端请求 | `(c *TSClient) AddBan(ip, name, uid string, timeSeconds int, reason string) string` | 添加封禁 | 调用 `banadd ip=X name=X uid=X time=X banreason=X``ip`/`name`/`uid` 至少指定一个,可组合使用。`timeSeconds` 为封禁时长(秒),0=永久。`reason` 为封禁原因(可选)。返回空字符串表示成功。 |
### DeleteBan
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `DeleteBan` | 客户端请求 | `(c *TSClient) DeleteBan(banIDStr string) string` | 删除封禁 | 调用 `bandel banid=X``banIDStr` 为封禁 ID 字符串(从 `ListBansJSON` 获取)。返回空字符串表示成功。 |
### DeleteAllBans
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `DeleteAllBans` | 客户端请求 | `(c *TSClient) DeleteAllBans() string` | 清除所有封禁 | 调用 `bandelall` 协议命令,删除服务器上的全部封禁记录。返回空字符串表示成功。 |
---
## 十三、Token 管理
### ListTokensJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `ListTokensJSON` | 客户端请求 | `(c *TSClient) ListTokensJSON() string` | 获取权限密钥列表 | 调用 `tokenlist` 协议命令,返回 JSON 数组。每个元素包含 `token`(密钥字符串)、`tokenType`0=服务器组, 1=频道组)、`tokenId1`(组 ID)、`tokenId2`(频道 ID,仅 tokenType=1)、`created`(创建时间戳)、`description`。未连接返回 `"[]"`。 |
### UseToken
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `UseToken` | 客户端请求 | `(c *TSClient) UseToken(token string) string` | 激活权限密钥 | 调用 `tokenuse token=X``token` 为权限密钥字符串。激活后自动获得对应的服务器组或频道组权限。返回空字符串表示成功。 |
---
## 十四、投诉管理
### ListComplaintsJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `ListComplaintsJSON` | 客户端请求 | `(c *TSClient) ListComplaintsJSON(targetDBIDStr string) string` | 获取投诉列表 | 调用 `complainlist [tcldbid=X]` 协议命令,返回 JSON 数组。每个元素包含 `fromDbid`(投诉者 DBID)、`toDbid`(被投诉者 DBID)、`message`(投诉内容)、`timestamp`(投诉时间戳)。`targetDBIDStr``"0"` 或空字符串时返回全部投诉。未连接返回 `"[]"`。 |
### AddComplaint
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `AddComplaint` | 客户端请求 | `(c *TSClient) AddComplaint(targetDBIDStr, message string) string` | 提交投诉 | 调用 `complainadd tcldbid=X message=X``targetDBIDStr` 为被投诉者的数据库 ID 字符串。`message` 为投诉内容。返回空字符串表示成功。 |
### DeleteComplaint
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `DeleteComplaint` | 客户端请求 | `(c *TSClient) DeleteComplaint(targetDBIDStr, fromDBIDStr string) string` | 删除投诉 | 调用 `complaindel tcldbid=X fcldbid=X``targetDBIDStr` 为被投诉者 DBID`fromDBIDStr` 为投诉者 DBID。返回空字符串表示成功。 |
---
## 十五、文件传输
### ListFilesJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `ListFilesJSON` | 客户端请求 | `(c *TSClient) ListFilesJSON(channelIDStr, path string) string` | 获取频道文件列表 | 调用 `ftgetfilelist cid=X path=X` 协议命令,返回 JSON 数组。每个元素包含 `name`(文件/目录名)、`size`(字节数,目录为 0)、`dateTime`(修改时间戳)、`isFile`true=文件, false=目录)。`channelIDStr` 为频道 ID 字符串。`path` 为虚拟路径,根目录为 `"/"`。未连接返回 `"[]"`。 |
### FileTransferInitUploadJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `FileTransferInitUploadJSON` | 客户端请求 | `(c *TSClient) FileTransferInitUploadJSON(channelIDStr, path string, size int64, overwrite bool) string` | 初始化文件上传 | 调用 `ftinitupload cid=X path=X size=X overwrite=X`,等待服务器返回传输参数。返回 JSON 对象:`port`TCP 端口)、`key`(传输密钥)、`clientFileTransferID``serverFileTransferID``seekPosition`(断点续传位置)。`channelIDStr` 为频道 ID。`path` 为目标路径。`size` 为文件字节数。`overwrite` 为是否覆盖。TCP 连接 host 为当前服务器地址。未连接返回 `"{}"`。 |
### FileTransferInitDownloadJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `FileTransferInitDownloadJSON` | 客户端请求 | `(c *TSClient) FileTransferInitDownloadJSON(channelIDStr, path string) string` | 初始化文件下载 | 调用 `ftinitdownload cid=X path=X`,等待服务器返回传输参数。返回 JSON 对象:`port`TCP 端口)、`key`(传输密钥)、`size`(文件字节数)、`clientFileTransferID``serverFileTransferID``channelIDStr` 为频道 ID。`path` 为源路径。未连接返回 `"{}"`。 |
### DeleteFile
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `DeleteFile` | 客户端请求 | `(c *TSClient) DeleteFile(channelIDStr, pathsJSON string) string` | 删除频道文件 | 调用 `ftdeletefile cid=X path=X [path2=X ...]``channelIDStr` 为频道 ID 字符串。`pathsJSON` 为要删除的文件路径 JSON 数组,如 `["/file1.txt","/dir/file2.txt"]`。返回空字符串表示成功。 |
---
## 十六、批量查询
### GetInitialSyncJSON
| 名字 | 触发形式 | 用法 | 作用 | 详细描述 |
|------|----------|------|------|----------|
| `GetInitialSyncJSON` | 客户端请求 | `(c *TSClient) GetInitialSyncJSON() string` | 首次同步批量查询 | 一次性返回连接后首次同步所需的全部数据,将 4 次 JNI 调用合并为 1 次。内部依次调用 `GetChannelsDetailedJSON``GetClientsJSON``GetClientID``GetChannelID``GetServerInfoJSON`,合并为单个 JSON 对象返回。任一子查询失败时对应字段为 null/空,不影响其他字段。未连接返回 `"{}"`。 |
**返回格式**
```json
{
"channels": [
{"id":"1","name":"Lobby","parentId":"0","topic":"","order":"0","codec":4,...}
],
"clients": [
{"id":1,"nickname":"Admin","uid":"abc","channelId":"1","serverGroups":[],"isSelf":true}
],
"selfId": 1,
"selfChannelId": "1",
"server": {
"name":"My Server","welcomeMessage":"","maxClients":100,"clientsOnline":5,...
}
}
```
---
## 十七、事件回调接口
### EventCallback
所有事件通过 `EventCallback` 接口回调。Kotlin 侧实现此接口并传入 `Connect``ConnectWithIdentity`。所有回调在同一个 goroutine 中顺序执行(通过内部事件队列保证),无需担心并发问题。
| 回调方法 | 触发时机 | 参数 | 描述 |
|----------|----------|------|------|
| `OnConnected()` | 连接握手完成 | 无 | 服务器握手成功,可以开始发送业务命令。此时应执行首次同步(调用 `GetInitialSyncJSON`)。 |
| `OnDisconnected(message string)` | 连接断开 | `message`: 错误原因 | 网络中断或服务器主动断开。`message` 为空表示正常断开。此时应清理 UI 状态并提示用户。 |
| `OnTextMessage(msg *TextMsg)` | 收到文本消息 | `msg.TargetMode`: 1=私聊/2=频道/3=服务器;`msg.TargetID`: 目标 ID`msg.InvokerName`: 发送者昵称;`msg.InvokerUID`: 发送者 UID`msg.Message`: 消息内容 | 收到其他客户端发送的文本消息。按 TargetMode + Target 归档到正确的会话。 |
| `OnClientEnter(client *Client)` | 用户进入视野 | `client.ID`: 客户端 ID`client.Nickname`: 昵称;`client.UID`: UID`client.ChannelID`: 所在频道 ID | 新客户端进入服务器。应添加到本地成员表。`client.ChannelID` 来自 `notifycliententerview`,可能不准确,需补偿同步。 |
| `OnClientLeave(id int, reasonMsg string)` | 用户离开 | `id`: 客户端 ID`reasonMsg`: 离开原因 | 客户端离开服务器。应从本地成员表移除。 |
| `OnClientMoved(id int, targetChannelID string)` | 用户移动频道 | `id`: 客户端 ID`targetChannelID`: 目标频道 ID | 客户端在频道间移动。当 `id == GetClientID()` 时,表示自己被移动(含密码验证结果)。应更新成员所在频道。 |
| `OnKicked(reason string)` | 被踢出 | `reason`: 踢出原因 | 自己被从频道或服务器踢出。应停止语音采集,清理会话状态,显示被踢原因并允许重连。 |
| `OnVoiceData(clientID int, data []byte, codec int)` | 收到语音 | `clientID`: 发送者 ID`data`: Opus 编码帧;`codec`: 4=Opus Voice/5=Opus Music | 收到同频道其他客户端的语音数据。`data` 可直接送入 Opus 解码器。回调中不要做耗时操作,应推入 channel 由独立协程解码播放。 |
| `OnPoked(event *PokeEvent)` | 被 Poke | `event.InvokerID`: 发送者 ID`event.InvokerName`: 发送者昵称;`event.InvokerUID`: 发送者 UID`event.Message`: Poke 消息 | 收到其他用户的 Poke 消息。应显示 Toast 或弹窗通知。 |
### Kotlin 侧事件处理流程
以下三个事件在 Android 端有完整的 UI 处理链路:
#### 被管理员移动到指定频道(OnClientMoved
```
Go SDK notifyclientmoved
→ EventCallback.OnClientMoved(id, targetChannelID)
→ TSBridge 转发
→ ChannelViewModel.handleClientMoved()
→ 判断 id == selfId → 标记为"被外部移动"
→ 更新 _currentChannelId
→ refreshClientList() 刷新当前频道成员
→ UI 自动更新频道列表和成员列表
```
**日志标识**: `Client moved: {id} -> channel {channelID}``Self moved by external action to channel {channelID}`
#### 收到频道内文本消息(OnTextMessage, targetMode=2
```
Go SDK notifytextmessage
→ EventCallback.OnTextMessage(msg)
→ TSBridge 转发
→ ServerViewModel.handleTextMessage()
→ 解析 senderId(通过 clientlist 匹配 invokerUID
→ 转发给 ChatViewModel
→ ChatViewModel.handleTextMessage()
→ 判断 targetMode=2(频道消息)
→ 归档到对应会话(频道 ID 为 key)
→ 如果匹配当前打开的聊天,更新实时消息列表
```
**日志标识**: `onTextMessage: targetMode=2, targetID={channelID}, invokerName={name}, message={content}`
#### 被 Poke 带文本消息(OnPoked
```
Go SDK notifyclientpoke
→ EventCallback.OnPoked(event)
→ TSBridge 转发
→ ServerViewModel.handlePoked()
→ 更新 _pokeNotification 状态
→ triggerVibration() 震动反馈(需 VIBRATE 权限)
→ 5 秒后自动隐藏通知
→ UI 显示 Poke 弹窗(发送者昵称 + 消息内容)
```
**日志标识**: `Poked by {name}: {message}`
**注意**: Poke 震动需要 `android.permission.VIBRATE` 权限(AndroidManifest.xml 中声明即可,无需运行时请求)。
---
## 十八、导出数据类型
以下类型通过 gomobile 导出到 Kotlin 侧,可直接在回调参数中使用。
### Channel
| 字段 | 类型 | 描述 |
|------|------|------|
| `ID` | `string` | 频道 ID |
| `Name` | `string` | 频道名称 |
| `ParentID` | `string` | 父频道 ID |
| `Description` | `string` | 频道描述 |
### Client
| 字段 | 类型 | 描述 |
|------|------|------|
| `ID` | `int` | 客户端 IDclid |
| `Nickname` | `string` | 昵称 |
| `UID` | `string` | 唯一标识 |
| `ChannelID` | `string` | 所在频道 ID |
| `IsSelf` | `bool` | 是否是当前用户(仅 `GetClientsJSON` 中自动标记) |
### TextMsg
| 字段 | 类型 | 描述 |
|------|------|------|
| `InvokerName` | `string` | 发送者昵称 |
| `InvokerUID` | `string` | 发送者唯一标识 |
| `Message` | `string` | 消息内容 |
| `TargetMode` | `int` | 1=私聊, 2=频道, 3=服务器 |
| `TargetID` | `string` | 目标 ID |
### PokeEvent
| 字段 | 类型 | 描述 |
|------|------|------|
| `InvokerID` | `int` | 发送者客户端 ID |
| `InvokerName` | `string` | 发送者昵称 |
| `InvokerUID` | `string` | 发送者唯一标识 |
| `Message` | `string` | Poke 消息内容 |
---
## 十九、JSON 数据结构参考
以下 JSON 结构由查询方法返回,供 Kotlin 侧反序列化使用。
### channelJSONGetChannelsJSON / FindChannelsJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `id` | `string` | 频道 ID |
| `name` | `string` | 频道名称 |
| `parentId` | `string` | 父频道 IDGetChannelsJSON 有,FindChannelsJSON 无) |
| `description` | `string` | 频道描述(GetChannelsJSON 有,FindChannelsJSON 无) |
### channelDetailedJSONGetChannelsDetailedJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `id` | `string` | 频道 ID |
| `name` | `string` | 频道名称 |
| `parentId` | `string` | 父频道 ID |
| `topic` | `string` | 频道主题 |
| `order` | `string` | 排序顺序 |
| `codec` | `int` | 编解码器(4=Opus Voice, 5=Opus Music |
| `codecQuality` | `int` | 编解码质量(0-10 |
| `neededTalkPower` | `int` | 发言所需权限等级 |
| `maxClients` | `int` | 最大客户端数(-1=无限) |
| `maxFamilyClients` | `int` | 最大族客户端数(-1=无限) |
| `isMaxClientsUnlimited` | `bool` | 是否无限人数 |
| `isMaxFamilyClientsUnlimited` | `bool` | 是否无限族人数 |
| `isPermanent` | `bool` | 永久频道 |
| `isSemiPermanent` | `bool` | 半永久频道 |
| `isDefault` | `bool` | 默认频道 |
| `isPassword` | `bool` | 有密码 |
| `isOrdered` | `bool` | 手动排序 |
| `iconId` | `string` | 频道图标 ID |
| `neededModifyPower` | `int` | 修改频道所需权限 |
### channelDetailedInfoJSONGetChannelDetailInfoJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `id` | `string` | 频道 ID |
| `parentId` | `string` | 父频道 ID |
| `name` | `string` | 频道名称 |
| `topic` | `string` | 频道主题 |
| `description` | `string` | 完整描述(可能很长) |
| `codec` | `int` | 编解码器 |
| `codecQuality` | `int` | 编解码质量 |
| `maxClients` | `int` | 最大人数 |
| `maxFamilyClients` | `int` | 最大族人数 |
| `neededTalkPower` | `int` | 发言权限 |
| `iconId` | `string` | 图标 ID |
| `isPermanent` | `bool` | 永久 |
| `isSemiPermanent` | `bool` | 半永久 |
| `isDefault` | `bool` | 默认 |
| `isPassword` | `bool` | 有密码 |
| `order` | `string` | 排序 |
| `bannerGfxUrl` | `string` | Banner 图片 URL |
### clientJSONGetClientsJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `id` | `int` | 客户端 ID |
| `nickname` | `string` | 昵称 |
| `uid` | `string` | 唯一标识 |
| `channelId` | `string` | 所在频道 ID |
| `serverGroups` | `[]string` | 所在服务器组 ID 列表 |
| `isSelf` | `bool` | 是否是当前用户 |
### clientDetailedInfoJSONGetClientDetailInfoJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `id` | `string` | 客户端 ID |
| `nickname` | `string` | 昵称 |
| `uid` | `string` | 唯一标识 |
| `channelId` | `string` | 所在频道 ID |
| `type` | `int` | 客户端类型 |
| `serverGroups` | `[]string` | 服务器组 |
| `away` | `bool` | 是否离开 |
| `awayMessage` | `string` | 离开消息 |
| `inputMuted` | `bool` | 输入静音 |
| `outputMuted` | `bool` | 输出静音 |
| `platform` | `string` | 平台 |
| `version` | `string` | 版本 |
| `ip` | `string` | IP 地址 |
| `created` | `string` | 首次连接时间戳 |
| `lastConnected` | `string` | 最近连接时间戳 |
| `totalConnections` | `int` | 总连接次数 |
| `description` | `string` | 用户描述 |
| `iconId` | `string` | 图标 ID |
### serverInfoJSONGetServerInfoJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `name` | `string` | 服务器名称 |
| `welcomeMessage` | `string` | 欢迎消息 |
| `maxClients` | `int` | 最大客户端数 |
| `clientsOnline` | `int` | 在线客户端数 |
| `channelsOnline` | `int` | 在线频道数 |
| `uptime` | `string` | 运行时长(秒) |
| `version` | `string` | 服务器版本 |
| `platform` | `string` | 服务器平台 |
| `created` | `string` | 创建时间戳 |
| `iconId` | `string` | 服务器图标 ID |
| `defaultServerGroup` | `int` | 默认服务器组 ID |
| `defaultChannelGroup` | `int` | 默认频道组 ID |
### dbClientJSONListDBClientsJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `dbid` | `string` | 数据库 ID |
| `uid` | `string` | 唯一标识 |
| `nickname` | `string` | 昵称 |
| `created` | `string` | 首次连接时间戳 |
| `lastConnected` | `string` | 最近连接时间戳 |
| `totalConnections` | `int` | 总连接次数 |
| `description` | `string` | 描述 |
### banEntryJSONListBansJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `banId` | `string` | 封禁 ID |
| `ip` | `string` | IP |
| `name` | `string` | 名称 |
| `uid` | `string` | 唯一标识 |
| `created` | `string` | 封禁时间戳 |
| `invokerName` | `string` | 操作者昵称 |
| `invokerUid` | `string` | 操作者 UID |
| `reason` | `string` | 封禁原因 |
| `enforcement` | `bool` | 是否立即执行 |
### fileEntryJSONListFilesJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `name` | `string` | 文件/目录名 |
| `size` | `string` | 字节数(目录为 "0" |
| `dateTime` | `string` | 修改时间戳 |
| `isFile` | `bool` | true=文件, false=目录 |
### tokenEntryJSONListTokensJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `token` | `string` | 权限密钥字符串 |
| `tokenType` | `int` | 0=服务器组, 1=频道组 |
| `tokenId1` | `string` | 组 ID |
| `tokenId2` | `string` | 频道 ID(仅 tokenType=1 |
| `created` | `string` | 创建时间戳 |
| `description` | `string` | 描述 |
### complaintEntryJSONListComplaintsJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `fromDbid` | `string` | 投诉者 DBID |
| `toDbid` | `string` | 被投诉者 DBID |
| `message` | `string` | 投诉内容 |
| `timestamp` | `string` | 投诉时间戳 |
### fileTransferInitJSONFileTransferInitUploadJSON / FileTransferInitDownloadJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `port` | `int` | TCP 传输端口 |
| `key` | `string` | 传输密钥 |
| `size` | `int` | 文件字节数(仅下载) |
| `clientFileTransferID` | `int` | 客户端传输 ID |
| `serverFileTransferID` | `int` | 服务器传输 ID |
| `seekPosition` | `int` | 断点续传位置(仅上传) |
### initialSyncJSONGetInitialSyncJSON
| 字段 | 类型 | 描述 |
|------|------|------|
| `channels` | `[]channelDetailedJSON` | 详细频道列表 |
| `clients` | `[]clientJSON` | 在线客户端列表 |
| `selfId` | `int` | 自身客户端 ID |
| `selfChannelId` | `string` | 自身所在频道 ID |
| `server` | `serverInfoJSON` | 服务器信息 |
---
## 二十、方法来源标记
标记每个方法的实现文件,便于定位代码。
| 方法 | 来源文件 | 说明 |
|------|----------|------|
| `NewClient` | bridge.go | |
| `GenerateIdentity` | kotlin_api.go | |
| `Connect` | bridge.go | 每次生成新 Identity |
| `ConnectWithIdentity` | kotlin_api.go | 复用已有 Identity |
| `Disconnect` | bridge.go | |
| `IsConnected` | bridge.go | |
| `GetClientID` | bridge.go | |
| `GetChannelID` | bridge.go | |
| `GetChannelsJSON` | bridge.go | |
| `GetChannelsDetailedJSON` | bridge.go | |
| `ListChannelsSortedJSON` | kotlin_api.go | 去重+排序 |
| `GetClientsJSON` | bridge.go | |
| `GetServerInfoJSON` | bridge.go | |
| `GetChannelDetailInfoJSON` | bridge.go | |
| `GetClientDetailInfoJSON` | bridge.go | |
| `ListDBClientsJSON` | bridge.go | |
| `FindChannelsJSON` | kotlin_api.go | |
| `FindClientByNameJSON` | kotlin_api.go | |
| `FindClientByDBIDJSON` | kotlin_api.go | |
| `SendTextMessage` | bridge.go | |
| `SendChannelMessage` | bridge.go | 快捷方式 |
| `Poke` | bridge.go | |
| `MoveToChannel` | bridge.go | 移动自己 |
| `MoveClient` | kotlin_api.go | 移动指定客户端 |
| `MoveChannel` | kotlin_api.go | 移动频道位置 |
| `CreateChannelJSON` | bridge.go | |
| `EditChannelJSON` | bridge.go | |
| `DeleteChannel` | bridge.go | |
| `UpdateSelfJSON` | bridge.go | |
| `KickClient` | bridge.go | |
| `SendVoice` | bridge.go | |
| `ListBansJSON` | bridge.go | |
| `AddBan` | bridge.go | |
| `DeleteBan` | bridge.go | |
| `DeleteAllBans` | kotlin_api.go | |
| `ListTokensJSON` | bridge.go | |
| `UseToken` | bridge.go | |
| `ListComplaintsJSON` | bridge.go | |
| `AddComplaint` | bridge.go | |
| `DeleteComplaint` | kotlin_api.go | |
| `ListFilesJSON` | bridge.go | |
| `FileTransferInitUploadJSON` | kotlin_api.go | |
| `FileTransferInitDownloadJSON` | kotlin_api.go | |
| `DeleteFile` | kotlin_api.go | |
| `GetInitialSyncJSON` | kotlin_api.go | |
+888
View File
@@ -0,0 +1,888 @@
# teamspeak-go SDK 文档
基于 `github.com/honeybbq/teamspeak-go` 源码整理。
触发形式说明:
- **客户端请求** — 客户端主动发送命令到服务端,等待响应
- **服务端推送** — 服务端主动下发通知,客户端被动接收
- **本地调用** — 纯客户端本地操作,不涉及网络通信
> **关于"通过指令构建的能力"**: 部分 API 标注为"通过指令构建的能力",表示其底层封装了 TS3 协议命令(如 `serverinfo`、`channelinfo`、`banlist` 等),通过 SDK 的 `ExecCommand` / `ExecCommandWithResponse` 基础设施发送并解析响应。这些命令与 SDK 原生内置的命令(如握手、事件通知)不同,是通过协议命令扩展出的额外能力,可参考对应的协议命令语法进行调试或扩展。
---
## 1. 连接管理
### 构造与连接
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `NewClient` | 本地调用 | `NewClient(identity, addr, nickname, ...options) *Client` | 创建客户端 | 创建 TeamSpeak 客户端实例。`identity` 为加密身份,`addr` 为服务器地址,`nickname` 为昵称,`options` 可选配置 |
| `Connect` | 客户端请求 | `Connect() error` | 连接服务器 | 发起 UDP 会话和握手连接 |
| `Disconnect` | 客户端请求 | `Disconnect() error` | 断开连接 | 优雅断开连接,发送 shutdown reason |
| `WaitConnected` | 本地调用 | `WaitConnected(ctx context.Context) error` | 等待连接就绪 | 阻塞等待握手完成,支持 context 取消。发送命令前必须先调用 |
### 连接选项(ClientOption
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `WithLogger` | 本地调用 | `WithLogger(logger *slog.Logger)` | 设置日志 | 注入自定义 slog.Logger |
| `WithResolver` | 本地调用 | `WithResolver(r AddrResolver)` | 设置解析器 | 自定义 DNS/TSDNS 解析 |
| `WithServerPassword` | 本地调用 | `WithServerPassword(password string)` | 服务器密码 | 连接时使用的服务器密码 |
| `WithDefaultChannel` | 本地调用 | `WithDefaultChannel(channel string)` | 默认频道 | 连接后自动加入的频道名 |
| `WithDefaultChannelPassword` | 本地调用 | `WithDefaultChannelPassword(password string)` | 默认频道密码 | 默认频道的密码 |
| `WithCommandMiddleware` | 本地调用 | `WithCommandMiddleware(mw ...CommandMiddleware)` | 命令中间件 | 拦截/修改发送的命令 |
| `WithEventMiddleware` | 本地调用 | `WithEventMiddleware(mw ...EventMiddleware)` | 事件中间件 | 拦截/修改接收的事件 |
---
## 2. 事件注册
### 事件处理器
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|--------------------------------------------------------|
| `OnConnected` | 服务端推送 | `OnConnected(fn func())` | 连接成功 | 客户端完成握手后触发 |
| `OnDisconnected` | 服务端推送 | `OnDisconnected(fn func(error))` | 断开连接 | 连接断开时触发,携带错误原因 |
| `OnTextMessage` | 服务端推送 | `OnTextMessage(fn func(TextMessage))` | 收到消息 | 收到文本消息(私聊/频道/服务器),对应 `notifytextmessage` |
| `OnClientEnter` | 服务端推送 | `OnClientEnter(fn func(ClientInfo))` | 用户进入 | 客户端进入视野(进入服务器),对应 `notifycliententerview` |
| `OnClientLeave` | 服务端推送 | `OnClientLeave(fn func(ClientLeftViewEvent))` | 用户离开 | 客户端离开视野(离开服务器),对应 `notifyclientleftview` |
| `OnClientMoved` | 服务端推送 | `OnClientMoved(fn func(ClientMovedEvent))` | 用户移动 | 客户端在频道间移动,对应 `notifyclientmoved` |
| `OnPoked` | 服务端推送 | `OnPoked(fn func(PokeEvent))` | 被戳一戳 | 收到其他用户的 Poke,对应 `notifyclientpoke` |
| `OnKicked` | 服务端推送 | `OnKicked(fn func(string))` | 被踢出 | 自己被踢出频道或服务器,从 `notifyclientleftview` 中 reasonid=4/5 触发 |
| `OnVoiceData` | 服务端推送 | `OnVoiceData(fn func(VoiceDataEvent))` | 收到语音 | 收到同频道其他客户端发送的 Opus 语音帧,通过 UDP 二进制包传输 |
### VoiceDataEvent 结构
收到语音数据的事件载荷,由 `OnVoiceData` 回调接收。
| 字段 | 类型 | 描述 |
|------|------|------|
| `ClientID` | `uint16` | 发送者客户端 ID |
| `Data` | `[]byte` | Opus 编码的语音帧原始数据 |
| `Codec` | `byte` | 编解码器类型:4 = Opus Voice(语音),5 = Opus Music(音乐) |
**语音包 UDP 二进制格式**SDK 内部解析后填充 `VoiceDataEvent`):
```
Offset Size Field
0 2 packetIDbig-endian
2 2 clientIDlittle-endian
4 1 codec4=Opus Voice, 5=Opus Music
5 N Opus 编码数据
```
**语音接收流程**
```
Server UDP 语音包
→ PacketHandler 解密
→ handlePacket() 路由 PacketTypeVoice(0) / PacketTypeVoiceWhisper(1)
→ 解析 clientID、codec、opusData
→ notifyEvent(VoiceDataEvent{...})
→ startEventLoop 串行分发
→ OnVoiceData 注册的所有 handler 依次调用
```
---
## 3. 聊天命令
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `SendTextMessage` | 客户端请求 | `SendTextMessage(targetMode int, targetID uint64, msg string) error` | 发送文本消息 | `targetMode`: 1=私聊, 2=频道, 3=服务器。对应协议 `sendtextmessage` |
| `Poke` | 客户端请求 | `Poke(clid uint16, msg string) error` | 发送 Poke | 向指定用户发送戳一戳消息。对应协议 `clientpoke` |
### TextMessage 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `TargetMode` | `int` | 1=私聊, 2=频道, 3=服务器 |
| `Target` | `uint64` | 目标 ID(频道 ID 或客户端 ID) |
| `InvokerID` | `uint16` | 发送者客户端 ID |
| `InvokerName` | `string` | 发送者昵称 |
| `InvokerUID` | `string` | 发送者唯一标识 |
| `InvokerGroups` | `[]string` | 发送者所在组 |
| `Message` | `string` | 消息内容 |
### PokeEvent 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `InvokerID` | `uint16` | 发送者客户端 ID |
| `InvokerName` | `string` | 发送者昵称 |
| `InvokerUID` | `string` | 发送者唯一标识 |
| `Message` | `string` | Poke 消息内容 |
---
## 4. 客户端命令
### 基础客户端操作
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `ClientID` | 本地调用 | `ClientID() uint16` | 获取自身 ID | 返回服务器分配的客户端 ID(本地缓存) |
| `ListClients` | 客户端请求 | `ListClients() ([]ClientInfo, error)` | 在线用户列表 | 返回当前服务器所有在线客户端。对应协议 `clientlist` |
| `ClientMove` | 客户端请求 | `ClientMove(clid uint16, channelID uint64, password string) error` | 移动用户 | 将客户端移至指定频道。对应协议 `clientmove` |
### 客户端信息查询
> **通过指令构建的能力** — 底层封装 TS3 协议命令 `clientinfo`、`clientdblist`、`clientdbfind`。
| 方法 | 触发形式 | 协议命令 | 用法 | 作用 |
|------|----------|----------|------|------|
| `GetClientInfo` | 客户端请求 | `clientinfo clid=X` | `GetClientInfo(clid uint16) (map[string]string, error)` | 查询在线用户详情(原始 map) |
| `GetClientDetailInfo` | 客户端请求 | `clientinfo clid=X` | `GetClientDetailInfo(clid uint16) (*ClientDetailInfo, error)` | 查询在线用户详情(结构化) |
| `ListDBClients` | 客户端请求 | `clientdblist start=X duration=X` | `ListDBClients(start, duration int) ([]DBClient, error)` | 数据库客户端列表 |
| `FindClientByName` | 客户端请求 | `clientdbfind pattern=X -uid` | `FindClientByName(nickname string) (uid string, dbid uint64, err error)` | 按昵称搜索数据库用户 |
| `FindClientByDBID` | 客户端请求 | `clientdbfind -uid cldbid=X` | `FindClientByDBID(dbid uint64) (string, error)` | 按 DBID 查找 UID |
### 客户端状态与操作
> **通过指令构建的能力** — 底层封装 TS3 协议命令 `clientupdate`、`clientkick`。
| 方法 | 触发形式 | 协议命令 | 用法 | 作用 |
|------|----------|----------|------|------|
| `UpdateSelf` | 客户端请求 | `clientupdate` | `UpdateSelf(properties map[string]string) error` | 更新自身属性(昵称、away、静音等) |
| `KickClient` | 客户端请求 | `clientkick clid=X reasonid=X reasonmsg=X` | `KickClient(clid uint16, reasonID int, reasonMsg string) error` | 踢出用户(4=频道踢出, 5=服务器踢出) |
### ClientInfo 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `ID` | `uint16` | 客户端 ID |
| `Nickname` | `string` | 昵称 |
| `ChannelID` | `uint64` | 所在频道 ID |
| `UID` | `string` | 唯一标识 |
| `Type` | `int` | 客户端类型 |
| `ServerGroups` | `[]string` | 所在服务器组 |
### ClientDetailInfo 结构
通过 `clientinfo clid=X` 获取的完整客户端信息。比 `ClientInfo` 多出 away 状态、平台、版本、IP 等字段。
| 字段 | 类型 | 描述 |
|------|------|------|
| `ID` | `uint16` | 客户端 ID (clid) |
| `Nickname` | `string` | 昵称 |
| `UID` | `string` | 唯一标识 |
| `ChannelID` | `uint64` | 所在频道 ID |
| `Type` | `int` | 客户端类型 |
| `ServerGroups` | `[]string` | 所在服务器组 |
| `Away` | `bool` | 是否离开 |
| `AwayMessage` | `string` | 离开消息 |
| `InputMuted` | `bool` | 输入静音 |
| `OutputMuted` | `bool` | 输出静音 |
| `Platform` | `string` | 客户端平台 |
| `Version` | `string` | 客户端版本 |
| `IP` | `string` | 客户端 IP(需权限) |
| `Created` | `int64` | 首次连接时间(unix 时间戳) |
| `LastConnected` | `int64` | 最近连接时间 |
| `TotalConnections` | `int` | 总连接次数 |
| `Description` | `string` | 用户描述 |
| `IconID` | `int64` | 用户图标 ID |
### DBClient 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `DBID` | `uint64` | 数据库 ID (cldbid) |
| `UID` | `string` | 唯一标识 |
| `Nickname` | `string` | 昵称 |
| `Created` | `int64` | 首次连接时间 |
| `LastConnected` | `int64` | 最近连接时间 |
| `TotalConnections` | `int` | 总连接次数 |
| `Description` | `string` | 用户描述 |
### UpdateSelf 常用参数
| 参数 | 值 | 说明 |
|------|------|------|
| `client_nickname` | 字符串 | 新昵称 |
| `client_away` | `"1"` / `"0"` | 是否离开 |
| `client_away_message` | 字符串 | 离开消息 |
| `client_input_muted` | `"1"` / `"0"` | 输入静音 |
| `client_output_muted` | `"1"` / `"0"` | 输出静音 |
| `client_phonetic_nickname` | 字符串 | 语音昵称 |
### Bridge 层 JSON 接口
| 方法 | 返回 | 描述 |
|------|------|------|
| `GetClientsJSON()` | `string` | 在线客户端列表(含 isSelf 标志) |
| `GetClientDetailInfoJSON(clid int)` | `string` | 单个客户端详细信息 |
| `ListDBClientsJSON(start, duration int)` | `string` | 数据库客户端列表 |
| `UpdateSelfJSON(propertiesJSON string)` | `string` | 更新自身(错误信息或空串) |
| `KickClient(clid int, reasonID int, reasonMsg string)` | `string` | 踢出用户(错误信息或空串) |
### ClientLeftViewEvent 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `ClientID` | `uint16` | 离开的客户端 ID |
| `ReasonID` | `int` | 原因:0=正常离开, 4=频道踢, 5=服务器踢 |
| `ReasonMessage` | `string` | 原因描述 |
| `IsSelf` | `bool` | 是否是自己 |
### ClientMovedEvent 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `ClientID` | `uint16` | 被移动的客户端 ID |
| `TargetChannelID` | `uint64` | 目标频道 ID |
| `ReasonID` | `int` | 原因 |
| `InvokerID` | `uint16` | 操作者 ID |
| `InvokerName` | `string` | 操作者昵称 |
| `InvokerUID` | `string` | 操作者唯一标识 |
---
## 5. 频道命令
### 基础频道列表
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `ListChannels` | 客户端请求 | `ListChannels() ([]ChannelInfo, error)` | 频道列表(基础) | 返回服务器所有频道的基础信息(ID、父频道、名称)。对应协议 `channellist` |
### 详细频道列表
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `ListChannelsDetailed` | 客户端请求 | `ListChannelsDetailed() ([]ChannelInfoDetailed, error)` | 频道列表(详细) | 返回服务器所有频道的完整属性。对应协议 `channellist -topic -flags -voice -limits -icon` |
`channellist` 命令支持的 flag 参数:
| Flag | 返回字段 | 说明 |
|------|---------|------|
| `-topic` | `channel_topic` | 频道主题描述 |
| `-flags` | `channel_flag_permanent`, `channel_flag_semi_permanent`, `channel_flag_default`, `channel_flag_password`, `channel_flag_maxclients_unlimited`, `channel_flag_maxfamilyclients_unlimited`, `channel_order` | 频道标志位(永久、半永久、默认、密码、人数限制、排序) |
| `-voice` | `channel_codec`, `channel_codec_quality`, `channel_needed_talk_power` | 语音编解码相关 |
| `-limits` | `channel_maxclients`, `channel_maxfamilyclients` | 频道人数限制 |
| `-icon` | `channel_icon_id` | 频道自定义图标 ID |
### 频道查询
> **通过指令构建的能力** — 底层封装 TS3 协议命令 `channelinfo`、`channelfind`。
| 方法 | 触发形式 | 协议命令 | 用法 | 作用 |
|------|----------|----------|------|------|
| `GetChannelInfo` | 客户端请求 | `channelinfo cid=X` | `GetChannelInfo(channelID uint64) (*ChannelDetailInfo, error)` | 单频道完整详情(含 description |
| `FindChannels` | 客户端请求 | `channelfind pattern=X` | `FindChannels(pattern string) ([]ChannelInfo, error)` | 按名称搜索频道 |
### 频道管理
> **通过指令构建的能力** — 底层封装 TS3 协议命令 `channelcreate`、`channeledit`、`channeldelete`、`channelmove`。
| 方法 | 触发形式 | 协议命令 | 用法 | 作用 |
|------|----------|----------|------|------|
| `CreateChannel` | 客户端请求 | `channelcreate channel_name=X ...` | `CreateChannel(name string, options map[string]string) (uint64, error)` | 创建频道,返回新频道 ID |
| `EditChannel` | 客户端请求 | `channeledit cid=X ...` | `EditChannel(channelID uint64, properties map[string]string) error` | 编辑频道属性 |
| `DeleteChannel` | 客户端请求 | `channeldelete cid=X force=X` | `DeleteChannel(channelID uint64, force bool) error` | 删除频道,force=true 强制删除 |
| `MoveChannel` | 客户端请求 | `channelmove cid=X cpid=X order=X` | `MoveChannel(channelID, parentID, order uint64) error` | 移动频道到新父频道或调整排序 |
#### CreateChannel 常用可选参数
| 参数 | 值 | 说明 |
|------|------|------|
| `channel_topic` | 字符串 | 频道主题 |
| `channel_flag_permanent` | `"1"` / `"0"` | 永久频道 |
| `channel_flag_semi_permanent` | `"1"` / `"0"` | 半永久频道 |
| `channel_flag_default` | `"1"` / `"0"` | 默认频道 |
| `channel_password` | 字符串 | 频道密码 |
| `cpid` | 字符串(父频道ID) | 父频道 |
| `channel_maxclients` | 字符串 | 最大人数 |
| `channel_codec` | 字符串 | 编解码器(0-5) |
### ChannelInfo 结构(基础)
| 字段 | 类型 | 描述 |
|------|------|------|
| `ID` | `uint64` | 频道 ID |
| `ParentID` | `uint64` | 父频道 ID(0 = 顶层频道) |
| `Name` | `string` | 频道名称(已 Unescape |
| `Description` | `string` | 频道描述(`ListChannels` 返回为空) |
### ChannelInfoDetailed 结构(详细列表项)
来自 `channellist -topic -flags -voice -limits -icon` 的批量列表项。
| 字段 | 类型 | 描述 |
|------|------|------|
| **基础** | | |
| `ID` | `uint64` | 频道 ID |
| `ParentID` | `uint64` | 父频道 ID(0 = 顶层频道) |
| `Order` | `uint64` | 排序顺序(前一个频道 ID,0 = 最顶部) |
| `Name` | `string` | 频道名称 |
| `Topic` | `string` | 频道主题(来自 `-topic` |
| **语音(`-voice`** | | |
| `Codec` | `int` | 0=Speex Narrowband, 1=Speex Wideband, 2=Speex UltraWideband, 3=CELT Mono, **4=Opus Voice**, **5=Opus Music** |
| `CodecQuality` | `int` | 编解码质量(0-10 |
| `NeededTalkPower` | `int` | 发言所需权限等级 |
| **限制(`-limits`** | | |
| `MaxClients` | `int` | 最大客户端数 |
| `MaxFamilyClients` | `int` | 最大族客户端数 |
| `IsMaxClientsUnlimited` | `bool` | 是否无限人数 |
| `IsMaxFamilyClientsUnlimited` | `bool` | 是否无限族人数 |
| **标志(`-flags`** | | |
| `IsPermanent` | `bool` | 永久频道 |
| `IsSemiPermanent` | `bool` | 半永久频道 |
| `IsDefault` | `bool` | 默认频道 |
| `IsPassword` | `bool` | 是否设置密码 |
| `IsOrdered` | `bool` | 是否手动排序 |
| `NeededModifyPower` | `int` | 修改频道所需权限 |
| **图标(`-icon`** | | |
| `IconID` | `int64` | 频道图标 ID |
### ChannelDetailInfo 结构(单频道详情)
来自 `channelinfo cid=X` 的完整频道信息,比 `ChannelInfoDetailed` 多出 `Description`(完整描述)和 `BannerGfxURL` 等字段。
| 字段 | 类型 | 描述 |
|------|------|------|
| `ID` | `uint64` | 频道 ID |
| `ParentID` | `uint64` | 父频道 ID |
| `Name` | `string` | 频道名称 |
| `Topic` | `string` | 频道主题 |
| `Description` | `string` | 完整描述 |
| `Codec` | `int` | 编解码器 |
| `CodecQuality` | `int` | 编解码质量 |
| `MaxClients` | `int` | 最大人数 |
| `MaxFamilyClients` | `int` | 最大族人数 |
| `NeededTalkPower` | `int` | 发言权限 |
| `IconID` | `int64` | 图标 ID |
| `IsPermanent` | `bool` | 永久 |
| `IsSemiPermanent` | `bool` | 半永久 |
| `IsDefault` | `bool` | 默认 |
| `IsPassword` | `bool` | 有密码 |
| `Order` | `uint64` | 排序 |
| `BannerGfxURL` | `string` | Banner 图片 URL |
### Bridge 层 JSON 接口
| 方法 | 返回 | 描述 |
|------|------|------|
| `GetChannelsJSON()` | `string` | 基础频道列表(向后兼容) |
| `GetChannelsDetailedJSON()` | `string` | 详细频道列表(含 flags/voice/limits/icon |
| `GetChannelDetailInfoJSON(channelIDStr string)` | `string` | 单频道完整详情 |
| `CreateChannelJSON(name, propertiesJSON string)` | `string` | 创建频道,返回新频道 ID(空串=失败) |
| `EditChannelJSON(channelIDStr, propertiesJSON string)` | `string` | 编辑频道(错误信息或空串) |
| `DeleteChannel(channelIDStr string, force bool)` | `string` | 删除频道(错误信息或空串) |
`GetChannelsDetailedJSON()` 返回的 JSON 示例:
```json
[
{
"id": "1",
"name": "Lobby",
"parentId": "0",
"topic": "欢迎来到大厅",
"order": "0",
"codec": 4,
"codecQuality": 7,
"neededTalkPower": 0,
"maxClients": -1,
"maxFamilyClients": -1,
"isMaxClientsUnlimited": true,
"isMaxFamilyClientsUnlimited": true,
"isPermanent": true,
"isSemiPermanent": false,
"isDefault": true,
"isPassword": false,
"isOrdered": false,
"iconId": "0",
"neededModifyPower": 75
}
]
```
### 典型用法
```go
// 获取详细频道列表
channels, err := client.ListChannelsDetailed()
if err != nil {
return err
}
for _, ch := range channels {
// 显示频道名和状态图标
icons := ""
if ch.IsPassword { icons += "🔒" }
if ch.IsPermanent { icons += "📌" }
if !ch.IsMaxClientsUnlimited {
icons += fmt.Sprintf(" 👥%d", ch.MaxClients)
}
log.Printf("%s %s %s", icons, ch.Name, ch.Topic)
// 根据编解码器选择解码策略
switch ch.Codec {
case 4: // Opus Voice — 20ms 帧,适合语音
case 5: // Opus Music — 更高采样率,适合音乐
}
}
```
---
## 6. 语音命令
### 发送语音
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `SendVoice` | 客户端请求 | `SendVoice(data []byte, codec byte) error` | 发送语音帧 | 发送原始 Opus 帧。codec: 4=Opus 语音, 5=Opus 音乐。通过 UDP 传输 |
### 接收语音
接收语音通过事件回调实现,无需主动调用。
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `OnVoiceData` | 服务端推送 | `OnVoiceData(fn func(VoiceDataEvent))` | 注册语音接收回调 | 当同频道其他客户端发送语音时,SDK 解密后触发回调 |
**Codec 值说明**
| 值 | 类型 | 适用场景 |
|----|------|---------|
| `4` | Opus Voice | 语音通话(默认) |
| `5` | Opus Music | 音乐/高保真音频 |
**典型用法**
```go
client.OnVoiceData(func(evt teamspeak.VoiceDataEvent) {
// evt.ClientID — 发送者客户端 ID
// evt.Data — Opus 编码帧,可直接送入解码器
// evt.Codec — 4=Opus Voice, 5=Opus Music
decoded := opusDecoder.Decode(evt.Data, pcmBuffer)
audioTrack.Write(pcmBuffer[:decoded])
})
```
**注意事项**
- `OnVoiceData` 回调在事件循环 goroutine 中串行执行,**不要在回调中做耗时操作**(如 Opus 解码),应将数据推入 channel 由独立协程处理
- SDK 不内置 Opus 解码器,需要在应用层(Kotlin/Go)集成 `opus.Decode()`
- 语音帧以 20ms 为单位发送,采样率通常为 48kHz
---
## 7. 服务器查询
> **通过指令构建的能力** — 底层封装 TS3 协议命令 `serverinfo`。
### 服务器信息
| 方法 | 触发形式 | 协议命令 | 用法 | 作用 |
|------|----------|----------|------|------|
| `GetServerInfo` | 客户端请求 | `serverinfo` | `GetServerInfo() (*ServerInfo, error)` | 获取服务器完整信息 |
### ServerInfo 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `Name` | `string` | 服务器名称 |
| `WelcomeMessage` | `string` | 欢迎消息 |
| `MaxClients` | `int` | 最大客户端数 |
| `ClientsOnline` | `int` | 在线客户端数 |
| `ChannelsOnline` | `int` | 在线频道数 |
| `Uptime` | `int64` | 服务器运行时长(秒) |
| `Version` | `string` | 服务器版本 |
| `Platform` | `string` | 服务器平台 |
| `Created` | `int64` | 创建时间(unix 时间戳) |
| `IconID` | `int64` | 服务器图标 ID |
| `DefaultServerGroup` | `int` | 默认服务器组 ID |
| `DefaultChannelGroup` | `int` | 默认频道组 ID |
### Bridge 层 JSON 接口
| 方法 | 返回 | 描述 |
|------|------|------|
| `GetServerInfoJSON()` | `string` | 服务器信息(JSON 对象,空 `"{}"` 表示未连接或出错) |
---
## 8. Ban 管理
> **通过指令构建的能力** — 底层封装 TS3 协议命令 `banlist`、`banadd`、`bandel`、`bandelall`。
### Ban 操作
| 方法 | 触发形式 | 协议命令 | 用法 | 作用 |
|------|----------|----------|------|------|
| `ListBans` | 客户端请求 | `banlist` | `ListBans() ([]BanEntry, error)` | 获取所有封禁记录 |
| `AddBan` | 客户端请求 | `banadd ip=X name=X uid=X time=X banreason=X` | `AddBan(ip, name, uid string, timeSeconds int, reason string) error` | 添加封禁(ip/name/uid 至少指定一个,time=0 为永久) |
| `DeleteBan` | 客户端请求 | `bandel banid=X` | `DeleteBan(banID int64) error` | 解除指定封禁 |
| `DeleteAllBans` | 客户端请求 | `bandelall` | `DeleteAllBans() error` | 清除所有封禁 |
### BanEntry 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `BanID` | `int64` | 封禁 ID |
| `IP` | `string` | IP(可能为空或部分掩码) |
| `Name` | `string` | 名称模式 |
| `UID` | `string` | 唯一标识 |
| `Created` | `int64` | 封禁时间(unix 时间戳) |
| `InvokerName` | `string` | 操作者昵称 |
| `InvokerUID` | `string` | 操作者 UID |
| `Reason` | `string` | 封禁原因 |
| `Enforcement` | `bool` | 是否立即执行 |
### Bridge 层 JSON 接口
| 方法 | 返回 | 描述 |
|------|------|------|
| `ListBansJSON()` | `string` | Ban 列表 |
| `AddBan(ip, name, uid string, timeSeconds int, reason string)` | `string` | 添加封禁(错误信息或空串) |
| `DeleteBan(banIDStr string)` | `string` | 删除封禁(错误信息或空串) |
---
## 9. Token 管理
> **通过指令构建的能力** — 底层封装 TS3 协议命令 `tokenlist`、`tokenuse`。
Token(权限密钥)用于让用户自动获得服务器组/频道组权限。
### Token 操作
| 方法 | 触发形式 | 协议命令 | 用法 | 作用 |
|------|----------|----------|------|------|
| `ListTokens` | 客户端请求 | `tokenlist` | `ListTokens() ([]TokenEntry, error)` | 获取所有权限密钥 |
| `UseToken` | 客户端请求 | `tokenuse token=X` | `UseToken(token string) error` | 激活权限密钥 |
### TokenEntry 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `Token` | `string` | 权限密钥字符串 |
| `TokenType` | `int` | 类型:0=服务器组, 1=频道组 |
| `TokenID1` | `int64` | 组 ID |
| `TokenID2` | `int64` | 频道 ID(仅 token_type=1 时有效) |
| `Created` | `int64` | 创建时间(unix 时间戳) |
| `Description` | `string` | 描述 |
### Bridge 层 JSON 接口
| 方法 | 返回 | 描述 |
|------|------|------|
| `ListTokensJSON()` | `string` | Token 列表 |
| `UseToken(token string)` | `string` | 使用 Token(错误信息或空串) |
---
## 10. 投诉管理
> **通过指令构建的能力** — 底层封装 TS3 协议命令 `complainlist`、`complainadd`、`complaindel`。
### 投诉操作
| 方法 | 触发形式 | 协议命令 | 用法 | 作用 |
|------|----------|----------|------|------|
| `ListComplaints` | 客户端请求 | `complainlist [tcldbid=X]` | `ListComplaints(targetDBID uint64) ([]ComplaintEntry, error)` | 查询投诉(targetDBID=0 查全部) |
| `AddComplaint` | 客户端请求 | `complainadd tcldbid=X message=X` | `AddComplaint(targetDBID uint64, message string) error` | 提交投诉 |
| `DeleteComplaint` | 客户端请求 | `complaindel tcldbid=X fcldbid=X` | `DeleteComplaint(targetDBID, fromDBID uint64) error` | 删除投诉 |
### ComplaintEntry 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `FromDBID` | `uint64` | 投诉者 DBID |
| `ToDBID` | `uint64` | 被投诉者 DBID |
| `Message` | `string` | 投诉内容 |
| `Timestamp` | `int64` | 投诉时间(unix 时间戳) |
### Bridge 层 JSON 接口
| 方法 | 返回 | 描述 |
|------|------|------|
| `ListComplaintsJSON(targetDBIDStr string)` | `string` | 投诉列表(`"0"` 表示全部) |
| `AddComplaint(targetDBIDStr, message string)` | `string` | 提交投诉(错误信息或空串) |
---
## 11. 文件传输
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `FileTransferInitUpload` | 客户端请求 | `FileTransferInitUpload(channelID uint64, path string, password string, size uint64, overwrite bool) (*FileUploadInfo, error)` | 初始化上传 | 请求上传文件到频道文件目录。对应协议 `ftinitupload` |
| `FileTransferInitDownload` | 客户端请求 | `FileTransferInitDownload(channelID uint64, path string, password string) (*FileDownloadInfo, error)` | 初始化下载 | 请求下载频道文件。对应协议 `ftinitdownload` |
| `FileTransferDeleteFile` | 客户端请求 | `FileTransferDeleteFile(channelID uint64, paths []string) error` | 删除文件 | 删除频道中的文件。对应协议 `ftdeletefile` |
### 文件列表查询
> **通过指令构建的能力** — 底层封装 TS3 协议命令 `ftgetfilelist`。
| 方法 | 触发形式 | 协议命令 | 用法 | 作用 |
|------|----------|----------|------|------|
| `ListFiles` | 客户端请求 | `ftgetfilelist cid=X path=X` | `ListFiles(channelID uint64, path string) ([]FileEntry, error)` | 列出频道目录下的文件和子目录(path 为虚拟路径,根目录为 `/` |
### FileEntry 结构
| 字段 | 类型 | 描述 |
|------|------|------|
| `Name` | `string` | 文件/目录名 |
| `Size` | `uint64` | 文件大小(字节,目录为 0) |
| `DateTime` | `int64` | 修改时间(unix 时间戳) |
| `IsFile` | `bool` | 是否为文件(false = 目录) |
### Bridge 层 JSON 接口
| 方法 | 返回 | 描述 |
|------|------|------|
| `ListFilesJSON(channelIDStr, path string)` | `string` | 频道文件列表 |
### 辅助函数
| 函数 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `DialFileTransfer` | 客户端请求 | `DialFileTransfer(host string, port uint16, key string) (net.Conn, error)` | 建立文件传输连接 | 建立到文件传输端口的 TCP 连接 |
| `UploadFileData` | 客户端请求 | `UploadFileData(host string, info *FileUploadInfo, data io.Reader) error` | 上传数据 | 通过已初始化的连接上传文件数据 |
| `DownloadFileData` | 客户端请求 | `DownloadFileData(host string, info *FileDownloadInfo, dest io.Writer) error` | 下载数据 | 通过已初始化的连接下载文件数据 |
---
## 12. 中间件
| 类型 | 触发形式 | 定义 | 作用 | 描述 |
|------|----------|------|------|------|
| `CommandMiddleware` | 本地调用 | `func(next func(string) error) func(string) error` | 命令中间件 | 拦截/修改即将发送的命令字符串 |
| `EventMiddleware` | 本地调用 | `func(next func(any)) func(any)` | 事件中间件 | 拦截/修改即将分发的事件 |
---
## 13. 解析器接口
| 类型 | 触发形式 | 定义 | 作用 | 描述 |
|------|----------|------|------|------|
| `AddrResolver` | 本地调用 | `Resolve(ctx context.Context, addr string) ([]discovery.ResolvedAddr, error)` | 地址解析器 | 自定义 DNS/TSDNS 服务器地址解析 |
---
## 14. 协议转义
| 函数 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `commands.Escape` | 本地调用 | `commands.Escape(s string) string` | 转义 | 将字符串转义为 TS3 协议安全格式 |
| `commands.Unescape` | 本地调用 | `commands.Unescape(s string) string` | 反转义 | 将 TS3 协议转义字符串还原 |
| `commands.BuildCommand` | 本地调用 | `commands.BuildCommand(cmd string, params map[string]string) string` | 构建命令 | 从命令名和参数 map 构建协议命令字符串 |
| `commands.BuildCommandOrdered` | 本地调用 | `commands.BuildCommandOrdered(cmd string, params [][2]string) string` | 构建命令(有序) | 同上,但保持参数顺序 |
---
## 15. 服务器通知(内部处理)
以下通知由 SDK 内部解析并转换为事件,开发者通过 `On*` 方法注册处理器即可,无需直接处理。
| 通知 ID | 触发形式 | 事件类型 | 描述 |
|---------|----------|----------|-------------------------|
| `notifycliententerview` | 服务端推送 | `ClientInfo` | 客户端进入服务器(事件数据结构频道id未生效) |
| `notifyclientleftview` | 服务端推送 | `ClientLeftViewEvent` | 客户端离开视野(含踢出) |
| `notifyclientmoved` | 服务端推送 | `ClientMovedEvent` | 客户端频道移动 |
| `notifytextmessage` | 服务端推送 | `TextMessage` | 收到文本消息 |
| `notifyclientpoke` | 服务端推送 | `PokeEvent` | 收到 Poke |
| `notifyclientneededpermissions` | 服务端推送 | — | 仅 Debug 日志,无事件 |
| `notifystartupload` | 服务端推送 | `FileUploadInfo` | 文件上传开始 |
| `notifystartdownload` | 服务端推送 | `FileDownloadInfo` | 文件下载开始 |
| `notifystatusfiletransfer` | 服务端推送 | `FileTransferStatusInfo` | 文件传输状态变更 |
---
## 16. 未实现的 TS3 协议命令
以下命令在 teamspeak-go 中尚未封装,如需支持可在 `api.go` 中按现有模式扩展(通过 `ExecCommand` / `ExecCommandWithResponse` 发送协议命令)。
### 用户管理
| 命令 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `clientdbedit` | 客户端请求 | `clientdbedit cldbid=X ...` | 编辑数据库用户 | 修改数据库用户属性(描述、昵称等) |
| `clientsetservergroup` | 客户端请求 | `clientsetservergroup cldbid=X sgid=X` | 设置服务器组 | 将用户添加到指定服务器组 |
| `clientgetdbidfromuid` | 客户端请求 | `clientgetdbidfromuid cluid=X` | UID→DBID | 从唯一标识获取数据库 ID |
| `clientgetnamefromuid` | 客户端请求 | `clientgetnamefromuid cluid=X` | UID→昵称 | 从唯一标识获取昵称 |
| `clientgetnamefromdbid` | 客户端请求 | `clientgetnamefromdbid cldbid=X` | DBID→昵称 | 从数据库 ID 获取昵称 |
| `clientgetids` | 客户端请求 | `clientgetids cluid=X` | UID→clid | 从唯一标识获取在线客户端 ID |
### 服务器组管理
| 命令 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `servergroupadd` | 客户端请求 | `servergroupadd name=X` | 创建服务器组 | 创建新的服务器组 |
| `servergroupdel` | 客户端请求 | `servergroupdel sgid=X force=1` | 删除服务器组 | 删除指定服务器组 |
| `servergroupaddclient` | 客户端请求 | `servergroupaddclient sgid=X cldbid=X` | 添加用户到组 | 将数据库用户添加到服务器组 |
| `servergroupdelclient` | 客户端请求 | `servergroupdelclient sgid=X cldbid=X` | 从组移除用户 | 将用户从服务器组移除 |
| `servergrouplist` | 客户端请求 | `servergrouplist` | 服务器组列表 | 获取所有服务器组 |
### 服务器管理
| 命令 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `serveredit` | 客户端请求 | `serveredit virtualserver_name=X ...` | 编辑服务器 | 修改服务器属性 |
| `serverprocessstop` | 客户端请求 | `serverprocessstop reasonmsg=X` | 关闭服务器 | 停止服务器进程 |
### 权限查询
| 命令 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `permoverview` | 客户端请求 | `permoverview cid=X cldbid=X` | 权限概览 | 获取用户在指定频道的权限概览 |
| `permget` | 客户端请求 | `permget permid=X` | 获取权限 | 获取指定权限的当前值 |
| `permfind` | 客户端请求 | `permfind permid=X` | 查找权限 | 查找拥有指定权限的所有对象 |
### 其他
| 命令 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `sendpluginmessage` | 客户端请求 | `sendpluginmessage target=X msg=X` | 插件消息 | 向指定目标发送插件消息 |
| `tokenadd` | 客户端请求 | `tokenadd tokentype=X ...` | 创建 Token | 创建新的权限 Token |
| `tokendelete` | 客户端请求 | `tokendelete token=X` | 删除 Token | 删除指定 Token |
| `banclient` | 客户端请求 | `banclient clid=X time=X banreason=X` | 踢+Ban | 踢出并封禁指定在线客户端 |
---
## 17. Bridge 层 Kotlin 友好 APIkotlin_api.go
`go/teamspeak/kotlin_api.go` 是对 `bridge.go` 的补充封装,暴露 SDK 中已有但 bridge.go 未导出的能力,并提供 Identity 管理接口。
所有方法遵循 bridge.go 的 gomobile 导出约定:
- 返回 `string`:空字符串=成功,非空=错误信息
- 返回 JSON `string`:查询结果以 JSON 编码
### 17.1 Identity 管理
| 方法 | 触发形式 | 用法 | 作用 | 描述 |
|------|----------|------|------|------|
| `GenerateIdentity` | 本地调用 | `GenerateIdentity(securityLevel int) string` | 生成身份 | 生成加密身份并序列化为字符串。`securityLevel` 推荐值 8。Kotlin 侧应持久化返回值,后续通过 `ConnectWithIdentity` 复用 |
| `ConnectWithIdentity` | 客户端请求 | `ConnectWithIdentity(identityStr, host, nickname, password, defaultChannel, defaultChannelPassword string, cb EventCallback) string` | 用已有身份连接 | 使用已持久化的 identity 字符串连接。行为与 `Connect` 相同 |
**Identity 序列化格式**: `"base64EncodedPrivateKey:offset"`(由 SDK 的 `Identity.String()` 生成)
**典型用法**
```kotlin
// 首次使用:生成并持久化
val identity = GenerateIdentity(8)
preferences.edit().putString("ts_identity", identity).apply()
// 后续使用:从持久化读取
val identity = preferences.getString("ts_identity", "") ?: ""
val error = client.connectWithIdentity(identity, host, nickname, password, "", "", callback)
```
### 17.2 查询能力(补充)
以下方法补充 bridge.go 中未暴露的 SDK 查询能力。
| 方法 | 返回 | 描述 |
|------|------|------|
| `FindChannelsJSON(pattern string) string` | JSON 数组 | 按名称搜索频道。返回 `[{"id":"1","name":"匹配的频道"}]` |
| `FindClientByNameJSON(nickname string) string` | JSON 对象 | 按昵称搜索数据库客户端。返回 `{"uid":"xxx","dbid":"123"}` |
| `FindClientByDBIDJSON(dbidStr string) string` | JSON 对象 | 按 DBID 查找客户端 UID。返回 `{"uid":"xxx"}` |
### 17.3 操作能力(补充)
以下方法补充 bridge.go 中未暴露的 SDK 操作能力。
| 方法 | 返回 | 描述 |
|------|------|------|
| `MoveClient(clientID int, channelIDStr, password string) string` | 错误信息 | 将指定客户端移动到目标频道 |
| `MoveChannel(channelIDStr, parentIDStr, orderStr string) string` | 错误信息 | 移动频道到新父频道或调整排序 |
| `DeleteAllBans() string` | 错误信息 | 清除所有封禁记录 |
| `DeleteComplaint(targetDBIDStr, fromDBIDStr string) string` | 错误信息 | 删除指定投诉 |
### 17.4 文件传输(初始化)
文件传输遵循三阶段流程:初始化 → TCP 连接 → 数据传输。以下方法封装初始化阶段。
| 方法 | 返回 | 描述 |
|------|------|------|
| `FileTransferInitUploadJSON(channelIDStr, path string, size int64, overwrite bool) string` | JSON 对象 | 初始化上传。返回 `{"port":0,"key":"...","clientFileTransferID":0,"serverFileTransferID":0,"seekPosition":0}` |
| `FileTransferInitDownloadJSON(channelIDStr, path string) string` | JSON 对象 | 初始化下载。返回 `{"port":0,"key":"...","size":0,"clientFileTransferID":0,"serverFileTransferID":0}` |
| `DeleteFile(channelIDStr, pathsJSON string) string` | 错误信息 | 删除频道文件。`pathsJSON` 为 JSON 数组如 `["/file1.txt","/file2.txt"]` |
**注意**:TCP 连接的 host 为当前服务器地址,port 从初始化返回的 JSON 中获取。完整的文件传输流程(TCP 连接 + 数据传输)需要额外封装。
### 17.5 批量查询(首次同步优化)
| 方法 | 返回 | 描述 |
|------|------|------|
| `GetInitialSyncJSON() string` | JSON 对象 | 一次性返回首次同步所需的全部数据,减少 JNI 调用次数 |
返回格式:
```json
{
"channels": [
{"id":"1","name":"Lobby","parentId":"0","topic":"","order":"0","codec":4,"codecQuality":7,...}
],
"clients": [
{"id":1,"nickname":"User","uid":"xxx","channelId":"1","serverGroups":[],"isSelf":true}
],
"selfId": 1,
"selfChannelId": "1",
"server": {
"name":"My Server","welcomeMessage":"","maxClients":100,"clientsOnline":5,"channelsOnline":3,...
}
}
```
任一子查询失败时对应字段为 null/空数组,不影响其他字段。
### 17.6 Bridge 层方法完整索引
#### bridge.go 已有方法
| 分类 | 方法 | 返回 |
|------|------|------|
| 连接 | `Connect(host, nickname, password, defaultChannel, defaultChannelPassword, cb)` | 错误信息 |
| 连接 | `Disconnect()` | — |
| 连接 | `IsConnected()` | bool |
| 连接 | `GetClientID()` | int |
| 连接 | `GetChannelID()` | string |
| 查询 | `GetChannelsJSON()` | JSON 数组 |
| 查询 | `GetChannelsDetailedJSON()` | JSON 数组 |
| 查询 | `GetClientsJSON()` | JSON 数组 |
| 查询 | `GetServerInfoJSON()` | JSON 对象 |
| 查询 | `GetChannelDetailInfoJSON(channelIDStr)` | JSON 对象 |
| 查询 | `GetClientDetailInfoJSON(clid)` | JSON 对象 |
| 查询 | `ListDBClientsJSON(start, duration)` | JSON 数组 |
| 查询 | `ListBansJSON()` | JSON 数组 |
| 查询 | `ListTokensJSON()` | JSON 数组 |
| 查询 | `ListFilesJSON(channelIDStr, path)` | JSON 数组 |
| 查询 | `ListComplaintsJSON(targetDBIDStr)` | JSON 数组 |
| 操作 | `SendChannelMessage(channelIDStr, message)` | 错误信息 |
| 操作 | `SendTextMessage(targetMode, targetIDStr, message)` | 错误信息 |
| 操作 | `MoveToChannel(channelIDStr, password)` | 错误信息 |
| 操作 | `Poke(clidStr, message)` | 错误信息 |
| 操作 | `SendVoice(data, codec)` | 错误信息 |
| 操作 | `CreateChannelJSON(name, propertiesJSON)` | 新频道 ID |
| 操作 | `EditChannelJSON(channelIDStr, propertiesJSON)` | 错误信息 |
| 操作 | `DeleteChannel(channelIDStr, force)` | 错误信息 |
| 操作 | `UpdateSelfJSON(propertiesJSON)` | 错误信息 |
| 操作 | `KickClient(clid, reasonID, reasonMsg)` | 错误信息 |
| 操作 | `AddBan(ip, name, uid, timeSeconds, reason)` | 错误信息 |
| 操作 | `DeleteBan(banIDStr)` | 错误信息 |
| 操作 | `UseToken(token)` | 错误信息 |
| 操作 | `AddComplaint(targetDBIDStr, message)` | 错误信息 |
#### kotlin_api.go 新增方法
| 分类 | 方法 | 返回 |
|------|------|------|
| Identity | `GenerateIdentity(securityLevel)` | 序列化的 identity 字符串 |
| Identity | `ConnectWithIdentity(identityStr, host, nickname, password, defaultChannel, defaultChannelPassword, cb)` | 错误信息 |
| 查询 | `FindChannelsJSON(pattern)` | JSON 数组 |
| 查询 | `FindClientByNameJSON(nickname)` | JSON 对象 |
| 查询 | `FindClientByDBIDJSON(dbidStr)` | JSON 对象 |
| 操作 | `MoveClient(clientID, channelIDStr, password)` | 错误信息 |
| 操作 | `MoveChannel(channelIDStr, parentIDStr, orderStr)` | 错误信息 |
| 操作 | `DeleteAllBans()` | 错误信息 |
| 操作 | `DeleteComplaint(targetDBIDStr, fromDBIDStr)` | 错误信息 |
| 文件 | `FileTransferInitUploadJSON(channelIDStr, path, size, overwrite)` | JSON 对象 |
| 文件 | `FileTransferInitDownloadJSON(channelIDStr, path)` | JSON 对象 |
| 文件 | `DeleteFile(channelIDStr, pathsJSON)` | 错误信息 |
| 批量 | `GetInitialSyncJSON()` | JSON 对象 |
Binary file not shown.
File diff suppressed because it is too large Load Diff
+261
View File
@@ -0,0 +1,261 @@
=============================================================
TeamSpeak - Software Development Kit Changelog
Copyright TeamSpeak Systems GmbH
http://www.teamspeak.com
=============================================================
+ Added feature or noticable improvement
- Bug fix or something removed
* Changed or Information
! Important - Take note!
=============================================================
=== SDK Release 3.5.2 17 Jun 2026
* Improved connection stability under packet loss
- Client(Windows): fixed an occasional crash on shutdown
- Client(Windows): fixed rare crash on device format change
=== SDK Release 3.5.1 03 Jun 2026
* Maintenance release with minor internal improvements
=== SDK Release 3.5.0 27 May 2026
! Server: CVE-2026-4390
Use-After-Free via Inconsistent Connection State Management Leading to Denial-of-Service:
A vulnerability in connection state handling could allow authenticated remote attackers
to trigger denial-of-service conditions, potentially resulting in service instability
or server restarts.
! Server: CVE-2026-4392
Assertion Failure Triggered by Crafted Input Leading to Denial-of-Service:
A vulnerability in input validation could allow unauthenticated remote attackers to
trigger denial-of-service conditions, including service instability or server restarts.
! Server: ts3server_initServerLib signature changed
! Client: struct ClientUIFunctions layout changed
Please always update the headers alongside the binaries
* iOS Soundbackend is now built into the client library, no separate framework required
=== SDK Release 3.4.0 20 Mar 2024
+ Apple: The server library is now available for arm64 and distributed as an xcframework
* Apple: xcframework packages have been updated to include modulemaps. This enables the
use of @import TS3Client/TS3Server statements for automatic header file inclusion,
simplifying Swift integration
- Fixed a crash occurring on arm Macs after initializing the client library
+ Modification in client and server libraries to ensure interoperability between
accounting versions 1 and 2 (known as key and key2 respectively).
This supports a smoother transitions to newer SDKs.
=== SDK Release 3.3.1 02 Feb 2023
* Adjustments for Mac App Store compliance
* Frameworks Folder is now a tar.gz inside the zip due to issues with other platforms
(Path length on windows, Symlinks)
* Linux: The binaries of this release are built against glibc 2.31
* Apple: In addition to the xcframework, dylibs are provided for macOS
=== SDK Release 3.3.0 02 Nov 2022
! On any target except iOS the client library contains a default sound backend
-> From your deployment please remove:
coreaudio_soundbackend.dylib on MacOS
windows_audio_session_[platform].dll on Windows
libpulseaudio[platform].so on Linux
opensles.so on Android
as those are now built-in.
Please note:
On Android it's still recommended to use the Java (Kotlin) SB.
Non-default external sound backends can still be deployed if desired, like:
Alsa on Linux, DirectSound on Windows
* Updated System requirement: iOS 11
- Removed armv7 on iOS
* Restored Mac and iOS compatibility with latest Apple App Store requirements
! Added native support for Apple Silicon
+ Apple: Client library is now distributed as xcframework
+ iOS: Sound backend is now distributed as xcframework
* Fixed an issue with licenses
* To kickstart testing, prebuilt samples are included for select platforms
=== SDK Release 3.2.0 05 Nov 2021
! getCaptureDeviceList and getPlaybackDeviceList have slightly changed
on windows. Please have a look at the documentation if you use those
functions
+ Added Win32 server
+ Added 32bit examples
- Fixed issues with zero playback or capture devices
- Fixed issue with Airpods on MacOS
- Fixed client bug hard limiting client count
- Various internal updates
=== SDK Release 3.1.1.0 14 Jan 2021
+ For iOS, there's now a xcframework provided
- Fixed linking of samples
- Fixed an issue with Android soundbackend
- Fixed a rare issue where connect would take a break at
ConnectStatus::Establishing
- Android Timber dependency removed
=== SDK Release 3.1.0.0 31 Aug 2020
! Minimum Versions increased:
Windows to Windows 7
Android to Lollipop (5.0, API Level 21)
iOS to 11.0
! Mac OS and FreeBSD Server have been removed, it is adviced to use docker to
run it on these platforms
! Linux x86 server has been removed, it is recommended to use the arm64 version
! AGC is now on playback
! iOS and MacOS client libraries are now delivered as frameworks for improved
convenience
! If you already have an sdk license issued before 2018, you need to contact
sales at bizdev@teamspeak.com to upgrade your license in order for it to work reliably on this SDK
+ Added Armv7, Armv8 client and server on Linux
+ New audio dsp algorithms for Automatic Gain Control, Comfort Noise, Denoiser
and Echo Cancellation
+ Added Echo Reduction Ducker and Typing Suppression algorithms
+ Client SDK: onEditCapturedVoiceDataPreprocessEvent
+ Client SDK: TEST_MODE_TALK_STATUS_CHANGES_ONLY to LocalTestMode enumeration
+ Client SDK: getWhisperReceiveWhitelist, isWhisperReceiveWhitelisted,
setWhisperReceiveWhitelist
+ Client SDK: setKeyPressedDuringChunk, getGlobalConfigValueAsInt,
setGlobalConfigValue
+ ChannelProperties: CHANNEL_UNIQUE_IDENTIFIER
* Client SDK: requestClientMove, requestClientKickFromChannel,
requestClientKickFromServer now take an array of client IDs
* Client SDK: requestServerVariables now accepts a return code
=== SDK Release 3.0.4.4 30 May 2018
+ Added Android and iOS soundbackends
System requirements: iOS 10 or later, Android 4.1 or later
+ Android got two soundbackends to choose from:
1) OpenSL ES C++ based (see examples/client_android), which is delivered as a native shared library.
2) AudioRecord Java based (see examples/client_android_javasound), which is delivered as Kotlin source code.
+ Added samples to demonstrate mobile soundbackends
* Updated Android JNI wrapper, new function ts3client_android_initJni to initialize the TeamSpeak
native library in one step
=== SDK Release 3.0.4 27 Feb 2016
+ Added IPv6 support
+ Added ts3client_startConnectionWithChannelID to clientlib to allow specifying the default channel
as ID
+ Added get/set channel/client variables as uint64 to serverlib
+ Added 64 bit platform support for android
+ Added a new server API call "ts3server_createVirtualServer2" that will create one virtual server
with all the required channels configured in one call. See the documentation for more details,
and our new server_creation_params example
+ Added new logtarget LogType_SYSLOG. Does not work on Windows. Logs to system syslog facility.
+ Added TEST_MODE_VOICE_LOCAL_AND_REMOTE status for ts3client_setLocalTestMode. In this mode, the
client hears both its own input, and the sound of remote clients.
* public_errors.h now defines the error codes as enums, instead of const unsigned int, to make it
easier to include this file in c projects
* Reimplemented file transfer code
* ts3client_getTransferFilePath and ts3client_getTransferFileRemotePath do now not return a
trailing '/' character
! Starting this release we have a new directory structure. For all platforms the shared libraries
(dll/so/dylib) are in bin directry, and static libraries (.lib/.a) are in lib directory
! Starting this release we have dropped the platform suffix for the ts3client and ts3server
libraries. For example ts3client_win32.dll and ts3client_win64.dll are now both called
ts3client.dll and are located in different directories
! 3.0.4 will be the last sdk supporting windows xp
- Lots of other internal improvements that came from TeamSpeak 3.1 client and 3.0.13 server
=== SDK Release 3.0.3.2 29 Jun 2015
- Fixed issue with offline licenses
- Fixed utf8 conversion issues with invalid utf8 strings
- Fixed windows audio session backend error reporting issues
=== SDK Release 3.0.3.1 24 Apr 2015
! Fixed critical bug causing SDK license not being accepted
- Fixed missing build number on FreeBSD server
=== SDK Release 3.0.3 30 Mar 2015
! Callbacks in the client are now asynchronous
+ Added Opus voice codec
+ Added SecuritySalt/SecurityHash mechanism. Note this makes 3.0.3 and 3.0.2
clients/servers incompatible.
+ Server can disable selected client commands
+ Added callbacks for lots of server function to enable custom permissions
+ Added custom password checks.
+ Added new CHANNEL_DELETE_DELAY param for server side channel creation
+ Added filetransfer support
+ Mobile SDKs (Android, iOS) are now included in the TeamSpeak SDK package
+ Android: Added x86 support
+ iOS: Added armv7s and arm64 to device and x86_64 to simulator
+ iOS: Changed std lib from libstdc++ to libc++
* Updated example projects to Visual Studio 2013
=== SDK Release 3.0.2 15 May 2012
+ Added function calls for communication with a provisioning server, which is
only available in special scenarios on request
- onUpdateClientEvent callback now passes an invoker block for the cases where
a client was updated by somebody else than himself
- numerous bug fixes and performance improvements
=== SDK Release 3.0.1 14 Sep 2011
+ Update Client Example to include recording of playback data to *.wav file.
- Fix bug that led to the channelSpeakerArray in audio callbacks to contain
the wrong value
- Fix bug that could lead to client crashes in channels with a
latency_factor of 2 or higher
=== SDK Release 3.0.0 05 Aug 2011
! New sound system added. The fmod libraries needed previously are no longer
required to be deployed. Instead the client side now requires a
"soundbackends" folder with a few platform dependent sound backends.
! The ts3client_initClientLib function now requires an additional parameter: A
path where to find the "soundbackends" folder.
! The 3.0.0 SDK server requires 3.0.0 SDK clients, and vice versa. You should
not mix older (-betaX) builds with 3.0.0 or higher builds.
* Most sound related function calls have changed, since the "modeID" now a
string instead of an integer
* Voice data packet encryption is now configurable to save CPU on huge servers,
see the "VIRTUALSERVER_CODEC_ENCRYPTION_MODE" setting to set it.
* Reduced CPU usage on the server side, especially for large servers
* requestChannel(Un)subscribe now takes an array of {client,channel}IDs instead
of only one ID.
+ Added callbacks that allow you to view and change sound data as it passes
through the playback and capture chain. This allows great flexibility:
Recording Audio at various stages, applying sound effects or filters are just
some of the new possibilities.
+ Echo cancellation added
+ Added "CustomDevice" functions that allow you to implement capture and
playback your own way, you will need to feed in audio (capture) and retrieve
audio (playback) regularly. See new custom device example for details.
+ Added ability to playback wave files
- numerous bug fixes and performance improvements
=== SDK Release 3.0.0-beta6 02 Jul 2010
- Fix bug in sdk server that had disabled the talk status callbacks
- Fix bug that lead to some normal channel based chatting not reaching all
clients in the channel
=== SDK Release 3.0.0-beta5 10 Jun 2010
! The beta5 sdk server requires beta5 sdk clients, and the beta5 sdk client
requires a beta5 sdk server. You should not mix older sdk builds with beta5
builds.
- Greatly improved the whispering code. It is now possible to whisper to
clients that do not have you in view. Also note that you need to explicitly
allow any incoming whispers, use the new allowWhispersFrom function (possibly
from within the onIgnoredWhisperEvent callback)
- onTalkStatusChangeEvent now has a isReceivedWhisper parameter telling you if
this is a whisper message or regular non whisper communication.
- Channel Codec now has an additional parameter, the codec latency factor. The
default is 1, which results in the same behavior as pre beta5. Higher values
lead to less voice packets sent per second meaning higher delay but less
bandwidth usage.
- server side onTextMessageEvent callback split into two callbacks, one for
messages to the server, one for messages to a channel
- numerous bug fixes and performance improvements
!skipped beta4
=== SDK Release 3.0.0-beta3 27 Jan 2010
! The beta3 sdk server requires beta3 sdk clients, you cannot connect to a new
beta3 sdk server with an older sdk client.
! Switched channelIDs, logIDs, serverIDs, serverConnectionHandlerIDs, banIDs,
offlineMessageIDs from anyID to uint64
* changed parameters of onTextMessageEvent
+ added new onServerProtocolEvent callback that triggers uppon connect telling
you which protocol version the server is running
- numerous bug fixes and performance improvements
=== SDK Release 3.0.0-beta2 20 Dec 2009
* CLIENT_OUTPUT_MUTED will now mute both speakers and microphone, if really
want to mute the headphones only, use the new CLIENT_OUTPUTONLY_MUTED flag
=== SDK Release 3.0.0-beta1 19 Dec 2009
* Initial beta release
@@ -0,0 +1,23 @@
#ifndef TEAMLOG_LOGTYPES_H
#define TEAMLOG_LOGTYPES_H
enum LogTypes {
LogType_NONE = 0x0000, ///< Logging is disabled
LogType_FILE = 0x0001, ///< Log to regular log file
LogType_CONSOLE = 0x0002, ///< Log to standard output / error
LogType_USERLOGGING = 0x0004, ///< User defined logging. Will call the \ref ServerLibFunctions.onUserLoggingMessageEvent callback for every message to be logged
LogType_NO_NETLOGGING = 0x0008, ///< Not used
LogType_DATABASE = 0x0010, ///< Log to database (deprecated, server only, no effect in SDK)
LogType_SYSLOG = 0x0020, ///< Log to syslog (only available on Linux)
};
enum LogLevel {
LogLevel_CRITICAL = 0, ///< these messages stop the program
LogLevel_ERROR, ///< everything that is really bad, but not so bad we need to shut down
LogLevel_WARNING, ///< everything that *might* be bad
LogLevel_DEBUG, ///< output that might help find a problem
LogLevel_INFO, ///< informational output, like "starting database version x.y.z"
LogLevel_DEVEL ///< developer only output (will not be displayed in release mode)
};
#endif //TEAMLOG_LOGTYPES_H
@@ -0,0 +1,58 @@
#ifndef CLIENTLIB_SDK_H
#define CLIENTLIB_SDK_H
// system
#include <stdlib.h>
// own
#include "teamspeak/public_definitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets the client to which to transmit voice. Stops standard channel voice transmission.
*
* The client will still receive voice from their current channel, however their voice will not be transmitted to their
* current channel anymore. If this call is successful (check onServerErrorEvent) then voice of the specified client
* will be transmitted to all specified channels and all the specified clients. Pass 0 to both target parameter arrays
* to restore default behavior of transmitting voice to current channel. You will receive an onServerErrorEvent with the
* passed returnCode indicating whether or not the operation was successful.
*
* @param server_connection_handler_id the connection handler on which to set the whisper list
* @param client_id the client to set the whisper list for. Set to 0 or your own client ID to set your own whisper list.
* @param channel_ids an array of channel ids to transmit voice to.
* @param channel_ids_size number of elements in aforementioned array.
* @param client_ids a zero terminated array of client ids to transmit voice to.
* @param client_ids_size number of elements in aforementioned array.
* @param impersonate if the target client is a webrtc client, the voice packets will look like as if they have been
* send by the invoking client id
* @param return_code a c string to identify this request in callbacks. Pass an empty string if unused.
* @return An error code from the @ref Ts3ErrorType enum indicating either success or the failure reason
*/
EXPORTDLL unsigned int ts_client_request_client_set_whisper_list(uint64 server_connection_handler_id, anyID client_id,
const uint64* channel_ids,
int channel_ids_size,
const anyID* client_ids,
int client_ids_size, int impersonate,
const char* return_code);
/**
* @brief Send a binary-serialized ClientCommandRequest protobuf to the client library.
*
* The response will be delivered asynchronously via the onProtoResponse callback
* as a serialized ClientCommandResponse protobuf.
*
* @param data Pointer to serialized ClientCommandRequest protobuf bytes
* @param size Size of the serialized data in bytes
* @param return_code Caller-provided string to correlate the response in onProtoResponse. May be NULL.
* @return An error code: ERROR_ok on successful dispatch, ERROR_parameter_invalid on parse failure
*/
EXPORTDLL unsigned int ts3client_postProtoCommand(const void* data, size_t size, const char* return_code);
#ifdef __cplusplus
}
#endif
#endif // CLIENTLIB_SDK_H
@@ -0,0 +1,635 @@
#ifndef PUBLIC_DEFINITIONS_H
#define PUBLIC_DEFINITIONS_H
#include "teamlog/logtypes.h"
#define TS3_MAX_SIZE_CHANNEL_NAME 40 // channel name maximum length in characters
#define TS3_MAX_SIZE_VIRTUALSERVER_NAME 64 // virtual server name maximum length in characters
#define TS3_MAX_SIZE_CLIENT_NICKNAME 64 // client display name length limit in characters
#define TS3_MIN_SIZE_CLIENT_NICKNAME 3 // client display name minimum length in characters
#define TS3_MAX_SIZE_REASON_MESSAGE 80 // length limit in characters for kick, move, etc reasons
#define TS3_MAX_SIZE_TEXTMESSAGE 8192 // text message length limit, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_TOPIC 255 // channel topic lengt limith, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_DESCRIPTION 8192 // channel description length limit, measured in bytes (utf8 encoded)
// server welcome message length limit measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_VIRTUALSERVER_WELCOMEMESSAGE 1024
#define TS3_SIZE_MYTSID 44
// minimum amount of seconds before a clientID that was in use can be assigned to a new client
#define TS3_MIN_SECONDS_CLIENTID_REUSE 300
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32)
typedef unsigned __int16 anyID;
typedef unsigned __int64 uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __declspec(dllexport)
#else
#define EXPORTDLL
#endif
#endif
#else
#include <stdint.h>
typedef uint16_t anyID;
typedef uint64_t uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __attribute__((visibility("default")))
#else
#define EXPORTDLL
#endif
#endif
#endif
enum Visibility
{
ENTER_VISIBILITY = 0, ///< Client joined from an unsubscribed channel, or joined the server.
RETAIN_VISIBILITY, ///< Client switched from one subscribed channel to a different subscribed channel.
LEAVE_VISIBILITY ///< Client switches to an unsubscribed channel, or disconnected from server.
};
enum ConnectStatus
{
STATUS_DISCONNECTED = 0, ///< There is no activity to the server, this is the default value
STATUS_CONNECTING, ///< We are trying to connect, we haven't got a client id yet, we haven't been accepted by the server
STATUS_CONNECTED, ///< The server has accepted us, we can talk and hear and we have a client id, but we don't
///< have the channels and clients yet, we can get server infos (welcome msg etc.)
STATUS_CONNECTION_ESTABLISHING, ///< we are connected and we are visible
STATUS_CONNECTION_ESTABLISHED, ///< we are connected and we have the client and channels available
};
enum LocalTestMode
{
TEST_MODE_OFF = 0,
TEST_MODE_VOICE_LOCAL_ONLY,
TEST_MODE_VOICE_LOCAL_AND_REMOTE,
TEST_MODE_TALK_STATUS_CHANGES_ONLY
};
enum TalkStatus
{
STATUS_NOT_TALKING = 0, ///< client is not talking
STATUS_TALKING = 1, ///< client is talking
STATUS_TALKING_WHILE_DISABLED = 2, ///< client is talking while the microphone is muted (only valid for own client)
};
enum CodecType
{
CODEC_SPEEX_NARROWBAND = 0, ///< (deprecated) mono, 16bit, 8kHz, bitrate dependent on the quality setting
CODEC_SPEEX_WIDEBAND, ///< (deprecated) mono, 16bit, 16kHz, bitrate dependent on the quality setting
CODEC_SPEEX_ULTRAWIDEBAND, ///< (deprecated) mono, 16bit, 32kHz, bitrate dependent on the quality setting
CODEC_CELT_MONO, ///< (deprecated) mono, 16bit, 48kHz, bitrate dependent on the quality setting
CODEC_OPUS_VOICE, ///< mono, 16bit, 48khz, bitrate dependent on the quality setting, optimized for voice
CODEC_OPUS_MUSIC, ///< stereo, 16bit, 48khz, bitrate dependent on the quality setting, optimized for music
};
enum CodecEncryptionMode
{
CODEC_ENCRYPTION_PER_CHANNEL = 0, ///< voice data encryption decided per channel
CODEC_ENCRYPTION_FORCED_OFF, ///< voice data encryption disabled
CODEC_ENCRYPTION_FORCED_ON, ///< voice data encryption enabled
};
enum TextMessageTargetMode
{
TextMessageTarget_CLIENT = 1, ///< Message is a private message to another client
TextMessageTarget_CHANNEL, ///< Message is sent to a channel, received by all clients in that channel at the time
TextMessageTarget_SERVER, ///< Message is sent to every client on the server
TextMessageTarget_MAX
};
enum MuteInputStatus
{
MUTEINPUT_NONE = 0, ///< Microphone is not muted, audio is sent to the server
MUTEINPUT_MUTED, ///< Microphone is muted, no audio is transmitted to the server
};
enum MuteOutputStatus
{
MUTEOUTPUT_NONE = 0, ///< Speaker is active, server is sending us audio
MUTEOUTPUT_MUTED, ///< Speaker is muted, server is not sending audio to us
};
enum HardwareInputStatus
{
HARDWAREINPUT_DISABLED = 0, ///< no capture device opened
HARDWAREINPUT_ENABLED, ///< capture device open
};
enum HardwareOutputStatus
{
HARDWAREOUTPUT_DISABLED = 0, ///< no playback device opened
HARDWAREOUTPUT_ENABLED, ///< playback device open
};
enum InputDeactivationStatus
{
INPUT_ACTIVE = 0, ///< Audio is captured from the capture device.
INPUT_DEACTIVATED = 1, ///< No audio is captured from the capture device.
};
enum ReasonIdentifier
{
REASON_NONE = 0, ///< no reason data
REASON_MOVED = 1, ///< client was moved
REASON_SUBSCRIPTION = 2, // no reason data
REASON_LOST_CONNECTION = 3, // reasonmsg=reason
REASON_KICK_CHANNEL = 4, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER = 5, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER_BAN = 6, //{SectionInvoker} reasonmsg=reason bantime=time //{SectionInvoker} is only added server->client
REASON_SERVERSTOP = 7, // reasonmsg=reason
REASON_CLIENTDISCONNECT = 8, // reasonmsg=reason
REASON_CHANNELUPDATE = 9, // no reason data
REASON_CHANNELEDIT = 10, //{SectionInvoker}
REASON_CLIENTDISCONNECT_SERVER_SHUTDOWN = 11, // reasonmsg=reason
};
enum Protocol_Encryption_Cipher
{
AES_128 = 0b00000000,
AES_256 = 0b00000001,
PROTOCOL_ENCRYPTION_CIPHER_END_MARKER,
RESERVED = 0b00010000, // reserved until puzzle v2 is fully released, then can be reused
PUZZLE_2 = 0b00100000,
};
enum ChannelProperties
{
CHANNEL_NAME = 0, ///< String. Read/Write. Name of the channel. Always available.
CHANNEL_TOPIC, ///< String. Read/Write. Short single line text describing what the channel is about. Always available.
CHANNEL_DESCRIPTION, ///< String. Read/Write. Arbitrary text (up to 8k bytes) with information about the channel.
///< Must be requested (\ref ts3client_requestChannelDescription)
CHANNEL_PASSWORD, ///< String. Read/Write. Password of the channel. Read access is limited to the server. Clients
///< will only ever see the last password they attempted to use when joining the channel. Always available.
CHANNEL_CODEC, ///< Integer. Read/Write. The codec this channel is using. One of the values from the \ref CodecType
///< enum. Always available.
CHANNEL_CODEC_QUALITY, ///< Integer. Read/Write. The quality setting of the channel. Valid values are 0 to 10 inclusive.
///< Higher value means better voice quality but also more bandwidth usage. Always available.
CHANNEL_MAXCLIENTS, ///< Integer. Read/Write. The number of clients that can be in the channel simultaneously.
///< Always available.
CHANNEL_MAXFAMILYCLIENTS, ///< Integer. Read/Write. The total number of clients that can be in this channel and all
///< sub channels of this channel. Always available.
CHANNEL_ORDER, ///< UInt64. Read/Write. The ID of the channel below which this channel should be displayed. If 0
///< the channel is sorted at the top of the current level. Always available.
CHANNEL_FLAG_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when empty.
///< Permanent channels are stored to the database and available after server restart. SDK
///< users will need to take care of restoring channel at server start on their own.
///< Mutually exclusive with \ref CHANNEL_FLAG_SEMI_PERMANENT. Always available.
CHANNEL_FLAG_SEMI_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when
///< empty. Semi permanent channels are not stored to disk and gone after server
///< restart but remain while empty. Mutually exclusive with \ref
///< CHANNEL_FLAG_PERMANENT. Always available.
CHANNEL_FLAG_DEFAULT, ///< Integer. Read/Write. Boolean (1/0). The default channel is the channel that all clients
///< are located in when they join the server, unless the client explicitly specified a
///< different channel when connecting and is allowed to join their preferred channel. Only
///< one channel on the server can have this flag set. The default channel must have \ref
///< CHANNEL_FLAG_PERMANENT set. Always available.
CHANNEL_FLAG_PASSWORD, ///< Integer. Read/Write. Boolean (1/0) indicating whether this channel is password protected.
///< When removing or setting \ref CHANNEL_PASSWORD you also need to adjust this flag.
CHANNEL_CODEC_LATENCY_FACTOR, ///< (deprecated) Integer. Read/Write. Allows to increase packet size, reducing
///< bandwith at the cost of higher latency of voice transmission. Valid values are
///< 1-10 inclusive. 1 is the default and offers the lowest latency. Always available.
CHANNEL_CODEC_IS_UNENCRYPTED, ///< Integer. Read/Write. Boolean (1/0). If 0 voice data is encrypted, if 1 the voice
///< data is not encrypted. Only used if the server \ref
///< VIRTUALSERVER_CODEC_ENCRYPTION_MODE is set to \ref CODEC_ENCRYPTION_PER_CHANNEL.
///< Always available.
CHANNEL_SECURITY_SALT, ///< String. Read/Write. SDK Only, not used by TeamSpeak. This channels security hash. When
///< a client joins their \ref CLIENT_SECURITY_HASH is compared to this value, to allow or
///< deny the client access to the channel. Used to enforce clients joining the server with
///< specific identity and \ref CLIENT_META_DATA. See SDK Documentation about this feature
///< for further details. Always available.
CHANNEL_DELETE_DELAY, ///< UInt64. Read/Write. Number of seconds deletion of temporary channels is delayed after
///< the last client leaves the channel. Channel is only deleted if empty when the delete
///< delay expired. Always available.
CHANNEL_UNIQUE_IDENTIFIER, ///< String. Read only. An identifier that uniquely identifies a channel. Available in
///< Server >= 3.10.0
CHANNEL_ENDMARKER,
};
enum ClientProperties
{
CLIENT_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Public Identity, can be used to identify a client
///< installation. Remains identical as long as the client keeps using the same
///< identity. Available for visible clients.
CLIENT_NICKNAME, ///< String. Read/Write. Display name of the client. Available for visible clients.
CLIENT_VERSION, ///< String. Read only. Version String of the client used. For clients other than ourself this
///< needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_PLATFORM, ///< String. Read only. Operating system used by the client. For other clients other than ourself
///< this needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_FLAG_TALKING, ///< Integer. Read only. Whether the client is talking. Available on clients that are either
///< whispering to us, or in our channel.
CLIENT_INPUT_MUTED, ///< Integer. Read/Write. Microphone mute status. Available for visible clients. One of the
///< values from the \ref MuteInputStatus enum.
CLIENT_OUTPUT_MUTED, ///< Integer. Read/Write. Speaker mute status. Speaker mute implies microphone mute. Available
///< for visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_OUTPUTONLY_MUTED, ///< Integer. Read/Write. Speaker mute status. Microphone may be active. Available for
///< visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_INPUT_HARDWARE, ///< Integer. Read only. Indicates whether a capture device is open. Available for visible
///< clients. One of the values from the \ref HardwareInputStatus enum.
CLIENT_OUTPUT_HARDWARE, ///< Integer. Read only. Indicates whether a playback device is open. Available for visible
///< clients. One of the values from the \ref HardwareOutputStatus enum.
CLIENT_INPUT_DEACTIVATED, ///< Integer. Read/Write. Not available server side. Local microphone mute status.
///< Available only for own client. Used to implement Push To Talk. One of the values from
///< the \ref InputDeactivationStatus enum.
CLIENT_IDLE_TIME, ///< UInt64. Read only. Seconds since last activity. Available only for own client.
CLIENT_DEFAULT_CHANNEL, ///< String. Read only. User specified channel they joined when connecting to the server.
///< Available only for own client.
CLIENT_DEFAULT_CHANNEL_PASSWORD, ///< String. Read only. User specified channel password for the channel they
///< attempted to join when connecting to the server. Available only for own
///< client.
CLIENT_SERVER_PASSWORD, ///< String. Read only. User specified server password. Available only for own client.
CLIENT_META_DATA, ///< String. Read/Write. Can be used to store up to 4096 bytes of information on clients. Not
///< used by TeamSpeak. Available for visible clients.
CLIENT_IS_MUTED, ///< Integer. Read only. Not available server side. Indicates whether we have muted the client
///< using \ref ts3client_requestMuteClients. Available for visible clients other than ourselves.
CLIENT_IS_RECORDING, ///< Integer. Read only. Indicates whether the client is recording incoming audio. Available
///< for visible clients.
CLIENT_VOLUME_MODIFICATOR, ///< Integer. Read only. Volume adjustment for this client as set by \ref
///< ts3client_setClientVolumeModifier. Available for visible clients.
CLIENT_VERSION_SIGN, ///< String. Read only. TeamSpeak internal signature.
CLIENT_SECURITY_HASH, ///< String. Read/Write. This clients security hash. Not used by TeamSpeak, SDK only. Hash is
///< provided by an outside source. A channel will use the security salt + other client data
///< to calculate a hash, which must be the same as the one provided here. See SDK
///< documentation about Client / Channel Security Hashes for more details.
CLIENT_ENCRYPTION_CIPHERS, ///< String. Read only. SDK only. List of available ciphers this client can use.
CLIENT_IS_STREAMING, ///< bool. Read only, Is currently streaming.
CLIENT_ENDMARKER,
};
enum VirtualServerProperties
{
VIRTUALSERVER_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Unique identifier for a virtual server, does not
///< change on server restart. Available if \ref ts3client_getConnectionStatus
///< is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_NAME, ///< String. Read/Write. The virtual server display name. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_WELCOMEMESSAGE, ///< String. Read/Write. The welcome message displayed to clients on connect.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED. Not
///< updated automatically when changed, updates need to be requested (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_PLATFORM, ///< String. Read only. The operating system the server is running on. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_VERSION, ///< String. Read only. The server software version string. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_MAXCLIENTS, ///< UInt64. Read/Write. The maximum number of clients that can be connected
///< simultaneously. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_PASSWORD, ///< String. Read/Write. The server password. Read access is limited to the server. Clients
///< will only get the password they supplied when connecting. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_CLIENTS_ONLINE, ///< UInt64. Read only. The current number of clients connected to the server,
///< including query connections. Only available on request (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_CHANNELS_ONLINE, ///< UInt64. Read only. The current number of channels on the server. Only
///< available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CREATED, ///< Integer. Read only. The time this virtual server was created as unix timestamp.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_UPTIME, ///< UInt64. Read only. Number of seconds that have passed since the virtual server was
///< started. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CODEC_ENCRYPTION_MODE, ///< Integer. Read/Write. Boolean (1/0) that specifies if voice data is encrypted
///< during transfer. One of the values from the \ref CodecEncryptionMode enum.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_ENCRYPTION_CIPHERS, ///< String. Read/Write. Comma separated list of available ciphers to encrypt the
///< connection. The server will use the first cipher in the list that is also
///< listed in the \ref CLIENT_ENCRYPTION_CIPHERS of the connecting client.
///< Clients will fail to connect if no match is found. Always available.
VIRTUALSERVER_ADDRESS, ///< Any resolvable address for the specific virtual server
VIRTUALSERVER_VERSION_SIGN, ///< String. Read only. Signature of Platform and Version.
VIRTUALSERVER_ENDMARKER,
VIRTUALSERVER_FILEBASE = 24, ///< String. Read only. The path to the base directory used to store files
///< transferred using file transfer. Available only on the server. Is set by \ref
///< ts3server_enableFileManager
VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH = 29, ///< UInt64. Read/Write. Maximum traffic in bytes the server can
///< use for file transfer downloads. Only available on request
///< (\ref ts3client_requestServerVariables).
VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH = 30, ///< UInt64. Read/Write. Maximum traffic in bytes the server can use
///< for file transfer uploads. Only available on request (=>
///< requestServerVariables)
VIRTUALSERVER_LOG_FILETRANSFER = 64 ///< Integer. Read/Write. Boolean (1/0) indicating whether to include file
///< transfer activities (uploading or downloading of files) in the server log.
///< Always available.
};
/**
* Various connection properties.
* These are all read only, and except for your own client must be requested using \ref ts3client_requestConnectionInfo
*/
enum ConnectionProperties
{
CONNECTION_PING = 0, ///< UInt64. Round trip latency for the connection based on the last 5 seconds. On the server
///< this is the average across all connected clients for the last 5 seconds.
CONNECTION_PING_DEVIATION, ///< Double. Standard deviation for the round trip latency in \ref CONNECTION_PING
CONNECTION_CONNECTED_TIME, ///< UInt64. Seconds the client has been connected.
CONNECTION_IDLE_TIME, ///< UInt64. Time in seconds since the last activity (voice transmission, switching channels,
///< changing mic / speaker mute status) of the client.
CONNECTION_CLIENT_IP, ///< String. IP of this client (as seen from the server side)
CONNECTION_CLIENT_PORT, ///< UInt64. Client side port of this client (as seen from the server side)
CONNECTION_SERVER_IP, ///< String. The IP or hostname used to connect to the server. Only available on yourself.
CONNECTION_SERVER_PORT, ///< UInt64. The server port connected to. Only available on yourself.
CONNECTION_PACKETS_SENT_SPEECH, ///< UInt64. The number of voice packets transmitted by the client.
CONNECTION_PACKETS_SENT_KEEPALIVE, ///< UInt64. The number of keep alive packets transmitted by the client.
CONNECTION_PACKETS_SENT_CONTROL, ///< UInt64. The number of command & control packets transmitted by the client.
CONNECTION_PACKETS_SENT_TOTAL, ///< UInt64. Total number of packets transmitted by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_SENT_SPEECH, \ref CONNECTION_PACKETS_SENT_KEEPALIVE and
///< \ref CONNECTION_PACKETS_SENT_CONTROL
CONNECTION_BYTES_SENT_SPEECH, ///< UInt64. Outgoing traffic used for voice data by the client.
CONNECTION_BYTES_SENT_KEEPALIVE, ///< UInt64. Outgoing traffic used for keeping the connection alive by the client.
CONNECTION_BYTES_SENT_CONTROL, ///< UInt64. Outgoing traffic used for command & control data by the client.
CONNECTION_BYTES_SENT_TOTAL, ///< UInt64. Total outgoing traffic to the server by this client. Equal to the sum of
///< \ref CONNECTION_BYTES_SENT_SPEECH, \ref CONNECTION_BYTES_SENT_KEEPALIVE and \ref
///< CONNECTION_BYTES_SENT_CONTROL
CONNECTION_PACKETS_RECEIVED_SPEECH, ///< UInt64. Number of voice packets received by the client.
CONNECTION_PACKETS_RECEIVED_KEEPALIVE, ///< UInt64. Number of keep alive packets received by the client.
CONNECTION_PACKETS_RECEIVED_CONTROL, ///< UInt64. Number of command & control packets received by the client.
CONNECTION_PACKETS_RECEIVED_TOTAL, ///< UInt64. Total number of packets received by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_RECEIVED_SPEECH, \ref
///< CONNECTION_PACKETS_RECEIVED_KEEPALIVE and \ref
///< CONNECTION_PACKETS_RECEIVED_CONTROL
CONNECTION_BYTES_RECEIVED_SPEECH, ///< UInt64. Incoming traffic used by the client for voice data.
CONNECTION_BYTES_RECEIVED_KEEPALIVE, ///< UInt64. Incoming traffic used by the client to keep the connection alive.
CONNECTION_BYTES_RECEIVED_CONTROL, ///< UInt64. Incoming traffic used by the client for command & control data.
CONNECTION_BYTES_RECEIVED_TOTAL, ///< UInt64. Total incoming traffic used by the client. Equal to the sum of \ref
///< CONNECTION_BYTES_RECEIVED_SPEECH, \ref CONNECTION_BYTES_RECEIVED_KEEPALIVE and
///< \ref CONNECTION_BYTES_RECEIVED_CONTROL
CONNECTION_PACKETLOSS_SPEECH, ///< Double. Percentage points of voice packets for the client that did not arrive at
///< the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_KEEPALIVE, ///< Double. Percentage points of keep alive packets for the client that did not
///< arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_CONTROL, ///< Double. Percentage points of command & control packets for the client that did
///< not arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_TOTAL, ///< Double. Cumulative chance in percentage points with which a packet round trip
///< failed because a packet was lost
CONNECTION_SERVER2CLIENT_PACKETLOSS_SPEECH, ///< Double. Probability with which a voice packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< server was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the server was not
///< received by the client.
CONNECTION_CLIENT2SERVER_PACKETLOSS_SPEECH, ///< Double. Probability with which a speech packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< client was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the client was not
///< received by the server.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes sent for speech data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes sent for keepalive data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes sent for control data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes sent in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second sent for speech data, averaged over the
///< last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second sent for keepalive data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second sent for control data, averaged over
///< the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second sent, averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes received for speech data in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes received for keepalive data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes received for control data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes received in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second received for speech data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second received for keepalive data,
///< averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second received for control data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second received, averaged over the last minute.
CONNECTION_DUMMY_0,
CONNECTION_DUMMY_1,
CONNECTION_DUMMY_2,
CONNECTION_DUMMY_3,
CONNECTION_DUMMY_4,
CONNECTION_DUMMY_5,
CONNECTION_DUMMY_6,
CONNECTION_DUMMY_7,
CONNECTION_DUMMY_8,
CONNECTION_DUMMY_9,
CONNECTION_FILETRANSFER_BANDWIDTH_SENT, ///< UInt64. Current file transfer upstream activity in bytes per second.
///< Only available on request (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, ///< UInt64. Current file transfer downstream activity in bytes per
///< second. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, ///< UInt64. Total downstream traffic, in bytes, used for file
///< transfer since the server was started. Only available on request
///< (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, ///< UInt64. Total upstream traffic, in bytes, used for file transfer
///< since the server was started. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_ENDMARKER
};
/**
* Describes a client position in 3 dimensional space, used for 3D Sound.
*/
typedef struct
{
float x; ///< X co-ordinate in 3D space.
float y; ///< Y co-ordinate in 3D space.
float z; ///< Z co-ordinate in 3D space.
} TS3_VECTOR;
enum GroupWhisperType
{
GROUPWHISPERTYPE_SERVERGROUP = 0, ///< Whisper list consists of server groups
GROUPWHISPERTYPE_CHANNELGROUP = 1, ///< Whisper list consists of channel groups
GROUPWHISPERTYPE_CHANNELCOMMANDER = 2, ///< whisper to channel commanders
GROUPWHISPERTYPE_ALLCLIENTS = 3, ///< whisper to all clients
GROUPWHISPERTYPE_ENDMARKER,
};
enum GroupWhisperTargetMode
{
GROUPWHISPERTARGETMODE_ALL = 0,
GROUPWHISPERTARGETMODE_CURRENTCHANNEL = 1, ///< Whisper the current channel of the client
GROUPWHISPERTARGETMODE_PARENTCHANNEL = 2, ///< Whisper the parent channel of whatever channel the client is currently in
GROUPWHISPERTARGETMODE_ALLPARENTCHANNELS = 3, ///< Whipser to the parent channel and all their parent channels as well
GROUPWHISPERTARGETMODE_CHANNELFAMILY = 4, ///< Whisper to the current channel and all its sub channels
GROUPWHISPERTARGETMODE_ANCESTORCHANNELFAMILY = 5, ///< Whisper to the current channel, all its parent and sub channels.
GROUPWHISPERTARGETMODE_SUBCHANNELS = 6, ///< Whisper to all sub channels of the current channel of the client
GROUPWHISPERTARGETMODE_ENDMARKER,
};
enum MonoSoundDestination
{
MONO_SOUND_DESTINATION_ALL = 0, ///< Send mono sound to all available speakers
MONO_SOUND_DESTINATION_FRONT_CENTER = 1, ///< Send mono sound to front center speaker if available
MONO_SOUND_DESTINATION_FRONT_LEFT_AND_RIGHT = 2 ///< Send mono sound to front left/right speakers if available
};
enum SecuritySaltOptions
{
SECURITY_SALT_CHECK_NICKNAME = 1, ///< put nickname into security hash
SECURITY_SALT_CHECK_META_DATA = 2 ///< put meta data into security hash
};
/*this enum is used to disable client commands on the server*/
enum ClientCommand
{
CLIENT_COMMAND_requestConnectionInfo = 0, ///< disable client connection info request (client bandwidth usage, ip,
///< port, ping)
CLIENT_COMMAND_requestClientMove = 1, ///< disable moving clients
CLIENT_COMMAND_requestXXMuteClients = 2, ///< disable muting other clients
CLIENT_COMMAND_requestClientKickFromXXX = 3, ///< disable kicking clients
CLIENT_COMMAND_flushChannelCreation = 4, ///< disable creating channels
CLIENT_COMMAND_flushChannelUpdates = 5, ///< disable editing channels
CLIENT_COMMAND_requestChannelMove = 6, ///< disable moving channels
CLIENT_COMMAND_requestChannelDelete = 7, ///< disable deleting channels
CLIENT_COMMAND_requestChannelDescription = 8, ///< disable channel descriptions
CLIENT_COMMAND_requestChannelXXSubscribeXXX = 9, ///< disable being able to see clients in channels other than the
///< current channel the client is in
CLIENT_COMMAND_requestServerConnectionInfo = 10, ///< disable server connection info request (server bandwidth
///< usage, ip, port, ping)
CLIENT_COMMAND_requestSendXXXTextMsg = 11, ///< disable text messaging
CLIENT_COMMAND_filetransfers = 12, ///< disable file transfer
CLIENT_COMMAND_ENDMARKER
};
/* Access Control List*/
enum ACLType
{
ACL_NONE = 0,
ACL_WHITE_LIST = 1,
ACL_BLACK_LIST = 2
};
/* file transfer actions*/
enum FTAction
{
FT_INIT_SERVER = 0, ///< The virtual server is created. result->channelPath can be changed to create a different
///< directory than the default 'virtualserver_x' where x is the virtual server.
FT_INIT_CHANNEL = 1, ///< A channel is created. result->channelPath can be changed to create a different directory
///< then the default 'channel_x' where x is the channel id.
FT_UPLOAD = 2, ///< A file is being uploaded. All values in the result struct can be modified.
FT_DOWNLOAD = 3, ///< A file is being downloaded. All values in the result struct can be modified.
FT_DELETE = 4, ///< A file is being deleted. All values in the result struct can be modified.
FT_CREATEDIR = 5, ///< A directory is being created in a channel. All values in the result struct can be modified.
FT_RENAME = 6, ///< A file or folder is being renamed. The callback will be called twice! Once for the old and then
///< for the new name. All values in the result struct can be modified.
FT_FILELIST = 7, ///< A directory listing is requested. All values in the result struct can be modified.
FT_FILEINFO = 8 ///< Information of a file is requested. All values in the result struct can be modified.
};
/* file transfer status */
enum FileTransferState
{
FILETRANSFER_INITIALISING = 0, ///< File transfer is establishing connection.
FILETRANSFER_ACTIVE, ///< File transfer is in progress
FILETRANSFER_FINISHED, ///< File transfer has finished
};
/* file transfer types */
enum FileTransferType
{
FileListType_Directory = 0, ///< The file entry is a directory
FileListType_File, ///< The file entry is a regular file
};
/* some structs to handle variables in callbacks */
#define MAX_VARIABLES_EXPORT_COUNT 64
struct VariablesExportItem
{
unsigned char itemIsValid; ///< Whether or not there is any data in this item. Ignore this item if this is 0.
unsigned char proposedIsSet; ///< The value in proposed is set. If 0 ignore proposed
const char* current; ///< current value (stored in memory)
const char* proposed; ///< New value to change to (const, so no updates please)
};
struct VariablesExport
{
struct VariablesExportItem items[MAX_VARIABLES_EXPORT_COUNT];
};
struct ClientMiniExport
{
anyID ID; ///< id of the client
uint64 channel; ///< the channel the client is in
const char* ident; ///< client public identity
const char* nickname; ///< client display name
};
/**
* Structure used to describe a file transfer in the \ref ServerLibFunctions.onTransformFilePath callback.
* This describes the original values, and also contains hints for length limitations of the result parameter
* of the callback.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExport
{
uint64 channel; ///< The channel id of the file. 0 if action is \ref FT_INIT_SERVER
const char* filename; ///< utf8 encoded c string containing the original file name as intended by the client.
int action; ///< The action to be performed. One of the values from the \ref FTAction enum. Defines which values of
///< the result struct can be modified.
int transformedFileNameMaxSize; ///< The maximum length the file name can be rewritten to.
int channelPathMaxSize; ///< The maximum length the path can be rewritten to.
};
/**
* Structure to rewrite the file transfer file name and path in the \ref ServerLibFunctions.onTransformFilePath callback.
* The lengths are limited as described in the original parameter.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExportReturns
{
char* transformedFileName; ///< pointer to target file name. Fill the memory pointed to with an utf8 encoded c string
///< containing the new file name. Limited to original->transformedFileNameMaxSize bytes.
char* channelPath; ///< pointer to memory for new path. Fill the memory pointed to with an utf8 encoded c string
///< containing the new path. Limited to original->channelPathMaxSize bytes.
int logFileAction; ///< boolean (1/0). Whether to log this file transfer to the log. Action is not logged regardless
///< of this value if the servers \ref VIRTUALSERVER_LOG_FILETRANSFER property is 0.
};
struct FileTransferCallbackExport
{
anyID clientID; ///< the client who started the file transfer
anyID transferID; ///< local identifier of the transfer that has completed
anyID remoteTransferID; ///< remote identifier of the transfer that has completed
unsigned int status; ///< status of the transfer. One of the values from the \ref FileTransferState enum
const char* statusMessage; ///< utf8 encoded c string containing a human readable description of the status
uint64 remotefileSize; ///< size in bytes of the complete file to be transferred
uint64 bytes; ///< number of bytes transferred. Same as remotefileSize when the transfer completed entirely.
int isSender; ///< boolean. 1 if the server is sending the file. 0 if the server is receiving the file.
};
/*define for file transfer bandwith limits*/
#define BANDWIDTH_LIMIT_UNLIMITED 0xFFFFFFFFFFFFFFFFll
/*defines for speaker locations used by some sound callbacks*/
#ifndef SPEAKER_FRONT_LEFT
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#endif
#define SPEAKER_HEADPHONES_LEFT 0x10000000
#define SPEAKER_HEADPHONES_RIGHT 0x20000000
#define SPEAKER_MONO 0x40000000
#endif /*PUBLIC_DEFINITIONS_H*/
@@ -0,0 +1,217 @@
#ifndef PUBLIC_ERRORS_H
#define PUBLIC_ERRORS_H
//The idea here is: the values are 2 bytes wide, the first byte identifies the group, the second the count within that group
enum Ts3ErrorType {
//general
ERROR_ok = 0x0000, ///< Indicates success.
ERROR_undefined = 0x0001,
ERROR_not_implemented = 0x0002, ///< The attempted operation is not available in this context
ERROR_ok_no_update = 0x0003, ///< Indicates success, but no change occurred. Returned for example upon flushing (e.g. using \ref ts3client_flushChannelUpdates) when all indicated changes already matched the current state.
ERROR_dont_notify = 0x0004,
ERROR_lib_time_limit_reached = 0x0005,
ERROR_out_of_memory = 0x0006, ///< Not enough system memory to perform operation
ERROR_canceled = 0x0007,
ERROR_ok_no_error_event = 0x0008, ///< Indicates success, but no error event was generated. This is used because of the return code management and reduce packets.
//dunno
ERROR_command_not_found = 0x0100,
ERROR_unable_to_bind_network_port = 0x0101, ///< Unspecified failure to create a listening port
ERROR_no_network_port_available = 0x0102, ///< Failure to initialize a listening port for FileTransfer
ERROR_port_already_in_use = 0x0103, ///< Specified port is already in use by a different application
ERROR_command_line_parse_failed = 0x0104, ///< Command line arguments are invalid
ERROR_command_line_exit_version = 0x0105, ///< Command line specified version. The process should exit with code 0 after printing the version.
ERROR_command_line_exit_help = 0x0106, ///< Command line specified help. The process should exit with code 0 after priting the help.
//client
ERROR_client_invalid_id = 0x0200, ///< Client no longer connected
ERROR_client_nickname_inuse = 0x0201, ///< Client name is already in use. Client names must be unique
ERROR_client_protocol_limit_reached = 0x0203, ///< Too many clients on the server
ERROR_client_invalid_type = 0x0204, ///< Function called for normal clients that is only available for query clients or vice versa
ERROR_client_already_subscribed = 0x0205, ///< Attempting to subscribe to a channel already subscribed to
ERROR_client_not_logged_in = 0x0206,
ERROR_client_could_not_validate_identity = 0x0207, ///< Identity not valid or insufficient security level
ERROR_client_invalid_password = 0x0208,
ERROR_client_version_outdated = 0x020a, ///< Server requires newer client version as determined by the min_client_version properties
ERROR_client_is_flooding = 0x020c, ///< Triggered flood protection. Further information is supplied in the extra message if applicable.
ERROR_client_hacked = 0x020d,
ERROR_client_cannot_verify_now = 0x020e,
ERROR_client_login_not_permitted = 0x020f,
ERROR_client_not_subscribed = 0x0210, ///< Action is only available on subscribed channels
//channel
ERROR_channel_invalid_id = 0x0300, ///< Channel does not exist on the server (any longer)
ERROR_channel_protocol_limit_reached = 0x0301, ///< Too many channels on the server
ERROR_channel_already_in = 0x0302, ///< Attempting to move a client or channel to its current channel
ERROR_channel_name_inuse = 0x0303, ///< Channel name is already taken by another channel. Channel names must be unique
ERROR_channel_not_empty = 0x0304, ///< Attempting to delete a channel with clients or sub channels in it
ERROR_channel_can_not_delete_default = 0x0305, ///< Default channel cannot be deleted. Set a new default channel first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_default_require_permanent = 0x0306, ///< Attempt to set a non permanent channel as default channel. Set channel to permanent first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_invalid_flags = 0x0307, ///< Invalid combination of \ref ChannelProperties, trying to remove \ref CHANNEL_FLAG_DEFAULT or set a password on the default channel
ERROR_channel_parent_not_permanent = 0x0308, ///< Attempt to move a permanent channel into a non-permanent one, or set a channel to be permanent that is a sub channel of a non-permanent one
ERROR_channel_maxclients_reached = 0x0309, ///< Channel is full as determined by its \ref CHANNEL_MAXCLIENTS setting
ERROR_channel_maxfamily_reached = 0x030a, ///< Channel tree is full as determined by its \ref CHANNEL_MAXFAMILYCLIENTS setting
ERROR_channel_invalid_order = 0x030b, ///< Invalid value for the \ref CHANNEL_ORDER property. The specified channel must exist on the server and be on the same level.
ERROR_channel_no_filetransfer_supported = 0x030c, ///< Invalid \ref CHANNEL_FILEPATH set for the channel
ERROR_channel_invalid_password = 0x030d, ///< Channel has a password not matching the password supplied in the call
// used in public_rare_errors = 0x030e,
ERROR_channel_invalid_security_hash = 0x030f,
//server
ERROR_server_invalid_id = 0x0400, ///< Chosen virtual server does not exist or is offline
ERROR_server_running = 0x0401, ///< attempting to delete a server that is running. Stop the server before deleting it.
ERROR_server_is_shutting_down = 0x0402, ///< Client disconnected because the server is going offline
ERROR_server_maxclients_reached = 0x0403, ///< Given in the onConnectStatusChange event when the server has reached its maximum number of clients as defined by the \ref VIRTUALSERVER_MAXCLIENTS property
ERROR_server_invalid_password = 0x0404, ///< Specified server password is wrong. Provide the correct password in the \ref ts3client_startConnection / \ref ts3client_startConnectionWithChannelID call.
ERROR_server_is_virtual = 0x0407, ///< Server is in virtual status. The attempted action is not possible in this state. Start the virtual server first.
ERROR_server_is_not_running = 0x0409, ///< Attempting to stop a server that is not online.
ERROR_server_is_booting = 0x040a, // Not used
ERROR_server_status_invalid = 0x040b,
ERROR_server_version_outdated = 0x040d, ///< Attempt to connect to an outdated server version. The server needs to be updated.
ERROR_server_duplicate_running = 0x040e, ///< This server is already running within the instance. Each virtual server may only exist once.
//parameter
ERROR_parameter_quote = 0x0600, // Not used
ERROR_parameter_invalid_count = 0x0601, ///< Attempt to flush changes without previously calling set*VariableAs* since the last flush
ERROR_parameter_invalid = 0x0602, ///< At least one of the supplied parameters did not meet the criteria for that parameter
ERROR_parameter_not_found = 0x0603, ///< Failure to supply all the necessary parameters
ERROR_parameter_convert = 0x0604, ///< Invalid type supplied for a parameter, such as passing a string (ie. "five") that expects a number.
ERROR_parameter_invalid_size = 0x0605, ///< Value out of allowed range. Such as strings are too long/short or numeric values outside allowed range
ERROR_parameter_missing = 0x0606, ///< Neglecting to specify a required parameter
ERROR_parameter_checksum = 0x0607, ///< Attempting to deploy a modified snapshot
//unsorted, need further investigation
ERROR_vs_critical = 0x0700, ///< Failure to create default channel
ERROR_connection_lost = 0x0701, ///< Generic error with the connection.
ERROR_not_connected = 0x0702, ///< Attempting to call functions with a serverConnectionHandler that is not connected. You can use \ref ts3client_getConnectionStatus to check whether the connection handler is connected to a server
ERROR_no_cached_connection_info = 0x0703, ///< Attempting to query connection information (bandwidth usage, ping, etc) without requesting them first using \ref ts3client_requestConnectionInfo
ERROR_currently_not_possible = 0x0704, ///< Requested information is not currently available. You may have to call \ref ts3client_requestClientVariables or \ref ts3client_requestServerVariables
ERROR_failed_connection_initialisation = 0x0705, ///< No TeamSpeak server running on the specified IP address and port
ERROR_could_not_resolve_hostname = 0x0706, ///< Failure to resolve the specified hostname to an IP address
ERROR_invalid_server_connection_handler_id = 0x0707, ///< Attempting to perform actions on a non-existent server connection handler
ERROR_could_not_initialise_input_manager = 0x0708, // Not used
ERROR_clientlibrary_not_initialised = 0x0709, ///< Calling client library functions without successfully calling \ref ts3client_initClientLib before
ERROR_serverlibrary_not_initialised = 0x070a, ///< Calling server library functions without successfully calling \ref ts3server_initServerLib before
ERROR_whisper_too_many_targets = 0x070b, ///< Using a whisper list that contain more clients than the servers \ref VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE property
ERROR_whisper_no_targets = 0x070c, ///< The active whisper list is empty or no clients matched the whisper list (e.g. all channels in the list are empty)
ERROR_connection_ip_protocol_missing = 0x070d, ///< Invalid or unsupported protocol (e.g. attempting an IPv6 connection on an IPv4 only machine)
ERROR_handshake_failed = 0x070e,
ERROR_illegal_server_license = 0x070f,
//file transfer
ERROR_file_invalid_name = 0x0800, ///< Invalid UTF8 string or not a valid file
ERROR_file_invalid_permissions = 0x0801, ///< Permissions prevent opening the file
ERROR_file_already_exists = 0x0802, ///< Target path already exists as a directory
ERROR_file_not_found = 0x0803, ///< Attempt to access or move non existing file
ERROR_file_io_error = 0x0804, ///< Generic file input / output error
ERROR_file_invalid_transfer_id = 0x0805, ///< Attempt to get information about a file transfer after it has already been cleaned up. File transfer information is not available indefinitely after the transfer completed
ERROR_file_invalid_path = 0x0806, ///< specified path contains invalid characters or does not start with "/"
ERROR_file_no_files_available = 0x0807, // Not used
ERROR_file_overwrite_excludes_resume = 0x0808, ///< File overwrite and resume are mutually exclusive. Only one or neither can be 1.
ERROR_file_invalid_size = 0x0809, ///< Attempt to write more bytes than claimed file size.
ERROR_file_already_in_use = 0x080a, ///< File is currently not available, try again later.
ERROR_file_could_not_open_connection = 0x080b, ///< Generic failure in file transfer connection / other party did not conform to file transfer protocol
ERROR_file_no_space_left_on_device = 0x080c, ///< Operating system reports hard disk is full. May be caused by quota limitations.
ERROR_file_exceeds_file_system_maximum_size = 0x080d, ///< File is too large for the file system of the target device.
ERROR_file_transfer_connection_timeout = 0x080e, // Not used
ERROR_file_connection_lost = 0x080f, ///< File input / output timeout or connection failure
ERROR_file_exceeds_supplied_size = 0x0810, // Not used
ERROR_file_transfer_complete = 0x0811, ///< Indicates successful completion
ERROR_file_transfer_canceled = 0x0812, ///< Transfer was cancelled through @ref ts3client_haltTransfer
ERROR_file_transfer_interrupted = 0x0813, ///< Transfer failed because the server is shutting down, or network connection issues
ERROR_file_transfer_server_quota_exceeded = 0x0814, ///< Transfer terminated due to server bandwidth quota being exceeded. No client can transfer files.
ERROR_file_transfer_client_quota_exceeded = 0x0815, ///< Attempt to transfer more data than allowed by this clients' bandwidth quota. Other clients may continue to transfer files.
ERROR_file_transfer_reset = 0x0816, // Not used
ERROR_file_transfer_limit_reached = 0x0817, ///< Too many file transfers are in progress. Try again later
ERROR_file_invalid_storage_class = 0x0818, // TODO: Invalid storage class for HTTP FileTransfer (what is a storage class?)
ERROR_file_invalid_dimension = 0x0819, ///< Avatar image exceeds maximum width or height accepted by the server.
ERROR_file_transfer_channel_quota_exceeded = 0x081a, ///< Transfer failed because the channel quota was exceeded. Uploading to this channel is not possible, but other channels may be fine.
//sound
ERROR_sound_preprocessor_disabled = 0x0900, ///< Cannot set or query pre processor variables with preprocessing disabled
ERROR_sound_internal_preprocessor = 0x0901,
ERROR_sound_internal_encoder = 0x0902,
ERROR_sound_internal_playback = 0x0903,
ERROR_sound_no_capture_device_available = 0x0904, ///< No audio capture devices are available
ERROR_sound_no_playback_device_available = 0x0905, ///< No audio playback devices are available
ERROR_sound_could_not_open_capture_device = 0x0906, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_could_not_open_playback_device = 0x0907, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_handler_has_device = 0x0908, ///< Attempt to open a sound device on a connection handler which already has an open device. Close the already open device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_invalid_capture_device = 0x0909, ///< Attempt to use a device for capture that does not support capturing audio
ERROR_sound_invalid_playback_device = 0x090a, ///< Attempt to use a device for playback that does not support playback of audio
ERROR_sound_invalid_wave = 0x090b, ///< Attempt to use a non WAV file in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle
ERROR_sound_unsupported_wave = 0x090c, ///< Unsupported wave file used in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle.
ERROR_sound_open_wave = 0x090d, ///< Failure to open the specified sound file
ERROR_sound_internal_capture = 0x090e,
ERROR_sound_device_in_use = 0x090f, ///< Attempt to unregister a custom device that is being used. Close the device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_device_already_registerred = 0x0910, ///< Attempt to register a custom device with a device id that has already been used in a previous call. Device ids must be unique.
ERROR_sound_unknown_device = 0x0911, ///< Attempt to open, close, unregister or use a device which is not known. Custom devices must be registered before being used (see \ref ts3client_registerCustomDevice)
ERROR_sound_unsupported_frequency = 0x0912,
ERROR_sound_invalid_channel_count = 0x0913, ///< Invalid device audio channel count, must be > 0
ERROR_sound_read_wave = 0x0914, ///< Failure to read sound samples from an opened wave file. Is this a valid wave file?
ERROR_sound_need_more_data = 0x0915, // for internal purposes only
ERROR_sound_device_busy = 0x0916, // for internal purposes only
ERROR_sound_no_data = 0x0917, ///< Indicates there is currently no data for playback, e.g. nobody is speaking right now.
ERROR_sound_channel_mask_mismatch = 0x0918, ///< Opening a device with an unsupported channel count
//permissions
ERROR_permissions_client_insufficient = 0x0a08, ///< Not enough permissions to perform the requested activity
ERROR_permissions = 0x0a0c, ///< Permissions to use sound device not granted by operating system, e.g. Windows denied microphone access.
//accounting
ERROR_accounting_virtualserver_limit_reached = 0x0b00, ///< Attempt to use more virtual servers than allowed by the license
ERROR_accounting_slot_limit_reached = 0x0b01, ///< Attempt to set more slots than allowed by the license
ERROR_accounting_license_file_not_found = 0x0b02, // Not used
ERROR_accounting_license_date_not_ok = 0x0b03, ///< License expired or not valid yet
ERROR_accounting_unable_to_connect_to_server = 0x0b04, ///< Failure to communicate with accounting backend
ERROR_accounting_unknown_error = 0x0b05, ///< Failure to write update license file
ERROR_accounting_server_error = 0x0b06, // Not used
ERROR_accounting_instance_limit_reached = 0x0b07, ///< More than one process of the server is running
ERROR_accounting_instance_check_error = 0x0b08, ///< Shared memory access failure.
ERROR_accounting_license_file_invalid = 0x0b09, ///< License is not a TeamSpeak license
ERROR_accounting_running_elsewhere = 0x0b0a, ///< A copy of this server is already running in another instance. Each server may only exist once.
ERROR_accounting_instance_duplicated = 0x0b0b, ///< A copy of this server is running already in this process. Each server may only exist once.
ERROR_accounting_already_started = 0x0b0c, ///< Attempt to start a server that is already running
ERROR_accounting_not_started = 0x0b0d,
ERROR_accounting_to_many_starts = 0x0b0e, ///< Starting instance / virtual servers too often in too short a time period
//provisioning server
/// @cond HAS_PROVISIONING
ERROR_provisioning_invalid_password = 0x1100,
ERROR_provisioning_invalid_request = 0x1101,
ERROR_provisioning_no_slots_available = 0x1102,
ERROR_provisioning_pool_missing = 0x1103,
ERROR_provisioning_pool_unknown = 0x1104,
ERROR_provisioning_unknown_ip_location = 0x1105,
ERROR_provisioning_internal_tries_exceeded = 0x1106,
ERROR_provisioning_too_many_slots_requested = 0x1107,
ERROR_provisioning_too_many_reserved = 0x1108,
ERROR_provisioning_could_not_connect = 0x1109,
ERROR_provisioning_auth_server_not_connected = 0x1110,
ERROR_provisioning_auth_data_too_large = 0x1111,
ERROR_provisioning_already_initialized = 0x1112,
ERROR_provisioning_not_initialized = 0x1113,
ERROR_provisioning_connecting = 0x1114,
ERROR_provisioning_already_connected = 0x1115,
ERROR_provisioning_not_connected = 0x1116,
ERROR_provisioning_io_error = 0x1117,
ERROR_provisioning_invalid_timeout = 0x1118,
ERROR_provisioning_ts3server_not_found = 0x1119,
ERROR_provisioning_no_permission = 0x111A,
/// @endcond
// 0x12 - 0x15 are reserved in rare
// screen share
ERROR_already_registered = 0x1600,
ERROR_stream_session_limit_reached = 0x1601,
ERROR_stream_session_not_found = 0x1602,
ERROR_stream_unknown = 0x1603,
ERROR_stream_not_participating = 0x1604,
ERROR_not_streamer = 0x1605,
ERROR_already_joined = 0x1606,
ERROR_join_request_not_found = 0x1607,
ERROR_sfu_failed_to_start = 0x1608,
};
#endif
@@ -0,0 +1,236 @@
#ifndef TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#define TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Version definitions.
#define TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1 1
// Protocol used for communication between the session subscriber and the session (a single stream).
// Commands are sent bidirectionally or unidirectionally between the parties.
// e.g. SESSION => SUBSCRIBER: ON_FRAME, ON_PAUSED_CHANGED
// e.g. SUBSCRIBER => SESSION: ON_FRAME_ACK, ON_RESIZE
// Command type enum with a lowercase type name.
typedef enum
{
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME = 0,
TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE,
TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED,
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK,
TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP,
TS_SESSION_SUBSCRIBER_CMD_REMOVE_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED,
} ts_session_subscriber_command_type_t;
// Pixel format enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_I420 = 0,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_NV12,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ABGR,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ARGB,
} ts_session_subscriber_pixel_format_t;
// Buffer location enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_CPU = 0,
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_GPU
} ts_session_subscriber_buffer_location_t;
// Buffer type enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_SINGLE = 0,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_MAIN,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_SUB
} ts_session_subscriber_buffer_type_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(push, 4)
#endif
// Main buffer header for shared CPU Memory Front/Back Buffers.
// The Main Buffer contains metadata about the current front/back buffer and the versioning for both the main and sub buffer.
// The information from the main buffer can be used to always read the front buffer.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t front_buffer_index; // index of the front buffer. (0: main buffer, 1: sub buffer)
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_main_buffer_header_t;
// Sub buffer header.
typedef struct
{
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
} ts_session_subscriber_sub_buffer_header_t;
// Single frame buffer header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_single_frame_buffer_header_t;
// Command header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // Total message length (header + payload).
ts_session_subscriber_command_type_t type;
uint64_t target_session_id; // always set to the target session id this command is for or is originating from.
uint64_t target_subscriber_id; // 0 if broadcast.
} ts_session_subscriber_command_header_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME.
// The frame data is not included in the message, but is attached seperately or was sent beforehand. The buffer is identified by it's id.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_id; // buffer id, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_frame_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t frame_id;
} ts_session_subscriber_on_frame_ack_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE.
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t width;
uint32_t height;
} ts_session_subscriber_on_resize_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t paused; // 0 or 1.
} ts_session_subscriber_on_paused_changed_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE.
// Contains a single frame buffer. The header is of format |ts_session_subscriber_single_frame_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
ts_session_subscriber_buffer_type_t buffer_type;
} ts_session_subscriber_on_buffer_single_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK.
// Contains a main buffer and a sub buffer. The main buffer header
// contains metadata about the current front/back buffer and
// is of type |ts_session_subscriber_main_buffer_header_t|.
// The sub buffer's header is of type |ts_session_subscriber_sub_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t main_buffer_ptr; // main buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t main_buffer_length;
uint64_t sub_buffer_ptr; // sub buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t sub_buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
} ts_session_subscriber_on_buffer_front_back_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER.
// SUBSCRIBER => SESSION.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_resp_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_release_buffer_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr;
int bits_per_sample;
int sample_rate;
uint32_t number_of_channels;
uint32_t number_of_frames;
int64_t absolute_capture_timestamp_ms;
float volume;
} ts_session_subscriber_on_audio_frames_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t audio_enabled;
} ts_session_subscriber_on_audio_enabled_changed_payload_t;
// Overall Command structure.
typedef struct
{
ts_session_subscriber_command_header_t header;
union
{
ts_session_subscriber_on_frame_payload_t frame;
ts_session_subscriber_on_resize_payload_t resize;
ts_session_subscriber_on_paused_changed_payload_t paused;
ts_session_subscriber_on_frame_ack_payload_t frame_ack;
ts_session_subscriber_on_buffer_single_payload_t buffer_single;
ts_session_subscriber_on_buffer_front_back_payload_t buffer_front_back;
ts_session_subscriber_on_release_buffer_payload_t release_buffer;
ts_session_subscriber_add_subscriber_payload_t add_subscriber;
ts_session_subscriber_add_subscriber_resp_payload_t add_subscriber_resp;
ts_session_subscriber_on_audio_frames_payload_t audio_frames;
ts_session_subscriber_on_audio_enabled_changed_payload_t audio_enabled_changed;
} payload;
} ts_session_subscriber_command_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif // TS_SESSION_SUBSCRIBER_PROTOCOL_H_
@@ -0,0 +1,29 @@
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was team_clientConfig.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()
####################################################################################
include("${CMAKE_CURRENT_LIST_DIR}/team_clientTargets.cmake")
check_required_components(team_client)
@@ -0,0 +1,19 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "teamspeak::client" for configuration "Release"
set_property(TARGET teamspeak::client APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(teamspeak::client PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.so"
IMPORTED_SONAME_RELEASE "libteamspeak_sdk_client.so"
)
list(APPEND _cmake_import_check_targets teamspeak::client )
list(APPEND _cmake_import_check_files_for_teamspeak::client "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.so" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
@@ -0,0 +1,121 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.3")
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.3...4.0)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS teamspeak::client)
list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
if(TARGET "${_cmake_expected_target}")
list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
else()
list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
unset(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target teamspeak::client
add_library(teamspeak::client SHARED IMPORTED)
set_target_properties(teamspeak::client PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
if(NOT CMAKE_VERSION VERSION_LESS "3.23.0")
target_sources(teamspeak::client
INTERFACE
FILE_SET "public_headers"
TYPE "HEADERS"
BASE_DIRS "${_IMPORT_PREFIX}/include"
FILES "${_IMPORT_PREFIX}/include/teamspeak/clientlib.h" "${_IMPORT_PREFIX}/include/teamspeak/clientlib_sdk.h" "${_IMPORT_PREFIX}/include/teamspeak/video/session_subscriber_protocol.h"
)
else()
set_property(TARGET teamspeak::client
APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
"${_IMPORT_PREFIX}/include"
)
endif()
# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/team_clientTargets-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
if(CMAKE_VERSION VERSION_LESS "3.28"
OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target}
OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}")
foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
if(NOT EXISTS "${_cmake_file}")
message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
\"${_cmake_file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
endif()
unset(_cmake_file)
unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
@@ -0,0 +1,23 @@
#ifndef TEAMLOG_LOGTYPES_H
#define TEAMLOG_LOGTYPES_H
enum LogTypes {
LogType_NONE = 0x0000, ///< Logging is disabled
LogType_FILE = 0x0001, ///< Log to regular log file
LogType_CONSOLE = 0x0002, ///< Log to standard output / error
LogType_USERLOGGING = 0x0004, ///< User defined logging. Will call the \ref ServerLibFunctions.onUserLoggingMessageEvent callback for every message to be logged
LogType_NO_NETLOGGING = 0x0008, ///< Not used
LogType_DATABASE = 0x0010, ///< Log to database (deprecated, server only, no effect in SDK)
LogType_SYSLOG = 0x0020, ///< Log to syslog (only available on Linux)
};
enum LogLevel {
LogLevel_CRITICAL = 0, ///< these messages stop the program
LogLevel_ERROR, ///< everything that is really bad, but not so bad we need to shut down
LogLevel_WARNING, ///< everything that *might* be bad
LogLevel_DEBUG, ///< output that might help find a problem
LogLevel_INFO, ///< informational output, like "starting database version x.y.z"
LogLevel_DEVEL ///< developer only output (will not be displayed in release mode)
};
#endif //TEAMLOG_LOGTYPES_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,58 @@
#ifndef CLIENTLIB_SDK_H
#define CLIENTLIB_SDK_H
// system
#include <stdlib.h>
// own
#include "teamspeak/public_definitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets the client to which to transmit voice. Stops standard channel voice transmission.
*
* The client will still receive voice from their current channel, however their voice will not be transmitted to their
* current channel anymore. If this call is successful (check onServerErrorEvent) then voice of the specified client
* will be transmitted to all specified channels and all the specified clients. Pass 0 to both target parameter arrays
* to restore default behavior of transmitting voice to current channel. You will receive an onServerErrorEvent with the
* passed returnCode indicating whether or not the operation was successful.
*
* @param server_connection_handler_id the connection handler on which to set the whisper list
* @param client_id the client to set the whisper list for. Set to 0 or your own client ID to set your own whisper list.
* @param channel_ids an array of channel ids to transmit voice to.
* @param channel_ids_size number of elements in aforementioned array.
* @param client_ids a zero terminated array of client ids to transmit voice to.
* @param client_ids_size number of elements in aforementioned array.
* @param impersonate if the target client is a webrtc client, the voice packets will look like as if they have been
* send by the invoking client id
* @param return_code a c string to identify this request in callbacks. Pass an empty string if unused.
* @return An error code from the @ref Ts3ErrorType enum indicating either success or the failure reason
*/
EXPORTDLL unsigned int ts_client_request_client_set_whisper_list(uint64 server_connection_handler_id, anyID client_id,
const uint64* channel_ids,
int channel_ids_size,
const anyID* client_ids,
int client_ids_size, int impersonate,
const char* return_code);
/**
* @brief Send a binary-serialized ClientCommandRequest protobuf to the client library.
*
* The response will be delivered asynchronously via the onProtoResponse callback
* as a serialized ClientCommandResponse protobuf.
*
* @param data Pointer to serialized ClientCommandRequest protobuf bytes
* @param size Size of the serialized data in bytes
* @param return_code Caller-provided string to correlate the response in onProtoResponse. May be NULL.
* @return An error code: ERROR_ok on successful dispatch, ERROR_parameter_invalid on parse failure
*/
EXPORTDLL unsigned int ts3client_postProtoCommand(const void* data, size_t size, const char* return_code);
#ifdef __cplusplus
}
#endif
#endif // CLIENTLIB_SDK_H
@@ -0,0 +1,635 @@
#ifndef PUBLIC_DEFINITIONS_H
#define PUBLIC_DEFINITIONS_H
#include "teamlog/logtypes.h"
#define TS3_MAX_SIZE_CHANNEL_NAME 40 // channel name maximum length in characters
#define TS3_MAX_SIZE_VIRTUALSERVER_NAME 64 // virtual server name maximum length in characters
#define TS3_MAX_SIZE_CLIENT_NICKNAME 64 // client display name length limit in characters
#define TS3_MIN_SIZE_CLIENT_NICKNAME 3 // client display name minimum length in characters
#define TS3_MAX_SIZE_REASON_MESSAGE 80 // length limit in characters for kick, move, etc reasons
#define TS3_MAX_SIZE_TEXTMESSAGE 8192 // text message length limit, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_TOPIC 255 // channel topic lengt limith, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_DESCRIPTION 8192 // channel description length limit, measured in bytes (utf8 encoded)
// server welcome message length limit measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_VIRTUALSERVER_WELCOMEMESSAGE 1024
#define TS3_SIZE_MYTSID 44
// minimum amount of seconds before a clientID that was in use can be assigned to a new client
#define TS3_MIN_SECONDS_CLIENTID_REUSE 300
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32)
typedef unsigned __int16 anyID;
typedef unsigned __int64 uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __declspec(dllexport)
#else
#define EXPORTDLL
#endif
#endif
#else
#include <stdint.h>
typedef uint16_t anyID;
typedef uint64_t uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __attribute__((visibility("default")))
#else
#define EXPORTDLL
#endif
#endif
#endif
enum Visibility
{
ENTER_VISIBILITY = 0, ///< Client joined from an unsubscribed channel, or joined the server.
RETAIN_VISIBILITY, ///< Client switched from one subscribed channel to a different subscribed channel.
LEAVE_VISIBILITY ///< Client switches to an unsubscribed channel, or disconnected from server.
};
enum ConnectStatus
{
STATUS_DISCONNECTED = 0, ///< There is no activity to the server, this is the default value
STATUS_CONNECTING, ///< We are trying to connect, we haven't got a client id yet, we haven't been accepted by the server
STATUS_CONNECTED, ///< The server has accepted us, we can talk and hear and we have a client id, but we don't
///< have the channels and clients yet, we can get server infos (welcome msg etc.)
STATUS_CONNECTION_ESTABLISHING, ///< we are connected and we are visible
STATUS_CONNECTION_ESTABLISHED, ///< we are connected and we have the client and channels available
};
enum LocalTestMode
{
TEST_MODE_OFF = 0,
TEST_MODE_VOICE_LOCAL_ONLY,
TEST_MODE_VOICE_LOCAL_AND_REMOTE,
TEST_MODE_TALK_STATUS_CHANGES_ONLY
};
enum TalkStatus
{
STATUS_NOT_TALKING = 0, ///< client is not talking
STATUS_TALKING = 1, ///< client is talking
STATUS_TALKING_WHILE_DISABLED = 2, ///< client is talking while the microphone is muted (only valid for own client)
};
enum CodecType
{
CODEC_SPEEX_NARROWBAND = 0, ///< (deprecated) mono, 16bit, 8kHz, bitrate dependent on the quality setting
CODEC_SPEEX_WIDEBAND, ///< (deprecated) mono, 16bit, 16kHz, bitrate dependent on the quality setting
CODEC_SPEEX_ULTRAWIDEBAND, ///< (deprecated) mono, 16bit, 32kHz, bitrate dependent on the quality setting
CODEC_CELT_MONO, ///< (deprecated) mono, 16bit, 48kHz, bitrate dependent on the quality setting
CODEC_OPUS_VOICE, ///< mono, 16bit, 48khz, bitrate dependent on the quality setting, optimized for voice
CODEC_OPUS_MUSIC, ///< stereo, 16bit, 48khz, bitrate dependent on the quality setting, optimized for music
};
enum CodecEncryptionMode
{
CODEC_ENCRYPTION_PER_CHANNEL = 0, ///< voice data encryption decided per channel
CODEC_ENCRYPTION_FORCED_OFF, ///< voice data encryption disabled
CODEC_ENCRYPTION_FORCED_ON, ///< voice data encryption enabled
};
enum TextMessageTargetMode
{
TextMessageTarget_CLIENT = 1, ///< Message is a private message to another client
TextMessageTarget_CHANNEL, ///< Message is sent to a channel, received by all clients in that channel at the time
TextMessageTarget_SERVER, ///< Message is sent to every client on the server
TextMessageTarget_MAX
};
enum MuteInputStatus
{
MUTEINPUT_NONE = 0, ///< Microphone is not muted, audio is sent to the server
MUTEINPUT_MUTED, ///< Microphone is muted, no audio is transmitted to the server
};
enum MuteOutputStatus
{
MUTEOUTPUT_NONE = 0, ///< Speaker is active, server is sending us audio
MUTEOUTPUT_MUTED, ///< Speaker is muted, server is not sending audio to us
};
enum HardwareInputStatus
{
HARDWAREINPUT_DISABLED = 0, ///< no capture device opened
HARDWAREINPUT_ENABLED, ///< capture device open
};
enum HardwareOutputStatus
{
HARDWAREOUTPUT_DISABLED = 0, ///< no playback device opened
HARDWAREOUTPUT_ENABLED, ///< playback device open
};
enum InputDeactivationStatus
{
INPUT_ACTIVE = 0, ///< Audio is captured from the capture device.
INPUT_DEACTIVATED = 1, ///< No audio is captured from the capture device.
};
enum ReasonIdentifier
{
REASON_NONE = 0, ///< no reason data
REASON_MOVED = 1, ///< client was moved
REASON_SUBSCRIPTION = 2, // no reason data
REASON_LOST_CONNECTION = 3, // reasonmsg=reason
REASON_KICK_CHANNEL = 4, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER = 5, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER_BAN = 6, //{SectionInvoker} reasonmsg=reason bantime=time //{SectionInvoker} is only added server->client
REASON_SERVERSTOP = 7, // reasonmsg=reason
REASON_CLIENTDISCONNECT = 8, // reasonmsg=reason
REASON_CHANNELUPDATE = 9, // no reason data
REASON_CHANNELEDIT = 10, //{SectionInvoker}
REASON_CLIENTDISCONNECT_SERVER_SHUTDOWN = 11, // reasonmsg=reason
};
enum Protocol_Encryption_Cipher
{
AES_128 = 0b00000000,
AES_256 = 0b00000001,
PROTOCOL_ENCRYPTION_CIPHER_END_MARKER,
RESERVED = 0b00010000, // reserved until puzzle v2 is fully released, then can be reused
PUZZLE_2 = 0b00100000,
};
enum ChannelProperties
{
CHANNEL_NAME = 0, ///< String. Read/Write. Name of the channel. Always available.
CHANNEL_TOPIC, ///< String. Read/Write. Short single line text describing what the channel is about. Always available.
CHANNEL_DESCRIPTION, ///< String. Read/Write. Arbitrary text (up to 8k bytes) with information about the channel.
///< Must be requested (\ref ts3client_requestChannelDescription)
CHANNEL_PASSWORD, ///< String. Read/Write. Password of the channel. Read access is limited to the server. Clients
///< will only ever see the last password they attempted to use when joining the channel. Always available.
CHANNEL_CODEC, ///< Integer. Read/Write. The codec this channel is using. One of the values from the \ref CodecType
///< enum. Always available.
CHANNEL_CODEC_QUALITY, ///< Integer. Read/Write. The quality setting of the channel. Valid values are 0 to 10 inclusive.
///< Higher value means better voice quality but also more bandwidth usage. Always available.
CHANNEL_MAXCLIENTS, ///< Integer. Read/Write. The number of clients that can be in the channel simultaneously.
///< Always available.
CHANNEL_MAXFAMILYCLIENTS, ///< Integer. Read/Write. The total number of clients that can be in this channel and all
///< sub channels of this channel. Always available.
CHANNEL_ORDER, ///< UInt64. Read/Write. The ID of the channel below which this channel should be displayed. If 0
///< the channel is sorted at the top of the current level. Always available.
CHANNEL_FLAG_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when empty.
///< Permanent channels are stored to the database and available after server restart. SDK
///< users will need to take care of restoring channel at server start on their own.
///< Mutually exclusive with \ref CHANNEL_FLAG_SEMI_PERMANENT. Always available.
CHANNEL_FLAG_SEMI_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when
///< empty. Semi permanent channels are not stored to disk and gone after server
///< restart but remain while empty. Mutually exclusive with \ref
///< CHANNEL_FLAG_PERMANENT. Always available.
CHANNEL_FLAG_DEFAULT, ///< Integer. Read/Write. Boolean (1/0). The default channel is the channel that all clients
///< are located in when they join the server, unless the client explicitly specified a
///< different channel when connecting and is allowed to join their preferred channel. Only
///< one channel on the server can have this flag set. The default channel must have \ref
///< CHANNEL_FLAG_PERMANENT set. Always available.
CHANNEL_FLAG_PASSWORD, ///< Integer. Read/Write. Boolean (1/0) indicating whether this channel is password protected.
///< When removing or setting \ref CHANNEL_PASSWORD you also need to adjust this flag.
CHANNEL_CODEC_LATENCY_FACTOR, ///< (deprecated) Integer. Read/Write. Allows to increase packet size, reducing
///< bandwith at the cost of higher latency of voice transmission. Valid values are
///< 1-10 inclusive. 1 is the default and offers the lowest latency. Always available.
CHANNEL_CODEC_IS_UNENCRYPTED, ///< Integer. Read/Write. Boolean (1/0). If 0 voice data is encrypted, if 1 the voice
///< data is not encrypted. Only used if the server \ref
///< VIRTUALSERVER_CODEC_ENCRYPTION_MODE is set to \ref CODEC_ENCRYPTION_PER_CHANNEL.
///< Always available.
CHANNEL_SECURITY_SALT, ///< String. Read/Write. SDK Only, not used by TeamSpeak. This channels security hash. When
///< a client joins their \ref CLIENT_SECURITY_HASH is compared to this value, to allow or
///< deny the client access to the channel. Used to enforce clients joining the server with
///< specific identity and \ref CLIENT_META_DATA. See SDK Documentation about this feature
///< for further details. Always available.
CHANNEL_DELETE_DELAY, ///< UInt64. Read/Write. Number of seconds deletion of temporary channels is delayed after
///< the last client leaves the channel. Channel is only deleted if empty when the delete
///< delay expired. Always available.
CHANNEL_UNIQUE_IDENTIFIER, ///< String. Read only. An identifier that uniquely identifies a channel. Available in
///< Server >= 3.10.0
CHANNEL_ENDMARKER,
};
enum ClientProperties
{
CLIENT_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Public Identity, can be used to identify a client
///< installation. Remains identical as long as the client keeps using the same
///< identity. Available for visible clients.
CLIENT_NICKNAME, ///< String. Read/Write. Display name of the client. Available for visible clients.
CLIENT_VERSION, ///< String. Read only. Version String of the client used. For clients other than ourself this
///< needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_PLATFORM, ///< String. Read only. Operating system used by the client. For other clients other than ourself
///< this needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_FLAG_TALKING, ///< Integer. Read only. Whether the client is talking. Available on clients that are either
///< whispering to us, or in our channel.
CLIENT_INPUT_MUTED, ///< Integer. Read/Write. Microphone mute status. Available for visible clients. One of the
///< values from the \ref MuteInputStatus enum.
CLIENT_OUTPUT_MUTED, ///< Integer. Read/Write. Speaker mute status. Speaker mute implies microphone mute. Available
///< for visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_OUTPUTONLY_MUTED, ///< Integer. Read/Write. Speaker mute status. Microphone may be active. Available for
///< visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_INPUT_HARDWARE, ///< Integer. Read only. Indicates whether a capture device is open. Available for visible
///< clients. One of the values from the \ref HardwareInputStatus enum.
CLIENT_OUTPUT_HARDWARE, ///< Integer. Read only. Indicates whether a playback device is open. Available for visible
///< clients. One of the values from the \ref HardwareOutputStatus enum.
CLIENT_INPUT_DEACTIVATED, ///< Integer. Read/Write. Not available server side. Local microphone mute status.
///< Available only for own client. Used to implement Push To Talk. One of the values from
///< the \ref InputDeactivationStatus enum.
CLIENT_IDLE_TIME, ///< UInt64. Read only. Seconds since last activity. Available only for own client.
CLIENT_DEFAULT_CHANNEL, ///< String. Read only. User specified channel they joined when connecting to the server.
///< Available only for own client.
CLIENT_DEFAULT_CHANNEL_PASSWORD, ///< String. Read only. User specified channel password for the channel they
///< attempted to join when connecting to the server. Available only for own
///< client.
CLIENT_SERVER_PASSWORD, ///< String. Read only. User specified server password. Available only for own client.
CLIENT_META_DATA, ///< String. Read/Write. Can be used to store up to 4096 bytes of information on clients. Not
///< used by TeamSpeak. Available for visible clients.
CLIENT_IS_MUTED, ///< Integer. Read only. Not available server side. Indicates whether we have muted the client
///< using \ref ts3client_requestMuteClients. Available for visible clients other than ourselves.
CLIENT_IS_RECORDING, ///< Integer. Read only. Indicates whether the client is recording incoming audio. Available
///< for visible clients.
CLIENT_VOLUME_MODIFICATOR, ///< Integer. Read only. Volume adjustment for this client as set by \ref
///< ts3client_setClientVolumeModifier. Available for visible clients.
CLIENT_VERSION_SIGN, ///< String. Read only. TeamSpeak internal signature.
CLIENT_SECURITY_HASH, ///< String. Read/Write. This clients security hash. Not used by TeamSpeak, SDK only. Hash is
///< provided by an outside source. A channel will use the security salt + other client data
///< to calculate a hash, which must be the same as the one provided here. See SDK
///< documentation about Client / Channel Security Hashes for more details.
CLIENT_ENCRYPTION_CIPHERS, ///< String. Read only. SDK only. List of available ciphers this client can use.
CLIENT_IS_STREAMING, ///< bool. Read only, Is currently streaming.
CLIENT_ENDMARKER,
};
enum VirtualServerProperties
{
VIRTUALSERVER_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Unique identifier for a virtual server, does not
///< change on server restart. Available if \ref ts3client_getConnectionStatus
///< is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_NAME, ///< String. Read/Write. The virtual server display name. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_WELCOMEMESSAGE, ///< String. Read/Write. The welcome message displayed to clients on connect.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED. Not
///< updated automatically when changed, updates need to be requested (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_PLATFORM, ///< String. Read only. The operating system the server is running on. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_VERSION, ///< String. Read only. The server software version string. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_MAXCLIENTS, ///< UInt64. Read/Write. The maximum number of clients that can be connected
///< simultaneously. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_PASSWORD, ///< String. Read/Write. The server password. Read access is limited to the server. Clients
///< will only get the password they supplied when connecting. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_CLIENTS_ONLINE, ///< UInt64. Read only. The current number of clients connected to the server,
///< including query connections. Only available on request (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_CHANNELS_ONLINE, ///< UInt64. Read only. The current number of channels on the server. Only
///< available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CREATED, ///< Integer. Read only. The time this virtual server was created as unix timestamp.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_UPTIME, ///< UInt64. Read only. Number of seconds that have passed since the virtual server was
///< started. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CODEC_ENCRYPTION_MODE, ///< Integer. Read/Write. Boolean (1/0) that specifies if voice data is encrypted
///< during transfer. One of the values from the \ref CodecEncryptionMode enum.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_ENCRYPTION_CIPHERS, ///< String. Read/Write. Comma separated list of available ciphers to encrypt the
///< connection. The server will use the first cipher in the list that is also
///< listed in the \ref CLIENT_ENCRYPTION_CIPHERS of the connecting client.
///< Clients will fail to connect if no match is found. Always available.
VIRTUALSERVER_ADDRESS, ///< Any resolvable address for the specific virtual server
VIRTUALSERVER_VERSION_SIGN, ///< String. Read only. Signature of Platform and Version.
VIRTUALSERVER_ENDMARKER,
VIRTUALSERVER_FILEBASE = 24, ///< String. Read only. The path to the base directory used to store files
///< transferred using file transfer. Available only on the server. Is set by \ref
///< ts3server_enableFileManager
VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH = 29, ///< UInt64. Read/Write. Maximum traffic in bytes the server can
///< use for file transfer downloads. Only available on request
///< (\ref ts3client_requestServerVariables).
VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH = 30, ///< UInt64. Read/Write. Maximum traffic in bytes the server can use
///< for file transfer uploads. Only available on request (=>
///< requestServerVariables)
VIRTUALSERVER_LOG_FILETRANSFER = 64 ///< Integer. Read/Write. Boolean (1/0) indicating whether to include file
///< transfer activities (uploading or downloading of files) in the server log.
///< Always available.
};
/**
* Various connection properties.
* These are all read only, and except for your own client must be requested using \ref ts3client_requestConnectionInfo
*/
enum ConnectionProperties
{
CONNECTION_PING = 0, ///< UInt64. Round trip latency for the connection based on the last 5 seconds. On the server
///< this is the average across all connected clients for the last 5 seconds.
CONNECTION_PING_DEVIATION, ///< Double. Standard deviation for the round trip latency in \ref CONNECTION_PING
CONNECTION_CONNECTED_TIME, ///< UInt64. Seconds the client has been connected.
CONNECTION_IDLE_TIME, ///< UInt64. Time in seconds since the last activity (voice transmission, switching channels,
///< changing mic / speaker mute status) of the client.
CONNECTION_CLIENT_IP, ///< String. IP of this client (as seen from the server side)
CONNECTION_CLIENT_PORT, ///< UInt64. Client side port of this client (as seen from the server side)
CONNECTION_SERVER_IP, ///< String. The IP or hostname used to connect to the server. Only available on yourself.
CONNECTION_SERVER_PORT, ///< UInt64. The server port connected to. Only available on yourself.
CONNECTION_PACKETS_SENT_SPEECH, ///< UInt64. The number of voice packets transmitted by the client.
CONNECTION_PACKETS_SENT_KEEPALIVE, ///< UInt64. The number of keep alive packets transmitted by the client.
CONNECTION_PACKETS_SENT_CONTROL, ///< UInt64. The number of command & control packets transmitted by the client.
CONNECTION_PACKETS_SENT_TOTAL, ///< UInt64. Total number of packets transmitted by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_SENT_SPEECH, \ref CONNECTION_PACKETS_SENT_KEEPALIVE and
///< \ref CONNECTION_PACKETS_SENT_CONTROL
CONNECTION_BYTES_SENT_SPEECH, ///< UInt64. Outgoing traffic used for voice data by the client.
CONNECTION_BYTES_SENT_KEEPALIVE, ///< UInt64. Outgoing traffic used for keeping the connection alive by the client.
CONNECTION_BYTES_SENT_CONTROL, ///< UInt64. Outgoing traffic used for command & control data by the client.
CONNECTION_BYTES_SENT_TOTAL, ///< UInt64. Total outgoing traffic to the server by this client. Equal to the sum of
///< \ref CONNECTION_BYTES_SENT_SPEECH, \ref CONNECTION_BYTES_SENT_KEEPALIVE and \ref
///< CONNECTION_BYTES_SENT_CONTROL
CONNECTION_PACKETS_RECEIVED_SPEECH, ///< UInt64. Number of voice packets received by the client.
CONNECTION_PACKETS_RECEIVED_KEEPALIVE, ///< UInt64. Number of keep alive packets received by the client.
CONNECTION_PACKETS_RECEIVED_CONTROL, ///< UInt64. Number of command & control packets received by the client.
CONNECTION_PACKETS_RECEIVED_TOTAL, ///< UInt64. Total number of packets received by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_RECEIVED_SPEECH, \ref
///< CONNECTION_PACKETS_RECEIVED_KEEPALIVE and \ref
///< CONNECTION_PACKETS_RECEIVED_CONTROL
CONNECTION_BYTES_RECEIVED_SPEECH, ///< UInt64. Incoming traffic used by the client for voice data.
CONNECTION_BYTES_RECEIVED_KEEPALIVE, ///< UInt64. Incoming traffic used by the client to keep the connection alive.
CONNECTION_BYTES_RECEIVED_CONTROL, ///< UInt64. Incoming traffic used by the client for command & control data.
CONNECTION_BYTES_RECEIVED_TOTAL, ///< UInt64. Total incoming traffic used by the client. Equal to the sum of \ref
///< CONNECTION_BYTES_RECEIVED_SPEECH, \ref CONNECTION_BYTES_RECEIVED_KEEPALIVE and
///< \ref CONNECTION_BYTES_RECEIVED_CONTROL
CONNECTION_PACKETLOSS_SPEECH, ///< Double. Percentage points of voice packets for the client that did not arrive at
///< the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_KEEPALIVE, ///< Double. Percentage points of keep alive packets for the client that did not
///< arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_CONTROL, ///< Double. Percentage points of command & control packets for the client that did
///< not arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_TOTAL, ///< Double. Cumulative chance in percentage points with which a packet round trip
///< failed because a packet was lost
CONNECTION_SERVER2CLIENT_PACKETLOSS_SPEECH, ///< Double. Probability with which a voice packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< server was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the server was not
///< received by the client.
CONNECTION_CLIENT2SERVER_PACKETLOSS_SPEECH, ///< Double. Probability with which a speech packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< client was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the client was not
///< received by the server.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes sent for speech data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes sent for keepalive data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes sent for control data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes sent in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second sent for speech data, averaged over the
///< last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second sent for keepalive data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second sent for control data, averaged over
///< the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second sent, averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes received for speech data in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes received for keepalive data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes received for control data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes received in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second received for speech data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second received for keepalive data,
///< averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second received for control data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second received, averaged over the last minute.
CONNECTION_DUMMY_0,
CONNECTION_DUMMY_1,
CONNECTION_DUMMY_2,
CONNECTION_DUMMY_3,
CONNECTION_DUMMY_4,
CONNECTION_DUMMY_5,
CONNECTION_DUMMY_6,
CONNECTION_DUMMY_7,
CONNECTION_DUMMY_8,
CONNECTION_DUMMY_9,
CONNECTION_FILETRANSFER_BANDWIDTH_SENT, ///< UInt64. Current file transfer upstream activity in bytes per second.
///< Only available on request (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, ///< UInt64. Current file transfer downstream activity in bytes per
///< second. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, ///< UInt64. Total downstream traffic, in bytes, used for file
///< transfer since the server was started. Only available on request
///< (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, ///< UInt64. Total upstream traffic, in bytes, used for file transfer
///< since the server was started. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_ENDMARKER
};
/**
* Describes a client position in 3 dimensional space, used for 3D Sound.
*/
typedef struct
{
float x; ///< X co-ordinate in 3D space.
float y; ///< Y co-ordinate in 3D space.
float z; ///< Z co-ordinate in 3D space.
} TS3_VECTOR;
enum GroupWhisperType
{
GROUPWHISPERTYPE_SERVERGROUP = 0, ///< Whisper list consists of server groups
GROUPWHISPERTYPE_CHANNELGROUP = 1, ///< Whisper list consists of channel groups
GROUPWHISPERTYPE_CHANNELCOMMANDER = 2, ///< whisper to channel commanders
GROUPWHISPERTYPE_ALLCLIENTS = 3, ///< whisper to all clients
GROUPWHISPERTYPE_ENDMARKER,
};
enum GroupWhisperTargetMode
{
GROUPWHISPERTARGETMODE_ALL = 0,
GROUPWHISPERTARGETMODE_CURRENTCHANNEL = 1, ///< Whisper the current channel of the client
GROUPWHISPERTARGETMODE_PARENTCHANNEL = 2, ///< Whisper the parent channel of whatever channel the client is currently in
GROUPWHISPERTARGETMODE_ALLPARENTCHANNELS = 3, ///< Whipser to the parent channel and all their parent channels as well
GROUPWHISPERTARGETMODE_CHANNELFAMILY = 4, ///< Whisper to the current channel and all its sub channels
GROUPWHISPERTARGETMODE_ANCESTORCHANNELFAMILY = 5, ///< Whisper to the current channel, all its parent and sub channels.
GROUPWHISPERTARGETMODE_SUBCHANNELS = 6, ///< Whisper to all sub channels of the current channel of the client
GROUPWHISPERTARGETMODE_ENDMARKER,
};
enum MonoSoundDestination
{
MONO_SOUND_DESTINATION_ALL = 0, ///< Send mono sound to all available speakers
MONO_SOUND_DESTINATION_FRONT_CENTER = 1, ///< Send mono sound to front center speaker if available
MONO_SOUND_DESTINATION_FRONT_LEFT_AND_RIGHT = 2 ///< Send mono sound to front left/right speakers if available
};
enum SecuritySaltOptions
{
SECURITY_SALT_CHECK_NICKNAME = 1, ///< put nickname into security hash
SECURITY_SALT_CHECK_META_DATA = 2 ///< put meta data into security hash
};
/*this enum is used to disable client commands on the server*/
enum ClientCommand
{
CLIENT_COMMAND_requestConnectionInfo = 0, ///< disable client connection info request (client bandwidth usage, ip,
///< port, ping)
CLIENT_COMMAND_requestClientMove = 1, ///< disable moving clients
CLIENT_COMMAND_requestXXMuteClients = 2, ///< disable muting other clients
CLIENT_COMMAND_requestClientKickFromXXX = 3, ///< disable kicking clients
CLIENT_COMMAND_flushChannelCreation = 4, ///< disable creating channels
CLIENT_COMMAND_flushChannelUpdates = 5, ///< disable editing channels
CLIENT_COMMAND_requestChannelMove = 6, ///< disable moving channels
CLIENT_COMMAND_requestChannelDelete = 7, ///< disable deleting channels
CLIENT_COMMAND_requestChannelDescription = 8, ///< disable channel descriptions
CLIENT_COMMAND_requestChannelXXSubscribeXXX = 9, ///< disable being able to see clients in channels other than the
///< current channel the client is in
CLIENT_COMMAND_requestServerConnectionInfo = 10, ///< disable server connection info request (server bandwidth
///< usage, ip, port, ping)
CLIENT_COMMAND_requestSendXXXTextMsg = 11, ///< disable text messaging
CLIENT_COMMAND_filetransfers = 12, ///< disable file transfer
CLIENT_COMMAND_ENDMARKER
};
/* Access Control List*/
enum ACLType
{
ACL_NONE = 0,
ACL_WHITE_LIST = 1,
ACL_BLACK_LIST = 2
};
/* file transfer actions*/
enum FTAction
{
FT_INIT_SERVER = 0, ///< The virtual server is created. result->channelPath can be changed to create a different
///< directory than the default 'virtualserver_x' where x is the virtual server.
FT_INIT_CHANNEL = 1, ///< A channel is created. result->channelPath can be changed to create a different directory
///< then the default 'channel_x' where x is the channel id.
FT_UPLOAD = 2, ///< A file is being uploaded. All values in the result struct can be modified.
FT_DOWNLOAD = 3, ///< A file is being downloaded. All values in the result struct can be modified.
FT_DELETE = 4, ///< A file is being deleted. All values in the result struct can be modified.
FT_CREATEDIR = 5, ///< A directory is being created in a channel. All values in the result struct can be modified.
FT_RENAME = 6, ///< A file or folder is being renamed. The callback will be called twice! Once for the old and then
///< for the new name. All values in the result struct can be modified.
FT_FILELIST = 7, ///< A directory listing is requested. All values in the result struct can be modified.
FT_FILEINFO = 8 ///< Information of a file is requested. All values in the result struct can be modified.
};
/* file transfer status */
enum FileTransferState
{
FILETRANSFER_INITIALISING = 0, ///< File transfer is establishing connection.
FILETRANSFER_ACTIVE, ///< File transfer is in progress
FILETRANSFER_FINISHED, ///< File transfer has finished
};
/* file transfer types */
enum FileTransferType
{
FileListType_Directory = 0, ///< The file entry is a directory
FileListType_File, ///< The file entry is a regular file
};
/* some structs to handle variables in callbacks */
#define MAX_VARIABLES_EXPORT_COUNT 64
struct VariablesExportItem
{
unsigned char itemIsValid; ///< Whether or not there is any data in this item. Ignore this item if this is 0.
unsigned char proposedIsSet; ///< The value in proposed is set. If 0 ignore proposed
const char* current; ///< current value (stored in memory)
const char* proposed; ///< New value to change to (const, so no updates please)
};
struct VariablesExport
{
struct VariablesExportItem items[MAX_VARIABLES_EXPORT_COUNT];
};
struct ClientMiniExport
{
anyID ID; ///< id of the client
uint64 channel; ///< the channel the client is in
const char* ident; ///< client public identity
const char* nickname; ///< client display name
};
/**
* Structure used to describe a file transfer in the \ref ServerLibFunctions.onTransformFilePath callback.
* This describes the original values, and also contains hints for length limitations of the result parameter
* of the callback.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExport
{
uint64 channel; ///< The channel id of the file. 0 if action is \ref FT_INIT_SERVER
const char* filename; ///< utf8 encoded c string containing the original file name as intended by the client.
int action; ///< The action to be performed. One of the values from the \ref FTAction enum. Defines which values of
///< the result struct can be modified.
int transformedFileNameMaxSize; ///< The maximum length the file name can be rewritten to.
int channelPathMaxSize; ///< The maximum length the path can be rewritten to.
};
/**
* Structure to rewrite the file transfer file name and path in the \ref ServerLibFunctions.onTransformFilePath callback.
* The lengths are limited as described in the original parameter.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExportReturns
{
char* transformedFileName; ///< pointer to target file name. Fill the memory pointed to with an utf8 encoded c string
///< containing the new file name. Limited to original->transformedFileNameMaxSize bytes.
char* channelPath; ///< pointer to memory for new path. Fill the memory pointed to with an utf8 encoded c string
///< containing the new path. Limited to original->channelPathMaxSize bytes.
int logFileAction; ///< boolean (1/0). Whether to log this file transfer to the log. Action is not logged regardless
///< of this value if the servers \ref VIRTUALSERVER_LOG_FILETRANSFER property is 0.
};
struct FileTransferCallbackExport
{
anyID clientID; ///< the client who started the file transfer
anyID transferID; ///< local identifier of the transfer that has completed
anyID remoteTransferID; ///< remote identifier of the transfer that has completed
unsigned int status; ///< status of the transfer. One of the values from the \ref FileTransferState enum
const char* statusMessage; ///< utf8 encoded c string containing a human readable description of the status
uint64 remotefileSize; ///< size in bytes of the complete file to be transferred
uint64 bytes; ///< number of bytes transferred. Same as remotefileSize when the transfer completed entirely.
int isSender; ///< boolean. 1 if the server is sending the file. 0 if the server is receiving the file.
};
/*define for file transfer bandwith limits*/
#define BANDWIDTH_LIMIT_UNLIMITED 0xFFFFFFFFFFFFFFFFll
/*defines for speaker locations used by some sound callbacks*/
#ifndef SPEAKER_FRONT_LEFT
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#endif
#define SPEAKER_HEADPHONES_LEFT 0x10000000
#define SPEAKER_HEADPHONES_RIGHT 0x20000000
#define SPEAKER_MONO 0x40000000
#endif /*PUBLIC_DEFINITIONS_H*/
@@ -0,0 +1,217 @@
#ifndef PUBLIC_ERRORS_H
#define PUBLIC_ERRORS_H
//The idea here is: the values are 2 bytes wide, the first byte identifies the group, the second the count within that group
enum Ts3ErrorType {
//general
ERROR_ok = 0x0000, ///< Indicates success.
ERROR_undefined = 0x0001,
ERROR_not_implemented = 0x0002, ///< The attempted operation is not available in this context
ERROR_ok_no_update = 0x0003, ///< Indicates success, but no change occurred. Returned for example upon flushing (e.g. using \ref ts3client_flushChannelUpdates) when all indicated changes already matched the current state.
ERROR_dont_notify = 0x0004,
ERROR_lib_time_limit_reached = 0x0005,
ERROR_out_of_memory = 0x0006, ///< Not enough system memory to perform operation
ERROR_canceled = 0x0007,
ERROR_ok_no_error_event = 0x0008, ///< Indicates success, but no error event was generated. This is used because of the return code management and reduce packets.
//dunno
ERROR_command_not_found = 0x0100,
ERROR_unable_to_bind_network_port = 0x0101, ///< Unspecified failure to create a listening port
ERROR_no_network_port_available = 0x0102, ///< Failure to initialize a listening port for FileTransfer
ERROR_port_already_in_use = 0x0103, ///< Specified port is already in use by a different application
ERROR_command_line_parse_failed = 0x0104, ///< Command line arguments are invalid
ERROR_command_line_exit_version = 0x0105, ///< Command line specified version. The process should exit with code 0 after printing the version.
ERROR_command_line_exit_help = 0x0106, ///< Command line specified help. The process should exit with code 0 after priting the help.
//client
ERROR_client_invalid_id = 0x0200, ///< Client no longer connected
ERROR_client_nickname_inuse = 0x0201, ///< Client name is already in use. Client names must be unique
ERROR_client_protocol_limit_reached = 0x0203, ///< Too many clients on the server
ERROR_client_invalid_type = 0x0204, ///< Function called for normal clients that is only available for query clients or vice versa
ERROR_client_already_subscribed = 0x0205, ///< Attempting to subscribe to a channel already subscribed to
ERROR_client_not_logged_in = 0x0206,
ERROR_client_could_not_validate_identity = 0x0207, ///< Identity not valid or insufficient security level
ERROR_client_invalid_password = 0x0208,
ERROR_client_version_outdated = 0x020a, ///< Server requires newer client version as determined by the min_client_version properties
ERROR_client_is_flooding = 0x020c, ///< Triggered flood protection. Further information is supplied in the extra message if applicable.
ERROR_client_hacked = 0x020d,
ERROR_client_cannot_verify_now = 0x020e,
ERROR_client_login_not_permitted = 0x020f,
ERROR_client_not_subscribed = 0x0210, ///< Action is only available on subscribed channels
//channel
ERROR_channel_invalid_id = 0x0300, ///< Channel does not exist on the server (any longer)
ERROR_channel_protocol_limit_reached = 0x0301, ///< Too many channels on the server
ERROR_channel_already_in = 0x0302, ///< Attempting to move a client or channel to its current channel
ERROR_channel_name_inuse = 0x0303, ///< Channel name is already taken by another channel. Channel names must be unique
ERROR_channel_not_empty = 0x0304, ///< Attempting to delete a channel with clients or sub channels in it
ERROR_channel_can_not_delete_default = 0x0305, ///< Default channel cannot be deleted. Set a new default channel first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_default_require_permanent = 0x0306, ///< Attempt to set a non permanent channel as default channel. Set channel to permanent first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_invalid_flags = 0x0307, ///< Invalid combination of \ref ChannelProperties, trying to remove \ref CHANNEL_FLAG_DEFAULT or set a password on the default channel
ERROR_channel_parent_not_permanent = 0x0308, ///< Attempt to move a permanent channel into a non-permanent one, or set a channel to be permanent that is a sub channel of a non-permanent one
ERROR_channel_maxclients_reached = 0x0309, ///< Channel is full as determined by its \ref CHANNEL_MAXCLIENTS setting
ERROR_channel_maxfamily_reached = 0x030a, ///< Channel tree is full as determined by its \ref CHANNEL_MAXFAMILYCLIENTS setting
ERROR_channel_invalid_order = 0x030b, ///< Invalid value for the \ref CHANNEL_ORDER property. The specified channel must exist on the server and be on the same level.
ERROR_channel_no_filetransfer_supported = 0x030c, ///< Invalid \ref CHANNEL_FILEPATH set for the channel
ERROR_channel_invalid_password = 0x030d, ///< Channel has a password not matching the password supplied in the call
// used in public_rare_errors = 0x030e,
ERROR_channel_invalid_security_hash = 0x030f,
//server
ERROR_server_invalid_id = 0x0400, ///< Chosen virtual server does not exist or is offline
ERROR_server_running = 0x0401, ///< attempting to delete a server that is running. Stop the server before deleting it.
ERROR_server_is_shutting_down = 0x0402, ///< Client disconnected because the server is going offline
ERROR_server_maxclients_reached = 0x0403, ///< Given in the onConnectStatusChange event when the server has reached its maximum number of clients as defined by the \ref VIRTUALSERVER_MAXCLIENTS property
ERROR_server_invalid_password = 0x0404, ///< Specified server password is wrong. Provide the correct password in the \ref ts3client_startConnection / \ref ts3client_startConnectionWithChannelID call.
ERROR_server_is_virtual = 0x0407, ///< Server is in virtual status. The attempted action is not possible in this state. Start the virtual server first.
ERROR_server_is_not_running = 0x0409, ///< Attempting to stop a server that is not online.
ERROR_server_is_booting = 0x040a, // Not used
ERROR_server_status_invalid = 0x040b,
ERROR_server_version_outdated = 0x040d, ///< Attempt to connect to an outdated server version. The server needs to be updated.
ERROR_server_duplicate_running = 0x040e, ///< This server is already running within the instance. Each virtual server may only exist once.
//parameter
ERROR_parameter_quote = 0x0600, // Not used
ERROR_parameter_invalid_count = 0x0601, ///< Attempt to flush changes without previously calling set*VariableAs* since the last flush
ERROR_parameter_invalid = 0x0602, ///< At least one of the supplied parameters did not meet the criteria for that parameter
ERROR_parameter_not_found = 0x0603, ///< Failure to supply all the necessary parameters
ERROR_parameter_convert = 0x0604, ///< Invalid type supplied for a parameter, such as passing a string (ie. "five") that expects a number.
ERROR_parameter_invalid_size = 0x0605, ///< Value out of allowed range. Such as strings are too long/short or numeric values outside allowed range
ERROR_parameter_missing = 0x0606, ///< Neglecting to specify a required parameter
ERROR_parameter_checksum = 0x0607, ///< Attempting to deploy a modified snapshot
//unsorted, need further investigation
ERROR_vs_critical = 0x0700, ///< Failure to create default channel
ERROR_connection_lost = 0x0701, ///< Generic error with the connection.
ERROR_not_connected = 0x0702, ///< Attempting to call functions with a serverConnectionHandler that is not connected. You can use \ref ts3client_getConnectionStatus to check whether the connection handler is connected to a server
ERROR_no_cached_connection_info = 0x0703, ///< Attempting to query connection information (bandwidth usage, ping, etc) without requesting them first using \ref ts3client_requestConnectionInfo
ERROR_currently_not_possible = 0x0704, ///< Requested information is not currently available. You may have to call \ref ts3client_requestClientVariables or \ref ts3client_requestServerVariables
ERROR_failed_connection_initialisation = 0x0705, ///< No TeamSpeak server running on the specified IP address and port
ERROR_could_not_resolve_hostname = 0x0706, ///< Failure to resolve the specified hostname to an IP address
ERROR_invalid_server_connection_handler_id = 0x0707, ///< Attempting to perform actions on a non-existent server connection handler
ERROR_could_not_initialise_input_manager = 0x0708, // Not used
ERROR_clientlibrary_not_initialised = 0x0709, ///< Calling client library functions without successfully calling \ref ts3client_initClientLib before
ERROR_serverlibrary_not_initialised = 0x070a, ///< Calling server library functions without successfully calling \ref ts3server_initServerLib before
ERROR_whisper_too_many_targets = 0x070b, ///< Using a whisper list that contain more clients than the servers \ref VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE property
ERROR_whisper_no_targets = 0x070c, ///< The active whisper list is empty or no clients matched the whisper list (e.g. all channels in the list are empty)
ERROR_connection_ip_protocol_missing = 0x070d, ///< Invalid or unsupported protocol (e.g. attempting an IPv6 connection on an IPv4 only machine)
ERROR_handshake_failed = 0x070e,
ERROR_illegal_server_license = 0x070f,
//file transfer
ERROR_file_invalid_name = 0x0800, ///< Invalid UTF8 string or not a valid file
ERROR_file_invalid_permissions = 0x0801, ///< Permissions prevent opening the file
ERROR_file_already_exists = 0x0802, ///< Target path already exists as a directory
ERROR_file_not_found = 0x0803, ///< Attempt to access or move non existing file
ERROR_file_io_error = 0x0804, ///< Generic file input / output error
ERROR_file_invalid_transfer_id = 0x0805, ///< Attempt to get information about a file transfer after it has already been cleaned up. File transfer information is not available indefinitely after the transfer completed
ERROR_file_invalid_path = 0x0806, ///< specified path contains invalid characters or does not start with "/"
ERROR_file_no_files_available = 0x0807, // Not used
ERROR_file_overwrite_excludes_resume = 0x0808, ///< File overwrite and resume are mutually exclusive. Only one or neither can be 1.
ERROR_file_invalid_size = 0x0809, ///< Attempt to write more bytes than claimed file size.
ERROR_file_already_in_use = 0x080a, ///< File is currently not available, try again later.
ERROR_file_could_not_open_connection = 0x080b, ///< Generic failure in file transfer connection / other party did not conform to file transfer protocol
ERROR_file_no_space_left_on_device = 0x080c, ///< Operating system reports hard disk is full. May be caused by quota limitations.
ERROR_file_exceeds_file_system_maximum_size = 0x080d, ///< File is too large for the file system of the target device.
ERROR_file_transfer_connection_timeout = 0x080e, // Not used
ERROR_file_connection_lost = 0x080f, ///< File input / output timeout or connection failure
ERROR_file_exceeds_supplied_size = 0x0810, // Not used
ERROR_file_transfer_complete = 0x0811, ///< Indicates successful completion
ERROR_file_transfer_canceled = 0x0812, ///< Transfer was cancelled through @ref ts3client_haltTransfer
ERROR_file_transfer_interrupted = 0x0813, ///< Transfer failed because the server is shutting down, or network connection issues
ERROR_file_transfer_server_quota_exceeded = 0x0814, ///< Transfer terminated due to server bandwidth quota being exceeded. No client can transfer files.
ERROR_file_transfer_client_quota_exceeded = 0x0815, ///< Attempt to transfer more data than allowed by this clients' bandwidth quota. Other clients may continue to transfer files.
ERROR_file_transfer_reset = 0x0816, // Not used
ERROR_file_transfer_limit_reached = 0x0817, ///< Too many file transfers are in progress. Try again later
ERROR_file_invalid_storage_class = 0x0818, // TODO: Invalid storage class for HTTP FileTransfer (what is a storage class?)
ERROR_file_invalid_dimension = 0x0819, ///< Avatar image exceeds maximum width or height accepted by the server.
ERROR_file_transfer_channel_quota_exceeded = 0x081a, ///< Transfer failed because the channel quota was exceeded. Uploading to this channel is not possible, but other channels may be fine.
//sound
ERROR_sound_preprocessor_disabled = 0x0900, ///< Cannot set or query pre processor variables with preprocessing disabled
ERROR_sound_internal_preprocessor = 0x0901,
ERROR_sound_internal_encoder = 0x0902,
ERROR_sound_internal_playback = 0x0903,
ERROR_sound_no_capture_device_available = 0x0904, ///< No audio capture devices are available
ERROR_sound_no_playback_device_available = 0x0905, ///< No audio playback devices are available
ERROR_sound_could_not_open_capture_device = 0x0906, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_could_not_open_playback_device = 0x0907, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_handler_has_device = 0x0908, ///< Attempt to open a sound device on a connection handler which already has an open device. Close the already open device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_invalid_capture_device = 0x0909, ///< Attempt to use a device for capture that does not support capturing audio
ERROR_sound_invalid_playback_device = 0x090a, ///< Attempt to use a device for playback that does not support playback of audio
ERROR_sound_invalid_wave = 0x090b, ///< Attempt to use a non WAV file in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle
ERROR_sound_unsupported_wave = 0x090c, ///< Unsupported wave file used in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle.
ERROR_sound_open_wave = 0x090d, ///< Failure to open the specified sound file
ERROR_sound_internal_capture = 0x090e,
ERROR_sound_device_in_use = 0x090f, ///< Attempt to unregister a custom device that is being used. Close the device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_device_already_registerred = 0x0910, ///< Attempt to register a custom device with a device id that has already been used in a previous call. Device ids must be unique.
ERROR_sound_unknown_device = 0x0911, ///< Attempt to open, close, unregister or use a device which is not known. Custom devices must be registered before being used (see \ref ts3client_registerCustomDevice)
ERROR_sound_unsupported_frequency = 0x0912,
ERROR_sound_invalid_channel_count = 0x0913, ///< Invalid device audio channel count, must be > 0
ERROR_sound_read_wave = 0x0914, ///< Failure to read sound samples from an opened wave file. Is this a valid wave file?
ERROR_sound_need_more_data = 0x0915, // for internal purposes only
ERROR_sound_device_busy = 0x0916, // for internal purposes only
ERROR_sound_no_data = 0x0917, ///< Indicates there is currently no data for playback, e.g. nobody is speaking right now.
ERROR_sound_channel_mask_mismatch = 0x0918, ///< Opening a device with an unsupported channel count
//permissions
ERROR_permissions_client_insufficient = 0x0a08, ///< Not enough permissions to perform the requested activity
ERROR_permissions = 0x0a0c, ///< Permissions to use sound device not granted by operating system, e.g. Windows denied microphone access.
//accounting
ERROR_accounting_virtualserver_limit_reached = 0x0b00, ///< Attempt to use more virtual servers than allowed by the license
ERROR_accounting_slot_limit_reached = 0x0b01, ///< Attempt to set more slots than allowed by the license
ERROR_accounting_license_file_not_found = 0x0b02, // Not used
ERROR_accounting_license_date_not_ok = 0x0b03, ///< License expired or not valid yet
ERROR_accounting_unable_to_connect_to_server = 0x0b04, ///< Failure to communicate with accounting backend
ERROR_accounting_unknown_error = 0x0b05, ///< Failure to write update license file
ERROR_accounting_server_error = 0x0b06, // Not used
ERROR_accounting_instance_limit_reached = 0x0b07, ///< More than one process of the server is running
ERROR_accounting_instance_check_error = 0x0b08, ///< Shared memory access failure.
ERROR_accounting_license_file_invalid = 0x0b09, ///< License is not a TeamSpeak license
ERROR_accounting_running_elsewhere = 0x0b0a, ///< A copy of this server is already running in another instance. Each server may only exist once.
ERROR_accounting_instance_duplicated = 0x0b0b, ///< A copy of this server is running already in this process. Each server may only exist once.
ERROR_accounting_already_started = 0x0b0c, ///< Attempt to start a server that is already running
ERROR_accounting_not_started = 0x0b0d,
ERROR_accounting_to_many_starts = 0x0b0e, ///< Starting instance / virtual servers too often in too short a time period
//provisioning server
/// @cond HAS_PROVISIONING
ERROR_provisioning_invalid_password = 0x1100,
ERROR_provisioning_invalid_request = 0x1101,
ERROR_provisioning_no_slots_available = 0x1102,
ERROR_provisioning_pool_missing = 0x1103,
ERROR_provisioning_pool_unknown = 0x1104,
ERROR_provisioning_unknown_ip_location = 0x1105,
ERROR_provisioning_internal_tries_exceeded = 0x1106,
ERROR_provisioning_too_many_slots_requested = 0x1107,
ERROR_provisioning_too_many_reserved = 0x1108,
ERROR_provisioning_could_not_connect = 0x1109,
ERROR_provisioning_auth_server_not_connected = 0x1110,
ERROR_provisioning_auth_data_too_large = 0x1111,
ERROR_provisioning_already_initialized = 0x1112,
ERROR_provisioning_not_initialized = 0x1113,
ERROR_provisioning_connecting = 0x1114,
ERROR_provisioning_already_connected = 0x1115,
ERROR_provisioning_not_connected = 0x1116,
ERROR_provisioning_io_error = 0x1117,
ERROR_provisioning_invalid_timeout = 0x1118,
ERROR_provisioning_ts3server_not_found = 0x1119,
ERROR_provisioning_no_permission = 0x111A,
/// @endcond
// 0x12 - 0x15 are reserved in rare
// screen share
ERROR_already_registered = 0x1600,
ERROR_stream_session_limit_reached = 0x1601,
ERROR_stream_session_not_found = 0x1602,
ERROR_stream_unknown = 0x1603,
ERROR_stream_not_participating = 0x1604,
ERROR_not_streamer = 0x1605,
ERROR_already_joined = 0x1606,
ERROR_join_request_not_found = 0x1607,
ERROR_sfu_failed_to_start = 0x1608,
};
#endif
@@ -0,0 +1,236 @@
#ifndef TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#define TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Version definitions.
#define TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1 1
// Protocol used for communication between the session subscriber and the session (a single stream).
// Commands are sent bidirectionally or unidirectionally between the parties.
// e.g. SESSION => SUBSCRIBER: ON_FRAME, ON_PAUSED_CHANGED
// e.g. SUBSCRIBER => SESSION: ON_FRAME_ACK, ON_RESIZE
// Command type enum with a lowercase type name.
typedef enum
{
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME = 0,
TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE,
TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED,
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK,
TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP,
TS_SESSION_SUBSCRIBER_CMD_REMOVE_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED,
} ts_session_subscriber_command_type_t;
// Pixel format enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_I420 = 0,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_NV12,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ABGR,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ARGB,
} ts_session_subscriber_pixel_format_t;
// Buffer location enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_CPU = 0,
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_GPU
} ts_session_subscriber_buffer_location_t;
// Buffer type enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_SINGLE = 0,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_MAIN,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_SUB
} ts_session_subscriber_buffer_type_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(push, 4)
#endif
// Main buffer header for shared CPU Memory Front/Back Buffers.
// The Main Buffer contains metadata about the current front/back buffer and the versioning for both the main and sub buffer.
// The information from the main buffer can be used to always read the front buffer.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t front_buffer_index; // index of the front buffer. (0: main buffer, 1: sub buffer)
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_main_buffer_header_t;
// Sub buffer header.
typedef struct
{
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
} ts_session_subscriber_sub_buffer_header_t;
// Single frame buffer header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_single_frame_buffer_header_t;
// Command header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // Total message length (header + payload).
ts_session_subscriber_command_type_t type;
uint64_t target_session_id; // always set to the target session id this command is for or is originating from.
uint64_t target_subscriber_id; // 0 if broadcast.
} ts_session_subscriber_command_header_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME.
// The frame data is not included in the message, but is attached seperately or was sent beforehand. The buffer is identified by it's id.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_id; // buffer id, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_frame_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t frame_id;
} ts_session_subscriber_on_frame_ack_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE.
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t width;
uint32_t height;
} ts_session_subscriber_on_resize_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t paused; // 0 or 1.
} ts_session_subscriber_on_paused_changed_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE.
// Contains a single frame buffer. The header is of format |ts_session_subscriber_single_frame_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
ts_session_subscriber_buffer_type_t buffer_type;
} ts_session_subscriber_on_buffer_single_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK.
// Contains a main buffer and a sub buffer. The main buffer header
// contains metadata about the current front/back buffer and
// is of type |ts_session_subscriber_main_buffer_header_t|.
// The sub buffer's header is of type |ts_session_subscriber_sub_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t main_buffer_ptr; // main buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t main_buffer_length;
uint64_t sub_buffer_ptr; // sub buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t sub_buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
} ts_session_subscriber_on_buffer_front_back_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER.
// SUBSCRIBER => SESSION.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_resp_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_release_buffer_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr;
int bits_per_sample;
int sample_rate;
uint32_t number_of_channels;
uint32_t number_of_frames;
int64_t absolute_capture_timestamp_ms;
float volume;
} ts_session_subscriber_on_audio_frames_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t audio_enabled;
} ts_session_subscriber_on_audio_enabled_changed_payload_t;
// Overall Command structure.
typedef struct
{
ts_session_subscriber_command_header_t header;
union
{
ts_session_subscriber_on_frame_payload_t frame;
ts_session_subscriber_on_resize_payload_t resize;
ts_session_subscriber_on_paused_changed_payload_t paused;
ts_session_subscriber_on_frame_ack_payload_t frame_ack;
ts_session_subscriber_on_buffer_single_payload_t buffer_single;
ts_session_subscriber_on_buffer_front_back_payload_t buffer_front_back;
ts_session_subscriber_on_release_buffer_payload_t release_buffer;
ts_session_subscriber_add_subscriber_payload_t add_subscriber;
ts_session_subscriber_add_subscriber_resp_payload_t add_subscriber_resp;
ts_session_subscriber_on_audio_frames_payload_t audio_frames;
ts_session_subscriber_on_audio_enabled_changed_payload_t audio_enabled_changed;
} payload;
} ts_session_subscriber_command_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif // TS_SESSION_SUBSCRIBER_PROTOCOL_H_
@@ -0,0 +1,29 @@
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was team_clientConfig.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()
####################################################################################
include("${CMAKE_CURRENT_LIST_DIR}/team_clientTargets.cmake")
check_required_components(team_client)
@@ -0,0 +1,19 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "teamspeak::client" for configuration "Release"
set_property(TARGET teamspeak::client APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(teamspeak::client PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.so"
IMPORTED_SONAME_RELEASE "libteamspeak_sdk_client.so"
)
list(APPEND _cmake_import_check_targets teamspeak::client )
list(APPEND _cmake_import_check_files_for_teamspeak::client "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.so" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
@@ -0,0 +1,121 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.3")
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.3...4.0)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS teamspeak::client)
list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
if(TARGET "${_cmake_expected_target}")
list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
else()
list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
unset(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target teamspeak::client
add_library(teamspeak::client SHARED IMPORTED)
set_target_properties(teamspeak::client PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
if(NOT CMAKE_VERSION VERSION_LESS "3.23.0")
target_sources(teamspeak::client
INTERFACE
FILE_SET "public_headers"
TYPE "HEADERS"
BASE_DIRS "${_IMPORT_PREFIX}/include"
FILES "${_IMPORT_PREFIX}/include/teamspeak/clientlib.h" "${_IMPORT_PREFIX}/include/teamspeak/clientlib_sdk.h" "${_IMPORT_PREFIX}/include/teamspeak/video/session_subscriber_protocol.h"
)
else()
set_property(TARGET teamspeak::client
APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
"${_IMPORT_PREFIX}/include"
)
endif()
# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/team_clientTargets-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
if(CMAKE_VERSION VERSION_LESS "3.28"
OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target}
OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}")
foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
if(NOT EXISTS "${_cmake_file}")
message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
\"${_cmake_file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
endif()
unset(_cmake_file)
unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>AvailableLibraries</key>
<array>
<dict>
<key>BinaryPath</key>
<string>TeamSpeakClient.framework/TeamSpeakClient</string>
<key>LibraryIdentifier</key>
<string>ios-arm64</string>
<key>LibraryPath</key>
<string>TeamSpeakClient.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
</dict>
<dict>
<key>BinaryPath</key>
<string>TeamSpeakClient.framework/TeamSpeakClient</string>
<key>LibraryIdentifier</key>
<string>ios-arm64-simulator</string>
<key>LibraryPath</key>
<string>TeamSpeakClient.framework</string>
<key>SupportedArchitectures</key>
<array>
<string>arm64</string>
</array>
<key>SupportedPlatform</key>
<string>ios</string>
<key>SupportedPlatformVariant</key>
<string>simulator</string>
</dict>
</array>
<key>CFBundlePackageType</key>
<string>XFWK</string>
<key>XCFrameworkFormatVersion</key>
<string>1.0</string>
</dict>
</plist>
@@ -0,0 +1,23 @@
#ifndef TEAMLOG_LOGTYPES_H
#define TEAMLOG_LOGTYPES_H
enum LogTypes {
LogType_NONE = 0x0000, ///< Logging is disabled
LogType_FILE = 0x0001, ///< Log to regular log file
LogType_CONSOLE = 0x0002, ///< Log to standard output / error
LogType_USERLOGGING = 0x0004, ///< User defined logging. Will call the \ref ServerLibFunctions.onUserLoggingMessageEvent callback for every message to be logged
LogType_NO_NETLOGGING = 0x0008, ///< Not used
LogType_DATABASE = 0x0010, ///< Log to database (deprecated, server only, no effect in SDK)
LogType_SYSLOG = 0x0020, ///< Log to syslog (only available on Linux)
};
enum LogLevel {
LogLevel_CRITICAL = 0, ///< these messages stop the program
LogLevel_ERROR, ///< everything that is really bad, but not so bad we need to shut down
LogLevel_WARNING, ///< everything that *might* be bad
LogLevel_DEBUG, ///< output that might help find a problem
LogLevel_INFO, ///< informational output, like "starting database version x.y.z"
LogLevel_DEVEL ///< developer only output (will not be displayed in release mode)
};
#endif //TEAMLOG_LOGTYPES_H
@@ -0,0 +1,58 @@
#ifndef CLIENTLIB_SDK_H
#define CLIENTLIB_SDK_H
// system
#include <stdlib.h>
// own
#include "teamspeak/public_definitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets the client to which to transmit voice. Stops standard channel voice transmission.
*
* The client will still receive voice from their current channel, however their voice will not be transmitted to their
* current channel anymore. If this call is successful (check onServerErrorEvent) then voice of the specified client
* will be transmitted to all specified channels and all the specified clients. Pass 0 to both target parameter arrays
* to restore default behavior of transmitting voice to current channel. You will receive an onServerErrorEvent with the
* passed returnCode indicating whether or not the operation was successful.
*
* @param server_connection_handler_id the connection handler on which to set the whisper list
* @param client_id the client to set the whisper list for. Set to 0 or your own client ID to set your own whisper list.
* @param channel_ids an array of channel ids to transmit voice to.
* @param channel_ids_size number of elements in aforementioned array.
* @param client_ids a zero terminated array of client ids to transmit voice to.
* @param client_ids_size number of elements in aforementioned array.
* @param impersonate if the target client is a webrtc client, the voice packets will look like as if they have been
* send by the invoking client id
* @param return_code a c string to identify this request in callbacks. Pass an empty string if unused.
* @return An error code from the @ref Ts3ErrorType enum indicating either success or the failure reason
*/
EXPORTDLL unsigned int ts_client_request_client_set_whisper_list(uint64 server_connection_handler_id, anyID client_id,
const uint64* channel_ids,
int channel_ids_size,
const anyID* client_ids,
int client_ids_size, int impersonate,
const char* return_code);
/**
* @brief Send a binary-serialized ClientCommandRequest protobuf to the client library.
*
* The response will be delivered asynchronously via the onProtoResponse callback
* as a serialized ClientCommandResponse protobuf.
*
* @param data Pointer to serialized ClientCommandRequest protobuf bytes
* @param size Size of the serialized data in bytes
* @param return_code Caller-provided string to correlate the response in onProtoResponse. May be NULL.
* @return An error code: ERROR_ok on successful dispatch, ERROR_parameter_invalid on parse failure
*/
EXPORTDLL unsigned int ts3client_postProtoCommand(const void* data, size_t size, const char* return_code);
#ifdef __cplusplus
}
#endif
#endif // CLIENTLIB_SDK_H
@@ -0,0 +1,635 @@
#ifndef PUBLIC_DEFINITIONS_H
#define PUBLIC_DEFINITIONS_H
#include "teamlog/logtypes.h"
#define TS3_MAX_SIZE_CHANNEL_NAME 40 // channel name maximum length in characters
#define TS3_MAX_SIZE_VIRTUALSERVER_NAME 64 // virtual server name maximum length in characters
#define TS3_MAX_SIZE_CLIENT_NICKNAME 64 // client display name length limit in characters
#define TS3_MIN_SIZE_CLIENT_NICKNAME 3 // client display name minimum length in characters
#define TS3_MAX_SIZE_REASON_MESSAGE 80 // length limit in characters for kick, move, etc reasons
#define TS3_MAX_SIZE_TEXTMESSAGE 8192 // text message length limit, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_TOPIC 255 // channel topic lengt limith, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_DESCRIPTION 8192 // channel description length limit, measured in bytes (utf8 encoded)
// server welcome message length limit measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_VIRTUALSERVER_WELCOMEMESSAGE 1024
#define TS3_SIZE_MYTSID 44
// minimum amount of seconds before a clientID that was in use can be assigned to a new client
#define TS3_MIN_SECONDS_CLIENTID_REUSE 300
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32)
typedef unsigned __int16 anyID;
typedef unsigned __int64 uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __declspec(dllexport)
#else
#define EXPORTDLL
#endif
#endif
#else
#include <stdint.h>
typedef uint16_t anyID;
typedef uint64_t uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __attribute__((visibility("default")))
#else
#define EXPORTDLL
#endif
#endif
#endif
enum Visibility
{
ENTER_VISIBILITY = 0, ///< Client joined from an unsubscribed channel, or joined the server.
RETAIN_VISIBILITY, ///< Client switched from one subscribed channel to a different subscribed channel.
LEAVE_VISIBILITY ///< Client switches to an unsubscribed channel, or disconnected from server.
};
enum ConnectStatus
{
STATUS_DISCONNECTED = 0, ///< There is no activity to the server, this is the default value
STATUS_CONNECTING, ///< We are trying to connect, we haven't got a client id yet, we haven't been accepted by the server
STATUS_CONNECTED, ///< The server has accepted us, we can talk and hear and we have a client id, but we don't
///< have the channels and clients yet, we can get server infos (welcome msg etc.)
STATUS_CONNECTION_ESTABLISHING, ///< we are connected and we are visible
STATUS_CONNECTION_ESTABLISHED, ///< we are connected and we have the client and channels available
};
enum LocalTestMode
{
TEST_MODE_OFF = 0,
TEST_MODE_VOICE_LOCAL_ONLY,
TEST_MODE_VOICE_LOCAL_AND_REMOTE,
TEST_MODE_TALK_STATUS_CHANGES_ONLY
};
enum TalkStatus
{
STATUS_NOT_TALKING = 0, ///< client is not talking
STATUS_TALKING = 1, ///< client is talking
STATUS_TALKING_WHILE_DISABLED = 2, ///< client is talking while the microphone is muted (only valid for own client)
};
enum CodecType
{
CODEC_SPEEX_NARROWBAND = 0, ///< (deprecated) mono, 16bit, 8kHz, bitrate dependent on the quality setting
CODEC_SPEEX_WIDEBAND, ///< (deprecated) mono, 16bit, 16kHz, bitrate dependent on the quality setting
CODEC_SPEEX_ULTRAWIDEBAND, ///< (deprecated) mono, 16bit, 32kHz, bitrate dependent on the quality setting
CODEC_CELT_MONO, ///< (deprecated) mono, 16bit, 48kHz, bitrate dependent on the quality setting
CODEC_OPUS_VOICE, ///< mono, 16bit, 48khz, bitrate dependent on the quality setting, optimized for voice
CODEC_OPUS_MUSIC, ///< stereo, 16bit, 48khz, bitrate dependent on the quality setting, optimized for music
};
enum CodecEncryptionMode
{
CODEC_ENCRYPTION_PER_CHANNEL = 0, ///< voice data encryption decided per channel
CODEC_ENCRYPTION_FORCED_OFF, ///< voice data encryption disabled
CODEC_ENCRYPTION_FORCED_ON, ///< voice data encryption enabled
};
enum TextMessageTargetMode
{
TextMessageTarget_CLIENT = 1, ///< Message is a private message to another client
TextMessageTarget_CHANNEL, ///< Message is sent to a channel, received by all clients in that channel at the time
TextMessageTarget_SERVER, ///< Message is sent to every client on the server
TextMessageTarget_MAX
};
enum MuteInputStatus
{
MUTEINPUT_NONE = 0, ///< Microphone is not muted, audio is sent to the server
MUTEINPUT_MUTED, ///< Microphone is muted, no audio is transmitted to the server
};
enum MuteOutputStatus
{
MUTEOUTPUT_NONE = 0, ///< Speaker is active, server is sending us audio
MUTEOUTPUT_MUTED, ///< Speaker is muted, server is not sending audio to us
};
enum HardwareInputStatus
{
HARDWAREINPUT_DISABLED = 0, ///< no capture device opened
HARDWAREINPUT_ENABLED, ///< capture device open
};
enum HardwareOutputStatus
{
HARDWAREOUTPUT_DISABLED = 0, ///< no playback device opened
HARDWAREOUTPUT_ENABLED, ///< playback device open
};
enum InputDeactivationStatus
{
INPUT_ACTIVE = 0, ///< Audio is captured from the capture device.
INPUT_DEACTIVATED = 1, ///< No audio is captured from the capture device.
};
enum ReasonIdentifier
{
REASON_NONE = 0, ///< no reason data
REASON_MOVED = 1, ///< client was moved
REASON_SUBSCRIPTION = 2, // no reason data
REASON_LOST_CONNECTION = 3, // reasonmsg=reason
REASON_KICK_CHANNEL = 4, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER = 5, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER_BAN = 6, //{SectionInvoker} reasonmsg=reason bantime=time //{SectionInvoker} is only added server->client
REASON_SERVERSTOP = 7, // reasonmsg=reason
REASON_CLIENTDISCONNECT = 8, // reasonmsg=reason
REASON_CHANNELUPDATE = 9, // no reason data
REASON_CHANNELEDIT = 10, //{SectionInvoker}
REASON_CLIENTDISCONNECT_SERVER_SHUTDOWN = 11, // reasonmsg=reason
};
enum Protocol_Encryption_Cipher
{
AES_128 = 0b00000000,
AES_256 = 0b00000001,
PROTOCOL_ENCRYPTION_CIPHER_END_MARKER,
RESERVED = 0b00010000, // reserved until puzzle v2 is fully released, then can be reused
PUZZLE_2 = 0b00100000,
};
enum ChannelProperties
{
CHANNEL_NAME = 0, ///< String. Read/Write. Name of the channel. Always available.
CHANNEL_TOPIC, ///< String. Read/Write. Short single line text describing what the channel is about. Always available.
CHANNEL_DESCRIPTION, ///< String. Read/Write. Arbitrary text (up to 8k bytes) with information about the channel.
///< Must be requested (\ref ts3client_requestChannelDescription)
CHANNEL_PASSWORD, ///< String. Read/Write. Password of the channel. Read access is limited to the server. Clients
///< will only ever see the last password they attempted to use when joining the channel. Always available.
CHANNEL_CODEC, ///< Integer. Read/Write. The codec this channel is using. One of the values from the \ref CodecType
///< enum. Always available.
CHANNEL_CODEC_QUALITY, ///< Integer. Read/Write. The quality setting of the channel. Valid values are 0 to 10 inclusive.
///< Higher value means better voice quality but also more bandwidth usage. Always available.
CHANNEL_MAXCLIENTS, ///< Integer. Read/Write. The number of clients that can be in the channel simultaneously.
///< Always available.
CHANNEL_MAXFAMILYCLIENTS, ///< Integer. Read/Write. The total number of clients that can be in this channel and all
///< sub channels of this channel. Always available.
CHANNEL_ORDER, ///< UInt64. Read/Write. The ID of the channel below which this channel should be displayed. If 0
///< the channel is sorted at the top of the current level. Always available.
CHANNEL_FLAG_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when empty.
///< Permanent channels are stored to the database and available after server restart. SDK
///< users will need to take care of restoring channel at server start on their own.
///< Mutually exclusive with \ref CHANNEL_FLAG_SEMI_PERMANENT. Always available.
CHANNEL_FLAG_SEMI_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when
///< empty. Semi permanent channels are not stored to disk and gone after server
///< restart but remain while empty. Mutually exclusive with \ref
///< CHANNEL_FLAG_PERMANENT. Always available.
CHANNEL_FLAG_DEFAULT, ///< Integer. Read/Write. Boolean (1/0). The default channel is the channel that all clients
///< are located in when they join the server, unless the client explicitly specified a
///< different channel when connecting and is allowed to join their preferred channel. Only
///< one channel on the server can have this flag set. The default channel must have \ref
///< CHANNEL_FLAG_PERMANENT set. Always available.
CHANNEL_FLAG_PASSWORD, ///< Integer. Read/Write. Boolean (1/0) indicating whether this channel is password protected.
///< When removing or setting \ref CHANNEL_PASSWORD you also need to adjust this flag.
CHANNEL_CODEC_LATENCY_FACTOR, ///< (deprecated) Integer. Read/Write. Allows to increase packet size, reducing
///< bandwith at the cost of higher latency of voice transmission. Valid values are
///< 1-10 inclusive. 1 is the default and offers the lowest latency. Always available.
CHANNEL_CODEC_IS_UNENCRYPTED, ///< Integer. Read/Write. Boolean (1/0). If 0 voice data is encrypted, if 1 the voice
///< data is not encrypted. Only used if the server \ref
///< VIRTUALSERVER_CODEC_ENCRYPTION_MODE is set to \ref CODEC_ENCRYPTION_PER_CHANNEL.
///< Always available.
CHANNEL_SECURITY_SALT, ///< String. Read/Write. SDK Only, not used by TeamSpeak. This channels security hash. When
///< a client joins their \ref CLIENT_SECURITY_HASH is compared to this value, to allow or
///< deny the client access to the channel. Used to enforce clients joining the server with
///< specific identity and \ref CLIENT_META_DATA. See SDK Documentation about this feature
///< for further details. Always available.
CHANNEL_DELETE_DELAY, ///< UInt64. Read/Write. Number of seconds deletion of temporary channels is delayed after
///< the last client leaves the channel. Channel is only deleted if empty when the delete
///< delay expired. Always available.
CHANNEL_UNIQUE_IDENTIFIER, ///< String. Read only. An identifier that uniquely identifies a channel. Available in
///< Server >= 3.10.0
CHANNEL_ENDMARKER,
};
enum ClientProperties
{
CLIENT_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Public Identity, can be used to identify a client
///< installation. Remains identical as long as the client keeps using the same
///< identity. Available for visible clients.
CLIENT_NICKNAME, ///< String. Read/Write. Display name of the client. Available for visible clients.
CLIENT_VERSION, ///< String. Read only. Version String of the client used. For clients other than ourself this
///< needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_PLATFORM, ///< String. Read only. Operating system used by the client. For other clients other than ourself
///< this needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_FLAG_TALKING, ///< Integer. Read only. Whether the client is talking. Available on clients that are either
///< whispering to us, or in our channel.
CLIENT_INPUT_MUTED, ///< Integer. Read/Write. Microphone mute status. Available for visible clients. One of the
///< values from the \ref MuteInputStatus enum.
CLIENT_OUTPUT_MUTED, ///< Integer. Read/Write. Speaker mute status. Speaker mute implies microphone mute. Available
///< for visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_OUTPUTONLY_MUTED, ///< Integer. Read/Write. Speaker mute status. Microphone may be active. Available for
///< visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_INPUT_HARDWARE, ///< Integer. Read only. Indicates whether a capture device is open. Available for visible
///< clients. One of the values from the \ref HardwareInputStatus enum.
CLIENT_OUTPUT_HARDWARE, ///< Integer. Read only. Indicates whether a playback device is open. Available for visible
///< clients. One of the values from the \ref HardwareOutputStatus enum.
CLIENT_INPUT_DEACTIVATED, ///< Integer. Read/Write. Not available server side. Local microphone mute status.
///< Available only for own client. Used to implement Push To Talk. One of the values from
///< the \ref InputDeactivationStatus enum.
CLIENT_IDLE_TIME, ///< UInt64. Read only. Seconds since last activity. Available only for own client.
CLIENT_DEFAULT_CHANNEL, ///< String. Read only. User specified channel they joined when connecting to the server.
///< Available only for own client.
CLIENT_DEFAULT_CHANNEL_PASSWORD, ///< String. Read only. User specified channel password for the channel they
///< attempted to join when connecting to the server. Available only for own
///< client.
CLIENT_SERVER_PASSWORD, ///< String. Read only. User specified server password. Available only for own client.
CLIENT_META_DATA, ///< String. Read/Write. Can be used to store up to 4096 bytes of information on clients. Not
///< used by TeamSpeak. Available for visible clients.
CLIENT_IS_MUTED, ///< Integer. Read only. Not available server side. Indicates whether we have muted the client
///< using \ref ts3client_requestMuteClients. Available for visible clients other than ourselves.
CLIENT_IS_RECORDING, ///< Integer. Read only. Indicates whether the client is recording incoming audio. Available
///< for visible clients.
CLIENT_VOLUME_MODIFICATOR, ///< Integer. Read only. Volume adjustment for this client as set by \ref
///< ts3client_setClientVolumeModifier. Available for visible clients.
CLIENT_VERSION_SIGN, ///< String. Read only. TeamSpeak internal signature.
CLIENT_SECURITY_HASH, ///< String. Read/Write. This clients security hash. Not used by TeamSpeak, SDK only. Hash is
///< provided by an outside source. A channel will use the security salt + other client data
///< to calculate a hash, which must be the same as the one provided here. See SDK
///< documentation about Client / Channel Security Hashes for more details.
CLIENT_ENCRYPTION_CIPHERS, ///< String. Read only. SDK only. List of available ciphers this client can use.
CLIENT_IS_STREAMING, ///< bool. Read only, Is currently streaming.
CLIENT_ENDMARKER,
};
enum VirtualServerProperties
{
VIRTUALSERVER_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Unique identifier for a virtual server, does not
///< change on server restart. Available if \ref ts3client_getConnectionStatus
///< is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_NAME, ///< String. Read/Write. The virtual server display name. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_WELCOMEMESSAGE, ///< String. Read/Write. The welcome message displayed to clients on connect.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED. Not
///< updated automatically when changed, updates need to be requested (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_PLATFORM, ///< String. Read only. The operating system the server is running on. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_VERSION, ///< String. Read only. The server software version string. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_MAXCLIENTS, ///< UInt64. Read/Write. The maximum number of clients that can be connected
///< simultaneously. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_PASSWORD, ///< String. Read/Write. The server password. Read access is limited to the server. Clients
///< will only get the password they supplied when connecting. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_CLIENTS_ONLINE, ///< UInt64. Read only. The current number of clients connected to the server,
///< including query connections. Only available on request (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_CHANNELS_ONLINE, ///< UInt64. Read only. The current number of channels on the server. Only
///< available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CREATED, ///< Integer. Read only. The time this virtual server was created as unix timestamp.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_UPTIME, ///< UInt64. Read only. Number of seconds that have passed since the virtual server was
///< started. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CODEC_ENCRYPTION_MODE, ///< Integer. Read/Write. Boolean (1/0) that specifies if voice data is encrypted
///< during transfer. One of the values from the \ref CodecEncryptionMode enum.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_ENCRYPTION_CIPHERS, ///< String. Read/Write. Comma separated list of available ciphers to encrypt the
///< connection. The server will use the first cipher in the list that is also
///< listed in the \ref CLIENT_ENCRYPTION_CIPHERS of the connecting client.
///< Clients will fail to connect if no match is found. Always available.
VIRTUALSERVER_ADDRESS, ///< Any resolvable address for the specific virtual server
VIRTUALSERVER_VERSION_SIGN, ///< String. Read only. Signature of Platform and Version.
VIRTUALSERVER_ENDMARKER,
VIRTUALSERVER_FILEBASE = 24, ///< String. Read only. The path to the base directory used to store files
///< transferred using file transfer. Available only on the server. Is set by \ref
///< ts3server_enableFileManager
VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH = 29, ///< UInt64. Read/Write. Maximum traffic in bytes the server can
///< use for file transfer downloads. Only available on request
///< (\ref ts3client_requestServerVariables).
VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH = 30, ///< UInt64. Read/Write. Maximum traffic in bytes the server can use
///< for file transfer uploads. Only available on request (=>
///< requestServerVariables)
VIRTUALSERVER_LOG_FILETRANSFER = 64 ///< Integer. Read/Write. Boolean (1/0) indicating whether to include file
///< transfer activities (uploading or downloading of files) in the server log.
///< Always available.
};
/**
* Various connection properties.
* These are all read only, and except for your own client must be requested using \ref ts3client_requestConnectionInfo
*/
enum ConnectionProperties
{
CONNECTION_PING = 0, ///< UInt64. Round trip latency for the connection based on the last 5 seconds. On the server
///< this is the average across all connected clients for the last 5 seconds.
CONNECTION_PING_DEVIATION, ///< Double. Standard deviation for the round trip latency in \ref CONNECTION_PING
CONNECTION_CONNECTED_TIME, ///< UInt64. Seconds the client has been connected.
CONNECTION_IDLE_TIME, ///< UInt64. Time in seconds since the last activity (voice transmission, switching channels,
///< changing mic / speaker mute status) of the client.
CONNECTION_CLIENT_IP, ///< String. IP of this client (as seen from the server side)
CONNECTION_CLIENT_PORT, ///< UInt64. Client side port of this client (as seen from the server side)
CONNECTION_SERVER_IP, ///< String. The IP or hostname used to connect to the server. Only available on yourself.
CONNECTION_SERVER_PORT, ///< UInt64. The server port connected to. Only available on yourself.
CONNECTION_PACKETS_SENT_SPEECH, ///< UInt64. The number of voice packets transmitted by the client.
CONNECTION_PACKETS_SENT_KEEPALIVE, ///< UInt64. The number of keep alive packets transmitted by the client.
CONNECTION_PACKETS_SENT_CONTROL, ///< UInt64. The number of command & control packets transmitted by the client.
CONNECTION_PACKETS_SENT_TOTAL, ///< UInt64. Total number of packets transmitted by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_SENT_SPEECH, \ref CONNECTION_PACKETS_SENT_KEEPALIVE and
///< \ref CONNECTION_PACKETS_SENT_CONTROL
CONNECTION_BYTES_SENT_SPEECH, ///< UInt64. Outgoing traffic used for voice data by the client.
CONNECTION_BYTES_SENT_KEEPALIVE, ///< UInt64. Outgoing traffic used for keeping the connection alive by the client.
CONNECTION_BYTES_SENT_CONTROL, ///< UInt64. Outgoing traffic used for command & control data by the client.
CONNECTION_BYTES_SENT_TOTAL, ///< UInt64. Total outgoing traffic to the server by this client. Equal to the sum of
///< \ref CONNECTION_BYTES_SENT_SPEECH, \ref CONNECTION_BYTES_SENT_KEEPALIVE and \ref
///< CONNECTION_BYTES_SENT_CONTROL
CONNECTION_PACKETS_RECEIVED_SPEECH, ///< UInt64. Number of voice packets received by the client.
CONNECTION_PACKETS_RECEIVED_KEEPALIVE, ///< UInt64. Number of keep alive packets received by the client.
CONNECTION_PACKETS_RECEIVED_CONTROL, ///< UInt64. Number of command & control packets received by the client.
CONNECTION_PACKETS_RECEIVED_TOTAL, ///< UInt64. Total number of packets received by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_RECEIVED_SPEECH, \ref
///< CONNECTION_PACKETS_RECEIVED_KEEPALIVE and \ref
///< CONNECTION_PACKETS_RECEIVED_CONTROL
CONNECTION_BYTES_RECEIVED_SPEECH, ///< UInt64. Incoming traffic used by the client for voice data.
CONNECTION_BYTES_RECEIVED_KEEPALIVE, ///< UInt64. Incoming traffic used by the client to keep the connection alive.
CONNECTION_BYTES_RECEIVED_CONTROL, ///< UInt64. Incoming traffic used by the client for command & control data.
CONNECTION_BYTES_RECEIVED_TOTAL, ///< UInt64. Total incoming traffic used by the client. Equal to the sum of \ref
///< CONNECTION_BYTES_RECEIVED_SPEECH, \ref CONNECTION_BYTES_RECEIVED_KEEPALIVE and
///< \ref CONNECTION_BYTES_RECEIVED_CONTROL
CONNECTION_PACKETLOSS_SPEECH, ///< Double. Percentage points of voice packets for the client that did not arrive at
///< the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_KEEPALIVE, ///< Double. Percentage points of keep alive packets for the client that did not
///< arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_CONTROL, ///< Double. Percentage points of command & control packets for the client that did
///< not arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_TOTAL, ///< Double. Cumulative chance in percentage points with which a packet round trip
///< failed because a packet was lost
CONNECTION_SERVER2CLIENT_PACKETLOSS_SPEECH, ///< Double. Probability with which a voice packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< server was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the server was not
///< received by the client.
CONNECTION_CLIENT2SERVER_PACKETLOSS_SPEECH, ///< Double. Probability with which a speech packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< client was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the client was not
///< received by the server.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes sent for speech data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes sent for keepalive data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes sent for control data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes sent in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second sent for speech data, averaged over the
///< last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second sent for keepalive data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second sent for control data, averaged over
///< the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second sent, averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes received for speech data in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes received for keepalive data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes received for control data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes received in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second received for speech data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second received for keepalive data,
///< averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second received for control data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second received, averaged over the last minute.
CONNECTION_DUMMY_0,
CONNECTION_DUMMY_1,
CONNECTION_DUMMY_2,
CONNECTION_DUMMY_3,
CONNECTION_DUMMY_4,
CONNECTION_DUMMY_5,
CONNECTION_DUMMY_6,
CONNECTION_DUMMY_7,
CONNECTION_DUMMY_8,
CONNECTION_DUMMY_9,
CONNECTION_FILETRANSFER_BANDWIDTH_SENT, ///< UInt64. Current file transfer upstream activity in bytes per second.
///< Only available on request (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, ///< UInt64. Current file transfer downstream activity in bytes per
///< second. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, ///< UInt64. Total downstream traffic, in bytes, used for file
///< transfer since the server was started. Only available on request
///< (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, ///< UInt64. Total upstream traffic, in bytes, used for file transfer
///< since the server was started. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_ENDMARKER
};
/**
* Describes a client position in 3 dimensional space, used for 3D Sound.
*/
typedef struct
{
float x; ///< X co-ordinate in 3D space.
float y; ///< Y co-ordinate in 3D space.
float z; ///< Z co-ordinate in 3D space.
} TS3_VECTOR;
enum GroupWhisperType
{
GROUPWHISPERTYPE_SERVERGROUP = 0, ///< Whisper list consists of server groups
GROUPWHISPERTYPE_CHANNELGROUP = 1, ///< Whisper list consists of channel groups
GROUPWHISPERTYPE_CHANNELCOMMANDER = 2, ///< whisper to channel commanders
GROUPWHISPERTYPE_ALLCLIENTS = 3, ///< whisper to all clients
GROUPWHISPERTYPE_ENDMARKER,
};
enum GroupWhisperTargetMode
{
GROUPWHISPERTARGETMODE_ALL = 0,
GROUPWHISPERTARGETMODE_CURRENTCHANNEL = 1, ///< Whisper the current channel of the client
GROUPWHISPERTARGETMODE_PARENTCHANNEL = 2, ///< Whisper the parent channel of whatever channel the client is currently in
GROUPWHISPERTARGETMODE_ALLPARENTCHANNELS = 3, ///< Whipser to the parent channel and all their parent channels as well
GROUPWHISPERTARGETMODE_CHANNELFAMILY = 4, ///< Whisper to the current channel and all its sub channels
GROUPWHISPERTARGETMODE_ANCESTORCHANNELFAMILY = 5, ///< Whisper to the current channel, all its parent and sub channels.
GROUPWHISPERTARGETMODE_SUBCHANNELS = 6, ///< Whisper to all sub channels of the current channel of the client
GROUPWHISPERTARGETMODE_ENDMARKER,
};
enum MonoSoundDestination
{
MONO_SOUND_DESTINATION_ALL = 0, ///< Send mono sound to all available speakers
MONO_SOUND_DESTINATION_FRONT_CENTER = 1, ///< Send mono sound to front center speaker if available
MONO_SOUND_DESTINATION_FRONT_LEFT_AND_RIGHT = 2 ///< Send mono sound to front left/right speakers if available
};
enum SecuritySaltOptions
{
SECURITY_SALT_CHECK_NICKNAME = 1, ///< put nickname into security hash
SECURITY_SALT_CHECK_META_DATA = 2 ///< put meta data into security hash
};
/*this enum is used to disable client commands on the server*/
enum ClientCommand
{
CLIENT_COMMAND_requestConnectionInfo = 0, ///< disable client connection info request (client bandwidth usage, ip,
///< port, ping)
CLIENT_COMMAND_requestClientMove = 1, ///< disable moving clients
CLIENT_COMMAND_requestXXMuteClients = 2, ///< disable muting other clients
CLIENT_COMMAND_requestClientKickFromXXX = 3, ///< disable kicking clients
CLIENT_COMMAND_flushChannelCreation = 4, ///< disable creating channels
CLIENT_COMMAND_flushChannelUpdates = 5, ///< disable editing channels
CLIENT_COMMAND_requestChannelMove = 6, ///< disable moving channels
CLIENT_COMMAND_requestChannelDelete = 7, ///< disable deleting channels
CLIENT_COMMAND_requestChannelDescription = 8, ///< disable channel descriptions
CLIENT_COMMAND_requestChannelXXSubscribeXXX = 9, ///< disable being able to see clients in channels other than the
///< current channel the client is in
CLIENT_COMMAND_requestServerConnectionInfo = 10, ///< disable server connection info request (server bandwidth
///< usage, ip, port, ping)
CLIENT_COMMAND_requestSendXXXTextMsg = 11, ///< disable text messaging
CLIENT_COMMAND_filetransfers = 12, ///< disable file transfer
CLIENT_COMMAND_ENDMARKER
};
/* Access Control List*/
enum ACLType
{
ACL_NONE = 0,
ACL_WHITE_LIST = 1,
ACL_BLACK_LIST = 2
};
/* file transfer actions*/
enum FTAction
{
FT_INIT_SERVER = 0, ///< The virtual server is created. result->channelPath can be changed to create a different
///< directory than the default 'virtualserver_x' where x is the virtual server.
FT_INIT_CHANNEL = 1, ///< A channel is created. result->channelPath can be changed to create a different directory
///< then the default 'channel_x' where x is the channel id.
FT_UPLOAD = 2, ///< A file is being uploaded. All values in the result struct can be modified.
FT_DOWNLOAD = 3, ///< A file is being downloaded. All values in the result struct can be modified.
FT_DELETE = 4, ///< A file is being deleted. All values in the result struct can be modified.
FT_CREATEDIR = 5, ///< A directory is being created in a channel. All values in the result struct can be modified.
FT_RENAME = 6, ///< A file or folder is being renamed. The callback will be called twice! Once for the old and then
///< for the new name. All values in the result struct can be modified.
FT_FILELIST = 7, ///< A directory listing is requested. All values in the result struct can be modified.
FT_FILEINFO = 8 ///< Information of a file is requested. All values in the result struct can be modified.
};
/* file transfer status */
enum FileTransferState
{
FILETRANSFER_INITIALISING = 0, ///< File transfer is establishing connection.
FILETRANSFER_ACTIVE, ///< File transfer is in progress
FILETRANSFER_FINISHED, ///< File transfer has finished
};
/* file transfer types */
enum FileTransferType
{
FileListType_Directory = 0, ///< The file entry is a directory
FileListType_File, ///< The file entry is a regular file
};
/* some structs to handle variables in callbacks */
#define MAX_VARIABLES_EXPORT_COUNT 64
struct VariablesExportItem
{
unsigned char itemIsValid; ///< Whether or not there is any data in this item. Ignore this item if this is 0.
unsigned char proposedIsSet; ///< The value in proposed is set. If 0 ignore proposed
const char* current; ///< current value (stored in memory)
const char* proposed; ///< New value to change to (const, so no updates please)
};
struct VariablesExport
{
struct VariablesExportItem items[MAX_VARIABLES_EXPORT_COUNT];
};
struct ClientMiniExport
{
anyID ID; ///< id of the client
uint64 channel; ///< the channel the client is in
const char* ident; ///< client public identity
const char* nickname; ///< client display name
};
/**
* Structure used to describe a file transfer in the \ref ServerLibFunctions.onTransformFilePath callback.
* This describes the original values, and also contains hints for length limitations of the result parameter
* of the callback.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExport
{
uint64 channel; ///< The channel id of the file. 0 if action is \ref FT_INIT_SERVER
const char* filename; ///< utf8 encoded c string containing the original file name as intended by the client.
int action; ///< The action to be performed. One of the values from the \ref FTAction enum. Defines which values of
///< the result struct can be modified.
int transformedFileNameMaxSize; ///< The maximum length the file name can be rewritten to.
int channelPathMaxSize; ///< The maximum length the path can be rewritten to.
};
/**
* Structure to rewrite the file transfer file name and path in the \ref ServerLibFunctions.onTransformFilePath callback.
* The lengths are limited as described in the original parameter.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExportReturns
{
char* transformedFileName; ///< pointer to target file name. Fill the memory pointed to with an utf8 encoded c string
///< containing the new file name. Limited to original->transformedFileNameMaxSize bytes.
char* channelPath; ///< pointer to memory for new path. Fill the memory pointed to with an utf8 encoded c string
///< containing the new path. Limited to original->channelPathMaxSize bytes.
int logFileAction; ///< boolean (1/0). Whether to log this file transfer to the log. Action is not logged regardless
///< of this value if the servers \ref VIRTUALSERVER_LOG_FILETRANSFER property is 0.
};
struct FileTransferCallbackExport
{
anyID clientID; ///< the client who started the file transfer
anyID transferID; ///< local identifier of the transfer that has completed
anyID remoteTransferID; ///< remote identifier of the transfer that has completed
unsigned int status; ///< status of the transfer. One of the values from the \ref FileTransferState enum
const char* statusMessage; ///< utf8 encoded c string containing a human readable description of the status
uint64 remotefileSize; ///< size in bytes of the complete file to be transferred
uint64 bytes; ///< number of bytes transferred. Same as remotefileSize when the transfer completed entirely.
int isSender; ///< boolean. 1 if the server is sending the file. 0 if the server is receiving the file.
};
/*define for file transfer bandwith limits*/
#define BANDWIDTH_LIMIT_UNLIMITED 0xFFFFFFFFFFFFFFFFll
/*defines for speaker locations used by some sound callbacks*/
#ifndef SPEAKER_FRONT_LEFT
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#endif
#define SPEAKER_HEADPHONES_LEFT 0x10000000
#define SPEAKER_HEADPHONES_RIGHT 0x20000000
#define SPEAKER_MONO 0x40000000
#endif /*PUBLIC_DEFINITIONS_H*/
@@ -0,0 +1,217 @@
#ifndef PUBLIC_ERRORS_H
#define PUBLIC_ERRORS_H
//The idea here is: the values are 2 bytes wide, the first byte identifies the group, the second the count within that group
enum Ts3ErrorType {
//general
ERROR_ok = 0x0000, ///< Indicates success.
ERROR_undefined = 0x0001,
ERROR_not_implemented = 0x0002, ///< The attempted operation is not available in this context
ERROR_ok_no_update = 0x0003, ///< Indicates success, but no change occurred. Returned for example upon flushing (e.g. using \ref ts3client_flushChannelUpdates) when all indicated changes already matched the current state.
ERROR_dont_notify = 0x0004,
ERROR_lib_time_limit_reached = 0x0005,
ERROR_out_of_memory = 0x0006, ///< Not enough system memory to perform operation
ERROR_canceled = 0x0007,
ERROR_ok_no_error_event = 0x0008, ///< Indicates success, but no error event was generated. This is used because of the return code management and reduce packets.
//dunno
ERROR_command_not_found = 0x0100,
ERROR_unable_to_bind_network_port = 0x0101, ///< Unspecified failure to create a listening port
ERROR_no_network_port_available = 0x0102, ///< Failure to initialize a listening port for FileTransfer
ERROR_port_already_in_use = 0x0103, ///< Specified port is already in use by a different application
ERROR_command_line_parse_failed = 0x0104, ///< Command line arguments are invalid
ERROR_command_line_exit_version = 0x0105, ///< Command line specified version. The process should exit with code 0 after printing the version.
ERROR_command_line_exit_help = 0x0106, ///< Command line specified help. The process should exit with code 0 after priting the help.
//client
ERROR_client_invalid_id = 0x0200, ///< Client no longer connected
ERROR_client_nickname_inuse = 0x0201, ///< Client name is already in use. Client names must be unique
ERROR_client_protocol_limit_reached = 0x0203, ///< Too many clients on the server
ERROR_client_invalid_type = 0x0204, ///< Function called for normal clients that is only available for query clients or vice versa
ERROR_client_already_subscribed = 0x0205, ///< Attempting to subscribe to a channel already subscribed to
ERROR_client_not_logged_in = 0x0206,
ERROR_client_could_not_validate_identity = 0x0207, ///< Identity not valid or insufficient security level
ERROR_client_invalid_password = 0x0208,
ERROR_client_version_outdated = 0x020a, ///< Server requires newer client version as determined by the min_client_version properties
ERROR_client_is_flooding = 0x020c, ///< Triggered flood protection. Further information is supplied in the extra message if applicable.
ERROR_client_hacked = 0x020d,
ERROR_client_cannot_verify_now = 0x020e,
ERROR_client_login_not_permitted = 0x020f,
ERROR_client_not_subscribed = 0x0210, ///< Action is only available on subscribed channels
//channel
ERROR_channel_invalid_id = 0x0300, ///< Channel does not exist on the server (any longer)
ERROR_channel_protocol_limit_reached = 0x0301, ///< Too many channels on the server
ERROR_channel_already_in = 0x0302, ///< Attempting to move a client or channel to its current channel
ERROR_channel_name_inuse = 0x0303, ///< Channel name is already taken by another channel. Channel names must be unique
ERROR_channel_not_empty = 0x0304, ///< Attempting to delete a channel with clients or sub channels in it
ERROR_channel_can_not_delete_default = 0x0305, ///< Default channel cannot be deleted. Set a new default channel first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_default_require_permanent = 0x0306, ///< Attempt to set a non permanent channel as default channel. Set channel to permanent first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_invalid_flags = 0x0307, ///< Invalid combination of \ref ChannelProperties, trying to remove \ref CHANNEL_FLAG_DEFAULT or set a password on the default channel
ERROR_channel_parent_not_permanent = 0x0308, ///< Attempt to move a permanent channel into a non-permanent one, or set a channel to be permanent that is a sub channel of a non-permanent one
ERROR_channel_maxclients_reached = 0x0309, ///< Channel is full as determined by its \ref CHANNEL_MAXCLIENTS setting
ERROR_channel_maxfamily_reached = 0x030a, ///< Channel tree is full as determined by its \ref CHANNEL_MAXFAMILYCLIENTS setting
ERROR_channel_invalid_order = 0x030b, ///< Invalid value for the \ref CHANNEL_ORDER property. The specified channel must exist on the server and be on the same level.
ERROR_channel_no_filetransfer_supported = 0x030c, ///< Invalid \ref CHANNEL_FILEPATH set for the channel
ERROR_channel_invalid_password = 0x030d, ///< Channel has a password not matching the password supplied in the call
// used in public_rare_errors = 0x030e,
ERROR_channel_invalid_security_hash = 0x030f,
//server
ERROR_server_invalid_id = 0x0400, ///< Chosen virtual server does not exist or is offline
ERROR_server_running = 0x0401, ///< attempting to delete a server that is running. Stop the server before deleting it.
ERROR_server_is_shutting_down = 0x0402, ///< Client disconnected because the server is going offline
ERROR_server_maxclients_reached = 0x0403, ///< Given in the onConnectStatusChange event when the server has reached its maximum number of clients as defined by the \ref VIRTUALSERVER_MAXCLIENTS property
ERROR_server_invalid_password = 0x0404, ///< Specified server password is wrong. Provide the correct password in the \ref ts3client_startConnection / \ref ts3client_startConnectionWithChannelID call.
ERROR_server_is_virtual = 0x0407, ///< Server is in virtual status. The attempted action is not possible in this state. Start the virtual server first.
ERROR_server_is_not_running = 0x0409, ///< Attempting to stop a server that is not online.
ERROR_server_is_booting = 0x040a, // Not used
ERROR_server_status_invalid = 0x040b,
ERROR_server_version_outdated = 0x040d, ///< Attempt to connect to an outdated server version. The server needs to be updated.
ERROR_server_duplicate_running = 0x040e, ///< This server is already running within the instance. Each virtual server may only exist once.
//parameter
ERROR_parameter_quote = 0x0600, // Not used
ERROR_parameter_invalid_count = 0x0601, ///< Attempt to flush changes without previously calling set*VariableAs* since the last flush
ERROR_parameter_invalid = 0x0602, ///< At least one of the supplied parameters did not meet the criteria for that parameter
ERROR_parameter_not_found = 0x0603, ///< Failure to supply all the necessary parameters
ERROR_parameter_convert = 0x0604, ///< Invalid type supplied for a parameter, such as passing a string (ie. "five") that expects a number.
ERROR_parameter_invalid_size = 0x0605, ///< Value out of allowed range. Such as strings are too long/short or numeric values outside allowed range
ERROR_parameter_missing = 0x0606, ///< Neglecting to specify a required parameter
ERROR_parameter_checksum = 0x0607, ///< Attempting to deploy a modified snapshot
//unsorted, need further investigation
ERROR_vs_critical = 0x0700, ///< Failure to create default channel
ERROR_connection_lost = 0x0701, ///< Generic error with the connection.
ERROR_not_connected = 0x0702, ///< Attempting to call functions with a serverConnectionHandler that is not connected. You can use \ref ts3client_getConnectionStatus to check whether the connection handler is connected to a server
ERROR_no_cached_connection_info = 0x0703, ///< Attempting to query connection information (bandwidth usage, ping, etc) without requesting them first using \ref ts3client_requestConnectionInfo
ERROR_currently_not_possible = 0x0704, ///< Requested information is not currently available. You may have to call \ref ts3client_requestClientVariables or \ref ts3client_requestServerVariables
ERROR_failed_connection_initialisation = 0x0705, ///< No TeamSpeak server running on the specified IP address and port
ERROR_could_not_resolve_hostname = 0x0706, ///< Failure to resolve the specified hostname to an IP address
ERROR_invalid_server_connection_handler_id = 0x0707, ///< Attempting to perform actions on a non-existent server connection handler
ERROR_could_not_initialise_input_manager = 0x0708, // Not used
ERROR_clientlibrary_not_initialised = 0x0709, ///< Calling client library functions without successfully calling \ref ts3client_initClientLib before
ERROR_serverlibrary_not_initialised = 0x070a, ///< Calling server library functions without successfully calling \ref ts3server_initServerLib before
ERROR_whisper_too_many_targets = 0x070b, ///< Using a whisper list that contain more clients than the servers \ref VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE property
ERROR_whisper_no_targets = 0x070c, ///< The active whisper list is empty or no clients matched the whisper list (e.g. all channels in the list are empty)
ERROR_connection_ip_protocol_missing = 0x070d, ///< Invalid or unsupported protocol (e.g. attempting an IPv6 connection on an IPv4 only machine)
ERROR_handshake_failed = 0x070e,
ERROR_illegal_server_license = 0x070f,
//file transfer
ERROR_file_invalid_name = 0x0800, ///< Invalid UTF8 string or not a valid file
ERROR_file_invalid_permissions = 0x0801, ///< Permissions prevent opening the file
ERROR_file_already_exists = 0x0802, ///< Target path already exists as a directory
ERROR_file_not_found = 0x0803, ///< Attempt to access or move non existing file
ERROR_file_io_error = 0x0804, ///< Generic file input / output error
ERROR_file_invalid_transfer_id = 0x0805, ///< Attempt to get information about a file transfer after it has already been cleaned up. File transfer information is not available indefinitely after the transfer completed
ERROR_file_invalid_path = 0x0806, ///< specified path contains invalid characters or does not start with "/"
ERROR_file_no_files_available = 0x0807, // Not used
ERROR_file_overwrite_excludes_resume = 0x0808, ///< File overwrite and resume are mutually exclusive. Only one or neither can be 1.
ERROR_file_invalid_size = 0x0809, ///< Attempt to write more bytes than claimed file size.
ERROR_file_already_in_use = 0x080a, ///< File is currently not available, try again later.
ERROR_file_could_not_open_connection = 0x080b, ///< Generic failure in file transfer connection / other party did not conform to file transfer protocol
ERROR_file_no_space_left_on_device = 0x080c, ///< Operating system reports hard disk is full. May be caused by quota limitations.
ERROR_file_exceeds_file_system_maximum_size = 0x080d, ///< File is too large for the file system of the target device.
ERROR_file_transfer_connection_timeout = 0x080e, // Not used
ERROR_file_connection_lost = 0x080f, ///< File input / output timeout or connection failure
ERROR_file_exceeds_supplied_size = 0x0810, // Not used
ERROR_file_transfer_complete = 0x0811, ///< Indicates successful completion
ERROR_file_transfer_canceled = 0x0812, ///< Transfer was cancelled through @ref ts3client_haltTransfer
ERROR_file_transfer_interrupted = 0x0813, ///< Transfer failed because the server is shutting down, or network connection issues
ERROR_file_transfer_server_quota_exceeded = 0x0814, ///< Transfer terminated due to server bandwidth quota being exceeded. No client can transfer files.
ERROR_file_transfer_client_quota_exceeded = 0x0815, ///< Attempt to transfer more data than allowed by this clients' bandwidth quota. Other clients may continue to transfer files.
ERROR_file_transfer_reset = 0x0816, // Not used
ERROR_file_transfer_limit_reached = 0x0817, ///< Too many file transfers are in progress. Try again later
ERROR_file_invalid_storage_class = 0x0818, // TODO: Invalid storage class for HTTP FileTransfer (what is a storage class?)
ERROR_file_invalid_dimension = 0x0819, ///< Avatar image exceeds maximum width or height accepted by the server.
ERROR_file_transfer_channel_quota_exceeded = 0x081a, ///< Transfer failed because the channel quota was exceeded. Uploading to this channel is not possible, but other channels may be fine.
//sound
ERROR_sound_preprocessor_disabled = 0x0900, ///< Cannot set or query pre processor variables with preprocessing disabled
ERROR_sound_internal_preprocessor = 0x0901,
ERROR_sound_internal_encoder = 0x0902,
ERROR_sound_internal_playback = 0x0903,
ERROR_sound_no_capture_device_available = 0x0904, ///< No audio capture devices are available
ERROR_sound_no_playback_device_available = 0x0905, ///< No audio playback devices are available
ERROR_sound_could_not_open_capture_device = 0x0906, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_could_not_open_playback_device = 0x0907, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_handler_has_device = 0x0908, ///< Attempt to open a sound device on a connection handler which already has an open device. Close the already open device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_invalid_capture_device = 0x0909, ///< Attempt to use a device for capture that does not support capturing audio
ERROR_sound_invalid_playback_device = 0x090a, ///< Attempt to use a device for playback that does not support playback of audio
ERROR_sound_invalid_wave = 0x090b, ///< Attempt to use a non WAV file in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle
ERROR_sound_unsupported_wave = 0x090c, ///< Unsupported wave file used in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle.
ERROR_sound_open_wave = 0x090d, ///< Failure to open the specified sound file
ERROR_sound_internal_capture = 0x090e,
ERROR_sound_device_in_use = 0x090f, ///< Attempt to unregister a custom device that is being used. Close the device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_device_already_registerred = 0x0910, ///< Attempt to register a custom device with a device id that has already been used in a previous call. Device ids must be unique.
ERROR_sound_unknown_device = 0x0911, ///< Attempt to open, close, unregister or use a device which is not known. Custom devices must be registered before being used (see \ref ts3client_registerCustomDevice)
ERROR_sound_unsupported_frequency = 0x0912,
ERROR_sound_invalid_channel_count = 0x0913, ///< Invalid device audio channel count, must be > 0
ERROR_sound_read_wave = 0x0914, ///< Failure to read sound samples from an opened wave file. Is this a valid wave file?
ERROR_sound_need_more_data = 0x0915, // for internal purposes only
ERROR_sound_device_busy = 0x0916, // for internal purposes only
ERROR_sound_no_data = 0x0917, ///< Indicates there is currently no data for playback, e.g. nobody is speaking right now.
ERROR_sound_channel_mask_mismatch = 0x0918, ///< Opening a device with an unsupported channel count
//permissions
ERROR_permissions_client_insufficient = 0x0a08, ///< Not enough permissions to perform the requested activity
ERROR_permissions = 0x0a0c, ///< Permissions to use sound device not granted by operating system, e.g. Windows denied microphone access.
//accounting
ERROR_accounting_virtualserver_limit_reached = 0x0b00, ///< Attempt to use more virtual servers than allowed by the license
ERROR_accounting_slot_limit_reached = 0x0b01, ///< Attempt to set more slots than allowed by the license
ERROR_accounting_license_file_not_found = 0x0b02, // Not used
ERROR_accounting_license_date_not_ok = 0x0b03, ///< License expired or not valid yet
ERROR_accounting_unable_to_connect_to_server = 0x0b04, ///< Failure to communicate with accounting backend
ERROR_accounting_unknown_error = 0x0b05, ///< Failure to write update license file
ERROR_accounting_server_error = 0x0b06, // Not used
ERROR_accounting_instance_limit_reached = 0x0b07, ///< More than one process of the server is running
ERROR_accounting_instance_check_error = 0x0b08, ///< Shared memory access failure.
ERROR_accounting_license_file_invalid = 0x0b09, ///< License is not a TeamSpeak license
ERROR_accounting_running_elsewhere = 0x0b0a, ///< A copy of this server is already running in another instance. Each server may only exist once.
ERROR_accounting_instance_duplicated = 0x0b0b, ///< A copy of this server is running already in this process. Each server may only exist once.
ERROR_accounting_already_started = 0x0b0c, ///< Attempt to start a server that is already running
ERROR_accounting_not_started = 0x0b0d,
ERROR_accounting_to_many_starts = 0x0b0e, ///< Starting instance / virtual servers too often in too short a time period
//provisioning server
/// @cond HAS_PROVISIONING
ERROR_provisioning_invalid_password = 0x1100,
ERROR_provisioning_invalid_request = 0x1101,
ERROR_provisioning_no_slots_available = 0x1102,
ERROR_provisioning_pool_missing = 0x1103,
ERROR_provisioning_pool_unknown = 0x1104,
ERROR_provisioning_unknown_ip_location = 0x1105,
ERROR_provisioning_internal_tries_exceeded = 0x1106,
ERROR_provisioning_too_many_slots_requested = 0x1107,
ERROR_provisioning_too_many_reserved = 0x1108,
ERROR_provisioning_could_not_connect = 0x1109,
ERROR_provisioning_auth_server_not_connected = 0x1110,
ERROR_provisioning_auth_data_too_large = 0x1111,
ERROR_provisioning_already_initialized = 0x1112,
ERROR_provisioning_not_initialized = 0x1113,
ERROR_provisioning_connecting = 0x1114,
ERROR_provisioning_already_connected = 0x1115,
ERROR_provisioning_not_connected = 0x1116,
ERROR_provisioning_io_error = 0x1117,
ERROR_provisioning_invalid_timeout = 0x1118,
ERROR_provisioning_ts3server_not_found = 0x1119,
ERROR_provisioning_no_permission = 0x111A,
/// @endcond
// 0x12 - 0x15 are reserved in rare
// screen share
ERROR_already_registered = 0x1600,
ERROR_stream_session_limit_reached = 0x1601,
ERROR_stream_session_not_found = 0x1602,
ERROR_stream_unknown = 0x1603,
ERROR_stream_not_participating = 0x1604,
ERROR_not_streamer = 0x1605,
ERROR_already_joined = 0x1606,
ERROR_join_request_not_found = 0x1607,
ERROR_sfu_failed_to_start = 0x1608,
};
#endif
@@ -0,0 +1,236 @@
#ifndef TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#define TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Version definitions.
#define TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1 1
// Protocol used for communication between the session subscriber and the session (a single stream).
// Commands are sent bidirectionally or unidirectionally between the parties.
// e.g. SESSION => SUBSCRIBER: ON_FRAME, ON_PAUSED_CHANGED
// e.g. SUBSCRIBER => SESSION: ON_FRAME_ACK, ON_RESIZE
// Command type enum with a lowercase type name.
typedef enum
{
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME = 0,
TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE,
TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED,
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK,
TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP,
TS_SESSION_SUBSCRIBER_CMD_REMOVE_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED,
} ts_session_subscriber_command_type_t;
// Pixel format enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_I420 = 0,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_NV12,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ABGR,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ARGB,
} ts_session_subscriber_pixel_format_t;
// Buffer location enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_CPU = 0,
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_GPU
} ts_session_subscriber_buffer_location_t;
// Buffer type enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_SINGLE = 0,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_MAIN,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_SUB
} ts_session_subscriber_buffer_type_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(push, 4)
#endif
// Main buffer header for shared CPU Memory Front/Back Buffers.
// The Main Buffer contains metadata about the current front/back buffer and the versioning for both the main and sub buffer.
// The information from the main buffer can be used to always read the front buffer.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t front_buffer_index; // index of the front buffer. (0: main buffer, 1: sub buffer)
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_main_buffer_header_t;
// Sub buffer header.
typedef struct
{
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
} ts_session_subscriber_sub_buffer_header_t;
// Single frame buffer header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_single_frame_buffer_header_t;
// Command header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // Total message length (header + payload).
ts_session_subscriber_command_type_t type;
uint64_t target_session_id; // always set to the target session id this command is for or is originating from.
uint64_t target_subscriber_id; // 0 if broadcast.
} ts_session_subscriber_command_header_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME.
// The frame data is not included in the message, but is attached seperately or was sent beforehand. The buffer is identified by it's id.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_id; // buffer id, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_frame_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t frame_id;
} ts_session_subscriber_on_frame_ack_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE.
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t width;
uint32_t height;
} ts_session_subscriber_on_resize_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t paused; // 0 or 1.
} ts_session_subscriber_on_paused_changed_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE.
// Contains a single frame buffer. The header is of format |ts_session_subscriber_single_frame_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
ts_session_subscriber_buffer_type_t buffer_type;
} ts_session_subscriber_on_buffer_single_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK.
// Contains a main buffer and a sub buffer. The main buffer header
// contains metadata about the current front/back buffer and
// is of type |ts_session_subscriber_main_buffer_header_t|.
// The sub buffer's header is of type |ts_session_subscriber_sub_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t main_buffer_ptr; // main buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t main_buffer_length;
uint64_t sub_buffer_ptr; // sub buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t sub_buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
} ts_session_subscriber_on_buffer_front_back_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER.
// SUBSCRIBER => SESSION.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_resp_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_release_buffer_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr;
int bits_per_sample;
int sample_rate;
uint32_t number_of_channels;
uint32_t number_of_frames;
int64_t absolute_capture_timestamp_ms;
float volume;
} ts_session_subscriber_on_audio_frames_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t audio_enabled;
} ts_session_subscriber_on_audio_enabled_changed_payload_t;
// Overall Command structure.
typedef struct
{
ts_session_subscriber_command_header_t header;
union
{
ts_session_subscriber_on_frame_payload_t frame;
ts_session_subscriber_on_resize_payload_t resize;
ts_session_subscriber_on_paused_changed_payload_t paused;
ts_session_subscriber_on_frame_ack_payload_t frame_ack;
ts_session_subscriber_on_buffer_single_payload_t buffer_single;
ts_session_subscriber_on_buffer_front_back_payload_t buffer_front_back;
ts_session_subscriber_on_release_buffer_payload_t release_buffer;
ts_session_subscriber_add_subscriber_payload_t add_subscriber;
ts_session_subscriber_add_subscriber_resp_payload_t add_subscriber_resp;
ts_session_subscriber_on_audio_frames_payload_t audio_frames;
ts_session_subscriber_on_audio_enabled_changed_payload_t audio_enabled_changed;
} payload;
} ts_session_subscriber_command_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif // TS_SESSION_SUBSCRIBER_PROTOCOL_H_
@@ -0,0 +1,32 @@
// TeamSpeakClient framework module map — SDK surface.
//
// This minimal map covers only the ObjC-safe public surface exposed by the
// team_client library itself (teamspeak/*.h, teamlog/logtypes.h, and the
// common headers that make up the public clientlib API).
//
// For non-SDK iOS app builds, workspace/_iOS/CMakeLists.txt generates a full
// replacement map (installed over this one) that additionally declares the
// C++-only submodules for cloud_common, cloud_sync_client, interface, tsdns,
// compiler_settings, and team_revocation.
//
// Consumers:
// - In .m / .h reached from .m sources:
// #import <TeamSpeakClient/teamspeak/clientlib.h> // ObjC-safe
// @import TeamSpeakClient; // ObjC-safe surface
//
// - In Swift:
// import TeamSpeakClient // ObjC-safe surface only
framework module TeamSpeakClient {
// ObjC-safe surface: plain-C / ObjC-compatible headers only.
// Enumerated by CMake at configure time — see OBJC_SAFE_HEADERS in
// workspace/client/CMakeLists.txt.
export *
header "teamspeak/clientlib.h"
header "teamspeak/video/session_subscriber_protocol.h"
header "teamspeak/clientlib_sdk.h"
header "teamspeak/public_definitions.h"
header "teamspeak/public_errors.h"
header "teamlog/logtypes.h"
}
@@ -0,0 +1,23 @@
#ifndef TEAMLOG_LOGTYPES_H
#define TEAMLOG_LOGTYPES_H
enum LogTypes {
LogType_NONE = 0x0000, ///< Logging is disabled
LogType_FILE = 0x0001, ///< Log to regular log file
LogType_CONSOLE = 0x0002, ///< Log to standard output / error
LogType_USERLOGGING = 0x0004, ///< User defined logging. Will call the \ref ServerLibFunctions.onUserLoggingMessageEvent callback for every message to be logged
LogType_NO_NETLOGGING = 0x0008, ///< Not used
LogType_DATABASE = 0x0010, ///< Log to database (deprecated, server only, no effect in SDK)
LogType_SYSLOG = 0x0020, ///< Log to syslog (only available on Linux)
};
enum LogLevel {
LogLevel_CRITICAL = 0, ///< these messages stop the program
LogLevel_ERROR, ///< everything that is really bad, but not so bad we need to shut down
LogLevel_WARNING, ///< everything that *might* be bad
LogLevel_DEBUG, ///< output that might help find a problem
LogLevel_INFO, ///< informational output, like "starting database version x.y.z"
LogLevel_DEVEL ///< developer only output (will not be displayed in release mode)
};
#endif //TEAMLOG_LOGTYPES_H
@@ -0,0 +1,58 @@
#ifndef CLIENTLIB_SDK_H
#define CLIENTLIB_SDK_H
// system
#include <stdlib.h>
// own
#include "teamspeak/public_definitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets the client to which to transmit voice. Stops standard channel voice transmission.
*
* The client will still receive voice from their current channel, however their voice will not be transmitted to their
* current channel anymore. If this call is successful (check onServerErrorEvent) then voice of the specified client
* will be transmitted to all specified channels and all the specified clients. Pass 0 to both target parameter arrays
* to restore default behavior of transmitting voice to current channel. You will receive an onServerErrorEvent with the
* passed returnCode indicating whether or not the operation was successful.
*
* @param server_connection_handler_id the connection handler on which to set the whisper list
* @param client_id the client to set the whisper list for. Set to 0 or your own client ID to set your own whisper list.
* @param channel_ids an array of channel ids to transmit voice to.
* @param channel_ids_size number of elements in aforementioned array.
* @param client_ids a zero terminated array of client ids to transmit voice to.
* @param client_ids_size number of elements in aforementioned array.
* @param impersonate if the target client is a webrtc client, the voice packets will look like as if they have been
* send by the invoking client id
* @param return_code a c string to identify this request in callbacks. Pass an empty string if unused.
* @return An error code from the @ref Ts3ErrorType enum indicating either success or the failure reason
*/
EXPORTDLL unsigned int ts_client_request_client_set_whisper_list(uint64 server_connection_handler_id, anyID client_id,
const uint64* channel_ids,
int channel_ids_size,
const anyID* client_ids,
int client_ids_size, int impersonate,
const char* return_code);
/**
* @brief Send a binary-serialized ClientCommandRequest protobuf to the client library.
*
* The response will be delivered asynchronously via the onProtoResponse callback
* as a serialized ClientCommandResponse protobuf.
*
* @param data Pointer to serialized ClientCommandRequest protobuf bytes
* @param size Size of the serialized data in bytes
* @param return_code Caller-provided string to correlate the response in onProtoResponse. May be NULL.
* @return An error code: ERROR_ok on successful dispatch, ERROR_parameter_invalid on parse failure
*/
EXPORTDLL unsigned int ts3client_postProtoCommand(const void* data, size_t size, const char* return_code);
#ifdef __cplusplus
}
#endif
#endif // CLIENTLIB_SDK_H
@@ -0,0 +1,635 @@
#ifndef PUBLIC_DEFINITIONS_H
#define PUBLIC_DEFINITIONS_H
#include "teamlog/logtypes.h"
#define TS3_MAX_SIZE_CHANNEL_NAME 40 // channel name maximum length in characters
#define TS3_MAX_SIZE_VIRTUALSERVER_NAME 64 // virtual server name maximum length in characters
#define TS3_MAX_SIZE_CLIENT_NICKNAME 64 // client display name length limit in characters
#define TS3_MIN_SIZE_CLIENT_NICKNAME 3 // client display name minimum length in characters
#define TS3_MAX_SIZE_REASON_MESSAGE 80 // length limit in characters for kick, move, etc reasons
#define TS3_MAX_SIZE_TEXTMESSAGE 8192 // text message length limit, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_TOPIC 255 // channel topic lengt limith, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_DESCRIPTION 8192 // channel description length limit, measured in bytes (utf8 encoded)
// server welcome message length limit measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_VIRTUALSERVER_WELCOMEMESSAGE 1024
#define TS3_SIZE_MYTSID 44
// minimum amount of seconds before a clientID that was in use can be assigned to a new client
#define TS3_MIN_SECONDS_CLIENTID_REUSE 300
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32)
typedef unsigned __int16 anyID;
typedef unsigned __int64 uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __declspec(dllexport)
#else
#define EXPORTDLL
#endif
#endif
#else
#include <stdint.h>
typedef uint16_t anyID;
typedef uint64_t uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __attribute__((visibility("default")))
#else
#define EXPORTDLL
#endif
#endif
#endif
enum Visibility
{
ENTER_VISIBILITY = 0, ///< Client joined from an unsubscribed channel, or joined the server.
RETAIN_VISIBILITY, ///< Client switched from one subscribed channel to a different subscribed channel.
LEAVE_VISIBILITY ///< Client switches to an unsubscribed channel, or disconnected from server.
};
enum ConnectStatus
{
STATUS_DISCONNECTED = 0, ///< There is no activity to the server, this is the default value
STATUS_CONNECTING, ///< We are trying to connect, we haven't got a client id yet, we haven't been accepted by the server
STATUS_CONNECTED, ///< The server has accepted us, we can talk and hear and we have a client id, but we don't
///< have the channels and clients yet, we can get server infos (welcome msg etc.)
STATUS_CONNECTION_ESTABLISHING, ///< we are connected and we are visible
STATUS_CONNECTION_ESTABLISHED, ///< we are connected and we have the client and channels available
};
enum LocalTestMode
{
TEST_MODE_OFF = 0,
TEST_MODE_VOICE_LOCAL_ONLY,
TEST_MODE_VOICE_LOCAL_AND_REMOTE,
TEST_MODE_TALK_STATUS_CHANGES_ONLY
};
enum TalkStatus
{
STATUS_NOT_TALKING = 0, ///< client is not talking
STATUS_TALKING = 1, ///< client is talking
STATUS_TALKING_WHILE_DISABLED = 2, ///< client is talking while the microphone is muted (only valid for own client)
};
enum CodecType
{
CODEC_SPEEX_NARROWBAND = 0, ///< (deprecated) mono, 16bit, 8kHz, bitrate dependent on the quality setting
CODEC_SPEEX_WIDEBAND, ///< (deprecated) mono, 16bit, 16kHz, bitrate dependent on the quality setting
CODEC_SPEEX_ULTRAWIDEBAND, ///< (deprecated) mono, 16bit, 32kHz, bitrate dependent on the quality setting
CODEC_CELT_MONO, ///< (deprecated) mono, 16bit, 48kHz, bitrate dependent on the quality setting
CODEC_OPUS_VOICE, ///< mono, 16bit, 48khz, bitrate dependent on the quality setting, optimized for voice
CODEC_OPUS_MUSIC, ///< stereo, 16bit, 48khz, bitrate dependent on the quality setting, optimized for music
};
enum CodecEncryptionMode
{
CODEC_ENCRYPTION_PER_CHANNEL = 0, ///< voice data encryption decided per channel
CODEC_ENCRYPTION_FORCED_OFF, ///< voice data encryption disabled
CODEC_ENCRYPTION_FORCED_ON, ///< voice data encryption enabled
};
enum TextMessageTargetMode
{
TextMessageTarget_CLIENT = 1, ///< Message is a private message to another client
TextMessageTarget_CHANNEL, ///< Message is sent to a channel, received by all clients in that channel at the time
TextMessageTarget_SERVER, ///< Message is sent to every client on the server
TextMessageTarget_MAX
};
enum MuteInputStatus
{
MUTEINPUT_NONE = 0, ///< Microphone is not muted, audio is sent to the server
MUTEINPUT_MUTED, ///< Microphone is muted, no audio is transmitted to the server
};
enum MuteOutputStatus
{
MUTEOUTPUT_NONE = 0, ///< Speaker is active, server is sending us audio
MUTEOUTPUT_MUTED, ///< Speaker is muted, server is not sending audio to us
};
enum HardwareInputStatus
{
HARDWAREINPUT_DISABLED = 0, ///< no capture device opened
HARDWAREINPUT_ENABLED, ///< capture device open
};
enum HardwareOutputStatus
{
HARDWAREOUTPUT_DISABLED = 0, ///< no playback device opened
HARDWAREOUTPUT_ENABLED, ///< playback device open
};
enum InputDeactivationStatus
{
INPUT_ACTIVE = 0, ///< Audio is captured from the capture device.
INPUT_DEACTIVATED = 1, ///< No audio is captured from the capture device.
};
enum ReasonIdentifier
{
REASON_NONE = 0, ///< no reason data
REASON_MOVED = 1, ///< client was moved
REASON_SUBSCRIPTION = 2, // no reason data
REASON_LOST_CONNECTION = 3, // reasonmsg=reason
REASON_KICK_CHANNEL = 4, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER = 5, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER_BAN = 6, //{SectionInvoker} reasonmsg=reason bantime=time //{SectionInvoker} is only added server->client
REASON_SERVERSTOP = 7, // reasonmsg=reason
REASON_CLIENTDISCONNECT = 8, // reasonmsg=reason
REASON_CHANNELUPDATE = 9, // no reason data
REASON_CHANNELEDIT = 10, //{SectionInvoker}
REASON_CLIENTDISCONNECT_SERVER_SHUTDOWN = 11, // reasonmsg=reason
};
enum Protocol_Encryption_Cipher
{
AES_128 = 0b00000000,
AES_256 = 0b00000001,
PROTOCOL_ENCRYPTION_CIPHER_END_MARKER,
RESERVED = 0b00010000, // reserved until puzzle v2 is fully released, then can be reused
PUZZLE_2 = 0b00100000,
};
enum ChannelProperties
{
CHANNEL_NAME = 0, ///< String. Read/Write. Name of the channel. Always available.
CHANNEL_TOPIC, ///< String. Read/Write. Short single line text describing what the channel is about. Always available.
CHANNEL_DESCRIPTION, ///< String. Read/Write. Arbitrary text (up to 8k bytes) with information about the channel.
///< Must be requested (\ref ts3client_requestChannelDescription)
CHANNEL_PASSWORD, ///< String. Read/Write. Password of the channel. Read access is limited to the server. Clients
///< will only ever see the last password they attempted to use when joining the channel. Always available.
CHANNEL_CODEC, ///< Integer. Read/Write. The codec this channel is using. One of the values from the \ref CodecType
///< enum. Always available.
CHANNEL_CODEC_QUALITY, ///< Integer. Read/Write. The quality setting of the channel. Valid values are 0 to 10 inclusive.
///< Higher value means better voice quality but also more bandwidth usage. Always available.
CHANNEL_MAXCLIENTS, ///< Integer. Read/Write. The number of clients that can be in the channel simultaneously.
///< Always available.
CHANNEL_MAXFAMILYCLIENTS, ///< Integer. Read/Write. The total number of clients that can be in this channel and all
///< sub channels of this channel. Always available.
CHANNEL_ORDER, ///< UInt64. Read/Write. The ID of the channel below which this channel should be displayed. If 0
///< the channel is sorted at the top of the current level. Always available.
CHANNEL_FLAG_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when empty.
///< Permanent channels are stored to the database and available after server restart. SDK
///< users will need to take care of restoring channel at server start on their own.
///< Mutually exclusive with \ref CHANNEL_FLAG_SEMI_PERMANENT. Always available.
CHANNEL_FLAG_SEMI_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when
///< empty. Semi permanent channels are not stored to disk and gone after server
///< restart but remain while empty. Mutually exclusive with \ref
///< CHANNEL_FLAG_PERMANENT. Always available.
CHANNEL_FLAG_DEFAULT, ///< Integer. Read/Write. Boolean (1/0). The default channel is the channel that all clients
///< are located in when they join the server, unless the client explicitly specified a
///< different channel when connecting and is allowed to join their preferred channel. Only
///< one channel on the server can have this flag set. The default channel must have \ref
///< CHANNEL_FLAG_PERMANENT set. Always available.
CHANNEL_FLAG_PASSWORD, ///< Integer. Read/Write. Boolean (1/0) indicating whether this channel is password protected.
///< When removing or setting \ref CHANNEL_PASSWORD you also need to adjust this flag.
CHANNEL_CODEC_LATENCY_FACTOR, ///< (deprecated) Integer. Read/Write. Allows to increase packet size, reducing
///< bandwith at the cost of higher latency of voice transmission. Valid values are
///< 1-10 inclusive. 1 is the default and offers the lowest latency. Always available.
CHANNEL_CODEC_IS_UNENCRYPTED, ///< Integer. Read/Write. Boolean (1/0). If 0 voice data is encrypted, if 1 the voice
///< data is not encrypted. Only used if the server \ref
///< VIRTUALSERVER_CODEC_ENCRYPTION_MODE is set to \ref CODEC_ENCRYPTION_PER_CHANNEL.
///< Always available.
CHANNEL_SECURITY_SALT, ///< String. Read/Write. SDK Only, not used by TeamSpeak. This channels security hash. When
///< a client joins their \ref CLIENT_SECURITY_HASH is compared to this value, to allow or
///< deny the client access to the channel. Used to enforce clients joining the server with
///< specific identity and \ref CLIENT_META_DATA. See SDK Documentation about this feature
///< for further details. Always available.
CHANNEL_DELETE_DELAY, ///< UInt64. Read/Write. Number of seconds deletion of temporary channels is delayed after
///< the last client leaves the channel. Channel is only deleted if empty when the delete
///< delay expired. Always available.
CHANNEL_UNIQUE_IDENTIFIER, ///< String. Read only. An identifier that uniquely identifies a channel. Available in
///< Server >= 3.10.0
CHANNEL_ENDMARKER,
};
enum ClientProperties
{
CLIENT_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Public Identity, can be used to identify a client
///< installation. Remains identical as long as the client keeps using the same
///< identity. Available for visible clients.
CLIENT_NICKNAME, ///< String. Read/Write. Display name of the client. Available for visible clients.
CLIENT_VERSION, ///< String. Read only. Version String of the client used. For clients other than ourself this
///< needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_PLATFORM, ///< String. Read only. Operating system used by the client. For other clients other than ourself
///< this needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_FLAG_TALKING, ///< Integer. Read only. Whether the client is talking. Available on clients that are either
///< whispering to us, or in our channel.
CLIENT_INPUT_MUTED, ///< Integer. Read/Write. Microphone mute status. Available for visible clients. One of the
///< values from the \ref MuteInputStatus enum.
CLIENT_OUTPUT_MUTED, ///< Integer. Read/Write. Speaker mute status. Speaker mute implies microphone mute. Available
///< for visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_OUTPUTONLY_MUTED, ///< Integer. Read/Write. Speaker mute status. Microphone may be active. Available for
///< visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_INPUT_HARDWARE, ///< Integer. Read only. Indicates whether a capture device is open. Available for visible
///< clients. One of the values from the \ref HardwareInputStatus enum.
CLIENT_OUTPUT_HARDWARE, ///< Integer. Read only. Indicates whether a playback device is open. Available for visible
///< clients. One of the values from the \ref HardwareOutputStatus enum.
CLIENT_INPUT_DEACTIVATED, ///< Integer. Read/Write. Not available server side. Local microphone mute status.
///< Available only for own client. Used to implement Push To Talk. One of the values from
///< the \ref InputDeactivationStatus enum.
CLIENT_IDLE_TIME, ///< UInt64. Read only. Seconds since last activity. Available only for own client.
CLIENT_DEFAULT_CHANNEL, ///< String. Read only. User specified channel they joined when connecting to the server.
///< Available only for own client.
CLIENT_DEFAULT_CHANNEL_PASSWORD, ///< String. Read only. User specified channel password for the channel they
///< attempted to join when connecting to the server. Available only for own
///< client.
CLIENT_SERVER_PASSWORD, ///< String. Read only. User specified server password. Available only for own client.
CLIENT_META_DATA, ///< String. Read/Write. Can be used to store up to 4096 bytes of information on clients. Not
///< used by TeamSpeak. Available for visible clients.
CLIENT_IS_MUTED, ///< Integer. Read only. Not available server side. Indicates whether we have muted the client
///< using \ref ts3client_requestMuteClients. Available for visible clients other than ourselves.
CLIENT_IS_RECORDING, ///< Integer. Read only. Indicates whether the client is recording incoming audio. Available
///< for visible clients.
CLIENT_VOLUME_MODIFICATOR, ///< Integer. Read only. Volume adjustment for this client as set by \ref
///< ts3client_setClientVolumeModifier. Available for visible clients.
CLIENT_VERSION_SIGN, ///< String. Read only. TeamSpeak internal signature.
CLIENT_SECURITY_HASH, ///< String. Read/Write. This clients security hash. Not used by TeamSpeak, SDK only. Hash is
///< provided by an outside source. A channel will use the security salt + other client data
///< to calculate a hash, which must be the same as the one provided here. See SDK
///< documentation about Client / Channel Security Hashes for more details.
CLIENT_ENCRYPTION_CIPHERS, ///< String. Read only. SDK only. List of available ciphers this client can use.
CLIENT_IS_STREAMING, ///< bool. Read only, Is currently streaming.
CLIENT_ENDMARKER,
};
enum VirtualServerProperties
{
VIRTUALSERVER_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Unique identifier for a virtual server, does not
///< change on server restart. Available if \ref ts3client_getConnectionStatus
///< is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_NAME, ///< String. Read/Write. The virtual server display name. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_WELCOMEMESSAGE, ///< String. Read/Write. The welcome message displayed to clients on connect.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED. Not
///< updated automatically when changed, updates need to be requested (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_PLATFORM, ///< String. Read only. The operating system the server is running on. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_VERSION, ///< String. Read only. The server software version string. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_MAXCLIENTS, ///< UInt64. Read/Write. The maximum number of clients that can be connected
///< simultaneously. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_PASSWORD, ///< String. Read/Write. The server password. Read access is limited to the server. Clients
///< will only get the password they supplied when connecting. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_CLIENTS_ONLINE, ///< UInt64. Read only. The current number of clients connected to the server,
///< including query connections. Only available on request (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_CHANNELS_ONLINE, ///< UInt64. Read only. The current number of channels on the server. Only
///< available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CREATED, ///< Integer. Read only. The time this virtual server was created as unix timestamp.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_UPTIME, ///< UInt64. Read only. Number of seconds that have passed since the virtual server was
///< started. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CODEC_ENCRYPTION_MODE, ///< Integer. Read/Write. Boolean (1/0) that specifies if voice data is encrypted
///< during transfer. One of the values from the \ref CodecEncryptionMode enum.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_ENCRYPTION_CIPHERS, ///< String. Read/Write. Comma separated list of available ciphers to encrypt the
///< connection. The server will use the first cipher in the list that is also
///< listed in the \ref CLIENT_ENCRYPTION_CIPHERS of the connecting client.
///< Clients will fail to connect if no match is found. Always available.
VIRTUALSERVER_ADDRESS, ///< Any resolvable address for the specific virtual server
VIRTUALSERVER_VERSION_SIGN, ///< String. Read only. Signature of Platform and Version.
VIRTUALSERVER_ENDMARKER,
VIRTUALSERVER_FILEBASE = 24, ///< String. Read only. The path to the base directory used to store files
///< transferred using file transfer. Available only on the server. Is set by \ref
///< ts3server_enableFileManager
VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH = 29, ///< UInt64. Read/Write. Maximum traffic in bytes the server can
///< use for file transfer downloads. Only available on request
///< (\ref ts3client_requestServerVariables).
VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH = 30, ///< UInt64. Read/Write. Maximum traffic in bytes the server can use
///< for file transfer uploads. Only available on request (=>
///< requestServerVariables)
VIRTUALSERVER_LOG_FILETRANSFER = 64 ///< Integer. Read/Write. Boolean (1/0) indicating whether to include file
///< transfer activities (uploading or downloading of files) in the server log.
///< Always available.
};
/**
* Various connection properties.
* These are all read only, and except for your own client must be requested using \ref ts3client_requestConnectionInfo
*/
enum ConnectionProperties
{
CONNECTION_PING = 0, ///< UInt64. Round trip latency for the connection based on the last 5 seconds. On the server
///< this is the average across all connected clients for the last 5 seconds.
CONNECTION_PING_DEVIATION, ///< Double. Standard deviation for the round trip latency in \ref CONNECTION_PING
CONNECTION_CONNECTED_TIME, ///< UInt64. Seconds the client has been connected.
CONNECTION_IDLE_TIME, ///< UInt64. Time in seconds since the last activity (voice transmission, switching channels,
///< changing mic / speaker mute status) of the client.
CONNECTION_CLIENT_IP, ///< String. IP of this client (as seen from the server side)
CONNECTION_CLIENT_PORT, ///< UInt64. Client side port of this client (as seen from the server side)
CONNECTION_SERVER_IP, ///< String. The IP or hostname used to connect to the server. Only available on yourself.
CONNECTION_SERVER_PORT, ///< UInt64. The server port connected to. Only available on yourself.
CONNECTION_PACKETS_SENT_SPEECH, ///< UInt64. The number of voice packets transmitted by the client.
CONNECTION_PACKETS_SENT_KEEPALIVE, ///< UInt64. The number of keep alive packets transmitted by the client.
CONNECTION_PACKETS_SENT_CONTROL, ///< UInt64. The number of command & control packets transmitted by the client.
CONNECTION_PACKETS_SENT_TOTAL, ///< UInt64. Total number of packets transmitted by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_SENT_SPEECH, \ref CONNECTION_PACKETS_SENT_KEEPALIVE and
///< \ref CONNECTION_PACKETS_SENT_CONTROL
CONNECTION_BYTES_SENT_SPEECH, ///< UInt64. Outgoing traffic used for voice data by the client.
CONNECTION_BYTES_SENT_KEEPALIVE, ///< UInt64. Outgoing traffic used for keeping the connection alive by the client.
CONNECTION_BYTES_SENT_CONTROL, ///< UInt64. Outgoing traffic used for command & control data by the client.
CONNECTION_BYTES_SENT_TOTAL, ///< UInt64. Total outgoing traffic to the server by this client. Equal to the sum of
///< \ref CONNECTION_BYTES_SENT_SPEECH, \ref CONNECTION_BYTES_SENT_KEEPALIVE and \ref
///< CONNECTION_BYTES_SENT_CONTROL
CONNECTION_PACKETS_RECEIVED_SPEECH, ///< UInt64. Number of voice packets received by the client.
CONNECTION_PACKETS_RECEIVED_KEEPALIVE, ///< UInt64. Number of keep alive packets received by the client.
CONNECTION_PACKETS_RECEIVED_CONTROL, ///< UInt64. Number of command & control packets received by the client.
CONNECTION_PACKETS_RECEIVED_TOTAL, ///< UInt64. Total number of packets received by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_RECEIVED_SPEECH, \ref
///< CONNECTION_PACKETS_RECEIVED_KEEPALIVE and \ref
///< CONNECTION_PACKETS_RECEIVED_CONTROL
CONNECTION_BYTES_RECEIVED_SPEECH, ///< UInt64. Incoming traffic used by the client for voice data.
CONNECTION_BYTES_RECEIVED_KEEPALIVE, ///< UInt64. Incoming traffic used by the client to keep the connection alive.
CONNECTION_BYTES_RECEIVED_CONTROL, ///< UInt64. Incoming traffic used by the client for command & control data.
CONNECTION_BYTES_RECEIVED_TOTAL, ///< UInt64. Total incoming traffic used by the client. Equal to the sum of \ref
///< CONNECTION_BYTES_RECEIVED_SPEECH, \ref CONNECTION_BYTES_RECEIVED_KEEPALIVE and
///< \ref CONNECTION_BYTES_RECEIVED_CONTROL
CONNECTION_PACKETLOSS_SPEECH, ///< Double. Percentage points of voice packets for the client that did not arrive at
///< the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_KEEPALIVE, ///< Double. Percentage points of keep alive packets for the client that did not
///< arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_CONTROL, ///< Double. Percentage points of command & control packets for the client that did
///< not arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_TOTAL, ///< Double. Cumulative chance in percentage points with which a packet round trip
///< failed because a packet was lost
CONNECTION_SERVER2CLIENT_PACKETLOSS_SPEECH, ///< Double. Probability with which a voice packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< server was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the server was not
///< received by the client.
CONNECTION_CLIENT2SERVER_PACKETLOSS_SPEECH, ///< Double. Probability with which a speech packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< client was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the client was not
///< received by the server.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes sent for speech data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes sent for keepalive data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes sent for control data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes sent in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second sent for speech data, averaged over the
///< last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second sent for keepalive data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second sent for control data, averaged over
///< the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second sent, averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes received for speech data in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes received for keepalive data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes received for control data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes received in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second received for speech data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second received for keepalive data,
///< averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second received for control data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second received, averaged over the last minute.
CONNECTION_DUMMY_0,
CONNECTION_DUMMY_1,
CONNECTION_DUMMY_2,
CONNECTION_DUMMY_3,
CONNECTION_DUMMY_4,
CONNECTION_DUMMY_5,
CONNECTION_DUMMY_6,
CONNECTION_DUMMY_7,
CONNECTION_DUMMY_8,
CONNECTION_DUMMY_9,
CONNECTION_FILETRANSFER_BANDWIDTH_SENT, ///< UInt64. Current file transfer upstream activity in bytes per second.
///< Only available on request (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, ///< UInt64. Current file transfer downstream activity in bytes per
///< second. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, ///< UInt64. Total downstream traffic, in bytes, used for file
///< transfer since the server was started. Only available on request
///< (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, ///< UInt64. Total upstream traffic, in bytes, used for file transfer
///< since the server was started. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_ENDMARKER
};
/**
* Describes a client position in 3 dimensional space, used for 3D Sound.
*/
typedef struct
{
float x; ///< X co-ordinate in 3D space.
float y; ///< Y co-ordinate in 3D space.
float z; ///< Z co-ordinate in 3D space.
} TS3_VECTOR;
enum GroupWhisperType
{
GROUPWHISPERTYPE_SERVERGROUP = 0, ///< Whisper list consists of server groups
GROUPWHISPERTYPE_CHANNELGROUP = 1, ///< Whisper list consists of channel groups
GROUPWHISPERTYPE_CHANNELCOMMANDER = 2, ///< whisper to channel commanders
GROUPWHISPERTYPE_ALLCLIENTS = 3, ///< whisper to all clients
GROUPWHISPERTYPE_ENDMARKER,
};
enum GroupWhisperTargetMode
{
GROUPWHISPERTARGETMODE_ALL = 0,
GROUPWHISPERTARGETMODE_CURRENTCHANNEL = 1, ///< Whisper the current channel of the client
GROUPWHISPERTARGETMODE_PARENTCHANNEL = 2, ///< Whisper the parent channel of whatever channel the client is currently in
GROUPWHISPERTARGETMODE_ALLPARENTCHANNELS = 3, ///< Whipser to the parent channel and all their parent channels as well
GROUPWHISPERTARGETMODE_CHANNELFAMILY = 4, ///< Whisper to the current channel and all its sub channels
GROUPWHISPERTARGETMODE_ANCESTORCHANNELFAMILY = 5, ///< Whisper to the current channel, all its parent and sub channels.
GROUPWHISPERTARGETMODE_SUBCHANNELS = 6, ///< Whisper to all sub channels of the current channel of the client
GROUPWHISPERTARGETMODE_ENDMARKER,
};
enum MonoSoundDestination
{
MONO_SOUND_DESTINATION_ALL = 0, ///< Send mono sound to all available speakers
MONO_SOUND_DESTINATION_FRONT_CENTER = 1, ///< Send mono sound to front center speaker if available
MONO_SOUND_DESTINATION_FRONT_LEFT_AND_RIGHT = 2 ///< Send mono sound to front left/right speakers if available
};
enum SecuritySaltOptions
{
SECURITY_SALT_CHECK_NICKNAME = 1, ///< put nickname into security hash
SECURITY_SALT_CHECK_META_DATA = 2 ///< put meta data into security hash
};
/*this enum is used to disable client commands on the server*/
enum ClientCommand
{
CLIENT_COMMAND_requestConnectionInfo = 0, ///< disable client connection info request (client bandwidth usage, ip,
///< port, ping)
CLIENT_COMMAND_requestClientMove = 1, ///< disable moving clients
CLIENT_COMMAND_requestXXMuteClients = 2, ///< disable muting other clients
CLIENT_COMMAND_requestClientKickFromXXX = 3, ///< disable kicking clients
CLIENT_COMMAND_flushChannelCreation = 4, ///< disable creating channels
CLIENT_COMMAND_flushChannelUpdates = 5, ///< disable editing channels
CLIENT_COMMAND_requestChannelMove = 6, ///< disable moving channels
CLIENT_COMMAND_requestChannelDelete = 7, ///< disable deleting channels
CLIENT_COMMAND_requestChannelDescription = 8, ///< disable channel descriptions
CLIENT_COMMAND_requestChannelXXSubscribeXXX = 9, ///< disable being able to see clients in channels other than the
///< current channel the client is in
CLIENT_COMMAND_requestServerConnectionInfo = 10, ///< disable server connection info request (server bandwidth
///< usage, ip, port, ping)
CLIENT_COMMAND_requestSendXXXTextMsg = 11, ///< disable text messaging
CLIENT_COMMAND_filetransfers = 12, ///< disable file transfer
CLIENT_COMMAND_ENDMARKER
};
/* Access Control List*/
enum ACLType
{
ACL_NONE = 0,
ACL_WHITE_LIST = 1,
ACL_BLACK_LIST = 2
};
/* file transfer actions*/
enum FTAction
{
FT_INIT_SERVER = 0, ///< The virtual server is created. result->channelPath can be changed to create a different
///< directory than the default 'virtualserver_x' where x is the virtual server.
FT_INIT_CHANNEL = 1, ///< A channel is created. result->channelPath can be changed to create a different directory
///< then the default 'channel_x' where x is the channel id.
FT_UPLOAD = 2, ///< A file is being uploaded. All values in the result struct can be modified.
FT_DOWNLOAD = 3, ///< A file is being downloaded. All values in the result struct can be modified.
FT_DELETE = 4, ///< A file is being deleted. All values in the result struct can be modified.
FT_CREATEDIR = 5, ///< A directory is being created in a channel. All values in the result struct can be modified.
FT_RENAME = 6, ///< A file or folder is being renamed. The callback will be called twice! Once for the old and then
///< for the new name. All values in the result struct can be modified.
FT_FILELIST = 7, ///< A directory listing is requested. All values in the result struct can be modified.
FT_FILEINFO = 8 ///< Information of a file is requested. All values in the result struct can be modified.
};
/* file transfer status */
enum FileTransferState
{
FILETRANSFER_INITIALISING = 0, ///< File transfer is establishing connection.
FILETRANSFER_ACTIVE, ///< File transfer is in progress
FILETRANSFER_FINISHED, ///< File transfer has finished
};
/* file transfer types */
enum FileTransferType
{
FileListType_Directory = 0, ///< The file entry is a directory
FileListType_File, ///< The file entry is a regular file
};
/* some structs to handle variables in callbacks */
#define MAX_VARIABLES_EXPORT_COUNT 64
struct VariablesExportItem
{
unsigned char itemIsValid; ///< Whether or not there is any data in this item. Ignore this item if this is 0.
unsigned char proposedIsSet; ///< The value in proposed is set. If 0 ignore proposed
const char* current; ///< current value (stored in memory)
const char* proposed; ///< New value to change to (const, so no updates please)
};
struct VariablesExport
{
struct VariablesExportItem items[MAX_VARIABLES_EXPORT_COUNT];
};
struct ClientMiniExport
{
anyID ID; ///< id of the client
uint64 channel; ///< the channel the client is in
const char* ident; ///< client public identity
const char* nickname; ///< client display name
};
/**
* Structure used to describe a file transfer in the \ref ServerLibFunctions.onTransformFilePath callback.
* This describes the original values, and also contains hints for length limitations of the result parameter
* of the callback.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExport
{
uint64 channel; ///< The channel id of the file. 0 if action is \ref FT_INIT_SERVER
const char* filename; ///< utf8 encoded c string containing the original file name as intended by the client.
int action; ///< The action to be performed. One of the values from the \ref FTAction enum. Defines which values of
///< the result struct can be modified.
int transformedFileNameMaxSize; ///< The maximum length the file name can be rewritten to.
int channelPathMaxSize; ///< The maximum length the path can be rewritten to.
};
/**
* Structure to rewrite the file transfer file name and path in the \ref ServerLibFunctions.onTransformFilePath callback.
* The lengths are limited as described in the original parameter.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExportReturns
{
char* transformedFileName; ///< pointer to target file name. Fill the memory pointed to with an utf8 encoded c string
///< containing the new file name. Limited to original->transformedFileNameMaxSize bytes.
char* channelPath; ///< pointer to memory for new path. Fill the memory pointed to with an utf8 encoded c string
///< containing the new path. Limited to original->channelPathMaxSize bytes.
int logFileAction; ///< boolean (1/0). Whether to log this file transfer to the log. Action is not logged regardless
///< of this value if the servers \ref VIRTUALSERVER_LOG_FILETRANSFER property is 0.
};
struct FileTransferCallbackExport
{
anyID clientID; ///< the client who started the file transfer
anyID transferID; ///< local identifier of the transfer that has completed
anyID remoteTransferID; ///< remote identifier of the transfer that has completed
unsigned int status; ///< status of the transfer. One of the values from the \ref FileTransferState enum
const char* statusMessage; ///< utf8 encoded c string containing a human readable description of the status
uint64 remotefileSize; ///< size in bytes of the complete file to be transferred
uint64 bytes; ///< number of bytes transferred. Same as remotefileSize when the transfer completed entirely.
int isSender; ///< boolean. 1 if the server is sending the file. 0 if the server is receiving the file.
};
/*define for file transfer bandwith limits*/
#define BANDWIDTH_LIMIT_UNLIMITED 0xFFFFFFFFFFFFFFFFll
/*defines for speaker locations used by some sound callbacks*/
#ifndef SPEAKER_FRONT_LEFT
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#endif
#define SPEAKER_HEADPHONES_LEFT 0x10000000
#define SPEAKER_HEADPHONES_RIGHT 0x20000000
#define SPEAKER_MONO 0x40000000
#endif /*PUBLIC_DEFINITIONS_H*/
@@ -0,0 +1,217 @@
#ifndef PUBLIC_ERRORS_H
#define PUBLIC_ERRORS_H
//The idea here is: the values are 2 bytes wide, the first byte identifies the group, the second the count within that group
enum Ts3ErrorType {
//general
ERROR_ok = 0x0000, ///< Indicates success.
ERROR_undefined = 0x0001,
ERROR_not_implemented = 0x0002, ///< The attempted operation is not available in this context
ERROR_ok_no_update = 0x0003, ///< Indicates success, but no change occurred. Returned for example upon flushing (e.g. using \ref ts3client_flushChannelUpdates) when all indicated changes already matched the current state.
ERROR_dont_notify = 0x0004,
ERROR_lib_time_limit_reached = 0x0005,
ERROR_out_of_memory = 0x0006, ///< Not enough system memory to perform operation
ERROR_canceled = 0x0007,
ERROR_ok_no_error_event = 0x0008, ///< Indicates success, but no error event was generated. This is used because of the return code management and reduce packets.
//dunno
ERROR_command_not_found = 0x0100,
ERROR_unable_to_bind_network_port = 0x0101, ///< Unspecified failure to create a listening port
ERROR_no_network_port_available = 0x0102, ///< Failure to initialize a listening port for FileTransfer
ERROR_port_already_in_use = 0x0103, ///< Specified port is already in use by a different application
ERROR_command_line_parse_failed = 0x0104, ///< Command line arguments are invalid
ERROR_command_line_exit_version = 0x0105, ///< Command line specified version. The process should exit with code 0 after printing the version.
ERROR_command_line_exit_help = 0x0106, ///< Command line specified help. The process should exit with code 0 after priting the help.
//client
ERROR_client_invalid_id = 0x0200, ///< Client no longer connected
ERROR_client_nickname_inuse = 0x0201, ///< Client name is already in use. Client names must be unique
ERROR_client_protocol_limit_reached = 0x0203, ///< Too many clients on the server
ERROR_client_invalid_type = 0x0204, ///< Function called for normal clients that is only available for query clients or vice versa
ERROR_client_already_subscribed = 0x0205, ///< Attempting to subscribe to a channel already subscribed to
ERROR_client_not_logged_in = 0x0206,
ERROR_client_could_not_validate_identity = 0x0207, ///< Identity not valid or insufficient security level
ERROR_client_invalid_password = 0x0208,
ERROR_client_version_outdated = 0x020a, ///< Server requires newer client version as determined by the min_client_version properties
ERROR_client_is_flooding = 0x020c, ///< Triggered flood protection. Further information is supplied in the extra message if applicable.
ERROR_client_hacked = 0x020d,
ERROR_client_cannot_verify_now = 0x020e,
ERROR_client_login_not_permitted = 0x020f,
ERROR_client_not_subscribed = 0x0210, ///< Action is only available on subscribed channels
//channel
ERROR_channel_invalid_id = 0x0300, ///< Channel does not exist on the server (any longer)
ERROR_channel_protocol_limit_reached = 0x0301, ///< Too many channels on the server
ERROR_channel_already_in = 0x0302, ///< Attempting to move a client or channel to its current channel
ERROR_channel_name_inuse = 0x0303, ///< Channel name is already taken by another channel. Channel names must be unique
ERROR_channel_not_empty = 0x0304, ///< Attempting to delete a channel with clients or sub channels in it
ERROR_channel_can_not_delete_default = 0x0305, ///< Default channel cannot be deleted. Set a new default channel first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_default_require_permanent = 0x0306, ///< Attempt to set a non permanent channel as default channel. Set channel to permanent first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_invalid_flags = 0x0307, ///< Invalid combination of \ref ChannelProperties, trying to remove \ref CHANNEL_FLAG_DEFAULT or set a password on the default channel
ERROR_channel_parent_not_permanent = 0x0308, ///< Attempt to move a permanent channel into a non-permanent one, or set a channel to be permanent that is a sub channel of a non-permanent one
ERROR_channel_maxclients_reached = 0x0309, ///< Channel is full as determined by its \ref CHANNEL_MAXCLIENTS setting
ERROR_channel_maxfamily_reached = 0x030a, ///< Channel tree is full as determined by its \ref CHANNEL_MAXFAMILYCLIENTS setting
ERROR_channel_invalid_order = 0x030b, ///< Invalid value for the \ref CHANNEL_ORDER property. The specified channel must exist on the server and be on the same level.
ERROR_channel_no_filetransfer_supported = 0x030c, ///< Invalid \ref CHANNEL_FILEPATH set for the channel
ERROR_channel_invalid_password = 0x030d, ///< Channel has a password not matching the password supplied in the call
// used in public_rare_errors = 0x030e,
ERROR_channel_invalid_security_hash = 0x030f,
//server
ERROR_server_invalid_id = 0x0400, ///< Chosen virtual server does not exist or is offline
ERROR_server_running = 0x0401, ///< attempting to delete a server that is running. Stop the server before deleting it.
ERROR_server_is_shutting_down = 0x0402, ///< Client disconnected because the server is going offline
ERROR_server_maxclients_reached = 0x0403, ///< Given in the onConnectStatusChange event when the server has reached its maximum number of clients as defined by the \ref VIRTUALSERVER_MAXCLIENTS property
ERROR_server_invalid_password = 0x0404, ///< Specified server password is wrong. Provide the correct password in the \ref ts3client_startConnection / \ref ts3client_startConnectionWithChannelID call.
ERROR_server_is_virtual = 0x0407, ///< Server is in virtual status. The attempted action is not possible in this state. Start the virtual server first.
ERROR_server_is_not_running = 0x0409, ///< Attempting to stop a server that is not online.
ERROR_server_is_booting = 0x040a, // Not used
ERROR_server_status_invalid = 0x040b,
ERROR_server_version_outdated = 0x040d, ///< Attempt to connect to an outdated server version. The server needs to be updated.
ERROR_server_duplicate_running = 0x040e, ///< This server is already running within the instance. Each virtual server may only exist once.
//parameter
ERROR_parameter_quote = 0x0600, // Not used
ERROR_parameter_invalid_count = 0x0601, ///< Attempt to flush changes without previously calling set*VariableAs* since the last flush
ERROR_parameter_invalid = 0x0602, ///< At least one of the supplied parameters did not meet the criteria for that parameter
ERROR_parameter_not_found = 0x0603, ///< Failure to supply all the necessary parameters
ERROR_parameter_convert = 0x0604, ///< Invalid type supplied for a parameter, such as passing a string (ie. "five") that expects a number.
ERROR_parameter_invalid_size = 0x0605, ///< Value out of allowed range. Such as strings are too long/short or numeric values outside allowed range
ERROR_parameter_missing = 0x0606, ///< Neglecting to specify a required parameter
ERROR_parameter_checksum = 0x0607, ///< Attempting to deploy a modified snapshot
//unsorted, need further investigation
ERROR_vs_critical = 0x0700, ///< Failure to create default channel
ERROR_connection_lost = 0x0701, ///< Generic error with the connection.
ERROR_not_connected = 0x0702, ///< Attempting to call functions with a serverConnectionHandler that is not connected. You can use \ref ts3client_getConnectionStatus to check whether the connection handler is connected to a server
ERROR_no_cached_connection_info = 0x0703, ///< Attempting to query connection information (bandwidth usage, ping, etc) without requesting them first using \ref ts3client_requestConnectionInfo
ERROR_currently_not_possible = 0x0704, ///< Requested information is not currently available. You may have to call \ref ts3client_requestClientVariables or \ref ts3client_requestServerVariables
ERROR_failed_connection_initialisation = 0x0705, ///< No TeamSpeak server running on the specified IP address and port
ERROR_could_not_resolve_hostname = 0x0706, ///< Failure to resolve the specified hostname to an IP address
ERROR_invalid_server_connection_handler_id = 0x0707, ///< Attempting to perform actions on a non-existent server connection handler
ERROR_could_not_initialise_input_manager = 0x0708, // Not used
ERROR_clientlibrary_not_initialised = 0x0709, ///< Calling client library functions without successfully calling \ref ts3client_initClientLib before
ERROR_serverlibrary_not_initialised = 0x070a, ///< Calling server library functions without successfully calling \ref ts3server_initServerLib before
ERROR_whisper_too_many_targets = 0x070b, ///< Using a whisper list that contain more clients than the servers \ref VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE property
ERROR_whisper_no_targets = 0x070c, ///< The active whisper list is empty or no clients matched the whisper list (e.g. all channels in the list are empty)
ERROR_connection_ip_protocol_missing = 0x070d, ///< Invalid or unsupported protocol (e.g. attempting an IPv6 connection on an IPv4 only machine)
ERROR_handshake_failed = 0x070e,
ERROR_illegal_server_license = 0x070f,
//file transfer
ERROR_file_invalid_name = 0x0800, ///< Invalid UTF8 string or not a valid file
ERROR_file_invalid_permissions = 0x0801, ///< Permissions prevent opening the file
ERROR_file_already_exists = 0x0802, ///< Target path already exists as a directory
ERROR_file_not_found = 0x0803, ///< Attempt to access or move non existing file
ERROR_file_io_error = 0x0804, ///< Generic file input / output error
ERROR_file_invalid_transfer_id = 0x0805, ///< Attempt to get information about a file transfer after it has already been cleaned up. File transfer information is not available indefinitely after the transfer completed
ERROR_file_invalid_path = 0x0806, ///< specified path contains invalid characters or does not start with "/"
ERROR_file_no_files_available = 0x0807, // Not used
ERROR_file_overwrite_excludes_resume = 0x0808, ///< File overwrite and resume are mutually exclusive. Only one or neither can be 1.
ERROR_file_invalid_size = 0x0809, ///< Attempt to write more bytes than claimed file size.
ERROR_file_already_in_use = 0x080a, ///< File is currently not available, try again later.
ERROR_file_could_not_open_connection = 0x080b, ///< Generic failure in file transfer connection / other party did not conform to file transfer protocol
ERROR_file_no_space_left_on_device = 0x080c, ///< Operating system reports hard disk is full. May be caused by quota limitations.
ERROR_file_exceeds_file_system_maximum_size = 0x080d, ///< File is too large for the file system of the target device.
ERROR_file_transfer_connection_timeout = 0x080e, // Not used
ERROR_file_connection_lost = 0x080f, ///< File input / output timeout or connection failure
ERROR_file_exceeds_supplied_size = 0x0810, // Not used
ERROR_file_transfer_complete = 0x0811, ///< Indicates successful completion
ERROR_file_transfer_canceled = 0x0812, ///< Transfer was cancelled through @ref ts3client_haltTransfer
ERROR_file_transfer_interrupted = 0x0813, ///< Transfer failed because the server is shutting down, or network connection issues
ERROR_file_transfer_server_quota_exceeded = 0x0814, ///< Transfer terminated due to server bandwidth quota being exceeded. No client can transfer files.
ERROR_file_transfer_client_quota_exceeded = 0x0815, ///< Attempt to transfer more data than allowed by this clients' bandwidth quota. Other clients may continue to transfer files.
ERROR_file_transfer_reset = 0x0816, // Not used
ERROR_file_transfer_limit_reached = 0x0817, ///< Too many file transfers are in progress. Try again later
ERROR_file_invalid_storage_class = 0x0818, // TODO: Invalid storage class for HTTP FileTransfer (what is a storage class?)
ERROR_file_invalid_dimension = 0x0819, ///< Avatar image exceeds maximum width or height accepted by the server.
ERROR_file_transfer_channel_quota_exceeded = 0x081a, ///< Transfer failed because the channel quota was exceeded. Uploading to this channel is not possible, but other channels may be fine.
//sound
ERROR_sound_preprocessor_disabled = 0x0900, ///< Cannot set or query pre processor variables with preprocessing disabled
ERROR_sound_internal_preprocessor = 0x0901,
ERROR_sound_internal_encoder = 0x0902,
ERROR_sound_internal_playback = 0x0903,
ERROR_sound_no_capture_device_available = 0x0904, ///< No audio capture devices are available
ERROR_sound_no_playback_device_available = 0x0905, ///< No audio playback devices are available
ERROR_sound_could_not_open_capture_device = 0x0906, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_could_not_open_playback_device = 0x0907, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_handler_has_device = 0x0908, ///< Attempt to open a sound device on a connection handler which already has an open device. Close the already open device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_invalid_capture_device = 0x0909, ///< Attempt to use a device for capture that does not support capturing audio
ERROR_sound_invalid_playback_device = 0x090a, ///< Attempt to use a device for playback that does not support playback of audio
ERROR_sound_invalid_wave = 0x090b, ///< Attempt to use a non WAV file in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle
ERROR_sound_unsupported_wave = 0x090c, ///< Unsupported wave file used in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle.
ERROR_sound_open_wave = 0x090d, ///< Failure to open the specified sound file
ERROR_sound_internal_capture = 0x090e,
ERROR_sound_device_in_use = 0x090f, ///< Attempt to unregister a custom device that is being used. Close the device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_device_already_registerred = 0x0910, ///< Attempt to register a custom device with a device id that has already been used in a previous call. Device ids must be unique.
ERROR_sound_unknown_device = 0x0911, ///< Attempt to open, close, unregister or use a device which is not known. Custom devices must be registered before being used (see \ref ts3client_registerCustomDevice)
ERROR_sound_unsupported_frequency = 0x0912,
ERROR_sound_invalid_channel_count = 0x0913, ///< Invalid device audio channel count, must be > 0
ERROR_sound_read_wave = 0x0914, ///< Failure to read sound samples from an opened wave file. Is this a valid wave file?
ERROR_sound_need_more_data = 0x0915, // for internal purposes only
ERROR_sound_device_busy = 0x0916, // for internal purposes only
ERROR_sound_no_data = 0x0917, ///< Indicates there is currently no data for playback, e.g. nobody is speaking right now.
ERROR_sound_channel_mask_mismatch = 0x0918, ///< Opening a device with an unsupported channel count
//permissions
ERROR_permissions_client_insufficient = 0x0a08, ///< Not enough permissions to perform the requested activity
ERROR_permissions = 0x0a0c, ///< Permissions to use sound device not granted by operating system, e.g. Windows denied microphone access.
//accounting
ERROR_accounting_virtualserver_limit_reached = 0x0b00, ///< Attempt to use more virtual servers than allowed by the license
ERROR_accounting_slot_limit_reached = 0x0b01, ///< Attempt to set more slots than allowed by the license
ERROR_accounting_license_file_not_found = 0x0b02, // Not used
ERROR_accounting_license_date_not_ok = 0x0b03, ///< License expired or not valid yet
ERROR_accounting_unable_to_connect_to_server = 0x0b04, ///< Failure to communicate with accounting backend
ERROR_accounting_unknown_error = 0x0b05, ///< Failure to write update license file
ERROR_accounting_server_error = 0x0b06, // Not used
ERROR_accounting_instance_limit_reached = 0x0b07, ///< More than one process of the server is running
ERROR_accounting_instance_check_error = 0x0b08, ///< Shared memory access failure.
ERROR_accounting_license_file_invalid = 0x0b09, ///< License is not a TeamSpeak license
ERROR_accounting_running_elsewhere = 0x0b0a, ///< A copy of this server is already running in another instance. Each server may only exist once.
ERROR_accounting_instance_duplicated = 0x0b0b, ///< A copy of this server is running already in this process. Each server may only exist once.
ERROR_accounting_already_started = 0x0b0c, ///< Attempt to start a server that is already running
ERROR_accounting_not_started = 0x0b0d,
ERROR_accounting_to_many_starts = 0x0b0e, ///< Starting instance / virtual servers too often in too short a time period
//provisioning server
/// @cond HAS_PROVISIONING
ERROR_provisioning_invalid_password = 0x1100,
ERROR_provisioning_invalid_request = 0x1101,
ERROR_provisioning_no_slots_available = 0x1102,
ERROR_provisioning_pool_missing = 0x1103,
ERROR_provisioning_pool_unknown = 0x1104,
ERROR_provisioning_unknown_ip_location = 0x1105,
ERROR_provisioning_internal_tries_exceeded = 0x1106,
ERROR_provisioning_too_many_slots_requested = 0x1107,
ERROR_provisioning_too_many_reserved = 0x1108,
ERROR_provisioning_could_not_connect = 0x1109,
ERROR_provisioning_auth_server_not_connected = 0x1110,
ERROR_provisioning_auth_data_too_large = 0x1111,
ERROR_provisioning_already_initialized = 0x1112,
ERROR_provisioning_not_initialized = 0x1113,
ERROR_provisioning_connecting = 0x1114,
ERROR_provisioning_already_connected = 0x1115,
ERROR_provisioning_not_connected = 0x1116,
ERROR_provisioning_io_error = 0x1117,
ERROR_provisioning_invalid_timeout = 0x1118,
ERROR_provisioning_ts3server_not_found = 0x1119,
ERROR_provisioning_no_permission = 0x111A,
/// @endcond
// 0x12 - 0x15 are reserved in rare
// screen share
ERROR_already_registered = 0x1600,
ERROR_stream_session_limit_reached = 0x1601,
ERROR_stream_session_not_found = 0x1602,
ERROR_stream_unknown = 0x1603,
ERROR_stream_not_participating = 0x1604,
ERROR_not_streamer = 0x1605,
ERROR_already_joined = 0x1606,
ERROR_join_request_not_found = 0x1607,
ERROR_sfu_failed_to_start = 0x1608,
};
#endif
@@ -0,0 +1,236 @@
#ifndef TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#define TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Version definitions.
#define TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1 1
// Protocol used for communication between the session subscriber and the session (a single stream).
// Commands are sent bidirectionally or unidirectionally between the parties.
// e.g. SESSION => SUBSCRIBER: ON_FRAME, ON_PAUSED_CHANGED
// e.g. SUBSCRIBER => SESSION: ON_FRAME_ACK, ON_RESIZE
// Command type enum with a lowercase type name.
typedef enum
{
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME = 0,
TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE,
TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED,
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK,
TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP,
TS_SESSION_SUBSCRIBER_CMD_REMOVE_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED,
} ts_session_subscriber_command_type_t;
// Pixel format enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_I420 = 0,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_NV12,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ABGR,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ARGB,
} ts_session_subscriber_pixel_format_t;
// Buffer location enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_CPU = 0,
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_GPU
} ts_session_subscriber_buffer_location_t;
// Buffer type enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_SINGLE = 0,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_MAIN,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_SUB
} ts_session_subscriber_buffer_type_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(push, 4)
#endif
// Main buffer header for shared CPU Memory Front/Back Buffers.
// The Main Buffer contains metadata about the current front/back buffer and the versioning for both the main and sub buffer.
// The information from the main buffer can be used to always read the front buffer.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t front_buffer_index; // index of the front buffer. (0: main buffer, 1: sub buffer)
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_main_buffer_header_t;
// Sub buffer header.
typedef struct
{
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
} ts_session_subscriber_sub_buffer_header_t;
// Single frame buffer header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_single_frame_buffer_header_t;
// Command header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // Total message length (header + payload).
ts_session_subscriber_command_type_t type;
uint64_t target_session_id; // always set to the target session id this command is for or is originating from.
uint64_t target_subscriber_id; // 0 if broadcast.
} ts_session_subscriber_command_header_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME.
// The frame data is not included in the message, but is attached seperately or was sent beforehand. The buffer is identified by it's id.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_id; // buffer id, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_frame_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t frame_id;
} ts_session_subscriber_on_frame_ack_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE.
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t width;
uint32_t height;
} ts_session_subscriber_on_resize_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t paused; // 0 or 1.
} ts_session_subscriber_on_paused_changed_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE.
// Contains a single frame buffer. The header is of format |ts_session_subscriber_single_frame_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
ts_session_subscriber_buffer_type_t buffer_type;
} ts_session_subscriber_on_buffer_single_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK.
// Contains a main buffer and a sub buffer. The main buffer header
// contains metadata about the current front/back buffer and
// is of type |ts_session_subscriber_main_buffer_header_t|.
// The sub buffer's header is of type |ts_session_subscriber_sub_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t main_buffer_ptr; // main buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t main_buffer_length;
uint64_t sub_buffer_ptr; // sub buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t sub_buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
} ts_session_subscriber_on_buffer_front_back_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER.
// SUBSCRIBER => SESSION.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_resp_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_release_buffer_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr;
int bits_per_sample;
int sample_rate;
uint32_t number_of_channels;
uint32_t number_of_frames;
int64_t absolute_capture_timestamp_ms;
float volume;
} ts_session_subscriber_on_audio_frames_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t audio_enabled;
} ts_session_subscriber_on_audio_enabled_changed_payload_t;
// Overall Command structure.
typedef struct
{
ts_session_subscriber_command_header_t header;
union
{
ts_session_subscriber_on_frame_payload_t frame;
ts_session_subscriber_on_resize_payload_t resize;
ts_session_subscriber_on_paused_changed_payload_t paused;
ts_session_subscriber_on_frame_ack_payload_t frame_ack;
ts_session_subscriber_on_buffer_single_payload_t buffer_single;
ts_session_subscriber_on_buffer_front_back_payload_t buffer_front_back;
ts_session_subscriber_on_release_buffer_payload_t release_buffer;
ts_session_subscriber_add_subscriber_payload_t add_subscriber;
ts_session_subscriber_add_subscriber_resp_payload_t add_subscriber_resp;
ts_session_subscriber_on_audio_frames_payload_t audio_frames;
ts_session_subscriber_on_audio_enabled_changed_payload_t audio_enabled_changed;
} payload;
} ts_session_subscriber_command_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif // TS_SESSION_SUBSCRIBER_PROTOCOL_H_
@@ -0,0 +1,32 @@
// TeamSpeakClient framework module map — SDK surface.
//
// This minimal map covers only the ObjC-safe public surface exposed by the
// team_client library itself (teamspeak/*.h, teamlog/logtypes.h, and the
// common headers that make up the public clientlib API).
//
// For non-SDK iOS app builds, workspace/_iOS/CMakeLists.txt generates a full
// replacement map (installed over this one) that additionally declares the
// C++-only submodules for cloud_common, cloud_sync_client, interface, tsdns,
// compiler_settings, and team_revocation.
//
// Consumers:
// - In .m / .h reached from .m sources:
// #import <TeamSpeakClient/teamspeak/clientlib.h> // ObjC-safe
// @import TeamSpeakClient; // ObjC-safe surface
//
// - In Swift:
// import TeamSpeakClient // ObjC-safe surface only
framework module TeamSpeakClient {
// ObjC-safe surface: plain-C / ObjC-compatible headers only.
// Enumerated by CMake at configure time — see OBJC_SAFE_HEADERS in
// workspace/client/CMakeLists.txt.
export *
header "teamspeak/clientlib.h"
header "teamspeak/video/session_subscriber_protocol.h"
header "teamspeak/clientlib_sdk.h"
header "teamspeak/public_definitions.h"
header "teamspeak/public_errors.h"
header "teamlog/logtypes.h"
}
@@ -0,0 +1,23 @@
#ifndef TEAMLOG_LOGTYPES_H
#define TEAMLOG_LOGTYPES_H
enum LogTypes {
LogType_NONE = 0x0000, ///< Logging is disabled
LogType_FILE = 0x0001, ///< Log to regular log file
LogType_CONSOLE = 0x0002, ///< Log to standard output / error
LogType_USERLOGGING = 0x0004, ///< User defined logging. Will call the \ref ServerLibFunctions.onUserLoggingMessageEvent callback for every message to be logged
LogType_NO_NETLOGGING = 0x0008, ///< Not used
LogType_DATABASE = 0x0010, ///< Log to database (deprecated, server only, no effect in SDK)
LogType_SYSLOG = 0x0020, ///< Log to syslog (only available on Linux)
};
enum LogLevel {
LogLevel_CRITICAL = 0, ///< these messages stop the program
LogLevel_ERROR, ///< everything that is really bad, but not so bad we need to shut down
LogLevel_WARNING, ///< everything that *might* be bad
LogLevel_DEBUG, ///< output that might help find a problem
LogLevel_INFO, ///< informational output, like "starting database version x.y.z"
LogLevel_DEVEL ///< developer only output (will not be displayed in release mode)
};
#endif //TEAMLOG_LOGTYPES_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,58 @@
#ifndef CLIENTLIB_SDK_H
#define CLIENTLIB_SDK_H
// system
#include <stdlib.h>
// own
#include "teamspeak/public_definitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets the client to which to transmit voice. Stops standard channel voice transmission.
*
* The client will still receive voice from their current channel, however their voice will not be transmitted to their
* current channel anymore. If this call is successful (check onServerErrorEvent) then voice of the specified client
* will be transmitted to all specified channels and all the specified clients. Pass 0 to both target parameter arrays
* to restore default behavior of transmitting voice to current channel. You will receive an onServerErrorEvent with the
* passed returnCode indicating whether or not the operation was successful.
*
* @param server_connection_handler_id the connection handler on which to set the whisper list
* @param client_id the client to set the whisper list for. Set to 0 or your own client ID to set your own whisper list.
* @param channel_ids an array of channel ids to transmit voice to.
* @param channel_ids_size number of elements in aforementioned array.
* @param client_ids a zero terminated array of client ids to transmit voice to.
* @param client_ids_size number of elements in aforementioned array.
* @param impersonate if the target client is a webrtc client, the voice packets will look like as if they have been
* send by the invoking client id
* @param return_code a c string to identify this request in callbacks. Pass an empty string if unused.
* @return An error code from the @ref Ts3ErrorType enum indicating either success or the failure reason
*/
EXPORTDLL unsigned int ts_client_request_client_set_whisper_list(uint64 server_connection_handler_id, anyID client_id,
const uint64* channel_ids,
int channel_ids_size,
const anyID* client_ids,
int client_ids_size, int impersonate,
const char* return_code);
/**
* @brief Send a binary-serialized ClientCommandRequest protobuf to the client library.
*
* The response will be delivered asynchronously via the onProtoResponse callback
* as a serialized ClientCommandResponse protobuf.
*
* @param data Pointer to serialized ClientCommandRequest protobuf bytes
* @param size Size of the serialized data in bytes
* @param return_code Caller-provided string to correlate the response in onProtoResponse. May be NULL.
* @return An error code: ERROR_ok on successful dispatch, ERROR_parameter_invalid on parse failure
*/
EXPORTDLL unsigned int ts3client_postProtoCommand(const void* data, size_t size, const char* return_code);
#ifdef __cplusplus
}
#endif
#endif // CLIENTLIB_SDK_H
@@ -0,0 +1,635 @@
#ifndef PUBLIC_DEFINITIONS_H
#define PUBLIC_DEFINITIONS_H
#include "teamlog/logtypes.h"
#define TS3_MAX_SIZE_CHANNEL_NAME 40 // channel name maximum length in characters
#define TS3_MAX_SIZE_VIRTUALSERVER_NAME 64 // virtual server name maximum length in characters
#define TS3_MAX_SIZE_CLIENT_NICKNAME 64 // client display name length limit in characters
#define TS3_MIN_SIZE_CLIENT_NICKNAME 3 // client display name minimum length in characters
#define TS3_MAX_SIZE_REASON_MESSAGE 80 // length limit in characters for kick, move, etc reasons
#define TS3_MAX_SIZE_TEXTMESSAGE 8192 // text message length limit, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_TOPIC 255 // channel topic lengt limith, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_DESCRIPTION 8192 // channel description length limit, measured in bytes (utf8 encoded)
// server welcome message length limit measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_VIRTUALSERVER_WELCOMEMESSAGE 1024
#define TS3_SIZE_MYTSID 44
// minimum amount of seconds before a clientID that was in use can be assigned to a new client
#define TS3_MIN_SECONDS_CLIENTID_REUSE 300
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32)
typedef unsigned __int16 anyID;
typedef unsigned __int64 uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __declspec(dllexport)
#else
#define EXPORTDLL
#endif
#endif
#else
#include <stdint.h>
typedef uint16_t anyID;
typedef uint64_t uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __attribute__((visibility("default")))
#else
#define EXPORTDLL
#endif
#endif
#endif
enum Visibility
{
ENTER_VISIBILITY = 0, ///< Client joined from an unsubscribed channel, or joined the server.
RETAIN_VISIBILITY, ///< Client switched from one subscribed channel to a different subscribed channel.
LEAVE_VISIBILITY ///< Client switches to an unsubscribed channel, or disconnected from server.
};
enum ConnectStatus
{
STATUS_DISCONNECTED = 0, ///< There is no activity to the server, this is the default value
STATUS_CONNECTING, ///< We are trying to connect, we haven't got a client id yet, we haven't been accepted by the server
STATUS_CONNECTED, ///< The server has accepted us, we can talk and hear and we have a client id, but we don't
///< have the channels and clients yet, we can get server infos (welcome msg etc.)
STATUS_CONNECTION_ESTABLISHING, ///< we are connected and we are visible
STATUS_CONNECTION_ESTABLISHED, ///< we are connected and we have the client and channels available
};
enum LocalTestMode
{
TEST_MODE_OFF = 0,
TEST_MODE_VOICE_LOCAL_ONLY,
TEST_MODE_VOICE_LOCAL_AND_REMOTE,
TEST_MODE_TALK_STATUS_CHANGES_ONLY
};
enum TalkStatus
{
STATUS_NOT_TALKING = 0, ///< client is not talking
STATUS_TALKING = 1, ///< client is talking
STATUS_TALKING_WHILE_DISABLED = 2, ///< client is talking while the microphone is muted (only valid for own client)
};
enum CodecType
{
CODEC_SPEEX_NARROWBAND = 0, ///< (deprecated) mono, 16bit, 8kHz, bitrate dependent on the quality setting
CODEC_SPEEX_WIDEBAND, ///< (deprecated) mono, 16bit, 16kHz, bitrate dependent on the quality setting
CODEC_SPEEX_ULTRAWIDEBAND, ///< (deprecated) mono, 16bit, 32kHz, bitrate dependent on the quality setting
CODEC_CELT_MONO, ///< (deprecated) mono, 16bit, 48kHz, bitrate dependent on the quality setting
CODEC_OPUS_VOICE, ///< mono, 16bit, 48khz, bitrate dependent on the quality setting, optimized for voice
CODEC_OPUS_MUSIC, ///< stereo, 16bit, 48khz, bitrate dependent on the quality setting, optimized for music
};
enum CodecEncryptionMode
{
CODEC_ENCRYPTION_PER_CHANNEL = 0, ///< voice data encryption decided per channel
CODEC_ENCRYPTION_FORCED_OFF, ///< voice data encryption disabled
CODEC_ENCRYPTION_FORCED_ON, ///< voice data encryption enabled
};
enum TextMessageTargetMode
{
TextMessageTarget_CLIENT = 1, ///< Message is a private message to another client
TextMessageTarget_CHANNEL, ///< Message is sent to a channel, received by all clients in that channel at the time
TextMessageTarget_SERVER, ///< Message is sent to every client on the server
TextMessageTarget_MAX
};
enum MuteInputStatus
{
MUTEINPUT_NONE = 0, ///< Microphone is not muted, audio is sent to the server
MUTEINPUT_MUTED, ///< Microphone is muted, no audio is transmitted to the server
};
enum MuteOutputStatus
{
MUTEOUTPUT_NONE = 0, ///< Speaker is active, server is sending us audio
MUTEOUTPUT_MUTED, ///< Speaker is muted, server is not sending audio to us
};
enum HardwareInputStatus
{
HARDWAREINPUT_DISABLED = 0, ///< no capture device opened
HARDWAREINPUT_ENABLED, ///< capture device open
};
enum HardwareOutputStatus
{
HARDWAREOUTPUT_DISABLED = 0, ///< no playback device opened
HARDWAREOUTPUT_ENABLED, ///< playback device open
};
enum InputDeactivationStatus
{
INPUT_ACTIVE = 0, ///< Audio is captured from the capture device.
INPUT_DEACTIVATED = 1, ///< No audio is captured from the capture device.
};
enum ReasonIdentifier
{
REASON_NONE = 0, ///< no reason data
REASON_MOVED = 1, ///< client was moved
REASON_SUBSCRIPTION = 2, // no reason data
REASON_LOST_CONNECTION = 3, // reasonmsg=reason
REASON_KICK_CHANNEL = 4, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER = 5, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER_BAN = 6, //{SectionInvoker} reasonmsg=reason bantime=time //{SectionInvoker} is only added server->client
REASON_SERVERSTOP = 7, // reasonmsg=reason
REASON_CLIENTDISCONNECT = 8, // reasonmsg=reason
REASON_CHANNELUPDATE = 9, // no reason data
REASON_CHANNELEDIT = 10, //{SectionInvoker}
REASON_CLIENTDISCONNECT_SERVER_SHUTDOWN = 11, // reasonmsg=reason
};
enum Protocol_Encryption_Cipher
{
AES_128 = 0b00000000,
AES_256 = 0b00000001,
PROTOCOL_ENCRYPTION_CIPHER_END_MARKER,
RESERVED = 0b00010000, // reserved until puzzle v2 is fully released, then can be reused
PUZZLE_2 = 0b00100000,
};
enum ChannelProperties
{
CHANNEL_NAME = 0, ///< String. Read/Write. Name of the channel. Always available.
CHANNEL_TOPIC, ///< String. Read/Write. Short single line text describing what the channel is about. Always available.
CHANNEL_DESCRIPTION, ///< String. Read/Write. Arbitrary text (up to 8k bytes) with information about the channel.
///< Must be requested (\ref ts3client_requestChannelDescription)
CHANNEL_PASSWORD, ///< String. Read/Write. Password of the channel. Read access is limited to the server. Clients
///< will only ever see the last password they attempted to use when joining the channel. Always available.
CHANNEL_CODEC, ///< Integer. Read/Write. The codec this channel is using. One of the values from the \ref CodecType
///< enum. Always available.
CHANNEL_CODEC_QUALITY, ///< Integer. Read/Write. The quality setting of the channel. Valid values are 0 to 10 inclusive.
///< Higher value means better voice quality but also more bandwidth usage. Always available.
CHANNEL_MAXCLIENTS, ///< Integer. Read/Write. The number of clients that can be in the channel simultaneously.
///< Always available.
CHANNEL_MAXFAMILYCLIENTS, ///< Integer. Read/Write. The total number of clients that can be in this channel and all
///< sub channels of this channel. Always available.
CHANNEL_ORDER, ///< UInt64. Read/Write. The ID of the channel below which this channel should be displayed. If 0
///< the channel is sorted at the top of the current level. Always available.
CHANNEL_FLAG_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when empty.
///< Permanent channels are stored to the database and available after server restart. SDK
///< users will need to take care of restoring channel at server start on their own.
///< Mutually exclusive with \ref CHANNEL_FLAG_SEMI_PERMANENT. Always available.
CHANNEL_FLAG_SEMI_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when
///< empty. Semi permanent channels are not stored to disk and gone after server
///< restart but remain while empty. Mutually exclusive with \ref
///< CHANNEL_FLAG_PERMANENT. Always available.
CHANNEL_FLAG_DEFAULT, ///< Integer. Read/Write. Boolean (1/0). The default channel is the channel that all clients
///< are located in when they join the server, unless the client explicitly specified a
///< different channel when connecting and is allowed to join their preferred channel. Only
///< one channel on the server can have this flag set. The default channel must have \ref
///< CHANNEL_FLAG_PERMANENT set. Always available.
CHANNEL_FLAG_PASSWORD, ///< Integer. Read/Write. Boolean (1/0) indicating whether this channel is password protected.
///< When removing or setting \ref CHANNEL_PASSWORD you also need to adjust this flag.
CHANNEL_CODEC_LATENCY_FACTOR, ///< (deprecated) Integer. Read/Write. Allows to increase packet size, reducing
///< bandwith at the cost of higher latency of voice transmission. Valid values are
///< 1-10 inclusive. 1 is the default and offers the lowest latency. Always available.
CHANNEL_CODEC_IS_UNENCRYPTED, ///< Integer. Read/Write. Boolean (1/0). If 0 voice data is encrypted, if 1 the voice
///< data is not encrypted. Only used if the server \ref
///< VIRTUALSERVER_CODEC_ENCRYPTION_MODE is set to \ref CODEC_ENCRYPTION_PER_CHANNEL.
///< Always available.
CHANNEL_SECURITY_SALT, ///< String. Read/Write. SDK Only, not used by TeamSpeak. This channels security hash. When
///< a client joins their \ref CLIENT_SECURITY_HASH is compared to this value, to allow or
///< deny the client access to the channel. Used to enforce clients joining the server with
///< specific identity and \ref CLIENT_META_DATA. See SDK Documentation about this feature
///< for further details. Always available.
CHANNEL_DELETE_DELAY, ///< UInt64. Read/Write. Number of seconds deletion of temporary channels is delayed after
///< the last client leaves the channel. Channel is only deleted if empty when the delete
///< delay expired. Always available.
CHANNEL_UNIQUE_IDENTIFIER, ///< String. Read only. An identifier that uniquely identifies a channel. Available in
///< Server >= 3.10.0
CHANNEL_ENDMARKER,
};
enum ClientProperties
{
CLIENT_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Public Identity, can be used to identify a client
///< installation. Remains identical as long as the client keeps using the same
///< identity. Available for visible clients.
CLIENT_NICKNAME, ///< String. Read/Write. Display name of the client. Available for visible clients.
CLIENT_VERSION, ///< String. Read only. Version String of the client used. For clients other than ourself this
///< needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_PLATFORM, ///< String. Read only. Operating system used by the client. For other clients other than ourself
///< this needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_FLAG_TALKING, ///< Integer. Read only. Whether the client is talking. Available on clients that are either
///< whispering to us, or in our channel.
CLIENT_INPUT_MUTED, ///< Integer. Read/Write. Microphone mute status. Available for visible clients. One of the
///< values from the \ref MuteInputStatus enum.
CLIENT_OUTPUT_MUTED, ///< Integer. Read/Write. Speaker mute status. Speaker mute implies microphone mute. Available
///< for visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_OUTPUTONLY_MUTED, ///< Integer. Read/Write. Speaker mute status. Microphone may be active. Available for
///< visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_INPUT_HARDWARE, ///< Integer. Read only. Indicates whether a capture device is open. Available for visible
///< clients. One of the values from the \ref HardwareInputStatus enum.
CLIENT_OUTPUT_HARDWARE, ///< Integer. Read only. Indicates whether a playback device is open. Available for visible
///< clients. One of the values from the \ref HardwareOutputStatus enum.
CLIENT_INPUT_DEACTIVATED, ///< Integer. Read/Write. Not available server side. Local microphone mute status.
///< Available only for own client. Used to implement Push To Talk. One of the values from
///< the \ref InputDeactivationStatus enum.
CLIENT_IDLE_TIME, ///< UInt64. Read only. Seconds since last activity. Available only for own client.
CLIENT_DEFAULT_CHANNEL, ///< String. Read only. User specified channel they joined when connecting to the server.
///< Available only for own client.
CLIENT_DEFAULT_CHANNEL_PASSWORD, ///< String. Read only. User specified channel password for the channel they
///< attempted to join when connecting to the server. Available only for own
///< client.
CLIENT_SERVER_PASSWORD, ///< String. Read only. User specified server password. Available only for own client.
CLIENT_META_DATA, ///< String. Read/Write. Can be used to store up to 4096 bytes of information on clients. Not
///< used by TeamSpeak. Available for visible clients.
CLIENT_IS_MUTED, ///< Integer. Read only. Not available server side. Indicates whether we have muted the client
///< using \ref ts3client_requestMuteClients. Available for visible clients other than ourselves.
CLIENT_IS_RECORDING, ///< Integer. Read only. Indicates whether the client is recording incoming audio. Available
///< for visible clients.
CLIENT_VOLUME_MODIFICATOR, ///< Integer. Read only. Volume adjustment for this client as set by \ref
///< ts3client_setClientVolumeModifier. Available for visible clients.
CLIENT_VERSION_SIGN, ///< String. Read only. TeamSpeak internal signature.
CLIENT_SECURITY_HASH, ///< String. Read/Write. This clients security hash. Not used by TeamSpeak, SDK only. Hash is
///< provided by an outside source. A channel will use the security salt + other client data
///< to calculate a hash, which must be the same as the one provided here. See SDK
///< documentation about Client / Channel Security Hashes for more details.
CLIENT_ENCRYPTION_CIPHERS, ///< String. Read only. SDK only. List of available ciphers this client can use.
CLIENT_IS_STREAMING, ///< bool. Read only, Is currently streaming.
CLIENT_ENDMARKER,
};
enum VirtualServerProperties
{
VIRTUALSERVER_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Unique identifier for a virtual server, does not
///< change on server restart. Available if \ref ts3client_getConnectionStatus
///< is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_NAME, ///< String. Read/Write. The virtual server display name. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_WELCOMEMESSAGE, ///< String. Read/Write. The welcome message displayed to clients on connect.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED. Not
///< updated automatically when changed, updates need to be requested (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_PLATFORM, ///< String. Read only. The operating system the server is running on. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_VERSION, ///< String. Read only. The server software version string. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_MAXCLIENTS, ///< UInt64. Read/Write. The maximum number of clients that can be connected
///< simultaneously. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_PASSWORD, ///< String. Read/Write. The server password. Read access is limited to the server. Clients
///< will only get the password they supplied when connecting. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_CLIENTS_ONLINE, ///< UInt64. Read only. The current number of clients connected to the server,
///< including query connections. Only available on request (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_CHANNELS_ONLINE, ///< UInt64. Read only. The current number of channels on the server. Only
///< available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CREATED, ///< Integer. Read only. The time this virtual server was created as unix timestamp.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_UPTIME, ///< UInt64. Read only. Number of seconds that have passed since the virtual server was
///< started. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CODEC_ENCRYPTION_MODE, ///< Integer. Read/Write. Boolean (1/0) that specifies if voice data is encrypted
///< during transfer. One of the values from the \ref CodecEncryptionMode enum.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_ENCRYPTION_CIPHERS, ///< String. Read/Write. Comma separated list of available ciphers to encrypt the
///< connection. The server will use the first cipher in the list that is also
///< listed in the \ref CLIENT_ENCRYPTION_CIPHERS of the connecting client.
///< Clients will fail to connect if no match is found. Always available.
VIRTUALSERVER_ADDRESS, ///< Any resolvable address for the specific virtual server
VIRTUALSERVER_VERSION_SIGN, ///< String. Read only. Signature of Platform and Version.
VIRTUALSERVER_ENDMARKER,
VIRTUALSERVER_FILEBASE = 24, ///< String. Read only. The path to the base directory used to store files
///< transferred using file transfer. Available only on the server. Is set by \ref
///< ts3server_enableFileManager
VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH = 29, ///< UInt64. Read/Write. Maximum traffic in bytes the server can
///< use for file transfer downloads. Only available on request
///< (\ref ts3client_requestServerVariables).
VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH = 30, ///< UInt64. Read/Write. Maximum traffic in bytes the server can use
///< for file transfer uploads. Only available on request (=>
///< requestServerVariables)
VIRTUALSERVER_LOG_FILETRANSFER = 64 ///< Integer. Read/Write. Boolean (1/0) indicating whether to include file
///< transfer activities (uploading or downloading of files) in the server log.
///< Always available.
};
/**
* Various connection properties.
* These are all read only, and except for your own client must be requested using \ref ts3client_requestConnectionInfo
*/
enum ConnectionProperties
{
CONNECTION_PING = 0, ///< UInt64. Round trip latency for the connection based on the last 5 seconds. On the server
///< this is the average across all connected clients for the last 5 seconds.
CONNECTION_PING_DEVIATION, ///< Double. Standard deviation for the round trip latency in \ref CONNECTION_PING
CONNECTION_CONNECTED_TIME, ///< UInt64. Seconds the client has been connected.
CONNECTION_IDLE_TIME, ///< UInt64. Time in seconds since the last activity (voice transmission, switching channels,
///< changing mic / speaker mute status) of the client.
CONNECTION_CLIENT_IP, ///< String. IP of this client (as seen from the server side)
CONNECTION_CLIENT_PORT, ///< UInt64. Client side port of this client (as seen from the server side)
CONNECTION_SERVER_IP, ///< String. The IP or hostname used to connect to the server. Only available on yourself.
CONNECTION_SERVER_PORT, ///< UInt64. The server port connected to. Only available on yourself.
CONNECTION_PACKETS_SENT_SPEECH, ///< UInt64. The number of voice packets transmitted by the client.
CONNECTION_PACKETS_SENT_KEEPALIVE, ///< UInt64. The number of keep alive packets transmitted by the client.
CONNECTION_PACKETS_SENT_CONTROL, ///< UInt64. The number of command & control packets transmitted by the client.
CONNECTION_PACKETS_SENT_TOTAL, ///< UInt64. Total number of packets transmitted by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_SENT_SPEECH, \ref CONNECTION_PACKETS_SENT_KEEPALIVE and
///< \ref CONNECTION_PACKETS_SENT_CONTROL
CONNECTION_BYTES_SENT_SPEECH, ///< UInt64. Outgoing traffic used for voice data by the client.
CONNECTION_BYTES_SENT_KEEPALIVE, ///< UInt64. Outgoing traffic used for keeping the connection alive by the client.
CONNECTION_BYTES_SENT_CONTROL, ///< UInt64. Outgoing traffic used for command & control data by the client.
CONNECTION_BYTES_SENT_TOTAL, ///< UInt64. Total outgoing traffic to the server by this client. Equal to the sum of
///< \ref CONNECTION_BYTES_SENT_SPEECH, \ref CONNECTION_BYTES_SENT_KEEPALIVE and \ref
///< CONNECTION_BYTES_SENT_CONTROL
CONNECTION_PACKETS_RECEIVED_SPEECH, ///< UInt64. Number of voice packets received by the client.
CONNECTION_PACKETS_RECEIVED_KEEPALIVE, ///< UInt64. Number of keep alive packets received by the client.
CONNECTION_PACKETS_RECEIVED_CONTROL, ///< UInt64. Number of command & control packets received by the client.
CONNECTION_PACKETS_RECEIVED_TOTAL, ///< UInt64. Total number of packets received by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_RECEIVED_SPEECH, \ref
///< CONNECTION_PACKETS_RECEIVED_KEEPALIVE and \ref
///< CONNECTION_PACKETS_RECEIVED_CONTROL
CONNECTION_BYTES_RECEIVED_SPEECH, ///< UInt64. Incoming traffic used by the client for voice data.
CONNECTION_BYTES_RECEIVED_KEEPALIVE, ///< UInt64. Incoming traffic used by the client to keep the connection alive.
CONNECTION_BYTES_RECEIVED_CONTROL, ///< UInt64. Incoming traffic used by the client for command & control data.
CONNECTION_BYTES_RECEIVED_TOTAL, ///< UInt64. Total incoming traffic used by the client. Equal to the sum of \ref
///< CONNECTION_BYTES_RECEIVED_SPEECH, \ref CONNECTION_BYTES_RECEIVED_KEEPALIVE and
///< \ref CONNECTION_BYTES_RECEIVED_CONTROL
CONNECTION_PACKETLOSS_SPEECH, ///< Double. Percentage points of voice packets for the client that did not arrive at
///< the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_KEEPALIVE, ///< Double. Percentage points of keep alive packets for the client that did not
///< arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_CONTROL, ///< Double. Percentage points of command & control packets for the client that did
///< not arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_TOTAL, ///< Double. Cumulative chance in percentage points with which a packet round trip
///< failed because a packet was lost
CONNECTION_SERVER2CLIENT_PACKETLOSS_SPEECH, ///< Double. Probability with which a voice packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< server was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the server was not
///< received by the client.
CONNECTION_CLIENT2SERVER_PACKETLOSS_SPEECH, ///< Double. Probability with which a speech packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< client was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the client was not
///< received by the server.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes sent for speech data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes sent for keepalive data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes sent for control data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes sent in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second sent for speech data, averaged over the
///< last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second sent for keepalive data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second sent for control data, averaged over
///< the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second sent, averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes received for speech data in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes received for keepalive data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes received for control data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes received in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second received for speech data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second received for keepalive data,
///< averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second received for control data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second received, averaged over the last minute.
CONNECTION_DUMMY_0,
CONNECTION_DUMMY_1,
CONNECTION_DUMMY_2,
CONNECTION_DUMMY_3,
CONNECTION_DUMMY_4,
CONNECTION_DUMMY_5,
CONNECTION_DUMMY_6,
CONNECTION_DUMMY_7,
CONNECTION_DUMMY_8,
CONNECTION_DUMMY_9,
CONNECTION_FILETRANSFER_BANDWIDTH_SENT, ///< UInt64. Current file transfer upstream activity in bytes per second.
///< Only available on request (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, ///< UInt64. Current file transfer downstream activity in bytes per
///< second. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, ///< UInt64. Total downstream traffic, in bytes, used for file
///< transfer since the server was started. Only available on request
///< (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, ///< UInt64. Total upstream traffic, in bytes, used for file transfer
///< since the server was started. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_ENDMARKER
};
/**
* Describes a client position in 3 dimensional space, used for 3D Sound.
*/
typedef struct
{
float x; ///< X co-ordinate in 3D space.
float y; ///< Y co-ordinate in 3D space.
float z; ///< Z co-ordinate in 3D space.
} TS3_VECTOR;
enum GroupWhisperType
{
GROUPWHISPERTYPE_SERVERGROUP = 0, ///< Whisper list consists of server groups
GROUPWHISPERTYPE_CHANNELGROUP = 1, ///< Whisper list consists of channel groups
GROUPWHISPERTYPE_CHANNELCOMMANDER = 2, ///< whisper to channel commanders
GROUPWHISPERTYPE_ALLCLIENTS = 3, ///< whisper to all clients
GROUPWHISPERTYPE_ENDMARKER,
};
enum GroupWhisperTargetMode
{
GROUPWHISPERTARGETMODE_ALL = 0,
GROUPWHISPERTARGETMODE_CURRENTCHANNEL = 1, ///< Whisper the current channel of the client
GROUPWHISPERTARGETMODE_PARENTCHANNEL = 2, ///< Whisper the parent channel of whatever channel the client is currently in
GROUPWHISPERTARGETMODE_ALLPARENTCHANNELS = 3, ///< Whipser to the parent channel and all their parent channels as well
GROUPWHISPERTARGETMODE_CHANNELFAMILY = 4, ///< Whisper to the current channel and all its sub channels
GROUPWHISPERTARGETMODE_ANCESTORCHANNELFAMILY = 5, ///< Whisper to the current channel, all its parent and sub channels.
GROUPWHISPERTARGETMODE_SUBCHANNELS = 6, ///< Whisper to all sub channels of the current channel of the client
GROUPWHISPERTARGETMODE_ENDMARKER,
};
enum MonoSoundDestination
{
MONO_SOUND_DESTINATION_ALL = 0, ///< Send mono sound to all available speakers
MONO_SOUND_DESTINATION_FRONT_CENTER = 1, ///< Send mono sound to front center speaker if available
MONO_SOUND_DESTINATION_FRONT_LEFT_AND_RIGHT = 2 ///< Send mono sound to front left/right speakers if available
};
enum SecuritySaltOptions
{
SECURITY_SALT_CHECK_NICKNAME = 1, ///< put nickname into security hash
SECURITY_SALT_CHECK_META_DATA = 2 ///< put meta data into security hash
};
/*this enum is used to disable client commands on the server*/
enum ClientCommand
{
CLIENT_COMMAND_requestConnectionInfo = 0, ///< disable client connection info request (client bandwidth usage, ip,
///< port, ping)
CLIENT_COMMAND_requestClientMove = 1, ///< disable moving clients
CLIENT_COMMAND_requestXXMuteClients = 2, ///< disable muting other clients
CLIENT_COMMAND_requestClientKickFromXXX = 3, ///< disable kicking clients
CLIENT_COMMAND_flushChannelCreation = 4, ///< disable creating channels
CLIENT_COMMAND_flushChannelUpdates = 5, ///< disable editing channels
CLIENT_COMMAND_requestChannelMove = 6, ///< disable moving channels
CLIENT_COMMAND_requestChannelDelete = 7, ///< disable deleting channels
CLIENT_COMMAND_requestChannelDescription = 8, ///< disable channel descriptions
CLIENT_COMMAND_requestChannelXXSubscribeXXX = 9, ///< disable being able to see clients in channels other than the
///< current channel the client is in
CLIENT_COMMAND_requestServerConnectionInfo = 10, ///< disable server connection info request (server bandwidth
///< usage, ip, port, ping)
CLIENT_COMMAND_requestSendXXXTextMsg = 11, ///< disable text messaging
CLIENT_COMMAND_filetransfers = 12, ///< disable file transfer
CLIENT_COMMAND_ENDMARKER
};
/* Access Control List*/
enum ACLType
{
ACL_NONE = 0,
ACL_WHITE_LIST = 1,
ACL_BLACK_LIST = 2
};
/* file transfer actions*/
enum FTAction
{
FT_INIT_SERVER = 0, ///< The virtual server is created. result->channelPath can be changed to create a different
///< directory than the default 'virtualserver_x' where x is the virtual server.
FT_INIT_CHANNEL = 1, ///< A channel is created. result->channelPath can be changed to create a different directory
///< then the default 'channel_x' where x is the channel id.
FT_UPLOAD = 2, ///< A file is being uploaded. All values in the result struct can be modified.
FT_DOWNLOAD = 3, ///< A file is being downloaded. All values in the result struct can be modified.
FT_DELETE = 4, ///< A file is being deleted. All values in the result struct can be modified.
FT_CREATEDIR = 5, ///< A directory is being created in a channel. All values in the result struct can be modified.
FT_RENAME = 6, ///< A file or folder is being renamed. The callback will be called twice! Once for the old and then
///< for the new name. All values in the result struct can be modified.
FT_FILELIST = 7, ///< A directory listing is requested. All values in the result struct can be modified.
FT_FILEINFO = 8 ///< Information of a file is requested. All values in the result struct can be modified.
};
/* file transfer status */
enum FileTransferState
{
FILETRANSFER_INITIALISING = 0, ///< File transfer is establishing connection.
FILETRANSFER_ACTIVE, ///< File transfer is in progress
FILETRANSFER_FINISHED, ///< File transfer has finished
};
/* file transfer types */
enum FileTransferType
{
FileListType_Directory = 0, ///< The file entry is a directory
FileListType_File, ///< The file entry is a regular file
};
/* some structs to handle variables in callbacks */
#define MAX_VARIABLES_EXPORT_COUNT 64
struct VariablesExportItem
{
unsigned char itemIsValid; ///< Whether or not there is any data in this item. Ignore this item if this is 0.
unsigned char proposedIsSet; ///< The value in proposed is set. If 0 ignore proposed
const char* current; ///< current value (stored in memory)
const char* proposed; ///< New value to change to (const, so no updates please)
};
struct VariablesExport
{
struct VariablesExportItem items[MAX_VARIABLES_EXPORT_COUNT];
};
struct ClientMiniExport
{
anyID ID; ///< id of the client
uint64 channel; ///< the channel the client is in
const char* ident; ///< client public identity
const char* nickname; ///< client display name
};
/**
* Structure used to describe a file transfer in the \ref ServerLibFunctions.onTransformFilePath callback.
* This describes the original values, and also contains hints for length limitations of the result parameter
* of the callback.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExport
{
uint64 channel; ///< The channel id of the file. 0 if action is \ref FT_INIT_SERVER
const char* filename; ///< utf8 encoded c string containing the original file name as intended by the client.
int action; ///< The action to be performed. One of the values from the \ref FTAction enum. Defines which values of
///< the result struct can be modified.
int transformedFileNameMaxSize; ///< The maximum length the file name can be rewritten to.
int channelPathMaxSize; ///< The maximum length the path can be rewritten to.
};
/**
* Structure to rewrite the file transfer file name and path in the \ref ServerLibFunctions.onTransformFilePath callback.
* The lengths are limited as described in the original parameter.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExportReturns
{
char* transformedFileName; ///< pointer to target file name. Fill the memory pointed to with an utf8 encoded c string
///< containing the new file name. Limited to original->transformedFileNameMaxSize bytes.
char* channelPath; ///< pointer to memory for new path. Fill the memory pointed to with an utf8 encoded c string
///< containing the new path. Limited to original->channelPathMaxSize bytes.
int logFileAction; ///< boolean (1/0). Whether to log this file transfer to the log. Action is not logged regardless
///< of this value if the servers \ref VIRTUALSERVER_LOG_FILETRANSFER property is 0.
};
struct FileTransferCallbackExport
{
anyID clientID; ///< the client who started the file transfer
anyID transferID; ///< local identifier of the transfer that has completed
anyID remoteTransferID; ///< remote identifier of the transfer that has completed
unsigned int status; ///< status of the transfer. One of the values from the \ref FileTransferState enum
const char* statusMessage; ///< utf8 encoded c string containing a human readable description of the status
uint64 remotefileSize; ///< size in bytes of the complete file to be transferred
uint64 bytes; ///< number of bytes transferred. Same as remotefileSize when the transfer completed entirely.
int isSender; ///< boolean. 1 if the server is sending the file. 0 if the server is receiving the file.
};
/*define for file transfer bandwith limits*/
#define BANDWIDTH_LIMIT_UNLIMITED 0xFFFFFFFFFFFFFFFFll
/*defines for speaker locations used by some sound callbacks*/
#ifndef SPEAKER_FRONT_LEFT
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#endif
#define SPEAKER_HEADPHONES_LEFT 0x10000000
#define SPEAKER_HEADPHONES_RIGHT 0x20000000
#define SPEAKER_MONO 0x40000000
#endif /*PUBLIC_DEFINITIONS_H*/
@@ -0,0 +1,217 @@
#ifndef PUBLIC_ERRORS_H
#define PUBLIC_ERRORS_H
//The idea here is: the values are 2 bytes wide, the first byte identifies the group, the second the count within that group
enum Ts3ErrorType {
//general
ERROR_ok = 0x0000, ///< Indicates success.
ERROR_undefined = 0x0001,
ERROR_not_implemented = 0x0002, ///< The attempted operation is not available in this context
ERROR_ok_no_update = 0x0003, ///< Indicates success, but no change occurred. Returned for example upon flushing (e.g. using \ref ts3client_flushChannelUpdates) when all indicated changes already matched the current state.
ERROR_dont_notify = 0x0004,
ERROR_lib_time_limit_reached = 0x0005,
ERROR_out_of_memory = 0x0006, ///< Not enough system memory to perform operation
ERROR_canceled = 0x0007,
ERROR_ok_no_error_event = 0x0008, ///< Indicates success, but no error event was generated. This is used because of the return code management and reduce packets.
//dunno
ERROR_command_not_found = 0x0100,
ERROR_unable_to_bind_network_port = 0x0101, ///< Unspecified failure to create a listening port
ERROR_no_network_port_available = 0x0102, ///< Failure to initialize a listening port for FileTransfer
ERROR_port_already_in_use = 0x0103, ///< Specified port is already in use by a different application
ERROR_command_line_parse_failed = 0x0104, ///< Command line arguments are invalid
ERROR_command_line_exit_version = 0x0105, ///< Command line specified version. The process should exit with code 0 after printing the version.
ERROR_command_line_exit_help = 0x0106, ///< Command line specified help. The process should exit with code 0 after priting the help.
//client
ERROR_client_invalid_id = 0x0200, ///< Client no longer connected
ERROR_client_nickname_inuse = 0x0201, ///< Client name is already in use. Client names must be unique
ERROR_client_protocol_limit_reached = 0x0203, ///< Too many clients on the server
ERROR_client_invalid_type = 0x0204, ///< Function called for normal clients that is only available for query clients or vice versa
ERROR_client_already_subscribed = 0x0205, ///< Attempting to subscribe to a channel already subscribed to
ERROR_client_not_logged_in = 0x0206,
ERROR_client_could_not_validate_identity = 0x0207, ///< Identity not valid or insufficient security level
ERROR_client_invalid_password = 0x0208,
ERROR_client_version_outdated = 0x020a, ///< Server requires newer client version as determined by the min_client_version properties
ERROR_client_is_flooding = 0x020c, ///< Triggered flood protection. Further information is supplied in the extra message if applicable.
ERROR_client_hacked = 0x020d,
ERROR_client_cannot_verify_now = 0x020e,
ERROR_client_login_not_permitted = 0x020f,
ERROR_client_not_subscribed = 0x0210, ///< Action is only available on subscribed channels
//channel
ERROR_channel_invalid_id = 0x0300, ///< Channel does not exist on the server (any longer)
ERROR_channel_protocol_limit_reached = 0x0301, ///< Too many channels on the server
ERROR_channel_already_in = 0x0302, ///< Attempting to move a client or channel to its current channel
ERROR_channel_name_inuse = 0x0303, ///< Channel name is already taken by another channel. Channel names must be unique
ERROR_channel_not_empty = 0x0304, ///< Attempting to delete a channel with clients or sub channels in it
ERROR_channel_can_not_delete_default = 0x0305, ///< Default channel cannot be deleted. Set a new default channel first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_default_require_permanent = 0x0306, ///< Attempt to set a non permanent channel as default channel. Set channel to permanent first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_invalid_flags = 0x0307, ///< Invalid combination of \ref ChannelProperties, trying to remove \ref CHANNEL_FLAG_DEFAULT or set a password on the default channel
ERROR_channel_parent_not_permanent = 0x0308, ///< Attempt to move a permanent channel into a non-permanent one, or set a channel to be permanent that is a sub channel of a non-permanent one
ERROR_channel_maxclients_reached = 0x0309, ///< Channel is full as determined by its \ref CHANNEL_MAXCLIENTS setting
ERROR_channel_maxfamily_reached = 0x030a, ///< Channel tree is full as determined by its \ref CHANNEL_MAXFAMILYCLIENTS setting
ERROR_channel_invalid_order = 0x030b, ///< Invalid value for the \ref CHANNEL_ORDER property. The specified channel must exist on the server and be on the same level.
ERROR_channel_no_filetransfer_supported = 0x030c, ///< Invalid \ref CHANNEL_FILEPATH set for the channel
ERROR_channel_invalid_password = 0x030d, ///< Channel has a password not matching the password supplied in the call
// used in public_rare_errors = 0x030e,
ERROR_channel_invalid_security_hash = 0x030f,
//server
ERROR_server_invalid_id = 0x0400, ///< Chosen virtual server does not exist or is offline
ERROR_server_running = 0x0401, ///< attempting to delete a server that is running. Stop the server before deleting it.
ERROR_server_is_shutting_down = 0x0402, ///< Client disconnected because the server is going offline
ERROR_server_maxclients_reached = 0x0403, ///< Given in the onConnectStatusChange event when the server has reached its maximum number of clients as defined by the \ref VIRTUALSERVER_MAXCLIENTS property
ERROR_server_invalid_password = 0x0404, ///< Specified server password is wrong. Provide the correct password in the \ref ts3client_startConnection / \ref ts3client_startConnectionWithChannelID call.
ERROR_server_is_virtual = 0x0407, ///< Server is in virtual status. The attempted action is not possible in this state. Start the virtual server first.
ERROR_server_is_not_running = 0x0409, ///< Attempting to stop a server that is not online.
ERROR_server_is_booting = 0x040a, // Not used
ERROR_server_status_invalid = 0x040b,
ERROR_server_version_outdated = 0x040d, ///< Attempt to connect to an outdated server version. The server needs to be updated.
ERROR_server_duplicate_running = 0x040e, ///< This server is already running within the instance. Each virtual server may only exist once.
//parameter
ERROR_parameter_quote = 0x0600, // Not used
ERROR_parameter_invalid_count = 0x0601, ///< Attempt to flush changes without previously calling set*VariableAs* since the last flush
ERROR_parameter_invalid = 0x0602, ///< At least one of the supplied parameters did not meet the criteria for that parameter
ERROR_parameter_not_found = 0x0603, ///< Failure to supply all the necessary parameters
ERROR_parameter_convert = 0x0604, ///< Invalid type supplied for a parameter, such as passing a string (ie. "five") that expects a number.
ERROR_parameter_invalid_size = 0x0605, ///< Value out of allowed range. Such as strings are too long/short or numeric values outside allowed range
ERROR_parameter_missing = 0x0606, ///< Neglecting to specify a required parameter
ERROR_parameter_checksum = 0x0607, ///< Attempting to deploy a modified snapshot
//unsorted, need further investigation
ERROR_vs_critical = 0x0700, ///< Failure to create default channel
ERROR_connection_lost = 0x0701, ///< Generic error with the connection.
ERROR_not_connected = 0x0702, ///< Attempting to call functions with a serverConnectionHandler that is not connected. You can use \ref ts3client_getConnectionStatus to check whether the connection handler is connected to a server
ERROR_no_cached_connection_info = 0x0703, ///< Attempting to query connection information (bandwidth usage, ping, etc) without requesting them first using \ref ts3client_requestConnectionInfo
ERROR_currently_not_possible = 0x0704, ///< Requested information is not currently available. You may have to call \ref ts3client_requestClientVariables or \ref ts3client_requestServerVariables
ERROR_failed_connection_initialisation = 0x0705, ///< No TeamSpeak server running on the specified IP address and port
ERROR_could_not_resolve_hostname = 0x0706, ///< Failure to resolve the specified hostname to an IP address
ERROR_invalid_server_connection_handler_id = 0x0707, ///< Attempting to perform actions on a non-existent server connection handler
ERROR_could_not_initialise_input_manager = 0x0708, // Not used
ERROR_clientlibrary_not_initialised = 0x0709, ///< Calling client library functions without successfully calling \ref ts3client_initClientLib before
ERROR_serverlibrary_not_initialised = 0x070a, ///< Calling server library functions without successfully calling \ref ts3server_initServerLib before
ERROR_whisper_too_many_targets = 0x070b, ///< Using a whisper list that contain more clients than the servers \ref VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE property
ERROR_whisper_no_targets = 0x070c, ///< The active whisper list is empty or no clients matched the whisper list (e.g. all channels in the list are empty)
ERROR_connection_ip_protocol_missing = 0x070d, ///< Invalid or unsupported protocol (e.g. attempting an IPv6 connection on an IPv4 only machine)
ERROR_handshake_failed = 0x070e,
ERROR_illegal_server_license = 0x070f,
//file transfer
ERROR_file_invalid_name = 0x0800, ///< Invalid UTF8 string or not a valid file
ERROR_file_invalid_permissions = 0x0801, ///< Permissions prevent opening the file
ERROR_file_already_exists = 0x0802, ///< Target path already exists as a directory
ERROR_file_not_found = 0x0803, ///< Attempt to access or move non existing file
ERROR_file_io_error = 0x0804, ///< Generic file input / output error
ERROR_file_invalid_transfer_id = 0x0805, ///< Attempt to get information about a file transfer after it has already been cleaned up. File transfer information is not available indefinitely after the transfer completed
ERROR_file_invalid_path = 0x0806, ///< specified path contains invalid characters or does not start with "/"
ERROR_file_no_files_available = 0x0807, // Not used
ERROR_file_overwrite_excludes_resume = 0x0808, ///< File overwrite and resume are mutually exclusive. Only one or neither can be 1.
ERROR_file_invalid_size = 0x0809, ///< Attempt to write more bytes than claimed file size.
ERROR_file_already_in_use = 0x080a, ///< File is currently not available, try again later.
ERROR_file_could_not_open_connection = 0x080b, ///< Generic failure in file transfer connection / other party did not conform to file transfer protocol
ERROR_file_no_space_left_on_device = 0x080c, ///< Operating system reports hard disk is full. May be caused by quota limitations.
ERROR_file_exceeds_file_system_maximum_size = 0x080d, ///< File is too large for the file system of the target device.
ERROR_file_transfer_connection_timeout = 0x080e, // Not used
ERROR_file_connection_lost = 0x080f, ///< File input / output timeout or connection failure
ERROR_file_exceeds_supplied_size = 0x0810, // Not used
ERROR_file_transfer_complete = 0x0811, ///< Indicates successful completion
ERROR_file_transfer_canceled = 0x0812, ///< Transfer was cancelled through @ref ts3client_haltTransfer
ERROR_file_transfer_interrupted = 0x0813, ///< Transfer failed because the server is shutting down, or network connection issues
ERROR_file_transfer_server_quota_exceeded = 0x0814, ///< Transfer terminated due to server bandwidth quota being exceeded. No client can transfer files.
ERROR_file_transfer_client_quota_exceeded = 0x0815, ///< Attempt to transfer more data than allowed by this clients' bandwidth quota. Other clients may continue to transfer files.
ERROR_file_transfer_reset = 0x0816, // Not used
ERROR_file_transfer_limit_reached = 0x0817, ///< Too many file transfers are in progress. Try again later
ERROR_file_invalid_storage_class = 0x0818, // TODO: Invalid storage class for HTTP FileTransfer (what is a storage class?)
ERROR_file_invalid_dimension = 0x0819, ///< Avatar image exceeds maximum width or height accepted by the server.
ERROR_file_transfer_channel_quota_exceeded = 0x081a, ///< Transfer failed because the channel quota was exceeded. Uploading to this channel is not possible, but other channels may be fine.
//sound
ERROR_sound_preprocessor_disabled = 0x0900, ///< Cannot set or query pre processor variables with preprocessing disabled
ERROR_sound_internal_preprocessor = 0x0901,
ERROR_sound_internal_encoder = 0x0902,
ERROR_sound_internal_playback = 0x0903,
ERROR_sound_no_capture_device_available = 0x0904, ///< No audio capture devices are available
ERROR_sound_no_playback_device_available = 0x0905, ///< No audio playback devices are available
ERROR_sound_could_not_open_capture_device = 0x0906, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_could_not_open_playback_device = 0x0907, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_handler_has_device = 0x0908, ///< Attempt to open a sound device on a connection handler which already has an open device. Close the already open device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_invalid_capture_device = 0x0909, ///< Attempt to use a device for capture that does not support capturing audio
ERROR_sound_invalid_playback_device = 0x090a, ///< Attempt to use a device for playback that does not support playback of audio
ERROR_sound_invalid_wave = 0x090b, ///< Attempt to use a non WAV file in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle
ERROR_sound_unsupported_wave = 0x090c, ///< Unsupported wave file used in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle.
ERROR_sound_open_wave = 0x090d, ///< Failure to open the specified sound file
ERROR_sound_internal_capture = 0x090e,
ERROR_sound_device_in_use = 0x090f, ///< Attempt to unregister a custom device that is being used. Close the device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_device_already_registerred = 0x0910, ///< Attempt to register a custom device with a device id that has already been used in a previous call. Device ids must be unique.
ERROR_sound_unknown_device = 0x0911, ///< Attempt to open, close, unregister or use a device which is not known. Custom devices must be registered before being used (see \ref ts3client_registerCustomDevice)
ERROR_sound_unsupported_frequency = 0x0912,
ERROR_sound_invalid_channel_count = 0x0913, ///< Invalid device audio channel count, must be > 0
ERROR_sound_read_wave = 0x0914, ///< Failure to read sound samples from an opened wave file. Is this a valid wave file?
ERROR_sound_need_more_data = 0x0915, // for internal purposes only
ERROR_sound_device_busy = 0x0916, // for internal purposes only
ERROR_sound_no_data = 0x0917, ///< Indicates there is currently no data for playback, e.g. nobody is speaking right now.
ERROR_sound_channel_mask_mismatch = 0x0918, ///< Opening a device with an unsupported channel count
//permissions
ERROR_permissions_client_insufficient = 0x0a08, ///< Not enough permissions to perform the requested activity
ERROR_permissions = 0x0a0c, ///< Permissions to use sound device not granted by operating system, e.g. Windows denied microphone access.
//accounting
ERROR_accounting_virtualserver_limit_reached = 0x0b00, ///< Attempt to use more virtual servers than allowed by the license
ERROR_accounting_slot_limit_reached = 0x0b01, ///< Attempt to set more slots than allowed by the license
ERROR_accounting_license_file_not_found = 0x0b02, // Not used
ERROR_accounting_license_date_not_ok = 0x0b03, ///< License expired or not valid yet
ERROR_accounting_unable_to_connect_to_server = 0x0b04, ///< Failure to communicate with accounting backend
ERROR_accounting_unknown_error = 0x0b05, ///< Failure to write update license file
ERROR_accounting_server_error = 0x0b06, // Not used
ERROR_accounting_instance_limit_reached = 0x0b07, ///< More than one process of the server is running
ERROR_accounting_instance_check_error = 0x0b08, ///< Shared memory access failure.
ERROR_accounting_license_file_invalid = 0x0b09, ///< License is not a TeamSpeak license
ERROR_accounting_running_elsewhere = 0x0b0a, ///< A copy of this server is already running in another instance. Each server may only exist once.
ERROR_accounting_instance_duplicated = 0x0b0b, ///< A copy of this server is running already in this process. Each server may only exist once.
ERROR_accounting_already_started = 0x0b0c, ///< Attempt to start a server that is already running
ERROR_accounting_not_started = 0x0b0d,
ERROR_accounting_to_many_starts = 0x0b0e, ///< Starting instance / virtual servers too often in too short a time period
//provisioning server
/// @cond HAS_PROVISIONING
ERROR_provisioning_invalid_password = 0x1100,
ERROR_provisioning_invalid_request = 0x1101,
ERROR_provisioning_no_slots_available = 0x1102,
ERROR_provisioning_pool_missing = 0x1103,
ERROR_provisioning_pool_unknown = 0x1104,
ERROR_provisioning_unknown_ip_location = 0x1105,
ERROR_provisioning_internal_tries_exceeded = 0x1106,
ERROR_provisioning_too_many_slots_requested = 0x1107,
ERROR_provisioning_too_many_reserved = 0x1108,
ERROR_provisioning_could_not_connect = 0x1109,
ERROR_provisioning_auth_server_not_connected = 0x1110,
ERROR_provisioning_auth_data_too_large = 0x1111,
ERROR_provisioning_already_initialized = 0x1112,
ERROR_provisioning_not_initialized = 0x1113,
ERROR_provisioning_connecting = 0x1114,
ERROR_provisioning_already_connected = 0x1115,
ERROR_provisioning_not_connected = 0x1116,
ERROR_provisioning_io_error = 0x1117,
ERROR_provisioning_invalid_timeout = 0x1118,
ERROR_provisioning_ts3server_not_found = 0x1119,
ERROR_provisioning_no_permission = 0x111A,
/// @endcond
// 0x12 - 0x15 are reserved in rare
// screen share
ERROR_already_registered = 0x1600,
ERROR_stream_session_limit_reached = 0x1601,
ERROR_stream_session_not_found = 0x1602,
ERROR_stream_unknown = 0x1603,
ERROR_stream_not_participating = 0x1604,
ERROR_not_streamer = 0x1605,
ERROR_already_joined = 0x1606,
ERROR_join_request_not_found = 0x1607,
ERROR_sfu_failed_to_start = 0x1608,
};
#endif
@@ -0,0 +1,236 @@
#ifndef TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#define TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Version definitions.
#define TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1 1
// Protocol used for communication between the session subscriber and the session (a single stream).
// Commands are sent bidirectionally or unidirectionally between the parties.
// e.g. SESSION => SUBSCRIBER: ON_FRAME, ON_PAUSED_CHANGED
// e.g. SUBSCRIBER => SESSION: ON_FRAME_ACK, ON_RESIZE
// Command type enum with a lowercase type name.
typedef enum
{
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME = 0,
TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE,
TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED,
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK,
TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP,
TS_SESSION_SUBSCRIBER_CMD_REMOVE_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED,
} ts_session_subscriber_command_type_t;
// Pixel format enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_I420 = 0,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_NV12,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ABGR,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ARGB,
} ts_session_subscriber_pixel_format_t;
// Buffer location enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_CPU = 0,
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_GPU
} ts_session_subscriber_buffer_location_t;
// Buffer type enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_SINGLE = 0,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_MAIN,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_SUB
} ts_session_subscriber_buffer_type_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(push, 4)
#endif
// Main buffer header for shared CPU Memory Front/Back Buffers.
// The Main Buffer contains metadata about the current front/back buffer and the versioning for both the main and sub buffer.
// The information from the main buffer can be used to always read the front buffer.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t front_buffer_index; // index of the front buffer. (0: main buffer, 1: sub buffer)
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_main_buffer_header_t;
// Sub buffer header.
typedef struct
{
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
} ts_session_subscriber_sub_buffer_header_t;
// Single frame buffer header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_single_frame_buffer_header_t;
// Command header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // Total message length (header + payload).
ts_session_subscriber_command_type_t type;
uint64_t target_session_id; // always set to the target session id this command is for or is originating from.
uint64_t target_subscriber_id; // 0 if broadcast.
} ts_session_subscriber_command_header_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME.
// The frame data is not included in the message, but is attached seperately or was sent beforehand. The buffer is identified by it's id.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_id; // buffer id, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_frame_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t frame_id;
} ts_session_subscriber_on_frame_ack_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE.
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t width;
uint32_t height;
} ts_session_subscriber_on_resize_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t paused; // 0 or 1.
} ts_session_subscriber_on_paused_changed_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE.
// Contains a single frame buffer. The header is of format |ts_session_subscriber_single_frame_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
ts_session_subscriber_buffer_type_t buffer_type;
} ts_session_subscriber_on_buffer_single_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK.
// Contains a main buffer and a sub buffer. The main buffer header
// contains metadata about the current front/back buffer and
// is of type |ts_session_subscriber_main_buffer_header_t|.
// The sub buffer's header is of type |ts_session_subscriber_sub_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t main_buffer_ptr; // main buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t main_buffer_length;
uint64_t sub_buffer_ptr; // sub buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t sub_buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
} ts_session_subscriber_on_buffer_front_back_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER.
// SUBSCRIBER => SESSION.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_resp_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_release_buffer_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr;
int bits_per_sample;
int sample_rate;
uint32_t number_of_channels;
uint32_t number_of_frames;
int64_t absolute_capture_timestamp_ms;
float volume;
} ts_session_subscriber_on_audio_frames_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t audio_enabled;
} ts_session_subscriber_on_audio_enabled_changed_payload_t;
// Overall Command structure.
typedef struct
{
ts_session_subscriber_command_header_t header;
union
{
ts_session_subscriber_on_frame_payload_t frame;
ts_session_subscriber_on_resize_payload_t resize;
ts_session_subscriber_on_paused_changed_payload_t paused;
ts_session_subscriber_on_frame_ack_payload_t frame_ack;
ts_session_subscriber_on_buffer_single_payload_t buffer_single;
ts_session_subscriber_on_buffer_front_back_payload_t buffer_front_back;
ts_session_subscriber_on_release_buffer_payload_t release_buffer;
ts_session_subscriber_add_subscriber_payload_t add_subscriber;
ts_session_subscriber_add_subscriber_resp_payload_t add_subscriber_resp;
ts_session_subscriber_on_audio_frames_payload_t audio_frames;
ts_session_subscriber_on_audio_enabled_changed_payload_t audio_enabled_changed;
} payload;
} ts_session_subscriber_command_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif // TS_SESSION_SUBSCRIBER_PROTOCOL_H_
@@ -0,0 +1,29 @@
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was team_clientConfig.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()
####################################################################################
include("${CMAKE_CURRENT_LIST_DIR}/team_clientTargets.cmake")
check_required_components(team_client)
@@ -0,0 +1,19 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "teamspeak::client" for configuration "Release"
set_property(TARGET teamspeak::client APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(teamspeak::client PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.so"
IMPORTED_SONAME_RELEASE "libteamspeak_sdk_client.so"
)
list(APPEND _cmake_import_check_targets teamspeak::client )
list(APPEND _cmake_import_check_files_for_teamspeak::client "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.so" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
@@ -0,0 +1,121 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.3")
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.3...4.0)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS teamspeak::client)
list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
if(TARGET "${_cmake_expected_target}")
list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
else()
list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
unset(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target teamspeak::client
add_library(teamspeak::client SHARED IMPORTED)
set_target_properties(teamspeak::client PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
if(NOT CMAKE_VERSION VERSION_LESS "3.23.0")
target_sources(teamspeak::client
INTERFACE
FILE_SET "public_headers"
TYPE "HEADERS"
BASE_DIRS "${_IMPORT_PREFIX}/include"
FILES "${_IMPORT_PREFIX}/include/teamspeak/clientlib.h" "${_IMPORT_PREFIX}/include/teamspeak/clientlib_sdk.h" "${_IMPORT_PREFIX}/include/teamspeak/video/session_subscriber_protocol.h"
)
else()
set_property(TARGET teamspeak::client
APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
"${_IMPORT_PREFIX}/include"
)
endif()
# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/team_clientTargets-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
if(CMAKE_VERSION VERSION_LESS "3.28"
OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target}
OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}")
foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
if(NOT EXISTS "${_cmake_file}")
message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
\"${_cmake_file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
endif()
unset(_cmake_file)
unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
@@ -0,0 +1,23 @@
#ifndef TEAMLOG_LOGTYPES_H
#define TEAMLOG_LOGTYPES_H
enum LogTypes {
LogType_NONE = 0x0000, ///< Logging is disabled
LogType_FILE = 0x0001, ///< Log to regular log file
LogType_CONSOLE = 0x0002, ///< Log to standard output / error
LogType_USERLOGGING = 0x0004, ///< User defined logging. Will call the \ref ServerLibFunctions.onUserLoggingMessageEvent callback for every message to be logged
LogType_NO_NETLOGGING = 0x0008, ///< Not used
LogType_DATABASE = 0x0010, ///< Log to database (deprecated, server only, no effect in SDK)
LogType_SYSLOG = 0x0020, ///< Log to syslog (only available on Linux)
};
enum LogLevel {
LogLevel_CRITICAL = 0, ///< these messages stop the program
LogLevel_ERROR, ///< everything that is really bad, but not so bad we need to shut down
LogLevel_WARNING, ///< everything that *might* be bad
LogLevel_DEBUG, ///< output that might help find a problem
LogLevel_INFO, ///< informational output, like "starting database version x.y.z"
LogLevel_DEVEL ///< developer only output (will not be displayed in release mode)
};
#endif //TEAMLOG_LOGTYPES_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,58 @@
#ifndef CLIENTLIB_SDK_H
#define CLIENTLIB_SDK_H
// system
#include <stdlib.h>
// own
#include "teamspeak/public_definitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets the client to which to transmit voice. Stops standard channel voice transmission.
*
* The client will still receive voice from their current channel, however their voice will not be transmitted to their
* current channel anymore. If this call is successful (check onServerErrorEvent) then voice of the specified client
* will be transmitted to all specified channels and all the specified clients. Pass 0 to both target parameter arrays
* to restore default behavior of transmitting voice to current channel. You will receive an onServerErrorEvent with the
* passed returnCode indicating whether or not the operation was successful.
*
* @param server_connection_handler_id the connection handler on which to set the whisper list
* @param client_id the client to set the whisper list for. Set to 0 or your own client ID to set your own whisper list.
* @param channel_ids an array of channel ids to transmit voice to.
* @param channel_ids_size number of elements in aforementioned array.
* @param client_ids a zero terminated array of client ids to transmit voice to.
* @param client_ids_size number of elements in aforementioned array.
* @param impersonate if the target client is a webrtc client, the voice packets will look like as if they have been
* send by the invoking client id
* @param return_code a c string to identify this request in callbacks. Pass an empty string if unused.
* @return An error code from the @ref Ts3ErrorType enum indicating either success or the failure reason
*/
EXPORTDLL unsigned int ts_client_request_client_set_whisper_list(uint64 server_connection_handler_id, anyID client_id,
const uint64* channel_ids,
int channel_ids_size,
const anyID* client_ids,
int client_ids_size, int impersonate,
const char* return_code);
/**
* @brief Send a binary-serialized ClientCommandRequest protobuf to the client library.
*
* The response will be delivered asynchronously via the onProtoResponse callback
* as a serialized ClientCommandResponse protobuf.
*
* @param data Pointer to serialized ClientCommandRequest protobuf bytes
* @param size Size of the serialized data in bytes
* @param return_code Caller-provided string to correlate the response in onProtoResponse. May be NULL.
* @return An error code: ERROR_ok on successful dispatch, ERROR_parameter_invalid on parse failure
*/
EXPORTDLL unsigned int ts3client_postProtoCommand(const void* data, size_t size, const char* return_code);
#ifdef __cplusplus
}
#endif
#endif // CLIENTLIB_SDK_H
@@ -0,0 +1,635 @@
#ifndef PUBLIC_DEFINITIONS_H
#define PUBLIC_DEFINITIONS_H
#include "teamlog/logtypes.h"
#define TS3_MAX_SIZE_CHANNEL_NAME 40 // channel name maximum length in characters
#define TS3_MAX_SIZE_VIRTUALSERVER_NAME 64 // virtual server name maximum length in characters
#define TS3_MAX_SIZE_CLIENT_NICKNAME 64 // client display name length limit in characters
#define TS3_MIN_SIZE_CLIENT_NICKNAME 3 // client display name minimum length in characters
#define TS3_MAX_SIZE_REASON_MESSAGE 80 // length limit in characters for kick, move, etc reasons
#define TS3_MAX_SIZE_TEXTMESSAGE 8192 // text message length limit, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_TOPIC 255 // channel topic lengt limith, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_DESCRIPTION 8192 // channel description length limit, measured in bytes (utf8 encoded)
// server welcome message length limit measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_VIRTUALSERVER_WELCOMEMESSAGE 1024
#define TS3_SIZE_MYTSID 44
// minimum amount of seconds before a clientID that was in use can be assigned to a new client
#define TS3_MIN_SECONDS_CLIENTID_REUSE 300
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32)
typedef unsigned __int16 anyID;
typedef unsigned __int64 uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __declspec(dllexport)
#else
#define EXPORTDLL
#endif
#endif
#else
#include <stdint.h>
typedef uint16_t anyID;
typedef uint64_t uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __attribute__((visibility("default")))
#else
#define EXPORTDLL
#endif
#endif
#endif
enum Visibility
{
ENTER_VISIBILITY = 0, ///< Client joined from an unsubscribed channel, or joined the server.
RETAIN_VISIBILITY, ///< Client switched from one subscribed channel to a different subscribed channel.
LEAVE_VISIBILITY ///< Client switches to an unsubscribed channel, or disconnected from server.
};
enum ConnectStatus
{
STATUS_DISCONNECTED = 0, ///< There is no activity to the server, this is the default value
STATUS_CONNECTING, ///< We are trying to connect, we haven't got a client id yet, we haven't been accepted by the server
STATUS_CONNECTED, ///< The server has accepted us, we can talk and hear and we have a client id, but we don't
///< have the channels and clients yet, we can get server infos (welcome msg etc.)
STATUS_CONNECTION_ESTABLISHING, ///< we are connected and we are visible
STATUS_CONNECTION_ESTABLISHED, ///< we are connected and we have the client and channels available
};
enum LocalTestMode
{
TEST_MODE_OFF = 0,
TEST_MODE_VOICE_LOCAL_ONLY,
TEST_MODE_VOICE_LOCAL_AND_REMOTE,
TEST_MODE_TALK_STATUS_CHANGES_ONLY
};
enum TalkStatus
{
STATUS_NOT_TALKING = 0, ///< client is not talking
STATUS_TALKING = 1, ///< client is talking
STATUS_TALKING_WHILE_DISABLED = 2, ///< client is talking while the microphone is muted (only valid for own client)
};
enum CodecType
{
CODEC_SPEEX_NARROWBAND = 0, ///< (deprecated) mono, 16bit, 8kHz, bitrate dependent on the quality setting
CODEC_SPEEX_WIDEBAND, ///< (deprecated) mono, 16bit, 16kHz, bitrate dependent on the quality setting
CODEC_SPEEX_ULTRAWIDEBAND, ///< (deprecated) mono, 16bit, 32kHz, bitrate dependent on the quality setting
CODEC_CELT_MONO, ///< (deprecated) mono, 16bit, 48kHz, bitrate dependent on the quality setting
CODEC_OPUS_VOICE, ///< mono, 16bit, 48khz, bitrate dependent on the quality setting, optimized for voice
CODEC_OPUS_MUSIC, ///< stereo, 16bit, 48khz, bitrate dependent on the quality setting, optimized for music
};
enum CodecEncryptionMode
{
CODEC_ENCRYPTION_PER_CHANNEL = 0, ///< voice data encryption decided per channel
CODEC_ENCRYPTION_FORCED_OFF, ///< voice data encryption disabled
CODEC_ENCRYPTION_FORCED_ON, ///< voice data encryption enabled
};
enum TextMessageTargetMode
{
TextMessageTarget_CLIENT = 1, ///< Message is a private message to another client
TextMessageTarget_CHANNEL, ///< Message is sent to a channel, received by all clients in that channel at the time
TextMessageTarget_SERVER, ///< Message is sent to every client on the server
TextMessageTarget_MAX
};
enum MuteInputStatus
{
MUTEINPUT_NONE = 0, ///< Microphone is not muted, audio is sent to the server
MUTEINPUT_MUTED, ///< Microphone is muted, no audio is transmitted to the server
};
enum MuteOutputStatus
{
MUTEOUTPUT_NONE = 0, ///< Speaker is active, server is sending us audio
MUTEOUTPUT_MUTED, ///< Speaker is muted, server is not sending audio to us
};
enum HardwareInputStatus
{
HARDWAREINPUT_DISABLED = 0, ///< no capture device opened
HARDWAREINPUT_ENABLED, ///< capture device open
};
enum HardwareOutputStatus
{
HARDWAREOUTPUT_DISABLED = 0, ///< no playback device opened
HARDWAREOUTPUT_ENABLED, ///< playback device open
};
enum InputDeactivationStatus
{
INPUT_ACTIVE = 0, ///< Audio is captured from the capture device.
INPUT_DEACTIVATED = 1, ///< No audio is captured from the capture device.
};
enum ReasonIdentifier
{
REASON_NONE = 0, ///< no reason data
REASON_MOVED = 1, ///< client was moved
REASON_SUBSCRIPTION = 2, // no reason data
REASON_LOST_CONNECTION = 3, // reasonmsg=reason
REASON_KICK_CHANNEL = 4, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER = 5, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER_BAN = 6, //{SectionInvoker} reasonmsg=reason bantime=time //{SectionInvoker} is only added server->client
REASON_SERVERSTOP = 7, // reasonmsg=reason
REASON_CLIENTDISCONNECT = 8, // reasonmsg=reason
REASON_CHANNELUPDATE = 9, // no reason data
REASON_CHANNELEDIT = 10, //{SectionInvoker}
REASON_CLIENTDISCONNECT_SERVER_SHUTDOWN = 11, // reasonmsg=reason
};
enum Protocol_Encryption_Cipher
{
AES_128 = 0b00000000,
AES_256 = 0b00000001,
PROTOCOL_ENCRYPTION_CIPHER_END_MARKER,
RESERVED = 0b00010000, // reserved until puzzle v2 is fully released, then can be reused
PUZZLE_2 = 0b00100000,
};
enum ChannelProperties
{
CHANNEL_NAME = 0, ///< String. Read/Write. Name of the channel. Always available.
CHANNEL_TOPIC, ///< String. Read/Write. Short single line text describing what the channel is about. Always available.
CHANNEL_DESCRIPTION, ///< String. Read/Write. Arbitrary text (up to 8k bytes) with information about the channel.
///< Must be requested (\ref ts3client_requestChannelDescription)
CHANNEL_PASSWORD, ///< String. Read/Write. Password of the channel. Read access is limited to the server. Clients
///< will only ever see the last password they attempted to use when joining the channel. Always available.
CHANNEL_CODEC, ///< Integer. Read/Write. The codec this channel is using. One of the values from the \ref CodecType
///< enum. Always available.
CHANNEL_CODEC_QUALITY, ///< Integer. Read/Write. The quality setting of the channel. Valid values are 0 to 10 inclusive.
///< Higher value means better voice quality but also more bandwidth usage. Always available.
CHANNEL_MAXCLIENTS, ///< Integer. Read/Write. The number of clients that can be in the channel simultaneously.
///< Always available.
CHANNEL_MAXFAMILYCLIENTS, ///< Integer. Read/Write. The total number of clients that can be in this channel and all
///< sub channels of this channel. Always available.
CHANNEL_ORDER, ///< UInt64. Read/Write. The ID of the channel below which this channel should be displayed. If 0
///< the channel is sorted at the top of the current level. Always available.
CHANNEL_FLAG_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when empty.
///< Permanent channels are stored to the database and available after server restart. SDK
///< users will need to take care of restoring channel at server start on their own.
///< Mutually exclusive with \ref CHANNEL_FLAG_SEMI_PERMANENT. Always available.
CHANNEL_FLAG_SEMI_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when
///< empty. Semi permanent channels are not stored to disk and gone after server
///< restart but remain while empty. Mutually exclusive with \ref
///< CHANNEL_FLAG_PERMANENT. Always available.
CHANNEL_FLAG_DEFAULT, ///< Integer. Read/Write. Boolean (1/0). The default channel is the channel that all clients
///< are located in when they join the server, unless the client explicitly specified a
///< different channel when connecting and is allowed to join their preferred channel. Only
///< one channel on the server can have this flag set. The default channel must have \ref
///< CHANNEL_FLAG_PERMANENT set. Always available.
CHANNEL_FLAG_PASSWORD, ///< Integer. Read/Write. Boolean (1/0) indicating whether this channel is password protected.
///< When removing or setting \ref CHANNEL_PASSWORD you also need to adjust this flag.
CHANNEL_CODEC_LATENCY_FACTOR, ///< (deprecated) Integer. Read/Write. Allows to increase packet size, reducing
///< bandwith at the cost of higher latency of voice transmission. Valid values are
///< 1-10 inclusive. 1 is the default and offers the lowest latency. Always available.
CHANNEL_CODEC_IS_UNENCRYPTED, ///< Integer. Read/Write. Boolean (1/0). If 0 voice data is encrypted, if 1 the voice
///< data is not encrypted. Only used if the server \ref
///< VIRTUALSERVER_CODEC_ENCRYPTION_MODE is set to \ref CODEC_ENCRYPTION_PER_CHANNEL.
///< Always available.
CHANNEL_SECURITY_SALT, ///< String. Read/Write. SDK Only, not used by TeamSpeak. This channels security hash. When
///< a client joins their \ref CLIENT_SECURITY_HASH is compared to this value, to allow or
///< deny the client access to the channel. Used to enforce clients joining the server with
///< specific identity and \ref CLIENT_META_DATA. See SDK Documentation about this feature
///< for further details. Always available.
CHANNEL_DELETE_DELAY, ///< UInt64. Read/Write. Number of seconds deletion of temporary channels is delayed after
///< the last client leaves the channel. Channel is only deleted if empty when the delete
///< delay expired. Always available.
CHANNEL_UNIQUE_IDENTIFIER, ///< String. Read only. An identifier that uniquely identifies a channel. Available in
///< Server >= 3.10.0
CHANNEL_ENDMARKER,
};
enum ClientProperties
{
CLIENT_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Public Identity, can be used to identify a client
///< installation. Remains identical as long as the client keeps using the same
///< identity. Available for visible clients.
CLIENT_NICKNAME, ///< String. Read/Write. Display name of the client. Available for visible clients.
CLIENT_VERSION, ///< String. Read only. Version String of the client used. For clients other than ourself this
///< needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_PLATFORM, ///< String. Read only. Operating system used by the client. For other clients other than ourself
///< this needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_FLAG_TALKING, ///< Integer. Read only. Whether the client is talking. Available on clients that are either
///< whispering to us, or in our channel.
CLIENT_INPUT_MUTED, ///< Integer. Read/Write. Microphone mute status. Available for visible clients. One of the
///< values from the \ref MuteInputStatus enum.
CLIENT_OUTPUT_MUTED, ///< Integer. Read/Write. Speaker mute status. Speaker mute implies microphone mute. Available
///< for visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_OUTPUTONLY_MUTED, ///< Integer. Read/Write. Speaker mute status. Microphone may be active. Available for
///< visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_INPUT_HARDWARE, ///< Integer. Read only. Indicates whether a capture device is open. Available for visible
///< clients. One of the values from the \ref HardwareInputStatus enum.
CLIENT_OUTPUT_HARDWARE, ///< Integer. Read only. Indicates whether a playback device is open. Available for visible
///< clients. One of the values from the \ref HardwareOutputStatus enum.
CLIENT_INPUT_DEACTIVATED, ///< Integer. Read/Write. Not available server side. Local microphone mute status.
///< Available only for own client. Used to implement Push To Talk. One of the values from
///< the \ref InputDeactivationStatus enum.
CLIENT_IDLE_TIME, ///< UInt64. Read only. Seconds since last activity. Available only for own client.
CLIENT_DEFAULT_CHANNEL, ///< String. Read only. User specified channel they joined when connecting to the server.
///< Available only for own client.
CLIENT_DEFAULT_CHANNEL_PASSWORD, ///< String. Read only. User specified channel password for the channel they
///< attempted to join when connecting to the server. Available only for own
///< client.
CLIENT_SERVER_PASSWORD, ///< String. Read only. User specified server password. Available only for own client.
CLIENT_META_DATA, ///< String. Read/Write. Can be used to store up to 4096 bytes of information on clients. Not
///< used by TeamSpeak. Available for visible clients.
CLIENT_IS_MUTED, ///< Integer. Read only. Not available server side. Indicates whether we have muted the client
///< using \ref ts3client_requestMuteClients. Available for visible clients other than ourselves.
CLIENT_IS_RECORDING, ///< Integer. Read only. Indicates whether the client is recording incoming audio. Available
///< for visible clients.
CLIENT_VOLUME_MODIFICATOR, ///< Integer. Read only. Volume adjustment for this client as set by \ref
///< ts3client_setClientVolumeModifier. Available for visible clients.
CLIENT_VERSION_SIGN, ///< String. Read only. TeamSpeak internal signature.
CLIENT_SECURITY_HASH, ///< String. Read/Write. This clients security hash. Not used by TeamSpeak, SDK only. Hash is
///< provided by an outside source. A channel will use the security salt + other client data
///< to calculate a hash, which must be the same as the one provided here. See SDK
///< documentation about Client / Channel Security Hashes for more details.
CLIENT_ENCRYPTION_CIPHERS, ///< String. Read only. SDK only. List of available ciphers this client can use.
CLIENT_IS_STREAMING, ///< bool. Read only, Is currently streaming.
CLIENT_ENDMARKER,
};
enum VirtualServerProperties
{
VIRTUALSERVER_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Unique identifier for a virtual server, does not
///< change on server restart. Available if \ref ts3client_getConnectionStatus
///< is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_NAME, ///< String. Read/Write. The virtual server display name. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_WELCOMEMESSAGE, ///< String. Read/Write. The welcome message displayed to clients on connect.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED. Not
///< updated automatically when changed, updates need to be requested (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_PLATFORM, ///< String. Read only. The operating system the server is running on. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_VERSION, ///< String. Read only. The server software version string. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_MAXCLIENTS, ///< UInt64. Read/Write. The maximum number of clients that can be connected
///< simultaneously. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_PASSWORD, ///< String. Read/Write. The server password. Read access is limited to the server. Clients
///< will only get the password they supplied when connecting. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_CLIENTS_ONLINE, ///< UInt64. Read only. The current number of clients connected to the server,
///< including query connections. Only available on request (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_CHANNELS_ONLINE, ///< UInt64. Read only. The current number of channels on the server. Only
///< available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CREATED, ///< Integer. Read only. The time this virtual server was created as unix timestamp.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_UPTIME, ///< UInt64. Read only. Number of seconds that have passed since the virtual server was
///< started. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CODEC_ENCRYPTION_MODE, ///< Integer. Read/Write. Boolean (1/0) that specifies if voice data is encrypted
///< during transfer. One of the values from the \ref CodecEncryptionMode enum.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_ENCRYPTION_CIPHERS, ///< String. Read/Write. Comma separated list of available ciphers to encrypt the
///< connection. The server will use the first cipher in the list that is also
///< listed in the \ref CLIENT_ENCRYPTION_CIPHERS of the connecting client.
///< Clients will fail to connect if no match is found. Always available.
VIRTUALSERVER_ADDRESS, ///< Any resolvable address for the specific virtual server
VIRTUALSERVER_VERSION_SIGN, ///< String. Read only. Signature of Platform and Version.
VIRTUALSERVER_ENDMARKER,
VIRTUALSERVER_FILEBASE = 24, ///< String. Read only. The path to the base directory used to store files
///< transferred using file transfer. Available only on the server. Is set by \ref
///< ts3server_enableFileManager
VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH = 29, ///< UInt64. Read/Write. Maximum traffic in bytes the server can
///< use for file transfer downloads. Only available on request
///< (\ref ts3client_requestServerVariables).
VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH = 30, ///< UInt64. Read/Write. Maximum traffic in bytes the server can use
///< for file transfer uploads. Only available on request (=>
///< requestServerVariables)
VIRTUALSERVER_LOG_FILETRANSFER = 64 ///< Integer. Read/Write. Boolean (1/0) indicating whether to include file
///< transfer activities (uploading or downloading of files) in the server log.
///< Always available.
};
/**
* Various connection properties.
* These are all read only, and except for your own client must be requested using \ref ts3client_requestConnectionInfo
*/
enum ConnectionProperties
{
CONNECTION_PING = 0, ///< UInt64. Round trip latency for the connection based on the last 5 seconds. On the server
///< this is the average across all connected clients for the last 5 seconds.
CONNECTION_PING_DEVIATION, ///< Double. Standard deviation for the round trip latency in \ref CONNECTION_PING
CONNECTION_CONNECTED_TIME, ///< UInt64. Seconds the client has been connected.
CONNECTION_IDLE_TIME, ///< UInt64. Time in seconds since the last activity (voice transmission, switching channels,
///< changing mic / speaker mute status) of the client.
CONNECTION_CLIENT_IP, ///< String. IP of this client (as seen from the server side)
CONNECTION_CLIENT_PORT, ///< UInt64. Client side port of this client (as seen from the server side)
CONNECTION_SERVER_IP, ///< String. The IP or hostname used to connect to the server. Only available on yourself.
CONNECTION_SERVER_PORT, ///< UInt64. The server port connected to. Only available on yourself.
CONNECTION_PACKETS_SENT_SPEECH, ///< UInt64. The number of voice packets transmitted by the client.
CONNECTION_PACKETS_SENT_KEEPALIVE, ///< UInt64. The number of keep alive packets transmitted by the client.
CONNECTION_PACKETS_SENT_CONTROL, ///< UInt64. The number of command & control packets transmitted by the client.
CONNECTION_PACKETS_SENT_TOTAL, ///< UInt64. Total number of packets transmitted by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_SENT_SPEECH, \ref CONNECTION_PACKETS_SENT_KEEPALIVE and
///< \ref CONNECTION_PACKETS_SENT_CONTROL
CONNECTION_BYTES_SENT_SPEECH, ///< UInt64. Outgoing traffic used for voice data by the client.
CONNECTION_BYTES_SENT_KEEPALIVE, ///< UInt64. Outgoing traffic used for keeping the connection alive by the client.
CONNECTION_BYTES_SENT_CONTROL, ///< UInt64. Outgoing traffic used for command & control data by the client.
CONNECTION_BYTES_SENT_TOTAL, ///< UInt64. Total outgoing traffic to the server by this client. Equal to the sum of
///< \ref CONNECTION_BYTES_SENT_SPEECH, \ref CONNECTION_BYTES_SENT_KEEPALIVE and \ref
///< CONNECTION_BYTES_SENT_CONTROL
CONNECTION_PACKETS_RECEIVED_SPEECH, ///< UInt64. Number of voice packets received by the client.
CONNECTION_PACKETS_RECEIVED_KEEPALIVE, ///< UInt64. Number of keep alive packets received by the client.
CONNECTION_PACKETS_RECEIVED_CONTROL, ///< UInt64. Number of command & control packets received by the client.
CONNECTION_PACKETS_RECEIVED_TOTAL, ///< UInt64. Total number of packets received by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_RECEIVED_SPEECH, \ref
///< CONNECTION_PACKETS_RECEIVED_KEEPALIVE and \ref
///< CONNECTION_PACKETS_RECEIVED_CONTROL
CONNECTION_BYTES_RECEIVED_SPEECH, ///< UInt64. Incoming traffic used by the client for voice data.
CONNECTION_BYTES_RECEIVED_KEEPALIVE, ///< UInt64. Incoming traffic used by the client to keep the connection alive.
CONNECTION_BYTES_RECEIVED_CONTROL, ///< UInt64. Incoming traffic used by the client for command & control data.
CONNECTION_BYTES_RECEIVED_TOTAL, ///< UInt64. Total incoming traffic used by the client. Equal to the sum of \ref
///< CONNECTION_BYTES_RECEIVED_SPEECH, \ref CONNECTION_BYTES_RECEIVED_KEEPALIVE and
///< \ref CONNECTION_BYTES_RECEIVED_CONTROL
CONNECTION_PACKETLOSS_SPEECH, ///< Double. Percentage points of voice packets for the client that did not arrive at
///< the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_KEEPALIVE, ///< Double. Percentage points of keep alive packets for the client that did not
///< arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_CONTROL, ///< Double. Percentage points of command & control packets for the client that did
///< not arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_TOTAL, ///< Double. Cumulative chance in percentage points with which a packet round trip
///< failed because a packet was lost
CONNECTION_SERVER2CLIENT_PACKETLOSS_SPEECH, ///< Double. Probability with which a voice packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< server was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the server was not
///< received by the client.
CONNECTION_CLIENT2SERVER_PACKETLOSS_SPEECH, ///< Double. Probability with which a speech packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< client was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the client was not
///< received by the server.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes sent for speech data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes sent for keepalive data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes sent for control data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes sent in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second sent for speech data, averaged over the
///< last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second sent for keepalive data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second sent for control data, averaged over
///< the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second sent, averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes received for speech data in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes received for keepalive data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes received for control data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes received in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second received for speech data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second received for keepalive data,
///< averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second received for control data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second received, averaged over the last minute.
CONNECTION_DUMMY_0,
CONNECTION_DUMMY_1,
CONNECTION_DUMMY_2,
CONNECTION_DUMMY_3,
CONNECTION_DUMMY_4,
CONNECTION_DUMMY_5,
CONNECTION_DUMMY_6,
CONNECTION_DUMMY_7,
CONNECTION_DUMMY_8,
CONNECTION_DUMMY_9,
CONNECTION_FILETRANSFER_BANDWIDTH_SENT, ///< UInt64. Current file transfer upstream activity in bytes per second.
///< Only available on request (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, ///< UInt64. Current file transfer downstream activity in bytes per
///< second. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, ///< UInt64. Total downstream traffic, in bytes, used for file
///< transfer since the server was started. Only available on request
///< (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, ///< UInt64. Total upstream traffic, in bytes, used for file transfer
///< since the server was started. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_ENDMARKER
};
/**
* Describes a client position in 3 dimensional space, used for 3D Sound.
*/
typedef struct
{
float x; ///< X co-ordinate in 3D space.
float y; ///< Y co-ordinate in 3D space.
float z; ///< Z co-ordinate in 3D space.
} TS3_VECTOR;
enum GroupWhisperType
{
GROUPWHISPERTYPE_SERVERGROUP = 0, ///< Whisper list consists of server groups
GROUPWHISPERTYPE_CHANNELGROUP = 1, ///< Whisper list consists of channel groups
GROUPWHISPERTYPE_CHANNELCOMMANDER = 2, ///< whisper to channel commanders
GROUPWHISPERTYPE_ALLCLIENTS = 3, ///< whisper to all clients
GROUPWHISPERTYPE_ENDMARKER,
};
enum GroupWhisperTargetMode
{
GROUPWHISPERTARGETMODE_ALL = 0,
GROUPWHISPERTARGETMODE_CURRENTCHANNEL = 1, ///< Whisper the current channel of the client
GROUPWHISPERTARGETMODE_PARENTCHANNEL = 2, ///< Whisper the parent channel of whatever channel the client is currently in
GROUPWHISPERTARGETMODE_ALLPARENTCHANNELS = 3, ///< Whipser to the parent channel and all their parent channels as well
GROUPWHISPERTARGETMODE_CHANNELFAMILY = 4, ///< Whisper to the current channel and all its sub channels
GROUPWHISPERTARGETMODE_ANCESTORCHANNELFAMILY = 5, ///< Whisper to the current channel, all its parent and sub channels.
GROUPWHISPERTARGETMODE_SUBCHANNELS = 6, ///< Whisper to all sub channels of the current channel of the client
GROUPWHISPERTARGETMODE_ENDMARKER,
};
enum MonoSoundDestination
{
MONO_SOUND_DESTINATION_ALL = 0, ///< Send mono sound to all available speakers
MONO_SOUND_DESTINATION_FRONT_CENTER = 1, ///< Send mono sound to front center speaker if available
MONO_SOUND_DESTINATION_FRONT_LEFT_AND_RIGHT = 2 ///< Send mono sound to front left/right speakers if available
};
enum SecuritySaltOptions
{
SECURITY_SALT_CHECK_NICKNAME = 1, ///< put nickname into security hash
SECURITY_SALT_CHECK_META_DATA = 2 ///< put meta data into security hash
};
/*this enum is used to disable client commands on the server*/
enum ClientCommand
{
CLIENT_COMMAND_requestConnectionInfo = 0, ///< disable client connection info request (client bandwidth usage, ip,
///< port, ping)
CLIENT_COMMAND_requestClientMove = 1, ///< disable moving clients
CLIENT_COMMAND_requestXXMuteClients = 2, ///< disable muting other clients
CLIENT_COMMAND_requestClientKickFromXXX = 3, ///< disable kicking clients
CLIENT_COMMAND_flushChannelCreation = 4, ///< disable creating channels
CLIENT_COMMAND_flushChannelUpdates = 5, ///< disable editing channels
CLIENT_COMMAND_requestChannelMove = 6, ///< disable moving channels
CLIENT_COMMAND_requestChannelDelete = 7, ///< disable deleting channels
CLIENT_COMMAND_requestChannelDescription = 8, ///< disable channel descriptions
CLIENT_COMMAND_requestChannelXXSubscribeXXX = 9, ///< disable being able to see clients in channels other than the
///< current channel the client is in
CLIENT_COMMAND_requestServerConnectionInfo = 10, ///< disable server connection info request (server bandwidth
///< usage, ip, port, ping)
CLIENT_COMMAND_requestSendXXXTextMsg = 11, ///< disable text messaging
CLIENT_COMMAND_filetransfers = 12, ///< disable file transfer
CLIENT_COMMAND_ENDMARKER
};
/* Access Control List*/
enum ACLType
{
ACL_NONE = 0,
ACL_WHITE_LIST = 1,
ACL_BLACK_LIST = 2
};
/* file transfer actions*/
enum FTAction
{
FT_INIT_SERVER = 0, ///< The virtual server is created. result->channelPath can be changed to create a different
///< directory than the default 'virtualserver_x' where x is the virtual server.
FT_INIT_CHANNEL = 1, ///< A channel is created. result->channelPath can be changed to create a different directory
///< then the default 'channel_x' where x is the channel id.
FT_UPLOAD = 2, ///< A file is being uploaded. All values in the result struct can be modified.
FT_DOWNLOAD = 3, ///< A file is being downloaded. All values in the result struct can be modified.
FT_DELETE = 4, ///< A file is being deleted. All values in the result struct can be modified.
FT_CREATEDIR = 5, ///< A directory is being created in a channel. All values in the result struct can be modified.
FT_RENAME = 6, ///< A file or folder is being renamed. The callback will be called twice! Once for the old and then
///< for the new name. All values in the result struct can be modified.
FT_FILELIST = 7, ///< A directory listing is requested. All values in the result struct can be modified.
FT_FILEINFO = 8 ///< Information of a file is requested. All values in the result struct can be modified.
};
/* file transfer status */
enum FileTransferState
{
FILETRANSFER_INITIALISING = 0, ///< File transfer is establishing connection.
FILETRANSFER_ACTIVE, ///< File transfer is in progress
FILETRANSFER_FINISHED, ///< File transfer has finished
};
/* file transfer types */
enum FileTransferType
{
FileListType_Directory = 0, ///< The file entry is a directory
FileListType_File, ///< The file entry is a regular file
};
/* some structs to handle variables in callbacks */
#define MAX_VARIABLES_EXPORT_COUNT 64
struct VariablesExportItem
{
unsigned char itemIsValid; ///< Whether or not there is any data in this item. Ignore this item if this is 0.
unsigned char proposedIsSet; ///< The value in proposed is set. If 0 ignore proposed
const char* current; ///< current value (stored in memory)
const char* proposed; ///< New value to change to (const, so no updates please)
};
struct VariablesExport
{
struct VariablesExportItem items[MAX_VARIABLES_EXPORT_COUNT];
};
struct ClientMiniExport
{
anyID ID; ///< id of the client
uint64 channel; ///< the channel the client is in
const char* ident; ///< client public identity
const char* nickname; ///< client display name
};
/**
* Structure used to describe a file transfer in the \ref ServerLibFunctions.onTransformFilePath callback.
* This describes the original values, and also contains hints for length limitations of the result parameter
* of the callback.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExport
{
uint64 channel; ///< The channel id of the file. 0 if action is \ref FT_INIT_SERVER
const char* filename; ///< utf8 encoded c string containing the original file name as intended by the client.
int action; ///< The action to be performed. One of the values from the \ref FTAction enum. Defines which values of
///< the result struct can be modified.
int transformedFileNameMaxSize; ///< The maximum length the file name can be rewritten to.
int channelPathMaxSize; ///< The maximum length the path can be rewritten to.
};
/**
* Structure to rewrite the file transfer file name and path in the \ref ServerLibFunctions.onTransformFilePath callback.
* The lengths are limited as described in the original parameter.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExportReturns
{
char* transformedFileName; ///< pointer to target file name. Fill the memory pointed to with an utf8 encoded c string
///< containing the new file name. Limited to original->transformedFileNameMaxSize bytes.
char* channelPath; ///< pointer to memory for new path. Fill the memory pointed to with an utf8 encoded c string
///< containing the new path. Limited to original->channelPathMaxSize bytes.
int logFileAction; ///< boolean (1/0). Whether to log this file transfer to the log. Action is not logged regardless
///< of this value if the servers \ref VIRTUALSERVER_LOG_FILETRANSFER property is 0.
};
struct FileTransferCallbackExport
{
anyID clientID; ///< the client who started the file transfer
anyID transferID; ///< local identifier of the transfer that has completed
anyID remoteTransferID; ///< remote identifier of the transfer that has completed
unsigned int status; ///< status of the transfer. One of the values from the \ref FileTransferState enum
const char* statusMessage; ///< utf8 encoded c string containing a human readable description of the status
uint64 remotefileSize; ///< size in bytes of the complete file to be transferred
uint64 bytes; ///< number of bytes transferred. Same as remotefileSize when the transfer completed entirely.
int isSender; ///< boolean. 1 if the server is sending the file. 0 if the server is receiving the file.
};
/*define for file transfer bandwith limits*/
#define BANDWIDTH_LIMIT_UNLIMITED 0xFFFFFFFFFFFFFFFFll
/*defines for speaker locations used by some sound callbacks*/
#ifndef SPEAKER_FRONT_LEFT
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#endif
#define SPEAKER_HEADPHONES_LEFT 0x10000000
#define SPEAKER_HEADPHONES_RIGHT 0x20000000
#define SPEAKER_MONO 0x40000000
#endif /*PUBLIC_DEFINITIONS_H*/
@@ -0,0 +1,217 @@
#ifndef PUBLIC_ERRORS_H
#define PUBLIC_ERRORS_H
//The idea here is: the values are 2 bytes wide, the first byte identifies the group, the second the count within that group
enum Ts3ErrorType {
//general
ERROR_ok = 0x0000, ///< Indicates success.
ERROR_undefined = 0x0001,
ERROR_not_implemented = 0x0002, ///< The attempted operation is not available in this context
ERROR_ok_no_update = 0x0003, ///< Indicates success, but no change occurred. Returned for example upon flushing (e.g. using \ref ts3client_flushChannelUpdates) when all indicated changes already matched the current state.
ERROR_dont_notify = 0x0004,
ERROR_lib_time_limit_reached = 0x0005,
ERROR_out_of_memory = 0x0006, ///< Not enough system memory to perform operation
ERROR_canceled = 0x0007,
ERROR_ok_no_error_event = 0x0008, ///< Indicates success, but no error event was generated. This is used because of the return code management and reduce packets.
//dunno
ERROR_command_not_found = 0x0100,
ERROR_unable_to_bind_network_port = 0x0101, ///< Unspecified failure to create a listening port
ERROR_no_network_port_available = 0x0102, ///< Failure to initialize a listening port for FileTransfer
ERROR_port_already_in_use = 0x0103, ///< Specified port is already in use by a different application
ERROR_command_line_parse_failed = 0x0104, ///< Command line arguments are invalid
ERROR_command_line_exit_version = 0x0105, ///< Command line specified version. The process should exit with code 0 after printing the version.
ERROR_command_line_exit_help = 0x0106, ///< Command line specified help. The process should exit with code 0 after priting the help.
//client
ERROR_client_invalid_id = 0x0200, ///< Client no longer connected
ERROR_client_nickname_inuse = 0x0201, ///< Client name is already in use. Client names must be unique
ERROR_client_protocol_limit_reached = 0x0203, ///< Too many clients on the server
ERROR_client_invalid_type = 0x0204, ///< Function called for normal clients that is only available for query clients or vice versa
ERROR_client_already_subscribed = 0x0205, ///< Attempting to subscribe to a channel already subscribed to
ERROR_client_not_logged_in = 0x0206,
ERROR_client_could_not_validate_identity = 0x0207, ///< Identity not valid or insufficient security level
ERROR_client_invalid_password = 0x0208,
ERROR_client_version_outdated = 0x020a, ///< Server requires newer client version as determined by the min_client_version properties
ERROR_client_is_flooding = 0x020c, ///< Triggered flood protection. Further information is supplied in the extra message if applicable.
ERROR_client_hacked = 0x020d,
ERROR_client_cannot_verify_now = 0x020e,
ERROR_client_login_not_permitted = 0x020f,
ERROR_client_not_subscribed = 0x0210, ///< Action is only available on subscribed channels
//channel
ERROR_channel_invalid_id = 0x0300, ///< Channel does not exist on the server (any longer)
ERROR_channel_protocol_limit_reached = 0x0301, ///< Too many channels on the server
ERROR_channel_already_in = 0x0302, ///< Attempting to move a client or channel to its current channel
ERROR_channel_name_inuse = 0x0303, ///< Channel name is already taken by another channel. Channel names must be unique
ERROR_channel_not_empty = 0x0304, ///< Attempting to delete a channel with clients or sub channels in it
ERROR_channel_can_not_delete_default = 0x0305, ///< Default channel cannot be deleted. Set a new default channel first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_default_require_permanent = 0x0306, ///< Attempt to set a non permanent channel as default channel. Set channel to permanent first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_invalid_flags = 0x0307, ///< Invalid combination of \ref ChannelProperties, trying to remove \ref CHANNEL_FLAG_DEFAULT or set a password on the default channel
ERROR_channel_parent_not_permanent = 0x0308, ///< Attempt to move a permanent channel into a non-permanent one, or set a channel to be permanent that is a sub channel of a non-permanent one
ERROR_channel_maxclients_reached = 0x0309, ///< Channel is full as determined by its \ref CHANNEL_MAXCLIENTS setting
ERROR_channel_maxfamily_reached = 0x030a, ///< Channel tree is full as determined by its \ref CHANNEL_MAXFAMILYCLIENTS setting
ERROR_channel_invalid_order = 0x030b, ///< Invalid value for the \ref CHANNEL_ORDER property. The specified channel must exist on the server and be on the same level.
ERROR_channel_no_filetransfer_supported = 0x030c, ///< Invalid \ref CHANNEL_FILEPATH set for the channel
ERROR_channel_invalid_password = 0x030d, ///< Channel has a password not matching the password supplied in the call
// used in public_rare_errors = 0x030e,
ERROR_channel_invalid_security_hash = 0x030f,
//server
ERROR_server_invalid_id = 0x0400, ///< Chosen virtual server does not exist or is offline
ERROR_server_running = 0x0401, ///< attempting to delete a server that is running. Stop the server before deleting it.
ERROR_server_is_shutting_down = 0x0402, ///< Client disconnected because the server is going offline
ERROR_server_maxclients_reached = 0x0403, ///< Given in the onConnectStatusChange event when the server has reached its maximum number of clients as defined by the \ref VIRTUALSERVER_MAXCLIENTS property
ERROR_server_invalid_password = 0x0404, ///< Specified server password is wrong. Provide the correct password in the \ref ts3client_startConnection / \ref ts3client_startConnectionWithChannelID call.
ERROR_server_is_virtual = 0x0407, ///< Server is in virtual status. The attempted action is not possible in this state. Start the virtual server first.
ERROR_server_is_not_running = 0x0409, ///< Attempting to stop a server that is not online.
ERROR_server_is_booting = 0x040a, // Not used
ERROR_server_status_invalid = 0x040b,
ERROR_server_version_outdated = 0x040d, ///< Attempt to connect to an outdated server version. The server needs to be updated.
ERROR_server_duplicate_running = 0x040e, ///< This server is already running within the instance. Each virtual server may only exist once.
//parameter
ERROR_parameter_quote = 0x0600, // Not used
ERROR_parameter_invalid_count = 0x0601, ///< Attempt to flush changes without previously calling set*VariableAs* since the last flush
ERROR_parameter_invalid = 0x0602, ///< At least one of the supplied parameters did not meet the criteria for that parameter
ERROR_parameter_not_found = 0x0603, ///< Failure to supply all the necessary parameters
ERROR_parameter_convert = 0x0604, ///< Invalid type supplied for a parameter, such as passing a string (ie. "five") that expects a number.
ERROR_parameter_invalid_size = 0x0605, ///< Value out of allowed range. Such as strings are too long/short or numeric values outside allowed range
ERROR_parameter_missing = 0x0606, ///< Neglecting to specify a required parameter
ERROR_parameter_checksum = 0x0607, ///< Attempting to deploy a modified snapshot
//unsorted, need further investigation
ERROR_vs_critical = 0x0700, ///< Failure to create default channel
ERROR_connection_lost = 0x0701, ///< Generic error with the connection.
ERROR_not_connected = 0x0702, ///< Attempting to call functions with a serverConnectionHandler that is not connected. You can use \ref ts3client_getConnectionStatus to check whether the connection handler is connected to a server
ERROR_no_cached_connection_info = 0x0703, ///< Attempting to query connection information (bandwidth usage, ping, etc) without requesting them first using \ref ts3client_requestConnectionInfo
ERROR_currently_not_possible = 0x0704, ///< Requested information is not currently available. You may have to call \ref ts3client_requestClientVariables or \ref ts3client_requestServerVariables
ERROR_failed_connection_initialisation = 0x0705, ///< No TeamSpeak server running on the specified IP address and port
ERROR_could_not_resolve_hostname = 0x0706, ///< Failure to resolve the specified hostname to an IP address
ERROR_invalid_server_connection_handler_id = 0x0707, ///< Attempting to perform actions on a non-existent server connection handler
ERROR_could_not_initialise_input_manager = 0x0708, // Not used
ERROR_clientlibrary_not_initialised = 0x0709, ///< Calling client library functions without successfully calling \ref ts3client_initClientLib before
ERROR_serverlibrary_not_initialised = 0x070a, ///< Calling server library functions without successfully calling \ref ts3server_initServerLib before
ERROR_whisper_too_many_targets = 0x070b, ///< Using a whisper list that contain more clients than the servers \ref VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE property
ERROR_whisper_no_targets = 0x070c, ///< The active whisper list is empty or no clients matched the whisper list (e.g. all channels in the list are empty)
ERROR_connection_ip_protocol_missing = 0x070d, ///< Invalid or unsupported protocol (e.g. attempting an IPv6 connection on an IPv4 only machine)
ERROR_handshake_failed = 0x070e,
ERROR_illegal_server_license = 0x070f,
//file transfer
ERROR_file_invalid_name = 0x0800, ///< Invalid UTF8 string or not a valid file
ERROR_file_invalid_permissions = 0x0801, ///< Permissions prevent opening the file
ERROR_file_already_exists = 0x0802, ///< Target path already exists as a directory
ERROR_file_not_found = 0x0803, ///< Attempt to access or move non existing file
ERROR_file_io_error = 0x0804, ///< Generic file input / output error
ERROR_file_invalid_transfer_id = 0x0805, ///< Attempt to get information about a file transfer after it has already been cleaned up. File transfer information is not available indefinitely after the transfer completed
ERROR_file_invalid_path = 0x0806, ///< specified path contains invalid characters or does not start with "/"
ERROR_file_no_files_available = 0x0807, // Not used
ERROR_file_overwrite_excludes_resume = 0x0808, ///< File overwrite and resume are mutually exclusive. Only one or neither can be 1.
ERROR_file_invalid_size = 0x0809, ///< Attempt to write more bytes than claimed file size.
ERROR_file_already_in_use = 0x080a, ///< File is currently not available, try again later.
ERROR_file_could_not_open_connection = 0x080b, ///< Generic failure in file transfer connection / other party did not conform to file transfer protocol
ERROR_file_no_space_left_on_device = 0x080c, ///< Operating system reports hard disk is full. May be caused by quota limitations.
ERROR_file_exceeds_file_system_maximum_size = 0x080d, ///< File is too large for the file system of the target device.
ERROR_file_transfer_connection_timeout = 0x080e, // Not used
ERROR_file_connection_lost = 0x080f, ///< File input / output timeout or connection failure
ERROR_file_exceeds_supplied_size = 0x0810, // Not used
ERROR_file_transfer_complete = 0x0811, ///< Indicates successful completion
ERROR_file_transfer_canceled = 0x0812, ///< Transfer was cancelled through @ref ts3client_haltTransfer
ERROR_file_transfer_interrupted = 0x0813, ///< Transfer failed because the server is shutting down, or network connection issues
ERROR_file_transfer_server_quota_exceeded = 0x0814, ///< Transfer terminated due to server bandwidth quota being exceeded. No client can transfer files.
ERROR_file_transfer_client_quota_exceeded = 0x0815, ///< Attempt to transfer more data than allowed by this clients' bandwidth quota. Other clients may continue to transfer files.
ERROR_file_transfer_reset = 0x0816, // Not used
ERROR_file_transfer_limit_reached = 0x0817, ///< Too many file transfers are in progress. Try again later
ERROR_file_invalid_storage_class = 0x0818, // TODO: Invalid storage class for HTTP FileTransfer (what is a storage class?)
ERROR_file_invalid_dimension = 0x0819, ///< Avatar image exceeds maximum width or height accepted by the server.
ERROR_file_transfer_channel_quota_exceeded = 0x081a, ///< Transfer failed because the channel quota was exceeded. Uploading to this channel is not possible, but other channels may be fine.
//sound
ERROR_sound_preprocessor_disabled = 0x0900, ///< Cannot set or query pre processor variables with preprocessing disabled
ERROR_sound_internal_preprocessor = 0x0901,
ERROR_sound_internal_encoder = 0x0902,
ERROR_sound_internal_playback = 0x0903,
ERROR_sound_no_capture_device_available = 0x0904, ///< No audio capture devices are available
ERROR_sound_no_playback_device_available = 0x0905, ///< No audio playback devices are available
ERROR_sound_could_not_open_capture_device = 0x0906, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_could_not_open_playback_device = 0x0907, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_handler_has_device = 0x0908, ///< Attempt to open a sound device on a connection handler which already has an open device. Close the already open device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_invalid_capture_device = 0x0909, ///< Attempt to use a device for capture that does not support capturing audio
ERROR_sound_invalid_playback_device = 0x090a, ///< Attempt to use a device for playback that does not support playback of audio
ERROR_sound_invalid_wave = 0x090b, ///< Attempt to use a non WAV file in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle
ERROR_sound_unsupported_wave = 0x090c, ///< Unsupported wave file used in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle.
ERROR_sound_open_wave = 0x090d, ///< Failure to open the specified sound file
ERROR_sound_internal_capture = 0x090e,
ERROR_sound_device_in_use = 0x090f, ///< Attempt to unregister a custom device that is being used. Close the device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_device_already_registerred = 0x0910, ///< Attempt to register a custom device with a device id that has already been used in a previous call. Device ids must be unique.
ERROR_sound_unknown_device = 0x0911, ///< Attempt to open, close, unregister or use a device which is not known. Custom devices must be registered before being used (see \ref ts3client_registerCustomDevice)
ERROR_sound_unsupported_frequency = 0x0912,
ERROR_sound_invalid_channel_count = 0x0913, ///< Invalid device audio channel count, must be > 0
ERROR_sound_read_wave = 0x0914, ///< Failure to read sound samples from an opened wave file. Is this a valid wave file?
ERROR_sound_need_more_data = 0x0915, // for internal purposes only
ERROR_sound_device_busy = 0x0916, // for internal purposes only
ERROR_sound_no_data = 0x0917, ///< Indicates there is currently no data for playback, e.g. nobody is speaking right now.
ERROR_sound_channel_mask_mismatch = 0x0918, ///< Opening a device with an unsupported channel count
//permissions
ERROR_permissions_client_insufficient = 0x0a08, ///< Not enough permissions to perform the requested activity
ERROR_permissions = 0x0a0c, ///< Permissions to use sound device not granted by operating system, e.g. Windows denied microphone access.
//accounting
ERROR_accounting_virtualserver_limit_reached = 0x0b00, ///< Attempt to use more virtual servers than allowed by the license
ERROR_accounting_slot_limit_reached = 0x0b01, ///< Attempt to set more slots than allowed by the license
ERROR_accounting_license_file_not_found = 0x0b02, // Not used
ERROR_accounting_license_date_not_ok = 0x0b03, ///< License expired or not valid yet
ERROR_accounting_unable_to_connect_to_server = 0x0b04, ///< Failure to communicate with accounting backend
ERROR_accounting_unknown_error = 0x0b05, ///< Failure to write update license file
ERROR_accounting_server_error = 0x0b06, // Not used
ERROR_accounting_instance_limit_reached = 0x0b07, ///< More than one process of the server is running
ERROR_accounting_instance_check_error = 0x0b08, ///< Shared memory access failure.
ERROR_accounting_license_file_invalid = 0x0b09, ///< License is not a TeamSpeak license
ERROR_accounting_running_elsewhere = 0x0b0a, ///< A copy of this server is already running in another instance. Each server may only exist once.
ERROR_accounting_instance_duplicated = 0x0b0b, ///< A copy of this server is running already in this process. Each server may only exist once.
ERROR_accounting_already_started = 0x0b0c, ///< Attempt to start a server that is already running
ERROR_accounting_not_started = 0x0b0d,
ERROR_accounting_to_many_starts = 0x0b0e, ///< Starting instance / virtual servers too often in too short a time period
//provisioning server
/// @cond HAS_PROVISIONING
ERROR_provisioning_invalid_password = 0x1100,
ERROR_provisioning_invalid_request = 0x1101,
ERROR_provisioning_no_slots_available = 0x1102,
ERROR_provisioning_pool_missing = 0x1103,
ERROR_provisioning_pool_unknown = 0x1104,
ERROR_provisioning_unknown_ip_location = 0x1105,
ERROR_provisioning_internal_tries_exceeded = 0x1106,
ERROR_provisioning_too_many_slots_requested = 0x1107,
ERROR_provisioning_too_many_reserved = 0x1108,
ERROR_provisioning_could_not_connect = 0x1109,
ERROR_provisioning_auth_server_not_connected = 0x1110,
ERROR_provisioning_auth_data_too_large = 0x1111,
ERROR_provisioning_already_initialized = 0x1112,
ERROR_provisioning_not_initialized = 0x1113,
ERROR_provisioning_connecting = 0x1114,
ERROR_provisioning_already_connected = 0x1115,
ERROR_provisioning_not_connected = 0x1116,
ERROR_provisioning_io_error = 0x1117,
ERROR_provisioning_invalid_timeout = 0x1118,
ERROR_provisioning_ts3server_not_found = 0x1119,
ERROR_provisioning_no_permission = 0x111A,
/// @endcond
// 0x12 - 0x15 are reserved in rare
// screen share
ERROR_already_registered = 0x1600,
ERROR_stream_session_limit_reached = 0x1601,
ERROR_stream_session_not_found = 0x1602,
ERROR_stream_unknown = 0x1603,
ERROR_stream_not_participating = 0x1604,
ERROR_not_streamer = 0x1605,
ERROR_already_joined = 0x1606,
ERROR_join_request_not_found = 0x1607,
ERROR_sfu_failed_to_start = 0x1608,
};
#endif
@@ -0,0 +1,236 @@
#ifndef TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#define TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Version definitions.
#define TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1 1
// Protocol used for communication between the session subscriber and the session (a single stream).
// Commands are sent bidirectionally or unidirectionally between the parties.
// e.g. SESSION => SUBSCRIBER: ON_FRAME, ON_PAUSED_CHANGED
// e.g. SUBSCRIBER => SESSION: ON_FRAME_ACK, ON_RESIZE
// Command type enum with a lowercase type name.
typedef enum
{
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME = 0,
TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE,
TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED,
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK,
TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP,
TS_SESSION_SUBSCRIBER_CMD_REMOVE_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED,
} ts_session_subscriber_command_type_t;
// Pixel format enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_I420 = 0,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_NV12,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ABGR,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ARGB,
} ts_session_subscriber_pixel_format_t;
// Buffer location enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_CPU = 0,
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_GPU
} ts_session_subscriber_buffer_location_t;
// Buffer type enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_SINGLE = 0,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_MAIN,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_SUB
} ts_session_subscriber_buffer_type_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(push, 4)
#endif
// Main buffer header for shared CPU Memory Front/Back Buffers.
// The Main Buffer contains metadata about the current front/back buffer and the versioning for both the main and sub buffer.
// The information from the main buffer can be used to always read the front buffer.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t front_buffer_index; // index of the front buffer. (0: main buffer, 1: sub buffer)
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_main_buffer_header_t;
// Sub buffer header.
typedef struct
{
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
} ts_session_subscriber_sub_buffer_header_t;
// Single frame buffer header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_single_frame_buffer_header_t;
// Command header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // Total message length (header + payload).
ts_session_subscriber_command_type_t type;
uint64_t target_session_id; // always set to the target session id this command is for or is originating from.
uint64_t target_subscriber_id; // 0 if broadcast.
} ts_session_subscriber_command_header_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME.
// The frame data is not included in the message, but is attached seperately or was sent beforehand. The buffer is identified by it's id.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_id; // buffer id, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_frame_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t frame_id;
} ts_session_subscriber_on_frame_ack_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE.
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t width;
uint32_t height;
} ts_session_subscriber_on_resize_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t paused; // 0 or 1.
} ts_session_subscriber_on_paused_changed_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE.
// Contains a single frame buffer. The header is of format |ts_session_subscriber_single_frame_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
ts_session_subscriber_buffer_type_t buffer_type;
} ts_session_subscriber_on_buffer_single_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK.
// Contains a main buffer and a sub buffer. The main buffer header
// contains metadata about the current front/back buffer and
// is of type |ts_session_subscriber_main_buffer_header_t|.
// The sub buffer's header is of type |ts_session_subscriber_sub_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t main_buffer_ptr; // main buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t main_buffer_length;
uint64_t sub_buffer_ptr; // sub buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t sub_buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
} ts_session_subscriber_on_buffer_front_back_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER.
// SUBSCRIBER => SESSION.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_resp_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_release_buffer_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr;
int bits_per_sample;
int sample_rate;
uint32_t number_of_channels;
uint32_t number_of_frames;
int64_t absolute_capture_timestamp_ms;
float volume;
} ts_session_subscriber_on_audio_frames_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t audio_enabled;
} ts_session_subscriber_on_audio_enabled_changed_payload_t;
// Overall Command structure.
typedef struct
{
ts_session_subscriber_command_header_t header;
union
{
ts_session_subscriber_on_frame_payload_t frame;
ts_session_subscriber_on_resize_payload_t resize;
ts_session_subscriber_on_paused_changed_payload_t paused;
ts_session_subscriber_on_frame_ack_payload_t frame_ack;
ts_session_subscriber_on_buffer_single_payload_t buffer_single;
ts_session_subscriber_on_buffer_front_back_payload_t buffer_front_back;
ts_session_subscriber_on_release_buffer_payload_t release_buffer;
ts_session_subscriber_add_subscriber_payload_t add_subscriber;
ts_session_subscriber_add_subscriber_resp_payload_t add_subscriber_resp;
ts_session_subscriber_on_audio_frames_payload_t audio_frames;
ts_session_subscriber_on_audio_enabled_changed_payload_t audio_enabled_changed;
} payload;
} ts_session_subscriber_command_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif // TS_SESSION_SUBSCRIBER_PROTOCOL_H_
@@ -0,0 +1,29 @@
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was team_clientConfig.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()
####################################################################################
include("${CMAKE_CURRENT_LIST_DIR}/team_clientTargets.cmake")
check_required_components(team_client)
@@ -0,0 +1,19 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "teamspeak::client" for configuration "Release"
set_property(TARGET teamspeak::client APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(teamspeak::client PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.so"
IMPORTED_SONAME_RELEASE "libteamspeak_sdk_client.so"
)
list(APPEND _cmake_import_check_targets teamspeak::client )
list(APPEND _cmake_import_check_files_for_teamspeak::client "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.so" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
@@ -0,0 +1,121 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.3")
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.3...4.0)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS teamspeak::client)
list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
if(TARGET "${_cmake_expected_target}")
list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
else()
list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
unset(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target teamspeak::client
add_library(teamspeak::client SHARED IMPORTED)
set_target_properties(teamspeak::client PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
if(NOT CMAKE_VERSION VERSION_LESS "3.23.0")
target_sources(teamspeak::client
INTERFACE
FILE_SET "public_headers"
TYPE "HEADERS"
BASE_DIRS "${_IMPORT_PREFIX}/include"
FILES "${_IMPORT_PREFIX}/include/teamspeak/clientlib.h" "${_IMPORT_PREFIX}/include/teamspeak/clientlib_sdk.h" "${_IMPORT_PREFIX}/include/teamspeak/video/session_subscriber_protocol.h"
)
else()
set_property(TARGET teamspeak::client
APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
"${_IMPORT_PREFIX}/include"
)
endif()
# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/team_clientTargets-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
if(CMAKE_VERSION VERSION_LESS "3.28"
OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target}
OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}")
foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
if(NOT EXISTS "${_cmake_file}")
message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
\"${_cmake_file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
endif()
unset(_cmake_file)
unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
@@ -0,0 +1,23 @@
#ifndef TEAMLOG_LOGTYPES_H
#define TEAMLOG_LOGTYPES_H
enum LogTypes {
LogType_NONE = 0x0000, ///< Logging is disabled
LogType_FILE = 0x0001, ///< Log to regular log file
LogType_CONSOLE = 0x0002, ///< Log to standard output / error
LogType_USERLOGGING = 0x0004, ///< User defined logging. Will call the \ref ServerLibFunctions.onUserLoggingMessageEvent callback for every message to be logged
LogType_NO_NETLOGGING = 0x0008, ///< Not used
LogType_DATABASE = 0x0010, ///< Log to database (deprecated, server only, no effect in SDK)
LogType_SYSLOG = 0x0020, ///< Log to syslog (only available on Linux)
};
enum LogLevel {
LogLevel_CRITICAL = 0, ///< these messages stop the program
LogLevel_ERROR, ///< everything that is really bad, but not so bad we need to shut down
LogLevel_WARNING, ///< everything that *might* be bad
LogLevel_DEBUG, ///< output that might help find a problem
LogLevel_INFO, ///< informational output, like "starting database version x.y.z"
LogLevel_DEVEL ///< developer only output (will not be displayed in release mode)
};
#endif //TEAMLOG_LOGTYPES_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,58 @@
#ifndef CLIENTLIB_SDK_H
#define CLIENTLIB_SDK_H
// system
#include <stdlib.h>
// own
#include "teamspeak/public_definitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets the client to which to transmit voice. Stops standard channel voice transmission.
*
* The client will still receive voice from their current channel, however their voice will not be transmitted to their
* current channel anymore. If this call is successful (check onServerErrorEvent) then voice of the specified client
* will be transmitted to all specified channels and all the specified clients. Pass 0 to both target parameter arrays
* to restore default behavior of transmitting voice to current channel. You will receive an onServerErrorEvent with the
* passed returnCode indicating whether or not the operation was successful.
*
* @param server_connection_handler_id the connection handler on which to set the whisper list
* @param client_id the client to set the whisper list for. Set to 0 or your own client ID to set your own whisper list.
* @param channel_ids an array of channel ids to transmit voice to.
* @param channel_ids_size number of elements in aforementioned array.
* @param client_ids a zero terminated array of client ids to transmit voice to.
* @param client_ids_size number of elements in aforementioned array.
* @param impersonate if the target client is a webrtc client, the voice packets will look like as if they have been
* send by the invoking client id
* @param return_code a c string to identify this request in callbacks. Pass an empty string if unused.
* @return An error code from the @ref Ts3ErrorType enum indicating either success or the failure reason
*/
EXPORTDLL unsigned int ts_client_request_client_set_whisper_list(uint64 server_connection_handler_id, anyID client_id,
const uint64* channel_ids,
int channel_ids_size,
const anyID* client_ids,
int client_ids_size, int impersonate,
const char* return_code);
/**
* @brief Send a binary-serialized ClientCommandRequest protobuf to the client library.
*
* The response will be delivered asynchronously via the onProtoResponse callback
* as a serialized ClientCommandResponse protobuf.
*
* @param data Pointer to serialized ClientCommandRequest protobuf bytes
* @param size Size of the serialized data in bytes
* @param return_code Caller-provided string to correlate the response in onProtoResponse. May be NULL.
* @return An error code: ERROR_ok on successful dispatch, ERROR_parameter_invalid on parse failure
*/
EXPORTDLL unsigned int ts3client_postProtoCommand(const void* data, size_t size, const char* return_code);
#ifdef __cplusplus
}
#endif
#endif // CLIENTLIB_SDK_H
@@ -0,0 +1,635 @@
#ifndef PUBLIC_DEFINITIONS_H
#define PUBLIC_DEFINITIONS_H
#include "teamlog/logtypes.h"
#define TS3_MAX_SIZE_CHANNEL_NAME 40 // channel name maximum length in characters
#define TS3_MAX_SIZE_VIRTUALSERVER_NAME 64 // virtual server name maximum length in characters
#define TS3_MAX_SIZE_CLIENT_NICKNAME 64 // client display name length limit in characters
#define TS3_MIN_SIZE_CLIENT_NICKNAME 3 // client display name minimum length in characters
#define TS3_MAX_SIZE_REASON_MESSAGE 80 // length limit in characters for kick, move, etc reasons
#define TS3_MAX_SIZE_TEXTMESSAGE 8192 // text message length limit, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_TOPIC 255 // channel topic lengt limith, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_DESCRIPTION 8192 // channel description length limit, measured in bytes (utf8 encoded)
// server welcome message length limit measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_VIRTUALSERVER_WELCOMEMESSAGE 1024
#define TS3_SIZE_MYTSID 44
// minimum amount of seconds before a clientID that was in use can be assigned to a new client
#define TS3_MIN_SECONDS_CLIENTID_REUSE 300
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32)
typedef unsigned __int16 anyID;
typedef unsigned __int64 uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __declspec(dllexport)
#else
#define EXPORTDLL
#endif
#endif
#else
#include <stdint.h>
typedef uint16_t anyID;
typedef uint64_t uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __attribute__((visibility("default")))
#else
#define EXPORTDLL
#endif
#endif
#endif
enum Visibility
{
ENTER_VISIBILITY = 0, ///< Client joined from an unsubscribed channel, or joined the server.
RETAIN_VISIBILITY, ///< Client switched from one subscribed channel to a different subscribed channel.
LEAVE_VISIBILITY ///< Client switches to an unsubscribed channel, or disconnected from server.
};
enum ConnectStatus
{
STATUS_DISCONNECTED = 0, ///< There is no activity to the server, this is the default value
STATUS_CONNECTING, ///< We are trying to connect, we haven't got a client id yet, we haven't been accepted by the server
STATUS_CONNECTED, ///< The server has accepted us, we can talk and hear and we have a client id, but we don't
///< have the channels and clients yet, we can get server infos (welcome msg etc.)
STATUS_CONNECTION_ESTABLISHING, ///< we are connected and we are visible
STATUS_CONNECTION_ESTABLISHED, ///< we are connected and we have the client and channels available
};
enum LocalTestMode
{
TEST_MODE_OFF = 0,
TEST_MODE_VOICE_LOCAL_ONLY,
TEST_MODE_VOICE_LOCAL_AND_REMOTE,
TEST_MODE_TALK_STATUS_CHANGES_ONLY
};
enum TalkStatus
{
STATUS_NOT_TALKING = 0, ///< client is not talking
STATUS_TALKING = 1, ///< client is talking
STATUS_TALKING_WHILE_DISABLED = 2, ///< client is talking while the microphone is muted (only valid for own client)
};
enum CodecType
{
CODEC_SPEEX_NARROWBAND = 0, ///< (deprecated) mono, 16bit, 8kHz, bitrate dependent on the quality setting
CODEC_SPEEX_WIDEBAND, ///< (deprecated) mono, 16bit, 16kHz, bitrate dependent on the quality setting
CODEC_SPEEX_ULTRAWIDEBAND, ///< (deprecated) mono, 16bit, 32kHz, bitrate dependent on the quality setting
CODEC_CELT_MONO, ///< (deprecated) mono, 16bit, 48kHz, bitrate dependent on the quality setting
CODEC_OPUS_VOICE, ///< mono, 16bit, 48khz, bitrate dependent on the quality setting, optimized for voice
CODEC_OPUS_MUSIC, ///< stereo, 16bit, 48khz, bitrate dependent on the quality setting, optimized for music
};
enum CodecEncryptionMode
{
CODEC_ENCRYPTION_PER_CHANNEL = 0, ///< voice data encryption decided per channel
CODEC_ENCRYPTION_FORCED_OFF, ///< voice data encryption disabled
CODEC_ENCRYPTION_FORCED_ON, ///< voice data encryption enabled
};
enum TextMessageTargetMode
{
TextMessageTarget_CLIENT = 1, ///< Message is a private message to another client
TextMessageTarget_CHANNEL, ///< Message is sent to a channel, received by all clients in that channel at the time
TextMessageTarget_SERVER, ///< Message is sent to every client on the server
TextMessageTarget_MAX
};
enum MuteInputStatus
{
MUTEINPUT_NONE = 0, ///< Microphone is not muted, audio is sent to the server
MUTEINPUT_MUTED, ///< Microphone is muted, no audio is transmitted to the server
};
enum MuteOutputStatus
{
MUTEOUTPUT_NONE = 0, ///< Speaker is active, server is sending us audio
MUTEOUTPUT_MUTED, ///< Speaker is muted, server is not sending audio to us
};
enum HardwareInputStatus
{
HARDWAREINPUT_DISABLED = 0, ///< no capture device opened
HARDWAREINPUT_ENABLED, ///< capture device open
};
enum HardwareOutputStatus
{
HARDWAREOUTPUT_DISABLED = 0, ///< no playback device opened
HARDWAREOUTPUT_ENABLED, ///< playback device open
};
enum InputDeactivationStatus
{
INPUT_ACTIVE = 0, ///< Audio is captured from the capture device.
INPUT_DEACTIVATED = 1, ///< No audio is captured from the capture device.
};
enum ReasonIdentifier
{
REASON_NONE = 0, ///< no reason data
REASON_MOVED = 1, ///< client was moved
REASON_SUBSCRIPTION = 2, // no reason data
REASON_LOST_CONNECTION = 3, // reasonmsg=reason
REASON_KICK_CHANNEL = 4, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER = 5, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER_BAN = 6, //{SectionInvoker} reasonmsg=reason bantime=time //{SectionInvoker} is only added server->client
REASON_SERVERSTOP = 7, // reasonmsg=reason
REASON_CLIENTDISCONNECT = 8, // reasonmsg=reason
REASON_CHANNELUPDATE = 9, // no reason data
REASON_CHANNELEDIT = 10, //{SectionInvoker}
REASON_CLIENTDISCONNECT_SERVER_SHUTDOWN = 11, // reasonmsg=reason
};
enum Protocol_Encryption_Cipher
{
AES_128 = 0b00000000,
AES_256 = 0b00000001,
PROTOCOL_ENCRYPTION_CIPHER_END_MARKER,
RESERVED = 0b00010000, // reserved until puzzle v2 is fully released, then can be reused
PUZZLE_2 = 0b00100000,
};
enum ChannelProperties
{
CHANNEL_NAME = 0, ///< String. Read/Write. Name of the channel. Always available.
CHANNEL_TOPIC, ///< String. Read/Write. Short single line text describing what the channel is about. Always available.
CHANNEL_DESCRIPTION, ///< String. Read/Write. Arbitrary text (up to 8k bytes) with information about the channel.
///< Must be requested (\ref ts3client_requestChannelDescription)
CHANNEL_PASSWORD, ///< String. Read/Write. Password of the channel. Read access is limited to the server. Clients
///< will only ever see the last password they attempted to use when joining the channel. Always available.
CHANNEL_CODEC, ///< Integer. Read/Write. The codec this channel is using. One of the values from the \ref CodecType
///< enum. Always available.
CHANNEL_CODEC_QUALITY, ///< Integer. Read/Write. The quality setting of the channel. Valid values are 0 to 10 inclusive.
///< Higher value means better voice quality but also more bandwidth usage. Always available.
CHANNEL_MAXCLIENTS, ///< Integer. Read/Write. The number of clients that can be in the channel simultaneously.
///< Always available.
CHANNEL_MAXFAMILYCLIENTS, ///< Integer. Read/Write. The total number of clients that can be in this channel and all
///< sub channels of this channel. Always available.
CHANNEL_ORDER, ///< UInt64. Read/Write. The ID of the channel below which this channel should be displayed. If 0
///< the channel is sorted at the top of the current level. Always available.
CHANNEL_FLAG_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when empty.
///< Permanent channels are stored to the database and available after server restart. SDK
///< users will need to take care of restoring channel at server start on their own.
///< Mutually exclusive with \ref CHANNEL_FLAG_SEMI_PERMANENT. Always available.
CHANNEL_FLAG_SEMI_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when
///< empty. Semi permanent channels are not stored to disk and gone after server
///< restart but remain while empty. Mutually exclusive with \ref
///< CHANNEL_FLAG_PERMANENT. Always available.
CHANNEL_FLAG_DEFAULT, ///< Integer. Read/Write. Boolean (1/0). The default channel is the channel that all clients
///< are located in when they join the server, unless the client explicitly specified a
///< different channel when connecting and is allowed to join their preferred channel. Only
///< one channel on the server can have this flag set. The default channel must have \ref
///< CHANNEL_FLAG_PERMANENT set. Always available.
CHANNEL_FLAG_PASSWORD, ///< Integer. Read/Write. Boolean (1/0) indicating whether this channel is password protected.
///< When removing or setting \ref CHANNEL_PASSWORD you also need to adjust this flag.
CHANNEL_CODEC_LATENCY_FACTOR, ///< (deprecated) Integer. Read/Write. Allows to increase packet size, reducing
///< bandwith at the cost of higher latency of voice transmission. Valid values are
///< 1-10 inclusive. 1 is the default and offers the lowest latency. Always available.
CHANNEL_CODEC_IS_UNENCRYPTED, ///< Integer. Read/Write. Boolean (1/0). If 0 voice data is encrypted, if 1 the voice
///< data is not encrypted. Only used if the server \ref
///< VIRTUALSERVER_CODEC_ENCRYPTION_MODE is set to \ref CODEC_ENCRYPTION_PER_CHANNEL.
///< Always available.
CHANNEL_SECURITY_SALT, ///< String. Read/Write. SDK Only, not used by TeamSpeak. This channels security hash. When
///< a client joins their \ref CLIENT_SECURITY_HASH is compared to this value, to allow or
///< deny the client access to the channel. Used to enforce clients joining the server with
///< specific identity and \ref CLIENT_META_DATA. See SDK Documentation about this feature
///< for further details. Always available.
CHANNEL_DELETE_DELAY, ///< UInt64. Read/Write. Number of seconds deletion of temporary channels is delayed after
///< the last client leaves the channel. Channel is only deleted if empty when the delete
///< delay expired. Always available.
CHANNEL_UNIQUE_IDENTIFIER, ///< String. Read only. An identifier that uniquely identifies a channel. Available in
///< Server >= 3.10.0
CHANNEL_ENDMARKER,
};
enum ClientProperties
{
CLIENT_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Public Identity, can be used to identify a client
///< installation. Remains identical as long as the client keeps using the same
///< identity. Available for visible clients.
CLIENT_NICKNAME, ///< String. Read/Write. Display name of the client. Available for visible clients.
CLIENT_VERSION, ///< String. Read only. Version String of the client used. For clients other than ourself this
///< needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_PLATFORM, ///< String. Read only. Operating system used by the client. For other clients other than ourself
///< this needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_FLAG_TALKING, ///< Integer. Read only. Whether the client is talking. Available on clients that are either
///< whispering to us, or in our channel.
CLIENT_INPUT_MUTED, ///< Integer. Read/Write. Microphone mute status. Available for visible clients. One of the
///< values from the \ref MuteInputStatus enum.
CLIENT_OUTPUT_MUTED, ///< Integer. Read/Write. Speaker mute status. Speaker mute implies microphone mute. Available
///< for visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_OUTPUTONLY_MUTED, ///< Integer. Read/Write. Speaker mute status. Microphone may be active. Available for
///< visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_INPUT_HARDWARE, ///< Integer. Read only. Indicates whether a capture device is open. Available for visible
///< clients. One of the values from the \ref HardwareInputStatus enum.
CLIENT_OUTPUT_HARDWARE, ///< Integer. Read only. Indicates whether a playback device is open. Available for visible
///< clients. One of the values from the \ref HardwareOutputStatus enum.
CLIENT_INPUT_DEACTIVATED, ///< Integer. Read/Write. Not available server side. Local microphone mute status.
///< Available only for own client. Used to implement Push To Talk. One of the values from
///< the \ref InputDeactivationStatus enum.
CLIENT_IDLE_TIME, ///< UInt64. Read only. Seconds since last activity. Available only for own client.
CLIENT_DEFAULT_CHANNEL, ///< String. Read only. User specified channel they joined when connecting to the server.
///< Available only for own client.
CLIENT_DEFAULT_CHANNEL_PASSWORD, ///< String. Read only. User specified channel password for the channel they
///< attempted to join when connecting to the server. Available only for own
///< client.
CLIENT_SERVER_PASSWORD, ///< String. Read only. User specified server password. Available only for own client.
CLIENT_META_DATA, ///< String. Read/Write. Can be used to store up to 4096 bytes of information on clients. Not
///< used by TeamSpeak. Available for visible clients.
CLIENT_IS_MUTED, ///< Integer. Read only. Not available server side. Indicates whether we have muted the client
///< using \ref ts3client_requestMuteClients. Available for visible clients other than ourselves.
CLIENT_IS_RECORDING, ///< Integer. Read only. Indicates whether the client is recording incoming audio. Available
///< for visible clients.
CLIENT_VOLUME_MODIFICATOR, ///< Integer. Read only. Volume adjustment for this client as set by \ref
///< ts3client_setClientVolumeModifier. Available for visible clients.
CLIENT_VERSION_SIGN, ///< String. Read only. TeamSpeak internal signature.
CLIENT_SECURITY_HASH, ///< String. Read/Write. This clients security hash. Not used by TeamSpeak, SDK only. Hash is
///< provided by an outside source. A channel will use the security salt + other client data
///< to calculate a hash, which must be the same as the one provided here. See SDK
///< documentation about Client / Channel Security Hashes for more details.
CLIENT_ENCRYPTION_CIPHERS, ///< String. Read only. SDK only. List of available ciphers this client can use.
CLIENT_IS_STREAMING, ///< bool. Read only, Is currently streaming.
CLIENT_ENDMARKER,
};
enum VirtualServerProperties
{
VIRTUALSERVER_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Unique identifier for a virtual server, does not
///< change on server restart. Available if \ref ts3client_getConnectionStatus
///< is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_NAME, ///< String. Read/Write. The virtual server display name. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_WELCOMEMESSAGE, ///< String. Read/Write. The welcome message displayed to clients on connect.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED. Not
///< updated automatically when changed, updates need to be requested (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_PLATFORM, ///< String. Read only. The operating system the server is running on. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_VERSION, ///< String. Read only. The server software version string. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_MAXCLIENTS, ///< UInt64. Read/Write. The maximum number of clients that can be connected
///< simultaneously. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_PASSWORD, ///< String. Read/Write. The server password. Read access is limited to the server. Clients
///< will only get the password they supplied when connecting. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_CLIENTS_ONLINE, ///< UInt64. Read only. The current number of clients connected to the server,
///< including query connections. Only available on request (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_CHANNELS_ONLINE, ///< UInt64. Read only. The current number of channels on the server. Only
///< available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CREATED, ///< Integer. Read only. The time this virtual server was created as unix timestamp.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_UPTIME, ///< UInt64. Read only. Number of seconds that have passed since the virtual server was
///< started. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CODEC_ENCRYPTION_MODE, ///< Integer. Read/Write. Boolean (1/0) that specifies if voice data is encrypted
///< during transfer. One of the values from the \ref CodecEncryptionMode enum.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_ENCRYPTION_CIPHERS, ///< String. Read/Write. Comma separated list of available ciphers to encrypt the
///< connection. The server will use the first cipher in the list that is also
///< listed in the \ref CLIENT_ENCRYPTION_CIPHERS of the connecting client.
///< Clients will fail to connect if no match is found. Always available.
VIRTUALSERVER_ADDRESS, ///< Any resolvable address for the specific virtual server
VIRTUALSERVER_VERSION_SIGN, ///< String. Read only. Signature of Platform and Version.
VIRTUALSERVER_ENDMARKER,
VIRTUALSERVER_FILEBASE = 24, ///< String. Read only. The path to the base directory used to store files
///< transferred using file transfer. Available only on the server. Is set by \ref
///< ts3server_enableFileManager
VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH = 29, ///< UInt64. Read/Write. Maximum traffic in bytes the server can
///< use for file transfer downloads. Only available on request
///< (\ref ts3client_requestServerVariables).
VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH = 30, ///< UInt64. Read/Write. Maximum traffic in bytes the server can use
///< for file transfer uploads. Only available on request (=>
///< requestServerVariables)
VIRTUALSERVER_LOG_FILETRANSFER = 64 ///< Integer. Read/Write. Boolean (1/0) indicating whether to include file
///< transfer activities (uploading or downloading of files) in the server log.
///< Always available.
};
/**
* Various connection properties.
* These are all read only, and except for your own client must be requested using \ref ts3client_requestConnectionInfo
*/
enum ConnectionProperties
{
CONNECTION_PING = 0, ///< UInt64. Round trip latency for the connection based on the last 5 seconds. On the server
///< this is the average across all connected clients for the last 5 seconds.
CONNECTION_PING_DEVIATION, ///< Double. Standard deviation for the round trip latency in \ref CONNECTION_PING
CONNECTION_CONNECTED_TIME, ///< UInt64. Seconds the client has been connected.
CONNECTION_IDLE_TIME, ///< UInt64. Time in seconds since the last activity (voice transmission, switching channels,
///< changing mic / speaker mute status) of the client.
CONNECTION_CLIENT_IP, ///< String. IP of this client (as seen from the server side)
CONNECTION_CLIENT_PORT, ///< UInt64. Client side port of this client (as seen from the server side)
CONNECTION_SERVER_IP, ///< String. The IP or hostname used to connect to the server. Only available on yourself.
CONNECTION_SERVER_PORT, ///< UInt64. The server port connected to. Only available on yourself.
CONNECTION_PACKETS_SENT_SPEECH, ///< UInt64. The number of voice packets transmitted by the client.
CONNECTION_PACKETS_SENT_KEEPALIVE, ///< UInt64. The number of keep alive packets transmitted by the client.
CONNECTION_PACKETS_SENT_CONTROL, ///< UInt64. The number of command & control packets transmitted by the client.
CONNECTION_PACKETS_SENT_TOTAL, ///< UInt64. Total number of packets transmitted by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_SENT_SPEECH, \ref CONNECTION_PACKETS_SENT_KEEPALIVE and
///< \ref CONNECTION_PACKETS_SENT_CONTROL
CONNECTION_BYTES_SENT_SPEECH, ///< UInt64. Outgoing traffic used for voice data by the client.
CONNECTION_BYTES_SENT_KEEPALIVE, ///< UInt64. Outgoing traffic used for keeping the connection alive by the client.
CONNECTION_BYTES_SENT_CONTROL, ///< UInt64. Outgoing traffic used for command & control data by the client.
CONNECTION_BYTES_SENT_TOTAL, ///< UInt64. Total outgoing traffic to the server by this client. Equal to the sum of
///< \ref CONNECTION_BYTES_SENT_SPEECH, \ref CONNECTION_BYTES_SENT_KEEPALIVE and \ref
///< CONNECTION_BYTES_SENT_CONTROL
CONNECTION_PACKETS_RECEIVED_SPEECH, ///< UInt64. Number of voice packets received by the client.
CONNECTION_PACKETS_RECEIVED_KEEPALIVE, ///< UInt64. Number of keep alive packets received by the client.
CONNECTION_PACKETS_RECEIVED_CONTROL, ///< UInt64. Number of command & control packets received by the client.
CONNECTION_PACKETS_RECEIVED_TOTAL, ///< UInt64. Total number of packets received by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_RECEIVED_SPEECH, \ref
///< CONNECTION_PACKETS_RECEIVED_KEEPALIVE and \ref
///< CONNECTION_PACKETS_RECEIVED_CONTROL
CONNECTION_BYTES_RECEIVED_SPEECH, ///< UInt64. Incoming traffic used by the client for voice data.
CONNECTION_BYTES_RECEIVED_KEEPALIVE, ///< UInt64. Incoming traffic used by the client to keep the connection alive.
CONNECTION_BYTES_RECEIVED_CONTROL, ///< UInt64. Incoming traffic used by the client for command & control data.
CONNECTION_BYTES_RECEIVED_TOTAL, ///< UInt64. Total incoming traffic used by the client. Equal to the sum of \ref
///< CONNECTION_BYTES_RECEIVED_SPEECH, \ref CONNECTION_BYTES_RECEIVED_KEEPALIVE and
///< \ref CONNECTION_BYTES_RECEIVED_CONTROL
CONNECTION_PACKETLOSS_SPEECH, ///< Double. Percentage points of voice packets for the client that did not arrive at
///< the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_KEEPALIVE, ///< Double. Percentage points of keep alive packets for the client that did not
///< arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_CONTROL, ///< Double. Percentage points of command & control packets for the client that did
///< not arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_TOTAL, ///< Double. Cumulative chance in percentage points with which a packet round trip
///< failed because a packet was lost
CONNECTION_SERVER2CLIENT_PACKETLOSS_SPEECH, ///< Double. Probability with which a voice packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< server was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the server was not
///< received by the client.
CONNECTION_CLIENT2SERVER_PACKETLOSS_SPEECH, ///< Double. Probability with which a speech packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< client was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the client was not
///< received by the server.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes sent for speech data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes sent for keepalive data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes sent for control data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes sent in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second sent for speech data, averaged over the
///< last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second sent for keepalive data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second sent for control data, averaged over
///< the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second sent, averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes received for speech data in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes received for keepalive data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes received for control data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes received in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second received for speech data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second received for keepalive data,
///< averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second received for control data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second received, averaged over the last minute.
CONNECTION_DUMMY_0,
CONNECTION_DUMMY_1,
CONNECTION_DUMMY_2,
CONNECTION_DUMMY_3,
CONNECTION_DUMMY_4,
CONNECTION_DUMMY_5,
CONNECTION_DUMMY_6,
CONNECTION_DUMMY_7,
CONNECTION_DUMMY_8,
CONNECTION_DUMMY_9,
CONNECTION_FILETRANSFER_BANDWIDTH_SENT, ///< UInt64. Current file transfer upstream activity in bytes per second.
///< Only available on request (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, ///< UInt64. Current file transfer downstream activity in bytes per
///< second. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, ///< UInt64. Total downstream traffic, in bytes, used for file
///< transfer since the server was started. Only available on request
///< (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, ///< UInt64. Total upstream traffic, in bytes, used for file transfer
///< since the server was started. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_ENDMARKER
};
/**
* Describes a client position in 3 dimensional space, used for 3D Sound.
*/
typedef struct
{
float x; ///< X co-ordinate in 3D space.
float y; ///< Y co-ordinate in 3D space.
float z; ///< Z co-ordinate in 3D space.
} TS3_VECTOR;
enum GroupWhisperType
{
GROUPWHISPERTYPE_SERVERGROUP = 0, ///< Whisper list consists of server groups
GROUPWHISPERTYPE_CHANNELGROUP = 1, ///< Whisper list consists of channel groups
GROUPWHISPERTYPE_CHANNELCOMMANDER = 2, ///< whisper to channel commanders
GROUPWHISPERTYPE_ALLCLIENTS = 3, ///< whisper to all clients
GROUPWHISPERTYPE_ENDMARKER,
};
enum GroupWhisperTargetMode
{
GROUPWHISPERTARGETMODE_ALL = 0,
GROUPWHISPERTARGETMODE_CURRENTCHANNEL = 1, ///< Whisper the current channel of the client
GROUPWHISPERTARGETMODE_PARENTCHANNEL = 2, ///< Whisper the parent channel of whatever channel the client is currently in
GROUPWHISPERTARGETMODE_ALLPARENTCHANNELS = 3, ///< Whipser to the parent channel and all their parent channels as well
GROUPWHISPERTARGETMODE_CHANNELFAMILY = 4, ///< Whisper to the current channel and all its sub channels
GROUPWHISPERTARGETMODE_ANCESTORCHANNELFAMILY = 5, ///< Whisper to the current channel, all its parent and sub channels.
GROUPWHISPERTARGETMODE_SUBCHANNELS = 6, ///< Whisper to all sub channels of the current channel of the client
GROUPWHISPERTARGETMODE_ENDMARKER,
};
enum MonoSoundDestination
{
MONO_SOUND_DESTINATION_ALL = 0, ///< Send mono sound to all available speakers
MONO_SOUND_DESTINATION_FRONT_CENTER = 1, ///< Send mono sound to front center speaker if available
MONO_SOUND_DESTINATION_FRONT_LEFT_AND_RIGHT = 2 ///< Send mono sound to front left/right speakers if available
};
enum SecuritySaltOptions
{
SECURITY_SALT_CHECK_NICKNAME = 1, ///< put nickname into security hash
SECURITY_SALT_CHECK_META_DATA = 2 ///< put meta data into security hash
};
/*this enum is used to disable client commands on the server*/
enum ClientCommand
{
CLIENT_COMMAND_requestConnectionInfo = 0, ///< disable client connection info request (client bandwidth usage, ip,
///< port, ping)
CLIENT_COMMAND_requestClientMove = 1, ///< disable moving clients
CLIENT_COMMAND_requestXXMuteClients = 2, ///< disable muting other clients
CLIENT_COMMAND_requestClientKickFromXXX = 3, ///< disable kicking clients
CLIENT_COMMAND_flushChannelCreation = 4, ///< disable creating channels
CLIENT_COMMAND_flushChannelUpdates = 5, ///< disable editing channels
CLIENT_COMMAND_requestChannelMove = 6, ///< disable moving channels
CLIENT_COMMAND_requestChannelDelete = 7, ///< disable deleting channels
CLIENT_COMMAND_requestChannelDescription = 8, ///< disable channel descriptions
CLIENT_COMMAND_requestChannelXXSubscribeXXX = 9, ///< disable being able to see clients in channels other than the
///< current channel the client is in
CLIENT_COMMAND_requestServerConnectionInfo = 10, ///< disable server connection info request (server bandwidth
///< usage, ip, port, ping)
CLIENT_COMMAND_requestSendXXXTextMsg = 11, ///< disable text messaging
CLIENT_COMMAND_filetransfers = 12, ///< disable file transfer
CLIENT_COMMAND_ENDMARKER
};
/* Access Control List*/
enum ACLType
{
ACL_NONE = 0,
ACL_WHITE_LIST = 1,
ACL_BLACK_LIST = 2
};
/* file transfer actions*/
enum FTAction
{
FT_INIT_SERVER = 0, ///< The virtual server is created. result->channelPath can be changed to create a different
///< directory than the default 'virtualserver_x' where x is the virtual server.
FT_INIT_CHANNEL = 1, ///< A channel is created. result->channelPath can be changed to create a different directory
///< then the default 'channel_x' where x is the channel id.
FT_UPLOAD = 2, ///< A file is being uploaded. All values in the result struct can be modified.
FT_DOWNLOAD = 3, ///< A file is being downloaded. All values in the result struct can be modified.
FT_DELETE = 4, ///< A file is being deleted. All values in the result struct can be modified.
FT_CREATEDIR = 5, ///< A directory is being created in a channel. All values in the result struct can be modified.
FT_RENAME = 6, ///< A file or folder is being renamed. The callback will be called twice! Once for the old and then
///< for the new name. All values in the result struct can be modified.
FT_FILELIST = 7, ///< A directory listing is requested. All values in the result struct can be modified.
FT_FILEINFO = 8 ///< Information of a file is requested. All values in the result struct can be modified.
};
/* file transfer status */
enum FileTransferState
{
FILETRANSFER_INITIALISING = 0, ///< File transfer is establishing connection.
FILETRANSFER_ACTIVE, ///< File transfer is in progress
FILETRANSFER_FINISHED, ///< File transfer has finished
};
/* file transfer types */
enum FileTransferType
{
FileListType_Directory = 0, ///< The file entry is a directory
FileListType_File, ///< The file entry is a regular file
};
/* some structs to handle variables in callbacks */
#define MAX_VARIABLES_EXPORT_COUNT 64
struct VariablesExportItem
{
unsigned char itemIsValid; ///< Whether or not there is any data in this item. Ignore this item if this is 0.
unsigned char proposedIsSet; ///< The value in proposed is set. If 0 ignore proposed
const char* current; ///< current value (stored in memory)
const char* proposed; ///< New value to change to (const, so no updates please)
};
struct VariablesExport
{
struct VariablesExportItem items[MAX_VARIABLES_EXPORT_COUNT];
};
struct ClientMiniExport
{
anyID ID; ///< id of the client
uint64 channel; ///< the channel the client is in
const char* ident; ///< client public identity
const char* nickname; ///< client display name
};
/**
* Structure used to describe a file transfer in the \ref ServerLibFunctions.onTransformFilePath callback.
* This describes the original values, and also contains hints for length limitations of the result parameter
* of the callback.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExport
{
uint64 channel; ///< The channel id of the file. 0 if action is \ref FT_INIT_SERVER
const char* filename; ///< utf8 encoded c string containing the original file name as intended by the client.
int action; ///< The action to be performed. One of the values from the \ref FTAction enum. Defines which values of
///< the result struct can be modified.
int transformedFileNameMaxSize; ///< The maximum length the file name can be rewritten to.
int channelPathMaxSize; ///< The maximum length the path can be rewritten to.
};
/**
* Structure to rewrite the file transfer file name and path in the \ref ServerLibFunctions.onTransformFilePath callback.
* The lengths are limited as described in the original parameter.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExportReturns
{
char* transformedFileName; ///< pointer to target file name. Fill the memory pointed to with an utf8 encoded c string
///< containing the new file name. Limited to original->transformedFileNameMaxSize bytes.
char* channelPath; ///< pointer to memory for new path. Fill the memory pointed to with an utf8 encoded c string
///< containing the new path. Limited to original->channelPathMaxSize bytes.
int logFileAction; ///< boolean (1/0). Whether to log this file transfer to the log. Action is not logged regardless
///< of this value if the servers \ref VIRTUALSERVER_LOG_FILETRANSFER property is 0.
};
struct FileTransferCallbackExport
{
anyID clientID; ///< the client who started the file transfer
anyID transferID; ///< local identifier of the transfer that has completed
anyID remoteTransferID; ///< remote identifier of the transfer that has completed
unsigned int status; ///< status of the transfer. One of the values from the \ref FileTransferState enum
const char* statusMessage; ///< utf8 encoded c string containing a human readable description of the status
uint64 remotefileSize; ///< size in bytes of the complete file to be transferred
uint64 bytes; ///< number of bytes transferred. Same as remotefileSize when the transfer completed entirely.
int isSender; ///< boolean. 1 if the server is sending the file. 0 if the server is receiving the file.
};
/*define for file transfer bandwith limits*/
#define BANDWIDTH_LIMIT_UNLIMITED 0xFFFFFFFFFFFFFFFFll
/*defines for speaker locations used by some sound callbacks*/
#ifndef SPEAKER_FRONT_LEFT
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#endif
#define SPEAKER_HEADPHONES_LEFT 0x10000000
#define SPEAKER_HEADPHONES_RIGHT 0x20000000
#define SPEAKER_MONO 0x40000000
#endif /*PUBLIC_DEFINITIONS_H*/
@@ -0,0 +1,217 @@
#ifndef PUBLIC_ERRORS_H
#define PUBLIC_ERRORS_H
//The idea here is: the values are 2 bytes wide, the first byte identifies the group, the second the count within that group
enum Ts3ErrorType {
//general
ERROR_ok = 0x0000, ///< Indicates success.
ERROR_undefined = 0x0001,
ERROR_not_implemented = 0x0002, ///< The attempted operation is not available in this context
ERROR_ok_no_update = 0x0003, ///< Indicates success, but no change occurred. Returned for example upon flushing (e.g. using \ref ts3client_flushChannelUpdates) when all indicated changes already matched the current state.
ERROR_dont_notify = 0x0004,
ERROR_lib_time_limit_reached = 0x0005,
ERROR_out_of_memory = 0x0006, ///< Not enough system memory to perform operation
ERROR_canceled = 0x0007,
ERROR_ok_no_error_event = 0x0008, ///< Indicates success, but no error event was generated. This is used because of the return code management and reduce packets.
//dunno
ERROR_command_not_found = 0x0100,
ERROR_unable_to_bind_network_port = 0x0101, ///< Unspecified failure to create a listening port
ERROR_no_network_port_available = 0x0102, ///< Failure to initialize a listening port for FileTransfer
ERROR_port_already_in_use = 0x0103, ///< Specified port is already in use by a different application
ERROR_command_line_parse_failed = 0x0104, ///< Command line arguments are invalid
ERROR_command_line_exit_version = 0x0105, ///< Command line specified version. The process should exit with code 0 after printing the version.
ERROR_command_line_exit_help = 0x0106, ///< Command line specified help. The process should exit with code 0 after priting the help.
//client
ERROR_client_invalid_id = 0x0200, ///< Client no longer connected
ERROR_client_nickname_inuse = 0x0201, ///< Client name is already in use. Client names must be unique
ERROR_client_protocol_limit_reached = 0x0203, ///< Too many clients on the server
ERROR_client_invalid_type = 0x0204, ///< Function called for normal clients that is only available for query clients or vice versa
ERROR_client_already_subscribed = 0x0205, ///< Attempting to subscribe to a channel already subscribed to
ERROR_client_not_logged_in = 0x0206,
ERROR_client_could_not_validate_identity = 0x0207, ///< Identity not valid or insufficient security level
ERROR_client_invalid_password = 0x0208,
ERROR_client_version_outdated = 0x020a, ///< Server requires newer client version as determined by the min_client_version properties
ERROR_client_is_flooding = 0x020c, ///< Triggered flood protection. Further information is supplied in the extra message if applicable.
ERROR_client_hacked = 0x020d,
ERROR_client_cannot_verify_now = 0x020e,
ERROR_client_login_not_permitted = 0x020f,
ERROR_client_not_subscribed = 0x0210, ///< Action is only available on subscribed channels
//channel
ERROR_channel_invalid_id = 0x0300, ///< Channel does not exist on the server (any longer)
ERROR_channel_protocol_limit_reached = 0x0301, ///< Too many channels on the server
ERROR_channel_already_in = 0x0302, ///< Attempting to move a client or channel to its current channel
ERROR_channel_name_inuse = 0x0303, ///< Channel name is already taken by another channel. Channel names must be unique
ERROR_channel_not_empty = 0x0304, ///< Attempting to delete a channel with clients or sub channels in it
ERROR_channel_can_not_delete_default = 0x0305, ///< Default channel cannot be deleted. Set a new default channel first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_default_require_permanent = 0x0306, ///< Attempt to set a non permanent channel as default channel. Set channel to permanent first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_invalid_flags = 0x0307, ///< Invalid combination of \ref ChannelProperties, trying to remove \ref CHANNEL_FLAG_DEFAULT or set a password on the default channel
ERROR_channel_parent_not_permanent = 0x0308, ///< Attempt to move a permanent channel into a non-permanent one, or set a channel to be permanent that is a sub channel of a non-permanent one
ERROR_channel_maxclients_reached = 0x0309, ///< Channel is full as determined by its \ref CHANNEL_MAXCLIENTS setting
ERROR_channel_maxfamily_reached = 0x030a, ///< Channel tree is full as determined by its \ref CHANNEL_MAXFAMILYCLIENTS setting
ERROR_channel_invalid_order = 0x030b, ///< Invalid value for the \ref CHANNEL_ORDER property. The specified channel must exist on the server and be on the same level.
ERROR_channel_no_filetransfer_supported = 0x030c, ///< Invalid \ref CHANNEL_FILEPATH set for the channel
ERROR_channel_invalid_password = 0x030d, ///< Channel has a password not matching the password supplied in the call
// used in public_rare_errors = 0x030e,
ERROR_channel_invalid_security_hash = 0x030f,
//server
ERROR_server_invalid_id = 0x0400, ///< Chosen virtual server does not exist or is offline
ERROR_server_running = 0x0401, ///< attempting to delete a server that is running. Stop the server before deleting it.
ERROR_server_is_shutting_down = 0x0402, ///< Client disconnected because the server is going offline
ERROR_server_maxclients_reached = 0x0403, ///< Given in the onConnectStatusChange event when the server has reached its maximum number of clients as defined by the \ref VIRTUALSERVER_MAXCLIENTS property
ERROR_server_invalid_password = 0x0404, ///< Specified server password is wrong. Provide the correct password in the \ref ts3client_startConnection / \ref ts3client_startConnectionWithChannelID call.
ERROR_server_is_virtual = 0x0407, ///< Server is in virtual status. The attempted action is not possible in this state. Start the virtual server first.
ERROR_server_is_not_running = 0x0409, ///< Attempting to stop a server that is not online.
ERROR_server_is_booting = 0x040a, // Not used
ERROR_server_status_invalid = 0x040b,
ERROR_server_version_outdated = 0x040d, ///< Attempt to connect to an outdated server version. The server needs to be updated.
ERROR_server_duplicate_running = 0x040e, ///< This server is already running within the instance. Each virtual server may only exist once.
//parameter
ERROR_parameter_quote = 0x0600, // Not used
ERROR_parameter_invalid_count = 0x0601, ///< Attempt to flush changes without previously calling set*VariableAs* since the last flush
ERROR_parameter_invalid = 0x0602, ///< At least one of the supplied parameters did not meet the criteria for that parameter
ERROR_parameter_not_found = 0x0603, ///< Failure to supply all the necessary parameters
ERROR_parameter_convert = 0x0604, ///< Invalid type supplied for a parameter, such as passing a string (ie. "five") that expects a number.
ERROR_parameter_invalid_size = 0x0605, ///< Value out of allowed range. Such as strings are too long/short or numeric values outside allowed range
ERROR_parameter_missing = 0x0606, ///< Neglecting to specify a required parameter
ERROR_parameter_checksum = 0x0607, ///< Attempting to deploy a modified snapshot
//unsorted, need further investigation
ERROR_vs_critical = 0x0700, ///< Failure to create default channel
ERROR_connection_lost = 0x0701, ///< Generic error with the connection.
ERROR_not_connected = 0x0702, ///< Attempting to call functions with a serverConnectionHandler that is not connected. You can use \ref ts3client_getConnectionStatus to check whether the connection handler is connected to a server
ERROR_no_cached_connection_info = 0x0703, ///< Attempting to query connection information (bandwidth usage, ping, etc) without requesting them first using \ref ts3client_requestConnectionInfo
ERROR_currently_not_possible = 0x0704, ///< Requested information is not currently available. You may have to call \ref ts3client_requestClientVariables or \ref ts3client_requestServerVariables
ERROR_failed_connection_initialisation = 0x0705, ///< No TeamSpeak server running on the specified IP address and port
ERROR_could_not_resolve_hostname = 0x0706, ///< Failure to resolve the specified hostname to an IP address
ERROR_invalid_server_connection_handler_id = 0x0707, ///< Attempting to perform actions on a non-existent server connection handler
ERROR_could_not_initialise_input_manager = 0x0708, // Not used
ERROR_clientlibrary_not_initialised = 0x0709, ///< Calling client library functions without successfully calling \ref ts3client_initClientLib before
ERROR_serverlibrary_not_initialised = 0x070a, ///< Calling server library functions without successfully calling \ref ts3server_initServerLib before
ERROR_whisper_too_many_targets = 0x070b, ///< Using a whisper list that contain more clients than the servers \ref VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE property
ERROR_whisper_no_targets = 0x070c, ///< The active whisper list is empty or no clients matched the whisper list (e.g. all channels in the list are empty)
ERROR_connection_ip_protocol_missing = 0x070d, ///< Invalid or unsupported protocol (e.g. attempting an IPv6 connection on an IPv4 only machine)
ERROR_handshake_failed = 0x070e,
ERROR_illegal_server_license = 0x070f,
//file transfer
ERROR_file_invalid_name = 0x0800, ///< Invalid UTF8 string or not a valid file
ERROR_file_invalid_permissions = 0x0801, ///< Permissions prevent opening the file
ERROR_file_already_exists = 0x0802, ///< Target path already exists as a directory
ERROR_file_not_found = 0x0803, ///< Attempt to access or move non existing file
ERROR_file_io_error = 0x0804, ///< Generic file input / output error
ERROR_file_invalid_transfer_id = 0x0805, ///< Attempt to get information about a file transfer after it has already been cleaned up. File transfer information is not available indefinitely after the transfer completed
ERROR_file_invalid_path = 0x0806, ///< specified path contains invalid characters or does not start with "/"
ERROR_file_no_files_available = 0x0807, // Not used
ERROR_file_overwrite_excludes_resume = 0x0808, ///< File overwrite and resume are mutually exclusive. Only one or neither can be 1.
ERROR_file_invalid_size = 0x0809, ///< Attempt to write more bytes than claimed file size.
ERROR_file_already_in_use = 0x080a, ///< File is currently not available, try again later.
ERROR_file_could_not_open_connection = 0x080b, ///< Generic failure in file transfer connection / other party did not conform to file transfer protocol
ERROR_file_no_space_left_on_device = 0x080c, ///< Operating system reports hard disk is full. May be caused by quota limitations.
ERROR_file_exceeds_file_system_maximum_size = 0x080d, ///< File is too large for the file system of the target device.
ERROR_file_transfer_connection_timeout = 0x080e, // Not used
ERROR_file_connection_lost = 0x080f, ///< File input / output timeout or connection failure
ERROR_file_exceeds_supplied_size = 0x0810, // Not used
ERROR_file_transfer_complete = 0x0811, ///< Indicates successful completion
ERROR_file_transfer_canceled = 0x0812, ///< Transfer was cancelled through @ref ts3client_haltTransfer
ERROR_file_transfer_interrupted = 0x0813, ///< Transfer failed because the server is shutting down, or network connection issues
ERROR_file_transfer_server_quota_exceeded = 0x0814, ///< Transfer terminated due to server bandwidth quota being exceeded. No client can transfer files.
ERROR_file_transfer_client_quota_exceeded = 0x0815, ///< Attempt to transfer more data than allowed by this clients' bandwidth quota. Other clients may continue to transfer files.
ERROR_file_transfer_reset = 0x0816, // Not used
ERROR_file_transfer_limit_reached = 0x0817, ///< Too many file transfers are in progress. Try again later
ERROR_file_invalid_storage_class = 0x0818, // TODO: Invalid storage class for HTTP FileTransfer (what is a storage class?)
ERROR_file_invalid_dimension = 0x0819, ///< Avatar image exceeds maximum width or height accepted by the server.
ERROR_file_transfer_channel_quota_exceeded = 0x081a, ///< Transfer failed because the channel quota was exceeded. Uploading to this channel is not possible, but other channels may be fine.
//sound
ERROR_sound_preprocessor_disabled = 0x0900, ///< Cannot set or query pre processor variables with preprocessing disabled
ERROR_sound_internal_preprocessor = 0x0901,
ERROR_sound_internal_encoder = 0x0902,
ERROR_sound_internal_playback = 0x0903,
ERROR_sound_no_capture_device_available = 0x0904, ///< No audio capture devices are available
ERROR_sound_no_playback_device_available = 0x0905, ///< No audio playback devices are available
ERROR_sound_could_not_open_capture_device = 0x0906, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_could_not_open_playback_device = 0x0907, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_handler_has_device = 0x0908, ///< Attempt to open a sound device on a connection handler which already has an open device. Close the already open device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_invalid_capture_device = 0x0909, ///< Attempt to use a device for capture that does not support capturing audio
ERROR_sound_invalid_playback_device = 0x090a, ///< Attempt to use a device for playback that does not support playback of audio
ERROR_sound_invalid_wave = 0x090b, ///< Attempt to use a non WAV file in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle
ERROR_sound_unsupported_wave = 0x090c, ///< Unsupported wave file used in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle.
ERROR_sound_open_wave = 0x090d, ///< Failure to open the specified sound file
ERROR_sound_internal_capture = 0x090e,
ERROR_sound_device_in_use = 0x090f, ///< Attempt to unregister a custom device that is being used. Close the device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_device_already_registerred = 0x0910, ///< Attempt to register a custom device with a device id that has already been used in a previous call. Device ids must be unique.
ERROR_sound_unknown_device = 0x0911, ///< Attempt to open, close, unregister or use a device which is not known. Custom devices must be registered before being used (see \ref ts3client_registerCustomDevice)
ERROR_sound_unsupported_frequency = 0x0912,
ERROR_sound_invalid_channel_count = 0x0913, ///< Invalid device audio channel count, must be > 0
ERROR_sound_read_wave = 0x0914, ///< Failure to read sound samples from an opened wave file. Is this a valid wave file?
ERROR_sound_need_more_data = 0x0915, // for internal purposes only
ERROR_sound_device_busy = 0x0916, // for internal purposes only
ERROR_sound_no_data = 0x0917, ///< Indicates there is currently no data for playback, e.g. nobody is speaking right now.
ERROR_sound_channel_mask_mismatch = 0x0918, ///< Opening a device with an unsupported channel count
//permissions
ERROR_permissions_client_insufficient = 0x0a08, ///< Not enough permissions to perform the requested activity
ERROR_permissions = 0x0a0c, ///< Permissions to use sound device not granted by operating system, e.g. Windows denied microphone access.
//accounting
ERROR_accounting_virtualserver_limit_reached = 0x0b00, ///< Attempt to use more virtual servers than allowed by the license
ERROR_accounting_slot_limit_reached = 0x0b01, ///< Attempt to set more slots than allowed by the license
ERROR_accounting_license_file_not_found = 0x0b02, // Not used
ERROR_accounting_license_date_not_ok = 0x0b03, ///< License expired or not valid yet
ERROR_accounting_unable_to_connect_to_server = 0x0b04, ///< Failure to communicate with accounting backend
ERROR_accounting_unknown_error = 0x0b05, ///< Failure to write update license file
ERROR_accounting_server_error = 0x0b06, // Not used
ERROR_accounting_instance_limit_reached = 0x0b07, ///< More than one process of the server is running
ERROR_accounting_instance_check_error = 0x0b08, ///< Shared memory access failure.
ERROR_accounting_license_file_invalid = 0x0b09, ///< License is not a TeamSpeak license
ERROR_accounting_running_elsewhere = 0x0b0a, ///< A copy of this server is already running in another instance. Each server may only exist once.
ERROR_accounting_instance_duplicated = 0x0b0b, ///< A copy of this server is running already in this process. Each server may only exist once.
ERROR_accounting_already_started = 0x0b0c, ///< Attempt to start a server that is already running
ERROR_accounting_not_started = 0x0b0d,
ERROR_accounting_to_many_starts = 0x0b0e, ///< Starting instance / virtual servers too often in too short a time period
//provisioning server
/// @cond HAS_PROVISIONING
ERROR_provisioning_invalid_password = 0x1100,
ERROR_provisioning_invalid_request = 0x1101,
ERROR_provisioning_no_slots_available = 0x1102,
ERROR_provisioning_pool_missing = 0x1103,
ERROR_provisioning_pool_unknown = 0x1104,
ERROR_provisioning_unknown_ip_location = 0x1105,
ERROR_provisioning_internal_tries_exceeded = 0x1106,
ERROR_provisioning_too_many_slots_requested = 0x1107,
ERROR_provisioning_too_many_reserved = 0x1108,
ERROR_provisioning_could_not_connect = 0x1109,
ERROR_provisioning_auth_server_not_connected = 0x1110,
ERROR_provisioning_auth_data_too_large = 0x1111,
ERROR_provisioning_already_initialized = 0x1112,
ERROR_provisioning_not_initialized = 0x1113,
ERROR_provisioning_connecting = 0x1114,
ERROR_provisioning_already_connected = 0x1115,
ERROR_provisioning_not_connected = 0x1116,
ERROR_provisioning_io_error = 0x1117,
ERROR_provisioning_invalid_timeout = 0x1118,
ERROR_provisioning_ts3server_not_found = 0x1119,
ERROR_provisioning_no_permission = 0x111A,
/// @endcond
// 0x12 - 0x15 are reserved in rare
// screen share
ERROR_already_registered = 0x1600,
ERROR_stream_session_limit_reached = 0x1601,
ERROR_stream_session_not_found = 0x1602,
ERROR_stream_unknown = 0x1603,
ERROR_stream_not_participating = 0x1604,
ERROR_not_streamer = 0x1605,
ERROR_already_joined = 0x1606,
ERROR_join_request_not_found = 0x1607,
ERROR_sfu_failed_to_start = 0x1608,
};
#endif
@@ -0,0 +1,236 @@
#ifndef TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#define TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Version definitions.
#define TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1 1
// Protocol used for communication between the session subscriber and the session (a single stream).
// Commands are sent bidirectionally or unidirectionally between the parties.
// e.g. SESSION => SUBSCRIBER: ON_FRAME, ON_PAUSED_CHANGED
// e.g. SUBSCRIBER => SESSION: ON_FRAME_ACK, ON_RESIZE
// Command type enum with a lowercase type name.
typedef enum
{
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME = 0,
TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE,
TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED,
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK,
TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP,
TS_SESSION_SUBSCRIBER_CMD_REMOVE_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED,
} ts_session_subscriber_command_type_t;
// Pixel format enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_I420 = 0,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_NV12,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ABGR,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ARGB,
} ts_session_subscriber_pixel_format_t;
// Buffer location enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_CPU = 0,
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_GPU
} ts_session_subscriber_buffer_location_t;
// Buffer type enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_SINGLE = 0,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_MAIN,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_SUB
} ts_session_subscriber_buffer_type_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(push, 4)
#endif
// Main buffer header for shared CPU Memory Front/Back Buffers.
// The Main Buffer contains metadata about the current front/back buffer and the versioning for both the main and sub buffer.
// The information from the main buffer can be used to always read the front buffer.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t front_buffer_index; // index of the front buffer. (0: main buffer, 1: sub buffer)
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_main_buffer_header_t;
// Sub buffer header.
typedef struct
{
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
} ts_session_subscriber_sub_buffer_header_t;
// Single frame buffer header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_single_frame_buffer_header_t;
// Command header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // Total message length (header + payload).
ts_session_subscriber_command_type_t type;
uint64_t target_session_id; // always set to the target session id this command is for or is originating from.
uint64_t target_subscriber_id; // 0 if broadcast.
} ts_session_subscriber_command_header_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME.
// The frame data is not included in the message, but is attached seperately or was sent beforehand. The buffer is identified by it's id.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_id; // buffer id, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_frame_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t frame_id;
} ts_session_subscriber_on_frame_ack_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE.
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t width;
uint32_t height;
} ts_session_subscriber_on_resize_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t paused; // 0 or 1.
} ts_session_subscriber_on_paused_changed_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE.
// Contains a single frame buffer. The header is of format |ts_session_subscriber_single_frame_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
ts_session_subscriber_buffer_type_t buffer_type;
} ts_session_subscriber_on_buffer_single_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK.
// Contains a main buffer and a sub buffer. The main buffer header
// contains metadata about the current front/back buffer and
// is of type |ts_session_subscriber_main_buffer_header_t|.
// The sub buffer's header is of type |ts_session_subscriber_sub_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t main_buffer_ptr; // main buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t main_buffer_length;
uint64_t sub_buffer_ptr; // sub buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t sub_buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
} ts_session_subscriber_on_buffer_front_back_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER.
// SUBSCRIBER => SESSION.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_resp_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_release_buffer_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr;
int bits_per_sample;
int sample_rate;
uint32_t number_of_channels;
uint32_t number_of_frames;
int64_t absolute_capture_timestamp_ms;
float volume;
} ts_session_subscriber_on_audio_frames_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t audio_enabled;
} ts_session_subscriber_on_audio_enabled_changed_payload_t;
// Overall Command structure.
typedef struct
{
ts_session_subscriber_command_header_t header;
union
{
ts_session_subscriber_on_frame_payload_t frame;
ts_session_subscriber_on_resize_payload_t resize;
ts_session_subscriber_on_paused_changed_payload_t paused;
ts_session_subscriber_on_frame_ack_payload_t frame_ack;
ts_session_subscriber_on_buffer_single_payload_t buffer_single;
ts_session_subscriber_on_buffer_front_back_payload_t buffer_front_back;
ts_session_subscriber_on_release_buffer_payload_t release_buffer;
ts_session_subscriber_add_subscriber_payload_t add_subscriber;
ts_session_subscriber_add_subscriber_resp_payload_t add_subscriber_resp;
ts_session_subscriber_on_audio_frames_payload_t audio_frames;
ts_session_subscriber_on_audio_enabled_changed_payload_t audio_enabled_changed;
} payload;
} ts_session_subscriber_command_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif // TS_SESSION_SUBSCRIBER_PROTOCOL_H_
@@ -0,0 +1,29 @@
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was team_clientConfig.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()
####################################################################################
include("${CMAKE_CURRENT_LIST_DIR}/team_clientTargets.cmake")
check_required_components(team_client)
@@ -0,0 +1,19 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "teamspeak::client" for configuration "Release"
set_property(TARGET teamspeak::client APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(teamspeak::client PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.dylib"
IMPORTED_SONAME_RELEASE "@rpath/libteamspeak_sdk_client.dylib"
)
list(APPEND _cmake_import_check_targets teamspeak::client )
list(APPEND _cmake_import_check_files_for_teamspeak::client "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.dylib" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
@@ -0,0 +1,121 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.3")
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.3...4.0)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS teamspeak::client)
list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
if(TARGET "${_cmake_expected_target}")
list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
else()
list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
unset(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target teamspeak::client
add_library(teamspeak::client SHARED IMPORTED)
set_target_properties(teamspeak::client PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
if(NOT CMAKE_VERSION VERSION_LESS "3.23.0")
target_sources(teamspeak::client
INTERFACE
FILE_SET "public_headers"
TYPE "HEADERS"
BASE_DIRS "${_IMPORT_PREFIX}/include"
FILES "${_IMPORT_PREFIX}/include/teamspeak/clientlib.h" "${_IMPORT_PREFIX}/include/teamspeak/clientlib_sdk.h" "${_IMPORT_PREFIX}/include/teamspeak/video/session_subscriber_protocol.h"
)
else()
set_property(TARGET teamspeak::client
APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
"${_IMPORT_PREFIX}/include"
)
endif()
# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/team_clientTargets-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
if(CMAKE_VERSION VERSION_LESS "3.28"
OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target}
OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}")
foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
if(NOT EXISTS "${_cmake_file}")
message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
\"${_cmake_file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
endif()
unset(_cmake_file)
unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
@@ -0,0 +1,23 @@
#ifndef TEAMLOG_LOGTYPES_H
#define TEAMLOG_LOGTYPES_H
enum LogTypes {
LogType_NONE = 0x0000, ///< Logging is disabled
LogType_FILE = 0x0001, ///< Log to regular log file
LogType_CONSOLE = 0x0002, ///< Log to standard output / error
LogType_USERLOGGING = 0x0004, ///< User defined logging. Will call the \ref ServerLibFunctions.onUserLoggingMessageEvent callback for every message to be logged
LogType_NO_NETLOGGING = 0x0008, ///< Not used
LogType_DATABASE = 0x0010, ///< Log to database (deprecated, server only, no effect in SDK)
LogType_SYSLOG = 0x0020, ///< Log to syslog (only available on Linux)
};
enum LogLevel {
LogLevel_CRITICAL = 0, ///< these messages stop the program
LogLevel_ERROR, ///< everything that is really bad, but not so bad we need to shut down
LogLevel_WARNING, ///< everything that *might* be bad
LogLevel_DEBUG, ///< output that might help find a problem
LogLevel_INFO, ///< informational output, like "starting database version x.y.z"
LogLevel_DEVEL ///< developer only output (will not be displayed in release mode)
};
#endif //TEAMLOG_LOGTYPES_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,58 @@
#ifndef CLIENTLIB_SDK_H
#define CLIENTLIB_SDK_H
// system
#include <stdlib.h>
// own
#include "teamspeak/public_definitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets the client to which to transmit voice. Stops standard channel voice transmission.
*
* The client will still receive voice from their current channel, however their voice will not be transmitted to their
* current channel anymore. If this call is successful (check onServerErrorEvent) then voice of the specified client
* will be transmitted to all specified channels and all the specified clients. Pass 0 to both target parameter arrays
* to restore default behavior of transmitting voice to current channel. You will receive an onServerErrorEvent with the
* passed returnCode indicating whether or not the operation was successful.
*
* @param server_connection_handler_id the connection handler on which to set the whisper list
* @param client_id the client to set the whisper list for. Set to 0 or your own client ID to set your own whisper list.
* @param channel_ids an array of channel ids to transmit voice to.
* @param channel_ids_size number of elements in aforementioned array.
* @param client_ids a zero terminated array of client ids to transmit voice to.
* @param client_ids_size number of elements in aforementioned array.
* @param impersonate if the target client is a webrtc client, the voice packets will look like as if they have been
* send by the invoking client id
* @param return_code a c string to identify this request in callbacks. Pass an empty string if unused.
* @return An error code from the @ref Ts3ErrorType enum indicating either success or the failure reason
*/
EXPORTDLL unsigned int ts_client_request_client_set_whisper_list(uint64 server_connection_handler_id, anyID client_id,
const uint64* channel_ids,
int channel_ids_size,
const anyID* client_ids,
int client_ids_size, int impersonate,
const char* return_code);
/**
* @brief Send a binary-serialized ClientCommandRequest protobuf to the client library.
*
* The response will be delivered asynchronously via the onProtoResponse callback
* as a serialized ClientCommandResponse protobuf.
*
* @param data Pointer to serialized ClientCommandRequest protobuf bytes
* @param size Size of the serialized data in bytes
* @param return_code Caller-provided string to correlate the response in onProtoResponse. May be NULL.
* @return An error code: ERROR_ok on successful dispatch, ERROR_parameter_invalid on parse failure
*/
EXPORTDLL unsigned int ts3client_postProtoCommand(const void* data, size_t size, const char* return_code);
#ifdef __cplusplus
}
#endif
#endif // CLIENTLIB_SDK_H
@@ -0,0 +1,635 @@
#ifndef PUBLIC_DEFINITIONS_H
#define PUBLIC_DEFINITIONS_H
#include "teamlog/logtypes.h"
#define TS3_MAX_SIZE_CHANNEL_NAME 40 // channel name maximum length in characters
#define TS3_MAX_SIZE_VIRTUALSERVER_NAME 64 // virtual server name maximum length in characters
#define TS3_MAX_SIZE_CLIENT_NICKNAME 64 // client display name length limit in characters
#define TS3_MIN_SIZE_CLIENT_NICKNAME 3 // client display name minimum length in characters
#define TS3_MAX_SIZE_REASON_MESSAGE 80 // length limit in characters for kick, move, etc reasons
#define TS3_MAX_SIZE_TEXTMESSAGE 8192 // text message length limit, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_TOPIC 255 // channel topic lengt limith, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_DESCRIPTION 8192 // channel description length limit, measured in bytes (utf8 encoded)
// server welcome message length limit measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_VIRTUALSERVER_WELCOMEMESSAGE 1024
#define TS3_SIZE_MYTSID 44
// minimum amount of seconds before a clientID that was in use can be assigned to a new client
#define TS3_MIN_SECONDS_CLIENTID_REUSE 300
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32)
typedef unsigned __int16 anyID;
typedef unsigned __int64 uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __declspec(dllexport)
#else
#define EXPORTDLL
#endif
#endif
#else
#include <stdint.h>
typedef uint16_t anyID;
typedef uint64_t uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __attribute__((visibility("default")))
#else
#define EXPORTDLL
#endif
#endif
#endif
enum Visibility
{
ENTER_VISIBILITY = 0, ///< Client joined from an unsubscribed channel, or joined the server.
RETAIN_VISIBILITY, ///< Client switched from one subscribed channel to a different subscribed channel.
LEAVE_VISIBILITY ///< Client switches to an unsubscribed channel, or disconnected from server.
};
enum ConnectStatus
{
STATUS_DISCONNECTED = 0, ///< There is no activity to the server, this is the default value
STATUS_CONNECTING, ///< We are trying to connect, we haven't got a client id yet, we haven't been accepted by the server
STATUS_CONNECTED, ///< The server has accepted us, we can talk and hear and we have a client id, but we don't
///< have the channels and clients yet, we can get server infos (welcome msg etc.)
STATUS_CONNECTION_ESTABLISHING, ///< we are connected and we are visible
STATUS_CONNECTION_ESTABLISHED, ///< we are connected and we have the client and channels available
};
enum LocalTestMode
{
TEST_MODE_OFF = 0,
TEST_MODE_VOICE_LOCAL_ONLY,
TEST_MODE_VOICE_LOCAL_AND_REMOTE,
TEST_MODE_TALK_STATUS_CHANGES_ONLY
};
enum TalkStatus
{
STATUS_NOT_TALKING = 0, ///< client is not talking
STATUS_TALKING = 1, ///< client is talking
STATUS_TALKING_WHILE_DISABLED = 2, ///< client is talking while the microphone is muted (only valid for own client)
};
enum CodecType
{
CODEC_SPEEX_NARROWBAND = 0, ///< (deprecated) mono, 16bit, 8kHz, bitrate dependent on the quality setting
CODEC_SPEEX_WIDEBAND, ///< (deprecated) mono, 16bit, 16kHz, bitrate dependent on the quality setting
CODEC_SPEEX_ULTRAWIDEBAND, ///< (deprecated) mono, 16bit, 32kHz, bitrate dependent on the quality setting
CODEC_CELT_MONO, ///< (deprecated) mono, 16bit, 48kHz, bitrate dependent on the quality setting
CODEC_OPUS_VOICE, ///< mono, 16bit, 48khz, bitrate dependent on the quality setting, optimized for voice
CODEC_OPUS_MUSIC, ///< stereo, 16bit, 48khz, bitrate dependent on the quality setting, optimized for music
};
enum CodecEncryptionMode
{
CODEC_ENCRYPTION_PER_CHANNEL = 0, ///< voice data encryption decided per channel
CODEC_ENCRYPTION_FORCED_OFF, ///< voice data encryption disabled
CODEC_ENCRYPTION_FORCED_ON, ///< voice data encryption enabled
};
enum TextMessageTargetMode
{
TextMessageTarget_CLIENT = 1, ///< Message is a private message to another client
TextMessageTarget_CHANNEL, ///< Message is sent to a channel, received by all clients in that channel at the time
TextMessageTarget_SERVER, ///< Message is sent to every client on the server
TextMessageTarget_MAX
};
enum MuteInputStatus
{
MUTEINPUT_NONE = 0, ///< Microphone is not muted, audio is sent to the server
MUTEINPUT_MUTED, ///< Microphone is muted, no audio is transmitted to the server
};
enum MuteOutputStatus
{
MUTEOUTPUT_NONE = 0, ///< Speaker is active, server is sending us audio
MUTEOUTPUT_MUTED, ///< Speaker is muted, server is not sending audio to us
};
enum HardwareInputStatus
{
HARDWAREINPUT_DISABLED = 0, ///< no capture device opened
HARDWAREINPUT_ENABLED, ///< capture device open
};
enum HardwareOutputStatus
{
HARDWAREOUTPUT_DISABLED = 0, ///< no playback device opened
HARDWAREOUTPUT_ENABLED, ///< playback device open
};
enum InputDeactivationStatus
{
INPUT_ACTIVE = 0, ///< Audio is captured from the capture device.
INPUT_DEACTIVATED = 1, ///< No audio is captured from the capture device.
};
enum ReasonIdentifier
{
REASON_NONE = 0, ///< no reason data
REASON_MOVED = 1, ///< client was moved
REASON_SUBSCRIPTION = 2, // no reason data
REASON_LOST_CONNECTION = 3, // reasonmsg=reason
REASON_KICK_CHANNEL = 4, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER = 5, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER_BAN = 6, //{SectionInvoker} reasonmsg=reason bantime=time //{SectionInvoker} is only added server->client
REASON_SERVERSTOP = 7, // reasonmsg=reason
REASON_CLIENTDISCONNECT = 8, // reasonmsg=reason
REASON_CHANNELUPDATE = 9, // no reason data
REASON_CHANNELEDIT = 10, //{SectionInvoker}
REASON_CLIENTDISCONNECT_SERVER_SHUTDOWN = 11, // reasonmsg=reason
};
enum Protocol_Encryption_Cipher
{
AES_128 = 0b00000000,
AES_256 = 0b00000001,
PROTOCOL_ENCRYPTION_CIPHER_END_MARKER,
RESERVED = 0b00010000, // reserved until puzzle v2 is fully released, then can be reused
PUZZLE_2 = 0b00100000,
};
enum ChannelProperties
{
CHANNEL_NAME = 0, ///< String. Read/Write. Name of the channel. Always available.
CHANNEL_TOPIC, ///< String. Read/Write. Short single line text describing what the channel is about. Always available.
CHANNEL_DESCRIPTION, ///< String. Read/Write. Arbitrary text (up to 8k bytes) with information about the channel.
///< Must be requested (\ref ts3client_requestChannelDescription)
CHANNEL_PASSWORD, ///< String. Read/Write. Password of the channel. Read access is limited to the server. Clients
///< will only ever see the last password they attempted to use when joining the channel. Always available.
CHANNEL_CODEC, ///< Integer. Read/Write. The codec this channel is using. One of the values from the \ref CodecType
///< enum. Always available.
CHANNEL_CODEC_QUALITY, ///< Integer. Read/Write. The quality setting of the channel. Valid values are 0 to 10 inclusive.
///< Higher value means better voice quality but also more bandwidth usage. Always available.
CHANNEL_MAXCLIENTS, ///< Integer. Read/Write. The number of clients that can be in the channel simultaneously.
///< Always available.
CHANNEL_MAXFAMILYCLIENTS, ///< Integer. Read/Write. The total number of clients that can be in this channel and all
///< sub channels of this channel. Always available.
CHANNEL_ORDER, ///< UInt64. Read/Write. The ID of the channel below which this channel should be displayed. If 0
///< the channel is sorted at the top of the current level. Always available.
CHANNEL_FLAG_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when empty.
///< Permanent channels are stored to the database and available after server restart. SDK
///< users will need to take care of restoring channel at server start on their own.
///< Mutually exclusive with \ref CHANNEL_FLAG_SEMI_PERMANENT. Always available.
CHANNEL_FLAG_SEMI_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when
///< empty. Semi permanent channels are not stored to disk and gone after server
///< restart but remain while empty. Mutually exclusive with \ref
///< CHANNEL_FLAG_PERMANENT. Always available.
CHANNEL_FLAG_DEFAULT, ///< Integer. Read/Write. Boolean (1/0). The default channel is the channel that all clients
///< are located in when they join the server, unless the client explicitly specified a
///< different channel when connecting and is allowed to join their preferred channel. Only
///< one channel on the server can have this flag set. The default channel must have \ref
///< CHANNEL_FLAG_PERMANENT set. Always available.
CHANNEL_FLAG_PASSWORD, ///< Integer. Read/Write. Boolean (1/0) indicating whether this channel is password protected.
///< When removing or setting \ref CHANNEL_PASSWORD you also need to adjust this flag.
CHANNEL_CODEC_LATENCY_FACTOR, ///< (deprecated) Integer. Read/Write. Allows to increase packet size, reducing
///< bandwith at the cost of higher latency of voice transmission. Valid values are
///< 1-10 inclusive. 1 is the default and offers the lowest latency. Always available.
CHANNEL_CODEC_IS_UNENCRYPTED, ///< Integer. Read/Write. Boolean (1/0). If 0 voice data is encrypted, if 1 the voice
///< data is not encrypted. Only used if the server \ref
///< VIRTUALSERVER_CODEC_ENCRYPTION_MODE is set to \ref CODEC_ENCRYPTION_PER_CHANNEL.
///< Always available.
CHANNEL_SECURITY_SALT, ///< String. Read/Write. SDK Only, not used by TeamSpeak. This channels security hash. When
///< a client joins their \ref CLIENT_SECURITY_HASH is compared to this value, to allow or
///< deny the client access to the channel. Used to enforce clients joining the server with
///< specific identity and \ref CLIENT_META_DATA. See SDK Documentation about this feature
///< for further details. Always available.
CHANNEL_DELETE_DELAY, ///< UInt64. Read/Write. Number of seconds deletion of temporary channels is delayed after
///< the last client leaves the channel. Channel is only deleted if empty when the delete
///< delay expired. Always available.
CHANNEL_UNIQUE_IDENTIFIER, ///< String. Read only. An identifier that uniquely identifies a channel. Available in
///< Server >= 3.10.0
CHANNEL_ENDMARKER,
};
enum ClientProperties
{
CLIENT_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Public Identity, can be used to identify a client
///< installation. Remains identical as long as the client keeps using the same
///< identity. Available for visible clients.
CLIENT_NICKNAME, ///< String. Read/Write. Display name of the client. Available for visible clients.
CLIENT_VERSION, ///< String. Read only. Version String of the client used. For clients other than ourself this
///< needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_PLATFORM, ///< String. Read only. Operating system used by the client. For other clients other than ourself
///< this needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_FLAG_TALKING, ///< Integer. Read only. Whether the client is talking. Available on clients that are either
///< whispering to us, or in our channel.
CLIENT_INPUT_MUTED, ///< Integer. Read/Write. Microphone mute status. Available for visible clients. One of the
///< values from the \ref MuteInputStatus enum.
CLIENT_OUTPUT_MUTED, ///< Integer. Read/Write. Speaker mute status. Speaker mute implies microphone mute. Available
///< for visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_OUTPUTONLY_MUTED, ///< Integer. Read/Write. Speaker mute status. Microphone may be active. Available for
///< visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_INPUT_HARDWARE, ///< Integer. Read only. Indicates whether a capture device is open. Available for visible
///< clients. One of the values from the \ref HardwareInputStatus enum.
CLIENT_OUTPUT_HARDWARE, ///< Integer. Read only. Indicates whether a playback device is open. Available for visible
///< clients. One of the values from the \ref HardwareOutputStatus enum.
CLIENT_INPUT_DEACTIVATED, ///< Integer. Read/Write. Not available server side. Local microphone mute status.
///< Available only for own client. Used to implement Push To Talk. One of the values from
///< the \ref InputDeactivationStatus enum.
CLIENT_IDLE_TIME, ///< UInt64. Read only. Seconds since last activity. Available only for own client.
CLIENT_DEFAULT_CHANNEL, ///< String. Read only. User specified channel they joined when connecting to the server.
///< Available only for own client.
CLIENT_DEFAULT_CHANNEL_PASSWORD, ///< String. Read only. User specified channel password for the channel they
///< attempted to join when connecting to the server. Available only for own
///< client.
CLIENT_SERVER_PASSWORD, ///< String. Read only. User specified server password. Available only for own client.
CLIENT_META_DATA, ///< String. Read/Write. Can be used to store up to 4096 bytes of information on clients. Not
///< used by TeamSpeak. Available for visible clients.
CLIENT_IS_MUTED, ///< Integer. Read only. Not available server side. Indicates whether we have muted the client
///< using \ref ts3client_requestMuteClients. Available for visible clients other than ourselves.
CLIENT_IS_RECORDING, ///< Integer. Read only. Indicates whether the client is recording incoming audio. Available
///< for visible clients.
CLIENT_VOLUME_MODIFICATOR, ///< Integer. Read only. Volume adjustment for this client as set by \ref
///< ts3client_setClientVolumeModifier. Available for visible clients.
CLIENT_VERSION_SIGN, ///< String. Read only. TeamSpeak internal signature.
CLIENT_SECURITY_HASH, ///< String. Read/Write. This clients security hash. Not used by TeamSpeak, SDK only. Hash is
///< provided by an outside source. A channel will use the security salt + other client data
///< to calculate a hash, which must be the same as the one provided here. See SDK
///< documentation about Client / Channel Security Hashes for more details.
CLIENT_ENCRYPTION_CIPHERS, ///< String. Read only. SDK only. List of available ciphers this client can use.
CLIENT_IS_STREAMING, ///< bool. Read only, Is currently streaming.
CLIENT_ENDMARKER,
};
enum VirtualServerProperties
{
VIRTUALSERVER_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Unique identifier for a virtual server, does not
///< change on server restart. Available if \ref ts3client_getConnectionStatus
///< is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_NAME, ///< String. Read/Write. The virtual server display name. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_WELCOMEMESSAGE, ///< String. Read/Write. The welcome message displayed to clients on connect.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED. Not
///< updated automatically when changed, updates need to be requested (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_PLATFORM, ///< String. Read only. The operating system the server is running on. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_VERSION, ///< String. Read only. The server software version string. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_MAXCLIENTS, ///< UInt64. Read/Write. The maximum number of clients that can be connected
///< simultaneously. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_PASSWORD, ///< String. Read/Write. The server password. Read access is limited to the server. Clients
///< will only get the password they supplied when connecting. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_CLIENTS_ONLINE, ///< UInt64. Read only. The current number of clients connected to the server,
///< including query connections. Only available on request (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_CHANNELS_ONLINE, ///< UInt64. Read only. The current number of channels on the server. Only
///< available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CREATED, ///< Integer. Read only. The time this virtual server was created as unix timestamp.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_UPTIME, ///< UInt64. Read only. Number of seconds that have passed since the virtual server was
///< started. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CODEC_ENCRYPTION_MODE, ///< Integer. Read/Write. Boolean (1/0) that specifies if voice data is encrypted
///< during transfer. One of the values from the \ref CodecEncryptionMode enum.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_ENCRYPTION_CIPHERS, ///< String. Read/Write. Comma separated list of available ciphers to encrypt the
///< connection. The server will use the first cipher in the list that is also
///< listed in the \ref CLIENT_ENCRYPTION_CIPHERS of the connecting client.
///< Clients will fail to connect if no match is found. Always available.
VIRTUALSERVER_ADDRESS, ///< Any resolvable address for the specific virtual server
VIRTUALSERVER_VERSION_SIGN, ///< String. Read only. Signature of Platform and Version.
VIRTUALSERVER_ENDMARKER,
VIRTUALSERVER_FILEBASE = 24, ///< String. Read only. The path to the base directory used to store files
///< transferred using file transfer. Available only on the server. Is set by \ref
///< ts3server_enableFileManager
VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH = 29, ///< UInt64. Read/Write. Maximum traffic in bytes the server can
///< use for file transfer downloads. Only available on request
///< (\ref ts3client_requestServerVariables).
VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH = 30, ///< UInt64. Read/Write. Maximum traffic in bytes the server can use
///< for file transfer uploads. Only available on request (=>
///< requestServerVariables)
VIRTUALSERVER_LOG_FILETRANSFER = 64 ///< Integer. Read/Write. Boolean (1/0) indicating whether to include file
///< transfer activities (uploading or downloading of files) in the server log.
///< Always available.
};
/**
* Various connection properties.
* These are all read only, and except for your own client must be requested using \ref ts3client_requestConnectionInfo
*/
enum ConnectionProperties
{
CONNECTION_PING = 0, ///< UInt64. Round trip latency for the connection based on the last 5 seconds. On the server
///< this is the average across all connected clients for the last 5 seconds.
CONNECTION_PING_DEVIATION, ///< Double. Standard deviation for the round trip latency in \ref CONNECTION_PING
CONNECTION_CONNECTED_TIME, ///< UInt64. Seconds the client has been connected.
CONNECTION_IDLE_TIME, ///< UInt64. Time in seconds since the last activity (voice transmission, switching channels,
///< changing mic / speaker mute status) of the client.
CONNECTION_CLIENT_IP, ///< String. IP of this client (as seen from the server side)
CONNECTION_CLIENT_PORT, ///< UInt64. Client side port of this client (as seen from the server side)
CONNECTION_SERVER_IP, ///< String. The IP or hostname used to connect to the server. Only available on yourself.
CONNECTION_SERVER_PORT, ///< UInt64. The server port connected to. Only available on yourself.
CONNECTION_PACKETS_SENT_SPEECH, ///< UInt64. The number of voice packets transmitted by the client.
CONNECTION_PACKETS_SENT_KEEPALIVE, ///< UInt64. The number of keep alive packets transmitted by the client.
CONNECTION_PACKETS_SENT_CONTROL, ///< UInt64. The number of command & control packets transmitted by the client.
CONNECTION_PACKETS_SENT_TOTAL, ///< UInt64. Total number of packets transmitted by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_SENT_SPEECH, \ref CONNECTION_PACKETS_SENT_KEEPALIVE and
///< \ref CONNECTION_PACKETS_SENT_CONTROL
CONNECTION_BYTES_SENT_SPEECH, ///< UInt64. Outgoing traffic used for voice data by the client.
CONNECTION_BYTES_SENT_KEEPALIVE, ///< UInt64. Outgoing traffic used for keeping the connection alive by the client.
CONNECTION_BYTES_SENT_CONTROL, ///< UInt64. Outgoing traffic used for command & control data by the client.
CONNECTION_BYTES_SENT_TOTAL, ///< UInt64. Total outgoing traffic to the server by this client. Equal to the sum of
///< \ref CONNECTION_BYTES_SENT_SPEECH, \ref CONNECTION_BYTES_SENT_KEEPALIVE and \ref
///< CONNECTION_BYTES_SENT_CONTROL
CONNECTION_PACKETS_RECEIVED_SPEECH, ///< UInt64. Number of voice packets received by the client.
CONNECTION_PACKETS_RECEIVED_KEEPALIVE, ///< UInt64. Number of keep alive packets received by the client.
CONNECTION_PACKETS_RECEIVED_CONTROL, ///< UInt64. Number of command & control packets received by the client.
CONNECTION_PACKETS_RECEIVED_TOTAL, ///< UInt64. Total number of packets received by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_RECEIVED_SPEECH, \ref
///< CONNECTION_PACKETS_RECEIVED_KEEPALIVE and \ref
///< CONNECTION_PACKETS_RECEIVED_CONTROL
CONNECTION_BYTES_RECEIVED_SPEECH, ///< UInt64. Incoming traffic used by the client for voice data.
CONNECTION_BYTES_RECEIVED_KEEPALIVE, ///< UInt64. Incoming traffic used by the client to keep the connection alive.
CONNECTION_BYTES_RECEIVED_CONTROL, ///< UInt64. Incoming traffic used by the client for command & control data.
CONNECTION_BYTES_RECEIVED_TOTAL, ///< UInt64. Total incoming traffic used by the client. Equal to the sum of \ref
///< CONNECTION_BYTES_RECEIVED_SPEECH, \ref CONNECTION_BYTES_RECEIVED_KEEPALIVE and
///< \ref CONNECTION_BYTES_RECEIVED_CONTROL
CONNECTION_PACKETLOSS_SPEECH, ///< Double. Percentage points of voice packets for the client that did not arrive at
///< the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_KEEPALIVE, ///< Double. Percentage points of keep alive packets for the client that did not
///< arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_CONTROL, ///< Double. Percentage points of command & control packets for the client that did
///< not arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_TOTAL, ///< Double. Cumulative chance in percentage points with which a packet round trip
///< failed because a packet was lost
CONNECTION_SERVER2CLIENT_PACKETLOSS_SPEECH, ///< Double. Probability with which a voice packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< server was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the server was not
///< received by the client.
CONNECTION_CLIENT2SERVER_PACKETLOSS_SPEECH, ///< Double. Probability with which a speech packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< client was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the client was not
///< received by the server.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes sent for speech data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes sent for keepalive data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes sent for control data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes sent in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second sent for speech data, averaged over the
///< last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second sent for keepalive data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second sent for control data, averaged over
///< the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second sent, averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes received for speech data in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes received for keepalive data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes received for control data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes received in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second received for speech data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second received for keepalive data,
///< averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second received for control data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second received, averaged over the last minute.
CONNECTION_DUMMY_0,
CONNECTION_DUMMY_1,
CONNECTION_DUMMY_2,
CONNECTION_DUMMY_3,
CONNECTION_DUMMY_4,
CONNECTION_DUMMY_5,
CONNECTION_DUMMY_6,
CONNECTION_DUMMY_7,
CONNECTION_DUMMY_8,
CONNECTION_DUMMY_9,
CONNECTION_FILETRANSFER_BANDWIDTH_SENT, ///< UInt64. Current file transfer upstream activity in bytes per second.
///< Only available on request (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, ///< UInt64. Current file transfer downstream activity in bytes per
///< second. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, ///< UInt64. Total downstream traffic, in bytes, used for file
///< transfer since the server was started. Only available on request
///< (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, ///< UInt64. Total upstream traffic, in bytes, used for file transfer
///< since the server was started. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_ENDMARKER
};
/**
* Describes a client position in 3 dimensional space, used for 3D Sound.
*/
typedef struct
{
float x; ///< X co-ordinate in 3D space.
float y; ///< Y co-ordinate in 3D space.
float z; ///< Z co-ordinate in 3D space.
} TS3_VECTOR;
enum GroupWhisperType
{
GROUPWHISPERTYPE_SERVERGROUP = 0, ///< Whisper list consists of server groups
GROUPWHISPERTYPE_CHANNELGROUP = 1, ///< Whisper list consists of channel groups
GROUPWHISPERTYPE_CHANNELCOMMANDER = 2, ///< whisper to channel commanders
GROUPWHISPERTYPE_ALLCLIENTS = 3, ///< whisper to all clients
GROUPWHISPERTYPE_ENDMARKER,
};
enum GroupWhisperTargetMode
{
GROUPWHISPERTARGETMODE_ALL = 0,
GROUPWHISPERTARGETMODE_CURRENTCHANNEL = 1, ///< Whisper the current channel of the client
GROUPWHISPERTARGETMODE_PARENTCHANNEL = 2, ///< Whisper the parent channel of whatever channel the client is currently in
GROUPWHISPERTARGETMODE_ALLPARENTCHANNELS = 3, ///< Whipser to the parent channel and all their parent channels as well
GROUPWHISPERTARGETMODE_CHANNELFAMILY = 4, ///< Whisper to the current channel and all its sub channels
GROUPWHISPERTARGETMODE_ANCESTORCHANNELFAMILY = 5, ///< Whisper to the current channel, all its parent and sub channels.
GROUPWHISPERTARGETMODE_SUBCHANNELS = 6, ///< Whisper to all sub channels of the current channel of the client
GROUPWHISPERTARGETMODE_ENDMARKER,
};
enum MonoSoundDestination
{
MONO_SOUND_DESTINATION_ALL = 0, ///< Send mono sound to all available speakers
MONO_SOUND_DESTINATION_FRONT_CENTER = 1, ///< Send mono sound to front center speaker if available
MONO_SOUND_DESTINATION_FRONT_LEFT_AND_RIGHT = 2 ///< Send mono sound to front left/right speakers if available
};
enum SecuritySaltOptions
{
SECURITY_SALT_CHECK_NICKNAME = 1, ///< put nickname into security hash
SECURITY_SALT_CHECK_META_DATA = 2 ///< put meta data into security hash
};
/*this enum is used to disable client commands on the server*/
enum ClientCommand
{
CLIENT_COMMAND_requestConnectionInfo = 0, ///< disable client connection info request (client bandwidth usage, ip,
///< port, ping)
CLIENT_COMMAND_requestClientMove = 1, ///< disable moving clients
CLIENT_COMMAND_requestXXMuteClients = 2, ///< disable muting other clients
CLIENT_COMMAND_requestClientKickFromXXX = 3, ///< disable kicking clients
CLIENT_COMMAND_flushChannelCreation = 4, ///< disable creating channels
CLIENT_COMMAND_flushChannelUpdates = 5, ///< disable editing channels
CLIENT_COMMAND_requestChannelMove = 6, ///< disable moving channels
CLIENT_COMMAND_requestChannelDelete = 7, ///< disable deleting channels
CLIENT_COMMAND_requestChannelDescription = 8, ///< disable channel descriptions
CLIENT_COMMAND_requestChannelXXSubscribeXXX = 9, ///< disable being able to see clients in channels other than the
///< current channel the client is in
CLIENT_COMMAND_requestServerConnectionInfo = 10, ///< disable server connection info request (server bandwidth
///< usage, ip, port, ping)
CLIENT_COMMAND_requestSendXXXTextMsg = 11, ///< disable text messaging
CLIENT_COMMAND_filetransfers = 12, ///< disable file transfer
CLIENT_COMMAND_ENDMARKER
};
/* Access Control List*/
enum ACLType
{
ACL_NONE = 0,
ACL_WHITE_LIST = 1,
ACL_BLACK_LIST = 2
};
/* file transfer actions*/
enum FTAction
{
FT_INIT_SERVER = 0, ///< The virtual server is created. result->channelPath can be changed to create a different
///< directory than the default 'virtualserver_x' where x is the virtual server.
FT_INIT_CHANNEL = 1, ///< A channel is created. result->channelPath can be changed to create a different directory
///< then the default 'channel_x' where x is the channel id.
FT_UPLOAD = 2, ///< A file is being uploaded. All values in the result struct can be modified.
FT_DOWNLOAD = 3, ///< A file is being downloaded. All values in the result struct can be modified.
FT_DELETE = 4, ///< A file is being deleted. All values in the result struct can be modified.
FT_CREATEDIR = 5, ///< A directory is being created in a channel. All values in the result struct can be modified.
FT_RENAME = 6, ///< A file or folder is being renamed. The callback will be called twice! Once for the old and then
///< for the new name. All values in the result struct can be modified.
FT_FILELIST = 7, ///< A directory listing is requested. All values in the result struct can be modified.
FT_FILEINFO = 8 ///< Information of a file is requested. All values in the result struct can be modified.
};
/* file transfer status */
enum FileTransferState
{
FILETRANSFER_INITIALISING = 0, ///< File transfer is establishing connection.
FILETRANSFER_ACTIVE, ///< File transfer is in progress
FILETRANSFER_FINISHED, ///< File transfer has finished
};
/* file transfer types */
enum FileTransferType
{
FileListType_Directory = 0, ///< The file entry is a directory
FileListType_File, ///< The file entry is a regular file
};
/* some structs to handle variables in callbacks */
#define MAX_VARIABLES_EXPORT_COUNT 64
struct VariablesExportItem
{
unsigned char itemIsValid; ///< Whether or not there is any data in this item. Ignore this item if this is 0.
unsigned char proposedIsSet; ///< The value in proposed is set. If 0 ignore proposed
const char* current; ///< current value (stored in memory)
const char* proposed; ///< New value to change to (const, so no updates please)
};
struct VariablesExport
{
struct VariablesExportItem items[MAX_VARIABLES_EXPORT_COUNT];
};
struct ClientMiniExport
{
anyID ID; ///< id of the client
uint64 channel; ///< the channel the client is in
const char* ident; ///< client public identity
const char* nickname; ///< client display name
};
/**
* Structure used to describe a file transfer in the \ref ServerLibFunctions.onTransformFilePath callback.
* This describes the original values, and also contains hints for length limitations of the result parameter
* of the callback.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExport
{
uint64 channel; ///< The channel id of the file. 0 if action is \ref FT_INIT_SERVER
const char* filename; ///< utf8 encoded c string containing the original file name as intended by the client.
int action; ///< The action to be performed. One of the values from the \ref FTAction enum. Defines which values of
///< the result struct can be modified.
int transformedFileNameMaxSize; ///< The maximum length the file name can be rewritten to.
int channelPathMaxSize; ///< The maximum length the path can be rewritten to.
};
/**
* Structure to rewrite the file transfer file name and path in the \ref ServerLibFunctions.onTransformFilePath callback.
* The lengths are limited as described in the original parameter.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExportReturns
{
char* transformedFileName; ///< pointer to target file name. Fill the memory pointed to with an utf8 encoded c string
///< containing the new file name. Limited to original->transformedFileNameMaxSize bytes.
char* channelPath; ///< pointer to memory for new path. Fill the memory pointed to with an utf8 encoded c string
///< containing the new path. Limited to original->channelPathMaxSize bytes.
int logFileAction; ///< boolean (1/0). Whether to log this file transfer to the log. Action is not logged regardless
///< of this value if the servers \ref VIRTUALSERVER_LOG_FILETRANSFER property is 0.
};
struct FileTransferCallbackExport
{
anyID clientID; ///< the client who started the file transfer
anyID transferID; ///< local identifier of the transfer that has completed
anyID remoteTransferID; ///< remote identifier of the transfer that has completed
unsigned int status; ///< status of the transfer. One of the values from the \ref FileTransferState enum
const char* statusMessage; ///< utf8 encoded c string containing a human readable description of the status
uint64 remotefileSize; ///< size in bytes of the complete file to be transferred
uint64 bytes; ///< number of bytes transferred. Same as remotefileSize when the transfer completed entirely.
int isSender; ///< boolean. 1 if the server is sending the file. 0 if the server is receiving the file.
};
/*define for file transfer bandwith limits*/
#define BANDWIDTH_LIMIT_UNLIMITED 0xFFFFFFFFFFFFFFFFll
/*defines for speaker locations used by some sound callbacks*/
#ifndef SPEAKER_FRONT_LEFT
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#endif
#define SPEAKER_HEADPHONES_LEFT 0x10000000
#define SPEAKER_HEADPHONES_RIGHT 0x20000000
#define SPEAKER_MONO 0x40000000
#endif /*PUBLIC_DEFINITIONS_H*/
@@ -0,0 +1,217 @@
#ifndef PUBLIC_ERRORS_H
#define PUBLIC_ERRORS_H
//The idea here is: the values are 2 bytes wide, the first byte identifies the group, the second the count within that group
enum Ts3ErrorType {
//general
ERROR_ok = 0x0000, ///< Indicates success.
ERROR_undefined = 0x0001,
ERROR_not_implemented = 0x0002, ///< The attempted operation is not available in this context
ERROR_ok_no_update = 0x0003, ///< Indicates success, but no change occurred. Returned for example upon flushing (e.g. using \ref ts3client_flushChannelUpdates) when all indicated changes already matched the current state.
ERROR_dont_notify = 0x0004,
ERROR_lib_time_limit_reached = 0x0005,
ERROR_out_of_memory = 0x0006, ///< Not enough system memory to perform operation
ERROR_canceled = 0x0007,
ERROR_ok_no_error_event = 0x0008, ///< Indicates success, but no error event was generated. This is used because of the return code management and reduce packets.
//dunno
ERROR_command_not_found = 0x0100,
ERROR_unable_to_bind_network_port = 0x0101, ///< Unspecified failure to create a listening port
ERROR_no_network_port_available = 0x0102, ///< Failure to initialize a listening port for FileTransfer
ERROR_port_already_in_use = 0x0103, ///< Specified port is already in use by a different application
ERROR_command_line_parse_failed = 0x0104, ///< Command line arguments are invalid
ERROR_command_line_exit_version = 0x0105, ///< Command line specified version. The process should exit with code 0 after printing the version.
ERROR_command_line_exit_help = 0x0106, ///< Command line specified help. The process should exit with code 0 after priting the help.
//client
ERROR_client_invalid_id = 0x0200, ///< Client no longer connected
ERROR_client_nickname_inuse = 0x0201, ///< Client name is already in use. Client names must be unique
ERROR_client_protocol_limit_reached = 0x0203, ///< Too many clients on the server
ERROR_client_invalid_type = 0x0204, ///< Function called for normal clients that is only available for query clients or vice versa
ERROR_client_already_subscribed = 0x0205, ///< Attempting to subscribe to a channel already subscribed to
ERROR_client_not_logged_in = 0x0206,
ERROR_client_could_not_validate_identity = 0x0207, ///< Identity not valid or insufficient security level
ERROR_client_invalid_password = 0x0208,
ERROR_client_version_outdated = 0x020a, ///< Server requires newer client version as determined by the min_client_version properties
ERROR_client_is_flooding = 0x020c, ///< Triggered flood protection. Further information is supplied in the extra message if applicable.
ERROR_client_hacked = 0x020d,
ERROR_client_cannot_verify_now = 0x020e,
ERROR_client_login_not_permitted = 0x020f,
ERROR_client_not_subscribed = 0x0210, ///< Action is only available on subscribed channels
//channel
ERROR_channel_invalid_id = 0x0300, ///< Channel does not exist on the server (any longer)
ERROR_channel_protocol_limit_reached = 0x0301, ///< Too many channels on the server
ERROR_channel_already_in = 0x0302, ///< Attempting to move a client or channel to its current channel
ERROR_channel_name_inuse = 0x0303, ///< Channel name is already taken by another channel. Channel names must be unique
ERROR_channel_not_empty = 0x0304, ///< Attempting to delete a channel with clients or sub channels in it
ERROR_channel_can_not_delete_default = 0x0305, ///< Default channel cannot be deleted. Set a new default channel first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_default_require_permanent = 0x0306, ///< Attempt to set a non permanent channel as default channel. Set channel to permanent first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_invalid_flags = 0x0307, ///< Invalid combination of \ref ChannelProperties, trying to remove \ref CHANNEL_FLAG_DEFAULT or set a password on the default channel
ERROR_channel_parent_not_permanent = 0x0308, ///< Attempt to move a permanent channel into a non-permanent one, or set a channel to be permanent that is a sub channel of a non-permanent one
ERROR_channel_maxclients_reached = 0x0309, ///< Channel is full as determined by its \ref CHANNEL_MAXCLIENTS setting
ERROR_channel_maxfamily_reached = 0x030a, ///< Channel tree is full as determined by its \ref CHANNEL_MAXFAMILYCLIENTS setting
ERROR_channel_invalid_order = 0x030b, ///< Invalid value for the \ref CHANNEL_ORDER property. The specified channel must exist on the server and be on the same level.
ERROR_channel_no_filetransfer_supported = 0x030c, ///< Invalid \ref CHANNEL_FILEPATH set for the channel
ERROR_channel_invalid_password = 0x030d, ///< Channel has a password not matching the password supplied in the call
// used in public_rare_errors = 0x030e,
ERROR_channel_invalid_security_hash = 0x030f,
//server
ERROR_server_invalid_id = 0x0400, ///< Chosen virtual server does not exist or is offline
ERROR_server_running = 0x0401, ///< attempting to delete a server that is running. Stop the server before deleting it.
ERROR_server_is_shutting_down = 0x0402, ///< Client disconnected because the server is going offline
ERROR_server_maxclients_reached = 0x0403, ///< Given in the onConnectStatusChange event when the server has reached its maximum number of clients as defined by the \ref VIRTUALSERVER_MAXCLIENTS property
ERROR_server_invalid_password = 0x0404, ///< Specified server password is wrong. Provide the correct password in the \ref ts3client_startConnection / \ref ts3client_startConnectionWithChannelID call.
ERROR_server_is_virtual = 0x0407, ///< Server is in virtual status. The attempted action is not possible in this state. Start the virtual server first.
ERROR_server_is_not_running = 0x0409, ///< Attempting to stop a server that is not online.
ERROR_server_is_booting = 0x040a, // Not used
ERROR_server_status_invalid = 0x040b,
ERROR_server_version_outdated = 0x040d, ///< Attempt to connect to an outdated server version. The server needs to be updated.
ERROR_server_duplicate_running = 0x040e, ///< This server is already running within the instance. Each virtual server may only exist once.
//parameter
ERROR_parameter_quote = 0x0600, // Not used
ERROR_parameter_invalid_count = 0x0601, ///< Attempt to flush changes without previously calling set*VariableAs* since the last flush
ERROR_parameter_invalid = 0x0602, ///< At least one of the supplied parameters did not meet the criteria for that parameter
ERROR_parameter_not_found = 0x0603, ///< Failure to supply all the necessary parameters
ERROR_parameter_convert = 0x0604, ///< Invalid type supplied for a parameter, such as passing a string (ie. "five") that expects a number.
ERROR_parameter_invalid_size = 0x0605, ///< Value out of allowed range. Such as strings are too long/short or numeric values outside allowed range
ERROR_parameter_missing = 0x0606, ///< Neglecting to specify a required parameter
ERROR_parameter_checksum = 0x0607, ///< Attempting to deploy a modified snapshot
//unsorted, need further investigation
ERROR_vs_critical = 0x0700, ///< Failure to create default channel
ERROR_connection_lost = 0x0701, ///< Generic error with the connection.
ERROR_not_connected = 0x0702, ///< Attempting to call functions with a serverConnectionHandler that is not connected. You can use \ref ts3client_getConnectionStatus to check whether the connection handler is connected to a server
ERROR_no_cached_connection_info = 0x0703, ///< Attempting to query connection information (bandwidth usage, ping, etc) without requesting them first using \ref ts3client_requestConnectionInfo
ERROR_currently_not_possible = 0x0704, ///< Requested information is not currently available. You may have to call \ref ts3client_requestClientVariables or \ref ts3client_requestServerVariables
ERROR_failed_connection_initialisation = 0x0705, ///< No TeamSpeak server running on the specified IP address and port
ERROR_could_not_resolve_hostname = 0x0706, ///< Failure to resolve the specified hostname to an IP address
ERROR_invalid_server_connection_handler_id = 0x0707, ///< Attempting to perform actions on a non-existent server connection handler
ERROR_could_not_initialise_input_manager = 0x0708, // Not used
ERROR_clientlibrary_not_initialised = 0x0709, ///< Calling client library functions without successfully calling \ref ts3client_initClientLib before
ERROR_serverlibrary_not_initialised = 0x070a, ///< Calling server library functions without successfully calling \ref ts3server_initServerLib before
ERROR_whisper_too_many_targets = 0x070b, ///< Using a whisper list that contain more clients than the servers \ref VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE property
ERROR_whisper_no_targets = 0x070c, ///< The active whisper list is empty or no clients matched the whisper list (e.g. all channels in the list are empty)
ERROR_connection_ip_protocol_missing = 0x070d, ///< Invalid or unsupported protocol (e.g. attempting an IPv6 connection on an IPv4 only machine)
ERROR_handshake_failed = 0x070e,
ERROR_illegal_server_license = 0x070f,
//file transfer
ERROR_file_invalid_name = 0x0800, ///< Invalid UTF8 string or not a valid file
ERROR_file_invalid_permissions = 0x0801, ///< Permissions prevent opening the file
ERROR_file_already_exists = 0x0802, ///< Target path already exists as a directory
ERROR_file_not_found = 0x0803, ///< Attempt to access or move non existing file
ERROR_file_io_error = 0x0804, ///< Generic file input / output error
ERROR_file_invalid_transfer_id = 0x0805, ///< Attempt to get information about a file transfer after it has already been cleaned up. File transfer information is not available indefinitely after the transfer completed
ERROR_file_invalid_path = 0x0806, ///< specified path contains invalid characters or does not start with "/"
ERROR_file_no_files_available = 0x0807, // Not used
ERROR_file_overwrite_excludes_resume = 0x0808, ///< File overwrite and resume are mutually exclusive. Only one or neither can be 1.
ERROR_file_invalid_size = 0x0809, ///< Attempt to write more bytes than claimed file size.
ERROR_file_already_in_use = 0x080a, ///< File is currently not available, try again later.
ERROR_file_could_not_open_connection = 0x080b, ///< Generic failure in file transfer connection / other party did not conform to file transfer protocol
ERROR_file_no_space_left_on_device = 0x080c, ///< Operating system reports hard disk is full. May be caused by quota limitations.
ERROR_file_exceeds_file_system_maximum_size = 0x080d, ///< File is too large for the file system of the target device.
ERROR_file_transfer_connection_timeout = 0x080e, // Not used
ERROR_file_connection_lost = 0x080f, ///< File input / output timeout or connection failure
ERROR_file_exceeds_supplied_size = 0x0810, // Not used
ERROR_file_transfer_complete = 0x0811, ///< Indicates successful completion
ERROR_file_transfer_canceled = 0x0812, ///< Transfer was cancelled through @ref ts3client_haltTransfer
ERROR_file_transfer_interrupted = 0x0813, ///< Transfer failed because the server is shutting down, or network connection issues
ERROR_file_transfer_server_quota_exceeded = 0x0814, ///< Transfer terminated due to server bandwidth quota being exceeded. No client can transfer files.
ERROR_file_transfer_client_quota_exceeded = 0x0815, ///< Attempt to transfer more data than allowed by this clients' bandwidth quota. Other clients may continue to transfer files.
ERROR_file_transfer_reset = 0x0816, // Not used
ERROR_file_transfer_limit_reached = 0x0817, ///< Too many file transfers are in progress. Try again later
ERROR_file_invalid_storage_class = 0x0818, // TODO: Invalid storage class for HTTP FileTransfer (what is a storage class?)
ERROR_file_invalid_dimension = 0x0819, ///< Avatar image exceeds maximum width or height accepted by the server.
ERROR_file_transfer_channel_quota_exceeded = 0x081a, ///< Transfer failed because the channel quota was exceeded. Uploading to this channel is not possible, but other channels may be fine.
//sound
ERROR_sound_preprocessor_disabled = 0x0900, ///< Cannot set or query pre processor variables with preprocessing disabled
ERROR_sound_internal_preprocessor = 0x0901,
ERROR_sound_internal_encoder = 0x0902,
ERROR_sound_internal_playback = 0x0903,
ERROR_sound_no_capture_device_available = 0x0904, ///< No audio capture devices are available
ERROR_sound_no_playback_device_available = 0x0905, ///< No audio playback devices are available
ERROR_sound_could_not_open_capture_device = 0x0906, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_could_not_open_playback_device = 0x0907, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_handler_has_device = 0x0908, ///< Attempt to open a sound device on a connection handler which already has an open device. Close the already open device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_invalid_capture_device = 0x0909, ///< Attempt to use a device for capture that does not support capturing audio
ERROR_sound_invalid_playback_device = 0x090a, ///< Attempt to use a device for playback that does not support playback of audio
ERROR_sound_invalid_wave = 0x090b, ///< Attempt to use a non WAV file in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle
ERROR_sound_unsupported_wave = 0x090c, ///< Unsupported wave file used in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle.
ERROR_sound_open_wave = 0x090d, ///< Failure to open the specified sound file
ERROR_sound_internal_capture = 0x090e,
ERROR_sound_device_in_use = 0x090f, ///< Attempt to unregister a custom device that is being used. Close the device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_device_already_registerred = 0x0910, ///< Attempt to register a custom device with a device id that has already been used in a previous call. Device ids must be unique.
ERROR_sound_unknown_device = 0x0911, ///< Attempt to open, close, unregister or use a device which is not known. Custom devices must be registered before being used (see \ref ts3client_registerCustomDevice)
ERROR_sound_unsupported_frequency = 0x0912,
ERROR_sound_invalid_channel_count = 0x0913, ///< Invalid device audio channel count, must be > 0
ERROR_sound_read_wave = 0x0914, ///< Failure to read sound samples from an opened wave file. Is this a valid wave file?
ERROR_sound_need_more_data = 0x0915, // for internal purposes only
ERROR_sound_device_busy = 0x0916, // for internal purposes only
ERROR_sound_no_data = 0x0917, ///< Indicates there is currently no data for playback, e.g. nobody is speaking right now.
ERROR_sound_channel_mask_mismatch = 0x0918, ///< Opening a device with an unsupported channel count
//permissions
ERROR_permissions_client_insufficient = 0x0a08, ///< Not enough permissions to perform the requested activity
ERROR_permissions = 0x0a0c, ///< Permissions to use sound device not granted by operating system, e.g. Windows denied microphone access.
//accounting
ERROR_accounting_virtualserver_limit_reached = 0x0b00, ///< Attempt to use more virtual servers than allowed by the license
ERROR_accounting_slot_limit_reached = 0x0b01, ///< Attempt to set more slots than allowed by the license
ERROR_accounting_license_file_not_found = 0x0b02, // Not used
ERROR_accounting_license_date_not_ok = 0x0b03, ///< License expired or not valid yet
ERROR_accounting_unable_to_connect_to_server = 0x0b04, ///< Failure to communicate with accounting backend
ERROR_accounting_unknown_error = 0x0b05, ///< Failure to write update license file
ERROR_accounting_server_error = 0x0b06, // Not used
ERROR_accounting_instance_limit_reached = 0x0b07, ///< More than one process of the server is running
ERROR_accounting_instance_check_error = 0x0b08, ///< Shared memory access failure.
ERROR_accounting_license_file_invalid = 0x0b09, ///< License is not a TeamSpeak license
ERROR_accounting_running_elsewhere = 0x0b0a, ///< A copy of this server is already running in another instance. Each server may only exist once.
ERROR_accounting_instance_duplicated = 0x0b0b, ///< A copy of this server is running already in this process. Each server may only exist once.
ERROR_accounting_already_started = 0x0b0c, ///< Attempt to start a server that is already running
ERROR_accounting_not_started = 0x0b0d,
ERROR_accounting_to_many_starts = 0x0b0e, ///< Starting instance / virtual servers too often in too short a time period
//provisioning server
/// @cond HAS_PROVISIONING
ERROR_provisioning_invalid_password = 0x1100,
ERROR_provisioning_invalid_request = 0x1101,
ERROR_provisioning_no_slots_available = 0x1102,
ERROR_provisioning_pool_missing = 0x1103,
ERROR_provisioning_pool_unknown = 0x1104,
ERROR_provisioning_unknown_ip_location = 0x1105,
ERROR_provisioning_internal_tries_exceeded = 0x1106,
ERROR_provisioning_too_many_slots_requested = 0x1107,
ERROR_provisioning_too_many_reserved = 0x1108,
ERROR_provisioning_could_not_connect = 0x1109,
ERROR_provisioning_auth_server_not_connected = 0x1110,
ERROR_provisioning_auth_data_too_large = 0x1111,
ERROR_provisioning_already_initialized = 0x1112,
ERROR_provisioning_not_initialized = 0x1113,
ERROR_provisioning_connecting = 0x1114,
ERROR_provisioning_already_connected = 0x1115,
ERROR_provisioning_not_connected = 0x1116,
ERROR_provisioning_io_error = 0x1117,
ERROR_provisioning_invalid_timeout = 0x1118,
ERROR_provisioning_ts3server_not_found = 0x1119,
ERROR_provisioning_no_permission = 0x111A,
/// @endcond
// 0x12 - 0x15 are reserved in rare
// screen share
ERROR_already_registered = 0x1600,
ERROR_stream_session_limit_reached = 0x1601,
ERROR_stream_session_not_found = 0x1602,
ERROR_stream_unknown = 0x1603,
ERROR_stream_not_participating = 0x1604,
ERROR_not_streamer = 0x1605,
ERROR_already_joined = 0x1606,
ERROR_join_request_not_found = 0x1607,
ERROR_sfu_failed_to_start = 0x1608,
};
#endif
@@ -0,0 +1,236 @@
#ifndef TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#define TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Version definitions.
#define TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1 1
// Protocol used for communication between the session subscriber and the session (a single stream).
// Commands are sent bidirectionally or unidirectionally between the parties.
// e.g. SESSION => SUBSCRIBER: ON_FRAME, ON_PAUSED_CHANGED
// e.g. SUBSCRIBER => SESSION: ON_FRAME_ACK, ON_RESIZE
// Command type enum with a lowercase type name.
typedef enum
{
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME = 0,
TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE,
TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED,
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK,
TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP,
TS_SESSION_SUBSCRIBER_CMD_REMOVE_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED,
} ts_session_subscriber_command_type_t;
// Pixel format enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_I420 = 0,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_NV12,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ABGR,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ARGB,
} ts_session_subscriber_pixel_format_t;
// Buffer location enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_CPU = 0,
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_GPU
} ts_session_subscriber_buffer_location_t;
// Buffer type enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_SINGLE = 0,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_MAIN,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_SUB
} ts_session_subscriber_buffer_type_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(push, 4)
#endif
// Main buffer header for shared CPU Memory Front/Back Buffers.
// The Main Buffer contains metadata about the current front/back buffer and the versioning for both the main and sub buffer.
// The information from the main buffer can be used to always read the front buffer.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t front_buffer_index; // index of the front buffer. (0: main buffer, 1: sub buffer)
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_main_buffer_header_t;
// Sub buffer header.
typedef struct
{
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
} ts_session_subscriber_sub_buffer_header_t;
// Single frame buffer header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_single_frame_buffer_header_t;
// Command header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // Total message length (header + payload).
ts_session_subscriber_command_type_t type;
uint64_t target_session_id; // always set to the target session id this command is for or is originating from.
uint64_t target_subscriber_id; // 0 if broadcast.
} ts_session_subscriber_command_header_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME.
// The frame data is not included in the message, but is attached seperately or was sent beforehand. The buffer is identified by it's id.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_id; // buffer id, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_frame_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t frame_id;
} ts_session_subscriber_on_frame_ack_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE.
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t width;
uint32_t height;
} ts_session_subscriber_on_resize_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t paused; // 0 or 1.
} ts_session_subscriber_on_paused_changed_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE.
// Contains a single frame buffer. The header is of format |ts_session_subscriber_single_frame_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
ts_session_subscriber_buffer_type_t buffer_type;
} ts_session_subscriber_on_buffer_single_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK.
// Contains a main buffer and a sub buffer. The main buffer header
// contains metadata about the current front/back buffer and
// is of type |ts_session_subscriber_main_buffer_header_t|.
// The sub buffer's header is of type |ts_session_subscriber_sub_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t main_buffer_ptr; // main buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t main_buffer_length;
uint64_t sub_buffer_ptr; // sub buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t sub_buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
} ts_session_subscriber_on_buffer_front_back_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER.
// SUBSCRIBER => SESSION.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_resp_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_release_buffer_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr;
int bits_per_sample;
int sample_rate;
uint32_t number_of_channels;
uint32_t number_of_frames;
int64_t absolute_capture_timestamp_ms;
float volume;
} ts_session_subscriber_on_audio_frames_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t audio_enabled;
} ts_session_subscriber_on_audio_enabled_changed_payload_t;
// Overall Command structure.
typedef struct
{
ts_session_subscriber_command_header_t header;
union
{
ts_session_subscriber_on_frame_payload_t frame;
ts_session_subscriber_on_resize_payload_t resize;
ts_session_subscriber_on_paused_changed_payload_t paused;
ts_session_subscriber_on_frame_ack_payload_t frame_ack;
ts_session_subscriber_on_buffer_single_payload_t buffer_single;
ts_session_subscriber_on_buffer_front_back_payload_t buffer_front_back;
ts_session_subscriber_on_release_buffer_payload_t release_buffer;
ts_session_subscriber_add_subscriber_payload_t add_subscriber;
ts_session_subscriber_add_subscriber_resp_payload_t add_subscriber_resp;
ts_session_subscriber_on_audio_frames_payload_t audio_frames;
ts_session_subscriber_on_audio_enabled_changed_payload_t audio_enabled_changed;
} payload;
} ts_session_subscriber_command_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif // TS_SESSION_SUBSCRIBER_PROTOCOL_H_
@@ -0,0 +1,29 @@
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was team_clientConfig.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()
####################################################################################
include("${CMAKE_CURRENT_LIST_DIR}/team_clientTargets.cmake")
check_required_components(team_client)
@@ -0,0 +1,19 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "teamspeak::client" for configuration "Release"
set_property(TARGET teamspeak::client APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(teamspeak::client PROPERTIES
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.dylib"
IMPORTED_SONAME_RELEASE "@rpath/libteamspeak_sdk_client.dylib"
)
list(APPEND _cmake_import_check_targets teamspeak::client )
list(APPEND _cmake_import_check_files_for_teamspeak::client "${_IMPORT_PREFIX}/lib/libteamspeak_sdk_client.dylib" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
@@ -0,0 +1,121 @@
# Generated by CMake
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.8)
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
if(CMAKE_VERSION VERSION_LESS "2.8.3")
message(FATAL_ERROR "CMake >= 2.8.3 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.8.3...4.0)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_cmake_targets_defined "")
set(_cmake_targets_not_defined "")
set(_cmake_expected_targets "")
foreach(_cmake_expected_target IN ITEMS teamspeak::client)
list(APPEND _cmake_expected_targets "${_cmake_expected_target}")
if(TARGET "${_cmake_expected_target}")
list(APPEND _cmake_targets_defined "${_cmake_expected_target}")
else()
list(APPEND _cmake_targets_not_defined "${_cmake_expected_target}")
endif()
endforeach()
unset(_cmake_expected_target)
if(_cmake_targets_defined STREQUAL _cmake_expected_targets)
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
unset(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
return()
endif()
if(NOT _cmake_targets_defined STREQUAL "")
string(REPLACE ";" ", " _cmake_targets_defined_text "${_cmake_targets_defined}")
string(REPLACE ";" ", " _cmake_targets_not_defined_text "${_cmake_targets_not_defined}")
message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_cmake_targets_defined_text}\nTargets not yet defined: ${_cmake_targets_not_defined_text}\n")
endif()
unset(_cmake_targets_defined)
unset(_cmake_targets_not_defined)
unset(_cmake_expected_targets)
# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
set(_IMPORT_PREFIX "")
endif()
# Create imported target teamspeak::client
add_library(teamspeak::client SHARED IMPORTED)
set_target_properties(teamspeak::client PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)
if(NOT CMAKE_VERSION VERSION_LESS "3.23.0")
target_sources(teamspeak::client
INTERFACE
FILE_SET "public_headers"
TYPE "HEADERS"
BASE_DIRS "${_IMPORT_PREFIX}/include"
FILES "${_IMPORT_PREFIX}/include/teamspeak/clientlib.h" "${_IMPORT_PREFIX}/include/teamspeak/clientlib_sdk.h" "${_IMPORT_PREFIX}/include/teamspeak/video/session_subscriber_protocol.h"
)
else()
set_property(TARGET teamspeak::client
APPEND PROPERTY INTERFACE_INCLUDE_DIRECTORIES
"${_IMPORT_PREFIX}/include"
)
endif()
# Load information for each installed configuration.
file(GLOB _cmake_config_files "${CMAKE_CURRENT_LIST_DIR}/team_clientTargets-*.cmake")
foreach(_cmake_config_file IN LISTS _cmake_config_files)
include("${_cmake_config_file}")
endforeach()
unset(_cmake_config_file)
unset(_cmake_config_files)
# Cleanup temporary variables.
set(_IMPORT_PREFIX)
# Loop over all imported files and verify that they actually exist
foreach(_cmake_target IN LISTS _cmake_import_check_targets)
if(CMAKE_VERSION VERSION_LESS "3.28"
OR NOT DEFINED _cmake_import_check_xcframework_for_${_cmake_target}
OR NOT IS_DIRECTORY "${_cmake_import_check_xcframework_for_${_cmake_target}}")
foreach(_cmake_file IN LISTS "_cmake_import_check_files_for_${_cmake_target}")
if(NOT EXISTS "${_cmake_file}")
message(FATAL_ERROR "The imported target \"${_cmake_target}\" references the file
\"${_cmake_file}\"
but this file does not exist. Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
\"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
endif()
endforeach()
endif()
unset(_cmake_file)
unset("_cmake_import_check_files_for_${_cmake_target}")
endforeach()
unset(_cmake_target)
unset(_cmake_import_check_targets)
# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
@@ -0,0 +1,23 @@
#ifndef TEAMLOG_LOGTYPES_H
#define TEAMLOG_LOGTYPES_H
enum LogTypes {
LogType_NONE = 0x0000, ///< Logging is disabled
LogType_FILE = 0x0001, ///< Log to regular log file
LogType_CONSOLE = 0x0002, ///< Log to standard output / error
LogType_USERLOGGING = 0x0004, ///< User defined logging. Will call the \ref ServerLibFunctions.onUserLoggingMessageEvent callback for every message to be logged
LogType_NO_NETLOGGING = 0x0008, ///< Not used
LogType_DATABASE = 0x0010, ///< Log to database (deprecated, server only, no effect in SDK)
LogType_SYSLOG = 0x0020, ///< Log to syslog (only available on Linux)
};
enum LogLevel {
LogLevel_CRITICAL = 0, ///< these messages stop the program
LogLevel_ERROR, ///< everything that is really bad, but not so bad we need to shut down
LogLevel_WARNING, ///< everything that *might* be bad
LogLevel_DEBUG, ///< output that might help find a problem
LogLevel_INFO, ///< informational output, like "starting database version x.y.z"
LogLevel_DEVEL ///< developer only output (will not be displayed in release mode)
};
#endif //TEAMLOG_LOGTYPES_H
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,58 @@
#ifndef CLIENTLIB_SDK_H
#define CLIENTLIB_SDK_H
// system
#include <stdlib.h>
// own
#include "teamspeak/public_definitions.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Sets the client to which to transmit voice. Stops standard channel voice transmission.
*
* The client will still receive voice from their current channel, however their voice will not be transmitted to their
* current channel anymore. If this call is successful (check onServerErrorEvent) then voice of the specified client
* will be transmitted to all specified channels and all the specified clients. Pass 0 to both target parameter arrays
* to restore default behavior of transmitting voice to current channel. You will receive an onServerErrorEvent with the
* passed returnCode indicating whether or not the operation was successful.
*
* @param server_connection_handler_id the connection handler on which to set the whisper list
* @param client_id the client to set the whisper list for. Set to 0 or your own client ID to set your own whisper list.
* @param channel_ids an array of channel ids to transmit voice to.
* @param channel_ids_size number of elements in aforementioned array.
* @param client_ids a zero terminated array of client ids to transmit voice to.
* @param client_ids_size number of elements in aforementioned array.
* @param impersonate if the target client is a webrtc client, the voice packets will look like as if they have been
* send by the invoking client id
* @param return_code a c string to identify this request in callbacks. Pass an empty string if unused.
* @return An error code from the @ref Ts3ErrorType enum indicating either success or the failure reason
*/
EXPORTDLL unsigned int ts_client_request_client_set_whisper_list(uint64 server_connection_handler_id, anyID client_id,
const uint64* channel_ids,
int channel_ids_size,
const anyID* client_ids,
int client_ids_size, int impersonate,
const char* return_code);
/**
* @brief Send a binary-serialized ClientCommandRequest protobuf to the client library.
*
* The response will be delivered asynchronously via the onProtoResponse callback
* as a serialized ClientCommandResponse protobuf.
*
* @param data Pointer to serialized ClientCommandRequest protobuf bytes
* @param size Size of the serialized data in bytes
* @param return_code Caller-provided string to correlate the response in onProtoResponse. May be NULL.
* @return An error code: ERROR_ok on successful dispatch, ERROR_parameter_invalid on parse failure
*/
EXPORTDLL unsigned int ts3client_postProtoCommand(const void* data, size_t size, const char* return_code);
#ifdef __cplusplus
}
#endif
#endif // CLIENTLIB_SDK_H
@@ -0,0 +1,635 @@
#ifndef PUBLIC_DEFINITIONS_H
#define PUBLIC_DEFINITIONS_H
#include "teamlog/logtypes.h"
#define TS3_MAX_SIZE_CHANNEL_NAME 40 // channel name maximum length in characters
#define TS3_MAX_SIZE_VIRTUALSERVER_NAME 64 // virtual server name maximum length in characters
#define TS3_MAX_SIZE_CLIENT_NICKNAME 64 // client display name length limit in characters
#define TS3_MIN_SIZE_CLIENT_NICKNAME 3 // client display name minimum length in characters
#define TS3_MAX_SIZE_REASON_MESSAGE 80 // length limit in characters for kick, move, etc reasons
#define TS3_MAX_SIZE_TEXTMESSAGE 8192 // text message length limit, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_TOPIC 255 // channel topic lengt limith, measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_CHANNEL_DESCRIPTION 8192 // channel description length limit, measured in bytes (utf8 encoded)
// server welcome message length limit measured in bytes (utf8 encoded)
#define TS3_MAX_SIZE_VIRTUALSERVER_WELCOMEMESSAGE 1024
#define TS3_SIZE_MYTSID 44
// minimum amount of seconds before a clientID that was in use can be assigned to a new client
#define TS3_MIN_SECONDS_CLIENTID_REUSE 300
#if defined(WIN32) || defined(__WIN32__) || defined(_WIN32)
typedef unsigned __int16 anyID;
typedef unsigned __int64 uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __declspec(dllexport)
#else
#define EXPORTDLL
#endif
#endif
#else
#include <stdint.h>
typedef uint16_t anyID;
typedef uint64_t uint64;
#ifndef EXPORTDLL
#ifdef BUILDING_DLL
#define EXPORTDLL __attribute__((visibility("default")))
#else
#define EXPORTDLL
#endif
#endif
#endif
enum Visibility
{
ENTER_VISIBILITY = 0, ///< Client joined from an unsubscribed channel, or joined the server.
RETAIN_VISIBILITY, ///< Client switched from one subscribed channel to a different subscribed channel.
LEAVE_VISIBILITY ///< Client switches to an unsubscribed channel, or disconnected from server.
};
enum ConnectStatus
{
STATUS_DISCONNECTED = 0, ///< There is no activity to the server, this is the default value
STATUS_CONNECTING, ///< We are trying to connect, we haven't got a client id yet, we haven't been accepted by the server
STATUS_CONNECTED, ///< The server has accepted us, we can talk and hear and we have a client id, but we don't
///< have the channels and clients yet, we can get server infos (welcome msg etc.)
STATUS_CONNECTION_ESTABLISHING, ///< we are connected and we are visible
STATUS_CONNECTION_ESTABLISHED, ///< we are connected and we have the client and channels available
};
enum LocalTestMode
{
TEST_MODE_OFF = 0,
TEST_MODE_VOICE_LOCAL_ONLY,
TEST_MODE_VOICE_LOCAL_AND_REMOTE,
TEST_MODE_TALK_STATUS_CHANGES_ONLY
};
enum TalkStatus
{
STATUS_NOT_TALKING = 0, ///< client is not talking
STATUS_TALKING = 1, ///< client is talking
STATUS_TALKING_WHILE_DISABLED = 2, ///< client is talking while the microphone is muted (only valid for own client)
};
enum CodecType
{
CODEC_SPEEX_NARROWBAND = 0, ///< (deprecated) mono, 16bit, 8kHz, bitrate dependent on the quality setting
CODEC_SPEEX_WIDEBAND, ///< (deprecated) mono, 16bit, 16kHz, bitrate dependent on the quality setting
CODEC_SPEEX_ULTRAWIDEBAND, ///< (deprecated) mono, 16bit, 32kHz, bitrate dependent on the quality setting
CODEC_CELT_MONO, ///< (deprecated) mono, 16bit, 48kHz, bitrate dependent on the quality setting
CODEC_OPUS_VOICE, ///< mono, 16bit, 48khz, bitrate dependent on the quality setting, optimized for voice
CODEC_OPUS_MUSIC, ///< stereo, 16bit, 48khz, bitrate dependent on the quality setting, optimized for music
};
enum CodecEncryptionMode
{
CODEC_ENCRYPTION_PER_CHANNEL = 0, ///< voice data encryption decided per channel
CODEC_ENCRYPTION_FORCED_OFF, ///< voice data encryption disabled
CODEC_ENCRYPTION_FORCED_ON, ///< voice data encryption enabled
};
enum TextMessageTargetMode
{
TextMessageTarget_CLIENT = 1, ///< Message is a private message to another client
TextMessageTarget_CHANNEL, ///< Message is sent to a channel, received by all clients in that channel at the time
TextMessageTarget_SERVER, ///< Message is sent to every client on the server
TextMessageTarget_MAX
};
enum MuteInputStatus
{
MUTEINPUT_NONE = 0, ///< Microphone is not muted, audio is sent to the server
MUTEINPUT_MUTED, ///< Microphone is muted, no audio is transmitted to the server
};
enum MuteOutputStatus
{
MUTEOUTPUT_NONE = 0, ///< Speaker is active, server is sending us audio
MUTEOUTPUT_MUTED, ///< Speaker is muted, server is not sending audio to us
};
enum HardwareInputStatus
{
HARDWAREINPUT_DISABLED = 0, ///< no capture device opened
HARDWAREINPUT_ENABLED, ///< capture device open
};
enum HardwareOutputStatus
{
HARDWAREOUTPUT_DISABLED = 0, ///< no playback device opened
HARDWAREOUTPUT_ENABLED, ///< playback device open
};
enum InputDeactivationStatus
{
INPUT_ACTIVE = 0, ///< Audio is captured from the capture device.
INPUT_DEACTIVATED = 1, ///< No audio is captured from the capture device.
};
enum ReasonIdentifier
{
REASON_NONE = 0, ///< no reason data
REASON_MOVED = 1, ///< client was moved
REASON_SUBSCRIPTION = 2, // no reason data
REASON_LOST_CONNECTION = 3, // reasonmsg=reason
REASON_KICK_CHANNEL = 4, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER = 5, //{SectionInvoker} reasonmsg=reason //{SectionInvoker} is only added server->client
REASON_KICK_SERVER_BAN = 6, //{SectionInvoker} reasonmsg=reason bantime=time //{SectionInvoker} is only added server->client
REASON_SERVERSTOP = 7, // reasonmsg=reason
REASON_CLIENTDISCONNECT = 8, // reasonmsg=reason
REASON_CHANNELUPDATE = 9, // no reason data
REASON_CHANNELEDIT = 10, //{SectionInvoker}
REASON_CLIENTDISCONNECT_SERVER_SHUTDOWN = 11, // reasonmsg=reason
};
enum Protocol_Encryption_Cipher
{
AES_128 = 0b00000000,
AES_256 = 0b00000001,
PROTOCOL_ENCRYPTION_CIPHER_END_MARKER,
RESERVED = 0b00010000, // reserved until puzzle v2 is fully released, then can be reused
PUZZLE_2 = 0b00100000,
};
enum ChannelProperties
{
CHANNEL_NAME = 0, ///< String. Read/Write. Name of the channel. Always available.
CHANNEL_TOPIC, ///< String. Read/Write. Short single line text describing what the channel is about. Always available.
CHANNEL_DESCRIPTION, ///< String. Read/Write. Arbitrary text (up to 8k bytes) with information about the channel.
///< Must be requested (\ref ts3client_requestChannelDescription)
CHANNEL_PASSWORD, ///< String. Read/Write. Password of the channel. Read access is limited to the server. Clients
///< will only ever see the last password they attempted to use when joining the channel. Always available.
CHANNEL_CODEC, ///< Integer. Read/Write. The codec this channel is using. One of the values from the \ref CodecType
///< enum. Always available.
CHANNEL_CODEC_QUALITY, ///< Integer. Read/Write. The quality setting of the channel. Valid values are 0 to 10 inclusive.
///< Higher value means better voice quality but also more bandwidth usage. Always available.
CHANNEL_MAXCLIENTS, ///< Integer. Read/Write. The number of clients that can be in the channel simultaneously.
///< Always available.
CHANNEL_MAXFAMILYCLIENTS, ///< Integer. Read/Write. The total number of clients that can be in this channel and all
///< sub channels of this channel. Always available.
CHANNEL_ORDER, ///< UInt64. Read/Write. The ID of the channel below which this channel should be displayed. If 0
///< the channel is sorted at the top of the current level. Always available.
CHANNEL_FLAG_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when empty.
///< Permanent channels are stored to the database and available after server restart. SDK
///< users will need to take care of restoring channel at server start on their own.
///< Mutually exclusive with \ref CHANNEL_FLAG_SEMI_PERMANENT. Always available.
CHANNEL_FLAG_SEMI_PERMANENT, ///< Integer. Read/Write. Boolean (1/0) indicating whether the channel remains when
///< empty. Semi permanent channels are not stored to disk and gone after server
///< restart but remain while empty. Mutually exclusive with \ref
///< CHANNEL_FLAG_PERMANENT. Always available.
CHANNEL_FLAG_DEFAULT, ///< Integer. Read/Write. Boolean (1/0). The default channel is the channel that all clients
///< are located in when they join the server, unless the client explicitly specified a
///< different channel when connecting and is allowed to join their preferred channel. Only
///< one channel on the server can have this flag set. The default channel must have \ref
///< CHANNEL_FLAG_PERMANENT set. Always available.
CHANNEL_FLAG_PASSWORD, ///< Integer. Read/Write. Boolean (1/0) indicating whether this channel is password protected.
///< When removing or setting \ref CHANNEL_PASSWORD you also need to adjust this flag.
CHANNEL_CODEC_LATENCY_FACTOR, ///< (deprecated) Integer. Read/Write. Allows to increase packet size, reducing
///< bandwith at the cost of higher latency of voice transmission. Valid values are
///< 1-10 inclusive. 1 is the default and offers the lowest latency. Always available.
CHANNEL_CODEC_IS_UNENCRYPTED, ///< Integer. Read/Write. Boolean (1/0). If 0 voice data is encrypted, if 1 the voice
///< data is not encrypted. Only used if the server \ref
///< VIRTUALSERVER_CODEC_ENCRYPTION_MODE is set to \ref CODEC_ENCRYPTION_PER_CHANNEL.
///< Always available.
CHANNEL_SECURITY_SALT, ///< String. Read/Write. SDK Only, not used by TeamSpeak. This channels security hash. When
///< a client joins their \ref CLIENT_SECURITY_HASH is compared to this value, to allow or
///< deny the client access to the channel. Used to enforce clients joining the server with
///< specific identity and \ref CLIENT_META_DATA. See SDK Documentation about this feature
///< for further details. Always available.
CHANNEL_DELETE_DELAY, ///< UInt64. Read/Write. Number of seconds deletion of temporary channels is delayed after
///< the last client leaves the channel. Channel is only deleted if empty when the delete
///< delay expired. Always available.
CHANNEL_UNIQUE_IDENTIFIER, ///< String. Read only. An identifier that uniquely identifies a channel. Available in
///< Server >= 3.10.0
CHANNEL_ENDMARKER,
};
enum ClientProperties
{
CLIENT_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Public Identity, can be used to identify a client
///< installation. Remains identical as long as the client keeps using the same
///< identity. Available for visible clients.
CLIENT_NICKNAME, ///< String. Read/Write. Display name of the client. Available for visible clients.
CLIENT_VERSION, ///< String. Read only. Version String of the client used. For clients other than ourself this
///< needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_PLATFORM, ///< String. Read only. Operating system used by the client. For other clients other than ourself
///< this needs to be requested (\ref ts3client_requestClientVariables).
CLIENT_FLAG_TALKING, ///< Integer. Read only. Whether the client is talking. Available on clients that are either
///< whispering to us, or in our channel.
CLIENT_INPUT_MUTED, ///< Integer. Read/Write. Microphone mute status. Available for visible clients. One of the
///< values from the \ref MuteInputStatus enum.
CLIENT_OUTPUT_MUTED, ///< Integer. Read/Write. Speaker mute status. Speaker mute implies microphone mute. Available
///< for visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_OUTPUTONLY_MUTED, ///< Integer. Read/Write. Speaker mute status. Microphone may be active. Available for
///< visible clients. One of the values from the \ref MuteOutputStatus enum.
CLIENT_INPUT_HARDWARE, ///< Integer. Read only. Indicates whether a capture device is open. Available for visible
///< clients. One of the values from the \ref HardwareInputStatus enum.
CLIENT_OUTPUT_HARDWARE, ///< Integer. Read only. Indicates whether a playback device is open. Available for visible
///< clients. One of the values from the \ref HardwareOutputStatus enum.
CLIENT_INPUT_DEACTIVATED, ///< Integer. Read/Write. Not available server side. Local microphone mute status.
///< Available only for own client. Used to implement Push To Talk. One of the values from
///< the \ref InputDeactivationStatus enum.
CLIENT_IDLE_TIME, ///< UInt64. Read only. Seconds since last activity. Available only for own client.
CLIENT_DEFAULT_CHANNEL, ///< String. Read only. User specified channel they joined when connecting to the server.
///< Available only for own client.
CLIENT_DEFAULT_CHANNEL_PASSWORD, ///< String. Read only. User specified channel password for the channel they
///< attempted to join when connecting to the server. Available only for own
///< client.
CLIENT_SERVER_PASSWORD, ///< String. Read only. User specified server password. Available only for own client.
CLIENT_META_DATA, ///< String. Read/Write. Can be used to store up to 4096 bytes of information on clients. Not
///< used by TeamSpeak. Available for visible clients.
CLIENT_IS_MUTED, ///< Integer. Read only. Not available server side. Indicates whether we have muted the client
///< using \ref ts3client_requestMuteClients. Available for visible clients other than ourselves.
CLIENT_IS_RECORDING, ///< Integer. Read only. Indicates whether the client is recording incoming audio. Available
///< for visible clients.
CLIENT_VOLUME_MODIFICATOR, ///< Integer. Read only. Volume adjustment for this client as set by \ref
///< ts3client_setClientVolumeModifier. Available for visible clients.
CLIENT_VERSION_SIGN, ///< String. Read only. TeamSpeak internal signature.
CLIENT_SECURITY_HASH, ///< String. Read/Write. This clients security hash. Not used by TeamSpeak, SDK only. Hash is
///< provided by an outside source. A channel will use the security salt + other client data
///< to calculate a hash, which must be the same as the one provided here. See SDK
///< documentation about Client / Channel Security Hashes for more details.
CLIENT_ENCRYPTION_CIPHERS, ///< String. Read only. SDK only. List of available ciphers this client can use.
CLIENT_IS_STREAMING, ///< bool. Read only, Is currently streaming.
CLIENT_ENDMARKER,
};
enum VirtualServerProperties
{
VIRTUALSERVER_UNIQUE_IDENTIFIER = 0, ///< String. Read only. Unique identifier for a virtual server, does not
///< change on server restart. Available if \ref ts3client_getConnectionStatus
///< is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_NAME, ///< String. Read/Write. The virtual server display name. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_WELCOMEMESSAGE, ///< String. Read/Write. The welcome message displayed to clients on connect.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED. Not
///< updated automatically when changed, updates need to be requested (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_PLATFORM, ///< String. Read only. The operating system the server is running on. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_VERSION, ///< String. Read only. The server software version string. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_MAXCLIENTS, ///< UInt64. Read/Write. The maximum number of clients that can be connected
///< simultaneously. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_PASSWORD, ///< String. Read/Write. The server password. Read access is limited to the server. Clients
///< will only get the password they supplied when connecting. Available if \ref
///< ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_CLIENTS_ONLINE, ///< UInt64. Read only. The current number of clients connected to the server,
///< including query connections. Only available on request (\ref
///< ts3client_requestServerVariables).
VIRTUALSERVER_CHANNELS_ONLINE, ///< UInt64. Read only. The current number of channels on the server. Only
///< available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CREATED, ///< Integer. Read only. The time this virtual server was created as unix timestamp.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_UPTIME, ///< UInt64. Read only. Number of seconds that have passed since the virtual server was
///< started. Only available on request (\ref ts3client_requestServerVariables).
VIRTUALSERVER_CODEC_ENCRYPTION_MODE, ///< Integer. Read/Write. Boolean (1/0) that specifies if voice data is encrypted
///< during transfer. One of the values from the \ref CodecEncryptionMode enum.
///< Available if \ref ts3client_getConnectionStatus is >= \ref STATUS_CONNECTED.
VIRTUALSERVER_ENCRYPTION_CIPHERS, ///< String. Read/Write. Comma separated list of available ciphers to encrypt the
///< connection. The server will use the first cipher in the list that is also
///< listed in the \ref CLIENT_ENCRYPTION_CIPHERS of the connecting client.
///< Clients will fail to connect if no match is found. Always available.
VIRTUALSERVER_ADDRESS, ///< Any resolvable address for the specific virtual server
VIRTUALSERVER_VERSION_SIGN, ///< String. Read only. Signature of Platform and Version.
VIRTUALSERVER_ENDMARKER,
VIRTUALSERVER_FILEBASE = 24, ///< String. Read only. The path to the base directory used to store files
///< transferred using file transfer. Available only on the server. Is set by \ref
///< ts3server_enableFileManager
VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH = 29, ///< UInt64. Read/Write. Maximum traffic in bytes the server can
///< use for file transfer downloads. Only available on request
///< (\ref ts3client_requestServerVariables).
VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH = 30, ///< UInt64. Read/Write. Maximum traffic in bytes the server can use
///< for file transfer uploads. Only available on request (=>
///< requestServerVariables)
VIRTUALSERVER_LOG_FILETRANSFER = 64 ///< Integer. Read/Write. Boolean (1/0) indicating whether to include file
///< transfer activities (uploading or downloading of files) in the server log.
///< Always available.
};
/**
* Various connection properties.
* These are all read only, and except for your own client must be requested using \ref ts3client_requestConnectionInfo
*/
enum ConnectionProperties
{
CONNECTION_PING = 0, ///< UInt64. Round trip latency for the connection based on the last 5 seconds. On the server
///< this is the average across all connected clients for the last 5 seconds.
CONNECTION_PING_DEVIATION, ///< Double. Standard deviation for the round trip latency in \ref CONNECTION_PING
CONNECTION_CONNECTED_TIME, ///< UInt64. Seconds the client has been connected.
CONNECTION_IDLE_TIME, ///< UInt64. Time in seconds since the last activity (voice transmission, switching channels,
///< changing mic / speaker mute status) of the client.
CONNECTION_CLIENT_IP, ///< String. IP of this client (as seen from the server side)
CONNECTION_CLIENT_PORT, ///< UInt64. Client side port of this client (as seen from the server side)
CONNECTION_SERVER_IP, ///< String. The IP or hostname used to connect to the server. Only available on yourself.
CONNECTION_SERVER_PORT, ///< UInt64. The server port connected to. Only available on yourself.
CONNECTION_PACKETS_SENT_SPEECH, ///< UInt64. The number of voice packets transmitted by the client.
CONNECTION_PACKETS_SENT_KEEPALIVE, ///< UInt64. The number of keep alive packets transmitted by the client.
CONNECTION_PACKETS_SENT_CONTROL, ///< UInt64. The number of command & control packets transmitted by the client.
CONNECTION_PACKETS_SENT_TOTAL, ///< UInt64. Total number of packets transmitted by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_SENT_SPEECH, \ref CONNECTION_PACKETS_SENT_KEEPALIVE and
///< \ref CONNECTION_PACKETS_SENT_CONTROL
CONNECTION_BYTES_SENT_SPEECH, ///< UInt64. Outgoing traffic used for voice data by the client.
CONNECTION_BYTES_SENT_KEEPALIVE, ///< UInt64. Outgoing traffic used for keeping the connection alive by the client.
CONNECTION_BYTES_SENT_CONTROL, ///< UInt64. Outgoing traffic used for command & control data by the client.
CONNECTION_BYTES_SENT_TOTAL, ///< UInt64. Total outgoing traffic to the server by this client. Equal to the sum of
///< \ref CONNECTION_BYTES_SENT_SPEECH, \ref CONNECTION_BYTES_SENT_KEEPALIVE and \ref
///< CONNECTION_BYTES_SENT_CONTROL
CONNECTION_PACKETS_RECEIVED_SPEECH, ///< UInt64. Number of voice packets received by the client.
CONNECTION_PACKETS_RECEIVED_KEEPALIVE, ///< UInt64. Number of keep alive packets received by the client.
CONNECTION_PACKETS_RECEIVED_CONTROL, ///< UInt64. Number of command & control packets received by the client.
CONNECTION_PACKETS_RECEIVED_TOTAL, ///< UInt64. Total number of packets received by the client. Equal to the sum of
///< \ref CONNECTION_PACKETS_RECEIVED_SPEECH, \ref
///< CONNECTION_PACKETS_RECEIVED_KEEPALIVE and \ref
///< CONNECTION_PACKETS_RECEIVED_CONTROL
CONNECTION_BYTES_RECEIVED_SPEECH, ///< UInt64. Incoming traffic used by the client for voice data.
CONNECTION_BYTES_RECEIVED_KEEPALIVE, ///< UInt64. Incoming traffic used by the client to keep the connection alive.
CONNECTION_BYTES_RECEIVED_CONTROL, ///< UInt64. Incoming traffic used by the client for command & control data.
CONNECTION_BYTES_RECEIVED_TOTAL, ///< UInt64. Total incoming traffic used by the client. Equal to the sum of \ref
///< CONNECTION_BYTES_RECEIVED_SPEECH, \ref CONNECTION_BYTES_RECEIVED_KEEPALIVE and
///< \ref CONNECTION_BYTES_RECEIVED_CONTROL
CONNECTION_PACKETLOSS_SPEECH, ///< Double. Percentage points of voice packets for the client that did not arrive at
///< the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_KEEPALIVE, ///< Double. Percentage points of keep alive packets for the client that did not
///< arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_CONTROL, ///< Double. Percentage points of command & control packets for the client that did
///< not arrive at the client or server averaged across the last 5 seconds.
CONNECTION_PACKETLOSS_TOTAL, ///< Double. Cumulative chance in percentage points with which a packet round trip
///< failed because a packet was lost
CONNECTION_SERVER2CLIENT_PACKETLOSS_SPEECH, ///< Double. Probability with which a voice packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< server was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the server
///< was not received by the client.
CONNECTION_SERVER2CLIENT_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the server was not
///< received by the client.
CONNECTION_CLIENT2SERVER_PACKETLOSS_SPEECH, ///< Double. Probability with which a speech packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_KEEPALIVE, ///< Double. Probability with which a keepalive packet sent by the
///< client was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_CONTROL, ///< Double. Probability with which a control packet sent by the client
///< was not received by the server.
CONNECTION_CLIENT2SERVER_PACKETLOSS_TOTAL, ///< Double. Probability with which a packet sent by the client was not
///< received by the server.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes sent for speech data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes sent for keepalive data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes sent for control data in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes sent in the last second.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second sent for speech data, averaged over the
///< last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second sent for keepalive data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second sent for control data, averaged over
///< the last minute.
CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second sent, averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_SPEECH, ///< UInt64. Number of bytes received for speech data in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_KEEPALIVE, ///< UInt64. Number of bytes received for keepalive data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_CONTROL, ///< UInt64. Number of bytes received for control data in the
///< last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, ///< UInt64. Number of bytes received in the last second.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_SPEECH, ///< UInt64. Bytes per second received for speech data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_KEEPALIVE, ///< UInt64. Bytes per second received for keepalive data,
///< averaged over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_CONTROL, ///< UInt64. Bytes per second received for control data, averaged
///< over the last minute.
CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, ///< UInt64. Bytes per second received, averaged over the last minute.
CONNECTION_DUMMY_0,
CONNECTION_DUMMY_1,
CONNECTION_DUMMY_2,
CONNECTION_DUMMY_3,
CONNECTION_DUMMY_4,
CONNECTION_DUMMY_5,
CONNECTION_DUMMY_6,
CONNECTION_DUMMY_7,
CONNECTION_DUMMY_8,
CONNECTION_DUMMY_9,
CONNECTION_FILETRANSFER_BANDWIDTH_SENT, ///< UInt64. Current file transfer upstream activity in bytes per second.
///< Only available on request (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, ///< UInt64. Current file transfer downstream activity in bytes per
///< second. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, ///< UInt64. Total downstream traffic, in bytes, used for file
///< transfer since the server was started. Only available on request
///< (\ref ts3client_requestServerConnectionInfo).
CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, ///< UInt64. Total upstream traffic, in bytes, used for file transfer
///< since the server was started. Only available on request (\ref
///< ts3client_requestServerConnectionInfo).
CONNECTION_ENDMARKER
};
/**
* Describes a client position in 3 dimensional space, used for 3D Sound.
*/
typedef struct
{
float x; ///< X co-ordinate in 3D space.
float y; ///< Y co-ordinate in 3D space.
float z; ///< Z co-ordinate in 3D space.
} TS3_VECTOR;
enum GroupWhisperType
{
GROUPWHISPERTYPE_SERVERGROUP = 0, ///< Whisper list consists of server groups
GROUPWHISPERTYPE_CHANNELGROUP = 1, ///< Whisper list consists of channel groups
GROUPWHISPERTYPE_CHANNELCOMMANDER = 2, ///< whisper to channel commanders
GROUPWHISPERTYPE_ALLCLIENTS = 3, ///< whisper to all clients
GROUPWHISPERTYPE_ENDMARKER,
};
enum GroupWhisperTargetMode
{
GROUPWHISPERTARGETMODE_ALL = 0,
GROUPWHISPERTARGETMODE_CURRENTCHANNEL = 1, ///< Whisper the current channel of the client
GROUPWHISPERTARGETMODE_PARENTCHANNEL = 2, ///< Whisper the parent channel of whatever channel the client is currently in
GROUPWHISPERTARGETMODE_ALLPARENTCHANNELS = 3, ///< Whipser to the parent channel and all their parent channels as well
GROUPWHISPERTARGETMODE_CHANNELFAMILY = 4, ///< Whisper to the current channel and all its sub channels
GROUPWHISPERTARGETMODE_ANCESTORCHANNELFAMILY = 5, ///< Whisper to the current channel, all its parent and sub channels.
GROUPWHISPERTARGETMODE_SUBCHANNELS = 6, ///< Whisper to all sub channels of the current channel of the client
GROUPWHISPERTARGETMODE_ENDMARKER,
};
enum MonoSoundDestination
{
MONO_SOUND_DESTINATION_ALL = 0, ///< Send mono sound to all available speakers
MONO_SOUND_DESTINATION_FRONT_CENTER = 1, ///< Send mono sound to front center speaker if available
MONO_SOUND_DESTINATION_FRONT_LEFT_AND_RIGHT = 2 ///< Send mono sound to front left/right speakers if available
};
enum SecuritySaltOptions
{
SECURITY_SALT_CHECK_NICKNAME = 1, ///< put nickname into security hash
SECURITY_SALT_CHECK_META_DATA = 2 ///< put meta data into security hash
};
/*this enum is used to disable client commands on the server*/
enum ClientCommand
{
CLIENT_COMMAND_requestConnectionInfo = 0, ///< disable client connection info request (client bandwidth usage, ip,
///< port, ping)
CLIENT_COMMAND_requestClientMove = 1, ///< disable moving clients
CLIENT_COMMAND_requestXXMuteClients = 2, ///< disable muting other clients
CLIENT_COMMAND_requestClientKickFromXXX = 3, ///< disable kicking clients
CLIENT_COMMAND_flushChannelCreation = 4, ///< disable creating channels
CLIENT_COMMAND_flushChannelUpdates = 5, ///< disable editing channels
CLIENT_COMMAND_requestChannelMove = 6, ///< disable moving channels
CLIENT_COMMAND_requestChannelDelete = 7, ///< disable deleting channels
CLIENT_COMMAND_requestChannelDescription = 8, ///< disable channel descriptions
CLIENT_COMMAND_requestChannelXXSubscribeXXX = 9, ///< disable being able to see clients in channels other than the
///< current channel the client is in
CLIENT_COMMAND_requestServerConnectionInfo = 10, ///< disable server connection info request (server bandwidth
///< usage, ip, port, ping)
CLIENT_COMMAND_requestSendXXXTextMsg = 11, ///< disable text messaging
CLIENT_COMMAND_filetransfers = 12, ///< disable file transfer
CLIENT_COMMAND_ENDMARKER
};
/* Access Control List*/
enum ACLType
{
ACL_NONE = 0,
ACL_WHITE_LIST = 1,
ACL_BLACK_LIST = 2
};
/* file transfer actions*/
enum FTAction
{
FT_INIT_SERVER = 0, ///< The virtual server is created. result->channelPath can be changed to create a different
///< directory than the default 'virtualserver_x' where x is the virtual server.
FT_INIT_CHANNEL = 1, ///< A channel is created. result->channelPath can be changed to create a different directory
///< then the default 'channel_x' where x is the channel id.
FT_UPLOAD = 2, ///< A file is being uploaded. All values in the result struct can be modified.
FT_DOWNLOAD = 3, ///< A file is being downloaded. All values in the result struct can be modified.
FT_DELETE = 4, ///< A file is being deleted. All values in the result struct can be modified.
FT_CREATEDIR = 5, ///< A directory is being created in a channel. All values in the result struct can be modified.
FT_RENAME = 6, ///< A file or folder is being renamed. The callback will be called twice! Once for the old and then
///< for the new name. All values in the result struct can be modified.
FT_FILELIST = 7, ///< A directory listing is requested. All values in the result struct can be modified.
FT_FILEINFO = 8 ///< Information of a file is requested. All values in the result struct can be modified.
};
/* file transfer status */
enum FileTransferState
{
FILETRANSFER_INITIALISING = 0, ///< File transfer is establishing connection.
FILETRANSFER_ACTIVE, ///< File transfer is in progress
FILETRANSFER_FINISHED, ///< File transfer has finished
};
/* file transfer types */
enum FileTransferType
{
FileListType_Directory = 0, ///< The file entry is a directory
FileListType_File, ///< The file entry is a regular file
};
/* some structs to handle variables in callbacks */
#define MAX_VARIABLES_EXPORT_COUNT 64
struct VariablesExportItem
{
unsigned char itemIsValid; ///< Whether or not there is any data in this item. Ignore this item if this is 0.
unsigned char proposedIsSet; ///< The value in proposed is set. If 0 ignore proposed
const char* current; ///< current value (stored in memory)
const char* proposed; ///< New value to change to (const, so no updates please)
};
struct VariablesExport
{
struct VariablesExportItem items[MAX_VARIABLES_EXPORT_COUNT];
};
struct ClientMiniExport
{
anyID ID; ///< id of the client
uint64 channel; ///< the channel the client is in
const char* ident; ///< client public identity
const char* nickname; ///< client display name
};
/**
* Structure used to describe a file transfer in the \ref ServerLibFunctions.onTransformFilePath callback.
* This describes the original values, and also contains hints for length limitations of the result parameter
* of the callback.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExport
{
uint64 channel; ///< The channel id of the file. 0 if action is \ref FT_INIT_SERVER
const char* filename; ///< utf8 encoded c string containing the original file name as intended by the client.
int action; ///< The action to be performed. One of the values from the \ref FTAction enum. Defines which values of
///< the result struct can be modified.
int transformedFileNameMaxSize; ///< The maximum length the file name can be rewritten to.
int channelPathMaxSize; ///< The maximum length the path can be rewritten to.
};
/**
* Structure to rewrite the file transfer file name and path in the \ref ServerLibFunctions.onTransformFilePath callback.
* The lengths are limited as described in the original parameter.
* \verbatim embed:rst
.. important::
Which values of the struct can be modified is defined by the action value of the original parameter.
\endverbatim
*/
struct TransformFilePathExportReturns
{
char* transformedFileName; ///< pointer to target file name. Fill the memory pointed to with an utf8 encoded c string
///< containing the new file name. Limited to original->transformedFileNameMaxSize bytes.
char* channelPath; ///< pointer to memory for new path. Fill the memory pointed to with an utf8 encoded c string
///< containing the new path. Limited to original->channelPathMaxSize bytes.
int logFileAction; ///< boolean (1/0). Whether to log this file transfer to the log. Action is not logged regardless
///< of this value if the servers \ref VIRTUALSERVER_LOG_FILETRANSFER property is 0.
};
struct FileTransferCallbackExport
{
anyID clientID; ///< the client who started the file transfer
anyID transferID; ///< local identifier of the transfer that has completed
anyID remoteTransferID; ///< remote identifier of the transfer that has completed
unsigned int status; ///< status of the transfer. One of the values from the \ref FileTransferState enum
const char* statusMessage; ///< utf8 encoded c string containing a human readable description of the status
uint64 remotefileSize; ///< size in bytes of the complete file to be transferred
uint64 bytes; ///< number of bytes transferred. Same as remotefileSize when the transfer completed entirely.
int isSender; ///< boolean. 1 if the server is sending the file. 0 if the server is receiving the file.
};
/*define for file transfer bandwith limits*/
#define BANDWIDTH_LIMIT_UNLIMITED 0xFFFFFFFFFFFFFFFFll
/*defines for speaker locations used by some sound callbacks*/
#ifndef SPEAKER_FRONT_LEFT
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000
#endif
#define SPEAKER_HEADPHONES_LEFT 0x10000000
#define SPEAKER_HEADPHONES_RIGHT 0x20000000
#define SPEAKER_MONO 0x40000000
#endif /*PUBLIC_DEFINITIONS_H*/
@@ -0,0 +1,217 @@
#ifndef PUBLIC_ERRORS_H
#define PUBLIC_ERRORS_H
//The idea here is: the values are 2 bytes wide, the first byte identifies the group, the second the count within that group
enum Ts3ErrorType {
//general
ERROR_ok = 0x0000, ///< Indicates success.
ERROR_undefined = 0x0001,
ERROR_not_implemented = 0x0002, ///< The attempted operation is not available in this context
ERROR_ok_no_update = 0x0003, ///< Indicates success, but no change occurred. Returned for example upon flushing (e.g. using \ref ts3client_flushChannelUpdates) when all indicated changes already matched the current state.
ERROR_dont_notify = 0x0004,
ERROR_lib_time_limit_reached = 0x0005,
ERROR_out_of_memory = 0x0006, ///< Not enough system memory to perform operation
ERROR_canceled = 0x0007,
ERROR_ok_no_error_event = 0x0008, ///< Indicates success, but no error event was generated. This is used because of the return code management and reduce packets.
//dunno
ERROR_command_not_found = 0x0100,
ERROR_unable_to_bind_network_port = 0x0101, ///< Unspecified failure to create a listening port
ERROR_no_network_port_available = 0x0102, ///< Failure to initialize a listening port for FileTransfer
ERROR_port_already_in_use = 0x0103, ///< Specified port is already in use by a different application
ERROR_command_line_parse_failed = 0x0104, ///< Command line arguments are invalid
ERROR_command_line_exit_version = 0x0105, ///< Command line specified version. The process should exit with code 0 after printing the version.
ERROR_command_line_exit_help = 0x0106, ///< Command line specified help. The process should exit with code 0 after priting the help.
//client
ERROR_client_invalid_id = 0x0200, ///< Client no longer connected
ERROR_client_nickname_inuse = 0x0201, ///< Client name is already in use. Client names must be unique
ERROR_client_protocol_limit_reached = 0x0203, ///< Too many clients on the server
ERROR_client_invalid_type = 0x0204, ///< Function called for normal clients that is only available for query clients or vice versa
ERROR_client_already_subscribed = 0x0205, ///< Attempting to subscribe to a channel already subscribed to
ERROR_client_not_logged_in = 0x0206,
ERROR_client_could_not_validate_identity = 0x0207, ///< Identity not valid or insufficient security level
ERROR_client_invalid_password = 0x0208,
ERROR_client_version_outdated = 0x020a, ///< Server requires newer client version as determined by the min_client_version properties
ERROR_client_is_flooding = 0x020c, ///< Triggered flood protection. Further information is supplied in the extra message if applicable.
ERROR_client_hacked = 0x020d,
ERROR_client_cannot_verify_now = 0x020e,
ERROR_client_login_not_permitted = 0x020f,
ERROR_client_not_subscribed = 0x0210, ///< Action is only available on subscribed channels
//channel
ERROR_channel_invalid_id = 0x0300, ///< Channel does not exist on the server (any longer)
ERROR_channel_protocol_limit_reached = 0x0301, ///< Too many channels on the server
ERROR_channel_already_in = 0x0302, ///< Attempting to move a client or channel to its current channel
ERROR_channel_name_inuse = 0x0303, ///< Channel name is already taken by another channel. Channel names must be unique
ERROR_channel_not_empty = 0x0304, ///< Attempting to delete a channel with clients or sub channels in it
ERROR_channel_can_not_delete_default = 0x0305, ///< Default channel cannot be deleted. Set a new default channel first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_default_require_permanent = 0x0306, ///< Attempt to set a non permanent channel as default channel. Set channel to permanent first (see \ref ts3client_setChannelVariableAsInt or \ref ts3server_setChannelVariableAsInt )
ERROR_channel_invalid_flags = 0x0307, ///< Invalid combination of \ref ChannelProperties, trying to remove \ref CHANNEL_FLAG_DEFAULT or set a password on the default channel
ERROR_channel_parent_not_permanent = 0x0308, ///< Attempt to move a permanent channel into a non-permanent one, or set a channel to be permanent that is a sub channel of a non-permanent one
ERROR_channel_maxclients_reached = 0x0309, ///< Channel is full as determined by its \ref CHANNEL_MAXCLIENTS setting
ERROR_channel_maxfamily_reached = 0x030a, ///< Channel tree is full as determined by its \ref CHANNEL_MAXFAMILYCLIENTS setting
ERROR_channel_invalid_order = 0x030b, ///< Invalid value for the \ref CHANNEL_ORDER property. The specified channel must exist on the server and be on the same level.
ERROR_channel_no_filetransfer_supported = 0x030c, ///< Invalid \ref CHANNEL_FILEPATH set for the channel
ERROR_channel_invalid_password = 0x030d, ///< Channel has a password not matching the password supplied in the call
// used in public_rare_errors = 0x030e,
ERROR_channel_invalid_security_hash = 0x030f,
//server
ERROR_server_invalid_id = 0x0400, ///< Chosen virtual server does not exist or is offline
ERROR_server_running = 0x0401, ///< attempting to delete a server that is running. Stop the server before deleting it.
ERROR_server_is_shutting_down = 0x0402, ///< Client disconnected because the server is going offline
ERROR_server_maxclients_reached = 0x0403, ///< Given in the onConnectStatusChange event when the server has reached its maximum number of clients as defined by the \ref VIRTUALSERVER_MAXCLIENTS property
ERROR_server_invalid_password = 0x0404, ///< Specified server password is wrong. Provide the correct password in the \ref ts3client_startConnection / \ref ts3client_startConnectionWithChannelID call.
ERROR_server_is_virtual = 0x0407, ///< Server is in virtual status. The attempted action is not possible in this state. Start the virtual server first.
ERROR_server_is_not_running = 0x0409, ///< Attempting to stop a server that is not online.
ERROR_server_is_booting = 0x040a, // Not used
ERROR_server_status_invalid = 0x040b,
ERROR_server_version_outdated = 0x040d, ///< Attempt to connect to an outdated server version. The server needs to be updated.
ERROR_server_duplicate_running = 0x040e, ///< This server is already running within the instance. Each virtual server may only exist once.
//parameter
ERROR_parameter_quote = 0x0600, // Not used
ERROR_parameter_invalid_count = 0x0601, ///< Attempt to flush changes without previously calling set*VariableAs* since the last flush
ERROR_parameter_invalid = 0x0602, ///< At least one of the supplied parameters did not meet the criteria for that parameter
ERROR_parameter_not_found = 0x0603, ///< Failure to supply all the necessary parameters
ERROR_parameter_convert = 0x0604, ///< Invalid type supplied for a parameter, such as passing a string (ie. "five") that expects a number.
ERROR_parameter_invalid_size = 0x0605, ///< Value out of allowed range. Such as strings are too long/short or numeric values outside allowed range
ERROR_parameter_missing = 0x0606, ///< Neglecting to specify a required parameter
ERROR_parameter_checksum = 0x0607, ///< Attempting to deploy a modified snapshot
//unsorted, need further investigation
ERROR_vs_critical = 0x0700, ///< Failure to create default channel
ERROR_connection_lost = 0x0701, ///< Generic error with the connection.
ERROR_not_connected = 0x0702, ///< Attempting to call functions with a serverConnectionHandler that is not connected. You can use \ref ts3client_getConnectionStatus to check whether the connection handler is connected to a server
ERROR_no_cached_connection_info = 0x0703, ///< Attempting to query connection information (bandwidth usage, ping, etc) without requesting them first using \ref ts3client_requestConnectionInfo
ERROR_currently_not_possible = 0x0704, ///< Requested information is not currently available. You may have to call \ref ts3client_requestClientVariables or \ref ts3client_requestServerVariables
ERROR_failed_connection_initialisation = 0x0705, ///< No TeamSpeak server running on the specified IP address and port
ERROR_could_not_resolve_hostname = 0x0706, ///< Failure to resolve the specified hostname to an IP address
ERROR_invalid_server_connection_handler_id = 0x0707, ///< Attempting to perform actions on a non-existent server connection handler
ERROR_could_not_initialise_input_manager = 0x0708, // Not used
ERROR_clientlibrary_not_initialised = 0x0709, ///< Calling client library functions without successfully calling \ref ts3client_initClientLib before
ERROR_serverlibrary_not_initialised = 0x070a, ///< Calling server library functions without successfully calling \ref ts3server_initServerLib before
ERROR_whisper_too_many_targets = 0x070b, ///< Using a whisper list that contain more clients than the servers \ref VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE property
ERROR_whisper_no_targets = 0x070c, ///< The active whisper list is empty or no clients matched the whisper list (e.g. all channels in the list are empty)
ERROR_connection_ip_protocol_missing = 0x070d, ///< Invalid or unsupported protocol (e.g. attempting an IPv6 connection on an IPv4 only machine)
ERROR_handshake_failed = 0x070e,
ERROR_illegal_server_license = 0x070f,
//file transfer
ERROR_file_invalid_name = 0x0800, ///< Invalid UTF8 string or not a valid file
ERROR_file_invalid_permissions = 0x0801, ///< Permissions prevent opening the file
ERROR_file_already_exists = 0x0802, ///< Target path already exists as a directory
ERROR_file_not_found = 0x0803, ///< Attempt to access or move non existing file
ERROR_file_io_error = 0x0804, ///< Generic file input / output error
ERROR_file_invalid_transfer_id = 0x0805, ///< Attempt to get information about a file transfer after it has already been cleaned up. File transfer information is not available indefinitely after the transfer completed
ERROR_file_invalid_path = 0x0806, ///< specified path contains invalid characters or does not start with "/"
ERROR_file_no_files_available = 0x0807, // Not used
ERROR_file_overwrite_excludes_resume = 0x0808, ///< File overwrite and resume are mutually exclusive. Only one or neither can be 1.
ERROR_file_invalid_size = 0x0809, ///< Attempt to write more bytes than claimed file size.
ERROR_file_already_in_use = 0x080a, ///< File is currently not available, try again later.
ERROR_file_could_not_open_connection = 0x080b, ///< Generic failure in file transfer connection / other party did not conform to file transfer protocol
ERROR_file_no_space_left_on_device = 0x080c, ///< Operating system reports hard disk is full. May be caused by quota limitations.
ERROR_file_exceeds_file_system_maximum_size = 0x080d, ///< File is too large for the file system of the target device.
ERROR_file_transfer_connection_timeout = 0x080e, // Not used
ERROR_file_connection_lost = 0x080f, ///< File input / output timeout or connection failure
ERROR_file_exceeds_supplied_size = 0x0810, // Not used
ERROR_file_transfer_complete = 0x0811, ///< Indicates successful completion
ERROR_file_transfer_canceled = 0x0812, ///< Transfer was cancelled through @ref ts3client_haltTransfer
ERROR_file_transfer_interrupted = 0x0813, ///< Transfer failed because the server is shutting down, or network connection issues
ERROR_file_transfer_server_quota_exceeded = 0x0814, ///< Transfer terminated due to server bandwidth quota being exceeded. No client can transfer files.
ERROR_file_transfer_client_quota_exceeded = 0x0815, ///< Attempt to transfer more data than allowed by this clients' bandwidth quota. Other clients may continue to transfer files.
ERROR_file_transfer_reset = 0x0816, // Not used
ERROR_file_transfer_limit_reached = 0x0817, ///< Too many file transfers are in progress. Try again later
ERROR_file_invalid_storage_class = 0x0818, // TODO: Invalid storage class for HTTP FileTransfer (what is a storage class?)
ERROR_file_invalid_dimension = 0x0819, ///< Avatar image exceeds maximum width or height accepted by the server.
ERROR_file_transfer_channel_quota_exceeded = 0x081a, ///< Transfer failed because the channel quota was exceeded. Uploading to this channel is not possible, but other channels may be fine.
//sound
ERROR_sound_preprocessor_disabled = 0x0900, ///< Cannot set or query pre processor variables with preprocessing disabled
ERROR_sound_internal_preprocessor = 0x0901,
ERROR_sound_internal_encoder = 0x0902,
ERROR_sound_internal_playback = 0x0903,
ERROR_sound_no_capture_device_available = 0x0904, ///< No audio capture devices are available
ERROR_sound_no_playback_device_available = 0x0905, ///< No audio playback devices are available
ERROR_sound_could_not_open_capture_device = 0x0906, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_could_not_open_playback_device = 0x0907, ///< Error accessing audio device, or audio device does not support the requested mode
ERROR_sound_handler_has_device = 0x0908, ///< Attempt to open a sound device on a connection handler which already has an open device. Close the already open device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_invalid_capture_device = 0x0909, ///< Attempt to use a device for capture that does not support capturing audio
ERROR_sound_invalid_playback_device = 0x090a, ///< Attempt to use a device for playback that does not support playback of audio
ERROR_sound_invalid_wave = 0x090b, ///< Attempt to use a non WAV file in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle
ERROR_sound_unsupported_wave = 0x090c, ///< Unsupported wave file used in \ref ts3client_playWaveFile or \ref ts3client_playWaveFileHandle.
ERROR_sound_open_wave = 0x090d, ///< Failure to open the specified sound file
ERROR_sound_internal_capture = 0x090e,
ERROR_sound_device_in_use = 0x090f, ///< Attempt to unregister a custom device that is being used. Close the device first using \ref ts3client_closeCaptureDevice or \ref ts3client_closePlaybackDevice
ERROR_sound_device_already_registerred = 0x0910, ///< Attempt to register a custom device with a device id that has already been used in a previous call. Device ids must be unique.
ERROR_sound_unknown_device = 0x0911, ///< Attempt to open, close, unregister or use a device which is not known. Custom devices must be registered before being used (see \ref ts3client_registerCustomDevice)
ERROR_sound_unsupported_frequency = 0x0912,
ERROR_sound_invalid_channel_count = 0x0913, ///< Invalid device audio channel count, must be > 0
ERROR_sound_read_wave = 0x0914, ///< Failure to read sound samples from an opened wave file. Is this a valid wave file?
ERROR_sound_need_more_data = 0x0915, // for internal purposes only
ERROR_sound_device_busy = 0x0916, // for internal purposes only
ERROR_sound_no_data = 0x0917, ///< Indicates there is currently no data for playback, e.g. nobody is speaking right now.
ERROR_sound_channel_mask_mismatch = 0x0918, ///< Opening a device with an unsupported channel count
//permissions
ERROR_permissions_client_insufficient = 0x0a08, ///< Not enough permissions to perform the requested activity
ERROR_permissions = 0x0a0c, ///< Permissions to use sound device not granted by operating system, e.g. Windows denied microphone access.
//accounting
ERROR_accounting_virtualserver_limit_reached = 0x0b00, ///< Attempt to use more virtual servers than allowed by the license
ERROR_accounting_slot_limit_reached = 0x0b01, ///< Attempt to set more slots than allowed by the license
ERROR_accounting_license_file_not_found = 0x0b02, // Not used
ERROR_accounting_license_date_not_ok = 0x0b03, ///< License expired or not valid yet
ERROR_accounting_unable_to_connect_to_server = 0x0b04, ///< Failure to communicate with accounting backend
ERROR_accounting_unknown_error = 0x0b05, ///< Failure to write update license file
ERROR_accounting_server_error = 0x0b06, // Not used
ERROR_accounting_instance_limit_reached = 0x0b07, ///< More than one process of the server is running
ERROR_accounting_instance_check_error = 0x0b08, ///< Shared memory access failure.
ERROR_accounting_license_file_invalid = 0x0b09, ///< License is not a TeamSpeak license
ERROR_accounting_running_elsewhere = 0x0b0a, ///< A copy of this server is already running in another instance. Each server may only exist once.
ERROR_accounting_instance_duplicated = 0x0b0b, ///< A copy of this server is running already in this process. Each server may only exist once.
ERROR_accounting_already_started = 0x0b0c, ///< Attempt to start a server that is already running
ERROR_accounting_not_started = 0x0b0d,
ERROR_accounting_to_many_starts = 0x0b0e, ///< Starting instance / virtual servers too often in too short a time period
//provisioning server
/// @cond HAS_PROVISIONING
ERROR_provisioning_invalid_password = 0x1100,
ERROR_provisioning_invalid_request = 0x1101,
ERROR_provisioning_no_slots_available = 0x1102,
ERROR_provisioning_pool_missing = 0x1103,
ERROR_provisioning_pool_unknown = 0x1104,
ERROR_provisioning_unknown_ip_location = 0x1105,
ERROR_provisioning_internal_tries_exceeded = 0x1106,
ERROR_provisioning_too_many_slots_requested = 0x1107,
ERROR_provisioning_too_many_reserved = 0x1108,
ERROR_provisioning_could_not_connect = 0x1109,
ERROR_provisioning_auth_server_not_connected = 0x1110,
ERROR_provisioning_auth_data_too_large = 0x1111,
ERROR_provisioning_already_initialized = 0x1112,
ERROR_provisioning_not_initialized = 0x1113,
ERROR_provisioning_connecting = 0x1114,
ERROR_provisioning_already_connected = 0x1115,
ERROR_provisioning_not_connected = 0x1116,
ERROR_provisioning_io_error = 0x1117,
ERROR_provisioning_invalid_timeout = 0x1118,
ERROR_provisioning_ts3server_not_found = 0x1119,
ERROR_provisioning_no_permission = 0x111A,
/// @endcond
// 0x12 - 0x15 are reserved in rare
// screen share
ERROR_already_registered = 0x1600,
ERROR_stream_session_limit_reached = 0x1601,
ERROR_stream_session_not_found = 0x1602,
ERROR_stream_unknown = 0x1603,
ERROR_stream_not_participating = 0x1604,
ERROR_not_streamer = 0x1605,
ERROR_already_joined = 0x1606,
ERROR_join_request_not_found = 0x1607,
ERROR_sfu_failed_to_start = 0x1608,
};
#endif
@@ -0,0 +1,236 @@
#ifndef TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#define TS_SESSION_SUBSCRIBER_PROTOCOL_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
// Version definitions.
#define TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1 1
// Protocol used for communication between the session subscriber and the session (a single stream).
// Commands are sent bidirectionally or unidirectionally between the parties.
// e.g. SESSION => SUBSCRIBER: ON_FRAME, ON_PAUSED_CHANGED
// e.g. SUBSCRIBER => SESSION: ON_FRAME_ACK, ON_RESIZE
// Command type enum with a lowercase type name.
typedef enum
{
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME = 0,
TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE,
TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED,
TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE,
TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK,
TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP,
TS_SESSION_SUBSCRIBER_CMD_REMOVE_SUBSCRIBER,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES,
TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED,
} ts_session_subscriber_command_type_t;
// Pixel format enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_I420 = 0,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_NV12,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ABGR,
TS_SESSION_SUBSCRIBER_PIXEL_FORMAT_ARGB,
} ts_session_subscriber_pixel_format_t;
// Buffer location enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_CPU = 0,
TS_SESSION_SUBSCRIBER_BUFFER_LOCATION_GPU
} ts_session_subscriber_buffer_location_t;
// Buffer type enum.
typedef enum
{
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_SINGLE = 0,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_MAIN,
TS_SESSION_SUBSCRIBER_BUFFER_TYPE_FRONT_BACK_SUB
} ts_session_subscriber_buffer_type_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(push, 4)
#endif
// Main buffer header for shared CPU Memory Front/Back Buffers.
// The Main Buffer contains metadata about the current front/back buffer and the versioning for both the main and sub buffer.
// The information from the main buffer can be used to always read the front buffer.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t front_buffer_index; // index of the front buffer. (0: main buffer, 1: sub buffer)
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_main_buffer_header_t;
// Sub buffer header.
typedef struct
{
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
} ts_session_subscriber_sub_buffer_header_t;
// Single frame buffer header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // length of valid data of this buffer.
uint32_t pixel_data_offset; // offset of pixel data from the beginning of this buffer. (in bytes, total length of pixel data = length - pixel_data_offset)
uint32_t frame_id; // frame id. (used to skip duplicated frames)
uint32_t width; // width of the frame.
uint32_t height; // height of the frame.
ts_session_subscriber_pixel_format_t pixel_format; // pixel format.
} ts_session_subscriber_single_frame_buffer_header_t;
// Command header.
typedef struct
{
uint32_t version; // E.g., TS_SESSION_SUBSCRIBER_COMMAND_VERSION_1.
uint32_t length; // Total message length (header + payload).
ts_session_subscriber_command_type_t type;
uint64_t target_session_id; // always set to the target session id this command is for or is originating from.
uint64_t target_subscriber_id; // 0 if broadcast.
} ts_session_subscriber_command_header_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME.
// The frame data is not included in the message, but is attached seperately or was sent beforehand. The buffer is identified by it's id.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_id; // buffer id, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_frame_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_FRAME_ACK
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t frame_id;
} ts_session_subscriber_on_frame_ack_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RESIZE.
// SUBSCRIBER => SESSION.
typedef struct
{
uint32_t width;
uint32_t height;
} ts_session_subscriber_on_resize_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_PAUSED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t paused; // 0 or 1.
} ts_session_subscriber_on_paused_changed_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_SINGLE.
// Contains a single frame buffer. The header is of format |ts_session_subscriber_single_frame_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
ts_session_subscriber_buffer_type_t buffer_type;
} ts_session_subscriber_on_buffer_single_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_BUFFER_FRONT_BACK.
// Contains a main buffer and a sub buffer. The main buffer header
// contains metadata about the current front/back buffer and
// is of type |ts_session_subscriber_main_buffer_header_t|.
// The sub buffer's header is of type |ts_session_subscriber_sub_buffer_header_t|.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t main_buffer_ptr; // main buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t main_buffer_length;
uint64_t sub_buffer_ptr; // sub buffer pointer, in general the memory address of the buffer in the client lib process.
uint32_t sub_buffer_length;
ts_session_subscriber_buffer_location_t buffer_location;
} ts_session_subscriber_on_buffer_front_back_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER.
// SUBSCRIBER => SESSION.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ADD_SUBSCRIBER_RESP.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t request_id;
} ts_session_subscriber_add_subscriber_resp_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_RELEASE_BUFFER.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr; // buffer pointer, in general the memory address of the buffer in the client lib process.
} ts_session_subscriber_on_release_buffer_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_FRAMES.
// SESSION => SUBSCRIBER.
typedef struct
{
uint64_t buffer_ptr;
int bits_per_sample;
int sample_rate;
uint32_t number_of_channels;
uint32_t number_of_frames;
int64_t absolute_capture_timestamp_ms;
float volume;
} ts_session_subscriber_on_audio_frames_payload_t;
// Payload for TS_SESSION_SUBSCRIBER_CMD_ON_AUDIO_ENABLED_CHANGED.
// SESSION => SUBSCRIBER.
typedef struct
{
uint32_t audio_enabled;
} ts_session_subscriber_on_audio_enabled_changed_payload_t;
// Overall Command structure.
typedef struct
{
ts_session_subscriber_command_header_t header;
union
{
ts_session_subscriber_on_frame_payload_t frame;
ts_session_subscriber_on_resize_payload_t resize;
ts_session_subscriber_on_paused_changed_payload_t paused;
ts_session_subscriber_on_frame_ack_payload_t frame_ack;
ts_session_subscriber_on_buffer_single_payload_t buffer_single;
ts_session_subscriber_on_buffer_front_back_payload_t buffer_front_back;
ts_session_subscriber_on_release_buffer_payload_t release_buffer;
ts_session_subscriber_add_subscriber_payload_t add_subscriber;
ts_session_subscriber_add_subscriber_resp_payload_t add_subscriber_resp;
ts_session_subscriber_on_audio_frames_payload_t audio_frames;
ts_session_subscriber_on_audio_enabled_changed_payload_t audio_enabled_changed;
} payload;
} ts_session_subscriber_command_t;
#if defined(__clang__) || defined(__GNUC__) || defined(_MSC_VER)
#pragma pack(pop)
#endif
#ifdef __cplusplus
}
#endif
#endif // TS_SESSION_SUBSCRIBER_PROTOCOL_H_
@@ -0,0 +1,29 @@
####### Expanded from @PACKAGE_INIT@ by configure_package_config_file() #######
####### Any changes to this file will be overwritten by the next CMake run ####
####### The input file was team_clientConfig.cmake.in ########
get_filename_component(PACKAGE_PREFIX_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../" ABSOLUTE)
macro(set_and_check _var _file)
set(${_var} "${_file}")
if(NOT EXISTS "${_file}")
message(FATAL_ERROR "File or directory ${_file} referenced by variable ${_var} does not exist !")
endif()
endmacro()
macro(check_required_components _NAME)
foreach(comp ${${_NAME}_FIND_COMPONENTS})
if(NOT ${_NAME}_${comp}_FOUND)
if(${_NAME}_FIND_REQUIRED_${comp})
set(${_NAME}_FOUND FALSE)
endif()
endif()
endforeach()
endmacro()
####################################################################################
include("${CMAKE_CURRENT_LIST_DIR}/team_clientTargets.cmake")
check_required_components(team_client)
@@ -0,0 +1,19 @@
#----------------------------------------------------------------
# Generated CMake target import file for configuration "Release".
#----------------------------------------------------------------
# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)
# Import target "teamspeak::client" for configuration "Release"
set_property(TARGET teamspeak::client APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
set_target_properties(teamspeak::client PROPERTIES
IMPORTED_IMPLIB_RELEASE "${_IMPORT_PREFIX}/lib/teamspeak_sdk_client.lib"
IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/bin/teamspeak_sdk_client.dll"
)
list(APPEND _cmake_import_check_targets teamspeak::client )
list(APPEND _cmake_import_check_files_for_teamspeak::client "${_IMPORT_PREFIX}/lib/teamspeak_sdk_client.lib" "${_IMPORT_PREFIX}/bin/teamspeak_sdk_client.dll" )
# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)

Some files were not shown because too many files have changed in this diff Show More