Misc tweaks.
Fix potentially serious crash with sprites+csqc tracelines. Reworked fallback mouse cursor. Fix decals on q3 bmodels. Double-click to select a work to copy is now implemented. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5323 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
4ae635bc7b
commit
2bedc32ff9
49 changed files with 968 additions and 520 deletions
|
@ -195,6 +195,7 @@ ELSEIF(${UNIX}) #linux(ish)
|
|||
engine/client/sys_linux.c
|
||||
engine/common/sys_linux_threads.c
|
||||
engine/common/net_ssl_gnutls.c
|
||||
# engine/common/net_ssl_openssl.c
|
||||
|
||||
engine/client/snd_al.c
|
||||
engine/client/snd_alsa.c
|
||||
|
@ -241,8 +242,14 @@ ELSEIF(${UNIX}) #linux(ish)
|
|||
engine/server/sv_sys_unix.c
|
||||
engine/common/sys_linux_threads.c
|
||||
engine/common/net_ssl_gnutls.c
|
||||
# engine/common/net_ssl_openssl.c
|
||||
)
|
||||
SET(FTESV_LIBS ${ZLIB_LIBRARIES} m ${CMAKE_DL_LIBS} pthread)
|
||||
|
||||
# SET(FTE_DEFINES ${FTE_DEFINES};HAVE_OPENSSL)
|
||||
# SET(FTESV_DEFINES ${FTESV_DEFINES};HAVE_OPENSSL)
|
||||
# SET(FTE_LIBS ${FTE_LIBS} ssl crypto)
|
||||
# SET(FTESV_LIBS ${FTE_LIBS} ssl crypto)
|
||||
ELSEIF(1) #SDL
|
||||
# FIND_PACKAGE(Freetype REQUIRED)
|
||||
# INCLUDE_DIRECTORIES(engine/libs engine/libs/freetype2/include)
|
||||
|
|
|
@ -1638,8 +1638,8 @@ BASELDFLAGS:=-L$(ARCHLIBS) $(BASELDFLAGS)
|
|||
|
||||
.default: help
|
||||
all: rel
|
||||
rel: sv-rel m-rel mingl-rel qcc-rel
|
||||
dbg: sv-dbg m-dbg mingl-dbg qcc-dbg
|
||||
rel: sv-rel m-rel qcc-rel
|
||||
dbg: sv-dbg m-dbg qcc-dbg
|
||||
relcl: glcl-rel mcl-rel
|
||||
profile: sv-profile gl-profile mingl-profile
|
||||
|
||||
|
|
|
@ -5496,7 +5496,7 @@ void CL_SetSolidEntities (void)
|
|||
so we need to make sure that item pickups are not erroneously considered solid, but doors etc are.
|
||||
yes, this probably means that externally loaded models will be predicted non-solid - you'll need to upgrade your network protocol for the gamecode to be able to specify solidity.
|
||||
*/
|
||||
if (!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) && !((*cl.model_precache[state->modelindex]->name == '*' || cl.model_precache[state->modelindex]->numsubmodels) && cl.model_precache[state->modelindex]->hulls[1].firstclipnode))
|
||||
if (!(cls.fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS) && !((*cl.model_precache[state->modelindex]->name == '*' || cl.model_precache[state->modelindex]->numsubmodels) && cl.model_precache[state->modelindex]->funcs.NativeTrace))
|
||||
continue;
|
||||
|
||||
pent = &pmove.physents[pmove.numphysent];
|
||||
|
|
|
@ -2973,7 +2973,7 @@ void CL_ConnectionlessPacket (void)
|
|||
unsigned int curtime = Sys_Milliseconds();
|
||||
unsigned long pext = 0, pext2 = 0, huffcrc=0, mtu=0;
|
||||
#ifdef HAVE_DTLS
|
||||
qboolean candtls = false;
|
||||
int candtls = 0; //0=no,1=optional,2=mandatory
|
||||
#endif
|
||||
char guidhash[256];
|
||||
|
||||
|
@ -3183,6 +3183,10 @@ void CL_ConnectionlessPacket (void)
|
|||
//c2s DTLS(getchallenge)
|
||||
//DTLS(etc)
|
||||
|
||||
//getchallenge has to be done twice, with the outer one only reporting whether dtls can/should be used.
|
||||
//this means the actual connect packet is already over dtls, which protects the user's userinfo.
|
||||
//FIXME: do rcon via dtls too, but requires tracking pending rcon packets until the handshake completes.
|
||||
|
||||
//server says it can do tls.
|
||||
char *pkt = va("%c%c%c%cdtlsconnect %i", 255, 255, 255, 255, connectinfo.challenge);
|
||||
NET_SendPacket (NS_CLIENT, strlen(pkt), pkt, &net_from);
|
||||
|
@ -3440,9 +3444,9 @@ client_connect: //fixme: make function
|
|||
if (cls.netchan.remote_address.type != NA_LOOPBACK)
|
||||
{
|
||||
if (cls.netchan.remote_address.prot == NP_DTLS || cls.netchan.remote_address.prot == NP_TLS || cls.netchan.remote_address.prot == NP_WSS)
|
||||
Con_TPrintf ("Connected (encrypted).\n");
|
||||
Con_TPrintf ("Connected (^2encrypted^7).\n");
|
||||
else
|
||||
Con_TPrintf ("Connected (plain-text).\n");
|
||||
Con_TPrintf ("Connected (^1plain-text^7).\n");
|
||||
}
|
||||
#ifdef QUAKESPYAPI
|
||||
allowremotecmd = false; // localid required now for remote cmds
|
||||
|
@ -5724,7 +5728,7 @@ double Host_Frame (double time)
|
|||
if (sv.state && cls.state != ca_active)
|
||||
{
|
||||
maxfpsignoreserver = false;
|
||||
maxfps = 0;
|
||||
maxfps = cl_maxfps.ival;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
@ -6042,9 +6046,6 @@ void CL_StartCinematicOrMenu(void)
|
|||
|
||||
Con_ClearNotify();
|
||||
|
||||
TP_ExecTrigger("f_startup", true);
|
||||
Cbuf_Execute ();
|
||||
|
||||
if (com_installer)
|
||||
{
|
||||
com_installer = false;
|
||||
|
@ -6055,12 +6056,15 @@ void CL_StartCinematicOrMenu(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
if (!sv_state && !cls.demoinfile && !cls.state && !*cls.servername && !Media_PlayingFullScreen())
|
||||
{
|
||||
TP_ExecTrigger("f_startup", true);
|
||||
Cbuf_Execute ();
|
||||
}
|
||||
|
||||
//and any startup cinematics
|
||||
#ifdef HAVE_MEDIA_DECODER
|
||||
#ifndef CLIENTONLY
|
||||
if (!sv.state)
|
||||
#endif
|
||||
if (!cls.demoinfile && !cls.state && !*cls.servername && !Media_PlayingFullScreen())
|
||||
if (!sv_state && !cls.demoinfile && !cls.state && !*cls.servername && !Media_PlayingFullScreen())
|
||||
{
|
||||
int ol_depth;
|
||||
int idcin_depth;
|
||||
|
@ -6091,11 +6095,7 @@ void CL_StartCinematicOrMenu(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
if (!cls.demoinfile && !cls.state && !*cls.servername && !Media_PlayingFullScreen())
|
||||
{
|
||||
#ifndef CLIENTONLY
|
||||
if (!sv.state)
|
||||
#endif
|
||||
if (!sv_state && !cls.demoinfile && !cls.state && !*cls.servername && !Media_PlayingFullScreen())
|
||||
{
|
||||
if (qrenderer > QR_NONE && !Key_Dest_Has(kdm_emenu))
|
||||
{
|
||||
|
@ -6115,7 +6115,6 @@ void CL_StartCinematicOrMenu(void)
|
|||
}
|
||||
//Con_ForceActiveNow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CL_ArgumentOverrides(void)
|
||||
|
@ -6367,6 +6366,7 @@ void Host_Init (quakeparms_t *parms)
|
|||
Sys_Quit();
|
||||
return;
|
||||
}
|
||||
PM_Shutdown(); //will restart later as needed, but we need to be sure that no files are open or anything.
|
||||
}
|
||||
V_Init ();
|
||||
NET_Init ();
|
||||
|
|
|
@ -1166,6 +1166,7 @@ void CL_PredictMovePNum (int seat)
|
|||
}
|
||||
if (i == pe->num_entities && pv->nolocalplayer)
|
||||
{
|
||||
return;
|
||||
fromstate = &nullstate;
|
||||
nopred = true;
|
||||
}
|
||||
|
|
|
@ -990,28 +990,105 @@ void SCR_DrawCursor(void)
|
|||
key_customcursor[cmod].dirty = false;
|
||||
oldcurs = key_customcursor[cmod].handle;
|
||||
if (rf->VID_CreateCursor && strcmp(key_customcursor[cmod].name, "none"))
|
||||
{
|
||||
key_customcursor[cmod].handle = NULL;
|
||||
if (!key_customcursor[cmod].handle && *key_customcursor[cmod].name)
|
||||
{
|
||||
image_t dummytex;
|
||||
flocation_t loc;
|
||||
char bestname[MAX_QPATH];
|
||||
unsigned int bestflags;
|
||||
qbyte *rgbadata;
|
||||
uploadfmt_t format;
|
||||
void *filedata = NULL;
|
||||
int filelen = 0, width, height;
|
||||
|
||||
key_customcursor[cmod].handle = NULL;
|
||||
|
||||
memset(&dummytex, 0, sizeof(dummytex));
|
||||
dummytex.ident = key_customcursor[cmod].name;
|
||||
dummytex.flags = IF_NOREPLACE; //no dds files
|
||||
*bestname = 0;
|
||||
|
||||
//first try the named image, if possible
|
||||
if (!filedata && *key_customcursor[cmod].name)
|
||||
{
|
||||
dummytex.ident = key_customcursor[cmod].name;
|
||||
if (Image_LocateHighResTexture(&dummytex, &loc, bestname, sizeof(bestname), &bestflags))
|
||||
key_customcursor[cmod].handle = rf->VID_CreateCursor(bestname, key_customcursor[cmod].hotspot[0], key_customcursor[cmod].hotspot[1], key_customcursor[cmod].scale);
|
||||
else
|
||||
key_customcursor[cmod].handle = rf->VID_CreateCursor(key_customcursor[cmod].name, key_customcursor[cmod].hotspot[0], key_customcursor[cmod].hotspot[1], key_customcursor[cmod].scale);
|
||||
filelen = FS_LoadFile(bestname, &filedata);
|
||||
}
|
||||
if (!filedata)
|
||||
{
|
||||
dummytex.ident = "gfx/cursor.lmp";
|
||||
if (Image_LocateHighResTexture(&dummytex, &loc, bestname, sizeof(bestname), &bestflags))
|
||||
filelen = FS_LoadFile(bestname, &filedata);
|
||||
}
|
||||
if (!filedata)
|
||||
{
|
||||
static qbyte lamecursor[] =
|
||||
{
|
||||
#define W 0x8f,0x8f,0x8f,0xff,
|
||||
#define B 0x00,0x00,0x00,0xff,
|
||||
#define T 0x00,0x00,0x00,0x00,
|
||||
W T T T T T T T
|
||||
W W T T T T T T
|
||||
W B W T T T T T
|
||||
W B B W T T T T
|
||||
|
||||
W B B B W T T T
|
||||
W B B B B W T T
|
||||
W B B B B B W T
|
||||
W B B B B B B W
|
||||
|
||||
W B B B B W W W
|
||||
W B W B B W T T
|
||||
W W T W B B W T
|
||||
W T T W B B W T
|
||||
|
||||
T T T T W B B W
|
||||
T T T T W B B W
|
||||
T T T T T W W T
|
||||
#undef W
|
||||
#undef B
|
||||
};
|
||||
key_customcursor[cmod].handle = rf->VID_CreateCursor(lamecursor, 8, 15, PTI_LLLA8, 0, 0, 1); //try the fallback
|
||||
}
|
||||
else if (!filedata)
|
||||
FS_FreeFile(filedata); //format not okay, just free it.
|
||||
else
|
||||
{ //raw file loaded.
|
||||
rgbadata = ReadRawImageFile(filedata, filelen, &width, &height, &format, true, bestname);
|
||||
FS_FreeFile(filedata);
|
||||
if (rgbadata)
|
||||
{ //image loaded properly, yay
|
||||
if ((format==PTI_RGBX8 || format==PTI_LLLX8) && !strchr(bestname, ':'))
|
||||
{ //people seem to insist on using jpgs, which don't have alpha.
|
||||
//so screw over the alpha channel if needed.
|
||||
unsigned int alpha_width, alpha_height, p;
|
||||
char aname[MAX_QPATH];
|
||||
unsigned char *alphadata;
|
||||
char *alph;
|
||||
size_t alphsize;
|
||||
char ext[8];
|
||||
COM_StripExtension(bestname, aname, sizeof(aname));
|
||||
COM_FileExtension(bestname, ext, sizeof(ext));
|
||||
Q_strncatz(aname, "_alpha.", sizeof(aname));
|
||||
Q_strncatz(aname, ext, sizeof(aname));
|
||||
alphsize = FS_LoadFile(aname, (void**)&alph);
|
||||
if (alph)
|
||||
{
|
||||
if ((alphadata = ReadRawImageFile(alph, alphsize, &alpha_width, &alpha_height, &format, true, aname)))
|
||||
{
|
||||
if (alpha_width == width && alpha_height == height)
|
||||
for (p = 0; p < alpha_width*alpha_height; p++)
|
||||
rgbadata[(p<<2) + 3] = (alphadata[(p<<2) + 0] + alphadata[(p<<2) + 1] + alphadata[(p<<2) + 2])/3;
|
||||
BZ_Free(alphadata);
|
||||
}
|
||||
FS_FreeFile(alph);
|
||||
}
|
||||
format = (format==PTI_LLLX8)?PTI_LLLA8:PTI_RGBA8;
|
||||
}
|
||||
|
||||
key_customcursor[cmod].handle = rf->VID_CreateCursor(rgbadata, width, height, format, key_customcursor[cmod].hotspot[0], key_customcursor[cmod].hotspot[1], key_customcursor[cmod].scale); //try the fallback
|
||||
BZ_Free(rgbadata);
|
||||
}
|
||||
}
|
||||
if (!key_customcursor[cmod].handle)
|
||||
key_customcursor[cmod].handle = rf->VID_CreateCursor("gfx/cursor.tga", key_customcursor[cmod].hotspot[0], key_customcursor[cmod].hotspot[1], key_customcursor[cmod].scale); //try the fallback
|
||||
if (!key_customcursor[cmod].handle)
|
||||
key_customcursor[cmod].handle = rf->VID_CreateCursor("gfx/cursor.png", key_customcursor[cmod].hotspot[0], key_customcursor[cmod].hotspot[1], key_customcursor[cmod].scale); //try the fallback
|
||||
if (!key_customcursor[cmod].handle)
|
||||
key_customcursor[cmod].handle = rf->VID_CreateCursor("gfx/cursor.lmp", key_customcursor[cmod].hotspot[0], key_customcursor[cmod].hotspot[1], key_customcursor[cmod].scale); //try the fallback
|
||||
}
|
||||
else
|
||||
key_customcursor[cmod].handle = NULL;
|
||||
|
|
|
@ -697,6 +697,11 @@ void Con_Init (void)
|
|||
|
||||
con_main.linebuffered = Con_ExecuteLine;
|
||||
con_main.commandcompletion = true;
|
||||
// con_main.flags |= CONF_ISWINDOW;
|
||||
con_main.wnd_w = 640;
|
||||
con_main.wnd_h = 480;
|
||||
con_main.wnd_x = 0;
|
||||
con_main.wnd_y = 0;
|
||||
Q_strncpyz(con_main.title, "MAIN", sizeof(con_main.title));
|
||||
Q_strncpyz(con_main.prompt, "]", sizeof(con_main.prompt));
|
||||
|
||||
|
@ -2571,7 +2576,7 @@ void Con_DrawConsole (int lines, qboolean noback)
|
|||
}
|
||||
|
||||
//draw main console...
|
||||
if (lines > 0)
|
||||
if (lines > 0 && !(con_current->flags & CONF_ISWINDOW))
|
||||
{
|
||||
int top;
|
||||
#ifdef QTERM
|
||||
|
@ -2935,18 +2940,106 @@ static qbyte Con_IsTokenChar(unsigned int chr)
|
|||
return true;
|
||||
if (chr == '(' || chr == ')' || chr == '{' || chr == '}')
|
||||
return false;
|
||||
if (chr == '.' || chr == '/' || chr == '\\')
|
||||
return 2;
|
||||
if (chr == '/' || chr == '\\')
|
||||
return 2; //on left only
|
||||
if (chr == '.' || chr == ':')
|
||||
return 3; //disallow only if followed by whitespace
|
||||
if (chr >= 'a' && chr <= 'z')
|
||||
return true;
|
||||
if (chr >= 'A' && chr <= 'Z')
|
||||
return true;
|
||||
if (chr >= '0' && chr <= '9')
|
||||
return true;
|
||||
if (chr == '[' || chr == ']' || chr == '_' || chr == ':')
|
||||
if (chr == '[' || chr == ']' || chr == '_')
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
void Con_ExpandConsoleSelection(console_t *con)
|
||||
{
|
||||
conchar_t *cur, *n;
|
||||
conline_t *l;
|
||||
conchar_t *lstart;
|
||||
conchar_t *lend;
|
||||
unsigned int cf, uc;
|
||||
|
||||
//no selection to expand...
|
||||
if (!con->selstartline || !con->selendline)
|
||||
return;
|
||||
|
||||
l = con->selstartline;
|
||||
lstart = (conchar_t*)(l+1);
|
||||
cur = lstart + con->selstartoffset;
|
||||
|
||||
if (con->selstartline == con->selendline)
|
||||
{
|
||||
if (con->selstartoffset+1 == con->selendoffset)
|
||||
{
|
||||
//they only selected a single char?
|
||||
//fix that up to select the entire token
|
||||
while (cur > lstart)
|
||||
{
|
||||
cur--;
|
||||
uc = (*cur & CON_CHARMASK);
|
||||
if (!Con_IsTokenChar(uc))
|
||||
{
|
||||
cur++;
|
||||
break;
|
||||
}
|
||||
if (*cur == CON_LINKSTART)
|
||||
break;
|
||||
}
|
||||
for (n = lstart+con->selendoffset; con->selendoffset < l->length; )
|
||||
{
|
||||
n = Font_Decode(n, &cf, &uc);
|
||||
if (Con_IsTokenChar(uc)==3)
|
||||
continue;
|
||||
|
||||
if (Con_IsTokenChar(uc)==1 && lstart[con->selendoffset] != CON_LINKEND)
|
||||
con->selendoffset = n-lstart;
|
||||
else
|
||||
break;
|
||||
}
|
||||
/*while (con->selendoffset > l->length)
|
||||
{
|
||||
uc = (((conchar_t*)(l+1))[con->selendoffset] & CON_CHARMASK);
|
||||
if (Con_IsTokenChar(uc) == 2)
|
||||
con->selendoffset--;
|
||||
else
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
//scan backwards to find any link enclosure
|
||||
for(lend = cur-1; lend >= (conchar_t*)(l+1); lend--)
|
||||
{
|
||||
if (*lend == CON_LINKSTART)
|
||||
{
|
||||
//found one
|
||||
cur = lend;
|
||||
break;
|
||||
}
|
||||
if (*lend == CON_LINKEND)
|
||||
{
|
||||
//some other link ended here. don't use its start.
|
||||
break;
|
||||
}
|
||||
}
|
||||
//scan forwards to find the end of the selected link
|
||||
if (l->length && cur < (conchar_t*)(l+1)+l->length && *cur == CON_LINKSTART)
|
||||
{
|
||||
for(lend = (conchar_t*)(con->selendline+1) + con->selendoffset; lend < (conchar_t*)(con->selendline+1) + con->selendline->length; lend++)
|
||||
{
|
||||
if (*lend == CON_LINKEND)
|
||||
{
|
||||
con->selendoffset = lend+1 - (conchar_t*)(con->selendline+1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
con->selstartoffset = cur-(conchar_t*)(l+1);
|
||||
}
|
||||
char *Con_CopyConsole(console_t *con, qboolean nomarkup, qboolean onlyiflink)
|
||||
{
|
||||
conchar_t *cur;
|
||||
|
|
|
@ -5358,7 +5358,7 @@ static pixel32_t *Image_Block_Decode(qbyte *fte_restrict in, size_t insize, int
|
|||
sizediff = insize - blockbytes*((w+blockwidth-1)/blockwidth)*((h+blockheight-1)/blockheight);
|
||||
if (sizediff)
|
||||
{
|
||||
Con_Printf("Image_Block_Decode: %s data size is %u, expected %u\n\n", Image_FormatName(encoding), insize, insize-sizediff);
|
||||
Con_Printf("Image_Block_Decode: %s data size is %u, expected %u\n\n", Image_FormatName(encoding), (unsigned int)insize, (unsigned int)(insize-sizediff));
|
||||
if (sizediff < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -162,7 +162,7 @@ qboolean mouseactive;
|
|||
static cvar_t in_joystick = CVARAF("joystick","0", "in_joystick", CVAR_ARCHIVE);
|
||||
static qboolean joy_advancedinit;
|
||||
|
||||
static DWORD joy_flags;
|
||||
static DWORD joy_flags = JOY_RETURNALL|JOY_RETURNCENTERED;
|
||||
#define MAX_JOYSTICKS 8
|
||||
static struct wjoy_s {
|
||||
qboolean isxinput; //xinput device
|
||||
|
|
|
@ -671,7 +671,7 @@ qboolean Key_GetConsoleSelectionBox(console_t *con, int *sx, int *sy, int *ex, i
|
|||
{
|
||||
*sx = *sy = *ex = *ey = 0;
|
||||
|
||||
if (con->buttonsdown == CB_SCROLL)
|
||||
if (con->buttonsdown == CB_SCROLL || con->buttonsdown == CB_SCROLL_R)
|
||||
{
|
||||
//left-mouse.
|
||||
//scroll the console with the mouse. trigger links on release.
|
||||
|
@ -1071,74 +1071,10 @@ void Key_DefaultLinkClicked(console_t *con, char *text, char *info)
|
|||
}
|
||||
}
|
||||
|
||||
#define Key_IsTouchScreen() false
|
||||
void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
|
||||
void Key_HandleConsoleLink(console_t *con, char *buffer)
|
||||
{
|
||||
char *buffer;
|
||||
if (key < 0)
|
||||
key = 0;
|
||||
|
||||
if (key == K_MOUSE1 && con->buttonsdown == CB_SELECT)
|
||||
{
|
||||
if (con->selstartline)
|
||||
{
|
||||
if (con->selstartline == con->selendline && con->selendoffset <= con->selstartoffset+1)
|
||||
con->flags &= ~CONF_KEEPSELECTION;
|
||||
else
|
||||
con->flags |= CONF_KEEPSELECTION;
|
||||
if (con->userdata)
|
||||
{
|
||||
if (con->flags & CONF_BACKSELECTION)
|
||||
{
|
||||
con->userline = con->selendline;
|
||||
con->useroffset = con->selendoffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
con->userline = con->selstartline;
|
||||
con->useroffset = con->selstartoffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
con->buttonsdown = CB_NONE;
|
||||
|
||||
buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard
|
||||
if (buffer)
|
||||
{
|
||||
Sys_SaveClipboard(CBT_SELECTION, buffer);
|
||||
Z_Free(buffer);
|
||||
}
|
||||
}
|
||||
if (key == K_MOUSE1 && con->buttonsdown == CB_SCROLL)
|
||||
{
|
||||
con->buttonsdown = CB_NONE;
|
||||
if (abs(con->mousedown[0] - con->mousecursor[0]) < 5 && abs(con->mousedown[1] - con->mousecursor[1]) < 5)
|
||||
{
|
||||
buffer = Con_CopyConsole(con, false, false);
|
||||
Con_Footerf(con, false, "");
|
||||
if (!buffer)
|
||||
return;
|
||||
if (keydown[K_SHIFT])
|
||||
{
|
||||
int len;
|
||||
len = strlen(buffer);
|
||||
//strip any trailing dots/elipsis
|
||||
while (len > 1 && !strcmp(buffer+len-1, "."))
|
||||
{
|
||||
len-=1;
|
||||
buffer[len] = 0;
|
||||
}
|
||||
//strip any enclosing quotes
|
||||
while (*buffer == '\"' && len > 2 && !strcmp(buffer+len-1, "\""))
|
||||
{
|
||||
len-=2;
|
||||
memmove(buffer, buffer+1, len);
|
||||
buffer[len] = 0;
|
||||
}
|
||||
Key_ConsoleInsert(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (buffer[0] == '^' && buffer[1] == '[')
|
||||
{
|
||||
//looks like it might be a link!
|
||||
|
@ -1179,7 +1115,91 @@ void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
|
|||
end++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define Key_IsTouchScreen() false
|
||||
void Key_ConsoleRelease(console_t *con, int key, unsigned int unicode)
|
||||
{
|
||||
char *buffer;
|
||||
if (key < 0)
|
||||
key = 0;
|
||||
|
||||
if (key == K_MOUSE1 && con->buttonsdown == CB_SELECT)
|
||||
{
|
||||
if (con->selstartline)
|
||||
{
|
||||
if (con->selstartline == con->selendline && con->selendoffset <= con->selstartoffset+1)
|
||||
{
|
||||
con->flags &= ~CONF_KEEPSELECTION;
|
||||
if (keydown[K_LSHIFT] || keydown[K_RSHIFT])
|
||||
;
|
||||
else
|
||||
{
|
||||
buffer = Con_CopyConsole(con, false, true);
|
||||
if (buffer)
|
||||
{
|
||||
Key_HandleConsoleLink(con, buffer);
|
||||
Z_Free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
con->flags |= CONF_KEEPSELECTION;
|
||||
if (con->userdata)
|
||||
{
|
||||
if (con->flags & CONF_BACKSELECTION)
|
||||
{
|
||||
con->userline = con->selendline;
|
||||
con->useroffset = con->selendoffset;
|
||||
}
|
||||
else
|
||||
{
|
||||
con->userline = con->selstartline;
|
||||
con->useroffset = con->selstartoffset;
|
||||
}
|
||||
}
|
||||
|
||||
buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard
|
||||
if (buffer)
|
||||
{
|
||||
Sys_SaveClipboard(CBT_SELECTION, buffer);
|
||||
Z_Free(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
con->buttonsdown = CB_NONE;
|
||||
}
|
||||
if ((key == K_MOUSE1 && con->buttonsdown == CB_SCROLL) || (key == K_MOUSE2 && con->buttonsdown == CB_SCROLL_R))
|
||||
{
|
||||
con->buttonsdown = CB_NONE;
|
||||
if (abs(con->mousedown[0] - con->mousecursor[0]) < 5 && abs(con->mousedown[1] - con->mousecursor[1]) < 5)
|
||||
{
|
||||
buffer = Con_CopyConsole(con, false, false);
|
||||
Con_Footerf(con, false, "");
|
||||
if (!buffer)
|
||||
return;
|
||||
if (keydown[K_SHIFT])
|
||||
{
|
||||
int len;
|
||||
len = strlen(buffer);
|
||||
//strip any trailing dots/elipsis
|
||||
while (len > 1 && !strcmp(buffer+len-1, "."))
|
||||
{
|
||||
len-=1;
|
||||
buffer[len] = 0;
|
||||
}
|
||||
//strip any enclosing quotes
|
||||
while (*buffer == '\"' && len > 2 && !strcmp(buffer+len-1, "\""))
|
||||
{
|
||||
len-=2;
|
||||
memmove(buffer, buffer+1, len);
|
||||
buffer[len] = 0;
|
||||
}
|
||||
Key_ConsoleInsert(buffer);
|
||||
}
|
||||
else
|
||||
Key_HandleConsoleLink(con, buffer);
|
||||
Z_Free(buffer);
|
||||
}
|
||||
else
|
||||
|
@ -1553,6 +1573,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
|
|||
qboolean ctrl = keydown[K_LCTRL] || keydown[K_RCTRL];
|
||||
qboolean shift = keydown[K_LSHIFT] || keydown[K_RSHIFT];
|
||||
int rkey = key;
|
||||
char *buffer;
|
||||
|
||||
//weirdness for the keypad.
|
||||
if ((unicode >= '0' && unicode <= '9') || unicode == '.' || key < 0)
|
||||
|
@ -1576,6 +1597,7 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
|
|||
|
||||
if ((key == K_MOUSE1 || key == K_MOUSE2))
|
||||
{
|
||||
int olddown[2] = {con->mousedown[0],con->mousedown[1]};
|
||||
if (con->flags & CONF_ISWINDOW)
|
||||
if (con->mousecursor[0] < -8 || con->mousecursor[1] < 0 || con->mousecursor[0] > con->wnd_w || con->mousecursor[1] > con->wnd_h)
|
||||
return true;
|
||||
|
@ -1609,8 +1631,12 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
|
|||
{
|
||||
if (con->redirect && con->redirect(con, unicode, key))
|
||||
return true;
|
||||
con->buttonsdown = CB_COPY;
|
||||
|
||||
con->flags &= ~CONF_KEEPSELECTION;
|
||||
if (Key_IsTouchScreen()) //o.O mouse2+touchscreen? really?
|
||||
con->buttonsdown = CB_COPY;
|
||||
else
|
||||
con->buttonsdown = CB_SCROLL_R;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1625,13 +1651,38 @@ qboolean Key_Console (console_t *con, int key, unsigned int unicode)
|
|||
{
|
||||
if (con->redirect && con->redirect(con, unicode, key))
|
||||
return true;
|
||||
if (Key_IsTouchScreen())
|
||||
if (Key_IsTouchScreen() || con->mousecursor[0] > ((con->flags & CONF_ISWINDOW)?con->wnd_w-16:vid.width)-8)
|
||||
{ //just scroll the console up/down
|
||||
con->buttonsdown = CB_SCROLL;
|
||||
}
|
||||
else
|
||||
{ //selecting text. woo.
|
||||
if (realtime < con->mousedowntime + 0.4
|
||||
&& con->mousecursor[0] >= olddown[0]-3 && con->mousecursor[0] <= olddown[0]+3
|
||||
&& con->mousecursor[1] >= olddown[1]-3 && con->mousecursor[1] <= olddown[1]+3
|
||||
)
|
||||
{ //this was a double-click... expand the selection to the entire word
|
||||
//FIXME: detect tripple-clicks to select the entire line
|
||||
Con_ExpandConsoleSelection(con);
|
||||
con->flags |= CONF_KEEPSELECTION;
|
||||
|
||||
buffer = Con_CopyConsole(con, true, false); //don't keep markup if we're copying to the clipboard
|
||||
if (buffer)
|
||||
{
|
||||
Sys_SaveClipboard(CBT_SELECTION, buffer);
|
||||
Z_Free(buffer);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
con->mousedowntime = realtime;
|
||||
|
||||
con->buttonsdown = CB_SELECT;
|
||||
|
||||
if (shift)
|
||||
{
|
||||
con->mousedown[0] = olddown[0];
|
||||
con->mousedown[1] = olddown[1];
|
||||
}
|
||||
}
|
||||
con->flags &= ~CONF_KEEPSELECTION;
|
||||
}
|
||||
|
|
|
@ -424,7 +424,7 @@ typedef struct rendererinfo_s {
|
|||
void (*VID_SwapBuffers) (void); //force a buffer swap, regardless of what's displayed.
|
||||
qboolean (*VID_ApplyGammaRamps) (unsigned int size, unsigned short *ramps);
|
||||
|
||||
void *(*VID_CreateCursor) (const char *filename, float hotx, float hoty, float scale); //may be null, stub returns null
|
||||
void *(*VID_CreateCursor) (const qbyte *imagedata, int width, int height, uploadfmt_t format, float hotx, float hoty, float scale); //may be null, stub returns null
|
||||
qboolean (*VID_SetCursor) (void *cursor); //may be null
|
||||
void (*VID_DestroyCursor) (void *cursor); //may be null
|
||||
|
||||
|
|
|
@ -2467,8 +2467,8 @@ static void QCBUILTIN PF_cs_getstati(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
int stnum = G_FLOAT(OFS_PARM0);
|
||||
if (stnum < 0 || stnum >= MAX_CL_STATS)
|
||||
{
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
PR_RunWarning(prinst, "invalid stat index");
|
||||
G_INT(OFS_RETURN) = 0;
|
||||
PR_RunWarning(prinst, "PF_cs_getstati: invalid stat index (%i)\n", stnum);
|
||||
}
|
||||
else if (stnum >= 128 && csqc_isdarkplaces && cls.protocol != CP_NETQUAKE && !CPNQ_IS_DP)
|
||||
{ //dpp7 stats are fucked.
|
||||
|
@ -2486,7 +2486,7 @@ static void QCBUILTIN PF_cs_getstatbits(pubprogfuncs_t *prinst, struct globalvar
|
|||
if (stnum < 0 || stnum >= MAX_CL_STATS)
|
||||
{
|
||||
G_FLOAT(OFS_RETURN) = 0;
|
||||
PR_RunWarning(prinst, "invalid stat index");
|
||||
PR_RunWarning(prinst, "PF_cs_getstatbits: invalid stat index (%i)\n", stnum);
|
||||
}
|
||||
else if (prinst->callargc > 1)
|
||||
{
|
||||
|
@ -2515,14 +2515,14 @@ static void QCBUILTIN PF_cs_getstats(pubprogfuncs_t *prinst, struct globalvars_s
|
|||
if (stnum < 0 || stnum >= MAX_CL_STATS)
|
||||
{
|
||||
G_INT(OFS_RETURN) = 0;
|
||||
PR_RunWarning(prinst, "invalid stat index");
|
||||
PR_RunWarning(prinst, "PF_cs_getstats: invalid stat index (%i)\n", stnum);
|
||||
}
|
||||
else if (cls.fteprotocolextensions & PEXT_CSQC)
|
||||
RETURN_TSTRING(csqc_playerview->statsstr[stnum]);
|
||||
else if (stnum >= MAX_CL_STATS-3)
|
||||
else if (stnum >= MAX_CL_STATS-3) //we'll be reading the following 3 extra stats too.
|
||||
{
|
||||
G_INT(OFS_RETURN) = 0;
|
||||
PR_RunWarning(prinst, "invalid stat index");
|
||||
PR_RunWarning(prinst, "PF_cs_getstats: invalid packed-string stat index (%i)\n", stnum);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5751,7 +5751,7 @@ static void QCBUILTIN PF_cs_getplayerstat(pubprogfuncs_t *prinst, struct globalv
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void CL_CalcCrouch (playerview_t *pv);
|
||||
static void QCBUILTIN PF_V_CalcRefdef(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{ //this function is essentially an overcomplicated way to shirk from defining your own view bobbing.
|
||||
csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0);
|
||||
|
@ -5777,7 +5777,7 @@ static void QCBUILTIN PF_V_CalcRefdef(pubprogfuncs_t *prinst, struct globalvars_
|
|||
|
||||
CL_DecayLights ();
|
||||
|
||||
CL_ClearEntityLists();
|
||||
// CL_ClearEntityLists();
|
||||
|
||||
V_ClearRefdef(csqc_playerview);
|
||||
r_refdef.drawsbar = false; //csqc defaults to no sbar.
|
||||
|
@ -5787,6 +5787,7 @@ static void QCBUILTIN PF_V_CalcRefdef(pubprogfuncs_t *prinst, struct globalvars_
|
|||
VectorCopy(ent->v->origin, csqc_playerview->simorg);
|
||||
VectorCopy (ent->v->velocity, csqc_playerview->simvel);
|
||||
csqc_playerview->onground = !!((int)ent->v->flags & FL_ONGROUND);
|
||||
CL_CalcCrouch (csqc_playerview);
|
||||
V_CalcRefdef(csqc_playerview); //set up the defaults
|
||||
|
||||
VectorCopy(savedvel, csqc_playerview->simvel);
|
||||
|
@ -7094,10 +7095,19 @@ static void *CSQC_FindMainProgs(size_t *sz, const char *name, unsigned int check
|
|||
if (!file)
|
||||
{
|
||||
const char *progsname = InfoBuf_ValueForKey(&cl.serverinfo, "*csprogsname");
|
||||
if (*progsname && cls.state)
|
||||
file = COM_LoadTempFile (progsname, FSLF_IGNOREPURE, sz);
|
||||
if (!file && strcmp(progsname, "csprogs.dat"))
|
||||
file = COM_LoadTempFile ("csprogs.dat", FSLF_IGNOREPURE, sz);
|
||||
flocation_t loc={0};
|
||||
vfsfile_t *f;
|
||||
qboolean found = false;
|
||||
if (!found && *progsname && cls.state)
|
||||
found = FS_FLocateFile(progsname, FSLF_IGNOREPURE, &loc);
|
||||
if (!found && strcmp(progsname, "csprogs.dat"))
|
||||
found = FS_FLocateFile("csprogs.dat", FSLF_IGNOREPURE, &loc);
|
||||
if (found && (f=FS_OpenReadLocation(&loc)))
|
||||
{
|
||||
*sz = VFS_GETLEN(f);
|
||||
file = Hunk_TempAlloc (*sz);
|
||||
VFS_READ(f, file, *sz);
|
||||
VFS_CLOSE(f);
|
||||
|
||||
if (file && !cls.demoplayback) //allow them to use csprogs.dat if playing a demo, and don't care about the checksum
|
||||
{
|
||||
|
@ -7112,7 +7122,7 @@ static void *CSQC_FindMainProgs(size_t *sz, const char *name, unsigned int check
|
|||
//also kinda irrelevant with sv_pure.
|
||||
//FIXME: don't back up if it was in a package.
|
||||
#ifndef FTE_TARGET_WEB
|
||||
if (file
|
||||
if (file && !sv_state && !FS_WhichPackForLocation(&loc, false)
|
||||
#if !defined(CLIENTONLY) && defined(MVD_RECORDING)
|
||||
&& !sv_demo_write_csqc.ival
|
||||
#endif
|
||||
|
@ -7123,6 +7133,7 @@ static void *CSQC_FindMainProgs(size_t *sz, const char *name, unsigned int check
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return file;
|
||||
}
|
||||
qboolean CSQC_CheckDownload(const char *name, unsigned int checksum, size_t checksize)
|
||||
|
|
|
@ -1294,7 +1294,7 @@ void R2D_PolyBlend (void)
|
|||
return;
|
||||
|
||||
|
||||
if (bordersize && bordersize < r_refdef.vrect.width && bordersize < r_refdef.vrect.height)
|
||||
if (r_refdef.playerview->bordertint[3])
|
||||
{
|
||||
vec2_t points[4];
|
||||
vec2_t tcoords[4];
|
||||
|
|
|
@ -4228,6 +4228,11 @@ static void Sys_QueryDesktopParameters(void)
|
|||
|
||||
void Sys_Sleep (double seconds)
|
||||
{
|
||||
if (seconds < 0)
|
||||
seconds = 0;
|
||||
if (seconds > 1)
|
||||
seconds = 1;
|
||||
Con_Printf("Sys_Sleep%g\n", seconds);
|
||||
Sleep(seconds * 1000);
|
||||
}
|
||||
|
||||
|
@ -4235,57 +4240,19 @@ void Sys_Sleep (double seconds)
|
|||
|
||||
|
||||
HCURSOR hArrowCursor, hCustomCursor;
|
||||
void *WIN_CreateCursor(const char *filename, float hotx, float hoty, float scale)
|
||||
void *WIN_CreateCursor(const qbyte *imagedata, int width, int height, uploadfmt_t format, float hotx, float hoty, float scale)
|
||||
{
|
||||
int width, height;
|
||||
BITMAPV4HEADER bi;
|
||||
DWORD x,y;
|
||||
HCURSOR hAlphaCursor = NULL;
|
||||
ICONINFO ii;
|
||||
HDC maindc;
|
||||
|
||||
qbyte *rgbadata, *rgbadata_start, *bgradata, *bgradata_start;
|
||||
uploadfmt_t format;
|
||||
void *filedata;
|
||||
int filelen;
|
||||
if (!filename || !*filename)
|
||||
const qbyte *rgbadata;
|
||||
qbyte *bgradata, *bgradata_start;
|
||||
void *scaled = NULL;
|
||||
if (!imagedata)
|
||||
return NULL;
|
||||
filelen = FS_LoadFile(filename, &filedata);
|
||||
if (!filedata)
|
||||
return NULL;
|
||||
|
||||
rgbadata_start = ReadRawImageFile(filedata, filelen, &width, &height, &format, true, "cursor");
|
||||
FS_FreeFile(filedata);
|
||||
if (!rgbadata_start)
|
||||
return NULL;
|
||||
|
||||
if ((format==PTI_RGBX8 || format==PTI_LLLX8) && !strchr(filename, ':'))
|
||||
{ //people seem to insist on using jpgs, which don't have alpha.
|
||||
//screw over the alpha channel if needed.
|
||||
unsigned int alpha_width, alpha_height, p;
|
||||
char aname[MAX_QPATH];
|
||||
unsigned char *alphadata;
|
||||
char *alph;
|
||||
size_t alphsize;
|
||||
char ext[8];
|
||||
uploadfmt_t alphaformat;
|
||||
COM_StripExtension(filename, aname, sizeof(aname));
|
||||
COM_FileExtension(filename, ext, sizeof(ext));
|
||||
Q_strncatz(aname, "_alpha.", sizeof(aname));
|
||||
Q_strncatz(aname, ext, sizeof(aname));
|
||||
alphsize = FS_LoadFile(filename, (void**)&alph);
|
||||
if (alph)
|
||||
{
|
||||
if ((alphadata = ReadRawImageFile(alph, alphsize, &alpha_width, &alpha_height, &alphaformat, true, aname)))
|
||||
{
|
||||
if (alpha_width == width && alpha_height == height)
|
||||
for (p = 0; p < alpha_width*alpha_height; p++)
|
||||
rgbadata_start[(p<<2) + 3] = (alphadata[(p<<2) + 0] + alphadata[(p<<2) + 1] + alphadata[(p<<2) + 2])/3;
|
||||
BZ_Free(alphadata);
|
||||
}
|
||||
FS_FreeFile(alph);
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: CreateIconIndirect does NOT understand DPI scaling, and will show a tiny cursor in such cases.
|
||||
// we should rescale scale by vid_conautoscale etc.
|
||||
|
@ -4298,11 +4265,10 @@ void *WIN_CreateCursor(const char *filename, float hotx, float hoty, float scale
|
|||
if (nw <= 0 || nh <= 0 || nw > 128 || nh > 128) //don't go crazy.
|
||||
return NULL;
|
||||
nd = BZ_Malloc(nw*nh*4);
|
||||
Image_ResampleTexture((unsigned int*)rgbadata_start, width, height, (unsigned int*)nd, nw, nh);
|
||||
Image_ResampleTexture((unsigned int*)imagedata, width, height, (unsigned int*)nd, nw, nh);
|
||||
width = nw;
|
||||
height = nh;
|
||||
BZ_Free(rgbadata_start);
|
||||
rgbadata_start = nd;
|
||||
imagedata = scaled = nd;
|
||||
}
|
||||
|
||||
memset(&bi,0, sizeof(bi));
|
||||
|
@ -4327,11 +4293,11 @@ void *WIN_CreateCursor(const char *filename, float hotx, float hoty, float scale
|
|||
|
||||
if (!ii.hbmColor)
|
||||
{
|
||||
BZ_Free(rgbadata_start);
|
||||
BZ_Free(scaled);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (rgbadata=rgbadata_start,y=0;y<height;y++)
|
||||
for (rgbadata=imagedata,y=0;y<height;y++)
|
||||
{
|
||||
bgradata = bgradata_start + (height-1-y)*width*4;
|
||||
for (x=0;x<width;x++)
|
||||
|
@ -4345,7 +4311,7 @@ void *WIN_CreateCursor(const char *filename, float hotx, float hoty, float scale
|
|||
}
|
||||
}
|
||||
|
||||
BZ_Free(rgbadata_start);
|
||||
BZ_Free(scaled);
|
||||
|
||||
ii.fIcon = FALSE; // Change fIcon to TRUE to create an alpha icon
|
||||
ii.xHotspot = hotx;
|
||||
|
|
|
@ -784,7 +784,7 @@ void V_CalcBlend (float *hw_blend)
|
|||
|
||||
if (j == CSHIFT_SERVER)
|
||||
{
|
||||
/*server blend always goes into sw, ALWAYS*/
|
||||
/*server blend always goes into sw, ALWAYS. hardware is too unreliable.*/
|
||||
blend = pv->screentint;
|
||||
}
|
||||
else
|
||||
|
@ -792,7 +792,7 @@ void V_CalcBlend (float *hw_blend)
|
|||
/*flashing things should not change hardware gamma ramps - windows is too slow*/
|
||||
/*splitscreen should only use hw gamma ramps if they're all equal, and they're probably not*/
|
||||
/*hw blends may also not be supported or may be disabled*/
|
||||
if (gl_cshiftenabled.value)
|
||||
if (gl_cshiftenabled.ival == 2)
|
||||
blend = pv->bordertint; //show the colours only on the borders so we don't blind ourselves
|
||||
else if (j == CSHIFT_BONUS || j == CSHIFT_DAMAGE || gl_nohwblend.ival || !r2d_canhwgamma || cl.splitclients > 1)
|
||||
blend = pv->screentint;
|
||||
|
|
|
@ -27,7 +27,7 @@ void *wadmutex;
|
|||
void Wads_Flush (void){}
|
||||
qboolean Wad_NextDownload (void){return true;}
|
||||
void *W_GetLumpName (const char *name, size_t *size, qbyte *type) {return NULL;}
|
||||
qbyte *W_GetTexture(const char *name, int *width, int *height, qboolean *usesalpha){return NULL;}
|
||||
qbyte *W_GetTexture(const char *name, int *width, int *height, uploadfmt_t *format){return NULL;}
|
||||
void W_LoadWadFile (char *filename){}
|
||||
void W_Shutdown (void){}
|
||||
void CL_Skygroup_f(void){}
|
||||
|
|
|
@ -128,7 +128,7 @@ extern qboolean mouseinitialized;
|
|||
//extern HANDLE hinput, houtput;
|
||||
|
||||
extern HCURSOR hArrowCursor, hCustomCursor;
|
||||
void *WIN_CreateCursor(const char *filename, float hotx, float hoty, float scale);
|
||||
void *WIN_CreateCursor(const qbyte *imagedata, int width, int height, uploadfmt_t format, float hotx, float hoty, float scale);
|
||||
qboolean WIN_SetCursor(void *cursor);
|
||||
void WIN_DestroyCursor(void *cursor);
|
||||
void WIN_WindowCreated(HWND window);
|
||||
|
|
|
@ -368,6 +368,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#define HAVE_CLIENT
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_SERVER
|
||||
#undef MVD_RECORDING
|
||||
#endif
|
||||
|
||||
//software rendering is just too glitchy, don't use it - unless its the only choice.
|
||||
#if defined(SWQUAKE) && !defined(_DEBUG) && !defined(__DJGPP__)
|
||||
#undef SWQUAKE
|
||||
|
@ -620,10 +624,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#undef USE_EGL
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_WINSSPI) || defined(HAVE_GNUTLS)
|
||||
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) || defined(HAVE_WINSSPI)
|
||||
#define HAVE_SSL
|
||||
#endif
|
||||
#if defined(HAVE_GNUTLS) || defined(HAVE_WINSSPI)
|
||||
#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL) || defined(HAVE_WINSSPI)
|
||||
//FIXME: HAVE_WINSSPI does not work as a server.
|
||||
//FIXME: advertising dtls without a valid certificate will probably bug out if a client tries to auto-upgrade.
|
||||
//FIXME: we don't cache server certs
|
||||
|
|
|
@ -534,7 +534,7 @@ void FS_ReferenceControl(unsigned int refflag, unsigned int resetflags);
|
|||
typedef struct vfsfile_s
|
||||
{
|
||||
int (QDECL *ReadBytes) (struct vfsfile_s *file, void *buffer, int bytestoread);
|
||||
int (QDECL *WriteBytes) (struct vfsfile_s *file, const void *buffer, int bytestoread);
|
||||
int (QDECL *WriteBytes) (struct vfsfile_s *file, const void *buffer, int bytestowrite);
|
||||
qboolean (QDECL *Seek) (struct vfsfile_s *file, qofs_t pos); //returns false for error
|
||||
qofs_t (QDECL *Tell) (struct vfsfile_s *file);
|
||||
qofs_t (QDECL *GetLen) (struct vfsfile_s *file); //could give some lag
|
||||
|
@ -812,6 +812,8 @@ qbyte COM_BlockSequenceCRCByte (qbyte *base, int length, int sequence);
|
|||
qbyte Q2COM_BlockSequenceCRCByte (qbyte *base, int length, int sequence);
|
||||
|
||||
typedef size_t hashfunc_t(unsigned char *digest, size_t maxdigestsize, size_t numstrings, const unsigned char **strings, size_t *stringlens);
|
||||
#define SHA1 SHA1_quake
|
||||
#define HMAC HMAC_quake
|
||||
hashfunc_t SHA1_m;
|
||||
//int SHA1_m(char *digest, size_t maxdigestsize, size_t numstrings, const char **strings, size_t *stringlens);
|
||||
//#define SHA1(digest,maxdigestsize,string,stringlen) SHA1_m(digest, maxdigestsize, 1, &string, &stringlen)
|
||||
|
|
|
@ -119,6 +119,7 @@
|
|||
#define HAVE_PACKET //we can send unreliable messages!
|
||||
#define HAVE_TCP //we can create/accept TCP connections.
|
||||
#define HAVE_GNUTLS //on linux
|
||||
//#define HAVE_OPENSSL //on linux. hardlinked, so typically set only via the makefile.
|
||||
#define HAVE_WINSSPI //on windows
|
||||
#define FTPSERVER //sv_ftp cvar.
|
||||
#define WEBCLIENT //uri_get+any internal downloads etc
|
||||
|
|
|
@ -113,26 +113,35 @@ typedef struct conline_s {
|
|||
} conline_t;
|
||||
|
||||
//majority of these are mututally exclusive. the bits allow multiple.
|
||||
#define CB_NONE 0
|
||||
#define CB_SCROLL 1
|
||||
#define CB_COPY 2
|
||||
#define CB_CLOSE 3
|
||||
#define CB_MOVE 4
|
||||
#define CB_ACTIONBAR 5
|
||||
#define CB_SELECT 6
|
||||
#define CB_SIZELEFT (1u<<29)
|
||||
#define CB_SIZERIGHT (1u<<30)
|
||||
#define CB_SIZEBOTTOM (1u<<31)
|
||||
#define CONF_HIDDEN 1 /*do not show in the console list (unless active)*/
|
||||
#define CONF_NOTIFY 2 /*text printed to console also appears as notify lines*/
|
||||
#define CONF_NOTIFY_BOTTOM 4 /*align the bottom*/
|
||||
#define CONF_NOTIFY_RIGHT 8
|
||||
//#define CONF_NOTIMES 16
|
||||
#define CONF_KEYFOCUSED 32
|
||||
#define CONF_ISWINDOW 64
|
||||
#define CONF_NOWRAP 128
|
||||
#define CONF_KEEPSELECTION 256 //there's text selected, keep it selected.
|
||||
#define CONF_BACKSELECTION 512 //a hint that the text was selected from the end
|
||||
enum
|
||||
{
|
||||
CB_NONE = 0,
|
||||
CB_SCROLL = 1,
|
||||
CB_COPY = 2,
|
||||
CB_CLOSE = 3,
|
||||
CB_MOVE = 4,
|
||||
CB_ACTIONBAR = 5,
|
||||
CB_SELECT = 6,
|
||||
CB_SCROLL_R = 7,
|
||||
|
||||
//the flags part
|
||||
CB_SIZELEFT = (1u<<29),
|
||||
CB_SIZERIGHT = (1u<<30),
|
||||
CB_SIZEBOTTOM = (1u<<31),
|
||||
};
|
||||
enum
|
||||
{
|
||||
CONF_HIDDEN = 1u<<0, /*do not show in the console list (unless active)*/
|
||||
CONF_NOTIFY = 1u<<1, /*text printed to console also appears as notify lines*/
|
||||
CONF_NOTIFY_BOTTOM = 1u<<2, /*align the bottom*/
|
||||
CONF_NOTIFY_RIGHT = 1u<<3,
|
||||
//CONF_NOTIMES = 1u<<4,
|
||||
CONF_KEYFOCUSED = 1u<<5,
|
||||
CONF_ISWINDOW = 1u<<6,
|
||||
CONF_NOWRAP = 1u<<7,
|
||||
CONF_KEEPSELECTION = 1u<<8, //there's text selected, keep it selected.
|
||||
CONF_BACKSELECTION = 1u<<9, //a hint that the text was selected from the end
|
||||
};
|
||||
typedef struct console_s
|
||||
{
|
||||
int id;
|
||||
|
@ -186,6 +195,7 @@ typedef struct console_s
|
|||
int mousedown[2]; //x,y position that the current buttons were clicked.
|
||||
unsigned int buttonsdown;
|
||||
int mousecursor[2]; //x,y
|
||||
float mousedowntime; //time mouse1 last went down, to detect double-clicks
|
||||
|
||||
struct console_s *next;
|
||||
} console_t;
|
||||
|
@ -220,6 +230,7 @@ void Con_History_Load(void);
|
|||
struct font_s;
|
||||
void Con_DrawOneConsole(console_t *con, qboolean focused, struct font_s *font, float fx, float fy, float fsx, float fsy, float lineagelimit);
|
||||
void Con_DrawConsole (int lines, qboolean noback);
|
||||
void Con_ExpandConsoleSelection(console_t *con);
|
||||
char *Con_CopyConsole(console_t *con, qboolean nomarkup, qboolean onlyiflink);
|
||||
void Con_Print (const char *txt);
|
||||
void Con_CenterPrint(const char *txt);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
void FS_BeginManifestUpdates(void);
|
||||
static void QDECL fs_game_callback(cvar_t *var, char *oldvalue);
|
||||
static void COM_InitHomedir(ftemanifest_t *man);
|
||||
hashtable_t filesystemhash;
|
||||
qboolean com_fschanged = true;
|
||||
qboolean com_installer = false;
|
||||
|
@ -550,7 +551,7 @@ static qboolean FS_Manifest_ParseTokens(ftemanifest_t *man)
|
|||
Z_Free(man->defaultexec);
|
||||
man->defaultexec = Z_StrDup(Cmd_Argv(1));
|
||||
}
|
||||
else if (!Q_strcasecmp(cmd, "bind") || !Q_strcasecmp(cmd, "set") || !Q_strcasecmp(cmd, "seta"))
|
||||
else if (!Q_strcasecmp(cmd, "bind") || !Q_strcasecmp(cmd, "set") || !Q_strcasecmp(cmd, "seta") || !Q_strcasecmp(cmd, "alias"))
|
||||
{
|
||||
Z_StrCat(&man->defaultoverrides, va("%s %s\n", Cmd_Argv(0), Cmd_Args()));
|
||||
}
|
||||
|
@ -5607,6 +5608,7 @@ qboolean FS_ChangeGame(ftemanifest_t *man, qboolean allowreloadconfigs, qboolean
|
|||
|
||||
{
|
||||
qboolean oldhome = com_homepathenabled;
|
||||
COM_InitHomedir(man);
|
||||
com_homepathenabled = com_homepathusable;
|
||||
|
||||
if (man->disablehomedir && !COM_CheckParm("-usehome"))
|
||||
|
@ -6145,56 +6147,21 @@ void FS_ArbitraryFile_c(int argn, const char *partial, struct xcommandargcomplet
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
COM_InitFilesystem
|
||||
|
||||
note: does not actually load any packs, just makes sure the basedir+cvars+etc is set up. vfs_fopens will still fail.
|
||||
================
|
||||
*/
|
||||
void COM_InitFilesystem (void)
|
||||
static void COM_InitHomedir(ftemanifest_t *man)
|
||||
{
|
||||
int i;
|
||||
|
||||
char *ev;
|
||||
qboolean usehome;
|
||||
|
||||
FS_RegisterDefaultFileSystems();
|
||||
|
||||
Cmd_AddCommand("fs_restart", FS_ReloadPackFiles_f);
|
||||
Cmd_AddCommandD("fs_changegame", FS_ChangeGame_f, "Switch between different manifests (or registered games)");
|
||||
Cmd_AddCommandD("fs_changemod", FS_ChangeMod_f, "Provides the backend functionality of a transient online installer. Eg, for quaddicted's map/mod database.");
|
||||
Cmd_AddCommand("fs_showmanifest", FS_ShowManifest_f);
|
||||
Cmd_AddCommand ("fs_flush", COM_RefreshFSCache_f);
|
||||
Cmd_AddCommandAD("dir", COM_Dir_f, FS_ArbitraryFile_c, "Displays filesystem listings. Accepts wildcards."); //q3 like
|
||||
Cmd_AddCommandD("path", COM_Path_f, "prints a list of current search paths.");
|
||||
Cmd_AddCommandAD("flocate", COM_Locate_f, FS_ArbitraryFile_c, "Searches for a named file, and displays where it can be found in the OS's filesystem"); //prints the pak or whatever where this file can be found.
|
||||
|
||||
|
||||
//
|
||||
// -basedir <path>
|
||||
// Overrides the system supplied base directory (under id1)
|
||||
//
|
||||
i = COM_CheckParm ("-basedir");
|
||||
if (i && i < com_argc-1)
|
||||
strcpy (com_gamepath, com_argv[i+1]);
|
||||
else
|
||||
strcpy (com_gamepath, host_parms.basedir);
|
||||
|
||||
FS_CleanDir(com_gamepath, sizeof(com_gamepath));
|
||||
|
||||
|
||||
Cvar_Register(&cfg_reload_on_gamedir, "Filesystem");
|
||||
Cvar_Register(&com_fs_cache, "Filesystem");
|
||||
Cvar_Register(&fs_gamename, "Filesystem");
|
||||
Cvar_Register(&pm_downloads_url, "Filesystem");
|
||||
Cvar_Register(&pm_autoupdate, "Filesystem");
|
||||
Cvar_Register(&com_protocolname, "Server Info");
|
||||
Cvar_Register(&com_protocolversion, "Server Info");
|
||||
Cvar_Register(&fs_game, "Filesystem");
|
||||
#ifdef Q2SERVER
|
||||
Cvar_Register(&fs_gamedir, "Filesystem");
|
||||
Cvar_Register(&fs_basedir, "Filesystem");
|
||||
//FIXME: this should come from the manifest, as fte_GAME or something
|
||||
#ifdef _WIN32
|
||||
#define HOMESUBDIR FULLENGINENAME
|
||||
#else
|
||||
#ifdef GAME_SHORTNAME
|
||||
#define HOMESUBDIR GAME_SHORTNAME
|
||||
#else
|
||||
#define HOMESUBDIR "fte"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
usehome = false;
|
||||
|
@ -6221,7 +6188,7 @@ void COM_InitFilesystem (void)
|
|||
if (dSHGetFolderPathW(NULL, 0x5, NULL, 0, wfolder) == S_OK)
|
||||
{
|
||||
narrowen(folder, sizeof(folder), wfolder);
|
||||
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/My Games/%s/", folder, FULLENGINENAME);
|
||||
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/My Games/%s/", folder, HOMESUBDIR);
|
||||
}
|
||||
}
|
||||
// if (shfolder)
|
||||
|
@ -6231,12 +6198,12 @@ void COM_InitFilesystem (void)
|
|||
{
|
||||
ev = getenv("USERPROFILE");
|
||||
if (ev)
|
||||
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/My Documents/My Games/%s/", ev, FULLENGINENAME);
|
||||
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/My Documents/My Games/%s/", ev, HOMESUBDIR);
|
||||
}
|
||||
|
||||
#ifdef NPFTE
|
||||
if (!*com_homepath)
|
||||
Q_snprintfz(com_homepath, sizeof(com_homepath), "/%s/", FULLENGINENAME);
|
||||
Q_snprintfz(com_homepath, sizeof(com_homepath), "/%s/", HOMESUBDIR);
|
||||
//as a browser plugin, always use their home directory
|
||||
usehome = true;
|
||||
#else
|
||||
|
@ -6319,29 +6286,33 @@ void COM_InitFilesystem (void)
|
|||
char newhome[MAX_OSPATH];
|
||||
struct stat s;
|
||||
|
||||
#ifdef GAME_SHORTNAME
|
||||
#define HOMESUBDIR GAME_SHORTNAME
|
||||
#else
|
||||
#define HOMESUBDIR "fte" //FIXME: this should come from the manifest, as fte_GAME or something
|
||||
#endif
|
||||
|
||||
if (ev[strlen(ev)-1] == '/')
|
||||
Q_snprintfz(oldhome, sizeof(oldhome), "%s."HOMESUBDIR"/", ev);
|
||||
else
|
||||
Q_snprintfz(oldhome, sizeof(oldhome), "%s/."HOMESUBDIR"/", ev);
|
||||
|
||||
xdghome = getenv("XDG_DATA_HOME");
|
||||
if (!xdghome || !*xdghome)
|
||||
xdghome = va("%s/.local/share", ev);
|
||||
if (man && man->installation)
|
||||
{
|
||||
if (xdghome[strlen(xdghome)-1] == '/')
|
||||
Q_snprintfz(newhome, sizeof(newhome), "%s"HOMESUBDIR"/", xdghome);
|
||||
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s%s/", xdghome, *man->installation?man->installation:HOMESUBDIR);
|
||||
else
|
||||
Q_snprintfz(newhome, sizeof(newhome), "%s/"HOMESUBDIR"/", xdghome);
|
||||
Q_snprintfz(com_homepath, sizeof(com_homepath), "%s/%s/", xdghome, *man->installation?man->installation:HOMESUBDIR);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xdghome[strlen(xdghome)-1] == '/')
|
||||
Q_snprintfz(newhome, sizeof(newhome), "%s%s/", xdghome, HOMESUBDIR);
|
||||
else
|
||||
Q_snprintfz(newhome, sizeof(newhome), "%s/%s/", xdghome, HOMESUBDIR);
|
||||
|
||||
if (ev[strlen(ev)-1] == '/')
|
||||
Q_snprintfz(oldhome, sizeof(oldhome), "%s.%s/", ev, HOMESUBDIR);
|
||||
else
|
||||
Q_snprintfz(oldhome, sizeof(oldhome), "%s/.%s/", ev, HOMESUBDIR);
|
||||
|
||||
if (stat(newhome, &s) == -1 && stat(oldhome, &s) != -1)
|
||||
Q_strncpyz(com_homepath, oldhome, sizeof(com_homepath));
|
||||
else
|
||||
Q_strncpyz(com_homepath, newhome, sizeof(com_homepath));
|
||||
}
|
||||
usehome = true; // always use home on unix unless told not to
|
||||
}
|
||||
#endif
|
||||
|
@ -6364,6 +6335,60 @@ void COM_InitFilesystem (void)
|
|||
|
||||
com_homepathenabled = com_homepathusable;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
COM_InitFilesystem
|
||||
|
||||
note: does not actually load any packs, just makes sure the basedir+cvars+etc is set up. vfs_fopens will still fail.
|
||||
================
|
||||
*/
|
||||
void COM_InitFilesystem (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
FS_RegisterDefaultFileSystems();
|
||||
|
||||
Cmd_AddCommand("fs_restart", FS_ReloadPackFiles_f);
|
||||
Cmd_AddCommandD("fs_changegame", FS_ChangeGame_f, "Switch between different manifests (or registered games)");
|
||||
Cmd_AddCommandD("fs_changemod", FS_ChangeMod_f, "Provides the backend functionality of a transient online installer. Eg, for quaddicted's map/mod database.");
|
||||
Cmd_AddCommand("fs_showmanifest", FS_ShowManifest_f);
|
||||
Cmd_AddCommand ("fs_flush", COM_RefreshFSCache_f);
|
||||
Cmd_AddCommandAD("dir", COM_Dir_f, FS_ArbitraryFile_c, "Displays filesystem listings. Accepts wildcards."); //q3 like
|
||||
Cmd_AddCommandD("path", COM_Path_f, "prints a list of current search paths.");
|
||||
Cmd_AddCommandAD("flocate", COM_Locate_f, FS_ArbitraryFile_c, "Searches for a named file, and displays where it can be found in the OS's filesystem"); //prints the pak or whatever where this file can be found.
|
||||
|
||||
|
||||
//
|
||||
// -basedir <path>
|
||||
// Overrides the system supplied base directory (under id1)
|
||||
//
|
||||
i = COM_CheckParm ("-basedir");
|
||||
if (i && i < com_argc-1)
|
||||
strcpy (com_gamepath, com_argv[i+1]);
|
||||
else
|
||||
strcpy (com_gamepath, host_parms.basedir);
|
||||
|
||||
FS_CleanDir(com_gamepath, sizeof(com_gamepath));
|
||||
|
||||
|
||||
Cvar_Register(&cfg_reload_on_gamedir, "Filesystem");
|
||||
Cvar_Register(&com_fs_cache, "Filesystem");
|
||||
Cvar_Register(&fs_gamename, "Filesystem");
|
||||
Cvar_Register(&pm_downloads_url, "Filesystem");
|
||||
Cvar_Register(&pm_autoupdate, "Filesystem");
|
||||
Cvar_Register(&com_protocolname, "Server Info");
|
||||
Cvar_Register(&com_protocolversion, "Server Info");
|
||||
Cvar_Register(&fs_game, "Filesystem");
|
||||
#ifdef Q2SERVER
|
||||
Cvar_Register(&fs_gamedir, "Filesystem");
|
||||
Cvar_Register(&fs_basedir, "Filesystem");
|
||||
#endif
|
||||
|
||||
COM_InitHomedir(NULL);
|
||||
|
||||
fs_readonly = COM_CheckParm("-readonly");
|
||||
|
||||
fs_thread_mutex = Sys_CreateMutex();
|
||||
|
|
|
@ -183,6 +183,7 @@ qboolean NET_DTLS_Decode(struct ftenet_connections_s *col);
|
|||
qboolean NET_DTLS_Disconnect(struct ftenet_connections_s *col, netadr_t *to);
|
||||
void NET_DTLS_Timeouts(struct ftenet_connections_s *col);
|
||||
#endif
|
||||
extern cvar_t timeout;
|
||||
|
||||
//============================================================================
|
||||
|
||||
|
|
|
@ -1087,7 +1087,7 @@ static qboolean SSL_InitConnection(gnutlsfile_t *newf, qboolean isserver, qboole
|
|||
return true;
|
||||
}
|
||||
|
||||
vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean isserver)
|
||||
vfsfile_t *GNUTLS_OpenVFS(const char *hostname, vfsfile_t *source, qboolean isserver)
|
||||
{
|
||||
gnutlsfile_t *newf;
|
||||
|
||||
|
@ -1127,7 +1127,7 @@ vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean isserver
|
|||
return &newf->funcs;
|
||||
}
|
||||
|
||||
int TLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize)
|
||||
int GNUTLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize)
|
||||
{
|
||||
gnutls_datum_t cb;
|
||||
gnutlsfile_t *f = (gnutlsfile_t*)vf;
|
||||
|
@ -1337,7 +1337,7 @@ const dtlsfuncs_t *GNUDTLS_InitClient(void)
|
|||
|
||||
qboolean SSL_InitGlobal(qboolean isserver) {return false;}
|
||||
vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean isserver) {return NULL;}
|
||||
int TLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize) {return -1;}
|
||||
int GNUTLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize) {return -1;}
|
||||
const dtlsfuncs_t *GNUDTLS_InitClient(void) {return NULL;}
|
||||
const dtlsfuncs_t *GNUDTLS_InitServer(void) {return NULL;}
|
||||
#endif
|
||||
|
|
|
@ -1012,7 +1012,7 @@ static qboolean QDECL SSPI_Close (struct vfsfile_s *file)
|
|||
}
|
||||
|
||||
#include <wchar.h>
|
||||
vfsfile_t *FS_OpenSSL(const char *servername, vfsfile_t *source, qboolean server)
|
||||
vfsfile_t *SSPI_OpenVFS(const char *servername, vfsfile_t *source, qboolean server)
|
||||
{
|
||||
sslfile_t *newf;
|
||||
int i = 0;
|
||||
|
@ -1095,7 +1095,7 @@ typedef struct _SecPkgContext_Bindings
|
|||
SEC_CHANNEL_BINDINGS *Bindings;
|
||||
} SecPkgContext_Bindings, *PSecPkgContext_Bindings;
|
||||
#endif
|
||||
int TLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize)
|
||||
int SSPI_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize)
|
||||
{
|
||||
int ret;
|
||||
sslfile_t *f = (sslfile_t*)vf;
|
||||
|
|
|
@ -120,13 +120,16 @@ int UDP6_OpenSocket (int port);
|
|||
#ifdef HAVE_IPX
|
||||
void IPX_CloseSocket (int socket);
|
||||
#endif
|
||||
cvar_t timeout = CVARD("timeout","65", "Connections will time out if no packets are received for this duration of time."); // seconds without any message
|
||||
cvar_t net_hybriddualstack = CVARD("net_hybriddualstack", "1", "Uses hybrid ipv4+ipv6 sockets where possible. Not supported on xp or below.");
|
||||
cvar_t net_fakeloss = CVARFD("net_fakeloss", "0", CVAR_CHEAT, "Simulates packetloss in both receiving and sending, on a scale from 0 to 1.");
|
||||
cvar_t net_enabled = CVARD("net_enabled", "1", "If 0, disables all network access, including name resolution and socket creation. Does not affect loopback/internal connections.");
|
||||
#if defined(TCPCONNECT) && !defined(CLIENTONLY)
|
||||
cvar_t net_enable_qizmo = CVARD("net_enable_qizmo", "1", "Enables compatibility with qizmo's tcp connections serverside. Frankly, using sv_port_tcp without this is a bit pointless.");
|
||||
cvar_t net_enable_qtv = CVARD("net_enable_qtv", "1", "Listens for qtv proxies, or clients using the qtvplay command.");
|
||||
#if defined(HAVE_SSL)
|
||||
cvar_t net_enable_tls = CVARD("net_enable_tls", "1", "If enabled, binary data sent to a non-tls tcp port will be interpretted as a tls handshake (enabling https or wss over the same tcp port.");
|
||||
#endif
|
||||
cvar_t net_enable_http = CVARD("net_enable_http", "0", "If enabled, tcp ports will accept http clients, potentially serving large files which could distrupt gameplay.");
|
||||
cvar_t net_enable_websockets = CVARD("net_enable_websockets", "1", "If enabled, tcp ports will accept websocket game clients.");
|
||||
cvar_t net_enable_webrtcbroker = CVARD("net_enable_webrtcbroker", "0", "If 1, tcp ports will accept websocket connections from clients trying to broker direct webrtc connections. This should be low traffic, but might involve a lot of mostly-idle connections.");
|
||||
|
@ -2035,6 +2038,44 @@ qboolean NET_IsLoopBackAddress (netadr_t *adr)
|
|||
return adr->type == NA_LOOPBACK;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_SSL
|
||||
vfsfile_t *FS_OpenSSL(const char *hostname, vfsfile_t *source, qboolean isserver)
|
||||
{
|
||||
vfsfile_t *f = NULL;
|
||||
#ifdef HAVE_GNUTLS
|
||||
if (!f)
|
||||
f = GNUTLS_OpenVFS(hostname, source, isserver);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (!f)
|
||||
f = OSSL_OpenVFS(hostname, source, isserver);
|
||||
#endif
|
||||
#ifdef HAVE_WINSSPI
|
||||
if (!f)
|
||||
f = SSPI_OpenVFS(hostname, source, isserver);
|
||||
#endif
|
||||
return f;
|
||||
}
|
||||
int TLS_GetChannelBinding(vfsfile_t *stream, qbyte *data, size_t *datasize)
|
||||
{
|
||||
int r = -1;
|
||||
#ifdef HAVE_GNUTLS
|
||||
if (r == -1)
|
||||
r = GNUTLS_GetChannelBinding(stream, data, datasize);
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (r == -1)
|
||||
r = OSSL_GetChannelBinding(stream, data, datasize);
|
||||
#endif
|
||||
#ifdef HAVE_WINSSPI
|
||||
if (r == -1)
|
||||
r = SSPI_GetChannelBinding(stream, data, datasize);
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//loopback stuff
|
||||
|
||||
|
@ -2495,34 +2536,56 @@ struct dtlspeer_s
|
|||
|
||||
void NET_DTLS_Timeouts(ftenet_connections_t *col)
|
||||
{
|
||||
struct dtlspeer_s *peer;
|
||||
struct dtlspeer_s *peer, **link;
|
||||
if (!col)
|
||||
return;
|
||||
for (peer = col->dtls; peer; peer = peer->next)
|
||||
for (link = &col->dtls; (peer=*link); )
|
||||
{
|
||||
if (peer->timeout < realtime)
|
||||
{
|
||||
peer->funcs->DestroyContext(peer->dtlsstate);
|
||||
*link = peer->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
peer->funcs->Timeouts(peer->dtlsstate);
|
||||
link = &peer->next;
|
||||
}
|
||||
}
|
||||
|
||||
const dtlsfuncs_t *DTLS_InitServer(void)
|
||||
{
|
||||
#if defined(HAVE_GNUTLS)
|
||||
return GNUDTLS_InitServer();
|
||||
#elif defined(HAVE_WINSSPI)
|
||||
return SSPI_DTLS_InitServer();
|
||||
#else
|
||||
return NULL;
|
||||
const dtlsfuncs_t *f = NULL;
|
||||
#ifdef HAVE_GNUTLS
|
||||
if (!f)
|
||||
f = GNUDTLS_InitServer();
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (!f)
|
||||
f = OSSL_InitServer();
|
||||
#endif
|
||||
#ifdef HAVE_WINSSPI
|
||||
if (!f)
|
||||
f = SSPI_DTLS_InitServer();
|
||||
#endif
|
||||
return f;
|
||||
}
|
||||
const dtlsfuncs_t *DTLS_InitClient(void)
|
||||
{
|
||||
const dtlsfuncs_t *f = NULL;
|
||||
#ifdef HAVE_WINSSPI
|
||||
return SSPI_DTLS_InitClient();
|
||||
#elif defined(HAVE_GNUTLS)
|
||||
return GNUDTLS_InitClient();
|
||||
#else
|
||||
return NULL;
|
||||
if (!f)
|
||||
f = SSPI_DTLS_InitClient();
|
||||
#endif
|
||||
#ifdef HAVE_GNUTLS
|
||||
if (!f)
|
||||
f = GNUDTLS_InitClient();
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL
|
||||
if (!f)
|
||||
f = OSSL_InitClient();
|
||||
#endif
|
||||
return f;
|
||||
}
|
||||
|
||||
static neterr_t NET_SendPacketCol (ftenet_connections_t *collection, int length, const void *data, netadr_t *to);
|
||||
|
@ -2533,6 +2596,7 @@ static neterr_t FTENET_DTLS_DoSendPacket(void *cbctx, const qbyte *data, size_t
|
|||
}
|
||||
qboolean NET_DTLS_Create(ftenet_connections_t *col, netadr_t *to)
|
||||
{
|
||||
extern cvar_t timeout;
|
||||
struct dtlspeer_s *peer;
|
||||
if (to->prot != NP_DGRAM)
|
||||
return false;
|
||||
|
@ -2554,6 +2618,8 @@ qboolean NET_DTLS_Create(ftenet_connections_t *col, netadr_t *to)
|
|||
peer->funcs = DTLS_InitClient();
|
||||
if (peer->funcs)
|
||||
peer->dtlsstate = peer->funcs->CreateContext(NET_BaseAdrToString(hostname, sizeof(hostname), to), peer, FTENET_DTLS_DoSendPacket, col->islisten);
|
||||
|
||||
peer->timeout = realtime+timeout.value;
|
||||
if (peer->dtlsstate)
|
||||
{
|
||||
if (peer->next)
|
||||
|
@ -2616,11 +2682,13 @@ static neterr_t FTENET_DTLS_SendPacket(ftenet_connections_t *col, int length, co
|
|||
|
||||
qboolean NET_DTLS_Decode(ftenet_connections_t *col)
|
||||
{
|
||||
extern cvar_t timeout;
|
||||
struct dtlspeer_s *peer;
|
||||
for (peer = col->dtls; peer; peer = peer->next)
|
||||
{
|
||||
if (NET_CompareAdr(&peer->addr, &net_from))
|
||||
{
|
||||
peer->timeout = realtime+timeout.value; //refresh the timeout if our peer is still alive.
|
||||
switch(peer->funcs->Received(peer->dtlsstate, net_message.data, net_message.cursize))
|
||||
{
|
||||
case NETERR_DISCONNECTED:
|
||||
|
@ -7137,12 +7205,22 @@ void NET_PrintConnectionsStatus(ftenet_connections_t *collection)
|
|||
}
|
||||
|
||||
#ifdef HAVE_DTLS
|
||||
if (developer.ival)
|
||||
{
|
||||
struct dtlspeer_s *dtls;
|
||||
char adr[64];
|
||||
for (dtls = collection->dtls; dtls; dtls = dtls->next)
|
||||
Con_Printf("dtls: %s\n", NET_AdrToString(adr, sizeof(adr), &dtls->addr));
|
||||
}
|
||||
else
|
||||
{
|
||||
struct dtlspeer_s *dtls;
|
||||
int c = 0;
|
||||
for (dtls = collection->dtls; dtls; dtls = dtls->next)
|
||||
c++;
|
||||
if (c)
|
||||
Con_Printf("dtls connections : %i\n", c);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -7720,6 +7798,7 @@ void NET_Init (void)
|
|||
#endif
|
||||
}
|
||||
|
||||
Cvar_Register(&timeout, "networking");
|
||||
Cvar_Register(&net_hybriddualstack, "networking");
|
||||
Cvar_Register(&net_fakeloss, "networking");
|
||||
|
||||
|
@ -7912,7 +7991,9 @@ void SVNET_RegisterCvars(void)
|
|||
#if defined(TCPCONNECT) && !defined(CLIENTONLY)
|
||||
Cvar_Register (&net_enable_qizmo, "networking");
|
||||
Cvar_Register (&net_enable_qtv, "networking");
|
||||
#if defined(HAVE_SSL)
|
||||
Cvar_Register (&net_enable_tls, "networking");
|
||||
#endif
|
||||
Cvar_Register (&net_enable_http, "networking");
|
||||
Cvar_Register (&net_enable_websockets, "networking");
|
||||
Cvar_Register (&net_enable_webrtcbroker, "networking");
|
||||
|
|
|
@ -311,14 +311,24 @@ typedef struct dtlsfuncs_s
|
|||
} dtlsfuncs_t;
|
||||
const dtlsfuncs_t *DTLS_InitServer(void);
|
||||
const dtlsfuncs_t *DTLS_InitClient(void);
|
||||
#endif
|
||||
#ifdef HAVE_WINSSPI
|
||||
vfsfile_t *SSPI_OpenVFS(const char *hostname, vfsfile_t *source, qboolean isserver);
|
||||
int SSPI_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize);
|
||||
const dtlsfuncs_t *SSPI_DTLS_InitServer(void); //returns NULL if there's no cert available.
|
||||
const dtlsfuncs_t *SSPI_DTLS_InitClient(void); //should always return something, if implemented.
|
||||
#endif
|
||||
#ifdef HAVE_GNUTLS
|
||||
vfsfile_t *GNUTLS_OpenVFS(const char *hostname, vfsfile_t *source, qboolean isserver);
|
||||
int GNUTLS_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize);
|
||||
const dtlsfuncs_t *GNUDTLS_InitServer(void); //returns NULL if there's no cert available.
|
||||
const dtlsfuncs_t *GNUDTLS_InitClient(void); //should always return something, if implemented.
|
||||
#endif
|
||||
#ifdef HAVE_OPENSSL
|
||||
vfsfile_t *OSSL_OpenVFS(const char *hostname, vfsfile_t *source, qboolean isserver);
|
||||
int OSSL_GetChannelBinding(vfsfile_t *vf, qbyte *binddata, size_t *bindsize);
|
||||
const dtlsfuncs_t *OSSL_InitServer(void); //returns NULL if there's no cert available.
|
||||
const dtlsfuncs_t *OSSL_InitClient(void); //should always return something, if implemented.
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -380,7 +380,10 @@ int QDECL QCEditor (pubprogfuncs_t *prinst, const char *filename, int *line, int
|
|||
return DEBUG_TRACE_ABORT;
|
||||
if (!*filename || !line || !*line) //don't try editing an empty line, it won't work
|
||||
{
|
||||
if (!*filename)
|
||||
Con_Printf("Unable to debug, please disable optimisations\n");
|
||||
else
|
||||
Con_Printf("Unable to debug, please provide line number info\n");
|
||||
if (fatal)
|
||||
return DEBUG_TRACE_ABORT;
|
||||
return DEBUG_TRACE_OFF;
|
||||
|
@ -5724,8 +5727,8 @@ void QCBUILTIN PF_gettime (pubprogfuncs_t *prinst, struct globalvars_s *pr_globa
|
|||
case 0: //cached time at start of frame
|
||||
G_FLOAT(OFS_RETURN) = realtime;
|
||||
break;
|
||||
case 1: //actual time
|
||||
G_FLOAT(OFS_RETURN) = Sys_DoubleTime();
|
||||
case 1: //actual time, ish. we round to milliseconds to reduce spectre exposure
|
||||
G_FLOAT(OFS_RETURN) = (qint64_t)(Sys_DoubleTime()*1000) / 1000.0;
|
||||
break;
|
||||
//case 2: //highres.. looks like time into the frame
|
||||
//case 3: //uptime
|
||||
|
|
|
@ -627,7 +627,16 @@ void Mod_ClipDecal(struct model_s *mod, vec3_t center, vec3_t normal, vec3_t tan
|
|||
#endif
|
||||
#ifdef Q3BSPS
|
||||
else if (cl.worldmodel->fromgame == fg_quake3)
|
||||
{
|
||||
if (mod->submodelof)
|
||||
{
|
||||
msurface_t *surf;
|
||||
for (surf = mod->surfaces+mod->firstmodelsurface, p = 0; p < mod->nummodelsurfaces; p++, surf++)
|
||||
Fragment_Mesh(&dec, surf->mesh, surf->texinfo);
|
||||
}
|
||||
else
|
||||
Q3BSP_ClipDecalToNodes(&dec, mod->rootnode);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TERRAIN
|
||||
|
|
|
@ -16,7 +16,7 @@ This file came to FTE via EzQuake.
|
|||
|
||||
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
||||
#define SHA1HANDSOFF
|
||||
//#include "quakedef.h"
|
||||
#include "quakedef.h"
|
||||
#include <string.h>
|
||||
|
||||
#define BigLong(l) (((unsigned char*)&l)[0]<<24) | (((unsigned char*)&l)[1]<<16) | (((unsigned char*)&l)[2]<<8) | (((unsigned char*)&l)[3]<<0)
|
||||
|
|
|
@ -1528,6 +1528,8 @@ qboolean Font_LoadFreeTypeFont(struct font_s *f, int height, const char *fontfil
|
|||
error = pFT_New_Face(fontlib, va("/usr/share/fonts/%s", fontfilename), 0, &face);
|
||||
if (error)
|
||||
error = pFT_New_Face(fontlib, va("/usr/share/fonts/truetype/%s.ttf", fontfilename), 0, &face);
|
||||
if (error) //just to give a chance of the same names working on more than one os, with the right package installed.
|
||||
error = pFT_New_Face(fontlib, va("/usr/share/fonts/truetype/msttcorefonts/%s.ttf", fontfilename), 0, &face);
|
||||
}
|
||||
#endif
|
||||
if (!error)
|
||||
|
|
|
@ -172,7 +172,7 @@ m*_t structures are in-memory
|
|||
#define EF_BLUE (1<<6)
|
||||
#define EF_RED (1<<7)
|
||||
#define H2EF_NODRAW (1<<7) //this is going to get complicated... emulated server side.
|
||||
#define DPEF_NOGUNBOB (1<<8) //viewmodel attachment does not bob
|
||||
#define DPEF_NOGUNBOB (1<<8) //viewmodel attachment does not bob. only applies to viewmodelforclient/RF_WEAPONMODEL
|
||||
#define EF_FULLBRIGHT (1<<9) //abslight=1
|
||||
#define DPEF_FLAME (1<<10) //'onfire'
|
||||
#define DPEF_STARDUST (1<<11) //'showering sparks'
|
||||
|
|
|
@ -7273,6 +7273,8 @@ char *Shader_GetShaderBody(shader_t *s, char *fname, size_t fnamesize)
|
|||
|
||||
if (fnamesize)
|
||||
{
|
||||
*fname = 0;
|
||||
|
||||
if (parsename)
|
||||
{
|
||||
unsigned int key;
|
||||
|
@ -7297,8 +7299,24 @@ char *Shader_GetShaderBody(shader_t *s, char *fname, size_t fnamesize)
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
*fname = 0;
|
||||
|
||||
if (!strchr(parsename, ':'))
|
||||
{
|
||||
//if the named shader is a .shader file then just directly load it.
|
||||
const char *token = COM_GetFileExtension(parsename, NULL);
|
||||
if (!strcmp(token, ".shader") || !*token)
|
||||
{
|
||||
char shaderfile[MAX_QPATH];
|
||||
if (!*token)
|
||||
{
|
||||
Q_snprintfz(shaderfile, sizeof(shaderfile), "%s.shader", parsename);
|
||||
if (COM_FCheckExists(shaderfile))
|
||||
Q_snprintfz(fname, fnamesize, "%s:%i", shaderfile, 1);
|
||||
}
|
||||
else if (COM_FCheckExists(parsename))
|
||||
Q_snprintfz(fname, fnamesize, "%s:%i", parsename, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
|
|
@ -2744,50 +2744,11 @@ static void *X11VID_CreateCursorRGBA(const qbyte *rgbacursor, size_t w, size_t h
|
|||
Z_Free(cursor);
|
||||
return NULL;
|
||||
}
|
||||
static void *X11VID_CreateCursor(const char *filename, float hotx, float hoty, float scale)
|
||||
static void *X11VID_CreateCursor(const qbyte *imagedata, int width, int height, uploadfmt_t format, float hotx, float hoty, float scale)
|
||||
{
|
||||
void *r;
|
||||
qbyte *rgbadata;
|
||||
uploadfmt_t format;
|
||||
void *filedata;
|
||||
int filelen, width, height;
|
||||
if (!filename || !*filename)
|
||||
if (!imagedata)
|
||||
return NULL;
|
||||
filelen = FS_LoadFile(filename, &filedata);
|
||||
if (!filedata)
|
||||
return NULL;
|
||||
|
||||
rgbadata = ReadRawImageFile(filedata, filelen, &width, &height, &format, true, filename);
|
||||
FS_FreeFile(filedata);
|
||||
if (!rgbadata)
|
||||
return NULL;
|
||||
|
||||
if ((format==PTI_RGBX8 || format==PTI_LLLX8) && !strchr(filename, ':'))
|
||||
{ //people seem to insist on using jpgs, which don't have alpha.
|
||||
//so screw over the alpha channel if needed.
|
||||
unsigned int alpha_width, alpha_height, p;
|
||||
char aname[MAX_QPATH];
|
||||
unsigned char *alphadata;
|
||||
char *alph;
|
||||
size_t alphsize;
|
||||
char ext[8];
|
||||
COM_StripExtension(filename, aname, sizeof(aname));
|
||||
COM_FileExtension(filename, ext, sizeof(ext));
|
||||
Q_strncatz(aname, "_alpha.", sizeof(aname));
|
||||
Q_strncatz(aname, ext, sizeof(aname));
|
||||
alphsize = FS_LoadFile(filename, (void**)&alph);
|
||||
if (alph)
|
||||
{
|
||||
if ((alphadata = ReadRawImageFile(alph, alphsize, &alpha_width, &alpha_height, &format, true, aname)))
|
||||
{
|
||||
if (alpha_width == width && alpha_height == height)
|
||||
for (p = 0; p < alpha_width*alpha_height; p++)
|
||||
rgbadata[(p<<2) + 3] = (alphadata[(p<<2) + 0] + alphadata[(p<<2) + 1] + alphadata[(p<<2) + 2])/3;
|
||||
BZ_Free(alphadata);
|
||||
}
|
||||
FS_FreeFile(alph);
|
||||
}
|
||||
}
|
||||
|
||||
if (scale != 1)
|
||||
{
|
||||
|
@ -2798,15 +2759,14 @@ static void *X11VID_CreateCursor(const char *filename, float hotx, float hoty, f
|
|||
if (nw <= 0 || nh <= 0 || nw > 128 || nh > 128) //don't go crazy.
|
||||
return NULL;
|
||||
nd = BZ_Malloc(nw*nh*4);
|
||||
Image_ResampleTexture((unsigned int*)rgbadata, width, height, (unsigned int*)nd, nw, nh);
|
||||
Image_ResampleTexture((unsigned int*)imagedata, width, height, (unsigned int*)nd, nw, nh);
|
||||
width = nw;
|
||||
height = nh;
|
||||
BZ_Free(rgbadata);
|
||||
rgbadata = nd;
|
||||
r = X11VID_CreateCursorRGBA(nd, width, height, hotx, hoty);
|
||||
BZ_Free(nd);
|
||||
}
|
||||
|
||||
r = X11VID_CreateCursorRGBA(rgbadata, width, height, hotx, hoty);
|
||||
BZ_Free(rgbadata);
|
||||
else
|
||||
r = X11VID_CreateCursorRGBA(imagedata, width, height, hotx, hoty);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -60,25 +60,11 @@ static void *GLVID_getsdlglfunction(char *functionname)
|
|||
#endif
|
||||
|
||||
#if SDL_MAJOR_VERSION >= 2
|
||||
void *GLVID_CreateCursor (const char *filename, float hotx, float hoty, float scale)
|
||||
void *GLVID_CreateCursor (const qbyte *imagedata, int width, int height, uploadfmt_t format, float hotx, float hoty, float scale)
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
SDL_Cursor *curs;
|
||||
SDL_Surface *surf;
|
||||
qbyte *rgbadata_start;
|
||||
qboolean hasalpha;
|
||||
void *filedata;
|
||||
int filelen;
|
||||
if (!filename || !*filename)
|
||||
return NULL;
|
||||
filelen = FS_LoadFile(filename, &filedata);
|
||||
if (!filedata)
|
||||
return NULL;
|
||||
|
||||
rgbadata_start = Read32BitImageFile(filedata, filelen, &width, &height, &hasalpha, "cursor");
|
||||
FS_FreeFile(filedata);
|
||||
if (!rgbadata_start)
|
||||
if (!imagedata)
|
||||
return NULL;
|
||||
|
||||
if (scale != 1)
|
||||
|
@ -90,17 +76,20 @@ void *GLVID_CreateCursor (const char *filename, float hotx, float hoty, float
|
|||
if (nw <= 0 || nh <= 0 || nw > 128 || nh > 128) //don't go crazy.
|
||||
return NULL;
|
||||
nd = BZ_Malloc(nw*nh*4);
|
||||
Image_ResampleTexture((unsigned int*)rgbadata_start, width, height, (unsigned int*)nd, nw, nh);
|
||||
width = nw;
|
||||
height = nh;
|
||||
BZ_Free(rgbadata_start);
|
||||
rgbadata_start = nd;
|
||||
}
|
||||
Image_ResampleTexture((unsigned int*)imagedata, width, height, (unsigned int*)nd, nw, nh);
|
||||
|
||||
surf = SDL_CreateRGBSurfaceFrom(rgbadata_start, width, height, 32, width*4, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
surf = SDL_CreateRGBSurfaceFrom(nd, nw, nh, 32, nw*4, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
curs = SDL_CreateColorCursor(surf, hotx, hoty);
|
||||
SDL_FreeSurface(surf);
|
||||
BZ_Free(rgbadata_start);
|
||||
|
||||
BZ_Free(nd);
|
||||
}
|
||||
else
|
||||
{
|
||||
surf = SDL_CreateRGBSurfaceFrom((void*)imagedata, width, height, 32, width*4, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
curs = SDL_CreateColorCursor(surf, hotx, hoty);
|
||||
SDL_FreeSurface(surf);
|
||||
}
|
||||
return curs;
|
||||
}
|
||||
qboolean GLVID_SetCursor (void *cursor)
|
||||
|
|
|
@ -375,7 +375,7 @@ void Cookie_Monster(void)
|
|||
//path) I'm going to call this an optimisation feature and not bother with it... hopefully there won't be too many sites that have sub-paths or third-party stuff... gah.
|
||||
//httponly) irrelevant until we support javascript... which we don't.
|
||||
//secure) assumed to be true. https:// vs http:// are thus completely independant. sorry.
|
||||
//expires) gah, parsing time values sucks! plus we don't have persistent storage.
|
||||
//expires) gah, parsing time values sucks! plus we don't have persistent storage. All cookies are session cookies.
|
||||
void Cookie_Parse(char *domain, int secure, char *line, char *end)
|
||||
{
|
||||
char *e;
|
||||
|
|
|
@ -706,6 +706,7 @@ QCC_type_t *QCC_PR_GenFunctionType (QCC_type_t *rettype, struct QCC_typeparam_s
|
|||
char *QCC_PR_ParseName (void);
|
||||
CompilerConstant_t *QCC_PR_DefineName(char *name);
|
||||
struct QCC_typeparam_s *QCC_PR_FindStructMember(QCC_type_t *t, const char *membername, unsigned int *out_ofs);
|
||||
QCC_type_t *QCC_PR_PointerType (QCC_type_t *pointsto);
|
||||
|
||||
const char *QCC_VarAtOffset(QCC_sref_t ref);
|
||||
|
||||
|
@ -730,6 +731,8 @@ void QCC_PR_ParsePrintSRef (int warningtype, QCC_sref_t sref);
|
|||
void VARGS QCC_PR_ParseErrorPrintDef (int errortype, QCC_def_t *def, const char *error, ...);
|
||||
void VARGS QCC_PR_ParseErrorPrintSRef (int errortype, QCC_sref_t sref, const char *error, ...);
|
||||
|
||||
QCC_type_t *QCC_PR_MakeThiscall(QCC_type_t *orig, QCC_type_t *thistype);
|
||||
|
||||
int QCC_WarningForName(const char *name);
|
||||
char *QCC_NameForWarning(int idx);
|
||||
|
||||
|
|
|
@ -9,6 +9,14 @@
|
|||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define longlong __int64
|
||||
#define LL(x) x##i64
|
||||
#else
|
||||
#define longlong long long
|
||||
#define LL(x) x##ll
|
||||
#endif
|
||||
|
||||
/*
|
||||
TODO:
|
||||
*foo++ = 5;
|
||||
|
@ -236,7 +244,8 @@ QCC_sref_t QCC_MakeTranslateStringConst(const char *value);
|
|||
QCC_sref_t QCC_MakeStringConst(const char *value);
|
||||
QCC_sref_t QCC_MakeStringConstLength(const char *value, int length);
|
||||
QCC_sref_t QCC_MakeFloatConst(float value);
|
||||
QCC_sref_t QCC_MakeIntConst(int value);
|
||||
QCC_sref_t QCC_MakeFloatConstFromInt(longlong llvalue);
|
||||
QCC_sref_t QCC_MakeIntConst(longlong llvalue);
|
||||
QCC_sref_t QCC_MakeVectorConst(float a, float b, float c);
|
||||
|
||||
enum
|
||||
|
@ -2181,7 +2190,7 @@ static int QCC_PR_RoundFloatConst(const QCC_eval_t *eval)
|
|||
float val = eval->_float;
|
||||
int ival = val;
|
||||
if (val != (float)ival)
|
||||
QCC_PR_ParseWarning(WARN_OVERFLOW, "Constant float operand not an integer value");
|
||||
QCC_PR_ParseWarning(WARN_OVERFLOW, "Constant float operand %f will be truncated to %i", val, ival);
|
||||
return ival;
|
||||
}
|
||||
|
||||
|
@ -4553,7 +4562,7 @@ static void QCC_VerifyFormatString (const char *funcname, QCC_ref_t **arglist, u
|
|||
{
|
||||
case 0:
|
||||
if (argpos < argcount && argn_last < argcount)
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: surplus trailing arguments for format", funcname);
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: surplus trailing %s%s%s argument(s) for format %s\"%s\"%s", funcname, col_symbol, TypeName(ARGCTYPE(argpos), temp, sizeof(temp)), col_none, col_name, strings + formatstring->string, col_none);
|
||||
return;
|
||||
case '%':
|
||||
if(*++s == '%')
|
||||
|
@ -4575,7 +4584,7 @@ static void QCC_VerifyFormatString (const char *funcname, QCC_ref_t **arglist, u
|
|||
width = strtol(s, &err, 10);
|
||||
if(!err)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: bad format string: %s", funcname, s0);
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: bad format string: %s%s%s", funcname, col_name, s0, col_none);
|
||||
return;
|
||||
}
|
||||
if(*err == '$')
|
||||
|
@ -4621,7 +4630,7 @@ noflags:
|
|||
arg = strtol(s, &err, 10);
|
||||
if(!err || *err != '$')
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s", funcname, s0);
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s%s%s", funcname, col_name, s0, col_none);
|
||||
return;
|
||||
}
|
||||
s = err + 1;
|
||||
|
@ -4636,7 +4645,7 @@ noflags:
|
|||
strtol(s, &err, 10);
|
||||
if(!err)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s", funcname, s0);
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s%s%s", funcname, col_name, s0, col_none);
|
||||
return;
|
||||
}
|
||||
s = err;
|
||||
|
@ -4656,7 +4665,7 @@ noflags:
|
|||
arg = strtol(s, &err, 10);
|
||||
if(!err || *err != '$')
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s", funcname, s0);
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s%s%s", funcname, col_name, s0, col_none);
|
||||
return;
|
||||
}
|
||||
s = err + 1;
|
||||
|
@ -4672,14 +4681,14 @@ noflags:
|
|||
strtol(s, &err, 10);
|
||||
if(!err)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s", funcname, s0);
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s%s%s", funcname, col_name, s0, col_none);
|
||||
return;
|
||||
}
|
||||
s = err;
|
||||
}
|
||||
else
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s", funcname, s0);
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s%s%s", funcname, col_name, s0, col_none);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -4744,7 +4753,7 @@ nolength:
|
|||
break;
|
||||
default:
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires float at arg %i (got %s)", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)));
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires float at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -4759,7 +4768,7 @@ nolength:
|
|||
case ev_variant:
|
||||
break;
|
||||
default:
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires pointer at arg %i (got %s)", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)));
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires pointer at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4775,7 +4784,7 @@ nolength:
|
|||
break;
|
||||
//fallthrough
|
||||
default:
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires int at arg %i (got %s)", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)));
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires int at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4790,12 +4799,12 @@ nolength:
|
|||
case ev_variant:
|
||||
break;
|
||||
default:
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires vector at arg %i (got %s)", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)));
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires vector at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires intvector at arg %i (got %s)", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)));
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires intvector at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none);
|
||||
break;
|
||||
case 's':
|
||||
case 'S':
|
||||
|
@ -4805,12 +4814,12 @@ nolength:
|
|||
case ev_variant:
|
||||
break;
|
||||
default:
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s requires string at arg %i", funcname, formatbuf, thisarg+1, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)));
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: %s%s%s requires string at arg %i (got %s%s%s)", funcname, col_name, formatbuf, col_none, thisarg+1, col_symbol, TypeName(ARGCTYPE(thisarg), temp, sizeof(temp)), col_none);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s", funcname, s0);
|
||||
QCC_PR_ParseWarning(WARN_FORMATSTRING, "%s: invalid format string: %s%s%s", funcname, col_name, s0, col_none);
|
||||
return;
|
||||
}
|
||||
s++;
|
||||
|
@ -5877,7 +5886,7 @@ static QCC_sref_t QCC_PR_ParseFunctionCall (QCC_ref_t *funcref) //warning, the f
|
|||
if (t)
|
||||
{
|
||||
QCC_PR_Expect(")");
|
||||
return QCC_MakeIntConst(t->size * 4);
|
||||
return QCC_PR_Statement(&pr_opcodes[OP_ADD_PIW], QCC_MakeIntConst(0), QCC_MakeIntConst(t->size), NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -6523,9 +6532,13 @@ QCC_sref_t QCC_MakeSRef(QCC_def_t *def, unsigned int ofs, QCC_type_t *type)
|
|||
//int varchecks;
|
||||
//int typechecks;
|
||||
extern hashtable_t floatconstdefstable;
|
||||
QCC_sref_t QCC_MakeIntConst(int value)
|
||||
QCC_sref_t QCC_MakeIntConst(longlong llvalue)
|
||||
{
|
||||
QCC_def_t *cn;
|
||||
int value = llvalue;
|
||||
|
||||
if (value != llvalue)
|
||||
QCC_PR_ParseWarning(WARN_OVERFLOW, "Constant int operand %lld will be truncated to %i", llvalue, value);
|
||||
|
||||
cn = Hash_GetKey(&floatconstdefstable, value);
|
||||
if (cn)
|
||||
|
@ -7806,6 +7819,28 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo
|
|||
if (assumeclass && assumeclass->parentclass)
|
||||
{ //try getting a member.
|
||||
QCC_type_t *type;
|
||||
if (assumeclass->type == ev_struct)
|
||||
{
|
||||
unsigned int ofs;
|
||||
struct QCC_typeparam_s *p = QCC_PR_FindStructMember(assumeclass, name, &ofs);
|
||||
if (p)
|
||||
{
|
||||
QCC_sref_t ths;
|
||||
ths = QCC_PR_GetSRef(QCC_PR_PointerType(pr_classtype), "this", pr_scope, false, 0, false);
|
||||
if (ths.cast)
|
||||
{
|
||||
ths.cast = QCC_PR_PointerType(p->type);
|
||||
|
||||
if (d.sym->arraysize)
|
||||
{
|
||||
//FIXME: this should result in a pointer type, and not this->member[0]
|
||||
}
|
||||
return QCC_PR_ParseRefArrayPointer(refbuf, QCC_PR_BuildRef(refbuf, REF_POINTER, ths, QCC_MakeIntConst(ofs), p->type, false), allowarrayassign, makearraypointers);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(type = assumeclass; type && !d.cast; type = type->parentclass)
|
||||
{
|
||||
//look for virtual things
|
||||
|
@ -7819,6 +7854,7 @@ QCC_ref_t *QCC_PR_ParseRefValue (QCC_ref_t *refbuf, QCC_type_t *assumeclass, pbo
|
|||
d = QCC_PR_GetSRef (NULL, membername, pr_scope, false, 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!d.cast)
|
||||
{
|
||||
// look through the defs
|
||||
|
@ -15452,6 +15488,8 @@ void QCC_PR_ParseDefs (char *classname, pbool fatal)
|
|||
allocatenew = true;
|
||||
if (classname)
|
||||
{
|
||||
unsigned int ofs;
|
||||
struct QCC_typeparam_s *p;
|
||||
char *membername = name;
|
||||
name = qccHunkAlloc(strlen(classname) + strlen(name) + 3);
|
||||
sprintf(name, "%s::%s", classname, membername);
|
||||
|
@ -15460,6 +15498,13 @@ void QCC_PR_ParseDefs (char *classname, pbool fatal)
|
|||
allocatenew = false;
|
||||
else if (!defclass || !defclass->parentclass)
|
||||
QCC_PR_ParseError(ERR_NOTANAME, "%s is not a class\n", classname);
|
||||
|
||||
if (defclass->type == ev_struct)
|
||||
{
|
||||
p = QCC_PR_FindStructMember(defclass, membername, &ofs);
|
||||
if (p && p->isvirtual)
|
||||
type = QCC_PR_MakeThiscall(type, defclass);
|
||||
}
|
||||
}
|
||||
else
|
||||
defclass = NULL;
|
||||
|
|
|
@ -2081,13 +2081,13 @@ static void QCC_PR_LexNumber (void)
|
|||
num*=base;
|
||||
num += c-'0';
|
||||
}
|
||||
else if (c >= 'a' && c <= 'f' && base > 10)
|
||||
else if (c >= 'a' && c <= 'z' && c < 'a'+base-10)
|
||||
{
|
||||
pr_token[tokenlen++] = c;
|
||||
num*=base;
|
||||
num += c -'a'+10;
|
||||
}
|
||||
else if (c >= 'A' && c <= 'F' && base > 10)
|
||||
else if (c >= 'A' && c <= 'Z' && c < 'A'+base-10)
|
||||
{
|
||||
pr_token[tokenlen++] = c;
|
||||
num*=base;
|
||||
|
@ -4797,7 +4797,7 @@ char *pr_parm_argcount_name;
|
|||
|
||||
int recursivefunctiontype;
|
||||
|
||||
static QCC_type_t *QCC_PR_MakeThiscall(QCC_type_t *orig, QCC_type_t *thistype)
|
||||
QCC_type_t *QCC_PR_MakeThiscall(QCC_type_t *orig, QCC_type_t *thistype)
|
||||
{
|
||||
QCC_type_t ftype = *orig;
|
||||
|
||||
|
@ -4807,9 +4807,12 @@ static QCC_type_t *QCC_PR_MakeThiscall(QCC_type_t *orig, QCC_type_t *thistype)
|
|||
ftype.params = qccHunkAlloc(sizeof(*ftype.params) * ftype.num_parms);
|
||||
memcpy(ftype.params+1, orig->params, sizeof(*ftype.params) * orig->num_parms);
|
||||
ftype.params[0].paramname = "this";
|
||||
ftype.params[0].type = QCC_PointerTypeTo(thistype);
|
||||
ftype.params[0].type = QCC_PR_PointerType(thistype);
|
||||
ftype.params[0].isvirtual = true;
|
||||
|
||||
memmove(&pr_parm_names[1], &pr_parm_names[0], sizeof(*pr_parm_names)*orig->num_parms);
|
||||
strcpy(pr_parm_names[0], "this");
|
||||
|
||||
orig = QCC_PR_FindType (&ftype);
|
||||
if (!orig)
|
||||
{
|
||||
|
@ -5869,6 +5872,8 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
newt = QCC_PR_NewType(tname, ev_struct, true);
|
||||
newt->parentclass = parenttype;
|
||||
}
|
||||
else if (!newt->size && !newt->parentclass)
|
||||
newt->parentclass = parenttype;
|
||||
else if (parenttype && newt->parentclass != parenttype)
|
||||
QCC_PR_ParseError(ERR_NOTANAME, "Redeclaration of struct with different parent type", tname, parenttype->name);
|
||||
|
||||
|
@ -5992,7 +5997,12 @@ QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
|
|||
QC_snprintfz(membername, sizeof(membername), "%s::%s", newt->name, parmname);
|
||||
d = QCC_PR_GetDef(type, membername, NULL, true, 0, (type->type==ev_function)?GDF_CONST:0);
|
||||
if (QCC_PR_CheckToken("=") || (type->type == ev_function && QCC_PR_PeekToken("{")))
|
||||
{
|
||||
//FIXME: methods cannot be compiled yet, as none of the fields are not actually defined yet.
|
||||
pr_classtype = newt;
|
||||
QCC_PR_ParseInitializerDef(d, 0);
|
||||
pr_classtype = NULL;
|
||||
}
|
||||
QCC_FreeDef(d);
|
||||
if (!QCC_PR_PeekToken(","))
|
||||
newparm = NULL;
|
||||
|
|
|
@ -4175,13 +4175,19 @@ static void QCC_PR_CommandLinePrecompilerOptions (void)
|
|||
{
|
||||
flag_ifvector = flag_vectorlogic = true;
|
||||
flag_dblstarexp = flag_attributes = flag_assumevar = pr_subscopedlocals = flag_cpriority = flag_allowuninit = true;
|
||||
flag_boundchecks = false; //gmqcc doesn't support these, so xonotic is buggy shite.
|
||||
flag_boundchecks = false; //gmqcc doesn't support dynamic bound checks, so xonotic is buggy shite. we don't want to generate code that will crash.
|
||||
opt_logicops = true;
|
||||
qccwarningaction[WARN_CONSTANTCOMPARISON] = WA_IGNORE;
|
||||
qccwarningaction[WARN_POINTLESSSTATEMENT] = WA_IGNORE;
|
||||
qccwarningaction[WARN_OVERFLOW] = WA_IGNORE;
|
||||
qccwarningaction[WARN_STRICTTYPEMISMATCH] = WA_IGNORE;
|
||||
qccwarningaction[WARN_PARAMWITHNONAME] = WA_IGNORE;
|
||||
|
||||
//we have to disable some of these warnings, because xonotic insists on using -Werror. use -Wextra to override.
|
||||
qccwarningaction[WARN_NOTREFERENCEDCONST] = WA_IGNORE; //gmqcc doesn't warn about function prototypes without any names
|
||||
qccwarningaction[WARN_CONSTANTCOMPARISON] = WA_IGNORE; //xonotic abuses this, and gmqcc doesn't warn.
|
||||
qccwarningaction[WARN_POINTLESSSTATEMENT] = WA_IGNORE; //so many macro expansions that we can't mute because of xonotic using an external preprocessor.
|
||||
qccwarningaction[WARN_OVERFLOW] = WA_IGNORE; //xonotic has data loss from implicit conversions too.
|
||||
qccwarningaction[WARN_STRICTTYPEMISMATCH] = WA_IGNORE; //gmqcc doesn't enforce checks on auxilliary types.
|
||||
qccwarningaction[WARN_PARAMWITHNONAME] = WA_IGNORE; //nor does it care if a parameter isn't named.
|
||||
qccwarningaction[WARN_IFSTRING_USED] = WA_IGNORE; //and many people would argue that this was a feature rather than a bug
|
||||
qccwarningaction[WARN_UNINITIALIZED] = WA_IGNORE; //all locals get 0-initialised anyway, and our checks are not quite up to scratch.
|
||||
qccwarningaction[WARN_GMQCC_SPECIFIC] = WA_IGNORE; //we shouldn't warn about gmqcc syntax when we're trying to be compatible with it. there's always -Wextra.
|
||||
|
||||
keyword_asm = false;
|
||||
keyword_inout = keyword_optional = keyword_state = keyword_inline = keyword_nosave = keyword_extern = keyword_shared = keyword_unused = keyword_used = keyword_nonstatic = keyword_ignore = keyword_strip = false;
|
||||
|
@ -4284,10 +4290,30 @@ static void QCC_PR_CommandLinePrecompilerOptions (void)
|
|||
for (j = 0; j < ERR_PARSEERRORS; j++)
|
||||
if (qccwarningaction[j] == WA_IGNORE)
|
||||
{
|
||||
if (j != WARN_FTE_SPECIFIC && //kinda annoying when its actually valid code.
|
||||
j != WARN_NOTREFERENCEDCONST && //warning about every single constant is annoying as heck. note that this includes both stuff like MOVETYPE_ and builtins.
|
||||
j != WARN_EXTRAPRECACHE) //we can't guarentee that we can parse this correctly. this warning is thus a common false positive. its available with -Wextra, and there's intrinsics to reduce false positives.
|
||||
switch(j)
|
||||
{
|
||||
//these warnings do not get switched on with -Wall when using -std=gmqcc, because mods that use -Werror would screw up too much
|
||||
case WARN_CONSTANTCOMPARISON:
|
||||
case WARN_POINTLESSSTATEMENT:
|
||||
case WARN_OVERFLOW:
|
||||
case WARN_STRICTTYPEMISMATCH:
|
||||
case WARN_PARAMWITHNONAME:
|
||||
case WARN_IFSTRING_USED:
|
||||
case WARN_UNINITIALIZED:
|
||||
case WARN_GMQCC_SPECIFIC:
|
||||
qccwarningaction[j] = qccwarningaction[WARN_GMQCC_SPECIFIC];
|
||||
break;
|
||||
|
||||
//these warnings require -Wextra to enable, as they're too annoying to have to fix
|
||||
case WARN_NOTREFERENCEDCONST: //warning about every single constant is annoying as heck. note that this includes both stuff like MOVETYPE_ and builtins.
|
||||
case WARN_EXTRAPRECACHE: //we can't guarentee that we can parse this correctly. this warning is thus a common false positive. its available with -Wextra, and there's intrinsics to reduce false positives.
|
||||
case WARN_FTE_SPECIFIC: //kinda annoying when its actually valid code.
|
||||
break;
|
||||
|
||||
default:
|
||||
qccwarningaction[j] = WA_WARN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!stricmp(a, "extra"))
|
||||
|
|
|
@ -828,6 +828,9 @@ void NPP_NQFlush(void)
|
|||
break;
|
||||
|
||||
case svcfte_cgamepacket:
|
||||
if (writedest != &sv.multicast)
|
||||
{
|
||||
Con_Printf(CON_WARNING"Warning: svc_cgamepacket used outside of a multicast\n");
|
||||
if (sv.csqcdebug)
|
||||
{
|
||||
/*shift the data up by two bytes*/
|
||||
|
@ -839,6 +842,7 @@ void NPP_NQFlush(void)
|
|||
|
||||
bufferlen += 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case svc_temp_entity:
|
||||
switch (buffer[1])
|
||||
|
@ -846,6 +850,9 @@ void NPP_NQFlush(void)
|
|||
default:
|
||||
if (te_515sevilhackworkaround)
|
||||
{
|
||||
if (writedest != &sv.multicast)
|
||||
{
|
||||
Con_Printf(CON_WARNING"Warning: unknown svc_temp_entity used outside of a multicast\n");
|
||||
if (sv.csqcdebug)
|
||||
{
|
||||
/*shift the data up by two bytes, but don't care about the first byte*/
|
||||
|
@ -857,6 +864,7 @@ void NPP_NQFlush(void)
|
|||
|
||||
bufferlen += 2;
|
||||
}
|
||||
}
|
||||
/*replace the svc itself*/
|
||||
buffer[0] = svcfte_cgamepacket;
|
||||
}
|
||||
|
@ -1870,6 +1878,9 @@ void NPP_QWFlush(void)
|
|||
|
||||
break;
|
||||
case svcfte_cgamepacket:
|
||||
if (writedest != &sv.nqmulticast)
|
||||
{
|
||||
Con_Printf(CON_WARNING"Warning: svc_cgamepacket used outside of a multicast\n");
|
||||
if (sv.csqcdebug)
|
||||
{
|
||||
/*shift the data up by two bytes*/
|
||||
|
@ -1881,6 +1892,7 @@ void NPP_QWFlush(void)
|
|||
|
||||
bufferlen += 2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case svc_temp_entity:
|
||||
switch(minortype)
|
||||
|
@ -1888,6 +1900,9 @@ void NPP_QWFlush(void)
|
|||
default:
|
||||
if (te_515sevilhackworkaround)
|
||||
{
|
||||
if (writedest != &sv.nqmulticast)
|
||||
{
|
||||
Con_Printf(CON_WARNING"Warning: unknown svc_temp_entity used outside of a multicast\n");
|
||||
if (sv.csqcdebug)
|
||||
{
|
||||
/*shift the data up by two bytes*/
|
||||
|
@ -1899,6 +1914,7 @@ void NPP_QWFlush(void)
|
|||
|
||||
bufferlen += 2;
|
||||
}
|
||||
}
|
||||
/*replace the svc itself*/
|
||||
buffer[0] = svcfte_cgamepacket;
|
||||
}
|
||||
|
|
|
@ -6255,6 +6255,44 @@ void QCBUILTIN PF_multicast (pubprogfuncs_t *prinst, struct globalvars_s *pr_glo
|
|||
NPP_Flush();
|
||||
#endif
|
||||
|
||||
if (sv.csqcdebug)
|
||||
{
|
||||
#ifdef NQPROT
|
||||
if (sv.nqmulticast.cursize && sv.nqmulticast.data[0] == svcfte_cgamepacket)
|
||||
{
|
||||
if (sv.nqmulticast.cursize + 2 > sv.nqmulticast.maxsize)
|
||||
sv.nqmulticast.cursize = 0;
|
||||
else
|
||||
{
|
||||
/*shift the data up by two bytes*/
|
||||
memmove(sv.nqmulticast.data+3, sv.nqmulticast.data+1, sv.nqmulticast.cursize-1);
|
||||
|
||||
/*add a length in the 2nd/3rd bytes*/
|
||||
sv.nqmulticast.data[1] = (sv.nqmulticast.cursize-1);
|
||||
sv.nqmulticast.data[2] = (sv.nqmulticast.cursize-1) >> 8;
|
||||
|
||||
sv.nqmulticast.cursize += 2;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (sv.multicast.cursize)
|
||||
{
|
||||
if (sv.multicast.cursize + 2 > sv.multicast.maxsize)
|
||||
sv.multicast.cursize = 0;
|
||||
else
|
||||
{
|
||||
/*shift the data up by two bytes*/
|
||||
memmove(sv.multicast.data+3, sv.multicast.data+1, sv.multicast.cursize-1);
|
||||
|
||||
/*add a length in the 2nd/3rd bytes*/
|
||||
sv.multicast.data[1] = (sv.multicast.cursize-1);
|
||||
sv.multicast.data[2] = (sv.multicast.cursize-1) >> 8;
|
||||
|
||||
sv.multicast.cursize += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SV_MulticastProtExt(o, to, pr_global_struct->dimension_send, 0, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -130,7 +130,7 @@ typedef struct
|
|||
PAUSE_EXPLICIT = 1, //someone hit pause
|
||||
PAUSE_SERVICE = 2, //we're running as a service and someone paused us rather than killing us.
|
||||
PAUSE_AUTO = 4 //console is down in a singleplayer game.
|
||||
} paused;
|
||||
} paused, oldpaused;
|
||||
float pausedstart;
|
||||
|
||||
//check player/eyes models for hacks
|
||||
|
|
|
@ -1902,7 +1902,10 @@ static void SV_Status_f (void)
|
|||
int columns = 80;
|
||||
extern cvar_t sv_listen_qw;
|
||||
#if defined(TCPCONNECT) && !defined(CLIENTONLY)
|
||||
extern cvar_t net_enable_tls, net_enable_http, net_enable_webrtcbroker, net_enable_websockets, net_enable_qizmo, net_enable_qtv;
|
||||
#if defined(HAVE_SSL)
|
||||
extern cvar_t net_enable_tls;
|
||||
#endif
|
||||
extern cvar_t net_enable_http, net_enable_webrtcbroker, net_enable_websockets, net_enable_qizmo, net_enable_qtv;
|
||||
#endif
|
||||
#ifdef NQPROT
|
||||
extern cvar_t sv_listen_nq, sv_listen_dp;
|
||||
|
@ -1978,8 +1981,10 @@ static void SV_Status_f (void)
|
|||
Con_Printf(" DTLS");
|
||||
#endif
|
||||
#if defined(TCPCONNECT) && !defined(CLIENTONLY)
|
||||
#if defined(HAVE_SSL)
|
||||
if (net_enable_tls.ival)
|
||||
Con_Printf(" TLS");
|
||||
#endif
|
||||
if (net_enable_http.ival)
|
||||
Con_Printf(" HTTP");
|
||||
if (net_enable_webrtcbroker.ival)
|
||||
|
|
|
@ -3893,7 +3893,6 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
|
|||
|
||||
// this is the frame we are creating
|
||||
frame = &client->frameunion.frames[client->netchan.incoming_sequence & UPDATE_MASK];
|
||||
if (!sv.paused)
|
||||
memset(frame->playerpresent, 0, sizeof(frame->playerpresent));
|
||||
|
||||
// find the client's PVS
|
||||
|
|
|
@ -58,8 +58,7 @@ cvar_t sv_nopvs = CVARD("sv_nopvs", "0", "Set to 1 to ignore pvs on the serv
|
|||
cvar_t fraglog_public = CVARD("fraglog_public", "1", "Enables support for connectionless fraglog requests");
|
||||
cvar_t fraglog_details = CVARD("fraglog_details", "1", "Bitmask\n1: killer+killee names.\n2: killer+killee teams\n4:timestamp.\n8:killer weapon\n16:killer+killee guid.\nFor compatibility, use 1(vanilla) or 7(mvdsv).");
|
||||
|
||||
cvar_t timeout = CVAR("timeout","65"); // seconds without any message
|
||||
cvar_t zombietime = CVAR("zombietime", "2"); // seconds to sink messages
|
||||
cvar_t zombietime = CVARD("zombietime", "2", "Client slots will not be reused for this number of seconds."); // seconds to sink messages
|
||||
|
||||
cvar_t sv_crypt_rcon = CVARFD("sv_crypt_rcon", "", CVAR_ARCHIVE, "Controls whether the rcon password must be hashed or not. Hashed passwords also partially prevent replay attacks, but does NOT prevent malicious actors from reading the commands/results.\n0: completely insecure. ONLY allows plain-text passwords. Do not use.\n1: Mandatory hashing (recommended).\nEmpty: Allow either, whether the password is secure or not is purely the client's responsibility/fault. Only use this for comptibility with old clients.");
|
||||
cvar_t sv_crypt_rcon_clockskew = CVARFD("sv_timestamplen", "60", CVAR_ARCHIVE, "Limits clock skew to reduce (delayed) replay attacks");
|
||||
|
@ -4780,7 +4779,6 @@ float SV_Frame (void)
|
|||
static int oldpackets;
|
||||
float oldtime;
|
||||
qboolean isidle;
|
||||
static int oldpaused;
|
||||
float timedelta;
|
||||
float delay;
|
||||
|
||||
|
@ -4820,10 +4818,10 @@ float SV_Frame (void)
|
|||
sv.paused ^= PAUSE_AUTO;
|
||||
#endif
|
||||
|
||||
if (oldpaused != sv.paused)
|
||||
if (sv.oldpaused != sv.paused)
|
||||
{
|
||||
sv.oldpaused = sv.paused;
|
||||
SV_PauseChanged();
|
||||
oldpaused = sv.paused;
|
||||
}
|
||||
|
||||
|
||||
|
@ -5084,7 +5082,7 @@ static void SV_InfoChanged(void *context, const char *key)
|
|||
#endif
|
||||
for (i = 0; i < svs.allocated_client_slots; i++)
|
||||
{
|
||||
if (svs.clients[i].state >= cs_connected)
|
||||
if (svs.clients[i].state >= cs_connected && !svs.clients[i].controller)
|
||||
{
|
||||
InfoSync_Add(&svs.clients[i].infosync, context, key);
|
||||
}
|
||||
|
@ -5155,7 +5153,6 @@ void SV_InitLocal (void)
|
|||
Cvar_Register (&sv_allow_splitscreen, cvargroup_serverinfo);
|
||||
Cvar_Register (&fbskins, cvargroup_serverinfo);
|
||||
|
||||
Cvar_Register (&timeout, cvargroup_servercontrol);
|
||||
Cvar_Register (&zombietime, cvargroup_servercontrol);
|
||||
|
||||
Cvar_Register (&sv_pupglow, cvargroup_serverinfo);
|
||||
|
@ -5615,8 +5612,10 @@ void SV_ExtractFromUserinfo (client_t *cl, qboolean verbose)
|
|||
cl->playercolor = top*16 + bottom;
|
||||
if (svs.gametype == GT_PROGS || svs.gametype == GT_Q1QVM)
|
||||
{
|
||||
#ifndef NOLEGACY
|
||||
if (cl->edict)
|
||||
cl->edict->xv->clientcolors = cl->playercolor;
|
||||
#endif
|
||||
MSG_WriteByte (&sv.nqreliable_datagram, svc_updatecolors);
|
||||
MSG_WriteByte (&sv.nqreliable_datagram, cl-svs.clients);
|
||||
MSG_WriteByte (&sv.nqreliable_datagram, cl->playercolor);
|
||||
|
|
|
@ -53,6 +53,7 @@ cvar_t sv_airaccelerate = CVAR( "sv_airaccelerate", "0.7");
|
|||
cvar_t sv_wateraccelerate = CVAR( "sv_wateraccelerate", "10");
|
||||
cvar_t sv_friction = CVAR( "sv_friction", "4");
|
||||
cvar_t sv_waterfriction = CVAR( "sv_waterfriction", "4");
|
||||
cvar_t sv_wallfriction = CVARD( "sv_wallfriction", "1", "Additional friction when running into walls");
|
||||
cvar_t sv_gameplayfix_noairborncorpse = CVAR( "sv_gameplayfix_noairborncorpse", "0");
|
||||
cvar_t sv_gameplayfix_multiplethinks = CVARD( "sv_gameplayfix_multiplethinks", "1", "Enables multiple thinks per entity per frame so small nextthink times are accurate. QuakeWorld mods expect a value of 1.");
|
||||
cvar_t sv_gameplayfix_stepdown = CVARD( "sv_gameplayfix_stepdown", "0", "Attempt to step down steps, instead of only up them. Affects non-predicted movetype_walk.");
|
||||
|
@ -87,6 +88,7 @@ void WPhys_Init(void)
|
|||
Cvar_Register (&sv_wateraccelerate, cvargroup_serverphysics);
|
||||
Cvar_Register (&sv_friction, cvargroup_serverphysics);
|
||||
Cvar_Register (&sv_waterfriction, cvargroup_serverphysics);
|
||||
Cvar_Register (&sv_wallfriction, cvargroup_serverphysics);
|
||||
Cvar_Register (&sv_sound_watersplash, cvargroup_serverphysics);
|
||||
Cvar_Register (&sv_sound_land, cvargroup_serverphysics);
|
||||
Cvar_Register (&sv_stepheight, cvargroup_serverphysics);
|
||||
|
@ -1887,7 +1889,7 @@ static void SV_WalkMove (edict_t *ent)
|
|||
#else
|
||||
|
||||
// 1/32 epsilon to keep floating point happy
|
||||
#define DIST_EPSILON (0.03125)
|
||||
/*#define DIST_EPSILON (0.03125)
|
||||
static int WPhys_SetOnGround (world_t *w, wedict_t *ent, const float *gravitydir)
|
||||
{
|
||||
vec3_t end;
|
||||
|
@ -1896,6 +1898,8 @@ static int WPhys_SetOnGround (world_t *w, wedict_t *ent, const float *gravitydir
|
|||
return 1;
|
||||
VectorMA(ent->v->origin, 1, gravitydir, end);
|
||||
trace = World_Move(w, ent->v->origin, ent->v->mins, ent->v->maxs, end, MOVE_NORMAL, (wedict_t*)ent);
|
||||
if (DotProduct(trace.plane.normal, ent->v->velocity) > 0)
|
||||
return 0; //velocity is away from the plane normal, so this does not count as a contact.
|
||||
if (trace.fraction <= DIST_EPSILON && -DotProduct(gravitydir, trace.plane.normal) >= 0.7)
|
||||
{
|
||||
ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
|
||||
|
@ -1903,7 +1907,7 @@ static int WPhys_SetOnGround (world_t *w, wedict_t *ent, const float *gravitydir
|
|||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
static void WPhys_WalkMove (world_t *w, wedict_t *ent, const float *gravitydir)
|
||||
{
|
||||
//int originalmove_clip;
|
||||
|
@ -1922,7 +1926,7 @@ static void WPhys_WalkMove (world_t *w, wedict_t *ent, const float *gravitydir)
|
|||
|
||||
clip = WPhys_FlyMove (w, ent, gravitydir, host_frametime, NULL);
|
||||
|
||||
WPhys_SetOnGround (w, ent, gravitydir);
|
||||
// WPhys_SetOnGround (w, ent, gravitydir);
|
||||
WPhys_CheckVelocity(w, ent);
|
||||
|
||||
VectorCopy(ent->v->origin, originalmove_origin);
|
||||
|
@ -1967,9 +1971,9 @@ static void WPhys_WalkMove (world_t *w, wedict_t *ent, const float *gravitydir)
|
|||
WPhys_PushEntity(w, ent, upmove, MOVE_NORMAL);
|
||||
|
||||
// move forward
|
||||
ent->v->velocity[2] = 0;
|
||||
VectorMA(ent->v->velocity, -DotProduct(gravitydir, ent->v->velocity), gravitydir, ent->v->velocity); //ent->v->velocity[2] = 0;
|
||||
clip = WPhys_FlyMove (w, ent, gravitydir, host_frametime, &steptrace);
|
||||
ent->v->velocity[2] += start_velocity[2];
|
||||
VectorMA(ent->v->velocity, DotProduct(gravitydir, start_velocity), gravitydir, ent->v->velocity); //ent->v->velocity[2] += start_velocity[2];
|
||||
|
||||
WPhys_CheckVelocity(w, ent);
|
||||
|
||||
|
@ -1994,22 +1998,23 @@ static void WPhys_WalkMove (world_t *w, wedict_t *ent, const float *gravitydir)
|
|||
//Con_Printf("step - ");
|
||||
|
||||
// extra friction based on view angle
|
||||
if (clip & 2)// && sv_wallfriction.value)
|
||||
if ((clip & 2) && sv_wallfriction.value)
|
||||
{
|
||||
// Con_Printf("wall\n");
|
||||
WPhys_WallFriction (ent, &steptrace);
|
||||
}
|
||||
}
|
||||
else if (!sv_gameplayfix_stepdown.ival || !oldonground || start_velocity[2] > 0 || ((int)ent->v->flags & FL_ONGROUND) || ent->v->waterlevel >= 2)
|
||||
else if (!sv_gameplayfix_stepdown.ival || !oldonground || -DotProduct(gravitydir,start_velocity) > 0 || ((int)ent->v->flags & FL_ONGROUND) || ent->v->waterlevel >= 2)
|
||||
return;
|
||||
|
||||
// move down
|
||||
VectorScale(gravitydir, -(-movevars.stepheight + start_velocity[2]*host_frametime), downmove);
|
||||
VectorScale(gravitydir, movevars.stepheight + (1/32.0) - DotProduct(gravitydir,start_velocity)*host_frametime, downmove);
|
||||
// FIXME: don't link?
|
||||
downtrace = WPhys_PushEntity (w, ent, downmove, MOVE_NORMAL);
|
||||
|
||||
if (downtrace.fraction < 1 && -DotProduct(gravitydir, downtrace.plane.normal) > 0.7)
|
||||
{
|
||||
if (DotProduct(downtrace.plane.normal, ent->v->velocity)<=0) //Spike: moving away from the surface should not count as onground.
|
||||
// LordHavoc: disabled this check so you can walk on monsters/players
|
||||
//if (ent->v->solid == SOLID_BSP)
|
||||
{
|
||||
|
@ -2031,7 +2036,7 @@ static void WPhys_WalkMove (world_t *w, wedict_t *ent, const float *gravitydir)
|
|||
ent->v->groundentity = originalmove_groundentity;
|
||||
}
|
||||
|
||||
WPhys_SetOnGround (w, ent, gravitydir);
|
||||
// WPhys_SetOnGround (w, ent, gravitydir);
|
||||
WPhys_CheckVelocity(w, ent);
|
||||
}
|
||||
#endif
|
||||
|
@ -2142,9 +2147,9 @@ void WPhys_RunEntity (world_t *w, wedict_t *ent)
|
|||
if (ent->lastruntime == w->framenum)
|
||||
return;
|
||||
ent->lastruntime = w->framenum;
|
||||
if (progstype == PROG_QW) //we don't use the field any more, but qw mods might.
|
||||
ent->v->lastruntime = w->physicstime;
|
||||
#ifndef CLIENTONLY
|
||||
if (progstype == PROG_QW && w == &sv.world) //we don't use the field any more, but qw mods might.
|
||||
ent->v->lastruntime = w->physicstime;
|
||||
svent = NULL;
|
||||
#endif
|
||||
}
|
||||
|
@ -2233,9 +2238,9 @@ void WPhys_RunEntity (world_t *w, wedict_t *ent)
|
|||
WPhys_WalkMove (w, ent, gravitydir);
|
||||
|
||||
#ifndef CLIENTONLY
|
||||
if (!(ent->entnum > 0 && ent->entnum <= sv.allocated_client_slots) && w == &sv.world)
|
||||
World_LinkEdict (w, ent, true);
|
||||
if (!svent)
|
||||
#endif
|
||||
World_LinkEdict (w, ent, true);
|
||||
break;
|
||||
#ifdef USERBE
|
||||
case MOVETYPE_PHYSICS:
|
||||
|
@ -2257,7 +2262,7 @@ void WPhys_RunEntity (world_t *w, wedict_t *ent)
|
|||
#ifndef CLIENTONLY
|
||||
if (svent)
|
||||
{
|
||||
World_LinkEdict (w, (wedict_t*)svent, true);
|
||||
World_LinkEdict (w, ent, true);
|
||||
|
||||
if (!host_client->spectator)
|
||||
{
|
||||
|
@ -2416,7 +2421,6 @@ void World_Physics_Frame(world_t *w)
|
|||
host_client = &svs.clients[i-1];
|
||||
sv_player = svs.clients[i-1].edict;
|
||||
|
||||
host_client->lastruncmd = newt;
|
||||
SV_PreRunCmd();
|
||||
#ifndef NEWSPEEDCHEATPROT
|
||||
svs.clients[i-1].last_check = 0;
|
||||
|
|
|
@ -1081,7 +1081,10 @@ void SV_SendClientPrespawnInfo(client_t *client)
|
|||
else if (client->prespawn_idx == 5)
|
||||
{
|
||||
ClientReliableWrite_Begin(client, svc_setpause, 2);
|
||||
ClientReliableWrite_Byte (client, sv.paused!=0);
|
||||
ClientReliableWrite_Byte (client, sv.oldpaused!=0);
|
||||
|
||||
if (sv.oldpaused && sv.oldpaused&~PAUSE_AUTO)
|
||||
SV_PrintToClient(client, PRINT_HIGH, "server is paused\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1796,7 +1799,7 @@ void SVQW_Spawn_f (void)
|
|||
|
||||
// send all current names, colors, and frag counts
|
||||
// FIXME: is this a good thing?
|
||||
SZ_Clear (&host_client->netchan.message);
|
||||
// SZ_Clear (&host_client->netchan.message);
|
||||
|
||||
// send current status of all other players
|
||||
|
||||
|
@ -2138,6 +2141,8 @@ void SV_Begin_Core(client_t *split)
|
|||
SV_PostRunCmd();
|
||||
host_client = oh;
|
||||
sv_player = oh?oh->edict:NULL;
|
||||
|
||||
host_client->lastruncmd = sv.time*1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2217,18 +2222,6 @@ void SV_Begin_f (void)
|
|||
SV_BroadcastTPrintf (PRINT_HIGH, "warning: %s eyes or player model does not match\n", host_client->name);
|
||||
}
|
||||
|
||||
// if we are paused, tell the client
|
||||
if (sv.paused)
|
||||
{
|
||||
if (!ISQ2CLIENT(host_client))
|
||||
{
|
||||
ClientReliableWrite_Begin (host_client, svc_setpause, 2);
|
||||
ClientReliableWrite_Byte (host_client, sv.paused!=0);
|
||||
}
|
||||
if (sv.paused&~PAUSE_AUTO)
|
||||
SV_ClientTPrintf(host_client, PRINT_HIGH, "server is paused\n");
|
||||
}
|
||||
|
||||
if (sendangles)
|
||||
{
|
||||
//
|
||||
|
@ -5518,7 +5511,7 @@ static void SVNQ_Spawn_f (void)
|
|||
|
||||
// send all current names, colors, and frag counts
|
||||
// FIXME: is this a good thing?
|
||||
SZ_Clear (&host_client->netchan.message);
|
||||
// SZ_Clear (&host_client->netchan.message);
|
||||
|
||||
// send current status of all other players
|
||||
|
||||
|
@ -5640,19 +5633,6 @@ static void SVNQ_Begin_f (void)
|
|||
SV_BroadcastTPrintf (PRINT_HIGH, "warning: %s eyes or player model not verified\n", host_client->name);
|
||||
}
|
||||
|
||||
|
||||
// if we are paused, tell the client
|
||||
if (sv.paused)
|
||||
{
|
||||
if (!ISQ2CLIENT(host_client))
|
||||
{
|
||||
ClientReliableWrite_Begin (host_client, svc_setpause, 2);
|
||||
ClientReliableWrite_Byte (host_client, sv.paused!=0);
|
||||
}
|
||||
if (sv.paused&~PAUSE_AUTO)
|
||||
SV_ClientTPrintf(host_client, PRINT_HIGH, "server is paused\n");
|
||||
}
|
||||
|
||||
if (sendangles)
|
||||
{
|
||||
//
|
||||
|
@ -6830,6 +6810,7 @@ size_t playertouchmax;
|
|||
void SV_PreRunCmd(void)
|
||||
{
|
||||
size_t max = MAX_EDICTS;//(sv.world.num_edicts+7)&~7;
|
||||
host_client->lastruncmd = sv.time*1000;
|
||||
if (max > playertouchmax)
|
||||
{
|
||||
playertouchmax = max;
|
||||
|
|
|
@ -2294,7 +2294,7 @@ static void World_ClipToNetwork (world_t *w, moveclip_t *clip)
|
|||
if (!((int)clip->passedict->xv->dimension_hit & 1))
|
||||
continue;
|
||||
|
||||
if (!model || model->loadstate != MLS_LOADED)
|
||||
if (!model || model->loadstate != MLS_LOADED || !model->funcs.NativeTrace)
|
||||
{
|
||||
model = NULL;
|
||||
|
||||
|
|
Loading…
Reference in a new issue