mirror of
https://github.com/tengge1/ShadowEditor.git
synced 2026-02-01 16:08:17 +00:00
Merge branch 'golang'
This commit is contained in:
commit
50f94c273d
0
scripts/build.bat
Normal file → Executable file
0
scripts/build.bat
Normal file → Executable file
0
scripts/run.bat
Normal file → Executable file
0
scripts/run.bat
Normal file → Executable file
@ -22,6 +22,6 @@ var versionCmd = &cobra.Command{
|
||||
Short: "Print the version number of ShadowEditor",
|
||||
Long: `All software has versions. This is ShadowEditor's`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("ShadowEditor version: v0.4.6")
|
||||
fmt.Println("ShadowEditor version: v0.5.0")
|
||||
},
|
||||
}
|
||||
|
||||
23
server/config-server.toml
Normal file
23
server/config-server.toml
Normal file
@ -0,0 +1,23 @@
|
||||
# Shadow Editor Server Configuration
|
||||
|
||||
[server]
|
||||
port = ":2020" # server address
|
||||
|
||||
[database]
|
||||
type = "mongo" # only support mongo
|
||||
connection = "mongodb://127.0.0.1:27017" # mongo connection string
|
||||
database = "ShadowEditor" # mongo database name
|
||||
|
||||
[authority]
|
||||
enabled = true # enable authority
|
||||
expires = 120 # login time, minutes, only support integer
|
||||
|
||||
[upload]
|
||||
max_size = 1000000000 # max upload file size
|
||||
|
||||
[remote]
|
||||
enabled = false # enable remote edit
|
||||
web_socket_port = 5000 # web socket server port
|
||||
|
||||
[log]
|
||||
file = "../logs/ShadowServer.txt"
|
||||
@ -5,11 +5,12 @@ port = ":2020" # server address
|
||||
|
||||
[database]
|
||||
type = "mongo" # only support mongo
|
||||
connection = "mongodb://127.0.0.1:27017" # mongo connection string
|
||||
database = "ShadowEditor" # mongo database name
|
||||
host = "127.0.0.1" # mongoDB host
|
||||
port = 27017 # mongoDB port
|
||||
database = "ShadowEditor" # mongoDB database name
|
||||
|
||||
[authority]
|
||||
enabled = true # enable authority
|
||||
enabled = true # enable authority
|
||||
expires = 120 # login time, minutes, only support integer
|
||||
|
||||
[upload]
|
||||
@ -19,5 +20,10 @@ max_size = 1000000000 # max upload file size
|
||||
enabled = false # enable remote edit
|
||||
web_socket_port = 5000 # web socket server port
|
||||
|
||||
[path]
|
||||
public_dir = "./public" # The directory that contains index.html.
|
||||
# Path `./public/Upload` need write authority.
|
||||
log_dir = "./logs" # The directory that contains log files. Need write authority.
|
||||
|
||||
[log]
|
||||
file = "../logs/ShadowServer.txt"
|
||||
file = "./logs/ShadowServer.txt"
|
||||
@ -8,12 +8,15 @@
|
||||
package helper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
// GetConfig get config from config.toml
|
||||
// GetConfig get server config from `config.toml`
|
||||
func GetConfig(path string) (config *ConfigModel, err error) {
|
||||
file, err := os.Open(path)
|
||||
if err != nil {
|
||||
@ -27,49 +30,68 @@ func GetConfig(path string) (config *ConfigModel, err error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// parse mongoDB connection string.
|
||||
config.Database.Connection = fmt.Sprintf("mongodb://%v:%v", config.Database.Host, config.Database.Port)
|
||||
|
||||
// In windows system, path separator "/" should be replace with "\\".
|
||||
if strings.HasPrefix(runtime.GOOS, "windows") {
|
||||
config.Path.PublicDir = strings.ReplaceAll(config.Path.PublicDir, "/", "\\")
|
||||
config.Path.LogDir = strings.ReplaceAll(config.Path.LogDir, "/", "\\")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// ConfigModel shadoweditor config
|
||||
// ConfigModel is the structure of file `config.toml`.
|
||||
type ConfigModel struct {
|
||||
Server ServerConfigModel `toml:"server"`
|
||||
Database DatabaseConfigModel `toml:"database"`
|
||||
Authority AuthorityConfigModel `toml:"authority"`
|
||||
Upload UploadConfigModel `toml:"upload"`
|
||||
Remote RemoteConfigModel `toml:"remote"`
|
||||
Path PathConfigModel `toml:"path"`
|
||||
Log LogConfigModel `toml:"log"`
|
||||
}
|
||||
|
||||
// ServerConfigModel server config
|
||||
// ServerConfigModel is the server config section in `config.toml`;
|
||||
type ServerConfigModel struct {
|
||||
Port string `toml:"port"`
|
||||
}
|
||||
|
||||
// DatabaseConfigModel database config
|
||||
// DatabaseConfigModel is the database config section in `config.toml`;
|
||||
type DatabaseConfigModel struct {
|
||||
Type string `toml:"type"`
|
||||
Connection string `toml:"connection"`
|
||||
Type string `toml:"type"`
|
||||
Host string `toml:"host"`
|
||||
Port int `toml:"port"`
|
||||
// Connection should not read from config.toml.
|
||||
Connection string
|
||||
Database string `toml:"database"`
|
||||
}
|
||||
|
||||
// AuthorityConfigModel authority config
|
||||
// AuthorityConfigModel is the authority config section in `config.toml`;
|
||||
type AuthorityConfigModel struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
Expires int `toml:"expires"`
|
||||
}
|
||||
|
||||
// UploadConfigModel upload config
|
||||
// UploadConfigModel is the upload config section in `config.toml`;
|
||||
type UploadConfigModel struct {
|
||||
MaxSize int64 `toml:"max_size"`
|
||||
}
|
||||
|
||||
// RemoteConfigModel remote config
|
||||
// RemoteConfigModel is the remote config section in `config.toml`;
|
||||
type RemoteConfigModel struct {
|
||||
Enabled bool `toml:"enabled"`
|
||||
WebSocketPort int `toml:"web_socket_port"`
|
||||
}
|
||||
|
||||
// LogConfigModel log config
|
||||
// PathConfigModel is the authority path section in `config.toml`;
|
||||
type PathConfigModel struct {
|
||||
PublicDir string `toml:"public_dir"`
|
||||
LogDir string `toml:"log_dir"`
|
||||
}
|
||||
|
||||
// LogConfigModel is the log config section in `config.toml`;
|
||||
type LogConfigModel struct {
|
||||
File string `toml:"file"`
|
||||
}
|
||||
|
||||
@ -29,5 +29,8 @@ func TestConfig(t *testing.T) {
|
||||
t.Logf("remote.enabled: %v", config.Remote.Enabled)
|
||||
t.Logf("remote.web_socket_port: %v", config.Remote.WebSocketPort)
|
||||
|
||||
t.Logf("path.public_dir: %v", config.Path.PublicDir)
|
||||
t.Logf("path.log_dir: %v", config.Path.LogDir)
|
||||
|
||||
t.Logf("log.file: %v", config.Log.File)
|
||||
}
|
||||
|
||||
@ -8,19 +8,24 @@
|
||||
package helper
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
|
||||
jsoniter "github.com/json-iterator/go"
|
||||
|
||||
"github.com/tengge1/shadoweditor/helper/encoder"
|
||||
)
|
||||
|
||||
func init() {
|
||||
jsoniter.RegisterTypeEncoder("time.Time", encoder.TimeEncoder{})
|
||||
jsoniter.RegisterTypeEncoder(reflect.TypeOf(time.Now()).String(), encoder.TimeEncoder{})
|
||||
jsoniter.RegisterTypeEncoder(
|
||||
"go.mongodb.org/mongo-driver/bson/primitive.ObjectID",
|
||||
reflect.TypeOf(primitive.NewObjectID()).String(),
|
||||
encoder.PrimitiveObjectIDEncoder{},
|
||||
)
|
||||
jsoniter.RegisterTypeEncoder(
|
||||
"go.mongodb.org/mongo-driver/bson/primitive.D",
|
||||
reflect.TypeOf(primitive.D{}).String(),
|
||||
encoder.PrimitiveDEncoder{},
|
||||
)
|
||||
}
|
||||
|
||||
@ -166,7 +166,7 @@ func (Animation) Add(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
|
||||
savePath := fmt.Sprintf("/Upload/Animation/%v", helper.TimeToString(now, "yyyyMMddHHmmss"))
|
||||
physicalPath := helper.MapPath(savePath)
|
||||
physicalPath := server.MapPath(savePath)
|
||||
|
||||
tempPath := filepath.Join(physicalPath, "temp")
|
||||
|
||||
@ -375,7 +375,7 @@ func (Animation) Delete(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
path := doc["SavePath"].(string)
|
||||
physicalPath := helper.MapPath(path)
|
||||
physicalPath := server.MapPath(path)
|
||||
os.RemoveAll(physicalPath)
|
||||
|
||||
db.DeleteOne(server.AnimationCollectionName, filter)
|
||||
|
||||
@ -166,7 +166,7 @@ func (Audio) Add(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
|
||||
savePath := fmt.Sprintf("/Upload/Audio/%v", helper.TimeToString(now, "yyyyMMddHHmmss"))
|
||||
physicalPath := helper.MapPath(savePath)
|
||||
physicalPath := server.MapPath(savePath)
|
||||
|
||||
if _, err := os.Stat(physicalPath); os.IsNotExist(err) {
|
||||
os.MkdirAll(physicalPath, 0755)
|
||||
@ -343,7 +343,7 @@ func (Audio) Delete(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
path := doc["SavePath"].(string)
|
||||
physicalPath := helper.MapPath(path)
|
||||
physicalPath := server.MapPath(path)
|
||||
os.RemoveAll(physicalPath)
|
||||
|
||||
db.DeleteOne(server.AudioCollectionName, filter)
|
||||
|
||||
@ -19,7 +19,7 @@ import (
|
||||
// CopyAssets copy the assets needed to the exported scene.
|
||||
func CopyAssets(path string) error {
|
||||
// copy html files
|
||||
sourceName := helper.MapPath("/index.html")
|
||||
sourceName := server.MapPath("/index.html")
|
||||
destName := filepath.Join(path, "editor.html")
|
||||
if err := helper.CopyFile(sourceName, destName); err != nil {
|
||||
return err
|
||||
@ -41,28 +41,28 @@ func CopyAssets(path string) error {
|
||||
os.MkdirAll(dirName, 0755)
|
||||
}
|
||||
|
||||
sourceName = helper.MapPath("/build/ShadowEditor.js")
|
||||
sourceName = server.MapPath("/build/ShadowEditor.js")
|
||||
destName = filepath.Join(path, "build", "ShadowEditor.js")
|
||||
if err := helper.CopyFile(sourceName, destName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// copy assets folder
|
||||
sourceName = helper.MapPath("/assets")
|
||||
sourceName = server.MapPath("/assets")
|
||||
destName = filepath.Join(path, "assets")
|
||||
if err := helper.CopyDirectory(sourceName, destName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// copy language pack
|
||||
sourceName = helper.MapPath("/lang")
|
||||
sourceName = server.MapPath("/lang")
|
||||
destName = filepath.Join(path, "lang")
|
||||
if err := helper.CopyDirectory(sourceName, destName); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// copy website icon
|
||||
sourceName = helper.MapPath("/favicon.ico")
|
||||
sourceName = server.MapPath("/favicon.ico")
|
||||
destName = filepath.Join(path, "favicon.ico")
|
||||
return helper.CopyDirectory(sourceName, destName)
|
||||
}
|
||||
|
||||
@ -26,7 +26,7 @@ func init() {
|
||||
func Run(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
|
||||
path := helper.MapPath(fmt.Sprintf("/temp/%v", helper.TimeToString(now, "yyyyMMddHHmmss")))
|
||||
path := server.MapPath(fmt.Sprintf("/temp/%v", helper.TimeToString(now, "yyyyMMddHHmmss")))
|
||||
|
||||
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||
os.MkdirAll(path, 0755)
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
// For more information, please visit: https://github.com/tengge1/ShadowEditor
|
||||
// You can also visit: https://gitee.com/tengge1/ShadowEditor
|
||||
|
||||
package helper
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -18,6 +18,6 @@ func MapPath(path string) string {
|
||||
if !strings.HasPrefix(path, "/") {
|
||||
path = "/" + path
|
||||
}
|
||||
path = strings.ReplaceAll(path, "/", string(filepath.Separator))
|
||||
return fmt.Sprintf("./%v", path)
|
||||
path = fmt.Sprintf("%v%v", Config.Path.PublicDir, path)
|
||||
return strings.ReplaceAll(path, "/", string(filepath.Separator))
|
||||
}
|
||||
@ -5,7 +5,7 @@
|
||||
// For more information, please visit: https://github.com/tengge1/ShadowEditor
|
||||
// You can also visit: https://gitee.com/tengge1/ShadowEditor
|
||||
|
||||
package helper
|
||||
package server
|
||||
|
||||
import "testing"
|
||||
|
||||
@ -169,7 +169,7 @@ func (Mesh) Add(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
|
||||
savePath := fmt.Sprintf("/Upload/Model/%v", helper.TimeToString(now, "yyyyMMddHHmmss"))
|
||||
physicalPath := helper.MapPath(savePath)
|
||||
physicalPath := server.MapPath(savePath)
|
||||
|
||||
tempPath := filepath.Join(physicalPath, "temp")
|
||||
|
||||
@ -540,7 +540,7 @@ func (Mesh) Delete(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
path := doc["SavePath"].(string)
|
||||
physicalPath := helper.MapPath(path)
|
||||
physicalPath := server.MapPath(path)
|
||||
os.RemoveAll(physicalPath)
|
||||
|
||||
db.DeleteOne(server.MeshCollectionName, filter)
|
||||
@ -588,11 +588,11 @@ func (Mesh) Download(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// create zip file
|
||||
savePath := helper.MapPath(doc["SavePath"].(string))
|
||||
savePath := server.MapPath(doc["SavePath"].(string))
|
||||
|
||||
now := helper.TimeToString(time.Now(), "yyyyMMddHHmmssfff")
|
||||
destFile := fmt.Sprintf("/temp/%v.zip", now)
|
||||
descPhysicalFile := helper.MapPath(destFile)
|
||||
descPhysicalFile := server.MapPath(destFile)
|
||||
|
||||
helper.Zip(savePath, descPhysicalFile)
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
// For more information, please visit: https://github.com/tengge1/ShadowEditor
|
||||
// You can also visit: https://gitee.com/tengge1/ShadowEditor
|
||||
|
||||
package middleware
|
||||
package server
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
@ -5,7 +5,7 @@
|
||||
// For more information, please visit: https://github.com/tengge1/ShadowEditor
|
||||
// You can also visit: https://gitee.com/tengge1/ShadowEditor
|
||||
|
||||
package middleware
|
||||
package server
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
@ -5,7 +5,7 @@
|
||||
// For more information, please visit: https://github.com/tengge1/ShadowEditor
|
||||
// You can also visit: https://gitee.com/tengge1/ShadowEditor
|
||||
|
||||
package middleware
|
||||
package server
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
@ -15,8 +15,6 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/tengge1/shadoweditor/helper"
|
||||
)
|
||||
|
||||
// StaticHandler is responsible for serve static contents.
|
||||
@ -29,7 +27,7 @@ func StaticHandler(w http.ResponseWriter, r *http.Request, next http.HandlerFunc
|
||||
// TODO: May have security risk.
|
||||
|
||||
// static contents
|
||||
path := helper.MapPath("/public/") + r.URL.Path
|
||||
path := MapPath("/public/") + r.URL.Path
|
||||
|
||||
if strings.HasSuffix(path, "/") {
|
||||
path += "index.html"
|
||||
@ -169,7 +169,7 @@ func (Screenshot) Add(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
|
||||
savePath := fmt.Sprintf("/Upload/Screenshot/%v", helper.TimeToString(now, "yyyyMMddHHmmss"))
|
||||
physicalPath := helper.MapPath(savePath)
|
||||
physicalPath := server.MapPath(savePath)
|
||||
|
||||
if _, err := os.Stat(physicalPath); os.IsNotExist(err) {
|
||||
os.MkdirAll(physicalPath, 0755)
|
||||
@ -345,7 +345,7 @@ func (Screenshot) Delete(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
path := doc["SavePath"].(string)
|
||||
physicalPath := helper.MapPath(path)
|
||||
physicalPath := server.MapPath(path)
|
||||
os.RemoveAll(physicalPath)
|
||||
|
||||
db.DeleteOne(server.ScreenshotCollectionName, filter)
|
||||
|
||||
@ -12,8 +12,6 @@ import (
|
||||
"net/http"
|
||||
|
||||
"github.com/urfave/negroni"
|
||||
|
||||
"github.com/tengge1/shadoweditor/server/middleware"
|
||||
)
|
||||
|
||||
// Start start the server
|
||||
@ -21,9 +19,9 @@ func Start() {
|
||||
log.Printf("starting shadoweditor server on port %v", Config.Server.Port)
|
||||
|
||||
handler := negroni.Classic()
|
||||
handler.Use(negroni.HandlerFunc(middleware.CrossOriginHandler))
|
||||
handler.Use(negroni.HandlerFunc(middleware.GZipHandler))
|
||||
// handler.Use(negroni.HandlerFunc(middleware.StaticHandler))
|
||||
handler.Use(negroni.HandlerFunc(CrossOriginHandler))
|
||||
handler.Use(negroni.HandlerFunc(GZipHandler))
|
||||
handler.Use(negroni.HandlerFunc(StaticHandler))
|
||||
handler.UseHandler(Mux)
|
||||
|
||||
err := http.ListenAndServe(Config.Server.Port, handler)
|
||||
|
||||
@ -183,7 +183,7 @@ func (Texture) Add(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
|
||||
savePath := fmt.Sprintf("/Upload/Texture/%v", helper.TimeToString(now, "yyyyMMddHHmmss"))
|
||||
physicalPath := helper.MapPath(savePath)
|
||||
physicalPath := server.MapPath(savePath)
|
||||
|
||||
if _, err := os.Stat(physicalPath); os.IsNotExist(err) {
|
||||
os.MkdirAll(physicalPath, 0755)
|
||||
@ -406,7 +406,7 @@ func (Texture) Delete(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// 删除纹理所在目录
|
||||
path := doc["SavePath"].(string)
|
||||
physicalPath := helper.MapPath(path)
|
||||
physicalPath := server.MapPath(path)
|
||||
|
||||
err = os.RemoveAll(physicalPath)
|
||||
if err != nil {
|
||||
|
||||
@ -67,7 +67,7 @@ func (Upload) Upload(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
|
||||
savePath := fmt.Sprintf("/Upload/File/%v", helper.TimeToString(now, "yyyyMMddHHmmss"))
|
||||
physicalPath := helper.MapPath(savePath)
|
||||
physicalPath := server.MapPath(savePath)
|
||||
|
||||
if _, err := os.Stat(physicalPath); os.IsNotExist(err) {
|
||||
os.MkdirAll(physicalPath, 0755)
|
||||
|
||||
@ -167,7 +167,7 @@ func (Video) Add(w http.ResponseWriter, r *http.Request) {
|
||||
now := time.Now()
|
||||
|
||||
savePath := fmt.Sprintf("/Upload/Video/%v", helper.TimeToString(now, "yyyyMMddHHmmss"))
|
||||
physicalPath := helper.MapPath(savePath)
|
||||
physicalPath := server.MapPath(savePath)
|
||||
|
||||
if _, err := os.Stat(physicalPath); os.IsNotExist(err) {
|
||||
os.MkdirAll(physicalPath, 0755)
|
||||
@ -343,7 +343,7 @@ func (Video) Delete(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
path := doc["SavePath"].(string)
|
||||
physicalPath := helper.MapPath(path)
|
||||
physicalPath := server.MapPath(path)
|
||||
os.RemoveAll(physicalPath)
|
||||
|
||||
db.DeleteOne(server.VideoCollectionName, filter)
|
||||
|
||||
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||
@ -15,7 +16,7 @@ func main() {
|
||||
{Key: "hello", Value: "world"},
|
||||
}
|
||||
|
||||
jsoniter.RegisterTypeEncoder("go.mongodb.org/mongo-driver/bson/primitive.D", PrimitiveDEncoder{})
|
||||
jsoniter.RegisterTypeEncoder(reflect.TypeOf(primitive.D{}).String(), PrimitiveDEncoder{})
|
||||
|
||||
bytes, err := jsoniter.Marshal(data)
|
||||
if err != nil {
|
||||
|
||||
10
server/test/system/check_type.go
Normal file
10
server/test/system/check_type.go
Normal file
@ -0,0 +1,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println(runtime.GOOS)
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user