Last active
June 6, 2017 22:22
-
-
Save davidsth/84793f44ba6852e34e9a0a3076aa9707 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from optparse import OptionParser | |
import ctypes | |
from ctypes import wintypes | |
import time | |
user32 = ctypes.WinDLL('user32', use_last_error=True) | |
INPUT_MOUSE = 0 | |
INPUT_KEYBOARD = 1 | |
INPUT_HARDWARE = 2 | |
KEYEVENTF_EXTENDEDKEY = 0x0001 | |
KEYEVENTF_KEYUP = 0x0002 | |
KEYEVENTF_UNICODE = 0x0004 | |
KEYEVENTF_SCANCODE = 0x0008 | |
MAPVK_VK_TO_VSC = 0 | |
# msdn.microsoft.com/en-us/library/dd375731 | |
VK_TAB = 0x09 | |
VK_MENU = 0x12 | |
VK_UP = 0x26 | |
VK_CONTROL = 0x11 | |
VK_A = 0x41 | |
VK_Q = 0x51 | |
VK_DELETE = 0x2E | |
VK_RETURN = 0x0D | |
# C struct definitions | |
wintypes.ULONG_PTR = wintypes.WPARAM | |
class MOUSEINPUT(ctypes.Structure): | |
_fields_ = (("dx", wintypes.LONG), | |
("dy", wintypes.LONG), | |
("mouseData", wintypes.DWORD), | |
("dwFlags", wintypes.DWORD), | |
("time", wintypes.DWORD), | |
("dwExtraInfo", wintypes.ULONG_PTR)) | |
class KEYBDINPUT(ctypes.Structure): | |
_fields_ = (("wVk", wintypes.WORD), | |
("wScan", wintypes.WORD), | |
("dwFlags", wintypes.DWORD), | |
("time", wintypes.DWORD), | |
("dwExtraInfo", wintypes.ULONG_PTR)) | |
def __init__(self, *args, **kwds): | |
super(KEYBDINPUT, self).__init__(*args, **kwds) | |
# some programs use the scan code even if KEYEVENTF_SCANCODE | |
# isn't set in dwFflags, so attempt to map the correct code. | |
if not self.dwFlags & KEYEVENTF_UNICODE: | |
self.wScan = user32.MapVirtualKeyExW(self.wVk, | |
MAPVK_VK_TO_VSC, 0) | |
class HARDWAREINPUT(ctypes.Structure): | |
_fields_ = (("uMsg", wintypes.DWORD), | |
("wParamL", wintypes.WORD), | |
("wParamH", wintypes.WORD)) | |
class INPUT(ctypes.Structure): | |
class _INPUT(ctypes.Union): | |
_fields_ = (("ki", KEYBDINPUT), | |
("mi", MOUSEINPUT), | |
("hi", HARDWAREINPUT)) | |
_anonymous_ = ("_input",) | |
_fields_ = (("type", wintypes.DWORD), | |
("_input", _INPUT)) | |
LPINPUT = ctypes.POINTER(INPUT) | |
def _check_count(result, func, args): | |
if result == 0: | |
raise ctypes.WinError(ctypes.get_last_error()) | |
return args | |
user32.SendInput.errcheck = _check_count | |
user32.SendInput.argtypes = (wintypes.UINT, # nInputs | |
LPINPUT, # pInputs | |
ctypes.c_int) # cbSize | |
# Functions | |
def PressKey(hexKeyCode): | |
x = INPUT(type=INPUT_KEYBOARD, | |
ki=KEYBDINPUT(wVk=hexKeyCode)) | |
user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x)) | |
def ReleaseKey(hexKeyCode): | |
x = INPUT(type=INPUT_KEYBOARD, | |
ki=KEYBDINPUT(wVk=hexKeyCode, | |
dwFlags=KEYEVENTF_KEYUP)) | |
user32.SendInput(1, ctypes.byref(x), ctypes.sizeof(x)) | |
def main(): | |
parser = OptionParser() | |
parser.add_option("-r", "--repeat", dest="repeat", | |
help="number of messages to remove. If not provided it will run once and stop") | |
(options, args) = parser.parse_args() | |
if not options.repeat: | |
parser.error('number of message to delete not specified\n\tex: cleanup_dms --repeat 10') | |
repeat = options.repeat | |
if (options.repeat): | |
repeat = int(options.repeat) | |
else: | |
repeat = 1 | |
print("Please have your discord tab open for the dm you would like to delete.\n") | |
for i in range(10, 0, -1): | |
print("Starting up in %d seconds:", i) | |
time.sleep(1) | |
for i in range(repeat): | |
PressKey(VK_UP) # Alt | |
ReleaseKey(VK_UP) | |
PressKey(VK_CONTROL) | |
PressKey(VK_A) | |
ReleaseKey(VK_A) | |
time.sleep(0.5) | |
ReleaseKey(VK_CONTROL) | |
time.sleep(0.5) | |
PressKey(VK_DELETE) | |
ReleaseKey(VK_DELETE) | |
PressKey(VK_RETURN) | |
ReleaseKey(VK_RETURN) | |
time.sleep(1) | |
PressKey(VK_RETURN) | |
ReleaseKey(VK_RETURN) | |
time.sleep(1) | |
if __name__=="__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment