mirror of
https://github.com/WiiLink24/wfc-server.git
synced 2026-03-21 17:44:58 -05:00
RACE: Create a foundation for the 'RACE' server
This commit is contained in:
parent
ed9aba05f5
commit
1665977524
110
common/mario_kart_wii.go
Normal file
110
common/mario_kart_wii.go
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
package common
|
||||
|
||||
type MarioKartWiiRegionID uint
|
||||
type MarioKartWiiCourseID uint
|
||||
|
||||
const MarioKartWiiGameSpyGameID uint = 1687
|
||||
|
||||
const (
|
||||
Worldwide = iota // 0
|
||||
Japan = iota // 1
|
||||
UnitedStates = iota // 2
|
||||
Europe = iota // 3
|
||||
Australia = iota // 4
|
||||
Taiwan = iota // 5
|
||||
Korea = iota // 6
|
||||
China = iota // 7
|
||||
)
|
||||
|
||||
const (
|
||||
MarioCircuit = iota // 0x00
|
||||
MooMooMeadows = iota // 0x01
|
||||
MushroomGorge = iota // 0x02
|
||||
GrumbleVolcano = iota // 0x03
|
||||
ToadsFactory = iota // 0x04
|
||||
CoconutMall = iota // 0x05
|
||||
DKSummit = iota // 0x06
|
||||
WarioGoldMine = iota // 0x07
|
||||
LuigiCircuit = iota // 0x08
|
||||
DaisyCircuit = iota // 0x09
|
||||
MoonviewHighway = iota // 0x0A
|
||||
MapleTreeway = iota // 0x0B
|
||||
BowsersCastle = iota // 0x0C
|
||||
RainbowRoad = iota // 0x0D
|
||||
DryDryRuins = iota // 0x0E
|
||||
KoopaCape = iota // 0x0F
|
||||
GCNPeachBeach = iota // 0x10
|
||||
GCNMarioCircuit = iota // 0x11
|
||||
GCNWaluigiStadium = iota // 0x12
|
||||
GCNDKMountain = iota // 0x13
|
||||
DSYoshiFalls = iota // 0x14
|
||||
DSDesertHills = iota // 0x15
|
||||
DSPeachGardens = iota // 0x16
|
||||
DSDelfinoSquare = iota // 0x17
|
||||
SNESMarioCircuit3 = iota // 0x18
|
||||
SNESGhostValley2 = iota // 0x19
|
||||
N64MarioRaceway = iota // 0x1A
|
||||
N64SherbetLand = iota // 0x1B
|
||||
N64BowsersCastle = iota // 0x1C
|
||||
N64DKsJungleParkway = iota // 0x1D
|
||||
GBABowserCastle3 = iota // 0x1E
|
||||
GBAShyGuyBeach = iota // 0x1F
|
||||
)
|
||||
|
||||
func (regionId MarioKartWiiRegionID) IsValid() bool {
|
||||
return regionId >= Worldwide && regionId <= China
|
||||
}
|
||||
|
||||
func (courseId MarioKartWiiCourseID) IsValid() bool {
|
||||
return courseId >= MarioCircuit && courseId <= GBAShyGuyBeach
|
||||
}
|
||||
|
||||
func (regionId MarioKartWiiRegionID) ToString() string {
|
||||
return [...]string{
|
||||
"Worldwide",
|
||||
"Japan",
|
||||
"United States",
|
||||
"Europe",
|
||||
"Australia",
|
||||
"Taiwan",
|
||||
"Korea",
|
||||
"China",
|
||||
}[regionId]
|
||||
}
|
||||
|
||||
func (courseId MarioKartWiiCourseID) ToString() string {
|
||||
return [...]string{
|
||||
"Mario Circuit",
|
||||
"Moo Moo Meadows",
|
||||
"Mushroom Gorge",
|
||||
"Grumble Volcano",
|
||||
"Toad's Factory",
|
||||
"Coconut Mall",
|
||||
"DK Summit",
|
||||
"Wario's Gold Mine",
|
||||
"Luigi Circuit",
|
||||
"Daisy Circuit",
|
||||
"Moonview Highway",
|
||||
"Maple Treeway",
|
||||
"Bowser's Castle",
|
||||
"Rainbow Road",
|
||||
"Dry Dry Ruins",
|
||||
"Koopa Cape",
|
||||
"GCN Peach Beach",
|
||||
"GCN Mario Circuit",
|
||||
"GCN Waluigi Stadium",
|
||||
"GCN DK Mountain",
|
||||
"DS Yoshi Falls",
|
||||
"DS Desert Hills",
|
||||
"DS Peach Gardens",
|
||||
"DS Delfino Square",
|
||||
"SNES Mario Circuit 3",
|
||||
"SNES Ghost Valley 2",
|
||||
"N64 Mario Raceway",
|
||||
"N64 Sherbet Land",
|
||||
"N64 Bowser's Castle",
|
||||
"N64 DK's Jungle Parkway",
|
||||
"GBA Bowser Castle 3",
|
||||
"GBA Shy Guy Beach",
|
||||
}[courseId]
|
||||
}
|
||||
5
main.go
5
main.go
|
|
@ -22,6 +22,7 @@ import (
|
|||
"wwfc/nas"
|
||||
"wwfc/natneg"
|
||||
"wwfc/qr2"
|
||||
"wwfc/race"
|
||||
"wwfc/sake"
|
||||
"wwfc/serverbrowser"
|
||||
|
||||
|
|
@ -99,7 +100,7 @@ func backendMain(noSignal, noReload bool) {
|
|||
}
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
actions := []func(bool){nas.StartServer, gpcm.StartServer, qr2.StartServer, gpsp.StartServer, serverbrowser.StartServer, sake.StartServer, natneg.StartServer, api.StartServer, gamestats.StartServer}
|
||||
actions := []func(bool){nas.StartServer, gpcm.StartServer, qr2.StartServer, gpsp.StartServer, serverbrowser.StartServer, race.StartServer, sake.StartServer, natneg.StartServer, api.StartServer, gamestats.StartServer}
|
||||
wg.Add(len(actions))
|
||||
for _, action := range actions {
|
||||
go func(ac func(bool)) {
|
||||
|
|
@ -215,7 +216,7 @@ func (r *RPCPacket) Shutdown(stateUuid string, _ *struct{}) error {
|
|||
}
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
actions := []func(){nas.Shutdown, gpcm.Shutdown, qr2.Shutdown, gpsp.Shutdown, serverbrowser.Shutdown, sake.Shutdown, natneg.Shutdown, api.Shutdown, gamestats.Shutdown}
|
||||
actions := []func(){nas.Shutdown, gpcm.Shutdown, qr2.Shutdown, gpsp.Shutdown, serverbrowser.Shutdown, race.Shutdown, sake.Shutdown, natneg.Shutdown, api.Shutdown, gamestats.Shutdown}
|
||||
wg.Add(len(actions))
|
||||
for _, action := range actions {
|
||||
go func(ac func()) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import (
|
|||
"wwfc/gamestats"
|
||||
"wwfc/logging"
|
||||
"wwfc/nhttp"
|
||||
"wwfc/race"
|
||||
"wwfc/sake"
|
||||
|
||||
"github.com/logrusorgru/aurora/v3"
|
||||
|
|
@ -71,6 +72,7 @@ func Shutdown() {
|
|||
}
|
||||
}
|
||||
|
||||
var regexRaceHost = regexp.MustCompile(`^([a-z\-]+\.)?race\.gs\.`)
|
||||
var regexSakeHost = regexp.MustCompile(`^([a-z\-]+\.)?sake\.gs\.`)
|
||||
var regexGamestatsHost = regexp.MustCompile(`^([a-z\-]+\.)?gamestats2?\.gs\.`)
|
||||
var regexStage1URL = regexp.MustCompile(`^/w([0-9])$`)
|
||||
|
|
@ -90,6 +92,13 @@ func handleRequest(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
// Check for *.race.gs.* or race.gs.*
|
||||
if regexRaceHost.MatchString(r.Host) {
|
||||
// Redirect to the race server
|
||||
race.HandleRequest(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
moduleName := "NAS:" + r.RemoteAddr
|
||||
|
||||
// Handle conntest server
|
||||
|
|
|
|||
25
race/main.go
Normal file
25
race/main.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package race
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"path"
|
||||
"wwfc/logging"
|
||||
|
||||
"github.com/logrusorgru/aurora/v3"
|
||||
)
|
||||
|
||||
func StartServer(reload bool) {
|
||||
}
|
||||
|
||||
func Shutdown() {
|
||||
}
|
||||
|
||||
func HandleRequest(responseWriter http.ResponseWriter, request *http.Request) {
|
||||
logging.Info("RACE", aurora.Yellow(request.Method), aurora.Cyan(request.URL), "via", aurora.Cyan(request.Host), "from", aurora.BrightCyan(request.RemoteAddr))
|
||||
|
||||
switch path.Base(request.URL.Path) {
|
||||
case "NintendoRacingService.asmx":
|
||||
moduleName := "RACE:RacingService:" + request.RemoteAddr
|
||||
handleNintendoRacingServiceRequest(moduleName, responseWriter, request)
|
||||
}
|
||||
}
|
||||
73
race/nintendo_racing_service.go
Normal file
73
race/nintendo_racing_service.go
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
package race
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
"io"
|
||||
"net/http"
|
||||
"wwfc/common"
|
||||
"wwfc/logging"
|
||||
|
||||
"github.com/logrusorgru/aurora/v3"
|
||||
)
|
||||
|
||||
type rankingsRequestEnvelope struct {
|
||||
XMLName xml.Name
|
||||
Body rankingsRequestBody
|
||||
}
|
||||
|
||||
type rankingsRequestBody struct {
|
||||
XMLName xml.Name
|
||||
Data rankingsRequestData `xml:",any"`
|
||||
}
|
||||
|
||||
type rankingsRequestData struct {
|
||||
XMLName xml.Name
|
||||
GameId uint `xml:"gameid"`
|
||||
RegionId common.MarioKartWiiRegionID `xml:"regionid"`
|
||||
CourseId common.MarioKartWiiCourseID `xml:"courseid"`
|
||||
}
|
||||
|
||||
func handleNintendoRacingServiceRequest(moduleName string, responseWriter http.ResponseWriter, request *http.Request) {
|
||||
soapActionHeader := request.Header.Get("SOAPAction")
|
||||
if soapActionHeader == "" {
|
||||
logging.Error(moduleName, "No SOAPAction header")
|
||||
return
|
||||
}
|
||||
|
||||
requestBody, err := io.ReadAll(request.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
soapMessage := rankingsRequestEnvelope{}
|
||||
err = xml.Unmarshal(requestBody, &soapMessage)
|
||||
if err != nil {
|
||||
logging.Error(moduleName, "Malformed XML")
|
||||
return
|
||||
}
|
||||
soapMessageData := soapMessage.Body.Data
|
||||
|
||||
gameId := soapMessageData.GameId
|
||||
if gameId != common.MarioKartWiiGameSpyGameID {
|
||||
logging.Error(moduleName, "Wrong GameSpy game id")
|
||||
return
|
||||
}
|
||||
|
||||
soapAction := soapMessageData.XMLName.Local
|
||||
switch soapAction {
|
||||
case "GetTopTenRankings":
|
||||
regionId := soapMessageData.RegionId
|
||||
courseId := soapMessageData.CourseId
|
||||
|
||||
if !regionId.IsValid() {
|
||||
logging.Error(moduleName, "Invalid region id")
|
||||
return
|
||||
}
|
||||
if !courseId.IsValid() {
|
||||
logging.Error(moduleName, "Invalid course id")
|
||||
return
|
||||
}
|
||||
|
||||
logging.Info(moduleName, "Received a request for the Top 10 of", aurora.BrightCyan(courseId.ToString()))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user