Go+Gin代理所有静态资源
远端不再使用nodojs工具,如hexo server等,直接使用go框架代理全部资源,减少部署流程。一个go srever即可启动所有站点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23// 使用Gin框架的Static和StaticFile接口,生成静态资源服务器
func (u *StaticDir) Bind() {
for _, param := range config_site.Site.ParamStaticService {
println("路由路径:", param.Path, "=>", param.Index)
dirs, err := os.ReadDir(param.Path)
if err != nil {
log.Println("读取静态文件夹失败:", param.Path)
continue
}
for _, fi := range dirs {
fi.Name()
if fi.IsDir() {
u.Ge.Static(param.Index+fi.Name(), param.Path+fi.Name())
// fmt.Println("路由目录:", param.Index+fi.Name(), param.Path+fi.Name())
} else {
u.Ge.StaticFile(param.Index+fi.Name(), param.Path+fi.Name())
// fmt.Println("路由文件:", param.Index+fi.Name(), param.Path+fi.Name())
}
}
u.Ge.StaticFile(param.Index, param.Path+"index.html")
}
}Live2D的资源,也可采用同样方式
1
2# 通过配置表,可以使gin指向不同的静态资源
{ index: /live2d_api/model/, path: ../live2d_api/model/ }
Go重写php接口
原live2d-widget给出的示例接口,是通过php实现。需在站点部署php、php-fpm等工具,麻烦还经常抽风。遂放弃使用php自行重写
这里选择直接套用现成的开源代码live2d_api_go,并做如部分修改,达到原php接口的效果:
将net/http库,改为gin库
1
2
3
4
5
6
7
8
9
10
11
12
13
14// old
mux := http.NewServeMux()
mux.Handle("/live2Dmodel/", http.StripPrefix("/live2Dmodel/", fs))
mux.HandleFunc("/get/", GetModel)
mux.HandleFunc("/switch/", SwitchModel)
mux.HandleFunc("/rand_textures/", RandomTextures)
// new
live2dRouter := u.Ge.Group("/live2d_api")
{
live2dRouter.GET("/get/", u.getModel)
live2dRouter.GET("/switch/", u.switchModel)
live2dRouter.GET("/rand_textures/", u.randomTextures)
}修改get方法参数获取方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25// old
func GetModel(w http.ResponseWriter, req *http.Request) {
ids, ok := req.URL.Query()["id"]
var id string
if !ok || len(ids) < 1 {
//log.Printf("err")
//error handling
w.Write([]byte("error"))
return
} else {
id = ids[0]
}
// --- skip ---
}
// new
func (u *Live2D) getModel(c *gin.Context) {
id := c.Query("id")
if len(id) < 1 {
// c.String(http.StatusNotFound, "error")
// return
id = "0-0"
}
// --- skip ---
}调整rand_textures接口。原接口仅根据model_list.json文件,来返回可以使用的皮肤。
但部分模型未将皮肤信息写入model_list.json中,而是需要读取模型中的textures.cache文件,并替换index.json中的textures字段,来实现换装
修改/rand_textures/接口,使其可以随机出textures.cache中的皮肤
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54// old
func RandomTextures(w http.ResponseWriter, req *http.Request) {
// --- skip ---
switch modelList.Models[modelId].(type) {
case string:
resp.Textures.ID = textureId
case []interface{}:
length := len(modelList.Models[modelId].([]interface{}))
resp.Textures.ID = rand.Intn(length)
for resp.Textures.ID == textureId {
resp.Textures.ID = rand.Intn(length)
}
}
// --- skip ---
}
// new
func (u *Live2D) randomTextures(c *gin.Context) {
// --- skip ---
switch modelList.Models[modelId].(type) {
case string:
resp.Textures.ID = textureId
// 这里判断一下textures中是否有换装资源
resp.Textures.ID = getTexturesID(modelList.Models[modelId].(string), textureId)
case []interface{}:
length := len(modelList.Models[modelId].([]interface{}))
resp.Textures.ID = rand.Intn(length)
for resp.Textures.ID == textureId {
resp.Textures.ID = rand.Intn(length)
}
}
// --- skip ---
}
// 从textures.cache中获取id
func getTexturesID(path string, id int) int {
cacheFile, err := os.Open(live2d_resources + "model/" + path + "/textures.cache")
if err != nil {
return id
}
defer cacheFile.Close()
byteValue, _ := io.ReadAll(cacheFile)
var list []interface{}
json.Unmarshal(byteValue, &list)
length := len(list)
newId := rand.Intn(length)
for newId == id {
newId = rand.Intn(length)
}
return newId
}修改/get/接口,使其返回的indox.json中的textures字段可变
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75// old
func GetModel(w http.ResponseWriter, req *http.Request) {
// --- skip ---
var path string
switch modelList.Models[modelId].(type) {
case string:
path = modelList.Models[modelId].(string)
case []interface{}:
path = modelList.Models[modelId].([]interface{})[textureId].(string)
}
model := GetModelData(path)
// --- skip ---
}
// new
func (u *Live2D) getModel(c *gin.Context) {
// --- skip ---
var path string
switch modelList.Models[modelId].(type) {
case string:
path = modelList.Models[modelId].(string)
case []interface{}:
path = modelList.Models[modelId].([]interface{})[textureId].(string)
textureId = -1
}
model := getModelData(path, textureId)
// --- skip ---
}
// 获取index.json
func getModelData(path string, texId int) ModelData {
// Open our jsonFile
jsonFile, err := os.Open(live2d_resources + "model/" + path + "/index.json")
// if we os.Open returns an error then handle it
if err != nil {
fmt.Println(err)
}
// defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close()
byteValue, _ := io.ReadAll(jsonFile)
var model ModelData
json.Unmarshal(byteValue, &model)
if texId > -1 {
getTextures(&model, path, texId)
}
changeDataPathInModel(&model, path)
return model
}
// 获取textures.cache中的值
func getTextures(data *ModelData, path string, id int) {
cacheFile, err := os.Open(live2d_resources + "model/" + path + "/textures.cache")
if err != nil {
return
}
defer cacheFile.Close()
byteValue, _ := io.ReadAll(cacheFile)
var list []interface{}
json.Unmarshal(byteValue, &list)
switch list[id].(type) {
case string:
data.Textures = []string{list[id].(string)}
case []interface{}:
data.Textures = []string{}
for _, s := range list[id].([]interface{}) {
data.Textures = append(data.Textures, s.(string))
}
}
}