]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - console.c
added sv_threaded cvar, the server can now be moved to another thread
[xonotic/darkplaces.git] / console.c
index 7c0499ad535320a4ea1019c1218c62ed38c1d4dc..2f7e99b72f96d41a0d22c861a256247d1385a858 100644 (file)
--- a/console.c
+++ b/console.c
@@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include <time.h>
 
 #include "quakedef.h"
+#include "thread.h"
 
 // for u8_encodech
 #include "ft2.h"
@@ -35,6 +36,7 @@ float con_cursorspeed = 4;
 int con_backscroll;
 
 conbuffer_t con;
+void *con_mutex = NULL;
 
 #define CON_LINES(i) CONBUFFER_LINES(&con, i)
 #define CON_LINES_LAST CONBUFFER_LINES_LAST(&con)
@@ -93,6 +95,7 @@ lhnetsocket_t *rcon_redirect_sock = NULL;
 lhnetaddress_t *rcon_redirect_dest = NULL;
 int rcon_redirect_bufferpos = 0;
 char rcon_redirect_buffer[1400];
+qboolean rcon_redirect_proquakeprotocol = false;
 
 // generic functions for console buffers
 
@@ -125,8 +128,10 @@ ConBuffer_Shutdown
 void ConBuffer_Shutdown(conbuffer_t *buf)
 {
        buf->active = false;
-       Mem_Free(buf->text);
-       Mem_Free(buf->lines);
+       if (buf->text)
+               Mem_Free(buf->text);
+       if (buf->lines)
+               Mem_Free(buf->lines);
        buf->text = NULL;
        buf->lines = NULL;
 }
@@ -593,6 +598,10 @@ Con_ToggleConsole_f
 */
 void Con_ToggleConsole_f (void)
 {
+       if (COM_CheckParm ("-noconsole"))
+               if (!(key_consoleactive & KEY_CONSOLEACTIVE_USER))
+                       return; // only allow the key bind to turn off console
+
        // toggle the 'user wants console' bit
        key_consoleactive ^= KEY_CONSOLEACTIVE_USER;
        Con_ClearNotify();
@@ -620,8 +629,11 @@ void Con_MessageMode_f (void)
 {
        key_dest = key_message;
        chat_mode = 0; // "say"
-       chat_bufferlen = 0;
-       chat_buffer[0] = 0;
+       if(Cmd_Argc() > 1)
+       {
+               dpsnprintf(chat_buffer, sizeof(chat_buffer), "%s ", Cmd_Args());
+               chat_bufferlen = strlen(chat_buffer);
+       }
 }
 
 
@@ -634,8 +646,11 @@ void Con_MessageMode2_f (void)
 {
        key_dest = key_message;
        chat_mode = 1; // "say_team"
-       chat_bufferlen = 0;
-       chat_buffer[0] = 0;
+       if(Cmd_Argc() > 1)
+       {
+               dpsnprintf(chat_buffer, sizeof(chat_buffer), "%s ", Cmd_Args());
+               chat_bufferlen = strlen(chat_buffer);
+       }
 }
 
 /*
@@ -713,17 +728,21 @@ void Con_ConDump_f (void)
                Con_Printf("condump: unable to write file \"%s\"\n", Cmd_Argv(1));
                return;
        }
+       if (con_mutex) Thread_LockMutex(con_mutex);
        for(i = 0; i < CON_LINES_COUNT; ++i)
        {
                FS_Write(file, CON_LINES(i).start, CON_LINES(i).len);
                FS_Write(file, "\n", 1);
        }
+       if (con_mutex) Thread_UnlockMutex(con_mutex);
        FS_Close(file);
 }
 
 void Con_Clear_f (void)
 {
+       if (con_mutex) Thread_LockMutex(con_mutex);
        ConBuffer_Clear(&con);
+       if (con_mutex) Thread_UnlockMutex(con_mutex);
 }
 
 /*
@@ -735,6 +754,8 @@ void Con_Init (void)
 {
        con_linewidth = 80;
        ConBuffer_Init(&con, CON_TEXTSIZE, CON_MAXLINES, zonemempool);
+       if (Thread_HasThreads())
+               con_mutex = Thread_CreateMutex();
 
        // Allocate a log queue, this will be freed after configs are parsed
        logq_size = MAX_INPUTLINE;
@@ -791,7 +812,10 @@ void Con_Init (void)
 
 void Con_Shutdown (void)
 {
+       if (con_mutex) Thread_LockMutex(con_mutex);
        ConBuffer_Shutdown(&con);
+       if (con_mutex) Thread_UnlockMutex(con_mutex);
+       if (con_mutex) Thread_DestroyMutex(con_mutex);con_mutex = NULL;
 }
 
 /*
@@ -816,6 +840,7 @@ void Con_PrintToHistory(const char *txt, int mask)
        if(!con.text) // FIXME uses a non-abstracted property of con
                return;
 
+       if (con_mutex) Thread_LockMutex(con_mutex);
        for(; *txt; ++txt)
        {
                if(cr_pending)
@@ -846,6 +871,7 @@ void Con_PrintToHistory(const char *txt, int mask)
                                break;
                }
        }
+       if (con_mutex) Thread_UnlockMutex(con_mutex);
 }
 
 /*! The translation table between the graphical font and plain ASCII  --KB */
@@ -885,20 +911,38 @@ static char qfont_table[256] = {
        'x',  'y',  'z',  '{',  '|',  '}',  '~',  '<'
 };
 
-void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest)
+void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest, qboolean proquakeprotocol)
 {
        rcon_redirect_sock = sock;
        rcon_redirect_dest = dest;
-       memcpy(rcon_redirect_buffer, "\377\377\377\377n", 5); // QW rcon print
+       rcon_redirect_proquakeprotocol = proquakeprotocol;
+       if (rcon_redirect_proquakeprotocol)
+       {
+               // reserve space for the packet header
+               rcon_redirect_buffer[0] = 0;
+               rcon_redirect_buffer[1] = 0;
+               rcon_redirect_buffer[2] = 0;
+               rcon_redirect_buffer[3] = 0;
+               // this is a reply to a CCREQ_RCON
+               rcon_redirect_buffer[4] = (char)CCREP_RCON;
+       }
+       else
+               memcpy(rcon_redirect_buffer, "\377\377\377\377n", 5); // QW rcon print
        rcon_redirect_bufferpos = 5;
 }
 
 void Con_Rcon_Redirect_Flush(void)
 {
        rcon_redirect_buffer[rcon_redirect_bufferpos] = 0;
-       NetConn_WriteString(rcon_redirect_sock, rcon_redirect_buffer, rcon_redirect_dest);
+       if (rcon_redirect_proquakeprotocol)
+       {
+               // update the length in the packet header
+               StoreBigLong((unsigned char *)rcon_redirect_buffer, NETFLAG_CTL | (rcon_redirect_bufferpos & NETFLAG_LENGTH_MASK));
+       }
+       NetConn_Write(rcon_redirect_sock, rcon_redirect_buffer, rcon_redirect_bufferpos, rcon_redirect_dest);
        memcpy(rcon_redirect_buffer, "\377\377\377\377n", 5); // QW rcon print
        rcon_redirect_bufferpos = 5;
+       rcon_redirect_proquakeprotocol = false;
 }
 
 void Con_Rcon_Redirect_End(void)
@@ -1026,11 +1070,12 @@ void Con_MaskPrint(int additionalmask, const char *msg)
        static int index = 0;
        static char line[MAX_INPUTLINE];
 
+       if (con_mutex)
+               Thread_LockMutex(con_mutex);
+
        for (;*msg;msg++)
        {
                Con_Rcon_AddChar(*msg);
-               if (index == 0)
-                       mask |= additionalmask;
                // if this is the beginning of a new line, print timestamp
                if (index == 0)
                {
@@ -1075,6 +1120,8 @@ void Con_MaskPrint(int additionalmask, const char *msg)
                        for (;*timestamp;index++, timestamp++)
                                if (index < (int)sizeof(line) - 2)
                                        line[index] = *timestamp;
+                       // add the mask
+                       mask |= additionalmask;
                }
                // append the character
                line[index++] = *msg;
@@ -1089,16 +1136,29 @@ void Con_MaskPrint(int additionalmask, const char *msg)
                        if (con_initialized && cls.state != ca_dedicated)
                        {
                                Con_PrintToHistory(line, mask);
-                               mask = 0;
                        }
                        // send to terminal or dedicated server window
                        if (!sys_nostdout)
+                       if (developer.integer || !(mask & CON_MASK_DEVELOPER))
                        {
-                               unsigned char *p;
                                if(sys_specialcharactertranslation.integer)
                                {
-                                       for (p = (unsigned char *) line;*p; p++)
-                                               *p = qfont_table[*p];
+                                       char *p;
+                                       const char *q;
+                                       p = line;
+                                       while(*p)
+                                       {
+                                               int ch = u8_getchar(p, &q);
+                                               if(ch >= 0xE000 && ch <= 0xE0FF)
+                                               {
+                                                       *p = qfont_table[ch - 0xE000];
+                                                       if(q > p+1)
+                                                               memmove(p+1, q, strlen(q)+1);
+                                                       p = p + 1;
+                                               }
+                                               else
+                                                       p = p + (q - p);
+                                       }
                                }
 
                                if(sys_colortranslation.integer == 1) // ANSI
@@ -1276,8 +1336,12 @@ void Con_MaskPrint(int additionalmask, const char *msg)
                        }
                        // empty the line buffer
                        index = 0;
+                       mask = 0;
                }
        }
+
+       if (con_mutex)
+               Thread_UnlockMutex(con_mutex);
 }
 
 /*
@@ -1623,6 +1687,7 @@ void Con_DrawNotify (void)
        int numChatlines;
        int chatpos;
 
+       if (con_mutex) Thread_LockMutex(con_mutex);
        ConBuffer_FixTimes(&con);
 
        numChatlines = con_chat.integer;
@@ -1713,6 +1778,7 @@ void Con_DrawNotify (void)
                x = min(xr, x);
                DrawQ_String(x, v, temptext, 0, inputsize, inputsize, 1.0, 1.0, 1.0, 1.0, 0, &colorindex, false, FONT_CHAT);
        }
+       if (con_mutex) Thread_UnlockMutex(con_mutex);
 }
 
 /*
@@ -1831,6 +1897,8 @@ void Con_DrawConsole (int lines)
        if (lines <= 0)
                return;
 
+       if (con_mutex) Thread_LockMutex(con_mutex);
+
        if (con_backscroll < 0)
                con_backscroll = 0;
 
@@ -1937,6 +2005,7 @@ void Con_DrawConsole (int lines)
        Con_DrawInput ();
 
        r_draw2d_force = false;
+       if (con_mutex) Thread_UnlockMutex(con_mutex);
 }
 
 /*
@@ -2787,11 +2856,11 @@ void Con_CompleteCommandLine (void)
                                        }
                                        else
                                        {
-                                               stringlistsort(&resultbuf); // dirbuf is already sorted
+                                               stringlistsort(&resultbuf, true); // dirbuf is already sorted
                                                Con_Printf("\n%i possible filenames\n", resultbuf.numstrings + dirbuf.numstrings);
                                                for(i = 0; i < dirbuf.numstrings; ++i)
                                                {
-                                                       Con_Printf("%s/\n", dirbuf.strings[i]);
+                                                       Con_Printf("^4%s^7/\n", dirbuf.strings[i]);
                                                }
                                                for(i = 0; i < resultbuf.numstrings; ++i)
                                                {