def handlepage(socket, packet): item = wolfpack.finditem(packet.getint(3)) if not item: console.log(LOG_ERROR, "Client tried to update non existing book %x." % (packet.getint(3))) return 1 page = packet.getshort(9) linecount = packet.getshort(11) # A page was requested if linecount == -1: if item.hastag('pages'): pages = int(item.gettag('pages')) else: pages = 64 if page > pages or page == 0: return if item.hastag('page%u' % page): content = item.gettag('page%u' % page).split("\n") else: content = [] sendPage(socket, item.serial, page) # The client wants to update the page. else: if item.hastag('protected'): socket.sysmessage('This book is read only.') return 1 if item.hastag('pages'): pages = int(item.gettag('pages')) else: pages = 64 # Invalid page if page > pages or page < 1: socket.log("Client tried to update invalid page %d of book 0x%x.\n" % (page, item.serial)) return 1 offset = 13 lines = [] for i in range(0, linecount): line = packet.getascii(offset, 0) offset += len(line) + 1 lines.append(unicode(line, 'utf-8')) content = "\n".join(lines) if not content or len(content.strip()) == 0: item.deltag('page%u' % page) return 1 item.settag('page%u' % page, content) item.resendtooltip() return 1
def onUpdateDatabase(current, version): # Find the update table for the database driver in use driver = database.driver(WORLD) if driver == 'mysql': updates = MYSQL_UPDATES elif driver == 'sqlite': updates = SQLITE_UPDATES else: console.log(LOG_ERROR, "Unknown database driver: %s.\n" % driver) return False for i in range(version, current): # No update for this version available if not updates.has_key(i): console.log(LOG_ERROR, "No update available for database version %u.\n" % i) return False console.log(LOG_MESSAGE, "Updating database from version %u to %u.\n" % (i, i+1)) try: if not updates[i](): return False except Exception, e: console.log(LOG_ERROR, str(e) + "\n") return False wolfpack.setoption('db_version', str(i + 1)) try: if driver == 'mysql': database.execute("REPLACE INTO `settings` VALUES('db_version', '%u');" % (i + 1)) elif driver == 'sqlite': database.execute("REPLACE INTO settings VALUES('db_version', '%u');" % (i + 1)) except Exception, e: console.log(LOG_WARNING, "Unable to update database version to %u:\n%s\n" % (i + 1, str(e)))
def updatebook(socket, packet): item = wolfpack.finditem(packet.getint(3)) if not item: console.log(LOG_ERROR, "Client tried to update non existing book %x." % (packet.getint(3))) return 1 title_length = packet.getshort(11) title = "" for i in range(0, title_length): byte = packet.getbyte(13 + i) if byte > 0: title += chr(byte) title = unicode(title, 'utf-8') author_length = packet.getshort(13 + title_length) author = "" for i in range(0, author_length): byte = packet.getbyte(15 + title_length + i) if byte > 0: author += chr(byte) author = unicode(author, 'utf-8') if item.hastag('protected'): char.message('This book is read only.') return 1 if len(author) == 0: item.deltag('author') else: item.settag('author', author) item.name = title item.resendtooltip() return 1
def dropitem(item, char, container): item.decay = True # Make SURE the item decays item.movable = 1 # Also make sure the item is movable console.log( LOG_MESSAGE, "Dropped item 0x%x (%s, %u) for npc 0x%x.\n" % (item.serial, item.baseid, item.amount, char.serial)) if container: if not utilities.tocontainer(item, container): item.update() else: items = wolfpack.items(char.pos.x, char.pos.y, char.pos.map, 0) for stackable in items: if stackable.pos.z == item.pos.z: if item.canstack(stackable): # We can completely stack the item if stackable.amount + item.amount <= 65535: stackable.amount += item.amount stackable.update() item.delete() return item.moveto(char.pos) item.update()
def checkRestockInventory(self, vendor, force = False): # If the inventory check is not forced, # see if the last check was performed more than an hour ago if not force: vendor_magic = vendor.gettag('magic') if vendor_magic == magic: return restock = vendor.itemonlayer(LAYER_NPCRESTOCK) if restock: restock.delete() # Delete the old restock container restock = self.getRestockContainer(vendor) # Create a new restock container # Recreate the content from our buyitems array for i in range(0, len(self.buylist)): dispitem = self.buylist[i].createDisplayItem() # Try to create a display item # Unable to create display item if not dispitem: console.log(LOG_ERROR, "Unable to create display item for buyitem at index %u for vendor 0x%x.\n" % (i, vendor.serial)) continue dispitem.settag('buyitemindex', i) # Store the index of the buyitem that created the dispitem restock.additem(dispitem) # Add the dispitem to the restock container # Once the check has been completed, save the vendor magic vendor.settag('magic', magic)
def onLoad(): # Send a message to the log console.log(LOG_MESSAGE, "Starting shard status page thread.\n") # Create the worker thread global processthread processthread = ProcessThread() processthread.start() return
def updateacctversion(version, driver): try: if driver == 'mysql': database.execute("REPLACE INTO `settings` VALUES('db_version', '%u');" % version) else: database.execute("REPLACE INTO settings VALUES('db_version', '%u');" % version) except Exception, e: console.log(LOG_WARNING, "Unable to update account database version to %u:\n%s\n" % (i + 1, str(e)))
def startElement(self, name, atts): if name == "item": self.itemid = str(atts.getValue("id")) if "hue" in atts: self.hue = int(hex2dec(str(atts.getValue("hue")))) else: self.hue = 0 if "amount" in atts: self.amount = int(atts.getValue("amount")) else: self.amount = 0 self.statements = [] elif name == "attribute": type = "str" if "type" in atts: type = str(atts.getValue("type")) if "value" in atts and "key" in atts: self.statements.append( str(atts.getValue("key")) + "," + type + "," + str(atts.getValue("value"))) elif name == "pos": if int(hex2dec(self.itemid)) >= 0x4000: item = wolfpack.addmulti("%x" % hex2dec(self.itemid)) else: item = wolfpack.additem("%x" % hex2dec(self.itemid)) if not item or item == None: return if self.hue > 0: item.color = self.hue if self.amount > 0: item.amount = self.amount for p in self.statements: parts = p.split(",") if hasattr(item, parts[0]): if parts[1] == "str": value = parts[2] elif parts[1] == "int": value = int(parts[2]) setattr(item, parts[0], value) x = int(atts.getValue("x")) y = int(atts.getValue("y")) z = int(atts.getValue("z")) map = int(atts.getValue("map")) item.moveto(x, y, z, map) item.movable = 3 # not movable item.decay = 0 # no decay item.update() elif name == "include": path = atts.getValue("file") if not os.path.isfile(path): console.log(LOG_ERROR, tr("File '%s' not found.\n") % (path)) return parser = xml.sax.make_parser() handler = DecorationHandler() parser.setContentHandler(handler) parser.parse(path)
def loadMenu(id, parent = None): definition = wolfpack.getdefinition(WPDT_MENU, id) if not definition: if parent: console.log(LOG_ERROR, "Unknown submenu %s in menu %s.\n" % (id, parent.id)) else: console.log(LOG_ERROR, "Unknown menu: %s.\n" % id) return name = definition.getattribute('name', '') menu = MasonryMenu(id, parent, name) # See if we have any submenus for i in range(0, definition.childcount): child = definition.getchild(i) # Submenu if child.name == 'menu': if not child.hasattribute('id'): console.log(LOG_ERROR, "Submenu with missing id attribute in menu %s.\n" % menu.id) else: loadMenu(child.getattribute('id'), menu) # Craft an item elif child.name in ['masonry', 'semasonry']: if not child.hasattribute('definition'): console.log(LOG_ERROR, "Masonry action without definition in menu %s.\n" % menu.id) else: itemdef = child.getattribute('definition') try: # See if we can find an item id if it's not given if not child.hasattribute('itemid'): item = wolfpack.getdefinition(WPDT_ITEM, itemdef) itemid = 0 if item: itemchild = item.findchild('id') if itemchild: itemid = itemchild.value else: itemid = hex2dec(child.getattribute('itemid', '0')) if child.hasattribute('name'): name = child.getattribute('name') else: name = generateNamefromDef(itemdef) if child.name == 'semasonry': action = SeStonecrafterItemAction(menu, name, int(itemid), itemdef) else: action = StonecrafterItemAction(menu, name, int(itemid), itemdef) except: console.log(LOG_ERROR, "Masonry action with invalid item id in menu %s.\n" % menu.id) # Process subitems for j in range(0, child.childcount): subchild = child.getchild(j) action.processnode(subchild, menu) # Sort the menu. This is important for the makehistory to make. menu.sort()
def startElement( self, name, atts ): if name == "item": self.itemid = str(atts.getValue("id")); if "hue" in atts: self.hue = int(hex2dec(str(atts.getValue("hue")))); else: self.hue = 0 if "amount" in atts: self.amount = int(atts.getValue("amount")); else: self.amount = 0 self.statements = [] elif name == "attribute": type = "str" if "type" in atts: type = str(atts.getValue("type")) if "value" in atts and "key" in atts: self.statements.append( str(atts.getValue("key")) + "," + type + ","+ str(atts.getValue("value")) ) elif name == "pos": if int(hex2dec( self.itemid )) >= 0x4000: item = wolfpack.addmulti( "%x" % hex2dec( self.itemid ) ) else: item = wolfpack.additem( "%x" % hex2dec( self.itemid ) ) if not item or item == None: return if self.hue > 0: item.color = self.hue if self.amount > 0: item.amount = self.amount for p in self.statements: parts = p.split(",") if hasattr(item, parts[0]): if parts[1] == "str": value = parts[2] elif parts[1] == "int": value = int(parts[2]) setattr(item, parts[0], value) x = int( atts.getValue("x") ) y = int( atts.getValue("y") ) z = int( atts.getValue("z") ) map = int( atts.getValue("map") ) item.moveto( x, y, z, map ) item.movable = 3 # not movable item.decay = 0 # no decay item.update() elif name == "include": path = atts.getValue("file") if not os.path.isfile(path): console.log(LOG_ERROR, tr("File '%s' not found.\n") % (path)) return parser = xml.sax.make_parser() handler = DecorationHandler() parser.setContentHandler(handler) parser.parse(path)
def sendBuyList(self, vendor, player): if not self.canBuyItems(vendor, player): return False if not self.checkAccess(vendor, player): return False self.ensurePacks(vendor) # Make sure the packs are there # Compile a list of items that should be sold buylist = BuyList() restock = self.getRestockContainer(vendor) norestock = self.getBuyContainer(vendor) # Add items that are in the restock container for item in restock.content: buyitemindex = item.gettag('buyitemindex') if buyitemindex == None or buyitemindex < 0 or buyitemindex >= len( self.buylist): console.log( LOG_ERROR, "Item 0x%x has invalid buy item index %s.\n" % (item.serial, buyitemindex)) continue buyitem = self.buylist[buyitemindex] # Scale the price price = self.scaleBuyPrice(vendor, player, buyitem, buyitem.getPrice(vendor, player)) # Add the item to the buylist buylist.add(restock, item, self.getInStock(item), price) # Add items from the no restock container for item in norestock.content: baseid = item.baseid if not baseid in self.sellmap: continue # Should we delete this? sellitem = self.sellmap[baseid] price = self.scaleResellPrice( vendor, player, item, sellitem.getPrice(vendor, player, item)) if price <= 0: continue # We don't donate... # Another quirk in the osi protocol. no restock items are still in the # restock pack, oherwise they don't have a price. buylist.add(restock, item, self.getInStock(item), price) # Send the buylist to the player return buylist.send(vendor, player)
def onUnload(): console.log(LOG_MESSAGE, "Stopping shard status page thread.\n") global processthread if processthread: processthread.stopped.set() time.sleep(0.01) # Sleep a little to give the thread time to exit if processthread: processthread.join() processthread = None return
def onUnload(): console.log(LOG_MESSAGE, "Stopping shard status page thread.\n") global processthread if processthread: processthread.stopped.set() time.sleep( 0.01 ) # Sleep a little to give the thread time to exit if processthread: processthread.join() processthread = None return
def growthCheck(obj, args): if args[0] != magic: return # This is an outdated timer # Notify the log that we're running a growth check console.log(LOG_MESSAGE, "Running plant growth check for %u plants.\n" % len(PLANTS)) # Copy the list of known plant serials and # start the subprocessing function processGrowthCheck(None, ( PLANTS[:], 0, magic ))
def gainresObject(obj, args): if args[0] != magic_farming: return # This is an outdated timer # Notify the log that we're running a growth check console.log(LOG_MESSAGE, "Running farming growth check for %u objects.\n" % len(OBJECTS)) # Copy the list of known object serials and # start the subprocessing function processGainresObject(None, (OBJECTS[:], 0, magic_farming))
def gainresObject(obj, args): if args[0] != magic_farming: return # This is an outdated timer # Notify the log that we're running a growth check console.log(LOG_MESSAGE, "Running farming growth check for %u objects.\n" % len(OBJECTS)) # Copy the list of known object serials and # start the subprocessing function processGainresObject(None, ( OBJECTS[:], 0, magic_farming ))
def growthCheck(obj, args): if args[0] != magic_crops: return # This is an outdated timer # Notify the log that we're running a growth check console.log(LOG_MESSAGE, "Running crop growth check for %u crops.\n" % len(CROPS)) # Copy the list of known plant serials and # start the subprocessing function processGrowthCheck(None, ( CROPS[:], 0, magic_crops ))
def onCollide(player, item): if item.hastag('playersonly') and player.npc: return False if not item.hastag('target'): if player.socket: player.socket.sysmessage( tr('This gate leads nowhere...') ) else: console.log(LOG_ERROR, tr("NPC [%x] using gate [%x] without target.\n") % (player.serial, item.serial)) return False target = item.gettag('target').split(',') # Convert the target of the gate. try: target = map(int, target) except: player.socket.sysmessage( tr('This gate leads nowhere...') ) return False # Validate the coord try: m = target[3] except: m = player.pos.map pos = wolfpack.coord( target[0], target[1], target[2], m ) if not utilities.isValidPosition( pos ): player.socket.sysmessage( tr('This gate leads nowhere...') ) return False if not utilities.isMapAvailableTo( player, pos.map ): return False # Move his pets if he has any if player.player: for follower in player.followers: if follower.wandertype == 4 and follower.distanceto(player) < 5: follower.removefromview() follower.moveto(pos) follower.update() player.removefromview() player.moveto(pos) player.update() if player.socket: player.socket.resendworld() # show some nice effects if not item.hastag('silent'): item.soundeffect(0x1fe) utilities.smokepuff(player, pos) utilities.smokepuff(player, item.pos) return True
def loadMenu(id, parent = None): definition = wolfpack.getdefinition(WPDT_MENU, id) if not definition: if parent: console.log(LOG_ERROR, "Unknown submenu %s in menu %s.\n" % (id, parent.id)) else: console.log(LOG_ERROR, "Unknown menu: %s.\n" % id) return name = definition.getattribute('name', '') menu = GlassblowingMenu(id, parent, name) # See if we have any submenus for i in range(0, definition.childcount): child = definition.getchild(i) # Submenu if child.name == 'menu': if not child.hasattribute('id'): console.log(LOG_ERROR, "Submenu with missing id attribute in menu %s.\n" % menu.id) else: loadMenu(child.getattribute('id'), menu) # Craft an item elif child.name == 'glassblowing': if not child.hasattribute('definition'): console.log(LOG_ERROR, "Glassblowing action without definition in menu %s.\n" % menu.id) else: itemdef = child.getattribute('definition') try: # See if we can find an item id if it's not given if not child.hasattribute('itemid'): item = wolfpack.getdefinition(WPDT_ITEM, itemdef) itemid = 0 if item: itemchild = item.findchild('id') if itemchild: itemid = itemchild.value else: itemid = hex2dec(child.getattribute('itemid', '0')) if child.hasattribute('name'): name = child.getattribute('name') else: name = generateNamefromDef(itemdef) action = GlassblowerItemAction(menu, name, int(itemid), itemdef) except: console.log(LOG_ERROR, "Glassblowing action with invalid item id in menu %s.\n" % menu.id) # Process subitems for j in range(0, child.childcount): subchild = child.getchild(j) action.processnode(subchild, menu) # Sort the menu. This is important for the makehistory to make. menu.sort()
def make(self, player, arguments, nodelay=0): item = wolfpack.additem(self.definition) if not item: console.log(LOG_ERROR, "Unknown item definition used in action %u of menu %s.\n" % \ (self.parent.subactions.index(self), self.parent.id)) else: if self.amount > 0: item.amount = self.amount if not tobackpack(item, player): item.update() player.socket.sysmessage('You put the new item into your backpack.') MakeAction.make(self, player, arguments, nodelay)
def onCollide(player, item): if item.hastag('playersonly') and player.npc: return 0 if not item.hastag('target'): if player.socket: player.socket.sysmessage('This gate leads nowhere...') else: console.log(LOG_ERROR, "NPC [%x] using gate [%x] without target.\n" % (player.serial, item.serial)) return 0 target = item.gettag('target').split(',') # Convert the target of the gate. try: target = map(int, target) except: player.socket.sysmessage('This gate leads nowhere...') return 0 # Move the player pos = player.pos pos.x = target[0] pos.y = target[1] pos.z = target[2] if len(target) > 3: pos.map = target[3] if not utilities.isMapAvailableTo(player, pos.map): return False # Move his pets if he has any if player.player: for follower in player.followers: if follower.wandertype == 4 and follower.distanceto(player) < 5: follower.removefromview() follower.moveto(pos) follower.update(0) player.removefromview() player.moveto(pos) player.update(0) if player.socket: player.socket.resendworld() # show some nice effects if not item.hastag('silent'): item.soundeffect(0x1fe) utilities.smokepuff(player, pos) utilities.smokepuff(player, item.pos) return 1
def sendBuyList(self, vendor, player): if not self.canBuyItems(vendor, player): return False if not self.checkAccess(vendor, player): return False self.ensurePacks(vendor) # Make sure the packs are there # Compile a list of items that should be sold buylist = BuyList() restock = self.getRestockContainer(vendor) norestock = self.getBuyContainer(vendor) # Add items that are in the restock container for item in restock.content: buyitemindex = item.gettag('buyitemindex') if buyitemindex == None or buyitemindex < 0 or buyitemindex >= len(self.buylist): console.log(LOG_ERROR, "Item 0x%x has invalid buy item index %s.\n" % (item.serial, buyitemindex)) continue buyitem = self.buylist[buyitemindex] # Scale the price price = self.scaleBuyPrice(vendor, player, buyitem, buyitem.getPrice(vendor, player)) # Add the item to the buylist buylist.add(restock, item, self.getInStock(item), price) # Add items from the no restock container for item in norestock.content: baseid = item.baseid if not baseid in self.sellmap: continue # Should we delete this? sellitem = self.sellmap[baseid] price = self.scaleResellPrice(vendor, player, item, sellitem.getPrice(vendor, player, item)) if price <= 0: continue # We don't donate... # Another quirk in the osi protocol. no restock items are still in the # restock pack, oherwise they don't have a price. buylist.add(restock, item, self.getInStock(item), price) # Send the buylist to the player return buylist.send(vendor, player)
def onUpdateAcctDatabase(current, version): database.open(ACCOUNTS) driver = database.driver(ACCOUNTS) if driver == 'mysql': updates = ACCT_MYSQL_UPDATES elif driver == 'sqlite': updates = ACCT_SQLITE_UPDATES else: console.log(LOG_ERROR, "Unknown database driver for Accounts: %s.\n" % driver) database.close(ACCOUNTS) return False for i in range(version, current): # No update for this version available if not i in updates: console.log(LOG_ERROR, "No update available for database version %u.\n" % i) database.close(ACCOUNTS) return False console.log(LOG_MESSAGE, "Updating database from version %u to %u.\n" % (i, i+1)) try: if not updates[i](): database.close(ACCOUNTS) return False except Exception, e: console.log(LOG_ERROR, str(e) + "\n") database.close(ACCOUNTS) return False # Updating Version Number updateacctversion(i+1, driver)
def updateacctversion(version, driver): try: if driver == 'mysql': database.execute( "REPLACE INTO `settings` VALUES('db_version', '%u');" % version) else: database.execute( "REPLACE INTO settings VALUES('db_version', '%u');" % version) except Exception, e: console.log( LOG_WARNING, "Unable to update account database version to %u:\n%s\n" % (i + 1, str(e)))
def make(self, player, arguments, nodelay=0): item = wolfpack.additem(self.definition) if not item: console.log( LOG_ERROR, "Unknown item definition used in action %u of menu %s.\n" % (self.parent.subactions.index(self), self.parent.id), ) else: if self.amount > 0: item.amount = self.amount if not tobackpack(item, player): item.update() player.socket.clilocmessage(500442) CraftAction.make(self, player, arguments, nodelay)
def processGrowthCheck(obj, args): if args[2] != magic_crops: return # The scripts have been reloaded croplist = args[0] # We keep a reference here to prevent reallocation index = args[1] upperindex = min(index + CHECKSPERCYCLE, len(croplist)) # Process the list of plants for i in range(index, upperindex): try: crop = wolfpack.finditem(croplist[i]) growCrop(crop) except Exception, e: console.log(LOG_ERROR, "An error occured while checking crop 0x%x: %s.\n" % (crop.serial, str(e)))
def processGrowthCheck(obj, args): if args[2] != magic: return # The scripts have been reloaded plantlist = args[0] # We keep a reference here to prevent reallocation index = args[1] upperindex = min(index + CHECKSPERCYCLE, len(plantlist)) planthash = hash('plant') # Process the list of plants for i in range(index, upperindex): try: plant = wolfpack.finditem(plantlist[i]) if plant and hash(plant.baseid) == planthash: plants.plant.growthCheck(plant) except Exception, e: console.log(LOG_ERROR, "An error occured while checking plant 0x%x: %s.\n" % (plant.serial, str(e)))
def onDeath(char, killer, corpse): if char.player or char.summoned: return lootlist = char.lootpacks if len(lootlist) == 0: return packs = lootlist.split(';') # Create the items for each pack for pack in packs: if not PACKS.has_key( pack ): console.log(LOG_ERROR, "Trying to create an unknown loot pack %s.\n" % pack) continue createpack( char, killer, corpse, PACKS[ pack ] )
def onDeath(char, killer, corpse): if char.player or char.summoned: return lootlist = char.lootpacks if len(lootlist) == 0: return packs = lootlist.split(';') # Create the items for each pack for pack in packs: if not pack in PACKS: console.log(LOG_ERROR, "Trying to create an unknown loot pack %s.\n" % pack) continue createpack(char, killer, corpse, PACKS[pack])
def spawn(spawner, spawntype, spawndef, current, area): try: if spawntype == 1: npc = wolfpack.addnpc(spawndef, spawner.pos) npc.settag('spawner', spawner.serial) npc.wandertype = 3 npc.wanderx1 = spawner.pos.x npc.wandery1 = spawner.pos.y npc.wanderradius = area npc.addscript( 'system.spawns' ) npc.update() elif spawntype == 0: pass except: if( spawner ): console.log(LOG_WARNING, "Invalid spawner: 0x%x.\n" % spawner.serial) return spawner.settag('current', current + 1)
def processGainresObject(obj, args): if args[2] != magic_farming: return # The scripts have been reloaded objectlist = args[0] # We keep a reference here to prevent reallocation index = args[1] upperindex = min(index + CHECKSPERCYCLE, len(objectlist)) # Process the list of objects for i in range(index, upperindex): try: object = wolfpack.findobject(objectlist[i]) if object: if object.hastag("resourcecount") and object.gettag("resourcecount") >= actions[ object.baseid ][1]: continue else: addresource(object) except Exception, e: console.log(LOG_ERROR, "An error occured while checking farming object 0x%x: %s.\n" % (object.serial, str(e)))
def onWalk(char, dir, sequence): # Only talk if talking toward our attack target if not char.attacktarget or char.distanceto(char.attacktarget) > 5: return False # Otherwise a 10% chance if random.random() >= 0.10: return False speech = char.getstrproperty('monsterspeech', '') global speechbuilders if not speech in speechbuilders: console.log(LOG_MESSAGE, speech + "\n") return False speechbuilder = speechbuilders[speech] char.soundeffect(speechbuilder.saysound) char.say(speechbuilder.buildsentence(6), speechbuilder.saycolor) return False
def updatebook(socket, packet): item = wolfpack.finditem(packet.getint(3)) if not item: console.log( LOG_ERROR, "Client tried to update non existing book %x." % (packet.getint(3))) return 1 title_length = packet.getshort(11) title = "" for i in range(0, title_length): byte = packet.getbyte(13 + i) if byte > 0: title += chr(byte) title = unicode(title, 'utf-8') author_length = packet.getshort(13 + title_length) author = "" for i in range(0, author_length): byte = packet.getbyte(15 + title_length + i) if byte > 0: author += chr(byte) author = unicode(author, 'utf-8') if item.hastag('protected'): char.message(tr('This book is read only.')) return 1 outmost = item.getoutmostchar() if outmost and outmost != socket.player: socket.sysmessage(tr('This book is read only.')) return 1 # Not writeable if len(author) == 0: item.deltag('author') else: item.settag('author', author) item.name = title item.resendtooltip() return 1
def onWalk(char, dir, sequence): # Only talk if talking toward our attack target if not char.attacktarget or char.distanceto(char.attacktarget) > 5: return False # Otherwise a 10% chance if random.random() >= 0.10: return False speech = char.getstrproperty('monsterspeech', '') global speechbuilders if not speech in speechbuilders: console.log(LOG_MESSAGE, speech + "\n") return False speechbuilder = speechbuilders[speech] char.soundeffect( speechbuilder.saysound ) char.say( speechbuilder.buildsentence(6), speechbuilder.saycolor ) return False
def onUpdateDatabase(current, version): # Find the update table for the database driver in use driver = database.driver(WORLD) if driver == 'mysql': updates = MYSQL_UPDATES elif driver == 'sqlite': updates = SQLITE_UPDATES else: console.log(LOG_ERROR, "Unknown database driver: %s.\n" % driver) return False for i in range(version, current): # No update for this version available if not i in updates: console.log(LOG_ERROR, "No update available for database version %u.\n" % i) return False console.log(LOG_MESSAGE, "Updating database from version %u to %u.\n" % (i, i + 1)) try: if not updates[i](): return False except Exception, e: console.log(LOG_ERROR, str(e) + "\n") return False wolfpack.setoption('db_version', str(i + 1)) try: if driver == 'mysql': database.execute( "REPLACE INTO `settings` VALUES('db_version', '%u');" % (i + 1)) else: database.execute( "REPLACE INTO settings VALUES('db_version', '%u');" % (i + 1)) except Exception, e: console.log( LOG_WARNING, "Unable to update database version to %u:\n%s\n" % (i + 1, str(e)))
def processGrowthCheck(obj, args): if args[2] != magic: return # The scripts have been reloaded plantlist = args[0] # We keep a reference here to prevent reallocation index = args[1] upperindex = min(index + CHECKSPERCYCLE, len(plantlist)) planthash = hash('plant') # Process the list of plants for i in range(index, upperindex): try: plant = wolfpack.finditem(plantlist[i]) if plant and hash(plant.baseid) == planthash: plants.plant.growthCheck(plant) except Exception, e: console.log( LOG_ERROR, "An error occured while checking plant 0x%x: %s.\n" % (plant.serial, str(e)))
def callEvent(item, event, args): scripts = list(item.scripts) + item.basescripts.split(',') # Build the scriptlist for script in scripts: if len(script) == 0: continue try: if not wolfpack.hasnamedevent(script, event): continue result = wolfpack.callnamedevent(script, event, args) except: console.log(LOG_ERROR, "Error processing script %s.\n" % script) raise if result: return True return False
def run(self): while not self.stopped.isSet(): # Check if status data is available and process it data = None self.mutex.acquire() if self.data: data = self.data self.data = None self.mutex.release() if data: global outputfile try: fp = file(outputfile, 'wu') fp.write(data.encode('utf-8')) fp.close() except Exception, e: console.log(LOG_PYTHON, "Couldn't write status to '%s': %s.\n" % (outputfile, str(e))) self.stopped.wait(0.5)
def run(self): while not self.stopped.isSet(): self.lock() process = self.unprocessed[:50] self.unprocessed = self.unprocessed[50:] if DEBUG_SPAWNS == 1: console.log(LOG_MESSAGE, "Found %u spawn items." % len(process)) wolfpack.queuecode(processSpawns, (process, )) self.processed += process if len(self.unprocessed) == 0: self.unprocessed = self.processed self.processed = [] self.unlock() self.stopped.wait(15.0) # Every 15 seconds.
def run(self): while not self.stopped.isSet(): self.lock() process = self.unprocessed[:SpawnGemsCheckAmount] self.unprocessed = self.unprocessed[SpawnGemsCheckAmount:] if DEBUG_SPAWNS: console.log(LOG_MESSAGE, "Found %u spawn items." % len(process)) wolfpack.queuecode(processSpawns, (process, )) self.processed += process if len(self.unprocessed) == 0: self.unprocessed = self.processed self.processed = [] self.unlock() self.stopped.wait(SpawnGemsCheckTime) # Every 15 seconds default.
def updatebook(socket, packet): item = wolfpack.finditem(packet.getint(3)) if not item: console.log(LOG_ERROR, "Client tried to update non existing book %x." % (packet.getint(3))) return 1 title_length = packet.getshort(11) title = "" for i in range(0, title_length): byte = packet.getbyte(13 + i) if byte > 0: title += chr(byte) title = unicode(title, "utf-8") author_length = packet.getshort(13 + title_length) author = "" for i in range(0, author_length): byte = packet.getbyte(15 + title_length + i) if byte > 0: author += chr(byte) author = unicode(author, "utf-8") if item.hastag("protected"): char.message("This book is read only.") return 1 outmost = item.getoutmostchar() if outmost and outmost != socket.player: socket.sysmessage("This book is read only.") return 1 # Not writeable if len(author) == 0: item.deltag("author") else: item.settag("author", author) item.name = title item.resendtooltip() return 1
def processGainresObject(obj, args): if args[2] != magic_farming: return # The scripts have been reloaded objectlist = args[0] # We keep a reference here to prevent reallocation index = args[1] upperindex = min(index + CHECKSPERCYCLE, len(objectlist)) # Process the list of objects for i in range(index, upperindex): try: object = wolfpack.findobject(objectlist[i]) if object: if object.hastag("resourcecount") and object.gettag("resourcecount") >= actions[object.baseid][1]: continue else: addresource(object) except Exception, e: console.log( LOG_ERROR, "An error occured while checking farming object 0x%x: %s.\n" % (object.serial, str(e)) )
def onCollide(player, item): if item.hastag('playersonly') and player.npc: return 0 if not item.hastag('target'): if player.socket: player.socket.sysmessage('This gate leads nowhere...') else: console.log(LOG_ERROR, "NPC [%x] using gate [%x] without target.\n" % (player.serial, item.serial)) return 0 target = item.gettag('target').split(',') # Convert the target of the gate. try: target = map(int, target) except: player.socket.sysmessage('This gate leads nowhere...') return 0 # Move the player pos = player.pos pos.x = target[0] pos.y = target[1] pos.z = target[2] player.removefromview() player.moveto(pos) player.update(0) if player.socket: player.socket.resendworld() # show some nice effects if not item.hastag('silent'): player.soundeffect(0x1fe) item.soundeffect(0x1fe) wolfpack.effect(0x3728, player.pos, 10, 30) pos = item.pos wolfpack.effect(0x3728, pos, 10, 30) return 1
def run(self): while not self.stopped.isSet(): # Check if status data is available and process it data = None self.mutex.acquire() if self.data: data = self.data self.data = None self.mutex.release() if data: global outputfile try: fp = file(outputfile, 'w') fp.write(data.encode('utf-8')) fp.close() except Exception, e: console.log( LOG_PYTHON, "Couldn't write status to '%s': %s.\n" % (outputfile, str(e))) self.stopped.wait(0.5)
def onAttach(object): if not object.isitem(): return if not object.hastag("itemdef"): console.log(LOG_ERROR, "Missing itemdef tag for multibag object.\n") return if not object.hastag("itemamount"): console.log(LOG_ERROR, "Missing itemamount tag for multibag object.\n") return id = str(object.gettag("itemdef")) amount = int(object.gettag("itemamount")) for i in range(0, amount): item = wolfpack.additem(id) item.container = object object.deltag("itemdef") object.deltag("itemamount") object.removescript("testing.multibag")
def checkRestockInventory(self, vendor, force=False): # If the inventory check is not forced, # see if the last check was performed more than an hour ago if not force: vendor_magic = vendor.gettag('magic') if vendor_magic == magic: return restock = vendor.itemonlayer(LAYER_NPCRESTOCK) if restock: restock.delete() # Delete the old restock container restock = self.getRestockContainer( vendor) # Create a new restock container # Recreate the content from our buyitems array for i in range(0, len(self.buylist)): dispitem = self.buylist[i].createDisplayItem( ) # Try to create a display item # Unable to create display item if not dispitem: console.log( LOG_ERROR, "Unable to create display item for buyitem at index %u for vendor 0x%x.\n" % (i, vendor.serial)) continue dispitem.settag( 'buyitemindex', i) # Store the index of the buyitem that created the dispitem restock.additem( dispitem) # Add the dispitem to the restock container # Once the check has been completed, save the vendor magic vendor.settag('magic', magic)
def changeweather(region): if not ENABLEDWEATHER: return # Season modifications season = returnseason() # Ok. Now, lets check if this Region have to begins to Rain or Snow rainchance = region.rainchance + SEASONS[season][0] snowchance = region.snowchance + SEASONS[season][1] randomrain = random.randint(1, 100) randomsnow = random.randint(1, 100) # Rain (And possible Snow too) if randomrain <= rainchance: region.startrain() if randomsnow <= snowchance: region.startsnow() console.log(LOG_MESSAGE, "Raining and Snowing on " + region.name) else: console.log(LOG_MESSAGE, "Raining on " + region.name) weatherduration(region) weatherintensity(region) # Snow elif randomsnow <= snowchance: region.startsnow() console.log(LOG_MESSAGE, "Snowing on " + region.name) weatherduration(region) weatherintensity(region) # Dry else: if region.israining: region.stoprain() if region.issnowing: region.stopsnow() weatherduration(region) # Updating all Clients in this Region (I think socket iterator is cheaper than regionchars iterator) worldsocket = wolfpack.sockets.first() while worldsocket: # Finding TopRegion topregion = worldsocket.player.region if topregion.parent: topregion = topregion.parent # Checking Region if unicode(topregion) == unicode(region): worldsocket.player.update() worldsocket = wolfpack.sockets.next()
def onUpdateAcctDatabase(current, version): database.open(ACCOUNTS) driver = database.driver(ACCOUNTS) if driver == 'mysql': updates = ACCT_MYSQL_UPDATES elif driver == 'sqlite': updates = ACCT_SQLITE_UPDATES else: console.log(LOG_ERROR, "Unknown database driver for Accounts: %s.\n" % driver) database.close(ACCOUNTS) return False for i in range(version, current): # No update for this version available if not i in updates: console.log(LOG_ERROR, "No update available for database version %u.\n" % i) database.close(ACCOUNTS) return False console.log(LOG_MESSAGE, "Updating database from version %u to %u.\n" % (i, i + 1)) try: if not updates[i](): database.close(ACCOUNTS) return False except Exception, e: console.log(LOG_ERROR, str(e) + "\n") database.close(ACCOUNTS) return False # Updating Version Number updateacctversion(i + 1, driver)
def processSpawns(process): # Process the designated partition for i in range(0, len(process)): item = wolfpack.finditem(process[i]) # Check if the spawn is valid. valid = item != None if valid and not item.hasscript('spawngem'): valid = False if valid and (not item.hastag('spawntype') or not item.hastag('spawndef')): valid = False if not valid: if DEBUG_SPAWNS: console.log(LOG_WARNING, "Invalid spawn item: 0x%x.\n" % item.serial) pass else: spawntype = int(item.gettag('spawntype')) # 0: Items, 1: NPCs spawndef = str(item.gettag('spawndef')) # Definition # This is either how far the npcs will wander # or how far from the spawn the items will be spawned. area = 0 if item.hastag('area'): area = int(item.gettag('area')) # This is a minimum/maximum spawn interval in minutes mininterval = 5 if item.hastag('mininterval'): try: mininterval = int(item.gettag('mininterval')) except: mininterval = 10 maxinterval = mininterval if item.hastag('maxinterval'): try: maxinterval = int(item.gettag('maxinterval')) except: maxinterval = 10 # Normalize min and maxinterval (min. is 1) if mininterval < 1: mininterval = 1 if maxinterval < 1: maxinterval = 1 if mininterval > maxinterval: temp = maxinterval maxinterval = mininterval mininterval = temp # Currently / Maximimum spawned by this gem current = 0 if item.hastag('current'): try: current = int(item.gettag('current')) except: current = 0 maximum = 1 if item.hastag('maximum'): try: maximum = int(item.gettag('maximum')) except: maximum = 1 nextspawn = 0 if item.hastag('nextspawn'): try: nextspawn = int(item.gettag('nextspawn')) except: nextspawn = 0 currenttime = wolfpack.tickcount() # It's possible that the spawntime got too far into the future (server-reload etc.) # reset it here. if nextspawn - currenttime > maxinterval * 60 * 1000: nextspawn = 0 # If we didn't have a spawntime set yet. if nextspawn == 0 and current < maximum: delay = random.randint(mininterval, maxinterval) * 60 * 1000 item.settag('nextspawn', currenttime + delay) if DEBUG_SPAWNS: console.log( LOG_MESSAGE, "Set spawntime for spawngem 0x%x to %u miliseconds in the future.\n" % (item.serial, delay)) continue elif current >= maximum: item.deltag('nextspawn') continue if nextspawn <= currenttime: spawn(item, spawntype, spawndef, current, area) #console.log(LOG_MESSAGE, "SPAWNTIME REACHED!") item.deltag('nextspawn') if DEBUG_SPAWNS: console.log(LOG_MESSAGE, "Valid Spawnpoint: %x, Cur/Max: %u/%u, Def: %s, Type: %u, Interval: %u,%u, Time: %d/%d" % \ (item.serial, current, maximum, spawndef, spawntype, mininterval, maxinterval, currenttime, nextspawn))
def WritePage(status='Online'): global processthread console.log(LOG_MESSAGE, "Generating Shard Status Page.\n") # Default/Static Information if status != 'Online' and status != 'Offline': status = "Unknown" #Prepare Information uptime = wolfpack.time.currenttime() / 1000 # Build an uptime: upseconds = 0 upminutes = 0 uphours = 0 updays = 0 upseconds = uptime upminutes = uptime / 60 upseconds -= upminutes * 60 if upseconds <= 9: upseconds = '0%s' % upseconds uphours = upminutes / 60 upminutes -= uphours * 60 if upminutes <= 9: upminutes = '0%s' % upminutes if uphours <= 9: uphours = '0%s' % uphours #Make a time string timestring = '%s:%s:%s' % (uphours, upminutes, upseconds) # Account Counting accountcount = 0 admincount = 0 gmcount = 0 seercount = 0 counselorcount = 0 playercount = 0 players = "" # ACC List for i in accounts.list(): record = accounts.find(i) if record.acl == 'admin': admincount += 1 elif record.acl == 'gm': gmcount += 1 elif record.acl == 'seer': seercount += 1 elif record.acl == 'counselor': counselorcount += 1 elif record.acl == 'player': playercount += 1 #Write the page file = open(output_file, 'w') outputtext = "<div class='box' style='min-width:480px;width:90%;'>\n" outputtext += "<table class='contentinfo' style='width:100%;' cellpadding='0' cellspacing='0'>\n" outputtext += "<caption>Rayonnant Server Status [ <?=$phase?> ]</caption>\n" outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span style='font-weight:bold;'>Server Address:</span> </td>" outputtext += "<td> <span class='server_good'>%s</span></td></tr>\n" % ( address) outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span style='font-weight:bold;'>Server Status:</span> </td>" if status == 'Online': outputtext += "<td> <span class='server_good'>%s</span></td></tr>\n" % ( status) outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span style='font-weight:bold;'>Server Uptime:</span> </td>" outputtext += "<td> <span class='server_good'>%s</span></td></tr>\n" % ( timestring) elif status == 'Offline': outputtext += "<td> <span class='server_bad'>%s</span></td></tr>\n" % ( status) outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span style='font-weight:bold;'>Previous Uptime:</span> </td>" outputtext += "<td> <span class='server_bad'>%s</span></td></tr>\n" % ( timestring) else: outputtext += "<td> <span class='server_neutral'>%s</span></td></tr>\n" % ( status) outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span style='font-weight:bold;'>Server Uptime:</span> </td>" outputtext += "<td> <span class='server_neutral'>%s</span></td></tr>\n" % ( timestring) outputtext += "<tr><td style='width:90px;'>" outputtext += "<span style='font-weight:bold;'>Server Version:</span> </td>" outputtext += "<td> <span class='server_good'>%s</span></td></tr>\n" % ( wolfpack.serverversion()) if status == 'Online': outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span style='font-weight:bold;'>Accounts:</span> </td><td></td></tr>\n" outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span class='server_neutral'>%s</span> / <span class='server_good'>%s</span></td>" % ( wolfpack.sockets.count(), wolfpack.accounts.count()) outputtext += "<td style='text-indent:1em;'> Online / Total Accounts</td></tr>\n" outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span class='server_neutral'>%s</span> </td>" % ( admincount) outputtext += "<td style='text-indent:1em;'> Admin Accounts</td></tr>\n" outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span class='server_neutral'>%s</span> </td>" % ( gmcount) outputtext += "<td style='text-indent:1em;'> GM Accounts</td></tr>\n" outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span class='server_neutral'>%s</span> </td>" % ( seercount) outputtext += "<td style='text-indent:1em;'> Seer Accounts</td></tr>\n" outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span class='server_neutral'>%s</span> </td>" % ( counselorcount) outputtext += "<td style='text-indent:1em;'> Counselor Accounts</td></tr>\n" outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span class='server_neutral'>%s</span> </td>" % ( playercount) outputtext += "<td style='text-indent:1em;'> Player Accounts</td></tr>\n" # Statistics Item/Char Totals outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span style='font-weight:bold;'>Statistics:</span> </td><td></td></tr>\n" outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span class='server_neutral'>%s</span> </td>" % ( wolfpack.playercount()) outputtext += "<td style='text-indent:1em;'> Total Players</td></tr>\n" outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span class='server_neutral'>%s</span> </td>" % ( wolfpack.itemcount()) outputtext += "<td style='text-indent:1em;'> Total Items</td></tr>\n" outputtext += "<tr><td style='width:90px;text-align:right;'>" outputtext += "<span class='server_neutral'>%s</span> </td>" % ( wolfpack.npccount()) outputtext += "<td style='text-indent:1em;'> Total NPCs</td></tr>\n" outputtext += "</table>\n" outputtext += "</div>\n" file.write(outputtext) file.close() wolfpack.addtimer(1000, autostatuswrapper) processthread.mutex.acquire() processthread.processed = True processthread.mutex.release() return True
def loadMenu(id, parent=None): definition = getdefinition(WPDT_MENU, id) if not definition: if parent: console.log(LOG_ERROR, "Unknown submenu %s in menu %s.\n" % (id, parent.id)) else: console.log(LOG_ERROR, "Unknown menu: %s.\n" % id) return name = definition.getattribute('name', '') menu = BowcraftMenu(id, parent, name) # See if we have any submenus for i in range(0, definition.childcount): child = definition.getchild(i) # Submenu if child.name == 'menu': if not child.hasattribute('id'): console.log( LOG_ERROR, "Submenu with missing id attribute in menu %s.\n" % menu.id) else: loadMenu(child.getattribute('id'), menu) # Craft an item elif child.name in ['fletch', 'sefletch']: if not child.hasattribute('definition'): console.log( LOG_ERROR, "Bowcraft action without definition in menu %s.\n" % menu.id) else: itemdef = child.getattribute('definition') try: # See if we can find an item id if it's not given if not child.hasattribute('itemid'): item = getdefinition(WPDT_ITEM, itemdef) itemid = 0 if item: itemchild = item.findchild('id') if itemchild: itemid = itemchild.value else: console.log( LOG_ERROR, "Bowcraft action with invalid definition %s in menu %s.\n" % (itemdef, menu.id)) else: itemid = hex2dec(child.getattribute('itemid', '0')) if child.hasattribute('name'): name = child.getattribute('name') else: name = generateNamefromDef(itemdef) if child.name == 'sefletch': action = SeFletchItemAction(menu, name, int(itemid), itemdef) else: action = FletchItemAction(menu, name, int(itemid), itemdef) except: console.log( LOG_ERROR, "Bowcraft action with invalid item id in menu %s.\n" % menu.id) # Process subitems for j in range(0, child.childcount): subchild = child.getchild(j) # How much of the primary resource should be consumed if subchild.name == 'logs': action.submaterial1 = hex2dec( subchild.getattribute('amount', '0')) # Normal Material if subchild.name == 'material': if not subchild.hasattribute('id'): console.log( LOG_ERROR, "Material element without id list in menu %s.\n" % menu.id) break else: ids = subchild.getattribute('id').split(';') try: amount = hex2dec( subchild.getattribute('amount', '1')) materialname = subchild.getattribute( 'name', 'Unknown') except: console.log( LOG_ERROR, "Material element with invalid id list in menu %s.\n" % menu.id) break action.materials.append( [ids, amount, materialname]) # Consume all available materials scaled by the # amount of each submaterial elif subchild.name == 'stackable': action.stackable = True # This item will never be exceptional elif subchild.name == 'nomark': action.markable = False # Skill requirement elif subchild.name in skillnamesids: skill = skillnamesids[subchild.name] try: minimum = hex2dec(subchild.getattribute( 'min', '0')) except: console.log( LOG_ERROR, "%s element with invalid min value in menu %s.\n" % (subchild.name, menu.id)) try: maximum = hex2dec( subchild.getattribute('max', '1200')) except: console.log( LOG_ERROR, "%s element with invalid max value in menu %s.\n" % (subchild.name, menu.id)) try: penalty = hex2dec( subchild.getattribute('penalty', '0')) except: console.log( LOG_ERROR, "%s element with invalid penalty value in menu %s.\n" % (subchild.name, menu.id)) action.skills[skill] = [minimum, maximum, penalty] # Sort the menu. This is important for the makehistory to make. menu.sort()
blocks += '+ ' + repr(current) else: blocks += 'print ' + repr(current) blocks += "\n" except Exception, e: console.log(LOG_PYTHON, "Unable to parse python template file: %s\n" % str(e)) return # Try to compile the file try: templatemodule = compile(blocks, htmltemplate, 'exec') except Exception, e: console.log( LOG_PYTHON, "Unable to compile python template file: %s\n" % str(e)) templatemodule = None return # Re-execute after interval miliseconds wolfpack.addtimer(interval, generate, [magic]) # Try to execute the code savedstdout = sys.stdout sys.stdout = StringIO() output = sys.stdout exec templatemodule sys.stdout = savedstdout text = output.getvalue()
def handlepage(socket, packet): item = wolfpack.finditem(packet.getint(3)) if not item: console.log( LOG_ERROR, "Client tried to update non existing book %x." % (packet.getint(3))) return 1 page = packet.getshort(9) linecount = packet.getshort(11) # A page was requested if linecount == -1: if item.hastag('pages'): pages = int(item.gettag('pages')) else: pages = 64 if page > pages or page == 0: return if item.hastag('page%u' % page): content = item.gettag('page%u' % page).split("\n") else: content = [] sendPage(socket, item.serial, page, content) # The client wants to update the page. else: if item.hastag('protected'): socket.sysmessage(tr('This book is read only.')) return 1 outmost = item.getoutmostchar() if outmost and outmost != socket.player: socket.sysmessage(tr('This book is read only.')) return 1 # Not writeable if item.hastag('pages'): pages = int(item.gettag('pages')) else: pages = 64 # Invalid page if page > pages or page < 1: socket.log( "Client tried to update invalid page %d of book 0x%x.\n" % (page, item.serial)) return 1 offset = 13 lines = [] for i in range(0, linecount): line = packet.getascii(offset, 0) offset += len(line) + 1 lines.append(unicode(line, 'utf-8')) content = "\n".join(lines) if not content or len(content.strip()) == 0: item.deltag('page%u' % page) return 1 item.settag('page%u' % page, content) item.resendtooltip() return 1
def generate(object, arguments): global magic, interval # The script has been reloaded if arguments[0] != magic: return global templatemodule if not templatemodule: global htmltemplate try: fp = file(htmltemplate, 'rU') template = fp.read() fp.close() console.log(LOG_MESSAGE, "Loaded status template from '%s'.\n" % htmltemplate) except Exception, e: console.log( LOG_PYTHON, "Couldn't load status template from '%s': %s.\n" % (htmltemplate, str(e))) return # Search for python codeblocks <%= %> length = len(template) blocks = '' current = '' inlineprint = 0 # PROLOG try: for i in range(0, length): if template[i:i + 3] == "<%\n": # Dump previous string if current != '': if inlineprint: blocks += '+ ' + repr(current) else: blocks += 'print ' + repr(current) current = '' inlineprint = 0 continue elif template[i - 1:i + 1] == "%>": # Gather code current = current[1:-1].strip("%") if inlineprint: blocks += " + unicode(%s)" % current[1:] else: blocks += "\n%s" % current inlineprint = 0 current = '' continue elif template[i:i + 3] == "<%=": # Dump previous string if current != '': if inlineprint: blocks += '+ ' + repr(current) else: blocks += 'print ' + repr(current) current = '' inlineprint = 1 continue current += template[i] if inlineprint: blocks += '+ ' + repr(current) else: blocks += 'print ' + repr(current) blocks += "\n" except Exception, e: console.log(LOG_PYTHON, "Unable to parse python template file: %s\n" % str(e)) return
def loadMenu(id, parent=None): definition = wolfpack.getdefinition(WPDT_MENU, id) if not definition: if parent: console.log(LOG_ERROR, "Unknown submenu %s in menu %s.\n" % (id, parent.id)) else: console.log(LOG_ERROR, "Unknown menu: %s.\n" % id) return name = definition.getattribute('name', '') menu = CartographyMenu(id, parent, name) # See if we have any submenus for i in range(0, definition.childcount): child = definition.getchild(i) # Submenu if child.name == 'menu': if not child.hasattribute('id'): console.log( LOG_ERROR, "Submenu with missing id attribute in menu %s.\n" % menu.id) else: loadMenu(child.getattribute('id'), menu) # Craft an item elif child.name == 'craft': if not child.hasattribute('definition'): console.log( LOG_ERROR, "craft action without definition in menu %s.\n" % menu.id) else: itemdef = child.getattribute('definition') try: # See if we can find an item id if it's not given if not child.hasattribute('itemid'): item = wolfpack.getdefinition(WPDT_ITEM, itemdef) itemid = 0 if item: itemchild = item.findchild('id') if itemchild: itemid = itemchild.value else: itemid = hex2dec(child.getattribute('itemid', '0')) except Exception, e: console.log( LOG_ERROR, "Craft action with invalid item id in menu %s: %s\n" % (menu.id, str(e))) if child.hasattribute('name'): name = child.getattribute('name') else: name = generateNamefromDef(itemdef) action = CartItemAction(menu, name, int(itemid), itemdef) # Process subitems for j in range(0, child.childcount): subchild = child.getchild(j) # Normal Material if subchild.name == 'material': if not subchild.hasattribute('id'): console.log( LOG_ERROR, "Material element without id list in menu %s.\n" % menu.id) break else: ids = subchild.getattribute('id').split(';') try: amount = hex2dec( subchild.getattribute('amount', '1')) materialname = subchild.getattribute( 'name', 'Unknown') except: console.log( LOG_ERROR, "Material element with invalid id list in menu %s.\n" % menu.id) break action.materials.append( [ids, amount, materialname]) # Skill requirement elif subchild.name in skillnamesids: skill = skillnamesids[subchild.name] try: minimum = hex2dec(subchild.getattribute( 'min', '0')) except: console.log( LOG_ERROR, "%s element with invalid min value in menu %s.\n" % (subchild.name, menu.id)) try: maximum = hex2dec( subchild.getattribute('max', '1200')) except: console.log( LOG_ERROR, "%s element with invalid max value in menu %s.\n" % (subchild.name, menu.id)) action.skills[skill] = [minimum, maximum]
def spawn(spawner, spawntype, spawndef, current, area): try: if spawntype == 1: npc = wolfpack.addnpc(spawndef, spawner.pos) npc.settag('spawner', spawner.serial) # NPCs with Area 0 have to stay on Origin Point if not area == 0: npc.wandertype = 3 else: npc.wandertype = 0 npc.wanderx1 = spawner.pos.x npc.wandery1 = spawner.pos.y npc.wanderradius = area npc.addscript('system.spawns') # Now Adv. Settings if spawner.hastag('color'): npc.skin = int(spawner.gettag('color')) if spawner.hastag('modstr'): npc.strength = npc.strength * float(spawner.gettag('modstr')) if spawner.hastag('moddex'): npc.dexterity = npc.dexterity * float(spawner.gettag('moddex')) if spawner.hastag('modint'): npc.intelligence = npc.intelligence * float( spawner.gettag('modint')) if spawner.hastag('modmaxhits'): npc.maxhitpoints = npc.maxhitpoints * float( spawner.gettag('modmaxhits')) if spawner.hastag('modmaxstam'): npc.maxstamina = npc.maxstamina * float( spawner.gettag('modmaxstam')) if spawner.hastag('modmaxmana'): npc.maxmana = npc.maxmana * float(spawner.gettag('modmaxmana')) if spawner.hastag('name'): npc.name = spawner.gettag('name') if spawner.hastag('nameprefix'): npc.settag('name.prefix', spawner.gettag('nameprefix')) if spawner.hastag('namesuffix'): npc.settag('name.suffix', spawner.gettag('namesuffix')) npc.update() # Updating visual of Spawn if SHOWNPCICON: bodyinfo = wolfpack.bodyinfo(npc.id) spawner.id = bodyinfo['figurine'] spawner.update() elif spawntype == 0: newitem = wolfpack.additem(spawndef) newitem.pos = spawner.pos newitem.settag('spawner', spawner.serial) newitem.decay = 0 newitem.addscript('system.spawns') newitem.update() except: if (spawner): console.log(LOG_WARNING, "Invalid spawner: 0x%x.\n" % spawner.serial) return spawner.settag('current', current + 1) spawner.resendtooltip()
def onBuyItems(self, vendor, player, bought): if not self.canBuyItems(vendor, player): return False if not self.checkAccess(vendor, player): return False validitems = [ ] # A list with 3-tuples containing the dispitem, buyitem and amount to be bought totalprice = 0 # Total purchase controlslots = player.maxcontrolslots - player.controlslots # Amount of controlslots left partial = False # We assume we can buy everything here # Process the buy item list for (item, amount) in bought: # Check the amount of the bought item instock = self.getInStock(item) amount = min(instock, amount) if amount == 0: continue # The item isn't available at all # Get the buyitem/sellitem if item.container.layer == LAYER_NPCNORESTOCK: if item.baseid not in self.sellmap: continue # Invalid item sellitem = self.sellmap[item.baseid] price = self.scaleResellPrice( vendor, player, item, sellitem.getPrice(vendor, player, item)) * amount if price <= 0: continue # We don't donate... totalprice += price validitems.append((item, sellitem, amount)) else: buyitemindex = item.gettag('buyitemindex') if buyitemindex == None or buyitemindex < 0 or buyitemindex >= len( self.buylist): console.log( LOG_ERROR, "Item 0x%x has invalid buy item index %s.\n" % (item.serial, buyitemindex)) continue buyitem = self.buylist[buyitemindex] # Check for the price and the controlslots if buyitem.controlslots * amount > controlslots: amount = controlslots / buyitem.controlslots partial = True if amount == 0: continue # Cannot buy this. Too few control slots. controlslots -= buyitem.controlslots * amount # Reduce remaining control slots # Scale the price totalprice += self.scaleBuyPrice( vendor, player, buyitem, buyitem.getPrice(vendor, player)) * amount validitems.append((item, buyitem, amount)) if len(bought) == 0: self.onNoItemsBought(vendor, player) return False # Don't close the buygump elif len(validitems) == 0: self.onNoItemsBought(vendor, player, True) return False # Don't close the buygump # Check for enough money consume = self.consumeGold(vendor, player, totalprice) if consume == Vendor.CONSUME_NONE: return False # Dont close the buygump player.soundeffect(0x32) # Play a gold soundeffect # Create the bought items. for (item, buyitem, amount) in validitems: buyitem.createItems(vendor, player, item, amount) frombank = consume == Vendor.CONSUME_BANKBOX # Was the amount deducted from the bank? self.onItemsBought(vendor, player, totalprice, frombank, partial) # Notify the event handler return True # Close the buygump