예제 #1
0
 public static bool IsPlaceable <TForeground, TBackground>
     (PlaceSendMessage p, IReadOnlyWorld <TForeground, TBackground> world)
     where TForeground : struct
     where TBackground : struct
 {
     return(p.X >= 0 && p.Y >= 0 && p.X < world.Width && p.Y < world.Height);
 }
예제 #2
0
        public static bool IsPlaceable <TForeground, TBackground>
            (PlaceSendMessage p, IWorld <TForeground, TBackground> world, bool respectBorder)
            where TForeground : struct
            where TBackground : struct
        {
            if (p.X < 0 || p.Y < 0 || p.X >= world.Width || p.Y >= world.Height)
            {
                return(false);                                                                 // If out of range
            }
            if (!respectBorder)
            {
                return(true);
            }
            if (p.X == 0 || p.Y == 0 || p.X == world.Width - 1 || p.Y == world.Height - 1) // If on border
            {
                if (p.Layer == Layer.Background)
                {
                    return(false);
                }

                return(IsBorderPlaceable((Foreground.Id)p.Id));
            }

            return(true);
        }
예제 #3
0
        private bool ShouldSend(PlaceSendMessage b, Point3D p)
        {
            if (b.SendCount > 15)
            {
                return(false);
            }
            if (b.NoChecks)
            {
                return(true);
            }
            if (this._room.AccessRight < AccessRight.Edit)
            {
                return(false);
            }

            // TODO: Count blocks
            var isAdministrator = this._connectionManager.PlayerObject.IsAdministrator;
            var isClubMember    = this._connectionManager.PlayerObject.ClubMember;

            if (!WorldUtils.IsPlaceable(b, this._world, !isAdministrator))
            {
                return(false);
            }
            if (!this._connectionManager.ShopData.HasBlock(b.Id, 0, isClubMember, isAdministrator))
            {
                return(false);
            }

            CheckHandle handle;

            return(!(this._sentLocations.TryGetValue(p, out handle)
                ? WorldUtils.AreSame(b, handle.Message)
                : WorldUtils.IsAlreadyPlaced(b, this._world)));
        }
예제 #4
0
        private bool ShouldSend(PlaceSendMessage b, Point3D p)
        {
            if (b.SendCount > 10)
            {
                return(false);
            }
            if (b.NoChecks)
            {
                return(true);
            }
            if (!Actions.Of(this.BotBits).CanEdit)
            {
                return(false);
            }

            var playerData      = ConnectionManager.Of(this.BotBits).PlayerData;
            var blocks          = Blocks.Of(this.BotBits);
            var isAdministrator = playerData.PlayerObject.IsAdministrator;

            if (!WorldUtils.IsPlaceable(b, blocks, !isAdministrator))
            {
                return(false);
            }
            if (!playerData.HasBlock(b.Id))
            {
                return(false);
            }

            CheckHandle handle;

            return(!(this._sentLocations.TryGetValue(p, out handle)
                ? WorldUtils.AreSame(b, handle.Message)
                : WorldUtils.IsAlreadyPlaced(b, blocks)));
        }
예제 #5
0
 private void BlockChecker_InitializeFinish(object sender, EventArgs e)
 {
     this._connectionManager = ConnectionManager.Of(this.BotBits);
     this._room                  = Room.Of(this.BotBits);
     this._world                 = Blocks.Of(this.BotBits);
     this._messageQueue          = PlaceSendMessage.Of(this.BotBits);
     this._messageQueue.Sending += this.OnSendingPlace;
     this._messageQueue.Send    += this.OnSendPlace;
 }
예제 #6
0
        public static bool IsAlreadyPlaced(PlaceSendMessage sent, Blocks world)
        {
            switch (sent.Layer)
            {
            case Layer.Foreground:
                var fg = world.Foreground[sent.X, sent.Y];
                return(sent.Id == (int)fg.Block.Id &&
                       sent.Args.SequenceEqual(fg.Block.GetArgs()));

            case Layer.Background:
                var bg = world.Background[sent.X, sent.Y];
                return(sent.Id == (int)bg.Block.Id);

            default:
                throw new NotSupportedException("Unknown layer.");
            }
        }
예제 #7
0
        internal static bool AreSame <T, TBlock>(PlaceSendMessage sent, T received)
            where T : PlaceEvent <T, TBlock>
            where TBlock : struct
        {
            var bg = received as BackgroundPlaceEvent;

            if (bg != null)
            {
                return(AreSame(sent, bg));
            }
            var fg = received as ForegroundPlaceEvent;

            if (fg != null)
            {
                return(AreSame(sent, fg));
            }

            throw new NotSupportedException("Unknown PlaceEvent.");
        }
예제 #8
0
        private async void OnScanRequest(ScanRequestEvent e)
        {
            var spots = EmptyMapSpots;

            if (spots.Count == 0)
            {
                new ScanResultEvent(false, "No empty slots left.").RaiseIn(BotBits);
                return;
            }

            List <Map> maps;

            try
            {
                maps =
                    await
                    new MapScanner(MapWidth, MapHeight).LoadMapsAsync(e.TargetWorldId, ScanSignFormat,
                                                                      MapPositionMapper);
            }
            catch (MapLoadException ex)
            {
                new ScanResultEvent(false, ex.Message).RaiseIn(BotBits);
                return;
            }

            if (maps.Count == 0)
            {
                new ScanResultEvent(false, "No maps found.").RaiseIn(BotBits);
                return;
            }

            var blocks     = Blocks.Of(BotBits);
            var spotNumber = 0;

            var numAccepted = 0;
            var numRejected = 0;

            var result = ReviewResult.Rejected;

            foreach (var map in maps)
            {
                spots[spotNumber].AddMap(blocks, map);

                await PlaceSendMessage.Of(BotBits).FinishQueueAsync();

                await BlockChecker.Of(BotBits).FinishChecksAsync();

                reviewResult       = new TaskCompletionSource <ReviewResult>();
                waitingForResponse = true;
                new MapForReviewEvent(map.Name, map.Creators, numAccepted + numRejected + 1, maps.Count).RaiseIn(BotBits);

                result = await reviewResult.Task;

                waitingForResponse = false;

                switch (result)
                {
                case ReviewResult.Accepted:
                {
                    numAccepted++;
                    spotNumber++;

                    if (spotNumber < spots.Count)
                    {
                        continue;
                    }

                    new ScanResultEvent(false,
                                        "Scan not finished completely. Ran out of free spots.",
                                        numAccepted,
                                        numRejected).RaiseIn(BotBits);
                    return;
                }

                case ReviewResult.Rejected:
                {
                    numRejected++;
                    break;
                }

                case ReviewResult.Stopped:
                {
                    spots[spotNumber].Clear(blocks);

                    new ScanResultEvent(false,
                                        "Scan stopped.",
                                        numAccepted,
                                        numRejected).RaiseIn(BotBits);
                    return;
                }
                }
            }

            // Clear last map when rejected
            if (result == ReviewResult.Rejected)
            {
                spots[spotNumber].Clear(blocks);
            }

            new ScanResultEvent(true, "Scan succeeded.", numAccepted, numRejected).RaiseIn(BotBits);
        }
예제 #9
0
 internal static bool AreSame(PlaceSendMessage b1, PlaceSendMessage b2)
 {
     return(b1.Id == b2.Id && b1.Args.SequenceEqual(b2.Args));
 }
예제 #10
0
 internal static bool AreSame(PlaceSendMessage sent, BackgroundPlaceEvent received)
 {
     return(sent.Id == (int)received.New.Block.Id);
 }
예제 #11
0
 internal static bool AreSame(PlaceSendMessage sent, ForegroundPlaceEvent received)
 {
     return(sent.Id == (int)received.New.Block.Id &&
            sent.Args.SequenceEqual(received.New.Block.GetArgs()));
 }
예제 #12
0
 public CheckHandle(PlaceSendMessage message, int overwrittenSends)
 {
     this.Message          = message;
     this.OverwrittenSends = overwrittenSends;
 }
예제 #13
0
 public static Point3D GetPoint3D(this PlaceSendMessage placeSendMessage)
 {
     return(new Point3D(placeSendMessage.Layer, placeSendMessage.X, placeSendMessage.Y));
 }
예제 #14
0
 private void BlockChecker_InitializeFinish(object sender, EventArgs e)
 {
     this._messageQueue = PlaceSendMessage.Of(this.BotBits);
 }
예제 #15
0
 private static Point3D GetPoint3D(PlaceSendMessage placeSendMessage)
 {
     return(new Point3D(placeSendMessage.Layer, placeSendMessage.X, placeSendMessage.Y));
 }
예제 #16
0
        private void RemoveFromSendQueue(PlaceSendMessage message)
        {
            var key = new Point3D(message.Layer, message.X, message.Y);

            this._queuedItems.TryRemove(key, message);
        }