implemented player modification on a per-team per-league basis

This commit is contained in:
Sakimori 2021-07-05 21:26:55 -04:00
parent 99dc2905a9
commit f7164f207e
4 changed files with 125 additions and 6 deletions

View file

@ -333,7 +333,7 @@ def search_teams(search_string):
conn = create_connection()
if conn is not None:
c = conn.cursor()
c.execute("SELECT team_json_string FROM teams WHERE name LIKE ?",(re.sub('[^A-Za-z0-9 %]+', '', f"%{search_string}%"),))
c.execute("SELECT team_json_string, counter FROM teams WHERE name LIKE ?",(re.sub('[^A-Za-z0-9 %]+', '', f"%{search_string}%"),))
team_json_strings = c.fetchall()
conn.close()
return team_json_strings

View file

@ -1,5 +1,6 @@
import json, random, os, math, jsonpickle, weather
import database as db
from league_storage import get_mods, get_team_mods
from gametext import base_string, appearance_outcomes, game_strings_base
data_dir = "data"
@ -79,6 +80,10 @@ class player(object):
stars = half_star + 0.5
self.stlats[key] = stars
def apply_mods(self, mod_dic):
for stat in iter(mod_dic.keys()):
self.stlats[stat] = self.stlats[stat] + mod_dic[stat]
class team(object):
def __init__(self):
@ -190,6 +195,14 @@ class team(object):
self.pitcher = None
return (len(self.lineup) >= 1 and len(self.rotation) > 0)
def apply_team_mods(self, league_name):
mod_dic = get_team_mods(league_name, self.name)
if mod_dic != {} and mod_dic != None:
for player_name in iter(mod_dic.keys()):
this_player = self.find_player(player_name)[0]
if this_player is not None:
this_player.apply_mods(mod_dic[player_name])
def prepare_for_save(self):
self.lineup_position = 0
self.score = 0

View file

@ -17,6 +17,14 @@ def create_connection(league_name):
# enable write-ahead log for performance and resilience
conn.execute('pragma journal_mode=wal')
modifications_table_check_string = """ CREATE TABLE IF NOT EXISTS mods (
counter integer PRIMARY KEY,
name text NOT NULL,
team_name text NOT NULL,
modifications_json text
);"""
conn.execute(modifications_table_check_string)
return conn
except:
print("oops, db connection no work")
@ -124,10 +132,18 @@ def init_league_db(league):
run_diff integer DEFAULT 0
); """
modifications_table_check_string = """ CREATE TABLE IF NOT EXISTS mods (
counter integer PRIMARY KEY,
name text NOT NULL,
team_name text NOT NULL,
modifications_json text
);"""
if conn is not None:
c = conn.cursor()
c.execute(player_stats_table_check_string)
c.execute(teams_table_check_string)
c.execute(modifications_table_check_string)
for team in league.teams_in_league():
c.execute("INSERT INTO teams (name) VALUES (?)", (team.name,))
@ -195,6 +211,63 @@ def get_stats(league_name, stat, is_batter=True, day = 10):
conn.close()
return stats
def get_mods(league_name, player:str, team:str):
"""returns a player's modifications dict"""
conn = create_connection(league_name)
if conn is not None:
c = conn.cursor()
c.execute("SELECT * FROM stats WHERE name=? AND team_name=?", (player, team)) #check stats table to make sure player actually exists in the league
row = c.fetchone()
if row is None:
return False
c.execute("SELECT modifications_json FROM mods WHERE name=? AND team_name=?", (player, team))
mod_string = c.fetchone()
if mod_string is None:
return None
mods = json.loads(mod_string[0])
conn.close()
return mods
return False
def get_team_mods(league_name, team:str):
"""returns a dictionary of player modifications belonging to a team"""
conn = create_connection(league_name)
if conn is not None:
c = conn.cursor()
c.execute("SELECT * FROM stats WHERE team_name=?", (team,)) #check stats table to make sure team actually exists in the league
row = c.fetchone()
if row is None:
return False
c.execute("SELECT name, modifications_json FROM mods WHERE team_name=?",(team,))
rows = c.fetchall()
if len(rows) == 0:
return None
mods_dic = {}
for row in rows:
mods_dic[row[0]] = json.loads(row[1])
return mods_dic
def set_mods(league_name, player:str, team:str, modifications:dict):
"""Overwrites a player's modifications with an entirely new set"""
conn = create_connection(league_name)
if conn is not None:
c = conn.cursor()
c.execute("SELECT * FROM stats WHERE name=? AND team_name=?", (player, team)) #check stats table to make sure player actually exists in the league
row = c.fetchone()
if row is None:
return False
mod_string = json.dumps(modifications)
c.execute("SELECT counter FROM mods WHERE name=? AND team_name=?", (player, team)) #check stats table to make sure player actually exists in the league
counter = c.fetchone()
if counter is None:
c.execute("INSERT INTO mods(name, team_name, modifications_json) VALUES (?,?,?)", (player, team, mod_string))
else:
c.execute("UPDATE mods SET modifications_json = ? WHERE counter=?", (mod_string, counter))
conn.commit()
conn.close
return True
return False
def update_standings(league_name, update_dic):
if league_exists(league_name):
conn = create_connection(league_name)

View file

@ -1,7 +1,7 @@
import discord, json, math, os, roman, games, asyncio, random, main_controller, threading, time, urllib, leagues, datetime, gametext, real_players
import database as db
import onomancer as ono
from league_storage import league_exists, season_save, season_restart
from league_storage import league_exists, season_save, season_restart, get_mods, get_team_mods, set_mods
from the_draft import Draft
from flask import Flask
from uuid import uuid4
@ -643,6 +643,7 @@ class DraftFlagsCommand(Command):
--wait or -w: Sets the timeout, in seconds, to wait for draftees to pick a player.
--chaos or -c: The percentage of onomancer names in the pool. Higher numbers mean less real names, but faster pool generation. Accepts any number between 0 and 1.
"""
await msg.channel.send(text)
class StartDraftCommand(Command):
name = "startdraft"
@ -896,6 +897,36 @@ Not every team will play every series, due to how the scheduling algorithm is co
else:
raise CommandError("Couldn't find that league, boss. Did you save it on the website?")
class LeagueSetPlayerModifiersCommand(Command):
name = "setplayermods"
template = "m;setplayermods [league name]\n[team name]\n[player name]\n4 numbers, seperated by a space, for batting pitching baserunning defense"
description = "Set a pack of modifiers to a specific player in your league. Commissioners only."
async def execute(self, msg, command, flags):
if league_exists(command.split("\n")[0].strip()):
try:
league = leagues.load_league_file(command.split("\n")[0].strip())
except IndexError:
raise CommandError("League name goes on the second line now, boss.")
else:
raise CommandError("Can't find that league, boss.")
try:
team_name = command.split("\n")[1].strip()
player_name = command.split("\n")[2].strip()
mods_text_list = command.split("\n")[3].strip().split(" ")
keys = ["batting_stars", "pitching_stars", "baserunning_stars", "defense_stars"]
mod_dic = {}
for i in range(0,4):
mod_dic[keys[i]] = float(mods_text_list[i])
set_mods(league.name, player_name, team_name, mod_dic)
await msg.channel.send("You got it, boss. Divine intervention, served by yours truly.")
except IndexError:
raise CommandError("You didn't give us enough info, chief. Check the help text.")
#except ValueError:
#raise CommandError("Those modifiers didn't make a lick of sense. Try again with sensible numbers this time.")
class LeagueSubscribeCommand(Command):
name = "leaguesub"
template = "m;leaguesub [league name]"
@ -1542,6 +1573,7 @@ commands = [
OBLResetCommand(),
LeagueClaimCommand(),
LeagueAddOwnersCommand(),
LeagueSetPlayerModifiersCommand(),
StartLeagueCommand(),
LeagueSubscribeCommand(),
LeaguePauseCommand(),
@ -1841,6 +1873,9 @@ def prepare_game(newgame, league = None, weather_name = None):
state_init["is_league"] = False
else:
state_init["is_league"] = True
newgame.teams['away'].apply_team_mods(league.name)
newgame.teams['home'].apply_team_mods(league.name)
return newgame, state_init
@ -2345,9 +2380,8 @@ async def start_league_day(channel, league, partial = False):
this_game = games.game(away.finalize(), home.finalize(), length = game_length)
this_game.weather = league.get_weather_now(home.name)(this_game)
this_game, state_init = prepare_game(this_game)
this_game, state_init = prepare_game(this_game, league=league)
state_init["is_league"] = True
if not partial:
series_string = "Series score:"
state_init["title"] = f"{series_string} 0 - 0"
@ -2562,9 +2596,8 @@ async def continue_league_series(league, queue, games_list, series_results, miss
home_team.set_pitcher(rotation_slot=league.day)
this_game = games.game(away_team.finalize(), home_team.finalize(), length = league.game_length)
this_game.weather = league.get_weather_now(home_team.name)(this_game)
this_game, state_init = prepare_game(this_game)
this_game, state_init = prepare_game(this_game, league=league)
state_init["is_league"] = True
series_string = f"Series score:"
if missed <= 0: