1. #include "stdafx.h"
  2. #include "../../libgame/include/attribute.h"
  3. #include "../../libgame/include/targa.h"
  4. #include "../../common/d3dtype.h"
  5. #include "utils.h"
  6. #include "minilzo.h"
  7. #include "sectree.h"
  8. #include "sectree_manager.h"
  9. #include "vector.h"
  10. #include "lzo_manager.h"
  11. #include "char_manager.h"
  12. #include "desc_manager.h"
  13. #include "questmanager.h"
  14. #include "arena.h"
  15. #include "pvp.h"
  16. #include "cmd.h"
  17. enum
  18. {
  19. COLLISION_TYPE_PLANE,
  20. COLLISION_TYPE_BOX,
  21. COLLISION_TYPE_SPHERE,
  22. COLLISION_TYPE_CYLINDER,
  23. };
  24. typedef struct SSphereData
  25. {
  26. D3DXVECTOR3 v3Position;
  27. float fRadius;
  28. } TSphereData;
  29. typedef struct SPlaneData
  30. {
  31. D3DXVECTOR3 v3Position;
  32. D3DXVECTOR3 v3Normal;
  33. D3DXVECTOR3 v3QuadPosition[4];
  34. D3DXVECTOR3 v3InsideVector[4];
  35. } TPlaneData;
  36. typedef struct SCylinderData
  37. {
  38. D3DXVECTOR3 v3Position;
  39. float fRadius;
  40. float fHeight;
  41. } TCylinderData;
  42. LPSECTREE_MAP g_pkMapSectree;
  43. int max_bytes_written = 0;
  44. int total_bytes_written = 0;
  45. int current_bytes_written = 0;
  46. int g_bx;
  47. int g_by;
  48. LPFDWATCH main_fdw = NULL;
  49. socket_t udp_socket = 0;
  50. bool g_bShutdown = false;
  51. void ConvertAttribute(const char * c_pszCollisionDataFileName, const char * c_pszMapDirectory);
  52. void ReadColorMapRecursive(const char * c_pszFileName);
  53. void ConvertAttribute2(const char * filename);
  54. void ContinueOnFatalError()
  55. {
  56. }
  57. void ShutdownOnFatalError()
  58. {
  59. }
  60. void heartbeat(LPHEART heart, int pulse)
  61. {
  62. }
  63. bool Metin2Server_IsInvalid()
  64. {
  65. return false;
  66. }
  67. void SectreeTest(LPSECTREE pSec)
  68. {
  69. sys_log(0, " %d %d section attribute ------------------------------", pSec->GetID().coord.x, pSec->GetID().coord.y);
  70. DWORD * line = M2_NEW DWORD[SECTREE_SIZE / CELL_SIZE];
  71. for (int y = 0; y < SECTREE_SIZE / CELL_SIZE; y++)
  72. {
  73. pSec->GetAttributePtr()->CopyRow(y, line);
  74. for (int x = 0; x < SECTREE_SIZE / CELL_SIZE; x++)
  75. printf("%c", line[x] ? 'X' : ' ');
  76. puts("");
  77. }
  78. M2_DELETE_ARRAY(line);
  79. }
  80. int start(int argc, char ** argv)
  81. {
  82. extern const char * _malloc_options;
  83. _malloc_options = "A";
  84. if (lzo_init() != LZO_E_OK)
  85. {
  86. sys_err("lzo_init() failed");
  87. return 0;
  88. }
  89. thecore_init(25, heartbeat);
  90. signal_timer_disable();
  91. return 1;
  92. }
  93. int main(int argc, char ** argv)
  94. {
  95. SECTREE_MANAGER sectree_manager;
  96. DESC_MANAGER desc_manager;
  97. CHARACTER_MANAGER char_manager;
  98. quest::CQuestManager quest_manager; // CHARACTER::Intiailize에서 필요함
  99. CArenaManager arena_manager;
  100. CPVPManager pvp_manager;
  101. LZOManager lzo;
  102. if (!start(argc, argv))
  103. return 0;
  104. signal_timer_disable();
  105. char buf[256];
  106. char last_cmd[256];
  107. char * p;
  108. bool bEnd = false;
  109. while (!bEnd && fgets(buf, 256, stdin))
  110. {
  111. while ((p = strrchr(buf, '\r'))) *p = '\0';
  112. while ((p = strrchr(buf, '\n'))) *p = '\0';
  113. if (buf[0] == '!')
  114. strlcpy(buf, last_cmd, sizeof(buf));
  115. strlcpy(last_cmd, buf, sizeof(last_cmd));
  116. char arg1[64], arg2[64];//, arg3[64], arg4[64];
  117. const char * line = one_argument(buf, arg1, sizeof(arg1));
  118. switch (arg1[0])
  119. {
  120. case 'a':
  121. {
  122. two_arguments(line, arg1, sizeof(arg1), arg2, sizeof(arg2));
  123. if (!*arg1 || !*arg2)
  124. {
  125. printf("Syntax: a <collision data filename> <map directory>\n");
  126. break;
  127. }
  128. ConvertAttribute(arg1, arg2);
  129. puts("build server_attr done");
  130. }
  131. break;
  132. case 'c':
  133. {
  134. one_argument(line, arg1, sizeof(arg1));
  135. if (!*arg1)
  136. {
  137. printf("Syntax: c <filename>\n");
  138. break;
  139. }
  140. ConvertAttribute2(arg1);
  141. }
  142. //ReadColorMapRecursive(line);
  143. break;
  144. case 'b':
  145. {
  146. // Buffer overflow test (must use with valgrind or gdb at least)
  147. LPCHARACTER ch = CHARACTER_MANAGER::instance().CreateCharacter("test");
  148. // 스택에 할당하면 valgrind가 제대로 오류를 잡지 못함
  149. size_t bufsize = 512 + 1;
  150. size_t linesize = 1024 + 1;
  151. if (bufsize > 0 && linesize > 0)
  152. {
  153. char *buf = (char *) malloc(bufsize);
  154. char *line = (char *) malloc(linesize);
  155. memset(buf, 0, bufsize);
  156. memset(line, 0, linesize);
  157. for (size_t i = 0; i < bufsize - 1; ++i)
  158. {
  159. buf[i] = '$';
  160. int linelen = snprintf(line, linesize, "pvp %s", buf);
  161. if (linelen < 0 || linelen >= (int) linesize)
  162. linelen = linesize - 1;
  163. printf("%d %s\n", i, line);
  164. interpret_command(ch, line, linelen);
  165. }
  166. free(buf);
  167. free(line);
  168. }
  169. else
  170. {
  171. printf("size error!\n");
  172. abort();
  173. }
  174. printf("Buffer overflow test finished\n");
  175. }
  176. break;
  177. case 'q':
  178. bEnd = true;
  179. break;
  180. }
  181. }
  182. thecore_destroy();
  183. event_destroy();
  184. return 0;
  185. }
  186. const int region[8][2] =
  187. {
  188. { 0, 64 },
  189. { 64, 128 },
  190. { 128, 192 },
  191. { 192, 256 }
  192. /*{ 0, 32 },
  193. { 32, 64 },
  194. { 64, 96 },
  195. { 96, 128 },
  196. { 128, 160 },
  197. { 160, 192 },
  198. { 192, 224 },
  199. { 224, 256 },*/
  200. };
  201. bool ReadMapAttribute(DWORD dwAreaX, DWORD dwAreaY, const char * c_pszFileName)
  202. {
  203. FILE * fp = fopen(c_pszFileName, "rb");
  204. if (!fp)
  205. {
  206. sys_err("cannot open %s", c_pszFileName);
  207. return false;
  208. }
  209. WORD wCC, wWidth, wHeight;
  210. fread(&wCC, sizeof(WORD), 1, fp);
  211. if (wCC != 2634)
  212. {
  213. sys_err("not a attribute file: %s cc: %d", c_pszFileName, wCC);
  214. fclose(fp);
  215. return false;
  216. }
  217. fread(&wWidth, sizeof(WORD), 1, fp);
  218. fread(&wHeight, sizeof(WORD), 1, fp);
  219. sys_log(0, "Reading attribute on %d %d (w %d h %d)", dwAreaX, dwAreaY, wWidth, wHeight);
  220. //printf("Reading attribute on %d %d (w %d h %d)", dwAreaX, dwAreaY, wWidth, wHeight);
  221. BYTE * pbAttr = M2_NEW BYTE [wWidth * wHeight];
  222. if (fread(pbAttr, sizeof(BYTE), wWidth * wHeight, fp) != (DWORD) (wWidth * wHeight))
  223. {
  224. sys_err("cannot read %s", c_pszFileName);
  225. M2_DELETE_ARRAY(pbAttr);
  226. fclose(fp);
  227. return false;
  228. }
  229. fclose(fp); // close file
  230. //
  231. // 하나의 SECTREE는 6400 PIXEL을 차지 100픽셀이 1미터 이므로
  232. // 1 SECTREE = 64m = 6400px
  233. //
  234. // 클라이언트의 하나의 Area는 256m를 차지하므로 SECTREE 네개를 처리해야
  235. // 한다.
  236. //
  237. DWORD dwStartX, dwStartY, dwEndX, dwEndY;
  238. dwEndX = (dwAreaX + 1) * (25600 / SECTREE_SIZE);
  239. dwEndY = (dwAreaY + 1) * (25600 / SECTREE_SIZE);
  240. dwStartX = dwEndX - (25600 / SECTREE_SIZE);
  241. dwStartY = dwEndY - (25600 / SECTREE_SIZE);
  242. for (DWORD y = dwStartY; y < dwEndY; ++y)
  243. {
  244. for (DWORD x = dwStartX; x < dwEndX; ++x)
  245. {
  246. SECTREEID id;
  247. id.coord.x = x+g_bx;
  248. id.coord.y = y+g_by;
  249. LPSECTREE pSec;
  250. if (!(pSec = g_pkMapSectree->Find(id.package)))
  251. {
  252. sys_err("cannot get sectree (id %d %d)", id.coord.x, id.coord.y);
  253. break;
  254. }
  255. // 64 128 192 256
  256. // 0 1 2 3
  257. for (int ay = region[y - dwStartY][0], py = 0; ay < region[y - dwStartY][1]; ++ay, py += 2)
  258. {
  259. for (int ax = region[x - dwStartX][0], px = 0; ax < region[x - dwStartX][1]; ++ax, px += 2)
  260. {
  261. // AREA의 경우 속성 해상도가 1m 이므로
  262. // CELL 1개가 50x50cm인 SECTREE에서는
  263. // AREA의 속성 한개가 2x2개를 차지 한다.
  264. BYTE bAttr = pbAttr[ay * wHeight + ax];
  265. if (bAttr & ATTR_OBJECT)
  266. {
  267. printf("8");
  268. REMOVE_BIT(bAttr, ATTR_OBJECT);
  269. }
  270. printf("%u", bAttr);
  271. pSec->SetAttribute(px , py , bAttr);
  272. pSec->SetAttribute(px , py + 1, bAttr);
  273. pSec->SetAttribute(px + 1, py , bAttr);
  274. pSec->SetAttribute(px + 1, py + 1, bAttr);
  275. }
  276. }
  277. }
  278. }
  279. M2_DELETE_ARRAY(pbAttr);
  280. return true;
  281. }
  282. void ReadMapRecursive(const char * c_pszFileName)
  283. {
  284. struct stat s;
  285. char buf[512 + 1];
  286. //printf("%s\n",c_pszFileName);
  287. if (stat(c_pszFileName, &s) != 0)
  288. {
  289. sys_log(0, "No map directory: %s", c_pszFileName);
  290. return;
  291. }
  292. if (S_ISDIR(s.st_mode))
  293. {
  294. struct dirent ** namelist;
  295. int n;
  296. n = scandir(c_pszFileName, &namelist, 0, alphasort);
  297. if (n < 0)
  298. perror("scandir");
  299. else
  300. {
  301. while (n-- > 0)
  302. {
  303. if (namelist[n]->d_name[0] == '.')
  304. continue;
  305. snprintf(buf, sizeof(buf), "%s/%s", c_pszFileName, namelist[n]->d_name);
  306. ReadMapRecursive(buf);
  307. }
  308. }
  309. free(namelist);
  310. return;
  311. }
  312. const char * p;
  313. if ((p = strrchr(c_pszFileName, '.')))
  314. {
  315. ++p;
  316. if (!strncmp(p, "atr", 3))
  317. {
  318. int count = 0;
  319. int i;
  320. for (i = strlen(c_pszFileName); i >= 0; --i)
  321. if (c_pszFileName[i] == '/' && ++count == 2)
  322. break;
  323. if (i > 0)
  324. p = &c_pszFileName[i + 1];
  325. else
  326. return;
  327. char szCoordX[4];
  328. char szCoordY[4];
  329. strlcpy(szCoordX, p, sizeof(szCoordX));
  330. strlcpy(szCoordY, p + 3, sizeof(szCoordY));
  331. ReadMapAttribute(atoi(szCoordX), atoi(szCoordY), c_pszFileName);
  332. }
  333. }
  334. }
  335. void ReadColorMap(const char * c_pszFileName)
  336. {
  337. FILE * fp = fopen(c_pszFileName, "rb");
  338. WORD wMagic, wWidth, wHeight;
  339. WORD awTileMap[256 * 256];
  340. fread(&wMagic, sizeof(WORD), 1, fp);
  341. fread(&wWidth, sizeof(WORD), 1, fp);
  342. fread(&wHeight, sizeof(WORD), 1, fp);
  343. fread(&awTileMap, sizeof(WORD), 256 * 256, fp);
  344. bool abUsed[32];
  345. memset(&abUsed, 0, sizeof(abUsed));
  346. for (int y = 0; y < 256; ++y)
  347. for (int x = 0; x < 256; ++x)
  348. {
  349. BYTE t = awTileMap[y * 256 + x] >> 8;
  350. if (t >= 32)
  351. {
  352. printf("ERROR! %d %dx%d\n", t, x, y);
  353. continue;
  354. }
  355. else
  356. abUsed[t] = true;
  357. }
  358. int iUsed = 0;
  359. for (int i = 0; i < 32; ++i)
  360. if (abUsed[i])
  361. ++iUsed;
  362. printf("%s %d\n", c_pszFileName, iUsed);
  363. fclose(fp);
  364. }
  365. void ReadColorMapRecursive(const char * c_pszFileName)
  366. {
  367. struct stat s;
  368. char buf[512 + 1];
  369. if (stat(c_pszFileName, &s) != 0)
  370. {
  371. sys_log(0, "No map directory: %s", c_pszFileName);
  372. return;
  373. }
  374. if (S_ISDIR(s.st_mode))
  375. {
  376. struct dirent ** namelist;
  377. int n;
  378. n = scandir(c_pszFileName, &namelist, 0, alphasort);
  379. if (n < 0)
  380. perror("scandir");
  381. else
  382. {
  383. while (n-- > 0)
  384. {
  385. if (namelist[n]->d_name[0] == '.')
  386. continue;
  387. snprintf(buf, sizeof(buf), "%s/%s", c_pszFileName, namelist[n]->d_name);
  388. ReadColorMapRecursive(buf);
  389. }
  390. }
  391. free(namelist);
  392. return;
  393. }
  394. char * p;
  395. if ((p = strrchr(c_pszFileName, '.')))
  396. {
  397. ++p;
  398. if (!strncmp(p, "cmp", 3))
  399. ReadColorMap(c_pszFileName);
  400. }
  401. }
  402. template <typename _f>
  403. void ProcessLine(int sx, int sy, int ex, int ey, _f f)
  404. {
  405. int mode = 0;
  406. int w, h;
  407. int x = 0, y = 0;
  408. int d;
  409. int px, py;
  410. // 0: dx > 0 && dy > 0
  411. // 1: dx < 0 && dy > 0
  412. // 2: dx > 0 && dy < 0
  413. // 3: dx < 0 && dy < 0
  414. if (sx > ex)
  415. {
  416. mode |= 1;
  417. w = sx - ex;
  418. }
  419. else
  420. w = ex - sx;
  421. if (sy > ey)
  422. {
  423. mode |= 2;
  424. h = sy - ey;
  425. }
  426. else
  427. h = ey - sy;
  428. // distance = (w * w) + (h * h); // 거리
  429. if (w > h)
  430. {
  431. d = (h << 1) - w;
  432. while (x < w)
  433. {
  434. if (d < 0)
  435. {
  436. d += (h << 1);
  437. x++;
  438. }
  439. else
  440. {
  441. d += ((h - w) << 1);
  442. x++;
  443. y++;
  444. }
  445. switch (mode)
  446. {
  447. case 0: px = sx + x; py = sy + y; break;
  448. case 1: px = sx - x; py = sy + y; break;
  449. case 2: px = sx + x; py = sy - y; break;
  450. case 3: px = sx - x; py = sy - y; break;
  451. default: return;
  452. }
  453. if (!f(px, py)) // false 가 리턴 되면 중단 한다.
  454. {
  455. printf("putting error %d %d", px, py);
  456. return;
  457. }
  458. }
  459. }
  460. else
  461. {
  462. d = h - (w << 1);
  463. while (y < h)
  464. {
  465. if (d > 0)
  466. {
  467. d += -(w << 1);
  468. y++;
  469. }
  470. else
  471. {
  472. d += ((h - w) << 1);
  473. x++;
  474. y++;
  475. }
  476. switch (mode)
  477. {
  478. case 0: px = sx + x; py = sy + y; break;
  479. case 1: px = sx - x; py = sy + y; break;
  480. case 2: px = sx + x; py = sy - y; break;
  481. case 3: px = sx - x; py = sy - y; break;
  482. default: return;
  483. }
  484. if (!f(px, py)) // false 가 리턴 되면 중단 한다.
  485. {
  486. printf("putting error %d %d", px, py);
  487. return;
  488. }
  489. }
  490. }
  491. }
  492. template <typename _f>
  493. void ProcessSphere(float x, float y, float fRadius, _f f)
  494. {
  495. //printf("%f %f %f\n", x, y, fRadius);
  496. int r = (int)fRadius + 1;
  497. int ix = (int)x;
  498. int iy = (int)y;
  499. //int ex = (int) (ix + r);
  500. //int ey = (int) (iy + r);
  501. //printf("%d %d %d\n", ix, iy, r);
  502. for (int rx = - r; rx < + r; rx+=25)
  503. for (int ry = - r; ry < + r; ry+=25)
  504. {
  505. //printf("%d %d %d %d %d %d\n", rx, ry, ix-rx, iy-ry, (ix-rx)*(ix-rx)+(iy-ry)*(iy-ry), r*r);
  506. //if ((ix-rx)*(ix-rx)+(iy-ry)*(iy-ry)<r*r)
  507. if (rx*rx + ry*ry < r*r)
  508. {
  509. //printf("#%d %d\n", rx+ix, ry+iy);
  510. if (!f(rx+ix, ry+iy))
  511. {
  512. printf("putting error");
  513. return;
  514. }
  515. }
  516. }
  517. }
  518. bool BlockAttribute(int x, int y)
  519. {
  520. int bx = x / SECTREE_SIZE;
  521. int by = y / SECTREE_SIZE;
  522. SECTREEID id;
  523. id.coord.x = bx;
  524. id.coord.y = by;
  525. LPSECTREE pSec = g_pkMapSectree->Find(id.package);
  526. if (!pSec)
  527. {
  528. printf("BlockAttribute: no sectree on %d %d", bx, by);
  529. return false;
  530. }
  531. pSec->SetAttribute((x % SECTREE_SIZE) / CELL_SIZE, (y % SECTREE_SIZE) / CELL_SIZE, 1);
  532. //printf("BlockAttribute: put on %d %d", x, y);
  533. return true;
  534. }
  535. void ReadCollisionData(const char * c_pszFileName, int iBaseX, int iBaseY)
  536. {
  537. FILE * fp = fopen(c_pszFileName, "rb");
  538. printf("Reading collision data file: %s\n", c_pszFileName);
  539. if (!fp)
  540. {
  541. printf("No collision data file: %s\n", c_pszFileName);
  542. return;
  543. }
  544. DWORD dwFourCC;
  545. fread(&dwFourCC, sizeof(DWORD), 1, fp);
  546. if (dwFourCC != MAKEFOURCC('M', '2', 'C', 'D'))
  547. {
  548. printf("Not a collision data file: %s", c_pszFileName);
  549. fclose(fp);
  550. return;
  551. }
  552. WORD wxSize, wySize;
  553. fread(&wxSize, sizeof(WORD), 1, fp);
  554. fread(&wySize, sizeof(WORD), 1, fp);
  555. printf("collision area size: %d %d", wxSize, wySize);
  556. for (DWORD x = 0; x < wxSize; ++x)
  557. {
  558. for (DWORD y = 0; y < wySize; ++y)
  559. {
  560. DWORD dwCount;
  561. fread(&dwCount, sizeof(DWORD), 1, fp);
  562. printf("\n%ux%u %u ", x, y, dwCount);
  563. for (DWORD j = 0; j < dwCount; ++j)
  564. {
  565. BYTE bType;
  566. fread(&bType, sizeof(BYTE), 1, fp);
  567. switch (bType)
  568. {
  569. case COLLISION_TYPE_PLANE:
  570. printf("P");
  571. {
  572. TPlaneData PlaneData;
  573. fread(&PlaneData, sizeof(TPlaneData), 1, fp);
  574. int pairs[6][2] =
  575. {
  576. { 0, 3 },
  577. { 0, 1 },
  578. { 0, 2 },
  579. { 1, 2 },
  580. { 1, 3 },
  581. { 2, 3 },
  582. };
  583. for (int iPairIndex = 0; iPairIndex < 6; iPairIndex++)
  584. {
  585. int iFrom = pairs[iPairIndex][0];
  586. int iTo = pairs[iPairIndex][1];
  587. if (fabs(PlaneData.v3QuadPosition[iFrom].x - PlaneData.v3QuadPosition[iTo].x) > 100000.0f ||
  588. fabs(PlaneData.v3QuadPosition[iFrom].y - PlaneData.v3QuadPosition[iTo].y) > 100000.0f)
  589. {
  590. sys_log(0, "Blcok too big: %d %d %d %d",
  591. iBaseX + (int) PlaneData.v3QuadPosition[iFrom].x,
  592. iBaseY + (int) -PlaneData.v3QuadPosition[iFrom].y,
  593. iBaseX + (int) PlaneData.v3QuadPosition[iTo].x,
  594. iBaseY + (int) -PlaneData.v3QuadPosition[iTo].y);
  595. }
  596. else
  597. {
  598. printf("Block %d %d %d %d\n",
  599. iBaseX + (int) PlaneData.v3QuadPosition[iFrom].x,
  600. iBaseY + (int) -PlaneData.v3QuadPosition[iFrom].y,
  601. iBaseX + (int) PlaneData.v3QuadPosition[iTo].x,
  602. iBaseY + (int) -PlaneData.v3QuadPosition[iTo].y);
  603. ProcessLine(
  604. iBaseX + (int) PlaneData.v3QuadPosition[iFrom].x,
  605. iBaseY + (int) -PlaneData.v3QuadPosition[iFrom].y,
  606. iBaseX + (int) PlaneData.v3QuadPosition[iTo].x,
  607. iBaseY + (int) -PlaneData.v3QuadPosition[iTo].y,
  608. BlockAttribute);
  609. }
  610. }
  611. // 사각형 채우기도 합시다
  612. // 0 1 2 3 순서대로
  613. // -- +- -+ ++
  614. // 근데 y 는 마이너스 취하는거 확인하시길
  615. // TODO
  616. }
  617. break;
  618. case COLLISION_TYPE_SPHERE:
  619. printf("S");
  620. {
  621. TSphereData SphereData;
  622. fread(&SphereData, sizeof(TSphereData), 1, fp);
  623. ProcessSphere(
  624. iBaseX + SphereData.v3Position.x,
  625. iBaseY - SphereData.v3Position.y,
  626. SphereData.fRadius,
  627. BlockAttribute);
  628. }
  629. break;
  630. case COLLISION_TYPE_CYLINDER:
  631. printf("C");
  632. {
  633. TCylinderData CylinderData;
  634. fread(&CylinderData, sizeof(TCylinderData), 1, fp);
  635. ProcessSphere(
  636. iBaseX + CylinderData.v3Position.x,
  637. iBaseY - CylinderData.v3Position.y,
  638. CylinderData.fRadius,
  639. BlockAttribute);
  640. }
  641. break;
  642. default:
  643. printf("invalid type!");
  644. break;
  645. }
  646. }
  647. }
  648. }
  649. printf("%d %d\n", iBaseX, iBaseY);
  650. fclose(fp);
  651. }
  652. void ConvertAttribute(const char * c_pszCollisionDataFileName, const char * c_pszMapDirectory)
  653. {
  654. char szFilename[256];
  655. snprintf(szFilename, sizeof(szFilename), "%s/Setting.txt", c_pszMapDirectory);
  656. TMapSetting setting;
  657. SECTREE_MANAGER::instance().LoadSettingFile(0, szFilename, setting);
  658. g_pkMapSectree = SECTREE_MANAGER::instance().BuildSectreeFromSetting(setting);
  659. int iMapHeight = setting.iHeight / 128 / 200;
  660. int iMapWidth = setting.iWidth / 128 / 200;
  661. if (iMapHeight < 0 || iMapWidth < 0)
  662. {
  663. printf("SYSERR: setting.w/h %d %d, base %d %d\n", setting.iWidth, setting.iHeight, setting.iBaseX, setting.iBaseY);
  664. return;
  665. }
  666. int bx = setting.iBaseX;
  667. int by = setting.iBaseY;
  668. printf("w %d h %d\n", iMapWidth, iMapHeight);
  669. bx /= SECTREE_SIZE;
  670. by /= SECTREE_SIZE;
  671. g_bx = bx;
  672. g_by = by;
  673. printf("bx by %d %d\n", bx, by);
  674. int x, y;
  675. // 일단 속성 초기화
  676. for (y = 0; y < iMapHeight * (25600 / SECTREE_SIZE); ++y)
  677. {
  678. for (x = 0; x < iMapWidth * (25600 / SECTREE_SIZE); ++x)
  679. {
  680. SECTREEID id;
  681. id.coord.x = x + bx;
  682. id.coord.y = y + by;
  683. g_pkMapSectree->Find(id.package)->BindAttribute(M2_NEW CAttribute(SECTREE_SIZE / CELL_SIZE, SECTREE_SIZE / CELL_SIZE));
  684. }
  685. }
  686. ReadMapRecursive(c_pszMapDirectory);
  687. printf("iMapWidth %d iMapHeight %d\n", iMapWidth, iMapHeight);
  688. ReadCollisionData(c_pszCollisionDataFileName, setting.iBaseX, setting.iBaseY);
  689. SECTREE_MANAGER::instance().SaveAttributeToImage(0, "test.tga", g_pkMapSectree);
  690. snprintf(szFilename, sizeof(szFilename), "%s/server_attr", c_pszMapDirectory);
  691. FILE * fp = fopen(szFilename, "wb");
  692. if (!fp)
  693. {
  694. sys_err("cannot open %s for writing", szFilename);
  695. return;
  696. }
  697. iMapWidth *= 4;
  698. iMapHeight *= 4;
  699. fwrite(&iMapWidth, sizeof(int), 1, fp);
  700. fwrite(&iMapHeight, sizeof(int), 1, fp);
  701. unsigned int uiBlockSize = sizeof(DWORD) * (SECTREE_SIZE / CELL_SIZE) * (SECTREE_SIZE / CELL_SIZE);
  702. unsigned int uiMemSize = iMapWidth * iMapHeight;
  703. unsigned int uiCompSize;
  704. printf("Attribute size: %u block %u\n", uiMemSize, uiBlockSize);
  705. char * pAttr = (char *) malloc(LZOManager::instance().GetMaxCompressedSize(sizeof(DWORD) * (SECTREE_SIZE / CELL_SIZE) * (SECTREE_SIZE / CELL_SIZE)));
  706. for (y = 0; y < iMapHeight; ++y)
  707. for (x = 0; x < iMapWidth; ++x)
  708. {
  709. SECTREEID id;
  710. id.coord.x = x+bx;
  711. id.coord.y = y+by;
  712. LPSECTREE pSec = g_pkMapSectree->Find(id.package);
  713. LZOManager::instance().Compress((unsigned char *) pSec->GetAttributePtr()->GetDataPtr(),
  714. uiBlockSize,
  715. (unsigned char *) pAttr,
  716. &uiCompSize);
  717. fwrite(&uiCompSize, sizeof(int), 1, fp);
  718. fwrite(pAttr, sizeof(char), uiCompSize, fp);
  719. }
  720. fclose(fp);
  721. free(pAttr);
  722. }
  723. void ConvertAttribute2(const char * filename)
  724. {
  725. std::string newFileName = std::string(filename) + ".new";
  726. FILE * fp = fopen(filename, "rb");
  727. FILE * wfp = fopen(newFileName.c_str(), "wb");
  728. if (!fp)
  729. {
  730. printf("cannot open %s\n", filename);
  731. return;
  732. }
  733. if (!wfp)
  734. {
  735. printf("cannot open %s\n", newFileName.c_str());
  736. return;
  737. }
  738. unsigned int uiSize;
  739. unsigned int uiDestSize;
  740. size_t maxMemSize = LZOManager::instance().GetMaxCompressedSize(sizeof(DWORD) * (SECTREE_SIZE / CELL_SIZE) * (SECTREE_SIZE / CELL_SIZE));
  741. BYTE abComp[maxMemSize];
  742. DWORD * attr = M2_NEW DWORD[maxMemSize];
  743. int iWidth, iHeight;
  744. fread(&iWidth, sizeof(int), 1, fp);
  745. fread(&iHeight, sizeof(int), 1, fp);
  746. fwrite(&iWidth, sizeof(int), 1, wfp);
  747. fwrite(&iHeight, sizeof(int), 1, wfp);
  748. printf("width %d height %d\n", iWidth, iHeight);
  749. sleep(1);
  750. for (int y = 0; y < iHeight; ++y)
  751. for (int x = 0; x < iWidth; ++x)
  752. {
  753. fread(&uiSize, sizeof(int), 1, fp);
  754. fread(abComp, sizeof(char), uiSize, fp);
  755. printf("orig_size %d ", uiSize);
  756. uiDestSize = sizeof(DWORD) * maxMemSize;
  757. LZOManager::instance().Decompress(abComp, uiSize, (BYTE *) attr, &uiDestSize);
  758. if (uiDestSize != sizeof(DWORD) * (SECTREE_SIZE / CELL_SIZE) * (SECTREE_SIZE / CELL_SIZE))
  759. {
  760. printf("SECTREE_MANAGER::LoadAttribte: %s: size mismatch! %d\n", filename, uiDestSize);
  761. fclose(fp);
  762. M2_DELETE_ARRAY(attr);
  763. continue;
  764. }
  765. bool found = false;
  766. for (int i = 0; i < (SECTREE_SIZE / CELL_SIZE) * (SECTREE_SIZE / CELL_SIZE); ++i)
  767. if (IS_SET(attr[i], 0xFFFFFFF8))
  768. {
  769. if (!found)
  770. {
  771. printf("!!! ");
  772. found = true;
  773. }
  774. REMOVE_BIT(attr[i], 0xFFFFFFF8);
  775. }
  776. LZOManager::instance().Compress((unsigned char *) attr, uiDestSize, abComp, &uiDestSize);
  777. printf("new_size %d\n", uiDestSize);
  778. fwrite(&uiDestSize, sizeof(int), 1, wfp);
  779. fwrite(abComp, uiDestSize, 1, wfp);
  780. }
  781. fclose(fp);
  782. fclose(wfp);
  783. }