llviewerassetstorage.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:8k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llviewerassetstorage.cpp
  3.  * @brief Subclass capable of loading asset data to/from an external source.
  4.  *
  5.  * $LicenseInfo:firstyear=2003&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2003-2010, Linden Research, Inc.
  8.  * 
  9.  * Second Life Viewer Source Code
  10.  * The source code in this file ("Source Code") is provided by Linden Lab
  11.  * to you under the terms of the GNU General Public License, version 2.0
  12.  * ("GPL"), unless you have obtained a separate licensing agreement
  13.  * ("Other License"), formally executed by you and Linden Lab.  Terms of
  14.  * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15.  * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16.  * 
  17.  * There are special exceptions to the terms and conditions of the GPL as
  18.  * it is applied to this Source Code. View the full text of the exception
  19.  * in the file doc/FLOSS-exception.txt in this software distribution, or
  20.  * online at
  21.  * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22.  * 
  23.  * By copying, modifying or distributing this software, you acknowledge
  24.  * that you have read and understood your obligations described above,
  25.  * and agree to abide by those obligations.
  26.  * 
  27.  * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28.  * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29.  * COMPLETENESS OR PERFORMANCE.
  30.  * $/LicenseInfo$
  31.  */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llviewerassetstorage.h"
  34. #include "llvfile.h"
  35. #include "llvfs.h"
  36. #include "message.h"
  37. #include "llagent.h"
  38. LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
  39.    LLVFS *vfs, const LLHost &upstream_host)
  40. : LLAssetStorage(msg, xfer, vfs, upstream_host)
  41. {
  42. }
  43. LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
  44.    LLVFS *vfs)
  45. : LLAssetStorage(msg, xfer, vfs)
  46. {
  47. }
  48. // virtual 
  49. void LLViewerAssetStorage::storeAssetData(
  50. const LLTransactionID& tid,
  51. LLAssetType::EType asset_type,
  52. LLStoreAssetCallback callback,
  53. void* user_data,
  54. bool temp_file,
  55. bool is_priority,
  56. bool store_local,
  57. bool user_waiting,
  58. F64 timeout)
  59. {
  60. LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
  61. llinfos << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type)
  62. << " ASSET_ID: " << asset_id << llendl;
  63. if (mUpstreamHost.isOk())
  64. {
  65. if (mVFS->getExists(asset_id, asset_type))
  66. {
  67. // Pack data into this packet if we can fit it.
  68. U8 buffer[MTUBYTES];
  69. buffer[0] = 0;
  70. LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ);
  71. S32 asset_size = vfile.getSize();
  72. LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type);
  73. req->mUpCallback = callback;
  74. req->mUserData = user_data;
  75. if (asset_size < 1)
  76. {
  77. // This can happen if there's a bug in our code or if the VFS has been corrupted.
  78. llwarns << "LLViewerAssetStorage::storeAssetData()  Data _should_ already be in the VFS, but it's not! " << asset_id << llendl;
  79. // LLAssetStorage metric: Zero size VFS
  80. reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
  81. delete req;
  82. if (callback)
  83. {
  84. callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT);
  85. }
  86. return;
  87. }
  88. else
  89. {
  90. // LLAssetStorage metric: Successful Request
  91. S32 size = mVFS->getSize(asset_id, asset_type);
  92. const char *message = "Added to upload queue";
  93. reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message );
  94. if(is_priority)
  95. {
  96. mPendingUploads.push_front(req);
  97. }
  98. else
  99. {
  100. mPendingUploads.push_back(req);
  101. }
  102. }
  103. // Read the data from the VFS if it'll fit in this packet.
  104. if (asset_size + 100 < MTUBYTES)
  105. {
  106. BOOL res = vfile.read(buffer, asset_size); /* Flawfinder: ignore */
  107. S32 bytes_read = res ? vfile.getLastBytesRead() : 0;
  108. if( bytes_read == asset_size )
  109. {
  110. req->mDataSentInFirstPacket = TRUE;
  111. //llinfos << "LLViewerAssetStorage::createAsset sending data in first packet" << llendl;
  112. }
  113. else
  114. {
  115. llwarns << "Probable corruption in VFS file, aborting store asset data" << llendl;
  116. // LLAssetStorage metric: VFS corrupt - bogus size
  117. reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, asset_size, MR_VFS_CORRUPTION, __FILE__, __LINE__, "VFS corruption" );
  118. if (callback)
  119. {
  120. callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT);
  121. }
  122. return;
  123. }
  124. }
  125. else
  126. {
  127. // Too big, do an xfer
  128. buffer[0] = 0;
  129. asset_size = 0;
  130. }
  131. mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest);
  132. mMessageSys->nextBlockFast(_PREHASH_AssetBlock);
  133. mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid);
  134. mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type);
  135. mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file);
  136. mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local);
  137. mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size );
  138. mMessageSys->sendReliable(mUpstreamHost);
  139. }
  140. else
  141. {
  142. llwarns << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
  143. // LLAssetStorage metric: Zero size VFS
  144. reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
  145. if (callback)
  146. {
  147. callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE);
  148. }
  149. }
  150. }
  151. else
  152. {
  153. llwarns << "Attempt to move asset store request upstream w/o valid upstream provider" << llendl;
  154. // LLAssetStorage metric: Upstream provider dead
  155. reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" );
  156. if (callback)
  157. {
  158. callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
  159. }
  160. }
  161. }
  162. void LLViewerAssetStorage::storeAssetData(
  163. const std::string& filename,
  164. const LLTransactionID& tid,
  165. LLAssetType::EType asset_type,
  166. LLStoreAssetCallback callback,
  167. void* user_data,
  168. bool temp_file,
  169. bool is_priority,
  170. bool user_waiting,
  171. F64 timeout)
  172. {
  173. if(filename.empty())
  174. {
  175. // LLAssetStorage metric: no filename
  176. reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_VFS_CORRUPTION, __FILE__, __LINE__, "Filename missing" );
  177. llerrs << "No filename specified" << llendl;
  178. return;
  179. }
  180. LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
  181. llinfos << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << llendl;
  182. llinfos << "ASSET_ID: " << asset_id << llendl;
  183. S32 size = 0;
  184. LLFILE* fp = LLFile::fopen(filename, "rb");
  185. if (fp)
  186. {
  187. fseek(fp, 0, SEEK_END);
  188. size = ftell(fp);
  189. fseek(fp, 0, SEEK_SET);
  190. }
  191. if( size )
  192. {
  193. LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
  194. legacy->mUpCallback = callback;
  195. legacy->mUserData = user_data;
  196. LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE);
  197. file.setMaxSize(size);
  198. const S32 buf_size = 65536;
  199. U8 copy_buf[buf_size];
  200. while ((size = (S32)fread(copy_buf, 1, buf_size, fp)))
  201. {
  202. file.write(copy_buf, size);
  203. }
  204. fclose(fp);
  205. // if this upload fails, the caller needs to setup a new tempfile for us
  206. if (temp_file)
  207. {
  208. LLFile::remove(filename);
  209. }
  210. // LLAssetStorage metric: Success not needed; handled in the overloaded method here:
  211. LLViewerAssetStorage::storeAssetData(
  212. tid,
  213. asset_type,
  214. legacyStoreDataCallback,
  215. (void**)legacy,
  216. temp_file,
  217. is_priority);
  218. }
  219. else // size == 0 (but previous block changes size)
  220. {
  221. if( fp )
  222. {
  223. // LLAssetStorage metric: Zero size
  224. reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" );
  225. }
  226. else
  227. {
  228. // LLAssetStorage metric: Missing File
  229. reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" );
  230. }
  231. if (callback)
  232. {
  233. callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE);
  234. }
  235. }
  236. }