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


C++ FS_CreatePath函数代码示例

本文整理汇总了C++中FS_CreatePath函数的典型用法代码示例。如果您正苦于以下问题:C++ FS_CreatePath函数的具体用法?C++ FS_CreatePath怎么用?C++ FS_CreatePath使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。


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

示例1: FS_FOpenDemoFileWrite

/*
===========
FS_FOpenDemoFileWrite

===========
*/
qboolean FS_FOpenDemoFileWrite( const char *filename, fileHandleData_t *fh ) {
	
	char ospath[MAX_OSPATH];

	if ( !FS_Initialized() ) {
		Com_Error( ERR_FATAL, "Filesystem call made without initialization" );
	}

	FS_BuildOSPathForThread( fs_homepath->string, filename, "", ospath, 0 );
	ospath[strlen(ospath)-1] = '\0';

	fh->zipFile = qfalse;

	if ( fs_debug->boolean ) {
		Com_Printf( "FS_SV_FOpenDemoFileWrite: %s\n", ospath );
	}

	if( FS_CreatePath( ospath ) ) {
		return qfalse;
	}

	fh->handleFiles.file.o = fopen( ospath, "wb" );

	Q_strncpyz( fh->name, filename, sizeof( fh->name ) );

	fh->handleSync = qfalse;
	if (!fh->handleFiles.file.o) {
		return qfalse;
	}
	fh->writebuffer = Z_Malloc(FS_DEMOWRITEBUF_SIZE);
	fh->bufferSize = FS_DEMOWRITEBUF_SIZE;
	return qtrue;
}
开发者ID:BraXi,项目名称:CoD4X18-Server,代码行数:39,代码来源:sv_demo.c

示例2: Log_AutoLogging_SaveMatch

void Log_AutoLogging_SaveMatch(void) {
	int error, num;
	FILE *f;
	char *dir, *tempname, savedname[2 * MAX_OSPATH], *fullsavedname, *exts[] = {"log", NULL};

	if (!temp_log_ready)
		return;

	temp_log_ready = false;

	dir = Log_LogDirectory();
	tempname = va("%s/%s", MT_TempDirectory(), TEMP_LOG_NAME);

	fullsavedname = va("%s/%s", dir, auto_matchname);
	if ((num = Util_Extend_Filename(fullsavedname, exts)) == -1) {
		Com_Printf("Error: no available filenames\n");
		return;
	}
	snprintf (savedname, sizeof(savedname), "%s_%03i.log", auto_matchname, num);

	fullsavedname = va("%s/%s", dir, savedname);

	
	if (!(f = fopen(tempname, "rb")))
		return;
	fclose(f);

	if ((error = rename(tempname, fullsavedname))) {
		FS_CreatePath(fullsavedname);
		error = rename(tempname, fullsavedname);
	}

	if (!error)
		Com_Printf("Match console log saved to %s\n", savedname);
}
开发者ID:jogi1,项目名称:camquake,代码行数:35,代码来源:logging.c

示例3: FS_FOpenFileAppend

/*
 * Returns file size or -1 on error.
 */
int
FS_FOpenFileAppend(fsHandle_t *handle)
{
	char path[MAX_OSPATH];

	FS_CreatePath(handle->name);

	Com_sprintf(path, sizeof(path), "%s/%s", fs_gamedir, handle->name);

	handle->file = fopen(path, "ab");

	if (handle->file)
	{
		if (fs_debug->value)
		{
			Com_Printf("FS_FOpenFileAppend: '%s'.\n", path);
		}

		return FS_FileLength(handle->file);
	}

	if (fs_debug->value)
	{
		Com_Printf("FS_FOpenFileAppend: couldn't open '%s'.\n", path);
	}

	return -1;
}
开发者ID:Jenco420,项目名称:yquake2,代码行数:31,代码来源:filesystem.c

示例4: FS_AddHomeAsGameDirectory

/*
 * Use ~/.quake2/dir as fs_gamedir.
 */
void
FS_AddHomeAsGameDirectory(char *dir)
{
	char *home;
	char gdir[MAX_OSPATH];
	size_t len;

	home = Sys_GetHomeDir();

	if (home == NULL)
	{
		return;
	}

    len = snprintf(gdir, sizeof(gdir), "%s%s/", home, dir);
	FS_CreatePath(gdir);

	if ((len > 0) && (len < sizeof(gdir)) && (gdir[len - 1] == '/'))
	{
		gdir[len - 1] = 0;
	}

	Q_strlcpy(fs_gamedir, gdir, sizeof(fs_gamedir));

	FS_AddGameDirectory(gdir);
}
开发者ID:Jenco420,项目名称:yquake2,代码行数:29,代码来源:filesystem.c

示例5: FS_FOpenFileAppend

/*
===========
FS_FOpenFileAppend

===========
*/
fileHandle_t FS_FOpenFileAppend( const char *filename ) {
	char			*ospath;
	fileHandle_t	f;

	if ( !fs_searchpaths ) {
		Com_Error( ERR_FATAL, "Filesystem call made without initialization\n" );
	}

	f = FS_HandleForFile();
	fsh[f].zipFile = qfalse;

	Q_strncpyz( fsh[f].name, filename, sizeof( fsh[f].name ) );

	// don't let sound stutter
	S_ClearSoundBuffer();

#ifdef _XBOX
	ospath = FS_BuildOSPath( filename );
#else
	ospath = FS_BuildOSPath( fs_basepath->string, fs_gamedir, filename );
#endif

	if ( fs_debug->integer ) {
		Com_Printf( "FS_FOpenFileAppend: %s\n", ospath );
	}

	FS_CreatePath( ospath );
	fsh[f].handleFiles.file.o = fopen( ospath, "ab" );
	fsh[f].handleSync = qfalse;
	if (!fsh[f].handleFiles.file.o) {
		f = 0;
	}
	return f;
}
开发者ID:AlexCSilva,项目名称:jediacademy,代码行数:40,代码来源:files_common.cpp

示例6: FS_FOpenFileWrite

/*
 * Always returns 0 or -1 on error.
 */
int
FS_FOpenFileWrite(fsHandle_t *handle)
{
	char path[MAX_OSPATH];

	FS_CreatePath(handle->name);

	Com_sprintf(path, sizeof(path), "%s/%s", fs_gamedir, handle->name);

	if ((handle->file = fopen(path, "wb")) != NULL)
	{
		if (fs_debug->value)
		{
			Com_Printf("FS_FOpenFileWrite: '%s'.\n", path);
		}

		return 0;
	}

	if (fs_debug->value)
	{
		Com_Printf("FS_FOpenFileWrite: couldn't open '%s'.\n", path);
	}

	return -1;
}
开发者ID:Jenco420,项目名称:yquake2,代码行数:29,代码来源:filesystem.c

示例7: Host_LockSession

void Host_LockSession(void)
{
	if(locksession_run)
		return;
	locksession_run = true;
	if(locksession.integer != 0 && !COM_CheckParm("-readonly"))
	{
		char vabuf[1024];
		char *p = va(vabuf, sizeof(vabuf), "%slock%s", *fs_userdir ? fs_userdir : fs_basedir, sessionid.string);
		FS_CreatePath(p);
		locksession_fh = FS_SysOpen(p, "wl", false);
		// TODO maybe write the pid into the lockfile, while we are at it? may help server management tools
		if(!locksession_fh)
		{
			if(locksession.integer == 2)
			{
				Con_Printf("WARNING: session lock %s could not be acquired. Please run with -sessionid and an unique session name. Continuing anyway.\n", p);
			}
			else
			{
				Sys_Error("session lock %s could not be acquired. Please run with -sessionid and an unique session name.\n", p);
			}
		}
	}
}
开发者ID:divVerent,项目名称:darkplaces-travis,代码行数:25,代码来源:host.c

示例8: FS_FOpenDemoFileWrite

/*
===========
FS_FOpenDemoFileWrite

===========
*/
fileHandle_t FS_FOpenDemoFileWrite( const char *filename ) {
	char *ospath;
	fileHandle_t	f;

	if ( !fs_searchpaths ) {
		Com_Error( ERR_FATAL, "Filesystem call made without initialization" );
	}

	ospath = FS_BuildOSPath( fs_homepath->string, filename, "" );
	ospath[strlen(ospath)-1] = '\0';

	f = FS_HandleForDemoFile();
	demofsh[f].zipFile = qfalse;

	if ( fs_debug->boolean ) {
		Com_Printf( "FS_SV_FOpenDemoFileWrite: %s\n", ospath );
	}

	if( FS_CreatePath( ospath ) ) {
		return 0;
	}

	demofsh[f].handleFiles.file.o = fopen( ospath, "wb" );

	Q_strncpyz( demofsh[f].name, filename, sizeof( demofsh[f].name ) );

	demofsh[f].handleSync = qfalse;
	if (!demofsh[f].handleFiles.file.o) {
		f = 0;
	}
	return f;
}
开发者ID:dioda,项目名称:apb,代码行数:38,代码来源:sv_demo.c

示例9: SV_GameMap_f

/*
==================
SV_GameMap_f

Saves the state of the map just being exited and goes to a new map.

If the initial character of the map string is '*', the next map is
in a new unit, so the current savegame directory is cleared of
map files.

Example:

*inter.cin+jail

Clears the archived maps, plays the inter.cin cinematic, then
goes to map jail.bsp.
==================
*/
void SV_GameMap_f (void)
{
	char		*map;
	int			i;
	client_t	*cl;
	qboolean	*savedInuse;

	if (Cmd_Argc() != 2)
	{
		Com_Printf ("USAGE: gamemap <map>\n");
		return;
	}

	Com_DPrintf("SV_GameMap(%s)\n", Cmd_Argv(1));

	FS_CreatePath (va("%s/save/current/", FS_Gamedir()));

	// check for clearing the current savegame
	map = Cmd_Argv(1);
	if (map[0] == '*')
	{
		// wipe all the *.sav files
		SV_WipeSavegame ("current");
	}
	else
	{	// save the map just exited
		if (sv.state == ss_game)
		{
			// clear all the client inuse flags before saving so that
			// when the level is re-entered, the clients will spawn
			// at spawn points instead of occupying body shells
			savedInuse = malloc(maxclients->value * sizeof(qboolean));
			for (i=0,cl=svs.clients ; i<maxclients->value; i++,cl++)
			{
				savedInuse[i] = cl->edict->inuse;
				cl->edict->inuse = false;
			}

			SV_WriteLevelFile ();

			// we must restore these for clients to transfer over correctly
			for (i=0,cl=svs.clients ; i<maxclients->value; i++,cl++)
				cl->edict->inuse = savedInuse[i];
			free (savedInuse);
		}
	}

	// start up the next map
	SV_Map (false, Cmd_Argv(1), false );

	// archive server state
	strncpy (svs.mapcmd, Cmd_Argv(1), sizeof(svs.mapcmd)-1);

	// copy off the level to the autosave slot
	if (!dedicated->value)
	{
		SV_WriteServerFile (true);
		SV_CopySaveGame ("current", "save0");
	}
}
开发者ID:AJenbo,项目名称:Quake-2,代码行数:78,代码来源:sv_ccmds.c

示例10: DL_BeginDownload

/*
=======================================================================================================================================
DL_BeginDownload

Inspired from http://www.w3.org/Library/Examples/LoadToFile.c, setup the download, return once we have a connection.
=======================================================================================================================================
*/
int DL_BeginDownload(char *localName, const char *remoteName) {
	char referer[MAX_STRING_CHARS + 5 /*"ET://"*/];

	if (dl_request) {
		Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - called with a download request already active\n");
		return 0;
	}

	if (!localName[0] || !remoteName[0]) {
		Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - empty download URL or empty local file name\n");
		return 0;
	}

	if (FS_CreatePath(localName)) {
		Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - unable to create directory(%s).\n", localName);
		return 0;
	}

	dl_file = fopen(localName, "wb + ");

	if (!dl_file) {
		Com_Printf(S_COLOR_RED  "DL_BeginDownload: Error - unable to open '%s' for writing\n", localName);
		return 0;
	}

	DL_InitDownload();
	// ET://ip:port
	strcpy(referer, "ET://");
	Q_strncpyz(referer + 5, Cvar_VariableString("cl_currentServerIP"), MAX_STRING_CHARS);

	dl_request = curl_easy_init();
	curl_easy_setopt(dl_request, CURLOPT_USERAGENT, va("%s %s", APP_NAME "/" APP_VERSION, curl_version()));
	curl_easy_setopt(dl_request, CURLOPT_REFERER, referer);
	curl_easy_setopt(dl_request, CURLOPT_URL, remoteName);
	curl_easy_setopt(dl_request, CURLOPT_WRITEFUNCTION, DL_cb_FWriteFile);
	curl_easy_setopt(dl_request, CURLOPT_WRITEDATA, (void *)dl_file);
	curl_easy_setopt(dl_request, CURLOPT_PROGRESSFUNCTION, DL_cb_Progress);
	curl_easy_setopt(dl_request, CURLOPT_NOPROGRESS, 0);
	curl_easy_setopt(dl_request, CURLOPT_FAILONERROR, 1);
	curl_easy_setopt(dl_request, CURLOPT_FOLLOWLOCATION, 1);
	curl_easy_setopt(dl_request, CURLOPT_MAXREDIRS, 5);
#ifdef FEATURE_OPENSSL
#if 0
	curl_easy_setopt(dl_request, CURLOPT_CAINFO, "./cert.crt");
#else
	curl_easy_setopt(dl_request, CURLOPT_SSL_VERIFYHOST, 0);
	curl_easy_setopt(dl_request, CURLOPT_SSL_VERIFYPEER, 0);
#endif
#endif
	if (curl_multi_add_handle(dl_multi, dl_request) != CURLM_OK) {
		Com_Printf(S_COLOR_RED "DL_BeginDownload: Error - invalid handle.\n");
	}

	Cvar_Set("cl_downloadName", remoteName);

	return 1;
}
开发者ID:ioid3-games,项目名称:ioid3-wet,代码行数:64,代码来源:dl_main_curl.c

示例11: FS_InitFilesystem

void
FS_InitFilesystem(void)
{
	/* Register FS commands. */
	Cmd_AddCommand("path", FS_Path_f);
	Cmd_AddCommand("link", FS_Link_f);
	Cmd_AddCommand("dir", FS_Dir_f);

	/* basedir <path> Allows the game to run from outside the data tree.  */
	fs_basedir = Cvar_Get("basedir",
#ifdef SYSTEMWIDE
		SYSTEMDIR,
#else
		".",
#endif
		CVAR_NOSET);

	/* cddir <path> Logically concatenates the cddir after the basedir to
	   allow the game to run from outside the data tree. */
	fs_cddir = Cvar_Get("cddir", "", CVAR_NOSET);

	if (fs_cddir->string[0] != '\0')
	{
		FS_AddGameDirectory(va("%s/" BASEDIRNAME, fs_cddir->string));
	}

	/* Debug flag. */
	fs_debug = Cvar_Get("fs_debug", "0", 0);

	/* Game directory. */
	fs_gamedirvar = Cvar_Get("game", "", CVAR_LATCH | CVAR_SERVERINFO);

	/* Current directory. */
	fs_homepath = Cvar_Get("homepath", Sys_GetCurrentDirectory(), CVAR_NOSET);

	/* Add baseq2 to search path. */
	FS_AddGameDirectory(va("%s/" BASEDIRNAME, fs_basedir->string));
	FS_AddBinaryDirAsGameDirectory(BASEDIRNAME);
	FS_AddHomeAsGameDirectory(BASEDIRNAME);

	/* Any set gamedirs will be freed up to here. */
	fs_baseSearchPaths = fs_searchPaths;
	Q_strlcpy(fs_currentGame, BASEDIRNAME, sizeof(fs_currentGame));

	/* Check for game override. */
	if (fs_gamedirvar->string[0] != '\0')
	{
		FS_SetGamedir(fs_gamedirvar->string);
	}

	/* Create directory if it does not exist. */
	FS_CreatePath(fs_gamedir);

	Com_Printf("Using '%s' for writing.\n", fs_gamedir);
}
开发者ID:Clever-Boy,项目名称:yquake2,代码行数:55,代码来源:filesystem.c

示例12: SV_CopySaveGame

/*
================
SV_CopySaveGame
================
*/
void SV_CopySaveGame (char *src, char *dst)
{
	char	name[MAX_OSPATH], name2[MAX_OSPATH];
	int		l, len;
	char	*found;

	Com_DPrintf("SV_CopySaveGame(%s, %s)\n", src, dst);

	SV_WipeSavegame (dst);

	// copy the savegame over
	Com_sprintf (name, sizeof(name), "%s/save/%s/server.ssv", FS_Gamedir(), src);
	Com_sprintf (name2, sizeof(name2), "%s/save/%s/server.ssv", FS_Gamedir(), dst);
	FS_CreatePath (name2);
	CopyFile (name, name2);

	Com_sprintf (name, sizeof(name), "%s/save/%s/game.ssv", FS_Gamedir(), src);
	Com_sprintf (name2, sizeof(name2), "%s/save/%s/game.ssv", FS_Gamedir(), dst);
	CopyFile (name, name2);

	// Knightmare- copy screenshot
	if (strcmp(dst, "kmq2save0")) // no screenshot for start of level autosaves
	{
		Com_sprintf (name, sizeof(name), "%s/save/%s/shot.jpg", FS_Gamedir(), src);
		Com_sprintf (name2, sizeof(name2), "%s/save/%s/shot.jpg", FS_Gamedir(), dst);
		CopyFile (name, name2);
	}

	Com_sprintf (name, sizeof(name), "%s/save/%s/", FS_Gamedir(), src);
	len = strlen(name);
	Com_sprintf (name, sizeof(name), "%s/save/%s/*.sav", FS_Gamedir(), src);
	found = Sys_FindFirst(name, 0, 0 );
	while (found)
	{
	//	strncpy (name+len, found+len);
		Q_strncpyz (name+len, found+len, sizeof(name)-len);
		Com_sprintf (name2, sizeof(name2), "%s/save/%s/%s", FS_Gamedir(), dst, found+len);
		CopyFile (name, name2);

		// change sav to sv2
		l = strlen(name);
	//	strncpy (name+l-3, "sv2");
		Q_strncpyz (name+l-3, "sv2", sizeof(name)-l+3);
		l = strlen(name2);
	//	strncpy (name2+l-3, "sv2");
		Q_strncpyz (name2+l-3, "sv2", sizeof(name2)-l+3);
		CopyFile (name, name2);

		found = Sys_FindNext( 0, 0 );
	}
	Sys_FindClose ();
}
开发者ID:Kiln707,项目名称:KMQuake2,代码行数:57,代码来源:sv_ccmds.c

示例13: screenshotJPEG

void screenshotJPEG(char *filename, qbyte *screendata, int screenwidth, int screenheight)	//input is rgb NOT rgba
{
	qbyte	*buffer;
	vfsfile_t	*outfile;
	jpeg_error_mgr_wrapper jerr;
	struct jpeg_compress_struct cinfo;
	JSAMPROW row_pointer[1];

	if (!(outfile = FS_OpenVFS(filename, "wb", FS_GAMEONLY)))
	{
		FS_CreatePath (filename, FS_GAME);
		if (!(outfile = FS_OpenVFS(filename, "wb", FS_GAMEONLY)))
		{
			Con_Printf("Error opening %s\n", filename);
			return;
		}
	}

	cinfo.err = jpeg_std_error(&jerr.pub);
	jerr.pub.error_exit = jpeg_error_exit;
	if (setjmp(jerr.setjmp_buffer))
	{
		jpeg_destroy_compress(&cinfo);
		VFS_CLOSE(outfile);
		FS_Remove(filename, FS_GAME);
		Con_Printf("Failed to create jpeg\n");
		return;
	}
	jpeg_create_compress(&cinfo);

	buffer = screendata;
	
	jpeg_mem_dest(&cinfo, outfile);
	cinfo.image_width = screenwidth; 	
	cinfo.image_height = screenheight;
	cinfo.input_components = 3;
	cinfo.in_color_space = JCS_RGB;
	jpeg_set_defaults(&cinfo);
	jpeg_set_quality (&cinfo, 75/*bound(0, (int) gl_image_jpeg_quality_level.value, 100)*/, true);
	jpeg_start_compress(&cinfo, true);

	while (cinfo.next_scanline < cinfo.image_height)
	{
	    *row_pointer = &buffer[(cinfo.image_height - cinfo.next_scanline - 1) * cinfo.image_width * 3];
	    jpeg_write_scanlines(&cinfo, row_pointer, 1);
	}

	jpeg_finish_compress(&cinfo);
	VFS_CLOSE(outfile);
	jpeg_destroy_compress(&cinfo);
}
开发者ID:DrLabman,项目名称:Vengeance-r2,代码行数:51,代码来源:gl_jpg.c

示例14: Log_AutoLogging_StartMatch

void Log_AutoLogging_StartMatch(char *logname) {
	char extendedname[MAX_OSPATH * 2], *fullname;
	FILE *templog;
	void *buf;

	temp_log_ready = false;

	if (!match_auto_logconsole.value)
		return;

	if (Log_IsLogging()) {
		if (autologging) {		
			
			autologging = false;
			Log_Stop();
		} else {
			Com_Printf("Auto console logging skipped (already logging)\n");
			return;
		}
	}


	strlcpy(auto_matchname, logname, sizeof(auto_matchname));

	strlcpy (extendedname, TEMP_LOG_NAME, sizeof(extendedname));
	COM_ForceExtensionEx (extendedname, ".log", sizeof (extendedname));
	fullname = va("%s/%s", MT_TempDirectory(), extendedname);


	if (!(templog = fopen (fullname, log_readable.value ? "w" : "wb"))) {
		FS_CreatePath(fullname);
		if (!(templog = fopen (fullname, log_readable.value ? "w" : "wb"))) {
			Com_Printf("Error: Couldn't open %s\n", fullname);
			return;
		}
	}

	buf = Q_calloc(1, LOGFILEBUFFER);
	if (!buf) {
		Com_Printf("Not enough memory to allocate log buffer\n");
		return;
	}
	memlogfile = FSMMAP_OpenVFS(buf, LOGFILEBUFFER);

	Com_Printf ("Auto console logging commenced\n");

	logfile = templog;
	autologging = true;
	auto_starttime = cls.realtime;
}
开发者ID:DeejStar,项目名称:ezquake-source,代码行数:50,代码来源:logging.c

示例15: SV_CopySaveGame

void
SV_CopySaveGame(char *src, char *dst)
{
	char name[MAX_OSPATH], name2[MAX_OSPATH];
	size_t l, len;
	char *found;

	Com_DPrintf("SV_CopySaveGame(%s, %s)\n", src, dst);

	SV_WipeSavegame(dst);

	/* copy the savegame over */
	Com_sprintf(name, sizeof(name), "%s/save/%s/server.ssv", FS_Gamedir(), src);
	Com_sprintf(name2, sizeof(name2), "%s/save/%s/server.ssv", FS_Gamedir(), dst);
	FS_CreatePath(name2);
	CopyFile(name, name2);

	Com_sprintf(name, sizeof(name), "%s/save/%s/game.ssv", FS_Gamedir(), src);
	Com_sprintf(name2, sizeof(name2), "%s/save/%s/game.ssv", FS_Gamedir(), dst);
	CopyFile(name, name2);

	Com_sprintf(name, sizeof(name), "%s/save/%s/", FS_Gamedir(), src);
	len = strlen(name);
	Com_sprintf(name, sizeof(name), "%s/save/%s/*.sav", FS_Gamedir(), src);
	found = Sys_FindFirst(name, 0, 0);

	while (found)
	{
		strcpy(name + len, found + len);

		Com_sprintf(name2, sizeof(name2), "%s/save/%s/%s",
					FS_Gamedir(), dst, found + len);
		CopyFile(name, name2);

		/* change sav to sv2 */
		l = strlen(name);
		strcpy(name + l - 3, "sv2");
		l = strlen(name2);
		strcpy(name2 + l - 3, "sv2");
		CopyFile(name, name2);

		found = Sys_FindNext(0, 0);
	}

	Sys_FindClose();
}
开发者ID:bradc6,项目名称:yquake2,代码行数:46,代码来源:sv_save.c


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