tangled
alpha
login
or
join now
opencourse.world
/
ocw-server
0
fork
atom
The server for Open Course World
0
fork
atom
overview
issues
pulls
pipelines
util/generate_super_wagon_world_db/by_super_world.go
mm2srv
3 years ago
3fae37fa
8c55a4d3
+286
-1
5 changed files
expand all
collapse all
unified
split
.gitignore
db
dump
super_world.go
thumbnail_encryption.go
util
generate_super_wagon_world_db
by_levels.go
by_super_world.go
+4
.gitignore
reviewed
···
19
19
env/
20
20
21
21
*.bin
22
22
+
23
23
+
.DS_Store
24
24
+
25
25
+
util/generate_super_wagon_world_db/tmp/
+142
db/dump/super_world.go
reviewed
···
1
1
+
package dump
2
2
+
3
3
+
import (
4
4
+
"encoding/json"
5
5
+
"fmt"
6
6
+
"reflect"
7
7
+
"strconv"
8
8
+
"strings"
9
9
+
10
10
+
"github.com/jmoiron/sqlx"
11
11
+
)
12
12
+
13
13
+
type SuperWorld struct {
14
14
+
Pid string `db:"pid" json:"pid"`
15
15
+
Id string `db:"world_id" json:"id"`
16
16
+
Worlds int `db:"worlds" json:"worlds"`
17
17
+
Levels int `db:"levels" json:"levels"`
18
18
+
PlanetType int `db:"planet_type" json:"planet_type"`
19
19
+
Created int `db:"created" json:"created"`
20
20
+
Unk1 []byte `db:"unk1" json:"unk1"`
21
21
+
Unk5 int `db:"unk5" json:"unk5"`
22
22
+
Unk6 int `db:"unk6" json:"unk6"`
23
23
+
Unk7 int `db:"unk7" json:"unk7"`
24
24
+
Thumbnail []byte `db:"thumbnail" json:"thumbnail"`
25
25
+
ThumbnailUrl string `db:"thumbnail_url"`
26
26
+
ThumbnailSize int `db:"thumbnail_size"`
27
27
+
ThumbnailFilename string `db:"thumbnail_filename"`
28
28
+
}
29
29
+
30
30
+
func (s SuperWorld) Save(db *sqlx.DB) error {
31
31
+
var pid string
32
32
+
db.QueryRowx("SELECT pid FROM world WHERE pid = ?", s.Pid).Scan(&pid)
33
33
+
34
34
+
if pid == "" {
35
35
+
return s.Create(db)
36
36
+
}
37
37
+
38
38
+
return s.Update(db)
39
39
+
}
40
40
+
41
41
+
func (s SuperWorld) Create(db *sqlx.DB) error {
42
42
+
v := reflect.ValueOf(s)
43
43
+
fields := []string{}
44
44
+
values_placeholder := []string{}
45
45
+
values := []any{}
46
46
+
for i := 0; i < v.NumField(); i++ {
47
47
+
field := v.Type().Field(i).Tag.Get("db")
48
48
+
if field != "" {
49
49
+
fields = append(fields, field)
50
50
+
values_placeholder = append(values_placeholder, "?")
51
51
+
values = append(values, v.Field(i).Interface())
52
52
+
}
53
53
+
}
54
54
+
55
55
+
stmt := fmt.Sprintf("INSERT INTO world (%s) VALUES (%s)", strings.Join(fields, ", "), strings.Join(values_placeholder, ", "))
56
56
+
57
57
+
_, err := db.Exec(stmt, values...)
58
58
+
if err != nil {
59
59
+
return err
60
60
+
}
61
61
+
62
62
+
return nil
63
63
+
}
64
64
+
65
65
+
func (s SuperWorld) Update(db *sqlx.DB) error {
66
66
+
v := reflect.ValueOf(s)
67
67
+
fields := []string{}
68
68
+
values := []any{}
69
69
+
for i := 0; i < v.NumField(); i++ {
70
70
+
field := v.Type().Field(i).Tag.Get("db")
71
71
+
if field != "" {
72
72
+
fields = append(fields, fmt.Sprintf("%s = ?", field))
73
73
+
values = append(values, v.Field(i).Interface())
74
74
+
}
75
75
+
}
76
76
+
77
77
+
values = append(values, s.Pid)
78
78
+
79
79
+
stmt := fmt.Sprintf("UPDATE world SET %s WHERE pid = ?", strings.Join(fields, ", "))
80
80
+
81
81
+
_, err := db.Exec(stmt, values...)
82
82
+
if err != nil {
83
83
+
return err
84
84
+
}
85
85
+
86
86
+
return nil
87
87
+
}
88
88
+
89
89
+
func SuperWorldFromJson(buf []byte) (SuperWorld, []CourseInfo, []UserInfo, error) {
90
90
+
var data map[string]any
91
91
+
92
92
+
err := json.Unmarshal(buf, &data)
93
93
+
if err != nil {
94
94
+
return SuperWorld{}, []CourseInfo{}, []UserInfo{}, err
95
95
+
}
96
96
+
97
97
+
delete(data, "thumbnail")
98
98
+
99
99
+
if vv, ok := data["uploader"]; ok {
100
100
+
if v, ok := vv.(map[string]any)["pid"]; ok {
101
101
+
data["pid"] = strconv.FormatUint(uint64(v.(float64)), 10)
102
102
+
}
103
103
+
}
104
104
+
105
105
+
buf, _ = json.Marshal(data)
106
106
+
107
107
+
var superWorld SuperWorld
108
108
+
err = json.Unmarshal(buf, &superWorld)
109
109
+
if err != nil {
110
110
+
return SuperWorld{}, []CourseInfo{}, []UserInfo{}, err
111
111
+
}
112
112
+
113
113
+
users := []UserInfo{}
114
114
+
courses := []CourseInfo{}
115
115
+
116
116
+
if vv, ok := data["courses"]; ok {
117
117
+
for _, course := range vv.([]any) {
118
118
+
buf, _ = json.Marshal(course)
119
119
+
courseInfo, userInfos, err := FromJson(buf)
120
120
+
if err != nil {
121
121
+
return SuperWorld{}, []CourseInfo{}, []UserInfo{}, err
122
122
+
}
123
123
+
courses = append(courses, courseInfo)
124
124
+
125
125
+
for _, u := range userInfos {
126
126
+
found := false
127
127
+
for _, uu := range users {
128
128
+
if uu.Pid == u.Pid {
129
129
+
found = true
130
130
+
}
131
131
+
}
132
132
+
if !found {
133
133
+
users = append(users, u)
134
134
+
}
135
135
+
}
136
136
+
137
137
+
//users = append(users, userInfos...)
138
138
+
}
139
139
+
}
140
140
+
141
141
+
return superWorld, courses, users, nil
142
142
+
}
+1
-1
db/dump/thumbnail_encryption.go
reviewed
···
23
23
}
24
24
25
25
out := &bytes.Buffer{}
26
26
-
err = jpeg.Encode(out, img, &jpeg.Options{Quality: 85})
26
26
+
err = jpeg.Encode(out, img, &jpeg.Options{Quality: 65})
27
27
if err != nil {
28
28
return nil, err
29
29
}
+139
util/generate_super_wagon_world_db/by_super_world.go
reviewed
···
1
1
+
package main
2
2
+
3
3
+
import (
4
4
+
"fmt"
5
5
+
"io/ioutil"
6
6
+
"log"
7
7
+
"net/http"
8
8
+
"os"
9
9
+
"smm2_gameserver/db/dump"
10
10
+
)
11
11
+
12
12
+
func GetData(url string) ([]byte, error) {
13
13
+
resp, err := http.Get(url)
14
14
+
if err != nil {
15
15
+
return []byte{}, err
16
16
+
}
17
17
+
buf, err := ioutil.ReadAll(resp.Body)
18
18
+
if err != nil {
19
19
+
return []byte{}, err
20
20
+
}
21
21
+
return buf, nil
22
22
+
}
23
23
+
24
24
+
func GetDataCached(url, file string) ([]byte, error) {
25
25
+
if _, err := os.Stat(file); err == nil {
26
26
+
return ioutil.ReadFile(file)
27
27
+
}
28
28
+
fmt.Println("fetch", url)
29
29
+
buf, err := GetData(url)
30
30
+
if err != nil {
31
31
+
return []byte{}, err
32
32
+
}
33
33
+
34
34
+
err = ioutil.WriteFile(file, buf, 0644)
35
35
+
return buf, err
36
36
+
}
37
37
+
38
38
+
func main() {
39
39
+
superWorldId := "2383f7c2cb5c5ce0_20230303172233043040"
40
40
+
41
41
+
filename := "Super_Wagon_World_05.03.2023.db"
42
42
+
db, err := dump.InitDump(filename)
43
43
+
if err != nil {
44
44
+
log.Fatal(err)
45
45
+
}
46
46
+
fmt.Println(db)
47
47
+
48
48
+
buf, err := GetDataCached(fmt.Sprintf("https://smm2.wizul.us/mm2/super_world/%s", superWorldId), fmt.Sprintf("world_%s.json", superWorldId))
49
49
+
if err != nil {
50
50
+
log.Fatal(err)
51
51
+
}
52
52
+
53
53
+
world, courses, users, err := dump.SuperWorldFromJson(buf)
54
54
+
55
55
+
if err := world.Save(db); err != nil {
56
56
+
log.Fatal(err)
57
57
+
}
58
58
+
59
59
+
for _, course := range courses {
60
60
+
var check string
61
61
+
db.QueryRowx("SELECT pid FROM world_levels WHERE pid = ? AND data_id = ?", world.Pid, course.DataId).Scan(&check)
62
62
+
if check == "" {
63
63
+
_, err := db.Exec("INSERT INTO world_levels (pid, data_id, ninjis) VALUES (?, ?, ?)", world.Pid, course.DataId, 0)
64
64
+
if err != nil {
65
65
+
log.Fatal(err)
66
66
+
}
67
67
+
}
68
68
+
69
69
+
// add thumb
70
70
+
buf, err := GetDataCached(fmt.Sprintf("https://smm2.wizul.us/mm2/level_thumbnail/%s", course.CourseId), fmt.Sprintf("thumb_%s.jpg", course.CourseId))
71
71
+
if err != nil {
72
72
+
log.Fatal(err)
73
73
+
}
74
74
+
unpacked, err := dump.UnpackJpegThumbnail(buf)
75
75
+
if err != nil {
76
76
+
log.Fatal(err)
77
77
+
}
78
78
+
course.OneScreenThumbnail = unpacked
79
79
+
80
80
+
// add entire_thumb
81
81
+
buf, err = GetDataCached(fmt.Sprintf("https://smm2.wizul.us/mm2/level_entire_thumbnail/%s", course.CourseId), fmt.Sprintf("thumb_entire_%s.jpg", course.CourseId))
82
82
+
if err != nil {
83
83
+
log.Fatal(err)
84
84
+
}
85
85
+
course.EntireThumbnail = buf
86
86
+
87
87
+
// add level_data
88
88
+
buf, err = GetDataCached(fmt.Sprintf("https://smm2.wizul.us/mm2/level_data/%s", course.CourseId), fmt.Sprintf("level_%s.bcd", course.CourseId))
89
89
+
if err != nil {
90
90
+
log.Fatal(err)
91
91
+
}
92
92
+
decrypted, err := dump.DecryptLevel(buf)
93
93
+
if err != nil {
94
94
+
log.Fatal(err)
95
95
+
}
96
96
+
97
97
+
buf, err = dump.Compress(decrypted)
98
98
+
if err != nil {
99
99
+
log.Fatal(err)
100
100
+
}
101
101
+
course.LevelData = buf
102
102
+
103
103
+
// reset stats
104
104
+
course.WorldRecord = 0
105
105
+
course.NumComments = 0
106
106
+
course.Clears = 0
107
107
+
course.Attempts = 0
108
108
+
course.Plays = 0
109
109
+
course.VersusMatches = 0
110
110
+
course.CoopMatches = 0
111
111
+
course.Likes = 0
112
112
+
course.Boos = 0
113
113
+
course.UniquePlayersAndVersus = 0
114
114
+
course.WeeklyLikes = 0
115
115
+
course.WeeklyPlays = 0
116
116
+
course.FirstCompleterPid = ""
117
117
+
course.RecordHolderPid = ""
118
118
+
119
119
+
if err := course.Save(db); err != nil {
120
120
+
log.Fatal(err)
121
121
+
}
122
122
+
}
123
123
+
124
124
+
for _, user := range users {
125
125
+
if user.Pid == world.Pid {
126
126
+
user.Name = "Wagon"
127
127
+
if err := user.Save(db); err != nil {
128
128
+
log.Fatal(err)
129
129
+
}
130
130
+
}
131
131
+
}
132
132
+
133
133
+
/*
134
134
+
spew.Dump(world)
135
135
+
spew.Dump(len(courses))
136
136
+
spew.Dump(len(users))
137
137
+
fmt.Println(err)
138
138
+
*/
139
139
+
}
util/generate_super_wagon_world_db/main.go
util/generate_super_wagon_world_db/by_levels.go
reviewed