@@ 24,10 24,15 @@ type packetHeader struct{
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
+func WriteCommandString(w io.Writer, cmdtype CmdType, body string) error {
+ return WriteCommand(w, cmdtype, []byte(body))
+}
+
+func WriteCommand(w io.Writer, cmdtype CmdType, body []byte) error {
+ // For the size, the header is 3 fields each 4 bytes in size (but we
+ // ignore the Size field), the length of the body, and then our two zero
+ // bytes at the end
+ size := 2 * 4 + len(body) + 2
p := &packetHeader{
Size: int32(size),
Id: int32(0),
@@ 36,25 41,9 @@ func WriteCommand(w io.Writer, cmdtype C
if err := binary.Write(w, binary.LittleEndian, p); err != nil {
return err
}
- if err := binary.Write(w, binary.LittleEndian, bodybytes); err != nil {
+ if _, err := w.Write(body); 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)
- }
-}
@@ 9,29 9,59 @@ import "io/ioutil"
var _ = fmt.Println
var _ = log.Println
-func TestRequestSimple(t *testing.T) {
+func bytesAreEqual(a, b []byte) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for idx := range a {
+ if a[idx] != b[idx] {
+ return false
+ }
+ }
+ return true
+}
+
+func DumpCommandString(cmdtype CmdType, body string) ([]byte, error) {
var buf bytes.Buffer
- if err := WriteCommand(&buf, SERVERDATA_AUTH, ` !"#'&%$`); err != nil {
- t.Fatal(err)
+ if err := WriteCommandString(&buf, cmdtype, body); err != nil {
+ return nil, err
}
- data, err := ioutil.ReadAll(&buf)
+ return ioutil.ReadAll(&buf)
+}
+
+func TestRequestSimple(t *testing.T) {
+ data, err := DumpCommandString(SERVERDATA_AUTH, ` !"#'&%$`)
if err != nil {
t.Fatal(err)
}
expected := []byte{
- 22, 0, 0, 0, // Length
+ 18, 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) {
+ if bytesAreEqual(expected, data) == false {
+ log.Println("Expected: ", expected)
+ log.Println("Got: ", data)
t.FailNow()
}
- for idx := range data {
- if data[idx] != expected[idx] {
- t.FailNow()
- }
+}
+
+func TestRequestAlsoSimple(t *testing.T) {
+ // Borrowed from https://developer.valvesoftware.com/wiki/Source_RCON_Protocol
+ data, err := DumpCommandString(SERVERDATA_AUTH, `passwrd`)
+ if err != nil {
+ t.Fatal(err)
+ }
+ expected := []byte{
+ 0x11, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00,
+ 0x03, 0x00, 0x00, 0x00,
+ 0x70, 0x61, 0x73, 0x73, 0x77, 0x72, 0x64, 0x00,
+ 0x00}
+ if bytesAreEqual(expected, data) == false {
+ log.Println("Expected: ", expected)
+ log.Println("Got: ", data)
+ t.FailNow()
}
}