diff --git a/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/OptionUI.prefab b/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/OptionUI.prefab index fc677e08..e20dea9c 100644 --- a/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/OptionUI.prefab +++ b/AxibugEmuOnline.Client/Assets/Resources/UIPrefabs/OptionUI.prefab @@ -520,6 +520,81 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: gradient: {fileID: 46877084639177849} +--- !u!1 &804908692400837359 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 8642975113305060610} + - component: {fileID: 6956713201433508184} + - component: {fileID: 1041409322641615} + m_Layer: 5 + m_Name: download + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &8642975113305060610 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 804908692400837359} + 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: 905458728127029103} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 25, y: 25} + m_SizeDelta: {x: 50, y: 50} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &6956713201433508184 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 804908692400837359} + m_CullTransparentMesh: 1 +--- !u!114 &1041409322641615 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 804908692400837359} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 961aba7b7a39e4d4c832e94350f44d4c, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &1280900818828460255 GameObject: m_ObjectHideFlags: 0 @@ -706,7 +781,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} + m_Color: {r: 1, g: 0.80982494, b: 0, a: 1} m_RaycastTarget: 0 m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_Maskable: 1 @@ -973,9 +1048,12 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: - {fileID: 3539783812791358836} - - {fileID: 6030618878828304669} - {fileID: 2303902335643923373} - {fileID: 8677023902282266940} + - {fileID: 7976727918032113692} + - {fileID: 8642975113305060610} + - {fileID: 5521327881148589877} + - {fileID: 1660924397234324979} m_Father: {fileID: 5970282275929291192} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} @@ -1442,97 +1520,6 @@ MonoBehaviour: m_EffectColor: {r: 0, g: 0, b: 0, a: 0.5} m_EffectDistance: {x: 1.5, y: -1.5} m_UseGraphicAlpha: 1 ---- !u!1 &4078965612622303339 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 6030618878828304669} - - component: {fileID: 6018890508858230420} - - component: {fileID: 1865219663044263670} - - component: {fileID: 6562970432720184454} - m_Layer: 5 - m_Name: Syncing - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &6030618878828304669 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4078965612622303339} - 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: 905458728127029103} - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 25, y: 25} - m_SizeDelta: {x: 50, y: 50} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!222 &6018890508858230420 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4078965612622303339} - m_CullTransparentMesh: 1 ---- !u!114 &1865219663044263670 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4078965612622303339} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 0 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 21300000, guid: c5a9535bb63e1f14f9a1528566864ab2, type: 3} - m_Type: 0 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!114 &6562970432720184454 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 4078965612622303339} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 8707b921aaba60d45b4041e96f3542dd, type: 3} - m_Name: - m_EditorClassIdentifier: - m_duration: 2 - m_ease: 1 - m_reverseRotation: 1 --- !u!1 &4124172888520656882 GameObject: m_ObjectHideFlags: 0 @@ -3183,7 +3170,10 @@ MonoBehaviour: UI_Empty: {fileID: 8350228378118296958} UI_SavTime: {fileID: 13043593624240728} UI_Disconnect: {fileID: 6998836277133601669} - UI_Syncing: {fileID: 4078965612622303339} + UI_DownloadError: {fileID: 8857746597932873861} + UI_Downloading: {fileID: 804908692400837359} + UI_Uploading: {fileID: 8872483836623718893} + UI_Checking: {fileID: 7267609509608397888} UI_Conflict: {fileID: 1601163034082482360} UI_Synced: {fileID: 2637678715180681658} --- !u!1 &7141318786199574664 @@ -3286,6 +3276,81 @@ MonoBehaviour: m_EffectColor: {r: 0, g: 0, b: 0, a: 0.5} m_EffectDistance: {x: 1.5, y: -1.5} m_UseGraphicAlpha: 1 +--- !u!1 &7267609509608397888 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1660924397234324979} + - component: {fileID: 5687683890234766428} + - component: {fileID: 6995705272401882157} + m_Layer: 5 + m_Name: checking + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &1660924397234324979 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7267609509608397888} + 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: 905458728127029103} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 25, y: 25} + m_SizeDelta: {x: 50, y: 50} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &5687683890234766428 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7267609509608397888} + m_CullTransparentMesh: 1 +--- !u!114 &6995705272401882157 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7267609509608397888} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 3efbb404fd0fa2440b59f2759cb66521, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &7579340952198812870 GameObject: m_ObjectHideFlags: 0 @@ -3888,6 +3953,156 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 +--- !u!1 &8857746597932873861 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7976727918032113692} + - component: {fileID: 8830922541807882247} + - component: {fileID: 74709689621410332} + m_Layer: 5 + m_Name: syncerror + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &7976727918032113692 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8857746597932873861} + 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: 905458728127029103} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 25, y: 25} + m_SizeDelta: {x: 50, y: 50} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &8830922541807882247 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8857746597932873861} + m_CullTransparentMesh: 1 +--- !u!114 &74709689621410332 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8857746597932873861} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 0, b: 0, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: 5ab158116cd13094f8aeec03e9c776bd, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 +--- !u!1 &8872483836623718893 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 5521327881148589877} + - component: {fileID: 1453351515137974665} + - component: {fileID: 625482330037984562} + m_Layer: 5 + m_Name: upload + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!224 &5521327881148589877 +RectTransform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8872483836623718893} + 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: 905458728127029103} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} + m_AnchorMin: {x: 0, y: 0} + m_AnchorMax: {x: 0, y: 0} + m_AnchoredPosition: {x: 25, y: 25} + m_SizeDelta: {x: 50, y: 50} + m_Pivot: {x: 0.5, y: 0.5} +--- !u!222 &1453351515137974665 +CanvasRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8872483836623718893} + m_CullTransparentMesh: 1 +--- !u!114 &625482330037984562 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 8872483836623718893} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} + m_Name: + m_EditorClassIdentifier: + m_Material: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_RaycastTarget: 0 + m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} + m_Maskable: 1 + m_OnCullStateChanged: + m_PersistentCalls: + m_Calls: [] + m_Sprite: {fileID: 21300000, guid: fe23eed4ad510ca42885889dbb8aaf06, type: 3} + m_Type: 0 + m_PreserveAspect: 0 + m_FillCenter: 1 + m_FillMethod: 4 + m_FillAmount: 1 + m_FillClockwise: 1 + m_FillOrigin: 0 + m_UseSpriteMesh: 0 + m_PixelsPerUnitMultiplier: 1 --- !u!1 &8884391103430529053 GameObject: m_ObjectHideFlags: 0 diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFile.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFile.cs index 75733541..91568212 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFile.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFile.cs @@ -52,7 +52,7 @@ namespace AxibugEmuOnline.Client } } - public SimpleFSM.State GetState() + public SimpleFSM.State GetCurrentState() { return FSM.CurrentState; } @@ -79,8 +79,10 @@ namespace AxibugEmuOnline.Client FSM.AddState();//? FSM.AddState(); FSM.AddState(); + FSM.AddState(); FSM.AddState(); FSM.AddState(); + FSM.AddState(); FSM.OnStateChanged += FSM_OnStateChanged; IsEmpty = !AxiIO.File.Exists(FilePath); @@ -234,6 +236,11 @@ namespace AxibugEmuOnline.Client SyncingFilesUtility.Remove(this); } + public override string ToString() + { + return $"{EmuPlatform}|{RomID}|{SlotIndex}"; + } + public static class SyncingFilesUtility { static SyncingFileRecord m_syncFiles = new SyncingFileRecord(); @@ -315,7 +322,6 @@ namespace AxibugEmuOnline.Client var jsonStr = JsonUtility.ToJson(temp); AxiPlayerPrefs.SetString("SYNCING_SAVE", jsonStr); } - } [Serializable] diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingState.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingState.cs index 20c8a71f..21e17f70 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingState.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingState.cs @@ -29,7 +29,8 @@ namespace AxibugEmuOnline.Client m_timeOut -= Time.deltaTime; if (m_timeOut < 0) //已超时 { - FSM.ChangeState(); + FSM.GetState().Error = "拉取云存档数据超时"; + FSM.ChangeState(); } } @@ -44,7 +45,15 @@ namespace AxibugEmuOnline.Client } else { - FSM.ChangeState(); + if (Host.Sequecen > (uint)NetData.Sequence)//本地序列号大于云存档序列号,视为冲突 + { + FSM.GetState().NetData = NetData; + FSM.ChangeState(); + } + else + { + FSM.ChangeState(); + } } } } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/ConflictState.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/ConflictState.cs index e35f1ee7..85ce15d8 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/ConflictState.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/ConflictState.cs @@ -1,4 +1,5 @@ using AxibugEmuOnline.Client.Tools; +using AxibugProtobuf; namespace AxibugEmuOnline.Client { @@ -6,7 +7,7 @@ namespace AxibugEmuOnline.Client { public class ConflictState : SimpleFSM.State { - + public Protobuf_Mine_GameSavInfo NetData { get; set; } } } } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/DownloadingState.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/DownloadingState.cs index 3d8a5cdf..951d4c9d 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/DownloadingState.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/DownloadingState.cs @@ -1,5 +1,6 @@ using AxibugEmuOnline.Client.ClientCore; using AxibugEmuOnline.Client.Tools; +using AxibugProtobuf; using System; namespace AxibugEmuOnline.Client @@ -14,14 +15,14 @@ namespace AxibugEmuOnline.Client public override void OnEnter(SimpleFSM.State preState) { - var checkState = preState as CheckingState; - - var netData = checkState.NetData; - - if (Host.Sequecen >= (uint)netData.Sequence) + Protobuf_Mine_GameSavInfo netData = null; + if (preState is CheckingState checkState) { - FSM.ChangeState(); - return; + netData = checkState.NetData; + } + else if (preState is ConflictState conflictState) //由冲突状态转换为下载状态,代表使用网络存档覆盖本地 + { + netData = conflictState.NetData; } m_sequece = (uint)netData.Sequence; @@ -42,7 +43,8 @@ namespace AxibugEmuOnline.Client if (m_downloadTask.downloadHandler.bHadErr) //下载失败 { - FSM.ChangeState(); + FSM.GetState().Error = m_downloadTask.downloadHandler.ErrInfo; + FSM.ChangeState(); return; } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SimpleSFM.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SimpleSFM.cs index e077e8c5..b59fa540 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SimpleSFM.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SimpleSFM.cs @@ -7,7 +7,10 @@ namespace AxibugEmuOnline.Client.Tools public partial class SimpleFSM { public event Action OnStateChanged; + private Dictionary m_states = new Dictionary(); + private bool isInTransition = false; // 新增:标识是否处于切换过程中 + private Queue pendingStateQueue = new Queue(); // 新增:延迟请求的队列 public HOST Host { get; private set; } @@ -16,15 +19,15 @@ namespace AxibugEmuOnline.Client.Tools Host = host; } - private State m_current; + private State m_currentState; public State CurrentState { - get => m_current; + get => m_currentState; set { - if (m_current == value) return; + if (m_currentState == value) return; - m_current = value; + m_currentState = value; OnStateChanged?.Invoke(); } } @@ -40,47 +43,59 @@ namespace AxibugEmuOnline.Client.Tools return (T)state; } - public void BackToLast() - { - if (m_current == null) return; - if (m_current.LastState == null) return; - - if (m_states.Values.FirstOrDefault(s => s == m_current.LastState) is State lastState) - { - m_current.LastState = null; - m_current.OnExit(lastState); - - lastState.OnEnter(m_current); - m_current = lastState; - } - } - - public void Stop() - { - if (m_current != null) - { - m_current.OnExit(null); - m_current = null; - } - - foreach (var state in m_states.Values) - state.LastState = null; - } - + public void ChangeState() where T : State, new() { var stateType = typeof(T); - m_states.TryGetValue(stateType, out State nextState); + if (!m_states.ContainsKey(stateType)) + return; + // 如果处于切换中,加入队列等待后续处理 + if (isInTransition) + { + pendingStateQueue.Enqueue(stateType); + return; + } + + // 标记开始切换 + isInTransition = true; + InternalChangeState(stateType); + isInTransition = false; // 切换结束 + + // 处理队列中积累的切换请求 + ProcessPendingQueue(); + } + + // 新增:实际执行状态切换的方法 + private void InternalChangeState(Type stateType) + { + State nextState = m_states[stateType]; if (nextState == null) return; - if (m_current != null) m_current.OnExit(nextState); + State preState = CurrentState; + // 退出当前状态 + if (preState != null) preState.OnExit(nextState); - var preState = m_current; - m_current = nextState; + // 更新当前状态 + CurrentState = nextState; + CurrentState.LastState = preState; - m_current.LastState = preState; - m_current.OnEnter(preState); + // 进入新状态 + CurrentState.OnEnter(preState); + } + + // 新增:处理队列中的切换请求 + private void ProcessPendingQueue() + { + while (pendingStateQueue.Count > 0) + { + Type nextType = pendingStateQueue.Dequeue(); + if (!m_states.ContainsKey(nextType)) continue; + + isInTransition = true; + InternalChangeState(nextType); + isInTransition = false; + } } public T GetState() where T : State, new() @@ -91,11 +106,11 @@ namespace AxibugEmuOnline.Client.Tools public void Update() { - m_current?.OnUpdate(); + CurrentState?.OnUpdate(); foreach (var state in m_states.Values) { - if (state == m_current) continue; - state.AnyStateUpdate(m_current); + if (state == CurrentState) continue; + state.AnyStateUpdate(CurrentState); } } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI_SavSlotItem.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI_SavSlotItem.cs index 5286eadc..6648e0d6 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI_SavSlotItem.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI_SavSlotItem.cs @@ -14,7 +14,10 @@ namespace AxibugEmuOnline.Client public Text UI_SavTime; public GameObject UI_Disconnect; - public GameObject UI_Syncing; + public GameObject UI_DownloadError; + public GameObject UI_Downloading; + public GameObject UI_Uploading; + public GameObject UI_Checking; public GameObject UI_Conflict; public GameObject UI_Synced; @@ -24,12 +27,13 @@ namespace AxibugEmuOnline.Client private void Awake() { - m_stateNodes[typeof(SaveFile.CheckingState)] = UI_Syncing; + m_stateNodes[typeof(SaveFile.CheckingState)] = UI_Checking; m_stateNodes[typeof(SaveFile.ConflictState)] = UI_Conflict; - m_stateNodes[typeof(SaveFile.DownloadingState)] = UI_Syncing; + m_stateNodes[typeof(SaveFile.DownloadingState)] = UI_Downloading; m_stateNodes[typeof(SaveFile.SyncedState)] = UI_Synced; - m_stateNodes[typeof(SaveFile.UploadingState)] = UI_Syncing; + m_stateNodes[typeof(SaveFile.UploadingState)] = UI_Uploading; m_stateNodes[typeof(SaveFile.CheckingNetworkState)] = UI_Disconnect; + m_stateNodes[typeof(SaveFile.SyncFailedState)] = UI_DownloadError; } protected override void OnSetData(InternalOptionMenu menuData) @@ -80,7 +84,7 @@ namespace AxibugEmuOnline.Client private void UpdateStateNode() { - var stateType = MenuData.SavFile.GetState().GetType(); + var stateType = MenuData.SavFile.GetCurrentState().GetType(); foreach (var item in m_stateNodes) {