Skip to content

Instantly share code, notes, and snippets.

@pR0Ps
Created August 17, 2020 03:23
Show Gist options
  • Save pR0Ps/b12b853ef9b3395307921c9a248d6db2 to your computer and use it in GitHub Desktop.
Save pR0Ps/b12b853ef9b3395307921c9a248d6db2 to your computer and use it in GitHub Desktop.
Set the number of stars you have in Sky Force Reloaded
#!/usr/bin/env python
"""
The game Sky Force Reloaded on Android stores how many in-game stars you've
collected in an obfuscated config file. This program was made by
reverse-engineering that obfuscation using a bunch of sample values.
Given the number of stars you want, it will generate a line to add to the
game's config file. Note that the game will treat invalid values as 0 so make a
backup of your config before modifying it.
"""
# Samples:
# 4A-10-1D-42-0B-70-4B-10 = 0191
# 4B-10-1D-42-0B-70-4B-10 = 1191
# 48-10-1D-42-0B-70-4B-10 = 2191
# 49-10-1D-42-0B-70-4B-10 = 3191
# 4E-10-1D-42-0B-70-4B-10 = 4191
# 4F-10-1D-42-0B-70-4B-10 = 5191
# 4C-10-1D-42-0B-70-4B-10 = 6191
# 4D-10-1D-42-0B-70-4B-10 = 7191
# 42-10-1D-42-0B-70-4B-10 = 8191
# 43-10-1D-42-0B-70-4B-10 = 9191
# 4B-10-1F-42-03-70-4F-10 = 1315
# 4E-10-1A-42-06-70-4F-10 = 4645
# 4B-10-1D-42-04-70-4F-10-1D-42 = 11651
# 43-10-1D-42-04-70-4F-10-1D-42 = 91651
# 43-10-1D-42-06-70-48-10-1A-42 = 91426
# 43-10-1E-42-06-70-48-10-1A-42 = 92426
# 43-10-14-42-06-70-48-10-1A-42 = 98426
# 43-10-15-42-06-70-48-10-1A-42 = 99426
# 43-10-15-42-07-70-48-10-1A-42 = 99526
# 43-10-15-42-03-70-48-10-1A-42 = 99126
# 43-10-15-42-0B-70-48-10-1A-42 = 99926
# 43-10-15-42-0B-70-48-10-15-42 = 99929
# 43-10-15-42-04-70-48-10-15-42 = 99629
# Each digit is represented by a single byte, separated by a filler value
# The translation of digit to byte depends on its position in the number mod 3
# Filler:
# c1 c2 c3
# ---------
# 10 42 70
# Digits:
# n: c1 c2 c3
# ------------
# 0: 4A 1C 02
# 1: 4B 1D 03
# 2: 48 1E 00
# 3: 49 1F 01
# 4: 4E 18 06
# 5: 4F 19 07
# 6: 4C 1A 04
# 7: 4D 1B 05
# 8: 42 14 0A
# 9: 43 15 0B
# extrapolation...
# A: 40 16 08
# B: 41 17 09
# C: 46 10 0E
# D: 47 11 0F
# E: 44 12 0C
# F: 45 13 0D
# The digit mappings can be generated by repeatly splitting a list of 1 - 16 in
# half and swapping (or not) the 2 halves
import argparse
STARS_KEY = "2A-10-40-42-53-70-03-10-49-42-40-70-22-10-7C-42"
def swap(lst, s):
"""Recursively swap list halves
s is a bit array (0=leave, 1=swap) consumed from the right (0b100 = leave, leave, swap).
Will stop swapping when s is 0
"""
if not s:
return lst
m = len(lst) // 2
if s & 1:
lst[:m], lst[m:] = lst[m:], lst[:m]
s >>= 1
return swap(lst[:m], s) + swap(lst[m:], s)
# Filler values - static bytes that follow the actual data
FILLER = [0x10, 0x42, 0x70]
# Data bytes. The index is the value they represent
# ex: 5 = VALUES[x][5]
VALUES = [
[0x40 + x for x in swap(list(range(0, 16)), 0b101)],
[0x10 + x for x in swap(list(range(0, 16)), 0b11)],
[0x00 + x for x in swap(list(range(0, 16)), 0b100)],
]
def encode(val):
out = []
# Add a byte representing each digit followed by the correct filler byte
for i, x in enumerate(str(val)):
out.append(VALUES[i % 3][int(x)])
out.append(FILLER[i % 3])
return "-".join("{:0>2X}".format(x) for x in out)
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Set the number of stars in Sky Force Reloaded"
)
parser.add_argument("stars", type=int, help="Number of stars you want")
args = parser.parse_args()
val = encode(args.stars)
print(
"To apply the stars, edit:\n"
" /data/data/pl.idreams.SkyForceReloaded2016/shared_prefs/pl.idreams.SkyForceReloaded2016.v2.playerprefs.xml\n"
"and add the following line just before the closing </map> tag:\n"
' <string name="{}">{}</string>'.format(STARS_KEY, val)
)
@pR0Ps
Copy link
Author

pR0Ps commented Aug 17, 2020

Sample output:

$ ./skyforcestars.py 9999999
To apply the stars, edit:
   /data/data/pl.idreams.SkyForceReloaded2016/shared_prefs/pl.idreams.SkyForceReloaded2016.v2.playerprefs.xml
and add the following line just before the closing </map> tag:
    <string name="2A-10-40-42-53-70-03-10-49-42-40-70-22-10-7C-42">43-10-15-42-0B-70-43-10-15-42-0B-70-43-10</string>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment