Skip to content

Commit e96cf11

Browse files
committed
Run Auto Mod when submitting for rank
1 parent cd6a2cf commit e96cf11

File tree

3 files changed

+142
-0
lines changed

3 files changed

+142
-0
lines changed

files/zip.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package files
2+
3+
import (
4+
"archive/zip"
5+
"fmt"
6+
"io"
7+
"os"
8+
"path/filepath"
9+
"strings"
10+
)
11+
12+
// UnzipArchive Unzips an archive to an output path
13+
func UnzipArchive(zipPath string, outputPath string) error {
14+
archive, err := zip.OpenReader(zipPath)
15+
16+
if err != nil {
17+
return err
18+
}
19+
20+
defer archive.Close()
21+
22+
for _, f := range archive.File {
23+
filePath := filepath.Join(outputPath, f.Name)
24+
25+
if !strings.HasPrefix(filePath, filepath.Clean(outputPath)+string(os.PathSeparator)) {
26+
return fmt.Errorf("invalid file path for: %v", filePath)
27+
}
28+
29+
if f.FileInfo().IsDir() {
30+
if err := os.MkdirAll(filePath, os.ModePerm); err != nil {
31+
return err
32+
}
33+
continue
34+
}
35+
36+
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
37+
return err
38+
}
39+
40+
dstFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
41+
42+
if err != nil {
43+
return err
44+
}
45+
46+
fileInArchive, err := f.Open()
47+
48+
if err != nil {
49+
return err
50+
}
51+
52+
if _, err := io.Copy(dstFile, fileInArchive); err != nil {
53+
return err
54+
}
55+
56+
dstFile.Close()
57+
fileInArchive.Close()
58+
}
59+
60+
return nil
61+
}

handlers/ranking.go

+42
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@ import (
55
"github.com/Quaver/api2/config"
66
"github.com/Quaver/api2/db"
77
"github.com/Quaver/api2/enums"
8+
"github.com/Quaver/api2/files"
9+
"github.com/Quaver/api2/tools"
810
"github.com/Quaver/api2/webhooks"
911
"github.com/gin-gonic/gin"
1012
"gorm.io/gorm"
1113
"net/http"
14+
"os"
15+
"path/filepath"
1216
"strconv"
1317
"time"
1418
)
@@ -120,13 +124,51 @@ func SubmitMapsetToRankingQueue(c *gin.Context) *APIError {
120124
return APIErrorForbidden("You cannot submit any more mapsets to the queue at this time.")
121125
}
122126

127+
automodOk, err := downloadAndRunAutomod(mapset)
128+
129+
if err != nil {
130+
return APIErrorServerError("Error running automod", err)
131+
}
132+
133+
if !automodOk {
134+
return APIErrorBadRequest("Your mapset has Auto Mod issues. Please fix them, then try again.")
135+
}
136+
123137
if existingQueueMapset == nil {
124138
return addMapsetToRankingQueue(c, mapset)
125139
} else {
126140
return resubmitMapsetToRankingQueue(c, existingQueueMapset)
127141
}
128142
}
129143

144+
// Runs the automod and returns an error if the mapset is good
145+
func downloadAndRunAutomod(mapset *db.Mapset) (bool, error) {
146+
archivePath, err := files.CacheMapset(mapset)
147+
148+
if err != nil {
149+
return false, err
150+
}
151+
152+
output, _ := filepath.Abs(fmt.Sprintf("%v/%v", files.GetTempDirectory(), time.Now().UnixMilli()))
153+
154+
if err := files.UnzipArchive(archivePath, output); err != nil {
155+
return false, err
156+
}
157+
158+
automod, err := tools.RunAutoMod(output)
159+
160+
if err != nil {
161+
return false, err
162+
}
163+
164+
if automod.HasIssues {
165+
return false, nil
166+
}
167+
168+
_ = os.Remove(output)
169+
return true, nil
170+
}
171+
130172
// RemoveFromRankingQueue Allows a user to remove their mapset from the ranking queue (self deny)
131173
// Endpoint: POST /v2/ranking/queue/:id/remove
132174
func RemoveFromRankingQueue(c *gin.Context) *APIError {

tools/automod.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package tools
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"fmt"
7+
"github.com/Quaver/api2/config"
8+
"os/exec"
9+
)
10+
11+
type AutoMod struct {
12+
HasIssues bool `json:"HasIssues"`
13+
}
14+
15+
func RunAutoMod(directory string) (*AutoMod, error) {
16+
cmd := exec.Command(
17+
config.Instance.QuaverToolsPath,
18+
"-automod",
19+
directory)
20+
21+
var out bytes.Buffer
22+
var stderr bytes.Buffer
23+
cmd.Stdout = &out
24+
cmd.Stderr = &stderr
25+
26+
err := cmd.Run()
27+
28+
if err != nil {
29+
return nil, fmt.Errorf("%v\n\n```%v```", err, stderr.String())
30+
}
31+
32+
var automod AutoMod
33+
34+
if err := json.Unmarshal(out.Bytes(), &automod); err != nil {
35+
return nil, err
36+
}
37+
38+
return &automod, nil
39+
}

0 commit comments

Comments
 (0)