Additional typing fixes for safety and to be able to compile more code with mypyc.
This commit is contained in:
parent
732e2afb42
commit
83495f44af
@ -0,0 +1,3 @@
|
||||
import os.path
|
||||
|
||||
package_root = os.path.dirname(os.path.abspath(__file__))
|
@ -13,19 +13,19 @@ class AESCipher:
|
||||
self.__padamt = 16
|
||||
self.__key = hashlib.sha256(key.encode('utf-8')).digest()
|
||||
|
||||
def __pad(self, s: str) -> str:
|
||||
def _pad(self, s: str) -> str:
|
||||
intermediate = f"{len(s)}.{s}"
|
||||
while len(intermediate) % self.__padamt != 0:
|
||||
intermediate = intermediate + '-'
|
||||
return intermediate
|
||||
|
||||
def __unpad(self, s: str) -> str:
|
||||
def _unpad(self, s: str) -> str:
|
||||
length, string = s.split('.', 1)
|
||||
intlength = int(length)
|
||||
return string[:intlength]
|
||||
|
||||
def encrypt(self, raw: str) -> str:
|
||||
raw = self.__pad(raw)
|
||||
raw = self._pad(raw)
|
||||
random = Random.new()
|
||||
iv = random.read(AES.block_size)
|
||||
cipher = AES.new(self.__key, AES.MODE_CBC, iv)
|
||||
@ -35,4 +35,4 @@ class AESCipher:
|
||||
enc = base64.b64decode(encoded.encode('utf-8'), altchars=b"._")
|
||||
iv = enc[:AES.block_size]
|
||||
cipher = AES.new(self.__key, AES.MODE_CBC, iv)
|
||||
return self.__unpad(cipher.decrypt(enc[AES.block_size:]).decode('utf-8'))
|
||||
return self._unpad(cipher.decrypt(enc[AES.block_size:]).decode('utf-8'))
|
||||
|
@ -1,4 +1,4 @@
|
||||
from typing import List
|
||||
from typing import Dict, Final, List
|
||||
|
||||
|
||||
class CardCipherException(Exception):
|
||||
@ -13,7 +13,7 @@ class CardCipher:
|
||||
Tau and converted ham-fistedly to Python.
|
||||
"""
|
||||
|
||||
KEY = [
|
||||
KEY: Final[List[int]] = [
|
||||
0x20d0d03c, 0x868ecb41, 0xbcd89c84, 0x4c0e0d0d,
|
||||
0x84fc30ac, 0x4cc1890e, 0xfc5418a4, 0x02c50f44,
|
||||
0x68acb4e0, 0x06cd4a4e, 0xcc28906c, 0x4f0c8ac0,
|
||||
@ -40,7 +40,7 @@ class CardCipher:
|
||||
0x60443ce4, 0x4c0b8b8d, 0xe054e8bc, 0x02008e89,
|
||||
]
|
||||
|
||||
LUT_A0 = [
|
||||
LUT_A0: Final[List[int]] = [
|
||||
0x02080008, 0x02082000, 0x00002008, 0x00000000,
|
||||
0x02002000, 0x00080008, 0x02080000, 0x02082008,
|
||||
0x00000008, 0x02000000, 0x00082000, 0x00002008,
|
||||
@ -59,7 +59,7 @@ class CardCipher:
|
||||
0x02000000, 0x02080008, 0x00002000, 0x00082008,
|
||||
]
|
||||
|
||||
LUT_A1 = [
|
||||
LUT_A1: Final[List[int]] = [
|
||||
0x08000004, 0x00020004, 0x00000000, 0x08020200,
|
||||
0x00020004, 0x00000200, 0x08000204, 0x00020000,
|
||||
0x00000204, 0x08020204, 0x00020200, 0x08000000,
|
||||
@ -78,7 +78,7 @@ class CardCipher:
|
||||
0x08020000, 0x00000204, 0x00000004, 0x08020004,
|
||||
]
|
||||
|
||||
LUT_A2 = [
|
||||
LUT_A2: Final[List[int]] = [
|
||||
0x80040100, 0x01000100, 0x80000000, 0x81040100,
|
||||
0x00000000, 0x01040000, 0x81000100, 0x80040000,
|
||||
0x01040100, 0x81000000, 0x01000000, 0x80000100,
|
||||
@ -97,7 +97,7 @@ class CardCipher:
|
||||
0x80000100, 0x01000000, 0x81000000, 0x01040100,
|
||||
]
|
||||
|
||||
LUT_A3 = [
|
||||
LUT_A3: Final[List[int]] = [
|
||||
0x04010801, 0x00000000, 0x00010800, 0x04010000,
|
||||
0x04000001, 0x00000801, 0x04000800, 0x00010800,
|
||||
0x00000800, 0x04010001, 0x00000001, 0x04000800,
|
||||
@ -116,7 +116,7 @@ class CardCipher:
|
||||
0x04000801, 0x00000001, 0x04010000, 0x00010800,
|
||||
]
|
||||
|
||||
LUT_B0 = [
|
||||
LUT_B0: Final[List[int]] = [
|
||||
0x00000400, 0x00000020, 0x00100020, 0x40100000,
|
||||
0x40100420, 0x40000400, 0x00000420, 0x00000000,
|
||||
0x00100000, 0x40100020, 0x40000020, 0x00100400,
|
||||
@ -135,7 +135,7 @@ class CardCipher:
|
||||
0x40100000, 0x00100420, 0x00100400, 0x40000400,
|
||||
]
|
||||
|
||||
LUT_B1 = [
|
||||
LUT_B1: Final[List[int]] = [
|
||||
0x00800000, 0x00001000, 0x00000040, 0x00801042,
|
||||
0x00801002, 0x00800040, 0x00001042, 0x00801000,
|
||||
0x00001000, 0x00000002, 0x00800002, 0x00001040,
|
||||
@ -154,7 +154,7 @@ class CardCipher:
|
||||
0x00000002, 0x00001042, 0x00801000, 0x00800002,
|
||||
]
|
||||
|
||||
LUT_B2 = [
|
||||
LUT_B2: Final[List[int]] = [
|
||||
0x10400000, 0x00404010, 0x00000010, 0x10400010,
|
||||
0x10004000, 0x00400000, 0x10400010, 0x00004010,
|
||||
0x00400010, 0x00004000, 0x00404000, 0x10000000,
|
||||
@ -173,7 +173,7 @@ class CardCipher:
|
||||
0x10400000, 0x10004010, 0x00000010, 0x00404000,
|
||||
]
|
||||
|
||||
LUT_B3 = [
|
||||
LUT_B3: Final[List[int]] = [
|
||||
0x00208080, 0x00008000, 0x20200000, 0x20208080,
|
||||
0x00200000, 0x20008080, 0x20008000, 0x20200000,
|
||||
0x20008080, 0x00208080, 0x00208000, 0x20000080,
|
||||
@ -192,8 +192,8 @@ class CardCipher:
|
||||
0x20000000, 0x20208000, 0x00000080, 0x20008080,
|
||||
]
|
||||
|
||||
VALID_CHARS = "0123456789ABCDEFGHJKLMNPRSTUWXYZ"
|
||||
CONV_CHARS = {
|
||||
VALID_CHARS: Final[str] = "0123456789ABCDEFGHJKLMNPRSTUWXYZ"
|
||||
CONV_CHARS: Final[Dict[str, str]] = {
|
||||
"I": "1",
|
||||
"O": "0",
|
||||
}
|
||||
@ -231,7 +231,7 @@ class CardCipher:
|
||||
reverse[7 - i] = cardint[i]
|
||||
|
||||
# Encipher
|
||||
ciphered = CardCipher.__encode(bytes(reverse))
|
||||
ciphered = CardCipher._encode(bytes(reverse))
|
||||
|
||||
# Convert 8 x 8 bit bytes into 13 x 5 bit groups (sort of)
|
||||
bits = [0] * 65
|
||||
@ -330,7 +330,7 @@ class CardCipher:
|
||||
ciphered[int(i / 8)] |= bits[i] << (~i & 7)
|
||||
|
||||
# Decipher and reverse
|
||||
deciphered = CardCipher.__decode(bytes(ciphered))
|
||||
deciphered = CardCipher._decode(bytes(ciphered))
|
||||
reverse = [0] * 8
|
||||
for i in range(0, 8):
|
||||
reverse[i] = deciphered[7 - i]
|
||||
@ -362,7 +362,7 @@ class CardCipher:
|
||||
return checksum
|
||||
|
||||
@staticmethod
|
||||
def __encode(inbytes: bytes) -> bytes:
|
||||
def _encode(inbytes: bytes) -> bytes:
|
||||
if len(inbytes) != 8:
|
||||
raise CardCipherException(
|
||||
f'Expected 8-byte input, got {len(inbytes)}',
|
||||
@ -378,7 +378,7 @@ class CardCipher:
|
||||
return bytes(out)
|
||||
|
||||
@staticmethod
|
||||
def __decode(inbytes: bytes) -> bytes:
|
||||
def _decode(inbytes: bytes) -> bytes:
|
||||
if len(inbytes) != 8:
|
||||
raise CardCipherException(
|
||||
f'Expected 8-byte input, got {len(inbytes)}',
|
||||
|
@ -1,124 +1,127 @@
|
||||
from typing import Final
|
||||
|
||||
|
||||
class GameConstants:
|
||||
BISHI_BASHI = 'bishi'
|
||||
DANCE_EVOLUTION = 'danevo'
|
||||
DDR = 'ddr'
|
||||
IIDX = 'iidx'
|
||||
JUBEAT = 'jubeat'
|
||||
MUSECA = 'museca'
|
||||
POPN_MUSIC = 'pnm'
|
||||
REFLEC_BEAT = 'reflec'
|
||||
SDVX = 'sdvx'
|
||||
BISHI_BASHI: Final[str] = 'bishi'
|
||||
DANCE_EVOLUTION: Final[str] = 'danevo'
|
||||
DDR: Final[str] = 'ddr'
|
||||
IIDX: Final[str] = 'iidx'
|
||||
JUBEAT: Final[str] = 'jubeat'
|
||||
MUSECA: Final[str] = 'museca'
|
||||
POPN_MUSIC: Final[str] = 'pnm'
|
||||
REFLEC_BEAT: Final[str] = 'reflec'
|
||||
SDVX: Final[str] = 'sdvx'
|
||||
|
||||
|
||||
class VersionConstants:
|
||||
BISHI_BASHI_TSBB = 1
|
||||
BISHI_BASHI_TSBB: Final[int] = 1
|
||||
|
||||
DDR_1STMIX = 1
|
||||
DDR_2NDMIX = 2
|
||||
DDR_3RDMIX = 3
|
||||
DDR_4THMIX = 4
|
||||
DDR_5THMIX = 5
|
||||
DDR_6THMIX = 6
|
||||
DDR_7THMIX = 7
|
||||
DDR_EXTREME = 8
|
||||
DDR_SUPERNOVA = 9
|
||||
DDR_SUPERNOVA_2 = 10
|
||||
DDR_X = 11
|
||||
DDR_X2 = 12
|
||||
DDR_X3_VS_2NDMIX = 13
|
||||
DDR_2013 = 14
|
||||
DDR_2014 = 15
|
||||
DDR_ACE = 16
|
||||
DDR_A20 = 17
|
||||
DDR_1STMIX: Final[int] = 1
|
||||
DDR_2NDMIX: Final[int] = 2
|
||||
DDR_3RDMIX: Final[int] = 3
|
||||
DDR_4THMIX: Final[int] = 4
|
||||
DDR_5THMIX: Final[int] = 5
|
||||
DDR_6THMIX: Final[int] = 6
|
||||
DDR_7THMIX: Final[int] = 7
|
||||
DDR_EXTREME: Final[int] = 8
|
||||
DDR_SUPERNOVA: Final[int] = 9
|
||||
DDR_SUPERNOVA_2: Final[int] = 10
|
||||
DDR_X: Final[int] = 11
|
||||
DDR_X2: Final[int] = 12
|
||||
DDR_X3_VS_2NDMIX: Final[int] = 13
|
||||
DDR_2013: Final[int] = 14
|
||||
DDR_2014: Final[int] = 15
|
||||
DDR_ACE: Final[int] = 16
|
||||
DDR_A20: Final[int] = 17
|
||||
|
||||
IIDX = 1
|
||||
IIDX_2ND_STYLE = 2
|
||||
IIDX_3RD_STYLE = 3
|
||||
IIDX_4TH_STYLE = 4
|
||||
IIDX_5TH_STYLE = 5
|
||||
IIDX_6TH_STYLE = 6
|
||||
IIDX_7TH_STYLE = 7
|
||||
IIDX_8TH_STYLE = 8
|
||||
IIDX_9TH_STYLE = 9
|
||||
IIDX_10TH_STYLE = 10
|
||||
IIDX_RED = 11
|
||||
IIDX_HAPPY_SKY = 12
|
||||
IIDX_DISTORTED = 13
|
||||
IIDX_GOLD = 14
|
||||
IIDX_DJ_TROOPERS = 15
|
||||
IIDX_EMPRESS = 16
|
||||
IIDX_SIRIUS = 17
|
||||
IIDX_RESORT_ANTHEM = 18
|
||||
IIDX_LINCLE = 19
|
||||
IIDX_TRICORO = 20
|
||||
IIDX_SPADA = 21
|
||||
IIDX_PENDUAL = 22
|
||||
IIDX_COPULA = 23
|
||||
IIDX_SINOBUZ = 24
|
||||
IIDX_CANNON_BALLERS = 25
|
||||
IIDX: Final[int] = 1
|
||||
IIDX_2ND_STYLE: Final[int] = 2
|
||||
IIDX_3RD_STYLE: Final[int] = 3
|
||||
IIDX_4TH_STYLE: Final[int] = 4
|
||||
IIDX_5TH_STYLE: Final[int] = 5
|
||||
IIDX_6TH_STYLE: Final[int] = 6
|
||||
IIDX_7TH_STYLE: Final[int] = 7
|
||||
IIDX_8TH_STYLE: Final[int] = 8
|
||||
IIDX_9TH_STYLE: Final[int] = 9
|
||||
IIDX_10TH_STYLE: Final[int] = 10
|
||||
IIDX_RED: Final[int] = 11
|
||||
IIDX_HAPPY_SKY: Final[int] = 12
|
||||
IIDX_DISTORTED: Final[int] = 13
|
||||
IIDX_GOLD: Final[int] = 14
|
||||
IIDX_DJ_TROOPERS: Final[int] = 15
|
||||
IIDX_EMPRESS: Final[int] = 16
|
||||
IIDX_SIRIUS: Final[int] = 17
|
||||
IIDX_RESORT_ANTHEM: Final[int] = 18
|
||||
IIDX_LINCLE: Final[int] = 19
|
||||
IIDX_TRICORO: Final[int] = 20
|
||||
IIDX_SPADA: Final[int] = 21
|
||||
IIDX_PENDUAL: Final[int] = 22
|
||||
IIDX_COPULA: Final[int] = 23
|
||||
IIDX_SINOBUZ: Final[int] = 24
|
||||
IIDX_CANNON_BALLERS: Final[int] = 25
|
||||
|
||||
JUBEAT = 1
|
||||
JUBEAT_RIPPLES = 2
|
||||
JUBEAT_RIPPLES_APPEND = 3
|
||||
JUBEAT_KNIT = 4
|
||||
JUBEAT_KNIT_APPEND = 5
|
||||
JUBEAT_COPIOUS = 6
|
||||
JUBEAT_COPIOUS_APPEND = 7
|
||||
JUBEAT_SAUCER = 8
|
||||
JUBEAT_SAUCER_FULFILL = 9
|
||||
JUBEAT_PROP = 10
|
||||
JUBEAT_QUBELL = 11
|
||||
JUBEAT_CLAN = 12
|
||||
JUBEAT_FESTO = 13
|
||||
JUBEAT: Final[int] = 1
|
||||
JUBEAT_RIPPLES: Final[int] = 2
|
||||
JUBEAT_RIPPLES_APPEND: Final[int] = 3
|
||||
JUBEAT_KNIT: Final[int] = 4
|
||||
JUBEAT_KNIT_APPEND: Final[int] = 5
|
||||
JUBEAT_COPIOUS: Final[int] = 6
|
||||
JUBEAT_COPIOUS_APPEND: Final[int] = 7
|
||||
JUBEAT_SAUCER: Final[int] = 8
|
||||
JUBEAT_SAUCER_FULFILL: Final[int] = 9
|
||||
JUBEAT_PROP: Final[int] = 10
|
||||
JUBEAT_QUBELL: Final[int] = 11
|
||||
JUBEAT_CLAN: Final[int] = 12
|
||||
JUBEAT_FESTO: Final[int] = 13
|
||||
|
||||
MUSECA = 1
|
||||
MUSECA_1_PLUS = 2
|
||||
MUSECA: Final[int] = 1
|
||||
MUSECA_1_PLUS: Final[int] = 2
|
||||
|
||||
POPN_MUSIC = 1
|
||||
POPN_MUSIC_2 = 2
|
||||
POPN_MUSIC_3 = 3
|
||||
POPN_MUSIC_4 = 4
|
||||
POPN_MUSIC_5 = 5
|
||||
POPN_MUSIC_6 = 6
|
||||
POPN_MUSIC_7 = 7
|
||||
POPN_MUSIC_8 = 8
|
||||
POPN_MUSIC_9 = 9
|
||||
POPN_MUSIC_10 = 10
|
||||
POPN_MUSIC_11 = 11
|
||||
POPN_MUSIC_IROHA = 12
|
||||
POPN_MUSIC_CARNIVAL = 13
|
||||
POPN_MUSIC_FEVER = 14
|
||||
POPN_MUSIC_ADVENTURE = 15
|
||||
POPN_MUSIC_PARTY = 16
|
||||
POPN_MUSIC_THE_MOVIE = 17
|
||||
POPN_MUSIC_SENGOKU_RETSUDEN = 18
|
||||
POPN_MUSIC_TUNE_STREET = 19
|
||||
POPN_MUSIC_FANTASIA = 20
|
||||
POPN_MUSIC_SUNNY_PARK = 21
|
||||
POPN_MUSIC_LAPISTORIA = 22
|
||||
POPN_MUSIC_ECLALE = 23
|
||||
POPN_MUSIC_USANEKO = 24
|
||||
POPN_MUSIC_PEACE = 25
|
||||
POPN_MUSIC: Final[int] = 1
|
||||
POPN_MUSIC_2: Final[int] = 2
|
||||
POPN_MUSIC_3: Final[int] = 3
|
||||
POPN_MUSIC_4: Final[int] = 4
|
||||
POPN_MUSIC_5: Final[int] = 5
|
||||
POPN_MUSIC_6: Final[int] = 6
|
||||
POPN_MUSIC_7: Final[int] = 7
|
||||
POPN_MUSIC_8: Final[int] = 8
|
||||
POPN_MUSIC_9: Final[int] = 9
|
||||
POPN_MUSIC_10: Final[int] = 10
|
||||
POPN_MUSIC_11: Final[int] = 11
|
||||
POPN_MUSIC_IROHA: Final[int] = 12
|
||||
POPN_MUSIC_CARNIVAL: Final[int] = 13
|
||||
POPN_MUSIC_FEVER: Final[int] = 14
|
||||
POPN_MUSIC_ADVENTURE: Final[int] = 15
|
||||
POPN_MUSIC_PARTY: Final[int] = 16
|
||||
POPN_MUSIC_THE_MOVIE: Final[int] = 17
|
||||
POPN_MUSIC_SENGOKU_RETSUDEN: Final[int] = 18
|
||||
POPN_MUSIC_TUNE_STREET: Final[int] = 19
|
||||
POPN_MUSIC_FANTASIA: Final[int] = 20
|
||||
POPN_MUSIC_SUNNY_PARK: Final[int] = 21
|
||||
POPN_MUSIC_LAPISTORIA: Final[int] = 22
|
||||
POPN_MUSIC_ECLALE: Final[int] = 23
|
||||
POPN_MUSIC_USANEKO: Final[int] = 24
|
||||
POPN_MUSIC_PEACE: Final[int] = 25
|
||||
|
||||
REFLEC_BEAT = 1
|
||||
REFLEC_BEAT_LIMELIGHT = 2
|
||||
REFLEC_BEAT_COLETTE = 3
|
||||
REFLEC_BEAT_GROOVIN = 4
|
||||
REFLEC_BEAT_VOLZZA = 5
|
||||
REFLEC_BEAT_VOLZZA_2 = 6
|
||||
REFLEC_BEAT_REFLESIA = 7
|
||||
REFLEC_BEAT: Final[int] = 1
|
||||
REFLEC_BEAT_LIMELIGHT: Final[int] = 2
|
||||
REFLEC_BEAT_COLETTE: Final[int] = 3
|
||||
REFLEC_BEAT_GROOVIN: Final[int] = 4
|
||||
REFLEC_BEAT_VOLZZA: Final[int] = 5
|
||||
REFLEC_BEAT_VOLZZA_2: Final[int] = 6
|
||||
REFLEC_BEAT_REFLESIA: Final[int] = 7
|
||||
|
||||
SDVX_BOOTH = 1
|
||||
SDVX_INFINITE_INFECTION = 2
|
||||
SDVX_GRAVITY_WARS = 3
|
||||
SDVX_HEAVENLY_HAVEN = 4
|
||||
SDVX_BOOTH: Final[int] = 1
|
||||
SDVX_INFINITE_INFECTION: Final[int] = 2
|
||||
SDVX_GRAVITY_WARS: Final[int] = 3
|
||||
SDVX_HEAVENLY_HAVEN: Final[int] = 4
|
||||
|
||||
|
||||
class APIConstants:
|
||||
ID_TYPE_SERVER = 'server'
|
||||
ID_TYPE_CARD = 'card'
|
||||
ID_TYPE_SONG = 'song'
|
||||
ID_TYPE_INSTANCE = 'instance'
|
||||
ID_TYPE_SERVER: Final[str] = 'server'
|
||||
ID_TYPE_CARD: Final[str] = 'card'
|
||||
ID_TYPE_SONG: Final[str] = 'song'
|
||||
ID_TYPE_INSTANCE: Final[str] = 'instance'
|
||||
|
||||
|
||||
class DBConstants:
|
||||
@ -140,114 +143,114 @@ class DBConstants:
|
||||
# will only be found in the DB itself, as well as used on the frontend
|
||||
# to display various general information about scores.
|
||||
|
||||
OMNIMIX_VERSION_BUMP = 10000
|
||||
OMNIMIX_VERSION_BUMP: Final[int] = 10000
|
||||
|
||||
DDR_HALO_NONE = 100
|
||||
DDR_HALO_GOOD_FULL_COMBO = 200
|
||||
DDR_HALO_GREAT_FULL_COMBO = 300
|
||||
DDR_HALO_PERFECT_FULL_COMBO = 400
|
||||
DDR_HALO_MARVELOUS_FULL_COMBO = 500
|
||||
DDR_RANK_E = 100
|
||||
DDR_RANK_D = 200
|
||||
DDR_RANK_D_PLUS = 233
|
||||
DDR_RANK_C_MINUS = 266
|
||||
DDR_RANK_C = 300
|
||||
DDR_RANK_C_PLUS = 333
|
||||
DDR_RANK_B_MINUS = 366
|
||||
DDR_RANK_B = 400
|
||||
DDR_RANK_B_PLUS = 433
|
||||
DDR_RANK_A_MINUS = 466
|
||||
DDR_RANK_A = 500
|
||||
DDR_RANK_A_PLUS = 533
|
||||
DDR_RANK_AA_MINUS = 566
|
||||
DDR_RANK_AA = 600
|
||||
DDR_RANK_AA_PLUS = 650
|
||||
DDR_RANK_AAA = 700
|
||||
DDR_HALO_NONE: Final[int] = 100
|
||||
DDR_HALO_GOOD_FULL_COMBO: Final[int] = 200
|
||||
DDR_HALO_GREAT_FULL_COMBO: Final[int] = 300
|
||||
DDR_HALO_PERFECT_FULL_COMBO: Final[int] = 400
|
||||
DDR_HALO_MARVELOUS_FULL_COMBO: Final[int] = 500
|
||||
DDR_RANK_E: Final[int] = 100
|
||||
DDR_RANK_D: Final[int] = 200
|
||||
DDR_RANK_D_PLUS: Final[int] = 233
|
||||
DDR_RANK_C_MINUS: Final[int] = 266
|
||||
DDR_RANK_C: Final[int] = 300
|
||||
DDR_RANK_C_PLUS: Final[int] = 333
|
||||
DDR_RANK_B_MINUS: Final[int] = 366
|
||||
DDR_RANK_B: Final[int] = 400
|
||||
DDR_RANK_B_PLUS: Final[int] = 433
|
||||
DDR_RANK_A_MINUS: Final[int] = 466
|
||||
DDR_RANK_A: Final[int] = 500
|
||||
DDR_RANK_A_PLUS: Final[int] = 533
|
||||
DDR_RANK_AA_MINUS: Final[int] = 566
|
||||
DDR_RANK_AA: Final[int] = 600
|
||||
DDR_RANK_AA_PLUS: Final[int] = 650
|
||||
DDR_RANK_AAA: Final[int] = 700
|
||||
|
||||
IIDX_CLEAR_STATUS_NO_PLAY = 50
|
||||
IIDX_CLEAR_STATUS_FAILED = 100
|
||||
IIDX_CLEAR_STATUS_ASSIST_CLEAR = 200
|
||||
IIDX_CLEAR_STATUS_EASY_CLEAR = 300
|
||||
IIDX_CLEAR_STATUS_CLEAR = 400
|
||||
IIDX_CLEAR_STATUS_HARD_CLEAR = 500
|
||||
IIDX_CLEAR_STATUS_EX_HARD_CLEAR = 600
|
||||
IIDX_CLEAR_STATUS_FULL_COMBO = 700
|
||||
IIDX_DAN_RANK_7_KYU = 100
|
||||
IIDX_DAN_RANK_6_KYU = 200
|
||||
IIDX_DAN_RANK_5_KYU = 300
|
||||
IIDX_DAN_RANK_4_KYU = 400
|
||||
IIDX_DAN_RANK_3_KYU = 500
|
||||
IIDX_DAN_RANK_2_KYU = 600
|
||||
IIDX_DAN_RANK_1_KYU = 700
|
||||
IIDX_DAN_RANK_1_DAN = 800
|
||||
IIDX_DAN_RANK_2_DAN = 900
|
||||
IIDX_DAN_RANK_3_DAN = 1000
|
||||
IIDX_DAN_RANK_4_DAN = 1100
|
||||
IIDX_DAN_RANK_5_DAN = 1200
|
||||
IIDX_DAN_RANK_6_DAN = 1300
|
||||
IIDX_DAN_RANK_7_DAN = 1400
|
||||
IIDX_DAN_RANK_8_DAN = 1500
|
||||
IIDX_DAN_RANK_9_DAN = 1600
|
||||
IIDX_DAN_RANK_10_DAN = 1700
|
||||
IIDX_DAN_RANK_CHUDEN = 1800
|
||||
IIDX_DAN_RANK_KAIDEN = 1900
|
||||
IIDX_CLEAR_STATUS_NO_PLAY: Final[int] = 50
|
||||
IIDX_CLEAR_STATUS_FAILED: Final[int] = 100
|
||||
IIDX_CLEAR_STATUS_ASSIST_CLEAR: Final[int] = 200
|
||||
IIDX_CLEAR_STATUS_EASY_CLEAR: Final[int] = 300
|
||||
IIDX_CLEAR_STATUS_CLEAR: Final[int] = 400
|
||||
IIDX_CLEAR_STATUS_HARD_CLEAR: Final[int] = 500
|
||||
IIDX_CLEAR_STATUS_EX_HARD_CLEAR: Final[int] = 600
|
||||
IIDX_CLEAR_STATUS_FULL_COMBO: Final[int] = 700
|
||||
IIDX_DAN_RANK_7_KYU: Final[int] = 100
|
||||
IIDX_DAN_RANK_6_KYU: Final[int] = 200
|
||||
IIDX_DAN_RANK_5_KYU: Final[int] = 300
|
||||
IIDX_DAN_RANK_4_KYU: Final[int] = 400
|
||||
IIDX_DAN_RANK_3_KYU: Final[int] = 500
|
||||
IIDX_DAN_RANK_2_KYU: Final[int] = 600
|
||||
IIDX_DAN_RANK_1_KYU: Final[int] = 700
|
||||
IIDX_DAN_RANK_1_DAN: Final[int] = 800
|
||||
IIDX_DAN_RANK_2_DAN: Final[int] = 900
|
||||
IIDX_DAN_RANK_3_DAN: Final[int] = 1000
|
||||
IIDX_DAN_RANK_4_DAN: Final[int] = 1100
|
||||
IIDX_DAN_RANK_5_DAN: Final[int] = 1200
|
||||
IIDX_DAN_RANK_6_DAN: Final[int] = 1300
|
||||
IIDX_DAN_RANK_7_DAN: Final[int] = 1400
|
||||
IIDX_DAN_RANK_8_DAN: Final[int] = 1500
|
||||
IIDX_DAN_RANK_9_DAN: Final[int] = 1600
|
||||
IIDX_DAN_RANK_10_DAN: Final[int] = 1700
|
||||
IIDX_DAN_RANK_CHUDEN: Final[int] = 1800
|
||||
IIDX_DAN_RANK_KAIDEN: Final[int] = 1900
|
||||
|
||||
JUBEAT_PLAY_MEDAL_FAILED = 100
|
||||
JUBEAT_PLAY_MEDAL_CLEARED = 200
|
||||
JUBEAT_PLAY_MEDAL_NEARLY_FULL_COMBO = 300
|
||||
JUBEAT_PLAY_MEDAL_FULL_COMBO = 400
|
||||
JUBEAT_PLAY_MEDAL_NEARLY_EXCELLENT = 500
|
||||
JUBEAT_PLAY_MEDAL_EXCELLENT = 600
|
||||
JUBEAT_PLAY_MEDAL_FAILED: Final[int] = 100
|
||||
JUBEAT_PLAY_MEDAL_CLEARED: Final[int] = 200
|
||||
JUBEAT_PLAY_MEDAL_NEARLY_FULL_COMBO: Final[int] = 300
|
||||
JUBEAT_PLAY_MEDAL_FULL_COMBO: Final[int] = 400
|
||||
JUBEAT_PLAY_MEDAL_NEARLY_EXCELLENT: Final[int] = 500
|
||||
JUBEAT_PLAY_MEDAL_EXCELLENT: Final[int] = 600
|
||||
|
||||
MUSECA_GRADE_DEATH = 100 # 没
|
||||
MUSECA_GRADE_POOR = 200 # 拙
|
||||
MUSECA_GRADE_MEDIOCRE = 300 # 凡
|
||||
MUSECA_GRADE_GOOD = 400 # 佳
|
||||
MUSECA_GRADE_GREAT = 500 # 良
|
||||
MUSECA_GRADE_EXCELLENT = 600 # 優
|
||||
MUSECA_GRADE_SUPERB = 700 # 秀
|
||||
MUSECA_GRADE_MASTERPIECE = 800 # 傑
|
||||
MUSECA_GRADE_PERFECT = 900 # 傑
|
||||
MUSECA_CLEAR_TYPE_FAILED = 100
|
||||
MUSECA_CLEAR_TYPE_CLEARED = 200
|
||||
MUSECA_CLEAR_TYPE_FULL_COMBO = 300
|
||||
MUSECA_GRADE_DEATH: Final[int] = 100 # 没
|
||||
MUSECA_GRADE_POOR: Final[int] = 200 # 拙
|
||||
MUSECA_GRADE_MEDIOCRE: Final[int] = 300 # 凡
|
||||
MUSECA_GRADE_GOOD: Final[int] = 400 # 佳
|
||||
MUSECA_GRADE_GREAT: Final[int] = 500 # 良
|
||||
MUSECA_GRADE_EXCELLENT: Final[int] = 600 # 優
|
||||
MUSECA_GRADE_SUPERB: Final[int] = 700 # 秀
|
||||
MUSECA_GRADE_MASTERPIECE: Final[int] = 800 # 傑
|
||||
MUSECA_GRADE_PERFECT: Final[int] = 900 # 傑
|
||||
MUSECA_CLEAR_TYPE_FAILED: Final[int] = 100
|
||||
MUSECA_CLEAR_TYPE_CLEARED: Final[int] = 200
|
||||
MUSECA_CLEAR_TYPE_FULL_COMBO: Final[int] = 300
|
||||
|
||||
POPN_MUSIC_PLAY_MEDAL_CIRCLE_FAILED = 100
|
||||
POPN_MUSIC_PLAY_MEDAL_DIAMOND_FAILED = 200
|
||||
POPN_MUSIC_PLAY_MEDAL_STAR_FAILED = 300
|
||||
POPN_MUSIC_PLAY_MEDAL_EASY_CLEAR = 400
|
||||
POPN_MUSIC_PLAY_MEDAL_CIRCLE_CLEARED = 500
|
||||
POPN_MUSIC_PLAY_MEDAL_DIAMOND_CLEARED = 600
|
||||
POPN_MUSIC_PLAY_MEDAL_STAR_CLEARED = 700
|
||||
POPN_MUSIC_PLAY_MEDAL_CIRCLE_FULL_COMBO = 800
|
||||
POPN_MUSIC_PLAY_MEDAL_DIAMOND_FULL_COMBO = 900
|
||||
POPN_MUSIC_PLAY_MEDAL_STAR_FULL_COMBO = 1000
|
||||
POPN_MUSIC_PLAY_MEDAL_PERFECT = 1100
|
||||
POPN_MUSIC_PLAY_MEDAL_CIRCLE_FAILED: Final[int] = 100
|
||||
POPN_MUSIC_PLAY_MEDAL_DIAMOND_FAILED: Final[int] = 200
|
||||
POPN_MUSIC_PLAY_MEDAL_STAR_FAILED: Final[int] = 300
|
||||
POPN_MUSIC_PLAY_MEDAL_EASY_CLEAR: Final[int] = 400
|
||||
POPN_MUSIC_PLAY_MEDAL_CIRCLE_CLEARED: Final[int] = 500
|
||||
POPN_MUSIC_PLAY_MEDAL_DIAMOND_CLEARED: Final[int] = 600
|
||||
POPN_MUSIC_PLAY_MEDAL_STAR_CLEARED: Final[int] = 700
|
||||
POPN_MUSIC_PLAY_MEDAL_CIRCLE_FULL_COMBO: Final[int] = 800
|
||||
POPN_MUSIC_PLAY_MEDAL_DIAMOND_FULL_COMBO: Final[int] = 900
|
||||
POPN_MUSIC_PLAY_MEDAL_STAR_FULL_COMBO: Final[int] = 1000
|
||||
POPN_MUSIC_PLAY_MEDAL_PERFECT: Final[int] = 1100
|
||||
|
||||
REFLEC_BEAT_CLEAR_TYPE_NO_PLAY = 100
|
||||
REFLEC_BEAT_CLEAR_TYPE_FAILED = 200
|
||||
REFLEC_BEAT_CLEAR_TYPE_CLEARED = 300
|
||||
REFLEC_BEAT_CLEAR_TYPE_HARD_CLEARED = 400
|
||||
REFLEC_BEAT_CLEAR_TYPE_S_HARD_CLEARED = 500
|
||||
REFLEC_BEAT_COMBO_TYPE_NONE = 100
|
||||
REFLEC_BEAT_COMBO_TYPE_ALMOST_COMBO = 200
|
||||
REFLEC_BEAT_COMBO_TYPE_FULL_COMBO = 300
|
||||
REFLEC_BEAT_COMBO_TYPE_FULL_COMBO_ALL_JUST = 400
|
||||
REFLEC_BEAT_CLEAR_TYPE_NO_PLAY: Final[int] = 100
|
||||
REFLEC_BEAT_CLEAR_TYPE_FAILED: Final[int] = 200
|
||||
REFLEC_BEAT_CLEAR_TYPE_CLEARED: Final[int] = 300
|
||||
REFLEC_BEAT_CLEAR_TYPE_HARD_CLEARED: Final[int] = 400
|
||||
REFLEC_BEAT_CLEAR_TYPE_S_HARD_CLEARED: Final[int] = 500
|
||||
REFLEC_BEAT_COMBO_TYPE_NONE: Final[int] = 100
|
||||
REFLEC_BEAT_COMBO_TYPE_ALMOST_COMBO: Final[int] = 200
|
||||
REFLEC_BEAT_COMBO_TYPE_FULL_COMBO: Final[int] = 300
|
||||
REFLEC_BEAT_COMBO_TYPE_FULL_COMBO_ALL_JUST: Final[int] = 400
|
||||
|
||||
SDVX_CLEAR_TYPE_NO_PLAY = 50
|
||||
SDVX_CLEAR_TYPE_FAILED = 100
|
||||
SDVX_CLEAR_TYPE_CLEAR = 200
|
||||
SDVX_CLEAR_TYPE_HARD_CLEAR = 300
|
||||
SDVX_CLEAR_TYPE_ULTIMATE_CHAIN = 400
|
||||
SDVX_CLEAR_TYPE_PERFECT_ULTIMATE_CHAIN = 500
|
||||
SDVX_GRADE_NO_PLAY = 100
|
||||
SDVX_GRADE_D = 200
|
||||
SDVX_GRADE_C = 300
|
||||
SDVX_GRADE_B = 400
|
||||
SDVX_GRADE_A = 500
|
||||
SDVX_GRADE_A_PLUS = 550
|
||||
SDVX_GRADE_AA = 600
|
||||
SDVX_GRADE_AA_PLUS = 650
|
||||
SDVX_GRADE_AAA = 700
|
||||
SDVX_GRADE_AAA_PLUS = 800
|
||||
SDVX_GRADE_S = 900
|
||||
SDVX_CLEAR_TYPE_NO_PLAY: Final[int] = 50
|
||||
SDVX_CLEAR_TYPE_FAILED: Final[int] = 100
|
||||
SDVX_CLEAR_TYPE_CLEAR: Final[int] = 200
|
||||
SDVX_CLEAR_TYPE_HARD_CLEAR: Final[int] = 300
|
||||
SDVX_CLEAR_TYPE_ULTIMATE_CHAIN: Final[int] = 400
|
||||
SDVX_CLEAR_TYPE_PERFECT_ULTIMATE_CHAIN: Final[int] = 500
|
||||
SDVX_GRADE_NO_PLAY: Final[int] = 100
|
||||
SDVX_GRADE_D: Final[int] = 200
|
||||
SDVX_GRADE_C: Final[int] = 300
|
||||
SDVX_GRADE_B: Final[int] = 400
|
||||
SDVX_GRADE_A: Final[int] = 500
|
||||
SDVX_GRADE_A_PLUS: Final[int] = 550
|
||||
SDVX_GRADE_AA: Final[int] = 600
|
||||
SDVX_GRADE_AA_PLUS: Final[int] = 650
|
||||
SDVX_GRADE_AAA: Final[int] = 700
|
||||
SDVX_GRADE_AAA_PLUS: Final[int] = 800
|
||||
SDVX_GRADE_S: Final[int] = 900
|
||||
|
@ -2,7 +2,7 @@ import calendar
|
||||
import datetime
|
||||
from dateutil import tz
|
||||
|
||||
from typing import List, Optional
|
||||
from typing import List, Final, Optional
|
||||
|
||||
|
||||
class Time:
|
||||
@ -11,10 +11,10 @@ class Time:
|
||||
standard unix timestamps at UTC timezone given various parameters.
|
||||
"""
|
||||
|
||||
SECONDS_IN_MINUTE = 60
|
||||
SECONDS_IN_HOUR = 3600
|
||||
SECONDS_IN_DAY = 86400
|
||||
SECONDS_IN_WEEK = 604800
|
||||
SECONDS_IN_MINUTE: Final[int] = 60
|
||||
SECONDS_IN_HOUR: Final[int] = 3600
|
||||
SECONDS_IN_DAY: Final[int] = 86400
|
||||
SECONDS_IN_WEEK: Final[int] = 604800
|
||||
|
||||
@staticmethod
|
||||
def now() -> int:
|
||||
|
@ -1,5 +1,5 @@
|
||||
import struct
|
||||
from typing import Optional, List, Dict, Any
|
||||
from typing import Optional, Final, List, Dict, Any
|
||||
|
||||
from bemani.protocol.stream import InputStream, OutputStream
|
||||
from bemani.protocol.node import Node
|
||||
@ -708,17 +708,17 @@ class BinaryEncoding:
|
||||
"""
|
||||
Wrapper class representing a Binary Encoding.
|
||||
"""
|
||||
MAGIC = 0xA0
|
||||
MAGIC: Final[int] = 0xA0
|
||||
|
||||
COMPRESSED_WITH_DATA = 0x42
|
||||
COMPRESSED_WITHOUT_DATA = 0x43
|
||||
DECOMPRESSED_WITH_DATA = 0x45
|
||||
DECOMPRESSED_WITHOUT_DATA = 0x46
|
||||
COMPRESSED_WITH_DATA: Final[int] = 0x42
|
||||
COMPRESSED_WITHOUT_DATA: Final[int] = 0x43
|
||||
DECOMPRESSED_WITH_DATA: Final[int] = 0x45
|
||||
DECOMPRESSED_WITHOUT_DATA: Final[int] = 0x46
|
||||
|
||||
# The string values should match the constants in EAmuseProtocol.
|
||||
# I have no better way to link these than to write this comment,
|
||||
# as otherwise we would have a circular dependency.
|
||||
ENCODINGS = {
|
||||
ENCODINGS: Final[Dict[int, str]] = {
|
||||
0x00: "ascii",
|
||||
0x20: "shift-jis-legacy",
|
||||
0x60: "euc-jp",
|
||||
|
@ -1,13 +1,15 @@
|
||||
import ctypes
|
||||
import os
|
||||
from collections import defaultdict
|
||||
from typing import Generator, List, MutableMapping, Optional, Set, Tuple
|
||||
from typing import Generator, Final, List, MutableMapping, Optional, Set, Tuple
|
||||
|
||||
from .. import package_root
|
||||
|
||||
|
||||
# Attempt to use the faster C++ libraries if they're available
|
||||
try:
|
||||
clib = None
|
||||
clib_path = os.path.dirname(os.path.abspath(__file__))
|
||||
clib_path = os.path.join(package_root, "protocol")
|
||||
files = [f for f in os.listdir(clib_path) if f.startswith("lz77cpp") and f.endswith(".so")]
|
||||
if len(files) > 0:
|
||||
clib = ctypes.cdll.LoadLibrary(os.path.join(clib_path, files[0]))
|
||||
@ -32,10 +34,10 @@ class Lz77Decompress:
|
||||
over-the-wire compression of XML data, as well as compression inside a decent
|
||||
amount of file formats found in various Konami games.
|
||||
"""
|
||||
RING_LENGTH = 0x1000
|
||||
RING_LENGTH: Final[int] = 0x1000
|
||||
|
||||
FLAG_COPY = 1
|
||||
FLAG_BACKREF = 0
|
||||
FLAG_COPY: Final[int] = 1
|
||||
FLAG_BACKREF: Final[int] = 0
|
||||
|
||||
def __init__(self, data: bytes, backref: Optional[int] = None) -> None:
|
||||
"""
|
||||
@ -56,7 +58,7 @@ class Lz77Decompress:
|
||||
self.ringlength: int = backref or self.RING_LENGTH
|
||||
self.ring: bytes = b'\x00' * self.ringlength
|
||||
|
||||
def __ring_read(self, copy_pos: int, copy_len: int) -> Generator[bytes, None, None]:
|
||||
def _ring_read(self, copy_pos: int, copy_len: int) -> Generator[bytes, None, None]:
|
||||
"""
|
||||
Read the next bytes from the backref ring at the current copy position.
|
||||
|
||||
@ -72,13 +74,13 @@ class Lz77Decompress:
|
||||
amount = copy_len
|
||||
|
||||
ret = self.ring[copy_pos:(copy_pos + amount)]
|
||||
self.__ring_write(ret)
|
||||
self._ring_write(ret)
|
||||
yield ret
|
||||
|
||||
copy_pos = (copy_pos + amount) % self.ringlength
|
||||
copy_len -= amount
|
||||
|
||||
def __ring_write(self, bytedata: bytes) -> None:
|
||||
def _ring_write(self, bytedata: bytes) -> None:
|
||||
"""
|
||||
Write bytes into the backref ring.
|
||||
|
||||
@ -117,7 +119,7 @@ class Lz77Decompress:
|
||||
# ringbuffer). So, since we read that last time and wrote it to the backbuffer
|
||||
# we are safe to read again.
|
||||
amount = min(self.pending_copy_amount, self.pending_copy_max)
|
||||
yield from self.__ring_read(self.pending_copy_pos, amount)
|
||||
yield from self._ring_read(self.pending_copy_pos, amount)
|
||||
|
||||
# We read this many bytes and are about to write them to the ringbuffer,
|
||||
# so bookkeep that.
|
||||
@ -149,17 +151,17 @@ class Lz77Decompress:
|
||||
|
||||
# Grab chunk right out of the data source
|
||||
b = self.data[self.read_pos:(self.read_pos + amount)]
|
||||
self.__ring_write(b)
|
||||
self._ring_write(b)
|
||||
yield b
|
||||
|
||||
self.read_pos += amount
|
||||
self.left -= amount
|
||||
elif flag == self.FLAG_BACKREF:
|
||||
yield from self.__read_backref()
|
||||
yield from self._read_backref()
|
||||
else:
|
||||
raise Exception("Logic error!")
|
||||
|
||||
def __read_backref(self) -> Generator[bytes, None, None]:
|
||||
def _read_backref(self) -> Generator[bytes, None, None]:
|
||||
"""
|
||||
Read a backref chunk. Grab the copy length and copy position
|
||||
from the first two bytes and then read the first byte from
|
||||
@ -204,7 +206,7 @@ class Lz77Decompress:
|
||||
while copy_pos < 0:
|
||||
copy_pos += self.ringlength
|
||||
copy_pos = copy_pos % self.ringlength
|
||||
yield from self.__ring_read(copy_pos, copy_len)
|
||||
yield from self._ring_read(copy_pos, copy_len)
|
||||
else:
|
||||
self.eof = True
|
||||
return
|
||||
@ -221,12 +223,12 @@ class Lz77Compress:
|
||||
once, and if we use a proxy to direct traffic, possibly a second time.
|
||||
"""
|
||||
|
||||
RING_LENGTH = 0x1000
|
||||
RING_LENGTH: Final[int] = 0x1000
|
||||
|
||||
LOOSE_COMPRESS_THRESHOLD = 1024 * 512
|
||||
LOOSE_COMPRESS_THRESHOLD: Final[int] = 1024 * 512
|
||||
|
||||
FLAG_COPY = 1
|
||||
FLAG_BACKREF = 0
|
||||
FLAG_COPY: Final[int] = 1
|
||||
FLAG_BACKREF: Final[int] = 0
|
||||
|
||||
def __init__(self, data: bytes, backref: Optional[int] = None) -> None:
|
||||
"""
|
||||
@ -246,11 +248,11 @@ class Lz77Compress:
|
||||
self.last_start: Tuple[int, int, int] = (0, 0, 0)
|
||||
|
||||
if len(data) > self.LOOSE_COMPRESS_THRESHOLD:
|
||||
self.__ring_write = self.__ring_write_starts_only
|
||||
self._ring_write = self._ring_write_starts_only
|
||||
else:
|
||||
self.__ring_write = self.__ring_write_both
|
||||
self._ring_write = self._ring_write_both
|
||||
|
||||
def __ring_write_starts_only(self, bytedata: bytes) -> None:
|
||||
def _ring_write_starts_only(self, bytedata: bytes) -> None:
|
||||
"""
|
||||
Write bytes into the backref ring.
|
||||
|
||||
@ -266,7 +268,7 @@ class Lz77Compress:
|
||||
# Keep track of the fact that we wrote this byte.
|
||||
self.bytes_written += 1
|
||||
|
||||
def __ring_write_both(self, bytedata: bytes) -> None:
|
||||
def _ring_write_both(self, bytedata: bytes) -> None:
|
||||
"""
|
||||
Write bytes into the backref ring.
|
||||
|
||||
@ -321,7 +323,7 @@ class Lz77Compress:
|
||||
|
||||
chunk = self.data[self.read_pos:(self.read_pos + 1)]
|
||||
data[flagpos] = chunk
|
||||
self.__ring_write(chunk)
|
||||
self._ring_write(chunk)
|
||||
|
||||
self.read_pos += 1
|
||||
self.left -= 1
|
||||
@ -346,7 +348,7 @@ class Lz77Compress:
|
||||
|
||||
chunk = self.data[self.read_pos:(self.read_pos + 1)]
|
||||
data[flagpos] = chunk
|
||||
self.__ring_write(chunk)
|
||||
self._ring_write(chunk)
|
||||
|
||||
self.read_pos += 1
|
||||
self.left -= 1
|
||||
@ -356,7 +358,7 @@ class Lz77Compress:
|
||||
# we're going to write at least these three bytes, so append it to the
|
||||
# output buffer.
|
||||
start_write_size = self.bytes_written
|
||||
self.__ring_write(index)
|
||||
self._ring_write(index)
|
||||
copy_amount = 3
|
||||
while copy_amount < backref_amount:
|
||||
# First, let's see if we have any 3-wide chunks to consume.
|
||||
@ -369,7 +371,7 @@ class Lz77Compress:
|
||||
|
||||
if new_backref_locations:
|
||||
# Mark that we're copying an extra byte from the backref.
|
||||
self.__ring_write(index)
|
||||
self._ring_write(index)
|
||||
copy_amount += 3
|
||||
possible_backref_locations = new_backref_locations
|
||||
else:
|
||||
@ -388,7 +390,7 @@ class Lz77Compress:
|
||||
break
|
||||
|
||||
# Mark that we're copying an extra byte from the backref.
|
||||
self.__ring_write(self.data[(self.read_pos + copy_amount):(self.read_pos + copy_amount + 1)])
|
||||
self._ring_write(self.data[(self.read_pos + copy_amount):(self.read_pos + copy_amount + 1)])
|
||||
copy_amount += 1
|
||||
possible_backref_locations = new_backref_locations
|
||||
|
||||
|
@ -1,6 +1,11 @@
|
||||
import copy
|
||||
import struct
|
||||
from typing import Any, Dict, List, Optional, Union
|
||||
from typing import Any, Dict, Final, List, Optional, Union
|
||||
|
||||
|
||||
# Hack to get around mypy's lack of scoping on types.
|
||||
_renamed_float = float
|
||||
_renamed_bool = bool
|
||||
|
||||
|
||||
class NodeException(Exception):
|
||||
@ -16,60 +21,60 @@ class Node:
|
||||
supported for a node to not have a value or children. This also includes a decent amount of
|
||||
constructor helper classmethods to make constructing a tree from source code easier.
|
||||
"""
|
||||
NODE_NAME_CHARS = "0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
|
||||
NODE_NAME_CHARS: Final[str] = "0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
NODE_TYPE_VOID = 1
|
||||
NODE_TYPE_S8 = 2
|
||||
NODE_TYPE_U8 = 3
|
||||
NODE_TYPE_S16 = 4
|
||||
NODE_TYPE_U16 = 5
|
||||
NODE_TYPE_S32 = 6
|
||||
NODE_TYPE_U32 = 7
|
||||
NODE_TYPE_S64 = 8
|
||||
NODE_TYPE_U64 = 9
|
||||
NODE_TYPE_BIN = 10
|
||||
NODE_TYPE_STR = 11
|
||||
NODE_TYPE_IP4 = 12
|
||||
NODE_TYPE_TIME = 13
|
||||
NODE_TYPE_FLOAT = 14
|
||||
NODE_TYPE_DOUBLE = 15
|
||||
NODE_TYPE_VOID: Final[int] = 1
|
||||
NODE_TYPE_S8: Final[int] = 2
|
||||
NODE_TYPE_U8: Final[int] = 3
|
||||
NODE_TYPE_S16: Final[int] = 4
|
||||
NODE_TYPE_U16: Final[int] = 5
|
||||
NODE_TYPE_S32: Final[int] = 6
|
||||
NODE_TYPE_U32: Final[int] = 7
|
||||
NODE_TYPE_S64: Final[int] = 8
|
||||
NODE_TYPE_U64: Final[int] = 9
|
||||
NODE_TYPE_BIN: Final[int] = 10
|
||||
NODE_TYPE_STR: Final[int] = 11
|
||||
NODE_TYPE_IP4: Final[int] = 12
|
||||
NODE_TYPE_TIME: Final[int] = 13
|
||||
NODE_TYPE_FLOAT: Final[int] = 14
|
||||
NODE_TYPE_DOUBLE: Final[int] = 15
|
||||
|
||||
NODE_TYPE_2S8 = 16
|
||||
NODE_TYPE_2U8 = 17
|
||||
NODE_TYPE_2S16 = 18
|
||||
NODE_TYPE_2U16 = 19
|
||||
NODE_TYPE_2S32 = 20
|
||||
NODE_TYPE_2U32 = 21
|
||||
NODE_TYPE_2S64 = 22
|
||||
NODE_TYPE_2U64 = 23
|
||||
NODE_TYPE_2FLOAT = 24
|
||||
NODE_TYPE_2DOUBLE = 25
|
||||
NODE_TYPE_2S8: Final[int] = 16
|
||||
NODE_TYPE_2U8: Final[int] = 17
|
||||
NODE_TYPE_2S16: Final[int] = 18
|
||||
NODE_TYPE_2U16: Final[int] = 19
|
||||
NODE_TYPE_2S32: Final[int] = 20
|
||||
NODE_TYPE_2U32: Final[int] = 21
|
||||
NODE_TYPE_2S64: Final[int] = 22
|
||||
NODE_TYPE_2U64: Final[int] = 23
|
||||
NODE_TYPE_2FLOAT: Final[int] = 24
|
||||
NODE_TYPE_2DOUBLE: Final[int] = 25
|
||||
|
||||
NODE_TYPE_3S8 = 26
|
||||
NODE_TYPE_3U8 = 27
|
||||
NODE_TYPE_3S16 = 28
|
||||
NODE_TYPE_3U16 = 29
|
||||
NODE_TYPE_3S32 = 30
|
||||
NODE_TYPE_3U32 = 31
|
||||
NODE_TYPE_3S64 = 32
|
||||
NODE_TYPE_3U64 = 33
|
||||
NODE_TYPE_3FLOAT = 34
|
||||
NODE_TYPE_3DOUBLE = 35
|
||||
NODE_TYPE_3S8: Final[int] = 26
|
||||
NODE_TYPE_3U8: Final[int] = 27
|
||||
NODE_TYPE_3S16: Final[int] = 28
|
||||
NODE_TYPE_3U16: Final[int] = 29
|
||||
NODE_TYPE_3S32: Final[int] = 30
|
||||
NODE_TYPE_3U32: Final[int] = 31
|
||||
NODE_TYPE_3S64: Final[int] = 32
|
||||
NODE_TYPE_3U64: Final[int] = 33
|
||||
NODE_TYPE_3FLOAT: Final[int] = 34
|
||||
NODE_TYPE_3DOUBLE: Final[int] = 35
|
||||
|
||||
NODE_TYPE_4S8 = 36
|
||||
NODE_TYPE_4U8 = 37
|
||||
NODE_TYPE_4S16 = 38
|
||||
NODE_TYPE_4U16 = 39
|
||||
NODE_TYPE_4S32 = 40
|
||||
NODE_TYPE_4U32 = 41
|
||||
NODE_TYPE_4S64 = 42
|
||||
NODE_TYPE_4U64 = 43
|
||||
NODE_TYPE_4FLOAT = 44
|
||||
NODE_TYPE_4DOUBLE = 45
|
||||
NODE_TYPE_4S8: Final[int] = 36
|
||||
NODE_TYPE_4U8: Final[int] = 37
|
||||
NODE_TYPE_4S16: Final[int] = 38
|
||||
NODE_TYPE_4U16: Final[int] = 39
|
||||
NODE_TYPE_4S32: Final[int] = 40
|
||||
NODE_TYPE_4U32: Final[int] = 41
|
||||
NODE_TYPE_4S64: Final[int] = 42
|
||||
NODE_TYPE_4U64: Final[int] = 43
|
||||
NODE_TYPE_4FLOAT: Final[int] = 44
|
||||
NODE_TYPE_4DOUBLE: Final[int] = 45
|
||||
|
||||
NODE_TYPE_BOOL = 52
|
||||
NODE_TYPE_BOOL: Final[int] = 52
|
||||
|
||||
NODE_TYPES = {
|
||||
NODE_TYPES: Final[Dict[int, Dict[str, Any]]] = {
|
||||
NODE_TYPE_VOID: {
|
||||
'name': 'void',
|
||||
'enc': '',
|
||||
@ -347,10 +352,10 @@ class Node:
|
||||
'composite': False,
|
||||
},
|
||||
}
|
||||
ARRAY_BIT = 0x40
|
||||
ATTR_TYPE = 0x2E
|
||||
END_OF_NODE = 0xFE
|
||||
END_OF_DOCUMENT = 0xFF
|
||||
ARRAY_BIT: Final[int] = 0x40
|
||||
ATTR_TYPE: Final[int] = 0x2E
|
||||
END_OF_NODE: Final[int] = 0xFE
|
||||
END_OF_DOCUMENT: Final[int] = 0xFF
|
||||
|
||||
@staticmethod
|
||||
def void(name: str) -> 'Node':
|
||||
@ -365,11 +370,11 @@ class Node:
|
||||
return Node(name=name, type=Node.NODE_TYPE_BIN, value=value)
|
||||
|
||||
@staticmethod
|
||||
def __float(name: str, value: float) -> 'Node':
|
||||
def float(name: str, value: _renamed_float) -> 'Node':
|
||||
return Node(name=name, type=Node.NODE_TYPE_FLOAT, value=value)
|
||||
|
||||
@staticmethod
|
||||
def __bool(name: str, value: bool) -> 'Node':
|
||||
def bool(name: str, value: _renamed_bool) -> 'Node':
|
||||
return Node(name=name, type=Node.NODE_TYPE_BOOL, value=value)
|
||||
|
||||
@staticmethod
|
||||
@ -425,11 +430,11 @@ class Node:
|
||||
return Node(name=name, type=Node.NODE_TYPE_TIME, array=True, value=values)
|
||||
|
||||
@staticmethod
|
||||
def float_array(name: str, values: List[float]) -> 'Node':
|
||||
def float_array(name: str, values: List[_renamed_float]) -> 'Node':
|
||||
return Node(name=name, type=Node.NODE_TYPE_FLOAT, array=True, value=values)
|
||||
|
||||
@staticmethod
|
||||
def bool_array(name: str, values: List[bool]) -> 'Node':
|
||||
def bool_array(name: str, values: List[_renamed_bool]) -> 'Node':
|
||||
return Node(name=name, type=Node.NODE_TYPE_BOOL, array=True, value=values)
|
||||
|
||||
@staticmethod
|
||||
@ -532,7 +537,7 @@ class Node:
|
||||
if value < -9223372036854775808 or value > 9223372036854775807:
|
||||
raise NodeException(f'Invalid value {value} for s32 {name}')
|
||||
|
||||
def __init__(self, name: Optional[str]=None, type: Optional[int]=None, array: Optional[bool]=None, value: Optional[Any]=None) -> None:
|
||||
def __init__(self, name: Optional[str]=None, type: Optional[int]=None, array: Optional[_renamed_bool]=None, value: Optional[Any]=None) -> None:
|
||||
"""
|
||||
Initialize a node, with an optional name and type.
|
||||
|
||||
@ -589,7 +594,7 @@ class Node:
|
||||
raise Exception('Logic error, tried to fetch name before setting!')
|
||||
return self.__name
|
||||
|
||||
def set_type(self, type: int, array: Optional[bool]=None) -> None:
|
||||
def set_type(self, type: int, array: Optional[_renamed_bool]=None) -> None:
|
||||
"""
|
||||
Set the type of the node to a new integer type, as specified in Node.NODE_TYPES.
|
||||
|
||||
@ -763,7 +768,7 @@ class Node:
|
||||
return self.__attrs
|
||||
|
||||
@property
|
||||
def is_array(self) -> bool:
|
||||
def is_array(self) -> _renamed_bool:
|
||||
"""
|
||||
Wrapper for accessing array type.
|
||||
|
||||
@ -773,7 +778,7 @@ class Node:
|
||||
return self.__array
|
||||
|
||||
@property
|
||||
def is_composite(self) -> bool:
|
||||
def is_composite(self) -> _renamed_bool:
|
||||
"""
|
||||
Returns whether or not this element is a composite type (basically
|
||||
an array, but packed differently).
|
||||
@ -905,7 +910,7 @@ class Node:
|
||||
attrs_dict['__type'] = translated_type['name']
|
||||
order.insert(0, '__type')
|
||||
|
||||
def escape(val: Any, attr: bool=False) -> str:
|
||||
def escape(val: Any, attr: _renamed_bool=False) -> str:
|
||||
if isinstance(val, str):
|
||||
val = val.replace('&', '&')
|
||||
val = val.replace('<', '<')
|
||||
@ -977,7 +982,7 @@ class Node:
|
||||
"""
|
||||
return self.__to_xml(0)
|
||||
|
||||
def __eq__(self, other: object) -> bool:
|
||||
def __eq__(self, other: object) -> _renamed_bool:
|
||||
"""
|
||||
Convenience function for comparing two nodes.
|
||||
|
||||
@ -1027,7 +1032,7 @@ class Node:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def __ne__(self, other: object) -> bool:
|
||||
def __ne__(self, other: object) -> _renamed_bool:
|
||||
"""
|
||||
Convenience function for comparing two nodes.
|
||||
|
||||
@ -1038,7 +1043,3 @@ class Node:
|
||||
True if this node doesn't equal the other node, False if it does equal.
|
||||
"""
|
||||
return not self.__eq__(other)
|
||||
|
||||
# Nasty hack to get around mypy's lack of scoping
|
||||
float = __float
|
||||
bool = __bool
|
||||
|
@ -1,6 +1,6 @@
|
||||
import binascii
|
||||
import hashlib
|
||||
from typing import Optional
|
||||
from typing import Final, Optional
|
||||
|
||||
from bemani.protocol.lz77 import Lz77
|
||||
from bemani.protocol.binary import BinaryEncoding
|
||||
@ -18,16 +18,16 @@ class EAmuseProtocol:
|
||||
"""
|
||||
A wrapper object that encapsulates encoding/decoding the E-Amusement protocol by Konami.
|
||||
"""
|
||||
SHARED_SECRET = b'\x69\xD7\x46\x27\xD9\x85\xEE\x21\x87\x16\x15\x70\xD0\x8D\x93\xB1\x24\x55\x03\x5B\x6D\xF0\xD8\x20\x5D\xF5'
|
||||
SHARED_SECRET: Final[bytes] = b'\x69\xD7\x46\x27\xD9\x85\xEE\x21\x87\x16\x15\x70\xD0\x8D\x93\xB1\x24\x55\x03\x5B\x6D\xF0\xD8\x20\x5D\xF5'
|
||||
|
||||
XML = 1
|
||||
BINARY = 2
|
||||
XML: Final[int] = 1
|
||||
BINARY: Final[int] = 2
|
||||
|
||||
SHIFT_JIS_LEGACY = "shift-jis-legacy"
|
||||
SHIFT_JIS = "shift-jis"
|
||||
EUC_JP = "euc-jp"
|
||||
UTF_8 = "utf-8"
|
||||
ASCII = "ascii"
|
||||
SHIFT_JIS_LEGACY: Final[str] = "shift-jis-legacy"
|
||||
SHIFT_JIS: Final[str] = "shift-jis"
|
||||
EUC_JP: Final[str] = "euc-jp"
|
||||
UTF_8: Final[str] = "utf-8"
|
||||
ASCII: Final[str] = "ascii"
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""
|
||||
@ -36,7 +36,7 @@ class EAmuseProtocol:
|
||||
self.last_text_encoding: Optional[str] = None
|
||||
self.last_packet_encoding: Optional[int] = None
|
||||
|
||||
def __rc4_crypt(self, data: bytes, key: bytes) -> bytes:
|
||||
def _rc4_crypt(self, data: bytes, key: bytes) -> bytes:
|
||||
"""
|
||||
Given a data blob and a key blob, perform RC4 encryption/decryption.
|
||||
|
||||
@ -95,7 +95,7 @@ class EAmuseProtocol:
|
||||
|
||||
if key:
|
||||
# This is an encrypted old-style packet
|
||||
return self.__rc4_crypt(data, key)
|
||||
return self._rc4_crypt(data, key)
|
||||
|
||||
# No encryption
|
||||
return data
|
||||
|
@ -1,6 +1,6 @@
|
||||
import copy
|
||||
import struct
|
||||
from typing import Any, Dict, Iterator, List, Optional, Tuple
|
||||
from typing import Any, Dict, Final, Iterator, List, Optional, Tuple
|
||||
|
||||
from bemani.protocol.stream import InputStream
|
||||
from bemani.protocol.node import Node
|
||||
@ -468,7 +468,7 @@ class XmlEncoding:
|
||||
# The string values should match the constants in EAmuseProtocol.
|
||||
# I have no better way to link these than to write this comment,
|
||||
# as otherwise we would have a circular dependency.
|
||||
ACCEPTED_ENCODINGS = ['shift-jis', 'euc-jp', 'utf-8', 'ascii']
|
||||
ACCEPTED_ENCODINGS: Final[List[str]] = ['shift-jis', 'euc-jp', 'utf-8', 'ascii']
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""
|
||||
|
@ -1,4 +1,5 @@
|
||||
# vim: set fileencoding=utf-8
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
from typing import Container, List, Dict, Any
|
||||
@ -32,3 +33,9 @@ class FakeCursor():
|
||||
|
||||
def fetchall(self) -> List[Dict[str, Any]]:
|
||||
return self.__rows
|
||||
|
||||
|
||||
def get_fixture(name: str) -> bytes:
|
||||
location = os.path.dirname(os.path.abspath(__file__))
|
||||
with open(os.path.join(location, name), "rb") as fp:
|
||||
return fp.read()
|
||||
|
@ -8,14 +8,14 @@ class TestAESCipher(unittest.TestCase):
|
||||
|
||||
def test_pad(self) -> None:
|
||||
aes = AESCipher('a wonderful key')
|
||||
self.assertEqual(aes._AESCipher__pad(''), '0.--------------')
|
||||
self.assertEqual(aes._AESCipher__unpad(aes._AESCipher__pad('')), '')
|
||||
self.assertEqual(aes._AESCipher__pad('1337'), '4.1337----------')
|
||||
self.assertEqual(aes._AESCipher__unpad(aes._AESCipher__pad('1337')), '1337')
|
||||
self.assertEqual(aes._AESCipher__pad('aaaaaaaaaaaaaaaa'), '16.aaaaaaaaaaaaaaaa-------------')
|
||||
self.assertEqual(aes._AESCipher__unpad(aes._AESCipher__pad('aaaaaaaaaaaaaaaa')), 'aaaaaaaaaaaaaaaa')
|
||||
self.assertEqual(aes._AESCipher__pad('aaaaaaaaaaaaa'), '13.aaaaaaaaaaaaa')
|
||||
self.assertEqual(aes._AESCipher__unpad(aes._AESCipher__pad('aaaaaaaaaaaaa')), 'aaaaaaaaaaaaa')
|
||||
self.assertEqual(aes._pad(''), '0.--------------')
|
||||
self.assertEqual(aes._unpad(aes._pad('')), '')
|
||||
self.assertEqual(aes._pad('1337'), '4.1337----------')
|
||||
self.assertEqual(aes._unpad(aes._pad('1337')), '1337')
|
||||
self.assertEqual(aes._pad('aaaaaaaaaaaaaaaa'), '16.aaaaaaaaaaaaaaaa-------------')
|
||||
self.assertEqual(aes._unpad(aes._pad('aaaaaaaaaaaaaaaa')), 'aaaaaaaaaaaaaaaa')
|
||||
self.assertEqual(aes._pad('aaaaaaaaaaaaa'), '13.aaaaaaaaaaaaa')
|
||||
self.assertEqual(aes._unpad(aes._pad('aaaaaaaaaaaaa')), 'aaaaaaaaaaaaa')
|
||||
|
||||
def test_crypto(self) -> None:
|
||||
aes = AESCipher('a wonderful key')
|
||||
|
@ -15,9 +15,9 @@ class TestCardCipher(unittest.TestCase):
|
||||
for pair in test_ciphers:
|
||||
inp = bytes(pair[0])
|
||||
out = bytes(pair[1])
|
||||
encoded = CardCipher._CardCipher__encode(inp) # type: ignore
|
||||
encoded = CardCipher._encode(inp) # type: ignore
|
||||
self.assertEqual(encoded, out, f"Card encode {encoded} doesn't match expected {out}")
|
||||
decoded = CardCipher._CardCipher__decode(out) # type: ignore
|
||||
decoded = CardCipher._decode(out) # type: ignore
|
||||
self.assertEqual(decoded, inp, f"Card decode {decoded} doesn't match expected {inp}")
|
||||
|
||||
def test_external_cipher(self) -> None:
|
||||
|
@ -13,10 +13,10 @@ class TestRC4Cipher(unittest.TestCase):
|
||||
encrypted = b'\x04]Q\x11\x0cw\x7fO\xfa\x03\xa3\xdf\xb6\x02\xb7d\x9f\x13U\x19\xc9-j\x96\x15yl\x98\xee_<\xfa\x9b\x8f\xbe}\xf4\x05l5\x0e\xd6'
|
||||
proto = EAmuseProtocol()
|
||||
|
||||
cyphertext = proto._EAmuseProtocol__rc4_crypt(data, key)
|
||||
cyphertext = proto._rc4_crypt(data, key)
|
||||
self.assertEqual(encrypted, cyphertext)
|
||||
|
||||
plaintext = proto._EAmuseProtocol__rc4_crypt(cyphertext, key)
|
||||
plaintext = proto._rc4_crypt(cyphertext, key)
|
||||
self.assertEqual(data, plaintext)
|
||||
|
||||
def test_small_data_random(self) -> None:
|
||||
@ -24,10 +24,10 @@ class TestRC4Cipher(unittest.TestCase):
|
||||
key = bytes([random.randint(0, 255) for _ in range(16)])
|
||||
proto = EAmuseProtocol()
|
||||
|
||||
cyphertext = proto._EAmuseProtocol__rc4_crypt(data, key)
|
||||
cyphertext = proto._rc4_crypt(data, key)
|
||||
self.assertNotEqual(data, cyphertext)
|
||||
|
||||
plaintext = proto._EAmuseProtocol__rc4_crypt(cyphertext, key)
|
||||
plaintext = proto._rc4_crypt(cyphertext, key)
|
||||
self.assertEqual(data, plaintext)
|
||||
|
||||
def test_large_data_random(self) -> None:
|
||||
@ -35,8 +35,8 @@ class TestRC4Cipher(unittest.TestCase):
|
||||
key = bytes([random.randint(0, 255) for _ in range(16)])
|
||||
proto = EAmuseProtocol()
|
||||
|
||||
cyphertext = proto._EAmuseProtocol__rc4_crypt(data, key)
|
||||
cyphertext = proto._rc4_crypt(data, key)
|
||||
self.assertNotEqual(data, cyphertext)
|
||||
|
||||
plaintext = proto._EAmuseProtocol__rc4_crypt(cyphertext, key)
|
||||
plaintext = proto._rc4_crypt(cyphertext, key)
|
||||
self.assertEqual(data, plaintext)
|
||||
|
@ -4,6 +4,7 @@ import random
|
||||
import unittest
|
||||
|
||||
from bemani.protocol.lz77 import Lz77, Lz77Decompress
|
||||
from bemani.tests.helpers import get_fixture
|
||||
|
||||
|
||||
class TestLZ77Decompressor(unittest.TestCase):
|
||||
@ -16,22 +17,16 @@ class TestLZ77Decompressor(unittest.TestCase):
|
||||
|
||||
# Save our ring position, write a chunk of data
|
||||
readpos = dec.write_pos
|
||||
dec._Lz77Decompress__ring_write(data)
|
||||
dec._ring_write(data)
|
||||
|
||||
# Read a chunk of data back from that buffer, see its the same
|
||||
newdata = b''.join(dec._Lz77Decompress__ring_read(readpos, amount))
|
||||
newdata = b''.join(dec._ring_read(readpos, amount))
|
||||
self.assertEqual(data, newdata)
|
||||
|
||||
# Verify integrity of ringbuffer
|
||||
self.assertEqual(len(dec.ring), Lz77Decompress.RING_LENGTH)
|
||||
|
||||
|
||||
def get_fixture(name: str) -> bytes:
|
||||
location = os.path.dirname(os.path.abspath(__file__))
|
||||
with open(os.path.join(location, name), "rb") as fp:
|
||||
return fp.read()
|
||||
|
||||
|
||||
class TestLz77RealCompressor(unittest.TestCase):
|
||||
def test_small_data_random(self) -> None:
|
||||
lz77 = Lz77()
|
||||
|
Loading…
Reference in New Issue
Block a user