Exemple #1
0
        private void CachePost(SignedData signedHeader, PostHeader header)
        {
            if (Core.InvokeRequired)
                Debug.Assert(false);

            if (header.ParentID == 0 && header.SourceID != header.TargetID)
            {
                Network.UpdateLog("Board", "Post made to board other than source's");
                return;
            }

            if (!File.Exists(GetPostPath(header)))
            {
                DownloadPost(signedHeader, header);
                return;
            }

            // check if current version loaded
            OpPost post = GetPost(header);

            if (post != null && post.Header.Version >= header.Version )
            {
                UpdateGui(post);
                return;
            }

            // put into map
            OpBoard board = GetBoard(header.TargetID);

            if (board == null)
            {
                board = new OpBoard(header.Target);
                BoardMap.SafeAdd(header.TargetID, board);
            }

            PostUID uid = new PostUID(header);

            post = new OpPost();
            post.Header = header;
            post.SignedHeader = signedHeader.Encode(Network.Protocol);
            post.Ident = header.TargetID.GetHashCode() ^ uid.GetHashCode();
            post.Unique = Loading;

            // remove previous version of file, if its different
            OpPost prevPost = board.GetPost(uid);

            if (prevPost != null && GetPostPath(prevPost.Header) != GetPostPath(header))
                try { File.Delete(GetPostPath(prevPost.Header)); }
                catch { }

            board.Posts.SafeAdd(uid,  post);

            // update replies
            if (post.Header.ParentID == 0)
                board.UpdateReplies(post);
            else
            {
                PostUID parentUid = new PostUID(board.UserID, post.Header.ProjectID, post.Header.ParentID);
                OpPost parentPost = board.GetPost(parentUid);

                if (parentPost != null)
                {
                    board.UpdateReplies(parentPost);
                    UpdateGui(post);
                }
            }

            lock (SaveHeaders)
                if (!SaveHeaders.Contains(header.TargetID))
                    SaveHeaders.Add(header.TargetID);

            ushort replies = 0;
            if (SavedReplyCount.SafeTryGetValue(post.Ident, out replies))
            {
                post.Replies = replies;
                SavedReplyCount.SafeRemove(post.Ident);
            }

            UpdateGui(post);

            if (Core.NewsWorthy(header.TargetID, header.ProjectID, true))
                Core.MakeNews(ServiceIDs.Board, "Board updated by " + Core.GetName(header.SourceID), header.SourceID, 0, false);
        }
Exemple #2
0
        public void PostMessage(ulong user, uint project, uint parent, ScopeType scope, string subject, string message, TextFormat format, string quip, List<AttachedFile> files, OpPost edit)
        {
            // post header
            PostHeader header = new PostHeader();

            header.Source = Core.User.Settings.KeyPublic;
            header.SourceID = Core.UserID;

            header.Target = Core.KeyMap[user];
            header.TargetID = user;

            header.ParentID = parent;
            header.ProjectID = project;

            header.Scope = scope;

            if (edit == null)
            {
                header.Time = Core.TimeNow.ToUniversalTime();

                byte[] rnd = new byte[4];
                Core.RndGen.NextBytes(rnd);
                header.PostID = BitConverter.ToUInt32(rnd, 0);
            }
            else
            {
                header.PostID = edit.Header.PostID;
                header.Version = (ushort) (edit.Header.Version + 1);
                header.Time = edit.Header.Time;
                header.EditTime = Core.TimeNow.ToUniversalTime();
            }

            header.FileKey = Utilities.GenerateKey(Core.StrongRndGen, 256);

            // setup temp file
            string tempPath = Core.GetTempPath();
            using (IVCryptoStream stream = IVCryptoStream.Save(tempPath, header.FileKey))
            {
                int written = 0;

                // write post file
                written += Protocol.WriteToFile(new PostInfo(subject, format, quip, Core.RndGen), stream);

                byte[] msgBytes = UTF8Encoding.UTF8.GetBytes(message);
                written += Protocol.WriteToFile(new PostFile("body", msgBytes.Length), stream);

                foreach (AttachedFile attached in files)
                    written += Protocol.WriteToFile(new PostFile(attached.Name, attached.Size), stream);

                stream.WriteByte(0); // end packets
                header.FileStart = (long)written + 1;

                // write files
                stream.Write(msgBytes, 0, msgBytes.Length);

                if (files != null)
                {
                    int buffSize = 4096;
                    byte[] buffer = new byte[buffSize];

                    foreach (AttachedFile attached in files)
                        using (FileStream embed = File.OpenRead(attached.FilePath))
                        {
                            int read = buffSize;
                            while (read == buffSize)
                            {
                                read = embed.Read(buffer, 0, buffSize);
                                stream.Write(buffer, 0, read);
                            }
                        }
                }

                stream.WriteByte(0); // signal last packet

                stream.FlushFinalBlock();
            }

            // finish building header
            Utilities.HashTagFile(tempPath, Network.Protocol, ref header.FileHash, ref header.FileSize);

            string finalPath = GetPostPath(header);
            File.Move(tempPath, finalPath);

            FinishPost(header);
        }
Exemple #3
0
 public void UpdateGui(OpPost post)
 {
     if (PostUpdate != null)
         Core.RunInGuiThread(PostUpdate, post);
 }
Exemple #4
0
        public void LoadThread(OpPost parent)
        {
            OpBoard board = GetBoard(parent.Header.TargetID);

            if (board == null)
                return;

            // have all replies fire an update
            board.Posts.LockReading(delegate()
            {
               foreach (OpPost post in board.Posts.Values)
                   if (post.Header.ProjectID == parent.Header.ProjectID &&
                       post.Header.ParentID == parent.Header.PostID)
                       UpdateGui(post);
            });

            // do search for thread
            ThreadSearch(board.UserID, parent.Header.ProjectID, parent.Header.PostID);
        }
Exemple #5
0
        public void PostEdit(OpPost edit)
        {
            // used for archive/restore
            PostHeader copy = edit.Header.Copy();

            copy.Version++;
            copy.EditTime = Core.TimeNow.ToUniversalTime();

            FinishPost(copy);
        }
Exemple #6
0
        public string GetPostTitle(OpPost post)
        {
            // loads info when first demanded, cached afterwards
            if (post.Info == null)
                try
                {
                    string path = GetPostPath(post.Header);
                    if (!File.Exists(path))
                        return "";

                    post.Attached = new List<PostFile>();

                    using (TaggedStream file = new TaggedStream(path, Network.Protocol))
                    using (IVCryptoStream crypto = IVCryptoStream.Load(file, post.Header.FileKey))
                    {
                        PacketStream stream = new PacketStream(crypto, Network.Protocol, FileAccess.Read);

                        G2Header root = null;

                        while (stream.ReadPacket(ref root))
                        {
                            if (root.Name == BoardPacket.PostInfo)
                                post.Info = PostInfo.Decode(root);

                            else if (root.Name == BoardPacket.PostFile)
                                post.Attached.Add(PostFile.Decode(root));
                        }
                    }
                }
                catch (Exception ex)
                {
                    Network.UpdateLog("Board", "Could not load post " + post.Header.SourceID.ToString() + ": " + ex.Message);
                }

            if (post.Info == null)
                return "";

            if (post.Header.ParentID == 0)
                return post.Info.Subject;
            else
                return post.Info.Quip;
        }
Exemple #7
0
        // cant delete post because we dont control them with any master header
        // future - local board file that consists of deleted post ids
        public void Archive(OpPost post, bool state)
        {
            post.Header.Archived = state;

            PostEdit(post);

            UpdateGui(null);
        }
Exemple #8
0
        public void UpdateReplies(OpPost parent)
        {
            // count replies to post, if greater than variable set, overwrite

            ushort replies = 0;

            Posts.LockReading(delegate()
            {
                foreach (OpPost post in Posts.Values)
                    if (post.Header.ParentID == parent.Header.PostID)
                        replies++;
            });

            if (replies > parent.Replies)
                parent.Replies = replies;
        }
Exemple #9
0
        public void PostReply(OpPost parent)
        {
            Reply = true;

            ParentPost = parent;
            ParentID = parent.Header.PostID ;

            SubjectTextBox.Text = parent.Info.Subject;
            SubjectTextBox.Enabled = false;
            SubjectTextBox.BackColor = Color.WhiteSmoke;

            SetScopeInvisible();

            PostButton.Text = "Reply";
        }
Exemple #10
0
        public void PostEdit(OpPost post, uint parentID, string rtf, bool plain)
        {
            EditPost = post;

            ParentID = parentID;

            SubjectTextBox.Text = post.Info.Subject;

            MessageBody.InputBox.Rtf = rtf;
            MessageBody.PlainTextMode = plain;

            if (post.Header.Scope == ScopeType.All)
                ScopeAll.Checked = true;
            else if (post.Header.Scope == ScopeType.High)
                ScopeHigh.Checked = true;
            else if (post.Header.Scope == ScopeType.Low)
                ScopeLow.Checked = true;

            if (parentID != 0)
            {
                SubjectTextBox.Text = post.Info.Subject;
                SubjectTextBox.Enabled = false;

                SetScopeInvisible();
            }

            PostButton.Text = "Edit";
        }