FixupAllPlayers
One of the common issues that can occur is that Loot/Items were misconfigured, or players were given items that they should not have. This can be fixed by running a fix-up script for all players.
This script is only meant to run at a relatively small scale (probably less than 5k players). The iteration batches are quite fast, however calling other APIs from it on a per-player basis will likely take a long time. It could be improved with multi-threading, but that is left as an exercise for the reader.
Prerequisites
In order to run the following python script, you’ll need to have the following:
- Your RallyHere environment URL
- A Client ID and secret for a client that has at least the
user:player:iterate
permission from its policy.- If you need to do other operations, you may need other permissions. Such as
inv:*
to do any operation on inventory
- If you need to do other operations, you may need other permissions. Such as
By default this script simply iterates all players and logs the number found. You can add your own logic to the process_batch
function to call other RallyHere Environment APIs. The RallyHereAccessToken
class will handle getting and refreshing the access token for you.
import requestsfrom datetime import datetime, timedeltafrom requests.auth import HTTPBasicAuth
rally_here_environment_url: str = "YOUR ENVIRONMENT URL HERE"rally_here_client_id: str = "YOUR CLIENT ID HERE"rally_here_client_secret: str = "YOUR CLIENT SECRET HERE"
def process_batch(players: list, sess: requests.Session, access_token, base_url: str): """ This function is responsible for processing a batch of players. You can add your own logic here. """ # for player in players: # print(f"Player: {player.get('player_uuid')} (player_id: {player.get('player_id')})")
class RallyHereAccessToken: """ This class is responsible for managing the access token for RallyHere. """ def __init__(self, sess: requests.Session, base_url: str, client_id: str, client_secret: str): """ :param sess: The requests session to use for all requests. :param base_url: The base URL of the RallyHere Environment API. :param client_id: The client ID for the RallyHere Environment API. :param client_secret: The client secret for the RallyHere Environment API. """ self.sess: requests.Session = sess self.base_url: str = base_url self.client_id: str = client_id self.client_secret: str = client_secret self.access_token: str = None self.access_token_type: str = None self.access_token_expiration: datetime = None
def get_authorization_header(self): """ This function is responsible for getting the authorization header for the RallyHere Environment API. :return: The authorization header. """ return f"{self.access_token_type} {self.get_token()}"
def get_token(self, force_refresh: bool = False): """ This function is responsible for getting the access token. It will refresh the token if it is expired or if force_refresh is True. :param force_refresh: If True, the token will be refreshed even if it is not expired. :return: The access token. """ if self.access_token is None or force_refresh or datetime.utcnow() > self.access_token_expiration: self.access_token, self.access_token_type, expiration_seconds = self.authenticate() self.access_token_expiration = datetime.utcnow() + timedelta(seconds=expiration_seconds - 60) return self.access_token
def authenticate(self): """ This function is responsible for authenticating to the RallyHere Environment API. :return: The access token, the access token type, and the expiration in seconds. """ response = self.sess.post(f"{self.base_url}/users/v1/login", auth=HTTPBasicAuth(self.client_id, self.client_secret), json={ "grant_type": "client_credentials", }) if response.status_code != 200: raise Exception(f"authenticate - Got status code {response.status_code} from auth request: {response.content}") result = response.json() return result["access_token"], result['token_type'], result["expires_in"]
def get_iteration_batch(sess: requests.Session, access_token: RallyHereAccessToken, base_url: str, cursor: str, page_size: int = 1000): """ This function is responsible for getting a batch of players from a RallyHere Environment API. :param sess: The requests session to use for all requests. :param access_token: The access token to use for the request. :param base_url: The base URL of the RallyHere Environment API. :param cursor: The cursor to use for the request. """ params = {"page_size": page_size} if cursor is not None: params["cursor"] = cursor response = sess.get(f"{base_url}/users/v2/player:iterate", params=params, headers={ "Authorization": access_token.get_authorization_header(), }) if response.status_code != 200: raise Exception(f"do_iteration - Got status code {response.status_code} from server") result = response.json() return result["players"], result["cursor"]
def iterate_all(base_url: str, client_id: str, client_secret: str): with requests.Session() as sess: access_token = RallyHereAccessToken(sess, base_url, client_id, client_secret) last_player_count: int = 1 cursor: str = None iteration_number: int = 0 while last_player_count > 0: players, cursor = get_iteration_batch(sess, access_token, base_url, cursor) process_batch(players, sess, access_token, base_url) last_player_count = len(players) print(f"Found {last_player_count} players in iteration {iteration_number}") iteration_number += 1
iterate_all(rally_here_environment_url, rally_here_client_id, rally_here_client_secret)