修改密码

This commit is contained in:
coldmint 2022-08-26 16:47:55 +08:00
parent 5497ed86ef
commit 212cd4f041
14 changed files with 47 additions and 2686 deletions

View File

@ -0,0 +1,11 @@
package com.coldmint.rust.pro
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
class ChangePasswordActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_change_password)
}
}

View File

@ -1,54 +0,0 @@
package com.coldmint.rust.pro.adapters
import android.content.Context
import android.text.SpannableString
import androidx.recyclerview.widget.RecyclerView
import android.view.ViewGroup
import android.view.LayoutInflater
import com.coldmint.rust.pro.R
import android.text.method.LinkMovementMethod
import android.view.View
import android.widget.TextView
import androidx.core.view.isVisible
import com.bumptech.glide.Glide
import com.coldmint.rust.core.AnalysisResult
import com.coldmint.rust.pro.base.BaseAdapter
import com.coldmint.rust.pro.databinding.LogItemBinding
import com.coldmint.rust.pro.tool.GlobalMethod
//编译日志适配器
class CompileLogAdapter( context: Context, analysisResults: MutableList<AnalysisResult>) :
BaseAdapter<LogItemBinding, AnalysisResult>(context, analysisResults) {
override fun getViewBindingObject(
layoutInflater: LayoutInflater,
parent: ViewGroup,
viewType: Int
): LogItemBinding {
return LogItemBinding.inflate(layoutInflater, parent, false)
}
override fun onBingView(
data: AnalysisResult,
viewBinding: LogItemBinding,
viewHolder: ViewHolder<LogItemBinding>,
position: Int
) {
// viewBinding.logInfoView.movementMethod = LinkMovementMethod.getInstance()
viewBinding.logInfoView.text = data.errorInfo
if (data.icon == null) {
viewBinding.imageView.isVisible = false
} else {
viewBinding.imageView.isVisible = true
Glide.with(context).load(data.icon).apply(GlobalMethod.getRequestOptions()).into(viewBinding.imageView)
}
val temFun = data.function
if (temFun != null) {
viewBinding.logInfoView.setOnClickListener {
temFun.invoke(viewBinding.root)
}
}
}
}

View File

@ -1,908 +1,4 @@
package com.coldmint.rust.pro.adapters package com.coldmint.rust.pro.adapters
class ModActionAdapter {
import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityOptions
import android.content.Context
import com.google.android.material.bottomsheet.BottomSheetDialog
import android.widget.BaseAdapter
import com.coldmint.rust.core.dataBean.ModConfigurationData
import android.view.ViewGroup
import android.view.LayoutInflater
import android.widget.TextView
import com.coldmint.rust.core.tool.AppOperator
import android.widget.Toast
import android.widget.EditText
import android.os.Bundle
import android.content.Intent
import com.coldmint.rust.pro.tool.AppSettings
import com.afollestad.materialdialogs.MaterialDialog
import android.content.DialogInterface
import android.os.Handler
import android.os.Looper
import android.view.View
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AlertDialog
import androidx.core.content.ContentProviderCompat.requireContext
import com.coldmint.dialog.InputDialog
import com.coldmint.rust.core.*
import com.google.android.material.snackbar.Snackbar
import com.coldmint.rust.core.dataBean.CompileConfiguration
import com.coldmint.rust.core.dataBean.ModErrorReport
import com.coldmint.rust.core.database.code.ValueTypeInfo
import com.coldmint.rust.core.interfaces.*
import com.coldmint.rust.core.tool.FileFinder2
import com.coldmint.rust.core.tool.FileOperator
import com.coldmint.rust.pro.*
import com.coldmint.rust.pro.R
import com.coldmint.rust.pro.databinding.ModActionItemBinding
import com.coldmint.rust.pro.fragments.ModFragment
import com.coldmint.rust.pro.tool.GlobalMethod
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.gson.Gson
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.io.File
import java.lang.NumberFormatException
import java.util.*
import java.util.concurrent.Executor
import java.util.concurrent.Executors
import java.util.zip.ZipEntry
import kotlin.collections.ArrayList
/**
* @author Cold Mint
*/
class ModActionAdapter(
private val mContext: Context,
private val mdata: List<String>,
private val mModpath: String,
private val mModFragment: ModFragment,
private val mBottomSheetDialog: BottomSheetDialog
) : BaseAdapter() {
private var modConfigurationData: ModConfigurationData? = null
private val handler = Handler(Looper.getMainLooper())
/**
* 设置模组配置信息
*
* @param modConfigurationData 模组配置
*/
fun setModConfigurationData(modConfigurationData: ModConfigurationData?) {
this.modConfigurationData = modConfigurationData
}
override fun getCount(): Int {
return mdata.size
}
override fun getItem(position: Int): Any {
return mdata[position]
}
override fun getItemId(position: Int): Long {
return position.toLong()
}
@SuppressLint("ViewHolder")
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
val dialogView = ModActionItemBinding.inflate(LayoutInflater.from(mContext), parent, false)
//LayoutInflater.from(mContext).inflate(R.layout.mod_action_item, parent, false)
val textView = dialogView.operation
val itemName = mdata[position]
textView.text = itemName
dialogView.root.setOnClickListener {
mBottomSheetDialog.cancel()
when (itemName) {
mContext.getString(R.string.manages_files) -> {
managesFileItem()
}
mContext.getString(R.string.packmod) -> {
packmodItem()
}
mContext.getString(R.string.share_mod) -> {
shareItem()
}
mContext.getString(R.string.mod_action10) -> {
repairItem()
}
mContext.getString(R.string.optimization) -> {
optimizationItem()
}
mContext.getString(R.string.mod_action1) -> {
editUnitItem()
}
mContext.getString(R.string.mod_action8) -> {
unzipItem()
}
mContext.getString(R.string.mod_action2) -> {
editInfoItem()
}
mContext.getString(R.string.rename) -> {
renameItem()
}
mContext.getString(R.string.release) -> {
releaseItem()
}
mContext.getString(R.string.work_of_home_page) -> {
openHomePage()
}
mContext.getString(R.string.global_operations) -> {
val intent = Intent(mContext, GlobalOperationsActivity::class.java)
intent.putExtra("modPath", mModpath)
mContext.startActivity(intent)
}
mContext.getString(R.string.generate_error_report) -> {
//而coroutineScope会挂起所在的协程直至其内部任务(包括子协程)执行完成,它不会阻塞所在的线程。
//coroutineScope是一个挂起函数它被挂起后会转而执行之前的子协程。
val scope = CoroutineScope(Job())
scope.launch {
//启动协程
var dialog: MaterialDialog? = null
handler.post {
dialog = MaterialDialog(mContext).show {
title(R.string.generate_error_report).message(R.string.loading_data)
.positiveButton(R.string.dialog_ok).cancelable(false)
}
}
val gson = Gson()
val modClass = ModClass(File(mModpath))
val modErrorReport = ModErrorReport(modClass.modFile.absolutePath)
val outputFolder =
File(AppSettings.dataRootDirectory + "/modErrorReport/" + modClass.modName)
val warningFolder = File(outputFolder.absolutePath + "/warning")
if (!warningFolder.exists()) {
warningFolder.mkdirs()
}
val errorFolder = File(outputFolder.absolutePath + "/error")
if (!errorFolder.exists()) {
errorFolder.mkdirs()
}
val fileFinder2 = FileFinder2(modClass.modFile)
fileFinder2.findMode = true
fileFinder2.asRe = true
fileFinder2.findRule = modConfigurationData?.sourceFileFilteringRule
?: ".+\\.ini|.+\\.template"
val codeCompiler2 = CodeCompiler2.getInstance(mContext)
val apkFolder = GameSynchronizer.getPackAgeFolder(
mContext, AppSettings.getValue(
AppSettings.Setting.GamePackage,
GlobalMethod.DEFAULT_GAME_PACKAGE
)
)
fileFinder2.setFinderListener(object : FileFinderListener {
override fun whenFindFile(file: File): Boolean {
val code = FileOperator.readFile(file)
if (code != null) {
handler.post {
dialog?.message(text = file.absolutePath)
}
codeCompiler2.translation(
code,
object : CodeTranslatorListener {
override fun beforeTranslate() {
}
override fun onTranslateComplete(code: String) {
codeCompiler2.compile(
code,
CompileConfiguration(
mContext,
OpenedSourceFile(file),
modClass, apkFolder
), object : CodeCompilerListener {
override fun onCompilationComplete(
compileConfiguration: CompileConfiguration,
code: String
) {
//如果有错误或警告那么创建文件
if (compileConfiguration.getWarningNumber() > 0) {
val outFile =
File(
warningFolder.absolutePath +
"/" + FileOperator.getPrefixName(
file.name
) + ".json"
)
val warningList =
ArrayList<String>()
compileConfiguration.getAnalysisResult()
.forEach {
if (it.errorType == CompileConfiguration.ErrorType.Warning) {
warningList.add("" + it.lineData + "" + it.errorInfo)
}
}
FileOperator.writeFile(
outFile,
gson.toJson(warningList)
)
}
if (compileConfiguration.getErrorNumber() > 0) {
val outFile =
File(
errorFolder.absolutePath +
"/" + FileOperator.getPrefixName(
file.name
) + ".json"
)
val errorList =
ArrayList<String>()
compileConfiguration.getAnalysisResult()
.forEach {
if (it.errorType == CompileConfiguration.ErrorType.Error) {
errorList.add("" + it.lineData + "" + it.errorInfo)
}
}
FileOperator.writeFile(
outFile,
gson.toJson(errorList)
)
}
modErrorReport.addFileReport(
compileConfiguration
)
}
override fun beforeCompilation() {
}
override fun onClickKeyNotFoundItem(
lineNum: Int,
columnNum: Int,
view: View,
code: String,
section: String
) {
}
override fun onClickValueTypeErrorItem(
lineNum: Int,
columnNum: Int,
view: View,
valueType: ValueTypeInfo
) {
}
override fun onClickSectionIndexError(
lineNum: Int,
columnNum: Int,
view: View,
sectionName: String
) {
}
override fun onClickResourceErrorItem(
lineNum: Int,
columnNum: Int,
view: View,
resourceFile: File
) {
}
override fun onClickSectionErrorItem(
lineNum: Int,
view: View,
displaySectionName: String
) {
}
override fun onClickSynchronizationGame(
lineNum: Int,
columnNum: Int,
view: View
) {
}
override fun onClickSectionNameErrorItem(
lineNum: Int,
columnNum: Int,
view: View,
sectionName: String,
symbolIndex: Int?,
needName: Boolean
) {
}
override fun onClickCodeIndexErrorItem(
lineNum: Int,
view: View,
sectionName: String
) {
}
override fun onShowCompilationResult(code: String): Boolean {
return true
}
}
)
}
})
}
return true
}
override fun whenFindFolder(folder: File): Boolean {
return true
}
})
val a = fileFinder2.onStart()
FileOperator.writeFile(
File(outputFolder.absolutePath + "/list.json"),
gson.toJson(modErrorReport)
)
handler.post {
dialog?.message(R.string.generate_error_report_ok)
}
}
}
else -> {
if (modConfigurationData != null) {
val title = modConfigurationData!!.updateTitle
if ((title == itemName)) {
val type = modConfigurationData!!.updateType
if ((type == ModConfigurationManager.qqGroupType)) {
try {
val integer = Integer.valueOf(
modConfigurationData!!.updateLink
)
val result = AppOperator.openQQGroupCard(
mContext, integer
)
if (!result) {
Toast.makeText(
mContext,
R.string.open_qq_group_card_error,
Toast.LENGTH_SHORT
).show()
}
} catch (e: NumberFormatException) {
Toast.makeText(
mContext,
R.string.qq_group_error,
Toast.LENGTH_SHORT
).show()
}
} else if ((type == ModConfigurationManager.webLinkType)) {
val result = AppOperator.useBrowserAccessWebPage(
mContext, modConfigurationData!!.updateLink
)
if (!result) {
Toast.makeText(
mContext,
R.string.not_found_activity,
Toast.LENGTH_SHORT
).show()
}
} else {
Toast.makeText(
mContext,
R.string.update_type_error,
Toast.LENGTH_SHORT
).show()
}
}
} else {
Toast.makeText(mContext, "没有设置事件", Toast.LENGTH_SHORT).show()
}
}
}
}
return dialogView.root
}
/**
* 打开作品首页
*/
private fun openHomePage() {
val modId = modConfigurationData?.modId
if (modId != null) {
val bundle = Bundle()
bundle.putString("modId", modId)
bundle.putString("modName", modId)
val intent = Intent(mContext, WebModInfoActivity::class.java)
intent.putExtra("data", bundle)
mContext.startActivity(intent)
}
}
/**
* 点击了发布
*/
private fun releaseItem() {
val releaseBundle = Bundle()
val modId = modConfigurationData?.modId
releaseBundle.putString("modPath", mModpath)
if (modId == null) {
releaseBundle.putString("mode", "firstReleaseMode")
} else {
releaseBundle.putString("mode", "loadMode")
releaseBundle.putString("modId", modId)
}
val intent = Intent(mContext, ReleaseModActivity::class.java)
intent.putExtra("data", releaseBundle)
mContext.startActivity(intent)
}
/**
* 点击了重命名
*/
private fun renameItem() {
val mod_file = File(mModpath)
val oldname = ModClass(mod_file).modName
InputDialog(mContext).setInputCanBeEmpty(false).setTitle(R.string.rename).setMaxNumber(255)
.setHint(R.string.file_name).setText(oldname)
.setPositiveButton(R.string.dialog_ok) { string ->
if (string.isNotEmpty() && string != oldname) {
val newFile = File(FileOperator.getSuperDirectory(mod_file) + "/" + string)
mod_file.renameTo(newFile)
mModFragment.loadModList()
}
true
}.setNegativeButton(R.string.dialog_cancel) {
}.setCancelable(false).show()
}
/**
* 点击了编辑信息
*/
private fun editInfoItem() {
val fileBundle = Bundle()
val infoIntent = Intent(mContext, EditModInfoActivity::class.java)
// val modClass = ModClass(File(mModpath))
//fileBundle.putString("infoPath", modClass.getInfoFile().getAbsolutePath());
fileBundle.putString("modPath", mModpath)
infoIntent.putExtra("data", fileBundle)
mContext.startActivity(infoIntent)
}
/**
* 点击了解压
*/
private fun unzipItem() {
val uzipThread = UnzipThread()
uzipThread.start()
}
/**
* 点击编辑单位
*/
private fun editUnitItem() {
val bundle = Bundle()
val uintent = Intent(mContext, UnitsActivity::class.java)
bundle.putString("path", mModpath)
uintent.putExtra("data", bundle)
mContext.startActivity(uintent)
}
/**
* 点击了管理文件
*/
private fun managesFileItem() {
val managesIntent = Intent(mContext, FileManagerActivity::class.java)
val configurationBundle = Bundle()
managesIntent.putExtra("data", configurationBundle)
configurationBundle.putString("type", "default")
configurationBundle.putString("path", mModpath)
mContext.startActivity(managesIntent)
}
/**
* 点击了打包
*/
private fun packmodItem() {
val packIntent = Intent(mContext, PackActivity::class.java)
val packData = Bundle()
packIntent.putExtra("data", packData)
packData.putString("modPath", mModpath)
mContext.startActivity(packIntent)
}
/**
* 点击了优化
*/
private fun optimizationItem() {
val oBundle = Bundle()
oBundle.putString("modPath", mModpath)
val intent = Intent(mContext, OptimizeActivity::class.java)
intent.putExtra("data", oBundle)
mContext.startActivity(intent)
}
/**
* 点击修复项目时
*/
private fun repairItem() {
val repairThread = RepairThread()
repairThread.start()
}
/**
* 点击分享项目时
*/
private fun shareItem() {
val file = File(mModpath)
if (file.isDirectory) {
val needShowTip = AppSettings.getValue(AppSettings.Setting.ShareTip, true)
if (needShowTip) {
val materialDialog = MaterialDialog(mContext, MaterialDialog.DEFAULT_BEHAVIOR)
materialDialog.title(R.string.packmod, null)
materialDialog.message(R.string.share_tip, null, null)
materialDialog.positiveButton(
R.string.dialog_ok,
null
) { materialDialog: MaterialDialog? ->
packShare(file)
null
}
materialDialog.negativeButton(
R.string.no_longer_prompt,
null
) { materialDialog: MaterialDialog? ->
AppSettings.setValue(AppSettings.Setting.ShareTip, false)
packShare(file)
null
}
materialDialog.show()
} else {
packShare(file)
}
} else {
FileOperator.shareFile(mContext, file)
}
}
/**
* 打包分享事件对话框
*
* @param file 文件夹
*/
private fun packShare(file: File) {
val modClass = ModClass(file)
val materialDialog = MaterialDialog(mContext)
Thread(object : Runnable {
override fun run() {
handler.post {
materialDialog.title(R.string.packmod).message(
text =
String.format(
mContext.getString(R.string.dialog_packing),
modClass.modName
)
).cancelable(false).positiveButton(R.string.dialog_close2) {
Snackbar.make(
(mModFragment.view)!!,
R.string.dialog_close_tip3,
Snackbar.LENGTH_SHORT
).show()
}.show()
}
val cacheDirectory = File(mContext.cacheDir.absolutePath + "/share/mod")
if (!cacheDirectory.exists()) {
cacheDirectory.mkdirs()
}
val toFile =
File(cacheDirectory.absolutePath + "/" + file.name + ".rwmod")
val compressionManager = CompressionManager.instance
compressionManager.compression(file, toFile, object : CompressionListener {
override fun whenCompressionFile(file: File): Boolean {
handler.post {
materialDialog.message(
text =
String.format(
mContext.getString(R.string.dialog_packing),
file.name
)
)
}
return true
}
override fun whenCompressionFolder(folder: File): Boolean {
handler.post {
materialDialog.message(
text =
String.format(
mContext.getString(R.string.dialog_packing),
folder.name
)
)
}
return true
}
override fun whenCompressionComplete(result: Boolean) {
handler.post {
if (result) {
materialDialog.title(R.string.share_mod).message(
text =
String.format(
mContext.getString(R.string.pack_success),
modClass.modName
)
).clearPositiveListeners().positiveButton(R.string.share_mod) {
FileOperator.shareFile(
mContext, toFile
)
}.negativeButton(R.string.dialog_cancel) {
toFile.delete()
}.show()
} else {
materialDialog.dismiss()
Snackbar.make(
(mModFragment.view)!!,
R.string.pack_failed,
Snackbar.LENGTH_SHORT
).show()
}
}
}
}, null)
}
}).start()
}
internal inner class RepairThread() : Thread(), Runnable {
private var modpath = mModpath
lateinit var materialDialog: MaterialDialog
//设置模组路径
fun setModpath(modpath: String) {
this.modpath = modpath
}
override fun run() {
super.run()
val modClass = ModClass(File(modpath))
handler.post {
materialDialog = MaterialDialog(mContext).title(R.string.dialog_title3).message(
text = String.format(
mContext.getString(R.string.dialog_repair), modClass.modName
)
).cancelable(false).positiveButton(R.string.dialog_close2) {
Snackbar.make(
(mModFragment.view)!!,
R.string.dialog_close_tip2,
Snackbar.LENGTH_SHORT
).show()
}
materialDialog.show()
}
val fileFinder = FileFinder2(modClass.modFile)
var targetFile: File? = null
fileFinder.setFinderListener(object : FileFinderListener {
override fun whenFindFile(file: File): Boolean {
handler.post {
materialDialog.message(
text = String.format(
mContext.getString(R.string.dialog_search), file.name
)
)
}
val fileName = file.name.lowercase()
val result = fileName == modClass.INFOFILENAME
if (result) {
targetFile = file
}
return !result
}
override fun whenFindFolder(folder: File): Boolean {
return true
}
})
fileFinder.onStart()
val findFile = targetFile?.parentFile
if (findFile != null) {
val modFile = modClass.modFile
val ok =
FileOperator.removeFiles(findFile, modFile, object : RemoveAndCopyListener {
override fun whenOperatorFile(file: File) {
handler.post {
materialDialog.message(
text = String.format(
mContext.getString(R.string.dialog_remove), file.name
)
)
}
}
})
if (ok) {
handler.post {
materialDialog.dismiss()
mModFragment.loadModList()
Snackbar.make(
(mModFragment.view)!!,
R.string.repair_complete,
Snackbar.LENGTH_SHORT
).show()
}
} else {
handler.post {
materialDialog.dismiss()
Snackbar.make(
(mModFragment.view)!!,
R.string.repair_complete,
Snackbar.LENGTH_SHORT
).setAction(R.string.create) {
createInfoFile(modClass, false)
}.show()
}
}
} else {
createInfoFile(modClass)
}
}
/**
* 创建信息文件并显示修复完成
* @param modClass ModClass
* @param needShowSnackbar 是否要提示
*/
fun createInfoFile(modClass: ModClass, needShowSnackbar: Boolean = true) {
FileOperator.writeFile(
modClass.infoFile,
"[mod]\ntitle: " + modClass.modName + "\ndescription: " + mContext.getText(R.string.repair_complete)
)
handler.post {
materialDialog.dismiss()
mModFragment.loadModList()
if (needShowSnackbar) {
Snackbar.make(
(mModFragment.view)!!,
R.string.repair_complete,
Snackbar.LENGTH_SHORT
).show()
}
}
}
}
internal inner class UnzipThread() : Thread(), Runnable {
lateinit var materialDialog: MaterialDialog
override fun run() {
super.run()
val main_path =
AppSettings.getValue(AppSettings.Setting.ModFolder, "")
val unzip_path = File(
main_path + FileOperator.getPrefixName(
File(
mModpath
)
)
)
//如果模组存在
if (unzip_path.exists()) {
handler.post {
Snackbar.make(
(mModFragment.view)!!,
mContext.resources.getText(R.string.directory_error),
Snackbar.LENGTH_SHORT
).show()
}
return
} else {
handler.post {
materialDialog =
MaterialDialog(mContext).title(R.string.dialog_title2).message(
text = String.format(
(mContext.resources.getText(R.string.dialog_unziping) as String),
ModClass(
File(
mModpath
)
).modName
)
).cancelable(false).positiveButton(R.string.dialog_close2) {
Snackbar.make(
(mModFragment.view)!!,
mContext.resources.getText(R.string.dialog_close_tip),
Snackbar.LENGTH_SHORT
).show()
}
materialDialog.show()
}
unzip_path.mkdirs()
}
val compressionManager = CompressionManager.instance
compressionManager.unzip(File(mModpath), unzip_path, object : UnzipListener {
override fun whenUnzipFile(zipEntry: ZipEntry, file: File): Boolean {
handler.post {
materialDialog.message(
text = String.format(
(mContext.resources.getText(R.string.dialog_unziping) as String),
file.name
)
)
}
return true
}
override fun whenUnzipFolder(zipEntry: ZipEntry, folder: File): Boolean {
handler.post {
materialDialog.message(
text =
String.format(
(mContext.resources.getText(R.string.dialog_unziping) as String),
folder.name
)
)
}
return true
}
override fun whenUnzipComplete(result: Boolean) {
if (result) {
val keepFile = AppSettings.getValue(AppSettings.Setting.KeepRwmodFile, true)
if (!keepFile) {
val modFile = File(mModpath)
val needRecycling = AppSettings.getValue(
AppSettings.Setting.EnableRecoveryStation,
true
)
if (needRecycling) {
val removeFile: File
val removePath: String = AppSettings.getValue(
AppSettings.Setting.RecoveryStationFolder,
mContext.filesDir.absolutePath + "/backup/"
).toString() + modFile.name
removeFile = File(removePath)
FileOperator.removeFiles(modFile, removeFile)
handler.post {
Snackbar.make(
(mModFragment.view)!!, String.format(
mContext.getString(R.string.recovery_prompt),
modFile.name
), Snackbar.LENGTH_SHORT
).show()
}
} else {
FileOperator.delete_files(modFile)
}
}
handler.post {
materialDialog.dismiss()
val modClass = ModClass(unzip_path)
if (!modClass.hasInfo()) {
val repairThread = RepairThread()
repairThread.setModpath(unzip_path.absolutePath)
repairThread.start()
}
mModFragment.loadModList()
}
} else {
handler.post {
materialDialog.dismiss()
Snackbar.make(
(mModFragment.view)!!,
mContext.resources.getText(R.string.import_error1),
Snackbar.LENGTH_SHORT
).show()
}
}
}
})
}
}
} }

View File

@ -1,7 +1,5 @@
package com.coldmint.rust.pro.edit package com.coldmint.rust.pro.edit
import com.coldmint.rust.core.dataBean.CompileConfiguration
/** /**
* Rust代码标记 * Rust代码标记
* @property offset Int * @property offset Int

View File

@ -1,29 +0,0 @@
package com.coldmint.rust.pro.viewmodel
import android.app.Application
import android.text.SpannableString
import androidx.lifecycle.MutableLiveData
import com.coldmint.rust.core.AnalysisResult
import com.coldmint.rust.pro.base.BaseAndroidViewModel
/**
* @author Cold Mint
* @date 2022/2/5 14:18
*/
class EditEndViewModel(application: Application) : BaseAndroidViewModel(application) {
/**
* 分析结果LiveData
*/
val analysisResultLiveData: MutableLiveData<List<AnalysisResult>> by lazy {
MutableLiveData<List<AnalysisResult>>()
}
/**
*加载状态LiveData
*/
val loadStateLiveData: MutableLiveData<Boolean> by lazy {
MutableLiveData<Boolean>()
}
}

View File

@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M22,6c0,-1.1 -0.9,-2 -2,-2L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6zM20,6l-8,5 -8,-5h16zM20,18L4,18L4,8l8,5 8,-5v10z"/>
</vector>

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChangePasswordActivity">
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@ -1,21 +0,0 @@
package com.coldmint.rust.core
import android.graphics.drawable.Drawable
import android.text.SpannableString
import android.view.View
import com.coldmint.rust.core.dataBean.CompileConfiguration
/**
* 代码分析结果
* @property text String 文本
* @property icon Drawable 图标
* @constructor
*/
data class AnalysisResult(
val lineData: String,
val errorInfo: String,
var icon: Drawable? = null,
var function: ((View) -> Unit)? = null,
val errorType: CompileConfiguration.ErrorType
)

View File

@ -0,0 +1,21 @@
package com.coldmint.rust.core
/**
* 代码编辑器类
*/
class CodeCompiler(val input: String) {
//英文模式
private var englishMode: Boolean = false
/**
* 设置是否启用英文模式 当启用时禁用翻译和编译功能
* @param enable Boolean
*/
fun setEnglishMode(enable: Boolean) {
this.englishMode = enable
}
}

View File

@ -1,314 +0,0 @@
package com.coldmint.rust.core.dataBean
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.util.Log
import android.view.View
import com.coldmint.rust.core.*
import com.coldmint.rust.core.tool.DebugHelper
import java.io.File
/**
* @author Cold Mint
* @date 2022/1/27 15:09
*/
data class CompileConfiguration(
val context: Context,
val openedSourceFile: OpenedSourceFile,
val modClass: ModClass,
val apkFolder: File,
private var line: Int = 0,
private var column: Int = 0,
private var errorNumber: Int = 0,
private var warningNumber: Int = 0,
var codeBlockType: CodeBlockType = CodeBlockType.Key,
var lastSection: String? = null,
//只能在特定函数内添加错误,否则将抛出异常
private var canAddError: Boolean = false,
private val keyBuilder: StringBuilder = StringBuilder(),
private val valueBuilder: StringBuilder = StringBuilder(),
private val arrayList: ArrayList<AnalysisResult> = ArrayList(),
private val errorIcon: Drawable? = context.getDrawable(R.drawable.error),
private val warningIcon: Drawable? = context.getDrawable(R.drawable.warning),
private val lineData: StringBuilder = StringBuilder(),
//错误记录映射记录表()
private
var errorRecordMap: HashMap<CodeIndex, ErrorRecord>? = null
) {
/**
* 增加值
* @param string String
*/
fun appendValue(string: String) {
if (codeBlockType == CodeBlockType.Reference) {
valueBuilder.append(string)
} else {
Log.e(CodeCompiler2.debugKey, "只能在引用语句块设置值。")
}
}
/**
* 增加键
* @param string String
*/
fun appendKey(string: String) {
if (codeBlockType == CodeBlockType.Reference) {
keyBuilder.append(string)
} else {
Log.e(CodeCompiler2.debugKey, "只能在引用语句块设置键。")
}
}
/**
* 设置是否可以添加错误只能在特定的函数内添加错误
* @param canAddError Boolean
*/
fun setCanAddError(canAddError: Boolean) {
this.canAddError = canAddError
}
/**
* 追加结果到Key或Value仅在行内有效
* @param string String
*/
fun appendResult(string: String) {
when (codeBlockType) {
CodeBlockType.Key -> {
keyBuilder.append(string)
lineData.append(string)
lineData.append(':')
}
CodeBlockType.Value -> {
valueBuilder.append(string)
lineData.append(string)
}
else -> {
DebugHelper.printLog(
CodeCompiler2.debugKey,
"无法分配[" + string + "],因为代码类型为" + codeBlockType + "不是Value或Key", "追加结果",
true
)
}
}
}
/**
* 获取Key
* @param needTrim Boolean 是否需要去除空格
* @return String
*/
fun getKey(needTrim: Boolean = true): String {
return if (needTrim) {
keyBuilder.toString().trim()
} else {
keyBuilder.toString()
}
}
/**
* 获取行内容
* @return String
*/
fun getLineData(): String {
return lineData.toString()
}
/**
* 获取Value
* @param needTrim Boolean 是否需要去除空格
* @return String
*/
fun getValue(needTrim: Boolean = true): String {
return if (needTrim) {
valueBuilder.toString().trim()
} else {
valueBuilder.toString()
}
}
/**
* 设置错误映射对象
* @param errorRecordMap HashMap<CodeIndex, ErrorRecord>?
*/
fun setErrorRecordMap(errorRecordMap: HashMap<CodeIndex, ErrorRecord>?) {
this.errorRecordMap = errorRecordMap
}
//通常 跟随主题色
//警告 标识为黄色
//错误 标识为红色
enum class ErrorType {
General, Warning, Error
}
/**
* 代码块类
* 注释变量名,引用
* Reference 引用是一种特殊的数据类型编译器会尝试编译此值若无法编译则使用原始值
*/
enum class CodeBlockType {
Key, Value, Section, Note, VariableName, Reference, Symbol
}
/**
* 错误记录
* @property info String 错误信息
* @property function function? 点击事件
* @property errorType ErrorType 错误类型
* @property verifyFunction Function0<Boolean>? 错误验证函数会被二次执行返回真则不再显示内容
* @constructor
*/
data class ErrorRecord(
val info: String,
var function: ((View) -> Unit)? = null,
val errorType: ErrorType = ErrorType.Warning,
var verifyFunction: ((CompileConfiguration) -> Boolean)? = null,
)
/**
* 代码位置记录
* @property string String
* @property line Int
* @property column Int
* @constructor
*/
data class CodeIndex(val string: String, val line: Int, val column: Int)
/**
* 创建代码位置记录
* @param string String
* @return CodeIndex
*/
fun createCodeIndex(string: String): CodeIndex {
return CodeIndex(string, line, column)
}
/**
* 获取错误数量
* @return Int
*/
fun getErrorNumber(): Int {
return errorNumber
}
/**
* 获取解析结果
* @return List<AnalysisResult>
*/
fun getAnalysisResult(): List<AnalysisResult> {
return arrayList.toList()
}
/**
* 获取警告数量
* @return Int
*/
fun getWarningNumber(): Int {
return warningNumber
}
/**
* 添加错误
* 若未同步错误表[CompileConfiguration.setErrorRecordMap]则抛出异常
* 使用[CompileConfiguration.setCanAddError]授权方法添加错误
* @param codeIndex 代码位置记录
* @param errorRecord ErrorRecord 错误记录
*/
fun addError(codeIndex: CodeIndex, errorRecord: ErrorRecord) {
if (!canAddError) {
arrayList.add(
AnalysisResult(
getLineData(),
"程序错误:未经许可的方法被调用。$errorRecord",
errorIcon, errorType = ErrorType.General
)
)
return
}
val location = String.format(
context.getString(R.string.location_info),
openedSourceFile.file.name,
line + 1
)
val analysisResult =
AnalysisResult(
getLineData(),
location + errorRecord.info,
errorType = errorRecord.errorType
)
analysisResult.function = errorRecord.function
when (errorRecord.errorType) {
ErrorType.Error -> {
analysisResult.icon = errorIcon
errorNumber++
}
ErrorType.Warning -> {
analysisResult.icon = warningIcon
warningNumber++
}
else -> {}
}
if (errorRecordMap == null) {
throw NullPointerException("错误记录表未同步。")
} else {
errorRecordMap?.set(codeIndex, errorRecord)
}
arrayList.add(analysisResult)
}
/**
* 添加编译信息
* @param string String
*/
fun addInfo(string: String) {
val analysisResult = AnalysisResult(getLineData(), string, errorType = ErrorType.General)
arrayList.add(analysisResult)
}
/**
* 获取行号
* @return Int
*/
fun getLineNum(): Int {
return line
}
/**
* 获取列号
* @return Int
*/
fun getColumnNum(): Int {
return column
}
/**
* 将光标指向下一行初始化行参数
*/
fun nextLine() {
line++
column = 0
codeBlockType = CodeBlockType.Key
keyBuilder.clear()
valueBuilder.clear()
lineData.clear()
}
/**
* 添加列内容添加列值
* @param string String
*/
fun addColumn(string: String) {
column += string.length
}
}

View File

@ -1,27 +0,0 @@
package com.coldmint.rust.core.dataBean
/**
* 模组错误报告开发者模式测试使用
* @property modPath String
* @property errorNumber Int
* @property warningNumber Int
* @constructor
*/
data class ModErrorReport(
val modPath: String,
private var errorNumber: Int = 0,
private var warningNumber: Int = 0,
private val errorList: ArrayList<String> = ArrayList()
) {
/**
* 添加单位错误报告
* @param compileConfiguration CompileConfiguration
*/
fun addFileReport(compileConfiguration: CompileConfiguration) {
if (compileConfiguration.getErrorNumber() > 0) {
errorList.add(compileConfiguration.openedSourceFile.file.absolutePath)
}
this.errorNumber += compileConfiguration.getErrorNumber()
this.warningNumber += compileConfiguration.getWarningNumber()
}
}

View File

@ -1,30 +0,0 @@
package com.coldmint.rust.core.interfaces
import com.coldmint.rust.core.dataBean.CompileConfiguration
/**
* @author Cold Mint
* @date 2022/1/27 16:37
*/
interface CodeCompilerInterface {
/**
* 实现翻译方法
* @param code String
* @param translatorListener CodeTranslatorListener
*/
fun translation(code: String, translatorListener: CodeTranslatorListener)
/**
* 编译方法
* @param code String
* @param compileConfiguration CompileConfiguration
* @param compilerListener CodeCompilerListener?
*/
fun compile(
code: String,
compileConfiguration: CompileConfiguration,
compilerListener: CodeCompilerListener? = null
)
}

View File

@ -1,123 +0,0 @@
package com.coldmint.rust.core.interfaces
import android.text.SpannableString
import android.view.View
import com.coldmint.rust.core.AnalysisResult
import com.coldmint.rust.core.dataBean.CompileConfiguration
import com.coldmint.rust.core.database.code.ValueTypeInfo
import java.io.File
interface CodeCompilerListener {
/**
* 当编译完成时
* @param compileConfiguration CompileConfiguration 编译配置包含错误信息
* @param code String 代码
*/
fun onCompilationComplete(compileConfiguration: CompileConfiguration, code: String)
/**
* 当翻译之前
*/
fun beforeCompilation()
/**
* 当点击Key不存在项目
* @param lineNum Int 行号
* @param view View 视图
* @param code String 代码
* @param section String
*/
fun onClickKeyNotFoundItem(
lineNum: Int,
columnNum: Int,
view: View,
code: String,
section: String
)
/**
* 当点击值类型错误项目
* @param lineNum Int 行号
* @param columnNum 列号
* @param view View 视图
* @param valueType ValueTypeInfo 值类型
*/
fun onClickValueTypeErrorItem(
lineNum: Int,
columnNum: Int,
view: View,
valueType: ValueTypeInfo
)
/**
* 当点击节位置错误
* @param lineNum Int
* @param columnNum Int
* @param view View
* @param sectionName String
*/
fun onClickSectionIndexError(lineNum: Int, columnNum: Int, view: View, sectionName: String)
/**
* 当点击资源文件不存在项目
* @param lineNum Int 行号
* @param view View 视图
* @param resourceFile File 资源文件
*/
fun onClickResourceErrorItem(lineNum: Int, columnNum: Int, view: View, resourceFile: File)
/**
* 当点击节错误项目未知的节
* @param lineNum Int 行号
* @param view View 视图
* @param displaySectionName String 显示的节名
*/
fun onClickSectionErrorItem(lineNum: Int, view: View, displaySectionName: String)
/**
* 单击了游戏同步项目
* @param lineNum Int
* @param columnNum Int
* @param view View
*/
fun onClickSynchronizationGame(lineNum: Int, columnNum: Int, view: View)
/**
* 当点击节名错误项目
* @param lineNum Int 行号
* @param columnNum Int 列名
* @param view View 视图
* @param sectionName String 节名
* @param needName Boolean 是否需要附加名
*/
fun onClickSectionNameErrorItem(
lineNum: Int,
columnNum: Int,
view: View,
sectionName: String,
symbolIndex: Int?,
needName: Boolean
)
/**
* 当点击代码位置错误
* @param lineNum Int 行号
* @param view View 视图
* @param sectionName String 节名
*/
fun onClickCodeIndexErrorItem(lineNum: Int, view: View, sectionName: String)
/**
* 当展示编译结果
* @param code String
* @return Boolean
*/
fun onShowCompilationResult(code: String): Boolean
}