From b7cd09a0c6f8229bd3ed287d03e262c90a91155e Mon Sep 17 00:00:00 2001
From: Lycoon
Date: Sun, 19 Nov 2023 15:01:54 +0100
Subject: [PATCH 1/7] feat: working on updating API
---
.../java/com/lycoon/clashapi/core/ClashAPI.kt | 45 ++++++++++++-------
.../clashapi/core/QueryParametersBuilder.kt | 21 +++++++++
.../models/capital/CapitalRaidSeason.kt | 19 ++++++++
.../models/capital/CapitalRaidSeasonAttack.kt | 10 +++++
.../capital/CapitalRaidSeasonAttackLog.kt | 12 +++++
.../capital/CapitalRaidSeasonAttacker.kt | 9 ++++
.../capital/CapitalRaidSeasonClanInfo.kt | 12 +++++
.../capital/CapitalRaidSeasonDefenseLog.kt | 12 +++++
.../capital/CapitalRaidSeasonDistrict.kt | 15 +++++++
.../models/capital/CapitalRaidSeasonMember.kt | 13 ++++++
.../com/lycoon/clashapi/models/clan/Clan.kt | 15 +++++--
.../lycoon/clashapi/models/clan/ClanList.kt | 6 ---
.../lycoon/clashapi/models/clan/ClanMember.kt | 3 +-
.../clashapi/models/clan/ClanMemberList.kt | 6 ---
.../clashapi/models/clan/ClanRanking.kt | 2 +-
.../clashapi/models/clan/ClanRankingList.kt | 6 ---
.../clashapi/models/clan/ClanVersusRanking.kt | 6 ++-
.../models/clan/ClanVersusRankingList.kt | 6 ---
.../clashapi/models/common/BadgeUrls.kt | 6 ++-
.../lycoon/clashapi/models/common/Label.kt | 6 ++-
.../clashapi/models/common/LabelList.kt | 6 ---
.../lycoon/clashapi/models/common/Language.kt | 6 ++-
.../clashapi/models/common/LocationList.kt | 6 ---
.../clashapi/models/common/TokenResponse.kt | 6 ++-
.../{LeagueList.kt => BuilderBaseLeague.kt} | 15 ++++---
.../lycoon/clashapi/models/league/League.kt | 6 ++-
.../models/league/LeagueSeasonList.kt | 6 ---
.../models/league/LegendSeasonResult.kt | 6 ++-
.../clashapi/models/player/Achievement.kt | 2 +-
.../lycoon/clashapi/models/player/Player.kt | 23 +++++++---
.../clashapi/models/player/PlayerClan.kt | 7 ++-
.../{PlayerRankingList.kt => PlayerHouse.kt} | 14 +++---
.../models/player/PlayerHouseElement.kt | 11 +++++
.../models/player/PlayerLegendStatistics.kt | 6 ++-
.../clashapi/models/player/PlayerRanking.kt | 2 +-
.../models/player/PlayerRankingClan.kt | 6 ++-
.../models/player/PlayerVersusRanking.kt | 3 +-
.../models/player/PlayerVersusRankingList.kt | 6 ---
.../lycoon/clashapi/models/player/Troop.kt | 8 ++--
.../com/lycoon/clashapi/models/war/War.kt | 10 ++++-
.../lycoon/clashapi/models/war/WarMember.kt | 2 +-
.../lycoon/clashapi/models/war/WarlogClan.kt | 3 +-
.../lycoon/clashapi/models/war/WarlogEntry.kt | 7 ++-
.../clashapi/models/warleague/WarLeague.kt | 5 ++-
.../models/warleague/WarLeagueGroup.kt | 6 ++-
.../models/warleague/WarLeagueList.kt | 6 ---
.../models/warleague/WarLeagueMember.kt | 6 ++-
.../models/warleague/WarLeagueRound.kt | 4 +-
src/test/java/ClashAPITest.kt | 27 ++++++++++-
49 files changed, 329 insertions(+), 122 deletions(-)
create mode 100644 src/main/java/com/lycoon/clashapi/core/QueryParametersBuilder.kt
create mode 100644 src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeason.kt
create mode 100644 src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttack.kt
create mode 100644 src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttackLog.kt
create mode 100644 src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttacker.kt
create mode 100644 src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonClanInfo.kt
create mode 100644 src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDefenseLog.kt
create mode 100644 src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDistrict.kt
create mode 100644 src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonMember.kt
delete mode 100644 src/main/java/com/lycoon/clashapi/models/clan/ClanList.kt
delete mode 100644 src/main/java/com/lycoon/clashapi/models/clan/ClanMemberList.kt
delete mode 100644 src/main/java/com/lycoon/clashapi/models/clan/ClanRankingList.kt
delete mode 100644 src/main/java/com/lycoon/clashapi/models/clan/ClanVersusRankingList.kt
delete mode 100644 src/main/java/com/lycoon/clashapi/models/common/LabelList.kt
delete mode 100644 src/main/java/com/lycoon/clashapi/models/common/LocationList.kt
rename src/main/java/com/lycoon/clashapi/models/league/{LeagueList.kt => BuilderBaseLeague.kt} (54%)
delete mode 100644 src/main/java/com/lycoon/clashapi/models/league/LeagueSeasonList.kt
rename src/main/java/com/lycoon/clashapi/models/player/{PlayerRankingList.kt => PlayerHouse.kt} (59%)
create mode 100644 src/main/java/com/lycoon/clashapi/models/player/PlayerHouseElement.kt
delete mode 100644 src/main/java/com/lycoon/clashapi/models/player/PlayerVersusRankingList.kt
delete mode 100644 src/main/java/com/lycoon/clashapi/models/warleague/WarLeagueList.kt
diff --git a/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt b/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt
index 6569f09..5672d63 100644
--- a/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt
+++ b/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt
@@ -4,19 +4,17 @@ 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.models.capital.CapitalRaidSeason
import com.lycoon.clashapi.models.clan.*
import com.lycoon.clashapi.models.common.*
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
@@ -153,7 +151,24 @@ class ClashAPI(private val token: String) {
fun getClanMembers(clanTag: String): List {
val tag = formatTag(clanTag)
val res = get("/clans/$tag/members")
- return deserialize(res).items
+ return deserialize(res)
+ }
+
+ /**
+ * Returns the capital raid seasons of clan attached to the tag.
+ *
+ * @param clanTag `String` of the clan's tag
+ * @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): List {
+ val tag = formatTag(clanTag)
+ val res = get("/clans/$tag/capitalraidseasons")
+ return deserialize(res)
}
/**
@@ -203,7 +218,7 @@ class ClashAPI(private val token: String) {
@Throws(IOException::class, ClashAPIException::class)
fun getLeagues(): List {
val res = get("/leagues")
- return deserialize(res).items
+ return deserialize(res)
}
/**
@@ -220,7 +235,7 @@ class ClashAPI(private val token: String) {
@Throws(IOException::class, ClashAPIException::class)
fun getLeagueSeasonRankings(leagueId: String, seasonId: String): List {
val res = get("/leagues/$leagueId/seasons/$seasonId")
- return deserialize(res).items
+ return deserialize(res)
}
/**
@@ -252,7 +267,7 @@ class ClashAPI(private val token: String) {
@Throws(IOException::class, ClashAPIException::class)
fun getLeagueSeasons(leagueId: String): List {
val res = get("/leagues/$leagueId/seasons")
- return deserialize(res).items
+ return deserialize(res)
}
/**
@@ -283,7 +298,7 @@ class ClashAPI(private val token: String) {
@Throws(IOException::class, ClashAPIException::class)
fun getWarLeagues(): List {
val res = get("/warleagues")
- return deserialize(res).items
+ return deserialize(res)
}
/**
@@ -299,7 +314,7 @@ class ClashAPI(private val token: String) {
@Throws(IOException::class, ClashAPIException::class)
fun getClanRankings(locationId: String): List {
val res = get("/locations/${locationId}/rankings/clans")
- return deserialize(res).items
+ return deserialize(res)
}
/**
@@ -315,7 +330,7 @@ class ClashAPI(private val token: String) {
@Throws(IOException::class, ClashAPIException::class)
fun getClanVersusRankings(locationId: String): List {
val res = get("/locations/${locationId}/rankings/clans-versus")
- return deserialize(res).items
+ return deserialize(res)
}
/**
@@ -331,7 +346,7 @@ class ClashAPI(private val token: String) {
@Throws(IOException::class, ClashAPIException::class)
fun getPlayerRankings(locationId: String): List {
val res = get("/locations/${locationId}/rankings/players")
- return deserialize(res).items
+ return deserialize(res)
}
/**
@@ -347,7 +362,7 @@ class ClashAPI(private val token: String) {
@Throws(IOException::class, ClashAPIException::class)
fun getPlayerVersusRankings(locationId: String): List {
val res = get("/locations/${locationId}/rankings/players-versus")
- return deserialize(res).items
+ return deserialize(res)
}
/**
@@ -362,7 +377,7 @@ class ClashAPI(private val token: String) {
@Throws(IOException::class, ClashAPIException::class)
fun getLocations(): List {
val res = get("/locations")
- return deserialize(res).items
+ return deserialize(res)
}
/**
@@ -393,7 +408,7 @@ class ClashAPI(private val token: String) {
@Throws(IOException::class, ClashAPIException::class)
fun getPlayerLabels(): List
-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.lycoonclash-api
- 4.0.0
+ 5.0.0${project.groupId}:${project.artifactId}
From 0f6881e8d3a018909b1bf787ff1e1198842b94b8 Mon Sep 17 00:00:00 2001
From: Lycoon
Date: Wed, 22 Nov 2023 16:23:31 +0100
Subject: [PATCH 5/7] chore: fixing models serialization
---
.gitignore | 3 +--
.../clashapi/models/capital/CapitalRaidSeason.kt | 15 ++++++++-------
.../models/capital/CapitalRaidSeasonAttack.kt | 7 ++++---
.../models/capital/CapitalRaidSeasonAttackLog.kt | 9 +++++----
.../models/capital/CapitalRaidSeasonClanInfo.kt | 5 +++--
.../models/capital/CapitalRaidSeasonDefenseLog.kt | 9 +++++----
.../models/capital/CapitalRaidSeasonDistrict.kt | 15 ++++++++-------
.../models/capital/CapitalRaidSeasonMember.kt | 15 ++++++++-------
.../java/com/lycoon/clashapi/models/clan/Clan.kt | 14 ++++++++------
.../clashapi/models/league/BuilderBaseLeague.kt | 5 +++--
.../clashapi/models/league/CapitalLeague.kt | 7 ++++---
.../com/lycoon/clashapi/models/player/Player.kt | 10 ++++++----
.../clashapi/models/player/PlayerHouseElement.kt | 12 ++++++------
.../com/lycoon/clashapi/models/player/Troop.kt | 5 +++--
.../models/player/enums/PlayerHouseType.kt | 13 +++++++++++++
.../com/lycoon/clashapi/models/war/WarlogEntry.kt | 14 +++++++-------
.../lycoon/clashapi/models/war/enums/WarResult.kt | 12 ++++++++++++
src/test/java/ClashAPITest.kt | 5 +++++
18 files changed, 109 insertions(+), 66 deletions(-)
create mode 100644 src/main/java/com/lycoon/clashapi/models/player/enums/PlayerHouseType.kt
create mode 100644 src/main/java/com/lycoon/clashapi/models/war/enums/WarResult.kt
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/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeason.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeason.kt
index 18955eb..648a0e0 100644
--- a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeason.kt
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeason.kt
@@ -3,17 +3,18 @@ package com.lycoon.clashapi.models.capital
import kotlinx.serialization.Serializable
@Serializable
-data class CapitalRaidSeason(
+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 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
index 61294eb..1e18712 100644
--- a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttack.kt
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttack.kt
@@ -3,8 +3,9 @@ package com.lycoon.clashapi.models.capital
import kotlinx.serialization.Serializable
@Serializable
-data class CapitalRaidSeasonAttack(
+data class CapitalRaidSeasonAttack
+(
val attacker: CapitalRaidSeasonAttacker,
- val destructionPercent: Int? = 0,
- val stars: Int? = 0
+ 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
index 86e1c09..b51b250 100644
--- a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttackLog.kt
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonAttackLog.kt
@@ -3,10 +3,11 @@ package com.lycoon.clashapi.models.capital
import kotlinx.serialization.Serializable
@Serializable
-data class CapitalRaidSeasonAttackLog(
+data class CapitalRaidSeasonAttackLog
+(
val defender: CapitalRaidSeasonClanInfo,
- val attackCount: Int? = 0,
- val districtCount: Int? = 0,
- val districtsDestroyed: Int? = 0,
+ 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/CapitalRaidSeasonClanInfo.kt b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonClanInfo.kt
index 7acc706..6b7e7df 100644
--- a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonClanInfo.kt
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonClanInfo.kt
@@ -4,9 +4,10 @@ import com.lycoon.clashapi.models.common.BadgeUrls
import kotlinx.serialization.Serializable
@Serializable
-data class CapitalRaidSeasonClanInfo(
+data class CapitalRaidSeasonClanInfo
+(
val tag: String? = null,
val name: String? = null,
- val level: Int? = 0,
+ 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
index 105168f..908ad59 100644
--- a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDefenseLog.kt
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDefenseLog.kt
@@ -3,10 +3,11 @@ package com.lycoon.clashapi.models.capital
import kotlinx.serialization.Serializable
@Serializable
-data class CapitalRaidSeasonDefenseLog(
+data class CapitalRaidSeasonDefenseLog
+(
val defender: CapitalRaidSeasonClanInfo,
- val attackCount: Int? = 0,
- val districtCount: Int? = 0,
- val districtsDestroyed: Int? = 0,
+ 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
index 83a3d7f..5f30264 100644
--- a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDistrict.kt
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonDistrict.kt
@@ -3,13 +3,14 @@ package com.lycoon.clashapi.models.capital
import kotlinx.serialization.Serializable
@Serializable
-data class CapitalRaidSeasonDistrict(
- val stars: Int? = 0,
+data class CapitalRaidSeasonDistrict
+(
+ val id: Int = 0,
val name: String? = null,
- val id: Int? = 0,
- val destructionPercent: Float? = 0f,
- val attackCount: Int? = 0,
- val totalLooted: Int? = 0,
+ val stars: Int = 0,
+ val destructionPercent: Float = 0f,
+ val attackCount: Int = 0,
+ val totalLooted: Int = 0,
val attacks: List,
- val districtHallLevel: Int? = 0
+ 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
index 7fd1d69..b351788 100644
--- a/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonMember.kt
+++ b/src/main/java/com/lycoon/clashapi/models/capital/CapitalRaidSeasonMember.kt
@@ -3,11 +3,12 @@ package com.lycoon.clashapi.models.capital
import kotlinx.serialization.Serializable
@Serializable
-data class CapitalRaidSeasonMember(
- val tag: String? = null,
- val name: String? = null,
- val attacks: Int? = 0,
- val attackLimit: Int? = 0,
- val bonusAttackLimit: Int? = 0,
- val capitalResourcesLooted: Int? = 0
+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/clan/Clan.kt b/src/main/java/com/lycoon/clashapi/models/clan/Clan.kt
index 3d96938..744ff26 100644
--- a/src/main/java/com/lycoon/clashapi/models/clan/Clan.kt
+++ b/src/main/java/com/lycoon/clashapi/models/clan/Clan.kt
@@ -8,8 +8,8 @@ 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.league.CapitalLeague
-import com.lycoon.clashapi.models.war.WarMember
import com.lycoon.clashapi.models.warleague.WarLeague
+import jdk.nashorn.internal.objects.annotations.Getter
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@@ -19,16 +19,17 @@ 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 isFamilyFriendly: Boolean = false,
- val chatLanguage: Language? = null,
+ val chatLanguage: Language? = null, // nullable when not set
val labels: List,
- val location: Location? = null,
- val badgeUrls: BadgeUrls? = null,
+ val location: Location? = null, // nullable when using clan search
+ val badgeUrls: BadgeUrls,
val members: Int = 0,
val memberList: List? = null, // nullable when using clan search
@@ -44,9 +45,10 @@ data class Clan
val clanCapitalPoints: Int = 0,
val clanCapital: ClanCapital? = null, // nullable if clan has no capital
+ @get:Getter(name = "isWarLogPublic")
+ val isWarLogPublic: Boolean = false,
val warLeague: WarLeague,
val capitalLeague: CapitalLeague,
- val isWarLogPublic: Boolean = false,
val warFrequency: WarFrequency,
val warWinStreak: Int = 0,
val warWins: Int = 0,
diff --git a/src/main/java/com/lycoon/clashapi/models/league/BuilderBaseLeague.kt b/src/main/java/com/lycoon/clashapi/models/league/BuilderBaseLeague.kt
index 5837523..651a358 100644
--- a/src/main/java/com/lycoon/clashapi/models/league/BuilderBaseLeague.kt
+++ b/src/main/java/com/lycoon/clashapi/models/league/BuilderBaseLeague.kt
@@ -3,7 +3,8 @@ package com.lycoon.clashapi.models.league
import kotlinx.serialization.Serializable
@Serializable
-data class BuilderBaseLeague(
+data class BuilderBaseLeague
+(
+ val id: Int = 0,
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/CapitalLeague.kt b/src/main/java/com/lycoon/clashapi/models/league/CapitalLeague.kt
index bb35dc6..cdcf1fa 100644
--- a/src/main/java/com/lycoon/clashapi/models/league/CapitalLeague.kt
+++ b/src/main/java/com/lycoon/clashapi/models/league/CapitalLeague.kt
@@ -3,7 +3,8 @@ package com.lycoon.clashapi.models.league
import kotlinx.serialization.Serializable
@Serializable
-data class CapitalLeague(
- val name: String? = null,
- val id: Int? = 0
+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/player/Player.kt b/src/main/java/com/lycoon/clashapi/models/player/Player.kt
index 8154f45..d43ef25 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/Player.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/Player.kt
@@ -7,6 +7,9 @@ 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
(
@@ -24,15 +27,15 @@ data class Player
val warStars: Int = 0,
val achievements: List,
val labels: List,
- val clanCapitalContributions: Int? = 0,
+ 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 heroes: List,
+ val spells: List,
val bestTrophies: Int = 0,
val builderBaseTrophies: Int = 0,
@@ -45,5 +48,4 @@ data class Player
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/PlayerHouseElement.kt b/src/main/java/com/lycoon/clashapi/models/player/PlayerHouseElement.kt
index cde592c..d8b8e00 100644
--- a/src/main/java/com/lycoon/clashapi/models/player/PlayerHouseElement.kt
+++ b/src/main/java/com/lycoon/clashapi/models/player/PlayerHouseElement.kt
@@ -1,11 +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: Type
-) {
- enum class Type{ GROUND, ROOF, FOOT, DECO }
-}
\ No newline at end of file
+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/Troop.kt b/src/main/java/com/lycoon/clashapi/models/player/Troop.kt
index d11cf76..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,6 +1,7 @@
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
@@ -12,6 +13,6 @@ data class Troop
val maxLevel: Int,
val village: Village,
- @SerialName("superTroopIsActive")
- val isSuperTroopActive: Boolean? = false
+ @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/war/WarlogEntry.kt b/src/main/java/com/lycoon/clashapi/models/war/WarlogEntry.kt
index 36c6f9d..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,15 +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 attacksPerMember: Int = 0,
val opponent: WarlogClan? = null,
val endTime: String? = null,
- val result: Result
-) {
- enum class Result { LOSE, WIN, TIE }
-}
\ No newline at end of file
+ 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/test/java/ClashAPITest.kt b/src/test/java/ClashAPITest.kt
index 6cce5cc..9a44f68 100644
--- a/src/test/java/ClashAPITest.kt
+++ b/src/test/java/ClashAPITest.kt
@@ -122,6 +122,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)
From a648e3a367665b8f732301db77f155f76609fd5a Mon Sep 17 00:00:00 2001
From: Lycoon
Date: Wed, 22 Nov 2023 17:31:10 +0100
Subject: [PATCH 6/7] chore: cleaned API architecture by adding interfaces and
ClashAPIClient abstract class
---
.../java/com/lycoon/clashapi/core/ClashAPI.kt | 518 +++---------------
.../lycoon/clashapi/core/ClashAPIClient.kt | 41 ++
.../com/lycoon/clashapi/core/CoreUtils.kt | 2 +-
.../AuthException.kt | 10 +-
.../BadRequestException.kt | 10 +-
.../ClashAPIException.kt | 14 +-
.../MaintenanceException.kt | 10 +-
.../NotFoundException.kt | 10 +-
.../RateLimitException.kt | 10 +-
.../UnknownException.kt | 10 +-
.../clashapi/core/interfaces/IClanAPI.kt | 123 +++++
.../clashapi/core/interfaces/IGoldPassAPI.kt | 20 +
.../clashapi/core/interfaces/ILabelAPI.kt | 35 ++
.../clashapi/core/interfaces/ILeagueAPI.kt | 151 +++++
.../clashapi/core/interfaces/ILocationAPI.kt | 140 +++++
.../clashapi/core/interfaces/IPlayerAPI.kt | 34 ++
src/test/java/ClashAPITest.kt | 12 +-
17 files changed, 655 insertions(+), 495 deletions(-)
create mode 100644 src/main/java/com/lycoon/clashapi/core/ClashAPIClient.kt
rename src/main/java/com/lycoon/clashapi/core/{exception => exceptions}/AuthException.kt (66%)
rename src/main/java/com/lycoon/clashapi/core/{exception => exceptions}/BadRequestException.kt (71%)
rename src/main/java/com/lycoon/clashapi/core/{exception => exceptions}/ClashAPIException.kt (74%)
rename src/main/java/com/lycoon/clashapi/core/{exception => exceptions}/MaintenanceException.kt (76%)
rename src/main/java/com/lycoon/clashapi/core/{exception => exceptions}/NotFoundException.kt (68%)
rename src/main/java/com/lycoon/clashapi/core/{exception => exceptions}/RateLimitException.kt (74%)
rename src/main/java/com/lycoon/clashapi/core/{exception => exceptions}/UnknownException.kt (66%)
create mode 100644 src/main/java/com/lycoon/clashapi/core/interfaces/IClanAPI.kt
create mode 100644 src/main/java/com/lycoon/clashapi/core/interfaces/IGoldPassAPI.kt
create mode 100644 src/main/java/com/lycoon/clashapi/core/interfaces/ILabelAPI.kt
create mode 100644 src/main/java/com/lycoon/clashapi/core/interfaces/ILeagueAPI.kt
create mode 100644 src/main/java/com/lycoon/clashapi/core/interfaces/ILocationAPI.kt
create mode 100644 src/main/java/com/lycoon/clashapi/core/interfaces/IPlayerAPI.kt
diff --git a/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt b/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt
index 6094bc2..51d2f25 100644
--- a/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt
+++ b/src/main/java/com/lycoon/clashapi/core/ClashAPI.kt
@@ -2,9 +2,8 @@ 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.CoreUtils.unwrapList
-import com.lycoon.clashapi.core.exception.ClashAPIException
+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.*
@@ -15,192 +14,72 @@ import com.lycoon.clashapi.models.league.League
import com.lycoon.clashapi.models.league.LeagueSeason
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 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)
+class ClashAPI(token: String) : ClashAPIClient(token), IClashAPI
{
- 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)
- private fun get(url: String, queryParamsBuilder: QueryParamsBuilder? = null): Response
- {
- val req = getBaseRequest(url, queryParamsBuilder).build()
- val res = http.newCall(req).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)
- }
-
// ##############################################
// || Clans API ||
// ##############################################
- /**
- * 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 {
+ 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
- * @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 {
+ override fun getWarlog(clanTag: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val tag = formatTag(clanTag)
val res = get("/clans/$tag/warlog", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getClans(queryParamsBuilder: ClanQueryParamsBuilder?): List
+ {
val res = get("/clans", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ 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
- * @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 {
+ override fun getClanMembers(clanTag: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val tag = formatTag(clanTag)
val res = get("/clans/$tag/members", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getCapitalRaidSeasons(clanTag: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val tag = formatTag(clanTag)
val res = get("/clans/$tag/capitalraidseasons", queryParamsBuilder)
return unwrapList(deserialize(res))
@@ -210,365 +89,142 @@ class ClashAPI(private val token: String)
// || Player API ||
// ##############################################
- /**
- * 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 {
+ 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"
}
// ##############################################
- // || Leagues API ||
+ // || League API ||
// ##############################################
- /**
- * 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 {
+ override fun getCapitalLeagues(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/capitalleagues", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getLeagues(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/leagues", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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
+ override fun getLeagueSeasonRankings(
+ leagueId: String, seasonId: String,
+ queryParamsBuilder: SimpleQueryParamsBuilder?): List
{
val res = get("/leagues/$leagueId/seasons/$seasonId", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getCapitalLeague(leagueId: String): CapitalLeague
+ {
val res = get("/capitalleagues/$leagueId")
return deserialize(res)
}
- /**
- * 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 {
+ override fun getBuilderBaseLeague(leagueId: String): BuilderBaseLeague
+ {
val res = get("/builderbaseleagues/$leagueId")
return deserialize(res)
}
- /**
- * 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 {
+ override fun getBuilderBaseLeagues(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/builderbaseleagues", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getLeague(leagueId: String): League
+ {
val res = get("/leagues/$leagueId")
return deserialize(res)
}
- /**
- * 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 {
+ override fun getLeagueSeasons(leagueId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/leagues/$leagueId/seasons", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 getWarLeague(leagueId: String): WarLeague
+ {
val res = get("/warleagues/$leagueId")
return deserialize(res)
}
- /**
- * 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 {
+ override fun getWarLeagues(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/warleagues", queryParamsBuilder)
return unwrapList(deserialize(res))
}
// ##############################################
- // || Locations API ||
+ // || Location API ||
// ##############################################
- /**
- * 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 {
+ override fun getClanRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/locations/${locationId}/rankings/clans", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getPlayerRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/locations/${locationId}/rankings/players", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getClanBuilderBaseRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/locations/${locationId}/rankings/clans-builder-base", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getClanVersusRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/locations/${locationId}/rankings/clans-versus", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getPlayerBuilderBaseRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/locations/${locationId}/rankings/players-builder-base", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getPlayerVersusRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/locations/${locationId}/rankings/players-versus", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getLocations(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/locations", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getCapitalRankings(locationId: String, queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/locations/$locationId/rankings/capitals", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getLocation(locationId: String): Location
+ {
val res = get("/locations/$locationId")
return deserialize(res)
}
@@ -577,54 +233,24 @@ class ClashAPI(private val token: String)
// || GoldPass API ||
// ##############################################
- /**
- * 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 {
+ override fun getGoldPass(): GoldPassSeason
+ {
val res = get("/goldpass/seasons/current")
return deserialize(res)
}
-
// ##############################################
- // || Labels API ||
+ // || Label API ||
// ##############################################
- /**
- * 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 {
+ override fun getPlayerLabels(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/labels/players", queryParamsBuilder)
return unwrapList(deserialize(res))
}
- /**
- * 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 {
+ override fun getClanLabels(queryParamsBuilder: SimpleQueryParamsBuilder?): List
+ {
val res = get("/labels/clans", queryParamsBuilder)
return unwrapList(deserialize(res))
}
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 3ee83f0..81ba5c1 100644
--- a/src/main/java/com/lycoon/clashapi/core/CoreUtils.kt
+++ b/src/main/java/com/lycoon/clashapi/core/CoreUtils.kt
@@ -1,6 +1,6 @@
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
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/test/java/ClashAPITest.kt b/src/test/java/ClashAPITest.kt
index 9a44f68..b9ed6e2 100644
--- a/src/test/java/ClashAPITest.kt
+++ b/src/test/java/ClashAPITest.kt
@@ -1,19 +1,9 @@
import com.lycoon.clashapi.core.ClanQueryParamsBuilder
import junit.framework.TestCase
import com.lycoon.clashapi.core.ClashAPI
-import com.lycoon.clashapi.core.CoreUtils
-import com.lycoon.clashapi.core.SimpleQueryParamsBuilder
import java.io.FileInputStream
import java.io.IOException
-import com.lycoon.clashapi.core.exception.NotFoundException
-import kotlinx.serialization.*
-import kotlinx.serialization.descriptors.PrimitiveKind
-import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
-import kotlinx.serialization.descriptors.SerialDescriptor
-import kotlinx.serialization.descriptors.buildClassSerialDescriptor
-import kotlinx.serialization.encoding.Decoder
-import kotlinx.serialization.encoding.Encoder
-import kotlinx.serialization.encoding.decodeStructure
+import com.lycoon.clashapi.core.exceptions.NotFoundException
import java.util.*
const val CLAN_TAG = "UPCU2098"
From 3155a130d7819014827ef6e2dde311fcf67a3881 Mon Sep 17 00:00:00 2001
From: Hugo Bois
Date: Wed, 22 Nov 2023 21:22:36 +0100
Subject: [PATCH 7/7] chore: fixed more serialization errors
---
.../com/lycoon/clashapi/core/QueryBuilder.kt | 16 ++++++++--------
.../com/lycoon/clashapi/models/clan/Clan.kt | 2 +-
.../com/lycoon/clashapi/models/war/War.kt | 14 +++++---------
.../com/lycoon/clashapi/models/war/WarClan.kt | 11 ++++++-----
.../lycoon/clashapi/models/war/WarMember.kt | 2 +-
.../clashapi/models/war/enums/WarState.kt | 19 +++++++++++++++++++
6 files changed, 40 insertions(+), 24 deletions(-)
create mode 100644 src/main/java/com/lycoon/clashapi/models/war/enums/WarState.kt
diff --git a/src/main/java/com/lycoon/clashapi/core/QueryBuilder.kt b/src/main/java/com/lycoon/clashapi/core/QueryBuilder.kt
index 4cac007..f77c8a1 100644
--- a/src/main/java/com/lycoon/clashapi/core/QueryBuilder.kt
+++ b/src/main/java/com/lycoon/clashapi/core/QueryBuilder.kt
@@ -31,14 +31,14 @@ 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
+ 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
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 744ff26..98098b4 100644
--- a/src/main/java/com/lycoon/clashapi/models/clan/Clan.kt
+++ b/src/main/java/com/lycoon/clashapi/models/clan/Clan.kt
@@ -31,7 +31,7 @@ data class Clan
val location: Location? = null, // nullable when using clan search
val badgeUrls: BadgeUrls,
val members: Int = 0,
- val memberList: List? = null, // nullable when using clan search
+ val memberList: List = emptyList(), // nullable when using clan search
@Deprecated("Use requiredBuilderBaseTrophies instead")
val requiredVersusTrophies: Int = 0,
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 62a74c2..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,21 +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: State,
+ 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)
-) {
- enum class State {
- CLAN_NOT_FOUND, ACCESS_DENIED, NOT_IN_WAR,
- IN_MATCHMAKING, ENTER_WAR, MATCHED, PREPARATION,
- WAR, IN_WAR, ENDED
- }
-}
\ No newline at end of file
+)
\ 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 f418446..83cc194 100644
--- a/src/main/java/com/lycoon/clashapi/models/war/WarMember.kt
+++ b/src/main/java/com/lycoon/clashapi/models/war/WarMember.kt
@@ -10,5 +10,5 @@ data class WarMember(
val townhallLevel: 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/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