function Librarian:ImportFromLoreLibrary() self.unreadPerCollections = {} local hasImportedBooks = false local chatEnabled = self.settings.chatEnabled local alertEnabled = self.settings.alertEnabled self.settings.chatEnabled = true self.settings.alertEnabled = false local identifier = "LibrarianLoreImport" local em = GetEventManager() local function endSearch() em:UnregisterForUpdate(identifier) self.settings.chatEnabled = chatEnabled self.settings.alertEnabled = alertEnabled if hasImportedBooks then self:RefreshAllData() else self:RefreshLoreLibraryData() end end local categoryIndex, collectionIndex, bookIndex = 0, 0, 0 local numCollections, totalBooks = 0, 0 local function step() if bookIndex >= totalBooks then if collectionIndex >= numCollections then if categoryIndex >= self:GetNumLoreCategories() then endSearch() return false else categoryIndex = categoryIndex + 1 local loreCategoryName numCollections = self:GetLoreCollectionCount(categoryIndex) collectionIndex = 0 end end collectionIndex = collectionIndex + 1 totalBooks = self:GetLoreCollectionTotalBook(categoryIndex, collectionIndex) bookIndex = 0 if totalBooks == 0 then -- if there is no book in this collection, it is probably an obsolete collection so let's skip it instead of crashing later here return true end end bookIndex = bookIndex + 1 local title, known, bookId = self:GetBookInfo(categoryIndex, collectionIndex, bookIndex) if known then local book = self:FindBook(bookId) local characterBook = self:FindCharacterBook(bookId) if book and characterBook and book.unread then self:AddUnreadBookInCollection(categoryIndex, collectionIndex) elseif not characterBook then local newBook = { bookId = bookId, title = title } self:AddBook(newBook, false) hasImportedBooks = true end end return true end local function steps() local gettime = GetGameTimeMilliseconds local start = gettime() -- do as much as possible in 5ms while ((gettime() - start) < 5) and step() do end end em:RegisterForUpdate(identifier, 0, steps) end function Librarian:FindCharacterBook(bookId) if not self.characterBooks then return nil end if self.characterBooksCache[bookId] then return self.characterBooksCache[bookId] end for _,book in ipairs(self.characterBooks) do if book.bookId == bookId then self.characterBooksCache[bookId] = book return book end end return nil end function Librarian:FindBook(bookId) for _,book in ipairs(self.books) do if book.bookId == bookId then return book end end end function Librarian:AddBookToGlobalSave(book) book.timeStamp = GetTimeStamp() book.unread = true local categoryIndex, collectionIndex, bookIndex = self:GetLoreBookIndicesFromBookId(book.bookId) if categoryIndex and collectionIndex and bookIndex then -- if these indexes exist in the API, this mean that we will be able to get these info when needed (so no need to save them) book.title = nil book.body = nil book.medium = nil book.showTitle = nil else local newBody = book.body book.body = {} while string.len(newBody) > 1024 do table.insert(book.body, string.sub(newBody, 0, 1024)) newBody = string.sub(newBody, 1025) end table.insert(book.body, newBody) end table.insert(self.books, book) for index, bookIdToDelete in ipairs(self.globalSavedVars.deletedBooks) do if bookIdToDelete == book.bookId then table.remove(self.globalSavedVars.deletedBooks, index) break end end end function Librarian:AddBook(book, refreshDataRightAway) if not self:FindCharacterBook(book.bookId) then local bookTitle = book.title -- storing it because AddBookToGlobalSave will delete it if we can retrieve it thanks to ESO API local foundBook = self:FindBook(book.bookId) if foundBook then book = foundBook else self:AddBookToGlobalSave(book) end local characterBook = { bookId = book.bookId, timeStamp = GetTimeStamp() } table.insert(self.characterBooks, characterBook) if book.unread then local categoryIndex, collectionIndex = self:GetLoreBookIndicesFromBookId(book.bookId) if categoryIndex and collectionIndex then self:AddUnreadBookInCollection(categoryIndex, collectionIndex) end end if refreshDataRightAway then self:RefreshAllData() end if self.settings.alertEnabled then --CENTER_SCREEN_ANNOUNCE:AddMessage(EVENT_SKILL_RANK_UPDATE, CSA_EVENT_LARGE_TEXT, SOUNDS.BOOK_ACQUIRED, GetString(SI_LIBRARIAN_NEW_BOOK_FOUND)) local params = CENTER_SCREEN_ANNOUNCE:CreateMessageParams(CSA_EVENT_LARGE_TEXT, SOUNDS.BOOK_ACQUIRED) params:SetCSAType(CENTER_SCREEN_ANNOUNCE_TYPE_DISPLAY_ANNOUNCEMENT ) params:SetText(GetString(LIBRARIAN_NEW_BOOK_FOUND)) CENTER_SCREEN_ANNOUNCE:AddMessageWithParams(params) end if self.settings.chatEnabled then d(string.format(GetString(LIBRARIAN_NEW_BOOK_FOUND_WITH_TITLE), bookTitle)) end self.newBookCount = self.newBookCount + 1 if self.settings.reloadReminderBookCount and self.settings.reloadReminderBookCount > 0 and self.settings.reloadReminderBookCount <= self.newBookCount then d(GetString(LIBRARIAN_RELOAD_REMINDER)) end end end function Librarian:RemoveBook(bookId) for _, bookIdToDelete in ipairs(self.globalSavedVars.deletedBooks) do if bookIdToDelete == bookId then d("Couldn't delete book, it is already beeing deleted") return end end table.insert(self.globalSavedVars.deletedBooks, bookId) for index ,book in ipairs(self.books) do if book.bookId == bookId then table.remove(self.books, index) break end end self.characterBooksCache[bookId] = nil self:RemoveCharacterBook(bookId) -- Clean the master list to be sure the entry is removed from the display as well self.masterList = {} self:RefreshAllData() end function Librarian:RemoveCharacterBook(bookId) for index ,book in ipairs(self.characterBooks) do if book.bookId == bookId then table.remove(self.characterBooks, index) break end end end function Librarian:AddUnreadBookInCollection(categoryIndex, collectionIndex) if not self.unreadPerCollections[categoryIndex] then self.unreadPerCollections[categoryIndex] = {} end if not self.unreadPerCollections[categoryIndex][collectionIndex] then self.unreadPerCollections[categoryIndex][collectionIndex] = 0 end self.unreadPerCollections[categoryIndex][collectionIndex] = self.unreadPerCollections[categoryIndex][collectionIndex] + 1 end function Librarian:ToggleReadBook(book) book.unread = not book.unread local categoryIndex, collectionIndex = self:GetLoreBookIndicesFromBookId(book.bookId) if categoryIndex and collectionIndex then if not self.unreadPerCollections[categoryIndex] then self.unreadPerCollections[categoryIndex] = {} end if not self.unreadPerCollections[categoryIndex][collectionIndex] then self.unreadPerCollections[categoryIndex][collectionIndex] = 0 end if book.unread then self.unreadPerCollections[categoryIndex][collectionIndex] = self.unreadPerCollections[categoryIndex][collectionIndex] + 1 elseif self.unreadPerCollections[categoryIndex][collectionIndex] > 0 then self.unreadPerCollections[categoryIndex][collectionIndex] = self.unreadPerCollections[categoryIndex][collectionIndex] - 1 end end self:RefreshAllData() end