雅白
强制更新 EVE 国服资源服务器缓存
众所周知,EVE 的 DoD 功能可以在安装游戏时只下载启动器,在游戏时从服务器下载所需要的资源文件。世界服的资源服务器的地址是 res.eveonline.ccpgames.com,如果与资源服务器连接不畅,在游戏中就会遇到资源加载缓慢的情况,如左下角指示器长时间提示加载资源但仍有贴图、模型丢失等。
我们 (EVEModX Developers) 发现,国服的资源文件服务器 res.eve-online.com.cn 实际上是世界服资源服务器的反向代理。这也就意味着即使国服不更新,我们也可以从国内的服务器上加载到世界服的资源。
两台服务器的 HTTP Header 对比图
可以知道这其实是一个反代,为了让国内玩家也可以流畅使用这个缓存,需要让这个服务器把世界服的资源也缓存下来。
在世界服客户端内找到了资源文件 Index,写了个脚本跑一遍缓存
package main
import (
"io"
"os"
"fmt"
"log"
"bufio"
"strings"
"net/http"
p "path/filepath"
"github.com/cheggaaa/pb"
)
var (
uris []string
concurrency int = 20 //线程数
endPoint = "http://res.eve-online.com.cn/"
logger = log.New(os.Stdout, "", log.Lshortfile| log.Ldate| log.Ltime| log.Lmicroseconds)
)
func downloadFile(filepath string, url string) (err error) {
os.MkdirAll(p.Dir(filepath), 0777)
RETRY1:
out, err := os.Create(filepath)
if err != nil {
goto RETRY1
}
defer out.Close()
RETRY2:
resp, err := http.Get(url)
if err != nil {
logger.Println(fmt.Sprintf("Encountered error: %s retrying...", err.Error()))
goto RETRY2
}
defer resp.Body.Close()
_, err = io.Copy(out, resp.Body)
if err != nil {
logger.Println(fmt.Sprintf("Encountered error: %s retrying...", err.Error()))
goto RETRY2
}
return nil
}
func readLines(fileName string, arrayhandler func(string)) error {
f, err := os.Open(fileName)
if err != nil {
return err
}
buf := bufio.NewReader(f)
for {
line, err := buf.ReadString('\n')
line = strings.TrimSpace(line)
arrayhandler(line)
if err != nil {
if err == io.EOF {
return nil
}
return err
}
}
return nil
}
func split(indexLine string){
uri := strings.Split(indexLine, ",")[1]
uris = append(uris, uri)
}
func main() {
logger.Println("Start reading file index")
err := readLines("index.txt", split)
if err != nil {
panic(err)
}
logger.Println("Finished reading file index")
logger.Println(fmt.Sprintf("Index: %d total entries", len(uris)))
logger.Println(fmt.Sprintf("Start caching, %d threads", concurrency))
sem := make(chan bool, concurrency)
bar := pb.StartNew(len(uris))
j := len(uris) - 1
for i := 0; i < j; i++ {
sem <- true
go func(i int){
defer func() { <-sem }()
bar.Prefix(uris[i])
err := downloadFile("data/" + uris[i], endPoint + uris[i])
if err != nil {
panic(err)
}
bar.Increment()
}(i)
}
for i := 0; i < cap(sem); i++ {
sem <- true
}
}