Advertisement
egor230

voice control in the game

Apr 20th, 2022
616
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 18.23 KB | None
  1. from tkinter import *
  2. from tkinter.ttk import Combobox  # импортируем только то что надо
  3. from tkinter import messagebox
  4. import json, os, time, copy
  5. from selenium import webdriver
  6. from selenium.webdriver.common.keys import Keys
  7. from selenium.webdriver.chrome.options import Options
  8. from selenium.webdriver.chrome.service import Service
  9. from threading import *
  10. import pydirectinput as pyinput
  11.  
  12.  
  13. KEYS = {"LBUTTON": 0x01, "RBUTTON": 0x02, "CANCEL": 0x03, "MBUTTON": 0x04, "XBUTTON1": 0x05,
  14.               "XBUTTON2": 0x06, "BACK": 0x08, "TAB": 0x09, "CLEAR": 0x0C, "RETURN": 0x0D,
  15.               "SHIFT": 0x10, "CONTROL": 0x11, "MENU": 0x12, "PAUSE": 0x13, "CAPITAL": 0x14,
  16.               "KANA": 0x15, "JUNJA": 0x17, "FINAL": 0x18, "KANJI": 0x19, "ESCAPE": 0x1B,
  17.               "CONVERT": 0x1C, "NONCONVERT": 0x1D, "ACCEPT": 0x1E, "MODECHANGE": 0x1F, "SPACE": 0x20,
  18.               "PRIOR": 0x21, "NEXT": 0x22, "END": 0x23, "HOME": 0x24, "LEFT": 0x25, "UP": 0x26,
  19.               "RIGHT": 0x27, "DOWN": 0x28, "SELECT": 0x29, "PRINT": 0x2A, "EXECUTE": 0x2B,
  20.               "SNAPSHOT": 0x2C, "INSERT": 0x2D, "DELETE": 0x2E, "HELP": 0x2F, "KEY0": 0x30,
  21.               "KEY1": 0x31, "KEY2": 0x32, "key3": 0x33, "key4": 0x34, "key5": 0x35, "key6": 0x36,
  22.               "key7": 0x37, "key8": 0x38, "key9": 0x39, "A": 0x41, "B": 0x42, "C": 0x43, "D": 0x44,
  23.               "E": 0x45, "F": 0x46, "G": 0x47, "H": 0x48, "I": 0x49,
  24.               "J": 0x4A, "K": 0x4B, "L": 0x4C, "M": 0x4D, "N": 0x4E, "O": 0x4F, "P": 0x50, "Q": 0x51, "R": 0x52,
  25.               "S": 0x53, "T": 0x54, "U": 0x55, "V": 0x56, "W": 0x57, "X": 0x58, "Y": 0x59,
  26.               "Z": 0x5A, "LWIN": 0x5B, "RWIN": 0x5C, "APPS": 0x5D, "SLEEP": 0x5F, "NUMPAD0": 0x60, "NUMPAD1": 0x61,
  27.               "NUMPAD2": 0x62, "NUMPAD3": 0x63, "NUMPAD4": 0x64, "NUMPAD5": 0x65,
  28.               "NUMPAD6": 0x66, "NUMPAD7": 0x67, "NUMPAD8": 0x68, "NUMPAD9": 0x69, "MULTIPLY": 0x6A, "ADD": 0x6B,
  29.               "SEPARATOR": 0x6C, "SUBTRACT": 0x6D, "DECIMAL": 0x6E, "DIVIDE": 0x6F, "F1": 0x70, "F2": 0x71,
  30.               "F3": 0x72, "F4": 0x73, "F5": 0x74, "F6": 0x75, "F7": 0x76, "F8": 0x77, "F9": 0x78, "F10": 0x79,
  31.               "F11": 0x7A, "F12": 0x7B, "F13": 0x7C, "F14": 0x7D,
  32.               "F15": 0x7E, "F16": 0x7F, "F17": 0x80, "F18": 0x81, "F19": 0x82, "F20": 0x83, "F21": 0x84,
  33.               "F22": 0x85, "F23": 0x86, "F24": 0x87, "NUMLOCK": 0x90, "SCROLL": 0x91, "OEM_FJ_JISHO": 0x92, "OEM_FJ_MASSHOU": 0x93,
  34.               "OEM_FJ_TOUROKU": 0x94, "OEM_FJ_LOYA": 0x95, "OEM_FJ_ROYA": 0x96, "LSHIFT": 0xA0, "RSHIFT": 0xA1, "LCONTROL": 0xA2, "RCONTROL": 0xA3, "LMENU": 0xA4, "RMENU": 0xA5, "BROWSER_BACK": 0xA6,
  35.               "BROWSER_FORWARD": 0xA7, "BROWSER_REFRESH": 0xA8, "BROWSER_STOP": 0xA9, "BROWSER_SEARCH": 0xAA, "BROWSER_FAVORITES": 0xAB, "BROWSER_HOME": 0xAC, "VOLUME_MUTE": 0xAD, "VOLUME_DOWN": 0xAE,
  36.               "VOLUME_UP": 0xAF, "MEDIA_NEXT_TRACK": 0xB0, "MEDIA_PREV_TRACK": 0xB1, "MEDIA_STOP": 0xB2, "MEDIA_PLAY_PAUSE": 0xB3, "LAUNCH_MAIL": 0xB4, "LAUNCH_MEDIA_SELECT": 0xB5, "LAUNCH_APP1": 0xB6,
  37.               "LAUNCH_APP2": 0xB7, "OEM_1": 0xBA, "OEM_PLUS": 0xBB, "OEM_COMMA": 0xBC, "OEM_MINUS": 0xBD, "OEM_PERIOD": 0xBE, " OEM_2": 0xBF, "OEM_3": 0xC0, "ABNT_C1": 0xC1, "ABNT_C2": 0xC2, "OEM_4": 0xDB, "OEM_5": 0xDC, "OEM_6": 0xDD, "OEM_7": 0xDE, "OEM_8": 0xDF, "OEM_AX": 0xE1,
  38.               "OEM_102": 0xE2, "ICO_HELP": 0xE3, "PROCESSKEY": 0xE5, "ICO_CLEAR": 0xE6, "PACKET": 0xE7, "OEM_RESET": 0xE9, "OEM_JUMP": 0xEA, "OEM_PA1": 0xEB, "OEM_PA2": 0xEC, "OEM_PA3": 0xED,
  39.               "OEM_WSCTRL": 0xEE, "OEM_CUSEL": 0xEF, "OEM_ATTN": 0xF0, "OEM_FINISH": 0xF1, "OEM_COPY": 0xF2, "OEM_AUTO": 0xF3, "OEM_ENLW": 0xF4, "OEM_BACKTAB": 0xF5, "ATTN": 0xF6, "CRSEL": 0xF7, "EXSEL": 0xF8, " EREOF": 0xF9, "PLAY": 0xFA, "ZOOM": 0xFB, "PA1": 0xFD, " OEM_CLEAR": 0xFE
  40.               }
  41.  
  42. def check(driver):
  43.   url = driver.current_url
  44.   driver.implicitly_wait(3)
  45.   try:
  46.     return 0
  47.   except Exception as ex:
  48.     check(driver)
  49. def prease_on_key(driver, key, *words):
  50.  word1=str(words[0])
  51.  words=word1.rsplit(",")
  52.  words=list(words)
  53.  while 1:
  54.      try:
  55.       time.sleep(0.75)
  56.       driver.find_element_by_xpath('//*[@class="p_edit dir_LTR"]').clear()  # удалить старый текст.
  57.       text= driver.find_element_by_xpath('//*[@id="speech-display"]').text
  58.       if len(text) != 0 and text != None:
  59.         text = str(text).lower()
  60.         for word1 in words:
  61.            word= str(word1).lower()
  62.  
  63.            if word == text:
  64.               key1=key.upper()
  65.               key2=KEYS[key1]
  66.               driver.find_element_by_xpath('//*[@id="bottom-navbar"]//*[@id="mic"]').click()
  67.               pyinput.keyDown(str(key1).replace("KEY","").lower())
  68.               time.sleep(0.75)
  69.               pyinput.keyUp(str(key1).replace("KEY","").lower())
  70.               driver.find_element_by_xpath('//*[@id="bottom-navbar"]//*[@id="mic"]').click()
  71.               break
  72.      except Exception as ex:
  73.        print(ex)
  74.        pass
  75. def prease_on_key1(driver, key, *word):
  76.   t1 = Thread(target = prease_on_key, args =(driver, key, *word))
  77.   t1.start()
  78.  
  79.  
  80. def web():
  81.     os.system("taskkill /f /im  chromedriver.exe")
  82.     options = Options()
  83.     home =r"C:\Program Files (x86)\Google\Chrome"
  84.     options.add_argument("--use-fake-ui-for-media-stream")# звук
  85.     options.add_experimental_option("excludeSwitches", ['enable-automation']) # убрать окно
  86.     options.binary_location = home +r"\Application\chrome.exe"
  87.     options.add_argument(r"--user-data-dir=C:\Users\egor\AppData\Local\Google\Chrome\User Data")
  88.     try:
  89.       s = Service(home + r'\chromedriver\chromedriver.exe')
  90.       driver = webdriver.Chrome(service=s, options=options)
  91.       driver.set_window_position(600, 650)
  92.       driver.set_window_size(624, 368) # optiol
  93.       driver.get("https://www.speechtexter.com")# открыть сайт
  94.       check(driver)
  95.       driver.minimize_window()
  96.       driver.find_element_by_xpath('//*[@id="bottom-navbar"]//*[@class="wave" and @id="mic"]').click()# включить запись голоса
  97.  
  98.       options.add_argument("--disable-extensions")  # отключить расширения.
  99.       return driver
  100.  
  101.     except Exception as ex:
  102.        pass
  103.     finally:
  104.        pass
  105. # добавление нового элемента
  106. list_profiles = ["default"]  # список профилей.
  107.  
  108. def start_voice():
  109.   driver = web()
  110.   for i in range(len(arg)):
  111.     value=(str(arg[i].get()))
  112.     key= str(values[i].get())
  113.     try:
  114.         if key=="":
  115.             messagebox.showerror("Erorr","key emrty")
  116.             os.system("taskkill /f /im  chromedriver.exe")
  117.             break
  118.             return
  119.         if value == "":
  120.            messagebox.showerror("Erorr", "Value emrty")
  121.            os.system("taskkill /f /im  chromedriver.exe")
  122.            break
  123.            return
  124.  
  125.         prease_on_key1(driver, key, value)
  126.  
  127.     except Exception as ex:
  128.             pass
  129.  
  130. class save_dict:
  131.     def __init__(self):
  132.         self.jnson = {}
  133.         self.old_data = {}
  134.  
  135.     def save_old_data(self, jnson):
  136.       self.old_data= copy.deepcopy(jnson)
  137.  
  138.     def save_jnson(self, jn):
  139.        self.jnson= jn
  140.  
  141.     def return_jnson(self):
  142.        return self.jnson
  143.  
  144.     def return_old_data(self):
  145.        return self.old_data
  146.  
  147.     def write_to_file(self, new_data):
  148.      json_string = json.dumps(new_data, ensure_ascii=False, indent=2)
  149.      with open("settings.json", "w", encoding="cp1251") as w:
  150.        w.write(json_string)  # сохранить изменения в файле настроек.
  151.      return self
  152.  
  153. def save_keys_and_values(event=0):
  154.  d,d1={},{}
  155.  d=dict_save.return_jnson()# старый словарь.
  156.  d["last_pfofile"]=str(profile_current.get())
  157.  d1=d["profiles"]
  158.  d=d1[str(profile_current.get())]
  159.  for i in range(len(arg)):
  160.         key = str(arg[i].get())
  161.         value = str(values[i].get())
  162.         d[key]=value# обновления словаря.
  163.  d1[str(profile_current.get())]=d
  164. def on_close():
  165.     os.system("taskkill /f /im  chromedriver.exe")
  166.     save_keys_and_values()
  167.  
  168.     old_data =dict_save.return_old_data()# старые значения настроек.
  169.     new_data= dict_save.return_jnson() # новые значения настроек.
  170.  
  171.     if new_data != old_data:
  172.       if old_data['profiles'] != new_data['profiles']:
  173.        if (messagebox.askokcancel("Quit", "Do you want to save the changes?")):
  174.           dict_save.write_to_file(new_data)# записать настройки в файл.
  175.        else:
  176.          pass
  177.       else:
  178.           dict_save.write_to_file(new_data) # записать настройки в файл.
  179.     root.destroy()
  180.  
  181. # удаления записи и значения.
  182. def remove_box_and_entry(ent_arr, box_arr):
  183.  if len(values)>0:
  184.     r = len(arg)
  185.     values[r-1].set("")
  186.     arg[r-1].set("")
  187.     ent_arr[r-1].destroy()
  188.     box_arr[r-1].destroy()
  189.     ent_arr.pop()
  190.     box_arr.pop()
  191.     values.pop()
  192.     arg.pop()
  193.     return ent_arr, box_arr
  194.  else:
  195.     return ent_arr, box_arr
  196.  
  197. class iter_counter:
  198.   def __init__(self):
  199.      self._value = -1
  200.      self.box_arr = []
  201.      self.ent_arr = []
  202.   def add_new_command(self, scrollable_frame, entry_value=0, box_value=0):
  203.         self._value += 1
  204.         value= self._value  # print(value)
  205.         a = list(KEYS.keys()), arg.append(StringVar()), values.append(StringVar())
  206.         entry = Entry(scrollable_frame, width=25,textvariable=arg[value])  # текстовое поле и кнопка для добавления в список
  207.         entry.grid(column=0, row=value+1, padx=10, pady=8, sticky=W)
  208.         box = Combobox(scrollable_frame, width=12, textvariable=values[value], values=a[0])
  209.         box.grid(column=1, row=value+1, padx=22, pady=0)  # поле со списком
  210.         key=str(profile_current.get())
  211.         if entry_value != 0 and box_value != 0:
  212.             arg[value].set(entry_value)
  213.             values[value].set(box_value)
  214.         else:
  215.             arg[value].set("")
  216.             values[value].set("")
  217.         return self.ent_arr.append(entry), self.box_arr.append(box),self._value,
  218.   def del_command(self):
  219.        value = self._value
  220.        ent_arr, box_arr= self.box_arr, self.ent_arr
  221.        ent_arr, box_arr=remove_box_and_entry(ent_arr, box_arr)
  222.  
  223.        self._value -= 1
  224.        return self._value, self.box_arr, self.ent_arr
  225.   def remove_all_command(self, scrollable_frame):
  226.        self._value=-1
  227.        ent_arr, box_arr, value = self.box_arr, self.ent_arr, self._value
  228.        for i in range(len(box_arr)):
  229.         ent_arr, box_arr = remove_box_and_entry(ent_arr, box_arr)
  230.        new.add_new_command(scrollable_frame)
  231.        return self._value, self.box_arr, self.ent_arr
  232.   def remove_all_command_without_adding(self):
  233.        value = self._value
  234.        ent_arr, box_arr= self.box_arr, self.ent_arr
  235.        for i in range(len(box_arr)):
  236.         ent_arr, box_arr = remove_box_and_entry(ent_arr, box_arr)
  237.        self._value=-1
  238.        return self._value, self.box_arr, self.ent_arr
  239.  
  240. def filling_fields(dict_save, last_pfofile):
  241.     d=dict_save.return_jnson()# получить словарь со всеми значениями.
  242.     d=d["profiles"]
  243.     for k, v in d.items():
  244.        if k not in list_profiles:
  245.          list_profiles.append(k)
  246.        if k== last_pfofile:
  247.         for k1, v1 in v.items():
  248.          v1=v[k1]
  249.          new.add_new_command(scrollable_frame,k1,v1)
  250.  
  251. def update(event):
  252.     new.remove_all_command_without_adding()
  253.     filling_fields(dict_save, profile_current.get())
  254.  
  255. def create_box():
  256.     box = Combobox(root, width=12, textvariable=profile_current, values=list_profiles, state='readonly')
  257.     box.grid(column=1, row=0, padx=3, pady=0)  # поле со списком.
  258.     box.bind('<Button-1>', save_keys_and_values)  # при нажатии на выпадающий список.
  259.     box.bind('<<ComboboxSelected>>', update)# при изменения профиля.
  260.     return box
  261. def add1(root,window, new, scrollable_frame):
  262.     value= new_profile.get()
  263.     if value != '':
  264.      list_profiles.append(str(value))
  265.      box = Combobox(root, width=12, textvariable=profile_current, values=list_profiles, state='readonly')
  266.      box.bind('<<ComboboxSelected>>', update)
  267.      box.grid(column=1, row=0, padx=3, pady=0)  # поле со списком
  268.      add_button = Button(text="Добавить профиль", command= lambda:add_new_profile(root, box)).grid(column=2, row=0, padx=10, pady=6)
  269.      box.current(len(list_profiles)-1)
  270.  
  271.      window.destroy()
  272.      new_profile.set('')
  273.      new.remove_all_command(scrollable_frame)
  274.  
  275. def add_new_profile(root,box,new,scrollable_frame):
  276.     window = Toplevel(root)# основа
  277.     window.title("add new profile")  # заголовок
  278.     window.geometry("500x150+750+400")  # Первые 2 определяют ширину высоту. Пос 2 x и y координаты на экране.
  279.     window.configure(bg='DimGray')  # Цвет фона окна
  280.  
  281.     e=Entry(window, width=30, textvariable=new_profile) #строка ввода профиля.
  282.     e.grid(column=2, row=0, padx=50, pady=5)
  283.     e.focus_set()
  284.     Button(window, text="Добавить профиль", command= lambda:add1(root,window,new,scrollable_frame))\
  285.         .grid(column=2, row=1, padx=50, pady=30) # кнопка добавить профиль, откроется новое окно.
  286. def del_profile_box(root, window, box, profile_for_del):
  287.   profile =profile_for_del.get()
  288.   if profile=="":
  289.    messagebox.showerror("Erorr", "profile not selected")
  290.   if profile=="default":
  291.    messagebox.showerror("Erorr", "this profile cannot be deleted")
  292.   else:
  293.       last_pfofile = list_profiles.index(profile)-1
  294.       list_profiles.remove(profile)
  295.       res= dict_save.return_jnson()['profiles']
  296.       del res[profile]
  297.  
  298.       box = Combobox(root, width=12, textvariable=profile_current, values=list_profiles, state='readonly')
  299.       box.current(last_pfofile)
  300.       box.bind('<<ComboboxSelected>>', update)
  301.       box.grid(column=1, row=0, padx=3, pady=0)  # поле со списком
  302.       add_button = Button(text="Добавить профиль", command=lambda: add_new_profile(root, box)).grid(column=2, row=0, padx=10, pady=6)
  303.  
  304.       new.remove_all_command(scrollable_frame)
  305.       box = create_box()  # Создания выпадающего списка.
  306.       box.current(last_pfofile)
  307.       new.remove_all_command_without_adding()
  308.       filling_fields(dict_save, list_profiles[last_pfofile])  # запол полей
  309.   window.destroy()
  310.  
  311. def del_profile(root,box):
  312.     window = Toplevel(root)# основа
  313.     window.title("Delete profile")  # заголовок
  314.     window.geometry("500x150+750+400")  # Первые 2 определяют ширину высоту. Пос 2 x и y координаты на экране.
  315.     window.configure(bg='DimGray')  # Цвет фона окна
  316.     profile_for_del = StringVar()
  317.     box1 = Combobox(window, width=30, textvariable=profile_for_del, values=list_profiles, state='readonly') # box с профилями.
  318.     box1.grid(column=2, row=1, padx=50, pady=5)
  319.     Button(window, text="Удалить профиль", command= lambda:del_profile_box(root, window, box, profile_for_del))\
  320.         .grid(column=2, row=2, padx=50, pady=30) # кнопка добавить профиль, откроется новое окно.
  321.  
  322. def start(new, scrollable_frame,box):
  323.   data ="settings.json"  # файл настроек.
  324.   if os.path.exists(data):  # есть ли этот файл.
  325.       with open(data) as json_file:
  326.         res= json.load(json_file)
  327.       dict_save.save_jnson(res)# соранить начальные настройки.
  328.       dict_save.save_old_data(res)
  329.       last_pfofile = res["last_pfofile"] # последний исполь профиль.
  330.       for name in res["profiles"]:
  331.        if not name in list_profiles:
  332.           list_profiles.append(name)
  333.       # input()
  334.       box =create_box() # Создания выпадающего списка.
  335.       box.current(list_profiles.index(last_pfofile))
  336.       filling_fields(dict_save, last_pfofile)# запол полей
  337.  
  338.   else:
  339.      box.current(0)
  340.      new.add_new_command(scrollable_frame)
  341.  
  342. dict_save=save_dict()
  343. root = Tk()
  344. root.geometry("580x250+650+400")
  345. root.title("voice control in the game")
  346. profile_current, new_profile=StringVar(),StringVar()
  347.  
  348. lb = Label(root, text="Голосовое управления в играх",width=25).grid(column=0, row=0)  # текстовое поле и кнопка для добавления в список
  349.  
  350. arg, values = [], []# списки для слов и значений.
  351.  
  352. container = Frame(root)
  353. canvas = Canvas(container,width=320, height=200)
  354. scrollbar = Scrollbar(container, orient="vertical", command=canvas.yview)
  355. scrollable_frame = Frame(canvas)
  356. scrollable_frame.bind( "<Configure>",
  357.     lambda e: canvas.configure( scrollregion=canvas.bbox("all")
  358.     ))
  359. canvas.create_window((0, 0), window=scrollable_frame, anchor="n")
  360. canvas.configure(yscrollcommand=scrollbar.set)
  361. container.grid()
  362. canvas.grid(sticky=N+S)
  363. scrollbar.grid(column=0, row=0,sticky=N+S+E)# полоса прокрутки.
  364.  
  365. box = create_box() # Создания выпадающего списка.
  366.  
  367. new=iter_counter()# объект класса.
  368. start(new, scrollable_frame,box)# запуск всего.
  369.  
  370. add_button = Button(text="Добавить профиль", command= lambda:add_new_profile(root, box, new,scrollable_frame))\
  371.     .grid(column=2, row=0, padx=10, pady=6,sticky=NE)
  372.  
  373. add_button = Button(text="Удалить профиль", command= lambda:del_profile(root, box))\
  374.     .grid(column=2, row=1, padx=10, pady=16,sticky=N)
  375.  
  376. add_key_button = Button(text="Добавить команду", command= lambda:new.add_new_command(scrollable_frame))\
  377.     .grid(column=1, row=1, padx=1, pady=30,sticky=N)
  378.  
  379. del_key_button_1 = Button(text="Удалить команду", command= lambda:new.del_command())\
  380.     .grid(column=1, row=1,padx=1,pady=90,sticky=N)
  381.  
  382. go_button_2 = Button(text="  Старт  ", command= lambda:start_voice())\
  383.     .grid(column=2, row=1,padx=0,pady=10,sticky=SE)# Запуск управления.
  384. root.protocol("WM_DELETE_WINDOW", on_close)
  385.  
  386. box.grid(column=1, row=0, padx=3, pady=0)  # поле со списком
  387. root.mainloop()
  388.  
  389.  
Advertisement
RAW Paste Data Copied
Advertisement