149 lines
4.0 KiB
Go
149 lines
4.0 KiB
Go
package pak
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/gogf/gf/v2/net/ghttp"
|
|
"github.com/tiger1103/gfast/v3/api/v1/common/globe"
|
|
"github.com/tiger1103/gfast/v3/api/v1/common/tool"
|
|
"github.com/tiger1103/gfast/v3/database"
|
|
"github.com/tiger1103/gfast/v3/database/sqlite"
|
|
"math"
|
|
"net/http"
|
|
"os"
|
|
"path"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
image = "image"
|
|
terrain = "terrain"
|
|
)
|
|
|
|
func InitPakData(group *ghttp.RouterGroup) {
|
|
//group.GET("/data/pak/{source_id}/{z}/{x}/{y}.*", pakCallback)
|
|
//group.GET("/data/pak/{source_id}/layer.json", pakCallback)
|
|
group.GET("/data/pak/{source_id}/*.action", pakCallback)
|
|
}
|
|
|
|
type Json struct {
|
|
Layerjson []byte `json:"layerjson"`
|
|
}
|
|
|
|
// 获取pak文件中的表名
|
|
func gettablename(x int, y int, z int) string {
|
|
if z < 10 {
|
|
return "blocks"
|
|
} else {
|
|
tx := math.Ceil(float64(x / 512))
|
|
ty := math.Ceil(float64(y / 512))
|
|
return "blocks_" + strconv.Itoa(z) + "_" + strconv.Itoa(int(tx)) + "_" + strconv.Itoa(int(ty))
|
|
}
|
|
}
|
|
|
|
type Tile struct {
|
|
Tile []byte `json:"tile"`
|
|
Z int `json:"z"`
|
|
X int `json:"x"`
|
|
Y int `json:"y"`
|
|
}
|
|
|
|
func pakCallback(request *ghttp.Request) {
|
|
sourceId := request.Get("source_id").String()
|
|
pakobj := database.GetSourceDB(sourceId)
|
|
if pakobj.DB == nil {
|
|
request.Response.WriteStatus(http.StatusNotFound)
|
|
return
|
|
}
|
|
suffix := path.Ext(request.RequestURI)
|
|
if suffix == ".json" {
|
|
json := Json{}
|
|
pakobj.DB.Model(&Info{}).First(&json)
|
|
request.Response.Header().Set("content-type", "application/json")
|
|
globe.RenderData(request, json.Layerjson)
|
|
return
|
|
} else {
|
|
uri := request.RequestURI
|
|
arr := strings.Split(uri, "/")
|
|
//z := request.Get("z").Int()
|
|
//x := request.Get("x").Int()
|
|
//y := request.Get("y").Int()
|
|
z, _ := strconv.Atoi(arr[7])
|
|
x, _ := strconv.Atoi(arr[8])
|
|
y, _ := strconv.Atoi(strings.Split(arr[9], ".")[0])
|
|
//y = int(math.Pow(2, float64(z))) - 1 - y
|
|
tile := Tile{}
|
|
RowsAffected := pakobj.DB.Table(gettablename(x, y, z)).Select("tile").Where(&Tile{Z: z, X: x, Y: y}).First(&tile).RowsAffected
|
|
if RowsAffected > 0 {
|
|
request.Response.Header().Set("content-type", pakobj.ContentType)
|
|
if pakobj.Gzip {
|
|
request.Response.Header().Set("Content-Encoding", "gzip")
|
|
}
|
|
globe.RenderData(request, tile.Tile)
|
|
return
|
|
} else {
|
|
request.Response.WriteStatus(http.StatusNotFound)
|
|
}
|
|
}
|
|
}
|
|
|
|
type Info struct {
|
|
Minx float64 `json:"minx"`
|
|
Miny float64 `json:"miny"`
|
|
Maxx float64 `json:"maxx"`
|
|
Maxy float64 `json:"maxy"`
|
|
Minlevel int `json:"minlevel"`
|
|
Maxlevel int `json:"maxlevel"`
|
|
Type string `json:"type"`
|
|
Zip int `json:"zip"`
|
|
//Layerjson []byte `json:"layerjson"`
|
|
Contenttype string `json:"contenttype"`
|
|
}
|
|
|
|
func OpenPak(pakPath string, sourceID string) (error, *database.SourceObj) {
|
|
//if !globe.IS_OFFLINE_VERSION {
|
|
// //网络版事 需要拼接数据地址,方便服务器迁移
|
|
// pakPath = path.Join(globe.SOURCE, pakPath)
|
|
//}
|
|
getwd, err := os.Getwd()
|
|
if err != nil {
|
|
return err, nil
|
|
}
|
|
pakPath = path.Join(getwd, pakPath)
|
|
|
|
if !tool.PathExists(pakPath) {
|
|
return globe.GetErrors("资源不存在," + pakPath), nil
|
|
}
|
|
fmt.Println("资源存在")
|
|
db, err := sqlite.OpenDB(pakPath)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return err, nil
|
|
}
|
|
var obj database.SourceObj
|
|
obj.DB = db
|
|
info := Info{}
|
|
db.Model(&Info{}).First(&info)
|
|
if info.Type == image {
|
|
obj.Type = globe.LAYER
|
|
obj.ContentType = info.Contenttype
|
|
obj.Url = "/zm/api/v1/data/pak/" + sourceID + "/{z}/{x}/{y}." + strings.Split(obj.ContentType, "/")[1]
|
|
}
|
|
if info.Type == terrain {
|
|
obj.Type = globe.TERRAIN
|
|
obj.ContentType = "application/octet-stream"
|
|
obj.Url = "/zm/api/v1/data/pak/" + sourceID + "/"
|
|
}
|
|
if info.Zip > 0 {
|
|
obj.Gzip = true
|
|
}
|
|
obj.Info.MaxLevel = info.Maxlevel
|
|
obj.Info.MinLevel = info.Minlevel
|
|
obj.Info.West = strconv.FormatFloat(info.Minx, 'f', -1, 64)
|
|
obj.Info.South = strconv.FormatFloat(info.Miny, 'f', -1, 64)
|
|
obj.Info.East = strconv.FormatFloat(info.Maxx, 'f', -1, 64)
|
|
obj.Info.North = strconv.FormatFloat(info.Maxy, 'f', -1, 64)
|
|
database.SetSourceDB(sourceID, obj)
|
|
return err, &obj
|
|
}
|