diff --git a/Nursery.png b/Nursery.png new file mode 100644 index 0000000..50a1566 Binary files /dev/null and b/Nursery.png differ diff --git a/Repel.png b/Repel.png new file mode 100644 index 0000000..23d9b4a Binary files /dev/null and b/Repel.png differ diff --git a/config.json b/config.json deleted file mode 100644 index d02640f..0000000 --- a/config.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "MonitorWindow": true, - "WindowPrefix": "SysDVR-Client [PID ", - "image": "./munchlax/eye.png", - "view": [470, 430, 50, 60], - "reidentify": "" -} \ No newline at end of file diff --git a/config_cave.json b/config_cave.json deleted file mode 100644 index 9dcee9a..0000000 --- a/config_cave.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "MonitorWindow": true, - "WindowPrefix": "SysDVR-Client [PID ", - "image": "./trainer/cave/eye.png", - "view": [610, 330, 30, 30], - "reidentify": "0x37a35d28 0x488e6831 0xb7f56519 0x79a3b387" -} \ No newline at end of file diff --git a/config_munchlax.json b/config_munchlax.json deleted file mode 100644 index d02640f..0000000 --- a/config_munchlax.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "MonitorWindow": true, - "WindowPrefix": "SysDVR-Client [PID ", - "image": "./munchlax/eye.png", - "view": [470, 430, 50, 60], - "reidentify": "" -} \ No newline at end of file diff --git a/config_wild.json b/configs/config_cave.json similarity index 63% rename from config_wild.json rename to configs/config_cave.json index c5d6d81..9ac1f5e 100644 --- a/config_wild.json +++ b/configs/config_cave.json @@ -1,7 +1,7 @@ { "MonitorWindow": true, "WindowPrefix": "SysDVR-Client [PID ", - "image": "./trainer/ruins/eye.png", + "image": "./images/cave/eye.png", "view": [610, 330, 30, 30], - "reidentify": "" + "thresh": 0.9 } \ No newline at end of file diff --git a/configs/config_munchlax.json b/configs/config_munchlax.json new file mode 100644 index 0000000..2e170ce --- /dev/null +++ b/configs/config_munchlax.json @@ -0,0 +1,12 @@ +{ + "MonitorWindow": true, + "WindowPrefix": "SysDVR-Client [PID ", + "image": "./images/munchlax/eye.png", + "view": [ + 470, + 430, + 50, + 60 + ], + "thresh": 0.9 +} \ No newline at end of file diff --git a/configs/config_room.json b/configs/config_room.json new file mode 100644 index 0000000..d33fd00 --- /dev/null +++ b/configs/config_room.json @@ -0,0 +1,12 @@ +{ + "MonitorWindow": true, + "WindowPrefix": "SysDVR-Client [PID ", + "image": "images\\home\\eye.png", + "view": [ + 610, + 347, + 30, + 30 + ], + "thresh": 0.9 +} \ No newline at end of file diff --git a/configs/config_spear_pillar.json b/configs/config_spear_pillar.json new file mode 100644 index 0000000..4d35494 --- /dev/null +++ b/configs/config_spear_pillar.json @@ -0,0 +1,7 @@ +{ + "MonitorWindow": true, + "WindowPrefix": "SysDVR-Client [PID ", + "image": "./images/spear_pillar/eye.png", + "view": [625, 338, 17, 19], + "thresh": 0.75 +} \ No newline at end of file diff --git a/config_unown.json b/configs/config_unown.json similarity index 63% rename from config_unown.json rename to configs/config_unown.json index c5d6d81..f7a4442 100644 --- a/config_unown.json +++ b/configs/config_unown.json @@ -1,7 +1,7 @@ { "MonitorWindow": true, "WindowPrefix": "SysDVR-Client [PID ", - "image": "./trainer/ruins/eye.png", + "image": "./images/ruins/eye.png", "view": [610, 330, 30, 30], - "reidentify": "" + "thresh": 0.9 } \ No newline at end of file diff --git a/egg.md b/egg.md new file mode 100644 index 0000000..b2ba61e --- /dev/null +++ b/egg.md @@ -0,0 +1,28 @@ +## Preface +- Set up Project_Xs +- Make sure you know how to find your state with blinks either manually or via screen capture +- You must have masuda method and/or shiny charm to rng for shininess +- Include gender ratio in pokefinder or you will not get correct results + +## Steps +1. Set up pokefinder according to your parents information and your filters +2. Remove at least one parent from nursery/have your two parents ready to enter the nursery +3. Stand 1 tile away from being able to talk to the nursery lady (as seen below) +![](./Nursery.png) +4. Use a super repel +5. Take 21 total steps going up one square then down one square + - You should end directly in front of the nursery lady +6. Deposit parents into daycare +7. Fly to your house and enter your room +8. Take steps in your room until the repel text comes up + - Make sure that you are facing down when the repel expires + - If you are not facing down, then turn to face down and activate the "Theres a time and place for everything but not now" text box by using a key item +![](./Repel.png) +9. If the repel text is open then hover over "No" +10. Find your current state/advances with blinks +11. Find a target in pokefinder +12. As you approach your target advance, hold the down arrow +13. When you reach the target, hold A to close the text box and take a step +14. Head back to the daycare to collect your egg! + - If there is no egg/the egg is not shiny, make sure that your parents info is correct in pokefinder and if so then find the advance you actually hit + - If the advance you hit was near your target, account for the delay for your next attempt \ No newline at end of file diff --git a/trainer/cave/eye.png b/images/cave/eye.png similarity index 100% rename from trainer/cave/eye.png rename to images/cave/eye.png diff --git a/images/home/eye.png b/images/home/eye.png new file mode 100644 index 0000000..08f065f Binary files /dev/null and b/images/home/eye.png differ diff --git a/munchlax/eye.png b/images/munchlax/eye.png similarity index 100% rename from munchlax/eye.png rename to images/munchlax/eye.png diff --git a/trainer/ruins/eye.png b/images/ruins/eye.png similarity index 100% rename from trainer/ruins/eye.png rename to images/ruins/eye.png diff --git a/trainer/secretbase/eye.png b/images/secretbase/eye.png similarity index 100% rename from trainer/secretbase/eye.png rename to images/secretbase/eye.png diff --git a/images/spear_pillar/eye.png b/images/spear_pillar/eye.png new file mode 100644 index 0000000..f526d1f Binary files /dev/null and b/images/spear_pillar/eye.png differ diff --git a/trainer/underground/central/eye.png b/images/underground/central/eye.png similarity index 100% rename from trainer/underground/central/eye.png rename to images/underground/central/eye.png diff --git a/trainer/underground/north/eye.png b/images/underground/north/eye.png similarity index 100% rename from trainer/underground/north/eye.png rename to images/underground/north/eye.png diff --git a/src/player_blink_gui.py b/src/player_blink_gui.py new file mode 100644 index 0000000..164db59 --- /dev/null +++ b/src/player_blink_gui.py @@ -0,0 +1,338 @@ +import json +import signal +import sys +import time +import tkinter as tk +import tkinter.filedialog as fd +import threading +from tkinter import ttk +from os import listdir +from os.path import isfile, join +import rngtool +import cv2 +import time +import json +import os.path +from PIL import Image, ImageTk +from xorshift import Xorshift + +class Application(tk.Frame): + def __init__(self, master=None): + super().__init__(master) + self.master = master + self.previewing = False + self.monitoring = False + self.reidentifying = False + self.config_json = {} + self.default_config = { + "MonitorWindow": True, + "WindowPrefix": "SysDVR-Client [PID ", + "image": "./images/cave/eye.png", + "view": [0, 0, 0, 0], + "thresh": 0.9 + } + self.pack() + self.create_widgets() + signal.signal(signal.SIGINT, self.signal_handler) + + def update_configs(self,event=None): + self.config_jsons = [f for f in listdir("configs") if isfile(join("configs", f))] + self.config_combobox['values'] = self.config_jsons + + def create_widgets(self): + self.master.title("Player Blink") + + self.progress = ttk.Label(self,text="0/0") + self.progress.grid(column=0,row=0) + + self.config_combobox = ttk.Combobox(self, state="readonly", values=[]) + self.config_combobox.grid(column=1,row=0) + self.config_combobox.bind("<>", self.config_combobox_onchange) + self.config_combobox.bind("", self.update_configs) + self.update_configs() + + self.new_config_button = ttk.Button(self,text="+",command=self.new_config,width=2) + self.new_config_button.grid(column=2,row=0) + + self.eye_display = ttk.Label(self) + self.eye_display.grid(column=1,row=1) + self.monitor_display_buffer = ttk.Label(self) + self.monitor_display_buffer.grid(column=1,row=2,rowspan=64) + self.monitor_display = ttk.Label(self) + self.monitor_display.grid(column=1,row=2,rowspan=64) + + self.monitor_blink_button = ttk.Button(self, text="Monitor Blinks", command=self.monitor_blinks) + self.monitor_blink_button.grid(column=3,row=0) + + self.reidentify_button = ttk.Button(self, text="Reidentify", command=self.reidentify) + self.reidentify_button.grid(column=4,row=0,columnspan=2) + + self.preview_button = ttk.Button(self, text="Preview", command=self.preview) + self.preview_button.grid(column=6,row=0) + + self.stop_tracking_button = ttk.Button(self, text="Stop Tracking", command=self.stop_tracking) + self.stop_tracking_button.grid(column=7,row=0) + + x = y = w = h = 0 + th = 0.9 + + ttk.Label(self,text="X").grid(column=4,row=1) + ttk.Label(self,text="Y").grid(column=4,row=2) + ttk.Label(self,text="W").grid(column=4,row=3) + ttk.Label(self,text="H").grid(column=4,row=4) + ttk.Label(self,text="Th").grid(column=4,row=5) + + self.pos_x = tk.Spinbox(self, from_= 0, to = 99999, width = 5) + self.pos_x.grid(column=5,row=1) + self.pos_y = tk.Spinbox(self, from_= 0, to = 99999, width = 5) + self.pos_y.grid(column=5,row=2) + self.pos_w = tk.Spinbox(self, from_= 0, to = 99999, width = 5) + self.pos_w.grid(column=5,row=3) + self.pos_h = tk.Spinbox(self, from_= 0, to = 99999, width = 5) + self.pos_h.grid(column=5,row=4) + self.pos_th = tk.Spinbox(self, from_= 0, to = 1, width = 5, increment=0.1) + self.pos_th.grid(column=5,row=5) + + self.save_button = ttk.Button(self, text="Select Eye",command=self.new_eye) + self.save_button.grid(column=4,row=6,columnspan=2) + + self.new_eye_button = ttk.Button(self, text="Save Config",command=self.save_config) + self.new_eye_button.grid(column=4,row=7,columnspan=2) + + self.s0_1_2_3 = tk.Text(self, width=10, height=4) + self.s0_1_2_3.grid(column=0,row=2,rowspan=4) + + self.s01_23 = tk.Text(self, width=20, height=2) + self.s01_23.grid(column=0,row=6,rowspan=4) + + self.advances = 0 + self.adv = ttk.Label(self,text=self.advances) + self.adv.grid(column=0,row=10) + + self.pos_x.delete(0, tk.END) + self.pos_x.insert(0, x) + self.pos_y.delete(0, tk.END) + self.pos_y.insert(0, y) + self.pos_w.delete(0, tk.END) + self.pos_w.insert(0, w) + self.pos_h.delete(0, tk.END) + self.pos_h.insert(0, h) + self.pos_th.delete(0, tk.END) + self.pos_th.insert(0, th) + + self.after_task() + + def new_config(self): + with fd.asksaveasfile(initialdir="./configs/", filetypes=[("JSON", ".json")]) as f: + json.dump(self.default_config,f,indent=4) + self.config_combobox.set(os.path.basename(f.name)) + self.config_combobox_onchange() + + def new_eye(self): + self.config_json["image"] = os.path.relpath(fd.askopenfilename(initialdir="./images/", filetypes=[("Image", ".png")])) + self.player_eye = cv2.imread(self.config_json["image"], cv2.IMREAD_GRAYSCALE) + self.player_eye_tk = self.cv_image_to_tk(self.player_eye) + self.eye_display['image'] = self.player_eye_tk + + def save_config(self): + json.dump(self.config_json,open(join("configs",self.config_combobox.get()),"w"),indent=4) + + def cv_image_to_tk(self, image): + split = cv2.split(image) + if len(split) == 3: + b,g,r = split + image = cv2.merge((r,g,b)) + im = Image.fromarray(image) + return ImageTk.PhotoImage(image=im) + + def config_combobox_onchange(self, event=None): + self.config_json = json.load(open(join("configs",self.config_combobox.get()))) + x,y,w,h = self.config_json["view"] + self.pos_x.delete(0, tk.END) + self.pos_x.insert(0, x) + self.pos_y.delete(0, tk.END) + self.pos_y.insert(0, y) + self.pos_w.delete(0, tk.END) + self.pos_w.insert(0, w) + self.pos_h.delete(0, tk.END) + self.pos_h.insert(0, h) + self.pos_th.delete(0, tk.END) + self.pos_th.insert(0, self.config_json["thresh"]) + self.player_eye = cv2.imread(self.config_json["image"], cv2.IMREAD_GRAYSCALE) + self.player_eye_tk = self.cv_image_to_tk(self.player_eye) + self.eye_display['image'] = self.player_eye_tk + + def stop_tracking(self): + self.tracking = False + + def monitor_blinks(self): + if not self.monitoring: + self.monitor_blink_button['text'] = "Stop Monitoring" + self.monitoring = True + self.monitoring_thread=threading.Thread(target=self.monitoring_work) + self.monitoring_thread.daemon = True + self.monitoring_thread.start() + else: + self.monitor_blink_button['text'] = "Monitor Blinks" + self.monitoring = False + + def reidentify(self): + if not self.reidentifying: + self.reidentify_button['text'] = "Stop Reidentifying" + self.reidentifying = True + self.reidentifying_thread=threading.Thread(target=self.reidentifying_work) + self.reidentifying_thread.daemon = True + self.reidentifying_thread.start() + else: + self.reidentify_button['text'] = "Reidentify" + self.reidentifying = False + + def monitoring_work(self): + self.tracking = False + blinks, intervals, offset_time = rngtool.tracking_blink(self.player_eye, *self.config_json["view"], MonitorWindow=self.config_json["MonitorWindow"], WindowPrefix=self.config_json["WindowPrefix"], tk_window=self, th=self.config_json["thresh"]) + prng = rngtool.recov(blinks, intervals) + + self.monitor_blink_button['text'] = "Monitor Blinks" + self.monitoring = False + self.preview() + + waituntil = time.perf_counter() + diff = round(waituntil-offset_time) + prng.getNextRandSequence(diff) + + state = prng.getState() + s0 = f"{state[0]:08X}" + s1 = f"{state[1]:08X}" + s2 = f"{state[2]:08X}" + s3 = f"{state[3]:08X}" + + s01 = s0+s1 + s23 = s2+s3 + + print(s01,s23) + print(s0,s1,s2,s3) + self.s0_1_2_3.delete(1.0, tk.END) + self.s01_23.delete(1.0, tk.END) + + self.s0_1_2_3.insert(1.0,s0+"\n"+s1+"\n"+s2+"\n"+s3) + self.s01_23.insert(1.0,s01+"\n"+s23) + + self.advances = 0 + self.tracking = True + while self.tracking: + self.advances += 1 + r = prng.next() + waituntil += 1.018 + + print(f"advances:{self.advances}, blinks:{hex(r&0xF)}") + + next_time = waituntil - time.perf_counter() or 0 + time.sleep(next_time) + + def reidentifying_work(self): + self.tracking = False + state = [int(x,16) for x in self.s0_1_2_3.get(1.0,tk.END).split("\n")[:4]] + + s0 = f"{state[0]:08X}" + s1 = f"{state[1]:08X}" + s2 = f"{state[2]:08X}" + s3 = f"{state[3]:08X}" + + s01 = s0+s1 + s23 = s2+s3 + + print(s01,s23) + print(s0,s1,s2,s3) + self.s0_1_2_3.delete(1.0, tk.END) + self.s01_23.delete(1.0, tk.END) + + self.s0_1_2_3.insert(1.0,s0+"\n"+s1+"\n"+s2+"\n"+s3) + self.s01_23.insert(1.0,s01+"\n"+s23) + + print([hex(x) for x in state]) + observed_blinks, _, offset_time = rngtool.tracking_blink(self.player_eye, *self.config_json["view"], MonitorWindow=self.config_json["MonitorWindow"], WindowPrefix=self.config_json["WindowPrefix"], tk_window=self, th=self.config_json["thresh"], size=20) + reidentified_rng, adv = rngtool.reidentifyByBlinks(Xorshift(*state), observed_blinks, return_advance=True, npc=1) + + + self.reidentify_button['text'] = "Reidentify" + self.reidentifying = False + self.preview() + + waituntil = time.perf_counter() + diff = round(waituntil-offset_time)+1 + reidentified_rng.getNextRandSequence(diff) + state = reidentified_rng.getState() + + self.advances = adv+diff + self.tracking = True + while self.tracking: + self.advances += 1 + r = reidentified_rng.next() + waituntil += 1.018 + + print(f"advances:{self.advances}, blinks:{hex(r&0xF)}") + + next_time = waituntil - time.perf_counter() or 0 + time.sleep(next_time) + + def preview(self): + if not self.previewing: + self.preview_button['text'] = "Stop Preview" + self.previewing = True + self.previewing_thread=threading.Thread(target=self.previewing_work) + self.previewing_thread.daemon = True + self.previewing_thread.start() + else: + self.preview_button['text'] = "Preview" + self.previewing = False + + def previewing_work(self): + last_frame_tk = None + + if self.config_json["MonitorWindow"]: + from windowcapture import WindowCapture + video = WindowCapture(self.config_json["WindowPrefix"]) + else: + video = cv2.VideoCapture(0,cv2.CAP_DSHOW) + video.set(cv2.CAP_PROP_FRAME_WIDTH,1920) + video.set(cv2.CAP_PROP_FRAME_HEIGHT,1080) + video.set(cv2.CAP_PROP_BUFFERSIZE,1) + + + while self.previewing: + eye = self.player_eye + w, h = eye.shape[::-1] + roi_x, roi_y, roi_w, roi_h = self.config_json["view"] + _, frame = video.read() + roi = cv2.cvtColor(frame[roi_y:roi_y+roi_h,roi_x:roi_x+roi_w],cv2.COLOR_RGB2GRAY) + res = cv2.matchTemplate(roi,eye,cv2.TM_CCOEFF_NORMED) + _, match, _, max_loc = cv2.minMaxLoc(res) + + cv2.rectangle(frame,(roi_x,roi_y), (roi_x+roi_w,roi_y+roi_h), (0,0,255), 2) + if 0.01Tuple[List[int],List[int],float]: +def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40, MonitorWindow = False, WindowPrefix = "SysDVR-Client [PID ", tk_window = None)->Tuple[List[int],List[int],float]: """measuring the type and interval of player's blinks Returns: @@ -24,6 +24,7 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40, Monitor """ eye = img + last_frame_tk = None if MonitorWindow: from windowcapture import WindowCapture @@ -47,6 +48,12 @@ def tracking_blink(img, roi_x, roi_y, roi_w, roi_h, th = 0.9, size = 40, Monitor # 瞬きの観測 while len(blinks)0.7: state = IDLE - # print(debug_txt) - cv2.destroyAllWindows() + if tk_window == None: + cv2.destroyAllWindows() + else: + tk_window.progress['text'] = "0/0" + frame_tk = None + last_frame_tk = None return (blinks, intervals, offset_time) def tracking_blink_manual(size = 40, reidentify = False)->Tuple[List[int],List[int],float]: @@ -237,7 +259,7 @@ def recov(blinks:List[int],rawintervals:List[int])->Xorshift: result.getNextRandSequence(advanced_frame) return result -def reidentifyByBlinks(rng:Xorshift, observed_blinks:List[int], npc = 0, search_max=10**6, search_min=0)->Xorshift: +def reidentifyByBlinks(rng:Xorshift, observed_blinks:List[int], npc = 0, search_max=10**6, search_min=0, return_advance=False)->Xorshift: if search_maxXorshift: """Recover the xorshift from the interval of Munchlax blinks. diff --git a/trainer/home/eye_blur.png b/trainer/home/eye_blur.png deleted file mode 100644 index 1b9f955..0000000 Binary files a/trainer/home/eye_blur.png and /dev/null differ diff --git a/trainer/home/eye_normal.png b/trainer/home/eye_normal.png deleted file mode 100644 index bb48e3f..0000000 Binary files a/trainer/home/eye_normal.png and /dev/null differ