diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFile.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFile.cs
index ea95067c..30882e71 100644
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFile.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFile.cs
@@ -1,6 +1,7 @@
 using AxibugEmuOnline.Client.ClientCore;
 using AxibugEmuOnline.Client.Tools;
 using AxibugProtobuf;
+using MAME.Core;
 using System;
 using System.IO;
 using System.Runtime.InteropServices;
@@ -8,7 +9,7 @@ using System.Runtime.InteropServices;
 namespace AxibugEmuOnline.Client
 {
     /// <summary> 存档文件抽象类 </summary>
-    public class SaveFile
+    public partial class SaveFile
     {
         public SavCloudApi CloudAPI => App.SavMgr.CloudApi;
 
@@ -38,7 +39,24 @@ namespace AxibugEmuOnline.Client
             }
         }
 
+        public bool IsBusy
+        {
+            get
+            {
+                if (FSM.CurrentState is DownloadingState) return true;
+                else if (FSM.CurrentState is UploadingState) return true;
+
+                return false;
+            }
+        }
+
+        public SimpleFSM<SaveFile>.State GetState()
+        {
+            return FSM.CurrentState;
+        }
+
         public event Action OnSavSuccessed;
+        public event Action OnStateChanged;
 
         /// <summary> 存档顺序号,用于判断云存档和本地存档的同步状态,是否存在冲突 </summary>
         public uint Sequecen { get; private set; }
@@ -55,11 +73,12 @@ namespace AxibugEmuOnline.Client
             EmuPlatform = platform;
             SlotIndex = slotIndex;
             FSM = new SimpleFSM<SaveFile>(this);
-            FSM.AddState<UnkownState>();
+            FSM.AddState<IdleState>();
             FSM.AddState<CheckingState>();
             FSM.AddState<DownloadingState>();
             FSM.AddState<UploadingState>();
             FSM.AddState<SyncedState>();
+            FSM.OnStateChanged += FSM_OnStateChanged;
 
             IsEmpty = !File.Exists(FilePath);
 
@@ -82,7 +101,12 @@ namespace AxibugEmuOnline.Client
                 streaming.Dispose();
             }
 
-            FSM.ChangeState<UnkownState>();
+            FSM.ChangeState<IdleState>();
+        }
+
+        private void FSM_OnStateChanged()
+        {
+            OnStateChanged?.Invoke();
         }
 
         public void Update()
@@ -145,6 +169,8 @@ namespace AxibugEmuOnline.Client
 
         public unsafe void Save(uint sequence, byte[] savData, byte[] screenShotData)
         {
+            if (IsBusy) return;
+
             var filePath = FilePath;
 
             var header = new Header
@@ -190,9 +216,9 @@ namespace AxibugEmuOnline.Client
         /// </summary>
         public void TrySync()
         {
-            if (FSM.CurrentState is not UnkownState && FSM.CurrentState is not SyncedState) return;
+            if (FSM.CurrentState is not IdleState && FSM.CurrentState is not SyncedState) return;
 
-            FSM.ChangeState<CheckingState>();
+            FSM.ChangeState<CheckingNetworkState>();
         }
 
 
@@ -210,14 +236,5 @@ namespace AxibugEmuOnline.Client
             [FieldOffset(20)]
             public uint ScreenShotLength;
         }
-
-        public enum EnumState
-        {
-            Unkown,
-            Checking,
-            Downloading,
-            Uploading,
-            Synced
-        }
     }
 }
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingNetworkState.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingNetworkState.cs
new file mode 100644
index 00000000..70f95926
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingNetworkState.cs
@@ -0,0 +1,21 @@
+using AxibugEmuOnline.Client.ClientCore;
+using AxibugEmuOnline.Client.Tools;
+using System;
+
+namespace AxibugEmuOnline.Client
+{
+    public partial class SaveFile
+    {
+
+        public class CheckingNetworkState : SimpleFSM<SaveFile>.State
+        {
+            public override void OnUpdate()
+            {
+                if (App.network.isConnected)
+                {
+                    FSM.ChangeState<CheckingState>();
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingNetworkState.cs.meta b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingNetworkState.cs.meta
new file mode 100644
index 00000000..91f6544a
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingNetworkState.cs.meta
@@ -0,0 +1,2 @@
+fileFormatVersion: 2
+guid: 288e73ce3cb773e46b7d37a53a3b43ee
\ No newline at end of file
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 2dbf54a7..5ae92843 100644
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingState.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/CheckingState.cs
@@ -4,45 +4,48 @@ using UnityEngine;
 
 namespace AxibugEmuOnline.Client
 {
-    public class CheckingState : SimpleFSM<SaveFile>.State
+    public partial class SaveFile
     {
-        private float m_timeOut;
-
-        public Protobuf_Mine_GameSavInfo NetData { get; private set; }
-
-        public override void OnEnter(SimpleFSM<SaveFile>.State preState)
+        public class CheckingState : SimpleFSM<SaveFile>.State
         {
-            m_timeOut = 5f;
-            Host.CloudAPI.OnFetchGameSavList += CloudAPI_OnFetchGameSavList;
-            Host.CloudAPI.SendGetGameSavList(Host.RomID);
-        }
+            private float m_timeOut;
 
-        public override void OnExit(SimpleFSM<SaveFile>.State nextState)
-        {
-            Host.CloudAPI.OnFetchGameSavList -= CloudAPI_OnFetchGameSavList;
-        }
+            public Protobuf_Mine_GameSavInfo NetData { get; private set; }
 
-        public override void OnUpdate()
-        {
-            m_timeOut -= Time.deltaTime;
-            if (m_timeOut < 0) //已超时
+            public override void OnEnter(SimpleFSM<SaveFile>.State preState)
             {
-                FSM.ChangeState<UnkownState>();
+                m_timeOut = 5f;
+                Host.CloudAPI.OnFetchGameSavList += CloudAPI_OnFetchGameSavList;
+                Host.CloudAPI.SendGetGameSavList(Host.RomID);
             }
-        }
 
-        private void CloudAPI_OnFetchGameSavList(int romID, Protobuf_Mine_GameSavInfo[] savSlotData)
-        {
-            if (romID != Host.RomID) return;
-            NetData = savSlotData[Host.SlotIndex];
-
-            if (NetData == null) //云存档不存在,上传本地存档
+            public override void OnExit(SimpleFSM<SaveFile>.State nextState)
             {
-                FSM.ChangeState<UploadingState>();
+                Host.CloudAPI.OnFetchGameSavList -= CloudAPI_OnFetchGameSavList;
             }
-            else
+
+            public override void OnUpdate()
             {
-                FSM.ChangeState<DownloadingState>();
+                m_timeOut -= Time.deltaTime;
+                if (m_timeOut < 0) //已超时
+                {
+                    FSM.ChangeState<IdleState>();
+                }
+            }
+
+            private void CloudAPI_OnFetchGameSavList(int romID, Protobuf_Mine_GameSavInfo[] savSlotData)
+            {
+                if (romID != Host.RomID) return;
+                NetData = savSlotData[Host.SlotIndex];
+
+                if (NetData == null) //云存档不存在,上传本地存档
+                {
+                    FSM.ChangeState<UploadingState>();
+                }
+                else
+                {
+                    FSM.ChangeState<DownloadingState>();
+                }
             }
         }
     }
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 5bd1b593..e35f1ee7 100644
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/ConflictState.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/ConflictState.cs
@@ -2,8 +2,11 @@
 
 namespace AxibugEmuOnline.Client
 {
-    public class ConflictState : SimpleFSM<SaveFile>.State
+    public partial class SaveFile
     {
+        public class ConflictState : SimpleFSM<SaveFile>.State
+        {
 
+        }
     }
 }
\ 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 e0e9e2df..7884f129 100644
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/DownloadingState.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/DownloadingState.cs
@@ -3,51 +3,54 @@ using AxibugEmuOnline.Client.Tools;
 
 namespace AxibugEmuOnline.Client
 {
-    public class DownloadingState : SimpleFSM<SaveFile>.State
+    public partial class SaveFile
     {
-        uint m_sequece;
-        private AxiHttpProxy.SendDownLoadProxy m_downloadTask;
-        private AxiHttpProxy.SendDownLoadProxy m_downloadTaskImg;
-
-        public override void OnEnter(SimpleFSM<SaveFile>.State preState)
+        public class DownloadingState : SimpleFSM<SaveFile>.State
         {
-            var checkState = preState as CheckingState;
+            uint m_sequece;
+            private AxiHttpProxy.SendDownLoadProxy m_downloadTask;
+            private AxiHttpProxy.SendDownLoadProxy m_downloadTaskImg;
 
-            var netData = checkState.NetData;
-
-            if (Host.Sequecen >= (uint)netData.Sequence)
+            public override void OnEnter(SimpleFSM<SaveFile>.State preState)
             {
-                FSM.ChangeState<ConflictState>();
-                return;
+                var checkState = preState as CheckingState;
+
+                var netData = checkState.NetData;
+
+                if (Host.Sequecen >= (uint)netData.Sequence)
+                {
+                    FSM.ChangeState<ConflictState>();
+                    return;
+                }
+
+                m_sequece = (uint)netData.Sequence;
+                m_downloadTask = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{netData.SavUrl}");
+                m_downloadTaskImg = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{netData.SavImgUrl}");
             }
 
-            m_sequece = (uint)netData.Sequence;
-            m_downloadTask = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{netData.SavUrl}");
-            m_downloadTaskImg = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{netData.SavImgUrl}");
-        }
-
-        public override void OnUpdate()
-        {
-            if (!m_downloadTask.downloadHandler.isDone) return;
-
-            if (m_downloadTask.downloadHandler.bHadErr) //下载失败
+            public override void OnUpdate()
             {
-                FSM.ChangeState<UnkownState>();
-                return;
+                if (!m_downloadTask.downloadHandler.isDone) return;
+
+                if (m_downloadTask.downloadHandler.bHadErr) //下载失败
+                {
+                    FSM.ChangeState<IdleState>();
+                    return;
+                }
+
+                if (!m_downloadTaskImg.downloadHandler.isDone) return;
+
+                if (m_downloadTaskImg.downloadHandler.bHadErr) //下载失败
+                {
+                    FSM.ChangeState<IdleState>();
+                    return;
+                }
+
+                var savData = Host.CloudAPI.UnGzipData(m_downloadTask.downloadHandler.data);
+                var imgData = Host.CloudAPI.UnGzipData(m_downloadTaskImg.downloadHandler.data);
+                Host.Save(m_sequece, savData, imgData);
+                FSM.ChangeState<SyncedState>();
             }
-
-            if (!m_downloadTaskImg.downloadHandler.isDone) return;
-
-            if (m_downloadTaskImg.downloadHandler.bHadErr) //下载失败
-            {
-                FSM.ChangeState<UnkownState>();
-                return;
-            }
-
-            var savData = Host.CloudAPI.UnGzipData(m_downloadTask.downloadHandler.data);
-            var imgData = Host.CloudAPI.UnGzipData(m_downloadTaskImg.downloadHandler.data);
-            Host.Save(m_sequece, savData, imgData);
-            FSM.ChangeState<SyncedState>();
         }
     }
 }
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/IdleState.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/IdleState.cs
new file mode 100644
index 00000000..68e014f7
--- /dev/null
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/IdleState.cs
@@ -0,0 +1,11 @@
+using AxibugEmuOnline.Client.Tools;
+
+namespace AxibugEmuOnline.Client
+{
+    public partial class SaveFile
+    {
+        public class IdleState : SimpleFSM<SaveFile>.State
+        {
+        }
+    }
+}
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/UnkownState.cs.meta b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/IdleState.cs.meta
similarity index 100%
rename from AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/UnkownState.cs.meta
rename to AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/IdleState.cs.meta
diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/SyncedState.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/SyncedState.cs
index 00c031e9..46bb251f 100644
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/SyncedState.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/SyncedState.cs
@@ -2,7 +2,10 @@
 
 namespace AxibugEmuOnline.Client
 {
-    public class SyncedState : SimpleFSM<SaveFile>.State
+    public partial class SaveFile
     {
+        public class SyncedState : SimpleFSM<SaveFile>.State
+        {
+        }
     }
 }
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/UnkownState.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/UnkownState.cs
deleted file mode 100644
index 81061ba4..00000000
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/UnkownState.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using AxibugEmuOnline.Client.Tools;
-
-namespace AxibugEmuOnline.Client
-{
-    public class UnkownState : SimpleFSM<SaveFile>.State
-    {
-    }
-}
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/UploadingState.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/UploadingState.cs
index da9f426b..8276411f 100644
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/UploadingState.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SaveFileSyncStates/UploadingState.cs
@@ -2,27 +2,30 @@
 
 namespace AxibugEmuOnline.Client
 {
-    public class UploadingState : SimpleFSM<SaveFile>.State
+    public partial class SaveFile
     {
-        public override void OnEnter(SimpleFSM<SaveFile>.State preState)
+        public class UploadingState : SimpleFSM<SaveFile>.State
         {
-            Host.CloudAPI.OnUploadedSavData += Api_OnUploadedSavData;
+            public override void OnEnter(SimpleFSM<SaveFile>.State preState)
+            {
+                Host.CloudAPI.OnUploadedSavData += Api_OnUploadedSavData;
 
-            Host.GetSavData(out byte[] savData, out byte[] screenData);
-            Host.CloudAPI.SendUpLoadGameSav(Host.RomID, Host.SlotIndex, Host.Sequecen, savData, screenData);
-        }
+                Host.GetSavData(out byte[] savData, out byte[] screenData);
+                Host.CloudAPI.SendUpLoadGameSav(Host.RomID, Host.SlotIndex, Host.Sequecen, savData, screenData);
+            }
 
-        public override void OnExit(SimpleFSM<SaveFile>.State nextState)
-        {
-            Host.CloudAPI.OnUploadedSavData -= Api_OnUploadedSavData;
-        }
+            public override void OnExit(SimpleFSM<SaveFile>.State nextState)
+            {
+                Host.CloudAPI.OnUploadedSavData -= Api_OnUploadedSavData;
+            }
 
-        private void Api_OnUploadedSavData(int romID, int slotIndex, AxibugProtobuf.Protobuf_Mine_GameSavInfo savInfo)
-        {
-            if (Host.RomID != romID) return;
-            if (Host.SlotIndex != slotIndex) return;
+            private void Api_OnUploadedSavData(int romID, int slotIndex, AxibugProtobuf.Protobuf_Mine_GameSavInfo savInfo)
+            {
+                if (Host.RomID != romID) return;
+                if (Host.SlotIndex != slotIndex) return;
 
-            FSM.ChangeState<SyncedState>();
+                FSM.ChangeState<SyncedState>();
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SimpleSFM.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SimpleSFM.cs
index 4ad5a06f..814207ee 100644
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SimpleSFM.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/SaveSlotManager/SimpleSFM.cs
@@ -4,10 +4,10 @@ using System.Linq;
 
 namespace AxibugEmuOnline.Client.Tools
 {
-    public class SimpleFSM<HOST>
+    public partial class SimpleFSM<HOST>
     {
+        public event Action OnStateChanged;
         private Dictionary<Type, State> m_states = new Dictionary<Type, State>();
-        private State m_current;
 
         public HOST Host { get; private set; }
 
@@ -16,7 +16,18 @@ namespace AxibugEmuOnline.Client.Tools
             Host = host;
         }
 
-        public State CurrentState => m_current;
+        private State m_current;
+        public State CurrentState
+        {
+            get => m_current;
+            set
+            {
+                if (m_current == value) return;
+
+                m_current = value;
+                OnStateChanged?.Invoke();
+            }
+        }
         public T AddState<T>() where T : State, new()
         {
             var stateType = typeof(T);
diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI_SaveStateMenu.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI_SaveStateMenu.cs
index 994d5f64..1da77c5f 100644
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI_SaveStateMenu.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/InGameUI/InGameUI_SaveStateMenu.cs
@@ -46,6 +46,13 @@ namespace AxibugEmuOnline.Client
                 m_subOptions.Add(new LoadMenuItem(inGameui, savFile));
             }
 
+            public override void OnShow(OptionUI_MenuItem ui)
+            {
+                base.OnShow(ui);
+
+                SavFile.TrySync();
+            }
+
             protected override List<InternalOptionMenu> GetOptionMenus()
             {
                 return m_subOptions;
@@ -65,6 +72,13 @@ namespace AxibugEmuOnline.Client
 
                 public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
                 {
+                    if (m_savFile.IsBusy)
+                    {
+                        OverlayManager.PopTip("存档正在同步中");
+                        cancelHide = true;
+                        return;
+                    }
+
                     var stateData = m_ingameUI.Core.GetStateBytes();
                     var tex = m_ingameUI.Core.OutputPixel;
                     var screenData = tex.ToJPG(m_ingameUI.Core.DrawCanvas.transform.localScale);
diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI.cs
index b52e8316..029ae216 100644
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI.cs
@@ -439,7 +439,6 @@ namespace AxibugEmuOnline.Client
         public abstract string Name { get; }
         public virtual Sprite Icon { get; }
         public virtual bool Visible => true;
-        public virtual bool Enable => true;
 
         public virtual void OnFocus() { }
         public virtual void OnShow(OptionUI_MenuItem ui) { }
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 d0fc9d20..5286eadc 100644
--- a/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI_SavSlotItem.cs
+++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/UI/OptionUI/OptionUI_SavSlotItem.cs
@@ -1,4 +1,7 @@
-using UnityEngine;
+using AxibugEmuOnline.Client.Tools;
+using System;
+using System.Collections.Generic;
+using UnityEngine;
 using UnityEngine.UI;
 using static AxibugEmuOnline.Client.InGameUI_SaveStateMenu;
 
@@ -10,15 +13,38 @@ namespace AxibugEmuOnline.Client
         public Image UI_Empty;
         public Text UI_SavTime;
 
+        public GameObject UI_Disconnect;
+        public GameObject UI_Syncing;
+        public GameObject UI_Conflict;
+        public GameObject UI_Synced;
+
         Texture2D m_screenTex;
 
+        Dictionary<Type, GameObject> m_stateNodes = new Dictionary<Type, GameObject>();
+
+        private void Awake()
+        {
+            m_stateNodes[typeof(SaveFile.CheckingState)] = UI_Syncing;
+            m_stateNodes[typeof(SaveFile.ConflictState)] = UI_Conflict;
+            m_stateNodes[typeof(SaveFile.DownloadingState)] = UI_Syncing;
+            m_stateNodes[typeof(SaveFile.SyncedState)] = UI_Synced;
+            m_stateNodes[typeof(SaveFile.UploadingState)] = UI_Syncing;
+            m_stateNodes[typeof(SaveFile.CheckingNetworkState)] = UI_Disconnect;
+        }
+
         protected override void OnSetData(InternalOptionMenu menuData)
         {
             base.OnSetData(menuData);
 
             RefreshUI();
+            MenuData.SavFile.OnSavSuccessed += SavFile_OnSavSuccessed;
+            MenuData.SavFile.OnStateChanged += UpdateStateNode;
+        }
 
-            MenuData.SavFile.OnSavSuccessed += RefreshUI;
+        private void SavFile_OnSavSuccessed()
+        {
+            MenuData.SavFile.TrySync();
+            RefreshUI();
         }
 
         private void RefreshUI()
@@ -48,6 +74,21 @@ namespace AxibugEmuOnline.Client
                 m_screenTex.LoadImage(screenShotData);
                 UI_ScreenShot.texture = m_screenTex;
             }
+
+            UpdateStateNode();
+        }
+
+        private void UpdateStateNode()
+        {
+            var stateType = MenuData.SavFile.GetState().GetType();
+
+            foreach (var item in m_stateNodes)
+            {
+                var type = item.Key;
+                var nodeGo = item.Value;
+
+                nodeGo.SetActiveEx(type == stateType);
+            }
         }
 
         public override void OnHide()
@@ -60,7 +101,8 @@ namespace AxibugEmuOnline.Client
                 m_screenTex = null;
             }
 
-            MenuData.SavFile.OnSavSuccessed -= RefreshUI;
+            MenuData.SavFile.OnSavSuccessed -= SavFile_OnSavSuccessed;
+            MenuData.SavFile.OnStateChanged -= UpdateStateNode;
         }
 
         public override void OnExecute(OptionUI optionUI, ref bool cancelHide)