A => gorcon.go +60 -0
@@ 0,0 1,60 @@
+package gorcon
+
+import "encoding/binary"
+import "fmt"
+import "io"
+import "log"
+import "net"
+
+var _ = fmt.Println
+var _ = log.Println
+
+const (
+ SERVERDATA_AUTH = CmdType(3)
+ SERVERDATA_AUTH_RESPONSE = CmdType(2)
+ SERVERDATA_EXECCOMMAND = CmdType(2)
+ SERVERDATA_RESPONSE_VALUE = CmdType(0)
+)
+
+type CmdType int32
+
+type packetHeader struct{
+ Size int32
+ Id int32
+ Type int32
+}
+
+func WriteCommand(w io.Writer, cmdtype CmdType, body string) error {
+ bodybytes := []byte(body)
+ // For the size, the header is 3 fields each 4 bytes in size, the length of the body, and then our two zero bytes at the end
+ size := 3 * 4 + len(bodybytes) + 2
+ p := &packetHeader{
+ Size: int32(size),
+ Id: int32(0),
+ Type: int32(cmdtype),
+ }
+ if err := binary.Write(w, binary.LittleEndian, p); err != nil {
+ return err
+ }
+ if err := binary.Write(w, binary.LittleEndian, bodybytes); err != nil {
+ return err
+ }
+ // 16 bits here since []byte doesn't add a terminal character
+ return binary.Write(w, binary.LittleEndian, int16(0))
+}
+
+func main() {
+ log.Println("Hello, world!")
+
+ conn, err := net.Dial("tcp", "74.91.117.120:27015")
+ if err != nil {
+ log.Panicln(err)
+ }
+
+ log.Println(conn)
+
+ err = WriteCommand(conn, SERVERDATA_AUTH, "rcon_password hunter2")
+ if err != nil {
+ log.Panicln(err)
+ }
+}
A => gorcon_test.go +37 -0
@@ 0,0 1,37 @@
+package gorcon
+
+import "log"
+import "testing"
+import "bytes"
+import "fmt"
+import "io/ioutil"
+
+var _ = fmt.Println
+var _ = log.Println
+
+func TestRequestSimple(t *testing.T) {
+ var buf bytes.Buffer
+ if err := WriteCommand(&buf, SERVERDATA_AUTH, ` !"#'&%$`); err != nil {
+ t.Fatal(err)
+ }
+ data, err := ioutil.ReadAll(&buf)
+ if err != nil {
+ t.Fatal(err)
+ }
+ expected := []byte{
+ 22, 0, 0, 0, // Length
+ 0, 0, 0, 0, // Id is always zero for now
+ 3, 0, 0, 0, // Auth command
+ 32, 33, 34, 35, 39, 38, 37, 36, 0,
+ 0}
+ log.Println("Expected: ", expected)
+ log.Println("Got: ", data)
+ if len(data) != len(expected) {
+ t.FailNow()
+ }
+ for idx := range data {
+ if data[idx] != expected[idx] {
+ t.FailNow()
+ }
+ }
+}