玩饥荒那个挑战关卡的时候,想通关看看什么样,所以用控制台代码解锁所有物品来玩。可是每次进入新的地图都需要手动输入这些代码,很麻烦,于是上网查了python如何模拟键盘输入,查到要使用两个库:
win32api和win32con,同时使用键值码模拟键盘按键。饥荒打开控制台需要按下~
键,所以找到了keyboard库,运行程序的时候只有按下~
键才继续往下执行
import win32api
import win32con
import keyboard
'''A 65 0 96 F1 112 Backspace 8
B 66 1 97 F2 113 Tab 9
C 67 2 98 F3 114 Clear 12
D 68 3 99 F4 115 Enter 13
E 69 4 100 F5 116 Shift 16
F 70 5 101 F6 117 Control 17
G 71 6 102 F7 118 Alt 18
H 72 7 103 F8 119 Caps Lock 20
I 73 8 104 F9 120 Esc 27
J 74 9 105 F10 121 Spacebar 32
K 75 * 106 F11 122 Page Up 33
L 76 + 107 F12 123 Page Down 34
M 77 Enter 108 End 35
N 78 - 109 Home 36
O 79 . 110 Left Arrow 37
P 80 / 111 Up Arrow 38
Q 81 Right Arrow 39
R 82 Down Arrow 40
S 83 Insert 45
T 84 Delete 46
U 85 Help 47
V 86 Num Lock 144
W 87
X 88 186 Oem1 ;
Y 89 187 Oemplus =
Z 90 188 Oemcomma ,
0 48 189 OemMinus -
1 49 190 OemPeriod .
2 50 191 OemQuestion /
3 51 192 Oemtilde `
4 52 219 OemOpenBrackets [
5 53 220 Oem5 \
6 54 221 Oem6 ]
7 55 222 Oem7 '
8 56
9 57
'''
开始只有一个需求,就是输入GetPlayer().components.builder:GiveAllRecipes()
按照网上的方法是这样模拟键盘的
# G
win32api.keybd_event(16, 0, 0, 0)
win32api.keybd_event(71, 0, 0, 0)
win32api.keybd_event(71, 0, win32con.KEYEVENTF_KEYUP, 0)
win32api.keybd_event(16, 0, win32con.KEYEVENTF_KEYUP, 0)
# e
win32api.keybd_event(71, 0, 0, 0)
win32api.keybd_event(71, 0, win32con.KEYEVENTF_KEYUP, 0)
一个大写字母就要四行代码,小写字母两行,这代码工作量也太大了,代码格式固定,就想到了用循环语句减少输入量。
keyboard.wait('`')
for i in [20, 71, 20, 69, 84, 20, 80, 20, 76, 65, 89, 69, 82]:
win32api.keybd_event(i, 0, 0, 0)
win32api.keybd_event(i, 0, win32con.KEYEVENTF_KEYUP, 0)
win32api.keybd_event(16, 0, 0, 0)
for i in [57, 48]:
win32api.keybd_event(i, 0, 0, 0)
win32api.keybd_event(i, 0, win32con.KEYEVENTF_KEYUP, 0)
win32api.keybd_event(16, 0, win32con.KEYEVENTF_KEYUP, 0)
for i in [190, 67, 79, 77, 80, 79, 78, 69, 78, 84, 83, 190, 66, 85, 73, 76, 68, 69, 82]:
win32api.keybd_event(i, 0, 0, 0)
win32api.keybd_event(i, 0, win32con.KEYEVENTF_KEYUP, 0)
win32api.keybd_event(16, 0, 0, 0)
for i in [186, 71, 65, 82, 57, 48]:
win32api.keybd_event(i, 0, 0, 0)
win32api.keybd_event(i, 0, win32con.KEYEVENTF_KEYUP, 0)
win32api.keybd_event(16, 0, win32con.KEYEVENTF_KEYUP, 0)
for i in [37, 37, 37, 37, 73, 86, 69, 39, 76, 76, 39, 69, 73, 80, 69, 83, 39, 39, 13, 192]:
win32api.keybd_event(i, 0, 0, 0)
win32api.keybd_event(i, 0, win32con.KEYEVENTF_KEYUP, 0)
虽然也很繁琐,但是输入一串控制台代码来说够用了,在记事本试了一下,秒输,很爽。同时也在考虑,都这么快了,干脆把用得到的控制台代码都让python一次输入得了。但是那么多代码,这种方法肯定不行,代码工作量还是太大。观察规律发现完全可以用函数来节约代码量,于是做了两个函数,分别是不用shift键和用shift键
def WithoutShift(*args): # 不带shift建的输入
for i in args:
win32api.keybd_event(i, 0, 0, 0)
win32api.keybd_event(i, 0, win32con.KEYEVENTF_KEYUP, 0)
def WithShift(*args):
win32api.keybd_event(16, 0, 0, 0)
for i in args:
win32api.keybd_event(i, 0, 0, 0)
win32api.keybd_event(i, 0, win32con.KEYEVENTF_KEYUP, 0)
win32api.keybd_event(16, 0, win32con.KEYEVENTF_KEYUP, 0)
这样代码量就减少很多了,一个饥荒控制台代码只需最多5行python代码就可以实现
keyboard.wait('`')
'''GetPlayer().components.builder:GiveAllRecipes() '''
WithoutShift(20, 71, 20, 69, 84, 20, 80, 20, 76, 65, 89, 69, 82)
WithShift(57, 48)
WithoutShift(190, 67, 79, 77, 80, 79, 78, 69, 78, 84, 83, 190, 66, 85, 73, 76, 68, 69, 82)
WithShift(186, 71, 65, 82, 57, 48)
WithoutShift(37, 37, 37, 37, 73, 86, 69, 39, 76, 76, 39, 69, 67, 73, 80, 69, 83, 39, 39, 13, 192)
# minimap = TheSim:FindFirstEntityWithTag("minimap")
WithoutShift(77, 73, 78, 73, 77, 65, 80, 32, 187, 32, 20, 84, 20, 72, 69, 20, 83, 20, 73, 77)
WithShift(186, 57, 222, 222, 48) # :("")
WithoutShift(37, 37, 37, 37, 20, 70, 20, 73, 78, 68, 20, 70, 20, 73, 82, 83, 84, 20, 69, 20, 78, 84, 73, 84, 89,
20, 87, 20, 73, 84, 72, 20, 84, 20, 65, 71, 39, 39, 77, 73, 78, 73, 77, 65, 80, 39, 39, 13, 192)
# minimap.MiniMap:ShowArea(0,0,0, 10000)
WithoutShift(77, 73, 78, 73, 77, 65, 80, 190, 20, 77, 20, 73, 78, 73, 20, 77, 20, 65, 80)
WithShift(186, 83, 65, 57, 48) # :("")
WithoutShift(37, 37, 37, 72, 79, 87, 39, 82, 69, 65, 39, 48, 188, 48, 188, 48, 188, 32, 49, 48, 48, 48, 48, 39, 13)
用记事本测试非常完美,迫不及待打开饥荒测试,一测试完犊子了,运行程序的时候饥荒控制台打开一下就关了,而且画面乱晃,小人瞎走,工具栏自己开关,心累啊。又一个字母一个字母的测试找原因,没解决,想了想应该是自动输入太快了,饥荒反应不过来了,于是在函数中加了计时器,让每个字母输入的时候慢一点,测试发现方向是对的,但是还有一个问题就是第一个大写字母总是输入不上,也不知道原因,干脆让电脑先随便输一个字母再正式开始输入控制台代码吧。测试通过,完美!完整代码如下,希望有大神可以指点一下,再改进一下。
import win32api
import win32con
import keyboard
import time
'''A 65 0 96 F1 112 Backspace 8
B 66 1 97 F2 113 Tab 9
C 67 2 98 F3 114 Clear 12
D 68 3 99 F4 115 Enter 13
E 69 4 100 F5 116 Shift 16
F 70 5 101 F6 117 Control 17
G 71 6 102 F7 118 Alt 18
H 72 7 103 F8 119 Caps Lock 20
I 73 8 104 F9 120 Esc 27
J 74 9 105 F10 121 Spacebar 32
K 75 * 106 F11 122 Page Up 33
L 76 + 107 F12 123 Page Down 34
M 77 Enter 108 End 35
N 78 - 109 Home 36
O 79 . 110 Left Arrow 37
P 80 / 111 Up Arrow 38
Q 81 Right Arrow 39
R 82 Down Arrow 40
S 83 Insert 45
T 84 Delete 46
U 85 Help 47
V 86 Num Lock 144
W 87
x 88 186 Oem1 ;
Y 89 187 Oemplus =
Z 90 188 Oemcomma ,
0 48 189 OemMinus -
1 49 190 OemPeriod .
2 50 191 OemQuestion /
3 51 192 Oemtilde `
4 52 219 OemOpenBrackets [
5 53 220 Oem5 \
6 54 221 Oem6 ]
7 55 222 Oem7 '
8 56
9 57
'''
def WithoutShift(*args): # 不带shift建的输入
for i in args:
win32api.keybd_event(i, 0, 0, 0)
win32api.keybd_event(i, 0, win32con.KEYEVENTF_KEYUP, 0)
time.sleep(0.05)
time.sleep(0.05)
def WithShift(*args):
win32api.keybd_event(16, 0, 0, 0)
for i in args:
win32api.keybd_event(i, 0, 0, 0)
win32api.keybd_event(i, 0, win32con.KEYEVENTF_KEYUP, 0)
time.sleep(0.05)
win32api.keybd_event(16, 0, win32con.KEYEVENTF_KEYUP, 0)
time.sleep(0.05)
keyboard.wait('`')
'''GetPlayer().components.builder:GiveAllRecipes() '''
WithoutShift(65, 13, 192) # 先随便输一个字母,回车,~
WithoutShift(20, 71, 20, 69, 84, 20, 80, 20, 76, 65, 89, 69, 82)
WithShift(57, 48)
WithoutShift(190, 67, 79, 77, 80, 79, 78, 69, 78, 84, 83, 190, 66, 85, 73, 76, 68, 69, 82)
WithShift(186, 71, 65, 82, 57, 48)
WithoutShift(37, 37, 37, 37, 73, 86, 69, 39, 76, 76, 39, 69, 67, 73, 80, 69, 83, 39, 39, 13, 192)
# 生命100000
WithoutShift(20, 71, 20, 69, 84, 20, 80, 20, 76, 65, 89, 69, 82)
WithShift(57, 48)
WithoutShift(190, 67, 79, 77, 80, 79, 78, 69, 78, 84, 83, 190, 72, 69, 65, 76, 84, 72)
WithShift(186, 83, 77, 72, 57, 48)
WithoutShift(37, 37, 37, 37, 69, 84, 39, 65, 88, 39, 69, 65, 76, 84, 72, 39, 49, 48, 48, 48, 48, 48, 48, 39, 13, 192)
# 饥饿1000
WithoutShift(20, 71, 20, 69, 84, 20, 80, 20, 76, 65, 89, 69, 82)
WithShift(57, 48)
WithoutShift(190, 67, 79, 77, 80, 79, 78, 69, 78, 84, 83, 190, 72, 85, 78, 71, 69, 82)
WithShift(186, 83, 77, 57, 48)
WithoutShift(37, 37, 37, 69, 84, 39, 65, 88, 39, 49, 48, 48, 48, 39, 13, 192)
# 脑残1000
WithoutShift(20, 71, 20, 69, 84, 20, 80, 20, 76, 65, 89, 69, 82)
WithShift(57, 48)
WithoutShift(190, 67, 79, 77, 80, 79, 78, 69, 78, 84, 83, 190, 83, 65, 78, 73, 84, 89)
WithShift(186, 83, 77, 57, 48)
WithoutShift(37, 37, 37, 69, 84, 39, 65, 88, 39, 49, 48, 48, 48, 39, 13, 192)
# minimap = TheSim:FindFirstEntityWithTag("minimap")
WithoutShift(77, 73, 78, 73, 77, 65, 80, 32, 187, 32, 20, 84, 20, 72, 69, 20, 83, 20, 73, 77)
WithShift(186, 57, 222, 222, 48) # :("")
WithoutShift(37, 37, 37, 37, 20, 70, 20, 73, 78, 68, 20, 70, 20, 73, 82, 83, 84, 20, 69, 20, 78, 84, 73, 84, 89,
20, 87, 20, 73, 84, 72, 20, 84, 20, 65, 71, 39, 39, 77, 73, 78, 73, 77, 65, 80, 39, 39, 13, 192)
# minimap.MiniMap:ShowArea(0,0,0, 10000)
WithoutShift(77, 73, 78, 73, 77, 65, 80, 190, 20, 77, 20, 73, 78, 73, 20, 77, 20, 65, 80)
WithShift(186, 83, 65, 57, 48) # :("")
WithoutShift(37, 37, 37, 72, 79, 87, 39, 82, 69, 65, 39, 48, 188, 48, 188, 48, 188, 32, 49, 48, 48, 48, 48, 39, 13)