From 036d3ec0485818b49d2b6cec58d4031a8cd78050 Mon Sep 17 00:00:00 2001 From: Sakimori Date: Fri, 5 Feb 2021 18:43:40 -0500 Subject: [PATCH 01/12] undid the emoji "fix" because it didn't fix anything --- games.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/games.py b/games.py index f12b787..0773eb8 100644 --- a/games.py +++ b/games.py @@ -884,7 +884,7 @@ class weather(object): def __init__(self, new_name, new_emoji): self.name = new_name - self.emoji = new_emoji + "\uFE00" + self.emoji = new_emoji self.counter_away = 0 self.counter_home = 0 From 501e96901d23b07422e5f4d9d1b214d06f4eea16 Mon Sep 17 00:00:00 2001 From: Sakimori Date: Sun, 7 Feb 2021 14:23:26 -0500 Subject: [PATCH 02/12] added another backer --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a36951a..462524a 100644 --- a/README.md +++ b/README.md @@ -158,6 +158,7 @@ these folks are helping me a *ton* via patreon, and i cannot possibly thank them - Evie Diver - iliana etaoin - yooori +- Bend ## Attribution From 9b9a25f35a81c43b1b984450f395f10256effdfe Mon Sep 17 00:00:00 2001 From: Sakimori Date: Wed, 10 Feb 2021 00:00:34 -0500 Subject: [PATCH 03/12] fixed bug where pauseleague didn't work between series --- the_prestige.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/the_prestige.py b/the_prestige.py index 1003b1a..9b617e1 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -2010,7 +2010,7 @@ async def league_day_watcher(channel, league, games_list, filter_url, last = Fal else: league.active = False - if league.autoplay == 0 or config()["game_freeze"]: #if number of series to autoplay has been reached + if league.autoplay <= 0 or config()["game_freeze"]: #if number of series to autoplay has been reached if league in active_standings.keys(): await active_standings[league].unpin() active_standings[league] = await channel.send(embed=league.standings_embed()) From f845bb431a6809e9aa3bc903672d20f3c3dad5be Mon Sep 17 00:00:00 2001 From: Sakimori Date: Thu, 11 Feb 2021 18:12:36 -0500 Subject: [PATCH 04/12] stopped deleting startgame messages due to less reliance on discord as a display format --- the_prestige.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/the_prestige.py b/the_prestige.py index 9b617e1..103d34b 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -182,7 +182,6 @@ class StartGameCommand(Command): game.teams['away'].set_pitcher(rotation_slot = day) game.teams['home'].set_pitcher(rotation_slot = day) channel = msg.channel - await msg.delete() game_task = asyncio.create_task(watch_game(channel, game, user=msg.author, league=league)) await game_task @@ -201,7 +200,6 @@ class StartRandomGameCommand(Command): return channel = msg.channel - await msg.delete() await channel.send("Rolling the bones... This might take a while.") teamslist = games.get_all_teams() From bc7f1784626185cd6456e73cdea29148c743ad96 Mon Sep 17 00:00:00 2001 From: Sakimori Date: Thu, 11 Feb 2021 18:19:58 -0500 Subject: [PATCH 05/12] fixes #191 --- the_prestige.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/the_prestige.py b/the_prestige.py index 103d34b..a66e831 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -1164,6 +1164,7 @@ active_tournaments = [] active_leagues = [] active_standings = {} setupmessages = {} +watching = False thread1 = threading.Thread(target=main_controller.update_loop) thread1.start() @@ -1195,8 +1196,10 @@ def config(): async def on_ready(): db.initialcheck() print(f"logged in as {client.user} with token {config()['token']} to {len(client.guilds)} servers") - watch_task = asyncio.create_task(game_watcher()) - await watch_task + if not watching: + watching = True + watch_task = asyncio.create_task(game_watcher()) + await watch_task @client.event From 28e4e68c5a13ac99e458a639a0d0fa60676cc7ae Mon Sep 17 00:00:00 2001 From: Sakimori Date: Thu, 11 Feb 2021 18:34:26 -0500 Subject: [PATCH 06/12] really fixed #191. closes #190, -w or --weather flag on startgame can set weather --- the_prestige.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/the_prestige.py b/the_prestige.py index a66e831..d5071a9 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -145,6 +145,12 @@ class StartGameCommand(Command): await msg.channel.send("Make sure you put an integer after the -d flag.") return + weather_name = None + if "-w " in command.split("\n")[0]: + weather_name = command.split("\n")[0].split("-w ")[1].split("-")[0].strip() + elif "--weather " in command.split("\n")[0]: + weather_name = command.split("\n")[0].split("--weather ")[1].split("-")[0].strip() + innings = None try: team_name1 = command.split("\n")[1].strip() @@ -183,6 +189,10 @@ class StartGameCommand(Command): game.teams['home'].set_pitcher(rotation_slot = day) channel = msg.channel + if weather_name is not None and weather_name in games.all_weathers().keys(): + game.weather = games.all_weathers()[weather_name] + + game_task = asyncio.create_task(watch_game(channel, game, user=msg.author, league=league)) await game_task else: @@ -1158,13 +1168,14 @@ commands = [ DraftPlayerCommand() ] +watching = False client = discord.Client() gamesarray = [] active_tournaments = [] active_leagues = [] active_standings = {} setupmessages = {} -watching = False + thread1 = threading.Thread(target=main_controller.update_loop) thread1.start() @@ -1194,6 +1205,7 @@ def config(): @client.event async def on_ready(): + global watching db.initialcheck() print(f"logged in as {client.user} with token {config()['token']} to {len(client.guilds)} servers") if not watching: @@ -1396,7 +1408,7 @@ async def watch_game(channel, newgame, user = None, league = None): main_controller.master_games_dic[id] = (newgame, state_init, discrim_string) def prepare_game(newgame, league = None, weather_name = None): - if weather_name is None: + if weather_name is None and newgame.weather.name == "Sunny": #if no weather name supplied and the game's weather is default, pick random weather weathers = games.all_weathers() newgame.weather = weathers[random.choice(list(weathers.keys()))] From bd43b5018a7644522e9ea412524815ba7a3bb567 Mon Sep 17 00:00:00 2001 From: Sakimori Date: Thu, 11 Feb 2021 18:47:45 -0500 Subject: [PATCH 07/12] added bat_base_req and pitch_base_req which get added at the end of the respective sql statements; multiplied by day of league --- league_storage.py | 15 +++++++++++---- leagues.py | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/league_storage.py b/league_storage.py index 2b36a6f..1307e4e 100644 --- a/league_storage.py +++ b/league_storage.py @@ -34,11 +34,16 @@ def statements(): ROUND(total_bases*1.0 / (plate_appearances - (walks_taken + sacrifices)*1.0),3) as SLG, ROUND((walks_taken + hits)*1.0/plate_appearances*1.0,3) as OBP, ROUND((walks_taken + hits)*1.0/plate_appearances*1.0,3) + ROUND(total_bases*1.0 / (plate_appearances - (walks_taken + sacrifices)*1.0),3) as OPS -FROM stats WHERE plate_appearances > 8""", +FROM stats WHERE plate_appearances > """, + "bat_base_req": 3, "avg" : ["ORDER BY BA DESC;", "bat_base"], "slg" : ["ORDER BY SLG DESC;", "bat_base"], "obp" : ["ORDER BY OBP DESC;", "bat_base"], "ops" : ["ORDER BY OPS DESC;", "bat_base"], + "bat_count_base": "SELECT name, team_name,\n\tplate_appearances - (walks_taken + sacrifices) as ABs,\nwalks_taken as BB,\nhits as H,\nhome_runs as HR,\nrbis as RBIs,\nstrikeouts_taken as K,\nsacrifices\nFROM stats WHERE plate_appearances > 8", + "home runs": ["ORDER BY HR DESC;", "bat_count_base"], + "walks drawn": ["ORDER BY BB DESC;", "bat_count_base"], + "bat_count_base_req" : 3, "pitch_base" : """SELECT name, team_name, ROUND(((outs_pitched*1.0)/3.0),1) as IP, ROUND(runs_allowed*27.0/(outs_pitched*1.0),3) as ERA, @@ -46,8 +51,9 @@ FROM stats WHERE plate_appearances > 8""", ROUND(walks_allowed*27.0/(outs_pitched*1.0),3) as BBper9, ROUND(strikeouts_given*27.0/(outs_pitched*1.0),3) as Kper9, ROUND(strikeouts_given*1.0/walks_allowed*1.0,3) as KperBB -FROM stats WHERE outs_pitched > 20 +FROM stats WHERE outs_pitched > """, + "pitch_base_req": 2, "era" : ["ORDER BY ERA ASC;", "pitch_base"], "whip" : ["ORDER BY WHIP ASC;", "pitch_base"], "kper9" : ["ORDER BY Kper9 DESC;", "pitch_base"], @@ -169,7 +175,7 @@ def add_stats(league_name, player_game_stats_list): conn.commit() conn.close() -def get_stats(league_name, stat, is_batter=True): +def get_stats(league_name, stat, is_batter=True, day = 10): conn = create_connection(league_name) stats = None if conn is not None: @@ -177,7 +183,8 @@ def get_stats(league_name, stat, is_batter=True): c=conn.cursor() if stat in statements().keys(): - c.execute(statements()[statements()[stat][1]]+"\n"+statements()[stat][0]) + req_number = str(day * int(statements()[statements()[stat][1]+"_req"])) + c.execute(statements()[statements()[stat][1]]+req_number+"\n"+statements()[stat][0]) stats = c.fetchall() conn.close() return stats diff --git a/leagues.py b/leagues.py index 7970c0d..2f87736 100644 --- a/leagues.py +++ b/leagues.py @@ -417,7 +417,7 @@ class league_structure(object): def stat_embed(self, stat_name): this_embed = Embed(color=Color.purple(), title=f"{self.name} Season {self.season} {stat_name} Leaders") - stats = league_db.get_stats(self.name, stat_name.lower()) + stats = league_db.get_stats(self.name, stat_name.lower(), day = self.day) if stats is None: return None else: From eced24439814af6750fd51077ce7300aad00de7f Mon Sep 17 00:00:00 2001 From: Sakimori Date: Thu, 11 Feb 2021 19:26:33 -0500 Subject: [PATCH 08/12] implemented m;leagueswapteam --- league_storage.py | 3 +++ leagues.py | 15 ++++++++++++--- the_prestige.py | 39 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 5 deletions(-) diff --git a/league_storage.py b/league_storage.py index 1307e4e..0dcee16 100644 --- a/league_storage.py +++ b/league_storage.py @@ -91,6 +91,9 @@ def state(league_name): return json.load(state_file) def init_league_db(league): + if os.path.exists(os.path.join(data_dir, league_dir, league.name, f"{league.name}.db")): + os.remove(os.path.join(data_dir, league_dir, league.name, f"{league.name}.db")) + conn = create_connection(league.name) player_stats_table_check_string = """ CREATE TABLE IF NOT EXISTS stats ( diff --git a/leagues.py b/leagues.py index 2f87736..f4dd135 100644 --- a/leagues.py +++ b/leagues.py @@ -89,11 +89,13 @@ class league_structure(object): tournaments.append(tourney) return tournaments - def find_team(self, team_name): + def find_team(self, team_search): for subleague in iter(self.league.keys()): for division in iter(self.league[subleague].keys()): - if team_name in self.league[subleague][division]: - return (subleague, division) + for team in self.league[subleague][division]: + if team.name == team_search.name: + return (subleague, division) + return (None, None) def teams_in_league(self): teams = [] @@ -548,6 +550,13 @@ def save_league(this_league): json.dump(league_json_string, league_file, indent=4) league_db.save_league(this_league) +def save_league_as_new(this_league): + league_db.init_league_db(this_league) + with open(os.path.join(data_dir, league_dir, this_league.name, f"{this_league.name}.league"), "w") as league_file: + league_json_string = jsonpickle.encode(this_league.league, keys=True) + json.dump(league_json_string, league_file, indent=4) + league_db.save_league(this_league) + def load_league_file(league_name): if league_db.league_exists(league_name): state = league_db.state(league_name) diff --git a/the_prestige.py b/the_prestige.py index d5071a9..af781ae 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -1123,9 +1123,43 @@ class LeagueForceStopCommand(Command): await msg.channel.send("League halted, boss. We hope you did that on purpose.") return await msg.channel.send("That league either doesn't exist or isn't in the active list. So, huzzah?") - - +class LeagueSwapTeamCommand(Command): + name = "leagueswapteam" + template = "m;leagueswapteam [league name]\n[team to remove]\n[team to add]" + description = "Adds a team to a league, removing the old one in the process. Can only be executed by a league owner, and only before the start of a new season." + + async def execute(self, msg, command): + league_name = command.split("\n")[0].strip() + if league_exists(league_name): + league = leagues.load_league_file(league_name) + if league.day != 1: + await msg.channel.send("That league hasn't finished its current season yet, chief. Either reset it, or be patient.") + return + if (league.owner is not None and msg.author.id in league.owner) or (league.owner is not None and msg.author.id in config()["owners"]): + try: + team_del = get_team_fuzzy_search(command.split("\n")[1].strip()) + team_add = get_team_fuzzy_search(command.split("\n")[2].strip()) + except IndexError: + await msg.channel.send("Three lines, boss. Make sure you give us the team to remove, then the team to add.") + return + + if team_del is None or team_add is None: + await msg.channel.send("We couldn't find one or both of those teams, boss. Try again.") + return + subleague, division = league.find_team(team_del) + if subleague is None or division is None: + await msg.channel.send("That first team isn't in that league, chief. So, that's good, right?") + return + for index in range(0, len(league.league[subleague][division])): + if league.league[subleague][division][index].name == team_del.name: + league.league[subleague][division].pop(index) + league.league[subleague][division].append(team_add) + league.schedule = {} + league.generate_schedule() + leagues.save_league_as_new(league) + await msg.channel.send(embed=league.standings_embed()) + await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.") commands = [ IntroduceCommand(), @@ -1160,6 +1194,7 @@ commands = [ LeagueScheduleCommand(), LeagueTeamScheduleCommand(), LeagueRegenerateScheduleCommand(), + LeagueSwapTeamCommand(), LeagueForceStopCommand(), CreditCommand(), RomanCommand(), From f0d589fecddc178c7f0346c252dd07ec1f26f64d Mon Sep 17 00:00:00 2001 From: Sakimori Date: Thu, 11 Feb 2021 19:30:48 -0500 Subject: [PATCH 09/12] added input validation and responses to leagueswapteam --- the_prestige.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/the_prestige.py b/the_prestige.py index af781ae..8a04c1f 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -1143,14 +1143,23 @@ class LeagueSwapTeamCommand(Command): except IndexError: await msg.channel.send("Three lines, boss. Make sure you give us the team to remove, then the team to add.") return + if team_add.name == team_del.name: + await msg.channel.send("Quit being cheeky. The teams have to be different.") + return if team_del is None or team_add is None: await msg.channel.send("We couldn't find one or both of those teams, boss. Try again.") return - subleague, division = league.find_team(team_del) + subleague, division = league.find_team(team_del) + if subleague is None or division is None: await msg.channel.send("That first team isn't in that league, chief. So, that's good, right?") return + + if league.find_team(team_add)[0] is not None: + await msg.channel.send("That second team is already in that league, chief. No doubles.") + return + for index in range(0, len(league.league[subleague][division])): if league.league[subleague][division][index].name == team_del.name: league.league[subleague][division].pop(index) From 93f43ba88f8613256267a02faabfd62669685edd Mon Sep 17 00:00:00 2001 From: Sakimori Date: Thu, 11 Feb 2021 19:52:43 -0500 Subject: [PATCH 10/12] added leaguerename, to rename divisions and subleagues; NO SUPPORT FOR RENAMING LEAGUES --- the_prestige.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/the_prestige.py b/the_prestige.py index 8a04c1f..5499332 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -1169,6 +1169,69 @@ class LeagueSwapTeamCommand(Command): leagues.save_league_as_new(league) await msg.channel.send(embed=league.standings_embed()) await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.") + else: + await msg.channel.send("That league isn't yours, chief.") + else: + await msg.channel.send("We can't find that league.") + +class LeagueRenameCommand(Command): + name = "leaguerename" + template = "m;leaguerename [league name]\n[old subleague/division name]\n[new subleague/division name]" + description = "Changes the name of an existing subleague or division. Can only be executed by a league owner, and only before the start of a new season." + + async def execute(self, msg, command): + league_name = command.split("\n")[0].strip() + if league_exists(league_name): + league = leagues.load_league_file(league_name) + if league.day != 1: + await msg.channel.send("That league hasn't finished its current season yet, chief. Either reset it, or be patient.") + return + if (league.owner is not None and msg.author.id in league.owner) or (league.owner is not None and msg.author.id in config()["owners"]): + try: + old_name = command.split("\n")[1].strip() + new_name = command.split("\n")[2].strip() + except IndexError: + await msg.channel.send("Three lines, boss. Make sure you give us the old name, then the new name, on their own lines.") + return + + if old_name == new_name: + await msg.channel.send("Quit being cheeky. They have to be different names, clearly.") + + + found = False + for subleague in league.league.keys(): + if subleague == new_name: + found = True + break + for division in league.league[subleague]: + if division == new_name: + found = True + break + if found: + await msg.channel.send(f"{new_name} is already present in that league, chief. They have to be different.") + + found = False + for subleague in league.league.keys(): + if subleague == old_name: + league.league[new_name] = league.league.pop(old_name) + found = True + break + for division in league.league[subleague]: + if division == old_name: + league.league[subleague][new_name] = league.league[subleague].pop(old_name) + found = True + break + if not found: + await msg.channel.send(f"We couldn't find {old_name} anywhere in that league, boss.") + return + leagues.save_league_as_new(league) + await msg.channel.send(embed=league.standings_embed()) + await msg.channel.send("Paperwork signed, stamped, copied, and faxed up to the goddess. Xie's pretty quick with this stuff.") + else: + await msg.channel.send("That league isn't yours, chief.") + else: + await msg.channel.send("We can't find that league.") + commands = [ IntroduceCommand(), @@ -1204,6 +1267,7 @@ commands = [ LeagueTeamScheduleCommand(), LeagueRegenerateScheduleCommand(), LeagueSwapTeamCommand(), + LeagueRenameCommand(), LeagueForceStopCommand(), CreditCommand(), RomanCommand(), From ceab8e626445e03f95ea2fc14a46ad52f6e6fab6 Mon Sep 17 00:00:00 2001 From: Sakimori Date: Fri, 19 Feb 2021 19:04:40 -0500 Subject: [PATCH 11/12] fixed a bug with finals end card for non-league tournaments --- the_prestige.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/the_prestige.py b/the_prestige.py index 5499332..201aa8e 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -1701,7 +1701,7 @@ async def tourney_round_watcher(channel, tourney, games_list, filter_url, finals if finals: #if this last round was finals embed = discord.Embed(color = discord.Color.dark_purple(), title = f"{winner_list[0]} win the {tourney.name} finals!") - if tourney.day > tourney.league.day: + if tourney.league is not None and tourney.day > tourney.league.day: tourney.league.day = tourney.day await channel.send(embed=embed) tourney.winner = get_team_fuzzy_search(winner_list[0]) From e9df24444628569915b7be2ca97f803d41a5ac65 Mon Sep 17 00:00:00 2001 From: Sakimori Date: Fri, 19 Feb 2021 19:05:06 -0500 Subject: [PATCH 12/12] enabled all weathers --- games.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/games.py b/games.py index 0773eb8..ed39dae 100644 --- a/games.py +++ b/games.py @@ -30,9 +30,9 @@ def config(): def all_weathers(): weathers_dic = { - #"Supernova" : weather("Supernova", "🌟"), - #"Midnight": weather("Midnight", "🕶"), - #"Slight Tailwind": weather("Slight Tailwind", "🏌️‍♀️"), + "Supernova" : weather("Supernova", "🌟"), + "Midnight": weather("Midnight", "🕶"), + "Slight Tailwind": weather("Slight Tailwind", "🏌️‍♀️"), "Heavy Snow": weather("Heavy Snow", "❄"), "Twilight" : weather("Twilight", "👻"), "Thinned Veil" : weather("Thinned Veil", "🌌"),