Esempio n. 1
0
        public static ServerPacketStructures.MessagingResponse GetMessageList(UuidReference userRef, ushort boardId, short startPostId, bool isClick = false)
        {
            MessageStore      store;
            var               displayname  = string.Empty;
            BoardResponseType responseType = BoardResponseType.GetBoardIndex;

            if (boardId == 0)
            {
                store        = Game.World.WorldData.GetOrCreate <Mailbox>(userRef);
                displayname  = $"{store.DisplayName}'s Mail";
                responseType = BoardResponseType.GetMailboxIndex;
            }
            else if (boardId == ushort.MaxValue - 1)
            {
                store       = Game.World.WorldData.GetOrCreate <SentMail>(userRef);
                displayname = $"{userRef.UserName}'s Sent Messages";
            }
            else
            {
                if (Game.World.WorldData.TryGetValueByIndex(boardId, out Board board))
                {
                    store       = board;
                    displayname = board.DisplayName;
                }
                else
                {
                    return(new ServerPacketStructures.MessagingResponse()
                    {
                        ResponseString = "Board not found.",
                        ResponseType = BoardResponseType.EndResult,
                        ResponseSuccess = false
                    });
                }
            }

            return(new ServerPacketStructures.MessagingResponse()
            {
                ResponseType = responseType,
                isClick = isClick,
                BoardId = boardId,
                BoardName = displayname,
                Messages = store.GetIndex()
            });
        }
Esempio n. 2
0
        public static ServerPacketStructures.MessagingResponse BoardList(UuidReference userRef)
        {
            var boards = new List <(ushort Id, string Name)>();

            // "Mail" is hardcoded in the client and does not need to be sent here
            // We also store a special mailbox called sent messages, which has all of the
            // user's stored messages

            boards.Add(((ushort)ushort.MaxValue - 1, $"{userRef.UserName}'s Sent Messages"));

            foreach (var board in Game.World.WorldData.Values <Board>().Where(mb => mb.Global &&
                                                                              mb.CheckAccessLevel(userRef.UserName, BoardAccessLevel.Read)))
            {
                boards.Add(((ushort)board.Id, board.DisplayName));
            }

            return(new ServerPacketStructures.MessagingResponse()
            {
                ResponseType = BoardResponseType.DisplayList,
                Boards = boards
            });
        }
Esempio n. 3
0
        public static ServerPacketStructures.MessagingResponse HighlightMessage(UuidReference userRef, ushort boardId, short postId)
        {
            string response = string.Empty;
            var    success  = false;
            Board  board;
            var    messageId = postId - 1;

            if (Game.World.WorldData.TryGetAuthInfo(userRef.UserName, out AuthInfo ainfo) && ainfo.IsPrivileged)
            {
                if (Game.World.WorldData.TryGetValueByIndex(boardId, out board))
                {
                    if (board.ToggleHighlight((short)messageId))
                    {
                        response = "The message was highlighted.";
                        success  = true;
                    }
                    else
                    {
                        response = "Message not found.";
                    }
                }
                else
                {
                    response = "Board not found.";
                }
            }
            else
            {
                response = "You cannot highlight this message.";
            }

            return(new ServerPacketStructures.MessagingResponse()
            {
                ResponseType = BoardResponseType.HighlightMessage,
                ResponseString = response,
                ResponseSuccess = success
            });
        }
Esempio n. 4
0
        public static ServerPacketStructures.MessagingResponse SendMessage(UuidReference senderRef, ushort boardId, string recipient, string subject, string body)
        {
            var response = string.Empty;
            var success  = true;

            var senderSentMail = Game.World.WorldData.GetOrCreate <SentMail>(senderRef);

            // Don't allow blank title or subject
            if (string.IsNullOrWhiteSpace(subject))
            {
                success  = false;
                response = "The message had no subject.";
            }
            else if (string.IsNullOrWhiteSpace(body))
            {
                success  = false;
                response = "You can't send empty messages.";
            }
            else if (!body.IsAscii() || !subject.IsAscii())
            {
                success  = false;
                response = "You can't use special characters in a message (ASCII only).";
            }
            else if (boardId == ushort.MaxValue - 1)
            {
                success  = false;
                response = "You can't post messages here.";
            }

            // Handle plugin response

            if (!Game.World.TryGetActiveUser(senderRef.UserName, out _))
            {
                // Currently a user must be online to send mail, so if we get here, something really wacky is happening
                return(UnknownError);
            }
            try
            {
                IMessageHandler handler;
                Xml.MessageType type;
                if (boardId == 0)
                {
                    type = Xml.MessageType.Mail;
                }
                else
                {
                    type = Xml.MessageType.BoardMessage;
                }

                var message = new Plugins.Message(type, senderRef.UserName, recipient, subject, body);

                handler = Game.World.ResolveMessagingPlugin(type, message);

                if (handler is IProcessingMessageHandler pmh && success)
                {
                    var msg  = new Plugins.Message(Xml.MessageType.Mail, senderRef.UserName, recipient, subject, body);
                    var resp = pmh.Process(msg);
                    if (!pmh.Passthrough)
                    {
                        // TODO: implement cast / resolve duplication
                        var hmsg = new Message(recipient, senderRef.UserName, subject, body);
                        senderSentMail.ReceiveMessage((Message)hmsg);

                        // Plugin is "last destination" for message
                        return(new ServerPacketStructures.MessagingResponse()
                        {
                            ResponseType = BoardResponseType.EndResult,
                            ResponseSuccess = resp.Success,
                            ResponseString = resp.PluginResponse
                        });
                    }
                    else if (resp.Transformed)
                    {
                        // Update message if transformed, and keep going
                        recipient = resp.Message.Recipient;
                        subject   = resp.Message.Subject;
                        body      = resp.Message.Text;
                    }
                }
            }
            catch (Exception e)
            {
                Game.ReportException(e);
                success  = false;
                response = "An unknown error occurred. Sorry!";
            }

            // Annoyingly board replies use the same packet path as sending mail replies, so we need to handle
            // both here
            if (boardId == 0 && success)
            {
                var receiverRef = Game.World.WorldData.GetUuidReference(recipient);
                if (receiverRef == null)
                {
                    success  = false;
                    response = "Sadly, no record of that person exists in the realm.";
                }
                else
                {
                    var mailbox = Game.World.WorldData.GetOrCreate <Mailbox>(receiverRef);
                    var msg     = new Message(recipient, senderRef.UserName, subject, body);
                    try
                    {
                        if ((DateTime.Now - senderSentMail.LastMailMessageSent).TotalSeconds < Constants.MAIL_MESSAGE_COOLDOWN &&
                            senderSentMail.LastMailRecipient == recipient)
                        {
                            success  = false;
                            response = $"You've sent too much mail to {recipient} recently. Give it a rest.";
                        }
                        else if (mailbox.ReceiveMessage(msg))
                        {
                            response = $"Your letter to {recipient} was sent.";
                            GameLog.InfoFormat("mail: {0} sent message to {1}", senderRef.UserName, recipient);
                            World.ControlMessageQueue.Add(new HybrasylControlMessage(ControlOpcodes.MailNotifyUser,
                                                                                     recipient));
                            senderSentMail.LastMailRecipient   = recipient;
                            senderSentMail.LastMailMessageSent = DateTime.Now;
                        }
                        else
                        {
                            success  = false;
                            response = $"{recipient}'s mailbox is full or locked. A copy was kept in your sent mailbox. Sorry!";
                        }
                    }
                    catch (MessageStoreLocked e)
                    {
                        Game.ReportException(e);
                        success  = false;
                        response = $"{recipient} cannot receive mail at this time. Sorry!";
                    }
                    senderSentMail.ReceiveMessage((Message)msg.Clone());
                }
            }
            else if (success)
            {
                if (Game.World.WorldData.TryGetValueByIndex(boardId, out Board board))
                {
                    if (Game.World.WorldData.TryGetAuthInfo(senderRef.UserUuid, out AuthInfo ainfo))
                    {
                        if (ainfo.IsPrivileged || board.CheckAccessLevel(ainfo.Username, BoardAccessLevel.Write))
                        {
                            var msg = new Message(board.DisplayName, senderRef.UserName, subject, body);
                            if (board.ReceiveMessage(msg))
                            {
                                response = "The message was sent.";
                                success  = true;
                                var sentMsg = (Message)msg.Clone();
                                sentMsg.Recipient = board.DisplayName;
                                senderSentMail.ReceiveMessage(sentMsg);
                            }
                            else
                            {
                                response = "The message could not be sent.";
                            }
                        }
                        else
                        {
                            response = "You don't have permission to do that.";
                        }
                    }
                    else
                    {
                        response = "Authentication information could not be verified.";
                    }
                }
                else
                {
                    response = "Board not found.";
                }
            }

            return(new ServerPacketStructures.MessagingResponse()
            {
                ResponseType = BoardResponseType.EndResult,
                ResponseString = response,
                ResponseSuccess = success
            });
        }
Esempio n. 5
0
        public static ServerPacketStructures.MessagingResponse DeleteMessage(UuidReference userRef, ushort boardId, ushort postId)
        {
            var response  = string.Empty;
            var success   = false;
            var messageId = postId - 1;

            if (boardId == 0 || boardId == ushort.MaxValue - 1) // Mailbox access
            {
                MessageStore store;
                if (boardId == 0)
                {
                    store = Game.World.WorldData.GetOrCreate <Mailbox>(userRef);
                }
                else
                {
                    store = Game.World.WorldData.GetOrCreate <SentMail>(userRef);
                }

                if (store.DeleteMessage(messageId))
                {
                    response = "The message was destroyed.";
                    success  = true;
                }
                else
                {
                    response = "The message could not be found.";
                }
            }
            else if (Game.World.WorldData.TryGetValueByIndex(boardId, out Board board))
            {
                if (Game.World.WorldData.TryGetAuthInfo(userRef.UserUuid, out AuthInfo ainfo))
                {
                    var delmsg = board.GetMessage(messageId);

                    if (delmsg == null)
                    {
                        response = "That message could not be found.";
                    }

                    else if (ainfo.IsPrivileged || board.CheckAccessLevel(ainfo.Username, BoardAccessLevel.Moderate) ||
                             delmsg.Sender.ToLower() == userRef.UserName.ToLower())
                    {
                        if (board.DeleteMessage(postId - 1))
                        {
                            response = "The message was destroyed.";
                            success  = true;
                        }
                        else
                        {
                            response = "Sorry, an error occurred.";
                        }
                    }
                    else
                    {
                        response = "You can't do that.";
                    }
                }
                else
                {
                    response = "Authentication information could not be verified.";
                }
            }
            else
            {
                response = "Board not found.";
            }

            return(new ServerPacketStructures.MessagingResponse()
            {
                ResponseType = BoardResponseType.DeleteMessage,
                ResponseSuccess = success,
                ResponseString = response
            });
        }
Esempio n. 6
0
        public static ServerPacketStructures.MessagingResponse GetMessage(UuidReference userRef, short postId, sbyte offset, ushort boardId)
        {
            Message      message = null;
            string       error   = "An unknown error occured.";
            MessageStore store;

            if (boardId == 0)
            {
                store = Game.World.WorldData.GetOrCreate <Mailbox>(userRef);
            }
            else if (boardId == ushort.MaxValue - 1)
            {
                store = Game.World.WorldData.GetOrCreate <SentMail>(userRef);
            }
            else
            {
                if (Game.World.WorldData.TryGetValueByIndex(boardId, out Board board))
                {
                    if (!board.CheckAccessLevel(userRef.UserName, BoardAccessLevel.Read))
                    {
                        return new ServerPacketStructures.MessagingResponse()
                               {
                                   ResponseType    = BoardResponseType.EndResult,
                                   ResponseString  = "Access denied.",
                                   ResponseSuccess = false
                               }
                    }
                    ;
                    store = board;
                }
                else
                {
                    return new ServerPacketStructures.MessagingResponse()
                           {
                               ResponseType   = BoardResponseType.EndResult,
                               ResponseString = "That message store was not found."
                           }
                };
            }
            var messageId = postId - 1;

            switch (offset)
            {
            case 0:
            {
                // postId is the exact message
                if (postId >= 0 && postId <= store.Messages.Count)
                {
                    message = store.Messages[messageId];
                }
                else
                {
                    error = "That post could not be found.";
                }
                break;
            }

            case 1:
            {
                // Client clicked "prev", which hilariously means "newer"
                // postId in this case is the next message
                if (postId > store.Messages.Count)
                {
                    error = "There are no newer messages.";
                }
                else
                {
                    var messageList = store.Messages.GetRange(messageId,
                                                              store.Messages.Count - messageId);
                    message = messageList.Find(m => m.Deleted == false);

                    if (message == null)
                    {
                        error = "There are no newer messages.";
                    }
                }
            }
            break;

            case -1:
            {
                // Client clicked "next", which means "older"
                // postId is previous message
                if (postId < 0)
                {
                    error = "There are no older messages.";
                }
                else
                {
                    var messageList = store.Messages.GetRange(0, postId);
                    messageList.Reverse();
                    message = messageList.Find(m => m.Deleted == false);
                    if (message == null)
                    {
                        error = "There are no older messages.";
                    }
                }
            }
            break;

            default:
            {
                error = "Invalid offset (nice try, chief)";
            }
            break;
            }
            if (message != null)
            {
                message.Read = true;
                //                    Mailbox.Save();
                //                    user.UpdateAttributes(StatUpdateFlags.Secondary);
                return(new ServerPacketStructures.MessagingResponse()
                {
                    BoardId = 0,
                    Messages = message.InfoAsList,
                    ResponseType = store is Mailbox ? BoardResponseType.GetMailMessage : BoardResponseType.GetBoardMessage
                });
            }
            return(new ServerPacketStructures.MessagingResponse()
            {
                ResponseType = BoardResponseType.EndResult,
                ResponseSuccess = false,
                ResponseString = error
            });
        }