首次推送
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
<div align="center">
|
||||
|
||||
# teamspeak-go
|
||||
|
||||
**A clean-room TeamSpeak client protocol library written in pure Go.**
|
||||
|
||||
Compatible with TeamSpeak 3, 5 & 6. No proprietary SDK. No copy-pasted code.
|
||||
|
||||
[](https://github.com/honeybbq/teamspeak-go/actions/workflows/ci.yml)
|
||||
[](https://codecov.io/gh/honeybbq/teamspeak-go)
|
||||
[](https://goreportcard.com/report/github.com/honeybbq/teamspeak-go)
|
||||
|
||||
[](https://pkg.go.dev/github.com/honeybbq/teamspeak-go)
|
||||
[](go.mod)
|
||||
[](LICENSE)
|
||||
|
||||
</div>
|
||||
|
||||
## Features
|
||||
|
||||
- **Full protocol handshake** — ECDH key exchange, RSA puzzle, EAX-encrypted transport
|
||||
- **Command & notification system** — Send commands, receive server events
|
||||
- **Event-driven API** — Register handlers for text messages, client enter/leave, channel moves, kicks, etc.
|
||||
- **Voice data** — Send Opus voice packets (codec 4 & 5)
|
||||
- **File transfers** — Upload, download, and delete files on the server
|
||||
- **Address resolution** — SRV records, TSDNS, and direct address support
|
||||
- **Middleware** — Pluggable command and event middleware chains
|
||||
- **Built-in rate limiter** — Token-bucket throttling to prevent server-side flood kicks
|
||||
- **Identity management** — Generate, import/export, and upgrade security level of identities
|
||||
- **Zero CGO** — Pure Go, cross-compile anywhere
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
go get github.com/honeybbq/teamspeak-go
|
||||
```
|
||||
|
||||
Requires **Go 1.26** or later.
|
||||
|
||||
## Quick Start
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"time"
|
||||
|
||||
teamspeak "github.com/honeybbq/teamspeak-go"
|
||||
"github.com/honeybbq/teamspeak-go/crypto"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Generate a new identity (or load an existing one)
|
||||
identity, err := crypto.GenerateIdentity(8)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Create the client
|
||||
client := teamspeak.NewClient(
|
||||
identity,
|
||||
"localhost",
|
||||
"GoBot",
|
||||
teamspeak.WithServerPassword(os.Getenv("TEAMSPEAK_SERVER_PASSWORD")),
|
||||
teamspeak.WithDefaultChannel("Lobby"),
|
||||
teamspeak.WithDefaultChannelPassword(os.Getenv("TEAMSPEAK_DEFAULT_CHANNEL_PASSWORD")),
|
||||
)
|
||||
|
||||
// Register event handlers
|
||||
client.OnConnected(func() {
|
||||
fmt.Println("Connected to server!")
|
||||
})
|
||||
|
||||
client.OnTextMessage(func(msg teamspeak.TextMessage) {
|
||||
fmt.Printf("[%s]: %s\n", msg.InvokerName, msg.Message)
|
||||
})
|
||||
|
||||
client.OnDisconnected(func(err error) {
|
||||
fmt.Println("Disconnected:", err)
|
||||
})
|
||||
|
||||
// Connect
|
||||
if err := client.Connect(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Wait until connected
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
if err := client.WaitConnected(ctx); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Wait for interrupt signal
|
||||
sig := make(chan os.Signal, 1)
|
||||
signal.Notify(sig, os.Interrupt)
|
||||
<-sig
|
||||
|
||||
client.Disconnect()
|
||||
}
|
||||
```
|
||||
|
||||
## API Overview
|
||||
|
||||
### Client Lifecycle
|
||||
|
||||
| Method | Description |
|
||||
|---|---|
|
||||
| `NewClient(identity, addr, nickname, ...opts)` | Create a new client |
|
||||
| `Connect()` | Initiate connection to the server |
|
||||
| `WaitConnected(ctx)` | Block until the handshake completes |
|
||||
| `Disconnect()` | Gracefully disconnect |
|
||||
|
||||
### Events
|
||||
|
||||
| Method | Description |
|
||||
|---|---|
|
||||
| `OnConnected(func())` | Fires when fully connected |
|
||||
| `OnDisconnected(func(error))` | Fires on disconnect |
|
||||
| `OnTextMessage(func(TextMessage))` | Fires on text messages |
|
||||
| `OnClientEnter(func(ClientInfo))` | Fires when a client joins |
|
||||
| `OnClientLeave(func(ClientLeftViewEvent))` | Fires when a client leaves |
|
||||
| `OnClientMoved(func(ClientMovedEvent))` | Fires when a client moves channels |
|
||||
| `OnKicked(func(string))` | Fires when the bot is kicked |
|
||||
|
||||
### Commands
|
||||
|
||||
| Method | Description |
|
||||
|---|---|
|
||||
| `SendTextMessage(targetMode, targetID, msg)` | Send a text message |
|
||||
| `ClientMove(clid, channelID, password)` | Move a client to a channel |
|
||||
| `Poke(clid, message)` | Poke a client |
|
||||
| `SendVoice(data, codec)` | Send Opus voice data |
|
||||
| `ListChannels()` | List all channels |
|
||||
| `ListClients()` | List all connected clients |
|
||||
| `GetClientInfo(clid)` | Get detailed client information |
|
||||
| `ExecCommand(cmd, timeout)` | Execute a raw command |
|
||||
| `ExecCommandWithResponse(cmd, timeout)` | Execute a command and return response data |
|
||||
|
||||
### File Transfers
|
||||
|
||||
| Method | Description |
|
||||
|---|---|
|
||||
| `FileTransferInitUpload(...)` | Initialize a file upload |
|
||||
| `FileTransferInitDownload(...)` | Initialize a file download |
|
||||
| `FileTransferDeleteFile(...)` | Delete files on the server |
|
||||
| `UploadFileData(host, info, reader)` | Transfer file data to the server |
|
||||
| `DownloadFileData(host, info, writer)` | Receive file data from the server |
|
||||
|
||||
### Identity
|
||||
|
||||
```go
|
||||
// Generate a new identity with security level 8
|
||||
identity, err := crypto.GenerateIdentity(8)
|
||||
|
||||
// Export to string for persistent storage
|
||||
exported := identity.String()
|
||||
|
||||
// Import from a previously exported string
|
||||
identity, err = crypto.IdentityFromString(exported)
|
||||
|
||||
// Upgrade security level (CPU-intensive)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
err = identity.UpgradeToLevel(10, ctx)
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```go
|
||||
client := teamspeak.NewClient(identity, "ts.example.com", "Bot",
|
||||
teamspeak.WithLogger(slog.Default()),
|
||||
teamspeak.WithResolver(customResolver),
|
||||
teamspeak.WithCommandMiddleware(loggingMiddleware),
|
||||
teamspeak.WithEventMiddleware(filterMiddleware),
|
||||
teamspeak.WithServerPassword(os.Getenv("TEAMSPEAK_SERVER_PASSWORD")),
|
||||
teamspeak.WithDefaultChannel("Lobby"),
|
||||
teamspeak.WithDefaultChannelPassword(os.Getenv("TEAMSPEAK_DEFAULT_CHANNEL_PASSWORD")),
|
||||
)
|
||||
```
|
||||
|
||||
Connection auth options:
|
||||
|
||||
- `WithServerPassword(password)` accepts the plain-text server password and sends the TeamSpeak protocol hash during `clientinit`
|
||||
- `WithDefaultChannel(channel)` requests a default channel during `clientinit`
|
||||
- `WithDefaultChannelPassword(password)` accepts the plain-text channel password and sends the TeamSpeak protocol hash for the configured default channel
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
teamspeak-go/
|
||||
├── client.go # Client lifecycle, connection management
|
||||
├── api.go # High-level API (messages, channels, clients)
|
||||
├── commands.go # Command sending and response tracking
|
||||
├── events.go # Event handler registration and middleware
|
||||
├── notifications.go # Server notification parsing and dispatch
|
||||
├── handshake.go # Protocol handshake orchestration
|
||||
├── transfer.go # File transfer operations
|
||||
├── crypto/ # ECDH, EAX encryption, identity management
|
||||
├── handshake/ # Crypto handshake and license verification
|
||||
├── transport/ # UDP packet framing, ACK, compression
|
||||
├── commands/ # Command builder and parser
|
||||
└── discovery/ # SRV / TSDNS / direct address resolution
|
||||
```
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
Protocol knowledge was primarily informed by the [TSLib](https://github.com/Splamy/TS3AudioBot) implementation in [TS3AudioBot](https://github.com/Splamy/TS3AudioBot) by Splamy. Huge thanks to the TS3AudioBot project and its contributors.
|
||||
|
||||
## Disclaimer
|
||||
|
||||
TeamSpeak is a registered trademark of [TeamSpeak Systems GmbH](https://teamspeak.com/). This project is not affiliated with, endorsed by, or associated with TeamSpeak Systems GmbH in any way.
|
||||
|
||||
This library is a **clean-room implementation** developed from publicly available documentation, protocol analysis of network traffic, and independent research. No proprietary TeamSpeak SDK code, headers, or libraries were used in its creation.
|
||||
|
||||
## License
|
||||
|
||||
[MIT](LICENSE)
|
||||
Reference in New Issue
Block a user