mirror of
https://github.com/Sheldan/gw2-tools.git
synced 2026-04-09 00:09:36 +00:00
initial commit of functioning opening tracking
This commit is contained in:
71
gw2-tools-backend/gw2-api-client/pom.xml
Normal file
71
gw2-tools-backend/gw2-api-client/pom.xml
Normal file
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>gw2-tools</artifactId>
|
||||
<version>0.0.9-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>gw2-api-client</artifactId>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src/main/kotlin</sourceDirectory>
|
||||
<testSourceDirectory>src/test/kotlin</testSourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>compile</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>test-compile</id>
|
||||
<phase>test-compile</phase>
|
||||
<goals>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-test-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains.kotlin</groupId>
|
||||
<artifactId>kotlin-stdlib</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.github.kryszak</groupId>
|
||||
<artifactId>gwatlin</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>dev.sheldan.gw2.tools</groupId>
|
||||
<artifactId>database</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.config
|
||||
|
||||
interface ApiKey {
|
||||
fun getApiKey(): String
|
||||
fun setApiKey(key: String)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package dev.sheldan.gw2.tools.config
|
||||
|
||||
import io.github.kryszak.gwatlin.api.account.GWAccountClient
|
||||
import io.github.kryszak.gwatlin.api.characters.GWCharactersClient
|
||||
import io.github.kryszak.gwatlin.api.items.GWItemsClient
|
||||
import io.github.kryszak.gwatlin.api.miscellaneous.GWMiscellaneousClient
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.context.annotation.ScopedProxyMode
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@Configuration
|
||||
class BeanConfig(val apiKey: ApiKey) {
|
||||
|
||||
@Bean
|
||||
@RequestScope(proxyMode = ScopedProxyMode.DEFAULT)
|
||||
fun gwCharacterClient(): GWCharactersClient {
|
||||
return GWCharactersClient(apiKey.getApiKey())
|
||||
}
|
||||
|
||||
@Bean
|
||||
@RequestScope(proxyMode = ScopedProxyMode.DEFAULT)
|
||||
fun getAccountClient(): GWAccountClient {
|
||||
return GWAccountClient(apiKey.getApiKey())
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun getMiscellaneousClient(): GWMiscellaneousClient {
|
||||
return GWMiscellaneousClient()
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun gwItemClient(): GWItemsClient {
|
||||
return GWItemsClient()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package dev.sheldan.gw2.tools.loader
|
||||
|
||||
import dev.sheldan.gw2.tools.models.*
|
||||
import dev.sheldan.gw2.tools.service.ItemManagement
|
||||
import io.github.kryszak.gwatlin.api.account.GWAccountClient
|
||||
import io.github.kryszak.gwatlin.api.characters.GWCharactersClient
|
||||
import io.github.kryszak.gwatlin.api.miscellaneous.GWMiscellaneousClient
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@Component
|
||||
@RequestScope
|
||||
class AccountLoader(
|
||||
val charClient: GWCharactersClient,
|
||||
val accountClient: GWAccountClient,
|
||||
val miscellaneousClient: GWMiscellaneousClient,
|
||||
val itemManagement: ItemManagement
|
||||
) {
|
||||
fun getCharacters(): List<String>? {
|
||||
return charClient.getCharacters()
|
||||
}
|
||||
|
||||
fun getWallet(): AccountWalletView {
|
||||
val wallet = accountClient.getWallet()
|
||||
val currencies = miscellaneousClient.getCurrencies().associateBy { it.id }
|
||||
val enrichedCurrencies = wallet.mapNotNull { walletCurrency ->
|
||||
val currency = currencies[walletCurrency.id]
|
||||
currency?.let {
|
||||
EnrichedCurrency(walletCurrency.id, walletCurrency.value, it.name, it.description, it.icon)
|
||||
}
|
||||
}
|
||||
return AccountWalletView(enrichedCurrencies)
|
||||
}
|
||||
|
||||
fun getBank(): AccountVaultView {
|
||||
val bank = accountClient.getAccountVault()
|
||||
val itemIds = mutableSetOf<Int>()
|
||||
val items = bank.filterNotNull().mapNotNull {
|
||||
itemIds.add(it.id)
|
||||
EnrichedItem(it.id, it.count, it.boundTo)
|
||||
}
|
||||
val itemStats = itemManagement.getItemsAsMap(itemIds.toList())
|
||||
items.forEach { item ->
|
||||
itemStats[item.id]?.let {
|
||||
item.setValuesFromDbItem(it)
|
||||
}
|
||||
}
|
||||
return AccountVaultView(items)
|
||||
}
|
||||
|
||||
fun getMaterials(): AccountMaterialView{
|
||||
val materials = accountClient.getMaterials()
|
||||
val itemIds = mutableSetOf<Int>()
|
||||
val items = materials
|
||||
.filter { it.count > 0 }
|
||||
.map {
|
||||
|
||||
itemIds.add(it.id)
|
||||
EnrichedItem(it.id, it.count)
|
||||
}
|
||||
val actualMaterials = itemManagement.getItemsAsMap(itemIds.toList())
|
||||
items.forEach { item ->
|
||||
actualMaterials[item.id]?.let {
|
||||
item.setValuesFromDbItem(it)
|
||||
}
|
||||
}
|
||||
return AccountMaterialView(items)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package dev.sheldan.gw2.tools.loader
|
||||
|
||||
import dev.sheldan.gw2.tools.models.EnrichedCurrency
|
||||
import io.github.kryszak.gwatlin.api.miscellaneous.GWMiscellaneousClient
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class CurrencyLoader(
|
||||
var miscellaneousClient: GWMiscellaneousClient,
|
||||
) {
|
||||
fun getAllCurrencies(): List<EnrichedCurrency> {
|
||||
return miscellaneousClient.getCurrencies().map { EnrichedCurrency(it.id, 0, it.name, it.description, it.icon) }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package dev.sheldan.gw2.tools.loader
|
||||
|
||||
import dev.sheldan.gw2.tools.entity.Item
|
||||
import dev.sheldan.gw2.tools.models.*
|
||||
import dev.sheldan.gw2.tools.service.ItemManagement
|
||||
import io.github.kryszak.gwatlin.api.account.GWAccountClient
|
||||
import io.github.kryszak.gwatlin.api.account.model.InventoryItem
|
||||
import io.github.kryszak.gwatlin.api.characters.GWCharactersClient
|
||||
import io.github.kryszak.gwatlin.api.characters.model.character.inventory.Bag
|
||||
import io.github.kryszak.gwatlin.api.characters.model.character.inventory.InventorySlot
|
||||
import org.springframework.stereotype.Component
|
||||
import org.springframework.web.context.annotation.RequestScope
|
||||
|
||||
@Component
|
||||
@RequestScope
|
||||
class InventoryLoader(
|
||||
val charClient: GWCharactersClient,
|
||||
val accountClient: GWAccountClient,
|
||||
val itemManagement: ItemManagement
|
||||
) {
|
||||
|
||||
fun getInventory(characterName: String): List<Bag?>? {
|
||||
return charClient.getInventory(characterName)
|
||||
}
|
||||
|
||||
fun getFullCharacterInventory(characterName: String): CharacterInventory {
|
||||
val itemIds = mutableSetOf<Int>()
|
||||
val characterInventory = getCharacterInventory(characterName, itemIds)
|
||||
val itemStats = getFullItemInfos(itemIds)
|
||||
enrichCharacterInventory(characterInventory, itemStats)
|
||||
return characterInventory
|
||||
}
|
||||
|
||||
private fun getCharacterInventory(characterName: String, itemIds: MutableSet<Int>): CharacterInventory {
|
||||
val characterInventory = getInventory(characterName)
|
||||
val convertedBags = mutableListOf<InventoryBag>()
|
||||
characterInventory?.let {
|
||||
for (bag in characterInventory.filterNotNull()) {
|
||||
convertedBags.addLast(convertApiBagToCharacterInventory(bag, itemIds))
|
||||
}
|
||||
}
|
||||
return CharacterInventory(characterName, convertedBags)
|
||||
}
|
||||
|
||||
fun getAccountInventory(): AccountInventoryView {
|
||||
val characters = charClient.getCharacters()
|
||||
val itemIds = mutableSetOf<Int>()
|
||||
val inventories = mutableListOf<CharacterInventory>()
|
||||
for (characterName in characters) {
|
||||
inventories.addLast(getCharacterInventory(characterName, itemIds))
|
||||
}
|
||||
|
||||
val itemStats = getFullItemInfos(itemIds)
|
||||
inventories.forEach { enrichCharacterInventory(it, itemStats) }
|
||||
return AccountInventoryView(inventories)
|
||||
}
|
||||
|
||||
private fun enrichCharacterInventory(characterInventory: CharacterInventory, itemStats: Map<Int, Item>) {
|
||||
return characterInventory.bags.forEach { bag ->
|
||||
bag.items.forEach { item ->
|
||||
itemStats[item.id]?.let {
|
||||
item.setValuesFromDbItem(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun convertApiBagToCharacterInventory(bag: Bag, itemIds: MutableSet<Int>): InventoryBag {
|
||||
val items = bag.inventory.filterNotNull().map { convertInventorySlot(it, itemIds) }
|
||||
return InventoryBag(bag.id, bag.size, items)
|
||||
}
|
||||
|
||||
private fun convertInventorySlot(slot: InventorySlot, itemIds: MutableSet<Int>): EnrichedItem {
|
||||
itemIds.add(slot.id)
|
||||
return EnrichedItem(slot.id, slot.count, slot.boundTo)
|
||||
}
|
||||
|
||||
private fun convertInventoryItem(item: InventoryItem, itemIds: MutableSet<Int>): EnrichedItem {
|
||||
itemIds.add(item.id)
|
||||
return EnrichedItem(item.id, item.count, item.binding)
|
||||
}
|
||||
|
||||
fun getSharedInventory(): AccountInventory {
|
||||
val itemIds = mutableSetOf<Int>()
|
||||
val sharedInventorySlots = accountClient.getInventory().filterNotNull()
|
||||
val sharedItems = sharedInventorySlots.map { convertInventoryItem(it, itemIds) }
|
||||
val fullItemInfo = getFullItemInfos(itemIds)
|
||||
sharedItems.forEach { item ->
|
||||
fullItemInfo[item.id]?.let {
|
||||
item.setValuesFromDbItem(it)
|
||||
}
|
||||
}
|
||||
return AccountInventory(sharedItems)
|
||||
}
|
||||
|
||||
private fun getFullItemInfos(itemIds: MutableSet<Int>) = itemManagement.getItemsAsMap(itemIds.toList())
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package dev.sheldan.gw2.tools.loader
|
||||
|
||||
import dev.sheldan.gw2.tools.models.EnrichedItem
|
||||
import io.github.kryszak.gwatlin.api.items.GWItemsClient
|
||||
import org.springframework.stereotype.Component
|
||||
|
||||
@Component
|
||||
class ItemLoader(
|
||||
val itemClient: GWItemsClient
|
||||
) {
|
||||
fun getAllItems(): List<EnrichedItem> {
|
||||
return itemClient.getItemIds().chunked(200)
|
||||
.flatMap { (itemClient.getItems(it)) }
|
||||
.map {
|
||||
val item = EnrichedItem(it.id, 1)
|
||||
item.setValuesFromItem(it)
|
||||
item
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
class AccountInventory(
|
||||
val slots: List<EnrichedItem>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
data class AccountInventoryView(
|
||||
val inventories: List<CharacterInventory>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
class AccountMaterialView(
|
||||
val slots: List<EnrichedItem>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
class AccountVaultView(
|
||||
val slots: List<EnrichedItem>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
class AccountWalletView(
|
||||
val currencies: List<EnrichedCurrency>
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
data class CharacterInventory(
|
||||
val name: String,
|
||||
val bags: List<InventoryBag>
|
||||
)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
class EnrichedCurrency(
|
||||
val id: Int,
|
||||
var amount: Int,
|
||||
val name: String,
|
||||
val description: String,
|
||||
val iconUrl: String
|
||||
) {
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
import io.github.kryszak.gwatlin.api.items.model.item.Item
|
||||
|
||||
data class EnrichedItem(
|
||||
val id: Int,
|
||||
var count: Int,
|
||||
val boundTo: String? = null,
|
||||
|
||||
var iconUrl: String? = null,
|
||||
var name: String? = null,
|
||||
var description: String? = null,
|
||||
var type: Gw2TItemType? = null,
|
||||
var level: Int? = null,
|
||||
var rarity: Gw2TItemRarity? = null
|
||||
) {
|
||||
fun setValuesFromItem(item: Item) {
|
||||
this.name = item.name
|
||||
this.level = item.level
|
||||
this.description = item.description
|
||||
this.type = Gw2TItemType.convertFromAPI(item.type)
|
||||
this.rarity = Gw2TItemRarity.convertFromAPI(item.rarity)
|
||||
this.iconUrl = item.icon.ifBlank { "https://render.guildwars2.com/file/4BC52199DBDEEF5D4D90736B582DDA0F092B0DE4/434780.png" } // default icon if nothing is shown
|
||||
}
|
||||
|
||||
fun setValuesFromDbItem(item: dev.sheldan.gw2.tools.entity.Item) {
|
||||
this.name = item.name
|
||||
this.description = item.description
|
||||
this.type = Gw2TItemType.valueOf(item.type)
|
||||
this.rarity = Gw2TItemRarity.valueOf(item.rarity)
|
||||
this.iconUrl = item.iconUrl
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
import io.github.kryszak.gwatlin.api.items.model.item.ItemRarity
|
||||
|
||||
enum class Gw2TItemRarity {
|
||||
JUNK,
|
||||
BASIC,
|
||||
FINE,
|
||||
MASTERWORK,
|
||||
RARE,
|
||||
EXOTIC,
|
||||
ASCENDED,
|
||||
LEGENDARY;
|
||||
|
||||
companion object {
|
||||
fun convertFromAPI(rarity: ItemRarity): Gw2TItemRarity = when (rarity) {
|
||||
ItemRarity.FINE -> FINE
|
||||
ItemRarity.MASTERWORK -> MASTERWORK
|
||||
ItemRarity.RARE -> RARE
|
||||
ItemRarity.EXOTIC -> EXOTIC
|
||||
ItemRarity.JUNK -> JUNK
|
||||
ItemRarity.BASIC -> BASIC
|
||||
ItemRarity.ASCENDED -> ASCENDED
|
||||
ItemRarity.LEGENDARY -> LEGENDARY
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
import io.github.kryszak.gwatlin.api.items.model.item.ItemType
|
||||
|
||||
enum class Gw2TItemType {
|
||||
CONTAINER,
|
||||
ARMOR,
|
||||
BACK,
|
||||
BAG,
|
||||
CONSUMABLE,
|
||||
CRAFTING_MATERIAL,
|
||||
GATHERING,
|
||||
GIZMO,
|
||||
JADE_TECH_MODULE,
|
||||
KEY,
|
||||
MINI_PET,
|
||||
POWER_CORE,
|
||||
TOOL,
|
||||
TRAIT,
|
||||
TRINKET,
|
||||
TROPHY,
|
||||
UPGRADE_COMPONENT,
|
||||
WEAPON,
|
||||
RELIC;
|
||||
|
||||
companion object {
|
||||
fun convertFromAPI(type: ItemType): Gw2TItemType = when (type) {
|
||||
ItemType.CONTAINER -> CONTAINER
|
||||
ItemType.ARMOR -> ARMOR
|
||||
ItemType.BACK -> BACK
|
||||
ItemType.BAG -> BAG
|
||||
ItemType.CONSUMABLE -> CONSUMABLE
|
||||
ItemType.CRAFTING_MATERIAL -> CRAFTING_MATERIAL
|
||||
ItemType.GATHERING -> GATHERING
|
||||
ItemType.GIZMO -> GIZMO
|
||||
ItemType.JADE_TECH_MODULE -> JADE_TECH_MODULE
|
||||
ItemType.KEY -> KEY
|
||||
ItemType.MINI_PET -> MINI_PET
|
||||
ItemType.POWER_CORE -> POWER_CORE
|
||||
ItemType.TOOL -> TOOL
|
||||
ItemType.TRAIT -> TRAIT
|
||||
ItemType.TRINKET -> TRINKET
|
||||
ItemType.TROPHY -> TROPHY
|
||||
ItemType.UPGRADE_COMPONENT -> UPGRADE_COMPONENT
|
||||
ItemType.WEAPON -> WEAPON
|
||||
ItemType.RELIC -> RELIC
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package dev.sheldan.gw2.tools.models
|
||||
|
||||
data class InventoryBag(
|
||||
val id: Int,
|
||||
val size: Int,
|
||||
val items: List<EnrichedItem>
|
||||
) {
|
||||
}
|
||||
Reference in New Issue
Block a user