Parcourir la source

deadlock bug fix

jstzwj il y a 6 ans
Parent
commit
5f30cf6bdd

+ 4 - 2
src/MineCase.Server.Grains/World/ChunkColumnGrain.cs

@@ -242,9 +242,11 @@ namespace MineCase.Server.World
 
 
             (var worldKey, var chunkPos) = this.GetWorldAndChunkWorldPos();
             (var worldKey, var chunkPos) = this.GetWorldAndChunkWorldPos();
             var world = GrainFactory.GetGrain<IWorld>(worldKey);
             var world = GrainFactory.GetGrain<IWorld>(worldKey);
-            for (int xOffset = -2; xOffset <= 2; ++xOffset)
+
+            int range = 1;
+            for (int xOffset = -range; xOffset <= range; ++xOffset)
             {
             {
-                for (int zOffset = -2; zOffset <= 2; ++zOffset)
+                for (int zOffset = -range; zOffset <= range; ++zOffset)
                 {
                 {
                     var curChunkPos = new ChunkWorldPos(chunkPos.X + xOffset, chunkPos.Z + zOffset);
                     var curChunkPos = new ChunkWorldPos(chunkPos.X + xOffset, chunkPos.Z + zOffset);
                     var chunkColumnKey = world.MakeAddressByPartitionKey(curChunkPos);
                     var chunkColumnKey = world.MakeAddressByPartitionKey(curChunkPos);

+ 33 - 8
src/MineCase.Server.Grains/World/Decoration/Mine/MinableGeneratorGrain.cs

@@ -12,6 +12,35 @@ namespace MineCase.Server.World.Decoration.Mine
     [StatelessWorker]
     [StatelessWorker]
     public class MinableGeneratorGrain : Grain, IMinableGenerator
     public class MinableGeneratorGrain : Grain, IMinableGenerator
     {
     {
+        protected Task SetBlock(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState state)
+        {
+            var chunkColumnKey = world.MakeAddressByPartitionKey(pos.ToChunkWorldPos());
+            var chunkGrain = GrainFactory.GetGrain<IChunkColumn>(chunkColumnKey);
+
+            BlockChunkPos blockChunkPos = pos.ToBlockChunkPos();
+            return chunkGrain.SetBlockStateUnsafe(blockChunkPos.X, blockChunkPos.Y, blockChunkPos.Z, state);
+        }
+
+        protected Task<BlockState> GetBlock(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos)
+        {
+            var chunkColumnKey = world.MakeAddressByPartitionKey(pos.ToChunkWorldPos());
+            var chunkGrain = GrainFactory.GetGrain<IChunkColumn>(chunkColumnKey);
+            BlockChunkPos blockChunkPos = pos.ToBlockChunkPos();
+
+            return chunkGrain.GetBlockStateUnsafe(blockChunkPos.X, blockChunkPos.Y, blockChunkPos.Z);
+        }
+
+        protected async Task SetIfStone(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState state)
+        {
+            if (pos.Y >= 0 &&
+                pos.Y < 255 &&
+                (await GetBlock(world, chunkWorldPos, pos)) == BlockStates.Stone())
+            {
+                // replace as ore
+                await SetBlock(world, chunkWorldPos, pos, state);
+            }
+        }
+
         public async Task Generate(IWorld world, ChunkWorldPos chunkWorldPos, BlockState blockState, int count, int size, int minHeight, int maxHeight)
         public async Task Generate(IWorld world, ChunkWorldPos chunkWorldPos, BlockState blockState, int count, int size, int minHeight, int maxHeight)
         {
         {
             int seed = await world.GetSeed();
             int seed = await world.GetSeed();
@@ -35,6 +64,7 @@ namespace MineCase.Server.World.Decoration.Mine
                     --minHeight;
                     --minHeight;
             }
             }
 
 
+            // List<Task> genTasks = new List<Task>();
             for (int j = 0; j < count; ++j)
             for (int j = 0; j < count; ++j)
             {
             {
                 BlockWorldPos blockpos = BlockWorldPos.Add(
                 BlockWorldPos blockpos = BlockWorldPos.Add(
@@ -44,6 +74,8 @@ namespace MineCase.Server.World.Decoration.Mine
                     random.Next(16));
                     random.Next(16));
                 await GenerateSingle(world, chunkWorldPos, blockpos, blockState, size);
                 await GenerateSingle(world, chunkWorldPos, blockpos, blockState, size);
             }
             }
+
+            // await Task.WhenAll(genTasks);
         }
         }
 
 
         public async Task GenerateSingle(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState state, int size)
         public async Task GenerateSingle(IWorld world, ChunkWorldPos chunkWorldPos, BlockWorldPos pos, BlockState state, int size)
@@ -114,14 +146,7 @@ namespace MineCase.Server.World.Decoration.Mine
                                     // 参考椭球方程
                                     // 参考椭球方程
                                     if (xDist * xDist + yDist * yDist + zDist * zDist < 1.0D)
                                     if (xDist * xDist + yDist * yDist + zDist * zDist < 1.0D)
                                     {
                                     {
-                                        BlockWorldPos blockpos = new BlockWorldPos(x, y, z);
-                                        if (blockpos.Y >= 0 &&
-                                            blockpos.Y < 255 &&
-                                            (await world.GetBlockState(this.GrainFactory, blockpos)) == BlockStates.Stone())
-                                        {
-                                            // 替换为矿石
-                                            await world.SetBlockState(this.GrainFactory, blockpos, state);
-                                        }
+                                        await SetIfStone(world, chunkWorldPos, new BlockWorldPos(x, y, z), state);
                                     }
                                     }
                                 }
                                 }
                             }
                             }