icecon/internal/rcon/client.go

111 lines
1.9 KiB
Go

package rcon
import (
"bytes"
"errors"
"fmt"
"net"
"strings"
quake "github.com/icedream/go-q3net"
)
type Client struct {
address *net.UDPAddr
addressStr string
password string
socket *net.UDPConn
socketBuffer []byte
}
func NewRconClient() *Client {
socketBuffer := make([]byte, 64*1024)
return &Client{
socketBuffer: socketBuffer,
}
}
func (c *Client) SetSocketAddr(addr string) (err error) {
newAddr, err := net.ResolveUDPAddr("udp", addr)
if err != nil {
return
}
c.address, c.addressStr = newAddr, addr
return
}
func (c *Client) SetPassword(pw string) {
c.password = pw
}
func (c *Client) Address() *net.UDPAddr {
return c.address
}
func (c *Client) AddressString() string {
return c.addressStr
}
func (c *Client) Password() string {
return c.password
}
func (c *Client) InitSocket() (err error) {
c.socket, err = net.ListenUDP("udp", nil)
if err != nil {
return
}
return
}
func (c *Client) udpReceiveAndUnmarshal() (msg *quake.Message, err error) {
length, _, err := c.socket.ReadFromUDP(c.socketBuffer)
if err != nil {
return
}
msg, err = quake.UnmarshalMessage(c.socketBuffer[0:length])
if err != nil {
return
}
return
}
func (c *Client) Receive() (msg *quake.Message, err error) {
msg, err = c.udpReceiveAndUnmarshal()
if err != nil {
return
}
if !strings.EqualFold(msg.Name, "print") {
err = errors.New("rcon: Unexpected response from server: " + msg.Name)
}
return
}
func (c *Client) Send(input string) (err error) {
buf := new(bytes.Buffer)
msg := &quake.Message{
Header: quake.OOBHeader,
Name: "rcon",
Data: []byte(fmt.Sprintf("%s %s", c.password, input)),
}
if err = msg.Marshal(buf); err != nil {
return
}
if _, err = c.socket.WriteToUDP(buf.Bytes(), c.address); err != nil {
return
}
return
}
func (c *Client) Release() {
if c.socket != nil {
c.socket.Close()
c.socket = nil
}
}