雅白

Programmer, Data Analyst and Gamer

github twitter rss
强制更新 EVE 国服资源服务器缓存
Apr 10, 2017
已阅读了 2 分钟

众所周知,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
    }

}

回到文章列表


comments powered by Disqus