KFilePath.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:13k
源码类别:

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Engine (c) 1999-2000 by Kingsoft
  3. //
  4. // File: KPath.cpp
  5. // Date: 2000.08.08
  6. // Code: WangWei(Daphnis)
  7. // Desc: File Path Utility
  8. //---------------------------------------------------------------------------
  9. #include "KWin32.h"
  10. #include "KDebug.h"
  11. #include "KMemBase.h"
  12. #include "KStrBase.h"
  13. #include "KFilePath.h"
  14. #ifndef _SERVER
  15. #include "KPakList.h"
  16. #endif
  17. #ifndef WIN32
  18. #include <unistd.h>
  19. #else
  20. #include <direct.h>
  21. #endif
  22. #include <string.h>
  23. //---------------------------------------------------------------------------
  24. #ifdef WIN32
  25. static char szRootPath[MAXPATH] = "C:"; // 启动路径
  26. static char szCurrPath[MAXPATH] = "\"; // 当前路径
  27. #else
  28. static char szRootPath[MAXPATH] = "/"; // 启动路径
  29. static char szCurrPath[MAXPATH] = "/"; // 当前路径
  30. #endif
  31. int RemoveTwoPointPath(LPTSTR szPath, int nLength)
  32. {
  33. int nRemove = 0;
  34. KASSERT(szPath);
  35. #ifdef WIN32
  36. LPCTSTR lpszOld = "\..\";
  37. #else
  38. LPCTSTR lpszOld = "/../";
  39. #endif
  40. LPTSTR lpszTarget = strstr(szPath, lpszOld);
  41. if (lpszTarget)
  42. {
  43. LPTSTR lpszAfter = lpszTarget + 3;
  44. while(lpszTarget > szPath)
  45. {
  46. lpszTarget--;
  47. if ((*lpszTarget) == '\' ||(*lpszTarget) == '/')
  48. break;
  49. }
  50. memmove(lpszTarget, lpszAfter, (nLength - (lpszAfter - szPath) + 1) * sizeof(char));
  51. nRemove = (lpszAfter - lpszTarget);
  52. return RemoveTwoPointPath(szPath, nLength - nRemove);
  53. }
  54. return nLength - nRemove;
  55. }
  56. int RemoveOnePointPath(LPTSTR szPath, int nLength)
  57. {
  58. int nRemove = 0;
  59. KASSERT(szPath);
  60. #ifdef WIN32
  61. LPCTSTR lpszOld = "\.\";
  62. #else
  63. LPCTSTR lpszOld = "/./";
  64. #endif
  65. LPTSTR lpszTarget = strstr(szPath, lpszOld);
  66. if (lpszTarget)
  67. {
  68. LPTSTR lpszAfter = lpszTarget + 2;
  69. memmove(lpszTarget, lpszAfter, (nLength - (lpszAfter - szPath) + 1) * sizeof(char));
  70. nRemove = (lpszAfter - lpszTarget);
  71. return RemoveOnePointPath(szPath, nLength - nRemove);
  72. }
  73. return nLength - nRemove;
  74. }
  75. int RemoveAllPointPath(LPTSTR szPath, int nLength)
  76. {
  77. return RemoveOnePointPath(szPath, RemoveTwoPointPath(szPath, nLength));
  78. }
  79. //---------------------------------------------------------------------------
  80. // 函数: SetRootPath
  81. // 功能: 设置程序的根路径
  82. // 参数: lpPathName 路径名
  83. // 返回: void
  84. //---------------------------------------------------------------------------
  85. ENGINE_API void g_SetRootPath(LPSTR lpPathName)
  86. {
  87. if (lpPathName)
  88. {
  89. g_DebugLog("set path %sn", lpPathName);
  90. g_StrCpy(szRootPath, lpPathName);
  91. }
  92. else
  93. {
  94. //#ifdef WIN32
  95. // GetCurrentDirectory(MAXPATH, szRootPath);
  96. //#else
  97. g_DebugLog("set path NULLn");
  98. getcwd(szRootPath, MAXPATH);
  99. //#endif
  100. }
  101. // 去掉路径末尾的 ''
  102. int len = g_StrLen(szRootPath);
  103. g_DebugLog("set path %s(%d)n", szRootPath, len);
  104. if (szRootPath[len - 1] == '\' || szRootPath[len - 1] == '/')
  105. {
  106. szRootPath[len - 1] = 0;
  107. }
  108. g_DebugLog("RootPath = %s", szRootPath);
  109. }
  110. //---------------------------------------------------------------------------
  111. // 函数: GetRootPath
  112. // 功能: 取得程序的根路径
  113. // 参数: lpPathName 路径名
  114. // 返回: void
  115. //---------------------------------------------------------------------------
  116. ENGINE_API void g_GetRootPath(LPSTR lpPathName)
  117. {
  118. g_StrCpy(lpPathName, szRootPath);
  119. }
  120. //---------------------------------------------------------------------------
  121. // 函数: SetFilePath
  122. // 功能: 设置当前文件路径
  123. // 参数: lpPathName 路径名
  124. // 返回: void
  125. //---------------------------------------------------------------------------
  126. ENGINE_API void g_SetFilePath(LPSTR lpPathName)
  127. {
  128. // 去掉前面的 "\"
  129. if (lpPathName[0] == '\' ||lpPathName[0] == '/')
  130. {
  131. g_StrCpy(szCurrPath, lpPathName + 1);
  132. }
  133. else
  134. {
  135. g_StrCpy(szCurrPath, lpPathName);
  136. }
  137. // 末尾加上 "\"
  138. int len = g_StrLen(szCurrPath);
  139. if (len > 0 && szCurrPath[len - 1] != '\' && szCurrPath[len - 1] != '/')
  140. {
  141. #ifdef WIN32
  142. szCurrPath[len] = '\';
  143. #else
  144. szCurrPath[len] = '/';
  145. #endif
  146. szCurrPath[len + 1] = 0;
  147. }
  148. RemoveAllPointPath(szCurrPath, len + 1);
  149. #ifndef WIN32
  150. //'\' -> '/' [wxb 2003-7-29]
  151. for (len = 0; szCurrPath[len]; len++)
  152. {
  153. if (szCurrPath[len] == '\')
  154. szCurrPath[len] = '/';
  155. }
  156. #endif
  157. }
  158. //---------------------------------------------------------------------------
  159. // 函数: GetFilePath
  160. // 功能: 取得当前文件路径
  161. // 参数: lpPathName 路径名
  162. // 返回: void
  163. //---------------------------------------------------------------------------
  164. ENGINE_API void g_GetFilePath(LPSTR lpPathName)
  165. {
  166. g_StrCpy(lpPathName, szCurrPath);
  167. }
  168. //---------------------------------------------------------------------------
  169. // 函数: GetFullPath
  170. // 功能: 取得文件的全路径名
  171. // 参数: lpPathName 路径名
  172. // lpFileName 文件名
  173. // 返回: void
  174. //---------------------------------------------------------------------------
  175. ENGINE_API void g_GetFullPath(LPSTR lpPathName, LPSTR lpFileName)
  176. {
  177. // 文件带有全路径
  178. if (lpFileName[1] == ':')
  179. {
  180. g_StrCpy(lpPathName, lpFileName);
  181. return;
  182. }
  183. // 文件带有部分路径
  184. if (lpFileName[0] == '\' || lpFileName[0] == '/')
  185. {
  186. g_StrCpy(lpPathName, szRootPath);
  187. g_StrCat(lpPathName, lpFileName);
  188. return;
  189. }
  190. // 当前路径为全路径
  191. #ifdef WIN32
  192. if (szCurrPath[1] == ':')
  193. {
  194. g_StrCpy(lpPathName, szCurrPath);
  195. g_StrCat(lpPathName, lpFileName);
  196. return;
  197. }
  198. #endif
  199. // 当前路径为部分路径
  200. g_StrCpy(lpPathName, szRootPath);
  201.         if(szCurrPath[0] != '\' && szCurrPath[0] != '/') {
  202. #ifdef WIN32
  203. g_StrCat(lpPathName, "\");
  204. #else
  205. g_StrCat(lpPathName, "/");
  206. #endif
  207.       }
  208. g_StrCat(lpPathName, szCurrPath);
  209. if (lpFileName[0] == '.' && (lpFileName[1] == '\'||lpFileName[1] == '/') )
  210. g_StrCat(lpPathName, lpFileName + 2);
  211. else
  212. g_StrCat(lpPathName, lpFileName);
  213. }
  214. //---------------------------------------------------------------------------
  215. // 函数: GetHalfPath
  216. // 功能: 取得文件的半路径名,不带根路径
  217. // 参数: lpPathName 路径名
  218. // lpFileName 文件名
  219. // 返回: void
  220. //---------------------------------------------------------------------------
  221. ENGINE_API void g_GetHalfPath(LPSTR lpPathName, LPSTR lpFileName)
  222. {
  223. // 文件带有部分路径
  224. if (lpFileName[0] == '\' || lpFileName[0] == '/')
  225. {
  226. g_StrCpy(lpPathName, lpFileName);
  227. }
  228. else
  229. {
  230. #ifdef WIN32
  231. g_StrCpy(lpPathName, "\");
  232. #else
  233. g_StrCpy(lpPathName, "/");
  234. #endif
  235. g_StrCat(lpPathName, szCurrPath);
  236. g_StrCat(lpPathName, lpFileName);
  237. }
  238. }
  239. //---------------------------------------------------------------------------
  240. // 函数: GetPackPath
  241. // 功能: 取得文件在压缩包中的路径名
  242. // 参数: lpPathName 路径名
  243. // lpFileName 文件名
  244. // 返回: void
  245. //---------------------------------------------------------------------------
  246. ENGINE_API void g_GetPackPath(LPSTR lpPathName, LPSTR lpFileName)
  247. {
  248. // 文件带有部分路径
  249. if (lpFileName[0] == '\' || lpFileName[0] == '/')
  250. {
  251. g_StrCpy(lpPathName, lpFileName + 1);
  252. }
  253. else
  254. {
  255. g_StrCpy(lpPathName, szCurrPath);
  256. g_StrCat(lpPathName, lpFileName);
  257. }
  258. int len = g_StrLen(lpPathName);
  259. RemoveAllPointPath(lpPathName, len + 1);
  260. // 全部转换为小写字母
  261. g_StrLower(lpPathName);
  262. }
  263. //---------------------------------------------------------------------------
  264. // 函数: GetDiskPath
  265. // 功能: 取得CDROM对应的文件路径名
  266. // 参数: lpPathName 路径名
  267. // lpFileName 文件名
  268. // 返回: void
  269. //---------------------------------------------------------------------------
  270. ENGINE_API void g_GetDiskPath(LPSTR lpPathName, LPSTR lpFileName)
  271. {
  272. g_StrCpy(lpPathName, "C:");
  273. for (int i = 0; i < 24; lpPathName[0]++, i++)
  274. {
  275. // if (GetDriveType(lpPathName) == DRIVE_CDROM)
  276. // break;
  277. }
  278. if (lpFileName[0] == '\' || lpPathName[0] == '/')
  279. {
  280. g_StrCat(lpPathName, lpFileName);
  281. }
  282. else
  283. {
  284. #ifdef WIN32
  285. g_StrCat(lpPathName, "\");
  286. #else
  287. g_StrCat(lpPathName, "/");
  288. #endif
  289. g_StrCat(lpPathName, szCurrPath);
  290. g_StrCat(lpPathName, lpFileName);
  291. }
  292. }
  293. //---------------------------------------------------------------------------
  294. // 函数: CreatePath
  295. // 功能: 在游戏跟目录下建立一条路径
  296. // 参数: lpPathName 路径名
  297. // 返回: void
  298. //---------------------------------------------------------------------------
  299. ENGINE_API void g_CreatePath(LPSTR lpPathName)
  300. {
  301. if (!lpPathName || !lpPathName[0])
  302. return;
  303. char szFullPath[MAXPATH];
  304. int i;
  305. // 文件带有全路径
  306. if (lpPathName[1] == ':')
  307. {
  308. if (g_StrLen(lpPathName) < 4)
  309. return;
  310. g_StrCpy(szFullPath, lpPathName);
  311. i = 4;
  312. }
  313. else if (lpPathName[0] == '\' || lpPathName[0] == '/')
  314. {
  315. g_StrCpy(szFullPath, szRootPath);
  316. g_StrCat(szFullPath, lpPathName);
  317. i = g_StrLen(szRootPath) + 1;
  318. }
  319. else
  320. {
  321. g_StrCpy(szFullPath, szRootPath);
  322. #ifdef WIN32
  323. g_StrCat(szFullPath, "\");
  324. #else
  325. g_StrCat(szFullPath, "/");
  326. #endif
  327. g_StrCat(szFullPath, lpPathName);
  328.                 
  329. i = g_StrLen(szRootPath) + 1;
  330. }
  331. for (; i < g_StrLen(szFullPath); i++)
  332. {
  333. #ifdef WIN32
  334. if (szFullPath[i] == '\') {
  335. szFullPath[i] = 0;
  336. CreateDirectory(szFullPath, NULL);
  337. szFullPath[i] = '\';
  338. }
  339. #else
  340. if (szFullPath[i] == '/') {
  341. szFullPath[i] = 0;
  342. szFullPath[i] = '/';
  343. }
  344. #endif
  345. }
  346. #ifdef WIN32
  347. CreateDirectory(szFullPath, NULL);
  348. #else
  349. // flying comment
  350. // 朱传靖实现这个调用
  351. //mkdir();
  352. #endif
  353. }
  354. //---------------------------------------------------------------------------
  355. // 函数: g_UnitePathAndName
  356. // 功能: 一个路径和一个文件名,合并到lpGet中形成一个完整的路径文件名
  357. // 参数: lpPath 传入路径名 lpFile 传入文件名 lpGet 获得的最终完整文件名
  358. // 返回: void
  359. // 注意:   这里没有考虑字符串的长度,使用的时候要保证字符串的长度足够
  360. //---------------------------------------------------------------------------
  361. ENGINE_API void g_UnitePathAndName(char *lpPath, char *lpFile, char *lpGet)
  362. {
  363. if (!lpPath || !lpFile || !lpGet)
  364. return;
  365. strcpy(lpGet, lpPath);
  366. int nSize = strlen(lpGet);
  367. if (lpGet[nSize] - 1 != '\')
  368. {
  369. lpGet[nSize] = '\';
  370. lpGet[nSize + 1] = 0;
  371. }
  372. if (lpFile[0] != '\')
  373. {
  374. strcat(lpGet, lpFile);
  375. }
  376. else
  377. {
  378. strcat(lpGet, &lpFile[1]);
  379. }
  380. }
  381. //---------------------------------------------------------------------------
  382. // 函数: find if file exists in pak or in hard disk
  383. // 功能: 返回指定的文件是否存在
  384. // 参数: lpPathName 路径名+文件名
  385. // 返回: TRUE-成功,FALSE-失败。
  386. //---------------------------------------------------------------------------
  387. ENGINE_API BOOL g_FileExists(LPSTR FileName)
  388. {
  389. BOOL bExist = FALSE;
  390. char szFullName[MAX_PATH];
  391. if (FileName && FileName[0])
  392. {
  393. #ifndef _SERVER
  394. //先查是是否在打包文件中
  395. if (g_pPakList)
  396. {
  397. XPackElemFileRef PackRef;
  398. bExist = g_pPakList->FindElemFile(FileName, PackRef);
  399. }
  400. #endif
  401. //在检查是否单独存在文件系统里
  402. if (bExist == FALSE)
  403. {
  404. #ifdef WIN32
  405. g_GetFullPath(szFullName, FileName);
  406. bExist = !(GetFileAttributes(szFullName) & FILE_ATTRIBUTE_DIRECTORY);// || dword == INVALID_FILE_ATTRIBUTES)
  407. #endif
  408. }
  409. }
  410. return bExist;
  411. }
  412. //---------------------------------------------------------------------------
  413. // 函数: File Name to 32bit Id
  414. // 功能: 文件名转换成 Hash 32bit ID
  415. // 参数: lpFileName 文件名
  416. // 返回: FileName Hash 32bit ID
  417. // 
  418. // 注意: 游戏世界和主网关交互数据所用的哈希查找索引也是用
  419. // 的这个函数,所以请修改这个函数时也对应修改主网管
  420. // 中相对应的那个函数。这个函数存在于Common.lib工程的Utils.h
  421. // 中,函数声明为 DWORD HashStr2ID( const char * const pStr );
  422. //---------------------------------------------------------------------------
  423. ENGINE_API DWORD g_FileName2Id(LPSTR lpFileName)
  424. {
  425. DWORD Id = 0;
  426. char c = 0;
  427. for (int i = 0; lpFileName[i]; i++)
  428. {
  429. c = lpFileName[i];
  430. #ifndef WIN32
  431. //for linux path looking up
  432. if ('/' == c)
  433. c = '\';
  434. #endif
  435. Id = (Id + (i + 1) * c) % 0x8000000b * 0xffffffef;
  436. }
  437. return (Id ^ 0x12345678);
  438. }
  439. //---------------------------------------------------------------------------
  440. // 函数: change file extention
  441. // 功能: 改变文件的扩展名
  442. // 参数: lpFileName 文件名
  443. // lpNewExt 新扩展名,不能有'.'
  444. // 返回: void
  445. //---------------------------------------------------------------------------
  446. ENGINE_API void g_ChangeFileExt(LPSTR lpFileName, LPSTR lpNewExt)
  447. {
  448. int  i;
  449. for (i = 0; lpFileName[i]; i++)
  450. {
  451. if (lpFileName[i] == '.')
  452. break;
  453. }
  454. if (lpFileName[i] == '.')
  455. {
  456. g_StrCpy(&lpFileName[i + 1], lpNewExt);
  457. }
  458. else
  459. {
  460. g_StrCat(lpFileName, ".");
  461. g_StrCat(lpFileName, lpNewExt);
  462. }
  463. }
  464. //---------------------------------------------------------------------------
  465. // 函数: Extract File Name from path name
  466. // 功能: 取得文件名(不包含路径)
  467. // 参数: lpFileName 文件名(不包含路径)
  468. // lpFilePath 文件名(包含路径)
  469. // 返回: void
  470. //---------------------------------------------------------------------------
  471. ENGINE_API void g_ExtractFileName(LPSTR lpFileName, LPSTR lpFilePath)
  472. {
  473. int nLen = g_StrLen(lpFilePath);
  474. if (nLen < 5)
  475. return;
  476. int nPos = nLen;
  477. while (--nPos > 0)
  478. {
  479. if (lpFilePath[nPos] == '\'||lpFilePath[nPos] == '/')
  480. break;
  481. }
  482. g_StrCpy(lpFileName, &lpFilePath[nPos + 1]);
  483. }
  484. //---------------------------------------------------------------------------
  485. // 函数: Extract File Path from path name
  486. // 功能: 取得路径名
  487. // 参数: lpFileName 路径名
  488. // lpFilePath 路径名+文件名
  489. // 返回: void
  490. //---------------------------------------------------------------------------
  491. ENGINE_API void g_ExtractFilePath(LPSTR lpPathName, LPSTR lpFilePath)
  492. {
  493. int nLen = g_StrLen(lpFilePath);
  494. if (nLen < 5)
  495. return;
  496. int nPos = nLen;
  497. while (--nPos > 0)
  498. {
  499. if (lpFilePath[nPos] == '\' ||lpFilePath[nPos] == '/')
  500. break;
  501. }
  502. g_StrCpyLen(lpPathName, lpFilePath, nPos);
  503. }
  504. //---------------------------------------------------------------------------