├── LICENSE ├── README.md ├── START BOT.bat ├── auths.json ├── config.json ├── fortnite.py ├── info.json └── requirements.txt /LICENSE: -------------------------------------------------------------------------------- 1 | 1. You are allowed to modify the code, but you have to keep Credits in Console. 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![GitHub stars](https://img.shields.io/github/stars/KaosDrip/Xensis.svg)](https://github.com/KaosDrip/Xensis/stargazers) 2 | [![Python version](https://img.shields.io/badge/python-3.6%2B-blue.svg)](https://python.org) 3 | 4 | # Xensis 5 | 6 | An expansive Fortnite lobby bot packed with powerful features to enhance your gaming experience. 7 | 8 | > Join our community: [Xensis Bots Discord](https://discord.gg/88r2ShB) 9 | 10 | --- 11 | 12 | ## Overview 13 | 14 | Xensis is a feature-rich Fortnite lobby bot designed to automate and elevate your in-game interactions. Whether you're switching skins, managing parties, or showcasing your style, Xensis has you covered—all with a sleek, user-friendly setup. 15 | 16 | --- 17 | 18 | ## Getting Started 19 | 20 | Follow these steps to get Xensis up and running on your local machine for development, testing, or just having fun. 21 | 22 | ### Prerequisites 23 | 24 | - **Python 3.6+**: Ensure you have Python 3.6 or higher installed. 25 | [Download Python](https://www.python.org/downloads/release/python-370/) 26 | 27 | --- 28 | 29 | ### Installation 30 | 31 | Setting up Xensis is quick and easy—no separate package installation required! 32 | 33 | 1. **Clone or Download** 34 | Grab the repository from GitHub by clicking "Clone or Download". 35 | 36 | 2. **Extract Files** 37 | Unzip the downloaded files to a folder on your PC. 38 | 39 | 3. **Create an Epic Games Account** 40 | Set up a new Epic Games account dedicated to your bot. 41 | 42 | 4. **Configure the Bot** 43 | Open `config.json` and fill in your bot’s details. Need help? Check the [Config Guide](https://github.com/KaosDrip/Xensis/wiki/Config-Guide). 44 | 45 | 5. **Launch Xensis** 46 | Double-click `START BOT.bat`—it automatically installs all required packages and starts the bot for you! 47 | 48 | 6. **Enjoy!** 49 | Your bot is ready! Explore the full command list in the [Command Wiki](https://github.com/KaosDrip/Xensis/wiki/Commands). 50 | 51 | --- 52 | 53 | ### How `START BOT.bat` Works 54 | 55 | The `START BOT.bat` script is your one-stop solution: 56 | - **Installs Dependencies**: Automatically updates and installs packages from `requirements.txt`. 57 | - **Clears the Console**: Gives you a clean slate for the bot’s output. 58 | - **Runs the Bot**: Launches `fortnite.py` with a single click. 59 | 60 | No need for a separate "Install Packages" step—it’s all handled for you! 61 | 62 | --- 63 | 64 | ## Deployment 65 | 66 | - **Authorization Code**: If prompted, get your code from the [Authorization Code Guide](https://github.com/KaosDrip/Xensis/wiki/Authorization-Code). 67 | - **Troubleshooting**: Run into issues? Join our [Discord Server](https://discord.gg/88r2ShB) or check the [FAQ](https://github.com/KaosDrip/Xensis/wiki/FAQ). 68 | 69 | --- 70 | 71 | ## Features 72 | 73 | - **Dynamic Skin Switching**: Change your bot’s in-game look on the fly. 74 | - **Party Management**: Invite, kick, or promote players with ease. 75 | - **Live Patch Updates**: Always shows the current Fortnite patch via the Fortnite API. 76 | - **Admin Controls**: Secure commands for trusted users. 77 | 78 | For a full list, see the [Command Wiki](https://github.com/KaosDrip/Xensis/wiki/Commands). 79 | 80 | --- 81 | 82 | ## Acknowledgments 83 | 84 | - **[rebootpy](https://github.com/rebootpy/rebootpy)**: The backbone of Xensis, powering Fortnite interactions. 85 | Check the [rebootpy Docs](https://rebootpy.readthedocs.io/en/latest/intro.html) for more details. 86 | - **Community**: Thanks to everyone in the [Xensis Bots Discord](https://discord.gg/88r2ShB) for feedback and support! 87 | 88 | --- 89 | 90 | ## Contributing 91 | 92 | Love Xensis? Want to make it better? Fork the repo, submit a pull request, or share your ideas on [Discord](https://discord.gg/88r2ShB). 93 | 94 | --- 95 | 96 | ## License 97 | 98 | This project is open-source and free to use. See the [LICENSE](LICENSE) file for details. 99 | 100 | --- 101 | 102 | *Created by [KaosDrip](https://github.com/KaosDrip) – Bringing Fortnite bots to life since 2023.* 103 | -------------------------------------------------------------------------------- /START BOT.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | title Xensis Lobby Bot created by github.com/KaosDrip. 3 | 4 | ECHO Installing the required packages for the bot! 5 | TIMEOUT 3 6 | 7 | py -3 -m pip install -U -r requirements.txt 8 | 9 | CLS 10 | ECHO Starting the bot... 11 | 12 | py fortnite.py 13 | cmd /k 14 | -------------------------------------------------------------------------------- /auths.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "email": "", 3 | "password": "", 4 | "cid": "CID_028_Athena_Commando_F", 5 | "bid": "BID_004_BlackKnight", 6 | "pid": "Pickaxe_Lockjaw", 7 | "banner": "otherbanner27", 8 | "banner_color": "defaultcolor22", 9 | "level": "999", 10 | "bp_tier": "999", 11 | "status": "Xensis Lobby Bot - discord.gg/88r2ShB", 12 | "platform": "PSN", 13 | "friendaccept": "True", 14 | "joinoninvite": "True", 15 | "AdminPassword": "0001" 16 | } 17 | -------------------------------------------------------------------------------- /fortnite.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | try: 4 | import asyncio 5 | import sys 6 | import os 7 | import time 8 | from datetime import datetime 9 | import json 10 | from functools import partial 11 | import random as rand 12 | 13 | from colorama import Fore, Back, Style, init 14 | init(autoreset=True) 15 | 16 | import rebootpy 17 | from rebootpy.ext import commands 18 | import FortniteAPIAsync 19 | import aiohttp 20 | import requests 21 | 22 | except ModuleNotFoundError as e: 23 | print(e) 24 | print(Fore.RED + f'[-] ' + Fore.RESET + 'Failed to import 1 or more modules. Run "INSTALL PACKAGES.bat') 25 | exit() 26 | 27 | os.system('cls||clear') 28 | 29 | fortnite_api = FortniteAPIAsync.APIClient() 30 | 31 | intro = Fore.LIGHTRED_EX + """ 32 | ----------------------------------------------------- 33 | | ██╗ ██╗███████╗███╗ ██╗███████╗██╗███████╗ | 34 | | ╚██╗██╔╝██╔════╝████╗ ██║██╔════╝██║██╔════╝ | 35 | | ╚███╔╝ █████╗ ██╔██╗ ██║███████╗██║███████╗ | 36 | | ██╔██╗ ██╔══╝ ██║╚██╗██║╚════██║██║╚════██║ | 37 | | ██╔╝ ██╗███████╗██║ ╚████║███████║██║███████║ | 38 | | ╚═╝ ╚═╝╚══════╝╚═╝ ╚═══╝╚══════╝╚═╝╚══════╝ | 39 | ----------------------------------------------------- 40 | """ 41 | 42 | print(intro) 43 | 44 | def get_current_patch(): 45 | try: 46 | response = requests.get('https://fortnite-api.com/v2/aes') 47 | response.raise_for_status() 48 | data = response.json() 49 | build = data['data']['build'] 50 | return build 51 | except requests.RequestException as e: 52 | print(f"Failed to fetch patch version: {e}") 53 | return "Unknown" 54 | except (KeyError, IndexError) as e: 55 | print(f"Error parsing patch data: {e}") 56 | return "Unknown" 57 | 58 | patch = get_current_patch() 59 | 60 | print(f'\n A free lobbybot network, created by KaosDrip. Works for Patch: {patch}.\n') 61 | 62 | def lenPartyMembers(): 63 | members = client.party.members 64 | return len(members) 65 | 66 | def warn(*args, **kwargs): 67 | pass 68 | import warnings 69 | warnings.warn = warn 70 | 71 | def lenFriends(): 72 | friends = client.friends 73 | return len(friends) 74 | 75 | def getNewSkins(): 76 | r = requests.get('https://fortnite-api.com/v2/cosmetics/br/new') 77 | 78 | response = r.json() 79 | 80 | cids = [] 81 | 82 | for cid in [item for item in response if item.split('/')[-1].upper().startswith('CID_')]: 83 | cids.append(cid.split('/')[-1].split('.')[0]) 84 | 85 | return cids 86 | 87 | def getNewEmotes(): 88 | r = requests.get('https://fortnite-api.com/v2/cosmetics/br/new') 89 | 90 | response = r.json() 91 | 92 | eids = [] 93 | 94 | for cid in [item for item in response if item.split('/')[-1].upper().startswith('EID_')]: 95 | eids.append(cid.split('/')[-1].split('.')[0]) 96 | 97 | return eids 98 | 99 | def get_device_auth_details(): 100 | if os.path.isfile("auths.json"): 101 | with open("auths.json", 'r') as fp: 102 | return json.load(fp) 103 | return {} 104 | 105 | def store_device_auth_details(email, details): 106 | existing = get_device_auth_details() 107 | existing[email] = details 108 | 109 | with open("auths.json", 'w') as fp: 110 | json.dump(existing, fp) 111 | 112 | with open('config.json') as f: 113 | try: 114 | data = json.load(f) 115 | except json.decoder.JSONDecodeError as e: 116 | print(Fore.RED + ' [ERROR] ' + Fore.RESET + "There was an error in one of the bot's files! (config.json). If you have problems trying to fix it, join the discord support server for help - https://discord.gg/88r2ShB") 117 | print(Fore.LIGHTRED_EX + f'\n {e}') 118 | exit(1) 119 | 120 | with open('info.json') as f: 121 | try: 122 | info = json.load(f) 123 | except json.decoder.JSONDecodeError as e: 124 | print(Fore.RED + ' [ERROR] ' + Fore.RESET + "There was an error in one of the bot's files! (info.json) If you have problems trying to fix it, join the discord support server for help - https://discord.gg/88r2ShB") 125 | print(Fore.LIGHTRED_EX + f'\n {e}') 126 | exit(1) 127 | 128 | def is_admin(): 129 | async def predicate(ctx): 130 | return ctx.author.id in info['FullAccess'] 131 | return commands.check(predicate) 132 | 133 | device_auth_details = get_device_auth_details().get(data['email'], {}) 134 | 135 | prefix = '!' 136 | 137 | client = commands.Bot( 138 | command_prefix=prefix, 139 | case_insensitive=True, 140 | auth=rebootpy.AdvancedAuth( 141 | email=data['email'], 142 | password=data['password'], 143 | prompt_authorization_code=True, 144 | delete_existing_device_auths=True, 145 | **device_auth_details 146 | ), 147 | status=data['status'], 148 | platform=rebootpy.Platform(data['platform']), 149 | ) 150 | client.party_build_id = "1:3:" # Fix for error code 91 and 93 151 | 152 | @client.event 153 | async def event_device_auth_generate(details): 154 | store_device_auth_details(data['email'], details) 155 | 156 | @client.event 157 | async def event_ready(): 158 | os.system('cls||clear') 159 | print(intro) 160 | print(Fore.GREEN + ' [+] ' + Fore.RESET + 'Client ready as ' + Fore.LIGHTGREEN_EX + f'{client.user.display_name}') 161 | 162 | member = client.party.me 163 | 164 | await member.edit_and_keep( 165 | partial( 166 | rebootpy.ClientPartyMember.set_outfit, 167 | asset=data['cid'] 168 | ), 169 | partial( 170 | rebootpy.ClientPartyMember.set_backpack, 171 | asset=data['bid'] 172 | ), 173 | partial( 174 | rebootpy.ClientPartyMember.set_pickaxe, 175 | asset=data['pid'] 176 | ), 177 | partial( 178 | rebootpy.ClientPartyMember.set_banner, 179 | icon=data['banner'], 180 | color=data['banner_color'], 181 | season_level=data['level'] 182 | ), 183 | partial( 184 | rebootpy.ClientPartyMember.set_battlepass_info, 185 | has_purchased=True, 186 | level=data['bp_tier'] 187 | ) 188 | ) 189 | 190 | @client.event 191 | async def event_party_invite(invite): 192 | if data['joinoninvite'].lower() == 'true': 193 | try: 194 | await invite.accept() 195 | print(Fore.GREEN + ' [+] ' + Fore.RESET + f'Accepted party invite from {invite.sender.display_name}') 196 | except Exception: 197 | pass 198 | elif data['joinoninvite'].lower() == 'false': 199 | if invite.sender.id in info['FullAccess']: 200 | await invite.accept() 201 | print(Fore.GREEN + ' [+] ' + Fore.RESET + 'Accepted party invite from ' + Fore.LIGHTGREEN_EX + f'{invite.sender.display_name}') 202 | else: 203 | print(Fore.GREEN + ' [+] ' + Fore.RESET + f'Never accepted party invite from {invite.sender.display_name}') 204 | 205 | @commands.dm_only() 206 | @client.command() 207 | async def pinkghoul(ctx): 208 | skin_variants = client.party.me.create_variants( 209 | material=3 210 | ) 211 | 212 | await client.party.me.set_outfit( 213 | asset='CID_029_Athena_Commando_F_Halloween', 214 | variants=skin_variants 215 | ) 216 | 217 | await ctx.send('Skin set to Pink Ghoul Trooper!') 218 | 219 | @client.event 220 | async def event_friend_request(request): 221 | if data['friendaccept'].lower() == 'true': 222 | try: 223 | await request.accept() 224 | print(f' [+] Accepted friend request from {request.display_name}' + Fore.LIGHTBLACK_EX + f' ({lenFriends()})') 225 | except Exception: 226 | pass 227 | elif data['friendaccept'].lower() == 'false': 228 | if request.id in info['FullAccess']: 229 | try: 230 | await request.accept() 231 | print(Fore.GREEN + ' [+] ' + Fore.RESET + 'Accepted friend request from ' + Fore.LIGHTGREEN_EX + f'{request.display_name}' + Fore.LIGHTBLACK_EX + f' ({lenFriends()})') 232 | except Exception: 233 | pass 234 | else: 235 | print(f' [+] Never accepted friend request from {request.display_name}') 236 | 237 | 238 | @client.event 239 | async def event_party_member_join(member): 240 | if client.user.display_name != member.display_name: 241 | try: 242 | if client.user.id in info['FullAccess']: 243 | print(Fore.LIGHTGREEN_EX + f' [+] {member.display_name}' + Fore.RESET + 'has joined the lobby.') 244 | else: 245 | print(f' [+] {member.display_name} has joined the lobby.' + Fore.LIGHTBLACK_EX + f' ({lenPartyMembers()})') 246 | except rebootpy.HTTPException: 247 | pass 248 | 249 | 250 | @client.event 251 | async def event_party_member_leave(member): 252 | if client.user.display_name != member.display_name: 253 | try: 254 | if client.user.id in info['FullAccess']: 255 | print(Fore.LIGHTGREEN_EX + f' [+] {member.display_name}' + Fore.RESET + 'has left the lobby.') 256 | else: 257 | print(f' [+] {member.display_name} has left the lobby.' + Fore.LIGHTBLACK_EX + f' ({lenPartyMembers()})') 258 | except rebootpy.HTTPException: 259 | pass 260 | 261 | 262 | @client.event 263 | async def event_party_message(message): 264 | if message.author.id in info['FullAccess']: 265 | name = Fore.LIGHTGREEN_EX + f'{message.author.display_name}' 266 | else: 267 | name = Fore.RESET + f'{message.author.display_name}' 268 | print(Fore.LIGHTGREEN_EX + ' [Party] ' + f'{name}' + Fore.RESET + f': {message.content}') 269 | 270 | 271 | @client.event 272 | async def event_friend_message(message): 273 | if message.author.id in info['FullAccess']: 274 | name = Fore.LIGHTMAGENTA_EX + f'{message.author.display_name}' 275 | else: 276 | name = Fore.RESET + f'{message.author.display_name}' 277 | print(Fore.LIGHTMAGENTA_EX + ' [Whisper] ' + f'{name}' + Fore.RESET + f': {message.content}') 278 | 279 | if message.content.upper().startswith('CID_'): 280 | await client.party.me.set_outfit(asset=message.content.upper()) 281 | await message.reply(f'Skin set to: {message.content}') 282 | elif message.content.upper().startswith('BID_'): 283 | await client.party.me.set_backpack(asset=message.content.upper()) 284 | await message.reply(f'Backpack set to: {message.content}') 285 | elif message.content.upper().startswith('EID_'): 286 | await client.party.me.set_emote(asset=message.content.upper()) 287 | await message.reply(f'Emote set to: {message.content}') 288 | elif message.content.upper().startswith('PID_'): 289 | await client.party.me.set_pickaxe(asset=message.content.upper()) 290 | await message.reply(f'Pickaxe set to: {message.content}') 291 | elif message.content.startswith('Playlist_'): 292 | try: 293 | await client.party.set_playlist(playlist=message.content) 294 | await message.reply(f'Playlist set to: {message.content}') 295 | except rebootpy.Forbidden: 296 | await message.reply(f"I can not set gamemode because I am not party leader.") 297 | elif message.content.lower().startswith('prefix'): 298 | await message.reply(f'Current prefix: {prefix}') 299 | 300 | 301 | @client.event 302 | async def event_command_error(ctx, error): 303 | if isinstance(error, commands.CommandNotFound): 304 | await ctx.send(f'That is not a command. Try {prefix}help') 305 | elif isinstance(error, IndexError): 306 | pass 307 | elif isinstance(error, rebootpy.HTTPException): 308 | pass 309 | elif isinstance(error, commands.CheckFailure): 310 | await ctx.send("You don't have access to that command.") 311 | elif isinstance(error, TimeoutError): 312 | await ctx.send("You took too long to respond!") 313 | else: 314 | print(error) 315 | 316 | @commands.dm_only() 317 | @client.command() 318 | @commands.dm_only() 319 | async def skin(ctx, *, content = None): 320 | if content is None: 321 | await ctx.send(f'No skin was given, try: {prefix}skin (skin name)') 322 | elif content.upper().startswith('CID_'): 323 | await client.party.me.set_outfit(asset=content.upper()) 324 | await ctx.send(f'Skin set to: {content}') 325 | else: 326 | try: 327 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 328 | lang="en", 329 | searchLang="en", 330 | name=content, 331 | backendType="AthenaCharacter" 332 | ) 333 | await client.party.me.set_outfit(asset=cosmetic.id) 334 | await ctx.send(f'Skin set to: {cosmetic.name}') 335 | except FortniteAPIAsync.exceptions.NotFound: 336 | await ctx.send(f'Could not find a skin named: {content}') 337 | 338 | @commands.dm_only() 339 | @client.command() 340 | @commands.dm_only() 341 | async def backpack(ctx, *, content = None): 342 | if content is None: 343 | await ctx.send(f'No backpack was given, try: {prefix}backpack (backpack name)') 344 | elif content.lower() == 'none': 345 | await client.party.me.clear_backpack() 346 | await ctx.send('Backpack set to: None') 347 | elif content.upper().startswith('BID_'): 348 | await client.party.me.set_backpack(asset=content.upper()) 349 | await ctx.send(f'Backpack set to: {content}') 350 | else: 351 | try: 352 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 353 | lang="en", 354 | searchLang="en", 355 | matchMethod="contains", 356 | name=content, 357 | backendType="AthenaBackpack" 358 | ) 359 | await client.party.me.set_backpack(asset=cosmetic.id) 360 | await ctx.send(f'Backpack set to: {cosmetic.name}') 361 | except FortniteAPIAsync.exceptions.NotFound: 362 | await ctx.send(f'Could not find a backpack named: {content}') 363 | 364 | @commands.dm_only() 365 | @client.command() 366 | async def emote(ctx, *, content = None): 367 | if content is None: 368 | await ctx.send(f'No emote was given, try: {prefix}emote (emote name)') 369 | elif content.lower() == 'floss': 370 | await client.party.me.clear_emote() 371 | await client.party.me.set_emote(asset='EID_Floss') 372 | await ctx.send(f'Emote set to: Floss') 373 | elif content.lower() == 'scenario': 374 | await client.party.me.clear_emote() 375 | await client.party.me.set_emote(asset='EID_KPopDance03') 376 | await ctx.send(f'Emote set to: Scenario') 377 | elif content.lower() == 'none': 378 | await client.party.me.clear_emote() 379 | await ctx.send(f'Emote set to: None') 380 | elif content.upper().startswith('EID_'): 381 | await client.party.me.clear_emote() 382 | await client.party.me.set_emote(asset=content.upper()) 383 | await ctx.send(f'Emote set to: {content}') 384 | else: 385 | try: 386 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 387 | lang="en", 388 | searchLang="en", 389 | matchMethod="contains", 390 | name=content, 391 | backendType="AthenaDance" 392 | ) 393 | await client.party.me.clear_emote() 394 | await client.party.me.set_emote(asset=cosmetic.id) 395 | await ctx.send(f'Emote set to: {cosmetic.name}') 396 | except FortniteAPIAsync.exceptions.NotFound: 397 | await ctx.send(f'Could not find an emote named: {content}') 398 | 399 | @commands.dm_only() 400 | @client.command() 401 | async def pickaxe(ctx, *, content = None): 402 | if content is None: 403 | await ctx.send(f'No pickaxe was given, try: {prefix}pickaxe (pickaxe name)') 404 | elif content.upper().startswith('Pickaxe_'): 405 | await client.party.me.set_pickaxe(asset=content.upper()) 406 | await ctx.send(f'Pickaxe set to: {content}') 407 | else: 408 | try: 409 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 410 | lang="en", 411 | searchLang="en", 412 | matchMethod="contains", 413 | name=content, 414 | backendType="AthenaPickaxe" 415 | ) 416 | await client.party.me.set_pickaxe(asset=cosmetic.id) 417 | await ctx.send(f'Pickaxe set to: {cosmetic.name}') 418 | except FortniteAPIAsync.exceptions.NotFound: 419 | await ctx.send(f'Could not find a pickaxe named: {content}') 420 | 421 | @commands.dm_only() 422 | @client.command() 423 | async def pet(ctx, *, content = None): 424 | if content is None: 425 | await ctx.send(f'No pet was given, try: {prefix}pet (pet name)') 426 | elif content.lower() == 'none': 427 | await client.party.me.clear_pet() 428 | await ctx.send('Pet set to: None') 429 | else: 430 | try: 431 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 432 | lang="en", 433 | searchLang="en", 434 | matchMethod="contains", 435 | name=content, 436 | backendType="AthenaPet" 437 | ) 438 | await client.party.me.set_pet(asset=cosmetic.id) 439 | await ctx.send(f'Pet set to: {cosmetic.name}') 440 | except FortniteAPIAsync.exceptions.NotFound: 441 | await ctx.send(f'Could not find a pet named: {content}') 442 | 443 | @commands.dm_only() 444 | @client.command() 445 | async def emoji(ctx, *, content = None): 446 | if content is None: 447 | await ctx.send(f'No emoji was given, try: {prefix}emoji (emoji name)') 448 | try: 449 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 450 | lang="en", 451 | searchLang="en", 452 | matchMethod="contains", 453 | name=content, 454 | backendType="AthenaEmoji" 455 | ) 456 | await client.party.me.clear_emoji() 457 | await client.party.me.set_emoji(asset=cosmetic.id) 458 | await ctx.send(f'Emoji set to: {cosmetic.name}') 459 | except FortniteAPIAsync.exceptions.NotFound: 460 | await ctx.send(f'Could not find an emoji named: {content}') 461 | 462 | 463 | @commands.dm_only() 464 | @client.command() 465 | async def current(ctx, setting = None): 466 | if setting is None: 467 | await ctx.send(f"Missing argument. Try: {prefix}current (skin, backpack, emote, pickaxe, banner)") 468 | elif setting.lower() == 'banner': 469 | await ctx.send(f'Banner ID: {client.party.me.banner[0]} - Banner Color ID: {client.party.me.banner[1]}') 470 | else: 471 | try: 472 | if setting.lower() == 'skin': 473 | cosmetic = await fortnite_api.cosmetics.get_cosmetic_from_id( 474 | cosmetic_id=client.party.me.outfit 475 | ) 476 | 477 | elif setting.lower() == 'backpack': 478 | cosmetic = await fortnite_api.cosmetics.get_cosmetic_from_id( 479 | cosmetic_id=client.party.me.backpack 480 | ) 481 | 482 | elif setting.lower() == 'emote': 483 | cosmetic = await fortnite_api.cosmetics.get_cosmetic_from_id( 484 | cosmetic_id=client.party.me.emote 485 | ) 486 | 487 | elif setting.lower() == 'pickaxe': 488 | cosmetic = await fortnite_api.cosmetics.get_cosmetic_from_id( 489 | cosmetic_id=client.party.me.pickaxe 490 | ) 491 | 492 | await ctx.send(f"My current {setting} is: {cosmetic.name}") 493 | except fortnite_api.cosmetics.exceptions.NotFound: 494 | await ctx.send(f"I couldn't find a {setting} name for that.") 495 | 496 | 497 | @commands.dm_only() 498 | @client.command() 499 | async def name(ctx, *, content=None): 500 | if content is None: 501 | await ctx.send(f'No ID was given, try: {prefix}name (cosmetic ID)') 502 | else: 503 | try: 504 | cosmetic = await fortnite_api.cosmetics.get_cosmetic_from_id( 505 | cosmetic_id=content 506 | ) 507 | await ctx.send(f'The name for that ID is: {cosmetic.name}') 508 | print(f' [+] The name for {cosmetic.id} is: {cosmetic.name}') 509 | except FortniteAPIAsync.exceptions.NotFound: 510 | await ctx.send(f'Could not find a cosmetic name for ID: {content}') 511 | 512 | 513 | @commands.dm_only() 514 | @client.command() 515 | async def cid(ctx, *, content = None): 516 | if content is None: 517 | await ctx.send(f'No skin was given, try: {prefix}cid (skin name)') 518 | else: 519 | try: 520 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 521 | lang="en", 522 | searchLang="en", 523 | matchMethod="contains", 524 | name=content, 525 | backendType="AthenaCharacter" 526 | ) 527 | await ctx.send(f'The CID for {cosmetic.name} is: {cosmetic.id}') 528 | print(f' [+] The CID for {cosmetic.name} is: {cosmetic.id}') 529 | except FortniteAPIAsync.exceptions.NotFound: 530 | await ctx.send(f'Could not find a skin named: {content}') 531 | 532 | 533 | @commands.dm_only() 534 | @client.command() 535 | async def bid(ctx, *, content): 536 | if content is None: 537 | await ctx.send(f'No backpack was given, try: {prefix}bid (backpack name)') 538 | else: 539 | try: 540 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 541 | lang="en", 542 | searchLang="en", 543 | matchMethod="contains", 544 | name=content, 545 | backendType="AthenaBackpack" 546 | ) 547 | await ctx.send(f'The BID for {cosmetic.name} is: {cosmetic.id}') 548 | print(f' [+] The BID for {cosmetic.name} is: {cosmetic.id}') 549 | except FortniteAPIAsync.exceptions.NotFound: 550 | await ctx.send(f'Could not find a backpack named: {content}') 551 | 552 | 553 | @commands.dm_only() 554 | @client.command() 555 | async def eid(ctx, *, content): 556 | if content is None: 557 | await ctx.send(f'No emote was given, try: {prefix}eid (emote name)') 558 | elif content.lower() == 'floss': 559 | await ctx.send(f'The EID for Floss is: EID_Floss') 560 | else: 561 | try: 562 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 563 | lang="en", 564 | searchLang="en", 565 | matchMethod="contains", 566 | name=content, 567 | backendType="AthenaDance" 568 | ) 569 | await ctx.send(f'The EID for {cosmetic.name} is: {cosmetic.id}') 570 | print(f' [+] The EID for {cosmetic.name} is: {cosmetic.id}') 571 | except FortniteAPIAsync.exceptions.NotFound: 572 | await ctx.send(f'Could not find an emote named: {content}') 573 | 574 | 575 | @commands.dm_only() 576 | @client.command() 577 | async def pid(ctx, *, content): 578 | if content is None: 579 | await ctx.send(f'No pickaxe was given, try: {prefix}pid (pickaxe name)') 580 | else: 581 | try: 582 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 583 | lang="en", 584 | searchLang="en", 585 | matchMethod="contains", 586 | name=content, 587 | backendType="AthenaPickaxe" 588 | ) 589 | await ctx.send(f'The PID for {cosmetic.name} is: {cosmetic.id}') 590 | print(f' [+] The PID for {cosmetic.name} is: {cosmetic.id}') 591 | except FortniteAPIAsync.exceptions.NotFound: 592 | await ctx.send(f'Could not find a pickaxe named: {content}') 593 | 594 | 595 | @commands.dm_only() 596 | @client.command() 597 | async def random(ctx, content = None): 598 | 599 | skins = await fortnite_api.cosmetics.get_cosmetics( 600 | lang="en", 601 | backendType="AthenaCharacter" 602 | ) 603 | 604 | skin = rand.choice(skins) 605 | 606 | backpacks = await fortnite_api.cosmetics.get_cosmetics( 607 | lang="en", 608 | backendType="AthenaBackpack" 609 | ) 610 | 611 | backpack = rand.choice(backpacks) 612 | 613 | emotes = await fortnite_api.cosmetics.get_cosmetics( 614 | lang="en", 615 | backendType="AthenaDance" 616 | ) 617 | 618 | emote = rand.choice(emotes) 619 | 620 | pickaxes = await fortnite_api.cosmetics.get_cosmetics( 621 | lang="en", 622 | backendType="AthenaPickaxe" 623 | ) 624 | 625 | pickaxe = rand.choice(pickaxes) 626 | 627 | 628 | if content is None: 629 | me = client.party.me 630 | await me.set_outfit(asset=skin.id) 631 | await me.set_backpack(asset=backpack.id) 632 | await me.set_pickaxe(asset=pickaxe.id) 633 | 634 | await ctx.send(f'Loadout randomly set to: {skin.name}, {backpack.name}, {pickaxe.name}') 635 | else: 636 | if content.lower() == 'skin': 637 | await client.party.me.set_outfit(asset=skin.id) 638 | await ctx.send(f'Skin randomly set to: {skin.name}') 639 | 640 | elif content.lower() == 'backpack': 641 | await client.party.me.set_backpack(asset=backpack.id) 642 | await ctx.send(f'Backpack randomly set to: {backpack.name}') 643 | 644 | elif content.lower() == 'emote': 645 | await client.party.me.set_emote(asset=emote.id) 646 | await ctx.send(f'Emote randomly set to: {emote.name}') 647 | 648 | elif content.lower() == 'pickaxe': 649 | await client.party.me.set_pickaxe(asset=pickaxe.id) 650 | await ctx.send(f'Pickaxe randomly set to: {pickaxe.name}') 651 | 652 | else: 653 | await ctx.send(f"I don't know that, try: {prefix}random (skin, backpack, emote, pickaxe - og, exclusive, unreleased") 654 | 655 | 656 | @commands.dm_only() 657 | @client.command() 658 | async def point(ctx, *, content = None): 659 | if content is None: 660 | await client.party.me.clear_emote() 661 | await client.party.me.set_emote(asset='EID_IceKing') 662 | await ctx.send(f'Pointing with: {client.party.me.pickaxe}') 663 | 664 | else: 665 | if content.upper().startswith('Pickaxe_'): 666 | await client.party.me.set_pickaxe(asset=content.upper()) 667 | await client.party.me.clear_emote() 668 | asyncio.sleep(0.25) 669 | await client.party.me.set_emote(asset='EID_IceKing') 670 | await ctx.send(f'Pointing with: {content}') 671 | else: 672 | try: 673 | cosmetic = await fortnite_api.cosmetics.get_cosmetic( 674 | lang="en", 675 | searchLang="en", 676 | matchMethod="contains", 677 | name=content, 678 | backendType="AthenaPickaxe" 679 | ) 680 | await client.party.me.set_pickaxe(asset=cosmetic.id) 681 | await client.party.me.clear_emote() 682 | await client.party.me.set_emote(asset='EID_IceKing') 683 | await ctx.send(f'Pointing with: {cosmetic.name}') 684 | except FortniteAPIAsync.exceptions.NotFound: 685 | await ctx.send(f'Could not find a pickaxe named: {content}') 686 | 687 | 688 | @commands.dm_only() 689 | @client.command() 690 | async def checkeredrenegade(ctx): 691 | variants = client.party.me.create_variants(material=2) 692 | 693 | await client.party.me.set_outfit( 694 | asset='CID_028_Athena_Commando_F', 695 | variants=variants 696 | ) 697 | 698 | await ctx.send('Skin set to: Checkered Renegade') 699 | 700 | 701 | @commands.dm_only() 702 | @client.command() 703 | async def purpleportal(ctx): 704 | variants = client.party.me.create_variants( 705 | item='AthenaBackpack', 706 | particle_config='Particle', 707 | particle=1 708 | ) 709 | 710 | await client.party.me.set_backpack( 711 | asset='BID_105_GhostPortal', 712 | variants=variants 713 | ) 714 | 715 | await ctx.send('Backpack set to: Purple Ghost Portal') 716 | 717 | @commands.dm_only() 718 | @client.command() 719 | async def purpleskull(ctx): 720 | variants = client.party.me.create_variants( 721 | clothing_color=1 722 | ) 723 | 724 | await client.party.me.set_outfit( 725 | asset='CID_030_Athena_Commando_M_Halloween', 726 | variants=variants 727 | ) 728 | 729 | await ctx.send('Skin set to Purple Skull Trooper!') 730 | 731 | @commands.dm_only() 732 | @client.command() 733 | async def goldpeely(ctx): 734 | variants = client.party.me.create_variants(progressive=4) 735 | 736 | await client.party.me.set_outfit( 737 | asset='CID_701_Athena_Commando_M_BananaAgent', 738 | variants=variants, 739 | enlightenment=(2, 350) 740 | ) 741 | 742 | await ctx.send('Skin set to: Golden Peely') 743 | 744 | @commands.dm_only() 745 | @client.command() 746 | async def hatlessrecon(ctx): 747 | variants = client.party.me.create_variants(parts=2) 748 | 749 | await client.party.me.set_outfit( 750 | asset='CID_022_Athena_Commando_F', 751 | variants=variants 752 | ) 753 | 754 | await ctx.send('Skin set to: Hatless Recon Expert') 755 | 756 | 757 | @commands.dm_only() 758 | @client.command() 759 | async def hologram(ctx): 760 | await client.party.me.set_outfit( 761 | asset='CID_VIP_Athena_Commando_M_GalileoGondola_SG' 762 | ) 763 | 764 | await ctx.send("Skin set to: Hologram") 765 | 766 | 767 | @commands.dm_only() 768 | @client.command() 769 | async def itemshop(ctx): 770 | previous_skin = client.party.me.outfit 771 | 772 | store = await client.fetch_item_shop() 773 | 774 | await ctx.send("Equipping all item shop skins + emotes") 775 | 776 | for cosmetic in store.featured_items + store.daily_items: 777 | for grant in cosmetic.grants: 778 | if grant['type'] == 'AthenaCharacter': 779 | await client.party.me.set_outfit(asset=grant['asset']) 780 | await asyncio.sleep(5) 781 | elif grant['type'] == 'AthenaDance': 782 | await client.party.me.clear_emote() 783 | await client.party.me.set_emote(asset=grant['asset']) 784 | await asyncio.sleep(5) 785 | 786 | await client.party.me.clear_emote() 787 | 788 | await ctx.send("Done!") 789 | 790 | await asyncio.sleep(1.5) 791 | 792 | await client.party.me.set_outfit(asset=previous_skin) 793 | 794 | 795 | @commands.dm_only() 796 | @client.command() 797 | async def new(ctx, content = None): 798 | newSkins = getNewSkins() 799 | newEmotes = getNewEmotes() 800 | 801 | previous_skin = client.party.me.outfit 802 | 803 | if content is None: 804 | await ctx.send(f'There are {len(newSkins) + len(newEmotes)} new skins + emotes') 805 | 806 | for cosmetic in newSkins + newEmotes: 807 | if cosmetic.startswith('CID_'): 808 | await client.party.me.set_outfit(asset=cosmetic) 809 | await asyncio.sleep(4) 810 | elif cosmetic.startswith('EID_'): 811 | await client.party.me.clear_emote() 812 | await client.party.me.set_emote(asset=cosmetic) 813 | await asyncio.sleep(4) 814 | 815 | elif 'skin' in content.lower(): 816 | await ctx.send(f'There are {len(newSkins)} new skins') 817 | 818 | for skin in newSkins: 819 | await client.party.me.set_outfit(asset=skin) 820 | await asyncio.sleep(4) 821 | 822 | elif 'emote' in content.lower(): 823 | await ctx.send(f'There are {len(newEmotes)} new emotes') 824 | 825 | for emote in newEmotes: 826 | await client.party.me.clear_emote() 827 | await client.party.me.set_emote(asset=emote) 828 | await asyncio.sleep(4) 829 | 830 | await client.party.me.clear_emote() 831 | 832 | await ctx.send('Done!') 833 | 834 | await asyncio.sleep(1.5) 835 | 836 | await client.party.me.set_outfit(asset=previous_skin) 837 | 838 | if (content is not None) and ('skin' or 'emote' not in content.lower()): 839 | ctx.send(f"Not a valid option. Try: {prefix}new (skins, emotes)") 840 | 841 | 842 | @commands.dm_only() 843 | @client.command() 844 | async def ready(ctx): 845 | await client.party.me.set_ready(rebootpy.ReadyState.READY) 846 | await ctx.send('Ready!') 847 | 848 | 849 | @commands.dm_only() 850 | @client.command() 851 | async def unready(ctx): 852 | await client.party.me.set_ready(rebootpy.ReadyState.NOT_READY) 853 | await ctx.send('Unready!') 854 | 855 | 856 | @commands.dm_only() 857 | @client.command() 858 | async def sitin(ctx): 859 | await client.party.me.set_ready(rebootpy.ReadyState.NOT_READY) 860 | await ctx.send('Sitting in') 861 | 862 | @commands.dm_only() 863 | @client.command() 864 | async def sitout(ctx): 865 | await client.party.me.set_ready(rebootpy.ReadyState.SITTING_OUT) 866 | await ctx.send('Sitting out') 867 | 868 | 869 | @commands.dm_only() 870 | @client.command() 871 | async def tier(ctx, tier = None): 872 | if tier is None: 873 | await ctx.send(f'No tier was given. Try: {prefix}tier (tier number)') 874 | else: 875 | await client.party.me.set_battlepass_info( 876 | has_purchased=True, 877 | level=tier 878 | ) 879 | 880 | await ctx.send(f'Battle Pass tier set to: {tier}') 881 | 882 | 883 | @commands.dm_only() 884 | @client.command() 885 | async def level(ctx, level = None): 886 | if level is None: 887 | await ctx.send(f'No level was given. Try: {prefix}level (number)') 888 | else: 889 | await client.party.me.set_banner(season_level=level) 890 | await ctx.send(f'Level set to: {level}') 891 | 892 | 893 | @commands.dm_only() 894 | @client.command() 895 | async def banner(ctx, args1 = None, args2 = None): 896 | if (args1 is not None) and (args2 is None): 897 | if args1.startswith('defaultcolor'): 898 | await client.party.me.set_banner( 899 | color = args1 900 | ) 901 | 902 | await ctx.send(f'Banner color set to: {args1}') 903 | 904 | elif args1.isnumeric() == True: 905 | await client.party.me.set_banner( 906 | color = 'defaultcolor' + args1 907 | ) 908 | 909 | await ctx.send(f'Banner color set to: defaultcolor{args1}') 910 | 911 | else: 912 | await client.party.me.set_banner( 913 | icon = args1 914 | ) 915 | 916 | await ctx.send(f'Banner Icon set to: {args1}') 917 | 918 | elif (args1 is not None) and (args2 is not None): 919 | if args2.startswith('defaultcolor'): 920 | await client.party.me.set_banner( 921 | icon = args1, 922 | color = args2 923 | ) 924 | 925 | await ctx.send(f'Banner icon set to: {args1} -- Banner color set to: {args2}') 926 | 927 | elif args2.isnumeric() == True: 928 | await client.party.me.set_banner( 929 | icon = args1, 930 | color = 'defaultcolor' + args2 931 | ) 932 | 933 | await ctx.send(f'Banner icon set to: {args1} -- Banner color set to: defaultcolor{args2}') 934 | 935 | else: 936 | await ctx.send(f'Not proper format. Try: {prefix}banner (Banner ID) (Banner Color ID)') 937 | 938 | 939 | copied_player = "" 940 | 941 | 942 | @commands.dm_only() 943 | @client.command() 944 | async def stop(ctx): 945 | global copied_player 946 | if copied_player != "": 947 | copied_player = "" 948 | await ctx.send(f'Stopped copying all users.') 949 | return 950 | else: 951 | try: 952 | await client.party.me.clear_emote() 953 | except RuntimeWarning: 954 | pass 955 | 956 | 957 | @commands.dm_only() 958 | @client.command() 959 | async def copy(ctx, *, username = None): 960 | global copied_player 961 | 962 | if username is None: 963 | member = [m for m in client.party.members if m.id == ctx.author.id][0] 964 | 965 | else: 966 | user = await client.fetch_user(username) 967 | member = [m for m in client.party.members if m.id == user.id][0] 968 | 969 | await client.party.me.edit_and_keep( 970 | partial( 971 | rebootpy.ClientPartyMember.set_outfit, 972 | asset=member.outfit, 973 | variants=member.outfit_variants 974 | ), 975 | partial( 976 | rebootpy.ClientPartyMember.set_backpack, 977 | asset=member.backpack, 978 | variants=member.backpack_variants 979 | ), 980 | partial( 981 | rebootpy.ClientPartyMember.set_pickaxe, 982 | asset=member.pickaxe, 983 | variants=member.pickaxe_variants 984 | ), 985 | partial( 986 | rebootpy.ClientPartyMember.set_banner, 987 | icon=member.banner[0], 988 | color=member.banner[1], 989 | season_level=member.banner[2] 990 | ), 991 | partial( 992 | rebootpy.ClientPartyMember.set_battlepass_info, 993 | has_purchased=member.battlepass_info[0], 994 | level=member.battlepass_info[1] 995 | ), 996 | partial( 997 | rebootpy.ClientPartyMember.set_emote, 998 | asset=member.emote 999 | ) 1000 | ) 1001 | 1002 | await ctx.send(f"Now copying: {member.display_name}") 1003 | 1004 | @client.event() 1005 | async def event_party_member_backpack_change(member, before, after): 1006 | if member == copied_player: 1007 | if after is None: 1008 | await client.party.me.clear_backpack() 1009 | else: 1010 | await client.party.me.edit_and_keep( 1011 | partial( 1012 | rebootpy.ClientPartyMember.set_backpack, 1013 | asset=after, 1014 | variants=member.backpack_variants 1015 | ) 1016 | ) 1017 | 1018 | @client.event() 1019 | async def event_party_member_backpack_variants_change(member, before, after): 1020 | if member == copied_player: 1021 | await client.party.me.edit_and_keep( 1022 | partial( 1023 | rebootpy.ClientPartyMember.set_backpack, 1024 | variants=member.backpack_variants 1025 | ) 1026 | ) 1027 | 1028 | @client.event() 1029 | async def event_party_member_emote_change(member, before, after): 1030 | if member == copied_player: 1031 | if after is None: 1032 | await client.party.me.clear_emote() 1033 | else: 1034 | await client.party.me.edit_and_keep( 1035 | partial( 1036 | rebootpy.ClientPartyMember.set_emote, 1037 | asset=after 1038 | ) 1039 | ) 1040 | 1041 | @client.event() 1042 | async def event_party_member_pickaxe_change(member, before, after): 1043 | if member == copied_player: 1044 | await client.party.me.edit_and_keep( 1045 | partial( 1046 | rebootpy.ClientPartyMember.set_pickaxe, 1047 | asset=after, 1048 | variants=member.pickaxe_variants 1049 | ) 1050 | ) 1051 | 1052 | @client.event() 1053 | async def event_party_member_pickaxe_variants_change(member, before, after): 1054 | if member == copied_player: 1055 | await client.party.me.edit_and_keep( 1056 | partial( 1057 | rebootpy.ClientPartyMember.set_pickaxe, 1058 | variants=member.pickaxe_variants 1059 | ) 1060 | ) 1061 | 1062 | @client.event() 1063 | async def event_party_member_banner_change(member, before, after): 1064 | if member == copied_player: 1065 | await client.party.me.edit_and_keep( 1066 | partial( 1067 | rebootpy.ClientPartyMember.set_banner, 1068 | icon=member.banner[0], 1069 | color=member.banner[1], 1070 | season_level=member.banner[2] 1071 | ) 1072 | ) 1073 | 1074 | @client.event() 1075 | async def event_party_member_battlepass_info_change(member, before, after): 1076 | if member == copied_player: 1077 | await client.party.me.edit_and_keep( 1078 | partial( 1079 | rebootpy.ClientPartyMember.set_battlepass_info, 1080 | has_purchased=member.battlepass_info[0], 1081 | level=member.battlepass_info[1] 1082 | ) 1083 | ) 1084 | 1085 | async def set_and_update_party_prop(schema_key: str, new_value: str): 1086 | prop = {schema_key: client.party.me.meta.set_prop(schema_key, new_value)} 1087 | await client.party.patch(updated=prop) 1088 | 1089 | @commands.dm_only() 1090 | @client.command() 1091 | @is_admin() 1092 | async def hide(ctx, *, user = None): 1093 | if client.party.me.leader: 1094 | if user != "all": 1095 | try: 1096 | if user is None: 1097 | user = await client.fetch_profile(ctx.message.author.id) 1098 | member = client.party.members.get(user.id) 1099 | else: 1100 | user = await client.fetch_profile(user) 1101 | member = client.party.members.get(user.id) 1102 | 1103 | raw_squad_assignments = client.party.meta.get_prop('Default:RawSquadAssignments_j')["RawSquadAssignments"] 1104 | 1105 | for m in raw_squad_assignments: 1106 | if m['memberId'] == member.id: 1107 | raw_squad_assignments.remove(m) 1108 | 1109 | await set_and_update_party_prop( 1110 | 'Default:RawSquadAssignments_j', 1111 | { 1112 | 'RawSquadAssignments': raw_squad_assignments 1113 | } 1114 | ) 1115 | 1116 | await ctx.send(f"Hid {member.display_name}") 1117 | except AttributeError: 1118 | await ctx.send("I could not find that user.") 1119 | except rebootpy.HTTPException: 1120 | await ctx.send("I am not party leader.") 1121 | else: 1122 | try: 1123 | await set_and_update_party_prop( 1124 | 'Default:RawSquadAssignments_j', 1125 | { 1126 | 'RawSquadAssignments': [ 1127 | { 1128 | 'memberId': client.user.id, 1129 | 'absoluteMemberIdx': 1 1130 | } 1131 | ] 1132 | } 1133 | ) 1134 | 1135 | await ctx.send("Hid everyone in the party.") 1136 | except rebootpy.HTTPException: 1137 | await ctx.send("I am not party leader.") 1138 | else: 1139 | await ctx.send("I need party leader to do this!") 1140 | 1141 | @commands.dm_only() 1142 | @client.command() 1143 | @is_admin() 1144 | async def unhide(ctx: rebootpy.ext.commands.Context, *, username = None): 1145 | if client.party.me.leader: 1146 | user = await client.fetch_user(ctx.author.display_name) 1147 | member = client.party.get_member(user.id) 1148 | 1149 | await member.promote() 1150 | 1151 | await ctx.send("Unhid all players.") 1152 | 1153 | else: 1154 | await ctx.send("I am not party leader.") 1155 | 1156 | @commands.dm_only() 1157 | @client.command() 1158 | @is_admin() 1159 | async def say(ctx, *, message = None): 1160 | if message is not None: 1161 | await client.party.send(message) 1162 | await ctx.send(f'Sent "{message}" to party chat') 1163 | else: 1164 | await ctx.send(f'No message was given. Try: {prefix}say (message)') 1165 | 1166 | 1167 | @commands.dm_only() 1168 | @client.command() 1169 | @is_admin() 1170 | async def whisper(ctx, member = None, *, message = None): 1171 | if (member is not None) and (message is not None): 1172 | try: 1173 | user = await client.fetch_profile(member) 1174 | friend = client.get_friend(user.id) 1175 | 1176 | if friend.is_online(): 1177 | await friend.send(message) 1178 | await ctx.send("Message sent.") 1179 | else: 1180 | await ctx.send("That friend is offline.") 1181 | except AttributeError: 1182 | await ctx.send("I couldn't find that friend.") 1183 | except rebootpy.HTTPException: 1184 | await ctx.send("Something went wrong sending the message.") 1185 | else: 1186 | await ctx.send(f"Command missing one or more arguments. Try: {prefix}whisper (friend) (message)") 1187 | 1188 | 1189 | @commands.dm_only() 1190 | @client.command() 1191 | @is_admin() 1192 | async def match(ctx, players = None): 1193 | time = datetime.utcnow() 1194 | if players is not None: 1195 | if 'auto' in players.lower(): 1196 | if client.party.me.in_match(): 1197 | left = client.party.me.match_players_left 1198 | else: 1199 | left = 100 1200 | await client.party.me.set_in_match(players_left=left, started_at=time) 1201 | 1202 | await asyncio.sleep(rand.randint(20, 30)) 1203 | 1204 | while client.party.me.match_players_left > 5 and client.party.me.in_match(): 1205 | await client.party.me.set_in_match(players_left=client.party.me.match_players_left - rand.randint(3, 5), started_at=time), 1206 | 1207 | await asyncio.sleep(rand.randint(8, 18)) 1208 | 1209 | while (client.party.me.match_players_left <= 5) and (client.party.me.match_players_left > 3): 1210 | await client.party.me.set_in_match(players_left=client.party.me.match_players_left - rand.randint(1, 2), started_at=time) 1211 | 1212 | await asyncio.sleep(rand.randint(12, 20)) 1213 | 1214 | while (client.party.me.match_players_left <= 3) and (client.party.me.match_players_left > 1): 1215 | await client.party.me.set_in_match(players_left=client.party.me.match_players_left - 1, started_at=time) 1216 | 1217 | await asyncio.sleep(rand.randint(12, 20)) 1218 | 1219 | await asyncio.sleep(6) 1220 | await client.party.me.clear_in_match() 1221 | 1222 | elif 'leave' in players.lower(): 1223 | await client.party.me.clear_in_match() 1224 | 1225 | else: 1226 | try: 1227 | await client.party.me.set_in_match(players_left=int(players), started_at=time) 1228 | except ValueError: 1229 | await ctx.send(f"Invalid usage. Try: {prefix}match (0-255)") 1230 | pass 1231 | 1232 | else: 1233 | await ctx.send(f'Incorrect usage. Try: {prefix}match (auto, #, leave)') 1234 | 1235 | 1236 | @commands.dm_only() 1237 | @client.command() 1238 | @is_admin() 1239 | async def status(ctx, *, status = None): 1240 | await client.set_presence(status) 1241 | await ctx.send(f'Status set to {status}') 1242 | await ctx.send(f'No status was given. Try: {prefix}status (status message)') 1243 | 1244 | 1245 | @commands.dm_only() 1246 | @client.command() 1247 | @is_admin() 1248 | async def leave(ctx): 1249 | await client.party.me.leave() 1250 | await ctx.send('Left party.') 1251 | 1252 | 1253 | @commands.dm_only() 1254 | @client.command() 1255 | @is_admin() 1256 | async def kick(ctx: rebootpy.ext.commands.Context, *, member = None): 1257 | try: 1258 | user = await client.fetch_user(member) 1259 | member = client.party.get_member(user.id) 1260 | if member is None: 1261 | await ctx.send("Couldn't find that user. Are you sure they're in the party?") 1262 | 1263 | await member.kick() 1264 | await ctx.send(f'Kicked: {member.display_name}') 1265 | except rebootpy.Forbidden: 1266 | await ctx.send("I can't kick that user because I am not party leader") 1267 | except AttributeError: 1268 | await ctx.send("Couldn't find that user.") 1269 | 1270 | 1271 | @commands.dm_only() 1272 | @client.command() 1273 | @is_admin() 1274 | async def promote(ctx, *, username = None): 1275 | if username is None: 1276 | user = await client.fetch_user(ctx.author.display_name) 1277 | member = client.party.get_member(user.id) 1278 | else: 1279 | user = await client.fetch_user(username) 1280 | member = client.party.get_member(user.id) 1281 | try: 1282 | await member.promote() 1283 | await ctx.send(f"Promoted: {member.display_name}") 1284 | except rebootpy.Forbidden: 1285 | await ctx.send("Client is not party leader") 1286 | except rebootpy.PartyError: 1287 | await ctx.send("That person is already party leader") 1288 | except rebootpy.HTTPException: 1289 | await ctx.send("Something went wrong trying to promote that member") 1290 | except AttributeError: 1291 | await ctx.send("I could not find that user") 1292 | 1293 | 1294 | @commands.dm_only() 1295 | @client.command() 1296 | @is_admin() 1297 | async def privacy(ctx, setting = None): 1298 | if setting is not None: 1299 | try: 1300 | if setting.lower() == 'public': 1301 | await client.party.set_privacy(rebootpy.PartyPrivacy.PUBLIC) 1302 | await ctx.send(f"Party Privacy set to: Public") 1303 | elif setting.lower() == 'friends': 1304 | await client.party.set_privacy(rebootpy.PartyPrivacy.FRIENDS) 1305 | await ctx.send(f"Party Privacy set to: Friends Only") 1306 | elif setting.lower() == 'private': 1307 | await client.party.set_privacy(rebootpy.PartyPrivacy.PRIVATE) 1308 | await ctx.send(f"Party Privacy set to: Private") 1309 | else: 1310 | await ctx.send("That is not a valid privacy setting. Try: Public, Friends, or Private") 1311 | except rebootpy.Forbidden: 1312 | await ctx.send("I can not set the party privacy because I am not party leader.") 1313 | else: 1314 | await ctx.send(f"No privacy setting was given. Try: {prefix}privacy (Public, Friends, Private)") 1315 | 1316 | 1317 | @commands.dm_only() 1318 | @client.command() 1319 | @is_admin() 1320 | async def join(ctx, *, member = None): 1321 | try: 1322 | if member is None: 1323 | user = await client.fetch_profile(ctx.message.author.id) 1324 | friend = client.get_friend(user.id) 1325 | elif member is not None: 1326 | user = await client.fetch_profile(member) 1327 | friend = client.get_friend(user.id) 1328 | 1329 | await friend.join_party() 1330 | await ctx.send(f"Joined {friend.display_name}'s party.") 1331 | except rebootpy.Forbidden: 1332 | await ctx.send("I can not join that party because it is private.") 1333 | except rebootpy.PartyError: 1334 | await ctx.send("That user is already in the party.") 1335 | except rebootpy.HTTPException: 1336 | await ctx.send("Something went wrong joining the party") 1337 | except AttributeError: 1338 | await ctx.send("I can not join that party. Are you sure I have them friended?") 1339 | 1340 | 1341 | @commands.dm_only() 1342 | @client.command() 1343 | @is_admin() 1344 | async def invite(ctx, *, member = None): 1345 | if member == 'all': 1346 | friends = client.friends 1347 | invited = [] 1348 | 1349 | try: 1350 | for f in friends: 1351 | friend = client.get_friend(f) 1352 | 1353 | if friend.is_online(): 1354 | invited.append(friend.display_name) 1355 | await friend.invite() 1356 | 1357 | await ctx.send(f"Invited {len(invited)} friends to the party.") 1358 | 1359 | except Exception: 1360 | pass 1361 | 1362 | else: 1363 | try: 1364 | if member is None: 1365 | user = await client.fetch_profile(ctx.message.author.id) 1366 | friend = client.get_friend(user.id) 1367 | if member is not None: 1368 | user = await client.fetch_profile(member) 1369 | friend = client.get_friend(user.id) 1370 | 1371 | await friend.invite() 1372 | await ctx.send(f"Invited {friend.display_name} to the party.") 1373 | except rebootpy.PartyError: 1374 | await ctx.send("That user is already in the party.") 1375 | except rebootpy.HTTPException: 1376 | await ctx.send("Something went wrong inviting that user.") 1377 | except AttributeError: 1378 | await ctx.send("I can not invite that user. Are you sure I have them friended?") 1379 | except Exception: 1380 | pass 1381 | 1382 | 1383 | @commands.dm_only() 1384 | @client.command() 1385 | @is_admin() 1386 | async def add(ctx, *, member = None): 1387 | if member is not None: 1388 | try: 1389 | user = await client.fetch_profile(member) 1390 | friends = client.friends 1391 | 1392 | if user.id in friends: 1393 | await ctx.send(f"I already have {user.display_name} as a friend") 1394 | else: 1395 | await client.add_friend(user.id) 1396 | await ctx.send(f'Sent a friend request to {user.display_name}') 1397 | print(Fore.GREEN + ' [+] ' + Fore.RESET + 'Sent a friend request to: ' + Fore.LIGHTBLACK_EX + f'{user.display_name}') 1398 | 1399 | except rebootpy.HTTPException: 1400 | await ctx.send("There was a problem trying to add this friend.") 1401 | except AttributeError: 1402 | await ctx.send("I can't find a player with that name.") 1403 | else: 1404 | await ctx.send(f"No user was given. Try: {prefix}add (user)") 1405 | 1406 | 1407 | @commands.dm_only() 1408 | @client.command() 1409 | @is_admin() 1410 | async def block(ctx, *, user = None): 1411 | if user is not None: 1412 | try: 1413 | user = await client.fetch_profile(user) 1414 | friends = client.friends 1415 | 1416 | if user.id in friends: 1417 | try: 1418 | await user.block() 1419 | await ctx.send(f"Blocked {user.display_name}") 1420 | except rebootpy.HTTPException: 1421 | await ctx.send("Something went wrong trying to block that user.") 1422 | 1423 | elif user.id in client.blocked_users: 1424 | await ctx.send(f"I already have {user.display_name} blocked.") 1425 | except AttributeError: 1426 | await ctx.send("I can't find a player with that name.") 1427 | else: 1428 | await ctx.send(f"No user was given. Try: {prefix}block (friend)") 1429 | 1430 | 1431 | @commands.dm_only() 1432 | @client.command() 1433 | @is_admin() 1434 | async def blocked(ctx): 1435 | 1436 | blockedusers = [] 1437 | 1438 | for b in client.blocked_users: 1439 | user = client.get_blocked_user(b) 1440 | blockedusers.append(user.display_name) 1441 | 1442 | await ctx.send(f'Client has {len(blockedusers)} users blocked:') 1443 | for x in blockedusers: 1444 | if x is not None: 1445 | await ctx.send(x) 1446 | 1447 | 1448 | @commands.dm_only() 1449 | @client.command() 1450 | @is_admin() 1451 | async def unblock(ctx, *, user = None): 1452 | if user is not None: 1453 | try: 1454 | member = await client.fetch_profile(user) 1455 | blocked = client.blocked_users 1456 | if member.id in blocked: 1457 | try: 1458 | await client.unblock_user(member.id) 1459 | await ctx.send(f'Successfully unblocked {member.display_name}') 1460 | except rebootpy.HTTPException: 1461 | await ctx.send('Something went wrong trying to unblock that user.') 1462 | else: 1463 | await ctx.send('That user is not blocked') 1464 | except AttributeError: 1465 | await ctx.send("I can't find a player with that name.") 1466 | else: 1467 | await ctx.send(f'No user was given. Try: {prefix}unblock (blocked user)') 1468 | 1469 | 1470 | @commands.dm_only() 1471 | @client.command() 1472 | @is_admin() 1473 | async def friends(ctx): 1474 | cfriends = client.friends 1475 | onlineFriends = [] 1476 | offlineFriends = [] 1477 | 1478 | try: 1479 | for f in cfriends: 1480 | friend = client.get_friend(f) 1481 | if friend.is_online(): 1482 | onlineFriends.append(friend.display_name) 1483 | else: 1484 | offlineFriends.append(friend.display_name) 1485 | 1486 | await ctx.send(f"Client has: {len(onlineFriends)} friends online and {len(offlineFriends)} friends offline") 1487 | await ctx.send("(Check cmd for full list of friends)") 1488 | 1489 | print(" [+] Friends List: " + Fore.GREEN + f'{len(onlineFriends)} Online ' + Fore.RESET + "/" + Fore.LIGHTBLACK_EX + f' {len(offlineFriends)} Offline ' + Fore.RESET + "/" + Fore.LIGHTWHITE_EX + f' {len(onlineFriends) + len(offlineFriends)} Total') 1490 | 1491 | for x in onlineFriends: 1492 | if x is not None: 1493 | print(Fore.GREEN + " " + x) 1494 | for x in offlineFriends: 1495 | if x is not None: 1496 | print(Fore.LIGHTBLACK_EX + " " + x) 1497 | except Exception: 1498 | pass 1499 | 1500 | 1501 | @commands.dm_only() 1502 | @client.command() 1503 | @is_admin() 1504 | async def members(ctx: rebootpy.ext.commands.Context): 1505 | pmembers = client.party.members 1506 | partyMembers = [] 1507 | 1508 | for m in pmembers: 1509 | member = client.get_user(m) 1510 | partyMembers.append(member.display_name) 1511 | 1512 | await ctx.send(f"There are {len(partyMembers)} members in {client.user.display_name}'s party:") 1513 | for x in partyMembers: 1514 | if x is not None: 1515 | await ctx.send(x) 1516 | 1517 | @commands.dm_only() 1518 | @client.command() 1519 | async def invisible(ctx: rebootpy.ext.commands.Context): 1520 | await client.party.me.set_outfit("CID_Invisible") 1521 | await ctx.send("I am now invisible.") 1522 | 1523 | 1524 | @commands.dm_only() 1525 | @client.command() 1526 | @is_admin() 1527 | async def id(ctx, *, user = None): 1528 | if user is not None: 1529 | user = await client.fetch_profile(user) 1530 | 1531 | elif user is None: 1532 | user = await client.fetch_profile(ctx.message.author.id) 1533 | 1534 | try: 1535 | await ctx.send(f"{user}'s Epic ID is: {user.id}") 1536 | print(Fore.GREEN + ' [+] ' + Fore.RESET + f"{user}'s Epic ID is: " + Fore.LIGHTBLACK_EX + f'{user.id}') 1537 | except AttributeError: 1538 | await ctx.send("I couldn't find an Epic account with that name.") 1539 | 1540 | 1541 | @commands.dm_only() 1542 | @client.command() 1543 | @is_admin() 1544 | async def user(ctx, *, user = None): 1545 | if user is not None: 1546 | user = await client.fetch_profile(user) 1547 | 1548 | try: 1549 | await ctx.send(f"The ID: {user.id} belongs to: {user.display_name}") 1550 | print(Fore.GREEN + ' [+] ' + Fore.RESET + f'The ID: {user.id} belongs to: ' + Fore.LIGHTBLACK_EX + f'{user.display_name}') 1551 | except AttributeError: 1552 | await ctx.send(f"I couldn't find a user that matches that ID") 1553 | else: 1554 | await ctx.send(f'No ID was given. Try: {prefix}user (ID)') 1555 | 1556 | 1557 | @commands.dm_only() 1558 | @client.command() 1559 | async def admin(ctx, setting = None, *, user = None): 1560 | if (setting is None) and (user is None): 1561 | await ctx.send(f"Missing one or more arguments. Try: {prefix}admin (add, remove, list) (user)") 1562 | elif (setting is not None) and (user is None): 1563 | 1564 | user = await client.fetch_profile(ctx.message.author.id) 1565 | 1566 | if setting.lower() == 'add': 1567 | if user.id in info['FullAccess']: 1568 | await ctx.send("You are already an admin") 1569 | 1570 | else: 1571 | await ctx.send("Password?") 1572 | response = await client.wait_for('friend_message', timeout=20) 1573 | content = response.content.lower() 1574 | if content == data['AdminPassword']: 1575 | info['FullAccess'].append(user.id) 1576 | with open('info.json', 'w') as f: 1577 | json.dump(info, f, indent=4) 1578 | await ctx.send(f"Correct. Added {user.display_name} as an admin.") 1579 | print(Fore.GREEN + " [+] " + Fore.LIGHTGREEN_EX + user.display_name + Fore.RESET + " was added as an admin.") 1580 | else: 1581 | await ctx.send("Incorrect Password.") 1582 | 1583 | elif setting.lower() == 'remove': 1584 | if user.id not in info['FullAccess']: 1585 | await ctx.send("You are not an admin.") 1586 | else: 1587 | await ctx.send("Are you sure you want to remove yourself as an admin?") 1588 | response = await client.wait_for('friend_message', timeout=20) 1589 | content = response.content.lower() 1590 | if (content.lower() == 'yes') or (content.lower() == 'y'): 1591 | info['FullAccess'].remove(user.id) 1592 | with open('info.json', 'w') as f: 1593 | json.dump(info, f, indent=4) 1594 | await ctx.send("You were removed as an admin.") 1595 | print(Fore.BLUE + " [+] " + Fore.LIGHTBLUE_EX + user.display_name + Fore.RESET + " was removed as an admin.") 1596 | elif (content.lower() == 'no') or (content.lower() == 'n'): 1597 | await ctx.send("You were kept as admin.") 1598 | else: 1599 | await ctx.send("Not a correct reponse. Cancelling command.") 1600 | 1601 | elif setting == 'list': 1602 | if user.id in info['FullAccess']: 1603 | admins = [] 1604 | 1605 | for admin in info['FullAccess']: 1606 | user = await client.fetch_profile(admin) 1607 | admins.append(user.display_name) 1608 | 1609 | await ctx.send(f"The bot has {len(admins)} admins:") 1610 | 1611 | for admin in admins: 1612 | await ctx.send(admin) 1613 | 1614 | else: 1615 | await ctx.send("You don't have permission to this command.") 1616 | 1617 | else: 1618 | await ctx.send(f"That is not a valid setting. Try: {prefix}admin (add, remove, list) (user)") 1619 | 1620 | elif (setting is not None) and (user is not None): 1621 | user = await client.fetch_profile(user) 1622 | 1623 | if setting.lower() == 'add': 1624 | if ctx.message.author.id in info['FullAccess']: 1625 | if user.id not in info['FullAccess']: 1626 | info['FullAccess'].append(user.id) 1627 | with open('info.json', 'w') as f: 1628 | json.dump(info, f, indent=4) 1629 | await ctx.send(f"Correct. Added {user.display_name} as an admin.") 1630 | print(Fore.GREEN + " [+] " + Fore.LIGHTGREEN_EX + user.display_name + Fore.RESET + " was added as an admin.") 1631 | else: 1632 | await ctx.send("That user is already an admin.") 1633 | else: 1634 | await ctx.send("You don't have access to add other people as admins. Try just: !admin add") 1635 | elif setting.lower() == 'remove': 1636 | if ctx.message.author.id in info['FullAccess']: 1637 | if user.id in info['FullAccess']: 1638 | await ctx.send("Password?") 1639 | response = await client.wait_for('friend_message', timeout=20) 1640 | content = response.content.lower() 1641 | if content == data['AdminPassword']: 1642 | info['FullAccess'].remove(user.id) 1643 | with open('info.json', 'w') as f: 1644 | json.dump(info, f, indent=4) 1645 | await ctx.send(f"{user.display_name} was removed as an admin.") 1646 | print(Fore.BLUE + " [+] " + Fore.LIGHTBLUE_EX + user.display_name + Fore.RESET + " was removed as an admin.") 1647 | else: 1648 | await ctx.send("Incorrect Password.") 1649 | else: 1650 | await ctx.send("That person is not an admin.") 1651 | else: 1652 | await ctx.send("You don't have permission to remove players as an admin.") 1653 | else: 1654 | await ctx.send(f"Not a valid setting. Try: {prefix}admin (add, remove) (user)") 1655 | 1656 | 1657 | if (data['email'] and data['password']) and (data['email'] != "" and data['password'] != ""): 1658 | try: 1659 | client.run() 1660 | except rebootpy.errors.AuthException as e: 1661 | print(Fore.RED + ' [ERROR] ' + Fore.RESET + f'{e}') 1662 | except ModuleNotFoundError as e: 1663 | print(e) 1664 | print(Fore.RED + f'[-] ' + Fore.RESET + 'Failed to import 1 or more modules. Run "INSTALL PACKAGES.bat') 1665 | exit() 1666 | else: 1667 | print(Fore.RED + ' [ERROR] ' + Fore.RESET + 'Can not log in, as no accounts credentials were provided.') 1668 | -------------------------------------------------------------------------------- /info.json: -------------------------------------------------------------------------------- 1 | { 2 | "FullAccess": [] 3 | } -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | rebootpy 2 | aiohttp 3 | aioconsole 4 | colorama 5 | FortniteAPIAsync==0.1.6 6 | requests 7 | pytz 8 | --------------------------------------------------------------------------------