Files
work_cation/service/server.go
T
2024-10-18 15:11:40 +08:00

220 lines
4.6 KiB
Go

package service
import (
"archive/zip"
"errors"
"fmt"
"github.com/gin-gonic/gin"
"io"
"log"
"net/http"
"os"
"path/filepath"
"work_cation/cfg"
"work_cation/global"
"work_cation/models"
"work_cation/repo"
)
type serverService struct {
Status string
server *http.Server
}
const (
StatusOnline = "online"
StatusOffline = "offline"
)
var Server = &serverService{Status: StatusOffline}
func (s *serverService) Online() error {
if s.Status == StatusOnline {
return nil
}
// 启动服务发现
user := repo.User.GetUserInfo(global.DB)
if err := Zeroconf.Register(user); err != nil {
return err
}
// 修改状态
s.Status = StatusOnline
return nil
}
func (s *serverService) StatusOffline() error {
//if err := s.server.Close(); err != nil {
// return err
//}
// 关闭服务发现
Zeroconf.Close()
// 修改状态
s.Status = StatusOffline
return nil
}
func (s *serverService) StartListenServer() error {
router := gin.Default()
router.GET("/user", func(c *gin.Context) {
user := repo.User.GetUserInfo(global.DB)
c.JSON(200, user)
})
router.GET("/cards", func(c *gin.Context) {
cards := repo.BaseCard.FindAll(global.DB)
c.JSON(200, cards)
})
router.GET("/download/card/:uuid", func(c *gin.Context) {
uuid := c.Param("uuid")
card := repo.BaseCard.Find(global.DB, uuid)
if card.UUID == "" {
c.JSON(404, nil)
return
}
cardPath := filepath.Join(cfg.T.CardDir, card.UUID)
// 设置响应头
c.Header("Content-Disposition", fmt.Sprintf("attachment; filename=%s.zip", uuid))
c.Header("Content-Type", "application/zip")
err := zipFolder(cardPath, c.Writer)
if err != nil {
c.JSON(500, err)
return
}
})
router.POST("/chat", func(c *gin.Context) {
user, msg, is := publicPostCheck(c)
if !is {
return
}
message := &models.Message{
Cmd: "chat",
User: *user,
ChatMessage: *models.NewTextChatMsg(&user.Users, msg["text"].(string)),
}
global.Send.SendChan <- message
c.JSON(200, gin.H{"message": "ok"})
})
// 开始游戏
router.POST("/start_game", func(c *gin.Context) {
user, msg, is := publicPostCheck(c)
if !is {
return
}
message := &models.GameMessage{
Router: "/start_game",
User: &user.Users,
GameType: int(msg["type"].(float64)),
GameUuid: msg["game_uuid"].(string),
}
global.Send.Game1Chan <- message
c.JSON(200, gin.H{"message": "ok"})
})
router.POST("/play_game", func(c *gin.Context) {
user, msg, is := publicPostCheck(c)
if !is {
return
}
message := &models.GameMessage{
Router: "/play_game",
User: &user.Users,
Pos: int(msg["pos"].(float64)),
GameUuid: msg["game_uuid"].(string),
}
global.Send.Game1Chan <- message
c.JSON(200, gin.H{"message": "ok"})
})
router.POST("/close_game", func(c *gin.Context) {
user, msg, is := publicPostCheck(c)
if !is {
return
}
message := &models.GameMessage{
Router: "/close_game",
User: &user.Users,
GameUuid: msg["game_uuid"].(string),
}
global.Send.Game1Chan <- message
c.JSON(200, gin.H{"message": "ok"})
})
srv := &http.Server{
Addr: cfg.T.ServerAddr,
Handler: router,
}
go func() {
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatalf("listen: %s\n", err)
}
}()
s.server = srv
return nil
}
func zipFolder(folderPath string, zipFile io.Writer) error {
zipWriter := zip.NewWriter(zipFile)
defer zipWriter.Close()
err := filepath.Walk(folderPath, func(filePath string, info os.FileInfo, err error) error {
if err != nil {
return err
}
header, err := zip.FileInfoHeader(info)
if err != nil {
return err
}
header.Name, err = filepath.Rel(folderPath, filePath)
if err != nil {
return err
}
if info.IsDir() {
header.Name += "/"
} else {
header.Method = zip.Deflate
}
writer, err := zipWriter.CreateHeader(header)
if err != nil {
return err
}
if !info.IsDir() {
file, err := os.Open(filePath)
if err != nil {
return err
}
defer file.Close()
_, err = io.Copy(writer, file)
if err != nil {
return err
}
}
return nil
})
if err != nil {
return err
}
return nil
}
func publicPostCheck(c *gin.Context) (*models.UserFollows, map[string]interface{}, bool) {
uuid := c.GetHeader("User-User")
user := repo.UserFollow.GetUser(global.DB, uuid)
if user.Ip != c.ClientIP() {
c.JSON(200, gin.H{"message": "对方未关注你"})
return nil, nil, false
}
var msg = make(map[string]interface{})
if err := c.ShouldBind(&msg); err != nil {
c.JSON(200, gin.H{"message": "输入异常"})
return nil, nil, false
}
return user, msg, true
}