from PyQt5.QtGui import * from PyQt5.QtWidgets import * from PyQt5.QtCore import * import os import getpass import telnetlib import re import time import keyboard import random import sys import paho.mqtt.client as mqtt #Test #HOST = "telnet.goldenunicorn.net" #HOST = "192.168.254.238" #MQTT_ENABLED = False player_list = [] MAX_SELL_ITEMS = 1 class player(): def __init__(self): self.usr = "" self.pwrd = "" self.char_sel = 4 self.weapon = "" self.spell = "" self.auto_combat = True self.auto_ion = True self.meander = False self.auto_farm = False self.hunt = False self.bait = False self.start_year = 2000 self.end_year = 2500 self.no_action = 50 login_f = sys.argv[1] print("login file: "+sys.argv[1]) def player_add(usr,pwd,char_sel,weapon,spell,ac,ai,me,af,hu,ba,start_year,end_year,no_action): plyr = player() plyr.usr = usr plyr.pwrd = pwd plyr.char_sel = char_sel plyr.weapon = weapon plyr.spell = spell plyr.auto_combat = ac plyr.auto_ion = ai plyr.meander = me plyr.auto_farm = af plyr.hunt = hu plyr.bait = ba plyr.start_year = start_year plyr.end_year = end_year plyr.no_action = no_action player_list.append(plyr) #load player def load_player_file(login): file = "./"+login with open(file, 'r') as login_file: system_line = login_file.readline().strip() system_conf = system_line.split(",") global HOST HOST = system_conf[0] global MQTT_ENABLED MQTT_ENABLED = system_conf[1] == 'True' #quit(0) while True: in_str = login_file.readline().strip() if in_str != "": f_player=in_str.split(",") plyr = player() plyr.usr = f_player[0] plyr.pwrd = f_player[1] plyr.char_sel = int(f_player[2]) plyr.weapon = f_player[3] plyr.spell = f_player[4] plyr.auto_combat = f_player[5] == 'True' plyr.auto_ion = f_player[6] == 'True' plyr.meander = f_player[7] == 'True' plyr.auto_farm = f_player[8] == 'True' plyr.hunt = f_player[9] == 'True' plyr.bait = f_player[10] == 'True' plyr.start_year = int(f_player[11]) plyr.end_year = int(f_player[12]) plyr.no_action = int(f_player[13]) player_list.append(plyr) # end of file is reached if not in_str: break load_player_file(login_f) #static lists convert_list = ["Ion-Pack","Ion-Decay","Cheese","Nuclear-thong","Skull","Bottle-Cap","Cigarette-Butt","Knife","Gas-Grenade","Leather-Vest","Buckler","Bola","Bug-Plate", "Light-Spear","Silver-Potion","Bastard-Sword","Invisible-Knife","Great-Club","Spear","Blizzard-Staff","Devil_Key","Grey-Dagger","Bone","Axe","BlackJack", "Golden-Key","Crystal-Key","Trident","Ice-Knife","Iron-Sickle","Gold-Spear","Fang-Dagger","Hound-Fang","Pink-Potion","Small-Dagger","Mage-Stick","Purple-Potion", "Tree-Branch","Poker","Bronze Knife","Small-Club","Wonderous-Sword","Spell-Potion","Long-Sword","Ion-Gauntlet","Sling-Sword","Small-Spear","Iron-Mace","Iron-Boots", "Tree-Stump","Saphire","Flame-Sword","Rock-Club","Lava-Dagger","Bloody-Arm","Golden-Needle","Ion-Booster","Devil-Key","Chain-Mail","Weak-Cloth","Splint-Mail","Rags", "Bug-Skin","Troll-Sword","Axe","Plate-Mail","Common-Hide","Kelp-Mail","Green-Vial","Broken-Armour","Broken-Weapon"] farm_sell_list = ["Gold-Chunck","Nuclear-Rock","Nuclear-Waste"] farm_stock_list = ["Nuclear-Decay","Eazy-Armor","Hell-Blade"] friend_list = ["Epilectrik","ImBait","Mtron","Im","IonJunkies-Merc","Robin-Hood","Doctor","Assassin","Mercenary","Mutant-warrior-1","Mutant-warrior-2","CarlRam","tkls-Warrior","tkls-Warrior2","tkls-Priest","tkls-Wizard1"] #cure_path = ["done","tra 2000","north","north","north","north","cure me","!return","done"] help_list = ["$ - Key listener on/off", "8 - North", "2 - South", "6 - East", "4 - West", "5 - Look direction", "c - Combat", "w - Wield weapon", "a - Auto combat on/off", "f - Auto farm on/off", "i - Auto Ion on/off", "t - time travel", "d - drop item", "k - keyboard input", "v - status", "m - meander" ] opposite_dir = { "north":"south", "south":"north", "east":"west", "west":"east", } #Heater popup window class mutant(QWidget): command_str = pyqtSignal(str) mqtt_str = pyqtSignal(str) mqtt_str_quiet = pyqtSignal(str,str) tab_color = pyqtSignal(int,str) broadcast = pyqtSignal(list) def __init__(self,player,idx): QWidget.__init__(self) self.player=player self.idx=idx #file related self.path=player.usr #dynamic lists self.local_items = [] self.local_monsters = [] self.direction_list = [] self.sell_list = [] self.stock_list = [] self.bank_list = [] self.cmd_buffer = [] #modes self.heal = False self.wander = False self.bait = False self.hunt = False self.auto_combat = True self.auto_ion = True self.auto_farm = False self.key_detect = False #states self.time_steps = 0 self.in_play = False self.in_combat = False self.hits = 0 self.lock_key="[" self.area_indexed = True self.stat_parsed = True self.previous_dir = "" self.selected_path = 0 self.path_step = 0 self.location = [0,0] self.weapon = "Nuclear-Decay" self.spell = player.spell self.watchdog = 0 self.cmd_watchdog = 0 self.prompt = False self.poisoned = False self.current_path = "" self.year_limit_high=player.end_year self.year_limit_low=player.start_year #value tracking self.riblets = 0 self.ions = 0 self.hp = 0 self.exp = 0 self.clss = "Thief" self.level = 0 self.riblet_thresh = 200000 self.ion_thresh = 4000000 self.present_year=player.start_year self.no_action_cnt = 0 self.na_thresh = player.no_action self.status = "" self.area = "" self.console_lines = 0 self.min_riblets = 6000000 #account self.user = player.usr self.password = player.pwrd self.char_sel = player.char_sel if self.char_sel == 2: convert_list.append('Gold-Chunck') self.ion_thresh = 8000000 self.logged_in = False #timers #healing self.heal_timer = QTimer() self.heal_timer.setInterval(1000) self.heal_timer.timeout.connect(self.heal_trig) self.heal_timer.start() #wielding self.wield_timer = QTimer() self.wield_timer.setInterval(200) self.wield_timer.timeout.connect(self.wield_trig) self.wield_timer.start() #wander self.wander_timer = QTimer() self.wander_timer.setInterval(500) self.wander_timer.timeout.connect(self.wander_trig) self.wander_timer.start() #stat self.stat_timer = QTimer() self.stat_timer.setInterval(30000) self.stat_timer.timeout.connect(self.stat_trig) self.stat_timer.start() #path self.path_timer = QTimer() self.path_timer.setInterval(100) self.path_timer.timeout.connect(self.path_trig) self.path_timer.start() #watchdog self.watchdog_timer = QTimer() self.watchdog_timer.setInterval(30000) self.watchdog_timer.timeout.connect(self.watchdog_t) self.watchdog_timer.start() #cmd watchdog self.watchdog_cmd_timer = QTimer() self.watchdog_cmd_timer.setInterval(100) self.watchdog_cmd_timer.timeout.connect(self.watchdog_cmd) self.watchdog_cmd_timer.start() #layout stuff self.layout = QVBoxLayout() # Add console self.console = QTextEdit() self.console.setTextColor(QColor(255, 255, 255)) self.console.setStyleSheet("QTextEdit { color: white; background-color: rgb(0, 0, 0); font-size: 18px; }") self.console.clear() self.console.append("test") self.console.setMinimumHeight(300) self.layout.addWidget(self.console) #Add buttons self.button_group() # Add text input self.formGroupBox = QFormLayout() self.text_input = QLineEdit() self.text_button = QPushButton("Send") self.text_button.clicked.connect(self.send_str) self.text_input_2 = QLineEdit() self.text_button_2 = QPushButton("Send") self.text_button_2.clicked.connect(self.send_str_2) self.formGroupBox.addRow(self.text_button,self.text_input) self.formGroupBox.addRow(self.text_button_2,self.text_input_2) self.layout.addLayout(self.formGroupBox) #stat group self.createStatGroup() self.layout.addLayout(self.stat_layout) #mode group self.createModeGroup() self.layout.addLayout(self.mode_layout) #settings group self.createSettingsGroup() self.layout.addLayout(self.settings_layout) self.weapon_input.setText(player.weapon) self.setLayout(self.layout) self.load_bank_paths() self.init_telnet() #self.set_color() def request_received(self,request): print("global request received") print(request) req_type = request[0] req_year = request[1] req_player = request[2] if self.char_sel == 2: if req_type == 'poison': cure_path = ['done','tra '+req_year,'cast '+req_player,'!return','done'] self.current_path = cure_path self.path_step = 1 def send_cmd(self,cmd_str): if self.prompt: self.command_str.emit(cmd_str) else: self.cmd_buffer.append(cmd_str) def transmit_bfr(self): while len(self.cmd_buffer)>0: self.command_str.emit(self.cmd_buffer[0]) self.cmd_buffer.pop(0) def set_color(self): self.setAttribute(Qt.WA_StyledBackground, True) self.setStyleSheet('background-color: red;') def init_telnet(self): #init telnet thread self.tn_obj = telnet_thread() self.tn_thread = QThread() self.tn_obj.moveToThread(self.tn_thread) #Connect signals self.tn_thread.started.connect(self.tn_obj.telnet_listen) self.tn_obj.received.connect(self.execute_loop) self.command_str.connect(self.tn_obj.tn_write) self.tn_obj.disconnected.connect(self.reconnect) #start thread self.tn_thread.start() def reconnect(self): self.player_exit() print("obj restarting") #create buttons def button_group(self): hbox1 = QHBoxLayout() b_grid = QGridLayout() button_w = 50 north_button = QPushButton("North") south_button = QPushButton("South") east_button = QPushButton("East") west_button = QPushButton("West") heal_button = QPushButton("Heal") combat_button = QPushButton("Combat") path_button = QPushButton("Path") look_button = QPushButton("Look") stat_button = QPushButton("Stat") b_grid.addWidget(north_button,0,1) b_grid.addWidget(south_button,2,1) b_grid.addWidget(east_button,1,2) b_grid.addWidget(west_button,1,0) b_grid.addWidget(heal_button,0,0) b_grid.addWidget(combat_button,0,2) b_grid.addWidget(path_button,2,0) b_grid.addWidget(look_button,1,1) b_grid.addWidget(stat_button,2,2) hbox1.addItem(QSpacerItem(150, 0, QSizePolicy.Minimum)) hbox1.addLayout(b_grid) hbox1.addItem(QSpacerItem(150, 0, QSizePolicy.Minimum)) north_button.clicked.connect(self.n_btn) south_button.clicked.connect(self.s_btn) east_button.clicked.connect(self.e_btn) west_button.clicked.connect(self.w_btn) heal_button.clicked.connect(self.h_btn) combat_button.clicked.connect(self.c_btn) path_button.clicked.connect(self.p_btn) look_button.clicked.connect(self.l_btn) stat_button.clicked.connect(self.st_btn) self.layout.addLayout(hbox1) #Creates the form groupbox def createModeGroup(self): self.mode_layout = QVBoxLayout() hbox1 = QHBoxLayout() hbox2 = QHBoxLayout() self.ac_check = QCheckBox("Auto Combat") self.ac_check.setChecked(True) self.af_check = QCheckBox("Auto Farm") self.ai_check = QCheckBox("Auto Ion") self.ai_check.setChecked(True) self.me_check = QCheckBox("Meander") self.ba_check = QCheckBox("Bait") self.hu_check = QCheckBox("Hunt") self.ac_check.stateChanged.connect(self.ac_checked) self.af_check.stateChanged.connect(self.af_checked) self.ai_check.stateChanged.connect(self.ai_checked) self.me_check.stateChanged.connect(self.me_checked) self.ba_check.stateChanged.connect(self.ba_checked) self.hu_check.stateChanged.connect(self.hu_checked) hbox1.addWidget(self.ac_check) hbox1.addWidget(self.af_check) hbox1.addWidget(self.ba_check) hbox2.addWidget(self.ai_check) hbox2.addWidget(self.me_check) hbox2.addWidget(self.hu_check) self.mode_layout.addLayout(hbox1) self.mode_layout.addLayout(hbox2) #stat labels def createStatGroup(self): self.stat_layout = QVBoxLayout() hbox1 = QHBoxLayout() hbox2 = QHBoxLayout() userLabel = QLabel("User: ") self.userLabel = QLabel("None") expLabel = QLabel("Exp: ") self.expLabel = QLabel("None") levelLabel = QLabel("Level: ") self.levelLabel = QLabel("None") yearLabel = QLabel("Year: ") self.yearLabel = QLabel("None") locationLabel = QLabel("Loc: ") self.locationLabel = QLabel("None") hpLabel = QLabel("HP: ") self.hpLabel = QLabel("None") ribletLabel = QLabel("Riblets: ") self.ribletLabel = QLabel("None") ionLabel = QLabel("Ions: ") self.ionLabel = QLabel("None") hbox1.addWidget(userLabel) hbox1.addWidget(self.userLabel) hbox1.addWidget(expLabel) hbox1.addWidget(self.expLabel) hbox1.addWidget(levelLabel) hbox1.addWidget(self.levelLabel) hbox1.addWidget(yearLabel) hbox1.addWidget(self.yearLabel) hbox2.addWidget(locationLabel) hbox2.addWidget(self.locationLabel) hbox2.addWidget(hpLabel) hbox2.addWidget(self.hpLabel) hbox2.addWidget(ribletLabel) hbox2.addWidget(self.ribletLabel) hbox2.addWidget(ionLabel) hbox2.addWidget(self.ionLabel) self.stat_layout.addLayout(hbox1) self.stat_layout.addLayout(hbox2) #Text inputs def createSettingsGroup(self): self.settings_layout = QHBoxLayout() self.settingsGroupBox = QFormLayout() self.settingsGroupBox_2 = QFormLayout() self.weapon_input = QLineEdit("Nuclear-Decay") self.na_input = QLineEdit(str(self.na_thresh)) self.yl_start_input = QLineEdit(str(self.year_limit_low)) self.yl_end_input = QLineEdit(str(self.year_limit_high)) self.path_input = QLineEdit("0") self.settingsGroupBox.addRow(QLabel("Weapon:"),self.weapon_input) self.settingsGroupBox.addRow(QLabel("No Action:"),self.na_input) self.settingsGroupBox.addRow(QLabel("Year Limit Start:"),self.yl_start_input) self.settingsGroupBox_2.addRow(QLabel("Year Limit End:"),self.yl_end_input) self.settingsGroupBox_2.addRow(QLabel("Path:"),self.path_input) self.settings_layout.addLayout(self.settingsGroupBox) self.settings_layout.addLayout(self.settingsGroupBox_2) #buttons def n_btn(self): self.send_cmd("north\r\n") def s_btn(self): self.send_cmd("south\r\n") def e_btn(self): self.send_cmd("east\r\n") def w_btn(self): self.send_cmd("west\r\n") def h_btn(self): self.heal = True def c_btn(self): self.combat_start() def p_btn(self): self.send_cmd("stat\r\n") self.current_path = self.bank_list[self.selected_path][:] self.path_step = 1 def l_btn(self): self.send_cmd("look\r\n") def st_btn(self): self.send_cmd("stat\r\n") #load bank file def load_bank_paths(self): file = "./"+self.path+"/banks.txt" if (os.path.exists(self.path) == False): os.makedirs(self.path) f = open(file, "x") f.write("done,done\r\n") f.seek(0) print("creating "+file) else: print("File Exists") with open(file, 'r') as script: while True: in_str = script.readline().strip() if in_str != "": self.bank_list.append(in_str.split(",")) # end of file is reached if not in_str: break self.current_path = self.bank_list[0][:] #Button send text def send_str(self): self.send_cmd(self.text_input.text()+"\r\n") def send_str_2(self): self.send_cmd(self.text_input_2.text()+"\r\n") #auto combat checked def ac_checked(self): self.auto_combat = self.ac_check.isChecked() print("Auto Combat: "+str(self.auto_combat)) #auto farm checked def af_checked(self): self.auto_farm = self.af_check.isChecked() print("Auto farm: "+str(self.auto_farm)) #auto ion checked def ai_checked(self): self.auto_ion = self.ai_check.isChecked() print("Auto ion: "+str(self.auto_ion)) #meander checked def me_checked(self): self.wander = self.me_check.isChecked() print("Wander: "+str(self.wander)) #meander checked def ba_checked(self): self.bait = self.ba_check.isChecked() print("Bait: "+str(self.bait)) #meander checked def hu_checked(self): self.hunt = self.hu_check.isChecked() print("Hunt: "+str(self.hunt)) #heal timer def heal_trig(self): if self.heal and self.logged_in and self.in_play: self.send_cmd("heal\r\n") #self.mqtt_str_quiet.emit(self.user," is healing." ) #wield timer def wield_trig(self): if self.in_combat and self.logged_in and self.in_play: self.send_cmd("wield "+self.weapon+"\r\n") #wander timer def wander_trig(self): if self.wander and self.logged_in and self.in_play and not self.in_combat and self.path_step == 0: self.area_indexed = False self.local_monsters = [] self.local_items = [] #print("wander triggered") #print("no action: " + str(self.no_action_cnt)) #increment no action counter self.no_action_cnt = self.no_action_cnt + 1 if len(self.direction_list) == 0: self.send_cmd("look\r\n") #pick randomly if len(self.direction_list) > 0: if len(self.direction_list) > 1: try: self.direction_list.remove(self.previous_dir) except: pass #print(self.direction_list) dir_choice = random.choice(self.direction_list) try: if dir_choice == "north": self.location[1] = self.location[1] + 1 if dir_choice == "south": self.location[1] = self.location[1] - 1 if dir_choice == "east": self.location[0] = self.location[0] + 1 if dir_choice == "west": self.location[0] = self.location[0] - 1 except: pass self.send_cmd(dir_choice+"\r\n") self.direction_list = [] self.previous_dir = opposite_dir[dir_choice] #stat timer def stat_trig(self): if self.logged_in and self.in_play and not self.in_combat and self.path_step == 0: self.send_cmd("stat\r\n") self.send_cmd("look\r\n") #path timer def path_trig(self): if self.logged_in and self.in_play and not self.in_combat: self.path_process() #search a list def search(self, list, platform): for i in range(len(list)): if list[i] == platform: return True return False #Reup Ions def convert_items(self): for item_l in self.local_items: for item in convert_list: if item_l == item: self.send_cmd("get "+item+"\r\n") self.send_cmd("con "+item+"\r\n") self.mqtt_str_quiet.emit(self.user," converted " + item ) try: self.local_items.remove(item_l) except: pass #Farms valuable stuff def farm_sell_items(self): for item_l in self.local_items: for item in farm_sell_list: if item_l == item and self.sell_list.count(item) < MAX_SELL_ITEMS: #print("Farm sell count:"+item) #print(self.sell_list.count(item)) #print(self.sell_list) self.send_cmd("get "+item+"\r\n") self.local_items.remove(item_l) self.sell_list.append(item_l) #print(self.sell_list) self.no_action_cnt = 0 #Farms valuable stuff def farm_stock_items(self): for item_l in self.local_items: for item in farm_stock_list: if item_l == item: self.send_cmd("get "+item+"\r\n") self.local_items.remove(item_l) self.stock_list.append(item_l) self.no_action_cnt = 0 #Sell items def sell_items(self): #print(self.sell_list) while len(self.sell_list) > 0: item_l=self.sell_list[0] self.sell_list.pop(0) self.send_cmd("sell "+item_l+"\r\n") time.sleep(.05) self.send_cmd("stat\r\n") #Stock def stock_items(self): #print(self.stock_list) for item_s in farm_stock_list: for item in self.stock_list: if item == item_s: cnt = self.stock_list.count(item) #print("item count: "+str(cnt)) if item == self.weapon: cnt = cnt - 1 #print("sub weapon count: "+str(cnt)) for x in range(cnt): self.send_cmd("stock "+item+"\r\n") self.stock_list.remove(item) time.sleep(.05) #Add to convert list def add_convert(self): temp_list = farm_sell_list + farm_stock_list + convert_list for item in self.local_items: if not temp_list.count(item): convert_list.append(item) print("Convert Item Added: " + item) #Drop monster baits def drop_baits(self): while self.stock_list.count("Monster-Bait") > 1: self.send_cmd("drop monster-bait\r\n") self.stock_list.remove("Monster-Bait") #Remove friends from monster list def remove_friends(self): for friend in friend_list: try: self.local_monsters.remove(friend) except: pass #Flushes keyboard def flush_input(self): try: import msvcrt while msvcrt.kbhit(): msvcrt.getch() except ImportError: import sys, termios termios.tcflush(sys.stdin, termios.TCIOFLUSH) #Decode incoming information def decode_line(self,line): result = "" if line.decode('cp1252') != "": ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') result = ansi_escape.sub('', line.decode('cp1252').strip('\n')) self.console.append(result) return result #initiate combat def combat_start(self): try: self.send_cmd("combat " + self.local_monsters[0]+"\r\n") self.mqtt_str_quiet.emit(self.user," is attacking " + self.local_monsters[0] ) except: pass self.in_combat = True self.heal = True self.wield_trig() self.path_step = 0 self.no_action_cnt = 0 #process wander def wander_process(self, result): #area clear if result.find("north - area continues.") != -1 or result.find("north - open gate.") != -1: self.direction_list.append("north") if result.find("south - area continues.") != -1 or result.find("south - open gate.") != -1: self.direction_list.append("south") if result.find("east - area continues.") != -1 or result.find("east - open gate.") != -1: self.direction_list.append("east") if result.find("west - area continues.") != -1 or result.find("west - open gate.") != -1: self.direction_list.append("west") #are there monsters if result.find("You see shadows to the") != -1 and not self.hunt: try: if result.find("north") != -1: self.direction_list.remove("north") if result.find("south") != -1: self.direction_list.remove("south") if result.find("east") != -1: self.direction_list.remove("east") if result.find("west") != -1: self.direction_list.remove("west") except: pass #process combat per loop def combat_process(self, result): if result.find("You suffer") != -1: self.hits = self.hits + 1 if self.hits == 2: self.send_cmd("heal\r\n") self.send_cmd("heal\r\n") self.hits = 0 if result.find("have slain") != -1 or result.find("has just left") != -1 or result.find("isn't around here!") != -1 or result.find("You're not ready") != -1: try: self.local_monsters.pop(0) except: pass if len(self.local_monsters) > 0: self.send_cmd("combat " + self.local_monsters[0]+"\r\n") else: #print("Area cleared") self.in_combat = False #time travel def time_travel(self): self.local_items = [] self.location = [0,0] self.present_year = self.present_year + 100 if self.present_year > self.year_limit_high: self.present_year = self.year_limit_low self.send_cmd("tra "+str(self.present_year)+"\r\n") self.drop_baits() if self.bait and not self.stock_list.count("Monster-Bait"): self.send_cmd("get Monster-Bait\r\n") self.stock_list.append("Monster-Bait") self.send_cmd("look\r\n") #process path def path_process(self): #path_str = self.bank_list[self.selected_path][self.path_step] path_str = self.current_path[self.path_step] if path_str != "done": if path_str[0] == "!": self.script_function(path_str.strip("!").upper()) else: self.send_cmd(path_str+"\r\n") self.path_step = self.path_step + 1 self.no_action_cnt = 0 else: self.path_step = 0 #handle functions in path script def script_function(self,function): if function == "DEPOSIT": #Calculate riblets to deposit dep_ribs = self.riblets - self.min_riblets if dep_ribs < 0: dep_ribs = 0 #Deposit self.send_cmd("deposit "+str(dep_ribs)+"\r\n") self.mqtt_str_quiet.emit(self.user," deposited "+str(self.riblets)+" riblets" ) self.riblets = self.min_riblets #Secure ions if high if self.ions > self.ion_thresh: self.send_cmd("secure "+str(self.ions-self.ion_thresh)+"\r\n") self.mqtt_str_quiet.emit(self.user," secured "+str(self.ions-self.ion_thresh)+" ions" ) self.ions = self.ion_thresh #Unsecure ions if low if self.ions < self.ion_thresh: self.send_cmd("unsecure "+str(self.ion_thresh-self.ions)+"\r\n") self.mqtt_str_quiet.emit(self.user," unsecured "+str(self.ion_thresh-self.ions)+" ions" ) self.ions = self.ion_thresh #Stock items if function == "STOCK" and self.auto_farm: self.stock_items() #Sell items if function == "SELL": self.sell_items() #Return to starting year if function == "RETURN": self.path_step = -1 self.send_cmd("tra "+str(self.present_year)+"\r\n") new_path = self.selected_path + 1 if new_path == len(self.bank_list): new_path = 0 self.path_input.setText(str(new_path)) self.tab_color.emit(self.idx,'green') #Request poison cure if function == "POISON": request = ['poison',str(self.present_year),self.user] self.broadcast.emit(request) #process stats def parse_stat(self, result): if self.stat_parsed == False: self.status += result if (result.find("(N)onstop") != -1 or result.find("(Q)uit") != -1 or result.find("(C)ontinue") != -1 or result.find("wield") != -1): self.status = "" self.stat_parsed = True if result.find(">") != -1: #Retally items, convert extras if not self.stat_parsed and self.status != "": self.sell_list = [] self.stock_list = [] self.watchdog = 0 for item_l in farm_sell_list: x = self.status.count(item_l) for i in range(x): if i < MAX_SELL_ITEMS: self.sell_list.append(item_l) else: self.send_cmd("con "+item_l+"\r\n") #print(self.sell_list) for item_l in farm_stock_list: x = self.status.count(item_l) for i in range(x): if i < 3: self.stock_list.append(item_l) else: self.send_cmd("con "+item_l+"\r\n") #HP if self.status.find("Hit Points :") != -1: start_index = self.status.index('Hit Points : ') + 15 hp_str = self.status[start_index:] try: end_index = hp_str.index('/') hp_str = hp_str[:end_index] self.hp = int(hp_str) except: pass #exp if self.status.find("Exp. Points :") != -1: start_index = self.status.index('Exp. Points : ') + 15 exp_str = self.status[start_index:] try: end_index = exp_str.index('Level') exp_str = exp_str[:end_index] self.exp = int(exp_str) except: pass #scrape level if self.status.find("Level: ") != -1: start_index = self.status.index('Level: ') + 7 level_str = self.status[start_index:] try: end_index = level_str.index('Riblets') level_str = level_str[:end_index] self.level = int(level_str) except: pass #scrape riblets if self.status.find("Riblets :") != -1: start_index = self.status.index('Riblets : ') + 16 riblets_str = self.status[start_index:] try: end_index = riblets_str.index('Ions') riblets_str = riblets_str[:end_index] self.riblets = int(riblets_str) except: pass #scrape ions if self.status.find("Ions : ") != -1: start_index = self.status.index('Ions : ') + 16 ions_str = self.status[start_index:] try: end_index = ions_str.index('Wearing') ions_str = ions_str[:end_index] self.ions = int(ions_str) except: pass #scrape year if self.status.find("Year A.D. :") != -1: start_index = self.status.index('Year A.D. : ') + 17 year_str = self.status[start_index:] try: end_index = 4 year_str = year_str[:end_index] current_year = int(year_str) if not self.wander: self.present_year = current_year else: if current_year != self.present_year: self.send_cmd("tra "+str(self.present_year)+"\r\n") except: pass self.status = "" self.stat_parsed = True #index area def index_area(self,result): if self.area_indexed == False: self.area += result if result.find(">") != -1: self.area_indexed = True if self.area_indexed and self.area != "": if self.area.find("On the ground lies:") != -1: start_index = self.area.index('On the ground lies:') item_str = self.area[start_index:] try: end_index = item_str.index('***') except: try: end_index = item_str.index('>') except: pass item_str = item_str[:end_index] item_str = item_str.replace("On the ground lies:","") item_str = item_str.replace("0","") item_str = item_str.replace("1","") item_str = item_str.replace("2","") item_str = item_str.replace("3","") item_str = item_str.replace("4","") item_str = item_str.replace("5","") item_str = item_str.replace("6","") item_str = item_str.replace("7","") item_str = item_str.replace("8","") item_str = item_str.replace("9","") item_str = item_str.replace("(","") item_str = item_str.replace(")","") item_str = item_str.replace("A ","") item_str = item_str.replace("An ","") item_str = item_str.replace(" ","") item_str = item_str.replace(".","") item_str = item_str.replace("\r\n","") item_str = item_str.replace("***","") self.local_items = list(item_str.split(",")) #print(self.local_items) if self.area.find("is here") != -1 or self.area.find("are here") != -1: try: end_index = self.area.index('here') monster_str = self.area[:end_index] start_index = monster_str.rindex('***') monster_str = monster_str[start_index:] monster_str = monster_str.replace("\r\n","") monster_str = monster_str.replace(" and ","") monster_str = monster_str.replace(" are ","") monster_str = monster_str.replace(" is ","") monster_str = monster_str.replace(" ","") monster_str = monster_str.replace(".","") monster_str = monster_str.replace("***","") self.local_monsters = list(monster_str.split(",")) self.remove_friends() #print(self.local_monsters) except: pass self.area = "" #drop def exit_game(self): self.in_combat=False self.heal = False self.wander = False self.auto_farm = False self.auto_combat = False self.in_play = False self.hunt = False self.ac_check.setChecked(False) self.af_check.setChecked(False) self.ai_check.setChecked(False) self.me_check.setChecked(False) self.ba_check.setChecked(False) self.hu_check.setChecked(False) self.tab_color.emit(self.idx,'red') #Sync checkbox with state def change_hunt_state(self,state): self.hunt = state self.hu_check.setChecked(self.hunt) #Sync checkbox with state def change_meander_state(self,state): self.wander = state self.me_check.setChecked(self.wander) #Player starting condition def player_init(self): self.in_combat=False self.heal = False self.in_play = True self.logged_in = True self.wander = self.player.meander self.auto_farm = self.player.auto_farm self.auto_combat = self.player.auto_combat self.auto_ion = self.player.auto_ion self.hunt = self.player.hunt self.bait = self.player.bait self.ac_check.setChecked(self.auto_combat) self.af_check.setChecked(self.auto_farm) self.ai_check.setChecked(self.auto_ion) self.me_check.setChecked(self.wander) self.ba_check.setChecked(self.bait) self.hu_check.setChecked(self.hunt) self.tab_color.emit(self.idx,'green') #Player starting condition def player_exit(self): self.in_combat=False self.heal = False self.in_play = False self.logged_in = False self.wander = False self.auto_farm = False self.auto_combat = False self.auto_ion = False self.hunt = False self.bait = False self.ac_check.setChecked(self.auto_combat) self.af_check.setChecked(self.auto_farm) self.ai_check.setChecked(self.auto_ion) self.me_check.setChecked(self.wander) self.ba_check.setChecked(self.bait) self.hu_check.setChecked(self.hunt) self.tab_color.emit(self.idx,'red') #Resets connection with no activity def watchdog_t(self): if self.watchdog > 4: self.player_exit() self.tn_obj.close_telnet() self.watchdog = 0 else: self.watchdog = self.watchdog + 1 def watchdog_cmd(self): if self.cmd_watchdog > 2: if len(self.cmd_buffer)>0: self.transmit_bfr() self.cmd_watchdog = 0 else: self.cmd_watchdog = self.cmd_watchdog + 1 #Main game loop def mutants(self,result): #update farm year text box try: self.userLabel.setText(self.user) self.expLabel.setText(str(self.exp)) self.levelLabel.setText(str(self.level)) self.yearLabel.setText(str(self.present_year)) self.locationLabel.setText(str(self.location)) self.hpLabel.setText(str(self.hp)) self.ribletLabel.setText(str(self.riblets)) self.ionLabel.setText(str(self.ions)) self.weapon = self.weapon_input.text() self.na_thresh = int(self.na_input.text()) self.year_limit_low = int(self.yl_start_input.text()) self.year_limit_high = int(self.yl_end_input.text()) self.selected_path = int(self.path_input.text()) except: pass #Detect prompt if result.find(">") != -1: self.transmit_bfr() self.cmd_watchdog = 0 self.prompt = True else: self.prompt = False #Nothing has happened in a while, time jump if self.no_action_cnt > self.na_thresh: self.time_travel() self.no_action_cnt = 0 #New area, take a look #Detect in play if result.find("Prepare to walk a thousand years!") != -1: self.in_play = True #self.player_init() self.send_cmd("blurb\r\n") self.send_cmd("deaf\r\n") self.send_cmd("memorize "+self.spell+"\r\n") self.tab_color.emit(self.idx,'green') print("Character in play..") #New area, set index, get location if result.find("Compass:") != -1: res_filter = result.replace("Compass:","") res_filter = res_filter.replace("Compass:","") res_filter = res_filter.replace("N","") res_filter = res_filter.replace("E","") res_filter = res_filter.replace(":",",") res_filter = res_filter.replace("(","") res_filter = res_filter.replace(")","") res_filter = res_filter.replace(" ","") try: self.location = list(map(int, res_filter.split(","))) except: print('location failed') #print(self.location) self.area_indexed = False #drop baits if self.location == [0,0]: self.drop_baits() #parse status self.parse_stat(result) #index area self.index_area(result) #deposit riblets if (self.riblets > (self.min_riblets + self.riblet_thresh) or self.ions < (self.ion_thresh/2)) and self.path_step == 0 and self.wander and not self.in_combat: self.send_cmd("stat\r\n") self.current_path = self.bank_list[self.selected_path][:] self.path_step = 1 #process wander if self.wander and not self.in_combat and self.path_step == 0: self.wander_process(result) #process combat if self.in_combat: self.combat_process(result) #scrapers if result.find("(N)onstop, (Q)uit, or (C)ontinue?") != -1: self.command_str.emit("\r\n") #ion starvation if result.find("You're starving for IONS!") != -1 or result.find("You don't have enough ions to heal!") != -1: self.mqtt_str.emit(self.user+" needs ions") self.send_cmd("X\r\n") #too heavy if self.wander and result.find("The weight of all your items forces you to the ground.") != -1: self.wander = False self.send_cmd("X\r\n") #Detect bait mode, add or remove from stock list if self.bait: if not farm_stock_list.count("Monster-Bait"): farm_stock_list.append("Monster-Bait") else: try: farm_stock_list.remove("Monster-Bait") except: pass #Exit game if.. if self.in_combat and result.find("You're not carrying a "+self.weapon.lower()) != -1: self.send_cmd("kick\r\n") self.mqtt_str.emit(self.user+" has no weapon") #self.exit_game() #Lighten if result.find("It's too dark to see anything!") != -1: if self.char_sel == 4: self.send_cmd("cast\r\n") else: self.time_travel() #GTFO #if result.find("You're blocked!") != -1 or len(self.local_monsters) > 4: # self.heal = True # local_monsters = [] # self.command_str.emit("tra "+str(self.present_year)+"\r\n") # self.in_combat = False #Sell the loot if (result.find("City Trading Centre") != -1 or result.find("Satan Inc. Trade Centre") != -1) and self.path_step == 0 and not self.in_combat: if len(self.sell_list) > 0: self.sell_items() #cure poison #if result.find("You're in a maintenance shop.") != -1: # if self.poisoned: # self.send_cmd("cure me\r\n") # self.poisoned = False # self.change_hunt_state(True) # self.tab_color.emit(self.idx,'green') #Parse character status if result.find("stat") != -1: self.stat_parsed = False #Trigger stop healing if result.find("Nothing happens!") != -1 or result.find("You don't have enough ions to heal!") != -1: self.heal = False #Turn on healing if result.find("You suffer") != -1 or result.find("You are poisoned!") != -1: self.heal = True #Detect poisoning if result.find("You are poisoned!") != -1: #self.change_meander_state(False) #self.change_hunt_state(False) #self.poisoned = True self.mqtt_str.emit(self.user+" is poisoned") self.tab_color.emit(self.idx,'Yellow') self.send_cmd("heal\r\n") self.send_cmd("heal\r\n") self.change_meander_state(False) cure_path = ['done','tra '+str(self.present_year),'!poison','done'] self.current_path = cure_path self.path_step = 1 #Poison cured if result.find("has just cured your poison!") != -1: self.mqtt_str.emit(self.user+" is cured") self.tab_color.emit(self.idx,'Green') self.change_meander_state(True) #Monster list related if (result.find("yells: Gimmie") != -1 or result.find("just arrived from") != -1 or result.find("has hit") != -1 or result.find("body is glowing") != -1 or result.find("Get away from me") != -1 or result.find("just appeared through a time portal!") != -1): m = result.index(' ') monster = result[:m] if not self.search(self.local_monsters, monster): self.local_monsters.append(monster) self.remove_friends() #print(self.local_monsters) #Start Combat if len(self.local_monsters) > 0 and self.auto_combat and not self.in_combat: self.combat_start() #Monster took off, remove from list if result.find("has just left") != -1: try: end_index = result.index(' has') mon_str = result[:end_index] mon_str = mon_str.replace(" ","") self.local_monsters.remove(mon_str) except: pass #Monster died, remove from list if result.find("is crumbling to dust") != -1: try: end_index = result.index(' is') mon_str = result[:end_index] mon_str = mon_str.replace(" ","") self.local_monsters.remove(mon_str) except: pass #Someone picked something up, remove from item list if result.find("picked up the") != -1: try: start_index = result.index('the') + 4 item_str = result[start_index:] end_index = item_str.index('.') item_str = item_str[:end_index] item_str = item_str.replace(" ","") self.local_items.remove(item_str) except: pass #Dead person dropping stuff, add to local list if result.find("is falling from") != -1: try: start_index = result.index('A') item_str = result[start_index:] end_index = item_str.index('is') item_str = item_str[:end_index] item_str = item_str.replace(" ","") item_str = item_str.replace("is","") item_str = item_str.replace("An","") item_str = item_str.replace("A","") self.local_items.append(item_str) except: print("Monster item drop error") print(result) #print(self.local_items) #You died, do some stuff if result.find("Select (Bury, 1-5, ?)") != -1: self.mqtt_str.emit(self.user+" has died") self.mqtt_str_quiet.emit(self.user," has died") print("MQTT signal emitted") self.exit_game() #farm items if len(self.local_items) > 0 and not self.in_combat and not self.path_step: farm_zero = True if self.location == [0,0]: farm_zero = False if not self.wander: farm_zero = True if self.auto_farm and farm_zero: self.farm_sell_items() self.farm_stock_items() if self.auto_ion: self.add_convert() self.convert_items() #push("convert") def process_keys(self, key): #keyboard related - this part sucks if key==ord(self.lock_key): if self.key_detect: self.key_detect = False print("Key detect off") else: self.key_detect = True print("Key detect on") if self.key_detect: if key==ord("?"): for help in help_list: print(help) #directions if key==ord("8"): self.local_monsters = [] self.local_items = [] self.send_cmd("north\r\n") if key==ord("2"): self.local_monsters = [] self.local_items = [] self.send_cmd("south\r\n") if key==ord("4"): self.local_monsters = [] self.local_items = [] self.send_cmd("west\r\n") if key==ord("6"): self.local_monsters = [] self.local_items = [] self.send_cmd("east\r\n") #functions if key==ord("a"): if self.auto_combat: self.auto_combat = False print("Auto combat off") else: self.auto_combat = True print("Auto combat on") #Auto Ion if key==ord("i"): if self.auto_ion: self.auto_ion = False print("Auto ion off") else: self.auto_ion = True print("Auto ion on") #Auto farm if key==ord("f"): if self.auto_farm: self.auto_farm = False print("Auto farm off") else: self.auto_farm = True print("Auto farm on") #Year limit if key==ord("y"): self.flush_input() st = input("Year limit: ") self.year_limit_high = int(st) #No action threshhold if key==ord("n"): self.flush_input() st = input("No action: ") self.na_thresh = int(st) #Start combat if key==ord("c"): if len(self.local_monsters) > 0: combat_start() #look around if key==ord("5"): self.send_cmd("look ") #meander status if key==ord("m"): if self.wander: self.wander = False print("Meander off") else: self.wander = True print("Meander on") self.send_cmd("look\r\n") #heal if key==ord("h"): self.send_cmd("heal\r\n") self.heal = True #look around if key==ord("l"): self.send_cmd("look\r\n") #stats if key==ord("v"): self.send_cmd("stat\r\n") #sell items if key==ord("s"): self.sell_items() #store path select if key==ord("p") and not self.in_combat: self.flush_input() st = input("Choose path input: ") self.selected_path = int(st) self.path_step = 1 self.send_cmd("Starting path..\r\n") self.flush_input() if key==ord("K") and not self.in_combat: print("working?") st = input("Keyboard input: ") self.send_cmd(st+"\r\n") self.flush_input() #wield weapon if key==ord("w"): self.send_cmd("wield "+self.weapon+"\r\n") #drop item if key==ord("d"): self.flush_input() #toss = keyboard.read_key() st = input("drop item: ") drop_item = "drop " + st self.send_cmd(drop_item+"\r\n") #time travel if key==ord("t") and not self.in_combat: monster_list = [] self.flush_input() #toss = keyboard.read_key() st = input("year: ") year = "travel " + st self.send_cmd(year+"\r\n") if key==ord("x"): pass #login routine def login_listener(self, result): if result == "Otherwise type \"new\": ": self.command_str.emit(self.user+"\r\n") if result == "Enter your password: ": self.command_str.emit(self.password+"\r\n") if result == "(N)onstop, (Q)uit, or (C)ontinue?": self.command_str.emit("Q") if "(TOP)" in result: self.command_str.emit("G\r\n") self.mqtt_str.emit(self.user+" is online") self.mqtt_str_quiet.emit(self.user,"is online") if "(DOORS)" in result: self.command_str.emit("C\r\n") if result == "Select (P,I,H,S,W,X,?): ": self.command_str.emit("P\r\n") if result == "Select (Bury, 1-5, ?) ": self.command_str.emit(str(self.char_sel)+"\r\n") #self.mutants() self.logged_in = True self.player_init() #doesnt work yet def delete_line(self,line): cursor = self.console.textCursor() cursor.movePosition(QTextCursor.Start + line + 1) cursor.movePosition( QTextCursor.PreviousBlock, QTextCursor.KeepAnchor, 1) cursor.removeSelectedText() self.console.setTextCursor(cursor) #main game loop def execute_loop(self, result): self.console.append(result) self.console_lines = self.console_lines + 1 if self.logged_in == False: self.login_listener(result) else: self.mutants(result) if self.console_lines>5000: self.console.clear() self.console_lines = 0 self.console.moveCursor(QTextCursor.End) class telnet_thread(QObject): received = pyqtSignal(str) disconnected = pyqtSignal() #Init def __init__(self): QWidget.__init__(self) #telnet lib self.tn = telnetlib.Telnet() self.open_telnet() #Open connection def open_telnet(self): try: self.tn.open(HOST,23) print("telnet connected..") except: print("Connection attempt failed..") #Close telnet def close_telnet(self): try: self.tn.close() print("closing telnet...") except: print("Telnet close failed...") #Decode incoming information def decode_line(self,line): result = "" if line.decode('cp1252') != "": ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])') result = ansi_escape.sub('', line.decode('cp1252').strip('\n')) return result #Write to telnet object def tn_write(self,send_str): try: self.tn.write(send_str.encode('ascii')) except: pass #Listen perpetually def telnet_listen(self): print("listening..") while True: #data decode QApplication.processEvents() result = "" line = None try: line = self.tn.read_until(b"\n",0) # Read one line result = self.decode_line(line).strip("\r").strip("\n").strip("\b") if result != "": self.received.emit(result) except: try: print("Reconnectiong...") self.tn.close() self.disconnected.emit() self.open_telnet() except: print("Reconnect failed!") class MainWindow(QMainWindow): keyPressed = pyqtSignal(int) bcast = pyqtSignal(list) def __init__(self): super(MainWindow, self).__init__() widget = QWidget(self) self.layout = QVBoxLayout(widget) self.setCentralWidget(widget) self.setup_mqtt() #Create tabs self.tabs = QTabWidget() self.tab1 = QWidget() self.tab2 = QWidget() self.tab3 = QWidget() self.tab4 = QWidget() self.mutant_list = [] print(player_list) for player in player_list: mutbox = QHBoxLayout() index = player_list.index(player) print(player.usr) print(index) mut = mutant(player,index) self.mutant_list.append(mut) mutbox.addWidget(self.mutant_list[-1]) self.mutant_list[-1].mqtt_str.connect(self.send_mqtt) self.mutant_list[-1].mqtt_str_quiet.connect(self.send_mqtt_quiet) self.mutant_list[-1].tab_color.connect(self.color_tab) self.mutant_list[-1].broadcast.connect(self.broadcast) self.bcast.connect(self.mutant_list[-1].request_received) tab = QWidget() tab.setLayout(mutbox) self.tabs.addTab(tab,player.usr) self.layout.addWidget(self.tabs) self.setLayout(self.layout) #self.layout.addLayout(mutbox) self.button_group() self.createModeGroup() self.show() #Connect signals #self.keyPressed.connect(self.m.process_keys) # Add text input self.formGroupBox = QFormLayout() self.text_input = QLineEdit() self.text_button = QPushButton("Send") self.text_button.clicked.connect(self.send_str) self.formGroupBox.addRow(self.text_button,self.text_input) self.layout.addLayout(self.formGroupBox) def broadcast(self,request): self.bcast.emit(request) def color_tab(self,idx,color): self.tabs.tabBar().setTabTextColor(idx, QColor(color)) #Events like mouse movement and keyboard action that happen on the main form def eventFilter(self, source, event): #print(source) if str(source).find("QWindow") != -1: if event.type() == QEvent.KeyPress: self.keyPressed.emit(event.key()) return QMainWindow.eventFilter(self, source, event) #create buttons def button_group(self): hbox1 = QHBoxLayout() hbox2 = QHBoxLayout() b_grid = QGridLayout() north_button = QPushButton("North") south_button = QPushButton("South") east_button = QPushButton("East") west_button = QPushButton("West") heal_button = QPushButton("Heal") combat_button = QPushButton("Combat") hbox2.addWidget(heal_button) hbox2.addWidget(combat_button) b_grid.addWidget(north_button,0,1) b_grid.addWidget(south_button,2,1) b_grid.addWidget(east_button,1,2) b_grid.addWidget(west_button,1,0) b_grid.addLayout(hbox2,1,1) #b_grid.addWidget(heal_button,2,2) #b_grid.addWidget(combat_button,2,0) hbox1.addItem(QSpacerItem(350, 0, QSizePolicy.Minimum)) hbox1.addLayout(b_grid) hbox1.addItem(QSpacerItem(350, 0, QSizePolicy.Minimum)) north_button.clicked.connect(self.n_btn) south_button.clicked.connect(self.s_btn) east_button.clicked.connect(self.e_btn) west_button.clicked.connect(self.w_btn) heal_button.clicked.connect(self.h_btn) combat_button.clicked.connect(self.c_btn) self.layout.addLayout(hbox1) #buttons def n_btn(self): self.send_all("north\r\n") def s_btn(self): self.send_all("south\r\n") def e_btn(self): self.send_all("east\r\n") def w_btn(self): self.send_all("west\r\n") def h_btn(self): for mut in self.mutant_list: mut.heal=True def c_btn(self): for mut in self.mutant_list: mut.combat_start() #Button send text def send_str(self): self.send_all(self.text_input.text()) def send_all(self,out_str): for mut in self.mutant_list: mut.command_str.emit(out_str+"\r\n") #Creates the form groupbox def createModeGroup(self): self.mode_layout = QVBoxLayout() hbox1 = QHBoxLayout() hbox2 = QHBoxLayout() self.mq_check = QCheckBox("MQTT") self.mq_check.setChecked(True) hbox1.addWidget(self.mq_check) self.layout.addLayout(hbox1) def setup_mqtt(self): try: if MQTT_ENABLED: broker_address="192.168.86.27" #print("creating new instance") self.client = mqtt.Client("P1") #create new instance self.client.username_pw_set("homeassistant", "oes5gohng9gau1Quei2ohpixashi4Thidoon1shohGai2mae0ru2zaph2vooshai") self.client.connect(broker_address) except: pass #Send mqtt with talking def send_mqtt(self,out_str): if MQTT_ENABLED: self.setup_mqtt() if self.mq_check.isChecked(): self.client.publish("mutants/talk", out_str) #Send mqtt with talking def send_mqtt_quiet(self,user,out_str): if MQTT_ENABLED: self.setup_mqtt() if self.mq_check.isChecked(): self.client.publish("mutants/stat/"+user, out_str) if __name__ == "__main__": App = QApplication(sys.argv) QApplication.setQuitOnLastWindowClosed(True) Root = MainWindow() Root.show() App.installEventFilter(Root) sys.exit(App.exec())