# Cube 2 codec implementation for Python
#
# Cube 2 (and games based on it, e.g., Red Eclipse) use a weird custom encoding with byte-size characters. It supports
# a certain subset of unicode characters that seems to be considered "sufficient" for game chat, descriptions etc.
#
# After calling register_codec(), you can use "cube2" as encoder for strings resp. as decoder for bytes

import codecs

from typing import Tuple


class Cube2Codec(codecs.Codec):
    # copied from src/shared/cube2font.c
    CUBE2UNICHARS = [
        0, 192, 193, 194, 195, 196, 197, 198, 199, 9, 10, 11, 12, 13, 200,
        201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 216,
        217, 218, 219, 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, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
        111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
        125, 126, 220, 221, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
        234, 235, 236, 237, 238, 239, 241, 242, 243, 244, 245, 246, 233, 248,
        249, 250, 251, 252, 253, 255, 0x104, 0x105, 0x106, 0x107, 0x10C,
        0x10D, 0x10E, 0x10F, 0x118, 0x119, 0x11A, 0x11B, 0x11E, 0x11F, 0x130,
        0x131, 0x141, 0x142, 0x143, 0x144, 0x147, 0x148, 0x150, 0x151, 0x152,
        0x153, 0x158, 0x159, 0x15A, 0x15B, 0x15E, 0x15F, 0x160, 0x161, 0x164,
        0x165, 0x16E, 0x16F, 0x170, 0x171, 0x178, 0x179, 0x17A, 0x17B, 0x17C,
        0x17D, 0x17E, 0x404, 0x411, 0x413, 0x414, 0x416, 0x417, 0x418, 0x419,
        0x41B, 0x41F, 0x423, 0x424, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B,
        0x42C, 0x42D, 0x42E, 0x42F, 0x431, 0x432, 0x433, 0x434, 0x436, 0x437,
        0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43F, 0x442, 0x444, 0x446,
        0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x454,
        0x490, 0x491
    ]

    @classmethod
    def encode(cls, string: str, **kwargs) -> Tuple[bytes, int]:
        encoded = b"".join([bytes([cls.CUBE2UNICHARS.index(ord(char))]) for char in string])
        assert len(encoded) == len(string)
        return encoded, len(string)

    @classmethod
    def decode(cls, binary: bytes, **kwargs) -> Tuple[str, int]:
        decoded = "".join([chr(cls.CUBE2UNICHARS[char]) for char in binary])
        assert len(decoded) == len(binary)
        return decoded, len(binary)


def register_codec():
    codecs.register(lambda _: codecs.CodecInfo(Cube2Codec.encode, Cube2Codec.decode, name="cube2"))

071749fe37ea6ba00229ff2c9b21c591eb0ce48c
<mask token>


class Cube2Codec(codecs.Codec):
    <mask token>

    @classmethod
    def encode(cls, string: str, **kwargs) ->Tuple[bytes, int]:
        encoded = b''.join([bytes([cls.CUBE2UNICHARS.index(ord(char))]) for
            char in string])
        assert len(encoded) == len(string)
        return encoded, len(string)

    @classmethod
    def decode(cls, binary: bytes, **kwargs) ->Tuple[str, int]:
        decoded = ''.join([chr(cls.CUBE2UNICHARS[char]) for char in binary])
        assert len(decoded) == len(binary)
        return decoded, len(binary)


<mask token>

<mask token>


class Cube2Codec(codecs.Codec):
    CUBE2UNICHARS = [0, 192, 193, 194, 195, 196, 197, 198, 199, 9, 10, 11, 
        12, 13, 200, 201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212,
        213, 214, 216, 217, 218, 219, 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, 99, 100, 101, 102, 103, 104, 105, 106, 
        107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 
        120, 121, 122, 123, 124, 125, 126, 220, 221, 223, 224, 225, 226, 
        227, 228, 229, 230, 231, 232, 234, 235, 236, 237, 238, 239, 241, 
        242, 243, 244, 245, 246, 233, 248, 249, 250, 251, 252, 253, 255, 
        260, 261, 262, 263, 268, 269, 270, 271, 280, 281, 282, 283, 286, 
        287, 304, 305, 321, 322, 323, 324, 327, 328, 336, 337, 338, 339, 
        344, 345, 346, 347, 350, 351, 352, 353, 356, 357, 366, 367, 368, 
        369, 376, 377, 378, 379, 380, 381, 382, 1028, 1041, 1043, 1044, 
        1046, 1047, 1048, 1049, 1051, 1055, 1059, 1060, 1062, 1063, 1064, 
        1065, 1066, 1067, 1068, 1069, 1070, 1071, 1073, 1074, 1075, 1076, 
        1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1087, 1090, 1092, 
        1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1108, 
        1168, 1169]

    @classmethod
    def encode(cls, string: str, **kwargs) ->Tuple[bytes, int]:
        encoded = b''.join([bytes([cls.CUBE2UNICHARS.index(ord(char))]) for
            char in string])
        assert len(encoded) == len(string)
        return encoded, len(string)

    @classmethod
    def decode(cls, binary: bytes, **kwargs) ->Tuple[str, int]:
        decoded = ''.join([chr(cls.CUBE2UNICHARS[char]) for char in binary])
        assert len(decoded) == len(binary)
        return decoded, len(binary)


<mask token>

<mask token>


class Cube2Codec(codecs.Codec):
    CUBE2UNICHARS = [0, 192, 193, 194, 195, 196, 197, 198, 199, 9, 10, 11, 
        12, 13, 200, 201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212,
        213, 214, 216, 217, 218, 219, 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, 99, 100, 101, 102, 103, 104, 105, 106, 
        107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 
        120, 121, 122, 123, 124, 125, 126, 220, 221, 223, 224, 225, 226, 
        227, 228, 229, 230, 231, 232, 234, 235, 236, 237, 238, 239, 241, 
        242, 243, 244, 245, 246, 233, 248, 249, 250, 251, 252, 253, 255, 
        260, 261, 262, 263, 268, 269, 270, 271, 280, 281, 282, 283, 286, 
        287, 304, 305, 321, 322, 323, 324, 327, 328, 336, 337, 338, 339, 
        344, 345, 346, 347, 350, 351, 352, 353, 356, 357, 366, 367, 368, 
        369, 376, 377, 378, 379, 380, 381, 382, 1028, 1041, 1043, 1044, 
        1046, 1047, 1048, 1049, 1051, 1055, 1059, 1060, 1062, 1063, 1064, 
        1065, 1066, 1067, 1068, 1069, 1070, 1071, 1073, 1074, 1075, 1076, 
        1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1087, 1090, 1092, 
        1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1108, 
        1168, 1169]

    @classmethod
    def encode(cls, string: str, **kwargs) ->Tuple[bytes, int]:
        encoded = b''.join([bytes([cls.CUBE2UNICHARS.index(ord(char))]) for
            char in string])
        assert len(encoded) == len(string)
        return encoded, len(string)

    @classmethod
    def decode(cls, binary: bytes, **kwargs) ->Tuple[str, int]:
        decoded = ''.join([chr(cls.CUBE2UNICHARS[char]) for char in binary])
        assert len(decoded) == len(binary)
        return decoded, len(binary)


def register_codec():
    codecs.register(lambda _: codecs.CodecInfo(Cube2Codec.encode,
        Cube2Codec.decode, name='cube2'))

import codecs
from typing import Tuple


class Cube2Codec(codecs.Codec):
    CUBE2UNICHARS = [0, 192, 193, 194, 195, 196, 197, 198, 199, 9, 10, 11, 
        12, 13, 200, 201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212,
        213, 214, 216, 217, 218, 219, 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, 99, 100, 101, 102, 103, 104, 105, 106, 
        107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 
        120, 121, 122, 123, 124, 125, 126, 220, 221, 223, 224, 225, 226, 
        227, 228, 229, 230, 231, 232, 234, 235, 236, 237, 238, 239, 241, 
        242, 243, 244, 245, 246, 233, 248, 249, 250, 251, 252, 253, 255, 
        260, 261, 262, 263, 268, 269, 270, 271, 280, 281, 282, 283, 286, 
        287, 304, 305, 321, 322, 323, 324, 327, 328, 336, 337, 338, 339, 
        344, 345, 346, 347, 350, 351, 352, 353, 356, 357, 366, 367, 368, 
        369, 376, 377, 378, 379, 380, 381, 382, 1028, 1041, 1043, 1044, 
        1046, 1047, 1048, 1049, 1051, 1055, 1059, 1060, 1062, 1063, 1064, 
        1065, 1066, 1067, 1068, 1069, 1070, 1071, 1073, 1074, 1075, 1076, 
        1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1087, 1090, 1092, 
        1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1108, 
        1168, 1169]

    @classmethod
    def encode(cls, string: str, **kwargs) ->Tuple[bytes, int]:
        encoded = b''.join([bytes([cls.CUBE2UNICHARS.index(ord(char))]) for
            char in string])
        assert len(encoded) == len(string)
        return encoded, len(string)

    @classmethod
    def decode(cls, binary: bytes, **kwargs) ->Tuple[str, int]:
        decoded = ''.join([chr(cls.CUBE2UNICHARS[char]) for char in binary])
        assert len(decoded) == len(binary)
        return decoded, len(binary)


def register_codec():
    codecs.register(lambda _: codecs.CodecInfo(Cube2Codec.encode,
        Cube2Codec.decode, name='cube2'))

# Cube 2 codec implementation for Python
#
# Cube 2 (and games based on it, e.g., Red Eclipse) use a weird custom encoding with byte-size characters. It supports
# a certain subset of unicode characters that seems to be considered "sufficient" for game chat, descriptions etc.
#
# After calling register_codec(), you can use "cube2" as encoder for strings resp. as decoder for bytes

import codecs

from typing import Tuple


class Cube2Codec(codecs.Codec):
    # copied from src/shared/cube2font.c
    CUBE2UNICHARS = [
        0, 192, 193, 194, 195, 196, 197, 198, 199, 9, 10, 11, 12, 13, 200,
        201, 202, 203, 204, 205, 206, 207, 209, 210, 211, 212, 213, 214, 216,
        217, 218, 219, 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, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
        111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
        125, 126, 220, 221, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
        234, 235, 236, 237, 238, 239, 241, 242, 243, 244, 245, 246, 233, 248,
        249, 250, 251, 252, 253, 255, 0x104, 0x105, 0x106, 0x107, 0x10C,
        0x10D, 0x10E, 0x10F, 0x118, 0x119, 0x11A, 0x11B, 0x11E, 0x11F, 0x130,
        0x131, 0x141, 0x142, 0x143, 0x144, 0x147, 0x148, 0x150, 0x151, 0x152,
        0x153, 0x158, 0x159, 0x15A, 0x15B, 0x15E, 0x15F, 0x160, 0x161, 0x164,
        0x165, 0x16E, 0x16F, 0x170, 0x171, 0x178, 0x179, 0x17A, 0x17B, 0x17C,
        0x17D, 0x17E, 0x404, 0x411, 0x413, 0x414, 0x416, 0x417, 0x418, 0x419,
        0x41B, 0x41F, 0x423, 0x424, 0x426, 0x427, 0x428, 0x429, 0x42A, 0x42B,
        0x42C, 0x42D, 0x42E, 0x42F, 0x431, 0x432, 0x433, 0x434, 0x436, 0x437,
        0x438, 0x439, 0x43A, 0x43B, 0x43C, 0x43D, 0x43F, 0x442, 0x444, 0x446,
        0x447, 0x448, 0x449, 0x44A, 0x44B, 0x44C, 0x44D, 0x44E, 0x44F, 0x454,
        0x490, 0x491
    ]

    @classmethod
    def encode(cls, string: str, **kwargs) -> Tuple[bytes, int]:
        encoded = b"".join([bytes([cls.CUBE2UNICHARS.index(ord(char))]) for char in string])
        assert len(encoded) == len(string)
        return encoded, len(string)

    @classmethod
    def decode(cls, binary: bytes, **kwargs) -> Tuple[str, int]:
        decoded = "".join([chr(cls.CUBE2UNICHARS[char]) for char in binary])
        assert len(decoded) == len(binary)
        return decoded, len(binary)


def register_codec():
    codecs.register(lambda _: codecs.CodecInfo(Cube2Codec.encode, Cube2Codec.decode, name="cube2"))
