diff --git a/VPet-Simulator.Windows.Interface/IMainWindow.cs b/VPet-Simulator.Windows.Interface/IMainWindow.cs index 99890423..7bb43449 100644 --- a/VPet-Simulator.Windows.Interface/IMainWindow.cs +++ b/VPet-Simulator.Windows.Interface/IMainWindow.cs @@ -1,5 +1,6 @@ using LinePutScript; using LinePutScript.Dictionary; +using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; @@ -164,6 +165,10 @@ namespace VPet_Simulator.Windows.Interface /// 主窗体 Pet Grid /// Grid PetGrid { get; } + /// + /// 当创建/加入新的多人联机窗口(访客表)时触发 + /// + event Action MutiPlayerHandle; } } diff --git a/VPet-Simulator.Windows.Interface/MutiPlayer/IMPFriend.cs b/VPet-Simulator.Windows.Interface/MutiPlayer/IMPFriend.cs new file mode 100644 index 00000000..cf90af5b --- /dev/null +++ b/VPet-Simulator.Windows.Interface/MutiPlayer/IMPFriend.cs @@ -0,0 +1,56 @@ +using LinePutScript; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VPet_Simulator.Core; +using static VPet_Simulator.Windows.Interface.MPMessage; + +namespace VPet_Simulator.Windows.Interface; +/// +/// 好友的宠物(图形)模块接口 +/// +public interface IMPFriend +{ + /// + /// 访客表id + /// + ulong LobbyID { get; } + /// + /// 好友id + /// + ulong FriendID { get; } + /// + /// 桌宠数据核心 + /// + GameCore Core { get; } + /// + /// 图像资源集 + /// + ImageResources ImageSources { get; } + + /// + /// 当前宠物图形名称 + /// + string SetPetGraph { get; } + /// + /// 桌宠主要部件 + /// + Main Main { get; } + + /// + /// 智能化显示后续过度动画 + /// + void DisplayAuto(GraphInfo gi); + + /// + /// 根据好友数据显示动画 + /// + bool DisplayGraph(GraphInfo gi); + /// + /// 显示好友之间聊天消息 + /// + /// 聊天内容 + void DisplayMessage(Chat msg); +} diff --git a/VPet-Simulator.Windows.Interface/MutiPlayer/IMPWindows.cs b/VPet-Simulator.Windows.Interface/MutiPlayer/IMPWindows.cs new file mode 100644 index 00000000..ce287027 --- /dev/null +++ b/VPet-Simulator.Windows.Interface/MutiPlayer/IMPWindows.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VPet_Simulator.Windows.Interface; + +/// +/// 多人联机窗口接口 (访客表) +/// +public interface IMPWindows +{ + /// + /// 访客表id + /// + ulong LobbyID { get; } + /// + /// 所有好友(不包括自己) + /// + IEnumerable Friends { get; } + /// + /// 主持人SteamID + /// + ulong OwnerID { get; } + + /// + /// 事件:成员退出 + /// + event Action OnMemberLeave; + /// + /// 事件:成员加入 + /// + event Action OnMemberJoined; + /// + /// 给指定好友发送消息(数据包) + /// + /// 好友id + /// 消息内容(数据包) + void SendMessage(ulong friendid, MPMessage msg); + + /// + /// 给所有人发送消息 + /// + void SendMessageALL(MPMessage msg); + + /// + /// 发送日志消息 + /// + /// 日志 + void Log(string message); + + /// + /// 收到消息日志 发送人id, 消息内容 + /// + event Action ReceivedMessage; + /// + /// 事件: 结束访客表, 窗口关闭 + /// + event Action ClosingMutiPlayer; +} diff --git a/VPet-Simulator.Windows.Interface/MutiPlayer/MPMessage.cs b/VPet-Simulator.Windows.Interface/MutiPlayer/MPMessage.cs index 6818db0a..2cb89652 100644 --- a/VPet-Simulator.Windows.Interface/MutiPlayer/MPMessage.cs +++ b/VPet-Simulator.Windows.Interface/MutiPlayer/MPMessage.cs @@ -48,7 +48,7 @@ public struct MPMessage /// /// 消息类型 /// - [Line] public MSGType Type { get; set; } + [Line] public int Type { get; set; } /// /// 消息内容 diff --git a/VPet-Simulator.Windows/MainWindow.cs b/VPet-Simulator.Windows/MainWindow.cs index a1100c18..1d459176 100644 --- a/VPet-Simulator.Windows/MainWindow.cs +++ b/VPet-Simulator.Windows/MainWindow.cs @@ -2003,6 +2003,13 @@ namespace VPet_Simulator.Windows } TextBlock tlvplus; + + public event Action MutiPlayerHandle; + internal void MutiPlayerStart(IMPWindows mp) + { + MutiPlayerHandle?.Invoke(mp); + } + private void MWUIHandle(Main main) { if (Main.ToolBar.BdrPanel.Visibility == Visibility.Visible) diff --git a/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs b/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs index 38ea2db4..24a269c4 100644 --- a/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs +++ b/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs @@ -30,7 +30,7 @@ namespace VPet_Simulator.Windows; /// /// MPFriends.xaml 的交互逻辑 /// -public partial class MPFriends : WindowX +public partial class MPFriends : WindowX, IMPFriend { public Lobby lb; MainWindow mw; @@ -42,7 +42,7 @@ public partial class MPFriends : WindowX public List Pets { get; set; } = new List(); public ILine OnMod { get; set; } - public string SetPetGraph; + public string SetPetGraph { get; set; } public bool IsOnMod(string ModName) { if (CoreMOD.OnModDefList.Contains(ModName)) @@ -166,6 +166,11 @@ public partial class MPFriends : WindowX } public List MPMODs = new List(); public Main Main { get; set; } + + public ulong LobbyID => lb.Id; + + public ulong FriendID => friend.Id; + /// /// 加载游戏 /// @@ -446,7 +451,7 @@ public partial class MPFriends : WindowX Task.Run(() => { MPMessage msg = new MPMessage(); - msg.Type = MSGType.Chat; + msg.Type = (int)MSGType.Chat; msg.SetContent(new Chat() { Content = cont, ChatType = (Chat.Type)talktype, SendName = SteamClient.Name }); msg.To = SteamClient.SteamId; diff --git a/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs b/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs index c66be0a9..0d956393 100644 --- a/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs +++ b/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs @@ -9,6 +9,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; @@ -28,7 +29,7 @@ namespace VPet_Simulator.Windows; /// /// winMutiPlayer.xaml 的交互逻辑 /// -public partial class winMutiPlayer : Window +public partial class winMutiPlayer : Window, IMPWindows { Steamworks.Data.Lobby lb; MainWindow mw; @@ -108,7 +109,12 @@ public partial class winMutiPlayer : Window BitmapFrame result = BitmapFrame.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); return result; } - ulong owner; + public ulong OwnerID { get; set; } + + public ulong LobbyID => lb.Id.Value; + + public IEnumerable Friends => MPFriends; + public void ShowLobbyInfo() { _ = Task.Run(async () => @@ -117,7 +123,6 @@ public partial class winMutiPlayer : Window lb.SetMemberData("onmod", mw.Set.FindLine("onmod")?.ToString() ?? "onmod"); lb.SetMemberData("petgraph", mw.Set.PetGraph); - SteamMatchmaking.OnLobbyDataChanged += SteamMatchmaking_OnLobbyDataChanged; SteamMatchmaking.OnLobbyMemberJoined += SteamMatchmaking_OnLobbyMemberJoined; SteamMatchmaking.OnLobbyMemberLeave += SteamMatchmaking_OnLobbyMemberLeave; Steamworks.Data.Image? img = await lb.Owner.GetMediumAvatarAsync(); @@ -125,7 +130,7 @@ public partial class winMutiPlayer : Window Dispatcher.Invoke(() => { hostName.Text = lb.Owner.Name; - owner = lb.Owner.Id.Value; + OwnerID = lb.Owner.Id.Value; lbLid.Text = lb.Id.Value.ToString("x"); HostHead.Source = ConvertToImageSource(img.Value); }); @@ -175,13 +180,16 @@ public partial class winMutiPlayer : Window }); }); } + mw.MutiPlayerStart(this); LoopP2PPacket(); }); } - + public event Action OnMemberLeave; private void SteamMatchmaking_OnLobbyMemberLeave(Lobby lobby, Friend friend) { - if (friend.Id == owner) + if (lobby.Id != lb.Id) return; + OnMemberLeave?.Invoke(friend.Id); + if (friend.Id == OwnerID) { Task.Run(() => MessageBox.Show("访客表已被房主{0}关闭".Translate(friend.Name))); lb = default(Lobby); @@ -212,7 +220,7 @@ public partial class winMutiPlayer : Window return; lastgraph = info; MPMessage msg = new MPMessage(); - msg.Type = MSGType.DispayGraph; + msg.Type = (int)MSGType.DispayGraph; msg.SetContent(info); msg.To = SteamClient.SteamId.Value; SendMessageALL(msg); @@ -220,8 +228,6 @@ public partial class winMutiPlayer : Window /// /// 给指定好友发送消息 /// - /// - /// public void SendMessage(ulong friendid, MPMessage msg) { byte[] data = ConverTo(msg); @@ -240,7 +246,19 @@ public partial class winMutiPlayer : Window } } + /// + /// 发送日志消息 + /// + /// 日志 + public void Log(string message) + { + Dispatcher.Invoke(() => tbLog.AppendText($"[{DateTime.Now.ToShortTimeString()}]{message}\n")); + } + /// + /// 事件:成员加入 + /// + public event Action OnMemberJoined; private void SteamMatchmaking_OnLobbyMemberJoined(Lobby lobby, Friend friend) { if (lobby.Id == lb.Id) @@ -251,15 +269,7 @@ public partial class winMutiPlayer : Window var mpuc = new MPUserControl(this, mpf); MUUCList.Children.Add(mpuc); MPUserControls.Add(mpuc); - } - } - - - private void SteamMatchmaking_OnLobbyDataChanged(Lobby lobby) - { - if (lobby.Id == lb.Id) - { - + OnMemberJoined?.Invoke(friend.Id); } } private void LoopP2PPacket() @@ -272,15 +282,17 @@ public partial class winMutiPlayer : Window var packet = SteamNetworking.ReadP2PPacket(); if (packet.HasValue) { - var From = packet.Value.SteamId; + SteamId From = packet.Value.SteamId; var MSG = ConverTo(packet.Value.Data); - var To = MPFriends.Find(x => x.friend.Id == MSG.To); + ReceivedMessage?.Invoke(From.Value, MSG); switch (MSG.Type) { - case MSGType.DispayGraph: + case (int)MSGType.DispayGraph: + var To = MPFriends.Find(x => x.friend.Id == MSG.To); To.DisplayGraph(MSG.GetContent()); break; - case MSGType.Chat: + case (int)MSGType.Chat: + To = MPFriends.Find(x => x.friend.Id == MSG.To); To.DisplayMessage(MSG.GetContent()); break; } @@ -294,9 +306,10 @@ public partial class winMutiPlayer : Window } } + + public event Action ReceivedMessage; private void Window_Closed(object sender, EventArgs e) { - SteamMatchmaking.OnLobbyDataChanged -= SteamMatchmaking_OnLobbyDataChanged; mw.Main.GraphDisplayHandler -= Main_GraphDisplayHandler; SteamMatchmaking.OnLobbyMemberJoined -= SteamMatchmaking_OnLobbyMemberJoined; lb.Leave(); @@ -307,6 +320,10 @@ public partial class winMutiPlayer : Window mw.winMutiPlayer = null; } bool isOPEN = true; + /// + /// 事件: 结束访客表, 窗口关闭 + /// + public event Action ClosingMutiPlayer; private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { if (!lb.Equals(default(Lobby))) @@ -315,6 +332,7 @@ public partial class winMutiPlayer : Window e.Cancel = true; return; } + ClosingMutiPlayer?.Invoke(); isOPEN = false; }