Further defined the Expansion class
This commit is contained in:
14
players.json
14
players.json
@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"expansions":
|
"expansions":
|
||||||
{
|
{
|
||||||
"ShockColar1": {"players": ["Brosef"], "types": ["shock"]},
|
"ShockColar1": {"players": ["Brosef"], "tags": ["shock"]},
|
||||||
"RobotBarman": {"players": ["Tango", "TRS_MML"], "types": ["drink"]},
|
"RobotBarman": {"players": ["Tango", "TRS_MML"], "tags": ["drink"]},
|
||||||
"ChallengeDB": {"players": ["TRS_MML"], "types": ["challenge"]},
|
"ChallengeDB": {"players": ["TRS_MML"], "tags": ["challenge"]},
|
||||||
"SourCandy": {"players": [], "types": ["food"]}
|
"SourCandy": {"players": [], "tags": ["food"]}
|
||||||
},
|
},
|
||||||
"players": {
|
"players": {
|
||||||
"Brosef": {"flags": [], "expansions": {"exampleExpansion": {"playerOption": 5}}, "games": {"gameID0": 2}},
|
"Brosef": {"flags": [], "expansions": {"exampleExpansion": {"playerOption": 5}}, "gamesSave": {"gameID0": 2}},
|
||||||
"TRS_MML": {"flags": [], "expansions": {"exampleExpansion": {"playerOption": 5}}, "games": {"gameID0": 1}},
|
"TRS_MML": {"flags": [], "expansions": {"exampleExpansion": {"playerOption": 5}}, "gamesSave": {"gameID0": 1}},
|
||||||
"Tango": {"flags": [], "expansions": {"exampleExpansion": {"playerOption": 5}}, "games": {"gameID0": 0}}
|
"Tango": {"flags": [], "expansions": {"exampleExpansion": {"playerOption": 5}}, "gamesSave": {"gameID0": 0}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,7 +1,20 @@
|
|||||||
class Expansion:
|
from player_settings import Expansion
|
||||||
def __init__(self, parent, globalConfig):
|
|
||||||
setattr(parent, self.__class__.ID, self)
|
|
||||||
|
|
||||||
class PlayerExpansion:
|
class serialShockers(Expansion):
|
||||||
def __init__(self, player, localConfig):
|
_api = None
|
||||||
|
|
||||||
|
def __init__(self, ID, expansionsManager):
|
||||||
|
super().__init__(ID, expansionsManager)
|
||||||
|
if serialShockers._api is None:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def step(self, action):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def close(self):
|
||||||
pass
|
pass
|
||||||
|
|||||||
@ -13,14 +13,21 @@ _log = logging.getLogger('NoPE-Lib')
|
|||||||
|
|
||||||
|
|
||||||
class Hook:
|
class Hook:
|
||||||
|
"""
|
||||||
|
A class that allows the creation of hooks.
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
connect: Connect a slot when the signal is launched.
|
||||||
|
"""
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._slot = []
|
self._slot = []
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
for fct in self._slot:
|
for fct in self._slot:
|
||||||
fct(*args, **kwargs)
|
fct(*args, **kwargs)
|
||||||
|
|
||||||
def connect(self, fct):
|
def connect(self, fct):
|
||||||
|
""" Connect a slot when the signal is launched. """
|
||||||
self._slot.append(fct)
|
self._slot.append(fct)
|
||||||
|
|
||||||
|
|
||||||
@ -43,15 +50,21 @@ class PlayersManager:
|
|||||||
"""
|
"""
|
||||||
defaultPlayerConfig = {"flags": [], "expansions": {}, "games": {}}
|
defaultPlayerConfig = {"flags": [], "expansions": {}, "games": {}}
|
||||||
|
|
||||||
def __init__(self, gameID: str=None, activePlayers: list[str]=None, playersPath: str='../players.json', loggerID: str='PlayersManager'):
|
def __init__(
|
||||||
|
self, gameID: str=None, activePlayers: list[str]=None,
|
||||||
|
playersPath: str='../players.json', loggerID: str='PlayersManager'
|
||||||
|
):
|
||||||
"""
|
"""
|
||||||
Initialises a list of players.
|
Initialises a list of players.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
gameID (str): The ID of the game used in the configuration file.
|
gameID (str): The ID of the game used in the configuration file.
|
||||||
activePlayers (list of str): The names of the players that are playing. Defaults to none which includes all players.
|
activePlayers (list of str): The names of the players that are playing.
|
||||||
playersPath (str, optional): The path of the players.json file. Defaults to '../players.json'.
|
Defaults to none which includes all players.
|
||||||
loggerID (str, optional): The ID used for logging. Defaults to 'Players'.
|
playersPath (str, optional): The path of the players.json file.
|
||||||
|
Defaults to '../players.json'.
|
||||||
|
loggerID (str, optional): The ID used for logging. Defaults to
|
||||||
|
'Players'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Store the arguments
|
# Store the arguments
|
||||||
@ -60,7 +73,7 @@ class PlayersManager:
|
|||||||
# Deal with the path
|
# Deal with the path
|
||||||
self._playersPath = Path(playersPath)
|
self._playersPath = Path(playersPath)
|
||||||
# Get the config file
|
# Get the config file
|
||||||
with open(self._playersPath, 'r') as f:
|
with open(self._playersPath, "r", encoding="utf-8") as f:
|
||||||
self._cfg = json.load(f)
|
self._cfg = json.load(f)
|
||||||
# Create the players
|
# Create the players
|
||||||
activePlayers = activePlayers if activePlayers is not None else self._cfg["players"].keys()
|
activePlayers = activePlayers if activePlayers is not None else self._cfg["players"].keys()
|
||||||
@ -72,7 +85,7 @@ class PlayersManager:
|
|||||||
# Create the signals
|
# Create the signals
|
||||||
self.onMadePlayerActive = Hook()
|
self.onMadePlayerActive = Hook()
|
||||||
self.onMadePlayerInactive = Hook()
|
self.onMadePlayerInactive = Hook()
|
||||||
|
|
||||||
def __getitem__(self, playerName: str):
|
def __getitem__(self, playerName: str):
|
||||||
"""
|
"""
|
||||||
Get a player object.
|
Get a player object.
|
||||||
@ -88,16 +101,12 @@ class PlayersManager:
|
|||||||
self._log.debug(f"Made {playerName} active")
|
self._log.debug(f"Made {playerName} active")
|
||||||
self.onMadePlayerActive(playerName)
|
self.onMadePlayerActive(playerName)
|
||||||
return self._player_data[playerName]
|
return self._player_data[playerName]
|
||||||
|
|
||||||
def __setitem__(self, playerName: str, config: dict, makeNewPlayerObject=False):
|
def __setitem__(self, playerName: str, config: dict):
|
||||||
"""
|
"""
|
||||||
Replace a player's config with another one.
|
Replace a player's config with another one.
|
||||||
|
|
||||||
Arguments:
|
|
||||||
playerName (str):
|
|
||||||
config (dict):
|
|
||||||
makeNewPlayerObject (bool):
|
|
||||||
"""
|
"""
|
||||||
|
makeNewPlayerObject = False
|
||||||
if makeNewPlayerObject:
|
if makeNewPlayerObject:
|
||||||
previousInstance = self._player_data[playerName]
|
previousInstance = self._player_data[playerName]
|
||||||
self._player_data[playerName] = Player(playerName, self, **config)
|
self._player_data[playerName] = Player(playerName, self, **config)
|
||||||
@ -109,49 +118,58 @@ class PlayersManager:
|
|||||||
del self._player_data[playerName]
|
del self._player_data[playerName]
|
||||||
self.onMadePlayerInactive(playerName)
|
self.onMadePlayerInactive(playerName)
|
||||||
self._log.debug(f"Removed {playerName} from active players")
|
self._log.debug(f"Removed {playerName} from active players")
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return len(self._player_data)
|
return len(self._player_data)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self._player_data.__iter__()
|
return self._player_data.__iter__()
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"Manager is playing {self.gameID} with {len(self._player_data)} active players"
|
return f"Manager is playing {self.gameID} with {len(self._player_data)} active players"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def config(self):
|
def config(self):
|
||||||
|
""" Deepcopy of the dictionnary of the config. """
|
||||||
return copy.deepcopy(self._cfg)
|
return copy.deepcopy(self._cfg)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gameID(self):
|
def gameID(self):
|
||||||
|
""" String of the current game ID. """
|
||||||
return self._currentGameID
|
return self._currentGameID
|
||||||
|
|
||||||
@gameID.setter
|
@gameID.setter
|
||||||
def gameID(self, gameID: str):
|
def gameID(self, gameID: str):
|
||||||
self._currentGameID = gameID
|
self._currentGameID = gameID
|
||||||
self._player_data = {name: Player(name, self, **cfg) for name, cfg in self._cfg["players"].items()}
|
self._player_data = {
|
||||||
|
name: Player(name, self, **cfg)
|
||||||
|
for name, cfg in self._cfg["players"].items()
|
||||||
|
}
|
||||||
|
|
||||||
@gameID.deleter
|
@gameID.deleter
|
||||||
def gameID(self):
|
def gameID(self):
|
||||||
self._currentGameID = None
|
self._currentGameID = None
|
||||||
self._player_data = {name: Player(name, self, **cfg) for name, cfg in self._cfg["players"].items()}
|
self._player_data = {
|
||||||
|
name: Player(name, self, **cfg)
|
||||||
|
for name, cfg in self._cfg["players"].items()
|
||||||
|
}
|
||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
""" Iterator of the active players' names """
|
""" Iterator of the active players' names """
|
||||||
return self._player_data.keys()
|
return self._player_data.keys()
|
||||||
|
|
||||||
def values(self):
|
def values(self):
|
||||||
""" Iterator of the active players' objects """
|
""" Iterator of the active players' objects """
|
||||||
return self._player_data.keys()
|
return self._player_data.keys()
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
""" Two iterators of the activate players' names and object """
|
""" Two iterators of the activate players' names and object """
|
||||||
return self._player_data.items()
|
return self._player_data.items()
|
||||||
|
|
||||||
def save(self):
|
def save(self):
|
||||||
with open(self._playersPath, 'w') as f:
|
""" Save the config to the disk. """
|
||||||
self._cfg = json.dump(f, self._cfg)
|
with open(self._playersPath, "w", encoding="utf-8") as f:
|
||||||
|
self._cfg = f.write(json.dump(f, self._cfg))
|
||||||
|
|
||||||
|
|
||||||
class Player:
|
class Player:
|
||||||
@ -165,58 +183,74 @@ class Player:
|
|||||||
gameState:
|
gameState:
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
generateConfig:
|
exportConfig:
|
||||||
punish:
|
punish:
|
||||||
"""
|
"""
|
||||||
def __init__(self, name: str, manager: PlayersManager, **cfg):
|
def __init__(self, playerName: str, manager: PlayersManager, **cfg):
|
||||||
self._name = name
|
self._name = playerName
|
||||||
self._manager = manager
|
self._manager = manager
|
||||||
|
self._gamesSave = {}
|
||||||
for key, val in cfg.items():
|
for key, val in cfg.items():
|
||||||
setattr(self, "_" + key, val)
|
setattr(self, "_" + key, val)
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"Player {self._name} has {len(self._flags)} flag(s), {len(self._expansions)} expansions and {len(self._games)} saved game"
|
txt = f"Player {self._name} has "
|
||||||
|
txt += f"{len(self.flags)} flags, "
|
||||||
|
txt += f"{len(self._expansions)} expansions and "
|
||||||
|
txt += f"{len(self._gamesSave)} saved game"
|
||||||
|
return txt
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
""" String representing the name of the player. """
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def flags(self):
|
def flags(self):
|
||||||
|
""" List of the flags associated with the player. """
|
||||||
return self._flags
|
return self._flags
|
||||||
|
|
||||||
@flags.setter
|
@flags.setter
|
||||||
def flags(self, newFlags):
|
def flags(self, newFlags):
|
||||||
self._flags = newFlags
|
self._flags = newFlags
|
||||||
# The container was changed and must be transmited to the manager
|
# The container was changed and must be transmited to the manager
|
||||||
self._manager[self._name] = self.generateConfig()
|
self._manager[self._name] = self.exportConfig()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def expansionsConfig(self):
|
def expansions(self):
|
||||||
return self._expansionsConfig
|
""" Dictionnary of the player's expansion settings. """
|
||||||
|
return self._expansions
|
||||||
@expansionsConfig.setter
|
|
||||||
|
@expansions.setter
|
||||||
def expansions(self, newExpansions):
|
def expansions(self, newExpansions):
|
||||||
self._expansionsConfig = newExpansions
|
self._expansions = newExpansions
|
||||||
# The container was changed and must be transmited to the manager
|
# The container was changed and must be transmited to the manager
|
||||||
self._manager[self._name] = self.generateConfig()
|
self._manager[self._name] = self.exportConfig()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gameSave(self):
|
def gameSave(self):
|
||||||
"""The save for the current game. If no configuration was found None is returned."""
|
"""
|
||||||
return self._games.get(self._manager.gameID)
|
The save for the current game. If no configuration was found None
|
||||||
|
is returned.
|
||||||
|
"""
|
||||||
|
return self._gamesSave.get(self._manager.gameID)
|
||||||
|
|
||||||
@gameSave.setter
|
@gameSave.setter
|
||||||
def gameSave(self, newGameSave):
|
def gameSave(self, newGameSave):
|
||||||
self._games[self._manager.gameID] = newGameSave
|
self._gamesSave[self._manager.gameID] = newGameSave
|
||||||
|
|
||||||
|
def exportConfig(self):
|
||||||
|
""" Export the exact player's configuration. """
|
||||||
|
return {
|
||||||
|
"flags": self._flags,
|
||||||
|
"expansions": self._expansions,
|
||||||
|
"games": self._gamesSave
|
||||||
|
}
|
||||||
|
|
||||||
def generateConfig(self):
|
|
||||||
return {"flags": self._flags, "expansions": self._expansions, "games": self._games}
|
|
||||||
|
|
||||||
def punish(self, value, preferedExpansion: str=None):
|
def punish(self, value, preferedExpansion: str=None):
|
||||||
do_something = lambda value: value
|
do_something = lambda value, preferedExpansion: value
|
||||||
additionalInfos = {
|
additionalInfos = {
|
||||||
"expansionClass": "challengeDB",
|
"expansionID": "challengeDB",
|
||||||
"balancedValue": 0.2,
|
"balancedValue": 0.2,
|
||||||
"showOnScreen": "Do 100 push-up",
|
"showOnScreen": "Do 100 push-up",
|
||||||
"error": None,
|
"error": None,
|
||||||
@ -224,59 +258,10 @@ class Player:
|
|||||||
}
|
}
|
||||||
# NOTE Make a result class instead and an error class
|
# NOTE Make a result class instead and an error class
|
||||||
# TODO Implement a way to choose between the available expansions
|
# TODO Implement a way to choose between the available expansions
|
||||||
additionalInfos = do_something(value)
|
additionalInfos = do_something(value, preferedExpansion)
|
||||||
return additionalInfos
|
return additionalInfos
|
||||||
|
|
||||||
|
|
||||||
class Expansion:
|
|
||||||
"""
|
|
||||||
|
|
||||||
Attributes:
|
|
||||||
specs:
|
|
||||||
|
|
||||||
Methods:
|
|
||||||
step:
|
|
||||||
reset:
|
|
||||||
close:
|
|
||||||
|
|
||||||
Signals:
|
|
||||||
onError:
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""
|
|
||||||
Intended behavior of the method:
|
|
||||||
Initialise the creation of an expansion
|
|
||||||
Should NEVER use any kind of argument.
|
|
||||||
Raise an error if not available.
|
|
||||||
"""
|
|
||||||
self.onError = Hook()
|
|
||||||
self._specs
|
|
||||||
pass
|
|
||||||
|
|
||||||
@property
|
|
||||||
def specs(self):
|
|
||||||
return self._specs
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def step(self, action):
|
|
||||||
"""
|
|
||||||
Call close if an error is thrown
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def reset(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def close(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def makeSpecs(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class ExpansionsManager:
|
class ExpansionsManager:
|
||||||
"""
|
"""
|
||||||
Manager of the availability of the expansions.
|
Manager of the availability of the expansions.
|
||||||
@ -286,75 +271,100 @@ class ExpansionsManager:
|
|||||||
Container of the expansions to try making available
|
Container of the expansions to try making available
|
||||||
activeExpansions: dict of Expansion
|
activeExpansions: dict of Expansion
|
||||||
Container of the relevent expansions
|
Container of the relevent expansions
|
||||||
|
|
||||||
TODO Add an interface to allow the modification of the expansion settings
|
|
||||||
"""
|
"""
|
||||||
defaultExpansionConfig = {"players": (), "types": ()}
|
defaultExpansionConfig = {"players": (), "types": ()}
|
||||||
keysConvert2Tuple = ("players", "types")
|
keysConvert2Tuple = ("players", "types")
|
||||||
tags = ["shock", "spice", "sour", "drink", "challenge"]
|
tags = ["shock", "spice", "sour", "drink", "challenge"]
|
||||||
|
# TODO Add an interface to allow the modification of the expansion settings
|
||||||
|
# (attributed players / types)
|
||||||
|
# TODO Allow to get a list of expansions with a specific tag/player
|
||||||
|
|
||||||
def __init__(self, playersManager: PlayersManager, includedExpansions: tuple[str]=None):
|
def __init__(self, playersManager: PlayersManager, includedExpansions: tuple[str]=None):
|
||||||
|
"""
|
||||||
|
Arguments:
|
||||||
|
tryInclude: bool=False, tryActivate: bool=False
|
||||||
|
"""
|
||||||
# Create the attributes
|
# Create the attributes
|
||||||
self.playersManager = playersManager
|
self.playersManager = playersManager
|
||||||
self._cfg = playersManager.config["expansions"]
|
self._cfg = playersManager.config["expansions"]
|
||||||
self._includedExpansions = tuple(includedExpansions) if includedExpansions is not None else ()
|
if includedExpansions is not None:
|
||||||
|
self._includedExpansions = tuple(includedExpansions)
|
||||||
|
else:
|
||||||
|
self._includedExpansions = ()
|
||||||
# Convert the required lists into tuples
|
# Convert the required lists into tuples
|
||||||
for expansionID in self._cfg["expansions"]:
|
for expansionID in self._cfg["expansions"]:
|
||||||
for key in self.keysConvert2Tuple:
|
for key in self.keysConvert2Tuple:
|
||||||
self._cfg["expansions"][expansionID][key] = tuple(self._cfg["expansions"][expansionID][key])
|
converted = tuple(self._cfg["expansions"][expansionID][key])
|
||||||
|
self._cfg["expansions"][expansionID][key] = converted
|
||||||
# Compute the active expansions
|
# Compute the active expansions
|
||||||
self._activeExpansions = {}
|
self._activeExpansions = {}
|
||||||
for expansionID in self._listPossiblyValidExpansions():
|
for expansionID in self._listPossiblyValidExpansions():
|
||||||
self._createExpansion(expansionID)
|
self._createExpansion(expansionID)
|
||||||
|
|
||||||
# Connect the signals to the slots
|
# Connect the signals to the slots
|
||||||
playersManager.onMadePlayerActive.connect(self._activePlayerAdded)
|
playersManager.onMadePlayerActive.connect(self._activePlayerAdded)
|
||||||
playersManager.onMadePlayerInactive.connect(self._activePlayerRemoved)
|
playersManager.onMadePlayerInactive.connect(self._activePlayerRemoved)
|
||||||
|
|
||||||
|
def __getitem__(self, expansionID: str):
|
||||||
|
return self._activeExpansions[expansionID]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._activeExpansions)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self._activeExpansions.__iter__()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"ExpansionsManager has {len(self._activeExpansions)} active expansions"
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def includedExpansions(self):
|
def includedExpansions(self):
|
||||||
|
""" Dictionnary of the included expansions. """
|
||||||
return self._includedExpansions
|
return self._includedExpansions
|
||||||
|
|
||||||
@includedExpansions.setter
|
@includedExpansions.setter
|
||||||
def includedExpansions(self, newIncluded: tuple[str]):
|
def includedExpansions(self, newIncluded: tuple[str]):
|
||||||
self._includedExpansions = tuple(newIncluded)
|
self._includedExpansions = tuple(newIncluded)
|
||||||
self._includeChanged()
|
self._includeChanged()
|
||||||
|
|
||||||
@includedExpansions.deleter
|
@includedExpansions.deleter
|
||||||
def includedExpansions(self):
|
def includedExpansions(self):
|
||||||
self._includedExpansions = ()
|
self._includedExpansions = ()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def activeExpansions(self):
|
def config(self):
|
||||||
return self._activeExpansions
|
""" Dictionnary of the expansions' settings. """
|
||||||
|
return self._cfg
|
||||||
|
|
||||||
def _getPlayersFillMissing(self, expansionID):
|
def _getPlayersFillMissing(self, expansionID):
|
||||||
return set(self._cfg["expansions"].get(expansionID, {}).get("players", []))
|
return set(self._cfg["expansions"].get(expansionID, {}).get("players", []))
|
||||||
|
|
||||||
def _listPossiblyValidExpansions(self):
|
def _listPossiblyValidExpansions(self):
|
||||||
"""
|
"""
|
||||||
List expansions that are included, defined in PDOLib and are available to at least one active player.
|
List expansions that are included, defined in PDOLib and are available
|
||||||
|
to at least one active player.
|
||||||
"""
|
"""
|
||||||
activePlayers = set(self.playersManager.keys())
|
activePlayers = set(self.playersManager.keys())
|
||||||
possiblyValidExpansions = [
|
possiblyValidExpansions = [
|
||||||
expansion for expansion in self._includedExpansions
|
expansion for expansion in self._includedExpansions
|
||||||
if hasattr(PDOLib, expansion) and not self._getPlayersFillMissing(expansion).isdisjoint(activePlayers)
|
if hasattr(PDOLib, expansion) and
|
||||||
|
not self._getPlayersFillMissing(expansion).isdisjoint(activePlayers)
|
||||||
]
|
]
|
||||||
return possiblyValidExpansions
|
return possiblyValidExpansions
|
||||||
|
|
||||||
def _createExpansion(self, expansionID):
|
def _createExpansion(self, expansionID):
|
||||||
try:
|
try:
|
||||||
expansion = getattr(PDOLib, expansionID)()
|
expansion = getattr(PDOLib, expansionID)(expansionID, self)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
self._activeExpansions[expansionID] = expansion
|
self._activeExpansions[expansionID] = expansion
|
||||||
|
|
||||||
def _removeExpansion(self, expansionID):
|
def _removeExpansion(self, expansionID):
|
||||||
expansion = self._activeExpansions.pop(expansionID)
|
expansion = self._activeExpansions.pop(expansionID)
|
||||||
expansion.close()
|
expansion.close()
|
||||||
del expansion
|
del expansion
|
||||||
|
|
||||||
def _includeChanged(self):
|
def _includeChanged(self):
|
||||||
"""
|
"""
|
||||||
Update the list of active Expansions
|
Update the list of active Expansions
|
||||||
@ -374,10 +384,11 @@ class ExpansionsManager:
|
|||||||
|
|
||||||
def _activePlayerAdded(self, playerName):
|
def _activePlayerAdded(self, playerName):
|
||||||
# Find the expansions that are to be created
|
# Find the expansions that are to be created
|
||||||
possibleAddition = set(self._includedExpansions).difference(self.activeExpansions)
|
possibleAddition = set(self._includedExpansions).difference(self._activeExpansions)
|
||||||
filteredAddition = [
|
filteredAddition = [
|
||||||
expansionID for expansionID in possibleAddition
|
expansionID for expansionID in possibleAddition
|
||||||
if hasattr(PDOLib, expansionID) and playerName in self._getPlayersFillMissing(expansionID)
|
if hasattr(PDOLib, expansionID) and
|
||||||
|
playerName in self._getPlayersFillMissing(expansionID)
|
||||||
]
|
]
|
||||||
# Create the expansions
|
# Create the expansions
|
||||||
for expansionID in filteredAddition:
|
for expansionID in filteredAddition:
|
||||||
@ -386,7 +397,7 @@ class ExpansionsManager:
|
|||||||
def _activePlayerRemoved(self, playerName):
|
def _activePlayerRemoved(self, playerName):
|
||||||
# Find the expansions that are to be removed
|
# Find the expansions that are to be removed
|
||||||
filteredRemoval = [
|
filteredRemoval = [
|
||||||
expansionID for expansionID in self.activeExpansions
|
expansionID for expansionID in self._activeExpansions
|
||||||
if playerName in self._cfg["players"] and len(self._cfg["players"]) == 1
|
if playerName in self._cfg["players"] and len(self._cfg["players"]) == 1
|
||||||
]
|
]
|
||||||
# Close the expansions
|
# Close the expansions
|
||||||
@ -396,7 +407,7 @@ class ExpansionsManager:
|
|||||||
def _errorOccured(self, expansionID):
|
def _errorOccured(self, expansionID):
|
||||||
self._removeExpansion(expansionID)
|
self._removeExpansion(expansionID)
|
||||||
|
|
||||||
def _expansionPlayersChanged(self, expansionID):
|
def expansionPlayersChanged(self, expansionID):
|
||||||
expansionIsActive = expansionID in self._activeExpansions
|
expansionIsActive = expansionID in self._activeExpansions
|
||||||
activePlayers = set(self.playersManager.keys())
|
activePlayers = set(self.playersManager.keys())
|
||||||
expansionHasNoPlayers = self._getPlayersFillMissing(expansionID).isdisjoint(activePlayers)
|
expansionHasNoPlayers = self._getPlayersFillMissing(expansionID).isdisjoint(activePlayers)
|
||||||
@ -405,32 +416,109 @@ class ExpansionsManager:
|
|||||||
self._removeExpansion(expansionID)
|
self._removeExpansion(expansionID)
|
||||||
elif (not expansionIsActive) and (not expansionHasNoPlayers) and expansionDefined:
|
elif (not expansionIsActive) and (not expansionHasNoPlayers) and expansionDefined:
|
||||||
self._createExpansion(expansionID)
|
self._createExpansion(expansionID)
|
||||||
|
|
||||||
def initilizeExpansion(self, expansionID: str, suppressError: bool=False):
|
def initilizeExpansion(self, expansionID: str, suppressError: bool=False):
|
||||||
"""
|
"""
|
||||||
Initilise the expansion.
|
Initilise (possibly again) the expansion.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
expansionID (str):
|
||||||
|
suppressError (bool):
|
||||||
"""
|
"""
|
||||||
if expansionID in self._activeExpansions:
|
if expansionID in self._activeExpansions:
|
||||||
self._removeExpansion(expansionID)
|
self._removeExpansion(expansionID)
|
||||||
|
# Make sure that the expansion is relevent
|
||||||
if not suppressError:
|
if not suppressError:
|
||||||
# Make sure that the expansion is relevent
|
|
||||||
# Verify that creating the expansion was successful
|
# Verify that creating the expansion was successful
|
||||||
pass
|
pass
|
||||||
# Try creating a new instance of the expansion
|
# Try creating a new instance of the expansion
|
||||||
# Update the list of relevent expansions
|
# Update the list of relevent expansions
|
||||||
pass
|
# TODO Implement the rest
|
||||||
|
|
||||||
|
|
||||||
|
class Expansion:
|
||||||
|
"""
|
||||||
|
A meta class implementation meant to describe how to interact with any kind
|
||||||
|
of expansions.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
players (tuple of str):
|
||||||
|
tags (tuple of flag):
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
step:
|
||||||
|
reset:
|
||||||
|
close:
|
||||||
|
|
||||||
|
Signals:
|
||||||
|
onError:
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, ID: str, expansionsManager: ExpansionsManager):
|
||||||
|
"""
|
||||||
|
Initialise the creation of an expansion and raise an error if not
|
||||||
|
available.
|
||||||
|
"""
|
||||||
|
self._ID = ID
|
||||||
|
self._manager = expansionsManager
|
||||||
|
self.onError = Hook()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def players(self):
|
||||||
|
""" Players that have access to this expansion. """
|
||||||
|
return self._manager.config[self._ID]["players"]
|
||||||
|
|
||||||
|
@players.setter
|
||||||
|
def players(self, newPlayers):
|
||||||
|
""" Players that have access to this expansion. """
|
||||||
|
self._manager.config[self._ID]["players"] = tuple(newPlayers)
|
||||||
|
self._manager.expansionPlayersChanged(self._ID)
|
||||||
|
|
||||||
|
@players.deleter
|
||||||
|
def players(self):
|
||||||
|
self._manager.config[self._ID]["players"] = ()
|
||||||
|
self._manager.expansionPlayersChanged(self._ID)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def tags(self):
|
||||||
|
""" Players that have access to this expansion. """
|
||||||
|
return self._manager.config[self._ID]["tags"]
|
||||||
|
|
||||||
|
@tags.setter
|
||||||
|
def tags(self, newPlayers):
|
||||||
|
""" Players that have access to this expansion. """
|
||||||
|
self._manager.config[self._ID]["tags"] = tuple(newPlayers)
|
||||||
|
|
||||||
|
@tags.deleter
|
||||||
|
def tags(self):
|
||||||
|
self._manager.config[self._ID]["tags"] = ()
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def step(self, action):
|
||||||
|
"""
|
||||||
|
Call close if an error is thrown
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def reset(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def close(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Test run to make sure nothing is flagrantly flawed
|
# Test run to make sure nothing is flagrantly flawed
|
||||||
configPath = Path(__file__).parent / "players.json"
|
configPath = Path(__file__).parent / "players.json"
|
||||||
manager = PlayersManager(playersPath=configPath, gameID="gameID0")
|
pm = PlayersManager(playersPath=configPath, gameID="gameID0")
|
||||||
# Iteration
|
# Iteration
|
||||||
for playerName in manager:
|
for name in pm:
|
||||||
print(playerName)
|
print(name)
|
||||||
# Modification of a players data
|
# Modification of a players data
|
||||||
brosef = manager["Brosef"]
|
brosef = pm["Brosef"]
|
||||||
brosef.gameSave = [1]
|
brosef.gameSave = [1]
|
||||||
print(manager["Brosef"].gameSave)
|
print(pm["Brosef"].gameSave)
|
||||||
brosef.state = ["alive"]
|
brosef.state = ["alive"]
|
||||||
# TODO Verify that changing the gameID works as intended
|
# TODO Verify that changing the gameID works as intended
|
||||||
|
|||||||
Reference in New Issue
Block a user