Add game clock commands, command completions and Cyrene login tooling
This commit is contained in:
1 parent
1fa9504176
commit
67a819a4d3
21 files changed
+1194
-7
No files matched your search
@@ -0,0 +1,71 @@
|
||||
package sdkserver
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"gac-hkrpg-go/internal/common"
|
||||
)
|
||||
|
||||
// Route name is part of this server's HTTP interface, not a machine URL.
|
||||
const luaOverlayRoute = "/gacy-lua-overlay"
|
||||
|
||||
var luaBundleName = regexp.MustCompile(`^(?:M_LuaV|LuaV_[0-9a-f]{32}|[0-9a-f]{32})\.bytes$`)
|
||||
|
||||
// Dispatch outside ServeMux: a subtree registration conflicts with the
|
||||
// product-name wildcard used by the existing login endpoints in newer Go.
|
||||
func withLuaOverlay(next http.Handler, cfg common.LuaOverlayConfig) http.Handler {
|
||||
if !cfg.Enabled {
|
||||
return next
|
||||
}
|
||||
overlay := luaOverlayHandler(cfg)
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if strings.HasPrefix(r.URL.Path, luaOverlayRoute+"/") {
|
||||
overlay(w, r)
|
||||
return
|
||||
}
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// Serve only the Lua updater's known flat namespace. Stage files win, then the
|
||||
// local hotfix and shipping files; no filesystem path or remote URL is derived
|
||||
// from untrusted input. The original caches remain untouched.
|
||||
func luaOverlayHandler(cfg common.LuaOverlayConfig) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet && r.Method != http.MethodHead {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
path := strings.TrimPrefix(r.URL.Path, luaOverlayRoute+"/")
|
||||
path = strings.TrimPrefix(path, "client/Windows/")
|
||||
if !luaBundleName.MatchString(path) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
for _, root := range []string{cfg.StageDir, cfg.HotfixDir, cfg.StreamingDir} {
|
||||
file, err := os.Open(filepath.Join(root, path))
|
||||
if os.IsNotExist(err) {
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
http.Error(w, "Lua overlay read failed", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
info, err := file.Stat()
|
||||
if err != nil || !info.Mode().IsRegular() {
|
||||
file.Close()
|
||||
http.Error(w, "Lua overlay file invalid", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", "application/octet-stream")
|
||||
http.ServeContent(w, r, path, info.ModTime(), file)
|
||||
file.Close()
|
||||
return
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user