diff --git a/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt similarity index 59% rename from app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt rename to app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt index 885449f..d9c1d3c 100644 --- a/app/src/main/java/com/github/nacabaro/vbhelper/daos/DiMDao.kt +++ b/app/src/main/java/com/github/nacabaro/vbhelper/daos/CardDao.kt @@ -4,16 +4,13 @@ import androidx.room.Dao import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query -import com.github.nacabaro.vbhelper.domain.characters.Card +import com.github.nacabaro.vbhelper.domain.card.Card @Dao -interface DiMDao { +interface CardDao { @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? } \ 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 52b9f6b..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 @@ -12,40 +12,24 @@ 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 @Insert suspend fun insertSprite(vararg sprite: Sprite) - @Query("SELECT * FROM Sprite") - suspend fun getAllSprites(): List - @Query( """ SELECT - d.dimId as cardId, - c.monIndex as charId + d.cardId as cardId, + 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 + WHERE c.id = :charId """ ) - suspend fun getCharacterInfo(charId: Long): CharacterDtos.DiMInfo - - @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) + suspend fun getCharacterInfo(charId: Long): CharacterDtos.CardCharacterInfo } \ 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/daos/UserCharacterDao.kt b/app/src/main/java/com/github/nacabaro/vbhelper/daos/UserCharacterDao.kt index e5f16e5..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 @@ -8,7 +8,10 @@ import androidx.room.Upsert import com.github.nacabaro.vbhelper.domain.characters.Character 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.domain.device_data.VitalsHistory import com.github.nacabaro.vbhelper.dtos.CharacterDtos @Dao @@ -19,6 +22,9 @@ interface UserCharacterDao { @Insert fun insertBECharacterData(characterData: BECharacterData) + @Insert + fun insertVBCharacterData(characterData: VBCharacterData) + @Upsert fun updateCharacter(character: UserCharacter) @@ -28,6 +34,9 @@ interface UserCharacterDao { @Insert(onConflict = OnConflictStrategy.REPLACE) fun insertTransformationHistory(vararg transformationHistory: TransformationHistory) + @Insert + fun insertSpecialMissions(vararg specialMissions: SpecialMissions) + @Query(""" SELECT c.id AS id, @@ -41,7 +50,7 @@ interface UserCharacterDao { JOIN Sprite s ON s.id = c.spriteId WHERE monId = :monId """) - fun getTransformationHistory(monId: Long): List? + suspend fun getTransformationHistory(monId: Long): List? @Query( """ @@ -97,6 +106,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 @@ -141,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/database/AppDatabase.kt b/app/src/main/java/com/github/nacabaro/vbhelper/database/AppDatabase.kt index 3779378..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,36 +5,46 @@ 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 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.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, BECharacterData::class, + 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 8e3a379..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 @@ -7,7 +7,7 @@ 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, 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..9ec48f2 --- /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: Long, + 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/SpecialMissions.kt b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/SpecialMissions.kt new file mode 100644 index 0000000..13b092d --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/SpecialMissions.kt @@ -0,0 +1,28 @@ +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, + 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 8f2afb0..8f13f3d 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 @@ -24,7 +24,6 @@ data class UserCharacter ( @PrimaryKey(autoGenerate = true) val id: Long = 0, var charId: Long, 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/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..313e7c1 --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/domain/device_data/VitalsHistory.kt @@ -0,0 +1,24 @@ +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 = ["id"], + childColumns = ["charId"], + onDelete = ForeignKey.CASCADE + ) + ] +) +data class VitalsHistory ( + @PrimaryKey(autoGenerate = true) val id: Long = 0, + val charId: 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/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 0f45508..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 @@ -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 @@ -58,33 +57,69 @@ 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 = characterToNfc(context, 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!!) + } } } } - 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,6 +140,9 @@ fun ScanScreen( } } ) + } + + if (secrets != null && nfcCharacter != null) { if (!isDoneSendingCard) { scanScreenController.onClickCheckCard(secrets!!, nfcCharacter!!) { isDoneSendingCard = true @@ -115,8 +153,9 @@ fun ScanScreen( } } } + onDispose { - if(readingScreen || writingScreen) { + if(writingScreen) { scanScreenController.unregisterActivityLifecycleListener(SCAN_SCREEN_ACTIVITY_LIFECYCLE_LISTENER) scanScreenController.cancelRead() } @@ -132,7 +171,7 @@ fun ScanScreen( LaunchedEffect(storageRepository) { withContext(Dispatchers.IO) { storageRepository - .deleteCharacter(characterId!!) + .deleteCharacter(selectedCharacterId!!) } } } @@ -158,7 +197,7 @@ fun ScanScreen( } else { ChooseConnectOption( onClickRead = when { - characterId != null -> null + selectedCharacterId != null -> null else -> { { if(secrets == null) { @@ -268,6 +307,8 @@ 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 609ab50..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 @@ -15,4 +15,7 @@ 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..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 @@ -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,101 +146,17 @@ class ScanScreenControllerImpl( componentActivity.startActivity(Intent(Settings.ACTION_WIRELESS_SETTINGS)) } - 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(), - 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 + override fun characterFromNfc(nfcCharacter: NfcCharacter): String { + val nfcConverter = FromNfcConverter( + componentActivity = componentActivity ) + return nfcConverter.addCharacter(nfcCharacter) + } - 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 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 new file mode 100644 index 0000000..459afbc --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/FromNfcConverter.kt @@ -0,0 +1,253 @@ +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 +import com.github.cfogrady.vbnfc.vb.VBNfcCharacter +import com.github.nacabaro.vbhelper.di.VBHelper +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 + +class FromNfcConverter ( + componentActivity: ComponentActivity +) { + private val application = componentActivity.applicationContext as VBHelper + private val database = application.container.db + + + + fun addCharacter(nfcCharacter: NfcCharacter): String { + val cardData = database + .cardDao() + .getDimById(nfcCharacter.dimId.toInt()) + + if (cardData == null) + return "Card not found" + + val cardCharData = database + .characterDao() + .getCharacterByMonIndex(nfcCharacter.charIndex.toInt(), cardData.id) + + updateCardProgress(nfcCharacter, cardData) + + 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 + ) + + 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 = cardData + ) + + addVitalsHistoryToDatabase( + characterId = characterId, + nfcCharacter = nfcCharacter + ) + + return "Done reading character!" + } + + + + private fun updateCardProgress( + nfcCharacter: NfcCharacter, + cardData: Card + ) { + val currentCardProgress = CardProgress( + cardId = cardData.id, + currentStage = nfcCharacter.nextAdventureMissionStage.toInt(), + unlocked = nfcCharacter.nextAdventureMissionStage.toInt() > cardData.stageCount + ) + + database + .cardProgressDao() + .updateDimProgress(currentCardProgress) + } + + + + 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) + } + + + + private fun addSpecialMissionsToDatabase( + nfcCharacter: VBNfcCharacter, + characterId: Long + ) { + 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() + .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 addVitalsHistoryToDatabase( + characterId: Long, + nfcCharacter: NfcCharacter + ) { + val vitalsHistoryWatch = nfcCharacter.vitalHistory + 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() + ) + } + + database + .userCharacterDao() + .insertVitals(*vitalsHistory.toTypedArray()) + } + + + 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 + .userCharacterDao() + .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..819aa2a --- /dev/null +++ b/app/src/main/java/com/github/nacabaro/vbhelper/screens/scanScreen/converters/ToNfcConverter.kt @@ -0,0 +1,271 @@ +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 +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 + .cardProgressDao() + .getCardProgress(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.CardCharacterInfo, + currentCardStage: Int, + userCharacter: UserCharacter + ): VBNfcCharacter { + val vbData = database + .userCharacterDao() + .getVbData(characterId) + + val paddedTransformationArray = generateTransformationHistory(characterId) + + val watchSpecialMissions = generateSpecialMissionsArray(characterId) + + val nfcData = VBNfcCharacter( + dimId = characterInfo.cardId.toUShort(), + charIndex = characterInfo.charId.toUShort(), + stage = characterInfo.stage.toByte(), + attribute = characterInfo.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 = generateVitalsHistoryArray(characterId), + appReserved1 = ByteArray(12) {0}, + appReserved2 = Array(3) {0u}, + generation = vbData.generation.toUShort(), + totalTrophies = vbData.totalTrophies.toUShort(), + specialMissions = watchSpecialMissions.toTypedArray() + ) + + 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 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, + 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 = characterInfo.stage.toByte(), + attribute = characterInfo.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 = generateVitalsHistoryArray(characterId), + 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 372f859..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 @@ -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 @@ -117,9 +118,9 @@ 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, logoHeight = card.spriteData.sprites[0].height, logoWidth = card.spriteData.sprites[0].width, @@ -127,10 +128,22 @@ class SettingsScreenControllerImpl( ) val dimId = database - .dimDao() + .cardDao() .insertNewDim(cardModel) - val characters = card.characterStats.characterEntries + val cardProgress = CardProgress( + cardId = dimId, + currentStage = 0, + unlocked = false + ) + + database + .cardProgressDao() + .updateDimProgress(cardProgress) + + val characters = card + .characterStats + .characterEntries var spriteCounter = when (card is BemCard) { true -> 54 @@ -140,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() } 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