├── Files
└── EventAssets
│ └── pop_up_1920x1235_welcome.png
├── Logic
├── Classes
│ ├── LogicDataTables.py
│ ├── LogicOfferBundle.py
│ ├── LogicClientAvatar.py
│ ├── LogicConfData.py
│ ├── LogicDataSlot.py
│ ├── LogicDailyData.py
│ └── LogicClientHome.py
├── Player.py
├── Device.py
└── Entry
│ ├── CooldownEntry.py
│ ├── AdStatus.py
│ ├── RelaseEntry.py
│ ├── EventSlot.py
│ ├── IntValueEntry.py
│ └── EventData.py
├── Packets
├── Messages
│ ├── Server
│ │ ├── Home
│ │ │ ├── KeepAliveOkMessage.py
│ │ │ ├── PlayerJWTokenMessage.py
│ │ │ ├── OwnHomeDataMessage.py
│ │ │ ├── LobbyInfoMessage.py
│ │ │ ├── SeasonRewardsMessage.py
│ │ │ ├── LeaderboardMessage.py
│ │ │ └── PlayerProfileMessage.py
│ │ ├── Battle
│ │ │ ├── MatchMakingCancelledMessage.py
│ │ │ ├── UdpConnectionInfoMessage.py
│ │ │ ├── VisionUpdateMessage.py
│ │ │ ├── MatchMakingStatusMessage.py
│ │ │ ├── StartLoadingMessage.py
│ │ │ └── BattleEndMessage.py
│ │ ├── Login
│ │ │ ├── ServerHelloMessage.py
│ │ │ ├── CryptoErrorMessage.py
│ │ │ └── LoginOkMessage.py
│ │ └── Alliance
│ │ │ ├── MyAllianceMessage.py
│ │ │ ├── AllianceWarMessage.py
│ │ │ └── AllianceDataMessage.py
│ └── Client
│ │ ├── Gameroom
│ │ ├── TeamLeaveMessage.py
│ │ ├── TeamMemberStatusMessage.py
│ │ ├── TeamSetLocationMessage.py
│ │ ├── TeamSetMemberReadyMessage.py
│ │ ├── TeamSetEventMessage.py
│ │ ├── TeamChangeMemberSettingsMessage.py
│ │ └── TeamCreateMessage.py
│ │ ├── Home
│ │ ├── UdpCheckConnectionMessage.py
│ │ ├── PlayerStatusMessage.py
│ │ ├── ClientCapabilitiesMessage.py
│ │ ├── ReportUserMessage.py
│ │ ├── AnalyticEventMessage.py
│ │ ├── KeepAliveMessage.py
│ │ ├── GetSeasonRewardsMessage.py
│ │ ├── AskPlayerJWTokenMessage.py
│ │ ├── GetPlayerProfileMessage.py
│ │ └── GetLeaderboardMessage.py
│ │ ├── Login
│ │ ├── AuthenticationCheckMessage.py
│ │ ├── ResetAccountMessage.py
│ │ ├── AccountSwitchedMessage.py
│ │ ├── SetDeviceTokenMessage.py
│ │ ├── ClientCryptoErrorMessage.py
│ │ ├── CreateAccountMessage.py
│ │ ├── UnlockAccountMessage.py
│ │ ├── LoginUsingSessionMessage.py
│ │ ├── ClientHelloMessage.py
│ │ └── LoginMessage.py
│ │ ├── Billing
│ │ ├── BillingCancelledByClientMessage.py
│ │ ├── KunlunBillingRequestMessage.py
│ │ ├── TencentBillingRequestMessage.py
│ │ ├── AppleBillingRequestMessage.py
│ │ ├── GoogleBillingRequestMessage.py
│ │ └── CafeBazaarBillingRequestMessage.py
│ │ ├── Alliance
│ │ ├── ReportAllianceStreamMessage.py
│ │ └── AskForAllianceDataMessage.py
│ │ └── Battle
│ │ ├── GoHomeMessage.py
│ │ ├── CancelMatchMakingMessage.py
│ │ ├── GoHomeFromOfflinePractiseMessage.py
│ │ ├── MatchmakeRequestMessage.py
│ │ └── AskForBattleEndMessage.py
└── LogicLaserFactory.py
├── README.md
├── Utility
├── Utils.py
└── ByteStream.py
└── main.py
/Files/EventAssets/pop_up_1920x1235_welcome.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IsaaSooBarr/Project-LaserScratch/HEAD/Files/EventAssets/pop_up_1920x1235_welcome.png
--------------------------------------------------------------------------------
/Logic/Classes/LogicDataTables.py:
--------------------------------------------------------------------------------
1 | from Logic.Helpers.GlobalID import GlobalID
2 |
3 |
4 | class LogicDataTables:
5 | def getDataById(self, globalId):
6 | GlobalID.getClassID(globalId)
--------------------------------------------------------------------------------
/Logic/Player.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Players:
4 | ClientDict = {}
5 | Major = 0
6 | Minor = 0
7 | Revision = 0
8 | BattleTick = 0
9 |
10 |
11 | def __init__(self, device):
12 | self.device = device
13 |
--------------------------------------------------------------------------------
/Logic/Device.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | class Device:
4 | AndroidID = None
5 | DeviveModel = None
6 | OpenUDID = None
7 | OSVersion = None
8 | isAndroid = False
9 | Language = None
10 |
11 |
12 | def __init__(self, socket):
13 | self.socket = socket
14 |
15 |
16 | def SendData(self, data):
17 | self.socket.send(data)
--------------------------------------------------------------------------------
/Logic/Entry/CooldownEntry.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class CooldownEntry(Writer):
5 | def encode(self):
6 | self.writeVInt(0) # Count
7 | for x in range(0):
8 | self.writeVInt(0)
9 | self.writeDataReference(0, 0)
10 | self.writeVInt(0)
--------------------------------------------------------------------------------
/Logic/Entry/AdStatus.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class AdStatus(Writer):
5 | def encode(self):
6 | self.writeVInt(0) # Count
7 | for x in range(0):
8 | self.writeVInt(0)
9 | self.writeVInt(0) # Used Daily Ads
10 | self.writeVInt(5) # Maximum Daily Ads
--------------------------------------------------------------------------------
/Logic/Entry/RelaseEntry.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class RelaseEntry(Writer):
5 | def encode(self):
6 | self.writeVInt(0) # Count
7 | for x in range(0):
8 | self.writeDataReference(16, 0) # Locked Item
9 | self.writeInt(0) # Locked Timer
10 | self.writeInt(-1)
--------------------------------------------------------------------------------
/Packets/Messages/Server/Home/KeepAliveOkMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class KeepAliveOkMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 20108
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | pass
14 |
--------------------------------------------------------------------------------
/Packets/Messages/Server/Battle/MatchMakingCancelledMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class MatchMakingCancelledMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 20406
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | pass
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Packets/Messages/Server/Home/PlayerJWTokenMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class PlayerJWTokenMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 23774
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | self.writeString("") # JSON Web Token
14 |
--------------------------------------------------------------------------------
/Packets/Messages/Client/Gameroom/TeamLeaveMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class TeamLeaveMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | pass
13 |
14 |
15 | def process(self):
16 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Home/UdpCheckConnectionMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class UdpCheckConnectionMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | pass
13 |
14 |
15 | def process(self):
16 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Server/Login/ServerHelloMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class ServerHelloMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 20100
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | self.writeInt(24)
14 | self.writeBytes(b'')
15 |
--------------------------------------------------------------------------------
/Packets/Messages/Client/Login/AuthenticationCheckMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class AuthenticationCheckMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | pass
13 |
14 |
15 | def process(self):
16 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Home/PlayerStatusMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class PlayerStatusMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.Status = self.readVInt()
13 |
14 |
15 | def process(self):
16 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Home/ClientCapabilitiesMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class ClientCapabilitiesMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.Ping = self.readVInt()
13 |
14 |
15 | def process(self):
16 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Login/ResetAccountMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class ResetAccountMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.AccountPreset = self.readInt()
13 |
14 |
15 | def process(self):
16 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Gameroom/TeamMemberStatusMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class TeamMemberStatusMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.Status = self.readVInt()
13 |
14 |
15 | def process(self):
16 | pass
17 |
18 |
--------------------------------------------------------------------------------
/Packets/Messages/Client/Billing/BillingCancelledByClientMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class BillingCancelledByClientMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.readInt()
13 |
14 |
15 | def process(self):
16 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Home/ReportUserMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class ReportUserMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.readInt()
13 | self.ReportedAvatarId = self.readLong()
14 |
15 |
16 | def process(self):
17 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Gameroom/TeamSetLocationMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class TeamSetLocationMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.LocationID = self.readDataReference()[1]
13 |
14 |
15 | def process(self):
16 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Server/Login/CryptoErrorMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class CryptoErrorMessage(Writer):
5 | def __init__(self, client, player, CryptoError):
6 | super().__init__(client)
7 | self.id = 29997
8 | self.client = client
9 | self.player = player
10 | self.CryptoError = CryptoError
11 |
12 |
13 | def encode(self):
14 | self.writeVInt(self.CryptoError) # Crypto Error
--------------------------------------------------------------------------------
/Packets/Messages/Client/Gameroom/TeamSetMemberReadyMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class TeamSetMemberReadyMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.readBoolean()
13 | self.readVInt()
14 |
15 |
16 | def process(self):
17 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Gameroom/TeamSetEventMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class TeamSetEventMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.EventSlot = self.readVInt()
13 | self.readVInt()
14 |
15 |
16 | def process(self):
17 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Alliance/ReportAllianceStreamMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class ReportAllianceStreamMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.Id = self.readLong()
13 | self.ReportedAvatarId = self.readLong()
14 |
15 |
16 | def process(self):
17 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Gameroom/TeamChangeMemberSettingsMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class TeamChangeMemberSettingsMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.readVInt()
13 | self.BrawlerID = self.readDataReference()[1]
14 |
15 |
16 | def process(self):
17 | pass
--------------------------------------------------------------------------------
/Logic/Entry/EventSlot.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class EventSlot(Writer):
5 | def encode(self):
6 | self.writeVInt(7) # Event Slots Count
7 | self.writeVInt(1) # Gem Grab
8 | self.writeVInt(2) # Showdown
9 | self.writeVInt(3) # Daily Events
10 | self.writeVInt(4) # Special Events
11 | self.writeVInt(5) # Duo Showdown
12 | self.writeVInt(6) # Special Events (Duo Showdown)
13 | self.writeVInt(7) # Ticketed Events
--------------------------------------------------------------------------------
/Packets/Messages/Client/Login/AccountSwitchedMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class AccountSwitchedMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.SwitchedToAccountId = self.readLong()
13 | self.readByte()
14 | self.readString()
15 |
16 |
17 | def process(self):
18 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Login/SetDeviceTokenMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class SetDeviceTokenMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | #self.DeviceToken = self.readBytes()
13 | #self.AntihackFlags = self.readInt()
14 | pass
15 |
16 |
17 | def process(self):
18 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Gameroom/TeamCreateMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class TeamCreateMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.EventSlot = self.readVInt()
13 | self.readVInt()
14 | self.readVInt()
15 | self.readBoolean()
16 |
17 |
18 | def process(self):
19 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Home/AnalyticEventMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class AnalyticEventMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.Type = self.readStringReference()
13 | self.Event = self.readString()
14 |
15 |
16 | def process(self):
17 | print("[INFO] " + self.Type + " " + self.Event)
--------------------------------------------------------------------------------
/Packets/Messages/Client/Home/KeepAliveMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Home.KeepAliveOkMessage import KeepAliveOkMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class KeepAliveMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | pass
14 |
15 |
16 | def process(self):
17 | KeepAliveOkMessage(self.client, self.player).send()
--------------------------------------------------------------------------------
/Packets/Messages/Server/Battle/UdpConnectionInfoMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class UdpConnectionInfoMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 24112
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | self.writeVInt(9339) # Server Port
14 | self.writeString("10.0.0.169") # Server Host
15 | self.writeBytes(b'')
16 | self.writeBytes(b'')
--------------------------------------------------------------------------------
/Packets/Messages/Client/Home/GetSeasonRewardsMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Home.SeasonRewardsMessage import SeasonRewardsMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class GetSeasonRewardsMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | pass
14 |
15 |
16 | def process(self):
17 | SeasonRewardsMessage(self.client, self.player).send()
--------------------------------------------------------------------------------
/Packets/Messages/Client/Home/AskPlayerJWTokenMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Home.PlayerJWTokenMessage import PlayerJWTokenMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class AskPlayerJWTokenMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | pass
14 |
15 |
16 | def process(self):
17 | PlayerJWTokenMessage(self.client, self.player).send()
--------------------------------------------------------------------------------
/Packets/Messages/Client/Battle/GoHomeMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Home.OwnHomeDataMessage import OwnHomeDataMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class GoHomeMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | self.ClearActiveBattle = self.readBoolean()
14 |
15 |
16 | def process(self):
17 | OwnHomeDataMessage(self.client, self.player).send()
--------------------------------------------------------------------------------
/Packets/Messages/Client/Battle/CancelMatchMakingMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Battle.MatchMakingCancelledMessage import MatchMakingCancelledMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class CancelMatchMakingMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | pass
14 |
15 |
16 | def process(self):
17 | MatchMakingCancelledMessage(self.client, self.player).send()
--------------------------------------------------------------------------------
/Packets/Messages/Client/Login/ClientCryptoErrorMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Login.CryptoErrorMessage import CryptoErrorMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class ClientCryptoErrorMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | self.CryptoError = self.readInt()
14 |
15 |
16 | def process(self):
17 | CryptoErrorMessage(self.client, self.player, self.CryptoError).send()
18 |
--------------------------------------------------------------------------------
/Packets/Messages/Client/Battle/GoHomeFromOfflinePractiseMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Home.OwnHomeDataMessage import OwnHomeDataMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class GoHomeFromOfflinePractiseMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | self.ClearActiveBattle = self.readBoolean()
14 |
15 |
16 | def process(self):
17 | OwnHomeDataMessage(self.client, self.player).send()
--------------------------------------------------------------------------------
/Packets/Messages/Server/Battle/VisionUpdateMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class VisionUpdateMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 24109
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | self.writeVInt(self.player.BattleTick) # Battle Tick
14 | self.writeVInt(int(self.player.BattleTick / 10))
15 | self.writeVInt(0)
16 | self.writeVInt(0) # Spectates
17 | self.writeBoolean(False) # Brawl TV Battle
--------------------------------------------------------------------------------
/Packets/Messages/Client/Login/CreateAccountMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class CreateAccountMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.DeviceId = self.readString()
13 | self.FacebookId = self.readString()
14 | self.GameCenterId = self.readString()
15 | self.TwitterId = self.readString()
16 | self.Email = self.readString()
17 |
18 |
19 | def process(self):
20 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Billing/KunlunBillingRequestMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class KunlunBillingRequestMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.TID = self.readStringReference()
13 | self.ProdId = self.readStringReference()
14 | self.PurchaseToken = self.readStringReference()
15 | self.Price = self.readStringReference()
16 |
17 |
18 | def process(self):
19 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Billing/TencentBillingRequestMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class TencentBillingRequestMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.OriginalJSON = self.readStringReference()
13 | self.Signature = self.readStringReference()
14 | self.ProdId = self.readStringReference()
15 | self.Price = self.readStringReference()
16 |
17 |
18 | def process(self):
19 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Billing/AppleBillingRequestMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class AppleBillingRequestMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.TID = self.readString()
13 | self.ProdId = self.readString()
14 | self.CurrencyCode = self.readString()
15 | self.Price = self.readString()
16 | #self.ReceiptDataLength = self.readBytes()
17 |
18 |
19 | def process(self):
20 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Server/Battle/MatchMakingStatusMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class MatchMakingStatusMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 20405
8 | self.player = player
9 |
10 |
11 | def encode(self):
12 | self.writeInt(60) # Matchmake Timer
13 | self.writeInt(1) # Current Players in Matchmake
14 | self.writeInt(1) # Maximum Players in Matchmake
15 | self.writeInt(1) # Play Again Accepted Players
16 | self.writeInt(0) # Play Again Maximum Players
17 | self.writeBoolean(True) # Matchmake Timer Enabled State
--------------------------------------------------------------------------------
/Packets/Messages/Client/Login/UnlockAccountMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class UnlockAccountMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.AccountID = self.readLong()
13 | self.PassToken = self.readString()
14 | self.UnlockCode = self.readString()
15 | self.SupercellIDToken = self.readString()
16 |
17 |
18 | def process(self):
19 | self.HighID = self.AccountID[0]
20 | self.LowID = self.AccountID[1]
--------------------------------------------------------------------------------
/Packets/Messages/Server/Home/OwnHomeDataMessage.py:
--------------------------------------------------------------------------------
1 | from Logic.Classes.LogicClientHome import LogicClientHome
2 | from Logic.Classes.LogicClientAvatar import LogicClientAvatar
3 | from Utility.ByteStream import Writer
4 | from Utility.Utils import Utils
5 |
6 |
7 | class OwnHomeDataMessage(Writer):
8 | def __init__(self, client, player):
9 | super().__init__(client)
10 | self.id = 24101
11 | self.client = client
12 | self.player = player
13 |
14 |
15 | def encode(self):
16 | LogicClientHome.encode(self)
17 | LogicClientAvatar.encode(self)
18 | self.writeVInt(Utils.getCurrentTimeInSecondsSinceEpoch(self)) # Current Time
19 |
--------------------------------------------------------------------------------
/Packets/Messages/Client/Home/GetPlayerProfileMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Home.PlayerProfileMessage import PlayerProfileMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class GetPlayerProfileMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | self.PlayerID = self.readLong()
14 |
15 |
16 | def process(self):
17 | self.HighID = self.PlayerID[0]
18 | self.LowID = self.PlayerID[1]
19 | PlayerProfileMessage(self.client, self.player, self.HighID, self.LowID).send()
20 |
--------------------------------------------------------------------------------
/Packets/Messages/Client/Billing/GoogleBillingRequestMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class GoogleBillingRequestMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.TID = self.readString()
13 | self.ProdId = self.readString()
14 | self.CurrencyCode = self.readString()
15 | self.Price = self.readString()
16 | self.PurchaseData = self.readString()
17 | self.Signature = self.readString()
18 |
19 |
20 | def process(self):
21 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Home/GetLeaderboardMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Home.LeaderboardMessage import LeaderboardMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class GetLeaderboardMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | self.isLocal = self.readBoolean()
14 | self.Type = self.readVInt()
15 | self.BralwerID = self.readDataReference()[1]
16 |
17 |
18 | def process(self):
19 | LeaderboardMessage(self.client, self.player, self.isLocal, self.Type, self.BralwerID).send()
--------------------------------------------------------------------------------
/Packets/Messages/Client/Billing/CafeBazaarBillingRequestMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class CafeBazaarBillingRequestMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.TID = self.readString()
13 | self.ProdId = self.readString()
14 | self.CurrencyCode = self.readString()
15 | self.Price = self.readString()
16 | self.PurchaseData = self.readString()
17 | self.Signature = self.readString()
18 |
19 |
20 | def process(self):
21 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Alliance/AskForAllianceDataMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Alliance.AllianceDataMessage import AllianceDataMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class AskForAllianceDataMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | self.AllianceID = self.readLong()
14 | self.readBoolean()
15 |
16 |
17 | def process(self):
18 | self.HighID = self.AllianceID[0]
19 | self.LowID = self.AllianceID[1]
20 | AllianceDataMessage(self.client, self.player, self.HighID, self.LowID).send()
--------------------------------------------------------------------------------
/Packets/Messages/Client/Login/LoginUsingSessionMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Reader
2 |
3 |
4 | class LoginUsingSessionMessage(Reader):
5 | def __init__(self, client, player, initial_bytes):
6 | super().__init__(initial_bytes)
7 | self.player = player
8 | self.client = client
9 |
10 |
11 | def decode(self):
12 | self.AccountIdHigherInt = self.readInt()
13 | self.AccountIdLowerInt = self.readInt()
14 | self.SessionKey = self.readString()
15 | self.FacebookAccessToken = self.readString()
16 | self.Source = self.readString()
17 | self.DeviceIdentifier = self.readString()
18 | self.DeviceToken = self.readString()
19 |
20 |
21 | def process(self):
22 | pass
--------------------------------------------------------------------------------
/Packets/Messages/Client/Battle/MatchmakeRequestMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Battle.MatchMakingStatusMessage import MatchMakingStatusMessage
2 | from Utility.ByteStream import Reader
3 | import time
4 |
5 |
6 | class MatchmakeRequestMessage(Reader):
7 | def __init__(self, client, player, initial_bytes):
8 | super().__init__(initial_bytes)
9 | self.player = player
10 | self.client = client
11 |
12 |
13 | def decode(self):
14 | self.readDataReference()[1] # Selected Brawler
15 | self.readVInt() # Event Index
16 | self.readVInt() # Event Index
17 | self.readVInt() # Highstakes Index
18 | self.readVInt()
19 |
20 |
21 | def process(self):
22 | MatchMakingStatusMessage(self.client, self.player).send()
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
Laser Scratch
2 |
3 | Brawl Stars open source server for v20!
4 |
5 |
6 | 
7 |
8 |
9 | ## Implemented Features
10 | - Battle End
11 | - Leaderboard
12 | - Player Profile
13 | - Lobby Info
14 | - Menu Notifications
15 | - Club Wars
16 |
17 |
18 | ## Important Notes
19 | - Python 3.7 is the minimum requirement to run the server.
20 | - This server was made ONLY for testing purposes. If you aren't a coder, don't try to use it.
21 | - Missing features should be added in future.
22 | - The server doesn't have his own client yet. A custom client will be available soon.
23 |
24 |
25 | ## Authors
26 | 👤 **Isadora**
27 | * Github: [@Isaa](https://github.com/IsaaSooBarr)
28 |
29 |
30 | Contributors:
31 | - PhoenixFire
32 | - Crazor
33 | - BreadDev
34 | - XshadowX
35 | - Peter
36 | - Peka
37 | - eesdf
38 |
--------------------------------------------------------------------------------
/Packets/Messages/Server/Alliance/MyAllianceMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class MyAllianceMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 24399
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | self.writeVInt(1)
14 | self.writeBoolean(True) # Joined In a Club
15 | self.writeDataReference(25, 1) # Club Role
16 | # Club Header Entry
17 | self.writeLong(0, 1) # Club ID
18 | self.writeString("Club") # Club Name
19 | self.writeDataReference(8, 0) # Club Badge
20 | self.writeVInt(1) # Club Type
21 | self.writeVInt(1) # Club Members
22 | self.writeVInt(0) # Club Trophies
23 | self.writeVInt(0) # Club Required Trophies
24 | self.writeDataReference(0, -1)
25 | self.writeString("BR") # Club Region
26 | self.writeVInt(1) # Club Online Members
27 | # Club Header Entry End
--------------------------------------------------------------------------------
/Packets/Messages/Server/Home/LobbyInfoMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 | from Utility.Utils import Utils
3 |
4 |
5 | class LobbyInfoMessage(Writer):
6 | def __init__(self, client, player, count):
7 | super().__init__(client)
8 | self.id = 23457
9 | self.client = client
10 | self.player = player
11 | self.count = count
12 |
13 |
14 | def encode(self):
15 | self.writeVInt(self.count) # Players Online
16 | self.writeString(f"Project LaserScratch (v1.1.1)\nVersion: {self.player.Major}.{self.player.Minor}.{self.player.Revision}\n{Utils.getLobbyInfoCurrentDate(self)}")
17 |
18 |
19 | # Lobby Info Entry Array
20 | self.writeVInt(0) # Events Count
21 | for x in range(0):
22 | self.writeVInt(0) # Event Index
23 | self.writeVInt(0) # Pvp Battle
24 | self.writeVInt(0) # Pvp Matchmake
25 | self.writeVInt(0) # Co-op Battle
26 | self.writeVInt(0) # Co-op Matchmake
27 | # Lobby Info Entry Array End
28 |
29 |
--------------------------------------------------------------------------------
/Logic/Classes/LogicOfferBundle.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 | from Utility.Utils import Utils
3 |
4 |
5 | class LogicOfferBundle(Writer):
6 | def encode(self):
7 | self.writeVInt(0) # Shop Offers Count
8 | for x in range(0):
9 | self.writeVInt(0) # Offer Items Count
10 | for x in range(0):
11 | self.writeVInt(0) # Offer Item ID
12 | self.writeVInt(0) # Offer Amount
13 | self.writeDataReference(16, 0) # Offer Character
14 | self.writeVInt(0) # Offer Item Extra Data
15 | self.writeVInt(0) # Offer Resource Type
16 | self.writeVInt(0) # Offer Cost
17 | self.writeVInt(0) # Offer Timer
18 | self.writeVInt(0) # Offer New Tag State
19 | self.writeVInt(0) # Offer Bundle Percentage Value
20 | self.writeBoolean(False) # Offer Purchased
21 | self.writeVInt(0)
22 | self.writeBoolean(False) # Daily Deals Offer
23 | self.writeVInt(0) # Offer Original Cost
24 | self.ChronosTextEntry(2, "") # Offer Text Entry
25 | self.writeBoolean(False)
--------------------------------------------------------------------------------
/Logic/Entry/IntValueEntry.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class IntValueEntryLogicDailyData(Writer):
5 | def encode(self):
6 | self.writeVInt(9) # Home Events Count
7 | self.writeLong(1, False) # Daily Created Club State
8 | self.writeLong(2, False) # Daily Changed Location State
9 | self.writeLong(3, 0) # Tokens Gained
10 | self.writeLong(4, 0) # Trophies Gained
11 | self.writeLong(5, 0) # Star Tokens Gained
12 | self.writeLong(6, False) # Demo Account State
13 | self.writeLong(7, False) # Do Not Disturb State
14 | self.writeLong(8, 0) # Star Points Gained
15 | self.writeLong(9, False) # Star Points Enabled State
16 |
17 |
18 | class IntValueEntryLogicConfData(Writer):
19 | def encode(self):
20 | self.writeVInt(6) # Home Events Count
21 | self.writeLong(1, 41000000) # Menu Theme
22 | self.writeLong(3, 3) # Level Required For Unlock Friendly Games
23 | self.writeLong(5, False) # Temporarily Disable Shop
24 | self.writeLong(6, False) # Temporarily Disable Brawl Boxes
25 | self.writeLong(14, False) # Double Token Weekend
26 | self.writeLong(15, True) # Disable Content Creator Boost
--------------------------------------------------------------------------------
/Packets/Messages/Client/Login/ClientHelloMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Login.ServerHelloMessage import ServerHelloMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class ClientHelloMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | self.Protocol = self.readInt()
14 | self.KeyVersion = self.readInt()
15 | self.Major = self.readInt()
16 | self.Minor = self.readInt()
17 | self.Build = self.readInt()
18 | self.ContentHash = self.readString()
19 | self.DeviceType = self.readInt()
20 | self.AppStore = self.readInt()
21 | print("Protocol:", self.Protocol)
22 | print("Key Version:", self.KeyVersion)
23 | print("Client Major:", self.Major)
24 | print("Client Minor:", self.Minor)
25 | print("Client Build:", self.Build)
26 | print("Content Hash:", self.ContentHash)
27 | print("Device Type:", self.DeviceType)
28 | print("App Store Type:", self.AppStore)
29 |
30 |
31 | def process(self):
32 | ServerHelloMessage(self.client, self.player).send()
--------------------------------------------------------------------------------
/Packets/Messages/Server/Alliance/AllianceWarMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class AllianceWarMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 24776
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | self.writeLong(0, 1) # Player ID
14 | self.writeVInt(1) # Your Club Faction
15 |
16 |
17 | # Club War Events Array
18 | self.writeVInt(1) # Count
19 | for x in range(1):
20 | self.writeVInt(0)
21 | self.writeVInt(0) # Event Column Index
22 | self.writeVInt(0) # Event Row Index
23 | self.writeVInt(1) # Club Faction
24 | self.writeDataReference(15, 0) # War Location ID
25 | self.writeVInt(1) # War Node State
26 | self.writeVInt(0) # War Node State Time Left
27 | self.writeVInt(9) # Faction Score
28 | self.writeArrayVInt([])
29 | # Club War Events Array End
30 |
31 |
32 | # Club War Factions Array
33 | self.writeVInt(1) # Count
34 | for x in range(1):
35 | self.writeVInt(1) # Club Faction
36 | self.writeVInt(1) # Faction Score
37 | # Club War Factions Array End
--------------------------------------------------------------------------------
/Packets/Messages/Server/Home/SeasonRewardsMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class SeasonRewardsMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 24123
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | StarPointsTrophiesStart = [550,600,650,700,750,800,850,900,950,1000,1050,1100,1150,1200,1250,1300,1350,1400]
14 | StarPointsTrophiesEnd = [599,649,699,749,799,849,899,949,999,1049,1099,1149,1199,1249,1299,1349,1399,-1]
15 | StarPointsSeasonRewardAmount = [70,120,160,200,220,240,260,280,300,320,340,360,380,400,420,440,460,480]
16 | StarPointsTrophiesInReset = [525,550,575,600,625,650,675,700,725,750,775,800,825,850,875,900,925,950]
17 | self.writeVInt(len(StarPointsTrophiesStart)) # Index Count
18 | for StarPointsIndex in range(len(StarPointsTrophiesStart)):
19 | self.writeVInt(StarPointsTrophiesStart[StarPointsIndex]) # Minimum Trophies Index For Season Reward
20 | self.writeVInt(StarPointsTrophiesEnd[StarPointsIndex]) # Maximum Trophies Index For Season Reward
21 | self.writeVInt(StarPointsSeasonRewardAmount[StarPointsIndex]) # Season Star Points Reward Amount
22 | self.writeVInt(StarPointsTrophiesInReset[StarPointsIndex]) # Trophies After Season End
--------------------------------------------------------------------------------
/Utility/Utils.py:
--------------------------------------------------------------------------------
1 | from datetime import datetime
2 | import string
3 | import random
4 | import time
5 | import numpy as np
6 |
7 |
8 | class Utils:
9 | connected_clients = {"ClientsCount": 0, "Clients": {}}
10 |
11 |
12 | def getLogicDataTable(self, GlobalID):
13 | return (GlobalID / 1000000 + (GlobalID >> 31)) - (GlobalID * 1125899907 >> 63)
14 |
15 |
16 | def getCurrentDate(self):
17 | result = time.localtime(int(time.time()))
18 | return (result.tm_year * 1000 + result.tm_yday)
19 |
20 |
21 | def getTimeForNextDay(self):
22 | result = time.localtime(int(time.time()))
23 | return (86400 - (result.tm_sec + (result.tm_min * 60) + (result.tm_hour * 3600)))
24 |
25 |
26 | def getCurrentTimeInSecondsSinceEpoch(self):
27 | result = int(time.time())
28 | return result
29 |
30 |
31 | def getLobbyInfoCurrentDate(self):
32 | result = datetime.utcnow().strftime("%a %b %d %H:%M:%S UTC %Y")
33 | return result
34 |
35 |
36 | def getAccountCreatedDate(self):
37 | result = int(time.time())
38 | return (result * 1000)
39 |
40 |
41 | def getServerTime(self):
42 | result = int(time.time() * 1000)
43 | return result
44 |
45 |
46 | def getBattleTime(self):
47 | result = int(time.time())
48 | return result
49 |
50 |
51 | def EventTimer(self):
52 | result = time.localtime(int(time.time()))
53 | return (86400 - (result.tm_sec + (result.tm_min * 60) + (result.tm_hour * 3600)))
54 |
--------------------------------------------------------------------------------
/Packets/Messages/Server/Alliance/AllianceDataMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class AllianceDataMessage(Writer):
5 | def __init__(self, client, player, HighID, LowID):
6 | super().__init__(client)
7 | self.id = 24301
8 | self.client = client
9 | self.player = player
10 | self.HighID = HighID
11 | self.LowID = LowID
12 |
13 |
14 | def encode(self):
15 | self.writeBoolean(False)
16 | # Club Full Entry
17 | # Club Header Entry
18 | self.writeLong(self.HighID, self.LowID) # Club ID
19 | self.writeString("Club") # Club Name
20 | self.writeDataReference(8, 0) # Club Badge
21 | self.writeVInt(1) # Club Type
22 | self.writeVInt(1) # Club Members
23 | self.writeVInt(0) # Club Trophies
24 | self.writeVInt(0) # Club Required Trophies
25 | self.writeDataReference(0, -1)
26 | self.writeString("BR") # Club Region
27 | self.writeVInt(1) # Club Online Members
28 | # Club Header Entry End
29 | self.writeString("Club Description") # Club Description
30 |
31 |
32 | # Club Members Array
33 | self.writeVInt(1) # Club Members Count
34 | for x in range(1):
35 | self.writeLong(0, 1) # Player ID
36 | self.writeVInt(1) # Player Club Role
37 | self.writeVInt(0) # Player Trophies
38 | self.writeVInt(8) # Player Status
39 | self.writeVInt(0) # Player Status Timer
40 | self.writeBoolean(False)
41 | # Player Display Data
42 | self.writeString("Brawler") # Player Name
43 | self.writeVInt(100)
44 | self.writeVInt(28000000) # Player Profile Icon
45 | self.writeVInt(43000000) # Player Name Color
46 | # Player Display Data End
47 | # Club Members Array End
48 | # Club Full Entry End
--------------------------------------------------------------------------------
/Packets/Messages/Server/Home/LeaderboardMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class LeaderboardMessage(Writer):
5 | def __init__(self, client, player, isLocal, Type, BralwerID):
6 | super().__init__(client)
7 | self.id = 24403
8 | self.client = client
9 | self.player = player
10 | self.isLocal = isLocal
11 | self.Type = Type
12 | self.BralwerID = BralwerID
13 |
14 |
15 | def encode(self):
16 | self.writeVInt(self.Type)
17 | self.writeDataReference(16, self.BralwerID)
18 | self.writeString("BR") if self.isLocal == True else self.writeString()
19 |
20 |
21 | # Leaderboard Entry Array
22 | self.writeVInt(1) # Leaderboard Entry Count
23 | for x in range(1):
24 | self.writeLogicLong(0, 1) # Target ID
25 | self.writeVInt(0)
26 | self.writeVInt(0) # Target Trophies
27 | # Leaderboard Player Entry
28 | self.writeBoolean(True) # Leaderboard Player Entry
29 | self.writeString("Club") # Club Name
30 | # Player Display Data
31 | self.writeString("Brawler") # Player Name
32 | self.writeVInt(100)
33 | self.writeVInt(28000000) # Player Profile Icon
34 | self.writeVInt(43000000) # Player Name Color
35 | # Player Display Data End
36 | # Leaderboard Player Entry End
37 | # Leaderboard Alliance Entry
38 | self.writeBoolean(True) # Leaderboard Alliance Entry
39 | self.writeString("Club") # Club Name
40 | self.writeVInt(1) # Club Members Count
41 | self.writeDataReference(8, 0) # Club Badge
42 | # Leaderboard Alliance Entry End
43 | # Leaderboard Entry Array End
44 |
45 |
46 | self.writeVInt(0)
47 | self.writeVInt(1) # Leaderboard Entry Count
48 | self.writeVInt(0)
49 | self.writeVInt(0) # Leaderboard Global Region
50 | self.writeString("BR") # Leaderboard Local Region
--------------------------------------------------------------------------------
/Packets/Messages/Server/Login/LoginOkMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class LoginOkMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 20104
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | self.writeLong(0, 1) # Account ID
14 | self.writeLong(0, 1) # Home ID
15 | self.writeString("") # Pass Token
16 | self.writeString() # Facebook ID
17 | self.writeString() # Gamecenter ID
18 | self.writeInt(self.player.Major) # Server Major Version
19 | self.writeInt(self.player.Revision) # Server Build Version
20 | self.writeInt(self.player.Minor) # Content Version
21 | self.writeString("dev") # Environment
22 | self.writeInt(0) # Session Count
23 | self.writeInt(0) # Play Time Seconds
24 | self.writeInt(0) # Days Since Started Playing
25 | self.writeString("103121310241222") # Facebook Application ID
26 | self.writeString("") # Server Time
27 | self.writeString("") # Account Created Date
28 | self.writeInt(0) # Startup Cooldown
29 | self.writeString() # Google Service ID
30 | self.writeString("BR") # Login Country
31 | self.writeString() # Kunlun ID
32 | self.writeInt(2) # Tier
33 | self.writeString("")
34 | self.writeInt(2) # Url Entry Array Count
35 | self.writeString("https://game-assets.brawlstarsgame.com")
36 | self.writeString("http://a678dbc1c015a893c9fd-4e8cc3b1ad3a3c940c504815caefa967.r87.cf2.rackcdn.com")
37 | self.writeInt(2) # Url Entry Array Count
38 | self.writeString("https://raw.githubusercontent.com/IsaaSooBarr/Project-LaserScratch/main/Files/EventAssets/") # Event Assets
39 | self.writeString("https://24b999e6da07674e22b0-8209975788a0f2469e68e84405ae4fcf.ssl.cf2.rackcdn.com/event-assets")
40 | self.writeVInt(0) # Seconds Until Account Deletion
41 | self.writeCompressedString(b'') # Supercell ID Token
42 | self.writeBoolean(True,False) # Double Boolean
43 | self.writeString("")
44 |
--------------------------------------------------------------------------------
/Packets/Messages/Server/Battle/StartLoadingMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class StartLoadingMessage(Writer):
5 | def __init__(self, client, player):
6 | super().__init__(client)
7 | self.id = 20559
8 | self.client = client
9 | self.player = player
10 |
11 |
12 | def encode(self):
13 | self.writeInt(1) # Game Mode Total Players
14 | self.writeInt(0)
15 | self.writeInt(0)
16 |
17 |
18 | # Logic Player Array
19 | self.writeInt(1) # Players Count
20 |
21 |
22 | self.writeLong(0, 1) # Player ID
23 | self.writeVInt(1) # Player Index
24 | self.writeVInt(0) # Player Team
25 | self.writeVInt(0)
26 | self.writeInt(1000000) # ???
27 | self.writeDataReference(16, 0) # Player Brawler
28 | self.writeDataReference(29, 0) # Player Skin
29 | # Logic Hero Upgrades Array
30 | self.writeBoolean(True) # Hero Upgrades
31 | self.writeVInt(0) # Brawler Power Level
32 | self.writeDataReference(23, -1) # Brawler Star Power
33 | # Logic Hero Upgrades Array End
34 | # Player Display Data
35 | self.writeString("Icaro") # Player Name
36 | self.writeVInt(100)
37 | self.writeVInt(28000000) # Player Profile Icon
38 | self.writeVInt(43000000) # Player Name Color
39 | # Player Display Data End
40 | # Logic Player Array End
41 |
42 |
43 | # Logic Vector Array
44 | self.writeInt(0) # Array
45 | for x in range(0):
46 | self.writeInt(0)
47 | self.writeInt(0)
48 | # Logic Vector Array End
49 |
50 |
51 | self.writeInt(0) # Count
52 |
53 |
54 | self.writeInt(1413965001) # Unknown
55 | self.writeVInt(1)
56 | self.writeVInt(1) # Map Blocks
57 | self.writeVInt(1) # Joystick Mode
58 | self.writeBoolean(True) # Battle Hints
59 | self.writeVInt(0)
60 | self.writeVInt(0)
61 | self.writeDataReference(15, 0) # Location ID
62 |
--------------------------------------------------------------------------------
/Logic/Classes/LogicClientAvatar.py:
--------------------------------------------------------------------------------
1 | from Logic.Classes.LogicDataSlot import LogicDataSlotHeroOrItemUnlocked
2 | from Logic.Classes.LogicDataSlot import LogicDataSlotHeroScore
3 | from Logic.Classes.LogicDataSlot import LogicDataSlotHeroHighestScore
4 | from Logic.Classes.LogicDataSlot import LogicDataSlotResourceCount
5 | from Logic.Classes.LogicDataSlot import LogicDataSlotHeroPower
6 | from Logic.Classes.LogicDataSlot import LogicDataSlotHeroLevel
7 | from Logic.Classes.LogicDataSlot import LogicDataSlotCardCount
8 | from Logic.Classes.LogicDataSlot import LogicDataSlotHeroSeenState
9 | from Utility.ByteStream import Writer
10 |
11 |
12 | class LogicClientAvatar(Writer):
13 | def encode(self):
14 | self.writeLogicLong(0, 1) # Account ID
15 | self.writeLogicLong(0, 0)
16 | self.writeLogicLong(0, 0)
17 | self.writeStringReference("Brawler") # Player Name
18 | self.writeBoolean(True) # Registered Name State
19 | self.writeInt(-1)
20 | self.writeVInt(8) # Commodity Count
21 |
22 |
23 | # Unlocked Brawlers and Resources Array
24 | LogicDataSlotHeroOrItemUnlocked.encode(self)
25 | # Unlocked Brawlers and Resources Array End
26 |
27 |
28 | # Brawlers Trophies Array
29 | LogicDataSlotHeroScore.encode(self)
30 | # Brawlers Trophies Array End
31 |
32 |
33 | # Brawlers Highest Trophies Array
34 | LogicDataSlotHeroHighestScore.encode(self)
35 | # Brawlers Highest Trophies Array End
36 |
37 |
38 | # Highest Resources Amount Array
39 | LogicDataSlotResourceCount.encode(self)
40 | # Highest Resources Amount Array End
41 |
42 |
43 | # Brawlers Power Points Array
44 | LogicDataSlotHeroPower.encode(self)
45 | # Brawlers Power Points Array End
46 |
47 |
48 | # Brawlers Power Level Array
49 | LogicDataSlotHeroLevel.encode(self)
50 | # Brawlers Power Level Array End
51 |
52 |
53 | # Brawlers Star Powers Array
54 | LogicDataSlotCardCount.encode(self)
55 | # Brawlers Star Powers Array End
56 |
57 |
58 | # Brawlers Seem State Array
59 | LogicDataSlotHeroSeenState.encode(self)
60 | # Brawlers Seem State Array End
61 |
62 |
63 | self.writeVInt(0) # Player Gems
64 | self.writeVInt(0) # Player Free Gems
65 | self.writeVInt(1) # Player Experience Level
66 | self.writeVInt(100)
67 | self.writeVInt(0) # Cumulative Purchased Gems
68 | self.writeVInt(0) # Battles Count
69 | self.writeVInt(0) # Win Count
70 | self.writeVInt(0) # Lose Count
71 | self.writeVInt(0) # Win/Loose Streak
72 | self.writeVInt(0) # Npc Win Count
73 | self.writeVInt(0) # Npc Lose Count
74 | self.writeVInt(2) # Tutorial State
--------------------------------------------------------------------------------
/Logic/Classes/LogicConfData.py:
--------------------------------------------------------------------------------
1 | from Logic.Entry.EventSlot import EventSlot
2 | from Logic.Entry.EventData import EventDataActiveEvent
3 | from Logic.Entry.EventData import EventDataUpcomingEvent
4 | from Logic.Entry.RelaseEntry import RelaseEntry
5 | from Logic.Entry.IntValueEntry import IntValueEntryLogicConfData
6 | from Utility.ByteStream import Writer
7 | from Utility.Utils import Utils
8 |
9 |
10 | class LogicConfData(Writer):
11 | def encode(self):
12 | self.writeVInt(Utils.getCurrentDate(self)) # Current Year and Day
13 | self.writeVInt(100) # Brawl Box Tokens
14 | self.writeVInt(10) # Shop Brawl Box Cost
15 | self.writeVInt(30) # Shop Big Box Cost
16 | self.writeVInt(3) # Shop Big Box Multipler
17 | self.writeVInt(80) # Shop Megabox Cost
18 | self.writeVInt(10) # Shop Megabox Multipler
19 | self.writeVInt(50) # Shop Token Doubler Cost
20 | self.writeVInt(1000) # Shop Token Doubler Amount
21 | self.writeVInt(550) # Minimum Brawler Trophies For Season Reset
22 | self.writeVInt(50) # Brawler Trophy Loss Percentage In Season Reset
23 | self.writeVInt(999900) # Token Limit Amount
24 | self.writeArrayVInt([0,30,80,170,350,0]) # Boxes With Guaranteed Brawlers Cost
25 |
26 |
27 | # Event Slots Array
28 | EventSlot.encode(self)
29 | # Event Slots Array End
30 |
31 |
32 | # Event Slots Data Array
33 | EventDataActiveEvent.encode(self)
34 | # Event Slots Data Array End
35 |
36 |
37 | # Upcoming Event Slots Data Array
38 | EventDataUpcomingEvent.encode(self)
39 | # Upcoming Event Slots Data Array End
40 |
41 |
42 | self.writeArrayVInt([20,35,75,140,290,480,800,1250]) # Brawler Coins Upgrade Cost
43 | self.writeArrayVInt([1,2,3,4,5,10,15,20]) # Highstakes Rewards
44 | self.writeArrayVInt([10,30,80]) # Event Tickets Cost
45 | self.writeArrayVInt([6,20,60]) # Event Tickets Amount
46 | self.writeArrayVInt([20,50,140,280]) # Coin Packs Cost
47 | self.writeArrayVInt([150,400,1200,2600]) # Coin Packs Amount
48 | self.writeVInt(0) # Coin Packs State
49 | self.writeVInt(200) # Maximun Battle Tokens
50 | self.writeVInt(20) # Tokens Gained In Refresh
51 | self.writeVInt(8640) # Tokens Refresh Timer
52 | self.writeVInt(10) # Big Box Star Tokens
53 | self.writeVInt(5)
54 | self.writeBoolean(False,False,False) # Unlocked Event Slots State
55 | self.writeVInt(50)
56 | self.writeVInt(604800)
57 | self.writeBoolean(True) # Shop Boxes Enabled State
58 |
59 |
60 | # Locked For Chronos Array
61 | RelaseEntry.encode(self)
62 | # Locked For Chronos Array End
63 |
64 |
65 | # Home Events Array
66 | IntValueEntryLogicConfData.encode(self)
67 | # Home Events Array End
--------------------------------------------------------------------------------
/Logic/Classes/LogicDataSlot.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class LogicDataSlotHeroOrItemUnlocked(Writer):
5 | def encode(self):
6 | self.writeVInt(1 + 7) # Items Count
7 | for x in range(1):
8 | self.writeDataReference(23, x) # Item ID
9 | self.writeVInt(1) # Item Data
10 | self.writeDataReference(5, 1) # Resource ID
11 | self.writeVInt(0) # Tokens Amount
12 | self.writeDataReference(5, 5) # Resource ID
13 | self.writeVInt(0) # Chips Amount
14 | self.writeDataReference(5, 6) # Resource ID
15 | self.writeVInt(0) # Elixir Amount
16 | self.writeDataReference(5, 7) # Resource ID
17 | self.writeVInt(0) # Upgrade Tokens Amount
18 | self.writeDataReference(5, 8) # Resource ID
19 | self.writeVInt(0) # Coins Amount
20 | self.writeDataReference(5, 9) # Resource ID
21 | self.writeVInt(0) # Star Tokens Amount
22 | self.writeDataReference(5, 10) # Resource ID
23 | self.writeVInt(0) # Star Points Amount
24 |
25 |
26 | class LogicDataSlotHeroScore(Writer):
27 | def encode(self):
28 | self.writeVInt(0) # Brawlers Count
29 | for x in range(0):
30 | self.writeDataReference(16, 0) # Brawler ID
31 | self.writeVInt(0) # Brawler Trophies
32 |
33 |
34 | class LogicDataSlotHeroHighestScore(Writer):
35 | def encode(self):
36 | self.writeVInt(0) # Brawlers Count
37 | for x in range(0):
38 | self.writeDataReference(16, 0) # Brawler ID
39 | self.writeVInt(0) # Brawler Highest Trophies
40 |
41 |
42 | class LogicDataSlotResourceCount(Writer):
43 | def encode(self):
44 | self.writeVInt(0) # Resources Count
45 | for x in range(0):
46 | self.writeDataReference(5, 0) # Resource ID
47 | self.writeVInt(0) # Resource Amount
48 |
49 |
50 | class LogicDataSlotHeroPower(Writer):
51 | def encode(self):
52 | self.writeVInt(0) # Brawlers Count
53 | for x in range(0):
54 | self.writeDataReference(16, 0) # Brawler ID
55 | self.writeVInt(0) # Brawler Power Points Amount
56 |
57 |
58 | class LogicDataSlotHeroLevel(Writer):
59 | def encode(self):
60 | self.writeVInt(0) # Brawlers Count
61 | for x in range(0):
62 | self.writeDataReference(16, 0) # Brawler ID
63 | self.writeVInt(0) # Brawler Power Level
64 |
65 |
66 | class LogicDataSlotCardCount(Writer):
67 | def encode(self):
68 | self.writeVInt(0) # Items Count
69 | for x in range(0):
70 | self.writeDataReference(23, 0) # Item ID
71 | self.writeVInt(0) # Item Data
72 |
73 |
74 | class LogicDataSlotHeroSeenState(Writer):
75 | def encode(self):
76 | self.writeVInt(0) # Brawlers Count
77 | for x in range(0):
78 | self.writeDataReference(16, 0) # Brawler ID
79 | self.writeVInt(0) # Brawler Seem State
--------------------------------------------------------------------------------
/Packets/Messages/Server/Home/PlayerProfileMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class PlayerProfileMessage(Writer):
5 | def __init__(self, client, player, HighID, LowID):
6 | super().__init__(client)
7 | self.id = 24113
8 | self.client = client
9 | self.player = player
10 | self.HighID = HighID
11 | self.LowID = LowID
12 |
13 |
14 | def encode(self):
15 | # Player Profile
16 | self.writeLogicLong(self.HighID, self.LowID) # Player ID
17 | self.writeDataReference(0, -1)
18 |
19 |
20 | # Hero Entry Array
21 | self.writeVInt(1) # Brawlers Count
22 | for x in range(1):
23 | self.writeDataReference(16, x) # Brawler ID
24 | self.writeDataReference(29, -1) # Skin ID
25 | self.writeVInt(0) # Brawler Trophies
26 | self.writeVInt(0) # Brawler Trophies for Rank
27 | self.writeVInt(1) # Brawler Power Level
28 | # Hero Entry Array End
29 |
30 |
31 | # Stats Entry Array
32 | self.writeVInt(11) # Stats Count
33 | self.writeVInt(1) # Stats Index
34 | self.writeVInt(0) # 3 vs 3 Victories
35 | self.writeVInt(2) # Stats Index
36 | self.writeVInt(0) # Player Experience Points
37 | self.writeVInt(3) # Stats Index
38 | self.writeVInt(0) # Player Trophies
39 | self.writeVInt(4) # Stats Index
40 | self.writeVInt(0) # Player Highest Trophies
41 | self.writeVInt(5) # Stats Index
42 | self.writeVInt(1) # Unlocked Brawlers
43 | self.writeVInt(6) # Stats Index
44 | self.writeVInt(0) # Unknown
45 | self.writeVInt(7) # Stats Index
46 | self.writeVInt(28000000) # Player Profile Icon
47 | self.writeVInt(8) # Stats Index
48 | self.writeVInt(0) # Solo Victories
49 | self.writeVInt(9) # Stats Index
50 | self.writeVInt(0) # Best Robo Rumble Time
51 | self.writeVInt(10) # Stats Index
52 | self.writeVInt(0) # Best Time As Big Brawler
53 | self.writeVInt(11) # Stats Index
54 | self.writeVInt(0) # Duo Victories
55 | # Stats Entry Array End
56 |
57 |
58 | # Player Display Data
59 | self.writeString("Brawler") # Player Name
60 | self.writeVInt(100)
61 | self.writeVInt(28000000) # Player Profile Icon
62 | self.writeVInt(43000000) # Player Name Color
63 | # Player Display Data End
64 | # Player Profile End
65 |
66 |
67 | # Club Header Entry Array
68 | self.writeBoolean(True) # Joined In a Club
69 | self.writeLong(0, 1) # Club ID
70 | self.writeString("Club") # Club Name
71 | self.writeDataReference(8, 0) # Club Badge
72 | self.writeVInt(1) # Club Type
73 | self.writeVInt(1) # Club Members
74 | self.writeVInt(0) # Club Trophies
75 | self.writeVInt(0) # Club Required Trophies
76 | self.writeDataReference(0, 0)
77 | self.writeString("BR") # Club Region
78 | self.writeVInt(1) # Club Online Members
79 | # Club Header Entry Array End
80 |
81 |
82 | self.writeDataReference(25, 1) # Club Role
--------------------------------------------------------------------------------
/Logic/Classes/LogicDailyData.py:
--------------------------------------------------------------------------------
1 | from Logic.Classes.LogicOfferBundle import LogicOfferBundle
2 | from Logic.Entry.AdStatus import AdStatus
3 | from Logic.Entry.IntValueEntry import IntValueEntryLogicDailyData
4 | from Logic.Entry.CooldownEntry import CooldownEntry
5 | from Utility.ByteStream import Writer
6 | from Utility.Utils import Utils
7 |
8 |
9 | class LogicDailyData(Writer):
10 | def encode(self):
11 | self.writeVInt(Utils.getCurrentDate(self)) # Current Year and Day
12 | self.writeVInt(Utils.getTimeForNextDay(self)) # Time Remaining For Next Day
13 | self.writeVInt(0) # Player Trophies
14 | self.writeVInt(0) # Player Highest Trophies
15 | self.writeVInt(0) # Player Daily Highest Trophies
16 | self.writeVInt(1) # Collected Trophy Road Reward
17 | self.writeVInt(0) # Player Experience Points
18 | self.writeDataReference(28, 0) # Player Profile Icon
19 | self.writeDataReference(43, 0) # Player Name Color
20 | self.writeArrayVInt([]) # Played Game Modes
21 |
22 |
23 | # Selected Skins Array
24 | SelectedSkins = []
25 | self.writeVInt(len(SelectedSkins)) # Skins Count
26 | for i in range(len(SelectedSkins)):
27 | self.writeDataReference(29, i) # Selected Skin
28 | # Selected Skins Array End
29 |
30 |
31 | # Unlocked Skins Array
32 | UnlockedSkins = []
33 | self.writeVInt(len(UnlockedSkins)) # Skins Count
34 | for i in range(len(UnlockedSkins)):
35 | self.writeDataReference(29, i) # Unlocked Skin
36 | # Unlocked Skins Array End
37 |
38 |
39 | self.writeVInt(0) # Leaderboard Region
40 | self.writeVInt(0) # Player Highest League Trophies
41 | self.writeVInt(0) # Tokens Used In Battles
42 | self.writeBoolean(False) # Token Limit Reached State
43 | self.writeVInt(1) # Control Mode
44 | self.writeBoolean(True) # Battle Hints
45 | self.writeVInt(0) # Tokens Remaining From Token Doubler
46 | self.writeVInt(0) # Season End Timer
47 | self.writeBoolean(False, False, False, True) # Shop Exclusive Offer and Token Doubler State
48 | self.writeVInt(0) # Token Doubler Seem State
49 | self.writeVInt(0) # Event Tickets Seem State
50 | self.writeVInt(0) # Coin Packs Seem State
51 | self.writeVInt(0) # Change Name Cost
52 | self.writeVInt(0) # Timer For the Next Name Change
53 |
54 |
55 | # Shop Offers Array
56 | LogicOfferBundle.encode(self)
57 | # Shop Offers Array End
58 |
59 |
60 | # Brawl Box Ad Status Array
61 | AdStatus.encode(self)
62 | # Brawl Box Ad Status Array End
63 |
64 |
65 | self.writeVInt(0) # Available Tokens From Battles
66 | self.writeVInt(0) # Timer For New Tokens
67 | self.writeArrayVInt([]) # Event Tickets Purchased Index
68 | self.writeVInt(0) # Player Event Tickets
69 | self.writeVInt(0)
70 | self.writeDataReference(16, 0) # Selected Brawler
71 | self.writeString("BR") # Player Location
72 | self.writeString() # Supported Content Creator
73 |
74 |
75 | # Home Events Array
76 | IntValueEntryLogicDailyData.encode(self)
77 | # Home Events Array End
78 |
79 |
80 | # Cooldown Entry Array
81 | CooldownEntry.encode(self)
82 | # Cooldown Entry Array End
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import socket
3 | import time
4 | import os
5 | from threading import *
6 | from Logic.Device import Device
7 | from Logic.Player import Players
8 | from Utility.Utils import Utils
9 | from Packets.LogicLaserFactory import AvailablePackets
10 | from Packets.Messages.Server.Home.LobbyInfoMessage import LobbyInfoMessage
11 |
12 |
13 | def _(*args):
14 | print('[INFO]', end=' ')
15 | for arg in args:
16 | print(arg, end=' ')
17 | print()
18 |
19 |
20 |
21 | class Server:
22 | Clients = {"ClientCounts": 0, "Clients": {}}
23 | ThreadCount = 0
24 |
25 |
26 | def __init__(self, ip: str, port: int):
27 | self.server = socket.socket()
28 | self.port = port
29 | self.ip = ip
30 |
31 |
32 | def start(self):
33 | self.server.bind((self.ip, self.port))
34 | _(f'Server started! Ip: {self.ip}, Port: {self.port}')
35 | while True:
36 | self.server.listen()
37 | client, address = self.server.accept()
38 | _(f'New connection! Ip: {address[0]}')
39 | ClientThread(client, address).start()
40 | Utils.connected_clients['ClientsCount'] += 1
41 |
42 |
43 | class ClientThread(Thread):
44 | def __init__(self, client, address):
45 | super().__init__()
46 | self.client = client
47 | self.address = address
48 | self.device = Device(self.client)
49 | self.player = Players(self.device)
50 |
51 |
52 | def recvall(self, length: int):
53 | data = b''
54 | while len(data) < length:
55 | s = self.client.recv(length)
56 | if not s:
57 | print("Receive Error!")
58 | break
59 | data += s
60 | return data
61 |
62 |
63 | def run(self):
64 | LastPacketRecived = time.time()
65 | try:
66 | while True:
67 | header = self.client.recv(7)
68 | if len(header) > 0:
69 | LastPacketRecived = time.time()
70 | PacketID = int.from_bytes(header[:2], 'big')
71 | PacketLenght = int.from_bytes(header[2:5], 'big')
72 | PacketData = self.recvall(PacketLenght)
73 | LobbyInfoMessage(self.client, self.player, Utils.connected_clients['ClientsCount']).send()
74 | if PacketID in AvailablePackets:
75 | PacketName = AvailablePackets[PacketID].__name__
76 | _(f'Packet {PacketID}: {PacketName} was received!')
77 | message = AvailablePackets[PacketID](self.client, self.player, PacketData)
78 | message.decode()
79 | message.process()
80 | if PacketID == 10101:
81 | Server.Clients["Clients"][str(self.player.low_id)] = {"SocketInfo": self.client}
82 | Server.Clients["ClientCounts"] = Server.ThreadCount
83 | self.player.ClientDict = Server.Clients
84 | else:
85 | _(f'Packet {PacketID} is not handled!')
86 | if time.time() - LastPacketRecived > 10:
87 | print(f"[INFO] Ip: {self.address[0]} disconnected!")
88 | self.client.close()
89 | break
90 | except ConnectionAbortedError:
91 | print(f"[INFO] Ip: {self.address[0]} disconnected!")
92 | self.client.close()
93 | except ConnectionResetError:
94 | print(f"[INFO] Ip: {self.address[0]} disconnected!")
95 | self.client.close()
96 | except TimeoutError:
97 | print(f"[INFO] Ip: {self.address[0]} disconnected!")
98 | self.client.close()
99 |
100 |
101 | if __name__ == '__main__':
102 | server = Server('0.0.0.0', 9339)
103 | server.start()
--------------------------------------------------------------------------------
/Packets/Messages/Client/Login/LoginMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Login.LoginOkMessage import LoginOkMessage
2 | from Packets.Messages.Server.Home.OwnHomeDataMessage import OwnHomeDataMessage
3 | from Packets.Messages.Server.Alliance.MyAllianceMessage import MyAllianceMessage
4 | from Packets.Messages.Server.Alliance.AllianceWarMessage import AllianceWarMessage
5 | from Utility.ByteStream import Reader
6 |
7 |
8 | class LoginMessage(Reader):
9 | def __init__(self, client, player, initial_bytes):
10 | super().__init__(initial_bytes)
11 | self.player = player
12 | self.client = client
13 |
14 |
15 | def decode(self):
16 | self.player.high_id = self.readInt()
17 | self.player.low_id = self.readInt()
18 | self.player.token = self.readString()
19 | self.player.Major = self.readInt()
20 | self.player.Revision = self.readInt()
21 | self.player.Minor = self.readInt()
22 | self.FingerprintSHA = self.readString()
23 | Unknown1 = self.readString()
24 | self.DeviceID = self.readString()
25 | Unknown2 = self.readString()
26 | self.Device = self.readString()
27 | self.PreferredLanguage = self.readDataReference()[1]
28 | self.PreferredDeviceLanguage = self.readString()
29 | self.DeviceUUID = self.readString()
30 | self.OSVersion = self.readString()
31 | self.isAndroid = self.readBoolean()
32 | Unknown3 = self.readStringReference()
33 | self.AndroidID = self.readStringReference()
34 | Unknown4 = self.readStringReference()
35 | self.isAdvertisingEnabled = self.readBoolean()
36 | Unknown5 = self.readString()
37 | Unknown6 = self.readInt()
38 | self.AppStore = self.readVInt()
39 | Unknown7 = self.readStringReference()
40 | Unknown8 = self.readStringReference()
41 | self.AppVersion = self.readStringReference()
42 | Unknown9 = self.readStringReference()
43 | Unknown10 = self.readStringReference()
44 | self.TencentPlatform = self.readVInt()
45 | Unknown11 = self.readStringReference()
46 | Unknown12 = self.readStringReference()
47 | Unknown13 = self.readStringReference()
48 | print("Account HighID:", self.player.high_id)
49 | print("Account LowID:", self.player.low_id)
50 | print("Pass Token:", self.player.token)
51 | print("Client Major:", self.player.Major)
52 | print("Client Content:", self.player.Revision)
53 | print("Client Build:", self.player.Minor)
54 | print("Resource SHA:", self.FingerprintSHA)
55 | print("Unknown:", Unknown1)
56 | print("Device ID:", self.DeviceID)
57 | print("Unknown:", Unknown2)
58 | print("Device Model:", self.Device)
59 | print("App Language:", self.PreferredLanguage)
60 | print("Device Language:", self.PreferredDeviceLanguage)
61 | print("Device UUID:", self.DeviceUUID)
62 | print("OS Version:", self.OSVersion)
63 | print("isAndroid:", self.isAndroid)
64 | print("Unknown:", Unknown3)
65 | print("Android ID:", self.AndroidID)
66 | print("Unknown:", Unknown4)
67 | print("Advertising Enabled:", self.isAdvertisingEnabled)
68 | print("Unknown:", Unknown5)
69 | print("Unknown:", Unknown6)
70 | print("App Store Type:", self.AppStore)
71 | print("Unknown:", Unknown7)
72 | print("Unknown:", Unknown8)
73 | print("App Version:", self.AppVersion)
74 | print("Unknown:", Unknown9)
75 | print("Unknown:", Unknown10)
76 | print("Tencent Platform:", self.TencentPlatform)
77 | print("Unknown:", Unknown11)
78 | print("Unknown:", Unknown12)
79 | print("Unknown:", Unknown13)
80 |
81 |
82 | def process(self):
83 | LoginOkMessage(self.client, self.player).send()
84 | OwnHomeDataMessage(self.client, self.player).send()
85 | MyAllianceMessage(self.client, self.player).send()
86 | AllianceWarMessage(self.client, self.player).send()
--------------------------------------------------------------------------------
/Packets/Messages/Server/Battle/BattleEndMessage.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 |
3 |
4 | class BattleEndMessage(Writer):
5 | def __init__(self, client, player, Type):
6 | super().__init__(client)
7 | self.id = 23456
8 | self.client = client
9 | self.player = player
10 | self.Type = Type
11 |
12 |
13 | def encode(self):
14 | self.writeVInt(self.Type) # Battle End Game Mode
15 | self.writeVInt(self.player.BattleResult) # Battle Result
16 | self.writeVInt(0) # Tokens Gained
17 | self.writeVInt(0) # Trophies Result
18 | self.writeVInt(0) # Doubled Tokens
19 | self.writeVInt(0) # Double Token Weekend
20 | self.writeVInt(0) # Token Doubler Remaining
21 | self.writeVInt(0) # Ticketed Events Extra Data
22 | self.writeBoolean(False,False,False,False,False,False) # Battle End Type
23 |
24 |
25 | # Player Entry Array
26 | self.writeVInt(self.player.BattlePlayers) # Battle Players
27 | self.writeBoolean(True,False,False) # Team And Star Player Type
28 | self.writeDataReference(16, self.player.BrawlerID) # Player Brawler
29 | self.writeDataReference(29, self.player.SkinID) # Player Skin
30 | self.writeVInt(0) # Brawler Trophies
31 | self.writeVInt(1) # Brawler Power Level
32 | self.writeBoolean(True) # IsPlayer Array
33 | self.writeLong(0, 1) # Player ID
34 | # Player Display Data
35 | self.writeString("Icaro") # Player Name
36 | self.writeVInt(100)
37 | self.writeVInt(28000000) # Player Profile Icon
38 | self.writeVInt(43000000) # Player Name Color
39 | # Player Display Data End
40 |
41 |
42 | BotName = [self.player.Bot1Name, self.player.Bot2Name, self.player.Bot3Name, self.player.Bot4Name, self.player.Bot5Name, self.player.Bot6Name, self.player.Bot7Name, self.player.Bot8Name, self.player.Bot9Name]
43 | BotTeam = [self.player.Bot1Team, self.player.Bot2Team, self.player.Bot3Team, self.player.Bot4Team, self.player.Bot5Team, self.player.Bot6Team, self.player.Bot7Team, self.player.Bot8Team, self.player.Bot9Team]
44 | BotBrawler = [self.player.Bot1Brawler, self.player.Bot2Brawler, self.player.Bot3Brawler, self.player.Bot4Brawler, self.player.Bot5Brawler, self.player.Bot6Brawler, self.player.Bot7Brawler, self.player.Bot8Brawler, self.player.Bot9Brawler]
45 | for PlayerIndex in range(self.player.BattlePlayers - 1):
46 | if self.player.PlayerTeam == 0:
47 | if BotTeam[PlayerIndex] == 0:
48 | self.writeBoolean(False,False,False) # Team And Star Player Type
49 | else:
50 | self.writeBoolean(False,True,False) # Team And Star Player Type
51 | else:
52 | if BotTeam[PlayerIndex] == 0:
53 | self.writeBoolean(False,True,False) # Team And Star Player Type
54 | else:
55 | self.writeBoolean(False,False,False) # Team And Star Player Type
56 | self.writeDataReference(16, BotBrawler[PlayerIndex]) # Player Brawler
57 | self.writeDataReference(29, -1) # Player Skin
58 | self.writeVInt(0) # Brawler Trophies
59 | self.writeVInt(1) # Brawler Power Level
60 | self.writeBoolean(False) # IsPlayer Array
61 | # Player Display Data
62 | self.writeString(BotName[PlayerIndex]) # Player Name
63 | self.writeVInt(100)
64 | self.writeVInt(28000000) # Player Profile Icon
65 | self.writeVInt(43000000) # Player Name Color
66 | # Player Display Data End
67 | # Player Entry Array End
68 |
69 |
70 | # Experience Entry Array
71 | self.writeVInt(2) # Count
72 | self.writeVInt(0) # Normal Experience ID
73 | self.writeVInt(0) # Normal Experience Gained
74 | self.writeVInt(8) # Star Player Experience ID
75 | self.writeVInt(0) # Star Player Experience Gained
76 | # Experience Entry Array End
77 |
78 |
79 | # Milestone Rewards Array
80 | self.writeVInt(0) # Milestones Count
81 | for x in range(0):
82 | self.writeDataReference(39, 0) # Milestones Index
83 | # Milestone Rewards Array End
84 |
85 |
86 | # Milestone Progress Array
87 | self.writeVInt(2) # Count
88 | self.writeVInt(1) # Milestone ID
89 | self.writeVInt(0) # Brawler Trophies
90 | self.writeVInt(0) # Brawler Highest Trophies
91 | self.writeVInt(5) # Milestone ID
92 | self.writeVInt(0) # Player Experience Points
93 | self.writeVInt(0) # Player Experience Points
94 | # Milestone Progress Array End
95 |
96 |
97 | self.writeDataReference(28, 0) # Player Profile Icon
98 |
99 |
100 | self.writeBoolean(False) # Play Again
--------------------------------------------------------------------------------
/Packets/LogicLaserFactory.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Client.Home.AskPlayerJWTokenMessage import AskPlayerJWTokenMessage
2 | from Packets.Messages.Client.Login.ClientCryptoErrorMessage import ClientCryptoErrorMessage
3 | from Packets.Messages.Client.Login.ClientHelloMessage import ClientHelloMessage
4 | from Packets.Messages.Client.Login.LoginMessage import LoginMessage
5 | from Packets.Messages.Client.Login.LoginUsingSessionMessage import LoginUsingSessionMessage
6 | from Packets.Messages.Client.Login.CreateAccountMessage import CreateAccountMessage
7 | from Packets.Messages.Client.Home.ClientCapabilitiesMessage import ClientCapabilitiesMessage
8 | from Packets.Messages.Client.Home.KeepAliveMessage import KeepAliveMessage
9 | from Packets.Messages.Client.Home.UdpCheckConnectionMessage import UdpCheckConnectionMessage
10 | from Packets.Messages.Client.Home.AnalyticEventMessage import AnalyticEventMessage
11 | from Packets.Messages.Client.Login.AuthenticationCheckMessage import AuthenticationCheckMessage
12 | from Packets.Messages.Client.Login.SetDeviceTokenMessage import SetDeviceTokenMessage
13 | from Packets.Messages.Client.Login.ResetAccountMessage import ResetAccountMessage
14 | from Packets.Messages.Client.Battle.GoHomeMessage import GoHomeMessage
15 | from Packets.Messages.Client.Home.ReportUserMessage import ReportUserMessage
16 | from Packets.Messages.Client.Login.AccountSwitchedMessage import AccountSwitchedMessage
17 | from Packets.Messages.Client.Alliance.ReportAllianceStreamMessage import ReportAllianceStreamMessage
18 | from Packets.Messages.Client.Login.UnlockAccountMessage import UnlockAccountMessage
19 | from Packets.Messages.Client.Billing.AppleBillingRequestMessage import AppleBillingRequestMessage
20 | from Packets.Messages.Client.Billing.GoogleBillingRequestMessage import GoogleBillingRequestMessage
21 | from Packets.Messages.Client.Billing.TencentBillingRequestMessage import TencentBillingRequestMessage
22 | from Packets.Messages.Client.Billing.CafeBazaarBillingRequestMessage import CafeBazaarBillingRequestMessage
23 | from Packets.Messages.Client.Billing.KunlunBillingRequestMessage import KunlunBillingRequestMessage
24 | from Packets.Messages.Client.Billing.BillingCancelledByClientMessage import BillingCancelledByClientMessage
25 | ### TODO ###
26 | from Packets.Messages.Client.Battle.MatchmakeRequestMessage import MatchmakeRequestMessage
27 | from Packets.Messages.Client.Battle.CancelMatchMakingMessage import CancelMatchMakingMessage
28 | from Packets.Messages.Client.Battle.GoHomeFromOfflinePractiseMessage import GoHomeFromOfflinePractiseMessage
29 | from Packets.Messages.Client.Battle.AskForBattleEndMessage import AskForBattleEndMessage
30 | from Packets.Messages.Client.Home.GetPlayerProfileMessage import GetPlayerProfileMessage
31 | from Packets.Messages.Client.Home.GetSeasonRewardsMessage import GetSeasonRewardsMessage
32 | from Packets.Messages.Client.Alliance.AskForAllianceDataMessage import AskForAllianceDataMessage
33 | from Packets.Messages.Client.Gameroom.TeamCreateMessage import TeamCreateMessage
34 | from Packets.Messages.Client.Gameroom.TeamLeaveMessage import TeamLeaveMessage
35 | from Packets.Messages.Client.Gameroom.TeamChangeMemberSettingsMessage import TeamChangeMemberSettingsMessage
36 | from Packets.Messages.Client.Gameroom.TeamSetMemberReadyMessage import TeamSetMemberReadyMessage
37 | from Packets.Messages.Client.Gameroom.TeamMemberStatusMessage import TeamMemberStatusMessage
38 | from Packets.Messages.Client.Gameroom.TeamSetEventMessage import TeamSetEventMessage
39 | from Packets.Messages.Client.Gameroom.TeamSetLocationMessage import TeamSetLocationMessage
40 | from Packets.Messages.Client.Home.PlayerStatusMessage import PlayerStatusMessage
41 | from Packets.Messages.Client.Home.GetLeaderboardMessage import GetLeaderboardMessage
42 |
43 |
44 | AvailablePackets = {
45 | 10055: AskPlayerJWTokenMessage,
46 | 10099: ClientCryptoErrorMessage,
47 | 10100: ClientHelloMessage,
48 | 10101: LoginMessage,
49 | 10102: LoginUsingSessionMessage,
50 | 10103: CreateAccountMessage,
51 | 10107: ClientCapabilitiesMessage,
52 | 10108: KeepAliveMessage,
53 | 10109: UdpCheckConnectionMessage,
54 | 10110: AnalyticEventMessage,
55 | 10112: AuthenticationCheckMessage,
56 | 10113: SetDeviceTokenMessage,
57 | 10116: ResetAccountMessage,
58 | 10117: ReportUserMessage,
59 | 10118: AccountSwitchedMessage,
60 | 10119: ReportAllianceStreamMessage,
61 | 10121: UnlockAccountMessage,
62 | 10150: AppleBillingRequestMessage,
63 | 10151: GoogleBillingRequestMessage,
64 | 10152: TencentBillingRequestMessage,
65 | 10153: CafeBazaarBillingRequestMessage,
66 | 10159: KunlunBillingRequestMessage,
67 | 10160: BillingCancelledByClientMessage,
68 | ### TODO ###
69 | 14101: GoHomeMessage,
70 | 14103: MatchmakeRequestMessage,
71 | 14106: CancelMatchMakingMessage,
72 | 14109: GoHomeFromOfflinePractiseMessage,
73 | 14110: AskForBattleEndMessage,
74 | 14113: GetPlayerProfileMessage,
75 | 14277: GetSeasonRewardsMessage,
76 | 14302: AskForAllianceDataMessage,
77 | 14350: TeamCreateMessage,
78 | 14353: TeamLeaveMessage,
79 | 14354: TeamChangeMemberSettingsMessage,
80 | 14355: TeamSetMemberReadyMessage,
81 | 14361: TeamMemberStatusMessage,
82 | 14362: TeamSetEventMessage,
83 | 14363: TeamSetLocationMessage,
84 | 14366: PlayerStatusMessage,
85 | 14403: GetLeaderboardMessage,
86 | }
87 |
--------------------------------------------------------------------------------
/Logic/Entry/EventData.py:
--------------------------------------------------------------------------------
1 | from Utility.ByteStream import Writer
2 | from Utility.Utils import Utils
3 |
4 |
5 | class EventSlots:
6 | EventsData = [
7 | {
8 | 'EventIndex': 1,
9 | 'NewEventReward': 10,
10 | 'LocationID': 7,
11 | 'MapStatus': 2,
12 | 'TextEntry': None,
13 | 'Modifiers': []
14 | },
15 |
16 |
17 |
18 | {
19 | 'EventIndex': 2,
20 | 'NewEventReward': 10,
21 | 'LocationID': 13,
22 | 'MapStatus': 2,
23 | 'TextEntry': None,
24 | 'Modifiers': []
25 | },
26 |
27 |
28 |
29 | {
30 | 'EventIndex': 3,
31 | 'NewEventReward': 10,
32 | 'LocationID': 24,
33 | 'MapStatus': 2,
34 | 'TextEntry': None,
35 | 'Modifiers': []
36 | },
37 |
38 |
39 |
40 | {
41 | 'EventIndex': 4,
42 | 'NewEventReward': 10,
43 | 'LocationID': 5,
44 | 'MapStatus': 2,
45 | 'TextEntry': None,
46 | 'Modifiers': []
47 | },
48 |
49 |
50 |
51 | {
52 | 'EventIndex': 5,
53 | 'NewEventReward': 0,
54 | 'LocationID': 34,
55 | 'MapStatus': 0,
56 | 'TextEntry': None,
57 | 'Modifiers': []
58 | },
59 |
60 |
61 |
62 |
63 | {
64 | 'EventIndex': 7,
65 | 'NewEventReward': 2,
66 | 'LocationID': 21,
67 | 'MapStatus': 2,
68 | 'TextEntry': "TID_WEEKEND_EVENT",
69 | 'Modifiers': []
70 | }
71 | ]
72 |
73 |
74 | ComingUpEventsData = [
75 | {
76 | 'EventIndex': 1,
77 | 'NewEventReward': 10,
78 | 'LocationID': 7,
79 | 'MapStatus': 2,
80 | 'TextEntry': None,
81 | 'Modifiers': []
82 | },
83 |
84 |
85 |
86 | {
87 | 'EventIndex': 2,
88 | 'NewEventReward': 10,
89 | 'LocationID': 13,
90 | 'MapStatus': 2,
91 | 'TextEntry': None,
92 | 'Modifiers': []
93 | },
94 |
95 |
96 |
97 | {
98 | 'EventIndex': 3,
99 | 'NewEventReward': 10,
100 | 'LocationID': 24,
101 | 'MapStatus': 2,
102 | 'TextEntry': None,
103 | 'Modifiers': []
104 | },
105 |
106 |
107 |
108 | {
109 | 'EventIndex': 4,
110 | 'NewEventReward': 10,
111 | 'LocationID': 5,
112 | 'MapStatus': 2,
113 | 'TextEntry': None,
114 | 'Modifiers': []
115 | },
116 |
117 |
118 |
119 | {
120 | 'EventIndex': 5,
121 | 'NewEventReward': 0,
122 | 'LocationID': 34,
123 | 'MapStatus': 0,
124 | 'TextEntry': None,
125 | 'Modifiers': []
126 | },
127 |
128 |
129 |
130 |
131 | {
132 | 'EventIndex': 7,
133 | 'NewEventReward': 2,
134 | 'LocationID': 21,
135 | 'MapStatus': 2,
136 | 'TextEntry': "TID_WEEKEND_EVENT",
137 | 'Modifiers': []
138 | }
139 | ]
140 |
141 |
142 | class EventDataActiveEvent(Writer):
143 | def encode(self):
144 | EventsCount = len(EventSlots.EventsData)
145 | self.writeVInt(EventsCount) # Event Slots Count
146 | for map in EventSlots.EventsData:
147 | self.writeVInt(0)
148 | self.writeVInt(map['EventIndex']) # Event ID
149 | self.writeVInt(0) # New Event Timer
150 | self.writeVInt(Utils.EventTimer(self)) # Event Timer
151 | self.writeVInt(map['NewEventReward']) # New Event Reward Amount
152 | self.writeDataReference(15, map['LocationID']) # Location ID
153 | self.writeVInt(map['MapStatus']) # Event Status
154 | self.writeString(map['TextEntry']) # Event Text Entry
155 | self.writeVInt(0) # Boxes Purchased
156 | self.writeArrayVInt(map['Modifiers']) # Event Mofifiers
157 | self.writeVInt(0) # Ticketed Events Difficulty
158 |
159 |
160 | class EventDataUpcomingEvent(Writer):
161 | def encode(self):
162 | EventsCount = len(EventSlots.ComingUpEventsData)
163 | self.writeVInt(EventsCount) # Event Slots Count
164 | for map in EventSlots.ComingUpEventsData:
165 | self.writeVInt(0)
166 | self.writeVInt(map['EventIndex']) # Event ID
167 | self.writeVInt(Utils.EventTimer(self)) # New Event Timer
168 | self.writeVInt(Utils.EventTimer(self)) # Event Timer
169 | self.writeVInt(map['NewEventReward']) # New Event Reward Amount
170 | self.writeDataReference(15, map['LocationID']) # Location ID
171 | self.writeVInt(map['MapStatus']) # Event Status
172 | self.writeString(map['TextEntry']) # Event Text Entry
173 | self.writeVInt(0) # Boxes Purchased
174 | self.writeArrayVInt(map['Modifiers']) # Event Mofifiers
175 | self.writeVInt(0) # Ticketed Events Difficulty
--------------------------------------------------------------------------------
/Packets/Messages/Client/Battle/AskForBattleEndMessage.py:
--------------------------------------------------------------------------------
1 | from Packets.Messages.Server.Battle.BattleEndMessage import BattleEndMessage
2 | from Utility.ByteStream import Reader
3 |
4 |
5 | class AskForBattleEndMessage(Reader):
6 | def __init__(self, client, player, initial_bytes):
7 | super().__init__(initial_bytes)
8 | self.player = player
9 | self.client = client
10 |
11 |
12 | def decode(self):
13 | self.player.BattleResult = self.readVInt()
14 | self.readVInt()
15 | self.player.Rank = self.readVInt()
16 | self.Map = self.readDataReference()[1] # Locations CsvID
17 | self.BattlePlayers = self.readVInt() # Battle End Players
18 |
19 |
20 | self.player.BrawlerID = self.readDataReference()[1]
21 | self.player.SkinID = self.readDataReference()[1]
22 | self.PlayerTeam = self.readVInt()
23 | self.IsPlayer = self.readBoolean()
24 | self.PlayerName = self.readString()
25 |
26 |
27 | self.Bot1Brawler = self.readDataReference()[1]
28 | self.Bot1Skin = self.readDataReference()[1]
29 | self.Bot1Team = self.readVInt()
30 | self.Bot1IsPlayer = self.readBoolean()
31 | self.Bot1Name = self.readString()
32 |
33 |
34 | self.Bot2Brawler = self.readDataReference()[1]
35 | self.Bot2Skin = self.readDataReference()[1]
36 | self.Bot2Team = self.readVInt()
37 | self.Bot2IsPlayer = self.readBoolean()
38 | self.Bot2Name = self.readString()
39 |
40 |
41 | self.Bot3Brawler = self.readDataReference()[1]
42 | self.Bot3Skin = self.readDataReference()[1]
43 | self.Bot3Team = self.readVInt()
44 | self.Bot3IsPlayer = self.readBoolean()
45 | self.Bot3Name = self.readString()
46 |
47 |
48 | self.Bot4Brawler = self.readDataReference()[1]
49 | self.Bot4Skin = self.readDataReference()[1]
50 | self.Bot4Team = self.readVInt()
51 | self.Bot4IsPlayer = self.readBoolean()
52 | self.Bot4Name = self.readString()
53 |
54 |
55 | self.Bot5Brawler = self.readDataReference()[1]
56 | self.Bot5Skin = self.readDataReference()[1]
57 | self.Bot5Team = self.readVInt()
58 | self.Bot5IsPlayer = self.readBoolean()
59 | self.Bot5Name = self.readString()
60 |
61 |
62 | self.Bot6Brawler = self.readDataReference()[1]
63 | self.Bot6Skin = self.readDataReference()[1]
64 | self.Bot6Team = self.readVInt()
65 | self.Bot6IsPlayer = self.readBoolean()
66 | self.Bot6Name = self.readString()
67 |
68 |
69 | self.Bot7Brawler = self.readDataReference()[1]
70 | self.Bot7Skin = self.readDataReference()[1]
71 | self.Bot7Team = self.readVInt()
72 | self.Bot7IsPlayer = self.readBoolean()
73 | self.Bot7Name = self.readString()
74 |
75 |
76 | self.Bot8Brawler = self.readDataReference()[1]
77 | self.Bot8Skin = self.readDataReference()[1]
78 | self.Bot8Team = self.readVInt()
79 | self.Bot8IsPlayer = self.readBoolean()
80 | self.Bot8Name = self.readString()
81 |
82 |
83 | self.Bot9Brawler = self.readDataReference()[1]
84 | self.Bot9Skin = self.readDataReference()[1]
85 | self.Bot9Team = self.readVInt()
86 | self.Bot9IsPlayer = self.readBoolean()
87 | self.Bot9Name = self.readString()
88 |
89 |
90 | def process(self):
91 | self.player.Bot1Name = self.Bot1Name
92 | self.player.Bot2Name = self.Bot2Name
93 | self.player.Bot3Name = self.Bot3Name
94 | self.player.Bot4Name = self.Bot4Name
95 | self.player.Bot5Name = self.Bot5Name
96 | self.player.Bot6Name = self.Bot6Name
97 | self.player.Bot7Name = self.Bot7Name
98 | self.player.Bot8Name = self.Bot8Name
99 | self.player.Bot9Name = self.Bot9Name
100 | self.player.Bot1Brawler = self.Bot1Brawler
101 | self.player.Bot2Brawler = self.Bot2Brawler
102 | self.player.Bot3Brawler = self.Bot3Brawler
103 | self.player.Bot4Brawler = self.Bot4Brawler
104 | self.player.Bot5Brawler = self.Bot5Brawler
105 | self.player.Bot6Brawler = self.Bot6Brawler
106 | self.player.Bot7Brawler = self.Bot7Brawler
107 | self.player.Bot8Brawler = self.Bot8Brawler
108 | self.player.Bot9Brawler = self.Bot9Brawler
109 | self.player.PlayerTeam = self.PlayerTeam
110 | self.player.Bot1Team = self.Bot1Team
111 | self.player.Bot2Team = self.Bot2Team
112 | self.player.Bot3Team = self.Bot3Team
113 | self.player.Bot4Team = self.Bot4Team
114 | self.player.Bot5Team = self.Bot5Team
115 | self.player.Bot6Team = self.Bot6Team
116 | self.player.Bot7Team = self.Bot7Team
117 | self.player.Bot8Team = self.Bot8Team
118 | self.player.Bot9Team = self.Bot9Team
119 | self.player.BattlePlayers = self.BattlePlayers
120 | if self.BattlePlayers == 10 and self.Bot1Team == 0:
121 | self.Type = 5
122 | elif self.BattlePlayers == 10:
123 | self.Type = 2
124 | elif self.BattlePlayers == 3 and self.Map in [27, 29, 39, 68]:
125 | self.Type = 3
126 | elif self.BattlePlayers == 3 and self.Map in [57, 67, 133, 269]:
127 | self.Type = 6
128 | elif self.BattlePlayers == 6 and self.Map in [21, 30, 65, 66, 119, 120]:
129 | self.Type = 4
130 | else:
131 | self.Type = 1
132 | BattleEndMessage(self.client, self.player, self.Type).send()
--------------------------------------------------------------------------------
/Utility/ByteStream.py:
--------------------------------------------------------------------------------
1 | from io import BufferedReader, BytesIO
2 | import zlib
3 |
4 |
5 | class Writer:
6 | def __init__(self, client, endian: str = 'big'):
7 | self.client = client
8 | self.endian = endian
9 | self.buffer = b''
10 |
11 |
12 | def writeInt(self, data: int, length: int = 4):
13 | if data > 0:
14 | self.buffer += data.to_bytes(length, 'big', signed=False)
15 | else:
16 | self.buffer += data.to_bytes(length, 'big', signed=True)
17 |
18 |
19 | def writeInt8(self, data):
20 | self.writeInt(data, 1)
21 |
22 |
23 | def writeInt16(self, data):
24 | self.writeInt(data, 2)
25 |
26 |
27 | def writeInt24(self, data):
28 | self.writeInt(data, 3)
29 |
30 |
31 | def writeIntLE(self, data, length=4):
32 | self.buffer += data.to_bytes(length, 'little')
33 |
34 |
35 | def writeLong(self, high, low):
36 | self.buffer += high.to_bytes(4, 'big') + low.to_bytes(4, 'big')
37 |
38 |
39 | def writeUInteger(self, data: int, length: int = 1):
40 | self.buffer += data.to_bytes(length, 'big', signed=False)
41 |
42 |
43 | def writeUInt8(self, integer: int):
44 | self.writeUInteger(integer)
45 |
46 |
47 | def writeVInt(self, data, rotate: bool = True):
48 | final = b''
49 | if data == 0:
50 | self.writeByte(0)
51 | elif data < 0:
52 | self.writeVInt((2147483648 * 2) + data)
53 | else:
54 | data = (data << 1) ^ (data >> 31)
55 | while data:
56 | b = data & 0x7f
57 |
58 | if data >= 0x80:
59 | b |= 0x80
60 | if rotate:
61 | rotate = False
62 | lsb = b & 0x1
63 | msb = (b & 0x80) >> 7
64 | b >>= 1
65 | b = b & ~0xC0
66 | b = b | (msb << 7) | (lsb << 6)
67 |
68 | final += b.to_bytes(1, 'big')
69 | data >>= 7
70 | self.buffer += final
71 |
72 |
73 | def writeArrayVInt(self, arraydata):
74 | self.writeVInt(len(arraydata))
75 | for i in arraydata:
76 | self.writeVInt(i)
77 |
78 |
79 | def writeLogicLong(self, high, low):
80 | self.writeVInt(high)
81 | self.writeVInt(low)
82 |
83 |
84 | def writeDataReference(self, ClassID, InstanceID=0):
85 | if ClassID >= 1 and InstanceID >= 0:
86 | self.writeVInt(ClassID)
87 | self.writeVInt(InstanceID)
88 | else:
89 | self.writeVInt(0)
90 |
91 |
92 | def writeBoolean(self, *args):
93 | boolean = 0
94 | i = 0
95 | for value in args:
96 | if value:
97 | boolean |= 1 << i
98 | i += 1
99 | self.writeByte(boolean)
100 |
101 |
102 | def writeString(self, string = None):
103 | if string is None:
104 | self.writeInt((2 ** 32) - 1)
105 | else:
106 | if type(string) == bytes:
107 | encoded = string
108 | else:
109 | encoded = string.encode('utf-8')
110 | self.writeInt(len(encoded))
111 | self.buffer += encoded
112 |
113 |
114 | def writeStringReference(self, string = None):
115 | if string is None:
116 | self.writeInt((2 ** 32) - 1)
117 | else:
118 | if type(string) == bytes:
119 | encoded = string
120 | else:
121 | encoded = string.encode('utf-8')
122 | self.writeInt(len(encoded))
123 | self.buffer += encoded
124 |
125 |
126 | def writeCompressedString(self, data: bytes):
127 | compressed = zlib.compress(data)
128 | self.writeInt(len(compressed) + 4)
129 | self.writeIntLE(len(data))
130 | self.buffer += compressed
131 |
132 |
133 | def writeByte(self, data):
134 | if data > 255:
135 | self.buffer += data.to_bytes(2, 'big', signed=False)
136 | elif data > 127:
137 | self.buffer += data.to_bytes(1, 'big', signed=False)
138 | else:
139 | self.buffer += data.to_bytes(1, 'big', signed=True)
140 |
141 |
142 | def writeHexa(self, data):
143 | if data:
144 | if data.startswith('0x'):
145 | data = data[2:]
146 | self.buffer += bytes.fromhex(''.join(data.split()).replace('-', ''))
147 |
148 |
149 | def size(self):
150 | return len(self.buffer)
151 |
152 |
153 | def getRaw(self):
154 | return self.buffer
155 |
156 |
157 | def writeBytes(self, data):
158 | self.buffer += data
159 |
160 |
161 | def ChronosTextEntry(self, TextType, TextEntry):
162 | self.writeInt(TextType)
163 | self.writeStringReference(TextEntry)
164 |
165 |
166 | def ChronosFileEntry(self, FilePath, FileSHA):
167 | self.writeStringReference(FilePath)
168 | self.writeStringReference(FileSHA)
169 |
170 |
171 | def send(self):
172 | self.encode()
173 | packet = self.buffer
174 | self.buffer = self.id.to_bytes(2, 'big', signed=True)
175 | self.writeInt24(len(packet))
176 | if hasattr(self, 'version'):
177 | self.writeInt16(self.version)
178 | else:
179 | self.writeInt16(0)
180 | self.buffer += packet + b'\xff\xff\x00\x00\x00\x00\x00'
181 | self.client.send(self.buffer)
182 | print(f'[INFO] Packet {self.id}: {self.__class__.__name__} was sent!')
183 |
184 |
185 | class Reader(BufferedReader):
186 | def __init__(self, header_bytes):
187 | super().__init__(BytesIO(header_bytes))
188 | self.bytes_of_packets = header_bytes
189 |
190 |
191 | def readInt(self):
192 | return int.from_bytes(self.read(4), "big")
193 |
194 |
195 | def readInt8(self):
196 | return int.from_bytes(self.read(1), "big")
197 |
198 |
199 | def readInt16(self):
200 | return int.from_bytes(self.read(2), "big")
201 |
202 |
203 | def readInt24(self):
204 | return int.from_bytes(self.read(3), "big")
205 |
206 |
207 | def readIntLE(self):
208 | return int.from_bytes(self.read(4), "little")
209 |
210 |
211 | def readLong(self):
212 | high = self.readInt()
213 | low = self.readInt()
214 | return high, low
215 |
216 |
217 | def readUInteger(self, length: int = 1, endian: str = 'big'):
218 | result = 0
219 | i = 0
220 | for x in range(length):
221 | byte = self.bytes_of_packets[i]
222 | bit_padding = x * 8
223 | if endian == 'big':
224 | bit_padding = (8 * (length - 1)) - bit_padding
225 | result |= byte << bit_padding
226 | i += 1
227 | return result
228 |
229 |
230 | def readUInt8(self):
231 | return self.readUInteger()
232 |
233 |
234 | def readVInt(self):
235 | n = self.readVarInt(True)
236 | return (n >> 1) ^ (-(n & 1))
237 |
238 |
239 | def readLogicLong(self):
240 | high = self.readVInt()
241 | low = self.readVInt()
242 | return high, low
243 |
244 |
245 | def readDataReference(self):
246 | ClassID = self.readVInt()
247 | if ClassID != 0:
248 | InstanceID = self.readVInt()
249 | else:
250 | InstanceID = -1
251 | return ClassID, InstanceID
252 |
253 |
254 | def readBoolean(self):
255 | result = bool.from_bytes(bytes=self.read(1), byteorder='big', signed=False)
256 | if result == True:
257 | return True
258 | else:
259 | return False
260 |
261 |
262 | def readString(self):
263 | lenght = self.readInt()
264 | if lenght == pow(2, 32) - 1:
265 | return b""
266 | else:
267 | try:
268 | decoded = self.read(lenght)
269 | except MemoryError:
270 | raise IndexError("String out of range.")
271 | else:
272 | return decoded.decode('utf-8')
273 |
274 |
275 | def readStringReference(self):
276 | return self.readString()
277 |
278 |
279 | def readCompressedString(self):
280 | self.readInt()
281 | data_length = self.readIntLE()
282 | compressed = self.readBytes(data_length)
283 | return zlib.decompress(compressed)
284 |
285 |
286 | def readByte(self):
287 | return int.from_bytes(self.read(1), "big")
288 |
289 |
290 | def readBytes(self, length):
291 | return self.read(length)
292 |
293 |
294 | def readShort(self, length=2):
295 | return int.from_bytes(self.read(length), "big")
296 |
297 |
298 | def readVarInt(self, rotate: bool = True):
299 | result = 0
300 | shift = 0
301 | while True:
302 | byte = self.readByte()
303 | if rotate and shift == 0:
304 | seventh = (byte & 0x40) >> 6
305 | msb = (byte & 0x80) >> 7
306 | n = byte << 1
307 | n = n & ~0x181
308 | byte = n | (msb << 7) | seventh
309 | result |= (byte & 0x7f) << shift
310 | shift += 7
311 | if not (byte & 0x80):
312 | break
313 | return result
314 |
315 |
316 | def peekInt(self, length=4):
317 | return int.from_bytes(self.peek(length)[:length], "big")
--------------------------------------------------------------------------------
/Logic/Classes/LogicClientHome.py:
--------------------------------------------------------------------------------
1 | from Logic.Classes.LogicDailyData import LogicDailyData
2 | from Logic.Classes.LogicConfData import LogicConfData
3 | from Utility.ByteStream import Writer
4 |
5 |
6 | class LogicClientHome(Writer):
7 | def encode(self):
8 | LogicDailyData.encode(self)
9 | LogicConfData.encode(self)
10 | self.writeLong(0, 1) # Home ID
11 |
12 |
13 | self.writeVInt(16) # Notification Factory
14 |
15 |
16 | # New Brawler Ranks Notification
17 | self.writeVInt(78) # Notification ID
18 | self.writeInt(0) # Notification Index
19 | self.writeBoolean(True) # Notification Read
20 | self.writeInt(0) # Notification Time Ago
21 | self.writeString() # Notification Message Entry
22 | self.writeVInt(400) # Star Points Gained
23 | self.writeVInt(50) # Tokens Gained
24 | # New Brawler Ranks Notification End
25 |
26 |
27 | # Season End Notification
28 | self.writeVInt(79) # Notification ID
29 | self.writeInt(1) # Notification Index
30 | self.writeBoolean(True) # Notification Read
31 | self.writeInt(0) # Notification Time Ago
32 | self.writeString() # Notification Message Entry
33 | self.writeVInt(28) # Brawlers Count
34 | for x in range(28):
35 | self.writeVInt(16000000 + x) # Brawler ID
36 | self.writeVInt(1400) # Brawler Trophies
37 | self.writeVInt(450) # Brawler Trophy Loss
38 | self.writeVInt(480) # Star Points Gained
39 | # Season End Notification End
40 |
41 |
42 | # Star Points Migration Notification
43 | self.writeVInt(80) # Notification ID
44 | self.writeInt(2) # Notification Index
45 | self.writeBoolean(True) # Notification Read
46 | self.writeInt(0) # Notification Time Ago
47 | self.writeString() # Notification Message Entry
48 | self.writeVInt(8000) # Star Points Gained
49 | # Star Points Migration Notification End
50 |
51 |
52 | # Custom Support Message Notification
53 | self.writeVInt(81) # Notification ID
54 | self.writeInt(3) # Notification Index
55 | self.writeBoolean(True) # Notification Read
56 | self.writeInt(0) # Notification Time Ago
57 | self.writeString("Hacc") # Notification Message Entry
58 | self.writeVInt(0)
59 | # Custom Support Message Notification End
60 |
61 |
62 | # Club Mail Notification
63 | self.writeVInt(82) # Notification ID
64 | self.writeInt(4) # Notification Index
65 | self.writeBoolean(True) # Notification Read
66 | self.writeInt(0) # Notification Time Ago
67 | self.writeString("Hacc") # Message Entry
68 | # Player Display Data
69 | self.writeString("Brawler") # Player Name
70 | self.writeVInt(100)
71 | self.writeVInt(28000000) # Player Profile Icon
72 | self.writeVInt(43000000) # Player Name Color
73 | # Player Display Data End
74 | # Club Mail Notification End
75 |
76 |
77 | # Promo Popup Notification
78 | self.writeVInt(83) # Notification ID
79 | self.writeInt(5) # Notification Index
80 | self.writeBoolean(False) # Notification Read
81 | self.writeInt(0) # Notification Time Ago
82 | self.writeString() # Notification Message Entry
83 | self.ChronosTextEntry(0, "Welcome to LaserScratch!") # Primary Text Entry
84 | self.ChronosTextEntry(0, "Check GitHub for more info and updates!") # Secondary Text Entry
85 | self.ChronosTextEntry(0, "View More") # Button Text Entry
86 | self.ChronosFileEntry("pop_up_1920x1235_welcome.png", "6bb3b752a80107a14671c7bdebe0a1b662448d0c") # Notification Banner Data
87 | self.writeStringReference("brawlstars://extlink?page=https%3A%2F%2Fgithub.com%2FIcaro072%2FProject-LaserScratch") # Notification Event
88 | self.writeVInt(0)
89 | # Promo Popup Notification End
90 |
91 |
92 | # Star Power Donated Notification
93 | self.writeVInt(84) # Notification ID
94 | self.writeInt(6) # Notification Index
95 | self.writeBoolean(True) # Notification Read
96 | self.writeInt(0) # Notification Time Ago
97 | self.writeString() # Notification Message Entry
98 | self.writeVInt(0)
99 | self.writeVInt(23000000 + 76) # Star Power Donated
100 | # Star Power Donated Notification End
101 |
102 |
103 | # Gems Refunded Notification
104 | self.writeVInt(85) # Notification ID
105 | self.writeInt(7) # Notification Index
106 | self.writeBoolean(True) # Notification Read
107 | self.writeInt(0) # Notification Time Ago
108 | self.writeString() # Notification Message Entry
109 | self.writeVInt(0) # Revoke Type
110 | self.writeVInt(0) # Gems Revoked
111 | self.writeLong(0, 1) # Player ID
112 | self.writeVInt(0)
113 | self.writeString("") # Offer Purchased Timestamp
114 | # Gems Refunded Notification End
115 |
116 |
117 | # News Notification
118 | self.writeVInt(87) # Notification ID
119 | self.writeInt(8) # Notification Index
120 | self.writeBoolean(True) # Notification Read
121 | self.writeInt(0) # Notification Time Ago
122 | self.writeString() # Notification Message Entry
123 | self.writeStringReference()
124 | # News Notification End
125 |
126 |
127 | # Token Doubler Donated Notification
128 | self.writeVInt(88) # Notification ID
129 | self.writeInt(9) # Notification Index
130 | self.writeBoolean(True) # Notification Read
131 | self.writeInt(0) # Notification Time Ago
132 | self.writeString() # Notification Message Entry
133 | self.writeVInt(0)
134 | self.writeVInt(0) # Token Doublers Donated
135 | # Token Doubler Donated Notification End
136 |
137 |
138 | # Gems Donated Notification
139 | self.writeVInt(89) # Notification ID
140 | self.writeInt(10) # Notification Index
141 | self.writeBoolean(True) # Notification Read
142 | self.writeInt(0) # Notification Time Ago
143 | self.writeString() # Notification Message Entry
144 | self.writeVInt(0)
145 | self.writeVInt(0) # Gems Donated
146 | # Gems Donated Notification End
147 |
148 |
149 | # Resource Donated Notification
150 | self.writeVInt(90) # Notification ID
151 | self.writeInt(11) # Notification Index
152 | self.writeBoolean(True) # Notification Read
153 | self.writeInt(0) # Notification Time Ago
154 | self.writeString() # Notification Message Entry
155 | self.writeVInt(0)
156 | self.writeVInt(5000000 + 1) # Resource ID
157 | self.writeVInt(0) # Resource Donated
158 | # Resource Donated Notification End
159 |
160 |
161 | # Tickets Donated Notification
162 | self.writeVInt(91) # Notification ID
163 | self.writeInt(12) # Notification Index
164 | self.writeBoolean(True) # Notification Read
165 | self.writeInt(0) # Notification Time Ago
166 | self.writeString() # Notification Message Entry
167 | self.writeVInt(0)
168 | self.writeVInt(0) # Token Doublers Donated
169 | # Tickets Donated Notification End
170 |
171 |
172 | # Brawler Power Points Donated Notification
173 | self.writeVInt(92) # Notification ID
174 | self.writeInt(13) # Notification Index
175 | self.writeBoolean(True) # Notification Read
176 | self.writeInt(0) # Notification Time Ago
177 | self.writeString() # Notification Message Entry
178 | self.writeVInt(0)
179 | self.writeVInt(16000000 + 0) # Brawler ID
180 | self.writeVInt(0) # Power Points Donated
181 | # Brawler Power Points Donated Notification End
182 |
183 |
184 | # Brawler Donated Notification
185 | self.writeVInt(93) # Notification ID
186 | self.writeInt(14) # Notification Index
187 | self.writeBoolean(True) # Notification Read
188 | self.writeInt(0) # Notification Time Ago
189 | self.writeString() # Notification Message Entry
190 | self.writeVInt(0)
191 | self.writeVInt(16000000 + 0) # Brawler Donated
192 | # Brawler Donated Notification End
193 |
194 |
195 | # Skin Donated Notification
196 | self.writeVInt(94) # Notification ID
197 | self.writeInt(15) # Notification Index
198 | self.writeBoolean(True) # Notification Read
199 | self.writeInt(0) # Notification Time Ago
200 | self.writeString() # Notification Message Entry
201 | self.writeVInt(29000000 + 2) # Skin Donated
202 | # Skin Donated Notification End
203 |
204 |
205 | self.writeVInt(-1)
206 | self.writeBoolean(False)
207 |
208 |
209 | # Gatcha Drop Array
210 | self.writeVInt(0) # Count
211 | for x in range(0):
212 | self.writeVInt(0)
213 | self.writeDataReference(16, -1)
214 | self.writeVInt(0)
215 | self.writeDataReference(29, -1)
216 | self.writeDataReference(23, -1)
217 | self.writeVInt(0)
218 | # Gatcha Drop Array End
--------------------------------------------------------------------------------