def parseMount(title, attributes, c, mountStuff, getURL): name = title if 'name' in attributes: name = attributes['name'] speed = 10 if 'speed' in attributes: speed = int(attributes['speed']) url = "http://tibia.wikia.com/wiki/%s" % (title.replace(' ', '_')) image = getImage(url, getURL, imageRegex, crop_image) if image == None: url = "http://tibia.wikia.com/wiki/File:%s.gif" % (title.replace(' ', '_')) image = getImage(url, getURL, imageRegex2, crop_image) if image == None: print('failed to get image for item', title) return False c.execute('INSERT INTO Mounts (title, name, tameitemid, tamecreatureid, speed, tibiastore, image) VALUES (?,?,?,?,?,?,?)', (title, name, None, None, speed, False, image)) mountid = c.lastrowid if 'taming_method' in attributes: mountStuff[mountid] = list() index = 0 while True: match = bracketRegex.search(attributes['taming_method'][index:]) if match == None: break mountStuff[mountid].append(match.groups()[0]) index += match.end() return True
def parseNPC(title, attributes, c, spells, getURL): name = title if 'name' in attributes: name = attributes['name'] posx = None if 'posx' in attributes: try: posx = convert_x(attributes['posx']) except: pass posy = None if 'posy' in attributes: try: posy = convert_y(attributes['posy']) except: pass posz = None if 'posz' in attributes: try: posz = int(attributes['posz']) except: pass city = None if 'city' in attributes: city = attributes['city'].lower() if city == None: return False job = None if 'job2' in attributes: job = attributes['job2'] if 'job' in attributes and (job == None or 'guild leader' in attributes['job'].lower()): job = attributes['job'] url = "http://tibia.wikia.com/wiki/%s" % (title.replace(' ', '_')) image = getImage(url, getURL, imageRegex) if image == None or image == False: url = "http://tibia.wikia.com/wiki/File:%s.gif" % (title.replace(' ', '_')) image = getImage(url, getURL, imageRegex2) if image == None or image == False: print('failed to get image for npc', title) return False c.execute('INSERT INTO NPCs (title,name, city, job, x, y, z, image) VALUES (?,?,?,?,?,?,?,?)', (title,name, city, job, posx, posy, posz, image)) npcid = c.lastrowid if 'sells' in attributes and 'teaches' in attributes['sells'].lower(): spells[npcid] = parseSpells(attributes['sells']) if 'notes' in attributes: match = re.search('{{Transport([^}]+)', attributes['notes']) if match != None: splits = match.groups()[0].split('|') for spl in splits: spl = spl.strip() if ',' in spl: splits2 = spl.split(',') dest = splits2[0].strip() notes = "" if ';' in splits2[1]: splits3 = splits2[1].split(';') splits2[1] = splits3[0] notes = splits3[1].replace('[', '').replace(']', '') try: cost = int(splits2[1].strip()) except: continue c.execute('INSERT INTO NPCDestinations(npcid, destination, cost, notes) VALUES (?,?,?,?)', (npcid, dest, cost, notes)) return True
def parseObject(title, attributes, c, getURL): name = title if 'actualname' in attributes: name = attributes['actualname'] elif 'name' in attributes: name = attributes['name'] c.execute('SELECT title FROM WorldObjects WHERE LOWER(title)=?', (title.lower(),)) results = c.fetchall() if len(results) > 0: print('object already exists', title) return False url = "http://tibia.wikia.com/wiki/%s" % (title.replace(' ', '_')) image = getImage(url, getURL, imageRegex) if image == None or image == False: url = "http://tibia.wikia.com/wiki/File:%s.gif" % (title.replace(' ', '_')) image = getImage(url, getURL, imageRegex2) if image == None or image == False: print('failed to get image for object', title) return False c.execute('INSERT INTO WorldObjects(title, name, image) VALUES (?,?,?)', (title, name, image)) return True
def parseObject(title, attributes, c, getURL): name = title if "actualname" in attributes: name = attributes["actualname"] elif "name" in attributes: name = attributes["name"] c.execute("SELECT title FROM WorldObjects WHERE LOWER(title)=?", (title.lower(),)) results = c.fetchall() if len(results) > 0: print("object already exists", title) return False url = "http://tibia.wikia.com/wiki/%s" % (title.replace(" ", "_")) image = getImage(url, getURL, imageRegex) if image == None or image == False: url = "http://tibia.wikia.com/wiki/File:%s.gif" % (title.replace(" ", "_")) image = getImage(url, getURL, imageRegex2) if image == None or image == False: print("failed to get image for object", title) return False c.execute("INSERT INTO WorldObjects(title, name, image) VALUES (?,?,?)", (title, name, image)) return True
def parseItem(title, attributes, c, buyitems, sellitems, currencymap, getURL): npcValue = None if 'npcvalue' in attributes: try: npcValue = int(attributes['npcvalue']) except: pass if (npcValue == None or npcValue == 0) and 'npcprice' in attributes: try: npcValue = int(attributes['npcprice']) except: pass actualValue = None if 'value' in attributes: match = numberRegex.search(attributes['value']) if match != None: actualValue = int(match.groups()[0].replace(',', '').replace('.', '')) npcPrice = None if 'npcprice' in attributes: try: npcPrice = int(attributes['npcprice']) if actualValue != None and npcPrice > 0 and actualValue > npcPrice: actualValue = npcPrice except: pass if npcValue != None and (actualValue == None or npcValue > actualValue): actualValue = npcValue name = title if 'actualname' in attributes and len(attributes['actualname']) > 0: name = attributes['actualname'] capacity = None if 'weight' in attributes: try: capacity = float(attributes['weight']) except: pass stackable = False if 'stackable' in attributes: stackable = 'yes' in attributes['stackable'].strip().lower() category = None if 'primarytype' in attributes: category = attributes['primarytype'] elif 'itemclass' in attributes: category = attributes['itemclass'] # tibia wiki uses some function to get the image url rather than storing it explicitly, and I don't really want to bother to decipher it url = "http://tibia.wikia.com/wiki/%s" % (title.replace(' ', '_')) itemHTML = getURL(url, True) if itemHTML == None: return False image = getImage(url, getURL, imageRegex, properly_crop_item) if image == None or image == False: url = "http://tibia.wikia.com/wiki/File:%s.gif" % (title.replace( ' ', '_')) image = getImage(url, getURL, imageRegex2, properly_crop_item) if image == None or image == False: print('failed to get image for item', title) match = lookRegex.search(itemHTML) look_text = None if match != None: look_text = match.groups()[0] look_text = look_text.replace(' ', ' ').replace('\n', ' ').replace( '.', '. ').replace('. ', '. ') look_text = re.sub(r'[.] (\d)', '.\g<1>', look_text).strip() while True: match = htmlTagRegex.search(look_text) if match == None: break look_text = look_text[:match.start()] + look_text[match.end():] convert_to_gold, discard = False, False gold_ratio = max( 0 if npcValue == None else npcValue, 0 if actualValue == None else actualValue) / (1 if capacity == None or capacity == 0 else capacity) if gold_ratio < 10: discard = True if gold_ratio < 20 and stackable == False: convert_to_gold = True else: convert_to_gold = False c.execute( 'INSERT INTO Items (title,name, vendor_value, actual_value, capacity, stackable, image, category, discard, convert_to_gold, look_text) VALUES (?,?,?,?,?,?,?,?,?,?,?)', (title, name, npcValue, actualValue, capacity, stackable, image, category, discard, convert_to_gold, look_text)) itemid = c.lastrowid if 'buyfrom' in attributes: buyitems[itemid] = dict() npcs = attributes['buyfrom'].split(',') for n in npcs: npc = n if npc == '' or npc == '-' or npc == '--': continue value = npcPrice if ';' in npc: npc = npc.split(';')[0] if ':' in npc: token = npc.split(':')[1].strip() npc = npc.split(':')[0] try: value = math.ceil(float(token)) except: match = re.search('\\[\\[([^]]+)\\]\\]', token) if match == None: continue currencymap[itemid] = match.groups()[0] match = numberRegex.search(token) if match == None: continue value = float(match.groups()[0]) if value == None: continue buyitems[itemid][npc.strip()] = value if 'sellto' in attributes: sellitems[itemid] = dict() npcs = attributes['sellto'].split(',') for n in npcs: npc = n if npc == '' or npc == '-' or npc == '--': continue value = npcValue if ';' in npc: npc = npc.split(';')[0] if ':' in npc: value = math.ceil(float(npc.split(':')[1].strip())) npc = npc.split(':')[0] if value == None: continue sellitems[itemid][npc.strip()] = value if 'vocrequired' in attributes and len( attributes['vocrequired'].strip()) > 1: attributes['vocrequired'] = attributes['vocrequired'].replace( 'knights', 'k').replace('druids', 'd').replace('sorcerers', 's').replace('paladins', 'p').replace(' and ', '+') c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Voc', attributes['vocrequired'].strip())) if 'plural' in attributes: plural = attributes['plural'].strip().lower() if len(plural) > 2: f = open('pluralMap.txt', 'a') f.write('%s=%s\n' % (plural, name.strip().lower())) f.close() if 'damagetype' in attributes and len( attributes['damagetype'].strip()) > 1: c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Type', attributes['damagetype'].strip())) if 'attrib' in attributes and len(attributes['attrib'].strip()) > 1: attrib = attributes['attrib'].strip().replace("fighting", "").replace( "level", "").replace("[", "").replace("]", "").replace("faster regeneration", "regen +1") c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Attrib', attrib)) if 'armor' in attributes and len(attributes['armor'].strip()) > 0: try: armor = int(attributes['armor'].strip()) c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Arm', str(armor))) except: print(name) print(attributes['armor']) exit(1) pass if 'attack' in attributes and len(attributes['attack'].strip()) > 0: try: attack = int(attributes['attack'].strip()) c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Atk', str(attack))) except: attack = 0 for atk in re.findall('[0-9]+', attributes['attack']): attack += int(atk) if attack == 0: print(name) print(attributes['attack']) exit(1) pass else: c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Atk', str(attack))) if 'defense' in attributes and len(attributes['defense'].strip()) > 0: try: defense = int(attributes['defense'].strip()) if 'defensemod' in attributes and len( attributes['defensemod'].strip()) > 1: defense = str( defense) + ' (' + attributes['defensemod'].strip() + ')' c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Def', str(defense))) except: print(name) print(attributes['defense']) exit(1) pass if 'levelrequired' in attributes and len( attributes['levelrequired'].strip()) > 0: try: levelrequired = int(attributes['levelrequired'].strip()) c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Level', str(levelrequired))) except: print(name) print(attributes['levelrequired']) exit(1) if 'damage' in attributes and len(attributes['damage'].strip()) > 0: try: damage = int(attributes['damage'].strip()) c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Atk', str(damage))) except: try: spl = attributes['damage'].split('-') damage = int((int(spl[0].strip()) + int(spl[1].strip())) / 2) c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Atk', str(damage))) except: pass if 'range' in attributes and len(attributes['range'].strip()) > 0: try: rng = int(attributes['range'].strip()) c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Range', str(rng))) except: pass if 'atk_mod' in attributes and len(attributes['atk_mod'].strip()) > 0: c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Atk+', attributes['atk_mod'].strip())) if 'hit_mod' in attributes and len(attributes['atk_mod'].strip()) > 0: c.execute( 'INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Hit+', attributes['hit_mod'].strip())) return True
def parseCreature(title, attributes, c, creaturedrops, getURL): if title in passList: return False name = title if 'actualname' in attributes and len(attributes['actualname']) > 0: name = formatTitle(attributes['actualname']) elif 'name' in attributes and len(attributes['name']) > 0: name = formatTitle(attributes['name']) hp = getInteger(attributes, 'hp') exp = None if 'exp' in attributes: try: exp = int(attributes['exp']) except: pass summon = None if 'summon' in attributes: try: summon = int(attributes['summon']) except: pass illusionable = getBoolean(attributes, 'illusionable') pushable = getBoolean(attributes, 'pushable') pushes = getBoolean(attributes, 'pushes') paralysable = getBoolean(attributes, 'paraimmune') senseinvis = getBoolean(attributes, 'senseinvis', True) armor = getInteger(attributes, 'armor') maxdmg = getMaxInteger(attributes, 'maxdmg') physical = getInteger(attributes, 'physicalDmgMod') holy = getInteger(attributes, 'holyDmgMod') death = getInteger(attributes, 'deathDmgMod') fire = getInteger(attributes, 'fireDmgMod') energy = getInteger(attributes, 'energyDmgMod') ice = getInteger(attributes, 'iceDmgMod') earth = getInteger(attributes, 'earthDmgMod') drown = getInteger(attributes, 'drownDmgMod') lifedrain = getInteger(attributes, 'hpDrainDmgMod') speed = getInteger(attributes, 'speed') boss = False if 'isboss' in attributes and attributes['isboss'].lower().strip( ) == 'yes': boss = True abilities = None if 'abilities' in attributes: # first take care of [[Fire Rune||Great Fireball]] => Great Fireball b = re.sub(r'\[\[[^]|]+\|([^]]+)\]\]', '\g<1>', attributes['abilities']) # then take care of [[Fire Rune]] => Fire Rune b = re.sub(r'\[\[([^]]+)\]\]', '\g<1>', b) # sometimes there are links in single brackets [http:www.link.com] => remove htem b = re.sub(r'\[[^]]+\]', '', b) # if there are brackets without numbers, remove them (maybe not necessary) b = re.sub(r'\(([^0-9]+)\)', '', b) # replace double spaces with single spaces b = b.replace(' ', ' ') # if there are commas in brackets (300-500, Fire Damage) => replace the comma with a semicolon (for later splitting purposes) abilities = re.sub(r'(\([^,)]+)\,([^)]+\))', '\g<1>;\g<2>', b) url = "http://tibia.wikia.com/wiki/%s" % (title.replace(' ', '_')) image = getImage(url, getURL, imageRegex, crop_image) if image == None or image == False: url = "http://tibia.wikia.com/wiki/File:%s.gif" % (title.replace( ' ', '_')) image = getImage(url, getURL, imageRegex2, crop_image) if image == None or image == False: print('failed to get image for creature', title) # add stuff to database c.execute( 'INSERT INTO Creatures (title,name,health,experience,maxdamage,summon,illusionable,pushable,pushes,physical,holy,death,fire,energy,ice,earth,drown,lifedrain,paralysable,senseinvis,image,abilities,speed,armor,boss) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', (title, name, hp, exp, maxdmg, summon, illusionable, pushable, pushes, physical, holy, death, fire, energy, ice, earth, drown, lifedrain, paralysable, senseinvis, image, abilities, speed, armor, boss)) creatureid = c.lastrowid creaturedrops[creatureid] = dict() # for some reason loot statistics are not in the xml file, so we get it from the website url = 'http://tibia.wikia.com/wiki/Loot_Statistics:%s' % title.replace( ' ', '_') stats = getURL(url, True) if stats != None: loot_stats = list() current_index = 0 while True: match = lootListRegex.search(stats[current_index:]) if match == None: break index = match.end() match = lootListRegex.search(stats[current_index + index:]) if match == None: endindex = len(stats) - current_index else: endindex = index + match.start() kill_count = 0 match = re.search( '([0-9]+) kills', stats[current_index + index:current_index + endindex]) if match != None: kill_count = int(match.groups()[0]) list.append( loot_stats, [current_index + index, current_index + endindex, kill_count]) current_index = current_index + endindex lootdrops = dict() killcount = dict() score = dict() for i in range(len(loot_stats)): index = loot_stats[i][0] endindex = loot_stats[i][1] kills = loot_stats[i][2] lootdrops[i] = dict() killcount[i] = kills bag = False highpercentage = False while True: match = wikiURLRegex.search(stats[index:endindex]) if match == None: break item_name = filterItemName(match.groups()[0]).lower() # creatures don't drop bags, but they used to in the past # if there is a bag in the creature kills, we know it's old startindex = index index = index + match.end() if index > endindex or item_name == "loot": break match = lootCountRegex.search(stats[startindex:index]) if match == None: mindrop = 1 maxdrop = 1 else: mindrop = int(match.groups()[0]) maxdrop = int(match.groups()[1]) match = lootChanceRegex.search(stats[index:]) if match == None: break percentage = float(match.groups()[0]) if percentage > 100: highpercentage = True index = index + match.end() if item_name.strip() == "bag": bag = True else: lootdrops[i][item_name] = (percentage, mindrop, maxdrop) score[i] = 0 if bag else ( 1 if highpercentage else len(lootdrops[i])) maxdict = dict() maxkey = "" killcount[maxkey] = -1 score[maxkey] = -1 # pick the loot statistics with the most items for key in lootdrops.keys(): if score[key] > score[maxkey]: maxdict = lootdrops[key] maxkey = key elif score[key] == score[ maxkey] and killcount[key] > killcount[maxkey]: # if the items are equal, pick the one with the highest kills maxdict = lootdrops[key] maxkey = key creaturedrops[creatureid] = maxdict # read the dropped items from the 'loot' attribute if 'loot' in attributes: lootItems = [ filterItemName(x).lower() for x in parseLoot(attributes['loot']) ] for item in lootItems: if item not in creaturedrops[creatureid]: creaturedrops[creatureid][item] = (None, 1, 1) return True
def parseItem(title, attributes, c, buyitems, sellitems, currencymap, durationMap, getURL): npcValue = None if 'npcvalue' in attributes: try: npcValue = int(attributes['npcvalue']) except: pass if (npcValue == None or npcValue == 0) and 'npcprice' in attributes: try: npcValue = int(attributes['npcprice']) except: pass actualValue = None if 'value' in attributes: match = numberRegex.search(attributes['value']) if match != None: actualValue = int(match.groups()[0].replace(',','').replace('.','')) npcPrice = None if 'npcprice' in attributes: try: npcPrice = int(attributes['npcprice']) if actualValue != None and npcPrice > 0 and actualValue > npcPrice: actualValue = npcPrice except: pass if npcValue != None and (actualValue == None or npcValue > actualValue): actualValue = npcValue name = title if 'actualname' in attributes and len(attributes['actualname']) > 0: name = attributes['actualname'] capacity = None if 'weight' in attributes: try: capacity = float(attributes['weight']) except: pass stackable = False if 'stackable' in attributes: stackable = 'yes' in attributes['stackable'].strip().lower() category = None if 'primarytype' in attributes: category = attributes['primarytype'] elif 'itemclass' in attributes: category = attributes['itemclass'] duration, itemcost, itemcostcount = (None, None, None) durationText = None if title.lower() in consumableMap: tpl = consumableMap[title.lower()] durationText = tpl[0] itemcostcount = tpl[1] itemcost = tpl[2] elif 'duration' in attributes: durationText = attributes['duration'] itemcost = title itemcostcount = 1 if durationText != None: match = numberRegex.search(durationText) if match != None: duration = float(match.groups()[0]) if duration != None: if 'minute' in durationText: duration *= 60 elif 'hour' in durationText: duration *= 3600 if duration != None: durationMap[title] = (duration, itemcost, itemcostcount) # tibia wiki uses some function to get the image url rather than storing it explicitly, and I don't really want to bother to decipher it url = "http://tibia.wikia.com/wiki/%s" % (title.replace(' ', '_')) itemHTML = getURL(url, True) if itemHTML == None: return False image = getImage(url, getURL, imageRegex, properly_crop_item) if image == None or image == False: url = "http://tibia.wikia.com/wiki/File:%s.gif" % (title.replace(' ', '_')) image = getImage(url, getURL, imageRegex2, properly_crop_item) if image == None or image == False: print('failed to get image for item', title) match = lookRegex.search(itemHTML) look_text = None if match != None: look_text = match.groups()[0] look_text = look_text.replace(' ', ' ').replace('\n', ' ').replace('.', '. ').replace('. ', '. ') look_text = re.sub(r'[.] (\d)', '.\g<1>', look_text).strip() while True: match = htmlTagRegex.search(look_text) if match == None: break look_text = look_text[:match.start()] + look_text[match.end():] convert_to_gold, discard = False, False gold_ratio = max(0 if npcValue == None else npcValue, 0 if actualValue == None else actualValue) / (1 if capacity == None or capacity == 0 else capacity) if gold_ratio < 10: discard = True if gold_ratio < 20 and stackable == False: convert_to_gold = True else: convert_to_gold = False c.execute('INSERT INTO Items (title,name, vendor_value, actual_value, capacity, stackable, image, category, discard, convert_to_gold, look_text) VALUES (?,?,?,?,?,?,?,?,?,?,?)', (title,name, npcValue, actualValue, capacity, stackable, image, category, discard, convert_to_gold, look_text)) itemid = c.lastrowid if 'itemid' in attributes: splits = attributes['itemid'].split(',') for item in splits: try: tibiaid = int(item.strip()) c.execute('INSERT INTO ItemIDMap (tibiaid, itemid) VALUES (?,?)', (tibiaid, itemid)) except: pass if 'buyfrom' in attributes: buyitems[itemid] = dict() npcs = attributes['buyfrom'].split(',') for n in npcs: npc = n if npc == '' or npc == '-' or npc == '--': continue value = npcPrice if ';' in npc: npc = npc.split(';')[0] if ':' in npc: token = npc.split(':')[1].strip() npc = npc.split(':')[0] try: value = math.ceil(float(token)) except: match = re.search('\\[\\[([^]]+)\\]\\]', token) if match == None: continue currencymap[itemid] = match.groups()[0] match = numberRegex.search(token) if match == None: continue value = float(match.groups()[0]) if value == None: continue buyitems[itemid][npc.strip()] = value if 'sellto' in attributes: sellitems[itemid] = dict() npcs = attributes['sellto'].split(',') for n in npcs: npc = n if npc == '' or npc == '-' or npc == '--': continue value = npcValue if ';' in npc: npc = npc.split(';')[0] if ':' in npc: value = math.ceil(float(npc.split(':')[1].strip())) npc = npc.split(':')[0] if value == None: continue sellitems[itemid][npc.strip()] = value if 'vocrequired' in attributes and len(attributes['vocrequired'].strip()) > 1: attributes['vocrequired'] = attributes['vocrequired'].replace('knights', 'k').replace('druids', 'd').replace('sorcerers', 's').replace('paladins', 'p').replace(' and ','+') c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Voc', attributes['vocrequired'].strip())) if 'plural' in attributes: plural = attributes['plural'].strip().lower() if len(plural) > 2: f = open('pluralMap.txt', 'a') f.write('%s=%s\n' % (plural, name.strip().lower())) f.close() if 'damagetype' in attributes and len(attributes['damagetype'].strip()) > 1: c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Type', attributes['damagetype'].strip())) if 'attrib' in attributes and len(attributes['attrib'].strip()) > 1: attrib = attributes['attrib'].strip().replace("fighting", "").replace("level", "").replace("[","").replace("]","").replace("faster regeneration", "regen +1") c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Attrib', attrib)) if 'armor' in attributes and len(attributes['armor'].strip()) > 0: try: armor = int(attributes['armor'].strip()) c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Arm', str(armor))) except: print(name) print(attributes['armor']) exit(1) pass if 'attack' in attributes and len(attributes['attack'].strip()) > 0: try: attack = int(attributes['attack'].strip()) c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Atk', str(attack))) except: attack = 0 for atk in re.findall('[0-9]+', attributes['attack']): attack += int(atk) if attack == 0: print(name) print(attributes['attack']) exit(1) pass else: c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Atk', str(attack))) if 'defense' in attributes and len(attributes['defense'].strip()) > 0: try: defense = int(attributes['defense'].strip()) if 'defensemod' in attributes and len(attributes['defensemod'].strip()) > 1: defense = str(defense) + ' (' + attributes['defensemod'].strip() + ')' c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Def', str(defense))) except: print(name) print(attributes['defense']) exit(1) pass if 'levelrequired' in attributes and len(attributes['levelrequired'].strip()) > 0: try: levelrequired = int(attributes['levelrequired'].strip()) c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Level', str(levelrequired))) except: print(name) print(attributes['levelrequired']) exit(1) if 'damage' in attributes and len(attributes['damage'].strip()) > 0: try: damage = int(attributes['damage'].strip()) c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Atk', str(damage))) except: try: spl = attributes['damage'].split('-') damage = int((int(spl[0].strip()) + int(spl[1].strip())) / 2) c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Atk', str(damage))) except: pass if 'range' in attributes and len(attributes['range'].strip()) > 0: try: rng = int(attributes['range'].strip()) c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Range', str(rng))) except: pass if 'atk_mod' in attributes and len(attributes['atk_mod'].strip()) > 0: c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Atk+', attributes['atk_mod'].strip())) if 'hit_mod' in attributes and len(attributes['atk_mod'].strip()) > 0: c.execute('INSERT INTO ItemProperties(itemid, property, value) VALUES (?,?,?)', (itemid, 'Hit+', attributes['hit_mod'].strip())) return True
def parseCreature(title, attributes, c, creaturedrops, getURL): if title in passList: return False name = title if 'actualname' in attributes and len(attributes['actualname']) > 0: name = formatTitle(attributes['actualname']) elif 'name' in attributes and len(attributes['name']) > 0: name = formatTitle(attributes['name']) hp = getInteger(attributes, 'hp') exp = None if 'exp' in attributes: try: exp = int(attributes['exp']) except: pass summon = None if 'summon' in attributes: try: summon = int(attributes['summon']) except: pass illusionable = getBoolean(attributes,'illusionable') pushable = getBoolean(attributes,'pushable') pushes = getBoolean(attributes,'pushes') paralysable = getBoolean(attributes,'paraimmune') senseinvis = getBoolean(attributes,'senseinvis', True) armor = getInteger(attributes,'armor') maxdmg = getMaxInteger(attributes,'maxdmg') physical = getInteger(attributes,'physicalDmgMod') holy = getInteger(attributes,'holyDmgMod') death = getInteger(attributes,'deathDmgMod') fire = getInteger(attributes,'fireDmgMod') energy = getInteger(attributes,'energyDmgMod') ice = getInteger(attributes,'iceDmgMod') earth = getInteger(attributes,'earthDmgMod') drown = getInteger(attributes,'drownDmgMod') lifedrain = getInteger(attributes,'hpDrainDmgMod') speed = getInteger(attributes,'speed') boss = False if 'isboss' in attributes and attributes['isboss'].lower().strip() == 'yes': boss = True abilities = None if 'abilities' in attributes: # first take care of [[Fire Rune||Great Fireball]] => Great Fireball b = re.sub(r'\[\[[^]|]+\|([^]]+)\]\]', '\g<1>', attributes['abilities']) # then take care of [[Fire Rune]] => Fire Rune b = re.sub(r'\[\[([^]]+)\]\]', '\g<1>', b) # sometimes there are links in single brackets [http:www.link.com] => remove htem b = re.sub(r'\[[^]]+\]', '', b) # if there are brackets without numbers, remove them (maybe not necessary) b = re.sub(r'\(([^0-9]+)\)', '', b) # replace double spaces with single spaces b = b.replace(' ', ' ') # if there are commas in brackets (300-500, Fire Damage) => replace the comma with a semicolon (for later splitting purposes) abilities = re.sub(r'(\([^,)]+)\,([^)]+\))', '\g<1>;\g<2>', b) url = "http://tibia.wikia.com/wiki/%s" % (title.replace(' ', '_')) image = getImage(url, getURL, imageRegex, crop_image) if image == None or image == False: url = "http://tibia.wikia.com/wiki/File:%s.gif" % (title.replace(' ', '_')) image = getImage(url, getURL, imageRegex2, crop_image) if image == None or image == False: print('failed to get image for creature', title) return False if physical == None: print('pass', title) # add stuff to database c.execute('INSERT INTO Creatures (title,name,health,experience,maxdamage,summon,illusionable,pushable,pushes,physical,holy,death,fire,energy,ice,earth,drown,lifedrain,paralysable,senseinvis,image,abilities,speed,armor,boss) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', (title,name, hp, exp, maxdmg, summon, illusionable, pushable, pushes, physical, holy, death, fire, energy, ice, earth, drown, lifedrain, paralysable, senseinvis, image, abilities, speed, armor,boss)) creatureid = c.lastrowid creaturedrops[creatureid] = dict() # for some reason loot statistics are not in the xml file, so we get it from the website url = 'http://tibia.wikia.com/wiki/Loot_Statistics:%s' % title.replace(' ','_') stats = getURL(url, True) if stats != None: loot_stats = list() current_index = 0 while True: match = lootListRegex.search(stats[current_index:]) if match == None: break index = match.end() match = lootListRegex.search(stats[current_index + index:]) if match == None: endindex = len(stats) - current_index else: endindex = index + match.start() kill_count = 0 match = re.search('([0-9]+) kills', stats[current_index + index:current_index + endindex]) if match != None: kill_count = int(match.groups()[0]) list.append(loot_stats, [current_index + index, current_index + endindex, kill_count]) current_index = current_index + endindex lootdrops = dict() killcount = dict() score = dict() for i in range(len(loot_stats)): index = loot_stats[i][0] endindex = loot_stats[i][1] kills = loot_stats[i][2] lootdrops[i] = dict() killcount[i] = kills bag = False highpercentage = False while True: match = wikiURLRegex.search(stats[index:endindex]) if match == None: break item_name = filterItemName(match.groups()[0]).lower() # creatures don't drop bags, but they used to in the past # if there is a bag in the creature kills, we know it's old startindex = index index = index + match.end() if index > endindex or item_name == "loot": break match = lootCountRegex.search(stats[startindex:index]) if match == None: mindrop = 1 maxdrop = 1 else: mindrop = int(match.groups()[0]) maxdrop = int(match.groups()[1]) match = lootChanceRegex.search(stats[index:]) if match == None: break percentage = float(match.groups()[0]) if percentage > 100: highpercentage = True index = index + match.end() if item_name.strip() == "bag": bag = True else: lootdrops[i][item_name] = (percentage, mindrop, maxdrop) score[i] = 0 if bag else (1 if highpercentage else len(lootdrops[i])) maxdict = dict() maxkey = "" killcount[maxkey] = -1 score[maxkey] = -1 # pick the loot statistics with the most items for key in lootdrops.keys(): if score[key] > score[maxkey]: maxdict = lootdrops[key] maxkey = key elif score[key] == score[maxkey] and killcount[key] > killcount[maxkey]: # if the items are equal, pick the one with the highest kills maxdict = lootdrops[key] maxkey = key creaturedrops[creatureid] = maxdict # read the dropped items from the 'loot' attribute if 'loot' in attributes: lootItems = [filterItemName(x).lower() for x in parseLoot(attributes['loot'])] for item in lootItems: if item not in creaturedrops[creatureid]: creaturedrops[creatureid][item] = (None, 1, 1) return True