diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 178e52f..701cffb 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -49,6 +49,23 @@ android {
)
}
}
+
+ productFlavors {
+
+ flavorDimensions.add("nfsmw")
+
+ create("devmenu") {
+ dimension = "nfsmw"
+ minSdk = 21
+ }
+ create("no_devmenu") {
+ dimension = "nfsmw"
+ minSdk = 21
+ }
+ }
+
+
+
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
@@ -79,7 +96,6 @@ dependencies {
implementation(libs.ui.graphics)
implementation(libs.ui.tooling.preview)
implementation(libs.material3)
- implementation(project(":devmenu:data"))
testImplementation(libs.junit.v412)
//testImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.ext.junit)
diff --git a/app/src/devmenu/AndroidManifest.xml b/app/src/devmenu/AndroidManifest.xml
new file mode 100644
index 0000000..7e0c762
--- /dev/null
+++ b/app/src/devmenu/AndroidManifest.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5dbedb2..e3df730 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -34,13 +34,7 @@
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/devmenu/build.gradle.kts b/devmenu/build.gradle.kts
index 6be7607..409620d 100644
--- a/devmenu/build.gradle.kts
+++ b/devmenu/build.gradle.kts
@@ -1,7 +1,7 @@
-@Suppress("DSL_SCOPE_VIOLATION") // TODO: Remove once KTIJ-19369 is fixed
plugins {
alias(libs.plugins.androidLibrary)
alias(libs.plugins.kotlinAndroid)
+ alias(libs.plugins.ksp)
}
android {
@@ -59,6 +59,7 @@ dependencies {
implementation(libs.ui.graphics)
implementation(libs.ui.tooling.preview)
implementation(libs.material3)
+ implementation(project(mapOf("path" to ":devmenu:domain")))
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.espresso.core)
@@ -66,4 +67,9 @@ dependencies {
androidTestImplementation(libs.ui.test.junit4)
debugImplementation(libs.ui.tooling)
debugImplementation(libs.ui.test.manifest)
+
+ implementation(libs.dagger)
+ ksp(libs.dagger.compiler)
+ implementation(libs.room)
+ ksp(libs.room.compiler)
}
\ No newline at end of file
diff --git a/devmenu/data/build.gradle.kts b/devmenu/data/build.gradle.kts
index 6ab1e4a..edc6321 100644
--- a/devmenu/data/build.gradle.kts
+++ b/devmenu/data/build.gradle.kts
@@ -38,6 +38,7 @@ dependencies {
implementation(libs.core.ktx)
implementation(libs.appcompat)
implementation(libs.material)
+ implementation(project(mapOf("path" to ":devmenu:domain")))
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.test.ext.junit)
androidTestImplementation(libs.espresso.core)
diff --git a/devmenu/data/src/main/java/com/megboyzz/devmenu/data/repositories/MyClass.kt b/devmenu/data/src/main/java/com/megboyzz/devmenu/data/repositories/MyClass.kt
deleted file mode 100644
index d48b0d7..0000000
--- a/devmenu/data/src/main/java/com/megboyzz/devmenu/data/repositories/MyClass.kt
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.megboyzz.devmenu.data.repositories
-
-class MyClass {
-
- fun main(){
-
- val input = readln().split(",").associate {
- val s = it.trim().split(" ")
- s[0] to s[1].toInt()
- }
-
- var sum = 0
-
- readln().split(" ").forEach {
-
- val s = input[it] ?: 0
- sum += s
-
- }
-
- println(sum)
-
-
- }
-
-}
\ No newline at end of file
diff --git a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/entities/FileProps.kt b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/entities/FileProps.kt
index 2141304..1cccd68 100644
--- a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/entities/FileProps.kt
+++ b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/entities/FileProps.kt
@@ -4,6 +4,6 @@ import java.util.Date
data class FileProps(
val fileName: String,
- val size: Int,
- val dateOfCreation: Date
+ val size: Long,
+ val lastModify: Date
)
diff --git a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/entities/TrackingData.kt b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/entities/TrackingData.kt
new file mode 100644
index 0000000..656c0cb
--- /dev/null
+++ b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/entities/TrackingData.kt
@@ -0,0 +1,6 @@
+package com.megboyzz.devmenu.domain.entities
+
+data class TrackingData(
+ val enabled: Boolean,
+ val pathToSave: String
+)
diff --git a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/repository/SettingsRepository.kt b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/repository/SettingsRepository.kt
index 27d886b..da5e07b 100644
--- a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/repository/SettingsRepository.kt
+++ b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/repository/SettingsRepository.kt
@@ -4,7 +4,6 @@ import com.megboyzz.devmenu.domain.entities.GameLang
interface SettingsRepository {
- fun setGameLang(lang: GameLang): Boolean
-
+ var gameLang: GameLang
}
\ No newline at end of file
diff --git a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/repository/TrackingRepository.kt b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/repository/TrackingRepository.kt
index a58c6e1..01f8bb6 100644
--- a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/repository/TrackingRepository.kt
+++ b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/repository/TrackingRepository.kt
@@ -1,7 +1,13 @@
package com.megboyzz.devmenu.domain.repository
+import com.megboyzz.devmenu.domain.entities.TrackingData
+
interface TrackingRepository {
- fun setTracking(enabled: Boolean, pathToSave: String): Boolean
+ var trackingData: TrackingData
+
+ fun startTracking()
+
+ fun stopTracking()
}
\ No newline at end of file
diff --git a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/IsDevMenuEnabledUseCase.kt b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/IsDevMenuEnabledUseCase.kt
new file mode 100644
index 0000000..3e6a848
--- /dev/null
+++ b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/IsDevMenuEnabledUseCase.kt
@@ -0,0 +1,12 @@
+package com.megboyzz.devmenu.domain.usecases
+
+import com.megboyzz.devmenu.domain.entities.devmenuId
+import com.megboyzz.devmenu.domain.repository.FilesRepository
+import java.io.File
+import javax.inject.Inject
+
+class IsDevMenuEnabledUseCase @Inject constructor(
+ private val filesRepository: FilesRepository
+) {
+ operator fun invoke() = File(filesRepository.externalRoot, devmenuId).exists()
+}
\ No newline at end of file
diff --git a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/StartTrackingUseCase.kt b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/StartTrackingUseCase.kt
new file mode 100644
index 0000000..85a7a7a
--- /dev/null
+++ b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/StartTrackingUseCase.kt
@@ -0,0 +1,17 @@
+package com.megboyzz.devmenu.domain.usecases
+
+import com.megboyzz.devmenu.domain.repository.TrackingRepository
+import javax.inject.Inject
+
+class StartTrackingUseCase @Inject constructor(
+ private val trackingRepository: TrackingRepository
+) {
+
+ operator fun invoke(){
+
+ if(trackingRepository.trackingData.enabled)
+ trackingRepository.startTracking()
+
+ }
+
+}
\ No newline at end of file
diff --git a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/StopTrackingUseCase.kt b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/StopTrackingUseCase.kt
new file mode 100644
index 0000000..979c5af
--- /dev/null
+++ b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/StopTrackingUseCase.kt
@@ -0,0 +1,11 @@
+package com.megboyzz.devmenu.domain.usecases
+
+import com.megboyzz.devmenu.domain.repository.TrackingRepository
+import javax.inject.Inject
+class StopTrackingUseCase @Inject constructor(
+ private val trackingRepository: TrackingRepository
+) {
+
+ operator fun invoke() = trackingRepository.stopTracking()
+
+}
\ No newline at end of file
diff --git a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/settings/SetGameLangUseCase.kt b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/settings/SetGameLangUseCase.kt
index edb131f..338f964 100644
--- a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/settings/SetGameLangUseCase.kt
+++ b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/settings/SetGameLangUseCase.kt
@@ -8,6 +8,8 @@ class SetGameLangUseCase @Inject constructor(
private val settingsRepository: SettingsRepository
) {
- operator fun invoke(gameLang: GameLang) = settingsRepository.setGameLang(gameLang)
+ operator fun invoke(gameLang: GameLang){
+ settingsRepository.gameLang = gameLang
+ }
}
\ No newline at end of file
diff --git a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/settings/SetTrackingSaveFileUseCase.kt b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/settings/SetTrackingSaveFileUseCase.kt
index afb1eb7..4ce20ae 100644
--- a/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/settings/SetTrackingSaveFileUseCase.kt
+++ b/devmenu/domain/src/main/java/com/megboyzz/devmenu/domain/usecases/settings/SetTrackingSaveFileUseCase.kt
@@ -1,5 +1,6 @@
package com.megboyzz.devmenu.domain.usecases.settings
+import com.megboyzz.devmenu.domain.entities.TrackingData
import com.megboyzz.devmenu.domain.repository.TrackingRepository
import javax.inject.Inject
@@ -7,7 +8,8 @@ class SetTrackingSaveFileUseCase @Inject constructor(
private val trackingRepository: TrackingRepository
) {
- operator fun invoke(enabled: Boolean, pathToSave: String) =
- trackingRepository.setTracking(enabled, pathToSave)
+ operator fun invoke(enabled: Boolean, pathToSave: String) {
+ trackingRepository.trackingData = TrackingData(enabled, pathToSave)
+ }
}
\ No newline at end of file
diff --git a/devmenu/domain/src/test/java/UseCaseTest.kt b/devmenu/domain/src/test/java/UseCaseTest.kt
deleted file mode 100644
index 38320bb..0000000
--- a/devmenu/domain/src/test/java/UseCaseTest.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-import com.megboyzz.devmenu.domain.repository.FilesRepository
-import com.megboyzz.devmenu.domain.repository.ReplacementRepository
-import com.megboyzz.devmenu.domain.repository.SaveRepository
-import com.megboyzz.devmenu.domain.repository.SvmwRepository
-import org.mockito.Mockito.mock
-import org.mockito.Mockito.`when`
-import java.io.File
-
-class UseCaseTest {
-
- private val filesRepository = mock(FilesRepository::class.java)
- private val replacementRepository = mock(ReplacementRepository::class.java)
- private val saveRepository = mock(SaveRepository::class.java)
- private val svmwRepository = mock(SvmwRepository::class.java)
-
- private val externalFile = File("D:\\NFSMW Online\\com.ea.games.nfs13_na")
- private val internalFile = File("D:\\NFSMW Online")
-
- init {
-
- `when`(filesRepository.externalRoot).thenReturn(externalFile)
- `when`(filesRepository.internalRoot).thenReturn(internalFile)
-
-
- //`when`(replacementRepository.getAllReplacements()).thenReturn()
-
-
- }
-
-}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/MainActivity.kt b/devmenu/src/main/java/com/megboyzz/devmenu/MainActivity.kt
index 15110c8..9b8a398 100644
--- a/devmenu/src/main/java/com/megboyzz/devmenu/MainActivity.kt
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/MainActivity.kt
@@ -3,10 +3,14 @@ package com.megboyzz.devmenu
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
+import com.megboyzz.devmenu.di.components.AppComponent
+import dagger.internal.DaggerGenerated
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+
+
setContent {}
}
}
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/db/AppDatabase.kt b/devmenu/src/main/java/com/megboyzz/devmenu/db/AppDatabase.kt
new file mode 100644
index 0000000..52c2b6d
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/db/AppDatabase.kt
@@ -0,0 +1,11 @@
+package com.megboyzz.devmenu.db
+
+import androidx.room.Database
+import androidx.room.RoomDatabase
+import com.megboyzz.devmenu.db.dao.ReplacementDao
+import com.megboyzz.devmenu.db.entites.Replacement
+
+@Database(entities = [Replacement::class], version = 1, exportSchema = false)
+abstract class AppDatabase: RoomDatabase() {
+ abstract val replacementDao: ReplacementDao
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/db/dao/ReplacementDao.kt b/devmenu/src/main/java/com/megboyzz/devmenu/db/dao/ReplacementDao.kt
new file mode 100644
index 0000000..5cfeaa1
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/db/dao/ReplacementDao.kt
@@ -0,0 +1,24 @@
+package com.megboyzz.devmenu.db.dao
+
+import androidx.room.Dao
+import androidx.room.Delete
+import androidx.room.Insert
+import androidx.room.Query
+import com.megboyzz.devmenu.db.entites.Replacement
+
+@Dao
+interface ReplacementDao {
+
+ @get:Query("SELECT * from replacement")
+ val all: List
+
+ @Insert
+ fun addReplacement(replacement: Replacement)
+
+ @Query("SELECT * FROM replacement WHERE original_file_name=:originalFileName")
+ fun getReplacementByOriginalName(originalFileName: String): Replacement
+
+ @Delete
+ fun removeReplacement(replacement: Replacement)
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/db/entites/Replacement.kt b/devmenu/src/main/java/com/megboyzz/devmenu/db/entites/Replacement.kt
new file mode 100644
index 0000000..fb7431c
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/db/entites/Replacement.kt
@@ -0,0 +1,18 @@
+package com.megboyzz.devmenu.db.entites
+
+import androidx.room.ColumnInfo
+import androidx.room.Entity
+import androidx.room.PrimaryKey
+
+@Entity
+data class Replacement(
+
+ @PrimaryKey(autoGenerate = true)
+ val id: Int = 0,
+
+ @ColumnInfo(name = "original_file_name")
+ val originalFileName: String,
+
+ @ColumnInfo(name = "replacement_file_name")
+ val replacementFileName: String
+)
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/di/components/AppComponent.kt b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/AppComponent.kt
new file mode 100644
index 0000000..60f50e1
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/AppComponent.kt
@@ -0,0 +1,50 @@
+package com.megboyzz.devmenu.di.components
+
+import android.content.Context
+import com.megboyzz.devmenu.db.entites.Replacement
+import com.megboyzz.devmenu.di.components.subcomponents.FilesUseCaseComponent
+import com.megboyzz.devmenu.di.components.subcomponents.HideFilesUseCaseComponent
+import com.megboyzz.devmenu.di.components.subcomponents.ReplacementUseCaseComponent
+import com.megboyzz.devmenu.di.components.subcomponents.SettingsUseCaseComponent
+import com.megboyzz.devmenu.di.components.subcomponents.TrackingHandlerUseCaseComponent
+import com.megboyzz.devmenu.di.modules.DatabaseModule
+import com.megboyzz.devmenu.di.modules.RepositoryModule
+import com.megboyzz.devmenu.di.modules.SubcomponentsModule
+import com.megboyzz.devmenu.domain.usecases.files.GetFilePropsUseCase
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Subcomponent
+import javax.inject.Singleton
+
+
+@Component(
+ modules = [
+ SubcomponentsModule::class,
+ DatabaseModule::class,
+ RepositoryModule::class
+ ]
+)
+@Singleton
+interface AppComponent {
+
+ val filesUseCaseComponent: FilesUseCaseComponent.Builder
+
+ val hideFilesUseCaseComponent: HideFilesUseCaseComponent.Builder
+
+ val replacementUseCaseComponent: ReplacementUseCaseComponent.Builder
+
+ val settingsUseCaseComponent: SettingsUseCaseComponent.Builder
+
+ val trackingHandlerUseCaseComponent: TrackingHandlerUseCaseComponent.Builder
+
+ @Component.Builder
+ interface Builder{
+
+ @BindsInstance
+ fun context(context: Context): Builder
+
+ fun build(): AppComponent
+
+ }
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/FilesUseCaseComponent.kt b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/FilesUseCaseComponent.kt
new file mode 100644
index 0000000..e9b2435
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/FilesUseCaseComponent.kt
@@ -0,0 +1,32 @@
+package com.megboyzz.devmenu.di.components.subcomponents
+
+import android.content.Context
+import com.megboyzz.devmenu.di.components.AppComponent
+import com.megboyzz.devmenu.domain.usecases.files.GetExternalFilesUseCase
+import com.megboyzz.devmenu.domain.usecases.files.GetFilePropsUseCase
+import com.megboyzz.devmenu.domain.usecases.files.GetInternalFilesUseCase
+import com.megboyzz.devmenu.domain.usecases.files.RemoveFileUseCase
+import com.megboyzz.devmenu.domain.usecases.files.RenameFileUseCase
+import dagger.BindsInstance
+import dagger.Component
+import dagger.Subcomponent
+
+@Subcomponent
+interface FilesUseCaseComponent {
+
+ val getExternalFilesUseCase: GetExternalFilesUseCase
+
+ val getInternalFilesUseCase: GetInternalFilesUseCase
+
+ val getFilePropsUseCase: GetFilePropsUseCase
+
+ val removeFileUseCase: RemoveFileUseCase
+
+ val renameFileUseCase: RenameFileUseCase
+
+ @Component.Builder
+ interface Builder{
+ fun build(): AppComponent
+ }
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/HideFilesUseCaseComponent.kt b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/HideFilesUseCaseComponent.kt
new file mode 100644
index 0000000..e9f8cda
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/HideFilesUseCaseComponent.kt
@@ -0,0 +1,27 @@
+package com.megboyzz.devmenu.di.components.subcomponents
+
+import com.megboyzz.devmenu.di.components.AppComponent
+import com.megboyzz.devmenu.domain.usecases.hidefiles.GetAllHidedFilesUseCase
+import com.megboyzz.devmenu.domain.usecases.hidefiles.HideFileUseCase
+import com.megboyzz.devmenu.domain.usecases.hidefiles.UnHideAllUseCase
+import com.megboyzz.devmenu.domain.usecases.hidefiles.UnHideFileUseCase
+import dagger.Component
+import dagger.Subcomponent
+
+@Subcomponent
+interface HideFilesUseCaseComponent {
+
+ val getAllHidedFilesUseCase: GetAllHidedFilesUseCase
+
+ val hideFileUseCase: HideFileUseCase
+
+ val unHideFileUseCase: UnHideFileUseCase
+
+ val unHideAllUseCase: UnHideAllUseCase
+
+ @Component.Builder
+ interface Builder{
+ fun build(): AppComponent
+ }
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/ReplacementUseCaseComponent.kt b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/ReplacementUseCaseComponent.kt
new file mode 100644
index 0000000..48aabff
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/ReplacementUseCaseComponent.kt
@@ -0,0 +1,27 @@
+package com.megboyzz.devmenu.di.components.subcomponents
+
+import com.megboyzz.devmenu.di.components.AppComponent
+import com.megboyzz.devmenu.domain.usecases.replacement.GetAllReplacedFilesUseCase
+import com.megboyzz.devmenu.domain.usecases.replacement.RecoverAllReplacementsUseCase
+import com.megboyzz.devmenu.domain.usecases.replacement.RecoverReplacementUseCase
+import com.megboyzz.devmenu.domain.usecases.replacement.ReplaceFileUseCase
+import dagger.Component
+import dagger.Subcomponent
+
+@Subcomponent
+interface ReplacementUseCaseComponent {
+
+ val getAllReplacedFilesUseCase: GetAllReplacedFilesUseCase
+
+ val recoverAllReplacedFilesUseCase: RecoverAllReplacementsUseCase
+
+ val recoverReplacementUseCase: RecoverReplacementUseCase
+
+ val replaceFileUseCase: ReplaceFileUseCase
+
+ @Component.Builder
+ interface Builder{
+ fun build(): AppComponent
+ }
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/SettingsUseCaseComponent.kt b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/SettingsUseCaseComponent.kt
new file mode 100644
index 0000000..42f1094
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/SettingsUseCaseComponent.kt
@@ -0,0 +1,27 @@
+package com.megboyzz.devmenu.di.components.subcomponents
+
+import com.megboyzz.devmenu.di.components.AppComponent
+import com.megboyzz.devmenu.domain.usecases.settings.RemoveGameDataUseCase
+import com.megboyzz.devmenu.domain.usecases.settings.SetGameLangUseCase
+import com.megboyzz.devmenu.domain.usecases.settings.SetTrackingSaveFileUseCase
+import com.megboyzz.devmenu.domain.usecases.settings.TurnOffDevMenuUseCase
+import dagger.Component
+import dagger.Subcomponent
+
+@Subcomponent
+interface SettingsUseCaseComponent {
+
+ val removeGameDataUseCase: RemoveGameDataUseCase
+
+ val setGameLangUseCase: SetGameLangUseCase
+
+ val setTrackingSaveFileUseCase: SetTrackingSaveFileUseCase
+
+ val turnOffDevMenuUseCase: TurnOffDevMenuUseCase
+
+ @Component.Builder
+ interface Builder{
+ fun build(): AppComponent
+ }
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/TrackingHandlerUseCaseComponent.kt b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/TrackingHandlerUseCaseComponent.kt
new file mode 100644
index 0000000..986be68
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/di/components/subcomponents/TrackingHandlerUseCaseComponent.kt
@@ -0,0 +1,24 @@
+package com.megboyzz.devmenu.di.components.subcomponents
+
+import com.megboyzz.devmenu.di.components.AppComponent
+import com.megboyzz.devmenu.domain.usecases.IsDevMenuEnabledUseCase
+import com.megboyzz.devmenu.domain.usecases.StartTrackingUseCase
+import com.megboyzz.devmenu.domain.usecases.StopTrackingUseCase
+import dagger.Component
+import dagger.Subcomponent
+
+@Subcomponent
+interface TrackingHandlerUseCaseComponent {
+
+ val isDevMenuEnabledUseCase: IsDevMenuEnabledUseCase
+
+ val startTrackingUseCase: StartTrackingUseCase
+
+ val stopTrackingUseCase: StopTrackingUseCase
+
+ @Component.Builder
+ interface Builder{
+ fun build(): AppComponent
+ }
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/di/modules/DatabaseModule.kt b/devmenu/src/main/java/com/megboyzz/devmenu/di/modules/DatabaseModule.kt
new file mode 100644
index 0000000..ffe966a
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/di/modules/DatabaseModule.kt
@@ -0,0 +1,25 @@
+package com.megboyzz.devmenu.di.modules
+
+import android.content.Context
+import androidx.room.Room
+import androidx.room.RoomDatabase
+import com.megboyzz.devmenu.db.AppDatabase
+import dagger.Module
+import dagger.Provides
+
+@Module
+class DatabaseModule {
+
+ @Provides
+ fun providesDataBase(context: Context): AppDatabase =
+ Room.databaseBuilder(
+ context,
+ AppDatabase::class.java,
+ "replacement-db"
+ ).build()
+
+
+ @Provides
+ fun providesReplacementDao(appDatabase: AppDatabase) = appDatabase.replacementDao
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/di/modules/RepositoryModule.kt b/devmenu/src/main/java/com/megboyzz/devmenu/di/modules/RepositoryModule.kt
new file mode 100644
index 0000000..9ae1dc1
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/di/modules/RepositoryModule.kt
@@ -0,0 +1,51 @@
+package com.megboyzz.devmenu.di.modules
+
+import android.content.Context
+import com.megboyzz.devmenu.db.dao.ReplacementDao
+import com.megboyzz.devmenu.domain.repository.FilesRepository
+import com.megboyzz.devmenu.domain.repository.ReplacementRepository
+import com.megboyzz.devmenu.domain.repository.SaveRepository
+import com.megboyzz.devmenu.domain.repository.SettingsRepository
+import com.megboyzz.devmenu.domain.repository.TrackingRepository
+import com.megboyzz.devmenu.repositories.FilesRepositoryImpl
+import com.megboyzz.devmenu.repositories.ReplacementRepositoryImpl
+import com.megboyzz.devmenu.repositories.SaveRepositoryImpl
+import com.megboyzz.devmenu.repositories.SettingsRepositoryImpl
+import com.megboyzz.devmenu.repositories.TrackingRepositoryImpl
+import dagger.Module
+import dagger.Provides
+
+@Module
+class RepositoryModule {
+
+ @Provides
+ fun providesFilesRepository(context: Context): FilesRepository =
+ FilesRepositoryImpl(context)
+
+ @Provides
+ fun providesReplacementRepository(
+ replacementDao: ReplacementDao,
+ filesRepository: FilesRepository
+ ): ReplacementRepository =
+ ReplacementRepositoryImpl(replacementDao, filesRepository)
+
+ @Provides
+ fun providesSaveRepositoryImpl(
+ filesRepository: FilesRepository
+ ): SaveRepository =
+ SaveRepositoryImpl(filesRepository)
+
+ @Provides
+ fun providesSettingsRepository(
+ filesRepository: FilesRepository
+ ): SettingsRepository =
+ SettingsRepositoryImpl(filesRepository)
+
+ @Provides
+ fun providesTrackingRepository(
+ context: Context,
+ filesRepository: FilesRepository
+ ): TrackingRepository =
+ TrackingRepositoryImpl(context, filesRepository)
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/di/modules/SubcomponentsModule.kt b/devmenu/src/main/java/com/megboyzz/devmenu/di/modules/SubcomponentsModule.kt
new file mode 100644
index 0000000..15ae17f
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/di/modules/SubcomponentsModule.kt
@@ -0,0 +1,19 @@
+package com.megboyzz.devmenu.di.modules
+
+import com.megboyzz.devmenu.di.components.subcomponents.FilesUseCaseComponent
+import com.megboyzz.devmenu.di.components.subcomponents.HideFilesUseCaseComponent
+import com.megboyzz.devmenu.di.components.subcomponents.ReplacementUseCaseComponent
+import com.megboyzz.devmenu.di.components.subcomponents.SettingsUseCaseComponent
+import com.megboyzz.devmenu.di.components.subcomponents.TrackingHandlerUseCaseComponent
+import dagger.Module
+
+@Module(
+ subcomponents = [
+ FilesUseCaseComponent::class,
+ HideFilesUseCaseComponent::class,
+ ReplacementUseCaseComponent::class,
+ SettingsUseCaseComponent::class,
+ TrackingHandlerUseCaseComponent::class
+ ]
+)
+object SubcomponentsModule
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/repositories/FilesRepositoryImpl.kt b/devmenu/src/main/java/com/megboyzz/devmenu/repositories/FilesRepositoryImpl.kt
new file mode 100644
index 0000000..e54738b
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/repositories/FilesRepositoryImpl.kt
@@ -0,0 +1,32 @@
+package com.megboyzz.devmenu.repositories
+
+import android.content.Context
+import com.megboyzz.devmenu.domain.entities.FileProps
+import com.megboyzz.devmenu.domain.repository.FilesRepository
+import java.io.File
+import java.util.Date
+
+class FilesRepositoryImpl(
+ private val context: Context
+): FilesRepository {
+
+ override val internalRoot = File(context.applicationInfo.dataDir)
+ override val externalRoot = context.getExternalFilesDir(null)!!
+
+ override fun getFileProps(file: File) = FileProps(
+ fileName = file.name,
+ size = file.length(),
+ lastModify = Date(file.lastModified())
+ )
+
+ override suspend fun hideFile(file: File): Boolean {
+ TODO("Not yet implemented")
+ }
+
+ override suspend fun unHideFile(file: File): Boolean {
+ TODO("Not yet implemented")
+ }
+
+ override val allHidedFiles: List
+ get() = TODO("Not yet implemented")
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/repositories/ReplacementRepositoryImpl.kt b/devmenu/src/main/java/com/megboyzz/devmenu/repositories/ReplacementRepositoryImpl.kt
new file mode 100644
index 0000000..d47cceb
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/repositories/ReplacementRepositoryImpl.kt
@@ -0,0 +1,73 @@
+package com.megboyzz.devmenu.repositories
+
+import com.megboyzz.devmenu.db.dao.ReplacementDao
+import com.megboyzz.devmenu.db.entites.Replacement
+import com.megboyzz.devmenu.domain.repository.FilesRepository
+import com.megboyzz.devmenu.domain.repository.ReplacementRepository
+import java.io.File
+import java.lang.Exception
+import javax.inject.Inject
+import kotlin.random.Random
+
+class ReplacementRepositoryImpl @Inject constructor(
+ private val replacementDao: ReplacementDao,
+ private val filesRepository: FilesRepository
+): ReplacementRepository {
+
+ private val folderToSaveReplacements = File("${filesRepository.internalRoot}/replacements")
+
+ private fun generateRandomPostfix(): String {
+ val length = 10
+ return (1..length)
+ .map { _ -> Random.nextInt(0, 36) }
+ .joinToString("") { charIndex -> charIndex.toString(radix = 36) }
+ }
+ override suspend fun replaceFile(what: File, to: File): Result {
+
+ return kotlin.runCatching {
+ val replacementFile =
+ File(folderToSaveReplacements, "replacement-${generateRandomPostfix()}")
+ replacementFile.createNewFile()
+
+ to.copyTo(replacementFile, overwrite = true)
+ what.copyTo(to, overwrite = true)
+
+ val replacement = Replacement(
+ originalFileName = what.absolutePath,
+ replacementFileName = replacementFile.absolutePath
+ )
+ replacementDao.addReplacement(replacement)
+
+ return Result.success(true)
+ }.onFailure {
+ return Result.failure(it)
+ }
+
+ }
+
+ override suspend fun recoverReplacement(replacement: File): Result {
+ return kotlin.runCatching {
+ val rep = replacementDao.getReplacementByOriginalName(replacement.absolutePath)
+
+ val repFile = File(rep.replacementFileName)
+
+ repFile.copyTo(File(rep.originalFileName), overwrite = true)
+
+ repFile.delete()
+
+ replacementDao.removeReplacement(rep)
+
+ return Result.success(true)
+ }.onFailure {
+ return Result.failure(it)
+ }
+ }
+
+ override suspend fun getAllReplacements(): List {
+ return replacementDao.all.map {
+ File(it.originalFileName)
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/repositories/SaveRepositoryImpl.kt b/devmenu/src/main/java/com/megboyzz/devmenu/repositories/SaveRepositoryImpl.kt
new file mode 100644
index 0000000..2aac431
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/repositories/SaveRepositoryImpl.kt
@@ -0,0 +1,27 @@
+package com.megboyzz.devmenu.repositories
+
+import com.megboyzz.devmenu.domain.repository.FilesRepository
+import com.megboyzz.devmenu.domain.repository.SaveRepository
+import java.io.File
+
+class SaveRepositoryImpl(
+ private val filesRepository: FilesRepository
+): SaveRepository {
+
+ private val saveFile = File(filesRepository.internalRoot, "/files/var/nfstr_save.sb")
+
+ override suspend fun loadSaveFile(file: File): Boolean {
+
+ file.copyTo(saveFile, overwrite = true)
+
+ return true
+ }
+
+ override suspend fun uploadCurrentSaveFile(fileToUpload: File): Boolean {
+
+ saveFile.copyTo(fileToUpload, overwrite = true)
+
+ return true
+ }
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/repositories/SettingsRepositoryImpl.kt b/devmenu/src/main/java/com/megboyzz/devmenu/repositories/SettingsRepositoryImpl.kt
new file mode 100644
index 0000000..b9ef077
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/repositories/SettingsRepositoryImpl.kt
@@ -0,0 +1,47 @@
+package com.megboyzz.devmenu.repositories
+
+import android.content.res.Resources
+import com.megboyzz.devmenu.domain.entities.GameLang
+import com.megboyzz.devmenu.domain.repository.FilesRepository
+import com.megboyzz.devmenu.domain.repository.SettingsRepository
+import java.io.File
+import java.nio.charset.Charset
+import javax.inject.Inject
+
+class SettingsRepositoryImpl @Inject constructor(
+ private val filesRepository: FilesRepository
+): SettingsRepository {
+
+ private val localeFile = File(filesRepository.internalRoot, "files/var/locale")
+
+ private fun getSystemLangAsGameLang(): GameLang {
+
+ val configuration = Resources.getSystem().configuration
+ return GameLang.values().find { it.name == configuration.locale.language } ?: GameLang.Russian
+
+ }
+
+
+ override var gameLang: GameLang
+ get() {
+
+ val systemLang = getSystemLangAsGameLang()
+
+ if(!localeFile.exists()){
+ localeFile.createNewFile()
+ localeFile.writeBytes(byteArrayOf(0x02, 0x0) + systemLang.name.toByteArray())
+ return systemLang
+ }
+
+ val curLocale = String(localeFile.readBytes().takeLast(2).toByteArray())
+ return GameLang.values().find { it.name == curLocale } ?: systemLang
+ }
+ set(value) {
+
+ if(!localeFile.exists()) localeFile.createNewFile()
+
+ localeFile.writeBytes(byteArrayOf(0x02, 0x0) + value.name.toByteArray())
+
+ }
+
+}
\ No newline at end of file
diff --git a/devmenu/src/main/java/com/megboyzz/devmenu/repositories/TrackingRepositoryImpl.kt b/devmenu/src/main/java/com/megboyzz/devmenu/repositories/TrackingRepositoryImpl.kt
new file mode 100644
index 0000000..7359006
--- /dev/null
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/repositories/TrackingRepositoryImpl.kt
@@ -0,0 +1,55 @@
+package com.megboyzz.devmenu.repositories
+
+import android.content.Context
+import com.megboyzz.devmenu.domain.entities.TrackingData
+import com.megboyzz.devmenu.domain.repository.FilesRepository
+import com.megboyzz.devmenu.domain.repository.TrackingRepository
+import com.megboyzz.devmenu.util.SaveFileObserver
+import javax.inject.Inject
+
+class TrackingRepositoryImpl @Inject constructor(
+ private val context: Context,
+ private val filesRepository: FilesRepository
+) : TrackingRepository {
+
+ private val TAG = this::class.simpleName
+
+ private val trackingStateKey = "tracking_enabled"
+ private val trackingSavePath = "tracking_save_path"
+ private val defaultPathToSave = "${filesRepository.externalRoot}/files/saveTracking"
+
+ private val saveFile = "${filesRepository.internalRoot}/files/var/nfstr_save.sb"
+
+ private val sharedPreferences = context.getSharedPreferences("tracking", Context.MODE_PRIVATE)
+
+ private val editor = sharedPreferences.edit()
+
+ private lateinit var saveFileObserver: SaveFileObserver
+
+ override var trackingData: TrackingData
+ get() {
+ val enabled = sharedPreferences.getBoolean(trackingStateKey, false)
+ val path = sharedPreferences.getString(trackingStateKey, defaultPathToSave)?: defaultPathToSave
+
+ return TrackingData(
+ enabled = enabled,
+ pathToSave = path
+ )
+ }
+ set(value) {
+ with(editor) {
+ putBoolean(trackingStateKey, value.enabled)
+ putString(trackingSavePath, value.pathToSave)
+ apply()
+ }
+ }
+
+ override fun startTracking() {
+ saveFileObserver = SaveFileObserver(saveFile, trackingData.pathToSave)
+ saveFileObserver.startWatching()
+ }
+
+ override fun stopTracking() {
+ saveFileObserver.stopWatching()
+ }
+}
\ No newline at end of file
diff --git a/devmenu/data/src/main/java/com/megboyzz/devmenu/data/util/BaseObserver.kt b/devmenu/src/main/java/com/megboyzz/devmenu/util/BaseObserver.kt
similarity index 98%
rename from devmenu/data/src/main/java/com/megboyzz/devmenu/data/util/BaseObserver.kt
rename to devmenu/src/main/java/com/megboyzz/devmenu/util/BaseObserver.kt
index 2f4d5c3..3707ee1 100644
--- a/devmenu/data/src/main/java/com/megboyzz/devmenu/data/util/BaseObserver.kt
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/util/BaseObserver.kt
@@ -1,4 +1,4 @@
-package com.megboyzz.devmenu.data.util
+package com.megboyzz.devmenu.util
import android.os.FileObserver
import android.util.Log
diff --git a/devmenu/data/src/main/java/com/megboyzz/devmenu/data/util/FileEvent.kt b/devmenu/src/main/java/com/megboyzz/devmenu/util/FileEvent.kt
similarity index 93%
rename from devmenu/data/src/main/java/com/megboyzz/devmenu/data/util/FileEvent.kt
rename to devmenu/src/main/java/com/megboyzz/devmenu/util/FileEvent.kt
index 2e0ae60..1af0974 100644
--- a/devmenu/data/src/main/java/com/megboyzz/devmenu/data/util/FileEvent.kt
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/util/FileEvent.kt
@@ -1,4 +1,4 @@
-package com.megboyzz.devmenu.data.util
+package com.megboyzz.devmenu.util
import android.os.FileObserver
diff --git a/devmenu/data/src/main/java/com/megboyzz/devmenu/data/util/SaveFileObserver.kt b/devmenu/src/main/java/com/megboyzz/devmenu/util/SaveFileObserver.kt
similarity index 91%
rename from devmenu/data/src/main/java/com/megboyzz/devmenu/data/util/SaveFileObserver.kt
rename to devmenu/src/main/java/com/megboyzz/devmenu/util/SaveFileObserver.kt
index 55b9701..e6b072a 100644
--- a/devmenu/data/src/main/java/com/megboyzz/devmenu/data/util/SaveFileObserver.kt
+++ b/devmenu/src/main/java/com/megboyzz/devmenu/util/SaveFileObserver.kt
@@ -1,4 +1,4 @@
-package com.megboyzz.devmenu.data.util
+package com.megboyzz.devmenu.util
import android.util.Log
import java.io.File
@@ -13,10 +13,10 @@ class SaveFileObserver(
private var countSnapshots: Int = 1
private val checkList = listOf(
- FileEvent.CLOSE_WRITE,
- FileEvent.MODIFY,
+ //FileEvent.CLOSE_WRITE,
+ //FileEvent.MODIFY,
//FileEvent.DELETE,
- FileEvent.CREATE,
+ //FileEvent.CREATE,
//FileEvent.ACCESS,
//FileEvent.OPEN,
FileEvent.CLOSE_NOWRITE
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 8112cc2..1c87d57 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -12,6 +12,9 @@ compose-bom = "2023.08.00"
appcompat = "1.6.1"
material = "1.10.0"
org-jetbrains-kotlin-jvm = "1.9.0"
+ksp = "1.9.21-1.0.15"
+dagger = "2.46.1"
+room = "2.6.1"
[libraries]
core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "core-ktx" }
@@ -31,10 +34,15 @@ ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
material3 = { group = "androidx.compose.material3", name = "material3" }
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
+dagger = { module = "com.google.dagger:dagger", version.ref = "dagger" }
+dagger-compiler = { module = "com.google.dagger:dagger-compiler", version.ref = "dagger" }
+room = { module = "androidx.room:room-runtime", version.ref = "room" }
+room-compiler = { module = "androidx.room:room-compiler", version.ref = "room" }
+room-ktx = { module = "androidx.room:room-ktx", version.ref = "room" }
[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
androidLibrary = { id = "com.android.library", version.ref = "agp" }
org-jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "org-jetbrains-kotlin-jvm" }
-
+ksp = { id = "com.google.devtools.ksp", version.ref = "ksp"}
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 2beff7b..7b82154 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -23,4 +23,3 @@ rootProject.name = "NFS Most Wanted"
include(":app")
include(":devmenu")
include(":devmenu:domain")
-include(":devmenu:data")