mirror of
https://github.com/WiiLink24/wfc-server.git
synced 2026-03-21 17:44:58 -05:00
SAKE: Support file download requests for champion ghosts from Mario Kart Wii
Helps address issue #43.
This commit is contained in:
parent
46f269d470
commit
a55800eb2f
|
|
@ -21,6 +21,18 @@ const (
|
|||
"AND courseid = $2 " +
|
||||
"ORDER BY score ASC " +
|
||||
"LIMIT 10"
|
||||
getStoredGhostDataQuery = "" +
|
||||
"SELECT pid, id " +
|
||||
"FROM mario_kart_wii_sake " +
|
||||
"WHERE ($1 = 0 OR regionid = $1) " +
|
||||
"AND courseid = $2 " +
|
||||
"ORDER BY score ASC " +
|
||||
"LIMIT 1"
|
||||
getFileQuery = "" +
|
||||
"SELECT ghost " +
|
||||
"FROM mario_kart_wii_sake " +
|
||||
"WHERE id = $1 " +
|
||||
"LIMIT 1"
|
||||
getGhostFileQuery = "" +
|
||||
"SELECT ghost " +
|
||||
"FROM mario_kart_wii_sake " +
|
||||
|
|
@ -54,21 +66,43 @@ func GetMarioKartWiiTopTenRankings(pool *pgxpool.Pool, ctx context.Context, regi
|
|||
|
||||
topTenRankings = append(topTenRankings, topTenRanking)
|
||||
}
|
||||
err = rows.Err()
|
||||
if err != nil {
|
||||
if err = rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return topTenRankings, nil
|
||||
}
|
||||
|
||||
func GetMarioKartWiiStoredGhostData(pool *pgxpool.Pool, ctx context.Context, regionId common.MarioKartWiiLeaderboardRegionId,
|
||||
courseId common.MarioKartWiiCourseId) (int, int, error) {
|
||||
row := pool.QueryRow(ctx, getStoredGhostDataQuery, regionId, courseId)
|
||||
|
||||
var pid int
|
||||
var fileId int
|
||||
if err := row.Scan(&pid, &fileId); err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
return pid, fileId, nil
|
||||
}
|
||||
|
||||
func GetMarioKartWiiFile(pool *pgxpool.Pool, ctx context.Context, fileId int) ([]byte, error) {
|
||||
row := pool.QueryRow(ctx, getFileQuery, fileId)
|
||||
|
||||
var file []byte
|
||||
if err := row.Scan(&file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return file, nil
|
||||
}
|
||||
|
||||
func GetMarioKartWiiGhostFile(pool *pgxpool.Pool, ctx context.Context, courseId common.MarioKartWiiCourseId,
|
||||
time int, pid int) ([]byte, error) {
|
||||
row := pool.QueryRow(ctx, getGhostFileQuery, courseId, time, pid)
|
||||
|
||||
var ghost []byte
|
||||
err := row.Scan(&ghost)
|
||||
if err != nil {
|
||||
if err := row.Scan(&ghost); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,23 +9,24 @@ import (
|
|||
func UpdateTables(pool *pgxpool.Pool, ctx context.Context) {
|
||||
pool.Exec(ctx, `
|
||||
|
||||
ALTER TABLE ONLY public.users
|
||||
ADD IF NOT EXISTS last_ip_address character varying DEFAULT ''::character varying,
|
||||
ADD IF NOT EXISTS last_ingamesn character varying DEFAULT ''::character varying,
|
||||
ADD IF NOT EXISTS has_ban boolean DEFAULT false,
|
||||
ADD IF NOT EXISTS ban_issued timestamp without time zone,
|
||||
ADD IF NOT EXISTS ban_expires timestamp without time zone,
|
||||
ADD IF NOT EXISTS ban_reason character varying,
|
||||
ADD IF NOT EXISTS ban_reason_hidden character varying,
|
||||
ADD IF NOT EXISTS ban_moderator character varying,
|
||||
ADD IF NOT EXISTS ban_tos boolean,
|
||||
ADD IF NOT EXISTS open_host boolean DEFAULT false;
|
||||
ALTER TABLE ONLY public.users
|
||||
ADD IF NOT EXISTS last_ip_address character varying DEFAULT ''::character varying,
|
||||
ADD IF NOT EXISTS last_ingamesn character varying DEFAULT ''::character varying,
|
||||
ADD IF NOT EXISTS has_ban boolean DEFAULT false,
|
||||
ADD IF NOT EXISTS ban_issued timestamp without time zone,
|
||||
ADD IF NOT EXISTS ban_expires timestamp without time zone,
|
||||
ADD IF NOT EXISTS ban_reason character varying,
|
||||
ADD IF NOT EXISTS ban_reason_hidden character varying,
|
||||
ADD IF NOT EXISTS ban_moderator character varying,
|
||||
ADD IF NOT EXISTS ban_tos boolean,
|
||||
ADD IF NOT EXISTS open_host boolean DEFAULT false;
|
||||
|
||||
`)
|
||||
|
||||
pool.Exec(ctx, `
|
||||
|
||||
ALTER TABLE ONLY public.mario_kart_wii_sake
|
||||
ADD IF NOT EXISTS id serial PRIMARY KEY,
|
||||
ADD IF NOT EXISTS upload_time timestamp without time zone;
|
||||
|
||||
`)
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ const (
|
|||
xmlNamespace = "http://gamespy.net/RaceService/"
|
||||
)
|
||||
|
||||
var MarioKartWiiGameID = common.GetGameIDOrPanic("mariokartwii") // 1687
|
||||
var marioKartWiiGameID = common.GetGameIDOrPanic("mariokartwii") // 1687
|
||||
|
||||
func handleNintendoRacingServiceRequest(moduleName string, responseWriter http.ResponseWriter, request *http.Request) {
|
||||
soapActionHeader := request.Header.Get("SOAPAction")
|
||||
|
|
@ -123,7 +123,7 @@ func handleGetTopTenRankingsRequest(moduleName string, responseWriter http.Respo
|
|||
requestData := requestXML.Body.Data
|
||||
|
||||
gameId := requestData.GameId
|
||||
if gameId != MarioKartWiiGameID {
|
||||
if gameId != marioKartWiiGameID {
|
||||
logging.Error(moduleName, "Wrong GameSpy game ID:", aurora.Cyan(gameId))
|
||||
writeErrorResponse(raceServiceResultInvalidParameters, responseWriter)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -37,6 +37,36 @@ func handleMarioKartWiiFileDownloadRequest(moduleName string, responseWriter htt
|
|||
handleMarioKartWiiGhostDownloadRequest(moduleName, responseWriter, request)
|
||||
return
|
||||
}
|
||||
|
||||
query := request.URL.Query()
|
||||
|
||||
fileIdString := query.Get("fileid")
|
||||
pidString := query.Get("pid")
|
||||
|
||||
fileId, err := strconv.Atoi(fileIdString)
|
||||
if err != nil || fileId <= 0 {
|
||||
logging.Error(moduleName, "Invalid file ID:", aurora.Cyan(fileIdString))
|
||||
responseWriter.Header().Set(SakeFileResultHeader, strconv.Itoa(SakeFileResultMissingParameter))
|
||||
return
|
||||
}
|
||||
|
||||
pid, err := strconv.Atoi(pidString)
|
||||
if err != nil || pid <= 0 {
|
||||
logging.Error(moduleName, "Invalid profile ID:", aurora.Cyan(pidString))
|
||||
responseWriter.Header().Set(SakeFileResultHeader, strconv.Itoa(SakeFileResultMissingParameter))
|
||||
return
|
||||
}
|
||||
|
||||
file, err := database.GetMarioKartWiiFile(pool, ctx, fileId)
|
||||
if err != nil {
|
||||
logging.Error(moduleName, "Failed to get the file from the database:", err)
|
||||
responseWriter.Header().Set(SakeFileResultHeader, strconv.Itoa(SakeFileResultServerError))
|
||||
return
|
||||
}
|
||||
|
||||
responseWriter.Header().Set(SakeFileResultHeader, strconv.Itoa(SakeFileResultSuccess))
|
||||
responseWriter.Header().Set("Content-Length", strconv.Itoa(len(file)))
|
||||
responseWriter.Write(file)
|
||||
}
|
||||
|
||||
func handleMarioKartWiiGhostDownloadRequest(moduleName string, responseWriter http.ResponseWriter, request *http.Request) {
|
||||
|
|
|
|||
|
|
@ -382,6 +382,71 @@ func searchForRecords(moduleName string, gameInfo common.GameInfo, request Stora
|
|||
"info": binaryDataValueBase64(database.GetMKWFriendInfo(pool, ctx, uint32(ownerId))),
|
||||
},
|
||||
}
|
||||
|
||||
case "mariokartwii/StoredGhostData":
|
||||
if request.Sort != "time" {
|
||||
logging.Error(moduleName, "Invalid sort string:", aurora.Cyan(request.Sort))
|
||||
return &errorResponse
|
||||
}
|
||||
|
||||
if request.Offset != 0 {
|
||||
logging.Error(moduleName, "Invalid offset value:", aurora.Cyan(request.Offset))
|
||||
return &errorResponse
|
||||
}
|
||||
|
||||
if request.Max != 1 {
|
||||
logging.Error(moduleName, "Invalid number of records to return:", aurora.Cyan(request.Max))
|
||||
return &errorResponse
|
||||
}
|
||||
|
||||
if request.Surrounding != 0 {
|
||||
logging.Error(moduleName, "Invalid number of surrounding records to return:", aurora.Cyan(request.Surrounding))
|
||||
return &errorResponse
|
||||
}
|
||||
|
||||
if request.OwnerIDs != "" {
|
||||
logging.Error(moduleName, "Invalid owner id array:", aurora.Cyan(request.OwnerIDs))
|
||||
return &errorResponse
|
||||
}
|
||||
|
||||
if request.CacheFlag != 0 {
|
||||
logging.Error(moduleName, "Invalid cache value:", aurora.Cyan(request.CacheFlag))
|
||||
return &errorResponse
|
||||
}
|
||||
|
||||
match := regexp.MustCompile(`^course = ([1-9]\d?|0) and gameid = 1687(?: and region = ([1-7]))?$`).FindStringSubmatch(request.Filter)
|
||||
if match == nil {
|
||||
logging.Error(moduleName, "Invalid filter string:", aurora.Cyan(request.Filter))
|
||||
return &errorResponse
|
||||
}
|
||||
|
||||
courseIdInt, _ := strconv.Atoi(match[1])
|
||||
courseId := common.MarioKartWiiCourseId(courseIdInt)
|
||||
if !courseId.IsValid() {
|
||||
logging.Error(moduleName, "Invalid course ID:", aurora.Cyan(courseIdInt))
|
||||
return &errorResponse
|
||||
}
|
||||
|
||||
var regionId common.MarioKartWiiLeaderboardRegionId
|
||||
if regionIdExists := match[2] != ""; regionIdExists {
|
||||
regionIdInt, _ := strconv.Atoi(match[2])
|
||||
regionId = common.MarioKartWiiLeaderboardRegionId(regionIdInt)
|
||||
} else {
|
||||
regionId = common.Worldwide
|
||||
}
|
||||
|
||||
pid, fileId, err := database.GetMarioKartWiiStoredGhostData(pool, ctx, regionId, courseId)
|
||||
if err != nil {
|
||||
logging.Error(moduleName, "Failed to get the stored ghost data from the database:", err)
|
||||
return &errorResponse
|
||||
}
|
||||
|
||||
values = []map[string]StorageValue{
|
||||
{
|
||||
"profile": intValue(int32(pid)),
|
||||
"fileid": intValue(int32(fileId)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Sort the values now
|
||||
|
|
|
|||
|
|
@ -68,6 +68,11 @@ CREATE TABLE IF NOT EXISTS public.mario_kart_wii_sake (
|
|||
);
|
||||
|
||||
|
||||
ALTER TABLE ONLY public.mario_kart_wii_sake
|
||||
ADD IF NOT EXISTS id serial PRIMARY KEY,
|
||||
ADD IF NOT EXISTS upload_time timestamp without time zone;
|
||||
|
||||
|
||||
ALTER TABLE public.mario_kart_wii_sake OWNER TO wiilink;
|
||||
|
||||
--
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user