From 61f962529744df3a76df4b09e3dac6feaac29bef Mon Sep 17 00:00:00 2001 From: Tnze Date: Fri, 27 May 2022 10:37:10 +0800 Subject: [PATCH] fix data race --- examples/frameworkServer/main.go | 2 +- .../58f6356e-b30c-4811-8bfc-d72a9ee99e73.dat | Bin 688 -> 690 bytes server/gameplay.go | 10 ++++++++-- server/player/player.go | 16 +++++++++++++++- 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/examples/frameworkServer/main.go b/examples/frameworkServer/main.go index f91cdf7..5e1df37 100644 --- a/examples/frameworkServer/main.go +++ b/examples/frameworkServer/main.go @@ -18,7 +18,7 @@ import ( ) var motd = chat.Message{Text: "A Minecraft Server ", Extra: []chat.Message{{Text: "Powered by go-mc", Color: "yellow"}}} -var addr = flag.String("Address", ":25565", "Listening address") +var addr = flag.String("Address", "127.0.0.1:25565", "Listening address") var iconPath = flag.String("ServerIcon", "./server-icon.png", "The path to server icon") var maxPlayer = flag.Int("MaxPlayer", 16384, "The maximum number of players") var regionPath = flag.String("Regions", "./save/testdata/region/", "The region files") diff --git a/save/testdata/playerdata/58f6356e-b30c-4811-8bfc-d72a9ee99e73.dat b/save/testdata/playerdata/58f6356e-b30c-4811-8bfc-d72a9ee99e73.dat index 4ac425e444f4e4682dfb8e0a20836ff7a24466c9..555c98c51bd7d6231a780e531f9bbc897e892d9f 100644 GIT binary patch delta 397 zcmV;80doGZ1+oPQABzY8HlvVYu?R5%e-IB>9Js?xD44MX*2%SGF?P7HR1Uef?20qu zILA$tssZZNoNs0*>1vUiOI&@JwJJm+kO@{`GD@-ts&j@7s_?LK13d!FQ2Y?r|)0i9ort%*N_Rj z-#T%|LSLyQVm8;zg>K*hilq}ry4vEpa-Vv>DOWX(QBrA;5YiwGIl{tZcxh(!q0%Dp zp|MS39FXVs;`GC#r{OdNLzzS9ds4I)#Yzt+!-wjYGDE^&ZlV{;imK3TGs|9~9+HFR!z%br+BoatNb1VleU_UGsbzwOTk3Ip r<|7msTTC2!B$O>P`m~6&m`WF;gtHE=%j3al?dkjl5VSf%Hv|9xNH)o3 delta 395 zcmV;60d)Sd1+WDOABzY800000u?R5%e;D^fDerI-3T7;Ub#g6Pj2$j4l|$|=yW)&E z&T$i^YJhq*=bITyx?1Gs5?3E)tqPF{WP%k`#WKx2IhXJg0H2$Qar46A()`!|qd5t^ zG3ItjB#npPMrQZjc(@U&?`9E}w5l+@n{^en&{<8W?d+_#>94l?>#_Vevv&2}fA4Si zj(;2*YV}ZzUZuh578#bBng&rWYfQK`q`Uq?xvtlT$fNV+(>3q({p-79+k^TVGGX^y zC(c;tE0sjd=9;Zw^4wmWet7gWoQ7a1a|m6EdG?}M>7fK4s$0qo34gs^5?tCI5&vF(r=Zs18vp$C zpt_rFl~KWpOi-^|Ov@>%LbJ^*dxd&P4w?_E;5%vKtcxS5D{uE%ZZ4#j2^wyx$L*Pq pP+)8^ap;jyw#?|$BGO_iU5paWI=C*62cxy8^A|Gtu~at%001-Fz)S!D diff --git a/server/gameplay.go b/server/gameplay.go index 260ac64..fa22546 100644 --- a/server/gameplay.go +++ b/server/gameplay.go @@ -3,6 +3,7 @@ package server import ( "context" _ "embed" + "sync" "time" "github.com/google/uuid" @@ -23,8 +24,9 @@ type GamePlay interface { type Game struct { *ecs.World *ecs.Dispatcher - handlers map[int32][]*PacketHandler - components []Component + WorldLocker sync.Mutex + handlers map[int32][]*PacketHandler + components []Component } type PacketHandler struct { @@ -68,7 +70,9 @@ func (g *Game) Run(ctx context.Context) { for { select { case <-ticker.C: + g.WorldLocker.Lock() g.Dispatcher.Run(g.World) + g.WorldLocker.Unlock() case <-ctx.Done(): return } @@ -76,6 +80,7 @@ func (g *Game) Run(ctx context.Context) { } func (g *Game) AcceptPlayer(name string, id uuid.UUID, protocol int32, conn *net.Conn) { + g.WorldLocker.Lock() eid := g.CreateEntity( Client{ Conn: conn, @@ -90,6 +95,7 @@ func (g *Game) AcceptPlayer(name string, id uuid.UUID, protocol int32, conn *net ) c := ecs.GetComponent[Client](g.World).GetValue(eid) p := ecs.GetComponent[Player](g.World).GetValue(eid) + g.WorldLocker.Unlock() defer c.packetQueue.Close() go func() { diff --git a/server/player/player.go b/server/player/player.go index 3136b47..55ab7d3 100644 --- a/server/player/player.go +++ b/server/player/player.go @@ -20,6 +20,7 @@ type playerSpawnSystem struct { func (p playerSpawnSystem) Update(w *ecs.World) { clients := ecs.GetComponent[server.Client](w) players := ecs.GetComponent[server.Player](w) + pos, rot := ecs.GetComponent[server.Pos](w), ecs.GetComponent[server.Rot](w) profiles := ecs.GetComponent[PlayerProfile](w) dimensionRes := ecs.GetResource[world.DimensionList](w) players.AndNot(profiles.BitSetLike).Range(func(eid ecs.Index) { @@ -35,6 +36,15 @@ func (p playerSpawnSystem) Update(w *ecs.World) { panic("dimension " + profile.Dimension + " not found") } profiles.SetValue(eid, PlayerProfile{Dim: dim}) + pos.SetValue(eid, server.Pos{ + X: profile.Pos[0], + Y: profile.Pos[1], + Z: profile.Pos[2], + }) + rot.SetValue(eid, server.Rot{ + Yaw: profile.Rotation[0], + Pitch: profile.Rotation[1], + }) client.WritePacket(server.Packet758(pk.Marshal( packetid.ClientboundLogin, pk.Int(eid), // Entity ID @@ -59,7 +69,11 @@ func (p playerSpawnSystem) Update(w *ecs.World) { func SpawnSystem(g *server.Game, playerdataPath string) { ecs.Register[PlayerProfile, *ecs.HashMapStorage[PlayerProfile]](g.World) - g.Dispatcher.Add(playerSpawnSystem{storage: storage{playerdataPath}}, "go-mc:player:SpawnSystem", nil) + g.Dispatcher.Add( + playerSpawnSystem{storage: storage{playerdataPath}}, + "go-mc:player:SpawnSystem", + nil, + ) } // PosAndRotSystem add a system to g.Dispatcher that