├── requirements.txt ├── Patcher ├── Patch │ ├── Patchs │ │ ├── VERSION │ │ └── 6a1871422ccb1b2f029f15941324196d41aeb14e │ │ │ ├── csv_client │ │ │ └── credits.csv │ │ │ └── fingerprint.json │ └── Gamefiles │ │ ├── csv_client │ │ └── credits.csv │ │ └── fingerprint.json ├── how-to-use.txt ├── LZMA.py ├── Patch.py └── Lib │ └── ATPatchmaker.py ├── GameAssets ├── csv_logic │ ├── skinsrarity.csv │ ├── alliance_roles.csv │ ├── name_colors.csv │ ├── pins.csv │ ├── resources.csv │ ├── bosses.csv │ ├── themes.csv │ ├── alliance_badges.csv │ ├── challenges.csv │ ├── globals.csv │ ├── tiles.csv │ ├── player_thumbnails.csv │ ├── messages.csv │ ├── game_mode_variations.csv │ ├── items.csv │ ├── map_blocks.csv │ ├── regions.csv │ └── accessories.csv ├── fingerprint.json └── csv_client │ ├── health_bars.csv │ ├── links.csv │ ├── hints.csv │ ├── color_gradients.csv │ ├── credits.csv │ ├── local_notifications.csv │ ├── music.csv │ ├── tutorial.csv │ ├── shop_items.csv │ └── faces.csv ├── Protocol ├── Commands │ ├── Server │ │ ├── LogicChangeAvatarNameCommand.py │ │ ├── LogicSetSupportedCreatorCommand.py │ │ └── LogicGiveDeliveryItemsCommand.py │ └── Client │ │ ├── LogicPurchaseBrawlPassCommand.py │ │ ├── LogicSetPlayerNameColorCommand.py │ │ ├── LogicSetPlayerThumbnailCommand.py │ │ ├── LogicLevelUpCommand.py │ │ ├── LogicPurchaseDoubleCoinsCommand.py │ │ ├── LogicPurchaseHeroLvlUpMaterialCommand.py │ │ ├── LogicGatchaCommand.py │ │ ├── LogicSelectSkinCommand.py │ │ └── LogicPurchaseOfferCommand.py ├── Messages │ ├── Server │ │ ├── KeepAliveOkMessage.py │ │ ├── TeamLeftMessage.py │ │ ├── MatchMakingCancelledMessage.py │ │ ├── AvatarNameChangeFailedMessage.py │ │ ├── AllianceResponseMessage.py │ │ ├── SetSupportedCreatorResponseMessage.py │ │ ├── AvatarNameCheckResponseMessage.py │ │ ├── OwnHomeDataMessage.py │ │ ├── LobbyInfoMessage.py │ │ ├── JoinableAllianceListMessage.py │ │ ├── AllianceListMessage.py │ │ ├── AvailableServerCommandMessage.py │ │ ├── AllianceStreamMessage.py │ │ ├── LoginOkMessage.py │ │ ├── MyAllianceMessage.py │ │ ├── LoginFailedMessage.py │ │ ├── AllianceDataMessage.py │ │ ├── TeamMessage.py │ │ ├── BattleEndMessage.py │ │ ├── LeaderboardMessage.py │ │ └── PlayerProfileMessage.py │ └── Client │ │ ├── TeamLeaveMessage.py │ │ ├── KeepAliveMessage.py │ │ ├── GoHomeFromOfflinePractiseMessage.py │ │ ├── TeamToggleSettingsMessage.py │ │ ├── TeamSetLocationMessage.py │ │ ├── AvatarNameCheckRequestMessage.py │ │ ├── AskForAllianceDataMessage.py │ │ ├── GetPlayerProfileMessage.py │ │ ├── AskForJoinableAlliancesListMessage.py │ │ ├── SearchAlliancesMessage.py │ │ ├── TeamCreateMessage.py │ │ ├── StartGameMessage.py │ │ ├── GetLeaderboardMessage.py │ │ ├── SetSupportedCreatorMessage.py │ │ ├── EndClientTurnMessage.py │ │ ├── ChatToAllianceStreamMessage.py │ │ ├── SetNameMessage.py │ │ ├── LeaveAllianceMessage.py │ │ ├── AskForBattleEndMessage.py │ │ ├── TeamChangeMemberSettingsMessage.py │ │ ├── JoinAllianceMessage.py │ │ ├── ChangeAllianceSettingsMessage.py │ │ ├── CreateAllianceMessage.py │ │ └── LoginMessage.py ├── LogicCommandManager.py └── LogicLaserMessageFactory.py ├── Logic ├── Device.py ├── ClientHome.py ├── Avatar │ └── LogicPlayerStats.py ├── Home │ ├── LogicEventData.py │ ├── LogicConfData.py │ ├── LogicShopData.py │ └── LogicDailyData.py ├── ClientAvatar.py └── Player.py ├── Files ├── CsvLogic │ ├── Regions.py │ ├── Skins.py │ ├── Emotes.py │ ├── Characters.py │ └── Cards.py └── CsvReader.py ├── config.json ├── Main.py ├── Utils ├── Fingerprint.py └── Helpers.py ├── shop.json ├── events.json ├── Core └── Networking │ ├── Server.py │ └── ClientThread.py ├── DataBase ├── MongoUtils.py └── MongoDB.py ├── README.md └── ByteStream ├── Reader.py └── Writer.py /requirements.txt: -------------------------------------------------------------------------------- 1 | colorama 2 | pymongo 3 | dnspython -------------------------------------------------------------------------------- /Patcher/Patch/Patchs/VERSION: -------------------------------------------------------------------------------- 1 | 26.165.7 2 | e23f79220541f056889f8cb6517ee18019a74d9d -------------------------------------------------------------------------------- /GameAssets/csv_logic/skinsrarity.csv: -------------------------------------------------------------------------------- 1 | "Name","Price","Rarity" 2 | "String","int","int" 3 | "Common","30","1" 4 | "Rare","80","2" 5 | "Epic","150","3" 6 | "Legendary","300","4" 7 | -------------------------------------------------------------------------------- /GameAssets/fingerprint.json: -------------------------------------------------------------------------------- 1 | {"files": [{"file": "csv_client\/credits.csv", "sha": "0d09c99a8c35cd125fb8d6ab787a2024c4638c35"}], "sha": "6a1871422ccb1b2f029f15941324196d41aeb14e", "version": "26.165.7"} -------------------------------------------------------------------------------- /Patcher/Patch/Patchs/6a1871422ccb1b2f029f15941324196d41aeb14e/csv_client/credits.csv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhoenixFire6934/Modern-Brawl/HEAD/Patcher/Patch/Patchs/6a1871422ccb1b2f029f15941324196d41aeb14e/csv_client/credits.csv -------------------------------------------------------------------------------- /Patcher/Patch/Patchs/6a1871422ccb1b2f029f15941324196d41aeb14e/fingerprint.json: -------------------------------------------------------------------------------- 1 | {"files": [{"file": "csv_client\/credits.csv", "sha": "0d09c99a8c35cd125fb8d6ab787a2024c4638c35"}], "sha": "6a1871422ccb1b2f029f15941324196d41aeb14e", "version": "26.165.7"} -------------------------------------------------------------------------------- /Protocol/Commands/Server/LogicChangeAvatarNameCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class LogicChangeAvatarNameCommand(Writer): 4 | 5 | def encode(self): 6 | self.writeString(self.player.name) 7 | self.writeVInt(1) -------------------------------------------------------------------------------- /Protocol/Commands/Server/LogicSetSupportedCreatorCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class LogicSetSupportedCreatorCommand(Writer): 4 | 5 | def encode(self): 6 | self.writeVInt(1) 7 | self.writeString(self.player.content_creator) 8 | self.writeVInt(1) -------------------------------------------------------------------------------- /Logic/Device.py: -------------------------------------------------------------------------------- 1 | class Device: 2 | AndroidID = None 3 | DeviveModel = None 4 | OpenUDID = None 5 | OSVersion = None 6 | isAndroid = False 7 | Language = None 8 | 9 | def __init__(self, socket): 10 | self.socket = socket 11 | 12 | def SendData(self, data): 13 | self.socket.send(data) -------------------------------------------------------------------------------- /Protocol/Messages/Server/KeepAliveOkMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class KeepAliveOkMessage(Writer): 4 | 5 | def __init__(self, client, player): 6 | super().__init__(client) 7 | self.id = 20108 8 | self.player = player 9 | 10 | def encode(self): 11 | pass 12 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/TeamLeftMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class TeamLeftMessage(Writer): 4 | 5 | def __init__(self, client, player): 6 | super().__init__(client) 7 | self.id = 24125 8 | self.player = player 9 | 10 | def encode(self): 11 | self.writeInt(0) -------------------------------------------------------------------------------- /Patcher/how-to-use.txt: -------------------------------------------------------------------------------- 1 | 1. Put your files in Patch/Gamefiles folder + fingerprint.json 2 | 2. Run Patch.py 3 | 3. Copy the link from Patch.py. Example: "http://192.168.0.19:8080/" 4 | 4. Open server config.json and paste the link from Patch.py in "PatchUrl": "Your_Link", and set boolean "Patch" to true 5 | 5. Restart the server and have fun! 6 | -------------------------------------------------------------------------------- /Files/CsvLogic/Regions.py: -------------------------------------------------------------------------------- 1 | from Files.CsvReader import CsvReader 2 | 3 | class Regions: 4 | def get_region_string(self, region_id): 5 | reader = CsvReader() 6 | rowData = reader.readCsv('GameAssets/csv_logic/regions.csv') 7 | for row in rowData: 8 | if rowData.index(row) == region_id: 9 | return row[0] -------------------------------------------------------------------------------- /Protocol/Messages/Server/MatchMakingCancelledMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class MatchMakingCancelledMessage(Writer): 4 | 5 | def __init__(self, client, player): 6 | super().__init__(client) 7 | self.id = 20406 8 | self.player = player 9 | 10 | 11 | def encode(self): 12 | pass -------------------------------------------------------------------------------- /Protocol/Messages/Server/AvatarNameChangeFailedMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class AvatarNameChangeFailedMessage(Writer): 4 | 5 | def __init__(self, client, player): 6 | super().__init__(client) 7 | self.id = 20205 8 | self.player = player 9 | 10 | def encode(self): 11 | self.writeVInt(0) -------------------------------------------------------------------------------- /Files/CsvLogic/Skins.py: -------------------------------------------------------------------------------- 1 | from Files.CsvReader import CsvReader 2 | 3 | class Skins: 4 | def get_skins_id(self): 5 | SkinsID = [] 6 | reader = CsvReader() 7 | rowData = reader.readCsv('GameAssets/csv_logic/skins.csv') 8 | for row in rowData: 9 | SkinsID.append(rowData.index(row)) 10 | 11 | return SkinsID -------------------------------------------------------------------------------- /Protocol/Messages/Server/AllianceResponseMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class AllianceResponseMessage(Writer): 4 | 5 | def __init__(self, client, player, action): 6 | super().__init__(client) 7 | self.id = 24333 8 | self.player = player 9 | self.action = action 10 | 11 | def encode(self): 12 | self.writeVInt(self.action) -------------------------------------------------------------------------------- /GameAssets/csv_client/health_bars.csv: -------------------------------------------------------------------------------- 1 | "Name","FileName","PlayerExportNameTop","PlayerExportNameBot","EnemyExportNameTop","EnemyExportNameBot","YourTeamExportNameTop","YourTeamExportNameBot" 2 | "String","String","String","String","String","String","String","String" 3 | "Medium","sc/ui.sc","player_info_badge","player_info_badge_btm","enemy_info_badge","enemy_info_badge_btm","yourteam_info_badge","teammate_info_badge_btm" 4 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/SetSupportedCreatorResponseMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class SetSupportedCreatorResponseMessage(Writer): 4 | 5 | def __init__(self, client, player): 6 | super().__init__(client) 7 | self.id = 28686 8 | self.player = player 9 | 10 | def encode(self): 11 | self.writeVInt(1) 12 | self.writeString(self.player.content_creator) -------------------------------------------------------------------------------- /Files/CsvLogic/Emotes.py: -------------------------------------------------------------------------------- 1 | from Files.CsvReader import CsvReader 2 | 3 | 4 | class Emotes: 5 | def get_emotes_id(self): 6 | emotesID = [] 7 | reader = CsvReader() 8 | rowData = reader.readCsv('GameAssets/csv_logic/emotes.csv') 9 | for row in rowData: 10 | if row[1].lower() != 'true' and row[6].lower != 'true': 11 | emotesID.append(rowData.index(row)) 12 | 13 | return emotesID 14 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/AvatarNameCheckResponseMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class AvatarNameCheckResponseMessage(Writer): 4 | 5 | def __init__(self, client, player, username): 6 | super().__init__(client) 7 | self.id = 20300 8 | self.player = player 9 | self.username = username 10 | 11 | def encode(self): 12 | self.writeUInt8(0) 13 | self.writeInt(0) 14 | self.writeString(self.username) -------------------------------------------------------------------------------- /Protocol/Messages/Client/TeamLeaveMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.TeamLeftMessage import TeamLeftMessage 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 | def decode(self): 11 | pass 12 | 13 | def process(self, db): 14 | TeamLeftMessage(self.client, self.player).send() -------------------------------------------------------------------------------- /Protocol/Messages/Client/KeepAliveMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.KeepAliveOkMessage import KeepAliveOkMessage 3 | 4 | class KeepAliveMessage(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | 10 | def decode(self): 11 | pass 12 | 13 | def process(self, db): 14 | KeepAliveOkMessage(self.client, self.player).send() -------------------------------------------------------------------------------- /Logic/ClientHome.py: -------------------------------------------------------------------------------- 1 | from Logic.Home.LogicDailyData import LogicDailyData 2 | from Logic.Home.LogicConfData import LogicConfData 3 | 4 | class LogicClientHome: 5 | 6 | def encode(self): 7 | LogicDailyData.encode(self) 8 | LogicConfData.encode(self) 9 | 10 | self.writeLong(self.player.ID) 11 | 12 | self.writeVInt(0) # Unknown Array 13 | for x in range(0): 14 | pass 15 | 16 | self.writeVInt(0) # Unknown 17 | 18 | self.writeUInt8(0) # Unknown 19 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "MongoConnectionURL": "", 3 | 4 | "StarPoints": 5000, 5 | "Tickets": 7000, 6 | "Gold": 10000, 7 | "Gems": 100000, 8 | "Trophies": 0, 9 | "ExperiencePoints": 999999, 10 | "BrawlBoxTokens": 99999, 11 | "BigBoxTokens": 99999, 12 | "Region": "RO", 13 | "ThemeID": 0, 14 | "ContentCreatorCodes": ["modern brawl"], 15 | "BannedIPs": [], 16 | "Maintenance": false, 17 | "SecondsTillMaintenanceOver": 3600, 18 | "Patch": false, 19 | "PatchURL": "http://192.168.0.103:8080/", 20 | "UpdateURL": "" 21 | } -------------------------------------------------------------------------------- /Protocol/Messages/Client/GoHomeFromOfflinePractiseMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.OwnHomeDataMessage import OwnHomeDataMessage 3 | 4 | class GoHomeFromOfflinePractiseMessage(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | 10 | def decode(self): 11 | pass 12 | 13 | def process(self, db): 14 | OwnHomeDataMessage(self.client, self.player).send() -------------------------------------------------------------------------------- /Protocol/Messages/Client/TeamToggleSettingsMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.TeamMessage import TeamMessage 3 | 4 | class TeamToggleSettingsMessage(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | 10 | def decode(self): 11 | self.player.use_gadget = self.readBool() 12 | 13 | def process(self, db): 14 | TeamMessage(self.client, self.player).send() -------------------------------------------------------------------------------- /Protocol/Messages/Client/TeamSetLocationMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.TeamMessage import TeamMessage 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 | def decode(self): 11 | self.readVInt() 12 | self.player.map_id = self.readVInt() 13 | 14 | def process(self, db): 15 | TeamMessage(self.client, self.player).send() -------------------------------------------------------------------------------- /Files/CsvReader.py: -------------------------------------------------------------------------------- 1 | import csv 2 | 3 | class CsvReader: 4 | def readCsv(self, filename): 5 | self.rowData = [] 6 | self.lineCount = 0 7 | with open(filename) as csvFile: 8 | self.csvReader = csv.reader(csvFile, delimiter=',') 9 | for row in self.csvReader: 10 | if self.lineCount == 0 or self.lineCount == 1: 11 | self.lineCount += 1 12 | else: 13 | self.rowData.append(row) 14 | self.lineCount += 1 15 | return self.rowData 16 | -------------------------------------------------------------------------------- /Main.py: -------------------------------------------------------------------------------- 1 | from Core.Networking.Server import Server 2 | 3 | 4 | def main(): 5 | 6 | print(r""" 7 | ____ __ _____ __ 8 | / __ )_________ __ __/ / / ___// /_____ ___________ 9 | / __ / ___/ __ `/ | /| / / / \__ \/ __/ __ `/ ___/ ___/ 10 | / /_/ / / / /_/ /| |/ |/ / / ___/ / /_/ /_/ / / (__ ) 11 | /_____/_/ \__,_/ |__/|__/_/ /____/\__/\__,_/_/ /____/ 12 | 13 | """) 14 | 15 | Server("0.0.0.0", 9339).start() 16 | 17 | 18 | if __name__ == '__main__': 19 | main() 20 | -------------------------------------------------------------------------------- /Protocol/Commands/Client/LogicPurchaseBrawlPassCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | 3 | class LogicPurchaseBrawlPassCommand(Reader): 4 | def __init__(self, client, player, initial_bytes): 5 | super().__init__(initial_bytes) 6 | self.player = player 7 | self.client = client 8 | 9 | def decode(self): 10 | self.readVInt() 11 | self.readVInt() 12 | self.readLogicLong() 13 | 14 | def process(self, db): 15 | self.player.bp_activated = True 16 | db.update_player_account(self.player.token, 'BrawlPassActivated', self.player.bp_activated) -------------------------------------------------------------------------------- /Protocol/Messages/Client/AvatarNameCheckRequestMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.AvatarNameCheckResponseMessage import AvatarNameCheckResponseMessage 3 | 4 | class AvatarNameCheckRequestMessage(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | 10 | def decode(self): 11 | self.username = self.readString() 12 | 13 | def process(self, db): 14 | AvatarNameCheckResponseMessage(self.client, self.player, self.username).send() -------------------------------------------------------------------------------- /Protocol/Commands/Client/LogicSetPlayerNameColorCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | 3 | class LogicSetPlayerNameColorCommand(Reader): 4 | def __init__(self, client, player, initial_bytes): 5 | super().__init__(initial_bytes) 6 | self.player = player 7 | self.client = client 8 | 9 | def decode(self): 10 | self.readVInt() 11 | self.readVInt() 12 | self.readLogicLong() 13 | self.player.name_color = self.readDataReference()[1] 14 | 15 | def process(self, db): 16 | db.update_player_account(self.player.token, 'NameColor', self.player.name_color) -------------------------------------------------------------------------------- /Protocol/Messages/Client/AskForAllianceDataMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.AllianceDataMessage import AllianceDataMessage 3 | 4 | class AskForAllianceDataMessage(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | 10 | def decode(self): 11 | self.club_id = self.readLong() 12 | 13 | def process(self, db): 14 | club_data = db.load_club(self.club_id) 15 | 16 | AllianceDataMessage(self.client, self.player, club_data).send() -------------------------------------------------------------------------------- /Protocol/Commands/Client/LogicSetPlayerThumbnailCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | 3 | class LogicSetPlayerThumbnailCommand(Reader): 4 | def __init__(self, client, player, initial_bytes): 5 | super().__init__(initial_bytes) 6 | self.player = player 7 | self.client = client 8 | 9 | def decode(self): 10 | self.readVInt() 11 | self.readVInt() 12 | self.readLogicLong() 13 | self.player.profile_icon = self.readDataReference()[1] 14 | 15 | def process(self, db): 16 | db.update_player_account(self.player.token, 'ProfileIcon', self.player.profile_icon) -------------------------------------------------------------------------------- /Protocol/Messages/Server/OwnHomeDataMessage.py: -------------------------------------------------------------------------------- 1 | from Logic.ClientHome import LogicClientHome 2 | from Logic.ClientAvatar import LogicClientAvatar 3 | from ByteStream.Writer import Writer 4 | from datetime import datetime 5 | 6 | class OwnHomeDataMessage(Writer): 7 | 8 | def __init__(self, client, player): 9 | super().__init__(client) 10 | self.id = 24101 11 | self.player = player 12 | self.time_stamp = int(datetime.timestamp(datetime.now())) 13 | 14 | def encode(self): 15 | 16 | LogicClientHome.encode(self) 17 | LogicClientAvatar.encode(self) 18 | 19 | self.writeVInt(self.time_stamp) 20 | 21 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/alliance_roles.csv: -------------------------------------------------------------------------------- 1 | "Name","Level","TID","CanInvite","CanSendMail","CanChangeAllianceSettings","CanAcceptJoinRequest","CanKick","CanBePromotedToLeader","PromoteSkill" 2 | "String","int","String","Boolean","Boolean","Boolean","Boolean","Boolean","Boolean","int" 3 | "NonMember",0,,"false","false","false","false",,,0 4 | "Member",1,"TID_ALLIANCE_ROLE_MEMBER","false","false","false","false","false",,0 5 | "Leader",20,"TID_ALLIANCE_ROLE_LEADER","true","true","true","true","true","true",2 6 | "Elder",5,"TID_ALLIANCE_ROLE_ELDER","true","false","false","true","true",,0 7 | "Co-leader",10,"TID_ALLIANCE_ROLE_CO_LEADER","true","true","true","true","true","true",2 8 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/GetPlayerProfileMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.PlayerProfileMessage import PlayerProfileMessage 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 | def decode(self): 12 | self.account_id = self.readLong() 13 | 14 | def process(self, db): 15 | account_data = db.load_player_account_by_id(self.account_id) 16 | 17 | PlayerProfileMessage(self.client, self.player, account_data, db).send() -------------------------------------------------------------------------------- /GameAssets/csv_logic/name_colors.csv: -------------------------------------------------------------------------------- 1 | "Name","ColorCode","Gradient","RequiredExpLevel","RequiredTotalTrophies","RequiredSeasonPoints","RequiredHero","SortOrder","ColorGradient" 2 | "String","String","String","int","int","int","String","int","String" 3 | "default","0xffffffff","DefaultName",,,,,0 4 | 1,"0xff4ddba2","Name1",,,,,2 5 | 2,"0xffffce89","Name2",,,,,7 6 | 3,"0xfff9c908","Name3",,,,,6 7 | 4,"0xffff9727","Name4",,,,,3 8 | 5,"0xfff9775d","Name5",,,,,4 9 | 6,"0xfff05637","Name6",,,,,5 10 | 7,"0xffff8afb","Name7",,,,,10 11 | 8,"0xffa2e3fe","Name8",,,,,1 12 | 9,"0xff1ba5f5","Name9",,,,,9 13 | 10,"0xffcb5aff","Name10",,,,,11 14 | 11,"0xffa8e132","Name11",,,,,8 15 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/LobbyInfoMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class LobbyInfoMessage(Writer): 4 | 5 | def __init__(self, client, player, count): 6 | super().__init__(client) 7 | self.id = 23457 8 | self.player = player 9 | self.count = count 10 | 11 | def encode(self): 12 | self.writeVInt(self.count) 13 | self.writeString("Modern Brawl v2.0") 14 | 15 | self.writeVInt(0) # array 16 | for x in range(0): 17 | self.writeVInt(0) 18 | self.writeVInt(0) 19 | self.writeVInt(0) 20 | self.writeVInt(0) 21 | self.writeVInt(0) 22 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/AskForJoinableAlliancesListMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.JoinableAllianceListMessage import JoinableAllianceListMessage 3 | 4 | class AskForJoinableAlliancesListMessage(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | 10 | def decode(self): 11 | pass 12 | 13 | def process(self, db): 14 | clubs = db.load_all_clubs_sorted({}, 'Trophies') 15 | clubs.reverse() 16 | 17 | JoinableAllianceListMessage(self.client, self.player, clubs).send() 18 | -------------------------------------------------------------------------------- /Utils/Fingerprint.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | class Fingerprint: 4 | def loadFinger(path): 5 | try: 6 | finger_file = open(path, 'r') 7 | finger_content = json.loads(finger_file.read()) 8 | def_sha = finger_content['sha'] 9 | return def_sha 10 | except Exception as e: 11 | print(f"Could not load fingerprint: {e}") 12 | 13 | def loadFinger_full(path): 14 | try: 15 | finger_file = open(path, 'r') 16 | finger_content = json.loads(finger_file.read()) 17 | return json.dumps(finger_content) 18 | except Exception as e: 19 | print(f"Could not load fingerprint: {e}") -------------------------------------------------------------------------------- /GameAssets/csv_logic/pins.csv: -------------------------------------------------------------------------------- 1 | "Name","PinType","Rarity","Index","Bonus","CraftCost" 2 | "string","int","int","int","int","int" 3 | "pinHp0",1,0,0,1,20 4 | "pinHp1",1,0,1,1,20 5 | "pinHp2",1,0,2,1,20 6 | "pinAtt0",2,0,0,1,20 7 | "pinAtt1",2,0,1,1,20 8 | "pinAtt2",2,0,2,1,20 9 | "pinUlti0",3,0,0,1,20 10 | "pinUlti1",3,0,1,1,20 11 | "pinUlti2",3,0,2,1,20 12 | "badgeHp0",1,1,0,2,50 13 | "badgeHp1",1,1,1,2,50 14 | "badgeAtt0",2,1,0,2,50 15 | "bargeAtt1",2,1,1,2,50 16 | "badgeUlti0",3,1,0,2,50 17 | "badgeUlti1",3,1,1,2,50 18 | "medalHp",1,2,0,3,120 19 | "medalAtt",2,2,0,3,120 20 | "medalUlti",3,2,0,3,120 21 | "crest0",4,3,0,4,300 22 | "crest1",4,3,1,4,300 23 | "crest2",4,3,2,4,300 24 | "brawlstar",5,4,0,8,1000 25 | -------------------------------------------------------------------------------- /Patcher/Patch/Gamefiles/csv_client/credits.csv: -------------------------------------------------------------------------------- 1 | Name,0 2 | String,int 3 | PhoenixFire, 4 | , 5 | , 6 | , 7 | , 8 | , 9 | , 10 | , 11 | , 12 | , 13 | , 14 | , 15 | , 16 | , 17 | , 18 | , 19 | , 20 | , 21 | , 22 | , 23 | , 24 | , 25 | , 26 | , 27 | , 28 | , 29 | , 30 | , 31 | , 32 | , 33 | , 34 | , 35 | , 36 | , 37 | , 38 | , 39 | , 40 | , 41 | , 42 | , 43 | , 44 | , 45 | , 46 | , 47 | , 48 | , 49 | , 50 | , 51 | , 52 | , 53 | , 54 | , 55 | , 56 | , 57 | , 58 | , 59 | , 60 | , 61 | , 62 | , 63 | , 64 | , 65 | , 66 | , 67 | , 68 | , 69 | , 70 | , 71 | , 72 | , 73 | , 74 | , 75 | , 76 | , 77 | , 78 | , 79 | , 80 | , 81 | , 82 | , 83 | , 84 | , 85 | , 86 | , 87 | , 88 | , 89 | , 90 | , 91 | , 92 | , 93 | , 94 | , 95 | -------------------------------------------------------------------------------- /Protocol/Commands/Client/LogicLevelUpCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | 3 | class LogicLevelUpCommand(Reader): 4 | def __init__(self, client, player, initial_bytes): 5 | super().__init__(initial_bytes) 6 | self.player = player 7 | self.client = client 8 | 9 | def decode(self): 10 | self.readVInt() 11 | self.readVInt() 12 | self.readLogicLong() 13 | self.brawler = self.readDataReference()[1] 14 | 15 | def process(self, db): 16 | self.player.brawlers_level[str(self.brawler)] = self.player.brawlers_level[str(self.brawler)] + 1 17 | db.update_player_account(self.player.token, 'BrawlersLevel', self.player.brawlers_level) 18 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/SearchAlliancesMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.AllianceListMessage import AllianceListMessage 3 | 4 | class SearchAlliancesMessage(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | 10 | def decode(self): 11 | self.query = self.readString() 12 | 13 | def process(self, db): 14 | result = [] 15 | clubs = db.load_all_clubs({}) 16 | 17 | for club in clubs: 18 | if self.query.lower() in club['Name'].lower(): 19 | result.append(club) 20 | 21 | AllianceListMessage(self.client, self.player, self.query, result).send() 22 | 23 | 24 | -------------------------------------------------------------------------------- /GameAssets/csv_client/links.csv: -------------------------------------------------------------------------------- 1 | "Name","Language","URL" 2 | "string","string","string" 3 | "ShellyTutorial",, 4 | "ColtTutorial",, 5 | "BullTutorial",, 6 | "BrockTutorial",, 7 | "RicoTutorial",, 8 | "SpikeTutorial",, 9 | "BarleyTutorial",, 10 | "JessieTutorial",, 11 | "NitaTutorial",, 12 | "MikeTutorial",, 13 | "PrimpTutorial",, 14 | "MortisTutorial",, 15 | "CrowTutorial",, 16 | "PocoTutorial",, 17 | "BoTutorial",, 18 | "PiperTutorial",, 19 | "PamTutorial",, 20 | "TaraTutorial",, 21 | "DarrylTutorial",, 22 | "PennyTutorial",, 23 | "FrankTutorial",, 24 | "GeneTutorial",, 25 | "LeonTutorial",, 26 | "CoinRush","EN",, 27 | "AttackDefend",, 28 | "BossFight",, 29 | "BountyHunter",, 30 | "Artifact",, 31 | "LaserBall",, 32 | "BattleRoyale",, 33 | "BattleRoyaleTeam",, 34 | "Survival",, 35 | "Raid",, 36 | "RoboWars",, 37 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/TeamCreateMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.TeamMessage import TeamMessage 3 | from Logic.Home.LogicEventData import LogicEventData 4 | 5 | class TeamCreateMessage(Reader): 6 | def __init__(self, client, player, initial_bytes): 7 | super().__init__(initial_bytes) 8 | self.player = player 9 | self.client = client 10 | 11 | def decode(self): 12 | self.map_slot = self.readVInt() 13 | self.map_id = self.readVInt() 14 | self.room_type = self.readVInt() 15 | 16 | def process(self, db): 17 | if self.map_slot != -64: 18 | self.player.map_id = LogicEventData.events[self.map_slot - 1]['ID'] 19 | else: 20 | self.player.map_id = 7 21 | 22 | TeamMessage(self.client, self.player).send() -------------------------------------------------------------------------------- /Protocol/Commands/Client/LogicPurchaseDoubleCoinsCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Logic.Home.LogicShopData import LogicShopData 3 | 4 | class LogicPurchaseDoubleCoinsCommand(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | 10 | def decode(self): 11 | self.readVInt() 12 | self.readVInt() 13 | self.readLogicLong() 14 | 15 | def process(self, db): 16 | 17 | self.player.token_doubler = self.player.token_doubler + LogicShopData.token_doubler[0]['Amount'] 18 | db.update_player_account(self.player.token, 'TokenDoubler', self.player.token_doubler) 19 | 20 | self.player.gems = self.player.gems - LogicShopData.token_doubler[0]['Cost'] 21 | db.update_player_account(self.player.token, 'Gems', self.player.gems) -------------------------------------------------------------------------------- /Protocol/Messages/Client/StartGameMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.TeamMessage import TeamMessage 3 | from Protocol.Messages.Server.MatchMakingCancelledMessage import MatchMakingCancelledMessage 4 | from Logic.Home.LogicEventData import LogicEventData 5 | 6 | class StartGameMessage(Reader): 7 | def __init__(self, client, player, initial_bytes): 8 | super().__init__(initial_bytes) 9 | self.player = player 10 | self.client = client 11 | 12 | def decode(self): 13 | self.readVInt() 14 | self.readVInt() 15 | self.readVInt() 16 | self.map_slot = self.readVInt() 17 | 18 | 19 | def process(self, db): 20 | self.player.map_id = LogicEventData.events[self.map_slot - 1]['ID'] 21 | 22 | MatchMakingCancelledMessage(self.client, self.player).send() 23 | TeamMessage(self.client, self.player).send() -------------------------------------------------------------------------------- /Logic/Avatar/LogicPlayerStats.py: -------------------------------------------------------------------------------- 1 | class LogicPlayerStats: 2 | 3 | def getPlayerStats(self, accountData): 4 | 5 | playerStats = { 6 | 7 | '3v3Victories': 0, 8 | 'ExperiencePoints': accountData['ExperiencePoints'], 9 | 'Trophies': accountData['Trophies'], 10 | 'HighestTrophies': accountData['HighestTrophies'], 11 | 'UnlockedBrawlersCount': len(accountData['UnlockedBrawlers']), 12 | 'Unknown2': 0, 13 | 'ProfileIconID': 28000000 + accountData['ProfileIcon'], 14 | 'SoloVictories': 0, 15 | 'HighestRoboRumbleLvlPassed': 21, 16 | 'Unknown3': 0, 17 | 'DuoVictories': 0, 18 | 'HighestBossFightLvlPassed': 21, 19 | 'Unknown4': 0, 20 | 'PowerPlayRank': 1, 21 | 'MostChallengeWins': 0, 22 | 'HighestRampageLvlPassed': 21 23 | 24 | } 25 | 26 | return playerStats 27 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/resources.csv: -------------------------------------------------------------------------------- 1 | "Name","TID","IconSWF","CollectEffect","IconExportName","Type","Rarity","PremiumCurrency","TextRed","TextGreen","TextBlue","Cap" 2 | "String","String","String","String","String","String","String","Boolean","int","int","int","int" 3 | "Diamonds","TID_DIAMONDS","sc/ui.sc",,"genicon_gem",,,"TRUE",,255,92, 4 | "Gold","TID_TOKENS","sc/ui.sc","Collect Gold","genicon_coin",,,,192,,192, 5 | "owcAny",,"sc/ui.sc",,"icon_owcAny",,,,,,, 6 | "owcRareOrBetter",,"sc/ui.sc",,"icon_owcRareOrBetter",,,,,,, 7 | "owcEpicOrBetter",,"sc/ui.sc",,"icon_owcEpicOrBetter",,,,,,, 8 | "Dust",,"sc/ui.sc",,"genicon_dust",,,,,,, 9 | "Upgradium",,"sc/ui.sc",,"genicon_upgradium",,,,,,, 10 | "Bolts",,"sc/ui.sc",,"genicon_upgradium",,,,,,, 11 | "HeroLvlUpMaterial","TID_HERO_LVL_UP_MATERIAL","sc/ui.sc",,"genicon_upgradium",,,,,,, 12 | "FirstWins","TID_FIRST_WINS","sc/ui.sc",,"genicon_upgradium",,,,,,, 13 | "LegendaryTrophies","TID_LEGENDARY_TROPHIES","sc/ui.sc",,"genicon_upgradium",,,,,,, 14 | -------------------------------------------------------------------------------- /shop.json: -------------------------------------------------------------------------------- 1 | { 2 | "GoldPacks":[ 3 | { 4 | "Cost":20, 5 | "Amount":150 6 | }, 7 | { 8 | "Cost":50, 9 | "Amount":400 10 | }, 11 | { 12 | "Cost":140, 13 | "Amount":1200 14 | }, 15 | { 16 | "Cost":280, 17 | "Amount":2600 18 | } 19 | ], 20 | "Boxes":[ 21 | { 22 | "Cost":30, 23 | "Multiplier":3 24 | }, 25 | { 26 | "Cost":80, 27 | "Multiplier":10 28 | } 29 | ], 30 | "TokenDoubler":[ 31 | { 32 | "Cost":50, 33 | "Amount":1000 34 | } 35 | ], 36 | 37 | "Offers": [ 38 | { 39 | "OfferID": 6, 40 | "DataReference": [16,0], 41 | "ShopType": 0, 42 | "ShopDisplay": 0, 43 | "Cost": 15, 44 | "Timer": 3600, 45 | "Multiplier": 10, 46 | "OfferText": "SPECIAL OFFER", 47 | "Claimed": false 48 | } 49 | 50 | ] 51 | } 52 | -------------------------------------------------------------------------------- /Protocol/Commands/Client/LogicPurchaseHeroLvlUpMaterialCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Logic.Home.LogicShopData import LogicShopData 3 | 4 | class LogicPurchaseHeroLvlUpMaterialCommand(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | 10 | def decode(self): 11 | self.readVInt() 12 | self.readVInt() 13 | self.readLogicLong() 14 | self.gold_value = self.readVInt() 15 | 16 | 17 | def process(self, db): 18 | 19 | self.player.resources[1]['Amount'] = self.player.resources[1]['Amount'] + LogicShopData.gold_packs[self.gold_value]['Amount'] 20 | db.update_player_account(self.player.token, 'Resources', self.player.resources) 21 | 22 | self.player.gems = self.player.gems - LogicShopData.gold_packs[self.gold_value]['Cost'] 23 | db.update_player_account(self.player.token, 'Gems', self.player.gems) 24 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/JoinableAllianceListMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | from Files.CsvLogic.Regions import Regions 3 | 4 | class JoinableAllianceListMessage(Writer): 5 | 6 | def __init__(self, client, player, clubs): 7 | super().__init__(client) 8 | self.id = 24304 9 | self.player = player 10 | self.clubs = clubs 11 | 12 | def encode(self): 13 | self.writeVInt(len(self.clubs)) 14 | 15 | for club in self.clubs: 16 | self.writeLong(club['ID']) 17 | self.writeString(club['Name']) 18 | self.writeDataReference(8, club['BadgeID']) 19 | self.writeVInt(club['Type']) 20 | self.writeVInt(len(club['Members'])) 21 | self.writeVInt(club['Trophies']) 22 | self.writeVInt(club['RequiredTrophies']) 23 | self.writeDataReference(0, 0) 24 | self.writeString(Regions().get_region_string(club['Region'])) 25 | self.writeVInt(0) 26 | self.writeVInt(club['FamilyFriendly']) -------------------------------------------------------------------------------- /Protocol/Messages/Client/GetLeaderboardMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.LeaderboardMessage import LeaderboardMessage 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 | def decode(self): 12 | self.readBool() 13 | self.readVInt() 14 | self.type = self.readVInt() 15 | 16 | 17 | def process(self, db): 18 | if self.type == 1: 19 | self.player.leaderboard_type = 1 20 | players = db.load_all_players_sorted({}, 'Trophies') 21 | players.reverse() 22 | 23 | LeaderboardMessage(self.client, self.player, players).send() 24 | 25 | elif self.type == 2: 26 | self.player.leaderboard_type = 2 27 | clubs = db.load_all_clubs_sorted({}, 'Trophies') 28 | clubs.reverse() 29 | 30 | LeaderboardMessage(self.client, self.player, clubs).send() 31 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/SetSupportedCreatorMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.AvailableServerCommandMessage import AvailableServerCommandMessage 3 | from Protocol.Messages.Server.SetSupportedCreatorResponseMessage import SetSupportedCreatorResponseMessage 4 | 5 | class SetSupportedCreatorMessage(Reader): 6 | def __init__(self, client, player, initial_bytes): 7 | super().__init__(initial_bytes) 8 | self.player = player 9 | self.client = client 10 | 11 | def decode(self): 12 | self.player.content_creator = self.readString() 13 | 14 | def process(self, db): 15 | 16 | if self.player.content_creator.lower() in self.player.content_creator_codes or self.player.content_creator == '': 17 | db.update_player_account(self.player.token, 'SupportedContentCreator', self.player.content_creator) 18 | AvailableServerCommandMessage(self.client, self.player, 215).send() 19 | else: 20 | SetSupportedCreatorResponseMessage(self.client, self.player).send() 21 | 22 | 23 | -------------------------------------------------------------------------------- /events.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ID":7, 4 | "Status":3, 5 | "Ended":false, 6 | "Timer": 99999, 7 | "Modifier":0 8 | }, 9 | { 10 | "ID":32, 11 | "Status":3, 12 | "Ended":false, 13 | "Timer": 99999, 14 | "Modifier":0 15 | }, 16 | { 17 | "ID":17, 18 | "Status":3, 19 | "Ended":false, 20 | "Timer": 99999, 21 | "Modifier":0 22 | }, 23 | { 24 | "ID":0, 25 | "Status":3, 26 | "Ended":false, 27 | "Timer": 99999, 28 | "Modifier":0 29 | }, 30 | { 31 | "ID":38, 32 | "Status":3, 33 | "Ended":false, 34 | "Timer": 99999, 35 | "Modifier":0 36 | }, 37 | { 38 | "ID":24, 39 | "Status":3, 40 | "Ended":false, 41 | "Timer": 99999, 42 | "Modifier":0 43 | }, 44 | { 45 | "ID": 269, 46 | "Status":3, 47 | "Ended":false, 48 | "Timer": 99999, 49 | "Modifier":0 50 | }, 51 | { 52 | "ID":261, 53 | "Status":3, 54 | "Ended":false, 55 | "Timer": 99999, 56 | "Modifier":0 57 | } 58 | ] -------------------------------------------------------------------------------- /GameAssets/csv_logic/bosses.csv: -------------------------------------------------------------------------------- 1 | "Name","TID","PlayerCount","RequiredCampaignProgressToUnlock","Location","AllowedHeroes","Reward","LevelGenerationSeed","Map","Boss","BossLevel" 2 | "string","string","int","int","string","string","String","int","string","string","int" 3 | "boss1","TID_BOSS_1",3,6,"Planet1","Trooper,Techie,Vanguard,Sniper,PoisonDude,Healer","Diamonds:10:",,"Pvp4","Boss2",1 4 | "boss2","TID_BOSS_2",3,12,"Planet2","Trooper,Techie,Vanguard,Sniper,PoisonDude,Healer","Diamonds:10:",,"Pvp4","Boss1",5 5 | "boss3","TID_BOSS_3",3,18,"Planet3","Trooper,Techie,Vanguard,Sniper,PoisonDude,Healer","Diamonds:10:",,"Pvp4","Boss2",9 6 | "boss4","TID_BOSS_4",3,24,"Planet4","Trooper,Techie,Vanguard,Sniper,PoisonDude,Healer","Diamonds:10:",,"Pvp4","Boss1",12 7 | "boss5","TID_BOSS_5",3,30,"Planet5","Trooper,Techie,Vanguard,Sniper,PoisonDude,Healer","Diamonds:10:",,"Pvp4","Boss2",15 8 | "boss6","TID_BOSS_6",3,36,"Planet6","Trooper,Techie,Vanguard,Sniper,PoisonDude,Healer","Diamonds:10:",,"Pvp4","Boss1",18 9 | "boss7",,3,54,"Planet7","Trooper,Techie,Vanguard,Sniper,PoisonDude,Healer","Diamonds:10:",,"Pvp4","Boss2",20 10 | -------------------------------------------------------------------------------- /Patcher/LZMA.py: -------------------------------------------------------------------------------- 1 | import lzma 2 | from hashlib import md5 3 | 4 | 5 | 6 | def len_2_bytes(datalen, max_len=4): 7 | data = [] 8 | while datalen > 0: 9 | item = datalen % 256 10 | datalen = int(datalen / 256) 11 | data.append(item) 12 | while len(data) < max_len: 13 | data.append(0) 14 | return data 15 | 16 | 17 | def compress(data, max_len = 4): 18 | filters = [ 19 | { 20 | "id": lzma.FILTER_LZMA1, 21 | "dict_size": 256 * 1024, 22 | "lc": 3, 23 | "lp": 0, 24 | "pb": 2, 25 | "mode": lzma.MODE_NORMAL 26 | }, 27 | ] 28 | 29 | compressed_data = lzma.compress(data, format=lzma.FORMAT_ALONE, filters=filters) 30 | lzmadata = bytearray() 31 | 32 | for i in range(0, 5): 33 | lzmadata.append(compressed_data[i]) 34 | 35 | data_size = len_2_bytes(len(data), max_len) 36 | 37 | for size in data_size: 38 | lzmadata.append(size) 39 | for i in range(13, len(compressed_data)): 40 | lzmadata.append(compressed_data[i]) 41 | 42 | 43 | return lzmadata 44 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/AllianceListMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | from Files.CsvLogic.Regions import Regions 3 | 4 | class AllianceListMessage(Writer): 5 | 6 | def __init__(self, client, player, query, clubs): 7 | super().__init__(client) 8 | self.id = 24310 9 | self.player = player 10 | self.query = query 11 | self.clubs = clubs 12 | 13 | def encode(self): 14 | 15 | self.writeString(self.query) 16 | 17 | self.writeVInt(len(self.clubs)) 18 | 19 | for club in self.clubs: 20 | self.writeLong(club['ID']) 21 | self.writeString(club['Name']) 22 | self.writeDataReference(8, club['BadgeID']) 23 | self.writeVInt(club['Type']) 24 | self.writeVInt(len(club['Members'])) 25 | self.writeVInt(club['Trophies']) 26 | self.writeVInt(club['RequiredTrophies']) 27 | self.writeDataReference(0,0) 28 | self.writeString(Regions().get_region_string(club['Region'])) 29 | self.writeVInt(0) 30 | self.writeVInt(club['FamilyFriendly']) -------------------------------------------------------------------------------- /Protocol/Messages/Client/EndClientTurnMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Utils.Helpers import Helpers 3 | from Protocol.LogicCommandManager import commands 4 | 5 | class EndClientTurnMessage(Reader): 6 | def __init__(self, client, player, initial_bytes): 7 | super().__init__(initial_bytes) 8 | self.client = client 9 | self.player = player 10 | 11 | def decode(self): 12 | self.readVInt() 13 | self.readVInt() 14 | self.readVInt() 15 | self.tick = self.readVInt() 16 | if self.tick != 0: 17 | self.commandID = self.readVInt() 18 | 19 | 20 | def process(self, db): 21 | if self.tick != 0: 22 | if self.commandID in commands: 23 | command = commands[self.commandID] 24 | try: 25 | command.decode(self) 26 | command.process(self, db) 27 | except AttributeError: 28 | command(self.client, self.player).send() # Exception for OutOfSyncMessage 29 | else: 30 | print(f'{Helpers.cyan}[CLIENT] Unhandled Command! ID: {self.commandID}') -------------------------------------------------------------------------------- /Protocol/Messages/Server/AvailableServerCommandMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | from Utils.Helpers import Helpers 3 | from Protocol.Commands.Server.LogicChangeAvatarNameCommand import LogicChangeAvatarNameCommand 4 | from Protocol.Commands.Server.LogicSetSupportedCreatorCommand import LogicSetSupportedCreatorCommand 5 | from Protocol.Commands.Server.LogicGiveDeliveryItemsCommand import LogicGiveDeliveryItemsCommand 6 | 7 | class AvailableServerCommandMessage(Writer): 8 | 9 | def __init__(self, client, player, commandID): 10 | super().__init__(client) 11 | self.id = 24111 12 | self.player = player 13 | self.commandID = commandID 14 | 15 | def encode(self): 16 | 17 | commands = { 18 | 201: LogicChangeAvatarNameCommand, 19 | 203: LogicGiveDeliveryItemsCommand, 20 | 215: LogicSetSupportedCreatorCommand 21 | } 22 | 23 | if self.commandID in commands: 24 | 25 | self.writeVInt(self.commandID) 26 | commands[self.commandID].encode(self) 27 | else: 28 | print(f"{Helpers.yellow}[SERVER] Cannot create command! ID: {self.commandID}") -------------------------------------------------------------------------------- /Core/Networking/Server.py: -------------------------------------------------------------------------------- 1 | import json 2 | import socket 3 | from Utils.Helpers import Helpers 4 | from DataBase.MongoDB import MongoDB 5 | from Core.Networking.ClientThread import ClientThread 6 | from Protocol.Messages.Server.LoginFailedMessage import LoginFailedMessage 7 | 8 | def _(*args): 9 | for arg in args: 10 | print(arg, end=' ') 11 | print() 12 | 13 | class Server: 14 | clients_count = 0 15 | 16 | def __init__(self, ip: str, port: int): 17 | self.config = json.loads(open('config.json', 'r').read()) 18 | self.db = MongoDB(self.config['MongoConnectionURL']) 19 | self.server = socket.socket() 20 | self.port = port 21 | self.ip = ip 22 | 23 | def start(self): 24 | self.server.bind((self.ip, self.port)) 25 | 26 | _(f'{Helpers.cyan}[DEBUG] Server started! Listening on {self.ip}:{self.port}') 27 | 28 | while True: 29 | self.server.listen() 30 | client, address = self.server.accept() 31 | 32 | _(f'{Helpers.cyan}[DEBUG] Client connected! IP: {address[0]}') 33 | 34 | ClientThread(client, address, self.db).start() 35 | 36 | Helpers.connected_clients['ClientsCount'] += 1 -------------------------------------------------------------------------------- /Files/CsvLogic/Characters.py: -------------------------------------------------------------------------------- 1 | from Files.CsvReader import CsvReader 2 | 3 | 4 | class Characters: 5 | def get_brawlers_id(self): 6 | BrawlersID = [] 7 | reader = CsvReader() 8 | rowData = reader.readCsv('GameAssets/csv_logic/characters.csv') 9 | for row in rowData: 10 | if row[20] == 'Hero' and row[2].lower() != 'true' and row[1].lower() != 'true': 11 | BrawlersID.append(rowData.index(row)) 12 | 13 | return BrawlersID 14 | 15 | 16 | def get_brawler_by_skin_id(self, skin_id): 17 | reader = CsvReader() 18 | charsData = reader.readCsv('GameAssets/csv_logic/characters.csv') 19 | skinsData = reader.readCsv('GameAssets/csv_logic/skins.csv') 20 | skinsConfsData = reader.readCsv('GameAssets/csv_logic/skin_confs.csv') 21 | for row in skinsData: 22 | if skinsData.index(row) == skin_id: 23 | conf = row[1] 24 | for row in skinsConfsData: 25 | if row[0] == conf: 26 | brawler = row[1] 27 | for row in charsData: 28 | if row[0] == brawler: 29 | return charsData.index(row) -------------------------------------------------------------------------------- /Protocol/Messages/Client/ChatToAllianceStreamMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.AllianceStreamMessage import AllianceStreamMessage 3 | 4 | class ChatToAllianceStreamMessage(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | 10 | def decode(self): 11 | self.msg = self.readString() 12 | 13 | def process(self, db): 14 | club_data = db.load_club(self.player.club_id) 15 | 16 | self.player.message_tick = club_data['Messages'][-1]['Tick'] if club_data['Messages'] else self.player.message_tick 17 | self.player.message_tick += 1 18 | 19 | message = {'Event': 2 ,'Message': self.msg, 'PlayerID': self.player.ID, 'PlayerName':self.player.name, 'PlayerRole':self.player.club_role, 'Tick': self.player.message_tick} 20 | 21 | club_data['Messages'].append(message) 22 | db.update_club(self.player.club_id, 'Messages', club_data['Messages']) 23 | 24 | for member in club_data['Members']: 25 | member_id = member['ID'] 26 | AllianceStreamMessage(self.client, self.player, [message]).sendByID(member_id) -------------------------------------------------------------------------------- /Protocol/Messages/Client/SetNameMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.AvailableServerCommandMessage import AvailableServerCommandMessage 3 | from Protocol.Messages.Server.AvatarNameChangeFailedMessage import AvatarNameChangeFailedMessage 4 | 5 | class SetNameMessage(Reader): 6 | def __init__(self, client, player, initial_bytes): 7 | super().__init__(initial_bytes) 8 | self.player = player 9 | self.client = client 10 | 11 | def decode(self): 12 | self.username = self.readString() 13 | self.state = self.readVInt() 14 | 15 | def process(self, db): 16 | if self.username != '': 17 | if len(self.username) >= 2 and len(self.username) <= 20: 18 | self.player.name = self.username 19 | db.update_player_account(self.player.token, 'Name', self.username) 20 | db.update_player_account(self.player.token, 'NameSet', True) 21 | AvailableServerCommandMessage(self.client, self.player, 201).send() 22 | else: 23 | AvatarNameChangeFailedMessage(self.client, self.player).send() 24 | else: 25 | AvatarNameChangeFailedMessage(self.client, self.player).send() -------------------------------------------------------------------------------- /Protocol/LogicCommandManager.py: -------------------------------------------------------------------------------- 1 | from Protocol.Commands.Client.LogicSelectSkinCommand import LogicSelectSkinCommand 2 | from Protocol.Commands.Client.LogicSetPlayerThumbnailCommand import LogicSetPlayerThumbnailCommand 3 | from Protocol.Commands.Client.LogicSetPlayerNameColorCommand import LogicSetPlayerNameColorCommand 4 | from Protocol.Commands.Client.LogicPurchaseDoubleCoinsCommand import LogicPurchaseDoubleCoinsCommand 5 | from Protocol.Commands.Client.LogicPurchaseHeroLvlUpMaterialCommand import LogicPurchaseHeroLvlUpMaterialCommand 6 | from Protocol.Commands.Client.LogicPurchaseBrawlPassCommand import LogicPurchaseBrawlPassCommand 7 | from Protocol.Commands.Client.LogicPurchaseOfferCommand import LogicPurchaseOfferCommand 8 | from Protocol.Commands.Client.LogicGatchaCommand import LogicGatchaCommand 9 | from Protocol.Commands.Client.LogicLevelUpCommand import LogicLevelUpCommand 10 | 11 | commands = { 12 | 500: LogicGatchaCommand, 13 | 505: LogicSetPlayerThumbnailCommand, 14 | 506: LogicSelectSkinCommand, 15 | 509: LogicPurchaseDoubleCoinsCommand, 16 | 519: LogicPurchaseOfferCommand, 17 | 520: LogicLevelUpCommand, 18 | 521: LogicPurchaseHeroLvlUpMaterialCommand, 19 | 527: LogicSetPlayerNameColorCommand, 20 | 534: LogicPurchaseBrawlPassCommand 21 | 22 | } 23 | -------------------------------------------------------------------------------- /DataBase/MongoUtils.py: -------------------------------------------------------------------------------- 1 | class MongoUtils: 2 | def insert_data(self, collection, data): 3 | collection.insert_one(data) 4 | 5 | 6 | def update_document(self, collection, query, item, value): 7 | collection.update_one(query, { "$set": { item: value } }) 8 | 9 | 10 | def update_all_documents(self, collection, query, item, value): 11 | collection.update_many(query, { "$set": { item: value } }) 12 | 13 | 14 | def delete_document(self, collection, args): 15 | collection.delete_one(args) 16 | 17 | 18 | def delete_all_documents(self, collection, args): 19 | collection.delete_many(args) 20 | 21 | 22 | def load_document(self, collection, args): 23 | return collection.find_one(args) 24 | 25 | 26 | def load_all_documents(self, collection, args): 27 | doc_list = [] 28 | cursor = collection.find(args) 29 | for document in cursor: 30 | doc_list.append(document) 31 | 32 | return doc_list 33 | 34 | def load_all_documents_sorted(self, collection, args, element): 35 | doc_list = [] 36 | cursor = collection.find(args).sort(element) 37 | for document in cursor: 38 | doc_list.append(document) 39 | 40 | return doc_list 41 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/LeaveAllianceMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.AllianceResponseMessage import AllianceResponseMessage 3 | from Protocol.Messages.Server.MyAllianceMessage import MyAllianceMessage 4 | 5 | 6 | class LeaveAllianceMessage(Reader): 7 | def __init__(self, client, player, initial_bytes): 8 | super().__init__(initial_bytes) 9 | self.player = player 10 | self.client = client 11 | 12 | def decode(self): 13 | pass 14 | 15 | def process(self, db): 16 | club_data = db.load_club(self.player.club_id) 17 | 18 | if len(club_data['Members']) == 1: 19 | db.delete_club(self.player.club_id) 20 | else: 21 | for member in club_data['Members']: 22 | if member['ID'] == self.player.ID: 23 | del club_data['Members'][club_data['Members'].index(member)] 24 | db.update_club(self.player.club_id, 'Members', club_data['Members'] ) 25 | 26 | self.player.club_id = 0 27 | db.update_player_account(self.player.token, 'ClubID', 0) 28 | 29 | AllianceResponseMessage(self.client, self.player, 80).send() 30 | MyAllianceMessage(self.client, self.player, {'ID':0}).send() -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Modern Brawl 2 | 3 | Simple Brawl Stars v28.189 server emulator written in Python. 4 | 5 | ![ScreenShot](https://cdn.discordapp.com/attachments/817282221177569332/817717138256560188/Screenshot_20210306-131235_Modern_Brawl.jpg) 6 | 7 | ### Requirements: 8 | - Python 3.7 or higher 9 | - pymongo 10 | - dnspython 11 | - colorama 12 | 13 | ### MongoDB configuration 14 | First you'll need to put your MongoDB connection string in `config.json`. If you don't know how to get it here's a quick tutorial: https://imgur.com/a/oXI34dA 15 | 16 | ### Running the server 17 | In a terminal, type __`pip install -r requirements.txt`__ then __`python Main.py`__ 18 | 19 | ### Configuring the client app 20 | To connect to your server, a **patched client** is required. 21 | Download this [base APK](https://mega.nz/file/uDoGmLKI#QmTXlIunmwBdGEX30qjuxyBupX_fiWAOoyY-T81jXdo) and change the IP in `libmg.config.so` 22 | 23 | ### Need help? 24 | Join us on [Discord](https://discord.gg/FdppDWGRbY) 25 | 26 | ### Special thanks 27 | - [athemm](https://github.com/athemm) - for making the patcher. 28 | 29 | ### Was this useful? Support the developer with a coffee ☕ 30 | [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/decosoftapps) 31 | -------------------------------------------------------------------------------- /Logic/Home/LogicEventData.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | class LogicEventData: 4 | events = json.loads(open("events.json", 'r').read()) 5 | 6 | def encode(self): 7 | events = json.loads(open("events.json", 'r').read()) 8 | 9 | self.writeVInt(len(events)) 10 | for i in range(len(events)): 11 | self.writeVInt(i) 12 | 13 | self.writeVInt(len(events)) 14 | 15 | for event in events: 16 | self.writeVInt(events.index(event) + 1) 17 | self.writeVInt(events.index(event) + 1) 18 | self.writeVInt(event['Ended']) 19 | self.writeVInt(99999) # Timer 20 | 21 | self.writeVInt(0) 22 | self.writeDataReference(15, event['ID']) 23 | 24 | self.writeVInt(event['Status']) 25 | 26 | self.writeString() 27 | self.writeVInt(0) 28 | self.writeVInt(0) 29 | self.writeVInt(0) 30 | 31 | if event['Modifier'] > 0: 32 | self.writeBoolean(True) 33 | self.writeVInt(event['Modifier']) 34 | else: 35 | self.writeBoolean(False) 36 | 37 | self.writeVInt(0) 38 | self.writeVInt(0) 39 | 40 | 41 | self.writeVInt(0) 42 | for x in range(0): 43 | pass 44 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/AllianceStreamMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class AllianceStreamMessage(Writer): 4 | 5 | def __init__(self, client, player, msg): 6 | super().__init__(client) 7 | self.id = 24311 8 | self.player = player 9 | self.msg = msg 10 | 11 | 12 | def encode(self): 13 | if self.player.club_id != 0: 14 | self.writeVInt(len(self.msg)) 15 | for x in self.msg: 16 | print(x) 17 | self.writeVInt(x['Event']) 18 | self.writeVInt(0) 19 | self.writeVInt(x['Tick']) 20 | self.writeLogicLong(x['PlayerID']) 21 | self.writeString(x['PlayerName']) 22 | self.writeVInt(x['PlayerRole']) 23 | self.writeVInt(0) 24 | self.writeVInt(0) 25 | 26 | if x['Event'] == 4: 27 | self.writeVInt(x['Message']) 28 | self.writeVInt(1) 29 | self.writeVInt(0) 30 | self.writeLogicLong(x['PlayerID']) 31 | self.writeString(x['PlayerName']) 32 | 33 | else: 34 | self.writeString(x['Message']) 35 | else: 36 | self.writeVInt(0) 37 | 38 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/LoginOkMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | 4 | class LoginOkMessage(Writer): 5 | def __init__(self, client, player, account_id, account_token): 6 | super().__init__(client) 7 | self.player = player 8 | self.account_id = account_id 9 | self.account_token = account_token 10 | self.id = 20104 11 | 12 | def encode(self): 13 | self.writeLong(self.account_id) 14 | self.writeLong(self.account_id) 15 | 16 | self.writeString(self.account_token) 17 | self.writeString() 18 | self.writeString() 19 | 20 | self.writeInt(26) 21 | self.writeInt(184) 22 | self.writeInt(1) 23 | 24 | self.writeString("dev") 25 | 26 | self.writeInt(0) 27 | self.writeInt(0) 28 | self.writeInt(0) 29 | 30 | self.writeString() 31 | self.writeString() 32 | self.writeString() 33 | 34 | self.writeInt(0) 35 | 36 | self.writeString() 37 | self.writeString(self.player.region) 38 | self.writeString() 39 | 40 | self.writeInt(1) 41 | self.writeString() 42 | 43 | self.writeInt(2) 44 | self.writeString() 45 | self.writeString() 46 | 47 | self.writeInt(1) 48 | self.writeString() 49 | 50 | -------------------------------------------------------------------------------- /Protocol/Commands/Client/LogicGatchaCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Utils.Helpers import Helpers 3 | from Logic.Home.LogicShopData import LogicShopData 4 | from Protocol.Messages.Server.AvailableServerCommandMessage import AvailableServerCommandMessage 5 | 6 | class LogicGatchaCommand(Reader): 7 | def __init__(self, client, player, initial_bytes): 8 | super().__init__(initial_bytes) 9 | self.player = player 10 | self.client = client 11 | 12 | def decode(self): 13 | self.readVInt() 14 | self.readVInt() 15 | self.readLogicLong() 16 | self.box_id = self.readVInt() 17 | 18 | 19 | def process(self, db): 20 | self.player.delivery_items = {'Count': 1, 'Type': Helpers.get_box_type(self, self.box_id)} 21 | 22 | if self.box_id == 1: 23 | self.player.gems = self.player.gems - LogicShopData.boxes[0]['Cost'] 24 | db.update_player_account(self.player.token, 'Gems', self.player.gems) 25 | elif self.box_id == 3: 26 | self.player.gems = self.player.gems - LogicShopData.boxes[1]['Cost'] 27 | db.update_player_account(self.player.token, 'Gems', self.player.gems) 28 | 29 | self.player.db = db 30 | AvailableServerCommandMessage(self.client, self.player, 203).send() 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/MyAllianceMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | from Files.CsvLogic.Regions import Regions 3 | 4 | class MyAllianceMessage(Writer): 5 | 6 | def __init__(self, client, player, club_data): 7 | super().__init__(client) 8 | self.id = 24399 9 | self.player = player 10 | self.club_data = club_data 11 | 12 | def encode(self): 13 | if self.club_data['ID'] != 0: 14 | 15 | self.writeVInt(len(self.club_data['Members'])) 16 | self.writeVInt(1) 17 | self.writeDataReference(25, self.player.club_role) 18 | self.writeLong(self.club_data['ID']) 19 | self.writeString(self.club_data['Name']) 20 | self.writeDataReference(8, self.club_data['BadgeID']) 21 | self.writeVInt(self.club_data['Type']) 22 | self.writeVInt(len(self.club_data['Members'])) 23 | self.writeVInt(self.club_data['Trophies']) 24 | self.writeVInt(self.club_data['RequiredTrophies']) 25 | self.writeDataReference(0, 0) 26 | self.writeString(Regions().get_region_string(self.club_data['Region'])) 27 | self.writeVInt(0) 28 | self.writeVInt(self.club_data['FamilyFriendly']) 29 | 30 | else: 31 | self.writeVInt(0) 32 | self.writeVInt(0) 33 | 34 | -------------------------------------------------------------------------------- /Protocol/Commands/Client/LogicSelectSkinCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Files.CsvLogic.Cards import Cards 3 | from Files.CsvLogic.Characters import Characters 4 | 5 | class LogicSelectSkinCommand(Reader): 6 | def __init__(self, client, player, initial_bytes): 7 | super().__init__(initial_bytes) 8 | self.player = player 9 | self.client = client 10 | 11 | def decode(self): 12 | self.readVInt() 13 | self.readVInt() 14 | self.readLogicLong() 15 | self.skinID = self.readDataReference()[1] 16 | 17 | 18 | def process(self, db): 19 | self.player.home_brawler = Characters.get_brawler_by_skin_id(self, self.skinID) 20 | db.update_player_account(self.player.token, 'HomeBrawler', self.player.home_brawler) 21 | 22 | self.player.selected_skins[str(self.player.home_brawler)] = self.skinID 23 | db.update_player_account(self.player.token, 'SelectedSkins', self.player.selected_skins) 24 | 25 | self.player.starpower = Cards.get_spg_by_brawler_id(self, self.player.home_brawler, 4) 26 | db.update_player_account(self.player.token, 'StarPower', self.player.starpower) 27 | 28 | self.player.gadget = Cards.get_spg_by_brawler_id(self, self.player.home_brawler, 5) 29 | db.update_player_account(self.player.token, 'Gadget', self.player.gadget) -------------------------------------------------------------------------------- /Protocol/Commands/Server/LogicGiveDeliveryItemsCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | from Logic.Home.LogicBoxData import LogicBoxData 3 | 4 | class LogicGiveDeliveryItemsCommand(Writer): 5 | 6 | def encode(self): 7 | 8 | self.writeVInt(0) 9 | self.writeVInt(self.player.delivery_items['Count']) # multiplier 10 | 11 | for y in range(self.player.delivery_items['Count']): 12 | # DeliveryUnit 13 | type = self.player.delivery_items['Type'] 14 | self.writeVInt(type) 15 | if type != 100: 16 | rewards = LogicBoxData.randomize(self, type)['Rewards'] 17 | else: 18 | rewards = self.player.delivery_items['Items'] 19 | 20 | self.writeVInt(len(rewards)) 21 | 22 | for x in rewards: 23 | # GatchaDrop 24 | self.writeVInt(x['Amount']) 25 | self.writeDataReference(x['DataRef'][0], x['DataRef'][1]) 26 | self.writeVInt(x['Value']) 27 | self.writeDataReference(0, 0) 28 | self.writeDataReference(0, 0) 29 | self.writeDataReference(0, 0) 30 | self.writeVInt(0) 31 | 32 | self.writeBool(True) # ForcedDrops 33 | 34 | self.writeVInt(1) 35 | self.writeVInt(1) 36 | self.writeVInt(0) 37 | self.writeVInt(0) 38 | self.writeVInt(0) 39 | self.writeVInt(0) 40 | self.writeLogicLong(0) 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/AskForBattleEndMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.BattleEndMessage import BattleEndMessage 3 | 4 | class AskForBattleEndMessage(Reader): 5 | def __init__(self, client, player, initial_bytes): 6 | super().__init__(initial_bytes) 7 | self.player = player 8 | self.client = client 9 | self.players = {} 10 | 11 | def decode(self): 12 | self.result = self.readVInt() 13 | self.unk = self.readVInt() 14 | self.rank = self.readVInt() 15 | self.mapID = self.readDataReference() 16 | 17 | self.count = self.readVInt() 18 | 19 | for player in range(self.count): 20 | self.brawler = self.readDataReference() 21 | self.skin = self.readDataReference() 22 | self.team = self.readVInt() 23 | self.unk = self.readVInt() 24 | self.username = self.readString() 25 | 26 | self.players[player] = {f'Name': self.username, 'Team': self.team, 'Brawler': self.brawler[1], 'Skin': self.skin[1]} 27 | 28 | 29 | def process(self, db): 30 | if self.rank != 0: 31 | if self.players[0]['Team'] == self.players[1]['Team']: 32 | self.type = 5 33 | else: 34 | self.type = 2 35 | else: 36 | self.type = 0 37 | 38 | BattleEndMessage(self.client, self.player, self.type, self.result, self.players).send() 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/themes.csv: -------------------------------------------------------------------------------- 1 | "Name","FileName","ExportName","ParticleFileName","ParticleExportName","ParticleStyle","ParticleVariations","ThemeMusic","UseInLevelSelection" 2 | "string","string","string","string","string","string","int","string","boolean" 3 | "Default","sc/background_basic.sc","bgr","sc/ui.sc",,,,"Monsterbrawl_menu_muzak","true" 4 | "Winter","sc/background_basic.sc","bgr","sc/ui.sc","particle_snow_","Snow",2,"Snow_brawl","true" 5 | "LNY","sc/background_lny.sc","bgr_cny",,,,,"Cnymenu_music","true" 6 | "CR","sc/background_basic.sc","bgr_royale",,,,,"Brawl_royale_menu_music","true" 7 | "Easter","sc/background_basic.sc","bgr",,,,,"MenuMusic","true" 8 | "GoldenWeek","sc/background_golden_week.sc","bgr_golden_week",,,,,"MenuMusic","true" 9 | "Retropolis","sc/background_retropolis.sc","bgr_retropolis",,,,,"Retropolis_menu","true" 10 | "Mecha","sc/background_mecha.sc","bgr_mecha",,,,,"MechMenuMusic","true" 11 | "Halloween","sc/background_brawloween.sc","bgr_brawloween",,,,,"Halloween_menu","true" 12 | "Brawlidays","sc/background_brawlidays.sc","bgr_brawlidays",,,,,"Xmas_Pirate_Menu","true" 13 | "LNY20","sc/background_lny_20.sc","bgr_lny20",,,,,"Brawlcade_Menu","true" 14 | "PSG","sc/background_psg.sc","bgr_psg","sc/ui.sc",,,,"Footbrawl_menu_muzak","true" 15 | "SC10","sc/background_s_anniversary.sc","bgr_s_anniversary",,,,,"10th_Anniversary_Menu","true" 16 | "Bazaar","sc/background_t_bazaar.sc","bgr_t_bazaar",,,,,"Brawzaar_menu_muzak","true" 17 | "Monsters","sc/background_scity.sc","bgr_scity",,,,,"Monsterbrawl_menu_muzak","true" 18 | -------------------------------------------------------------------------------- /Patcher/Patch.py: -------------------------------------------------------------------------------- 1 | import http.server 2 | import socketserver 3 | import socket 4 | import subprocess 5 | import os 6 | import shutil 7 | import Lib.ATPatchmaker as pm 8 | 9 | def all_subdirs_of(b='.') -> list: 10 | result = [] 11 | for d in os.listdir(b): 12 | bd = os.path.join(b, d) 13 | if os.path.isdir(bd): result.append(bd) 14 | return result 15 | 16 | 17 | 18 | ip = "0.0.0.0" 19 | port = 8080 20 | 21 | 22 | current_path = os.getcwd() # backing this up for later use 23 | 24 | os.chdir(current_path + "/Patch") 25 | 26 | print("Please wait until the patcher finishes running\n") 27 | pm.Make() 28 | print("\nPatching done!") 29 | 30 | os.chdir(current_path) 31 | 32 | # Copy the output to the correct folder 33 | patch_folder = max(all_subdirs_of(os.getcwd() + "/Patch/Patchs"), key=os.path.getctime) # select the newest created folder 34 | 35 | latest_finger = patch_folder + "/fingerprint.json" 36 | 37 | parent = os.path.dirname(current_path) # classic brawl parent dir 38 | 39 | shutil.copy(latest_finger, parent + "/GameAssets") 40 | 41 | 42 | os.chdir(current_path + "/Patch/Patchs") # get back to the original folder/patch 43 | handler = http.server.SimpleHTTPRequestHandler 44 | 45 | with socketserver.TCPServer((ip, port), handler) as httpserver: 46 | host_name = socket.gethostname() 47 | host_ip = socket.gethostbyname(host_name) 48 | 49 | print(f"\nPatching HTTP server started at URL \nhttp://{host_ip}:{port}/\n") 50 | print("Do not close this window and restart your Classic Brawl server for changes to take effect") 51 | httpserver.serve_forever() 52 | -------------------------------------------------------------------------------- /GameAssets/csv_client/hints.csv: -------------------------------------------------------------------------------- 1 | "Name","TID","MinXPLevel","MaxXPLevel","FileName","ExportName","Character","ReferringSCID" 2 | "String","String","int","int","String","String","String","boolean" 3 | 1,"TID_HINT_0",1,40,,,, 4 | 2,"TID_HINT_1",1,40,,,, 5 | 3,"TID_HINT_2",1,40,,,, 6 | 4,"TID_HINT_3",1,40,,,, 7 | 5,"TID_HINT_4",1,40,,,, 8 | 6,"TID_HINT_5",3,999,,,, 9 | 7,"TID_HINT_6",3,999,,,, 10 | 8,"TID_HINT_7",20,999,,,, 11 | 9,"TID_HINT_8",999,999,,,, 12 | 10,"TID_HINT_9",20,999,,,, 13 | 11,"TID_HINT_10",1,40,,,, 14 | 12,"TID_HINT_11",1,40,,,, 15 | 13,"TID_HINT_12",3,60,,,, 16 | 14,"TID_HINT_13",3,60,,,, 17 | 15,"TID_HINT_14",3,60,,,, 18 | 16,"TID_HINT_15",3,60,,,, 19 | 17,"TID_HINT_16",3,60,,,, 20 | 18,"TID_HINT_17",3,60,,,, 21 | 19,"TID_HINT_18",3,60,,,, 22 | 20,"TID_HINT_19",3,60,,,, 23 | 21,"TID_HINT_20",3,60,,,, 24 | 22,"TID_HINT_21",1,40,,,, 25 | 23,"TID_HINT_22",1,40,,,, 26 | 24,"TID_HINT_23",3,60,,,, 27 | 25,"TID_HINT_24",3,60,,,, 28 | 26,"TID_HINT_25",3,60,,,, 29 | 27,"TID_HINT_26",20,999,,,, 30 | 28,"TID_HINT_27",3,999,,,, 31 | 29,"TID_HINT_28",3,999,,,, 32 | 30,"TID_HINT_29",3,60,,,, 33 | 31,"TID_HINT_30",3,999,,,, 34 | 32,"TID_HINT_31",20,999,,,, 35 | 33,"TID_HINT_32",3,60,,,, 36 | 34,"TID_HINT_33",3,999,,,, 37 | 35,"TID_HINT_34",3,999,,,, 38 | 36,"TID_HINT_35",3,999,,,, 39 | 37,"TID_HINT_36",3,999,,,, 40 | 38,"TID_HINT_37",999,999,,,, 41 | 39,"TID_HINT_38",7,999,,,, 42 | 40,"TID_HINT_39",7,999,,,, 43 | 41,"TID_HINT_40",3,999,,,,"TRUE" 44 | 42,"TID_HINT_41",7,999,,,, 45 | 43,"TID_HINT_42",1,40,,,, 46 | 44,"TID_HINT_43",20,999,,,, 47 | 45,"TID_HINT_44",20,999,,,, 48 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/TeamChangeMemberSettingsMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Files.CsvLogic.Cards import Cards 3 | from Files.CsvLogic.Characters import Characters 4 | from Protocol.Messages.Server.TeamMessage import TeamMessage 5 | 6 | 7 | class TeamChangeMemberSettingsMessage(Reader): 8 | def __init__(self, client, player, initial_bytes): 9 | super().__init__(initial_bytes) 10 | self.player = player 11 | self.client = client 12 | 13 | 14 | def decode(self): 15 | self.data_ref = self.readDataReference() 16 | if self.data_ref[0] == 0: 17 | self.data_ref = self.readDataReference() 18 | 19 | 20 | def process(self, db): 21 | if self.data_ref[0] == 29: 22 | self.player.home_brawler = Characters.get_brawler_by_skin_id(self, self.data_ref[1]) 23 | self.player.home_skin = self.data_ref[1] 24 | self.player.starpower = Cards.get_spg_by_brawler_id(self, self.player.home_brawler, 4) 25 | self.player.gadget = Cards.get_spg_by_brawler_id(self, self.player.home_brawler, 5) 26 | 27 | elif self.data_ref[0] == 23: 28 | type = Cards.check_spg_id(self, self.data_ref[1]) 29 | if type == '4': 30 | self.player.starpower = self.data_ref[1] 31 | elif type == '5': 32 | self.player.gadget = self.data_ref[1] 33 | 34 | db.update_player_account(self.player.token, 'StarPower', self.player.starpower) 35 | db.update_player_account(self.player.token, 'Gadget', self.player.gadget) 36 | 37 | 38 | TeamMessage(self.client, self.player).send() -------------------------------------------------------------------------------- /GameAssets/csv_client/color_gradients.csv: -------------------------------------------------------------------------------- 1 | "Name","Colors","Speed","Scale" 2 | "String","String","int","int" 3 | "FreeOffer","0xFF9FFF72",40,100 4 | ,"0xFF68E524",, 5 | ,"0xFF68E524",, 6 | ,"0xFF9FFF72",, 7 | ,"0xFFE0FFA0",, 8 | "Golden","0xFFFFFABC",50,100 9 | ,"0xFFFFD12E",, 10 | ,"0xFFF29928",, 11 | ,"0xFFFFD12E",, 12 | "Purple","0xFFFABCFF",50,100 13 | ,"0xFFD12EFF",, 14 | ,"0xFF9928F2",, 15 | ,"0xFFD12EFF",, 16 | "DoubleTokenGold","0xFFFFDAAC",50,70 17 | ,"0xFFFFD12E",, 18 | ,"0xFFF29928",, 19 | ,"0xFFFFD12E",, 20 | "DefaultName","0xFFFFFFFF",50,70 21 | ,"0xFFFFFFFF",, 22 | "Name1","0xFF45ffb1",50,100 23 | ,"0xFF2eef60",, 24 | ,"0xFF00c74b",, 25 | ,"0xFF2eef60",, 26 | "Name2","0xFFfff5d6",50,100 27 | ,"0xFFFFDBA7",, 28 | ,"0xFFffb777",, 29 | ,"0xFFFFDBA7",, 30 | "Name3","0xFFffffce",50,100 31 | ,"0xFFfff76c",, 32 | ,"0xFFffe034",, 33 | ,"0xFFfff76c",, 34 | "Name4","0xFFFDF542",50,100 35 | ,"0xFFfdd000",, 36 | ,"0xFFFF9005",, 37 | ,"0xFFfdd000",, 38 | "Name5","0xFFffd49d",50,100 39 | ,"0xFFFFAA82",, 40 | ,"0xFFff7b4f",, 41 | ,"0xFFFFAA82",, 42 | "Name6","0xFFffae1f",50,100 43 | ,"0xFFff7b06",, 44 | ,"0xFFff382e",, 45 | ,"0xFFff7b06",, 46 | "Name7","0xFFff9368",50,100 47 | ,"0xFFFF6178",, 48 | ,"0xFFf51a73",, 49 | ,"0xFFFF6178",, 50 | "Name8","0xFFffc92f",30,100 51 | ,"0xFFff9c4c",, 52 | ,"0xFFff6856",, 53 | ,"0xFFf931a3",, 54 | ,"0xFFe300b9",, 55 | ,"0xFFf931a3",, 56 | ,"0xFFff6856",, 57 | ,"0xFFff9c4c",, 58 | "Name9","0xFF20fbff",50,100 59 | ,"0xFF00d0fa",, 60 | ,"0xFF359eff",, 61 | ,"0xFF00d0fa",, 62 | "Name10","0xFFFF6DEA",50,100 63 | ,"0xFFFA00D6",, 64 | ,"0xFFCA00F4",, 65 | ,"0xFFFA00D6",, 66 | "Name11","0xFFdffd67",50,100 67 | ,"0xFF7efc7d",, 68 | " ","0xFF13cf00",, 69 | ,"0xFF7efc7d",, 70 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/alliance_badges.csv: -------------------------------------------------------------------------------- 1 | "Name","IconSWF","IconExportName","Category" 2 | "String","String","String","String" 3 | "clan_badge_01_01","sc/ui.sc","clan_badge_01_01", 4 | "clan_badge_01_02","sc/ui.sc","clan_badge_01_02", 5 | "clan_badge_01_03","sc/ui.sc","clan_badge_01_03", 6 | "clan_badge_01_04","sc/ui.sc","clan_badge_01_04", 7 | "clan_badge_02_01","sc/ui.sc","clan_badge_02_01", 8 | "clan_badge_02_02","sc/ui.sc","clan_badge_02_02", 9 | "clan_badge_02_03","sc/ui.sc","clan_badge_02_03", 10 | "clan_badge_02_04","sc/ui.sc","clan_badge_02_04", 11 | "clan_badge_03_01","sc/ui.sc","clan_badge_03_01", 12 | "clan_badge_03_02","sc/ui.sc","clan_badge_03_02", 13 | "clan_badge_03_03","sc/ui.sc","clan_badge_03_03", 14 | "clan_badge_03_04","sc/ui.sc","clan_badge_03_04", 15 | "clan_badge_04_01","sc/ui.sc","clan_badge_04_01", 16 | "clan_badge_04_02","sc/ui.sc","clan_badge_04_02", 17 | "clan_badge_04_03","sc/ui.sc","clan_badge_04_03", 18 | "clan_badge_04_04","sc/ui.sc","clan_badge_04_04", 19 | "clan_badge_05_01","sc/ui.sc","clan_badge_05_01", 20 | "clan_badge_05_02","sc/ui.sc","clan_badge_05_02", 21 | "clan_badge_05_03","sc/ui.sc","clan_badge_05_03", 22 | "clan_badge_05_04","sc/ui.sc","clan_badge_05_04", 23 | "clan_badge_01_05","sc/ui.sc","clan_badge_01_05", 24 | "clan_badge_01_06","sc/ui.sc","clan_badge_01_06", 25 | "clan_badge_02_05","sc/ui.sc","clan_badge_02_05", 26 | "clan_badge_02_06","sc/ui.sc","clan_badge_02_06", 27 | "clan_badge_03_05","sc/ui.sc","clan_badge_03_05", 28 | "clan_badge_03_06","sc/ui.sc","clan_badge_03_06", 29 | "clan_badge_04_05","sc/ui.sc","clan_badge_04_05", 30 | "clan_badge_04_06","sc/ui.sc","clan_badge_04_06", 31 | "clan_badge_05_05","sc/ui.sc","clan_badge_05_05", 32 | "clan_badge_05_06","sc/ui.sc","clan_badge_05_06", 33 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/challenges.csv: -------------------------------------------------------------------------------- 1 | "Name","ChallengeId","FileName","Locale","LogoAsset","HomeScreenLogo","EventAsset","BannerSWF","EventBanner","RewardItem","RewardUnlockedItem","HeaderFrame","TID","StageTID","RewardTID","CompletedTID","RewardPopupTID","BattleEndHeaderTID","BattleEndWinLabelTID","BattleEndWinTID","StartNotification","ReminderNotification","TeaserTitleTID","TeaserInfoTID" 2 | "string","int","string","StringArray","StringArray","StringArray","string","string","string","string","string","string","string","string","string","string","string","string","string","string","string","string","string","string" 3 | "ChampionShip",0,"sc/ui.sc","EN","bsc_logo_en",,"event_info_championship_challenge","sc/events.sc","event_bs_challenge_banner","championship_challenge_qualify","championship_challenge_qualify","basic","TID_CC_POPUP_TITLE","TID_CC_POPUP_WINS_FOR_EVENT","TID_CC_POPUP_QUALIFY_INFO","TID_CC_POPUP_QUALIFY_INFO_COMPLETED","TID_QUALIFIED_INFO","TID_EVENT_LABEL_CHAMPIONSHIP_CHALLENGE","TID_BATTLE_END_CC_QUALIFY_LABEL","TID_BATTLE_END_CC_QUALIFY_INFO","CCStart","CCReminder","TID_CC_TEASER_TITLE","TID_CC_TEASER_INFO" 4 | ,,,"JP","bsc_logo_jp",,,,,,,,,,,,,,,,,,, 5 | ,,,"KR","bsc_logo_kr",,,,,,,,,,,,,,,,,,, 6 | ,,,"CN","bsc_logo_cns",,,,,,,,,,,,,,,,,,, 7 | ,,,"CNT","bsc_logo_cnt",,,,,,,,,,,,,,,,,,, 8 | "PSG",1,"sc/ui.sc",,"psg_logo","psg_logo_mainscreen","event_info_psg_challenge","sc/events.sc","event_psg_challenge_banner","championship_challenge_qualify_psg","psg_logo","psg","TID_CC_POPUP_1_TITLE","TID_POPUP_WINS_FOR_EVENT_PSG","TID_CC_POPUP_QUALIFY_INFO_PSG","TID_CC_POPUP_QUALIFY_INFO_COMPLETED","TID_QUALIFIED_INFO_PSG","TID_CC_POPUP_1_TITLE","TID_BATTLE_END_CHALLENGE_WIN_LABEL","TID_BATTLE_END_PSG_CHALLENGE_WIN_INFO","PSGStart","PSGReminder","TID_PSG_TEASER_TITLE","TID_PSG_TEASER_INFO" 9 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/JoinAllianceMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.AllianceResponseMessage import AllianceResponseMessage 3 | from Protocol.Messages.Server.MyAllianceMessage import MyAllianceMessage 4 | from Protocol.Messages.Server.AllianceStreamMessage import AllianceStreamMessage 5 | 6 | class JoinAllianceMessage(Reader): 7 | def __init__(self, client, player, initial_bytes): 8 | super().__init__(initial_bytes) 9 | self.player = player 10 | self.client = client 11 | 12 | def decode(self): 13 | self.club_id = self.readLong() 14 | 15 | def process(self, db): 16 | self.player.club_id = self.club_id 17 | self.player.club_role = 1 18 | 19 | club_data = db.load_club(self.club_id) 20 | club_data['Members'].append( 21 | { 22 | f'Name': self.player.name, 23 | 'ID': self.player.ID, 24 | 'Role': self.player.club_role, 25 | 'Trophies': self.player.trophies, 26 | 'ProfileIcon': self.player.profile_icon, 27 | 'NameColor': self.player.name_color 28 | } 29 | ) 30 | 31 | db.update_club(self.club_id, 'Members', club_data['Members']) 32 | db.update_club(self.club_id, 'Trophies', club_data['Trophies'] + self.player.trophies) 33 | db.update_player_account(self.player.token, 'ClubID', self.player.club_id) 34 | db.update_player_account(self.player.token, 'ClubRole', self.player.club_role) 35 | 36 | AllianceResponseMessage(self.client, self.player, 40).send() 37 | MyAllianceMessage(self.client, self.player, club_data).send() 38 | AllianceStreamMessage(self.client, self.player, club_data['Messages']).send() 39 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/ChangeAllianceSettingsMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Protocol.Messages.Server.AllianceResponseMessage import AllianceResponseMessage 3 | from Protocol.Messages.Server.MyAllianceMessage import MyAllianceMessage 4 | from Protocol.Messages.Server.AllianceDataMessage import AllianceDataMessage 5 | 6 | 7 | class ChangeAllianceSettingsMessage(Reader): 8 | def __init__(self, client, player, initial_bytes): 9 | super().__init__(initial_bytes) 10 | self.player = player 11 | self.client = client 12 | 13 | def decode(self): 14 | self.club_id = self.player.club_id 15 | self.club_desc = self.readString() 16 | self.club_badge = self.readDataReference()[1] 17 | self.club_region = self.readDataReference()[1] 18 | self.club_type = self.readVInt() 19 | self.club_req_trophies = self.readVInt() 20 | self.club_family_friendly = self.readVInt() 21 | 22 | def process(self, db): 23 | db.update_club(self.club_id, 'Description', self.club_desc) 24 | db.update_club(self.club_id, 'Type', self.club_type) 25 | db.update_club(self.club_id, 'BadgeID', self.club_badge) 26 | db.update_club(self.club_id, 'RequiredTrophies', self.club_req_trophies) 27 | db.update_club(self.club_id, 'FamilyFriendly', self.club_family_friendly) 28 | db.update_club(self.club_id, 'Region', self.club_region) 29 | 30 | print(self.club_region) 31 | 32 | club_data = db.load_club(self.club_id) 33 | 34 | MyAllianceMessage(self.client, self.player, club_data).send() 35 | AllianceResponseMessage(self.client, self.player, 10).send() 36 | AllianceDataMessage(self.client, self.player, club_data).send() -------------------------------------------------------------------------------- /Protocol/Messages/Server/LoginFailedMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | from Utils.Fingerprint import Fingerprint 3 | 4 | 5 | class LoginFailedMessage(Writer): 6 | 7 | def __init__(self, client, player, msg): 8 | super().__init__(client) 9 | self.id = 20103 10 | self.player = player 11 | self.msg = msg 12 | self.fingerprint = Fingerprint.loadFinger_full("GameAssets/fingerprint.json") 13 | 14 | """ 15 | << Error Code List >> 16 | # 1 = Custom Message 17 | # 7 = Patch 18 | # 8 = Update Available 19 | # 9 = Redirect 20 | # 10 = Maintenance 21 | # 11 = Banned 22 | # 13 = Acc Locked PopUp 23 | # 16 = Updating Cr/Maintenance/Too high version 24 | # 18 = Chinese Text? 25 | 26 | """ 27 | 28 | if self.player.err_code == 7 or self.player.err_code == 8: 29 | self.isPatching = True 30 | else: 31 | self.isPatching = False 32 | 33 | def encode(self): 34 | 35 | self.writeInt(self.player.err_code) 36 | 37 | if self.isPatching: # refer to above note about codes 38 | self.writeString(self.fingerprint) 39 | else: 40 | self.writeString() 41 | 42 | self.writeString() # Server host 43 | 44 | self.writeString(self.player.patch_url) 45 | self.writeString(self.player.update_url) 46 | 47 | self.writeString(self.msg) 48 | 49 | self.writeInt(self.player.maintenance_time) 50 | self.writeBoolean(False) 51 | 52 | self.writeString() 53 | self.writeString() 54 | 55 | self.writeInt(0) 56 | self.writeInt(3) 57 | 58 | self.writeString() 59 | self.writeString() 60 | 61 | self.writeInt(0) 62 | self.writeInt(0) 63 | 64 | self.writeBoolean(False) 65 | self.writeBoolean(False) 66 | -------------------------------------------------------------------------------- /Patcher/Patch/Gamefiles/fingerprint.json: -------------------------------------------------------------------------------- 1 | {"files": [{"file": "csv_client\/animations.csv", "sha": "e9714430d57e879e4f7889bcd9b112c94881799f"}, {"file": "csv_client\/color_gradients.csv", "sha": "1f075732aeecfef23ec4ed21247fec55fb1dea70"}, {"file": "csv_client\/credits.csv", "sha": "ff9bf91f17fcbbc7d0326b931170982cf944f4c4"}, {"file": "csv_client\/effects.csv", "sha": "532768693b4e34d3712d6246e47fbd3f9c8fcc27"}, {"file": "csv_logic\/accessories.csv", "sha": "f90c35230d8f2c24810de4dcf2fccfaa464285d2"}, {"file": "csv_logic\/cards.csv", "sha": "5f47da271d6d03937539d7cd94321189e30f12f4"}, {"file": "csv_logic\/characters.csv", "sha": "a885a0a18086f14cb5bf5a506770cf9659be1a4c"}, {"file": "csv_logic\/locales.csv", "sha": "974b5a9a590fa57605a91a7bebdfb07043a92887"}, {"file": "csv_logic\/locations.csv", "sha": "0245ee292f41fc9c727f0079fe4d520c3538738e"}, {"file": "csv_logic\/location_themes.csv", "sha": "953e7b285a7d80538f1a5bbe595b3585b816d5ec"}, {"file": "csv_logic\/maps.csv", "sha": "a63fb19d76d3f78fc84a7c8d7549e36da58ad3dd"}, {"file": "csv_logic\/name_colors.csv", "sha": "fb91ef907b5e4896b872d32aa514bcef3150e620"}, {"file": "csv_logic\/player_thumbnails.csv", "sha": "3e07370d2e17ed3fe05a8ef79fd595361f07117f"}, {"file": "csv_logic\/projectiles.csv", "sha": "cf4e6a7d0138bf3fc333bd5df9362025a40865e6"}, {"file": "csv_logic\/skills.csv", "sha": "d026e2ea44b37a7580590d87056ef3c0836146ec"}, {"file": "csv_logic\/skins.csv", "sha": "0e6227a0d56578c45a6622899be89e62016510c8"}, {"file": "csv_logic\/skin_confs.csv", "sha": "a4cc8eeadb7b60c46eff01fbc08f150f2ab9db51"}, {"file": "csv_logic\/themes.csv", "sha": "588432e74a05bdc33aeae313eed209bb4b3fcb86"}, {"file": "csv_logic\/tiles.csv", "sha": "5db2b9aba0467344fcec576536269dbb8d322380"}, {"file": "localization\/texts_patch.csv", "sha": "359f80a913b282ce13233348b82d4f87a69a340f"}, {"file": "sc\/loading_tex.sc", "sha": "05e86576de25e102c28cec520b8f50cef70a6a8b"}], "sha": "a7ae8c565faebf3862bb4383e865685aaa96727a", "version": "28.189.10"} -------------------------------------------------------------------------------- /Protocol/Messages/Server/AllianceDataMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | from Files.CsvLogic.Regions import Regions 3 | 4 | class AllianceDataMessage(Writer): 5 | 6 | def __init__(self, client, player, club_data): 7 | super().__init__(client) 8 | self.id = 24301 9 | self.player = player 10 | self.club_data = club_data 11 | 12 | def encode(self): 13 | if self.club_data['ID'] != 0: 14 | 15 | self.writeVInt(0) 16 | self.writeLong(self.club_data['ID']) 17 | self.writeString(self.club_data['Name']) 18 | self.writeDataReference(8, self.club_data['BadgeID']) 19 | self.writeVInt(self.club_data['Type']) 20 | self.writeVInt(len(self.club_data['Members'])) 21 | self.writeVInt(self.club_data['Trophies']) 22 | self.writeVInt(self.club_data['RequiredTrophies']) 23 | self.writeDataReference(0, 0) 24 | self.writeString(Regions().get_region_string(self.club_data['Region'])) 25 | self.writeVInt(0) 26 | self.writeVInt(self.club_data['FamilyFriendly']) 27 | 28 | self.writeString(self.club_data['Description']) 29 | 30 | self.writeVInt(len(self.club_data['Members'])) 31 | 32 | for member in self.club_data['Members']: 33 | self.writeLong(member['ID']) 34 | self.writeVInt(member['Role']) 35 | self.writeVInt(member['Trophies']) 36 | self.writeVInt(2) # Player Status 37 | self.writeVInt(0) 38 | self.writeVInt(0) 39 | 40 | self.writeString(member['Name']) 41 | self.writeVInt(100) 42 | self.writeVInt(28000000 + member['ProfileIcon']) 43 | self.writeVInt(43000000 + member['NameColor']) 44 | self.writeNullVInt() 45 | 46 | else: 47 | self.writeVInt(2) 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /Logic/Home/LogicConfData.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from Logic.Home.LogicEventData import LogicEventData 3 | from Logic.Home.LogicShopData import LogicShopData 4 | 5 | class LogicConfData: 6 | 7 | def encode(self): 8 | 9 | LogicShopData.encodeShopResources(self) 10 | 11 | self.writeVInt(500) # Unknown 12 | self.writeVInt(50) # Unknown 13 | self.writeVInt(999900) # Unknown 14 | 15 | self.writeVInt(0) 16 | for x in range(0): 17 | self.writeVInt(x) 18 | 19 | LogicEventData.encode(self) 20 | 21 | LogicShopData.encodeShopPacks(self) 22 | 23 | self.writeVInt(0) # Unknown 24 | self.writeVInt(200) # Max Tokens 25 | self.writeVInt(20) # Plus Tokens 26 | self.writeVInt(0) # Unknown 27 | self.writeVInt(10) # Unknown 28 | self.writeVInt(0) # Unknown 29 | self.writeVInt(0) # Unknown 30 | self.writeVInt(0) # Unknown 31 | self.writeVInt(0) # Unknown 32 | self.writeUInt8(1) # Shop Box State 33 | 34 | self.writeVInt(0) # Unknown Array 35 | for x in range(0): 36 | # ReleaseEntry::encode 37 | self.writeDataReference(16,0) 38 | self.writeInt(99999) 39 | self.writeInt(0) 40 | 41 | self.writeVInt(1) # Menu Theme Array 42 | for x in range(1): 43 | # IntValueEntry::encode 44 | self.writeInt(1) # Unknown 45 | self.writeInt(41000000 + self.player.theme_id) # Theme ID 46 | 47 | self.writeVInt(0) 48 | for x in range(0): 49 | # CustomEvent::encode 50 | self.writeVInt(0) 51 | self.writeVInt(0) 52 | self.writeVInt(0) 53 | self.writeVInt(0) 54 | 55 | 56 | self.writeVInt(0) 57 | for x in range(0): 58 | self.writeVInt(0) 59 | self.writeVInt(0) 60 | for x in range(3): 61 | self.writeInt(0) 62 | self.writeStringReference('') 63 | -------------------------------------------------------------------------------- /GameAssets/csv_client/credits.csv: -------------------------------------------------------------------------------- 1 | "Name",0 2 | "String","int" 3 | "Santtu Ahola", 4 | "Patrick Almgren", 5 | "Chris Bancroft", 6 | "Mauritz Bart", 7 | "Brad Bolinder", 8 | "Javier Calvo", 9 | "Paul Chambers", 10 | "Dalei Chen", 11 | "Liang Chen", 12 | "Xuhui Chen", 13 | "David Diaz", 14 | "Jason Dou", 15 | "Praveen Dubey", 16 | "Chris Duong", 17 | "Anders Ehrenborg", 18 | "James Ellis", 19 | "Jon Franzas", 20 | "Laura Gilliland", 21 | "Eero Harmaala", 22 | "Stefan Hauk", 23 | "Mikko Hokkanen", 24 | "Chih-Han Hsu", 25 | "Juha Huotari", 26 | "Aki Immonen", 27 | "Kim Jensen", 28 | "Tomi Joki-Korpela", 29 | "Pauli Kaila", 30 | "Robert Kamphuis", 31 | "Bill Kang", 32 | "Minyoung Kang", 33 | "Frank Keienburg", 34 | "Matti Kemppainen", 35 | "WooHyun Kim", 36 | "Terje Koskinen", 37 | "Byeongmin Kwon", 38 | "Petri Kärkäs", 39 | "Mikko Laakkio", 40 | "Christina Lee", 41 | "Jimmy Lee", 42 | "Mikko Lehtonen", 43 | "Juha Leinonen", 44 | "Ryan Lighton", 45 | "Janne Lindholm", 46 | "Agnes Liou", 47 | "Chen Liu", 48 | "Phillip Lockwood", 49 | "Jonne Loikkanen", 50 | "Frieda Ma", 51 | "Damien Mabin", 52 | "Lauri Manninen", 53 | "Antti Mattila", 54 | "Doug McCracken", 55 | "Daniel Medeiros", 56 | "Jani Mensonen", 57 | "Yukiko Morishita", 58 | "Jumpei Oki", 59 | "Taneli Oksama", 60 | "Jeff Ostler", 61 | "Janne Peltola", 62 | "Asko Puurula", 63 | "Miika Pylkkö", 64 | "Brianne Read", 65 | "Antti Ripatti", 66 | "Martin Schjøler", 67 | "Mika Seppä", 68 | "Mikko Sivulainen", 69 | "Shawn Su", 70 | "Antti Summala", 71 | "Qianyue Sun", 72 | "Tommi Suvinen", 73 | "Nelly Sääksjärvi", 74 | "Antti Takala", 75 | "Touko Tahkokallio", 76 | "Erol Tekkanat", 77 | "Ella-Roosa Tenhunen", 78 | "Emily Tierney", 79 | "Wilhelm Tigerstedt", 80 | "Ricardo Tomé", 81 | "Jouni Utriainen", 82 | "Jerry Vahn", 83 | "Antti Varila", 84 | "Félix Vivier", 85 | "Slava Volkov", 86 | "Kustaa Vuori", 87 | "Jaakko Väyrynen", 88 | "Toshizumi Waki", 89 | "Ryan Wener", 90 | "Julie Woo", 91 | "Choong Yoon", 92 | "Junheng Zang", 93 | "Oscar Zhang", 94 | "Jean Zoch", 95 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/TeamMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | from Utils.Helpers import Helpers 3 | 4 | class TeamMessage(Writer): 5 | 6 | def __init__(self, client, player): 7 | super().__init__(client) 8 | self.id = 24124 9 | self.player = player 10 | 11 | def encode(self): 12 | self.writeVInt(1) 13 | self.writeUInt8(0) 14 | self.writeVInt(1) 15 | self.writeLong(Helpers().randomMapID()) 16 | self.writeUInt8(0) 17 | self.writeUInt8(0) 18 | self.writeVInt(0) 19 | self.writeVInt(0) 20 | 21 | self.writeDataReference(15, self.player.map_id) 22 | 23 | self.writeVInt(1) 24 | for x in range(1): 25 | 26 | self.writeVInt(1) 27 | 28 | self.writeLong(self.player.ID) 29 | 30 | self.writeDataReference(16, self.player.home_brawler) 31 | self.writeDataReference(29, self.player.home_skin) 32 | 33 | self.writeVInt(99999) 34 | self.writeVInt(99999) 35 | self.writeVInt(10) 36 | 37 | self.writeVInt(3) 38 | self.writeVInt(0) 39 | self.writeVInt(0) 40 | self.writeVInt(0) 41 | self.writeVInt(0) 42 | 43 | self.writeString(self.player.name) 44 | self.writeVInt(100) 45 | self.writeVInt(28000000 + self.player.profile_icon) 46 | self.writeVInt(43000000 + self.player.name_color) 47 | self.writeNullVInt() 48 | 49 | self.writeDataReference(23, self.player.starpower) if self.player.starpower != None else self.writeVInt(0) 50 | self.writeDataReference(23, self.player.gadget) if self.player.gadget != None else self.writeVInt(0) 51 | 52 | self.writeVInt(0) 53 | for x in range(0): 54 | pass 55 | 56 | self.writeVInt(0) 57 | for x in range(0): 58 | pass 59 | 60 | self.writeUInt8(0) 61 | if self.player.use_gadget: 62 | self.writeUInt8(6) 63 | else: 64 | self.writeUInt8(0) 65 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/globals.csv: -------------------------------------------------------------------------------- 1 | "Name","NumberValue","BooleanValue","TextValue","StringArray","NumberArray" 2 | "String","int","boolean","string","String","int" 3 | "ALLIANCE_CREATE_RESOURCE",,,"Gold",, 4 | "ALLIANCE_CREATE_COST",0,,,, 5 | "STARTING_DIAMONDS",0,,,, 6 | "MAX_MESSAGE_LENGTH",128,,,, 7 | "MAX_ALLIANCE_MAIL_LENGTH",256,,,, 8 | "SPEED_UP_DIAMOND_COST_1_MIN",1,,,, 9 | "SPEED_UP_DIAMOND_COST_1_HOUR",4,,,, 10 | "SPEED_UP_DIAMOND_COST_24_HOURS",96,,,, 11 | "SPEED_UP_DIAMOND_COST_1_WEEK",672,,,, 12 | "SPEED_UP_FREE_SECONDS",0,,,, 13 | "RESOURCE_DIAMOND_COST_1",1,,,, 14 | "RESOURCE_DIAMOND_COST_10",2,,,, 15 | "RESOURCE_DIAMOND_COST_100",20,,,, 16 | "RESOURCE_DIAMOND_COST_1000",200,,,, 17 | "RESOURCE_DIAMOND_COST_10000",2000,,,, 18 | "RESOURCE_DIAMOND_COST_100000",20000,,,, 19 | "RESOURCE_DIAMOND_COST_1000000",200000,,,, 20 | "RESOURCE_DIAMOND_COST_10000000",2000000,,,, 21 | "ALLIANCE_SCORE_CONTRIBUTION_PERCENTAGE",,,,,50 22 | ,,,,,25 23 | ,,,,,12 24 | ,,,,,10 25 | ,,,,,3 26 | "STARTING_GOLD",0,,,, 27 | "BATTLE_PING_SAMPLE_SECONDS",15,,,, 28 | "ALLIANCE_UNLOCK_EXP_LEVEL",1,,,, 29 | "AFK_TIMER_SECONDS",15,,,, 30 | "BOSS_DAMAGE_PERCENT_INCREASE",50,,,, 31 | "BOSS_PET_DAMAGE_PERCENT_INCREASE",20,,,, 32 | "BOSS_HEALTH_INCREASE_FIXED",40000,,,, 33 | "BOSS_HEALTH_INCREASE_PERCENT",800,,,, 34 | "BOSS_SPEED_INCREASE",100,,,, 35 | "BOSS_RELOAD_TIME_DIV",20,,,, 36 | "BOSS_PET_HEALTH_INCREASE_PERCENT",20,,,, 37 | "BOSS_ULTI_CHARGE_MUL",60,,,, 38 | "BOSS_ULTI_CHARGE_DIV",100,,,, 39 | "BOSS_HEAL_MUL",10,,,, 40 | "BOSS_HEAL_DIV",100,,,, 41 | "COOP_ULTI_CHARGE_MUL",30,,,, 42 | "COOP_ULTI_CHARGE_DIV",100,,,, 43 | "MAX_CORPSES_PER_TEAM",10,,,, 44 | "USE_MASK",,"false",,, 45 | "DISPLAY_JOYSTICK_AREA",,"true",,, 46 | "VISIBILITY_X",43,,,, 47 | "VISIBILITY_UP",33,,,, 48 | "VISIBILITY_DOWN",28,,,, 49 | "VISIBILITY_HORIZONTAL_MARGIN",6,,,, 50 | "VISIBILITY_VERTICAL_MARGIN_1",18,,,, 51 | "VISIBILITY_VERTICAL_MARGIN_2",26,,,, 52 | "STARTING_HERO_LVL_UP_MATERIAL",100,,,, 53 | "TRANSFORM_FREE_BOX_TO_AD_BOX",,"false",,, 54 | "VAMPIRES_HEAL_MUL",25,,,, 55 | "VAMPIRES_HEAL_DIV",100,,,, 56 | "EMOTE_COOLDOWN_TICKS",200,,,, 57 | "EMOTE_COOLDOWN_TICKS_MATCH_END",60,,,, 58 | "CHINA_BOX_LIMIT",25,,,, 59 | "OFFLINE_RAID_DIFFICULTY",1,,,, 60 | "DEVICE_LINK_CODE_LENGTH",12,,,, 61 | "DEVICE_LINK_CODE_VALID_SECONDS",120,,,, 62 | -------------------------------------------------------------------------------- /Files/CsvLogic/Cards.py: -------------------------------------------------------------------------------- 1 | from Files.CsvReader import CsvReader 2 | 3 | class Cards: 4 | def get_spg_id(self): 5 | CardSkillsID = [] 6 | reader = CsvReader() 7 | rowData = reader.readCsv('GameAssets/csv_logic/cards.csv') 8 | for row in rowData: 9 | if row[6].lower() == '4' or row[6].lower() == '5': 10 | CardSkillsID.append(rowData.index(row)) 11 | return CardSkillsID 12 | 13 | 14 | def check_spg_id(self, id): 15 | reader = CsvReader() 16 | rowData = reader.readCsv('GameAssets/csv_logic/cards.csv') 17 | for row in rowData: 18 | if rowData.index(row) == id: 19 | return row[6].lower() 20 | 21 | 22 | def get_brawler_unlock(self): 23 | CardUnlockID = [] 24 | reader = CsvReader() 25 | rowData = reader.readCsv('GameAssets/csv_logic/cards.csv') 26 | for row in rowData: 27 | if row[6].lower() == '0': 28 | CardUnlockID.append(rowData.index(row)) 29 | return CardUnlockID 30 | 31 | 32 | def get_spg_by_brawler_id(self, brawler_id, type): 33 | reader = CsvReader() 34 | charsData = reader.readCsv('GameAssets/csv_logic/characters.csv') 35 | cardsData = reader.readCsv('GameAssets/csv_logic/cards.csv') 36 | for row in charsData: 37 | if charsData.index(row) == brawler_id: 38 | name = row[0] 39 | for row in cardsData: 40 | if type == 4: 41 | if row[6].lower() == '4' and row[3] == name: 42 | return cardsData.index(row) 43 | elif type == 5: 44 | if row[3] == name and row[6].lower() == '5': 45 | return cardsData.index(row) 46 | 47 | 48 | 49 | def get_unlock_by_brawler_id(self, brawler_id): 50 | reader = CsvReader() 51 | charsData = reader.readCsv('GameAssets/csv_logic/characters.csv') 52 | cardsData = reader.readCsv('GameAssets/csv_logic/cards.csv') 53 | for row in charsData: 54 | if charsData.index(row) == brawler_id: 55 | name = row[0] 56 | for row in cardsData: 57 | if row[6].lower() == '0' and row[3] == name: 58 | return cardsData.index(row) 59 | -------------------------------------------------------------------------------- /Protocol/Messages/Client/CreateAllianceMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Utils.Helpers import Helpers 3 | from Protocol.Messages.Server.MyAllianceMessage import MyAllianceMessage 4 | from Protocol.Messages.Server.AllianceResponseMessage import AllianceResponseMessage 5 | from Protocol.Messages.Server.AllianceDataMessage import AllianceDataMessage 6 | 7 | 8 | class CreateAllianceMessage(Reader): 9 | def __init__(self, client, player, initial_bytes): 10 | super().__init__(initial_bytes) 11 | self.player = player 12 | self.client = client 13 | 14 | def decode(self): 15 | self.club_name = self.readString() 16 | self.club_desc = self.readString() 17 | self.club_badge = self.readDataReference()[1] 18 | self.club_region = self.readDataReference()[1] 19 | self.club_type = self.readVInt() 20 | self.club_req_trophies = self.readVInt() 21 | self.club_family_friendly = self.readVInt() 22 | 23 | def process(self, db): 24 | data = { 25 | "Name": self.club_name, 26 | "Description": self.club_desc, 27 | "Region": self.club_region, 28 | "BadgeID": self.club_badge, 29 | "Type": self.club_type, 30 | "Trophies": self.player.trophies, 31 | "RequiredTrophies": self.club_req_trophies, 32 | "FamilyFriendly": self.club_family_friendly, 33 | "Members": [ 34 | { 35 | 'Name': self.player.name, 36 | 'ID': self.player.ID, 37 | 'Role': 2, 38 | 'Trophies': self.player.trophies, 39 | 'ProfileIcon': self.player.profile_icon, 40 | 'NameColor': self.player.name_color 41 | } 42 | ], 43 | "Messages": [] 44 | } 45 | 46 | self.player.club_id = Helpers.randomID(self) 47 | self.player.club_role = 2 48 | 49 | db.create_club(self.player.club_id, data) 50 | db.update_player_account(self.player.token, 'ClubID', self.player.club_id) 51 | db.update_player_account(self.player.token, 'ClubRole', self.player.club_role) 52 | 53 | club_data = db.load_club(self.player.club_id) 54 | 55 | MyAllianceMessage(self.client, self.player, club_data).send() 56 | AllianceResponseMessage(self.client, self.player, 20).send() 57 | AllianceDataMessage(self.client, self.player, club_data).send() 58 | 59 | -------------------------------------------------------------------------------- /GameAssets/csv_client/local_notifications.csv: -------------------------------------------------------------------------------- 1 | "Name","Priority","NotificationText","IsRegularEventRefresh","DontCompare","AutoAdd","TimeOffsetMins","MaxRandomTimeOffsetMins","CheckRangeMins" 2 | "String","int","String","boolean","boolean","boolean","int","int","int" 3 | "CCStart",10000,"TID_NOTIFICATION_CC_STARTED",,,,15,60,0 4 | "CCReminder",10000,"TID_NOTIFICATION_CC_ENDING",,,,-600,60,0 5 | "PSGStart",10000,"TID_NOTIFICATION_PSG_STARTED",,,,15,60,0 6 | "PSGReminder",10000,"TID_NOTIFICATION_PSG_ENDING",,,,-600,60,0 7 | "CoinRushStart",2,"TID_NOTIFICATION_COIN_RUSH","TRUE",,,30,30,0 8 | "AttackDefendStart",5,"TID_NOTIFICATION_ATTACK_DEFEND","TRUE",,,15,30,0 9 | "BountyStart",5,"TID_NOTIFICATION_BOUNTY_HUNTER","TRUE",,,15,30,0 10 | "LaserBallStart",2,"TID_NOTIFICATION_LASER_BALL","TRUE",,,15,30,0 11 | "BRStart",2,"TID_NOTIFICATION_BATTLE_ROYAL","TRUE",,,15,30,0 12 | "BossStart",1000,"TID_NOTIFICATION_BOSS",,,,60,60,0 13 | "CoopStart",1000,"TID_NOTIFICATION_COOP",,,,60,60,0 14 | "RaidBossStart",1000,"TID_NOTIFICATION_RAID_BOSS",,,,60,60,0 15 | "RoboWarsStart",1000,"TID_NOTIFICATION_ROBO_WARS",,,,15,30,0 16 | "TakedownStart",3,"TID_NOTIFICATION_BOSS_RACE","TRUE",,,15,30,0 17 | "LoneStarStart",3,"TID_NOTIFICATION_LONE_STAR","TRUE",,,15,30,0 18 | "CTFStart",3,"TID_NOTIFICATION_CTF","TRUE",,,15,30,0 19 | "KOHStart",5,"TID_NOTIFICATION_KING_OF_HILL","TRUE",,,15,30,0 20 | "MultipleModesStart",10,"TID_NOTIFICATION_MULTIPLE_MODES",,,,15,30,0 21 | "FreeBox",1,"TID_FREE_BOX_AVAILABLE_0",,,,60,30,120 22 | ,,"TID_FREE_BOX_AVAILABLE_1",,,,,, 23 | ,,"TID_FREE_BOX_AVAILABLE_2",,,,,, 24 | ,,"TID_FREE_BOX_AVAILABLE_3",,,,,, 25 | ,,"TID_FREE_BOX_AVAILABLE_4",,,,,, 26 | "SeasonEnd",2000,"TID_SEASON_ENDED_NOTI",,,,30,60, 27 | "KeyBarFull",100000,"TID_KEY_BAR_FULL",,"TRUE",,,, 28 | "ComeBackSmall",1,"TID_COME_BACK_NOTIFICATION_SMALL",,,"TRUE",2880,,1440 29 | "ComeBackMedium",1,"TID_COME_BACK_NOTIFICATION_MEDIUM",,,"TRUE",7200,,1440 30 | "ComeBackLarge",1,"TID_COME_BACK_NOTIFICATION_LARGE",,,"TRUE",14400,,1440 31 | "PPRefresh",500,"TID_POWER_PLAY_NOTIFICATION",,,,15,30,0 32 | "NewBrawler",50000,"TID_NOTIFICATION_NEW_BRAWLER",,,,,30,0 33 | "DoubleTokens",1500,"TID_NOTIFICATION_DOUBLE_TOKENS_STARTED",,,,,30,0 34 | "DoubleCoins",1500,"TID_NOTIFICATION_DOUBLE_COINS_STARTED",,,,,30,0 35 | "BPSeasonStart",50000,"TID_NOTIFICATION_BP_SEASON_STARTED",,,,,30, 36 | "BPSeasonReminder",50000,"TID_NOTIFICATION_BP_SEASON_ENDING",,,,-7200,30, 37 | "QuestBatch",750,"TID_NOTIFICATION_QUEST_REFRESH",,,,,30,60 38 | "TownCrusherStart",1000,"TID_NOTIFICATION_TOWN_CRUSHER",,,,60,60,0 39 | -------------------------------------------------------------------------------- /Patcher/Lib/ATPatchmaker.py: -------------------------------------------------------------------------------- 1 | import os 2 | import hashlib 3 | import json 4 | import datetime 5 | import random 6 | import shutil 7 | from LZMA import compress 8 | 9 | def _(*args): 10 | print('[INFO]', end=' ') 11 | for arg in args: 12 | print(arg, end=' ') 13 | print() 14 | 15 | 16 | def Make(): 17 | backup = os.getcwd() 18 | 19 | def FP(arg: str) -> str: # get filename in like fingerprint.json 20 | return arg.replace("\\", r"\/").replace("Gamefiles\\/", "") 21 | 22 | def iterate_over(path: str) -> list: # get all subfiles and files 23 | r = [] 24 | for root, dirs, files in os.walk(path, topdown=False): 25 | for name in files: 26 | if name != 'fingerprint.json': 27 | r.append(os.path.join(root, name)) 28 | return r 29 | 30 | def shash(inp) -> str: # get hash sha1 31 | hash_object = hashlib.sha1(inp) 32 | pbHash = hash_object.hexdigest() 33 | return pbHash 34 | 35 | def MasterHasher(): 36 | time = str(int(datetime.datetime.timestamp(datetime.datetime.now()))) 37 | by = shash(time.encode()).encode() 38 | return by 39 | 40 | MH = MasterHasher().decode() 41 | base = '''{ "files": [], 42 | "sha": "''' + MH + '",' + ''' 43 | "version": "''' + "26.165." + str(random.randint(1, 9)) + '"}' 44 | 45 | out = json.loads(base) 46 | 47 | _(f'MasterHash is {MH}\n') 48 | 49 | all_file = iterate_over("Gamefiles") 50 | 51 | for file in all_file: 52 | _(f'Processing {file} ...') 53 | 54 | if file.endswith('.csv'): 55 | file_cont = compress(open(file, "rb").read()) 56 | else: 57 | file_cont = open(file, "rb").read() 58 | 59 | sha = shash(file_cont) 60 | out["files"].append({"file": FP(file), "sha": sha}) 61 | 62 | 63 | os.chdir("Patchs") 64 | shutil.copytree(backup + "/Gamefiles", os.getcwd() + f"/{MH}") 65 | os.chdir(MH) # mode write doesnt create file unless this 66 | 67 | all_file = iterate_over('./') 68 | 69 | for file in all_file: 70 | if file.endswith('.csv'): 71 | file_cont = compress(open(file, "rb").read()) 72 | 73 | with open(file, "wb") as new_file: 74 | new_file.write(file_cont) 75 | new_file.close() 76 | else: 77 | _(f"Skipping compression for {file}") 78 | pass 79 | 80 | 81 | json_out = open("fingerprint.json", "w") 82 | json_out.write(str(out).replace("'", '"').replace("\\\\", "\\")) # WRITE fingerprint.json 83 | json_out.close() -------------------------------------------------------------------------------- /Protocol/Messages/Server/BattleEndMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | 4 | class BattleEndMessage(Writer): 5 | 6 | def __init__(self, client, player, type, result, players): 7 | super().__init__(client) 8 | self.id = 23456 9 | self.player = player 10 | self.type = type 11 | self.result = result 12 | self.players = players 13 | 14 | def encode(self): 15 | self.writeVInt(self.type) 16 | self.writeVInt(self.result) 17 | self.writeVInt(0) 18 | self.writeVInt(0) 19 | 20 | self.writeVInt(0) 21 | self.writeVInt(0) 22 | self.writeVInt(0) 23 | self.writeVInt(0) 24 | 25 | self.writeVInt(0) 26 | self.writeVInt(0) 27 | self.writeVInt(0) 28 | self.writeVInt(0) 29 | 30 | self.writeVInt(0) 31 | self.writeVInt(0) 32 | self.writeVInt(0) 33 | self.writeVInt(1) 34 | 35 | self.writeVInt(0) 36 | self.writeVInt(32) 37 | self.writeVInt(0) 38 | self.writeVInt(1) 39 | 40 | self.writeVInt(len(self.players)) 41 | 42 | for player in self.players: 43 | self.brawler = self.players[player]['Brawler'] 44 | self.skin = self.players[player]['Skin'] 45 | self.team = self.players[player]['Team'] 46 | self.username = self.players[player]['Name'] 47 | 48 | if self.type == 5: 49 | if self.team == 0: 50 | self.writeVInt(player) 51 | else: 52 | self.writeVInt(2) 53 | 54 | elif self.type == 2: 55 | if self.team != 0: 56 | self.writeVInt(2 if self.team != 0 else 1) 57 | 58 | else: 59 | self.writeVInt(self.team if self.team != 1 else 2) 60 | 61 | # 5 - player, 62 | self.writeDataReference(16, self.brawler)if self.brawler != -1 else self.writeVInt(0) 63 | self.writeDataReference(29, self.skin) if self.skin != -1 else self.writeVInt(0) 64 | 65 | self.writeVInt(99999) 66 | self.writeVInt(99999) 67 | self.writeVInt(10) 68 | 69 | self.writeBool(False) 70 | 71 | # sub_64DF74 72 | self.writeString(self.username) 73 | self.writeVInt(100) 74 | self.writeVInt(28000000) 75 | self.writeVInt(43000000) 76 | self.writeNullVInt() 77 | 78 | self.writeBool(False) 79 | self.writeBool(False) 80 | self.writeBool(False) 81 | 82 | self.writeDataReference(28, 0) 83 | 84 | self.writeBool(False) -------------------------------------------------------------------------------- /Protocol/Messages/Server/LeaderboardMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | 3 | class LeaderboardMessage(Writer): 4 | 5 | def __init__(self, client, player, data): 6 | super().__init__(client) 7 | self.id = 24403 8 | self.player = player 9 | self.data = data 10 | 11 | def encode(self): 12 | self.writeVInt(self.player.leaderboard_type) 13 | self.writeVInt(0) 14 | self.writeVInt(0) 15 | self.writeString() 16 | 17 | if self.player.leaderboard_type == 1: 18 | 19 | self.writeVInt(len(self.data)) 20 | 21 | for entry in self.data: 22 | 23 | self.writeLogicLong(entry['ID']) 24 | self.writeVInt(1) 25 | self.writeVInt(entry['Trophies']) 26 | 27 | self.writeVInt(1) 28 | self.writeString() 29 | self.writeString(entry['Name']) 30 | 31 | self.writeVInt(9) 32 | self.writeVInt(28000000 + entry['ProfileIcon']) 33 | self.writeVInt(43000000 + entry['NameColor']) 34 | if self.player.bp_activated: 35 | self.writeVInt(43000000 + entry['NameColor']) 36 | else: 37 | self.writeNullVInt() 38 | self.writeVInt(0) 39 | 40 | self.writeVInt(0) 41 | 42 | check = False 43 | 44 | for entry in self.data: 45 | if entry['ID'] == self.player.ID: 46 | self.writeVInt(self.data.index(entry) + 1) 47 | check = True 48 | 49 | if not check: 50 | self.writeVInt(0) 51 | 52 | 53 | elif self.player.leaderboard_type == 2: 54 | self.writeVInt(len(self.data)) 55 | 56 | for entry in self.data: 57 | 58 | self.writeLogicLong(entry['ID']) 59 | self.writeVInt(1) 60 | self.writeVInt(entry['Trophies']) 61 | self.writeVInt(2) 62 | self.writeString(entry['Name']) 63 | self.writeVInt(len(entry['Members'])) 64 | self.writeDataReference(8, entry['BadgeID']) 65 | 66 | self.writeVInt(0) 67 | 68 | check = False 69 | 70 | for x in self.data: 71 | if x['ID'] == self.player.club_id: 72 | self.writeVInt(self.data.index(x) + 1) 73 | check = True 74 | 75 | if not check: 76 | self.writeVInt(0) 77 | 78 | 79 | self.writeVInt(0) 80 | self.writeVInt(0) 81 | 82 | self.writeString(self.player.region) 83 | 84 | 85 | -------------------------------------------------------------------------------- /GameAssets/csv_client/music.csv: -------------------------------------------------------------------------------- 1 | Name,FileName,Volume,Loop,PlayCount,FadeOutTimeSec,DurationSec 2 | String,String,int,boolean,int,int,int 3 | BattleMusic,music/Slugfest_ingame_01.ogg,70,true,,,60 4 | ,music/Slugfest_ingame_03.ogg,70,true,,,90 5 | ,music/Slugfest_ingame_06.ogg,70,true,,,75 6 | Footbrawl_ingame_muzak,music/footbrawl_ingame_muzak_01.ogg,70,true,,,59 7 | Footbrawl_menu_muzak,music/footbrawl_menu_muzak_01.ogg,60,true,,,70 8 | Brawzaar_menu_muzak,music/brawzaar_menu_01.ogg,60,true,,,126 9 | Monsterbrawl_menu_muzak,music/bm_menu_01.ogg,60,true,,,68 10 | Monsterbrawl_ingame_muzak,music/bm_ingame_01.ogg,70,true,,,70 11 | ,music/big_brawl_battle_02.ogg,70,true,,,53 12 | Monsterbrawl_boss,music/brawlzilla_boss_01.ogg,70,true,,,48 13 | Brawzaar_ingame_muzak,music/brawzaar_ingame_01.ogg,70,true,,,59 14 | ,music/brawzaar_ingame_02.ogg,70,true,,,63 15 | Snow_brawl,music/Snow_brawl_01.ogg,70,true,,,57 16 | ,music/Snow_brawl_02.ogg,70,true,,,65 17 | ,music/Snow_brawl_03.ogg,70,true,,,57 18 | Cny_levels,music/cny_ingame_01.ogg,70,true,,,64 19 | ,music/cny_ingame_02.ogg,70,true,,,56 20 | Retropolis_battle,music/retro_brawl_ingame_01.ogg,70,true,,,55 21 | Retropolis_menu,music/brawl_retro_menu_01.ogg,60,true,,,66 22 | Halloween_menu,music/brawloween_menu_01.ogg,60,true,,,80 23 | Halloween_ingame,music/brawloween_ingame_02.ogg,70,true,,,56 24 | Brawlcade_Menu,music/brawlcade_menu_01.ogg,60,true,,,57 25 | Brawlcade_Ingame,music/brawlcade_ingame_01.ogg,70,true,,,57 26 | ,music/brawlcade_ingame_02.ogg,70,true,,,62 27 | Xmas_Pirate_Menu,music/brawl_pirate_menu_01.ogg,60,true,,,67 28 | Pirate_Brawl_Ingame,music/pirate_brawl_ingame_01.ogg,70,true,,,63 29 | MenuMusic,music/brawl_stars_menu_01.ogg,60,true,,,153 30 | MechMenuMusic,music/mech_menu_01.ogg,60,true,,,78 31 | Cnymenu_music,music/cny_brawl_menu_01.ogg,60,true,,,178 32 | Brawl_royale_menu_music,music/royale_brawl_menu_01.ogg,60,true,,,91 33 | Brawl_dawgs_menu,music/brawl_dawgs_menu_01.ogg,60,true,,,95 34 | 10th_Anniversary_Menu,music/brawl_original_menu_01.ogg,60,true,,,124 35 | WinJingle,music/slugfest_game_won_01.ogg,80,,1,, 36 | LoseJingle,music/slugfest_game_lost_01.ogg,70,,1,, 37 | DrawJingle,music/laser_game_draw_01.ogg,70,,1,, 38 | Win_loop,music/win_screen_loop_4x_01.ogg,60,true,,,30 39 | Draw_loop,music/draw_screen_loop_4x_01.ogg,60,true,,,34 40 | Lose_loop,music/lose_screen_loop_4x_01.ogg,60,true,,,28 41 | Brawlbawl_goal,music/brawl_goal_02.ogg,80,,1,, 42 | Brawlbawl_other_goal,music/brawl_other_goal_01.ogg,80,,1,, 43 | 30_sec_panic,music/brawl_panic_time_01.ogg,75,true,,,30 44 | Brawl_xmas_flag_win,music/brawl_xmas_flag_win_01.ogg,70,,1,, 45 | Brawl_xmas_flag_lose,music/brawl_xmas_flag_lose_01.ogg,70,,1,, 46 | -------------------------------------------------------------------------------- /Protocol/Messages/Server/PlayerProfileMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Writer import Writer 2 | from Files.CsvLogic.Regions import Regions 3 | from Logic.Avatar.LogicPlayerStats import LogicPlayerStats 4 | 5 | 6 | class PlayerProfileMessage(Writer): 7 | 8 | def __init__(self, client, player, player_data, db): 9 | super().__init__(client) 10 | self.id = 24113 11 | self.player = player 12 | self.player_data = player_data 13 | self.db = db 14 | 15 | def encode(self): 16 | self.writeLogicLong(self.player_data['ID']) 17 | 18 | self.writeDataReference(0, 0) 19 | 20 | self.writeVInt(len(self.player_data['UnlockedBrawlers'])) 21 | for x in self.player_data['UnlockedBrawlers']: 22 | # HeroEntry::encode 23 | self.writeDataReference(16, x) 24 | self.writeDataReference(0, 0) 25 | self.writeVInt(self.player_data['BrawlersTrophies'][str(x)]) 26 | self.writeVInt(self.player_data['BrawlersHighestTrophies'][str(x)]) 27 | self.writeVInt(self.player_data['BrawlersLevel'][str(x)] + 2) 28 | 29 | self.playerStats = LogicPlayerStats.getPlayerStats(self, self.player_data) 30 | 31 | self.writeVInt(len(self.playerStats)) 32 | for x in self.playerStats: 33 | self.writeVInt(list(self.playerStats.keys()).index(x) + 1) 34 | self.writeVInt(self.playerStats[x]) 35 | 36 | # PlayerDisplayData::encode 37 | self.writeString(self.player_data['Name']) 38 | self.writeVInt(100) # Unknown 39 | self.writeVInt(28000000 + self.player_data['ProfileIcon']) 40 | self.writeVInt(43000000 + self.player_data['NameColor']) 41 | if self.player.bp_activated: 42 | self.writeVInt(43000000 + self.player_data['NameColor']) 43 | else: 44 | self.writeNullVInt() 45 | 46 | if self.player_data['ClubID'] != 0: 47 | club_data = self.db.load_club(self.player_data['ClubID']) 48 | 49 | self.writeBoolean(True) 50 | self.writeLong(club_data['ID']) 51 | self.writeString(club_data['Name']) 52 | self.writeDataReference(8, club_data['BadgeID']) 53 | self.writeVInt(club_data['Type']) 54 | self.writeVInt(len(club_data['Members'])) 55 | self.writeVInt(club_data['Trophies']) 56 | self.writeVInt(club_data['RequiredTrophies']) 57 | self.writeDataReference(0, 0) 58 | self.writeString(Regions().get_region_string(club_data['Region'])) 59 | self.writeVInt(0) 60 | self.writeUInt8(0) 61 | self.writeDataReference(25, self.player_data['ClubRole']) 62 | 63 | else: 64 | self.writeBoolean(False) 65 | self.writeVInt(0) -------------------------------------------------------------------------------- /Protocol/Messages/Client/LoginMessage.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Utils.Helpers import Helpers 3 | from Protocol.Messages.Server.LoginOkMessage import LoginOkMessage 4 | from Protocol.Messages.Server.LoginFailedMessage import LoginFailedMessage 5 | from Protocol.Messages.Server.OwnHomeDataMessage import OwnHomeDataMessage 6 | from Protocol.Messages.Server.MyAllianceMessage import MyAllianceMessage 7 | from Protocol.Messages.Server.AllianceStreamMessage import AllianceStreamMessage 8 | 9 | 10 | class LoginMessage(Reader): 11 | def __init__(self, client, player, initial_bytes): 12 | super().__init__(initial_bytes) 13 | self.player = player 14 | self.client = client 15 | self.helpers = Helpers() 16 | 17 | def decode(self): 18 | 19 | self.account_id = self.readLong() 20 | self.account_token = self.readString() 21 | self.game_major = self.readInt() 22 | self.game_minor = self.readInt() 23 | self.game_build = self.readInt() 24 | 25 | self.fingerprint_sha = self.readString() 26 | 27 | 28 | def process(self, db): 29 | 30 | if self.player.maintenance: 31 | self.player.err_code = 10 32 | LoginFailedMessage(self.client, self.player, '').send() 33 | 34 | if self.fingerprint_sha != self.player.patch_sha and self.player.patch: 35 | self.player.err_code = 7 36 | LoginFailedMessage(self.client, self.player, "").send() 37 | 38 | if self.account_id == 0: 39 | self.player.ID = self.helpers.randomID() 40 | self.player.token = self.helpers.randomToken() 41 | db.create_player_account(self.player.ID, self.player.token) 42 | 43 | else: 44 | self.player.ID = self.account_id 45 | self.player.token = self.account_token 46 | 47 | player_data = db.load_player_account(self.player.ID, self.player.token) 48 | 49 | if player_data: 50 | Helpers.load_account(self, player_data) 51 | club_data = db.load_club(self.player.club_id) 52 | Helpers.load_club(self, club_data) 53 | else: 54 | self.player.err_code = 1 55 | LoginFailedMessage(self.client, self.player, "Account not found in database!\nPlease clear app data.").send() 56 | 57 | 58 | LoginOkMessage(self.client, self.player, self.player.ID, self.player.token).send() 59 | OwnHomeDataMessage(self.client, self.player).send() 60 | 61 | if self.player.club_id != 0: 62 | club_data = db.load_club(self.player.club_id) 63 | MyAllianceMessage(self.client, self.player, club_data).send() 64 | AllianceStreamMessage(self.client, self.player, club_data['Messages']).send() 65 | 66 | 67 | -------------------------------------------------------------------------------- /ByteStream/Reader.py: -------------------------------------------------------------------------------- 1 | from io import BufferedReader, BytesIO 2 | 3 | 4 | class Reader(BufferedReader): 5 | def __init__(self, initial_bytes, endian: str = 'big'): 6 | super().__init__(BytesIO(initial_bytes)) 7 | self.buffer = initial_bytes 8 | self.endian = endian 9 | self.i = 0 10 | 11 | def readByte(self): 12 | return int.from_bytes(self.read(1), "big") 13 | 14 | def readVInt(self): 15 | n = self._read_varint(True) 16 | return (n >> 1) ^ (-(n & 1)) 17 | 18 | def readShort(self, length=2): 19 | return int.from_bytes(self.read(length), "big") 20 | 21 | def readInt(self, length=4): 22 | return int.from_bytes(self.read(length), "big") 23 | 24 | def readLong(self): 25 | return self.readInt(8) 26 | 27 | def readUInt8(self) -> int: 28 | return self.readUInteger() 29 | 30 | def readUInteger(self, length: int = 1) -> int: 31 | result = 0 32 | for x in range(length): 33 | byte = self.buffer[self.i] 34 | 35 | bit_padding = x * 8 36 | if self.endian == 'big': 37 | bit_padding = (8 * (length - 1)) - bit_padding 38 | 39 | result |= byte << bit_padding 40 | self.i += 1 41 | 42 | return result 43 | 44 | def _read_varint(self, rotate: bool = True): 45 | result = 0 46 | shift = 0 47 | while True: 48 | byte = self.readByte() 49 | if rotate and shift == 0: 50 | seventh = (byte & 0x40) >> 6 51 | msb = (byte & 0x80) >> 7 52 | n = byte << 1 53 | n = n & ~0x181 54 | byte = n | (msb << 7) | seventh 55 | result |= (byte & 0x7f) << shift 56 | shift += 7 57 | if not (byte & 0x80): 58 | break 59 | return result 60 | 61 | 62 | def readBool(self) -> bool: 63 | if self.readUInt8() >= 1: 64 | return True 65 | else: 66 | return False 67 | 68 | def readDataReference(self): 69 | a = self.readVInt() 70 | if a != 0: 71 | b = self.readVInt() 72 | else: 73 | b = -1 74 | return a, b 75 | 76 | def readString(self): 77 | length = self.readInt() 78 | if length == pow(2, 32) - 1: 79 | return b"" 80 | else: 81 | try: 82 | decoded = self.read(length) 83 | except MemoryError: 84 | raise IndexError("String out of range!") 85 | else: 86 | return decoded.decode('utf-8') 87 | 88 | def peekInt(self, length=4): 89 | return int.from_bytes(self.peek(length)[:length], "big") 90 | 91 | def readLogicLong(self): 92 | x = self.readVInt() 93 | y = self.readVInt() 94 | return x, y -------------------------------------------------------------------------------- /GameAssets/csv_client/tutorial.csv: -------------------------------------------------------------------------------- 1 | "Name","StepName","StartDelayMS","EndDelayMS","ForceSpeechBubbleCloseMS","StartCondition","StartLocationX","StartLocationY","StartLocationRadius","AnimationX","AnimationY","AnimationX2","AnimationY2","CompleteCondition","ShouldUseAutoShoot","CompleteLocationX","CompleteLocationY","CompleteLocationRadius","UseUltiX","UseUltiY","AnimationClipSWF","AnimationMovieClip","AnimationClipSWF2","AnimationMovieClip2","SpeechBubbleCharacterSWF","SpeechBubbleCharacterMovieClip","SpeechBubbleTIDs","StartSound","SpawnCharacter","SpawnLocationX","SpawnLocationY","CustomData","BlockingSpeechBubble","ShowUlti","ShowShootStick","LeftSpeechBubble" 2 | "string","string","int","int","int","string","int","int","int","int","int","int","int","string","boolean","int","int","int","int","int","string","string","string","string","string","string","string","string","string","int","int","int","boolean","boolean","boolean","boolean" 3 | 1,"loot_1",10000,,,"none",,,,,,,,"loot",,,,,,,,,,,"sc/ui.sc","tutorial_character_top","TID_TUTORIAL_1","Tut_speech",,,,3,,,, 4 | 2,"loot_2",0,,,"none",,,,,,,,"loot",,,,,,,,,,,"sc/ui.sc","tutorial_character_top","TID_TUTORIAL_2","Tut_speech",,,,0,,,, 5 | 3,,500,2500,,"none",,,,,,,,"none",,,,,,,,,,,"sc/ui.sc","tutorial_character_top","TID_TUTORIAL_GOOD_JOB_1","Tutorial_circle",,,,,,,, 6 | 4,,500,,,"none",,,,,,,,"none",,,,,,,,,,,,,,"Pve_wave_01","TutorialDummy",1400,3200,1,,,, 7 | 5,,300,,,"none",,,,,,,,"none",,,,,,,,,,,,,,,"TutorialDummy",2200,3200,1,,,, 8 | 6,,300,,,"none",,,,,,,,"none",,,,,,,,,,,,,,,"TutorialDummy",3000,3200,1,,,, 9 | 7,,300,,,"none",,,,,,,,"none",,,,,,,,,,,,,,,"TutorialDummy",3800,3200,1,,,, 10 | 8,"manual_shoot",1000,,,"none",,,,,,,,"kill_everything",,,,,,,,,,,"sc/ui.sc","tutorial_character_top","TID_TUTORIAL_3","Tut_speech",,,,,,,"true", 11 | 9,,500,6000,,"none",,,,,,,,"none",,,,,,,,,,,"sc/ui.sc","tutorial_character_top","TID_TUTORIAL_GOOD_JOB_2","Tutorial_circle",,,,,,,, 12 | 10,,500,,,"none",,,,,,,,"none",,,,,,,,,,,,,,"Pve_wave_01","TutorialDummy2",1400,4500,1,,,, 13 | 11,,300,,,"none",,,,,,,,"none",,,,,,,,,,,,,,,"TutorialDummy2",1900,3100,1,,,, 14 | 12,,300,,,"none",,,,,,,,"none",,,,,,,,,,,,,,,"TutorialDummy2",3000,2900,1,,,, 15 | 13,,300,,,"none",,,,,,,,"none",,,,,,,,,,,,,,,"TutorialDummy2",3800,4000,1,,,, 16 | 14,"auto_shoot",1000,,,"none",,,,,,,,"kill_everything","true",,,,,,,,,,"sc/ui.sc","tutorial_character_top","TID_TUTORIAL_5","Tut_speech",,,,,,,, 17 | 15,,500,6000,,"none",,,,,,,,"none",,,,,,,,,,,"sc/ui.sc","tutorial_character_top","TID_TUTORIAL_GOOD_JOB_3","Tutorial_circle",,,,,,,, 18 | 16,,500,,,"none",,,,,,,,"none",,,,,,,,,,,,,,"Pve_wave_01","TutorialDummy3",2600,1600,1,,,, 19 | 17,"use_ulti",1000,,,"none",,,,,,,,"use_ulti",,,,,2600,1200,,,,,"sc/ui.sc","tutorial_character_top","TID_TUTORIAL_6","Tut_speech",,,,,,"true",, 20 | 18,"click_to_end",1500,,4000,"none",,,,,,,,"none",,,,,,,,,,,"sc/ui.sc","tutorial_character_top","TID_TUTORIAL_9","Tutorial_circle",,,,,"true",,, 21 | -------------------------------------------------------------------------------- /Logic/Home/LogicShopData.py: -------------------------------------------------------------------------------- 1 | import json 2 | from datetime import datetime 3 | 4 | class LogicShopData: 5 | 6 | shop_resources = json.loads(open('shop.json', 'r').read()) 7 | 8 | gold_packs = shop_resources['GoldPacks'] 9 | gold_cost, gold_amount = [], [] 10 | 11 | for x in gold_packs: 12 | gold_cost.append(x['Cost']) 13 | gold_amount.append(x['Amount']) 14 | 15 | boxes = shop_resources['Boxes'] 16 | token_doubler = shop_resources['TokenDoubler'] 17 | 18 | offers = shop_resources['Offers'] 19 | 20 | def encodeShopPacks(self): 21 | # Unknown 22 | self.writeArrayVint([20, 35, 75, 140, 290, 480, 800, 1250]) 23 | self.writeArrayVint([1, 2, 3, 4, 5, 10, 15, 20]) 24 | # Tickets 25 | self.writeArrayVint([10, 30, 80]) 26 | self.writeArrayVint([6, 20, 60]) 27 | # Gold 28 | self.writeArrayVint(LogicShopData.gold_cost) 29 | self.writeArrayVint(LogicShopData.gold_amount) 30 | 31 | def encodeShopResources(self): 32 | time_stamp = int(datetime.timestamp(datetime.now())) 33 | 34 | self.writeVInt(time_stamp) 35 | LogicShopData.encodeBoxes(self) 36 | LogicShopData.encodeTokenDoubler(self) 37 | 38 | 39 | def encodeShopOffers(self): 40 | self.writeVInt(len(LogicShopData.offers)) 41 | for x in LogicShopData.offers: 42 | self.writeVInt(1) # array 43 | for y in range(1): 44 | self.writeVInt(x['OfferID']) 45 | self.writeVInt(x['Multiplier']) 46 | self.writeDataReference(x['DataReference'][0], x['DataReference'][1]) 47 | self.writeVInt(0) 48 | 49 | self.writeVInt(x['ShopType']) 50 | 51 | self.writeVInt(x['Cost']) 52 | self.writeVInt(x['Timer']) 53 | 54 | self.writeVInt(1) 55 | self.writeVInt(100) 56 | self.writeUInt8(0) 57 | 58 | self.writeUInt8(0) 59 | self.writeVInt(x['ShopDisplay']) 60 | self.writeUInt8(0) 61 | self.writeVInt(0) 62 | 63 | self.writeInt(0) 64 | self.writeStringReference(x['OfferText']) 65 | 66 | self.writeUInt8(0) 67 | self.writeString() 68 | self.writeVInt(0) 69 | self.writeUInt8(0) 70 | self.writeVInt(2) 71 | self.writeVInt(0) 72 | 73 | 74 | 75 | 76 | def encodeBoxes(self): 77 | self.writeVInt(100) # Tokens for 1 Brawl Box 78 | self.writeVInt(10) # Tokens for 1 Big Box 79 | 80 | self.writeVInt(LogicShopData.boxes[0]['Cost']) 81 | self.writeVInt(LogicShopData.boxes[0]['Multiplier']) 82 | 83 | self.writeVInt(LogicShopData.boxes[1]['Cost']) 84 | self.writeVInt(LogicShopData.boxes[1]['Multiplier']) 85 | 86 | 87 | def encodeTokenDoubler(self): 88 | self.writeVInt(LogicShopData.token_doubler[0]['Cost']) 89 | self.writeVInt(LogicShopData.token_doubler[0]['Amount']) 90 | -------------------------------------------------------------------------------- /Protocol/LogicLaserMessageFactory.py: -------------------------------------------------------------------------------- 1 | from Protocol.Messages.Client.EndClientTurnMessage import EndClientTurnMessage 2 | from Protocol.Messages.Client.LoginMessage import LoginMessage 3 | from Protocol.Messages.Client.KeepAliveMessage import KeepAliveMessage 4 | from Protocol.Messages.Client.SetNameMessage import SetNameMessage 5 | from Protocol.Messages.Client.TeamCreateMessage import TeamCreateMessage 6 | from Protocol.Messages.Client.TeamLeaveMessage import TeamLeaveMessage 7 | from Protocol.Messages.Client.TeamChangeMemberSettingsMessage import TeamChangeMemberSettingsMessage 8 | from Protocol.Messages.Client.TeamToggleSettingsMessage import TeamToggleSettingsMessage 9 | from Protocol.Messages.Client.TeamSetLocationMessage import TeamSetLocationMessage 10 | from Protocol.Messages.Client.GoHomeFromOfflinePractiseMessage import GoHomeFromOfflinePractiseMessage 11 | from Protocol.Messages.Client.StartGameMessage import StartGameMessage 12 | from Protocol.Messages.Client.GetPlayerProfileMessage import GetPlayerProfileMessage 13 | from Protocol.Messages.Client.GetLeaderboardMessage import GetLeaderboardMessage 14 | from Protocol.Messages.Client.SetSupportedCreatorMessage import SetSupportedCreatorMessage 15 | from Protocol.Messages.Client.AskForBattleEndMessage import AskForBattleEndMessage 16 | from Protocol.Messages.Client.AvatarNameCheckRequestMessage import AvatarNameCheckRequestMessage 17 | from Protocol.Messages.Client.CreateAllianceMessage import CreateAllianceMessage 18 | from Protocol.Messages.Client.AskForAllianceDataMessage import AskForAllianceDataMessage 19 | from Protocol.Messages.Client.ChangeAllianceSettingsMessage import ChangeAllianceSettingsMessage 20 | from Protocol.Messages.Client.JoinAllianceMessage import JoinAllianceMessage 21 | from Protocol.Messages.Client.AskForJoinableAlliancesListMessage import AskForJoinableAlliancesListMessage 22 | from Protocol.Messages.Client.LeaveAllianceMessage import LeaveAllianceMessage 23 | from Protocol.Messages.Client.SearchAlliancesMessage import SearchAlliancesMessage 24 | from Protocol.Messages.Client.ChatToAllianceStreamMessage import ChatToAllianceStreamMessage 25 | 26 | packets = { 27 | 10101: LoginMessage, 28 | 14103: StartGameMessage, 29 | 10108: KeepAliveMessage, 30 | 10212: SetNameMessage, 31 | 14102: EndClientTurnMessage, 32 | 14109: GoHomeFromOfflinePractiseMessage, 33 | 14110: AskForBattleEndMessage, 34 | 14113: GetPlayerProfileMessage, 35 | 14301: CreateAllianceMessage, 36 | 14302: AskForAllianceDataMessage, 37 | 14303: AskForJoinableAlliancesListMessage, 38 | 14305: JoinAllianceMessage, 39 | 14308: LeaveAllianceMessage, 40 | 14315: ChatToAllianceStreamMessage, 41 | 14316: ChangeAllianceSettingsMessage, 42 | 14324: SearchAlliancesMessage, 43 | 14350: TeamCreateMessage, 44 | 14353: TeamLeaveMessage, 45 | 14354: TeamChangeMemberSettingsMessage, 46 | 14363: TeamSetLocationMessage, 47 | 14372: TeamToggleSettingsMessage, 48 | 14403: GetLeaderboardMessage, 49 | 14600: AvatarNameCheckRequestMessage, 50 | 18686: SetSupportedCreatorMessage, 51 | 52 | } 53 | -------------------------------------------------------------------------------- /Logic/ClientAvatar.py: -------------------------------------------------------------------------------- 1 | from Files.CsvLogic.Cards import Cards 2 | 3 | class LogicClientAvatar: 4 | 5 | def encode(self): 6 | 7 | self.writeVInt(0) 8 | self.writeVInt(0) 9 | 10 | for x in range(3): 11 | self.writeLogicLong(self.player.ID) 12 | 13 | if self.player.name == "Guest" and not self.player.name_set: 14 | self.writeString("Guest") 15 | self.writeVInt(0) 16 | else: 17 | self.writeString(self.player.name) 18 | self.writeVInt(1) 19 | 20 | self.writeInt(0) 21 | 22 | self.writeVInt(8) # Commodity Array 23 | 24 | self.player.brawlers_card_id = [] 25 | for x in self.player.brawlers_unlocked: 26 | self.player.brawlers_card_id.append(Cards().get_unlock_by_brawler_id(x)) 27 | 28 | # Unlocked Brawlers & Resources array 29 | self.writeVInt(len(self.player.resources) + len(self.player.brawlers_card_id)) 30 | 31 | for x in self.player.brawlers_card_id: 32 | self.writeDataReference(23, x) 33 | self.writeVInt(1) 34 | 35 | for resource in self.player.resources: 36 | self.writeDataReference(5, resource['ID']) 37 | self.writeVInt(resource['Amount']) 38 | 39 | self.writeVInt(len(self.player.brawlers_id)) 40 | for x in self.player.brawlers_id: 41 | self.writeDataReference(16, x) 42 | self.writeVInt(self.player.brawlers_trophies[str(x)]) 43 | 44 | self.writeVInt(len(self.player.brawlers_id)) 45 | for x in self.player.brawlers_id: 46 | self.writeDataReference(16, x) 47 | self.writeVInt(self.player.brawlers_high_trophies[str(x)]) 48 | 49 | self.writeVInt(0) 50 | for x in range(0): 51 | self.writeDataReference(16, x) 52 | self.writeVInt(0) 53 | 54 | self.writeVInt(len(self.player.brawlers_unlocked)) 55 | for x in self.player.brawlers_unlocked: 56 | self.writeDataReference(16, x) 57 | self.writeVInt(self.player.brawlers_powerpoints[str(x)]) 58 | 59 | self.writeVInt(len(self.player.brawlers_id)) 60 | for x in self.player.brawlers_id: 61 | self.writeDataReference(16, x) 62 | self.writeVInt(self.player.brawlers_level[str(x)]) 63 | 64 | self.writeVInt(len(self.player.brawlers_spg)) 65 | for x in self.player.brawlers_spg: 66 | self.writeDataReference(23, x) 67 | self.writeVInt(1) 68 | 69 | self.writeVInt(0) # New Brawlers Array 70 | for x in range(0): 71 | self.writeDataReference(16, x) 72 | self.writeVInt(0) 73 | 74 | self.writeVInt(self.player.gems) # Player Gems 75 | self.writeVInt(self.player.gems) # Player Free Gems 76 | 77 | self.writeVInt(0) 78 | self.writeVInt(0) 79 | self.writeVInt(0) 80 | self.writeVInt(0) 81 | self.writeVInt(0) 82 | self.writeVInt(0) 83 | self.writeVInt(0) 84 | self.writeVInt(0) 85 | self.writeVInt(0) 86 | 87 | self.writeVInt(2) # Tutorial State 88 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/tiles.csv: -------------------------------------------------------------------------------- 1 | "Name","TileCode","DynamicCode","BlocksMovement","BlocksProjectiles","IsDestructible","IsDestructibleNormalWeapon","HidesHero","RestroreAfterDynamicOverlap","RespawnSeconds","CollisionMargin","BaseExportName","BaseExplosionEffect","BaseHitEffect","BaseWindEffect","BaseBulletHole1","BaseBulletHole2","BaseCrack1","BaseCrack2","SortOffset","HasHitAnim","HasWindAnim","ShadowScaleX","ShadowScaleY","ShadowX","ShadowY","ShadowSkew","Lifetime","CustomSCW","CustomMesh","CustomAngleStep" 2 | "string","string","int","boolean","boolean","boolean","boolean","boolean","boolean","int","int","string","string","string","string","string","string","string","string","int","boolean","boolean","int","int","int","int","int","int","string","string","int" 3 | "Open",".",,,,,,,,,,,,,,,,,,,,,100,60,-10,60,25,,,, 4 | "Blocking1","M",,"true","true","true",,,,,,"blocking1","Rock_explo_fx","Rock_hit_fx",,,,,,,"true",,100,60,-10,60,25,,,, 5 | "Blocking2","X",,"true","true","true",,,,,,"blocking2","blocking2_explosion","blocking2_hit",,,,,,-1,"true",,100,60,-10,60,25,,,, 6 | "Blocking3","Y",,"true","true","true",,,,,,"blocking3","crate_explosion","crate_hit",,,,,,,"true",,100,60,-10,60,25,,,, 7 | "Blocking4","C",,"true","true","true",,,,,,"blocking4","barrel_explosion","barrel_hit",,,,,,,"true",,100,60,-10,60,25,,,, 8 | "DecoDestructible","D",,,,,"true",,,,,"destructable",,,,,,,,,"true",,100,60,-10,60,25,,,, 9 | "Indestructible","I",,"true","true",,,,,,,"indestructible",,"Solid_hit_fx",,,,,,1,"true",,100,60,-10,60,25,,,, 10 | "Forest","F",,,,"true",,"true",,,,"forest","Grass_explo_fx_yellow","Grass_hit_fx_yellow",,,,,,-1,"true","true",100,60,-10,60,25,,,, 11 | "RespawningForest","R",,,,"true",,"true",,,,"respawningforest","Grass_explo_fx","Grass_hit_fx",,,,,,-1,"true","true",100,60,-10,60,25,,,, 12 | "Water","W",,"true",,,,,,,,"water_tile",,,,,,,,,,,100,60,-10,60,25,,,, 13 | "RespawningWall","T",,"true","true","true",,,,,,"respawningwall","Green_explo_fx","Green_hit_fx",,,,,,-1,"true",,100,60,-10,60,25,,,, 14 | "InvisibleWater","V",,"true",,,,,,,,,,,,,,,,,,,100,60,-10,60,25,,,, 15 | "BlockingDestroyableWithWeapon","B",,"true","true","true","true",,,,,"fragile","fragile_explo_debris",,,,,,,,"true",,100,60,-10,60,25,,,, 16 | "Fence","N",,"true","true","true",,,,,,"fence_tile","fence_explosion","fence_hit",,,,,,,,,100,60,-10,30,25,,,, 17 | "InvisibleIndestructible","J",,"true","true",,,,,,,,,,,,,,,,,,100,60,-10,60,25,,,, 18 | "Bench1","A",,"true","true","true",,,,,,"bench_tile_1","bench_explosion","bench_hit",,,,,,,"true",,100,60,-10,60,25,,,, 19 | "Bench2","E",,"true","true","true",,,,,,"bench_tile_2","bench_explosion","bench_hit",,,,,,,"true",,100,60,-10,60,25,,,, 20 | "WallyWall","-",1,"true","true","true",,,,,,"custom","sprout_def_wall_explo","sprout_def_wall_hit",,,,,,,"true",,100,60,-10,60,25,200,"sc3d/wally_wall.scw","wally_wall",90 21 | "WallyFillerWall","-",2,"true","true","true",,,,,,"custom","sprout_def_wall_explo","sprout_def_wall_hit",,,,,,,"true",,100,60,-10,60,25,200,"sc3d/wally_wall.scw","wally_wall_filler",90 22 | "ExtraBush","-",3,,,"true",,"true",,,,"forest","Grass_explo_fx","Grass_hit_fx",,,,,,-1,"true","true",100,60,-10,60,25,,,, 23 | "RopeFence","a",,"true",,"true",,,,,,"rope_fence_pole","Rope_explo_fx",,,,,,,,,,100,60,-10,60,25,,,, 24 | "Road","b",,,,,,,"true",,,"road",,,,,,,,,,,100,60,-10,60,25,,,, 25 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/player_thumbnails.csv: -------------------------------------------------------------------------------- 1 | "Name","RequiredExpLevel","RequiredTotalTrophies","RequiredSeasonPoints","RequiredHero","IconSWF","IconExportName","SortOrder" 2 | "string","int","int","int","string","string","string","int" 3 | "base1",1,0,,,"sc/ui.sc","player_icon_00",0 4 | "base2",10,0,,,"sc/ui.sc","player_icon_01",1 5 | "base3",20,0,,,"sc/ui.sc","player_icon_02",2 6 | "hero1",0,0,,"ShotgunGirl","sc/ui.sc","player_icon_shelly",101 7 | "hero2",0,0,,"Gunslinger","sc/ui.sc","player_icon_colt",103 8 | "hero3",0,0,,"RocketGirl","sc/ui.sc","player_icon_brock",106 9 | "hero4",0,0,,"Mechanic","sc/ui.sc","player_icon_jess",105 10 | "hero5",0,0,,"Shaman","sc/ui.sc","player_icon_nita",102 11 | "hero6",0,0,,"TntDude","sc/ui.sc","player_icon_mike",107 12 | "hero7",0,0,,"Luchador","sc/ui.sc","player_icon_primo",201 13 | "hero8",0,0,,"BullDude","sc/ui.sc","player_icon_bull",104 14 | "hero9",0,0,,"TrickshotDude","sc/ui.sc","player_icon_rick",301 15 | "hero10",0,0,,"Barkeep","sc/ui.sc","player_icon_barley",202 16 | "hero11",0,0,,"DeadMariachi","sc/ui.sc","player_icon_poco",203 17 | "hero12",0,0,,"Undertaker","sc/ui.sc","player_icon_mortis",501 18 | "hero13",0,0,,"BowDude","sc/ui.sc","player_icon_bo",108 19 | "hero14",0,0,,"Cactus","sc/ui.sc","player_icon_spike",601 20 | "hero15",0,0,,"Crow","sc/ui.sc","player_icon_crow",602 21 | "hero16",0,0,,"Sniper","sc/ui.sc","player_icon_piper",401 22 | "base4",40,0,,,"sc/ui.sc","player_icon_03",3 23 | "base5",60,0,,,"sc/ui.sc","player_icon_04",4 24 | "base6",80,0,,,"sc/ui.sc","player_icon_05",5 25 | "base7",100,0,,,"sc/ui.sc","player_icon_06",6 26 | "base8",120,0,,,"sc/ui.sc","player_icon_07",7 27 | "trophy1",0,500,,,"sc/ui.sc","player_icon_trophy_00",8 28 | "trophy2",0,1000,,,"sc/ui.sc","player_icon_trophy_01",9 29 | "trophy3",0,2000,,,"sc/ui.sc","player_icon_trophy_02",10 30 | "trophy4",0,3000,,,"sc/ui.sc","player_icon_trophy_03",11 31 | "hero17",0,0,,"MinigunDude","sc/ui.sc","player_icon_mj",402 32 | "hero18",0,0,,"BlackHole","sc/ui.sc","player_icon_taro",502 33 | "trophy5",0,5000,,,"sc/ui.sc","player_icon_elite_00",12 34 | "trophy6",0,7000,,,"sc/ui.sc","player_icon_elite_01",13 35 | "trophy7",0,10000,,,"sc/ui.sc","player_icon_elite_02",14 36 | "trophy8",0,13000,,,"sc/ui.sc","player_icon_elite_03",15 37 | "hero19",0,0,,"BarrelBot","sc/ui.sc","player_icon_barrelbot",302 38 | "hero20",0,0,,"ArtilleryDude","sc/ui.sc","player_icon_penny",303 39 | "hero21",0,0,,"HammerDude","sc/ui.sc","player_icon_frank",403 40 | "hero22",0,0,,"Ninja","sc/ui.sc","player_icon_leon",603 41 | "hero23",0,0,,"HookDude","sc/ui.sc","player_icon_gene",503 42 | "hero24",0,0,,"Whirlwind","sc/ui.sc","player_icon_carl",304 43 | "hero25",0,0,,"Rosa","sc/ui.sc","player_icon_rosa",204 44 | "hero26",0,0,,"Baseball","sc/ui.sc","player_icon_bibi",404 45 | "hero27",0,0,,"ClusterBombDude","sc/ui.sc","player_icon_tick",109 46 | "hero28",0,0,,"Arcade","sc/ui.sc","player_icon_8bit",110 47 | "hero29",0,0,,"Sandstorm","sc/ui.sc","player_icon_sandy",604 48 | "hero30",0,0,,"Mummy","sc/ui.sc","player_icon_emz",111 49 | "hero31",0,0,,"BeeSniper","sc/ui.sc","player_icon_bea",405 50 | "hero32",0,0,,"Speedy","sc/ui.sc","player_icon_max",504 51 | "hero33",0,0,,"SpawnerDude","sc/ui.sc","player_icon_mrp",505 52 | "hero34",0,0,,"Driller","sc/ui.sc","player_icon_jacky",305 53 | "hero35",0,0,,"Wally","sc/ui.sc","player_icon_sprout",506 54 | "hero36",0,0,,"Blower","sc/ui.sc","player_icon_gale",701 55 | "hero37",0,0,,"Controller","sc/ui.sc","player_icon_nani",406 56 | "hero38",0,0,,"PowerLeveler","sc/ui.sc","player_icon_surge",702 57 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/messages.csv: -------------------------------------------------------------------------------- 1 | "Name","TID","BubbleOverrideTID","Disabled","MessageType","FileName","ExportName","QuickEmojiType","SortPriority","AgeGated" 2 | "string","string","string","Boolean","int","string","string","int","int","Boolean" 3 | "msg1","TID_QUICK_MESSAGE_CHOOSE_BRAWLER",,,1,"sc/ui.sc","button_chat_item",,, 4 | "msg2","TID_QUICK_MESSAGE_CHOOSE_MODE",,,2,"sc/ui.sc","button_chat_item",,, 5 | "msg3","TID_QUICK_MESSAGE_CHANGE_BRAWLERS",,"TRUE",,"sc/ui.sc","button_chat_item",,0, 6 | "msg4","TID_QUICK_MESSAGE_GOOD_GAME",,"TRUE",,"sc/ui.sc","button_chat_item",,23, 7 | "msg5","TID_QUICK_MESSAGE_PLAY_AGAIN",,"TRUE",,"sc/ui.sc","button_chat_item",,2, 8 | "msg6","TID_QUICK_MESSAGE_WELL_PLAYED",,,,"sc/ui.sc","button_chat_item",,3, 9 | "msg7","TID_QUICK_MESSAGE_WOW",,,,"sc/ui.sc","button_chat_item",,4, 10 | "msg8","TID_QUICK_MESSAGE_OK",,"TRUE",,"sc/ui.sc","button_chat_item",,5, 11 | "msg9","TID_QUICK_MESSAGE_GOTTA_GO",,,,"sc/ui.sc","button_chat_item",,6, 12 | "msg10","TID_QUICK_MESSAGE_CHANGE_MODE",,"TRUE",,"sc/ui.sc","button_chat_item",,7, 13 | "msg11","TID_QUICK_MESSAGE_BYE",,"TRUE",,"sc/ui.sc","button_chat_item",,8, 14 | "msg12","TID_QUICK_MESSAGE_CLOSE_MATCH",,,,"sc/ui.sc","button_chat_item",,9, 15 | "msg13","TID_QUICK_MESSAGE_READY",,"TRUE",,"sc/ui.sc","button_chat_item",,10, 16 | "msg14","TID_QUICK_MESSAGE_READY_GO",,"TRUE",,"sc/ui.sc","button_chat_item",,11, 17 | "msg15","TID_QUICK_MESSAGE_HI",,,,"sc/ui.sc","button_chat_item",,12, 18 | "msg16","TID_QUICK_MESSAGE_NEED_BREAK",,"TRUE",,"sc/ui.sc","button_chat_item",,13, 19 | "msg17","TID_QUICK_MESSAGE_NEED_TO_GO",,"TRUE",,"sc/ui.sc","button_chat_item",,14, 20 | "msg18","TID_QUICK_MESSAGE_THANKS",,,,"sc/ui.sc","button_chat_item",,15, 21 | "msg19","TID_QUICK_MESSAGE_SORRY",,"TRUE",,"sc/ui.sc","button_chat_item",,16, 22 | "msg20","TID_QUICK_MESSAGE_OOPS",,,,"sc/ui.sc","button_chat_item",,17, 23 | "msg21","TID_QUICK_MESSAGE_SUGGEST_BRAWLER",,"TRUE",,"sc/ui.sc","button_chat_item",,18, 24 | "msg22","TID_QUICK_MESSAGE_SUGGEST_STARPOWER",,"TRUE",,"sc/ui.sc","button_chat_item",,19, 25 | "msg23","TID_QUICK_MESSAGE_SUGGEST_MODE",,"TRUE",,"sc/ui.sc","button_chat_item",,20, 26 | "msg24","TID_QUICK_MESSAGE_ASK_BRAWLER","TID_QUICK_MESSAGE_ASK_BRAWLER_SPLIT",,5,"sc/ui.sc","button_chat_item",,21, 27 | "msg25","TID_QUICK_MESSAGE_ASK_MODE","TID_QUICK_MESSAGE_ASK_MODE_SPLIT",,6,"sc/ui.sc","button_chat_item",,22, 28 | "msg26",,,,3,"sc/ui.sc","emoji_thumbsup",1,30, 29 | "msg27",,,,3,"sc/ui.sc","emoji_thumbsdown",2,30, 30 | "msg28",,,,3,"sc/ui.sc","emoji_smile",3,0, 31 | "msg29",,,,3,"sc/ui.sc","emoji_sad",4,11, 32 | "msg30",,,,3,"sc/ui.sc","emoji_laugh",,0, 33 | "msg31",,,,3,"sc/ui.sc","emoji_angry",5,22, 34 | "msg32",,,,3,"sc/ui.sc","emoji_annoyed",,21, 35 | "msg33",,,,3,"sc/ui.sc","emoji_blank",,10, 36 | "msg34",,,,3,"sc/ui.sc","emoji_grin",,1, 37 | "msg35",,,,3,"sc/ui.sc","emoji_rage",,22, 38 | "msg36",,,,3,"sc/ui.sc","emoji_shocked",,12, 39 | "msg37","TID_QUICK_MESSAGE_CHOOSE_FRIENDLY_LOCATION",,,4,"sc/ui.sc","button_chat_item",,, 40 | "msg38",,,,3,"sc/ui.sc","emoji_happy",,0, 41 | "msg39",,,,3,"sc/ui.sc","emoji_stunned",,11, 42 | "msg40",,,,3,"sc/ui.sc","emoji_bothered",,20, 43 | "msg41",,,,3,"sc/ui.sc","emoji_ecstatic",,1, 44 | "msg42",,,,3,"sc/ui.sc","emoji_speechless",,10, 45 | "msg43",,,,3,"sc/ui.sc","emoji_frenzied",,22, 46 | "msg44","TID_QUICK_MESSAGE_ONE_MOMENT",,,,"sc/ui.sc","button_chat_item",,24, 47 | "msg45","TID_QUICK_MESSAGE_ASK_STAR_TOKEN_HELP",,"TRUE",,"sc/ui.sc","button_chat_item",,25, 48 | "msg55","TID_QUICK_MESSAGE_LETS_CHAT",,,7,"sc/ui.sc","button_chat_item",,26,TRUE 49 | "msg56",,,,8,"sc/ui.sc","emoji_happy",,0, 50 | 51 | -------------------------------------------------------------------------------- /Logic/Player.py: -------------------------------------------------------------------------------- 1 | import json 2 | from Utils.Helpers import Helpers 3 | from Utils.Fingerprint import Fingerprint 4 | from Files.CsvLogic.Characters import Characters 5 | from Files.CsvLogic.Skins import Skins 6 | from Files.CsvLogic.Cards import Cards 7 | from Files.CsvLogic.Emotes import Emotes 8 | 9 | class Player: 10 | try: 11 | config = open('config.json', 'r') 12 | content = config.read() 13 | except FileNotFoundError: 14 | Helpers().create_config() 15 | config = open('config.json', 'r') 16 | content = config.read() 17 | 18 | settings = json.loads(content) 19 | 20 | skins_id = Skins().get_skins_id() 21 | brawlers_id = Characters().get_brawlers_id() 22 | 23 | ID = 0 24 | token = None 25 | 26 | trophies = settings['Trophies'] 27 | tickets = settings['Tickets'] 28 | gems = settings['Gems'] 29 | resources = [{'ID': 1, 'Amount': settings['BrawlBoxTokens']}, {'ID': 8, 'Amount': settings['Gold']}, {'ID': 9, 'Amount': settings['BigBoxTokens']}, {'ID': 10, 'Amount': settings['StarPoints']}] 30 | high_trophies = 999999 31 | trophy_reward = 300 32 | exp_points = settings['ExperiencePoints'] 33 | profile_icon = 0 34 | name_color = 0 35 | selected_brawler = 0 36 | region = settings['Region'] 37 | content_creator = "Modern Brawl" 38 | name_set = False 39 | name = 'Guest' 40 | map_id = 0 41 | use_gadget = True 42 | starpower = 76 43 | gadget = 255 44 | home_brawler = 0 45 | home_skin = 0 46 | leaderboard_type = 0 47 | leaderboard_is_global = False 48 | bp_activated = False 49 | token_doubler = 0 50 | welcome_msg_viewed = False 51 | theme_id = settings['ThemeID'] 52 | content_creator_codes = settings['ContentCreatorCodes'] 53 | maintenance = settings['Maintenance'] 54 | maintenance_time = settings['SecondsTillMaintenanceOver'] 55 | patch = settings['Patch'] 56 | patch_url = settings['PatchURL'] 57 | patch_sha = Fingerprint.loadFinger("GameAssets/fingerprint.json") 58 | update_url = settings['UpdateURL'] 59 | 60 | delivery_items = {} 61 | box_rewards = {} 62 | 63 | db = None 64 | 65 | battle_tick = 0 66 | 67 | emotes_id = Emotes().get_emotes_id() 68 | 69 | unlocked_skins = skins_id 70 | 71 | selected_skins = {} 72 | for id in brawlers_id: 73 | selected_skins.update({f"{id}": 0}) 74 | 75 | brawlers_unlocked = [0, 1] 76 | 77 | brawlers_card_id = [] 78 | for x in brawlers_unlocked: 79 | brawlers_card_id.append(Cards().get_unlock_by_brawler_id(x)) 80 | 81 | brawlers_spg = Cards().get_spg_id() 82 | 83 | def_trophies = 0 84 | def_high_trophies = 99999 85 | 86 | brawlers_trophies = {} 87 | for x in brawlers_id: 88 | brawlers_trophies.update({f'{x}': def_trophies}) 89 | 90 | brawlers_high_trophies = {} 91 | for x in brawlers_id: 92 | brawlers_high_trophies.update({f'{x}': def_high_trophies}) 93 | 94 | def_level = 0 95 | 96 | brawlers_level = {} 97 | for x in brawlers_id: 98 | brawlers_level.update({f'{x}': def_level}) 99 | 100 | def_pp = 0 101 | 102 | brawlers_powerpoints = {} 103 | for x in brawlers_id: 104 | brawlers_powerpoints.update({f'{x}': def_pp}) 105 | 106 | 107 | club_id = 0 108 | club_role = 0 109 | 110 | message_tick = 0 111 | 112 | clients = {} 113 | 114 | 115 | def __init__(self, device): 116 | self.device = device 117 | 118 | 119 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/game_mode_variations.csv: -------------------------------------------------------------------------------- 1 | "Name","Variation","Disabled","TID","ChatSuggestionItemName","GameModeRoomIconName","GameModeIconName","ScoreSfx","OpponentScoreSfx","ScoreText","ScoreTextEnd","FriendlyMenuOrder","IntroText","IntroDescText","IntroDescText2","StartNotification","EndNotification","Color" 2 | "string","int","Boolean","string","string","string","string","string","string","string","string","int","string","string","string","String","String","string" 3 | "GemGrab",0,,"TID_GAME_MODE_0","chat_letsplay_gemgrab","event_gameroom_gemgrab","event_icon_gemgrab",,,,,1,"TID_GAME_MODE_0","TID_COIN_RUSH_INTRO_TEXT",,"CoinRushStart",,"0xffd852ff" 4 | "Deleted1",1,"TRUE",,,,"event_icon_gemgrab",,,,,,,,,,, 5 | "Heist",2,,"TID_GAME_MODE_2","chat_letsplay_heist","event_gameroom_heist","event_icon_heist",,,,,3,"TID_GAME_MODE_2","TID_ATTACK_DEFEND_INTRO_TEXT_ATTACK","TID_ATTACK_DEFEND_INTRO_TEXT_DEFEND","AttackDefendStart",,"0xffd852ff" 6 | "Bounty",3,,"TID_GAME_MODE_3","chat_letsplay_wanted","event_gameroom_wanted","event_icon_wanted",,,,,4,"TID_GAME_MODE_3","TID_BOUNTY_HUNTER_INTRO_TEXT",,"BountyStart",,"0xff24d6ff" 7 | "Deleted2",4,"TRUE",,,,"event_icon_gemgrab",,,,,,,,,,, 8 | "BrawlBall",5,,"TID_GAME_MODE_5","chat_letsplay_brawlball","event_gameroom_brawlball","event_icon_brawlball","Brawlbawl_goal","Brawlbawl_other_goal","TID_GOAL","TID_GOAL_MATCH_OVER",5,"TID_GAME_MODE_5","TID_LASER_BALL_INTRO_TEXT",,"LaserBallStart",,"0xff9ab1fd" 9 | "Showdown",6,,"TID_GAME_MODE_6","chat_letsplay_survival","event_gameroom_survival","event_icon_survival",,,,,2,"TID_GAME_MODE_6","TID_BATTLE_ROYALE_INTRO_TEXT",,"BRStart",,"0xff91e136" 10 | "BigGame",7,,"TID_GAME_MODE_7","chat_letsplay_bossmode","event_gameroom_bossmode","event_icon_bossmode",,,,,10,"TID_GAME_MODE_7","TID_BOSS_INTRO_TEXT_ATTACK","TID_BOSS_INTRO_TEXT_DEFEND","BossStart",,"0xffff6847" 11 | "RoboRumble",8,,"TID_GAME_MODE_8","chat_letsplay_coop","event_gameroom_coop","event_icon_coop",,,,,11,"TID_GAME_MODE_8","TID_COOP_INTRO_TEXT",,"CoopStart",,"0xffff6847" 12 | "DuoShowdown",9,,"TID_GAME_MODE_9","chat_letsplay_teamsurvival","event_gameroom_teamsurvival","event_icon_teamsurvival",,,,,,"TID_GAME_MODE_9","TID_BATTLE_ROYALE_TEAM_INTRO_TEXT",,,,"0xff91e136" 13 | "BossFight",10,,"TID_GAME_MODE_10","chat_letsplay_raid","event_gameroom_raid","event_icon_raid",,,,,12,"TID_GAME_MODE_10","TID_RAID_BOSS_INTRO_TEXT",,"RaidBossStart",,"0xffff6847" 14 | "Siege",11,,"TID_GAME_MODE_11","chat_letsplay_robowars","event_gameroom_robowars","event_icon_robowars",,,,,7,"TID_GAME_MODE_11","TID_ROBO_WARS_INTRO_TEXT",,"RoboWarsStart",,"0xffff6847" 15 | "Tutorial",12,,,,,"event_icon_gemgrab",,,,,,,,,,, 16 | "Training",13,,,,,"event_icon_gemgrab",,,,,,,,,,, 17 | "Takedown",14,,"TID_GAME_MODE_14","chat_letsplay_takedown","event_gameroom_takedown","event_icon_takedown",,,,,8,"TID_GAME_MODE_14","TID_BOSS_RACE_INTRO_TEXT",,"TakedownStart",,"0xff3891ff" 18 | "LoneStar",15,,"TID_GAME_MODE_15","chat_letsplay_lone_star","event_gameroom_lone_star","event_icon_lone_star",,,,,9,"TID_GAME_MODE_15","TID_BOUNTY_HUNTER_INTRO_TEXT",,"LoneStarStart",,"0xffe24e5a" 19 | "CTF",16,,"TID_GAME_MODE_16","chat_letsplay_ctf","event_gameroom_ctf","event_icon_ctf","Brawl_xmas_flag_win","Brawl_xmas_flag_lose","TID_CTF_GOAL","TID_CTF_GOAL_MATCH_OVER",6,"TID_GAME_MODE_16","TID_CTF_INTRO_TEXT",,"CTFStart",,"0xff27be47" 20 | "KingOfHill",17,,"TID_GAME_MODE_17","chat_letsplay_king_of_hill","event_gameroom_king_of_hill","event_icon_king_of_hill",,,"TID_FLAG_RAISE","TID_FLAG_RAISE_GAME_OVER",13,"TID_GAME_MODE_17","TID_KING_OF_HILL_INTRO_TEXT",,"KOHStart",,"0xffff4343" 21 | "BossFight_TownCrush",18,,"TID_GAME_MODE_18","chat_letsplay_rampage","event_gameroom_rampage","event_icon_rampage",,,,,14,"TID_GAME_MODE_18","TID_RAID_BOSS_INTRO_TEXT",,"TownCrusherStart",,"0xffff6847" 22 | -------------------------------------------------------------------------------- /Utils/Helpers.py: -------------------------------------------------------------------------------- 1 | import json 2 | import string 3 | import random 4 | from colorama import Fore 5 | 6 | class Helpers: 7 | connected_clients = {"ClientsCount": 0, "Clients": {}} 8 | 9 | yellow = Fore.YELLOW 10 | green = Fore.GREEN 11 | blue = Fore.LIGHTBLUE_EX 12 | cyan = Fore.CYAN 13 | red = Fore.RED 14 | 15 | def randomToken(self): 16 | lettersAndDigits = string.ascii_letters + string.digits 17 | return ''.join(random.choice(lettersAndDigits) for i in range(40)) 18 | 19 | def randomID(self, length = 8): 20 | return int(''.join([str(random.randint(0, 9)) for _ in range(length)])) 21 | 22 | def randomMapID(self): 23 | return random.randint(1, 2147483647) 24 | 25 | def get_box_type(self, id): 26 | if id == 5: # Brawl Box 27 | return 10 28 | elif id == 4: # Big Box 29 | return 12 30 | elif id == 3: # Shop Mega Box 31 | return 11 32 | elif id == 1: # Shop Big Box 33 | return 12 34 | 35 | def create_config(self): 36 | settings = { 37 | "MongoConnectionURL": "", 38 | "StarPoints": 5000, 39 | "Gold": 10000, 40 | "Gems": 100000, 41 | "Trophies": 0, 42 | "ExperiencePoints": 999999, 43 | "BrawlBoxTokens": 99999, 44 | "BigBoxTokens": 99999, 45 | "Region": "RO", 46 | "ThemeID": 0, 47 | "Maintenance": False, 48 | "SecondsTillMaintenanceOver": 3600 49 | } 50 | 51 | 52 | with open('config.json', 'w') as config_file: 53 | json.dump(settings, config_file) 54 | 55 | def load_account(self, player_data): 56 | self.player.name_set = player_data['NameSet'] 57 | self.player.name = player_data['Name'] 58 | self.player.trophies = player_data['Trophies'] 59 | self.player.gems = player_data['Gems'] 60 | self.player.resources = player_data['Resources'] 61 | self.player.token_doubler = player_data['TokenDoubler'] 62 | self.player.high_trophies = player_data['HighestTrophies'] 63 | self.player.trophy_reward = player_data['TrophyRoadReward'] 64 | self.player.exp_points = player_data['ExperiencePoints'] 65 | self.player.profile_icon = player_data['ProfileIcon'] 66 | self.player.name_color = player_data['NameColor'] 67 | self.player.brawlers_unlocked = player_data['UnlockedBrawlers'] 68 | self.player.brawlers_trophies = player_data['BrawlersTrophies'] 69 | self.player.brawlers_high_trophies = player_data['BrawlersHighestTrophies'] 70 | self.player.brawlers_level = player_data['BrawlersLevel'] 71 | self.player.brawlers_powerpoints = player_data['BrawlersPowerPoints'] 72 | self.player.unlocked_skins = player_data['UnlockedSkins'] 73 | self.player.selected_skins = player_data['SelectedSkins'] 74 | self.player.tickets = player_data['Tickets'] 75 | self.player.home_brawler = player_data['HomeBrawler'] 76 | self.player.region = player_data['Region'] 77 | self.player.content_creator = player_data['SupportedContentCreator'] 78 | self.player.bp_activated = player_data['BrawlPassActivated'] 79 | self.player.starpower = player_data['StarPower'] 80 | self.player.gadget = player_data['Gadget'] 81 | self.player.welcome_msg_viewed = player_data['WelcomeMessageViewed'] 82 | self.player.club_id = player_data['ClubID'] 83 | self.player.club_role = player_data['ClubRole'] 84 | 85 | 86 | def load_club(self, club_data): 87 | try: 88 | self.player.message_tick = club_data['Messages'][-1]['Tick'] 89 | except: 90 | pass -------------------------------------------------------------------------------- /Core/Networking/ClientThread.py: -------------------------------------------------------------------------------- 1 | import time 2 | import json 3 | from threading import * 4 | from Logic.Player import Player 5 | from Logic.Device import Device 6 | from Utils.Helpers import Helpers 7 | from Protocol.LogicLaserMessageFactory import packets 8 | from Protocol.Messages.Server.LobbyInfoMessage import LobbyInfoMessage 9 | from Protocol.Messages.Server.LoginFailedMessage import LoginFailedMessage 10 | 11 | def _(*args): 12 | for arg in args: 13 | print(arg, end=' ') 14 | print() 15 | 16 | 17 | class ClientThread(Thread): 18 | def __init__(self, client, address, db): 19 | super().__init__() 20 | self.client = client 21 | self.address = address 22 | self.db = db 23 | self.config = json.loads(open('config.json', 'r').read()) 24 | self.device = Device(self.client) 25 | self.player = Player(self.device) 26 | 27 | 28 | def recvall(self, length: int): 29 | data = b'' 30 | 31 | while len(data) < length: 32 | s = self.client.recv(length) 33 | 34 | if not s: 35 | _(f"{Helpers.red}ERROR while receiving data!") 36 | break 37 | 38 | data += s 39 | return data 40 | 41 | 42 | 43 | def run(self): 44 | try: 45 | last_packet = time.time() 46 | while True: 47 | header = self.client.recv(7) 48 | 49 | if len(header) > 0: 50 | 51 | last_packet = time.time() 52 | 53 | # Packet Info 54 | packet_id = int.from_bytes(header[:2], 'big') 55 | packet_length = int.from_bytes(header[2:5], 'big') 56 | packet_data = self.recvall(packet_length) 57 | 58 | if self.address[0] in self.config['BannedIPs']: 59 | self.player.err_code = 11 60 | LoginFailedMessage(self.client, self.player, 'Account banned!').send() 61 | 62 | LobbyInfoMessage(self.client, self.player, Helpers.connected_clients['ClientsCount']).send() 63 | 64 | 65 | if packet_id in packets: 66 | packet_name = packets[packet_id].__name__ 67 | _(f'{Helpers.blue}[CLIENT] PacketID: {packet_id}, Name: {packet_name} Length: {packet_length}') 68 | 69 | message = packets[packet_id](self.client, self.player, packet_data) 70 | message.decode() 71 | message.process(self.db) 72 | 73 | if packet_id == 10101: 74 | Helpers.connected_clients["Clients"][str(self.player.ID)] = {"SocketInfo": self.client} 75 | 76 | else: 77 | _(f'{Helpers.cyan}[CLIENT] Unhandled Packet! ID: {packet_id}, Length: {packet_length}') 78 | 79 | if time.time() - last_packet > 10: 80 | _(f"{Helpers.cyan}[DEBUG] Client disconnected! IP: {self.address[0]}") 81 | self.client.close() 82 | _(f"{Helpers.cyan}[DEBUG] Client disconnected! IP: {self.address[0]}") 83 | Helpers.connected_clients['ClientsCount'] -= 1 84 | break 85 | 86 | 87 | except ConnectionAbortedError: 88 | _(f"{Helpers.cyan}[DEBUG] Client disconnected! IP: {self.address[0]}") 89 | self.client.close() 90 | Helpers.connected_clients['ClientsCount'] -= 1 91 | except ConnectionResetError: 92 | _(f"{Helpers.cyan}[DEBUG] Client disconnected! IP: {self.address[0]}") 93 | self.client.close() 94 | Helpers.connected_clients['ClientsCount'] -= 1 95 | except TimeoutError: 96 | _(f"{Helpers.cyan}[DEBUG] Client disconnected! IP: {self.address[0]}") 97 | self.client.close() 98 | Helpers.connected_clients['ClientsCount'] -= 1 -------------------------------------------------------------------------------- /GameAssets/csv_logic/items.csv: -------------------------------------------------------------------------------- 1 | "Name","ParentItemForSkin","FileName","ExportName","ExportNameEnemy","ShadowExportName","GroundGlowExportName","LoopingEffect","Value","Value2","TriggerRangeSubTiles","TriggerAreaEffect","CanBePickedUp","SpawnEffect","ActivateEffect","SCW","SCWEnemy","Layer" 2 | "string","String","string","string","string","string","string","string","int","int","int","string","boolean","string","string","string","string","string" 3 | "Health",,"sc/effects.sc","soul","soul",,"pickup_glow_green","Health_fx",16000,,4,,"true","Spawn_plasmoid",,,,"Above" 4 | "Speed",,"sc/effects.sc","red_pickup","red_pickup",,"pickup_glow_green","Health_fx",300,,4,,"true","Spawn_plasmoid",,,,"Above" 5 | "DamageAndSpeed",,"sc/effects.sc",,,,"pickup_glow_green","power_up_bottle_sparkle",200,200,4,,"true","Spawn_buff",,"sc3d/item_power_up_bottle.scw","sc3d/item_power_up_bottle.scw","Above" 6 | "Point",,"sc/effects.sc","blob_pickup","blob_pickup",,"pickup_glow","Blob_fx",,,4,,"true","Spawn_plasmoid",,,,"Above" 7 | "Corpse",,"sc/effects.sc","soul","soul",,"pickup_glow_green","Health_fx",800,,4,,"true","Spawn_plasmoid",,,,"Above" 8 | "OrbSpawner",,,,,,,,,,,,,"Spawn_plasmoid",,"sc3d/mine_gem_spawn.scw","sc3d/mine_gem_spawn.scw","GroundLow" 9 | "Mine",,"sc/effects_brawler.sc","bo_def_mine_blue","bo_def_mine_red",,,,800,1150,3,"Bo_def_ulti2_area","true","bo_def_ulti2_spawn",,,,"Above" 10 | "SupplyCrate",,"sc/effects.sc","red_pickup","red_pickup",,"pickup_glow_green",,,,,,,"Spawn_plasmoid",,,,"Above" 11 | "BoxOfMines",,"sc/effects.sc",,,,"pickup_glow_green",,3,6,,,,"Spawn_plasmoid",,,,"Above" 12 | "BattleRoyaleBuff",,"sc/effects.sc",,,,"pickup_glow_green","Health_fx",10,400,4,,"true","Spawn_plasmoid",,"sc3d/item_showdown_boost.scw","sc3d/item_showdown_boost.scw","Above" 13 | "Money",,"sc/effects.sc","wanted_star_pickup","wanted_star_pickup",,"pickup_glow_gold","Blob_fx",1,,4,,"true","Spawn_plasmoid",,,,"Above" 14 | "BoxOfBombs",,"sc/effects.sc",,,,"pickup_glow_green",,4,8,,,,"Spawn_plasmoid",,,,"Above" 15 | "Bomb",,"sc/effects.sc","grenade_01","grenade_01_red","projectile_shadow",,,800,300,200,"SniperBombExplosion","true","Spawn_sniper_bomb",,,,"Above" 16 | "BoxOfSelfDestructBombs",,"sc/effects.sc","red_pickup","red_pickup",,"pickup_glow_green",,4,40,,,,"Spawn_plasmoid",,,,"Above" 17 | "SelfDestructBomb",,"sc/effects.sc","cannon_projectile_blue","cannon_projectile_red","projectile_shadow",,,800,1300,200,"SelfDestructExplosion","true","artillery_dude_turret_attack",,,,"Above" 18 | "Scrap",,"sc/effects.sc",,,,"pickup_glow_green","power_up_bottle_sparkle",,,4,,"true","Spawn_buff",,"sc3d/item_bolt.scw","sc3d/item_bolt.scw","Above" 19 | "SpringBoardLeft",,,,,,,,,,3,,,"Spawn_plasmoid",,"sc3d/spring_board.scw","sc3d/spring_board.scw","Object" 20 | "SpringBoardRight",,,,,,,,,,3,,,"Spawn_plasmoid",,"sc3d/spring_board.scw","sc3d/spring_board.scw","Object" 21 | "SpringBoardUp",,,,,,,,,,3,,,"Spawn_plasmoid",,"sc3d/spring_board.scw","sc3d/spring_board.scw","Object" 22 | "SpringBoardDown",,,,,,,,,,3,,,"Spawn_plasmoid",,"sc3d/spring_board.scw","sc3d/spring_board.scw","Object" 23 | "SpringBoardUpLeft",,,,,,,,,,3,,,"Spawn_plasmoid",,"sc3d/spring_board_diagonal.scw","sc3d/spring_board_diagonal.scw","Object" 24 | "SpringBoardUpRight",,,,,,,,,,3,,,"Spawn_plasmoid",,"sc3d/spring_board_diagonal.scw","sc3d/spring_board_diagonal.scw","Object" 25 | "SpringBoardDownLeft",,,,,,,,,,3,,,"Spawn_plasmoid",,"sc3d/spring_board_diagonal.scw","sc3d/spring_board_diagonal.scw","Object" 26 | "SpringBoardDownRight",,,,,,,,,,3,,,"Spawn_plasmoid",,"sc3d/spring_board_diagonal.scw","sc3d/spring_board_diagonal.scw","Object" 27 | "TrainSpawner",,,,,,,,,,,,,,,,,"Above" 28 | "ClusterMine",,"sc/effects_brawler.sc","tick_def_atk2","tick_def_atk2_red","shadow_normal_circle",,,800,2000,200,"ClusterBombExplosion2","true",,,,,"Above" 29 | "Tick002Mine","ClusterMine","sc/effects_brawler.sc","tick_002_atk2","tick_002_atk2_red","shadow_normal_circle",,,800,2000,200,"ClusterBombExplosion2","true",,,,,"Above" 30 | "MineMecha","Mine","sc/effects_brawler.sc","bo_002_mine_blue","bo_002_mine_red",,,,,,,"Bo_def_ulti2_area",,"bo_def_ulti2_spawn",,,,"Above" 31 | "ValentineBomb","Bomb","sc/effects_brawler.sc","piper_002_ulti_projectile","piper_002_ulti_projectile_red","shadow_normal_circle_big",,,,,,"Bo_def_ulti2_area",,"bo_def_ulti2_spawn",,,,"Above" 32 | "MineHorus","Mine","sc/effects_brawler.sc","bo_003_mine_blue","bo_003_mine_red",,,,,,,"Bo_def_ulti2_area",,"bo_def_ulti2_spawn",,,,"Above" 33 | "ScorePole",,,,,,,,,,,,,"Spawn_plasmoid",,"sc3d/flagpole.scw","sc3d/flagpole.scw","Above" 34 | "ScoreFlag",,,,,,,,,,,,,"Spawn_plasmoid",,"sc3d/flag_blue.scw","sc3d/flag_red.scw","Above" 35 | "ScoreFlagHoisted",,,,,,,"mode_koh_complete",,,,,,"mode_koh_captured",,"sc3d/flag_blue_hoisted.scw","sc3d/flag_red_hoisted.scw","Above" 36 | "GroundFiller",,,,,,,,,,3,,"true",,"car_explo","sc3d/minicity_parked_cars.scw","sc3d/minicity_parked_cars.scw","GroundLow" 37 | -------------------------------------------------------------------------------- /ByteStream/Writer.py: -------------------------------------------------------------------------------- 1 | from Utils.Helpers import Helpers 2 | 3 | class Writer: 4 | def __init__(self, client, endian: str = 'big'): 5 | self.client = client 6 | self.endian = endian 7 | self.buffer = b'' 8 | 9 | def writeInt(self, data, length = 4): 10 | self.buffer += data.to_bytes(length, self.endian, signed=True) 11 | 12 | def writeUInteger(self, integer: int, length: int = 1): 13 | self.buffer += integer.to_bytes(length, self.endian, signed=False) 14 | 15 | def writeLong(self, data): 16 | self.writeInt(data, 8) 17 | 18 | def writeLogicLong(self, data): 19 | self.writeVInt(0) 20 | self.writeVInt(data) 21 | 22 | def writeArrayVint(self, data): 23 | self.writeVInt(len(data)) 24 | for x in data: 25 | self.writeVInt(x) 26 | 27 | def writeUInt8(self, integer: int): 28 | self.writeUInteger(integer) 29 | 30 | def writeInt8(self, integer: int): 31 | self.writeInt(integer, 1) 32 | 33 | def writeInt16(self, data): 34 | self.writeInt(data, 2) 35 | 36 | def writeBool(self, boolean: bool): 37 | if boolean: 38 | self.writeUInt8(1) 39 | else: 40 | self.writeUInt8(0) 41 | 42 | def writeHexa(self, data): 43 | if data: 44 | if data.startswith('0x'): 45 | data = data[2:] 46 | 47 | self.buffer += bytes.fromhex(''.join(data.split()).replace('-', '')) 48 | 49 | def send(self): 50 | self.encode() 51 | packet = self.buffer 52 | self.buffer = self.id.to_bytes(2, 'big', signed=True) 53 | self.writeInt(len(packet), 3) 54 | if hasattr(self, 'version'): 55 | self.writeInt16(self.version) 56 | else: 57 | self.writeInt16(0) 58 | self.buffer += packet + b'\xff\xff\x00\x00\x00\x00\x00' 59 | self.client.send(self.buffer) 60 | print(f'{Helpers.yellow}[SERVER] PacketID: {self.id}, Name: {type(self).__name__}, Length: {len(self.buffer)}') 61 | 62 | 63 | def sendByID(self, ID): 64 | try: 65 | self.encode() 66 | packet = self.buffer 67 | self.buffer = self.id.to_bytes(2, 'big', signed=True) 68 | self.writeInt(len(packet), 3) 69 | if hasattr(self, 'version'): 70 | self.writeInt16(self.version) 71 | else: 72 | self.writeInt16(0) 73 | self.buffer += packet + b'\xff\xff\x00\x00\x00\x00\x00' 74 | Helpers.connected_clients["Clients"][str(ID)]["SocketInfo"].send(self.buffer) 75 | except: 76 | pass 77 | 78 | def writeVInt(self, data, rotate: bool = True): 79 | final = b'' 80 | if data == 0: 81 | self.writeByte(0) 82 | else: 83 | data = (data << 1) ^ (data >> 31) 84 | while data: 85 | b = data & 0x7f 86 | 87 | if data >= 0x80: 88 | b |= 0x80 89 | if rotate: 90 | rotate = False 91 | lsb = b & 0x1 92 | msb = (b & 0x80) >> 7 93 | b >>= 1 94 | b = b & ~0xC0 95 | b = b | (msb << 7) | (lsb << 6) 96 | 97 | final += b.to_bytes(1, 'big') 98 | data >>= 7 99 | self.buffer += final 100 | 101 | def writeDataReference(self, x, y=0): 102 | if x != 0: 103 | self.writeVInt(x) 104 | self.writeVInt(y) 105 | else: 106 | self.writeVInt(0) 107 | 108 | 109 | def writeString(self, string: str = None): 110 | if string is None: 111 | self.writeInt(-1) 112 | else: 113 | encoded = string.encode('utf-8') 114 | self.writeInt(len(encoded)) 115 | self.buffer += encoded 116 | 117 | def writeStringShort(self, string: str = None): 118 | if string is None: 119 | self.writeInt(-1) 120 | else: 121 | encoded = string.encode('utf-8') 122 | self.writeInt8(len(encoded)) 123 | self.buffer += encoded 124 | 125 | def writeStringReference(self, string: str = None): 126 | encoded = string.encode('utf-8') 127 | self.writeInt16(0) 128 | self.writeVInt(len(encoded)) 129 | self.buffer += encoded 130 | 131 | def writeByte(self, data): 132 | self.writeInt(data, 1) 133 | 134 | def writeNullVInt(self): 135 | self.writeVInt(-1) 136 | 137 | def size(self): 138 | return len(self.buffer) 139 | 140 | def getRaw(self): 141 | return self.buffer 142 | 143 | def writeBytes(self, data): 144 | self.buffer += data 145 | 146 | writeBoolean = writeBool 147 | writeInt32 = writeInt -------------------------------------------------------------------------------- /Logic/Home/LogicDailyData.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from Logic.Home.LogicShopData import LogicShopData 3 | 4 | class LogicDailyData: 5 | 6 | def encode(self): 7 | 8 | time_stamp = int(datetime.timestamp(datetime.now())) 9 | 10 | self.writeVInt(time_stamp) 11 | self.writeVInt(time_stamp) 12 | 13 | self.writeVInt(self.player.trophies) 14 | self.writeVInt(self.player.high_trophies) 15 | self.writeVInt(self.player.high_trophies) 16 | 17 | self.writeVInt(self.player.trophy_reward) 18 | self.writeVInt(self.player.exp_points) 19 | 20 | self.writeDataReference(28, self.player.profile_icon) 21 | self.writeDataReference(43, self.player.name_color) 22 | 23 | self.writeVInt(50) 24 | for x in range(50): 25 | self.writeVInt(x) 26 | 27 | self.writeVInt(len(self.player.selected_skins)) 28 | for x in self.player.selected_skins: 29 | self.writeDataReference(29, self.player.selected_skins[x]) 30 | 31 | self.writeVInt(len(self.player.unlocked_skins)) 32 | for x in self.player.unlocked_skins: 33 | self.writeDataReference(29, x) 34 | 35 | self.writeVInt(0) # Unknown Array 36 | for x in range(0): 37 | self.writeDataReference(0,0) 38 | 39 | self.writeVInt(0) # Leaderboard Global TID 40 | self.writeVInt(50000) # Trophy Road Reached Icon 41 | self.writeVInt(0) # Unknown 42 | self.writeVInt(0) # Unknown 43 | 44 | self.writeUInt8(0) # Is Token Limit Reached 45 | 46 | self.writeVInt(self.player.token_doubler) 47 | self.writeVInt(99999) # Trophy Road Timer 48 | self.writeVInt(0) # Power Play Timer 49 | self.writeVInt(99999) # Brawl Pass Timer 50 | 51 | self.writeVInt(0) # Unknown 52 | 53 | self.writeBoolean(False) 54 | self.writeBoolean(False) 55 | 56 | self.writeUInt8(4) # Shop Token Doubler 57 | 58 | self.writeVInt(2) # Unknown 59 | self.writeVInt(2) # Unknown 60 | self.writeVInt(2) # Unknown 61 | 62 | self.writeVInt(0) # Name Change Cost 63 | self.writeVInt(0) # Name Change Timer 64 | 65 | 66 | LogicShopData.encodeShopOffers(self) 67 | 68 | self.writeVInt(0) # AdStatus 69 | for x in range(0): 70 | self.writeVInt(0) 71 | self.writeVInt(0) 72 | self.writeVInt(0) 73 | 74 | self.writeVInt(200) # Available Battle Tokens 75 | self.writeVInt(0) # Time till Bonus Tokens 76 | 77 | self.writeVInt(0) # Unknown Array 78 | for x in range(0): 79 | self.writeVInt(x) 80 | 81 | self.writeVInt(1) 82 | self.writeVInt(1) # Unknown 83 | 84 | self.writeDataReference(16, self.player.home_brawler) 85 | 86 | self.writeString(self.player.region) 87 | self.writeString(self.player.content_creator) 88 | 89 | self.writeVInt(0) # Unknown Array 90 | for x in range(0): 91 | self.writeInt(0) 92 | self.writeInt(0) 93 | 94 | self.writeVInt(0) # CooldownEntry 95 | for x in range(0): 96 | self.writeVInt(0) 97 | self.writeDataReference(0, 0) 98 | self.writeVInt(0) 99 | 100 | self.writeVInt(1) # BrawlPassSeasonData 101 | for x in range(1): 102 | self.writeVInt(1) # Current Season 103 | self.writeVInt(0) # Pass Tokens 104 | self.writeBool(self.player.bp_activated) 105 | self.writeVInt(2) # Pass Progress 106 | 107 | self.writeInt8(1) 108 | for i in range(4): 109 | self.writeInt(4) 110 | 111 | self.writeInt8(1) 112 | for i in range(4): 113 | self.writeInt(4) 114 | 115 | self.writeVInt(0) # ProLeagueSeasonData 116 | for x in range(0): 117 | self.writeVInt(0) 118 | self.writeVInt(0) 119 | 120 | self.writeBoolean(True) # LogicQuests 121 | if True: 122 | self.writeVInt(0) 123 | for x in range(0): 124 | self.writeVInt(0) # Unknown 125 | self.writeVInt(0) # Unknown 126 | self.writeVInt(1) # Mission Type 127 | self.writeVInt(2) # Achieved Goal 128 | self.writeVInt(8) # Quest Goal 129 | self.writeVInt(10) # Tokens Reward 130 | self.writeVInt(0) # Unknown 131 | self.writeVInt(0) # Current level 132 | self.writeVInt(0) # Max level 133 | self.writeVInt(1) # Quest Type 134 | self.writeUInt8(2) # Quest State 135 | self.writeDataReference(16, 0) 136 | self.writeVInt(0) # GameMode 137 | self.writeVInt(0) # Unknown 138 | self.writeVInt(0) # Unknown 139 | 140 | # Emotes Array 141 | self.writeBoolean(True) 142 | if True: 143 | self.writeVInt(len(self.player.emotes_id)) 144 | for x in self.player.emotes_id: 145 | self.writeDataReference(52, x) 146 | self.writeVInt(1) # Unknown 147 | self.writeVInt(1) # Unknown 148 | self.writeVInt(1) # Unknown 149 | 150 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/map_blocks.csv: -------------------------------------------------------------------------------- 1 | "CodeName","Group","Data" 2 | "String","String","String" 3 | "r0","roboleft","........" 4 | "r1","****","........" 5 | "r2",,"..D..D.." 6 | "r3",,"......I." 7 | "r4",,"......I." 8 | "r5",,"..I...I." 9 | "r6",,"..II..I." 10 | "r7",,"..II...." 11 | "r8","roboleft","........" 12 | "r9","****","........" 13 | "r10",,"........" 14 | "r11",,"....D..." 15 | "r12",,"........" 16 | "r13",,"..I....." 17 | "r14",,"..I..II." 18 | "r15",,"..IIIII." 19 | "r16","roboleft","........" 20 | "r17","****","........" 21 | "r18",,".....II." 22 | "r19",,".....II." 23 | "r20",,"........" 24 | "r21",,"........" 25 | "r22",,"..II...." 26 | "r23",,"..IIII.." 27 | "r24","roboleft","........" 28 | "r25","****","........" 29 | "r26",,"..II..I." 30 | "r27",,"..I...I." 31 | "r28",,"......I." 32 | "r29",,"........" 33 | "r30",,"..I....." 34 | "r31",,"..II...." 35 | "r32","roboleft","........" 36 | "r33","****","....D..." 37 | "r34",,"...III.." 38 | "r35",,"........" 39 | "r36",,"........" 40 | "r37",,"..I...I." 41 | "r38",,"..I..II." 42 | "r39",,"..I..II." 43 | "r40","roboleft","........" 44 | "r41","****","........" 45 | "r42",,"....II.." 46 | "r43",,"....II.." 47 | "r44",,"........" 48 | "r45",,"........" 49 | "r46",,".....II." 50 | "r47",,".....II." 51 | "r48","roboleft","........" 52 | "r49","****","........" 53 | "r50",,"....III." 54 | "r51",,"........" 55 | "r52",,"..D...D." 56 | "r53",,"......I." 57 | "r54",,"..I...I." 58 | "r55",,"III...I." 59 | "r56","roboleft","........" 60 | "r57","****","........" 61 | "r58",,"IIII...." 62 | "r59",,"..II...." 63 | "r60",,"........" 64 | "r61",,"........" 65 | "r62",,".....II." 66 | "r63",,"....III." 67 | "r64","roboleft","........" 68 | "r65","****","........" 69 | "r66",,"..II...." 70 | "r67",,"..I....." 71 | "r68",,"..I....." 72 | "r69",,"III....." 73 | "r70",,".....D.." 74 | "r71",,"........" 75 | "r72","roboright","........" 76 | "r73","****","........" 77 | "r74",,"III...D." 78 | "r75",,".....I.." 79 | "r76",,".....I.." 80 | "r77",,".I...I.." 81 | "r78",,".II..I.." 82 | "r79",,"........" 83 | "r80","roboright","........" 84 | "r81","****","........" 85 | "r82",,".II....." 86 | "r83",,".II....." 87 | "r84",,"II......" 88 | "r85",,"........" 89 | "r86",,"....II.." 90 | "r87",,"....II.." 91 | "r88","roboright","........" 92 | "r89","****","........" 93 | "r90",,"..IIII.." 94 | "r91",,"....II.." 95 | "r92",,"..D....." 96 | "r93",,".....D.." 97 | "r94",,".II....." 98 | "r95",,"IIIIII.." 99 | "r96","roboright","........" 100 | "r97","****","........" 101 | "r98",,".....I.." 102 | "r99",,".I...I.." 103 | "r100",,".I...I.." 104 | "r101",,".I...I.." 105 | "r102",,".I......" 106 | "r103",,"II......" 107 | "r104","roboright","........" 108 | "r105","****","......D." 109 | "r106",,"..III..." 110 | "r107",,"........" 111 | "r108",,"........" 112 | "r109",,"II...I.." 113 | "r110",,".I..II.." 114 | "r111",,"....II.." 115 | "r112","roboright","........" 116 | "r113","****","........" 117 | "r114",,".II....." 118 | "r115",,".II....." 119 | "r116",,"........" 120 | "r117",,".D......" 121 | "r118",,"....II.." 122 | "r119",,"....II.." 123 | "r120","roboright","........" 124 | "r121","****","........" 125 | "r122",,"III....." 126 | "r123",,"........" 127 | "r124",,".......D" 128 | "r125",,".D...I.." 129 | "r126",,"....II.." 130 | "r127",,"....IIII" 131 | "r128","roboright","........" 132 | "r129","****","........" 133 | "r130",,".II..III" 134 | "r131",,".I...I.." 135 | "r132",,".....I.." 136 | "r133",,".....I.D" 137 | "r134",,".I......" 138 | "r135",,"III....." 139 | "r136","roboright","........" 140 | "r137","****",".....D.." 141 | "r138",,"IIII...." 142 | "r139",,"........" 143 | "r140",,".D...III" 144 | "r141",,".....I.." 145 | "r142",,".II..I.." 146 | "r143",,".II....." 147 | "r144","roboleft","........" 148 | "r145","****","........" 149 | "r146",,"..IIIII." 150 | "r147",,"..I...I." 151 | "r148",,"..I..DI." 152 | "r149",,"..I...I." 153 | "r150",,"..I...I." 154 | "r151",,"..II..I." 155 | "r152","roboleft","........" 156 | "r153","****","........" 157 | "r154",,"........" 158 | "r155",,"IIIIIII." 159 | "r156",,"....D..." 160 | "r157",,"........" 161 | "r158",,"..I...I." 162 | "r159",,"..IIIII." 163 | "r160","roboright","........" 164 | "r161","****","........" 165 | "r162",,"....D..." 166 | "r163",,"........" 167 | "r164",,".IIIIIII" 168 | "r165",,".I...I.." 169 | "r166",,".I...I.." 170 | "r167",,".I..II.." 171 | "r168","roboright","........" 172 | "r169","****","........" 173 | "r170",,".IIIII.." 174 | "r171",,".I......" 175 | "r172",,".I......" 176 | "r173",,"II...I.." 177 | "r174",,".I...I.." 178 | "r175",,"........" 179 | "r176","spawnroboleft","........" 180 | "r177","****","........" 181 | "r178",,"..III..." 182 | "r179",,"..I....." 183 | "r180",,"..I....." 184 | "r181",,"........" 185 | "r182",,".......5" 186 | "r183",,".....1.1" 187 | "r184","spawnroboright","........" 188 | "r185","****","........" 189 | "r186",,".III...." 190 | "r187",,"...I..II" 191 | "r188",,"...I...." 192 | "r189",,"........" 193 | "r190",,"........" 194 | "r191",,"1......." 195 | "r192","spawnroboleft","........" 196 | "r193","****","........" 197 | "r194",,"...III.." 198 | "r195",,"........" 199 | "r196",,"........" 200 | "r197",,"........" 201 | "r198",,".......5" 202 | "r199",,".....1.1" 203 | "r200","spawnroboright","........" 204 | "r201","****","........" 205 | "r202",,"...I...." 206 | "r203",,"...I...." 207 | "r204",,"...I...." 208 | "r205",,"...I...." 209 | "r206",,"........" 210 | "r207",,"1......." 211 | -------------------------------------------------------------------------------- /DataBase/MongoDB.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import pymongo 3 | import datetime 4 | from DataBase.MongoUtils import MongoUtils 5 | from Logic.Player import Player 6 | import json 7 | import bson 8 | #import dnspython 9 | from Utils.Helpers import Helpers 10 | 11 | 12 | class MongoDB: 13 | def __init__(self, conn_str): 14 | self.player = Player 15 | self.client = pymongo.MongoClient(conn_str, serverSelectionTimeoutMS = 5000) 16 | try: 17 | print(f"{Helpers.cyan}[DEBUG] Connecting to Mongo DataBase...") 18 | self.client.server_info() 19 | except Exception: 20 | print(f"{Helpers.red}[ERROR] Unable to connect to Mongo server!") 21 | sys.exit() 22 | 23 | self.database = self.client['Classic-Brawl'] 24 | self.players = self.database['Players'] 25 | self.clubs = self.database['Clubs'] 26 | self.mongo_utils = MongoUtils() 27 | 28 | self.data = { 29 | 'Name': 'Guest', 30 | 'NameSet': False, 31 | 'Gems': Player.gems, 32 | 'Trophies': Player.trophies, 33 | 'Tickets': Player.tickets, 34 | 'Resources': Player.resources, 35 | 'TokenDoubler': 0, 36 | 'HighestTrophies': 0, 37 | 'HomeBrawler': 0, 38 | 'TrophyRoadReward': 300, 39 | 'ExperiencePoints': Player.exp_points, 40 | 'ProfileIcon': 0, 41 | 'NameColor': 0, 42 | 'UnlockedBrawlers': Player.brawlers_unlocked, 43 | 'BrawlersTrophies': Player.brawlers_trophies, 44 | 'BrawlersHighestTrophies': Player.brawlers_high_trophies, 45 | 'BrawlersLevel': Player.brawlers_level, 46 | 'BrawlersPowerPoints': Player.brawlers_powerpoints, 47 | 'UnlockedSkins': Player.unlocked_skins, 48 | 'SelectedSkins': Player.selected_skins, 49 | 'SelectedBrawler': 0, 50 | 'Region': Player.region, 51 | 'SupportedContentCreator': "Modern Brawl", 52 | 'StarPower': Player.starpower, 53 | 'Gadget': Player.gadget, 54 | 'BrawlPassActivated': False, 55 | 'WelcomeMessageViewed': False, 56 | 'ClubID': 0, 57 | 'ClubRole': 1, 58 | 'TimeStamp': str(datetime.datetime.now()) 59 | } 60 | 61 | self.club_data = { 62 | 'Name': '', 63 | 'Description': '', 64 | 'Region': '', 65 | 'BadgeID': 0, 66 | 'Type': 0, 67 | 'Trophies': 0, 68 | 'RequiredTrophies': 0, 69 | 'FamilyFriendly': 0, 70 | 'Members': [], 71 | 'Messages': [] 72 | } 73 | 74 | def merge(self, dict1, dict2): 75 | return (dict1.update(dict2)) 76 | 77 | 78 | def create_player_account(self, id, token): 79 | auth = { 80 | 'ID': id, 81 | 'Token': token, 82 | } 83 | 84 | auth.update(self.data) 85 | 86 | self.mongo_utils.insert_data(self.players, auth) 87 | 88 | 89 | def load_player_account(self, id, token): 90 | query = {"Token": token} 91 | result = self.mongo_utils.load_document(self.players, query) 92 | 93 | if result: 94 | for x in self.data: 95 | if x not in result: 96 | self.update_player_account(token, x, self.data[x]) 97 | 98 | query = {"Token": token} 99 | result = self.mongo_utils.load_document(self.players, query) 100 | 101 | return result 102 | 103 | 104 | def load_player_account_by_id(self, id): 105 | query = {"ID": id} 106 | result = self.mongo_utils.load_document(self.players, query) 107 | 108 | if result: 109 | return result 110 | 111 | 112 | def update_player_account(self, token, item, value): 113 | query = {"Token": token} 114 | self.mongo_utils.update_document(self.players, query, item, value) 115 | 116 | 117 | def update_all_players(self, query, item, value): 118 | self.mongo_utils.update_all_documents(self.players, query, item, value) 119 | 120 | 121 | def delete_all_players(self, args): 122 | self.mongo_utils.delete_all_documents(self.players, args) 123 | 124 | 125 | def delete_player(self, token): 126 | query = {"Token": token} 127 | self.mongo_utils.delete_document(self.players, query) 128 | 129 | 130 | def load_all_players(self, args): 131 | result = self.mongo_utils.load_all_documents(self.players, args) 132 | 133 | return result 134 | 135 | 136 | def load_all_players_sorted(self, args, element): 137 | result = self.mongo_utils.load_all_documents_sorted(self.players, args, element) 138 | 139 | return result 140 | 141 | 142 | def create_club(self, id, data): 143 | auth = { 144 | 'ID': id, 145 | } 146 | 147 | auth.update(data) 148 | 149 | self.mongo_utils.insert_data(self.clubs, auth) 150 | 151 | 152 | def update_club(self, id, item, value): 153 | query = {"ID": id} 154 | self.mongo_utils.update_document(self.clubs, query, item, value) 155 | 156 | 157 | def load_club(self, id): 158 | query = {"ID": id} 159 | result = self.mongo_utils.load_document(self.clubs, query) 160 | 161 | if result: 162 | for x in self.club_data: 163 | if x not in result: 164 | self.update_club(id, x, self.club_data[x]) 165 | 166 | query = {"ID": id} 167 | result = self.mongo_utils.load_document(self.clubs, query) 168 | 169 | return result 170 | 171 | 172 | def load_all_clubs_sorted(self, args, element): 173 | result = self.mongo_utils.load_all_documents_sorted(self.clubs, args, element) 174 | 175 | return result 176 | 177 | def load_all_clubs(self, args): 178 | result = self.mongo_utils.load_all_documents(self.clubs, args) 179 | 180 | return result 181 | 182 | def delete_club(self, id): 183 | query = {"ID": id} 184 | self.mongo_utils.delete_document(self.clubs, query) -------------------------------------------------------------------------------- /Protocol/Commands/Client/LogicPurchaseOfferCommand.py: -------------------------------------------------------------------------------- 1 | from ByteStream.Reader import Reader 2 | from Logic.Home.LogicShopData import LogicShopData 3 | from Protocol.Messages.Server.AvailableServerCommandMessage import AvailableServerCommandMessage 4 | 5 | class LogicPurchaseOfferCommand(Reader): 6 | def __init__(self, client, player, initial_bytes): 7 | super().__init__(initial_bytes) 8 | self.player = player 9 | self.client = client 10 | 11 | def decode(self): 12 | self.readVInt() 13 | self.readVInt() 14 | self.readLogicLong() 15 | 16 | self.offer_index = self.readVInt() 17 | 18 | self.brawler = self.readDataReference()[1] 19 | 20 | def process(self, db): 21 | offer_id = LogicShopData.offers[self.offer_index]['OfferID'] 22 | offer_resource = LogicShopData.offers[self.offer_index]['ShopType'] 23 | offer_cost = LogicShopData.offers[self.offer_index]['Cost'] 24 | offer_amount = LogicShopData.offers[self.offer_index]['Multiplier'] 25 | offer_char = LogicShopData.offers[self.offer_index]['DataReference'][1] 26 | 27 | if not LogicShopData.offers[self.offer_index]['Claimed']: 28 | 29 | 30 | self.player.delivery_items = { 31 | 'Count': 1, 32 | 'Type': 0, 33 | 'Items': [] 34 | } 35 | 36 | if offer_id == 1: 37 | item = {'Amount': offer_amount, 'DataRef': [0, 0], 'Value':7 } 38 | self.player.delivery_items['Type'] = 100 39 | self.player.delivery_items['Items'].append(item) 40 | 41 | self.player.resources[1]['Amount'] = self.player.resources[1]['Amount'] + offer_amount 42 | db.update_player_account(self.player.token, 'Resources', self.player.resources) 43 | LogicShopData.offers[self.offer_index]['Claimed'] = True 44 | 45 | 46 | elif offer_id == 16: 47 | item = {'Amount': offer_amount, 'DataRef': [0, 0], 'Value':8 } 48 | self.player.delivery_items['Type'] = 100 49 | self.player.delivery_items['Items'].append(item) 50 | 51 | self.player.gems = self.player.gems + offer_amount 52 | db.update_player_account(self.player.token, 'Gems', self.player.gems) 53 | LogicShopData.offers[self.offer_index]['Claimed'] = True 54 | 55 | elif offer_id == 9: 56 | item = {'Amount': offer_amount, 'DataRef': [0, 0], 'Value':2 } 57 | self.player.delivery_items['Type'] = 100 58 | self.player.delivery_items['Items'].append(item) 59 | 60 | self.player.token_doubler = self.player.token_doubler + offer_amount 61 | db.update_player_account(self.player.token, 'TokenDoubler', self.player.token_doubler) 62 | LogicShopData.offers[self.offer_index]['Claimed'] = True 63 | 64 | elif offer_id == 3: 65 | item = {'Amount': offer_amount, 'DataRef': [16, offer_char ], 'Value':1 } 66 | self.player.delivery_items['Type'] = 100 67 | self.player.delivery_items['Items'].append(item) 68 | if offer_char not in self.player.brawlers_unlocked: 69 | self.player.brawlers_unlocked.append(offer_char) 70 | db.update_player_account(self.player.token, 'UnlockedBrawlers', self.player.brawlers_unlocked) 71 | LogicShopData.offers[self.offer_index]['Claimed'] = True 72 | 73 | elif offer_id == 12: 74 | item = {'Amount': offer_amount, 'DataRef': [16, self.brawler ], 'Value':6 } 75 | self.player.delivery_items['Type'] = 100 76 | self.player.delivery_items['Items'].append(item) 77 | 78 | self.player.brawlers_powerpoints[str(self.brawler)] = self.player.brawlers_powerpoints[str(self.brawler)] + offer_amount 79 | db.update_player_account(self.player.token, 'BrawlersPowerPoints', self.player.brawlers_powerpoints) 80 | LogicShopData.offers[self.offer_index]['Claimed'] = True 81 | 82 | 83 | elif offer_id == 8: 84 | item = {'Amount': offer_amount, 'DataRef': [16, offer_char ], 'Value':6 } 85 | self.player.delivery_items['Type'] = 100 86 | self.player.delivery_items['Items'].append(item) 87 | 88 | self.player.brawlers_powerpoints[str(offer_char)] = self.player.brawlers_powerpoints[str(offer_char)] + offer_amount 89 | db.update_player_account(self.player.token, 'BrawlersPowerPoints', self.player.brawlers_powerpoints) 90 | LogicShopData.offers[self.offer_index]['Claimed'] = True 91 | 92 | elif offer_id in [0, 6]: 93 | self.player.delivery_items['Type'] = 10 94 | self.player.delivery_items['Count'] = offer_amount 95 | LogicShopData.offers[self.offer_index]['Claimed'] = True 96 | 97 | 98 | elif offer_id == 14: 99 | self.player.delivery_items['Type'] = 12 100 | self.player.delivery_items['Count'] = offer_amount 101 | LogicShopData.offers[self.offer_index]['Claimed'] = True 102 | 103 | 104 | elif offer_id == 10: 105 | self.player.delivery_items['Type'] = 11 106 | self.player.delivery_items['Count'] = offer_amount 107 | LogicShopData.offers[self.offer_index]['Claimed'] = True 108 | 109 | else: 110 | print(f"Unsupported offer ID: {offer_id}") 111 | 112 | 113 | if offer_resource == 0: 114 | self.player.gems = self.player.gems - offer_cost 115 | db.update_player_account(self.player.token, 'Gems', self.player.gems) 116 | 117 | elif offer_resource == 1: 118 | self.player.resources[1]['Amount'] = self.player.resources[1]['Amount'] - offer_cost 119 | db.update_player_account(self.player.token, 'Resources', self.player.resources) 120 | 121 | elif offer_resource == 3: 122 | self.player.resources[3]['Amount'] = self.player.resources[3]['Amount'] - offer_cost 123 | db.update_player_account(self.player.token, 'Resources', self.player.resources) 124 | 125 | self.player.db = db 126 | 127 | AvailableServerCommandMessage(self.client, self.player, 203).send() 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/regions.csv: -------------------------------------------------------------------------------- 1 | Name,TID,DisplayName,IsCountry 2 | String,String,String,boolean 3 | _EU,,Europe,FALSE 4 | _NA,,North America,FALSE 5 | _SA,,South America,FALSE 6 | _AS,,Asia,FALSE 7 | _AU,,Australia,FALSE 8 | _AF,,Africa,FALSE 9 | _INT,TID_REGION_INT,International,FALSE 10 | AF,,Afghanistan,TRUE 11 | AX,,Åland Islands,TRUE 12 | AL,,Albania,TRUE 13 | DZ,,Algeria,TRUE 14 | AS,,American Samoa,TRUE 15 | AD,,Andorra,TRUE 16 | AO,,Angola,TRUE 17 | AI,,Anguilla,TRUE 18 | AQ,,Antarctica,TRUE 19 | AG,,Antigua and Barbuda,TRUE 20 | AR,,Argentina,TRUE 21 | AM,,Armenia,TRUE 22 | AW,,Aruba,TRUE 23 | AC,,Ascension Island,TRUE 24 | AU,,Australia,TRUE 25 | AT,,Austria,TRUE 26 | AZ,,Azerbaijan,TRUE 27 | BS,,Bahamas,TRUE 28 | BH,,Bahrain,TRUE 29 | BD,,Bangladesh,TRUE 30 | BB,,Barbados,TRUE 31 | BY,,Belarus,TRUE 32 | BE,,Belgium,TRUE 33 | BZ,,Belize,TRUE 34 | BJ,,Benin,TRUE 35 | BM,,Bermuda,TRUE 36 | BT,,Bhutan,TRUE 37 | BO,,Bolivia,TRUE 38 | BA,,Bosnia and Herzegovina,TRUE 39 | BW,,Botswana,TRUE 40 | BV,,Bouvet Island,TRUE 41 | BR,,Brazil,TRUE 42 | IO,,British Indian Ocean Territory,TRUE 43 | VG,,British Virgin Islands,TRUE 44 | BN,,Brunei,TRUE 45 | BG,,Bulgaria,TRUE 46 | BF,,Burkina Faso,TRUE 47 | BI,,Burundi,TRUE 48 | KH,,Cambodia,TRUE 49 | CM,,Cameroon,TRUE 50 | CA,,Canada,TRUE 51 | IC,,Canary Islands,TRUE 52 | CV,,Cape Verde,TRUE 53 | BQ,,Caribbean Netherlands,TRUE 54 | KY,,Cayman Islands,TRUE 55 | CF,,Central African Republic,TRUE 56 | EA,,Ceuta and Melilla,TRUE 57 | TD,,Chad,TRUE 58 | CL,,Chile,TRUE 59 | CN,,China,TRUE 60 | CX,,Christmas Island,TRUE 61 | CC,,Cocos (Keeling) Islands,TRUE 62 | CO,,Colombia,TRUE 63 | KM,,Comoros,TRUE 64 | CG,,Congo (DRC),TRUE 65 | CD,,Congo (Republic),TRUE 66 | CK,,Cook Islands,TRUE 67 | CR,,Costa Rica,TRUE 68 | CI,,Côte d’Ivoire,TRUE 69 | HR,,Croatia,TRUE 70 | CU,,Cuba,TRUE 71 | CW,,Curaçao,TRUE 72 | CY,,Cyprus,TRUE 73 | CZ,,Czech Republic,TRUE 74 | DK,,Denmark,TRUE 75 | DG,,Diego Garcia,TRUE 76 | DJ,,Djibouti,TRUE 77 | DM,,Dominica,TRUE 78 | DO,,Dominican Republic,TRUE 79 | EC,,Ecuador,TRUE 80 | EG,,Egypt,TRUE 81 | SV,,El Salvador,TRUE 82 | GQ,,Equatorial Guinea,TRUE 83 | ER,,Eritrea,TRUE 84 | EE,,Estonia,TRUE 85 | ET,,Ethiopia,TRUE 86 | FK,,Falkland Islands,TRUE 87 | FO,,Faroe Islands,TRUE 88 | FJ,,Fiji,TRUE 89 | FI,,Finland,TRUE 90 | FR,,France,TRUE 91 | GF,,French Guiana,TRUE 92 | PF,,French Polynesia,TRUE 93 | TF,,French Southern Territories,TRUE 94 | GA,,Gabon,TRUE 95 | GM,,Gambia,TRUE 96 | GE,,Georgia,TRUE 97 | DE,,Germany,TRUE 98 | GH,,Ghana,TRUE 99 | GI,,Gibraltar,TRUE 100 | GR,,Greece,TRUE 101 | GL,,Greenland,TRUE 102 | GD,,Grenada,TRUE 103 | GP,,Guadeloupe,TRUE 104 | GU,,Guam,TRUE 105 | GT,,Guatemala,TRUE 106 | GG,,Guernsey,TRUE 107 | GN,,Guinea,TRUE 108 | GW,,Guinea-Bissau,TRUE 109 | GY,,Guyana,TRUE 110 | HT,,Haiti,TRUE 111 | HM,,Heard & McDonald Islands,TRUE 112 | HN,,Honduras,TRUE 113 | HK,,Hong Kong,TRUE 114 | HU,,Hungary,TRUE 115 | IS,,Iceland,TRUE 116 | IN,,India,TRUE 117 | ID,,Indonesia,TRUE 118 | IR,,Iran,TRUE 119 | IQ,,Iraq,TRUE 120 | IE,,Ireland,TRUE 121 | IM,,Isle of Man,TRUE 122 | IL,,Israel,TRUE 123 | IT,,Italy,TRUE 124 | JM,,Jamaica,TRUE 125 | JP,,Japan,TRUE 126 | JE,,Jersey,TRUE 127 | JO,,Jordan,TRUE 128 | KZ,,Kazakhstan,TRUE 129 | KE,,Kenya,TRUE 130 | KI,,Kiribati,TRUE 131 | XK,,Kosovo,TRUE 132 | KW,,Kuwait,TRUE 133 | KG,,Kyrgyzstan,TRUE 134 | LA,,Laos,TRUE 135 | LV,,Latvia,TRUE 136 | LB,,Lebanon,TRUE 137 | LS,,Lesotho,TRUE 138 | LR,,Liberia,TRUE 139 | LY,,Libya,TRUE 140 | LI,,Liechtenstein,TRUE 141 | LT,,Lithuania,TRUE 142 | LU,,Luxembourg,TRUE 143 | MO,,Macau,TRUE 144 | MK,,Macedonia (FYROM),TRUE 145 | MG,,Madagascar,TRUE 146 | MW,,Malawi,TRUE 147 | MY,,Malaysia,TRUE 148 | MV,,Maldives,TRUE 149 | ML,,Mali,TRUE 150 | MT,,Malta,TRUE 151 | MH,,Marshall Islands,TRUE 152 | MQ,,Martinique,TRUE 153 | MR,,Mauritania,TRUE 154 | MU,,Mauritius,TRUE 155 | YT,,Mayotte,TRUE 156 | MX,,Mexico,TRUE 157 | FM,,Micronesia,TRUE 158 | MD,,Moldova,TRUE 159 | MC,,Monaco,TRUE 160 | MN,,Mongolia,TRUE 161 | ME,,Montenegro,TRUE 162 | MS,,Montserrat,TRUE 163 | MA,,Morocco,TRUE 164 | MZ,,Mozambique,TRUE 165 | MM,,Myanmar (Burma),TRUE 166 | NA,,Namibia,TRUE 167 | NR,,Nauru,TRUE 168 | NP,,Nepal,TRUE 169 | NL,,Netherlands,TRUE 170 | NC,,New Caledonia,TRUE 171 | NZ,,New Zealand,TRUE 172 | NI,,Nicaragua,TRUE 173 | NE,,Niger,TRUE 174 | NG,,Nigeria,TRUE 175 | NU,,Niue,TRUE 176 | NF,,Norfolk Island,TRUE 177 | KP,,North Korea,TRUE 178 | MP,,Northern Mariana Islands,TRUE 179 | NO,,Norway,TRUE 180 | OM,,Oman,TRUE 181 | PK,,Pakistan,TRUE 182 | PW,,Palau,TRUE 183 | PS,,Palestine,TRUE 184 | PA,,Panama,TRUE 185 | PG,,Papua New Guinea,TRUE 186 | PY,,Paraguay,TRUE 187 | PE,,Peru,TRUE 188 | PH,,Philippines,TRUE 189 | PN,,Pitcairn Islands,TRUE 190 | PL,,Poland,TRUE 191 | PT,,Portugal,TRUE 192 | PR,,Puerto Rico,TRUE 193 | QA,,Qatar,TRUE 194 | RE,,Réunion,TRUE 195 | RO,,Romania,TRUE 196 | RU,,Russia,TRUE 197 | RW,,Rwanda,TRUE 198 | BL,,Saint Barthélemy,TRUE 199 | SH,,Saint Helena,TRUE 200 | KN,,Saint Kitts and Nevis,TRUE 201 | LC,,Saint Lucia,TRUE 202 | MF,,Saint Martin,TRUE 203 | PM,,Saint Pierre and Miquelon,TRUE 204 | WS,,Samoa,TRUE 205 | SM,,San Marino,TRUE 206 | ST,,São Tomé and Príncipe,TRUE 207 | SA,,Saudi Arabia,TRUE 208 | SN,,Senegal,TRUE 209 | RS,,Serbia,TRUE 210 | SC,,Seychelles,TRUE 211 | SL,,Sierra Leone,TRUE 212 | SG,,Singapore,TRUE 213 | SX,,Sint Maarten,TRUE 214 | SK,,Slovakia,TRUE 215 | SI,,Slovenia,TRUE 216 | SB,,Solomon Islands,TRUE 217 | SO,,Somalia,TRUE 218 | ZA,,South Africa,TRUE 219 | KR,,South Korea,TRUE 220 | SS,,South Sudan,TRUE 221 | ES,,Spain,TRUE 222 | LK,,Sri Lanka,TRUE 223 | VC,,St. Vincent & Grenadines,TRUE 224 | SD,,Sudan,TRUE 225 | SR,,Suriname,TRUE 226 | SJ,,Svalbard and Jan Mayen,TRUE 227 | SZ,,Swaziland,TRUE 228 | SE,,Sweden,TRUE 229 | CH,,Switzerland,TRUE 230 | SY,,Syria,TRUE 231 | TW,,Taiwan,TRUE 232 | TJ,,Tajikistan,TRUE 233 | TZ,,Tanzania,TRUE 234 | TH,,Thailand,TRUE 235 | TL,,Timor-Leste,TRUE 236 | TG,,Togo,TRUE 237 | TK,,Tokelau,TRUE 238 | TO,,Tonga,TRUE 239 | TT,,Trinidad and Tobago,TRUE 240 | TA,,Tristan da Cunha,TRUE 241 | TN,,Tunisia,TRUE 242 | TR,,Turkey,TRUE 243 | TM,,Turkmenistan,TRUE 244 | TC,,Turks and Caicos Islands,TRUE 245 | TV,,Tuvalu,TRUE 246 | UM,,U.S. Outlying Islands,TRUE 247 | VI,,U.S. Virgin Islands,TRUE 248 | UG,,Uganda,TRUE 249 | UA,,Ukraine,TRUE 250 | AE,,United Arab Emirates,TRUE 251 | GB,,United Kingdom,TRUE 252 | US,,United States,TRUE 253 | UY,,Uruguay,TRUE 254 | UZ,,Uzbekistan,TRUE 255 | VU,,Vanuatu,TRUE 256 | VA,,Vatican City,TRUE 257 | VE,,Venezuela,TRUE 258 | VN,,Vietnam,TRUE 259 | WF,,Wallis and Futuna,TRUE 260 | EH,,Western Sahara,TRUE 261 | YE,,Yemen,TRUE 262 | ZM,,Zambia,TRUE 263 | ZW,,Zimbabwe,TRUE 264 | CUSTOM1,TID_REGION_CUSTOM1,,FALSE 265 | CUSTOM2,TID_REGION_CUSTOM2,,FALSE 266 | CUSTOM3,TID_REGION_CUSTOM3,,FALSE 267 | CUSTOM4,TID_REGION_CUSTOM4,,FALSE 268 | CUSTOM5,TID_REGION_CUSTOM5,,FALSE 269 | -------------------------------------------------------------------------------- /GameAssets/csv_logic/accessories.csv: -------------------------------------------------------------------------------- 1 | "Name","Type","SubType","ChargeCount","Cooldown","UseEffect","LoopingEffect","LoopingEffectPet","ActivationDelay","ActiveTicks","StopMovement","AnimationIndex","SetAttackAngle","AimGuideType","ConsumesAmmo","AreaEffect","PetAreaEffect","InterruptsAction","AllowStunActivation","RequirePetDistance","DestroyPet","Range","RequireEnemyInRange","TargetFriends","TargetIndirect","ShieldPercent","ShieldTicks","SpeedBoost","SpeedBoostTicks","SkipTypeCondition","CustomObject","CustomValue1","CustomValue2","CustomValue3","CustomValue4","CustomValue5","CustomValue6","MissingTargetText","TargetTooFarText","TargetAlreadyActiveText" 2 | "string","string","int","int","int","string","string","string","int","int","boolean","int","boolean","int","boolean","string","string","boolean","boolean","int","boolean","int","boolean","boolean","boolean","int","int","int","int","boolean","string","int","int","int","int","int","int","string","string","string" 3 | "Rosa_GrowBush",,,3,100,"gadget_activate",,,,,,,,1,,"BushGrowArea",,,,,,,,,,,,,,,,,,,,,,,, 4 | "Crow_Shield",,,2,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,60,60,,,,,,,,,,,,, 5 | "Wally_Heal","consume_bush",,3,100,"gadget_activate",,,,,,,,2,,,,"true",,,,,,,,,,,,,,2000,,,,,,,"TID_ACCESSORY_BLOCKED_BUSH_TOO_FAR", 6 | "RocketGirl_Jump","jump",,3,100,"gadget_activate",,,,,,,,1,,"RocketJumpExplosion",,"true",,,,,,,,,,,,,,200,,,,,,,, 7 | "TrickshotDude_ShootAround","repeat_area",,3,100,"gadget_activate",,,,20,,,,,,"TrickshotDudeAccessoryExplosion",,,,,,,,,,,,,,,,10,,,,,,,, 8 | "Cactus_ShootAround","repeat_area",,3,100,"gadget_activate",,,,30,,,,,,"CactusAccessoryExplosion",,,,,,,,,,,,,,,,10,,,,,,,, 9 | "ArtilleryDude_DestroyPet",,,3,100,"gadget_activate",,,,,,,,3,,,"ArtilleryDudeAccessoryExplosion",,,12,"true",,,,,,,,,,,,,,,,,"TID_ACCESSORY_BLOCKED_MISSING_TURRET","TID_ACCESSORY_BLOCKED_TURRET_TOO_FAR", 10 | "Shaman_PetSlam",,,2,100,"gadget_activate",,,,,,,,3,,,"ShamanBearSlam",,,12,,,,,,,,,,,,,,,,,,"TID_ACCESSORY_BLOCKED_MISSING_BEAR","TID_ACCESSORY_BLOCKED_BEAR_TOO_FAR", 11 | "Barkeep_Slow",,,3,100,"gadget_activate",,,,,,,,1,,"BarkeepSlowPuddle",,,,,,,,,,,,,,,,,,,,,,,, 12 | "Mechanic_Slow",,,3,100,"gadget_activate",,,,,,,,3,,,"MechanicSlowArea",,,12,,,,,,,,,,,,,,,,,,"TID_ACCESSORY_BLOCKED_MISSING_TURRET","TID_ACCESSORY_BLOCKED_TURRET_TOO_FAR", 13 | "HookDude_Push","heal",1,2,100,"gadget_activate",,,,,,,,1,,"HookDudePushback",,,,,,,,,,,,,,"true",,700,,,,,,,, 14 | "ClusterBombDude_Dash","dash",,3,100,"gadget_activate","gadget_max_dash",,,8,,,,,,"ClusterBombDashMine",,"true",,,,,,,,,,,,,,900,2000,,,,,,, 15 | "Speedy_Dash","dash",,3,100,"gadget_activate","gadget_max_dash",,,8,,,,,,,,"true",,,,,,,,100,10,,,,,1000,2400,,,,,,, 16 | "ShotgunGirl_Dash","dash",,3,100,"gadget_activate","gadget_max_dash",,,8,,,,,,,,"true",,,,,,,,,,,,,,900,2000,,,,,,, 17 | "Driller_SpeedBoost",,,3,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,,,158,60,,,,,,,,,,, 18 | "MinigunDude_BurstHeal",,,3,100,"gadget_activate",,,,,,,,3,,,"MinigunDudeTowerBurstHeal",,,12,,,,,,,,,,,,,,,,,,"TID_ACCESSORY_BLOCKED_MISSING_TURRET","TID_ACCESSORY_BLOCKED_TURRET_TOO_FAR", 19 | "TntDude_Spin","spin_shoot",,3,100,"gadget_activate",,,,40,,,,,,,,"true",,,,,,,,,,150,40,,"TntDudeProjectile",2,100,700,700,100,,,, 20 | "Arcade_Teleport","teleport_to_pet",,3,100,"gadget_activate",,,,10,"true",,,,,,,"true",,12,,,,,,,,,,,"ArcadeTeleport",,,,,,,"TID_ACCESSORY_BLOCKED_MISSING_TURRET","TID_ACCESSORY_BLOCKED_TURRET_TOO_FAR", 21 | "BarrelBot_Spin","spin_shoot",,3,100,"gadget_activate","darryl_def_atk",,,15,,,,,,,,"true",,,,,,,,,,,,,"BarrelBotSpinProjectile",1,25,400,2500,0,1000,,, 22 | "HammerDude_Immunity","cc_immunity",,3,100,"gadget_activate","gadget_frank_headphones",,,30,,,,,,,,,"true",,,,,,,,,,,,,30,,,,,,,, 23 | "Whirlwind_Trail","trail",,3,100,"gadget_activate",,,,100,,,,,,,,,,,,,,,,,,,,,"WhirlwindTrail",,,,,,,,, 24 | "BowDude_Totem","spawn",1,3,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,,,,,,"BowDudeTotem",,,,,,,,, 25 | "Luchador_Grab","throw_opponent",,3,100,"gadget_activate",,,,10,"true",,,4,,,,"true",,,,3,"true",,,,,,,,,300,,,,,,,, 26 | "Undertaker_Swing","spin_shoot",,3,100,"gadget_activate",,,,8,,,,1,,"UndertakerSwingDamage",,"true",,,,,,,,,,,,,,100,,,,,,,, 27 | "BlackHole_Vision","vision",,3,100,"gadget_activate","gadget_tara_vision",,,100,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 28 | "DeadMariachi_Regen",,,3,100,"gadget_activate",,,,,,,,1,,"PocoRegenArea",,,,,,,,,,,,,,,,,,,,,,,, 29 | "Sniper_HandGun","repeat_shot",,3,100,"gadget_activate",,,,5,,1,"true",4,,,,"true",,,,7,"true",,,,,,,,"PiperHandgunProjectile",5,100,,,,,,, 30 | "SpawnerDude_Promote","promote_minion",,3,100,"gadget_activate",,,,,,,,,,,,,,12,,,,,,,,,,,,150,1000,,,,,"TID_ACCESSORY_BLOCKED_NO_PORTERS_IN_RANGE","TID_ACCESSORY_BLOCKED_NO_PORTERS_IN_RANGE","TID_ACCESSORY_BLOCKED_PORTER_ALREADY_PROMOTED" 31 | "Sandstorm_Sleep","heal",1,3,100,"gadget_activate","gadget_sandy_sleep",,40,,"true",,,,,,,"true",,,,,,,,,,,,,,,,,,,,,, 32 | "BeeSniper_Slow","spawn",1,3,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,,,,,,"BeeSniperSlowPot",,,,,,,,, 33 | "BullDude_Heal","heal",1,3,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,,,,,,,1500,,,,,,,, 34 | "Gunslinger_Reload","reload",,3,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,,,,,,,200,,,,,,,, 35 | "Mummy_Push",,,3,100,"gadget_activate",,,,,,,,1,,"MummyAccessoryPushback",,,,,,,,,,,,,,,,,,,,,,,, 36 | "Baseball_Heal","heal",2,3,100,"gadget_activate",,,,80,,,,,,,,,,,,,,,,,,,,,,600,,,,,,,, 37 | "Ninja_Fake","spawn",2,3,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,,,,,,"NinjaFake",200,,,,,,,, 38 | "Blower_Trampoline","spawn",3,3,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 39 | "Controller_Explode","kill_projectile",,3,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,,,,,,"ArcadeTeleport",,,,,,,"TID_ACCESSORY_BLOCKED_MISSING_GUIDED_PROJECTILE",, 40 | "PowerLeveler_Blink","teleport_forward",,3,100,"gadget_activate",,,,5,"true",,,,,,,"true",,,,,,,,,,,,,"ArcadeTeleport",1000,,,,,,,, 41 | "Crow_PoisonTrigger","poison_trigger",,3,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,,,,,,,350,50,,,,,,, 42 | "ArtilleryDude_Barrage","turret_barrage",,3,100,"gadget_activate",,,,25,,,,,,,,,,14,,,,,,,,,,,,5,500,,,,,"TID_ACCESSORY_BLOCKED_MISSING_TURRET","TID_ACCESSORY_BLOCKED_TURRET_TOO_FAR", 43 | "ShotgunGirl_Focus","next_attack_change",1,3,100,"gadget_activate","gadget_on_loop",,,100000,,,,,,,,,,,,,,,,,,,,,,20,10,1000,,,,,,"TID_ACCESSORY_BLOCKED_ALREADY_ACTIVE" 44 | "BowDude_MineTrigger","mine_trigger",,3,100,"gadget_activate",,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,"TID_ACCESSORY_BLOCKED_MISSING_MINES",, 45 | "Undertaker_Reload","reload_speed",,3,100,"gadget_activate",,,,80,,,,,,,,,,,,,,,,,,,,,,80,,,,,,,, 46 | "Sniper_Seeker","next_attack_change",2,3,100,"gadget_activate","gadget_on_loop",,,100000,,,,,,,,,,,,,,,,,,,,,"SniperHomingProjectile",,,,,,,,,"TID_ACCESSORY_BLOCKED_ALREADY_ACTIVE" 47 | "Luchador_Meteor","spawn",4,3,100,"gadget_activate",,,,,,,,4,,,,,,,,10,"true",,"true",,,,,,"LuchadorMeteorSpawn",,,,,,,,, 48 | "Barkeep_HealPotion","repeat_shot",,3,100,"gadget_activate",,,,30,,,"true",4,,,,"true",,,,10,,"true","true",,,,,,"BarkeepHealingProjectile",5,-500,3000,,,,,, 49 | "TntDude_Stun","next_attack_change",3,3,100,"gadget_activate","gadget_on_loop",,,100000,,,,,,,,,,,,,,,,,,,,,,30,,,,,,,,"TID_ACCESSORY_BLOCKED_ALREADY_ACTIVE" 50 | "Mechanic_TurretBuff","pet_attack_speed",,3,100,"gadget_activate",,"gadget_pet_on_loop",,100,,,,,,,,,,12,,,,,,,,,,,,3,,,,,,"TID_ACCESSORY_BLOCKED_MISSING_TURRET","TID_ACCESSORY_BLOCKED_TURRET_TOO_FAR", 51 | -------------------------------------------------------------------------------- /GameAssets/csv_client/shop_items.csv: -------------------------------------------------------------------------------- 1 | "Name","OfferType","IconFrameNumber","MaxResourcePerFrame","FileName","ShopItemAsset","PopupItemAsset","ShopItemBg","MiniOfferAsset","SeparatedSectionOfferAsset","SeparatedSectionTeaseAsset","SeasonalEventOfferAsset","LegendaryOfferAsset","ConfirmItemAsset","ConfirmItemBg","OfferAssetSmall","OfferAssetLarge","OfferAssetVerySmall","OfferAssetRankProfile","OfferAssetRankLarge","BrawlPassAssetPaid","BrawlPassAssetFree" 2 | "String","int","int","int","String","String","String","String","String","String","String","String","String","String","String","String","String","String","String","String","String","String" 3 | "FreeBox",0,0,,"sc/ui.sc","shop_item_resourses_boxes",,"shop_price_wrapper_1","shop_item_boxes",,,,"shop_item_resourses_boxes","shop_popupitem_6","shop_popupprice_wrapper_1",,,,,,, 4 | "UpgradeMaterial",1,0,200,"sc/ui.sc","shop_item_resourses_coins","shop_popupitem_1","shop_price_wrapper_1","shop_item_resourses_coins",,,,"shop_item_resourses_coins",,"shop_popupprice_wrapper_1","offer_item_coins_small","offer_item_coins_big",,"reward_profilebutton_1","reward_popupitem_large_1","brawlpass_reward_premium_coins","brawlpass_reward_free_coins" 5 | ,,1,500,,,,,,,,,,,,,,,,,, 6 | ,,2,1500,,,,,,,,,,,,,,,,,, 7 | ,,3,-1,,,,,,,,,,,,,,,,,, 8 | "GuaranteedBox",2,,,"sc/ui.sc","shop_item_brawler","shop_popupitem_2","shop_price_wrapper_1","shop_item_brawler",,,,"shop_item_brawler",,"shop_popupprice_wrapper_1","offer_item_guarantee_brawler_small","offer_item_guarantee_brawler_big",,,,, 9 | "GuaranteedHero",3,,,"sc/ui.sc","shop_listitem_3","shop_popupitem_3","shop_price_wrapper_1","shop_listitem_3",,,,"shop_listitem_3",,"shop_popupprice_wrapper_1","offer_item_brawler_small","offer_item_brawler_big","offer_item_skin_small","reward_profilebutton_3","reward_popupitem_large_3","brawlpass_reward_premium_brawler","offer_item_skin_small" 10 | "Skin",4,,,"sc/ui.sc","shop_listitem_4","shop_popupitem_4","shop_price_wrapper_1","shop_listitem_4","shop_item_skins","shop_item_skins_coming_soon","shop_item_event_skins","shop_item_legendary_skins",,"shop_popupprice_wrapper_1","offer_item_brawler_small","offer_item_brawler_big","offer_item_skin_small","reward_profilebutton_3","reward_popupitem_large_3","brawlpass_reward_premium_brawler","offer_item_skin_small" 11 | "StarPower",5,,,"sc/ui.sc","shop_item_starpower","shop_popupitem_5","shop_price_wrapper_1","shop_item_starpower",,,,"shop_item_starpower",,"shop_popupprice_wrapper_1","offer_item_star_power_small","offer_item_star_power_big",,,,, 12 | "BrawlBox",6,0,,"sc/ui.sc","shop_item_resourses_boxes","shop_popupitem_6","shop_price_wrapper_1","shop_item_boxes",,,,"shop_item_resourses_boxes","shop_popupitem_6","shop_popupprice_wrapper_1","offer_item_boxes_small","offer_item_boxes_big",,"reward_profilebutton_6",,"brawlpass_reward_premium_brawl_box","brawlpass_reward_free_brawl_box" 13 | "Ticket",7,0,10,"sc/ui.sc","shop_item_resourses_tickets","shop_popupitem_7","shop_price_wrapper_1","shop_item_resourses_tickets",,,,"shop_item_resourses_tickets",,"shop_popupprice_wrapper_1","offer_item_tickets_small","offer_item_tickets_big",,"reward_profilebutton_7",,, 14 | ,,1,50,,,,,,,,,,,,,,,,,, 15 | ,,2,-1,,,,,,,,,,,,,,,,,, 16 | "HeroPower",8,,,"sc/ui.sc","shop_item_powerpoints","shop_popupitem_8","shop_price_wrapper_1","shop_item_powerpoints",,,,"shop_item_powerpoints",,"shop_popupprice_wrapper_1","offer_item_brawler_ppoints_small","offer_item_brawler_ppoints_big",,,,, 17 | "CoinDoubler",9,,,"sc/ui.sc","shop_item_resourses_coin_doubler","shop_popupitem_9","shop_price_wrapper_1","shop_item_coin_doubler",,,,"shop_item_coin_doubler",,"shop_popupprice_wrapper_1","offer_item_token_doubler_small","offer_item_token_doubler_big",,"reward_profilebutton_9","reward_popupitem_large_9","reward_popupitem_large_9","reward_popupitem_small_9" 18 | "BigBox",10,2,,"sc/ui.sc","shop_item_resourses_boxes","shop_popupitem_10","shop_price_wrapper_1","shop_item_boxes",,,,"shop_item_resourses_boxes","shop_popupitem_10","shop_popupprice_wrapper_1","offer_item_boxes_small","offer_item_boxes_big",,"reward_profilebutton_10","reward_popupitem_large_10","brawlpass_reward_premium_mega_box","brawlpass_reward_free_mega_box" 19 | "Keys",11,,,"sc/ui.sc","shop_listitem_11",,"shop_price_wrapper_1","shop_listitem_11",,,,"shop_listitem_11",,"shop_popupprice_wrapper_1","shop_listitem_11","shop_largeitem_11",,,,, 20 | "WildcardPower",12,,,"sc/ui.sc","shop_listitem_12","shop_popupitem_12","shop_price_wrapper_1","shop_listitem_12",,,,"shop_listitem_12",,"shop_popupprice_wrapper_1","offer_item_power_points_small","offer_item_power_points_big",,"reward_profilebutton_12","reward_popupitem_large_12","brawlpass_reward_premium_power_points","brawlpass_reward_free_power_points" 21 | "EventSlot",13,,,"sc/ui.sc","shop_listitem_13",,"shop_price_wrapper_1","shop_listitem_13",,,,"shop_listitem_13",,"shop_popupprice_wrapper_1","shop_listitem_13","shop_largeitem_13",,"reward_profilebutton_13","reward_popupitem_large_13","reward_popupitem_large_13", 22 | "MediumBox",14,1,,"sc/ui.sc","shop_item_resourses_boxes","shop_popupitem_14","shop_price_wrapper_1","shop_item_boxes",,,,"shop_item_resourses_boxes","shop_popupitem_14","shop_popupprice_wrapper_1","offer_item_boxes_small","offer_item_boxes_big",,"reward_profilebutton_14",,"brawlpass_reward_premium_big_box","brawlpass_reward_free_big_box" 23 | "AdBox",15,,,"sc/ui.sc",,,,,,,,,,,,,,,,, 24 | "Gems",16,0,30,"sc/ui.sc","shop_item_resourses_gems","shop_popupitem_16","shop_price_wrapper_1","shop_item_resourses_gems",,,,"shop_item_resourses_gems",,"shop_popupprice_wrapper_1","offer_item_gems_small","offer_item_gems_big",,"reward_profilebutton_16","reward_popupitem_large_16","reward_popupitem_large_16","brawlpass_reward_free_gems" 25 | ,,1,80,,,,,,,,,,,,,,,,,, 26 | ,,2,170,,,,,,,,,,,,,,,,,, 27 | ,,3,360,,,,,,,,,,,,,,,,,, 28 | ,,4,950,,,,,,,,,,,,,,,,,, 29 | ,,5,2000,,,,,,,,,,,,,,,,,, 30 | "Emote",19,,,"sc/ui.sc","shop_listitem_19","shop_popupitem_19","shop_price_wrapper_1","shop_listitem_19",,,,"shop_listitem_19",,"shop_popupprice_wrapper_1","offer_item_emote_small","offer_item_emote_big",,"reward_profilebutton_19","reward_popupitem_large_19","brawlpass_reward_premium_emote","reward_popupitem_small_19" 31 | "EmoteBundle",20,,,"sc/ui.sc","shop_listitem_21",,"shop_price_wrapper_1","shop_listitem_21",,,,"shop_listitem_21",,"shop_popupprice_wrapper_1","offer_item_random_emotes_small","offer_item_random_emotes_big",,"reward_popupitem_small_20","reward_popupitem_small_20","brawlpass_reward_premium_emote_bundle","reward_popupitem_small_20" 32 | "RandomEmotes",21,,,"sc/ui.sc","shop_listitem_21","shop_popupitem_21","shop_price_wrapper_1","shop_listitem_21",,,,"shop_listitem_21",,"shop_popupprice_wrapper_1","offer_item_random_emotes_small","offer_item_random_emotes_big",,"reward_profilebutton_21","reward_popupitem_large_21","reward_popupitem_large_21","reward_popupitem_small_21" 33 | "RandomEmotesForBrawler",22,,,"sc/ui.sc","shop_listitem_22","shop_popupitem_22","shop_price_wrapper_1","shop_listitem_22",,,,"shop_listitem_22",,"shop_popupprice_wrapper_1","offer_item_random_emotes_for_brawler_small","offer_item_random_emotes_for_brawler_big",,"reward_profilebutton_22","reward_popupitem_large_22","reward_popupitem_large_22","reward_popupitem_small_22" 34 | "RandomEmoteOfRarity",23,,,"sc/ui.sc","shop_listitem_23","shop_popupitem_23","shop_price_wrapper_1","shop_listitem_23",,,,"shop_listitem_23",,"shop_popupprice_wrapper_1","offer_item_random_emote_of_rarity_small","offer_item_random_emote_of_rarity_big",,"reward_profilebutton_22","reward_popupitem_large_22","reward_popupitem_large_22","reward_popupitem_small_22" 35 | -------------------------------------------------------------------------------- /GameAssets/csv_client/faces.csv: -------------------------------------------------------------------------------- 1 | "Name","FileName","ExportName" 2 | "String","String","String" 3 | "BullGuyIdle","ui.sc","hero_portrait" 4 | "BullGuyWalk","ui.sc","hero_portrait" 5 | "BullGuyHappy","ui.sc","hero_portrait" 6 | "BullGuySad","ui.sc","hero_portrait" 7 | "BullGuySignature","ui.sc","hero_portrait" 8 | "ShellyFace","characters.sc","shelly_face" 9 | "ShellyStill","characters.sc","shelly_still" 10 | "ShellyHappy","characters.sc","shelly_happy" 11 | "ShellySad","characters.sc","shelly_sad" 12 | "ShellySadLoop","characters.sc","shelly_sadLoop" 13 | "ShellyBanditFace","characters.sc","shelly_bandit_face" 14 | "JunkerStillFace","characters.sc","jessie_still_face" 15 | "JunkerFace","characters.sc","jessie_face" 16 | "JunkerDreamyFace","characters.sc","jessie_dreamy_face" 17 | "JunkerKnightDarkStill","characters.sc","jessie_knightdark_still" 18 | "JunkerKnightDarkIdle","characters.sc","jessie_knightdark_idle" 19 | "ColtFace","characters.sc","colt_face" 20 | "ColtStill","characters.sc","colt_still" 21 | "ColtHappy","characters.sc","colt_happy" 22 | "ColtSad","characters.sc","colt_sad" 23 | "ColtSadLoop","characters.sc","colt_sadLoop" 24 | "BullFace","characters.sc","bull_face" 25 | "PamFace","characters.sc","pam_def_face" 26 | "PamStill","characters.sc","pam_def_still" 27 | "PamHappy","characters.sc","pam_def_happy" 28 | "CrowFace","characters.sc","crow_def_face" 29 | "CrowHappy","characters.sc","crow_def_happy" 30 | "CrowSad","characters.sc","crow_def_sad" 31 | "Crow002Face","characters.sc","crow_002_face" 32 | "Crow002Happy","characters.sc","crow_002_happy" 33 | "Crow002Sad","characters.sc","crow_002_sad" 34 | "TaraFaceIdle","characters.sc","tara_idle" 35 | "TaraFaceWin","characters.sc","tara_win" 36 | "TaraFaceWinLoop","characters.sc","tara_winloop" 37 | "TaraFaceLose","characters.sc","tara_lose" 38 | "TaraFaceLoseloop","characters.sc","tara_loseloop" 39 | "MortisFace","characters.sc","mortis_face" 40 | "MortisWin","characters.sc","mortis_win" 41 | "MortisWinloop","characters.sc","mortis_winloop" 42 | "PennyFace","characters.sc","penny_face" 43 | "LeonIdle","characters.sc","leon_idle" 44 | "LeonWin","characters.sc","leon_win" 45 | "LeonWinLoop","characters.sc","leon_winloop" 46 | "LeonLose","characters.sc","leon_lose" 47 | "LeonLoseLoop","characters.sc","leon_loseloop" 48 | "MortisNightwitchWin","characters.sc","mortis_nightwitch_win" 49 | "MortisNightwitchFace","characters.sc","mortis_nightwitch_face" 50 | "MortisNightwitchWinloop","characters.sc","mortis_nightwitch_winloop" 51 | "CarlIdle","characters.sc","carl_idle" 52 | "CarlAngry","characters.sc","carl_angry" 53 | "CarlAngryloop","characters.sc","carl_angry_loop" 54 | "CarlProfile","characters.sc","carl_profile" 55 | "BarleyMsFace","characters.sc","barley_ms_face" 56 | "BarleyMsLose","characters.sc","barley_ms_lose" 57 | "BarleyMsLoseloop","characters.sc","barley_ms_loseloop" 58 | "CarlHotrodIdle","characters.sc","hotrod_carl_idle" 59 | "CarlHotrodAngry","characters.sc","hotrod_carl_angry" 60 | "CarlHotrodAngryloop","characters.sc","hotrod_carl_angry_loop" 61 | "Bibi_Idle","characters.sc","bibi_face" 62 | "Bibi_Win","characters.sc","bibi_win" 63 | "BibiGamer_Idle","characters.sc","bibi_002_face" 64 | "BibiGamer_Win","characters.sc","bibi_002_win" 65 | "DynamikeRoboFace","characters.sc","mecha_mike_face" 66 | "DynamikeRoboLose","characters.sc","mecha_mike_lose" 67 | "DynamikeRoboLoseloop","characters.sc","mecha_mike_loseloop" 68 | "ArcadeFace","characters.sc","arcade_def_angry" 69 | "ArcadeLose","characters.sc","arcade_def_continue" 70 | "ArcadeLooseloop","characters.sc","arcade_def_gameover" 71 | "ArcadeClassicFace","characters.sc","arcade_002_angry" 72 | "ArcadeVirusFace","characters.sc","arcade_003_angry" 73 | "ArcadeVirusFaceloop","characters.sc","arcade_003_angryloop" 74 | "ArcadeVirusLose","characters.sc","arcade_003_gameover" 75 | "ArcadeVirusLoseloop","characters.sc","arcade_003_gameover_loop" 76 | "PiperIdleOpen","characters.sc","piper_idle_open" 77 | "PiperIdleClosed","characters.sc","piper_idle_closed" 78 | "PiperWin","characters.sc","piper_win" 79 | "PiperWinLoop","characters.sc","piper_idle_closed" 80 | "PrimoElreyIdle","characters.sc","primo_elrey_idle" 81 | "SandyIdle","characters.sc","sandy_idle" 82 | "SandyWin","characters.sc","sandy_win" 83 | "SandyWinloop","characters.sc","sandy_winloop" 84 | "SandyWalk","characters.sc","sandy_walk" 85 | "SandyProfile","characters.sc","sandy_profile" 86 | "PiperRoseIdleOpen","characters.sc","rose_idle_open" 87 | "PiperRoseIdleClosed","characters.sc","rose_idle_closed" 88 | "PiperRoseWin","characters.sc","rose_win" 89 | "PiperRoseWinLoop","characters.sc","rose_idle_closed" 90 | "FrankIdle","characters.sc","frank_idle" 91 | "FrankDJIdle","characters.sc","dj_idle" 92 | "FrankDJWin","characters.sc","dj_win" 93 | "FrankDJWinLoop","characters.sc","dj_winLoop" 94 | "LeonWolfIdle","characters.sc","wolf_leon_idle" 95 | "LeonWolfWin","characters.sc","wolf_leon_win" 96 | "EmzIdle","characters.sc","emz_idle" 97 | "EmzWin","characters.sc","emz_win" 98 | "EmzWinLoop","characters.sc","emz_winloop" 99 | "EmzFront","characters.sc","emz_front" 100 | "EmzLose","characters.sc","emz_lose" 101 | "EmzLoseLoop","characters.sc","emz_loseloop" 102 | "BrownIdle","characters.sc","primo_brown_idle" 103 | "BrownWin","characters.sc","primo_brown_win" 104 | "BrownWinLoop","characters.sc","primo_brown_winLoop" 105 | "BrownLose","characters.sc","primo_brown_lose" 106 | "BrownLoseLoop","characters.sc","primo_brown_loseLoop" 107 | "BrownHS","characters.sc","primo_brown_hS" 108 | "CarlLeonardIdle","characters.sc","carl_leonard_idle" 109 | "CarlLeonardHappy","characters.sc","carl_leonard_happy" 110 | "CarlLeonardSad","characters.sc","carl_leonard_sad" 111 | "CarlLeonardSadLoop","characters.sc","carl_leonard_sadLoop" 112 | "CarlPirateIdle","characters.sc","pirate_carl_idle" 113 | "CarlPirateAngry","characters.sc","pirate_carl_angry" 114 | "CarlPirateAngryloop","characters.sc","carl_angry_loop" 115 | "CarlPirateProfile","characters.sc","pirate_carl_profile" 116 | "BeaIdle","characters.sc","bea_idle" 117 | "BeaHappy","characters.sc","bea_happy" 118 | "BeaLose","characters.sc","bea_lose" 119 | "BeaLoseloop","characters.sc","bea_loseloop" 120 | "MaxIdle","characters.sc","max_idle" 121 | "MaxLose","characters.sc","max_lose" 122 | "MaxLoseloop","characters.sc","max_loseloop" 123 | "TaraStreeninjaFaceIdle","characters.sc","tara_streetninja_idle" 124 | "MrPPetOff","characters.sc","mrp_pet_off" 125 | "MrPPetOn","characters.sc","mrp_pet_on" 126 | "MrPAgentpPetOff","characters.sc","mrp_agentp_pet_off" 127 | "MrPAgentpPetOn","characters.sc","mrp_agentp_pet_on" 128 | "JackyIdle","characters.sc","jacky_idle" 129 | "JackyWin","characters.sc","jacky_win" 130 | "JackyWinLoop","characters.sc","jacky_winloop" 131 | "JackyLose","characters.sc","jacky_lose" 132 | "JackyLoseLoop","characters.sc","jacky_lose" 133 | "JackyPortrait","characters.sc","jacky_portrait" 134 | "Jacky002Idle","characters.sc","jacky_002_idle" 135 | "Jacky002Win","characters.sc","jacky_002_win" 136 | "Jacky002WinLoop","characters.sc","jacky_002_winloop" 137 | "Jacky002Lose","characters.sc","jacky_002_lose" 138 | "Jacky002LoseLoop","characters.sc","jacky_002_loseloop" 139 | "GeneBazaarHappy","characters.sc","gene_003_happy" 140 | "GeneBazaarIdle","characters.sc","gene_003_idle" 141 | "GeneBazaarIntro","characters.sc","gene_003_intro" 142 | "GeneBazaarSad","characters.sc","gene_003_sad" 143 | "MortisBazaarFace","characters.sc","mortis_002_face" 144 | "MortisBazaarIdle","characters.sc","mortis_002_idle" 145 | --------------------------------------------------------------------------------