From f7b3b7256a61a5356dbc73d2304d20388be5053c Mon Sep 17 00:00:00 2001 From: Nacho Date: Mon, 10 Feb 2025 17:44:13 +0100 Subject: [PATCH 1/4] VB NFC compatibility - Refactored some names (not really relevant) - Added the ability to store special missions inside the application's database - Refactored the conversion code into two classes inside the scan screen package - Added the missing tables to store the necessary vb data Also not relevant to this update - Updated adventure progress app wide, so that instead of it being stored in a character basis, it is shared across all characters in the same dim --- .../nacabaro/vbhelper/daos/CharacterDao.kt | 8 +- .../github/nacabaro/vbhelper/daos/DiMDao.kt | 21 +- .../vbhelper/daos/UserCharacterDao.kt | 16 +- .../nacabaro/vbhelper/database/AppDatabase.kt | 4 + .../vbhelper/domain/characters/Card.kt | 3 +- .../domain/device_data/SpecialMissions.kt | 20 ++ .../domain/device_data/UserCharacter.kt | 1 - .../domain/device_data/VBCharacterData.kt | 21 +- .../vbhelper/screens/scanScreen/ScanScreen.kt | 60 +++-- .../scanScreen/ScanScreenController.kt | 2 + .../scanScreen/ScanScreenControllerImpl.kt | 114 ++------- .../scanScreen/converters/FromNfcConverter.kt | 187 +++++++++++++++ .../scanScreen/converters/ToNfcConverter.kt | 218 ++++++++++++++++++ .../SettingsScreenControllerImpl.kt | 5 +- .../vbhelper/utils/CharacterToNFCCharacter.kt | 99 -------- .../vbhelper/utils/padTransformationArray.kt | 23 -- 16 files changed, 539 insertions(+), 263 deletions(-) create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/SpecialMissions.kt create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt delete mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/utils/CharacterToNFCCharacter.kt delete mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/utils/padTransformationArray.kt diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt index a42e6c7..2d9fdfb 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt @@ -12,12 +12,6 @@ interface CharacterDao { @Insert suspend fun insertCharacter(vararg characterData: Character) - @Query("SELECT * FROM Character") - suspend fun getAllCharacters(): List - - @Query("SELECT * FROM Character WHERE dimId = :dimId") - suspend fun getCharacterByDimId(dimId: Int): List - @Query("SELECT * FROM Character WHERE monIndex = :monIndex AND dimId = :dimId LIMIT 1") fun getCharacterByMonIndex(monIndex: Int, dimId: Long): Character @@ -30,7 +24,7 @@ interface CharacterDao { @Query( """ SELECT - d.dimId as cardId, + d.cardId as cardId, c.monIndex as charId FROM Character c JOIN UserCharacter uc ON c.id = uc.charId diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt index 885449f..9fee717 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt @@ -11,9 +11,22 @@ interface DiMDao { @Insert(onConflict = OnConflictStrategy.IGNORE) suspend fun insertNewDim(card: Card): Long - @Query("SELECT * FROM Card") - suspend fun getAllDims(): List - - @Query("SELECT * FROM Card WHERE dimId = :id") + @Query("SELECT * FROM Card WHERE cardId = :id") fun getDimById(id: Int): Card? + + @Query( + """ + UPDATE Card + SET currentStage = :currentStage + WHERE cardId = :id + """ + ) + fun updateCurrentStage(id: Int, currentStage: Int) + + @Query(""" + SELECT currentStage + FROM Card + WHERE cardId = :id + """) + fun getCurrentStage(id: Int): Int } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt index 6e8e33f..4b95d2a 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt @@ -7,7 +7,9 @@ import androidx.room.Query import androidx.room.Upsert import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData +import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory +import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData import com.github.nacabaro.vbhelper.dtos.CharacterDtos @Dao @@ -18,6 +20,9 @@ interface UserCharacterDao { @Insert fun insertBECharacterData(characterData: BECharacterData) + @Insert + fun insertVBCharacterData(characterData: VBCharacterData) + @Upsert fun updateCharacter(character: UserCharacter) @@ -27,6 +32,9 @@ interface UserCharacterDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertTransformationHistory(vararg transformationHistory: TransformationHistory) + @Insert + fun insertSpecialMissions(vararg specialMissions: SpecialMissions) + @Query(""" SELECT c.id AS id, @@ -39,7 +47,7 @@ interface UserCharacterDao { JOIN Character c ON c.id = t.stageId WHERE monId = :monId """) - fun getTransformationHistory(monId: Long): List? + suspend fun getTransformationHistory(monId: Long): List? @Query( """ @@ -87,6 +95,12 @@ interface UserCharacterDao { @Query("SELECT * FROM BECharacterData WHERE id = :id") suspend fun getBeData(id: Long): BECharacterData + @Query("SELECT * FROM VBCharacterData WHERE id = :id") + suspend fun getVbData(id: Long): VBCharacterData + + @Query("SELECT * FROM SpecialMissions WHERE characterId = :id") + suspend fun getSpecialMissions(id: Long): List + @Query( """ SELECT diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt b/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt index 6b5bf5f..f248032 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt @@ -14,8 +14,10 @@ import com.github.nacabaro.vbhelper.domain.Sprites import com.github.nacabaro.vbhelper.domain.characters.Adventure import com.github.nacabaro.vbhelper.domain.characters.Dex import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData +import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter +import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData import com.github.nacabaro.vbhelper.domain.items.Items @Database( @@ -26,6 +28,8 @@ import com.github.nacabaro.vbhelper.domain.items.Items Sprites::class, UserCharacter::class, BECharacterData::class, + VBCharacterData::class, + SpecialMissions::class, TransformationHistory::class, Dex::class, Items::class, diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Card.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Card.kt index 8e3a379..536413f 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Card.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Card.kt @@ -7,11 +7,12 @@ import androidx.room.PrimaryKey data class Card( @PrimaryKey(autoGenerate = true) val id: Long = 0, - val dimId: Int, + val cardId: Int, val logo: ByteArray, val logoWidth: Int, val logoHeight: Int, val name: String, val stageCount: Int, + val currentStage: Int, val isBEm: Boolean ) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/SpecialMissions.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/SpecialMissions.kt new file mode 100644 index 0000000..37f5664 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/SpecialMissions.kt @@ -0,0 +1,20 @@ +package com.github.nacabaro.vbhelper.domain.device_data + +import androidx.room.Entity +import androidx.room.PrimaryKey +import com.github.cfogrady.vbnfc.vb.SpecialMission + +@Entity( + +) +data class SpecialMissions ( + @PrimaryKey(autoGenerate = true) var id: Long = 0, + var characterId: Long, + var goal: Int, + val watchId: Int, + val progress: Int, + val status: SpecialMission.Status, + val timeElapsedInMinutes: Int, + val timeLimitInMinutes: Int, + val missionType: SpecialMission.Type +) \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/UserCharacter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/UserCharacter.kt index 75007d7..018afcf 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/UserCharacter.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/UserCharacter.kt @@ -23,7 +23,6 @@ data class UserCharacter ( var stage: Int, var attribute: NfcCharacter.Attribute, var ageInDays: Int, - var nextAdventureMissionStage: Int, // next adventure mission stage on the character's dim var mood: Int, var vitalPoints: Int, var transformationCountdown: Int, diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VBCharacterData.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VBCharacterData.kt index c60dba0..33a45e3 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VBCharacterData.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VBCharacterData.kt @@ -1,4 +1,21 @@ package com.github.nacabaro.vbhelper.domain.device_data -class VBCharacterData { -} \ No newline at end of file +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.PrimaryKey + +@Entity( + foreignKeys = [ + ForeignKey( + entity = UserCharacter::class, + parentColumns = ["id"], + childColumns = ["id"], + onDelete = ForeignKey.CASCADE + ) + ] +) +data class VBCharacterData ( + @PrimaryKey val id: Long, + val generation: Int, + val totalTrophies: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt index a4cbb03..f406651 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt @@ -34,7 +34,6 @@ import com.github.nacabaro.vbhelper.navigation.NavigationItems import com.github.nacabaro.vbhelper.source.StorageRepository import com.github.nacabaro.vbhelper.source.isMissingSecrets import com.github.nacabaro.vbhelper.source.proto.Secrets -import com.github.nacabaro.vbhelper.utils.characterToNfc import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.withContext @@ -62,29 +61,43 @@ fun ScanScreen( LaunchedEffect(storageRepository) { withContext(Dispatchers.IO) { if(characterId != null && nfcCharacter == null) { - nfcCharacter = characterToNfc(context, characterId) + nfcCharacter = scanScreenController.characterToNfc(characterId) } } } - DisposableEffect(readingScreen || writingScreen, isDoneSendingCard) { + DisposableEffect(readingScreen) { if(readingScreen) { - scanScreenController.registerActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER, object: ActivityLifecycleListener { - override fun onPause() { - scanScreenController.cancelRead() - } + scanScreenController.registerActivityLifecycleListener( + SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER, + object: ActivityLifecycleListener { + override fun onPause() { + scanScreenController.cancelRead() + } - override fun onResume() { - scanScreenController.onClickRead(secrets!!) { - isDoneReadingCharacter = true + override fun onResume() { + scanScreenController.onClickRead(secrets!!) { + isDoneReadingCharacter = true + } } } - - }) + ) scanScreenController.onClickRead(secrets!!) { isDoneReadingCharacter = true } - } else if (writingScreen) { + } + onDispose { + if(readingScreen) { + scanScreenController.unregisterActivityLifecycleListener( + SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER + ) + scanScreenController.cancelRead() + } + } + } + + DisposableEffect(writingScreen, isDoneSendingCard) { + if (writingScreen) { scanScreenController.registerActivityLifecycleListener( SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER, object : ActivityLifecycleListener { @@ -105,18 +118,20 @@ fun ScanScreen( } } ) - if (!isDoneSendingCard) { - scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) { - isDoneSendingCard = true - } - } else if (!isDoneWritingCharacter) { - scanScreenController.onClickWrite(secrets!!, nfcCharacter!!) { - isDoneWritingCharacter = true - } + } + + if (!isDoneSendingCard) { + scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) { + isDoneSendingCard = true + } + } else if (!isDoneWritingCharacter) { + scanScreenController.onClickWrite(secrets!!, nfcCharacter!!) { + isDoneWritingCharacter = true } } + onDispose { - if(readingScreen || writingScreen) { + if(writingScreen) { scanScreenController.unregisterActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER) scanScreenController.cancelRead() } @@ -259,6 +274,7 @@ fun ScanScreenPreview() { override fun onClickCheckCard(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {} override fun onClickWrite(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {} override fun cancelRead() {} + override suspend fun characterToNfc(characterId: Long): NfcCharacter? { return null } }, characterId = null ) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt index 609ab50..f52426e 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt @@ -15,4 +15,6 @@ interface ScanScreenController { fun registerActivityLifecycleListener(key: String, activityLifecycleListener: ActivityLifecycleListener) fun unregisterActivityLifecycleListener(key: String) + + suspend fun characterToNfc(characterId: Long): NfcCharacter? } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt index d7caf92..be4941f 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt @@ -11,22 +11,19 @@ import android.widget.Toast import androidx.activity.ComponentActivity import androidx.lifecycle.lifecycleScope import com.github.cfogrady.vbnfc.TagCommunicator -import com.github.cfogrady.vbnfc.be.BENfcCharacter import com.github.cfogrady.vbnfc.data.NfcCharacter -import com.github.cfogrady.vbnfc.vb.VBNfcCharacter import com.github.nacabaro.vbhelper.ActivityLifecycleListener +import com.github.nacabaro.vbhelper.database.AppDatabase import com.github.nacabaro.vbhelper.di.VBHelper -import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData -import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter import com.github.nacabaro.vbhelper.source.getCryptographicTransformerMap import com.github.nacabaro.vbhelper.source.isMissingSecrets import com.github.nacabaro.vbhelper.source.proto.Secrets -import com.github.nacabaro.vbhelper.utils.DeviceType +import com.github.nacabaro.vbhelper.screens.scanScreen.converters.FromNfcConverter +import com.github.nacabaro.vbhelper.screens.scanScreen.converters.ToNfcConverter import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import java.util.GregorianCalendar class ScanScreenControllerImpl( override val secretsFlow: Flow, @@ -37,6 +34,8 @@ class ScanScreenControllerImpl( private val nfcAdapter: NfcAdapter + private val storageRepository: AppDatabase + init { val maybeNfcAdapter = NfcAdapter.getDefaultAdapter(componentActivity) if (maybeNfcAdapter == null) { @@ -44,6 +43,8 @@ class ScanScreenControllerImpl( } nfcAdapter = maybeNfcAdapter checkSecrets() + val application = componentActivity.applicationContext as VBHelper + storageRepository = application.container.db } override fun onClickRead(secrets: Secrets, onComplete: ()->Unit) { @@ -152,102 +153,13 @@ class ScanScreenControllerImpl( } private fun addCharacterScannedIntoDatabase(nfcCharacter: NfcCharacter): String { - val application = componentActivity.applicationContext as VBHelper - val storageRepository = application.container.db + val fromNfcConverter = FromNfcConverter(componentActivity) + return fromNfcConverter.addCharacter(nfcCharacter) + } - val dimData = storageRepository - .dimDao() - .getDimById(nfcCharacter.dimId.toInt()) - if (dimData == null) return "Card not found" - - val cardCharData = storageRepository - .characterDao() - .getCharacterByMonIndex(nfcCharacter.charIndex.toInt(), dimData.id) - - val characterData = UserCharacter( - charId = cardCharData.id, - stage = nfcCharacter.stage.toInt(), - attribute = nfcCharacter.attribute, - ageInDays = nfcCharacter.ageInDays.toInt(), - nextAdventureMissionStage = nfcCharacter.nextAdventureMissionStage.toInt(), - mood = nfcCharacter.mood.toInt(), - vitalPoints = nfcCharacter.vitalPoints.toInt(), - transformationCountdown = nfcCharacter.transformationCountdownInMinutes.toInt(), - injuryStatus = nfcCharacter.injuryStatus, - trophies = nfcCharacter.trophies.toInt(), - currentPhaseBattlesWon = nfcCharacter.currentPhaseBattlesWon.toInt(), - currentPhaseBattlesLost = nfcCharacter.currentPhaseBattlesLost.toInt(), - totalBattlesWon = nfcCharacter.totalBattlesWon.toInt(), - totalBattlesLost = nfcCharacter.totalBattlesLost.toInt(), - activityLevel = nfcCharacter.activityLevel.toInt(), - heartRateCurrent = nfcCharacter.heartRateCurrent.toInt(), - characterType = when (nfcCharacter) { - is BENfcCharacter -> DeviceType.BEDevice - else -> DeviceType.VBDevice - }, - isActive = true - ) - - storageRepository - .userCharacterDao() - .clearActiveCharacter() - - val characterId: Long = storageRepository - .userCharacterDao() - .insertCharacterData(characterData) - - if (nfcCharacter is BENfcCharacter) { - val extraCharacterData = BECharacterData( - id = characterId, - trainingHp = nfcCharacter.trainingHp.toInt(), - trainingAp = nfcCharacter.trainingAp.toInt(), - trainingBp = nfcCharacter.trainingBp.toInt(), - remainingTrainingTimeInMinutes = nfcCharacter.remainingTrainingTimeInMinutes.toInt(), - itemEffectActivityLevelValue = nfcCharacter.itemEffectActivityLevelValue.toInt(), - itemEffectMentalStateValue = nfcCharacter.itemEffectMentalStateValue.toInt(), - itemEffectMentalStateMinutesRemaining = nfcCharacter.itemEffectMentalStateMinutesRemaining.toInt(), - itemEffectActivityLevelMinutesRemaining = nfcCharacter.itemEffectActivityLevelMinutesRemaining.toInt(), - itemEffectVitalPointsChangeValue = nfcCharacter.itemEffectVitalPointsChangeValue.toInt(), - itemEffectVitalPointsChangeMinutesRemaining = nfcCharacter.itemEffectVitalPointsChangeMinutesRemaining.toInt(), - abilityRarity = nfcCharacter.abilityRarity, - abilityType = nfcCharacter.abilityType.toInt(), - abilityBranch = nfcCharacter.abilityBranch.toInt(), - abilityReset = nfcCharacter.abilityReset.toInt(), - rank = nfcCharacter.abilityReset.toInt(), - itemType = nfcCharacter.itemType.toInt(), - itemMultiplier = nfcCharacter.itemMultiplier.toInt(), - itemRemainingTime = nfcCharacter.itemRemainingTime.toInt(), - otp0 = "", //nfcCharacter.value!!.otp0.toString(), - otp1 = "", //nfcCharacter.value!!.otp1.toString(), - minorVersion = nfcCharacter.characterCreationFirmwareVersion.minorVersion.toInt(), - majorVersion = nfcCharacter.characterCreationFirmwareVersion.majorVersion.toInt(), - ) - - storageRepository - .userCharacterDao() - .insertBECharacterData(extraCharacterData) - - val transformationHistoryWatch = nfcCharacter.transformationHistory - transformationHistoryWatch.map { item -> - if (item.toCharIndex.toInt() != 255) { - val date = GregorianCalendar(item.year.toInt(), item.month.toInt(), item.day.toInt()) - .time - .time - - storageRepository - .characterDao() - .insertTransformation(characterId, item.toCharIndex.toInt(), dimData.id, date) - - storageRepository - .dexDao() - .insertCharacter(item.toCharIndex.toInt(), dimData.id, date) - } - } - } else if (nfcCharacter is VBNfcCharacter) { - return "Not implemented yet" - } - - return "Done reading character!" + override suspend fun characterToNfc(characterId: Long): NfcCharacter { + val nfcCharacterConverter = ToNfcConverter(componentActivity) + return nfcCharacterConverter.characterToNfc(characterId) } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt new file mode 100644 index 0000000..08fb68d --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt @@ -0,0 +1,187 @@ +package com.github.nacabaro.vbhelper.screens.scanScreen.converters + +import androidx.activity.ComponentActivity +import com.github.cfogrady.vbnfc.be.BENfcCharacter +import com.github.cfogrady.vbnfc.data.NfcCharacter +import com.github.cfogrady.vbnfc.vb.VBNfcCharacter +import com.github.nacabaro.vbhelper.di.VBHelper +import com.github.nacabaro.vbhelper.domain.characters.Card +import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData +import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions +import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter +import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData +import com.github.nacabaro.vbhelper.utils.DeviceType +import java.util.GregorianCalendar + +class FromNfcConverter ( + componentActivity: ComponentActivity +) { + private val application = componentActivity.applicationContext as VBHelper + private val database = application.container.db + + fun addCharacter(nfcCharacter: NfcCharacter): String { + val dimData = database + .dimDao() + .getDimById(nfcCharacter.dimId.toInt()) + + if (dimData == null) + return "Card not found" + + val cardCharData = database + .characterDao() + .getCharacterByMonIndex(nfcCharacter.charIndex.toInt(), dimData.id) + + database + .dimDao() + .updateCurrentStage( + id = nfcCharacter.dimId.toInt(), + currentStage = nfcCharacter.nextAdventureMissionStage.toInt() + ) + + val characterData = UserCharacter( + charId = cardCharData.id, + stage = nfcCharacter.stage.toInt(), + attribute = nfcCharacter.attribute, + ageInDays = nfcCharacter.ageInDays.toInt(), + mood = nfcCharacter.mood.toInt(), + vitalPoints = nfcCharacter.vitalPoints.toInt(), + transformationCountdown = nfcCharacter.transformationCountdownInMinutes.toInt(), + injuryStatus = nfcCharacter.injuryStatus, + trophies = nfcCharacter.trophies.toInt(), + currentPhaseBattlesWon = nfcCharacter.currentPhaseBattlesWon.toInt(), + currentPhaseBattlesLost = nfcCharacter.currentPhaseBattlesLost.toInt(), + totalBattlesWon = nfcCharacter.totalBattlesWon.toInt(), + totalBattlesLost = nfcCharacter.totalBattlesLost.toInt(), + activityLevel = nfcCharacter.activityLevel.toInt(), + heartRateCurrent = nfcCharacter.heartRateCurrent.toInt(), + characterType = when (nfcCharacter) { + is BENfcCharacter -> DeviceType.BEDevice + else -> DeviceType.VBDevice + }, + isActive = true + ) + + database + .userCharacterDao() + .clearActiveCharacter() + + val characterId: Long = database + .userCharacterDao() + .insertCharacterData(characterData) + + if (nfcCharacter is BENfcCharacter) { + addBeCharacterToDatabase( + characterId = characterId, + nfcCharacter = nfcCharacter + ) + } else if (nfcCharacter is VBNfcCharacter) { + addVbCharacterToDatabase( + characterId = characterId, + nfcCharacter = nfcCharacter + ) + } + + addTransformationHistoryToDatabase( + characterId = characterId, + nfcCharacter = nfcCharacter, + dimData = dimData + ) + + return "Done reading character!" + + } + + private fun addVbCharacterToDatabase(characterId: Long, nfcCharacter: VBNfcCharacter) { + val extraCharacterData = VBCharacterData( + id = characterId, + generation = nfcCharacter.generation.toInt(), + totalTrophies = nfcCharacter.totalTrophies.toInt() + ) + + val specialMissionsWatch = nfcCharacter.specialMissions + val specialMissionsDb = specialMissionsWatch.map { item -> + SpecialMissions( + characterId = characterId, + goal = item.goal.toInt(), + watchId = item.id.toInt(), + progress = item.progress.toInt(), + status = item.status, + timeElapsedInMinutes = item.timeElapsedInMinutes.toInt(), + timeLimitInMinutes = item.timeLimitInMinutes.toInt(), + missionType = item.type, + ) + } + + database + .userCharacterDao() + .insertVBCharacterData(extraCharacterData) + + database + .userCharacterDao() + .insertSpecialMissions(*specialMissionsDb.toTypedArray()) + } + + private fun addBeCharacterToDatabase(characterId: Long, nfcCharacter: BENfcCharacter) { + val extraCharacterData = BECharacterData( + id = characterId, + trainingHp = nfcCharacter.trainingHp.toInt(), + trainingAp = nfcCharacter.trainingAp.toInt(), + trainingBp = nfcCharacter.trainingBp.toInt(), + remainingTrainingTimeInMinutes = nfcCharacter.remainingTrainingTimeInMinutes.toInt(), + itemEffectActivityLevelValue = nfcCharacter.itemEffectActivityLevelValue.toInt(), + itemEffectMentalStateValue = nfcCharacter.itemEffectMentalStateValue.toInt(), + itemEffectMentalStateMinutesRemaining = nfcCharacter.itemEffectMentalStateMinutesRemaining.toInt(), + itemEffectActivityLevelMinutesRemaining = nfcCharacter.itemEffectActivityLevelMinutesRemaining.toInt(), + itemEffectVitalPointsChangeValue = nfcCharacter.itemEffectVitalPointsChangeValue.toInt(), + itemEffectVitalPointsChangeMinutesRemaining = nfcCharacter.itemEffectVitalPointsChangeMinutesRemaining.toInt(), + abilityRarity = nfcCharacter.abilityRarity, + abilityType = nfcCharacter.abilityType.toInt(), + abilityBranch = nfcCharacter.abilityBranch.toInt(), + abilityReset = nfcCharacter.abilityReset.toInt(), + rank = nfcCharacter.abilityReset.toInt(), + itemType = nfcCharacter.itemType.toInt(), + itemMultiplier = nfcCharacter.itemMultiplier.toInt(), + itemRemainingTime = nfcCharacter.itemRemainingTime.toInt(), + otp0 = "", //nfcCharacter.value!!.otp0.toString(), + otp1 = "", //nfcCharacter.value!!.otp1.toString(), + minorVersion = nfcCharacter.characterCreationFirmwareVersion.minorVersion.toInt(), + majorVersion = nfcCharacter.characterCreationFirmwareVersion.majorVersion.toInt(), + ) + + database + .userCharacterDao() + .insertBECharacterData(extraCharacterData) + } + + private fun addTransformationHistoryToDatabase(characterId: Long, nfcCharacter: NfcCharacter, dimData: Card) { + val transformationHistoryWatch = nfcCharacter.transformationHistory + transformationHistoryWatch.map { item -> + if (item.toCharIndex.toInt() != 255) { + val date = GregorianCalendar( + item.year.toInt(), + item.month.toInt(), + item.day.toInt() + ) + .time + .time + + database + .characterDao() + .insertTransformation( + characterId, + item.toCharIndex.toInt(), + dimData.id, + date + ) + + database + .dexDao() + .insertCharacter( + item.toCharIndex.toInt(), + dimData.id, + date + ) + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt new file mode 100644 index 0000000..8ad9228 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt @@ -0,0 +1,218 @@ +package com.github.nacabaro.vbhelper.screens.scanScreen.converters + +import android.icu.util.Calendar +import androidx.activity.ComponentActivity +import com.github.cfogrady.vbnfc.be.BENfcCharacter +import com.github.cfogrady.vbnfc.be.FirmwareVersion +import com.github.cfogrady.vbnfc.data.NfcCharacter +import com.github.cfogrady.vbnfc.vb.SpecialMission +import com.github.cfogrady.vbnfc.vb.VBNfcCharacter +import com.github.nacabaro.vbhelper.database.AppDatabase +import com.github.nacabaro.vbhelper.di.VBHelper +import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter +import com.github.nacabaro.vbhelper.dtos.CharacterDtos +import com.github.nacabaro.vbhelper.utils.DeviceType +import java.util.Date + +class ToNfcConverter( + private val componentActivity: ComponentActivity +) { + private val application: VBHelper = componentActivity.applicationContext as VBHelper + private val database: AppDatabase = application.container.db + + suspend fun characterToNfc(characterId: Long): NfcCharacter { + val app = componentActivity.applicationContext as VBHelper + val database = app.container.db + + val userCharacter = database + .userCharacterDao() + .getCharacter(characterId) + + val characterInfo = database + .characterDao() + .getCharacterInfo(userCharacter.charId) + + val currentCardStage = database.dimDao().getCurrentStage(characterInfo.cardId) + + return if (userCharacter.characterType == DeviceType.BEDevice) + nfcToBENfc(characterId, characterInfo, currentCardStage, userCharacter) + else + nfcToVBNfc(characterId, characterInfo, currentCardStage, userCharacter) + } + + private suspend fun nfcToVBNfc( + characterId: Long, + characterInfo: CharacterDtos.DiMInfo, + currentCardStage: Int, + userCharacter: UserCharacter + ): VBNfcCharacter { + val vbData = database + .userCharacterDao() + .getVbData(characterId) + + val specialMissions = database + .userCharacterDao() + .getSpecialMissions(characterId) + + val paddedTransformationArray = generateTransformationHistory(characterId) + + val watchSpecialMissions = specialMissions.map { + SpecialMission( + goal = it.goal.toUShort(), + id = it.watchId.toUShort(), + progress = it.progress.toUShort(), + status = it.status, + timeElapsedInMinutes = it.timeElapsedInMinutes.toUShort(), + timeLimitInMinutes = it.timeLimitInMinutes.toUShort(), + type = it.missionType + ) + } + + val nfcData = VBNfcCharacter( + dimId = characterInfo.cardId.toUShort(), + charIndex = characterInfo.charId.toUShort(), + stage = userCharacter.stage.toByte(), + attribute = userCharacter.attribute, + ageInDays = userCharacter.ageInDays.toByte(), + nextAdventureMissionStage = currentCardStage.toByte(), + mood = userCharacter.mood.toByte(), + vitalPoints = userCharacter.vitalPoints.toUShort(), + transformationCountdownInMinutes = userCharacter.transformationCountdown.toUShort(), + injuryStatus = userCharacter.injuryStatus, + trophies = userCharacter.trophies.toUShort(), + currentPhaseBattlesWon = userCharacter.currentPhaseBattlesWon.toUShort(), + currentPhaseBattlesLost = userCharacter.currentPhaseBattlesLost.toUShort(), + totalBattlesWon = userCharacter.totalBattlesWon.toUShort(), + totalBattlesLost = userCharacter.totalBattlesLost.toUShort(), + activityLevel = userCharacter.activityLevel.toByte(), + heartRateCurrent = userCharacter.heartRateCurrent.toUByte(), + transformationHistory = paddedTransformationArray, + vitalHistory = Array(7) { + NfcCharacter.DailyVitals(0u, 0u, 0u, 0u) + }, + appReserved1 = ByteArray(12) {0}, + appReserved2 = Array(3) {0u}, + generation = vbData.generation.toUShort(), + totalTrophies = vbData.totalTrophies.toUShort(), + specialMissions = watchSpecialMissions.toTypedArray() + ) + + return nfcData + } + + private suspend fun nfcToBENfc( + characterId: Long, + characterInfo: CharacterDtos.DiMInfo, + currentCardStage: Int, + userCharacter: UserCharacter + ): BENfcCharacter { + val beData = database + .userCharacterDao() + .getBeData(characterId) + + val paddedTransformationArray = generateTransformationHistory(characterId) + + val nfcData = BENfcCharacter( + dimId = characterInfo.cardId.toUShort(), + charIndex = characterInfo.charId.toUShort(), + stage = userCharacter.stage.toByte(), + attribute = userCharacter.attribute, + ageInDays = userCharacter.ageInDays.toByte(), + nextAdventureMissionStage = currentCardStage.toByte(), + mood = userCharacter.mood.toByte(), + vitalPoints = userCharacter.vitalPoints.toUShort(), + itemEffectMentalStateValue = beData.itemEffectMentalStateValue.toByte(), + itemEffectMentalStateMinutesRemaining = beData.itemEffectMentalStateMinutesRemaining.toByte(), + itemEffectActivityLevelValue = beData.itemEffectActivityLevelValue.toByte(), + itemEffectActivityLevelMinutesRemaining = beData.itemEffectActivityLevelMinutesRemaining.toByte(), + itemEffectVitalPointsChangeValue = beData.itemEffectVitalPointsChangeValue.toByte(), + itemEffectVitalPointsChangeMinutesRemaining = beData.itemEffectVitalPointsChangeMinutesRemaining.toByte(), + transformationCountdownInMinutes = userCharacter.transformationCountdown.toUShort(), + injuryStatus = userCharacter.injuryStatus, + trainingPp = userCharacter.trophies.toUShort(), + currentPhaseBattlesWon = userCharacter.currentPhaseBattlesWon.toUShort(), + currentPhaseBattlesLost = userCharacter.currentPhaseBattlesLost.toUShort(), + totalBattlesWon = userCharacter.totalBattlesWon.toUShort(), + totalBattlesLost = userCharacter.totalBattlesLost.toUShort(), + activityLevel = userCharacter.activityLevel.toByte(), + heartRateCurrent = userCharacter.heartRateCurrent.toUByte(), + transformationHistory = paddedTransformationArray, + vitalHistory = Array(7) { + NfcCharacter.DailyVitals(0u, 0u, 0u, 0u) + }, + appReserved1 = ByteArray(12) {0}, + appReserved2 = Array(3) {0u}, + trainingHp = beData.trainingHp.toUShort(), + trainingAp = beData.trainingAp.toUShort(), + trainingBp = beData.trainingBp.toUShort(), + remainingTrainingTimeInMinutes = beData.remainingTrainingTimeInMinutes.toUShort(), + abilityRarity = beData.abilityRarity, + abilityType = beData.abilityType.toUShort(), + abilityBranch = beData.abilityBranch.toUShort(), + abilityReset = beData.abilityReset.toByte(), + rank = beData.rank.toByte(), + itemType = beData.itemType.toByte(), + itemMultiplier = beData.itemMultiplier.toByte(), + itemRemainingTime = beData.itemRemainingTime.toByte(), + otp0 = byteArrayOf(8), + otp1 = byteArrayOf(8), + characterCreationFirmwareVersion = FirmwareVersion( + minorVersion = beData.minorVersion.toByte(), + majorVersion = beData.majorVersion.toByte() + ) + ) + + return nfcData + + } + + private suspend fun generateTransformationHistory( + characterId: Long + ): Array { + val transformationHistory = database + .userCharacterDao() + .getTransformationHistory(characterId)!! + .map { + val date = Date(it.transformationDate) + val calendar = android.icu.util.GregorianCalendar() + calendar.time = date + + NfcCharacter.Transformation( + toCharIndex = it.monIndex.toUByte(), + year = calendar + .get(Calendar.YEAR) + .toUShort(), + month = calendar + .get(Calendar.MONTH) + .toUByte(), + day = calendar + .get(Calendar.DAY_OF_MONTH) + .toUByte() + ) + }.toTypedArray() + + val paddedTransformationArray = padTransformationArray(transformationHistory) + + return paddedTransformationArray + } + + private fun padTransformationArray( + transformationArray: Array + ): Array { + if (transformationArray.size >= 8) { + return transformationArray + } + + val paddedArray = Array(8) { + NfcCharacter.Transformation( + toCharIndex = 255u, + year = 65535u, + month = 255u, + day = 255u + ) + } + + System.arraycopy(transformationArray, 0, paddedArray, 0, transformationArray.size) + return paddedArray + } +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt index a9c87cc..a45aeb8 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt @@ -115,10 +115,11 @@ class SettingsScreenControllerImpl( val card = dimReader.readCard(fileReader, false) val cardModel = Card( - dimId = card.header.dimId, + cardId = card.header.dimId, logo = card.spriteData.sprites[0].pixelData, - name = card.spriteData.text, // TODO Make user write card name// TODO Make user write card name + name = card.spriteData.text, // TODO Make user write card name stageCount = card.adventureLevels.levels.size, + currentStage = 0, logoHeight = card.spriteData.sprites[0].height, logoWidth = card.spriteData.sprites[0].width, isBEm = card is BemCard diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/utils/CharacterToNFCCharacter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/utils/CharacterToNFCCharacter.kt deleted file mode 100644 index 8abd9a1..0000000 --- a/app/src/main/java/com/github/nacabaro/vbhelper/utils/CharacterToNFCCharacter.kt +++ /dev/null @@ -1,99 +0,0 @@ -package com.github.nacabaro.vbhelper.utils - -import android.content.Context -import android.icu.util.Calendar -import android.icu.util.GregorianCalendar -import com.github.cfogrady.vbnfc.be.BENfcCharacter -import com.github.cfogrady.vbnfc.be.FirmwareVersion -import com.github.cfogrady.vbnfc.data.NfcCharacter -import com.github.nacabaro.vbhelper.di.VBHelper -import com.github.nacabaro.vbhelper.source.StorageRepository -import java.util.Date - -suspend fun characterToNfc(context: Context, characterId: Long): NfcCharacter? { - val app = context.applicationContext as VBHelper - val database = app.container.db - val storageRepository = StorageRepository(database) - val userCharacter = storageRepository.getSingleCharacter(characterId) - val characterInfo = storageRepository.getCharacterData(characterId) - - if (userCharacter.characterType == DeviceType.BEDevice) { - val beData = storageRepository.getCharacterBeData(characterId) - val transformationHistory = storageRepository - .getTransformationHistory(characterId)!! - .map { - val date = Date(it.transformationDate) - val calendar = GregorianCalendar() - calendar.time = date - - NfcCharacter.Transformation( - toCharIndex = it.monIndex.toUByte(), - year = calendar - .get(Calendar.YEAR) - .toUShort(), - month = calendar - .get(Calendar.MONTH) - .toUByte(), - day = calendar - .get(Calendar.DAY_OF_MONTH) - .toUByte() - ) - }.toTypedArray() - - val paddedTransformationArray = padTransformationArray(transformationHistory) - - val nfcData = BENfcCharacter( - dimId = characterInfo.cardId.toUShort(), - charIndex = characterInfo.charId.toUShort(), - stage = userCharacter.stage.toByte(), - attribute = userCharacter.attribute, - ageInDays = userCharacter.ageInDays.toByte(), - nextAdventureMissionStage = userCharacter.nextAdventureMissionStage.toByte(), - mood = userCharacter.mood.toByte(), - vitalPoints = userCharacter.vitalPoints.toUShort(), - itemEffectMentalStateValue = beData.itemEffectMentalStateValue.toByte(), - itemEffectMentalStateMinutesRemaining = beData.itemEffectMentalStateMinutesRemaining.toByte(), - itemEffectActivityLevelValue = beData.itemEffectActivityLevelValue.toByte(), - itemEffectActivityLevelMinutesRemaining = beData.itemEffectActivityLevelMinutesRemaining.toByte(), - itemEffectVitalPointsChangeValue = beData.itemEffectVitalPointsChangeValue.toByte(), - itemEffectVitalPointsChangeMinutesRemaining = beData.itemEffectVitalPointsChangeMinutesRemaining.toByte(), - transformationCountdownInMinutes = userCharacter.transformationCountdown.toUShort(), - injuryStatus = userCharacter.injuryStatus, - trainingPp = userCharacter.trophies.toUShort(), - currentPhaseBattlesWon = userCharacter.currentPhaseBattlesWon.toUShort(), - currentPhaseBattlesLost = userCharacter.currentPhaseBattlesLost.toUShort(), - totalBattlesWon = userCharacter.totalBattlesWon.toUShort(), - totalBattlesLost = userCharacter.totalBattlesLost.toUShort(), - activityLevel = userCharacter.activityLevel.toByte(), - heartRateCurrent = userCharacter.heartRateCurrent.toUByte(), - transformationHistory = paddedTransformationArray, - vitalHistory = Array(7) { - NfcCharacter.DailyVitals(0u, 0u, 0u, 0u) - }, - appReserved1 = ByteArray(12) {0}, - appReserved2 = Array(3) {0u}, - trainingHp = beData.trainingHp.toUShort(), - trainingAp = beData.trainingAp.toUShort(), - trainingBp = beData.trainingBp.toUShort(), - remainingTrainingTimeInMinutes = beData.remainingTrainingTimeInMinutes.toUShort(), - abilityRarity = beData.abilityRarity, - abilityType = beData.abilityType.toUShort(), - abilityBranch = beData.abilityBranch.toUShort(), - abilityReset = beData.abilityReset.toByte(), - rank = beData.rank.toByte(), - itemType = beData.itemType.toByte(), - itemMultiplier = beData.itemMultiplier.toByte(), - itemRemainingTime = beData.itemRemainingTime.toByte(), - otp0 = byteArrayOf(8), - otp1 = byteArrayOf(8), - characterCreationFirmwareVersion = FirmwareVersion( - minorVersion = beData.minorVersion.toByte(), - majorVersion = beData.majorVersion.toByte() - ) - ) - - return nfcData - } - - return null -} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/utils/padTransformationArray.kt b/app/src/main/java/com/github/nacabaro/vbhelper/utils/padTransformationArray.kt deleted file mode 100644 index ea879f5..0000000 --- a/app/src/main/java/com/github/nacabaro/vbhelper/utils/padTransformationArray.kt +++ /dev/null @@ -1,23 +0,0 @@ -package com.github.nacabaro.vbhelper.utils - -import com.github.cfogrady.vbnfc.data.NfcCharacter - -fun padTransformationArray( - transformationArray: Array -): Array { - if (transformationArray.size >= 8) { - return transformationArray - } - - val paddedArray = Array(8) { - NfcCharacter.Transformation( - toCharIndex = 255u, - year = 65535u, - month = 255u, - day = 255u - ) - } - - System.arraycopy(transformationArray, 0, paddedArray, 0, transformationArray.size) - return paddedArray -} \ No newline at end of file From 9f5f806786c9254eabbff38d08f62450eb51367a Mon Sep 17 00:00:00 2001 From: Nacho Date: Sun, 1 Jun 2025 18:51:30 +0200 Subject: [PATCH 2/4] Added basic stuff for compatibility with VB --- .../nacabaro/vbhelper/daos/CharacterDao.kt | 10 ++++++++ .../vbhelper/daos/UserCharacterDao.kt | 1 + .../domain/device_data/SpecialMissions.kt | 10 +++++++- .../domain/device_data/VitalsHistory.kt | 22 ++++++++++++++++ .../scanScreen/converters/FromNfcConverter.kt | 25 +++++++++++++++++++ 5 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt index 2d9fdfb..097f37a 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt @@ -42,4 +42,14 @@ interface CharacterDao { :transformationDate) """) fun insertTransformation(monId: Long, stage: Int, dimId: Long, transformationDate: Long) + + @Query(""" + INSERT INTO VitalsHistory(characterId, date, vitalPoints) + VALUES + (:characterId, + (:date), + :vitalPoints) + """) + fun insertVitals(characterId: Long, date: Long, vitalPoints: Int) + } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt index 4b95d2a..8fbe7a3 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt @@ -10,6 +10,7 @@ import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData +import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory import com.github.nacabaro.vbhelper.dtos.CharacterDtos @Dao diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/SpecialMissions.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/SpecialMissions.kt index 37f5664..13b092d 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/SpecialMissions.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/SpecialMissions.kt @@ -1,11 +1,19 @@ package com.github.nacabaro.vbhelper.domain.device_data import androidx.room.Entity +import androidx.room.ForeignKey import androidx.room.PrimaryKey import com.github.cfogrady.vbnfc.vb.SpecialMission @Entity( - + foreignKeys = [ + ForeignKey( + entity = UserCharacter::class, + parentColumns = ["id"], + childColumns = ["characterId"], + onDelete = ForeignKey.CASCADE + ) + ] ) data class SpecialMissions ( @PrimaryKey(autoGenerate = true) var id: Long = 0, diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt new file mode 100644 index 0000000..e59cf52 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt @@ -0,0 +1,22 @@ +package com.github.nacabaro.vbhelper.domain.device_data + +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.PrimaryKey + +@Entity( + foreignKeys = [ + ForeignKey( + entity = UserCharacter::class, + parentColumns = ["characterId"], + childColumns = ["id"], + onDelete = ForeignKey.CASCADE + ) + ] +) +data class VitalsHistory ( + @PrimaryKey(autoGenerate = true) val id: Long = 0, + val characterId: Long, + val date: Long, + val vitalPoints: Int +) \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt index 08fb68d..ba85216 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt @@ -10,6 +10,7 @@ import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData +import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory import com.github.nacabaro.vbhelper.utils.DeviceType import java.util.GregorianCalendar @@ -112,6 +113,9 @@ class FromNfcConverter ( ) } + val vitalsHistory = nfcCharacter.vitalHistory + + database .userCharacterDao() .insertVBCharacterData(extraCharacterData) @@ -153,6 +157,27 @@ class FromNfcConverter ( .insertBECharacterData(extraCharacterData) } + private fun addVitalsHistoryToDatabase(characterId: Long, nfcCharacter: NfcCharacter) { + val vitalsHistoryWatch = nfcCharacter.vitalHistory + vitalsHistoryWatch.map { item -> + val date = GregorianCalendar( + item.year.toInt(), + item.month.toInt(), + item.day.toInt() + ) + .time + .time + + database + .characterDao() + .insertVitals( + characterId, + date, + item.vitalsGained.toInt() + ) + } + } + private fun addTransformationHistoryToDatabase(characterId: Long, nfcCharacter: NfcCharacter, dimData: Card) { val transformationHistoryWatch = nfcCharacter.transformationHistory transformationHistoryWatch.map { item -> From d847f600f138c62d7c29e1c5957f47cec99f610b Mon Sep 17 00:00:00 2001 From: Nacho Date: Tue, 29 Jul 2025 02:50:15 +0200 Subject: [PATCH 3/4] Quite a few things - Renamed a few objects to avoid legality issues - Added a few accompanying tables to support the VB/VH - While we speak about tables, added an auxiliary table to track card adventure progress - Extracted NFC character generation and extraction to different classes, should result in a cleaner ScanScreenController --- .../github/nacabaro/vbhelper/daos/CardDao.kt | 16 +++ .../nacabaro/vbhelper/daos/CardProgressDao.kt | 17 +++ .../nacabaro/vbhelper/daos/CharacterDao.kt | 15 ++- .../github/nacabaro/vbhelper/daos/DiMDao.kt | 32 ----- .../nacabaro/vbhelper/daos/DiMProgressDao.kt | 11 -- .../nacabaro/vbhelper/database/AppDatabase.kt | 12 +- .../nacabaro/vbhelper/domain/DimProgress.kt | 29 ----- .../domain/{characters => card}/Card.kt | 3 +- .../vbhelper/domain/card/CardProgress.kt | 21 ++++ .../vbhelper/domain/characters/Character.kt | 3 +- .../domain/device_data/VitalsHistory.kt | 6 +- .../nacabaro/vbhelper/dtos/CharacterDtos.kt | 8 +- .../nacabaro/vbhelper/screens/DexScreen.kt | 1 - .../vbhelper/screens/scanScreen/ScanScreen.kt | 1 + .../scanScreen/ScanScreenController.kt | 1 + .../scanScreen/ScanScreenControllerImpl.kt | 31 +++-- .../scanScreen/converters/FromNfcConverter.kt | 112 +++++++++++++----- .../scanScreen/converters/ToNfcConverter.kt | 71 +++++++---- .../SettingsScreenControllerImpl.kt | 22 +++- .../nacabaro/vbhelper/source/DexRepository.kt | 1 - .../vbhelper/source/StorageRepository.kt | 6 +- 21 files changed, 254 insertions(+), 165 deletions(-) create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/daos/CardProgressDao.kt delete mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt delete mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMProgressDao.kt delete mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/domain/DimProgress.kt rename app/src/main/java/com/github/nacabaro/vbhelper/domain/{characters => card}/Card.kt (79%) create mode 100644 app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardProgress.kt diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt new file mode 100644 index 0000000..d9c1d3c --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt @@ -0,0 +1,16 @@ +package com.github.nacabaro.vbhelper.daos + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import com.github.nacabaro.vbhelper.domain.card.Card + +@Dao +interface CardDao { + @Insert(onConflict = OnConflictStrategy.IGNORE) + suspend fun insertNewDim(card: Card): Long + + @Query("SELECT * FROM Card WHERE cardId = :id") + fun getDimById(id: Int): Card? +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardProgressDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardProgressDao.kt new file mode 100644 index 0000000..788dc77 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardProgressDao.kt @@ -0,0 +1,17 @@ +package com.github.nacabaro.vbhelper.daos + +import androidx.room.Dao +import androidx.room.Query +import androidx.room.Upsert +import com.github.nacabaro.vbhelper.domain.card.CardProgress + +@Dao +interface CardProgressDao { + @Upsert + fun updateDimProgress(vararg cardProgresses: CardProgress) + + @Query( + "SELECT currentStage FROM CardProgress WHERE cardId = :cardId" + ) + fun getCardProgress(cardId: Int): Int +} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt index 7797078..a6f5993 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt @@ -18,21 +18,20 @@ interface CharacterDao { @Insert suspend fun insertSprite(vararg sprite: Sprite) - @Query("SELECT * FROM Sprite") - suspend fun getAllSprites(): List - @Query( """ SELECT d.cardId as cardId, - c.monIndex as charId + c.monIndex as charId, + c.stage as stage, + c.attribute as attribute FROM Character c JOIN UserCharacter uc ON c.id = uc.charId JOIN Card d ON c.dimId = d.id WHERE uc.id = :charId """ ) - suspend fun getCharacterInfo(charId: Long): CharacterDtos.DiMInfo + suspend fun getCharacterInfo(charId: Long): CharacterDtos.CardCharacterInfo @Query(""" INSERT INTO TransformationHistory(monId, stageId, transformationDate) @@ -44,12 +43,12 @@ interface CharacterDao { fun insertTransformation(monId: Long, stage: Int, dimId: Long, transformationDate: Long) @Query(""" - INSERT INTO VitalsHistory(characterId, date, vitalPoints) + INSERT INTO VitalsHistory(charId, date, vitalPoints) VALUES - (:characterId, + (:charId, (:date), :vitalPoints) """) - fun insertVitals(characterId: Long, date: Long, vitalPoints: Int) + fun insertVitals(charId: Long, date: Long, vitalPoints: Int) } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt deleted file mode 100644 index 9fee717..0000000 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.github.nacabaro.vbhelper.daos - -import androidx.room.Dao -import androidx.room.Insert -import androidx.room.OnConflictStrategy -import androidx.room.Query -import com.github.nacabaro.vbhelper.domain.characters.Card - -@Dao -interface DiMDao { - @Insert(onConflict = OnConflictStrategy.IGNORE) - suspend fun insertNewDim(card: Card): Long - - @Query("SELECT * FROM Card WHERE cardId = :id") - fun getDimById(id: Int): Card? - - @Query( - """ - UPDATE Card - SET currentStage = :currentStage - WHERE cardId = :id - """ - ) - fun updateCurrentStage(id: Int, currentStage: Int) - - @Query(""" - SELECT currentStage - FROM Card - WHERE cardId = :id - """) - fun getCurrentStage(id: Int): Int -} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMProgressDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMProgressDao.kt deleted file mode 100644 index 7f6c913..0000000 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMProgressDao.kt +++ /dev/null @@ -1,11 +0,0 @@ -package com.github.nacabaro.vbhelper.daos - -import androidx.room.Dao -import androidx.room.Upsert -import com.github.nacabaro.vbhelper.domain.DimProgress - -@Dao -interface DiMProgressDao { - @Upsert - suspend fun updateDimProgress(vararg dimProgress: DimProgress) -} \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt b/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt index d9900cd..1cd5dfe 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt @@ -5,12 +5,14 @@ import androidx.room.RoomDatabase import com.github.nacabaro.vbhelper.daos.AdventureDao import com.github.nacabaro.vbhelper.daos.CharacterDao import com.github.nacabaro.vbhelper.daos.DexDao -import com.github.nacabaro.vbhelper.daos.DiMDao +import com.github.nacabaro.vbhelper.daos.CardDao +import com.github.nacabaro.vbhelper.daos.CardProgressDao import com.github.nacabaro.vbhelper.daos.ItemDao import com.github.nacabaro.vbhelper.daos.SpriteDao import com.github.nacabaro.vbhelper.daos.UserCharacterDao import com.github.nacabaro.vbhelper.domain.characters.Character -import com.github.nacabaro.vbhelper.domain.characters.Card +import com.github.nacabaro.vbhelper.domain.card.Card +import com.github.nacabaro.vbhelper.domain.card.CardProgress import com.github.nacabaro.vbhelper.domain.characters.Sprite import com.github.nacabaro.vbhelper.domain.characters.Adventure import com.github.nacabaro.vbhelper.domain.characters.Dex @@ -19,12 +21,14 @@ import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions import com.github.nacabaro.vbhelper.domain.device_data.TransformationHistory import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData +import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory import com.github.nacabaro.vbhelper.domain.items.Items @Database( version = 1, entities = [ Card::class, + CardProgress::class, Character::class, Sprite::class, UserCharacter::class, @@ -32,13 +36,15 @@ import com.github.nacabaro.vbhelper.domain.items.Items VBCharacterData::class, SpecialMissions::class, TransformationHistory::class, + VitalsHistory::class, Dex::class, Items::class, Adventure::class ] ) abstract class AppDatabase : RoomDatabase() { - abstract fun dimDao(): DiMDao + abstract fun cardDao(): CardDao + abstract fun cardProgressDao(): CardProgressDao abstract fun characterDao(): CharacterDao abstract fun userCharacterDao(): UserCharacterDao abstract fun dexDao(): DexDao diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/DimProgress.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/DimProgress.kt deleted file mode 100644 index df9bbff..0000000 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/DimProgress.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.github.nacabaro.vbhelper.domain - -import androidx.room.Entity -import androidx.room.ForeignKey -import androidx.room.PrimaryKey -import com.github.nacabaro.vbhelper.domain.characters.Card - -@Entity( - foreignKeys = [ - ForeignKey( - entity = User::class, - parentColumns = ["id"], - childColumns = ["userId"], - onDelete = ForeignKey.CASCADE - ), - ForeignKey( - entity = Card::class, - parentColumns = ["id"], - childColumns = ["dimId"], - onDelete = ForeignKey.CASCADE - ) - ] -) -data class DimProgress( - @PrimaryKey val dimId: Int, - @PrimaryKey val userId: Int, - val currentStage: Int, - val unlocked: Boolean -) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Card.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/card/Card.kt similarity index 79% rename from app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Card.kt rename to app/src/main/java/com/github/nacabaro/vbhelper/domain/card/Card.kt index 536413f..87a2ba1 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Card.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/card/Card.kt @@ -1,4 +1,4 @@ -package com.github.nacabaro.vbhelper.domain.characters +package com.github.nacabaro.vbhelper.domain.card import androidx.room.Entity import androidx.room.PrimaryKey @@ -13,6 +13,5 @@ data class Card( val logoHeight: Int, val name: String, val stageCount: Int, - val currentStage: Int, val isBEm: Boolean ) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardProgress.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardProgress.kt new file mode 100644 index 0000000..d40aa93 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardProgress.kt @@ -0,0 +1,21 @@ +package com.github.nacabaro.vbhelper.domain.card + +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.PrimaryKey + +@Entity( + foreignKeys = [ + ForeignKey( + entity = Card::class, + parentColumns = ["id"], + childColumns = ["cardId"], + onDelete = ForeignKey.CASCADE + ) + ] +) +data class CardProgress( + @PrimaryKey val cardId: Int, + val currentStage: Int, + val unlocked: Boolean +) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Character.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Character.kt index b521edf..a514660 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Character.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/characters/Character.kt @@ -4,6 +4,7 @@ import androidx.room.Entity import androidx.room.PrimaryKey import androidx.room.ForeignKey import com.github.cfogrady.vbnfc.data.NfcCharacter +import com.github.nacabaro.vbhelper.domain.card.Card @Entity( foreignKeys = [ @@ -23,7 +24,7 @@ import com.github.cfogrady.vbnfc.data.NfcCharacter ) /* - * Character represents a character on a DIM card. There should only be one of these per dimId + * Character represents a character on a card. There should only be one of these per dimId * and monIndex. * TODO: Customs will mean this should be unique per cardName and monIndex */ diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt index e59cf52..a92a177 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt @@ -8,15 +8,15 @@ import androidx.room.PrimaryKey foreignKeys = [ ForeignKey( entity = UserCharacter::class, - parentColumns = ["characterId"], - childColumns = ["id"], + parentColumns = ["id"], + childColumns = ["charId"], onDelete = ForeignKey.CASCADE ) ] ) data class VitalsHistory ( @PrimaryKey(autoGenerate = true) val id: Long = 0, - val characterId: Long, + val charId: Long, val date: Long, val vitalPoints: Int ) \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt b/app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt index 435bc61..b89fab0 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/dtos/CharacterDtos.kt @@ -11,7 +11,6 @@ object CharacterDtos { var stage: Int, var attribute: NfcCharacter.Attribute, var ageInDays: Int, - var nextAdventureMissionStage: Int, // next adventure mission stage on the character's dim var mood: Int, var vitalPoints: Int, var transformationCountdown: Int, @@ -35,9 +34,11 @@ object CharacterDtos { val isInAdventure: Boolean ) - data class DiMInfo( + data class CardCharacterInfo( val cardId: Int, - val charId: Int + val charId: Int, + val stage: Int, + val attribute: NfcCharacter.Attribute ) data class TransformationHistory( @@ -63,7 +64,6 @@ object CharacterDtos { var stage: Int, var attribute: NfcCharacter.Attribute, var ageInDays: Int, - var nextAdventureMissionStage: Int, // next adventure mission stage on the character's dim var mood: Int, var vitalPoints: Int, var transformationCountdown: Int, diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt index bec0a25..6a99b4f 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/DexScreen.kt @@ -18,7 +18,6 @@ import com.github.nacabaro.vbhelper.utils.BitmapData import com.github.nacabaro.vbhelper.components.DexDiMEntry import com.github.nacabaro.vbhelper.components.TopBanner import com.github.nacabaro.vbhelper.di.VBHelper -import com.github.nacabaro.vbhelper.domain.characters.Card import com.github.nacabaro.vbhelper.dtos.CardDtos import com.github.nacabaro.vbhelper.navigation.NavigationItems import com.github.nacabaro.vbhelper.source.DexRepository diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt index 5dabac5..58add74 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt @@ -283,6 +283,7 @@ fun ScanScreenPreview() { override fun onClickCheckCard(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {} override fun onClickWrite(secrets: Secrets, nfcCharacter: NfcCharacter, onComplete: () -> Unit) {} override fun cancelRead() {} + override fun characterFromNfc(nfcCharacter: NfcCharacter): String { return "" } override suspend fun characterToNfc(characterId: Long): NfcCharacter? { return null } }, characterId = null diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt index f52426e..72032cf 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenController.kt @@ -16,5 +16,6 @@ interface ScanScreenController { fun registerActivityLifecycleListener(key: String, activityLifecycleListener: ActivityLifecycleListener) fun unregisterActivityLifecycleListener(key: String) + fun characterFromNfc(nfcCharacter: NfcCharacter): String suspend fun characterToNfc(characterId: Long): NfcCharacter? } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt index 43638e9..ed951eb 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt @@ -11,22 +11,17 @@ import android.widget.Toast import androidx.activity.ComponentActivity import androidx.lifecycle.lifecycleScope import com.github.cfogrady.vbnfc.TagCommunicator -import com.github.cfogrady.vbnfc.be.BENfcCharacter import com.github.cfogrady.vbnfc.data.NfcCharacter -import com.github.cfogrady.vbnfc.vb.VBNfcCharacter import com.github.nacabaro.vbhelper.ActivityLifecycleListener -import com.github.nacabaro.vbhelper.di.VBHelper -import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData -import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter +import com.github.nacabaro.vbhelper.screens.scanScreen.converters.FromNfcConverter +import com.github.nacabaro.vbhelper.screens.scanScreen.converters.ToNfcConverter import com.github.nacabaro.vbhelper.source.getCryptographicTransformerMap import com.github.nacabaro.vbhelper.source.isMissingSecrets import com.github.nacabaro.vbhelper.source.proto.Secrets -import com.github.nacabaro.vbhelper.utils.DeviceType import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch -import java.util.GregorianCalendar class ScanScreenControllerImpl( override val secretsFlow: Flow, @@ -49,7 +44,7 @@ class ScanScreenControllerImpl( override fun onClickRead(secrets: Secrets, onComplete: ()->Unit) { handleTag(secrets) { tagCommunicator -> val character = tagCommunicator.receiveCharacter() - val resultMessage = addCharacterScannedIntoDatabase(character) + val resultMessage = characterFromNfc(character) onComplete.invoke() resultMessage } @@ -151,6 +146,11 @@ class ScanScreenControllerImpl( componentActivity.startActivity(Intent(Settings.ACTION_WIRELESS_SETTINGS)) } + /* + // Todo: Move all of this to a separate class + // Todo: Test the new mess + // Todo: Remove this + private fun addCharacterScannedIntoDatabase(nfcCharacter: NfcCharacter): String { val application = componentActivity.applicationContext as VBHelper val storageRepository = application.container.db @@ -168,7 +168,6 @@ class ScanScreenControllerImpl( val characterData = UserCharacter( charId = cardCharData.id, ageInDays = nfcCharacter.ageInDays.toInt(), - nextAdventureMissionStage = nfcCharacter.nextAdventureMissionStage.toInt(), mood = nfcCharacter.mood.toInt(), vitalPoints = nfcCharacter.vitalPoints.toInt(), transformationCountdown = nfcCharacter.transformationCountdownInMinutes.toInt(), @@ -247,5 +246,19 @@ class ScanScreenControllerImpl( } return "Done reading character!" + }*/ + + override fun characterFromNfc(nfcCharacter: NfcCharacter): String { + val nfcConverter = FromNfcConverter( + componentActivity = componentActivity + ) + return nfcConverter.addCharacter(nfcCharacter) + } + + override suspend fun characterToNfc(characterId: Long): NfcCharacter { + val nfcGenerator = ToNfcConverter( + componentActivity = componentActivity + ) + return nfcGenerator.characterToNfc(characterId) } } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt index ba85216..09d41d0 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt @@ -5,12 +5,12 @@ import com.github.cfogrady.vbnfc.be.BENfcCharacter import com.github.cfogrady.vbnfc.data.NfcCharacter import com.github.cfogrady.vbnfc.vb.VBNfcCharacter import com.github.nacabaro.vbhelper.di.VBHelper -import com.github.nacabaro.vbhelper.domain.characters.Card +import com.github.nacabaro.vbhelper.domain.card.Card +import com.github.nacabaro.vbhelper.domain.card.CardProgress import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData -import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory import com.github.nacabaro.vbhelper.utils.DeviceType import java.util.GregorianCalendar @@ -20,29 +20,24 @@ class FromNfcConverter ( private val application = componentActivity.applicationContext as VBHelper private val database = application.container.db + + fun addCharacter(nfcCharacter: NfcCharacter): String { - val dimData = database - .dimDao() + val cardData = database + .cardDao() .getDimById(nfcCharacter.dimId.toInt()) - if (dimData == null) + if (cardData == null) return "Card not found" val cardCharData = database .characterDao() - .getCharacterByMonIndex(nfcCharacter.charIndex.toInt(), dimData.id) + .getCharacterByMonIndex(nfcCharacter.charIndex.toInt(), cardData.id) - database - .dimDao() - .updateCurrentStage( - id = nfcCharacter.dimId.toInt(), - currentStage = nfcCharacter.nextAdventureMissionStage.toInt() - ) + updateCardProgress(nfcCharacter, cardData) val characterData = UserCharacter( charId = cardCharData.id, - stage = nfcCharacter.stage.toInt(), - attribute = nfcCharacter.attribute, ageInDays = nfcCharacter.ageInDays.toInt(), mood = nfcCharacter.mood.toInt(), vitalPoints = nfcCharacter.vitalPoints.toInt(), @@ -62,6 +57,8 @@ class FromNfcConverter ( isActive = true ) + updateCardProgress(cardData, nfcCharacter) + database .userCharacterDao() .clearActiveCharacter() @@ -85,20 +82,73 @@ class FromNfcConverter ( addTransformationHistoryToDatabase( characterId = characterId, nfcCharacter = nfcCharacter, - dimData = dimData + dimData = cardData ) return "Done reading character!" - } - private fun addVbCharacterToDatabase(characterId: Long, nfcCharacter: VBNfcCharacter) { + + + private fun updateCardProgress( + nfcCharacter: NfcCharacter, + cardData: Card + ) { + val currentCardProgress = CardProgress( + cardId = cardData.cardId, + currentStage = nfcCharacter.nextAdventureMissionStage.toInt(), + unlocked = nfcCharacter.nextAdventureMissionStage.toInt() > cardData.stageCount + ) + + database + .cardProgressDao() + .updateDimProgress(currentCardProgress) + } + + + + private fun updateCardProgress( + cardData: Card, + nfcCharacter: NfcCharacter, + ) { + val cardProgress = CardProgress( + cardId = cardData.cardId, + currentStage = nfcCharacter.nextAdventureMissionStage.toInt(), + unlocked = nfcCharacter.nextAdventureMissionStage.toInt() > cardData.stageCount + ) + + database + .cardProgressDao() + .updateDimProgress(cardProgress) + } + + + + private fun addVbCharacterToDatabase( + characterId: Long, + nfcCharacter: VBNfcCharacter + ) { val extraCharacterData = VBCharacterData( id = characterId, generation = nfcCharacter.generation.toInt(), totalTrophies = nfcCharacter.totalTrophies.toInt() ) + database + .userCharacterDao() + .insertVBCharacterData(extraCharacterData) + + addSpecialMissionsToDatabase(nfcCharacter, characterId) + + addVitalsHistoryToDatabase(characterId, nfcCharacter) + } + + + + private fun addSpecialMissionsToDatabase( + nfcCharacter: VBNfcCharacter, + characterId: Long + ) { val specialMissionsWatch = nfcCharacter.specialMissions val specialMissionsDb = specialMissionsWatch.map { item -> SpecialMissions( @@ -113,19 +163,17 @@ class FromNfcConverter ( ) } - val vitalsHistory = nfcCharacter.vitalHistory - - - database - .userCharacterDao() - .insertVBCharacterData(extraCharacterData) - database .userCharacterDao() .insertSpecialMissions(*specialMissionsDb.toTypedArray()) } - private fun addBeCharacterToDatabase(characterId: Long, nfcCharacter: BENfcCharacter) { + + + private fun addBeCharacterToDatabase( + characterId: Long, + nfcCharacter: BENfcCharacter + ) { val extraCharacterData = BECharacterData( id = characterId, trainingHp = nfcCharacter.trainingHp.toInt(), @@ -157,7 +205,12 @@ class FromNfcConverter ( .insertBECharacterData(extraCharacterData) } - private fun addVitalsHistoryToDatabase(characterId: Long, nfcCharacter: NfcCharacter) { + + + private fun addVitalsHistoryToDatabase( + characterId: Long, + nfcCharacter: NfcCharacter + ) { val vitalsHistoryWatch = nfcCharacter.vitalHistory vitalsHistoryWatch.map { item -> val date = GregorianCalendar( @@ -178,7 +231,12 @@ class FromNfcConverter ( } } - private fun addTransformationHistoryToDatabase(characterId: Long, nfcCharacter: NfcCharacter, dimData: Card) { + + private fun addTransformationHistoryToDatabase( + characterId: Long, + nfcCharacter: NfcCharacter, + dimData: Card + ) { val transformationHistoryWatch = nfcCharacter.transformationHistory transformationHistoryWatch.map { item -> if (item.toCharIndex.toInt() != 255) { diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt index 8ad9228..9227869 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt @@ -20,7 +20,11 @@ class ToNfcConverter( private val application: VBHelper = componentActivity.applicationContext as VBHelper private val database: AppDatabase = application.container.db - suspend fun characterToNfc(characterId: Long): NfcCharacter { + + + suspend fun characterToNfc( + characterId: Long + ): NfcCharacter { val app = componentActivity.applicationContext as VBHelper val database = app.container.db @@ -32,7 +36,9 @@ class ToNfcConverter( .characterDao() .getCharacterInfo(userCharacter.charId) - val currentCardStage = database.dimDao().getCurrentStage(characterInfo.cardId) + val currentCardStage = database + .cardProgressDao() + .getCardProgress(characterInfo.cardId) return if (userCharacter.characterType == DeviceType.BEDevice) nfcToBENfc(characterId, characterInfo, currentCardStage, userCharacter) @@ -40,9 +46,11 @@ class ToNfcConverter( nfcToVBNfc(characterId, characterInfo, currentCardStage, userCharacter) } + + private suspend fun nfcToVBNfc( characterId: Long, - characterInfo: CharacterDtos.DiMInfo, + characterInfo: CharacterDtos.CardCharacterInfo, currentCardStage: Int, userCharacter: UserCharacter ): VBNfcCharacter { @@ -50,29 +58,15 @@ class ToNfcConverter( .userCharacterDao() .getVbData(characterId) - val specialMissions = database - .userCharacterDao() - .getSpecialMissions(characterId) - val paddedTransformationArray = generateTransformationHistory(characterId) - val watchSpecialMissions = specialMissions.map { - SpecialMission( - goal = it.goal.toUShort(), - id = it.watchId.toUShort(), - progress = it.progress.toUShort(), - status = it.status, - timeElapsedInMinutes = it.timeElapsedInMinutes.toUShort(), - timeLimitInMinutes = it.timeLimitInMinutes.toUShort(), - type = it.missionType - ) - } + val watchSpecialMissions = generateSpecialMissionsArray(characterId) val nfcData = VBNfcCharacter( dimId = characterInfo.cardId.toUShort(), charIndex = characterInfo.charId.toUShort(), - stage = userCharacter.stage.toByte(), - attribute = userCharacter.attribute, + stage = characterInfo.stage.toByte(), + attribute = characterInfo.attribute, ageInDays = userCharacter.ageInDays.toByte(), nextAdventureMissionStage = currentCardStage.toByte(), mood = userCharacter.mood.toByte(), @@ -100,9 +94,35 @@ class ToNfcConverter( return nfcData } + + + private suspend fun generateSpecialMissionsArray( + characterId: Long + ): List { + val specialMissions = database + .userCharacterDao() + .getSpecialMissions(characterId) + + val watchSpecialMissions = specialMissions.map { + SpecialMission( + goal = it.goal.toUShort(), + id = it.watchId.toUShort(), + progress = it.progress.toUShort(), + status = it.status, + timeElapsedInMinutes = it.timeElapsedInMinutes.toUShort(), + timeLimitInMinutes = it.timeLimitInMinutes.toUShort(), + type = it.missionType + ) + } + + return watchSpecialMissions + } + + + private suspend fun nfcToBENfc( characterId: Long, - characterInfo: CharacterDtos.DiMInfo, + characterInfo: CharacterDtos.CardCharacterInfo, currentCardStage: Int, userCharacter: UserCharacter ): BENfcCharacter { @@ -115,8 +135,8 @@ class ToNfcConverter( val nfcData = BENfcCharacter( dimId = characterInfo.cardId.toUShort(), charIndex = characterInfo.charId.toUShort(), - stage = userCharacter.stage.toByte(), - attribute = userCharacter.attribute, + stage = characterInfo.stage.toByte(), + attribute = characterInfo.attribute, ageInDays = userCharacter.ageInDays.toByte(), nextAdventureMissionStage = currentCardStage.toByte(), mood = userCharacter.mood.toByte(), @@ -163,9 +183,10 @@ class ToNfcConverter( ) return nfcData - } + + private suspend fun generateTransformationHistory( characterId: Long ): Array { @@ -196,6 +217,8 @@ class ToNfcConverter( return paddedTransformationArray } + + private fun padTransformationArray( transformationArray: Array ): Array { diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt index a4ccde3..b81a198 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt @@ -16,7 +16,8 @@ import com.github.cfogrady.vbnfc.data.NfcCharacter import com.github.nacabaro.vbhelper.database.AppDatabase import com.github.nacabaro.vbhelper.di.VBHelper import com.github.nacabaro.vbhelper.domain.characters.Sprite -import com.github.nacabaro.vbhelper.domain.characters.Card +import com.github.nacabaro.vbhelper.domain.card.Card +import com.github.nacabaro.vbhelper.domain.card.CardProgress import com.github.nacabaro.vbhelper.domain.characters.Character import com.github.nacabaro.vbhelper.source.ApkSecretsImporter import com.github.nacabaro.vbhelper.source.SecretsImporter @@ -121,17 +122,28 @@ class SettingsScreenControllerImpl( logo = card.spriteData.sprites[0].pixelData, name = card.spriteData.text, // TODO Make user write card name stageCount = card.adventureLevels.levels.size, - currentStage = 0, logoHeight = card.spriteData.sprites[0].height, logoWidth = card.spriteData.sprites[0].width, isBEm = card is BemCard ) val dimId = database - .dimDao() + .cardDao() .insertNewDim(cardModel) - val characters = card.characterStats.characterEntries + val cardProgress = CardProgress( + cardId = cardModel.cardId, + currentStage = 0, + unlocked = false + ) + + database + .cardProgressDao() + .updateDimProgress(cardProgress) + + val characters = card + .characterStats + .characterEntries var spriteCounter = when (card is BemCard) { true -> 54 @@ -141,7 +153,7 @@ class SettingsScreenControllerImpl( val domainCharacters = mutableListOf() for (index in 0 until characters.size) { - var domainSprite: Sprite? = null; + var domainSprite: Sprite? if (index < 2 && card is DimCard) { domainSprite = Sprite( diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/source/DexRepository.kt b/app/src/main/java/com/github/nacabaro/vbhelper/source/DexRepository.kt index 6105620..e2df631 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/source/DexRepository.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/source/DexRepository.kt @@ -1,7 +1,6 @@ package com.github.nacabaro.vbhelper.source import com.github.nacabaro.vbhelper.database.AppDatabase -import com.github.nacabaro.vbhelper.domain.characters.Card import com.github.nacabaro.vbhelper.dtos.CardDtos import com.github.nacabaro.vbhelper.dtos.CharacterDtos diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt b/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt index d463d06..d4caee8 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/source/StorageRepository.kt @@ -19,14 +19,10 @@ class StorageRepository ( return db.userCharacterDao().getBeData(id) } - fun getTransformationHistory(characterId: Long): List? { + suspend fun getTransformationHistory(characterId: Long): List? { return db.userCharacterDao().getTransformationHistory(characterId) } - suspend fun getCharacterData(id: Long): CharacterDtos.DiMInfo { - return db.characterDao().getCharacterInfo(id) - } - suspend fun getActiveCharacter(): CharacterDtos.CharacterWithSprites? { return db.userCharacterDao().getActiveCharacter() } From 220a61a55357452564342fee51f9f192646a41e8 Mon Sep 17 00:00:00 2001 From: Nacho Date: Tue, 29 Jul 2025 10:36:07 +0200 Subject: [PATCH 4/4] Bug fixes - Fixed an issue with the calendar, now I store the date as year/month/day in the database directly. - VB expects to have a year between 2021 and 2032, for some reason it gives me back a 2000 year when reading an empty history. I just patched it in the application to return as year 0 in those cases. - VitalsHistory works as intended now. Also verified functionality of the new classes. - Moved a few SQL queries too, since they didn't belong where they were. Also added a small feature, now the application knows if you entered the scan screen through a character in the storage, or the home screen. If there is an active character and you opened the home screen, the application will let you send the active character, while if it was opened through the storage screen, the application will send the character from the storage screen. What's now missing is to create a VBSCanScreen, and depending on which device we are using, make use of one screen or the other. --- .../nacabaro/vbhelper/daos/CharacterDao.kt | 21 +--- .../vbhelper/daos/UserCharacterDao.kt | 16 +++ .../vbhelper/domain/card/CardProgress.kt | 2 +- .../domain/device_data/VitalsHistory.kt | 4 +- .../vbhelper/screens/scanScreen/ScanScreen.kt | 46 ++++++-- .../scanScreen/ScanScreenControllerImpl.kt | 102 ------------------ .../scanScreen/converters/FromNfcConverter.kt | 59 ++++------ .../scanScreen/converters/ToNfcConverter.kt | 42 ++++++-- .../SettingsScreenControllerImpl.kt | 2 +- 9 files changed, 114 insertions(+), 180 deletions(-) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt index a6f5993..172f303 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CharacterDao.kt @@ -28,27 +28,8 @@ interface CharacterDao { FROM Character c JOIN UserCharacter uc ON c.id = uc.charId JOIN Card d ON c.dimId = d.id - WHERE uc.id = :charId + WHERE c.id = :charId """ ) suspend fun getCharacterInfo(charId: Long): CharacterDtos.CardCharacterInfo - - @Query(""" - INSERT INTO TransformationHistory(monId, stageId, transformationDate) - VALUES - (:monId, - (SELECT id FROM Character WHERE monIndex = :stage AND dimId = :dimId), - :transformationDate) - """) - fun insertTransformation(monId: Long, stage: Int, dimId: Long, transformationDate: Long) - - @Query(""" - INSERT INTO VitalsHistory(charId, date, vitalPoints) - VALUES - (:charId, - (:date), - :vitalPoints) - """) - fun insertVitals(charId: Long, date: Long, vitalPoints: Int) - } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt index af0e849..39d43ee 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt @@ -156,4 +156,20 @@ interface UserCharacterDao { """ ) suspend fun getCharacterInfo(charId: Long): Character + + + @Query(""" + INSERT INTO TransformationHistory(monId, stageId, transformationDate) + VALUES + (:monId, + (SELECT id FROM Character WHERE monIndex = :stage AND dimId = :dimId), + :transformationDate) + """) + fun insertTransformation(monId: Long, stage: Int, dimId: Long, transformationDate: Long) + + @Upsert + fun insertVitals(vararg vitalsHistory: VitalsHistory) + + @Query("""SELECT * FROM VitalsHistory WHERE charId = :charId ORDER BY id ASC""") + suspend fun getVitalsHistory(charId: Long): List } \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardProgress.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardProgress.kt index d40aa93..9ec48f2 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardProgress.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/card/CardProgress.kt @@ -15,7 +15,7 @@ import androidx.room.PrimaryKey ] ) data class CardProgress( - @PrimaryKey val cardId: Int, + @PrimaryKey val cardId: Long, val currentStage: Int, val unlocked: Boolean ) diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt index a92a177..313e7c1 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt @@ -17,6 +17,8 @@ import androidx.room.PrimaryKey data class VitalsHistory ( @PrimaryKey(autoGenerate = true) val id: Long = 0, val charId: Long, - val date: Long, + val year: Int, + val month: Int, + val day: Int, val vitalPoints: Int ) \ No newline at end of file diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt index 58add74..da6b07d 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreen.kt @@ -57,11 +57,33 @@ fun ScanScreen( val storageRepository = StorageRepository(application.container.db) var nfcCharacter by remember { mutableStateOf(null) } + /* + This is in the case there is an active character, + that way active characters are quicker to send. + */ + var selectedCharacterId by remember { mutableStateOf(null) } + selectedCharacterId = characterId + val context = LocalContext.current + LaunchedEffect(storageRepository) { withContext(Dispatchers.IO) { - if(characterId != null && nfcCharacter == null) { - nfcCharacter = scanScreenController.characterToNfc(characterId) + /* + First check if there is a character sent through the navigation system + If there is not, that means we got here through the home screen nfc button + If we got here through the home screen, it does not hurt to check if there is + an active character. + */ + if (characterId != null && nfcCharacter == null) { + selectedCharacterId = characterId + nfcCharacter = scanScreenController.characterToNfc(selectedCharacterId!!) + } + else if (characterId == null && nfcCharacter == null) { + val activeCharacter = storageRepository.getActiveCharacter() + if (activeCharacter != null) { + selectedCharacterId = activeCharacter.id + nfcCharacter = scanScreenController.characterToNfc(selectedCharacterId!!) + } } } } @@ -120,13 +142,15 @@ fun ScanScreen( ) } - if (!isDoneSendingCard) { - scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) { - isDoneSendingCard = true - } - } else if (!isDoneWritingCharacter) { - scanScreenController.onClickWrite(secrets!!, nfcCharacter!!) { - isDoneWritingCharacter = true + if (secrets != null && nfcCharacter != null) { + if (!isDoneSendingCard) { + scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) { + isDoneSendingCard = true + } + } else if (!isDoneWritingCharacter) { + scanScreenController.onClickWrite(secrets!!, nfcCharacter!!) { + isDoneWritingCharacter = true + } } } @@ -147,7 +171,7 @@ fun ScanScreen( LaunchedEffect(storageRepository) { withContext(Dispatchers.IO) { storageRepository - .deleteCharacter(characterId!!) + .deleteCharacter(selectedCharacterId!!) } } } @@ -173,7 +197,7 @@ fun ScanScreen( } else { ChooseConnectOption( onClickRead = when { - characterId != null -> null + selectedCharacterId != null -> null else -> { { if(secrets == null) { diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt index ed951eb..f610f5f 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/ScanScreenControllerImpl.kt @@ -146,108 +146,6 @@ class ScanScreenControllerImpl( componentActivity.startActivity(Intent(Settings.ACTION_WIRELESS_SETTINGS)) } - /* - // Todo: Move all of this to a separate class - // Todo: Test the new mess - // Todo: Remove this - - private fun addCharacterScannedIntoDatabase(nfcCharacter: NfcCharacter): String { - val application = componentActivity.applicationContext as VBHelper - val storageRepository = application.container.db - - val dimData = storageRepository - .dimDao() - .getDimById(nfcCharacter.dimId.toInt()) - - if (dimData == null) return "Card not found" - - val cardCharData = storageRepository - .characterDao() - .getCharacterByMonIndex(nfcCharacter.charIndex.toInt(), dimData.id) - - val characterData = UserCharacter( - charId = cardCharData.id, - ageInDays = nfcCharacter.ageInDays.toInt(), - mood = nfcCharacter.mood.toInt(), - vitalPoints = nfcCharacter.vitalPoints.toInt(), - transformationCountdown = nfcCharacter.transformationCountdownInMinutes.toInt(), - injuryStatus = nfcCharacter.injuryStatus, - trophies = nfcCharacter.trophies.toInt(), - currentPhaseBattlesWon = nfcCharacter.currentPhaseBattlesWon.toInt(), - currentPhaseBattlesLost = nfcCharacter.currentPhaseBattlesLost.toInt(), - totalBattlesWon = nfcCharacter.totalBattlesWon.toInt(), - totalBattlesLost = nfcCharacter.totalBattlesLost.toInt(), - activityLevel = nfcCharacter.activityLevel.toInt(), - heartRateCurrent = nfcCharacter.heartRateCurrent.toInt(), - characterType = when (nfcCharacter) { - is BENfcCharacter -> DeviceType.BEDevice - else -> DeviceType.VBDevice - }, - isActive = true - ) - - storageRepository - .userCharacterDao() - .clearActiveCharacter() - - val characterId: Long = storageRepository - .userCharacterDao() - .insertCharacterData(characterData) - - if (nfcCharacter is BENfcCharacter) { - val extraCharacterData = BECharacterData( - id = characterId, - trainingHp = nfcCharacter.trainingHp.toInt(), - trainingAp = nfcCharacter.trainingAp.toInt(), - trainingBp = nfcCharacter.trainingBp.toInt(), - remainingTrainingTimeInMinutes = nfcCharacter.remainingTrainingTimeInMinutes.toInt(), - itemEffectActivityLevelValue = nfcCharacter.itemEffectActivityLevelValue.toInt(), - itemEffectMentalStateValue = nfcCharacter.itemEffectMentalStateValue.toInt(), - itemEffectMentalStateMinutesRemaining = nfcCharacter.itemEffectMentalStateMinutesRemaining.toInt(), - itemEffectActivityLevelMinutesRemaining = nfcCharacter.itemEffectActivityLevelMinutesRemaining.toInt(), - itemEffectVitalPointsChangeValue = nfcCharacter.itemEffectVitalPointsChangeValue.toInt(), - itemEffectVitalPointsChangeMinutesRemaining = nfcCharacter.itemEffectVitalPointsChangeMinutesRemaining.toInt(), - abilityRarity = nfcCharacter.abilityRarity, - abilityType = nfcCharacter.abilityType.toInt(), - abilityBranch = nfcCharacter.abilityBranch.toInt(), - abilityReset = nfcCharacter.abilityReset.toInt(), - rank = nfcCharacter.abilityReset.toInt(), - itemType = nfcCharacter.itemType.toInt(), - itemMultiplier = nfcCharacter.itemMultiplier.toInt(), - itemRemainingTime = nfcCharacter.itemRemainingTime.toInt(), - otp0 = "", //nfcCharacter.value!!.otp0.toString(), - otp1 = "", //nfcCharacter.value!!.otp1.toString(), - minorVersion = nfcCharacter.characterCreationFirmwareVersion.minorVersion.toInt(), - majorVersion = nfcCharacter.characterCreationFirmwareVersion.majorVersion.toInt(), - ) - - storageRepository - .userCharacterDao() - .insertBECharacterData(extraCharacterData) - - val transformationHistoryWatch = nfcCharacter.transformationHistory - transformationHistoryWatch.map { item -> - if (item.toCharIndex.toInt() != 255) { - val date = GregorianCalendar(item.year.toInt(), item.month.toInt(), item.day.toInt()) - .time - .time - - storageRepository - .characterDao() - .insertTransformation(characterId, item.toCharIndex.toInt(), dimData.id, date) - - storageRepository - .dexDao() - .insertCharacter(item.toCharIndex.toInt(), dimData.id, date) - } - } - } else if (nfcCharacter is VBNfcCharacter) { - return "Not implemented yet" - } - - return "Done reading character!" - }*/ - override fun characterFromNfc(nfcCharacter: NfcCharacter): String { val nfcConverter = FromNfcConverter( componentActivity = componentActivity diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt index 09d41d0..459afbc 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt @@ -1,5 +1,6 @@ package com.github.nacabaro.vbhelper.screens.scanScreen.converters +import android.util.Log import androidx.activity.ComponentActivity import com.github.cfogrady.vbnfc.be.BENfcCharacter import com.github.cfogrady.vbnfc.data.NfcCharacter @@ -11,6 +12,7 @@ import com.github.nacabaro.vbhelper.domain.device_data.BECharacterData import com.github.nacabaro.vbhelper.domain.device_data.SpecialMissions import com.github.nacabaro.vbhelper.domain.device_data.UserCharacter import com.github.nacabaro.vbhelper.domain.device_data.VBCharacterData +import com.github.nacabaro.vbhelper.domain.device_data.VitalsHistory import com.github.nacabaro.vbhelper.utils.DeviceType import java.util.GregorianCalendar @@ -57,8 +59,6 @@ class FromNfcConverter ( isActive = true ) - updateCardProgress(cardData, nfcCharacter) - database .userCharacterDao() .clearActiveCharacter() @@ -85,6 +85,11 @@ class FromNfcConverter ( dimData = cardData ) + addVitalsHistoryToDatabase( + characterId = characterId, + nfcCharacter = nfcCharacter + ) + return "Done reading character!" } @@ -95,7 +100,7 @@ class FromNfcConverter ( cardData: Card ) { val currentCardProgress = CardProgress( - cardId = cardData.cardId, + cardId = cardData.id, currentStage = nfcCharacter.nextAdventureMissionStage.toInt(), unlocked = nfcCharacter.nextAdventureMissionStage.toInt() > cardData.stageCount ) @@ -107,23 +112,6 @@ class FromNfcConverter ( - private fun updateCardProgress( - cardData: Card, - nfcCharacter: NfcCharacter, - ) { - val cardProgress = CardProgress( - cardId = cardData.cardId, - currentStage = nfcCharacter.nextAdventureMissionStage.toInt(), - unlocked = nfcCharacter.nextAdventureMissionStage.toInt() > cardData.stageCount - ) - - database - .cardProgressDao() - .updateDimProgress(cardProgress) - } - - - private fun addVbCharacterToDatabase( characterId: Long, nfcCharacter: VBNfcCharacter @@ -139,8 +127,6 @@ class FromNfcConverter ( .insertVBCharacterData(extraCharacterData) addSpecialMissionsToDatabase(nfcCharacter, characterId) - - addVitalsHistoryToDatabase(characterId, nfcCharacter) } @@ -212,23 +198,20 @@ class FromNfcConverter ( nfcCharacter: NfcCharacter ) { val vitalsHistoryWatch = nfcCharacter.vitalHistory - vitalsHistoryWatch.map { item -> - val date = GregorianCalendar( - item.year.toInt(), - item.month.toInt(), - item.day.toInt() + val vitalsHistory = vitalsHistoryWatch.map { historyElement -> + Log.d("VitalsHistory", "${historyElement.year.toInt()} ${historyElement.month.toInt()} ${historyElement.day.toInt()}") + VitalsHistory( + charId = characterId, + year = historyElement.year.toInt(), + month = historyElement.month.toInt(), + day = historyElement.day.toInt(), + vitalPoints = historyElement.vitalsGained.toInt() ) - .time - .time - - database - .characterDao() - .insertVitals( - characterId, - date, - item.vitalsGained.toInt() - ) } + + database + .userCharacterDao() + .insertVitals(*vitalsHistory.toTypedArray()) } @@ -249,7 +232,7 @@ class FromNfcConverter ( .time database - .characterDao() + .userCharacterDao() .insertTransformation( characterId, item.toCharIndex.toInt(), diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt index 9227869..819aa2a 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt @@ -1,6 +1,7 @@ package com.github.nacabaro.vbhelper.screens.scanScreen.converters import android.icu.util.Calendar +import android.util.Log import androidx.activity.ComponentActivity import com.github.cfogrady.vbnfc.be.BENfcCharacter import com.github.cfogrady.vbnfc.be.FirmwareVersion @@ -81,9 +82,7 @@ class ToNfcConverter( activityLevel = userCharacter.activityLevel.toByte(), heartRateCurrent = userCharacter.heartRateCurrent.toUByte(), transformationHistory = paddedTransformationArray, - vitalHistory = Array(7) { - NfcCharacter.DailyVitals(0u, 0u, 0u, 0u) - }, + vitalHistory = generateVitalsHistoryArray(characterId), appReserved1 = ByteArray(12) {0}, appReserved2 = Array(3) {0u}, generation = vbData.generation.toUShort(), @@ -120,6 +119,39 @@ class ToNfcConverter( + private suspend fun generateVitalsHistoryArray( + characterId: Long + ): Array { + val vitalsHistory = database + .userCharacterDao() + .getVitalsHistory(characterId) + + val nfcVitalsHistory = Array(7) { + NfcCharacter.DailyVitals(0u, 0u, 0u, 0u) + } + + vitalsHistory.mapIndexed { index, historyElement -> + var actualYear = 0 + if (historyElement.year != 2000) { + actualYear = historyElement.year + } + nfcVitalsHistory[index] = NfcCharacter.DailyVitals( + day = historyElement.day.toUByte(), + month = historyElement.month.toUByte(), + year = actualYear.toUShort(), + vitalsGained = vitalsHistory[index].vitalPoints.toUShort() + ) + } + + nfcVitalsHistory.map { + Log.d("NFC", it.toString()) + } + + return nfcVitalsHistory + } + + + private suspend fun nfcToBENfc( characterId: Long, characterInfo: CharacterDtos.CardCharacterInfo, @@ -157,9 +189,7 @@ class ToNfcConverter( activityLevel = userCharacter.activityLevel.toByte(), heartRateCurrent = userCharacter.heartRateCurrent.toUByte(), transformationHistory = paddedTransformationArray, - vitalHistory = Array(7) { - NfcCharacter.DailyVitals(0u, 0u, 0u, 0u) - }, + vitalHistory = generateVitalsHistoryArray(characterId), appReserved1 = ByteArray(12) {0}, appReserved2 = Array(3) {0u}, trainingHp = beData.trainingHp.toUShort(), diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt b/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt index b81a198..0e46146 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/settingsScreen/SettingsScreenControllerImpl.kt @@ -132,7 +132,7 @@ class SettingsScreenControllerImpl( .insertNewDim(cardModel) val cardProgress = CardProgress( - cardId = cardModel.cardId, + cardId = dimId, currentStage = 0, unlocked = false )