mirror of
https://github.com/WiiLink24/wfc-server.git
synced 2026-09-07 16:15:30 -05:00
Add support for DWC match version 3
This commit is contained in:
@@ -73,6 +73,9 @@ type MatchCommandDataResvOK struct {
|
||||
ReceiverNewAID uint32
|
||||
ClientCount uint32
|
||||
ResvCheckValue uint32
|
||||
|
||||
// Only exists in version 3
|
||||
ProfileIDs []uint32
|
||||
}
|
||||
|
||||
type MatchCommandDataResvDeny struct {
|
||||
@@ -160,10 +163,14 @@ func GetMatchCommandString(command byte) string {
|
||||
return "UNKNOWN"
|
||||
}
|
||||
|
||||
func DecodeMatchCommand(command byte, buffer []byte) (MatchCommandData, bool) {
|
||||
func DecodeMatchCommand(command byte, buffer []byte, version int) (MatchCommandData, bool) {
|
||||
if version != 3 && version != 11 && version != 90 {
|
||||
return MatchCommandData{}, false
|
||||
}
|
||||
|
||||
switch command {
|
||||
case MatchReservation:
|
||||
if len(buffer) != 0x24 {
|
||||
if (version == 3 && len(buffer) != 0xC) || (version == 90 && len(buffer) != 0x24) {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -172,64 +179,102 @@ func DecodeMatchCommand(command byte, buffer []byte) (MatchCommandData, bool) {
|
||||
break
|
||||
}
|
||||
|
||||
isFriendValue := binary.LittleEndian.Uint32(buffer[0x18:0x1C])
|
||||
if isFriendValue > 1 {
|
||||
break
|
||||
}
|
||||
isFriend := isFriendValue != 0
|
||||
|
||||
publicPort := binary.LittleEndian.Uint32(buffer[0x08:0x0C])
|
||||
if publicPort > 0xffff {
|
||||
break
|
||||
}
|
||||
|
||||
localPort := binary.LittleEndian.Uint32(buffer[0x10:0x14])
|
||||
if localPort > 0xffff {
|
||||
break
|
||||
}
|
||||
if version == 3 {
|
||||
return MatchCommandData{Reservation: &MatchCommandDataReservation{
|
||||
MatchType: byte(matchType),
|
||||
PublicIP: binary.BigEndian.Uint32(buffer[0x04:0x08]),
|
||||
PublicPort: uint16(publicPort),
|
||||
}}, true
|
||||
} else if version == 90 {
|
||||
localPort := binary.LittleEndian.Uint32(buffer[0x10:0x14])
|
||||
if localPort > 0xffff {
|
||||
break
|
||||
}
|
||||
|
||||
return MatchCommandData{Reservation: &MatchCommandDataReservation{
|
||||
MatchType: byte(matchType),
|
||||
PublicIP: binary.BigEndian.Uint32(buffer[0x04:0x08]),
|
||||
PublicPort: uint16(publicPort),
|
||||
LocalIP: binary.BigEndian.Uint32(buffer[0x0C:0x10]),
|
||||
LocalPort: uint16(localPort),
|
||||
Unknown: binary.LittleEndian.Uint32(buffer[0x14:0x18]),
|
||||
IsFriend: isFriend,
|
||||
LocalPlayerCount: binary.LittleEndian.Uint32(buffer[0x1C:0x20]),
|
||||
ResvCheckValue: binary.LittleEndian.Uint32(buffer[0x20:0x24]),
|
||||
}}, true
|
||||
isFriendValue := binary.LittleEndian.Uint32(buffer[0x18:0x1C])
|
||||
if isFriendValue > 1 {
|
||||
break
|
||||
}
|
||||
isFriend := isFriendValue != 0
|
||||
|
||||
return MatchCommandData{Reservation: &MatchCommandDataReservation{
|
||||
MatchType: byte(matchType),
|
||||
PublicIP: binary.BigEndian.Uint32(buffer[0x04:0x08]),
|
||||
PublicPort: uint16(publicPort),
|
||||
LocalIP: binary.BigEndian.Uint32(buffer[0x0C:0x10]),
|
||||
LocalPort: uint16(localPort),
|
||||
Unknown: binary.LittleEndian.Uint32(buffer[0x14:0x18]),
|
||||
IsFriend: isFriend,
|
||||
LocalPlayerCount: binary.LittleEndian.Uint32(buffer[0x1C:0x20]),
|
||||
ResvCheckValue: binary.LittleEndian.Uint32(buffer[0x20:0x24]),
|
||||
}}, true
|
||||
}
|
||||
|
||||
case MatchResvOK:
|
||||
if len(buffer) != 0x34 {
|
||||
break
|
||||
}
|
||||
switch version {
|
||||
case 3:
|
||||
if len(buffer) < 0xC {
|
||||
break
|
||||
}
|
||||
|
||||
publicPort := binary.LittleEndian.Uint32(buffer[0x10:0x14])
|
||||
if publicPort > 0xffff {
|
||||
break
|
||||
}
|
||||
clientCount := binary.LittleEndian.Uint32(buffer[0x00:0x04])
|
||||
if clientCount > 29 || len(buffer) != int(0xC+clientCount*0x4) {
|
||||
break
|
||||
}
|
||||
|
||||
localPort := binary.LittleEndian.Uint32(buffer[0x18:0x1C])
|
||||
if localPort > 0xffff {
|
||||
break
|
||||
}
|
||||
var profileIDs []uint32
|
||||
for i := uint32(0); i < clientCount; i++ {
|
||||
profileIDs = append(profileIDs, binary.LittleEndian.Uint32(buffer[0x4+i*4:0x4+i*4+4]))
|
||||
}
|
||||
|
||||
return MatchCommandData{ResvOK: &MatchCommandDataResvOK{
|
||||
MaxPlayers: binary.LittleEndian.Uint32(buffer[0x00:0x04]),
|
||||
SenderAID: binary.LittleEndian.Uint32(buffer[0x04:0x08]),
|
||||
ProfileID: binary.LittleEndian.Uint32(buffer[0x08:0x0C]),
|
||||
PublicIP: binary.BigEndian.Uint32(buffer[0x0C:0x10]),
|
||||
PublicPort: uint16(publicPort),
|
||||
LocalIP: binary.BigEndian.Uint32(buffer[0x14:0x18]),
|
||||
LocalPort: uint16(localPort),
|
||||
Unknown: binary.LittleEndian.Uint32(buffer[0x1C:0x20]),
|
||||
LocalPlayerCount: binary.LittleEndian.Uint32(buffer[0x20:0x24]),
|
||||
GroupID: binary.LittleEndian.Uint32(buffer[0x24:0x28]),
|
||||
ReceiverNewAID: binary.LittleEndian.Uint32(buffer[0x28:0x2C]),
|
||||
ClientCount: binary.LittleEndian.Uint32(buffer[0x2C:0x30]),
|
||||
ResvCheckValue: binary.LittleEndian.Uint32(buffer[0x30:0x34]),
|
||||
}}, true
|
||||
publicPort := binary.LittleEndian.Uint32(buffer[0x08:0x0C])
|
||||
if publicPort > 0xffff {
|
||||
break
|
||||
}
|
||||
|
||||
return MatchCommandData{ResvOK: &MatchCommandDataResvOK{
|
||||
PublicIP: binary.BigEndian.Uint32(buffer[0x04:0x08]),
|
||||
PublicPort: uint16(publicPort),
|
||||
ClientCount: clientCount,
|
||||
ProfileIDs: profileIDs,
|
||||
}}, true
|
||||
|
||||
case 90:
|
||||
if len(buffer) != 0x34 {
|
||||
break
|
||||
}
|
||||
|
||||
publicPort := binary.LittleEndian.Uint32(buffer[0x10:0x14])
|
||||
if publicPort > 0xffff {
|
||||
break
|
||||
}
|
||||
|
||||
localPort := binary.LittleEndian.Uint32(buffer[0x18:0x1C])
|
||||
if localPort > 0xffff {
|
||||
break
|
||||
}
|
||||
|
||||
return MatchCommandData{ResvOK: &MatchCommandDataResvOK{
|
||||
MaxPlayers: binary.LittleEndian.Uint32(buffer[0x00:0x04]),
|
||||
SenderAID: binary.LittleEndian.Uint32(buffer[0x04:0x08]),
|
||||
ProfileID: binary.LittleEndian.Uint32(buffer[0x08:0x0C]),
|
||||
PublicIP: binary.BigEndian.Uint32(buffer[0x0C:0x10]),
|
||||
PublicPort: uint16(publicPort),
|
||||
LocalIP: binary.BigEndian.Uint32(buffer[0x14:0x18]),
|
||||
LocalPort: uint16(localPort),
|
||||
Unknown: binary.LittleEndian.Uint32(buffer[0x1C:0x20]),
|
||||
LocalPlayerCount: binary.LittleEndian.Uint32(buffer[0x20:0x24]),
|
||||
GroupID: binary.LittleEndian.Uint32(buffer[0x24:0x28]),
|
||||
ReceiverNewAID: binary.LittleEndian.Uint32(buffer[0x28:0x2C]),
|
||||
ClientCount: binary.LittleEndian.Uint32(buffer[0x2C:0x30]),
|
||||
ResvCheckValue: binary.LittleEndian.Uint32(buffer[0x30:0x34]),
|
||||
}}, true
|
||||
}
|
||||
|
||||
case MatchResvDeny:
|
||||
if len(buffer) != 0x04 {
|
||||
@@ -354,41 +399,64 @@ func DecodeMatchCommand(command byte, buffer []byte) (MatchCommandData, bool) {
|
||||
return MatchCommandData{}, false
|
||||
}
|
||||
|
||||
func EncodeMatchCommand(command byte, data MatchCommandData) ([]byte, bool) {
|
||||
func EncodeMatchCommand(command byte, data MatchCommandData, version int) ([]byte, bool) {
|
||||
if version != 3 && version != 11 && version != 90 {
|
||||
return []byte{}, false
|
||||
}
|
||||
|
||||
switch command {
|
||||
case MatchReservation:
|
||||
message := binary.LittleEndian.AppendUint32([]byte{}, uint32(data.Reservation.MatchType))
|
||||
message = binary.BigEndian.AppendUint32(message, data.Reservation.PublicIP)
|
||||
message = binary.LittleEndian.AppendUint32(message, uint32(data.Reservation.PublicPort))
|
||||
message = binary.BigEndian.AppendUint32(message, data.Reservation.LocalIP)
|
||||
message = binary.LittleEndian.AppendUint32(message, uint32(data.Reservation.LocalPort))
|
||||
message = binary.LittleEndian.AppendUint32(message, data.Reservation.Unknown)
|
||||
|
||||
isFriendInt := uint32(0)
|
||||
if data.Reservation.IsFriend {
|
||||
isFriendInt = 1
|
||||
if version != 3 {
|
||||
message = binary.BigEndian.AppendUint32(message, data.Reservation.LocalIP)
|
||||
message = binary.LittleEndian.AppendUint32(message, uint32(data.Reservation.LocalPort))
|
||||
message = binary.LittleEndian.AppendUint32(message, data.Reservation.Unknown)
|
||||
|
||||
isFriendInt := uint32(0)
|
||||
if data.Reservation.IsFriend {
|
||||
isFriendInt = 1
|
||||
}
|
||||
message = binary.LittleEndian.AppendUint32(message, isFriendInt)
|
||||
|
||||
message = binary.LittleEndian.AppendUint32(message, data.Reservation.LocalPlayerCount)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.Reservation.ResvCheckValue)
|
||||
}
|
||||
message = binary.LittleEndian.AppendUint32(message, isFriendInt)
|
||||
|
||||
message = binary.LittleEndian.AppendUint32(message, data.Reservation.LocalPlayerCount)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.Reservation.ResvCheckValue)
|
||||
return message, true
|
||||
|
||||
case MatchResvOK:
|
||||
message := binary.LittleEndian.AppendUint32([]byte{}, data.ResvOK.MaxPlayers)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.SenderAID)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.ProfileID)
|
||||
message = binary.BigEndian.AppendUint32(message, data.ResvOK.PublicIP)
|
||||
message = binary.LittleEndian.AppendUint32(message, uint32(data.ResvOK.PublicPort))
|
||||
message = binary.BigEndian.AppendUint32(message, data.ResvOK.LocalIP)
|
||||
message = binary.LittleEndian.AppendUint32(message, uint32(data.ResvOK.LocalPort))
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.Unknown)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.LocalPlayerCount)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.GroupID)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.ReceiverNewAID)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.ClientCount)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.ResvCheckValue)
|
||||
return message, true
|
||||
switch version {
|
||||
case 3:
|
||||
if int(data.ResvOK.ClientCount) != len(data.ResvOK.ProfileIDs) {
|
||||
return []byte{}, false
|
||||
}
|
||||
|
||||
message := binary.LittleEndian.AppendUint32([]byte{}, data.ResvOK.ClientCount)
|
||||
for _, pid := range data.ResvOK.ProfileIDs {
|
||||
message = binary.LittleEndian.AppendUint32(message, pid)
|
||||
}
|
||||
message = binary.BigEndian.AppendUint32(message, data.ResvOK.PublicIP)
|
||||
message = binary.LittleEndian.AppendUint32(message, uint32(data.ResvOK.PublicPort))
|
||||
return message, true
|
||||
|
||||
case 90:
|
||||
message := binary.LittleEndian.AppendUint32([]byte{}, data.ResvOK.MaxPlayers)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.SenderAID)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.ProfileID)
|
||||
message = binary.BigEndian.AppendUint32(message, data.ResvOK.PublicIP)
|
||||
message = binary.LittleEndian.AppendUint32(message, uint32(data.ResvOK.PublicPort))
|
||||
message = binary.BigEndian.AppendUint32(message, data.ResvOK.LocalIP)
|
||||
message = binary.LittleEndian.AppendUint32(message, uint32(data.ResvOK.LocalPort))
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.Unknown)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.LocalPlayerCount)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.GroupID)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.ReceiverNewAID)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.ClientCount)
|
||||
message = binary.LittleEndian.AppendUint32(message, data.ResvOK.ResvCheckValue)
|
||||
return message, true
|
||||
}
|
||||
|
||||
case MatchResvDeny:
|
||||
message := binary.LittleEndian.AppendUint32([]byte{}, data.ResvDeny.Reason)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package gpcm
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"github.com/logrusorgru/aurora/v3"
|
||||
"strconv"
|
||||
"strings"
|
||||
@@ -161,40 +162,60 @@ func (g *GameSpySession) bestieMessage(command common.GameSpyCommand) {
|
||||
}
|
||||
|
||||
// Parse message for security and room tracking purposes
|
||||
if !strings.HasPrefix(msg, "GPCM") {
|
||||
logging.Error(g.ModuleName, "Invalid message prefix")
|
||||
var version int
|
||||
var msgDataIndex int
|
||||
|
||||
if strings.HasPrefix(msg, "GPCM3vMAT") {
|
||||
version = 3
|
||||
msgDataIndex = 9
|
||||
} else if strings.HasPrefix(msg, "GPCM11vMAT") {
|
||||
// Only used for Brawl
|
||||
version = 11
|
||||
msgDataIndex = 10
|
||||
} else if strings.HasPrefix(msg, "GPCM90vMAT") {
|
||||
version = 90
|
||||
msgDataIndex = 10
|
||||
} else {
|
||||
logging.Error(g.ModuleName, "Invalid message prefix; message:", msg)
|
||||
g.replyError(ErrMessage)
|
||||
return
|
||||
}
|
||||
|
||||
currentIndex := strings.Index(msg, "vMAT") + 4
|
||||
isMessageHeaderValid := false
|
||||
switch currentIndex {
|
||||
case 9: // 1 - 9
|
||||
isMessageHeaderValid = msg[4] >= '1' && msg[4] <= '9' && len(msg) >= 11
|
||||
case 10: // 10 - 99
|
||||
isMessageHeaderValid = msg[4] >= '1' && msg[4] <= '9' && msg[5] >= '0' && msg[5] <= '9' && len(msg) >= 12
|
||||
}
|
||||
if !isMessageHeaderValid {
|
||||
logging.Error(g.ModuleName, "Invalid message header")
|
||||
g.replyError(ErrMessage)
|
||||
return
|
||||
cmd := msg[msgDataIndex]
|
||||
msgDataIndex++
|
||||
|
||||
var msgData []byte
|
||||
|
||||
switch version {
|
||||
case 3:
|
||||
for _, stringValue := range strings.Split(msg[msgDataIndex:], "/") {
|
||||
intValue, err := strconv.ParseUint(stringValue, 10, 32)
|
||||
if err != nil {
|
||||
logging.Error(g.ModuleName, "Invalid message value; message:", msg)
|
||||
g.replyError(ErrMessage)
|
||||
return
|
||||
}
|
||||
|
||||
msgData = binary.LittleEndian.AppendUint32(msgData, uint32(intValue))
|
||||
}
|
||||
break
|
||||
|
||||
// TODO: Version 11 (Super Smash Bros. Brawl)
|
||||
|
||||
case 90:
|
||||
msgData, err = common.Base64DwcEncoding.DecodeString(msg[msgDataIndex:])
|
||||
if err != nil {
|
||||
logging.Error(g.ModuleName, "Invalid message base64 data; message:", msg)
|
||||
g.replyError(ErrMessage)
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
cmd := msg[currentIndex]
|
||||
currentIndex++
|
||||
|
||||
msgData, err := common.Base64DwcEncoding.DecodeString(msg[currentIndex:])
|
||||
if err != nil {
|
||||
logging.Error(g.ModuleName, "Invalid message base64 data")
|
||||
g.replyError(ErrMessage)
|
||||
return
|
||||
}
|
||||
|
||||
msgMatchData, ok := common.DecodeMatchCommand(cmd, msgData)
|
||||
msgMatchData, ok := common.DecodeMatchCommand(cmd, msgData, version)
|
||||
common.LogMatchCommand(g.ModuleName, strconv.FormatInt(int64(toProfileId), 10), cmd, msgMatchData)
|
||||
if !ok {
|
||||
logging.Error(g.ModuleName, "Invalid match command data")
|
||||
logging.Error(g.ModuleName, "Invalid match command data; message:", msg)
|
||||
g.replyError(ErrMessage)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -54,6 +54,12 @@ func SendClientMessage(senderIP string, destSearchID uint64, message []byte) {
|
||||
return
|
||||
}
|
||||
|
||||
version := int(binary.LittleEndian.Uint32(message[0x04:0x08]))
|
||||
if version != 3 && version != 11 && version != 90 {
|
||||
logging.Error(moduleName, "Received invalid match version")
|
||||
return
|
||||
}
|
||||
|
||||
senderProfileID := binary.LittleEndian.Uint32(message[0x10:0x14])
|
||||
moduleName = "QR2/MSG:p" + strconv.FormatUint(uint64(senderProfileID), 10)
|
||||
|
||||
@@ -81,7 +87,7 @@ func SendClientMessage(senderIP string, destSearchID uint64, message []byte) {
|
||||
}
|
||||
|
||||
var ok bool
|
||||
matchData, ok = common.DecodeMatchCommand(message[8], message[0x14:])
|
||||
matchData, ok = common.DecodeMatchCommand(message[8], message[0x14:], version)
|
||||
if !ok {
|
||||
logging.Error(moduleName, "Received invalid match command:", aurora.Cyan(message[8]))
|
||||
return
|
||||
@@ -99,14 +105,16 @@ func SendClientMessage(senderIP string, destSearchID uint64, message []byte) {
|
||||
return
|
||||
}
|
||||
|
||||
if matchData.Reservation.PublicPort < 1024 {
|
||||
logging.Error(moduleName, "RESERVATION: Public port is reserved")
|
||||
if qr2Port != matchData.Reservation.PublicPort {
|
||||
logging.Error(moduleName, "RESERVATION: Public port mismatch in header and command")
|
||||
return
|
||||
}
|
||||
|
||||
if matchData.Reservation.LocalPort < 1024 {
|
||||
logging.Error(moduleName, "RESERVATION: Local port is reserved")
|
||||
return
|
||||
if version != 3 {
|
||||
if matchData.Reservation.LocalPort < 1024 {
|
||||
logging.Error(moduleName, "RESERVATION: Local port is reserved")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if useSearchID {
|
||||
@@ -123,19 +131,21 @@ func SendClientMessage(senderIP string, destSearchID uint64, message []byte) {
|
||||
return
|
||||
}
|
||||
|
||||
if matchData.ResvOK.PublicPort < 1024 {
|
||||
logging.Error(moduleName, "RESV_OK: Public port is reserved")
|
||||
if qr2Port != matchData.Reservation.PublicPort {
|
||||
logging.Error(moduleName, "RESERVATION: Public port mismatch in header and command")
|
||||
return
|
||||
}
|
||||
|
||||
if matchData.ResvOK.LocalPort < 1024 {
|
||||
logging.Error(moduleName, "RESV_OK: Local port is reserved")
|
||||
return
|
||||
}
|
||||
if version != 3 {
|
||||
if matchData.ResvOK.LocalPort < 1024 {
|
||||
logging.Error(moduleName, "RESV_OK: Local port is reserved")
|
||||
return
|
||||
}
|
||||
|
||||
if matchData.ResvOK.ProfileID != senderProfileID {
|
||||
logging.Error(moduleName, "RESV_OK: Profile ID mismatch in header")
|
||||
return
|
||||
if matchData.ResvOK.ProfileID != senderProfileID {
|
||||
logging.Error(moduleName, "RESV_OK: Profile ID mismatch in header")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if useSearchID {
|
||||
@@ -171,7 +181,7 @@ func SendClientMessage(senderIP string, destSearchID uint64, message []byte) {
|
||||
}
|
||||
|
||||
var matchMessage []byte
|
||||
matchMessage, ok = common.EncodeMatchCommand(message[8], matchData)
|
||||
matchMessage, ok = common.EncodeMatchCommand(message[8], matchData, version)
|
||||
if !ok {
|
||||
logging.Error(moduleName, "Failed to reencode match command:", aurora.Cyan(message[8]))
|
||||
return
|
||||
|
||||
@@ -15,53 +15,6 @@ import (
|
||||
// Example: dwc_mver = 90 and dwc_pid != 43 and maxplayers = 11 and numplayers < 11 and dwc_mtype = 0 and dwc_hoststate = 2 and dwc_suspend = 0 and (rk = 'vs' and ev >= 4250 and ev <= 5750 and p = 0)
|
||||
|
||||
func filterServers(servers []map[string]string, queryGame string, expression string, publicIP string) []map[string]string {
|
||||
if match := regexSelfLookup.FindStringSubmatch(expression); match != nil {
|
||||
dwcPid := match[1]
|
||||
|
||||
var filtered []map[string]string
|
||||
|
||||
// Search for where the profile ID matches
|
||||
for _, server := range servers {
|
||||
if server["gamename"] != queryGame {
|
||||
continue
|
||||
}
|
||||
|
||||
if server["dwc_pid"] == dwcPid {
|
||||
if server["publicip"] != publicIP {
|
||||
logging.Error(ModuleName, "Self lookup", aurora.Cyan(dwcPid), "from wrong IP")
|
||||
return []map[string]string{}
|
||||
}
|
||||
|
||||
logging.Info(ModuleName, "Self lookup from", aurora.Cyan(dwcPid), "ok")
|
||||
filtered = []map[string]string{server}
|
||||
break
|
||||
}
|
||||
|
||||
// Alternatively, if the server hasn't set its dwcPid field yet, we return servers matching the request's public IP.
|
||||
// If multiple servers exist with the same public IP then the client will use the one with the matching port.
|
||||
// This is a bit of a hack to speed up server creation.
|
||||
if _, ok := server["dwc_pid"]; !ok && server["publicip"] == publicIP {
|
||||
// Create a copy of the map with some values changed
|
||||
newServer := map[string]string{}
|
||||
for k, v := range server {
|
||||
newServer[k] = v
|
||||
}
|
||||
newServer["dwc_pid"] = dwcPid
|
||||
newServer["dwc_mtype"] = "0"
|
||||
newServer["dwc_mver"] = "0"
|
||||
filtered = append(filtered, newServer)
|
||||
}
|
||||
}
|
||||
|
||||
if len(filtered) == 0 {
|
||||
logging.Error(ModuleName, "Could not find server with dwcPid", aurora.Cyan(dwcPid))
|
||||
return []map[string]string{}
|
||||
}
|
||||
|
||||
logging.Info(ModuleName, "Self lookup for", aurora.Cyan(dwcPid), "matched", aurora.BrightCyan(len(filtered)), "servers via public IP")
|
||||
return filtered
|
||||
}
|
||||
|
||||
// Matchmaking search
|
||||
tree, err := filter.Parse(expression)
|
||||
if err != nil {
|
||||
@@ -76,7 +29,7 @@ func filterServers(servers []map[string]string, queryGame string, expression str
|
||||
continue
|
||||
}
|
||||
|
||||
if server["dwc_hoststate"] != "0" && server["dwc_hoststate"] != "2" {
|
||||
if server["dwc_mver"] == "90" && (server["dwc_hoststate"] != "0" && server["dwc_hoststate"] != "2") {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -105,12 +58,8 @@ func filterSelfLookup(servers []map[string]string, queryGame string, dwcPid stri
|
||||
}
|
||||
|
||||
if server["dwc_pid"] == dwcPid {
|
||||
if server["publicip"] != publicIP {
|
||||
logging.Error(ModuleName, "Self lookup", aurora.Cyan(dwcPid), "from wrong IP")
|
||||
return []map[string]string{}
|
||||
}
|
||||
|
||||
logging.Info(ModuleName, "Self lookup from", aurora.Cyan(dwcPid), "ok")
|
||||
// May not be a self lookup, some games search for friends like this
|
||||
logging.Info(ModuleName, "Lookup", aurora.Cyan(dwcPid), "ok")
|
||||
return []map[string]string{server}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user