From b96c7ada7a74ffaae314a5d023464c58da102805 Mon Sep 17 00:00:00 2001 From: bdnugget Date: Sat, 18 Jan 2025 23:23:03 +0100 Subject: [PATCH] Menu with broken exit and settings --- game/game.go | 35 ++++++++++++++++++++++++++++++++++- go.mod | 4 ++-- go.sum | 16 ++-------------- goonserver | 2 +- network/network.go | 18 ++++++++++++++++++ types/types.go | 3 ++- 6 files changed, 59 insertions(+), 19 deletions(-) diff --git a/game/game.go b/game/game.go index 270ea19..b46441e 100644 --- a/game/game.go +++ b/game/game.go @@ -18,6 +18,7 @@ type Game struct { Chat *Chat MenuOpen bool QuitChan chan struct{} // Channel to signal shutdown + QuitDone chan struct{} // New channel to signal when cleanup is complete } func New() *Game { @@ -29,6 +30,7 @@ func New() *Game { Speed: 50.0, TargetPath: []types.Tile{}, UserData: nil, + QuitDone: make(chan struct{}), }, OtherPlayers: make(map[int32]*types.Player), Camera: rl.Camera3D{ @@ -40,6 +42,7 @@ func New() *Game { }, Chat: NewChat(), QuitChan: make(chan struct{}), + QuitDone: make(chan struct{}), } game.Player.UserData = game game.Chat.userData = game @@ -182,6 +185,35 @@ func (g *Game) Render() { } rl.EndMode3D() + // Draw floating messages + drawFloatingMessage := func(msg *types.FloatingMessage) { + if msg == nil || time.Now().After(msg.ExpireTime) { + return + } + pos := msg.ScreenPos + text := msg.Content + textWidth := rl.MeasureText(text, 20) + + for offsetX := -2; offsetX <= 2; offsetX++ { + for offsetY := -2; offsetY <= 2; offsetY++ { + rl.DrawText(text, + int32(pos.X)-textWidth/2+int32(offsetX), + int32(pos.Y)+int32(offsetY), + 20, + rl.Black) + } + } + rl.DrawText(text, int32(pos.X)-textWidth/2, int32(pos.Y), 20, rl.Yellow) + } + + if g.Player.FloatingMessage != nil { + drawFloatingMessage(g.Player.FloatingMessage) + } + + for _, other := range g.OtherPlayers { + drawFloatingMessage(other.FloatingMessage) + } + // Draw menu if open if g.MenuOpen { g.DrawMenu() @@ -261,7 +293,8 @@ func (g *Game) DrawMenu() { case "Settings": // TODO: Implement settings case "Exit Game": - close(g.QuitChan) // Signal all goroutines to shut down + close(g.QuitChan) + <-g.QuitDone rl.CloseWindow() } } diff --git a/go.mod b/go.mod index 53e5898..285c671 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.23.0 require ( gitea.boner.be/bdnugget/goonserver v0.0.0-20250113131525-49e23114973c github.com/gen2brain/raylib-go/raylib v0.0.0-20250109172833-6dbba4f81a9b - google.golang.org/protobuf v1.36.2 + google.golang.org/protobuf v1.36.3 ) require ( @@ -14,4 +14,4 @@ require ( golang.org/x/sys v0.29.0 // indirect ) -// replace gitea.boner.be/bdnugget/goonserver => ./goonserver +replace gitea.boner.be/bdnugget/goonserver => ./goonserver diff --git a/go.sum b/go.sum index 4152fb6..c8e48ea 100644 --- a/go.sum +++ b/go.sum @@ -1,24 +1,12 @@ -gitea.boner.be/bdnugget/goonserver v0.0.0-20250113131525-49e23114973c h1:TO14y5QeQXn6sLCv6vORVdjnMn5hP/Vd+60UjqcrtFA= -gitea.boner.be/bdnugget/goonserver v0.0.0-20250113131525-49e23114973c/go.mod h1:inR1bKrr/vcTba+G1KzmmY6vssMq9oGNOk836VwPa4c= -github.com/ebitengine/purego v0.8.0 h1:JbqvnEzRvPpxhCJzJJ2y0RbiZ8nyjccVUrSM3q+GvvE= -github.com/ebitengine/purego v0.8.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/ebitengine/purego v0.8.2 h1:jPPGWs2sZ1UgOSgD2bClL0MJIqu58nOmIcBuXr62z1I= github.com/ebitengine/purego v0.8.2/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= -github.com/gen2brain/raylib-go/raylib v0.0.0-20240930075631-c66f9e2942fe h1:mInjrbJkUglTM7tBmXG+epnPCE744aj15J7vjJwM4gs= -github.com/gen2brain/raylib-go/raylib v0.0.0-20240930075631-c66f9e2942fe/go.mod h1:BaY76bZk7nw1/kVOSQObPY1v1iwVE1KHAGMfvI6oK1Q= github.com/gen2brain/raylib-go/raylib v0.0.0-20250109172833-6dbba4f81a9b h1:JJfspevP3YOXcSKVABizYOv++yMpTJIdPUtoDzF/RWw= github.com/gen2brain/raylib-go/raylib v0.0.0-20250109172833-6dbba4f81a9b/go.mod h1:BaY76bZk7nw1/kVOSQObPY1v1iwVE1KHAGMfvI6oK1Q= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= -golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= -google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= -google.golang.org/protobuf v1.36.2 h1:R8FeyR1/eLmkutZOM5CWghmo5itiG9z0ktFlTVLuTmU= -google.golang.org/protobuf v1.36.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.3 h1:82DV7MYdb8anAVi3qge1wSnMDrnKK7ebr+I0hHRN1BU= +google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= diff --git a/goonserver b/goonserver index b73d8de..b44cdab 160000 --- a/goonserver +++ b/goonserver @@ -1 +1 @@ -Subproject commit b73d8de85149e8f6d6fe1e8d69562a0a26f7df23 +Subproject commit b44cdab6114914ba2bd66049541447d3dd1f9fcb diff --git a/network/network.go b/network/network.go index 65779ba..feb8f4b 100644 --- a/network/network.go +++ b/network/network.go @@ -61,11 +61,26 @@ func HandleServerCommunication(conn net.Conn, playerID int32, player *types.Play actionTicker := time.NewTicker(types.ClientTickRate) defer actionTicker.Stop() + defer conn.Close() + defer close(player.QuitDone) + + // Create a channel to signal when goroutines are done + done := make(chan struct{}) go func() { for { select { case <-quitChan: + // Send disconnect message to server + disconnectMsg := &pb.ActionBatch{ + PlayerId: playerID, + Actions: []*pb.Action{{ + Type: pb.Action_DISCONNECT, + PlayerId: playerID, + }}, + } + writeMessage(conn, disconnectMsg) + done <- struct{}{} return case <-actionTicker.C: player.Lock() @@ -96,6 +111,9 @@ func HandleServerCommunication(conn net.Conn, playerID int32, player *types.Play for { select { case <-quitChan: + <-done // Wait for action goroutine to finish + close(done) + time.Sleep(100 * time.Millisecond) // Give time for disconnect message to be sent return default: // Read message length (4 bytes) diff --git a/types/types.go b/types/types.go index 6062703..c47a0c4 100644 --- a/types/types.go +++ b/types/types.go @@ -27,8 +27,9 @@ type Player struct { CurrentTick int64 LastUpdateTime time.Time InterpolationProgress float32 - UserData interface{} // Used to store reference to game + UserData interface{} FloatingMessage *FloatingMessage + QuitDone chan struct{} } type ModelAsset struct {