Пример #1
0
        private void BuildPatch(PatchDefinition definition, BuildDefinition fromDefinition, BuildDefinition toDefinition)
        {
            var skipAmount = Math.Max(fromDefinition.Entries.Length, toDefinition.Entries.Length) - definition.Entries.Count;

            for (int i = 0; i < skipAmount; i++)
            {
                _context.ReportProgress(string.Format(_context.LocalizedMessages.PatchSkippingFile));
            }

            foreach (var entry in definition.Entries)
            {
                switch (entry.Operation)
                {
                case PatchOperation.Added:
                    _context.LogProgress(string.Format(_context.LocalizedMessages.PatchAddingFile, entry.RelativePath));
                    HandleAddedFile(entry);
                    _context.ReportProgress(string.Format(_context.LocalizedMessages.PatchAddedFile, entry.RelativePath));
                    break;

                case PatchOperation.Updated:
                    _context.LogProgress(string.Format(_context.LocalizedMessages.PatchPatchingFile, entry.RelativePath));
                    HandleUpdatedFile(entry);
                    _context.ReportProgress(string.Format(_context.LocalizedMessages.PatchPatchedFile, entry.RelativePath));
                    break;

                case PatchOperation.ChangedAttributes:
                    _context.LogProgress(string.Format(_context.LocalizedMessages.PatchChangingAttributesFile, entry.RelativePath));
                    HandleChangedAttributesFile(entry);
                    _context.ReportProgress(string.Format(_context.LocalizedMessages.PatchChangedAttributesFile, entry.RelativePath));
                    break;
                }
            }
        }
        public List <KnowledgeGroupRecord> UpdateKnowledgeGroups(
            IList <KnowledgeGroupRecord> importKnowledgeGroups,
            IKnowledgeGroupService service,
            ref int modifiedRecords
            )
        {
            var knowledgeGroupRecords = service.FindAllAsync().Result;

            var patch = new PatchDefinition <KnowledgeGroupRecord, KnowledgeGroupRecord>(
                (source, list) => list.SingleOrDefault(a => a.Id == source.Id)
                );

            patch
            .Map(s => s.Id, t => t.Id)
            .Map(s => s.Name, t => t.Name)
            .Map(s => s.Description, t => t.Description)
            .Map(s => s.FontAwesomeIconCharacterUnicodeAddress, t => t.FontAwesomeIconCharacterUnicodeAddress)
            .Map(s => s.Order, t => t.Order);

            var diff = patch.Patch(importKnowledgeGroups, knowledgeGroupRecords);

            service.ApplyPatchOperationAsync(diff).Wait();

            modifiedRecords += diff.Count(a => a.Action != ActionEnum.NotModified);
            return(diff.Where(a => a.Entity.IsDeleted == 0).Select(a => a.Entity).ToList());
        }
Пример #3
0
        private void ValidatePatch(PatchDefinition patchDef, IntPtr address)
        {
            // validate that we can at least read the specified location
            // we could (should) virtualquery here instead to check read/write, but this is lazier
            Memory.Read(address, 1);

            // TODO: exe version, once exposed

            if (patchDef.Validation?.RequiredBytes != null)
            {
                var actualBytes = Memory.Read(address, patchDef.Validation.RequiredBytes.Length);
                for (var i = 0; i < actualBytes.Length; i++)
                {
                    // null bytes are wildcards, so just skip over them
                    if (patchDef.Validation.RequiredBytes[i] != null && patchDef.Validation.RequiredBytes[i] != actualBytes[i])
                    {
                        throw new InvalidOperationException(string.Format("Expected bytes at patch address {0} do not match.  Expected [{1}], found [{2}]",
                                                                          address,
                                                                          patchDef.Validation.RequiredBytesString,
                                                                          BitConverter.ToString(actualBytes).Replace("-", " ")));
                    }
                }
            }

            // TODO: this should probably go somewhere else, but it's not really useful at the moment anyway
            if (patchDef.Patch.Location.ToLowerInvariant() != "overwrite")
            {
                PluginLog.Log("[WARN] Patch.Location only supports \"overwrite\" for now, defaulting to that behavior");
            }

            if (this.Patches.Any(p => p.Definition.Name == patchDef.Name))
            {
                throw new ArgumentException($"A patch with name {patchDef.Name} already exists");
            }
        }
        public List <KnowledgeEntryRecord> UpdateKnowledgeEntries(
            IList <KnowledgeEntryRecord> importKnowledgeEntries,
            IKnowledgeEntryService service,
            ref int modifiedRecords
            )
        {
            var knowledgeEntryRecords = service.FindAllAsync().Result;

            var patch = new PatchDefinition <KnowledgeEntryRecord, KnowledgeEntryRecord>(
                (source, list) => list.SingleOrDefault(a => a.Id == source.Id)
                );

            patch
            .Map(s => s.Id, t => t.Id)
            .Map(s => s.KnowledgeGroupId, t => t.KnowledgeGroupId)
            .Map(s => s.Title, t => t.Title)
            .Map(s => s.Text, t => t.Text)
            .Map(s => s.Order, t => t.Order)
            .Map(s => s.Links, t => t.Links)
            .Map(s => s.ImageIds, t => t.ImageIds);

            var diff = patch.Patch(importKnowledgeEntries, knowledgeEntryRecords);

            service.ApplyPatchOperationAsync(diff).Wait();

            modifiedRecords += diff.Count(a => a.Action != ActionEnum.NotModified);
            return(diff.Where(a => a.Entity.IsDeleted == 0).Select(a => a.Entity).ToList());
        }
Пример #5
0
        private void ProcessFile(PatchDefinition definition, PatchDefinitionEntry entry)
        {
            switch (entry.Operation)
            {
            case PatchOperation.Added:
                _context.LogProgress(string.Format(_context.LocalizedMessages.UpdateProcessingNewFile, entry.RelativePath));
                HandleAddedFile(definition, entry);
                _context.ReportProgress(string.Format(_context.LocalizedMessages.UpdateProcessedNewFile, entry.RelativePath));
                break;

            case PatchOperation.Deleted:
                _context.LogProgress(string.Format(_context.LocalizedMessages.UpdateProcessingDeletedFile, entry.RelativePath));
                HandleDeletedFile(definition, entry);
                _context.ReportProgress(string.Format(_context.LocalizedMessages.UpdateProcessedDeletedFile, entry.RelativePath));
                break;

            case PatchOperation.Updated:
                _context.LogProgress(string.Format(_context.LocalizedMessages.UpdateProcessingUpdatedFile, entry.RelativePath));
                HandleUpdatedFile(definition, entry);
                _context.ReportProgress(string.Format(_context.LocalizedMessages.UpdateProcessedUpdatedFile, entry.RelativePath));
                break;

            case PatchOperation.ChangedAttributes:
                _context.LogProgress(string.Format(_context.LocalizedMessages.UpdateProcessingChangedAttributesFile, entry.RelativePath));
                HandleChangedAttributesFile(definition, entry);
                _context.ReportProgress(string.Format(_context.LocalizedMessages.UpdateProcessedChangedAttributesFile, entry.RelativePath));
                break;
            }
        }
Пример #6
0
        private void DownloadPatch(PatchDefinition definition)
        {
            DirectoriesManager.Create(_context.Settings.GetTempPath());

            var archivePath  = _context.Settings.GetDownloadedPatchArchivePath(definition.From, definition.To);
            var leftAttempts = _context.Settings.PatchDownloadAttempts;
            var success      = false;

            do
            {
                try
                {
                    Downloader.Download(_context.Settings.GetRemotePatchArchiveUrl(definition.From, definition.To), _context.Settings.GetTempPath());
                    var downloadedArchiveHash = Hashing.GetFileHash(archivePath);
                    if (downloadedArchiveHash == definition.Hash)
                    {
                        success = true;
                        break;
                    }
                }
                catch
                {
                    // ignored
                }

                FilesManager.Delete(archivePath);
                leftAttempts--;
            } while (leftAttempts > 0);

            if (!success)
            {
                throw new PatchCannotBeDownloadedException();
            }
        }
Пример #7
0
        private void BuildPatchDefinition(PatchDefinition definition)
        {
            definition.Hash = Hashing.GetFileHash(PathsManager.Combine(_context.Settings.GetPatchesFolderPath(), _context.PatchName));
            definition.From = _context.VersionFrom;
            definition.To   = _context.VersionTo;

            File.WriteAllText(_context.Settings.GetPatchIndexPath(_context.VersionFrom, _context.VersionTo), _context.Serializer.Serialize(definition));
        }
Пример #8
0
        private void DecompressPatch(PatchDefinition definition)
        {
            var path = _context.Settings.GetUncompressedPatchArchivePath(definition.From, definition.To);

            DirectoriesManager.Create(path);

            Compressor.Decompress(path, _context.Settings.GetDownloadedPatchArchivePath(definition.From, definition.To), null);
        }
Пример #9
0
        private void HandleAddedFile(PatchDefinition definition, PatchDefinitionEntry entry)
        {
            var sourcePath      = PathsManager.Combine(_context.Settings.GetUncompressedPatchArchivePath(definition.From, definition.To), entry.RelativePath);
            var destinationPath = PathsManager.Combine(_context.Settings.GetGamePath(), entry.RelativePath);

            FilesManager.Delete(destinationPath);
            FilesManager.Move(sourcePath, destinationPath);

            EnsureDefinition(destinationPath, entry);
        }
Пример #10
0
        private void LoadPatchDefinitions()
        {
            if (LoadingPatchDefinitions)
            {
                return;
            }
            LoadingPatchDefinitions = true;

            string PatchDefinitionName = cmbPatchDefinitionName.Text;
            string TargetVersion       = cmbTargetVersion.Text;
            string TargetPath          = cmbTargetPath.Text;

            cmbPatchDefinitionName.SelectedIndex = -1;
            cmbTargetVersion.SelectedIndex       = -1;
            cmbTargetPath.SelectedIndex          = -1;

            cmbPatchDefinitionName.Items.Clear();
            cmbTargetVersion.Items.Clear();
            cmbTargetPath.Items.Clear();

            cmbPatchDefinitionName.Text = PatchDefinitionName;
            cmbTargetVersion.Text       = TargetVersion;
            cmbTargetPath.Text          = TargetPath;

            try
            {
                string      Definitions = File.ReadAllText(txtPatchDefinitionsFile.Text);
                PatchEngine Engine      = new PatchEngine(Definitions);
                Engine.PatchDefinitions.Where(d => !string.IsNullOrEmpty(d.Name)).Select(d => d.Name).Distinct().ToList().ForEach(n => cmbPatchDefinitionName.Items.Add(n));
                PatchDefinition Definition = null;
                if (cmbPatchDefinitionName.Text.Trim().Length > 0)
                {
                    Definition = Engine.PatchDefinitions.Where(d => string.Compare(d.Name, cmbPatchDefinitionName.Text.Trim(), true) == 0).FirstOrDefault();
                }
                if (Definition != null)
                {
                    Definition.TargetVersions.Where(v => !string.IsNullOrEmpty(v.Description)).Select(v => v.Description).Distinct().ToList().ForEach(d => cmbTargetVersion.Items.Add(d));
                    TargetVersion Version = null;
                    if (cmbTargetVersion.Text.Trim().Length > 0)
                    {
                        Version = Definition.TargetVersions.Where(v => string.Compare(v.Description, cmbTargetVersion.Text.Trim(), true) == 0).FirstOrDefault();
                    }
                    if (Version != null)
                    {
                        Version.TargetFiles.Where(f => !string.IsNullOrEmpty(f.Path)).Select(f => Path.GetDirectoryName(f.Path)).Distinct().ToList().ForEach(f => cmbTargetPath.Items.Add(f));
                    }
                }
            }
            catch { }

            LoadingPatchDefinitions = false;
        }
Пример #11
0
        private Patch LoadPatch(PatchDefinition patchDef)
        {
            PluginLog.Log($"Loading patch {patchDef.Name}");

            var address = ResolveAddress(patchDef);

            ValidatePatch(patchDef, address);

            return(new Patch()
            {
                Address = address,
                Bytes = patchDef.Patch.Bytes,
                Definition = patchDef
            });
        }
Пример #12
0
        private PatchDefinition BuildPatchDefinition(BuildDefinition fromDefinition, BuildDefinition toDefinition)
        {
            var patchDefinition = new PatchDefinition();

            patchDefinition.Entries = new List <PatchDefinitionEntry>();

            foreach (var newDefinition in toDefinition.Entries)
            {
                var oldDefinition = fromDefinition.Entries.FirstOrDefault(f => f.RelativePath == newDefinition.RelativePath);
                var alreadyExists = oldDefinition != null;

                var operation = PatchOperation.Added;

                if (alreadyExists)
                {
                    // The file exists in both versions. I have to check what type of change it got.
                    operation = GetOperation(newDefinition, oldDefinition);
                }

                if (operation != PatchOperation.Unchanged)
                {
                    patchDefinition.Entries.Add(new PatchDefinitionEntry()
                    {
                        Operation    = operation,
                        RelativePath = newDefinition.RelativePath
                    });
                }

                _context.ReportProgress(string.Format(_context.LocalizedMessages.PatchCollectedPatchData, newDefinition.RelativePath, operation.ToString()));
            }

            foreach (var oldDefinition in fromDefinition.Entries)
            {
                if (toDefinition.Entries.All(f => f.RelativePath != oldDefinition.RelativePath))
                {
                    // The old file does not exist in the new definition. This means it has been deleted.
                    patchDefinition.Entries.Add(new PatchDefinitionEntry()
                    {
                        Operation    = PatchOperation.Deleted,
                        RelativePath = oldDefinition.RelativePath
                    });
                }

                _context.ReportProgress(string.Format(_context.LocalizedMessages.PatchCollectedPatchData, oldDefinition.RelativePath, PatchOperation.Deleted.ToString()));
            }

            return(patchDefinition);
        }
Пример #13
0
        private void PerformUpdate(PatchDefinition definition)
        {
            _context.LogProgress(string.Format(_context.LocalizedMessages.UpdateDownloadingArchive, definition.From, definition.To));
            DownloadPatch(definition);
            _context.ReportProgress(string.Format(_context.LocalizedMessages.UpdateDownloadedArchive, definition.From, definition.To));

            _context.LogProgress(string.Format(_context.LocalizedMessages.UpdateDecompressingArchive, definition.From, definition.To));
            DecompressPatch(definition);
            _context.ReportProgress(string.Format(_context.LocalizedMessages.UpdateDecompressedArchive, definition.From, definition.To));

            foreach (var definitionEntry in definition.Entries)
            {
                ProcessFile(definition, definitionEntry);
            }

            DirectoriesManager.Delete(_context.Settings.GetTempPath());
        }
        private List <EventRecord> UpdateEventEntries(
            IList <EventImportRow> ImportEventEntries,
            IList <EventConferenceTrackRecord> CurrentConferenceTracks,
            IList <EventConferenceRoomRecord> CurrentConferenceRooms,
            IList <EventConferenceDayRecord> CurrentConferenceDays,
            ref int modifiedRecords
            )
        {
            var eventRecords = _eventService.FindAllAsync().Result;

            var patch = new PatchDefinition <EventImportRow, EventRecord>(
                (source, list) => list.SingleOrDefault(a => a.SourceEventId == source.EventId)
                );

            patch.Map(s => s.EventId, t => t.SourceEventId)
            .Map(s => s.Slug, t => t.Slug)
            .Map(s => s.Title.Split('–')[0]?.Trim(), t => t.Title)
            .Map(s => (s.Title + '–').Split('–')[1]?.Trim(), t => t.SubTitle)
            .Map(s => s.Abstract, t => t.Abstract)
            .Map(
                s => CurrentConferenceTracks.Single(a => a.Name == s.ConferenceTrack).Id,
                t => t.ConferenceTrackId)
            .Map(
                s => CurrentConferenceRooms.Single(a => a.Name == s.ConferenceRoom).Id,
                t => t.ConferenceRoomId)
            .Map(
                s => CurrentConferenceDays.Single(a => a.Name == s.ConferenceDayName).Id,
                t => t.ConferenceDayId)
            .Map(s => s.Description, t => t.Description)
            .Map(s => s.Duration, t => t.Duration)
            .Map(s => s.StartTime, t => t.StartTime)
            .Map(s => s.EndTime, t => t.EndTime)
            .Map(s => DateTime.SpecifyKind(CurrentConferenceDays.Single(a => a.Name == s.ConferenceDayName)
                                           .Date.Add(s.StartTime), DateTimeKind.Utc).AddHours(-2), t => t.StartDateTimeUtc)
            .Map(s => DateTime.SpecifyKind(CurrentConferenceDays.Single(a => a.Name == s.ConferenceDayName)
                                           .Date.Add(s.EndTime).AddDays(s.StartTime < s.EndTime ? 0 : 1).AddHours(-2), DateTimeKind.Utc),
                 t => t.EndDateTimeUtc)
            .Map(s => s.PanelHosts, t => t.PanelHosts);

            var diff = patch.Patch(ImportEventEntries, eventRecords);

            _eventService.ApplyPatchOperationAsync(diff).Wait();

            modifiedRecords += diff.Count(a => a.Action != ActionEnum.NotModified);
            return(diff.Where(a => a.Entity.IsDeleted == 0).Select(a => a.Entity).ToList());
        }
Пример #15
0
        public static List <EventConferenceRoomRecord> UpdateEventConferenceRooms(
            IList <string> importConferenceRooms,
            IEventConferenceRoomService service
            )
        {
            var eventConferenceRoomRecords = service.FindAllAsync().Result;

            var patch = new PatchDefinition <string, EventConferenceRoomRecord>(
                (source, list) => list.SingleOrDefault(a => a.Name == source)
                );

            patch.Map(s => s, t => t.Name);
            var diff = patch.Patch(importConferenceRooms, eventConferenceRoomRecords);

            service.ApplyPatchOperationAsync(diff).Wait();

            return(diff.Where(a => a.Entity.IsDeleted == 0).Select(a => a.Entity).ToList());
        }
        private List <EventConferenceRoomRecord> UpdateEventConferenceRooms(
            IList <string> importConferenceRooms,
            ref int modifiedRecords
            )
        {
            var eventConferenceRoomRecords = _eventConferenceRoomService.FindAllAsync().Result;

            var patch = new PatchDefinition <string, EventConferenceRoomRecord>(
                (source, list) => list.SingleOrDefault(a => a.Name == source)
                );

            patch.Map(s => s, t => t.Name);
            var diff = patch.Patch(importConferenceRooms, eventConferenceRoomRecords);

            _eventConferenceRoomService.ApplyPatchOperationAsync(diff).Wait();

            modifiedRecords += diff.Count(a => a.Action != ActionEnum.NotModified);
            return(diff.Where(a => a.Entity.IsDeleted == 0).Select(a => a.Entity).ToList());
        }
Пример #17
0
        public static List <EventConferenceDayRecord> UpdateEventConferenceDays(
            IList <Tuple <DateTime, string> > importConferenceDays,
            IEventConferenceDayService service
            )
        {
            var eventConferenceDayRecords = service.FindAllAsync().Result;

            var patch = new PatchDefinition <Tuple <DateTime, string>, EventConferenceDayRecord>(
                (source, list) => list.SingleOrDefault(a => a.Date == source.Item1)
                );

            patch.Map(s => s.Item1, t => t.Date)
            .Map(s => s.Item2, t => t.Name);

            var diff = patch.Patch(importConferenceDays, eventConferenceDayRecords);

            service.ApplyPatchOperationAsync(diff).Wait();

            return(diff.Where(a => a.Entity.IsDeleted == 0).Select(a => a.Entity).ToList());
        }
Пример #18
0
        public static List <EventRecord> UpdateEventEntries(
            IList <EventImportRow> ImportEventEntries,
            IList <EventConferenceTrackRecord> CurrentConferenceTracks,
            IList <EventConferenceRoomRecord> CurrentConferenceRooms,
            IList <EventConferenceDayRecord> CurrentConferenceDays,
            IEventService service
            )
        {
            var eventRecords = service.FindAllAsync().Result;

            var patch = new PatchDefinition <EventImportRow, EventRecord>(
                (source, list) => list.SingleOrDefault(a => a.SourceEventId == source.EventId)
                );

            patch.Map(s => s.EventId, t => t.SourceEventId)
            .Map(s => s.Slug, t => t.Slug)
            .Map(s => s.Title.Split('|')[0], t => t.Title)
            .Map(s => (s.Title + '|').Split('|')[1], t => t.SubTitle)
            .Map(s => s.Abstract, t => t.Abstract)
            .Map(
                s => CurrentConferenceTracks.Single(a => a.Name == s.ConferenceTrack).Id,
                t => t.ConferenceTrackId)
            .Map(
                s => CurrentConferenceRooms.Single(a => a.Name == s.ConferenceRoom).Id,
                t => t.ConferenceRoomId)
            .Map(
                s => CurrentConferenceDays.Single(a => a.Name == s.ConferenceDayName).Id,
                t => t.ConferenceDayId)
            .Map(s => s.Description, t => t.Description)
            .Map(s => s.Duration, t => t.Duration)
            .Map(s => s.StartTime, t => t.StartTime)
            .Map(s => s.EndTime, t => t.EndTime)
            .Map(s => s.PanelHosts, t => t.PanelHosts);

            var diff = patch.Patch(ImportEventEntries, eventRecords);

            service.ApplyPatchOperationAsync(diff).Wait();

            return(diff.Where(a => a.Entity.IsDeleted == 0).Select(a => a.Entity).ToList());
        }
Пример #19
0
        private void HandleUpdatedFile(PatchDefinition definition, PatchDefinitionEntry entry)
        {
            var filePath       = PathsManager.Combine(_context.Settings.GetGamePath(), entry.RelativePath);
            var fileBackupPath = filePath + ".bak";
            var patchPath      = PathsManager.Combine(_context.Settings.GetUncompressedPatchArchivePath(definition.From, definition.To), entry.RelativePath + ".patch");

            try
            {
                FilesManager.Rename(filePath, fileBackupPath);

                DeltaFileApplier.Apply(fileBackupPath, patchPath, filePath);

                EnsureDefinition(filePath, entry);
            }
            catch
            {
            }
            finally
            {
                FilesManager.Delete(fileBackupPath);
            }
        }
        public static List <KnowledgeGroupRecord> UpdateKnowledgeGroups(
            IList <KnowledgeGroupRecord> importKnowledgeGroups,
            IKnowledgeGroupService service
            )
        {
            var knowledgeGroupRecords = service.FindAllAsync().Result;

            var patch = new PatchDefinition <KnowledgeGroupRecord, KnowledgeGroupRecord>(
                (source, list) => list.SingleOrDefault(a => a.Id == source.Id)
                );

            patch
            .Map(s => s.Id, t => t.Id)
            .Map(s => s.Name, t => t.Name)
            .Map(s => s.Description, t => t.Description)
            .Map(s => s.Order, t => t.Order);

            var diff = patch.Patch(importKnowledgeGroups, knowledgeGroupRecords);

            service.ApplyPatchOperationAsync(diff).Wait();

            return(diff.Where(a => a.Entity.IsDeleted == 0).Select(a => a.Entity).ToList());
        }
Пример #21
0
        private IntPtr ResolveAddress(PatchDefinition patchDef)
        {
            var address = scanner.Module.BaseAddress;

            // if we have a signature, use that as the base instead of the module base
            if (!string.IsNullOrEmpty(patchDef.Location.Signature))
            {
                // TODO: do we need to handle .data too?
                address = scanner.ScanText(patchDef.Location.Signature);

                // ensure that there is only one instance found
                try
                {
                    var offset   = (int)(address.ToInt64() - scanner.TextSectionBase.ToInt64());
                    var dupeAddr = scanner.Scan(address + 1, scanner.TextSectionSize - offset, patchDef.Location.Signature);
                    // if we get here, there is a duplicate
                    throw new ArgumentException("Signatures specified in Location.Signature must resolve to a unique address");
                }
                catch (KeyNotFoundException)
                {
                    // Scan() throws this if not found, so getting here means we are ok
                }
            }

            // if there is an offset, add it to the current base
            if (!string.IsNullOrEmpty(patchDef.Location.Offset))
            {
                address += int.Parse(patchDef.Location.Offset, NumberStyles.HexNumber | NumberStyles.AllowHexSpecifier);
            }

            if (address == scanner.Module.BaseAddress)
            {
                throw new ArgumentException("At least one of Location.Signature and Location.Offset must be specified");
            }

            return(address);
        }
Пример #22
0
        public async Task ImportZipPackageAsync(string fileName)
        {
            var importRecords = new List <DealerRecord>();

            using (var fileStream = File.OpenRead(fileName))
                using (var archive = new ZipArchive(fileStream))
                {
                    var csvEntry =
                        archive.Entries.Single(a => a.Name.EndsWith(".csv", StringComparison.CurrentCultureIgnoreCase));

                    TextReader reader = new StreamReader(csvEntry.Open(), Encoding.GetEncoding(1252));

                    var csvReader = new CsvReader(reader);
                    csvReader.Configuration.RegisterClassMap <DealerImportRowClassMap>();
                    var csvRecords = csvReader.GetRecords <DealerImportRow>().ToList();

                    foreach (var record in csvRecords)
                    {
                        var dealerRecord = new DealerRecord
                        {
                            RegistrationNumber = record.RegNo,
                            AttendeeNickname   = record.Nickname,
                            AboutTheArtistText = record.AboutTheArtist,
                            AboutTheArtText    = record.AboutTheArt,
                            ArtPreviewCaption  = record.ArtPreviewCaption,
                            DisplayName        = record.DisplayName,
                            ShortDescription   = record.ShortDescription
                        };

                        dealerRecord.ArtistImageId = await GetImageIdAsync(archive, $"artist_{record.RegNo}.",
                                                                           $"dealer:artist:{record.RegNo}");

                        dealerRecord.ArtistThumbnailImageId = await GetImageIdAsync(archive, $"thumbnail_{record.RegNo}.",
                                                                                    $"dealer:thumbnail:{record.RegNo}");

                        dealerRecord.ArtPreviewImageId =
                            await GetImageIdAsync(archive, $"art_{record.RegNo}.", $"dealer:art:{record.RegNo}");

                        ImportLinks(dealerRecord, record.WebsiteUrl);
                        SanitizeFields(dealerRecord);

                        importRecords.Add(dealerRecord);
                    }
                }

            var existingRecords = await _dealerService.FindAllAsync();

            var patch = new PatchDefinition <DealerRecord, DealerRecord>((source, list) =>
                                                                         list.SingleOrDefault(a => a.RegistrationNumber == source.RegistrationNumber));

            patch
            .Map(s => s.RegistrationNumber, t => t.RegistrationNumber)
            .Map(s => s.AttendeeNickname, t => t.AttendeeNickname)
            .Map(s => s.AboutTheArtistText, t => t.AboutTheArtistText)
            .Map(s => s.AboutTheArtText, t => t.AboutTheArtText)
            .Map(s => s.ArtPreviewCaption, t => t.ArtPreviewCaption)
            .Map(s => s.DisplayName, t => t.DisplayName)
            .Map(s => s.ShortDescription, t => t.ShortDescription)
            .Map(s => s.ArtistImageId, t => t.ArtistImageId)
            .Map(s => s.ArtistThumbnailImageId, t => t.ArtistThumbnailImageId)
            .Map(s => s.ArtPreviewImageId, t => t.ArtPreviewImageId)
            .Map(s => s.Links, t => t.Links);

            var diff = patch.Patch(importRecords, existingRecords);
            await _dealerService.ApplyPatchOperationAsync(diff);
        }
Пример #23
0
        private void HandleDeletedFile(PatchDefinition definition, PatchDefinitionEntry entry)
        {
            var path = PathsManager.Combine(_context.Settings.GetGamePath(), entry.RelativePath);

            FilesManager.Delete(path);
        }
Пример #24
0
        private void HandleChangedAttributesFile(PatchDefinition definition, PatchDefinitionEntry entry)
        {
            var path = PathsManager.Combine(_context.Settings.GetGamePath(), entry.RelativePath);

            EnsureDefinition(path, entry);
        }
Пример #25
0
        public async Task ImportZipPackageAsync(string fileName)
        {
            var importRecords = new List <DealerRecord>();

            using (var fileStream = File.OpenRead(fileName))
                using (var archive = new ZipArchive(fileStream))
                {
                    var csvEntry =
                        archive.Entries.Single(a => a.Name.EndsWith(".csv", StringComparison.CurrentCultureIgnoreCase));

                    TextReader reader = new StreamReader(csvEntry.Open(), true);

                    var csvReader = new CsvReader(reader);
                    csvReader.Configuration.RegisterClassMap <DealerImportRowClassMap>();
                    csvReader.Configuration.Delimiter = ";";
                    var csvRecords = csvReader.GetRecords <DealerImportRow>().ToList();

                    _output?.WriteLine($"Parsed {csvRecords.Count} records from CSV");

                    foreach (var record in csvRecords)
                    {
                        var dealerRecord = new DealerRecord
                        {
                            RegistrationNumber = record.RegNo,
                            AttendeeNickname   = record.Nickname,
                            AboutTheArtistText = record.AboutTheArtist,
                            AboutTheArtText    = record.AboutTheArt,
                            ArtPreviewCaption  = record.ArtPreviewCaption,
                            DisplayName        = record.DisplayName,
                            ShortDescription   = record.ShortDescription,
                            Merchandise        = record.Merchandise,
                            AttendsOnThursday  = !string.IsNullOrWhiteSpace(record.AttendsThu),
                            AttendsOnFriday    = !string.IsNullOrWhiteSpace(record.AttendsFri),
                            AttendsOnSaturday  = !string.IsNullOrWhiteSpace(record.AttendsSat),
                            TelegramHandle     = record.Telegram,
                            TwitterHandle      = record.Twitter
                        };

                        dealerRecord.ArtistImageId = await GetImageIdAsync(archive, $"artist_{record.RegNo}.",
                                                                           $"dealer:artist:{record.RegNo}");

                        dealerRecord.ArtistThumbnailImageId = await GetImageIdAsync(archive, $"thumbnail_{record.RegNo}.",
                                                                                    $"dealer:thumbnail:{record.RegNo}");

                        dealerRecord.ArtPreviewImageId =
                            await GetImageIdAsync(archive, $"art_{record.RegNo}.", $"dealer:art:{record.RegNo}");

                        ImportLinks(dealerRecord, record.Website);
                        SanitizeFields(dealerRecord);

                        importRecords.Add(dealerRecord);
                    }
                }

            var existingRecords = await _dealerService.FindAllAsync();

            var patch = new PatchDefinition <DealerRecord, DealerRecord>((source, list) =>
                                                                         list.SingleOrDefault(a => a.RegistrationNumber == source.RegistrationNumber));

            patch
            .Map(s => s.RegistrationNumber, t => t.RegistrationNumber)
            .Map(s => s.AttendeeNickname, t => t.AttendeeNickname)
            .Map(s => s.AboutTheArtistText, t => t.AboutTheArtistText)
            .Map(s => s.AboutTheArtText, t => t.AboutTheArtText)
            .Map(s => s.ArtPreviewCaption, t => t.ArtPreviewCaption)
            .Map(s => s.DisplayName, t => t.DisplayName)
            .Map(s => s.ShortDescription, t => t.ShortDescription)
            .Map(s => s.Merchandise, t => t.Merchandise)
            .Map(s => s.ArtistImageId, t => t.ArtistImageId)
            .Map(s => s.ArtistThumbnailImageId, t => t.ArtistThumbnailImageId)
            .Map(s => s.ArtPreviewImageId, t => t.ArtPreviewImageId)
            .Map(s => s.TelegramHandle, t => t.TelegramHandle)
            .Map(s => s.TwitterHandle, t => t.TwitterHandle)
            .Map(s => s.AttendsOnThursday, t => t.AttendsOnThursday)
            .Map(s => s.AttendsOnFriday, t => t.AttendsOnFriday)
            .Map(s => s.AttendsOnSaturday, t => t.AttendsOnSaturday)
            .Map(s => s.Links, t => t.Links);

            var diff = patch.Patch(importRecords, existingRecords);
            await _dealerService.ApplyPatchOperationAsync(diff);

            _output?.WriteLine($"Added: {diff.Count(a => a.Action == ActionEnum.Add)}");
            _output?.WriteLine($"Deleted: {diff.Count(a => a.Action == ActionEnum.Delete)}");
            _output?.WriteLine($"Updated: {diff.Count(a => a.Action == ActionEnum.Update)}");
            _output?.WriteLine($"Not Modified: {diff.Count(a => a.Action == ActionEnum.NotModified)}");
        }
        public async Task ExecuteAsync()
        {
            _logger.LogDebug("Job started");

            var response = string.Empty;

            using (var client = new HttpClient())
            {
                var url = _configuration["source:url"];
                _logger.LogDebug("Fetching data from {url}", url);
                response = await client.GetStringAsync(url);
            }

            if (response == "null")
            {
                _logger.LogDebug("Received null response");
                return;
            }


            var records       = JsonConvert.DeserializeObject <JObject[]>(response);
            var unixReference = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc);

            var mapping = records.Select(j => new
            {
                Record = new AnnouncementRecord()
                {
                    ExternalReference = j["id"].Value <string>(),
                    Area    = j["news"]["type"].Value <string>().UppercaseFirst(),
                    Author  = j["news"]?["department"]?.Value <string>().UppercaseFirst() ?? "Eurofurence",
                    Title   = j["news"]["title"].Value <string>(),
                    Content = j["news"]["message"].Value <string>().RemoveMarkdown(),
                    ValidFromDateTimeUtc  = unixReference.AddSeconds(j["date"].Value <double>()).ToUniversalTime(),
                    ValidUntilDateTimeUtc = unixReference
                                            .AddSeconds(j["news"]["valid_until"].Value <double>()).ToUniversalTime(),
                },
                Type = j["news"]["type"].Value <string>()
            }).ToList();

            foreach (var item in mapping)
            {
                if (new[] { "new", "reschedule" }.Contains(item.Type))
                {
                    item.Record.ValidUntilDateTimeUtc = item.Record.ValidFromDateTimeUtc.AddHours(48);
                }
            }

            var existingRecords = await _announcementService.FindAllAsync();

            var patch = new PatchDefinition <AnnouncementRecord, AnnouncementRecord>((source, list) =>
                                                                                     list.SingleOrDefault(a => a.ExternalReference == source.ExternalReference));

            patch
            .Map(s => s.ExternalReference, t => t.ExternalReference)
            .Map(s => s.Area, t => t.Area)
            .Map(s => s.Author, t => t.Author)
            .Map(s => s.Title, t => t.Title)
            .Map(s => s.Content, t => t.Content)
            .Map(s => s.ValidUntilDateTimeUtc, t => t.ValidUntilDateTimeUtc)
            .Map(s => s.ValidFromDateTimeUtc, t => t.ValidFromDateTimeUtc);

            var diff = patch.Patch(mapping.Select(a => a.Record), existingRecords)
                       .Where(a => !string.IsNullOrEmpty(a.Entity.ExternalReference) && a.Action != ActionEnum.NotModified)
                       .ToList();

            _logger.LogDebug("Diff results in {count} new/modified records", diff.Count);

            if (diff.Count == 0)
            {
                return;
            }

            _logger.LogInformation("Processing {count} new/modified records", diff.Count);

            await _announcementService.ApplyPatchOperationAsync(diff);

            await _pushEventMediator.PushSyncRequestAsync();

            foreach (var record in diff.Where(a => a.Action == ActionEnum.Add))
            {
                _logger.LogInformation("Sending push notification for announcement {id} ({title})", record.Entity.Id, record.Entity.Title);
                await _pushEventMediator.PushAnnouncementNotificationAsync(record.Entity);
            }

            _logger.LogDebug("Job finished");
        }
Пример #27
0
        // TargetFilePath is relative to the root of the PatchDefinition
        // OutputFilePath can be null
        public static void AddPatch(string InputFilePath, string OutputFilePath, string PatchDefinitionName, string TargetVersionDescription, string TargetFilePath, string PathToVisualStudioWithWP8SDK, UInt32 VirtualAddress, CodeType CodeType, string ArmCodeFragment, string PatchDefintionsXmlPath)
        {
            SHA1Managed SHA = new SHA1Managed();

            // Compile ARM code
            byte[] CompiledCode = null;
            if (VirtualAddress != 0)
            {
                CompiledCode = ArmCompiler.Compile(PathToVisualStudioWithWP8SDK, VirtualAddress, CodeType, ArmCodeFragment);
            }

            // Read original binary
            byte[] Binary = File.ReadAllBytes(InputFilePath);

            // Backup original checksum
            UInt32 ChecksumOffset   = GetChecksumOffset(Binary);
            UInt32 OriginalChecksum = ByteOperations.ReadUInt32(Binary, ChecksumOffset);

            // Determine Raw Offset
            PeFile PeFile    = new PeFile(Binary);
            UInt32 RawOffset = 0;

            if (VirtualAddress != 0)
            {
                RawOffset = PeFile.ConvertVirtualAddressToRawOffset(VirtualAddress);
            }

            // Add or replace patch
            string          PatchDefintionsXml = File.ReadAllText(PatchDefintionsXmlPath);
            PatchEngine     PatchEngine        = new PatchEngine(PatchDefintionsXml);
            PatchDefinition PatchDefinition    = PatchEngine.PatchDefinitions.Where(d => (string.Compare(d.Name, PatchDefinitionName, true) == 0)).FirstOrDefault();

            if (PatchDefinition == null)
            {
                PatchDefinition      = new PatchDefinition();
                PatchDefinition.Name = PatchDefinitionName;
                PatchEngine.PatchDefinitions.Add(PatchDefinition);
            }
            TargetVersion TargetVersion = PatchDefinition.TargetVersions.Where(v => (string.Compare(v.Description, TargetVersionDescription, true) == 0)).FirstOrDefault();

            if (TargetVersion == null)
            {
                TargetVersion             = new TargetVersion();
                TargetVersion.Description = TargetVersionDescription;
                PatchDefinition.TargetVersions.Add(TargetVersion);
            }
            TargetFile TargetFile = TargetVersion.TargetFiles.Where(f => ((f.Path != null) && (string.Compare(f.Path.TrimStart(new char[] { '\\' }), TargetFilePath.TrimStart(new char[] { '\\' }), true) == 0))).FirstOrDefault();

            if (TargetFile == null)
            {
                TargetFile = new TargetFile();
                TargetVersion.TargetFiles.Add(TargetFile);
            }
            TargetFile.Path         = TargetFilePath;
            TargetFile.HashOriginal = SHA.ComputeHash(Binary);
            Patch Patch;

            if (VirtualAddress != 0)
            {
                Patch = TargetFile.Patches.Where(p => p.Address == RawOffset).FirstOrDefault();
                if (Patch == null)
                {
                    Patch         = new Patch();
                    Patch.Address = RawOffset;
                    TargetFile.Patches.Add(Patch);
                }
                Patch.OriginalBytes = new byte[CompiledCode.Length];
                Buffer.BlockCopy(Binary, (int)RawOffset, Patch.OriginalBytes, 0, CompiledCode.Length);
                Patch.PatchedBytes = CompiledCode;
            }

            // Apply all patches
            foreach (Patch CurrentPatch in TargetFile.Patches)
            {
                Buffer.BlockCopy(CurrentPatch.PatchedBytes, 0, Binary, (int)CurrentPatch.Address, CurrentPatch.PatchedBytes.Length);
            }

            // Calculate checksum
            // This also modifies the binary
            // Original checksum is already backed up
            UInt32 Checksum = CalculateChecksum(Binary);

            // Add or replace checksum patch
            Patch = TargetFile.Patches.Where(p => p.Address == ChecksumOffset).FirstOrDefault();
            if (Patch == null)
            {
                Patch         = new Patch();
                Patch.Address = ChecksumOffset;
                TargetFile.Patches.Add(Patch);
            }
            Patch.OriginalBytes = new byte[4];
            ByteOperations.WriteUInt32(Patch.OriginalBytes, 0, OriginalChecksum);
            Patch.PatchedBytes = new byte[4];
            ByteOperations.WriteUInt32(Patch.PatchedBytes, 0, Checksum);

            // Calculate hash for patched target file
            TargetFile.HashPatched = SHA.ComputeHash(Binary);

            // Write patched file
            if (OutputFilePath != null)
            {
                File.WriteAllBytes(OutputFilePath, Binary);
            }

            // Write PatchDefintions
            PatchEngine.WriteDefinitions(PatchDefintionsXmlPath);
        }