diff options
author | Rawng <rawng.github@gmail.com> | 2015-06-01 19:56:10 -0400 |
---|---|---|
committer | Rawng <rawng.github@gmail.com> | 2015-06-01 19:56:10 -0400 |
commit | 1e8140f0f62ecfd0ccbe046cf6ea9faed926f327 (patch) | |
tree | ca92a7a0cd2256ffbb0b43563ee183400d1aacc5 /main.py | |
parent | b4f19a8e28cf09b7c8a042c8faf068217669bca5 (diff) | |
parent | b7e3823588ae9354daf5fc0a0cbf27b699afb7d5 (diff) | |
download | manamarket-1e8140f0f62ecfd0ccbe046cf6ea9faed926f327.tar.gz manamarket-1e8140f0f62ecfd0ccbe046cf6ea9faed926f327.tar.bz2 manamarket-1e8140f0f62ecfd0ccbe046cf6ea9faed926f327.tar.xz manamarket-1e8140f0f62ecfd0ccbe046cf6ea9faed926f327.zip |
Merge branch 'storage'
Diffstat (limited to 'main.py')
-rwxr-xr-x | main.py | 307 |
1 files changed, 240 insertions, 67 deletions
@@ -22,7 +22,6 @@ this program. If not, see <http://www.gnu.org/licenses/>. Additionally to the GPL, you are *strongly* encouraged to share any modifications you do on these sources. """ - import logging import logging.handlers import socket @@ -41,6 +40,7 @@ from net.packet import * from net.protocol import * from net.packet_out import * from player import * +from storage import * import tradey import utils import eliza @@ -50,12 +50,74 @@ shop_broadcaster = utils.Broadcast() trader_state = utils.TraderState() ItemDB = utils.ItemDB() player_node = Player('') +storage = Storage() beingManager = BeingManager() user_tree = tradey.UserTree() sale_tree = tradey.ItemTree() +stack_tree = tradey.StackTree() +delisted_tree = tradey.DelistedTree() ItemLog = utils.ItemLog() +DelistedLog = utils.DelistedLog() logger = logging.getLogger('ManaLogger') +def do_delist(): + cleaned = 0 + for elem in sale_tree.root: + item = Item() + item.index = player_node.find_inventory_index(int(elem.get('itemId'))) + item.itemId = int(elem.get('itemId')) + item.amount = int(elem.get('amount')) + if time.time() - float(elem.get('add_time')) > config.delist_time: + try: + storage.storage_send(item.index, item.amount) + except: + logger.info("Couldn't send item to storage") + return -10 + storage.add_item(item) + player_node.remove_item(item.index, item.amount) + delisted_tree.add_item(elem.get('name'), item.itemId, item.amount) + sale_tree.remove_item_uid(int(elem.get('uid'))) + DelistedLog.add_item(item.itemId, item.amount, elem.get('name')) + cleaned += 1 + if cleaned > 0: + logger.info("Delisting routine done. %d items added to delisted.xml", cleaned) + stacked = len(stack_tree.u_id) + if stacked > 0: + if cleaned - stacked < 0: + stacked = cleaned + while stacked: + err = unstack() + if err == -10: + return err + else: + stacked -= 1 + return 0 + +def unstack(): + elem = stack_tree.get_uid(stack_tree.next_id) + index = storage.find_storage_index(int(elem.get('itemId'))) + try: + storage.storage_get(index, int(elem.get('amount'))) + except: + logger.info("Couldn't remove item from storage") + return -10 + + storage.remove_item(index, int(elem.get('amount'))) + sale_tree.add_item(elem.get('name'), int(elem.get('itemId')), int(elem.get('amount')), int(elem.get('price'))) + stack_tree.remove_item_uid(stack_tree.next_id) + return 0 + +def storage_operation(func, args=[]): + storage.storage_open() + # Using a timed thread here to wait storage response. + # Main reason: time.sleep() stops execution, thus it denies storage to open. Yeah, that bad. + timer = utils.CustomTimer(2.0, func, args) + timer.start() + result = timer.join() + if timer.finished: + storage.storage_close() + return result + def process_whisper(nick, msg, mapserv): msg = filter(lambda x: x in utils.allowed_chars, msg) if len(msg) == 0: @@ -90,7 +152,7 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "No items for sale.")) for elem in sale_tree.root: - if time.time() - float(elem.get('add_time')) < config.relist_time: # Check if an items time is up. + if time.time() - float(elem.get('add_time')) < config.delist_time: # Check if an items time is up. msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + \ elem.get("itemId") + "|" + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" mapserv.sendall(whisper(nick, msg)) @@ -100,7 +162,7 @@ def process_whisper(nick, msg, mapserv): data = '\302\202B1' for elem in sale_tree.root: - if time.time() - float(elem.get('add_time')) < config.relist_time: + if time.time() - float(elem.get('add_time')) < config.delist_time: # Check if an items time is up. data += utils.encode_str(int(elem.get("itemId")), 2) data += utils.encode_str(int(elem.get("price")), 4) data += utils.encode_str(int(elem.get("amount")), 3) @@ -131,10 +193,10 @@ def process_whisper(nick, msg, mapserv): items_for_sale = False for elem in sale_tree.root: if elem.get('name') == nick: - if time.time() - float(elem.get('add_time')) > config.relist_time: - msg = "[expired] [" - else: + if time.time() - float(elem.get('add_time')) < config.delist_time: msg = "[selling] [" + else: + msg = "[expired] [" msg += elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" + \ ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" @@ -145,8 +207,38 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, msg)) + for elem in stack_tree.root: + if elem.get('name') == nick: + msg = "[waiting] [" + + msg += elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" + \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" + + if items_for_sale == False: + mapserv.sendall(whisper(nick, "Your have the following items waiting for sale:")) + items_for_sale = True + + mapserv.sendall(whisper(nick, msg)) + if items_for_sale == False: mapserv.sendall(whisper(nick, "You have no items for sale.")) + + items_for_getback = False + for elem in delisted_tree.root: + if elem.get('name') == nick: + msg = "[expired] [" + + msg += elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" + \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@]" + + if items_for_getback == False: + mapserv.sendall(whisper(nick, "Your have the following items waiting for getback:")) + items_for_getback = True + + mapserv.sendall(whisper(nick, msg)) + + if items_for_sale == False: + mapserv.sendall(whisper(nick, "You have no expired items.")) money = int(user.get('money')) mapserv.sendall(whisper(nick, "You have " + str(money) + "gp to collect.")) @@ -157,7 +249,7 @@ def process_whisper(nick, msg, mapserv): # Sends help information if len(broken_string) == 1: mapserv.sendall(whisper(nick, "Welcome to ManaMarket!")) - mapserv.sendall(whisper(nick, "The basic commands for the bot are: !list, !find <id> or <Item Name>, !buy <amount> <uid>, !add <amount> <price> <Item Name>, !money, !relist <uid>, !info, !getback <uid> ")) + mapserv.sendall(whisper(nick, "The basic commands for the bot are: !list, !find <id> or <Item Name>, !buy <amount> <uid>, !add <amount> <price> <Item Name>, !money, !info, !getback <uid> ")) mapserv.sendall(whisper(nick, "For a detailed description of each command, type !help <command> e.g. !help !buy")) mapserv.sendall(whisper(nick, "For example to purchase an item shown in the list as:")) mapserv.sendall(whisper(nick, "[selling] [6] 5 [@@640|Iron Ore@@] for 1000gp each")) @@ -189,8 +281,6 @@ def process_whisper(nick, msg, mapserv): mapserv.sendall(whisper(nick, "!add <amount> <price> <Item Name> - Add an item to the sell list (requires that you have an account).")) elif broken_string[1] == '!money': mapserv.sendall(whisper(nick, "!money - Allows you to collect money for any sales made on your behalf.")) - elif broken_string[1] == '!relist': - mapserv.sendall(whisper(nick, "!relist <uid> - Allows you to relist an item which has expired.")) elif broken_string[1] == '!info': mapserv.sendall(whisper(nick, "!info - Displays basic information about your account.")) elif broken_string[1] == '!getback': @@ -217,6 +307,9 @@ def process_whisper(nick, msg, mapserv): if not trader_state.Trading.testandset(): mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) return + if not storage.Open.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with storage. Try again shortly")) + return trader_state.money = nick player_id = beingManager.findId(nick) @@ -238,20 +331,32 @@ def process_whisper(nick, msg, mapserv): if item.isdigit(): # an id for elem in sale_tree.root: - if ((time.time() - float(elem.get('add_time'))) < config.relist_time) \ - and int(elem.get("itemId")) == int(item): # Check if an items time is up. + if int(elem.get("itemId")) == int(item): msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" mapserv.sendall(whisper(nick, msg)) items_found = True + if not items_found: # if no items on list, gives priority to stack + for elem in stack_tree.root: + if int(elem.get("itemId")) == int(item): + msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" + mapserv.sendall(whisper(nick, msg)) + items_found = True else: # an item name for elem in sale_tree.root: - if ((time.time() - float(elem.get('add_time'))) < config.relist_time) \ - and item.lower() in ItemDB.getItem(int(elem.get("itemId"))).name.lower(): # Check if an items time is up. + if item.lower() in ItemDB.getItem(int(elem.get("itemId"))).name.lower(): msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" mapserv.sendall(whisper(nick, msg)) items_found = True + if not items_found: # if no items on list, gives priority to stack + for elem in stack_tree.root: + if item.lower() in ItemDB.getItem(int(elem.get("itemId"))).name.lower(): + msg = "[selling] [" + elem.get("uid") + "] " + elem.get("amount") + " [@@" + elem.get("itemId") + "|" \ + + ItemDB.getItem(int(elem.get("itemId"))).name + "@@] for " + elem.get("price") + "gp each" + mapserv.sendall(whisper(nick, msg)) + items_found = True if not items_found: mapserv.sendall(whisper(nick, "Item not found.")) @@ -267,6 +372,8 @@ def process_whisper(nick, msg, mapserv): if trader_state.Trading.test(): mapserv.sendall(whisper(nick, "I'm busy with a trade.")) + elif storage.Open.test(): + mapserv.sendall(whisper(nick, "I'm busy with storage.")) else: mapserv.sendall(whisper(nick, "I'm free.")) @@ -283,7 +390,12 @@ def process_whisper(nick, msg, mapserv): if broken_string[1].isdigit(): uid = int(broken_string[1]) - item_info = sale_tree.get_uid(uid) + if uid <= MAX_INVENTORY: + item_info = sale_tree.get_uid(uid) + elif uid > MAX_INVENTORY and uid <= MAX_STORAGE: + item_info = stack_tree.get_uid(uid) + else: + item_info = delisted_tree.get_uid(uid) if item_info == -10: mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) @@ -480,6 +592,9 @@ def process_whisper(nick, msg, mapserv): if not trader_state.Trading.testandset(): mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) return + if not storage.Open.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with storage. Try again shortly")) + return trader_state.item = item player_id = beingManager.findId(nick) @@ -501,7 +616,10 @@ def process_whisper(nick, msg, mapserv): if broken_string[1].isdigit() and broken_string[2].isdigit(): amount = int(broken_string[1]) uid = int(broken_string[2]) - item_info = sale_tree.get_uid(uid) + if uid <= MAX_INVENTORY: + item_info = sale_tree.get_uid(uid) + else: + item_info = stack_tree.get_uid(uid) if item_info == -10: mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) @@ -526,6 +644,9 @@ def process_whisper(nick, msg, mapserv): if not trader_state.Trading.testandset(): mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) return + if not storage.Open.testandset(): + mapserv.sendall(whisper(nick, "I'm currently buse with storage. Try again shortly")) + return trader_state.item = item player_id = beingManager.findId(nick) @@ -560,43 +681,6 @@ def process_whisper(nick, msg, mapserv): elif check == -10: mapserv.sendall(whisper(nick, "User removal failed. Please check spelling.")) - elif broken_string[0] == "!relist": - # Relist an item which has expired - !relist <uid>. - if user == -10 or len(broken_string) != 2: - mapserv.sendall(whisper(nick, "Syntax incorrect.")) - return - - if int(user.get("accesslevel")) < 5: - mapserv.sendall(whisper(nick, "You don't have the correct permissions.")) - return - - if broken_string[1].isdigit(): - uid = int(broken_string[1]) - item_info = sale_tree.get_uid(uid) - - if item_info == -10: - mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) - return - - if item_info.get('name') != nick: - mapserv.sendall(whisper(nick, "That doesn't belong to you!")) - return - - time_relisted = int(item_info.get('relisted')) - - if int(item_info.get('relisted')) < 3: - sale_tree.get_uid(uid).set('add_time', str(time.time())) - sale_tree.get_uid(uid).set('relisted', str(time_relisted + 1)) - sale_tree.save() - mapserv.sendall(whisper(nick, "The item has been successfully relisted.")) - user_tree.get_user(nick).set('last_use', str(time.time())) - user_tree.save() - else: - mapserv.sendall(whisper(nick, "This item can no longer be relisted. Please collect it using !getback "+str(uid)+".")) - return - else: - mapserv.sendall(whisper(nick, "Syntax incorrect.")) - elif broken_string[0] == "!getback": # Trade the player back uid, remove from sale_items if trade successful - !getback <uid>. if user == -10 or len(broken_string) != 2: @@ -609,7 +693,12 @@ def process_whisper(nick, msg, mapserv): if broken_string[1].isdigit(): uid = int(broken_string[1]) - item_info = sale_tree.get_uid(uid) + if uid <= MAX_INVENTORY: + item_info = sale_tree.get_uid(uid) + elif uid > MAX_INVENTORY and uid <= MAX_STORAGE: + item_info = stack_tree.get_uid(uid) + else: + item_info = delisted_tree.get_uid(uid) if item_info == -10: mapserv.sendall(whisper(nick, "Item not found. Please check the uid number and try again.")) @@ -630,10 +719,16 @@ def process_whisper(nick, msg, mapserv): if not trader_state.Trading.testandset(): mapserv.sendall(whisper(nick, "I'm currently busy with a trade. Try again shortly")) return + if not storage.Open.testandset(): + mapserv.sendall(whisper(nick, "I'm currently busy with storage. Try again shortly")) + return trader_state.item = item player_id = beingManager.findId(nick) if player_id != -10: + if uid > MAX_INVENTORY: + item.index = storage.find_storage_index(item.id) + storage_operation(storage.storage_get, (item.index, item.amount)) mapserv.sendall(trade_request(player_id)) trader_state.timer = time.time() else: @@ -770,6 +865,7 @@ def main(): pb = PacketBuffer() shop_broadcaster.mapserv = mapserv + storage.mapserv = mapserv # Map server packet loop print "Entering map packet loop\n"; @@ -785,6 +881,12 @@ def main(): logger.info("Trade Cancelled - Timeout.") trader_state.timer = time.time() mapserv.sendall(str(PacketOut(CMSG_TRADE_CANCEL_REQUEST))) + + # The same applies to storage, now + if storage.Open.test(): + if time.time() - storage.timer > 2*60: + logger.info("Storage operation cancelled - Timeout.") + storage.storage_close() for packet in pb: if packet.is_type(SMSG_MAP_LOGIN_SUCCESS): # connected @@ -870,12 +972,19 @@ def main(): err = packet.read_int8() if err == 0: - if item.index in player_node.inventory: - player_node.inventory[item.index].amount += item.amount - else: - player_node.inventory[item.index] = item + if len(player_node.inventory) < MAX_INVENTORY: + if item.index in player_node.inventory: + player_node.inventory[item.index].amount += item.amount + else: + player_node.inventory[item.index] = item + placement = "Inventory" + else: # If only one slot left, move to stack + err = storage_operation(storage.storage_send, (item.index, item.amount)) + if err == 0: + item.index = storage.add_item(item) + placement = "Storage" - logger.info("Picked up: %s, Amount: %s, Index: %s", ItemDB.getItem(item.itemId).name, str(item.amount), str(item.index)) + logger.info("Picked up: %s, Amount: %s, Index: %s - %s", ItemDB.getItem(item.itemId).name, str(item.amount), str(item.index), placement) elif packet.is_type(SMSG_PLAYER_INVENTORY_REMOVE): index = packet.read_int16() - inventory_offset @@ -884,6 +993,10 @@ def main(): logger.info("Remove item: %s, Amount: %s, Index: %s", ItemDB.getItem(player_node.inventory[index].itemId).name, str(amount), str(index)) player_node.remove_item(index, amount) + # Now taking an item from stack if inventory was full before + if len(player_node.inventory) == MAX_INVENTORY-1: + storage_operation(unstack) + elif packet.is_type(SMSG_PLAYER_INVENTORY): player_node.inventory.clear() # Clear the inventory - incase of new index. packet.skip(2) @@ -922,6 +1035,47 @@ def main(): else: logger.info("Inventory Check Passed.") + # IMO the best moment to run delisting + storage_operation(do_delist) + + elif packet.is_type(SMSG_PLAYER_STORAGE_ITEMS): + storage.storage.clear() # Clear storage - same as inventory. + packet.skip(2) + number = (len(packet.data)-2) / 18 + for loop in range(number): + item = Item() + item.index = packet.read_int16() - storage_offset + item.itemId = packet.read_int16() + packet.skip(2) + item.amount = packet.read_int16() + packet.skip(10) + storage.storage[item.index] = item + + elif packet.is_type(SMSG_PLAYER_STORAGE_EQUIP): + packet.read_int16() + number = (len(packet.data)) / 20 + for loop in range(number): + item = Item() + item.index = packet.read_int16() - storage_offset + item.itemId = packet.read_int16() + packet.skip(16) + item.amount = 1 + storage.storage[item.index] = item + + logger.info("Storage information received:") + for item in storage.storage: + logger.info("Name: %s, Id: %s, Index: %s, Amount: %s.", \ + ItemDB.getItem(storage.storage[item].itemId).name, \ + storage.storage[item].itemId, item, storage.storage[item].amount) + + errorOccured = storage.check_storage(stack_tree, delisted_tree) + if errorOccured: + logger.info(errorOccured) + shop_broadcaster.stop() + sys.exit(1) + else: + logger.info("Storage Check Passed.") + elif packet.is_type(SMSG_TRADE_REQUEST): name = packet.read_string(24) logger.info("Trade request: " + name) @@ -1062,24 +1216,39 @@ def main(): elif packet.is_type(SMSG_TRADE_COMPLETE): commitMessage="" - # The sale_tree is only ammended after a complete trade packet. + # we get here which tree it should be through UID + if trader_state.item.get == 1: + if len(player_node.inventory) <= MAX_INVENTORY: + tree = sale_tree + else: + tree = stack_tree + elif trader_state.item.get == 0: + if trader_state.item.uid <= MAX_INVENTORY: + tree = sale_tree + elif trader_state.item.uid > MAX_INVENTORY \ + and trader_state.item.uid <= MAX_STORAGE: + tree = stack_tree + else: + tree = delisted_tree + + # The trees are only ammended after a complete trade packet. if trader_state.item and trader_state.money == 0: if trader_state.item.get == 1: # !add - sale_tree.add_item(trader_state.item.player, trader_state.item.id, trader_state.item.amount, trader_state.item.price) + tree.add_item(trader_state.item.player, trader_state.item.id, trader_state.item.amount, trader_state.item.price) user_tree.get_user(trader_state.item.player).set('used_stalls', \ str(int(user_tree.get_user(trader_state.item.player).get('used_stalls')) + 1)) user_tree.get_user(trader_state.item.player).set('last_use', str(time.time())) commitMessage = "Add" elif trader_state.item.get == 0: # !buy \ !getback - seller = sale_tree.get_uid(trader_state.item.uid).get('name') - item = sale_tree.get_uid(trader_state.item.uid) + seller = tree.get_uid(trader_state.item.uid).get('name') + item = tree.get_uid(trader_state.item.uid) current_amount = int(item.get("amount")) - sale_tree.get_uid(trader_state.item.uid).set("amount", str(current_amount - trader_state.item.amount)) + tree.get_uid(trader_state.item.uid).set("amount", str(current_amount - trader_state.item.amount)) if int(item.get("amount")) == 0: - user_tree.get_user(sale_tree.get_uid(trader_state.item.uid).get('name')).set('used_stalls', \ - str(int(user_tree.get_user(sale_tree.get_uid(trader_state.item.uid).get('name')).get('used_stalls'))-1)) - sale_tree.remove_item_uid(trader_state.item.uid) + user_tree.get_user(tree.get_uid(trader_state.item.uid).get('name')).set('used_stalls', \ + str(int(user_tree.get_user(tree.get_uid(trader_state.item.uid).get('name')).get('used_stalls'))-1)) + tree.remove_item_uid(trader_state.item.uid) current_money = int(user_tree.get_user(seller).get("money")) user_tree.get_user(seller).set("money", str(current_money + trader_state.item.price * trader_state.item.amount)) @@ -1092,7 +1261,7 @@ def main(): user_tree.get_user(trader_state.money).set('money', str(0)) commitMessage = "Money" - sale_tree.save() + tree.save() user_tree.save() tradey.saveData(commitMessage) @@ -1104,6 +1273,10 @@ def main(): logger.info(errorOccured) shop_broadcaster.stop() sys.exit(1) + + elif packet.is_type(SMSG_PLAYER_STORAGE_CLOSE): + storage.reset() + else: pass |