当前位置: 首页>>代码示例>>C++>>正文


C++ XmlNodeRef::getAttr方法代码示例

本文整理汇总了C++中XmlNodeRef::getAttr方法的典型用法代码示例。如果您正苦于以下问题:C++ XmlNodeRef::getAttr方法的具体用法?C++ XmlNodeRef::getAttr怎么用?C++ XmlNodeRef::getAttr使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在XmlNodeRef的用法示例。


在下文中一共展示了XmlNodeRef::getAttr方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: LoadGeometry

void SAmmoParams::LoadGeometry(const XmlNodeRef& ammoParamsNode)
{
	CGameXmlParamReader reader(ammoParamsNode);

	XmlNodeRef geometryNode = reader.FindFilteredChild("geometry");
	if (!geometryNode)
		return;

	CGameXmlParamReader geometryReader(geometryNode);

	XmlNodeRef firstpersonNode = geometryReader.FindFilteredChild("firstperson");
	if (firstpersonNode)
	{
		const char *modelName = firstpersonNode->getAttr("name");

		if (modelName && modelName[0])
		{
			Ang3 angles(0,0,0);
			Vec3 position(0,0,0);
			float scale=1.0f;
			firstpersonNode->getAttr("position", position);
			firstpersonNode->getAttr("angles", angles);
			firstpersonNode->getAttr("scale", scale);

			fpLocalTM = Matrix34(Matrix33::CreateRotationXYZ(DEG2RAD(angles)));
			fpLocalTM.ScaleColumn(Vec3(scale, scale, scale));
			fpLocalTM.SetTranslation(position);

			fpGeometryName = modelName;
		}
	}
}
开发者ID:danielasun,项目名称:dbho-GameSDK,代码行数:32,代码来源:AmmoParams.cpp

示例2: SerializeWorldTM

void CCheckpointSystem::SerializeWorldTM(IEntity *pEntity, XmlNodeRef data, bool writing)
{
	if(!pEntity || !data)
		return;

	if(writing)
	{
		//write all TM columns to checkpoint node
		const Matrix34 &tm = pEntity->GetWorldTM();
		data->setAttr("TMcol0", tm.GetColumn0());
		data->setAttr("TMcol1", tm.GetColumn1());
		data->setAttr("TMcol2", tm.GetColumn2());
		data->setAttr("TMcol3", tm.GetColumn3());
	}
	else
	{
		//read and set TM columns from node
		Matrix34 tm;
		Vec3 temp = Vec3(0,0,0);
		bool foundData = data->getAttr("TMcol0", temp);
		tm.SetColumn(0, temp);
		foundData &= data->getAttr("TMcol1", temp);
		tm.SetColumn(1, temp);
		foundData &= data->getAttr("TMcol2", temp);
		tm.SetColumn(2, temp);
		foundData &= data->getAttr("TMcol3", temp);
		tm.SetColumn(3, temp);
		CRY_ASSERT(foundData);
		//set matrix to entity
		pEntity->SetWorldTM(tm);
	}
}
开发者ID:NightOwlsEntertainment,项目名称:PetBox_A_Journey_to_Conquer_Elementary_Algebra,代码行数:32,代码来源:CheckPointSystem.cpp

示例3: PrecacheLevel

void CPlayerPlugin_InteractiveEntityMonitor::PrecacheLevel()
{
	XmlNodeRef rootNode = gEnv->pSystem->LoadXmlFromFile(INTERACTIVE_ENTITY__MONITOR_DATA_FILE);
	if(rootNode)
	{
		const char* pLevelName = gEnv->pGame->GetIGameFramework()->GetLevelName();
		if(!pLevelName)
		{
			pLevelName = "default";
		}
		else if( const char * pTrim = strstr(pLevelName, "/") )
		{
			pLevelName = pTrim+1;
		}
		CGameXmlParamReader nodeDataReader(rootNode);
		XmlNodeRef levelNode = nodeDataReader.FindFilteredChild(pLevelName);
		if(!levelNode)
		{
			levelNode = nodeDataReader.FindFilteredChild("default");
		}
		if(levelNode)
		{
			ColorB color;
			if(levelNode->getAttr("color", color))
			{
				m_silhouetteInteractColor = ColorF(color.r, color.g, color.b, color.a) / 255.f;
			}
			if(levelNode->getAttr("shoot_color", color))
			{
				m_silhouetteShootColor = ColorF(color.r, color.g, color.b, color.a) / 255.f;
			}
		}
	}
}
开发者ID:Xydrel,项目名称:Infected,代码行数:34,代码来源:PlayerPlugin_InteractiveEntityMonitor.cpp

示例4: LoadExternalEntities

void CCheckpointSystem::LoadExternalEntities(XmlNodeRef parentNode)
{
	XmlNodeRef data = parentNode->findChild(EXTERNAL_ENTITIES_SECTION);
	if(!data)
		return;

	int numEntities = data->getChildCount();
	for(int i = 0; i < numEntities; ++i)
	{
		XmlNodeRef nextEntity = data->getChild(i);
		if(nextEntity)
		{
			EntityId id = 0;
			nextEntity->getAttr("id", id);
			const char *name = nextEntity->getAttr("name");
			
			//fix entityId if broken
			if(RepairEntityId(id, name))
			{
				IEntity *pEntity = gEnv->pEntitySystem->GetEntity(id);
				//setup entity
				bool bActive = false;
				bool bHidden = false;
				nextEntity->getAttr("active", bActive);
				nextEntity->getAttr("hidden", bHidden);
				pEntity->Activate(bActive);
				pEntity->Hide(bHidden);
				//load matrix
				SerializeWorldTM(pEntity, nextEntity, false);
			}
		}
	}
}
开发者ID:NightOwlsEntertainment,项目名称:PetBox_A_Journey_to_Conquer_Elementary_Algebra,代码行数:33,代码来源:CheckPointSystem.cpp

示例5: Reset

void SRecoilHints::Reset(const XmlNodeRef& paramsNode, bool defaultInit /* = true */)
{
	if (defaultInit)
	{
		hints.resize(0);
	}

	CGameXmlParamReader reader(paramsNode);

	XmlNodeRef hintsNode = reader.FindFilteredChild("hints");
	if (hintsNode && (hintsNode->getChildCount() > 0))
	{
		//Replacing hints, delete previous ones
		hints.resize(0);

		CGameXmlParamReader hintsReader(hintsNode);

		Vec2 hintPoint;
		const int hintCount = hintsReader.GetUnfilteredChildCount();
		hints.reserve(hintCount);

		for (int i = 0; i < hintCount; i++)
		{
			XmlNodeRef hintNode = hintsReader.GetFilteredChildAt(i);
			if (hintNode && hintNode->getAttr("x", hintPoint.x) && hintNode->getAttr("y", hintPoint.y))
			{
				hints.push_back(hintPoint);
			}
		}
	}

}
开发者ID:Kufusonic,项目名称:Work-in-Progress-Sonic-Fangame,代码行数:32,代码来源:Recoil.cpp

示例6: atoi

//-------------------------------------------------------------------------
/* static */ void CStatsEntityIdRegistry::ReadStringIds( XmlNodeRef xmlNode, uint16 &defaultId, TStringIdVec &vec )
{
	const char *pDefault;
	if (xmlNode->getAttr("default", &pDefault))
	{
		defaultId = atoi(pDefault);
	}

	const int numEntities = xmlNode->getChildCount();
	vec.reserve(numEntities);
	for (int i = 0; i < numEntities; ++ i)
	{
		XmlNodeRef xmlEntity = xmlNode->getChild(i);

		const char *pName;
		const char *pValue;
		if (xmlEntity->getAttr("name", &pName) && xmlEntity->getAttr("value", &pValue))
		{
			SStringId entity;
			entity.m_name = pName;
			entity.m_id = atoi(pValue);
			vec.push_back(entity);
		}
	}
}
开发者ID:Kufusonic,项目名称:Work-in-Progress-Sonic-Fangame,代码行数:26,代码来源:StatsEntityIdRegistry.cpp

示例7: Init

//------------------------------------------------------------------------
void CGameRulesHoldObjectiveBase::Init( XmlNodeRef xml )
{
	const int numChildren = xml->getChildCount();
	for (int childIdx = 0; childIdx < numChildren; ++ childIdx)
	{
		XmlNodeRef xmlChild = xml->getChild(childIdx);
		if (!stricmp(xmlChild->getTag(), "SpawnParams"))
		{
			const char *pType = 0;
			if (xmlChild->getAttr("type", &pType))
			{
				if (!stricmp(pType, "avoid"))
				{
					m_spawnPOIType = eSPT_Avoid;
				}
				else
				{
					CryLog("CGameRulesHoldObjectiveBase::Init: ERROR: Unknown spawn point of interest type ('%s')", pType);
				}
				xmlChild->getAttr("distance", m_spawnPOIDistance);
			}
		}
		else if (!stricmp(xmlChild->getTag(), "EffectData"))
		{
			InitEffectData(xmlChild);
		}
	}

	for (int i = 0; i < HOLD_OBJECTIVE_MAX_ENTITIES; ++ i)
	{
		m_entities[i].Reset();
	}
}
开发者ID:aronarts,项目名称:FireNET,代码行数:34,代码来源:GameRulesHoldObjectiveBase.cpp

示例8: LoadAntiCheatVars

void CAntiCheatManager::LoadAntiCheatVars(XmlNodeRef child)
{
	int numVars = child->getChildCount();
	for (int i=0; i<numVars; ++i)
	{
		XmlNodeRef varsChild = child->getChild(i);
		if (varsChild->isTag("Var"))
		{
			const char* sVarName = varsChild->getAttr("name");
			TAntiCheatVarIdx antiCheatVarIdx = FindAntiCheatVarIdx_Float(sVarName);
			if (antiCheatVarIdx != eAV_Invalid_Float)
			{
				varsChild->getAttr("value", m_cheatVarsFloat[antiCheatVarIdx]);
			}
			else
			{
				antiCheatVarIdx = FindAntiCheatVarIdx_Int(sVarName);
				if (antiCheatVarIdx != eAV_Invalid_Int)
				{
					varsChild->getAttr("value", m_cheatVarsInt[antiCheatVarIdx]);
				}
				else
				{
					CryLog("Unrecognised anti cheat var '%s'", sVarName);
				}
			}
		}
		else
		{
			CryLog("Unrecognised child node '%s'", varsChild->getTag());
		}
	}
}
开发者ID:aronarts,项目名称:FireNET,代码行数:33,代码来源:AntiCheatManager.cpp

示例9: LoadAttributes

//------------------------------------------------------------------------
bool CPlayerProfile::LoadAttributes(const XmlNodeRef& root, int requiredVersion)
{
	int version = 0;
	const bool bHaveVersion = root->getAttr(VERSION_TAG, version);
	
	if (requiredVersion > 0)
	{
		if (bHaveVersion && version < requiredVersion)
		{
			GameWarning("CPlayerProfile::LoadAttributes: Attributes of profile '%s' have different version (%d != %d). Updated.", GetName(), version, requiredVersion);
			return false;
		}
		else if (!bHaveVersion)
		{
			GameWarning("CPlayerProfile::LoadAttributes: Attributes of legacy profile '%s' has no version (req=%d). Loading anyway.", GetName(), requiredVersion);
		}
		m_attributesVersion = requiredVersion;
	}
	else
		// for default profile we set the version we found in the rootNode
		m_attributesVersion = version;

	int nChilds = root->getChildCount();
	for (int i=0; i<nChilds; ++i)
	{
		XmlNodeRef child = root->getChild(i);
		if (child && strcmp(child->getTag(), "Attr") == 0)
		{
			const char* name = child->getAttr("name");
			const char* value = child->getAttr("value");
			const char* platform = child->getAttr("platform");

			bool platformValid = true;
			if(platform != NULL && platform[0])
			{
#if defined(DURANGO)
				platformValid = (strstr(platform, "xbox")!=0);
#elif defined(ORBIS)
				platformValid = (strstr(platform, "ps4")!=0);
#else
				platformValid = (strstr(platform, "pc")!=0);
#endif
			}

			if (name && value && platformValid)
			{
				m_attributeMap[name] = TFlowInputData(string(value));
			}
		}
	}

	if(m_pManager->HasEnabledOnlineAttributes() && m_pManager->CanProcessOnlineAttributes() && !IsDefault())
	{
		m_pManager->LoadOnlineAttributes(this);
	}

	return true;
}
开发者ID:aronarts,项目名称:FireNET,代码行数:59,代码来源:PlayerProfile.cpp

示例10: Init

//------------------------------------------------------------------------
void CGameRulesCommonDamageHandling::Init( XmlNodeRef xml )
{
	m_pGameRules = g_pGame->GetGameRules();

	// Reserved hit types - in sync with RESERVED_HIT_TYPES
	/*00*/ //m_pGameRules->RegisterHitType("invalid",							CGameRules::EHitTypeFlag::None);
	/*01*/ m_pGameRules->RegisterHitType("melee",								CGameRules::EHitTypeFlag::IsMeleeAttack | CGameRules::EHitTypeFlag::IgnoreHeadshots);
	/*02*/ m_pGameRules->RegisterHitType("collision",						CGameRules::EHitTypeFlag::Server);
	/*03*/ m_pGameRules->RegisterHitType("frag",								CGameRules::EHitTypeFlag::Server | CGameRules::EHitTypeFlag::AllowPostDeathDamage);
	/*04*/ m_pGameRules->RegisterHitType("explosion",						CGameRules::EHitTypeFlag::Server | CGameRules::EHitTypeFlag::AllowPostDeathDamage);
	/*05*/ m_pGameRules->RegisterHitType("stealthKill",					CGameRules::EHitTypeFlag::Server | CGameRules::EHitTypeFlag::AllowPostDeathDamage);
	/*06*/ m_pGameRules->RegisterHitType("silentMelee",					CGameRules::EHitTypeFlag::IsMeleeAttack | CGameRules::EHitTypeFlag::SinglePlayerOnly | CGameRules::EHitTypeFlag::IgnoreHeadshots);
	/*07*/ m_pGameRules->RegisterHitType("punish",							CGameRules::EHitTypeFlag::ClientSelfHarm);
	/*08*/ m_pGameRules->RegisterHitType("punishFall",					CGameRules::EHitTypeFlag::ClientSelfHarm);
	/*10*/ m_pGameRules->RegisterHitType("fall",								CGameRules::EHitTypeFlag::ClientSelfHarm);
	/*11*/ m_pGameRules->RegisterHitType("normal",							CGameRules::EHitTypeFlag::Server);	//Used for killing players so they can switch teams
	/*12*/ m_pGameRules->RegisterHitType("fire",								CGameRules::EHitTypeFlag::Server); // used by PressurizedObject.lua
	/*14*/ m_pGameRules->RegisterHitType("heavyBullet",					CGameRules::EHitTypeFlag::ValidationRequired);
	/*18*/ m_pGameRules->RegisterHitType("environmentalThrow",	CGameRules::EHitTypeFlag::CustomValidationRequired | CGameRules::EHitTypeFlag::AllowPostDeathDamage | CGameRules::EHitTypeFlag::IgnoreHeadshots);
	/*19*/ m_pGameRules->RegisterHitType("meleeLeft",						CGameRules::EHitTypeFlag::IsMeleeAttack | CGameRules::EHitTypeFlag::SinglePlayerOnly | CGameRules::EHitTypeFlag::IgnoreHeadshots);
	/*20*/ m_pGameRules->RegisterHitType("meleeRight",					CGameRules::EHitTypeFlag::IsMeleeAttack | CGameRules::EHitTypeFlag::SinglePlayerOnly | CGameRules::EHitTypeFlag::IgnoreHeadshots);
	/*21*/ m_pGameRules->RegisterHitType("meleeKick",						CGameRules::EHitTypeFlag::IsMeleeAttack | CGameRules::EHitTypeFlag::SinglePlayerOnly | CGameRules::EHitTypeFlag::IgnoreHeadshots);
	/*22*/ m_pGameRules->RegisterHitType("meleeUppercut",				CGameRules::EHitTypeFlag::IsMeleeAttack | CGameRules::EHitTypeFlag::SinglePlayerOnly | CGameRules::EHitTypeFlag::IgnoreHeadshots);
	/*23*/ m_pGameRules->RegisterHitType("vehicleDestruction",	CGameRules::EHitTypeFlag::Server | CGameRules::EHitTypeFlag::AllowPostDeathDamage);
	/*27*/ m_pGameRules->RegisterHitType("eventDamage",					CGameRules::EHitTypeFlag::ClientSelfHarm);
	/*29*/ m_pGameRules->RegisterHitType("environmentalMelee",	CGameRules::EHitTypeFlag::IsMeleeAttack | CGameRules::EHitTypeFlag::CustomValidationRequired | CGameRules::EHitTypeFlag::AllowPostDeathDamage | CGameRules::EHitTypeFlag::IgnoreHeadshots);
	
	CRY_ASSERT(m_pGameRules->GetHitTypesCount() == CGameRules::EHitType::Unreserved);

	// Read any non-native hit_types from the HitTypes.xml file!
	XmlNodeRef xmlNode = gEnv->pSystem->LoadXmlFromFile( "Scripts/Entities/Items/HitTypes.xml" );

	if( xmlNode )
	{
		const int numEntries = xmlNode->getChildCount();
		for (int i = 0; i < numEntries; ++i)
		{
			XmlNodeRef hitTypeXML = xmlNode->getChild(i);

			if (strcmp(hitTypeXML->getTag(), "hit_type") != 0)
				continue;

			if( const char* pHitType = hitTypeXML->getAttr("name") )
			{
				TBitfield flags = CGameRules::EHitTypeFlag::None;

				if( const char * pHitTypeFlags = hitTypeXML->getAttr("flags"))
				{
					flags = AutoEnum_GetBitfieldFromString(pHitTypeFlags, CGameRules::s_hitTypeFlags, CGameRules::EHitTypeFlag::HIT_TYPES_FLAGS_numBits);
				}

				m_pGameRules->RegisterHitType( pHitType, flags );
			}
		}
	}
	m_scriptHitInfo.Create(gEnv->pScriptSystem);
}
开发者ID:Xydrel,项目名称:Infected,代码行数:58,代码来源:GameRulesCommonDamageHandling.cpp

示例11: PreLoadModule

bool CFlowGraphModule::PreLoadModule(const char* fileName)
{
	m_fileName = fileName;

	XmlNodeRef moduleRef = gEnv->pSystem->LoadXmlFromFile(fileName);

	if (!moduleRef)
	{
		CryWarning(VALIDATOR_MODULE_FLOWGRAPH, VALIDATOR_WARNING, "Unable to preload Flowgraph Module: %s", PathUtil::GetFileName(fileName).c_str());
		return false;
	}

	assert(!stricmp(moduleRef->getTag(), "Graph"));

	bool module = false;
	moduleRef->getAttr("isModule", module);
	assert(module);

	XmlString tempName;
	if (moduleRef->getAttr("moduleName", tempName))
		m_name = tempName;

	bool bResult = (m_pRootGraph != NULL);
	assert(m_pRootGraph == NULL);

	// first handle module ports
	XmlNodeRef modulePorts = moduleRef->findChild("ModuleInputsOutputs");
	RemoveModulePorts();
	if (modulePorts)
	{
		int nPorts = modulePorts->getChildCount();
		for (int i = 0; i < nPorts; ++i)
		{
			XmlString portName;
			int       portType;
			bool      isInput;

			XmlNodeRef port = modulePorts->getChild(i);
			port->getAttr("Name", portName);
			port->getAttr("Type", portType);
			port->getAttr("Input", isInput);

			IFlowGraphModule::SModulePortConfig portConfig;
			portConfig.name  = portName.c_str();
			portConfig.type  = (EFlowDataTypes)portType;
			portConfig.input = isInput;

			AddModulePort(portConfig);
		}
	}

	// and create nodes for this module (needs to be done before actual graph load, so that the
	//	nodes can be created there)
	RegisterNodes();

	return bResult;
}
开发者ID:joewan,项目名称:pycmake,代码行数:57,代码来源:Module.cpp

示例12: AddOption

void CProfileOptions::AddOption(const XmlNodeRef node)
{
	const char *platform = node->getAttr("platform");
	if(platform != NULL && platform[0])
	{
		bool result = (strstr(platform, "pc")==0);

		if (result)
			return;
	}

	// Ignore gameOnly attributes in the editor
	bool gameOnly = false;
	node->getAttr("gameOnly",gameOnly);
	if(gameOnly && gEnv->IsEditor())
		return;

	const char* name = node->getAttr("name");
	const char* val = node->getAttr("value");
	const char* cvar = node->getAttr("cvar");

	bool preview = false;
	node->getAttr("preview", preview);

	bool confirmation = false;
	node->getAttr("confirmation", confirmation);

	bool restart = false;
	node->getAttr("requiresRestart", restart);

	bool writeToConfig = false;
	node->getAttr("writeToConfig", writeToConfig);

	AddOption(name, val, cvar, preview, confirmation, restart, restart||writeToConfig); //options that require restart also need to be written to the config
}
开发者ID:aronarts,项目名称:FireNET,代码行数:35,代码来源:ProfileOptions.cpp

示例13: Init

void CGameRulesSpawningBase::Init(XmlNodeRef xml)
{
	m_pGameRules = g_pGame->GetGameRules();

	int ival;
	if (xml->getAttr("team1AlwaysUsesInitialSpawns", ival))
	{
		m_bTeamAlwaysUsesInitialSpawns[0] = (ival != 0);
	}
	if (xml->getAttr("team2AlwaysUsesInitialSpawns", ival))
	{
		m_bTeamAlwaysUsesInitialSpawns[1] = (ival != 0);
	}
}
开发者ID:aronarts,项目名称:FireNET,代码行数:14,代码来源:GameRulesSpawningBase.cpp

示例14: ReadXMLNode

void CMFXForceFeedbackEffect::ReadXMLNode(XmlNodeRef &node)
{
	IMFXEffect::ReadXMLNode(node);

	m_forceFeedbackParams.forceFeedbackEventName = node->getAttr("name");

	float minFallOffDistance = 0.0f;
	node->getAttr("minFallOffDistance", minFallOffDistance);
	float maxFallOffDistance = 5.0f;
	node->getAttr("maxFallOffDistance", maxFallOffDistance);

	m_forceFeedbackParams.intensityFallOffMinDistanceSqr = minFallOffDistance * minFallOffDistance;
	m_forceFeedbackParams.intensityFallOffMaxDistanceSqr = maxFallOffDistance * maxFallOffDistance;
}
开发者ID:aronarts,项目名称:FireNET,代码行数:14,代码来源:MFXForceFeedbackFX.cpp

示例15: PopulateDLCContents

void CDLCManager::PopulateDLCContents(const XmlNodeRef &rootNode, int dlcId, const char* name )
{
	mbstowcs( m_dlcContents[dlcId].name, name, MAX_DLC_NAME );

	XmlNodeRef levelsNode = rootNode->findChild("levels");
	if (levelsNode)
	{
		XmlString levelName;
		int numLevels = levelsNode->getChildCount();

		CryLog( "Found %d levels in the DLC", numLevels );
		
		m_dlcContents[dlcId].levels.reserve(numLevels);
		for (int i=0; i<numLevels; ++i)
		{
			XmlNodeRef levelNode = levelsNode->getChild(i);
			if (levelNode->getAttr("name", levelName))
			{
				CryLog( "Found level %s and added to the DLC manager", levelName.c_str() );
				m_dlcContents[dlcId].levels.push_back(levelName);
			}
		}
	}

	XmlNodeRef bonusNode = rootNode->findChild("bonus");
	if( bonusNode )
	{
		CryLog( "DLC pak includes a pre-sale bonus" );
		uint32 bonusID = 0;
		bonusNode->getAttr("id", bonusID );
		m_dlcContents[dlcId].bonusID = bonusID;
	}

	XmlNodeRef uniqueIdNode = rootNode->findChild("uniqueId");
	if( uniqueIdNode )
	{
		uint32 uniqueID = 0;
		uniqueIdNode->getAttr("id", uniqueID );
		m_dlcContents[dlcId].uniqueID = uniqueID;
	}

	XmlNodeRef uniqueTagNode = rootNode->findChild("uniqueTag");
	if( uniqueTagNode )
	{
		const char* str =	uniqueTagNode->getAttr( "tag" );
		m_dlcContents[dlcId].uniqueTag.Format( str );
	}
}
开发者ID:aronarts,项目名称:FireNET,代码行数:48,代码来源:DLCManager.cpp


注:本文中的XmlNodeRef::getAttr方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。