diff --git a/VPet-Simulator.Core/Display/Main.xaml.cs b/VPet-Simulator.Core/Display/Main.xaml.cs
index c22bb57..46e911a 100644
--- a/VPet-Simulator.Core/Display/Main.xaml.cs
+++ b/VPet-Simulator.Core/Display/Main.xaml.cs
@@ -68,6 +68,8 @@ namespace VPet_Simulator.Core
             UIGrid.Children.Add(MsgBar.This);
             labeldisplaytimer.Elapsed += Labledisplaytimer_Elapsed;
 
+            DisplayNomal = DisplayDefault;
+
             if (loadtouchevent)
             {
                 LoadTouchEvent();
diff --git a/VPet-Simulator.Core/Display/MainDisplay.cs b/VPet-Simulator.Core/Display/MainDisplay.cs
index 67f2a86..cbdb6c6 100644
--- a/VPet-Simulator.Core/Display/MainDisplay.cs
+++ b/VPet-Simulator.Core/Display/MainDisplay.cs
@@ -46,9 +46,13 @@ namespace VPet_Simulator.Core
             }
         }
         /// <summary>
-        /// 显示默认情况
+        /// 显示默认情况, 默认为默认动画
         /// </summary>
-        public void DisplayNomal()
+        public Action DisplayNomal;
+        /// <summary>
+        /// 显示默认动画
+        /// </summary>
+        public void DisplayDefault()
         {
             CountNomal++;
             Display(GraphType.Default, AnimatType.Single, DisplayNomal);
@@ -68,51 +72,6 @@ namespace VPet_Simulator.Core
                 Display(graph, EndAction);
                 return true;
             }
-            //switch (DisplayType)
-            //{
-            //    case GraphType.Idel:
-            //        Display(GraphType.Boring_C_End, EndAction);
-            //        return true;
-            //    case GraphType.Squat_B_Loop:
-            //        Display(GraphType.Squat_C_End, EndAction);
-            //        return true;
-            //    case GraphType.Crawl_Left_B_Loop:
-            //        Display(GraphType.Crawl_Left_C_End, EndAction);
-            //        return true;
-            //    case GraphType.Crawl_Right_B_Loop:
-            //        Display(GraphType.Crawl_Right_C_End, EndAction);
-            //        return true;
-            //    case GraphType.Fall_Left_B_Loop:
-            //        Display(GraphType.Fall_Left_C_End,
-            //            () => Display(GraphType.Climb_Up_Left, EndAction));
-            //        return true;
-            //    case GraphType.Fall_Right_B_Loop:
-            //        Display(GraphType.Fall_Right_C_End,
-            //            () => Display(GraphType.Climb_Up_Right, EndAction));
-            //        return true;
-            //    case GraphType.Walk_Left_B_Loop:
-            //        Display(GraphType.Walk_Left_C_End, EndAction);
-            //        return true;
-            //    case GraphType.Walk_Right_B_Loop:
-            //        Display(GraphType.Walk_Right_C_End, EndAction);
-            //        return true;
-            //    case GraphType.Sleep_B_Loop:
-            //        State = WorkingState.Nomal;
-            //        Display(GraphType.Sleep_C_End, EndAction);
-            //        return true;
-            //    case GraphType.Idel_StateONE_B_Loop:
-            //        Display(GraphType.Idel_StateONE_C_End, EndAction);
-            //        return true;
-            //    case GraphType.Idel_StateTWO_B_Loop:
-            //        Display(GraphType.Idel_StateTWO_C_End, () => Display(GraphType.Idel_StateONE_C_End, EndAction));
-            //        return true;
-            //        //case GraphType.Climb_Left:
-            //        //case GraphType.Climb_Right:
-            //        //case GraphType.Climb_Top_Left:
-            //        //case GraphType.Climb_Top_Right:
-            //        //    DisplayFalled_Left();
-            //        //    return true;
-            //}
             return false;
         }
         /// <summary>
diff --git a/VPet-Simulator.Core/Graph/GraphInfo.cs b/VPet-Simulator.Core/Graph/GraphInfo.cs
index 7144c9d..fcae9b7 100644
--- a/VPet-Simulator.Core/Graph/GraphInfo.cs
+++ b/VPet-Simulator.Core/Graph/GraphInfo.cs
@@ -21,6 +21,13 @@ namespace VPet_Simulator.Core
     /// 状态: 动画的状态 Save.GameSave.ModeType
     public class GraphInfo
     {
+        /// <summary>
+        /// 用于Convert的空动画信息
+        /// </summary>
+        public GraphInfo()
+        {
+
+        }
         /// <summary>
         /// 创建动画信息
         /// </summary>
diff --git a/VPet-Simulator.Windows.Interface/MPMessage.cs b/VPet-Simulator.Windows.Interface/MPMessage.cs
index 1fe7569..6313ec9 100644
--- a/VPet-Simulator.Windows.Interface/MPMessage.cs
+++ b/VPet-Simulator.Windows.Interface/MPMessage.cs
@@ -12,7 +12,7 @@ namespace VPet_Simulator.Windows.Interface;
 /// 多人模式传输的消息
 /// </summary>
 public struct MPMessage
-{
+{  
     /// <summary>
     /// 消息类型
     /// </summary>
@@ -49,10 +49,6 @@ public struct MPMessage
     /// </summary>
     public string Content;
     /// <summary>
-    /// 操作来自者 (也可能是自己)
-    /// </summary>
-    public ulong From;
-    /// <summary>
     /// 被操作者 (显示动画用)
     /// </summary>
     public ulong To;
diff --git a/VPet-Simulator.Windows/MainWindow.cs b/VPet-Simulator.Windows/MainWindow.cs
index 892d8f1..c109236 100644
--- a/VPet-Simulator.Windows/MainWindow.cs
+++ b/VPet-Simulator.Windows/MainWindow.cs
@@ -19,15 +19,12 @@ using System.Windows;
 using System.Windows.Controls;
 using System.Windows.Forms;
 using System.Windows.Interop;
-using System.Windows.Media.Imaging;
 using VPet_Simulator.Core;
 using VPet_Simulator.Windows.Interface;
 using static VPet_Simulator.Core.GraphHelper;
 using static VPet_Simulator.Core.GraphInfo;
 using Timer = System.Timers.Timer;
 using ToolBar = VPet_Simulator.Core.ToolBar;
-
-using MessageBox = System.Windows.MessageBox;
 using ContextMenu = System.Windows.Forms.ContextMenuStrip;
 using MenuItem = System.Windows.Forms.ToolStripMenuItem;
 using Application = System.Windows.Application;
@@ -378,7 +375,7 @@ namespace VPet_Simulator.Windows
                 }
             }
 
-            foreach (Sub sub in Set["diy"])
+            foreach (ISub sub in Set["diy"])
                 Main.ToolBar.AddMenuButton(ToolBar.MenuType.DIY, sub.Name, () =>
                 {
                     Main.ToolBar.Visibility = Visibility.Collapsed;
@@ -1334,7 +1331,7 @@ namespace VPet_Simulator.Windows
             Path.AddRange(new DirectoryInfo(ModPath).EnumerateDirectories());
 
             var workshop = Set["workshop"];
-            foreach (Sub ws in workshop)
+            foreach (ISub ws in workshop)
             {
                 Path.Add(new DirectoryInfo(ws.Name));
             }
@@ -1944,6 +1941,7 @@ namespace VPet_Simulator.Windows
                                  var panelWindow = new winCharacterPanel(this);
                                  panelWindow.MainTab.SelectedIndex = 2;
                                  panelWindow.Show();
+                                 Main.MsgBar.ForceClose();
                              };
                              return button;
                          });
diff --git a/VPet-Simulator.Windows/MainWindow.xaml.cs b/VPet-Simulator.Windows/MainWindow.xaml.cs
index 87559dd..20bbe4d 100644
--- a/VPet-Simulator.Windows/MainWindow.xaml.cs
+++ b/VPet-Simulator.Windows/MainWindow.xaml.cs
@@ -322,6 +322,7 @@ namespace VPet_Simulator.Windows
                 {
                     winMutiPlayer = new winMutiPlayer(this, lobby.Id);
                     winMutiPlayer.Show();
+                    Main.MsgBar.ForceClose();
                 };
                 Main.Say("收到来自{0}的访客邀请,是否加入?".Translate(friend.Name), msgcontent: btn);
             });
@@ -393,8 +394,9 @@ namespace VPet_Simulator.Windows
                     }
                     while (Windows.Count != 0)
                     {
-                        Windows[0].Close();
-                        Windows.RemoveAt(0);
+                        var w = Windows[0];
+                        w.Close();
+                        Windows.Remove(w);
                     }
                     Main?.Dispose();
                     AutoSaveTimer?.Stop();
diff --git a/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs b/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs
index 996b789..c0c37ae 100644
--- a/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs
+++ b/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs
@@ -20,6 +20,9 @@ using System.Drawing;
 using Point = System.Windows.Point;
 using Size = System.Windows.Size;
 using static VPet_Simulator.Core.GraphInfo;
+using System.Xml.Linq;
+using System.Windows.Interop;
+using LinePutScript.Converter;
 
 namespace VPet_Simulator.Windows;
 /// <summary>
@@ -60,7 +63,6 @@ public partial class MPFriends : WindowX
 
             //MGrid.Height = 500 * mw.Set.ZoomLevel;
             MGrid.Width = 500 * mw.Set.ZoomLevel;
-
             double L = 0, T = 0;
             if (mw.Set.StartRecordLast)
             {
@@ -203,6 +205,9 @@ public partial class MPFriends : WindowX
 
             Core.Graph = petloader.Graph(mw.Set.Resolution);
             Main = new Main(Core);
+            Main.DisplayNomal = DisplayMPNomal;
+            Main.EventTimer.AutoReset = false;
+            Main.EventTimer.Enabled = false;
 
             //清空资源
             Main.Resources = Application.Current.Resources;
@@ -232,28 +237,25 @@ public partial class MPFriends : WindowX
                     new Point(pin[(gdbe)"px"], pin[(gdbe)"py"]), new Size(pin[(gdbe)"sw"], pin[(gdbe)"sh"])
                     , DisplayPinch, true));
             }
-            SteamMatchmaking.OnLobbyMemberDataChanged += SteamMatchmaking_OnLobbyMemberDataChanged;
-            SteamMatchmaking.OnLobbyMemberLeave += SteamMatchmaking_OnLobbyMemberLeave;
-            Loaded = true;
-
             LoadingText.Content = "{0}的{1}".Translate(friend.Name, Core.Save.Name);
             LoadingText.Background = Function.ResourcesBrush(Function.BrushType.DARKPrimaryTransA);
             LoadingText.VerticalAlignment = VerticalAlignment.Top;
+
+            Loaded = true;
         }));
     }
     public new bool Loaded = false;
-    private void SteamMatchmaking_OnLobbyMemberLeave(Lobby lobby, Friend friend)
+    /// <summary>
+    /// 显示默认动画
+    /// </summary>
+    private void DisplayMPNomal()
     {
-        if (lobby.Id == lb.Id && friend.Id == this.friend.Id)
-            Quit();
-    }
+        Core.Save = GameSave_VPet.Load(new Line(lb.GetMemberData(friend, "save")));
 
-    private void SteamMatchmaking_OnLobbyMemberDataChanged(Lobby lobby, Friend friend)
-    {
-        if (lobby.Id == lb.Id && friend.Id == this.friend.Id)
-        {
-            Core.Save = GameSave_VPet.Load(new Line(lb.GetMemberData(friend, "save")));
-        }
+        if (DisplayGraph(LPSConvert.DeserializeObject<GraphInfo>(new LPS(lb.GetMemberData(friend, "display"))))) return;
+
+        Main.CountNomal++;
+        Main.Display(GraphType.Default, AnimatType.Single, DisplayMPNomal);
     }
 
     /// <summary>
@@ -313,11 +315,6 @@ public partial class MPFriends : WindowX
         }
     }
 
-    private void WindowX_Closed(object sender, EventArgs e)
-    {
-        wmp.MPFriends.Remove(this);
-        Loaded = false;
-    }
     /// <summary>
     /// 播放关闭动画并关闭,如果10秒后还未关闭则强制关闭
     /// </summary>
@@ -331,4 +328,29 @@ public partial class MPFriends : WindowX
                 Dispatcher.Invoke(Close);
         });
     }
+
+    public bool DisplayGraph(GraphInfo gi)
+    {
+        if (!Loaded || Main.DisplayType.Type == GraphType.StartUP || Main.DisplayType.Type == GraphType.Raised_Dynamic || Main.DisplayType.Type == GraphType.Raised_Static)
+        {
+            return false;
+        }
+        if (gi.Type == Main.DisplayType.Type && gi.Animat == Main.DisplayType.Animat)
+        {
+            if (gi.Type != GraphType.Common)
+                return false;
+        }
+        var img = Core.Graph.FindGraph(gi.Name, gi.Animat, Core.Save.Mode);
+        if (img != null)
+        {
+            Main.Display(img, DisplayMPNomal);
+            return true;
+        }
+        return false;
+    }
+
+    private void WindowX_Closed(object sender, EventArgs e)
+    {
+        mw.Windows.Remove(this);
+    }
 }
diff --git a/VPet-Simulator.Windows/MutiPlayer/MPUserControl.xaml.cs b/VPet-Simulator.Windows/MutiPlayer/MPUserControl.xaml.cs
index b9f3570..6551dda 100644
--- a/VPet-Simulator.Windows/MutiPlayer/MPUserControl.xaml.cs
+++ b/VPet-Simulator.Windows/MutiPlayer/MPUserControl.xaml.cs
@@ -22,9 +22,9 @@ namespace VPet_Simulator.Windows;
 /// </summary>
 public partial class MPUserControl : Border
 {
-    Friend friend => mpf.friend;
+    public Friend friend => mpf.friend;
     winMutiPlayer wmp;
-    MPFriends mpf;
+    public MPFriends mpf;
     Lobby lb => mpf.lb;
     public MPUserControl(winMutiPlayer wmp, MPFriends mpf)
     {
diff --git a/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs b/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs
index dc0283f..8d807ce 100644
--- a/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs
+++ b/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs
@@ -22,6 +22,7 @@ using System.Windows.Media.Imaging;
 using System.Windows.Shapes;
 using VPet_Simulator.Core;
 using VPet_Simulator.Windows.Interface;
+using static VPet_Simulator.Core.GraphInfo;
 
 namespace VPet_Simulator.Windows;
 /// <summary>
@@ -35,6 +36,7 @@ public partial class winMutiPlayer : Window
     /// 好友宠物模块
     /// </summary>
     public List<MPFriends> MPFriends = new List<MPFriends>();
+    public List<MPUserControl> MPUserControls = new List<MPUserControl>();
     public winMutiPlayer(MainWindow mw, ulong? lobbyid = null)
     {
         InitializeComponent();
@@ -46,7 +48,6 @@ public partial class winMutiPlayer : Window
     }
     public async void JoinLobby(ulong lobbyid)
     {
-        MessageBoxX.Show(lobbyid.ToString("x"));
         var lbt = (await SteamMatchmaking.JoinLobbyAsync((SteamId)lobbyid));
         if (!lbt.HasValue || lbt.Value.Owner.Id.Value == 0)
         {
@@ -107,6 +108,7 @@ public partial class winMutiPlayer : Window
         BitmapFrame result = BitmapFrame.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad);
         return result;
     }
+    ulong owner;
     public async void ShowLobbyInfo()
     {
         lb.SetMemberData("save", mw.GameSavesData.GameSave.ToLine().ToString());
@@ -115,14 +117,16 @@ public partial class winMutiPlayer : Window
 
         SteamMatchmaking.OnLobbyDataChanged += SteamMatchmaking_OnLobbyDataChanged;
         SteamMatchmaking.OnLobbyMemberJoined += SteamMatchmaking_OnLobbyMemberJoined;
+        SteamMatchmaking.OnLobbyMemberLeave += SteamMatchmaking_OnLobbyMemberLeave;
         hostName.Text = lb.Owner.Name;
+        owner = lb.Owner.Id.Value;
         lbLid.Text = lb.Id.Value.ToString("x");
         Steamworks.Data.Image? img = await lb.Owner.GetMediumAvatarAsync();
         HostHead.Source = ConvertToImageSource(img.Value);
 
         //给自己动画添加绑定
         mw.Main.GraphDisplayHandler += Main_GraphDisplayHandler;
-        if (lb.Owner.Id == SteamClient.SteamId)
+        if (lb.Owner.IsMe)
         {
             hostPet.Text = mw.GameSavesData.GameSave.Name;
             Title = "{0}的访客表".Translate(mw.GameSavesData.GameSave.Name);
@@ -136,6 +140,8 @@ public partial class winMutiPlayer : Window
             mpf.Show();
             var mpuc = new MPUserControl(this, mpf);
             MUUCList.Children.Add(mpuc);
+            MPUserControls.Add(mpuc);
+            SteamNetworking.AcceptP2PSessionWithUser(v.Id);
             if (v.Id == lb.Owner.Id)
                 _ = Task.Run(() =>
                 {
@@ -152,9 +158,35 @@ public partial class winMutiPlayer : Window
                 });
         }
     }
+
+    private void SteamMatchmaking_OnLobbyMemberLeave(Lobby lobby, Friend friend)
+    {
+        if (friend.Id == owner)
+        {
+            Task.Run(() => MessageBox.Show("访客表已被房主{0}关闭".Translate(friend.Name)));
+            lb = default(Lobby);
+            Close();
+        }
+        else
+        {
+            var mpuc = MPUserControls.Find(x => x.mpf.friend.Id == friend.Id);
+            if (mpuc != null)
+            {
+                MPUserControls.Remove(mpuc);
+                MUUCList.Children.Remove(mpuc);
+                MPFriends.Remove(mpuc.mpf);
+            }
+        }
+    }
+
     private void Main_GraphDisplayHandler(GraphInfo info)
     {
-        lb.SendChatString(MPMessage.ConverTo(new MPMessage() { Type = MPMessage.MSGType.DispayGraph, Content = LPSConvert.SerializeObject(info).ToString() }));
+        if (info.Type == GraphType.Shutdown || info.Type == GraphType.Common || info.Type == GraphType.Move
+            || info.Type == GraphType.Raised_Dynamic || info.Type == GraphType.Raised_Static || info.Type == GraphType.Default)
+        {
+            return;
+        }
+        lb.SetMemberData("display", LPSConvert.SerializeObject(info).ToString());
     }
 
     private void SteamMatchmaking_OnLobbyMemberJoined(Lobby lobby, Friend friend)
@@ -165,31 +197,18 @@ public partial class winMutiPlayer : Window
         }
     }
 
-    private void SteamMatchmaking_OnLobbyMemberDataChanged(Lobby lobby, Friend friend)
-    {
-        if (lobby.Id == lb.Id)
-        {
-
-        }
-    }
 
     private void SteamMatchmaking_OnLobbyDataChanged(Lobby lobby)
     {
         if (lobby.Id == lb.Id)
         {
-            if (lb.GetData("leave") == "true")
-            {
-                MessageBoxX.Show("访客表已被房主{0}关闭".Translate(lb.Owner.Name));
-                lb = default(Lobby);
-                Close();
-            }
+
         }
     }
 
     private void Window_Closed(object sender, EventArgs e)
     {
         SteamMatchmaking.OnLobbyDataChanged -= SteamMatchmaking_OnLobbyDataChanged;
-        SteamMatchmaking.OnLobbyMemberDataChanged -= SteamMatchmaking_OnLobbyMemberDataChanged;
         mw.Main.GraphDisplayHandler -= Main_GraphDisplayHandler;
         if (lb.Owner.Id == SteamClient.SteamId)
             lb.SetData("leave", "true");
diff --git a/VPet-Simulator.Windows/Properties/launchSettings.json b/VPet-Simulator.Windows/Properties/launchSettings.json
index 3e7b8fa..e2b6f2f 100644
--- a/VPet-Simulator.Windows/Properties/launchSettings.json
+++ b/VPet-Simulator.Windows/Properties/launchSettings.json
@@ -1,7 +1,8 @@
 {
   "profiles": {
     "VPet-Simulator.Windows": {
-      "commandName": "Project"
+      "commandName": "Project",
+      "nativeDebugging": true
     }
   }
 }
\ No newline at end of file
diff --git a/VPet-Simulator.Windows/VPet-Simulator.Windows.csproj b/VPet-Simulator.Windows/VPet-Simulator.Windows.csproj
index e3198c7..a3926ce 100644
--- a/VPet-Simulator.Windows/VPet-Simulator.Windows.csproj
+++ b/VPet-Simulator.Windows/VPet-Simulator.Windows.csproj
@@ -39,19 +39,23 @@
 		<PlatformTarget>x64</PlatformTarget>
 		<OutputPath>bin\x64\Debug\</OutputPath>
 		<DefineConstants>$(DefineConstants);X64</DefineConstants>
+		<NoWarn>1701;1702</NoWarn>
 	</PropertyGroup>
 	<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
 		<PlatformTarget>x64</PlatformTarget>
 		<OutputPath>bin\x64\Release\</OutputPath>
 		<DefineConstants>$(DefineConstants);X64</DefineConstants>
+		<NoWarn>1701;1702</NoWarn>
 	</PropertyGroup>
 	<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
 		<PlatformTarget>x86</PlatformTarget>
 		<OutputPath>bin\x86\Debug\</OutputPath>
+		<NoWarn>1701;1702</NoWarn>
 	</PropertyGroup>
 	<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
 		<PlatformTarget>x86</PlatformTarget>
 		<OutputPath>bin\x86\Release\</OutputPath>
+		<NoWarn>1701;1702</NoWarn>
 	</PropertyGroup>
 	<ItemGroup>
 		<AssemblyAttribute Include="System.Reflection.AssemblyTrademarkAttribute">
diff --git a/VPet-Simulator.Windows/WinDesign/winWorkMenu.xaml.cs b/VPet-Simulator.Windows/WinDesign/winWorkMenu.xaml.cs
index fa05d48..f442f65 100644
--- a/VPet-Simulator.Windows/WinDesign/winWorkMenu.xaml.cs
+++ b/VPet-Simulator.Windows/WinDesign/winWorkMenu.xaml.cs
@@ -73,7 +73,7 @@ public partial class winWorkMenu : Window
         }
         else
         {
-            int max = mw.GameSavesData.GameSave.Level / (nowwork.LevelLimit + 10);
+            int max = Math.Min(4000, mw.GameSavesData.GameSave.Level) / (nowwork.LevelLimit + 10);
             if (max <= 1)
             {
                 wDouble.IsEnabled = false;
@@ -83,7 +83,7 @@ public partial class winWorkMenu : Window
             {
                 wDouble.IsEnabled = true;
                 wDouble.Maximum = max;
-                wDouble.Value = mw.Set.GameData.GetDouble("workmenu_" + nowwork.Name, 1);
+                wDouble.Value = mw.Set.GameData.GetInt("workmenu_" + nowwork.Name, 1);
             }
         }
         if (wDouble.Value == 1)
@@ -147,6 +147,7 @@ public partial class winWorkMenu : Window
     private void wDouble_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
     {
         if (!AllowChange) return;
+        mw.Set.GameData.SetInt("workmenu_" + nowwork.Name, (int)wDouble.Value);
         ShowWork(nowwork.Double((int)wDouble.Value));
     }