Skip to content

API used by the ExtraLeaderboardPosition plugin on Trackmania. Allow users to request data from the Nadeo API

Notifications You must be signed in to change notification settings

Banalian/ExtraLeaderboardAPI

Repository files navigation

ExtraLeaderboardAPI

Introduction

ExtraLeaderboardAPI is a Java/JEE-based application programming interface (API) that allows developers to access and retrieve information about map leaderboards in the TrackMania Next game.

ExtraLeaderboardAPI is designed to be called by an Openplanet plugin inside the game, and it uses the Nadeo API to retrieve leaderboard data.

Installation

You will need Java 17 to run the API.

This API uses Maven to manage dependencies. To install the API, simply clone the repository and run mvn install in the root directory.

It was deployed on a JBoss/Wildfly server.

The following properties are required :

  • ubisoft.email : the email address used to log in to the Ubisoft account
  • ubisoft.password : the password used to log in to the Ubisoft account

Usage

When deployed (for example locally), the API can be accessed at http://localhost:8080/ELP.

When using GitHub, the war file generated by a push on master is automatically deployed on a AWS EC2 instance.

Endpoints

Important notes

All the endpoints take a mapId as a URL parameter, which is the ID of the map in which we want to get scores, leaderboards etc.

Endpoints return info in the form of UserResponse objects, a UserResponse mainly contains:

  • A list of LeaderboardPosition objects (a LeaderboardPosition quantifies a time and rank, and a players Account ID).
  • One MapInfo object (a MapInfo contains basic information regarding a map).
  • A map<String,Object> containing metadata about the map, for now it is only the player count of the map.

Here is a typical UserResponse object Generated by the url: /api/leaderboard/map/JADzePlJElXk6wLX3z5Fksf6wL3/records?score=42000,42500,43000&medal=1,2,3,4&position=10,100,200&getplayercount=true&getmapinfo=true

{
  "positions": [
    {
      "time": 65000,
      "rank": 5316,
      "accountId": "8ff2fad2-059d-4a9a-99d3-93861e2e8f89"
    },
    {
      "time": 52000,
      "rank": 4759,
      "accountId": "8ff2fad2-059d-4a9a-99d3-93861e2e8f89"
    },
    {
      "time": 46000,
      "rank": 3232,
      "accountId": "8ff2fad2-059d-4a9a-99d3-93861e2e8f89"
    },
    {
      "time": 42908,
      "rank": 338,
      "accountId": "8ff2fad2-059d-4a9a-99d3-93861e2e8f89"
    },
    {
      "time": 43000,
      "rank": 376,
      "accountId": "8ff2fad2-059d-4a9a-99d3-93861e2e8f89"
    },
    {
      "time": 43500,
      "rank": 809,
      "accountId": "8ff2fad2-059d-4a9a-99d3-93861e2e8f89"
    },
    {
      "time": 44000,
      "rank": 1310,
      "accountId": "8ff2fad2-059d-4a9a-99d3-93861e2e8f89"
    },
    {
      "time": 42095,
      "rank": 10,
      "accountId": "9219cc64-63ec-4cfe-8890-a4239093e71c"
    },
    {
      "time": 42550,
      "rank": 100,
      "accountId": "dbe9698f-68ce-4792-ab6f-3262ddcf9c75"
    },
    {
      "time": 42747,
      "rank": 200,
      "accountId": "b59bc880-ef99-4a3b-9865-213117b2734d"
    }
  ],
  "meta": {
    "playerCount": 5625
  },
  "mapInfo": {
    "uid": "QqCyGzZKOCU2duwiEEgCeZ7Ivj7",
    "name": "$s$09FDeform$FFFative$09F|Ξ",
    "author": "70d991d1-434e-4e69-80df-f6e9c5ab6ea7",
    "nbLaps": 0,
    "submitter": "70d991d1-434e-4e69-80df-f6e9c5ab6ea7",
    "authorTime": 42908,
    "goldTime": 46000,
    "silverTime": 52000,
    "bronzeTime": 65000
  }
}

GET /api/leaderboard/map/{mapId}

Query parameters

  • None

Response:

  • UserResponse containing information relative to the map

GET /api/leaderboard/map/{mapId}/medal

Query parameters

  • None

Response:

  • UserResponse containing information about the medals of the map

The returned UserResponse contains all theoretical positions and times corresponding to the medals of the map, in the form of a MapInfo object.

GET /api/leaderboard/map/{mapId}/medal/at

Query parameters

  • None

Response:

  • UserResponse containing information on the theoretical time and position of the author medal of the map.

GET /api/leaderboard/map/{mapId}/medal/gold

Query parameters

  • None

Response:

  • UserResponse containing information on the theoretical time and position of the gold medal of the map.

GET /api/leaderboard/map/{mapId}/medal/silver

Query parameters

  • None

Response:

  • UserResponse containing information on the theoretical time and position of the silver medal of the map.

GET /api/leaderboard/map/{mapId}/medal/bronze

Query parameters

  • None

Response:

  • UserResponse containing information on the theoretical time and position of the bronze medal of the map.

GET /api/leaderboard/map/{mapId}/playercount

Query parameters

  • None

Response:

  • UserResponse containing the amount of players that have a time on the map.

- GET /leaderboard/map/{mapId}/position

Query parameters

  • pos: the position in the map leaderboard from which to get the time

Response:

  • UserResponse containing the time of the given position.

- GET /leaderboard/map/{mapId}/time

Query parameters

  • time: the time from which to get a leaderboard position

Response:

  • UserResponse containing the position of the given time on the leaderboard.

GET /api/leaderboard/map/{mapId}/records

Query parameters

  • score: list of the time scores on the map to get the positions for.
  • player: list of players to get the time scores and positions of.
  • medal: list of medals to get the theoretical time scores and positions of.
  • position: list of positions to get the time scores of.
  • getplayercount: whether to return the amount of players that have a time on the map.
  • getmapinfo: whether to return general info about the map (the corresponding mapInfo object).
  • isStunt : whether the map uses the stunt gamemode.

Response:

  • UserResponse containing information corresponding to the results of all queries.

Planned features

  • Add better logging
  • Add telemetry
  • Generate Swagger documentation
  • Add more information in the leaderboardposition in the response (like what request does this position refers)
  • Better error handling to return more information to the user
  • Optimize requests to the Nadeo API (e.g. if we want top 1,2,5 for example, we can do only one request to the Nadeo API with a length of 5 and return the top 1,2,5)

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Contact

You can send a mail to extraleaderboard@gmail.com if you have any questions or suggestions. You may also open an issue on GitHub.

Inner workings

Here is some explanation about how the API works.

When a request is made to the API, it will arrive at a resource class. this function will then do the bare minimum to handle the input data, before calling the business logic class. The business logic class will then do the actual work, and return the result to the resource class. The resource class will then return the result to the user.

The business logic classes all have the same structure. They always prepare the input data and transform it into one or multiple Request. After that, it will create a MainHandler object, and call the method, giving it the requests.

This MainHandler object will then create a Payload to contain all necessary information, and give that to a sequence of handler. There are currently 2 handlers:

  • The RequestHandler : this handler will take the requests and send them to the Nadeo API, by using various classes. It will then store the result in the payload.
  • The ResponseHandler : this handler will take the result from the payload and transform it into a smaller response object that only contains the necessary data for us.

After that, the main handler will return a list of response objects to the business logic class, which will then return either use it to launch a new batch of request, or will create a UserResponse object to give back to the resource class.

There is also a system working in parallel of all of this. It will handle everything related to tokens. Nadeo Require a token to access the API, and it is valid for around one hour. This system will check if the token is still valid, and if not, it will request a new one or refresh the old one. This works thanks to a TimerTask which will automatically wait 55 min before refreshing tokens. Currently, the needed tokens are requested at the start of the application.

About

API used by the ExtraLeaderboardPosition plugin on Trackmania. Allow users to request data from the Nadeo API

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages