from phBot import * import QtBind import math import json import os pName = 'ItemCounter' pVersion = '1.7' pUrl = 'https://raw.githubusercontent.com/ryuzakidev/phBot-plugins/main/ItemCounter.py' gui = QtBind.init(__name__, pName) baseY = 30 pageLimit = 12 labelItems = [] countIn = 'Inventory' lastCountIn = countIn currPage = 0 totalPages = 0 lastPage = currPage searchText = '' buttonItems = {} quickSearchList = [] configStamp = None quickSearchDeleted = False # static labels QtBind.createLabel(gui, 'Search', 10, baseY + 4) QtBind.createLabel(gui, 'by Ryuzaki', 670, 267) QtBind.createLabel(gui, 'Where do you want to look?', 565, 10) QtBind.createLabel(gui, 'Quick Search', 310, baseY + 4) # dynamic labels lblTitle = QtBind.createLabel(gui, 'ITEMS', 10, 10) lblPaging = QtBind.createLabel(gui, '0/0', 100, baseY + 220) # buttons btnStorage = QtBind.createButton( gui, 'btnStorage_clicked', " Storage ", 595, 57) btnGuildStorage = QtBind.createButton( gui, 'btnGuildStorage_clicked', " Guild Storage ", 590, 80) btnInventory = QtBind.createButton( gui, 'btnInventory_clicked', " Inventory ", 595, 34) btnPet = QtBind.createButton( gui, 'btnPet_clicked', " Pet ", 595, 103) btnAll = QtBind.createButton( gui, 'btnAll_clicked', " All ", 595, 126) btnPagingPrev = QtBind.createButton( gui, 'btnPagingPrev_clicked', "<", 10, baseY + 215) btnPagingNext = QtBind.createButton( gui, 'btnPagingNext_clicked', ">", 130, baseY + 215) btnClearSearchBox = QtBind.createButton( gui, 'btnClearSearchBox_clicked', 'Clear', 205, baseY - 1) btnQuickSearchAdd = QtBind.createButton( gui, 'btnQuickSearchAdd_clicked', 'Add', 380, baseY - 1) btnQuickSearchRemove = QtBind.createButton( gui, 'btnQuickSearchRemove_clicked', 'Remove', 460, baseY - 1) # inputs txtBxSearch = QtBind.createLineEdit(gui, '', 50, baseY, 150, 21) # lines QtBind.createList(gui, 295, baseY - 5, 1, 670) # button events def btnStorage_clicked(): global countIn, currPage countIn = 'Storage' currPage = 0 def btnGuildStorage_clicked(): global countIn, currPage countIn = 'Guild Storage' currPage = 0 def btnInventory_clicked(): global countIn, currPage countIn = 'Inventory' currPage = 0 def btnPet_clicked(): global countIn, currPage countIn = 'Pet' currPage = 0 def btnAll_clicked(): global countIn, currPage countIn = 'All' currPage = 0 def btnPagingPrev_clicked(): global currPage currPage -= 1 if currPage < 0: currPage = 0 def btnPagingNext_clicked(): global currPage currPage += 1 if currPage >= totalPages: currPage = totalPages - 1 def btnClearSearchBox_clicked(): global currPage currPage = 0 QtBind.setText(gui, txtBxSearch, '') def btnQuickSearchAdd_clicked(): txt = QtBind.text(gui, txtBxSearch).strip() if txt.lower() not in map(str.lower, quickSearchList) and txt and len(quickSearchList) < 8: quickSearchList.append(txt) updateQuickSearchButtons() def btnQuickSearchRemove_clicked(): global quickSearchList, quickSearchDeleted txt = QtBind.text(gui, txtBxSearch).strip() i = 0 for qs in quickSearchList: if qs == txt: quickSearchList.remove(qs) i += 1 quickSearchDeleted = True updateQuickSearchButtons() # other functions def updateQuickSearchButtons(): # clear buttons from screen i = 0 for k in buttonItems: QtBind.move(gui, buttonItems[k], 3100, baseY + 33 + (i * 28)) i += 1 # display quick search buttons in order i = 0 for qs in quickSearchList: j = 0 btn = None for k in buttonItems: if i == j: btn = buttonItems[k] break j += 1 if btn is not None: QtBind.setText(gui, btn, ' {} '.format(qs)) QtBind.move(gui, btn, 310, baseY + 33 + (i * 28)) i += 1 # save saveConfig() def str_in(search, text): return search.lower() in text.lower() # create labels for x in range(pageLimit): labelItems.append(QtBind.createLabel( gui, 'None', 10, baseY + ((x + 2) * 15))) # create buttons for x in range(8): btn = 'btnQuickSearch' + str(x) buttonItems[btn] = QtBind.createButton(gui, btn + '_clicked', '', 3100, baseY + 33 + (x * 28)) func = f''' def {btn}_clicked(): global currPage btn = buttonItems['{btn}'] currPage = 0 QtBind.setText(gui, txtBxSearch, QtBind.text(gui, btn).strip()) ''' exec(func) # Called every 500ms def event_loop(): global searchText, configStamp, lastCountIn, lastPage, currPage txt = QtBind.text(gui, txtBxSearch) if searchText != txt or lastCountIn != countIn or lastPage != currPage: if lastPage == currPage: currPage = 0 countItems(countIn, currPage) searchText = txt lastCountIn = countIn lastPage = currPage # update if config is changed stamp = os.stat(getConfigPath()).st_mtime if stamp != configStamp: loadConfig() configStamp = stamp # Return the sox type as text, empty if none is found def getSoXText(servername,level): if level < 101: if servername.endswith('A_RARE'): return '^Star' elif servername.endswith('B_RARE'): return '^Moon' elif servername.endswith('C_RARE'): return '^Sun' else: if servername.endswith('A_RARE'): return '^Nova' elif servername.endswith('B_RARE'): return '^Rare' elif servername.endswith('C_RARE'): return '^Legend' elif servername.endswith('SET_A'): return '^Egy A' elif servername.endswith('SET_B'): return '^Egy B' return '' # plugin folder path def getPath(): return get_config_dir() + pName + "\\" # plugin config path def getConfigPath(): return getPath() + "data.json" # load config data def loadConfig(): global quickSearchList if os.path.exists(getConfigPath()): data = {} with open(getConfigPath(), "r") as f: try: data = json.load(f) except: pass f.close() if "QuickSearchList" in data: quickSearchList = data["QuickSearchList"] updateQuickSearchButtons() # save config data def saveConfig(): global quickSearchDeleted data = {"QuickSearchList": quickSearchList} if len(quickSearchList) == 0 and not quickSearchDeleted: return with open(getConfigPath(), "w") as f: f.write(json.dumps(data, indent=4, sort_keys=True)) f.close() quickSearchDeleted = False def countItems(countIn, page=0): global currPage, totalPages, pageLimit currPage = page clearLabels() items = [] itemCounter = {} start = 13 # for not showing weapon and set parts # get items try: if countIn == 'Storage': items = get_storage()['items'] elif countIn == 'Guild Storage': items = get_guild_storage()['items'] elif countIn == 'Inventory': items = get_inventory()['items'] elif countIn == 'Pet': pets = get_pets() if pets != None: for key in pets: pet = pets[key] if pet['type'] == 'pick': items = pet['items'] break elif countIn == 'All': # char items charItems = get_inventory()['items'] if charItems is not None: iterator = 0 for i in charItems: if iterator < start: iterator += 1 elif i is not None: items.append(i) # storage items storageItems = get_storage()['items'] if storageItems is not None: for i in storageItems: if i is not None: items.append(i) # guild storage items guildStorageItems = get_guild_storage()['items'] if guildStorageItems is not None: for i in guildStorageItems: if i is not None: items.append(i) # pet items pets = get_pets() if pets != None: for k in pets: pet = pets[k] if pet['type'] == 'pick': for i in pet['items']: if i is not None: items.append(i) except Exception as e: log('Error: ' + str(e)) clearLabels('None') return # update title QtBind.setText(gui, lblTitle, 'ITEMS (' + countIn + ')') # count items i = 0 txt = QtBind.text(gui, txtBxSearch) itemFound = False for item in items: if i < start and countIn == 'Inventory': i += 1 continue if item != None: itemFound = True level = 0 try: itemData = get_item_string(item['servername']) if itemData is not None: level = itemData['level'] except: log('err') race = '(CH)' if '_CH_' in item['servername'] else '(EU)' gender = '' if '_W_' in item['servername']: gender = '[F]' elif '_M_' in item['servername']: gender = '[M]' if str_in(txt, item['name']) or str_in(txt, item['servername']): # name = item['name'] + ' (+' + str( # item['plus']) + ')' if '_CH_' in item['servername'] or '_EU_' in item['servername'] else item['name'] name = item['name'] + ' ' + race + (' ' + gender if gender else '') + ' ' + getSoXText(item['servername'], level) + ' (+' + str(item['plus']) + ')' if '_CH_' in item['servername'] or '_EU_' in item['servername'] else item['name'] if name in itemCounter.keys(): itemCounter[name] += item['quantity'] else: itemCounter[name] = item['quantity'] i += 1 if len(itemCounter) == 0 and (len(txt) == 0 or not itemFound): clearLabels('None') # sort items currLetter = None letterCounter = 0 itemCounter = {key: itemCounter[key] for key in sorted(itemCounter.keys())} sortedItems = {} i = 0 for key in itemCounter: letter = key[0].lower() if letter != currLetter and i % pageLimit != 0: sortedItems['---' + ('-' * letterCounter)] = -1 i += 1 currLetter = letter letterCounter += 1 elif letter != currLetter: currLetter = letter sortedItems[key] = itemCounter[key] i += 1 # display items i = 0 totalPages = math.ceil(len(sortedItems) / pageLimit) sortedItems = sliceDict(sortedItems, page * pageLimit, len(labelItems)) for key in sortedItems: count = sortedItems[key] itemString = key if count == -1 else key + ': ' + str(count) + '' QtBind.setText(gui, labelItems[i], '' + itemString + '') i += 1 # paging QtBind.setText(gui, lblPaging, str(page + 1) + '/' + str(totalPages)) def sliceDict(dict, start, length=0): i = 0 temp = {} for k in dict: if i >= start and (length == 0 or i < start + length): temp[k] = dict[k] i += 1 return temp def clearLabels(text=''): global labelItems for item in labelItems: QtBind.setText(gui, item, text) ### COMMUNICATION WITH OTHER CHARACTERS IN LOCAL ### #################################################### # check plugin folder is exists if not os.path.exists(getPath()): # Creating plugin folder os.makedirs(getPath()) # load config loadConfig() log('Plugin: ['+pName+' v'+pVersion+'] successfully loaded') # use it in conditions def isProfileWizz(): return get_profile() == 'wizz' def isProfileBard(): return get_profile() == 'bard'