-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathlaunch.py
More file actions
98 lines (86 loc) · 2.59 KB
/
launch.py
File metadata and controls
98 lines (86 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#!/usr/bin/env python3
import asyncio
import sys
from contextlib import asynccontextmanager
COMMAND_PORT = 9028
LAUNCH_CMD = b'\x01'
KILL_APP_CMD = b'\x04'
PROC_LIST_CMD = b'\x02'
RESPONSE_OK = b'\x00'
RESPONSE_ERROR = 255
@asynccontextmanager
async def open_connection(host: str, port: int):
while True:
try:
reader, writer = await asyncio.open_connection(host, port)
except OSError:
await asyncio.sleep(1)
continue
try:
yield reader, writer
break
finally:
await writer.drain()
writer.close()
async def launch(host: str, appId: str):
async with open_connection(host, COMMAND_PORT) as (reader, writer):
writer.write(LAUNCH_CMD)
writer.write(appId.encode('latin-1'))
await writer.drain()
reply = await reader.read()
if not reply:
print('no response')
return
err = reply[0]
reply = reply[1:]
print(err)
if err == RESPONSE_ERROR:
print(f'launch failed: {reply.decode("latin-1")}')
else:
print('launch successful')
async def kill(host: str, appId: int):
async with open_connection(host, COMMAND_PORT) as (reader, writer):
writer.write(KILL_APP_CMD)
writer.write(appId.to_bytes(length=4, byteorder='little'))
await writer.drain()
reply = await reader.read()
if not reply:
print('no response')
return
err = reply[0]
reply = reply[1:]
print(err)
if err == RESPONSE_ERROR:
print(f'launch failed: {reply.decode("latin-1")}')
else:
print('launch successful')
async def list_procs(host: str):
async with open_connection(host, COMMAND_PORT) as (_, writer):
writer.write(PROC_LIST_CMD)
await writer.drain()
if __name__ == '__main__':
if len(sys.argv) > 4:
print(f'usage: {__file__} ps5ip titleId')
sys.exit()
if len(sys.argv) == 2:
try:
asyncio.run(list_procs(sys.argv[1]))
except KeyboardInterrupt:
pass
sys.exit()
if sys.argv[2] == 'kill':
try:
try:
id = int(sys.argv[3])
except ValueError:
id = int(sys.argv[3], 16)
asyncio.run(kill(sys.argv[1], id))
except KeyboardInterrupt:
pass
if len(sys.argv[2]) > 9:
print('invalid title id')
sys.exit()
try:
asyncio.run(launch(sys.argv[1], sys.argv[2]))
except KeyboardInterrupt:
pass