主流程跑通
This commit is contained in:
@@ -16,7 +16,7 @@ me:开始治疗吧
|
||||
===
|
||||
title: 诊断初始化
|
||||
tags:
|
||||
position: 261,-1155
|
||||
position: 254,-1295
|
||||
---
|
||||
///在这里决定这次诊疗的目标是什么,以及目标判断相关的数值
|
||||
|
||||
@@ -37,9 +37,24 @@ position: 261,-1155
|
||||
//方便的触发针对eyetarget的对话,如果不喜欢这种写法可以商量,然后分开写
|
||||
<<declare $currentEyeTarget="未定义">>
|
||||
|
||||
|
||||
//当前步骤的填入clueName
|
||||
<<declare $clueName="">>
|
||||
//当前要分析的是第几个slot
|
||||
<<declare $clueBoardStep=0>>
|
||||
//当前要分析的slot填入的clue分类
|
||||
<<declare $clueCategory="">>
|
||||
//当前要分析的slot填入的cluematchCode
|
||||
<<declare $clueMatchCode="">>
|
||||
//上一步骤的matchCode
|
||||
<<declare $previousMatchCode="">>
|
||||
|
||||
|
||||
|
||||
<<fade_in 0.5>>
|
||||
<<load_scene 佩佩视觉模块>>
|
||||
<<OpenClueBoard ClueBoard>>
|
||||
<<Set_ViewVisualState ViewManager "ColorView" 1>>
|
||||
<<wait 0.5>>
|
||||
<<fade_out 0.5>>
|
||||
//<<jump 主维修界面>>
|
||||
@@ -47,9 +62,19 @@ position: 261,-1155
|
||||
|
||||
===
|
||||
|
||||
|
||||
title: AddAllClueToFavorites
|
||||
position: -760,-1665
|
||||
---
|
||||
<<generate_PunchTape ClueManager "海报" "EyeView" "liuying1-1" "红色" true>>
|
||||
<<generate_PunchTape ClueManager "植物" "EyeView" "liuying1-2" "绿色" true>>
|
||||
<<generate_PunchTape ClueManager "天空" "EyeView" "liuying1-3" "蓝色" true>>
|
||||
<<generate_MemoryClue ClueManager "病房" "liuying1-3" "蓝色" true>>
|
||||
<<generate_MemoryClue ClueManager "草地绘画" "liuying1-2" "绿色" true>>
|
||||
<<generate_MemoryClue ClueManager "夕阳景色" "liuying1-1" "红色" true>>
|
||||
<<generate_UFClue ClueManager UFImage can_grass_error 绿色 true>>
|
||||
===
|
||||
title: 主维修界面
|
||||
position: 261,-768
|
||||
position: 261,-771
|
||||
---
|
||||
<<start_transition ViewManager "MainView">>
|
||||
|
||||
@@ -57,11 +82,11 @@ position: 261,-768
|
||||
<<jump 流程结束>>
|
||||
<<endif>>
|
||||
|
||||
<<if $isFinishedClueBoard == true>>
|
||||
<<jump 结论>>
|
||||
<<endif>>
|
||||
// <<if $isFinishedClueBoard == true>>
|
||||
// <<jump 结论>>
|
||||
// <<endif>>
|
||||
|
||||
// 检查主目标是否完成并提供反馈
|
||||
// 检查主目标是否完成并提供反馈
|
||||
<<if $isFinishedEyeCheck == -1 && $isFinishedUFCheck == -1>>
|
||||
<<if $memoryCount == 3>>
|
||||
me: 似乎该检查的都检查了,应该去看下诊疗单了
|
||||
@@ -71,9 +96,60 @@ position: 261,-768
|
||||
<<endif>>
|
||||
<<endif>>
|
||||
===
|
||||
title: ClueBoard
|
||||
tags:
|
||||
position: -236,-1318
|
||||
---
|
||||
<<if $clueBoardStep == 0>>
|
||||
<<if $clueCategory == "UFView">>
|
||||
me: 嗯,这就是佩佩所说的绘画错误吧
|
||||
me: 不过,这个绘画错误又是由什么导致的呢?
|
||||
//<<set $clueBoardStep = $clueBoardStep + 1>>
|
||||
<<SetSlotCorrect ClueBoard>>
|
||||
<<AddNewClueSlot ClueBoard>>
|
||||
<<else>>
|
||||
<<if $clueCategory == "EyeView">>
|
||||
me: 似乎确实和佩佩的症状有关,但是先把最直接的错误表现找到吧
|
||||
<<elseif $clueCategory == "MemoryView">>
|
||||
me: 似乎确实和佩佩的症状有关,但是先把最直接的错误表现找到吧
|
||||
<<endif>>
|
||||
<<endif>>
|
||||
<<elseif $clueBoardStep == 1>>
|
||||
<<if $clueCategory == "MemoryView" && $clueMatchCode == $previousMatchCode>>
|
||||
me: 嗯,UF绘图需要索引记忆,就是由于这个记忆的调用出了问题,才导致了UF绘图的颜色错误
|
||||
me: 但是这个记忆的颜色为什么会出错呢?
|
||||
//<<set $clueBoardStep = $clueBoardStep + 1>>
|
||||
<<SetSlotCorrect ClueBoard>>
|
||||
<<AddNewClueSlot ClueBoard>>
|
||||
<<else>>
|
||||
<<if $clueCategory == "MemoryView">>
|
||||
me: 确实应该是记忆导致的UF绘图问题,但是从颜色看,应该不是这个记忆?
|
||||
<<elseif $clueCategory == "EyeView">>
|
||||
me: 似乎确实和佩佩的症状有关,但是先把导致绘图错误最直接的原因找到吧
|
||||
<<else>>
|
||||
me: 似乎不太相关呢
|
||||
<<endif>>
|
||||
<<endif>>
|
||||
<<elseif $clueBoardStep == 2>>
|
||||
<<if $clueCategory == "EyeView" && $clueMatchCode == $previousMatchCode>>
|
||||
me: 没错!佩佩在视觉中想象颜色的时候调用了这部分记忆
|
||||
me: 因为想象视觉的颜色而占据了部分记忆,所以UF在绘图时索引失效
|
||||
me: 一切都搞清楚了
|
||||
<<SetSlotCorrect ClueBoard>>
|
||||
<<jump 结论>>
|
||||
//<<command CompleteAnalysis>>
|
||||
<<else>>
|
||||
<<if $clueCategory == "EyeView">>
|
||||
me: 确实应该是视觉导致的记忆调用,但是好像不是这次调用引起的?
|
||||
<<else>>
|
||||
me: 似乎不太相关呢
|
||||
<<endif>>
|
||||
<<endif>>
|
||||
<<endif>>
|
||||
===
|
||||
title: 结论
|
||||
tags:
|
||||
position: 977,-739
|
||||
position: -236,-1047
|
||||
---
|
||||
//现在关于切换场景的数据保存还没有完成,建议先不切场景
|
||||
peipei:佩佩需要手术
|
||||
@@ -82,7 +158,7 @@ peipei:我们去手术吧
|
||||
===
|
||||
title: 手术
|
||||
tags:
|
||||
position: 978,-402
|
||||
position: -235,-768
|
||||
---
|
||||
<<wait_for_ClueBoard_close ClueBoard>>
|
||||
<<set_scissors_mode LineManager true>>
|
||||
@@ -90,7 +166,7 @@ position: 978,-402
|
||||
[command name=activate_socket_choice /]
|
||||
-> MemoryEyeScissor
|
||||
<<set_scissors_mode LineManager false>>
|
||||
<<complete_task TaskManager "执行记忆-视觉桥阻断术">>
|
||||
// <<complete_task TaskManager "执行记忆-视觉桥阻断术">>
|
||||
///<<shakeScreen ScreenEffect>>
|
||||
///<<hide_dialog>>
|
||||
///<<wait 2>>
|
||||
@@ -117,19 +193,12 @@ position: 978,-402
|
||||
|
||||
title: 流程结束
|
||||
tags:
|
||||
position: 262,-362
|
||||
position: 265,-184
|
||||
---
|
||||
me:再见佩佩
|
||||
===
|
||||
|
||||
title: Eye_sky
|
||||
tags:
|
||||
position: 1722,-1730
|
||||
---
|
||||
<<set_EyeState EyeManager "CanImagineColor">>
|
||||
<<EyeEffect_FadeIn EyeManager>>
|
||||
<<jump EyeCheckEnd>>
|
||||
===
|
||||
|
||||
title: IntoEyeView
|
||||
tags:
|
||||
position: 1962,-2069
|
||||
@@ -186,6 +255,14 @@ me:啊,出现错误抖动了
|
||||
<<jump EyeCheckEnd>>
|
||||
|
||||
===
|
||||
title: Eye_sky
|
||||
tags:
|
||||
position: 1722,-1730
|
||||
---
|
||||
<<set_EyeState EyeManager "CanImagineColor">>
|
||||
<<EyeEffect_FadeIn EyeManager>>
|
||||
<<jump EyeCheckEnd>>
|
||||
===
|
||||
|
||||
title: Eye_computer
|
||||
position: 2683,-1726
|
||||
@@ -374,10 +451,11 @@ position: -377,-1655
|
||||
<<generate_UFClue ClueManager UFImage can_grass_error 绿色>>
|
||||
me:生成好了
|
||||
<<elseif $isFinishedUFCheck==1>>
|
||||
<<set $isFinishedUFCheck=-1>>
|
||||
me: 再试试生成
|
||||
<<show_photo UFManager "can_grass_nromal">>
|
||||
<<show_photo UFManager "can_grass_normal">>
|
||||
<<hide_photo UFManager>>
|
||||
<<generate_UFClue ClueManager UFImage can_grass_error 绿色>>
|
||||
<<generate_UFClue ClueManager UFImage can_grass_normal 绿色>>
|
||||
me:生成好了
|
||||
<<endif>>
|
||||
<<jump 主维修界面>>
|
||||
|
||||
@@ -307,6 +307,37 @@ RectTransform:
|
||||
m_CorrespondingSourceObject: {fileID: 7131956091114956203, guid: e2211373480d40243a377721316dd8f7, type: 3}
|
||||
m_PrefabInstance: {fileID: 1886390393148784126}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
--- !u!1 &72131186
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
serializedVersion: 6
|
||||
m_Component:
|
||||
- component: {fileID: 72131187}
|
||||
m_Layer: 0
|
||||
m_Name: TestManager
|
||||
m_TagString: Untagged
|
||||
m_Icon: {fileID: 0}
|
||||
m_NavMeshLayer: 0
|
||||
m_StaticEditorFlags: 0
|
||||
m_IsActive: 1
|
||||
--- !u!4 &72131187
|
||||
Transform:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 72131186}
|
||||
serializedVersion: 2
|
||||
m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
|
||||
m_LocalPosition: {x: 0, y: 0, z: 0}
|
||||
m_LocalScale: {x: 1, y: 1, z: 1}
|
||||
m_ConstrainProportionsScale: 0
|
||||
m_Children: []
|
||||
m_Father: {fileID: 1009826577}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &72512885
|
||||
GameObject:
|
||||
m_ObjectHideFlags: 0
|
||||
@@ -2689,6 +2720,7 @@ Transform:
|
||||
- {fileID: 442870838}
|
||||
- {fileID: 2000641911}
|
||||
- {fileID: 1445926171}
|
||||
- {fileID: 72131187}
|
||||
m_Father: {fileID: 0}
|
||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||
--- !u!1 &1015707783
|
||||
@@ -5421,7 +5453,7 @@ PrefabInstance:
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4855407103418339723, guid: 68892fec64b888548bb2dc685526cf91, type: 3}
|
||||
propertyPath: m_Name
|
||||
value: ClueBaord
|
||||
value: ClueBoard
|
||||
objectReference: {fileID: 0}
|
||||
- target: {fileID: 4855407103418339723, guid: 68892fec64b888548bb2dc685526cf91, type: 3}
|
||||
propertyPath: m_IsActive
|
||||
|
||||
@@ -88,77 +88,84 @@ public class ClueBoardManager : MonoBehaviour
|
||||
}
|
||||
|
||||
// 添加新的 ClueSlot
|
||||
private void AddNewClueSlot()
|
||||
[YarnCommand("AddNewClueSlot")]
|
||||
public void AddNewClueSlot()
|
||||
{
|
||||
ClueSlotBase newSlot = Instantiate(initialClueSlotPrefab, clueSlotContainer);
|
||||
newSlot.ReleaseSlot(); // 初始化插槽为未占用状态
|
||||
newSlot.ReleaseSlot();
|
||||
clueSlots.Add(newSlot);
|
||||
}
|
||||
[YarnCommand("SetSlotCorrect")]
|
||||
public void SetSlotCorrect()
|
||||
{
|
||||
clueSlots[currentStep].SetSlotCorrect();
|
||||
currentStep++;
|
||||
}
|
||||
|
||||
private void CheckCurrentSlot()
|
||||
{
|
||||
if (currentStep >= clueSlots.Count) return;
|
||||
if (currentStep >= clueSlots.Count) return;
|
||||
|
||||
ClueSlotBase currentSlot = clueSlots[currentStep];
|
||||
if (!currentSlot.isOccupied)
|
||||
ClueSlotBase currentSlot = clueSlots[currentStep];
|
||||
Clue currentClue = currentSlot.GetComponentInChildren<ClueItem>()?.GetClueData();
|
||||
|
||||
if (currentClue == null)
|
||||
{
|
||||
conclue.text="还有待填入的症状";
|
||||
Debug.Log("Slot is empty. Please insert a Clue.");
|
||||
TriggerDialogue("", "", "", currentStep);
|
||||
return;
|
||||
}
|
||||
|
||||
Clue currentClue = currentSlot.GetComponentInChildren<ClueItem>()?.GetClueData();
|
||||
if (currentClue == null) return;
|
||||
// Trigger Yarn to handle the current clue, name, and step
|
||||
TriggerDialogue(currentClue.Category, currentClue.MatchCode, currentClue.ClueName, currentStep);
|
||||
}
|
||||
private void TriggerDialogue(string clueCategory, string matchCode, string clueName, int step)
|
||||
{
|
||||
if (DialogController.Instance.CheckIfNodeExistInCurrentYarnProject("ClueBoard"))
|
||||
{
|
||||
// Set Yarn variables
|
||||
DialogController.Instance.SetVariable("$clueBoardStep", step);
|
||||
DialogController.Instance.SetVariable("$clueCategory", clueCategory);
|
||||
DialogController.Instance.SetVariable("$clueMatchCode", matchCode);
|
||||
DialogController.Instance.SetVariable("$clueName", clueName);
|
||||
|
||||
// // 执行判定逻辑
|
||||
if (IsValidClueForStep(currentStep, currentClue))
|
||||
// Set the previous MatchCode for comparison in Yarn
|
||||
if (step > 0)
|
||||
{
|
||||
|
||||
Debug.Log("Correct Clue for step " + currentStep);
|
||||
currentStep++;
|
||||
|
||||
if (HasNextStep())
|
||||
Clue previousClue = clueSlots[step - 1].GetComponentInChildren<ClueItem>()?.GetClueData();
|
||||
if (previousClue != null)
|
||||
{
|
||||
conclue.text="正确,但似乎这个症状不是源头";
|
||||
AddNewClueSlot();
|
||||
}
|
||||
else
|
||||
{
|
||||
conclue.text="完成分析";
|
||||
DialogController.Instance.StartDialogNode("结论");
|
||||
Debug.Log("All steps completed. Puzzle is solved!");
|
||||
DialogController.Instance.SetVariable("$previousMatchCode", previousClue.MatchCode);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
conclue.text="症状分析错误";
|
||||
Debug.Log("Incorrect Clue. Please try again.");
|
||||
}
|
||||
}
|
||||
|
||||
// 根据步骤判定当前 Clue 是否符合条件
|
||||
private bool IsValidClueForStep(int step, Clue clue)
|
||||
{
|
||||
switch (step)
|
||||
{
|
||||
case 0:
|
||||
return clue.Category == "UFView"; // 第一关要求Clue的Category为"UF"
|
||||
case 1:
|
||||
Clue previousClue = clueSlots[step - 1].GetComponentInChildren<ClueItem>()?.GetClueData();
|
||||
return clue.Category == "MemoryView" && clue.MatchCode == previousClue?.MatchCode; // 第二关要求Category为"Memory"且匹配MatchCode
|
||||
// 可以根据需要继续添加更多步骤和判定规则
|
||||
case 2:
|
||||
Clue previousClue2 = clueSlots[step - 1].GetComponentInChildren<ClueItem>()?.GetClueData();
|
||||
return clue.Category == "EyeView" && clue.MatchCode == previousClue2?.MatchCode; // 第二关要求Category为"EyeView"且匹配MatchCode
|
||||
// 可以根据需要继续添加更多步骤和判定规则
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// // 检查是否包含下一步
|
||||
private bool HasNextStep()
|
||||
{
|
||||
return currentStep < 3;
|
||||
// Start the Yarn dialog node
|
||||
DialogController.Instance.StartDialogNode("ClueBoard");
|
||||
}
|
||||
}
|
||||
|
||||
// 根据步骤判定当前 Clue 是否符合条件
|
||||
// private bool IsValidClueForStep(int step, Clue clue)
|
||||
// {
|
||||
// switch (step)
|
||||
// {
|
||||
// case 0:
|
||||
// return clue.Category == "UFView"; // 第一关要求Clue的Category为"UF"
|
||||
// case 1:
|
||||
// Clue previousClue = clueSlots[step - 1].GetComponentInChildren<ClueItem>()?.GetClueData();
|
||||
// return clue.Category == "MemoryView" && clue.MatchCode == previousClue?.MatchCode; // 第二关要求Category为"Memory"且匹配MatchCode
|
||||
// // 可以根据需要继续添加更多步骤和判定规则
|
||||
// case 2:
|
||||
// Clue previousClue2 = clueSlots[step - 1].GetComponentInChildren<ClueItem>()?.GetClueData();
|
||||
// return clue.Category == "EyeView" && clue.MatchCode == previousClue2?.MatchCode; // 第二关要求Category为"EyeView"且匹配MatchCode
|
||||
// // 可以根据需要继续添加更多步骤和判定规则
|
||||
// default:
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// // 检查是否包含下一步
|
||||
// private bool HasNextStep()
|
||||
// {
|
||||
// return currentStep < 3;
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using AibisDream;
|
||||
using Unity.VisualScripting;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
@@ -17,10 +18,11 @@ public class ClueManager : MonoBehaviour
|
||||
}
|
||||
void Update()
|
||||
{
|
||||
// if(Input.GetKeyDown(KeyCode.U))
|
||||
// {
|
||||
// GenerateUFClue("错误绘制","UFView","can_grass_error","绿色");
|
||||
// }
|
||||
if(Input.GetKeyDown(KeyCode.U))
|
||||
{
|
||||
DialogController.Instance.StartDialogNode("AddAllClueToFavorites");
|
||||
//GenerateUFClue("错误绘制","UFView","can_grass_error","绿色");
|
||||
}
|
||||
// if(Input.GetKeyDown(KeyCode.M))
|
||||
// {
|
||||
// GenerateMemoryClue("草地","MemoryView","liuying1-2","绿色");
|
||||
@@ -62,28 +64,44 @@ public class ClueManager : MonoBehaviour
|
||||
}
|
||||
//用于生成打孔带的函数
|
||||
[YarnCommand("generate_PunchTape")]
|
||||
public void GeneratePunchTape(string clueName, string category, string memoryIndex,string mathCode=null)
|
||||
public void GeneratePunchTape(string clueName, string category, string memoryIndex,string mathCode=null,bool directlyAddToFavorites=false)
|
||||
{
|
||||
PunchTape punchTape = new PunchTape(category, clueName, memoryIndex,mathCode);
|
||||
|
||||
if(directlyAddToFavorites)
|
||||
{
|
||||
FavoritesManager.Instance.AddClue(punchTape);
|
||||
return;
|
||||
}
|
||||
GameObject clueGO = Instantiate(punchTapecluePrefab, canvas.transform);
|
||||
|
||||
ClueItem clueItem = clueGO.GetComponent<ClueItem>();
|
||||
clueItem.Setup(punchTape);
|
||||
}
|
||||
[YarnCommand("generate_UFClue")]
|
||||
public void GenerateUFClue(string clueName, string imageName,string mathCode)
|
||||
public void GenerateUFClue(string clueName, string imageName,string mathCode,bool directlyAddToFavorites=false)
|
||||
{
|
||||
Sprite UFSprite = Resources.Load<Sprite>("Art/Photos/" + imageName);
|
||||
ImageClue imageClue=new ImageClue("UFView", clueName, UFSprite,mathCode);
|
||||
if(directlyAddToFavorites)
|
||||
{
|
||||
FavoritesManager.Instance.AddClue(imageClue);
|
||||
return;
|
||||
}
|
||||
GameObject clueGO = Instantiate(imageCluePrefab, canvas.transform);
|
||||
ClueItem clueItem = clueGO.GetComponent<ClueItem>();
|
||||
clueItem.Setup(imageClue);
|
||||
}
|
||||
[YarnCommand("generate_MemoryClue")]
|
||||
public void GenerateMemoryClue(string clueName, string imageName,string mathCode)
|
||||
public void GenerateMemoryClue(string clueName, string imageName,string mathCode,bool directlyAddToFavorites=false)
|
||||
{
|
||||
Sprite UFSprite = Resources.Load<Sprite>("Art/Memory/" + imageName);
|
||||
ImageClue imageClue=new ImageClue("MemoryView", clueName, UFSprite,mathCode);
|
||||
if(directlyAddToFavorites)
|
||||
{
|
||||
FavoritesManager.Instance.AddClue(imageClue);
|
||||
return;
|
||||
}
|
||||
GameObject clueGO = Instantiate(imageCluePrefab, canvas.transform);
|
||||
ClueItem clueItem = clueGO.GetComponent<ClueItem>();
|
||||
clueItem.Setup(imageClue);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.EventSystems;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class ClueSlotBase : MonoBehaviour, IDropHandler
|
||||
{
|
||||
@@ -16,9 +18,18 @@ public class ClueSlotBase : MonoBehaviour, IDropHandler
|
||||
[HideInInspector]
|
||||
public bool isLocked = false; // 插槽是否已占用
|
||||
|
||||
private Image slotFrame;
|
||||
|
||||
protected virtual void Start()
|
||||
{
|
||||
currentClueItem = null;
|
||||
slotFrame=transform.GetChild(0).GetComponent<Image>();
|
||||
slotFrame.color=Color.white;
|
||||
}
|
||||
public void SetSlotCorrect()
|
||||
{
|
||||
slotFrame.color=Color.green;
|
||||
SetSlotLockState(true);
|
||||
}
|
||||
|
||||
public void OnDrop(PointerEventData eventData)
|
||||
@@ -94,8 +105,6 @@ public class ClueSlotBase : MonoBehaviour, IDropHandler
|
||||
if (clueItem != null)
|
||||
{
|
||||
ClueInteraction clueInteraction = clueItem.GetComponent<ClueInteraction>();
|
||||
RectTransform transform=clueInteraction.GetComponent<RectTransform>();
|
||||
transform=OriginalTransform;
|
||||
clueInteraction?.ReturnToOriginalPosition(); // 返回到原位的逻辑
|
||||
// 你也可以在这里添加额外的逻辑来处理集合的更新
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user