public static Interactive LoadLocal(Stream stream) { Interactive story = new Interactive(); BinaryReader binReader = new BinaryReader(stream); story.ItemId = binReader.ReadUInt32(); story.Title = binReader.ReadString(); story.Owner = binReader.ReadString(); story.Description = binReader.ReadString(); story.InfoText = binReader.ReadString(); ushort count = binReader.ReadByte(); for (ushort us = 0; us < count; us++) { story.RootChapters.Add(binReader.ReadUInt16()); } count = binReader.ReadUInt16(); for (ushort us = 0; us < count; us++) { story.Chapters.Add(Chapter.LoadLocal(stream)); } return(story); }
public static async Task <Interactive> LoadWebSkeleton(uint itemId) { Interactive story = new Interactive(itemId); // Get HTML document for main story page. HtmlDocument htmlDoc = await WebUtilities.GetHtmlDocumentAsync(ParseParams.IABaseUrl + itemId); // Start downloading outline page. Task <HtmlDocument> outlineDocTask = WebUtilities.GetHtmlDocumentAsync(ParseParams.IABaseUrl + itemId + ParseParams.IAOutlineUrlSegment); // Check page title node to see if a valid ID was given. HtmlNode pageTitleNode = htmlDoc.DocumentNode.SelectSingleNode(ParseParams.PageTitleXPath); if (pageTitleNode == null) { throw new Exception("Cannot find page title."); } else if (pageTitleNode.InnerText.Contains("Item Not Found")) { throw new Exception("Story not found"); } // Find the HTML node with the text for each field we need, and assign the field value. story.Title = WebUtilities.GetHtmlNodeText(htmlDoc, ParseParams.IATitleXPath); story.Owner = WebUtilities.GetHtmlNodeText(htmlDoc, ParseParams.IAOwnerPath); story.Description = WebUtilities.GetHtmlNodeText(htmlDoc, ParseParams.IADescriptionXPath); story.InfoText = WebUtilities.GetHtmlNodeText(htmlDoc, ParseParams.IAInfoTextXPath); // Finish getting the outline HTML document. HtmlDocument outlineDoc = await outlineDocTask; // Check if we got the "Please Login" message. HtmlNode loginNode = outlineDoc.DocumentNode.SelectSingleNode(ParseParams.IAOutlineLoginXPath); if (loginNode != null && loginNode.InnerText.Contains("Please login")) { throw new Exception("Not logged in, unable to access outline."); } // Parse out chapter names and map structure. HtmlNode outlineParentNode = outlineDoc.DocumentNode.SelectSingleNode(ParseParams.IAOutlineParentXPath); List <HtmlNode> outlineHtmlNodes = new List <HtmlNode>(outlineParentNode.ChildNodes); int nodeIndex = 0; HtmlNode spanNode = null; HtmlNode bNode = null; while (nodeIndex < outlineHtmlNodes.Count) { // span element contains choice path string (1-2-1-1-3-...). if (outlineHtmlNodes[nodeIndex].Name.Equals("span", StringComparison.OrdinalIgnoreCase)) { spanNode = outlineHtmlNodes[nodeIndex]; // span element must come first. bNode = null; } // b element contains chapter name. else if (outlineHtmlNodes[nodeIndex].Name.Equals("b", StringComparison.OrdinalIgnoreCase)) { bNode = outlineHtmlNodes[nodeIndex]; } if (spanNode != null && bNode != null) { // Get choice path as array of ints. string choicePathStr = spanNode.InnerText; // Remove junk at end. choicePathStr = choicePathStr.Substring(0, choicePathStr.Length - 7); // Convert to int. List <byte> choices = new List <byte>(); foreach (string s in choicePathStr.Split('-')) { choices.Add(byte.Parse(s)); } string chapterName = WebUtilities.CleanHtmlSymbols(bNode.InnerText); // Remove "#_: " from start of name. chapterName = chapterName.Substring(chapterName.IndexOf(' ') + 1); Chapter chapter = new Chapter(chapterName, choices[choices.Count - 1]); story.AddChapter(chapter, choices); spanNode = null; bNode = null; } nodeIndex++; } return(story); }