Exemplo n.º 1
0
void JPLua_Serialiser_IterateTableRead( cJSON *parent, const char *name, lua_State *L ) {
	cJSON *t = NULL;
	int numElements, i, top;

	lua_newtable( L );
	top = lua_gettop( L );

	t = cJSON_GetObjectItem( parent, name );
	numElements = cJSON_GetArraySize( t );

	for ( i = 0; i < numElements; i++ ) {
		cJSON *e, *it;
		int kType, vType;
		const char *tmp;
		char k[256];

		e = cJSON_GetArrayItem( t, i );

		// key
		it = cJSON_GetObjectItem( e, "key" );
		kType = cJSON_ToInteger( cJSON_GetObjectItem( e, "key_type" ) );
		if ( (tmp = cJSON_ToString( it )) )
			Q_strncpyz( k, tmp, sizeof(k) );

		if ( kType == LUA_TSTRING ) {
			lua_pushstring( L, k );
		}
		else if ( kType == LUA_TNUMBER ) {
			lua_pushnumber( L, cJSON_ToNumber( it ) );
		}
		else {
			Com_Printf( "Invalid key type %s when reading table %s\n", lua_typename( L, kType ), name );
		}

		// value must be created based on type.
		it = cJSON_GetObjectItem( e, "value" );
		vType = cJSON_ToInteger( cJSON_GetObjectItem( e, "value_type" ) );
		if ( vType == LUA_TTABLE ) {
			JPLua_Serialiser_IterateTableRead( e, "value", L );
		}
		else if ( vType == LUA_TNUMBER ) {
			lua_pushnumber( L, cJSON_ToNumber( it ) );
		}
		else if ( vType == LUA_TBOOLEAN ) {
			lua_pushboolean( L, cJSON_ToBoolean( it ) );
		}
		else if ( vType == LUA_TSTRING ) {
			char v[1024 * 8]; // should be plenty..
			if ( (tmp = cJSON_ToString( it )) )
				Q_strncpyz( v, tmp, sizeof(v) );
			lua_pushstring( L, v );
		}

		lua_settable( L, top );
	}
}
Exemplo n.º 2
0
/*
============================
JKG_ParseSingleAmmo

Reads a single ammo entry from a .ammo file
============================
*/
static qboolean JKG_ParseSingleAmmo(cJSON* json) {
	const char* name = cJSON_GetItemKey(json);
	ammo_t* ammo = &ammoTable[numAmmoLoaded];
	cJSON* child;

	ammo->ammoIndex = numAmmoLoaded;
	Q_strncpyz(ammo->name, name, sizeof(ammo->name));

	Q_strncpyz(ammo->shortname, cJSON_ToStringOpt(cJSON_GetObjectItem(json, "shortname"), ""), sizeof(ammo->shortname));

	// Parse substitutes (we need to establish the link later)
	ammo->pSub = nullptr;
	child = cJSON_GetObjectItem(json, "basedOn");
	if (child) {
		Q_strncpyz(ammo->substitute, cJSON_ToString(child), sizeof(ammo->substitute));
	}
	else {
		Q_strncpyz(ammo->substitute, ammo->name, sizeof(ammo->substitute));
	}

	child = cJSON_GetObjectItem(json, "max");
	ammo->ammoMax = cJSON_ToIntegerOpt(child, 999);

	child = cJSON_GetObjectItem(json, "pricePerUnit");
	ammo->pricePerUnit = cJSON_ToNumberOpt(child, 1.0);

	child = cJSON_GetObjectItem(json, "overrides");
	if (child) {
		JKG_ParseAmmoOverrides(ammo, child);
	}

	return qtrue;
}
Exemplo n.º 3
0
/*
============================
JKG_ParseAmmoOverride_Means

Parses a means of death override
============================
*/
static void JKG_ParseAmmoOverride_Means(cJSON* json, const char* name, std::pair<qboolean, int>& field) {
	cJSON* node = cJSON_GetObjectItem(json, name);
	if (!node) {
		field.first = qfalse;
	}
	else {
		field.first = qtrue;
		field.second = JKG_GetMeansOfDamageIndex(cJSON_ToString(json));
	}
}
Exemplo n.º 4
0
void JKG_Bans_LoadBans()
{
	char *buffer;
	char error[256];
	fileHandle_t f;
	int len;
	int i, banCount;
	cJSON *root, *banlist, *item, *ip;
	banentry_t *entry;

	len = trap_FS_FOpenFile(g_banfile.string, &f, FS_READ);
	if (len < 1) {
		return;
	}
	buffer = malloc(len+1);
	trap_FS_Read(buffer, len, f);
	trap_FS_FCloseFile(f);

	buffer[len] = 0;

	root = cJSON_ParsePooled(buffer, error, sizeof(error));
	free(buffer);

	if (!root) {
		G_Printf("Error: Could not parse banlist: %s\n", error);
		return;
	}
	
	JKG_Bans_Clear();

	nextBanId = cJSON_ToInteger(cJSON_GetObjectItem(root, "nextid"));
	banlist = cJSON_GetObjectItem(root, "bans");

	banCount = cJSON_GetArraySize(banlist);
	for (i=0; i<banCount; i++) {
		item = cJSON_GetArrayItem(banlist, i);
		ip = cJSON_GetObjectItem(item, "ip");

		entry = malloc(sizeof(banentry_t));
		
		entry->id = cJSON_ToInteger(cJSON_GetObjectItem(item, "id"));
		entry->mask = cJSON_ToInteger(cJSON_GetObjectItem(item, "mask"));
		entry->expireTime = cJSON_ToInteger(cJSON_GetObjectItem(item, "expire"));
		Q_strncpyz(entry->banreason, cJSON_ToString(cJSON_GetObjectItem(item, "reason")), sizeof(entry->banreason));
		entry->ip[0] = cJSON_ToInteger(cJSON_GetArrayItem(ip, 0));
		entry->ip[1] = cJSON_ToInteger(cJSON_GetArrayItem(ip, 1));
		entry->ip[2] = cJSON_ToInteger(cJSON_GetArrayItem(ip, 2));
		entry->ip[3] = cJSON_ToInteger(cJSON_GetArrayItem(ip, 3));

		entry->next = bans;
		bans = entry;
	}
	cJSON_Delete(root);
}
Exemplo n.º 5
0
void Modification::Init(void){
	QDir basedir;
	basedir.setPath(Settings::JKFolder + "base/");
	QStringList modlist = basedir.entryList(QDir::Filter::Readable, QDir::SortFlag::Name);
	if (modlist.size() < 4){
		/* ERROR*/
	}/*assets0-3.pk3*/
	Q_FOREACH(QString name, modlist){
		if (name.contains(QRegExp("assets[0-4].pk3"))) continue;
		name.chop(3); //purge extension
		QFile *file = new QFile(Settings::JKFolder + "base" + name + ".json");
		QByteArray data = file->readAll();

		cJSON *root = cJSON_Parse(data.toStdString().c_str()), *temp;
		if (!root) continue; /* WARNING*/

		temp = cJSON_GetObjectItem(root, "id");
		Modification *mod = new Modification(cJSON_ToInteger(temp));

		temp = cJSON_GetObjectItem(root, "author");
		mod->author = cJSON_ToString(temp);

		temp = cJSON_GetObjectItem(root, "description");
		mod->description = cJSON_ToString(temp);

		temp = cJSON_GetObjectItem(root, "notcompatiblewith");
		QStringList list = QString(cJSON_ToString(temp)).split(QChar(','));
		Q_FOREACH(QString num, list){
			mod->notcompatiblewith.push_back(num.toInt());
		}

		temp = cJSON_GetObjectItem(root, "name");
		mod->name = cJSON_ToString(temp);

		temp = cJSON_GetObjectItem(root, "version");
		mod->version = cJSON_ToInteger(temp);

		cJSON_Delete(root);
		delete file;
	}
Exemplo n.º 6
0
/*
============================
JKG_ParseSimpleOverrideString

============================
*/
static void JKG_ParseSimpleOverrideString(std::pair<qboolean, std::string>& field, const char* nodeName, cJSON* json)
{
	cJSON* child = cJSON_GetObjectItem(json, nodeName);
	if (child)
	{
		field.first = qtrue;
		field.second = cJSON_ToString(child);
	}
	else
	{
		field.first = qfalse;
	}
}
Exemplo n.º 7
0
int registerFinalFunc (asyncTask_t *task) {
	cJSON *data = (cJSON *)task->finalData;
	
	if (task->errorCode == 0) {
		if (cJSON_ToInteger(cJSON_GetObjectItem(data, "errorCode"))) {
			Com_Printf("Registration failed: %s\n", cJSON_ToString(cJSON_GetObjectItem(data, "message")));
		} else {
			Com_Printf("Registration successful\n");
		}
	} else {
		Com_Printf("Registration request failed\n");
	}
	return 0;
}
Exemplo n.º 8
0
/*
============================
JKG_ParseSimpleOverrideVector

============================
*/
static void JKG_ParseSimpleOverrideVector(std::pair<qboolean, std::vector<std::string>>& field, const char* nodeName, cJSON* json)
{
	cJSON* child = cJSON_GetObjectItem(json, nodeName);
	if (child)
	{
		field.first = qtrue;
		for (int i = 0; i < cJSON_GetArraySize(child); i++)
		{
			field.second.push_back(cJSON_ToString(cJSON_GetArrayItem(child, i)));
		}
	}
	else
	{
		field.first = qfalse;
	}
}
static void ReadString ( cJSON *parent, const char *field, char *dest, size_t destSize )
{
    cJSON *node = NULL;
    const char *str = NULL;
    
    node = cJSON_GetObjectItem (parent, field);
    str = cJSON_ToString (node);
    if ( str && str[0] )
    {
        int len = strlen (str);
        if ( (len + 1) > destSize )
        {
            Com_Printf (S_COLOR_YELLOW "WARNING: %s is too long (%d chars). Max length for this string is %d.\n", str, len, destSize - 1);
        }
        Q_strncpyz (dest, str, destSize);
    }
}
static void BG_ParseAnimationObject ( cJSON *animationNode, int *torsoAnimation, int *legsAnimation )
{
    cJSON *node = cJSON_GetObjectItem (animationNode, "torso");
    const char *anim = cJSON_ToStringOpt (node, "BOTH_STAND1");
    
    *torsoAnimation = GetIDForString (animTable, anim);
    
    node = cJSON_GetObjectItem (animationNode, "legs");
    if ( node == NULL )
    {
        *legsAnimation = *torsoAnimation;
        return;
    }
    
    anim = cJSON_ToString (node);
    *legsAnimation = GetIDForString (animTable, anim);
}
Exemplo n.º 11
0
/*
============================
JKG_ParseJetpack

Parses a jetpack file, from memory.
============================
*/
static qboolean JKG_ParseJetpack(char* buffer, const char* fileName, jetpackData_t& jetpackData) {
	char errorBuffer[JETPACK_ERRBUFFER] {0};
	cJSON* json;
	cJSON* jsonNode;
	
	json = cJSON_ParsePooled(buffer, errorBuffer, sizeof(errorBuffer));
	if (json == nullptr) {
		Com_Printf(S_COLOR_RED "%s: %s\n", fileName, errorBuffer);
		return qfalse;
	}

	// Basic information
	jsonNode = cJSON_GetObjectItem(json, "ref");
	if (!jsonNode) {
		Com_Printf(S_COLOR_RED "%s doesn't contain a valid ref name!\n", fileName);
		cJSON_Delete(json);
		return qfalse;
	}
	Q_strncpyz(jetpackData.ref, cJSON_ToString(jsonNode), sizeof(jetpackData.ref));

	jsonNode = cJSON_GetObjectItem(json, "fuelCapacity");
	jetpackData.fuelCapacity = cJSON_ToIntegerOpt(jsonNode, 100);

	jsonNode = cJSON_GetObjectItem(json, "fuelConsumption");
	jetpackData.fuelConsumption = cJSON_ToNumberOpt(jsonNode, 1.0);

	jsonNode = cJSON_GetObjectItem(json, "thrustConsumption");
	jetpackData.thrustConsumption = cJSON_ToNumberOpt(jsonNode, 2.0);

	jsonNode = cJSON_GetObjectItem(json, "fuelRegeneration");
	jetpackData.fuelRegeneration = cJSON_ToNumberOpt(jsonNode, 1.0);

	// Movement related fields
	jsonNode = cJSON_GetObjectItem(json, "movement");
	JKG_ParseJetpackMovement(jsonNode, jetpackData);

	// Visuals
	jsonNode = cJSON_GetObjectItem(json, "visuals");
	JKG_ParseJetpackVisuals(jsonNode, jetpackData);

	cJSON_Delete(json);
	return qtrue;
}
Exemplo n.º 12
0
static int GLua_JSON_ToString( lua_State *L )
{
	// Check and make sure we're using a valid index
	if( !FJSON_ValidateNode( L, 1 ) )
	{
		lua_pushnil(L);
		return 1;
	}

	// Convert it to string (^.^)
	int index = luaL_checkint( L, 1 );
	const char *text = cJSON_ToString( fJSON.jsonBinding.at( index ) );
	if( !text )
	{
		lua_pushnil( L );
		return 1;
	}

	lua_pushstring( L, text );
	return 1;
}
Exemplo n.º 13
0
/*
============================
JKG_ParseJetpackVisuals

Parses the visual elements of a jetpack.
FIXME: Should precache?
============================
*/
static void JKG_ParseJetpackVisuals(cJSON* jsonNode, jetpackData_t& jetpackData) {
	cJSON* child;
	int boltSize;

	child = cJSON_GetObjectItem(jsonNode, "modelName");
	Q_strncpyz(jetpackData.visuals.modelName, cJSON_ToStringOpt(child, ""), MAX_QPATH);

	child = cJSON_GetObjectItem(jsonNode, "effectBolts");
	boltSize = cJSON_GetArraySize(child);
	for (int i = 0; i < boltSize; i++) {
		cJSON* arrayObj = cJSON_GetArrayItem(child, i);
		std::string bolt = cJSON_ToString(arrayObj);
		jetpackData.visuals.effectBolts.push_back(bolt);
	}

	child = cJSON_GetObjectItem(jsonNode, "hoverEffect");
	Q_strncpyz(jetpackData.visuals.hoverEffect, cJSON_ToStringOpt(child, ""), MAX_QPATH);

	child = cJSON_GetObjectItem(jsonNode, "thrustEffect");
	Q_strncpyz(jetpackData.visuals.thrustEffect, cJSON_ToStringOpt(child, ""), MAX_QPATH);

	child = cJSON_GetObjectItem(jsonNode, "jetEffect");
	Q_strncpyz(jetpackData.visuals.jetEffect, cJSON_ToStringOpt(child, ""), MAX_QPATH);

	child = cJSON_GetObjectItem(jsonNode, "idleSound");
	Q_strncpyz(jetpackData.visuals.idleSound, cJSON_ToStringOpt(child, ""), MAX_QPATH);

	child = cJSON_GetObjectItem(jsonNode, "thrustSound");
	Q_strncpyz(jetpackData.visuals.thrustSound, cJSON_ToStringOpt(child, ""), MAX_QPATH);

	child = cJSON_GetObjectItem(jsonNode, "activateSound");
	Q_strncpyz(jetpackData.visuals.activateSound, cJSON_ToStringOpt(child, ""), MAX_QPATH);

	child = cJSON_GetObjectItem(jsonNode, "deactivateSound");
	Q_strncpyz(jetpackData.visuals.deactivateSound, cJSON_ToStringOpt(child, ""), MAX_QPATH);

	child = cJSON_GetObjectItem(jsonNode, "sputterSound");
	Q_strncpyz(jetpackData.visuals.sputterSound, cJSON_ToStringOpt(child, ""), MAX_QPATH);
}
Exemplo n.º 14
0
/*
=====================
JKG_ParseArmorFile

=====================
*/
static qboolean JKG_ParseArmorFile(char* buffer, const char* fileName, armorData_t& armorData) {
	char errorBuffer[ARMOR_ERRBUFFER] {0};
	cJSON* json;
	cJSON* jsonNode;

	json = cJSON_ParsePooled(buffer, errorBuffer, sizeof(errorBuffer));
	if (json == nullptr) {
		Com_Printf(S_COLOR_RED "%s: %s\n", fileName, errorBuffer);
		return qfalse;
	}

	// Basic information
	jsonNode = cJSON_GetObjectItem(json, "ref");
	if (!jsonNode) {
		Com_Printf(S_COLOR_RED "%s doesn't contain a valid ref name!\n", fileName);
		cJSON_Delete(json);
		return qfalse;
	}
	Q_strncpyz(armorData.ref, cJSON_ToString(jsonNode), sizeof(armorData.ref));

	jsonNode = cJSON_GetObjectItem(json, "slot");
	armorData.slot = JKG_ArmorSlotFromText(cJSON_ToStringOpt(jsonNode, ""));

	jsonNode = cJSON_GetObjectItem(json, "armor");
	armorData.armor = cJSON_ToIntegerOpt(jsonNode, 0);

	jsonNode = cJSON_GetObjectItem(json, "hp");
	armorData.hp = cJSON_ToIntegerOpt(jsonNode, 0);

	jsonNode = cJSON_GetObjectItem(json, "movemodifier");
	armorData.movemodifier = cJSON_ToNumberOpt(jsonNode, 1.0);

	jsonNode = cJSON_GetObjectItem(json, "visuals");
	JKG_ParseArmorVisuals(jsonNode, armorData);

	cJSON_Delete(json);
	return qtrue;
}
Exemplo n.º 15
0
qboolean JKG_Items_LoadCraftFile( const char *filePath, craftRecipe_t *craftData, const char * const bench, const char * const type )
{
	char error[MAX_STRING_CHARS];
	int i, j;

	cJSON *json = NULL;
	cJSON *jsonNode = NULL;
	
	char craftFileData[MAX_CRAFTING_FILE_SIZE];
	fileHandle_t f;
	int fileLen = strap_FS_FOpenFile(filePath, &f, FS_READ);

	if(!f || fileLen == -1)
	{
		Com_Printf(S_COLOR_RED "Unreadable or empty loot file: %s\n", filePath);
		return qfalse;
	}
	if( (fileLen + 1) >= MAX_CRAFTING_FILE_SIZE )
	{
		strap_FS_FCloseFile(f);
		Com_Printf(S_COLOR_RED "%s: File too large\n", filePath);
		return qfalse;
	}

	strap_FS_Read(&craftFileData, fileLen, f);
	craftFileData[fileLen] = '\0';

	strap_FS_FCloseFile(f);

	json = cJSON_ParsePooled(craftFileData, error, sizeof(error));
	if(json == NULL)
	{
		Com_Printf(S_COLOR_RED "%s:%s\n", filePath, error);
		return qfalse;
	}

	JKG_Array_Init(&craftData->input, sizeof(craftInput_t), 1);
	JKG_Array_Init(&craftData->output, sizeof(craftInput_t), 1);

	for(i = 0; i < MAX_INPUTS; i++)
	{
		int inputSize;
		cJSON *inputNode = NULL;
		jsonNode = cJSON_GetObjectItem(json, va("input%i", i));
		inputSize = cJSON_GetArraySize(jsonNode);
		for(j = 0; j < inputSize; j++)
		{
			craftInput_t dummy2;
			inputNode = cJSON_GetArrayItem(jsonNode, j);
			dummy2.internalName = cJSON_ToString(cJSON_GetObjectItem(inputNode, "internal"));
			dummy2.itemID = cJSON_ToInteger(cJSON_GetObjectItem(inputNode, "itemid"));
			dummy2.quantity = 1;
			dummy2.quantity = cJSON_ToInteger(cJSON_GetObjectItem(inputNode, "quantity"));
			JKG_Array_Add(&craftData->input, &dummy2);
		}
	}

	for(i = 0; i < MAX_INPUTS; i++)
	{
		int outputSize;
		cJSON *outputNode = NULL;
		jsonNode = cJSON_GetObjectItem(json, va("output%i", i));
		outputSize = cJSON_GetArraySize(jsonNode);
		for(j = 0; j < outputSize; j++)
		{
			craftInput_t dummy2;
			outputNode = cJSON_GetArrayItem(jsonNode, j);
			dummy2.internalName = cJSON_ToString(cJSON_GetObjectItem(outputNode, "internal"));
			dummy2.itemID = cJSON_ToInteger(cJSON_GetObjectItem(outputNode, "itemid"));
			dummy2.quantity = 1;
			dummy2.quantity = cJSON_ToInteger(cJSON_GetObjectItem(outputNode, "quantity"));
			JKG_Array_Add(&craftData->output, &dummy2);
		}
	}

	if(Q_stricmp(bench, "workbench"))
		craftData->craftBench = CRAFTING_WORKBENCH;
	else if(Q_stricmp(bench, "welding"))
		craftData->craftBench = CRAFTING_WELDING;
	else if(Q_stricmp(bench, "laboratory"))
		craftData->craftBench = CRAFTING_CHEMICAL;
	else
		craftData->craftBench = CRAFTING_WORKBENCH;

	craftData->freestyle = (Q_stricmp(type, "freestyle") == 0) ? qtrue : qfalse;
	craftData->group = (craftData->freestyle == qtrue) ? cJSON_ToInteger(cJSON_GetObjectItem(json, "group")) : -1;

	if(craftData->freestyle)
		JKG_Array_Add(&FreestyleRecipes[craftData->craftBench], craftData);
	else
		JKG_Array_Add(&CraftingRecipes[craftData->craftBench], craftData);

	cJSON_Delete(json);
	return qtrue;
}
Exemplo n.º 16
0
// Called on a reconnect
void G_ReadClientSessionData( gclient_t *client ) {
	clientSession_t *sess = &client->sess;
	cJSON *root = NULL, *object = NULL;
	char fileName[MAX_QPATH] = {};
	char *buffer = NULL;
	fileHandle_t f = NULL_FILE;
	unsigned int len = 0;
	const char *tmp = NULL;
	char jsonError[MAX_STRING_CHARS] = {};

	Com_sprintf( fileName, sizeof(fileName), "session/client%02i.json", client - level.clients );
	len = trap->FS_Open( fileName, &f, FS_READ );

	// no file
	if ( !f || !len || len == -1 ) {
		trap->FS_Close( f );
		return;
	}

	buffer = (char *)malloc( len + 1 );
	if ( !buffer ) {
		return;
	}

	trap->FS_Read( buffer, len, f );
	trap->FS_Close( f );
	buffer[len] = '\0';

	// read buffer
	root = cJSON_Parse( buffer, jsonError, sizeof(jsonError) );
	free( buffer );

	if ( !root ) {
		Com_Printf( "G_ReadSessionData(%02i): could not parse session data\n", client - level.clients );
		return;
	}

	if ( (object = cJSON_GetObjectItem( root, "sessionTeam" )) ) {
		sess->sessionTeam = (team_t)cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "spectatorNum" )) ) {
		sess->spectatorNum = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "spectatorState" )) ) {
		sess->spectatorState = (spectatorState_t)cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "spectatorClient" )) ) {
		sess->spectatorClient = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "wins" )) ) {
		sess->wins = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "losses" )) ) {
		sess->losses = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "setForce" )) ) {
		sess->setForce = (qboolean)cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "saberLevel" )) ) {
		sess->saberLevel = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "selectedFP" )) ) {
		sess->selectedFP = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "updateUITime" )) ) {
		sess->updateUITime = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "duelTeam" )) ) {
		sess->duelTeam = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "siegeDesiredTeam" )) ) {
		sess->siegeDesiredTeam = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "saberType" )) ) {
		if ( (tmp = cJSON_ToString( object )) ) {
			Q_strncpyz( sess->saberType, tmp, sizeof(sess->saberType) );
		}
	}
	if ( (object = cJSON_GetObjectItem( root, "saber2Type" )) ) {
		if ( (tmp = cJSON_ToString( object )) ) {
			Q_strncpyz( sess->saber2Type, tmp, sizeof(sess->saber2Type) );
		}
	}
	if ( (object = cJSON_GetObjectItem( root, "IP" )) ) {
		if ( (tmp = cJSON_ToString( object )) ) {
			Q_strncpyz( sess->IP, tmp, sizeof(sess->IP) );
		}
	}
	if ( (object = cJSON_GetObjectItem( root, "connTime" )) ) {
		sess->connTime = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "noq3fill" )) ) {
		sess->noq3fill = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "validated" )) ) {
		sess->validated = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "adminRank" )) ) {
		sess->adminRank = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "canUseCheats" )) ) {
		sess->canUseCheats = !!cJSON_ToInteger( object );
	}

	client->ps.fd.saberAnimLevel = client->sess.saberLevel;
	client->ps.fd.saberDrawAnimLevel = client->sess.saberLevel;
	client->ps.fd.forcePowerSelected = client->sess.selectedFP;

	cJSON_Delete( root );
	root = NULL;
}
Exemplo n.º 17
0
// called on a reconnect
void G_ReadClientSessionData( gclient_t *client ) {
	clientSession_t *sess = &client->sess;
	cJSON *root = NULL, *object = NULL;
	char fileName[MAX_QPATH] = {};
	char *buffer = NULL;
	fileHandle_t f = NULL_FILE;
	unsigned int len = 0;
	const char *tmp = NULL;

	Com_sprintf( fileName, sizeof(fileName), "session/client%02i.json", client - level.clients );
	len = trap->FS_Open( fileName, &f, FS_READ );

	// no file
	if ( !f || !len || len == -1 ) {
		trap->FS_Close( f );
		return;
	}

	buffer = (char *)malloc( len + 1 );
	if ( !buffer ) {
		return;
	}

	trap->FS_Read( buffer, len, f );
	trap->FS_Close( f );
	buffer[len] = '\0';

	// read buffer
	root = cJSON_Parse( buffer );
	free( buffer );

	if ( !root ) {
		Com_Printf( "G_ReadSessionData(%02i): could not parse session data\n", client - level.clients );
		return;
	}

	if ( (object = cJSON_GetObjectItem( root, "sessionTeam" )) ) {
		sess->sessionTeam = (team_t)cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "spectatorTime" )) ) {
		sess->spectatorTime = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "spectatorState" )) ) {
		sess->spectatorState = (spectatorState_t)cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "spectatorClient" )) ) {
		sess->spectatorClient = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "wins" )) ) {
		sess->wins = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "losses" )) ) {
		sess->losses = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "setForce" )) ) {
		sess->setForce = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "saberLevel" )) ) {
		sess->saberLevel = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "selectedFP" )) ) {
		sess->selectedFP = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "duelTeam" )) ) {
		sess->duelTeam = cJSON_ToInteger( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "siegeDesiredTeam" )) ) {
		sess->siegeDesiredTeam = cJSON_ToInteger( object );
	}

	if ( (object = cJSON_GetObjectItem( root, "siegeClass" )) ) {
		if ( (tmp = cJSON_ToString( object )) ) {
			Q_strncpyz( sess->siegeClass, tmp, sizeof(sess->siegeClass) );
		}
	}
	if ( (object = cJSON_GetObjectItem( root, "IP" )) ) {
		if ( (tmp = cJSON_ToString( object )) ) {
			Q_strncpyz( sess->IP, tmp, sizeof(sess->IP) );
		}
	}
	if ( (object = cJSON_GetObjectItem( root, "admin" )) ) {
		if ( (tmp = cJSON_ToString( object )) ) {
			client->pers.adminUser = AM_ChecksumLogin( tmp );
		}
	}

	if ( (object = cJSON_GetObjectItem( root, "empowered" )) ) {
		client->pers.adminData.empowered = cJSON_ToBoolean( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "merc" )) ) {
		client->pers.adminData.merc = cJSON_ToBoolean( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "silenced" )) ) {
		client->pers.adminData.silenced = cJSON_ToBoolean( object );
	}
	if ( (object = cJSON_GetObjectItem( root, "slept" )) ) {
		client->pers.adminData.isSlept = cJSON_ToBoolean( object );
	}
	if ((object = cJSON_GetObjectItem(root, "tempprivs"))) {
		client->pers.tempprivs = cJSON_ToInteger(object);
	}

	client->ps.fd.saberAnimLevel = sess->saberLevel;
	client->ps.fd.saberDrawAnimLevel = sess->saberLevel;
	client->ps.fd.forcePowerSelected = sess->selectedFP;

	cJSON_Delete( root );
	root = NULL;
}
static void BG_ParseWeaponFireMode ( weaponFireModeStats_t *fireModeStats, cJSON *fireModeNode )
{
    cJSON *node;
    const char *str = NULL;
    
    if ( fireModeNode == NULL )
    {
        return;
    }
    
    node = cJSON_GetObjectItem (fireModeNode, "ammo");
    str = cJSON_ToString (node);
    if ( str && str[0] )
    {
        fireModeStats->ammo = BG_GetAmmo (str);
    }

    node = cJSON_GetObjectItem (fireModeNode, "damage");
#ifdef QAGAME
    BG_ParseDamage (fireModeStats, node, qfalse);
    
    node = cJSON_GetObjectItem (fireModeNode, "secondarydamage");
    BG_ParseDamage (fireModeStats, node, qtrue);
#else
	fireModeStats->baseDamage = cJSON_ToInteger (node);
#endif
    
    node = cJSON_GetObjectItem (fireModeNode, "grenade");
    fireModeStats->isGrenade = (qboolean)cJSON_ToBooleanOpt (node, 0);

	node = cJSON_GetObjectItem (fireModeNode, "grenadeBounces");
    fireModeStats->grenadeBounces = (qboolean)cJSON_ToBooleanOpt (node, 1);

	node = cJSON_GetObjectItem (fireModeNode, "grenadeBounceDMG");
    fireModeStats->grenadeBounceDMG = (char)cJSON_ToIntegerOpt (node, 10);
    
    node = cJSON_GetObjectItem (fireModeNode, "ballistic");
    fireModeStats->applyGravity = (char)cJSON_ToBooleanOpt (node, 0);
    
    node = cJSON_GetObjectItem (fireModeNode, "bounces");
    fireModeStats->bounceCount = (char)cJSON_ToIntegerOpt (node, 0);
    
    node = cJSON_GetObjectItem (fireModeNode, "hitscan");
    fireModeStats->hitscan = (char)cJSON_ToBooleanOpt (node, 0);
    
    node = cJSON_GetObjectItem (fireModeNode, "projectiles");
    fireModeStats->shotCount = (char)cJSON_ToIntegerOpt (node, 0);
    
    node = cJSON_GetObjectItem (fireModeNode, "collisionsize");
    fireModeStats->boxSize = (float)cJSON_ToNumberOpt (node, 0.0);
    
    node = cJSON_GetObjectItem (fireModeNode, "maxchargetime");
    fireModeStats->chargeMaximum = (short)cJSON_ToIntegerOpt (node, 0);
    
    node = cJSON_GetObjectItem (fireModeNode, "chargedamage");
    fireModeStats->chargeMultiplier = (float)cJSON_ToNumberOpt (node, 0);
    
    node = cJSON_GetObjectItem (fireModeNode, "chargedelay");
    fireModeStats->chargeTime = (short)cJSON_ToIntegerOpt (node, 0);
    
    node = cJSON_GetObjectItem (fireModeNode, "ammocost");
    fireModeStats->cost = (char)cJSON_ToIntegerOpt (node, 0);
    
    node = cJSON_GetObjectItem (fireModeNode, "firingtype");
    BG_ParseFireModeFiringType (fireModeStats, cJSON_ToStringOpt (node, "auto"));
    
    // 0 means fully automatic, otherwise one burst will fire weapon n times.
    node = cJSON_GetObjectItem (fireModeNode, "shotsperburst");
    fireModeStats->shotsPerBurst = (char)cJSON_ToIntegerOpt (node, 0);
    
    // 0 means infinite delay (semi-automatic), otherwise n milliseconds between
    // rounds in a burst.
    node = cJSON_GetObjectItem (fireModeNode, "burstshotdelay");
    fireModeStats->burstFireDelay = (short)cJSON_ToIntegerOpt (node, 0);
    
    node = cJSON_GetObjectItem (fireModeNode, "firedelay");
    fireModeStats->delay = (short)cJSON_ToIntegerOpt (node, 0);
    
    node = cJSON_GetObjectItem (fireModeNode, "range");
    fireModeStats->range = (float)cJSON_ToIntegerOpt (node, WPR_M);
    
    node = cJSON_GetObjectItem (fireModeNode, "splashrange");
    fireModeStats->rangeSplash = (float)cJSON_ToNumberOpt (node, 0.0);
    
    node = cJSON_GetObjectItem (fireModeNode, "recoil");
    fireModeStats->recoil = (float)cJSON_ToNumberOpt (node, 0.0);
    
    //node = cJSON_GetObjectItem (fireModeNode, "spread");
    //fireModeStats->spread = (float)cJSON_ToNumberOpt (node, 0.0);

	node = cJSON_GetObjectItem (fireModeNode, "accuracy");
	if( node )
	{
		cJSON *child = NULL;

		child = cJSON_GetObjectItem( node, "accuracyRating" );
		fireModeStats->weaponAccuracy.accuracyRating = (vec_t)cJSON_ToNumberOpt( child, 32.0f );

		child = cJSON_GetObjectItem( node, "crouchModifier" );
		fireModeStats->weaponAccuracy.crouchModifier = (float)cJSON_ToNumberOpt( child, 0.8f );

		child = cJSON_GetObjectItem( node, "runModifier" );
		fireModeStats->weaponAccuracy.runModifier = (float)cJSON_ToNumberOpt( child, 2.0f );

		child = cJSON_GetObjectItem( node, "sightsModifier" );
		fireModeStats->weaponAccuracy.sightsModifier = (float)cJSON_ToNumberOpt( child, 0.2f );

		child = cJSON_GetObjectItem( node, "walkModifier" );
		fireModeStats->weaponAccuracy.walkModifier = (float)cJSON_ToNumberOpt( child, 1.55f );

		child = cJSON_GetObjectItem( node, "inAirModifier" );
		fireModeStats->weaponAccuracy.inAirModifier = (float)cJSON_ToNumberOpt( child, 3.0f );

		child = cJSON_GetObjectItem( node, "accuracyRatingPerShot" );
		fireModeStats->weaponAccuracy.accuracyRatingPerShot = (int)cJSON_ToNumberOpt( child, 2 );

		child = cJSON_GetObjectItem( node, "msToDrainAccuracy" );
		fireModeStats->weaponAccuracy.msToDrainAccuracy = (int)cJSON_ToNumberOpt( child, 200 );

		child = cJSON_GetObjectItem( node, "maxAccuracyAdd" );
		fireModeStats->weaponAccuracy.maxAccuracyAdd = (int)cJSON_ToNumberOpt( child, 128 );
	}
	else
	{
		fireModeStats->weaponAccuracy.accuracyRating = 32.0f;
		fireModeStats->weaponAccuracy.crouchModifier = 0.8f;
		fireModeStats->weaponAccuracy.runModifier = 2.0f;
		fireModeStats->weaponAccuracy.sightsModifier = 0.2f;
		fireModeStats->weaponAccuracy.walkModifier = 1.55f;
		fireModeStats->weaponAccuracy.inAirModifier = 3.0f;
		fireModeStats->weaponAccuracy.accuracyRatingPerShot = 2;
		fireModeStats->weaponAccuracy.msToDrainAccuracy = 200;
		fireModeStats->weaponAccuracy.maxAccuracyAdd = 128;
	}
    
    node = cJSON_GetObjectItem (fireModeNode, "projectilespeed");
    fireModeStats->speed = (float)cJSON_ToNumberOpt (node, 0.0);
    
    node = cJSON_GetObjectItem (fireModeNode, "projectileclass");
    str = cJSON_ToStringOpt (node, "unknown_proj");
    Q_strncpyz (fireModeStats->weaponClass, str, sizeof (fireModeStats->weaponClass));
    
    node = cJSON_GetObjectItem (fireModeNode, "meansofdeath");
    str = cJSON_ToStringOpt (node, "MOD_UNKNOWN");
    fireModeStats->weaponMOD = GetIDForString (MODTable, str);
    
    node = cJSON_GetObjectItem (fireModeNode, "splashmeansofdeath");
    str = cJSON_ToStringOpt (node, "MOD_UNKNOWN");
    fireModeStats->weaponSplashMOD = GetIDForString (MODTable, str);
}
static void BG_ParseVisualsFireMode ( weaponVisualFireMode_t *fireMode, cJSON *fireModeNode, int numFireModes )
{
    cJSON *node = NULL;
    cJSON *child = NULL;
    qboolean isGrenade = qfalse;
    qboolean isBlaster = qfalse;
    qboolean isTripmine = qfalse;
    qboolean isDetpack = qfalse;

    ReadString (fireModeNode, "type", fireMode->type, sizeof (fireMode->type));
    isGrenade = (qboolean)(Q_stricmp (fireMode->type, "grenade") == 0);
    isBlaster = (qboolean)(Q_stricmp (fireMode->type, "blaster") == 0);
    isTripmine = (qboolean)(Q_stricmp (fireMode->type, "tripmine") == 0);
    isDetpack = (qboolean)(Q_stricmp (fireMode->type, "detpack") == 0);

	ReadString (fireModeNode, "displayName", fireMode->displayName, 128);

	ReadString (fireModeNode, "crosshairShader", fireMode->crosshairShader, MAX_QPATH);
	ReadString (fireModeNode, "switchToSound", fireMode->switchToSound, MAX_QPATH);
	if(!fireMode->switchToSound || !fireMode->switchToSound[0])
	{
		if(fmLoadCounter == 0)
		{
			Com_sprintf(fireMode->switchToSound, MAX_QPATH, "sound/weapons/common/click%i.wav", numFireModes);
		}
		else
		{
			Com_sprintf(fireMode->switchToSound, MAX_QPATH, "sound/weapons/common/click1.wav");
		}
	}

	node = cJSON_GetObjectItem (fireModeNode, "animType");
    fireMode->animType = (firingModeAnim_t)cJSON_ToInteger (node);

	fireMode->overrideIndicatorFrame = -1;											// set this as default since 0 is still a valid frame
	node = cJSON_GetObjectItem (fireModeNode, "overrideIndicatorFrame");
	if(node)
	{
		fireMode->overrideIndicatorFrame = cJSON_ToInteger (node);
	}
    
    // TODO: Need to tie this to the table in cg_weapons.c somehow...
    // Weapon Render
    node = cJSON_GetObjectItem (fireModeNode, "muzzlelightintensity");
    fireMode->weaponRender.generic.muzzleLightIntensity = (float)cJSON_ToNumber (node);
    
    ReadString (fireModeNode, "muzzlelightcolor", fireMode->weaponRender.generic.muzzleLightColor, sizeof (fireMode->weaponRender.generic.muzzleLightColor));
    ReadString (fireModeNode, "chargingfx", fireMode->weaponRender.generic.chargingEffect, sizeof (fireMode->weaponRender.generic.chargingEffect));    
    ReadString (fireModeNode, "muzzlefx", fireMode->weaponRender.generic.muzzleEffect, sizeof (fireMode->weaponRender.generic.muzzleEffect));
    
    // Weapon Fire
    child = cJSON_GetObjectItem (fireModeNode, "firesound");
    if ( child )
    {
        if ( cJSON_IsArray (child) )
        {
            const char *fireSounds[8];
            int numFireSounds = cJSON_ReadStringArray (child, 8, fireSounds);
            int i;
            
            for ( i = 0; i < numFireSounds; i++ )
            {
                Q_strncpyz (fireMode->weaponFire.generic.fireSound[i], fireSounds[i], sizeof (fireMode->weaponFire.generic.fireSound[i]));
            }
        }
        else
        {
            const char *s = cJSON_ToString (child);
            if ( s ) Q_strncpyz (fireMode->weaponFire.generic.fireSound[0], s, sizeof (fireMode->weaponFire.generic.fireSound[0]));
        }
    }
    
    // Traceline Render
    ReadString (fireModeNode, "tracelineshader", fireMode->tracelineRender.generic.tracelineShader, sizeof (fireMode->tracelineRender.generic.tracelineShader));
    
    node = cJSON_GetObjectItem (fireModeNode, "minsize");
    fireMode->tracelineRender.generic.minSize = (float)cJSON_ToNumber (node);
    
    node = cJSON_GetObjectItem (fireModeNode, "maxsize");
    fireMode->tracelineRender.generic.maxSize = (float)cJSON_ToNumber (node);
    
    node = cJSON_GetObjectItem (fireModeNode, "lifetime");
    fireMode->tracelineRender.generic.lifeTime = cJSON_ToInteger (node);
    
    // Weapon Charge
    ReadString (fireModeNode, "chargingsound", fireMode->weaponCharge.chargingSound, sizeof (fireMode->weaponCharge.chargingSound));
    
    // Projectile render
    ReadString (fireModeNode, "projectilemodel", fireMode->projectileRender.generic.projectileModel, sizeof (fireMode->projectileRender.generic.projectileModel));
    ReadString (fireModeNode, "projectilefx", fireMode->projectileRender.generic.projectileEffect, sizeof (fireMode->projectileRender.generic.projectileEffect));
    ReadString (fireModeNode, "runsound", fireMode->projectileRender.generic.runSound, sizeof (fireMode->projectileRender.generic.runSound));
    
    node = cJSON_GetObjectItem (fireModeNode, "lightintensity");
    fireMode->projectileRender.generic.lightIntensity = (float)cJSON_ToNumber (node);
    
    ReadString (fireModeNode, "lightcolor", fireMode->projectileRender.generic.lightColor, sizeof (fireMode->projectileRender.generic.lightColor));
  
    ReadString (fireModeNode, "deathfx", fireMode->projectileRender.generic.deathEffect, sizeof (fireMode->projectileRender.generic.deathEffect));
    
    // Projectile miss event
    child = cJSON_GetObjectItem (fireModeNode, "miss");
    if ( isTripmine || isDetpack )
    {
        ReadString (child, "sticksound", fireMode->projectileMiss.explosive.stickSound, sizeof (fireMode->projectileMiss.explosive.stickSound));
    }
    else
    {
        ReadString (child, "impactfx", fireMode->projectileMiss.generic.impactEffect, sizeof (fireMode->projectileMiss.generic.impactEffect));
        ReadString (child, "shockwavefx", fireMode->projectileMiss.grenade.shockwaveEffect, sizeof (fireMode->projectileMiss.grenade.shockwaveEffect));
    }
    
    // Projectile hit event
    child = cJSON_GetObjectItem (fireModeNode, "hit");
    ReadString (child, "impactfx", fireMode->projectileHitPlayer.generic.impactEffect, sizeof (fireMode->projectileHitPlayer.generic.impactEffect));
    ReadString (child, "shockwavefx", fireMode->projectileHitPlayer.grenade.shockwaveEffect, sizeof (fireMode->projectileHitPlayer.grenade.shockwaveEffect));
    
    // Projectile deflected event
    ReadString (fireModeNode, "deflectedfx", fireMode->projectileDeflected.generic.deflectEffect, sizeof (fireMode->projectileDeflected.generic.deflectEffect));
    
    // Grenade bounce event
    child = cJSON_GetObjectItem (fireModeNode, "bouncesound");
    if ( child )
    {
        const char *bounceSounds[2];
        int numBounceSounds = cJSON_ReadStringArray (child, 2, bounceSounds);
        int i;
        
        for ( i = 0; i < numBounceSounds; i++ )
        {
            Q_strncpyz (fireMode->grenadeBounce.grenade.bounceSound[i], bounceSounds[i], sizeof (fireMode->grenadeBounce.grenade.bounceSound[i]));
        }
    }
    
    // Explosive render
    ReadString (fireModeNode, "g2model", fireMode->explosiveRender.detpack.g2Model, sizeof (fireMode->explosiveRender.detpack.g2Model));
    
    node = cJSON_GetObjectItem (fireModeNode, "g2radius");
    fireMode->explosiveRender.detpack.g2Radius = (float)cJSON_ToNumber (node);
    
    ReadString (fireModeNode, "linefx", fireMode->explosiveRender.tripmine.lineEffect, sizeof (fireMode->explosiveRender.tripmine.lineEffect));
    
    // Explosive blow event
    ReadString (fireModeNode, "explodefx", fireMode->explosiveBlow.generic.explodeEffect, sizeof (fireMode->explosiveBlow.generic.explodeEffect));
    
    // Explosive armed event
    ReadString (fireModeNode, "armsound", fireMode->explosiveArm.armSound, sizeof (fireMode->explosiveArm.armSound));

	fmLoadCounter++;
}
Exemplo n.º 20
0
static void ParseAmmoFile ( const char *fileText )
{
	int i = 0;
    cJSON *json = NULL;
    char jsonError[MAX_STRING_CHARS] = { 0 };

    json = cJSON_ParsePooled (fileText, jsonError, sizeof (jsonError));
    if ( json == NULL )
    {
        Com_Printf (S_COLOR_RED "Error: %s\n", jsonError);
    }
    else
    {
        ammo_t *ammo = &ammoTable[0];
        cJSON *jsonNode;
        cJSON *field;
        const char *string = NULL;
        
        for ( jsonNode = cJSON_GetFirstItem (json); jsonNode; jsonNode = cJSON_GetNextItem (jsonNode), ammo++, numAmmoLoaded++, i++ )
        {
            field = cJSON_GetObjectItem (jsonNode, "name");
            string = cJSON_ToString (field);
			if(string && string[0])
				Q_strncpyz (ammo->name, string, sizeof (ammo->name));

			field = cJSON_GetObjectItem (jsonNode, "ammoMax");
			ammo->ammoMax = cJSON_ToNumber(field);

			ammo->ammoIndex = i;
            
            #ifdef _CGAME
            {
                cJSON *visual = cJSON_GetObjectItem (jsonNode, "visual");
                if ( visual )
                {
                    cJSON *child = NULL;
                
                    field = cJSON_GetObjectItem (visual, "model");
                    string = cJSON_ToString (field);
                    if ( string && string[0] )
                    {
                        ammo->model = trap->R_RegisterModel (string);
                    }
                    
                    field = cJSON_GetObjectItem (visual, "fx");
                    string = cJSON_ToString (field);
                    if ( string && string[0] )
                    {
                        ammo->fx = trap->FX_RegisterEffect (string);
                    }
                    
                    field = cJSON_GetObjectItem (visual, "deathfx");
                    string = cJSON_ToString (field);
                    if ( string && string[0] )
                    {
                        ammo->deathFx = trap->FX_RegisterEffect (string);
                    }
                    
                    child = cJSON_GetObjectItem (visual, "miss");
                    if ( child )
                    {
                        field = cJSON_GetObjectItem (child, "impactfx");
                        string = cJSON_ToString (field);
                        if ( string && string[0] )
                        {
                            ammo->missFx = trap->FX_RegisterEffect (string);
                        }
                    }
                    
                    child = cJSON_GetObjectItem (visual, "hit");
                    if ( child )
                    {
                        field = cJSON_GetObjectItem (child, "impactfx");
                        string = cJSON_ToString (field);
                        if ( string && string[0] )
                        {
                            ammo->hitFx = trap->FX_RegisterEffect (string);
                        }
                    }
                }
            }
            #endif
        }
    }
    
    cJSON_Delete (json);
    
    Com_Printf ("Successfully loaded %d ammo types.\n", numAmmoLoaded);
}
static qboolean BG_ParseWeaponFile ( const char *weaponFilePath )
{
    cJSON *json = NULL;
    cJSON *jsonNode = NULL;
    char error[MAX_STRING_CHARS];
    const char *str = NULL;
    int weapon;
	int i;
    
    char weaponFileData[MAX_WEAPON_FILE_LENGTH];
    fileHandle_t f;
    int fileLen = strap_FS_FOpenFile (weaponFilePath, &f, FS_READ);
    
    weaponData_t weaponData;

	fmLoadCounter = 0;
    
    if ( !f || fileLen == -1 )
    {
        Com_Printf (S_COLOR_RED "%s: failed to read the weapon file. File is unreadable or is empty.\n", weaponFilePath);
        return qfalse;
    }
    
    if ( (fileLen + 1) >= MAX_WEAPON_FILE_LENGTH )
    {
        trap_FS_FCloseFile (f);
        Com_Printf (S_COLOR_RED "%s: file too big (%d bytes, maximum is %d).\n", weaponFilePath, fileLen, MAX_WEAPON_FILE_LENGTH - 1);
        
        return qfalse;
    }
    
    strap_FS_Read (&weaponFileData, fileLen, f);
    weaponFileData[fileLen] = '\0';
    
    strap_FS_FCloseFile (f);
    
    json = cJSON_ParsePooled (weaponFileData, error, sizeof (error));
    if ( json == NULL )
    {
        Com_Printf (S_COLOR_RED "%s: %s\n", weaponFilePath, error);
        
        return qfalse;
    }
    
    BG_InitializeWeaponData (&weaponData);
    
    ReadString (json, "classname", weaponData.classname, sizeof (weaponData.classname));
    
    jsonNode = cJSON_GetObjectItem (json, "type");
    str = cJSON_ToString (jsonNode);
    weapon = GetIDForString (WPTable, str);
    weaponData.weaponBaseIndex = weapon;
    
    jsonNode = cJSON_GetObjectItem (json, "variation");
    weapon = cJSON_ToNumber (jsonNode);
    weaponData.weaponModIndex = weapon;

    jsonNode = cJSON_GetObjectItem (json, "stats");
    BG_ParseWeaponStats (&weaponData, jsonNode);
    
	weaponData.numFiringModes = 0;
	for(i = 0; i < MAX_FIREMODES; i++)
	{
		jsonNode = cJSON_GetObjectItem (json, va("firemode%i", i));
		if(jsonNode != NULL)
		{
			BG_ParseWeaponFireMode (&weaponData.firemodes[i], jsonNode);
			weaponData.numFiringModes++;
		}
	}
	// Old stuff for when we had primary/alt attacks --eez
    /*jsonNode = cJSON_GetObjectItem (json, "primaryattack");
    BG_ParseWeaponFireMode (&weaponData.firemodes[0], jsonNode);
    
    jsonNode = cJSON_GetObjectItem (json, "secondaryattack");
    if ( jsonNode != NULL )
    {
        weaponData.hasSecondary = 1;
        BG_ParseWeaponFireMode (&weaponData.firemodes[1], jsonNode);
    }*/
    
    jsonNode = cJSON_GetObjectItem (json, "playeranims");
    BG_ParseWeaponPlayerAnimations (&weaponData, jsonNode);
    
    jsonNode = cJSON_GetObjectItem (json, "name");
    str = cJSON_ToString (jsonNode);
    Q_strncpyz (weaponData.displayName, str, sizeof (weaponData.displayName));
    
#ifdef CGAME
    // TODO: Maybe we can turn this into a loop somehow? It's just turning into a stupidly long list.

    jsonNode = cJSON_GetObjectItem (json, "weaponanims");
    // TODO
    
    jsonNode = cJSON_GetObjectItem (json, "description");
    str = cJSON_ToString (jsonNode);
    Q_strncpyz (weaponData.visuals.description, str, sizeof (weaponData.visuals.description));
    
    jsonNode = cJSON_GetObjectItem (json, "visual");
    BG_ParseVisuals (&weaponData, jsonNode);
#endif
    

    /*if ( weaponData.zoomType != ZOOM_NONE )
    {
        // If we have zoom mode, then copy over the data from the primary to the secondary
        // so it's as if we haven't changed fire modes at all! Ingenious! (And also temporary)
        weaponData.firemodes[1] = weaponData.firemodes[0];
    }*/
    
    BG_AddWeaponData (&weaponData);
    
    cJSON_Delete (json);
    
    return qtrue;
}