mirror of
https://github.com/WiiLink24/wfc-server.git
synced 2026-08-20 15:44:36 -05:00
Matchmaking: Handle server list command
This commit is contained in:
@@ -79,9 +79,6 @@ func handleRequest(conn net.Conn) {
|
||||
fmt.Printf("Unable to set keepalive - %s", err)
|
||||
}
|
||||
|
||||
// log.Printf("%s: Connection established from %s. Sending challenge.", aurora.Green("[NOTICE]"), aurora.Yellow(conn.RemoteAddr()))
|
||||
// conn.Write([]byte(fmt.Sprintf(`\lc\1\challenge\%s\id\1\final\`, challenge)))
|
||||
|
||||
// Here we go into the listening loop
|
||||
for {
|
||||
buffer := make([]byte, 1024)
|
||||
@@ -95,11 +92,13 @@ func handleRequest(conn net.Conn) {
|
||||
|
||||
switch buffer[2] {
|
||||
case ServerList:
|
||||
logging.Notice(ModuleName, "Command:", aurora.Yellow("SERVER_LIST").String())
|
||||
|
||||
serverList(conn, buffer)
|
||||
break
|
||||
|
||||
default:
|
||||
logging.Notice(ModuleName, "Command:", aurora.Yellow(buffer[2]).String())
|
||||
logging.Notice(ModuleName, "Unknown command:", aurora.Yellow(buffer[2]).String())
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package matchmaking
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"github.com/logrusorgru/aurora/v3"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -9,29 +10,36 @@ import (
|
||||
"wwfc/logging"
|
||||
)
|
||||
|
||||
func popString(buffer []byte, index int) (string, int) {
|
||||
str := common.GetString(buffer[index:])
|
||||
return str, index + len(str) + 1
|
||||
}
|
||||
|
||||
func popBytes(buffer []byte, index int, size int) ([]byte, int) {
|
||||
return buffer[index : index+size], index + size
|
||||
}
|
||||
|
||||
func popUint32(buffer []byte, index int) (uint32, int) {
|
||||
return binary.BigEndian.Uint32(buffer[index:]), index + 4
|
||||
}
|
||||
|
||||
func serverList(conn net.Conn, buffer []byte) {
|
||||
logging.Notice(ModuleName, "Received server list command")
|
||||
const (
|
||||
FlagNoServerList = 1 << 1 // 0x02
|
||||
FlagAlternateSourceIP = 1 << 3 // 0x08
|
||||
FlagLimitResultCount = 1 << 7 // 0x80
|
||||
)
|
||||
|
||||
index := 9
|
||||
queryGame := common.GetString(buffer[index:])
|
||||
index += len(queryGame) + 1
|
||||
gameName := common.GetString(buffer[index:])
|
||||
index += len(gameName) + 1
|
||||
queryGame, index := popString(buffer, index)
|
||||
gameName, index := popString(buffer, index)
|
||||
challenge, index := popBytes(buffer, index, 8)
|
||||
filter, index := popString(buffer, index)
|
||||
fields, index := popString(buffer, index)
|
||||
flags, index := popUint32(buffer, index)
|
||||
|
||||
challenge := buffer[index : index+8]
|
||||
index += 8
|
||||
logging.Notice(ModuleName, "queryGame:", aurora.Cyan(queryGame).String(), "- gameName:", aurora.Cyan(gameName).String(), "- filter:", aurora.Cyan(filter).String(), "- fields:", aurora.Cyan(fields).String())
|
||||
|
||||
filter := common.GetString(buffer[index:])
|
||||
index += len(filter) + 1
|
||||
fields := common.GetString(buffer[index:])
|
||||
index += len(fields) + 1
|
||||
|
||||
options := binary.BigEndian.Uint32(buffer[index:])
|
||||
index += 4
|
||||
|
||||
logging.Notice(ModuleName, "Values", queryGame, gameName, string(challenge), string(options))
|
||||
|
||||
// TODO: Find a game if possible, but there is nobody to do that with yet!
|
||||
var output []byte
|
||||
for _, s := range strings.Split(strings.Split(conn.RemoteAddr().String(), ":")[0], ".") {
|
||||
val, err := strconv.Atoi(s)
|
||||
@@ -42,8 +50,49 @@ func serverList(conn net.Conn, buffer []byte) {
|
||||
output = append(output, byte(val))
|
||||
}
|
||||
|
||||
output = binary.BigEndian.AppendUint16(output, 6500)
|
||||
var fieldList []string
|
||||
for _, field := range strings.Split(fields, "\\") {
|
||||
if len(field) == 0 || field == " " {
|
||||
continue
|
||||
}
|
||||
|
||||
encrypted := common.EncryptTypeX([]byte("9r3Rmy"), challenge, output)
|
||||
conn.Write(encrypted)
|
||||
fieldList = append(fieldList, field)
|
||||
}
|
||||
|
||||
if flags&FlagNoServerList != 0 || len(fieldList) == 0 {
|
||||
// The client requests its own public IP and game port
|
||||
logging.Notice(ModuleName, "Reply without server list", aurora.Cyan(conn.RemoteAddr()).String())
|
||||
|
||||
// The default game port 6500
|
||||
output = binary.BigEndian.AppendUint16(output, 6500)
|
||||
|
||||
// Write the encrypted reply
|
||||
conn.Write(common.EncryptTypeX([]byte("9r3Rmy"), challenge, output))
|
||||
return
|
||||
}
|
||||
|
||||
logging.Notice(ModuleName, "Reply with server list", aurora.Cyan(conn.RemoteAddr()).String())
|
||||
|
||||
// The client's port
|
||||
port, err := strconv.Atoi(strings.Split(conn.RemoteAddr().String(), ":")[1])
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
output = binary.BigEndian.AppendUint16(output, uint16(port))
|
||||
|
||||
output = append(output, byte(len(fieldList)))
|
||||
for _, field := range fieldList {
|
||||
output = append(output, 0x00) // Value?
|
||||
output = append(output, []byte(field)...)
|
||||
output = append(output, 0x00) // String end
|
||||
}
|
||||
output = append(output, 0x00) // Zero length string to end the list
|
||||
|
||||
// TODO: Send server list here
|
||||
|
||||
// Server with no flags and -1 tells the client the message has ended
|
||||
output = append(output, []byte{0x00, 0xff, 0xff, 0xff, 0xff}...)
|
||||
|
||||
// Write the encrypted reply
|
||||
conn.Write(common.EncryptTypeX([]byte("9r3Rmy"), challenge, output))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user