Skip to content

Commit

Permalink
minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
ucarno committed May 2, 2023
1 parent 377e6e1 commit 34667f4
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 44 deletions.
54 changes: 33 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Overwatch League Tokens Bot
This is an app that watches League streams for you on YouTube! Still experimental, [issues](#possible-issues) may occur.

Also, no contenders skins support as contenders skins are earned via Twitch drops - not watching on YouTube.
To earn contenders skins in the same automated fashion, try [this](https://github.com/DevilXD/TwitchDropsMiner) app.
Also, no contenders skins support as Contenders skins are earned via Twitch drops - not watching on YouTube.
To earn Contenders skins in the same automated fashion, try [this](https://github.com/DevilXD/TwitchDropsMiner) app.

<div align="center">

Expand All @@ -11,17 +11,17 @@ To earn contenders skins in the same automated fashion, try [this](https://githu
</div>

## Features
* Automatic live broadcast detection - don't worry about "when" and "where"
* Automatic live broadcast detection don't worry about "when" and "where"
* Multiple accounts support - you just need multiple Google accounts
* Headless mode - see only console window (as before) if extra Chrome window is bothering you
* No sound - Chrome will be muted entirely
* Headless mode see only a console window (as before) if an extra Chrome window is bothering you
* No sound Chrome will be muted entirely

## Planned Features
* Automatically set broadcast quality to 144p, so it does not consume a lot of bandwidth
* Automatically set broadcast quality to 144p, so it doesn't consume a lot of bandwidth

## Installation
### Windows
1. Download latest version [here](https://github.com/ucarno/ow-league-tokens/releases/latest).
1. Download the latest version [here](https://github.com/ucarno/ow-league-tokens/releases/latest).
2. Unpack zip anywhere you want.
3. Run `ow-league-tokens.exe` to open the app.
4. Ignore Windows Defender's complaints about "unknown publisher".
Expand All @@ -34,44 +34,56 @@ do everything on another machine with GUI and copy `profiles/` directory to your
3. Go to app's directory using `cd ow-league-tokens`
4. Install dependencies via `pip3 install -r requirements.txt`
5. Run `python3 main.py`
6. Add required amount of profiles using menu (single profile for single Battle.net/Google account).
6. Add the required number of profiles using a menu (single profile for single Battle.net/Google account).

## Usage
Make sure you have Google Chrome installed.
This bot uses [Chrome Driver](https://github.com/ultrafunkamsterdam/undetected-chromedriver)
under the hood that requires Google Chrome to be installed.

Make sure you have Google Chrome installed, and it is at least version 112;
you can check your Chrome version here: `chrome://version/`

Also make sure you have connected Battle.net account(s) to Google account(s)
on [this](https://www.youtube.com/account_sharing) page!

1. Start the bot using first menu option.
1. Start the bot using a first menu option.
You should see Chrome window(s) opening, with text in console guiding you.
2. When you see Google's login screen - log in to your account.
3. Then you should be redirected to YouTube page and the bot will confirm that everything is OK by writing a success
message in console and redirecting you to home screen.
3. Then you should be redirected to the YouTube page, and the bot will confirm that everything is OK by writing a success
message in the console and redirecting you to the home screen.

## Updating
Sometimes you may see "new version available" message in your console. It probably means that I have fixed something.
Sometimes you may see "new version available" message in your console. It probably means that I've fixed something.

Bot can be updated without losing your profile(s) data (no need to login into Google again):
1. Download latest version from [here](https://github.com/ucarno/ow-league-tokens/releases/latest).
1. Download the latest version from [here](https://github.com/ucarno/ow-league-tokens/releases/latest).
2. Unpack it anywhere you want.
3. Move `config.json` file and `profiles` directory from old version to new one.
3. Move `config.json` file and `profiles` directory from an old version to new one.
4. Done!

## Command-line Arguments
* Use `--nomenu` (or `Start_Without_Menu.bat` on Windows) to run the app without menu using your `config.json` file.
* Use `--nomenu` (or `Start_Without_Menu.bat` on Windows) to run the app without a menu using your `config.json` file.

## Possible Issues
### Stream window randomly unloading
This may happen for example in non-headless mode when you collapse Chrome window.
Will be fixed in later release.
If you encounter any problems, **make sure your Chrome is the latest version**!

### Stream window is randomly unloading
This may happen, for example, in non-headless mode when you collapse a Chrome window.
It will be fixed in later release.

### Google can log you out of account
### Google profile is not restored after logging into account and re-opening the bot
If this happens to you, then after logging into Google account, don't instantly close and re-open the bot.
Let Chrome be open for a few minutes, may be try browsing your gmail or open a YouTube video.

### Google randomly logs you out of an account
This may happen if Google thinks your activity is suspicious (automated). Didn't happen for me, but may happen for you.
You can check if everything is OK by restarting an app. If you see "Authentication check passed." message then
You can check if everything is OK by restarting an app. If you see "Authentication check passed." Message then
everything is working as expected. I will look into this issue further and implement some fixes and checkers.

### Bot is watching ALL owl streams, not just those which give tokens
At the current state, bot will watch ALL streams on OWL channel, no matter if they give tokens or not.
I may implement watching only token-giving streams in the future.

### Anything else?
Then [open new issue](https://github.com/ucarno/ow-league-tokens/issues/new) and I will look into this.

Expand Down
12 changes: 7 additions & 5 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
debug = lambda msg: log_debug(f'Bot', msg)

driver_error = lambda _driver, msg: log_error(f'Chrome - \'{get_driver_profile(_driver)}\'', msg)
driver_info = lambda _driver, msg: log_error(f'Chrome - \'{get_driver_profile(_driver)}\'', msg)
driver_debug = lambda _driver, msg: log_error(f'Chrome - \'{get_driver_profile(_driver)}\'', msg)
driver_info = lambda _driver, msg: log_info(f'Chrome - \'{get_driver_profile(_driver)}\'', msg)
driver_debug = lambda _driver, msg: log_debug(f'Chrome - \'{get_driver_profile(_driver)}\'', msg)

DRIVERS: list[uc.Chrome] = []

Expand All @@ -34,14 +34,15 @@ def get_driver(profile: str, is_headless: bool) -> uc.Chrome:
options.add_argument('--autoplay-policy=no-user-gesture-required')
options.add_argument('--disable-extensions')
options.add_argument('--mute-audio')

driver = uc.Chrome(
options=options,
user_data_dir=PATH_PROFILES.joinpath(profile).absolute(),
headless=is_headless,
log_level=3 if is_debug() else 0,
)
driver.set_window_size(1200, 800)

driver.set_window_size(1200, 800)
setattr(driver, '__profile_name', profile)

return driver
Expand Down Expand Up @@ -70,8 +71,9 @@ def start_chrome(profiles: list[str], is_headless: bool, check_owl: bool, check_
global DRIVERS

info(f'&yBooting {len(profiles)} {"headless " if is_headless else ""}Chrome driver(s)...')
info('&yFollow all instructions you see here and &rDO NOT &ypress or '
'do anything until asked, it may break the bot.')
if not is_headless:
info('&yFollow all instructions you see here and &rDO NOT &ypress or '
'do anything until asked, it may break the bot.')

drivers = [get_driver(profile, is_headless) for profile in profiles]
DRIVERS = drivers
Expand Down
2 changes: 1 addition & 1 deletion src/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from colorama import Fore

CURRENT_VERSION = '2.0.0'
CURRENT_VERSION = '2.0.1'
UPDATE_DOWNLOAD_URL = 'https://github.com/ucarno/ow-league-tokens/releases/latest'

DEBUG_ENVIRON = 'OW_LEAGUE_TOKENS_DEBUG'
Expand Down
1 change: 1 addition & 0 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@


if __name__ == '__main__':
# fix requests module not able to find certs in lib folder
if hasattr(sys, 'frozen'):
os.environ['REQUESTS_CA_BUNDLE'] = (
str(PATH_ROOT.joinpath('lib').joinpath('certifi').joinpath('cacert.pem').absolute())
Expand Down
54 changes: 38 additions & 16 deletions src/menu.py
Original file line number Diff line number Diff line change
@@ -1,70 +1,91 @@
import os

from app import bootstrap
from constants import PATH_PROFILES
from utils import get_console_message, load_config, save_config


P = lambda msg: print(get_console_message('&y' + msg))
cls = lambda: os.system('cls' if os.name == 'nt' else 'clear')
wait_for_enter = lambda: input('\nPress Enter...\n')
get_input = lambda: input(' >> ')


def add_profile(config):
cls()

allowed_characters = set(list('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'))
allowed_chars_repr = '&gA-Z&r, &ga-z&r, &g0-9&r, &g-&r, &g_&r'
P('\nOne account - one (Gmail) profile. '
P('One account - one (Gmail) profile. '
'I recommend adding one account at a time so you know what account you log into.')
while True:
P(f'Enter profile name (allowed characters: {allowed_chars_repr.replace("&r", "&y")}) or leave blank to exit:')
name = input(' >> ')
name = get_input()

if not name:
return

if len(set(list(name)) - allowed_characters) > 0:
P(f'&rProfile name contains forbidden characters! Allowed characters are {allowed_chars_repr}&r.')
P(f'&rProfile name contains forbidden characters! Allowed characters are {allowed_chars_repr}&r.\n')
continue

if name in config['profiles']:
P(f'&rProfile \'{name}\' already exists!\n')
continue

config['profiles'].append(name)
save_config(config)
P('&gProfile added!')
P('&gProfile added!\n')
continue


def view_profiles(config):
cls()

if len(config['profiles']) == 0:
P('&rNo profiles!')
return
wait_for_enter()

P('Your profiles:')
for profile in config['profiles']:
P(f' &c{profile}')

P('\nYour profiles:')
for index, profile in enumerate(config['profiles']):
P(f' {index + 1}. &c{profile}')
wait_for_enter()


def remove_profile(config):
if len(config['profiles']) == 0:
P('&rNo profiles!')
wait_for_enter()
return

P('\nYou are gonna remove your profile. Profile will not be deleted (just disabled), you can re-add it later. '
cls()

P('You are gonna remove your profile. Profile will not be deleted (just disabled), you can re-add it later. '
f'To remove profile completely, delete profile from &g{PATH_PROFILES.absolute()}&y directory.')

while True:
if len(config['profiles']) == 0:
return

view_profiles(config)
P('Choose profile to remove (leave blank to exit):')
profile_idx = input(' >> ')
P('\nYour profiles:')
for index, profile in enumerate(config['profiles']):
P(f' {index + 1}. &c{profile}')

P('\nChoose profile to remove (leave blank to exit):')
profile_idx = get_input()
if not profile_idx:
return

profile_count = len(config['profiles'])
if not profile_idx.isdigit() or not 0 < int(profile_idx) <= profile_count:
P('&rInvalid profile number!')
P('\n&rInvalid profile number!')
continue

profile_idx = int(profile_idx) - 1
config['profiles'].pop(profile_idx)
save_config(config)
P('&gProfile removed!')
P('\n&gProfile removed!')

if len(config['profiles']) == 0:
return
Expand Down Expand Up @@ -110,15 +131,16 @@ def menu():
)
]

P('\n&cSelect an option:')
cls()
P('&cSelect an option:')
for index, (option_name, _) in enumerate(options):
P(f' &c{index + 1}. &y{option_name}')

option = input(' >> ')

if not option or not option.isdigit() or not 0 < int(option) <= len(options):
P('&rInvalid option!')
continue
wait_for_enter()

option_idx = int(option) - 1
option_callback = options[option_idx][1]
Expand Down
2 changes: 1 addition & 1 deletion version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.0
2.0.1

0 comments on commit 34667f4

Please sign in to comment.