Skip to content

Commit

Permalink
feat: 联机排行榜
Browse files Browse the repository at this point in the history
  • Loading branch information
Jim-shop committed May 31, 2023
1 parent 5fc786a commit 0973250
Show file tree
Hide file tree
Showing 22 changed files with 425 additions and 161 deletions.
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ dependencies {
implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
implementation("com.google.android.material:material:1.9.0")
implementation("com.squareup.okhttp3:okhttp:4.10.0")
implementation("com.squareup.moshi:moshi-adapters:1.14.0")
implementation("com.squareup.moshi:moshi-kotlin:1.13.0")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-moshi:2.9.0")
implementation("com.squareup.retrofit2:converter-scalars:2.1.0")
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class AccountDaoSharedPreferences(context: Context) : AccountDao {
editor.putString("account", accountInfo.account)
editor.putString("token", accountInfo.token)
editor.putString(
"loginTime", accountInfo.loginTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)
"loginTime", accountInfo.loginTime.format(DateTimeFormatter.ISO_DATE_TIME)
)
editor.apply()
}
Expand All @@ -33,7 +33,7 @@ class AccountDaoSharedPreferences(context: Context) : AccountDao {
AccountInfo(
account,
token,
LocalDateTime.parse(loginTime, DateTimeFormatter.ISO_LOCAL_DATE_TIME)
LocalDateTime.parse(loginTime, DateTimeFormatter.ISO_DATE_TIME)
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ class LoginDialog(private val loginManager: LoginManager) : AppCompatDialogFragm
this.dialogView = view
MaterialAlertDialogBuilder(activity).apply {
setView(view)
setTitle(R.string.dialog_login_title).setIcon(R.drawable.ic_login_24)
setTitle(R.string.dialog_login_title)
setIcon(R.drawable.ic_login_24)
setPositiveButton(android.R.string.ok, null)
setNeutralButton(R.string.dialog_login_button_register, null)
setNegativeButton(android.R.string.cancel, null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package net.imshit.aircraftwar.data.account

import android.content.Context
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.sync.Semaphore
import java.security.MessageDigest
Expand Down Expand Up @@ -42,7 +41,6 @@ class LoginManager(private val context: Context) {
dao.clear()
} else {
dao.store(value)
Log.e("FFFFF", "store.")
}
}

Expand All @@ -52,6 +50,9 @@ class LoginManager(private val context: Context) {
val token: String?
get() = accountInfo?.token

val name: String?
get() = accountInfo?.account

suspend fun login(account: String, password: String): Boolean {
return try {
val result = LoginApi.api.login(account, encodePassword(password))
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,31 +1,7 @@
package net.imshit.aircraftwar.data.scoreboard

import android.os.Parcel
import android.os.Parcelable
import java.util.Date

data class ScoreInfo(
val name: String, val score: Int, val time: String
) : Parcelable {

constructor(parcel: Parcel) : this(
name = parcel.readString() ?: "", score = parcel.readInt(), time = parcel.readString() ?: ""
)

override fun describeContents(): Int = 0

override fun writeToParcel(dest: Parcel, flags: Int) {
dest.writeString(this.name)
dest.writeInt(this.score)
dest.writeString(this.time)
}

companion object CREATOR : Parcelable.Creator<ScoreInfo> {
override fun createFromParcel(parcel: Parcel): ScoreInfo {
return ScoreInfo(parcel)
}

override fun newArray(size: Int): Array<ScoreInfo?> {
return arrayOfNulls(size)
}
}
}
val id: Int, val name: String, val score: Int, val time: Date
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package net.imshit.aircraftwar.data.scoreboard

import androidx.appcompat.app.AppCompatActivity
import net.imshit.aircraftwar.data.account.LoginManager
import net.imshit.aircraftwar.data.scoreboard.offline.SaveScoreDialog
import net.imshit.aircraftwar.data.scoreboard.offline.ScoreboardDaoSharedPreferences
import net.imshit.aircraftwar.data.scoreboard.online.ScoreboardDaoOnline
import net.imshit.aircraftwar.gui.ScoreboardActivity
import net.imshit.aircraftwar.logic.game.Difficulty
import java.util.Date

class ScoreboardAgent(
private val activity: AppCompatActivity,
private val onlineMode: Boolean,
private val gameMode: Difficulty
) : ScoreboardDao by if (onlineMode) ScoreboardDaoOnline(
activity, gameMode
) else ScoreboardDaoSharedPreferences(activity, gameMode) {
var onFinishCallback: (() -> Unit)? = null
private val loginManager = if (onlineMode) LoginManager(activity) else null

fun requireSave(score: Int) {
if (onlineMode && loginManager != null) {
if (loginManager.isLogin) {
saveAndStart(loginManager.name!!, score)
}
onFinishCallback?.invoke()
} else {
SaveScoreDialog().apply {
onSubmitCallback = { name ->
saveAndStart(name, score)
}
this.onFinishCallback = this@ScoreboardAgent.onFinishCallback
}.show(activity.supportFragmentManager, "save_score")
}
}

private fun saveAndStart(name: String, score: Int) {
this.addItem(
ScoreInfo(0, name, score, Date(System.currentTimeMillis()))
)
ScoreboardActivity.actionStart(this@ScoreboardAgent.activity, gameMode, onlineMode)
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package net.imshit.aircraftwar.data.scoreboard

import java.io.Closeable

sealed interface ScoreboardDao : Closeable {
interface ScoreboardDao {
/**
* 返回最好的k条记录
*
* @param topK 要返回的记录数。=-1时,返回所有记录
* @return 返回记录列表
*/
fun getTopK(topK: Int = -1): List<ScoreInfo>
fun getAll() = getTopK(-1)

/**
* 向计分板添加项目(去重)
Expand All @@ -21,21 +20,7 @@ sealed interface ScoreboardDao : Closeable {
/**
* 从计分板删除项目
*
* @param item 项目
*/
fun deleteItem(item: ScoreInfo)

/**
* 从计分板删除项目
*
* @param indices 内部序号
*/
fun deleteItem(indices: IntArray)

fun clear()

/**
* 关闭计分板数据模型(通常来说意味着缓存写回)
* @param id 内部序号
*/
override fun close()
fun deleteItem(id: Int): Boolean
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package net.imshit.aircraftwar.data.scoreboard.offline

import android.app.Dialog
import android.content.DialogInterface
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatDialog
import androidx.appcompat.app.AppCompatDialogFragment
import androidx.core.widget.doOnTextChanged
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import net.imshit.aircraftwar.R
import net.imshit.aircraftwar.databinding.DialogSaveScoreBinding

class SaveScoreDialog : AppCompatDialogFragment() {
private var dialogView: View? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.dialog_save_score, container, false)
}

var onFinishCallback: (() -> Unit)? = null
var onSubmitCallback: ((String) -> Unit)? = null

override fun onDismiss(dialog: DialogInterface) {
onFinishCallback?.invoke()
super.onDismiss(dialog)
}

override fun onCreateDialog(savedInstanceState: Bundle?): AppCompatDialog {
return activity?.let { activity ->
onCreateView(requireActivity().layoutInflater, null, savedInstanceState)?.let { view ->
this.dialogView = view
MaterialAlertDialogBuilder(activity).apply {
setTitle(R.string.dialog_save_score_title)
setIcon(R.drawable.ic_assignment_turned_in_24)
setPositiveButton(android.R.string.ok, null)
setNegativeButton(android.R.string.cancel, null)
setView(view)
}.create()
}
} ?: throw IllegalStateException("Activity cannot be null")
}

override fun getView(): View? {
return this.dialogView
}

override fun onResume() {
super.onResume()
(dialog as? AlertDialog)?.apply {
val submitButton = getButton(Dialog.BUTTON_POSITIVE)
val cancelButton = getButton((Dialog.BUTTON_NEGATIVE))
view?.let { DialogSaveScoreBinding.bind(it) }?.apply {
dssTiet.doOnTextChanged { text, _, _, _ ->
submitButton.isEnabled = (text?.length in 2..16)
}
submitButton.isEnabled = false

submitButton.setOnClickListener {
onSubmitCallback?.invoke(dssTiet.text.toString())
onFinishCallback?.invoke()
}
cancelButton.setOnClickListener {
onFinishCallback?.invoke()
}
}
}
}
}
Loading

0 comments on commit 0973250

Please sign in to comment.