cut devmenu
This commit is contained in:
@@ -1,65 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu;
|
|
||||||
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.ReplacementDataBaseHelper.MAIN_TABLE_NAME;
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.ReplacementDataBaseHelper.PATH_TO_REPLACED_ELEMENT;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.TwoLineListItem;
|
|
||||||
|
|
||||||
import com.ea.ironmonkey.devmenu.util.ReplacementDataBaseHelper;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.UtilitiesAndData;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
class FileAdapter extends ArrayAdapter<File> {
|
|
||||||
|
|
||||||
private static int count = 0;
|
|
||||||
private List files;
|
|
||||||
private Context context;
|
|
||||||
private ReplacementDataBaseHelper dataBaseHelper;
|
|
||||||
private SQLiteDatabase database;
|
|
||||||
|
|
||||||
public FileAdapter(Context context, List files) {
|
|
||||||
super(context, android.R.layout.simple_list_item_2, files);
|
|
||||||
dataBaseHelper = new ReplacementDataBaseHelper(context);
|
|
||||||
database = dataBaseHelper.getDatabase();
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
|
|
||||||
View view;
|
|
||||||
LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
|
|
||||||
String name = getItem(position).getName();
|
|
||||||
|
|
||||||
Cursor query = database.query(MAIN_TABLE_NAME, new String[]{PATH_TO_REPLACED_ELEMENT},
|
|
||||||
PATH_TO_REPLACED_ELEMENT + " = \"" + getItem(position).getAbsolutePath() + "\""
|
|
||||||
, null, null, null, null);
|
|
||||||
|
|
||||||
if (query.getCount() > 0) {
|
|
||||||
TwoLineListItem listItem = (TwoLineListItem) inflater.inflate(android.R.layout.simple_list_item_2, null, true);
|
|
||||||
listItem.getText1().setText(name);
|
|
||||||
listItem.getText2().setText("Заменен");
|
|
||||||
view = listItem;
|
|
||||||
} else {
|
|
||||||
TextView textView = (TextView) inflater.inflate(android.R.layout.simple_list_item_1, null, true);
|
|
||||||
textView.setText(name);
|
|
||||||
view = textView;
|
|
||||||
}
|
|
||||||
query.close();
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List getFiles() {
|
|
||||||
return files;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,458 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu;
|
|
||||||
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.UtilitiesAndData.OPEN_FILE_ON_REPLACE_REQUEST;
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.UtilitiesAndData.copy;
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.UtilitiesAndData.generateMD5;
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.UtilitiesAndData.isFirstRun;
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.preference.PreferenceManager;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.RadioGroup;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.TwoLineListItem;
|
|
||||||
|
|
||||||
import com.ea.games.nfs13_na.BuildConfig;
|
|
||||||
import com.ea.games.nfs13_na.R;
|
|
||||||
import com.ea.ironmonkey.GameActivity;
|
|
||||||
import com.ea.ironmonkey.devmenu.components.LongPressContextMenu;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.ResultListener;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.UtilitiesAndData;
|
|
||||||
import com.ea.nimble.Utility;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.FileReader;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
//TODO сделать нормальный файл сохранения
|
|
||||||
//TODO сделать его нрмальное отображние
|
|
||||||
|
|
||||||
//TODO сделать нормальное отслеживние файлов сохранений
|
|
||||||
//TODO сдлеать настройки отслеживания файла
|
|
||||||
//TODO сделать отображение текущего пути в проводнике
|
|
||||||
//TODO добавить иконки к проводику
|
|
||||||
//TODO сделать динамическое контекстное меню файла
|
|
||||||
|
|
||||||
//TODO реализовать сохранение файлов в память телефона из внутреннего хранилища
|
|
||||||
public class MainActivity extends Activity{
|
|
||||||
|
|
||||||
private final String LOG_TAG = "InjectedActivity";
|
|
||||||
|
|
||||||
private String internalFiles;
|
|
||||||
private String externalFiles;
|
|
||||||
private ResultListener resultListener;
|
|
||||||
private ResultListener openResult = new ResultListener() {};
|
|
||||||
private static Thread observerThread;
|
|
||||||
private String globalPath = "";
|
|
||||||
private ListView fileList;
|
|
||||||
private Button backButton;
|
|
||||||
private static final int READ_FILE_REQUEST_CODE = 101;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
UtilitiesAndData.init(this);
|
|
||||||
internalFiles = UtilitiesAndData.getInternalStorage();
|
|
||||||
externalFiles = UtilitiesAndData.getExternalStorage();
|
|
||||||
|
|
||||||
File replacements = new File(UtilitiesAndData.getReplacementsStorage());
|
|
||||||
if(!replacements.exists()) replacements.mkdir();
|
|
||||||
|
|
||||||
File activityFlag = new File(externalFiles + File.separator + BuildConfig.DEV_MENU_ID);
|
|
||||||
// TODO доделать проверку первого запуска
|
|
||||||
if(isFirstRun()){
|
|
||||||
File data = new File(UtilitiesAndData.getExternalStorage());
|
|
||||||
if(!data.exists()){
|
|
||||||
|
|
||||||
File data1 = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + getPackageName() + "_");
|
|
||||||
if(data1.exists()) {
|
|
||||||
String path = data1.getPath();
|
|
||||||
data1.renameTo(new File(path.substring(0, path.length() - 2)));
|
|
||||||
activityFlag = data1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
File temp = new File(UtilitiesAndData.getInternalStorage() + File.separator + "load");
|
|
||||||
temp.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!activityFlag.exists()){
|
|
||||||
updateLanguage();
|
|
||||||
runGame();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setContentView(R.layout.custom);
|
|
||||||
|
|
||||||
|
|
||||||
String title = String.format(getString(R.string.dev_menu_title), /*BuildConfig.DEV_MENU_VERSION*/"");
|
|
||||||
|
|
||||||
getActionBar().setTitle(title);
|
|
||||||
|
|
||||||
fileList = (ListView) findViewById(R.id.FileList);
|
|
||||||
|
|
||||||
fileList.setAdapter(new FileAdapter(this, asList(externalFiles)));
|
|
||||||
globalPath = externalFiles;
|
|
||||||
|
|
||||||
RadioGroup group = (RadioGroup) findViewById(R.id.switcherFiles);
|
|
||||||
|
|
||||||
fileList.setOnItemClickListener((parent, view, position, id) -> {
|
|
||||||
String chosenElem =
|
|
||||||
(view instanceof TwoLineListItem) ?
|
|
||||||
((TwoLineListItem) view).getText1().getText().toString() :
|
|
||||||
((TextView) view).getText().toString(); // получаем текст нажатого элемента
|
|
||||||
|
|
||||||
File intermid = new File(globalPath + "/" + chosenElem);
|
|
||||||
if(intermid.isDirectory()) {
|
|
||||||
globalPath += "/" + chosenElem;
|
|
||||||
updateListView();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
openFile(intermid);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
fileList.setOnItemLongClickListener((parent, view, position, id) -> {
|
|
||||||
String chosenElem =
|
|
||||||
(view instanceof TwoLineListItem) ?
|
|
||||||
((TwoLineListItem) view).getText1().getText().toString() :
|
|
||||||
((TextView) view).getText().toString();
|
|
||||||
|
|
||||||
|
|
||||||
LongPressContextMenu ninja = new LongPressContextMenu(this, globalPath + "/" + chosenElem);
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
group.setOnCheckedChangeListener((group1, checkedId) -> {
|
|
||||||
globalPath = (checkedId == R.id.externalStoreButton) ? externalFiles : internalFiles;
|
|
||||||
updateListView();
|
|
||||||
});
|
|
||||||
|
|
||||||
backButton = (Button)findViewById(R.id.back_button);
|
|
||||||
|
|
||||||
backButton.setOnClickListener(v -> {
|
|
||||||
if(!( globalPath.equals(internalFiles) | globalPath.equals(externalFiles) )
|
|
||||||
& !globalPath.isEmpty()
|
|
||||||
& (new File(globalPath).exists())) {
|
|
||||||
globalPath = globalPath.substring(0, globalPath.lastIndexOf("/"));
|
|
||||||
updateListView();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
//Настройка языка игры
|
|
||||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void readAndSortNumbersFromFile(String fileName) {
|
|
||||||
List<Integer> numbersList = new ArrayList<>();
|
|
||||||
|
|
||||||
try {
|
|
||||||
File file = new File(fileName);
|
|
||||||
BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
|
|
||||||
String line;
|
|
||||||
|
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
|
||||||
try {
|
|
||||||
// Попытайтесь преобразовать строку в целое число и добавить его в список
|
|
||||||
int number = Integer.parseInt(line);
|
|
||||||
numbersList.add(number);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
// Если строка не является числом, проигнорируйте ее
|
|
||||||
Log.e("FileOperations", "Ошибка при чтении числа: " + line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bufferedReader.close();
|
|
||||||
|
|
||||||
// Отсортируйте числа в списке
|
|
||||||
Collections.sort(numbersList);
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e("Time", "Ошибка при чтении файла: " + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
|
||||||
backButton.callOnClick();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
getMenuInflater().inflate(R.menu.options, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
|
|
||||||
switch (requestCode){
|
|
||||||
case OPEN_FILE_ON_REPLACE_REQUEST:{
|
|
||||||
resultListener.onResult(data);
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case READ_FILE_REQUEST_CODE:{
|
|
||||||
openResult.onResult(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("NonConstantResourceId")
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
|
|
||||||
int itemId = item.getItemId();
|
|
||||||
if (itemId == R.id.optionRunTheGame) {
|
|
||||||
updateLanguage();
|
|
||||||
runGame();
|
|
||||||
} else if (itemId == R.id.optionSettings) {
|
|
||||||
Intent goToSettings = new Intent(this, SettingsActivity.class);
|
|
||||||
startActivity(goToSettings);
|
|
||||||
} else if (itemId == R.id.optionDeleteData) {
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setTitle(getString(R.string.remove_action_title));
|
|
||||||
builder.setMessage(getString(R.string.sure_remove_all_data_title));
|
|
||||||
builder.setPositiveButton(R.string.ok_title, (dialogInterface, i) -> {
|
|
||||||
File[] internals = new File(UtilitiesAndData.getInternalStorage()).listFiles();
|
|
||||||
for (File internal : internals) {
|
|
||||||
if (!UtilitiesAndData.isExclusionName(internal.getName())) {
|
|
||||||
internal.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
builder.setNegativeButton(R.string.cancel_title, null);
|
|
||||||
builder.show();
|
|
||||||
} else if (itemId == R.id.optionCheckRecovers) {
|
|
||||||
Intent goToRecovers = new Intent(this, RecoverListActivity.class);
|
|
||||||
startActivity(goToRecovers);
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void openFile(File url) {
|
|
||||||
File tempFile = null;
|
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
|
||||||
|
|
||||||
if(url.getAbsolutePath().contains(UtilitiesAndData.getInternalStorage())){
|
|
||||||
Log.wtf(LOG_TAG, "WTF, man, you cant read my files!!!");
|
|
||||||
|
|
||||||
//Создаем временный файл, там где можем его прочитать
|
|
||||||
Random random = new Random();
|
|
||||||
tempFile = new File(UtilitiesAndData.getExternalStorage() + File.separator + "temp_" + random.nextInt());
|
|
||||||
|
|
||||||
//Копируем тот файл который хотим посмотреть
|
|
||||||
copy(url.getAbsolutePath(), tempFile.getAbsolutePath());
|
|
||||||
|
|
||||||
//Сохраняем ссылку на окрытый файл, в случае его изменения
|
|
||||||
final File openedFile = url;
|
|
||||||
url = tempFile;
|
|
||||||
File finalTempFile = tempFile;
|
|
||||||
|
|
||||||
//Создаем хеш файла для того чтобы его потом сравнить
|
|
||||||
final byte[] compTemp = generateMD5(finalTempFile);
|
|
||||||
|
|
||||||
openResult = new ResultListener(){
|
|
||||||
@Override
|
|
||||||
public void onResult(Object data) {
|
|
||||||
byte[] bytes = generateMD5(finalTempFile);
|
|
||||||
//Если хеши не одинаковы то заменяем одно на другое
|
|
||||||
if(!Arrays.equals(bytes, compTemp))
|
|
||||||
copy(finalTempFile.getAbsolutePath(), openedFile.getAbsolutePath());
|
|
||||||
finalTempFile.delete();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
intent.putExtra("pathToTemp", tempFile.getAbsolutePath());
|
|
||||||
}
|
|
||||||
// Create URI
|
|
||||||
Uri uri = Uri.fromFile(url);
|
|
||||||
|
|
||||||
if (url.toString().contains(".doc") || url.toString().contains(".docx"))
|
|
||||||
intent.setDataAndType(uri, "application/msword");
|
|
||||||
else if(url.toString().contains(".pdf")) {
|
|
||||||
intent.setDataAndType(uri, "application/pdf");
|
|
||||||
} else if(url.toString().contains(".ppt") || url.toString().contains(".pptx")) {
|
|
||||||
intent.setDataAndType(uri, "application/vnd.ms-powerpoint");
|
|
||||||
} else if(url.toString().contains(".xls") || url.toString().contains(".xlsx")) {
|
|
||||||
intent.setDataAndType(uri, "application/vnd.ms-excel");
|
|
||||||
} else if(url.toString().contains(".zip") || url.toString().contains(".rar")) {
|
|
||||||
intent.setDataAndType(uri, "application/x-wav");
|
|
||||||
} else if(url.toString().contains(".rtf")) {
|
|
||||||
intent.setDataAndType(uri, "application/rtf");
|
|
||||||
} else if(url.toString().contains(".wav") || url.toString().contains(".mp3")) {
|
|
||||||
intent.setDataAndType(uri, "audio/x-wav");
|
|
||||||
} else if(url.toString().contains(".gif")) {
|
|
||||||
intent.setDataAndType(uri, "image/gif");
|
|
||||||
} else if(url.toString().contains(".jpg") || url.toString().contains(".jpeg") || url.toString().contains(".png")) {
|
|
||||||
intent.setDataAndType(uri, "image/jpeg");
|
|
||||||
} else if(url.toString().contains(".txt")) {
|
|
||||||
intent.setDataAndType(uri, "text/plain");
|
|
||||||
} else if(url.toString().contains(".3gp") || url.toString().contains(".mpg") || url.toString().contains(".mpeg") || url.toString().contains(".mpe") || url.toString().contains(".mp4") || url.toString().contains(".avi")) {
|
|
||||||
intent.setDataAndType(uri, "video/*");
|
|
||||||
} else {
|
|
||||||
intent.setDataAndType(uri, "*/*");
|
|
||||||
}
|
|
||||||
|
|
||||||
//intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
||||||
startActivityForResult(intent, READ_FILE_REQUEST_CODE);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runGame() {
|
|
||||||
|
|
||||||
Intent GoToGame = new Intent(this, GameActivity.class);
|
|
||||||
startActivity(GoToGame);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Сделать номальную систему учета измения файлов
|
|
||||||
public static void observ(){
|
|
||||||
File save = new File(UtilitiesAndData.getInternalStorage() + File.separator + "files/var/nfstr_save.sb");
|
|
||||||
File fileOut = new File(UtilitiesAndData.getExternalStorage() + File.separator + "Log.txt");
|
|
||||||
File pathToSave = new File(UtilitiesAndData.getExternalStorage() + File.separator + "saves");
|
|
||||||
pathToSave.mkdir();
|
|
||||||
if(!fileOut.exists()) {
|
|
||||||
try {
|
|
||||||
fileOut.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SimpleDateFormat format = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss", Locale.getDefault());
|
|
||||||
UtilitiesAndData.setLogger(fileOut);
|
|
||||||
observerThread = new Thread(() -> {
|
|
||||||
int count = 1;
|
|
||||||
byte[] lastMD5 = new byte[10];
|
|
||||||
while (true){
|
|
||||||
byte[] md5 = generateMD5(save);
|
|
||||||
if(!Arrays.equals(md5, lastMD5)) {
|
|
||||||
UtilitiesAndData.printLog(format.format(new Date()) + " | " + Utility.bytesToHexString(md5) + "\n");
|
|
||||||
File change = new File(pathToSave.getAbsolutePath() + File.separator + "nfs_save_change_"+ count +".sb");
|
|
||||||
try {
|
|
||||||
change.createNewFile();
|
|
||||||
copy(save, change);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastMD5 = md5;
|
|
||||||
try {
|
|
||||||
Thread.sleep(1000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
observerThread.start();
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> List<T> asList(T[] a){
|
|
||||||
return Arrays.asList(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO реализовать сокрытие лишних папок
|
|
||||||
private List<File> asList(String path){
|
|
||||||
return asList(new File(path).listFiles());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateLanguage(){
|
|
||||||
//Получаем текущий язык
|
|
||||||
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
|
|
||||||
String current_lang = preferences.getString(getString(R.string.current_lang), "00");
|
|
||||||
if(current_lang.equals("00")) {
|
|
||||||
Log.e(LOG_TAG, "Not found currentLang preference(");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if(current_lang.equals("sys"))
|
|
||||||
current_lang = Locale.getDefault().getLanguage();
|
|
||||||
|
|
||||||
byte[] current_lang_bytes = current_lang.getBytes();
|
|
||||||
|
|
||||||
//Открываем языковой файл и создаем поток чтения
|
|
||||||
File locale = new File(internalFiles + "/files/var/locale");
|
|
||||||
FileInputStream inputStream;
|
|
||||||
|
|
||||||
//Байтовое представление файла
|
|
||||||
byte[] bytes_locale = new byte[4];
|
|
||||||
try {
|
|
||||||
|
|
||||||
inputStream = new FileInputStream(locale);
|
|
||||||
inputStream.read(bytes_locale);
|
|
||||||
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Log.wtf(LOG_TAG, "No found locale(((((");
|
|
||||||
return;
|
|
||||||
}catch (IOException e){
|
|
||||||
Log.wtf(LOG_TAG, "Couldn't read the locale file((((((");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (
|
|
||||||
bytes_locale[2] != current_lang_bytes[0] &
|
|
||||||
bytes_locale[3] != current_lang_bytes[1]
|
|
||||||
) {
|
|
||||||
bytes_locale[2] = current_lang_bytes[0];
|
|
||||||
bytes_locale[3] = current_lang_bytes[1];
|
|
||||||
} else return;
|
|
||||||
}catch (Exception e){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileOutputStream outputStream;
|
|
||||||
try {
|
|
||||||
outputStream = new FileOutputStream(locale, false);
|
|
||||||
outputStream.write(bytes_locale, 0, 4);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}catch (IOException e){
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResultListener(ResultListener resultListener) {
|
|
||||||
this.resultListener = resultListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateListView(){
|
|
||||||
fileList.setAdapter(new FileAdapter(getApplicationContext(), asList(globalPath)));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import com.ea.nimble.ApplicationLifecycle;
|
|
||||||
|
|
||||||
//Активность-марионетка для проверки работы нативных методов жизненного цикла
|
|
||||||
public class PuppetActivity extends Activity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
ApplicationLifecycle.onActivityCreate(savedInstanceState, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
ApplicationLifecycle.onActivityResume(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStart() {
|
|
||||||
super.onStart();
|
|
||||||
ApplicationLifecycle.onActivityStart(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onDestroy() {
|
|
||||||
super.onDestroy();
|
|
||||||
ApplicationLifecycle.onActivityDestroy(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onBackPressed() {
|
|
||||||
super.onBackPressed();
|
|
||||||
ApplicationLifecycle.onBackPressed();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
ApplicationLifecycle.onActivityResult(resultCode, requestCode, data, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPause() {
|
|
||||||
super.onPause();
|
|
||||||
ApplicationLifecycle.onActivityPause(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onRestart() {
|
|
||||||
super.onRestart();
|
|
||||||
ApplicationLifecycle.onActivityRestart(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop() {
|
|
||||||
super.onStop();
|
|
||||||
ApplicationLifecycle.onActivityStop(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
|
||||||
super.onRestoreInstanceState(savedInstanceState);
|
|
||||||
ApplicationLifecycle.onActivityRestoreInstanceState(savedInstanceState, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.ea.games.nfs13_na.R;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.ReplacementDataBaseHelper;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.UtilitiesAndData;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
public class RecoverListActivity extends Activity {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
boolean flag = true;
|
|
||||||
|
|
||||||
getActionBar().setTitle(R.string.recover_file_title);
|
|
||||||
|
|
||||||
ListView view = new ListView(this);
|
|
||||||
|
|
||||||
SQLiteDatabase database = new ReplacementDataBaseHelper(this).getDatabase();
|
|
||||||
|
|
||||||
Cursor cursor = database.rawQuery("SELECT " + ReplacementDataBaseHelper.PATH_TO_REPLACED_ELEMENT + " FROM " + ReplacementDataBaseHelper.MAIN_TABLE_NAME, null);
|
|
||||||
|
|
||||||
ArrayList<String> arrayList = new ArrayList<>();
|
|
||||||
|
|
||||||
ArrayList<String> fullNames = new ArrayList<>();
|
|
||||||
ArrayList<String> shortNames = new ArrayList<>();
|
|
||||||
|
|
||||||
while (cursor.moveToNext()) {
|
|
||||||
String string = cursor.getString(0);
|
|
||||||
fullNames.add(string);
|
|
||||||
int from = string.lastIndexOf("/files/");
|
|
||||||
shortNames.add(string.substring(from));
|
|
||||||
}
|
|
||||||
if(fullNames.isEmpty()){
|
|
||||||
shortNames.add("Не чего заменять!!");
|
|
||||||
flag = false;
|
|
||||||
}
|
|
||||||
boolean thereIsSmthToRecover = flag;
|
|
||||||
|
|
||||||
ArrayAdapter<String> adapter;
|
|
||||||
|
|
||||||
view.setOnItemClickListener((parent, view1, position, id) -> {
|
|
||||||
if(thereIsSmthToRecover){
|
|
||||||
|
|
||||||
TextView textView = (TextView) view1;
|
|
||||||
String s = textView.getText().toString();
|
|
||||||
|
|
||||||
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
|
|
||||||
|
|
||||||
//TODO сделать нормальные строки
|
|
||||||
dialog.setTitle("Воостановить?");
|
|
||||||
|
|
||||||
dialog.setPositiveButton(R.string.ok_title, (dialog1, which) -> {
|
|
||||||
shortNames.remove(s);
|
|
||||||
view.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, shortNames));
|
|
||||||
String fullName = fullNames.get(position);
|
|
||||||
fullNames.remove(fullName);
|
|
||||||
UtilitiesAndData.recoverFile(fullName);
|
|
||||||
//System.out.println();
|
|
||||||
//TODO Сделать воостановление
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.setNegativeButton(R.string.cancel_title, (dialog1, which) -> {
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, shortNames);
|
|
||||||
|
|
||||||
view.setAdapter(adapter);
|
|
||||||
|
|
||||||
setContentView(view);
|
|
||||||
cursor.close();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.preference.Preference;
|
|
||||||
import android.preference.PreferenceActivity;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
|
|
||||||
import com.ea.games.nfs13_na.BuildConfig;
|
|
||||||
import com.ea.games.nfs13_na.R;
|
|
||||||
import com.ea.ironmonkey.devmenu.dialog.OpenFileDialog;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.SaveManager;
|
|
||||||
import com.ea.ironmonkey.devmenu.dialog.SvmwCreatorDialog;
|
|
||||||
import com.ea.ironmonkey.devmenu.dialog.SvmwInspectorDialog;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.UtilitiesAndData;
|
|
||||||
import com.ea.nimble.ApplicationLifecycle;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
|
|
||||||
public class SettingsActivity extends PreferenceActivity {
|
|
||||||
|
|
||||||
public static final String LOG_TAG = "SettingActivity";
|
|
||||||
|
|
||||||
private static final int PICKFILE_REQUEST_CODE = 128;
|
|
||||||
public static final int PICK_SVMW_REQUEST_CODE = 129;
|
|
||||||
public static final int PICK_SVMW_IN_CREATE = 228;
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
addPreferencesFromResource(R.xml.settings_xml);
|
|
||||||
|
|
||||||
ApplicationLifecycle.onActivityCreate(savedInstanceState, this);
|
|
||||||
|
|
||||||
String title = String.format(getString(R.string.dev_menu_title), BuildConfig.DEV_MENU_VERSION);
|
|
||||||
getActionBar().setTitle(title);
|
|
||||||
|
|
||||||
Preference chooseSaveFileButton = findPreference(getString(R.string.choose_save_file_title));
|
|
||||||
Preference chooseSVMWfileButton = findPreference(getString(R.string.choose_svmw_file_title));
|
|
||||||
Preference createSVMWfileButton = findPreference(getString(R.string.create_svmw_file_title));
|
|
||||||
Preference turnOffTheDevMenuButton = findPreference(getString(R.string.switch_off_devmenu_title));
|
|
||||||
|
|
||||||
final Context myContext = this;
|
|
||||||
|
|
||||||
turnOffTheDevMenuButton.setOnPreferenceClickListener(preference -> {
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder.setTitle(R.string.switch_off_devmenu_title);
|
|
||||||
builder.setMessage(R.string.msg_devmenu_off);
|
|
||||||
builder.setPositiveButton(R.string.ok_title, (dialog, which) -> UtilitiesAndData.getDevMenuSwitcher().delete());
|
|
||||||
builder.setNegativeButton(R.string.cancel_title, null);
|
|
||||||
builder.show();
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
chooseSaveFileButton.setOnPreferenceClickListener(preference -> {
|
|
||||||
|
|
||||||
OpenFileDialog fileDialog = new OpenFileDialog(myContext);
|
|
||||||
fileDialog
|
|
||||||
.setFilter(".*\\.sb")
|
|
||||||
.setOpenDialogListener(fileName -> {
|
|
||||||
|
|
||||||
File save = new File(fileName);
|
|
||||||
SaveManager manager = new SaveManager(this);
|
|
||||||
manager.loadSaveFile(save);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
fileDialog.show();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
chooseSVMWfileButton.setOnPreferenceClickListener(preference -> {
|
|
||||||
|
|
||||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
||||||
intent.setType("file/*");
|
|
||||||
startActivityForResult(intent, PICK_SVMW_REQUEST_CODE);
|
|
||||||
//TODO реализовать выбор svmw
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
//По нажатии на кнопку создания svmw файла осуществляется переход в диалог создания svmw
|
|
||||||
createSVMWfileButton.setOnPreferenceClickListener(preference -> {
|
|
||||||
|
|
||||||
SvmwCreatorDialog dialog = new SvmwCreatorDialog(this);
|
|
||||||
dialog.show();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
getActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data);
|
|
||||||
if(data != null) {
|
|
||||||
switch (requestCode) {
|
|
||||||
case PICKFILE_REQUEST_CODE: {
|
|
||||||
String s = data.getData().toString();
|
|
||||||
String s1 = s.replaceAll("file://", "");
|
|
||||||
File file = new File(s1);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PICK_SVMW_REQUEST_CODE: {
|
|
||||||
String s = data.getData().toString();
|
|
||||||
String s1 = s.replaceAll("file://", "");
|
|
||||||
File file = new File(s1);
|
|
||||||
SvmwInspectorDialog inspectorDialog = new SvmwInspectorDialog(this, file);
|
|
||||||
inspectorDialog.show();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
if (item.getItemId() == android.R.id.home) {
|
|
||||||
onBackPressed();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.components;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/** Динамический список для контекстного меню файла LongPressContextMenu */
|
|
||||||
public class DynamicOptionsListView extends ListView {
|
|
||||||
|
|
||||||
/** Названия позиций в контекстном меню */
|
|
||||||
private List<String> names = new ArrayList<>();
|
|
||||||
private List<OptionAction> actions = new ArrayList<>();
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
public DynamicOptionsListView(Context context) {
|
|
||||||
super(context);
|
|
||||||
this.context = context;
|
|
||||||
updateList();
|
|
||||||
setOnItemClickListener((parent, view, position, id) -> {
|
|
||||||
try {
|
|
||||||
actions.get(position).action();
|
|
||||||
}catch (IndexOutOfBoundsException e){
|
|
||||||
Log.i("DynamicListView", "No found action to do( in position " + position);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateList(){
|
|
||||||
setAdapter(
|
|
||||||
new ArrayAdapter<>(
|
|
||||||
context,
|
|
||||||
android.R.layout.simple_list_item_1,
|
|
||||||
names
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addOption(String title, OptionAction action){
|
|
||||||
names.add(title);
|
|
||||||
actions.add(action);
|
|
||||||
updateList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteOption(String title){
|
|
||||||
boolean removeInt = names.remove(title);
|
|
||||||
actions.remove(removeInt);
|
|
||||||
updateList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String deleteOption(int position){
|
|
||||||
String result = names.remove(position);
|
|
||||||
actions.remove(position);
|
|
||||||
updateList();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.components;
|
|
||||||
|
|
||||||
public interface FileAction {
|
|
||||||
|
|
||||||
void actionReplaceFile();
|
|
||||||
|
|
||||||
void actionRecoverFile();
|
|
||||||
|
|
||||||
void actionRemoveFile();
|
|
||||||
|
|
||||||
void actionTrackTheFile();
|
|
||||||
|
|
||||||
void actionGetPropsOfFile();
|
|
||||||
|
|
||||||
void actionHideTheFile();
|
|
||||||
//sfhsadfhsdjf
|
|
||||||
}
|
|
||||||
@@ -1,205 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.components;
|
|
||||||
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.ReplacementDataBaseHelper.MAIN_TABLE_NAME;
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.ReplacementDataBaseHelper.NAME_OF_BACKUPED_ELEMENT;
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.UtilitiesAndData.OPEN_FILE_ON_REPLACE_REQUEST;
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.UtilitiesAndData.copy;
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.UtilitiesAndData.getFileSize;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.ea.games.nfs13_na.R;
|
|
||||||
import com.ea.ironmonkey.devmenu.MainActivity;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.ReplacementDataBaseHelper;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.ResultListener;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.UtilitiesAndData;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.text.CharacterIterator;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.text.StringCharacterIterator;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Контекстное меню управления данными
|
|
||||||
*/
|
|
||||||
public class LongPressContextMenu extends AlertDialog.Builder implements FileAction {
|
|
||||||
|
|
||||||
private File chosenFile;
|
|
||||||
private MainActivity activity;
|
|
||||||
private static final String LOG_TAG = "LongPressContextMenu";
|
|
||||||
|
|
||||||
private AlertDialog show;
|
|
||||||
private ReplacementDataBaseHelper dataBaseHelper;
|
|
||||||
private SQLiteDatabase writableDatabase;
|
|
||||||
private ContentValues values;
|
|
||||||
|
|
||||||
private File generateReplacementFile(){
|
|
||||||
Random random = new Random();
|
|
||||||
int index = random.nextInt();
|
|
||||||
index = (index < 0) ? index * -1 : index;
|
|
||||||
String nameReplacedOriginal = "replacement_" + index + "";
|
|
||||||
File original = new File(UtilitiesAndData.getReplacementsStorage() + File.separator + nameReplacedOriginal);
|
|
||||||
try {
|
|
||||||
original.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return original;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String humanReadableByteCountSI(long bytes) {
|
|
||||||
if (-1000 < bytes && bytes < 1000) {
|
|
||||||
return bytes + " B";
|
|
||||||
}
|
|
||||||
CharacterIterator ci = new StringCharacterIterator("kMGTPE");
|
|
||||||
while (bytes <= -999_950 || bytes >= 999_950) {
|
|
||||||
bytes /= 1000;
|
|
||||||
ci.next();
|
|
||||||
}
|
|
||||||
return String.format("%.1f %cB", bytes / 1000.0, ci.current());
|
|
||||||
}
|
|
||||||
|
|
||||||
public LongPressContextMenu(MainActivity activity, String pathToChosenElem) {
|
|
||||||
super(activity);
|
|
||||||
this.activity = activity;
|
|
||||||
chosenFile = new File(pathToChosenElem);
|
|
||||||
DynamicOptionsListView optionsView = new DynamicOptionsListView(activity);
|
|
||||||
|
|
||||||
this.dataBaseHelper = new ReplacementDataBaseHelper(activity);
|
|
||||||
this.writableDatabase = dataBaseHelper.getDatabase();
|
|
||||||
this.values = new ContentValues();
|
|
||||||
|
|
||||||
optionsView.addOption(activity.getString(R.string.replace_file_title), this::actionReplaceFile);
|
|
||||||
optionsView.addOption(activity.getString(R.string.recover_file_title), this::actionRecoverFile);
|
|
||||||
optionsView.addOption(activity.getString(R.string.remove_file_title), this::actionRemoveFile);
|
|
||||||
optionsView.addOption(activity.getString(R.string.track_file_title), this::actionTrackTheFile);
|
|
||||||
optionsView.addOption(activity.getString(R.string.file_props_title), this::actionGetPropsOfFile);
|
|
||||||
optionsView.addOption(activity.getString(R.string.hide_file_title), this::actionHideTheFile);
|
|
||||||
|
|
||||||
setView(optionsView);
|
|
||||||
setTitle(chosenFile.getName()
|
|
||||||
+ " - " +
|
|
||||||
((chosenFile.isDirectory()) ?
|
|
||||||
activity.getString(R.string.folder_title) :
|
|
||||||
activity.getString(R.string.file_title)));
|
|
||||||
|
|
||||||
this.show = show();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionReplaceFile() {
|
|
||||||
Intent chooseFile = new Intent(Intent.ACTION_GET_CONTENT);
|
|
||||||
chooseFile.addCategory(Intent.CATEGORY_OPENABLE);
|
|
||||||
chooseFile.setType("text/plain");
|
|
||||||
activity.setResultListener(new ResultListener() {
|
|
||||||
@Override
|
|
||||||
public void onResult(Object object) {
|
|
||||||
//Реализовать замену и воостановление данных
|
|
||||||
Intent data;
|
|
||||||
if(object instanceof Intent)
|
|
||||||
data = (Intent) object;
|
|
||||||
else return;
|
|
||||||
|
|
||||||
String selectedFileToReplace = "";
|
|
||||||
selectedFileToReplace = data.getData().getPath();
|
|
||||||
|
|
||||||
//Создание файла куда будет складывться замена
|
|
||||||
File replacement = generateReplacementFile();
|
|
||||||
|
|
||||||
//Копирование выбранного оригинального файла в хранилище замен
|
|
||||||
//Иначе говоря, создание резервной копии
|
|
||||||
String path = chosenFile.getAbsolutePath();
|
|
||||||
copy(path, replacement.getPath());
|
|
||||||
|
|
||||||
//Непосредственная замена
|
|
||||||
copy(selectedFileToReplace, path);
|
|
||||||
|
|
||||||
values.put(NAME_OF_BACKUPED_ELEMENT, replacement.getName());
|
|
||||||
values.put(ReplacementDataBaseHelper.PATH_TO_REPLACED_ELEMENT, path);
|
|
||||||
|
|
||||||
//Запись в бд
|
|
||||||
writableDatabase.insert(MAIN_TABLE_NAME, null, values);
|
|
||||||
|
|
||||||
writableDatabase.close();
|
|
||||||
|
|
||||||
activity.updateListView();
|
|
||||||
show.cancel();
|
|
||||||
//TODO Язык!!!!
|
|
||||||
Toast.makeText(activity, "Заменено!", Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
activity.startActivityForResult(
|
|
||||||
Intent.createChooser(chooseFile, "Choose a file"),
|
|
||||||
OPEN_FILE_ON_REPLACE_REQUEST
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionRecoverFile() {
|
|
||||||
String path = chosenFile.getAbsolutePath();
|
|
||||||
UtilitiesAndData.recoverFile(path);
|
|
||||||
activity.updateListView();
|
|
||||||
show.cancel();
|
|
||||||
//дщд
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionRemoveFile() {
|
|
||||||
AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
|
|
||||||
dialog.setTitle(activity.getString(R.string.remove_file_title));
|
|
||||||
String message = String.format(activity.getString(R.string.sure_remove_title), chosenFile.getName());
|
|
||||||
dialog.setMessage(message);
|
|
||||||
|
|
||||||
dialog.setPositiveButton(R.string.ok_title, (dialog1, which) -> {
|
|
||||||
UtilitiesAndData.deleteRecursive(chosenFile);
|
|
||||||
activity.updateListView();
|
|
||||||
});
|
|
||||||
dialog.setNegativeButton(R.string.cancel_title, null);
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionTrackTheFile() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionGetPropsOfFile() {
|
|
||||||
AlertDialog.Builder dialog = new AlertDialog.Builder(activity);
|
|
||||||
dialog.setTitle(chosenFile.getName()
|
|
||||||
+ " - " +
|
|
||||||
((chosenFile.isDirectory()) ?
|
|
||||||
activity.getString(R.string.folder_title) :
|
|
||||||
activity.getString(R.string.file_title)));
|
|
||||||
|
|
||||||
long lastModified = chosenFile.lastModified();
|
|
||||||
Date date = new Date(lastModified);
|
|
||||||
|
|
||||||
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss:SS");
|
|
||||||
String formattedDate = sdf.format(date);
|
|
||||||
|
|
||||||
long size = getFileSize(chosenFile);
|
|
||||||
|
|
||||||
|
|
||||||
dialog.setMessage(
|
|
||||||
activity.getString(R.string.file_lastmod_title) + "\n" +
|
|
||||||
formattedDate + "\n\n" +
|
|
||||||
activity.getString(R.string.file_size_title) + "\n" +
|
|
||||||
humanReadableByteCountSI(size) + " (" + size + " B)"
|
|
||||||
);
|
|
||||||
dialog.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionHideTheFile() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.components;
|
|
||||||
|
|
||||||
public interface OptionAction {
|
|
||||||
void action();
|
|
||||||
}
|
|
||||||
@@ -1,246 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.dialog;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Paint;
|
|
||||||
import android.graphics.Point;
|
|
||||||
import android.graphics.Rect;
|
|
||||||
import android.graphics.drawable.Drawable;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.util.DisplayMetrics;
|
|
||||||
import android.util.TypedValue;
|
|
||||||
import android.view.Display;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.LinearLayout;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.ea.games.nfs13_na.R;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FilenameFilter;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class OpenFileDialog extends AlertDialog.Builder {
|
|
||||||
|
|
||||||
private String currentPath = Environment.getExternalStorageDirectory().getPath();
|
|
||||||
private FilenameFilter filenameFilter;
|
|
||||||
private List<File> files = new ArrayList<File>();
|
|
||||||
private TextView title;
|
|
||||||
private ListView listView;
|
|
||||||
private int selectedIndex = -1;
|
|
||||||
|
|
||||||
public OpenFileDialog(Context context) {
|
|
||||||
super(context);
|
|
||||||
title = createTitle(context);
|
|
||||||
changeTitle();
|
|
||||||
LinearLayout linearLayout = createMainLayout(context);
|
|
||||||
linearLayout.addView(createBackItem(context));
|
|
||||||
files.addAll(getFiles(currentPath));
|
|
||||||
listView = createListView(context);
|
|
||||||
listView.setAdapter(new FileAdapter(context, files));
|
|
||||||
linearLayout.addView(listView);
|
|
||||||
setCustomTitle(title)
|
|
||||||
.setView(linearLayout)
|
|
||||||
.setPositiveButton(R.string.ok_title, (dialog, which) -> {
|
|
||||||
if (selectedIndex > -1 && listener != null) {
|
|
||||||
listener.OnSelectedFile(listView.getItemAtPosition(selectedIndex).toString());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(R.string.cancel_title, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public AlertDialog show() {
|
|
||||||
files.addAll(getFiles(currentPath));
|
|
||||||
listView.setAdapter(new FileAdapter(getContext(), files));
|
|
||||||
return super.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private <T> List<T> asList(T[] a){
|
|
||||||
return Arrays.asList(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<File> getFiles(String directoryPath){
|
|
||||||
File directory = new File(directoryPath);
|
|
||||||
List<File> fileList = asList(directory.listFiles(filenameFilter));
|
|
||||||
Collections.sort(fileList, (file, file2) -> {
|
|
||||||
if (file.isDirectory() && file2.isFile())
|
|
||||||
return -1;
|
|
||||||
else if (file.isFile() && file2.isDirectory())
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return file.getPath().compareTo(file2.getPath());
|
|
||||||
});
|
|
||||||
return fileList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TextView createTextView(Context context, int style) {
|
|
||||||
TextView textView = new TextView(context);
|
|
||||||
textView.setTextAppearance(context, style);
|
|
||||||
int itemHeight = getItemHeight(context);
|
|
||||||
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight));
|
|
||||||
textView.setMinHeight(itemHeight);
|
|
||||||
textView.setGravity(Gravity.CENTER_VERTICAL);
|
|
||||||
textView.setPadding(15, 0, 0, 0);
|
|
||||||
return textView;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getItemHeight(Context context) {
|
|
||||||
TypedValue value = new TypedValue();
|
|
||||||
DisplayMetrics metrics = new DisplayMetrics();
|
|
||||||
context.getTheme().resolveAttribute(android.R.attr.rowHeight, value, true);
|
|
||||||
getDefaultDisplay(context).getMetrics(metrics);
|
|
||||||
return (int)TypedValue.complexToDimension(value.data, metrics);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTextWidth(String text, Paint paint) {
|
|
||||||
Rect bounds = new Rect();
|
|
||||||
paint.getTextBounds(text, 0, text.length(), bounds);
|
|
||||||
return bounds.left + bounds.width() + 80;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void changeTitle() {
|
|
||||||
String titleText = currentPath;
|
|
||||||
int screenWidth = getScreenSize(getContext()).x;
|
|
||||||
int maxWidth = (int) (screenWidth * 0.99);
|
|
||||||
if (getTextWidth(titleText, title.getPaint()) > maxWidth) {
|
|
||||||
while (getTextWidth("..." + titleText, title.getPaint()) > maxWidth)
|
|
||||||
{
|
|
||||||
int start = titleText.indexOf("/", 2);
|
|
||||||
if (start > 0)
|
|
||||||
titleText = titleText.substring(start);
|
|
||||||
else
|
|
||||||
titleText = titleText.substring(2);
|
|
||||||
}
|
|
||||||
title.setText("..." + titleText);
|
|
||||||
} else {
|
|
||||||
title.setText(titleText);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private TextView createTitle(Context context) {
|
|
||||||
TextView textView = new TextView(context);
|
|
||||||
textView.setTextAppearance(context, android.R.style.TextAppearance_DeviceDefault_DialogWindowTitle);
|
|
||||||
int itemHeight = getItemHeight(context);
|
|
||||||
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, itemHeight));
|
|
||||||
textView.setMinHeight(itemHeight);
|
|
||||||
textView.setGravity(Gravity.CENTER_VERTICAL);
|
|
||||||
textView.setPadding(15, 0, 0, 0);
|
|
||||||
textView.setText(currentPath);
|
|
||||||
return textView;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void RebuildFiles(ArrayAdapter<File> adapter) {
|
|
||||||
try{
|
|
||||||
List<File> fileList = getFiles(currentPath);
|
|
||||||
files.clear();
|
|
||||||
selectedIndex = -1;
|
|
||||||
files.addAll(fileList);
|
|
||||||
adapter.notifyDataSetChanged();
|
|
||||||
changeTitle();
|
|
||||||
} catch (NullPointerException e){
|
|
||||||
Toast.makeText(getContext(), android.R.string.unknownName, Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public OpenFileDialog setFilter(final String filter) {
|
|
||||||
filenameFilter = (file, fileName) -> {
|
|
||||||
File tempFile = new File(String.format("%s/%s", file.getPath(), fileName));
|
|
||||||
if (tempFile.isFile())
|
|
||||||
return tempFile.getName().matches(filter);
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ListView createListView(Context context) {
|
|
||||||
ListView listView = new ListView(context);
|
|
||||||
listView.setOnItemClickListener((adapterView, view, index, l) -> {
|
|
||||||
FileAdapter adapter = (FileAdapter) adapterView.getAdapter();
|
|
||||||
File file = adapter.getItem(index);
|
|
||||||
if (file.isDirectory()) {
|
|
||||||
currentPath = file.getPath();
|
|
||||||
RebuildFiles(adapter);
|
|
||||||
} else {
|
|
||||||
if (index != selectedIndex)
|
|
||||||
selectedIndex = index;
|
|
||||||
else
|
|
||||||
selectedIndex = -1;
|
|
||||||
adapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return listView;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Display getDefaultDisplay(Context context) {
|
|
||||||
return ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Point getScreenSize(Context context) {
|
|
||||||
Point screeSize = new Point();
|
|
||||||
getDefaultDisplay(context).getSize(screeSize);
|
|
||||||
return screeSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
private LinearLayout createMainLayout(Context context) {
|
|
||||||
LinearLayout linearLayout = new LinearLayout(context);
|
|
||||||
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
|
||||||
linearLayout.setMinimumHeight(750);
|
|
||||||
return linearLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
private TextView createBackItem(Context context) {
|
|
||||||
TextView textView = createTextView(context, android.R.style.TextAppearance_DeviceDefault_Small);
|
|
||||||
Drawable drawable = getContext().getResources().getDrawable(android.R.drawable.ic_menu_directions);
|
|
||||||
drawable.setBounds(0, 0, 60, 60);
|
|
||||||
textView.setCompoundDrawables(drawable, null, null, null);
|
|
||||||
textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
textView.setOnClickListener(view -> {
|
|
||||||
File file = new File(currentPath);
|
|
||||||
File parentDirectory = file.getParentFile();
|
|
||||||
if (parentDirectory != null) {
|
|
||||||
currentPath = parentDirectory.getPath();
|
|
||||||
RebuildFiles(((FileAdapter) listView.getAdapter()));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return textView;
|
|
||||||
}
|
|
||||||
|
|
||||||
class FileAdapter extends ArrayAdapter<File> {
|
|
||||||
|
|
||||||
public FileAdapter(Context context, List files) {
|
|
||||||
super(context, android.R.layout.simple_list_item_1, files);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
TextView view = (TextView) super.getView(position, convertView, parent);
|
|
||||||
File file = getItem(position);
|
|
||||||
view.setText(file.getName());
|
|
||||||
if (selectedIndex == position)
|
|
||||||
view.setBackgroundColor(getContext().getResources().getColor(android.R.color.holo_blue_light));
|
|
||||||
else
|
|
||||||
view.setBackgroundColor(getContext().getResources().getColor(android.R.color.background_dark));
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OpenDialogListener{
|
|
||||||
void OnSelectedFile(String fileName);
|
|
||||||
}
|
|
||||||
private OpenDialogListener listener;
|
|
||||||
|
|
||||||
public OpenFileDialog setOpenDialogListener(OpenDialogListener listener) {
|
|
||||||
this.listener = listener;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.dialog;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.Button;
|
|
||||||
import android.widget.CheckBox;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.ImageButton;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.ea.games.nfs13_na.R;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.SaveManager;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.UtilitiesAndData;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Диалог для содания бандлов
|
|
||||||
* Сам умеет их создавать
|
|
||||||
*/
|
|
||||||
public class SvmwCreatorDialog extends AlertDialog {
|
|
||||||
|
|
||||||
private EditText nameEdit;
|
|
||||||
private EditText desEdit;
|
|
||||||
private CheckBox isUseCurSaveBox;
|
|
||||||
private View mainView;
|
|
||||||
|
|
||||||
private boolean useCurrentSave;
|
|
||||||
|
|
||||||
private SaveManager manager;
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
private File svmwPath;
|
|
||||||
|
|
||||||
public SvmwCreatorDialog(Activity activity) {
|
|
||||||
super(activity);
|
|
||||||
context = activity.getApplicationContext();
|
|
||||||
svmwPath = new File(UtilitiesAndData.getExternalStorage() + File.separator + "svmw");
|
|
||||||
svmwPath.mkdir();
|
|
||||||
setTitle("Создание SVMW");
|
|
||||||
ImageButton a;
|
|
||||||
|
|
||||||
Button s;
|
|
||||||
mainView = LayoutInflater
|
|
||||||
.from(context)
|
|
||||||
.inflate(R.layout.saves, null, false);
|
|
||||||
|
|
||||||
nameEdit = (EditText) mainView.findViewById(R.id.name_svmw);
|
|
||||||
desEdit = (EditText) mainView.findViewById(R.id.des_svmw);
|
|
||||||
|
|
||||||
isUseCurSaveBox = (CheckBox) mainView.findViewById(R.id.isUseCurrentSave);
|
|
||||||
manager = new SaveManager(context);
|
|
||||||
|
|
||||||
//Конпка создания
|
|
||||||
setButton(context.getText(R.string.create_svmw_file_title), (dialog, witch) -> {
|
|
||||||
String name = getTextFrom(nameEdit);
|
|
||||||
String des = getTextFrom(desEdit);
|
|
||||||
if(name.isEmpty() | des.isEmpty()){
|
|
||||||
Toast.makeText(context, context.getText(R.string.toast_strings_must_be_entered), Toast.LENGTH_LONG).show();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
File to = new File(svmwPath.getAbsolutePath() + File.separator + name + ".svmw");
|
|
||||||
try {
|
|
||||||
to.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
manager.createBundleFile(des, to, UtilitiesAndData.getSaveFile());
|
|
||||||
});
|
|
||||||
//Кнопка отмены
|
|
||||||
setButton2(context.getText(R.string.cancel_title), (OnClickListener) null);
|
|
||||||
//Кнопка выбора отдельного файла
|
|
||||||
setButton3(context.getString(R.string.choose_svmw_file_title), (dialog, witch) -> {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
|
|
||||||
intent.setType("file/*");
|
|
||||||
getOwnerActivity().startActivityForResult(intent, 228);
|
|
||||||
});
|
|
||||||
|
|
||||||
isUseCurSaveBox.setOnCheckedChangeListener((buttonView, isChecked) -> getButton(AlertDialog.BUTTON3).setEnabled(!isChecked));
|
|
||||||
|
|
||||||
|
|
||||||
// Если включена опция "Использовать текущее сохранение" то заюлокировтаь кнопку выбора файла сохранения
|
|
||||||
|
|
||||||
setView(mainView);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getTextFrom(EditText editText){
|
|
||||||
return editText.getText().toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.dialog;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.TextView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import com.ea.games.nfs13_na.R;
|
|
||||||
import com.ea.ironmonkey.devmenu.util.SaveManager;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Диалог выбора и просмотра информации об svmw файле
|
|
||||||
*/
|
|
||||||
public class SvmwInspectorDialog extends AlertDialog {
|
|
||||||
|
|
||||||
private SaveManager manager;
|
|
||||||
private View mainView;
|
|
||||||
private boolean isWork;
|
|
||||||
private TextView description;
|
|
||||||
private TextView time;
|
|
||||||
|
|
||||||
public SvmwInspectorDialog(Context context, File svmw) {
|
|
||||||
super(context);
|
|
||||||
manager = new SaveManager(context);
|
|
||||||
//Если пришедший файл - svmw иницализируем работу с ним если нет
|
|
||||||
// то выходим
|
|
||||||
// и ничего интересного не показываем((
|
|
||||||
isWork = manager.isSvmwFile(svmw);
|
|
||||||
if(isWork){
|
|
||||||
|
|
||||||
setTitle("Файл - " + svmw.getName());
|
|
||||||
|
|
||||||
mainView = LayoutInflater
|
|
||||||
.from(context)
|
|
||||||
.inflate(R.layout.inspector, null, false);
|
|
||||||
|
|
||||||
description = (TextView) mainView.findViewById(R.id.description);
|
|
||||||
description.setText(manager.getDescriptionOf(svmw));
|
|
||||||
|
|
||||||
time = (TextView) mainView.findViewById(R.id.date);
|
|
||||||
Date dateOfCreate = manager.getDateOfCreateOf(svmw);
|
|
||||||
String format = SaveManager.dateFormat.format(dateOfCreate);
|
|
||||||
time.setText(time.getText() + ": " + format);
|
|
||||||
|
|
||||||
setButton(context.getString(R.string.title_load_svmw), (dialog, which) -> {
|
|
||||||
manager.loadBundleFile(svmw);
|
|
||||||
});
|
|
||||||
setButton2(context.getString(R.string.cancel_title), (OnClickListener) null);
|
|
||||||
|
|
||||||
setView(mainView);
|
|
||||||
|
|
||||||
|
|
||||||
}else Toast.makeText(context, "Это не svmw!", Toast.LENGTH_LONG).show();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void show() {
|
|
||||||
if(isWork) super.show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.util;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
public class Observer {
|
|
||||||
|
|
||||||
private static final String LOG_TAG = "Observer";
|
|
||||||
|
|
||||||
public static void onCallingMethod(Method... states){
|
|
||||||
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
|
|
||||||
|
|
||||||
Log.i(LOG_TAG, "info{");
|
|
||||||
if(states.length != 0){
|
|
||||||
Log.i(LOG_TAG, "States of method:");
|
|
||||||
for(Method mthd : states){
|
|
||||||
Log.i(LOG_TAG, "\t" + mthd.title);
|
|
||||||
}
|
|
||||||
Log.i(LOG_TAG, "\n");
|
|
||||||
}
|
|
||||||
for(int i = 1; i < stackTrace.length; i++) {
|
|
||||||
Log.i(LOG_TAG, "\t" + stackTrace[i]);
|
|
||||||
}
|
|
||||||
Log.i(LOG_TAG, "}");
|
|
||||||
}
|
|
||||||
|
|
||||||
private interface MethodCallingCounter{
|
|
||||||
|
|
||||||
|
|
||||||
void call();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Перечисление состояний методов при из анализе и изменении, доработке */
|
|
||||||
public enum Method implements MethodCallingCounter{
|
|
||||||
/** Состояние невозможгости декомпиляции */
|
|
||||||
IMPOSSIBLE_TO_DECOMPILE("Impossible to decompile"){
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Уровни подозртельности работы методов при их воостановлении после
|
|
||||||
декомпиляции, или их доработке и изменеии.
|
|
||||||
|
|
||||||
/** Зеленая зона. Небольшие подозрения */
|
|
||||||
SUSPICIOUS_METHOD("Suspicious method"){
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Желтая зона. уже более подозрительны метод, что ставит под вопрос корректоность отрработки некторого функционала */
|
|
||||||
VERY_SUSPICIOUS_METHOD("Very suspicious Method") {
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/** Красная зона. Опасный метод который может привести к фатальным ошибкам */
|
|
||||||
HAZARD_METHOD("Hazard method") {
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
/** Уровни воостонавливаемости кода */
|
|
||||||
HARD_TO_RECOVER_LOGIC("Hard to recover logic of method") {
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
ON_CATCHING_EXCEPTION("on catching exception") {
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
RETURN_NULL("Method returns null") {
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
SOME_PACKAGE_IS_DELETED("Some package is deleted"){
|
|
||||||
@Override
|
|
||||||
public void call() {
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
Method(String title) {
|
|
||||||
this.title = title;
|
|
||||||
//this.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
|
||||||
|
|
||||||
public class ReplacementDataBaseHelper extends SQLiteOpenHelper {
|
|
||||||
|
|
||||||
public static final String MAIN_TABLE_NAME = "Replacements";
|
|
||||||
public static final String PATH_TO_REPLACED_ELEMENT = "Path";
|
|
||||||
public static final String NAME_OF_BACKUPED_ELEMENT = "Original_element";
|
|
||||||
private static final int DATABASE_VERSION = 1;
|
|
||||||
|
|
||||||
public SQLiteDatabase getDatabase() {
|
|
||||||
return database;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SQLiteDatabase database;
|
|
||||||
|
|
||||||
|
|
||||||
public ReplacementDataBaseHelper(Context context) {
|
|
||||||
super(context, MAIN_TABLE_NAME + ".db", (SQLiteDatabase.CursorFactory) (db, masterQuery, editTable, query) -> null, DATABASE_VERSION);
|
|
||||||
database = context.openOrCreateDatabase(MAIN_TABLE_NAME + ".db", Context.MODE_PRIVATE, null);
|
|
||||||
database.execSQL("CREATE TABLE IF NOT EXISTS " + MAIN_TABLE_NAME + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, "
|
|
||||||
+ PATH_TO_REPLACED_ELEMENT + " TEXT,"
|
|
||||||
+ NAME_OF_BACKUPED_ELEMENT + " TEXT);");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(SQLiteDatabase db) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.util;
|
|
||||||
|
|
||||||
public interface ResultListener {
|
|
||||||
|
|
||||||
default void onResult(Object data){}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,186 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.util;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Менедженер создания и загрузки сохранений в игру<br/>
|
|
||||||
* Создает bundle-файлы .svmw и загружает их<br/>
|
|
||||||
* Умеет загружать обчные .sb сохранения в игру
|
|
||||||
*/
|
|
||||||
public class SaveManager {
|
|
||||||
|
|
||||||
private Context context;
|
|
||||||
private static final String LOG_TAG = "SaveManager";
|
|
||||||
private static final byte[] svmw_header = "SVMW".getBytes(StandardCharsets.UTF_8);
|
|
||||||
private static final byte[] save_header = "SBIN".getBytes(StandardCharsets.UTF_8);
|
|
||||||
public static final String dateFormatStr = "dd.MM.yy:hh:mm:ss";
|
|
||||||
public static final SimpleDateFormat dateFormat = new SimpleDateFormat(dateFormatStr);
|
|
||||||
|
|
||||||
public SaveManager(Context context) {
|
|
||||||
this.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public File createBundleFile(String description, File fileToSave, File save) {
|
|
||||||
|
|
||||||
if (fileToSave.exists()) fileToSave.delete();
|
|
||||||
|
|
||||||
try {
|
|
||||||
fileToSave.createNewFile();
|
|
||||||
FileOutputStream fos = new FileOutputStream(fileToSave);
|
|
||||||
|
|
||||||
Date date = new Date();
|
|
||||||
|
|
||||||
Long time = date.getTime();
|
|
||||||
|
|
||||||
ByteBuffer bb = ByteBuffer.allocate(Long.SIZE);
|
|
||||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
|
||||||
bb.putLong(time);
|
|
||||||
bb.flip();
|
|
||||||
//bb.
|
|
||||||
String curDate = dateFormat.format(new Date());
|
|
||||||
|
|
||||||
fos.write(svmw_header);
|
|
||||||
fos.write(curDate.getBytes(StandardCharsets.UTF_8));
|
|
||||||
fos.write(description.getBytes(StandardCharsets.UTF_8));
|
|
||||||
fos.write(UtilitiesAndData.fileAsByteArray(save));
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.i("lol", fileToSave.getAbsolutePath());
|
|
||||||
//fileToSave.getAbsolutePath()
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
return fileToSave;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadBundleFile(File svmw) {
|
|
||||||
|
|
||||||
if(isSvmwFile(svmw)){
|
|
||||||
byte[] byteFile = UtilitiesAndData.fileAsByteArray(svmw);
|
|
||||||
int headerInByteFile = UtilitiesAndData.findHeaderInByteFile(byteFile, save_header);
|
|
||||||
byte[] result = new byte[byteFile.length - headerInByteFile];
|
|
||||||
System.arraycopy(byteFile, headerInByteFile, result, 0, result.length);
|
|
||||||
File dest = new File("/data/data/" + context.getPackageName() + "/files/var/nfstr_save.sb");
|
|
||||||
if(!dest.exists()) {
|
|
||||||
try {
|
|
||||||
dest.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
FileOutputStream fos = new FileOutputStream(dest);
|
|
||||||
fos.write(result);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescriptionOf(File svmw){
|
|
||||||
if(isSvmwFile(svmw)){
|
|
||||||
int offset = svmw_header.length + dateFormatStr.length();
|
|
||||||
byte[] byteFile = UtilitiesAndData.fileAsByteArray(svmw);
|
|
||||||
int headerInByteFile = UtilitiesAndData.findHeaderInByteFile(byteFile, save_header);
|
|
||||||
return new String(byteFile, offset, headerInByteFile - offset, StandardCharsets.UTF_8);
|
|
||||||
}
|
|
||||||
Log.i(LOG_TAG, "getDescription(), this is not a svmw file((( Return empty description(((");
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getDateOfCreateOf(File svmw){
|
|
||||||
if(isSvmwFile(svmw)){
|
|
||||||
int offset = svmw_header.length;
|
|
||||||
byte[] byteFile = UtilitiesAndData.fileAsByteArray(svmw);
|
|
||||||
|
|
||||||
String s = new String(byteFile, offset, dateFormatStr.length(), StandardCharsets.UTF_8);
|
|
||||||
|
|
||||||
try {
|
|
||||||
return dateFormat.parse(s);
|
|
||||||
} catch (ParseException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Log.i(LOG_TAG, "getDateOfCreateOf, this is not a svmw file((( Return null date(((");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void loadSaveFile(File save) {
|
|
||||||
if(isSaveFile(save)){
|
|
||||||
copySave(save);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSaveFile(File save) {
|
|
||||||
if(!save.exists() | isEmptyFile(save)) return false;
|
|
||||||
byte[] arr = UtilitiesAndData.fileAsByteArray(save);
|
|
||||||
for (int i = 0; i < save_header.length; i++)
|
|
||||||
if (save_header[i] != arr[i]) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSvmwFile(File svmw) {
|
|
||||||
if(!svmw.exists() | isEmptyFile(svmw)) return false;
|
|
||||||
byte[] arr = UtilitiesAndData.fileAsByteArray(svmw);
|
|
||||||
for (int i = 0; i < svmw_header.length; i++)
|
|
||||||
if (svmw_header[i] != arr[i]) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean isEmptyFile(File file){
|
|
||||||
return UtilitiesAndData.fileAsByteArray(file).length == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void copySave(File save){
|
|
||||||
|
|
||||||
File source = save;
|
|
||||||
|
|
||||||
File dest = new File("/data/data/" + context.getPackageName() + "/files/var/nfstr_save.sb");
|
|
||||||
|
|
||||||
|
|
||||||
if(!dest.exists()) {
|
|
||||||
try {
|
|
||||||
dest.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InputStream is = null;
|
|
||||||
OutputStream os = null;
|
|
||||||
try {
|
|
||||||
is = new FileInputStream(source);
|
|
||||||
os = new FileOutputStream(dest);
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int length;
|
|
||||||
while ((length = is.read(buffer)) > 0) {
|
|
||||||
os.write(buffer, 0, length);
|
|
||||||
}
|
|
||||||
is.close();
|
|
||||||
os.close();
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,290 +0,0 @@
|
|||||||
package com.ea.ironmonkey.devmenu.util;
|
|
||||||
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.ReplacementDataBaseHelper.MAIN_TABLE_NAME;
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.ReplacementDataBaseHelper.NAME_OF_BACKUPED_ELEMENT;
|
|
||||||
import static com.ea.ironmonkey.devmenu.util.ReplacementDataBaseHelper.PATH_TO_REPLACED_ELEMENT;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.os.Environment;
|
|
||||||
import android.util.Log;
|
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
public class UtilitiesAndData {
|
|
||||||
|
|
||||||
private static Context context;
|
|
||||||
private static FileOutputStream stream;
|
|
||||||
public static final int OPEN_FILE_ON_REPLACE_REQUEST = 100;
|
|
||||||
public static final int READ_FILE_REQUEST_CODE = 101;
|
|
||||||
|
|
||||||
private static final String LOG_TAG = "UtilitiesAndData";
|
|
||||||
|
|
||||||
public static void init(Context context){
|
|
||||||
UtilitiesAndData.context = context;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setLogger(File file){
|
|
||||||
if(file.exists()){
|
|
||||||
try {
|
|
||||||
stream = new FileOutputStream(file);
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Log.wtf(LOG_TAG, "cant create out stream(((");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void deleteRecursive(File fileOrDirectory) {
|
|
||||||
if (fileOrDirectory.isDirectory())
|
|
||||||
for (File child : fileOrDirectory.listFiles())
|
|
||||||
deleteRecursive(child);
|
|
||||||
|
|
||||||
fileOrDirectory.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isLoggerEnabled(){
|
|
||||||
return stream != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void printLog(String msg){
|
|
||||||
try{
|
|
||||||
if(isLoggerEnabled())
|
|
||||||
stream.write(msg.getBytes(StandardCharsets.UTF_8));
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.wtf(LOG_TAG, "cant write to stream(((");
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getInternalStorage(){
|
|
||||||
return "/data/data/" + context.getPackageName();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getExternalStorage(){
|
|
||||||
return Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + context.getPackageName() + "/files";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static File getDevMenuSwitcher(){
|
|
||||||
return new File(UtilitiesAndData.getExternalStorage() + File.separator + "DevMenu");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static File getSaveFile(){
|
|
||||||
File save = new File(getInternalStorage() + File.separator + "files" + File.separator + "var" + File.separator + "nfstr_save.sb");
|
|
||||||
if(!save.exists()) {
|
|
||||||
try {
|
|
||||||
save.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return save;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getReplacementsStorage(){
|
|
||||||
return getInternalStorage() + File.separator + "replace";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isFirstRun(){
|
|
||||||
File temp = new File(getInternalStorage() + File.separator + "load");
|
|
||||||
try {
|
|
||||||
if(!temp.exists()){
|
|
||||||
temp.createNewFile();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final String[] exclusionNamesArr = {
|
|
||||||
|
|
||||||
"replace",
|
|
||||||
"lib",
|
|
||||||
"databases"
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
public static void copy(File from, File to){
|
|
||||||
copy(from.getAbsolutePath(), to.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void copy(String from, String to) {
|
|
||||||
File source = new File(from);
|
|
||||||
|
|
||||||
File dest = new File(to);
|
|
||||||
|
|
||||||
|
|
||||||
if (!dest.exists()) {
|
|
||||||
try {
|
|
||||||
dest.createNewFile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InputStream is = null;
|
|
||||||
OutputStream os = null;
|
|
||||||
try {
|
|
||||||
is = new FileInputStream(source);
|
|
||||||
os = new FileOutputStream(dest);
|
|
||||||
Math.max(getFileSize(source), getFileSize(dest));
|
|
||||||
byte[] buffer = new byte[1024];
|
|
||||||
int length;
|
|
||||||
while ((length = is.read(buffer)) > 0) {
|
|
||||||
os.write(buffer, 0, length);
|
|
||||||
}
|
|
||||||
is.close();
|
|
||||||
os.close();
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
Log.e("lol", e.toString());
|
|
||||||
e.printStackTrace();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e("lol1", e.toString());
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long getFileSize(final File file) {
|
|
||||||
if (file == null || !file.exists())
|
|
||||||
return 0;
|
|
||||||
if (!file.isDirectory())
|
|
||||||
return file.length();
|
|
||||||
final List<File> dirs = new LinkedList<>();
|
|
||||||
dirs.add(file);
|
|
||||||
long result = 0;
|
|
||||||
while (!dirs.isEmpty()) {
|
|
||||||
final File dir = dirs.remove(0);
|
|
||||||
if (!dir.exists())
|
|
||||||
continue;
|
|
||||||
final File[] listFiles = dir.listFiles();
|
|
||||||
if (listFiles == null || listFiles.length == 0)
|
|
||||||
continue;
|
|
||||||
for (final File child : listFiles) {
|
|
||||||
result += child.length();
|
|
||||||
if (child.isDirectory())
|
|
||||||
dirs.add(child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final Set<String> exclusionNames = new HashSet<>(Arrays.asList(exclusionNamesArr));
|
|
||||||
|
|
||||||
public static boolean isExclusionName(String name){
|
|
||||||
return exclusionNames.contains(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static void recoverFile(String path){
|
|
||||||
ReplacementDataBaseHelper dataBaseHelper = new ReplacementDataBaseHelper(context);
|
|
||||||
SQLiteDatabase writableDatabase = dataBaseHelper.getDatabase();
|
|
||||||
Cursor query = writableDatabase.rawQuery("SELECT " + PATH_TO_REPLACED_ELEMENT + " , " + NAME_OF_BACKUPED_ELEMENT + " FROM " + MAIN_TABLE_NAME + " WHERE " + PATH_TO_REPLACED_ELEMENT + " = \"" + path + "\"", null);
|
|
||||||
if(query.getCount() == 1) {
|
|
||||||
query.moveToFirst();
|
|
||||||
//Путь к заменяемому файлу
|
|
||||||
String pathToReplace = query.getString(query.getColumnIndex(PATH_TO_REPLACED_ELEMENT));
|
|
||||||
//Имя бэкапа
|
|
||||||
String nameFile = query.getString(query.getColumnIndex(NAME_OF_BACKUPED_ELEMENT));
|
|
||||||
|
|
||||||
//Файл замены
|
|
||||||
File toReplace = new File(pathToReplace);
|
|
||||||
|
|
||||||
//Файл бэкапа
|
|
||||||
File backup = new File(UtilitiesAndData.getReplacementsStorage() + File.separator + nameFile);
|
|
||||||
|
|
||||||
copy(backup, toReplace);
|
|
||||||
|
|
||||||
writableDatabase.delete(MAIN_TABLE_NAME, PATH_TO_REPLACED_ELEMENT + " = ?", new String[]{path});
|
|
||||||
backup.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
query.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] generateMD5(File file){
|
|
||||||
try {
|
|
||||||
return DigestUtils.md5(new FileInputStream(file));
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return new byte[1];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void getInfoAboutFile(File file){
|
|
||||||
Log.i(LOG_TAG, "Info about File -> " + file.getAbsolutePath());
|
|
||||||
if(file.exists()){
|
|
||||||
if(file.isFile()) {
|
|
||||||
Log.i(LOG_TAG, "isCanRead = " + file.canRead());
|
|
||||||
Log.i(LOG_TAG, "isCanWrite = " + file.canWrite());
|
|
||||||
Log.i(LOG_TAG, "isCanExecute = " + file.canExecute());
|
|
||||||
}else
|
|
||||||
Log.i(LOG_TAG, "its dir!");
|
|
||||||
}else
|
|
||||||
Log.wtf(LOG_TAG, "it does not exists!");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] fileAsByteArray(File file){
|
|
||||||
byte[] b = new byte[(int) file.length()];
|
|
||||||
try {
|
|
||||||
FileInputStream fileInputStream = new FileInputStream(file);
|
|
||||||
fileInputStream.read(b);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void saveBytesToFile(byte[] bytes, File saveTo){
|
|
||||||
try{
|
|
||||||
saveTo.createNewFile();
|
|
||||||
FileOutputStream outputStream = new FileOutputStream(saveTo);
|
|
||||||
outputStream.write(bytes);
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int findHeaderInByteFile(byte[] byteFile, byte[] header){
|
|
||||||
int[] pf = prefix(header);
|
|
||||||
int index = 0;
|
|
||||||
for (int i = 0; i < byteFile.length; i++){
|
|
||||||
while (index > 0 && header[index] != byteFile[i]) index = pf[index - 1];
|
|
||||||
if (header[index] == byteFile[i]) index++;
|
|
||||||
if (index == header.length) return i - index + 1;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Префикс функция для алгоритма КМП
|
|
||||||
*/
|
|
||||||
private static int[] prefix(byte[] s) {
|
|
||||||
int[] result = new int[s.length];
|
|
||||||
result[0] = 0;
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
for (int i = 1; i < s.length; i++) {
|
|
||||||
while (index >= 0 && s[index] != s[i]) { index--; }
|
|
||||||
index++;
|
|
||||||
result[i] = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user