Created
December 7, 2019 03:46
-
-
Save RGamberini/83abe0150d3687528d282f420757f310 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
import ctypes | |
import time | |
from mem_edit import Process | |
from controller import refreshShop, getFocus, refreshMaronaCreate, buyPhantom, buyWeapon | |
import psutil | |
def findProcessIdByName(processName): | |
''' | |
Get a list of all the PIDs of a all the running process whose name contains | |
the given string processName | |
''' | |
listOfProcessObjects = [] | |
# Iterate over the all the running process | |
for proc in psutil.process_iter(): | |
try: | |
pinfo = proc.as_dict(attrs=['pid', 'name', 'create_time']) | |
# Check if process name contains the given name string. | |
if processName.lower() in pinfo['name'].lower(): | |
listOfProcessObjects.append(pinfo) | |
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess): | |
pass | |
return listOfProcessObjects | |
def getTitleDatabase(): | |
result = {} | |
with open('formatted.txt', 'r') as f: | |
for line in f.readlines(): | |
info = list(map(str.strip, line.split(","))) | |
result[info[0]] = list(map(int, info[1:])) | |
return result | |
pid = findProcessIdByName("Phantom Brave PC.exe")[0]['pid'] # GOTTA HAVE THAT PID | |
titleDatabase = getTitleDatabase() | |
def getAscii(startAddr, size, count): | |
asciis = [] | |
buffer = (ctypes.c_byte * size)() # CREATE A BYTE BUFFER | |
with Process.open_process(pid) as p: | |
for i in range(count): | |
p.read_memory(startAddr + (size * i), buffer) | |
asciiBuffer = [] | |
for byte in buffer: | |
if byte != 0x00: | |
asciiBuffer.append(byte) | |
else: | |
break | |
asciis.append(asciiBuffer) | |
return asciis | |
def prettyPrintAsciis(asciis): | |
for i in range(len(asciis)): | |
print(i) | |
print("\t", end="") | |
print(list(map(hex, asciis[i]))) | |
try: | |
print("\t", end="") | |
print("".join(map(chr, asciis[i]))) | |
except: | |
print("\t", end="") | |
print("INDEX {0} DOES NOT WORK".format(i)) | |
""" | |
FOR GETTING THE TITLES OF PHANTOMS IN MARONA'S CREATE | |
""" | |
def getCreateStartAddr(): | |
""" | |
WE FIND THE STARTING ADDRESS I.E. THE ADDRESS OF THE FIRST PHANTOM'S TITLE | |
BY FIRST FINDING ALL THE MEMORY ADDRESSES CONTAINING 'Nameless Soul' | |
THEN FILTERING DOWN TO THE FIRST ADDRESS AFTER 0XC1BB0000 | |
""" | |
toFind = ctypes.create_string_buffer(b"Nameless Soul") | |
with Process.open_process(pid) as p: | |
startAddr = list(filter(lambda x: x >0x1CBB0000, p.search_all_memory(toFind)))[0] | |
startAddr += 23 | |
return startAddr | |
# MARONA_CREATE_STARTADDR = getCreateStartAddr() | |
MARONA_CREATE_STARTADDR = 0x0 | |
def getTitles(): | |
size = 2232 | |
count = 21 | |
startAddr = getCreateStartAddr() | |
prettyPrintAsciis(getAscii(startAddr, size, count)) | |
def getCreatureTypes(): | |
size = 58 | |
startAddr = 0x27525724 | |
count = 25 | |
asciis = getAscii(startAddr, size, count) | |
# prettyPrintAsciis(getAscii(startAddr, size, count)) | |
# ", ".join(list(map(chr, for ascii in asciis))) | |
# x = "\", \"".join(["".join(list(map(chr, ascii))) for ascii in asciis]) | |
# print(x) | |
def findDarkWpn(): | |
size = 720 | |
startAddr = 0x00F27430 | |
count = 15 | |
asciis = getAscii(startAddr, size, count) | |
weapons = ["".join(list(map(chr, ascii))) for ascii in asciis] | |
found = False | |
for weapon in weapons: | |
if "Dark Wpn" in weapon: | |
found = True | |
print("FOUND ONE") | |
return False | |
if not found: | |
refreshShop() | |
return True | |
def findFailureTitle(): | |
size = 2232 | |
count = 21 | |
startAddr = MARONA_CREATE_STARTADDR | |
asciis = getAscii(startAddr, size, count) | |
phantoms = ["".join(list(map(chr, ascii))) for ascii in asciis] | |
print(phantoms) | |
phantoms.pop(1) | |
for phantom in phantoms: | |
if "Failure" in phantom: | |
buyPhantom(phantoms.index(phantom)) | |
return False | |
refreshMaronaCreate() | |
return True | |
def findBestTitle(): | |
size = 720 | |
startAddr = 0x00907430 | |
count = 15 | |
asciis = getAscii(startAddr, size, count) | |
weapons = ["".join(list(map(chr, ascii))) for ascii in asciis] | |
print(weapons) | |
for weapon in weapons: | |
if "Chief" in weapon or "Techno" in weapon: | |
print("Found a {0}".format(weapon)) | |
buyWeapon(weapons.index(weapon)) | |
refreshShop() | |
return False | |
else: | |
refreshShop() | |
return True | |
START = { | |
"ENEMY LV": 0x00DCBF2C,# MAGIC NUMBER FOUND IN CHEAT ENGINE BY SEARCHING FOR ENEMY LV | |
"FLOOR NUMBER": 0x00DCBF30, | |
"MAIN ENEMY": 0x00DCBF80, | |
"RELEVANT": 0x00DCBF52, | |
"END": 0x00DCBF7E | |
} | |
CREATURES = dict(zip( | |
range(1, 20), | |
["Male", "Female", "Feeble", "Puny", "Warrior", "Mage", "Artisan", "Beast", "Giant", "Creepy", "Horror", "Owl", "DemiMan", "Chibi", "Putty", "Slime", "Common", "Shroom", "Weird"] | |
)) | |
CREATURES[33] = 'Variable' | |
def scrapeAllDungeonInfo(): | |
""" | |
FOR SCRAPING MEMORY AROUND DUNGEON INFOBOX (BASED ON MEMORY POSITION OF ENEMY LV) | |
""" | |
size = START["END"] - START["ENEMY LV"] | |
buffer = (ctypes.c_ubyte * size)() | |
with Process.open_process(pid) as p: | |
with open("out.txt", 'w') as out: | |
name = "" | |
while name != "q": | |
name = input() | |
p.read_memory(START["RELEVANT"], buffer) | |
# print(name, end=" ") | |
# print(' '.join('{:02X}'.format(a) for a in buffer)) | |
out.write(name) | |
out.write(' '.join('{:02X}'.format(a) for a in buffer)) | |
out.write("\n") | |
# print(" ".join(list(map(hex, buffer)))) | |
def getDungeonInfoBox(): | |
addresses = ( | |
("ENEMY LV", lambda n: n), | |
("FLOOR NUMBER", lambda n: n), | |
("MAIN ENEMY", lambda n: CREATURES[n]) | |
) | |
buffer = (ctypes.c_ubyte * 1)() | |
with Process.open_process(pid) as p: | |
for address, func in addresses: | |
p.read_memory(START[address], buffer) | |
print("{0}: {1}".format(address, func(buffer[0]))) | |
getFocus() | |
i = 0 | |
# while i < 3: | |
# if not findFailureTitle(): | |
# i += 1 | |
# time.sleep(2.5) | |
# seq2 = ["ENTER", "S", "S", "ENTER"] | |
# pressSeq(seq2, delay=.2) | |
# while findBestTitle(): | |
# continue | |
while i < 16: | |
if not findBestTitle(): | |
i += 1 | |
# refreshShop() | |
# findFailureTitle() | |
findBestTitle() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment