Closed dj-riley closed 4 months ago
A very nice refactoring. I intentionally kept it basic though, however I just can't let this go to waste, very nice naming conventions.
One thing though, when you are checking for session change (link) it seems like this MIN_SESSION_SCORE_ADDRESS
is very arbitrary to check against as this is not a single offset initially, rather a bunch of offets for a bunch of addresses, you can't add them together.
If the game resets the session address back to 00000000
when you change from SinglePlayer to MultiPlayer for example, it should raise an exception as you can not read (self.pm.read_int(session_score_address)
) outside the game's allocated memory space. So what happens with the address when you change session? What difference does that MIN_SESSION_SCORE_ADDRESS
make?
Good job for finding the cause of that silent fail bug by the way.
One thing though, when you are checking for session change (link) it seems like this
MIN_SESSION_SCORE_ADDRESS
is very arbitrary to check against as this is not a single offset initially, rather a bunch of offets for a bunch of addresses, you can't add them together.If the game resets the session address back to
00000000
when you change from SinglePlayer to MultiPlayer for example, it should raise an exception as you can not read (self.pm.read_int(session_score_address)
) outside the game's allocated memory space. So what happens with the address when you change session? What difference does thatMIN_SESSION_SCORE_ADDRESS
make?
Ah OK, thank you very much for the explanation. I'll admit, my skills working directly with reading memory in this manner are quite poor - I'll have to do some studying in this area to better understand things.
In regards to the MIN_SESSION_SCORE_ADDRESS
check before applying the new session_score_address
: in my testing, I reached an exception a couple times due to a new session address being detected as just 0x6B0
, the final offset, and not a full valid memory address. I believed this was triggered when switching from multiplayer to singleplayer, but I can't exactly recall. Putting it in a while loop with a 1 sec timeout before attempting to get the address again would eventually resolve it. With your explanation, I agree that the value of MIN_SESSION_SCORE_ADDRESS
is arbitrary and likely not needed. My best guess is that get_session_score_address()
returning just 0x6B0
was due to the address not being fully initialized, but again, my lack of knowledge in this area is likely showing. Hoping you may have a better idea...
I wonder if removing line #146, but keeping the time.sleep(1)
call before re-obtaining current_session_score_address = self.get_session_score_address()
would allow enough time to establish a validsession_score_address
instead of using 0x6B0
. Let me do more testing without the MIN_SESSION_SCORE_ADDRESS
check to see if I can readily reproduce the 0x6B0
exception. I'll report back.
Thank you for the complements btw. You have a really cool app here and I hope it's OK to continue contributing on it's future development, while communicating of course.
OK, so my hypothesis was somewhat correct. On session change, I am sometimes returning a new current_session_score_address
of 0x6b0
, although it does not replicate reliably. To illustrate my findings, utilize this check_and_set_new_session()
function definition:
def check_and_set_new_session(self):
try:
current_session_score_address = self.get_session_score_address()
if current_session_score_address != self.session_score_address:
print("INFO: Original check session address:\t{}".format(hex(current_session_score_address)))
time.sleep(1)
self.session_score_address = self.get_session_score_address()
print("INFO: Reobtained new session address:\t{}".format(hex(self.session_score_address)))
self.report_ok()
return None
except Exception as e:
self.report_error_and_quit("Unable to check and set session, have you closed the game?")
To replicate the issue, keep joining and leaving any multiplayer server (Exit to Main Menu) until you see the console output: INFO: Original check session address: 0x6b0
. It may take a few tries until you see 0x6b0
. The time.sleep(1)
seems to leave enough time to re-obtain the correct address in these cases. Curious on your thoughts whenever you get the chance to test, no rush.
Yeah, seems like the pointer address gets subtracted and only the field offset of the object is present on the final address, thus storing 0x6b0 in it.
I have yet to verify this PR, as soon as I have time I'll do so and if everything's all right we can merge.
Pressing anything other than 'n' or 'y' makes the tracker exit when it asks whether to record latest harvest. Other than that, it seems to work fine!
Improvements proposed:
main.py
file as class to remove duplicate code and improve on ease of future contributionscheck_and_set_new_session()
function that is utilized in the mainwhile True
loop that checks harvestscurrent_session_score_address
and compares result to thesession_score_address
that's being used from initializationsession_score_address
, continue monitoring harvestsWould you like to record your latest kill which happened before starting this program? (y/n)
so the tracker will continue monitoring for harvests if the user forgets to answerComment: