int CSkins::SkinScan(const char *pName, int IsDir, int DirType, void *pUser) { int l = str_length(pName); if(l < 5 || IsDir || str_comp(pName+l-5, ".json") != 0) return 0; CSkins *pSelf = (CSkins *)pUser; // read file data into buffer char aBuf[512]; str_format(aBuf, sizeof(aBuf), "skins/%s", pName); IOHANDLE File = pSelf->Storage()->OpenFile(aBuf, IOFLAG_READ, IStorage::TYPE_ALL); if(!File) return 0; int FileSize = (int)io_length(File); char *pFileData = (char *)mem_alloc(FileSize, 1); io_read(File, pFileData, FileSize); io_close(File); // init CSkin Skin = pSelf->m_DummySkin; str_copy(Skin.m_aName, pName, min((int)sizeof(Skin.m_aName),l-4)); if(pSelf->Find(Skin.m_aName, true) != -1) return 0; bool SpecialSkin = pName[0] == 'x' && pName[1] == '_'; // parse json data json_settings JsonSettings; mem_zero(&JsonSettings, sizeof(JsonSettings)); char aError[256]; json_value *pJsonData = json_parse_ex(&JsonSettings, pFileData, FileSize, aError); mem_free(pFileData); if(pJsonData == 0) { pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, aBuf, aError); return 0; } // extract data const json_value &rStart = (*pJsonData)["skin"]; if(rStart.type == json_object) { for(int PartIndex = 0; PartIndex < NUM_SKINPARTS; ++PartIndex) { const json_value &rPart = rStart[(const char *)ms_apSkinPartNames[PartIndex]]; if(rPart.type != json_object) continue; // filename const json_value &rFilename = rPart["filename"]; if(rFilename.type == json_string) { int SkinPart = pSelf->FindSkinPart(PartIndex, (const char *)rFilename, SpecialSkin); if(SkinPart > -1) Skin.m_apParts[PartIndex] = pSelf->GetSkinPart(PartIndex, SkinPart); } // use custom colors bool UseCustomColors = false; const json_value &rColour = rPart["custom_colors"]; if(rColour.type == json_string) { UseCustomColors = str_comp((const char *)rColour, "true") == 0; } Skin.m_aUseCustomColors[PartIndex] = UseCustomColors; // color components if(!UseCustomColors) continue; for(int i = 0; i < NUM_COLOR_COMPONENTS; i++) { if(PartIndex != SKINPART_MARKING && i == 3) continue; const json_value &rComponent = rPart[(const char *)ms_apColorComponents[i]]; if(rComponent.type == json_integer) { switch(i) { case 0: Skin.m_aPartColors[PartIndex] = (Skin.m_aPartColors[PartIndex]&0xFF00FFFF) | (rComponent.u.integer << 16); break; case 1: Skin.m_aPartColors[PartIndex] = (Skin.m_aPartColors[PartIndex]&0xFFFF00FF) | (rComponent.u.integer << 8); break; case 2: Skin.m_aPartColors[PartIndex] = (Skin.m_aPartColors[PartIndex]&0xFFFFFF00) | rComponent.u.integer; break; case 3: Skin.m_aPartColors[PartIndex] = (Skin.m_aPartColors[PartIndex]&0x00FFFFFF) | (rComponent.u.integer << 24); break; } } } } } // clean up json_value_free(pJsonData); // set skin data Skin.m_Flags = SpecialSkin ? SKINFLAG_SPECIAL : 0; if(DirType != IStorage::TYPE_SAVE) Skin.m_Flags |= SKINFLAG_STANDARD; if(g_Config.m_Debug) { str_format(aBuf, sizeof(aBuf), "load skin %s", Skin.m_aName); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "skins", aBuf); } pSelf->m_aSkins.add(Skin); return 0; }