raiguard / RecipeBook

Recipe Book for Factorio.
MIT License
20 stars 9 forks source link

Crash on mod update: recipe in favorites no longer exists #107

Closed OndraTakacs closed 2 years ago

OndraTakacs commented 2 years ago

Describe the Bug

Game crashes after loading mod update with recipe in favorites that no longer exists.

To Reproduce

Steps to reproduce the behavior:

  1. Add recipe X to favorites
  2. Change mod so that this recipe X no longer exists
  3. Load game again
  4. Game crashes

Fix for the bug

This change fixed it for me:

Update the function update_list_box in util.lua to this:

function gui_util.update_list_box(pane, source_tbl, player_data, iterator, options)
  local i = 0
  local children = pane.children
  local add = pane.add
  for k, obj_ident in iterator(source_tbl) do
    local obj_data_class = database[obj_ident.class]
    if obj_data_class == nill then
      goto continue
    end
    local obj_data = obj_data_class[obj_ident.name]
    local info = formatter(obj_data, player_data, options)
    if info then
      i = i + 1
      local style = info.researched and "rb_list_box_item" or "rb_unresearched_list_box_item"
      local item = children[i]
      if item then
        item.style = style
        item.caption = info.caption
        item.tooltip = info.tooltip
        item.enabled = info.num_interactions > 0
        gui.update_tags(item, { context = { class = obj_ident.class, name = obj_ident.name } })
      else
        add({
          type = "button",
          style = style,
          caption = info.caption,
          tooltip = info.tooltip,
          enabled = info.num_interactions > 0,
          mouse_button_filter = { "left", "middle" },
          tags = {
            [script.mod_name] = {
              context = { class = obj_ident.class, name = obj_ident.name },
              flib = {
                on_click = { gui = "search", action = "open_object" },
              },
            },
          },
        })
      end
    end
    ::continue::
  end
  -- Destroy extraneous items
  for j = i + 1, #children do
    children[j].destroy()
  end
end

Changes: added at loop start

if obj_data_class == nill then
  goto continue
end

added at loop end ::continue::

raiguard commented 2 years ago

Thanks for the report. Invalid favorites entries were not being removed as they should have been, because I neglected to update the code that removes them. That has been fixed.