Pārlūkot izejas kodu

1.用户头像切换到本地缓存
2.修复多工作区切换,页面不变的问题
3.WXContact切换到ObservableCollection
4.群聊名称支持

Suxue 1 gadu atpakaļ
vecāks
revīzija
191849e9c2

+ 7 - 3
Analyse.xaml.cs

@@ -31,10 +31,14 @@ namespace WechatPCMsgBakTool
 
         private void btn_analyse_Click(object sender, RoutedEventArgs e)
         {
-            List<WXContact>? contacts = UserReader.GetWXContacts();
-            List<WXMsgGroup> list = UserReader.GetWXMsgGroup().OrderByDescending(x => x.MsgCount).ToList();
-            if(contacts == null)
+            var tmp = UserReader.GetWXContacts();
+            List<WXContact> contacts;
+            if (tmp == null)
                 contacts = new List<WXContact>();
+            else
+                contacts = tmp.ToList();
+            
+            List<WXMsgGroup> list = UserReader.GetWXMsgGroup().OrderByDescending(x => x.MsgCount).ToList();
 
             foreach (WXMsgGroup item in list)
             {

+ 1 - 1
App.xaml

@@ -2,7 +2,7 @@
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
              xmlns:local="clr-namespace:WechatPCMsgBakTool"
-             StartupUri="Main.xaml">
+             StartupUri="Main2.xaml">
     <Application.Resources>
          
     </Application.Resources>

+ 1 - 1
Main2.xaml

@@ -125,7 +125,7 @@
         <Grid Width="230" Background="#2775b6" HorizontalAlignment="Left" IsHitTestVisible="True">
             <ListView BorderThickness="0" Background="Transparent" Margin="0,0,0,85" Name="list_workspace" ItemTemplate="{DynamicResource ListViewItemContentTemplate}" SelectionChanged="list_workspace_SelectionChanged"/>
             <Grid Name="new_workspace" Width="170" Height="40" VerticalAlignment="Bottom" Margin="30,45" IsHitTestVisible="True">
-                <Rectangle Name="new_workspace_fill" Fill="Transparent"  RadiusX="0" RadiusY="0" Stroke="White" StrokeDashArray="5" >
+                <Rectangle Name="new_workspace_fill" Fill="Transparent"  RadiusX="0" RadiusY="0" Stroke="White" StrokeDashArray="5" MouseDown="new_workspace_fill_MouseDown">
                     <Rectangle.Triggers>
                         <EventTrigger RoutedEvent="Rectangle.MouseEnter">
                             <BeginStoryboard>

+ 6 - 1
Main2.xaml.cs

@@ -75,7 +75,7 @@ namespace WechatPCMsgBakTool
             if(config != null)
             {
                 CurrentUserBakConfig = config;
-                MainFrame.Navigate(new Uri("pack://application:,,,/Pages/Workspace.xaml"));
+                MainFrame.Navigate(new Uri("pack://application:,,,/Pages/Workspace.xaml?datatime=" + DateTime.Now.Ticks));
             }
             else
             {
@@ -83,5 +83,10 @@ namespace WechatPCMsgBakTool
                 return;
             }
         }
+
+        private void new_workspace_fill_MouseDown(object sender, MouseButtonEventArgs e)
+        {
+            MainFrame.Navigate(new Uri("pack://application:,,,/Pages/CreateWork.xaml?datatime=" + DateTime.Now.Ticks));
+        }
     }
 }

+ 14 - 2
Model/WXModel.cs

@@ -5,6 +5,8 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.ComponentModel;
+using System.Drawing;
+using System.Windows.Media.Imaging;
 
 namespace WechatPCMsgBakTool.Model
 {
@@ -41,6 +43,14 @@ namespace WechatPCMsgBakTool.Model
         public string NickName { get; set; } = "";
     }
 
+    [Table("ContactHeadImg1")]
+    public class ContactHeadImg
+    {
+        public string usrName { get; set; } = "";
+        public int createTime { get; set; }
+        public byte[]? smallHeadBuf { get; set; }
+    }
+
     public class WXUserInfo
     {
         public string UserName { get; set; } = "";
@@ -121,6 +131,7 @@ namespace WechatPCMsgBakTool.Model
         public byte[]? CompressContent { get; set; }
         [Column("BytesExtra")]
         public byte[]? BytesExtra { get; set; }
+        public string NickName { get; set; } = "";
     }
 
     [Table("ChatRoom")]
@@ -158,8 +169,9 @@ namespace WechatPCMsgBakTool.Model
         public string LastMsg { get; set; } = "";
         [Column("ExtraBuf")]
         public byte[]? ExtraBuf { get; set; }
-        [Column("smallHeadImgUrl")]
-        public string Avatar { get; set; } = "";
+        public BitmapImage? Avatar { get; set; }
+        [Column("Remark")]
+        public string Remark { get; set; } = "";
     }
 
     [Table("ContactHeadImgUrl")]

+ 15 - 0
Pages/CreateWork.xaml

@@ -0,0 +1,15 @@
+<Page x:Class="WechatPCMsgBakTool.Pages.CreateWork"
+      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+      xmlns:local="clr-namespace:WechatPCMsgBakTool.Pages"
+      mc:Ignorable="d" 
+      d:DesignHeight="450" d:DesignWidth="800"
+      Title="Welcome" Background="White">
+
+    <Grid>
+        <Label FontSize="20" Margin="30,15" Content="新建工作区" HorizontalAlignment="Left" VerticalAlignment="Top" />
+        
+    </Grid>
+</Page>

+ 28 - 0
Pages/CreateWork.xaml.cs

@@ -0,0 +1,28 @@
+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.Navigation;
+using System.Windows.Shapes;
+
+namespace WechatPCMsgBakTool.Pages
+{
+    /// <summary>
+    /// CreateWork.xaml 的交互逻辑
+    /// </summary>
+    public partial class CreateWork : Page
+    {
+        public CreateWork()
+        {
+            InitializeComponent();
+        }
+    }
+}

+ 7 - 8
Pages/Workspace.xaml

@@ -51,8 +51,10 @@
         </DataTemplate>
         <DataTemplate x:Key="MsgText">
             <Grid Margin="0">
-                <Label Margin="60,8,0,0" FontWeight="Bold" VerticalAlignment="Top" HorizontalAlignment="Left" Content="{Binding NickName}" Width="130"/>
-                <Label Margin="60,25,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="140" Content="{Binding LastMsg}"/>
+                <Label Margin="60,8,0,0" FontWeight="Bold" VerticalAlignment="Top" Content="{Binding NickName}"/>
+                <Label Margin="60,25,0,8" VerticalAlignment="Top" HorizontalAlignment="Left" Width="380">
+                    <TextBlock Text="{Binding StrContent}" TextWrapping="Wrap"  />
+                </Label>
             </Grid>
         </DataTemplate>
         <DataTemplate x:Key="MsgImage">
@@ -124,12 +126,9 @@
                 </Style>
             </ListView.Resources>
         </ListView>
-        <Label Content="{Binding WXContact.UserName}" HorizontalAlignment="Left" Margin="258,21,0,0" VerticalAlignment="Top"/>
-        <ListView x:Name="list_msg" Margin="230,60,0,0" Background="Aqua" BorderThickness="0">
-            <Grid Margin="0">
-                <Label Margin="0,8,0,0" FontWeight="Bold" VerticalAlignment="Top" Content="溯雪" Width="130"/>
-                <Label Margin="60,25,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="140" Content="{Binding LastMsg}"/>
-            </Grid>
+        <Label Content="{Binding WXContact.NickName}" HorizontalAlignment="Left" Margin="258,21,0,0" VerticalAlignment="Top"/>
+        <ListView x:Name="list_msg" Margin="230,60,0,0" Background="Transparent" BorderThickness="0" ItemTemplate="{DynamicResource MsgText}">
+            
         </ListView>
     </Grid>
 </Page>

+ 2 - 1
Pages/Workspace.xaml.cs

@@ -3,6 +3,7 @@ using System.Collections;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Diagnostics;
+using System.IO;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -60,7 +61,7 @@ namespace WechatPCMsgBakTool.Pages
                 return;
             }
             List<WXMsg>? msgs = UserReader.GetWXMsgs(ViewModel.WXContact.UserName);
-            ListViewItem i = new ListViewItem();
+            list_msg.ItemsSource = msgs;
         }
 
         private void txt_find_user_TextChanged(object sender, TextChangedEventArgs e)

+ 1 - 0
README.md

@@ -54,3 +54,4 @@
 ##### [kn007/silk-v3-decoder](https://github.com/kn007/silk-v3-decoder)
 ##### [吾爱破解chenhahacjl/微信 DAT 图片解密 (C#)](https://www.52pojie.cn/forum.php?mod=viewthread&tid=1507922)
 ##### [huiyadanli/RevokeMsgPatcher](https://github.com/huiyadanli/RevokeMsgPatcher)
+##### [FuzzySecurity/Sharp-Suite](https://github.com/FuzzySecurity/Sharp-Suite)

+ 2 - 1
ViewModel/WorkspaceViewModel.cs

@@ -1,6 +1,7 @@
 using CommunityToolkit.Mvvm.ComponentModel;
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -14,7 +15,7 @@ namespace WechatPCMsgBakTool.ViewModel
         public WXContact? wXContact;
 
         [ObservableProperty]
-        public List<WXContact>? contacts;
+        public ObservableCollection<WXContact>? contacts;
 
         private string searchString = "";
         public string SearchString

+ 134 - 6
WXUserReader.cs

@@ -1,13 +1,19 @@
-using SQLite;
+using K4os.Compression.LZ4.Encoders;
+using K4os.Compression.LZ4;
+using SQLite;
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.IO;
 using System.Linq;
+using System.Net.Mime;
 using System.Security.Cryptography;
 using System.Text;
 using System.Threading.Tasks;
 using System.Windows.Interop;
+using System.Windows.Media.Imaging;
+using System.Xml;
 using System.Xml.Linq;
 using WechatPCMsgBakTool.Helpers;
 using WechatPCMsgBakTool.Model;
@@ -18,10 +24,13 @@ namespace WechatPCMsgBakTool
     {
         private Dictionary<string, SQLiteConnection> DBInfo = new Dictionary<string, SQLiteConnection>();
         private UserBakConfig? UserBakConfig = null;
+        private Hashtable HeadImgCache = new Hashtable();
+        private Hashtable UserNameCache = new Hashtable();
         public WXUserReader(UserBakConfig userBakConfig) {
             string path = Path.Combine(userBakConfig.UserWorkspacePath, "DecDB");
             UserBakConfig = userBakConfig;
             LoadDB(path);
+            InitCache();
         }
 
         public void LoadDB(string path)
@@ -38,27 +47,87 @@ namespace WechatPCMsgBakTool
             }
         }
 
-        public List<WXContact>? GetWXContacts(string? name = null)
+        public void InitCache()
+        {
+            SQLiteConnection con = DBInfo["Misc"];
+            if (con == null)
+                return;
+
+            string query = @"SELECT * FROM ContactHeadImg1";
+            List<ContactHeadImg> imgs = con.Query<ContactHeadImg>(query);
+            foreach(ContactHeadImg item in imgs)
+            {
+                if (!HeadImgCache.ContainsKey(item.usrName))
+                {
+                    HeadImgCache.Add(item.usrName, item);
+                }
+            }
+
+            List<WXContact> contacts = GetWXContacts(null, true).ToList();
+            foreach(WXContact contact in contacts)
+            {
+                if (!UserNameCache.ContainsKey(contact.UserName))
+                    UserNameCache.Add(contact.UserName, contact);
+            }
+        }
+        public byte[]? GetHeadImgCahce(string username)
+        {
+            if (HeadImgCache.ContainsKey(username))
+            {
+                ContactHeadImg? img = HeadImgCache[username] as ContactHeadImg;
+                if (img == null)
+                    return null;
+                else
+                    return img.smallHeadBuf;
+            }
+            return null;
+        }
+        public ObservableCollection<WXContact> GetWXContacts(string? name = null,bool all = false)
         {
             SQLiteConnection con = DBInfo["MicroMsg"];
             if (con == null)
-                return null;
+                return new ObservableCollection<WXContact>();
             string query = @"select contact.*,session.strContent,contactHeadImgUrl.smallHeadImgUrl,contactHeadImgUrl.bigHeadImgUrl from contact 
             left join session on session.strUsrName = contact.username
             left join contactHeadImgUrl on contactHeadImgUrl.usrName = contact.username
             where type != 4 {searchName}
             order by nOrder desc";
-            
+
+            if (all)
+            {
+                query = query.Replace("where type != 4 ", "");
+            }
+
+            List<WXContact>? contacts = null;
             if (name != null)
             {
                 query = query.Replace("{searchName}", " and (username like ? or alias like ? or nickname like ? or remark like ?)");
-                return con.Query<WXContact>(query, $"%{name}%", $"%{name}%", $"%{name}%", $"%{name}%");
+                contacts = con.Query<WXContact>(query, $"%{name}%", $"%{name}%", $"%{name}%", $"%{name}%");
             }
             else
             {
                 query = query.Replace("{searchName}", "");
-                return con.Query<WXContact>(query);
+                contacts = con.Query<WXContact>(query);
             }
+
+            foreach (WXContact contact in contacts)
+            {
+                byte[]? imgBytes = GetHeadImgCahce(contact.UserName);
+                if (imgBytes != null)
+                {
+                    MemoryStream stream = new MemoryStream(imgBytes);
+                    BitmapImage bitmapImage = new BitmapImage();
+                    bitmapImage.BeginInit();
+                    bitmapImage.CreateOptions = BitmapCreateOptions.IgnoreColorProfile;
+                    bitmapImage.StreamSource = stream;
+                    bitmapImage.EndInit();
+                    contact.Avatar = bitmapImage;
+                }
+                else
+                    continue;
+            }
+
+            return new ObservableCollection<WXContact>(contacts);
         }
 
         public List<WXUserImg>? GetUserImgs()
@@ -108,6 +177,65 @@ namespace WechatPCMsgBakTool
 
                     foreach (WXMsg w in wXMsgs)
                     {
+                        if (UserNameCache.ContainsKey(w.StrTalker))
+                        {
+                            WXContact? contact = UserNameCache[w.StrTalker] as WXContact;
+                            if (contact != null)
+                            {
+                                if (contact.Remark != null)
+                                    w.NickName = contact.Remark;
+                                else
+                                    w.NickName = contact.NickName;
+                            }
+                        }
+
+                        if (uid.Contains("@chatroom"))
+                        {
+                            string userId = "";
+
+                            if (w.BytesExtra == null)
+                                continue;
+
+                            string talkId = Encoding.UTF8.GetString(w.BytesExtra!);
+                            if (!w.IsSender)
+                            {
+                                if (w.BytesExtra[0] == 26)
+                                {
+                                    int usrLength = w.BytesExtra[1];
+                                    userId = Encoding.UTF8.GetString(w.BytesExtra.Skip(6).Take(usrLength - 4).ToArray());
+                                }
+                                if (w.BytesExtra[0] == 10)
+                                {
+                                    int version = w.BytesExtra[10];
+                                    if (version == 16)
+                                    {
+                                        int usrLength = w.BytesExtra[13];
+                                        userId = Encoding.UTF8.GetString(w.BytesExtra.Skip(18).Take(usrLength - 4).ToArray());
+                                    }
+                                    else if (version == 18)
+                                    {
+                                        int usrLength = w.BytesExtra[7];
+                                        userId = Encoding.UTF8.GetString(w.BytesExtra.Skip(12).Take(usrLength - 4).ToArray());
+                                    }
+                                }
+                                
+                                if(UserNameCache.ContainsKey(userId))
+                                {
+                                    WXContact? contact = UserNameCache[userId] as WXContact;
+                                    if (contact != null)
+                                        w.NickName = contact.Remark == "" ? contact.NickName : contact.Remark;
+                                }
+                                else
+                                {
+
+                                }
+                            }
+                            else
+                            {
+                                w.NickName = "我";
+                            }
+                        }
+                        
                         tmp.Add(w);
                     }
                 }