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