public static ServerMessage Compose(ModerationTicket Ticket)
        {
            string DisplayRoomName = string.Empty;

            if (Ticket.RoomId > 0)
            {
                RoomInfo Info = RoomInfoLoader.GetRoomInfo(Ticket.RoomId);
                DisplayRoomName = Info == null ? "(Unknown room " + Ticket.RoomId + ")" : Info.Name;
            }

            ServerMessage Message = new ServerMessage(OpcodesOut.MODERATION_TICKET);
            Message.AppendUInt32(Ticket.Id);
            Message.AppendUInt32(Ticket.TabId);
            Message.AppendUInt32(11); // ?? unknown
            Message.AppendUInt32(Ticket.CategoryId);
            Message.AppendUInt32(11); // ?? unknown
            Message.AppendUInt32(Ticket.Score);
            Message.AppendUInt32(Ticket.ReporteeUserId);
            Message.AppendStringWithBreak(CharacterResolverCache.GetNameFromUid(Ticket.ReporteeUserId));
            Message.AppendUInt32(Ticket.ReportedUserId);
            Message.AppendStringWithBreak(CharacterResolverCache.GetNameFromUid(Ticket.ReportedUserId));
            Message.AppendUInt32(Ticket.ModeratorUserId);
            Message.AppendStringWithBreak(CharacterResolverCache.GetNameFromUid(Ticket.ModeratorUserId));
            Message.AppendStringWithBreak(Ticket.Message);
            Message.AppendUInt32(Ticket.RoomId);
            Message.AppendStringWithBreak(DisplayRoomName);
            return Message;
        }
        public static ServerMessage Compose(ModerationTicket Ticket, RoomInfo Info, ReadOnlyCollection<ModerationChatlogEntry> Entries)
        {
            ServerMessage Message = new ServerMessage(OpcodesOut.MODERATION_CHATLOGS_TICKET);
            Message.AppendUInt32(Ticket.Id);
            Message.AppendUInt32(Ticket.ReporteeUserId);
            Message.AppendUInt32(Ticket.ReportedUserId);
            Message.AppendUInt32(Ticket.Id); // Number to display in title. Chatlog ID?
            Message.AppendBoolean(Info != null ? Info.Type == RoomType.Public : false);
            Message.AppendUInt32(Info != null ? Info.Id : 0);
            Message.AppendStringWithBreak(Info != null ? Info.Name : "(Unknown room)");

            Message.AppendInt32(Entries.Count);

            foreach (ModerationChatlogEntry Entry in Entries)
            {
                DateTime Time = UnixTimestamp.GetDateTimeFromUnixTimestamp(Entry.Timestamp);

                Message.AppendInt32(Time.Hour);
                Message.AppendInt32(Time.Minute);
                Message.AppendUInt32(Entry.UserId);
                Message.AppendStringWithBreak(Entry.UserName);
                Message.AppendStringWithBreak(Entry.Message);
            }

            return Message;
        }
        private static void HandleIncomingTicket(Session Session, ClientMessage Message)
        {
            if (GetPendingTicketForUser(Session.CharacterId) != null)
            {
                Session.SendData(HelpSubmitCfhResultComposer.Compose(CfhErrorCode.AlreadyHaveCall));
                return;
            }

            if (Session.CharacterInfo.ModerationTicketsCooldownSeconds > 0)
            {
                Session.SendData(HelpSubmitCfhResultComposer.Compose(CfhErrorCode.AbusiveCooldown));
                return;
            }

            string TicketBody = UserInputFilter.FilterString(Message.PopString());
            uint Unknown = Message.PopWiredUInt32();
            uint Category = Message.PopWiredUInt32();
            uint ReportedUser = Message.PopWiredUInt32();
            uint RoomId = Session.CurrentRoomId;
            double Timestamp = UnixTimestamp.GetCurrent();

            lock (mSyncRoot)
            {
                uint GeneratedId = 0;

                using (SqlDatabaseClient MySqlClient = SqlDatabaseManager.GetClient())
                {
                    MySqlClient.SetParameter("category", Category);
                    MySqlClient.SetParameter("reporteduid", ReportedUser);
                    MySqlClient.SetParameter("reporteeuid", Session.CharacterId);
                    MySqlClient.SetParameter("roomid", RoomId);
                    MySqlClient.SetParameter("timestamp", Timestamp);
                    MySqlClient.SetParameter("message", TicketBody);
                    string GeneratedResult = MySqlClient.ExecuteScalar("INSERT INTO moderation_tickets (category,reported_user_id,reportee_user_id,room_id,timestamp,message) VALUES (@category,@reporteduid,@reporteeuid,@roomid,@timestamp,@message); SELECT LAST_INSERT_ID();").ToString();

                    uint.TryParse(GeneratedResult, out GeneratedId);
                }

                if (GeneratedId > 0)
                {
                    ModerationTicket NewTicket = new ModerationTicket(GeneratedId, Category, ModerationTicketStatus.OpenTicket,
                        ReportedUser, Session.CharacterId, 0, RoomId, Timestamp, TicketBody);

                    mTickets.Add(GeneratedId, NewTicket);

                    ServerMessage TicketMessage = ModerationTicketComposer.Compose(NewTicket);
                    SendDataToAllModerators(TicketMessage);

                    Session.CharacterInfo.ModerationTickets++;
                }
            }

            Session.SendData(HelpSubmitCfhResultComposer.Compose(CfhErrorCode.Ok));
        }