def do_00a7(self, data_io): #キャラクター選択 num = io_unpack_byte(data_io) general.log("[login] select character", num) with self.user.lock: self.pc = self.user.pc_list[num] self.send("00a8", self.pc) #キャラクターマップ通知
def sync_map(self): with self.pc.lock: if not self.pc.map_obj: return with self.pc.map_obj.lock: for p in self.pc.map_obj.pc_list: if not p.online: continue if not p.visible: continue if self.pc == p: continue general.log("sync_map", self.pc, "<->", p) #他キャラ情報→自キャラ self.send("120c", p) #自キャラ情報→他キャラ p.map_send("120c", self.pc) for pet in self.pc.map_obj.pet_list: if not pet.master: continue self.send("122f", pet) #pet info for monster in self.pc.map_obj.monster_list: if monster.hp <= 0: continue self.send("122a", (monster.id, )) #モンスターID通知 self.send("1220", monster) #モンスター情報 for mi in self.pc.map_obj.mapitem_list: self.send("07d5", mi) #drop item info with usermaps.usermap_list_lock: i = self.pc.map_obj.map_id for key, value in usermaps.usermap_list.iteritems(): if value.entrance_map_id != i: continue self.send("0bb8", value.master) #飛空庭のひも・テント表示
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 do_07d0(self, data_io): #put item request iid = io_unpack_int(data_io) count = io_unpack_short(data_io) general.log("[ map ] put item: iid", iid, "count", count) with self.pc.lock: if self.pc.trade: #put item error, トレード中はアイテムを捨てる事が出来ません self.send("07d1", -8) return if self.pc.event_id: #put item error, イベント中はアイテムを捨てることが出来ません self.send("07d1", -10) return item, err = script.takeitem_byiid(self.pc, iid, count) if err: self.send("07d1", err) return if not item: general.log("[ map ] put item: not item but err = 0", iid, count) return self.pc.map_obj.mapitem_append(item, self.pc.x, self.pc.y, self.pc.id) self.pc.update_item_status()
def init(): general.init() general.log("-"*30+"\n", env.NAME, env.LAST_UPDATE, "\n"+"-"*30) server.init() pets.init() monsters.init() usermaps.init()
def do_11fe(self, data_io): #MAPワープ完了通知 general.log("[ map ]", "map load") self.pc.set_visible(True) self.send("09e9", self.pc) self.send("0226", self.pc, 0) #スキル一覧 一次職 self.send("0226", self.pc, 1) #スキル一覧 エキスパ self.send("022d", self.pc) #HEARTスキル self.send("13ec", self.pc) #れしぴ self.send("196e", self.pc) #クエスト回数・時間 #self.send("0259", self.pc) #ステータス試算結果 #self.send("1b67", self.pc) #MAPログイン時に基本情報を全て受信した後に受信される self.sync_map() self.pc.unset_pet() if self.pc.equip.pet: time.sleep(0.5) #must have some delay before send 122f (pet info) self.pc.set_pet() if self.send_login_event: self.send_login_event = False script.run(self.pc, env.LOGIN_EVENT_ID) if usermaps.map_id_in_range_flygarden(self.pc.map_obj.map_id): #bad packet, i dont known the structure of 1be4 #self.send("1be4", self.pc) #飛空庭ログイン #1bf9 only for reply 1bf8, plz remove when 1be4 work self.send("13bc", 2) #飛空庭の天候 self.send("13bd", 4) #飛空庭の天体 self.send("1bee", self.pc) #飛空庭の天候 self.send("1bf0", self.pc) #飛空庭の天候
def sync_map(self): with self.pc.lock: if not self.pc.map_obj: return with self.pc.map_obj.lock: for p in self.pc.map_obj.pc_list: if not p.online: continue if not p.visible: continue if self.pc == p: continue general.log("sync_map", self.pc, "<->", p) #他キャラ情報→自キャラ self.send("120c", p) #自キャラ情報→他キャラ p.map_send("120c", self.pc) for pet in self.pc.map_obj.pet_list: if not pet.master: continue self.send("122f", pet) #pet info for monster in self.pc.map_obj.monster_list: if monster.hp <= 0: continue self.send("122a", (monster.id,)) #モンスターID通知 self.send("1220", monster) #モンスター情報 for mi in self.pc.map_obj.mapitem_list: self.send("07d5", mi) #drop item info with usermaps.usermap_list_lock: i = self.pc.map_obj.map_id for key, value in usermaps.usermap_list.iteritems(): if value.entrance_map_id != i: continue self.send("0bb8", value.master) #飛空庭のひも・テント表示
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 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 do_001f(self, data_io): #認証情報 username = io_unpack_str(data_io) password_sha1 = io_unpack_raw(data_io)[:40] general.log("[login]", "login", username, password_sha1) for user in users.get_user_list(): with user.lock: if user.name != username: continue user_password_sha1 = hashlib.sha1( "".join((str(unpack_unsigned_int(self.word_front)), user.password, str(unpack_unsigned_int(self.word_back)), ))).hexdigest() if user_password_sha1 != password_sha1: self.send("0020", user, "loginfaild") #アカウント認証結果 return if user.login_client: user.reset_login() self.send("0020", user, "isonline") #アカウント認証結果 return user.reset_login() user.login_client = self self.user = user self.send("0020", user, "loginsucess") #アカウント認証結果 self.send("0028", user) #4キャラクターの基本属性 self.send("0029", user) #4キャラクターの装備 break else: self.send("0020", user, "loginfaild") #アカウント認証結果
def do_09fd(self, data_io): #倉庫に預ける item_iid = io_unpack_int(data_io) item_count = io_unpack_short(data_io) general.log("[ map ] store item to warehouse", item_iid, item_count) with self.pc.lock: if len(self.pc.warehouse) >= env.MAX_WAREHOURSE_STOCK: #倉庫に預けた時の結果 倉庫のアイテム数が上限を超えてしまうためキャンセルされました self.send("09fe", -4) return if self.pc.warehouse_open is None: #倉庫に預けた時の結果 #倉庫を開けていません self.send("09fe", -1) return if item_iid not in self.pc.item: #倉庫に預けた時の結果 #指定されたアイテムは存在しません self.send("09fe", -2) return item = self.pc.item[item_iid] if item.count < item_count: #倉庫に預けた時の結果 #指定された数量が不正です self.send("09fe", -3) elif item.count == item_count: self.pc.item_pop(item_iid) else: item.count -= item_count self.send("09cf", item, item_iid) #アイテム個数変化 script.msg(self.pc, "%sを%s個失いました"%(item.name, item_count)) item_store = general.copy(item) item_store.count = item_count item_store.warehouse = self.pc.warehouse_open self.pc.warehouse_append(item_store) #倉庫に預けた時の結果 #成功 self.send("09fe", 0) self.pc.update_item_status()
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 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 do_07e4(self, data_io): #pick up item request mapitem_id = io_unpack_int(data_io) general.log("[ map ] pick up item: mapitem_id", mapitem_id) if len(self.pc.item) >= env.MAX_ITEM_STOCK: script.msg(self.pc, "pick up item error: stock limit") return with self.pc.lock: if self.pc.trade: #pick up item error, トレード中はアイテムを拾うことが出来ません self.send("07e6", -8) return if self.pc.event_id: #pick up item error, イベント中はアイテムを拾うことが出来ません self.send("07e6", -9) return mapitem_obj = self.pc.map_obj.mapitem_pop(mapitem_id) if not mapitem_obj: #pick up item error, 存在しないアイテムです self.send("07e6", -1) return self.send_map("07df", mapitem_obj) #pick up item item = mapitem_obj.item if item.stock: script.item(self.pc, item.item_id, item.count) else: self.pc.item_append(mapitem_obj.item) self.pc.update_item_status()
def do_001f(self, data_io): #認証情報 username = io_unpack_str(data_io) password_sha1 = io_unpack_raw(data_io)[:40] general.log("[login]", "login", username, password_sha1) for user in users.get_user_list(): with user.lock: if user.name != username: continue user_password_sha1 = hashlib.sha1( "".join((str(unpack_unsigned_int(self.word_front)), user.password, str(unpack_unsigned_int(self.word_back)), ))).hexdigest() if user_password_sha1 != password_sha1: self.send("0020", user, "wloginfaild") #アカウント認証結果 return if user.wlogin_client: user.wreset_login() self.send("0020", user, "wisonline") #アカウント認証結果 return user.wreset_login() user.wlogin_client = self self.user = user self.send("0020", user, "wloginsucess") #アカウント認証結果 self.send("0028", user) #4キャラクターの基本属性 self.send("0029", user) #4キャラクターの装備 break else: self.send("0020", user, "wloginfaild") #アカウント認証結果
def do_0a1b(self, data_io): #トレードウィンドウに置いたアイテム・金の情報を送信? general.log("[ map ] trade send item list") iid_list = io_unpack_array(io_unpack_int, data_io) count_list = io_unpack_array(io_unpack_short, data_io) gold = io_unpack_int(data_io) self.pc.set_trade_list(gold, zip(iid_list, count_list))
def do_09fd(self, data_io): #倉庫に預ける item_iid = io_unpack_int(data_io) item_count = io_unpack_short(data_io) general.log("[ map ] store item to warehouse", item_iid, item_count) with self.pc.lock: if len(self.pc.warehouse) >= env.MAX_WAREHOURSE_STOCK: #倉庫に預けた時の結果 倉庫のアイテム数が上限を超えてしまうためキャンセルされました self.send("09fe", -4) return if self.pc.warehouse_open is None: #倉庫に預けた時の結果 #倉庫を開けていません self.send("09fe", -1) return if item_iid not in self.pc.item: #倉庫に預けた時の結果 #指定されたアイテムは存在しません self.send("09fe", -2) return item = self.pc.item[item_iid] if item.count < item_count: #倉庫に預けた時の結果 #指定された数量が不正です self.send("09fe", -3) elif item.count == item_count: self.pc.item_pop(item_iid) else: item.count -= item_count self.send("09cf", item, item_iid) #アイテム個数変化 script.msg(self.pc, "%sを%s個失いました" % (item.name, item_count)) item_store = general.copy(item) item_store.count = item_count item_store.warehouse = self.pc.warehouse_open self.pc.warehouse_append(item_store) #倉庫に預けた時の結果 #成功 self.send("09fe", 0) self.pc.update_item_status()
def do_002a(self, data_io): #キャラ番号通知 self.send("002b")#応答 general.log("[login]", "request friend list") if self.pc: self.send("00dd", self.pc) #フレンドリスト(自キャラ) self.send("00de")
def do_01fd(self, data_io): #選択したキャラ番号通知 unknow = io_unpack_int(data_io) if not self.pc: num = io_unpack_byte(data_io) with self.user.lock: if not self.user.pc_list[num]: self.stop() return self.pc = self.user.pc_list[num] self.pc.reset_map() with self.pc.lock: self.pc.online = True general.log("[ map ] set", self.pc) self.pc.update_status() self.pc.set_map() self.pc.set_visible(False) self.pc.set_motion(111, False) self.pc.set_coord(self.pc.x, self.pc.y) #on login if not self.pc.map_obj: self.pc.set_map(10023100) #アップタウン東可動橋 self.pc.set_coord(random.randint(252, 253), random.randint(126, 129)) self.send("1239", self.pc, 10) #キャラ速度通知・変更 #マップ読み込み中は10 self.send("1a5f") #右クリ設定 self.send_item_list() #インベントリ情報 self.send("01ff", self.pc) #自分のキャラクター情報 self.send("03f2", 0x04) #システムメッセージ #構えが「叩き」に変更されました self.send("09ec", self.pc) #ゴールド入手 self.send("0230", self.pc) #現在CAPA/PAYL self.send("0231", self.pc) #最大CAPA/PAYL self.send("0221", self.pc) #最大HP/MP/SP self.send("021c", self.pc) #現在のHP/MP/SP/EP self.send("157c", self.pc) #キャラの状態 self.send("0212", self.pc) #ステータス・補正・ボーナスポイント self.send("0217", self.pc) #詳細ステータス self.send("0226", self.pc, 0) #スキル一覧 一次職 self.send("0226", self.pc, 1) #スキル一覧 エキスパ self.send("022d", self.pc) #HEARTスキル self.send("0223", self.pc) #属性値 self.send("0244", self.pc) #ステータスウィンドウの職業 self.send("022e", self.pc) #リザーブスキル self.send("023a", self.pc) #Lv JobLv ボーナスポイント スキルポイント self.send("0235", self.pc) #EXP/JOBEXP self.send("09e9", self.pc) #キャラの見た目を変更 self.send("0fa7", self.pc) #キャラのモード変更 self.send("1f72") #もてなしタイニーアイコン self.send("122a") #モンスターID通知 self.send("1bbc") #スタンプ帳詳細 self.send("025d") #不明 self.send("0695") #不明 for i in xrange(14): self.send("1ce9", i) #useable motion_ex_id self.send("1d06", 0b1111) #emotion_ex enumerate self.send("0236", self.pc) #wrp ranking関係 self.send("1b67", self.pc) #MAPログイン時に基本情報を全て受信した後に受信される general.log("[ map ] send pc info success")
def stop(self): #will block 0 ~ sleep sec in join() self.running = False self.join() if self.map_obj: with self.map_obj.lock: self.map_obj.pet_list.remove(self) general.log("[ pet ] %s stop"%self)
def do_09e7(self, data_io): #アイテム装備 iid = io_unpack_int(data_io) if self.pc.dem_form_status(): general.log("[ map ] set equip failed", self.pc) self.send("09e8", iid, -1, -2, 1) #アイテム装備 else: self.pc.set_equip(iid)
def do_0031(self, data_io): #接続確認 general.log("[login] requested server information") self.send("0032")#接続先通知要求(0031)の応答 self.send("0033", "login")#接続先情報送信(ワールドログインサーバーAddr) #TODO: temp ws2_32 reconnect fix self.send("0033", "login")#接続先情報送信(ワールドログインサーバーAddr) self.send("0034")#接続先通知終了(0031)の応答
def assert_address_not_used(): general.log_line("[ srv ] server.assert_address_not_used ... ") general.assert_address_not_used( (env.SERVER_BROADCAST_ADDR, env.LOGIN_SERVER_PORT)) general.assert_address_not_used( (env.SERVER_BROADCAST_ADDR, env.MAP_SERVER_PORT)) general.assert_address_not_used( (env.SERVER_BROADCAST_ADDR, env.WEB_SERVER_PORT)) general.log("done.")
def delete(monster): with monster_list_lock and monster.lock: monster_list.remove(monster) monster_id_list.remove(monster.id) if monster.map_obj: script.send_map_obj(monster.map_obj, (), "1225", monster) #モンスター消去 general.log("[monster] delete monster id %s" % (monster.id)) monster.reset() del monster
def do_0001(self, data_io): #接続・接続確認 data = data_io.read() general.log("[login] eco version", unpack_unsigned_int(data[:4])) self.send("0002", data) #認証接続確認(s0001)の応答 self.send("001e", self.word_front+self.word_back) #PASS鍵 general.log("[login] send word", self.word_front.encode("hex"), self.word_back.encode("hex"), )
def delete(monster): with monster_list_lock and monster.lock: monster_list.remove(monster) monster_id_list.remove(monster.id) if monster.map_obj: script.send_map_obj(monster.map_obj, (), "1225", monster) #モンスター消去 general.log("[monster] delete monster id %s"%(monster.id)) monster.reset() del monster
def do_1e87(self, data_io): #DEMパーツ装着 #warning: cannot unset parts on dem parts window iid = io_unpack_int(data_io) if self.pc.dem_form_status(): self.pc.set_equip(iid) else: general.log("[ map ] set dem parts failed", self.pc) self.send("09e8", iid, -1, -2, 1) #アイテム装備
def do_1e7d(self, data_io): #DEMのフォームチェンジ #point pc.equip to pc.eqiup_dem or pc.equip_std before change #if not stable, it will back to unset all equip before change status = io_unpack_byte(data_io) if self.pc.dem_form_change(status): general.log("[ map ] dem form change success") else: general.log("[ map ] dem form change failed")
def do_000a(self, data_io): #接続・接続確認 data = data_io.read() general.log("[ map ] eco version", unpack_unsigned_int(data[:4])) self.send("000b", data) self.send("000f", self.word_front+self.word_back) general.log("[ map ] send word", self.word_front.encode("hex"), self.word_back.encode("hex"), )
def load(): global loginserver global mapserver loginserver_bind_addr = (env.SERVER_BIND_ADDR, env.LOGIN_SERVER_PORT) mapserver_bind_addr = (env.SERVER_BIND_ADDR, env.MAP_SERVER_PORT) general.log("[ srv ] start login server with\t%s:%d"%loginserver_bind_addr) loginserver = LoginServer(loginserver_bind_addr) general.log("[ srv ] start map server with\t%s:%d"%mapserver_bind_addr) mapserver = MapServer(mapserver_bind_addr)
def load(): global loginserver global mapserver loginserver_bind_addr = (env.SERVER_BIND_ADDR, env.LOGIN_SERVER_PORT) mapserver_bind_addr = (env.SERVER_BIND_ADDR, env.MAP_SERVER_PORT) general.log("[ srv ] start login server with\t%s:%d" % loginserver_bind_addr) loginserver = LoginServer(loginserver_bind_addr) general.log("[ srv ] start map server with\t%s:%d" % mapserver_bind_addr) mapserver = MapServer(mapserver_bind_addr)
def do_0617(self, data_io): """髪型変更(要変更)""" hair_cat_id = io_unpack_int(data_io) hair = io_unpack_short(data_io) wig = io_unpack_short(data_io) if hair_cat_id != -1: general.log("[ map ] use hair introduce id:%s" % (hair_cat_id)) if hair != -1: script.haircut(self.pc, hair, wig) self.send("0618", hair, wig)
def _shutdown(self): if not self.running: return general.log("[ srv ] shutdown", self) self.running = False self.socket.close() while self.client_list: client = self.client_list[0] general.log("[ srv ] shutdown", client) client.stop() #remove in StandardClient._stop
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 main(pc): usermap_obj = usermaps.get_usermap_from_map_id(pc.event_id) if not usermap_obj: script.msg(pc, "rope error: usermap id %s not exist" % pc.event_id) return general.log(usermap_obj.master, pc) if usermap_obj.master == pc: master_event(pc) else: guest_event(pc)
def main(pc): usermap_obj = usermaps.get_usermap_from_map_id(pc.map_obj.map_id) if not usermap_obj: script.msg(pc, "rope error: usermap id %s not exist"%pc.map_obj.map_id) return general.log(usermap_obj.master, pc) if usermap_obj.master == pc: master_event(pc, usermap_obj) else: guest_event(pc, usermap_obj)
def do_000a(self, data_io): #接続・接続確認 data = data_io.read() general.log("[ map ] eco version", unpack_unsigned_int(data[:4])) self.send("000b", data) self.send("000f", self.word_front + self.word_back) general.log( "[ map ] send word", self.word_front.encode("hex"), self.word_back.encode("hex"), )
def do_121b(self, data_io): #モーションセット&ログアウト motion_id = io_unpack_short(data_io) loop = True if io_unpack_byte(data_io) else False general.log("[ map ] motion %d loop %s"%(motion_id, loop)) #self.pc.set_motion(motion_id, loop) #self.send_map("121c", self.pc) #モーション通知 self.pc.set_motion(motion_id, loop) if motion_id == 135 and loop: #ログアウト開始 general.log("[ map ]", "start logout") self.send("0020", self.pc, "logoutstart") self.pc.logout = True
def ip_count_check(self, src): ip = src[0] ip_count = 1 with self.client_list_lock: for client in self.client_list: if ip == client.src_address[0]: ip_count += 1 general.log("[ srv ] src: %s ip_count: %s" % (src, ip_count)) if ip_count > env.MAX_CONNECTION_FROM_ONE_IP: return False else: return True
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 ip_count_check(self, src): ip = src[0] ip_count = 1 with self.client_list_lock: for client in self.client_list: if ip == client.src_address[0]: ip_count += 1 general.log("[ srv ] src: %s ip_count: %s"%(src, ip_count)) if ip_count > env.MAX_CONNECTION_FROM_ONE_IP: return False else: return True
def do_121b(self, data_io): #モーションセット&ログアウト motion_id = io_unpack_short(data_io) loop = True if io_unpack_byte(data_io) else False general.log("[ map ] motion %d loop %s" % (motion_id, loop)) #self.pc.set_motion(motion_id, loop) #self.send_map("121c", self.pc) #モーション通知 self.pc.set_motion(motion_id, loop) if motion_id == 135 and loop: #ログアウト開始 general.log("[ map ]", "start logout") self.send("0020", self.pc, "logoutstart") self.pc.logout = True
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 use(pc, target_id, x, y, skill_id, skill_lv): general.log("[skill] use skill (%s, %s) -> (%s, %s, %s)"%( skill_id, skill_lv, target_id, x, y, )) mod = name_map.get(str(skill_id)) if mod is None: skill_obj = db.skill.get(skill_id) skill_name = skill_obj.name if skill_obj else "unknow" script.msg(pc, "skill %s %s not define"%(skill_id, skill_name)) #スキル使用 #スキルを使用できません pc.map_send("1389", pc, -1, x, y, skill_id, skill_lv, 13, -1) #スキル使用通知 #スキルを使用できません pc.map_send("138a", pc, 13) return general.start_thread(use_thread, (mod, pc, target_id, x, y, skill_id, skill_lv)) return True
def make_1be4(pc): """飛空庭ログイン #unfinished""" i = len(general.FLYGARDEN_ATTR_LIST) usermap_obj = pc.map_obj result = pack_int(usermap_obj.map_id) result += pack_unsigned_byte(int(pc.x)) #x result += pack_unsigned_byte(int(pc.y)) #y result += pack_unsigned_byte(int(pc.dir)) #dir result += pack_array(pack_int, [ getattr(usermap_obj.flygarden, attr) for attr in general.FLYGARDEN_ATTR_LIST ]) #item_ids result += pack_array(pack_byte, (0,)*i) #colors result += pack_byte(0) #土台色? general.log(result.encode("hex")) return result
def unset_pet(pc, logout): with pc.lock: if not pc.pet: #general.log("[ pet ] unset_pet failed: pc.pet not exist") return with pc.user.lock and pc.pet.lock: if logout: pc.map_send_map_without_self("1234", pc.pet) ##hide pet else: pc.map_send_map("1234", pc.pet) ##hide pet pc.pet.stop() with pet_list_lock: pet_list.remove(pc.pet) pet_id_list.remove(pc.pet.id) general.log("[ pet ] del pet id %s"%(pc.pet.id)) pc.pet = None return True
def cancel_trade(self): with self.lock and self.user.lock: if not self.online: self.reset_trade() return general.log("[ pc ] cancel_trade") p = self.get_trade_target() #自分・相手がOKやキャンセルを押した際に双方に送信される self.map_send("0a19", self) self.reset_trade() self.map_send("0a1c") #トレード終了通知 if not p: return with p.lock and p.user.lock: #自分・相手がOKやキャンセルを押した際に双方に送信される p.map_send("0a19", p) p.reset_trade() p.map_send("0a1c") #トレード終了通知