import zlib

from Classes.ByteStreamHelper import ByteStreamHelper
from Classes.ChecksumEncoder import ChecksumEncoder
from Classes.Logic.LogicStringUtil import LogicStringUtil
from Classes.Debugger import Debugger
from Classes.Logic.LogicLong import LogicLong


class ByteStream(ChecksumEncoder):
    def __init__(self, messageBuffer, unknown=0):
        super().__init__()
        self.messagePayload = messageBuffer
        self.bitoffset = 0
        self.offset = 0
        self.length = len(self.messagePayload)

    def clear(self, length):
        if self.messagePayload:
            self.messagePayload = b''
        self.bitoffset = 0
        self.offset = 0

    def destroy(self):
        self.messagePayload = None
        self.bitoffset = 0
        self.offset = 0
        self.length = 0

    def ensureCapacity(self, length):
        offset = self.offset
        if len(self.messagePayload) < offset + length:
            buffer_copy = self.messagePayload
            buf_len = length
            self.length = buf_len
            self.messagePayload += bytes([0] * buf_len)

    def writeHexa(self, data, length):
        self.bitoffset = 0
        if data:
            if data.startswith('0x'):
                data = data[2:]

            self.messagePayload += bytes.fromhex(''.join(data.split()).replace('-', ''))
            self.offset += length

    def getBitOffset(self):
        return self.bitoffset

    def getByteArray(self):
        return self.messagePayload

    def getCapacityIncrement(self):
        return 100

    def getDataPointer(self):
        return self.messagePayload[self.offset]

    def getLength(self):
        length = self.length
        if self.length <= self.offset:
            length = self.offset
        return length

    def getOffset(self):
        return self.offset

    @staticmethod
    def getVIntSizeInBytes(value):
        if value < 0:
            if value > -64:
                return 1
            elif value > -8192:
                return 2
            elif value > -1048576:
                return 3
            elif value > -134217727:
                return 4
            else:
                return 5
        else:
            if value < 64:
                return 1
            elif value < 8192:
                return 2
            elif value < 1048576:
                return 3
            elif value < 134217727:
                return 4
            else:
                return 5

    @staticmethod
    def getVLongSizeInBytes(value):
        if value < 0:
            if value > -64:
                return 1
            elif value > -8192:
                return 2
            elif value > -1048576:
                return 3
            elif value > -134217727:
                return 4
            elif value > -17179869184:
                return 5
            elif value > -2199023255552:
                return 6
            elif value > -281474976710656:
                return 7
            elif value > -36028797018963968:
                return 8
            elif value > -4611686018427387903:
                return 9
            else:
                return 10
        else:
            if value < 64:
                return 1
            elif value < 8192:
                return 2
            elif value < 1048576:
                return 3
            elif value < 134217727:
                return 4
            elif value < 17179869184:
                return 5
            elif value < 2199023255552:
                return 6
            elif value < 281474976710656:
                return 7
            elif value < 36028797018963968:
                return 8
            elif value < 4611686018427387903:
                return 9
            else:
                return 10

    def isAtEnd(self):
        return len(self.messagePayload) <= self.offset

    @staticmethod
    def isByteStream():
        return True

    @staticmethod
    def isCheckSumOnlyMode():
        return False

    def readBoolean(self):
        bitoffset = self.bitoffset
        offset = self.offset + (8 - bitoffset >> 3)
        self.offset = offset
        self.bitoffset = bitoffset + 1 & 7
        return (1 << (bitoffset & 31) & self.messagePayload[offset - 1]) != 0

    def readByte(self):
        self.bitoffset = 0
        result = self.messagePayload[self.offset]
        self.offset += 1
        return result

    def readBytes(self, length, max=1000):
        self.bitoffset = 0
        if (length & 0x80000000) != 0:
            if length != -1:
                Debugger.warning("Negative readBytes length encountered.")
        elif length <= max:
            result = self.messagePayload[self.offset:self.offset + length]
            self.offset += length
            return bytes(result)
        else:
            Debugger.warning("readBytes too long array, max", max)
        return b''

    def readBytesLength(self):
        self.bitoffset = 0
        result = (self.messagePayload[self.offset] << 24)
        result += (self.messagePayload[self.offset + 1] << 16)
        result += (self.messagePayload[self.offset + 2] << 8)
        result += (self.messagePayload[self.offset + 3])
        self.offset += 4
        return result

    def readInt8(self):
        self.bitoffset = 0
        result = (self.messagePayload[self.offset])
        self.offset += 1
        return result

    def readInt16(self):
        self.bitoffset = 0
        result = (self.messagePayload[self.offset] << 8)
        result += (self.messagePayload[self.offset + 1])
        self.offset += 2
        return result

    def readInt24(self):
        self.bitoffset = 0
        result = (self.messagePayload[self.offset] << 16)
        result += (self.messagePayload[self.offset + 1] << 8)
        result += (self.messagePayload[self.offset + 2])
        self.offset += 3
        return result

    def readInt(self):
        self.bitoffset = 0
        result = (self.messagePayload[self.offset] << 24)
        result += (self.messagePayload[self.offset + 1] << 16)
        result += (self.messagePayload[self.offset + 2] << 8)
        result += (self.messagePayload[self.offset + 3])
        self.offset += 4
        return result

    def readIntLittleEndian(self):
        self.bitoffset = 0
        result = (self.messagePayload[self.offset])
        result += (self.messagePayload[self.offset + 1] << 8)
        result += (self.messagePayload[self.offset + 2] << 16)
        result += (self.messagePayload[self.offset + 3] << 24)
        self.offset += 4
        return result

    def readLong(self, logicLong=None):
        if not logicLong:
            logicLong = LogicLong(0, 0)
        logicLong.decode(self)
        return [logicLong.high, logicLong.low]

    def readLongLong(self):
        self.bitoffset = 0
        high = (self.messagePayload[self.offset] << 24)
        high += (self.messagePayload[self.offset + 1] << 16)
        high += (self.messagePayload[self.offset + 2] << 8)
        high += (self.messagePayload[self.offset + 3])
        self.offset += 4
        low = (self.messagePayload[self.offset] << 24)
        low += (self.messagePayload[self.offset + 1] << 16)
        low += (self.messagePayload[self.offset + 2] << 8)
        low += (self.messagePayload[self.offset + 3])
        self.offset += 4
        return LogicLong.toLong(high, low)

    def readShort(self):
        self.bitoffset = 0
        result = (self.messagePayload[self.offset] << 8)
        result += (self.messagePayload[self.offset + 1])
        self.offset += 2
        return result

    def readString(self, max=900000):
        self.bitoffset = 0
        length = (self.messagePayload[self.offset] << 24)
        length += (self.messagePayload[self.offset + 1] << 16)
        length += (self.messagePayload[self.offset + 2] << 8)
        length += (self.messagePayload[self.offset + 3])
        self.offset += 4
        if length <= -1:
            if length != -1:
                Debugger.warning("Negative String length encountered.")
            return b''
        elif length > max:
            Debugger.warning(f"Too long String encountered, length {length}, max {max}")
            return b''
        result = bytes(self.messagePayload[self.offset:self.offset + length]).decode('utf-8')
        self.offset += length
        return result

    def readStringReference(self, max):
        self.bitoffset = 0
        length = (self.messagePayload[self.offset] << 24)
        length += (self.messagePayload[self.offset + 1] << 16)
        length += (self.messagePayload[self.offset + 2] << 8)
        length += (self.messagePayload[self.offset + 3])
        self.offset += 4
        if length <= -1:
            if length != -1:
                Debugger.warning("Negative String length encountered.")
            return b''
        elif length > max:
            Debugger.warning(f"Too long String encountered, length {length}, max {max}")
            return b''
        result = self.messagePayload[self.offset].decode('utf-8')
        self.offset += length
        return result

    def readVInt(self):
        offset = self.offset
        self.bitoffset = 0
        v4 = offset + 1
        self.offset = offset + 1
        result = self.messagePayload[offset] & 0x3F
        if (self.messagePayload[offset] & 0x40) != 0:
            if (self.messagePayload[offset] & 0x80) != 0:
                self.offset = offset + 2
                v7 = self.messagePayload[v4]
                v8 = result & 0xFFFFE03F | ((v7 & 0x7F) << 6)
                if (v7 & 0x80) != 0:
                    self.offset = offset + 3
                    v9 = v8 & 0xFFF01FFF | ((self.messagePayload[offset + 2] & 0x7F) << 13)
                    if (self.messagePayload[offset + 2] & 0x80) != 0:
                        self.offset = offset + 4
                        v10 = v9 & 0xF80FFFFF | ((self.messagePayload[offset + 3] & 0x7F) << 20)
                        if (self.messagePayload[offset + 3] & 0x80) != 0:
                            self.offset = offset + 5
                            return v10 & 0x7FFFFFF | (self.messagePayload[offset + 4] << 27) | 0x80000000
                        else:
                            return v10 | 0xF8000000
                    else:
                        return v9 | 0xFFF00000
                else:
                    return v8 | 0xFFFFE000
            else:
                return self.messagePayload[offset] | 0xFFFFFFC0
        elif (self.messagePayload[offset] & 0x80) != 0:
            self.offset = offset + 2
            v6 = self.messagePayload[v4]
            result = result & 0xFFFFE03F | ((v6 & 0x7F) << 6)
            if (v6 & 0x80) != 0:
                self.offset = offset + 3
                result = result & 0xFFF01FFF | ((self.messagePayload[offset + 2] & 0x7F) << 13)
                if (self.messagePayload[offset + 2] & 0x80) != 0:
                    self.offset = offset + 4
                    result = result & 0xF80FFFFF | ((self.messagePayload[offset + 3] & 0x7F) << 20)
                    if (self.messagePayload[offset + 3] & 0x80) != 0:
                        self.offset = offset + 5
                        return result & 0x7FFFFFF | (self.messagePayload[offset + 4] << 27)

        return result

    def readVLong(self):
        result = []
        result.append(self.readVInt())
        result.append(self.readVInt())
        return result

    def removeByteArray(self):
        self.messagePayload = b''

    def reset(self):
        self.length = 0
        self.offset = 0

    def resetOffset(self):
        self.offset = 0
        self.bitoffset = 0

    def rewind(self):
        self.bitoffset = 0
        length = self.length
        if self.length <= self.offset:
            length = self.offset
        self.offset = 0
        self.length = length

    def setOffset(self, offset, bitoffset):
        self.offset = offset
        self.bitoffset = bitoffset

    def skip(self, bytes_to_skip):
        self.bitoffset = 0
        self.offset = self.offset + bytes_to_skip

    def writeBoolean(self, value):
        ChecksumEncoder.writeBoolean(self, value & 1)
        tempBuf = list(self.messagePayload)
        if self.bitoffset == 0:
            offset = self.offset
            self.offset += 1
            tempBuf.append(0)
        if (value & 1) != 0:
            tempBuf[self.offset - 1] = tempBuf[self.offset - 1] | 1 << (self.bitoffset & 31)
        self.bitoffset = self.bitoffset + 1 & 7
        self.messagePayload = bytes(tempBuf)

    def writeByte(self, value):
        ChecksumEncoder.writeByte(self, value)
        self.bitoffset = 0
        tempBuf = list(self.messagePayload)
        tempBuf.append(value & 0xFF)
        self.messagePayload = bytes(tempBuf)
        self.offset += 1

    def writeBytes(self, value, length):
        ChecksumEncoder.writeBytes(self, value, length)
        self.bitoffset = 0
        if value != 0:
            ByteStream.writeIntToByteArray(self, length)
            self.messagePayload += value
            self.offset += length
        else:
            ByteStream.writeIntToByteArray(self, -1)

    def writeInt8(self, value):
        ChecksumEncoder.writeInt(self, value)
        self.bitoffset = 0
        tempBuf = list(self.messagePayload)
        tempBuf.append(value & 0xFF)
        self.messagePayload = bytes(tempBuf)
        self.offset += 1
        
    def writeInt16(self, value):
        ChecksumEncoder.writeInt(self, value)
        self.bitoffset = 0
        tempBuf = list(self.messagePayload)
        tempBuf.append(value >> 8 & 0xFF)
        tempBuf.append(value & 0xFF)
        self.messagePayload = bytes(tempBuf)
        self.offset += 2

    def writeInt24(self, value):
        ChecksumEncoder.writeInt(self, value)
        self.bitoffset = 0
        tempBuf = list(self.messagePayload)
        tempBuf.append(value >> 16 & 0xFF)
        tempBuf.append(value >> 8 & 0xFF)
        tempBuf.append(value & 0xFF)
        self.messagePayload = bytes(tempBuf)
        self.offset += 3

    def writeInt(self, value):
        ChecksumEncoder.writeInt(self, value)
        ByteStream.writeIntToByteArray(self, value)

    def writeIntLittleEndian(self, value):
        self.bitoffset = 0
        tempBuf = list(self.messagePayload)
        tempBuf.append(value & 0xFF)
        tempBuf.append(value >> 8 & 0xFF)
        tempBuf.append(value >> 16 & 0xFF)
        tempBuf.append(value >> 24 & 0xFF)
        self.messagePayload = bytes(tempBuf)
        self.offset += 4

    def writeIntToByteArray(self, value):
        self.bitoffset = 0
        tempBuf = list(self.messagePayload)
        tempBuf.append(value >> 24 & 0xFF)
        tempBuf.append(value >> 16 & 0xFF)
        tempBuf.append(value >> 8 & 0xFF)
        tempBuf.append(value & 0xFF)
        self.messagePayload = bytes(tempBuf)
        self.offset += 4

    def writeLongLong(self, longlong):
        ChecksumEncoder.writeLongLong(self, longlong)
        self.bitoffset = 0
        high = LogicLong.getHigherInt(longlong)
        ByteStream.writeIntToByteArray(self, high)
        low = LogicLong.getLowerInt(longlong)
        ByteStream.writeIntToByteArray(self, low)

    def writeLong(self, high, low):
        self.writeIntToByteArray(high)
        self.writeIntToByteArray(low)

    def writeShort(self, value):
        ChecksumEncoder.writeShort(self, value)
        self.bitoffset = 0
        tempBuf = list(self.messagePayload)
        tempBuf.append(value >> 8 & 0xFF)
        tempBuf.append(value & 0xFF)
        self.messagePayload = bytes(tempBuf)
        self.offset += 2

    def writeString(self, value=None):
        ChecksumEncoder.writeString(self, value)
        self.bitoffset = 0
        if value != None:
            str_bytes = LogicStringUtil.getBytes(value)
            str_length = LogicStringUtil.getByteLength(str_bytes)
            if str_length < 900001:
                ByteStream.writeIntToByteArray(self, str_length)
                self.messagePayload += str_bytes
                self.offset += str_length
            else:
                Debugger.warning(f"ByteStream::writeString invalid string length {str_length}")
                ByteStream.writeIntToByteArray(self, -1)
        else:
            ByteStream.writeIntToByteArray(self, -1)

    def writeStringReference(self, value):
        ChecksumEncoder.writeStringReference(self, value)
        self.bitoffset = 0
        str_bytes = LogicStringUtil.getBytes(value)
        str_length = LogicStringUtil.getByteLength(str_bytes)
        if str_length < 900001:
            ByteStream.writeIntToByteArray(self, str_length)
            self.messagePayload += str_bytes
            self.offset += str_length
        else:
            Debugger.warning(f"ByteStream::writeString invalid string length {str_length}")
            ByteStream.writeIntToByteArray(self, -1)

    def writeVInt(self, data):
        self.bitoffset = 0
        if type(data) == str:
            data = int(data)
        final = b''
        if (data & 2147483648) != 0:
            if data >= -63:
                final += (data & 0x3F | 0x40).to_bytes(1, 'big', signed=False)
                self.offset += 1
            elif data >= -8191:
                final += (data & 0x3F | 0xC0).to_bytes(1, 'big', signed=False)
                final += ((data >> 6) & 0x7F).to_bytes(1, 'big', signed=False)
                self.offset += 2
            elif data >= -1048575:
                final += (data & 0x3F | 0xC0).to_bytes(1, 'big', signed=False)
                final += ((data >> 6) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 13) & 0x7F).to_bytes(1, 'big', signed=False)
                self.offset += 3
            elif data >= -134217727:
                final += (data & 0x3F | 0xC0).to_bytes(1, 'big', signed=False)
                final += ((data >> 6) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 13) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 20) & 0x7F).to_bytes(1, 'big', signed=False)
                self.offset += 4
            else:
                final += (data & 0x3F | 0xC0).to_bytes(1, 'big', signed=False)
                final += ((data >> 6) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 13) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 20) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 27) & 0xF).to_bytes(1, 'big', signed=False)
                self.offset += 5
        else:
            if data <= 63:
                final += (data & 0x3F).to_bytes(1, 'big', signed=False)
                self.offset += 1
            elif data <= 8191:
                final += (data & 0x3F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 6) & 0x7F).to_bytes(1, 'big', signed=False)
                self.offset += 2
            elif data <= 1048575:
                final += (data & 0x3F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 6) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 13) & 0x7F).to_bytes(1, 'big', signed=False)
                self.offset += 3
            elif data <= 134217727:
                final += (data & 0x3F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 6) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 13) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 20) & 0x7F).to_bytes(1, 'big', signed=False)
                self.offset += 4
            else:
                final += (data & 0x3F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 6) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 13) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 20) & 0x7F | 0x80).to_bytes(1, 'big', signed=False)
                final += ((data >> 27) & 0xF).to_bytes(1, 'big', signed=False)
                self.offset += 5

        self.messagePayload += final

    def writeVLong(self, high, low):
        ChecksumEncoder.writeVLong(self, high, low)
        self.bitoffset = 0
        self.writeVInt(high)
        self.writeVInt(low)

    def writeCompressedString(self, data):
        self.bitoffset = 0
        compressedText = zlib.compress(data)
        self.writeInt(len(compressedText) + 4)
        self.writeIntLittleEndian(len(data))
        self.messagePayload += compressedText

    def readCompressedString(self):
        data_length = self.readInt()
        self.readIntLittleEndian()
        return zlib.decompress(self.readBytes(data_length - 4))

    #region ByteStreamHelper lazy call

    def readDataReference(self):
        return ByteStreamHelper.readDataReference(self)

    def writeDataReference(self, high=0, low=-1):
        ByteStreamHelper.writeDataReference(self, high, low)

    def decodeIntList(self):
        return ByteStreamHelper.decodeIntList(self)

    def encodeIntList(self, intList):
        ByteStreamHelper.encodeIntList(self, intList)

    def decodeLogicLong(self, logicLong=None):
        return ByteStreamHelper.decodeLogicLong(self, logicLong)

    def encodeLogicLong(self, logicLong):
        ByteStreamHelper.encodeLogicLong(self, logicLong)

    def decodeLogicLongList(self):
        return ByteStreamHelper.decodeLogicLongList(self)

    def encodeLogicLongList(self, logicLongList):
        ByteStreamHelper.encodeLogicLongList(self, logicLongList)

    #endregion
Classes/ByteStream.py
risporce/BSDS
import zlib
from Classes.Logic.LogicLong import LogicLong

class ByteStreamHelper:
    def readDataReference(self):
        result = []
        result.append(self.readVInt())
        if not result[0]:
            return None
        result.append(self.readVInt())
        return result

    def writeDataReference(self, high=0, low=-1):
        self.writeVInt(high)
        if high != 0:
            self.writeVInt(low)

    def compress(self, data):
        compressedText = zlib.compress(data)
        self.writeInt(len(compressedText) + 4)
        self.writeIntLittleEndian(len(data))
        self.buffer += compressedText

    def decompress(self):
        data_length = self.readInt()
        self.readIntLittleEndian()
        return zlib.decompress(self.readBytes(data_length - 4))

    def decodeIntList(self):
        length = self.readVInt()
        intList = []
        for i in range(length):
            intList.append(self.readVInt())
        return intList

    def decodeLogicLong(self, logicLong=None):
        if logicLong is None:
            logicLong = LogicLong(0, 0)
        high = self.readVInt()
        logicLong.high = high
        low = self.readVInt()
        logicLong.low = low

    def decodeLogicLongList(self):
        length = self.readVInt()
        logicLongList = []
        for i in range(length):
            logicLongList.append(LogicLong(self.readVInt(), self.readVInt()))
        return logicLongList

    def encodeIntList(self, intList):
        length = len(intList)
        self.writeVInt(length)
        for i in intList:
            self.writeVInt(i)

    def encodeLogicLong(self, logicLong):
        if logicLong is None:
            logicLong = LogicLong(0, 0)
        self.writeVInt(logicLong.getHigherInt(self))
        self.writeVInt(logicLong.getLowerInt(self))

    def encodeLogicLongList(self, logicLongList):
        length = len(logicLongList)
        self.writeVInt(self, length)
        for logicLong in logicLongList:
            self.writeVInt(logicLong.getHigherInt(self))
            self.writeVInt(logicLong.getLowerInt(self))
Classes/ByteStreamHelper.py
risporce/BSDS
class CPPDefs:
    # region Rotate Left
    @staticmethod
    def rotl8(value, count):
        return value << count | value >> (8 - count)

    @staticmethod
    def rotl16(value, count):
        return value << count | value >> (16 - count)

    @staticmethod
    def rotl32(value, count):
        return value << count | value >> (32 - count)

    @staticmethod
    def rotl64(value, count):
        return value << count | value >> (64 - count)

    @staticmethod
    def __ROL1__(value, count):
        return CPPDefs.rotl8(value, count)

    @staticmethod
    def __ROL2__(value, count):
        return CPPDefs.rotl16(value, count)

    @staticmethod
    def __ROL4__(value, count):
        return CPPDefs.rotl32(value, count)

    @staticmethod
    def __ROL8__(value, count):
        return CPPDefs.rotl64(value, count)
    # endregion

    # region Rotate Right
    @staticmethod
    def rotr8(value, count):
        return value >> count | value << (8 - count)

    @staticmethod
    def rotr16(value, count):
        return value >> count | value << (16 - count)

    @staticmethod
    def rotr32(value, count):
        return value >> count | value << (32 - count)

    @staticmethod
    def rotr64(value, count):
        return value >> count | value << (64 - count)

    @staticmethod
    def __ROR1__(value, count):
        return CPPDefs.rotr8(value, count)

    @staticmethod
    def __ROR2__(value, count):
        return CPPDefs.rotr16(value, count)

    @staticmethod
    def __ROR4__(value, count):
        return CPPDefs.rotr32(value, count)

    @staticmethod
    def __ROR8__(value, count):
        return CPPDefs.rotr64(value, count)
    # endregion
Classes/CPPDefs.py
risporce/BSDS
from Classes.CPPDefs import CPPDefs
from Classes.Debugger import Debugger


class ChecksumEncoder:
    def __init__(self):
        self.checksum = 0
        self.checksum2 = 0
        self.checksumEnabled = True

    def destruct(self):
        self.checksum = 0
        self.checksum2 = 0
        self.checksumEnabled = True

    def enableCheckSum(self, state):
        if not self.checksumEnabled or state:
            if not self.checksumEnabled and state:
                self.checksum = self.checksum2
            self.checksumEnabled = state
        else:
            self.checksum2 = self.checksum
            self.checksumEnabled = False

    def equals(self, checksum_instance):
        if not checksum_instance:
            return False

        if not checksum_instance.checksumEnabled:
            checksum = checksum_instance.checksum
        else:
            checksum2 = checksum_instance.checksum2

        if not self.checksumEnabled:
            checksum = self.checksum
        else:
            checksum2 = self.checksum2
        return checksum == checksum2

    def getCheckSum(self):
        if not self.checksumEnabled:
            checksum = self.checksum2
        else:
            checksum = self.checksum
        return checksum

    @staticmethod
    def hashCode():
        Debugger.error("ChecksumEncoder hashCode not designed")
        return 42

    @staticmethod
    def isByteStream():
        return False

    def isCheckSumEnabled(self):
        return self.checksumEnabled

    @staticmethod
    def isCheckSumOnlyMode():
        return True

    def resetCheckSum(self):
        self.checksum = 0

    def writeBoolean(self, value):
        if value: integer = 13
        else: integer = 7
        self.checksum = integer + CPPDefs.__ROR4__(self.checksum, 31)

    def writeByte(self, value):
        self.checksum = CPPDefs.__ROR4__(self.checksum, 31) + value + 11

    def writeBytes(self, value, length):
        if value: integer = length + 38
        else: integer = 37
        self.checksum = CPPDefs.__ROR4__(self.checksum, 31)

    def writeInt8(self, value):
        if value + 0x80 >= 0x100:
            Debugger.error("")
        self.checksum = CPPDefs.__ROR4__(self.checksum, 31) + value + 11

    def writeInt16(self, value):
        if value + 0x8000 >= 0x10000:
            Debugger.error("")
        self.checksum = CPPDefs.__ROR4__(self.checksum, 31) + value + 19

    def writeInt24(self, value):
        if value + 0x800000 >= 0x1000000:
            Debugger.error("")
        self.checksum = (value & 0xFFFFFF) + CPPDefs.__ROR4__(self.checksum, 31) + value + 21

    def writeInt(self, value):
        self.checksum = CPPDefs.__ROR4__(self.checksum, 31) + value + 9

    @staticmethod
    def writeLong(bytestream, logicLong):
        logicLong.encode(bytestream)

    def writeLongLong(self, logicLong):
        self.checksum = logicLong.getLowerInt() + CPPDefs.__ROR4__(logicLong.getHigherInt() + CPPDefs.__ROR4__(self.checksum, 31) + 67, 31) + 91

    def writeShort(self, value):
        self.checksum = CPPDefs.__ROR4__(self.checksum, 31) + value + 19

    def writeString(self, value):
        checksum = CPPDefs.__ROR4__(self.checksum, 31)
        if value:
            self.checksum = checksum + len(value) + 28
        else:
            self.checksum = checksum + 27

    def writeStringReference(self, value):
        self.checksum = len(value) + CPPDefs.__ROR4__(self.checksum, 31) + 38

    def writeVInt(self, value):
        self.checksum = value + CPPDefs.__ROR4__(self.checksum, 31) + 33

    def writeVLong(self, high, low):
        self.checksum = low + CPPDefs.__ROR4__(high + CPPDefs.__ROR4__(self.checksum, 31) + 65, 31) + 88
Classes/ChecksumEncoder.py
risporce/BSDS
from Classes.ByteStream import ByteStream

class ChronosTextEntry:
    @staticmethod
    def decode(byteStream: ByteStream):
        fields = []
        fields.append(byteStream.readInt())
        fields.append(byteStream.readStringReference())
        return fields
        
Classes/ChronosTextEntry.py
risporce/BSDS
class ClientsManager:

    PlayersList = {}

    def AddPlayer(playerID, socket):
        if ClientsManager.PlayersList.keys().__contains__(playerID[1]):
            ClientsManager.RemovePlayer(playerID)
        ClientsManager.PlayersList[playerID[1]] = {"Socket": socket}

    def RemovePlayer(PlayerID):
        try:
            ClientsManager.PlayersList.pop(PlayerID[1])
        except KeyError:
            print(f"Cannot remove socket with id: {PlayerID} Reason: {PlayerID} is not in the list.")

    def GetAll():
        return ClientsManager.PlayersList

    def GetCount():
        return len(ClientsManager.PlayersList)
Classes/ClientsManager.py
risporce/BSDS
from Classes.Commands.LogicCommand import LogicCommand
from Classes.Messaging import Messaging

class LogicOpenRandomCommand(LogicCommand):
    def __init__(self, commandData):
        super().__init__(commandData)

    def encode(self, fields):
        LogicCommand.encode(self, fields)
        self.writeVInt(0)
        self.writeDataReference(0)
        return self.messagePayload

    def decode(self, calling_instance):
        fields = {}
        LogicCommand.decode(calling_instance, fields, False)
        fields["Unk1"] = calling_instance.readVInt()
        fields["RewardType"] = calling_instance.readVInt()
        fields["RewardAmount"] = calling_instance.readVInt()
        fields["Unk2"] = calling_instance.readVInt()
        fields["Unk3"] = calling_instance.readVInt()
        LogicCommand.parseFields(fields)
        return fields

    def execute(self, calling_instance, fields):
        pass

    def getCommandType(self):
        return 571
Classes/Commands/Client/LogicOpenRandomCommand.py
risporce/BSDS
from Classes.Commands.LogicCommand import LogicCommand
from Classes.Messaging import Messaging
from Classes.Logic.LogicStarrDropData import starrDropOpening

class LogicPurchaseOfferCommand(LogicCommand):
    def __init__(self, commandData):
        super().__init__(commandData)

    def encode(self, fields):
        LogicCommand.encode(self, fields)
        self.writeVInt(0)
        self.writeDataReference(0)
        return self.messagePayload

    def decode(self, calling_instance):
        fields = {}
        LogicCommand.decode(calling_instance, fields, False)
        fields["OfferIndex"] = calling_instance.readVInt()
        fields["Unk2"] = calling_instance.readDataReference()
        fields["Unk3"] = calling_instance.readDataReference()
        fields["Unk4"] = calling_instance.readVInt()
        
        LogicCommand.parseFields(fields)
        return fields

    def execute(self, calling_instance, fields):
        if fields["OfferIndex"] == 0:
            starrDropOpening.create_starrDrop_opening(3)
        elif fields["OfferIndex"] == 1:
            starrDropOpening.create_starrDrop_opening(10)
        elif fields["OfferIndex"] == 2:
            starrDropOpening.create_starrDrop_opening(25)
        elif fields["OfferIndex"] == 3:
            starrDropOpening.create_starrDrop_opening(10, "Rare", True)
        elif fields["OfferIndex"] == 4:
            starrDropOpening.create_starrDrop_opening(10, "Super_Rare", True)
        elif fields["OfferIndex"] == 5:
            starrDropOpening.create_starrDrop_opening(10, "Epic", True)
        elif fields["OfferIndex"] == 6:
            starrDropOpening.create_starrDrop_opening(10, "Mythic", True)
        elif fields["OfferIndex"] == 7:
            starrDropOpening.create_starrDrop_opening(10, "Legendary", True)

    def getCommandType(self):
        return 519
Classes/Commands/Client/LogicPurchaseOfferCommand.py
risporce/BSDS
import Configuration
from Classes.ByteStream import ByteStream
from Classes.Utility import Utility


class LogicCommand(ByteStream):
    def __init__(self, commandData):
        super().__init__(commandData)
        self.messageBuffer = commandData
        self.messagePayload = commandData

    def encode(self, fields):
        self.writeVInt(-1)
        self.writeVInt(-1)
        self.writeVInt(0)
        self.writeVInt(0)
        #self.writeVLong(0, 0)

    def decode(calling_instance, fields, auto_decode=True):
        fields["TickWhenGiven"] = calling_instance.readVInt()
        fields["ExecuteTick"] = calling_instance.readVInt()
        fields["ExecutorAccountID"] = calling_instance.readVLong()
        if Configuration.settings['PrintEnabled'] and auto_decode == True:
            Utility.parseFields(fields)
        return fields

    def parseFields(fields):
        if Configuration.settings['PrintEnabled']:
            Utility.parseFields(fields)

Classes/Commands/LogicCommand.py
risporce/BSDS
from Classes.Commands.LogicCommand import LogicCommand


class LogicServerCommand(LogicCommand):
    def __init__(self, commandData):
        super().__init__(commandData)

    def addCommand(self, fields):
        self.writeVInt(1)
        LogicCommand.encode(self, fields)

    def decode(calling_instance, fields):
        fields["ID"] = calling_instance.readVInt()
        return LogicCommand.decode(calling_instance, fields)

Classes/Commands/LogicServerCommand.py
risporce/BSDS
from Classes.Commands.LogicServerCommand import LogicServerCommand


class LogicChangeAvatarNameCommand(LogicServerCommand):
    def __init__(self, commandData):
        super().__init__(commandData)

    def encode(self, fields):
        self.writeString(fields["Name"])
        self.writeVInt(0)
        LogicServerCommand.encode(self, fields)
        return self.messagePayload

    def decode(self, calling_instance):
        fields = {}
        fields["Name"] = calling_instance.readString()
        fields["Unk1"] = calling_instance.readVInt()
        return LogicServerCommand.decode(calling_instance, fields)

    def getCommandType(self):
        return 201
Classes/Commands/Server/LogicChangeAvatarNameCommand.py
risporce/BSDS
from Classes.Commands.LogicServerCommand import LogicServerCommand
from Classes.Logic.LogicStarrDropData import starrDropOpening
import random


class LogicGiveDeliveryItemsCommand(LogicServerCommand):
    def __init__(self, commandData):
        super().__init__(commandData)

    def encode(self, fields):
        starrDrop = starrDropOpening.getStarrDropEncoding()
        print(starrDrop)
        self.writeVInt(30)
        self.writeVInt(1) # count rewards
        for x in range(1):
            item_name = starrDrop[0][1]
            deliveryID = starrDropOpening.getDeliveryIdFromOfferType(item_name)
            self.writeVInt(100) # type
            self.writeVInt(1)
            for y in range(1):
                self.writeVInt(starrDrop[0][2]) # amount
                if item_name == "Brawler":
                    self.writeDataReference(16,starrDrop[0][3])
                else:
                    self.writeDataReference(0, 0) # brawler id
                self.writeVInt(deliveryID)
                if item_name == "Skin":
                    self.writeDataReference(29, starrDrop[0][3])
                else:
                    self.writeDataReference(0,0) # skin id
                if item_name == "Pin":
                    self.writeDataReference(52,starrDrop[0][3]) # pin/thumbnail/spray
                elif item_name == "ProfilePic":
                    self.writeDataReference(28,starrDrop[0][3]) # pin/thumbnail/spray
                elif item_name == "Spray":
                    self.writeDataReference(68,starrDrop[0][3]) # pin/thumbnail/spray
                else:
                    self.writeDataReference(0, 0)
                if item_name == "StarPower" or item_name == "Gadget":
                    self.writeDataReference(23,starrDrop[0][3]) #star power/gadget
                else:
                    self.writeDataReference(0, 0)
                self.writeVInt(x)
                self.writeVInt(x)
                self.writeVInt(1)

        self.writeByte(1) # forced drop
        if True:
            self.writeVInt(200)
            self.writeVInt(200)
            self.writeVInt(5)
            for x in range(1):
                self.writeVInt(93)
                self.writeVInt(206)
                self.writeVInt(456)
                self.writeVInt(1001)
                self.writeVInt(2264)

        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(5)
        self.writeByte(2)
        self.writeDataReference(0, 0)
        self.writeVInt(-1)
        self.writeVInt(-1)
            
        LogicServerCommand.encode(self, fields)
        return self.messagePayload

    def decode(self, calling_instance):
        fields = {}
        return LogicServerCommand.decode(calling_instance, fields)

    def getCommandType(self):
        return 203
Classes/Commands/Server/LogicGiveDeliveryItemsCommand.py
risporce/BSDS
from Classes.Commands.LogicServerCommand import LogicServerCommand
from Classes.Logic.LogicStarrDropData import starrDropOpening


class LogicRefreshRandomRewardsCommand(LogicServerCommand):
    def __init__(self, commandData):
        super().__init__(commandData)

    def encode(self, fields):
        starrDropOpening.refreshData()

        self.writeVInt(1)
        self.writeVInt(-1)
        self.writeVInt(-1)
        self.writeVLong(0, 1)
        self.writeVInt(1)
        starrDropOpening.encode(self)

        return self.messagePayload

    def decode(self, calling_instance):
        fields = {}
        return LogicServerCommand.decode(calling_instance, fields)

    def getCommandType(self):
        return 228
Classes/Commands/Server/LogicRefreshRandomRewardsCommand.py
risporce/BSDS
import time
import threading
import traceback

from Classes.ClientsManager import ClientsManager
from Classes.Instances.Classes.Player import Player
from Classes.MessageManager import MessageManager
from Classes.Messaging import Messaging
from Classes.Crypto import Crypto


class Connection(threading.Thread):
    def __init__(self, socket, address):
        super().__init__()
        self.client = socket
        self.address = address
        self.player = Player()
        self.timeout = time.time()

    def recv(self, n):
        data = bytearray()
        while len(data) < n:
            packet = self.client.recv(n - len(data))
            if not packet:
                return b''
            data.extend(packet)
        return data

    def run(self):
        cryptoInit = Crypto()
        try:
            while True:
                time.sleep(0.001)
                messageHeader = self.client.recv(7)
                if len(messageHeader) >= 7:
                    headerData = Messaging.readHeader(messageHeader)
                    self.timeout = time.time()
                    packetPayload = Connection.recv(self, headerData[1])
                    packetID = headerData[0]
                    packetPayload = cryptoInit.decryptClient(packetID, bytes(packetPayload))
                    # print("Received", packetID, LogicLaserMessageFactory.getMessageName(packetID), "length", headerData[1], "data", packetPayload, '\n')
                    MessageManager.receiveMessage(self, packetID, packetPayload, cryptoInit)

                if time.time() - self.timeout > 7:
                    print(f"Client with ip: {self.address} disconnected!")
                    allSockets = ClientsManager.GetAll()
                    if self.player.ID[1] in allSockets.keys() and allSockets[self.player.ID[1]]["Socket"] == self.client:
                        ClientsManager.RemovePlayer(self.player.ID)
                    self.client.close()
                    break

        except ConnectionError:
            print(f"Client with ip: {self.address} disconnected!")
            allSockets = ClientsManager.GetAll()
            if self.player.ID[1] in allSockets.keys() and allSockets[self.player.ID[1]]["Socket"] == self.client:
                ClientsManager.RemovePlayer(self.player.ID)
            self.client.close()

        except Exception:
            print(traceback.format_exc())
Classes/Connection.py
risporce/BSDS
from os import urandom
from hashlib import blake2b
from Classes.TweetnaclCrypto.tweetnacl import (
    crypto_secretbox_xsalsa20poly1305_tweet,
    crypto_secretbox_xsalsa20poly1305_tweet_open,
    crypto_scalarmult_curve25519_tweet_base,
    crypto_box_curve25519xsalsa20poly1305_tweet_beforenm,
    )

class Nonce:
    def __init__(self, nonce=None, clientKey=None, serverKey=None):
        if not clientKey:
            if nonce:
                self._nonce = nonce
            else:
                self._nonce = urandom(24)
        else:
            b2 = blake2b(digest_size=24)
            if nonce:
                b2.update(bytes(nonce))
            b2.update(bytes(clientKey))
            b2.update(serverKey)
            self._nonce = b2.digest()

    def __bytes__(self):
        return self._nonce
    def __len__(self):
        return len(self._nonce)
    def increment(self):
        self._nonce = (int.from_bytes(self._nonce, 'little') + 2).to_bytes(24, 'little')


class Crypto:
    def __init__(self):
        self.server_private_key = bytearray(b'\x9e\xd9n\x05W\xf9\xde\xea\xccy\xb1\xe4;O]\xd9\x19!q\xb9w\xab\xcd\xf6\x0b\xb9\xb9\x16\x8c\x98k\x14')
        self.server_public_key = bytearray(32)
        self.client_public_key = None
        self.session_key = None
        self.shared_encryption_key = bytes(urandom(32))
        self.decryptNonce = None
        self.encryptNonce = Nonce(urandom(24))
        self.nonce = None
        self.s = bytearray(32)

    def decryptClient(self, packet_id, payload):
        if packet_id == 10100:
            return payload
        elif packet_id == 10101:
            self.client_public_key = bytes(payload[:32])
            payload = payload[32:]
            crypto_scalarmult_curve25519_tweet_base(self.server_public_key, self.server_private_key)
            self.nonce = Nonce(clientKey=self.client_public_key, serverKey=self.server_public_key)
            crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(self.s, self.client_public_key, self.server_private_key)
            payload = bytearray(16) + bytearray(payload) 
            decrypted = bytearray(len(payload))
            crypto_secretbox_xsalsa20poly1305_tweet_open(decrypted, payload, len(payload), bytes(self.nonce), self.s)
            decrypted = decrypted[32:]
            self.decryptNonce = Nonce(bytes(decrypted[24:48]))
            return decrypted[48:]
        elif self.decryptNonce is None:
            return payload
        else:
            self.decryptNonce.increment()
            payload = bytearray(16) + bytearray(payload)
            decrypted = bytearray(len(payload))
            crypto_secretbox_xsalsa20poly1305_tweet_open(decrypted, payload, len(payload), bytes(self.decryptNonce), self.shared_encryption_key)
            return decrypted[32:]

    def encryptServer(self, packet_id, payload):
        if packet_id == 20100 or packet_id == 20103:
            return payload
        else:
            if packet_id == 20104:
                nonce = Nonce(bytes(self.decryptNonce), clientKey=self.client_public_key, serverKey=self.server_public_key)
                payload = bytes(self.encryptNonce) + self.shared_encryption_key + payload
                payload = bytearray(32) + bytearray(payload)
                encrypted = bytearray(len(payload))
                crypto_secretbox_xsalsa20poly1305_tweet(encrypted, payload, len(payload), bytes(nonce), self.s)
                return encrypted[16:]
            else:
                self.encryptNonce.increment()
                payload = bytearray(32) + bytearray(payload)
                encrypted = bytearray(len(payload))
                crypto_secretbox_xsalsa20poly1305_tweet(encrypted, payload, len(payload), bytes(self.encryptNonce), self.shared_encryption_key)
                return encrypted[16:]
Classes/Crypto.py
risporce/BSDS
class Debugger:
    @staticmethod
    def error(message):
        print("[ERROR]", message)

    @staticmethod
    def warning(message):
        print("[WARNING]", message)
Classes/Debugger.py
risporce/BSDS
import csv


class Cards:
    def getCardsListFromMetaType(self, meta_type):
        CardsID = []
        with open('Classes/Files/Assets/cards.csv') as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            line_count = 0
            for row in csv_reader:
                if line_count == 0 or line_count == 1:
                    line_count += 1
                else:
                    if row[8] == str(meta_type) and row[4].lower() != "true":
                        CardsID.append(line_count - 2)
                    line_count += 1

            return CardsID
        
    def getBrawlerFromSepcificRarity(self, rarity):
        BrawlersCardsIds = []
        codenames = []
        Brawlers = []
        with open('Classes/Files/Assets/cards.csv') as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            line_count = 0
            for row in csv_reader:
                if line_count == 0 or line_count == 1:
                    line_count += 1
                else:
                    if row[8] == '0' and row[4].lower() != "true" and row[15].lower() == rarity:
                        BrawlersCardsIds.append(line_count - 2)
                        codenames.append(row[3])
                    line_count += 1
            with open("Classes/Files/Assets/characters.csv") as characters:
                csv_reader = csv.reader(characters, delimiter=',')
                line_count = 0
                for row in csv_reader:
                    if line_count == 0 or line_count == 1:
                        line_count+=1
                    else:
                        if row[0] in codenames and row[26] == 'Hero':
                            Brawlers.append(line_count -2)
            return Brawlers

Classes/Files/Classes/Cards.py
risporce/BSDS
import csv


class Characters:

    def getBrawlerFromSepcificRarity(self, rarity):
        BrawlersCardsIds = []
        codenames = []
        Brawlers = []
        with open('Classes/Files/Assets/cards.csv') as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            line_count = 0
            for row in csv_reader:
                if line_count == 0 or line_count == 1:
                    line_count += 1
                else:
                    if row[8] == '0' and row[4].lower() != "true" and row[15].lower() == rarity:
                        BrawlersCardsIds.append(line_count - 2)
                        codenames.append(row[3])
                    line_count += 1
            with open("Classes/Files/Assets/characters.csv") as characters:
                csv_reader = csv.reader(characters, delimiter=',')
                line_count = 0
                for row in csv_reader:
                    if line_count == 0 or line_count == 1:
                        line_count+=1
                    else:
                        if row[0] in codenames and row[26] == 'Hero':
                            Brawlers.append(line_count -2)
                        line_count+=1
            return Brawlers
Classes/Files/Classes/Characters.py
risporce/BSDS
import csv


class Locations:
    def getAllMaps():
        Maps = []
        with open('Classes/Files/assets/csv_logic/locations.csv', encoding="utf8") as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            line_count = 0
            for row in csv_reader:
                if line_count == 0 or line_count == 1:
                    line_count += 1
                else:
                    if row[1].lower() != 'true':
                            Maps.append(line_count - 2)
                    if row[0] != "":
                        line_count += 1
            return Maps
Classes/Files/Classes/Locations.py
risporce/BSDS
import csv

class Emotes:

    def getPinsIDSSpecificPrice(self, min, max):
        EmotesID = []
        with open('Classes/Files/Assets/emotes.csv') as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            line_count = 0
            for row in csv_reader:
                if line_count == 0 or line_count == 1:
                    line_count += 1
                else:
                    if row[1].lower() != 'true':
                        pin_gem_price = row[18]
                        if (pin_gem_price != ''):
                            if int(pin_gem_price) >= min and int(pin_gem_price) <= max:
                                EmotesID.append(line_count - 2)
                    if row[0] != "":
                        line_count += 1

            return EmotesID
Classes/Files/Classes/Pins.py
risporce/BSDS
import csv


class PlayerThumbnails:
    def getThumbnailsCount(self):
        with open('Classes/Files/Assets/player_thumbnails.csv') as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            line_count = 0
            for row in csv_reader:
                if row[0] != "":
                    line_count += 1
            return line_count - 3
Classes/Files/Classes/PlayerThumbnails.py
risporce/BSDS
import csv


class Regions:
    def getRegionByID(self, regionID):
        RegionID = 0
        with open('Classes/Files/assets/csv_logic/regions.csv') as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            line_count = 0
            for row in csv_reader:
                if line_count <= 1:
                    line_count += 1
                elif line_count - 2 == regionID:
                    RegionID = row[0]
                    break
                else:
                    line_count += 1

            return RegionID

    def getIDByRegion(self, regionName):
        RegionID = 0
        with open('Classes/Files/assets/csv_logic/regions.csv') as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            line_count = 0
            for row in csv_reader:
                if line_count <= 1:
                    line_count += 1
                elif row[0] == regionName:
                    RegionID = line_count - 2
                    break
                else:
                    line_count += 1

            return RegionID
Classes/Files/Classes/Regions.py
risporce/BSDS
import csv

class Skins:
    def getSkinsIDSSpecificPrice(self, min, max):
        SkinsID = []
        with open('Classes/Files/Assets/skins.csv') as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            line_count = 0
            for row in csv_reader:
                if line_count == 0 or line_count == 1:
                    line_count += 1
                else:
                    if row[2].lower() != 'true':
                        skin_gem_price = row[15]
                        if (skin_gem_price != ''):
                            if int(skin_gem_price) >= min and int(skin_gem_price) <= max:
                                SkinsID.append(line_count - 2)
                    if row[0] != "":
                        line_count += 1

            return SkinsID

Classes/Files/Classes/Skins.py
risporce/BSDS
import csv

class Sprays:
    def getSpraysIDSSpecificPrice(self, min, max):
        SpraysID = []
        with open('Classes/Files/Assets/sprays.csv') as csv_file:
            csv_reader = csv.reader(csv_file, delimiter=',')
            line_count = 0
            for row in csv_reader:
                if line_count == 0 or line_count == 1:
                    line_count += 1
                else:
                    if row[2].lower() != 'true':
                        spray_gem_price = row[17]
                        if (spray_gem_price != ''):
                            if int(spray_gem_price) >= min and int(spray_gem_price) <= max:
                                SpraysID.append(line_count - 2)
                    if row[0] != "":
                        line_count += 1

            return SpraysID

Classes/Files/Classes/Sprays.py
risporce/BSDS
class Alliance:
    pass
Classes/Instances/Classes/Alliance.py
risporce/BSDS
import json
import random
import string


class Player:
    ClientVersion = "0.0.0"

    ID = [0, 1]
    Token = ""
    Name = "Brawler"
    Registered = False
    Thumbnail = 0
    Namecolor = 0
    Region = "CA"
    ContentCreator = "BSDS"

    Coins = 999999
    Gems = 999999
    StarPoints = 999999
    Trophies = 999999
    HighestTrophies = 999999
    TrophyRoadTier = 105
    Experience = 999999
    Level = 500
    Tokens = 200
    TokensDoubler = 1000

    SelectedSkins = {}
    SelectedBrawlers = [56, 54, 48]
    RandomizerSelectedSkins = []
    OwnedPins = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 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, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687]
    OwnedThumbnails = [60, 61, 63, 64, 69, 70, 72, 73, 76, 77, 78, 79, 83, 84]
    OwnedBrawlers = {
        0: {'CardID': 0, 'Skins': [29, 52, 122, 158, 194, 195, 319, 320, 321, 358], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        1: {'CardID': 4, 'Skins': [2, 103, 69, 134, 216, 302, 322, 323, 324, 325, 329, 330, 376], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        2: {'CardID': 8, 'Skins': [25, 64, 102, 177, 217, 218, 261, 391, 466], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        3: {'CardID': 12, 'Skins': [5, 58, 72, 91, 200, 241, 398, 399], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        4: {'CardID': 16, 'Skins': [26, 68, 129, 170, 222, 223, 395, 463], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        5: {'CardID': 20, 'Skins': [11, 96, 207, 262, 300, 301, 442], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        6: {'CardID': 24, 'Skins': [27, 59, 90, 92, 116, 219, 220, 356, 432], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        7: {'CardID': 28, 'Skins': [44, 47, 123, 161, 173, 252, 253, 393], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        8: {'CardID': 32, 'Skins': [15, 435, 60, 79, 147, 296, 297, 346], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        9: {'CardID': 36, 'Skins': [56, 57, 97, 159, 235, 275, 313, 314, 315, 396, 428, 429, 456], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        10: {'CardID': 40, 'Skins': [28, 30, 128, 182, 186, 212, 316, 317, 318, 353, 359, 434, 437], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        11: {'CardID': 44, 'Skins': [50, 63, 75, 172, 227, 229, 226, 228, 310], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        12: {'CardID': 48, 'Skins': [20, 49, 95, 100, 101, 247, 248, 388], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        13: {'CardID': 52, 'Skins': [71, 139, 213, 341, 404, 405], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        14: {'CardID': 56, 'Skins': [94, 98, 99, 162, 215, 244, 362, 363, 439, 467], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        15: {'CardID': 60, 'Skins': [108, 120, 146, 196, 197, 233, 380], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        16: {'CardID': 64, 'Skins': [178, 354, 409, 410], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        17: {'CardID': 68, 'Skins': [111, 144, 258, 259, 281], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        18: {'CardID': 72, 'Skins': [70, 157, 249, 250, 263, 350], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        19: {'CardID': 95, 'Skins': [61, 88, 164, 273, 447, 448], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        20: {'CardID': 100, 'Skins': [45, 125, 224, 225, 243], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        21: {'CardID': 105, 'Skins': [117, 171, 303, 304, 387], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        22: {'CardID': 110, 'Skins': [189, 242, 245, 246], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        23: {'CardID': 115, 'Skins': [110, 126, 130, 198, 199, 311], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        24: {'CardID': 120, 'Skins': [214, 308, 440, 449, 450, 472], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        25: {'CardID': 125, 'Skins': [93, 104, 131, 133, 266, 307, 422, 423], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        26: {'CardID': 130, 'Skins': [145, 221, 272, 344, 420, 421], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        27: {'CardID': 177, 'Skins': [109, 142, 282, 400, 401, 407], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        28: {'CardID': 182, 'Skins': [118, 209, 286, 370, 371], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        29: {'CardID': 188, 'Skins': [138, 187, 283, 284, 289, 364, 365], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        30: {'CardID': 194, 'Skins': [166, 184, 185, 208], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        31: {'CardID': 200, 'Skins': [151, 331, 332, 413, 468], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        32: {'CardID': 206, 'Skins': [136, 201, 231, 309, 402, 403], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        34: {'CardID': 218, 'Skins': [175, 188, 306, 438, 443, 444], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        35: {'CardID': 224, 'Skins': [179, 240, 366, 367, 386], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        36: {'CardID': 230, 'Skins': [193, 232, 368, 369], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        37: {'CardID': 236, 'Skins': [176, 210, 378, 381, 477, 481, 482], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        38: {'CardID': 279, 'Skins': [202, 291, 417, 485, 486], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        39: {'CardID': 296, 'Skins': [211, 269, 389, 426, 427], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        40: {'CardID': 303, 'Skins': [279, 424, 425], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        41: {'CardID': 320, 'Skins': [236, 265, 305, 445, 446], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        42: {'CardID': 327, 'Skins': [357], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        43: {'CardID': 334, 'Skins': [462, 280, 433], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        44: {'CardID': 341, 'Skins': [267, 285, 479, 480], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        45: {'CardID': 358, 'Skins': [276, 345, 418], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        46: {'CardID': 365, 'Skins': [293, 478], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        47: {'CardID': 372, 'Skins': [390, 416], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        48: {'CardID': 379, 'Skins': [471], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        49: {'CardID': 386, 'Skins': [342, 384, 483, 484], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        50: {'CardID': 393, 'Skins': [452], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        51: {'CardID': 410, 'Skins': [379], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        52: {'CardID': 417, 'Skins': [464], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        53: {'CardID': 427, 'Skins': [431], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        54: {'CardID': 434, 'Skins': [454], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
        56: {'CardID': 448, 'Skins': [473], 'Trophies': 1250, 'HighestTrophies': 1250, 'PowerLevel': 11, 'PowerPoints': 0, 'State': 2},
    }

    def __init__(self):
        pass

    def getDataTemplate(self, highid, lowid, token):
        if highid == 0 or lowid == 0:
            self.ID[0] = int(''.join([str(random.randint(0, 9)) for _ in range(1)]))
            self.ID[1] = int(''.join([str(random.randint(0, 9)) for _ in range(8)]))
            self.Token = ''.join(random.choice(string.ascii_letters + string.digits) for i in range(40))
        else:
            self.ID[0] = highid
            self.ID[1] = lowid
            self.Token = token

        DBData = {
            'ID': self.ID,
            'Token': self.Token,
            'Name': self.Name,
            'Registered': self.Registered,
            'Thumbnail': self.Thumbnail,
            'Namecolor': self.Namecolor,
            'Region': self.Region,
            'ContentCreator': self.ContentCreator,
            'Coins': self.Coins,
            'Gems': self.Gems,
            'StarPoints': self.StarPoints,
            'Trophies': self.Trophies,
            'HighestTrophies': self.HighestTrophies,
            'TrophyRoadTier': self.TrophyRoadTier,
            'Experience': self.Experience,
            'Level': self.Level,
            'Tokens': self.Tokens,
            'TokensDoubler': self.TokensDoubler,
            'SelectedBrawlers': self.SelectedBrawlers,
            'OwnedPins': self.OwnedPins,
            'OwnedThumbnails': self.OwnedThumbnails,
            'OwnedBrawlers': self.OwnedBrawlers
        }
        return DBData

    def toJSON(self):
        return json.loads(json.dumps(self, default=lambda o: o.__dict__,
            sort_keys=True, indent=4))
Classes/Instances/Classes/Player.py
risporce/BSDS
class InstanceHandler:
    pass
Classes/Instances/InstanceHandler.py
risporce/BSDS
from Classes.ByteStreamHelper import ByteStreamHelper
from Classes.Logic.LogicLong import LogicLong

class LogicBattlePlayerMap:
    def decode(bytestream, fields):
        battleMap = fields["Map"][0]
        fields["MapID"] = LogicLong()
        ByteStreamHelper.decodeLogicLong(self, fields["MapID"])
        #fields[""]
Classes/Logic/LogicBattlePlayerMap.py
risporce/BSDS
from Classes.Commands.Client.LogicPurchaseOfferCommand import LogicPurchaseOfferCommand
from Classes.Commands.Client.LogicOpenRandomCommand import LogicOpenRandomCommand
from Classes.Commands.Server.LogicChangeAvatarNameCommand import LogicChangeAvatarNameCommand
from Classes.Commands.Server.LogicGiveDeliveryItemsCommand import LogicGiveDeliveryItemsCommand
from Classes.Commands.Server.LogicRefreshRandomRewardsCommand import LogicRefreshRandomRewardsCommand



class LogicCommandManager:
    commandsList = {
        201: LogicChangeAvatarNameCommand,
        202: 'LogicDiamondsAddedCommand',
        203: LogicGiveDeliveryItemsCommand,
        204: 'LogicDayChangedCommand',
        205: 'LogicDecreaseHeroScoreCommand',
        206: 'LogicAddNotificationCommand',
        207: 'LogicChangeResourcesCommand',
        208: 'LogicTransactionsRevokedCommand',
        209: 'LogicKeyPoolChangedCommand',
        210: 'LogicIAPChangedCommand',
        211: 'LogicOffersChangedCommand',
        212: 'LogicPlayerDataChangedCommand',
        213: 'LogicInviteBlockingChangedCommand',
        214: 'LogicGemNameChangeStateChangedCommand',
        215: 'LogicSetSupportedCreatorCommand',
        216: 'LogicCooldownExpiredCommand',
        217: 'LogicProLeagueSeasonChangedCommand',
        218: 'LogicBrawlPassSeasonChangedCommand',
        219: 'LogicBrawlPassUnlockedCommand',
        220: 'LogicHerowinQuestsChangedCommand',
        221: 'LogicTeamChatMuteStateChangedCommand',
        222: 'LogicRankedSeasonChangedCommand',
        223: 'LogicCooldownAddedCommand',
        224: 'LogicSetESportsHubNotificationCommand',
        228: LogicRefreshRandomRewardsCommand,
        500: 'LogicGatchaCommand',
        503: 'LogicClaimDailyRewardCommand',
        504: 'LogicSendAllianceMailCommand',
        505: 'LogicSetPlayerThumbnailCommand',
        506: 'LogicSelectSkinCommand',
        507: 'LogicUnlockSkinCommand',
        508: 'LogicChangeControlModeCommand',
        509: 'LogicPurchaseDoubleCoinsCommand',
        511: 'LogicHelpOpenedCommand',
        512: 'LogicToggleInGameHintsCommand',
        514: 'LogicDeleteNotificationCommand',
        515: 'LogicClearShopTickersCommand',
        517: 'LogicClaimRankUpRewardCommand',
        518: 'LogicPurchaseTicketsCommand',
        519: LogicPurchaseOfferCommand,
        520: 'LogicLevelUpCommand',
        521: 'LogicPurchaseHeroLvlUpMaterialCommand',
        522: 'LogicHeroSeenCommand',
        523: 'LogicClaimAdRewardCommand',
        524: 'LogicVideoStartedCommand',
        525: 'LogicSelectCharacterCommand',
        526: 'LogicUnlockFreeSkinsCommand',
        527: 'LogicSetPlayerNameColorCommand',
        528: 'LogicViewInboxNotificationCommand',
        529: 'LogicSelectStarPowerCommand',
        530: 'LogicSetPlayerAgeCommand',
        531: 'LogicCancelPurchaseOfferCommand',
        532: 'LogicItemSeenCommand',
        533: 'LogicQuestSeenCommand',
        534: 'LogicPurchaseBrawlPassCommand',
        535: 'LogicClaimTailRewardCommand',
        536: 'LogicPurchaseBrawlpassProgressCommand',
        537: 'LogicVanityItemSeenCommand',
        538: 'LogicSelectEmoteCommand',
        539: 'LogicBrawlPassAutoCollectWarningSeenCommand',
        540: 'LogicPurchaseChallengeLivesCommand',
        541: 'LogicClearESportsHubNotificationCommand',
        542: 'LogicSelectGroupSkinCommand',
        571: LogicOpenRandomCommand
    }

    def getCommandsName(commandType):
        try:
            command = LogicCommandManager.commandsList[commandType]
        except KeyError:
            command = str(commandType)
        if type(command) == str:
            return command
        else:
            return command.__name__

    def commandExist(commandType):
        return (commandType in LogicCommandManager.commandsList.keys())

    def createCommand(commandType, commandPayload=b''):
        commandList = LogicCommandManager.commandsList
        if LogicCommandManager.commandExist(commandType):
            print(LogicCommandManager.getCommandsName(commandType), "created")
            if type(commandList[commandType]) == str:
                pass
            else:
                return commandList[commandType](commandPayload)
        else:
            print(commandType, "skipped")
            return None

    def isServerToClient(commandType):
        if 200 <= commandType < 500:
            return True
        elif 500 <= commandType:
            return False
Classes/Logic/LogicCommandManager.py
risporce/BSDS
from Classes.Packets.Client.Authentification.ClientHelloMessage import ClientHelloMessage
from Classes.Packets.Client.Authentification.LoginMessage import LoginMessage
from Classes.Packets.Client.Battle.AskForBattleEndMessage import AskForBattleEndMessage
from Classes.Packets.Client.Home.ChangeAvatarNameMessage import ChangeAvatarNameMessage
from Classes.Packets.Client.Home.EndClientTurnMessage import EndClientTurnMessage
from Classes.Packets.Client.Home.GoHomeFromOfflinePractiseMessage import GoHomeFromOfflinePractiseMessage
from Classes.Packets.Client.Home.GoHomeMessage import GoHomeMessage
from Classes.Packets.Client.Home.GetPlayerProfileMessage import GetPlayerProfileMessage
from Classes.Packets.Client.Home.AskForAllianceDataMessage import AskForAllianceDataMessage
from Classes.Packets.Client.Socket.KeepAliveMessage import KeepAliveMessage
from Classes.Packets.Server.Authentification.LoginFailedMessage import LoginFailedMessage
from Classes.Packets.Server.Authentification.LoginOkMessage import LoginOkMessage
from Classes.Packets.Server.Authentification.OutOfSyncMessage import OutOfSyncMessage
from Classes.Packets.Server.Authentification.ServerHelloMessage import ServerHelloMessage
from Classes.Packets.Server.Battle.BattleEndMessage import BattleEndMessage
from Classes.Packets.Server.Home.AvailableServerCommandMessage import AvailableServerCommandMessage
from Classes.Packets.Server.Home.LobbyInfoMessage import LobbyInfoMessage
from Classes.Packets.Server.Home.OwnHomeDataMessage import OwnHomeDataMessage
from Classes.Packets.Server.Socket.KeepAliveServerMessage import KeepAliveServerMessage
from Classes.Packets.Server.Home.PlayerProfileMessage import PlayerProfileMessage
from Classes.Packets.Server.Home.MyAllianceMessage import MyAllianceMessage
from Classes.Packets.Server.Home.AllianceDataMessage import AllianceDataMessage


class LogicLaserMessageFactory:
    messagesList = {
        10055: 'AskPlayerJWTokenMessage',
        10099: 'ClientCryptoErrorMessage',
        10100: ClientHelloMessage,
        10101: LoginMessage,
        10102: 'LoginUsingSessionMessage',
        10103: 'CreateAccountMessage',
        10107: 'ClientCapabilitiesMessage',
        10108: KeepAliveMessage,
        10109: 'UdpCheckConnectionMessage',
        10110: 'AnalyticEventMessage',
        10111: 'AccountIdentifiersMessage',
        10112: 'AuthenticationCheckMessage',
        10113: 'SetDeviceTokenMessage',
        10116: 'ResetAccountMessage',
        10117: 'ReportUserMessage',
        10118: 'AccountSwitchedMessage',
        10119: 'ReportAllianceStreamMessage',
        10121: 'UnlockAccountMessage',
        10150: 'AppleBillingRequestMessage',
        10151: 'GoogleBillingRequestMessage',
        10152: 'TencentBillingRequestMessage',
        10153: 'CafeBazaarBillingRequestMessage',
        10159: 'KunlunBillingRequestMessage',
        10160: 'BillingCancelledByClientMessage',
        10177: 'ClientInfoMessage',
        10212: ChangeAvatarNameMessage,
        10309: 'GetAllianceInviteTokenMessage',
        10321: 'AttributionEventMessage',
        10401: 'CreateGameMessage',
        10501: 'AcceptFriendMessage',
        10502: 'AddFriendMessage',
        10503: 'AskForAddableFriendsMessage',
        10504: 'AskForFriendListMessage',
        10506: 'RemoveFriendMessage',
        10507: 'AddFriendByEmailMessage',
        10509: 'AddFriendByAvatarNameAndCodeMessage',
        10512: 'AskForPlayingGamecenterFriendsMessage',
        10513: 'AskForPlayingFacebookFriendsMessage',
        10514: 'AskForPlayingKakaoFriendsMessage',
        10515: 'AskForPlayingTencentFriendsMessage',
        10516: 'AskForPlayingLineFriendsMessage',
        10517: 'AskForPlayingSupercellFriendsMessage',
        10523: 'YoozooBillingRequestMessage',
        10555: 'ClientInputMessage',
        10576: 'SetBlockFriendRequestsMessage',
        10599: 'AskForFriendSuggestionsMessage',
        10636: 'SCIDBindAccountMessage',
        11736: 'SCIDLogoutAllDevicesMessage',
        12100: 'CreatePlayerMapMessage',
        12101: 'DeletePlayerMapMessage',
        12102: 'GetPlayerMapsMessage',
        12103: 'UpdatePlayerMapMessage',
        12104: 'SubmitPlayerMapMessage',
        12105: 'PublishPlayerMapMessage',
        12106: 'ChangePlayerMapNameMessage',
        12107: 'EnterMapEditorMessage',
        12108: 'GoHomeFromMapEditorMessage',
        12110: 'TeamSetPlayerMapMessage',
        12111: 'SignoffPlayerMapMessage',
        12125: 'ReportPlayerMapMessage',
        12152: 'RankedMatchBanHeroMessage',
        12155: 'RankedMatchPickHeroMessage',
        12157: 'RankedMatchUpdateHeroDataMessage',
        12905: 'GetCurrentBattleReplayDataMessage',
        12998: 'SetCountryMessage',
        13922: 'AcceptTokenFriendMessage',
        14101: GoHomeMessage,
        14102: EndClientTurnMessage,
        14103: 'StartGameMessage',
        14104: 'StartSpectateMessage',
        14105: 'HomeLogicStoppedMessage',
        14106: 'CancelMatchmakingMessage',
        14107: 'StopSpectateMessage',
        14108: 'GoHomeFromSpectateMessage',
        #14109: GoHomeFromOfflinePractiseMessage, //before v50
        14110: AskForBattleEndMessage,
        #14113: GetPlayerProfileMessage, //before v50
        14114: 'GetBattleLogMessage',
        14115: 'BattleLogViewReplayMessage',
        14116: 'ViewReplayByStringMessage',
        14117: 'RequestMatchCancelMessage',
        14118: 'SinglePlayerMatchRequestMessage',
        14166: 'ChronosEventSeenMessage',
        14167: 'ChronosEventSeenMessage',
        14177: 'PlayAgainMessage',
        14178: 'DebugCommandMessage',
        14199: 'LookForGameRoomRequestMessage',
        14211: 'UnbindFacebookAccountMessage',
        14201: 'BindFacebookAccountMessage',
        14202: 'BindKakaoAccountMessage',
        14203: 'BingLineAccountMessage',
        14212: 'BindGamecenterAccountMessage',
        14213: 'UnbindKakaoAccountMessage',
        14214: 'UnbindLineAccountMessage',
        14262: 'BindGoogleServiceAccountMessage',
        14266: 'BindTencentAccountMessage',
        14268: 'TencentCheckCanPayMessage',
        14276: 'TencentAntiAddictionInstructionExecutedMessage',
        14277: 'GetSeasonRewardsMessage',
        14299: 'SetAllianceCountryMessage',
        14301: 'CreateAllianceMessage',
        14302: AskForAllianceDataMessage,
        14303: 'AskForJoinableAlliancesListMessage',
        14304: 'AskForAllianceStreamMessage',
        14305: 'JoinAllianceMessage',
        14306: 'ChangeAllianceMemberRoleMessage',
        14307: 'KickAllianceMemberMessage',
        14308: 'LeaveAllianceMessage',
        14315: 'ChatToAllianceStreamMessage',
        14316: 'ChangeAllianceSettingsMessage',
        14317: 'RequestJoinAllianceMessage',
        14321: 'RespondToAllianceJoinRequestMessage',
        14322: 'SendAllianceInvitationMessage',
        14323: 'JoinAllianceUsingInvitationMessage',
        14324: 'SearchAlliancesMessage',
        14326: 'SendAllianceInvitationToFriendMessage',
        14330: 'SendAllianceMailMessage',
        14350: 'TeamCreateMessage',
        14351: 'TeamJoinMessage',
        14352: 'TeamKickMessage',
        14353: 'TeamLeaveMessage',
        14354: 'TeamChangeMemberSettingsMessage',
        14355: 'TeamSetMemberReadyMessage',
        14356: 'TeamTogglePractiseMessage',
        14357: 'TeamToggleMemberSideMessage',
        14358: 'TeamSpectateMessage',
        14359: 'TeamChatMessage',
        14360: 'TeamPostAdMessage',
        14361: 'TeamMemberStatusMessage',
        14362: 'TeamSetEventMessage',
        14363: 'TeamSetLocationMessage',
        14364: 'TeamReportChatMessage',
        14365: 'TeamInviteMessage',
        14366: 'PlayerStatusMessage',
        14367: 'TeamClearInviteMessage',
        14368: 'TeamInviteResponseMessage',
        14369: 'TeamPremadeChatMessage',
        14370: 'TeamAllianceMemberInviteMessage',
        14371: 'TeamJoinOrCreateGameRoomMessage',
        14372: 'TeamToggleSettingsMessage',
        14373: 'TeamBotSlotDisableMessage',
        14403: 'GetLeaderboardMessage',
        14405: 'AskForAvatarStreamMessage',
        14406: 'AskForBattleReplayStreamMessage',
        14418: 'RemoveAvatarStreamEntryMessage',
        14469: 'AlliancePremadeChatMessage',
        14479: 'TeamInvitationResponseMessage',
        14600: 'AvatarNameCheckRequestMessage',
        14700: 'ListBrawlTvChannelsMessage',
        14701: 'TuneBrawlTvChannelMessage',
        14715: 'SendGlobalChatLineMessage',
        14777: 'SetInvitesBlockedMessage',
        14778: 'SetTeamChatMutedMessage',
        14867: 'SetRegionMessage',
        14880: 'TeamRequestJoinCancelMessage',
        14881: 'TeamRequestJoinMessage',
        14882: 'TeamRequestJoinApproveMessage',
        15081: GetPlayerProfileMessage, #v50
        15793: 'GetTokenFriendMessage',
        16000: 'LogicDeviceLinkCodeRequestMessage',
        16001: 'LogicDeviceLinkMenuClosedMessage',
        16002: 'LogicDeviceLinkEnterCodeMessage',
        16003: 'LogicDeviceLinkConfirmYesMessage',
        16939: 'AskApiTokenMessage',
        17000: 'LogicAccountTransferCodeRequestMessage',
        17190: 'JoinAllianceUsingTokenMessage',
        17337: 'UnbotifyReportMessage',
        17338: 'AdjustPackageMessage',
        17750: GoHomeFromOfflinePractiseMessage, #v50
        18686: 'SetSupportedCreatorMessage',
        19001: 'LatencyTestResultMessage',
        19002: 'UdpLatencyTestRequestMessage',
        19003: 'TriggerStartLatencyTestMessage',
        19004: 'RequestLatencyTestStatusMessage',
        20000: 'SetEncryptionMessage',
        20100: ServerHelloMessage,
        20101: 'CreateAccountOkMessage',
        20103: LoginFailedMessage,
        20104: LoginOkMessage,
        20105: 'FriendListMessage',
        20106: 'FriendListUpdateMessage',
        20107: 'AddableFriendsMessage',
        20108: KeepAliveServerMessage,
        20109: 'FriendOnlineStatusMessage',
        20110: 'FriendLoggedInMessage',
        20111: 'FriendLoggedOutMessage',
        20112: 'AddFriendFailedMessage',
        20117: 'ReportUserStatusMessage',
        20118: 'ChatAccountBanStatusMessage',
        20121: 'BillingRequestFailedMessage',
        20132: 'UnlockAccountOkMessage',
        20133: 'UnlockAccountFailedMessage',
        20151: 'AppleBillingProcessedByServerMessage',
        20152: 'GoogleBillingProcessedByServerMessage',
        20153: 'TencentBillingProcessedByServerMessage',
        20154: 'CafeBazaarBillingProcessedByServerMessage',
        20156: 'KunlunBillingProcessedByServerMessage',
        20161: 'ShutdownStartedMessage',
        20171: 'PersonalBreakStartedMessage',
        20173: 'YoozooBillingProcessedByServerMessage',
        20199: 'FriendSuggestionsMessage',
        20205: 'AvatarNameChangeFailedMessage',
        20206: 'AvatarOnlineStatusUpdated',
        20207: 'AllianceOnlineStatusUpdatedMessage',
        20300: 'AvatarNameCheckResponseMessage',
        20402: 'CreateGameFailedMessage',
        20405: 'MatchMakingStatusMessage',
        20406: 'MatchMakingCancelledMessage',
        20501: 'AcceptFriendFailedMessage',
        20523: 'YoozooOrderAvailableMessage',
        20545: 'YoozooOrderDeliveryFailedMessage',
        20559: 'StartLoadingMessage',
        20801: 'NotificationMessage',
        20802: 'OpponentRejoinsMatchNotificationMessage',
        20931: 'AntiAddictionDataUpdatedMessage',
        22089: 'GetTokenFriendResultMessage',
        22100: 'CreatePlayerMapResponseMessage',
        22101: 'DeletePlayerMapResponseMessage',
        22102: 'PlayerMapsMessage',
        22103: 'UpdatePlayerMapResponseMessage',
        22104: 'SubmitPlayerMapResponseMessage',
        22105: 'PublishPlayerMapResponseMessage',
        22106: 'ChangePlayerMapNameMResponseMessage',
        22107: 'PlayerMapInfoUpdatedMessage',
        22109: 'DebugPlayerMapReviewResultOverrideSetMessage',
        22111: 'PlayerMapGreenlightedMessage',
        22125: 'ReportPlayerMapResponseMessage',
        22150: 'RankedMatchStartMessage',
        22151: 'RankedMatchBanStartedMessage',
        22152: 'RankedMatchBanHeroResponseMessage',
        22153: 'RankedMatchBanEndedMessage',
        22154: 'RankedMatchPickStartedMessage',
        22155: 'RankedMatchPickHeroFailedMessage',
        22156: 'RankedMatchHeroPickedMessage',
        22157: 'RankedMatchHeroDataUpdatedMessage',
        22158: 'RankedMatchFinalPreparationStartedMessage',
        22159: 'RankedMatchTerminatedMessage',
        22202: 'MapPreviewMessage',
        22377: 'GoogleServiceAccountBoundMessage',
        22687: 'GamecenterAccountAlreadyBoundMessage',
        22957: 'PvpMatchmakeNotificationMessage',
        23067: 'SCIDLogoutAllDevicesResultMessage',
        23302: 'GetAllianceInviteTokenResultMessage',
        23456: BattleEndMessage,
        23457: LobbyInfoMessage,
        23458: 'BattleLogMessage',
        23459: 'BattleLogReplayAvailableMessage',
        23494: 'GoogleServiceAccountAlreadyBoundMessage',
        23774: 'PlayerJWTokenMessage',
        24101: OwnHomeDataMessage,
        24104: OutOfSyncMessage,
        24105: 'SpectacleFailedMessage',
        24106: 'StopHomeLogicMessage',
        24108: 'MatchmakeFailedMessage',
        24109: 'VisionUpdateMessage',
        24111: AvailableServerCommandMessage,
        24112: 'UdpConnectionInfoMessage',
        24113: PlayerProfileMessage,
        24114: 'HomeBattleReplayDataMessage',
        24115: 'ServerErrorMessage',
        24116: 'HomeBattleReplayFailedMessage',
        24117: 'HomeBattleReplayViewedMessage',
        24123: 'SeasonRewardsMessage',
        24124: 'TeamMessage',
        24125: 'TeamLeftMessage',
        24129: 'TeamErrorMessage',
        24130: 'TeamGameStartingMessage',
        24131: 'TeamStreamMessage',
        24177: 'SetRegionResponseMessage',
        24178: 'SetCountryResponseMessage',
        24199: 'LookForGameRoomRequestMessage',
        24201: 'FacebookAccountBoundMessage',
        24202: 'FacebookAccountAlreadyBoundMessage',
        24203: 'KakaoAccountBoundMessage',
        24204: 'KakaoAccountAlreadyBoundMessage',
        24205: 'LineAccountAlreadyBoundMessage',
        24206: 'LineAccountBoundMessage',
        24214: 'FacebookAccountUnboundMessage',
        24215: 'KakaoAccountUnboundMessage',
        24216: 'LineAccountUnboundMessage',
        24220: 'TencentAccountBoundMessage',
        24221: 'TencentAccountAlreadyBoundMessage',
        24223: 'tencentCheckCanPayResponseMessage',
        24301: AllianceDataMessage,
        24304: 'JoinableAllianceListMessage',
        24308: 'AllianceMemberMessage',
        24309: 'AllianceMemberRemovedMessage',
        24310: 'AllianceListMessage',
        24311: 'AllianceStreamMessage',
        24312: 'AllianceStreamEntryMessage',
        24313: 'ChangeAllianceSettingsOkMessage',
        24318: 'AllianceStreamEntryRemovedMessage',
        24319: 'TeamStreamEntryRemovedMessage',
        24321: 'AllianceInvitationSendFailedMessage',
        24333: 'AllianceResponseMessage',
        24364: 'AllianceTeamsMessage',
        24365: 'AllianceTeamRemovedMessage',
        24399: MyAllianceMessage,
        24403: 'LeaderboardMessage',
        24411: 'AvatarStreamMessage',
        24412: 'AvatarStreamEntryMessage',
        24413: 'BattleReportStreamMessage',
        24418: 'AvatarStreamEntryRemovedMessage',
        24555: 'FriendOnlineStatusEntryMessage',
        24582: 'TeamInviteStatusMessage',
        24589: 'TeamInvitationMessage',
        24700: 'BrawlTvChannelListMessage',
        24701: 'BrawlTvChannelNextUpMessage',
        24715: 'GlobalChatLineMessage',
        24758: 'ApiTokenMessage',
        24776: 'AllianceWarMessage',
        24777: 'PlayAgainStatusMessage',
        25165: 'SCIDAccountBoundMessage',
        25892: 'DisconnectedMessage',
        26002: 'LogicDeviceLinkCodeResponseMessage',
        26003: 'LogicDeviceLinkNewDeviceLinkedMessage',
        26004: 'LogicDeviceLinkCodeDeactivatedMessage',
        26005: 'LogicDeviceLinkResponseMessage',
        26007: 'LogicDeviceLinkDoneMessage',
        26008: 'LogicDeviceLinkErrorMessage',
        26085: 'GamecenterAccountBoundMessage',
        27002: 'LogicAccountTransferCodeResponseMessage',
        28363: 'BuyBundleBillingPackResponseMessage',
        28686: 'SetSupportedCreatorResponseMessage',
        28689: 'SCIDAccountAlreadyBoundMessage',
        29001: 'StartLatencyTestRequestMessage',
        29002: 'UdpLatencyTestResponseMessage',
        29003: 'LatencyTestStatusMessage',
        29900: 'SupercellIdNotificationMessage',
        29997: 'CryptoErrorMessage',
        30000: 'AttributionMessage',
        40000: 'AdUpdateConversionValueMessage'
    }

    def getMessageName(messageType):
        try:
            message = LogicLaserMessageFactory.messagesList[messageType]
        except KeyError:
            message = str(messageType)
        if type(message) == str:
            return message
        else:
            return message.__name__

    def messageExist(messageType):
        return (messageType in LogicLaserMessageFactory.messagesList.keys())

    def createMessageByType(messageType, messagePayload):
        messagesList = LogicLaserMessageFactory.messagesList
        if LogicLaserMessageFactory.messageExist(messageType):
            if type(messagesList[messageType]) == str:
                print(LogicLaserMessageFactory.getMessageName(messageType), "skipped")
            else:
                print(LogicLaserMessageFactory.getMessageName(messageType), "created")
                return messagesList[messageType](messagePayload)
        else:
            print(messageType, "skipped")
            return None
Classes/Logic/LogicLaserMessageFactory.py
risporce/BSDS
from typing import overload


class LogicLong:
    def __init__(self):
        self.high = 0
        self.low = 0

    def __init__(self, high, low):
        self.high = high
        self.low = low

    @staticmethod
    def clone(logicLong):
        return LogicLong(logicLong.high, logicLong.low)

    def decode(self, bytestream):
        self.high = bytestream.readInt()
        self.low = bytestream.readInt()

    def encode(self, bytestream):
        bytestream.writeInt(self.high)
        bytestream.writeInt(self.low)

    def equals(self, logicLong):
        if logicLong:
            if self.low == logicLong.low:
                return self.high == logicLong.high
        return False

    @staticmethod
    def getHigherInt(longlong):
        return longlong >> 32

    @overload
    def getHigherInt(self):
        return self.high

    @staticmethod
    def getLowerInt(longlong):
        result = longlong & 0x7FFFFFFF
        if longlong < 0:
            return longlong | 0x80000000
        return result

    @overload
    def getLowerInt(self):
        return self.low

    def getLong(self):
        result = self.low
        if result >> 31 == -1:
            return result | 0x80000000
        return result

    def greaterThan(self, logicLong):
        result = False
        if logicLong:
            result = True
            if self.high <= logicLong.high:
                result = False
                if self.high == logicLong.high:
                    return self.low > logicLong.low
        return result

    def hashCode(self):
        return 31 * self.high + self.low

    def isZero(self):
        if not self.low:
            return self.high == 0
        else:
            return False

    def set(self, low, high):
        lowerInt = low & 0x7FFFFFFF
        if low < 0:
            lowerInt = low | 0x80000000
        self.high = high >> 32
        self.low = lowerInt

    def toLong(high, low):
        lowerInt = low & 0x7FFFFFFF
        if low < 0:
            lowerInt = low | 0x80000000
        return lowerInt | high << 32

    def toString(text, logiclong):
        print(text, f"LogicLong({logiclong.high},{logiclong.low})")
Classes/Logic/LogicLong.py
risporce/BSDS
from Classes.Files.Classes.Cards import Cards
from Classes.Files.Classes.Pins import Emotes
from Classes.Files.Classes.PlayerThumbnails import PlayerThumbnails
from Classes.Files.Classes.Skins import Skins
from Classes.Files.Classes.Sprays import Sprays
from Classes.Files.Classes.Characters import Characters

import random

items_ids = {
    "Coins": {
        "OfferID": 1,
        "DeliveryID": 7
    },
    "TokenDoubler": {
        "OfferID": 9,
        "DeliveryID": 2
    },
    "Credits": {
        "OfferID": 38,
        "DeliveryID": 22
    },
    "ChromaCredits": {
        "OfferID": 39,
        "DeliveryID": 23
    },
    "PowerPoints": {
        "OfferID": 41,
        "DeliveryID": 24
    },
    "Bling": {
        "OfferID": 45,
        "DeliveryID": 25
    },
    "Brawler": {
        "OfferID": 3,
        "DeliveryID": 1
    },
    "Skin": {
        "OfferID": 4,
        "DeliveryID": 9
    },
    "Pin": {
        "OfferID": 19,
        "DeliveryID": 11
    },
    "ProfilePic": {
        "OfferID": 25,
        "DeliveryID": 11
    },
    "Spray": {
        "OfferID": 35,
        "DeliveryID": 11
    },
    "StarPower": {
        "OfferID": 5,
        "DeliveryID": 4
    },
    "Gadget": {
        "OfferID": 5,
        "DeliveryID": 4
    },
}

starrDrop_data = {
    "Rare": {
        "Rarity_ID": 0,
        "DropChance": 50,
        "TotalTickets": 215,
        "Possibilities": {
            "Coins_s": {
                "Type": "Coins",
                "Tickets": 75,
                "Min": 50,
                "Max": 70,
                "Fallback": []
            },
            "PowerPoints_s": {
                "Type": "PowerPoints",
                "Tickets": 85,
                "Min": 20,
                "Max": 30,
                "Fallback": []
            },
            "Credits_s": {
                "Type": "Credits",
                "Tickets": 5,
                "Min": 20,
                "Max": 28,
                "Fallback": []
            },
            "Blings_s": {
                "Type": "Bling",
                "Tickets": 5,
                "Min": 20,
                "Max": 28,
                "Fallback": []
            },
            "TokenDoubler_s": {
                "Type": "TokenDoubler",
                "Tickets": 45,
                "Min": 100,
                "Max": 150,
                "Fallback": ["Credits", 100]
            }
        }
    },
    "Super_Rare": {
        "Rarity_ID": 1,
        "DropChance": 28,
        "TotalTickets": 151,
        "Possibilities": {
            "Coins_m": {
                "Type": "Coins",
                "Tickets": 45,
                "Min": 100,
                "Max": 140,
                "Fallback": []
            },
            "PowerPoints_m": {
                "Type": "PowerPoints",
                "Tickets": 60,
                "Min": 50,
                "Max": 70,
                "Fallback": []
            },
            "Credits_m": {
                "Type": "Credits",
                "Tickets": 4,
                "Min": 50,
                "Max": 60,
                "Fallback": []
            },
            "Blings_m": {
                "Type": "Bling",
                "Tickets": 5,
                "Min": 50,
                "Max": 60,
                "Fallback": []
            },
            "TokenDoubler_m": {
                "Type": "TokenDoubler",
                "Tickets": 37,
                "Min": 500,
                "Max": 575,
                "Fallback": ["Credits", 100]
            }
        }
    },
    "Epic": {
        "Rarity_ID": 2,
        "DropChance": 15,
        "TotalTickets": 227,
        "Possibilities": {
            "Coins_l": {
                "Type": "Coins",
                "Tickets": 90,
                "Min": 200,
                "Max": 240,
                "Fallback": []
            },
            "PowerPoints_l": {
                "Type": "PowerPoints",
                "Tickets": 60,
                "Min": 100,
                "Max": 130,
                "Fallback": []
            },
            "Brawler_Rare": {
                "Type": "Brawler",
                "Rarity": "rare",
                "Tickets": 7,
                "Fallback": ["Credits", 100]
            },
            "Brawler_SuperRare": {
                "Type": "Brawler",
                "Rarity": "super_rare",
                "Tickets": 3,
                "Fallback": ["Credits", 250]
            },
            "Pin_1-9Gems": {
                "Type": "Pin",
                "Tickets": 10,
                "MinPrice": 1,
                "MaxPrice": 9,
                "Fallback": ["Credits", 100]
            },
            "Spray_1-19Gems": {
                "Type": "Spray",
                "Tickets": 5,
                "MinPrice": 1,
                "MaxPrice": 19,
                "Fallback": ["Credits", 100]
            },
            "ProfilePic": {
                "Type": "ProfilePic",
                "Tickets": 7,
                "Fallback": ["Credits", 200]
            },
            "TokenDoubler_l": {
                "Type": "TokenDoubler",
                "Tickets": 45,
                "Min": 1000,
                "Max": 1200,
                "Fallback": ["Credits", 100]
            }
        }
    },
    "Mythic": {
        "Rarity_ID": 3,
        "DropChance": 5,
        "TotalTickets": 135,
        "Possibilities": {
            "Coins_xl": {
                "Type": "Coins",
                "Tickets": 25,
                "Min": 500,
                "Max": 540,
                "Fallback": []
            },
            "PowerPoints_xl": {
                "Type": "PowerPoints",
                "Tickets": 35,
                "Min": 240,
                "Max": 280,
                "Fallback": []
            },
            "Brawler_Epic": {
                "Type": "Brawler",
                "Rarity": "epic",
                "Tickets": 7,
                "Fallback": ["Credits", 500]
            },
            "Brawler_Mythic": {
                "Type": "Brawler",
                "Rarity": "mega_epic",
                "Tickets": 2,
                "Fallback": ["Credits", 1000]
            },
            "Skin_1-29Gems": {
                "Type": "Skin",
                "Tickets": 10,
                "MinPrice": 1,
                "MaxPrice": 29,
                "Fallback": ["Credits", 200]
            },
            "Skin_30-79Gems": {
                "Type": "Skin",
                "Tickets": 2,
                "MinPrice": 30,
                "MaxPrice": 79,
                "Fallback": ["Credits", 250]
            },
            "Pin_1-9Gems": {
                "Type": "Pin",
                "Tickets": 25,
                "MinPrice": 1,
                "MaxPrice": 9,
                "Fallback": ["Credits", 100]
            },
            "Pin_10-29Gems": {
                "Type": "Pin",
                "Tickets": 10,
                "MinPrice": 10,
                "MaxPrice": 29,
                "Fallback": ["Credits", 150]
            },
            "Spray_1-19Gems": {
                "Type": "Spray",
                "Tickets": 5,
                "MinPrice": 1,
                "MaxPrice": 19,
                "Fallback": ["Credits", 100]
            },
            "ProfilePic": {
                "Type": "ProfilePic",
                "Tickets": 14,
                "Fallback": ["Credits", 200]
            }
        }

    },
    "Legendary": {
        "Rarity_ID": 4,
        "DropChance": 2,
        "TotalTickets": 116,
        "Possibilities": {
            "Gadget": {
                "Type": "Gadget",
                "Tickets": 35,
                "Fallback": ["Coins", 1000]
            },
            "StarPower": {
                "Type": "StarPower",
                "Tickets": 30,
                "Fallback": ["Coins", 1000]
            },
            "Brawler_Epic": {
                "Type": "Brawler",
                "Rarity": "epic",
                "Tickets": 9,
                "Fallback": ["Credits", 500]
            },
            "Brawler_Mythic": {
                "Type": "Brawler",
                "Rarity": "mega_epic",
                "Tickets": 3,
                "Fallback": ["Credits", 1000]
            },
            "Brawler_Legendary": {
                "Type": "Brawler",
                "Rarity": "legendary",
                "Tickets": 2,
                "Fallback": ["Credits", 2000]
            },
            "Skin_1-29Gems": {
                "Type": "Skin",
                "Tickets": 10,
                "MinPrice": 1,
                "MaxPrice": 29,
                "Fallback": ["Credits", 200]
            },
            "Skin_30-79Gems": {
                "Type": "Skin",
                "Tickets": 6,
                "MinPrice": 30,
                "MaxPrice": 79,
                "Fallback": ["Credits", 250]
            },
            "Skin_80-149Gems": {
                "Type": "Skin",
                "Tickets": 4,
                "MinPrice": 80,
                "MaxPrice": 149,
                "Fallback": ["Credits", 300]
            },
            "Pin_30-39Gems": {
                "Type": "Pin",
                "Tickets": 12,
                "MinPrice": 30,
                "MaxPrice": 999,
                "Fallback": ["Credits", 200]
            },
            "Spray_20-29Gems": {
                "Type": "Spray",
                "Tickets": 5,
                "MinPrice": 20,
                "MaxPrice": 999,
                "Fallback": ["Credits", 150]
            }
        }

    },
}
class LogicStarrDropData():
    def __init__(self):
        self.starrDrop_data = starrDrop_data
        self.items_ids = items_ids
        self.starr_drop_encoding_data = []
        self.range_price_items = ["Skin", "Pin", "Spray"]
        self.skin = Skins()
        self.pin = Emotes()
        self.spray = Sprays()
        self.brawler = Characters()
        self.card = Cards()
        self.profile_pic = PlayerThumbnails()
        self.rare_count = 0
        self.super_rare_count = 0
        self.epic_count = 0
        self.mythic_count = 0
        self.legendary_count = 0

    def choose_random_starrDrop(self):
        random_number = random.randint(1, 100)
        cumulative = 0
        chosen_drop = None

        for box_type in self.starrDrop_data.items():
            cumulative += self.starrDrop_data[f"{box_type[0]}"]["DropChance"]
            if random_number <= cumulative:
                chosen_drop = box_type
                break
        return chosen_drop[0]
    
    def choose_random_reward(self, chosen_drop):
        random_number = random.randint(1, self.starrDrop_data[f"{chosen_drop}"]["TotalTickets"])
        cumulative = 0
        chosen_reward = None
        for item, data in self.starrDrop_data[f"{chosen_drop}"]["Possibilities"].items():
            cumulative += data["Tickets"]
            if random_number <= cumulative:
                chosen_reward = item
                break
        return chosen_reward

    def create_starrDrop_opening(self, drop_count, starrDrop_rarity = None, rarity_set = None):
        for i in range(drop_count):
            starrDrop = []
            if rarity_set is None:
                starrDrop_rarity = self.choose_random_starrDrop()
                starrDrop_reward = self.choose_random_reward(starrDrop_rarity)
            else:
                starrDrop_reward = self.choose_random_reward(starrDrop_rarity)
            try:
                starrDrop_reward_amount = random.randint(self.starrDrop_data[f"{starrDrop_rarity}"]["Possibilities"][f"{starrDrop_reward}"]["Min"],self.starrDrop_data[f"{starrDrop_rarity}"]["Possibilities"][f"{starrDrop_reward}"]["Max"])
            except KeyError:
                starrDrop_reward_amount = 1
            starrDrop_type = self.starrDrop_data[f"{starrDrop_rarity}"]["Possibilities"][f"{starrDrop_reward}"]["Type"]
            self.updateCount(self.starrDrop_data[f"{starrDrop_rarity}"]["Rarity_ID"])
            starrDrop.append(self.starrDrop_data[f"{starrDrop_rarity}"]["Rarity_ID"])
            starrDrop.append(starrDrop_type)
            starrDrop.append(starrDrop_reward_amount)
            if starrDrop_type in self.range_price_items:
                starrDrop.append(self.getRewarditemID(starrDrop_type, min=self.starrDrop_data[f"{starrDrop_rarity}"]["Possibilities"][f"{starrDrop_reward}"]["MinPrice"], max=self.starrDrop_data[f"{starrDrop_rarity}"]["Possibilities"][f"{starrDrop_reward}"]["MaxPrice"]))
            elif starrDrop_type == "Brawler":
                starrDrop.append(self.getRewarditemID(starrDrop_type, additional=self.starrDrop_data[f"{starrDrop_rarity}"]["Possibilities"][f"{starrDrop_reward}"]["Rarity"]))
            elif starrDrop_type == "StarPower":
                starrDrop.append(self.getRewarditemID(starrDrop_type, additional=4))
            elif starrDrop_type == "Gadget":
                starrDrop.append(self.getRewarditemID(starrDrop_type, additional=5))
            elif starrDrop_type == "ProfilePic":
                starrDrop.append(self.getRewarditemID(starrDrop_type))

            self.starr_drop_encoding_data.append(starrDrop)
        self.setStarrDropEncodingData(self.starr_drop_encoding_data)

    def getDeliveryIdFromOfferType(self, offer_type):
        return self.items_ids[f"{offer_type}"]["DeliveryID"]
    
    def getStarrDropEncoding(self):
        return self.starr_drop_encoding_data
    
    def setStarrDropEncodingData(self, starr_drop_encoding):
        self.starr_drop_encoding_data = starr_drop_encoding

    def refreshData(self):
        self.starr_drop_encoding_data.pop(0)
        self.setStarrDropEncodingData(self.starr_drop_encoding_data)
    
    def getRewarditemID(self, item, min=None, max=None, additional=None):
        if item == "Skin":
            skin_possibilities = self.skin.getSkinsIDSSpecificPrice(min, max)
            skin_awarded = random.randint(0, len(skin_possibilities) -1)
            return skin_possibilities[skin_awarded]
        elif item == "Pin":
            pin_possibilities = self.pin.getPinsIDSSpecificPrice(min, max)
            pin_awarded = random.randint(0, len(pin_possibilities) -1)
            return pin_possibilities[pin_awarded]
        elif item == "Spray":
            spray_possibilities = self.spray.getSpraysIDSSpecificPrice(min, max)
            spray_awarded = random.randint(0, len(spray_possibilities) -1)
            return spray_possibilities[spray_awarded]
        elif item == "Brawler":
            brawler_possibilities = self.brawler.getBrawlerFromSepcificRarity(additional)
            brawler_awarded = random.randint(0, len(brawler_possibilities) -1)
            return brawler_possibilities[brawler_awarded]
        elif item == "StarPower" or item == "Gadget":
            card_possibilities = self.card.getCardsListFromMetaType(additional)
            card_awarded = random.randint(0, len(card_possibilities) -1)
            return card_possibilities[card_awarded]
        elif item == "ProfilePic":
            return random.randint(0, self.profile_pic.getThumbnailsCount())
        
    def updateCount(self, rarity_id):
        if rarity_id == 0:
            self.rare_count +=1
        elif rarity_id == 1:
            self.super_rare_count += 1
        elif rarity_id == 2: 
            self.epic_count += 1
        elif rarity_id == 3:
            self.mythic_count += 1
        elif rarity_id == 4:
            self.legendary_count += 1

    def encode(self, ByteStream):
        ByteStream.writeVInt(5)
        for i in range(5):
            ByteStream.writeDataReference(80, i)
            ByteStream.writeVInt(-1)
            ByteStream.writeVInt(0)
        ByteStream.writeVInt(len(self.starr_drop_encoding_data))
        for x in range(len(self.starr_drop_encoding_data)):
            ByteStream.writeDataReference(80,self.starr_drop_encoding_data[len(self.starr_drop_encoding_data )-x -1][0])
        ByteStream.writeVInt(len(self.starr_drop_encoding_data))
        for x in range(len(self.starr_drop_encoding_data)):
            ByteStream.writeByte(1)
            reward_type = self.starr_drop_encoding_data[x][1]
            offer_id_type = self.items_ids[reward_type]["OfferID"]
            ByteStream.writeVInt(offer_id_type)
            ByteStream.writeVInt(self.starr_drop_encoding_data[x][2])
            ByteStream.writeDataReference(0, 0)
            ByteStream.writeVInt(0)
        ByteStream.writeInt(-1788180018)
        ByteStream.writeVInt(0) # progression step in battles
        ByteStream.writeVInt(0)
        ByteStream.writeVInt(73529) # timer until refresh
        ByteStream.writeVInt(0) #v51 new count
        ByteStream.writeVInt(0) #v51 new count

starrDropOpening = LogicStarrDropData()


Classes/Logic/LogicStarrDropData.py
risporce/BSDS
class LogicStringUtil:
    @staticmethod
    def getBytes(string):
        return string.encode()

    @staticmethod
    def getByteLength(string):
        return len(string)

Classes/Logic/LogicStringUtil.py
risporce/BSDS
import traceback
from Classes.Logic.LogicLaserMessageFactory import LogicLaserMessageFactory
from Classes.Messaging import Messaging


class MessageManager:
    def receiveMessage(self, messageType, messagePayload, cryptoInit):
        message = LogicLaserMessageFactory.createMessageByType(messageType, messagePayload)
        if message is not None:
            try:
                if message.isServerToClient():
                    message.encode()
                else:
                    message.fields = message.decode()
                    message.execute(self, message.fields, cryptoInit)

            except Exception:
                print(traceback.format_exc())
        if messageType > 10100:
            Messaging.sendMessage(23457, {"Socket": self.client}, cryptoInit, self.player)
Classes/MessageManager.py
risporce/BSDS
import traceback


class Messaging:
    def writeHeader(message, payloadLen):
        message.messageBuffer += message.getMessageType().to_bytes(2, 'big', signed=True)
        message.messageBuffer += payloadLen.to_bytes(3, 'big', signed=True)
        message.messageBuffer += message.messageVersion.to_bytes(2, 'big', signed=True)

    def readHeader(headerBytes):
        headerData = []
        headerData.append(int.from_bytes(headerBytes[:2], 'big', signed=True))
        headerData.append(int.from_bytes(headerBytes[2:5], 'big', signed=True))
        return headerData

    def sendMessage(messageType, fields, cryptoInit,  player=None):
        from Classes.Logic.LogicLaserMessageFactory import LogicLaserMessageFactory
        message = LogicLaserMessageFactory.createMessageByType(messageType, b'')
        if player is not None:
            message.encode(fields, player)
        else:
            message.encode(fields)
        message.messagePayload = cryptoInit.encryptServer(message.getMessageType(), message.messagePayload)
        Messaging.writeHeader(message, len(message.messagePayload))
        message.messageBuffer += message.messagePayload
        try:
            fields["Socket"].send(message.messageBuffer)
        except Exception:
            print(traceback.format_exc())
Classes/Messaging.py
risporce/BSDS
from Classes.Messaging import Messaging

from Classes.Packets.PiranhaMessage import PiranhaMessage


class ClientHelloMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        fields = {}
        fields["Protocol"] = self.readInt()
        fields["KeyVersion"] = self.readInt()
        fields["MajorVersion"] = self.readInt()
        fields["MinorVersion"] = self.readInt()
        fields["Build"] = self.readInt()
        fields["ContentHash"] = self.readString()
        fields["DeviceType"] = self.readInt()
        fields["AppStore"] = self.readInt()
        super().decode(fields)
        return fields

    def execute(message, calling_instance, fields, cryptoInit):
        fields["Socket"] = calling_instance.client
        Messaging.sendMessage(20100, fields, cryptoInit)

    def getMessageType(self):
        return 10100

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Client/Authentification/ClientHelloMessage.py
risporce/BSDS
from Classes.Messaging import Messaging

from Classes.Packets.PiranhaMessage import PiranhaMessage


class LoginMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        fields = {}
        fields["AccountID"] = self.readLong()
        fields["PassToken"] = self.readString()
        fields["ClientMajor"] = self.readInt()
        fields["ClientMinor"] = self.readInt()
        fields["ClientBuild"] = self.readInt()
        fields["ResourceSha"] = self.readString()
        fields["Device"] = self.readString()
        fields["PreferredLanguage"] = self.readDataReference()
        fields["PreferredDeviceLanguage"] = self.readString()
        fields["OSVersion"] = self.readString()
        fields["isAndroid"] = self.readBoolean()
        fields["IMEI"] = self.readString()
        fields["AndroidID"] = self.readString()
        fields["isAdvertisingEnabled"] = self.readBoolean()
        fields["AppleIFV"] = self.readString()
        fields["RndKey"] = self.readInt()
        fields["AppStore"] = self.readVInt()
        fields["ClientVersion"] = self.readString()
        fields["TencentOpenId"] = self.readString()
        fields["TencentToken"] = self.readString()
        fields["TencentPlatform"] = self.readVInt()
        fields["DeviceVerifierResponse"] = self.readString()
        fields["AppLicensingSignature"] = self.readString()
        fields["DeviceVerifierResponse"] = self.readString()
        fields["SupercellIdToken"] = self.readCompressedString()
        fields["UpdateMaintenanceMode"] = self.readBoolean()
        fields["YoozooOsdkTicket"] = self.readString()
        fields["YoozooDeviceId"] = self.readString()
        fields["unk1"] = self.readString()
        fields["unk2"] = self.readString()
        fields["unk3"] = self.readString()
        fields["unk4"] = self.readString()
        fields["Country"] = self.readString()
        fields["unk6"] = self.readString()
        super().decode(fields)
        return fields

    def execute(message, calling_instance, fields, cryptoInit):
        pass
        calling_instance.player.ClientVersion = f'{str(fields["ClientMajor"])}.{str(fields["ClientBuild"])}.{str(fields["ClientMinor"])}'
        fields["Socket"] = calling_instance.client
        # ClientsManager.AddPlayer(calling_instance.player.ID, calling_instance.client)
        Messaging.sendMessage(20104, fields, cryptoInit, calling_instance.player)
        Messaging.sendMessage(24101, fields, cryptoInit, calling_instance.player)
        Messaging.sendMessage(24399, fields, cryptoInit, calling_instance.player)

    def getMessageType(self):
        return 10101

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Client/Authentification/LoginMessage.py
risporce/BSDS
from Classes.Messaging import Messaging

from Classes.Packets.PiranhaMessage import PiranhaMessage


class AskForBattleEndMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        fields = {}
        fields["Unk1"] = self.readVInt()
        fields["Result"] = self.readVInt()
        fields["Rank"] = self.readVInt()
        fields["MapID"] = self.readDataReference()
        fields["HeroesCount"] = self.readVInt()
        fields["Heroes"] = []
        for i in range(fields["HeroesCount"]): fields["Heroes"].append({"Brawler": {"ID": self.readDataReference(), "SkinID": self.readDataReference()}, "Team": self.readVInt(), "IsPlayer": self.readBoolean(), "PlayerName": self.readString()})
        super().decode(fields)
        return fields

    def execute(message, calling_instance, fields, cryptoInit):
        fields["Socket"] = calling_instance.client
        Messaging.sendMessage(23456, fields, cryptoInit, calling_instance.player)

    def getMessageType(self):
        return 14110

    def getMessageVersion(self):
        return self.messageVersion

Classes/Packets/Client/Battle/AskForBattleEndMessage.py
risporce/BSDS
from Classes.Messaging import Messaging

from Classes.Packets.PiranhaMessage import PiranhaMessage


class SinglePlayerMatchRequestMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        fields = {}
        return fields

    def execute(message, calling_instance, fields, cryptoInit):
        fields["Socket"] = calling_instance.client
        Messaging.sendMessage(23456, fields, cryptoInit, calling_instance.player)

    def getMessageType(self):
        return 14118

    def getMessageVersion(self):
        return self.messageVersion

Classes/Packets/Client/Battle/SinglePlayerMatchRequestMessage.py
risporce/BSDS
from Classes.Messaging import Messaging

from Classes.Packets.PiranhaMessage import PiranhaMessage


class AskForAllianceDataMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        fields = {}
        fields["id"] = self.readVLong()
        fields["isInAlliance"] = self.readBoolean()
        if fields["isInAlliance"] == True:
            fields["anotherIDHigh"] = self.readVInt()
            fields["anotherIDLow"] = self.readVInt()
        super().decode(fields)

        return fields

    def execute(message, calling_instance, fields, cryptoInit):
        fields["Socket"] = calling_instance.client
        Messaging.sendMessage(24301, fields, cryptoInit, calling_instance.player)

    def getMessageType(self):
        return 14302

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Client/Home/AskForAllianceDataMessage.py
risporce/BSDS
from Classes.Messaging import Messaging

from Classes.Packets.PiranhaMessage import PiranhaMessage


class ChangeAvatarNameMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        self.writeString(fields["Name"])
        self.writeBoolean(fields["NameSetByUser"])

    def decode(self):
        fields = {}
        fields["Name"] = self.readString()
        fields["NameSetByUser"] = self.readBoolean()
        super().decode(fields)
        return fields

    def execute(message, calling_instance, fields, cryptoInit):
        fields["Socket"] = calling_instance.client
        fields["Command"] = {"ID": 201}
        Messaging.sendMessage(24111, fields, cryptoInit)

    def getMessageType(self):
        return 10212

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Client/Home/ChangeAvatarNameMessage.py
risporce/BSDS
from Classes.Logic.LogicCommandManager import LogicCommandManager
from Classes.Logic.LogicStarrDropData import starrDropOpening

from Classes.Packets.PiranhaMessage import PiranhaMessage
from Classes.Messaging import Messaging


class EndClientTurnMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        fields = {}
        self.readBoolean()
        fields["Tick"] = self.readVInt()
        fields["Checksum"] = self.readVInt()
        fields["CommandsCount"] = self.readVInt()
        super().decode(fields)
        fields["Commands"] = []
        for i in range(fields["CommandsCount"]):
            fields["Commands"].append({"ID": self.readVInt()})
            if LogicCommandManager.commandExist(fields["Commands"][i]["ID"]):
                command = LogicCommandManager.createCommand(fields["Commands"][i]["ID"])
                print("Command", LogicCommandManager.getCommandsName(fields["Commands"][i]["ID"]))
                if command is not None:
                    fields["Commands"][i]["Fields"] = command.decode(self)
                    fields["Commands"][i]["Instance"] = command
        return fields

    def execute(message, calling_instance, fields, cryptoInit):
        fields["Socket"] = calling_instance.client
        for command in fields["Commands"]:
            if "Instance" not in command.keys():
                return

            if hasattr(command["Instance"], 'execute'):
                command["Instance"].execute(calling_instance, command["Fields"])
            if command["ID"] == 571:
                fields["ServerCommandID"] = 203
                Messaging.sendMessage(24111, fields, cryptoInit, calling_instance.player)
                fields["ServerCommandID"] = 228
                Messaging.sendMessage(24111, fields, cryptoInit, calling_instance.player)
            elif command["ID"] == 519:
                Messaging.sendMessage(24104, {"Socket": calling_instance.client, "ServerChecksum": 0, "ClientChecksum": 0, "Tick": 0}, cryptoInit)

    def getMessageType(self):
        return 14102

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Client/Home/EndClientTurnMessage.py
risporce/BSDS
from Classes.Messaging import Messaging

from Classes.Packets.PiranhaMessage import PiranhaMessage


class GetPlayerProfileMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        fields = {}
        fields["BattleInfoBoolean"] = self.readBoolean()
        if fields["BattleInfoBoolean"]:
            fields["unk1"] = self.readVInt()
            fields["AnotherID"] = self.readLong()
            fields["unk2"] = self.readVInt()
            for i in self.readVInt():
                fields["CsvID"] = self.readDataReference()
                fields["unk3"] = self.readVInt()
                fields["unk4"] = self.readVInt()
                fields["unk5"] = self.readVInt()
            fields["unk6"] = self.readVInt()
            fields["PlayerName"] = self.readString()
            fields["unk7"] = self.readVInt()
            fields["Thumbnail"] = self.readVInt()
            fields["NameColor"] = self.readVInt()
            fields["unk10"] = self.readVInt()
        fields["unk11"] = self.readVInt()
        fields["PlayerHighID"] = self.readInt()
        fields["PlayerLowID"] = self.readInt()
        super().decode(fields)


        return fields

    def execute(message, calling_instance, fields, cryptoInit):
        fields["Socket"] = calling_instance.client
        Messaging.sendMessage(24113, fields, cryptoInit, calling_instance.player)

    def getMessageType(self):
        return 15081

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Client/Home/GetPlayerProfileMessage.py
risporce/BSDS
from Classes.Messaging import Messaging

from Classes.Packets.PiranhaMessage import PiranhaMessage


class GoHomeFromOfflinePractiseMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        fields = {}
        self.readBoolean()
        return fields

    def execute(message, calling_instance, fields, cryptoInit):
        fields["Socket"] = calling_instance.client
        Messaging.sendMessage(24101, fields, cryptoInit, calling_instance.player)

    def getMessageType(self):
        return 14109

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Client/Home/GoHomeFromOfflinePractiseMessage.py
risporce/BSDS
from Classes.Messaging import Messaging

from Classes.Packets.PiranhaMessage import PiranhaMessage


class GoHomeMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        fields = {}
        self.readBoolean()
        return fields

    def execute(message, calling_instance, fields, cryptoInit):
        fields["Socket"] = calling_instance.client
        Messaging.sendMessage(24101, fields, cryptoInit, calling_instance.player)

    def getMessageType(self):
        return 17750

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Client/Home/GoHomeMessage.py
risporce/BSDS
from Classes.Messaging import Messaging

from Classes.Packets.PiranhaMessage import PiranhaMessage


class KeepAliveMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        return {}

    def execute(message, calling_instance, fields, cryptoInit):
        fields["Socket"] = calling_instance.client
        Messaging.sendMessage(20108, fields, cryptoInit)

    def getMessageType(self):
        return 10108

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Client/Socket/KeepAliveMessage.py
risporce/BSDS
import Configuration
from Classes.ByteStream import ByteStream
from Classes.Utility import Utility


class PiranhaMessage(ByteStream):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageBuffer = messageData
        self.fields = {}

    def decode(self, fields):
        if Configuration.settings['PrintEnabled']:
            Utility.parseFields(fields)

    def getLength(self):
        return len(self.messageBuffer)

    def isServerToClient(self):
        messageType = self.getMessageType()
        if 20000 <= messageType < 30000 or messageType == 40000:
            return True
        elif 10000 <= messageType < 20000 or messageType == 30000:
            return False

Classes/Packets/PiranhaMessage.py
risporce/BSDS
from Classes.Packets.PiranhaMessage import PiranhaMessage


class LoginFailedMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        self.writeInt(fields['ErrorID'])
        self.writeString(fields['FingerprintData'])
        self.writeString()
        self.writeString(fields['ContentURL'])
        self.writeString()
        self.writeString(fields['Message'])
        self.writeInt(0)
        self.writeBoolean(False)
        self.writeInt(0)
        self.writeInt(0)
        self.writeInt(0)
        self.writeInt(0)
        self.writeString()
        self.writeInt(0)
        self.writeBoolean(True)
        self.writeBoolean(True)
        self.writeString()
        self.writeVInt(0)
        self.writeString()
        self.writeBoolean(False)

    def decode(self):
        fields = {}
        fields["ErrorCode"] = self.readInt()
        fields["ResourceFingerprintData"] = self.readString()
        fields["RedirectDomain"] = self.readString()
        fields["ContentURL"] = self.readString()
        fields["UpdateURL"] = self.readString()
        fields["Reason"] = self.readString()
        fields["SecondsUntilMaintenanceEnd"] = self.readInt()
        fields["ShowContactSupportForBan"] = self.readBoolean()
        fields["CompressedFingerprintData"] = self.readBytesWithoutLength()
        fields["ContentURLListCount"] = self.readInt()
        fields["ContentURLList"] = []
        for i in range(fields["ContentURLListCount"]):
            fields["ContentURLList"].append(self.readString())
        fields["KunlunAppStore"] = self.readInt()
        fields["MaintenanceType"] = self.readInt()
        fields["HelpshiftFaqId"] = self.readString()
        fields["Tier"] = self.readInt()
        fields["Unk1"] = self.readBoolean()
        fields["Unk2"] = self.readBoolean()
        fields["Unk3"] = self.readString()
        fields["Unk4"] = self.readVInt()
        fields["Unk5"] = self.readString()
        fields["OptionalTargetedAccountIdState"] = self.readBoolean()
        if fields["OptionalTargetedAccountIdState"] == True:
            fields["OptionalTargetedAccountId"] = self.readLong()
        super().decode(fields)
        return fields

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 20103

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Authentification/LoginFailedMessage.py
risporce/BSDS
from Classes.Packets.PiranhaMessage import PiranhaMessage

class LoginOkMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 1

    def encode(self, fields, player):
        self.writeLong(player.ID[0], player.ID[1])
        self.writeLong(player.ID[0], player.ID[1])
        self.writeString(player.Token)
        self.writeString()
        self.writeString()
        self.writeInt(47)
        self.writeInt(227)
        self.writeInt(1)
        self.writeString("dev")
        self.writeInt(0)
        self.writeInt(0)
        self.writeInt(0)
        self.writeString()
        self.writeString()
        self.writeString()
        self.writeInt(0)
        self.writeString()
        self.writeString("CA")
        self.writeString()
        self.writeInt(0)
        self.writeString()
        self.writeInt(2)
        self.writeString('https://game-assets.brawlstarsgame.com')
        self.writeString('http://a678dbc1c015a893c9fd-4e8cc3b1ad3a3c940c504815caefa967.r87.cf2.rackcdn.com')
        self.writeInt(2)
        self.writeString('https://event-assets.brawlstars.com')
        self.writeString('https://24b999e6da07674e22b0-8209975788a0f2469e68e84405ae4fcf.ssl.cf2.rackcdn.com/event-assets')
        self.writeVInt(0)
        self.writeCompressedString(b'')
        self.writeBoolean(True)
        self.writeBoolean(False)
        self.writeString()
        self.writeString()
        self.writeString()
        self.writeString('https://play.google.com/store/apps/details?id=com.supercell.brawlstars')
        self.writeString()
        self.writeBoolean(False)

        self.writeBoolean(False)
        if False:
            self.writeString()

        self.writeBoolean(False)
        if False:
            self.writeString()

        self.writeBoolean(False)
        if False:
            self.writeString()

        self.writeBoolean(False)
        if False:
            self.writeString()


    def decode(self):
        fields = {}
        fields["AccountID"] = self.readLong()
        fields["HomeID"] = self.readLong()
        fields["PassToken"] = self.readString()
        fields["FacebookID"] = self.readString()
        fields["GamecenterID"] = self.readString()
        fields["ServerMajorVersion"] = self.readInt()
        fields["ContentVersion"] = self.readInt()
        fields["ServerBuild"] = self.readInt()
        fields["ServerEnvironment"] = self.readString()
        fields["SessionCount"] = self.readInt()
        fields["PlayTimeSeconds"] = self.readInt()
        fields["DaysSinceStartedPlaying"] = self.readInt()
        fields["FacebookAppID"] = self.readString()
        fields["ServerTime"] = self.readString()
        fields["AccountCreatedDate"] = self.readString()
        fields["StartupCooldownSeconds"] = self.readInt()
        fields["GoogleServiceID"] = self.readString()
        fields["LoginCountry"] = self.readString()
        fields["KunlunID"] = self.readString()
        fields["Tier"] = self.readInt()
        fields["TencentID"] = self.readString()

        ContentUrlCount = self.readInt()
        fields["GameAssetsUrls"] = []
        for i in range(ContentUrlCount):
            fields["GameAssetsUrls"].append(self.readString())

        EventUrlCount = self.readInt()
        fields["EventAssetsUrls"] = []
        for i in range(EventUrlCount):
            fields["EventAssetsUrls"].append(self.readString())

        fields["SecondsUntilAccountDeletion"] = self.readVInt()
        fields["SupercellIDToken"] = self.readCompressedString()
        fields["IsSupercellIDLogoutAllDevicesAllowed"] = self.readBoolean()
        fields["isSupercellIDEligible"] = self.readBoolean()
        fields["LineID"] = self.readString()
        fields["SessionID"] = self.readString()
        fields["KakaoID"] = self.readString()
        fields["UpdateURL"] = self.readString()
        fields["YoozooPayNotifyUrl"] = self.readString()
        fields["UnbotifyEnabled"] = self.readBoolean()

        Unknown1 = self.readBoolean()
        fields["Unknown1"] = Unknown1
        if Unknown1:
            fields["Unknown2"] = self.readString()

        Unknown3 = self.readBoolean()
        fields["Unknown3"] = Unknown1
        if Unknown3:
            fields["Unknown4"] = self.readString()

        Unknown5 = self.readBoolean()
        fields["Unknown5"] = Unknown1
        if Unknown5:
            fields["Unknown6"] = self.readString()

        Unknown7 = self.readBoolean()
        fields["Unknown7"] = Unknown1
        if Unknown7:
            fields["Unknown8"] = self.readString()
        super().decode(fields)
        return fields

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 20104

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Authentification/LoginOkMessage.py
risporce/BSDS
from Classes.Packets.PiranhaMessage import PiranhaMessage


class OutOfSyncMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        self.writeVInt(fields["ServerChecksum"])
        self.writeVInt(fields["ClientChecksum"])
        self.writeVInt(fields["Tick"])

    def decode(self):
        fields = {}
        fields["ServerChecksum"] = self.readVInt()
        fields["ClientChecksum"] = self.readVInt()
        fields["Tick"] = self.readVInt()
        super().decode(fields)
        return fields

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 24104

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Authentification/OutOfSyncMessage.py
risporce/BSDS
from Classes.Packets.PiranhaMessage import PiranhaMessage
from os import urandom


class ServerHelloMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        self.writeBytes(urandom(24), 24)

    def decode(self):
        fields = {}
        fields["Random"] = self.readBytesWithoutLength()
        super().decode(fields)
        return fields

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 20100

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Authentification/ServerHelloMessage.py
risporce/BSDS
from Classes.Packets.PiranhaMessage import PiranhaMessage

class BattleEndMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields, player):
        self.writeLong(0, 0) # Battle UUID High
        self.writeLong(0, 0) # Battle UUID Low
        self.writeVInt(2) # Battle End Game Mode (gametype)
        self.writeVInt(fields["Rank"]) # Result (Victory/Defeat/Draw/Rank Score)
        self.writeVInt(0) # Tokens Gained (Gained Keys)
        self.writeVInt(0) # Trophies Result (Metascore change)
        self.writeVInt(0) # Power Play Points Gained (Pro League Points)
        self.writeVInt(0) # Doubled Tokens (Double Keys)
        self.writeVInt(0) # Double Token Event (Double Event Keys)
        self.writeVInt(0) # Token Doubler Remaining (Double Keys Remaining)
        self.writeVInt(0) # game Lenght In Seconds
        self.writeVInt(0) # Epic Win Power Play Points Gained (op Win Points)
        self.writeVInt(0) # Championship Level Reached (CC Wins)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeBoolean(True)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(-1)
        self.writeBoolean(False)

        self.writeVInt(fields["HeroesCount"])
        for heroEntry in fields["Heroes"]:
            self.writeBoolean(heroEntry["IsPlayer"])
            self.writeBoolean(bool(heroEntry["Team"]))
            self.writeBoolean(bool(heroEntry["Team"]))
            self.writeByte(1)
            for i in range(1):
                self.writeDataReference(heroEntry["Brawler"]["ID"][0], heroEntry["Brawler"]["ID"][1])
            self.writeByte(1)
            for i in range(1):
                if (heroEntry["Brawler"]["SkinID"] is None):
                    self.writeVInt(0)
                else:
                    self.writeDataReference(heroEntry["Brawler"]["SkinID"][0], heroEntry["Brawler"]["SkinID"][1])
            self.writeByte(1)
            for i in range(1):
                self.writeVInt(1250)
            self.writeByte(1)
            for i in range(1):
                self.writeVInt(11)
            self.writeByte(1)
            for i in range(1):
                self.writeVInt(0)

            self.writeVInt(0)
            self.writeVInt(0)

            self.writeBoolean(heroEntry["IsPlayer"])
            if heroEntry["IsPlayer"]:
                self.writeLong(player.ID[0], player.ID[1])
            self.writeString(heroEntry["PlayerName"])
            self.writeVInt(100)
            self.writeVInt(28000000)
            self.writeVInt(43000000)
            self.writeVInt(-2)
            if heroEntry["IsPlayer"]:
                self.writeBoolean(True)
                self.writeVLong(5, 4181497)
                self.writeString('haccer club')
                self.writeDataReference(8, 16)
            else:
                self.writeBoolean(False)

            self.writeInt8(1)
            self.writeVInt(5978)
            self.writeInt8(1)
            self.writeVInt(0)

            self.writeInt16(5)
            self.writeInt16(3)
            self.writeInt(27328)
            self.writeInt(25659)

            self.writeDataReference(0)

        self.writeVInt(0)
        self.writeVInt(1)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False) # 0x0
        self.writeBoolean(False) # 0x0
        self.writeBoolean(False) # 0x0
        self.writeBoolean(False) # 0x0
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False) # 0x0
        self.writeVInt(0)
        self.writeBoolean(False) # 0x0
        self.writeVInt(0)
        self.writeBoolean(False) # 0x0
        self.writeBoolean(False) # 0x0
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False) # 0x0
        self.writeBoolean(False) # 0x0
        self.writeBoolean(False) # 0x0

    def decode(self):
        fields = {}
        return {}

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 23456

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Battle/BattleEndMessage.py
risporce/BSDS
from Classes.Packets.PiranhaMessage import PiranhaMessage


class AllianceDataMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields, player):
        self.writeBoolean(True)

        self.writeLong(0, 1) # alliance ID
        self.writeString('haccers') # alliance name
        self.writeDataReference(8, 37) # alliance icon
        self.writeVInt(1) # type
        self.writeVInt(1) # member count
        self.writeVInt(9500) # total trophies
        self.writeVInt(0) # minimum trophies to enter
        self.writeVInt(0) # 0
        self.writeString('CA') # location
        self.writeVInt(1) # people online
        self.writeBoolean(True) # isFamilyFriendly
        self.writeVInt(0)

        self.writeString("this is the hacciest club in the world")

        self.writeVInt(1) # member count
        self.writeLong(0, 1) # player ID
        self.writeVInt(2) # role
        self.writeVInt(9500) # trophies
        self.writeVInt(0) # status: 0=offline 2=online
        self.writeVInt(1) # last connected time seconds ?
        highestPowerLeagueRank = 2
        self.writeVInt(highestPowerLeagueRank)
        if highestPowerLeagueRank != 0:
            self.writeVInt(2) #solo
            self.writeVInt(1) #duo
        self.writeBoolean(False) # boolean always false?

        self.writeString('risporce') # player name
        self.writeVInt(100) # VInt always 100
        self.writeVInt(28000183) # thumbnail
        self.writeVInt(43000008) # name color
        self.writeVInt(-1)

        self.writeVInt(-1) # most people have it -1 but some with something
        self.writeBoolean(False) # whats this ? only 2/30 people have it true in my club
        week = 58 # week 58 of club league as of 2023/07/05, this number is 0 if you just arrived in the club
        self.writeVInt(week)
        if week != 0: # club league week number?
            self.writeVInt(3) # day
            self.writeVInt(18) # total club trophies earned
            self.writeVInt(0) # event day club trophies earned
            self.writeVInt(8) # total tickets used
            self.writeVInt(0) # event day tickets used
            self.writeVInt(6) # event day max tickets
            self.writeVInt(6) # event day tickets left
            self.writeVInt(0) # event day player ranking
            self.writeBoolean(True) # everyone have it to true
        self.writeVInt(200) # player experience lvl but why tf it doesn't show for some people

    def decode(self):
        fields = {}
        super().decode(fields)
        return {}

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 24301

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Home/AllianceDataMessage.py
risporce/BSDS
from Classes.Logic.LogicCommandManager import LogicCommandManager
from Classes.Packets.PiranhaMessage import PiranhaMessage


class AvailableServerCommandMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields, player):
        self.writeVInt(fields["ServerCommandID"])
        command = LogicCommandManager.createCommand(fields["ServerCommandID"], self.messagePayload)
        self.messagePayload = command.encode(fields)

    def decode(self):
        return {}

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 24111

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Home/AvailableServerCommandMessage.py
risporce/BSDS
from Logic.Data.DataManager import Writer

class ListBrawlTvChannelsMessage(Writer):

    def __init__(self, client, player):
        super().__init__(client)
        self.id = 24700
        self.client = client
        self.player = player

    def encode(self):
        self.writeVint(1) # count
        
        self.writeVint(1)
        self.writeString("hacc")
        self.writeString("hacc2")


Classes/Packets/Server/Home/ListBrawlTvChannelsMessage.py
risporce/BSDS
from Classes.ClientsManager import ClientsManager
from Classes.Packets.PiranhaMessage import PiranhaMessage
from Classes.Logic.LogicStarrDropData import starrDropOpening


class LobbyInfoMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields, player):
        self.writeVInt(ClientsManager.GetCount())
        self.writeString(f"""Project BSDS \n Version: {player.ClientVersion}
starrdrop rare count: {starrDropOpening.rare_count}
starrdrop super rare count: {starrDropOpening.super_rare_count}
starrdrop epic count: {starrDropOpening.epic_count}
starrdrop mythic count: {starrDropOpening.mythic_count}
starrdrop legendary count: {starrDropOpening.legendary_count}
""")
        self.writeVInt(0) # count event
        self.writeVInt(0) # new timer in v51

    def decode(self):
        fields = {}
        fields["PlayerCount"] = self.readVInt()
        fields["Text"] = self.readString()
        fields["Unk1"] = self.readVInt()
        super().decode(fields)
        return {}

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 23457

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Home/LobbyInfoMessage.py
risporce/BSDS
from Classes.Packets.PiranhaMessage import PiranhaMessage


class MyAllianceMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields, player):
        self.writeVInt(1) # Online people in alliance
        self.writeBoolean(True) # isInAlliance
        self.writeDataReference(25, 4)
        self.writeLong(0, 1) # alliance ID
        self.writeString('haccers') # alliance name
        self.writeDataReference(8, 37) # alliance icon
        self.writeVInt(3) # type
        self.writeVInt(1) # member count
        self.writeVInt(9500) # total trophies
        self.writeVInt(1) # minimum trophies to enter
        self.writeVInt(0) # 0
        self.writeString('CA') # location
        self.writeVInt(3) # unknown
        self.writeBoolean(True) # isFamilyFriendly
        self.writeVInt(0)

    def decode(self):
        fields = {}
        super().decode(fields)
        return {}

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 24399

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Home/MyAllianceMessage.py
risporce/BSDS
from Classes.ByteStreamHelper import ByteStreamHelper
from Classes.Packets.PiranhaMessage import PiranhaMessage
from Classes.Logic.LogicStarrDropData import starrDropOpening


class OwnHomeDataMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields, player):

        self.writeVInt(1688816070) #timestamp
        self.writeVInt(1191532375)#timestamp
        self.writeVInt(2023189)#timestamp LogicDailyDataBegin
        self.writeVInt(73530) #timestamp
        self.writeVInt(50000) # current trophies
        self.writeVInt(50000) # hightest trophies
        self.writeVInt(50000) #highest trophies today
        self.writeVInt(300) # collected trophy road rewards
        self.writeVInt(528867) # exp points
         # profile icon
        self.writeDataReference(28, 128)
        # name color
        self.writeDataReference(43, 1)

        self.writeVInt(26) # played Game Mode
        for x in range(26):
            self.writeVInt(x)

        self.writeVInt(0) # selected skin count

        self.writeVInt(0) # available ramdon skins

        self.writeVInt(0) # random skins
        
        self.writeVInt(725)
        for x in range(725):
            self.writeDataReference(29, x) # unlocked skin array

        self.writeVInt(0) # skin purchase option

        self.writeVInt(0) # unk skin array5

        self.writeVInt(0) # leaderboard region
        self.writeVInt(50000) # highest trophies
        self.writeVInt(0) # tokens used in battle
        self.writeVInt(2) # control mode
        self.writeBoolean(True) # battle hints
        self.writeVInt(0) # token doubler left
        self.writeVInt(115) # maybe starr drop timer ? #v50
        self.writeVInt(335442) # trophy league timer
        self.writeVInt(1001442) # power play timer
        self.writeVInt(5778642) # Brawl pass season timer
        #self.writeVInt(0) # maybe starr drop timer ? #v50

        self.writeVInt(120) # 
        self.writeVInt(200) # 
        self.writeVInt(0) # drop chance of characters in boxes
        # self.writeVInt(93)
        # self.writeVInt(206)
        # self.writeVInt(456)
        # self.writeVInt(1001)
        # self.writeVInt(2264)

        self.writeBoolean(True) # false, false, true
        self.writeVInt(2) # token doubler  new tag state
        self.writeVInt(2) # event tickets new tag state
        self.writeVInt(2) # coins pack new tag state
        self.writeVInt(0) # name change cost
        self.writeVInt(0) # timer for next name change

        self.writeVInt(8) # shop offers count

        self.writeVInt(1) # reward count
        self.writeVInt(49) # item type
        self.writeVInt(3) # quantity
        self.writeDataReference(0)# csv reference
        self.writeVInt(0) 
        self.writeVInt(0)
        self.writeVInt(1) # new price
        self.writeVInt(19909) # timer until gone
        self.writeVInt(1)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(8881)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(0) # old price
        self.writeStringReference("3 STARR DROP OFFER") # title
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeString("offer_popstar")
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeVInt(1)
        self.writeVInt(5) # offer value
        self.writeString("")
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(-1)
        self.writeVInt(0)
        #v51
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)

        self.writeVInt(1) # reward count
        self.writeVInt(49) # item type
        self.writeVInt(10) # quantity
        self.writeDataReference(0)# csv reference
        self.writeVInt(0) 
        self.writeVInt(0)
        self.writeVInt(2) # new price
        self.writeVInt(19909) # timer until gone
        self.writeVInt(1)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(8881)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(0) # old price
        self.writeStringReference("10 STARR DROP OFFER") # title
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeString("offer_popstar")
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeVInt(1)
        self.writeVInt(10) # offer value
        self.writeString("")
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(-1)
        self.writeVInt(0)
        #v51
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)

        self.writeVInt(1) # reward count
        self.writeVInt(49) # item type
        self.writeVInt(25) # quantity
        self.writeDataReference(0)# csv reference
        self.writeVInt(0) 
        self.writeVInt(0)
        self.writeVInt(3) # new price
        self.writeVInt(19909) # timer until gone
        self.writeVInt(1)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(8881)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(0) # old price
        self.writeStringReference("25 STARR DROP OFFER") # title
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeString("offer_popstar")
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeVInt(1)
        self.writeVInt(25) # offer value
        self.writeString("")
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(-1)
        self.writeVInt(0)
        #v51
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)

        self.writeVInt(1) # reward count
        self.writeVInt(49) # item type
        self.writeVInt(10) # quantity
        self.writeDataReference(0)# csv reference
        self.writeVInt(0) 
        self.writeVInt(0)
        self.writeVInt(10) # new price
        self.writeVInt(19909) # timer until gone
        self.writeVInt(1)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(8881)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(0) # old price
        self.writeStringReference("10 RARE STARR DROP OFFER") # title
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeString("offer_wf")
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeVInt(1)
        self.writeVInt(10) # offer value
        self.writeString("")
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(-1)
        self.writeVInt(0)
        #v51
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)

        self.writeVInt(1) # reward count
        self.writeVInt(49) # item type
        self.writeVInt(10) # quantity
        self.writeDataReference(0)# csv reference
        self.writeVInt(0) 
        self.writeVInt(0)
        self.writeVInt(10) # new price
        self.writeVInt(19909) # timer until gone
        self.writeVInt(1)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(8881)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(0) # old price
        self.writeStringReference("10 SUPER RARE STARR DROP OFFER") # title
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeString("offer_wf")
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeVInt(1)
        self.writeVInt(10) # offer value
        self.writeString("")
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(-1)
        self.writeVInt(0)
        #v51
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)

        self.writeVInt(1) # reward count
        self.writeVInt(49) # item type
        self.writeVInt(10) # quantity
        self.writeDataReference(0)# csv reference
        self.writeVInt(0) 
        self.writeVInt(0)
        self.writeVInt(10) # new price
        self.writeVInt(19909) # timer until gone
        self.writeVInt(1)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(8881)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(0) # old price
        self.writeStringReference("10 EPIC STARR DROP OFFER") # title
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeString("offer_wf")
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeVInt(1)
        self.writeVInt(10) # offer value
        self.writeString("")
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(-1)
        self.writeVInt(0)
        #v51
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)

        self.writeVInt(1) # reward count
        self.writeVInt(49) # item type
        self.writeVInt(10) # quantity
        self.writeDataReference(0)# csv reference
        self.writeVInt(0) 
        self.writeVInt(0)
        self.writeVInt(10) # new price
        self.writeVInt(19909) # timer until gone
        self.writeVInt(1)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(8881)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(0) # old price
        self.writeStringReference("10 MYTHIC STARR DROP OFFER") # title
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeString("offer_wf")
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeVInt(1)
        self.writeVInt(10) # offer value
        self.writeString("")
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(-1)
        self.writeVInt(0)
        #v51
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)

        self.writeVInt(1) # reward count
        self.writeVInt(49) # item type
        self.writeVInt(10) # quantity
        self.writeDataReference(0)# csv reference
        self.writeVInt(0) 
        self.writeVInt(0)
        self.writeVInt(10) # new price
        self.writeVInt(19909) # timer until gone
        self.writeVInt(1)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(8881)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeVInt(0) # old price
        self.writeStringReference("10 LEGENDARY STARR DROP OFFER") # title
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeString("offer_wf")
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeVInt(1)
        self.writeVInt(10) # offer value
        self.writeString("")
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(-1)
        self.writeVInt(1)
        # v51
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)

        self.writeVInt(20) # tokens for battle
        self.writeVInt(1428) # timer until new token

        self.writeVInt(0) #count

        self.writeVInt(1) #unk
        self.writeVInt(30) #unk

        self.writeByte(1) # count brawlers selected
        self.writeDataReference(16, 5) # selected brawler
        self.writeString("CA") # location
        self.writeString("BSDS") # supported creator

        self.writeVInt(6) # count
        self.writeVInt(1) # resources id
        self.writeVInt(9) # resources gained
        self.writeVInt(1) # resources id
        self.writeVInt(22) # resources gained
        self.writeVInt(3) # resources id
        self.writeVInt(25) # resources gained
        self.writeVInt(1) # resources id
        self.writeVInt(24) # resources gained
        self.writeVInt(0) # resources id
        self.writeVInt(15) # resources gained
        self.writeVInt(32447) # resources id
        self.writeVInt(28) # resources gained


        self.writeVInt(0) # count 0

        self.writeVInt(20) # count brawl pass seasons
        for season in range(20):
            self.writeVInt(season) # season
            self.writeVInt(56796) # season token collected
            self.writeBoolean(True) # 0x1
            self.writeVInt(56)
            self.writeBoolean(False)
            self.writeBoolean(True) # 0x1
            self.writeInt(-4)
            self.writeInt(16383)
            self.writeInt(0)
            self.writeInt(0)
            self.writeBoolean(True) # 0x1
            self.writeInt(-4)
            self.writeInt(2147483647)
            self.writeInt(0)
            self.writeInt(0)

        self.writeVInt(0)


        self.writeBoolean(True) # 0x1
        self.writeVInt(0)
        self.writeVInt(1)
        self.writeVInt(2)
        self.writeVInt(0) # club league quest count

        self.writeBoolean(True) # Vanity items
        self.writeVInt(1)
        self.writeVInt(52)
        self.writeVInt(216)
        self.writeVInt(0)


        self.writeBoolean(False) # Power league season data

        self.writeInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False) # Logic Daily Data end

        self.writeVInt(2023189) # Logic Conf Data begin

        self.writeVInt(34) # event slot id
        self.writeVInt(1)
        self.writeVInt(2)
        self.writeVInt(3)
        self.writeVInt(4)
        self.writeVInt(5)
        self.writeVInt(6)
        self.writeVInt(7)
        self.writeVInt(8)
        self.writeVInt(9)
        self.writeVInt(10)
        self.writeVInt(11)
        self.writeVInt(12) # map maker candidate
        self.writeVInt(13) # map maker winner
        self.writeVInt(14)
        self.writeVInt(15)
        self.writeVInt(16)
        self.writeVInt(17)
        self.writeVInt(18) # mystery
        self.writeVInt(19)
        self.writeVInt(20)# championship challenge
        self.writeVInt(21) 
        self.writeVInt(22)
        self.writeVInt(23)
        self.writeVInt(24)
        self.writeVInt(25)
        self.writeVInt(26)
        self.writeVInt(27)
        self.writeVInt(28)
        self.writeVInt(29)
        self.writeVInt(30)
        self.writeVInt(31)
        self.writeVInt(32)
        self.writeVInt(33)
        self.writeVInt(34) # hypercharge 

        self.writeVInt(3) # event count

        self.writeVInt(4)
        self.writeVInt(1)
        self.writeVInt(0)
        self.writeVInt(72292)
        self.writeVInt(10)
        self.writeDataReference(15, 577) # map id
        self.writeVInt(-1)
        self.writeVInt(2)
        self.writeString("")
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0) # count
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False) # MapMaker map structure array
        self.writeVInt(0)
        self.writeBoolean(False) # Power League array entry
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(-1)
        self.writeVInt(0) # new count v51
        self.writeVInt(0) # new count v51
        self.writeVInt(0) # new count v51

        self.writeVInt(4)
        self.writeVInt(7)
        self.writeVInt(0)
        self.writeVInt(72292)
        self.writeVInt(10)
        self.writeDataReference(15, 21) # map id
        self.writeVInt(-1)
        self.writeVInt(2)
        self.writeString("")
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0) # count
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False) # MapMaker map structure array
        self.writeVInt(0)
        self.writeBoolean(False) # Power League array entry
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(-1)
        self.writeVInt(0) # new count v51
        self.writeVInt(0) # new count v51
        self.writeVInt(0) # new count v51

        self.writeVInt(1)
        self.writeVInt(34)
        self.writeVInt(0)
        self.writeVInt(72292)
        self.writeVInt(10)
        self.writeDataReference(15, 640) # map id
        self.writeVInt(-1)
        self.writeVInt(2)
        self.writeString("")
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(0) # count
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False) # MapMaker map structure array
        self.writeVInt(0)
        self.writeBoolean(False) # Power League array entry
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(-1)
        self.writeBoolean(False)
        self.writeBoolean(False)
        self.writeVInt(-1)
        self.writeVInt(0) # new count v51
        self.writeVInt(0) # new count v51
        self.writeVInt(0) # new count v51


        self.writeVInt(0) # upcoming event count
       
        ByteStreamHelper.encodeIntList(self, [20, 35, 75, 140, 290, 480, 800, 1250, 1875, 2800]) # Brawler Upgrade Cost
        ByteStreamHelper.encodeIntList(self, [20, 50, 140, 280]) # Shop Coins Price
        ByteStreamHelper.encodeIntList(self, [150, 400, 1200, 2600]) # Shop Coins Amount

        self.writeVInt(0) #locked for chronos
        for x in range(0):
            self.writeDataReference(16, 61)
            self.writeInt(0)
            self.writeInt(0)

        self.writeVInt(1)
        self.writeVInt(41000077) # theme
        self.writeVInt(1)
        


        self.writeVInt(0) # Timed int entry count
        # self.writeVInt(31)
        # self.writeVInt(1)
        # self.writeVInt(499427)
        # self.writeVInt(758627)
        # self.writeVInt(29)
        # self.writeVInt(24)
        # self.writeVInt(0)
        # self.writeVInt(413027)
        self.writeVInt(0) # custom event

        self.writeVInt(2)
        self.writeVInt(1)
        self.writeVInt(2)
        self.writeVInt(2)
        self.writeVInt(1)
        self.writeVInt(-1)
        self.writeVInt(2)
        self.writeVInt(1)
        self.writeVInt(4)

        ByteStreamHelper.encodeIntList(self, [0, 29, 79, 169, 349, 699]) # brawler cost gems ?
        ByteStreamHelper.encodeIntList(self, [0, 160, 450, 500, 1250, 2500]) # what is that ? looks like chroma price of chromatic brawlers but it doesn't go under 500

        self.writeLong(0, 1) # Player ID

        self.writeVInt(0) # Notification factory
        
        self.writeVInt(1)
        self.writeBoolean(False)
        self.writeVInt(0) # gatcha drop
        self.writeVInt(0) 
        self.writeVInt(0)
        self.writeBoolean(False)
        # new function v46
        self.writeVInt(0) # new function v46
        self.writeBoolean(False) # login calendar ?

        self.writeVInt(0) # new function v48

        self.writeVInt(0) # v48
        self.writeVInt(0) # v48
        self.writeVInt(0) # v48
        self.writeVInt(0) # v48
        self.writeVInt(0) # v48
        self.writeBoolean(False)  # v48
        self.writeBoolean(False)  # v48
        self.writeBoolean(False)  # v48
        self.writeBoolean(False)  # v48

        self.writeVInt(0)

        # v50 this is starr drop thing
        starrDropOpening.encode(self)
        #self.writeVInt(0) # end LogicClientHome

        self.writeVLong(0, 1) # player id
        self.writeVLong(0, 1)
        self.writeVLong(0, 1)
        self.writeStringReference("risporce")
        self.writeBoolean(True) # name set
        self.writeInt(-1)

        self.writeVInt(17) # commodity count
        unlocked_brawler = [0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 95, 100, 105, 110, 115, 120, 125, 130, 177, 182, 188, 194, 200, 206, 218, 224, 230, 236, 279, 296, 303, 320, 327, 334, 341, 358, 365, 372, 379, 386, 393, 410, 417, 427, 434, 448, 466, 474, 491, 499, 507, 515, 523, 531, 539, 547, 557, 565, 573, 581, 589, 597, 605]
        self.writeVInt(len(unlocked_brawler) + 2) # unlocked brawlers + resources
        for x in unlocked_brawler:
            self.writeDataReference(23, x)
            self.writeVInt(-1)
            self.writeVInt(1)

        self.writeDataReference(5, 8)
        self.writeVInt(-1)
        self.writeVInt(1000)

        self.writeDataReference(5, 10)
        self.writeVInt(-1)
        self.writeVInt(1234)

        countBrawler = 74
        self.writeVInt(countBrawler) # HeroScore
        for x in range(countBrawler):
            self.writeDataReference(16, x)
            self.writeVInt(-1)
            self.writeVInt(1250)
        
        self.writeVInt(countBrawler)
        for x in range(countBrawler):
            self.writeDataReference(16, x)
            self.writeVInt(-1)
            self.writeVInt(1)

        self.writeVInt(0) # Array

        self.writeVInt(countBrawler) # HeroPower
        for x in range(countBrawler):
            self.writeDataReference(16, x)
            self.writeVInt(-1)
            self.writeVInt(1)
        
        self.writeVInt(countBrawler) # HeroLevel
        for x in range(countBrawler):
            self.writeDataReference(16, x)
            self.writeVInt(-1)
            self.writeVInt(10)

        self.writeVInt(1) # hero star power gadget and hypercharge
        for x in range(1):
            self.writeDataReference(23, 613)
            self.writeVInt(-1)
            self.writeVInt(1)

        self.writeVInt(countBrawler) # HeroSeenState
        for x in range(countBrawler):
            self.writeDataReference(16, x)
            self.writeVInt(-1)
            self.writeVInt(2)

        self.writeVInt(0) # Array
        self.writeVInt(0) # Array
        self.writeVInt(0) # Array
        self.writeVInt(0) # Array
        self.writeVInt(0) # Array
        self.writeVInt(0) # Array
        self.writeVInt(0) # Array
        self.writeVInt(0) # Array
        self.writeVInt(0) # Array

        self.writeVInt(999) # Diamonds
        self.writeVInt(999) # Free Diamonds
        self.writeVInt(10) # Player Level
        self.writeVInt(100)
        self.writeVInt(0) # CumulativePurchasedDiamonds or Avatar User Level Tier | 10000 < Level Tier = 3 | 1000 < Level Tier = 2 | 0 < Level Tier = 1
        self.writeVInt(100) # Battle Count
        self.writeVInt(10) # WinCount
        self.writeVInt(80) # LoseCount
        self.writeVInt(50) # WinLooseStreak
        self.writeVInt(20) # NpcWinCount
        self.writeVInt(0) # NpcLoseCount
        self.writeVInt(2) # TutorialState | shouldGoToFirstTutorialBattle = State == 0
        self.writeVInt(12)
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeString()
        self.writeVInt(0)
        self.writeVInt(0)
        self.writeVInt(1)

        

    def decode(self):
        fields = {}
        # fields["AccountID"] = self.readLong()
        # fields["HomeID"] = self.readLong()
        # fields["PassToken"] = self.readString()
        # fields["FacebookID"] = self.readString()
        # fields["GamecenterID"] = self.readString()
        # fields["ServerMajorVersion"] = self.readInt()
        # fields["ContentVersion"] = self.readInt()
        # fields["ServerBuild"] = self.readInt()
        # fields["ServerEnvironment"] = self.readString()
        # fields["SessionCount"] = self.readInt()
        # fields["PlayTimeSeconds"] = self.readInt()
        # fields["DaysSinceStartedPlaying"] = self.readInt()
        # fields["FacebookAppID"] = self.readString()
        # fields["ServerTime"] = self.readString()
        # fields["AccountCreatedDate"] = self.readString()
        # fields["StartupCooldownSeconds"] = self.readInt()
        # fields["GoogleServiceID"] = self.readString()
        # fields["LoginCountry"] = self.readString()
        # fields["KunlunID"] = self.readString()
        # fields["Tier"] = self.readInt()
        # fields["TencentID"] = self.readString()
        #
        # ContentUrlCount = self.readInt()
        # fields["GameAssetsUrls"] = []
        # for i in range(ContentUrlCount):
        #     fields["GameAssetsUrls"].append(self.readString())
        #
        # EventUrlCount = self.readInt()
        # fields["EventAssetsUrls"] = []
        # for i in range(EventUrlCount):
        #     fields["EventAssetsUrls"].append(self.readString())
        #
        # fields["SecondsUntilAccountDeletion"] = self.readVInt()
        # fields["SupercellIDToken"] = self.readCompressedString()
        # fields["IsSupercellIDLogoutAllDevicesAllowed"] = self.readBoolean()
        # fields["isSupercellIDEligible"] = self.readBoolean()
        # fields["LineID"] = self.readString()
        # fields["SessionID"] = self.readString()
        # fields["KakaoID"] = self.readString()
        # fields["UpdateURL"] = self.readString()
        # fields["YoozooPayNotifyUrl"] = self.readString()
        # fields["UnbotifyEnabled"] = self.readBoolean()
        # super().decode(fields)
        return fields

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 24101

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Home/OwnHomeDataMessage.py
risporce/BSDS
from Classes.Packets.PiranhaMessage import PiranhaMessage


class PlayerProfileMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields, player):
        self.writeVLong(fields["PlayerHighID"], fields["PlayerLowID"])
        self.writeDataReference(16,11) # 
        self.writeVInt(70)
        for i in range(70):
            self.writeDataReference(16, i)
            self.writeDataReference(0)
            self.writeVInt(500) # trophies
            self.writeVInt(1250) # highestTrophies
            self.writeVInt(11) #power level
        
        self.writeVInt(18)

        self.writeVInt(1) 
        self.writeVInt(1) # 3v3 victories

        self.writeVInt(2)
        self.writeVInt(528859) # total exp

        self.writeVInt(3)
        self.writeVInt(3) # current trophies

        self.writeVInt(4)
        self.writeVInt(4) # highest trophies

        self.writeVInt(5) 
        self.writeVInt(5) # unlocked brawler?

        self.writeVInt(8)
        self.writeVInt(6) # solo victories

        self.writeVInt(11) 
        self.writeVInt(7) # duo victories

        self.writeVInt(9) 
        self.writeVInt(8) # highest level robo rumble

        self.writeVInt(12) 
        self.writeVInt(9) # highest level boss fight

        self.writeVInt(13)
        self.writeVInt(10) # highest power league points

        self.writeVInt(14)
        self.writeVInt(11) # some power league stuff

        self.writeVInt(15)
        self.writeVInt(12) # most challenge win

        self.writeVInt(16) #highest level city rampage
        self.writeVInt(13)

        self.writeVInt(18) #highest solo power league rank
        self.writeVInt(14)

        self.writeVInt(17) #highest team power league rank
        self.writeVInt(15)

        self.writeVInt(19) # highest Club league rank
        self.writeVInt(16)

        self.writeVInt(20) # number fame
        self.writeVInt(1000)

        self.writeVInt(21)
        self.writeVInt(502052) #v50

        self.writeString("risporce")  #PlayerInfo
        self.writeVInt(100)
        self.writeVInt(28000001)
        self.writeVInt(43000001)
        self.writeVInt(14)

        self.writeBoolean(True)
        self.writeVInt(300)

        self.writeString("hello world")
        self.writeVInt(100)
        self.writeVInt(200)
        self.writeDataReference(29, 558)
        self.writeDataReference(0)
        self.writeDataReference(0)
        self.writeDataReference(0)
        self.writeDataReference(0)

        self.writeBoolean(True) #alliance
        self.writeLong(0,1) #alliance ID
        self.writeString("haccers") #alliance name
        self.writeDataReference(8,1) # alliance icon
        self.writeVInt(1) # type
        self.writeVInt(1) # member count
        self.writeVInt(10000) # total trophies
        self.writeVInt(1) # minimum trophies to enter
        self.writeDataReference(0)
        self.writeString("CA") #location
        self.writeVInt(4) # unknown
        self.writeBoolean(True) #is Family friendly
        self.writeVInt(0)
        

        self.writeDataReference(25, 1) #alliance role
        self.writeVInt(16)

    def decode(self):
        pass
        # fields = {}
        # fields["PlayerCount"] = self.readVInt()
        # fields["Text"] = self.readString()
        # fields["Unk1"] = self.readVInt()
        # super().decode(fields)
        return {}

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 24113

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Home/PlayerProfileMessage.py
risporce/BSDS
from Classes.Packets.PiranhaMessage import PiranhaMessage


class KeepAliveServerMessage(PiranhaMessage):
    def __init__(self, messageData):
        super().__init__(messageData)
        self.messageVersion = 0

    def encode(self, fields):
        pass

    def decode(self):
        return {}

    def execute(message, calling_instance, fields):
        pass

    def getMessageType(self):
        return 20108

    def getMessageVersion(self):
        return self.messageVersion
Classes/Packets/Server/Socket/KeepAliveServerMessage.py
risporce/BSDS
import socket

import Configuration
from Classes.Connection import Connection


class ServerConnection:
    def __init__(self, address):
        self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if Configuration.settings["DisableNagle"] == True:
            self.server.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, True)
        self.setupConnection(address)

    def setupConnection(self, address):
        self.server.bind(address)
        print("Listening for new connection...")
        while True:
            self.server.listen()
            socket, address = self.server.accept()
            print("New connection with address", address[0], "on port", address[1])
            Connection(socket, address).start()
Classes/ServerConnection.py
risporce/BSDS
# -*- coding: utf-8 -*-

import sys
from array import array

if sys.version_info < (2, 6):
    raise NotImplementedError('pure_pynacl requires python-2.6 or later')

lt_py3 = sys.version_info < (3,)
lt_py33 = sys.version_info < (3, 3)

integer = long if lt_py3 else int


class TypeEnum(object):
    '''
    order types used by pure_py(tweet)nacl for rapid type promotion
    '''
    u8 = 1
    u32 = 2
    u64 = 3
    Int = 5
    i64 = 7
    integer = 11


class Int(integer):
    '''
    int types
    '''
    bits = array('i').itemsize*8
    mask = (1 << bits - 1) - 1
    signed = True
    order = TypeEnum.Int

    def __str__(self):
        return integer.__str__(self)

    def __repr__(self):
        return 'Int(%s)' % integer.__repr__(self)

    def __new__(self, val=0):
        '''
        ensure that new instances have the correct size and sign
        '''
        if val < 0:
            residue = integer(-val) & self.mask
            if self.signed:
                residue = -residue
        else:
            residue = integer(val) & self.mask
        return integer.__new__(self, residue)

    def __promote_type(self, other, result):
        '''
        determine the largest type from those in self and other; if result is
        negative and both self and other are unsigned, promote it to the least
        signed type
        '''
        self_order = self.order
        other_order = other.order if isinstance(other, Int) else TypeEnum.integer

        if result < 0 and self_order < 5 and other_order < 5:
            return Int
        return self.__class__ if self_order > other_order else other.__class__

    def __unary_typed(oper):
        '''
        return a function that redefines the operation oper such that the
        result conforms to the type of self
        '''
        def operate(self):
            '''
            type the result to self
            '''
            return self.__class__(oper(self))
        return operate

    def __typed(oper):
        '''
        return a function that redefines the operation oper such that the
        result conforms to the type of self or other, whichever is larger if
        both are strongly typed (have a bits attribute); otherwise return the
        result conforming to the type of self
        '''
        def operate(self, other):
            '''
            type and bitmask the result to either self or other, whichever is
            larger
            '''
            result = oper(self, other)
            return self.__promote_type(other, result)(result)
        return operate

    def __shift(oper):
        '''
        return a function that performs bit shifting, but preserves the type of
        the left value
        '''
        def operate(self, other):
            '''
            emulate C bit shifting
            '''
            return self.__class__(oper(self, other))
        return operate

    def __invert():
        '''
        return a function that performs bit inversion
        '''
        def operate(self):
            '''
            emulate C bit inversion
            '''
            if self.signed:
                return self.__class__(integer.__invert__(self))
            else:
                return self.__class__(integer.__xor__(self, self.mask))
        return operate

    # bitwise operations
    __lshift__  = __shift(integer.__lshift__)
    __rlshift__ = __shift(integer.__rlshift__)
    __rshift__  = __shift(integer.__rshift__)
    __rrshift__ = __shift(integer.__rrshift__)
    __and__     = __typed(integer.__and__)
    __rand__    = __typed(integer.__rand__)
    __or__      = __typed(integer.__or__)
    __ror__     = __typed(integer.__ror__)
    __xor__     = __typed(integer.__xor__)
    __rxor__    = __typed(integer.__rxor__)
    __invert__  = __invert()

    # arithmetic operations
    if not lt_py3:
        __ceil__  = __unary_typed(integer.__ceil__)
        __floor__ = __unary_typed(integer.__floor__)
        __int__   = __unary_typed(integer.__int__)
    __abs__       = __unary_typed(integer.__abs__)
    __pos__       = __unary_typed(integer.__pos__)
    __neg__       = __unary_typed(integer.__neg__)
    __add__       = __typed(integer.__add__)
    __radd__      = __typed(integer.__radd__)
    __sub__       = __typed(integer.__sub__)
    __rsub__      = __typed(integer.__rsub__)
    __mod__       = __typed(integer.__mod__)
    __rmod__      = __typed(integer.__rmod__)
    __mul__       = __typed(integer.__mul__)
    __rmul__      = __typed(integer.__rmul__)
    if lt_py3:
        __div__   = __typed(integer.__div__)
        __rdiv__  = __typed(integer.__rdiv__)
    __floordiv__  = __typed(integer.__floordiv__)
    __rfloordiv__ = __typed(integer.__rfloordiv__)
    __pow__       = __typed(integer.__pow__)
    __rpow__      = __typed(integer.__rpow__)


class IntArray(list):
    '''
    arrays of int types
    '''
    def __init__(self, typ, init=(), size=0):
        '''
        create array of ints
        '''
        self.typ = typ

        if lt_py3 and isinstance(init, bytes):
            init = [ord(i) for i in init]

        if size:
            init_size = len(init)
            if init_size < size:
                list.__init__(self, [typ(i) for i in init] + [typ() for i in range(size - init_size)])
            else:
                list.__init__(self, [typ(i) for i in init[:size]])
        else:
            list.__init__(self, [typ(i) for i in init])

    def __str__(self):
        return list.__str__(self)

    def __repr__(self):
        return 'IntArray(%s, init=%s)' % (self.typ, list.__repr__(self))


# TweetNaCl external functions
from Classes.TweetnaclCrypto.tweetnacl import (
    crypto_verify_16_tweet,
    crypto_verify_32_tweet,
    crypto_core_salsa20_tweet,
    crypto_core_hsalsa20_tweet,
    crypto_stream_salsa20_tweet_xor,
    crypto_stream_salsa20_tweet,
    crypto_stream_xsalsa20_tweet,
    crypto_stream_xsalsa20_tweet_xor,
    crypto_onetimeauth_poly1305_tweet,
    crypto_onetimeauth_poly1305_tweet_verify,
    crypto_secretbox_xsalsa20poly1305_tweet,
    crypto_secretbox_xsalsa20poly1305_tweet_open,
    crypto_scalarmult_curve25519_tweet,
    crypto_scalarmult_curve25519_tweet_base,
    crypto_box_curve25519xsalsa20poly1305_tweet_keypair,
    crypto_box_curve25519xsalsa20poly1305_tweet_beforenm,
    crypto_box_curve25519xsalsa20poly1305_tweet_afternm,
    crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm,
    crypto_box_curve25519xsalsa20poly1305_tweet,
    crypto_box_curve25519xsalsa20poly1305_tweet_open,
    crypto_hashblocks_sha512_tweet,
    crypto_hash_sha512_tweet,
    crypto_sign_ed25519_tweet_keypair,
    crypto_sign_ed25519_tweet,
    crypto_sign_ed25519_tweet_open,
)

Classes/TweetnaclCrypto/__init__.py
risporce/BSDS
# -*- coding: utf-8 -*-

"""
Build and install the TweetNaCl wrapper.
"""

from __future__ import print_function

import platform

from distutils.core import setup, Extension


libraries = []

if platform.system() == "Windows":
    libraries.append("advapi32")

nacl_module = Extension('_tweetnacl',
                        ["tweetnaclmodule.c", "tweetnacl.c", "randombytes.c"],
                        libraries=libraries,
                        extra_compile_args=["-O2",
                                            "-funroll-loops",
                                            "-fomit-frame-pointer"])

setup(name = 'tweetnaclCrypt',
       version = '0.1',
       author = "Brian Warner, Jan Mojžíš",
       description = """Python wrapper for TweetNaCl""",
       ext_modules = [nacl_module],
       packages = ["tweetnacl"],
       package_dir = {"tweetnacl": ""},
      )

Classes/TweetnaclCrypto/setup.py
risporce/BSDS
# -*- coding: utf-8 -*-

# import python libs
import os
from array import array

# import pure_pynacl libs

from Classes.TweetnaclCrypto import lt_py3, lt_py33, TypeEnum, integer, Int, IntArray
# from tweetnacl import TypeEnum, integer, Int, IntArray


class u8(Int):
    '''unsigned char'''
    bits = array('B').itemsize*8
    mask = (1 << bits) - 1
    signed = False
    order = TypeEnum.u8

    def __repr__(self):
        return 'u8(%s)' % integer.__repr__(self)


class u32(Int):
    '''unsigned long'''
    bits = array('L').itemsize*8
    mask = (1 << bits) - 1
    signed = False
    order = TypeEnum.u32

    def __repr__(self):
        return 'u32(%s)' % integer.__repr__(self)


class u64(Int):
    '''unsigned long long'''
    bits = array('L' if lt_py33 else 'Q').itemsize*8
    mask = (1 << bits) - 1
    signed = False
    order = TypeEnum.u64

    def __repr__(self):
        return 'u64(%s)' % integer.__repr__(self)


class i64(Int):
    '''long long'''
    bits = array('l' if lt_py33 else 'q').itemsize*8
    mask = (1 << bits - 1) - 1
    signed = True
    order = TypeEnum.i64

    def __repr__(self):
        return 'i64(%s)' % integer.__repr__(self)


class gf(IntArray):
    def __init__(self, init=()):
        IntArray.__init__(self, i64, init=init, size=16)


def randombytes(c, s):
    '''
    insert s random bytes into c
    '''
    if lt_py3:
        c[:s] = bytearray(os.urandom(s))
    else:
        c[:s] = os.urandom(s)


_0 = IntArray(u8, size=16)
_9 = IntArray(u8, size=32, init=[9])

gf0 = gf()
gf1 = gf([1])
_121665 = gf([0xDB41, 1])
D = gf([0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203])
D2 = gf([0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406])
X = gf([0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169])
Y = gf([0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666])
I = gf([0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83])


def L32(x, c):
    '''static u32 L32(u32 x, int c)'''
    return (u32(x) << c) | ((u32(x) & 0xffffffff) >> (32 - c))


def ld32(x):
    '''u32 ld32(const u8*x)'''
    u = u32(x[3])
    u = (u << 8) | u32(x[2])
    u = (u << 8) | u32(x[1])
    return (u << 8) | u32(x[0])


def dl64(x):
    '''u64 dl64(const u8*x)'''
    u = u64()
    for i in range(8): u = (u << 8) | u8(x[i])
    return u


def st32(x, u):
    '''void st32(u8*x, u32 u)'''
    for i in range(4): x[i] = u8(u); u >>= 8
    return x


def ts64(x, u):
    '''void ts64(u8*x, u64 u)'''
    for i in range(7, -1, -1): x[i] = u8(u); u >>= 8
    return x


def vn(x, y, n):
    '''int vn(const u8*x, const u8*y, int n)'''
    d = u32()
    for i in range(n): d |= x[i] ^ y[i]
    return (1 & ((d - 1) >> 8)) - 1


def crypto_verify_16_tweet(x, y):
    '''int crypto_verify_16_tweet(const u8*x, const u8*y)'''
    return vn(x, y, 16)


def crypto_verify_32_tweet(x, y):
    '''int crypto_verify_32_tweet(const u8*x, const u8*y)'''
    return vn(x, y, 32)


def core(out, in_, k, c, h):
    '''void core(u8*out, const u8*in, const u8*k, const u8*c, int h)'''
    w = IntArray(u32, size=16)
    x = IntArray(u32, size=16)
    y = IntArray(u32, size=16)
    t = IntArray(u32, size=4)

    for i in range(4):
        x[5*i] = ld32(c[4*i:])
        x[1 + i] = ld32(k[4*i:])
        x[6 + i] = ld32(in_[4*i:])
        x[11 + i] = ld32(k[16 + 4*i:])

    for i in range(16): y[i] = x[i]

    for i in range(19):
        for j in range(4):
            for m in range(4): t[m] = x[(5*j + 4*m)%16]
            t[1] ^= L32(t[0] + t[3], 7)
            t[2] ^= L32(t[1] + t[0], 9)
            t[3] ^= L32(t[2] + t[1],13)
            t[0] ^= L32(t[3] + t[2],18)
            for m in range(4): w[4*j + (j + m)%4] = t[m]
        for m in range(16): x[m] = w[m]

    if h:
        for i in range(16): x[i] += y[i]
        for i in range(4):
            x[5*i] -= ld32(c[4*i:])
            x[6+i] -= ld32(in_[4*i:])
        for i in range(4):
            out[4*i:] = st32(out[4*i:], x[5*i])
            out[16 + 4*i:] = st32(out[16 + 4*i:], x[6 + i])
    else:
        for i in range(16):
            out[4*i:] = st32(out[4*i:], x[i] + y[i])


def crypto_core_salsa20_tweet(out, in_, k, c):
    '''int crypto_core_salsa20_tweet(u8*out, const u8*in, const u8*k, const u8*c)'''
    core(out, in_, k, c, False)
    return 0


def crypto_core_hsalsa20_tweet(out, in_, k, c):
    '''int crypto_core_hsalsa20_tweet(u8*out, const u8*in, const u8*k, const u8*c)'''
    core(out, in_, k, c, True)
    return 0


sigma = IntArray(u8, size=16, init=b'expand 32-byte k')


def crypto_stream_salsa20_tweet_xor(c, m, b, n, k):
    '''int crypto_stream_salsa20_tweet_xor(u8*c, const u8*m, u64 b, const u8*n, const u8*k)'''
    z = IntArray(u8, size=16)
    x = IntArray(u8, size=64)

    if not b: return 0

    for i in range(8): z[i] = n[i]

    c_off = 0 ; m_off = 0
    while b >= 64:
        crypto_core_salsa20_tweet(x, z, k, sigma)
        for i in range(64): c[i + c_off] = (m[i + m_off] if m else 0) ^ x[i]
        u = u32(1)
        for i in range(8, 16):
            u += u32(z[i])
            z[i] = u
            u >>= 8
        b -= 64
        c_off += 64
        if m: m_off += 64

    if b:
        crypto_core_salsa20_tweet(x, z, k, sigma)
        for i in range(b): c[i + c_off] = (m[i + m_off] if m else 0) ^ x[i]

    return 0


def crypto_stream_salsa20_tweet(c, d, n, k):
    '''int crypto_stream_salsa20_tweet(u8*c, u64 d, const u8*n, const u8*k)'''
    return crypto_stream_salsa20_tweet_xor(c, IntArray(u8), d, n, k)


def crypto_stream_xsalsa20_tweet(c, d, n, k):
    '''int crypto_stream_xsalsa20_tweet(u8*c, u64 d, const u8*n, const u8*k)'''
    s = IntArray(u8, size=32)
    crypto_core_hsalsa20_tweet(s, n, k, sigma)
    return crypto_stream_salsa20_tweet(c, d, n[16:], s)


def crypto_stream_xsalsa20_tweet_xor(c, m, d, n, k):
    '''int crypto_stream_xsalsa20_tweet_xor(u8*c, const u8*m, u64 d, const u8*n, const u8*k)'''
    s = IntArray(u8, size=32)
    crypto_core_hsalsa20_tweet(s, n, k, sigma)
    return crypto_stream_salsa20_tweet_xor(c, m, d, n[16:], s)


def add1305(h, c):
    '''void add1305(u32*h, const u32*c)'''
    u = u32()
    for j in range(17):
        u += u32(h[j] + c[j])
        h[j] = u & 255
        u >>= 8


minusp = IntArray(u32, size=17, init=(5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252))


def crypto_onetimeauth_poly1305_tweet(out, m, n, k):
    '''int crypto_onetimeauth_poly1305_tweet(u8*out, const u8*m, u64 n, const u8*k)'''
    s = u32()
    u = u32()
    x = IntArray(u32, size=17)
    r = IntArray(u32, size=17)
    h = IntArray(u32, size=17)
    c = IntArray(u32, size=17)
    g = IntArray(u32, size=17)

    for j in range(16): r[j] = k[j]
    r[3] &= 15
    r[4] &= 252
    r[7] &= 15
    r[8] &= 252
    r[11] &= 15
    r[12] &= 252
    r[15] &= 15

    while n > 0:
        c[:17] = 17*[u32()]
        for j in range(16):
            if j >= n: j -= 1 ; break
            c[j] = m[j]
        j += 1
        c[j] = 1
        m = m[j:]; n -= j
        add1305(h, c)

        for i in range(17):
            x[i] = 0
            for j in range(17): x[i] += h[j]*(r[i - j] if j <= i else 320*r[i + 17 - j])

        for i in range(17): h[i] = x[i]
        u = 0

        for j in range(16):
            u += h[j]
            h[j] = u & 255
            u >>= 8

        u += h[16]; h[16] = u & 3
        u = 5*(u >> 2)

        for j in range(16):
            u += h[j]
            h[j] = u & 255
            u >>= 8

        u += h[16]; h[16] = u

    for j in range(17): g[j] = h[j]
    add1305(h, minusp)
    s = -(h[16] >> 7)
    for j in range(17): h[j] ^= s & (g[j] ^ h[j])

    for j in range(16): c[j] = k[j + 16]
    c[16] = 0
    add1305(h, c)
    for j in range(16): out[j] = h[j]

    return 0


def crypto_onetimeauth_poly1305_tweet_verify(h, m, n, k):
    '''int crypto_onetimeauth_poly1305_tweet_verify(const u8*h, const u8*m, u64 n, const u8*k)'''
    x = IntArray(u8, size=16)
    crypto_onetimeauth_poly1305_tweet(x, m, n, k)
    return crypto_verify_16_tweet(h, x)


def crypto_secretbox_xsalsa20poly1305_tweet(c, m, d, n, k):
    '''int crypto_secretbox_xsalsa20poly1305_tweet(u8*c, const u8*m, u64 d, const u8*n, const u8*k)'''
    if d < 32: return -1
    crypto_stream_xsalsa20_tweet_xor(c, m, d, n, k)
    c_out = c[16:]
    crypto_onetimeauth_poly1305_tweet(c_out, c[32:], d - 32, c)
    c[16:] = c_out
    c[:16] = 16*[u8()]
    return 0


def crypto_secretbox_xsalsa20poly1305_tweet_open(m, c, d, n, k):
    '''int crypto_secretbox_xsalsa20poly1305_tweet_open(u8*m, const u8*c, u64 d, const u8*n, const u8*k)'''
    x = IntArray(u8, size=32)
    if d < 32: return -1
    crypto_stream_xsalsa20_tweet(x, 32, n, k)
    if crypto_onetimeauth_poly1305_tweet_verify(c[16:], c[32:], d - 32, x) != 0: return -1
    crypto_stream_xsalsa20_tweet_xor(m, c, d, n, k)
    m[:32] = 32*[u8()]
    return 0


def set25519(r, a):
    '''void set25519(gf r, const gf a)'''
    for i in range(16): r[i] = a[i]


def car25519(o):
    '''void car25519(gf o)'''
    c = i64()
    for i in range(16):
        o[i] += (i64(1) << 16)
        c = o[i] >> 16
        o[(i + 1)*(i < 15)] += c - 1 + 37*(c - 1)*(i == 15)
        o[i] -= c << 16


def sel25519(p, q, b):
    '''void sel25519(gf p, gf q, int b)'''
    t = i64()
    c = i64(~(b - 1))
    for i in range(16):
        t = c & (p[i] ^ q[i])
        p[i] ^= t
        q[i] ^= t
    return p, q


def pack25519(o, n):
    '''void pack25519(u8*o, const gf n)'''
    b = int()
    m = gf()
    t = gf()
    for i in range(16): t[i] = n[i]

    car25519(t)
    car25519(t)
    car25519(t)

    for j in range(2):
        m[0] = t[0] - 0xffed
        for i in range(1,15):
            m[i] = t[i] - 0xffff - ((m[i - 1] >> 16) & 1)
            m[i-1] &= 0xffff

        m[15] = t[15] - 0x7fff - ((m[14] >> 16) & 1)
        b = (m[15] >> 16) & 1
        m[14] &= 0xffff

        sel25519(t, m, 1 - b)

    for i in range(16):
        o[2*i] = t[i] & 0xff
        o[2*i + 1] = t[i] >> 8


def neq25519(a, b):
    '''int neq25519(const gf a, const gf b)'''
    c = IntArray(u8, size=32)
    d = IntArray(u8, size=32)
    pack25519(c, a)
    pack25519(d, b)
    return crypto_verify_32_tweet(c, d)


def par25519(a):
    '''u8 par25519(const gf a)'''
    d = IntArray(u8, size=32)
    pack25519(d, a)
    return d[0] & 1


def unpack25519(o, n):
    '''void unpack25519(gf o, const u8*n)'''
    for i in range(16): o[i] = n[2*i] + (i64(n[2*i + 1]) << 8)
    o[15] &= 0x7fff


def A(o, a, b):
    '''void A(gf o, const gf a, const gf b)'''
    for i in range(16): o[i] = a[i] + b[i]


def Z(o, a, b):
    '''void Z(gf o, const gf a, const gf b)'''
    for i in range(16): o[i] = a[i] - b[i]


def M(o, a, b):
    '''void M(gf o, const gf a, const gf b)'''
    t = IntArray(i64, size=31)
    for i in range(16):
        for j in range(16): t[i + j] += a[i]*b[j]
    for i in range(15): t[i] += 38*t[i + 16]
    for i in range(16): o[i] = t[i]

    car25519(o)
    car25519(o)

    return o


def S(o, a):
    '''void S(gf o, const gf a)'''
    M(o, a, a)


def inv25519(o, i):
    '''void inv25519(gf o, const gf i)'''
    c = gf()
    for a in range(16): c[a] = i[a]
    for a in range(253, -1, -1):
        S(c, c)
        if a != 2 and a != 4: M(c, c, i)

    for a in range(16): o[a] = c[a]

    return o


def pow2523(o, i):
    '''void pow2523(gf o, const gf i)'''
    c = gf()
    for a in range(16): c[a] = i[a]
    for a in range(250, -1, -1):
        S(c, c)
        if a != 1: M(c, c, i)

    for a in range(16): o[a] = c[a]


def crypto_scalarmult_curve25519_tweet(q, n, p):
    '''int crypto_scalarmult_curve25519_tweet(u8*q, const u8*n, const u8*p)'''
    z = IntArray(u8, size=32)
    x = IntArray(i64, size=80)
    r = i64()

    a = gf()
    b = gf()
    c = gf()
    d = gf()
    e = gf()
    f = gf()

    for i in range(31): z[i] = n[i]
    z[31] = (n[31] & 127) | 64
    z[0] &= 248

    unpack25519(x, p)

    for i in range(16):
        b[i] = x[i]
        d[i] = a[i] = c[i] = 0

    a[0] = d[0] = 1
    for i in range(254, -1, -1):
        r = (z[i >> 3] >> (i & 7)) & 1
        sel25519(a, b, r)
        sel25519(c, d, r)
        A(e, a, c)
        Z(a, a, c)
        A(c, b, d)
        Z(b, b, d)
        S(d, e)
        S(f, a)
        M(a, c, a)
        M(c, b, e)
        A(e, a, c)
        Z(a, a, c)
        S(b, a)
        Z(c, d, f)
        M(a, c, _121665)
        A(a, a, d)
        M(c, c, a)
        M(a, d, f)
        M(d, b, x)
        S(b, e)
        sel25519(a, b, r)
        sel25519(c, d, r)

    for i in range(16):
        x[i + 16] = a[i]
        x[i + 32] = c[i]
        x[i + 48] = b[i]
        x[i + 64] = d[i]

    x[32:] = inv25519(x[32:], x[32:])
    x[16:] = M(x[16:], x[16:], x[32:])
    pack25519(q, x[16:])
    return 0


def crypto_scalarmult_curve25519_tweet_base(q, n):
    '''int crypto_scalarmult_curve25519_tweet_base(u8*q, const u8*n)'''
    return crypto_scalarmult_curve25519_tweet(q, n, _9)


def crypto_box_curve25519xsalsa20poly1305_tweet_keypair(y, x):
    '''int crypto_box_curve25519xsalsa20poly1305_tweet_keypair(u8*y, u8*x)'''
    randombytes(x, 32)
    return crypto_scalarmult_curve25519_tweet_base(y, x)


def crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(k, y, x):
    '''int crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(u8*k, const u8*y, const u8*x)'''
    s = IntArray(u8, size=32)
    crypto_scalarmult_curve25519_tweet(s, x, y)
    return crypto_core_hsalsa20_tweet(k, _0, s, sigma)


def crypto_box_curve25519xsalsa20poly1305_tweet_afternm(c, m, d, n, k):
    '''int crypto_box_curve25519xsalsa20poly1305_tweet_afternm(u8*c, const u8*m, u64 d, const u8*n, const u8*k)'''
    return crypto_secretbox_xsalsa20poly1305_tweet(c, m, d, n, k)


def crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(m, c, d, n, k):
    '''int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(u8*m, const u8*c, u64 d, const u8*n, const u8*k)'''
    return crypto_secretbox_xsalsa20poly1305_tweet_open(m, c, d, n, k)


def crypto_box_curve25519xsalsa20poly1305_tweet(c, m, d, n, y, x):
    '''int crypto_box_curve25519xsalsa20poly1305_tweet(u8*c, const u8*m, u64 d, const u8*n, const u8*y, const u8*x)'''
    k = IntArray(u8, size=32)
    crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(k, y, x)
    return crypto_box_curve25519xsalsa20poly1305_tweet_afternm(c, m, d, n, k)


def crypto_box_curve25519xsalsa20poly1305_tweet_open(m, c, d, n, y, x):
    '''int crypto_box_curve25519xsalsa20poly1305_tweet_open(u8*m, const u8*c, u64 d, const u8*n, const u8*y, const u8*x)'''
    k = IntArray(u8, size=32)
    crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(k, y, x)
    return crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(m, c, d, n, k)


def R(x, c):
    '''u64 R(u64 x, int c)'''
    return (u64(x) >> c) | (u64(x) << (64 - c))


def Ch(x, y, z):
    '''u64 Ch(u64 x, u64 y, u64 z)'''
    return (u64(x) & u64(y)) ^ (~u64(x) & u64(z))


def Maj(x, y, z):
    '''u64 Maj(u64 x, u64 y, u64 z)'''
    return (u64(x) & u64(y)) ^ (u64(x) & u64(z)) ^ (u64(y) & u64(z))


def Sigma0(x):
    '''u64 Sigma0(u64 x)'''
    return R(x, 28) ^ R(x, 34) ^ R(x, 39)


def Sigma1(x):
    '''u64 Sigma1(u64 x)'''
    return R(x, 14) ^ R(x, 18) ^ R(x, 41)


def sigma0(x):
    '''u64 sigma0(u64 x)'''
    return R(x, 1) ^ R(x, 8) ^ (x >> 7)


def sigma1(x):
    '''u64 sigma1(u64 x)'''
    return R(x, 19) ^ R(x, 61) ^ (x >> 6)


K = IntArray(u64, size=80, init=[
    0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc,
    0x3956c25bf348b538, 0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118,
    0xd807aa98a3030242, 0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
    0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235, 0xc19bf174cf692694,
    0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
    0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
    0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4,
    0xc6e00bf33da88fc2, 0xd5a79147930aa725, 0x06ca6351e003826f, 0x142929670a0e6e70,
    0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
    0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
    0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30,
    0xd192e819d6ef5218, 0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
    0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8,
    0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3,
    0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
    0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b,
    0xca273eceea26619c, 0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178,
    0x06f067aa72176fba, 0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
    0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c,
    0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
])


def crypto_hashblocks_sha512_tweet(x, m, n):
    '''int crypto_hashblocks_sha512_tweet(u8*x, const u8*m, u64 n)'''
    z = IntArray(u64, size=8)
    b = IntArray(u64, size=8)
    a = IntArray(u64, size=8)
    w = IntArray(u64, size=16)
    t = u64()

    for i in range(8): z[i] = a[i] = dl64(x[8*i:])

    m_off = 0
    while n >= 128:
        for i in range(16): w[i] = dl64(m[8*i + m_off:])

        for i in range(80):
            for j in range(8): b[j] = a[j]
            t = a[7] + Sigma1(a[4]) + Ch(a[4], a[5], a[6]) + K[i] + w[i%16]
            b[7] = t + Sigma0(a[0]) + Maj(a[0], a[1], a[2])
            b[3] += t

            for j in range(8): a[(j + 1)%8] = b[j]
            if i%16 == 15:
                for j in range(16):
                    w[j] += w[(j + 9)%16] + sigma0(w[(j + 1)%16]) + sigma1(w[(j + 14)%16])

        for i in range(8):
            a[i] += z[i]; z[i] = a[i]

        m_off += 128
        n -= 128

    for i in range(8): x[8*i:] = ts64(x[8*i:], z[i])

    return n


iv = IntArray(u8, size=64, init=[
    0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
    0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
    0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
    0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
    0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
    0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
    0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
    0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79
])


def crypto_hash_sha512_tweet(out, m, n):
    '''int crypto_hash_sha512_tweet(u8*out, const u8*m, u64 n)'''
    h = IntArray(u8, size=64)
    x = IntArray(u8, size=256)
    b = u64(n)

    for i in range(64): h[i] = iv[i]

    crypto_hashblocks_sha512_tweet(h, m, n)
    m_off = n
    n &= 127
    m_off -= n

    x[:256] = 256*[u8()]
    for i in range(n): x[i] = m[i + m_off]
    x[n] = 128

    n = 256 - 128*(n < 112)
    x[n - 9] = b >> 61
    x[n - 8:] = ts64(x[n - 8:], b << 3)
    crypto_hashblocks_sha512_tweet(h, x, n)

    for i in range(64): out[i] = h[i]

    return 0


def add(p, q):
    '''void add(gf p[4], gf q[4])'''
    a = gf()
    b = gf()
    c = gf()
    d = gf()
    t = gf()
    e = gf()
    f = gf()
    g = gf()
    h = gf()

    Z(a, p[1], p[0])
    Z(t, q[1], q[0])
    M(a, a, t)
    A(b, p[0], p[1])
    A(t, q[0], q[1])
    M(b, b, t)
    M(c, p[3], q[3])
    M(c, c, D2)
    M(d, p[2], q[2])
    A(d, d, d)
    Z(e, b, a)
    Z(f, d, c)
    A(g, d, c)
    A(h, b, a)

    M(p[0], e, f)
    M(p[1], h, g)
    M(p[2], g, f)
    M(p[3], e, h)


def cswap(p, q, b):
    '''void cswap(gf p[4], gf q[4], u8 b)'''
    for i in range(4):
        p[i], q[i] = sel25519(p[i], q[i], b)


def pack(r, p):
    '''void pack(u8*r, gf p[4])'''
    tx = gf()
    ty = gf()
    zi = gf()
    inv25519(zi, p[2])
    M(tx, p[0], zi)
    M(ty, p[1], zi)
    pack25519(r, ty)
    r[31] ^= par25519(tx) << 7


def scalarmult(p, q, s):
    '''void scalarmult(gf p[4], gf q[4], const u8*s)'''
    set25519(p[0], gf0)
    set25519(p[1], gf1)
    set25519(p[2], gf1)
    set25519(p[3], gf0)
    for i in range(255, -1, -1):
        b = u8((s[i//8] >> (i & 7)) & 1)
        cswap(p, q, b)
        add(q, p)
        add(p, p)
        cswap(p, q, b)


def scalarbase(p, s):
    '''void scalarbase(gf p[4], const u8*s)'''
    q = [gf() for i in range(4)]
    set25519(q[0], X)
    set25519(q[1], Y)
    set25519(q[2], gf1)
    M(q[3], X, Y)
    scalarmult(p, q, s)


def crypto_sign_ed25519_tweet_keypair(pk, sk):
    '''int crypto_sign_ed25519_tweet_keypair(u8*pk, u8*sk)'''
    d = IntArray(u8, size=64)
    p = [gf() for i in range(4)]

    randombytes(sk, 32)
    crypto_hash_sha512_tweet(d, sk, 32)
    d[0] &= 248
    d[31] &= 127
    d[31] |= 64

    scalarbase(p, d)
    pack(pk, p)

    for i in range(32): sk[32 + i] = pk[i]
    return 0


L = IntArray(u64, size=32, init=[
    0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10
])


def modL(r, x):
    '''void modL(u8*r, i64 x[64])'''
    carry = i64()
    for i in range(63, 31, -1):
        carry = 0
        for j in range(i - 32, i - 12):
            x[j] += carry - 16*x[i]*L[j - (i - 32)]
            carry = (x[j] + 128) >> 8
            x[j] -= carry << 8
        j += 1
        x[j] += carry
        x[i] = 0

    carry = 0
    for j in range(32):
        x[j] += carry - (x[31] >> 4)*L[j]
        carry = x[j] >> 8
        x[j] &= 255

    for j in range(32): x[j] -= carry*L[j]
    for i in range(32):
        x[i + 1] += x[i] >> 8
        r[i] = x[i] & 255

    return r


def reduce(r):
    '''void reduce(u8*r)'''
    x = IntArray(i64, size=64)
    for i in range(64): x[i] = u64(r[i])
    r[:64] = 64*[u8()]
    modL(r, x)


def crypto_sign_ed25519_tweet(sm, smlen, m, n, sk):
    '''int crypto_sign_ed25519_tweet(u8*sm, u64*smlen, const u8*m, u64 n, const u8*sk)'''
    d = IntArray(u8, size=64)
    h = IntArray(u8, size=64)
    r = IntArray(u8, size=64)
    x = IntArray(i64, size=64)
    p = [gf() for i in range(4)]

    crypto_hash_sha512_tweet(d, sk, 32)
    d[0] &= 248
    d[31] &= 127
    d[31] |= 64

    # There is no (simple?) way to return this argument's value back to the
    # user in python.  Rather than redefining the return value of this function
    # it is better to advise the user that ``smlen`` does not work as it does
    # in the C implementation and that its value will be equal to ``n + 64``.
    smlen = n + 64
    for i in range(n): sm[64 + i] = m[i]
    for i in range(32): sm[32 + i] = d[32 + i]

    crypto_hash_sha512_tweet(r, sm[32:], n + 32)
    reduce(r)
    scalarbase(p, r)
    pack(sm, p)

    for i in range(32): sm[i + 32] = sk[i + 32]
    crypto_hash_sha512_tweet(h, sm, n + 64)
    reduce(h)

    for i in range(64): x[i] = 0
    for i in range(32): x[i] = u64(r[i])
    for i in range(32):
        for j in range(32): x[i + j] += h[i]*u64(d[j])
    sm[32:] = modL(sm[32:], x)

    return 0


def unpackneg(r, p):
    '''int unpackneg(gf r[4], const u8 p[32])'''
    t = gf()
    chk = gf()
    num = gf()
    den = gf()
    den2 = gf()
    den4 = gf()
    den6 = gf()

    set25519(r[2], gf1)
    unpack25519(r[1], p)
    S(num, r[1])
    M(den, num, D)
    Z(num, num, r[2])
    A(den, r[2], den)

    S(den2, den)
    S(den4, den2)
    M(den6, den4, den2)
    M(t, den6, num)
    M(t, t, den)

    pow2523(t, t)
    M(t, t, num)
    M(t, t, den)
    M(t, t, den)
    M(r[0], t, den)

    S(chk, r[0])
    M(chk, chk, den)
    if neq25519(chk, num): M(r[0], r[0], I)

    S(chk, r[0])
    M(chk, chk, den)
    if neq25519(chk, num): return -1

    if par25519(r[0]) == (p[31] >> 7): Z(r[0], gf0, r[0])

    M(r[3], r[0], r[1])
    return 0


def crypto_sign_ed25519_tweet_open(m, mlen, sm, n, pk):
    '''int crypto_sign_ed25519_tweet_open(u8*m, u64*mlen, const u8*sm, u64 n, const u8*pk)'''
    t = IntArray(u8, size=32)
    h = IntArray(u8, size=64)
    p = [gf() for i in range(4)]
    q = [gf() for i in range(4)]

    mlen = -1
    if n < 64: return -1

    if unpackneg(q, pk): return -1

    for i in range(n): m[i] = sm[i]
    for i in range(32): m[i + 32] = pk[i]
    crypto_hash_sha512_tweet(h, m, n)
    reduce(h)
    scalarmult(p, q, h)

    scalarbase(q, sm[32:])
    add(p, q)
    pack(t, p)

    n -= 64
    if crypto_verify_32_tweet(sm, t):
        for i in range(n): m[i] = 0
        return -1

    for i in range(n): m[i] = sm[i + 64]
    # There is no (simple?) way to return this argument's value back to the
    # user in python.  Rather than redefining the return value of this function
    # it is better to advise the user that ``mlen`` does not work as it does in
    # the C implementation and that its value will be equal to ``-1`` if ``n <
    # 64`` or decryption fails and ``n - 64`` otherwise.
    mlen = n
    return 0

Classes/TweetnaclCrypto/tweetnacl.py
risporce/BSDS
class Utility:
    def parseFields(fields: dict):
        print()
        for typeName,value in fields.items():
            print(f"{typeName}: {value}")
        print()

Classes/Utility.py
risporce/BSDS
# DisableNagle: reduce delay and improve performance between client and server BUT require more power #

settings = {
    "DisableNagle": True,
    "PrintEnabled": True
}
Configuration.py
risporce/BSDS
from Classes.ServerConnection import ServerConnection

ServerConnection(("0.0.0.0", 9339))
Core.py
risporce/BSDS