├── .github
└── workflows
│ ├── jitpack-build.yml
│ ├── publish.yml
│ └── test.yml
├── .gitignore
├── LICENSE
├── README.md
├── build.gradle.kts
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── jitpack.yml
├── pull_request_template.md
├── settings.gradle.kts
└── src
├── main
└── kotlin
│ └── com
│ └── api
│ └── igdb
│ ├── apicalypse
│ ├── APICalypse.kt
│ └── Sort.kt
│ ├── exceptions
│ └── RequestException.kt
│ ├── request
│ ├── IGDBWrapper.kt
│ ├── JsonRequest.kt
│ ├── ProtoRequest.kt
│ └── TwitchAuthenticator.kt
│ └── utils
│ ├── Endpoint.kt
│ ├── Endpoints.kt
│ ├── ImageBuilder.kt
│ ├── ImageSize.kt
│ ├── ImageType.kt
│ └── TwitchToken.kt
├── resources
└── com
│ └── api
│ └── igdb
│ └── igdbproto.proto
└── test
├── java
└── com
│ └── api
│ └── igdb
│ ├── TestJavaWrapper.java
│ └── TestTwitchToken.java
└── kotlin
└── com
└── api
└── igdb
├── TestAPICalypseQueryParser.kt
├── TestIGDBWrapper.kt
├── TestImageBuilder.kt
├── TestProtobufRequest.kt
├── TestProxy.kt
├── TestRequestException.kt
└── TestTwitchTokenKotlin.kt
/.github/workflows/jitpack-build.yml:
--------------------------------------------------------------------------------
1 | name: jitpack-build
2 |
3 | on: [push]
4 |
5 | jobs:
6 | jitpack:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Branch Name
10 | run: echo running on branch ${BRANCH_NAME}
11 | env:
12 | BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
13 | - name: Trigger Jitpack Build
14 | run: curl https://jitpack.io/com/github/husnjak/IGDB-API-JVM/${BRANCH_NAME}-SNAPSHOT/build.log -L | grep -o 'BUILD SUCCESSFUL'
15 | env:
16 | BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
17 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | # This is a basic workflow to help you get started with Actions
2 |
3 | name: Publish package
4 |
5 | # Controls when the action will run. Triggers the workflow on push or pull request
6 | # events but only for the master branch
7 | on:
8 | workflow_dispatch:
9 | inputs:
10 | packagePrefix:
11 | required: true
12 | default: 'SNAPSHOT'
13 | description: "Packages require a package version, Keep SNAPSHOT for snapshot upload. Replace SNAPSHOT for staging deploy."
14 | release:
15 | types: # This configuration does not affect the page_build event above
16 | - created
17 |
18 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel
19 | jobs:
20 | # This workflow contains a single job called "build"
21 | build:
22 | # The type of runner that the job will run on
23 | runs-on: ubuntu-latest
24 | permissions:
25 | contents: read
26 | packages: write
27 | # Steps represent a sequence of tasks that will be executed as part of the job
28 | steps:
29 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
30 | - uses: actions/checkout@v4
31 | - name: Setup JDK 17
32 | uses: actions/setup-java@v3
33 | with:
34 | java-version: 17
35 | distribution: 'adopt'
36 | - name: Setup Gradle
37 | uses: gradle/gradle-build-action@v2.9.0
38 | - name: Extract branch name
39 | shell: bash
40 | run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
41 | id: extract_branch
42 | - if: github.event.release.tag_name == ''
43 | name: Publish SNAPSHOT package
44 | run: ./gradlew publish --no-daemon
45 | env:
46 | ORG_GRADLE_PROJECT_github_token: ${{ secrets.GITHUB_TOKEN }}
47 | ORG_GRADLE_PROJECT_github_actor: ${ GITHUB_ACTOR }
48 | ORG_GRADLE_PROJECT_sonatype_username: ${{ secrets.SONATYPE_USERNAME }}
49 | ORG_GRADLE_PROJECT_sonatype_password: ${{ secrets.SONATYPE_PASSWORD }}
50 | ORG_GRADLE_PROJECT_signingKey: ${{ secrets.PGP_KEY }}
51 | ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.PGP_PASSPHRASE }}
52 | ORG_GRADLE_PROJECT_version: ${{ steps.extract_branch.outputs.branch }}-${{ github.run_id }}-${{ github.event.inputs.packagePrefix }}
53 | - if: github.event.inputs.packagePrefix == ''
54 | name: Publish Release package
55 | run: ./gradlew publish --no-daemon
56 | env:
57 | ORG_GRADLE_PROJECT_github_token: ${{ secrets.GITHUB_TOKEN }}
58 | ORG_GRADLE_PROJECT_github_actor: ${ GITHUB_ACTOR }
59 | ORG_GRADLE_PROJECT_sonatype_username: ${{ secrets.SONATYPE_USERNAME }}
60 | ORG_GRADLE_PROJECT_sonatype_password: ${{ secrets.SONATYPE_PASSWORD }}
61 | ORG_GRADLE_PROJECT_signingKey: ${{ secrets.PGP_KEY }}
62 | ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.PGP_PASSPHRASE }}
63 | ORG_GRADLE_PROJECT_version: ${{ github.event.release.tag_name }}
64 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 |
2 | name: Java CI
3 |
4 | on: [push]
5 |
6 | jobs:
7 | build:
8 | runs-on: ubuntu-latest
9 | environment: apitesting
10 | steps:
11 | - uses: actions/checkout@v4
12 | - name: Setup JDK 17
13 | uses: actions/setup-java@v3
14 | with:
15 | java-version: 17
16 | distribution: 'adopt'
17 | - name: Setup Gradle
18 | uses: gradle/gradle-build-action@v2.9.0
19 | - name: Execute Gradle build
20 | run: ./gradlew build --no-daemon -x publish -x sign
21 | env:
22 | client_id: "${{ secrets.CLIENT_ID }}"
23 | client_secret: "${{ secrets.CLIENT_SECRET }}"
24 | bearer: "${{ secrets.BEARER_TOKEN }}"
25 | proxy_api_key: "${{ secrets.PROXY_KEY }}"
26 | proxy_url: "${{ secrets.PROXY_URL }}"
27 | ORG_GRADLE_PROJECT_version: Build-${{ github.run_id }}"
28 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Compiled class file
2 | *.class
3 |
4 | # Log file
5 | *.log
6 |
7 | # Package Files #
8 | *.jar
9 | *.war
10 | *.nar
11 | *.ear
12 | *.zip
13 | *.tar.gz
14 | *.tar
15 | *.rar
16 |
17 | # Gradle stuffs
18 | !gradle-wrapper.jar
19 | gradle.properties
20 | .gradle/
21 |
22 | # IDEA stuffs
23 | .idea/shelf
24 | /ideaSDK
25 | /idea/testData/debugger/tinyApp/classes*
26 | /ultimate/dependencies
27 | /ultimate/ideaSDK
28 | /ultimate/out
29 | /ultimate/tmp
30 | .idea/libraries/Gradle*.xml
31 | .idea/libraries/Maven*.xml
32 | .idea/artifacts
33 | .idea/modules
34 | .idea/runConfigurations/JPS_*.xml
35 | .idea/libraries
36 | .idea/modules.xml
37 | .idea/gradle.xml
38 | .idea/compiler.xml
39 | .idea/inspectionProfiles/profiles_settings.xml
40 | .idea/.name
41 | /.idea
42 | .idea/**/gradle.xml
43 | .idea/**/libraries
44 | .DS_Store
45 | .idea/replstate.xml
46 |
47 |
48 | # IntelliJ
49 | out/
50 | build/
51 | /build
52 | !**/src/**/build
53 | !**/test/**/build
54 |
55 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
56 | hs_err_pid*
57 | .idea/workspace.xml
58 | *.DS_Store
59 | .gradle/*
60 | *.csv
61 | *.xlsx
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 husnjak
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://central.sonatype.com/artifact/io.github.husnjak/igdb-api-jvm/1.3.1)
2 | [](https://jitpack.io/#husnjak/IGDB-API-JVM)
3 | # IGDB API-JVM (V4)
4 | A Kotlin wrapper for the IGDB.com Video Game Database API.
5 |
6 | __IMPORTANT__
7 |
8 | This wrapper is compatible with ONLY their newest release V4.
9 |
10 | ## About IGDB
11 | One of the principles behind IGDB.com is accessibility of data. We wish to share the data with anyone who wants to build cool video game oriented websites, apps and services. This means that the information you contribute to IGDB.com can be used by other projects as well.
12 |
13 | Thus, you are not only contributing to the value of this site but to thousands of other projects as well. We are looking forward to see what exciting game related projects you come up with. Happy coding!
14 |
15 | More info here:
16 | * [About the API](https://www.igdb.com/api)
17 | * [API Documentation](https://api-docs.igdb.com/)
18 |
19 | Information about the Querying language APICalypse:
20 | * [apicalypse.io](https://apicalypse.io/)
21 |
22 | ## About the wrapper
23 | This wrapper is written in Kotlin which uses the JVM and works with both Kotlin & Java projects. I have not tested it on other JVM languages but it should work for these languages as well. The examples below showcase this wrapper in both Kotlin and Java.
24 |
25 | Feel free to test it on other languages yourselves 😀
26 |
27 | The Wrapper can handle both the IGDB generated classes and JSON (Strings), I have chosen to make the API's Generated classes ([Protocol Buffers](https://developers.google.com/protocol-buffers/)) the standard way because it will make it easier to use as you don't have to create your own classes to hold the information.
28 |
29 | # Installation and setup
30 |
31 | __Maven__
32 |
33 | ```xml
34 |
35 | io.github.husnjak
36 | igdb-api-jvm
37 | 1.3.1
38 |
39 | ```
40 |
41 | __Gradle__
42 |
43 | ``` gradle
44 | dependencies {
45 | implementation 'io.github.husnjak:igdb-api-jvm:1.3.1'
46 | }
47 | ```
48 |
49 | Optional for Android (SDK: 19+). Add internet permissions in the manifest.
50 | ``` xml
51 |
52 | ```
53 |
54 | ## Using your Twitch Developer Credentials
55 | * Create a new TwitchToken object
56 | ``` java
57 | // Java Example
58 | TwitchAuthenticator tAuth = TwitchAuthenticator.INSTANCE;
59 | TwitchToken token = tAuth.requestTwitchToken("CLIENT_ID", "CLIENT_SECRET");
60 |
61 | // The instance stores the token in the object untill a new one is requested
62 | TwitchToken token = tAuth.getTwitchToken()
63 |
64 | ```
65 | ``` kotlin
66 | // Kotlin example
67 | val token = TwitchAuthenticator.requestTwitchToken("CLIENT_ID", "CLIENT_SECRET")
68 |
69 | // The instance stores the token in the object untill a new one is requested
70 | TwitchAuthenticator.twitchToken
71 | ```
72 | The `TwitchToken` object looks like this
73 | ``` json
74 | {
75 | "access_token": "ACCESS_TOKEN",
76 | "expires_in": 5135439,
77 | "token_type": "bearer"
78 | }
79 | ```
80 |
81 | * Authenticating requests for the IGDB API
82 | ``` java
83 | // Java Example
84 | IGDBWrapper wrapper = IGDBWrapper.INSTANCE;
85 | wrapper.setCredentials("CLIENT_ID", "ACCESS_TOKEN")
86 | ```
87 | ``` kotlin
88 | // Kotlin Example
89 | IGDBWrapper.setCredentials("CLIENT_ID", "ACCESS_TOKEN")
90 | ```
91 | You can use the access_token from the token object.
92 |
93 | ### Android projects
94 | Do not use the `TwitchAuthenticator` in your Android applications, you don't want to create multiple access_tokens for each device.
95 | It is recommended to create your token on a server and then use a proxy api to call the IGDB api, where you append the Bearer token for each request.
96 |
97 | IGDB provides a [free AWS CloudFormation template](https://api-docs.igdb.com/#proxy) that you can deploy for this purpose with instructions on how to use it.
98 | * Create a new IGDBWrapper Object connected to the AWS Proxy server.
99 | ``` java
100 | // Java Example
101 | IGDBWrapper wrapper = IGDBWrapper.INSTANCE;
102 | Map proxyHeaders = new HashMap() {{
103 | put("x-api-key", "PROXY_API_KEY");
104 | }};
105 | wrapper.setupProxy("PROXY_URL/v4", proxyHeaders);
106 | ```
107 | ``` kotlin
108 | // Kotlin Example
109 | IGDBWrapper.setupProxy("PROXY_URL/v4", mapOf("x-api-key" to "PROXY_API_KEY"))
110 | ```
111 |
112 | # How to use the wrapper
113 | The wrapper has two "wrapping" functions, and a lot of helper functions (one for each endpoint)
114 | The two main functions called `apiProtoRequest` and `apiJsonRequest` and they handle all the requests to the api.
115 | The class `APICalypse` handles the new querying language, so that you don't need to care about structure and syntax as much.
116 |
117 | * `apiProtoRequest`
118 | This method handles IGDB generated proto classes which returns an ByteArray to be used to fill the appropriate class.
119 | ```kotlin
120 | // Kotlin Example
121 | val bytes = apiProtoRequest(endpoint: Endpoints.GAMES, apicalypseQuery: "fields *;")
122 | val listOfGames: List = GamesResult.parseFrom(bytes).gamesList
123 | ```
124 | ```java
125 | // Java Example
126 | byte[] bytes = wrapper.apiProtoRequest(endpoint: Endpoints.GAMES, apicalypseQuery: "fields *;");
127 | List listOfGames = GameResult.parseFrom(bytes).getGamesList();
128 | ```
129 | returns a list of Game objects.
130 |
131 | * `apiJsonRequest`
132 | This method return raw JSON (String) from the API
133 | Example:
134 | ```kotlin
135 | // Kotlin Example
136 | val json: String = apiJsonRequest(endpoint: Endpoints.GAMES, APICalypseQuery: "fields *;")
137 | ```
138 | ```java
139 | // Java Example
140 | String json = wrapper.apiJsonRequest(endpoint: Endpoints.GAMES, "fields *;");
141 | ```
142 | returns a String.
143 |
144 | * `APICalypse`
145 | ```kotlin
146 | // Kotlin Example
147 | val apicalypse = APICalypse()
148 | .fields("*")
149 | .exclude("*")
150 | .limit(10)
151 | .offset(0)
152 | .search("Halo")
153 | .sort("release_dates.date", Sort.ASCENDING)
154 | .where("platforms = 48")
155 | ```
156 | ```java
157 | // Java Example
158 | APICalypse apicalypse = new APICalypse()
159 | .fields("*")
160 | .exclude("*")
161 | .limit(10)
162 | .offset(0)
163 | .search("Halo")
164 | .sort("release_dates.date", Sort.ASCENDING)
165 | .where("platforms = 48");
166 | ```
167 | Here are all the options, this creates a query for you. To get a String query from APICalypse just add `.buildQuery()`.
168 |
169 | __NOTE__
170 | These examples above are only here to show you how to use the "manual" part of the wrapper. This wrapper comes with complete functions for each endpoint in the API, so you don't have to deal with the manual implementation.
171 |
172 | There are two functions for each endpoint, one for classes and one for json, for quick access. The difference between them is the name see the examples below:
173 | ```kotlin
174 | // Example of functions in Kotlin
175 | IGDBWrapper.games(APICalypse())
176 | IGDBWrapper.platforms(APICalypse())
177 | IGDBWrapper.genres(APICalypse())
178 | ...
179 | IGDBWrapper.jsonGames(APICalypse())
180 | IGDBWrapper.jsonPlatforms(APICalypse())
181 | IGDBWrapper.jsonGenres(APICalypse())
182 | ...
183 | ```
184 | ```java
185 | // Example of functions in Java
186 | ProtoRequestKt.games(IGDBWrapper.INSTANCE, new APICalypse())
187 | ProtoRequestKt.platforms(IGDBWrapper.INSTANCE, new APICalypse())
188 | ProtoRequestKt.genres(IGDBWrapper.INSTANCE, new APICalypse())
189 | ...
190 | JsonRequestKt.jsonGames(IGDBWrapper.INSTANCE, new APICalypse())
191 | JsonRequestKt.jsonPlatforms(IGDBWrapper.INSTANCE, new APICalypse())
192 | JsonRequestKt.jsonGenres(IGDBWrapper.INSTANCE, new APICalypse())
193 | ...
194 | ```
195 |
196 | ## ImageBuilder
197 | To simplify the process of building the image URLs for IGDBs images there is a function called `imageBuilder` which is a helping tool in requesting the perfect sized images for your project. The function requires you to get the `image_id` then set your desired size (resolution), set your desired image format (default is set to PNG).
198 | ```kotlin
199 | // Kotlin Example
200 | val image_id = "mnljdjtrh44x4snmierh"
201 | val imageURL = imageBuilder(image_id, ImageSize.SCREENSHOT_HUGE, ImageType.PNG)
202 |
203 | /*
204 | * Result:
205 | * imageURL = https://images.igdb.com/igdb/image/upload/t_screenshot_huge/mnljdjtrh44x4snmierh.png
206 | */
207 | ```
208 |
209 | ```java
210 | // Java Example
211 | String image_id = "mnljdjtrh44x4snmierh";
212 | String imageURL = ImageBuilderKt.imageBuilder(image_id, ImageSize.SCREENSHOT_HUGE, ImageType.PNG)
213 |
214 | /*
215 | * Result:
216 | * imageURL = https://images.igdb.com/igdb/image/upload/t_screenshot_huge/mnljdjtrh44x4snmierh.png
217 | */
218 | ```
219 | More information about images can be found [here](https://api-docs.igdb.com/#images)
220 | ## Exceptions
221 | The wrapper throws an `RequestException` on every exception from the API. This exception hold three things:
222 | * HTTP status code
223 | * Request (The complete sent request for debugging)
224 | * Result (The response from the API)
225 | Request and Response come directly from the HTTP library [Fuel](https://github.com/kittinunf/Fuel)
226 |
227 | ## Code Examples
228 | * Request games from the API:
229 | ```kotlin
230 | // Kotlin
231 | IGDBWrapper.setCredentials("CLIENT_ID", "ACCESS_TOKEN")
232 | val apicalypse = APICalypse().fields("*").sort("release_dates.date", Sort.DESCENDING)
233 | try{
234 | val games: List = IGDBWrapper.games(apicalypse)
235 | } catch(e: RequestException) {
236 | // Do something or error
237 | }
238 | ```
239 | ```java
240 | // Java
241 | IGDBWrapper wrapper = IGDBWrapper.INSTANCE;
242 | wrapper.setCredentials("CLIENT_ID", "ACCESS_TOKEN")
243 | APICalypse apicalypse = new APICalypse().fields("*").sort("release_dates.date", Sort.DESCENDING);
244 | try{
245 | List games = ProtoRequestKt.games(wrapper, apicalypse);
246 | } catch(RequestException e) {
247 | // Do something or error
248 | }
249 | ```
250 | * Search in the API:
251 | __NOTE__
252 | Search objects contain the objects from search ex: Characters, Collections, Games, Platforms, and Themes.
253 | Search does not work with Sorting!
254 | ```kotlin
255 | // Kotlin
256 | IGDBWrapper.setCredentials("CLIENT_ID", "ACCESS_TOKEN")
257 | val apicalypse = APICalypse().search("Halo").fields("*")
258 | try{
259 | val searchResult: List = IGDBWrapper.search(apicalypse)
260 | } catch(e: RequestException) {
261 | // Do something or error
262 | }
263 | ```
264 | ```java
265 | // Java
266 | IGDBWrapper wrapper = IGDBWrapper.INSTANCE;
267 | wrapper.setCredentials("CLIENT_ID", "ACCESS_TOKEN")
268 | APICalypse apicalypse = new APICalypse().search("Halo").fields("*")
269 | try{
270 | List searchResult = ProtoRequestKt.search(wrapper, apicalypse);
271 | } catch(RequestException e) {
272 | // Do something or error
273 | }
274 | ```
275 | * Request filtered results:
276 | ```kotlin
277 | // Kotlin
278 | IGDBWrapper.setCredentials("CLIENT_ID", "ACCESS_TOKEN")
279 | val apicalypse = APICalypse().fields("*")
280 | .sort("release_dates.date", Sort.DESCENDING).where("themes != 42")
281 | try{
282 | val games: List = IGDBWrapper.games(apicalypse)
283 | } catch(e: RequestException) {
284 | // Do something or error
285 | }
286 | ```
287 | ```java
288 | // Java
289 | IGDBWrapper wrapper = IGDBWrapper.INSTANCE;
290 | wrapper.setCredentials("CLIENT_ID", "ACCESS_TOKEN")
291 | APICalypse apicalypse = new APICalypse().fields("*")
292 | .sort("release_dates.date", Sort.DESCENDING).where("themes != 42");
293 | try{
294 | List games = ProtoRequestKt.games(wrapper, apicalypse);
295 | } catch(RequestException e) {
296 | // Do something or error
297 | }
298 | ```
299 |
--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import com.google.protobuf.gradle.GenerateProtoTask
2 | import de.undercouch.gradle.tasks.download.Download
3 |
4 | plugins {
5 | kotlin("jvm") version "2.1.10"
6 | id("org.jetbrains.dokka") version "1.9.20"
7 | id("maven-publish")
8 | id("signing")
9 | id("de.undercouch.download") version "5.6.0"
10 | id("com.google.protobuf") version "0.9.4"
11 | }
12 |
13 | group = "io.github.husnjak"
14 | version = findProperty("version") as String
15 |
16 | val fuelVersion = "2.3.1"
17 | val protobufJavaVersion = "4.29.3"
18 | val junitJupiterVersion = "5.12.0"
19 | val junitPlatformVersion = "1.12.0"
20 | val protobufPluginVersion = "0.9.4"
21 |
22 | repositories {
23 | mavenCentral()
24 | gradlePluginPortal()
25 | }
26 |
27 | dependencies {
28 | implementation(kotlin("stdlib"))
29 | // HTTP
30 | implementation("com.github.kittinunf.fuel:fuel:$fuelVersion")
31 | implementation("com.github.kittinunf.fuel:fuel-gson:$fuelVersion")
32 | implementation("com.github.kittinunf.fuel:fuel-android:$fuelVersion")
33 | // Protocol Buffers
34 | // set to api() to add protobuf to client classpath
35 | api("com.google.protobuf:protobuf-kotlin:$protobufJavaVersion")
36 | implementation("com.google.protobuf:protobuf-gradle-plugin:$protobufPluginVersion")
37 | // Tests
38 | testImplementation("org.junit.jupiter:junit-jupiter-api:$junitJupiterVersion")
39 | testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:$junitJupiterVersion")
40 | testRuntimeOnly("org.junit.platform:junit-platform-launcher:$junitPlatformVersion")
41 |
42 | }
43 |
44 | sourceSets {
45 | main {
46 | resources {
47 | srcDirs("$projectDir/src/resources") // protofile
48 | }
49 | proto {
50 | srcDirs("$projectDir/src/resources")
51 | }
52 | }
53 | }
54 |
55 | tasks {
56 | dokkaJavadoc {
57 | outputDirectory.set(layout.buildDirectory.dir("javadoc"))
58 | dependsOn(getTasksByName("generateProto", true))
59 | }
60 | withType {
61 | dependsOn("downloadProtoFiles")
62 | }
63 | processResources{
64 | dependsOn(getTasksByName("generateProto", true))
65 | duplicatesStrategy = DuplicatesStrategy.INCLUDE
66 | }
67 | }
68 |
69 | protobuf {
70 | protoc {
71 | artifact = "com.google.protobuf:protoc:$protobufJavaVersion"
72 | }
73 | }
74 |
75 | tasks.register("downloadProtoFiles",Download::class) {
76 | this.src("https://api.igdb.com/v4/igdbapi.proto")
77 | this.dest("$projectDir/src/resources/com/api/igdb/igdbproto.proto")
78 | this.overwrite(true)
79 | }
80 |
81 | val dokkaJar by tasks.registering(Jar::class) {
82 | group = JavaBasePlugin.DOCUMENTATION_GROUP
83 | description = "Assembles Kotlin docs with Dokka"
84 | archiveClassifier.set("javadoc")
85 | from(tasks.dokkaJavadoc)
86 | }
87 |
88 | val sourcesJar by tasks.registering(Jar::class) {
89 | dependsOn("generateProto")
90 | manifest {
91 | attributes("Main-Class" to "com.api.igdb.ApiRequesterKt")
92 | }
93 | group = JavaBasePlugin.DOCUMENTATION_GROUP
94 | description = "Assembles sources jar"
95 | archiveClassifier.set("sources")
96 | from(sourceSets["main"].allSource)
97 | }
98 |
99 | publishing {
100 | publications {
101 | create("maven") {
102 | from(components["kotlin"])
103 | artifact(dokkaJar)
104 | artifact(sourcesJar)
105 |
106 | versionMapping {
107 | usage("java-api") {
108 | fromResolutionOf("runtimeClasspath")
109 | }
110 | usage("java-runtime") {
111 | fromResolutionResult()
112 | }
113 | }
114 |
115 | pom {
116 | name.set("igdb-api-jvm")
117 | description.set("Kotlin wrapper for the IGDB API compiled for the JVM.")
118 | url.set("https://github.com/husnjak/igdb-api-jvm.git")
119 | licenses {
120 | license {
121 | name.set("The MIT License (MIT)")
122 | url.set("https://mit-license.org")
123 | }
124 | }
125 | developers {
126 | developer {
127 | id.set("husnjak")
128 | }
129 | }
130 | scm {
131 | connection.set("scm:git:https://github.com/husnjak/IGDB-API-JVM.git")
132 | developerConnection.set("scm:git:git@github.com:husnjak/IGDB-API-JVM.git")
133 | url.set("https://github.com/husnjak/IGDB-API-JVM")
134 | }
135 | }
136 | }
137 | }
138 | repositories {
139 | maven {
140 | name = "GitHubPackages"
141 | url = uri("https://maven.pkg.github.com/husnjak/igdb-api-jvm")
142 | credentials {
143 | username = findProperty("github_actor") as String?
144 | password = findProperty("github_token") as String?
145 | }
146 | }
147 | maven {
148 | name = "Sonatype"
149 | val releasesRepoUrl = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
150 | val snapshotsRepoUrl = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")
151 | url = if (version.toString().contains("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl
152 | println("Sonatype release version: $version using: $url")
153 | credentials {
154 | username = findProperty("sonatype_username") as String?
155 | password = findProperty("sonatype_password") as String?
156 | }
157 | }
158 | }
159 | }
160 |
161 | signing {
162 | val isJitpack = System.getenv("JITPACK") ?: ""
163 | if (isJitpack == "true"){
164 | return@signing
165 | }
166 |
167 | if (version.toString().contains("local")) {
168 | useGpgCmd()
169 | } else {
170 | val signingKey: String? by project
171 | val signingPassword: String? by project
172 | useInMemoryPgpKeys(signingKey, signingPassword)
173 | }
174 | sign(publishing.publications["maven"])
175 | }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/husnjak/IGDB-API-JVM/e62b531a4bb42e5031702c06ca377917560552a5/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | #
4 | # Copyright 2015 the original author or authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | ##############################################################################
20 | ##
21 | ## Gradle start up script for UN*X
22 | ##
23 | ##############################################################################
24 |
25 | # Attempt to set APP_HOME
26 | # Resolve links: $0 may be a link
27 | PRG="$0"
28 | # Need this for relative symlinks.
29 | while [ -h "$PRG" ] ; do
30 | ls=`ls -ld "$PRG"`
31 | link=`expr "$ls" : '.*-> \(.*\)$'`
32 | if expr "$link" : '/.*' > /dev/null; then
33 | PRG="$link"
34 | else
35 | PRG=`dirname "$PRG"`"/$link"
36 | fi
37 | done
38 | SAVED="`pwd`"
39 | cd "`dirname \"$PRG\"`/" >/dev/null
40 | APP_HOME="`pwd -P`"
41 | cd "$SAVED" >/dev/null
42 |
43 | APP_NAME="Gradle"
44 | APP_BASE_NAME=`basename "$0"`
45 |
46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
48 |
49 | # Use the maximum available, or set MAX_FD != -1 to use that value.
50 | MAX_FD="maximum"
51 |
52 | warn () {
53 | echo "$*"
54 | }
55 |
56 | die () {
57 | echo
58 | echo "$*"
59 | echo
60 | exit 1
61 | }
62 |
63 | # OS specific support (must be 'true' or 'false').
64 | cygwin=false
65 | msys=false
66 | darwin=false
67 | nonstop=false
68 | case "`uname`" in
69 | CYGWIN* )
70 | cygwin=true
71 | ;;
72 | Darwin* )
73 | darwin=true
74 | ;;
75 | MINGW* )
76 | msys=true
77 | ;;
78 | NONSTOP* )
79 | nonstop=true
80 | ;;
81 | esac
82 |
83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
84 |
85 |
86 | # Determine the Java command to use to start the JVM.
87 | if [ -n "$JAVA_HOME" ] ; then
88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
89 | # IBM's JDK on AIX uses strange locations for the executables
90 | JAVACMD="$JAVA_HOME/jre/sh/java"
91 | else
92 | JAVACMD="$JAVA_HOME/bin/java"
93 | fi
94 | if [ ! -x "$JAVACMD" ] ; then
95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
96 |
97 | Please set the JAVA_HOME variable in your environment to match the
98 | location of your Java installation."
99 | fi
100 | else
101 | JAVACMD="java"
102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
103 |
104 | Please set the JAVA_HOME variable in your environment to match the
105 | location of your Java installation."
106 | fi
107 |
108 | # Increase the maximum file descriptors if we can.
109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
110 | MAX_FD_LIMIT=`ulimit -H -n`
111 | if [ $? -eq 0 ] ; then
112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
113 | MAX_FD="$MAX_FD_LIMIT"
114 | fi
115 | ulimit -n $MAX_FD
116 | if [ $? -ne 0 ] ; then
117 | warn "Could not set maximum file descriptor limit: $MAX_FD"
118 | fi
119 | else
120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
121 | fi
122 | fi
123 |
124 | # For Darwin, add options to specify how the application appears in the dock
125 | if $darwin; then
126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
127 | fi
128 |
129 | # For Cygwin or MSYS, switch paths to Windows format before running java
130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
133 |
134 | JAVACMD=`cygpath --unix "$JAVACMD"`
135 |
136 | # We build the pattern for arguments to be converted via cygpath
137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
138 | SEP=""
139 | for dir in $ROOTDIRSRAW ; do
140 | ROOTDIRS="$ROOTDIRS$SEP$dir"
141 | SEP="|"
142 | done
143 | OURCYGPATTERN="(^($ROOTDIRS))"
144 | # Add a user-defined pattern to the cygpath arguments
145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
147 | fi
148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
149 | i=0
150 | for arg in "$@" ; do
151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
153 |
154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
156 | else
157 | eval `echo args$i`="\"$arg\""
158 | fi
159 | i=`expr $i + 1`
160 | done
161 | case $i in
162 | 0) set -- ;;
163 | 1) set -- "$args0" ;;
164 | 2) set -- "$args0" "$args1" ;;
165 | 3) set -- "$args0" "$args1" "$args2" ;;
166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
172 | esac
173 | fi
174 |
175 | # Escape application args
176 | save () {
177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
178 | echo " "
179 | }
180 | APP_ARGS=`save "$@"`
181 |
182 | # Collect all arguments for the java command, following the shell quoting and substitution rules
183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
184 |
185 | exec "$JAVACMD" "$@"
186 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto init
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto init
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :init
68 | @rem Get command-line arguments, handling Windows variants
69 |
70 | if not "%OS%" == "Windows_NT" goto win9xME_args
71 |
72 | :win9xME_args
73 | @rem Slurp the command line arguments.
74 | set CMD_LINE_ARGS=
75 | set _SKIP=2
76 |
77 | :win9xME_args_slurp
78 | if "x%~1" == "x" goto execute
79 |
80 | set CMD_LINE_ARGS=%*
81 |
82 | :execute
83 | @rem Setup the command line
84 |
85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
86 |
87 |
88 | @rem Execute Gradle
89 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
90 |
91 | :end
92 | @rem End local scope for the variables with windows NT shell
93 | if "%ERRORLEVEL%"=="0" goto mainEnd
94 |
95 | :fail
96 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
97 | rem the _cmd.exe /c_ return code!
98 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
99 | exit /b 1
100 |
101 | :mainEnd
102 | if "%OS%"=="Windows_NT" endlocal
103 |
104 | :omega
105 |
--------------------------------------------------------------------------------
/jitpack.yml:
--------------------------------------------------------------------------------
1 | jdk:
2 | - openjdk17
--------------------------------------------------------------------------------
/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ### Change Summary
2 | _Describe your change_
3 |
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | rootProject.name = "igdb-api-jvm"
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/apicalypse/APICalypse.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.apicalypse
2 |
3 | /**
4 | * The ApiCalypse class uses it's functions to build out the query
5 | */
6 | class APICalypse {
7 | private var search = ""
8 | private var fields = ""
9 | private var exclude = ""
10 | private var limit = ""
11 | private var offset = ""
12 | private var sort = ""
13 | private var where = ""
14 |
15 | /**
16 | * The ApiCalypse sort function
17 | *
18 | * @property field The field to sort by
19 | * @property order The sorting order; Ascending | Descending
20 | * @return ApiCalypse object with set sort query.
21 | */
22 | fun sort(field: String, order: Sort): APICalypse {
23 | this.sort = "s $field ${order.apiName};"
24 | return this
25 | }
26 |
27 | /**
28 | * The ApiCalypse fields function
29 | *
30 | * @property fields The fields to select
31 | * @return ApiCalypse object with set field query.
32 | */
33 | fun fields(fields: String): APICalypse {
34 | this.fields = "f $fields;"
35 | return this
36 | }
37 |
38 | /**
39 | * The ApiCalypse exclude function
40 | *
41 | * @property fields The fields to exclude
42 | * @return ApiCalypse object with set exclude query.
43 | */
44 | fun exclude(fields: String): APICalypse {
45 | this.exclude = "x $fields;"
46 | return this
47 | }
48 |
49 | /**
50 | * The ApiCalypse limit function
51 | *
52 | * @property limit The number of items in the query
53 | * @return ApiCalypse object with set limit query.
54 | */
55 | fun limit(limit: Int): APICalypse {
56 | this.limit = "l $limit;"
57 | return this
58 | }
59 |
60 | /**
61 | * The ApiCalypse offset function
62 | *
63 | * @property offset The number of items to offset in the query
64 | * @return ApiCalypse object with set offset query.
65 | */
66 | fun offset(offset: Int): APICalypse {
67 | this.offset = "o $offset;"
68 | return this
69 | }
70 |
71 | /**
72 | * The ApiCalypse search function
73 | *
74 | * @property searchQuery The query to search for
75 | * @return ApiCalypse object with set search query.
76 | */
77 | fun search(searchQuery: String): APICalypse {
78 | this.search = "search \"$searchQuery\";"
79 | return this
80 | }
81 |
82 | /**
83 | * The ApiCalypse where function
84 | *
85 | * @property where The logic to filter the request by
86 | * @return ApiCalypse object with set where query.
87 | */
88 | fun where(where: String): APICalypse {
89 | if (where.contains("where ") || where.contains("w ")) {
90 | this.where = where
91 | } else {
92 | if (where.contains(";"))
93 | this.where = "w $where"
94 | else
95 | this.where = "w $where;"
96 | }
97 | return this
98 | }
99 |
100 | /**
101 | * The buildQuery function builds the ApiCalypse object to a String query.
102 | *
103 | * @return String query based on the ApiCalypse object.
104 | */
105 | fun buildQuery(): String {
106 | var query = ""
107 | if (search.isNotBlank())
108 | query += search
109 | if (fields.isNotBlank())
110 | query += fields
111 | if (exclude.isNotBlank())
112 | query += exclude
113 | if (limit.isNotBlank())
114 | query += limit
115 | if (offset.isNotBlank())
116 | query += offset
117 | if (sort.isNotBlank())
118 | query += sort
119 | // TODO where
120 | if (where.isNotBlank())
121 | query += where
122 |
123 | return query
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/apicalypse/Sort.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.apicalypse
2 |
3 | /**
4 | * The Sort Enum class maps the ApiCalypse sorting syntax to objects.
5 | */
6 | enum class Sort(val apiName: String) {
7 | ASCENDING("asc"), DESCENDING("desc")
8 | }
9 |
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/exceptions/RequestException.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.exceptions
2 |
3 | import com.github.kittinunf.fuel.core.FuelError
4 | import com.github.kittinunf.fuel.core.Request
5 | import com.github.kittinunf.result.Result
6 |
7 | /**
8 | * The Request exception class wrapps the Kotlin Fuel HTTP library exception.
9 | *
10 | * @property statucCode The status code from the API
11 | * @property request The Kotlin Fuel request object
12 | * @property result The Kotlin Fuel result object, holds the FuelError
13 | */
14 | class RequestException(val statusCode: Int, val request: Request, val result: Result) : Exception()
15 |
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/request/IGDBWrapper.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.request
2 |
3 | import com.api.igdb.exceptions.RequestException
4 | import com.api.igdb.utils.Endpoint
5 | import com.github.kittinunf.fuel.httpPost
6 |
7 | /**
8 | * The ApiRequester object holds the API Key and uses it to request the IGDB API.
9 | */
10 | private var IGDB_API_URL = "https://api.igdb.com/v4"
11 | object IGDBWrapper {
12 | private var requestHeaders: Map = mapOf("x-user-agent" to "igdb-api-jvm")
13 |
14 | /**
15 | * The Set method for API Credentials
16 | *
17 | * @property clientID The IGDB ClientID
18 | * @property accessToken The IGDB AccessToken
19 | */
20 | fun setCredentials(clientID: String, accessToken: String) {
21 | requestHeaders = mapOf(
22 | "client-id" to clientID,
23 | "authorization" to "Bearer $accessToken",
24 | "x-user-agent" to "igdb-api-jvm")
25 | }
26 |
27 | /**
28 | * The set method for Proxy credentials
29 | *
30 | * @property proxyURL The url of the Proxy Server
31 | * @property proxyHeaders The headers to send to the Proxy Server
32 | */
33 | fun setupProxy(proxyURL: String, proxyHeaders: Map) {
34 | IGDB_API_URL = proxyURL
35 | proxyHeaders.toMutableMap()["x-user-agent"] = "igdb-api-jvm"
36 | requestHeaders = proxyHeaders.toMap()
37 | }
38 |
39 | /**
40 | * The Api request function for Protocol Buffers
41 | *
42 | * @property endpoint The endpoint the request
43 | * @property query The Api query to request with
44 | * @return The raw ByteArray to use with generated proto files
45 | */
46 | @Throws(RequestException::class)
47 | fun apiProtoRequest(endpoint: Endpoint, query: String): ByteArray {
48 | val requestURL = "$IGDB_API_URL${endpoint.url()}.pb"
49 | val (request, response, result) = requestURL.httpPost()
50 | .header(requestHeaders).body(query).responseString()
51 |
52 | if (response.statusCode != 200) {
53 | throw RequestException(response.statusCode, request, result)
54 | }
55 | return response.data
56 | }
57 |
58 | /**
59 | * The Api request function for JSON
60 | *
61 | * @property endpoint The endpoint the request
62 | * @property query The Api query to request with
63 | * @return The raw String result from the request
64 | */
65 | @Throws(RequestException::class)
66 | fun apiJsonRequest(endpoint: Endpoint, query: String): String {
67 | val requestURL = "$IGDB_API_URL${endpoint.url()}"
68 | val (request, response, result) = requestURL.httpPost()
69 | .header(requestHeaders).body(query).responseString()
70 |
71 | if (response.statusCode != 200) {
72 | throw RequestException(response.statusCode, request, result)
73 | }
74 | return result.get()
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/request/JsonRequest.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.request
2 |
3 | import com.api.igdb.apicalypse.APICalypse
4 | import com.api.igdb.exceptions.RequestException
5 | import com.api.igdb.utils.Endpoints
6 |
7 | @Throws(RequestException::class)
8 | fun IGDBWrapper.jsonAgeRatings(APICalypse: APICalypse): String {
9 | return apiJsonRequest(Endpoints.AGE_RATINGS, APICalypse.buildQuery())
10 | }
11 |
12 | @Throws(RequestException::class)
13 | fun IGDBWrapper.jsonAgeRatingCategories(APICalypse: APICalypse): String {
14 | return apiJsonRequest(Endpoints.AGE_RATING_CATEGORIES, APICalypse.buildQuery())
15 | }
16 |
17 | @Throws(RequestException::class)
18 | fun IGDBWrapper.jsonAgeRatingContentDescriptions(APICalypse: APICalypse): String {
19 | return apiJsonRequest(Endpoints.AGE_RATING_CONTENT_DESCRIPTIONS, APICalypse.buildQuery())
20 | }
21 |
22 | @Throws(RequestException::class)
23 | fun IGDBWrapper.jsonAgeRatingContentDescriptionsV2(APICalypse: APICalypse): String {
24 | return apiJsonRequest(Endpoints.AGE_RATING_CONTENT_DESCRIPTIONS_V2, APICalypse.buildQuery())
25 | }
26 |
27 | @Throws(RequestException::class)
28 | fun IGDBWrapper.jsonAgeRatingOrganizations(APICalypse: APICalypse): String {
29 | return apiJsonRequest(Endpoints.AGE_RATING_ORGANIZATIONS, APICalypse.buildQuery())
30 | }
31 |
32 | @Throws(RequestException::class)
33 | fun IGDBWrapper.jsonAlternativeNames(APICalypse: APICalypse): String {
34 | return apiJsonRequest(Endpoints.ALTERNATIVE_NAMES, APICalypse.buildQuery())
35 | }
36 |
37 | @Throws(RequestException::class)
38 | fun IGDBWrapper.jsonArtworks(APICalypse: APICalypse): String {
39 | return apiJsonRequest(Endpoints.ARTWORKS, APICalypse.buildQuery())
40 | }
41 |
42 | @Throws(RequestException::class)
43 | fun IGDBWrapper.jsonCharacters(APICalypse: APICalypse): String {
44 | return apiJsonRequest(Endpoints.CHARACTERS, APICalypse.buildQuery())
45 | }
46 |
47 | @Throws(RequestException::class)
48 | fun IGDBWrapper.jsonCharacterGenders(APICalypse: APICalypse): String {
49 | return apiJsonRequest(Endpoints.CHARACTER_GENDERS, APICalypse.buildQuery())
50 | }
51 |
52 | @Throws(RequestException::class)
53 | fun IGDBWrapper.jsonCharacterSpecies(APICalypse: APICalypse): String {
54 | return apiJsonRequest(Endpoints.CHARACTER_SPECIES, APICalypse.buildQuery())
55 | }
56 |
57 | @Throws(RequestException::class)
58 | fun IGDBWrapper.jsonCollections(APICalypse: APICalypse): String {
59 | return apiJsonRequest(Endpoints.COLLECTIONS, APICalypse.buildQuery())
60 | }
61 |
62 | @Throws(RequestException::class)
63 | fun IGDBWrapper.jsonCharacterMugShots(APICalypse: APICalypse): String {
64 | return apiJsonRequest(Endpoints.CHARACTER_MUG_SHOTS, APICalypse.buildQuery())
65 | }
66 |
67 | @Throws(RequestException::class)
68 | fun IGDBWrapper.jsonCompanies(APICalypse: APICalypse): String {
69 | return apiJsonRequest(Endpoints.COMPANIES, APICalypse.buildQuery())
70 | }
71 |
72 | @Throws(RequestException::class)
73 | fun IGDBWrapper.jsonCompanyStatuses(APICalypse: APICalypse): String {
74 | return apiJsonRequest(Endpoints.COMPANY_STATUSES, APICalypse.buildQuery())
75 | }
76 |
77 | @Throws(RequestException::class)
78 | fun IGDBWrapper.jsonCompanyWebsites(APICalypse: APICalypse): String {
79 | return apiJsonRequest(Endpoints.COMPANY_WEBSITES, APICalypse.buildQuery())
80 | }
81 |
82 | @Throws(RequestException::class)
83 | fun IGDBWrapper.jsonCompanyLogos(APICalypse: APICalypse): String {
84 | return apiJsonRequest(Endpoints.COMPANY_LOGOS, APICalypse.buildQuery())
85 | }
86 |
87 | @Throws(RequestException::class)
88 | fun IGDBWrapper.jsonCovers(APICalypse: APICalypse): String {
89 | return apiJsonRequest(Endpoints.COVERS, APICalypse.buildQuery())
90 | }
91 |
92 | @Throws(RequestException::class)
93 | fun IGDBWrapper.jsonDateFormats(APICalypse: APICalypse): String {
94 | return apiJsonRequest(Endpoints.DATE_FORMATS, APICalypse.buildQuery())
95 | }
96 |
97 | @Throws(RequestException::class)
98 | fun IGDBWrapper.jsonExternalGames(APICalypse: APICalypse): String {
99 | return apiJsonRequest(Endpoints.EXTERNAL_GAMES, APICalypse.buildQuery())
100 | }
101 |
102 | @Throws(RequestException::class)
103 | fun IGDBWrapper.jsonExternalGameSources(APICalypse: APICalypse): String {
104 | return apiJsonRequest(Endpoints.EXTERNAL_GAME_SOURCES, APICalypse.buildQuery())
105 | }
106 |
107 | @Throws(RequestException::class)
108 | fun IGDBWrapper.jsonFranchises(APICalypse: APICalypse): String {
109 | return apiJsonRequest(Endpoints.FRANCHISES, APICalypse.buildQuery())
110 | }
111 |
112 | @Throws(RequestException::class)
113 | fun IGDBWrapper.jsonGames(APICalypse: APICalypse): String {
114 | return apiJsonRequest(Endpoints.GAMES, APICalypse.buildQuery())
115 | }
116 |
117 | @Throws(RequestException::class)
118 | fun IGDBWrapper.jsonGameEngines(APICalypse: APICalypse): String {
119 | return apiJsonRequest(Endpoints.GAME_ENGINES, APICalypse.buildQuery())
120 | }
121 |
122 | @Throws(RequestException::class)
123 | fun IGDBWrapper.jsonGameEngineLogos(APICalypse: APICalypse): String {
124 | return apiJsonRequest(Endpoints.GAME_ENGINE_LOGOS, APICalypse.buildQuery())
125 | }
126 |
127 | @Throws(RequestException::class)
128 | fun IGDBWrapper.jsonGameLocalizations(APICalypse: APICalypse): String {
129 | return apiJsonRequest(Endpoints.GAME_LOCALIZATIONS, APICalypse.buildQuery())
130 | }
131 |
132 | @Throws(RequestException::class)
133 | fun IGDBWrapper.jsonGameModes(APICalypse: APICalypse): String {
134 | return apiJsonRequest(Endpoints.GAME_MODES, APICalypse.buildQuery())
135 | }
136 |
137 | @Throws(RequestException::class)
138 | fun IGDBWrapper.jsonGameReleaseFormats(APICalypse: APICalypse): String {
139 | return apiJsonRequest(Endpoints.GAME_RELEASE_FORMATS, APICalypse.buildQuery())
140 | }
141 |
142 | @Throws(RequestException::class)
143 | fun IGDBWrapper.jsonGameStatuses(APICalypse: APICalypse): String {
144 | return apiJsonRequest(Endpoints.GAME_STATUSES, APICalypse.buildQuery())
145 | }
146 |
147 | @Throws(RequestException::class)
148 | fun IGDBWrapper.jsonGameTimeToBeats(APICalypse: APICalypse): String {
149 | return apiJsonRequest(Endpoints.GAME_TIME_TO_BEATS, APICalypse.buildQuery())
150 | }
151 |
152 | @Throws(RequestException::class)
153 | fun IGDBWrapper.jsonGameTypes(APICalypse: APICalypse): String {
154 | return apiJsonRequest(Endpoints.GAME_TYPES, APICalypse.buildQuery())
155 | }
156 |
157 | @Throws(RequestException::class)
158 | fun IGDBWrapper.jsonGameVersion(APICalypse: APICalypse): String {
159 | return apiJsonRequest(Endpoints.GAME_VERSIONS, APICalypse.buildQuery())
160 | }
161 |
162 | @Throws(RequestException::class)
163 | fun IGDBWrapper.jsonGameVersionFeatures(APICalypse: APICalypse): String {
164 | return apiJsonRequest(Endpoints.GAME_VERSION_FEATURES, APICalypse.buildQuery())
165 | }
166 |
167 | @Throws(RequestException::class)
168 | fun IGDBWrapper.jsonGameVersionFeatureValues(APICalypse: APICalypse): String {
169 | return apiJsonRequest(Endpoints.GAME_VERSION_FEATURE_VALUES, APICalypse.buildQuery())
170 | }
171 |
172 | @Throws(RequestException::class)
173 | fun IGDBWrapper.jsonGameVideos(APICalypse: APICalypse): String {
174 | return apiJsonRequest(Endpoints.GAME_VIDEOS, APICalypse.buildQuery())
175 | }
176 |
177 | @Throws(RequestException::class)
178 | fun IGDBWrapper.jsonGenres(APICalypse: APICalypse): String {
179 | return apiJsonRequest(Endpoints.GENRES, APICalypse.buildQuery())
180 | }
181 |
182 | @Throws(RequestException::class)
183 | fun IGDBWrapper.jsonInvolvedCompanies(APICalypse: APICalypse): String {
184 | return apiJsonRequest(Endpoints.INVOLVED_COMPANIES, APICalypse.buildQuery())
185 | }
186 |
187 | @Throws(RequestException::class)
188 | fun IGDBWrapper.jsonKeywords(APICalypse: APICalypse): String {
189 | return apiJsonRequest(Endpoints.KEYWORDS, APICalypse.buildQuery())
190 | }
191 |
192 | @Throws(RequestException::class)
193 | fun IGDBWrapper.jsonLanguages(APICalypse: APICalypse): String {
194 | return apiJsonRequest(Endpoints.LANGUAGES, APICalypse.buildQuery())
195 | }
196 |
197 | @Throws(RequestException::class)
198 | fun IGDBWrapper.jsonLanguageSupports(APICalypse: APICalypse): String {
199 | return apiJsonRequest(Endpoints.LANGUAGE_SUPPORTS, APICalypse.buildQuery())
200 | }
201 |
202 | @Throws(RequestException::class)
203 | fun IGDBWrapper.jsonLanguageSupportTypes(APICalypse: APICalypse): String {
204 | return apiJsonRequest(Endpoints.LANGUAGE_SUPPORT_TYPES, APICalypse.buildQuery())
205 | }
206 |
207 | @Throws(RequestException::class)
208 | fun IGDBWrapper.jsonMultiplayerModes(APICalypse: APICalypse): String {
209 | return apiJsonRequest(Endpoints.MULTIPLAYER_MODES, APICalypse.buildQuery())
210 | }
211 |
212 | @Throws(RequestException::class)
213 | fun IGDBWrapper.jsonPlatforms(APICalypse: APICalypse): String {
214 | return apiJsonRequest(Endpoints.PLATFORMS, APICalypse.buildQuery())
215 | }
216 |
217 | @Throws(RequestException::class)
218 | fun IGDBWrapper.jsonPlatformLogos(APICalypse: APICalypse): String {
219 | return apiJsonRequest(Endpoints.PLATFORM_LOGOS, APICalypse.buildQuery())
220 | }
221 |
222 | @Throws(RequestException::class)
223 | fun IGDBWrapper.jsonPlatformTypes(APICalypse: APICalypse): String {
224 | return apiJsonRequest(Endpoints.PLATFORM_TYPES, APICalypse.buildQuery())
225 | }
226 |
227 | @Throws(RequestException::class)
228 | fun IGDBWrapper.jsonPlatformVersions(APICalypse: APICalypse): String {
229 | return apiJsonRequest(Endpoints.PLATFORM_VERSIONS, APICalypse.buildQuery())
230 | }
231 |
232 | @Throws(RequestException::class)
233 | fun IGDBWrapper.jsonPlatformVersionCompanies(APICalypse: APICalypse): String {
234 | return apiJsonRequest(Endpoints.PLATFORM_VERSION_COMPANIES, APICalypse.buildQuery())
235 | }
236 |
237 | @Throws(RequestException::class)
238 | fun IGDBWrapper.jsonRegions(APICalypse: APICalypse): String {
239 | return apiJsonRequest(Endpoints.REGIONS, APICalypse.buildQuery())
240 | }
241 |
242 | @Throws(RequestException::class)
243 | fun IGDBWrapper.jsonPlatformVersionReleaseDates(APICalypse: APICalypse): String {
244 | return apiJsonRequest(Endpoints.PLATFORM_VERSION_RELEASE_DATES, APICalypse.buildQuery())
245 | }
246 |
247 | @Throws(RequestException::class)
248 | fun IGDBWrapper.jsonPlatformWebsites(APICalypse: APICalypse): String {
249 | return apiJsonRequest(Endpoints.PLATFORM_WEBSITES, APICalypse.buildQuery())
250 | }
251 |
252 | @Throws(RequestException::class)
253 | fun IGDBWrapper.jsonPlayerPerspectives(APICalypse: APICalypse): String {
254 | return apiJsonRequest(Endpoints.PLAYER_PERSPECTIVES, APICalypse.buildQuery())
255 | }
256 |
257 | @Throws(RequestException::class)
258 | fun IGDBWrapper.jsonPlatformFamilies(APICalypse: APICalypse): String {
259 | return apiJsonRequest(Endpoints.PLATFORM_FAMILIES, APICalypse.buildQuery())
260 | }
261 |
262 | @Throws(RequestException::class)
263 | fun IGDBWrapper.jsonReleaseDates(APICalypse: APICalypse): String {
264 | return apiJsonRequest(Endpoints.RELEASE_DATES, APICalypse.buildQuery())
265 | }
266 |
267 | @Throws(RequestException::class)
268 | fun IGDBWrapper.jsonReleaseDateRegions(APICalypse: APICalypse): String {
269 | return apiJsonRequest(Endpoints.RELEASE_DATE_REGIONS, APICalypse.buildQuery())
270 | }
271 |
272 | @Throws(RequestException::class)
273 | fun IGDBWrapper.jsonScreenshots(APICalypse: APICalypse): String {
274 | return apiJsonRequest(Endpoints.SCREENSHOTS, APICalypse.buildQuery())
275 | }
276 |
277 | @Throws(RequestException::class)
278 | fun IGDBWrapper.jsonSearch(APICalypse: APICalypse): String {
279 | return apiJsonRequest(Endpoints.SEARCH, APICalypse.buildQuery())
280 | }
281 |
282 | @Throws(RequestException::class)
283 | fun IGDBWrapper.jsonThemes(APICalypse: APICalypse): String {
284 | return apiJsonRequest(Endpoints.THEMES, APICalypse.buildQuery())
285 | }
286 |
287 | @Throws(RequestException::class)
288 | fun IGDBWrapper.jsonWebsites(APICalypse: APICalypse): String {
289 | return apiJsonRequest(Endpoints.WEBSITES, APICalypse.buildQuery())
290 | }
291 |
292 | @Throws(RequestException::class)
293 | fun IGDBWrapper.jsonWebsiteTypes(APICalypse: APICalypse): String {
294 | return apiJsonRequest(Endpoints.WEBSITE_TYPES, APICalypse.buildQuery())
295 | }
296 |
297 | @Throws(RequestException::class)
298 | fun IGDBWrapper.jsonEvents(APICalypse: APICalypse): String {
299 | return apiJsonRequest(Endpoints.EVENTS, APICalypse.buildQuery())
300 | }
301 |
302 | @Throws(RequestException::class)
303 | fun IGDBWrapper.jsonEventLogos(APICalypse: APICalypse): String {
304 | return apiJsonRequest(Endpoints.EVENT_LOGOS, APICalypse.buildQuery())
305 | }
306 |
307 | @Throws(RequestException::class)
308 | fun IGDBWrapper.jsonEventNetworks(APICalypse: APICalypse): String {
309 | return apiJsonRequest(Endpoints.EVENT_NETWORKS, APICalypse.buildQuery())
310 | }
311 |
312 | @Throws(RequestException::class)
313 | fun IGDBWrapper.jsonNetworkTypes(APICalypse: APICalypse): String {
314 | return apiJsonRequest(Endpoints.NETWORK_TYPES, APICalypse.buildQuery())
315 | }
316 |
317 | @Throws(RequestException::class)
318 | fun IGDBWrapper.jsonCollectionRelations(APICalypse: APICalypse): String {
319 | return apiJsonRequest(Endpoints.COLLECTION_RELATIONS, APICalypse.buildQuery())
320 | }
321 |
322 | @Throws(RequestException::class)
323 | fun IGDBWrapper.jsonCollectionRelationTypes(APICalypse: APICalypse): String {
324 | return apiJsonRequest(Endpoints.COLLECTION_RELATION_TYPES, APICalypse.buildQuery())
325 | }
326 |
327 | @Throws(RequestException::class)
328 | fun IGDBWrapper.jsonCollectionTypes(APICalypse: APICalypse): String {
329 | return apiJsonRequest(Endpoints.COLLECTION_TYPES, APICalypse.buildQuery())
330 | }
331 |
332 | @Throws(RequestException::class)
333 | fun IGDBWrapper.jsonCollectionMemberships(APICalypse: APICalypse): String {
334 | return apiJsonRequest(Endpoints.COLLECTION_MEMBERSHIPS, APICalypse.buildQuery())
335 | }
336 |
337 | @Throws(RequestException::class)
338 | fun IGDBWrapper.jsonCollectionMembershipTypes(APICalypse: APICalypse): String {
339 | return apiJsonRequest(Endpoints.COLLECTION_MEMBERSHIP_TYPES, APICalypse.buildQuery())
340 | }
341 |
342 | @Throws(RequestException::class)
343 | fun IGDBWrapper.jsonPopularityTypes(APICalypse: APICalypse): String {
344 | return apiJsonRequest(Endpoints.POPULARITY_TYPES, APICalypse.buildQuery())
345 | }
346 |
347 | @Throws(RequestException::class)
348 | fun IGDBWrapper.jsonPopularityPrimitives(APICalypse: APICalypse): String {
349 | return apiJsonRequest(Endpoints.POPULARITY_PRIMITIVES, APICalypse.buildQuery())
350 | }
351 |
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/request/ProtoRequest.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.request
2 |
3 | import com.api.igdb.apicalypse.APICalypse
4 | import com.api.igdb.exceptions.RequestException
5 | import com.api.igdb.utils.Endpoints
6 | import proto.*
7 | import proto.Collection
8 |
9 |
10 | @Throws(RequestException::class)
11 | fun IGDBWrapper.ageRatings(APICalypse: APICalypse): List {
12 | val bytes = apiProtoRequest(Endpoints.AGE_RATINGS, APICalypse.buildQuery())
13 | return AgeRatingResult.parseFrom(bytes).ageratingsList
14 | }
15 |
16 | @Throws(RequestException::class)
17 | fun IGDBWrapper.ageRatingCategories(APICalypse: APICalypse): List {
18 | val bytes = apiProtoRequest(Endpoints.AGE_RATING_CATEGORIES, APICalypse.buildQuery())
19 | return AgeRatingCategoryResult.parseFrom(bytes).ageratingcategoriesList
20 | }
21 |
22 | @Throws(RequestException::class)
23 | @Deprecated("Use ageRatingContentDescriptionsV2 instead")
24 | fun IGDBWrapper.ageRatingContentDescriptions(APICalypse: APICalypse): List {
25 | val bytes = apiProtoRequest(Endpoints.AGE_RATING_CONTENT_DESCRIPTIONS, APICalypse.buildQuery())
26 | return AgeRatingContentDescriptionResult.parseFrom(bytes).ageratingcontentdescriptionsList
27 | }
28 |
29 | @Throws(RequestException::class)
30 | fun IGDBWrapper.ageRatingContentDescriptionsV2(APICalypse: APICalypse): List {
31 | val bytes = apiProtoRequest(Endpoints.AGE_RATING_CONTENT_DESCRIPTIONS_V2, APICalypse.buildQuery())
32 | return AgeRatingContentDescriptionV2Result.parseFrom(bytes).ageratingcontentdescriptionsv2List
33 | }
34 |
35 | @Throws(RequestException::class)
36 | fun IGDBWrapper.ageRatingOrganizations(APICalypse: APICalypse): List {
37 | val bytes = apiProtoRequest(Endpoints.AGE_RATING_ORGANIZATIONS, APICalypse.buildQuery())
38 | return AgeRatingOrganizationResult.parseFrom(bytes).ageratingorganizationsList
39 | }
40 |
41 | @Throws(RequestException::class)
42 | fun IGDBWrapper.alternativeNames(APICalypse: APICalypse): List {
43 | val bytes = apiProtoRequest(Endpoints.ALTERNATIVE_NAMES, APICalypse.buildQuery())
44 | return AlternativeNameResult.parseFrom(bytes).alternativenamesList
45 | }
46 |
47 | @Throws(RequestException::class)
48 | fun IGDBWrapper.artworks(APICalypse: APICalypse): List {
49 | val bytes = apiProtoRequest(Endpoints.ARTWORKS, APICalypse.buildQuery())
50 | return ArtworkResult.parseFrom(bytes).artworksList
51 | }
52 |
53 | @Throws(RequestException::class)
54 | fun IGDBWrapper.characters(APICalypse: APICalypse): List {
55 | val bytes = apiProtoRequest(Endpoints.CHARACTERS, APICalypse.buildQuery())
56 | return CharacterResult.parseFrom(bytes).charactersList
57 | }
58 |
59 | @Throws(RequestException::class)
60 | fun IGDBWrapper.characterGenders(APICalypse: APICalypse): List {
61 | val bytes = apiProtoRequest(Endpoints.CHARACTER_GENDERS, APICalypse.buildQuery())
62 | return CharacterGenderResult.parseFrom(bytes).charactergendersList
63 | }
64 |
65 | @Throws(RequestException::class)
66 | fun IGDBWrapper.characterSpecies(APICalypse: APICalypse): List {
67 | val bytes = apiProtoRequest(Endpoints.CHARACTER_SPECIES, APICalypse.buildQuery())
68 | return CharacterSpecieResult.parseFrom(bytes).characterspeciesList
69 | }
70 |
71 | @Throws(RequestException::class)
72 | fun IGDBWrapper.collections(APICalypse: APICalypse): List {
73 | val bytes = apiProtoRequest(Endpoints.COLLECTIONS, APICalypse.buildQuery())
74 | return CollectionResult.parseFrom(bytes).collectionsList
75 | }
76 |
77 | @Throws(RequestException::class)
78 | fun IGDBWrapper.characterMugShots(APICalypse: APICalypse): List {
79 | val bytes = apiProtoRequest(Endpoints.CHARACTER_MUG_SHOTS, APICalypse.buildQuery())
80 | return CharacterMugShotResult.parseFrom(bytes).charactermugshotsList
81 | }
82 |
83 | @Throws(RequestException::class)
84 | fun IGDBWrapper.companies(APICalypse: APICalypse): List {
85 | val bytes = apiProtoRequest(Endpoints.COMPANIES, APICalypse.buildQuery())
86 | return CompanyResult.parseFrom(bytes).companiesList
87 | }
88 |
89 | @Throws(RequestException::class)
90 | fun IGDBWrapper.companyStatuses(APICalypse: APICalypse): List {
91 | val bytes = apiProtoRequest(Endpoints.COMPANY_STATUSES, APICalypse.buildQuery())
92 | return CompanyStatusResult.parseFrom(bytes).companystatusesList
93 | }
94 |
95 | @Throws(RequestException::class)
96 | fun IGDBWrapper.companyWebsites(APICalypse: APICalypse): List {
97 | val bytes = apiProtoRequest(Endpoints.COMPANY_WEBSITES, APICalypse.buildQuery())
98 | return CompanyWebsiteResult.parseFrom(bytes).companywebsitesList
99 | }
100 |
101 | @Throws(RequestException::class)
102 | fun IGDBWrapper.companyLogos(APICalypse: APICalypse): List {
103 | val bytes = apiProtoRequest(Endpoints.COMPANY_LOGOS, APICalypse.buildQuery())
104 | return CompanyLogoResult.parseFrom(bytes).companylogosList
105 | }
106 |
107 | @Throws(RequestException::class)
108 | fun IGDBWrapper.covers(APICalypse: APICalypse): List {
109 | val bytes = apiProtoRequest(Endpoints.COVERS, APICalypse.buildQuery())
110 | return CoverResult.parseFrom(bytes).coversList
111 | }
112 |
113 | @Throws(RequestException::class)
114 | fun IGDBWrapper.dateFormats(APICalypse: APICalypse): List {
115 | val bytes = apiProtoRequest(Endpoints.COVERS, APICalypse.buildQuery())
116 | return DateFormatResult.parseFrom(bytes).dateformatsList
117 | }
118 |
119 | @Throws(RequestException::class)
120 | fun IGDBWrapper.externalGames(APICalypse: APICalypse): List {
121 | val bytes = apiProtoRequest(Endpoints.EXTERNAL_GAMES, APICalypse.buildQuery())
122 | return ExternalGameResult.parseFrom(bytes).externalgamesList
123 | }
124 |
125 | @Throws(RequestException::class)
126 | fun IGDBWrapper.externalGameSources(APICalypse: APICalypse): List {
127 | val bytes = apiProtoRequest(Endpoints.EXTERNAL_GAME_SOURCES, APICalypse.buildQuery())
128 | return ExternalGameSourceResult.parseFrom(bytes).externalgamesourcesList
129 | }
130 |
131 | @Throws(RequestException::class)
132 | fun IGDBWrapper.franchises(APICalypse: APICalypse): List {
133 | val bytes = apiProtoRequest(Endpoints.FRANCHISES, APICalypse.buildQuery())
134 | return FranchiseResult.parseFrom(bytes).franchisesList
135 | }
136 |
137 | @Throws(RequestException::class)
138 | fun IGDBWrapper.games(APICalypse: APICalypse): List {
139 | val bytes = apiProtoRequest(Endpoints.GAMES, APICalypse.buildQuery())
140 | return GameResult.parseFrom(bytes).gamesList
141 | }
142 |
143 | @Throws(RequestException::class)
144 | fun IGDBWrapper.gameEngines(APICalypse: APICalypse): List {
145 | val bytes = apiProtoRequest(Endpoints.GAME_ENGINES, APICalypse.buildQuery())
146 | return GameEngineResult.parseFrom(bytes).gameenginesList
147 | }
148 |
149 | @Throws(RequestException::class)
150 | fun IGDBWrapper.gameEngineLogos(APICalypse: APICalypse): List {
151 | val bytes = apiProtoRequest(Endpoints.GAME_ENGINE_LOGOS, APICalypse.buildQuery())
152 | return GameEngineLogoResult.parseFrom(bytes).gameenginelogosList
153 | }
154 |
155 | @Throws(RequestException::class)
156 | fun IGDBWrapper.gameLocalizations(APICalypse: APICalypse): List {
157 | val bytes = apiProtoRequest(Endpoints.GAME_LOCALIZATIONS, APICalypse.buildQuery())
158 | return GameLocalizationResult.parseFrom(bytes).gamelocalizationsList
159 | }
160 |
161 | @Throws(RequestException::class)
162 | fun IGDBWrapper.gameModes(APICalypse: APICalypse): List {
163 | val bytes = apiProtoRequest(Endpoints.GAME_MODES, APICalypse.buildQuery())
164 | return GameModeResult.parseFrom(bytes).gamemodesList
165 | }
166 |
167 | @Throws(RequestException::class)
168 | fun IGDBWrapper.gameReleaseFormats(APICalypse: APICalypse): List {
169 | val bytes = apiProtoRequest(Endpoints.GAME_RELEASE_FORMATS, APICalypse.buildQuery())
170 | return GameReleaseFormatResult.parseFrom(bytes).gamereleaseformatsList
171 | }
172 |
173 | @Throws(RequestException::class)
174 | fun IGDBWrapper.gameStatuses(APICalypse: APICalypse): List {
175 | val bytes = apiProtoRequest(Endpoints.GAME_STATUSES, APICalypse.buildQuery())
176 | return GameStatusResult.parseFrom(bytes).gamestatusesList
177 | }
178 |
179 | @Throws(RequestException::class)
180 | fun IGDBWrapper.gameTimeToBeats(APICalypse: APICalypse): List {
181 | val bytes = apiProtoRequest(Endpoints.GAME_TIME_TO_BEATS, APICalypse.buildQuery())
182 | return GameTimeToBeatResult.parseFrom(bytes).gametimetobeatsList
183 | }
184 |
185 | @Throws(RequestException::class)
186 | fun IGDBWrapper.gameTypes(APICalypse: APICalypse): List {
187 | val bytes = apiProtoRequest(Endpoints.GAME_TYPES, APICalypse.buildQuery())
188 | return GameTypeResult.parseFrom(bytes).gametypesList
189 | }
190 |
191 | @Throws(RequestException::class)
192 | fun IGDBWrapper.gameVersion(APICalypse: APICalypse): List {
193 | val bytes = apiProtoRequest(Endpoints.GAME_VERSIONS, APICalypse.buildQuery())
194 | return GameVersionResult.parseFrom(bytes).gameversionsList
195 | }
196 |
197 | @Throws(RequestException::class)
198 | fun IGDBWrapper.gameVersionFeatures(APICalypse: APICalypse): List {
199 | val bytes = apiProtoRequest(Endpoints.GAME_VERSION_FEATURES, APICalypse.buildQuery())
200 | return GameVersionFeatureResult.parseFrom(bytes).gameversionfeaturesList
201 | }
202 |
203 | @Throws(RequestException::class)
204 | fun IGDBWrapper.gameVersionFeatureValues(APICalypse: APICalypse): List {
205 | val bytes = apiProtoRequest(Endpoints.GAME_VERSION_FEATURE_VALUES, APICalypse.buildQuery())
206 | return GameVersionFeatureValueResult.parseFrom(bytes).gameversionfeaturevaluesList
207 | }
208 |
209 | @Throws(RequestException::class)
210 | fun IGDBWrapper.gameVideos(APICalypse: APICalypse): List {
211 | val bytes = apiProtoRequest(Endpoints.GAME_VIDEOS, APICalypse.buildQuery())
212 | return GameVideoResult.parseFrom(bytes).gamevideosList
213 | }
214 |
215 | @Throws(RequestException::class)
216 | fun IGDBWrapper.genres(APICalypse: APICalypse): List {
217 | val bytes = apiProtoRequest(Endpoints.GENRES, APICalypse.buildQuery())
218 | return GenreResult.parseFrom(bytes).genresList
219 | }
220 |
221 | @Throws(RequestException::class)
222 | fun IGDBWrapper.involvedCompanies(APICalypse: APICalypse): List {
223 | val bytes = apiProtoRequest(Endpoints.INVOLVED_COMPANIES, APICalypse.buildQuery())
224 | return InvolvedCompanyResult.parseFrom(bytes).involvedcompaniesList
225 | }
226 |
227 | @Throws(RequestException::class)
228 | fun IGDBWrapper.keywords(APICalypse: APICalypse): List {
229 | val bytes = apiProtoRequest(Endpoints.KEYWORDS, APICalypse.buildQuery())
230 | return KeywordResult.parseFrom(bytes).keywordsList
231 | }
232 |
233 | @Throws(RequestException::class)
234 | fun IGDBWrapper.languages(APICalypse: APICalypse): List {
235 | val bytes = apiProtoRequest(Endpoints.LANGUAGES, APICalypse.buildQuery())
236 | return LanguageResult.parseFrom(bytes).languagesList
237 | }
238 |
239 | @Throws(RequestException::class)
240 | fun IGDBWrapper.languageSupports(APICalypse: APICalypse): List {
241 | val bytes = apiProtoRequest(Endpoints.LANGUAGE_SUPPORTS, APICalypse.buildQuery())
242 | return LanguageSupportResult.parseFrom(bytes).languagesupportsList
243 | }
244 |
245 | @Throws(RequestException::class)
246 | fun IGDBWrapper.languageSupportTypes(APICalypse: APICalypse): List {
247 | val bytes = apiProtoRequest(Endpoints.LANGUAGE_SUPPORT_TYPES, APICalypse.buildQuery())
248 | return LanguageSupportTypeResult.parseFrom(bytes).languagesupporttypesList
249 | }
250 |
251 | @Throws(RequestException::class)
252 | fun IGDBWrapper.multiplayerModes(APICalypse: APICalypse): List {
253 | val bytes = apiProtoRequest(Endpoints.MULTIPLAYER_MODES, APICalypse.buildQuery())
254 | return MultiplayerModeResult.parseFrom(bytes).multiplayermodesList
255 | }
256 |
257 | @Throws(RequestException::class)
258 | fun IGDBWrapper.platforms(APICalypse: APICalypse): List {
259 | val bytes = apiProtoRequest(Endpoints.PLATFORMS, APICalypse.buildQuery())
260 | return PlatformResult.parseFrom(bytes).platformsList
261 | }
262 |
263 | @Throws(RequestException::class)
264 | fun IGDBWrapper.platformLogos(APICalypse: APICalypse): List {
265 | val bytes = apiProtoRequest(Endpoints.PLATFORM_LOGOS, APICalypse.buildQuery())
266 | return PlatformLogoResult.parseFrom(bytes).platformlogosList
267 | }
268 |
269 | @Throws(RequestException::class)
270 | fun IGDBWrapper.platformTypes(APICalypse: APICalypse): List {
271 | val bytes = apiProtoRequest(Endpoints.PLATFORM_TYPES, APICalypse.buildQuery())
272 | return PlatformTypeResult.parseFrom(bytes).platformtypesList
273 | }
274 |
275 | @Throws(RequestException::class)
276 | fun IGDBWrapper.platformVersions(APICalypse: APICalypse): List {
277 | val bytes = apiProtoRequest(Endpoints.PLATFORM_VERSIONS, APICalypse.buildQuery())
278 | return PlatformVersionResult.parseFrom(bytes).platformversionsList
279 | }
280 |
281 | @Throws(RequestException::class)
282 | fun IGDBWrapper.platformVersionCompanies(APICalypse: APICalypse): List {
283 | val bytes = apiProtoRequest(Endpoints.PLATFORM_VERSION_COMPANIES, APICalypse.buildQuery())
284 | return PlatformVersionCompanyResult.parseFrom(bytes).platformversioncompaniesList
285 | }
286 |
287 | @Throws(RequestException::class)
288 | fun IGDBWrapper.platformVersionReleaseDates(APICalypse: APICalypse): List {
289 | val bytes = apiProtoRequest(Endpoints.PLATFORM_VERSION_RELEASE_DATES, APICalypse.buildQuery())
290 | return PlatformVersionReleaseDateResult.parseFrom(bytes).platformversionreleasedatesList
291 | }
292 |
293 | @Throws(RequestException::class)
294 | fun IGDBWrapper.platformWebsites(APICalypse: APICalypse): List {
295 | val bytes = apiProtoRequest(Endpoints.PLATFORM_WEBSITES, APICalypse.buildQuery())
296 | return PlatformWebsiteResult.parseFrom(bytes).platformwebsitesList
297 | }
298 |
299 | @Throws(RequestException::class)
300 | fun IGDBWrapper.playerPerspectives(APICalypse: APICalypse): List {
301 | val bytes = apiProtoRequest(Endpoints.PLAYER_PERSPECTIVES, APICalypse.buildQuery())
302 | return PlayerPerspectiveResult.parseFrom(bytes).playerperspectivesList
303 | }
304 |
305 | @Throws(RequestException::class)
306 | fun IGDBWrapper.platformFamilies(APICalypse: APICalypse): List {
307 | val bytes = apiProtoRequest(Endpoints.PLATFORM_FAMILIES, APICalypse.buildQuery())
308 | return PlatformFamilyResult.parseFrom(bytes).platformfamiliesList
309 | }
310 |
311 | @Throws(RequestException::class)
312 | fun IGDBWrapper.regions(APICalypse: APICalypse): List {
313 | val bytes = apiProtoRequest(Endpoints.REGIONS, APICalypse.buildQuery())
314 | return RegionResult.parseFrom(bytes).regionsList
315 | }
316 |
317 | @Throws(RequestException::class)
318 | fun IGDBWrapper.releaseDates(APICalypse: APICalypse): List {
319 | val bytes = apiProtoRequest(Endpoints.RELEASE_DATES, APICalypse.buildQuery())
320 | return ReleaseDateResult.parseFrom(bytes).releasedatesList
321 | }
322 |
323 | @Throws(RequestException::class)
324 | fun IGDBWrapper.releaseDateRegions(APICalypse: APICalypse): List {
325 | val bytes = apiProtoRequest(Endpoints.RELEASE_DATE_REGIONS, APICalypse.buildQuery())
326 | return ReleaseDateRegionResult.parseFrom(bytes).releasedateregionsList
327 | }
328 |
329 | @Throws(RequestException::class)
330 | fun IGDBWrapper.screenshots(APICalypse: APICalypse): List {
331 | val bytes = apiProtoRequest(Endpoints.SCREENSHOTS, APICalypse.buildQuery())
332 | return ScreenshotResult.parseFrom(bytes).screenshotsList
333 | }
334 |
335 | @Throws(RequestException::class)
336 | fun IGDBWrapper.search(APICalypse: APICalypse): List {
337 | val bytes = apiProtoRequest(Endpoints.SEARCH, APICalypse.buildQuery())
338 | return SearchResult.parseFrom(bytes).searchesList
339 | }
340 |
341 | @Throws(RequestException::class)
342 | fun IGDBWrapper.themes(APICalypse: APICalypse): List {
343 | val bytes = apiProtoRequest(Endpoints.THEMES, APICalypse.buildQuery())
344 | return ThemeResult.parseFrom(bytes).themesList
345 | }
346 |
347 | @Throws(RequestException::class)
348 | fun IGDBWrapper.websites(APICalypse: APICalypse): List {
349 | val bytes = apiProtoRequest(Endpoints.WEBSITES, APICalypse.buildQuery())
350 | return WebsiteResult.parseFrom(bytes).websitesList
351 | }
352 |
353 | @Throws(RequestException::class)
354 | fun IGDBWrapper.websiteTypes(APICalypse: APICalypse): List {
355 | val bytes = apiProtoRequest(Endpoints.WEBSITE_TYPES, APICalypse.buildQuery())
356 | return WebsiteTypeResult.parseFrom(bytes).websitetypesList
357 | }
358 |
359 | @Throws(RequestException::class)
360 | fun IGDBWrapper.events(APICalypse: APICalypse): List {
361 | val bytes = apiProtoRequest(Endpoints.EVENTS, APICalypse.buildQuery())
362 | return EventResult.parseFrom(bytes).eventsList
363 | }
364 |
365 | @Throws(RequestException::class)
366 | fun IGDBWrapper.eventLogos(APICalypse: APICalypse): List {
367 | val bytes = apiProtoRequest(Endpoints.EVENT_LOGOS, APICalypse.buildQuery())
368 | return EventLogoResult.parseFrom(bytes).eventlogosList
369 | }
370 |
371 | @Throws(RequestException::class)
372 | fun IGDBWrapper.eventNetworks(APICalypse: APICalypse): List {
373 | val bytes = apiProtoRequest(Endpoints.EVENT_NETWORKS, APICalypse.buildQuery())
374 | return EventNetworkResult.parseFrom(bytes).eventnetworksList
375 | }
376 |
377 | @Throws(RequestException::class)
378 | fun IGDBWrapper.networkTypes(APICalypse: APICalypse): List {
379 | val bytes = apiProtoRequest(Endpoints.NETWORK_TYPES, APICalypse.buildQuery())
380 | return NetworkTypeResult.parseFrom(bytes).networktypesList
381 | }
382 |
383 | @Throws(RequestException::class)
384 | fun IGDBWrapper.collectionRelations(APICalypse: APICalypse): List {
385 | val bytes = apiProtoRequest(Endpoints.COLLECTION_RELATIONS, APICalypse.buildQuery())
386 | return CollectionRelationResult.parseFrom(bytes).collectionrelationsList
387 | }
388 |
389 | @Throws(RequestException::class)
390 | fun IGDBWrapper.collectionRelationTypes(APICalypse: APICalypse): List {
391 | val bytes = apiProtoRequest(Endpoints.COLLECTION_RELATION_TYPES, APICalypse.buildQuery())
392 | return CollectionRelationTypeResult.parseFrom(bytes).collectionrelationtypesList
393 | }
394 |
395 | @Throws(RequestException::class)
396 | fun IGDBWrapper.collectionTypes(APICalypse: APICalypse): List {
397 | val bytes = apiProtoRequest(Endpoints.COLLECTION_TYPES, APICalypse.buildQuery())
398 | return CollectionTypeResult.parseFrom(bytes).collectiontypesList
399 | }
400 |
401 | @Throws(RequestException::class)
402 | fun IGDBWrapper.collectionMemberships(APICalypse: APICalypse): List {
403 | val bytes = apiProtoRequest(Endpoints.COLLECTION_MEMBERSHIPS, APICalypse.buildQuery())
404 | return CollectionMembershipResult.parseFrom(bytes).collectionmembershipsList
405 | }
406 |
407 | @Throws(RequestException::class)
408 | fun IGDBWrapper.collectionMembershipTypes(APICalypse: APICalypse): List {
409 | val bytes = apiProtoRequest(Endpoints.COLLECTION_MEMBERSHIP_TYPES, APICalypse.buildQuery())
410 | return CollectionMembershipTypeResult.parseFrom(bytes).collectionmembershiptypesList
411 | }
412 |
413 | @Throws(RequestException::class)
414 | fun IGDBWrapper.popularityTypes(APICalypse: APICalypse): List {
415 | val bytes = apiProtoRequest(Endpoints.POPULARITY_TYPES, APICalypse.buildQuery())
416 | return PopularityTypeResult.parseFrom(bytes).popularitytypesList
417 | }
418 |
419 | @Throws(RequestException::class)
420 | fun IGDBWrapper.popularityPrimitives(APICalypse: APICalypse): List {
421 | val bytes = apiProtoRequest(Endpoints.POPULARITY_PRIMITIVES, APICalypse.buildQuery())
422 | return PopularityPrimitiveResult.parseFrom(bytes).popularityprimitivesList
423 | }
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/request/TwitchAuthenticator.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.request
2 |
3 | import com.api.igdb.utils.TwitchToken
4 | import com.github.kittinunf.fuel.gson.responseObject
5 | import com.github.kittinunf.fuel.httpPost
6 | import com.github.kittinunf.result.Result
7 | import java.io.Serializable
8 | import kotlin.properties.Delegates
9 |
10 | object TwitchAuthenticator {
11 | private const val twitchOauthTokenURL = "https://id.twitch.tv/oauth2/token"
12 | private const val twitchGrantType = "client_credentials"
13 |
14 | private var twitchClientID: String = ""
15 | private var twitchClientSecret: String = ""
16 | private var twitchToken: TwitchToken? = null
17 |
18 | /**
19 | * The Twitch OAuth request function
20 | *
21 | * @property clientID Your application client_id found in the Twitch Developer Portal
22 | * @property clientSecret Your application client_secret found in the Twitch Developer Portal
23 | * @return The Twitch token response object, if successful otherwise null
24 | */
25 | fun requestTwitchToken(clientID: String, clientSecret: String): TwitchToken? {
26 | val parameters = listOf("client_id" to clientID, "client_secret" to clientSecret,
27 | "grant_type" to twitchGrantType)
28 | val (_, _, result) = twitchOauthTokenURL.httpPost(parameters)
29 | .responseObject()
30 |
31 | twitchToken = when (result) {
32 | is Result.Failure -> {
33 | null
34 | }
35 | is Result.Success -> {
36 | result.get()
37 | }
38 | }
39 | return twitchToken
40 | }
41 |
42 | }
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/utils/Endpoint.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.utils
2 |
3 | interface Endpoint {
4 | fun url(): String
5 | }
6 |
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/utils/Endpoints.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.utils
2 |
3 | /**
4 | * The Public Endpoint Enum class holds all of the accessible IGDB API Endpoints
5 | */
6 | enum class Endpoints : Endpoint {
7 | AGE_RATING_CATEGORIES, AGE_RATING_CONTENT_DESCRIPTIONS, AGE_RATING_CONTENT_DESCRIPTIONS_V2, AGE_RATING_ORGANIZATIONS, AGE_RATINGS,
8 | ALTERNATIVE_NAMES, ARTWORKS, CHARACTERS, CHARACTER_GENDERS, CHARACTER_MUG_SHOTS, CHARACTER_SPECIES, COLLECTION_MEMBERSHIPS,
9 | COLLECTION_MEMBERSHIP_TYPES, COLLECTION_RELATIONS, COLLECTION_RELATION_TYPES, COLLECTION_TYPES, COLLECTIONS, COMPANIES,
10 | COMPANY_LOGOS, COMPANY_STATUSES, COMPANY_WEBSITES, COVERS, DATE_FORMATS, EVENTS, EVENT_LOGOS,
11 | EVENT_NETWORKS, EXTERNAL_GAMES, EXTERNAL_GAME_SOURCES, FRANCHISES, GAMES, GAME_ENGINES, GAME_ENGINE_LOGOS, GAME_LOCALIZATIONS,
12 | GAME_MODES, GAME_RELEASE_FORMATS, GAME_STATUSES, GAME_TIME_TO_BEATS, GAME_TYPES, GAME_VERSIONS, GAME_VERSION_FEATURES, GAME_VERSION_FEATURE_VALUES,
13 | GAME_VIDEOS, GENRES, INVOLVED_COMPANIES, KEYWORDS, LANGUAGES, LANGUAGE_SUPPORTS, LANGUAGE_SUPPORT_TYPES, MULTIPLAYER_MODES,
14 | NETWORK_TYPES, PLATFORMS, PLATFORM_FAMILIES, PLATFORM_LOGOS, PLATFORM_TYPES, PLATFORM_VERSIONS, PLATFORM_VERSION_COMPANIES,
15 | PLATFORM_VERSION_RELEASE_DATES, PLATFORM_WEBSITES, PLAYER_PERSPECTIVES, POPULARITY_PRIMITIVES, POPULARITY_TYPES, REGIONS,
16 | RELEASE_DATES, RELEASE_DATE_REGIONS, SCREENSHOTS, SEARCH, THEMES, WEBSITES, WEBSITE_TYPES;
17 |
18 | override fun url(): String {
19 | return "/${this.name.lowercase()}"
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/utils/ImageBuilder.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.utils
2 |
3 | private const val IGDB_IMAGE_URL = "https://images.igdb.com/igdb/image/upload/"
4 |
5 | /**
6 | * The image builder function builds image urls
7 | *
8 | * @property imageID The image ID from the IGDB API
9 | * @property size The size of the image
10 | * @property imageType The file type of the image, default PNG
11 | * @return The complete image url in string
12 | */
13 | fun imageBuilder(imageID: String, size: ImageSize, imageType: ImageType = ImageType.PNG): String {
14 | return "$IGDB_IMAGE_URL${size.tSize}/$imageID.${imageType.type}"
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/utils/ImageSize.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.utils
2 |
3 | /*
4 | * The image size options from the IGDB API
5 | * */
6 | enum class ImageSize(val tSize: String) {
7 | MICRO("t_micro"), // 35 x 35 Thumb, Center gravity
8 | THUMB("t_thumb"), // 90 x 90 Thumb, Center gravity
9 | COVER_SMALL("t_cover_small"), // 90 x 128 Fit
10 | COVER_BIG("t_cover_big"), // 264 x 374 Fit
11 | LOGO_MEDIUM("t_logo_med"), // 284 x 160 Fit
12 | SCREENSHOT_MEDIUM("t_screenshot_med"), // 569 x 320 Lfill, Center gravity
13 | SCREENSHOT_BIG("t_screenshot_big"), // 889 x 500 Lfill, Center gravity
14 | SCREENSHOT_HUGE("t_screenshot_huge"), // 1280 x 720 Lfill, Center gravity
15 | HD("t_720p"), // 1280 x 720 Fit, Center gravity
16 | FHD("t_1080p") // 1920 x 1080 Fit, Center gravity
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/utils/ImageType.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.utils
2 |
3 | /*
4 | * The Image types offered by the IGDB API
5 | * */
6 | enum class ImageType(val type: String) {
7 | JPEG("jpg"),
8 | PNG("png"),
9 | GIF("gif"),
10 | WEBP("webp")
11 | }
12 |
--------------------------------------------------------------------------------
/src/main/kotlin/com/api/igdb/utils/TwitchToken.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb.utils
2 |
3 | import java.io.Serializable
4 | import kotlin.properties.Delegates
5 |
6 | /**
7 | * The Twitch OAuth object used to serialize the oauth response
8 | *
9 | * @property access_token Your Twitch Access Token
10 | * @property expires_in The token expiry time
11 | * @property token_type The token type
12 | */
13 | data class TwitchToken(
14 | val access_token: String,
15 | val expires_in: Long,
16 | val token_type: String
17 | ): Serializable {
18 | private var expiresAt: Long
19 |
20 | init {
21 | val currentTime = System.currentTimeMillis()
22 | val expiresAtMillis = expires_in * 1000
23 | expiresAt = currentTime + expiresAtMillis
24 | }
25 |
26 | fun getExpiresUnix() = expiresAt
27 | }
--------------------------------------------------------------------------------
/src/resources/com/api/igdb/igdbproto.proto:
--------------------------------------------------------------------------------
1 |
2 | syntax = "proto3";
3 |
4 | package proto;
5 |
6 | import "google/protobuf/timestamp.proto";
7 |
8 | option java_multiple_files = true; // Must be true because of private access in files.
9 | option optimize_for = CODE_SIZE;
10 |
11 | message Count {
12 | int64 count = 1;
13 | }
14 |
15 | message MultiQueryResult {
16 | string name = 1;
17 | repeated bytes results = 2;
18 | int64 count = 3;
19 | }
20 |
21 | message MultiQueryResultArray {
22 | repeated MultiQueryResult result = 1;
23 | }
24 |
25 | message AgeRatingResult {
26 | repeated AgeRating ageratings = 1;
27 | }
28 |
29 | message AgeRating {
30 | uint64 id = 1;
31 | AgeRatingCategoryEnum category = 2 [deprecated = true];
32 | repeated AgeRatingContentDescription content_descriptions = 3;
33 | AgeRatingRatingEnum rating = 4 [deprecated = true];
34 | string rating_cover_url = 5;
35 | string synopsis = 6;
36 | string checksum = 7;
37 | AgeRatingOrganization organization = 8;
38 | AgeRatingCategory rating_category = 9;
39 | repeated AgeRatingContentDescriptionV2 rating_content_descriptions = 10;
40 | }
41 |
42 |
43 | enum AgeRatingCategoryEnum {
44 | AGERATING_CATEGORY_NULL = 0 [deprecated = true];
45 | ESRB = 1 [deprecated = true];
46 | PEGI = 2 [deprecated = true];
47 | CERO = 3 [deprecated = true];
48 | USK = 4 [deprecated = true];
49 | GRAC = 5 [deprecated = true];
50 | CLASS_IND = 6 [deprecated = true];
51 | ACB = 7 [deprecated = true];
52 | }
53 |
54 |
55 | enum AgeRatingRatingEnum {
56 | AGERATING_RATING_NULL = 0 [deprecated = true];
57 | THREE = 1 [deprecated = true];
58 | SEVEN = 2 [deprecated = true];
59 | TWELVE = 3 [deprecated = true];
60 | SIXTEEN = 4 [deprecated = true];
61 | EIGHTEEN = 5 [deprecated = true];
62 | RP = 6 [deprecated = true];
63 | EC = 7 [deprecated = true];
64 | E = 8 [deprecated = true];
65 | E10 = 9 [deprecated = true];
66 | T = 10 [deprecated = true];
67 | M = 11 [deprecated = true];
68 | AO = 12 [deprecated = true];
69 | CERO_A = 13 [deprecated = true];
70 | CERO_B = 14 [deprecated = true];
71 | CERO_C = 15 [deprecated = true];
72 | CERO_D = 16 [deprecated = true];
73 | CERO_Z = 17 [deprecated = true];
74 | USK_0 = 18 [deprecated = true];
75 | USK_6 = 19 [deprecated = true];
76 | USK_12 = 20 [deprecated = true];
77 | USK_16 = 21 [deprecated = true];
78 | USK_18 = 22 [deprecated = true];
79 | GRAC_ALL = 23 [deprecated = true];
80 | GRAC_TWELVE = 24 [deprecated = true];
81 | GRAC_FIFTEEN = 25 [deprecated = true];
82 | GRAC_EIGHTEEN = 26 [deprecated = true];
83 | GRAC_TESTING = 27 [deprecated = true];
84 | CLASS_IND_L = 28 [deprecated = true];
85 | CLASS_IND_TEN = 29 [deprecated = true];
86 | CLASS_IND_TWELVE = 30 [deprecated = true];
87 | CLASS_IND_FOURTEEN = 31 [deprecated = true];
88 | CLASS_IND_SIXTEEN = 32 [deprecated = true];
89 | CLASS_IND_EIGHTEEN = 33 [deprecated = true];
90 | ACB_G = 34 [deprecated = true];
91 | ACB_PG = 35 [deprecated = true];
92 | ACB_M = 36 [deprecated = true];
93 | ACB_MA15 = 37 [deprecated = true];
94 | ACB_R18 = 38 [deprecated = true];
95 | ACB_RC = 39 [deprecated = true];
96 | }
97 |
98 | message AgeRatingCategoryResult {
99 | repeated AgeRatingCategory ageratingcategories = 1;
100 | }
101 |
102 | message AgeRatingCategory {
103 | uint64 id = 1;
104 | string rating = 2;
105 | AgeRatingOrganization organization = 3;
106 | google.protobuf.Timestamp created_at = 4;
107 | google.protobuf.Timestamp updated_at = 5;
108 | string checksum = 6;
109 | }
110 |
111 | message AgeRatingContentDescriptionResult {
112 | repeated AgeRatingContentDescription ageratingcontentdescriptions = 1;
113 | }
114 |
115 | message AgeRatingContentDescription {
116 | uint64 id = 1;
117 | AgeRatingContentDescriptionCategoryEnum category = 2 [deprecated = true];
118 | string description = 3;
119 | string checksum = 4;
120 | }
121 |
122 |
123 | enum AgeRatingContentDescriptionCategoryEnum {
124 | AGERATINGCONTENTDESCRIPTION_CATEGORY_NULL = 0 [deprecated = true];
125 | ESRB_ALCOHOL_REFERENCE = 1 [deprecated = true];
126 | ESRB_ANIMATED_BLOOD = 2 [deprecated = true];
127 | ESRB_BLOOD = 3 [deprecated = true];
128 | ESRB_BLOOD_AND_GORE = 4 [deprecated = true];
129 | ESRB_CARTOON_VIOLENCE = 5 [deprecated = true];
130 | ESRB_COMIC_MISCHIEF = 6 [deprecated = true];
131 | ESRB_CRUDE_HUMOR = 7 [deprecated = true];
132 | ESRB_DRUG_REFERENCE = 8 [deprecated = true];
133 | ESRB_FANTASY_VIOLENCE = 9 [deprecated = true];
134 | ESRB_INTENSE_VIOLENCE = 10 [deprecated = true];
135 | ESRB_LANGUAGE = 11 [deprecated = true];
136 | ESRB_LYRICS = 12 [deprecated = true];
137 | ESRB_MATURE_HUMOR = 13 [deprecated = true];
138 | ESRB_NUDITY = 14 [deprecated = true];
139 | ESRB_PARTIAL_NUDITY = 15 [deprecated = true];
140 | ESRB_REAL_GAMBLING = 16 [deprecated = true];
141 | ESRB_SEXUAL_CONTENT = 17 [deprecated = true];
142 | ESRB_SEXUAL_THEMES = 18 [deprecated = true];
143 | ESRB_SEXUAL_VIOLENCE = 19 [deprecated = true];
144 | ESRB_SIMULATED_GAMBLING = 20 [deprecated = true];
145 | ESRB_STRONG_LANGUAGE = 21 [deprecated = true];
146 | ESRB_STRONG_LYRICS = 22 [deprecated = true];
147 | ESRB_STRONG_SEXUAL_CONTENT = 23 [deprecated = true];
148 | ESRB_SUGGESTIVE_THEMES = 24 [deprecated = true];
149 | ESRB_TOBACCO_REFERENCE = 25 [deprecated = true];
150 | ESRB_USE_OF_ALCOHOL = 26 [deprecated = true];
151 | ESRB_USE_OF_DRUGS = 27 [deprecated = true];
152 | ESRB_USE_OF_TOBACCO = 28 [deprecated = true];
153 | ESRB_VIOLENCE = 29 [deprecated = true];
154 | ESRB_VIOLENT_REFERENCES = 30 [deprecated = true];
155 | ESRB_ANIMATED_VIOLENCE = 31 [deprecated = true];
156 | ESRB_MILD_LANGUAGE = 32 [deprecated = true];
157 | ESRB_MILD_VIOLENCE = 33 [deprecated = true];
158 | ESRB_USE_OF_DRUGS_AND_ALCOHOL = 34 [deprecated = true];
159 | ESRB_DRUG_AND_ALCOHOL_REFERENCE = 35 [deprecated = true];
160 | ESRB_MILD_SUGGESTIVE_THEMES = 36 [deprecated = true];
161 | ESRB_MILD_CARTOON_VIOLENCE = 37 [deprecated = true];
162 | ESRB_MILD_BLOOD = 38 [deprecated = true];
163 | ESRB_REALISTIC_BLOOD_AND_GORE = 39 [deprecated = true];
164 | ESRB_REALISTIC_VIOLENCE = 40 [deprecated = true];
165 | ESRB_ALCOHOL_AND_TOBACCO_REFERENCE = 41 [deprecated = true];
166 | ESRB_MATURE_SEXUAL_THEMES = 42 [deprecated = true];
167 | ESRB_MILD_ANIMATED_VIOLENCE = 43 [deprecated = true];
168 | ESRB_MILD_SEXUAL_THEMES = 44 [deprecated = true];
169 | ESRB_USE_OF_ALCOHOL_AND_TOBACCO = 45 [deprecated = true];
170 | ESRB_ANIMATED_BLOOD_AND_GORE = 46 [deprecated = true];
171 | ESRB_MILD_FANTASY_VIOLENCE = 47 [deprecated = true];
172 | ESRB_MILD_LYRICS = 48 [deprecated = true];
173 | ESRB_REALISTIC_BLOOD = 49 [deprecated = true];
174 | PEGI_VIOLENCE = 50 [deprecated = true];
175 | PEGI_SEX = 51 [deprecated = true];
176 | PEGI_DRUGS = 52 [deprecated = true];
177 | PEGI_FEAR = 53 [deprecated = true];
178 | PEGI_DISCRIMINATION = 54 [deprecated = true];
179 | PEGI_BAD_LANGUAGE = 55 [deprecated = true];
180 | PEGI_GAMBLING = 56 [deprecated = true];
181 | PEGI_ONLINE_GAMEPLAY = 57 [deprecated = true];
182 | PEGI_IN_GAME_PURCHASES = 58 [deprecated = true];
183 | CERO_LOVE = 59 [deprecated = true];
184 | CERO_SEXUAL_CONTENT = 60 [deprecated = true];
185 | CERO_VIOLENCE = 61 [deprecated = true];
186 | CERO_HORROR = 62 [deprecated = true];
187 | CERO_DRINKING_SMOKING = 63 [deprecated = true];
188 | CERO_GAMBLING = 64 [deprecated = true];
189 | CERO_CRIME = 65 [deprecated = true];
190 | CERO_CONTROLLED_SUBSTANCES = 66 [deprecated = true];
191 | CERO_LANGUAGES_AND_OTHERS = 67 [deprecated = true];
192 | GRAC_SEXUALITY = 68 [deprecated = true];
193 | GRAC_VIOLENCE = 69 [deprecated = true];
194 | GRAC_FEAR_HORROR_THREATENING = 70 [deprecated = true];
195 | GRAC_LANGUAGE = 71 [deprecated = true];
196 | GRAC_ALCOHOL_TOBACCO_DRUG = 72 [deprecated = true];
197 | GRAC_CRIME_ANTI_SOCIAL = 73 [deprecated = true];
198 | GRAC_GAMBLING = 74 [deprecated = true];
199 | CLASS_IND_VIOLENCIA = 75 [deprecated = true];
200 | CLASS_IND_VIOLENCIA_EXTREMA = 76 [deprecated = true];
201 | CLASS_IND_CONTEUDO_SEXUAL = 77 [deprecated = true];
202 | CLASS_IND_NUDEZ = 78 [deprecated = true];
203 | CLASS_IND_SEXO = 79 [deprecated = true];
204 | CLASS_IND_SEXO_EXPLICITO = 80 [deprecated = true];
205 | CLASS_IND_DROGAS = 81 [deprecated = true];
206 | CLASS_IND_DROGAS_LICITAS = 82 [deprecated = true];
207 | CLASS_IND_DROGAS_ILICITAS = 83 [deprecated = true];
208 | CLASS_IND_LINGUAGEM_IMPROPRIA = 84 [deprecated = true];
209 | CLASS_IND_ATOS_CRIMINOSOS = 85 [deprecated = true];
210 | }
211 |
212 | message AgeRatingContentDescriptionV2Result {
213 | repeated AgeRatingContentDescriptionV2 ageratingcontentdescriptionsv2 = 1;
214 | }
215 |
216 | message AgeRatingContentDescriptionV2 {
217 | uint64 id = 1;
218 | string description = 2;
219 | AgeRatingOrganization organization = 3;
220 | google.protobuf.Timestamp created_at = 4;
221 | google.protobuf.Timestamp updated_at = 5;
222 | string checksum = 6;
223 | }
224 |
225 | message AgeRatingOrganizationResult {
226 | repeated AgeRatingOrganization ageratingorganizations = 1;
227 | }
228 |
229 | message AgeRatingOrganization {
230 | uint64 id = 1;
231 | string name = 2;
232 | google.protobuf.Timestamp created_at = 3;
233 | google.protobuf.Timestamp updated_at = 4;
234 | string checksum = 5;
235 | }
236 |
237 | message AlternativeNameResult {
238 | repeated AlternativeName alternativenames = 1;
239 | }
240 |
241 | message AlternativeName {
242 | uint64 id = 1;
243 | string comment = 2;
244 | Game game = 3;
245 | string name = 4;
246 | string checksum = 5;
247 | }
248 |
249 | message ArtworkResult {
250 | repeated Artwork artworks = 1;
251 | }
252 |
253 | message Artwork {
254 | uint64 id = 1;
255 | bool alpha_channel = 2;
256 | bool animated = 3;
257 | Game game = 4;
258 | int32 height = 5;
259 | string image_id = 6;
260 | string url = 7;
261 | int32 width = 8;
262 | string checksum = 9;
263 | }
264 |
265 | message CharacterResult {
266 | repeated Character characters = 1;
267 | }
268 |
269 | message Character {
270 | uint64 id = 1;
271 | repeated string akas = 2;
272 | string country_name = 3;
273 | google.protobuf.Timestamp created_at = 4;
274 | string description = 5;
275 | repeated Game games = 6;
276 | GenderGenderEnum gender = 7 [deprecated = true];
277 | CharacterMugShot mug_shot = 8;
278 | string name = 9;
279 | string slug = 10;
280 | CharacterSpeciesEnum species = 11 [deprecated = true];
281 | google.protobuf.Timestamp updated_at = 12;
282 | string url = 13;
283 | string checksum = 14;
284 | CharacterGender character_gender = 15;
285 | CharacterSpecie character_species = 16;
286 | }
287 |
288 |
289 | enum GenderGenderEnum {
290 | MALE = 0 [deprecated = true];
291 | FEMALE = 1 [deprecated = true];
292 | OTHER = 2 [deprecated = true];
293 | }
294 |
295 |
296 | enum CharacterSpeciesEnum {
297 | CHARACTER_SPECIES_NULL = 0 [deprecated = true];
298 | HUMAN = 1 [deprecated = true];
299 | ALIEN = 2 [deprecated = true];
300 | ANIMAL = 3 [deprecated = true];
301 | ANDROID = 4 [deprecated = true];
302 | UNKNOWN = 5 [deprecated = true];
303 | }
304 |
305 | message CharacterGenderResult {
306 | repeated CharacterGender charactergenders = 1;
307 | }
308 |
309 | message CharacterGender {
310 | uint64 id = 1;
311 | string name = 2;
312 | google.protobuf.Timestamp created_at = 3;
313 | google.protobuf.Timestamp updated_at = 4;
314 | string checksum = 5;
315 | }
316 |
317 | message CharacterMugShotResult {
318 | repeated CharacterMugShot charactermugshots = 1;
319 | }
320 |
321 | message CharacterMugShot {
322 | uint64 id = 1;
323 | bool alpha_channel = 2;
324 | bool animated = 3;
325 | int32 height = 4;
326 | string image_id = 5;
327 | string url = 6;
328 | int32 width = 7;
329 | string checksum = 8;
330 | }
331 |
332 | message CharacterSpecieResult {
333 | repeated CharacterSpecie characterspecies = 1;
334 | }
335 |
336 | message CharacterSpecie {
337 | uint64 id = 1;
338 | string name = 2;
339 | google.protobuf.Timestamp created_at = 3;
340 | google.protobuf.Timestamp updated_at = 4;
341 | string checksum = 5;
342 | }
343 |
344 | message CollectionResult {
345 | repeated Collection collections = 1;
346 | }
347 |
348 | message Collection {
349 | uint64 id = 1;
350 | google.protobuf.Timestamp created_at = 2;
351 | repeated Game games = 3;
352 | string name = 4;
353 | string slug = 5;
354 | google.protobuf.Timestamp updated_at = 6;
355 | string url = 7;
356 | string checksum = 8;
357 | CollectionType type = 9;
358 | repeated CollectionRelation as_parent_relations = 10;
359 | repeated CollectionRelation as_child_relations = 11;
360 | }
361 |
362 | message CollectionMembershipResult {
363 | repeated CollectionMembership collectionmemberships = 1;
364 | }
365 |
366 | message CollectionMembership {
367 | uint64 id = 1;
368 | Game game = 2;
369 | Collection collection = 3;
370 | CollectionMembershipType type = 4;
371 | google.protobuf.Timestamp updated_at = 5;
372 | google.protobuf.Timestamp created_at = 6;
373 | string checksum = 7;
374 | }
375 |
376 | message CollectionMembershipTypeResult {
377 | repeated CollectionMembershipType collectionmembershiptypes = 1;
378 | }
379 |
380 | message CollectionMembershipType {
381 | uint64 id = 1;
382 | string name = 2;
383 | string description = 3;
384 | CollectionType allowed_collection_type = 4;
385 | google.protobuf.Timestamp updated_at = 5;
386 | google.protobuf.Timestamp created_at = 6;
387 | string checksum = 7;
388 | }
389 |
390 | message CollectionRelationResult {
391 | repeated CollectionRelation collectionrelations = 1;
392 | }
393 |
394 | message CollectionRelation {
395 | uint64 id = 1;
396 | Collection child_collection = 2;
397 | Collection parent_collection = 3;
398 | CollectionRelationType type = 4;
399 | google.protobuf.Timestamp updated_at = 5;
400 | google.protobuf.Timestamp created_at = 6;
401 | string checksum = 7;
402 | }
403 |
404 | message CollectionRelationTypeResult {
405 | repeated CollectionRelationType collectionrelationtypes = 1;
406 | }
407 |
408 | message CollectionRelationType {
409 | uint64 id = 1;
410 | string name = 2;
411 | string description = 3;
412 | CollectionType allowed_child_type = 4;
413 | CollectionType allowed_parent_type = 5;
414 | google.protobuf.Timestamp updated_at = 6;
415 | google.protobuf.Timestamp created_at = 7;
416 | string checksum = 8;
417 | }
418 |
419 | message CollectionTypeResult {
420 | repeated CollectionType collectiontypes = 1;
421 | }
422 |
423 | message CollectionType {
424 | uint64 id = 1;
425 | string name = 2;
426 | string description = 3;
427 | google.protobuf.Timestamp updated_at = 4;
428 | google.protobuf.Timestamp created_at = 5;
429 | string checksum = 6;
430 | }
431 |
432 | message CompanyResult {
433 | repeated Company companies = 1;
434 | }
435 |
436 | message Company {
437 | uint64 id = 1;
438 | google.protobuf.Timestamp change_date = 2;
439 | DateFormatChangeDateCategoryEnum change_date_category = 3 [deprecated = true];
440 | Company changed_company_id = 4;
441 | int32 country = 5;
442 | google.protobuf.Timestamp created_at = 6;
443 | string description = 7;
444 | repeated Game developed = 8;
445 | CompanyLogo logo = 9;
446 | string name = 10;
447 | Company parent = 11;
448 | repeated Game published = 12;
449 | string slug = 13;
450 | google.protobuf.Timestamp start_date = 14;
451 | DateFormatChangeDateCategoryEnum start_date_category = 15 [deprecated = true];
452 | google.protobuf.Timestamp updated_at = 16;
453 | string url = 17;
454 | repeated CompanyWebsite websites = 18;
455 | string checksum = 19;
456 | CompanyStatus status = 20;
457 | DateFormat start_date_format = 21;
458 | DateFormat change_date_format = 22;
459 | }
460 |
461 |
462 | enum DateFormatChangeDateCategoryEnum {
463 | YYYYMMMMDD = 0 [deprecated = true];
464 | YYYYMMMM = 1 [deprecated = true];
465 | YYYY = 2 [deprecated = true];
466 | YYYYQ1 = 3 [deprecated = true];
467 | YYYYQ2 = 4 [deprecated = true];
468 | YYYYQ3 = 5 [deprecated = true];
469 | YYYYQ4 = 6 [deprecated = true];
470 | TBD = 7 [deprecated = true];
471 | }
472 |
473 | message CompanyLogoResult {
474 | repeated CompanyLogo companylogos = 1;
475 | }
476 |
477 | message CompanyLogo {
478 | uint64 id = 1;
479 | bool alpha_channel = 2;
480 | bool animated = 3;
481 | int32 height = 4;
482 | string image_id = 5;
483 | string url = 6;
484 | int32 width = 7;
485 | string checksum = 8;
486 | }
487 |
488 | message CompanyStatusResult {
489 | repeated CompanyStatus companystatuses = 1;
490 | }
491 |
492 | message CompanyStatus {
493 | uint64 id = 1;
494 | string name = 2;
495 | google.protobuf.Timestamp created_at = 3;
496 | google.protobuf.Timestamp updated_at = 4;
497 | string checksum = 5;
498 | }
499 |
500 | message CompanyWebsiteResult {
501 | repeated CompanyWebsite companywebsites = 1;
502 | }
503 |
504 | message CompanyWebsite {
505 | uint64 id = 1;
506 | WebsiteCategoryEnum category = 2 [deprecated = true];
507 | bool trusted = 3;
508 | string url = 4;
509 | string checksum = 5;
510 | WebsiteType type = 6;
511 | }
512 |
513 |
514 | enum WebsiteCategoryEnum {
515 | WEBSITE_CATEGORY_NULL = 0 [deprecated = true];
516 | WEBSITE_OFFICIAL = 1 [deprecated = true];
517 | WEBSITE_WIKIA = 2 [deprecated = true];
518 | WEBSITE_WIKIPEDIA = 3 [deprecated = true];
519 | WEBSITE_FACEBOOK = 4 [deprecated = true];
520 | WEBSITE_TWITTER = 5 [deprecated = true];
521 | WEBSITE_TWITCH = 6 [deprecated = true];
522 | WEBSITE_INSTAGRAM = 8 [deprecated = true];
523 | WEBSITE_YOUTUBE = 9 [deprecated = true];
524 | WEBSITE_IPHONE = 10 [deprecated = true];
525 | WEBSITE_IPAD = 11 [deprecated = true];
526 | WEBSITE_ANDROID = 12 [deprecated = true];
527 | WEBSITE_STEAM = 13 [deprecated = true];
528 | WEBSITE_REDDIT = 14 [deprecated = true];
529 | WEBSITE_ITCH = 15 [deprecated = true];
530 | WEBSITE_EPICGAMES = 16 [deprecated = true];
531 | WEBSITE_GOG = 17 [deprecated = true];
532 | WEBSITE_DISCORD = 18 [deprecated = true];
533 | WEBSITE_BLUESKY = 19 [deprecated = true];
534 | }
535 |
536 | message CoverResult {
537 | repeated Cover covers = 1;
538 | }
539 |
540 | message Cover {
541 | uint64 id = 1;
542 | bool alpha_channel = 2;
543 | bool animated = 3;
544 | Game game = 4;
545 | int32 height = 5;
546 | string image_id = 6;
547 | string url = 7;
548 | int32 width = 8;
549 | string checksum = 9;
550 | GameLocalization game_localization = 10;
551 | }
552 |
553 | message DateFormatResult {
554 | repeated DateFormat dateformats = 1;
555 | }
556 |
557 | message DateFormat {
558 | uint64 id = 1;
559 | string format = 2;
560 | google.protobuf.Timestamp created_at = 3;
561 | google.protobuf.Timestamp updated_at = 4;
562 | string checksum = 5;
563 | }
564 |
565 | message EventResult {
566 | repeated Event events = 1;
567 | }
568 |
569 | message Event {
570 | uint64 id = 1;
571 | string name = 2;
572 | string description = 3;
573 | string slug = 4;
574 | EventLogo event_logo = 5;
575 | google.protobuf.Timestamp start_time = 6;
576 | string time_zone = 7;
577 | google.protobuf.Timestamp end_time = 8;
578 | string live_stream_url = 9;
579 | repeated Game games = 10;
580 | repeated GameVideo videos = 11;
581 | repeated EventNetwork event_networks = 12;
582 | google.protobuf.Timestamp created_at = 13;
583 | google.protobuf.Timestamp updated_at = 14;
584 | string checksum = 15;
585 | }
586 |
587 | message EventLogoResult {
588 | repeated EventLogo eventlogos = 1;
589 | }
590 |
591 | message EventLogo {
592 | uint64 id = 1;
593 | Event event = 2;
594 | bool alpha_channel = 3;
595 | bool animated = 4;
596 | int32 height = 5;
597 | string image_id = 6;
598 | string url = 7;
599 | int32 width = 8;
600 | google.protobuf.Timestamp created_at = 9;
601 | google.protobuf.Timestamp updated_at = 10;
602 | string checksum = 11;
603 | }
604 |
605 | message EventNetworkResult {
606 | repeated EventNetwork eventnetworks = 1;
607 | }
608 |
609 | message EventNetwork {
610 | uint64 id = 1;
611 | Event event = 2;
612 | string url = 3;
613 | NetworkType network_type = 4;
614 | google.protobuf.Timestamp created_at = 5;
615 | google.protobuf.Timestamp updated_at = 6;
616 | string checksum = 7;
617 | }
618 |
619 | message ExternalGameResult {
620 | repeated ExternalGame externalgames = 1;
621 | }
622 |
623 | message ExternalGame {
624 | uint64 id = 1;
625 | ExternalGameCategoryEnum category = 2 [deprecated = true];
626 | google.protobuf.Timestamp created_at = 3;
627 | Game game = 4;
628 | string name = 5;
629 | string uid = 6;
630 | google.protobuf.Timestamp updated_at = 7;
631 | string url = 8;
632 | int32 year = 9;
633 | ExternalGameMediaEnum media = 10 [deprecated = true];
634 | Platform platform = 11;
635 | repeated int32 countries = 12;
636 | string checksum = 13;
637 | ExternalGameSource external_game_source = 14;
638 | GameReleaseFormat game_release_format = 15;
639 | }
640 |
641 |
642 | enum ExternalGameCategoryEnum {
643 | EXTERNALGAME_CATEGORY_NULL = 0 [deprecated = true];
644 | EXTERNALGAME_STEAM = 1 [deprecated = true];
645 | EXTERNALGAME_GOG = 5 [deprecated = true];
646 | EXTERNALGAME_YOUTUBE = 10 [deprecated = true];
647 | EXTERNALGAME_MICROSOFT = 11 [deprecated = true];
648 | EXTERNALGAME_APPLE = 13 [deprecated = true];
649 | EXTERNALGAME_TWITCH = 14 [deprecated = true];
650 | EXTERNALGAME_ANDROID = 15 [deprecated = true];
651 | EXTERNALGAME_AMAZON_ASIN = 20 [deprecated = true];
652 | EXTERNALGAME_AMAZON_LUNA = 22 [deprecated = true];
653 | EXTERNALGAME_AMAZON_ADG = 23 [deprecated = true];
654 | EXTERNALGAME_EPIC_GAME_STORE = 26 [deprecated = true];
655 | EXTERNALGAME_OCULUS = 28 [deprecated = true];
656 | EXTERNALGAME_UTOMIK = 29 [deprecated = true];
657 | EXTERNALGAME_ITCH_IO = 30 [deprecated = true];
658 | EXTERNALGAME_XBOX_MARKETPLACE = 31 [deprecated = true];
659 | EXTERNALGAME_KARTRIDGE = 32 [deprecated = true];
660 | EXTERNALGAME_PLAYSTATION_STORE_US = 36 [deprecated = true];
661 | EXTERNALGAME_FOCUS_ENTERTAINMENT = 37 [deprecated = true];
662 | EXTERNALGAME_XBOX_GAME_PASS_ULTIMATE_CLOUD = 54 [deprecated = true];
663 | EXTERNALGAME_GAMEJOLT = 55 [deprecated = true];
664 | }
665 |
666 |
667 | enum ExternalGameMediaEnum {
668 | EXTERNALGAME_MEDIA_NULL = 0 [deprecated = true];
669 | EXTERNALGAME_DIGITAL = 1 [deprecated = true];
670 | EXTERNALGAME_PHYSICAL = 2 [deprecated = true];
671 | }
672 |
673 | message ExternalGameSourceResult {
674 | repeated ExternalGameSource externalgamesources = 1;
675 | }
676 |
677 | message ExternalGameSource {
678 | uint64 id = 1;
679 | string name = 2;
680 | google.protobuf.Timestamp created_at = 4;
681 | google.protobuf.Timestamp updated_at = 5;
682 | string checksum = 6;
683 | }
684 |
685 | message FranchiseResult {
686 | repeated Franchise franchises = 1;
687 | }
688 |
689 | message Franchise {
690 | uint64 id = 1;
691 | google.protobuf.Timestamp created_at = 2;
692 | repeated Game games = 3;
693 | string name = 4;
694 | string slug = 5;
695 | google.protobuf.Timestamp updated_at = 6;
696 | string url = 7;
697 | string checksum = 8;
698 | }
699 |
700 | message GameResult {
701 | repeated Game games = 1;
702 | }
703 |
704 | message Game {
705 | uint64 id = 1;
706 | repeated AgeRating age_ratings = 2;
707 | double aggregated_rating = 3;
708 | int32 aggregated_rating_count = 4;
709 | repeated AlternativeName alternative_names = 5;
710 | repeated Artwork artworks = 6;
711 | repeated Game bundles = 7;
712 | GameCategoryEnum category = 8 [deprecated = true];
713 | Collection collection = 9 [deprecated = true];
714 | Cover cover = 10;
715 | google.protobuf.Timestamp created_at = 11;
716 | repeated Game dlcs = 12;
717 | repeated Game expansions = 13;
718 | repeated ExternalGame external_games = 14;
719 | google.protobuf.Timestamp first_release_date = 15;
720 | int32 follows = 16 [deprecated = true];
721 | Franchise franchise = 17;
722 | repeated Franchise franchises = 18;
723 | repeated GameEngine game_engines = 19;
724 | repeated GameMode game_modes = 20;
725 | repeated Genre genres = 21;
726 | int32 hypes = 22;
727 | repeated InvolvedCompany involved_companies = 23;
728 | repeated Keyword keywords = 24;
729 | repeated MultiplayerMode multiplayer_modes = 25;
730 | string name = 26;
731 | Game parent_game = 27;
732 | repeated Platform platforms = 28;
733 | repeated PlayerPerspective player_perspectives = 29;
734 | double rating = 30;
735 | int32 rating_count = 31;
736 | repeated ReleaseDate release_dates = 32;
737 | repeated Screenshot screenshots = 33;
738 | repeated Game similar_games = 34;
739 | string slug = 35;
740 | repeated Game standalone_expansions = 36;
741 | GameStatusEnum status = 37 [deprecated = true];
742 | string storyline = 38;
743 | string summary = 39;
744 | repeated int32 tags = 40;
745 | repeated Theme themes = 41;
746 | double total_rating = 42;
747 | int32 total_rating_count = 43;
748 | google.protobuf.Timestamp updated_at = 44;
749 | string url = 45;
750 | Game version_parent = 46;
751 | string version_title = 47;
752 | repeated GameVideo videos = 48;
753 | repeated Website websites = 49;
754 | string checksum = 50;
755 | repeated Game remakes = 51;
756 | repeated Game remasters = 52;
757 | repeated Game expanded_games = 53;
758 | repeated Game ports = 54;
759 | repeated Game forks = 55;
760 | repeated LanguageSupport language_supports = 56;
761 | repeated GameLocalization game_localizations = 57;
762 | repeated Collection collections = 58;
763 | GameStatus game_status = 59;
764 | GameType game_type = 60;
765 | }
766 |
767 |
768 | enum GameCategoryEnum {
769 | MAIN_GAME = 0 [deprecated = true];
770 | DLC_ADDON = 1 [deprecated = true];
771 | EXPANSION = 2 [deprecated = true];
772 | BUNDLE = 3 [deprecated = true];
773 | STANDALONE_EXPANSION = 4 [deprecated = true];
774 | MOD = 5 [deprecated = true];
775 | EPISODE = 6 [deprecated = true];
776 | SEASON = 7 [deprecated = true];
777 | REMAKE = 8 [deprecated = true];
778 | REMASTER = 9 [deprecated = true];
779 | EXPANDED_GAME = 10 [deprecated = true];
780 | PORT = 11 [deprecated = true];
781 | FORK = 12 [deprecated = true];
782 | PACK = 13 [deprecated = true];
783 | UPDATE = 14 [deprecated = true];
784 | }
785 |
786 |
787 | enum GameStatusEnum {
788 | RELEASED = 0 [deprecated = true];
789 | ALPHA = 2 [deprecated = true];
790 | BETA = 3 [deprecated = true];
791 | EARLY_ACCESS = 4 [deprecated = true];
792 | OFFLINE = 5 [deprecated = true];
793 | CANCELLED = 6 [deprecated = true];
794 | RUMORED = 7 [deprecated = true];
795 | DELISTED = 8 [deprecated = true];
796 | }
797 |
798 | message GameEngineResult {
799 | repeated GameEngine gameengines = 1;
800 | }
801 |
802 | message GameEngine {
803 | uint64 id = 1;
804 | repeated Company companies = 2;
805 | google.protobuf.Timestamp created_at = 3;
806 | string description = 4;
807 | GameEngineLogo logo = 5;
808 | string name = 6;
809 | repeated Platform platforms = 7;
810 | string slug = 8;
811 | google.protobuf.Timestamp updated_at = 9;
812 | string url = 10;
813 | string checksum = 11;
814 | }
815 |
816 | message GameEngineLogoResult {
817 | repeated GameEngineLogo gameenginelogos = 1;
818 | }
819 |
820 | message GameEngineLogo {
821 | uint64 id = 1;
822 | bool alpha_channel = 2;
823 | bool animated = 3;
824 | int32 height = 4;
825 | string image_id = 5;
826 | string url = 6;
827 | int32 width = 7;
828 | string checksum = 8;
829 | }
830 |
831 | message GameLocalizationResult {
832 | repeated GameLocalization gamelocalizations = 1;
833 | }
834 |
835 | message GameLocalization {
836 | uint64 id = 1;
837 | string name = 2;
838 | Cover cover = 3;
839 | Game game = 4;
840 | Region region = 5;
841 | google.protobuf.Timestamp created_at = 6;
842 | google.protobuf.Timestamp updated_at = 7;
843 | string checksum = 8;
844 | }
845 |
846 | message GameModeResult {
847 | repeated GameMode gamemodes = 1;
848 | }
849 |
850 | message GameMode {
851 | uint64 id = 1;
852 | google.protobuf.Timestamp created_at = 2;
853 | string name = 3;
854 | string slug = 4;
855 | google.protobuf.Timestamp updated_at = 5;
856 | string url = 6;
857 | string checksum = 7;
858 | }
859 |
860 | message GameReleaseFormatResult {
861 | repeated GameReleaseFormat gamereleaseformats = 1;
862 | }
863 |
864 | message GameReleaseFormat {
865 | uint64 id = 1;
866 | string format = 2;
867 | google.protobuf.Timestamp created_at = 3;
868 | google.protobuf.Timestamp updated_at = 4;
869 | string checksum = 5;
870 | }
871 |
872 | message GameStatusResult {
873 | repeated GameStatus gamestatuses = 1;
874 | }
875 |
876 | message GameStatus {
877 | uint64 id = 1;
878 | string status = 2;
879 | google.protobuf.Timestamp created_at = 3;
880 | google.protobuf.Timestamp updated_at = 4;
881 | string checksum = 5;
882 | }
883 |
884 | message GameTimeToBeatResult {
885 | repeated GameTimeToBeat gametimetobeats = 1;
886 | }
887 |
888 | message GameTimeToBeat {
889 | uint64 id = 1;
890 | int32 game_id = 2;
891 | int32 hastily = 3;
892 | int32 normally = 4;
893 | int32 completely = 5;
894 | int32 count = 6;
895 | google.protobuf.Timestamp created_at = 7;
896 | google.protobuf.Timestamp updated_at = 8;
897 | string checksum = 9;
898 | }
899 |
900 | message GameTypeResult {
901 | repeated GameType gametypes = 1;
902 | }
903 |
904 | message GameType {
905 | uint64 id = 1;
906 | string type = 2;
907 | google.protobuf.Timestamp created_at = 3;
908 | google.protobuf.Timestamp updated_at = 4;
909 | string checksum = 5;
910 | }
911 |
912 | message GameVersionResult {
913 | repeated GameVersion gameversions = 1;
914 | }
915 |
916 | message GameVersion {
917 | uint64 id = 1;
918 | google.protobuf.Timestamp created_at = 2;
919 | repeated GameVersionFeature features = 3;
920 | Game game = 4;
921 | repeated Game games = 5;
922 | google.protobuf.Timestamp updated_at = 6;
923 | string url = 7;
924 | string checksum = 8;
925 | }
926 |
927 | message GameVersionFeatureResult {
928 | repeated GameVersionFeature gameversionfeatures = 1;
929 | }
930 |
931 | message GameVersionFeature {
932 | uint64 id = 1;
933 | GameVersionFeatureCategoryEnum category = 2;
934 | string description = 3;
935 | int32 position = 4;
936 | string title = 5;
937 | repeated GameVersionFeatureValue values = 6;
938 | string checksum = 7;
939 | }
940 |
941 |
942 | enum GameVersionFeatureCategoryEnum {
943 | BOOLEAN = 0;
944 | DESCRIPTION = 1;
945 | }
946 |
947 | message GameVersionFeatureValueResult {
948 | repeated GameVersionFeatureValue gameversionfeaturevalues = 1;
949 | }
950 |
951 | message GameVersionFeatureValue {
952 | uint64 id = 1;
953 | Game game = 2;
954 | GameVersionFeature game_feature = 3;
955 | GameVersionFeatureValueIncludedFeatureEnum included_feature = 4;
956 | string note = 5;
957 | string checksum = 6;
958 | }
959 |
960 |
961 | enum GameVersionFeatureValueIncludedFeatureEnum {
962 | NOT_INCLUDED = 0;
963 | INCLUDED = 1;
964 | PRE_ORDER_ONLY = 2;
965 | }
966 |
967 | message GameVideoResult {
968 | repeated GameVideo gamevideos = 1;
969 | }
970 |
971 | message GameVideo {
972 | uint64 id = 1;
973 | Game game = 2;
974 | string name = 3;
975 | string video_id = 4;
976 | string checksum = 5;
977 | }
978 |
979 | message GenreResult {
980 | repeated Genre genres = 1;
981 | }
982 |
983 | message Genre {
984 | uint64 id = 1;
985 | google.protobuf.Timestamp created_at = 2;
986 | string name = 3;
987 | string slug = 4;
988 | google.protobuf.Timestamp updated_at = 5;
989 | string url = 6;
990 | string checksum = 7;
991 | }
992 |
993 | message InvolvedCompanyResult {
994 | repeated InvolvedCompany involvedcompanies = 1;
995 | }
996 |
997 | message InvolvedCompany {
998 | uint64 id = 1;
999 | Company company = 2;
1000 | google.protobuf.Timestamp created_at = 3;
1001 | bool developer = 4;
1002 | Game game = 5;
1003 | bool porting = 6;
1004 | bool publisher = 7;
1005 | bool supporting = 8;
1006 | google.protobuf.Timestamp updated_at = 9;
1007 | string checksum = 10;
1008 | }
1009 |
1010 | message KeywordResult {
1011 | repeated Keyword keywords = 1;
1012 | }
1013 |
1014 | message Keyword {
1015 | uint64 id = 1;
1016 | google.protobuf.Timestamp created_at = 2;
1017 | string name = 3;
1018 | string slug = 4;
1019 | google.protobuf.Timestamp updated_at = 5;
1020 | string url = 6;
1021 | string checksum = 7;
1022 | }
1023 |
1024 | message LanguageResult {
1025 | repeated Language languages = 1;
1026 | }
1027 |
1028 | message Language {
1029 | uint64 id = 1;
1030 | string name = 2;
1031 | string native_name = 3;
1032 | string locale = 4;
1033 | google.protobuf.Timestamp created_at = 5;
1034 | google.protobuf.Timestamp updated_at = 6;
1035 | string checksum = 7;
1036 | }
1037 |
1038 | message LanguageSupportResult {
1039 | repeated LanguageSupport languagesupports = 1;
1040 | }
1041 |
1042 | message LanguageSupport {
1043 | uint64 id = 1;
1044 | Game game = 2;
1045 | Language language = 3;
1046 | LanguageSupportType language_support_type = 4;
1047 | google.protobuf.Timestamp created_at = 5;
1048 | google.protobuf.Timestamp updated_at = 6;
1049 | string checksum = 7;
1050 | }
1051 |
1052 | message LanguageSupportTypeResult {
1053 | repeated LanguageSupportType languagesupporttypes = 1;
1054 | }
1055 |
1056 | message LanguageSupportType {
1057 | uint64 id = 1;
1058 | string name = 2;
1059 | google.protobuf.Timestamp created_at = 3;
1060 | google.protobuf.Timestamp updated_at = 4;
1061 | string checksum = 5;
1062 | }
1063 |
1064 | message MultiplayerModeResult {
1065 | repeated MultiplayerMode multiplayermodes = 1;
1066 | }
1067 |
1068 | message MultiplayerMode {
1069 | uint64 id = 1;
1070 | bool campaigncoop = 2;
1071 | bool dropin = 3;
1072 | Game game = 4;
1073 | bool lancoop = 5;
1074 | bool offlinecoop = 6;
1075 | int32 offlinecoopmax = 7;
1076 | int32 offlinemax = 8;
1077 | bool onlinecoop = 9;
1078 | int32 onlinecoopmax = 10;
1079 | int32 onlinemax = 11;
1080 | Platform platform = 12;
1081 | bool splitscreen = 13;
1082 | bool splitscreenonline = 14;
1083 | string checksum = 15;
1084 | }
1085 |
1086 | message NetworkTypeResult {
1087 | repeated NetworkType networktypes = 1;
1088 | }
1089 |
1090 | message NetworkType {
1091 | uint64 id = 1;
1092 | string name = 2;
1093 | repeated EventNetwork event_networks = 3;
1094 | google.protobuf.Timestamp created_at = 4;
1095 | google.protobuf.Timestamp updated_at = 5;
1096 | string checksum = 6;
1097 | }
1098 |
1099 | message PlatformResult {
1100 | repeated Platform platforms = 1;
1101 | }
1102 |
1103 | message Platform {
1104 | uint64 id = 1;
1105 | string abbreviation = 2;
1106 | string alternative_name = 3;
1107 | PlatformCategoryEnum category = 4 [deprecated = true];
1108 | google.protobuf.Timestamp created_at = 5;
1109 | int32 generation = 6;
1110 | string name = 7;
1111 | PlatformLogo platform_logo = 8;
1112 | PlatformFamily platform_family = 9;
1113 | string slug = 10;
1114 | string summary = 11;
1115 | google.protobuf.Timestamp updated_at = 12;
1116 | string url = 13;
1117 | repeated PlatformVersion versions = 14;
1118 | repeated PlatformWebsite websites = 15;
1119 | string checksum = 16;
1120 | PlatformType platform_type = 17;
1121 | }
1122 |
1123 |
1124 | enum PlatformCategoryEnum {
1125 | PLATFORM_CATEGORY_NULL = 0 [deprecated = true];
1126 | CONSOLE = 1 [deprecated = true];
1127 | ARCADE = 2 [deprecated = true];
1128 | PLATFORM = 3 [deprecated = true];
1129 | OPERATING_SYSTEM = 4 [deprecated = true];
1130 | PORTABLE_CONSOLE = 5 [deprecated = true];
1131 | COMPUTER = 6 [deprecated = true];
1132 | }
1133 |
1134 | message PlatformFamilyResult {
1135 | repeated PlatformFamily platformfamilies = 1;
1136 | }
1137 |
1138 | message PlatformFamily {
1139 | uint64 id = 1;
1140 | string name = 2;
1141 | string slug = 3;
1142 | string checksum = 4;
1143 | }
1144 |
1145 | message PlatformLogoResult {
1146 | repeated PlatformLogo platformlogos = 1;
1147 | }
1148 |
1149 | message PlatformLogo {
1150 | uint64 id = 1;
1151 | bool alpha_channel = 2;
1152 | bool animated = 3;
1153 | int32 height = 4;
1154 | string image_id = 5;
1155 | string url = 6;
1156 | int32 width = 7;
1157 | string checksum = 8;
1158 | }
1159 |
1160 | message PlatformTypeResult {
1161 | repeated PlatformType platformtypes = 1;
1162 | }
1163 |
1164 | message PlatformType {
1165 | uint64 id = 1;
1166 | string name = 2;
1167 | google.protobuf.Timestamp created_at = 3;
1168 | google.protobuf.Timestamp updated_at = 4;
1169 | string checksum = 5;
1170 | }
1171 |
1172 | message PlatformVersionResult {
1173 | repeated PlatformVersion platformversions = 1;
1174 | }
1175 |
1176 | message PlatformVersion {
1177 | uint64 id = 1;
1178 | repeated PlatformVersionCompany companies = 2;
1179 | string connectivity = 3;
1180 | string cpu = 4;
1181 | string graphics = 5;
1182 | PlatformVersionCompany main_manufacturer = 6;
1183 | string media = 7;
1184 | string memory = 8;
1185 | string name = 9;
1186 | string os = 11;
1187 | string output = 12;
1188 | PlatformLogo platform_logo = 13;
1189 | repeated PlatformVersionReleaseDate platform_version_release_dates = 14;
1190 | string resolutions = 15;
1191 | string slug = 16;
1192 | string sound = 17;
1193 | string storage = 18;
1194 | string summary = 19;
1195 | string url = 20;
1196 | string checksum = 21;
1197 | }
1198 |
1199 | message PlatformVersionCompanyResult {
1200 | repeated PlatformVersionCompany platformversioncompanies = 1;
1201 | }
1202 |
1203 | message PlatformVersionCompany {
1204 | uint64 id = 1;
1205 | string comment = 2;
1206 | Company company = 3;
1207 | bool developer = 4;
1208 | bool manufacturer = 5;
1209 | string checksum = 6;
1210 | }
1211 |
1212 | message PlatformVersionReleaseDateResult {
1213 | repeated PlatformVersionReleaseDate platformversionreleasedates = 1;
1214 | }
1215 |
1216 | message PlatformVersionReleaseDate {
1217 | uint64 id = 1;
1218 | DateFormatChangeDateCategoryEnum category = 2 [deprecated = true];
1219 | google.protobuf.Timestamp created_at = 3;
1220 | google.protobuf.Timestamp date = 4;
1221 | string human = 5;
1222 | int32 m = 6;
1223 | PlatformVersion platform_version = 7;
1224 | RegionRegionEnum region = 8 [deprecated = true];
1225 | google.protobuf.Timestamp updated_at = 9;
1226 | int32 y = 10;
1227 | string checksum = 11;
1228 | DateFormat date_format = 12;
1229 | ReleaseDateRegion release_region = 13;
1230 | }
1231 |
1232 |
1233 | enum RegionRegionEnum {
1234 | REGION_REGION_NULL = 0 [deprecated = true];
1235 | EUROPE = 1 [deprecated = true];
1236 | NORTH_AMERICA = 2 [deprecated = true];
1237 | AUSTRALIA = 3 [deprecated = true];
1238 | NEW_ZEALAND = 4 [deprecated = true];
1239 | JAPAN = 5 [deprecated = true];
1240 | CHINA = 6 [deprecated = true];
1241 | ASIA = 7 [deprecated = true];
1242 | WORLDWIDE = 8 [deprecated = true];
1243 | KOREA = 9 [deprecated = true];
1244 | BRAZIL = 10 [deprecated = true];
1245 | }
1246 |
1247 | message PlatformWebsiteResult {
1248 | repeated PlatformWebsite platformwebsites = 1;
1249 | }
1250 |
1251 | message PlatformWebsite {
1252 | uint64 id = 1;
1253 | WebsiteCategoryEnum category = 2 [deprecated = true];
1254 | bool trusted = 3;
1255 | string url = 4;
1256 | string checksum = 5;
1257 | WebsiteType type = 6;
1258 | }
1259 |
1260 | message PlayerPerspectiveResult {
1261 | repeated PlayerPerspective playerperspectives = 1;
1262 | }
1263 |
1264 | message PlayerPerspective {
1265 | uint64 id = 1;
1266 | google.protobuf.Timestamp created_at = 2;
1267 | string name = 3;
1268 | string slug = 4;
1269 | google.protobuf.Timestamp updated_at = 5;
1270 | string url = 6;
1271 | string checksum = 7;
1272 | }
1273 |
1274 | message PopularityPrimitiveResult {
1275 | repeated PopularityPrimitive popularityprimitives = 1;
1276 | }
1277 |
1278 | message PopularityPrimitive {
1279 | uint64 id = 1;
1280 | int32 game_id = 2;
1281 | PopularityType popularity_type = 3;
1282 | PopularitySourcePopularitySourceEnum popularity_source = 4 [deprecated = true];
1283 | double value = 5;
1284 | google.protobuf.Timestamp calculated_at = 6;
1285 | google.protobuf.Timestamp created_at = 7;
1286 | google.protobuf.Timestamp updated_at = 8;
1287 | string checksum = 9;
1288 | ExternalGameSource external_popularity_source = 10;
1289 | }
1290 |
1291 |
1292 | enum PopularitySourcePopularitySourceEnum {
1293 | POPULARITYSOURCE_POPULARITY_SOURCE_NULL = 0 [deprecated = true];
1294 | IGDB = 121 [deprecated = true];
1295 | }
1296 |
1297 | message PopularityTypeResult {
1298 | repeated PopularityType popularitytypes = 1;
1299 | }
1300 |
1301 | message PopularityType {
1302 | uint64 id = 1;
1303 | PopularitySourcePopularitySourceEnum popularity_source = 2 [deprecated = true];
1304 | string name = 3;
1305 | google.protobuf.Timestamp created_at = 4;
1306 | google.protobuf.Timestamp updated_at = 5;
1307 | string checksum = 6;
1308 | ExternalGameSource external_popularity_source = 7;
1309 | }
1310 |
1311 | message RegionResult {
1312 | repeated Region regions = 1;
1313 | }
1314 |
1315 | message Region {
1316 | uint64 id = 1;
1317 | string name = 2;
1318 | string category = 3;
1319 | string identifier = 4;
1320 | google.protobuf.Timestamp created_at = 5;
1321 | google.protobuf.Timestamp updated_at = 6;
1322 | string checksum = 7;
1323 | }
1324 |
1325 | message ReleaseDateResult {
1326 | repeated ReleaseDate releasedates = 1;
1327 | }
1328 |
1329 | message ReleaseDate {
1330 | uint64 id = 1;
1331 | DateFormatChangeDateCategoryEnum category = 2 [deprecated = true];
1332 | google.protobuf.Timestamp created_at = 3;
1333 | google.protobuf.Timestamp date = 4;
1334 | Game game = 5;
1335 | string human = 6;
1336 | int32 m = 7;
1337 | Platform platform = 8;
1338 | RegionRegionEnum region = 9 [deprecated = true];
1339 | google.protobuf.Timestamp updated_at = 10;
1340 | int32 y = 11;
1341 | string checksum = 12;
1342 | ReleaseDateStatus status = 13;
1343 | DateFormat date_format = 14;
1344 | ReleaseDateRegion release_region = 15;
1345 | }
1346 |
1347 | message ReleaseDateRegionResult {
1348 | repeated ReleaseDateRegion releasedateregions = 1;
1349 | }
1350 |
1351 | message ReleaseDateRegion {
1352 | uint64 id = 1;
1353 | string region = 2;
1354 | google.protobuf.Timestamp created_at = 3;
1355 | google.protobuf.Timestamp updated_at = 4;
1356 | string checksum = 5;
1357 | }
1358 |
1359 | message ReleaseDateStatusResult {
1360 | repeated ReleaseDateStatus releasedatestatuses = 1;
1361 | }
1362 |
1363 | message ReleaseDateStatus {
1364 | uint64 id = 1;
1365 | string name = 2;
1366 | string description = 3;
1367 | google.protobuf.Timestamp created_at = 4;
1368 | google.protobuf.Timestamp updated_at = 5;
1369 | string checksum = 6;
1370 | }
1371 |
1372 | message ScreenshotResult {
1373 | repeated Screenshot screenshots = 1;
1374 | }
1375 |
1376 | message Screenshot {
1377 | uint64 id = 1;
1378 | bool alpha_channel = 2;
1379 | bool animated = 3;
1380 | Game game = 4;
1381 | int32 height = 5;
1382 | string image_id = 6;
1383 | string url = 7;
1384 | int32 width = 8;
1385 | string checksum = 9;
1386 | }
1387 |
1388 | message SearchResult {
1389 | repeated Search searches = 1;
1390 | }
1391 |
1392 | message Search {
1393 | uint64 id = 1;
1394 | string alternative_name = 2;
1395 | Character character = 3;
1396 | Collection collection = 4;
1397 | Company company = 5;
1398 | string description = 6;
1399 | Game game = 7;
1400 | string name = 8;
1401 | Platform platform = 9;
1402 | google.protobuf.Timestamp published_at = 10;
1403 | TestDummy test_dummy = 11;
1404 | Theme theme = 12;
1405 | string checksum = 13;
1406 | }
1407 |
1408 | message TestDummyResult {
1409 | repeated TestDummy testdummies = 1;
1410 | }
1411 |
1412 | message TestDummy {
1413 | uint64 id = 1;
1414 | bool bool_value = 2;
1415 | google.protobuf.Timestamp created_at = 3;
1416 | TestDummyEnumTestEnum enum_test = 4;
1417 | double float_value = 5;
1418 | Game game = 6;
1419 | repeated int32 integer_array = 7;
1420 | int32 integer_value = 8;
1421 | string name = 9;
1422 | int32 new_integer_value = 10;
1423 | bool private = 11;
1424 | string slug = 12;
1425 | repeated string string_array = 13;
1426 | repeated TestDummy test_dummies = 14;
1427 | TestDummy test_dummy = 15;
1428 | google.protobuf.Timestamp updated_at = 16;
1429 | string url = 17;
1430 | string checksum = 18;
1431 | }
1432 |
1433 |
1434 | enum TestDummyEnumTestEnum {
1435 | TESTDUMMY_ENUM_TEST_NULL = 0;
1436 | ENUM1 = 1;
1437 | ENUM2 = 2;
1438 | }
1439 |
1440 | message ThemeResult {
1441 | repeated Theme themes = 1;
1442 | }
1443 |
1444 | message Theme {
1445 | uint64 id = 1;
1446 | google.protobuf.Timestamp created_at = 2;
1447 | string name = 3;
1448 | string slug = 4;
1449 | google.protobuf.Timestamp updated_at = 5;
1450 | string url = 6;
1451 | string checksum = 7;
1452 | }
1453 |
1454 | message WebsiteResult {
1455 | repeated Website websites = 1;
1456 | }
1457 |
1458 | message Website {
1459 | uint64 id = 1;
1460 | WebsiteCategoryEnum category = 2 [deprecated = true];
1461 | Game game = 3;
1462 | bool trusted = 4;
1463 | string url = 5;
1464 | string checksum = 6;
1465 | WebsiteType type = 7;
1466 | }
1467 |
1468 | message WebsiteTypeResult {
1469 | repeated WebsiteType websitetypes = 1;
1470 | }
1471 |
1472 | message WebsiteType {
1473 | uint64 id = 1;
1474 | string type = 2;
1475 | google.protobuf.Timestamp created_at = 3;
1476 | google.protobuf.Timestamp updated_at = 4;
1477 | string checksum = 5;
1478 | }
1479 |
--------------------------------------------------------------------------------
/src/test/java/com/api/igdb/TestJavaWrapper.java:
--------------------------------------------------------------------------------
1 | package com.api.igdb;
2 |
3 | import com.api.igdb.apicalypse.APICalypse;
4 | import com.api.igdb.apicalypse.Sort;
5 | import com.api.igdb.exceptions.RequestException;
6 | import com.api.igdb.request.IGDBWrapper;
7 | import com.api.igdb.request.JsonRequestKt;
8 | import com.api.igdb.request.ProtoRequestKt;
9 | import com.api.igdb.utils.ImageBuilderKt;
10 | import com.api.igdb.utils.ImageSize;
11 | import com.api.igdb.utils.ImageType;
12 | import org.junit.jupiter.api.Test;
13 | import proto.Cover;
14 | import proto.Game;
15 | import proto.Search;
16 |
17 | import java.util.List;
18 |
19 | class TestJavaWrapper {
20 | private final IGDBWrapper wrapper = IGDBWrapper.INSTANCE;
21 |
22 | TestJavaWrapper() {
23 | wrapper.setCredentials(System.getenv("client_id"), System.getenv("bearer"));
24 | }
25 |
26 | /*
27 | * The proto tests should cover the rest of the endpoints
28 | * */
29 |
30 | @Test
31 | void testGetProtoGames() throws RequestException {
32 | List result = ProtoRequestKt.games(wrapper, new APICalypse());
33 | assert(!result.isEmpty());
34 | }
35 |
36 | @Test
37 | void testGetJsonGames() throws RequestException {
38 | String result = JsonRequestKt.jsonGames(wrapper, new APICalypse());
39 | assert(!result.isEmpty());
40 | }
41 |
42 | /*
43 | * Real-world test cases
44 | * */
45 |
46 | //Get all Coming Soon PS4 games
47 | @Test
48 | void testComingSoonPS4Games() {
49 | String date = String.valueOf((System.currentTimeMillis() / 1000));
50 | APICalypse query = new APICalypse()
51 | .fields("*")
52 | .where("platforms = 48 & release_dates.date > " + date)
53 | .sort("release_dates.date", Sort.ASCENDING);
54 |
55 | try {
56 | List ps4Games = ProtoRequestKt.games(wrapper, query);
57 | assert(!ps4Games.isEmpty());
58 | } catch (RequestException e) {
59 | assert(false);
60 | }
61 | }
62 |
63 | //Get all Recently released PS4 games
64 | @Test
65 | void testRecentlyReleasedPS4Games() {
66 | String date = String.valueOf((System.currentTimeMillis() / 1000));
67 | APICalypse query = new APICalypse()
68 | .fields("*")
69 | .where("platforms = 48 & release_dates.date < " + date)
70 | .sort("release_dates.date", Sort.DESCENDING);
71 |
72 | try {
73 | List ps4Games = ProtoRequestKt.games(wrapper, query);
74 | assert(!ps4Games.isEmpty());
75 | } catch (RequestException e) {
76 | assert(false);
77 | }
78 | }
79 |
80 | //Get all Recently released PS4 games
81 | @Test
82 | void testSearch() {
83 | APICalypse query = new APICalypse()
84 | .search("Assassins Creed")
85 | .fields("game.name,game.involved_companies")
86 | .where("game != null & game.version_parent = null");
87 |
88 | try {
89 | List result = ProtoRequestKt.search(wrapper, query);
90 | assert(!result.isEmpty());
91 | } catch (RequestException e) {
92 | assert(false);
93 | }
94 | }
95 |
96 | //Get all Recently released PS4 games
97 | @Test
98 | void testPS4Exclusives() {
99 | APICalypse query = new APICalypse()
100 | .fields("name,category,platforms")
101 | .where("category = 0 & platforms = 48");
102 |
103 | try {
104 | List result = ProtoRequestKt.games(wrapper, query);
105 | assert(!result.isEmpty());
106 | } catch (RequestException e) {
107 | assert(false);
108 | }
109 | }
110 |
111 | @Test
112 | void testJPEGImg() {
113 | APICalypse query = new APICalypse()
114 | .fields("image_id")
115 | .where("image_id != n");
116 | try {
117 | List covers = ProtoRequestKt.covers(wrapper, query);
118 | assert(!covers.isEmpty());
119 | Cover firstCover = covers.get(0);
120 | String coverUrl = ImageBuilderKt.imageBuilder(firstCover.getImageId(), ImageSize.HD, ImageType.JPEG);
121 | assert(!coverUrl.isEmpty());
122 | assert(coverUrl.endsWith("jpg"));
123 |
124 | } catch (RequestException e) {
125 | assert(false);
126 | }
127 | }
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/src/test/java/com/api/igdb/TestTwitchToken.java:
--------------------------------------------------------------------------------
1 | package com.api.igdb;
2 |
3 | import com.api.igdb.request.TwitchAuthenticator;
4 | import com.api.igdb.utils.TwitchToken;
5 | import org.junit.jupiter.api.Test;
6 |
7 | import java.time.Duration;
8 |
9 | import static org.junit.jupiter.api.Assertions.assertNotNull;
10 | import static org.junit.jupiter.api.Assertions.assertTrue;
11 |
12 | public class TestTwitchToken {
13 |
14 | @Test
15 | void testGetTwitchToken() {
16 | // Create the Twitch authenticator instance
17 | TwitchAuthenticator tAuth = TwitchAuthenticator.INSTANCE;
18 | // request a new Twitch Authentication token
19 | TwitchToken token = tAuth.requestTwitchToken(System.getenv("client_id"), System.getenv("client_secret"));
20 |
21 | assertNotNull(token);
22 | assertTrue(token.getExpires_in() > Duration.ofDays(57).toSeconds());
23 | long tokenFutureDate = System.currentTimeMillis() + Duration.ofDays(57).toSeconds();
24 | assertTrue(tokenFutureDate > token.getExpiresUnix());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/test/kotlin/com/api/igdb/TestAPICalypseQueryParser.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb
2 |
3 | import com.api.igdb.apicalypse.APICalypse
4 | import com.api.igdb.apicalypse.Sort
5 | import org.junit.jupiter.api.Assertions.assertEquals
6 | import org.junit.jupiter.api.Test
7 |
8 | class TestAPICalypseQueryParser {
9 |
10 | @Test
11 | fun testAllFields() {
12 | val apiCalypse = APICalypse().fields("*")
13 | assertEquals("f *;", apiCalypse.buildQuery())
14 | }
15 |
16 | @Test
17 | fun testLimit() {
18 | val apiCalypse = APICalypse().fields("name").limit(10)
19 | assertEquals("f name;l 10;", apiCalypse.buildQuery())
20 | }
21 |
22 | @Test
23 | fun testOffset() {
24 | val apiCalypse = APICalypse().fields("name").offset(10)
25 | assertEquals("f name;o 10;", apiCalypse.buildQuery())
26 | }
27 |
28 | @Test
29 | fun testWhereNoCommaOrWhere() {
30 | val apiCalypse = APICalypse().fields("*").where("id = 1942")
31 | assertEquals("f *;w id = 1942;", apiCalypse.buildQuery())
32 | }
33 |
34 | @Test
35 | fun testWhereNoWhere() {
36 | val apiCalypse = APICalypse().fields("*").where("id = 1942;")
37 | assertEquals("f *;w id = 1942;", apiCalypse.buildQuery())
38 | }
39 |
40 | @Test
41 | fun testWhere() {
42 | val apiCalypse = APICalypse().fields("*").where("where id = 1942;")
43 | assertEquals("f *;where id = 1942;", apiCalypse.buildQuery())
44 | }
45 |
46 | @Test
47 | fun testWhereW() {
48 | val apiCalypse = APICalypse().fields("*").where("w id = 1942;")
49 | assertEquals("f *;w id = 1942;", apiCalypse.buildQuery())
50 | }
51 |
52 | @Test
53 | fun testExclude() {
54 | val apiCalypse = APICalypse().fields("*").exclude("name")
55 | assertEquals("f *;x name;", apiCalypse.buildQuery())
56 | }
57 |
58 | @Test
59 | fun testSort() {
60 | val apiCalypse = APICalypse().fields("name,popularity").sort("popularity", Sort.DESCENDING)
61 | assertEquals("f name,popularity;s popularity desc;", apiCalypse.buildQuery())
62 | }
63 |
64 | @Test
65 | fun testComingSoonGamesForPS4() {
66 | val apiCalypse = APICalypse().fields("*")
67 | .where("platform = 48 & date > 1538129354;")
68 | .sort("date", Sort.ASCENDING)
69 | assertEquals("f *;s date asc;w platform = 48 & date > 1538129354;", apiCalypse.buildQuery())
70 | }
71 |
72 | @Test
73 | fun testRecentlyReleaseGamesPS4() {
74 | val apiCalypse = APICalypse().fields("*")
75 | .where("platform = 48 & date > 1538129354;")
76 | .sort("date", Sort.DESCENDING)
77 | assertEquals("f *;s date desc;w platform = 48 & date > 1538129354;", apiCalypse.buildQuery())
78 | }
79 |
80 | @Test
81 | fun testSearch() {
82 | val apiCalypse = APICalypse().search("Halo")
83 | .where("game != n").fields("game.name,game.invloved_companies")
84 | assertEquals(
85 | "search \"Halo\";f game.name,game.invloved_companies;w game != n;",
86 | apiCalypse.buildQuery()
87 | )
88 | }
89 |
90 | @Test
91 | fun testSearchWithExclude() {
92 | val apiCalypse = APICalypse().search("Assassins Creed")
93 | .fields("game.name,game.invloved_companies")
94 | .where("game != n & game.version_parent = n")
95 | assertEquals(
96 | "search \"Assassins Creed\";f game.name,game.invloved_companies;w game != n & game.version_parent = n;",
97 | apiCalypse.buildQuery()
98 | )
99 | }
100 |
101 | @Test
102 | fun testGetVersions() {
103 | val apiCalypse = APICalypse()
104 | .fields("version_parent.*")
105 | .where("id = 39047")
106 | assertEquals("f version_parent.*;w id = 39047;", apiCalypse.buildQuery())
107 | }
108 |
109 | @Test
110 | fun testGetAllPS4Exclusives() {
111 | val apiCalypse = APICalypse()
112 | .fields("name,category,platforms")
113 | .where("category = 0 & platforms = 48")
114 | assertEquals("f name,category,platforms;w category = 0 & platforms = 48;", apiCalypse.buildQuery())
115 | }
116 |
117 | @Test
118 | fun testGetAllPS4ANDPCExclusives() {
119 | val apiCalypse = APICalypse()
120 | .fields("name,category,platforms")
121 | .where("category = 0 & platforms = {48,6}")
122 | assertEquals(
123 | "f name,category,platforms;w category = 0 & platforms = {48,6};",
124 | apiCalypse.buildQuery()
125 | )
126 | }
127 |
128 | }
--------------------------------------------------------------------------------
/src/test/kotlin/com/api/igdb/TestIGDBWrapper.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb
2 |
3 | import com.api.igdb.apicalypse.APICalypse
4 | import com.api.igdb.apicalypse.Sort
5 | import com.api.igdb.exceptions.RequestException
6 | import com.api.igdb.request.IGDBWrapper
7 | import com.api.igdb.request.games
8 | import com.api.igdb.request.search
9 | import org.junit.jupiter.api.BeforeEach
10 | import org.junit.jupiter.api.Test
11 |
12 | class TestIGDBWrapper {
13 |
14 | private val wrapper = IGDBWrapper
15 |
16 | @BeforeEach
17 | fun setup() {
18 | wrapper.setCredentials(System.getenv("client_id"), System.getenv("bearer"))
19 | }
20 |
21 | //Get all Coming Soon PS4 games
22 | @Test
23 | fun testComingSoonPS4Games() {
24 | val date = (System.currentTimeMillis() / 1000).toString()
25 | val query = APICalypse()
26 | .fields("*")
27 | .where("platforms = 48 & release_dates.date > $date")
28 | .sort("release_dates.date", Sort.ASCENDING)
29 |
30 | try {
31 | val ps4Games = wrapper.games(query)
32 | assert(ps4Games.isNotEmpty())
33 | } catch (e: RequestException) {
34 | assert(false)
35 | }
36 | }
37 |
38 | //Get all Recently released PS4 games
39 | @Test
40 | fun testRecentlyReleasedPS4Games() {
41 | val date = (System.currentTimeMillis() / 1000).toString()
42 | val query = APICalypse()
43 | .fields("*")
44 | .where("platforms = 48 & release_dates.date < $date")
45 | .sort("release_dates.date", Sort.DESCENDING)
46 |
47 | try {
48 | val ps4Games = wrapper.games(query)
49 | assert(ps4Games.isNotEmpty())
50 | } catch (e: RequestException) {
51 | assert(false)
52 | }
53 | }
54 |
55 | //Get all Recently released PS4 games
56 | @Test
57 | fun testSearch() {
58 | val query = APICalypse()
59 | .search("Assassins Creed")
60 | .fields("game.name,game.involved_companies")
61 | .where("game != null & game.version_parent = null")
62 |
63 | try {
64 | val result = wrapper.search(query)
65 | assert(result.isNotEmpty())
66 | } catch (e: RequestException) {
67 | assert(false)
68 | }
69 |
70 | }
71 |
72 | //Get all Recently released PS4 games
73 | @Test
74 | fun testPS4Exclusives() {
75 | val query = APICalypse()
76 | .fields("name,category,platforms")
77 | .where("category = 0 & platforms = 48")
78 |
79 | try {
80 | val result = wrapper.games(query)
81 | assert(result.isNotEmpty())
82 | } catch (e: RequestException) {
83 | assert(false)
84 | }
85 |
86 | }
87 |
88 | }
--------------------------------------------------------------------------------
/src/test/kotlin/com/api/igdb/TestImageBuilder.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb
2 |
3 | import com.api.igdb.apicalypse.APICalypse
4 | import com.api.igdb.exceptions.RequestException
5 | import com.api.igdb.request.IGDBWrapper
6 | import com.api.igdb.request.covers
7 | import com.api.igdb.utils.ImageSize
8 | import com.api.igdb.utils.ImageType
9 | import com.api.igdb.utils.imageBuilder
10 | import org.junit.jupiter.api.BeforeEach
11 | import org.junit.jupiter.api.Test
12 |
13 | class TestImageBuilder {
14 |
15 | private val wrapper = IGDBWrapper
16 |
17 | @BeforeEach
18 | fun setup() {
19 | wrapper.setCredentials(System.getenv("client_id"), System.getenv("bearer"))
20 | }
21 |
22 | @Test
23 | fun testJPEGImg() {
24 | val query = APICalypse()
25 | .fields("image_id")
26 | .where("image_id != n")
27 | try {
28 | val covers = wrapper.covers(query)
29 | assert(covers.isNotEmpty())
30 | val firstCover = covers.first()
31 | val coverUrl = imageBuilder(firstCover.imageId, ImageSize.HD, ImageType.JPEG)
32 | assert(coverUrl.isNotBlank())
33 | assert(coverUrl.substringAfterLast(".") == "jpg")
34 |
35 | } catch (e: RequestException) {
36 | assert(false)
37 | }
38 | }
39 |
40 | @Test
41 | fun testPNGImg() {
42 | val query = APICalypse()
43 | .fields("image_id")
44 | .where("image_id != n")
45 | try {
46 | val covers = wrapper.covers(query)
47 | assert(covers.isNotEmpty())
48 | val firstCover = covers.first()
49 | val coverUrl = imageBuilder(firstCover.imageId, ImageSize.THUMB, ImageType.PNG)
50 | assert(coverUrl.isNotBlank())
51 | assert(coverUrl.substringAfterLast(".") == "png")
52 |
53 | } catch (e: RequestException) {
54 | assert(false)
55 | }
56 | }
57 |
58 | @Test
59 | fun testGIFImg() {
60 | val query = APICalypse()
61 | .fields("image_id")
62 | .where("image_id != n")
63 | try {
64 | val covers = wrapper.covers(query)
65 | assert(covers.isNotEmpty())
66 | val firstCover = covers.first()
67 | val coverUrl = imageBuilder(firstCover.imageId, ImageSize.LOGO_MEDIUM, ImageType.GIF)
68 | assert(coverUrl.isNotBlank())
69 | assert(coverUrl.substringAfterLast(".") == "gif")
70 |
71 | } catch (e: RequestException) {
72 | assert(false)
73 | }
74 | }
75 |
76 | @Test
77 | fun testWEBPImg() {
78 | val query = APICalypse()
79 | .fields("image_id")
80 | .where("image_id != n")
81 | try {
82 | val covers = wrapper.covers(query)
83 | assert(covers.isNotEmpty())
84 | val firstCover = covers.first()
85 | val coverUrl = imageBuilder(firstCover.imageId, ImageSize.SCREENSHOT_HUGE, ImageType.WEBP)
86 | assert(coverUrl.isNotBlank())
87 | assert(coverUrl.substringAfterLast(".") == "webp")
88 |
89 | } catch (e: RequestException) {
90 | assert(false)
91 | }
92 | }
93 |
94 | }
--------------------------------------------------------------------------------
/src/test/kotlin/com/api/igdb/TestProtobufRequest.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb
2 |
3 | import com.api.igdb.apicalypse.APICalypse
4 | import com.api.igdb.request.IGDBWrapper
5 | import com.api.igdb.request.*
6 | import org.junit.jupiter.api.Assertions.assertEquals
7 | import org.junit.jupiter.api.Assertions.assertNotEquals
8 | import org.junit.jupiter.api.BeforeEach
9 | import org.junit.jupiter.api.Test
10 |
11 | class TestProtobufRequest {
12 |
13 | private val wrapper = IGDBWrapper
14 |
15 | private val apiCalypseQuery = APICalypse().fields("*")
16 |
17 | @BeforeEach
18 | fun setup() {
19 | wrapper.setCredentials(System.getenv("client_id"), System.getenv("bearer"))
20 | }
21 |
22 | @Test
23 | fun testAgeRating() {
24 | val result = wrapper.ageRatings(apiCalypseQuery)
25 | assert(result.isNotEmpty())
26 | }
27 |
28 | @Test
29 | fun testAgeRatingCategories() {
30 | val result = wrapper.ageRatingCategories(apiCalypseQuery)
31 | assert(result.isNotEmpty())
32 | }
33 |
34 | @Test
35 | fun testAgeRatingContentDescriptions() {
36 | val result = wrapper.ageRatingContentDescriptions(apiCalypseQuery)
37 | assert(result.isNotEmpty())
38 | }
39 |
40 | @Test
41 | fun testAgeRatingContentDescriptionsV2() {
42 | val result = wrapper.ageRatingContentDescriptionsV2(apiCalypseQuery)
43 | assert(result.isNotEmpty())
44 | }
45 |
46 | @Test
47 | fun testAgeRatingOrganizations() {
48 | val result = wrapper.ageRatingOrganizations(apiCalypseQuery)
49 | assert(result.isNotEmpty())
50 | }
51 |
52 | @Test
53 | fun testAlternativeNames() {
54 | val result = wrapper.alternativeNames(apiCalypseQuery)
55 | assert(result.isNotEmpty())
56 | }
57 |
58 | @Test
59 | fun testArtwork() {
60 | val result = wrapper.artworks(apiCalypseQuery)
61 | assert(result.isNotEmpty())
62 | }
63 |
64 | @Test
65 | fun testCharactersGenders() {
66 | val result = wrapper.characterGenders(apiCalypseQuery)
67 | assert(result.isNotEmpty())
68 | }
69 |
70 | @Test
71 | fun testCharacterSpecies() {
72 | val result = wrapper.characterSpecies(apiCalypseQuery)
73 | assert(result.isNotEmpty())
74 | }
75 |
76 | @Test
77 | fun testCharacters() {
78 | val result = wrapper.characters(apiCalypseQuery)
79 | assert(result.isNotEmpty())
80 | }
81 |
82 | @Test
83 | fun testCollections() {
84 | val result = wrapper.collections(apiCalypseQuery)
85 | assert(result.isNotEmpty())
86 | }
87 |
88 | @Test
89 | fun testCharacterMugShots() {
90 | val result = wrapper.characterMugShots(apiCalypseQuery)
91 | assert(result.isNotEmpty())
92 | }
93 |
94 | @Test
95 | fun testCompanies() {
96 | val result = wrapper.companies(apiCalypseQuery)
97 | assert(result.isNotEmpty())
98 | }
99 |
100 | @Test
101 | fun testCompanyStatuses() {
102 | val result = wrapper.companyStatuses(apiCalypseQuery)
103 | assert(result.isNotEmpty())
104 | }
105 |
106 | @Test
107 | fun testComapnyWebsites() {
108 | val result = wrapper.companyWebsites(apiCalypseQuery)
109 | assert(result.isNotEmpty())
110 | }
111 |
112 | @Test
113 | fun testCompantLogos() {
114 | val result = wrapper.companyLogos(apiCalypseQuery)
115 | assert(result.isNotEmpty())
116 | }
117 |
118 | @Test
119 | fun testCover() {
120 | val result = wrapper.covers(apiCalypseQuery)
121 | assert(result.isNotEmpty())
122 | }
123 |
124 | @Test
125 | fun testDateFormats() {
126 | val result = wrapper.dateFormats(apiCalypseQuery)
127 | assert(result.isNotEmpty())
128 | }
129 |
130 | @Test
131 | fun testExternalGames() {
132 | val result = wrapper.externalGames(apiCalypseQuery)
133 | assert(result.isNotEmpty())
134 | }
135 |
136 | @Test
137 | fun testExternalGameSources() {
138 | val result = wrapper.externalGameSources(apiCalypseQuery)
139 | assert(result.isNotEmpty())
140 | }
141 |
142 | @Test
143 | fun testFranschises() {
144 | val result = wrapper.franchises(apiCalypseQuery)
145 | assert(result.isNotEmpty())
146 | }
147 |
148 | @Test
149 | fun testGames() {
150 | val result = wrapper.games(APICalypse()
151 | .fields("*, age_ratings.*, alternative_names.*, cover.*, external_games.*, franchises.*, genres.*, screenshots.*, videos.*")
152 | .where("id = 1942"))
153 | assert(result.isNotEmpty())
154 | val game = result.first()
155 | assertEquals("The Witcher 3: Wild Hunt", game.name)
156 | assertEquals("the-witcher-3-wild-hunt", game.slug)
157 | assert(game.name.isNotEmpty())
158 | assert(game.hasCreatedAt())
159 | if (game.checksum.isNullOrBlank()) println("checksumField empty") else println(game.checksum)
160 | assertNotEquals(" ", game.checksum)
161 |
162 | val ageRatings = game.ageRatingsList
163 | val ageRating = ageRatings.first()
164 | assert(ageRating.contentDescriptionsList.isNotEmpty())
165 | assert(ageRating.ratingContentDescriptionsList.isNotEmpty())
166 | assert(ageRating.hasOrganization())
167 | assert(ageRating.hasRatingCategory())
168 | if (ageRating.checksum.isNullOrBlank()) println("checksumField empty") else println(ageRating.checksum)
169 | assertNotEquals(" ", ageRating.checksum)
170 |
171 | val alternativeNames = game.alternativeNamesList
172 | assert(alternativeNames.isNotEmpty())
173 | if (alternativeNames.first().checksum.isNullOrBlank()) println("checksumField empty") else println(alternativeNames.first().checksum)
174 | assertNotEquals(" ", alternativeNames.first().checksum)
175 |
176 | val cover = game.cover
177 | assertNotEquals(" ", cover.imageId)
178 | if (cover.checksum.isNullOrBlank()) println("checksumField empty") else println(cover.checksum)
179 | assertNotEquals(" ", cover.checksum)
180 |
181 | val externalGames = game.externalGamesList
182 | assert(externalGames.isNotEmpty())
183 | if (externalGames.first().checksum.isNullOrBlank()) println("checksumField empty") else println(externalGames.first().checksum)
184 | assertNotEquals(" ", externalGames.first().checksum)
185 |
186 | val franchises = game.franchisesList
187 | assert(franchises.first().id == 452L)
188 | assertEquals("the-witcher", franchises.first().slug)
189 | val franchiseGames = franchises.first().gamesList
190 | assert(franchiseGames.isNotEmpty())
191 |
192 | val involvedCompany = game.involvedCompaniesList
193 | assert(involvedCompany.isNotEmpty())
194 |
195 | val genres = game.genresList
196 | assert(genres.isNotEmpty())
197 |
198 | val releaseDates = game.releaseDatesList
199 | assert(releaseDates.isNotEmpty())
200 |
201 | val screenshots = game.screenshotsList
202 | assert(screenshots.isNotEmpty())
203 | val screenshot = screenshots.first()
204 | assertNotEquals(" ", screenshot.imageId)
205 | assertNotEquals(" ", screenshot.checksum)
206 |
207 | val videos = game.videosList
208 | assert(videos.isNotEmpty())
209 | val video = videos.first()
210 | assertNotEquals(" ", video.checksum)
211 | assertNotEquals(" ", video.videoId)
212 | }
213 |
214 | @Test
215 | fun testGameEngines() {
216 | val result = wrapper.gameEngines(apiCalypseQuery)
217 | assert(result.isNotEmpty())
218 | }
219 |
220 | @Test
221 | fun testGameEngineLogos() {
222 | val result = wrapper.gameEngineLogos(apiCalypseQuery)
223 | assert(result.isNotEmpty())
224 | }
225 |
226 | @Test
227 | fun testGameLocalizations() {
228 | val result = wrapper.gameLocalizations(apiCalypseQuery)
229 | assert(result.isNotEmpty())
230 | }
231 |
232 | @Test
233 | fun testGameModes() {
234 | val result = wrapper.gameModes(apiCalypseQuery)
235 | assert(result.isNotEmpty())
236 | }
237 |
238 | @Test
239 | fun testGameReleaseFormats() {
240 | val result = wrapper.gameReleaseFormats(apiCalypseQuery)
241 | assert(result.isNotEmpty())
242 | }
243 |
244 | @Test
245 | fun testGameStatuses() {
246 | val result = wrapper.gameStatuses(apiCalypseQuery)
247 | assert(result.isNotEmpty())
248 | }
249 |
250 | @Test
251 | fun testGameTimeToBeats() {
252 | val result = wrapper.gameTimeToBeats(apiCalypseQuery)
253 | assert(result.isNotEmpty())
254 | }
255 |
256 | @Test
257 | fun testGameTypes() {
258 | val result = wrapper.gameTypes(apiCalypseQuery)
259 | assert(result.isNotEmpty())
260 | }
261 |
262 | @Test
263 | fun testGameVersions() {
264 | val result = wrapper.gameVersion(apiCalypseQuery)
265 | assert(result.isNotEmpty())
266 | }
267 |
268 | @Test
269 | fun testGameVersionFeatures() {
270 | val result = wrapper.gameVersionFeatures(apiCalypseQuery)
271 | assert(result.isNotEmpty())
272 | }
273 |
274 | @Test
275 | fun testGameVersionFeatureValues() {
276 | val result = wrapper.gameVersionFeatureValues(apiCalypseQuery)
277 | assert(result.isNotEmpty())
278 | }
279 |
280 | @Test
281 | fun testGameVideos() {
282 | val result = wrapper.gameVideos(apiCalypseQuery)
283 | assert(result.isNotEmpty())
284 | }
285 |
286 | @Test
287 | fun testGenres() {
288 | val result = wrapper.genres(apiCalypseQuery)
289 | assert(result.isNotEmpty())
290 | }
291 |
292 | @Test
293 | fun testInvolvedCompanies() {
294 | val result = wrapper.involvedCompanies(apiCalypseQuery)
295 | assert(result.isNotEmpty())
296 | }
297 |
298 | @Test
299 | fun testKeywords() {
300 | val result = wrapper.keywords(apiCalypseQuery)
301 | assert(result.isNotEmpty())
302 | }
303 |
304 | @Test
305 | fun testMultiplayerModes() {
306 | val result = wrapper.multiplayerModes(apiCalypseQuery)
307 | assert(result.isNotEmpty())
308 | }
309 |
310 | @Test
311 | fun testPlatforms() {
312 | val result = wrapper.platforms(apiCalypseQuery)
313 | assert(result.isNotEmpty())
314 | }
315 |
316 | @Test
317 | fun testPlatformLogos() {
318 | val result = wrapper.platformLogos(apiCalypseQuery)
319 | assert(result.isNotEmpty())
320 | }
321 |
322 | @Test
323 | fun testPlatformTypes() {
324 | val result = wrapper.platformTypes(apiCalypseQuery)
325 | assert(result.isNotEmpty())
326 | }
327 |
328 | @Test
329 | fun testPlatformVersions() {
330 | val result = wrapper.platformVersions(apiCalypseQuery)
331 | assert(result.isNotEmpty())
332 | }
333 |
334 | @Test
335 | fun testPlatformVerisonCompanies() {
336 | val result = wrapper.platformVersionCompanies(apiCalypseQuery)
337 | assert(result.isNotEmpty())
338 | }
339 |
340 | @Test
341 | fun testPlatformVersionReleaseDates() {
342 | val result = wrapper.platformVersionReleaseDates(apiCalypseQuery)
343 | assert(result.isNotEmpty())
344 | }
345 |
346 | @Test
347 | fun testPlatformWebsites() {
348 | val result = wrapper.platformWebsites(apiCalypseQuery)
349 | assert(result.isNotEmpty())
350 | }
351 |
352 | @Test
353 | fun testPlayerPerspectives() {
354 | val result = wrapper.playerPerspectives(apiCalypseQuery)
355 | assert(result.isNotEmpty())
356 | }
357 |
358 | @Test
359 | fun testProductFamilies() {
360 | val result = wrapper.platformFamilies(apiCalypseQuery)
361 | assert(result.isNotEmpty())
362 | }
363 |
364 | @Test
365 | fun testRegions() {
366 | val result = wrapper.regions(apiCalypseQuery)
367 | assert(result.isNotEmpty())
368 | }
369 |
370 | @Test
371 | fun testReleaseDates() {
372 | val result = wrapper.releaseDates(apiCalypseQuery)
373 | assert(result.isNotEmpty())
374 | }
375 |
376 | @Test
377 | fun testReleaseDateRegions() {
378 | val result = wrapper.releaseDateRegions(apiCalypseQuery)
379 | assert(result.isNotEmpty())
380 | }
381 |
382 | @Test
383 | fun testScreenshots() {
384 | val result = wrapper.screenshots(apiCalypseQuery)
385 | assert(result.isNotEmpty())
386 | }
387 |
388 | @Test
389 | fun testSearch() {
390 | val result = wrapper.search(apiCalypseQuery)
391 | assert(result.isNotEmpty())
392 | }
393 |
394 | @Test
395 | fun testThemes() {
396 | val result = wrapper.themes(apiCalypseQuery)
397 | assert(result.isNotEmpty())
398 | }
399 |
400 | @Test
401 | fun testWebsites() {
402 | val result = wrapper.websites(apiCalypseQuery)
403 | assert(result.isNotEmpty())
404 | }
405 |
406 | @Test
407 | fun testWebsiteTypes() {
408 | val result = wrapper.websiteTypes(apiCalypseQuery)
409 | assert(result.isNotEmpty())
410 | }
411 |
412 | @Test
413 | fun testEvents() {
414 | val result = wrapper.events(apiCalypseQuery)
415 | assert(result.isNotEmpty())
416 | }
417 |
418 | @Test
419 | fun testEventLogos() {
420 | val result = wrapper.eventLogos(apiCalypseQuery)
421 | assert(result.isNotEmpty())
422 | }
423 |
424 | @Test
425 | fun testEventNetworks() {
426 | val result = wrapper.eventNetworks(apiCalypseQuery)
427 | assert(result.isNotEmpty())
428 | }
429 |
430 | @Test
431 | fun testNetworkTypes() {
432 | val result = wrapper.networkTypes(apiCalypseQuery)
433 | assert(result.isNotEmpty())
434 | }
435 |
436 | @Test
437 | fun testCollectionRelations() {
438 | val result = wrapper.collectionRelations(apiCalypseQuery)
439 | assert(result.isNotEmpty())
440 | }
441 |
442 | @Test
443 | fun testCollectionRelationTypes() {
444 | val result = wrapper.collectionRelationTypes(apiCalypseQuery)
445 | assert(result.isNotEmpty())
446 | }
447 |
448 | @Test
449 | fun testCollectionTypes() {
450 | val result = wrapper.collectionTypes(apiCalypseQuery)
451 | assert(result.isNotEmpty())
452 | }
453 |
454 | @Test
455 | fun testCollectionMemberships() {
456 | val result = wrapper.collectionMemberships(apiCalypseQuery)
457 | assert(result.isNotEmpty())
458 | }
459 |
460 | @Test
461 | fun testCollectionMembershipTypes() {
462 | val result = wrapper.collectionMembershipTypes(apiCalypseQuery)
463 | assert(result.isNotEmpty())
464 | }
465 |
466 | @Test
467 | fun testPopularityTypes() {
468 | val result = wrapper.popularityTypes(APICalypse().fields("*"))
469 | assert(result.isNotEmpty())
470 | assert(result.first().hasExternalPopularitySource())
471 | }
472 |
473 | @Test
474 | fun testPopularityPrimitives() {
475 | val result = wrapper.popularityPrimitives(APICalypse().fields("*"))
476 | assert(result.isNotEmpty())
477 | assert(result.first().hasExternalPopularitySource())
478 | assert(result.first().hasCalculatedAt())
479 | assert(result.first().value > 0)
480 | }
481 |
482 | }
483 |
--------------------------------------------------------------------------------
/src/test/kotlin/com/api/igdb/TestProxy.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb
2 |
3 | import com.api.igdb.apicalypse.APICalypse
4 | import com.api.igdb.apicalypse.Sort
5 | import com.api.igdb.exceptions.RequestException
6 | import com.api.igdb.request.IGDBWrapper
7 | import com.api.igdb.request.games
8 | import com.api.igdb.request.search
9 | import org.junit.jupiter.api.BeforeEach
10 | import org.junit.jupiter.api.Test
11 |
12 | class TestProxy {
13 |
14 | private val wrapper = IGDBWrapper
15 |
16 | @BeforeEach
17 | fun setup() {
18 | wrapper.setupProxy(proxyURL = System.getenv("proxy_url"), proxyHeaders = mapOf("x-api-key" to System.getenv("proxy_api_key")))
19 | }
20 |
21 | //Get all Coming Soon PS4 games
22 | @Test
23 | fun testComingSoonPS4Games() {
24 | val date = (System.currentTimeMillis() / 1000).toString()
25 | val query = APICalypse()
26 | .fields("*")
27 | .where("platforms = 48 & release_dates.date > $date")
28 | .sort("release_dates.date", Sort.ASCENDING)
29 |
30 | try {
31 | val ps4Games = wrapper.games(query)
32 | assert(ps4Games.isNotEmpty())
33 | } catch (e: RequestException) {
34 | assert(false)
35 | }
36 | }
37 |
38 | //Get all Recently released PS4 games
39 | @Test
40 | fun testRecentlyReleasedPS4Games() {
41 | val date = (System.currentTimeMillis() / 1000).toString()
42 | val query = APICalypse()
43 | .fields("*")
44 | .where("platforms = 48 & release_dates.date < $date")
45 | .sort("release_dates.date", Sort.DESCENDING)
46 |
47 | try {
48 | val ps4Games = wrapper.games(query)
49 | assert(ps4Games.isNotEmpty())
50 | } catch (e: RequestException) {
51 | assert(false)
52 | }
53 | }
54 |
55 | //Get all Recently released PS4 games
56 | @Test
57 | fun testSearch() {
58 | val query = APICalypse()
59 | .search("Assassins Creed")
60 | .fields("game.name,game.involved_companies")
61 | .where("game != null & game.version_parent = null")
62 |
63 | try {
64 | val result = wrapper.search(query)
65 | assert(result.isNotEmpty())
66 | } catch (e: RequestException) {
67 | assert(false)
68 | }
69 |
70 | }
71 |
72 | //Get all Recently released PS4 games
73 | @Test
74 | fun testPS4Exclusives() {
75 | val query = APICalypse()
76 | .fields("name,category,platforms")
77 | .where("category = 0 & platforms = 48")
78 |
79 | try {
80 | val result = wrapper.games(query)
81 | assert(result.isNotEmpty())
82 | } catch (e: RequestException) {
83 | assert(false)
84 | }
85 |
86 | }
87 |
88 | }
--------------------------------------------------------------------------------
/src/test/kotlin/com/api/igdb/TestRequestException.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb
2 |
3 | import com.api.igdb.apicalypse.APICalypse
4 | import com.api.igdb.exceptions.RequestException
5 | import com.api.igdb.request.IGDBWrapper
6 | import com.api.igdb.request.games
7 | import com.api.igdb.request.jsonGameModes
8 | import org.junit.jupiter.api.Assertions
9 | import org.junit.jupiter.api.BeforeAll
10 | import org.junit.jupiter.api.BeforeEach
11 | import org.junit.jupiter.api.Test
12 | import org.junit.jupiter.api.TestInstance
13 | import org.junit.jupiter.api.assertThrows
14 |
15 | @TestInstance(TestInstance.Lifecycle.PER_CLASS)
16 | class TestRequestExceptions {
17 | private val wrapper = IGDBWrapper
18 |
19 | @BeforeAll
20 | internal fun beforeAll() {
21 | wrapper.setCredentials("", "")
22 | }
23 |
24 | @Test
25 | fun testNoKeyException() {
26 | try {
27 | wrapper.games(APICalypse())
28 | } catch (e: RequestException){
29 | Assertions.assertEquals(401, e.statusCode)
30 | }
31 | }
32 |
33 | @Test
34 | fun testException() {
35 | assertThrows {
36 | wrapper.jsonGameModes(APICalypse())
37 | }
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/src/test/kotlin/com/api/igdb/TestTwitchTokenKotlin.kt:
--------------------------------------------------------------------------------
1 | package com.api.igdb
2 |
3 | import com.api.igdb.request.TwitchAuthenticator
4 | import org.junit.jupiter.api.Test
5 | import java.time.Duration
6 |
7 | class TestTwitchTokenKotlin {
8 | @Test
9 | fun testGetTwitchToken() {
10 | // request a new Twitch Authentication token
11 | val token = TwitchAuthenticator.requestTwitchToken(System.getenv("client_id"), System.getenv("client_secret"))
12 |
13 | assert(token != null)
14 | assert(token!!.expires_in > Duration.ofDays(57).toSeconds())
15 | val tokenFutureDate = System.currentTimeMillis() + Duration.ofDays(57).toSeconds()
16 | assert(tokenFutureDate > token.getExpiresUnix())
17 | }
18 | }
--------------------------------------------------------------------------------