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) )); }
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); }
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); }
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)); } }