Skip to content

Commit 79161c8

Browse files
2 parents ee684a6 + 797605c commit 79161c8

File tree

5 files changed

+372
-108
lines changed

5 files changed

+372
-108
lines changed
Binary file not shown.

arrascopypasta.py

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def get_pixel_rgb(x, y):
4646
controller = KeyboardController()
4747
current_chars = 0
4848
current_percent = 0
49+
controller_typing = False # Flag to ignore synthetic keypresses
4950

5051
def interruptible_sleep(duration):
5152
global copypastaing
@@ -106,6 +107,20 @@ def split_sentences(filepath, max_length=60, disable_space_breaking=False, disab
106107
pause_event = threading.Event()
107108
pause_event.set() # Start as running
108109

110+
def safe_type(text):
111+
"""Type text while flagging to ignore synthetic keypresses"""
112+
global controller_typing
113+
controller_typing = True
114+
controller.type(text)
115+
controller_typing = False
116+
117+
def safe_tap(key):
118+
"""Tap key while flagging to ignore synthetic keypresses"""
119+
global controller_typing
120+
controller_typing = True
121+
controller.tap(key)
122+
controller_typing = False
123+
109124
def replace_emojis(text):
110125
# Emoji unicode ranges
111126
emoji_pattern = re.compile(
@@ -128,7 +143,7 @@ def replace_emojis(text):
128143

129144
def copypasta(id, prepare=False, disable_space_breaking=False, disable_finish_text=False, disable_line_breaks=False):
130145
time.sleep(2)
131-
global ids, copypastaing, filepaths, controller, pause_event, current_chars, current_percent
146+
global ids, copypastaing, filepaths, controller, pause_event, current_chars, current_percent, controller_typing
132147
if id in ids:
133148
index = ids.index(id)
134149
filepath = filepaths[index]
@@ -147,33 +162,33 @@ def copypasta(id, prepare=False, disable_space_breaking=False, disable_finish_te
147162
# Extract just the copypastas/filename.txt part for display
148163
path_obj = Path(filepath)
149164
relative_path = f"copypastas/{path_obj.name}"
150-
controller.tap(Key.enter)
165+
safe_tap(Key.enter)
151166
interruptible_sleep(0.1)
152-
controller.type(f"Arras Copypasta Utility [ACU] > v02.04.11-beta.4 < loading")
167+
safe_type(f"Arras Copypasta Utility [ACU] > v02.04.11-beta.4 < loading")
153168
interruptible_sleep(0.1)
154169
for _ in range(2):
155-
controller.tap(Key.enter)
170+
safe_tap(Key.enter)
156171
interruptible_sleep(0.1)
157-
controller.type(f"Filepath: > [.../{relative_path}] < | Loaded > {leng} chars <")
172+
safe_type(f"Filepath: > [.../{relative_path}] < | Loaded > {leng} chars <")
158173
interruptible_sleep(0.1)
159174
for _ in range(2):
160-
controller.tap(Key.enter)
175+
safe_tap(Key.enter)
161176
interruptible_sleep(0.1)
162-
controller.type(f"Size: > [{file_size_kb:.2f}KB] < | Time taken > [{round((end-start)*1000, 3)}ms] <")
177+
safe_type(f"Size: > [{file_size_kb:.2f}KB] < | Time taken > [{round((end-start)*1000, 3)}ms] <")
163178
interruptible_sleep(0.1)
164-
controller.tap(Key.enter)
179+
safe_tap(Key.enter)
165180
interruptible_sleep(10)
166181
endf = False
167182
for sentence in sentences:
168183
if not copypastaing:
169184
break
170185
pause_event.wait() # Wait here if paused
171-
controller.tap(Key.enter)
186+
safe_tap(Key.enter)
172187
interruptible_sleep(0.1)
173188
sentence_no_emoji = replace_emojis(sentence)
174-
controller.type(sentence_no_emoji)
189+
safe_type(sentence_no_emoji)
175190
interruptible_sleep(0.1)
176-
controller.tap(Key.enter)
191+
safe_tap(Key.enter)
177192
pos += len(sentence_no_emoji)
178193
current_chars = pos
179194
current_percent = (current_chars / leng) * 100 if leng > 0 else 0
@@ -184,58 +199,62 @@ def copypasta(id, prepare=False, disable_space_breaking=False, disable_finish_te
184199
percent_typed = (chars_typed / leng) * 100 if leng > 0 else 0
185200
if not endf: # Force stop by Escape
186201
print(f"Forced stop at > [{chars_typed}] characters [{percent_typed:.2f}%]")
187-
controller.tap(Key.enter)
202+
safe_tap(Key.enter)
188203
interruptible_sleep(0.1)
189-
controller.type(f"Forced stop at > [{chars_typed}] characters [{percent_typed:.2f}%]")
204+
safe_type(f"Forced stop at > [{chars_typed}] characters [{percent_typed:.2f}%]")
190205
interruptible_sleep(0.1)
191206
else:
192207
if not disable_finish_text:
193208
print(f"Copypasta of > [{leng}] characters < finished")
194-
controller.tap(Key.enter)
209+
safe_tap(Key.enter)
195210
interruptible_sleep(0.1)
196-
controller.type(f"Copypasta of > [{leng}] characters < finished")
211+
safe_type(f"Copypasta of > [{leng}] characters < finished")
197212
interruptible_sleep(0.1)
198213
else:
199214
print(f"Copypasta of > [{leng}] characters < finished (without finish text)")
200215
if not disable_finish_text:
201-
controller.tap(Key.enter)
216+
safe_tap(Key.enter)
202217
interruptible_sleep(0.1)
203218
time.sleep(3.5)
204-
controller.tap(Key.enter)
219+
safe_tap(Key.enter)
205220
interruptible_sleep(0.1)
206221
print(f"Time taken: > [{round(1000*(time.time()-start), 3)}ms] <")
207-
controller.type(f"Time taken: > [{round(1000*(time.time()-start), 3)}ms] <")
222+
safe_type(f"Time taken: > [{round(1000*(time.time()-start), 3)}ms] <")
208223
interruptible_sleep(0.1)
209-
controller.tap(Key.enter)
224+
safe_tap(Key.enter)
210225
interruptible_sleep(0.1)
211226
# Do not exit here; let the thread finish
212227
copypastaing = False
213228

214229
def on_press(key):
215-
global copypastaing, pause_event, current_chars, current_percent, controller
230+
global copypastaing, pause_event, current_chars, current_percent, controller, controller_typing
216231
try:
232+
# Ignore synthetic keypresses from the controller
233+
if controller_typing:
234+
return
235+
217236
if key == keyboard.Key.esc:
218237
copypastaing = False
219238
elif hasattr(key, 'char') and key.char == 'p' and copypastaing:
220239
if pause_event.is_set():
221240
pause_event.clear()
222241
time.sleep(3.3)
223242
print(f"Paused at > [{current_chars}] < chars | > [{current_percent:.2f}%] <")
224-
controller.tap(Key.enter)
243+
safe_tap(Key.enter)
225244
interruptible_sleep(0.1)
226-
controller.type(f"Paused at > [{current_chars}] < chars | > [{current_percent:.2f}%] <")
245+
safe_type(f"Paused at > [{current_chars}] < chars | > [{current_percent:.2f}%] <")
227246
interruptible_sleep(0.1)
228-
controller.tap(Key.enter)
247+
safe_tap(Key.enter)
229248
interruptible_sleep(0.1)
230249
else:
231250
pause_event.set()
232251
time.sleep(3.3)
233252
print(f"Resumed at > [{current_chars}] < chars | > [{current_percent:.2f}%] <")
234-
controller.tap(Key.enter)
253+
safe_tap(Key.enter)
235254
interruptible_sleep(0.1)
236-
controller.type(f"Resumed at > [{current_chars}] < chars | > [{current_percent:.2f}%] <")
255+
safe_type(f"Resumed at > [{current_chars}] < chars | > [{current_percent:.2f}%] <")
237256
interruptible_sleep(0.1)
238-
controller.tap(Key.enter)
257+
safe_tap(Key.enter)
239258
interruptible_sleep(0.1)
240259
except UnicodeDecodeError:
241260
print("UnicodeDecodeError: Non-standard key (emoji?) pressed. Ignored.")

0 commit comments

Comments
 (0)