def btnInjectPacket(IProxySend): strOpcode = QtBind.text(gui, txtOpcode) strData = QtBind.text(gui, txtData) # Opcode or Data is not empty if strOpcode and strData: data = bytearray() opcode = int(strOpcode, 16) strData = strData.replace(' ', '') strDataLen = len(strData) # Make sure is raw of bytes if not strDataLen % 2 == 0: log("Plugin: Error, data needs to be a raw of bytes") return # Add bytes as pairs for i in range(0, int(strDataLen), 2): data.append(int(strData[i:i + 2], 16)) # Check encryption encrypted = QtBind.isChecked(gui, cbxEncrypted) # Show injection log log("Plugin: Injecting packet" + (' (Encrypted)' if encrypted else '') + " :") log("(Opcode) 0x" + '{:02X}'.format(opcode) + " (Data) " + ("None" if not data else ' '.join('{:02X}'.format(x) for x in data))) IProxySend(opcode, data, encrypted)
def event_loop(): # Check if is in game at first if character_data: # generate disconnect event global checking_disconnect if checking_disconnect: global checking_disconnect_counter checking_disconnect_counter += 500 # Check if delay is longer to trigger disconnect event if checking_disconnect_counter >= CHECK_DISCONNECT_DELAY_MAX: # Execute only once checking_disconnect = False on_disconnect() # generate fetch stuff if at least one handler exists if discord_chat_handlers: global discord_fetch_counter discord_fetch_counter += 500 # Check if delay is longer to start fetching if discord_fetch_counter >= DISCORD_FETCH_DELAY: discord_fetch_counter = 0 if QtBind.isChecked(gui_,cbxDiscord_read_messages): # Fetch messages from guild Fetch(QtBind.text(gui_,tbxDiscord_guild_id))
def btnAddChannel_clicked(): if isJoined(): channel_id = QtBind.text(gui,tbxChannels) if channel_id and channel_id.isnumeric(): # channel it's not empty and not added if not ListContains(QtBind.getItems(gui,lstChannels),channel_id): # init dict data = {} # Load config if os.path.exists(getConfig()): with open(getConfig(), 'r') as f: data = json.load(f) # Add new channel if not "Channels" in data: data['Channels'] = [] data["Channels"].append(channel_id) # Replace configs with open(getConfig(),"w") as f: f.write(json.dumps(data, indent=4, sort_keys=True)) # Add new channel on everything QtBind.append(gui,lstChannels,channel_id) for name,cmbx in cmbxTriggers.items(): QtBind.append(gui,cmbx,channel_id) for name,cmbx in cmbxTriggers_.items(): QtBind.append(gui_,cmbx,channel_id) QtBind.setText(gui,tbxChannels,"") log('Plugin: Channel added ['+channel_id+']') else: log('Plugin: Error, The channel must be an identifier number!')
def notify_pickup(channel_id,itemID): item = get_item(itemID) # no filters usefilterName = QtBind.isChecked(gui_,cbxEvtPick_name_filter) usefilterServerName = QtBind.isChecked(gui_,cbxEvtPick_servername_filter) if not usefilterName and not usefilterServerName: Notify(channel_id,"|`"+character_data['name']+"`| - **Item** picked up ***"+item['name']+" "+getCountryType(item['servername'])+"***") return # check filter name if usefilterName: searchName = QtBind.text(gui_,tbxEvtPick_name_filter) if searchName: try: if not re.search(searchName,item['name']): return except Exception as ex: log("Plugin: Error at regex (name) ["+str(ex)+"]") # check filter servername if usefilterServerName: searchServername = QtBind.text(gui_,tbxEvtPick_servername_filter) if searchServername: try: if not re.search(searchServername,item['servername']): return except Exception as ex: log("Plugin: Error at regex (servername) ["+str(ex)+"]") # Filtered through both if checked Notify(channel_id,"|`"+character_data['name']+"`| - **Item (Filtered)** picked up ***"+item['name']+" "+getCountryType(item['servername'])+"***")
def btnUpdate_clicked(): py = QtBind.text(gui, lstPlugins) if py and "- Update available" in py: # Get url from GUI pyUrl = py[py.find('[') + 1:py.find(']')] try: req = urllib.request.Request( pyUrl, headers={ 'User-Agent': "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:22.0) Gecko/20100101 Firefox/22.0" }) with urllib.request.urlopen(req) as w: pyCode = str(w.read().decode("utf-8")) filename = py[:py.find(' ')] with open(filename + "a", "w+") as f: f.write(pyCode) QtBind.remove(gui, lstPlugins, py) pyVersion = py[py.rfind('(') + 1:py.rfind(')')] QtBind.append( gui, lstPlugins, filename + " (" + pyVersion + ") - Updated recently") log('Plugin: Your plugin has been successfully updated') except: log("Plugin: Error updating your plugin. Try again later..")
def btnCheck_clicked(): # List all files around files = os.listdir() for filename in files: # Check only python files if (re.search("[.]py", filename)): with open(filename, "r") as f: pyCode = str(f.read()) # Read file and check his version if re.search("\npVersion = [0-9.'\"]*", pyCode): pyVersion = re.search("\npVersion = ([0-9a-zA-Z.'\"]*)", pyCode)[1][1:-1] pyName = re.search("\npName = ([0-9a-zA-Z'\"]*)", pyCode)[1][1:-1] pyDesc = pyVersion if pyName and pyName + ".py" != filename: pyDesc = pyName + " " + pyDesc # It's up to the plugin if the url is wrong :P pyUrl = pyCode.find("\npUrl = ") pyMsg = "Updated" if pyUrl != -1: pyUrl = pyCode[pyUrl + 9:].split('\n')[0][:-1] pyNewVersion = getVersion(pyUrl) if pyNewVersion and compareVersion( pyVersion, pyNewVersion): pyMsg = "Update available (v" + pyNewVersion + ") [" + pyUrl + "]" else: pyMsg = "Cannot be update: URL not found" QtBind.append(gui, lstPlugins, filename + " (" + pyDesc + ") - " + pyMsg)
def btnSaveTimes_clicked(): if character_data: tempFromTime = None tempToTime = None try: tempFromTime = QtBind.text(gui, tbxFromTime) tempFromTime = datetime.strptime(tempFromTime, '%H:%M') except: log('Plugin: Error! FROM time needs to be at format "00:00" (hh:mm)' ) return try: tempToTime = QtBind.text(gui, tbxToTime) tempToTime = datetime.strptime(tempToTime, '%H:%M') except: log('Plugin: Error! TO time needs to be at format "00:00" (hh:mm)') return if tempFromTime == tempToTime: log('Plugin: Error! times cannot be equal, a better option is to disable the plugin' ) return # Everything is right.. global strFromTime, strToTime strFromTime = tempFromTime.strftime('%H:%M') strToTime = tempToTime.strftime('%H:%M') saveConfig("FROM", strFromTime) saveConfig("TO", strToTime) log("Plugin: Times saved correctly!")
def handle_event(t, data): # Filter events if t == 9: Notify(QtBind.text(gui_,cmbxEvtNear_gm),"|`"+character_data['name']+"`| - **GameMaster** `"+data+"` is near to you!",CreateInfo("position",get_position())) elif t == 0: Notify(QtBind.text(gui_,cmbxEvtNear_unique),"|`"+character_data['name']+"`| - **"+data+"** unique is near to you!",CreateInfo("position",get_position())) elif t == 1: Notify(QtBind.text(gui_,cmbxEvtNear_hunter),"|`"+character_data['name']+"`| - **Hunter/Trader** `"+data+"` is near to you!",CreateInfo("position",get_position())) elif t == 2: Notify(QtBind.text(gui_,cmbxEvtNear_thief),"|`"+character_data['name']+"`| - **Thief** `"+data+"` is near to you!",CreateInfo("position",get_position())) elif t == 4: Notify(QtBind.text(gui_,cmbxEvtChar_attacked),"|`"+character_data['name']+"`| - `"+data+"` is attacking you!",colour=0xFF5722) elif t == 7: Notify(QtBind.text(gui_,cmbxEvtChar_died),"|`"+character_data['name']+"`| - You died",CreateInfo("position",get_position())) elif t == 3: pet = get_pets()[data] Notify(QtBind.text(gui_,cmbxEvtPet_died),"|`"+character_data['name']+"`| - Your pet `"+(pet['type'].title())+"` died") elif t == 5: channel_id = QtBind.text(gui_,cmbxEvtPick_rare) if channel_id: item = get_item(int(data)) race = getRaceText(item['servername']) genre = getGenreText(item['servername']) Notify(channel_id,"|`"+character_data['name']+"`| - **Item (Rare)** picked up ***"+item['name']+(' '+race if race else '')+(' '+genre if genre else '')+"***") elif t == 6: channel_id = QtBind.text(gui_,cmbxEvtPick_equip) if channel_id: item = get_item(int(data)) race = getRaceText(item['servername']) genre = getGenreText(item['servername']) Notify(channel_id,"|`"+character_data['name']+"`| - **Item (Equipable)** picked up ***"+item['name']+(' '+race if race else '')+(' '+genre if genre else '')+"***") elif t == 8: Notify(QtBind.text(gui_,cmbxEvtBot_alchemy),"|`"+character_data['name']+"`| - **Auto alchemy** has been completed")
def handle_joymax(opcode, data): # Object skill action & Enabled xTargetSupport if opcode == 0xB070 and QtBind.isChecked(gui, cbxEnabled): # Success if data[0] == 1: skillType = data[1] # 2 = Attack index = 7 attackerUID = struct.unpack_from("<I", data, index)[0] index += 8 locale = get_locale() if locale == 18 or locale == 56: # iSRO & TRSRO index += 4 targetUID = struct.unpack_from("<I", data, index)[0] # Check attack types only if skillType == 2: # Check the nickname from attacker charName = getCharName(attackerUID) if charName and ListContains(charName, QtBind.getItems(gui, lvwLeaders)): log("Plugin: Targetting enemy from " + charName) Inject_SelectTarget(targetUID) elif QtBind.isChecked(gui, cbxDefensive): # Check the nickname from target charName = getCharName(targetUID) if charName and ListContains( charName, QtBind.getItems(gui, lvwLeaders)): log("Plugin: Targetting attacker from " + charName) Inject_SelectTarget(attackerUID) return True
def handle_joymax(opcode, data): if opcode == SERVER_GAME_PETITION_REQUEST: t = data[0] # petition type if t == 1: # exchange # Accept everyone if QtBind.isChecked(gui, cbxAcceptAll): Inject_GamePetitionResponse(True, t) return True # Try to extract nickname entityID = struct.unpack_from('<I', data, 1)[0] charName = get_charname(entityID) # Accept if nickname is found in list if string_in_list(charName, QtBind.getItems(gui, lvwExchangers)): Inject_GamePetitionResponse(True, t) # apply confirmations elif opcode == SERVER_EXCHANGE_PLAYER_CONFIRMED: if QtBind.isChecked(gui, cbxReplyAccept): # accept exchange inject_joymax(CLIENT_EXCHANGE_CONFIRM_REQUEST, b'', False) elif opcode == SERVER_EXCHANGE_CONFIRM_RESPONSE: # check success and try to reply again if data[0] == 1 and QtBind.isChecked(gui, cbxReplyApprove): # accept exchange inject_joymax(CLIENT_EXCHANGE_APPROVE_REQUEST, b'', False) return True
def Fetch(guild_id): # Check if there is enough data to fetch if not guild_id or not guild_id.isnumeric(): return url = QtBind.text(gui,tbxWebsite) if not url: return token = QtBind.text(gui,tbxToken) # Try to fetch messages try: # Prepare json to send through POST method params = json.dumps({'guild':guild_id,'token':token,'charname':character_data['name'],'fetch_all':QtBind.isChecked(gui_,cbxDiscord_read_all)}).encode() if not url.endswith("/"): url += "/" req = urllib.request.Request(url+"api/fetch",data=params,headers={'content-type': 'application/json'}) with urllib.request.urlopen(req,timeout=5) as f: try: resp = json.loads(f.read().decode()) if resp: if resp['success']: on_discord_fetch(resp['data']) else: log("Plugin: Fetch failed ["+resp['message']+"]") except Exception as ex2: log("Plugin: Error reading response from server ["+str(ex2)+"]") except Exception as ex: log("Plugin: Error loading url ["+str(ex)+"]")
def Notify(channel_id,message,info=None): # Check if there is enough data to create a notification if not channel_id or not message: return url = QtBind.text(gui,tbxWebsite) if not url: return token = QtBind.text(gui,tbxToken) # Try to send notification try: # Add timestamp if QtBind.isChecked(gui,cbxAddTimestamp): message = "||"+datetime.now().strftime('%H:%M:%S')+"|| "+message # Prepare json to send through POST method params = json.dumps({"token":token,"channel":channel_id,"message":message,'info':info}).encode() if not url.endswith("/"): url += "/" req = urllib.request.Request(url+"api/notify",data=params,headers={'content-type': 'application/json'}) with urllib.request.urlopen(req,timeout=5) as f: try: resp = json.loads(f.read().decode()) if resp: if resp['success']: log("Plugin: Notification sent to Discord!") else: log("Plugin: Notification failed ["+resp['message']+"]") except Exception as ex2: log("Plugin: Error reading response from server ["+str(ex2)+"]") except Exception as ex: log("Plugin: Error loading url ["+str(ex)+"]")
def btnRemMob_clicked(): selectedIndex = QtBind.currentIndex(gui,lstAutoSelectMobs) if selectedIndex >= 0: QtBind.removeAt(gui,lstAutoSelectMobs,selectedIndex) global lstAutoSelectMobsData lstAutoSelectMobsData.pop(selectedIndex) saveConfigs()
def btnRemoveItem(listview, glistview): index = QtBind.currentIndex(gui, listview) if index >= 0: # Remove it glist = globals()[glistview] del glist[index] # From UI QtBind.removeAt(gui, listview, index)
def event_loop(): if inGame: if cbxMsg_checked: global delayCounter if delayCounter%delayMsg == 0: chat(['chat','All',QtBind.text(gui,tbxMsg)]) QtBind.setText(gui,lblCounter,str(int(QtBind.text(gui,lblCounter))+1)) delayCounter += 500
def btnRemExchanger_clicked(): # Check in game data if character_data: selectedItem = QtBind.text(gui, lvwExchangers) if selectedItem: QtBind.remove(gui, lvwExchangers, selectedItem) # saved successfully save_configs() log("Plugin: Exchanger removed [" + selectedItem + "]")
def btnRemOpcode_clicked(): selectedIndex = QtBind.currentIndex(gui, lstOpcodes) if selectedIndex >= 0: strOpcode = '0x{:02X}'.format(lstOpcodesData[selectedIndex]) del lstOpcodesData[selectedIndex] QtBind.removeAt(gui, lstOpcodes, selectedIndex) # saved successfully saveConfigs() log("Plugin: Removed opcode [" + strOpcode + "]")
def btnRemMob_clicked(): global lstMobsData # Check selected selected = QtBind.text(gui, lstMobs) if selected: lstMobsData.remove(selected) # Remove visually QtBind.remove(gui, lstMobs, selected) saveConfigs() log('Plugin: Monster removed [' + selected + ']')
def gui_qlist(): a = 0 while True: if a == get_qa('l',0): break b = get_qa("q",a) if not gui_check_qlist(b): QtBind.append(gui,qlist,b) a += 1 return False
def translate_thread(): lang = get_lang(QtBind.text(gui,cmbxTranslateOutgoingLang)) newMsg = translate_text(msg,lang) # Encoding message newPacket = p + struct.pack('<H',len(newMsg)) newPacket += newMsg.encode(encoding) if encoding == 'cp1252' else newMsg.encode(encoding)[2:] inject_joymax(opcode,newPacket,False) # Log translation text = '> ['+datetime.now().strftime('%H:%M:%S')+'] '+get_chat_type(chatType)+':'+newMsg QtBind.append(gui,lstTranslatedMessages,text)
def loadConfigs(): loadDefaultConfig() # Check config exists to load if os.path.exists(getConfig()): data = {} with open(getConfig(),"r") as f: data = json.load(f) if "Leaders" in data: for nickname in data["Leaders"]: QtBind.append(gui,lstLeaders,nickname)
def handle_event(t, data): # Filter events if t == 0: Notify(QtBind.text(gui_,cmbxEvtNear_unique),"|`"+character_data['name']+"`| - **"+data+"** unique is near to you!",CreateInfo("position",get_position())) elif t == 1: Notify(QtBind.text(gui_,cmbxEvtNear_hunter),"|`"+character_data['name']+"`| - **Hunter/Trader** `"+data+"` is near to you!",CreateInfo("position",get_position())) elif t == 2: Notify(QtBind.text(gui_,cmbxEvtNear_thief),"|`"+character_data['name']+"`| - **Thief** `"+data+"` is near to you!",CreateInfo("position",get_position())) elif t == 4: Notify(QtBind.text(gui_,cmbxEvtChar_attacked),"|`"+character_data['name']+"`| - `"+data+"` is attacking you!") elif t == 7: Notify(QtBind.text(gui_,cmbxEvtChar_died),"|`"+character_data['name']+"`| - You died",CreateInfo("position",get_position())) elif t == 3: pet = get_pets()[data] Notify(QtBind.text(gui_,cmbxEvtPet_died),"|`"+character_data['name']+"`| - **"+(pet['type'].title())+"** pet died") elif t == 5: channel_id = QtBind.text(gui_,cmbxEvtPick_rare) if channel_id: item = get_item(int(data)) Notify(channel_id,"|`"+character_data['name']+"`| - **Item (Rare)** picked up ***"+item['name']+" "+getCountryType(item['servername'])+"***") elif t == 6: channel_id = QtBind.text(gui_,cmbxEvtPick_equip) if channel_id: item = get_item(int(data)) itemName = item['name'] Notify(channel_id,"|`"+character_data['name']+"`| - **Item (Equipable)** picked up ***"+item['name']+" "+getCountryType(item['servername'])+"***") elif t == 8: Notify(QtBind.text(gui_,cmbxEvtBot_alchemy),"|`"+character_data['name']+"`| - **Auto alchemy** has been completed")
def btnAddMob_clicked(): global lstMobsData # Check name text = QtBind.text(gui, tbxMobs) if text and not ListContains(text, lstMobsData): lstMobsData.append(text) # Add visually QtBind.append(gui, lstMobs, text) QtBind.setText(gui, tbxMobs, "") saveConfigs() log('Plugin: Monster added [' + text + ']')
def event_loop(): if character_data: if cbxMsg_checked: global message_delay_counter message_delay_counter += 500 if message_delay_counter >= MESSAGES_DELAY: message_delay_counter = 0 message = QtBind.text(gui,tbxMsg) if message: phBotChat.All(QtBind.text(gui,tbxMsg)) QtBind.setText(gui,lblCounter,str(int(QtBind.text(gui,lblCounter))+1))
def cbxMsg_clicked(checked): global cbxMsg_checked cbxMsg_checked = checked if checked: # restart spamer counter global message_delay_counter message_delay_counter = 0 QtBind.setText(gui, lblCounter, "0") log("Plugin: Starting spam") else: log("Plugin: Stopping spam")
def handle_chat(t, charName, msg): if charName: if msg.startswith("TARGET "): # Check player at leader list if ListContains(charName, QtBind.getItems(gui, lvwLeaders)): # Read next param msg = msg[7:] if msg == "ON": QtBind.setChecked(gui, cbxEnabled, True) elif msg == "OFF": QtBind.setChecked(gui, cbxEnabled, False)
def loadConfigs(): loadDefaultConfig() if isJoined(): # Check config exists to load if os.path.exists(getConfig()): data = {} with open(getConfig(), "r") as f: data = json.load(f) if "Leaders" in data: for charName in data["Leaders"]: QtBind.append(gui, lvwLeaders, charName)
def GetSequence(): sequence = QtBind.text(gui, tbxSequence) # Check valid value if sequence.isnumeric(): sequence = int(sequence) else: sequence = SEQUENCE_DEFAULT_NUMBER QtBind.setText(gui, tbxSequence, str(sequence + 1)) saveConfigs(QtBind.text(gui, tbxProfileName)) return sequence
def loadKervanKey(): # Reading key from file key = "" if os.path.exists(getKervanKeyPath()): with open(getKervanKeyPath(), "r") as f: key = f.read() # Update if file is not empty if key: QtBind.setText(gui, tbxKey, key) # Load from GUI key = QtBind.text(gui, tbxKey) return key
def btnAddMob_clicked(): # Selecting mob from the scan list selectedIndex = QtBind.currentIndex(gui,lstMobs) if selectedIndex >= 0: selectedMob = lstMobsData[selectedIndex] if not ListAutoSelectMob_Contains(selectedMob): QtBind.append(gui,lstAutoSelectMobs,selectedMob['name']+" ("+getMobType(selectedMob['type'])+")") global lstAutoSelectMobsData lstAutoSelectMobsData.append(selectedMob) saveConfigs()