int _buildFileList(const char* path, bool insert, bool buildList)
{
	WIN32_FIND_DATA data;
	char spec[MAX_OSPATH];
	int count = 0;

	// Look for all files
	Com_sprintf(spec, sizeof(spec), "%s\\*.*", path);

	HANDLE h = FindFirstFile(spec, &data);
	while (h != INVALID_HANDLE_VALUE)
	{
		char full[MAX_OSPATH];
		Com_sprintf(full, sizeof(full), "%s\\%s", path, data.cFileName);

		if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			// Directory -- lets go recursive
			if (data.cFileName[0] != '.') {
				count += _buildFileList(full, insert, buildList);
			}
		}
		else
		{

			if(insert || buildList)
			{
				// Regular file -- add it to the table
				strlwr(full);
				unsigned int code = crc32(0, (const byte *)full, strlen(full));

				FileInfo info;
				info.name = CopyString(full);
				info.size = data.nFileSizeLow;

				if(insert)
				{
					s_Files->Insert(info, code);
				}

				if(buildList)
				{
					// get the length of the filename
					int len;
					len = strlen(info.name) + 1;

					// save the file code
					*(int*)buffer		=  code;
					buffer				+= sizeof(code);

					// save the name of the file
					strcpy((char*)buffer,info.name);
					buffer				+= len;

					// save the size of the file
					*(int*)buffer		= info.size;
					buffer				+= sizeof(info.size);
				}
			}

			count++;
		}

		// Continue the loop
		if (!FindNextFile(h, &data))
		{
			FindClose(h);
			return count;
		}
	}
	return count;
}
qboolean HTTPCreateWebadminMessage(ftRequest_t* request, msg_t* msg, char* sessionkey, httpPostVals_t* values)
{
    byte *buf;
    char qpath[MAX_QPATH];
    int len;
    const char *session;
    char banmsg[1024];

    buf = NULL;

    MSG_Init(msg, buf, 0);
    Com_Printf("URL: %s\n", request->url);
    if(!Q_strncmp(request->url, "/files", 6))
    {
        if(request->url[6] != '/' || request->url[7] == '\0')
        {
            return qfalse;
        }
        Com_sprintf(qpath, sizeof(qpath), "/webadmindata/%s", &request->url[7]);

        if(strstr(qpath, "..") != NULL || strstr(qpath, "::") != NULL)
        {
            return qfalse;
        }
        len = FS_ReadFile(qpath, (void**)&buf);

        if(len < 0)
        {
            return qfalse;
        }
        msg->data = buf;
        msg->cursize = len;
        msg->maxsize = len;
        FS_FreeFileKeepBuf( );
        return qtrue;
    }

    len = 0x20000;

    buf = Z_Malloc(len);
    if(buf == NULL)
    {
        return qfalse;
    }

    msg->data = buf;
    msg->cursize = 0;
    msg->maxsize = len;

    if (Q_stricmpn(request->url, "/webadmin", 9))
    {
        Webadmin_BuildMessage(msg, NULL, qfalse, NULL ,request->url, values);
        return qtrue;
    }

    qboolean invalidlogin = qfalse;
    const char* username = NULL;
    const char* password = NULL;


    if(SV_PlayerBannedByip(&request->remote, banmsg, sizeof(banmsg)))
    {
        Webadmin_BuildMessage(msg, NULL, qfalse, banmsg, request->url, values);
        return qtrue;
    }

    username = Auth_FindSessionID(sessionkey);

    if(username == NULL)
    {

        username = Webadmin_GetPostVal(values, "username");
        password = Webadmin_GetPostVal(values, "password");

        if(username && password)
        {
            session = Auth_GetSessionId(username, password);
            if(session == NULL)
            {
                Com_Printf("^1Invalid login\n");
                invalidlogin = qtrue;
                SV_PlayerAddBanByip(&request->remote, "Invalid login attempt. You have to wait 20 seconds", 0, NULL, 0, Com_GetRealtime() + 10);
                username = NULL;
            } else {
                Com_Printf("^2Successful login with username: %s\n", username);
            }


        } else {
            Com_Printf("No login!\n");
            session = NULL;
            username = NULL;
        }

        /* not longer than 127 or overflow */
        if(session != NULL)
        {
            strcpy(sessionkey, session);
        }
    } else {
        Com_Printf("Already logged in as: %s\n", username);
    }

    Webadmin_BuildMessage(msg, username, invalidlogin, NULL, request->url, values);

    return qtrue;
}
Exemple #3
0
/*
==================
Cmd_CallVote_f
==================
*/
void Cmd_CallVote_f( gentity_t *ent ) {
	char*	c;
	int		i;
	char	arg1[MAX_STRING_TOKENS];
	char	arg2[MAX_STRING_TOKENS];

	if ( !g_allowVote.integer ) {
		trap_SendServerCommand( ent-g_entities, "print \"Voting not allowed here.\n\"" );
		return;
	}

	if ( level.voteTime ) {
		trap_SendServerCommand( ent-g_entities, "print \"A vote is already in progress.\n\"" );
		return;
	}
	if ( ent->client->pers.voteCount >= MAX_VOTE_COUNT ) {
		trap_SendServerCommand( ent-g_entities, "print \"You have called the maximum number of votes.\n\"" );
		return;
	}
	if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
		trap_SendServerCommand( ent-g_entities, "print \"Not allowed to call a vote as spectator.\n\"" );
		return;
	}

	// make sure it is a valid command to vote on
	trap_Argv( 1, arg1, sizeof( arg1 ) );
	trap_Argv( 2, arg2, sizeof( arg2 ) );

	// check for command separators in arg2
	for( c = arg2; *c; ++c) {
		switch(*c) {
			case '\n':
			case '\r':
			case ';':
				trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
				return;
			break;
		}
	}

	if ( !Q_stricmp( arg1, "map_restart" ) ) {
	} else if ( !Q_stricmp( arg1, "nextmap" ) ) {
	} else if ( !Q_stricmp( arg1, "map" ) ) {
	} else if ( !Q_stricmp( arg1, "g_gametype" ) ) {
	} else if ( !Q_stricmp( arg1, "kick" ) ) {
	} else if ( !Q_stricmp( arg1, "clientkick" ) ) {
	} else if ( !Q_stricmp( arg1, "g_doWarmup" ) ) {
	} else if ( !Q_stricmp( arg1, "timelimit" ) ) {
	} else if ( !Q_stricmp( arg1, "fraglimit" ) ) {
	} else {
		trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
		trap_SendServerCommand( ent-g_entities, "print \"Vote commands are: map_restart, nextmap, map <mapname>, g_gametype <n>, kick <player>, clientkick <clientnum>, g_doWarmup, timelimit <time>, fraglimit <frags>.\n\"" );
		return;
	}

	// if there is still a vote to be executed
	if ( level.voteExecuteTime ) {
		level.voteExecuteTime = 0;
		trap_SendConsoleCommand( EXEC_APPEND, va("%s\n", level.voteString ) );
	}

	// special case for g_gametype, check for bad values
	if ( !Q_stricmp( arg1, "g_gametype" ) ) {
		i = atoi( arg2 );
		if( i == GT_SINGLE_PLAYER || i < GT_FFA || i >= GT_MAX_GAME_TYPE) {
			trap_SendServerCommand( ent-g_entities, "print \"Invalid gametype.\n\"" );
			return;
		}

		Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %d", arg1, i );
		Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s %s", arg1, gameNames[i] );
	} else if ( !Q_stricmp( arg1, "map" ) ) {
		// special case for map changes, we want to reset the nextmap setting
		// this allows a player to change maps, but not upset the map rotation
		char	s[MAX_STRING_CHARS];

		trap_Cvar_VariableStringBuffer( "nextmap", s, sizeof(s) );
		if (*s) {
			Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s; set nextmap \"%s\"", arg1, arg2, s );
		} else {
			Com_sprintf( level.voteString, sizeof( level.voteString ), "%s %s", arg1, arg2 );
		}
		Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
	} else if ( !Q_stricmp( arg1, "nextmap" ) ) {
		char	s[MAX_STRING_CHARS];

		trap_Cvar_VariableStringBuffer( "nextmap", s, sizeof(s) );
		if (!*s) {
			trap_SendServerCommand( ent-g_entities, "print \"nextmap not set.\n\"" );
			return;
		}
		Com_sprintf( level.voteString, sizeof( level.voteString ), "vstr nextmap");
		Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
	} else {
		Com_sprintf( level.voteString, sizeof( level.voteString ), "%s \"%s\"", arg1, arg2 );
		Com_sprintf( level.voteDisplayString, sizeof( level.voteDisplayString ), "%s", level.voteString );
	}

	trap_SendServerCommand( -1, va("print \"%s called a vote.\n\"", ent->client->pers.netname ) );

	// start the voting, the caller autoamtically votes yes
	level.voteTime = level.time;
	level.voteYes = 1;
	level.voteNo = 0;

	for ( i = 0 ; i < level.maxclients ; i++ ) {
		level.clients[i].ps.eFlags &= ~EF_VOTED;
	}
	ent->client->ps.eFlags |= EF_VOTED;

	trap_SetConfigstring( CS_VOTE_TIME, va("%i", level.voteTime ) );
	trap_SetConfigstring( CS_VOTE_STRING, level.voteDisplayString );	
	trap_SetConfigstring( CS_VOTE_YES, va("%i", level.voteYes ) );
	trap_SetConfigstring( CS_VOTE_NO, va("%i", level.voteNo ) );	
}
Exemple #4
0
//Mostly parts of other functions merged into one another.
//Puts the current UI stuff into a string, legalizes it, and then reads it back out.
void UI_ReadLegalForce(void)
{
	char fcfString[512];
	char forceStringValue[4];
	int strPlace = 0;
	int forcePlace = 0;
	int i = 0;
	char singleBuf[64];
	char info[MAX_INFO_VALUE];
	int c = 0;
	int iBuf = 0;
	int forcePowerRank = 0;
	int currank = 0;
	int forceTeam = 0;
	qboolean updateForceLater = qfalse;

	//First, stick them into a string.
	Com_sprintf(fcfString, sizeof(fcfString), "%i-%i-", uiForceRank, uiForceSide);
	strPlace = strlen(fcfString);

	while (forcePlace < NUM_FORCE_POWERS)
	{
		Com_sprintf(forceStringValue, sizeof(forceStringValue), "%i", uiForcePowersRank[forcePlace]);
		//Just use the force digit even if multiple digits. Shouldn't be longer than 1.
		fcfString[strPlace] = forceStringValue[0];
		strPlace++;
		forcePlace++;
	}
	fcfString[strPlace] = '\n';
	fcfString[strPlace+1] = 0;

	info[0] = '\0';
	trap_GetConfigString(CS_SERVERINFO, info, sizeof(info));

	if (atoi( Info_ValueForKey( info, "g_forceBasedTeams" ) ))
	{
		switch((int)(trap_Cvar_VariableValue("ui_myteam")))
		{
		case TEAM_RED:
			forceTeam = FORCE_DARKSIDE;
			break;
		case TEAM_BLUE:
			forceTeam = FORCE_LIGHTSIDE;
			break;
		default:
			break;
		}
	}
	//Second, legalize them.
	if (!BG_LegalizedForcePowers(fcfString, uiMaxRank, ui_freeSaber.integer, forceTeam, atoi( Info_ValueForKey( info, "g_gametype" )), 0))
	{ //if they were illegal, we should refresh them.
		updateForceLater = qtrue;
	}

	//Lastly, put them back into the UI storage from the legalized string
	i = 0;

	while (fcfString[i] && fcfString[i] != '-')
	{
		singleBuf[c] = fcfString[i];
		c++;
		i++;
	}
	singleBuf[c] = 0;
	c = 0;
	i++;

	iBuf = atoi(singleBuf);

	if (iBuf > uiMaxRank || iBuf < 0)
	{ //this force config uses a rank level higher than our currently restricted level.. so we can't use it
	  //FIXME: Print a message indicating this to the user
	//	return;
	}

	uiForceRank = iBuf;

	while (fcfString[i] && fcfString[i] != '-')
	{
		singleBuf[c] = fcfString[i];
		c++;
		i++;
	}
	singleBuf[c] = 0;
	c = 0;
	i++;

	uiForceSide = atoi(singleBuf);

	if (uiForceSide != FORCE_LIGHTSIDE &&
		uiForceSide != FORCE_DARKSIDE)
	{
		uiForceSide = FORCE_LIGHTSIDE;
		return;
	}

	//clear out the existing powers
	while (c < NUM_FORCE_POWERS)
	{
		uiForcePowersRank[c] = 0;
		c++;
	}
	uiForceUsed = 0;
	uiForceAvailable = forceMasteryPoints[uiForceRank];
	gTouchedForce = qtrue;

	for (c=0;fcfString[i]&&c<NUM_FORCE_POWERS;c++,i++)
	{
		singleBuf[0] = fcfString[i];
		singleBuf[1] = 0;
		iBuf = atoi(singleBuf);	// So, that means that Force Power "c" wants to be set to rank "iBuf".
		
		if (iBuf < 0)
		{
			iBuf = 0;
		}

		forcePowerRank = iBuf;

		if (forcePowerRank > FORCE_LEVEL_3 || forcePowerRank < 0)
		{ //err..  not correct
			continue;  // skip this power
		}

		if (uiForcePowerDarkLight[c] && uiForcePowerDarkLight[c] != uiForceSide)
		{ //Apparently the user has crafted a force config that has powers that don't fit with the config's side.
			continue;  // skip this power
		}

		// Accrue cost for each assigned rank for this power.
		for (currank=FORCE_LEVEL_1;currank<=forcePowerRank;currank++)
		{	
			if (bgForcePowerCost[c][currank] > uiForceAvailable)
			{	// Break out, we can't afford any more power.
				break;
			}
			// Pay for this rank of this power.
			uiForceUsed += bgForcePowerCost[c][currank];
			uiForceAvailable -= bgForcePowerCost[c][currank];

			uiForcePowersRank[c]++;
		}
	}

	if (uiForcePowersRank[FP_LEVITATION] < 1)
	{
		uiForcePowersRank[FP_LEVITATION]=1;
	}
	if (uiForcePowersRank[FP_SABER_OFFENSE] < 1 && ui_freeSaber.integer)
	{
		uiForcePowersRank[FP_SABER_OFFENSE]=1;
	}
	if (uiForcePowersRank[FP_SABER_DEFENSE] < 1 && ui_freeSaber.integer)
	{
		uiForcePowersRank[FP_SABER_DEFENSE]=1;
	}

	UpdateForceUsed();

	if (updateForceLater)
	{
		gTouchedForce = qtrue;
		UI_UpdateClientForcePowers(NULL);
	}
}
void Webadmin_BuildServerStatus(xml_t* xmlobj, qboolean showfullguid)
{
    int i, numcl;
    client_t* cl;
    char strbuf[MAX_STRING_CHARS];
    char colorbuf[2048];
    mvabuf;
    char teamallies[32];
    char teamaxis[32];
    gclient_t *gclient;
    qboolean teambased = qfalse;
    qboolean ffabased = qfalse;



    numcl = 0;

    for (cl = svs.clients, gclient = level.clients, i = 0; i < sv_maxclients->integer; i++, cl++, gclient++)
    {
        if (cl->state < CS_CONNECTED) {
            continue;
        }

        if(gclient->sess.sessionTeam == TEAM_RED || gclient->sess.sessionTeam == TEAM_BLUE)
        {
            teambased = qtrue;
            break;
        }
        if(gclient->sess.sessionTeam == TEAM_FREE)
        {
            ffabased = qtrue;
            break;
        }
    }


    XO1("table","class","table table-striped table-bordered cod4xtable");
    XA("<th>CID</th><th>Name</th><th>UID/GUID</th><th>Power</th><th>Score</th><th>Ping</th>");


    if(teambased)
    {


        if(!Q_strncmp(g_TeamName_Axis->string,"MPUI_SPETSNAZ", 13))
            Q_strncpyz(teamaxis, "Spetsnaz", sizeof(teamaxis));
        else if(!Q_strncmp(g_TeamName_Axis->string,"MPUI_OPFOR", 10))
            Q_strncpyz(teamaxis, "Opfor", sizeof(teamaxis));
        else
            Q_strncpyz(teamaxis, g_TeamName_Axis->string, sizeof(teamaxis));

        if(!Q_strncmp(g_TeamName_Allies->string,"MPUI_MARINES", 12))
            Q_strncpyz(teamallies, "Marines", sizeof(teamallies));
        else if(!Q_strncmp(g_TeamName_Allies->string,"MPUI_SAS", 8))
            Q_strncpyz(teamallies, "S.A.S.", sizeof(teamallies));
        else
            Q_strncpyz(teamallies, g_TeamName_Allies->string, sizeof(teamallies));

        XO("tr");
        XO1("td", "colspan", "6");
        XA(teamaxis);
        XC;
        XC;
        for (cl = svs.clients, gclient = level.clients, i = 0; i < sv_maxclients->integer; i++, cl++, gclient++)
        {
            if (cl->state < CS_CONNECTED) {
                continue;
            }

            if(gclient->sess.sessionTeam != TEAM_RED)
            {
                continue;
            }

            ++numcl;

            XO("tr");

            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", i);//CID
            XA(strbuf);

            XO("td");//Name
            XA(Webadmin_ConvertToHTMLColor(cl->name, colorbuf, sizeof(colorbuf)));
            XC;

            XO("td");//GUID
            if(cl->uid > 0)
            {
                XA(va("%d", cl->uid));
            } else {
                if(showfullguid)
                    XA(cl->pbguid);
                else
                    XA(&cl->pbguid[24]);
            }

            XC;

            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", cl->power);//Ping
            XA(strbuf);

            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", gclient->pers.scoreboard.score);//Score
            XA(strbuf);


            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", cl->ping);//Ping
            XA(strbuf);
            XC;
        }

        XO("tr");
        XO1("td", "colspan", "6");
        XA(teamallies);
        XC;
        XC;
        for (cl = svs.clients, gclient = level.clients, i = 0; i < sv_maxclients->integer; i++, cl++, gclient++)
        {
            if (cl->state < CS_CONNECTED) {
                continue;
            }

            if(gclient->sess.sessionTeam != TEAM_BLUE)
            {
                continue;
            }

            ++numcl;

            XO("tr");

            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", i);//CID
            XA(strbuf);

            XO("td");//Name
            XA(Webadmin_ConvertToHTMLColor(cl->name, colorbuf, sizeof(colorbuf)));
            XC;

            XO("td");//GUID
            if(cl->uid > 0)
            {
                XA(va("%d", cl->uid));
            } else {
                if(showfullguid)
                    XA(cl->pbguid);
                else
                    XA(&cl->pbguid[24]);
            }

            XC;

            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", cl->power);//Ping
            XA(strbuf);

            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", gclient->pers.scoreboard.score);//Score
            XA(strbuf);


            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", cl->ping);//Ping
            XA(strbuf);
            XC;
        }


    } else if(ffabased) {

        XO("tr");
        XO1("td", "colspan", "6");
        XA("Players");
        XC;
        XC;

        for (cl = svs.clients, gclient = level.clients, i = 0; i < sv_maxclients->integer; i++, cl++, gclient++)
        {
            if (cl->state < CS_CONNECTED) {
                continue;
            }

            if(gclient->sess.sessionTeam != TEAM_FREE)
            {
                continue;
            }

            ++numcl;

            XO("tr");

            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", i);//CID
            XA(strbuf);

            XO("td");//Name
            XA(Webadmin_ConvertToHTMLColor(cl->name, colorbuf, sizeof(colorbuf)));
            XC;

            XO("td");//GUID
            if(cl->uid > 0)
            {
                XA(va("%d", cl->uid));
            } else {
                if(showfullguid)
                    XA(cl->pbguid);
                else
                    XA(&cl->pbguid[24]);
            }

            XC;

            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", cl->power);//Ping
            XA(strbuf);

            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", gclient->pers.scoreboard.score);//Score
            XA(strbuf);


            Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", cl->ping);//Ping
            XA(strbuf);
            XC;
        }

    }
    XO("tr");
    XO1("td", "colspan", "6");
    XA("Spectators");
    XC;
    XC;
    for (cl = svs.clients, gclient = level.clients, i = 0; i < sv_maxclients->integer; i++, cl++, gclient++)
    {
        if (cl->state < CS_CONNECTED) {
            continue;
        }

        if(gclient->sess.sessionTeam != TEAM_SPECTATOR)
        {
            continue;
        }

        ++numcl;

        XO("tr");

        Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", i);//CID
        XA(strbuf);

        XO("td");//Name
        XA(Webadmin_ConvertToHTMLColor(cl->name, colorbuf, sizeof(colorbuf)));
        XC;

        XO("td");//GUID
        if(cl->uid > 0)
        {
            XA(va("%d", cl->uid));
        } else {
            if(showfullguid)
                XA(cl->pbguid);
            else
                XA(&cl->pbguid[24]);
        }

        XC;

        Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", cl->power);//Ping
        XA(strbuf);

        Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", gclient->pers.scoreboard.score);//Score
        XA(strbuf);


        Com_sprintf(strbuf, sizeof(strbuf), "<td>%d</td>", cl->ping);//Ping
        XA(strbuf);
        XC;
    }

    XC;


    XA(va("%d players are on server", numcl));

}
Exemple #6
0
// This function is called recursively when a logical message has to be split into multiple lines
void CG_ChatboxAdd( const char *message, qboolean multiLine ) {
	chatEntry_t *chat = &chatbox.chatBuffer[MAX_CHATBOX_ENTRIES-1];
	size_t strLength = 0;
	int i = 0;
	float accumLength = 0.0f;

	chatbox.numActiveLines++;

	//Stop scrolling up if we've already scrolled, similar to console behaviour
	if ( chatbox.scrollAmount < 0 )
		chatbox.scrollAmount = MAX( chatbox.scrollAmount - 1, chatbox.numActiveLines >= cg_chatboxLineCount->integer ? ((MIN(chatbox.numActiveLines, MAX_CHATBOX_ENTRIES)-cg_chatboxLineCount->integer)*-1) : 0 ); //cb->scrollAmount--;

	for ( i=0, strLength=strlen( message );
		 i<strLength && i<CHAT_MESSAGE_LENGTH;
		 i++ )
	{
		char *p = (char*)&message[i];
		char buf[1];

		buf[0] = *p;

		if ( !Q_IsColorString( p ) && (i > 0 && !Q_IsColorString( p-1 )) )
			accumLength += CG_Text_Width( buf, CHATBOX_FONT_SCALE, -1 );

		if ( accumLength > SCREEN_WIDTH && (i>0 && !Q_IsColorString( p-1 )) ) {
			char lastColor = '2';
			int j = i;
			int savedOffset = i;
			char tempMessage[CHAT_MESSAGE_LENGTH];

			//Attempt to back-track, find a space (' ') within X characters or pixels
			//RAZTODO: Another method using character width? Meh
			while ( message[i] != ' ' )
			{
				if ( i <= 0 || i < savedOffset-16 )
				{
					i = j = savedOffset;
					break;
				}
				i--;
				j--;
			}

			memmove( &chatbox.chatBuffer[0], &chatbox.chatBuffer[1], sizeof( chatbox.chatBuffer ) - sizeof( chatEntry_t ) );
			memset( chat, 0, sizeof( chatEntry_t ) ); //Clear the last element, ready for writing
			Q_strncpyz( chat->message, message, i+1 );
			chat->time = cg.time + cg_chatboxMsgTime->integer*1000;

			chat->isUsed = qtrue;
			for ( j=i; j>=0; j-- )
			{
				if ( message[j] == '^' && message[j+1] >= '0' && message[j+1] <= '9' )
				{
					lastColor = message[j+1];
					break;
				}
			}
			Com_sprintf( tempMessage, sizeof( tempMessage ), "^%c%s", lastColor, (const char *)(message + i) );

			//Recursively insert until we don't have to split the message
			CG_ChatboxAdd( tempMessage, qtrue );
			return;
		}
	}

	memmove( &chatbox.chatBuffer[0], &chatbox.chatBuffer[1], sizeof( chatbox.chatBuffer ) - sizeof( chatEntry_t ) );
	memset( chat, 0, sizeof( chatEntry_t ) ); //Clear the last element, ready for writing
	Q_strncpyz( chat->message, message, i+1 );

	chat->time = cg.time + cg_chatboxMsgTime->integer*1000;
	chat->isUsed = qtrue;
}
/*
==============
SV_InitGame

A brand new game has been started
==============
*/
void SV_InitGame (void)
{
	int		i;
	edict_t	*ent;
	char	idmaster[32];

	if (svs.initialized)
	{
		// cause any connected clients to reconnect
		SV_Shutdown ("Server restarted\n", true);
	}
	else
	{
		// make sure the client is down
		CL_Drop ();
		SCR_BeginLoadingPlaque ();
	}

	// get any latched variable changes (maxclients, etc)
	Cvar_GetLatchedVars ();

	svs.initialized = true;

	if (Cvar_VariableValue ("coop") && Cvar_VariableValue ("deathmatch"))
	{
		Com_Printf("Deathmatch and Coop both set, disabling Coop\n");
		Cvar_FullSet ("coop", "0",  CVAR_SERVERINFO | CVAR_LATCH);
	}

	// dedicated servers are can't be single player and are usually DM
	// so unless they explicity set coop, force it to deathmatch
	if (dedicated->value)
	{
		if (!Cvar_VariableValue ("coop"))
			Cvar_FullSet ("deathmatch", "1",  CVAR_SERVERINFO | CVAR_LATCH);
	}

	// init clients
	if (Cvar_VariableValue ("deathmatch"))
	{
		if (maxclients->value <= 1)
			Cvar_FullSet ("maxclients", "8", CVAR_SERVERINFO | CVAR_LATCH);
		else if (maxclients->value > MAX_CLIENTS)
			Cvar_FullSet ("maxclients", va("%i", MAX_CLIENTS), CVAR_SERVERINFO | CVAR_LATCH);
	}
	else if (Cvar_VariableValue ("coop"))
	{
		if (maxclients->value <= 1 || maxclients->value > 4)
			Cvar_FullSet ("maxclients", "4", CVAR_SERVERINFO | CVAR_LATCH);
#ifdef COPYPROTECT
		if (!sv.attractloop && !dedicated->value)
			Sys_CopyProtect ();
#endif
	}
	else	// non-deathmatch, non-coop is one player
	{
		Cvar_FullSet ("maxclients", "1", CVAR_SERVERINFO | CVAR_LATCH);
#ifdef COPYPROTECT
		if (!sv.attractloop)
			Sys_CopyProtect ();
#endif
	}

	svs.spawncount = rand();
	svs.clients = Z_Malloc (sizeof(client_t)*maxclients->value);
	svs.num_client_entities = maxclients->value*UPDATE_BACKUP*64;
	svs.client_entities = Z_Malloc (sizeof(entity_state_t)*svs.num_client_entities);

	// init network stuff
	NET_Config ( (maxclients->value > 1) );

	// heartbeats will always be sent to the id master
	svs.last_heartbeat = -99999;		// send immediately
	Com_sprintf(idmaster, sizeof(idmaster), "192.246.40.37:%i", PORT_MASTER);
	NET_StringToAdr (idmaster, &master_adr[0]);

	// init game
	SV_InitGameProgs ();
	for (i=0 ; i<maxclients->value ; i++)
	{
		ent = EDICT_NUM(i+1);
		ent->s.number = i+1;
		svs.clients[i].edict = ent;
		memset (&svs.clients[i].lastcmd, 0, sizeof(svs.clients[i].lastcmd));
	}
}
Exemple #8
0
/*
================
SV_SpawnServer

Change the server to a new map, taking all connected
clients along with it.

================
*/
void SV_SpawnServer (char *server, char *spawnpoint, server_state_t serverstate, 
					 qboolean attractloop, qboolean loadgame)
{
	int			i;
	unsigned	checksum;
	float		cer_public;
	float		cer_sv_login;
	float		cer_sv_forcesky;
	float		cer_guntemp_inc;
	float		cer_guntemp_dec;
	float		cer_elim;
	float		cer_fraglimit;
	float		cer_timelimit;

	if (attractloop)
		Cvar_Set("paused", "0");

	Com_Printf("------- Server Initialization -------\n");
	Com_DPrintf("SpawnServer: %s\n", server);

	if (sv.demofile)
		fclose(sv.demofile);

	svs.spawncount++;		// any partially connected client will be restarted
	sv.state = ss_dead;
	Com_SetServerState(sv.state);

	// wipe the entire per-level structure
	memset(&sv, 0, sizeof(sv));
	svs.realtime = 0;
	sv.loadgame = loadgame;
	sv.attractloop = attractloop;

	// save name for levels that don't set message
	strcpy(sv.configstrings[CS_NAME], server);

	sprintf(sv.configstrings[CS_AIRACCEL], "%g", sv_airaccelerate->value);
	pm_airaccelerate = sv_airaccelerate->value;

	SV_ReplicatePhysicsSettings(); // jitmovephysics

	sprintf(sv.configstrings[CS_SERVEREVERSION], "Enginever: %g Enginebuild: %d", VERSION, BUILD);
	SZ_Init(&sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));
	strcpy(sv.name, server);

	// leave slots at start for clients only
	for (i = 0; i < maxclients->value; i++)
	{
		// needs to reconnect
		if (svs.clients[i].state > cs_connected)
			svs.clients[i].state = cs_connected;

		svs.clients[i].lastframe = -1;
	}

	sv.time = 1000;
	strcpy(sv.name, server);
	strcpy(sv.configstrings[CS_NAME], server);

	if (serverstate != ss_game)
	{
		sv.models[1] = CM_LoadMap("", false, &checksum);	// no real map
	}
	else
	{
		Com_sprintf(sv.configstrings[CS_MODELS + 1], sizeof(sv.configstrings[CS_MODELS + 1]), "maps/%s.bsp", server);
		sv.models[1] = CM_LoadMap(sv.configstrings[CS_MODELS + 1], false, &checksum);
	}

	Com_sprintf(sv.configstrings[CS_MAPCHECKSUM], sizeof(sv.configstrings[CS_MAPCHECKSUM]), "%i", checksum);

	// clear physics interaction links
	SV_ClearWorld();
	
	for (i = 1; i < CM_NumInlineModels(); i++)
	{
		Com_sprintf (sv.configstrings[CS_MODELS + 1 + i], sizeof(sv.configstrings[CS_MODELS + 1 + i]), "*%i", i);
		sv.models[i + 1] = CM_InlineModel(sv.configstrings[CS_MODELS + 1 + i]);
	}

	//
	// spawn the rest of the entities on the map
	//	

	// precache and static commands can be issued during
	// map initialization
	sv.state = ss_loading;
	Com_SetServerState(sv.state);

	//if(!sv.attractloop) // jitdemo -- don't spawn game stuff while demo is playing!
	{
		// load and spawn all other entities
		ge->SpawnEntities(sv.name, CM_EntityString(), spawnpoint);

		// run two frames to allow everything to settle
		ge->RunFrame();
		ge->RunFrame();
	}

	// all precaches are complete
	sv.state = serverstate;
	Com_SetServerState(sv.state);
	
	// create a baseline for more efficient communications
	SV_CreateBaseline();

	// check for a savegame
	SV_CheckForSavegame();

	// set serverinfo variable
	Cvar_FullSet("mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET, true);

	// T3RR0R15T: certificated server info (default settings atm)
	//cer_maxclients			= Cvar_VariableValue("maxclients");
	cer_elim				= Cvar_VariableValue("elim");
	cer_fraglimit			= Cvar_VariableValue("fraglimit");
	cer_timelimit			= Cvar_VariableValue("timelimit");
	//cer_sv_minclientbuild   = Cvar_VariableValue("sv_minclientbuild");
	cer_guntemp_inc			= Cvar_VariableValue("guntemp_inc");
	cer_guntemp_dec			= Cvar_VariableValue("guntemp_dec");
	cer_sv_forcesky			= Cvar_VariableValue("sv_forcesky");
	cer_sv_login			= Cvar_VariableValue("sv_login");
	cer_public				= Cvar_VariableValue("public");

	// Don't forget to change the SV_Certificatedinfo_f (sv_ccmds.c), if you change something here !
	if (//cer_maxclients->value == 16 &&
		(cer_elim >= 60.0f || cer_elim == 0.0f) &&
		cer_fraglimit == 50.0f &&
		cer_timelimit == 20.0f &&
		//cer_sv_minclientbuild >= 28.0f &&
		cer_guntemp_inc >= 10.5f && // 11 + some leeway
		cer_guntemp_dec <= 4.2f && // 4 + some leeway
		cer_sv_forcesky &&
		cer_sv_login &&
		cer_public)
	{
		Cvar_FullSet("sv_certificated", "1", CVAR_SERVERINFO | CVAR_NOSET, true);
	} else {
		Cvar_FullSet("sv_certificated", "0", CVAR_SERVERINFO | CVAR_NOSET, true);
	}

	Com_Printf("-------------------------------------\n");
}
Exemple #9
0
/*
======================
SV_Map

  the full syntax is:

  map [*]<map>$<startspot>+<nextserver>

command from the console or progs.
Map can also be a.cin, .pcx, or .dm2 file
Nextserver is used to allow a cinematic to play, then proceed to
another level:

	map tram.cin+jail_e3
======================
*/
void SV_Map (qboolean attractloop, const char *levelstring, qboolean loadgame)
{
	char	level[MAX_QPATH];
	char	*ch;
	int		l;
	char	spawnpoint[MAX_QPATH];

	strcpy(level, levelstring); // jit - copy level string before it gets modified by other commands (since it's a command argument)
	sv.loadgame = loadgame;
	sv.attractloop = attractloop;

	if (sv.state == ss_dead && !sv.loadgame)
		SV_InitGame();	// the game is just starting

	// if there is a + in the map, set nextserver to the remainder
	ch = strstr(level, "+");

	if (ch)
	{
		*ch = 0;
		Cvar_Set("nextserver", va("gamemap \"%s\"", ch + 1));
	}
	else
	{
		Cvar_Set("nextserver", "");
	}

	//ZOID special hack for end game screen in coop mode
	if (Cvar_VariableValue("coop") && Q_strcaseeq(level, "victory.pcx"))
		Cvar_Set("nextserver", "gamemap \"*base1\"");

	// if there is a $, use the remainder as a spawnpoint
	ch = strstr(level, "$");

	if (ch)
	{
		*ch = 0;
		strcpy(spawnpoint, ch + 1);
	}
	else
	{
		spawnpoint[0] = 0;
	}

	// skip the end-of-unit flag if necessary
	if (level[0] == '*')
		strcpy (level, level+1);

	l = strlen(level);

	if (l > 4 && Q_streq(level + l - 4, ".cin"))
	{
		SCR_BeginLoadingPlaque(NULL);			// for local system
		SV_BroadcastCommand("changing\n");
		SV_SpawnServer(level, spawnpoint, ss_cinematic, attractloop, loadgame);
	}
	else if (l > 4 && Q_streq(level + l - 4, ".dm2"))
	{
		SCR_BeginLoadingPlaque(NULL);			// for local system
		SV_BroadcastCommand("changing\n");
		SV_SpawnServer(level, spawnpoint, ss_demo, attractloop, loadgame);
	}
	else if (l > 4 && Q_streq(level + l - 4, ".pcx"))
	{
		SCR_BeginLoadingPlaque(NULL);			// for local system
		SV_BroadcastCommand("changing\n");
		SV_SpawnServer(level, spawnpoint, ss_pic, attractloop, loadgame);
	}
	else
	{
		char changing_cmd[1024];

		if (!dedicated->value)
			SCR_BeginLoadingPlaque(level);			// for local system

		Com_sprintf(changing_cmd, sizeof(changing_cmd), "changing \"%s\"\n", level);
		SV_BroadcastCommand(changing_cmd);
		SV_SendClientMessages();
		SV_SpawnServer(level, spawnpoint, ss_game, attractloop, loadgame);
		Cbuf_CopyToDefer();
	}

	SV_BroadcastCommand("reconnect\n");
}
// *** Referee voting ***
int G_Referee_v(gentity_t *ent, unsigned int dwVoteIndex, char *arg, char *arg2, qboolean fRefereeCmd)
{
	// Vote request (vote is being initiated)
	if (arg)
	{
		int pid;

		if (!vote_allow_referee.integer && ent && !ent->client->sess.referee)
		{
			G_voteDisableMessage(ent, arg);
			return(G_INVALID);
		}

		if (!ent->client->sess.referee && level.numPlayingClients < 3)
		{
			G_refPrintf(ent, "Sorry, not enough clients in the game to vote for a referee");
			return(G_INVALID);
		}

		if (ent->client->sess.referee && trap_Argc() == 2)
		{
			G_playersMessage(ent);
			return(G_INVALID);
		}
		else if (trap_Argc() == 2)
		{
			pid = ent - g_entities;
		}
		else if (G_voteDescription(ent, fRefereeCmd, dwVoteIndex))
		{
			return(G_INVALID);
		}
		else if ((pid = ClientNumberFromString(ent, arg2)) == -1)
		{
			return(G_INVALID);
		}

		if (level.clients[pid].sess.referee)
		{
			G_refPrintf(ent, "[lof]%s [lon]is already a referee!", level.clients[pid].pers.netname);
			return(-1);
		}

		Com_sprintf(level.voteInfo.vote_value, VOTE_MAXSTRING, "%d", pid);
		Com_sprintf(arg2, VOTE_MAXSTRING, "%s", level.clients[pid].pers.netname);

		// Vote action (vote has passed)
	}
	else
	{
		// Voting in a new referee
		gclient_t *cl = &level.clients[atoi(level.voteInfo.vote_value)];

		if (cl->pers.connected == CON_DISCONNECTED)
		{
			AP("print \"Player left before becoming referee\n\"");
		}
		else
		{
			cl->sess.referee     = RL_REFEREE; // FIXME: Differentiate voted refs from passworded refs
			cl->sess.spec_invite = TEAM_AXIS | TEAM_ALLIES;
			AP(va("cp \"%s^7 is now a referee\n\"", cl->pers.netname));
			ClientUserinfoChanged(atoi(level.voteInfo.vote_value));
		}
	}
	return(G_OK);
}
Exemple #11
0
script_t *LoadScriptFile(const char *filename) {
	fileHandle_t h_up, h_patch;
	char pathname[MAX_QPATH], pathpatch[MAX_QPATH];
	unsigned long inhash = 0;
	int inlength, outlength, plength;
	char *inbuffer, *outbuffer, *pbuffer;
	script_t *script;

	if (strlen(basefolder)) {
		Com_sprintf(pathname, sizeof(pathname), "%s/%s", basefolder, filename);
		Com_sprintf(pathpatch, sizeof(pathpatch), "%s/%s_patch", basefolder, filename);
	} else {
		Com_sprintf(pathname, sizeof(pathname), "%s", filename);
		Com_sprintf(pathpatch, sizeof(pathpatch), "%s_patch", filename);
	}
	inlength = botimport.FS_FOpenFileHash(pathname, &h_up, FS_READ, &inhash);
	if (!h_up) return NULL;
	plength = botimport.FS_FOpenFile(pathpatch, &h_patch, FS_READ);

	inbuffer = (char *)GetClearedMemory(inlength + 1);
	botimport.FS_Read(inbuffer, inlength, h_up);
	botimport.FS_FCloseFile(h_up);

	if (h_patch) {
		pbuffer = (char *)GetClearedMemory(plength + 1);
		botimport.FS_Read(pbuffer, plength, h_patch);
		botimport.FS_FCloseFile(h_patch);

		Com_Printf("patching menu file %s...\n", pathname);
		outlength = MV_MenuPatchFile(inbuffer, inhash, pbuffer, &outbuffer);
		if (outlength < 0) {
			if (outlength == ERROR_SYNTAX) {
				Com_Printf("patching failed: syntax error in patchfile\n");
			} else if (outlength == ERROR_HASH) {
				Com_Printf("patching skipped: hash mismatch\n");
			}

			outbuffer = inbuffer;
			outlength = inlength;
		}

		FreeMemory(pbuffer);

		// uncomment to dump patched file with _patched suffix; menu_patch

		/*
		char patchedName[MAX_QPATH];
		fileHandle_t patchedFile;
		Com_sprintf(patchedName, sizeof(patchedName), "%s_patched", pathname);
		botimport.FS_FOpenFile(patchedName, &patchedFile, FS_WRITE);
		botimport.FS_Write(outbuffer, outlength, patchedFile);
		botimport.FS_FCloseFile(patchedFile);
		*/
	} else {
		outbuffer = inbuffer;
		outlength = inlength;
	}

	script = (script_t *)GetClearedMemory(sizeof(script_t) + outlength + 1);
	Com_Memset(script, 0, sizeof(script_t));
	strcpy(script->filename, filename);
	script->buffer = (char *)script + sizeof(script_t);
	script->buffer[outlength] = 0;
	script->length = outlength;
	script->script_p = script->buffer;
	script->lastscript_p = script->buffer;
	script->end_p = &script->buffer[outlength];
	script->tokenavailable = 0;
	script->line = 1;
	script->lastline = 1;
	SetScriptPunctuations(script, NULL);

	Com_Memcpy(script->buffer, outbuffer, outlength);
	FreeMemory(outbuffer);

	if (outbuffer != inbuffer)
		FreeMemory(inbuffer);

	script->length = COM_Compress(script->buffer);
	return script;
} //end of the function LoadScriptFile
// *** Player Mute ***
int G_Mute_v(gentity_t *ent, unsigned int dwVoteIndex, char *arg, char *arg2, qboolean fRefereeCmd)
{
	if (fRefereeCmd)
	{
		// handled elsewhere
		return(G_NOTFOUND);
	}

	// Vote request (vote is being initiated)
	if (arg)
	{
		int pid;

		if (!vote_allow_muting.integer && ent && !ent->client->sess.referee)
		{
			G_voteDisableMessage(ent, arg);
			return(G_INVALID);
		}
		else if (G_voteDescription(ent, fRefereeCmd, dwVoteIndex))
		{
			return(G_INVALID);
		}
		else if ((pid = ClientNumberFromString(ent, arg2)) == -1)
		{
			return(G_INVALID);
		}

		if (level.clients[pid].sess.referee)
		{
			G_refPrintf(ent, "Can't vote to mute referees!");
			return(G_INVALID);
		}

		if (level.clients[pid].sess.muted)
		{
			G_refPrintf(ent, "Player is already muted!");
			return(G_INVALID);
		}

		Com_sprintf(level.voteInfo.vote_value, VOTE_MAXSTRING, "%d", pid);
		Com_sprintf(arg2, VOTE_MAXSTRING, "%s", level.clients[pid].pers.netname);

		// Vote action (vote has passed)
	}
	else
	{
		int pid = atoi(level.voteInfo.vote_value);

		// Mute a player
		if (level.clients[pid].sess.referee != RL_RCON)
		{
			trap_SendServerCommand(pid, va("cpm \"^3You have been muted\""));
			level.clients[pid].sess.muted = qtrue;
			AP(va("cp \"%s\n^3has been muted!\n\"", level.clients[pid].pers.netname));
			ClientUserinfoChanged(pid);
		}
		else
		{
			G_Printf("Cannot mute a referee.\n");
		}
	}

	return(G_OK);
}
// *** Un-Referee voting ***
int G_Unreferee_v(gentity_t *ent, unsigned int dwVoteIndex, char *arg, char *arg2, qboolean fRefereeCmd)
{
	// Vote request (vote is being initiated)
	if (arg)
	{
		int pid;

		if (!vote_allow_referee.integer && ent && !ent->client->sess.referee)
		{
			G_voteDisableMessage(ent, arg);
			return(G_INVALID);
		}

		if (ent->client->sess.referee && trap_Argc() == 2)
		{
			G_playersMessage(ent);
			return(G_INVALID);
		}
		else if (trap_Argc() == 2)
		{
			pid = ent - g_entities;
		}
		else if (G_voteDescription(ent, fRefereeCmd, dwVoteIndex))
		{
			return(G_INVALID);
		}
		else if ((pid = ClientNumberFromString(ent, arg2)) == -1)
		{
			return(G_INVALID);
		}

		if (level.clients[pid].sess.referee == RL_NONE)
		{
			G_refPrintf(ent, "[lof]%s [lon]isn't a referee!", level.clients[pid].pers.netname);
			return(G_INVALID);
		}

		if (level.clients[pid].sess.referee == RL_RCON)
		{
			G_refPrintf(ent, "[lof]%s's [lon]status cannot be removed", level.clients[pid].pers.netname);
			return(G_INVALID);
		}

		if (level.clients[pid].pers.localClient)
		{
			G_refPrintf(ent, "[lof]%s's [lon]is the Server Host", level.clients[pid].pers.netname);
			return(G_INVALID);
		}

		Com_sprintf(level.voteInfo.vote_value, VOTE_MAXSTRING, "%d", pid);
		Com_sprintf(arg2, VOTE_MAXSTRING, "%s", level.clients[pid].pers.netname);

		// Vote action (vote has passed)
	}
	else
	{
		// Stripping of referee status
		gclient_t *cl = &level.clients[atoi(level.voteInfo.vote_value)];

		cl->sess.referee     = RL_NONE;
		cl->sess.spec_invite = 0;
		AP(va("cp \"%s^7\nis no longer a referee\n\"", cl->pers.netname));
		ClientUserinfoChanged(atoi(level.voteInfo.vote_value));
	}

	return(G_OK);
}
Exemple #14
0
/*
=======================================================================================================================================
CL_GetServerCommand

Set up argc/argv for the given command.
=======================================================================================================================================
*/
qboolean CL_GetServerCommand(int serverCommandNumber) {
	char *s;
	char *cmd;
	static char bigConfigString[BIG_INFO_STRING];
	int argc;

	// if we have irretrievably lost a reliable command, drop the connection
	if (serverCommandNumber <= clc.serverCommandSequence - MAX_RELIABLE_COMMANDS) {
		// when a demo record was started after the client got a whole bunch of reliable commands then the client never got those first
		// reliable commands
		if (clc.demoplaying) {
			return qfalse;
		}

		Com_Error(ERR_DROP, "CL_GetServerCommand: a reliable command was cycled out");
		return qfalse;
	}

	if (serverCommandNumber > clc.serverCommandSequence) {
		Com_Error(ERR_DROP, "CL_GetServerCommand: requested a command not received");
		return qfalse;
	}

	s = clc.serverCommands[serverCommandNumber & (MAX_RELIABLE_COMMANDS - 1)];
	clc.lastExecutedServerCommand = serverCommandNumber;

	Com_DPrintf("serverCommand: %i : %s\n", serverCommandNumber, s);

rescan:
	Cmd_TokenizeString(s);

	cmd = Cmd_Argv(0);
	argc = Cmd_Argc();

	if (!strcmp(cmd, "disconnect")) {
		// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=552
		// allow server to indicate why they were disconnected
		if (argc >= 2) {
			Com_Error(ERR_SERVERDISCONNECT, "Server disconnected - %s", Cmd_Argv(1));
		} else {
			Com_Error(ERR_SERVERDISCONNECT, "Server disconnected");
		}
	}

	if (!strcmp(cmd, "bcs0")) {
		Com_sprintf(bigConfigString, BIG_INFO_STRING, "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2));
		return qfalse;
	}

	if (!strcmp(cmd, "bcs1")) {
		s = Cmd_Argv(2);

		if (strlen(bigConfigString) + strlen(s) >= BIG_INFO_STRING) {
			Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
		}

		strcat(bigConfigString, s);
		return qfalse;
	}

	if (!strcmp(cmd, "bcs2")) {
		s = Cmd_Argv(2);

		if (strlen(bigConfigString) + strlen(s) + 1 >= BIG_INFO_STRING) {
			Com_Error(ERR_DROP, "bcs exceeded BIG_INFO_STRING");
		}

		strcat(bigConfigString, s);
		strcat(bigConfigString, "\"");
		s = bigConfigString;
		goto rescan;
	}

	if (!strcmp(cmd, "cs")) {
		CL_ConfigstringModified();
		// reparse the string, because CL_ConfigstringModified may have done another Cmd_TokenizeString()
		Cmd_TokenizeString(s);
		return qtrue;
	}

	if (!strcmp(cmd, "map_restart")) {
		// clear notify lines and outgoing commands before passing the restart to the cgame
		Con_ClearNotify();
		// reparse the string, because Con_ClearNotify() may have done another Cmd_TokenizeString()
		Cmd_TokenizeString(s);
		Com_Memset(cl.cmds, 0, sizeof(cl.cmds));
		return qtrue;
	}
	// the clientLevelShot command is used during development to generate 128 * 128 screenshots from the intermission
	// point of levels for the menu system to use
	// we pass it along to the cgame to make appropriate adjustments, but we also clear the console and notify lines here
	if (!strcmp(cmd, "clientLevelShot")) {
		// don't do it if we aren't running the server locally, otherwise malicious remote servers could overwrite the existing thumbnails
		if (!com_sv_running->integer) {
			return qfalse;
		}
		// close the console
		Con_Close();
		// take a special screenshot next frame
		Cbuf_AddText("wait; wait; wait; wait; screenshot levelshot\n");
		return qtrue;
	}
	// we may want to put a "connect to other server" command here

	// cgame can now act on the command
	return qtrue;
}
Exemple #15
0
/*
==============
TDM_Disconnected
==============
A player disconnected, do things.
*/
void TDM_Disconnected (edict_t *ent)
{
    qboolean	removeTimeout;

    removeTimeout = false;

    //have to check this right up here since we nuke the teamplayer just below!
    if (tdm_match_status == MM_TIMEOUT && level.tdm_timeout_caller && level.tdm_timeout_caller->client == ent)
        removeTimeout = true;

    //we remove this up here so TDM_LeftTeam doesn't try to resume if we become implicit timeout caller
    TDM_RemoveStatsLink (ent);

    if (ent->client->pers.team)
    {
        if (tdm_match_status >= MM_PLAYING && tdm_match_status != MM_SCOREBOARD)
        {
            //do joincode stuff if a team player disconnects - save all their client info
            ent->client->resp.teamplayerinfo->saved_client = gi.TagMalloc (sizeof(gclient_t), TAG_GAME);
            *ent->client->resp.teamplayerinfo->saved_client = *ent->client;

            ent->client->resp.teamplayerinfo->saved_entity = gi.TagMalloc (sizeof(edict_t), TAG_GAME);
            *ent->client->resp.teamplayerinfo->saved_entity = *ent;

            if (TDM_Is1V1() && g_1v1_timeout->value > 0)
            {
                edict_t		*ghost;

                //may have already been set by a player or previous client disconnect
                if (tdm_match_status != MM_TIMEOUT)
                {
                    edict_t		*opponent;

                    //timeout is called implicitly in 1v1 games or the other player would auto win
                    level.timeout_end_framenum = level.realframenum + SECS_TO_FRAMES(g_1v1_timeout->value);
                    level.last_tdm_match_status = tdm_match_status;
                    tdm_match_status = MM_TIMEOUT;

                    level.tdm_timeout_caller = ent->client->resp.teamplayerinfo;
                    gi.bprintf (PRINT_CHAT, "%s disconnected and has %s to reconnect.\n", level.tdm_timeout_caller->name, TDM_SecsToString (g_1v1_timeout->value));

                    //show the opponent their options
                    opponent = TDM_FindPlayerForTeam (TEAM_A);
                    if (opponent)
                        gi.cprintf (opponent, PRINT_HIGH, "Your opponent has disconnected. You can allow them %s to reconnect, or you can force a forfeit by typing 'win' in the console.\n", TDM_SecsToString (g_1v1_timeout->value));

                    opponent = TDM_FindPlayerForTeam (TEAM_B);
                    if (opponent)
                        gi.cprintf (opponent, PRINT_HIGH, "Your opponent has disconnected. You can allow them %s to reconnect, or you can force a forfeit by typing 'win' in the console.\n", TDM_SecsToString (g_1v1_timeout->value));
                }

                //show a "ghost" player where the player was
                ghost = G_Spawn ();
                VectorCopy (ent->s.origin, ghost->s.origin);
                VectorCopy (ent->s.origin, ghost->old_origin);
                VectorCopy (ent->s.angles, ghost->s.angles);
                ghost->s.effects = EF_SPHERETRANS;
                ghost->s.modelindex = 255;
                ghost->s.modelindex2 = 255;
                ghost->s.skinnum = ent - g_edicts - 1;
                ghost->s.frame = ent->s.frame;
                ghost->count = ent->s.number;
                ghost->classname = "ghost";
                ghost->target_ent = ent;
                ghost->enttype = ENT_GHOST;
                gi.linkentity (ghost);
            }
        }

        if (removeTimeout)
            TDM_ResumeGame ();

        TDM_LeftTeam (ent, false);
    }

    TDM_TeamsChanged ();

    if (tdm_match_status == MM_WARMUP && teaminfo[TEAM_SPEC].players == 0 && teaminfo[TEAM_A].players == 0 && teaminfo[TEAM_B].players == 0)
    {
        if (vote.active)
            TDM_RemoveVote ();

        //reset the map if it's been running for over 7 days to workaround time precision bugs in the engine, fixes 0000208
        if (time (NULL) - level.spawntime > (86400 * 7))
        {
            char	command[256];
            Com_sprintf (command, sizeof(command), "gamemap \"%s\"\n", level.mapname);
            gi.AddCommandString (command);
        }
    }
    else
        TDM_CheckVote ();

    //zero for connecting clients on server browsers
    ent->client->ps.stats[STAT_FRAGS] = 0;
}
Exemple #16
0
void DeathmatchScoreboardMessage (edict_t *ent, edict_t *killer) 
{ 

     char entry[MAX_ENTRY_SIZE]; 
     char string[MAX_STRING_SIZE];
	 char name[20], classname[20];//3.78
     int stringlength; 
     int i, j, k; 
     int sorted[MAX_CLIENTS];
     int sortedscores[MAX_CLIENTS]; 
     int score, total, highscore=0; 
     int y;
	 //float accuracy;
	 int time_left=999, frag_left=999;
     gclient_t *cl; 
     edict_t *cl_ent; 

	 // if we are looking at the scoreboard or inventory, deactivate the scanner
	 if (ent->client->showscores || ent->client->showinventory)
	 {
		if (ent->client->pers.scanner_active)
			ent->client->pers.scanner_active = 2;
	 }
	 else
	 {
		 *string = 0;

		 // Scanner active ?
		if (ent->client->pers.scanner_active & 1)
			ShowScanner(ent,string);

		// normal quake code ...	
		gi.WriteByte (svc_layout);
		gi.WriteString (string);
		return;
	 }
	
     // sort the clients by score 
     total = 0; 
     for (i=0 ; i<game.maxclients ; i++)
	{
		cl_ent = g_edicts + 1 + i;

        //3.0 scoreboard code fix
		if (!cl_ent->client || !cl_ent->inuse || cl_ent->client->resp.spectator)
			continue;

		score = game.clients[i].resp.score;
		for (j=0 ; j<total ; j++)
		{
			if (score > sortedscores[j])
				break;
		}
		for (k=total ; k>j ; k--)
		{
			sorted[k] = sorted[k-1];
			sortedscores[k] = sortedscores[k-1];
		}
		sorted[j] = i;
		sortedscores[j] = score;
		total++;
	}
	// print level name and exit rules
	string[0] = 0;
	stringlength = strlen(string);

     // make a header for the data 
	//K03 Begin
	if (timelimit->value)
		time_left = (timelimit->value*60 - level.time);
	else
		time_left = 60*99;
	if (fraglimit->value)
		frag_left = (fraglimit->value - V_HighestFragScore());

	if (time_left < 0)
		time_left = 0;

	Com_sprintf(entry, sizeof(entry), 
		"xv 0 yv 16 string2 \"Time:%2im %2is Frags:%3i Players:%3i\" "
		"xv 0 yv 24 string2 \"Name       Lv Cl Score Frg Spr Png\" ",
		(int)(time_left/60), (int)(time_left-(int)((time_left/60)*60)),
		frag_left, total_players()); 

	 //K03 End
     j = strlen(entry); 

	 //gi.dprintf("header string length=%d\n", j);

     if (stringlength + j < MAX_ENTRY_SIZE) 
     { 
          strcpy (string + stringlength, entry); 
          stringlength += j; 
     } 

     // add the clients in sorted order 
     if (total > 24) 
          total = 24; 
     /* The screen is only so big :( */ 
	 
     for (i=0 ; i<total ; i++)
	 {
          cl = &game.clients[sorted[i]]; 
          cl_ent = g_edicts + 1 + sorted[i];

		  if (!cl_ent)
			  continue; 

          y = 34 + 8 * i; 
		
		// 3.78 truncate client's name and class string
		strcpy(name, V_TruncateString(cl->pers.netname, 11));
		strcpy(classname, V_TruncateString(GetClassString(cl_ent->myskills.class_num), 3));
		padRight(name, 10);

		Com_sprintf(entry, sizeof(entry),
			"xv 0 yv %i string \"%s %2i %s %5i %3i %3i %3i\" ",
			y, name, cl_ent->myskills.level, classname, cl->resp.score, 
			cl->resp.frags, cl_ent->myskills.streak, cl->ping); 

		j = strlen(entry);

		//gi.dprintf("player string length=%d\n", j);

		if (stringlength + j > MAX_ENTRY_SIZE)
			break; 

		strcpy (string + stringlength, entry); 
		stringlength += j; 
     } 

     gi.WriteByte (svc_layout); 
     gi.WriteString (string); 

} 
Exemple #17
0
/*
================
CL_DrawInventory
================
*/
void CL_DrawInventory(void)
{
    int i, j;
    int num, selected_num, item;
    int index[MAX_ITEMS];
    char string[1024];
    int x, y;
    char binding[1024];
    const char * bind;
    int selected;
    int top;

    enum
    {
        DISPLAY_ITEMS = 17
    };

    selected = cl.frame.playerstate.stats[STAT_SELECTED_ITEM];

    num = 0;
    selected_num = 0;
    for (i = 0; i < MAX_ITEMS; i++)
    {
        if (i == selected)
        {
            selected_num = num;
        }
        if (cl.inventory[i])
        {
            index[num] = i;
            num++;
        }
    }

    // determine scroll point
    top = selected_num - DISPLAY_ITEMS / 2;
    if (num - top < DISPLAY_ITEMS)
    {
        top = num - DISPLAY_ITEMS;
    }
    if (top < 0)
    {
        top = 0;
    }

    x = (viddef.width - 256) / 2;
    y = (viddef.height - 240) / 2;

    // repaint everything next frame
    SCR_DirtyScreen();

    re.DrawPic(x, y + 8, "inventory");

    y += 24;
    x += 24;
    Inv_DrawString(x, y, "hotkey ### item");
    Inv_DrawString(x, y + 8, "------ --- ----");
    y += 16;
    for (i = top; i < num && i < top + DISPLAY_ITEMS; i++)
    {
        item = index[i];
        // search for a binding
        Com_sprintf(binding, sizeof(binding), "use %s", cl.configstrings[CS_ITEMS + item]);
        bind = "";

        for (j = 0; j < 256; j++)
        {
            if (keybindings[j] && !Q_stricmp(keybindings[j], binding))
            {
                bind = Key_KeynumToString(j);
                break;
            }
        }

        Com_sprintf(string, sizeof(string), "%6s %3i %s", bind, cl.inventory[item],
                    cl.configstrings[CS_ITEMS + item]);

        if (item != selected)
        {
            SetStringHighBit(string);
        }
        else // draw a blinky cursor by the selected item
        {
            if ((int)(cls.realtime * 10) & 1)
                re.DrawChar(x - 8, y, 15);
        }

        Inv_DrawString(x, y, string);
        y += 8;
    }
}
Exemple #18
0
unsigned int __stdcall png_write_thread (byte *buffer)
{
	char		picname[MAX_OSPATH]; 
	char		checkname[MAX_OSPATH];
	int			i;
	FILE		*f;
	png_structp png_ptr;
	png_infop info_ptr;
	unsigned	k;
	png_bytepp	row_pointers;

	// create the scrnshots directory if it doesn't exist
	Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/", ri.FS_Gamedir());
	FS_CreatePath (checkname);

	for (i = 0; i < 999; i++) {
		sprintf (picname, "%s/scrnshot/quake%.3d.png", ri.FS_Gamedir(), i);
		f = fopen (picname, "rb");
		if (!f)
			break;
		fclose (f);
	}

	f = fopen (picname, "wb");
	if (!f)
	{
		ri.Con_Printf (PRINT_ALL, "Couldn't open %s for writing.\n", picname);
#ifdef USE_THREADS
		ExitThread (1);
#else
		return 1;
#endif
	}

    png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);

	if (!png_ptr) {
		ri.Con_Printf (PRINT_ALL, "libpng error\n", picname);
#ifdef USE_THREADS
		ExitThread (1);
#else
		return 1;
#endif
	}

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
       png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
       ri.Con_Printf (PRINT_ALL, "libpng error\n", picname);
#ifdef USE_THREADS
		ExitThread (1);
#else
		return 1;
#endif
    }

	png_init_io(png_ptr, f);

	png_set_IHDR(png_ptr, info_ptr, vid.width, vid.height, 8, PNG_COLOR_TYPE_RGB,
				PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

	png_set_compression_level(png_ptr, Z_DEFAULT_COMPRESSION);
	png_set_compression_mem_level(png_ptr, 9);
	png_set_compression_buffer_size(png_ptr, vid.width * vid.height * 3);

	png_write_info(png_ptr, info_ptr);

	row_pointers = malloc(vid.height * sizeof(png_bytep));
	if (!row_pointers)
		ri.Sys_Error (ERR_FATAL, "png_write_thread: out of memory");

	for (k = 0; k < vid.height; k++)
		row_pointers[k] = buffer + (vid.height-1-k)*3*vid.width;

	png_write_image(png_ptr, row_pointers);
	png_write_end(png_ptr, info_ptr);

	png_destroy_write_struct(&png_ptr, &info_ptr);

	fclose (f);

	free (buffer);
	free (row_pointers);

	ri.Con_Printf (PRINT_ALL, "Finished, wrote %s\n", picname);
#ifdef USE_THREADS
	ExitThread (0);
#endif

	return 0;
}
/*
================
SV_SpawnServer

Change the server to a new map, taking all connected
clients along with it.

================
*/
void SV_SpawnServer (char *server, char *spawnpoint, server_state_t serverstate, qboolean attractloop, qboolean loadgame)
{
	int			i;
	unsigned	checksum;

	if (attractloop)
		Cvar_Set ("paused", "0");

	Com_Printf ("------- Server Initialization -------\n");

	Com_DPrintf ("SpawnServer: %s\n",server);
	if (sv.demofile)
		fclose (sv.demofile);

	svs.spawncount++;		// any partially connected client will be
							// restarted
	sv.state = ss_dead;
	Com_SetServerState (sv.state);

	// wipe the entire per-level structure
	memset (&sv, 0, sizeof(sv));
	svs.realtime = 0;
	sv.loadgame = loadgame;
	sv.attractloop = attractloop;

	// save name for levels that don't set message
	strcpy (sv.configstrings[CS_NAME], server);
	if (Cvar_VariableValue ("deathmatch"))
	{
		sprintf(sv.configstrings[CS_AIRACCEL], "%g", sv_airaccelerate->value);
		pm_airaccelerate = sv_airaccelerate->value;
	}
	else
	{
		strcpy(sv.configstrings[CS_AIRACCEL], "0");
		pm_airaccelerate = 0;
	}

	SZ_Init (&sv.multicast, sv.multicast_buf, sizeof(sv.multicast_buf));

	strcpy (sv.name, server);

	// leave slots at start for clients only
	for (i=0 ; i<maxclients->value ; i++)
	{
		// needs to reconnect
		if (svs.clients[i].state > cs_connected)
			svs.clients[i].state = cs_connected;
		svs.clients[i].lastframe = -1;
	}

	sv.time = 1000;
	
	strcpy (sv.name, server);
	strcpy (sv.configstrings[CS_NAME], server);

	if (serverstate != ss_game)
	{
		sv.models[1] = CM_LoadMap ("", false, &checksum);	// no real map
	}
	else
	{
		Com_sprintf (sv.configstrings[CS_MODELS+1],sizeof(sv.configstrings[CS_MODELS+1]),
			"maps/%s.bsp", server);
		sv.models[1] = CM_LoadMap (sv.configstrings[CS_MODELS+1], false, &checksum);
	}
	Com_sprintf (sv.configstrings[CS_MAPCHECKSUM],sizeof(sv.configstrings[CS_MAPCHECKSUM]),
		"%i", checksum);

	//
	// clear physics interaction links
	//
	SV_ClearWorld ();
	
	for (i=1 ; i< CM_NumInlineModels() ; i++)
	{
		Com_sprintf (sv.configstrings[CS_MODELS+1+i], sizeof(sv.configstrings[CS_MODELS+1+i]),
			"*%i", i);
		sv.models[i+1] = CM_InlineModel (sv.configstrings[CS_MODELS+1+i]);
	}

	//
	// spawn the rest of the entities on the map
	//	

	// precache and static commands can be issued during
	// map initialization
	sv.state = ss_loading;
	Com_SetServerState (sv.state);

	// load and spawn all other entities
	ge->SpawnEntities ( sv.name, CM_EntityString(), spawnpoint );

	// run two frames to allow everything to settle
	ge->RunFrame ();
	ge->RunFrame ();

	// all precaches are complete
	sv.state = serverstate;
	Com_SetServerState (sv.state);
	
	// create a baseline for more efficient communications
	SV_CreateBaseline ();

	// check for a savegame
	SV_CheckForSavegame ();

	// set serverinfo variable
	Cvar_FullSet ("mapname", sv.name, CVAR_SERVERINFO | CVAR_NOSET);

	Com_Printf ("-------------------------------------\n");
}
Exemple #20
0
void GL_ScreenShot_JPG (byte *buffer)
{
	struct jpeg_compress_struct cinfo;
	struct jpeg_error_mgr jerr;
	JSAMPROW s[1];
	FILE *f;
	char picname[80], checkname[MAX_OSPATH];
	int i, offset, w3;

	// create the scrnshots directory if it doesn't exist
	Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/", ri.FS_Gamedir());
	FS_CreatePath (checkname);

	for (i = 0; i < 999; i++) {
		sprintf (picname, "%s/scrnshot/quake%.3d.jpg", ri.FS_Gamedir(), i);
		f = fopen (picname, "rb");
		if (!f)
			break;
		fclose (f);
	}

	f = fopen (picname, "wb");
	if (!f)
	{
		ri.Con_Printf (PRINT_ALL, "Couldn't open %s for writing.\n", picname);
		return;
	}

	// Initialise the JPEG compression object
	cinfo.err = jpeg_std_error(&jerr);
	jpeg_create_compress(&cinfo);
	jpeg_stdio_dest(&cinfo, f);

	// Setup JPEG Parameters
	cinfo.image_width = vid.width;
	cinfo.image_height = vid.height;
	cinfo.in_color_space = JCS_RGB;
	cinfo.input_components = 3;

	jpeg_set_defaults(&cinfo);

	// Niceass: 85 is the quality. 0-100
	jpeg_set_quality(&cinfo, Q_ftol(gl_jpg_quality->value), TRUE);

	// Start Compression
	jpeg_start_compress(&cinfo, true);

	// Feed scanline data
	w3 = cinfo.image_width * 3;
	offset = w3 * cinfo.image_height - w3;

	while (cinfo.next_scanline < cinfo.image_height)
	{
		s[0] = &buffer[offset - cinfo.next_scanline * w3];
		jpeg_write_scanlines(&cinfo, s, 1);
	}

	// Finish Compression
	jpeg_finish_compress(&cinfo);

	jpeg_destroy_compress(&cinfo);

	fclose(f);
	free(buffer);

	ri.Con_Printf (PRINT_ALL, "Wrote %s\n", picname);
}
Exemple #21
0
void UI_SaveForceTemplate()
{
	char *selectedName = UI_Cvar_VariableString("ui_SaveFCF");
	char fcfString[512];
	char forceStringValue[4];
	fileHandle_t f;
	int strPlace = 0;
	int forcePlace = 0;
	int i = 0;
	qboolean foundFeederItem = qfalse;

	if (!selectedName || !selectedName[0])
	{
		Com_Printf("You did not provide a name for the template.\n");
		return;
	}

	if (uiForceSide == FORCE_LIGHTSIDE)
	{ //write it into the light side folder
		trap_FS_FOpenFile(va("forcecfg/light/%s.fcf", selectedName), &f, FS_WRITE);
	}
	else
	{ //if it isn't light it must be dark
		trap_FS_FOpenFile(va("forcecfg/dark/%s.fcf", selectedName), &f, FS_WRITE);
	}

	if (!f)
	{
		Com_Printf("There was an error writing the template file (read-only?).\n");
		return;
	}

	Com_sprintf(fcfString, sizeof(fcfString), "%i-%i-", uiForceRank, uiForceSide);
	strPlace = strlen(fcfString);

	while (forcePlace < NUM_FORCE_POWERS)
	{
		Com_sprintf(forceStringValue, sizeof(forceStringValue), "%i", uiForcePowersRank[forcePlace]);
		//Just use the force digit even if multiple digits. Shouldn't be longer than 1.
		fcfString[strPlace] = forceStringValue[0];
		strPlace++;
		forcePlace++;
	}
	fcfString[strPlace] = '\n';
	fcfString[strPlace+1] = 0;

	trap_FS_Write(fcfString, strlen(fcfString), f);
	trap_FS_FCloseFile(f);

	Com_Printf("Template saved as \"%s\".\n", selectedName);

	//Now, update the FCF list
	UI_LoadForceConfig_List();

	//Then, scroll through and select the template for the file we just saved
	while (i < uiInfo.forceConfigCount)
	{
		if (!Q_stricmp(uiInfo.forceConfigNames[i], selectedName))
		{
			if ((uiForceSide == FORCE_LIGHTSIDE && uiInfo.forceConfigSide[i]) ||
				(uiForceSide == FORCE_DARKSIDE && !uiInfo.forceConfigSide[i]))
			{
				Menu_SetFeederSelection(NULL, FEEDER_FORCECFG, UI_TranslateFCFIndex(i), NULL);
				foundFeederItem = qtrue;
			}
		}

		i++;
	}

	//Else, go back to 0
	if (!foundFeederItem)
	{
		Menu_SetFeederSelection(NULL, FEEDER_FORCECFG, 0, NULL);
	}
}
Exemple #22
0
/*
==================
Cmd_CallTeamVote_f
==================
*/
void Cmd_CallTeamVote_f( gentity_t *ent ) {
	int		i, team, cs_offset;
	char	arg1[MAX_STRING_TOKENS];
	char	arg2[MAX_STRING_TOKENS];

	team = ent->client->sess.sessionTeam;
	if ( team == TEAM_RED )
		cs_offset = 0;
	else if ( team == TEAM_BLUE )
		cs_offset = 1;
	else
		return;

	if ( !g_allowVote.integer ) {
		trap_SendServerCommand( ent-g_entities, "print \"Voting not allowed here.\n\"" );
		return;
	}

	if ( level.teamVoteTime[cs_offset] ) {
		trap_SendServerCommand( ent-g_entities, "print \"A team vote is already in progress.\n\"" );
		return;
	}
	if ( ent->client->pers.teamVoteCount >= MAX_VOTE_COUNT ) {
		trap_SendServerCommand( ent-g_entities, "print \"You have called the maximum number of team votes.\n\"" );
		return;
	}
	if ( ent->client->sess.sessionTeam == TEAM_SPECTATOR ) {
		trap_SendServerCommand( ent-g_entities, "print \"Not allowed to call a vote as spectator.\n\"" );
		return;
	}

	// make sure it is a valid command to vote on
	trap_Argv( 1, arg1, sizeof( arg1 ) );
	arg2[0] = '\0';
	for ( i = 2; i < trap_Argc(); i++ ) {
		if (i > 2)
			strcat(arg2, " ");
		trap_Argv( i, &arg2[strlen(arg2)], sizeof( arg2 ) - strlen(arg2) );
	}

	if( strchr( arg1, ';' ) || strchr( arg2, ';' ) ) {
		trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
		return;
	}

	if ( !Q_stricmp( arg1, "leader" ) ) {
		char netname[MAX_NETNAME], leader[MAX_NETNAME];

		if ( !arg2[0] ) {
			i = ent->client->ps.clientNum;
		}
		else {
			// numeric values are just slot numbers
			for (i = 0; i < 3; i++) {
				if ( !arg2[i] || arg2[i] < '0' || arg2[i] > '9' )
					break;
			}
			if ( i >= 3 || !arg2[i]) {
				i = atoi( arg2 );
				if ( i < 0 || i >= level.maxclients ) {
					trap_SendServerCommand( ent-g_entities, va("print \"Bad client slot: %i\n\"", i) );
					return;
				}

				if ( !g_entities[i].inuse ) {
					trap_SendServerCommand( ent-g_entities, va("print \"Client %i is not active\n\"", i) );
					return;
				}
			}
			else {
				Q_strncpyz(leader, arg2, sizeof(leader));
				Q_CleanStr(leader);
				for ( i = 0 ; i < level.maxclients ; i++ ) {
					if ( level.clients[i].pers.connected == CON_DISCONNECTED )
						continue;
					if (level.clients[i].sess.sessionTeam != team)
						continue;
					Q_strncpyz(netname, level.clients[i].pers.netname, sizeof(netname));
					Q_CleanStr(netname);
					if ( !Q_stricmp(netname, leader) ) {
						break;
					}
				}
				if ( i >= level.maxclients ) {
					trap_SendServerCommand( ent-g_entities, va("print \"%s is not a valid player on your team.\n\"", arg2) );
					return;
				}
			}
		}
		Com_sprintf(arg2, sizeof(arg2), "%d", i);
	} else {
		trap_SendServerCommand( ent-g_entities, "print \"Invalid vote string.\n\"" );
		trap_SendServerCommand( ent-g_entities, "print \"Team vote commands are: leader <player>.\n\"" );
		return;
	}

	Com_sprintf( level.teamVoteString[cs_offset], sizeof( level.teamVoteString[cs_offset] ), "%s %s", arg1, arg2 );

	for ( i = 0 ; i < level.maxclients ; i++ ) {
		if ( level.clients[i].pers.connected == CON_DISCONNECTED )
			continue;
		if (level.clients[i].sess.sessionTeam == team)
			trap_SendServerCommand( i, va("print \"%s called a team vote.\n\"", ent->client->pers.netname ) );
	}

	// start the voting, the caller autoamtically votes yes
	level.teamVoteTime[cs_offset] = level.time;
	level.teamVoteYes[cs_offset] = 1;
	level.teamVoteNo[cs_offset] = 0;

	for ( i = 0 ; i < level.maxclients ; i++ ) {
		if (level.clients[i].sess.sessionTeam == team)
			level.clients[i].ps.eFlags &= ~EF_TEAMVOTED;
	}
	ent->client->ps.eFlags |= EF_TEAMVOTED;

	trap_SetConfigstring( CS_TEAMVOTE_TIME + cs_offset, va("%i", level.teamVoteTime[cs_offset] ) );
	trap_SetConfigstring( CS_TEAMVOTE_STRING + cs_offset, level.teamVoteString[cs_offset] );
	trap_SetConfigstring( CS_TEAMVOTE_YES + cs_offset, va("%i", level.teamVoteYes[cs_offset] ) );
	trap_SetConfigstring( CS_TEAMVOTE_NO + cs_offset, va("%i", level.teamVoteNo[cs_offset] ) );
}
Exemple #23
0
/*
================
CL_ParseSnapshot

If the snapshot is parsed properly, it will be copied to
cl.snap and saved in cl.snapshots[].  If the snapshot is invalid
for any reason, no changes to the state will be made at all.
================
*/
void CL_ParseSnapshot(msg_t* msg) {
    int len;
    clSnapshot_t* old;
    clSnapshot_t newSnap;
    int deltaNum;
    int oldMessageNum;
    int i, packetNum;

    // get the reliable sequence acknowledge number
    // NOTE: now sent with all server to client messages
    // clc.reliableAcknowledge = MSG_ReadLong( msg );

    // read in the new snapshot to a temporary buffer
    // we will only copy to cl.snap if it is valid
    Com_Memset(&newSnap, 0, sizeof(newSnap));

    // we will have read any new server commands in this
    // message before we got to svc_snapshot
    newSnap.serverCommandNum = clc.serverCommandSequence;

    newSnap.serverTime = MSG_ReadLong(msg);

    // if we were just unpaused, we can only *now* really let the
    // change come into effect or the client hangs.
    cl_paused->modified = 0;

    newSnap.messageNum = clc.serverMessageSequence;

    deltaNum = MSG_ReadByte(msg);

    if (!deltaNum) {
        newSnap.deltaNum = -1;
    } else {
        newSnap.deltaNum = newSnap.messageNum - deltaNum;
    }

    newSnap.snapFlags = MSG_ReadByte(msg);

    // If the frame is delta compressed from data that we
    // no longer have available, we must suck up the rest of
    // the frame, but not use it, then ask for a non-compressed
    // message
    if (newSnap.deltaNum <= 0) {
        newSnap.valid = true; // uncompressed frame
        old = nullptr;

        if (clc.demorecording) {
            clc.demowaiting = false; // we can start recording now
                                     //          if(cl_autorecord->integer) {
                                     //              Cvar_Set( "g_synchronousClients", "0" );
                                     //          }
        } else {
            if (cl_autorecord
                        ->integer /*&& Cvar_VariableValue( "g_synchronousClients") */) {
                char name[256];
                char mapname[MAX_QPATH];
                char* period;
                qtime_t time;

                Com_RealTime(&time);

                Q_strncpyz(mapname, cl.mapname, MAX_QPATH);

                for (period = mapname; *period; period++) {
                    if (*period == '.') {
                        *period = '\0';
                        break;
                    }
                }

                for (period = mapname; *period; period++) {
                    if (*period == '/') {
                        break;
                    }
                }

                if (*period) {
                    period++;
                }

                Com_sprintf(name, sizeof(name), "demos/%s_%04i-%02i-%02i_%02i%02i%02i.dm_%d", period, 1900 + time.tm_year, time.tm_mon + 1, time.tm_mday, time.tm_hour, time.tm_min, time.tm_sec, PROTOCOL_VERSION);

                CL_Record(name);
            }
        }
    } else {
        old = &cl.snapshots[newSnap.deltaNum & PACKET_MASK];

        if (!old->valid) {
            // should never happen
            Com_Printf("Delta from invalid frame (not supposed to happen!).\n");
        } else if (old->messageNum != newSnap.deltaNum) {
            // The frame that the server did the delta from
            // is too old, so we can't reconstruct it properly.
            Com_DPrintf("Delta frame too old.\n");
        } else if (cl.parseEntitiesNum - old->parseEntitiesNum >
                   MAX_PARSE_ENTITIES - 128) {
            Com_DPrintf("Delta parseEntitiesNum too old.\n");
        } else {
            newSnap.valid = true; // valid delta parse
        }
    }

    // read areamask
    len = MSG_ReadByte(msg);

    if (len > sizeof(newSnap.areamask)) {
        Com_Error(ERR_DROP, "CL_ParseSnapshot: Invalid size %d for areamask.", len);
    }

    MSG_ReadData(msg, &newSnap.areamask, len);

    // read playerinfo
    SHOWNET(msg, "playerstate");

    if (old) {
        MSG_ReadDeltaPlayerstate(msg, &old->ps, &newSnap.ps);
    } else {
        MSG_ReadDeltaPlayerstate(msg, nullptr, &newSnap.ps);
    }

    // read packet entities
    SHOWNET(msg, "packet entities");
    CL_ParsePacketEntities(msg, old, &newSnap);

    // if not valid, dump the entire thing now that it has
    // been properly read
    if (!newSnap.valid) {
        return;
    }

    // clear the valid flags of any snapshots between the last
    // received and this one, so if there was a dropped packet
    // it won't look like something valid to delta from next
    // time we wrap around in the buffer
    oldMessageNum = cl.snap.messageNum + 1;

    if (newSnap.messageNum - oldMessageNum >= PACKET_BACKUP) {
        oldMessageNum = newSnap.messageNum - (PACKET_BACKUP - 1);
    }

    for (; oldMessageNum < newSnap.messageNum; oldMessageNum++) {
        cl.snapshots[oldMessageNum & PACKET_MASK].valid = false;
    }

    // copy to the current good spot
    cl.snap = newSnap;
    cl.snap.ping = 999;

    // calculate ping time
    for (i = 0; i < PACKET_BACKUP; i++) {
        packetNum = (clc.netchan.outgoingSequence - 1 - i) & PACKET_MASK;

        if (cl.snap.ps.commandTime >= cl.outPackets[packetNum].p_serverTime) {
            cl.snap.ping = cls.realtime - cl.outPackets[packetNum].p_realtime;
            break;
        }
    }

    // save the frame off in the backup array for later delta comparisons
    cl.snapshots[cl.snap.messageNum & PACKET_MASK] = cl.snap;

    if (cl_shownet->integer == 3) {
        Com_Printf("   snapshot:%i  delta:%i  ping:%i\n", cl.snap.messageNum, cl.snap.deltaNum, cl.snap.ping);
    }

    cl.newSnapshots = true;
}
Exemple #24
0
void
func_clock_think (edict_t * self)
{
  if (!self->enemy)
    {
      self->enemy = G_Find (NULL, FOFS (targetname), self->target);
      if (!self->enemy)
	return;
    }

  if (self->spawnflags & 1)
    {
      func_clock_format_countdown (self);
      self->health++;
    }
  else if (self->spawnflags & 2)
    {
      func_clock_format_countdown (self);
      self->health--;
    }
  else
    {
      struct tm *ltime;
      time_t gmtime;

      time (&gmtime);
      ltime = localtime (&gmtime);
      Com_sprintf (self->message, CLOCK_MESSAGE_SIZE, "%2i:%2i:%2i",
		   ltime->tm_hour, ltime->tm_min, ltime->tm_sec);
      if (self->message[3] == ' ')
	self->message[3] = '0';
      if (self->message[6] == ' ')
	self->message[6] = '0';
    }

  self->enemy->message = self->message;
  self->enemy->use (self->enemy, self, self);

  if (((self->spawnflags & 1) && (self->health > self->wait)) ||
      ((self->spawnflags & 2) && (self->health < self->wait)))
    {
      if (self->pathtarget)
	{
	  char *savetarget;
	  char *savemessage;

	  savetarget = self->target;
	  savemessage = self->message;
	  self->target = self->pathtarget;
	  self->message = NULL;
	  G_UseTargets (self, self->activator);
	  self->target = savetarget;
	  self->message = savemessage;
	}

      if (!(self->spawnflags & 8))
	return;

      func_clock_reset (self);

      if (self->spawnflags & 4)
	return;
    }

  self->nextthink = level.time + 1;
}
Exemple #25
0
void InitSiegeMode( void ) {
	vmCvar_t		mapname;
	char			levelname[512];
	char			teamIcon[128];
	char			goalreq[64];
	char			teams[2048];
	char			objective[MAX_SIEGE_INFO_SIZE];
	char			objecStr[8192];
	int				len = 0;
	int				i = 0;
	//	int				j = 0;
	int				objectiveNumTeam1 = 0;
	int				objectiveNumTeam2 = 0;
	fileHandle_t	f;

	if ( level.gametype != GT_SIEGE ) {
		goto failure;
	}

	//reset
	SiegeSetCompleteData( 0 );

	//get pers data in case it existed from last level
	if ( g_siegeTeamSwitch.integer ) {
		trap->SiegePersGet( &g_siegePersistant );
		if ( g_siegePersistant.beatingTime ) {
			trap->SetConfigstring( CS_SIEGE_TIMEOVERRIDE, va( "%i", g_siegePersistant.lastTime ) );
		}
		else {
			trap->SetConfigstring( CS_SIEGE_TIMEOVERRIDE, "0" );
		}
	}
	else { //hmm, ok, nothing.
		trap->SetConfigstring( CS_SIEGE_TIMEOVERRIDE, "0" );
	}

	imperial_goals_completed = 0;
	rebel_goals_completed = 0;

	trap->Cvar_Register( &mapname, "mapname", "", CVAR_SERVERINFO | CVAR_ROM );

	Com_sprintf( levelname, sizeof(levelname), "maps/%s.siege\0", mapname.string );

	if ( !levelname[0] ) {
		goto failure;
	}

	len = trap->FS_Open( levelname, &f, FS_READ );

	if ( !f || len >= MAX_SIEGE_INFO_SIZE ) {
		goto failure;
	}

	trap->FS_Read( siege_info, len, f );

	trap->FS_Close( f );

	siege_valid = 1;

	//See if players should be specs or ingame preround
	if ( BG_SiegeGetPairedValue( siege_info, "preround_state", teams ) ) {
		if ( teams[0] ) {
			g_preroundState = atoi( teams );
		}
	}

	if ( BG_SiegeGetValueGroup( siege_info, "Teams", teams ) ) {
		if ( g_siegeTeam1.string[0] && Q_stricmp( g_siegeTeam1.string, "none" ) ) { //check for override
			Q_strncpyz( team1, g_siegeTeam1.string, sizeof(team1) );
		}
		else { //otherwise use level default
			BG_SiegeGetPairedValue( teams, "team1", team1 );
		}

		if ( g_siegeTeam2.string[0] && Q_stricmp( g_siegeTeam2.string, "none" ) ) { //check for override
			Q_strncpyz( team2, g_siegeTeam2.string, sizeof(team2) );
		}
		else { //otherwise use level default
			BG_SiegeGetPairedValue( teams, "team2", team2 );
		}
	}
	else {
		trap->Error( ERR_DROP, "Siege teams not defined" );
	}

	if ( BG_SiegeGetValueGroup( siege_info, team2, gParseObjectives ) ) {
		if ( BG_SiegeGetPairedValue( gParseObjectives, "TeamIcon", teamIcon ) ) {
			trap->Cvar_Set( "team2_icon", teamIcon );
		}

		if ( BG_SiegeGetPairedValue( gParseObjectives, "RequiredObjectives", goalreq ) ) {
			rebel_goals_required = atoi( goalreq );
		}
		if ( BG_SiegeGetPairedValue( gParseObjectives, "Timed", goalreq ) ) {
			rebel_time_limit = atoi( goalreq ) * 1000;
			if ( g_siegeTeamSwitch.integer &&
				g_siegePersistant.beatingTime ) {
				gRebelCountdown = level.time + g_siegePersistant.lastTime;
			}
			else {
				gRebelCountdown = level.time + rebel_time_limit;
			}
		}
		if ( BG_SiegeGetPairedValue( gParseObjectives, "attackers", goalreq ) ) {
			rebel_attackers = atoi( goalreq );
		}
	}

	if ( BG_SiegeGetValueGroup( siege_info, team1, gParseObjectives ) ) {

		if ( BG_SiegeGetPairedValue( gParseObjectives, "TeamIcon", teamIcon ) ) {
			trap->Cvar_Set( "team1_icon", teamIcon );
		}

		if ( BG_SiegeGetPairedValue( gParseObjectives, "RequiredObjectives", goalreq ) ) {
			imperial_goals_required = atoi( goalreq );
		}
		if ( BG_SiegeGetPairedValue( gParseObjectives, "Timed", goalreq ) ) {
			if ( rebel_time_limit ) {
				Com_Printf( "Tried to set imperial time limit, but there's already a rebel time limit!\nOnly one team can have a time limit.\n" );
			}
			else {
				imperial_time_limit = atoi( goalreq ) * 1000;
				if ( g_siegeTeamSwitch.integer &&
					g_siegePersistant.beatingTime ) {
					gImperialCountdown = level.time + g_siegePersistant.lastTime;
				}
				else {
					gImperialCountdown = level.time + imperial_time_limit;
				}
			}
		}
		if ( BG_SiegeGetPairedValue( gParseObjectives, "attackers", goalreq ) ) {
			imperial_attackers = atoi( goalreq );
		}
	}

	//Load the player class types
	BG_SiegeLoadClasses( NULL );

	if ( !bgNumSiegeClasses ) { //We didn't find any?!
		trap->Error( ERR_DROP, "Couldn't find any player classes for Siege" );
	}

	/*
	//We could probably just see what teams are used on this level,
	//then see what classes are used by those teams, and then precache
	//all weapons for said classes. However, I'm just going to do them
	//all for now.
	while (i < bgNumSiegeClasses)
	{
	cl = &bgSiegeClasses[i];
	j = 0;

	while (j < WP_NUM_WEAPONS)
	{
	if (cl->weapons & (1 << j))
	{ //we use this weapon so register it.
	RegisterItem(BG_FindItemForWeapon(j));
	}

	j++;
	}

	i++;
	}
	*/
	//Ok, I'm adding inventory item precaching now, so I'm finally going to optimize this
	//to only do weapons/items for the current teams used on the level.

	//Now load the teams since we have class data.
	BG_SiegeLoadTeams();

	if ( !bgNumSiegeTeams ) { //React same as with classes.
		trap->Error( ERR_DROP, "Couldn't find any player teams for Siege" );
	}

	//Get and set the team themes for each team. This will control which classes can be
	//used on each team.
	if ( BG_SiegeGetValueGroup( siege_info, team1, gParseObjectives ) ) {
		if ( BG_SiegeGetPairedValue( gParseObjectives, "UseTeam", goalreq ) ) {
			BG_SiegeSetTeamTheme( SIEGETEAM_TEAM1, goalreq );
		}

		//Now count up the objectives for this team.
		i = 1;
		strcpy( objecStr, va( "Objective%i", i ) );
		while ( BG_SiegeGetValueGroup( gParseObjectives, objecStr, objective ) ) {
			objectiveNumTeam1++;
			i++;
			strcpy( objecStr, va( "Objective%i", i ) );
		}
	}
	if ( BG_SiegeGetValueGroup( siege_info, team2, gParseObjectives ) ) {
		if ( BG_SiegeGetPairedValue( gParseObjectives, "UseTeam", goalreq ) ) {
			BG_SiegeSetTeamTheme( SIEGETEAM_TEAM2, goalreq );
		}

		//Now count up the objectives for this team.
		i = 1;
		strcpy( objecStr, va( "Objective%i", i ) );
		while ( BG_SiegeGetValueGroup( gParseObjectives, objecStr, objective ) ) {
			objectiveNumTeam2++;
			i++;
			strcpy( objecStr, va( "Objective%i", i ) );
		}
	}

	//Set the configstring to show status of all current objectives
	strcpy( gObjectiveCfgStr, "t1" );
	while ( objectiveNumTeam1 > 0 ) { //mark them all as not completed since we just initialized
		Q_strcat( gObjectiveCfgStr, 1024, "-0" );
		objectiveNumTeam1--;
	}
	//Finished doing team 1's objectives, now do team 2's
	Q_strcat( gObjectiveCfgStr, 1024, "|t2" );
	while ( objectiveNumTeam2 > 0 ) {
		Q_strcat( gObjectiveCfgStr, 1024, "-0" );
		objectiveNumTeam2--;
	}

	//And finally set the actual config string
	trap->SetConfigstring( CS_SIEGE_OBJECTIVES, gObjectiveCfgStr );

	//precache saber data for classes that use sabers on both teams
	BG_PrecacheSabersForSiegeTeam( SIEGETEAM_TEAM1 );
	BG_PrecacheSabersForSiegeTeam( SIEGETEAM_TEAM2 );

	G_SiegeRegisterWeaponsAndHoldables( SIEGETEAM_TEAM1 );
	G_SiegeRegisterWeaponsAndHoldables( SIEGETEAM_TEAM2 );

	return;

failure:
	siege_valid = 0;
}
Exemple #26
0
/*
==================
SCR_PlayCinematic

==================
*/
void SCR_PlayCinematic (char *arg)
{
	int		width, height;
	byte	*palette;
	char	name[MAX_OSPATH], *dot;
	int		old_khz;

	// make sure CD isn't playing music
	CDAudio_Stop();

	cl.cinematicframe = 0;
	dot = strstr (arg, ".");
	if (dot && !strcmp (dot, ".pcx"))
	{	// static pcx image
		Com_sprintf (name, sizeof(name), "pics/%s", arg);
		SCR_LoadPCX (name, &cin.pic, &palette, &cin.width, &cin.height);
		cl.cinematicframe = -1;
		cl.cinematictime = 1;
		SCR_EndLoadingPlaque ();
		cls.state = ca_active;
		if (!cin.pic)
		{
			Com_Printf ("%s not found.\n", name);
			cl.cinematictime = 0;
		}
		else
		{
			memcpy (cl.cinematicpalette, palette, sizeof(cl.cinematicpalette));
			Z_Free (palette);
		}
		return;
	}

	Com_sprintf (name, sizeof(name), "video/%s", arg);
	FS_FOpenFile (name, &cl.cinematic_file);
	if (!cl.cinematic_file)
	{
//		Com_Error (ERR_DROP, "Cinematic %s not found.\n", name);
		SCR_FinishCinematic ();
		cl.cinematictime = 0;	// done
		return;
	}

	SCR_EndLoadingPlaque ();

	cls.state = ca_active;

	FS_Read (&width, 4, cl.cinematic_file);
	FS_Read (&height, 4, cl.cinematic_file);
	cin.width = LittleLong(width);
	cin.height = LittleLong(height);

	FS_Read (&cin.s_rate, 4, cl.cinematic_file);
	cin.s_rate = LittleLong(cin.s_rate);
	FS_Read (&cin.s_width, 4, cl.cinematic_file);
	cin.s_width = LittleLong(cin.s_width);
	FS_Read (&cin.s_channels, 4, cl.cinematic_file);
	cin.s_channels = LittleLong(cin.s_channels);

	Huff1TableInit ();

	// switch up to 22 khz sound if necessary
	old_khz = Cvar_VariableValue ("s_khz");
	if (old_khz != cin.s_rate/1000)
	{
		cin.restart_sound = true;
		Cvar_SetValue ("s_khz", cin.s_rate/1000);
		CL_Snd_Restart_f ();
		Cvar_SetValue ("s_khz", old_khz);
	}

	cl.cinematicframe = 0;
	cin.pic = SCR_ReadNextFrame ();
	cl.cinematictime = Sys_Milliseconds ();
}
Exemple #27
0
/*
==================
UpdateTournamentInfo
==================
*/
void UpdateTournamentInfo(void)
{
	int             i;
	gentity_t      *player;
	int             playerClientNum;
	int             n, accuracy, perfect, msglen;
	int             buflen;
	int             score1, score2;
	qboolean        won;
	char            buf[32];
	char            msg[MAX_STRING_CHARS];

	// find the real player
	player = NULL;
	for(i = 0; i < level.maxclients; i++)
	{
		player = &g_entities[i];
		if(!player->inuse)
		{
			continue;
		}
		if(!(player->r.svFlags & SVF_BOT))
		{
			break;
		}
	}
	// this should never happen!
	if(!player || i == level.maxclients)
	{
		return;
	}
	playerClientNum = i;

	CalculateRanks();

	if(level.clients[playerClientNum].sess.sessionTeam == TEAM_SPECTATOR)
	{
		Com_sprintf(msg, sizeof(msg), "postgame %i %i 0 0 0 0 0 0 0 0 0 0 0 0", level.numNonSpectatorClients, playerClientNum);
	}
	else
	{
		if(player->client->accuracy_shots)
		{
			accuracy = player->client->accuracy_hits * 100 / player->client->accuracy_shots;
		}
		else
		{
			accuracy = 0;
		}

		won = qfalse;
		if(g_gametype.integer >= GT_CTF)
		{
			score1 = level.teamScores[TEAM_RED];
			score2 = level.teamScores[TEAM_BLUE];

			if(level.clients[playerClientNum].sess.sessionTeam == TEAM_RED)
			{
				won = (level.teamScores[TEAM_RED] > level.teamScores[TEAM_BLUE]);
			}
			else
			{
				won = (level.teamScores[TEAM_BLUE] > level.teamScores[TEAM_RED]);
			}
		}
		else
		{
			if(&level.clients[playerClientNum] == &level.clients[level.sortedClients[0]])
			{
				won = qtrue;
				score1 = level.clients[level.sortedClients[0]].ps.persistant[PERS_SCORE];
				score2 = level.clients[level.sortedClients[1]].ps.persistant[PERS_SCORE];
			}
			else
			{
				score2 = level.clients[level.sortedClients[0]].ps.persistant[PERS_SCORE];
				score1 = level.clients[level.sortedClients[1]].ps.persistant[PERS_SCORE];
			}
		}

		if(won && player->client->ps.persistant[PERS_KILLED] == 0)
		{
			perfect = 1;
		}
		else
		{
			perfect = 0;
		}

		Com_sprintf(msg, sizeof(msg), "postgame %i %i %i %i %i %i %i %i %i %i %i %i %i %i",
					level.numNonSpectatorClients,
					playerClientNum,
					accuracy,
					player->client->ps.persistant[PERS_IMPRESSIVE_COUNT],
					player->client->ps.persistant[PERS_EXCELLENT_COUNT],
					player->client->ps.persistant[PERS_GAUNTLET_FRAG_COUNT],
					player->client->ps.persistant[PERS_TELEFRAG_FRAG_COUNT],
					player->client->ps.persistant[PERS_SCORE],
					perfect,
					won,
					score1,
					score2,
					level.time,
					player->client->ps.persistant[PERS_CAPTURES]);
	}

	msglen = strlen(msg);
	for(i = 0; i < level.numNonSpectatorClients; i++)
	{
		n = level.sortedClients[i];
		Com_sprintf(buf, sizeof(buf), " %i %i %i", n, level.clients[n].ps.persistant[PERS_RANK],
					level.clients[n].ps.persistant[PERS_SCORE]);
		buflen = strlen(buf);
		if(msglen + buflen + 1 >= sizeof(msg))
		{
			break;
		}
		strcat(msg, buf);
	}

	trap_SendConsoleCommand(EXEC_APPEND, msg);
}
Exemple #28
0
/*
=================
S_CodecGetSound

Opens/loads a sound, tries codec based on the sound's file extension
then tries all supported codecs.
=================
*/
static void *S_CodecGetSound(const char *filename, snd_info_t *info)
{
	snd_codec_t *codec;
	snd_codec_t *orgCodec = NULL;
	qboolean	orgNameFailed = qfalse;
	char		localName[ MAX_QPATH ];
	const char	*ext;
	char		altName[ MAX_QPATH ];
	void		*rtn = NULL;

	Q_strncpyz(localName, filename, MAX_QPATH);

	ext = COM_GetExtension(localName);

	if( *ext )
	{
		// Look for the correct loader and use it
		for( codec = codecs; codec; codec = codec->next )
		{
			if( !Q_stricmp( ext, codec->ext ) )
			{
				// Load
				if( info )
					rtn = codec->load(localName, info);
				else
					rtn = codec->open(localName);
				break;
			}
		}

		// A loader was found
		if( codec )
		{
			if( !rtn )
			{
				// Loader failed, most likely because the file isn't there;
				// try again without the extension
				orgNameFailed = qtrue;
				orgCodec = codec;
				COM_StripExtension( filename, localName, MAX_QPATH );
			}
			else
			{
				// Something loaded
				return rtn;
			}
		}
	}

	// Try and find a suitable match using all
	// the sound codecs supported
	for( codec = codecs; codec; codec = codec->next )
	{
		if( codec == orgCodec )
			continue;

		Com_sprintf( altName, sizeof (altName), "%s.%s", localName, codec->ext );

		// Load
		if( info )
			rtn = codec->load(altName, info);
		else
			rtn = codec->open(altName);

		if( rtn )
		{
			if( orgNameFailed )
			{
				Com_DPrintf(S_COLOR_YELLOW "WARNING: %s not present, using %s instead\n",
						filename, altName );
			}

			return rtn;
		}
	}

	Com_Printf(S_COLOR_YELLOW "WARNING: Failed to %s sound %s!\n", info ? "load" : "open", filename);

	return NULL;
}
Exemple #29
0
void CL_cURL_BeginDownload( const char *localName, const char *remoteURL )
{
    clc.cURLUsed = qtrue;
    Com_Printf("URL: %s\n", remoteURL);
    Com_DPrintf("***** CL_cURL_BeginDownload *****\n"
                "Localname: %s\n"
                "RemoteURL: %s\n"
                "****************************\n", localName, remoteURL);
    CL_cURL_Cleanup();
    Q_strncpyz(clc.downloadURL, remoteURL, sizeof(clc.downloadURL));
    Q_strncpyz(clc.downloadName, localName, sizeof(clc.downloadName));
    Com_sprintf(clc.downloadTempName, sizeof(clc.downloadTempName),
                "%s.tmp", localName);

    // Set so UI gets access to it
    Cvar_Set("cl_downloadName", localName);
    Cvar_Set("cl_downloadSize", "0");
    Cvar_Set("cl_downloadCount", "0");
    Cvar_SetValue("cl_downloadTime", cls.realtime);

    clc.downloadBlock = 0; // Starting new file
    clc.downloadCount = 0;

    clc.downloadCURL = qcurl_easy_init();
    if(!clc.downloadCURL) {
        Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_easy_init() "
                  "failed\n");
        return;
    }
    clc.download = FS_SV_FOpenFileWrite(clc.downloadTempName);
    if(!clc.download) {
        Com_Error(ERR_DROP, "CL_cURL_BeginDownload: failed to open "
                  "%s for writing\n", clc.downloadTempName);
        return;
    }
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, clc.download);
    if(com_developer->integer)
        qcurl_easy_setopt(clc.downloadCURL, CURLOPT_VERBOSE, 1);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_URL, clc.downloadURL);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_TRANSFERTEXT, 0);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_REFERER, va("ioQ3://%s",
                      NET_AdrToString(clc.serverAddress)));
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_USERAGENT, va("%s %s",
                      Q3_VERSION, qcurl_version()));
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEFUNCTION,
                      CL_cURL_CallbackWrite);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_WRITEDATA, &clc.download);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_NOPROGRESS, 0);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSFUNCTION,
                      CL_cURL_CallbackProgress);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_PROGRESSDATA, NULL);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_FAILONERROR, 1);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_FOLLOWLOCATION, 1);
    qcurl_easy_setopt(clc.downloadCURL, CURLOPT_MAXREDIRS, 5);
    clc.downloadCURLM = qcurl_multi_init();
    if(!clc.downloadCURLM) {
        qcurl_easy_cleanup(clc.downloadCURL);
        clc.downloadCURL = NULL;
        Com_Error(ERR_DROP, "CL_cURL_BeginDownload: qcurl_multi_init() "
                  "failed\n");
        return;
    }
    qcurl_multi_add_handle(clc.downloadCURLM, clc.downloadCURL);

    if(!(clc.sv_allowDownload & DLF_NO_DISCONNECT) &&
            !clc.cURLDisconnected) {

        CL_AddReliableCommand("disconnect", qtrue);
        CL_WritePacket();
        CL_WritePacket();
        CL_WritePacket();
        clc.cURLDisconnected = qtrue;
    }
}
void R_RemapDeluxeImages( world_t *world )
{
	int i;

	if( !tr.deluxemaps[0] )
		return;

	R_InitConverter();

	R_StateSetActiveTmuUntracked( GL_TEXTURE0 );
	R_StateSetActiveClientTmuUntracked( GL_TEXTURE0 );

	glPushAttrib( GL_ALL_ATTRIB_BITS );
	glPushClientAttrib( GL_CLIENT_ALL_ATTRIB_BITS );

	glEnableClientState( GL_VERTEX_ARRAY );
	glEnableClientState( GL_NORMAL_ARRAY );
	glEnableVertexAttribArrayARB( 6 );
	glEnableVertexAttribArrayARB( 7 );

	glClearColor( 0, 0, 0, 0 );
	glDisable( GL_DEPTH_TEST );
	glDisable( GL_STENCIL_TEST );
	glDisable( GL_ALPHA_TEST );
	glDisable( GL_BLEND );
	glDisable( GL_CULL_FACE );
	glDisable( GL_MULTISAMPLE );
	glEnable( GL_POLYGON_SMOOTH );

	glMatrixMode( GL_PROJECTION );
	glLoadIdentity();
	glMatrixMode( GL_MODELVIEW );
	glLoadIdentity();

	glEnable( GL_VERTEX_PROGRAM_ARB );
	glBindProgramARB( GL_VERTEX_PROGRAM_ARB, conv.vp );
	glEnable( GL_FRAGMENT_PROGRAM_ARB );
	glBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, conv.fp );

	glEnable( GL_TEXTURE_2D );

	for( i = 0; i < tr.numLightmaps; i++ )
	{
		int j, y;
		unsigned *buf0, *buf1;

		image_t *img = tr.deluxemaps[i];
		glBindTexture( GL_TEXTURE_2D, img->texnum );

		glClear( GL_COLOR_BUFFER_BIT );

		glViewport( 0, img->uploadHeight, img->uploadWidth, img->uploadHeight );

		glDisable( GL_VERTEX_PROGRAM_ARB );
		glDisable( GL_FRAGMENT_PROGRAM_ARB );

		glBegin( GL_QUADS );
		{
			glTexCoord2f( 0, 0 );
			glVertex2f( -1, -1 );

			glTexCoord2f( 0, 1 );
			glVertex2f( -1, 1 );

			glTexCoord2f( 1, 1 );
			glVertex2f( 1, 1 );

			glTexCoord2f( 1, 0 );
			glVertex2f( 1, -1 );
		}
		glEnd();

		glEnable( GL_VERTEX_PROGRAM_ARB );
		glEnable( GL_FRAGMENT_PROGRAM_ARB );

		glViewport( 0, 0, img->uploadWidth, img->uploadHeight );

		glProgramLocalParameter4fARB( GL_VERTEX_PROGRAM_ARB, 0,
			img->uploadWidth, img->uploadHeight,
			1.0F / img->uploadWidth, 1.0F / img->uploadHeight );

		for( j = 0; j < world->numsurfaces; j++ )
		{
			const msurface_t *srf = world->surfaces + j;
			const shader_t *shader = srf->shader;
			const msurface_ex_t *exsrf = srf->redirect;
			
			if( !shader->stages[0] || !shader->stages[0]->active )
				continue;
			if( shader->stages[0]->deluxeMap != img )
				continue;

			if( !exsrf )
				continue;

			glVertexPointer( 2, GL_FLOAT, sizeof( drawVert_ex_t ),
				&exsrf->verts[0].uvL );
			glNormalPointer( GL_FLOAT, sizeof( drawVert_ex_t ),
				&exsrf->verts[0].norm );
			glVertexAttribPointerARB( 6, 3, GL_FLOAT, GL_FALSE,
				sizeof( drawVert_ex_t ), &exsrf->verts[0].tan );
			glVertexAttribPointerARB( 7, 3, GL_FLOAT, GL_FALSE,
				sizeof( drawVert_ex_t ), &exsrf->verts[0].bin );

			glDrawElements( exsrf->primType, exsrf->numIndices,
				GL_UNSIGNED_SHORT, exsrf->indices );
		}

		glFinish();
		
		buf0 = (unsigned*)ri.Hunk_AllocateTempMemory( img->uploadWidth * img->uploadHeight * 4 );
		buf1 = (unsigned*)ri.Hunk_AllocateTempMemory( img->uploadWidth * img->uploadHeight * 4 );

		//can't just copy to the texture since we
		//need the custom mipmap generator
		glReadPixels( 0, 0, img->uploadWidth, img->uploadHeight,
			GL_RGBA, GL_UNSIGNED_BYTE, buf0 );

#define DELUXEL( buf, x, y ) ((byte*)(buf) + (((y) * img->uploadWidth + (x)) * 4))

		Com_Memcpy( buf1, buf0, img->uploadWidth * img->uploadHeight * 4 );

		for( j = 0; j < 4; j++ )
		{
			for( y = 0; y < img->uploadHeight; y++ )
			{
				int x;

				for( x = 0; x < img->uploadWidth; x++ )
				{
					static int neighbors[8][2] =
					{
						{ 0, 1 },
						{ 1, 1 },
						{ 1, 0 },
						{ 1, -1 },
						{ 0, -1 },
						{ -1, -1 },
						{ -1, 0 },
						{ -1, 1 }
					};

					int i;
					int sum[3], c;

					byte *cIn = DELUXEL( buf0, x, y );
					byte *cOut = DELUXEL( buf1, x, y );

					cOut[3] = cIn[3];

					if( cIn[2] )
					{
						//if it has some Z value
						//then it's already good

						cOut[0] = cIn[0];
						cOut[1] = cIn[1];
						cOut[2] = cIn[2];

						continue;
					}

					c = 0;
					sum[0] = sum[1] = sum[2] = 0;

					for( i = 0; i < lengthof( neighbors ); i++ )
					{
						int nx = x + neighbors[i][0];
						int ny = y + neighbors[i][1];

						if( nx >= 0 && nx < img->uploadWidth &&
							ny >= 0 && ny < img->uploadHeight )
						{
							byte *n = DELUXEL( buf0, nx, ny );

							if( !n[2] )
								continue;

							sum[0] += n[0];
							sum[1] += n[1];
							sum[2] += n[2];

							c++;
						}
					}

					if( c )
					{
						cOut[0] = sum[0] / c;
						cOut[1] = sum[1] / c;
						cOut[2] = sum[2] / c;
					}
				}
			}

			Com_Memcpy( buf0, buf1, img->uploadWidth * img->uploadHeight * 4 );
		}

		for( y = 0; y < img->uploadHeight; y++ )
		{
			int x;

			for( x = 0; x < img->uploadWidth; x++ )
			{
				byte *d = DELUXEL( buf1, x, y );

				if( !d[2] )
				{
					d[0] = 0;
					d[1] = 0;
					d[2] = 0xFF;
				}
			}
		}

		//write it out to file
		{
			int size;
			char path[MAX_QPATH];
			byte *out_buf;
			
			Com_sprintf( path, sizeof( path ), "deluxe/%s/dm_%04d.tga",
				world->baseName, i );

			size = 18 + img->uploadWidth * img->uploadHeight * 3;
			out_buf = (byte*)ri.Hunk_AllocateTempMemory( size );

		   	Com_Memset( out_buf, 0, 18 );
			out_buf[2] = 2;		// uncompressed type
			out_buf[12] = img->uploadWidth & 255;
			out_buf[13] = img->uploadWidth >> 8;
			out_buf[14] = img->uploadHeight & 255;
			out_buf[15] = img->uploadHeight >> 8;
			out_buf[16] = 24;	// pixel size
			out_buf[17] = 0x20; // reverse row order

			for( y = 0; y < img->uploadHeight; y++ )
			{
				int x;
				for( x = 0; x < img->uploadWidth; x++ )
				{
					byte *d = DELUXEL( buf1, x, y );
					out_buf[18 + (y * img->uploadWidth + x) * 3 + 0] = d[2];
					out_buf[18 + (y * img->uploadWidth + x) * 3 + 1] = d[1];
					out_buf[18 + (y * img->uploadWidth + x) * 3 + 2] = d[0];
				}
			}
			
			ri.FS_WriteFile( path, out_buf, size );
			
			ri.Hunk_FreeTempMemory( out_buf );
		}

#undef DELUXEL

		Upload32( buf1, qfalse, img, ILF_VECTOR_SB3 );

#ifdef _DEBUG
		glEnable( GL_TEXTURE_2D );
		glBindTexture( GL_TEXTURE_2D, img->texnum );

		glViewport( img->uploadWidth, 0, img->uploadWidth, img->uploadHeight );

		glDisable( GL_VERTEX_PROGRAM_ARB );
		glDisable( GL_FRAGMENT_PROGRAM_ARB );

		glBegin( GL_QUADS );
		{
			glTexCoord2f( 0, 0 );
			glVertex2f( -1, -1 );

			glTexCoord2f( 0, 1 );
			glVertex2f( -1, 1 );

			glTexCoord2f( 1, 1 );
			glVertex2f( 1, 1 );

			glTexCoord2f( 1, 0 );
			glVertex2f( 1, -1 );
		}
		glEnd();

		glEnable( GL_VERTEX_PROGRAM_ARB );
		glEnable( GL_FRAGMENT_PROGRAM_ARB );

		GLimp_EndFrame();
#endif

		ri.Hunk_FreeTempMemory( buf1 );
		ri.Hunk_FreeTempMemory( buf0 );
	}

	glPopClientAttrib();
	glPopAttrib();

	glDeleteProgramsARB( 1, &conv.vp );
	glDeleteProgramsARB( 1, &conv.fp );
}