Commit 355e5ab8 authored by Dark Zane's avatar Dark Zane Committed by GitHub

Merge branch 'fallenstardust:master' into YGOMOBILE-1

parents da003669 de1bdabc
...@@ -656,7 +656,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) { ...@@ -656,7 +656,7 @@ bool MenuHandler::OnEvent(const irr::SEvent& event) {
myswprintf(infobuf, L"%ls\n===VS===\n%ls\n", player_names[0].c_str(), player_names[1].c_str()); myswprintf(infobuf, L"%ls\n===VS===\n%ls\n", player_names[0].c_str(), player_names[1].c_str());
repinfo.append(infobuf); repinfo.append(infobuf);
mainGame->ebRepStartTurn->setText(L"1"); mainGame->ebRepStartTurn->setText(L"1");
mainGame->SetStaticText(mainGame->stReplayInfo, 180, mainGame->guiFont, repinfo.c_str()); mainGame->SetStaticText(mainGame->stReplayInfo, 180 * mainGame->xScale, mainGame->guiFont, repinfo.c_str());
break; break;
} }
case LISTBOX_SINGLEPLAY_LIST: { case LISTBOX_SINGLEPLAY_LIST: {
......
...@@ -1335,7 +1335,7 @@ public class DeckManagerFragment extends BaseFragemnt implements RecyclerViewIte ...@@ -1335,7 +1335,7 @@ public class DeckManagerFragment extends BaseFragemnt implements RecyclerViewIte
String fileFullName = deckData.getDeckName() + YDK_FILE_EX; String fileFullName = deckData.getDeckName() + YDK_FILE_EX;
File dir = new File(getActivity().getApplicationInfo().dataDir, "cache"); File dir = new File(getActivity().getApplicationInfo().dataDir, "cache");
//将卡组存到cache缓存目录中 //将卡组存到cache缓存目录中
boolean result = DeckSquareFileUtil.saveFileToPath(dir.getPath(), fileFullName, deckData.getDeckYdk(), convertToUnixTimestamp(deckData.getDeckUpdateDate())); boolean result = DeckSquareFileUtil.saveFileToPath(dir.getPath(), fileFullName, deckData.getDeckYdk(), deckData.getDeckUpdateDate());
if (result) {//存储成功,使用预加载功能 if (result) {//存储成功,使用预加载功能
LogUtil.i(TAG, "square deck detail done"); LogUtil.i(TAG, "square deck detail done");
//File file = new File(dir, fileFullName); //File file = new File(dir, fileFullName);
......
...@@ -51,7 +51,7 @@ public class DeckManageDialog extends DialogFragment implements YGODeckDialogUti ...@@ -51,7 +51,7 @@ public class DeckManageDialog extends DialogFragment implements YGODeckDialogUti
ViewPager2 viewPager = view.findViewById(R.id.deck_view_pager); ViewPager2 viewPager = view.findViewById(R.id.deck_view_pager);
TabLayout tabLayout = view.findViewById(R.id.deck_manager_tab_layout); TabLayout tabLayout = view.findViewById(R.id.deck_manager_tab_layout);
viewPager.setUserInputEnabled(false); viewPager.setUserInputEnabled(true);
// Setup adapter // Setup adapter
ViewPagerAdapter adapter = new ViewPagerAdapter(this, mOnDeckMenuListener, this); ViewPagerAdapter adapter = new ViewPagerAdapter(this, mOnDeckMenuListener, this);
viewPager.setAdapter(adapter); viewPager.setAdapter(adapter);
......
package cn.garymb.ygomobile.ui.cards.deck_square; package cn.garymb.ygomobile.ui.cards.deck_square;
import static cn.garymb.ygomobile.Constants.CORE_DECK_PATH;
import android.widget.Toast; import android.widget.Toast;
import com.google.gson.Gson; import com.google.gson.Gson;
...@@ -35,7 +37,6 @@ import cn.garymb.ygomobile.ui.cards.deck_square.api_response.PushSingleDeck; ...@@ -35,7 +37,6 @@ import cn.garymb.ygomobile.ui.cards.deck_square.api_response.PushSingleDeck;
import cn.garymb.ygomobile.ui.cards.deck_square.api_response.PushSingleDeckResponse; import cn.garymb.ygomobile.ui.cards.deck_square.api_response.PushSingleDeckResponse;
import cn.garymb.ygomobile.ui.cards.deck_square.api_response.SquareDeckResponse; import cn.garymb.ygomobile.ui.cards.deck_square.api_response.SquareDeckResponse;
import cn.garymb.ygomobile.ui.cards.deck_square.bo.MyDeckItem; import cn.garymb.ygomobile.ui.cards.deck_square.bo.MyDeckItem;
import cn.garymb.ygomobile.ui.cards.deck_square.bo.SyncMutliDeckResult;
import cn.garymb.ygomobile.ui.plus.VUiKit; import cn.garymb.ygomobile.ui.plus.VUiKit;
import cn.garymb.ygomobile.utils.DeckUtil; import cn.garymb.ygomobile.utils.DeckUtil;
import cn.garymb.ygomobile.utils.LogUtil; import cn.garymb.ygomobile.utils.LogUtil;
...@@ -204,6 +205,7 @@ public class DeckSquareApiUtil { ...@@ -204,6 +205,7 @@ public class DeckSquareApiUtil {
deckData.setDeckId(deckId); deckData.setDeckId(deckId);
deckData.setDeckName(deckfile.getName()); deckData.setDeckName(deckfile.getName());
deckData.setDeckType(deckfile.getTypeName());
deckData.setDeckCoverCard1(deckfile.getFirstCode()); deckData.setDeckCoverCard1(deckfile.getFirstCode());
deckData.setDelete(false); deckData.setDelete(false);
deckData.setDeckYdk(deckContent); deckData.setDeckYdk(deckContent);
...@@ -243,7 +245,7 @@ public class DeckSquareApiUtil { ...@@ -243,7 +245,7 @@ public class DeckSquareApiUtil {
data.setDeckName(myDeckItem.getDeckName()); data.setDeckName(myDeckItem.getDeckName());
data.setDeckCoverCard1(myDeckItem.getDeckCoverCard1()); data.setDeckCoverCard1(myDeckItem.getDeckCoverCard1());
data.setDeckId(deckIdList.get(i)); data.setDeckId(deckIdList.get(i));
data.setDeckUpdateTime(myDeckItem.getUpdateTimestamp());
decks.add(data); decks.add(data);
} }
return pushMultiDecks(decks, loginToken); return pushMultiDecks(decks, loginToken);
...@@ -327,12 +329,14 @@ public class DeckSquareApiUtil { ...@@ -327,12 +329,14 @@ public class DeckSquareApiUtil {
if (deckIdResult == null) { if (deckIdResult == null) {
return null; return null;
} }
List<String> deckId = deckIdResult.getDeckId();//从服务器获取 List<String> deckIdList = deckIdResult.getDeckId();//从服务器获取
if (deckId == null) { if (deckIdList == null) {
return null; return null;
} else {
LogUtil.i(TAG,"requestIdAndPushNewDecks deckIdList"+ deckIdList);
} }
return pushDecks(deckDataList, loginToken, deckId); return pushDecks(deckDataList, loginToken, deckIdList);
} }
/** /**
...@@ -353,12 +357,14 @@ public class DeckSquareApiUtil { ...@@ -353,12 +357,14 @@ public class DeckSquareApiUtil {
PushMultiDeck.DeckData data = new PushMultiDeck.DeckData(); PushMultiDeck.DeckData data = new PushMultiDeck.DeckData();
data.setDeckId(item.getDeckId()); data.setDeckId(item.getDeckId());
data.setDeckName(item.getDeckName()); data.setDeckName(item.getDeckName());
data.setDeckType(item.getDeckType());
data.setDeckCoverCard1(item.getDeckCoverCard1()); data.setDeckCoverCard1(item.getDeckCoverCard1());
data.setDeckUpdateTime(item.getUpdateTimestamp());
String deckContent = DeckSquareFileUtil.setDeckId(item.getDeckPath(), loginToken.getUserId(), item.getDeckId()); String deckContent = DeckSquareFileUtil.setDeckId(item.getDeckPath(), loginToken.getUserId(), item.getDeckId());
data.setDeckYdk(deckContent); data.setDeckYdk(deckContent);
LogUtil.w(TAG, "seesee syncMyDecks*要上传的 本地卡组: " + data.getDeckName()+"//"+data.getDeckId()+"//"+data.getDeckCoverCard1()+"//"+data.getDeckYdk()); LogUtil.w(TAG, "syncMyDecks(368) *要上传的* 本地卡组: " + data.getDeckType() +"//" + data.getDeckName()+"//"+data.getDeckId()+"//"+data.getDeckCoverCard1()+"//"+data.getDeckUpdateTime());
dataList.add(data); dataList.add(data);
} }
return pushMultiDecks(dataList, loginToken); return pushMultiDecks(dataList, loginToken);
...@@ -516,7 +522,7 @@ public class DeckSquareApiUtil { ...@@ -516,7 +522,7 @@ public class DeckSquareApiUtil {
if (onlineDeck.getDeckName().equals(deckFile.getName())) { if (onlineDeck.getDeckName().equals(deckFile.getName())) {
// 删除在线卡组(异步处理) // 删除在线卡组(异步处理)
VUiKit.defer().when(() -> { VUiKit.defer().when(() -> {
PushSingleDeckResponse deckResponse = DeckSquareApiUtil.deleteDeck(onlineDeck.getDeckId(), loginToken); PushSingleDeckResponse deckResponse = deleteDeck(onlineDeck.getDeckId(), loginToken);
return deckResponse; return deckResponse;
}).fail((deleteError) -> { }).fail((deleteError) -> {
LogUtil.e(TAG, "Delete Online Deck failed: " + deleteError); LogUtil.e(TAG, "Delete Online Deck failed: " + deleteError);
...@@ -574,117 +580,6 @@ public class DeckSquareApiUtil { ...@@ -574,117 +580,6 @@ public class DeckSquareApiUtil {
String url = "http://rarnu.xyz:38383/api/mdpro3/deck/" + deckId; String url = "http://rarnu.xyz:38383/api/mdpro3/deck/" + deckId;
} }
public static SyncMutliDeckResult synchronizeDecksV2() throws IOException {
SyncMutliDeckResult autoSyncResult = new SyncMutliDeckResult();
// 检查用户是否登录
LoginToken loginToken = DeckSquareApiUtil.getLoginData();
if (loginToken == null) {
autoSyncResult.setFlag(false);
autoSyncResult.setInfo("need login");
return autoSyncResult;
}
// 获取本地卡组列表
List<MyDeckItem> localDecks = DeckSquareFileUtil.getMyDeckItem();
// 获取在线卡组列表
MyDeckResponse onlineDecksResponse = DeckSquareApiUtil.getUserDecks(loginToken);
if (onlineDecksResponse == null || onlineDecksResponse.getData() == null) {
autoSyncResult.setFlag(false);
autoSyncResult.setInfo("no online decks");
return autoSyncResult;
}
List<MyOnlineDeckDetail> onlineDecks = onlineDecksResponse.getData();
// 用于标记在线卡组是否在本地有对应
Map<String, Boolean> onlineDeckProcessed = new HashMap<>();
for (MyOnlineDeckDetail onlineDeck : onlineDecks) {
onlineDeckProcessed.put(onlineDeck.getDeckName(), false);
}
List<MyDeckItem> syncUploadDecks = new ArrayList<>();
List<MyDeckItem> newPushDecks = new ArrayList<>();
// 遍历本地卡组,处理同名卡组的情况
for (MyDeckItem localDeck : localDecks) {
boolean foundOnlineDeck = false;
String localDeckName = localDeck.getDeckName().replace(Constants.YDK_FILE_EX, "");
for (MyOnlineDeckDetail onlineDeck : onlineDecks) {
String onLineDeckName = onlineDeck.getDeckName().replace(Constants.YDK_FILE_EX, "");
if (localDeckName.equals(onLineDeckName)) {
// 标记该在线卡组已处理
onlineDeckProcessed.put(onLineDeckName, true);
// 标记该本地卡组已处理
foundOnlineDeck = true;
// 比对更新时间
long localUpdateDate = localDeck.getUpdateTimestamp();
long onlineUpdateDate = DeckSquareFileUtil.convertToUnixTimestamp(onlineDeck.getDeckUpdateDate());//todo 这里应该把2025-05-19T06:11:17转成毫秒,onlineDeck.getDeckUpdateDate();
LogUtil.d("seesee 本地和在线时间差", localDeckName + ": " + (localUpdateDate - onlineUpdateDate > 0 ? "本地的-新" : "在线的-新"));
LogUtil.d("seesee 差多少", localDeckName + ": " + (localUpdateDate - onlineUpdateDate));
if (onlineUpdateDate > localUpdateDate) {
// 在线卡组更新时间更晚,下载在线卡组覆盖本地卡组
LogUtil.w(TAG, "seesee *下载* " + localDeck.getDeckPath());
autoSyncResult.syncDownload.add(localDeck);
downloadOnlineDeck(onlineDeck, localDeck.getDeckPath(), onlineUpdateDate);
} else if (onlineUpdateDate == localUpdateDate) {
LogUtil.w(TAG, "seesee 不需要同步: " + localDeck.getDeckName());
//时间戳相同,不需要更新
} else {
// 本地卡组更新时间更晚,上传本地卡组覆盖在线卡组
localDeck.setDeckName(localDeck.getDeckName().replace(Constants.YDK_FILE_EX, ""));//TODO 上版本很多人已经传了带.ydk的云备份,姑且只在这次再次上传时去掉.ydk
localDeck.setDeckCoverCard1(DeckUtil.getFirstCardCode(localDeck.getDeckPath()));
localDeck.setDeckId(onlineDeck.getDeckId());
LogUtil.w(TAG, "seesee -上传-" + localDeck.getDeckName());
syncUploadDecks.add(localDeck);
autoSyncResult.syncUpload.add(localDeck);
}
break;
}
}
// 本地卡组在在线列表中不存在,则需要获取新的deckid来直接上传
if (!foundOnlineDeck) {
localDeck.setDeckName(localDeck.getDeckName().replace(Constants.YDK_FILE_EX, ""));
localDeck.setDeckCoverCard1(DeckUtil.getFirstCardCode(localDeck.getDeckPath()));
LogUtil.w(TAG, "seesee upload deck new: " + localDeck.getDeckName() + "、封面id:" + localDeck.getDeckCoverCard1());
newPushDecks.add(localDeck);
autoSyncResult.newUpload.add(localDeck);
}
}
LogUtil.w(TAG, "before syncMyDecks-unpload syncUploadDecks size(): " + syncUploadDecks.size());
if (!syncUploadDecks.isEmpty()) {
PushMultiResponse response = syncMyDecks(syncUploadDecks, loginToken);
autoSyncResult.pushResponse = response;
LogUtil.w(TAG, "after syncMyDecks-upload");
}
LogUtil.w(TAG, "newPushDecks size " + newPushDecks.size());
if (!newPushDecks.isEmpty()) {
LogUtil.w(TAG, "before new decks-upload");
PushMultiResponse pushNewRes = requestIdAndPushNewDecks(newPushDecks, loginToken);
LogUtil.w(TAG, "after new decks-upload");
}
LogUtil.w(TAG, "before download online decks " + onlineDecks.size());
// 处理只存在于在线的卡组(即本地没有同名卡组)
for (MyOnlineDeckDetail onlineDeck : onlineDecks) {
String onLineDeckName = onlineDeck.getDeckName().replace(Constants.YDK_FILE_EX, "");
if (!onlineDeckProcessed.get(onLineDeckName)) {
autoSyncResult.newDownload.add(onlineDeck);
LogUtil.w(TAG, "sync-download new deck: " + onlineDeck.getDeckName());
SyncMutliDeckResult.DownloadResult downloadResult = downloadMissingDeckToLocal(onlineDeck, DeckSquareFileUtil.convertToUnixTimestamp(onlineDeck.getDeckUpdateDate()));
autoSyncResult.downloadResponse.add(downloadResult);
}
}
return autoSyncResult;
}
public static void synchronizeDecks() throws IOException { public static void synchronizeDecks() throws IOException {
// 检查用户是否登录 // 检查用户是否登录
LoginToken loginToken = DeckSquareApiUtil.getLoginData(); LoginToken loginToken = DeckSquareApiUtil.getLoginData();
...@@ -704,7 +599,7 @@ public class DeckSquareApiUtil { ...@@ -704,7 +599,7 @@ public class DeckSquareApiUtil {
// 缓存原始在线卡组(使用副本避免后续修改影响缓存) // 缓存原始在线卡组(使用副本避免后续修改影响缓存)
DeckManagerFragment.getOriginalData().clear(); DeckManagerFragment.getOriginalData().clear();
DeckManagerFragment.getOriginalData().addAll(new ArrayList<>(onlineDecks)); DeckManagerFragment.getOriginalData().addAll(onlineDecks);
// 遍历本地卡组与云备份卡组,过滤差异项(使用迭代器避免ConcurrentModificationException) // 遍历本地卡组与云备份卡组,过滤差异项(使用迭代器避免ConcurrentModificationException)
List<MyDeckItem> syncUploadDecks = new ArrayList<>(); List<MyDeckItem> syncUploadDecks = new ArrayList<>();
...@@ -720,20 +615,18 @@ public class DeckSquareApiUtil { ...@@ -720,20 +615,18 @@ public class DeckSquareApiUtil {
localDeck.setDeckName(localDeckName); localDeck.setDeckName(localDeckName);
localDeck.setDeckCoverCard1(DeckUtil.getFirstCardCode(localDeck.getDeckPath())); localDeck.setDeckCoverCard1(DeckUtil.getFirstCardCode(localDeck.getDeckPath()));
boolean isMatched = false;
// 2. 使用在线卡组的迭代器遍历(支持安全删除) // 2. 使用在线卡组的迭代器遍历(支持安全删除)
Iterator<MyOnlineDeckDetail> onlineIterator = onlineDecks.iterator(); Iterator<MyOnlineDeckDetail> onlineIterator = onlineDecks.iterator();
while (onlineIterator.hasNext()) { while (onlineIterator.hasNext()) {
MyOnlineDeckDetail onlineDeck = onlineIterator.next(); MyOnlineDeckDetail onlineDeck = onlineIterator.next();
String onLineDeckName = onlineDeck.getDeckName().replace(Constants.YDK_FILE_EX, ""); String onLineDeckName = onlineDeck.getDeckName().replace(Constants.YDK_FILE_EX, "");
if (localDeckName.equals(onLineDeckName)) { if (localDeckName.equals(onLineDeckName)) {//TODO 上个版本不支持卡组分类字段,新版本安装后必然会出现在线备份没卡组分类的场合与本地有分类的进行比较 && localDeck.getDeckType().equals(onlineDeck.getDeckType())
// 匹配到同名卡组:加入同步上传列表,并从原始集合中删除(避免重复处理) // 匹配到同名卡组:加入同步上传列表,并从原始集合中删除(避免重复处理)
localDeck.setDeckId(onlineDeck.getDeckId()); localDeck.setDeckId(onlineDeck.getDeckId());
syncUploadDecks.add(localDeck); syncUploadDecks.add(localDeck);
localIterator.remove(); // 安全删除本地卡组(迭代器方法) localIterator.remove(); // 安全删除本地卡组(迭代器方法)
onlineIterator.remove(); // 安全删除在线卡组(迭代器方法) onlineIterator.remove(); // 安全删除在线卡组(迭代器方法)
isMatched = true;
break; // 匹配后跳出内部循环 break; // 匹配后跳出内部循环
} }
} }
...@@ -745,8 +638,8 @@ public class DeckSquareApiUtil { ...@@ -745,8 +638,8 @@ public class DeckSquareApiUtil {
// 剩余的在线卡组都是新卡组(云端独有,需要下载) // 剩余的在线卡组都是新卡组(云端独有,需要下载)
backupDownloadDecks.addAll(onlineDecks); backupDownloadDecks.addAll(onlineDecks);
LogUtil.w(TAG, "seesee +要下载的 云备份卡组: " + backupDownloadDecks);
for (MyOnlineDeckDetail onlineDeck : backupDownloadDecks) { for (MyOnlineDeckDetail onlineDeck : backupDownloadDecks) {
LogUtil.w(TAG, "synchronizeDecks(750) +要下载的 云备份卡组: " + onlineDeck.getDeckType() + "//" + onlineDeck.getDeckName() + "//" + onlineDeck.getDeckUpdateDate());
// 确保文件名包含.ydk扩展名 // 确保文件名包含.ydk扩展名
String fileName = onlineDeck.getDeckName(); String fileName = onlineDeck.getDeckName();
if (!fileName.toLowerCase().endsWith(Constants.YDK_FILE_EX)) { if (!fileName.toLowerCase().endsWith(Constants.YDK_FILE_EX)) {
...@@ -754,12 +647,16 @@ public class DeckSquareApiUtil { ...@@ -754,12 +647,16 @@ public class DeckSquareApiUtil {
} }
String fileFullPath = AppsSettings.get().getDeckDir() + "/" + fileName; String fileFullPath = AppsSettings.get().getDeckDir() + "/" + fileName;
if (!onlineDeck.getDeckType().equals(""))
fileFullPath = AppsSettings.get().getDeckDir() + "/" + onlineDeck.getDeckType()+ "/" + fileName;
// 保存在线卡组到本地 // 保存在线卡组到本地
boolean saved = DeckSquareFileUtil.saveFileToPath(fileFullPath, onlineDeck.getDeckYdk(), DeckSquareFileUtil.convertToUnixTimestamp(onlineDeck.getDeckUpdateDate())); boolean saved = DeckSquareFileUtil.saveFileToPath(fileFullPath, onlineDeck.getDeckYdk(), onlineDeck.getDeckUpdateDate());
if (!saved) LogUtil.e(TAG, "seesee Failed to save deck file: " + fileFullPath); if (!saved) {
LogUtil.e(TAG, "synchronizeDecks(761) 保存失败!的 云备份卡组: " + fileFullPath);
LogUtil.i(TAG, "seesee Deck saved to: " + fileFullPath); } else {
LogUtil.i(TAG, "synchronizeDecks(763) 保存成功√的 云备份卡组: " + fileFullPath);
}
} }
// 上传本地卡组覆盖在线卡组 // 上传本地卡组覆盖在线卡组
...@@ -769,111 +666,4 @@ public class DeckSquareApiUtil { ...@@ -769,111 +666,4 @@ public class DeckSquareApiUtil {
LogUtil.w(TAG, "seesee +要上传的 本地卡组: " + newPushDecks); LogUtil.w(TAG, "seesee +要上传的 本地卡组: " + newPushDecks);
} }
} }
private static SyncMutliDeckResult.DownloadResult downloadMissingDeckToLocal(MyOnlineDeckDetail onlineDeck, Long onlineUpdateDate) {
try {
// 根据卡组ID查询在线卡组详情
DownloadDeckResponse deckResponse = DeckSquareApiUtil.getDeckById(onlineDeck.getDeckId());
if (deckResponse == null || deckResponse.getData() == null) {
LogUtil.e(TAG, "seesee Failed to get deck details for: " + onlineDeck.getDeckName());
return new SyncMutliDeckResult.DownloadResult(false, onlineDeck.getDeckId(), "Failed to get deck details for: " + onlineDeck.getDeckName());
}
// 构建本地文件路径
String deckDirectory = AppsSettings.get().getDeckDir();
File dir = new File(deckDirectory);
if (!dir.exists()) {
boolean created = dir.mkdirs();
if (!created) {
LogUtil.e(TAG, "seesee Failed to create directory: " + deckDirectory);
return new SyncMutliDeckResult.DownloadResult(false, onlineDeck.getDeckId(), "Failed to create directory: " + deckDirectory);
}
}
// 确保文件名包含.ydk扩展名
String fileName = onlineDeck.getDeckName();
if (!fileName.toLowerCase().endsWith(Constants.YDK_FILE_EX)) {
fileName += Constants.YDK_FILE_EX;
}
String fileFullPath = deckDirectory + "/" + fileName;
// 保存在线卡组到本地
boolean saved = DeckSquareFileUtil.saveFileToPath(fileFullPath, deckResponse.getData().getDeckYdk(), onlineUpdateDate);
if (!saved) {
LogUtil.e(TAG, "seesee Failed to save deck file: " + fileFullPath);
return new SyncMutliDeckResult.DownloadResult(false, onlineDeck.getDeckId(), "Failed to save deck file: " + fileFullPath);
}
LogUtil.i(TAG, "seesee Deck saved to: " + fileFullPath);
return new SyncMutliDeckResult.DownloadResult(true, onlineDeck.getDeckId());
} catch (Exception e) {
LogUtil.e(TAG, "seesee Error downloading missing deck: " + e.getMessage());
e.printStackTrace();
return new SyncMutliDeckResult.DownloadResult(false, onlineDeck.getDeckId(), "Error downloading missing deck: " + e.getMessage());
}
}
private static boolean downloadOnlineDeck(MyOnlineDeckDetail onlineDeck, String fileFullPath, Long onlineUpdateDate) {
try {
// 根据卡组ID查询在线卡组详情
DownloadDeckResponse deckResponse = DeckSquareApiUtil.getDeckById(onlineDeck.getDeckId());
if (deckResponse == null || deckResponse.getData() == null) {
LogUtil.e(TAG, "Failed to get deck details for: " + onlineDeck.getDeckName());
return false;
}
MyOnlineDeckDetail deckDetail = deckResponse.getData();
String deckContent = deckDetail.getDeckYdk();
// 保存在线卡组到本地
boolean saved = DeckSquareFileUtil.saveFileToPath(fileFullPath, deckContent, onlineUpdateDate);
if (!saved) {
LogUtil.e(TAG, "Failed to save deck file: " + fileFullPath);
return false;
}
LogUtil.i(TAG, "Deck updated: " + fileFullPath);
return true;
} catch (Exception e) {
LogUtil.e(TAG, "Error downloading deck: " + e.getMessage());
e.printStackTrace();
return false;
}
}
/**
* 将MyDeckItem调用单卡组同步接口推送到服务器
*
* @param localDeck
* @param onlineDeckId
* @param loginToken
* @return
*/
private static boolean uploadLocalDeck(MyDeckItem localDeck, String
onlineDeckId, LoginToken loginToken) {
try {
DeckFile deckFile = new DeckFile(localDeck.getDeckPath(), DeckType.ServerType.MY_SQUARE);
deckFile.setName(localDeck.getDeckName());
deckFile.setFirstCode(localDeck.getDeckCoverCard1());
// 上传本地卡组,使用在线卡组的deckId
PushSingleDeckResponse response = DeckSquareApiUtil.pushDeck(deckFile, loginToken, onlineDeckId);
if (response == null || !response.isData()) {
LogUtil.e(TAG, "Failed to upload deck: " + localDeck.getDeckName());
return false;
}
// 上传成功,更新本地卡组的deckId和上传状态
localDeck.setDeckId(onlineDeckId);
localDeck.setIdUploaded(2);
LogUtil.i(TAG, "Deck uploaded successfully: " + localDeck.getDeckName());
return true;
} catch (Exception e) {
LogUtil.e(TAG, "Error uploading deck: " + e.getMessage());
e.printStackTrace();
return false;
}
}
} }
\ No newline at end of file
...@@ -33,7 +33,7 @@ import ocgcore.data.Card; ...@@ -33,7 +33,7 @@ import ocgcore.data.Card;
public class DeckSquareFileUtil { public class DeckSquareFileUtil {
// //
private static final String TAG = "decksquareApiUtil"; private static final String TAG = "DeckSquareFileUtil";
//将MyOnlineDeckDetail转MyDeckItem类型list,有时候会需要用到 //将MyOnlineDeckDetail转MyDeckItem类型list,有时候会需要用到
public static List<MyDeckItem> toDeckItemList(List<MyOnlineDeckDetail> serverDecks) { public static List<MyDeckItem> toDeckItemList(List<MyOnlineDeckDetail> serverDecks) {
...@@ -44,7 +44,7 @@ public class DeckSquareFileUtil { ...@@ -44,7 +44,7 @@ public class DeckSquareFileUtil {
item.setDeckId(detail.getDeckId()); item.setDeckId(detail.getDeckId());
item.setUserId(detail.getUserId()); item.setUserId(detail.getUserId());
item.setDeckCoverCard1(detail.getDeckCoverCard1()); item.setDeckCoverCard1(detail.getDeckCoverCard1());
item.setUpdateDate(detail.getDeckUpdateDate()); item.setUpdateTimestamp(detail.getDeckUpdateDate());
item.setPublic(detail.isPublic()); item.setPublic(detail.isPublic());
myOnlineDecks.add(item); myOnlineDecks.add(item);
} }
...@@ -74,7 +74,7 @@ public class DeckSquareFileUtil { ...@@ -74,7 +74,7 @@ public class DeckSquareFileUtil {
} }
// userId = Integer.parseInt(line.replaceAll("###", "")); // userId = Integer.parseInt(line.replaceAll("###", ""));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
LogUtil.e(TAG, "integer" + line + "parse error" + e.toString()); LogUtil.e(TAG, "getId(77): integer" + line + "parse error" + e.toString());
} }
} else if (line.startsWith("##")) { } else if (line.startsWith("##")) {
...@@ -148,6 +148,12 @@ public class DeckSquareFileUtil { ...@@ -148,6 +148,12 @@ public class DeckSquareFileUtil {
String deckId = getId(file); String deckId = getId(file);
MyDeckItem item = new MyDeckItem(); MyDeckItem item = new MyDeckItem();
item.setDeckName(file.getName()); item.setDeckName(file.getName());
//如果是deck并且上一个目录是ygocore的话,保证不会把名字为deck的卡包识别为未分类
if (file.getParentFile().getName().equals(Constants.CORE_DECK_PATH) && file.getParentFile().getParentFile().getName().equals(Constants.PREF_DEF_GAME_DIR)) {
item.setDeckType("");
} else {
item.setDeckType(file.getParentFile().getName());
}
item.setUpdateTimestamp(file.lastModified()); item.setUpdateTimestamp(file.lastModified());
item.setDeckPath(file.getPath()); item.setDeckPath(file.getPath());
if (deckId != null) { if (deckId != null) {
...@@ -216,25 +222,40 @@ public class DeckSquareFileUtil { ...@@ -216,25 +222,40 @@ public class DeckSquareFileUtil {
public static boolean saveFile(File file, String content, long modificationTime) { public static boolean saveFile(File file, String content, long modificationTime) {
FileOutputStream fos = null; FileOutputStream fos = null;
try { try {
// 创建文件对象 // 确保父目录存在
fos = new FileOutputStream(file); File parentDir = file.getParentFile();
if (parentDir != null && !parentDir.exists()) {
boolean dirsCreated = parentDir.mkdirs(); // 创建所有缺失的父目录
if (!dirsCreated) {
LogUtil.e(TAG, "无法创建文件目录: " + parentDir.getAbsolutePath());
return false;
}
}
// 创建文件对象(如果文件不存在,会自动创建)
if (!file.exists()) {
boolean fileCreated = file.createNewFile();
if (!fileCreated) {
LogUtil.e(TAG, "无法创建文件: " + file.getAbsolutePath());
return false;
}
}
// 创建文件输出流 // 创建文件输出流
fos = new FileOutputStream(file);
// 写入内容 // 写入内容
fos.write(content.getBytes()); fos.write(content.getBytes(StandardCharsets.UTF_8)); // 使用 UTF-8 编码
fos.flush(); fos.flush();
// 设置指定的最后修改时间 // 设置指定的最后修改时间
boolean timeSet = file.setLastModified(modificationTime); boolean timeSet = file.setLastModified(modificationTime);
if (!timeSet) { if (!timeSet) {
LogUtil.w(TAG, "设置文件修改时间失败: " + file.getPath()); LogUtil.w(TAG, "设置文件修改时间失败: " + file.getPath());
} else { } else {
LogUtil.d(TAG, "设置文件修改时间成功: " + file.getPath());
LogUtil.w(TAG, "设置文件修改时间成功: " + file.getPath());
} }
} catch (Exception e) { } catch (Exception e) {
LogUtil.e(TAG, "保存文件失败", e); LogUtil.e(TAG, "保存文件失败", e);
e.printStackTrace();
return false; return false;
} finally { } finally {
if (fos != null) { if (fos != null) {
......
package cn.garymb.ygomobile.ui.cards.deck_square; package cn.garymb.ygomobile.ui.cards.deck_square;
import static cn.garymb.ygomobile.ui.cards.deck_square.DeckSquareFileUtil.convertToGMTDate;
import android.util.Log; import android.util.Log;
import android.widget.ImageView; import android.widget.ImageView;
...@@ -73,7 +75,7 @@ public class DeckSquareListAdapter extends BaseQuickAdapter<OnlineDeckDetail, Ba ...@@ -73,7 +75,7 @@ public class DeckSquareListAdapter extends BaseQuickAdapter<OnlineDeckDetail, Ba
protected void convert(BaseViewHolder helper, OnlineDeckDetail item) { protected void convert(BaseViewHolder helper, OnlineDeckDetail item) {
helper.setText(R.id.deck_info_name, item.getDeckName()); helper.setText(R.id.deck_info_name, item.getDeckName());
helper.setText(R.id.deck_contributor, item.getDeckContributor()); helper.setText(R.id.deck_contributor, item.getDeckContributor());
helper.setText(R.id.deck_last_date, item.getLastDate()); helper.setText(R.id.deck_last_date, convertToGMTDate(item.getLastDate()));
helper.setText(R.id.like_count, item.getDeckLike()+""); helper.setText(R.id.like_count, item.getDeckLike()+"");
ImageView cardImage = helper.getView(R.id.deck_info_image); ImageView cardImage = helper.getView(R.id.deck_info_image);
long code = item.getDeckCoverCard1(); long code = item.getDeckCoverCard1();
......
...@@ -36,7 +36,7 @@ import cn.garymb.ygomobile.utils.glide.GlideCompat; ...@@ -36,7 +36,7 @@ import cn.garymb.ygomobile.utils.glide.GlideCompat;
//之后读取平台上的卡组,与本地卡组列表做比较。 //之后读取平台上的卡组,与本地卡组列表做比较。
public class DeckSquareMyDeckFragment extends Fragment { public class DeckSquareMyDeckFragment extends Fragment {
private static final String TAG = "seesee"; private static final String TAG = "DeckSquareMyDeckFragment";
private FragmentDeckSquareMyDeckBinding binding; private FragmentDeckSquareMyDeckBinding binding;
private MyDeckListAdapter deckListAdapter; private MyDeckListAdapter deckListAdapter;
private String keyWord; private String keyWord;
......
package cn.garymb.ygomobile.ui.cards.deck_square; package cn.garymb.ygomobile.ui.cards.deck_square;
import static cn.garymb.ygomobile.ui.cards.DeckManagerFragment.originalData; import static cn.garymb.ygomobile.ui.cards.DeckManagerFragment.originalData;
import static cn.garymb.ygomobile.ui.cards.deck_square.DeckSquareFileUtil.convertToGMTDate;
import android.util.Log; import android.util.Log;
import android.widget.ImageView; import android.widget.ImageView;
...@@ -156,8 +157,8 @@ public class MyDeckListAdapter extends BaseQuickAdapter<MyOnlineDeckDetail, Base ...@@ -156,8 +157,8 @@ public class MyDeckListAdapter extends BaseQuickAdapter<MyOnlineDeckDetail, Base
@Override @Override
protected void convert(BaseViewHolder helper, MyOnlineDeckDetail item) { protected void convert(BaseViewHolder helper, MyOnlineDeckDetail item) {
helper.setText(R.id.my_deck_name, item.getDeckName()); helper.setText(R.id.my_deck_name, item.getDeckType().equals("") ? item.getDeckName() : "-"+item.getDeckType()+ "-\n" + item.getDeckName());
helper.setText(R.id.deck_update_date, item.getDeckUpdateDate()); helper.setText(R.id.deck_update_date, convertToGMTDate(item.getDeckUpdateDate()));
ImageView cardImage = helper.getView(R.id.deck_info_image); ImageView cardImage = helper.getView(R.id.deck_info_image);
long code = item.getDeckCoverCard1(); long code = item.getDeckCoverCard1();
if (item.isPublic()) { if (item.isPublic()) {
......
...@@ -11,10 +11,11 @@ public class MyOnlineDeckDetail implements Parcelable { ...@@ -11,10 +11,11 @@ public class MyOnlineDeckDetail implements Parcelable {
private String deckId; private String deckId;
private String deckContributor; private String deckContributor;
private String deckName; private String deckName;
private String deckType;
private String deckRank; private String deckRank;
private String deckLike; private String deckLike;
private String deckUploadDate; private long deckUploadDate;
private String deckUpdateDate; private long deckUpdateDate;
private int deckCoverCard1; private int deckCoverCard1;
private int deckCoverCard2; private int deckCoverCard2;
private int deckCoverCard3; private int deckCoverCard3;
...@@ -27,14 +28,15 @@ public class MyOnlineDeckDetail implements Parcelable { ...@@ -27,14 +28,15 @@ public class MyOnlineDeckDetail implements Parcelable {
private boolean isDelete; private boolean isDelete;
protected MyOnlineDeckDetail(Parcel in) { public MyOnlineDeckDetail(Parcel in) {
deckId = in.readString(); deckId = in.readString();
deckContributor = in.readString(); deckContributor = in.readString();
deckName = in.readString(); deckName = in.readString();
deckType = in.readString();
deckRank = in.readString(); deckRank = in.readString();
deckLike = in.readString(); deckLike = in.readString();
deckUploadDate = in.readString(); deckUploadDate = in.readLong();
deckUpdateDate = in.readString(); deckUpdateDate = in.readLong();
deckCoverCard1 = in.readInt(); deckCoverCard1 = in.readInt();
deckCoverCard2 = in.readInt(); deckCoverCard2 = in.readInt();
deckCoverCard3 = in.readInt(); deckCoverCard3 = in.readInt();
...@@ -69,10 +71,11 @@ public class MyOnlineDeckDetail implements Parcelable { ...@@ -69,10 +71,11 @@ public class MyOnlineDeckDetail implements Parcelable {
dest.writeString(deckId); dest.writeString(deckId);
dest.writeString(deckContributor); dest.writeString(deckContributor);
dest.writeString(deckName); dest.writeString(deckName);
dest.writeString(deckType);
dest.writeString(deckRank); dest.writeString(deckRank);
dest.writeString(deckLike); dest.writeString(deckLike);
dest.writeString(deckUploadDate); dest.writeLong(deckUploadDate);
dest.writeString(deckUpdateDate); dest.writeLong(deckUpdateDate);
dest.writeInt(deckCoverCard1); dest.writeInt(deckCoverCard1);
dest.writeInt(deckCoverCard2); dest.writeInt(deckCoverCard2);
dest.writeInt(deckCoverCard3); dest.writeInt(deckCoverCard3);
...@@ -110,6 +113,14 @@ public class MyOnlineDeckDetail implements Parcelable { ...@@ -110,6 +113,14 @@ public class MyOnlineDeckDetail implements Parcelable {
this.deckName = deckName; this.deckName = deckName;
} }
public void setDeckType(String deckType) {
this.deckType = deckType;
}
public String getDeckType() {
return deckType;
}
public String getDeckRank() { public String getDeckRank() {
return deckRank; return deckRank;
} }
...@@ -126,19 +137,19 @@ public class MyOnlineDeckDetail implements Parcelable { ...@@ -126,19 +137,19 @@ public class MyOnlineDeckDetail implements Parcelable {
this.deckLike = deckLike; this.deckLike = deckLike;
} }
public String getDeckUploadDate() { public long getDeckUploadDate() {
return deckUploadDate; return deckUploadDate;
} }
public void setDeckUploadDate(String deckUploadDate) { public void setDeckUploadDate(long deckUploadDate) {
this.deckUploadDate = deckUploadDate; this.deckUploadDate = deckUploadDate;
} }
public String getDeckUpdateDate() { public long getDeckUpdateDate() {
return deckUpdateDate; return deckUpdateDate;
} }
public void setDeckUpdateDate(String deckUpdateDate) { public void setDeckUpdateDate(long deckUpdateDate) {
this.deckUpdateDate = deckUpdateDate; this.deckUpdateDate = deckUpdateDate;
} }
......
...@@ -16,7 +16,7 @@ public class OnlineDeckDetail implements Parcelable { ...@@ -16,7 +16,7 @@ public class OnlineDeckDetail implements Parcelable {
private int deckCoverCard3; private int deckCoverCard3;
private int deckCase; private int deckCase;
private int deckProtector; private int deckProtector;
private String lastDate; private long lastDate;
private int userId; private int userId;
...@@ -30,7 +30,7 @@ public class OnlineDeckDetail implements Parcelable { ...@@ -30,7 +30,7 @@ public class OnlineDeckDetail implements Parcelable {
deckCoverCard3 = in.readInt(); deckCoverCard3 = in.readInt();
deckCase = in.readInt(); deckCase = in.readInt();
deckProtector = in.readInt(); deckProtector = in.readInt();
lastDate = in.readString(); lastDate = in.readLong();
userId = in.readInt(); userId = in.readInt();
} }
...@@ -62,7 +62,7 @@ public class OnlineDeckDetail implements Parcelable { ...@@ -62,7 +62,7 @@ public class OnlineDeckDetail implements Parcelable {
dest.writeInt(deckCoverCard3); dest.writeInt(deckCoverCard3);
dest.writeInt(deckCase); dest.writeInt(deckCase);
dest.writeInt(deckProtector); dest.writeInt(deckProtector);
dest.writeString(lastDate); dest.writeLong(lastDate);
dest.writeInt(userId); dest.writeInt(userId);
} }
...@@ -138,11 +138,9 @@ public class OnlineDeckDetail implements Parcelable { ...@@ -138,11 +138,9 @@ public class OnlineDeckDetail implements Parcelable {
this.deckProtector = deckProtector; this.deckProtector = deckProtector;
} }
public String getLastDate() { public long getLastDate() {return lastDate;}
return lastDate;
}
public void setLastDate(String lastDate) { public void setLastDate(long lastDate) {
this.lastDate = lastDate; this.lastDate = lastDate;
} }
......
...@@ -39,11 +39,13 @@ public class PushMultiDeck { ...@@ -39,11 +39,13 @@ public class PushMultiDeck {
public static class DeckData { public static class DeckData {
private String deckId; private String deckId;
private String deckName; private String deckName;
private String deckType;
private Integer deckCoverCard1 = 0; private Integer deckCoverCard1 = 0;
private Integer deckCoverCard2 = 0; private Integer deckCoverCard2 = 0;
private Integer deckCoverCard3 = 0; private Integer deckCoverCard3 = 0;
private Integer deckCase = 0; private Integer deckCase = 0;
private Integer deckProtector = 0; private Integer deckProtector = 0;
private long timestamp = 0;
private String deckYdk; private String deckYdk;
public String getDeckId() { public String getDeckId() {
...@@ -62,6 +64,14 @@ public class PushMultiDeck { ...@@ -62,6 +64,14 @@ public class PushMultiDeck {
this.deckName = deckName; this.deckName = deckName;
} }
public String getDeckType() {
return deckType;
}
public void setDeckType(String deckType) {
this.deckType = deckType;
}
public Integer getDeckCoverCard1() { public Integer getDeckCoverCard1() {
return deckCoverCard1; return deckCoverCard1;
} }
...@@ -102,6 +112,14 @@ public class PushMultiDeck { ...@@ -102,6 +112,14 @@ public class PushMultiDeck {
this.deckProtector = deckProtector; this.deckProtector = deckProtector;
} }
public long getDeckUpdateTime() {
return timestamp;
}
public void setDeckUpdateTime(long deckUpdateTime) {
this.timestamp = deckUpdateTime;
}
public String getDeckYdk() { public String getDeckYdk() {
return deckYdk; return deckYdk;
} }
......
...@@ -33,6 +33,7 @@ public class PushSingleDeck { ...@@ -33,6 +33,7 @@ public class PushSingleDeck {
public static class DeckData { public static class DeckData {
private String deckId; private String deckId;
private String deckName; private String deckName;
private String deckType;
private Integer deckCoverCard1 = 0; private Integer deckCoverCard1 = 0;
private Integer deckCoverCard2 = 0; private Integer deckCoverCard2 = 0;
private Integer deckCoverCard3 = 0; private Integer deckCoverCard3 = 0;
...@@ -57,6 +58,14 @@ public class PushSingleDeck { ...@@ -57,6 +58,14 @@ public class PushSingleDeck {
this.deckName = deckName; this.deckName = deckName;
} }
public String getDeckType() {
return deckType;
}
public void setDeckType(String deckType) {
this.deckType = deckType;
}
public Integer getDeckCoverCard1(Integer firstCode) { public Integer getDeckCoverCard1(Integer firstCode) {
return deckCoverCard1; return deckCoverCard1;
} }
......
...@@ -5,11 +5,13 @@ public class MyDeckItem { ...@@ -5,11 +5,13 @@ public class MyDeckItem {
private int idUploaded; private int idUploaded;
private int userId; private int userId;
private String deckName; private String deckName;
private String deckType;
private String deckId; private String deckId;
private String updateDate;
private long updateTimestamp; private long updateTimestamp;
private String deckPath;//本地卡组时,存储卡组路径 private String deckPath;//本地卡组时,存储卡组路径
...@@ -42,20 +44,20 @@ public class MyDeckItem { ...@@ -42,20 +44,20 @@ public class MyDeckItem {
this.deckName = deckName; this.deckName = deckName;
} }
public String getDeckId() { public String getDeckType() {
return deckId; return deckType;
} }
public void setDeckId(String deckId) { public void setDeckType(String deckType) {
this.deckId = deckId; this.deckType = deckType;
} }
public String getUpdateDate() { public String getDeckId() {
return updateDate; return deckId;
} }
public void setUpdateDate(String updateDate) { public void setDeckId(String deckId) {
this.updateDate = updateDate; this.deckId = deckId;
} }
public long getUpdateTimestamp() { public long getUpdateTimestamp() {
...@@ -97,8 +99,8 @@ public class MyDeckItem { ...@@ -97,8 +99,8 @@ public class MyDeckItem {
"idUploaded=" + idUploaded + "idUploaded=" + idUploaded +
", userId=" + userId + ", userId=" + userId +
", deckName='" + deckName + '\'' + ", deckName='" + deckName + '\'' +
", deckType='" + deckType + '\'' +
", deckId='" + deckId + '\'' + ", deckId='" + deckId + '\'' +
", updateDate='" + updateDate + '\'' +
", updateTimestamp=" + updateTimestamp + ", updateTimestamp=" + updateTimestamp +
", deckPath='" + deckPath + '\'' + ", deckPath='" + deckPath + '\'' +
", deckCoverCard1=" + deckCoverCard1 + ", deckCoverCard1=" + deckCoverCard1 +
......
package cn.garymb.ygomobile.ui.cards.deck_square.bo;
import java.util.ArrayList;
import java.util.List;
import cn.garymb.ygomobile.ui.cards.deck_square.api_response.MyOnlineDeckDetail;
import cn.garymb.ygomobile.ui.cards.deck_square.api_response.PushMultiResponse;
import cn.garymb.ygomobile.ui.cards.deck_square.api_response.PushSingleDeckResponse;
public class SyncMutliDeckResult {
boolean flag = false;
String info = null;
public PushMultiResponse pushResponse;
public List<MyDeckItem> syncUpload;//用于记录已推送的卡组
public List<MyDeckItem> newUpload;//用于记录第一次推送到云的卡组
public List<MyDeckItem> syncDownload;//用于记录已推送的卡组
public List<MyOnlineDeckDetail> newDownload;
public List<DownloadResult> downloadResponse;
public static class DownloadResult {
boolean flag;
String deckId;
String info;
public DownloadResult(boolean flag, String deckId) {
this.flag = flag;
this.deckId = deckId;
}
public DownloadResult(boolean flag, String deckId, String info) {
this.flag = flag;
this.deckId = deckId;
this.info = info;
}
}
public SyncMutliDeckResult() {
flag = true;
downloadResponse = new ArrayList<>();
newDownload = new ArrayList<>();
syncUpload = new ArrayList<>();
newUpload = new ArrayList<>();
syncDownload = new ArrayList<>();
}
public SyncMutliDeckResult(boolean flag, String info) {
this.flag = flag;
this.info = info;
downloadResponse = new ArrayList<>();
newDownload = new ArrayList<>();
syncUpload = new ArrayList<>();
newUpload = new ArrayList<>();
syncDownload = new ArrayList<>();
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public String getMessage() {
String info = "sync decks: " + syncUpload.size() + ", push new:" + newUpload.size() + ", download " + newDownload.size();
return info;
}
}
package cn.garymb.ygomobile.ui.cards.deck_square.bo;
import java.util.List;
public class UserDeckIds {
public List<String> deckId;
}
...@@ -29,7 +29,7 @@ public class OkhttpUtil { ...@@ -29,7 +29,7 @@ public class OkhttpUtil {
.readTimeout(30, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS) .writeTimeout(30, TimeUnit.SECONDS)
// keep-alive and connection pool defaults // keep-alive and connection pool defaults
.connectionPool(new ConnectionPool(2, 20, TimeUnit.SECONDS)) .connectionPool(new ConnectionPool(2, 40, TimeUnit.SECONDS))
.build(); .build();
......
...@@ -379,7 +379,7 @@ ...@@ -379,7 +379,7 @@
<string name="register">注册萌卡</string> <string name="register">注册萌卡</string>
<string name="sign_out">切换账号</string> <string name="sign_out">切换账号</string>
<string name="deck_square">卡组广场</string> <string name="deck_square">卡组广场</string>
<string name="my_deck_online">备份</string> <string name="my_deck_online">在线备份</string>
<string name="input_contributor_name">输入共享者名称</string> <string name="input_contributor_name">输入共享者名称</string>
<string name="sort_by_time">按时间顺序</string> <string name="sort_by_time">按时间顺序</string>
<string name="sort_by_thumb">按点赞顺序</string> <string name="sort_by_thumb">按点赞顺序</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment