diff --git a/.gitignore b/.gitignore
index ab0999e..cee57ed 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,8 +9,7 @@ tmp/
*.bak
*.swp
*~.nib
-tokens.properties
-local.properties
+*.properties
.settings/
.loadpath
.recommenders
diff --git a/README.md b/README.md
index 754c145..1210c52 100644
--- a/README.md
+++ b/README.md
@@ -7,12 +7,33 @@
-ClashAPI is a very simple yet very complete Kotlin wrapper for the Clash of Clans mobile game API. It allows developers to easily do requests to the game API without bothering about JSON and HTTP handling.
+ClashAPI is a very simple yet very complete Kotlin wrapper for the Clash of Clans mobile game API.
+It allows developers to easily do requests to the game API without bothering about JSON and HTTP handling.
+It is intended to be lightweight and as intuitive as possible to use.
## How does it work?
-I analyzed JSON responses from the Clash of Clans API to recreate the models as Java structures so you don't have to deal with deserialization and data categorization each time. You can therefore simply access game data through classes and methods, all documented!
+I analyzed JSON responses from the Clash of Clans API to recreate the models as Java structures so you don't have to deal with deserialization and data categorization each time. You can therefore simply access game data through your Java/Kotlin (JVM) classes and methods, all documented!
+
+## Setup
+ClashAPI is available on Maven Central. You can add it to your project using Maven or Gradle.
+
+### Maven
+Inside your `` scope of your `pom.xml` file, add the following:
+```xml
+
+ io.github.lycoon
+ clash-api
+ 5.0.0
+
+```
+
+### Gradle
+Inside your `dependencies` scope of your `build.gradle` file, add the following:
+```gradle
+implementation 'io.github.lycoon:clash-api:5.0.0'
+```
-## How to use it?
+## Quick start
```java
// 1. Create an instance of ClashAPI by providing your Clash of Clans API token to the constructor
ClashAPI clashAPI = new ClashAPI("token");
@@ -31,9 +52,8 @@ In order to make calls to the Clash of Clans API, Supercell (developer of the ga
Though this token is linked to the IP address you gave, I would advise **not to hardcode it** inside your code, for safety sake. Paste it in a separate file that you would access from your code. It will prevent your token being spread if you ever share your files.
-## Dependencies
-* Kotlin serialization `1.3.1`
-* OkHttp `4.9.3`
+## Report bugs
+You've found a bug? Let me know by opening an issue.
## Disclaimer
*This material is unofficial and is not endorsed by Supercell. For more information see Supercell's Fan Content Policy: www.supercell.com/fan-content-policy.*
diff --git a/pom.xml b/pom.xml
index 30f4ffe..055c6ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
io.github.lycoon
clash-api
- 4.0.0
+ 5.0.0
${project.groupId}:${project.artifactId}
diff --git a/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt b/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt
index 6569f09..51d2f25 100644
--- a/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt
+++ b/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt
@@ -2,412 +2,256 @@ package com.lycoon.clashapi.core
import com.lycoon.clashapi.core.CoreUtils.deserialize
import com.lycoon.clashapi.core.CoreUtils.formatTag
-import com.lycoon.clashapi.core.CoreUtils.checkResponse
-import com.lycoon.clashapi.core.exception.ClashAPIException
+import com.lycoon.clashapi.core.CoreUtils.unwrapList
+import com.lycoon.clashapi.core.interfaces.*
+import com.lycoon.clashapi.models.capital.CapitalRaidSeason
+import com.lycoon.clashapi.models.capital.CapitalRanking
import com.lycoon.clashapi.models.clan.*
import com.lycoon.clashapi.models.common.*
+import com.lycoon.clashapi.models.league.BuilderBaseLeague
+import com.lycoon.clashapi.models.league.CapitalLeague
import com.lycoon.clashapi.models.league.League
-import com.lycoon.clashapi.models.league.LeagueList
import com.lycoon.clashapi.models.league.LeagueSeason
-import com.lycoon.clashapi.models.league.LeagueSeasonList
import com.lycoon.clashapi.models.player.*
import com.lycoon.clashapi.models.war.War
-import com.lycoon.clashapi.models.war.Warlog
import com.lycoon.clashapi.models.war.WarlogEntry
import com.lycoon.clashapi.models.warleague.WarLeague
import com.lycoon.clashapi.models.warleague.WarLeagueGroup
-import com.lycoon.clashapi.models.warleague.WarLeagueList
-import okhttp3.*
-import okhttp3.MediaType.Companion.toMediaTypeOrNull
-import okhttp3.RequestBody.Companion.toRequestBody
-import java.io.IOException
+
+interface IClashAPI: IClanAPI, IPlayerAPI, ILeagueAPI, ILocationAPI, IGoldPassAPI, ILabelAPI
/**
* Create an instance of this class to start using the API.
- *
* Are you lost? Check the [README](https://github.com/Lycoon/clash-api) to see what ClashAPI is all about.
*/
-class ClashAPI(private val token: String) {
- private val http: OkHttpClient = OkHttpClient()
- private fun getBaseRequest(suffix: String): Request.Builder {
- return Request.Builder()
- .header("authorization", "Bearer $token")
- .url(CoreUtils.URL + CoreUtils.API_VERSION + suffix)
- }
-
- @Throws(IOException::class, ClashAPIException::class)
- private fun get(url: String): Response {
- val res = http.newCall(getBaseRequest(url).build()).execute()
- return checkResponse(res)
- }
-
- @Throws(IOException::class, ClashAPIException::class)
- private fun post(url: String, body: RequestBody): Response {
- val res = http.newCall(getBaseRequest(url).post(body).build()).execute()
- return checkResponse(res)
- }
-
- private fun getTokenVerificationBody(token: String) : RequestBody {
- val contentType: MediaType? = "application/json; charset=utf-8".toMediaTypeOrNull()
- return "{\"token\":\"$token\"}".toRequestBody(contentType)
- }
-
- /**
- * Returns the warleague group in which the clan with the given tag is.
- *
- * @param clanTag `String` of the clan's tag
- * @return WarLeagueGroup
- * @see WarLeagueGroup
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getWarLeagueGroup(clanTag: String): WarLeagueGroup {
+class ClashAPI(token: String) : ClashAPIClient(token), IClashAPI
+{
+ // ##############################################
+ // || Clans API ||
+ // ##############################################
+
+ override fun getWarLeagueGroup(clanTag: String): WarLeagueGroup
+ {
val tag = formatTag(clanTag)
val res = get("/clans/$tag/currentwar/leaguegroup")
return deserialize(res)
}
- /**
- * Returns an individual warleague war associated to the given war tag.
- * You can obtain individual CWL war tags from:
- * `ClashAPI.getCWLGroup(clanTag).getRounds(index).getWarTags(index)`
- *
- * @param warTag `String` of the war tag
- * @return War
- * @see War
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getWarLeagueWar(warTag: String): War {
+ override fun getWarLeagueWar(warTag: String): War
+ {
val tag = formatTag(warTag)
val res = get("/clanwarleagues/wars/$tag")
return deserialize(res)
}
- /**
- * Returns the warlog of the clan with the given tag.
- *
- * @param clanTag `String` of the clan's tag
- * @return List
- * @see WarlogEntry
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getWarlog(clanTag: String): List {
+ override fun getWarlog(clanTag: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val tag = formatTag(clanTag)
- val res = get("/clans/$tag/warlog")
- return deserialize(res).items
- }
-
- /**
- * Returns the clan war occurring in the clan with the given tag.
- *
- * @param clanTag `String` of the clan's tag
- * @return War
- * @see War
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getCurrentWar(clanTag: String): War {
+ val res = get("/clans/$tag/warlog", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getClans(queryParamsBuilder: ClanQueryParamsBuilder?): List
+ {
+ val res = get("/clans", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getCurrentWar(clanTag: String): War
+ {
val tag = formatTag(clanTag)
val res = get("/clans/$tag/currentwar")
return deserialize(res)
}
- /**
- * Returns the clan attached to the tag.
- *
- * @param clanTag `String` of the clan's tag
- * @return Clan
- * @see Clan
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getClan(clanTag: String): Clan {
+ override fun getClan(clanTag: String): Clan
+ {
val tag = formatTag(clanTag)
val res = get("/clans/$tag")
return deserialize(res)
}
- /**
- * Returns the members of clan attached to the tag.
- *
- * @param clanTag `String` of the clan's tag
- * @return List
- * @see ClanMember
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getClanMembers(clanTag: String): List {
+ override fun getClanMembers(clanTag: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val tag = formatTag(clanTag)
+ val res = get("/clans/$tag/members", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getCapitalRaidSeasons(clanTag: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val tag = formatTag(clanTag)
- val res = get("/clans/$tag/members")
- return deserialize(res).items
- }
-
- /**
- * Returns the player attached to the tag.
- *
- * @param playerTag `String` of the player's tag
- * @return Player
- * @see Player
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getPlayer(playerTag: String): Player {
+ val res = get("/clans/$tag/capitalraidseasons", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ // ##############################################
+ // || Player API ||
+ // ##############################################
+
+ override fun getPlayer(playerTag: String): Player
+ {
val tag = formatTag(playerTag)
val res = get("/players/$tag")
return deserialize(res)
}
- /**
- * Returns whether the given player tag is verified or not.
- *
- * @param playerTag `String` of the player's tag
- * @param token `String` of the player token
- * @return a boolean
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun isVerifiedPlayer(playerTag: String, token: String): Boolean {
+ override fun isVerifiedPlayer(playerTag: String, token: String): Boolean
+ {
val tag = formatTag(playerTag)
val res = post("/players/$tag/verifytoken", getTokenVerificationBody(token))
-
return deserialize(res).status == "ok"
}
- /**
- * Returns all leagues from the game.
- *
- * @return List
- * @see League
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getLeagues(): List {
- val res = get("/leagues")
- return deserialize(res).items
- }
-
- /**
- * Returns league season rankings
- *
- * @param leagueId `String` of the league id
- * @param seasonId `String` of the season id
- * @return List
- * @see PlayerRanking
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getLeagueSeasonRankings(leagueId: String, seasonId: String): List {
- val res = get("/leagues/$leagueId/seasons/$seasonId")
- return deserialize(res).items
- }
-
- /**
- * Returns league information
- *
- * @param leagueId `String` of the league id
- * @return League
- * @see League
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getLeague(leagueId: String): League {
+ // ##############################################
+ // || League API ||
+ // ##############################################
+
+ override fun getCapitalLeagues(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/capitalleagues", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getLeagues(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/leagues", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getLeagueSeasonRankings(
+ leagueId: String, seasonId: String,
+ queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/leagues/$leagueId/seasons/$seasonId", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getCapitalLeague(leagueId: String): CapitalLeague
+ {
+ val res = get("/capitalleagues/$leagueId")
+ return deserialize(res)
+ }
+
+ override fun getBuilderBaseLeague(leagueId: String): BuilderBaseLeague
+ {
+ val res = get("/builderbaseleagues/$leagueId")
+ return deserialize(res)
+ }
+
+ override fun getBuilderBaseLeagues(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/builderbaseleagues", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getLeague(leagueId: String): League
+ {
val res = get("/leagues/$leagueId")
return deserialize(res)
}
- /**
- * Returns league seasons
- *
- * @param leagueId `String` of the league id
- * @return List
- * @see LeagueSeason
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getLeagueSeasons(leagueId: String): List {
- val res = get("/leagues/$leagueId/seasons")
- return deserialize(res).items
- }
-
- /**
- * Returns warleague information
- *
- * @param leagueId `String` of the league id
- * @return WarLeague
- * @see WarLeague
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getWarLeague(leagueId: String): WarLeague {
+ override fun getLeagueSeasons(leagueId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/leagues/$leagueId/seasons", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getWarLeague(leagueId: String): WarLeague
+ {
val res = get("/warleagues/$leagueId")
return deserialize(res)
}
- /**
- * Returns all warleagues
- *
- * @return List
- * @see WarLeague
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getWarLeagues(): List {
- val res = get("/warleagues")
- return deserialize(res).items
- }
-
- /**
- * Returns clan rankings for a specific location
- *
- * @param locationId `String` of the location id
- * @return List
- * @see ClanRanking
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getClanRankings(locationId: String): List {
- val res = get("/locations/${locationId}/rankings/clans")
- return deserialize(res).items
- }
-
- /**
- * Returns clan versus rankings for a specific location
- *
- * @param locationId `String` of the location id
- * @return List
- * @see ClanVersusRanking
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getClanVersusRankings(locationId: String): List {
- val res = get("/locations/${locationId}/rankings/clans-versus")
- return deserialize(res).items
- }
-
- /**
- * Returns player rankings for a specific location
- *
- * @param locationId `String` of the location id
- * @return List
- * @see PlayerRanking
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getPlayerRankings(locationId: String): List {
- val res = get("/locations/${locationId}/rankings/players")
- return deserialize(res).items
- }
-
- /**
- * Returns player versus rankings for a specific location
- *
- * @param locationId `String` of the location id
- * @return List
- * @see PlayerVersusRanking
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getPlayerVersusRankings(locationId: String): List {
- val res = get("/locations/${locationId}/rankings/players-versus")
- return deserialize(res).items
- }
-
- /**
- * Returns locations
- *
- * @return List
- * @see Location
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getLocations(): List {
- val res = get("/locations")
- return deserialize(res).items
- }
-
- /**
- * Returns specific location
- *
- * @param locationId `String` of the location id
- * @return Location
- * @see Location
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getLocation(locationId: String): Location {
+ override fun getWarLeagues(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/warleagues", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ // ##############################################
+ // || Location API ||
+ // ##############################################
+
+ override fun getClanRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/locations/${locationId}/rankings/clans", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getPlayerRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/locations/${locationId}/rankings/players", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getClanBuilderBaseRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/locations/${locationId}/rankings/clans-builder-base", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ @Deprecated("Use getClanBuilderBaseRankings instead")
+ override fun getClanVersusRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/locations/${locationId}/rankings/clans-versus", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getPlayerBuilderBaseRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/locations/${locationId}/rankings/players-builder-base", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ @Deprecated("Use getPlayerBuilderBaseRankings instead")
+ override fun getPlayerVersusRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/locations/${locationId}/rankings/players-versus", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getLocations(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/locations", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getCapitalRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/locations/$locationId/rankings/capitals", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getLocation(locationId: String): Location
+ {
val res = get("/locations/$locationId")
return deserialize(res)
}
- /**
- * Returns player labels
- *
- * @return List
- * @see Label
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getPlayerLabels(): List {
- val res = get("/labels/players")
- return deserialize(res).items
- }
-
- /**
- * Returns clan labels
- *
- * @return List
- * @see Label
- *
- * @throws IOException if the deserialization failed
- * @throws ClashAPIException if the request to the game API failed
- */
- @Throws(IOException::class, ClashAPIException::class)
- fun getClanLabels(): List {
- val res = get("/labels/clans")
- return deserialize(res).items
+ // ##############################################
+ // || GoldPass API ||
+ // ##############################################
+
+ override fun getGoldPass(): GoldPassSeason
+ {
+ val res = get("/goldpass/seasons/current")
+ return deserialize(res)
+ }
+
+ // ##############################################
+ // || Label API ||
+ // ##############################################
+
+ override fun getPlayerLabels(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/labels/players", queryParamsBuilder)
+ return unwrapList(deserialize(res))
+ }
+
+ override fun getClanLabels(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
+ val res = get("/labels/clans", queryParamsBuilder)
+ return unwrapList(deserialize(res))
}
}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/ClashAPIClient.kt b/src/main/java/com/lycoon/clashapi/core/ClashAPIClient.kt
new file mode 100644
index 0000000..c4efb77
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/core/ClashAPIClient.kt
@@ -0,0 +1,41 @@
+package com.lycoon.clashapi.core
+
+import com.lycoon.clashapi.core.exceptions.ClashAPIException
+import okhttp3.*
+import okhttp3.MediaType.Companion.toMediaTypeOrNull
+import okhttp3.RequestBody.Companion.toRequestBody
+import java.io.IOException
+import java.util.concurrent.CompletableFuture
+
+abstract class ClashAPIClient(private val token: String)
+{
+ private val http: OkHttpClient = OkHttpClient()
+ private fun getBaseRequest(suffix: String, queryParamsBuilder: QueryParamsBuilder? = null): Request.Builder
+ {
+ val query = queryParamsBuilder?.build() ?: ""
+ return Request.Builder()
+ .header("authorization", "Bearer $token")
+ .url(CoreUtils.URL + CoreUtils.API_VERSION + suffix + query)
+ }
+
+ @Throws(IOException::class, ClashAPIException::class)
+ protected fun get(url: String, queryParamsBuilder: QueryParamsBuilder? = null): Response
+ {
+ val req = getBaseRequest(url, queryParamsBuilder).build()
+ val res = http.newCall(req).execute()
+ return CoreUtils.checkResponse(res)
+ }
+
+ @Throws(IOException::class, ClashAPIException::class)
+ protected fun post(url: String, body: RequestBody): Response
+ {
+ val res = http.newCall(getBaseRequest(url).post(body).build()).execute()
+ return CoreUtils.checkResponse(res)
+ }
+
+ protected fun getTokenVerificationBody(token: String) : RequestBody
+ {
+ val contentType: MediaType? = "application/json; charset=utf-8".toMediaTypeOrNull()
+ return "{\"token\":\"$token\"}".toRequestBody(contentType)
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/CoreUtils.kt b/src/main/java/com/lycoon/clashapi/core/CoreUtils.kt
index 9af1822..81ba5c1 100644
--- a/src/main/java/com/lycoon/clashapi/core/CoreUtils.kt
+++ b/src/main/java/com/lycoon/clashapi/core/CoreUtils.kt
@@ -1,9 +1,9 @@
package com.lycoon.clashapi.core
-import com.lycoon.clashapi.core.exception.*
+import com.lycoon.clashapi.core.exceptions.*
+import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
-import kotlinx.serialization.json.JsonElement
import okhttp3.Response
import java.io.IOException
@@ -35,7 +35,23 @@ object CoreUtils {
return json.decodeFromString(res.body?.string() ?: "")
}
- fun formatTag(tag: String): String {
+ /*
+ * There are situations where we get a list from the API, but we can't return it directly as List
+ * because the API returns that list inside an object, within a single attribute named 'items' and
+ * Kotlinx Serialization doesn't support that.
+ *
+ * For the concerned routes, we unwrap the list to avoid duplicating useless single-attribute classes
+ * wrapping the list.
+ */
+ @Serializable
+ class WrapperList(val items: List)
+ fun unwrapList(obj: WrapperList): List { return obj.items }
+
+ /*
+ * We don't want to invalidate a request if the provided tag doesn't start with a '#', so we prepend it
+ * if it's not present. The %23 is the URL encoded version of '#'.
+ */
+ fun formatTag(tag: String): String{
return if (tag.startsWith("#")) tag.replace("#", "%23") else "%23$tag"
}
}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/QueryBuilder.kt b/src/main/java/com/lycoon/clashapi/core/QueryBuilder.kt
new file mode 100644
index 0000000..f77c8a1
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/core/QueryBuilder.kt
@@ -0,0 +1,60 @@
+package com.lycoon.clashapi.core
+
+abstract class QueryParamsBuilder(
+ open val limit: Int? = null,
+ open val after: String? = null,
+ open val before: String? = null,
+) {
+ open fun build(): String {
+ append(builder, "limit", limit)
+ append(builder, "after", after)
+ append(builder, "before", before)
+
+ return builder.toString()
+ }
+
+ companion object
+ {
+ fun append(builder: StringBuilder, key: String, value: T)
+ {
+ if (value != null) {
+ builder.append(if (builder.isEmpty()) "?" else "&")
+ builder.append("$key=$value")
+ }
+ }
+ }
+
+ protected val builder = StringBuilder()
+}
+
+class ClanQueryParamsBuilder(
+ override val limit: Int? = null,
+ override val after: String? = null,
+ override val before: String? = null,
+ val name: String? = null,
+ val warFrequency: String? = null,
+ val locationId: Int? = null,
+ val minMembers: Int? = null,
+ val maxMembers: Int? = null,
+ val minClanPoints: Int? = null,
+ val minClanLevel: Int? = null,
+ val labelIds: String? = null
+) : QueryParamsBuilder(limit, after, before)
+{
+ override fun build(): String
+ {
+ append(builder, "name", name)
+ append(builder, "warFrequency", warFrequency)
+ append(builder, "locationId", locationId)
+ append(builder, "minMembers", minMembers)
+ append(builder, "maxMembers", maxMembers)
+ append(builder, "minClanPoints", minClanPoints)
+ append(builder, "minClanLevel", minClanLevel)
+ append(builder, "labelIds", labelIds)
+
+ return super.build()
+ }
+}
+
+class SimpleQueryParamsBuilder(): QueryParamsBuilder(limit = null, after = "", before = "")
+{}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/exception/AuthException.kt b/src/main/java/com/lycoon/clashapi/core/exceptions/AuthException.kt
similarity index 66%
rename from src/main/java/com/lycoon/clashapi/core/exception/AuthException.kt
rename to src/main/java/com/lycoon/clashapi/core/exceptions/AuthException.kt
index a0824ff..622b38d 100644
--- a/src/main/java/com/lycoon/clashapi/core/exception/AuthException.kt
+++ b/src/main/java/com/lycoon/clashapi/core/exceptions/AuthException.kt
@@ -1,6 +1,6 @@
-package com.lycoon.clashapi.core.exception
-
-/**
- * Thrown if the API token is not valid
- */
+package com.lycoon.clashapi.core.exceptions
+
+/**
+ * Thrown if the API token is not valid
+ */
class AuthException : ClashAPIException("403")
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/exception/BadRequestException.kt b/src/main/java/com/lycoon/clashapi/core/exceptions/BadRequestException.kt
similarity index 71%
rename from src/main/java/com/lycoon/clashapi/core/exception/BadRequestException.kt
rename to src/main/java/com/lycoon/clashapi/core/exceptions/BadRequestException.kt
index a4294ed..02d99da 100644
--- a/src/main/java/com/lycoon/clashapi/core/exception/BadRequestException.kt
+++ b/src/main/java/com/lycoon/clashapi/core/exceptions/BadRequestException.kt
@@ -1,6 +1,6 @@
-package com.lycoon.clashapi.core.exception
-
-/**
- * Thrown if incorrect parameters are given to the request
- */
+package com.lycoon.clashapi.core.exceptions
+
+/**
+ * Thrown if incorrect parameters are given to the request
+ */
class BadRequestException : ClashAPIException("400")
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/exception/ClashAPIException.kt b/src/main/java/com/lycoon/clashapi/core/exceptions/ClashAPIException.kt
similarity index 74%
rename from src/main/java/com/lycoon/clashapi/core/exception/ClashAPIException.kt
rename to src/main/java/com/lycoon/clashapi/core/exceptions/ClashAPIException.kt
index acd769d..1d6f8e5 100644
--- a/src/main/java/com/lycoon/clashapi/core/exception/ClashAPIException.kt
+++ b/src/main/java/com/lycoon/clashapi/core/exceptions/ClashAPIException.kt
@@ -1,8 +1,8 @@
-package com.lycoon.clashapi.core.exception
-
-import java.lang.Exception
-
-/**
- * Parent class for ClashAPI exceptions
- */
+package com.lycoon.clashapi.core.exceptions
+
+import java.lang.Exception
+
+/**
+ * Parent class for ClashAPI exceptions
+ */
open class ClashAPIException(message: String) : Exception(message)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/exception/MaintenanceException.kt b/src/main/java/com/lycoon/clashapi/core/exceptions/MaintenanceException.kt
similarity index 76%
rename from src/main/java/com/lycoon/clashapi/core/exception/MaintenanceException.kt
rename to src/main/java/com/lycoon/clashapi/core/exceptions/MaintenanceException.kt
index 5f55cd0..ea29ae7 100644
--- a/src/main/java/com/lycoon/clashapi/core/exception/MaintenanceException.kt
+++ b/src/main/java/com/lycoon/clashapi/core/exceptions/MaintenanceException.kt
@@ -1,6 +1,6 @@
-package com.lycoon.clashapi.core.exception
-
-/**
- * Thrown if the request couldn't be executed because of Clash of Clans undergoing maintenance
- */
+package com.lycoon.clashapi.core.exceptions
+
+/**
+ * Thrown if the request couldn't be executed because of Clash of Clans undergoing maintenance
+ */
class MaintenanceException : ClashAPIException("503")
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/exception/NotFoundException.kt b/src/main/java/com/lycoon/clashapi/core/exceptions/NotFoundException.kt
similarity index 68%
rename from src/main/java/com/lycoon/clashapi/core/exception/NotFoundException.kt
rename to src/main/java/com/lycoon/clashapi/core/exceptions/NotFoundException.kt
index 2e1431d..69b6d41 100644
--- a/src/main/java/com/lycoon/clashapi/core/exception/NotFoundException.kt
+++ b/src/main/java/com/lycoon/clashapi/core/exceptions/NotFoundException.kt
@@ -1,6 +1,6 @@
-package com.lycoon.clashapi.core.exception
-
-/**
- * Thrown when the requested URL is not found
- */
+package com.lycoon.clashapi.core.exceptions
+
+/**
+ * Thrown when the requested URL is not found
+ */
class NotFoundException : ClashAPIException("404")
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/exception/RateLimitException.kt b/src/main/java/com/lycoon/clashapi/core/exceptions/RateLimitException.kt
similarity index 74%
rename from src/main/java/com/lycoon/clashapi/core/exception/RateLimitException.kt
rename to src/main/java/com/lycoon/clashapi/core/exceptions/RateLimitException.kt
index 737fd8d..cac13c1 100644
--- a/src/main/java/com/lycoon/clashapi/core/exception/RateLimitException.kt
+++ b/src/main/java/com/lycoon/clashapi/core/exceptions/RateLimitException.kt
@@ -1,6 +1,6 @@
-package com.lycoon.clashapi.core.exception
-
-/**
- * Thrown when too many requests are made to the game API within a certain period
- */
+package com.lycoon.clashapi.core.exceptions
+
+/**
+ * Thrown when too many requests are made to the game API within a certain period
+ */
class RateLimitException : ClashAPIException("429")
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/exception/UnknownException.kt b/src/main/java/com/lycoon/clashapi/core/exceptions/UnknownException.kt
similarity index 66%
rename from src/main/java/com/lycoon/clashapi/core/exception/UnknownException.kt
rename to src/main/java/com/lycoon/clashapi/core/exceptions/UnknownException.kt
index 7ffbd7b..708c431 100644
--- a/src/main/java/com/lycoon/clashapi/core/exception/UnknownException.kt
+++ b/src/main/java/com/lycoon/clashapi/core/exceptions/UnknownException.kt
@@ -1,6 +1,6 @@
-package com.lycoon.clashapi.core.exception
-
-/**
- * Thrown if an unknown error occurs
- */
+package com.lycoon.clashapi.core.exceptions
+
+/**
+ * Thrown if an unknown error occurs
+ */
class UnknownException : ClashAPIException("500")
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/interfaces/IClanAPI.kt b/src/main/java/com/lycoon/clashapi/core/interfaces/IClanAPI.kt
new file mode 100644
index 0000000..af00f26
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/core/interfaces/IClanAPI.kt
@@ -0,0 +1,123 @@
+package com.lycoon.clashapi.core.interfaces
+
+import com.lycoon.clashapi.core.ClanQueryParamsBuilder
+import com.lycoon.clashapi.core.SimpleQueryParamsBuilder
+import com.lycoon.clashapi.core.exceptions.ClashAPIException
+import com.lycoon.clashapi.models.capital.CapitalRaidSeason
+import com.lycoon.clashapi.models.clan.Clan
+import com.lycoon.clashapi.models.clan.ClanMember
+import com.lycoon.clashapi.models.war.War
+import com.lycoon.clashapi.models.war.WarlogEntry
+import com.lycoon.clashapi.models.warleague.WarLeagueGroup
+import java.io.IOException
+
+interface IClanAPI
+{
+ /**
+ * Returns the warleague group in which the clan with the given tag is.
+ *
+ * @param clanTag `String` of the clan's tag
+ * @return WarLeagueGroup
+ * @see WarLeagueGroup
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getWarLeagueGroup(clanTag: String): WarLeagueGroup
+
+ /**
+ * Returns an individual warleague war associated to the given war tag.
+ * You can obtain individual CWL war tags from:
+ * `ClashAPI.getCWLGroup(clanTag).getRounds(index).getWarTags(index)`
+ *
+ * @param warTag `String` of the war tag
+ * @return War
+ * @see War
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getWarLeagueWar(warTag: String): War
+
+ /**
+ * Returns the warlog of the clan with the given tag.
+ *
+ * @param clanTag `String` of the clan's tag
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see WarlogEntry
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getWarlog(clanTag: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns found clans from a clan search.
+ *
+ * @param queryParamsBuilder (optional) `ClanQueryBuilder` to build the query parameters
+ * @return List
+ * @see Clan
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getClans(queryParamsBuilder: ClanQueryParamsBuilder? = null): List
+
+ /**
+ * Returns the clan war occurring in the clan with the given tag.
+ *
+ * @param clanTag `String` of the clan's tag
+ * @return War
+ * @see War
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getCurrentWar(clanTag: String): War
+
+ /**
+ * Returns the clan attached to the tag.
+ *
+ * @param clanTag `String` of the clan's tag
+ * @return Clan
+ * @see Clan
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getClan(clanTag: String): Clan
+ /**
+ * Returns the members of clan attached to the tag.
+ *
+ * @param clanTag `String` of the clan's tag
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see ClanMember
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getClanMembers(clanTag: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns the capital raid seasons of clan attached to the tag.
+ *
+ * @param clanTag `String` of the clan's tag
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see CapitalRaidSeason
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getCapitalRaidSeasons(clanTag: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/interfaces/IGoldPassAPI.kt b/src/main/java/com/lycoon/clashapi/core/interfaces/IGoldPassAPI.kt
new file mode 100644
index 0000000..dba3318
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/core/interfaces/IGoldPassAPI.kt
@@ -0,0 +1,20 @@
+package com.lycoon.clashapi.core.interfaces
+
+import com.lycoon.clashapi.core.exceptions.ClashAPIException
+import com.lycoon.clashapi.models.common.GoldPassSeason
+import java.io.IOException
+
+interface IGoldPassAPI
+{
+ /**
+ * Returns gold pass information
+ *
+ * @return GoldPassSeason
+ * @see GoldPassSeason
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getGoldPass(): GoldPassSeason
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/interfaces/ILabelAPI.kt b/src/main/java/com/lycoon/clashapi/core/interfaces/ILabelAPI.kt
new file mode 100644
index 0000000..2c84b14
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/core/interfaces/ILabelAPI.kt
@@ -0,0 +1,35 @@
+package com.lycoon.clashapi.core.interfaces
+
+import com.lycoon.clashapi.core.SimpleQueryParamsBuilder
+import com.lycoon.clashapi.core.exceptions.ClashAPIException
+import com.lycoon.clashapi.models.common.Label
+import java.io.IOException
+
+interface ILabelAPI
+{
+ /**
+ * Returns player labels
+ *
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see Label
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getPlayerLabels(queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns clan labels
+ *
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see Label
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getClanLabels(queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/interfaces/ILeagueAPI.kt b/src/main/java/com/lycoon/clashapi/core/interfaces/ILeagueAPI.kt
new file mode 100644
index 0000000..fab79c4
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/core/interfaces/ILeagueAPI.kt
@@ -0,0 +1,151 @@
+package com.lycoon.clashapi.core.interfaces
+
+import com.lycoon.clashapi.core.SimpleQueryParamsBuilder
+import com.lycoon.clashapi.core.exceptions.ClashAPIException
+import com.lycoon.clashapi.models.league.BuilderBaseLeague
+import com.lycoon.clashapi.models.league.CapitalLeague
+import com.lycoon.clashapi.models.league.League
+import com.lycoon.clashapi.models.league.LeagueSeason
+import com.lycoon.clashapi.models.player.PlayerRanking
+import com.lycoon.clashapi.models.warleague.WarLeague
+import java.io.IOException
+
+interface ILeagueAPI
+{
+ /**
+ * Returns all capital leagues from the game.
+ *
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see CapitalLeague
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getCapitalLeagues(queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns all leagues from the game.
+ *
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see League
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getLeagues(queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns league season rankings
+ *
+ * @param leagueId `String` of the league id
+ * @param seasonId `String` of the season id
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see PlayerRanking
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getLeagueSeasonRankings(
+ leagueId: String,
+ seasonId: String,
+ queryParamsBuilder: SimpleQueryParamsBuilder? = null
+ ): List
+
+ /**
+ * Returns capital league information
+ *
+ * @param leagueId `String` of the league id
+ * @return CapitalLeague
+ * @see CapitalLeague
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getCapitalLeague(leagueId: String): CapitalLeague
+
+ /**
+ * Returns builder base league information
+ *
+ * @param leagueId `String` of the league id
+ * @return BuilderBaseLeague
+ * @see BuilderBaseLeague
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getBuilderBaseLeague(leagueId: String): BuilderBaseLeague
+
+ /**
+ * Returns all builder base leagues from the game.
+ *
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see BuilderBaseLeague
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getBuilderBaseLeagues(queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns league information
+ *
+ * @param leagueId `String` of the league id
+ * @return League
+ * @see League
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getLeague(leagueId: String): League
+
+ /**
+ * Returns league seasons
+ *
+ * @param leagueId `String` of the league id
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see LeagueSeason
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getLeagueSeasons(leagueId: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns warleague information
+ *
+ * @param leagueId `String` of the league id
+ * @return WarLeague
+ * @see WarLeague
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getWarLeague(leagueId: String): WarLeague
+
+ /**
+ * Returns all warleagues
+ *
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see WarLeague
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getWarLeagues(queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/interfaces/ILocationAPI.kt b/src/main/java/com/lycoon/clashapi/core/interfaces/ILocationAPI.kt
new file mode 100644
index 0000000..33c1d6a
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/core/interfaces/ILocationAPI.kt
@@ -0,0 +1,140 @@
+package com.lycoon.clashapi.core.interfaces
+
+import com.lycoon.clashapi.core.SimpleQueryParamsBuilder
+import com.lycoon.clashapi.core.exceptions.ClashAPIException
+import com.lycoon.clashapi.models.capital.CapitalRanking
+import com.lycoon.clashapi.models.clan.ClanBuilderBaseRanking
+import com.lycoon.clashapi.models.clan.ClanRanking
+import com.lycoon.clashapi.models.common.Location
+import com.lycoon.clashapi.models.player.PlayerBuilderBaseRanking
+import com.lycoon.clashapi.models.player.PlayerRanking
+import java.io.IOException
+
+interface ILocationAPI
+{
+ /**
+ * Returns clan rankings for a specific location
+ *
+ * @param locationId `String` of the location id
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see ClanRanking
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getClanRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns player rankings for a specific location
+ *
+ * @param locationId `String` of the location id
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see PlayerRanking
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getPlayerRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns clan builder base rankings for a specific location
+ *
+ * @param locationId `String` of the location id
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see ClanBuilderBaseRanking
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getClanBuilderBaseRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns clan versus rankings for a specific location
+ *
+ * @param locationId `String` of the location id
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see ClanBuilderBaseRanking
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Deprecated("Use getClanBuilderBaseRankings instead")
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getClanVersusRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns player builder base rankings for a specific location
+ *
+ * @param locationId `String` of the location id
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see PlayerBuilderBaseRanking
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getPlayerBuilderBaseRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns player versus rankings for a specific location
+ *
+ * @param locationId `String` of the location id
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see PlayerBuilderBaseRanking
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Deprecated("Use getPlayerBuilderBaseRankings instead")
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getPlayerVersusRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns locations
+ *
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see Location
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getLocations(queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns capital rankings for a specific location
+ *
+ * @param locationId `String` of the location id
+ * @param queryParamsBuilder (optional) `SimpleQueryParamsBuilder` to build the query parameters
+ * @return List
+ * @see CapitalRanking
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getCapitalRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder? = null): List
+
+ /**
+ * Returns specific location information
+ *
+ * @param locationId `String` of the location id
+ * @return Location
+ * @see Location
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getLocation(locationId: String): Location
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/core/interfaces/IPlayerAPI.kt b/src/main/java/com/lycoon/clashapi/core/interfaces/IPlayerAPI.kt
new file mode 100644
index 0000000..a457ee5
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/core/interfaces/IPlayerAPI.kt
@@ -0,0 +1,34 @@
+package com.lycoon.clashapi.core.interfaces
+
+import com.lycoon.clashapi.core.exceptions.ClashAPIException
+import com.lycoon.clashapi.models.player.Player
+import java.io.IOException
+
+interface IPlayerAPI
+{
+ /**
+ * Returns the player attached to the tag.
+ *
+ * @param playerTag `String` of the player's tag
+ * @return Player
+ * @see Player
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun getPlayer(playerTag: String): Player
+
+ /**
+ * Returns whether the given player tag is verified or not.
+ *
+ * @param playerTag `String` of the player's tag
+ * @param token `String` of the player token
+ * @return a boolean
+ *
+ * @throws IOException if the deserialization failed
+ * @throws ClashAPIException if the request to the game API failed
+ */
+ @Throws(IOException::class, ClashAPIException::class)
+ fun isVerifiedPlayer(playerTag: String, token: String): Boolean
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/CapitalDistrict.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalDistrict.kt
new file mode 100644
index 0000000..28ef42f
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalDistrict.kt
@@ -0,0 +1,11 @@
+package com.lycoon.clashapi.models.capital
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalDistrict
+(
+ val name: String? = null,
+ val id: Int = 0,
+ val districtHallLevel: Int = 0,
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeason.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeason.kt
new file mode 100644
index 0000000..648a0e0
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeason.kt
@@ -0,0 +1,20 @@
+package com.lycoon.clashapi.models.capital
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalRaidSeason
+(
+ val attackLog: List,
+ val defenseLog: List,
+ val state: String? = null,
+ val startTime: String? = null,
+ val endTime: String? = null,
+ val capitalTotalLoot: Int = 0,
+ val raidsCompleted: Int = 0,
+ val totalAttacks: Int = 0,
+ val enemyDistrictsDestroyed: Int = 0,
+ val offensiveReward: Int = 0,
+ val defensiveReward: Int = 0,
+ val members: List
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttack.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttack.kt
new file mode 100644
index 0000000..1e18712
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttack.kt
@@ -0,0 +1,11 @@
+package com.lycoon.clashapi.models.capital
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalRaidSeasonAttack
+(
+ val attacker: CapitalRaidSeasonAttacker,
+ val destructionPercent: Int = 0,
+ val stars: Int = 0
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttackLog.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttackLog.kt
new file mode 100644
index 0000000..b51b250
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttackLog.kt
@@ -0,0 +1,13 @@
+package com.lycoon.clashapi.models.capital
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalRaidSeasonAttackLog
+(
+ val defender: CapitalRaidSeasonClanInfo,
+ val attackCount: Int = 0,
+ val districtCount: Int = 0,
+ val districtsDestroyed: Int = 0,
+ val districts: List
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttacker.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttacker.kt
new file mode 100644
index 0000000..87c7a9d
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttacker.kt
@@ -0,0 +1,9 @@
+package com.lycoon.clashapi.models.capital
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalRaidSeasonAttacker(
+ val tag: String? = null,
+ val name: String? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonClanInfo.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonClanInfo.kt
new file mode 100644
index 0000000..6b7e7df
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonClanInfo.kt
@@ -0,0 +1,13 @@
+package com.lycoon.clashapi.models.capital
+
+import com.lycoon.clashapi.models.common.BadgeUrls
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalRaidSeasonClanInfo
+(
+ val tag: String? = null,
+ val name: String? = null,
+ val level: Int = 0,
+ val badgeUrls: BadgeUrls? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDefenseLog.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDefenseLog.kt
new file mode 100644
index 0000000..908ad59
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDefenseLog.kt
@@ -0,0 +1,13 @@
+package com.lycoon.clashapi.models.capital
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalRaidSeasonDefenseLog
+(
+ val defender: CapitalRaidSeasonClanInfo,
+ val attackCount: Int = 0,
+ val districtCount: Int = 0,
+ val districtsDestroyed: Int = 0,
+ val districts: List
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDistrict.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDistrict.kt
new file mode 100644
index 0000000..5f30264
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDistrict.kt
@@ -0,0 +1,16 @@
+package com.lycoon.clashapi.models.capital
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalRaidSeasonDistrict
+(
+ val id: Int = 0,
+ val name: String? = null,
+ val stars: Int = 0,
+ val destructionPercent: Float = 0f,
+ val attackCount: Int = 0,
+ val totalLooted: Int = 0,
+ val attacks: List,
+ val districtHallLevel: Int = 0
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonMember.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonMember.kt
new file mode 100644
index 0000000..b351788
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonMember.kt
@@ -0,0 +1,14 @@
+package com.lycoon.clashapi.models.capital
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalRaidSeasonMember
+(
+ val tag: String,
+ val name: String,
+ val attacks: Int = 0,
+ val attackLimit: Int = 0,
+ val bonusAttackLimit: Int = 0,
+ val capitalResourcesLooted: Int = 0
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRanking.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRanking.kt
new file mode 100644
index 0000000..c56822e
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRanking.kt
@@ -0,0 +1,9 @@
+package com.lycoon.clashapi.models.capital
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalRanking (
+ val clanPoints: Int = 0,
+ val clanCapitalPoints: Int = 0
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/capital/ClanCapital.kt b/src/main/java/com/lycoon/clashapi/models/capital/ClanCapital.kt
new file mode 100644
index 0000000..55e9918
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/capital/ClanCapital.kt
@@ -0,0 +1,10 @@
+package com.lycoon.clashapi.models.capital
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class ClanCapital
+(
+ val capitalHallLevel: Int = 0,
+ val districts: List,
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/Clan.kt b/src/main/java/com/lycoon/clashapi/models/clan/Clan.kt
index b4c3f00..98098b4 100644
--- a/src/main/java/com/lycoon/clashapi/models/clan/Clan.kt
+++ b/src/main/java/com/lycoon/clashapi/models/clan/Clan.kt
@@ -1,36 +1,57 @@
package com.lycoon.clashapi.models.clan
+import com.lycoon.clashapi.models.capital.ClanCapital
+import com.lycoon.clashapi.models.clan.enums.InviteType
+import com.lycoon.clashapi.models.clan.enums.WarFrequency
import com.lycoon.clashapi.models.common.BadgeUrls
import com.lycoon.clashapi.models.common.Label
import com.lycoon.clashapi.models.common.Language
import com.lycoon.clashapi.models.common.Location
-import com.lycoon.clashapi.models.war.WarMember
+import com.lycoon.clashapi.models.league.CapitalLeague
import com.lycoon.clashapi.models.warleague.WarLeague
+import jdk.nashorn.internal.objects.annotations.Getter
+import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
-data class Clan(
- val warLeague: WarLeague? = null,
- val memberList: List,
+data class Clan
+(
+ @SerialName("type")
+ val inviteType: InviteType,
+
+ @get:Getter(name = "isFamilyFriendly")
+ val isFamilyFriendly: Boolean = false,
+ val tag: String,
+ val name: String,
+ val clanLevel: Int = 0,
+ val clanPoints: Int = 0,
+ val description: String? = null, // nullable when using clan search
+ val chatLanguage: Language? = null, // nullable when not set
+ val labels: List,
+ val location: Location? = null, // nullable when using clan search
+ val badgeUrls: BadgeUrls,
+ val members: Int = 0,
+ val memberList: List = emptyList(), // nullable when using clan search
+
+ @Deprecated("Use requiredBuilderBaseTrophies instead")
val requiredVersusTrophies: Int = 0,
- val requiredTownhallLevel: Int = 0,
+ val requiredBuilderBaseTrophies: Int = 0,
val requiredTrophies: Int = 0,
+ val requiredTownhallLevel: Int = 0,
+
+ @Deprecated("Use clanBuilderBasePoints instead")
val clanVersusPoints: Int = 0,
- val tag: String? = null,
+ val clanBuilderBasePoints: Int = 0,
+ val clanCapitalPoints: Int = 0,
+ val clanCapital: ClanCapital? = null, // nullable if clan has no capital
+
+ @get:Getter(name = "isWarLogPublic")
val isWarLogPublic: Boolean = false,
- val warFrequency: String, // UNKNOWN, ALWAYS, MORE_THAN_ONCE_PER_WEEK, ONCE_PER_WEEK, LESS_THAN_ONCE_PER_WEEK, NEVER, ANY
- val clanLevel: Int = 0,
+ val warLeague: WarLeague,
+ val capitalLeague: CapitalLeague,
+ val warFrequency: WarFrequency,
val warWinStreak: Int = 0,
val warWins: Int = 0,
val warTies: Int = 0,
val warLosses: Int = 0,
- val clanPoints: Int = 0,
- val chatLanguage: Language? = null,
- val labels: List,
- val name: String? = null,
- val location: Location? = null,
- val type: String? = null,
- val members: Int = 0,
- val description: String? = null,
- val badgeUrls: BadgeUrls? = null
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/ClanBuilderBaseRanking.kt b/src/main/java/com/lycoon/clashapi/models/clan/ClanBuilderBaseRanking.kt
new file mode 100644
index 0000000..fbbc7c8
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/clan/ClanBuilderBaseRanking.kt
@@ -0,0 +1,10 @@
+package com.lycoon.clashapi.models.clan
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class ClanBuilderBaseRanking(
+ val clanPoints: Int = 0,
+ val clanBuilderBasePoints: Int = 0,
+ val clanVersusPoints: Int = 0
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/ClanList.kt b/src/main/java/com/lycoon/clashapi/models/clan/ClanList.kt
deleted file mode 100644
index c790511..0000000
--- a/src/main/java/com/lycoon/clashapi/models/clan/ClanList.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.lycoon.clashapi.models.clan
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class ClanList(val items: List)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/ClanMember.kt b/src/main/java/com/lycoon/clashapi/models/clan/ClanMember.kt
index 11acfd6..9d3a257 100644
--- a/src/main/java/com/lycoon/clashapi/models/clan/ClanMember.kt
+++ b/src/main/java/com/lycoon/clashapi/models/clan/ClanMember.kt
@@ -1,6 +1,7 @@
package com.lycoon.clashapi.models.clan
import com.lycoon.clashapi.models.league.League
+import com.lycoon.clashapi.models.player.enums.Role
import kotlinx.serialization.Serializable
@Serializable
@@ -8,7 +9,7 @@ data class ClanMember(
val league: League? = null,
val tag: String? = null,
val name: String? = null,
- val role: String? = null,
+ val role: Role,
val expLevel: Int = 0,
val clanRank: Int = 0,
val previousClanRank: Int = 0,
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/ClanMemberList.kt b/src/main/java/com/lycoon/clashapi/models/clan/ClanMemberList.kt
deleted file mode 100644
index f5ae22f..0000000
--- a/src/main/java/com/lycoon/clashapi/models/clan/ClanMemberList.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.lycoon.clashapi.models.clan
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class ClanMemberList(val items: List)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/ClanRanking.kt b/src/main/java/com/lycoon/clashapi/models/clan/ClanRanking.kt
index 19ce093..0c50717 100644
--- a/src/main/java/com/lycoon/clashapi/models/clan/ClanRanking.kt
+++ b/src/main/java/com/lycoon/clashapi/models/clan/ClanRanking.kt
@@ -6,8 +6,8 @@ import kotlinx.serialization.Serializable
@Serializable
data class ClanRanking(
- val clanLevel: Int = 0,
val clanPoints: Int = 0,
+ val clanLevel: Int = 0,
val location: Location? = null,
val members: Int = 0,
val tag: String? = null,
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/ClanRankingList.kt b/src/main/java/com/lycoon/clashapi/models/clan/ClanRankingList.kt
deleted file mode 100644
index 4bc9e73..0000000
--- a/src/main/java/com/lycoon/clashapi/models/clan/ClanRankingList.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.lycoon.clashapi.models.clan
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class ClanRankingList(val items: List)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/ClanVersusRanking.kt b/src/main/java/com/lycoon/clashapi/models/clan/ClanVersusRanking.kt
deleted file mode 100644
index 0d7cc80..0000000
--- a/src/main/java/com/lycoon/clashapi/models/clan/ClanVersusRanking.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.lycoon.clashapi.models.clan
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class ClanVersusRanking(val clanVersusPoints: Int = 0, val clanPoints: Int = 0)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/ClanVersusRankingList.kt b/src/main/java/com/lycoon/clashapi/models/clan/ClanVersusRankingList.kt
deleted file mode 100644
index f809f81..0000000
--- a/src/main/java/com/lycoon/clashapi/models/clan/ClanVersusRankingList.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.lycoon.clashapi.models.clan
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class ClanVersusRankingList(val items: List)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/enums/InviteType.kt b/src/main/java/com/lycoon/clashapi/models/clan/enums/InviteType.kt
new file mode 100644
index 0000000..146633f
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/clan/enums/InviteType.kt
@@ -0,0 +1,12 @@
+package com.lycoon.clashapi.models.clan.enums
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+enum class InviteType
+{
+ @SerialName("open") OPEN,
+ @SerialName("inviteOnly") INVITE_ONLY,
+ @SerialName("closed") CLOSED
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/clan/enums/WarFrequency.kt b/src/main/java/com/lycoon/clashapi/models/clan/enums/WarFrequency.kt
new file mode 100644
index 0000000..4554266
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/clan/enums/WarFrequency.kt
@@ -0,0 +1,15 @@
+package com.lycoon.clashapi.models.clan.enums
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+enum class WarFrequency {
+ @SerialName("unknown") UNKNOWN,
+ @SerialName("always") ALWAYS,
+ @SerialName("moreThanOncePerWeek") MORE_THAN_ONCE_PER_WEEK,
+ @SerialName("oncePerWeek") ONCE_PER_WEEK,
+ @SerialName("lessThanOncePerWeek") LESS_THAN_ONCE_PER_WEEK,
+ @SerialName("never") NEVER,
+ @SerialName("any") ANY
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/common/BadgeUrls.kt b/src/main/java/com/lycoon/clashapi/models/common/BadgeUrls.kt
index eb2be2d..1db198d 100644
--- a/src/main/java/com/lycoon/clashapi/models/common/BadgeUrls.kt
+++ b/src/main/java/com/lycoon/clashapi/models/common/BadgeUrls.kt
@@ -3,4 +3,8 @@ package com.lycoon.clashapi.models.common
import kotlinx.serialization.Serializable
@Serializable
-data class BadgeUrls(val small: String? = null, val medium: String? = null, val large: String? = null)
\ No newline at end of file
+data class BadgeUrls(
+ val small: String? = null,
+ val medium: String? = null,
+ val large: String? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/common/LabelList.kt b/src/main/java/com/lycoon/clashapi/models/common/GoldPassSeason.kt
similarity index 51%
rename from src/main/java/com/lycoon/clashapi/models/common/LabelList.kt
rename to src/main/java/com/lycoon/clashapi/models/common/GoldPassSeason.kt
index b1c280f..03c80d9 100644
--- a/src/main/java/com/lycoon/clashapi/models/common/LabelList.kt
+++ b/src/main/java/com/lycoon/clashapi/models/common/GoldPassSeason.kt
@@ -1,6 +1,9 @@
-package com.lycoon.clashapi.models.common
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class LabelList(val items: List)
\ No newline at end of file
+package com.lycoon.clashapi.models.common
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class GoldPassSeason (
+ val startTime: String? = null,
+ val endTime: String? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/common/Label.kt b/src/main/java/com/lycoon/clashapi/models/common/Label.kt
index cb385d8..c338e01 100644
--- a/src/main/java/com/lycoon/clashapi/models/common/Label.kt
+++ b/src/main/java/com/lycoon/clashapi/models/common/Label.kt
@@ -3,4 +3,8 @@ package com.lycoon.clashapi.models.common
import kotlinx.serialization.Serializable
@Serializable
-data class Label(val name: String? = null, val id: Int = 0, val iconUrls: IconUrls? = null)
\ No newline at end of file
+data class Label(
+ val name: String? = null,
+ val id: Int = 0,
+ val iconUrls: IconUrls? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/common/Language.kt b/src/main/java/com/lycoon/clashapi/models/common/Language.kt
index c7a1a07..f90ccc5 100644
--- a/src/main/java/com/lycoon/clashapi/models/common/Language.kt
+++ b/src/main/java/com/lycoon/clashapi/models/common/Language.kt
@@ -3,4 +3,8 @@ package com.lycoon.clashapi.models.common
import kotlinx.serialization.Serializable
@Serializable
-data class Language(val name: String? = null, val id: Int = 0, val languageCode: String? = null)
\ No newline at end of file
+data class Language(
+ val name: String? = null,
+ val id: Int = 0,
+ val languageCode: String? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/common/LocationList.kt b/src/main/java/com/lycoon/clashapi/models/common/LocationList.kt
deleted file mode 100644
index 86173d9..0000000
--- a/src/main/java/com/lycoon/clashapi/models/common/LocationList.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.lycoon.clashapi.models.common
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class LocationList(val items: List)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/common/TokenResponse.kt b/src/main/java/com/lycoon/clashapi/models/common/TokenResponse.kt
index bcf75ab..48a3adc 100644
--- a/src/main/java/com/lycoon/clashapi/models/common/TokenResponse.kt
+++ b/src/main/java/com/lycoon/clashapi/models/common/TokenResponse.kt
@@ -3,4 +3,8 @@ package com.lycoon.clashapi.models.common
import kotlinx.serialization.Serializable
@Serializable
-data class TokenResponse(val tag: String, val token: String, val status: String)
+data class TokenResponse(
+ val tag: String,
+ val token: String,
+ val status: String
+)
diff --git a/src/main/java/com/lycoon/clashapi/models/league/LeagueSeasonList.kt b/src/main/java/com/lycoon/clashapi/models/league/BuilderBaseLeague.kt
similarity index 54%
rename from src/main/java/com/lycoon/clashapi/models/league/LeagueSeasonList.kt
rename to src/main/java/com/lycoon/clashapi/models/league/BuilderBaseLeague.kt
index ea00a44..651a358 100644
--- a/src/main/java/com/lycoon/clashapi/models/league/LeagueSeasonList.kt
+++ b/src/main/java/com/lycoon/clashapi/models/league/BuilderBaseLeague.kt
@@ -1,6 +1,10 @@
-package com.lycoon.clashapi.models.league
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class LeagueSeasonList(val items: List)
\ No newline at end of file
+package com.lycoon.clashapi.models.league
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class BuilderBaseLeague
+(
+ val id: Int = 0,
+ val name: String? = null,
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/league/LeagueList.kt b/src/main/java/com/lycoon/clashapi/models/league/CapitalLeague.kt
similarity index 56%
rename from src/main/java/com/lycoon/clashapi/models/league/LeagueList.kt
rename to src/main/java/com/lycoon/clashapi/models/league/CapitalLeague.kt
index 006514f..cdcf1fa 100644
--- a/src/main/java/com/lycoon/clashapi/models/league/LeagueList.kt
+++ b/src/main/java/com/lycoon/clashapi/models/league/CapitalLeague.kt
@@ -1,6 +1,10 @@
-package com.lycoon.clashapi.models.league
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class LeagueList(val items: List)
\ No newline at end of file
+package com.lycoon.clashapi.models.league
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class CapitalLeague
+(
+ val name: String? = null,
+ val id: Int = 0
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/league/League.kt b/src/main/java/com/lycoon/clashapi/models/league/League.kt
index 112d6f8..62eb23a 100644
--- a/src/main/java/com/lycoon/clashapi/models/league/League.kt
+++ b/src/main/java/com/lycoon/clashapi/models/league/League.kt
@@ -4,4 +4,8 @@ import com.lycoon.clashapi.models.common.IconUrls
import kotlinx.serialization.Serializable
@Serializable
-data class League(val name: String? = null, val id: Int = 0, val iconUrls: IconUrls? = null)
\ No newline at end of file
+data class League(
+ val name: String? = null,
+ val id: Int = 0,
+ val iconUrls: IconUrls? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/league/LegendSeasonResult.kt b/src/main/java/com/lycoon/clashapi/models/league/LegendSeasonResult.kt
index 99c2e46..f21c5d7 100644
--- a/src/main/java/com/lycoon/clashapi/models/league/LegendSeasonResult.kt
+++ b/src/main/java/com/lycoon/clashapi/models/league/LegendSeasonResult.kt
@@ -3,4 +3,8 @@ package com.lycoon.clashapi.models.league
import kotlinx.serialization.Serializable
@Serializable
-data class LegendSeasonResult(val trophies: Int = 0, val id: String? = null, val rank: Int = 0)
\ No newline at end of file
+data class LegendSeasonResult(
+ val trophies: Int = 0,
+ val id: String? = null,
+ val rank: Int = 0
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/Achievement.kt b/src/main/java/com/lycoon/clashapi/models/player/Achievement.kt
index 99ee4d7..38746d7 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/Achievement.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/Achievement.kt
@@ -1,14 +1,16 @@
package com.lycoon.clashapi.models.player
+import com.lycoon.clashapi.models.player.enums.Village
import kotlinx.serialization.Serializable
@Serializable
-data class Achievement(
- val stars: Int = 0,
- val value: Int = 0,
- val name: String? = null,
- val target: Int = 0,
- val info: String? = null,
- val completionInfo: String? = null,
- val village: String? = null
+data class Achievement
+(
+ val stars: Int,
+ val value: Int,
+ val name: String,
+ val target: Int,
+ val info: String,
+ val completionInfo: String? = null, // nullable
+ val village: Village
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/Player.kt b/src/main/java/com/lycoon/clashapi/models/player/Player.kt
index 9d28b7b..d43ef25 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/Player.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/Player.kt
@@ -1,36 +1,51 @@
package com.lycoon.clashapi.models.player
import com.lycoon.clashapi.models.common.Label
+import com.lycoon.clashapi.models.league.BuilderBaseLeague
import com.lycoon.clashapi.models.league.League
+import com.lycoon.clashapi.models.player.enums.Role
+import com.lycoon.clashapi.models.player.enums.WarPreference
import kotlinx.serialization.Serializable
+typealias Spell = Troop
+typealias Hero = Troop
+
@Serializable
-data class Player(
- val clan: PlayerClan? = null,
- val league: League? = null,
- val role: String? = null,
- var warPreference: String? = null,
- val attackWins: Int = 0,
- val defenseWins: Int = 0,
- val townHallLevel: Int = 0,
+data class Player
+(
+ val tag: String,
+ val name: String,
+ val playerHouse: PlayerHouse? = null, // nullable if not in clan
+ val clan: PlayerClan? = null, // nullable if not in clan
+ val role: Role? = null, // nullable if not in clan
+ val expLevel: Int = 0,
+ val trophies: Int = 0,
+ val builderHallLevel: Int = 0,
val townHallWeaponLevel: Int = 0,
- val versusBattleWins: Int = 0,
+ val townHallLevel: Int = 0,
+ val warPreference: WarPreference? = null, // nullable if not in clan
+ val warStars: Int = 0,
+ val achievements: List,
+ val labels: List,
+ val clanCapitalContributions: Int = 0,
+
+ val builderBaseLeague: BuilderBaseLeague? = null,
+ val league: League? = null,
val legendStatistics: PlayerLegendStatistics? = null,
+
val troops: List,
- val heroes: List,
- val spells: List,
- val labels: List,
- val tag: String? = null,
- val name: String? = null,
- val expLevel: Int = 0,
- val trophies: Int = 0,
+ val heroes: List,
+ val spells: List,
+
val bestTrophies: Int = 0,
- val donations: Int = 0,
- val donationsReceived: Int = 0,
- val builderHallLevel: Int = 0,
+ val builderBaseTrophies: Int = 0,
+ val bestBuilderBaseTrophies: Int = 0,
val versusTrophies: Int = 0,
val bestVersusTrophies: Int = 0,
- val warStars: Int = 0,
- val achievements: List,
- val versusBattleWinCount: Int = 0
+
+ val attackWins: Int = 0,
+ val defenseWins: Int = 0,
+ val versusBattleWins: Int = 0,
+ val donations: Int = 0,
+ val donationsReceived: Int = 0,
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/PlayerVersusRanking.kt b/src/main/java/com/lycoon/clashapi/models/player/PlayerBuilderBaseRanking.kt
similarity index 74%
rename from src/main/java/com/lycoon/clashapi/models/player/PlayerVersusRanking.kt
rename to src/main/java/com/lycoon/clashapi/models/player/PlayerBuilderBaseRanking.kt
index 2772220..d8c7ca0 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/PlayerVersusRanking.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/PlayerBuilderBaseRanking.kt
@@ -1,15 +1,17 @@
-package com.lycoon.clashapi.models.player
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class PlayerVersusRanking(
- val clan: PlayerRankingClan? = null,
- val versusBattleWins: Int = 0,
- val tag: String? = null,
- val name: String? = null,
- val expLevel: Int = 0,
- val rank: Int = 0,
- val previousRank: Int = 0,
- val versusTrophies: Int = 0
+package com.lycoon.clashapi.models.player
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class PlayerBuilderBaseRanking
+(
+ val clan: PlayerRankingClan? = null,
+ val versusTrophies: Int = 0,
+ val versusBattleWins: Int = 0,
+ val tag: String? = null,
+ val name: String? = null,
+ val expLevel: Int = 0,
+ val rank: Int = 0,
+ val previousRank: Int = 0,
+ val builderBaseTrophies: Int = 0
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/PlayerClan.kt b/src/main/java/com/lycoon/clashapi/models/player/PlayerClan.kt
index 803e279..2a05e6a 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/PlayerClan.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/PlayerClan.kt
@@ -4,4 +4,10 @@ import com.lycoon.clashapi.models.common.BadgeUrls
import kotlinx.serialization.Serializable
@Serializable
-data class PlayerClan(val tag: String? = null, val clanLevel: Int = 0, val name: String? = null, val badgeUrls: BadgeUrls? = null)
\ No newline at end of file
+data class PlayerClan
+(
+ val tag: String,
+ val clanLevel: Int,
+ val name: String,
+ val badgeUrls: BadgeUrls? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/PlayerRankingList.kt b/src/main/java/com/lycoon/clashapi/models/player/PlayerHouse.kt
similarity index 59%
rename from src/main/java/com/lycoon/clashapi/models/player/PlayerRankingList.kt
rename to src/main/java/com/lycoon/clashapi/models/player/PlayerHouse.kt
index 4d19621..f19175a 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/PlayerRankingList.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/PlayerHouse.kt
@@ -1,6 +1,9 @@
-package com.lycoon.clashapi.models.player
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class PlayerRankingList(val items: List)
\ No newline at end of file
+package com.lycoon.clashapi.models.player
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class PlayerHouse
+(
+ val elements: List
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/PlayerHouseElement.kt b/src/main/java/com/lycoon/clashapi/models/player/PlayerHouseElement.kt
new file mode 100644
index 0000000..d8b8e00
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/player/PlayerHouseElement.kt
@@ -0,0 +1,11 @@
+package com.lycoon.clashapi.models.player
+
+import com.lycoon.clashapi.models.player.enums.PlayerHouseType
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class PlayerHouseElement
+(
+ val id: Int = 0,
+ val type: PlayerHouseType? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/PlayerLegendStatistics.kt b/src/main/java/com/lycoon/clashapi/models/player/PlayerLegendStatistics.kt
index c14e202..87bc3ef 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/PlayerLegendStatistics.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/PlayerLegendStatistics.kt
@@ -4,11 +4,14 @@ import com.lycoon.clashapi.models.league.LegendSeasonResult
import kotlinx.serialization.Serializable
@Serializable
-data class PlayerLegendStatistics(
- val currentSeason: LegendSeasonResult? = null,
- val previousVersusSeason: LegendSeasonResult? = null,
- val bestVersusSeason: LegendSeasonResult? = null,
+data class PlayerLegendStatistics
+(
val legendTrophies: Int = 0,
val previousSeason: LegendSeasonResult? = null,
+ val previousBuilderBaseSeason: LegendSeasonResult? = null,
+ val previousVersusSeason: LegendSeasonResult? = null,
+ val bestBuilderBaseSeason: LegendSeasonResult? = null,
+ val bestVersusSeason: LegendSeasonResult? = null,
+ val currentSeason: LegendSeasonResult? = null,
val bestSeason: LegendSeasonResult? = null
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/PlayerRanking.kt b/src/main/java/com/lycoon/clashapi/models/player/PlayerRanking.kt
index 53bd4dc..448d3a4 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/PlayerRanking.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/PlayerRanking.kt
@@ -5,8 +5,8 @@ import kotlinx.serialization.Serializable
@Serializable
data class PlayerRanking(
- val clan: PlayerRankingClan? = null,
val league: League? = null,
+ val clan: PlayerRankingClan? = null,
val attackWins: Int = 0,
val defenseWins: Int = 0,
val tag: String? = null,
diff --git a/src/main/java/com/lycoon/clashapi/models/player/PlayerRankingClan.kt b/src/main/java/com/lycoon/clashapi/models/player/PlayerRankingClan.kt
index 3530c8e..238fd79 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/PlayerRankingClan.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/PlayerRankingClan.kt
@@ -4,4 +4,8 @@ import com.lycoon.clashapi.models.common.BadgeUrls
import kotlinx.serialization.Serializable
@Serializable
-data class PlayerRankingClan(val tag: String? = null, val name: String? = null, val badgeUrls: BadgeUrls? = null)
\ No newline at end of file
+data class PlayerRankingClan(
+ val tag: String? = null,
+ val name: String? = null,
+ val badgeUrls: BadgeUrls? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/PlayerVersusRankingList.kt b/src/main/java/com/lycoon/clashapi/models/player/PlayerVersusRankingList.kt
deleted file mode 100644
index 31ce3fb..0000000
--- a/src/main/java/com/lycoon/clashapi/models/player/PlayerVersusRankingList.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.lycoon.clashapi.models.player
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class PlayerVersusRankingList(val items: List)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/Troop.kt b/src/main/java/com/lycoon/clashapi/models/player/Troop.kt
index 96d4b60..a0d614f 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/Troop.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/Troop.kt
@@ -1,13 +1,18 @@
package com.lycoon.clashapi.models.player
+import com.lycoon.clashapi.models.player.enums.Village
+import jdk.nashorn.internal.objects.annotations.Getter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
-data class Troop(
- val name: String? = null,
- val level: Int = 0,
- val maxLevel: Int = 0,
- val village: String? = null,
- @SerialName("superTroopIsActive") val isSuperTroopActive: Boolean? = false
+data class Troop
+(
+ val level: Int,
+ val name: String,
+ val maxLevel: Int,
+ val village: Village,
+
+ @get:Getter(name = "isSuperTroopActive")
+ val superTroopIsActive: Boolean = false
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/enums/PlayerHouseType.kt b/src/main/java/com/lycoon/clashapi/models/player/enums/PlayerHouseType.kt
new file mode 100644
index 0000000..f37801b
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/player/enums/PlayerHouseType.kt
@@ -0,0 +1,13 @@
+package com.lycoon.clashapi.models.player.enums
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+enum class PlayerHouseType
+{
+ @SerialName("ground") GROUND,
+ @SerialName("roof") ROOF,
+ @SerialName("foot") FOOT,
+ @SerialName("deco") DECO
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/enums/Role.kt b/src/main/java/com/lycoon/clashapi/models/player/enums/Role.kt
new file mode 100644
index 0000000..db85e9c
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/player/enums/Role.kt
@@ -0,0 +1,14 @@
+package com.lycoon.clashapi.models.player.enums
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+enum class Role
+{
+ @SerialName("notMember") NOT_MEMBER,
+ @SerialName("member") MEMBER,
+ @SerialName("leader") LEADER,
+ @SerialName("admin") ADMIN,
+ @SerialName("coleader") COLEADER
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/enums/Village.kt b/src/main/java/com/lycoon/clashapi/models/player/enums/Village.kt
new file mode 100644
index 0000000..5ccb19a
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/player/enums/Village.kt
@@ -0,0 +1,12 @@
+package com.lycoon.clashapi.models.player.enums
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+enum class Village
+{
+ @SerialName("home") HOME_VILLAGE,
+ @SerialName("builderBase") BUILDER_BASE,
+ @SerialName("clanCapital") CLAN_CAPITAL
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/player/enums/WarPreference.kt b/src/main/java/com/lycoon/clashapi/models/player/enums/WarPreference.kt
new file mode 100644
index 0000000..e26dda9
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/player/enums/WarPreference.kt
@@ -0,0 +1,11 @@
+package com.lycoon.clashapi.models.player.enums
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+enum class WarPreference
+{
+ @SerialName("out") OUT,
+ @SerialName("in") IN,
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/war/War.kt b/src/main/java/com/lycoon/clashapi/models/war/War.kt
index 2ae34e1..848c3fb 100644
--- a/src/main/java/com/lycoon/clashapi/models/war/War.kt
+++ b/src/main/java/com/lycoon/clashapi/models/war/War.kt
@@ -1,15 +1,17 @@
package com.lycoon.clashapi.models.war
+import com.lycoon.clashapi.models.war.enums.WarState
import kotlinx.serialization.Serializable
@Serializable
-data class War(
+data class War
+ (
val clan: WarClan? = null, // if warTag from warleague is #0 (not found)
val teamSize: Int = 0, // if clan is not in war
val attacksPerMember: Int = 0, // if from a warleague round war
val opponent: WarClan? = null, // if warTag from warleague is #0 (not found)
val startTime: String? = null, // if warTag from warleague is #0 (not found)
- val state: String? = null,
+ val state: WarState,
val endTime: String? = null, // if warTag from warleague is #0 (not found)
val preparationStartTime: String? = null // if warTag from warleague is #0 (not found)
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/war/WarClan.kt b/src/main/java/com/lycoon/clashapi/models/war/WarClan.kt
index d9ea63f..79de0ae 100644
--- a/src/main/java/com/lycoon/clashapi/models/war/WarClan.kt
+++ b/src/main/java/com/lycoon/clashapi/models/war/WarClan.kt
@@ -4,14 +4,15 @@ import com.lycoon.clashapi.models.common.BadgeUrls
import kotlinx.serialization.Serializable
@Serializable
-data class WarClan(
+data class WarClan
+(
val destructionPercentage: Float = 0f,
- val tag: String? = null, // if clan is not in war
- val name: String? = null, // if clan is not in war
+ val tag: String? = null, // if clan is not in war
+ val name: String? = null, // if clan is not in war
val badgeUrls: BadgeUrls? = null,
val clanLevel: Int = 0,
val attacks: Int = 0,
val stars: Int = 0,
- val expEarned: Int = 0, // if from a warleague round war
- val members: List?, // if clan is not in war
+ val expEarned: Int = 0, // if from a war league round war
+ val members: List = emptyList(), // if clan is not in war
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/war/WarMember.kt b/src/main/java/com/lycoon/clashapi/models/war/WarMember.kt
index 783213a..83cc194 100644
--- a/src/main/java/com/lycoon/clashapi/models/war/WarMember.kt
+++ b/src/main/java/com/lycoon/clashapi/models/war/WarMember.kt
@@ -8,7 +8,7 @@ data class WarMember(
val name: String? = null,
val mapPosition: Int = 0,
val townhallLevel: Int = 0,
- val opponentAttack: Int = 0,
+ val opponentAttacks: Int = 0,
val bestOpponentAttack: WarAttack? = null,
- val attacks: List?
+ val attacks: List = emptyList()
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/war/WarlogClan.kt b/src/main/java/com/lycoon/clashapi/models/war/WarlogClan.kt
index 0326ae6..88f57d0 100644
--- a/src/main/java/com/lycoon/clashapi/models/war/WarlogClan.kt
+++ b/src/main/java/com/lycoon/clashapi/models/war/WarlogClan.kt
@@ -12,5 +12,6 @@ data class WarlogClan(
val clanLevel: Int = 0,
val attacks: Int = 0, // if warleague result or opponent in warlog clan
val stars: Int = 0,
- val expEarned: Int = 0 // if warleague result or opponent in warlog clan
+ val expEarned: Int = 0, // if warleague result or opponent in warlog clan
+ val members: List
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/war/WarlogEntry.kt b/src/main/java/com/lycoon/clashapi/models/war/WarlogEntry.kt
index 1e515db..054c749 100644
--- a/src/main/java/com/lycoon/clashapi/models/war/WarlogEntry.kt
+++ b/src/main/java/com/lycoon/clashapi/models/war/WarlogEntry.kt
@@ -1,12 +1,15 @@
package com.lycoon.clashapi.models.war
+import com.lycoon.clashapi.models.war.enums.WarResult
import kotlinx.serialization.Serializable
@Serializable
-data class WarlogEntry(
- val clan: WarlogClan? = null,
+data class WarlogEntry
+(
+ val clan: WarlogClan,
val teamSize: Int = 0,
+ val attacksPerMember: Int = 0,
val opponent: WarlogClan? = null,
val endTime: String? = null,
- val result: String? = null
+ val result: WarResult
)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/war/enums/WarResult.kt b/src/main/java/com/lycoon/clashapi/models/war/enums/WarResult.kt
new file mode 100644
index 0000000..a8af00b
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/war/enums/WarResult.kt
@@ -0,0 +1,12 @@
+package com.lycoon.clashapi.models.war.enums
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+enum class WarResult
+{
+ @SerialName("lose") LOSE,
+ @SerialName("win") WIN,
+ @SerialName("tie") TIE
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/war/enums/WarState.kt b/src/main/java/com/lycoon/clashapi/models/war/enums/WarState.kt
new file mode 100644
index 0000000..6911c23
--- /dev/null
+++ b/src/main/java/com/lycoon/clashapi/models/war/enums/WarState.kt
@@ -0,0 +1,19 @@
+package com.lycoon.clashapi.models.war.enums
+
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+@Serializable
+enum class WarState
+{
+ @SerialName("clanNotFound") CLAN_NOT_FOUND,
+ @SerialName("accessDenied") ACCESS_DENIED,
+ @SerialName("notInWar") NOT_IN_WAR,
+ @SerialName("inMatchmaking") IN_MATCHMAKING,
+ @SerialName("enterWar") ENTER_WAR,
+ @SerialName("matched") MATCHED,
+ @SerialName("preparation") PREPARATION,
+ @SerialName("war") WAR,
+ @SerialName("inWar") IN_WAR,
+ @SerialName("ended") ENDED
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/warleague/WarLeague.kt b/src/main/java/com/lycoon/clashapi/models/warleague/WarLeague.kt
index e36d95b..0ec99c7 100644
--- a/src/main/java/com/lycoon/clashapi/models/warleague/WarLeague.kt
+++ b/src/main/java/com/lycoon/clashapi/models/warleague/WarLeague.kt
@@ -3,4 +3,7 @@ package com.lycoon.clashapi.models.warleague
import kotlinx.serialization.Serializable
@Serializable
-data class WarLeague(val name: String? = null, val id: Int = 0)
\ No newline at end of file
+data class WarLeague(
+ val name: String? = null,
+ val id: Int = 0
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueGroup.kt b/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueGroup.kt
index 065d8e1..3b6424b 100644
--- a/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueGroup.kt
+++ b/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueGroup.kt
@@ -5,8 +5,10 @@ import kotlinx.serialization.Serializable
@Serializable
data class WarLeagueGroup(
val tag: String? = null, // always null?
- val state: String? = null,
+ val state: State? = null,
val season: String? = null,
val clans: List,
val rounds: List
-)
\ No newline at end of file
+) {
+ enum class State {GROUP_NOT_FOUND, NOT_IN_WAR, PREPARATION, WAR, ENDED}
+}
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueList.kt b/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueList.kt
deleted file mode 100644
index c7e4e37..0000000
--- a/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueList.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package com.lycoon.clashapi.models.warleague
-
-import kotlinx.serialization.Serializable
-
-@Serializable
-data class WarLeagueList(val items: List)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueMember.kt b/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueMember.kt
index 56c77c1..10f8d02 100644
--- a/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueMember.kt
+++ b/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueMember.kt
@@ -3,4 +3,8 @@ package com.lycoon.clashapi.models.warleague
import kotlinx.serialization.Serializable
@Serializable
-data class WarLeagueMember(val tag: String? = null, val townHallLevel: Int = 0, val name: String? = null)
\ No newline at end of file
+data class WarLeagueMember(
+ val tag: String? = null,
+ val townHallLevel: Int = 0,
+ val name: String? = null
+)
\ No newline at end of file
diff --git a/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueRound.kt b/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueRound.kt
index 061d2d1..6f57b9c 100644
--- a/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueRound.kt
+++ b/src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueRound.kt
@@ -3,4 +3,6 @@ package com.lycoon.clashapi.models.warleague
import kotlinx.serialization.Serializable
@Serializable
-data class WarLeagueRound(val warTags: List)
\ No newline at end of file
+data class WarLeagueRound(
+ val warTags: List
+)
\ No newline at end of file
diff --git a/src/test/java/ClashAPITest.kt b/src/test/java/ClashAPITest.kt
index 7fa4bbb..b9ed6e2 100644
--- a/src/test/java/ClashAPITest.kt
+++ b/src/test/java/ClashAPITest.kt
@@ -1,13 +1,14 @@
+import com.lycoon.clashapi.core.ClanQueryParamsBuilder
import junit.framework.TestCase
import com.lycoon.clashapi.core.ClashAPI
import java.io.FileInputStream
import java.io.IOException
-import com.lycoon.clashapi.core.exception.NotFoundException
+import com.lycoon.clashapi.core.exceptions.NotFoundException
import java.util.*
const val CLAN_TAG = "UPCU2098"
const val CONFIG = "tokens.properties"
-const val PLAYER_TAG = "PGYROPR"
+const val PLAYER_TAG = "PGYR0PR"
class ClashAPITest(playerTestMethod: String?) : TestCase(playerTestMethod) {
private val clashAPI: ClashAPI
@@ -22,10 +23,10 @@ class ClashAPITest(playerTestMethod: String?) : TestCase(playerTestMethod) {
clashAPI = ClashAPI(tokens.getProperty("clash-of-clans"))
}
- fun testWarlog() {
+ /*fun testWarlog() {
val warlog = clashAPI.getWarlog(CLAN_TAG)
assertNotNull(warlog)
- }
+ }*/
fun testClanMembers() {
val clanMembers = clashAPI.getClanMembers(CLAN_TAG)
@@ -52,7 +53,7 @@ class ClashAPITest(playerTestMethod: String?) : TestCase(playerTestMethod) {
assertNotNull(locations)
}
- fun testWarLeague() {
+ /*fun testWarLeague() {
val warLeague = clashAPI.getWarLeague("48000000")
assertNotNull(warLeague)
}
@@ -60,7 +61,7 @@ class ClashAPITest(playerTestMethod: String?) : TestCase(playerTestMethod) {
fun testWarLeagues() {
val warLeagues = clashAPI.getWarLeagues()
assertNotNull(warLeagues)
- }
+ }*/
fun testPlayerLabels() {
val playerLabels = clashAPI.getPlayerLabels()
@@ -76,15 +77,15 @@ class ClashAPITest(playerTestMethod: String?) : TestCase(playerTestMethod) {
val warLeagueGroup = clashAPI.getWarLeagueGroup("#C0GJPLJG")
assertNotNull(warLeagueGroup)
print(warLeagueGroup.toString())
- }*/
+ }
- /*fun testWarLeagueWar() {
+ fun testWarLeagueWar() {
val warLeagueWar = clashAPI.getWarLeagueWar("#0")
assertNotNull(warLeagueWar)
print(warLeagueWar.toString())
- }*/
+ }
- /*fun testClanWar() {
+ fun testClanWar() {
val clanWar = clashAPI.getCurrentWar("#C0GJPLJG")
assertNotNull(clanWar)
print(clanWar.toString())
@@ -111,6 +112,11 @@ class ClashAPITest(playerTestMethod: String?) : TestCase(playerTestMethod) {
assertEquals(player.tag, "#$PLAYER_TAG")
}
+ fun testNewPlayer() {
+ val player = clashAPI.getPlayer("#GL2GLGLYR")
+ assertNotNull(player)
+ }
+
fun testClanWithSharp() {
val clan = clashAPI.getClan("#$CLAN_TAG")
assertNotNull(clan)
@@ -118,6 +124,12 @@ class ClashAPITest(playerTestMethod: String?) : TestCase(playerTestMethod) {
assertEquals(clan.tag, "#$CLAN_TAG")
}
+ fun testClanSearch() {
+ val query = ClanQueryParamsBuilder(name = "toto");
+ val clans = clashAPI.getClans(query);
+ assertNotNull(clans)
+ }
+
fun testPlayer404() {
try {
clashAPI.getPlayer("404")