Exemplo n.º 1
0
static int JPLua_Export_SendChatText( lua_State *L ) {
	char text[MAX_SAY_TEXT] = { 0 };

	if ( !cg_teamChatsOnly.integer ) {
		Q_strncpyz( text, lua_tostring( L, -1 ), MAX_SAY_TEXT );
		lua_pop( L, 1 );
		CG_LogPrintf( cg.log.console, va( "%s\n", text ) );
		if ( cg_newChatbox.integer )
			CG_ChatboxAddMessage( text, qfalse, "normal" );
		else
			CG_ChatBox_AddString( text );
	}

	return 0;
}
Exemplo n.º 2
0
	//Func: Write( string message )
	//Retn: --
	int Logger_Write( lua_State *L ) {
		logger_t *logger = CheckLogger( L, 1 );

		if ( lua_type( L, 2 ) != LUA_TSTRING ) {
			luaL_argcheck( L, 1, 2, "'string' expected" );
		}

	#if defined(PROJECT_GAME)
		G_LogPrintf( logger->fileHandle, "%s\n", lua_tostring( L, 2 ) );
	#elif defined(PROJECT_CGAME)
		CG_LogPrintf( logger->fileHandle, "%s\n", lua_tostring( L, 2 ) );
	#endif

		return 0;
	}
Exemplo n.º 3
0
// This is called explicitly when the gamestate is first received, and whenever the server updates any serverinfo flagged cvars
void CG_ParseServerinfo( void ) {
	const char *info = NULL, *tinfo = NULL, *mapname;
	int i, fraglimit, timelimit;

	info = CG_ConfigString( CS_SERVERINFO );

	cgs.debugMelee = atoi( Info_ValueForKey( info, "g_debugMelee" ) );
	cgs.stepSlideFix = atoi( Info_ValueForKey( info, "g_stepSlideFix" ) );
	cgs.noSpecMove = atoi( Info_ValueForKey( info, "g_noSpecMove" ) );
	cgs.siegeTeamSwitch = atoi( Info_ValueForKey( info, "g_siegeTeamSwitch" ) );
	cgs.showDuelHealths = atoi( Info_ValueForKey( info, "g_showDuelHealths" ) );
	cgs.needpass = atoi( Info_ValueForKey( info, "needpass" ) );
	cgs.jediVmerc = atoi( Info_ValueForKey( info, "g_jediVmerc" ) );
	cgs.wDisable = atoi( Info_ValueForKey( info, "wdisable" ) );
	cgs.fDisable = atoi( Info_ValueForKey( info, "fdisable" ) );
	cgs.dmflags = atoi( Info_ValueForKey( info, "dmflags" ) );
	cgs.duel_fraglimit = atoi( Info_ValueForKey( info, "duel_fraglimit" ) );
	cgs.capturelimit = atoi( Info_ValueForKey( info, "capturelimit" ) );
	cgs.gametype = (gametype_t)atoi( Info_ValueForKey( info, "g_gametype" ) );
	cgs.japp.jp_cinfo = atoi( Info_ValueForKey( info, "jp_cinfo" ) );
	cgs.japp.overbounce = atoi( Info_ValueForKey( info, "pmove_overbounce" ) );
	fraglimit = atoi( Info_ValueForKey( info, "fraglimit" ) );
	timelimit = atoi( Info_ValueForKey( info, "timelimit" ) );

	trap->Cvar_Set( "g_gametype", va( "%i", cgs.gametype ) );

	trap->Cvar_Set( "bg_fighterAltControl", Info_ValueForKey( info, "bg_fighterAltControl" ) );

	// reset fraglimit warnings
	if ( cgs.fraglimit < fraglimit )
		cg.fraglimitWarnings &= ~(1 | 2 | 4);
	cgs.fraglimit = fraglimit;

	// reset timelimit warnings
	if ( cgs.timelimit != timelimit )
		cg.timelimitWarnings &= ~(1 | 2);
	cgs.timelimit = timelimit;

	cgs.maxclients = Q_clampi( 0, atoi( Info_ValueForKey( info, "sv_maxclients" ) ), MAX_CLIENTS );

	//Raz: Server support flags
	tinfo = Info_ValueForKey( info, "ssf" );
	if ( !Q_stricmpn( Info_ValueForKey( info, "gamename" ), "JA+ Mod", 7 ) )
		cg.japp.SSF = JAPLUS_SERVER_FLAGS;

	if ( tinfo[0] && sscanf( tinfo, "%X", &cg.japp.SSF ) != 1 )
		CG_LogPrintf( cg.log.security, "CG_ParseServerinfo: serverinfo 'ssf' was found, but invalid.\n" );
	Com_Printf( "Server support hints: 0x%X\n", cg.japp.SSF );

	tinfo = Info_ValueForKey( info, "jp_gripSpeedScale" );
	if ( tinfo[0] ) {
		cgs.japp.gripSpeed.scale = atof( tinfo );
		cgs.japp.gripSpeed.set = qtrue;
	}
	else {
		cgs.japp.gripSpeed.set = qfalse;
	}

	mapname = Info_ValueForKey( info, "mapname" );
	Q_strncpyz( cgs.mapnameClean, mapname, sizeof(cgs.mapnameClean) );

	//rww - You must do this one here, Info_ValueForKey always uses the same memory pointer.
	trap->Cvar_Set( "ui_about_mapname", mapname );

	Com_sprintf( cgs.mapname, sizeof(cgs.mapname), "maps/%s.bsp", mapname );

	trap->Cvar_Set( "ui_about_gametype", va( "%i", cgs.gametype ) );
	trap->Cvar_Set( "ui_about_fraglimit", va( "%i", cgs.fraglimit ) );
	trap->Cvar_Set( "ui_about_duellimit", va( "%i", cgs.duel_fraglimit ) );
	trap->Cvar_Set( "ui_about_capturelimit", va( "%i", cgs.capturelimit ) );
	trap->Cvar_Set( "ui_about_timelimit", va( "%i", cgs.timelimit ) );
	trap->Cvar_Set( "ui_about_maxclients", va( "%i", cgs.maxclients ) );
	trap->Cvar_Set( "ui_about_dmflags", va( "%i", cgs.dmflags ) );
	trap->Cvar_Set( "ui_about_hostname", Info_ValueForKey( info, "sv_hostname" ) );
	trap->Cvar_Set( "ui_about_needpass", Info_ValueForKey( info, "g_needpass" ) );
	trap->Cvar_Set( "ui_about_botminplayers", Info_ValueForKey( info, "bot_minplayers" ) );

	//Set the siege teams based on what the server has for overrides.
	trap->Cvar_Set( "cg_siegeTeam1", Info_ValueForKey( info, "g_siegeTeam1" ) );
	trap->Cvar_Set( "cg_siegeTeam2", Info_ValueForKey( info, "g_siegeTeam2" ) );

	tinfo = CG_ConfigString( CS_TERRAINS + 1 );
	if ( !tinfo || !*tinfo )
		cg.mInRMG = qfalse;
	else {
		int weather = 0;

		cg.mInRMG = qtrue;
		trap->Cvar_Set( "RMG", "1" );

		weather = atoi( Info_ValueForKey( info, "RMG_weather" ) );

		trap->Cvar_Set( "RMG_weather", va( "%i", weather ) );

		if ( weather == 1 || weather == 2 )
			cg.mRMGWeather = qtrue;
		else
			cg.mRMGWeather = qfalse;
	}

	Q_strncpyz( cgs.japp.serverName, Info_ValueForKey( info, "sv_hostname" ), sizeof(cgs.japp.serverName) );
	CPM_UpdateSettings( !!(cgs.japp.jp_cinfo & CINFO_CPMPHYSICS) );

	//Fix f****d up vote strings
	Q_strncpyz( cgs.voteString, CG_ConfigString( CS_VOTE_STRING ), sizeof(cgs.voteString) );

	//Raz: Synchronise our expected snaps/sec with the server's framerate
	//		OpenJK servers will try to match us to the sv_fps too (sv_client.cpp -> SV_UserinfoChanged)
	i = atoi( Info_ValueForKey( info, "sv_fps" ) );
	if ( i )
		trap->Cvar_Set( "snaps", va( "%i", i ) );
}
Exemplo n.º 4
0
// The string has been tokenized and can be retrieved with Cmd_Argc() / Cmd_Argv()
static void CG_ServerCommand( void ) {
	const char	*cmd;
	char		text[MAX_SAY_TEXT];
	qboolean	IRCG = qfalse;

	if ( JPLua_Event_ServerCommand() )
		return;

	cmd = CG_Argv( 0 );

	// server claimed the command
	if ( !cmd[0] )
		return;

	if ( !strcmp( cmd, "sxd" ) ) {
		// siege extended data, contains extra info certain classes may want to know about other clients
		CG_ParseSiegeExtendedData();
		return;
	}

	if ( !strcmp( cmd, "sb" ) ) {
		// siege briefing display
		CG_SiegeBriefingDisplay( atoi( CG_Argv( 1 ) ), qfalse );
		return;
	}

	if ( !strcmp( cmd, "scl" ) ) {
		trap->OpenUIMenu( UIMENU_CLASSSEL );
		return;
	}

	if ( !strcmp( cmd, "spc" ) ) {
		if ( !cg.demoPlayback ) {
			trap->Cvar_Set( "ui_myteam", "3" );
			trap->OpenUIMenu( UIMENU_PLAYERCONFIG );
		}
		return;
	}

	if ( !strcmp( cmd, "nfr" ) ) {
		// new force rank
		int doMenu = 0, setTeam = 0, newRank = 0;

		if ( trap->Cmd_Argc() < 3 ) {
#ifdef _DEBUG
			Com_Printf( "WARNING: Invalid newForceRank string\n" );
#endif
			return;
		}

		newRank = atoi( CG_Argv( 1 ) );
		doMenu = atoi( CG_Argv( 2 ) );
		setTeam = atoi( CG_Argv( 3 ) );

		trap->Cvar_Set( "ui_rankChange", va( "%i", newRank ) );

		trap->Cvar_Set( "ui_myteam", va( "%i", setTeam ) );

		if ( !(trap->Key_GetCatcher() & KEYCATCH_UI) && doMenu && !cg.demoPlayback )
			trap->OpenUIMenu( UIMENU_PLAYERCONFIG );

		return;
	}

	if ( !strcmp( cmd, "kg2" ) ) {
		// Kill a ghoul2 instance in this slot.
		// If it has been occupied since this message was sent somehow, the worst that can (should) happen is the instance
		//	will have to reinit with its current info.
		int i, indexNum = 0, argNum = trap->Cmd_Argc();

		if ( argNum < 1 )
			return;

		for ( i = 1; i < argNum; i++ ) {
			indexNum = atoi( CG_Argv( i ) );

			if ( cg_entities[indexNum].ghoul2 && trap->G2_HaveWeGhoul2Models( cg_entities[indexNum].ghoul2 ) ) {
				if ( indexNum < MAX_CLIENTS ) { //You try to do very bad thing!
#ifdef _DEBUG
					Com_Printf( "WARNING: Tried to kill a client ghoul2 instance with a kg2 command!\n" );
#endif
					return;
				}

				CG_KillCEntityG2( indexNum );
			}
		}

		return;
	}

	if ( !strcmp( cmd, "kls" ) ) {
		// kill looping sounds
		int indexNum = 0, argNum = trap->Cmd_Argc();
		centity_t *clent = NULL, *trackerent = NULL;

		if ( argNum < 1 ) {
			assert( 0 );
			return;
		}

		indexNum = atoi( CG_Argv( 1 ) );

		if ( indexNum != -1 )
			clent = &cg_entities[indexNum];

		if ( argNum >= 2 ) {
			indexNum = atoi( CG_Argv( 2 ) );

			if ( indexNum != -1 )
				trackerent = &cg_entities[indexNum];
		}

		if ( clent )
			CG_S_StopLoopingSound( clent->currentState.number, -1 );
		if ( trackerent )
			CG_S_StopLoopingSound( trackerent->currentState.number, -1 );

		return;
	}

	// this means param 2 is the body index and we want to copy to bodyqueue on it
	if ( !strcmp( cmd, "ircg" ) )
		IRCG = qtrue;

	if ( !strcmp( cmd, "rcg" ) || IRCG ) {
		//rcg - Restore Client Ghoul (make sure limbs are reattached and ragdoll state is reset - this must be done reliably)
		int indexNum = 0, argNum = trap->Cmd_Argc();
		centity_t *clent;

		if ( argNum < 1 ) {
			assert( 0 );
			return;
		}

		indexNum = atoi( CG_Argv( 1 ) );
		if ( indexNum < 0 || indexNum >= MAX_CLIENTS ) {
			assert( 0 );
			return;
		}

		clent = &cg_entities[indexNum];

		// this can happen while connecting as a client
		if ( !clent->ghoul2 )
			return;

#ifdef _DEBUG
		if ( !trap->G2_HaveWeGhoul2Models( clent->ghoul2 ) )
			assert( !"Tried to reset state on a bad instance. Crash is inevitable." );
#endif

		if ( IRCG ) {
			int bodyIndex = 0, weaponIndex = 0, side = 0;
			centity_t *body;

			assert( argNum >= 3 );
			bodyIndex = atoi( CG_Argv( 2 ) );
			weaponIndex = atoi( CG_Argv( 3 ) );
			side = atoi( CG_Argv( 4 ) );

			body = &cg_entities[bodyIndex];
			body->teamPowerType = side ? 1 : 0;

			CG_BodyQueueCopy( body, clent->currentState.number, weaponIndex );
		}

		// reattach any missing limbs
		if ( clent->torsoBolt )
			CG_ReattachLimb( clent );

		// make sure ragdoll state is reset
		if ( clent->isRagging ) {
			clent->isRagging = qfalse;
			trap->G2API_SetRagDoll( clent->ghoul2, NULL ); //calling with null parms resets to no ragdoll.
		}

		// clear all the decals as well
		trap->G2API_ClearSkinGore( clent->ghoul2 );

		clent->weapon = 0;
		clent->ghoul2weapon = NULL; //force a weapon reinit

		return;
	}

	if ( !strcmp( cmd, "cp" ) ) {
		char strEd[MAX_STRINGED_SV_STRING];
		CG_CheckSVStringEdRef( strEd, CG_Argv( 1 ) );
		CG_CenterPrint( strEd, SCREEN_HEIGHT * 0.30f, BIGCHAR_WIDTH );
		return;
	}

	if ( !strcmp( cmd, "cps" ) ) {
		char strEd[MAX_STRINGED_SV_STRING];
		char *x = (char *)CG_Argv( 1 );
		if ( x[0] == '@' )
			x++;
		trap->SE_GetStringTextString( x, strEd, MAX_STRINGED_SV_STRING );
		//Raz: From OJP
		//	CG_CenterPrint( strEd, SCREEN_HEIGHT * 0.30f, BIGCHAR_WIDTH );
		CG_CenterPrint( strEd, SCREEN_HEIGHT * 0.20f, BIGCHAR_WIDTH );
		return;
	}

	if ( !strcmp( cmd, "cs" ) ) {
		CG_ConfigStringModified();
		return;
	}

	if ( !strcmp( cmd, "print" ) ) {
		char strEd[MAX_STRINGED_SV_STRING];
		CG_CheckSVStringEdRef( strEd, CG_Argv( 1 ) );
		CG_LogPrintf( cg.log.console, strEd );
		trap->Print( "%s", strEd );
		return;
	}

	if ( !strcmp( cmd, "chat" ) ) {
		char *msg = JPLua_Event_ChatMessageRecieved( CG_Argv( 1 ) );

		//If a JPLua plugin cancelled it, bail
		if ( !msg )
			return;

		if ( !cg_teamChatsOnly.integer ) {
			char cbName[MAX_CHATBOX_IDENTIFIER_SIZE] = "normal";
			trap->S_StartLocalSound( media.sounds.interface.talk, CHAN_LOCAL_SOUND );
			Q_strncpyz( text, msg, MAX_SAY_TEXT );

			if ( CG_ContainsChannelEscapeChar( text ) )
				Q_strncpyz( cbName, CG_RemoveChannelEscapeChar( text ), sizeof(cbName) );

			CG_RemoveChatEscapeChar( text );
			CG_LogPrintf( cg.log.console, va( "%s\n", text ) );
			if ( cg_newChatbox.integer )
				CG_ChatboxAddMessage( text, qfalse, cbName );
			else
				CG_ChatBox_AddString( text );
			trap->Print( "*%s\n", text );
			Q_CleanString( text, STRIP_COLOUR );
			CG_LogPrintf( cg.log.chat, va( "%s\n", text ) );
		}

		return;
	}

	if ( !strcmp( cmd, "tchat" ) ) {
		trap->S_StartLocalSound( media.sounds.interface.talk, CHAN_LOCAL_SOUND );
		Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
		CG_RemoveChatEscapeChar( text );
		CG_LogPrintf( cg.log.console, va( "%s\n", text ) );
		if ( cg_newChatbox.integer )
			CG_ChatboxAddMessage( text, qfalse, "team" );
		else
			CG_ChatBox_AddString( text );
		trap->Print( "*%s\n", text );
		Q_CleanString( text, STRIP_COLOUR );
		CG_LogPrintf( cg.log.chat, va( "%s\n", text ) );

		return;
	}

	//chat with location, possibly localized.
	if ( !strcmp( cmd, "lchat" ) ) {
		if ( !cg_teamChatsOnly.integer ) {
			char name[MAX_STRING_CHARS], loc[MAX_STRING_CHARS], color[8], message[MAX_STRING_CHARS];

			if ( trap->Cmd_Argc() < 4 )
				return;

			Q_strncpyz( name, CG_Argv( 1 ), sizeof(name) );
			Q_strncpyz( loc, CG_Argv( 2 ), sizeof(loc) );
			Q_strncpyz( color, CG_Argv( 3 ), sizeof(color) );
			Q_strncpyz( message, CG_Argv( 4 ), sizeof(message) );

			if ( loc[0] == '@' )
				trap->SE_GetStringTextString( loc + 1, loc, sizeof(loc) );

			trap->S_StartLocalSound( media.sounds.interface.talk, CHAN_LOCAL_SOUND );
			//	Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
			Com_sprintf( text, sizeof(text), "%s" S_COLOR_WHITE "<%s> ^%s%s", name, loc, color, message );
			CG_RemoveChatEscapeChar( text );
			//Raz: Siege chat now uses the fancy new chatbox
			if ( cg_newChatbox.integer )
				CG_ChatboxAddMessage( text, qfalse, "normal" );
			else
				CG_ChatBox_AddString( text );
			trap->Print( "*%s\n", text );
			Q_CleanString( text, STRIP_COLOUR );
			CG_LogPrintf( cg.log.chat, va( "%s\n", text ) );
		}
		return;
	}
	if ( !strcmp( cmd, "ltchat" ) ) {
		char name[MAX_STRING_CHARS], loc[MAX_STRING_CHARS], color[8], message[MAX_STRING_CHARS];

		if ( trap->Cmd_Argc() < 4 )
			return;

		Q_strncpyz( name, CG_Argv( 1 ), sizeof(name) );
		Q_strncpyz( loc, CG_Argv( 2 ), sizeof(loc) );
		Q_strncpyz( color, CG_Argv( 3 ), sizeof(color) );
		Q_strncpyz( message, CG_Argv( 4 ), sizeof(message) );

		if ( loc[0] == '@' )
			trap->SE_GetStringTextString( loc + 1, loc, sizeof(loc) );

		trap->S_StartLocalSound( media.sounds.interface.talk, CHAN_LOCAL_SOUND );
		//	Q_strncpyz( text, CG_Argv( 1 ), MAX_SAY_TEXT );
		Com_sprintf( text, sizeof(text), "%s" S_COLOR_WHITE "<%s> ^%s%s", name, loc, color, message );
		CG_RemoveChatEscapeChar( text );
		if ( cg_newChatbox.integer )
			CG_ChatboxAddMessage( text, qfalse, "team" );
		else
			CG_ChatBox_AddString( text );
		trap->Print( "*%s\n", text );
		Q_CleanString( text, STRIP_COLOUR );
		CG_LogPrintf( cg.log.chat, va( "%s\n", text ) );

		return;
	}

	if ( !strcmp( cmd, "scores" ) ) {
		CG_ParseScores();
		return;
	}

	if ( !strcmp( cmd, "tinfo" ) ) {
		CG_ParseTeamInfo();
		return;
	}

	if ( !strcmp( cmd, "map_restart" ) ) {
		CG_MapRestart();
		return;
	}

	if ( !Q_stricmp( cmd, "remapShader" ) ) {
		if ( trap->Cmd_Argc() == 4 ) {
			char shader1[MAX_QPATH], shader2[MAX_QPATH];
			Q_strncpyz( shader1, CG_Argv( 1 ), sizeof(shader1) );
			Q_strncpyz( shader2, CG_Argv( 2 ), sizeof(shader2) );
			trap->R_RemapShader( shader1, shader2, CG_Argv( 3 ) );
			return;
		}
		return;
	}

	// loaddeferred can be both a servercmd and a consolecmd
	if ( !strcmp( cmd, "loaddefered" ) ) {	// FIXME: spelled wrong, but not changing for demo
		CG_LoadDeferredPlayers();
		return;
	}

	// clientLevelShot is sent before taking a special screenshot for the menu system during development
	if ( !strcmp( cmd, "clientLevelShot" ) ) {
		cg.levelShot = qtrue;
		return;
	}

	trap->Print( "Unknown client game command: %s\n", cmd );
}