Skip to content

Commit 3782248

Browse files
committed
Rewrite loop to be non-blocking and non-destructive
1 parent 720ada6 commit 3782248

File tree

1 file changed

+60
-62
lines changed

1 file changed

+60
-62
lines changed

adafruit_ducky.py

Lines changed: 60 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -128,78 +128,76 @@ def __init__(
128128
self.layout = layout
129129
self.lines = []
130130
self.default_delay = 0
131-
self.last = 0
131+
self.prev_line = None
132+
self.next_index = 0
133+
self.wait_until = 0
134+
self.repeat = 0
132135

133136
with open(filename, "r") as duckyscript:
134137
for line in duckyscript:
135-
self.lines.append(line[:-1].rstrip("\r"))
138+
line = line.strip(" \r")
139+
if len(line) > 0:
140+
self.lines.append(line)
136141

137142
def loop( # pylint: disable=too-many-return-statements
138-
self, line: Optional[str] = None
143+
self
139144
) -> bool: # pylint: disable=too-many-branches
140145
"""Function that sends a line of the DuckyScript file over hid every time it is called"""
141-
if line is None:
142-
try:
143-
line = self.lines[0]
144-
except IndexError:
145-
print("Done!")
146-
return False
147-
if len(line) != 0:
148-
words = line.split(" ", 1)
149-
start = words[0]
150-
if start == "REM":
151-
print(words[1])
152-
time.sleep(self.default_delay)
153-
self.lines.pop(0)
154-
return True
155-
156-
if start in ("DEFAULT_DELAY", "DEFAULTDELAY"):
157-
self.default_delay = int(words[1]) / 1000
158-
time.sleep(self.default_delay)
159-
self.last = self.lines[0]
160-
self.lines.pop(0)
161-
return True
162-
163-
if start == "DELAY":
164-
time.sleep(int(words[1]) / 1000)
165-
time.sleep(self.default_delay)
166-
self.last = self.lines[0]
167-
self.lines.pop(0)
168-
return True
169-
170-
if start == "STRING":
171-
self.layout.write(words[1])
172-
time.sleep(self.default_delay)
173-
self.last = self.lines[0]
174-
self.lines.pop(0)
175-
return True
176-
177-
if start == "REPEAT":
178-
print(int(words[1]))
179-
for _ in range(int(words[1])):
180-
self.lines.insert(0, self.last)
181-
self.loop()
182-
self.last = self.lines[0]
183-
self.lines.pop(0)
184-
return True
185-
186-
self.write_key(start)
187-
if len(words) == 1:
188-
time.sleep(self.default_delay)
189-
self.last = self.lines[0]
190-
self.lines.pop(0)
191-
self.keyboard.release_all()
192-
return True
193-
if len(words[1]):
194-
self.loop(line=words[1])
146+
147+
now = time.monotonic_ns()
148+
if now < self.wait_until:
149+
return True
150+
151+
try:
152+
if self.repeat > 0:
153+
self.repeat -= 1
154+
line = self.prev_line
195155
else:
196-
self.keyboard.release_all()
197-
return True
156+
line = self.lines[self.next_index]
157+
self.next_index += 1
158+
except IndexError:
159+
print(" DONE!")
160+
self.prev_line = None
161+
self.next_index = 0
162+
return False
163+
164+
words = line.split(" ", 1)
165+
start = words[0]
166+
167+
if start == "REPEAT":
168+
self.repeat = int(words[1])
169+
return True
170+
171+
self.prev_line = line
172+
173+
# print(f" {line}")
174+
175+
if start == "REM":
176+
# print(words[1])
177+
return True
178+
179+
self.wait_until = now + self.default_delay
180+
181+
if start in ("DEFAULT_DELAY", "DEFAULTDELAY"):
182+
self.wait_until -= self.default_delay
183+
self.default_delay = int(words[1]) * 1000000
184+
self.wait_until += self.default_delay
185+
return True
186+
187+
if start == "DELAY":
188+
self.wait_until += int(words[1]) * 1000000
189+
return True
190+
191+
if start == "STRING":
192+
self.layout.write(words[1])
193+
return True
194+
195+
self.write_key(start)
196+
if len(words) > 1:
197+
for key in words[1].split(" "):
198+
self.write_key(key)
198199

199200
self.keyboard.release_all()
200-
time.sleep(self.default_delay)
201-
self.last = self.lines[0]
202-
self.lines.pop(0)
203201
return True
204202

205203
def write_key(self, start: str) -> None:

0 commit comments

Comments
 (0)