diff --git a/global/send.go b/global/send.go index 4dc9328..9660344 100644 --- a/global/send.go +++ b/global/send.go @@ -3,11 +3,9 @@ package global import "work_cation/models" type SendGlobal struct { - SendChan chan *models.Message - Game1Chan chan *models.GameMessage + SendChan chan *models.Message } var Send = &SendGlobal{ - SendChan: make(chan *models.Message, 1000), - Game1Chan: make(chan *models.GameMessage, 1000), + SendChan: make(chan *models.Message, 1000), } diff --git a/main.go b/main.go index f29ea7f..011ae27 100644 --- a/main.go +++ b/main.go @@ -36,11 +36,11 @@ func main() { func mainView(w fyne.Window) fyne.CanvasObject { service.Zeroconf.StartFindService() views.ListenChat() - views.StartGameListen() // 启动服务 if err := service.Server.StartListenServer(); err != nil { return widget.NewLabel(err.Error()) } + views.StartGameListen() var ( content = container.NewMax() a = fyne.CurrentApp() diff --git a/service/server.go b/service/server.go index ea6d6ca..1420622 100644 --- a/service/server.go +++ b/service/server.go @@ -16,9 +16,10 @@ import ( "work_cation/repo" ) -type serverService struct { +type ServerService struct { Status string server *http.Server + Router *gin.Engine } const ( @@ -26,9 +27,9 @@ const ( StatusOffline = "offline" ) -var Server = &serverService{Status: StatusOffline} +var Server = &ServerService{Status: StatusOffline} -func (s *serverService) Online() error { +func (s *ServerService) Online() error { if s.Status == StatusOnline { return nil } @@ -42,7 +43,7 @@ func (s *serverService) Online() error { return nil } -func (s *serverService) StatusOffline() error { +func (s *ServerService) StatusOffline() error { //if err := s.server.Close(); err != nil { // return err //} @@ -53,8 +54,9 @@ func (s *serverService) StatusOffline() error { return nil } -func (s *serverService) StartListenServer() error { +func (s *ServerService) StartListenServer() error { router := gin.Default() + s.Router = router router.GET("/user", func(c *gin.Context) { user := repo.User.GetUserInfo(global.DB) c.JSON(200, user) @@ -82,7 +84,7 @@ func (s *serverService) StartListenServer() error { }) router.POST("/chat", func(c *gin.Context) { - user, msg, is := publicPostCheck(c) + user, msg, is := PublicPostCheck(c) if !is { return } @@ -98,50 +100,6 @@ func (s *serverService) StartListenServer() error { 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, @@ -206,7 +164,7 @@ func zipFolder(folderPath string, zipFile io.Writer) error { return nil } -func publicPostCheck(c *gin.Context) (*models.UserFollows, map[string]interface{}, bool) { +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() { diff --git a/views/chatView.go b/views/chatView.go index a319a3b..efeb84b 100644 --- a/views/chatView.go +++ b/views/chatView.go @@ -7,10 +7,10 @@ import ( "fyne.io/fyne/v2/dialog" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" + "github.com/gin-gonic/gin" "time" "work_cation/global" "work_cation/models" - "work_cation/pkg/utils" "work_cation/repo" "work_cation/service" ) @@ -95,21 +95,35 @@ func OpenChat(user models.Users) { scroll.ScrollToBottom() } + online := &models.Online{ID: user.ID, Ip: user.Ip, Port: user.Port} // 分享 toolBar := widget.NewToolbar( widget.NewToolbarAction(theme.ContentAddIcon(), func() { dialog.ShowInformation("未开发", "分享脚本功能 尽请期待", w) }), widget.NewToolbarAction(theme.CancelIcon(), func() { w.Close() }), - widget.NewToolbarAction(theme.MailForwardIcon(), func() { - game := NewTenGame(nil) - online := &models.Online{ID: user.ID, Ip: user.Ip, Port: user.Port} - err := game.AddNet(utils.Uuid.CreateUUID(), 0, online, &user) - if err != nil { - dialog.ShowInformation("错误", err.Error(), w) - return + widget.NewToolbarAction(theme.WarningIcon(), func() { + var ilo *dialog.CustomDialog + box := container.NewVBox() + for _, item := range GameConfigList { + var itemCopy = item + box.Add(widget.NewButton(itemCopy.Name, func() { + req := gin.H{ + "name": itemCopy.Name, + "x": itemCopy.X, + "y": itemCopy.Y, + "win": itemCopy.Win} + _, err := service.PostSend("/send_game", online, req) + if err != nil { + dialog.ShowError(err, w) + } + ilo.Hide() + })) + } - game.StartShow() + ilo = dialog.NewCustomWithoutButtons("选择", box, w) + ilo.Show() + }), ) button := widget.NewButton("", submit) diff --git a/views/gamesViews.go b/views/gamesViews.go index fc951a1..423ee24 100644 --- a/views/gamesViews.go +++ b/views/gamesViews.go @@ -12,66 +12,115 @@ import ( "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" + "github.com/gin-gonic/gin" "image" "image/color" "image/draw" "image/png" + "net/http" "slices" "sync" "work_cation/global" "work_cation/models" + "work_cation/pkg/utils" "work_cation/service" ) +type GameConfig struct { + Name string + X int + Y int + Win int +} + +var GameConfigList = []GameConfig{ + {"3*3 井字棋", 3, 3, 3}, + {"10*10 五子棋", 10, 10, 5}, + {"19*19 五子棋", 19, 19, 5}, +} + func TenChinaGameView() { game := NewTenGame(nil) - //go func() { - // for { - // select { - // case <-game.Ctx.Done(): - // return - // case msg := <-global.Send.Game1Chan: - // game.play() - // } - // } - //}() - game.StartShow() + game.Show() } func StartGameListen() { - go func() { - for { - select { - case msg := <-global.Send.Game1Chan: - switch msg.Router { - case "/play_game": - g := global.GetGameInfo(msg.GameUuid) - if g != nil { - game := g.Obj.(*TenGame) - game.Play(game.userIndex, msg.Pos) - } - case "/close_game": - g := global.GetGameInfo(msg.GameUuid) - if g != nil { - dialog.NewConfirm("提示", "对方已退出", func(b bool) { - g.Obj.(*TenGame).w.Close() - }, g.Obj.(*TenGame).w).Show() - //dialog.ShowInformation("提示", "对方已退出", g.Obj.(*TenGame).w) - } - case "/start_game": - g := global.GetGameInfo(msg.GameUuid) - if g != nil { - fmt.Println("start_game") - continue - } - game := NewTenGame(nil) - online := &models.Online{ID: msg.User.ID, Ip: msg.User.Ip, Port: msg.User.Port} - game.AddNet(msg.GameUuid, 1, online, msg.User) - game.StartShow() - } - } + router := service.Server.Router + + // 推送游戏邀请 + service.Server.Router.POST("/send_game", func(c *gin.Context) { + user, msg, is := service.PublicPostCheck(c) + if !is { + return } - }() + w := fyne.CurrentApp().NewWindow("游戏邀请") + w.SetContent(container.NewVBox( + widget.NewLabel(fmt.Sprintf("%s向你发起了 %s 游戏邀请 ", user.Name, msg["name"])), + container.NewHBox( + widget.NewButton("同意", func() { + game := NewTenGame(nil) + game.itemX = float32(msg["x"].(float64)) + game.itemY = float32(msg["y"].(float64)) + game.winSum = int(msg["win"].(float64)) + online := &models.Online{ID: user.ID, Ip: user.Ip, Port: user.Port} + err := game.AddNet(utils.Uuid.CreateUUID(), 0, online, &user.Users) + if err != nil { + dialog.ShowInformation("错误", err.Error(), w) + return + } + game.Show() + w.Close() + }), + widget.NewButton("婉拒", w.Close), + ))) + w.CenterOnScreen() + w.RequestFocus() + w.Show() + c.JSON(http.StatusOK, gin.H{}) + }) + + // 开始游戏 + router.POST("/start_game", func(c *gin.Context) { + user, msg, is := service.PublicPostCheck(c) + if !is { + return + } + game := NewTenGame(nil) + game.itemX = float32(msg["x"].(float64)) + game.itemY = float32(msg["y"].(float64)) + game.winSum = int(msg["win"].(float64)) + online := &models.Online{ID: user.ID, Ip: user.Ip, Port: user.Port} + game.AddNet(utils.Uuid.CreateUUID(), 1, online, &user.Users) + game.Show() + c.JSON(200, gin.H{"message": "ok"}) + }) + router.POST("/play_game", func(c *gin.Context) { + _, msg, is := service.PublicPostCheck(c) + if !is { + return + } + g := global.GetGameInfo(msg["game_uuid"].(string)) + if g != nil { + game := g.Obj.(*TenGame) + game.Play(game.userIndex, int(msg["pos"].(float64))) + } + c.JSON(200, gin.H{"message": "ok"}) + }) + + router.POST("/close_game", func(c *gin.Context) { + _, msg, is := service.PublicPostCheck(c) + if !is { + return + } + g := global.GetGameInfo(msg["game_uuid"].(string)) + if g != nil { + dialog.NewConfirm("提示", "对方已退出", func(b bool) { + g.Obj.(*TenGame).w.Close() + }, g.Obj.(*TenGame).w).Show() + //dialog.ShowInformation("提示", "对方已退出", g.Obj.(*TenGame).w) + } + c.JSON(200, gin.H{"message": "ok"}) + }) } // 格子棋 Checkered-Chess @@ -123,9 +172,9 @@ func NewTenGame(winCallback func(int)) *TenGame { currentRoundPlayer: 0, players: make([][]int, len(playerImageMap)), winCallback: winCallback, - itemSize: fyne.NewSize(50, 50), - itemX: 10, - itemY: 10, + itemSize: fyne.NewSize(45, 45), + itemX: 19, + itemY: 19, winSum: 5, Ctx: ctx, Cancel: cancel, @@ -150,7 +199,14 @@ func (t *TenGame) AddNet(uuid string, myIndex int, online *models.Online, user * // 发起人 if myIndex == 0 { t.userIndex = 1 - _, err := service.Client.StartGame(t.online, t.uuid, global.GameType1) + req := gin.H{ + "type": global.GameType1, + "game_uuid": t.uuid, + "x": t.itemX, + "y": t.itemY, + "win": t.winSum, + } + _, err := service.PostSend("/start_game", online, req) if err != nil { t.isNet = false return err @@ -159,18 +215,12 @@ func (t *TenGame) AddNet(uuid string, myIndex int, online *models.Online, user * return nil } -func (t *TenGame) StartShow() { +func (t *TenGame) Show() { myApp := fyne.CurrentApp() - myWindow := myApp.NewWindow("") t.w = myWindow t.setTitle() - wSize := fyne.NewSize(t.itemX*(t.itemSize.Width), t.itemY*(t.itemSize.Height)) - myWindow.Resize(wSize) - myWindow.SetContent(container.New(layout.NewMaxLayout(), - canvas.NewImageFromResource(drawABackgroundImage(wSize, int(t.itemX), int(t.itemY))), - t.CanvasObject())) - + myWindow.SetContent(t.mainCanvasObject()) myWindow.SetOnClosed(func() { if t.isNet { global.DeleteGame(t.uuid) @@ -182,7 +232,16 @@ func (t *TenGame) StartShow() { myWindow.Show() } -func (t *TenGame) CanvasObject() fyne.CanvasObject { +// 主界面 +func (t *TenGame) mainCanvasObject() fyne.CanvasObject { + return container.NewBorder(nil, nil, nil, nil, t.chessCanvasObject()) +} + +// 棋盘界面 +func (t *TenGame) chessCanvasObject() fyne.CanvasObject { + // 计算大小 + wSize := fyne.NewSize(t.itemX*(t.itemSize.Width), t.itemY*(t.itemSize.Height)) + var items []fyne.CanvasObject for i := 0; i < int(t.itemX*t.itemY); i++ { @@ -202,14 +261,24 @@ func (t *TenGame) CanvasObject() fyne.CanvasObject { }) toggle.Resize(t.itemSize) - iViews := container.NewBorder(nil, nil, nil, nil, container.NewWithoutLayout(image, toggle)) + iViews := container.NewWithoutLayout(image, toggle) iViews.Resize(t.itemSize) //gridWrap.Add() items = append(items, iViews) } gridWrap := container.NewGridWithRows(int(t.itemX), items...) - return container.NewScroll(gridWrap) + scroll := container.NewScroll(gridWrap) + scroll.SetMinSize(wSize) + + // 绘制背景 + background := canvas.NewImageFromResource(drawABackgroundImage(wSize, int(t.itemX), int(t.itemY))) + background.SetMinSize(wSize) + + return container.New(layout.NewCenterLayout(), + background, + scroll, + ) } func (t *TenGame) Play(userIndex int, pos int) error {