Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash in "hf learns secret"-type events when the teacher ID is not set #18

Open
MatthiasValvekens opened this issue Jan 30, 2015 · 6 comments

Comments

@MatthiasValvekens
Copy link

This was the event that caused the problem:

    <historical_event>
        <id>26699</id>
        <year>125</year>
        <seconds72>22995</seconds72>
        <type>hf learns secret</type>
        <student_hfid>4018</student_hfid>
        <teacher_hfid>-1</teacher_hfid>
        <artifact_id>54</artifact_id>
        <interaction>SECRET_1</interaction>
    </historical_event>

The HF in question is my adventurer, who learned the secrets of life and death by reading a tome. Hence, there's no teacher involved as such. I got a NullReferenceException on the LegendsViewer.Legends.HFLearnsSecret.Print call when I tried to view my adventurer's summary page in LegendsViewer.

Changing the teacher_hfid to match the student's fixed the issue, though, but there's probably some code assuming that a teacher id is always set to some sensible value.

I don't have a working C# build environment at hand right now, but I'll try and track down the piece of code responsible for the crash.

@JyeGuru
Copy link
Contributor

JyeGuru commented Jan 30, 2015

case "teacher_hfid": Teacher = world.GetHistoricalFigure(Convert.ToInt32(property.Value)); break;

case "teacher_hfid": Teacher = world.GetHistoricalFigure(Convert.ToInt32(property.Value)); break;

world.GetHistoricalFigure() returns null if passed -1

@MatthiasValvekens
Copy link
Author

Hmm, the plot thickens. I restored my "broken" legends file, and tried searching for another HF who learned a secret from an artifact (and has teacher_hfid set to -1). For some reason, this worked fine. Could it be that the HFLearnSecret object itself somehow fails to be created? LegendsViewer.Legends.HFLearnsSecret.Print is the top entry in the NullReferenceException's stack trace, anyway. I suppose that means that the .Print call failed because its underlying object reference wasn't set.

Full stack trace for good measure:

System.NullReferenceException: Object reference not set to an instance of an object.
   at LegendsViewer.Legends.HFLearnsSecret.Print(Boolean link, DwarfObject pov)
   at LegendsViewer.Controls.HistoricalFigureHTMLPrinter.PrintEvents()
   at LegendsViewer.Controls.HistoricalFigureHTMLPrinter.Print()
   at LegendsViewer.Controls.HTMLControl.GetControl()
   at LegendsViewer.DwarfTabPage.LoadPageControl()
   at LegendsViewer.DwarfTabPage.NewPageControl(PageControl pageControl)
   at LegendsViewer.DwarfTabControl.Navigate(ControlOption control, Object navigateObject)
   at LegendsViewer.frmLegendsViewer.listSearch_SelectedIndexChanged(Object sender, EventArgs e)
   at System.Windows.Forms.ListBox.WmReflectCommand(Message& m)
   at System.Windows.Forms.ListBox.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

The (working) histfig's event:

    <historical_event>
        <id>5977</id>
        <year>53</year>
        <seconds72>252000</seconds72>
        <type>hf learns secret</type>
        <student_hfid>554</student_hfid>
        <teacher_hfid>-1</teacher_hfid>
        <artifact_id>2</artifact_id>
        <interaction>SECRET_1</interaction>
    </historical_event>

EDIT: upon closer inspection, the code that does the artifact parsing might be failing here. I got this when trying to view the tower I found the book at:

System.NullReferenceException: Object reference not set to an instance of an object.
   at LegendsViewer.Legends.ArtifactCreated.Print(Boolean link, DwarfObject pov)
   at LegendsViewer.Controls.SitePrinter.Print()
   at LegendsViewer.Controls.HTMLControl.GetControl()
   at LegendsViewer.DwarfTabPage.LoadPageControl()
   at LegendsViewer.DwarfTabPage.NewPageControl(PageControl pageControl)
   at LegendsViewer.DwarfTabControl.Navigate(ControlOption control, Object navigateObject)
   at LegendsViewer.frmLegendsViewer.listSearch_SelectedIndexChanged(Object sender, EventArgs e)
   at System.Windows.Forms.ListBox.WmReflectCommand(Message& m)
   at System.Windows.Forms.ListBox.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

EDIT 2: I found the root cause. Artifact ID 54 refers to a book that doesn't exist in the legends XML, so it's probably a bug in DF, not in Legends Viewer.

    <artifact>
        <id>53</id>
        <name>the tower is my life</name>
        <item>the tower is my life</item>
    </artifact>
    <artifact>
        <id>55</id>
        <name>uncanny book</name>
        <item>uncanny book</item>
    </artifact>

Still, it's probably worth replacing the artifact name by something like UNKNOWN_ARTIFACT, to prevent an exception from being raised.

@JyeGuru
Copy link
Contributor

JyeGuru commented Jan 30, 2015

I'll update my local copy of the source and see about reproducing this weekend. Can you pass your export file? (Dropbox link/etc)

@MatthiasValvekens
Copy link
Author

Here's a google drive link:
https://drive.google.com/file/d/0B3D_3d9BMj8NanlmTlRGYUFGTWc/view?usp=sharing

(file generated on DF 0.40.23, by the way)

@JyeGuru
Copy link
Contributor

JyeGuru commented Jan 30, 2015

Artifact ID 54 refers to a book that doesn't exist in the legends XML

That'd do it.

@JyeGuru
Copy link
Contributor

JyeGuru commented Jan 30, 2015

https://github.com/Parker147/Legends-Viewer/blob/master/LegendsViewer/Legends/Events.cs#L1252

            if (Teacher != null)
                eventString += Teacher.ToLink(link, pov) + " taught " + Student.ToLink(link, pov) + " (" + Interaction + ")";
            else 
                eventString += Student.ToLink(link, pov) + " learned (" + Interaction + ") from " + Artifact.ToLink(link, pov);

It appears to check for teacher being null, but not the artifact.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants