Skip to content

Commit

Permalink
add new unsafe-predict-replay flag that prefetches 3 random replays (#61
Browse files Browse the repository at this point in the history
)

* add new unsafe-predict-replay flag that prefetches 3 random replays instead of recommended ones

* Add -unsafe-cache-env and -unsafe-predict-replay to docs
  • Loading branch information
Borengar authored Sep 24, 2021
1 parent 4ded9a2 commit 40a9777
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 1 deletion.
25 changes: 25 additions & 0 deletions UNSAFE_SPEEDUPS.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,28 @@ GGST will display some default news instead of the latest ones.

Since this returns a completely empty body, it might break the game in future versions. If that happens this would have to be expanded to return some skeleton news entries.
Right now GGST seems to handle the empty body gracefully.

## `-unsafe-cache-env` ([@Borengar](https://github.com/Borengar))

(v1.6.0+)

Totsugeki returns a hard-coded response for `/api/sys/get_env` calls.

This request gets called before every `/api/user/login` one. (Initial loading on title screen; replays; ranking; entering tower; etc).

### Speedup

Up to 1 second every time when you enter the tower, open replays, open the ranking list, etc.
2 seconds on the initial title screen loading if you start fast enough.

## `-unsafe-predict-replay` ([@Borengar](https://github.com/Borengar))

(v1.7.0+)

Totsugeki prefetches random celestial floor replays for the loading screen `/api/catalog/get_replay` calls.

The first batch of recommended replays will contain random replays when you open the replays dialog. A refresh will load actual replays that are recommended for you.

### Speedup

2-3 seconds saved on the initial loading on title screen.
5 changes: 4 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ func main() {
var unsafePredictStatsGet = flag.Bool("unsafe-predict-stats-get", false, "UNSAFE: Asynchronously precache expected statistics/get calls.")
var unsafeCacheNews = flag.Bool("unsafe-cache-news", false, "UNSAFE: Cache first news call and return cached version on subsequent calls.")
var unsafeNoNews = flag.Bool("unsafe-no-news", false, "UNSAFE: Return an empty response for news.")
var unsafePredictReplay = flag.Bool("unsafe-predict-replay", false, "UNSAFE: Asynchronously precache expected get_replay calls. Needs unsafe-predict-stats-get to work.")
var unsafeCacheEnv = flag.Bool("unsafe-cache-env", false, "UNSAFE: Cache first get_env call and return cached version on subsequent calls.")
var ungaBunga = flag.Bool("unga-bunga", UngaBungaMode != "", "UNSAFE: Enable all unsafe speedups for maximum speed. Please read https://github.com/optix2000/totsugeki/blob/master/UNSAFE_SPEEDUPS.md")
var iKnowWhatImDoing = flag.Bool("i-know-what-im-doing", false, "UNSAFE: Suppress any UNSAFE warnings. I hope you know what you're doing...")
Expand Down Expand Up @@ -324,6 +325,7 @@ func main() {
*unsafeAsyncStatsSet = true
*unsafePredictStatsGet = true
*unsafeNoNews = true
*unsafePredictReplay = true
*unsafeCacheEnv = true
}

Expand Down Expand Up @@ -401,6 +403,7 @@ func main() {
PredictStatsGet: *unsafePredictStatsGet,
CacheNews: *unsafeCacheNews,
NoNews: *unsafeNoNews,
PredictReplay: *unsafePredictReplay,
CacheEnv: *unsafeCacheEnv,
})

Expand All @@ -414,7 +417,7 @@ func main() {
}()
}

if !*iKnowWhatImDoing && (*unsafeAsyncStatsSet || *unsafePredictStatsGet || *unsafeCacheNews || *unsafeNoNews || *unsafeCacheEnv) {
if !*iKnowWhatImDoing && (*unsafeAsyncStatsSet || *unsafePredictStatsGet || *unsafeCacheNews || *unsafeNoNews || *unsafeCacheEnv || *unsafePredictReplay) {
fmt.Println("WARNING: Unsafe feature used. Make sure you understand the implications: https://github.com/optix2000/totsugeki/blob/master/UNSAFE_SPEEDUPS.md")
}

Expand Down
8 changes: 8 additions & 0 deletions proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type StriveAPIProxyOptions struct {
PredictStatsGet bool
CacheNews bool
NoNews bool
PredictReplay bool
CacheEnv bool
}

Expand Down Expand Up @@ -169,6 +170,7 @@ func CreateStriveProxy(listen string, GGStriveAPIURL string, PatchedAPIURL strin
statsSet := proxy.HandleCatchall
statsGet := proxy.HandleCatchall
getNews := proxy.HandleCatchall
getReplay := proxy.HandleCatchall
r := chi.NewRouter()
r.Use(middleware.Logger)

Expand All @@ -192,6 +194,11 @@ func CreateStriveProxy(listen string, GGStriveAPIURL string, PatchedAPIURL strin
proxy.HandleCatchall(w, r)
}
}

if options.PredictReplay {
getReplay = statsGet
proxy.prediction.PredictReplay = true
}
}
if options.NoNews {
getNews = func(w http.ResponseWriter, r *http.Request) {
Expand Down Expand Up @@ -225,6 +232,7 @@ func CreateStriveProxy(listen string, GGStriveAPIURL string, PatchedAPIURL strin
r.HandleFunc("/sys/get_news", getNews)
r.HandleFunc("/catalog/get_follow", statsGet)
r.HandleFunc("/catalog/get_block", statsGet)
r.HandleFunc("/catalog/get_replay", getReplay)
r.HandleFunc("/lobby/get_vip_status", statsGet)
r.HandleFunc("/item/get_item", statsGet)
r.HandleFunc("/*", proxy.HandleCatchall)
Expand Down
21 changes: 21 additions & 0 deletions proxy/stats_get_prediction.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"io/ioutil"
"net/http"
"net/url"
"regexp"
"strings"
)

Expand All @@ -26,6 +27,7 @@ type StatsGetPrediction struct {
predictionState PredictionState
statsGetTasks map[string]*StatsGetTask
client *http.Client
PredictReplay bool
skipNext bool
}

Expand Down Expand Up @@ -95,6 +97,16 @@ func (s *StatsGetPrediction) HandleGetStats(w http.ResponseWriter, r *http.Reque
r.Body.Close() // must close
r.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes)) // Reset Body as the request gets reused by catchall if this has an error.
req := string(bodyBytes)
if strings.HasSuffix(r.RequestURI, "catalog/get_replay") {
regex := regexp.MustCompile(`940100059aff00.*$`)
for _, data := range []string{"940100059aff00636390ffff000001\x00", "940100059aff00636390ffff010001\x00", "940100059aff00636390ffff020001\x00"} {
possibleReq := regex.ReplaceAllString(req, data)
if _, ok := s.statsGetTasks[possibleReq]; ok {
req = possibleReq
break
}
}
}
if task, ok := s.statsGetTasks[req]; ok {
resp := <-task.response
if resp == nil {
Expand Down Expand Up @@ -194,6 +206,11 @@ func (s *StatsGetPrediction) AsyncGetStats(body []byte, reqType StatsGetType) {
queue := make(chan *StatsGetTask, len(reqs)+1)
for i := range reqs {
task := reqs[i]

if task.path == "catalog/get_replay" && !s.PredictReplay {
continue
}

id := bodyConst + task.data + "\x00"
task.request = id
task.response = make(chan *http.Response)
Expand All @@ -215,6 +232,7 @@ func CreateStatsGetPrediction(GGStriveAPIURL string, client *http.Client) StatsG
predictionState: ready,
statsGetTasks: make(map[string]*StatsGetTask),
client: client,
PredictReplay: false,
skipNext: false,
}
}
Expand Down Expand Up @@ -316,6 +334,9 @@ func ExpectedTitleScreenCalls() []StatsGetTask {
{data: "96a00101ffffff", path: "statistics/get"},
{data: "93000101", path: "catalog/get_follow"},
{data: "920101", path: "catalog/get_block"},
{data: "940100059aff00636390ffff000001", path: "catalog/get_replay"}, // these 3 only get used if unsafe-predict-replay is set
{data: "940100059aff00636390ffff010001", path: "catalog/get_replay"},
{data: "940100059aff00636390ffff020001", path: "catalog/get_replay"},
{data: "91a0", path: "lobby/get_vip_status"},
{data: "9105", path: "item/get_item"},
}
Expand Down

0 comments on commit 40a9777

Please sign in to comment.