Beispiel #1
0
bool JSON_ParseFile(char *filename, const unordered_map<const char*, jsonParseFunc>& parsers, void* output) {
	if(!filename || !filename[0]) {
		R_Message(PRIORITY_WARNING, "JSON_ParseFile: bad filename sent\n");
		return false;
	}
	File* file = trap->OpenFile(filename, "rb");
	if(!file) {
		R_Message(PRIORITY_WARNING, "JSON_ParseFile: could not open file %s\n", filename);
		return false;
	}
	size_t numChars = trap->GetFileSize(file);
	char* s = (char*)trap->Zone_Alloc(numChars * sizeof(char), "files");
	trap->ReadPlaintext(file, numChars, s);
	trap->CloseFile(file);

	char error[1024] = {0};
	cJSON* root = cJSON_ParsePooled(s, error, sizeof(error));
	if(error[0] || !root) {
		R_Message(PRIORITY_ERROR, "ERROR: %s: %s\n", filename, error);
		trap->Zone_FastFree(s, "files");
		return false;
	}
	for(auto it = cJSON_GetFirstItem(root); it; it = cJSON_GetNextItem(it)) {
		JSON_ParseFieldSet(root, parsers, output);
	}
	trap->Zone_FastFree(s, "files");
	return true;
}
Beispiel #2
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);
}
Beispiel #3
0
/*
===================
CG_ParseLoadingScreenTips
===================
*/
void CG_ParseLoadingScreenTips(void)
{
	fileHandle_t f;
	int len = trap->FS_Open("ext_data/tables/loadingTips.json", &f, FS_READ);
	char* buffer;
	char error[1024];

	memset(error, 0, sizeof(error));

	if (len == 0 || f == NULL_HANDLE)
	{
		Com_Printf("No loading tips to display\n");
		return;
	}

	trap->TrueMalloc((void**)&buffer, len);
	if (buffer == nullptr)
	{
		return;
	}
	trap->FS_Read(buffer, len, f);
	trap->FS_Close(f);

	cJSON* json = cJSON_ParsePooled(buffer, error, 1024);
	if (json == nullptr)
	{
		Com_Printf("Couldn't parse loading tips: %s\n", error);
		trap->TrueFree((void**)&buffer);
		return;
	}

	cJSON* child = cJSON_GetObjectItem(json, "tips");
	if (child)
	{
		int arraySize = cJSON_GetArraySize(child);
		for (int i = 0; i < arraySize; i++)
		{
			cJSON* arrayItem = cJSON_GetArrayItem(child, i);
			loadingTip_t tip;

			Q_strncpyz(tip.tipText, cJSON_ToStringOpt(arrayItem, ""), sizeof(tip));
			cg_loadingTips.push_back(tip);
		}
	}
	trap->TrueFree((void**)&buffer);

	// Display this tip
	cg_displayTipNumber = rand() % (cg_loadingTips.size() - 1);
	//cg_displayTipNumber = Q_irand(0, cg_loadingTips.size() - 1);
}
Beispiel #4
0
/*
============================
JKG_LoadAmmo

Loads an individual ammo (.ammo) file.
Called on both the client and the server.
============================
*/
static qboolean JKG_LoadAmmo(const char* fileName, const char* dir) {
	int fileLen;
	fileHandle_t f;
	char fileBuffer[AMMO_FILEBUFFER];
	char error[AMMO_ERRBUFFER];

	fileLen = trap->FS_Open(va("%s%s", dir, fileName), &f, FS_READ);

	if (!f || fileLen == -1) {
		Com_Printf(S_COLOR_RED "Could not read %s\n", fileName);
		return qfalse;
	}

	if (fileLen == 0) {
		trap->FS_Close(f);
		Com_Printf(S_COLOR_RED "%s is blank\n", fileName);
		return qfalse;
	}

	if ((fileLen + 1) >= AMMO_FILEBUFFER) {
		trap->FS_Close(f);
		Com_Printf(S_COLOR_RED "%s is too big - max file size %d bytes (%.2f kb)\n", fileName, AMMO_FILEBUFFER, AMMO_FILEBUFFER / 1024.0f);
		return qfalse;
	}

	trap->FS_Read(&fileBuffer, fileLen, f);
	fileBuffer[fileLen] = '\0';
	trap->FS_Close(f);

	cJSON* json = cJSON_ParsePooled(fileBuffer, error, AMMO_ERRBUFFER);
	if (!json) {
		Com_Printf(S_COLOR_RED "%s: %s\n", fileName, error);
		return qfalse;
	}

	// Read each node in the json file from top level as an ammo_t
	cJSON* child;
	for (child = cJSON_GetFirstItem(json); child; child = cJSON_GetNextItem(child)) {
		if (numAmmoLoaded >= MAX_AMMO_TYPES) {
			Com_Printf("MAX_AMMO_TYPES exceeded\n");
			break;
		}
		if (JKG_ParseSingleAmmo(child)) {
			numAmmoLoaded++;
		}
	}

	cJSON_Delete(json);
	return qtrue;
}
Beispiel #5
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;
}
static int GLua_JSON_Register( lua_State *L )
{
	// Check and make sure the file exists, for starters
	fileHandle_t f;
	const char *fName = luaL_checkstring(L,1);
	int len = trap->FS_Open( fName, &f, FS_READ );

	if( len < 0 || !f )
	{
		lua_pushnil(L);
		return 1;
	}

	// Read it now.
	char *buff = (char *)malloc(len + 1);
	
	trap->FS_Read( buff, len, f );
	buff[len] = '\0';
	trap->FS_Close( f );

	fJSON.fileBinding = buff;

	// fileBinding takes a copy of the buffer. Let's just free the original right now.
	free( buff );

	// Okay, now handle the deal with the first node.
	char error[MAX_STRING_CHARS];
	cJSON *json = cJSON_ParsePooled( fJSON.fileBinding.c_str(), error, sizeof( error ) );

	if( json == NULL )
	{
		trap->Print(va( S_COLOR_RED "Failed to get JSON node for Lua (file: %s): %s\n", fName, error));
		lua_pushnil(L);
		return 1;
	}

	// Pass the result to Lua
	FJSON_PassLastElement( L, json );
	
	return 1;
}
Beispiel #7
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;
}
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;
}
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;
}