| 
26 | 26 | from adafruit_hid.keycode import Keycode  | 
27 | 27 | 
 
  | 
28 | 28 | try:  | 
29 |  | -    from typing import Optional  | 
30 | 29 |     from adafruit_hid.keyboard import Keyboard  | 
31 | 30 |     from adafruit_hid.keyboard_layout_base import KeyboardLayoutBase  | 
32 | 31 | except ImportError:  | 
@@ -128,76 +127,76 @@ def __init__(  | 
128 | 127 |         self.layout = layout  | 
129 | 128 |         self.lines = []  | 
130 | 129 |         self.default_delay = 0  | 
131 |  | -        self.last = 0  | 
 | 130 | +        self.prev_line = None  | 
 | 131 | +        self.next_index = 0  | 
 | 132 | +        self.wait_until = 0  | 
 | 133 | +        self.repeat = 0  | 
132 | 134 | 
 
  | 
133 | 135 |         with open(filename, "r") as duckyscript:  | 
134 | 136 |             for line in duckyscript:  | 
135 |  | -                self.lines.append(line[:-1].rstrip("\r"))  | 
 | 137 | +                line = line.lstrip(" ").rstrip("\n\r")  | 
 | 138 | +                if len(line) > 0:  | 
 | 139 | +                    self.lines.append(line)  | 
136 | 140 | 
 
  | 
137 | 141 |     def loop(  # pylint: disable=too-many-return-statements  | 
138 |  | -        self, line: Optional[str] = None  | 
 | 142 | +        self,  | 
139 | 143 |     ) -> bool:  # pylint: disable=too-many-branches  | 
140 | 144 |         """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 |  | -                self.keyboard.release_all()  | 
189 |  | -                time.sleep(self.default_delay)  | 
190 |  | -                self.last = self.lines[0]  | 
191 |  | -                self.lines.pop(0)  | 
192 |  | -                return True  | 
193 |  | -            if len(words[1]):  | 
194 |  | -                self.loop(line=words[1])  | 
 | 145 | + | 
 | 146 | +        now = time.monotonic_ns()  | 
 | 147 | +        if now < self.wait_until:  | 
 | 148 | +            return True  | 
 | 149 | + | 
 | 150 | +        try:  | 
 | 151 | +            if self.repeat > 0:  | 
 | 152 | +                self.repeat -= 1  | 
 | 153 | +                line = self.prev_line  | 
195 | 154 |             else:  | 
196 |  | -                self.keyboard.release_all()  | 
197 |  | -                return True  | 
 | 155 | +                line = self.lines[self.next_index]  | 
 | 156 | +                self.next_index += 1  | 
 | 157 | +        except IndexError:  | 
 | 158 | +            print("  DONE!")  | 
 | 159 | +            self.prev_line = None  | 
 | 160 | +            self.next_index = 0  | 
 | 161 | +            return False  | 
 | 162 | + | 
 | 163 | +        words = line.split(" ", 1)  | 
 | 164 | +        start = words[0]  | 
 | 165 | + | 
 | 166 | +        if start == "REPEAT":  | 
 | 167 | +            self.repeat = int(words[1])  | 
 | 168 | +            return True  | 
 | 169 | + | 
 | 170 | +        self.prev_line = line  | 
 | 171 | + | 
 | 172 | +        # print(f"  {line}")  | 
 | 173 | + | 
 | 174 | +        if start == "REM":  | 
 | 175 | +            # print(words[1])  | 
 | 176 | +            return True  | 
 | 177 | + | 
 | 178 | +        self.wait_until = now + self.default_delay  | 
 | 179 | + | 
 | 180 | +        if start in ("DEFAULT_DELAY", "DEFAULTDELAY"):  | 
 | 181 | +            self.wait_until -= self.default_delay  | 
 | 182 | +            self.default_delay = int(words[1]) * 1000000  | 
 | 183 | +            self.wait_until += self.default_delay  | 
 | 184 | +            return True  | 
 | 185 | + | 
 | 186 | +        if start == "DELAY":  | 
 | 187 | +            self.wait_until += int(words[1]) * 1000000  | 
 | 188 | +            return True  | 
 | 189 | + | 
 | 190 | +        if start == "STRING":  | 
 | 191 | +            self.layout.write(words[1])  | 
 | 192 | +            return True  | 
 | 193 | + | 
 | 194 | +        self.write_key(start)  | 
 | 195 | +        if len(words) > 1:  | 
 | 196 | +            for key in filter(None, words[1].split(" ")):  | 
 | 197 | +                self.write_key(key)  | 
198 | 198 | 
 
  | 
199 | 199 |         self.keyboard.release_all()  | 
200 |  | -        time.sleep(self.default_delay)  | 
201 | 200 |         return True  | 
202 | 201 | 
 
  | 
203 | 202 |     def write_key(self, start: str) -> None:  | 
 | 
0 commit comments