private void InstallSet(string fname, Octgn.Data.Game SelectedGame) { string shortName = Path.GetFileName(fname); UpdateStatus("Installing Set " + shortName); string path = Path.Combine(Prefs.DataDirectory, "Games", SelectedGame.Id.ToString(), "Sets"); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } try { if (shortName != null) { string copyto = Path.Combine(path, shortName); if (fname.ToLower() != copyto.ToLower()) { File.Copy(fname, copyto, true); } SelectedGame.InstallSet(copyto); } UpdateStatus(string.Format("Set '{0}' installed.", shortName)); } catch (Exception ex) { UpdateStatus(string.Format("'{0}' an error occured during installation:", shortName)); UpdateStatus(ex.Message); } }
private void Apply(Package package, string localFilename, bool installed) { using (Package setPkg = Package.Open(localFilename, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { // Extract information about the target set PackageRelationship defRelationship = setPkg.GetRelationshipsByType("http://schemas.octgn.org/set/definition").First(); PackagePart definition = setPkg.GetPart(defRelationship.TargetUri); Set set; using (XmlReader reader = XmlReader.Create(definition.GetStream(), XmlSettings)) { reader.ReadToFollowing("set"); // <?xml ... ?> set = new Set(localFilename, reader, _game.Repository); // Check if the set game matches the patch if (set.Game != _game) { return; } } // Check if there is a patch for this set string relationId = "S" + set.Id.ToString("N"); if (!package.RelationshipExists(relationId)) { return; } PackagePart patchPart = package.GetPart(package.GetRelationship(relationId).TargetUri); XDocument patchDoc; using (Stream stream = patchPart.GetStream()) patchDoc = XDocument.Load(stream); // Check if the set is at least the required version for patching if (set.Version < patchDoc.Root.Attr <Version>("minVersion")) { return; } if (set.Version > patchDoc.Root.Attr <Version>("maxVersion")) { return; } if (installed) { _game.DeleteSet(_game.Sets.Single(s => s.PackageName == localFilename)); } // Process the set if (patchDoc.Root != null) { foreach (XElement action in patchDoc.Root.Elements()) { switch (action.Name.LocalName) { case "new": { var targetUri = new Uri(action.Attr <string>("targetUri"), UriKind.Relative); var relationshipId = action.Attr <string>("relationshipId"); var contentType = action.Attr <string>("contentType"); PackagePart part = setPkg.PartExists(targetUri) ? setPkg.GetPart(targetUri) : setPkg.CreatePart(targetUri, contentType, CompressionOption.Normal); if (part != null) { using (Stream targetStream = part.GetStream(FileMode.Create, FileAccess.Write)) using ( Stream srcStream = package.GetPart(patchPart.GetRelationship(relationshipId).TargetUri). GetStream()) srcStream.CopyTo(targetStream); } break; } case "newrel": { var partUri = new Uri(action.Attr <string>("partUri"), UriKind.Relative); var relationshipId = action.Attr <string>("relationshipId"); var targetUri = new Uri(action.Attr <string>("targetUri"), UriKind.Relative); var relationshipType = action.Attr <string>("relationshipType"); PackagePart part = setPkg.GetPart(partUri); if (part.RelationshipExists(relationshipId)) { part.DeleteRelationship(relationshipId); } part.CreateRelationship(targetUri, TargetMode.Internal, relationshipType, relationshipId); break; } default: throw new InvalidFileFormatException("Unknown patch action: " + action.Name); } } } } OnProgress(string.Format("{0} patched.", Path.GetFileName(localFilename))); if (installed) { try { _game.InstallSet(localFilename); } catch (Exception ex) { OnProgress(string.Format("{0} can't be re-installed.\nDetails: {1}", localFilename, ex.Message), true); } } }