def send_map(map_id, *args): map_obj = general.get_map(map_id) if not map_obj: error = "send_map: map_id %s not exist."%map_id general.log_error(error) return error send_map_obj(map_id, *args)
def handle_cmd(pc, cmd): if not (cmd.startswith("/") or cmd.startswith("~")): return l = filter(None, cmd[1:].split(" ")) if not l: return name, args = l[0], l[1:] types = NAME_WITH_TYPE.get(name) if types is None: return try: request_gmlevel = env.GMLEVEL_MAP.get(name) if request_gmlevel is None: raise Exception("env.GMLEVEL_MAP[%s] not exist" % name) if pc.gmlevel < request_gmlevel: raise Exception("pc.gmlevel < request_gmlevel") try: for i, arg in enumerate(args): if not types[i]: continue args[i] = types[i](arg) except IndexError: pass name_map.get(name)(pc, *args) except: exc_info = traceback.format_exc() msg(pc, filter(None, exc_info.split("\n"))[-1]) general.log_error("script.handle_cmd [%s] error:\n" % cmd, exc_info) return True
def run_script(pc, event_id, item_event_id=0): #general.log("run script id", event_id) with pc.lock and pc.user.lock: lock_move(pc) pc.event_id = event_id pc.item_event_id = item_event_id pc.map_send("05dc") #イベント開始の通知 pc.map_send("05e8", event_id) #EventID通知 Event送信に対する応答 if usermaps.map_id_in_range_flygarden(event_id): script_id = usermaps.MIN_FLYGARDEN_ID else: script_id = event_id with script_list_lock: event = script_list.get(script_id) try: if event: event["main"](pc) else: say(pc, "Script id %s not exist." % script_id, "") #raise ValueError("Script id not exist") except: general.log_error("run_script", event_id, traceback.format_exc()) with pc.lock and pc.user.lock: pc.event_id = 0 pc.item_event_id = 0 if pc.online: pc.map_send("05dd") #イベント終了の通知 unlock_move(pc)
def handle_data(self, data_decode): #000a 0001 000003f91e07e221 data_decode_io = general.stringio(data_decode) while True: data = io_unpack_short_raw(data_decode_io) if not data: break data_io = general.stringio(data) data_type = data_io.read(2).encode("hex") if data_type not in DATA_TYPE_NOT_PRINT: general.log("[ map ]", data[:2].encode("hex"), data[2:].encode("hex")) handler = self.name_map.get(data_type) if not handler: general.log_error("[ map ] unknow packet type", data[:2].encode("hex"), data[2:].encode("hex")) return try: handler(self, data_io) except: general.log_error("[ map ] handle_data error:", data.encode("hex")) general.log_error(traceback.format_exc()) if data_type in DATA_TYPE_CANCEL_TRADE_WHEN_EXCEPT: try: self.pc.cancel_trade() except: general.log_error("[ map ] cancel trade when except error:") general.log_error(traceback.format_exc())
def unset_usermap(pc, logout=False): with pc.lock: if not pc.usermap_obj: return i = pc.usermap_obj.id general.log("[umaps] del usermap id", i) usermap_obj = pc.usermap_obj map_obj = general.get_map(usermap_obj.entrance_map_id) if not map_obj: general.log_error( "[umaps] unset_usermap error: entrance_map_id not exist", usermap_obj.entrance_map_id, ) return if logout: script.send_map_obj(map_obj, (pc,), "0bb9", pc) #飛空庭のひも・テント消去 else: script.send_map_obj(map_obj, (), "0bb9", pc) #飛空庭のひも・テント消去 for p in general.copy(usermap_obj.pc_list): if logout and p == pc: pc.set_map(usermap_obj.entrance_map_id) pc.set_coord(usermap_obj.entrance_x, usermap_obj.entrance_y) continue try: script.warp( p, usermap_obj.entrance_map_id, usermap_obj.entrance_x, usermap_obj.entrance_y, ) except: general.log_error(traceback.format_exc()) with usermap_list_lock: del usermap_list[i] pc.usermap_obj = None
def send_map(map_id, *args): map_obj = general.get_map(map_id) if not map_obj: error = "send_map: map_id %s not exist." % map_id general.log_error(error) return error send_map_obj(map_id, *args)
def send_map(self, *args): with self.pc.lock: if not self.pc.map_obj: general.log_error("[ map ] send_map: not self.pc.map_obj", self.pc) return script.send_map_obj(self.pc.map_obj, (), *args)
def use_thread(mod, pc, target_id, x, y, skill_id, skill_lv): try: #with pc.lock: #remove global lock because time.sleep blocking mod(pc, target_id, x, y, skill_id, skill_lv) except: general.log_error("[skill] error", pc, target_id, x, y, skill_id, skill_lv) general.log_error(traceback.format_exc())
def handle_data(self, data_decode): #000a 0001 000003f91e07e221 data_decode_io = general.stringio(data_decode) while True: data = io_unpack_short_raw(data_decode_io) if not data: break data_io = general.stringio(data) data_type = data_io.read(2).encode("hex") if data_type not in DATA_TYPE_NOT_PRINT: general.log("[ map ]", data[:2].encode("hex"), data[2:].encode("hex")) handler = self.name_map.get(data_type) if not handler: general.log_error("[ map ] unknow packet type", data[:2].encode("hex"), data[2:].encode("hex")) return try: handler(self, data_io) except: general.log_error("[ map ] handle_data error:", data.encode("hex")) general.log_error(traceback.format_exc()) if data_type in DATA_TYPE_CANCEL_TRADE_WHEN_EXCEPT: try: self.pc.cancel_trade() except: general.log_error( "[ map ] cancel trade when except error:") general.log_error(traceback.format_exc())
def run_script(pc, event_id, item_event_id=0): #general.log("run script id", event_id) with pc.lock and pc.user.lock: lock_move(pc) pc.event_id = event_id pc.item_event_id = item_event_id pc.map_send("05dc") #イベント開始の通知 pc.map_send("05e8", event_id) #EventID通知 Event送信に対する応答 if usermaps.map_id_in_range_flygarden(event_id): script_id = usermaps.MIN_FLYGARDEN_ID else: script_id = event_id with script_list_lock: event = script_list.get(script_id) try: if event: event["main"](pc) else: say(pc, "Script id %s not exist."%script_id, "") #raise ValueError("Script id not exist") except: general.log_error("run_script", event_id, traceback.format_exc()) with pc.lock and pc.user.lock: pc.event_id = 0 pc.item_event_id = 0 if pc.online: pc.map_send("05dd") #イベント終了の通知 unlock_move(pc)
def handle_cmd(pc, cmd): if not (cmd.startswith("/") or cmd.startswith("~")): return l = filter(None, cmd[1:].split(" ")) if not l: return name, args = l[0], l[1:] types = NAME_WITH_TYPE.get(name) if types is None: return try: request_gmlevel = env.GMLEVEL_MAP.get(name) if request_gmlevel is None: raise Exception("env.GMLEVEL_MAP[%s] not exist"%name) if pc.gmlevel < request_gmlevel: raise Exception("pc.gmlevel < request_gmlevel") try: for i, arg in enumerate(args): if not types[i]: continue args[i] = types[i](arg) except IndexError: pass name_map.get(name)(pc, *args) except: exc_info = traceback.format_exc() msg(pc, filter(None, exc_info.split("\n"))[-1]) general.log_error("script.handle_cmd [%s] error:\n"%cmd, exc_info) return True
def npcshop(pc, shop_id): shop = db.shop.get(shop_id) if not shop: general.log_error("npc shop id %s not exist" % shop_id) return with pc.lock and pc.user.lock: pc.shop_open = shop_id pc.map_send("0613", pc, shop.item) #NPCのショップウィンドウ
def npcshop(pc, shop_id): shop = db.shop.get(shop_id) if not shop: general.log_error("npc shop id %s not exist"%shop_id) return with pc.lock and pc.user.lock: pc.shop_open = shop_id pc.map_send("0613", pc, shop.item) #NPCのショップウィンドウ
def send_server(*args): with users.user_list_lock: for p in users.get_pc_list(): try: if not p.online: continue p.map_send(*args) except: general.log_error("send_server error: %s"%traceback.format_exc())
def get_job_status(self): job = db.job.get(self.job) if not job: general.log_error("[ pc ] unknow job id:", self.job) return status.maxhp = int(status.maxhp*job.hp_rate) status.maxmp = int(status.maxmp*job.mp_rate) status.maxsp = int(status.maxsp*job.sp_rate) status.maxpayl = status.maxpayl*job.payl_rate status.maxcapa = status.maxcapa*job.capa_rate
def run(self): try: general.log("[ pet ] %s start"%self) self.wait_move_time = time.time()+1 while self.running: self._run() time.sleep(0.1) except: general.log_error(traceback.format_exc()) general.log_error(self, self.master)
def get_job_status(self): job = db.job.get(self.job) if not job: general.log_error("[ pc ] unknow job id:", self.job) return status.maxhp = int(status.maxhp * job.hp_rate) status.maxmp = int(status.maxmp * job.mp_rate) status.maxsp = int(status.maxsp * job.sp_rate) status.maxpayl = status.maxpayl * job.payl_rate status.maxcapa = status.maxcapa * job.capa_rate
def send_server(*args): with users.user_list_lock: for p in users.get_pc_list(): try: if not p.online: continue p.map_send(*args) except: general.log_error("send_server error: %s" % traceback.format_exc())
def run(pc, event_id, item_event_id=0): #vulnerability: #* send a lot of event or skill request can make thread number #* reached the system limits #if pc.event_id is not None or pc.item_event_id is not None: # general.log_error("script.run error: event duplicate", pc, pc.event_id) # return if not event_id: general.log_error("[event] event_id null", pc, event_id) return general.start_thread(run_script, (pc, event_id, item_event_id))
def warehouse_pop(self, iid): with self.lock: try: item = self.warehouse.pop(iid) self.sort.warehouse.remove(iid) except KeyError: general.log_error(traceback.format_exc()) return None if self.online: script.msg(self, "%sを%s個取り出しました" % (item.name, item.count)) return item
def run(self): while self.running: try: s, src = self.socket.accept() if not self.ip_count_check(src): s.close() continue with self.client_list_lock: self.client_list.append(self.client_class(self, s, src)) except: general.log_error(traceback.format_exc())
def warehouse_pop(self, iid): with self.lock: try: item = self.warehouse.pop(iid) self.sort.warehouse.remove(iid) except KeyError: general.log_error(traceback.format_exc()) return None if self.online: script.msg(self, "%sを%s個取り出しました"%(item.name, item.count)) return item
def run(self): try: self.recv_init() self.recv_key() while self.running: self.handle_packet() except EOFError: self.stop() except: general.log_error(traceback.format_exc()) self.stop() general.log("[ srv ] quit", self)
def send_map_obj(map_obj, without_list, *args): #don't lock pc and pc.user, easy to cause deadlock with map_obj.lock: for p in map_obj.pc_list: try: if not p.online: continue if p in without_list: continue p.map_send(*args) except: general.log_error("send_map error: %s"%traceback.format_exc())
def make(data_type, *args): if args and hasattr(args[0], "lock"): with args[0].lock: data_value = name_map[data_type](*args) else: data_value = name_map[data_type](*args) if data_value is None: general.log_error("packet make error:", data_type, args) return "" packet = pack_short(len(data_value)+2) packet += data_type.decode("hex") packet += data_value return packet
def item_pop(self, iid): with self.lock: try: item = self.item.pop(iid) self.sort.item.remove(iid) except KeyError: general.log_error(traceback.format_exc()) return None if self.online: #インベントリからアイテム消去 self.map_send("09ce", iid) script.msg(self, "%sを%s個失いました"%(item.name, item.count)) return item
def do_0f9f(self, data_io): #攻撃 monster_id = io_unpack_int(data_io) monster = monsters.get_monster_from_id(monster_id) if not monster: general.log_error("[ map ] monster id %s not exist"%monster_id) return general.log("[ map ] attack monster id %s"%monster_id) with self.pc.lock: self.pc.attack = True self.pc.attack_monster = monster self.pc.attack_delay = self.pc.status.delay_attack monsters.attack_monster(self.pc, monster)
def item_pop(self, iid): with self.lock: try: item = self.item.pop(iid) self.sort.item.remove(iid) except KeyError: general.log_error(traceback.format_exc()) return None if self.online: #インベントリからアイテム消去 self.map_send("09ce", iid) script.msg(self, "%sを%s個失いました" % (item.name, item.count)) return item
def do_0f9f(self, data_io): #攻撃 monster_id = io_unpack_int(data_io) monster = monsters.get_monster_from_id(monster_id) if not monster: general.log_error("[ map ] monster id %s not exist" % monster_id) return general.log("[ map ] attack monster id %s" % monster_id) with self.pc.lock: self.pc.attack = True self.pc.attack_monster = monster self.pc.attack_delay = self.pc.status.delay_attack monsters.attack_monster(self.pc, monster)
def send_map_obj(map_obj, without_list, *args): #don't lock pc and pc.user, easy to cause deadlock with map_obj.lock: for p in map_obj.pc_list: try: if not p.online: continue if p in without_list: continue p.map_send(*args) except: general.log_error("send_map error: %s" % traceback.format_exc())
def make_0020(user, _type): """アカウント認証結果/ログアウト開始/ログアウトキャンセル""" if _type == "loginsucess": return "\x00\x00\x00\x00"+pack_int(user.user_id)+"\x00\x00\x00\x00"*2 elif _type == "loginfaild": return "\xFF\xFF\xFF\xFE"+pack_int(user.user_id)+"\x00\x00\x00\x00"*2 elif _type == "isonline": return "\xFF\xFF\xFF\xFB"+pack_int(user.user_id)+"\x00\x00\x00\x00"*2 elif _type == "logoutstart": return "\x00" elif _type == "logoutcancel": return "\xF9" else: general.log_error("make_0020: type not exist", _type)
def damage(self, i): with self.lock: if self.status.hp <= 0: general.log_error("[monster] monster.hp <= 0", self) return 0 state_list = dict((j, 0) for j in xrange(10)) self.status.hp -= i if self.status.hp <= 0: self.status.hp = 0 state_list[0] |= 0x200 #行動不能 general.start_thread(monsters.delete_monster_thread, (self,)) script.send_map_obj(self.map_obj, (), "021c", self) #現在のHP/MP/SP/EP script.send_map_obj(self.map_obj, (), "157c", self, state_list) #キャラの状態 return self.status.hp
def damage(self, i): with self.lock: if self.status.hp <= 0: general.log_error("[monster] monster.hp <= 0", self) return 0 state_list = dict((j, 0) for j in xrange(10)) self.status.hp -= i if self.status.hp <= 0: self.status.hp = 0 state_list[0] |= 0x200 #行動不能 general.start_thread(monsters.delete_monster_thread, (self, )) script.send_map_obj(self.map_obj, (), "021c", self) #現在のHP/MP/SP/EP script.send_map_obj(self.map_obj, (), "157c", self, state_list) #キャラの状態 return self.status.hp
def make_00a1(_type): """キャラクター作成結果""" if _type == "sucess": return "\x00\x00\x00\x00" elif _type == "nametoolong": return "\xff\xff\xff\x9c" elif _type == "slotexist": return "\xff\xff\xff\x9d" elif _type == "nameexist": return "\xff\xff\xff\x9e" elif _type == "nametooshort": return "\xff\xff\xff\x9f" elif _type == "namebadchar": return "\xff\xff\xff\xa0" elif _type == "other": return "\xff\xff\xff\xff" else: general.log_error("make_00a1: type not exist", _type)
def load(): global general, PC, server from lib import general from lib.obj.pc import PC from lib import server with user_list_lock: for name in os.listdir(env.USER_DIR): try: user_list.append(User(name, os.path.join(env.USER_DIR, name))) except: general.log_error("load error:", name) raise #for user in get_user_list(): # general.log(user) #for p in get_pc_list(): # general.log(p) if env.BACKUP_USER_DATA_EVERY_DAY: backup_user_data_every_day() save_user_data_every_min()
def debugger(): general.log("[debug] load time %s"%(time.time()-env.LOAD_STARTUP_TIME)) general.log("[debug] interpreter start") while True: try: input_debug = raw_input() if input_debug in ("exit", "halt", "quit", "q"): raise SystemExit() except (SystemExit, EOFError, IOError, KeyboardInterrupt): if raw_input("Are you sure to exit? [y/N]: ").strip().lower() == "y": return continue except: general.log_error("[debug]", traceback.format_exc()) try: try: general.log(eval(input_debug)) except SyntaxError: exec input_debug except: general.log_error("[debug]", traceback.format_exc())
def load(): global server, monsters if not server or not monsters: #skip search sys.modules from lib import server from lib import monsters with script_list_lock: general.log_line("[load ] load %-20s"%("%s ..."%env.SCRIPT_DIR)) script_list.clear() for root, dirs, files in os.walk(env.SCRIPT_DIR): for name in files: if not name.endswith(".py"): continue if name.startswith("__"): continue path = os.path.join(root, name) #general.log("load script", path) try: load_single(path) except: general.log_error("script.load", path, traceback.format_exc()) general.log(" %d script load."%len(script_list))
def takeitem_byiid(pc, item_iid, item_count): general.assert_value_range("item_iid", item_iid, general.RANGE_UNSIGNED_INT) general.assert_value_range("item_count", item_count, general.RANGE_UNSIGNED_SHORT) with pc.lock and pc.user.lock: item_exist = pc.item.get(item_iid) item_return = None error = 0 if not item_exist: error = -2 #存在しないアイテムです general.log_error("takeitem byiid: iid not exist", item_iid) elif pc.in_equip(item_iid): error = -11 #装備中のアイテムは捨てることが出来ません general.log_error("takeitem byiid: iid not exist", item_iid) elif item_exist.count < item_count: error = -22 #ロックアイテムは捨てることが出来ません general.log_error("takeitem byiid: item.count < item_count", item_count) elif item_exist.count > item_count: item_exist.count -= item_count item_return = general.copy(item_exist) item_return.count = item_count pc.map_send("09cf", item_exist, item_iid) #アイテム個数変化 msg(pc, "%sを%s個失いました"%(item_exist.name, item_count)) elif item_exist.count == item_count: item_return = pc.item_pop(item_iid) return item_return, error
def do_0614(self, data_io): #NPCショップのアイテム購入 general.log("[ map ] npcshop") with self.pc.lock: if self.pc.shop_open is None: general.log_error("do_0614: shop_open is None") return if hasattr(self.pc.shop_open, "__iter__"): shop_item_list = self.pc.shop_open else: shop = db.shop.get(self.pc.shop_open) if not shop: general.log_error("do_0614 error: shop_id not exist", self.pc.shop_open) return shop_item_list = shop.item item_id_list = io_unpack_array(io_unpack_int, data_io) item_count_list = io_unpack_array(io_unpack_int, data_io) item_buy_list = zip(item_id_list, item_count_list) general.log("[ map ] item_buy_list", item_buy_list) if len(self.pc.item) + len(item_buy_list) > env.MAX_ITEM_STOCK: script.msg(self.pc, "npcshop buy error: stock limit") return for item_id, item_count in item_buy_list: if not item_count: general.log_error("do_0614 error: item_count is 0", item_count) continue if item_id not in shop_item_list: general.log_error( "do_0614 error: item_id not in shop_item_list", item_id, shop_item_list) continue item = db.item.get(item_id) if not item: general.log_error("do_0614 error: item_id not exist", item_id) continue if script.takegold(self.pc, (int(item.price / 10.0) or 1) * item_count): script.item(self.pc, item_id, item_count) self.pc.update_item_status()
def takeitem_byiid(pc, item_iid, item_count): general.assert_value_range("item_iid", item_iid, general.RANGE_UNSIGNED_INT) general.assert_value_range("item_count", item_count, general.RANGE_UNSIGNED_SHORT) with pc.lock and pc.user.lock: item_exist = pc.item.get(item_iid) item_return = None error = 0 if not item_exist: error = -2 #存在しないアイテムです general.log_error("takeitem byiid: iid not exist", item_iid) elif pc.in_equip(item_iid): error = -11 #装備中のアイテムは捨てることが出来ません general.log_error("takeitem byiid: iid not exist", item_iid) elif item_exist.count < item_count: error = -22 #ロックアイテムは捨てることが出来ません general.log_error("takeitem byiid: item.count < item_count", item_count) elif item_exist.count > item_count: item_exist.count -= item_count item_return = general.copy(item_exist) item_return.count = item_count pc.map_send("09cf", item_exist, item_iid) #アイテム個数変化 msg(pc, "%sを%s個失いました" % (item_exist.name, item_count)) elif item_exist.count == item_count: item_return = pc.item_pop(item_iid) return item_return, error
def spawn(monster_id, map_id, x, y): error = None monster = general.get_monster(monster_id) if not monster: error = "spawn: monster_id %s not exist."%monster_id general.log_error(error) return error map_obj = general.get_map(map_id) if not map_obj: error = "spawn: map_id %s not exist."%map_id general.log_error(error) return error monster.reset() with monster_list_lock and monster.lock: monster_id = general.make_id(monster_id_list, MIN_MONSTER_ID) if monster_id >= MAX_MONSTER_ID: error = "[monster] ERROR: monster_id [%s] >= MAX_MONSTER_ID"%monster_id general.log_error(error) return error monster.id = monster_id monster.set_map(map_id) monster.set_coord(x, y) monster_list.append(monster) monster_id_list.append(monster.id) script.send_map_obj(map_obj, (), "122a", (monster.id,)) #モンスターID通知 if error: delete(monster) return error general.log("[monster] spawn monster id %s"%(monster.id)) script.send_map_obj(map_obj, (), "1220", monster) #モンスター情報 script.send_map_obj(map_obj, (), "157c", monster) #キャラの状態
def spawn(monster_id, map_id, x, y): error = None monster = general.get_monster(monster_id) if not monster: error = "spawn: monster_id %s not exist." % monster_id general.log_error(error) return error map_obj = general.get_map(map_id) if not map_obj: error = "spawn: map_id %s not exist." % map_id general.log_error(error) return error monster.reset() with monster_list_lock and monster.lock: monster_id = general.make_id(monster_id_list, MIN_MONSTER_ID) if monster_id >= MAX_MONSTER_ID: error = "[monster] ERROR: monster_id [%s] >= MAX_MONSTER_ID" % monster_id general.log_error(error) return error monster.id = monster_id monster.set_map(map_id) monster.set_coord(x, y) monster_list.append(monster) monster_id_list.append(monster.id) script.send_map_obj(map_obj, (), "122a", (monster.id, )) #モンスターID通知 if error: delete(monster) return error general.log("[monster] spawn monster id %s" % (monster.id)) script.send_map_obj(map_obj, (), "1220", monster) #モンスター情報 script.send_map_obj(map_obj, (), "157c", monster) #キャラの状態
def set_pet(pc): with pc.lock: if pc.pet: #general.log("[ pet ] set_pet failed: pc.pet exist") return if not pc.equip.pet: #general.log("[ pet ] set_pet failed: pc.equip.pet not exist") return False item = pc.item.get(pc.equip.pet) if not item: #general.log("[ pet ] set_pet failed: item not exist") return False pet = general.get_pet(item.pet_id) if not pet: #general.log("[ pet ] set_pet failed: pet not exist") return False pet = obj_pet.PetObject(pet) pet.reset(item) with pet_list_lock: pet_id = general.make_id(pet_id_list, MIN_PET_ID) if pet_id >= MAX_PET_ID: general.log_error("[ pet ] ERROR: pet_id [%s] >= MAX_PET_ID" % pet_id) return False pet.id = pet_id pet_list.append(pet) pet_id_list.append(pet.id) with pc.user.lock and pet.lock: pc.pet = pet pet.master = pc if pc.item.get(pc.equip.pet).check_type(general.PET_TYPE_LIST): pet.set_map(pc.map_id) pet.set_coord_from_master() pet.set_dir(pc.dir) pet.start() pc.map_send_map("122f", pet) #pet info else: pet.start() general.log("[ pet ] set pet id %s" % (pc.pet.id)) return True
def load(): global server, monsters if not server or not monsters: #skip search sys.modules from lib import server from lib import monsters with script_list_lock: general.log_line("[load ] load %-20s" % ("%s ..." % env.SCRIPT_DIR)) script_list.clear() for root, dirs, files in os.walk(env.SCRIPT_DIR): for name in files: if not name.endswith(".py"): continue if name.startswith("__"): continue path = os.path.join(root, name) #general.log("load script", path) try: load_single(path) except: general.log_error("script.load", path, traceback.format_exc()) general.log(" %d script load." % len(script_list))
def do_0614(self, data_io): #NPCショップのアイテム購入 general.log("[ map ] npcshop") with self.pc.lock: if self.pc.shop_open is None: general.log_error("do_0614: shop_open is None") return if hasattr(self.pc.shop_open, "__iter__"): shop_item_list = self.pc.shop_open else: shop = db.shop.get(self.pc.shop_open) if not shop: general.log_error( "do_0614 error: shop_id not exist", self.pc.shop_open) return shop_item_list = shop.item item_id_list = io_unpack_array(io_unpack_int, data_io) item_count_list = io_unpack_array(io_unpack_int, data_io) item_buy_list = zip(item_id_list, item_count_list) general.log("[ map ] item_buy_list", item_buy_list) if len(self.pc.item)+len(item_buy_list) > env.MAX_ITEM_STOCK: script.msg(self.pc, "npcshop buy error: stock limit") return for item_id, item_count in item_buy_list: if not item_count: general.log_error("do_0614 error: item_count is 0", item_count) continue if item_id not in shop_item_list: general.log_error("do_0614 error: item_id not in shop_item_list", item_id, shop_item_list) continue item = db.item.get(item_id) if not item: general.log_error("do_0614 error: item_id not exist", item_id) continue if script.takegold(self.pc, (int(item.price/10.0) or 1)*item_count): script.item(self.pc, item_id, item_count) self.pc.update_item_status()
def do_0616(self, data_io): #ショップで売却 general.log("[ map ] npcsell") with self.pc.lock: if self.pc.shop_open != 65535: general.log_error("do_0616: shop_open != 65535", self.pc.shop_open) return item_iid_list = io_unpack_array(io_unpack_int, data_io) item_count_list = io_unpack_array(io_unpack_int, data_io) item_sell_list = zip(item_iid_list, item_count_list) general.log("[ map ] item_sell_list", item_sell_list) with self.pc.lock: for item_iid, item_count in item_sell_list: if not item_count: general.log_error("do_0616: not item_count", item_count) continue if self.pc.in_equip(item_iid): general.log_error("do_0616: in_equip(item_iid)", item_iid) continue item = self.pc.item.get(item_iid) if not item: general.log_error("do_0616: not item", item_iid) continue if item.count < item_count: general.log_error("do_0616: item.count < item_count") continue if script.gold(self.pc, (int(item.price / 100.0) or 1) * item_count): if item.count <= item_count: self.pc.item_pop(item_iid) else: item.count -= item_count script.msg(self.pc, "%sを%s個失いました" % (item.name, item_count)) self.send("09cf", item, item_iid) #アイテム個数変化 self.pc.update_item_status()
def set_pet(pc): with pc.lock: if pc.pet: #general.log("[ pet ] set_pet failed: pc.pet exist") return if not pc.equip.pet: #general.log("[ pet ] set_pet failed: pc.equip.pet not exist") return False item = pc.item.get(pc.equip.pet) if not item: #general.log("[ pet ] set_pet failed: item not exist") return False pet = general.get_pet(item.pet_id) if not pet: #general.log("[ pet ] set_pet failed: pet not exist") return False pet = obj_pet.PetObject(pet) pet.reset(item) with pet_list_lock: pet_id = general.make_id(pet_id_list, MIN_PET_ID) if pet_id >= MAX_PET_ID: general.log_error("[ pet ] ERROR: pet_id [%s] >= MAX_PET_ID"%pet_id) return False pet.id = pet_id pet_list.append(pet) pet_id_list.append(pet.id) with pc.user.lock and pet.lock: pc.pet = pet pet.master = pc pet.set_map(pc.map_id) pet.set_coord_from_master() pet.set_dir(pc.dir) pet.start() pc.map_send_map("122f", pet) #pet info general.log("[ pet ] set pet id %s"%(pc.pet.id)) return True
def do_0616(self, data_io): #ショップで売却 general.log("[ map ] npcsell") with self.pc.lock: if self.pc.shop_open != 65535: general.log_error("do_0616: shop_open != 65535", self.pc.shop_open) return item_iid_list = io_unpack_array(io_unpack_int, data_io) item_count_list = io_unpack_array(io_unpack_int, data_io) item_sell_list = zip(item_iid_list, item_count_list) general.log("[ map ] item_sell_list", item_sell_list) with self.pc.lock: for item_iid, item_count in item_sell_list: if not item_count: general.log_error("do_0616: not item_count", item_count) continue if self.pc.in_equip(item_iid): general.log_error("do_0616: in_equip(item_iid)", item_iid) continue item = self.pc.item.get(item_iid) if not item: general.log_error("do_0616: not item", item_iid) continue if item.count < item_count: general.log_error("do_0616: item.count < item_count") continue if script.gold(self.pc, (int(item.price/100.0) or 1)*item_count): if item.count <= item_count: self.pc.item_pop(item_iid) else: item.count -= item_count script.msg(self.pc, "%sを%s個失いました"%( item.name, item_count )) self.send("09cf", item, item_iid) #アイテム個数変化 self.pc.update_item_status()
def _unset_equip(self, iid, part): if iid == 0: general.log_error("[ pc ] unset_equip iid == 0", self) return False if iid not in self.item: general.log_error("[ pc ] unset_equip iid %d not exist"%iid, self) return False if self.equip.pet == iid: self.unset_pet() for attr in general.EQUIP_ATTR_LIST: if getattr(self.equip, attr) == iid: setattr(self.equip, attr, 0) general.log_error("[ pc ] unset_equip iid %d"%iid) self.sort.item.remove(iid) self.sort.item.append(iid) self.map_send("09e3", iid, part) #アイテム保管場所変更 self.map_send("09e8", -1, -1, 1, 1) #アイテムを外す self.map_send_map("09e9", self) #キャラの見た目を変更 self.update_equip_status() return True
def _set_equip(self, iid): item = self.item.get(iid) if not item: general.log_error("[ pc ] set_equip iid %d not exist" % iid, self) return False unset_iid_list = [] set_part = 0 if item.check_type(general.HEAD_TYPE_LIST): #頭 unset_iid_list.append(self.equip.head) self.equip.head = iid set_part = 6 elif item.check_type(general.ACCESORY_HEAD_TYPE_LIST): #頭 unset_iid_list.append(self.equip.head) self.equip.head = iid set_part = 7 elif item.check_type(general.FULLFACE_TYPE_LIST): #顔 unset_iid_list.append(self.equip.face) self.equip.face = iid set_part = 6 #8 before ver315 elif item.check_type(general.ACCESORY_FACE_TYPE_LIST): #顔 unset_iid_list.append(self.equip.face) self.equip.face = iid set_part = 8 #9 before ver315 elif item.check_type(general.ACCESORY_TYPE_LIST): #胸アクセサリ unset_iid_list.append(self.equip.chestacce) self.equip.chestacce = iid set_part = 10 elif item.check_type(general.ONEPIECE_TYPE_LIST): #... unset_iid_list.append(self.equip.tops) unset_iid_list.append(self.equip.bottoms) self.equip.tops = iid self.equip.bottoms = 0 set_part = 11 elif item.check_type(general.UPPER_TYPE_LIST): #上半身 unset_iid_list.append(self.equip.tops) self.equip.tops = iid set_part = 11 elif item.check_type(general.LOWER_TYPE_LIST): #下半身 item_tops = self.item.get(self.equip.tops) if item_tops and item_tops.check_type(general.ONEPIECE_TYPE_LIST): unset_iid_list.append(self.equip.tops) self.equip.tops = 0 unset_iid_list.append(self.equip.bottoms) self.equip.bottoms = iid set_part = 12 elif item.check_type(general.BACKPACK_TYPE_LIST): #背中 unset_iid_list.append(self.equip.backpack) self.equip.backpack = iid set_part = 13 elif item.check_type(general.RIGHT_TYPE_LIST): #右手装備 unset_iid_list.append(self.equip.right) self.equip.right = iid set_part = 14 elif item.check_type(general.LEFT_TYPE_LIST): #左手装備 unset_iid_list.append(self.equip.left) self.equip.left = iid set_part = 15 elif item.check_type(general.BOOTS_TYPE_LIST): #靴 unset_iid_list.append(self.equip.shoes) self.equip.shoes = iid set_part = 16 elif item.check_type(general.SOCKS_TYPE_LIST): #靴下 unset_iid_list.append(self.equip.socks) self.equip.socks = iid set_part = 17 elif item.check_type(general.PET_TYPE_LIST): #ペット unset_iid_list.append(self.equip.pet) self.unset_pet() self.equip.pet = iid self.set_pet() set_part = 18 elif item.check_type(general.EFFECT_TYPE_LIST): #effect unset_iid_list.append(self.equip.effect) self.equip.effect = iid set_part = 19 else: #装備しようとする装備タイプが不明の場合 general.log_error("[ pc ] set_equip unknow item type", item) self.map_send("09e8", iid, -1, -2, 1) #アイテム装備 return False general.log("[ pc ] set_equip", item) unset_iid_list = filter(None, unset_iid_list) for i in unset_iid_list: self.sort.item.remove(i) self.sort.item.append(i) self.map_send("09e3", i, 0x02) #アイテム保管場所変更 #body #self.map_send("0203", self.item[i], i, 0x02) #インベントリ情報 self.map_send("09e8", iid, set_part, 0, 1) #アイテム装備 self.map_send_map("09e9", self) #キャラの見た目を変更 #self.map_send_map_without_self("020d", self.pc) #キャラ情報 self.update_equip_status() return True
def load_1_1_3(self, data): self.id = data.getint("main", "id") self.name = data.get("main", "name") self.gmlevel = data.getint("main", "gmlevel") self.race = data.getint("main", "race") self.race_motion = data.getint("main", "race_motion") self.form = data.getint("main", "form") self.gender = data.getint("main", "gender") self.hair = data.getint("main", "hair") self.haircolor = data.getint("main", "haircolor") self.wig = data.getint("main", "wig") self.face = data.getint("main", "face") self.base_lv = data.getint("main", "base_lv") self.ex = data.getint("main", "ex") self.wing = data.getint("main", "wing") self.wingcolor = data.getint("main", "wingcolor") self.job = data.getint("main", "job") self.map_id = data.getint("main", "map_id") self.lv_base = data.getint("main", "lv_base") self.lv_job1 = data.getint("main", "lv_job1") self.lv_job2x = data.getint("main", "lv_job2x") self.lv_job2t = data.getint("main", "lv_job2t") self.lv_job3 = data.getint("main", "lv_job3") self.gold = data.getint("main", "gold") self.x = data.getfloat("main", "x") self.y = data.getfloat("main", "y") self.dir = data.getint("main", "dir") self.str = data.getint("status", "str") self.dex = data.getint("status", "dex") self.int = data.getint("status", "int") self.vit = data.getint("status", "vit") self.agi = data.getint("status", "agi") self.mag = data.getint("status", "mag") self.stradd = data.getint("status", "stradd") self.dexadd = data.getint("status", "dexadd") self.intadd = data.getint("status", "intadd") self.vitadd = data.getint("status", "vitadd") self.agiadd = data.getint("status", "agiadd") self.magadd = data.getint("status", "magadd") #{item_iid: item_object, ...} self.item = {} self.sort.item = general.str_to_list(data.get("sort", "item")) for i in self.sort.item: if i <= 0: general.log_error("[ pc ] item iid <= 0", self) self.item[i] = item_loads(data.get("item", str(i))) #{item_iid: item_object, ...} self.warehouse = {} self.sort.warehouse = general.str_to_list(data.get("sort", "warehouse")) for i in self.sort.warehouse: if i <= 0: general.log_error("[ pc ] warehouse iid <= 0", self) self.warehouse[i] = item_loads(data.get("warehouse", str(i))) #equip.place = iid for attr in general.EQUIP_ATTR_LIST: try: setattr(self.equip_std, attr, data.getint("equip", attr)) except ConfigParser.NoOptionError: general.log_error("[ pc ] warning: equip [%s] not exist in [%s]" % (attr, self)) if data.has_section("equip_dem"): for attr in general.EQUIP_ATTR_LIST: try: setattr(self.equip_dem, attr, data.getint("equip_dem", attr)) except ConfigParser.NoOptionError: general.log_error( "[ pc ] warning: dem equip [%s] not exist in [%s]" % (attr, self)) self.mirror_face = general.str_to_list(data.get("mirror", "face")) self.mirror_hair = general.str_to_list(data.get("mirror", "hair")) self.mirror_wig = general.str_to_list(data.get("mirror", "wig")) self.mirror_haircolor = general.str_to_list(data.get( "mirror", "haircolor")) #{name: value, ...} self.var = {} if data.has_section("var"): for key in data.options("var"): try: self.var[key] = dumpobj.loads(data.get("var", key)) except: general.log_error("[ pc ] load var error", self, key) general.log_error(traceback.format_exc()) #[skill_id, ...] self.skill_list = general.str_to_list(data.get("skill", "list")) if self.dem_form_status(): self.equip = self.equip_dem else: self.equip = self.equip_std