diff --git a/VPet-Simulator.Windows/MainWindow.cs b/VPet-Simulator.Windows/MainWindow.cs index a5b4a4d..892d8f1 100644 --- a/VPet-Simulator.Windows/MainWindow.cs +++ b/VPet-Simulator.Windows/MainWindow.cs @@ -1156,7 +1156,7 @@ namespace VPet_Simulator.Windows Grid IMainWindow.MGHost => MGHost; Grid IMainWindow.PetGrid => MGrid; - + internal MWController MWController { get; set; } /// /// 移除所有聊天对话框 /// @@ -1254,7 +1254,8 @@ namespace VPet_Simulator.Windows Top = T; // control position inside bounds - Core.Controller = new MWController(this); + MWController = new MWController(this); + Core.Controller = MWController; Task.Run(() => { double dist; @@ -1998,7 +1999,7 @@ namespace VPet_Simulator.Windows } - + #if NewYear int newyearsay = 0; diff --git a/VPet-Simulator.Windows/MainWindow.xaml.cs b/VPet-Simulator.Windows/MainWindow.xaml.cs index e7d2291..a8f7f36 100644 --- a/VPet-Simulator.Windows/MainWindow.xaml.cs +++ b/VPet-Simulator.Windows/MainWindow.xaml.cs @@ -21,7 +21,6 @@ using static VPet_Simulator.Core.GraphInfo; using System.Globalization; using LinePutScript.Dictionary; using Steamworks.Data; -using VPet_Simulator.Windows.WinDesign; namespace VPet_Simulator.Windows { @@ -221,7 +220,7 @@ namespace VPet_Simulator.Windows if (IsSteamUser) Dispatcher.Invoke(() => { - Main.ToolBar.AddMenuButton(ToolBar.MenuType.Setting, "访客表".Translate(), () => + Main.ToolBar.AddMenuButton(ToolBar.MenuType.Interact, "访客表".Translate(), () => { if (winMutiPlayer == null) { @@ -233,6 +232,15 @@ namespace VPet_Simulator.Windows winMutiPlayer.Focus(); } }); + int clid = Array.IndexOf(App.Args, "connect_lobby"); + if (clid != -1) + { + if (ulong.TryParse(App.Args[clid + 1], out ulong lid)) + { + winMutiPlayer = new winMutiPlayer(this, lid); + winMutiPlayer.Show(); + } + } }); }); diff --git a/VPet-Simulator.Windows/MutiPlayer/MPController.cs b/VPet-Simulator.Windows/MutiPlayer/MPController.cs new file mode 100644 index 0000000..38e651e --- /dev/null +++ b/VPet-Simulator.Windows/MutiPlayer/MPController.cs @@ -0,0 +1,116 @@ +using System.Windows.Forms; +using System.Windows.Interop; +using System.Drawing; +using VPet_Simulator.Core; + +namespace VPet_Simulator.Windows +{ + /// + /// 窗体控制器实现 + /// + public class MPController : IController + { + readonly MPFriends mp; + readonly MainWindow mw; + public MPController(MPFriends mp, MainWindow mw) + { + this.mp = mp; + this.mw = mw; + } + + public double GetWindowsDistanceLeft() + { + return mp.Dispatcher.Invoke(() => + { + if (mw.MWController.IsPrimaryScreen) return mp.Left; + return mp.Left - mw.MWController.ScreenBorder.X; + }); + } + + public double GetWindowsDistanceUp() + { + return mp.Dispatcher.Invoke(() => + { + if (mw.MWController.IsPrimaryScreen) return mp.Top; + return mp.Top - mw.MWController.ScreenBorder.Y; + }); + } + + public double GetWindowsDistanceRight() + { + return mp.Dispatcher.Invoke(() => + { + if (mw.MWController.IsPrimaryScreen) return System.Windows.SystemParameters.PrimaryScreenWidth - mp.Left - mp.ActualWidth; + return mw.MWController.ScreenBorder.Width + mw.MWController.ScreenBorder.X - mp.Left - mp.ActualWidth; + }); + } + + public double GetWindowsDistanceDown() + { + return mp.Dispatcher.Invoke(() => + { + if (mw.MWController.IsPrimaryScreen) return System.Windows.SystemParameters.PrimaryScreenHeight - mp.Top - mp.ActualHeight; + return mw.MWController.ScreenBorder.Height + mw.MWController.ScreenBorder.Y - mp.Top - mp.ActualHeight; + }); + } + + public void MoveWindows(double X, double Y) + { + mp.Dispatcher.Invoke(() => + { + mp.Left += X * ZoomRatio; + mp.Top += Y * ZoomRatio; + }); + } + + public void ShowSetting() + { + + } + + public void ShowPanel() + { + + } + + public void ResetPosition() + { + mp.Dispatcher.Invoke(() => + { + if (GetWindowsDistanceUp() < -0.25 * mp.ActualHeight && GetWindowsDistanceDown() < System.Windows.SystemParameters.PrimaryScreenHeight) + { + MoveWindows(0, -GetWindowsDistanceUp() / ZoomRatio); + } + else if (GetWindowsDistanceDown() < -0.25 * mp.ActualHeight && GetWindowsDistanceUp() < System.Windows.SystemParameters.PrimaryScreenHeight) + { + MoveWindows(0, GetWindowsDistanceDown() / ZoomRatio); + } + if (GetWindowsDistanceLeft() < -0.25 * mp.ActualWidth && GetWindowsDistanceRight() < System.Windows.SystemParameters.PrimaryScreenWidth) + { + MoveWindows(-GetWindowsDistanceLeft() / ZoomRatio, 0); + } + else if (GetWindowsDistanceRight() < -0.25 * mp.ActualWidth && GetWindowsDistanceLeft() < System.Windows.SystemParameters.PrimaryScreenWidth) + { + MoveWindows(GetWindowsDistanceRight() / ZoomRatio, 0); + } + }); + } + public bool CheckPosition() => mp.Dispatcher.Invoke(() => + GetWindowsDistanceUp() < -0.25 * mp.ActualHeight && GetWindowsDistanceDown() < System.Windows.SystemParameters.PrimaryScreenHeight + || GetWindowsDistanceDown() < -0.25 * mp.ActualHeight && GetWindowsDistanceUp() < System.Windows.SystemParameters.PrimaryScreenHeight + || GetWindowsDistanceLeft() < -0.25 * mp.ActualWidth && GetWindowsDistanceRight() < System.Windows.SystemParameters.PrimaryScreenWidth + || GetWindowsDistanceRight() < -0.25 * mp.ActualWidth && GetWindowsDistanceLeft() < System.Windows.SystemParameters.PrimaryScreenWidth + ); + + public bool RePostionActive { get; set; } = true; + + public double ZoomRatio => mw.Set.ZoomLevel; + + public int PressLength => mw.Set.PressLength; + + public bool EnableFunction => true; + + public int InteractionCycle => mw.Set.InteractionCycle; + + } +} diff --git a/VPet-Simulator.Windows/MWFriends.xaml b/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml similarity index 62% rename from VPet-Simulator.Windows/MWFriends.xaml rename to VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml index 11bd576..b9d3a05 100644 --- a/VPet-Simulator.Windows/MWFriends.xaml +++ b/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml @@ -1,4 +1,4 @@ - - - + + + diff --git a/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs b/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs new file mode 100644 index 0000000..962b31a --- /dev/null +++ b/VPet-Simulator.Windows/MutiPlayer/MPFriends.xaml.cs @@ -0,0 +1,300 @@ +using LinePutScript.Dictionary; +using LinePutScript; +using Panuon.WPF.UI; +using Steamworks; +using Steamworks.Data; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using LinePutScript.Localization.WPF; +using System.Threading; +using VPet_Simulator.Windows.Interface; +using VPet_Simulator.Core; +using static VPet_Simulator.Core.GraphHelper; +using System.Drawing; +using Point = System.Windows.Point; +using Size = System.Windows.Size; +using static VPet_Simulator.Core.GraphInfo; + +namespace VPet_Simulator.Windows; +/// +/// MPFriends.xaml 的交互逻辑 +/// +public partial class MPFriends : WindowX +{ + public Lobby lb; + MainWindow mw; + public Friend friend; + public GameCore Core { get; set; } = new GameCore(); + public List Foods { get; } = new List(); + public ImageResources ImageSources { get; } + public List Pets { get; set; } = new List(); + public ILine OnMod { get; set; } + + public string SetPetGraph; + public bool IsOnMod(string ModName) + { + if (CoreMOD.OnModDefList.Contains(ModName)) + return true; + return OnMod.Find(ModName.ToLower()) != null; + } + + public MPFriends(MainWindow mw, Lobby lb, Friend friend) + { + this.mw = mw; + this.lb = lb; + this.friend = friend; + + mw.Windows.Add(this); + try + { + + InitializeComponent(); + + //MGrid.Height = 500 * mw.Set.ZoomLevel; + MGrid.Width = 500 * mw.Set.ZoomLevel; + + double L = 0, T = 0; + if (mw.Set.StartRecordLast) + { + var point = mw.Set.StartRecordLastPoint; + if (point.X != 0 || point.Y != 0) + { + L = point.X; + T = point.Y; + } + } + else + { + var point = mw.Set.StartRecordPoint; + L = point.X; T = point.Y; + } + + Left = L; + Top = T; + + // control position inside bounds + Core.Controller = new MPController(this, mw); + Task.Run(() => + { + double dist; + if ((dist = Core.Controller.GetWindowsDistanceLeft()) < 0) + { + Thread.Sleep(100); + Dispatcher.Invoke(() => Left -= dist); + } + if ((dist = Core.Controller.GetWindowsDistanceRight()) < 0) + { + Thread.Sleep(100); + Dispatcher.Invoke(() => Left += dist); + } + if ((dist = Core.Controller.GetWindowsDistanceUp()) < 0) + { + Thread.Sleep(100); + Dispatcher.Invoke(() => Top -= dist); + } + if ((dist = Core.Controller.GetWindowsDistanceDown()) < 0) + { + Thread.Sleep(100); + Dispatcher.Invoke(() => Top += dist); + } + }); + if (mw.Set.TopMost) + { + Topmost = true; + } + + } + catch + { + Close(); + return; + } + + + ImageSources.AddRange(mw.ImageSources); + + + //加载所有MOD + List Path = new List(); + Path.AddRange(new DirectoryInfo(mw.ModPath).EnumerateDirectories()); + + var workshop = mw.Set["workshop"]; + foreach (Sub ws in workshop) + { + Path.Add(new DirectoryInfo(ws.Name)); + } + + Task.Run(async () => + { + //加载lobby传过来的数据 + string tmp = lb.GetMemberData(friend, "save"); + while (string.IsNullOrEmpty(tmp)) + { + Thread.Sleep(500); + tmp = lb.GetMemberData(friend, "save"); + } + Core.Save = GameSave_VPet.Load(new Line(tmp)); + tmp = lb.GetMemberData(friend, "onmod"); + while (string.IsNullOrEmpty(tmp)) + { + Thread.Sleep(100); + tmp = lb.GetMemberData(friend, "onmod"); + } + OnMod = new Line(tmp); + + tmp = lb.GetMemberData(friend, "petgraph"); + while (string.IsNullOrEmpty(tmp)) + { + Thread.Sleep(100); + tmp = lb.GetMemberData(friend, "onmod"); + } + SetPetGraph = tmp; + + await GameLoad(Path); + }); + + } + public List MPMODs = new List(); + public Main Main { get; set; } + /// + /// 加载游戏 + /// + /// MOD地址 + public async Task GameLoad(List Path) + { + Path = Path.Distinct().ToList(); + await Dispatcher.InvokeAsync(new Action(() => LoadingText.Content = "Loading MOD")); + //加载mod + foreach (DirectoryInfo di in Path) + { + if (!File.Exists(di.FullName + @"\info.lps")) + continue; + await Dispatcher.InvokeAsync(new Action(() => LoadingText.Content = $"Loading MOD: {di.Name}")); + MPMODs.Add(new MPMOD(di, this)); + } + + await Dispatcher.InvokeAsync(new Action(() => LoadingText.Content = "尝试加载游戏MOD".Translate())); + + //当前桌宠动画 + var petloader = Pets.Find(x => x.Name == SetPetGraph); + petloader ??= Pets[0]; + + + //加载数据合理化:食物 + foreach (Food f in Foods) + { + if (f.IsOverLoad()) + { + f.Price = Math.Max((int)f.RealPrice, 1); + f.isoverload = false; + } + } + await Dispatcher.InvokeAsync(new Action(() => + { + LoadingText.Content = "尝试加载动画和生成缓存\n该步骤可能会耗时比较长\n请耐心等待".Translate(); + + Core.Graph = petloader.Graph(mw.Set.Resolution); + Main = new Main(Core); + + //清空资源 + Main.Resources = Application.Current.Resources; + Main.MsgBar.This.Resources = Application.Current.Resources; + Main.ToolBar.Resources = Application.Current.Resources; + Main.ToolBar.LoadClean(); + + LoadingText.Content = "正在加载游戏\n该步骤可能会耗时比较长\n请耐心等待".Translate(); + + Main.PlayVoiceVolume = mw.Set.VoiceVolume; + + DisplayGrid.Child = Main; + Task.Run(async () => + { + while (Main.IsWorking) + { + Thread.Sleep(100); + } + await Dispatcher.InvokeAsync(() => LoadingText.Visibility = Visibility.Collapsed); + }); + + + Main.SetMoveMode(mw.Set.AllowMove, mw.Set.SmartMove, mw.Set.SmartMoveInterval * 1000); + Main.SetLogicInterval(1500); + if (mw.Set.MessageBarOutside) + Main.MsgBar.SetPlaceOUT(); + + Main.WorkCheck = mw.WorkCheck; + + + //添加捏脸动画(若有) + if (Core.Graph.GraphConfig.Data.ContainsLine("pinch")) + { + var pin = Core.Graph.GraphConfig.Data["pinch"]; + Main.Core.TouchEvent.Insert(0, new TouchArea( + new Point(pin[(gdbe)"px"], pin[(gdbe)"py"]), new Size(pin[(gdbe)"sw"], pin[(gdbe)"sh"]) + , DisplayPinch, true)); + } + })); + } + /// + /// 显示捏脸情况 + /// + public bool DisplayPinch() + { + if (Core.Graph.FindGraphs("pinch", AnimatType.A_Start, Core.Save.Mode) == null) + { + return false; + } + Main.CountNomal = 0; + + if (Core.Controller.EnableFunction && Core.Save.Strength >= 10 && Core.Save.Feeling < 100) + { + Core.Save.StrengthChange(-2); + Core.Save.FeelingChange(1); + Core.Save.Mode = Core.Save.CalMode(); + Main.LabelDisplayShowChangeNumber(LocalizeCore.Translate("体力-{0:f0} 心情+{1:f0}"), 2, 1); + } + if (Main.DisplayType.Name == "pinch") + { + if (Main.DisplayType.Animat == AnimatType.A_Start) + return false; + else if (Main.DisplayType.Animat == AnimatType.B_Loop) + if (Dispatcher.Invoke(() => Main.PetGrid.Tag) is IGraph ig && ig.GraphInfo.Name == "pinch" && ig.GraphInfo.Animat == AnimatType.B_Loop) + { + ig.IsContinue = true; + return true; + } + else if (Dispatcher.Invoke(() => Main.PetGrid2.Tag) is IGraph ig2 && ig2.GraphInfo.Name == "pinch" && ig2.GraphInfo.Animat == AnimatType.B_Loop) + { + ig2.IsContinue = true; + return true; + } + } + Main.Display("pinch", AnimatType.A_Start, () => + Main.Display("pinch", AnimatType.B_Loop, DisplayPinch_loop)); + return true; + } + private void DisplayPinch_loop() + { + if (Main.isPress && Main.DisplayType.Name == "pinch" && Main.DisplayType.Animat == AnimatType.B_Loop) + { + if (Core.Controller.EnableFunction && Core.Save.Strength >= 10 && Core.Save.Feeling < 100) + { + Core.Save.StrengthChange(-2); + Core.Save.FeelingChange(1); + Core.Save.Mode = Core.Save.CalMode(); + Main.LabelDisplayShowChangeNumber(LocalizeCore.Translate("体力-{0:f0} 心情+{1:f0}"), 2, 1); + } + Main.Display("pinch", AnimatType.B_Loop, DisplayPinch_loop); + } + else + { + Main.DisplayCEndtoNomal("pinch"); + } + } +} diff --git a/VPet-Simulator.Windows/MutiPlayer/MPMOD.cs b/VPet-Simulator.Windows/MutiPlayer/MPMOD.cs new file mode 100644 index 0000000..6a170a3 --- /dev/null +++ b/VPet-Simulator.Windows/MutiPlayer/MPMOD.cs @@ -0,0 +1,129 @@ +using LinePutScript.Converter; +using LinePutScript.Dictionary; +using LinePutScript.Localization.WPF; +using LinePutScript; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; +using VPet_Simulator.Core; +using VPet_Simulator.Windows.Interface; + +namespace VPet_Simulator.Windows; +public class MPMOD +{ + public static void LoadImage(MPFriends mw, DirectoryInfo di, string pre = "") + { + //加载其他放在文件夹的图片 + foreach (FileInfo fi in di.EnumerateFiles("*.png")) + { + mw.ImageSources.AddSource(pre + fi.Name.ToLower().Substring(0, fi.Name.Length - 4), fi.FullName); + } + //加载其他放在文件夹中文件夹的图片 + foreach (DirectoryInfo fordi in di.EnumerateDirectories()) + { + LoadImage(mw, fordi, pre + fordi.Name + "_"); + } + //加载标志好的图片和图片设置 + foreach (FileInfo fi in di.EnumerateFiles("*.lps")) + { + var tmp = new LpsDocument(File.ReadAllText(fi.FullName)); + if (fi.Name.ToLower().StartsWith("set_")) + foreach (var line in tmp) + mw.ImageSources.ImageSetting.AddorReplaceLine(line); + else + mw.ImageSources.AddImages(tmp, di.FullName); + } + } + public string Name { get; set; } + public MPMOD(DirectoryInfo directory, MPFriends mw) + { +#if !DEBUG + try + { +#endif + var Path = directory; + LpsDocument modlps = new LpsDocument(File.ReadAllText(directory.FullName + @"\info.lps")); + Name = modlps.FindLine("vupmod").Info; + + //MOD未加载时支持翻译 + foreach (var line in modlps.FindAllLine("lang")) + { + List ls = new List(); + foreach (var sub in line) + { + ls.Add(new Line(sub.Name, sub.info)); + } + LocalizeCore.AddCulture(line.info, ls); + } + if (!IsOnMOD(mw)) + { + return; + } + + foreach (DirectoryInfo di in Path.EnumerateDirectories()) + { + switch (di.Name.ToLower()) + { + case "pet": + //宠物模型 + foreach (FileInfo fi in di.EnumerateFiles("*.lps")) + { + LpsDocument lps = new LpsDocument(File.ReadAllText(fi.FullName)); + if (lps.First().Name.ToLower() == "pet") + { + var name = lps.First().Info; + var p = mw.Pets.FirstOrDefault(x => x.Name == name); + if (p == null) + { + p = new PetLoader(lps, di); + mw.Pets.Add(p); + } + else + { + var dis = new DirectoryInfo(di.FullName + "\\" + lps.First()["path"].Info); + p.path.Add(di.FullName + "\\" + lps.First()["path"].Info); + p.Config.Set(lps); + } + } + } + break; + case "food": + foreach (FileInfo fi in di.EnumerateFiles("*.lps")) + { + var tmp = new LpsDocument(File.ReadAllText(fi.FullName)); + foreach (ILine li in tmp) + { + if (li.Name != "food") + continue; + string tmps = li.Find("name").info; + mw.Foods.RemoveAll(x => x.Name == tmps); + mw.Foods.Add(LPSConvert.DeserializeObject(li)); + } + } + break; + case "image": + LoadImage(mw, di); + break; + case "lang": + foreach (FileInfo fi in di.EnumerateFiles("*.lps")) + { + LocalizeCore.AddCulture(fi.Name.Substring(0, fi.Name.Length - fi.Extension.Length), new LPS_D(File.ReadAllText(fi.FullName))); + } + foreach (DirectoryInfo dis in di.EnumerateDirectories()) + { + foreach (FileInfo fi in dis.EnumerateFiles("*.lps")) + { + LocalizeCore.AddCulture(dis.Name, new LPS_D(File.ReadAllText(fi.FullName))); + } + } + break; + } + } + } + public bool IsOnMOD(MPFriends mw) => mw.IsOnMod(Name); +} \ No newline at end of file diff --git a/VPet-Simulator.Windows/MutiPlayer/MPUserControl.xaml b/VPet-Simulator.Windows/MutiPlayer/MPUserControl.xaml new file mode 100644 index 0000000..b4c8ebb --- /dev/null +++ b/VPet-Simulator.Windows/MutiPlayer/MPUserControl.xaml @@ -0,0 +1,11 @@ + + + + + diff --git a/VPet-Simulator.Windows/MWFriends.xaml.cs b/VPet-Simulator.Windows/MutiPlayer/MPUserControl.xaml.cs similarity index 72% rename from VPet-Simulator.Windows/MWFriends.xaml.cs rename to VPet-Simulator.Windows/MutiPlayer/MPUserControl.xaml.cs index ca0d782..23e6da4 100644 --- a/VPet-Simulator.Windows/MWFriends.xaml.cs +++ b/VPet-Simulator.Windows/MutiPlayer/MPUserControl.xaml.cs @@ -1,5 +1,4 @@ -using Panuon.WPF.UI; -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -11,16 +10,16 @@ using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; +using System.Windows.Navigation; using System.Windows.Shapes; namespace VPet_Simulator.Windows; /// -/// MWFriends.xaml 的交互逻辑 +/// MPUserControl.xaml 的交互逻辑 /// -public partial class MWFriends : WindowX +public partial class MPUserControl : UserControl { - - public MWFriends() + public MPUserControl() { InitializeComponent(); } diff --git a/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml b/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml new file mode 100644 index 0000000..2d40a65 --- /dev/null +++ b/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml @@ -0,0 +1,41 @@ + + + + + + + : + : + + + + + + + + + + + + + + diff --git a/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs b/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs new file mode 100644 index 0000000..5357465 --- /dev/null +++ b/VPet-Simulator.Windows/MutiPlayer/winMutiPlayer.xaml.cs @@ -0,0 +1,161 @@ +using LinePutScript; +using LinePutScript.Localization.WPF; +using Panuon.WPF.UI; +using Steamworks; +using Steamworks.Data; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace VPet_Simulator.Windows; +/// +/// winMutiPlayer.xaml 的交互逻辑 +/// +public partial class winMutiPlayer : Window +{ + Steamworks.Data.Lobby lb; + MainWindow mw; + /// + /// 好友宠物模块 + /// + List mFriends = new List(); + public winMutiPlayer(MainWindow mw, ulong? lobbyid = null) + { + InitializeComponent(); + this.mw = mw; + if (lobbyid == null) + CreateLobby(); + else + JoinLobby(lobbyid); + } + public async void JoinLobby(ulong? lobbyid) + { + lb = (await SteamMatchmaking.JoinLobbyAsync((SteamId)lobbyid)).Value; + ShowLobbyInfo(); + } + public async void CreateLobby() + { + lb = (await SteamMatchmaking.CreateLobbyAsync()).Value; + lb.SetJoinable(true); + lb.SetPublic(); + swAllowJoin.Visibility = Visibility.Visible; + ShowLobbyInfo(); + } + public static BitmapFrame ConvertToImageSource(Steamworks.Data.Image image) + { + int stride = (int)((image.Width * 32 + 7) / 8); // 32 bits per pixel + // Convert RGBA to BGRA + for (int i = 0; i < image.Data.Length; i += 4) + { + byte r = image.Data[i]; + image.Data[i] = image.Data[i + 2]; + image.Data[i + 2] = r; + } + var bitmap = BitmapSource.Create( + (int)image.Width, + (int)image.Height, + 96, 96, // dpi x, dpi y + PixelFormats.Bgra32, // Pixel format + null, // Bitmap palette + image.Data, // Pixel data + stride // Stride + ); + + // Convert to ImageSource + var stream = new MemoryStream(); + var encoder = new PngBitmapEncoder(); // or use another encoder if you want + encoder.Frames.Add(BitmapFrame.Create(bitmap)); + encoder.Save(stream); + stream.Seek(0, SeekOrigin.Begin); + + BitmapFrame result = BitmapFrame.Create(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); + return result; + } + public async void ShowLobbyInfo() + { + lb.SetMemberData("save", mw.GameSavesData.GameSave.ToLine().ToString()); + lb.SetMemberData("onmod", mw.Set.FindLine("onmod").ToString()); + lb.SetMemberData("petgraph", mw.Set.PetGraph); + + SteamMatchmaking.OnLobbyDataChanged += SteamMatchmaking_OnLobbyDataChanged; + SteamMatchmaking.OnLobbyMemberDataChanged += SteamMatchmaking_OnLobbyMemberDataChanged; + SteamMatchmaking.OnLobbyMemberJoined += SteamMatchmaking_OnLobbyMemberJoined; + hostName.Text = lb.Owner.Name; + lbLid.Text = lb.Id.Value.ToString("x"); + Steamworks.Data.Image? img = (await lb.Owner.GetMediumAvatarAsync()); + if (img.HasValue) + { + HostHead.Source = ConvertToImageSource(img.Value); + } + else + { + HostHead.Source = new BitmapImage(new Uri("pack://application:,,,/Res/vpeticon.png")); + } + } + + private void SteamMatchmaking_OnLobbyMemberJoined(Lobby lobby, Friend friend) + { + if (lobby.Id == lb.Id) + { + + } + } + + private void SteamMatchmaking_OnLobbyMemberDataChanged(Lobby lobby, Friend friend) + { + if (lobby.Id == lb.Id) + { + + } + } + + private void SteamMatchmaking_OnLobbyDataChanged(Lobby lobby) + { + if (lobby.Id == lb.Id) + { + + } + } + + private void Window_Closed(object sender, EventArgs e) + { + SteamMatchmaking.OnLobbyDataChanged -= SteamMatchmaking_OnLobbyDataChanged; + SteamMatchmaking.OnLobbyMemberDataChanged -= SteamMatchmaking_OnLobbyMemberDataChanged; + lb.SetMemberData("leave", DateTime.Now.ToString()); + lb.Leave(); + foreach (var item in mFriends) + { + item.Close(); + } + mw.winMutiPlayer = null; + } + + private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) + { + if (MessageBoxX.Show("确定要关闭访客表吗?".Translate(), "离开游戏", MessageBoxButton.YesNo) != MessageBoxResult.Yes) + { + e.Cancel = true; + } + } + + private void swAllowJoin_Checked(object sender, RoutedEventArgs e) + { + lb.SetJoinable(true); + } + + private void swAllowJoin_Unchecked(object sender, RoutedEventArgs e) + { + lb.SetJoinable(false); + } +} diff --git a/VPet-Simulator.Windows/WinDesign/winMutiPlayer.xaml b/VPet-Simulator.Windows/WinDesign/winMutiPlayer.xaml deleted file mode 100644 index e0bdda9..0000000 --- a/VPet-Simulator.Windows/WinDesign/winMutiPlayer.xaml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - : - - - - diff --git a/VPet-Simulator.Windows/WinDesign/winMutiPlayer.xaml.cs b/VPet-Simulator.Windows/WinDesign/winMutiPlayer.xaml.cs deleted file mode 100644 index 3523d96..0000000 --- a/VPet-Simulator.Windows/WinDesign/winMutiPlayer.xaml.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Steamworks; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Documents; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Media.Imaging; -using System.Windows.Shapes; - -namespace VPet_Simulator.Windows.WinDesign; -/// -/// winMutiPlayer.xaml 的交互逻辑 -/// -public partial class winMutiPlayer : Window -{ - Steamworks.Data.Lobby lb; - MainWindow mw; - public winMutiPlayer(MainWindow mw, ulong? lobbyid = null) - { - InitializeComponent(); - this.mw = mw; - if (lobbyid == null) - CreateLobby(); - else - JoinLobby(lobbyid); - } - public async void JoinLobby(ulong? lobbyid) - { - lb = (await SteamMatchmaking.JoinLobbyAsync((SteamId)lobbyid)).Value; - } - public async void CreateLobby() - { - lb = (await SteamMatchmaking.CreateLobbyAsync()).Value; - lb.SetJoinable(true); - lb.SetPublic(); - - } - public void ShowLobbyInfo() - { - hostName.Text = lb.Owner.Name; - } - - private void Window_Closed(object sender, EventArgs e) - { - lb.Leave(); - mw.winMutiPlayer = null; - } -}