导入数据集和代码模板。

This commit is contained in:
Cold-Mint 2023-04-21 19:58:42 +08:00
parent 01ec14d156
commit a1a8341d93
21 changed files with 243 additions and 144 deletions

View File

@ -31,8 +31,8 @@ android {
applicationId "com.coldmint.rust.pro"
minSdkVersion 21
targetSdkVersion 33
versionCode 26
versionName "2.1 Bata4(2023-1-28)"
versionCode 27
versionName "2.1 Bata5(2023-4-21)"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -19,6 +19,8 @@ import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.animation.Animation
import android.view.animation.RotateAnimation
import android.widget.*
import androidx.core.view.isVisible
import androidx.core.widget.addTextChangedListener
@ -253,6 +255,39 @@ class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
return FileOperator.writeFile(mModClass.infoFile, resultBuilder.toString())
}
/**
* 执行旋转动画
*/
private fun doRotateAnimation(
view: View,
fromDegrees: Float,
toDegrees: Float, event: ((Boolean) -> Unit)? = null
) {
view.clearAnimation()
// 计算视图中心点的坐标
val centerX = view.width / 2
val centerY = view.height / 2
// 创建旋转动画,并设置中心点为视图中心
val rotateAnimation =
RotateAnimation(fromDegrees, toDegrees, centerX.toFloat(), centerY.toFloat())
rotateAnimation.duration = 150
rotateAnimation.fillAfter = true // 设置FillAfter属性为true使动画结束后保持最后一帧的状态
rotateAnimation.setAnimationListener(object : Animation.AnimationListener {
override fun onAnimationStart(animation: Animation) {
event?.invoke(false)
}
override fun onAnimationEnd(animation: Animation) {
event?.invoke(true)
}
override fun onAnimationRepeat(animation: Animation) {
}
})
// 启动动画
view.startAnimation(rotateAnimation)
}
fun initAction() {
viewBinding.modNameEdit.addTextChangedListener {
viewBinding.modNameInputLayout.isErrorEnabled = false
@ -408,13 +443,15 @@ class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
viewBinding.expandMusicList.isVisible = true
viewBinding.enabledMusic.text = getString(R.string.disabled)
} else {
showMusicConfigurationView(true)
viewBinding.musicListView.isVisible = false
viewBinding.addMusic.isVisible = false
viewBinding.expandMusicList.isVisible = false
viewBinding.enabledMusic.text = getText(R.string.enabled)
viewBinding.musicPathView.text = getString(R.string.no_enabled)
viewBinding.musicPathView.isVisible = true
showMusicConfigurationView(true) {
viewBinding.musicListView.isVisible = false
viewBinding.addMusic.isVisible = false
viewBinding.expandMusicList.clearAnimation()
viewBinding.expandMusicList.isVisible = false
viewBinding.enabledMusic.text = getText(R.string.enabled)
viewBinding.musicPathView.text = getString(R.string.no_enabled)
viewBinding.musicPathView.isVisible = true
}
}
}
@ -452,45 +489,47 @@ class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
* @param hide 隐藏视图
*/
@SuppressLint("StringFormatMatches")
fun showMusicConfigurationView(hide: Boolean) {
fun showMusicConfigurationView(hide: Boolean, func: (() -> Unit)? = null) {
if (hide) {
viewBinding.expandMusicList.setImageResource(R.drawable.animator_expand_off)
mExpandMusicList = false
viewBinding.musicOperation.isVisible = false
viewBinding.musicPathView.isVisible = false
} else {
viewBinding.expandMusicList.setImageResource(R.drawable.animator_expand_on)
mExpandMusicList = true
viewBinding.musicOperation.isVisible = true
val musicFolder = musicFolder
if (!musicFolder.exists()) {
musicFolder.mkdirs()
}
val files = ArrayList<File>()
val fileArray = musicFolder.listFiles()
if (fileArray.isNotEmpty()) {
for (f in fileArray) {
if (FileOperator.getFileType(f) == "ogg") {
files.add(f)
}
doRotateAnimation(viewBinding.expandMusicList, 180f, 360f) {
if (it) {
mExpandMusicList = false
viewBinding.musicOperation.isVisible = false
viewBinding.musicPathView.isVisible = false
func?.invoke()
}
}
val mapAndMusicAdapter = MapAndMusicAdapter(this, files, true)
val layoutManager = StableLinearLayoutManager(this@EditModInfoActivity)
mapAndMusicAdapter.setItemChangeEvent { changeType, i, file, i2 ->
viewBinding.musicPathView.text =
String.format(getString(R.string.filenum), i2)
}
viewBinding.musicListView.layoutManager = layoutManager
viewBinding.musicListView.adapter = mapAndMusicAdapter
viewBinding.musicPathView.isVisible = true
viewBinding.musicPathView.text = String.format(getString(R.string.filenum), files.size)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
(viewBinding.expandMusicList.drawable as AnimatedVectorDrawable).start()
} else {
(viewBinding.expandMusicList.drawable as AnimatedVectorDrawableCompat).start()
doRotateAnimation(viewBinding.expandMusicList, 0f, 180f) {
mExpandMusicList = true
viewBinding.musicOperation.isVisible = true
val musicFolder = musicFolder
if (!musicFolder.exists()) {
musicFolder.mkdirs()
}
val files = ArrayList<File>()
val fileArray = musicFolder.listFiles()
if (fileArray.isNotEmpty()) {
for (f in fileArray) {
if (FileOperator.getFileType(f) == "ogg") {
files.add(f)
}
}
}
val mapAndMusicAdapter = MapAndMusicAdapter(this, files, true)
val layoutManager = StableLinearLayoutManager(this@EditModInfoActivity)
mapAndMusicAdapter.setItemChangeEvent { changeType, i, file, i2 ->
viewBinding.musicPathView.text =
String.format(getString(R.string.filenum), i2)
}
viewBinding.musicListView.layoutManager = layoutManager
viewBinding.musicListView.adapter = mapAndMusicAdapter
viewBinding.musicPathView.isVisible = true
viewBinding.musicPathView.text =
String.format(getString(R.string.filenum), files.size)
func?.invoke()
}
}
}
@ -506,12 +545,14 @@ class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
viewBinding.mapPathView.isVisible = false
viewBinding.enabledMap.text = getString(R.string.disabled)
} else {
showMapConfigurationView(true)
viewBinding.expandMapList.isVisible = false
viewBinding.addMap.isVisible = false
viewBinding.enabledMap.text = getText(R.string.enabled)
viewBinding.mapPathView.text = getString(R.string.no_enabled)
viewBinding.mapPathView.isVisible = true
showMapConfigurationView(true) {
viewBinding.expandMapList.clearAnimation()
viewBinding.expandMapList.isVisible = false
viewBinding.addMap.isVisible = false
viewBinding.enabledMap.text = getText(R.string.enabled)
viewBinding.mapPathView.text = getString(R.string.no_enabled)
viewBinding.mapPathView.isVisible = true
}
}
}
@ -535,44 +576,48 @@ class EditModInfoActivity : BaseActivity<ActivityEditModInfoBinding>() {
* @param hide 隐藏视图
*/
@SuppressLint("StringFormatMatches")
fun showMapConfigurationView(hide: Boolean) {
fun showMapConfigurationView(hide: Boolean, func: (() -> Unit)? = null) {
if (hide) {
viewBinding.expandMapList.setImageResource(R.drawable.animator_expand_off)
mExpandMapList = false
viewBinding.mapOperation.isVisible = false
viewBinding.mapPathView.isVisible = false
} else {
viewBinding.expandMapList.setImageResource(R.drawable.animator_expand_on)
mExpandMapList = true
viewBinding.mapOperation.isVisible = true
val mapFolder = mapFolder
if (!mapFolder.exists()) {
mapFolder.mkdirs()
}
val files = ArrayList<File>()
val fileArray = mapFolder.listFiles()
if (fileArray.isNotEmpty()) {
for (f in fileArray) {
if (FileOperator.getFileType(f) == "tmx") {
files.add(f)
}
doRotateAnimation(viewBinding.expandMapList, 180f, 360f) {
if (it) {
mExpandMapList = false
viewBinding.mapOperation.isVisible = false
viewBinding.mapPathView.isVisible = false
func?.invoke()
}
}
val mapAndMapAdapter = MapAndMusicAdapter(this, files, false)
val layoutManager = StableLinearLayoutManager(this@EditModInfoActivity)
mapAndMapAdapter.setItemChangeEvent { changeType, i, file, i2 ->
viewBinding.mapPathView.text =
String.format(getString(R.string.filenum), i2)
}
viewBinding.mapListView.layoutManager = layoutManager
viewBinding.mapListView.adapter = mapAndMapAdapter
viewBinding.mapPathView.isVisible = true
viewBinding.mapPathView.text = String.format(getString(R.string.filenum), files.size)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
(viewBinding.expandMapList.drawable as AnimatedVectorDrawable).start()
} else {
(viewBinding.expandMapList.drawable as AnimatedVectorDrawableCompat).start()
doRotateAnimation(viewBinding.expandMapList, 0f, 180f) {
if (it) {
mExpandMapList = true
viewBinding.mapOperation.isVisible = true
val mapFolder = mapFolder
if (!mapFolder.exists()) {
mapFolder.mkdirs()
}
val files = ArrayList<File>()
val fileArray = mapFolder.listFiles()
if (fileArray.isNotEmpty()) {
for (f in fileArray) {
if (FileOperator.getFileType(f) == "tmx") {
files.add(f)
}
}
}
val mapAndMapAdapter = MapAndMusicAdapter(this, files, false)
val layoutManager = StableLinearLayoutManager(this@EditModInfoActivity)
mapAndMapAdapter.setItemChangeEvent { changeType, i, file, i2 ->
viewBinding.mapPathView.text =
String.format(getString(R.string.filenum), i2)
}
viewBinding.mapListView.layoutManager = layoutManager
viewBinding.mapListView.adapter = mapAndMapAdapter
viewBinding.mapPathView.isVisible = true
viewBinding.mapPathView.text =
String.format(getString(R.string.filenum), files.size)
func?.invoke()
}
}
}
}

View File

@ -260,11 +260,16 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
val codeTable = menu.findItem(R.id.code_table)
val mod = menu.findItem(R.id.mod_item)
val community = menu.findItem(R.id.community_item)
val group = menu.findItem(R.id.user_group)
group.setOnMenuItemClickListener {
viewBinding.drawerlayout.closeDrawer((GravityCompat.START))
val userGroupFragment = UserGroupFragment()
userGroupFragment.show(supportFragmentManager, "userGroup")
// val group = menu.findItem(R.id.user_group)
// group.setOnMenuItemClickListener {
// viewBinding.drawerlayout.closeDrawer((GravityCompat.START))
// val userGroupFragment = UserGroupFragment()
// userGroupFragment.show(supportFragmentManager, "userGroup")
// false
// }
val gitHub = menu.findItem(R.id.github)
gitHub.setOnMenuItemClickListener {
AppOperator.useBrowserAccessWebPage(this,"https://github.com/Cold-Mint/RustAssistant")
false
}
// val help = menu.findItem(R.id.help)

View File

@ -77,11 +77,11 @@ class SettingsActivity : BaseActivity<ActivitySettingsBinding>() {
true
}
val obtainSourceCode = manager.findPreference<PreferenceScreen>(requireContext().getString(R.string.setting_obtain_source_code))
obtainSourceCode!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {
AppOperator.useBrowserAccessWebPage(requireContext(),"https://github.com/Cold-Mint/RustAssistant")
true
}
// val obtainSourceCode = manager.findPreference<PreferenceScreen>(requireContext().getString(R.string.setting_obtain_source_code))
// obtainSourceCode!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {
// AppOperator.useBrowserAccessWebPage(requireContext(),"https://github.com/Cold-Mint/RustAssistant")
// true
// }
val game = manager.findPreference<PreferenceScreen>("set_game_pack")
game!!.onPreferenceClickListener = Preference.OnPreferenceClickListener {

View File

@ -56,6 +56,9 @@ class CommentAdapter(context: Context, dataList: MutableList<WebModCommentData.D
} else {
data.time + " " + data.location
}
viewBinding.thumbUpImageView.setOnClickListener {
Snackbar.make(viewBinding.thumbUpImageView,R.string.temporarily_unavailable,Snackbar.LENGTH_SHORT).show()
}
viewBinding.shareImageView.setOnClickListener {
AppOperator.shareText(context, context.getString(R.string.share_message), data.content);
}

View File

@ -1,9 +1,12 @@
package com.coldmint.rust.pro.adapters
import android.content.Context
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import com.coldmint.rust.core.DataSet
import com.coldmint.rust.core.tool.AppOperator
import com.coldmint.rust.pro.R
import com.coldmint.rust.pro.base.BaseAdapter
import com.coldmint.rust.pro.databinding.DatabaseItemBinding
@ -26,10 +29,27 @@ class DataSetAdapter(context: Context, dataList: MutableList<DataSet>) :
) {
val dataBaseManifest = data.getDataBaseManifest()
viewBinding.databaseNameView.text = data.getDataSetName()
if (dataBaseManifest != null) {
viewBinding.databaseIntroduce.text = dataBaseManifest.describe
viewBinding.databaseOther.text =
dataBaseManifest.author + "|" + dataBaseManifest.versionName
val appVersion = AppOperator.getAppVersionNum(context)
if (dataBaseManifest == null) {
viewBinding.databaseIntroduce.text = context.getString(R.string.dataset_not_exist)
viewBinding.databaseOther.text = ""
viewBinding.databaseUse.isEnabled = false
} else {
Log.d(
"DataSetAdapter",
"appVersion: ${appVersion} name: ${data.getDataSetName()} minVersion: ${dataBaseManifest.minAppVersion}"
)
if (dataBaseManifest.minAppVersion <= appVersion) {
viewBinding.databaseIntroduce.text = dataBaseManifest.describe
viewBinding.databaseOther.text =
dataBaseManifest.author + "|" + dataBaseManifest.versionName
viewBinding.databaseUse.isEnabled = true
} else {
viewBinding.databaseUse.isEnabled = false
viewBinding.databaseIntroduce.text =
context.getString(R.string.dataset_minversion_low)
viewBinding.databaseOther.text = ""
}
}
}

View File

@ -66,6 +66,9 @@ class DynamicAdapter(context: Context, dataList: MutableList<DynamicItemDataBean
viewBinding.shareImageView.setOnClickListener {
AppOperator.shareText(context, context.getString(R.string.share_message), data.content);
}
viewBinding.thumbUpImageView.setOnClickListener {
Snackbar.make(viewBinding.thumbUpImageView,R.string.temporarily_unavailable,Snackbar.LENGTH_SHORT).show()
}
viewBinding.moreImageView.setOnClickListener { view ->
val menu = GlobalMethod.createPopMenu(view)
menu.menu.add(R.string.copy)

View File

@ -109,6 +109,21 @@ class ModCommentsFragment(val modId: String) : BaseFragment<FragmentModCommentsB
loadCommentList(modId)
}
fun commentSizeChange(size: Int){
if (size == 0){
viewBinding.titleView.text = getString(R.string.discussion)
viewBinding.recyclerView.isVisible = false
viewBinding.noContentLayout.isVisible = true
}else{
viewBinding.titleView.text =
getString(R.string.discussion) + "(" + size + ")"
viewBinding.recyclerView.isVisible = true
viewBinding.noContentLayout.isVisible = false
}
}
/**
* 加载评论列表
* @param modId String
@ -116,7 +131,7 @@ class ModCommentsFragment(val modId: String) : BaseFragment<FragmentModCommentsB
fun loadCommentList(modId: String, useLinearProgressIndicator: Boolean = true) {
val key = "加载评论列表"
if (useLinearProgressIndicator) {
viewBinding.linearProgressIndicator.isVisible = true
viewBinding.linearProgressIndicator.visibility = View.VISIBLE
}
WebMod.instance.getCommentsList(modId, object : ApiCallBack<WebModCommentData> {
override fun onResponse(t: WebModCommentData) {
@ -124,34 +139,34 @@ class ModCommentsFragment(val modId: String) : BaseFragment<FragmentModCommentsB
if (list.isNullOrEmpty()) {
DebugHelper.printLog(key, "为空", isError = true)
if (useLinearProgressIndicator) {
viewBinding.linearProgressIndicator.isVisible = false
viewBinding.linearProgressIndicator.visibility = View.INVISIBLE
}
viewBinding.titleView.text = getString(R.string.discussion)
viewBinding.recyclerView.isVisible = false
viewBinding.noContentLayout.isVisible = true
commentSizeChange(0)
} else {
DebugHelper.printLog(key, "${list.size}条数据")
viewBinding.titleView.text =
getString(R.string.discussion) + "(" + list.size + ")"
commentSizeChange(list.size)
if (useLinearProgressIndicator) {
viewBinding.linearProgressIndicator.isVisible = false
viewBinding.linearProgressIndicator.visibility = View.INVISIBLE
}
viewBinding.recyclerView.isVisible = true
viewBinding.noContentLayout.isVisible = false
val adapter = CommentAdapter(requireContext(), list)
adapter.setItemEvent { i, itemCommentBinding, viewHolder, data ->
itemCommentBinding.iconView.setOnClickListener {
gotoUserPage(data.account)
}
}
viewBinding.recyclerView.adapter = adapter
adapter.setItemChangeEvent { changeType, i, data, i2 ->
viewBinding.titleView.text =
getString(R.string.discussion) + "(" + i2 + ")"
commentSizeChange(i2)
}
viewBinding.recyclerView.adapter = adapter
}
}
override fun onFailure(e: Exception) {
DebugHelper.printLog(key, "加载失败", isError = true)
if (useLinearProgressIndicator) {
viewBinding.linearProgressIndicator.isVisible = false
viewBinding.linearProgressIndicator.visibility = View.INVISIBLE
}
viewBinding.titleView.text = getString(R.string.discussion)
viewBinding.recyclerView.isVisible = false

View File

@ -347,15 +347,9 @@ class StartViewModel(application: Application) : BaseAndroidViewModel(applicatio
*/
private fun initRes() {
try {
val language = Locale.getDefault().language
DebugHelper.printLog("初始化资源", "语言" + language)
if (language == "zh") {
unzipDataSet("dataBase.rdb", true)
unzipDataSet("dataBase_en.rdb")
} else {
unzipDataSet("dataBase.rdb")
unzipDataSet("dataBase_en.rdb", true)
}
// val language = Locale.getDefault().language
// DebugHelper.printLog("初始化资源", "语言" + language)
unzipDataSet("dataBase_v2.2.0.rdb", true)
val defaultValues = File(context.filesDir.absolutePath + "/values.json")
if (!defaultValues.exists()) {
@ -368,7 +362,7 @@ class StartViewModel(application: Application) : BaseAndroidViewModel(applicatio
} catch (e: Exception) {
e.printStackTrace()
}
importingTemplatePackage("baseTemplate.rp")
importingTemplatePackage("baseTemplate_v2.0.rp")
}

View File

@ -51,9 +51,9 @@
<!--模组图标-->
<LinearLayout
android:layout_marginTop="8dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:gravity="center_vertical">
<TextView
@ -65,20 +65,19 @@
<com.google.android.material.card.MaterialCardView
style="@style/Widget.Material3.CardView.Filled"
android:layout_width="wrap_content"
android:layout_marginLeft="8dp"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:layout_marginLeft="8dp">
<ImageView
android:scaleType="centerCrop"
android:id="@+id/iconView"
android:layout_width="72dp"
android:layout_height="72dp"
android:scaleType="centerCrop"
android:src="@drawable/image" />
</com.google.android.material.card.MaterialCardView>
</LinearLayout>
<com.google.android.material.textfield.TextInputLayout
@ -174,12 +173,14 @@
android:text="@string/add" />
<ImageView
android:visibility="gone"
android:id="@+id/expandMusicList"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_below="@id/musicPathView"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignTop="@id/addMusic"
android:layout_alignBottom="@id/enabledMusic"
android:layout_alignParentEnd="true"
android:padding="2dp"
android:src="@drawable/expand_icon"
app:tint="?android:colorControlNormal" />
@ -260,12 +261,14 @@
android:text="@string/add" />
<ImageView
android:visibility="gone"
android:id="@+id/expandMapList"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_below="@id/mapPathView"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignTop="@id/addMap"
android:layout_alignBottom="@id/enabledMap"
android:layout_alignParentEnd="true"
android:padding="2dp"
android:src="@drawable/expand_icon"
app:tint="?android:colorControlNormal" />

View File

@ -33,12 +33,12 @@
style="@style/TextAppearance.Material3.BodySmall"/>
<Button
style="@style/Widget.Material3.Button.OutlinedButton"
android:id="@+id/database_use"
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="使用"/>
android:layout_alignParentEnd="true"
android:layout_centerInParent="true"
android:text="使用" />
</RelativeLayout>

View File

@ -41,7 +41,7 @@
android:id="@+id/linearProgressIndicator"
android:layout_width="match_parent"
android:layout_marginTop="8dp"
android:visibility="gone"
android:visibility="invisible"
android:layout_height="wrap_content"
android:indeterminate="true" />

View File

@ -55,10 +55,15 @@
android:title="@string/set_up" />
<!-- <item-->
<!-- android:id="@+id/user_group"-->
<!-- android:icon="@drawable/ic_outline_free_breakfast_24"-->
<!-- android:title="@string/user_group" />-->
<item
android:id="@+id/user_group"
android:icon="@drawable/ic_outline_free_breakfast_24"
android:title="@string/user_group" />
android:id="@+id/github"
android:icon="@drawable/github"
android:title="@string/github" />
<item
android:id="@+id/rust_api"
android:icon="@drawable/outline_book_24"

View File

@ -420,6 +420,7 @@
<string name="unable_cut">无法剪切此文件夹,该文件夹内有文件正在使用。</string>
<string name="unable_del">无法删除此文件夹,该文件夹内有文件正在使用。</string>
<string name="recovery_prompt">已将\"%1$s\"移动至回收站。</string>
<string name="temporarily_unavailable">暂不可用,请等待下个版本!</string>
<string name="recoverying_prompt">正在移动\"%1$s\"...</string>
<string name="open_directory_of_file">打开文件所在目录</string>
<string name="unable_to_detect">您的模组可能无法被游戏检查。</string>
@ -962,4 +963,7 @@
<string name="private_mod">私有</string>
<string name="minVersion">最低游戏版本</string>
<string name="thumbs_up">点赞</string>
<string name="github">GitHub</string>
<string name="dataset_not_exist">DataBaseManifest.json不存在无法加载信息。</string>
<string name="dataset_minversion_low">此数据集仅适用于旧版本助手。</string>
</resources>

View File

@ -266,10 +266,10 @@
app:key="developerModeGroup"
app:title="@string/sync_header">
<PreferenceScreen
app:key="@string/setting_obtain_source_code"
android:summary="@string/obtain_source_code_msg"
app:title="@string/obtain_source_code"/>
<!-- <PreferenceScreen-->
<!-- app:key="@string/setting_obtain_source_code"-->
<!-- android:summary="@string/obtain_source_code_msg"-->
<!-- app:title="@string/obtain_source_code"/>-->
<PreferenceScreen
app:key="@string/setting_see_error_info"

View File

@ -18,7 +18,9 @@ data class DataBaseManifest(
@SerializedName("versionName")
val versionName: String,
@SerializedName("versionNumber")
val versionNumber: Int
val versionNumber: Int,
@SerializedName("minAppVersion")
val minAppVersion:Int = Int.MAX_VALUE
) {
data class Tables(
@SerializedName("chain_inspection")