Overview
Tournaments extend leaderboard functionality by providing a dynamic configuration layer on top of all the leaderboard features. Tournaments are leaderboards which have start and end timestamps when “active”.
All leaderboards have instance ids, the highest one is the active_leaderboard_instance_id (instance ids will come in handy in the future when reviewing user score recent history). At tournament end, an empty leaderboard is set to an incremented active_leaderboard_instance_id.
All leaderboard and tournament information is stored in redis. There are redis keys for the leaderboard primary key, timestamp, userid/score mappings, tournament configs, a list of leaderboards used for account merges, group/tier primary key, set of group members, and each user also has a redis key for the leaderboards they are in which is used during account merging.
There are also some custom squash server endpoints related to tournaments. They appear to only be used for storing some custom tournament data to extend the v5 tournaments for scattergories. They are very simple endpoints that just set or get the data from the cusom redis.
Redis Keys
The following list describes what each piece of the redis keys correspond to:
ldrs5- leaderboardsdynmc- leaderboard type - currently everything is hardcoded to usedynmc.pri- primary key fieldts- timestamp fieldlist- list fieldcfg- config fieldg- group field{apiKey}- the game’s apiKey, used to scope a leaderboard to a game{subgameID}- the name of the subgame, for tournaments this is the tournament id{leaderboardID}- the name of the leaderboard (tournaments are assumed to use ‘scores’){leaderboardInstanceID}- the id of an instance of the leaderboard, the leaderboards current active instance i is stored in the primary key field{tier}- something to do with tournament groups, not really sure, ‘default’ is always used right now{groupID}- the id for a group in a tournament, starts at 0 and when a group is full and a new group is created the id is incremented
ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:pri
type: string
This is the primary key for a leaderboard. Keeps track of the id of the current instance of the leaderboard identified by the apiKey, subgameID, and leaderboardID.
The first instance of a leaderboard is created with the value “1”.
Leaderboards can have intervals. If you try to get the active leaderboard details and the interval has passed it will create a new instance of the leaderboard by incrementing the primary key.
ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:{leaderboardInstanceID}:ts
type: string
This is the current Unix timestamp set when a new active leaderboard is set.
ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:{leaderboardInstanceID}:list
type: sorted set
This is the actual leaderboard data that stores the users and their score.
The elements are the userIDs and the score used for sorting is the user’s score.
ldrs5:dynmc:{apiKey}:cfg
type: hash
This is game-scoped tournament configs (will apply to any leaderboardID for the tournament)
Keys in the hash are subgameIDs and the values are stringified JSON config objects.
ldrs5:dynmc:{apiKey}:list
type: set
The values are partial redis keys {subgameID}:{leaderboardID}:{leaderboardInstanceID}.
These are added to the set when active leaderboard details are retrieved. This is used when merging user accounts to look up scores for the user in all leaderboards associated with the game. Any expired leaderboards are removed from this set when doing an account merge.
ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:g:{tier}:pri
type: string
The primary key field for a group. This is the groupID of the latest group in the tournament. When the latest group is at capacity and a new user joins a new group is created and this value is updated with the id of the new group.
From what I can tell tier is always ‘default’ but is there for future use.
ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:g:{tier}:{groupID}
type: set
Values are user ids of the users in the group.
This is used when adding users to the tournament just to add them to a group and also when getting scores for a tournament or a particular user’s group.
usrs5:{userID}:ldrs5:dynmc:{apiKey}
type: set
Values are the redis keys for the tournament groups the user is in. This is used during account merge.
It is also used to see if the user is already registered when joining a tournament and in the endpoint to get all tournaments and scores for a user.
Tournament Configs
A tournament is essentially a leaderboard with a configuration object that defines the following properties:
start_time- The start time of the tournament. Defaults to 0.end_time- The end time of the tournament. Defaults to 0.score_carryover_factor- Factor used when carrying scores to the next leaderboard after the interval has been reached. Defaults to 0.score_carryover_constant- Constant used when carrying scores to the next leaderboard after the interval has been reached. Defaults to 0.interval- Interval at which leaderboards expire. Defaults to 0.archives- Number of previous instances of the tournament leaderboard to keep. Defaults to 0.group_size- The number of users that will be in each group in the tournament. Defaults to 0.Note: default value is 0 and according to a comment there that means unlimited, but the
/admin/tournaments/:tournament_idendpoint will not allow you to save a tournament config with group size of 0, also that’s not how the code works when adding a user to a group if it’s 0 it would create a new group for every usertournament_type- A string defining the type of tournament, this doesn’t appear to be used by v5. Defaults to null.
The following properties can be added to the configuration object in certain circumstances:
system_default- A boolean added to the config if we are returning the system defaults.tournament_id- The id of the tournament which is added to the config object when calling the function that returns all the configurations for the api key.
Tournament Creation
The page in hope to create a new tournament allows you to enter the tournament_id, tournament_type, start_time, end_time, and group_size. archives is always set to 1, score_carryover_factor is always set to 1, score_carryover_constant is always set to 0, and interval is never sent. It appears the interval/carryover features are not currently used, since interval is never explicitly set it uses (endTime - startTime). Creating the tournament sets the tournament config using the v5 endpoint /leaders/admin/tournaments/{tournament_id} and sends custom tournament data to the custom squash endpoint /custom/{apiKey}/createTournament.
Tournament Groups
When a user joins a tournament they are added to the next available group. Group size is set in the tournament config.
When a new group is needed it will move half the players from the previous group so the new group will not have only one user. So when adding a user to a tournament it will check if there is room in latestGroup-1 and fill that up before filling up latestGroup.
example:
group size = 6
group 1 contains users 1-6
1: {1, 2, 3, 4, 5, 6}
The following shows the groups after each user from 7-13 joins the tournament:
1: {1, 3, 5}
2: {2, 4, 6, 7}
1: {1, 3, 5, 8}
2: {2, 4, 6, 7}
1: {1, 3, 5, 8, 9}
2: {2, 4, 6, 7}
1: {1, 3, 5, 8, 9, 10}
2: {2, 4, 6, 7}
1: {1, 3, 5, 8, 9, 10}
2: {2, 4, 6, 7, 11}
1: {1, 3, 5, 8, 9, 10}
2: {2, 4, 6, 7, 11, 12}
1: {1, 3, 5, 8, 9, 10}
2: {2, 6, 11}
3: {4, 7, 12, 13}
…
Tournament Carryover
When creating a new active leaderboard for a tournament and the leaderboard interval has elapsed then scores from the previous instance will be carried over. The carryover factor and constant are used with “WEIGHTS” for the redis ZUNIONSTORE command.
V5
Redis functions
setLeaderboardConfiguration(config, apiKey, subgameID, callback)
Sets the leaderboard configuration in redis using the ldrs5:dynmc:{apiKey}:cfg redis key.
Parameters :
config- The config object that is stored as the value in the redis hash (stringified).apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used as the hash key.callback- The callback called with the result of the redissetHashValuecall or an error.callback(error, result)
getLeaderboardConfiguration(apiKey, subgameID, callback)
Gets the leaderboard configuration either from the v5 manifest or the ldrs5:dynmc:{apiKey}:cfg redis key.
If there is a config for the given {apiKey}/{subgameID} in the v5 manifest under configuration/leaderboards/{apiKey}/{subgameID} that will be returned, otherwise the redis hash ldrs5:dynmc:{apiKey}:cfg is used with {subgameID} as the hash key. If nothing for that key is found the system default config will be returned. See the Tournament Configs section for default values.
Parameters :
apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used as the hash key.callback- The callback called with the retrieved configuration or an error.callback(error, config)
getGameLeaderboardConfigurations(apiKey, callback)
Gets an array of all the leaderboard configurations for the game from the ldrs5:dynmc:{apiKey}:cfg redis key.
If any of the tournaments have expired the configs will be removed from redis and they will be omitted from the result.
The tournament id is added to the config objects returned. The result array is sorted by start time.
Parameters :
apiKey- The game’s api key used to create the redis key.callback- The callback called with an array of config objects or an error.callback(error, configs)
getUsersGroups(userID, apiKey, callback)
Gets an array of redis keys for the tournament groups the user is in.
Uses the redis key usrs5:{userID}:ldrs5:dynmc:{apiKey} to get the list of group redis keys. These keys are in the form of ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:g:{tier}:{groupID}.
The tournament configs will be checked for the resulting tournaments to check for expired tournaments. If any are expired they will be removed from the result and deleted from the usrs5:{userID}:ldrs5:dynmc:{apiKey} redis key.
Parameters :
userID- The user id used to create the redis key.apiKey- The game’s api key used to create the redis key.callback- The callback called with the results or an error.callback(error, userTournamentGroupsKeys);
getUserValuesLeaderboardKeys(userID, leaderboardKeys, callback)
Gets an array of scores for the user in the given leaderboards.
Parameters :
userID- The user id of the user to get scores for.leaderboardKeys- An array of redis keys identifying which leaderboards to retrieve scores for. The keys are in the form ofldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:{leaderboardInstanceID}:list.callback- The callback called with the results or an error.callback(error, responses)
getTournamentLeaderboardGroups(apiKey, subgameID, leaderboardID, tier, callback)
Gets an array of all the group ids for a given leaderboard and tier. Uses the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:g:{tier}:pri redis key to get the last group id and constructs an array of integers [0-primaryKey].
Parameters :
apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used to create the redis key.leaderboardID- The leaderboard id used to create the redis key.tier- The tier used to create the redis key.callback- The callback called with the results or an error.callback(error, groupIDs)
assignLeaderboardGroup(userID, apiKey, subgameID, leaderboardID, tier, config, callback)
Gets the redis key for the next available group for a dynamic tournament and adds the user to this group.
Retrieves the latest group id from the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:g:{tier}:pri redis key. Using that checks if either of the last two groups has room for another user by checking the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:g:{tier}:{groupID} to see how many users are in the group. If either of those have room the user will be added to it, otherwise the last group will be split. See the Tournament Groups section for an example of how the group is split.
The user is then added to the group that was found by adding the group key to the usrs5:{userID}:ldrs5:dynmc:{apiKey} redis key and adding the user id to the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:g:{tier}:{groupID} redis key.
Parameters :
userID- The user id for the user to add to the group.apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used to create the redis key.leaderboardID- The leaderboard id used to create the redis key.tier- The tier used to create the redis key.config- The config used to determine the group size and to determine if the redis group keys should expire.callbackThe callback called with the result or an error.callback(error, leaderboardGroupKey)
setScoreForLeaderboardInstance(score, userID, apiKey, subgameID, leaderboardID, active_leaderboardInstanceID, callback)
Adds a user’s score to the leaderboard using the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:{leaderboardInstanceID}:list redis key.
Parameters :
score- The user’s score.userID- The user’s user id.apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used to create the redis key.leaderboardID- The leaderboard id used to create the redis key.active_leaderboardInstanceID- The leaderboard instance id used to create the redis key.callback- The callback called with the score or an error.callback(error, score)
changeScoreForLeaderboardInstance(scoreChange, userID, apiKey, subgameID, leaderboardID, active_leaderboardInstanceID, callback)
Increments the user’s score in the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:{leaderboardInstanceID}:list redis key by scoreChange.
Parameters :
scoreChange- The amount to add to the user’s score.userID- The user’s user id.apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used to create the redis key.leaderboardID- The leaderboard id used to create the redis key.active_leaderboardInstanceID- The leaderboard instance id used to create the redis key.callback- The callback called with the score or an error.callback(error, response)
changeScoresForLeaderboardInstance(userScores, apiKey, subgameID, leaderboardID, active_leaderboardInstanceID, callback)
Same as the changeScoreForLeaderboardInstance function but takes an array of score objects {userID: id, score: score}.
Parameters :
userScores- The array of score objects to change.apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used to create the redis key.leaderboardID- The leaderboard id used to create the redis key.active_leaderboardInstanceID- The leaderboard instance id used to create the redis key.callback- The callback called with the score or an error.callback(error, response)
getValuesForUserIDsAndLeaderboardInstance(userIDs, apiKey, subgameID, leaderboardID, leaderboardInstanceID, callback)
Gets an array of scores (of the form ["userID", "score", "userID", "score", ...]) for the given users from the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:{leaderboardInstanceID}:list redis key in reverse order (highest first). Uses some temporary redis keys that expire in 10 seconds and does a redis set intersecting operation.
Parameters :
userIDs- An array of user ids.apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used to create the redis key.leaderboardID- The leaderboard id used to create the redis key.leaderboardInstanceID- The leaderboard instance id used to create the redis key.callback- The callback called with the results or an error.callback(error, results)
getActiveLeaderboardDetails(apiKey, subgameID, leaderboardID, callback)
Gets details (primary key, leaderboard timestamp, leaderboard interval end time, current timestamp) for a tournament.
Creates the current timestamp, gets the leaderboard config using the getLeaderboardConfiguration function, gets the primary key from the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:pri redis key, initiates the first instance of the leaderboard if needed, ensures the tournament is active using the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:{leaderboardInstanceID}:ts redis key, checks if the tournament has ended, and returns the results.
A leaderboard is still active if:
- timestamp < end_timestamp (and end_timestamp is not 0)
- timestamp + interval is greater than “now” (all times in seconds)
For checking if a tournament has ended:
- if
leaderboardEndtime === 0the tournament never ends - if
currentTimestamp >= leaderboardEndtimethe tournament is archived/expired - if
currentTimestamp >= leaderboardTournamentIntervalEndTimestampthe tournament should roll over- update to a new leaderboard with new timestamp values
- adds 1 to the primary key
- calls
setNewActiveLeaderboard
- otherwise the leaderboard is active
Parameters :
apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used to create the redis key.leaderboardID- The leaderboard id used to create the redis key.callback- The callback called with the results or an error.- if the tournament hasn’t started yet
callback(null, null, leaderboardStarttime, leaderboardEndtime, currentTimestamp) - otherwise
callback(error, leaderboardPrimaryKey, leaderboardTimestamp, leaderboardTournamentIntervalEndTimestamp, currentTimestamp)
- if the tournament hasn’t started yet
getLeaderboardGroupMembers(apiKey, subgameID, leaderboardID, tier, groupID, callback)
Gets the set of users for a leaderboard group using the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:g:{tier}:{groupID} redis key.
Parameters :
apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used to create the redis key.leaderboardID- The leaderboard id used to create the redis key.tier- The tier used to create the redis key.groupID- the group id used to create the redis key.callback- The callback called with the results or an error.callback(error, response)
setNewActiveLeaderboard(leaderboardPrimaryKeyValue, apiKey, subgameID, leaderboardID, leaderboardTimeToLive, leaderboardScoresCarryoverConstant, leaderboardScoresCarryoverFactor, callback)
Internal function used to set the primary key to the active leaderboard for a tournament.
Sets the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:{leaderboardInstanceID}:pri redis key to be the passed in leaderboardPrimaryKeyValue.
Sets the ldrs5:dynmc:{apiKey}:{subgameID}:{leaderboardID}:{leaderboardInstanceID}:ts to be the current timestamp.
Initiates the sorted set for the new leaderboard. If there is a score carryover factor and the primary key is not 1 then the scores need to be carried over to the new leaderboard, this is done by using a redis union command on the new leaderboard and the previous one with the carryover constant and factor as weights.
Sets the expiry time for the timestamp and score list redis keys using the passed in time to live. This is only done if score carryover factor and constant are both 0 because if there is a score carryover factor or constant, then the next instance of the scoreboard requires the previous scores so they can’t expire.
Parameters :
leaderboardPrimaryKeyValue- The primary key of the leaderboard. (The instance id of the active leaderboard instance)apiKey- The game’s api key used to create the redis key.subgameID- The subgame id or tournament id used to create the redis key.leaderboardID- The leaderboard id used to create the redis key.leaderboardTimeToLive- The amount of time to use for the expiry of the redis keys if they can expire (there is no carryover factor or constant).leaderboardScoresCarryoverConstant- The score carryover constant.leaderboardScoresCarryoverFactor- The score carryover factor.callback- The callback called with the primary key value or an error.callback(error, leaderboardPrimaryKeyValue)
Endpoints
Set tournament config
Sets the tournament config for a given tournament id.
Adds the passed in leaderboard config to the redis hash ldrs5:dynmc:{apiKey}:cfg using {tournament_id} as the hash key.
URL : /leaders/admin/tournaments/:tournament_id
Method : POST
Data :
- url params
tournament_id- corresponds tosubgame_id
- headers
mcs-key
- body
tournament_type- required - a string such as ‘mega’ or ‘sudoku’start_time- required - a unix timestamp when the tournament should startend_time- optional ifintervalprovided - the moment the tournament becomes unavailable for posting scoresinterval- optional ifend_timeprovided - duration of a tournament before resetting or decaying all the scoresarchives- required - number of archived versions (previous weeks for example) of the current active leaderboard for this tournamentscore_carryover_factor- required - the decay factor for carrying over scores, 0 resets scoresscore_carryover_constant- required - constant value to decay scores bygroup_size- required - can’t be 0 - the maximum number of players in a leaderboard group
Success Response
{
"success": true,
"tournament_id": tournament_id /* string */,
"config": config /* object */
}
Error Responses
40002 invalid input- “invalid tournament_id (corresponds to an admin service’s tournament id)” - if
tournament_idis falsy - “invalid tournament_type (examples ‘mega’,’sudoku’, etc)” - if
tournament_typeis falsy - “invalid start_time (initial start time for tournament)” - if
start_timeis null or undefined - “invalid tournament duration options, must specify at least end_time or interval, or both end_time and interval (tournament resets at interval until finished at end_time)” - if both
end_timeandintervalare falsy - “invalid number of archives (0 or greater integer)” - if
archivesis null or undefined - “invalid score_carryover_factor (0 to reset scores, signed integer to increase or decrease)” - if
score_carryover_factoris null or undefined - “invalid score_carryover_constant (0 to make no change, signed integer to add or subtrack (decay))” - if
score_carryover_constantis null or undefined - “invalid group_size” - if
group_sizeis falsy
- “invalid tournament_id (corresponds to an admin service’s tournament id)” - if
50003 database error- if there is an error setting leaderboard configuration in redis
Get tournament config
Gets the tournament config for a particular tournament by id.
Uses the getLeaderboardConfiguration function to retrieve the configuration, see the documentation of that method for notes on where it gets the configuration from.
URL : /leaders/tournaments/:tournament_id
Method : GET
Data :
- url params
tournament_id- corresponds tosubgame_id
- headers
mcs-key
Success Response
{
"success": true,
"tournament_id": tournament_id /* string */,
"config": config /* object */
}
Error Responses
50003 database error- if there is an error getting leaderboard configuration from redis
Get all tournament configs for a game id
Gets all the current and upcoming tournaments for the given api key.
A side effect of calling this endpoint is any configs for tournaments that are expired will be removed from the ldrs5:dynmc:{apiKey}:cfg redis hash.
The response includes an array of tournament configs sorted by start time.
Note: Unlike the endpoint to get a config for a specific tournament id this endpoint doesn’t check the v5 manifest, it only grabs configs from redis.
URL : /leaders/tournaments
Method : GET
Data :
- headers
mcs-key
Success Response
{
"tournaments": configs /* array of config objects (config object includes the tournament_id) */
}
Error Responses
50003 database error- if there is an error getting leaderboard configuration from redis
Join a tournament
Validates the given user_token and user_id.
If the user is not already registered in the tournament adds the given user_id to the tournament identified by the given subgame_id by adding them to the next available group.
URL : /leaders/tournaments/:subgame_id/register_user/:user_id
Method : POST
Data :
- url params
subgame_iduser_id
- headers
mcs-key
- body
user_tokenuser_id
Success Response
{
"success": true,
"tournament_id": /* subgame_id from url params */
}
Error Responses
40103 invalid user session token- “missing user token in request”
- “user token does not match for the provided user id”
40002 invalid input- “missing user id in request”
- “conflicting user ids in request”
40004 invalid tournament id- “invalid tournament id: configuration does not exist”
40501 access prohibited- “Tournament has not started yet.”
- “Tournament has ended.”
50003 database error
Get scores for all groups in a tournament
Gets the scores for all groups in a tournament. The tier is hardcoded to be ‘default’. Goes through all group ids and gets the members in each group, then gets the scores for those users.
Note This can result in a lot of connections to redis for tournaments with lots of users and a small group size which causes the call to take a long time and can be the source of timeout errors.
URL : /leaders/tournaments/:subgame_id/:leaderboard_id/all
Method : GET
Data :
- url params
subgame_idleaderboard_id
- headers
mcs-key
Success Response
{
"success": true,
"leaderboards": [ /* array of leaderboard groups (leaderboard group: array of sorted {uid: score} objects) */ ]
}
Error Responses
50003 database error
Get user’s scores for a subgame id
Gets the scores for subgame_id for user_id’s corresponding group. The scores in the url is the leaderboard id, the code for tournaments assumes the leaderboard id being used is scores.
URL : /leaders/tournaments/:subgame_id/scores/:user_id
Method : GET
Data :
- url params
subgame_iduser_id
- headers
mcs-key
Success Response
{
"success" : true,
"scores" : scoresMap,
"leaderboard" : scoresArray,
"subgame_id" : subgame_id,
"tournament_id" : subgame_id,
"tournament" : tournament_config,
"leaderboard_id" : leaderboard_id,
"active_leaderboard_instance_id" : leaderboardInstanceID,
"active_leaderboard_tournament_start_timestamp" : leaderboardTimestamp,
"active_leaderboard_tournament_end_timestamp" : leaderboardTournamentEndTimestamp,
"timestamp" : currentTimestamp
}
HINT: the keys in the ‘scores’ object are all the user_ids in the tournament group
Error Responses
40004 invalid tournament id- “invalid tournament id: configuration does not exist”
40501 access prohibited- “Tournament has not started yet.”
- “Tournament has ended.”
50003 database error
Get all tournaments and scores for a user
Gets all the tournaments and scores for a given user_id. This will check the scores leaderboard as well as any others defined for the game in the v5 manifest under configuration/batch/tournaments/{apiKey}/supplementary_leaderboard_ids.
URL : /leaders/tournaments/user/:user_id
Method : GET
Data :
- url params
user_id
- headers
mcs-key
Success Response
{
"user_tournament_scores": scoresToTournamentIDs /* object { tournamentID: { leaderboardID: score, ... }, ...} */
}
Error Responses
50003 database error
Get scores for some users for a specific leaderboard
Gets the leaderboard values for the POSTed users ids. If the tournament hasn’t started returns success with empty scores array and null leaderboard instance id.
The body must incude either user_ids or third_party_ids and third_party_type.
Currently scores in the response is an object but if the tournament hasn’t started yet it will be an empty array, there is a TODO in the code to change it to an empty object.
If you provide ids that do not have corresponding scores, those ids are omitted from the scores map (in other words, they do not map to “0” or null).
If you pass third_party_ids, scores provides a map to the third-party ids instead of the default user ids and third_party_ids_mapping provides a mapping of third-party ids to user ids.
URL : /leaders/:subgame_id/:leaderboard_id
Method : POST
Data :
- url params
subgame_idleaderboard_id
- headers
mcs-key
- body
user_idsthird_party_idsthird_party_type
Success Response
{
"success" : true,
"scores" : scores_map /* object */,
"third_party_ids_mapping" : third_party_ids_mapping /* object (if third party ids were provided) */,
"subgame_id" : subgame_id,
"leaderboard_id" : leaderboard_id,
"active_leaderboard_instance_id" : active_leaderboard_instance_id /* will be null if tourn hasn't started */,
"active_leaderboard_tournament_start_timestamp" : active_leaderboard_tournament_start_timestamp,
"active_leaderboard_tournament_end_timestamp" : active_leaderboard_tournament_end_timestamp,
"timestamp" : active_leaderboard_server_timestamp
}
Error Responses
40002 invalid input- “getCorrespondingUserIDsForThirdPartyIDsForRequest was not provided with a third_party_type”
- “getCorrespondingUserIDsForThirdPartyIDsForRequest was not provided with third_party_ids”
50003 database error
Get a specific user’s score for a specific leaderboard
Gets the score for a user in the specified leaderboard.
If the tournament hasn’t started returns with null score and leaderboard instance id.
URL : /leaders/:subgame_id/:leaderboard_id/:user_id
Method : GET
Data :
- url params
subgame_idleaderboard_iduser_id
- headers
mcs-key
Success Response
{
"success" : true,
"score" : score /* null if tourn hasn't started */,
"user_id" : user_id,
"subgame_id" : subgame_id,
"leaderboard_id" : leaderboard_id,
"active_leaderboard_instance_id" : active_leaderboard_instance_id /* null if tourn hasn't started */,
"active_leaderboard_tournament_start_timestamp" : active_leaderboard_tournament_start_timestamp,
"active_leaderboard_tournament_end_timestamp" : active_leaderboard_tournament_end_timestamp,
"timestamp" : active_leaderboard_server_timestamp
}
Error Responses
50003 database error
Set a score for this user on a specific leaderboard
Sets the score for a user in the given leaderboard.
URL : /leaders/:subgame_id/:leaderboard_id/:user_id
Method : POST
Data :
- url params
subgame_idleaderboard_iduser_id
- headers
mcs-key
- body
user_tokenuser_iduser_score
Success Response
{
"success" : true,
"score" : score,
"user_id" : userID,
"subgame_id" : subgameID,
"leaderboard_id" : leaderboardID,
"active_leaderboard_instance_id" : activeLeaderboardInstanceID,
"active_leaderboard_tournament_start_timestamp" : active_leaderboard_tournament_start_timestamp,
"active_leaderboard_tournament_end_timestamp" : active_leaderboard_tournament_end_timestamp,
"timestamp" : active_leaderboard_server_timestamp
}
Error Responses
40103 invalid user session token- “missing user token in request”
- “user token does not match for the provided user id”
40002 invalid input- “missing user id in request”
- “conflicting user ids in request”
- “missing user_score”
40004 invalid tournament id- “invalid tournament id: configuration does not exist”
40501 access prohibited- “Tournament has not started yet.”
- “Tournament has ended.”
50003 database error
Middleware
getUserIDsForThirdPartyIDsForRequest
Allows clients to provide third party ids instead of user ids in the request and converts the third party ids to v5 user ids.
Used by the /leaders/:subgame_id/:leaderboard_id endpoint.
getTournamentDetailsAndRegistrationForUserRequest
For requests that require a user is assigned to a group this middleware will guarantee that user_id is actually assigned to a group and get the tournament details associated with that group.
Note uses hardcoded tier and leaderboardID of ‘default’ and ‘scores’ respectively.
Used by the /leaders/tournaments/:subgame_id/register_user/:user_id and /leaders/tournaments/:subgame_id/scores/:user_id endpoints.
setActiveLeaderboardIDForRequest
Gets the active leaderboard details from redis and adds active_leaderboard_instance_id, active_leaderboard_tournament_start_timestamp, active_leaderboard_tournament_end_timestamp, and active_leaderboard_server_timestamp to the request body.
Used by the /leaders/tournaments/:subgame_id/:leaderboard_id/all, /leaders/:subgame_id/:leaderboard_id, and /leaders/:subgame_id/:leaderboard_id/:user_id (GET and POST) endpoints.
Squash Server
The custom endpoints on the squash server store some additional tournament data used by scattergories.
The custom data fields that are sent when creating a new tournament in Hope are:
tierspersonalGoalsplayerColouropponentColourstartTimeendTimemaxLeaderboardViewassetBundleunrankedImageNameplayButtonIdtournamentNamerewardMessageIcon
Redis Keys
sq:tournaments
type: set
Stores all the tournament ids.
sq:tournamentHash
type: hash
Stores the custom tournament data. The hash key is the tournament id and the value is the stringified tournament data.
Endpoints
Create a new tournament
Takes in a tournament id and tournament data and stores the id in the sq:tournaments redis key and the id/data pair in the sq:tournamentHash redis key.
URL /custom/{apiKey}/createTournament
Method POST
Get a tournament
Takes in a tournament id returns the tournament data retrieved from the sq:tournamentHash redis key.
URL /custom/{apiKey}/tournament
Method GET
Get all tournaments
Returns the set of tournament ids stored in the sq:tournaments redis key.
URL /custom/{apiKey}/tournaments
Method GET