联机功能实装: 聊天&动画同步

This commit is contained in:
ZouJin 2024-03-18 21:34:41 +08:00
parent 6ffbe4f632
commit 7fd2f74740
10 changed files with 244 additions and 32 deletions

View File

@ -109,7 +109,7 @@
<Menu Width="500" VerticalAlignment="Bottom" pu:MenuHelper.SubmenuItemsHorizontalContentAlignment="Center"
pu:MenuHelper.TopLevelItemsHorizontalContentAlignment="Center"
Style="{DynamicResource ToolBarMenuStyle}" ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Disabled" pu:DropDownHelper.Width="NaN"
pu:DropDownHelper.MaxHeight="500" Height="60">
<Menu.ItemsPanel>
<ItemsPanelTemplate>

View File

@ -26,7 +26,7 @@
<PackageReference Include="LinePutScript" Version="1.11.5" />
<PackageReference Include="LinePutScript.Localization.WPF" Version="1.0.6" />
<PackageReference Include="Panuon.WPF" Version="1.1.0" />
<PackageReference Include="Panuon.WPF.UI" Version="1.2.0.4" />
<PackageReference Include="Panuon.WPF.UI" Version="1.2.1" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">

View File

@ -5,6 +5,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Interop;
using VPet_Simulator.Core;
namespace VPet_Simulator.Windows.Interface;
@ -23,9 +25,9 @@ public struct MPMessage
/// </summary>
Empty,
/// <summary>
/// 聊天消息 (string)
/// 聊天消息 (chat)
/// </summary>
Message,
Chat,
/// <summary>
/// 显示动画 (graphinfo)
/// </summary>
@ -51,7 +53,7 @@ public struct MPMessage
/// <summary>
/// 消息内容
/// </summary>
[Line] public string Content { get; set; }
[Line] private string Content { get; set; }
/// <summary>
/// 被操作者 (显示动画用)
/// </summary>
@ -59,4 +61,49 @@ public struct MPMessage
public static byte[] ConverTo(MPMessage data) => Encoding.UTF8.GetBytes(LPSConvert.SerializeObject(data).ToString());
public static MPMessage ConverTo(byte[] data) => LPSConvert.DeserializeObject<MPMessage>(new LPS(Encoding.UTF8.GetString(data)));
public void SetContent(object content)
{
Content = LPSConvert.GetObjectString(content, convertNoneLineAttribute: true);
}
public T GetContent<T>()
{
return (T)LPSConvert.GetStringObject(Content, typeof(T), convertNoneLineAttribute: true);
}
/// <summary>
/// 聊天结构
/// </summary>
public struct Chat
{
/// <summary>
/// 聊天内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 消息类型
/// </summary>
public enum Type
{
/// <summary>
/// 私有
/// </summary>
Private,
/// <summary>
/// 半公开
/// </summary>
Internal,
/// <summary>
/// 公开
/// </summary>
Public
}
/// <summary>
/// 聊天类型
/// </summary>
public Type ChatType { get; set; }
/// <summary>
/// 发送者名字
/// </summary>
public string SendName { get; set; }
}
}

View File

@ -6,7 +6,7 @@
xmlns:ll="clr-namespace:LinePutScript.Localization.WPF;assembly=LinePutScript.Localization.WPF" mc:Ignorable="d"
xmlns:pu="clr-namespace:Panuon.WPF.UI;assembly=Panuon.WPF.UI" Height="500" Width="500" VerticalAlignment="Top">
<Border Background="{DynamicResource PrimaryLighter}" BorderBrush="{DynamicResource Primary}" BorderThickness="5"
VerticalAlignment="Top" Margin="5,50,5,5" CornerRadius="5" Padding="5,5,5,3">
VerticalAlignment="Top" Margin="5" CornerRadius="5" Padding="5,5,5,3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*" />

View File

@ -19,6 +19,6 @@
<PackageReference Include="LinePutScript" Version="1.11.5" />
<PackageReference Include="LinePutScript.Localization.WPF" Version="1.0.6" />
<PackageReference Include="Panuon.WPF" Version="1.1.0" />
<PackageReference Include="Panuon.WPF.UI" Version="1.2.0.4" />
<PackageReference Include="Panuon.WPF.UI" Version="1.2.1" />
</ItemGroup>
</Project>

View File

@ -10,6 +10,30 @@
<WindowChrome GlassFrameThickness="-1" />
</WindowChrome.WindowChrome>
<Grid x:Name="MGHost" x:FieldModifier="public">
<Grid x:Name="HideForDesign" Visibility="Collapsed" d:Visibility="Visible">
<Border x:Name="MPTalkBox" Background="{DynamicResource PrimaryLighter}"
BorderBrush="{DynamicResource Primary}" BorderThickness="5" VerticalAlignment="Top"
Margin="5,50,5,5" CornerRadius="5" Padding="5,5,5,3">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="4*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<ComboBox x:Name="cbTalk" Style="{DynamicResource StandardComboBoxStyle}" Height="Auto"
FontSize="30" VerticalAlignment="Center" Grid.Column="0"
SelectionChanged="cbTalk_SelectionChanged" />
<TextBox x:Name="tbTalk" Style="{DynamicResource StandardTextBoxStyle}" Height="Auto" FontSize="30"
AcceptsReturn="True" TextWrapping="WrapWithOverflow" PreviewKeyDown="tbTalk_KeyDown"
Grid.Column="1" ToolTip="{ll:Str 选择说话对象}" />
<Button pu:ButtonHelper.CornerRadius="4" Content="{ll:Str '发送'}" BorderThickness="2"
Background="{DynamicResource SecondaryLight}" Grid.Column="3"
BorderBrush="{DynamicResource DARKPrimaryDarker}" FontSize="30"
ToolTip="{ll:Str '按 Ctrl+Enter 发送'}" Click="Send_Click" />
</Grid>
</Border>
</Grid>
<Grid x:Name="MGrid" Width="250" Height="Auto" x:FieldModifier="public">
<Label x:Name="LoadingText" HorizontalAlignment="Center" VerticalAlignment="Center"
Background="{DynamicResource DARKPrimaryLight}" Foreground="{DynamicResource DARKPrimaryText}"

View File

@ -23,6 +23,8 @@ using static VPet_Simulator.Core.GraphInfo;
using System.Xml.Linq;
using System.Windows.Interop;
using LinePutScript.Converter;
using static VPet_Simulator.Windows.Interface.MPMessage;
using System.Windows.Input;
namespace VPet_Simulator.Windows;
/// <summary>
@ -207,11 +209,19 @@ public partial class MPFriends : WindowX
Main.EventTimer.Enabled = false;
//清空资源
//Main.Resources = Application.Current.Resources;
//Main.MsgBar.This.Resources = Application.Current.Resources;
//Main.ToolBar.Resources = Application.Current.Resources;
Main.Resources = Application.Current.Resources;
Main.MsgBar.This.Resources = Application.Current.Resources;
Main.ToolBar.Resources = Application.Current.Resources;
Main.ToolBar.LoadClean();
HideForDesign.Children.Remove(MPTalkBox);
Main.ToolBar.MainGrid.Children.Add(MPTalkBox);
cbTalk.Items.Add("私聊".Translate());
cbTalk.Items.Add("公聊".Translate());
cbTalk.Items.Add("大家".Translate());
cbTalk.SelectedIndex = 1;
LoadingText.Content = "正在加载游戏\n该步骤可能会耗时比较长\n请耐心等待".Translate();
Main.PlayVoiceVolume = mw.Set.VoiceVolume;
@ -240,7 +250,7 @@ public partial class MPFriends : WindowX
Loaded = true;
}));
}
public new bool Loaded = false;
public new bool Loaded = false;
/// <summary>
/// 显示捏脸情况
@ -313,6 +323,29 @@ public partial class MPFriends : WindowX
});
}
/// <summary>
/// 智能化显示后续过度动画
/// </summary>
public void DisplayAuto(GraphInfo gi)
{
switch (gi.Animat)
{
case AnimatType.A_Start:
gi.Animat = AnimatType.B_Loop;
Main.Display(gi.Name, AnimatType.B_Loop, () => DisplayAuto(gi));
break;
case AnimatType.B_Loop:
Main.Display(gi.Name, AnimatType.B_Loop, () => DisplayAuto(gi));
break;
case AnimatType.C_End:
case AnimatType.Single:
Main.DisplayToNomal();
break;
}
}
/// <summary>
/// 根据好友数据显示动画
/// </summary>
public bool DisplayGraph(GraphInfo gi)
{
if (!Loaded || Main.DisplayType.Type == GraphType.StartUP || Main.DisplayType.Type == GraphType.Raised_Dynamic || Main.DisplayType.Type == GraphType.Raised_Static)
@ -327,14 +360,94 @@ public partial class MPFriends : WindowX
var img = Core.Graph.FindGraph(gi.Name, gi.Animat, Core.Save.Mode);
if (img != null)
{
Main.Display(img);
Main.Display(img, () => DisplayAuto(gi));
return true;
}
return false;
}
public void DisplayMessage(Chat msg)
{
switch (msg.ChatType)
{
case Chat.Type.Private:
Main.Say("{0} 悄悄地对你说: {1}".Translate(msg.SendName, msg.Content));
break;
case Chat.Type.Internal:
Main.Say("{0} 对你说: {1}".Translate(msg.SendName, msg.Content));
break;
case Chat.Type.Public:
Main.Say("{0} 对大家说: {1}".Translate(msg.SendName, msg.Content));
break;
}
}
private void WindowX_Closed(object sender, EventArgs e)
{
mw.Windows.Remove(this);
}
private void tbTalk_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter && e.KeyboardDevice.Modifiers.HasFlag(ModifierKeys.Control))
{
Send_Click(sender, e);
e.Handled = true;
Main.ToolBar.Visibility = Visibility.Collapsed;
return;
}
if (tbTalk.Text.Length > 0)
{
Main.ToolBar.CloseTimer.Stop();
}
else
{
Main.ToolBar.CloseTimer.Start();
}
}
private void Send_Click(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(tbTalk.Text))
{
return;
}
var cont = tbTalk.Text;
tbTalk.Text = "";
Main.ToolBar.Visibility = Visibility.Collapsed;
int talktype = cbTalk.SelectedIndex;
Task.Run(() =>
{
MPMessage msg = new MPMessage();
msg.Type = MSGType.Chat;
msg.SetContent(new Chat() { Content = cont, ChatType = (Chat.Type)talktype, SendName = SteamClient.Name });
msg.To = SteamClient.SteamId;
switch (talktype)
{
case 0:
wmp.SendMessage(friend.Id, msg);
break;
case 1:
wmp.SendMessageALL(msg);
break;
case 2:
wmp.SendMessageALL(msg);
break;
}
});
}
private void cbTalk_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
switch (cbTalk.SelectedIndex)
{
case 0:
Panuon.WPF.UI.TextBoxHelper.SetWatermark(tbTalk, "和{0}悄悄说".Translate(friend.Name));
break;
case 1:
Panuon.WPF.UI.TextBoxHelper.SetWatermark(tbTalk, "和{0}说".Translate(friend.Name));
break;
case 2:
Panuon.WPF.UI.TextBoxHelper.SetWatermark(tbTalk, "和大家说");
break;
}
}
}

View File

@ -22,6 +22,7 @@ using System.Windows.Media.Imaging;
using VPet_Simulator.Core;
using VPet_Simulator.Windows.Interface;
using static VPet_Simulator.Core.GraphInfo;
using static VPet_Simulator.Windows.Interface.MPMessage;
namespace VPet_Simulator.Windows;
/// <summary>
@ -207,10 +208,27 @@ public partial class winMutiPlayer : Window
return;
}
MPMessage msg = new MPMessage();
msg.Type = MPMessage.MSGType.DispayGraph;
msg.Content = LPSConvert.GetObjectString(info, convertNoneLineAttribute: true);
msg.Type = MSGType.DispayGraph;
msg.SetContent(info);
msg.To = SteamClient.SteamId.Value;
byte[] data = MPMessage.ConverTo(msg);
SendMessageALL(msg);
}
/// <summary>
/// 给指定好友发送消息
/// </summary>
/// <param name="mpf"></param>
/// <param name="msg"></param>
public void SendMessage(ulong friendid, MPMessage msg)
{
byte[] data = ConverTo(msg);
SteamNetworking.SendP2PPacket(friendid, data);
}
/// <summary>
/// 给所有人发送消息
/// </summary>
public void SendMessageALL(MPMessage msg)
{
byte[] data = ConverTo(msg);
for (int i = 0; i < MPFriends.Count; i++)
{
MPFriends v = MPFriends[i];
@ -218,6 +236,7 @@ public partial class winMutiPlayer : Window
}
}
private void SteamMatchmaking_OnLobbyMemberJoined(Lobby lobby, Friend friend)
{
if (lobby.Id == lb.Id)
@ -241,33 +260,42 @@ public partial class winMutiPlayer : Window
}
private void LoopP2PPacket()
{
while (SteamNetworking.IsP2PPacketAvailable())
try
{
var packet = SteamNetworking.ReadP2PPacket();
if (packet.HasValue)
while (SteamNetworking.IsP2PPacketAvailable())
{
var From = packet.Value.SteamId;
var test = Encoding.UTF8.GetString(packet.Value.Data);
var MSG = MPMessage.ConverTo(packet.Value.Data);
var TO = MPFriends.Find(x => x.friend.Id == MSG.To);
switch (MSG.Type)
var packet = SteamNetworking.ReadP2PPacket();
if (packet.HasValue)
{
case MPMessage.MSGType.DispayGraph:
TO.DisplayGraph((GraphInfo)LPSConvert.GetStringObject(MSG.Content, typeof(GraphInfo), convertNoneLineAttribute: true));
break;
var From = packet.Value.SteamId;
var MSG = ConverTo(packet.Value.Data);
var To = MPFriends.Find(x => x.friend.Id == MSG.To);
switch (MSG.Type)
{
case MSGType.DispayGraph:
To.DisplayGraph(MSG.GetContent<GraphInfo>());
break;
case MSGType.Chat:
To.DisplayMessage(MSG.GetContent<Chat>());
break;
}
}
Thread.Sleep(100);
}
Thread.Sleep(100);
Thread.Sleep(1000);
if (isOPEN)
LoopP2PPacket();
}
Thread.Sleep(1000);
if (isOPEN)
LoopP2PPacket();
catch
{
}
}
private void Window_Closed(object sender, EventArgs e)
{
SteamMatchmaking.OnLobbyDataChanged -= SteamMatchmaking_OnLobbyDataChanged;
mw.Main.GraphDisplayHandler -= Main_GraphDisplayHandler;
SteamMatchmaking.OnLobbyMemberJoined -= SteamMatchmaking_OnLobbyMemberJoined;
lb.Leave();
for (int i = 0; i < MPFriends.Count; i++)
{

View File

@ -219,7 +219,7 @@
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="NAudio" Version="2.2.1" />
<PackageReference Include="Panuon.WPF" Version="1.1.0" />
<PackageReference Include="Panuon.WPF.UI" Version="1.2.0.4" />
<PackageReference Include="Panuon.WPF.UI" Version="1.2.1" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\VPet-Simulator.Core\VPet-Simulator.Core.csproj" />

View File

@ -24,7 +24,7 @@
<PackageReference Include="LinePutScript.Localization.WPF" Version="1.0.6" />
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
<PackageReference Include="Panuon.WPF" Version="1.1.0" />
<PackageReference Include="Panuon.WPF.UI" Version="1.2.0.4" />
<PackageReference Include="Panuon.WPF.UI" Version="1.2.1" />
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
</ItemGroup>
</Project>