示例#1
0
        private void Run()
        {
            EriverProtocol prot = new EriverProtocol();

            // Sending name first according to spec.
            prot.Kind       = Command.Name;
            prot.Name       = new Name();
            prot.Name.Value = name;
            Send(prot);

            while (!shutdown.WaitOne(0) && !stop.WaitOne(0))
            {
                try
                {
                    prot = readerWriter.Read();
                    using (log4net.ThreadContext.Stacks["NDC"].Push("ConnHandler_Handlers"))
                    {
                        var m = ConnHandler_Handlers.Messages[CommandConvert.ToByte(prot.Kind)]();
                        logger.Debug("Read packet: " + prot);
                        m.Accept(this, prot);
                    }
                }
                catch (InvalidOperationException e)
                {
                    using (log4net.ThreadContext.Stacks["NDC"].Push("InvalidOperationException"))
                    {
                        stop.Set();
                        logger.Error("Error in stream.");
                        logger.Debug(e);
                    }
                }
            }
        }
 public Task <IActionResult> Get(long id)
 {
     return(SelectOr404 <Scaffold.Command>(
                q => q.Where(c => c.CommandId == id).FromWorld(CurrentWorldId),
                c => CommandConvert.ModelToJson(c)
                ));
 }
示例#3
0
        public void TransformFromNameProtocolTest()
        {
            Command        underTest = Command.Name;
            EriverProtocol ep        = CreateTestProtocol(underTest);

            byte[] ans = EriverStreamReaderWriter.Transform(ep);

            Assert.AreEqual <int>(CommandConvert.ToLength(underTest) + 1, ans.Length);
            CollectionAssert.AreEqual(new byte[] { (byte)underTest, 0x21 }, ans);
        }
示例#4
0
        public void TransformFromStartCalProtocolTest()
        {
            Command        underTest = Command.StartCalibration;
            EriverProtocol ep        = CreateTestProtocol(underTest);

            byte[] ans = EriverStreamReaderWriter.Transform(ep);

            Assert.AreEqual <int>(CommandConvert.ToLength(underTest) + 1, ans.Length);
            CollectionAssert.AreEqual(new byte[] { (byte)underTest,
                                                   0x40, 0x2A, 0xBD, 0x70, 0xA3, 0xD7, 0x0A, 0x3D }, ans);
        }
示例#5
0
        public void TransformFromAddPointProtocolTest()
        {
            Command        underTest = Command.AddPoint;
            EriverProtocol ep        = CreateTestProtocol(Command.AddPoint);

            byte[] ans = EriverStreamReaderWriter.Transform(ep);

            Assert.AreEqual <int>(CommandConvert.ToLength(underTest) + 1, ans.Length);
            CollectionAssert.AreEqual(new byte[] { (byte)underTest,
                                                   0x3F, 0xDB, 0x95, 0x81, 0x06, 0x24, 0xDD, 0x2F,
                                                   0x3F, 0xD4, 0x18, 0x93, 0x74, 0xBC, 0x6A, 0x7F }, ans);
        }
        public async Task <IActionResult> Post([FromBody] JSON.ManyCommands jsonCommands)
        {
            if (ModelState.IsValid)
            {
                var mappedCommands = jsonCommands.Commands.ToDictionary(c => c.CommandId, c => c);
                var commandIds     = jsonCommands.Commands.Select(c => c.CommandId).ToList();

                var allVillageIds = jsonCommands.Commands
                                    .Select(c => c.SourceVillageId)
                                    .Concat(jsonCommands.Commands.Select(c => c.TargetVillageId))
                                    .Select(id => id.Value)
                                    .Distinct();

                var allCurrentVillageIds = await CurrentSets.CurrentVillage.Where(v => allVillageIds.Contains(v.VillageId)).Select(v => v.VillageId).ToListAsync();

                var allVillagesMissingCurrentEntries = allVillageIds.Except(allCurrentVillageIds).ToList();
                if (allVillagesMissingCurrentEntries.Count > 0)
                {
                    foreach (var id in allVillagesMissingCurrentEntries)
                    {
                        context.Add(new CurrentVillage
                        {
                            VillageId     = id,
                            AccessGroupId = CurrentAccessGroupId,
                            WorldId       = CurrentWorldId
                        });
                    }

                    await context.SaveChangesAsync();
                }

                var villageIdsFromCommandsMissingTroopType = jsonCommands.Commands
                                                             .Where(c => c.TroopType == null)
                                                             .SelectMany(c => new[] { c.SourceVillageId, c.TargetVillageId })
                                                             .Distinct()
                                                             .ToList();

                var scaffoldCommands = await Profile("Get existing commands", () => (
                                                         from command in CurrentSets.Command.IncludeCommandData()
                                                         where commandIds.Contains(command.CommandId)
                                                         select command
                                                         ).ToListAsync());

                var villageIdsFromCommandsMissingTroopTypes = await Profile("Get villages for commands missing troop type", () => (
                                                                                from village in CurrentSets.Village
                                                                                where villageIdsFromCommandsMissingTroopType.Contains(village.VillageId)
                                                                                select village
                                                                                ).ToListAsync());

                var allVillages = await Profile("Get all relevant villages", () => (
                                                    from village in CurrentSets.Village
                                                    where allVillageIds.Contains(village.VillageId)
                                                    select village
                                                    ).ToListAsync());

                var mappedScaffoldCommands = scaffoldCommands.ToDictionary(c => c.CommandId, c => c);
                var villagesById           = allVillages.ToDictionary(v => v.VillageId, v => v);

                var tx = BuildTransaction();
                context.Transaction.Add(tx);

                Profile("Generate scaffold commands", () =>
                {
                    foreach (var jsonCommand in jsonCommands.Commands)
                    {
                        if (!Configuration.Security.AllowCommandArrivalBeforeServerTime &&
                            jsonCommand.LandsAt.HasValue &&
                            jsonCommand.LandsAt.Value < CurrentServerTime)
                        {
                            context.InvalidDataRecord.Add(MakeInvalidDataRecord(
                                                              JsonConvert.SerializeObject(jsonCommand),
                                                              "Command.landsAt is earlier than current server time"
                                                              ));
                            continue;
                        }

                        if (!Configuration.Security.ReportIgnoreExpectedPopulationBounds &&
                            !ArmyValidate.MeetsPopulationRestrictions(jsonCommand.Troops))
                        {
                            context.InvalidDataRecord.Add(MakeInvalidDataRecord(
                                                              JsonConvert.SerializeObject(jsonCommand),
                                                              "Troops in command exceed possible village population"
                                                              ));
                            continue;
                        }

                        var scaffoldCommand = mappedScaffoldCommands.GetValueOrDefault(jsonCommand.CommandId.Value);
                        //  Don't process/update commands that are already "complete" (have proper army data attached to them)
                        if (scaffoldCommand?.Army != null)
                        {
                            continue;
                        }

                        var travelCalculator = new Features.Simulation.TravelCalculator(CurrentWorldSettings.GameSpeed, CurrentWorldSettings.UnitSpeed);
                        var timeRemaining    = jsonCommand.LandsAt.Value - CurrentServerTime;
                        var sourceVillage    = villagesById[jsonCommand.SourceVillageId.Value];
                        var targetVillage    = villagesById[jsonCommand.TargetVillageId.Value];
                        var estimatedType    = travelCalculator.EstimateTroopType(timeRemaining, sourceVillage, targetVillage);

                        if (jsonCommand.TroopType == null)
                        {
                            jsonCommand.TroopType = estimatedType;
                        }
                        else
                        {
                            var estimatedTravelSpeed = Native.ArmyStats.TravelSpeed[estimatedType];
                            var reportedTravelSpeed  = Native.ArmyStats.TravelSpeed[jsonCommand.TroopType.Value];

                            //  ie if command is tagged as "spy" but travel speed is effective for
                            //  rams
                            if (estimatedTravelSpeed > reportedTravelSpeed)
                            {
                                jsonCommand.TroopType = estimatedType;
                            }
                        }

                        if (scaffoldCommand == null)
                        {
                            scaffoldCommand               = new Scaffold.Command();
                            scaffoldCommand.World         = CurrentWorld;
                            scaffoldCommand.AccessGroupId = CurrentAccessGroupId;
                            jsonCommand.ToModel(CurrentWorldId, CurrentAccessGroupId, scaffoldCommand, CurrentServerTime, context);
                            context.Command.Add(scaffoldCommand);
                        }
                        else
                        {
                            var existingJsonCommand = CommandConvert.ModelToJson(scaffoldCommand);
                            if (existingJsonCommand.IsReturning == jsonCommand.IsReturning && existingJsonCommand != jsonCommand)
                            {
                                context.ConflictingDataRecord.Add(new Scaffold.ConflictingDataRecord
                                {
                                    OldTxId       = scaffoldCommand.TxId.Value,
                                    ConflictingTx = tx
                                });
                            }

                            jsonCommand.ToModel(CurrentWorldId, CurrentAccessGroupId, scaffoldCommand, CurrentServerTime, context);
                        }

                        if (String.IsNullOrWhiteSpace(scaffoldCommand.UserLabel) || scaffoldCommand.UserLabel == "Attack")
                        {
                            scaffoldCommand.UserLabel = scaffoldCommand.TroopType.Capitalized();
                        }

                        if (jsonCommand.TroopType != null)
                        {
                            var travelTime            = travelCalculator.CalculateTravelTime(jsonCommand.TroopType.Value, sourceVillage, targetVillage);
                            scaffoldCommand.ReturnsAt = scaffoldCommand.LandsAt + travelTime;
                        }

                        scaffoldCommand.Tx = tx;
                    }
                });

                await Profile("Save changes", () => context.SaveChangesAsync());

                //  Run upload history update in separate query to prevent creating multiple history
                //  entries
                var userUploadHistory = await EFUtil.GetOrCreateUserUploadHistory(context, CurrentUserId);

                if (jsonCommands.IsOwnCommands.Value)
                {
                    userUploadHistory.LastUploadedCommandsAt = CurrentServerTime;
                }
                else
                {
                    userUploadHistory.LastUploadedIncomingsAt = CurrentServerTime;
                }

                await context.SaveChangesAsync();

                return(Ok());
            }
            else
            {
                return(BadRequest(ModelState));
            }
        }