Advertisement
Guest User

Untitled

a guest
Jan 17th, 2016
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 200.03 KB | None | 0 0
  1. /************************************************************************
  2. Tethealla Login Server
  3. Copyright (C) 2008 Terry Chatman Jr.
  4.  
  5. This program is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License version 3 as
  7. published by the Free Software Foundation.
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. ************************************************************************/
  17.  
  18.  
  19. // Notes:
  20. //
  21. // - Limit to 40 guild cards for now.
  22. //
  23.  
  24. #define NO_SQL
  25. #define NO_CONNECT_TEST
  26.  
  27. #define SOCKET_ERROR -1
  28.  
  29. //#include <windows.h>
  30. #include <sys/select.h>
  31. #include <sys/socket.h>
  32. #include <netinet/in.h>
  33. #include <netinet/ip.h>
  34. #include <netdb.h>
  35.  
  36. #include <stdarg.h>
  37.  
  38. #include <stdlib.h>
  39.  
  40. #include <errno.h>
  41.  
  42. #include <stdio.h>
  43. #include <string.h>
  44. #include <time.h>
  45.  
  46. #ifndef NO_SQL
  47. #include <mysql.h>
  48. #endif
  49. #include <md5.h>
  50.  
  51. #include "resource.h"
  52. #include "pso_crypt.h"
  53. #include "bbtable.h"
  54. #include "prs.cpp"
  55.  
  56. #define max(a,b) (a>b?a:b)
  57.  
  58. #define tchar char
  59.  
  60. /* The Itoa code is in the puiblic domain */
  61. char *_itoa(int value, char* str, int radix) {
  62. static char dig[] =
  63. "0123456789"
  64. "abcdefghijklmnopqrstuvwxyz";
  65. int n = 0, neg = 0;
  66. unsigned int v;
  67. char* p, *q;
  68. char c;
  69. if (radix == 10 && value < 0) {
  70. value = -value;
  71. neg = 1;
  72. }
  73. v = value;
  74. do {
  75. str[n++] = dig[v%radix];
  76. v /= radix;
  77. } while (v);
  78. if (neg)
  79. str[n++] = '-';
  80. str[n] = '\0';
  81. for (p = str, q = p + n/2; p != q; ++p, --q)
  82. c = *p, *p = *q, *q = c;
  83. return str;
  84. }
  85.  
  86. void _strupr(char *p)
  87. {
  88. while(*p)
  89. {
  90. *p=toupper(p);
  91. p++;
  92. }
  93. }
  94.  
  95. #define MAX_SIMULTANEOUS_CONNECTIONS 6
  96. #define LOGIN_COMPILED_MAX_CONNECTIONS 300
  97. #define SHIP_COMPILED_MAX_CONNECTIONS 50
  98. #define MAX_EB02 800000
  99. #define SERVER_VERSION "0.048"
  100. #define MAX_ACCOUNTS 2000
  101. #define MAX_DRESS_FLAGS 500
  102. #define DRESS_FLAG_EXPIRY 7200
  103.  
  104. const char *PSO_CLIENT_VER_STRING = "TethVer12510";
  105. #define PSO_CLIENT_VER 0x41
  106.  
  107. //#define USEADDR_ANY
  108. #define DEBUG_OUTPUT
  109. #define TCP_BUFFER_SIZE 64000
  110. #define PACKET_BUFFER_SIZE ( TCP_BUFFER_SIZE * 16 )
  111.  
  112. #define SEND_PACKET_03 0x00 // Done
  113. #define SEND_PACKET_E6 0x01 // Done
  114. #define SEND_PACKET_E2 0x02 // Done
  115. #define SEND_PACKET_E5 0x03 // Done
  116. #define SEND_PACKET_E8 0x04 // Done
  117. #define SEND_PACKET_DC 0x05 // Done
  118. #define SEND_PACKET_EB 0x06 // Done
  119. #define SEND_PACKET_E4 0x07 // Done
  120. #define SEND_PACKET_B1 0x08
  121. #define SEND_PACKET_A0 0x09
  122. #define RECEIVE_PACKET_93 0x0A
  123. #define MAX_SENDCHECK 0x0B
  124.  
  125. #define CLASS_HUMAR 0x00
  126. #define CLASS_HUNEWEARL 0x01
  127. #define CLASS_HUCAST 0x02
  128. #define CLASS_RAMAR 0x03
  129. #define CLASS_RACAST 0x04
  130. #define CLASS_RACASEAL 0x05
  131. #define CLASS_FOMARL 0x06
  132. #define CLASS_FONEWM 0x07
  133. #define CLASS_FONEWEARL 0x08
  134. #define CLASS_HUCASEAL 0x09
  135. #define CLASS_FOMAR 0x0A
  136. #define CLASS_RAMARL 0x0B
  137. #define CLASS_MAX 0x0C
  138.  
  139. struct timeval select_timeout = {
  140. 0,
  141. 5000
  142. };
  143.  
  144. /* functions */
  145.  
  146. void send_to_server(int sock, char* packet);
  147. int receive_from_server(int sock, char* packet);
  148. void debug(char *fmt, ...);
  149. void debug_perror(char * msg);
  150. void tcp_listen (int sockfd);
  151. int tcp_accept (int sockfd, struct sockaddr *client_addr, int *addr_len );
  152. int tcp_sock_connect(char* dest_addr, int port);
  153. int tcp_sock_open(struct in_addr ip, int port);
  154.  
  155. /* Ship Packets */
  156.  
  157. unsigned char ShipPacket00[] = {
  158. 0x00, 0x00, 0x3F, 0x01, 0x03, 0x04, 0x19, 0x55, 0x54, 0x65, 0x74, 0x68, 0x65, 0x61, 0x6C, 0x6C,
  159. 0x61, 0x20, 0x4C, 0x6F, 0x67, 0x69, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  160. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  161. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  162. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  163. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  164. };
  165.  
  166. /* Start Encryption Packet */
  167.  
  168. unsigned char Packet03[] = {
  169. 0xC8, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x68, 0x61, 0x6E, 0x74, 0x61, 0x73, 0x79,
  170. 0x20, 0x53, 0x74, 0x61, 0x72, 0x20, 0x4F, 0x6E, 0x6C, 0x69, 0x6E, 0x65, 0x20, 0x42, 0x6C, 0x75,
  171. 0x65, 0x20, 0x42, 0x75, 0x72, 0x73, 0x74, 0x20, 0x47, 0x61, 0x6D, 0x65, 0x20, 0x53, 0x65, 0x72,
  172. 0x76, 0x65, 0x72, 0x2E, 0x20, 0x43, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x31,
  173. 0x39, 0x39, 0x39, 0x2D, 0x32, 0x30, 0x30, 0x34, 0x20, 0x53, 0x4F, 0x4E, 0x49, 0x43, 0x54, 0x45,
  174. 0x41, 0x4D, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  175. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  176. 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  177. 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
  178. 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  179. 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
  180. 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
  181. 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30
  182. };
  183.  
  184. const unsigned char Message03[] = { "Tethealla Gate v.047" };
  185.  
  186.  
  187. /* Server Redirect */
  188.  
  189. const unsigned char Packet19[] = {
  190. 0x10, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  191. };
  192.  
  193.  
  194. /* Login message */
  195.  
  196. const unsigned char Packet1A[] = {
  197. 0x00, 0x00, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x45, 0x00
  198. };
  199.  
  200. /* Ping pong */
  201.  
  202. const unsigned char Packet1D[] = {
  203. 0x08, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00
  204. };
  205.  
  206. /* Current time */
  207.  
  208. const unsigned char PacketB1[] = {
  209. 0x24, 0x00, 0xB1, 0x00, 0x00, 0x00, 0x00, 0x00
  210. };
  211.  
  212. /* Guild Card Data */
  213.  
  214. unsigned char PacketDC01[0x14] = {0};
  215. unsigned char PacketDC02[0x10] = {0};
  216. unsigned char PacketDC_Check[54672] = {0};
  217.  
  218. /* No Character Header */
  219.  
  220. unsigned char PacketE4[0x10] = { 0 };
  221.  
  222.  
  223. /* Character Header */
  224.  
  225. unsigned char PacketE5[0x88] = { 0 };
  226.  
  227. /* Security Packet */
  228.  
  229. const unsigned char PacketE6[] = {
  230. 0x44, 0x00, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
  231. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3F, 0x71, 0x8D, 0x34, 0x37, 0x7A, 0xBD,
  232. 0x67, 0x39, 0x65, 0x6B, 0x2C, 0xB1, 0xA5, 0x7C, 0x17, 0x93, 0x93, 0x29, 0x4A, 0x90, 0xE9, 0x11,
  233. 0xB8, 0xB5, 0x0E, 0x77, 0x41, 0x30, 0x9B, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  234. 0x01, 0x01, 0x00, 0x00
  235. };
  236.  
  237. /* Acknowledging client's expected checksum */
  238.  
  239. const unsigned char PacketE8[] = {
  240. 0x0C, 0x00, 0xE8, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00
  241. };
  242.  
  243. /* The "Top Broadcast" Packet */
  244.  
  245. const unsigned char PacketEE[] = {
  246. 0x00, 0x00, 0xEE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  247. };
  248.  
  249. unsigned char E2_Base[2808] = { 0 };
  250. unsigned char PacketE2Data[2808] = { 0 };
  251.  
  252. /* String sent to server to retrieve IP address. */
  253.  
  254. char* HTTP_REQ = "GET http://www.pioneer2.net/remote.php HTTP/1.0\r\n\r\n\r\n";
  255.  
  256. /* Populated by load_config_file(): */
  257.  
  258. char mySQL_Host[255] = {0};
  259. char mySQL_Username[255] = {0};
  260. char mySQL_Password[255] = {0};
  261. char mySQL_Database[255] = {0};
  262. unsigned int mySQL_Port;
  263. unsigned char serverIP[4];
  264. unsigned short serverPort;
  265. int override_on = 0;
  266. unsigned char overrideIP[4];
  267. unsigned short serverMaxConnections;
  268. unsigned short serverMaxShips;
  269. unsigned serverNumConnections = 0;
  270. unsigned serverConnectionList[LOGIN_COMPILED_MAX_CONNECTIONS];
  271. unsigned serverNumShips = 0;
  272. unsigned serverShipList[SHIP_COMPILED_MAX_CONNECTIONS];
  273. unsigned quest_numallows;
  274. unsigned* quest_allow;
  275. unsigned max_ship_keys = 0;
  276.  
  277. /* Rare table structure */
  278.  
  279. unsigned rt_tables_ep1[0x200 * 10 * 4] = {0};
  280. unsigned rt_tables_ep2[0x200 * 10 * 4] = {0};
  281. unsigned rt_tables_ep4[0x200 * 10 * 4] = {0};
  282.  
  283. unsigned mob_rate[8]; // rare appearance rate
  284.  
  285. char Welcome_Message[255] = {0};
  286. time_t servertime;
  287.  
  288. #ifndef NO_SQL
  289.  
  290. MYSQL * myData;
  291. char myQuery[0x10000] = {0};
  292. MYSQL_ROW myRow ;
  293. MYSQL_RES * myResult;
  294.  
  295. #endif
  296.  
  297. //#define NO_ALIGN __declspec(align(1))
  298. #define NO_ALIGN __attribute__((aligned(1)))
  299.  
  300. /* Mag data structure */
  301.  
  302. typedef struct NO_ALIGN st_mag
  303. {
  304. unsigned char two; // "02" =P
  305. unsigned char mtype;
  306. unsigned char level;
  307. unsigned char blasts;
  308. short defense;
  309. short power;
  310. short dex;
  311. short mind;
  312. unsigned itemid;
  313. char synchro;
  314. unsigned char IQ;
  315. unsigned char PBflags;
  316. unsigned char color;
  317. } MAG;
  318.  
  319.  
  320. /* Character Data Structure */
  321.  
  322. typedef struct NO_ALIGN st_minichar {
  323. unsigned short packetSize; // 0x00 - 0x01
  324. unsigned short command; // 0x02 - 0x03
  325. unsigned char flags[4]; // 0x04 - 0x07
  326. unsigned char unknown[8]; // 0x08 - 0x0F
  327. unsigned short level; // 0x10 - 0x11
  328. unsigned short reserved; // 0x12 - 0x13
  329. char gcString[10]; // 0x14 - 0x1D
  330. unsigned char unknown2[14]; // 0x1E - 0x2B
  331. unsigned char nameColorBlue; // 0x2C
  332. unsigned char nameColorGreen; // 0x2D
  333. unsigned char nameColorRed; // 0x2E
  334. unsigned char nameColorTransparency; // 0x2F
  335. unsigned short skinID; // 0x30 - 0x31
  336. unsigned char unknown3[18]; // 0x32 - 0x43
  337. unsigned char sectionID; // 0x44
  338. unsigned char _class; // 0x45
  339. unsigned char skinFlag; // 0x46
  340. unsigned char unknown4[5]; // 0x47 - 0x4B (same as unknown5 in E7)
  341. unsigned short costume; // 0x4C - 0x4D
  342. unsigned short skin; // 0x4E - 0x4F
  343. unsigned short face; // 0x50 - 0x51
  344. unsigned short head; // 0x52 - 0x53
  345. unsigned short hair; // 0x54 - 0x55
  346. unsigned short hairColorRed; // 0x56 - 0x57
  347. unsigned short hairColorBlue; // 0x58 - 0x59
  348. unsigned short hairColorGreen; // 0x5A - 0x5B
  349. unsigned proportionX; // 0x5C - 0x5F
  350. unsigned proportionY; // 0x60 - 0x63
  351. unsigned char name[24]; // 0x64 - 0x7B
  352. unsigned char unknown5[8] ; // 0x7C - 0x83
  353. unsigned playTime;
  354. } MINICHAR;
  355.  
  356. //packetSize = 0x399C;
  357. //command = 0x00E7;
  358.  
  359. typedef struct NO_ALIGN st_bank_item {
  360. unsigned char data[12]; // the standard $setitem1 - $setitem3 fare
  361. unsigned itemid; // player item id
  362. unsigned char data2[4]; // $setitem4 (mag use only)
  363. unsigned bank_count; // Why?
  364. } BANK_ITEM;
  365.  
  366. typedef struct NO_ALIGN st_bank {
  367. unsigned bankUse;
  368. unsigned bankMeseta;
  369. BANK_ITEM bankInventory [200];
  370. } BANK;
  371.  
  372. typedef struct NO_ALIGN st_item {
  373. unsigned char data[12]; // the standard $setitem1 - $setitem3 fare
  374. unsigned itemid; // player item id
  375. unsigned char data2[4]; // $setitem4 (mag use only)
  376. } ITEM;
  377.  
  378. typedef struct NO_ALIGN st_inventory {
  379. unsigned in_use; // 0x01 = item slot in use, 0xFF00 = unused
  380. unsigned flags; // 8 = equipped
  381. ITEM item;
  382. } INVENTORY;
  383.  
  384. typedef struct NO_ALIGN st_chardata {
  385. unsigned short packetSize; // 0x00-0x01 // Always set to 0x399C
  386. unsigned short command; // 0x02-0x03 // // Always set to 0x00E7
  387. unsigned char flags[4]; // 0x04-0x07
  388. unsigned char inventoryUse; // 0x08
  389. unsigned char HPuse; // 0x09
  390. unsigned char TPuse; // 0x0A
  391. unsigned char lang; // 0x0B
  392. INVENTORY inventory[30]; // 0x0C-0x353
  393. unsigned short ATP; // 0x354-0x355
  394. unsigned short MST; // 0x356-0x357
  395. unsigned short EVP; // 0x358-0x359
  396. unsigned short HP; // 0x35A-0x35B
  397. unsigned short DFP; // 0x35C-0x35D
  398. unsigned short TP; // 0x35E-0x35F
  399. unsigned short LCK; // 0x360-0x361
  400. unsigned short ATA; // 0x362-0x363
  401. unsigned char unknown[8]; // 0x364-0x36B (Offset 0x360 has 0x0A value on Schthack's...)
  402. unsigned short level; // 0x36C-0x36D;
  403. unsigned short unknown2; // 0x36E-0x36F;
  404. unsigned XP; // 0x370-0x373
  405. unsigned meseta; // 0x374-0x377;
  406. char gcString[10]; // 0x378-0x381;
  407. unsigned char unknown3[14]; // 0x382-0x38F; // Same as E5 unknown2
  408. unsigned char nameColorBlue; // 0x390;
  409. unsigned char nameColorGreen; // 0x391;
  410. unsigned char nameColorRed; // 0x392;
  411. unsigned char nameColorTransparency; // 0x393;
  412. unsigned short skinID; // 0x394-0x395;
  413. unsigned char unknown4[18]; // 0x396-0x3A7
  414. unsigned char sectionID; // 0x3A8;
  415. unsigned char _class; // 0x3A9;
  416. unsigned char skinFlag; // 0x3AA;
  417. unsigned char unknown5[5]; // 0x3AB-0x3AF; // Same as E5 unknown4.
  418. unsigned short costume; // 0x3B0 - 0x3B1;
  419. unsigned short skin; // 0x3B2 - 0x3B3;
  420. unsigned short face; // 0x3B4 - 0x3B5;
  421. unsigned short head; // 0x3B6 - 0x3B7;
  422. unsigned short hair; // 0x3B8 - 0x3B9;
  423. unsigned short hairColorRed; // 0x3BA-0x3BB;
  424. unsigned short hairColorBlue; // 0x3BC-0x3BD;
  425. unsigned short hairColorGreen; // 0x3BE-0x3BF;
  426. unsigned proportionX; // 0x3C0-0x3C3;
  427. unsigned proportionY; // 0x3C4-0x3C7;
  428. unsigned char name[24]; // 0x3C8-0x3DF;
  429. unsigned playTime; // 0x3E0 - 0x3E3
  430. unsigned char unknown6[4]; // 0x3E4 - 0x3E7;
  431. unsigned char keyConfig[232]; // 0x3E8 - 0x4CF;
  432. // Stored from ED 07 packet.
  433. unsigned char techniques[20]; // 0x4D0 - 0x4E3;
  434. unsigned char unknown7[16]; // 0x4E4 - 0x4F3;
  435. unsigned char options[4]; // 0x4F4-0x4F7;
  436. // Stored from ED 01 packet.
  437. unsigned char unknown8[520]; // 0x4F8 - 0x6FF;
  438. unsigned bankUse; // 0x700 - 0x703
  439. unsigned bankMeseta; // 0x704 - 0x707;
  440. BANK_ITEM bankInventory [200]; // 0x708 - 0x19C7
  441. unsigned guildCard; // 0x19C8-0x19CB;
  442. // Stored from E8 06 packet.
  443. unsigned char name2[24]; // 0x19CC - 0x19E3;
  444. unsigned char unknown9[232]; // 0x19E4-0x1ACB;
  445. unsigned char reserved1; // 0x1ACC; // Has value 0x01 on Schthack's
  446. unsigned char reserved2; // 0x1ACD; // Has value 0x01 on Schthack's
  447. unsigned char sectionID2; // 0x1ACE;
  448. unsigned char _class2; // 0x1ACF;
  449. unsigned char unknown10[4]; // 0x1AD0-0x1AD3;
  450. unsigned char symbol_chats[1248]; // 0x1AD4 - 0x1FB3
  451. // Stored from ED 02 packet.
  452. unsigned char shortcuts[2624]; // 0x1FB4 - 0x29F3
  453. // Stored from ED 03 packet.
  454. unsigned char unknown11[344]; // 0x29F4 - 0x2B4B;
  455. unsigned char GCBoard[172]; // 0x2B4C - 0x2BF7;
  456. unsigned char unknown12[200]; // 0x2BF8 - 0x2CBF;
  457. unsigned char challengeData[320]; // 0x2CC0 - 0X2DFF
  458. unsigned char unknown13[172]; // 0x2E00 - 0x2EAB;
  459. unsigned char unknown14[276]; // 0x2EAC - 0x2FBF; // I don't know what this is, but split from unknown13 because this chunk is
  460. // actually copied into the 0xE2 packet during login @ 0x08
  461. unsigned char keyConfigGlobal[364]; // 0x2FC0 - 0x312B // Copied into 0xE2 login packet @ 0x11C
  462. // Stored from ED 04 packet.
  463. unsigned char joyConfigGlobal[56]; // 0x312C - 0x3163 // Copied into 0xE2 login packet @ 0x288
  464. // Stored from ED 05 packet.
  465. unsigned guildCard2; // 0x3164 - 0x3167 (From here on copied into 0xE2 login packet @ 0x2C0...)
  466. unsigned teamID; // 0x3168 - 0x316B
  467. unsigned char teamInformation[8]; // 0x316C - 0x3173 (usually blank...)
  468. unsigned short privilegeLevel; // 0x3174 - 0x3175
  469. unsigned short reserved3; // 0x3176 - 0x3177
  470. unsigned char teamName[28]; // 0x3178 - 0x3193
  471. unsigned unknown15; // 0x3194 - 0x3197
  472. unsigned char teamFlag[2048]; // 0x3198 - 0x3997
  473. unsigned char teamRewards[8]; // 0x3998 - 0x39A0
  474. } CHARDATA;
  475.  
  476.  
  477. /* Player Structure */
  478.  
  479. typedef struct st_banana {
  480. int plySockfd;
  481. int login;
  482. unsigned char peekbuf[8];
  483. unsigned char rcvbuf [TCP_BUFFER_SIZE];
  484. unsigned short rcvread;
  485. unsigned short expect;
  486. unsigned char decryptbuf [TCP_BUFFER_SIZE];
  487. unsigned char sndbuf [TCP_BUFFER_SIZE];
  488. unsigned char encryptbuf [TCP_BUFFER_SIZE];
  489. int snddata,
  490. sndwritten;
  491. unsigned char packet [TCP_BUFFER_SIZE];
  492. unsigned short packetdata;
  493. unsigned short packetread;
  494. int crypt_on;
  495. PSO_CRYPT server_cipher, client_cipher;
  496. unsigned guildcard;
  497. char guildcard_string[12];
  498. unsigned char guildcard_data[20000];
  499. int sendingchars;
  500. short slotnum;
  501. unsigned lastTick; // The last second
  502. unsigned toBytesSec; // How many bytes per second the server sends to the client
  503. unsigned fromBytesSec; // How many bytes per second the server receives from the client
  504. unsigned packetsSec; // How many packets per second the server receives from the client
  505. unsigned connected;
  506. unsigned char sendCheck[MAX_SENDCHECK+2];
  507. int todc;
  508. unsigned char IP_Address[16];
  509. char hwinfo[18];
  510. int isgm;
  511. int dress_flag;
  512. unsigned connection_index;
  513. } BANANA;
  514.  
  515. typedef struct st_dressflag {
  516. unsigned guildcard;
  517. unsigned flagtime;
  518. } DRESSFLAG;
  519.  
  520. /* a RC4 expanded key session */
  521. struct rc4_key {
  522. unsigned char state[256];
  523. unsigned x, y;
  524. };
  525.  
  526. /* Ship Structure */
  527.  
  528. typedef struct st_orange {
  529. int shipSockfd;
  530. unsigned char name[13];
  531. unsigned playerCount;
  532. unsigned char shipAddr[5];
  533. unsigned char listenedAddr[4];
  534. unsigned short shipPort;
  535. unsigned char rcvbuf [TCP_BUFFER_SIZE];
  536. unsigned long rcvread;
  537. unsigned long expect;
  538. unsigned char decryptbuf [TCP_BUFFER_SIZE];
  539. unsigned char sndbuf [PACKET_BUFFER_SIZE];
  540. unsigned char encryptbuf [TCP_BUFFER_SIZE];
  541. unsigned char packet [PACKET_BUFFER_SIZE];
  542. unsigned long packetread;
  543. unsigned long packetdata;
  544. int snddata,
  545. sndwritten;
  546. unsigned shipID;
  547. int authed;
  548. int todc;
  549. int crypt_on;
  550. unsigned char user_key[128];
  551. int key_change[128];
  552. unsigned key_index;
  553. struct rc4_key cs_key; // Encryption keys
  554. struct rc4_key sc_key; // Encryption keys
  555. unsigned connection_index;
  556. unsigned connected;
  557. unsigned last_ping;
  558. int sent_ping;
  559. } ORANGE;
  560.  
  561. fd_set ReadFDs, WriteFDs, ExceptFDs;
  562.  
  563. DRESSFLAG dress_flags[MAX_DRESS_FLAGS];
  564. unsigned char dp[TCP_BUFFER_SIZE*4];
  565. unsigned char tmprcv[PACKET_BUFFER_SIZE];
  566. char Packet1AData[TCP_BUFFER_SIZE];
  567. char PacketEEData[TCP_BUFFER_SIZE];
  568. unsigned char PacketEB01[0x4C8*2] = {0};
  569. unsigned char PacketEB02[MAX_EB02] = {0};
  570. unsigned PacketEB01_Total;
  571. unsigned PacketEB02_Total;
  572.  
  573. unsigned keys_in_use [SHIP_COMPILED_MAX_CONNECTIONS+1] = { 0 };
  574.  
  575. #ifdef NO_SQL
  576.  
  577. typedef struct st_bank_file {
  578. unsigned guildcard;
  579. BANK common_bank;
  580. } L_BANK_DATA;
  581.  
  582. typedef struct st_account {
  583. char username[18];
  584. char password[33];
  585. char email[255];
  586. unsigned regtime;
  587. char lastip[16];
  588. long long lasthwinfo;
  589. unsigned guildcard;
  590. int isgm;
  591. int isbanned;
  592. int islogged;
  593. int isactive;
  594. int teamid;
  595. int privlevel;
  596. unsigned char lastchar[24];
  597. } L_ACCOUNT_DATA;
  598.  
  599.  
  600. typedef struct st_character {
  601. unsigned guildcard;
  602. int slot;
  603. CHARDATA data;
  604. MINICHAR header;
  605. } L_CHARACTER_DATA;
  606.  
  607.  
  608. typedef struct st_guild {
  609. unsigned accountid;
  610. unsigned friendid;
  611. char friendname[24];
  612. char friendtext[176];
  613. unsigned short reserved;
  614. unsigned short sectionid;
  615. unsigned short pclass;
  616. unsigned short comment[45];
  617. int priority;
  618. } L_GUILD_DATA;
  619.  
  620.  
  621. typedef struct st_hwbans {
  622. unsigned guildcard;
  623. long long hwinfo;
  624. } L_HW_BANS;
  625.  
  626.  
  627. typedef struct st_ipbans {
  628. unsigned char ipinfo;
  629. } L_IP_BANS;
  630.  
  631.  
  632. typedef struct st_key_data {
  633. unsigned guildcard;
  634. unsigned char controls[420];
  635. } L_KEY_DATA;
  636.  
  637.  
  638. typedef struct st_security_data {
  639. unsigned guildcard;
  640. unsigned thirtytwo;
  641. long long sixtyfour;
  642. int slotnum;
  643. int isgm;
  644. } L_SECURITY_DATA;
  645.  
  646.  
  647. typedef struct st_ship_data {
  648. unsigned char rc4key[128];
  649. unsigned idx;
  650. } L_SHIP_DATA;
  651.  
  652.  
  653. typedef struct st_team_data {
  654. unsigned short name[12];
  655. unsigned owner;
  656. unsigned char flag[2048];
  657. unsigned teamid;
  658. } L_TEAM_DATA;
  659.  
  660. // Oh brother :D
  661.  
  662. L_BANK_DATA *bank_data[MAX_ACCOUNTS];
  663. L_ACCOUNT_DATA *account_data[MAX_ACCOUNTS];
  664. L_CHARACTER_DATA *character_data[MAX_ACCOUNTS*4];
  665. L_GUILD_DATA *guild_data[MAX_ACCOUNTS*40];
  666. L_HW_BANS *hw_bans[MAX_ACCOUNTS];
  667. L_IP_BANS *ip_bans[MAX_ACCOUNTS];
  668. L_KEY_DATA *key_data[MAX_ACCOUNTS];
  669. L_SECURITY_DATA *security_data[MAX_ACCOUNTS];
  670. L_SHIP_DATA *ship_data[SHIP_COMPILED_MAX_CONNECTIONS];
  671. L_TEAM_DATA *team_data[MAX_ACCOUNTS];
  672.  
  673. unsigned num_accounts = 0;
  674. unsigned num_characters = 0;
  675. unsigned num_guilds = 0;
  676. unsigned num_hwbans = 0;
  677. unsigned num_ipbans = 0;
  678. unsigned num_keydata = 0;
  679. unsigned num_bankdata = 0;
  680. unsigned num_security = 0;
  681. unsigned num_shipkeys = 0;
  682. unsigned num_teams = 0;
  683. unsigned ds,ds2;
  684. int ds_found, new_record, free_record;
  685.  
  686. #endif
  687.  
  688. BANK empty_bank;
  689.  
  690. /* encryption stuff */
  691.  
  692. void prepare_key(unsigned char *keydata, unsigned len, struct rc4_key *key);
  693.  
  694. PSO_CRYPT* cipher_ptr;
  695.  
  696. void encryptcopy (BANANA* client, const unsigned char* src, unsigned size);
  697. void decryptcopy (unsigned char* dest, const unsigned char* src, unsigned size);
  698. void compressShipPacket ( ORANGE* ship, unsigned char* src, unsigned long src_size );
  699. void decompressShipPacket ( ORANGE* ship, unsigned char* dest, unsigned char* src );
  700.  
  701. #ifdef NO_SQL
  702.  
  703. void UpdateDataFile ( const char* filename, unsigned count, void* data, unsigned record_size, int new_record );
  704. void DumpDataFile ( const char* filename, unsigned* count, void** data, unsigned record_size );
  705.  
  706. unsigned lastdump = 0;
  707.  
  708. #endif
  709.  
  710. //#define MYWM_NOTIFYICON (WM_USER+2)
  711. //int program_hidden = 1;
  712. //HWND consoleHwnd;
  713. //HWND backupHwnd;
  714.  
  715. void WriteLog(char *fmt, ...)
  716. {
  717. #define MAX_GM_MESG_LEN 4096
  718.  
  719. va_list args;
  720. char text[ MAX_GM_MESG_LEN ];
  721. //SYSTEMTIME rawtime;
  722.  
  723.  
  724. FILE *fp;
  725.  
  726. //GetLocalTime (&rawtime);
  727. va_start (args, fmt);
  728. strcpy (text + vsprintf( text,fmt,args), "\r\n");
  729. va_end (args);
  730.  
  731. fp = fopen ( "login.log", "a");
  732. if (!fp)
  733. {
  734. printf ("Unable to log to login.log\n");
  735. }
  736.  
  737. fprintf (fp, "%s", text);
  738. fclose (fp);
  739.  
  740. printf ("%s", text);
  741. }
  742.  
  743.  
  744. void display_packet ( unsigned char* buf, int len )
  745. {
  746. int c, c2, c3, c4;
  747.  
  748. c = c2 = c3 = c4 = 0;
  749.  
  750. for (c=0;c<len;c++)
  751. {
  752. if (c3==16)
  753. {
  754. for (;c4<c;c4++)
  755. if (buf[c4] >= 0x20)
  756. dp[c2++] = buf[c4];
  757. else
  758. dp[c2++] = 0x2E;
  759. c3 = 0;
  760. sprintf (&dp[c2++], "\n" );
  761. }
  762.  
  763. if ((c == 0) || !(c % 16))
  764. {
  765. sprintf (&dp[c2], "(%04X) ", c);
  766. c2 += 7;
  767. }
  768.  
  769. sprintf (&dp[c2], "%02X ", buf[c]);
  770. c2 += 3;
  771. c3++;
  772. }
  773.  
  774. if ( len % 16 )
  775. {
  776. c3 = len;
  777. while (c3 % 16)
  778. {
  779. sprintf (&dp[c2], " ");
  780. c2 += 3;
  781. c3++;
  782. }
  783. }
  784.  
  785. for (;c4<c;c4++)
  786. if (buf[c4] >= 0x20)
  787. dp[c2++] = buf[c4];
  788. else
  789. dp[c2++] = 0x2E;
  790.  
  791. dp[c2] = 0;
  792. printf ("%s\n\n", &dp[0]);
  793. }
  794.  
  795. /* Computes the message digest for string inString.
  796. Prints out message digest, a space, the string (in quotes) and a
  797. carriage return.
  798. */
  799. void MDString (inString, outString)
  800. char *inString;
  801. char *outString;
  802. {
  803. unsigned char c;
  804. MD5_CTX mdContext;
  805. unsigned int len = strlen (inString);
  806.  
  807. MD5Init (&mdContext);
  808. MD5Update (&mdContext, inString, len);
  809. MD5Final (&mdContext);
  810. for (c=0;c<16;c++)
  811. {
  812. *outString = mdContext.digest[c];
  813. outString++;
  814. }
  815. }
  816.  
  817. void convertIPString (char* IPData, unsigned IPLen, int fromConfig )
  818. {
  819. unsigned p,p2,p3;
  820. char convert_buffer[5];
  821.  
  822. p2 = 0;
  823. p3 = 0;
  824. for (p=0;p<IPLen;p++)
  825. {
  826. if ((IPData[p] > 0x20) && (IPData[p] != 46))
  827. convert_buffer[p3++] = IPData[p]; else
  828. {
  829. convert_buffer[p3] = 0;
  830. if (IPData[p] == 46) // .
  831. {
  832. serverIP[p2] = atoi (&convert_buffer[0]);
  833. p2++;
  834. p3 = 0;
  835. if (p2>3)
  836. {
  837. if (fromConfig)
  838. printf ("tethealla.ini is corrupted. (Failed to read IP information from file!)\n"); else
  839. printf ("Failed to determine IP address.\n");
  840. printf ("Hit [ENTER]");
  841. gets (&dp[0]);
  842. exit (1);
  843. }
  844. }
  845. else
  846. {
  847. serverIP[p2] = atoi (&convert_buffer[0]);
  848. if (p2 != 3)
  849. {
  850. if (fromConfig)
  851. printf ("tethealla.ini is corrupted. (Failed to read IP information from file!)\n"); else
  852. printf ("Failed to determine IP address.\n");
  853. printf ("Hit [ENTER]");
  854. gets (&dp[0]);
  855. exit (1);
  856. }
  857. break;
  858. }
  859. }
  860. }
  861. }
  862.  
  863. long CalculateChecksum(void* data,unsigned long size)
  864. {
  865. long offset,y,cs = 0xFFFFFFFF;
  866. for (offset = 0; offset < (long)size; offset++)
  867. {
  868. cs ^= *(unsigned char*)((long)data + offset);
  869. for (y = 0; y < 8; y++)
  870. {
  871. if (!(cs & 1)) cs = (cs >> 1) & 0x7FFFFFFF;
  872. else cs = ((cs >> 1) & 0x7FFFFFFF) ^ 0xEDB88320;
  873. }
  874. }
  875. return (cs ^ 0xFFFFFFFF);
  876. }
  877.  
  878. unsigned char EBBuffer [0x10000];
  879.  
  880. void construct0xEB()
  881. {
  882. char EBFiles[16][255];
  883. unsigned EBSize;
  884. unsigned EBOffset = 0;
  885. unsigned EBChecksum;
  886. FILE* fp;
  887. FILE* fpb;
  888. unsigned char ch, ch6;
  889. unsigned ch2, ch3, ch4, ch5, ch7;
  890.  
  891. if ( ( fp = fopen ("e8send.txt", "r" ) ) == NULL )
  892. {
  893. printf ("Missing e8send.txt\n");
  894. printf ("Hit [ENTER]");
  895. gets (&dp[0]);
  896. exit (1);
  897. }
  898. PacketEB01[0x02] = 0xEB;
  899. PacketEB01[0x03] = 0x01;
  900. ch = ch6 = 0;
  901. ch3 = 0x08;
  902. ch4 = ch5 = 0x00;
  903. while ( fgets ( &EBFiles[ch][0], 255, fp ) != NULL )
  904. {
  905. ch2 = strlen (&EBFiles[ch][0]);
  906. if (EBFiles[ch][ch2-1] == 0x0A)
  907. EBFiles[ch][ch2--] = 0x00;
  908. EBFiles[ch][ch2] = 0;
  909. printf ("\nLoading data from %s ... ", &EBFiles[ch][0]);
  910. if ( ( fpb = fopen (&EBFiles[ch][0], "rb") ) == NULL )
  911. {
  912. printf ("Could not open %s!\n", &EBFiles[ch][0]);
  913. printf ("Hit [ENTER]");
  914. gets (&dp[0]);
  915. exit (1);
  916. }
  917. fseek (fpb, 0, SEEK_END);
  918. EBSize = ftell (fpb);
  919. fseek (fpb, 0, SEEK_SET);
  920. fread (&EBBuffer[0], 1, EBSize, fpb);
  921. EBChecksum = (unsigned) CalculateChecksum(&EBBuffer[0], EBSize);
  922. *(unsigned *) &PacketEB01[ch3] = EBSize;
  923. ch3 += 4;
  924. *(unsigned *) &PacketEB01[ch3] = EBChecksum;
  925. ch3 += 4;
  926. *(unsigned *) &PacketEB01[ch3] = EBOffset;
  927. ch3 += 4;
  928. memcpy (&PacketEB01[ch3], &EBFiles[ch][0], ch2+1 );
  929. ch3 += 0x40;
  930. EBOffset += EBSize;
  931. ch++;
  932. fclose ( fpb );
  933. for (ch7=0;ch7<EBSize;ch7++)
  934. {
  935. if (ch4 == 0x00)
  936. {
  937. ch5 += 2;
  938. PacketEB02[ch5++] = 0xEB;
  939. PacketEB02[ch5++] = 0x02;
  940. ch5 += 4;
  941. PacketEB02[ch5++] = ch6;
  942. ch5 += 3;
  943. ch4 = 0x0C;
  944. }
  945. PacketEB02[ch5++] = EBBuffer[ch7];
  946. ch4++;
  947. if (ch4 == 26636)
  948. {
  949. *(unsigned short*) &PacketEB02[ch5 - 26636] = (unsigned short) ch4;
  950. ch4 = 0;
  951. ch6++;
  952. }
  953. }
  954. }
  955.  
  956. if ( ch4 ) // Probably have some remaining data.
  957. {
  958. *(unsigned short*)&PacketEB02 [ch5 - ch4] = (unsigned short) ch4;
  959. PacketEB02_Total = ch5;
  960. if (ch5 > MAX_EB02)
  961. {
  962. printf ("Too much patch data to send.\n");
  963. printf ("Hit [ENTER]");
  964. gets (&dp[0]);
  965. exit (1);
  966. }
  967. }
  968.  
  969. *(unsigned short*) &PacketEB01[0x00] = (unsigned short) ch3;
  970. PacketEB01[0x04] = ch;
  971. PacketEB01_Total = ch3;
  972. fclose ( fp );
  973. }
  974.  
  975. unsigned normalName = 0xFFFFFFFF;
  976. unsigned globalName = 0xFF1D94F7;
  977. unsigned localName = 0xFFB0C4DE;
  978.  
  979. unsigned char hexToByte ( char* hs )
  980. {
  981. unsigned b;
  982.  
  983. if ( hs[0] < 58 ) b = (hs[0] - 48); else b = (hs[0] - 55);
  984. b *= 16;
  985. if ( hs[1] < 58 ) b += (hs[1] - 48); else b += (hs[1] - 55);
  986. return (unsigned char) b;
  987. }
  988.  
  989. void load_config_file()
  990. {
  991. int config_index = 0;
  992. unsigned char config_data[255];
  993. unsigned ch;
  994.  
  995. FILE* fp;
  996.  
  997. if ( ( fp = fopen ("tethealla.ini", "r" ) ) == NULL )
  998. {
  999. printf ("The configuration file tethealla.ini appears to be missing.\n");
  1000. printf ("Hit [ENTER]");
  1001. gets (&dp[0]);
  1002. exit (1);
  1003. }
  1004. else
  1005. while (fgets (&config_data[0], 255, fp) != NULL)
  1006. {
  1007. if (config_data[0] != 0x23)
  1008. {
  1009. if ((config_index < 0x04) || (config_index > 0x04))
  1010. {
  1011. ch = strlen (&config_data[0]);
  1012. if (config_data[ch-1] == 0x0A)
  1013. config_data[ch--] = 0x00;
  1014. config_data[ch] = 0;
  1015. }
  1016. switch (config_index)
  1017. {
  1018. case 0x00:
  1019. // MySQL Host
  1020. memcpy (&mySQL_Host[0], &config_data[0], ch+1);
  1021. break;
  1022. case 0x01:
  1023. // MySQL Username
  1024. memcpy (&mySQL_Username[0], &config_data[0], ch+1);
  1025. break;
  1026. case 0x02:
  1027. // MySQL Password
  1028. memcpy (&mySQL_Password[0], &config_data[0], ch+1);
  1029. break;
  1030. case 0x03:
  1031. // MySQL Database
  1032. memcpy (&mySQL_Database[0], &config_data[0], ch+1);
  1033. break;
  1034. case 0x04:
  1035. // MySQL Port
  1036. mySQL_Port = atoi (&config_data[0]);
  1037. break;
  1038. case 0x05:
  1039. // Server IP address
  1040. {
  1041. if ((config_data[0] == 0x41) || (config_data[0] == 0x61))
  1042. {
  1043. struct sockaddr_in pn_in;
  1044. struct hostent *pn_host;
  1045. int pn_sockfd, pn_len;
  1046. char pn_buf[512];
  1047. char* pn_ipdata;
  1048.  
  1049. printf ("\n** Determining IP address ... ");
  1050.  
  1051. pn_host = gethostbyname ( "www.pioneer2.net" );
  1052. if (!pn_host) {
  1053. printf ("Could not resolve www.pioneer2.net\n");
  1054. printf ("Hit [ENTER]");
  1055. gets (&dp[0]);
  1056. exit (1);
  1057. }
  1058.  
  1059. /* Create a reliable, stream socket using TCP */
  1060. if ((pn_sockfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
  1061. {
  1062. printf ("Unable to create TCP/IP streaming socket.");
  1063. printf ("Hit [ENTER]");
  1064. gets (&dp[0]);
  1065. exit(1);
  1066. }
  1067.  
  1068. /* Construct the server address structure */
  1069. memset(&pn_in, 0, sizeof(pn_in)); /* Zero out structure */
  1070. pn_in.sin_family = AF_INET; /* Internet address family */
  1071.  
  1072. *(unsigned*) &pn_in.sin_addr.s_addr = *(unsigned *) pn_host->h_addr; /* Web Server IP address */
  1073.  
  1074. pn_in.sin_port = htons(80); /* Web Server port */
  1075.  
  1076. /* Establish the connection to the pioneer2.net Web Server ... */
  1077.  
  1078. if (connect(pn_sockfd, (struct sockaddr *) &pn_in, sizeof(pn_in)) < 0)
  1079. {
  1080. printf ("\nCannot connect to www.pioneer2.net!");
  1081. printf ("Hit [ENTER]");
  1082. gets (&dp[0]);
  1083. exit(1);
  1084. }
  1085.  
  1086. /* Process pioneer2.net's response into the serverIP variable. */
  1087.  
  1088. send_to_server ( pn_sockfd, HTTP_REQ );
  1089. pn_len = recv(pn_sockfd, &pn_buf[0], sizeof(pn_buf) - 1, 0);
  1090. close(pn_sockfd);
  1091. pn_buf[pn_len] = 0;
  1092. pn_ipdata = strstr (&pn_buf[0], "/html");
  1093. if (!pn_ipdata)
  1094. {
  1095. printf ("Failed to determine IP address.\n");
  1096. }
  1097. else
  1098. pn_ipdata += 9;
  1099.  
  1100. convertIPString (pn_ipdata, strlen (pn_ipdata), 0 );
  1101. }
  1102. else
  1103. {
  1104. convertIPString (&config_data[0], ch+1, 1);
  1105. }
  1106. }
  1107. break;
  1108. case 0x06:
  1109. // Welcome Message
  1110. memcpy (&Welcome_Message[0], &config_data[0], ch+1 );
  1111. break;
  1112. case 0x07:
  1113. // Server Listen Port
  1114. serverPort = atoi (&config_data[0]);
  1115. break;
  1116. case 0x08:
  1117. // Max Client Connections
  1118. serverMaxConnections = atoi (&config_data[0]);
  1119. if ( serverMaxConnections > LOGIN_COMPILED_MAX_CONNECTIONS )
  1120. {
  1121. serverMaxConnections = LOGIN_COMPILED_MAX_CONNECTIONS;
  1122. printf ("This version of the login server has not been compiled to handle more than %u login connections. Adjusted.\n", LOGIN_COMPILED_MAX_CONNECTIONS );
  1123. }
  1124. if (!serverMaxConnections)
  1125. serverMaxConnections = LOGIN_COMPILED_MAX_CONNECTIONS;
  1126. break;
  1127. case 0x09:
  1128. // Max Ship Connections
  1129. serverMaxShips = atoi (&config_data[0]);
  1130. if ( serverMaxShips > SHIP_COMPILED_MAX_CONNECTIONS )
  1131. {
  1132. serverMaxShips = SHIP_COMPILED_MAX_CONNECTIONS;
  1133. printf ("This version of the login server has not been compiled to handle more than %u ship connections. Adjusted.\n", SHIP_COMPILED_MAX_CONNECTIONS );
  1134. }
  1135. if (!serverMaxShips)
  1136. serverMaxShips = SHIP_COMPILED_MAX_CONNECTIONS;
  1137. break;
  1138. case 0x0A:
  1139. // Override IP address (if specified, this IP will be sent out instead of your own to those who connect)
  1140. if ((config_data[0] > 0x30) && (config_data[0] < 0x3A))
  1141. {
  1142. override_on = 1;
  1143. *(unsigned *) &overrideIP[0] = *(unsigned *) &serverIP[0];
  1144. serverIP[0] = 0;
  1145. convertIPString (&config_data[0], ch+1, 1);
  1146. }
  1147. break;
  1148. case 0x0B:
  1149. // Hildebear rate
  1150. mob_rate[0] = atoi ( &config_data[0] );
  1151. break;
  1152. case 0x0C:
  1153. // Rappy rate
  1154. mob_rate[1] = atoi ( &config_data[0] );
  1155. break;
  1156. case 0x0D:
  1157. // Lily rate
  1158. mob_rate[2] = atoi ( &config_data[0] );
  1159. break;
  1160. case 0x0E:
  1161. // Slime rate
  1162. mob_rate[3] = atoi ( &config_data[0] );
  1163. break;
  1164. case 0x0F:
  1165. // Merissa rate
  1166. mob_rate[4] = atoi ( &config_data[0] );
  1167. break;
  1168. case 0x10:
  1169. // Pazuzu rate
  1170. mob_rate[5] = atoi ( &config_data[0] );
  1171. break;
  1172. case 0x11:
  1173. // Dorphon Eclair rate
  1174. mob_rate[6] = atoi ( &config_data[0] );
  1175. break;
  1176. case 0x12:
  1177. // Kondrieu rate
  1178. mob_rate[7] = atoi ( &config_data[0] );
  1179. break;
  1180. case 0x13:
  1181. // Global GM name color
  1182. config_data[6] = hexToByte (&config_data[4]);
  1183. config_data[7] = hexToByte (&config_data[2]);
  1184. config_data[8] = hexToByte (&config_data[0]);
  1185. config_data[9] = 0xFF;
  1186. globalName = *(unsigned *) &config_data[6];
  1187. break;
  1188. case 0x14:
  1189. // Local GM name color
  1190. config_data[6] = hexToByte (&config_data[4]);
  1191. config_data[7] = hexToByte (&config_data[2]);
  1192. config_data[8] = hexToByte (&config_data[0]);
  1193. config_data[9] = 0xFF;
  1194. localName = *(unsigned *) &config_data[6];
  1195. break;
  1196. case 0x15:
  1197. // Normal name color
  1198. config_data[6] = hexToByte (&config_data[4]);
  1199. config_data[7] = hexToByte (&config_data[2]);
  1200. config_data[8] = hexToByte (&config_data[0]);
  1201. config_data[9] = 0xFF;
  1202. normalName = *(unsigned *) &config_data[6];
  1203. break;
  1204. default:
  1205. break;
  1206. }
  1207. config_index++;
  1208. }
  1209. }
  1210. fclose (fp);
  1211.  
  1212. if (config_index < 0x13)
  1213. {
  1214. printf ("tethealla.ini seems to be corrupted.\n");
  1215. printf ("Hit [ENTER]");
  1216. gets (&dp[0]);
  1217. exit (1);
  1218. }
  1219. }
  1220.  
  1221. BANANA * connections[LOGIN_COMPILED_MAX_CONNECTIONS];
  1222. ORANGE * ships[SHIP_COMPILED_MAX_CONNECTIONS];
  1223. BANANA * workConnect;
  1224. ORANGE * workShip;
  1225.  
  1226. unsigned char PacketA0Data[0x4000] = {0};
  1227. unsigned short PacketA0Size = 0;
  1228. const char serverName[] = { "T\0E\0T\0H\0E\0A\0L\0L\0A\0" };
  1229.  
  1230. const char NoShips[9] = "No ships!";
  1231.  
  1232. void construct0xA0()
  1233. {
  1234. ORANGE* shipcheck;
  1235. unsigned totalShips = 0xFFFFFFF4;
  1236. unsigned short A0Offset;
  1237. char* shipName;
  1238. unsigned char playerCountString[5];
  1239. unsigned ch, ch2, shipNum;
  1240.  
  1241. memset (&PacketA0Data[0], 0, 0x4000);
  1242.  
  1243. PacketA0Data[0x02] = 0xA0;
  1244. PacketA0Data[0x0A] = 0x20;
  1245. *(unsigned *) &PacketA0Data[0x0C] = totalShips;
  1246. PacketA0Data[0x10] = 0x04;
  1247. memcpy (&PacketA0Data[0x12], &serverName[0], 18 );
  1248. A0Offset = 0x36;
  1249. totalShips = 0x00;
  1250. for (ch=0;ch<serverNumShips;ch++)
  1251. {
  1252. shipNum = serverShipList[ch];
  1253. if (ships[shipNum])
  1254. {
  1255. shipcheck = ships[shipNum];
  1256. if ((shipcheck->shipSockfd >= 0) && (shipcheck->playerCount < 10000))
  1257. {
  1258. totalShips++;
  1259. PacketA0Data[A0Offset] = 0x12;
  1260. *(unsigned *) &PacketA0Data[A0Offset+2] = shipcheck->shipID;
  1261. ch2 = A0Offset+0x08;
  1262. shipName = &shipcheck->name[0];
  1263. while (*shipName != 0x00)
  1264. {
  1265. PacketA0Data[ch2++] = *shipName;
  1266. PacketA0Data[ch2++] = 0x00;
  1267. shipName++;
  1268. }
  1269. PacketA0Data[ch2++] = 0x20;
  1270. PacketA0Data[ch2++] = 0x00;
  1271. PacketA0Data[ch2++] = 0x28;
  1272. PacketA0Data[ch2++] = 0x00;
  1273. _itoa (shipcheck->playerCount, &playerCountString[0], 10);
  1274. shipName = &playerCountString[0];
  1275. while (*shipName != 0x00)
  1276. {
  1277. PacketA0Data[ch2++] = *shipName;
  1278. PacketA0Data[ch2++] = 0x00;
  1279. shipName++;
  1280. }
  1281. PacketA0Data[ch2++] = 0x29;
  1282. PacketA0Data[ch2++] = 0x00;
  1283. A0Offset += 0x2C;
  1284. }
  1285. }
  1286. }
  1287. if (!totalShips)
  1288. {
  1289. totalShips++;
  1290. PacketA0Data[A0Offset] = 0x12;
  1291. *(unsigned *) &PacketA0Data[A0Offset+2] = totalShips;
  1292. for (ch=0;ch<9;ch++)
  1293. PacketA0Data[A0Offset+0x08+(ch*2)] = NoShips[ch];
  1294. A0Offset += 0x2C;
  1295. }
  1296. *(unsigned *) &PacketA0Data[0x04] = totalShips;
  1297. while (A0Offset % 8)
  1298. PacketA0Data[A0Offset++] = 0x00;
  1299. *(unsigned short*) &PacketA0Data[0x00] = (unsigned short) A0Offset;
  1300. PacketA0Size = A0Offset;
  1301. }
  1302.  
  1303.  
  1304.  
  1305. unsigned free_connection()
  1306. {
  1307. unsigned fc;
  1308. BANANA* wc;
  1309.  
  1310. for (fc=0;fc<serverMaxConnections;fc++)
  1311. {
  1312. wc = connections[fc];
  1313. if (wc->plySockfd<0)
  1314. return fc;
  1315. }
  1316. return 0xFFFF;
  1317. }
  1318.  
  1319. unsigned free_shipconnection()
  1320. {
  1321. unsigned fc;
  1322. ORANGE* wc;
  1323.  
  1324. for (fc=0;fc<serverMaxShips;fc++)
  1325. {
  1326. wc = ships[fc];
  1327. if (wc->shipSockfd<0)
  1328. return fc;
  1329. }
  1330. return 0xFFFF;
  1331. }
  1332.  
  1333.  
  1334. void initialize_connection (BANANA* connect)
  1335. {
  1336. unsigned ch, ch2;
  1337.  
  1338. if (connect->plySockfd >= 0)
  1339. {
  1340. ch2 = 0;
  1341. for (ch=0;ch<serverNumConnections;ch++)
  1342. {
  1343. if (serverConnectionList[ch] != connect->connection_index)
  1344. serverConnectionList[ch2++] = serverConnectionList[ch];
  1345. }
  1346. serverNumConnections = ch2;
  1347. close (connect->plySockfd);
  1348. }
  1349. memset (connect, 0, sizeof (BANANA));
  1350. connect->plySockfd = -1;
  1351. connect->login = -1;
  1352. connect->lastTick = 0xFFFFFFFF;
  1353. connect->connected = 0xFFFFFFFF;
  1354. }
  1355.  
  1356. void initialize_ship (ORANGE* ship)
  1357. {
  1358. unsigned ch, ch2;
  1359.  
  1360. if (ship->shipSockfd >= 0)
  1361. {
  1362. if ( ( ship->key_index ) && ( ship->key_index <= max_ship_keys ) && ( keys_in_use [ ship->key_index ] ) )
  1363. keys_in_use [ ship->key_index ] = 0; // key no longer in use
  1364.  
  1365. ch2 = 0;
  1366. for (ch=0;ch<serverNumShips;ch++)
  1367. {
  1368. if (serverShipList[ch] != ship->connection_index)
  1369. serverShipList[ch2++] = serverShipList[ch];
  1370. }
  1371. serverNumShips = ch2;
  1372. close (ship->shipSockfd);
  1373. }
  1374. memset (ship, 0, sizeof (ORANGE) );
  1375. for (ch=0;ch<128;ch++)
  1376. ship->key_change[ch] = -1;
  1377. ship->shipSockfd = -1;
  1378. // Will be changed upon a successful authentication
  1379. ship->playerCount = 0xFFFF;
  1380. construct0xA0(); // Removes inactive ships
  1381. }
  1382.  
  1383. void start_encryption(BANANA* connect)
  1384. {
  1385. unsigned c, c3, c4, connectNum;
  1386. BANANA *workConnect, *c5;
  1387.  
  1388. // Limit the number of connections from an IP address to MAX_SIMULTANEOUS_CONNECTIONS.
  1389.  
  1390. c3 = 0;
  1391.  
  1392. for (c=0;c<serverNumConnections;c++)
  1393. {
  1394. connectNum = serverConnectionList[c];
  1395. workConnect = connections[connectNum];
  1396. //debug ("%s comparing to %s", (char*) &workConnect->IP_Address[0], (char*) &connect->IP_Address[0]);
  1397. if ((!strcmp(&workConnect->IP_Address[0], &connect->IP_Address[0])) &&
  1398. (workConnect->plySockfd >= 0))
  1399. c3++;
  1400. }
  1401.  
  1402. if (c3 > MAX_SIMULTANEOUS_CONNECTIONS)
  1403. {
  1404. // More than MAX_SIMULTANEOUS_CONNECTIONS connections from a certain IP address...
  1405. // Delete oldest connection to server.
  1406. c4 = 0xFFFFFFFF;
  1407. c5 = NULL;
  1408. for (c=0;c<serverNumConnections;c++)
  1409. {
  1410. connectNum = serverConnectionList[c];
  1411. workConnect = connections[connectNum];
  1412. if ((!strcmp(&workConnect->IP_Address[0], &connect->IP_Address[0])) &&
  1413. (workConnect->plySockfd >= 0))
  1414. {
  1415. if (workConnect->connected < c4)
  1416. {
  1417. c4 = workConnect->connected;
  1418. c5 = workConnect;
  1419. }
  1420. }
  1421. }
  1422. if (c5)
  1423. {
  1424. workConnect = c5;
  1425. initialize_connection (workConnect);
  1426. }
  1427. }
  1428.  
  1429. memcpy (&connect->sndbuf[0], &Packet03[0], sizeof (Packet03));
  1430. for (c=0;c<0x30;c++)
  1431. {
  1432. connect->sndbuf[0x68+c] = (unsigned char) rand() % 255;
  1433. connect->sndbuf[0x98+c] = (unsigned char) rand() % 255;
  1434. }
  1435. connect->snddata += sizeof (Packet03);
  1436. cipher_ptr = &connect->server_cipher;
  1437. pso_crypt_table_init_bb (cipher_ptr, &connect->sndbuf[0x68]);
  1438. cipher_ptr = &connect->client_cipher;
  1439. pso_crypt_table_init_bb (cipher_ptr, &connect->sndbuf[0x98]);
  1440. connect->crypt_on = 1;
  1441. connect->sendCheck[SEND_PACKET_03] = 1;
  1442. connect->connected = (unsigned) servertime;
  1443. }
  1444.  
  1445. void SendB1 (BANANA* client)
  1446. {
  1447. //SYSTEMTIME rawtime;
  1448. time_t t;
  1449. struct tm *rawtime;
  1450.  
  1451. /*if ((client->guildcard) && (client->slotnum != -1))
  1452. {
  1453. GetSystemTime (&rawtime);
  1454. *(long long*) &client->encryptbuf[0] = *(long long*) &PacketB1[0];
  1455. memset (&client->encryptbuf[0x08], 0, 28);
  1456. sprintf (&client->encryptbuf[8], "%u:%02u:%02u: %02u:%02u:%02u.%03u", rawtime.wYear, rawtime.wMonth, rawtime.wDay,
  1457. rawtime.wHour, rawtime.wMinute, rawtime.wSecond, rawtime.wMilliseconds );
  1458. cipher_ptr = &client->server_cipher;
  1459. encryptcopy (client, &client->encryptbuf[0], 0x24 );
  1460. }*/
  1461. if ((client->guildcard) && (client->slotnum != -1))
  1462. {
  1463. time(&t);
  1464. rawtime = localtime(&t);
  1465. *(long long*) &client->encryptbuf[0] = *(long long*) &PacketB1[0];
  1466. memset (&client->encryptbuf[0x08], 0, 28);
  1467. sprintf (&client->encryptbuf[8], "%u:%02u:%02u: %02u:%02u:%02u.%03u", rawtime->tm_year, rawtime->tm_mon, rawtime->tm_mday,
  1468. rawtime->tm_hour, rawtime->tm_min, rawtime->tm_sec, rawtime->tm_sec/1000 ); //WICHTIG
  1469. cipher_ptr = &client->server_cipher;
  1470. encryptcopy (client, &client->encryptbuf[0], 0x24 );
  1471. }
  1472. else
  1473. client->todc = 1;
  1474. }
  1475.  
  1476. void Send1A (const char *mes, BANANA* client)
  1477. {
  1478. unsigned short x1A_Len;
  1479.  
  1480. memcpy (&Packet1AData[0], &Packet1A[0], sizeof (Packet1A));
  1481. x1A_Len = sizeof (Packet1A);
  1482.  
  1483. while (*mes != 0x00)
  1484. {
  1485. Packet1AData[x1A_Len++] = *(mes++);
  1486. Packet1AData[x1A_Len++] = 0x00;
  1487. }
  1488.  
  1489. Packet1AData[x1A_Len++] = 0x00;
  1490. Packet1AData[x1A_Len++] = 0x00;
  1491.  
  1492. while (x1A_Len % 8)
  1493. Packet1AData[x1A_Len++] = 0x00;
  1494. *(unsigned short*) &Packet1AData[0] = x1A_Len;
  1495. cipher_ptr = &client->server_cipher;
  1496. encryptcopy (client, &Packet1AData[0], x1A_Len);
  1497. client->todc = 1;
  1498. }
  1499.  
  1500. void SendA0 (BANANA* client)
  1501. {
  1502. if ((client->guildcard) && (client->slotnum != -1))
  1503. {
  1504. cipher_ptr = &client->server_cipher;
  1505. encryptcopy (client, &PacketA0Data[0], *(unsigned short*) &PacketA0Data[0]);
  1506. }
  1507. else
  1508. client->todc = 1;
  1509. }
  1510.  
  1511.  
  1512. void SendEE (const char *mes, BANANA* client)
  1513. {
  1514. unsigned short xEE_Len;
  1515.  
  1516. if ((client->guildcard) && (client->slotnum != -1))
  1517. {
  1518. memcpy (&PacketEEData[0], &PacketEE[0], sizeof (PacketEE));
  1519. xEE_Len = sizeof (PacketEE);
  1520.  
  1521. while (*mes != 0x00)
  1522. {
  1523. PacketEEData[xEE_Len++] = *(mes++);
  1524. PacketEEData[xEE_Len++] = 0x00;
  1525. }
  1526.  
  1527. PacketEEData[xEE_Len++] = 0x00;
  1528. PacketEEData[xEE_Len++] = 0x00;
  1529.  
  1530. while (xEE_Len % 8)
  1531. PacketEEData[xEE_Len++] = 0x00;
  1532. *(unsigned short*) &PacketEEData[0] = xEE_Len;
  1533. cipher_ptr = &client->server_cipher;
  1534. encryptcopy (client, &PacketEEData[0], xEE_Len);
  1535. }
  1536. }
  1537.  
  1538. void Send19 (unsigned char ip1, unsigned char ip2, unsigned char ip3, unsigned char ip4, unsigned short ipp, BANANA* client)
  1539. {
  1540. memcpy ( &client->encryptbuf[0], &Packet19, sizeof (Packet19));
  1541. client->encryptbuf[0x08] = ip1;
  1542. client->encryptbuf[0x09] = ip2;
  1543. client->encryptbuf[0x0A] = ip3;
  1544. client->encryptbuf[0x0B] = ip4;
  1545. *(unsigned short*) &client->encryptbuf[0x0C] = ipp;
  1546. cipher_ptr = &client->server_cipher;
  1547. encryptcopy (client, &client->encryptbuf[0], sizeof (Packet19));
  1548. }
  1549.  
  1550. unsigned char key_data_send[840+10] = {0};
  1551.  
  1552. void SendE2 (BANANA* client)
  1553. {
  1554. int key_exists = 0;
  1555.  
  1556. if ((client->guildcard) && (!client->sendCheck[SEND_PACKET_E2]))
  1557. {
  1558. memcpy (&PacketE2Data[0], &E2_Base[0], 2808);
  1559.  
  1560. #ifdef NO_SQL
  1561.  
  1562. ds_found = -1;
  1563. for (ds=0;ds<num_keydata;ds++)
  1564. {
  1565. if (key_data[ds]->guildcard == client->guildcard)
  1566. {
  1567. ds_found = ds;
  1568. break;
  1569. }
  1570. }
  1571. if (ds_found != -1)
  1572. memcpy (&PacketE2Data[0x11C], &key_data[ds_found]->controls, 420 );
  1573. else
  1574. {
  1575. key_data[num_keydata] = malloc (sizeof(L_KEY_DATA));
  1576. key_data[num_keydata]->guildcard = client->guildcard;
  1577. memcpy (&key_data[num_keydata]->controls, &E2_Base[0x11C], 420);
  1578. UpdateDataFile ("keydata.dat", num_keydata, key_data[num_keydata], sizeof(L_KEY_DATA), 1);
  1579. num_keydata++;
  1580. }
  1581.  
  1582. #else
  1583.  
  1584. sprintf (&myQuery[0], "SELECT * from key_data WHERE guildcard='%u'", client->guildcard );
  1585.  
  1586. //printf ("MySQL query %s\n", myQuery );
  1587.  
  1588. // Check to see if we've got some saved key data.
  1589.  
  1590. if ( ! mysql_query ( myData, &myQuery[0] ) )
  1591. {
  1592. myResult = mysql_store_result ( myData );
  1593. key_exists = (int) mysql_num_rows ( myResult );
  1594. if ( key_exists )
  1595. {
  1596. //debug ("Key data exists, fetching...");
  1597. myRow = mysql_fetch_row ( myResult );
  1598. memcpy (&PacketE2Data[0x11C], myRow[1], 420 );
  1599. }
  1600. else
  1601. {
  1602. //debug ("Key data does not exist...");
  1603. mysql_real_escape_string ( myData, &key_data_send[0], &E2_Base[0x11C], 420 );
  1604. sprintf (&myQuery[0], "INSERT INTO key_data (guildcard, controls) VALUES ('%u','%s')", client->guildcard, (char*) &key_data_send[0] );
  1605. memcpy (&PacketE2Data[0x11C], &E2_Base[0x11C], 420);
  1606. if ( mysql_query ( myData, &myQuery[0] ) )
  1607. debug ("Could not insert key information into database.");
  1608. }
  1609. mysql_free_result ( myResult );
  1610. }
  1611. else
  1612. {
  1613. Send1A ("Could not fetch key data.\n\nThere is a problem with the MySQL database.", client);
  1614. client->todc = 1;
  1615. return;
  1616. }
  1617. #endif
  1618. memset (&PacketE2Data[0xAF4], 0xFF, 4); // Enable dressing room, etc,.
  1619. cipher_ptr = &client->server_cipher;
  1620. encryptcopy (client, &PacketE2Data[0], sizeof (PacketE2Data));
  1621. client->sendCheck[SEND_PACKET_E2] = 0x01;
  1622. }
  1623. else
  1624. client->todc = 1;
  1625. }
  1626.  
  1627. unsigned StringLength (const char* src)
  1628. {
  1629. unsigned ch = 0;
  1630.  
  1631. while (*src != 0x00)
  1632. {
  1633. ch++;
  1634. src++;
  1635. }
  1636. return ch;
  1637. }
  1638.  
  1639. CHARDATA E7_Base, E7_Work;
  1640. unsigned char chardata[0x200];
  1641. unsigned char E7chardata[(sizeof(CHARDATA)*2)+100];
  1642. unsigned char startingStats[12*14];
  1643. unsigned char DefaultTeamFlagSlashes[4098];
  1644. unsigned char DefaultTeamFlag[2048];
  1645. unsigned char FlagSlashes[4098];
  1646.  
  1647. void AckCharacter_Creation(unsigned char slotnum, BANANA* client)
  1648. {
  1649. unsigned short *n;
  1650. #ifndef NO_SQL
  1651. int char_exists;
  1652. #endif
  1653. unsigned short packetSize;
  1654. MINICHAR* clientchar;
  1655. CHARDATA* E7Base;
  1656. CHARDATA* NewE7;
  1657. unsigned short maxFace, maxHair, maxHairColorRed, maxHairColorBlue, maxHairColorGreen,
  1658. maxCostume, maxSkin, maxHead;
  1659. unsigned ch;
  1660.  
  1661. packetSize = *(unsigned short*) &client->decryptbuf[0];
  1662. if ( ( client->guildcard ) && ( slotnum < 4 ) && ( client->sendingchars == 0 ) &&
  1663. ( packetSize == 0x88 ) && ( client->decryptbuf[0x45] < CLASS_MAX ) )
  1664. {
  1665. clientchar = (MINICHAR*) &client->decryptbuf[0x00];
  1666. clientchar->name[0] = 0x09; // Filter colored names
  1667. clientchar->name[1] = 0x00;
  1668. clientchar->name[2] = 0x45;
  1669. clientchar->name[3] = 0x00;
  1670. clientchar->name[22] = 0; // Truncate names too long
  1671. clientchar->name[23] = 0;
  1672. if ((clientchar->_class == CLASS_HUMAR) ||
  1673. (clientchar->_class == CLASS_HUNEWEARL) ||
  1674. (clientchar->_class == CLASS_RAMAR) ||
  1675. (clientchar->_class == CLASS_RAMARL) ||
  1676. (clientchar->_class == CLASS_FOMARL) ||
  1677. (clientchar->_class == CLASS_FONEWM) ||
  1678. (clientchar->_class == CLASS_FONEWEARL) ||
  1679. (clientchar->_class == CLASS_FOMAR))
  1680. {
  1681. maxFace = 0x05;
  1682. maxHair = 0x0A;
  1683. maxHairColorRed = 0xFF;
  1684. maxHairColorBlue = 0xFF;
  1685. maxHairColorGreen = 0xFF;
  1686. maxCostume = 0x11;
  1687. maxSkin = 0x03;
  1688. maxHead = 0x00;
  1689. }
  1690. else
  1691. {
  1692. maxFace = 0x00;
  1693. maxHair = 0x00;
  1694. maxHairColorRed = 0x00;
  1695. maxHairColorBlue = 0x00;
  1696. maxHairColorGreen = 0x00;
  1697. maxCostume = 0x00;
  1698. maxSkin = 0x18;
  1699. maxHead = 0x04;
  1700. }
  1701. if (clientchar->skinID > 0x06)
  1702. clientchar->skinID = 0x00;
  1703. clientchar->nameColorTransparency = 0xFF;
  1704. if (clientchar->sectionID > 0x09)
  1705. clientchar->sectionID = 0x00;
  1706. if (clientchar->proportionX > 0x3F800000)
  1707. clientchar->proportionX = 0x3F800000;
  1708. if (clientchar->proportionY > 0x3F800000)
  1709. clientchar->proportionY = 0x3F800000;
  1710. if (clientchar->face > maxFace)
  1711. clientchar->face = 0x00;
  1712. if (clientchar->hair > maxHair)
  1713. clientchar->hair = 0x00;
  1714. if (clientchar->hairColorRed > maxHairColorRed)
  1715. clientchar->hairColorRed = 0x00;
  1716. if (clientchar->hairColorBlue > maxHairColorBlue)
  1717. clientchar->hairColorBlue = 0x00;
  1718. if (clientchar->hairColorGreen > maxHairColorGreen)
  1719. clientchar->hairColorGreen = 0x00;
  1720. if (clientchar->costume > maxCostume)
  1721. clientchar->costume = 0x00;
  1722. if (clientchar->skin > maxSkin)
  1723. clientchar->skin = 0x00;
  1724. if (clientchar->head > maxHead)
  1725. clientchar->head = 0x00;
  1726. for (ch=0;ch<8;ch++)
  1727. clientchar->unknown5[ch] = 0x00;
  1728. clientchar->playTime = 0;
  1729.  
  1730. if ( client->dress_flag == 0 )
  1731. {
  1732. /* Yeah! MySQL! :D */
  1733.  
  1734. #ifndef NO_SQL
  1735.  
  1736. mysql_real_escape_string ( myData, &chardata[0], &client->decryptbuf[0x10], 0x78 );
  1737.  
  1738. #endif
  1739.  
  1740. /* Let's construct the FULL character now... */
  1741.  
  1742. E7Base = &E7_Base;
  1743. NewE7 = &E7_Work;
  1744. memset (NewE7, 0, sizeof (CHARDATA) );
  1745. NewE7->packetSize = 0x399C;
  1746. NewE7->command = 0x00E7;
  1747. memset (&NewE7->flags, 0, 4);
  1748. NewE7->HPuse = 0;
  1749. NewE7->TPuse = 0;
  1750. NewE7->lang = 0;
  1751. switch (clientchar->_class)
  1752. {
  1753. case CLASS_HUMAR:
  1754. case CLASS_HUNEWEARL:
  1755. case CLASS_HUCAST:
  1756. case CLASS_HUCASEAL:
  1757. // Saber
  1758. NewE7->inventory[0].in_use = 0x01;
  1759. NewE7->inventory[0].flags = 0x08;
  1760. NewE7->inventory[0].item.data[1] = 0x01;
  1761. NewE7->inventory[0].item.itemid = 0x00010000;
  1762. break;
  1763. case CLASS_RAMAR:
  1764. case CLASS_RACAST:
  1765. case CLASS_RACASEAL:
  1766. case CLASS_RAMARL:
  1767. // Handgun
  1768. NewE7->inventory[0].in_use = 0x01;
  1769. NewE7->inventory[0].flags = 0x08;
  1770. NewE7->inventory[0].item.data[1] = 0x06;
  1771. NewE7->inventory[0].item.itemid = 0x00010000;
  1772. break;
  1773. case CLASS_FONEWM:
  1774. case CLASS_FONEWEARL:
  1775. case CLASS_FOMARL:
  1776. case CLASS_FOMAR:
  1777. // Cane
  1778. NewE7->inventory[0].in_use = 0x01;
  1779. NewE7->inventory[0].flags = 0x08;
  1780. NewE7->inventory[0].item.data[1] = 0x0A;
  1781. NewE7->inventory[0].item.itemid = 0x00010000;
  1782. break;
  1783. default:
  1784. break;
  1785. }
  1786.  
  1787. // Frame
  1788. NewE7->inventory[1].in_use = 0x01;
  1789. NewE7->inventory[1].flags = 0x08;
  1790. NewE7->inventory[1].item.data[0] = 0x01;
  1791. NewE7->inventory[1].item.data[1] = 0x01;
  1792. NewE7->inventory[1].item.itemid = 0x00010001;
  1793.  
  1794. // Mag
  1795. NewE7->inventory[2].in_use = 0x01;
  1796. NewE7->inventory[2].flags = 0x08;
  1797. NewE7->inventory[2].item.data[0] = 0x02;
  1798. NewE7->inventory[2].item.data[2] = 0x05;
  1799. NewE7->inventory[2].item.data[4] = 0xF4;
  1800. NewE7->inventory[2].item.data[5] = 0x01;
  1801. NewE7->inventory[2].item.data2[0] = 0x14; // 20% synchro
  1802. NewE7->inventory[2].item.itemid = 0x00010002;
  1803.  
  1804. if ((clientchar->_class == CLASS_HUCAST) || (clientchar->_class == CLASS_HUCASEAL) ||
  1805. (clientchar->_class == CLASS_RACAST) || (clientchar->_class == CLASS_RACASEAL))
  1806. NewE7->inventory[2].item.data2[3] = (unsigned char) clientchar->skin;
  1807. else
  1808. NewE7->inventory[2].item.data2[3] = (unsigned char) clientchar->costume;
  1809.  
  1810. if (NewE7->inventory[2].item.data2[3] > 0x11)
  1811. NewE7->inventory[2].item.data2[3] -= 0x11;
  1812.  
  1813. // Monomates
  1814. NewE7->inventory[3].in_use = 0x01;
  1815. NewE7->inventory[3].item.data[0] = 0x03;
  1816. NewE7->inventory[3].item.data[5] = 0x04;
  1817. NewE7->inventory[3].item.itemid = 0x00010003;
  1818.  
  1819. memcpy (&NewE7->techniques, &E7Base->techniques, 20);
  1820.  
  1821. if ( ( clientchar->_class == CLASS_FONEWM ) || ( clientchar->_class == CLASS_FONEWEARL ) ||
  1822. ( clientchar->_class == CLASS_FOMARL ) || ( clientchar->_class == CLASS_FOMAR ) )
  1823. {
  1824. // Monofluids
  1825. NewE7->techniques[0] = 0x00;
  1826. NewE7->inventory[4].in_use = 0x01;
  1827. NewE7->inventory[4].flags = 0x00;
  1828. NewE7->inventory[4].item.data[0] = 0x03;
  1829. NewE7->inventory[4].item.data[1] = 0x01;
  1830. NewE7->inventory[4].item.data[2] = 0x00;
  1831. NewE7->inventory[4].item.data[3] = 0x00;
  1832. memset (&NewE7->inventory[4].item.data[4], 0x00, 8);
  1833. NewE7->inventory[4].item.data[5] = 0x04;
  1834. NewE7->inventory[4].item.itemid = 0x00010004;
  1835. memset (&NewE7->inventory[3].item.data2[0], 0x00, 4);
  1836. NewE7->inventoryUse = 5;
  1837. }
  1838. else
  1839. NewE7->inventoryUse = 4;
  1840.  
  1841. for (ch=NewE7->inventoryUse;ch<30;ch++)
  1842. {
  1843. NewE7->inventory[ch].in_use = 0x00;
  1844. NewE7->inventory[ch].item.data[1] = 0xFF;
  1845. NewE7->inventory[ch].item.itemid = 0xFFFFFFFF;
  1846. }
  1847.  
  1848. memcpy (&NewE7->ATP, &startingStats[clientchar->_class * 14], 14);
  1849. *(long long*) &NewE7->unknown = *(long long*) &E7Base->unknown;
  1850. //NewE7->level = 0x00;
  1851. NewE7->unknown2 = E7Base->unknown2;
  1852. //NewE7->XP = 0;
  1853. NewE7->meseta = 300;
  1854. memset (&NewE7->gcString[0], 0x20, 2);
  1855. *(long long*) &NewE7->gcString[2] = *(long long*) &client->guildcard_string[0];
  1856. memcpy (&NewE7->unknown3, &clientchar->unknown2, 14 );
  1857. *(unsigned *) &NewE7->nameColorBlue = *(unsigned *) &clientchar->nameColorBlue; // Will copy all 4 values.
  1858. NewE7->skinID = clientchar->skinID;
  1859. memcpy (&NewE7->unknown4, &clientchar->unknown3, 18);
  1860. NewE7->sectionID = clientchar->sectionID;
  1861. NewE7->_class = clientchar->_class;
  1862. NewE7->skinFlag = clientchar->skinFlag;
  1863. memcpy (&NewE7->unknown5, &clientchar->unknown4, 5);
  1864. NewE7->costume = clientchar->costume;
  1865. NewE7->skin = clientchar->skin;
  1866. NewE7->face = clientchar->face;
  1867. NewE7->head = clientchar->head;
  1868. NewE7->hair = clientchar->hair;
  1869. NewE7->hairColorRed = clientchar->hairColorRed;
  1870. NewE7->hairColorBlue = clientchar->hairColorBlue;
  1871. NewE7->hairColorGreen = clientchar->hairColorGreen;
  1872. NewE7->proportionX = clientchar->proportionX;
  1873. NewE7->proportionY = clientchar->proportionY;
  1874. n = (unsigned short*) &clientchar->name[4];
  1875. for (ch=0;ch<10;ch++)
  1876. {
  1877. if (*n == 0x0000)
  1878. break;
  1879. if ((*n == 0x0009) || (*n == 0x000A))
  1880. *n = 0x0020;
  1881. n++;
  1882. }
  1883. memcpy (&NewE7->name, &clientchar->name, 24);
  1884. *(unsigned *) &NewE7->unknown6 = *(unsigned *) &clientchar->unknown5;
  1885. memcpy (&NewE7->keyConfig, &E7Base->keyConfig, 232);
  1886. // TO DO: Give Foie to starting Forces.
  1887. memcpy (&NewE7->unknown7, &E7Base->unknown7, 16);
  1888. *(unsigned *) &NewE7->options = *(unsigned *) &E7Base->options;
  1889. memcpy (&NewE7->unknown8, &E7Base->unknown8, 520);
  1890. NewE7->bankUse = E7Base->bankUse;
  1891. NewE7->bankMeseta = E7Base->bankMeseta;
  1892. memcpy (&NewE7->bankInventory, &E7Base->bankInventory, 24*200);
  1893. NewE7->guildCard = client->guildcard;
  1894. memcpy (&NewE7->name2, &clientchar->name, 24);
  1895. memcpy (&NewE7->unknown9, &E7Base->unknown9, 232);
  1896. NewE7->reserved1 = 0x01;
  1897. NewE7->reserved2 = 0x01;
  1898. NewE7->sectionID2 = clientchar->sectionID;
  1899. NewE7->_class2 = clientchar->_class;
  1900. *(unsigned *) &NewE7->unknown10[0] = *(unsigned *) &E7Base->unknown10[0];
  1901. memcpy (&NewE7->symbol_chats, &E7Base->symbol_chats, 1248);
  1902. memcpy (&NewE7->shortcuts, &E7Base->shortcuts, 2624);
  1903. memcpy (&NewE7->unknown11, &E7Base->unknown11, 344);
  1904. memcpy (&NewE7->GCBoard, &E7Base->GCBoard, 172);
  1905. memcpy (&NewE7->unknown12, &E7Base->unknown12, 200);
  1906. memcpy (&NewE7->challengeData, &E7Base->challengeData, 320);
  1907. memcpy (&NewE7->unknown13, &E7Base->unknown13, 172);
  1908. memcpy (&NewE7->unknown14, &E7Base->unknown14, 276);
  1909. // TO DO: Actually, we should use the values from the database, but I haven't added columns for them yet...
  1910. // For now, we'll use the "base" packet's values.
  1911. memcpy (&NewE7->keyConfigGlobal, &E7Base->keyConfigGlobal, 364);
  1912. memcpy (&NewE7->joyConfigGlobal, &E7Base->joyConfigGlobal, 56);
  1913. memcpy (&NewE7->guildCard2, &E7Base->guildCard2, 2108);
  1914.  
  1915. #ifndef NO_SQL
  1916.  
  1917. mysql_real_escape_string ( myData, &E7chardata[0], (unsigned char*) NewE7, sizeof (CHARDATA) );
  1918.  
  1919. #endif
  1920.  
  1921. }
  1922.  
  1923. // Check to see if the character exists in that slot.
  1924.  
  1925. #ifdef NO_SQL
  1926.  
  1927. ds_found = -1;
  1928. free_record = -1;
  1929.  
  1930. for (ds=0;ds<num_characters;ds++)
  1931. {
  1932. if (character_data[ds]->guildcard == 0)
  1933. free_record = ds;
  1934.  
  1935. if ((character_data[ds]->guildcard == client->guildcard) &&
  1936. (character_data[ds]->slot == slotnum))
  1937. {
  1938. ds_found = ds;
  1939. break;
  1940. }
  1941. }
  1942.  
  1943. if ( ( client->dress_flag ) && ( ds_found != -1 ) )
  1944. {
  1945. debug ("Update character %u", client->guildcard);
  1946. NewE7 = &E7_Work;
  1947. memcpy (NewE7, &character_data[ds_found]->data, sizeof (CHARDATA) );
  1948. memcpy (&NewE7->gcString[0], &clientchar->gcString[0], 0x68);
  1949. *(long long*) &clientchar->unknown5[0] = *(long long*) &NewE7->unknown6[0];
  1950. //NewE7->playTime = 0;
  1951. memcpy (&character_data[ds_found]->header, &client->decryptbuf[0x10], 0x78);
  1952. memcpy (&character_data[ds_found]->data, NewE7, sizeof (CHARDATA));
  1953. UpdateDataFile ("character.dat", ds_found, character_data[ds_found], sizeof(L_CHARACTER_DATA), 0);
  1954. }
  1955. else
  1956. {
  1957. if (ds_found == -1)
  1958. {
  1959. if (free_record != -1)
  1960. {
  1961. ds_found = free_record;
  1962. new_record = 0;
  1963. }
  1964. else
  1965. {
  1966. ds_found = num_characters;
  1967. new_record = 1;
  1968. character_data[num_characters++] = malloc (sizeof(L_CHARACTER_DATA));
  1969. }
  1970. }
  1971. else
  1972. new_record = 0;
  1973. character_data[ds_found]->guildcard = client->guildcard;
  1974. character_data[ds_found]->slot = slotnum;
  1975. memcpy (&character_data[ds_found]->data, NewE7, sizeof (CHARDATA));
  1976. memcpy (&character_data[ds_found]->header, &client->decryptbuf[0x10], 0x78);
  1977. UpdateDataFile ("character.dat", ds_found, character_data[ds_found], sizeof(L_CHARACTER_DATA), new_record);
  1978. }
  1979. PacketE4[0x00] = 0x10;
  1980. PacketE4[0x02] = 0xE4;
  1981. PacketE4[0x03] = 0x00;
  1982. PacketE4[0x08] = slotnum;
  1983. PacketE4[0x0C] = 0x00;
  1984. cipher_ptr = &client->server_cipher;
  1985. encryptcopy (client, &PacketE4[0], sizeof (PacketE4));
  1986. ds_found = -1;
  1987. for (ds=0;ds<num_security;ds++)
  1988. {
  1989. if (security_data[ds]->guildcard == client->guildcard)
  1990. {
  1991. ds_found = ds;
  1992. security_data[ds]->slotnum = slotnum;
  1993. UpdateDataFile ("security.dat", ds, security_data[ds], sizeof (L_SECURITY_DATA), 0);
  1994. break;
  1995. }
  1996. }
  1997.  
  1998. if (ds_found == -1)
  1999. {
  2000. Send1A ("Could not select character.", client);
  2001. client->todc = 1;
  2002. }
  2003.  
  2004. #else
  2005.  
  2006. sprintf (&myQuery[0], "SELECT * from character_data WHERE guildcard='%u' AND slot='%u'", client->guildcard, slotnum );
  2007. //printf ("MySQL query %s\n", myQuery );
  2008.  
  2009. if ( ! mysql_query ( myData, &myQuery[0] ) )
  2010. {
  2011. myResult = mysql_store_result ( myData );
  2012. char_exists = (int) mysql_num_rows ( myResult );
  2013. if (char_exists)
  2014. {
  2015. if (client->dress_flag == 0)
  2016. {
  2017. // Delete character if recreating...
  2018. sprintf (&myQuery[0], "DELETE from character_data WHERE guildcard='%u' AND slot ='%u'", client->guildcard, slotnum );
  2019. mysql_query ( myData, &myQuery[0] );
  2020. }
  2021. else
  2022. {
  2023. // Updating character only...
  2024. myRow = mysql_fetch_row ( myResult );
  2025. NewE7 = &E7_Work;
  2026. memcpy (NewE7, myRow[2], sizeof (CHARDATA) );
  2027. memcpy (&NewE7->gcString[0], &clientchar->gcString[0], 0x68);
  2028. *(long long*) &clientchar->unknown5[0] = *(long long*) &NewE7->unknown6[0];
  2029. //NewE7->playTime = 0;
  2030. mysql_real_escape_string ( myData, &chardata[0], &client->decryptbuf[0x10], 0x78 );
  2031. mysql_real_escape_string ( myData, &E7chardata[0], (unsigned char*) NewE7, sizeof (CHARDATA) );
  2032. }
  2033. }
  2034. mysql_free_result ( myResult );
  2035. }
  2036. else
  2037. {
  2038. Send1A ("Could not check character information.\n\nThere is a problem with the MySQL database.", client);
  2039. client->todc = 1;
  2040. return;
  2041. }
  2042. if (client->dress_flag == 0)
  2043. sprintf (&myQuery[0], "INSERT INTO character_data (guildcard,slot,data,header) VALUES ('%u','%u','%s','%s')", client->guildcard, slotnum, (char*) &E7chardata[0], (char*) &chardata[0] );
  2044. else
  2045. {
  2046. debug ("Update character...");
  2047. sprintf (&myQuery[0], "UPDATE character_data SET data='%s', header='%s' WHERE guildcard='%u' AND slot='%u'", (char*) &E7chardata[0], (char*) &chardata[0], client->guildcard, slotnum );
  2048. }
  2049. if ( ! mysql_query ( myData, &myQuery[0] ) )
  2050. {
  2051. PacketE4[0x00] = 0x10;
  2052. PacketE4[0x02] = 0xE4;
  2053. PacketE4[0x03] = 0x00;
  2054. PacketE4[0x08] = slotnum;
  2055. PacketE4[0x0C] = 0x00;
  2056. cipher_ptr = &client->server_cipher;
  2057. encryptcopy (client, &PacketE4[0], sizeof (PacketE4));
  2058. sprintf (&myQuery[0], "UPDATE security_data SET slotnum = '%u' WHERE guildcard = '%u'", slotnum, client->guildcard );
  2059. if ( mysql_query ( myData, &myQuery[0] ) )
  2060. {
  2061. Send1A ("Could not select character.", client);
  2062. client->todc = 1;
  2063. }
  2064. }
  2065. else
  2066. {
  2067. Send1A ("Could not save character to database.\nPlease contact the server administrator.", client);
  2068. client->todc = 1;
  2069. }
  2070. #endif
  2071. }
  2072. else
  2073. client->todc = 1;
  2074. }
  2075. void SendE4_E5(unsigned char slotnum, unsigned char selecting, BANANA* client)
  2076. {
  2077. int char_exists = 0;
  2078. MINICHAR* mc;
  2079.  
  2080. if ((client->guildcard) && (slotnum < 0x04))
  2081. {
  2082. #ifdef NO_SQL
  2083. ds_found = -1;
  2084. for (ds=0;ds<num_characters;ds++)
  2085. {
  2086. if ((character_data[ds]->guildcard == client->guildcard) &&
  2087. (character_data[ds]->slot == slotnum))
  2088. {
  2089. ds_found = ds;
  2090. break;
  2091. }
  2092. }
  2093. if (ds_found != -1)
  2094. {
  2095. char_exists = 1;
  2096. if (!selecting)
  2097. {
  2098. mc = (MINICHAR*) &PacketE5[0x00];
  2099. *(unsigned short*) &PacketE5[0x10] = character_data[ds_found]->data.level; // Updated level
  2100. memcpy (&PacketE5[0x14], &character_data[ds_found]->data.gcString[0], 0x70 ); // Updated data
  2101. *(unsigned *) &PacketE5[0x84] = character_data[ds_found]->data.playTime; // Updated playtime
  2102. if ( mc->skinFlag )
  2103. {
  2104. // In case we got bots that crashed themselves...
  2105. mc->skin = 0;
  2106. mc->head = 0;
  2107. mc->hair = 0;
  2108. }
  2109. }
  2110. }
  2111.  
  2112.  
  2113. #else
  2114. sprintf (&myQuery[0], "SELECT * from character_data WHERE guildcard='%u' AND slot='%u'", client->guildcard, slotnum );
  2115. //printf ("MySQL query %s\n", myQuery );
  2116.  
  2117. // Check to see if the character exists in that slot.
  2118.  
  2119. if ( ! mysql_query ( myData, &myQuery[0] ) )
  2120. {
  2121. myResult = mysql_store_result ( myData );
  2122. char_exists = (int) mysql_num_rows ( myResult );
  2123.  
  2124. if (char_exists)
  2125. {
  2126. if (!selecting)
  2127. {
  2128. myRow = mysql_fetch_row ( myResult );
  2129. mc = (MINICHAR*) &PacketE5[0x00];
  2130. memcpy (&PacketE5[0x10], myRow[2] + 0x36C, 2 ); // Updated level
  2131. memcpy (&PacketE5[0x14], myRow[2] + 0x378, 0x70 ); // Updated data
  2132. memcpy (&PacketE5[0x84], myRow[2] + 0x3E0, 4 ); // Updated playtime
  2133. if ( mc->skinFlag )
  2134. {
  2135. // In case we got bots that crashed themselves...
  2136. mc->skin = 0;
  2137. mc->head = 0;
  2138. mc->hair = 0;
  2139. }
  2140. }
  2141. }
  2142. mysql_free_result ( myResult );
  2143. }
  2144. else
  2145. {
  2146. Send1A ("Could not check character information.\n\nThere is a problem with the MySQL database.", client);
  2147. client->todc = 1;
  2148. return;
  2149. }
  2150. #endif
  2151.  
  2152. if (!selecting)
  2153. {
  2154. if (char_exists)
  2155. {
  2156. PacketE5[0x00] = 0x88;
  2157. PacketE5[0x02] = 0xE5;
  2158. PacketE5[0x03] = 0x00;
  2159. PacketE5[0x08] = slotnum;
  2160. PacketE5[0x0C] = 0x00;
  2161. if (client->sendCheck[SEND_PACKET_E5] < 0x04)
  2162. {
  2163. cipher_ptr = &client->server_cipher;
  2164. encryptcopy (client, &PacketE5[0], sizeof (PacketE5));
  2165. client->sendCheck[SEND_PACKET_E5] ++;
  2166. }
  2167. else
  2168. client->todc = 1;
  2169. }
  2170. else
  2171. {
  2172. PacketE4[0x00] = 0x10;
  2173. PacketE4[0x02] = 0xE4;
  2174. PacketE4[0x03] = 0x00;
  2175. PacketE4[0x08] = slotnum;
  2176. PacketE4[0x0C] = 0x02;
  2177. if (client->sendCheck[SEND_PACKET_E4] < 0x04)
  2178. {
  2179. cipher_ptr = &client->server_cipher;
  2180. encryptcopy (client, &PacketE4[0], sizeof (PacketE4));
  2181. client->sendCheck[SEND_PACKET_E4]++;
  2182. }
  2183. else
  2184. client->todc = 1;
  2185. }
  2186. }
  2187. else
  2188. {
  2189. if (char_exists)
  2190. {
  2191. PacketE4[0x00] = 0x10;
  2192. PacketE4[0x02] = 0xE4;
  2193. PacketE4[0x03] = 0x00;
  2194. PacketE4[0x08] = slotnum;
  2195. PacketE4[0x0C] = 0x01;
  2196. if ((client->sendCheck[SEND_PACKET_E4] < 0x04) && (client->sendingchars == 0))
  2197. {
  2198. cipher_ptr = &client->server_cipher;
  2199. encryptcopy (client, &PacketE4[0], sizeof (PacketE4));
  2200. #ifdef NO_SQL
  2201. ds_found = -1;
  2202. for (ds=0;ds<num_security;ds++)
  2203. {
  2204. if (security_data[ds]->guildcard == client->guildcard)
  2205. {
  2206. ds_found = ds;
  2207. security_data[ds]->slotnum = slotnum;
  2208. UpdateDataFile ("security.dat", ds, security_data[ds], sizeof (L_SECURITY_DATA), 0);
  2209. break;
  2210. }
  2211. }
  2212.  
  2213. if (ds_found == -1)
  2214. {
  2215. Send1A ("Could not select character.", client);
  2216. client->todc = 1;
  2217. }
  2218. #else
  2219. sprintf (&myQuery[0], "UPDATE security_data SET slotnum = '%u' WHERE guildcard = '%u'", slotnum, client->guildcard );
  2220. if ( mysql_query ( myData, &myQuery[0] ) )
  2221. {
  2222. Send1A ("Could not select character.", client);
  2223. client->todc = 1;
  2224. }
  2225. #endif
  2226. client->sendCheck[SEND_PACKET_E4]++;
  2227. }
  2228. else
  2229. client->todc = 1;
  2230. }
  2231. else
  2232. client->todc = 1;
  2233. }
  2234. }
  2235. else
  2236. client->todc = 1;
  2237. }
  2238.  
  2239. void SendE8 (BANANA* client)
  2240. {
  2241. if ((client->guildcard) && (!client->sendCheck[SEND_PACKET_E8]))
  2242. {
  2243. cipher_ptr = &client->server_cipher;
  2244. encryptcopy (client, &PacketE8[0], sizeof (PacketE8));
  2245. client->sendCheck[SEND_PACKET_E8] = 1;
  2246. }
  2247. else
  2248. client->todc = 1;
  2249. }
  2250.  
  2251. void SendEB (unsigned char subCommand, unsigned char EBOffset, BANANA* client)
  2252. {
  2253. unsigned CalcOffset;
  2254.  
  2255. if ((client->guildcard) && (client->sendCheck[SEND_PACKET_EB] < 17))
  2256. {
  2257. client->sendCheck[SEND_PACKET_EB]++;
  2258. switch (subCommand)
  2259. {
  2260. case 0x01:
  2261. cipher_ptr = &client->server_cipher;
  2262. encryptcopy (client, &PacketEB01[0], PacketEB01_Total);
  2263. break;
  2264. case 0x02:
  2265. cipher_ptr = &client->server_cipher;
  2266. CalcOffset = (unsigned) EBOffset * 26636;
  2267. if (CalcOffset < PacketEB02_Total)
  2268. {
  2269. if (PacketEB02_Total - CalcOffset >= 26636)
  2270. encryptcopy (client, &PacketEB02[CalcOffset], 26636 );
  2271. else
  2272. encryptcopy (client, &PacketEB02[CalcOffset], PacketEB02_Total - CalcOffset );
  2273. }
  2274. else
  2275. client->todc = 1;
  2276. break;
  2277. }
  2278. }
  2279. else
  2280. client->todc = 1;
  2281. }
  2282.  
  2283. void SendDC (int sendChecksum, unsigned char PacketNum, BANANA* client)
  2284. {
  2285. unsigned gc_ofs = 0,
  2286. total_guilds = 0;
  2287. unsigned friendid;
  2288. unsigned short sectionid, _class;
  2289. unsigned GCChecksum = 0;
  2290. unsigned ch;
  2291. unsigned CalcOffset;
  2292. int numguilds = 0;
  2293. unsigned to_send;
  2294.  
  2295. if ((client->guildcard) && (client->sendCheck[SEND_PACKET_DC] < 0x04))
  2296. {
  2297. client->sendCheck[SEND_PACKET_DC]++;
  2298. if (sendChecksum)
  2299. {
  2300. #ifdef NO_SQL
  2301. for (ds=0;ds<num_guilds;ds++)
  2302. {
  2303. if (guild_data[ds]->accountid == client->guildcard)
  2304. {
  2305. if (total_guilds < 40)
  2306. {
  2307. friendid = guild_data[ds]->friendid;
  2308. sectionid = guild_data[ds]->sectionid;
  2309. _class = guild_data[ds]->pclass;
  2310. for (ch=0;ch<444;ch++)
  2311. client->guildcard_data[gc_ofs+ch] = 0x00;
  2312. *(unsigned*) &client->guildcard_data[gc_ofs] = friendid;
  2313. memcpy (&client->guildcard_data[gc_ofs+0x04], &guild_data[ds]->friendname, 0x18 );
  2314. memcpy (&client->guildcard_data[gc_ofs+0x54], &guild_data[ds]->friendtext, 0xB0 );
  2315. client->guildcard_data[gc_ofs+0x104] = 0x01;
  2316. client->guildcard_data[gc_ofs+0x106] = (unsigned char) sectionid;
  2317. *(unsigned short*) &client->guildcard_data[gc_ofs+0x107] = _class;
  2318. // comment @ 0x10C
  2319. memcpy (&client->guildcard_data[gc_ofs+0x10C], &guild_data[ds]->comment, 0x44 );
  2320. total_guilds++;
  2321. gc_ofs += 444;
  2322. }
  2323. else
  2324. break;
  2325. }
  2326. }
  2327. #else
  2328. sprintf (&myQuery[0], "SELECT * from guild_data WHERE accountid='%u' ORDER BY priority", client->guildcard );
  2329. //printf ("MySQL query %s\n", myQuery );
  2330.  
  2331. // Check to see if the account has any guild cards.
  2332.  
  2333. if ( ! mysql_query ( myData, &myQuery[0] ) )
  2334. {
  2335.  
  2336. myResult = mysql_store_result ( myData );
  2337. numguilds = (int) mysql_num_rows ( myResult );
  2338.  
  2339. if (numguilds)
  2340. {
  2341. while ((myRow = mysql_fetch_row ( myResult )) && (total_guilds < 40))
  2342. {
  2343. friendid = atoi (myRow[1]);
  2344. sectionid = (unsigned short) atoi (myRow[5]);
  2345. _class = (unsigned short) atoi (myRow[6]);
  2346. for (ch=0;ch<444;ch++)
  2347. client->guildcard_data[gc_ofs+ch] = 0x00;
  2348. *(unsigned*) &client->guildcard_data[gc_ofs] = friendid;
  2349. memcpy (&client->guildcard_data[gc_ofs+0x04], myRow[2], 0x18 );
  2350. memcpy (&client->guildcard_data[gc_ofs+0x54], myRow[3], 0xB0 );
  2351. client->guildcard_data[gc_ofs+0x104] = 0x01;
  2352. client->guildcard_data[gc_ofs+0x106] = (unsigned char) sectionid;
  2353. *(unsigned short*) &client->guildcard_data[gc_ofs+0x107] = _class;
  2354. // comment @ 0x10C
  2355. memcpy (&client->guildcard_data[gc_ofs+0x10C], myRow[7], 0x44 );
  2356. total_guilds++;
  2357. gc_ofs += 444;
  2358. }
  2359. }
  2360. mysql_free_result ( myResult );
  2361. }
  2362. else
  2363. {
  2364. Send1A ("Could not check guild card information.\n\nThere is a problem with the MySQL database.", client);
  2365. client->todc = 1;
  2366. return;
  2367. }
  2368. #endif
  2369.  
  2370. if (total_guilds)
  2371. {
  2372. ch = 0x1F74 + (total_guilds * 444 );
  2373. memcpy ( &PacketDC_Check[0x1F74], &client->guildcard_data[0], total_guilds * 444 );
  2374. }
  2375. else
  2376. ch = 0x1F74;
  2377. for (ch;ch<26624;ch++)
  2378. PacketDC_Check[ch] = 0x00;
  2379. PacketDC_Check[0x06] = 0x01;
  2380. PacketDC_Check[0x07] = 0x02;
  2381. GCChecksum = (unsigned) CalculateChecksum (&PacketDC_Check[0], 54672);
  2382. PacketDC01[0x00] = 0x14;
  2383. PacketDC01[0x02] = 0xDC;
  2384. PacketDC01[0x03] = 0x01;
  2385. PacketDC01[0x08] = 0x01;
  2386. PacketDC01[0x0C] = 0x90;
  2387. PacketDC01[0x0D] = 0xD5;
  2388. *(unsigned *) &PacketDC01[0x10] = GCChecksum;
  2389. cipher_ptr = &client->server_cipher;
  2390. encryptcopy (client, &PacketDC01[0], sizeof (PacketDC01));
  2391. }
  2392. else
  2393. {
  2394. CalcOffset = ((unsigned) PacketNum * 26624);
  2395. if (PacketNum > 0x02)
  2396. client->todc = 1;
  2397. else
  2398. {
  2399. if (PacketNum < 0x02)
  2400. to_send = 26640;
  2401. else
  2402. to_send = 1440;
  2403. *(unsigned short*) &PacketDC02[0x00] = to_send;
  2404. PacketDC02[0x02] = 0xDC;
  2405. PacketDC02[0x03] = 0x02;
  2406. PacketDC02[0x0C] = PacketNum;
  2407. memcpy (&client->encryptbuf[0x00], &PacketDC02[0], 0x10);
  2408. memcpy (&client->encryptbuf[0x10], &PacketDC_Check[CalcOffset], to_send);
  2409. cipher_ptr = &client->server_cipher;
  2410. encryptcopy (client, &client->encryptbuf[0x00], to_send);
  2411. }
  2412. }
  2413. }
  2414. else
  2415. client->todc = 1;
  2416. }
  2417.  
  2418. /* Ship start authentication */
  2419.  
  2420. const unsigned char RC4publicKey[32] = {
  2421. 103, 196, 247, 176, 71, 167, 89, 233, 200, 100, 044, 209, 190, 231, 83, 42,
  2422. 6, 95, 151, 28, 140, 243, 130, 61, 107, 234, 243, 172, 77, 24, 229, 156
  2423. };
  2424.  
  2425. void ShipSend0F (unsigned char episode, unsigned char part, ORANGE* ship)
  2426. {
  2427. ship->encryptbuf[0x00] = 0x0F;
  2428. ship->encryptbuf[0x01] = episode;
  2429. ship->encryptbuf[0x02] = part;
  2430. switch (episode)
  2431. {
  2432. case 0x01:
  2433. memcpy (&ship->encryptbuf[0x03], &rt_tables_ep1[(sizeof(rt_tables_ep1) >> 3) * part], sizeof(rt_tables_ep1) >> 1);
  2434. break;
  2435. case 0x02:
  2436. memcpy (&ship->encryptbuf[0x03], &rt_tables_ep2[(sizeof(rt_tables_ep2) >> 3) * part], sizeof(rt_tables_ep2) >> 1);
  2437. break;
  2438. case 0x03:
  2439. memcpy (&ship->encryptbuf[0x03], &rt_tables_ep4[(sizeof(rt_tables_ep4) >> 3) * part], sizeof(rt_tables_ep4) >> 1);
  2440. break;
  2441. }
  2442. compressShipPacket ( ship, &ship->encryptbuf[0], 3 + (sizeof (rt_tables_ep1) >> 1) );
  2443. }
  2444.  
  2445. void ShipSend10 (ORANGE* ship)
  2446. {
  2447. ship->encryptbuf[0x00] = 0x10;
  2448. ship->encryptbuf[0x01] = 0x00;
  2449. memcpy (&ship->encryptbuf[0x02], &mob_rate[0], 32);
  2450. compressShipPacket ( ship, &ship->encryptbuf[0], 34 );
  2451. }
  2452.  
  2453. void ShipSend11 (ORANGE* ship)
  2454. {
  2455. ship->encryptbuf[0x00] = 0x11;
  2456. ship->encryptbuf[0x01] = 0x00;
  2457. ship->encryptbuf[0x02] = 0x00;
  2458. ship->encryptbuf[0x03] = 0x00;
  2459. compressShipPacket ( ship, &ship->encryptbuf[0], 4 );
  2460. }
  2461.  
  2462.  
  2463. void ShipSend00 (ORANGE* ship)
  2464. {
  2465. unsigned char ch, ch2;
  2466.  
  2467. ch2 = 0;
  2468.  
  2469. for (ch=0x18;ch<0x58;ch+=2) // change 32 bytes of the key
  2470. {
  2471. ShipPacket00[ch] = (unsigned char) rand() % 255;
  2472. ShipPacket00[ch+1] = (unsigned char) rand() % 255;
  2473. ship->key_change [ch2+(ShipPacket00[ch] % 4)] = ShipPacket00[ch+1];
  2474. ch2 += 4;
  2475. }
  2476. compressShipPacket ( ship, &ShipPacket00[0], sizeof (ShipPacket00) );
  2477. // use the public key to get the ship's index first...
  2478. memcpy (&ship->user_key[0], &RC4publicKey[0], 32 );
  2479. prepare_key(&ship->user_key[0], 32, &ship->cs_key);
  2480. prepare_key(&ship->user_key[0], 32, &ship->sc_key);
  2481. ship->crypt_on = 1;
  2482. }
  2483.  
  2484. /* Ship authentication result */
  2485.  
  2486. void ShipSend02 (unsigned char result, ORANGE* ship)
  2487. {
  2488. unsigned si,ch,shipNum;
  2489. ORANGE* tempShip;
  2490.  
  2491. ship->encryptbuf [0x00] = 0x02;
  2492. ship->encryptbuf [0x01] = result;
  2493. si = 0xFFFFFFFF;
  2494. if ( result == 0x01 )
  2495. {
  2496. for (ch=0;ch<serverNumShips;ch++)
  2497. {
  2498. shipNum = serverShipList[ch];
  2499. tempShip = ships[shipNum];
  2500. if (tempShip->shipSockfd == ship->shipSockfd)
  2501. {
  2502. si = shipNum;
  2503. ship->shipID = 0xFFFFFFFF - shipNum;
  2504. construct0xA0();
  2505. break;
  2506. }
  2507. }
  2508. }
  2509. *(unsigned *) &ship->encryptbuf[0x02] = si;
  2510. *(unsigned *) &ship->encryptbuf[0x06] = *(unsigned *) &ship->shipAddr[0];
  2511. *(unsigned *) &ship->encryptbuf[0x0A] = quest_numallows;
  2512. memcpy (&ship->encryptbuf[0x0E], quest_allow, quest_numallows * 4 );
  2513. si = 0x0E + ( quest_numallows * 4 );
  2514. *(unsigned *) &ship->encryptbuf[si] = normalName;
  2515. si += 4;
  2516. *(unsigned *) &ship->encryptbuf[si] = localName;
  2517. si += 4;
  2518. *(unsigned *) &ship->encryptbuf[si] = globalName;
  2519. si += 4;
  2520. compressShipPacket ( ship, &ship->encryptbuf[0x00], si );
  2521. }
  2522.  
  2523. void ShipSend08 (unsigned gcn, ORANGE* ship)
  2524. {
  2525. // Tell the other ships this user logged on and to disconnect him/her if they're still active...
  2526. ship->encryptbuf[0x00] = 0x08;
  2527. ship->encryptbuf[0x01] = 0x00;
  2528. *(unsigned *) &ship->encryptbuf[0x02] = gcn;
  2529. compressShipPacket ( ship, &ship->encryptbuf[0x00], 0x06 );
  2530. }
  2531.  
  2532.  
  2533. void ShipSend0D (unsigned char command, ORANGE* ship)
  2534. {
  2535. unsigned shipNum;
  2536. ORANGE* tship;
  2537.  
  2538. switch (command)
  2539. {
  2540. case 0x00:
  2541. {
  2542. unsigned ch;
  2543. // Send ship list data.
  2544. unsigned short tempdw;
  2545.  
  2546. tempdw = *(unsigned short*) &PacketA0Data[0];
  2547. // Ship requesting the ship list.
  2548. memcpy (&ship->encryptbuf[0x00], &ship->decryptbuf[0x04], 6);
  2549. memcpy (&ship->encryptbuf[0x06], &PacketA0Data[0], tempdw);
  2550. ship->encryptbuf[0x01] = 0x01;
  2551. tempdw += 6;
  2552. for (ch=0;ch<serverNumShips;ch++)
  2553. {
  2554. shipNum = serverShipList[ch];
  2555. tship = ships[shipNum];
  2556. if ((tship->shipSockfd >= 0) && (tship->authed == 1))
  2557. {
  2558. *(unsigned *) &ship->encryptbuf[tempdw] = tship->shipID;
  2559. tempdw += 4;
  2560. *(unsigned *) &ship->encryptbuf[tempdw] = *(unsigned *) &tship->shipAddr[0];
  2561. tempdw += 4;
  2562. *(unsigned short*) &ship->encryptbuf[tempdw] = (unsigned short) tship->shipPort;
  2563. tempdw += 2;
  2564. }
  2565. }
  2566. //display_packet (&ship->encryptbuf[0x00], tempdw);
  2567. compressShipPacket ( ship, &ship->encryptbuf[0x00], tempdw );
  2568. }
  2569. break;
  2570. default:
  2571. break;
  2572. }
  2573. }
  2574.  
  2575.  
  2576. void FixItem (ITEM* i)
  2577. {
  2578. unsigned ch3;
  2579.  
  2580. if (i->data[0] == 2) // Mag
  2581. {
  2582. MAG* m;
  2583. short mDefense, mPower, mDex, mMind;
  2584. int total_levels;
  2585.  
  2586. m = (MAG*) &i->data[0];
  2587.  
  2588. if ( m->synchro > 120 )
  2589. m->synchro = 120;
  2590.  
  2591. if ( m->synchro < 0 )
  2592. m->synchro = 0;
  2593.  
  2594. if ( m->IQ > 200 )
  2595. m->IQ = 200;
  2596.  
  2597. if ((m->defense < 0) || (m->power < 0) || (m->dex < 0) || (m->mind < 0))
  2598. total_levels = 201;
  2599. else
  2600. {
  2601.  
  2602. mDefense = m->defense / 100;
  2603. mPower = m->power / 100;
  2604. mDex = m->dex / 100;
  2605. mMind = m->mind / 100;
  2606.  
  2607. total_levels = mDefense + mPower + mDex + mMind;
  2608. }
  2609.  
  2610. if ( ( total_levels > 200 ) || ( m->level > 200 ) )
  2611. {
  2612. // Mag fails IRL, initialize it
  2613.  
  2614. m->defense = 500;
  2615. m->power = 0;
  2616. m->dex = 0;
  2617. m->mind = 0;
  2618. m->level = 5;
  2619. m->blasts = 0;
  2620. m->IQ = 0;
  2621. m->synchro = 20;
  2622. m->mtype = 0;
  2623. m->PBflags = 0;
  2624. }
  2625. }
  2626.  
  2627. if (i->data[0] == 0) // Weapon
  2628. {
  2629. signed char percent_table[6];
  2630. signed char percent;
  2631. unsigned max_percents, num_percents;
  2632. int srank;
  2633.  
  2634. if ( ( i->data[1] == 0x33 ) || // SJS & Lame max 2 percents
  2635. ( i->data[1] == 0xAB ) )
  2636. max_percents = 2;
  2637. else
  2638. max_percents = 3;
  2639.  
  2640. srank = 0;
  2641. memset (&percent_table[0], 0, 6);
  2642. num_percents = 0;
  2643.  
  2644. for (ch3=6;ch3<=4+(max_percents*2);ch3+=2)
  2645. {
  2646. if ( i->data[ch3] & 128 )
  2647. {
  2648. srank = 1; // S-Rank
  2649. break;
  2650. }
  2651.  
  2652. if ( ( i->data[ch3] ) &&
  2653. ( i->data[ch3] < 0x06 ) )
  2654. {
  2655. // Percents over 100 or under -100 get set to 0
  2656. percent = (char) i->data[ch3+1];
  2657. if ( ( percent > 100 ) || ( percent < -100 ) )
  2658. percent = 0;
  2659. // Save percent
  2660. percent_table[i->data[ch3]] =
  2661. percent;
  2662. }
  2663. }
  2664.  
  2665. if (!srank)
  2666. {
  2667. for (ch3=6;ch3<=4+(max_percents*2);ch3+=2)
  2668. {
  2669. // Reset all %s
  2670. i->data[ch3] = 0;
  2671. i->data[ch3+1] = 0;
  2672. }
  2673.  
  2674. for (ch3=1;ch3<=5;ch3++)
  2675. {
  2676. // Rebuild %s
  2677. if ( percent_table[ch3] )
  2678. {
  2679. i->data[6 + ( num_percents * 2 )] = ch3;
  2680. i->data[7 + ( num_percents * 2 )] = (unsigned char) percent_table[ch3];
  2681. num_percents ++;
  2682. if ( num_percents == max_percents )
  2683. break;
  2684. }
  2685. }
  2686. }
  2687. }
  2688. }
  2689.  
  2690.  
  2691. unsigned char gcname[24*2];
  2692. unsigned char gctext[176*2];
  2693. unsigned short gccomment[45] = {0x305C};
  2694. unsigned char check_key[32];
  2695. unsigned char check_key2[32];
  2696.  
  2697. void ShipProcessPacket (ORANGE* ship)
  2698. {
  2699. unsigned cv, shipNum;
  2700. int pass;
  2701. unsigned char sv;
  2702. unsigned shop_checksum;
  2703. int key_exists;
  2704. #ifndef NO_CONNECT_TEST
  2705. int tempfd;
  2706. struct sockaddr_in sa;
  2707. #endif
  2708.  
  2709. switch (ship->decryptbuf[0x04])
  2710. {
  2711. case 0x01:
  2712. // Authentication
  2713. //
  2714. // Remember to reconstruct the A0 packet upon a successful authentication!
  2715. // Also, reset the playerCount.
  2716. //
  2717. pass = 1;
  2718. for (sv=0x06;sv<0x14;sv++)
  2719. if (ship->decryptbuf[sv] != ShipPacket00[sv-0x04])
  2720. {
  2721. // Yadda
  2722. pass = 0;
  2723. break;
  2724. }
  2725. if (pass == 0)
  2726. {
  2727. printf ("Ship connected but invalid authorization values were received.\n");
  2728. ShipSend02 (0x00, ship);
  2729. ship->todc = 1;
  2730. }
  2731. else
  2732. {
  2733. //unsigned ch, sameIP;
  2734. unsigned ch2, shipOK;
  2735. //ORANGE* tship;
  2736.  
  2737. shipOK = 1;
  2738.  
  2739. memcpy (&ship->name[0], &ship->decryptbuf[0x2C], 12);
  2740. ship->name[13] = 0x00;
  2741. ship->playerCount = *(unsigned *) &ship->decryptbuf[0x38];
  2742. if (ship->decryptbuf[0x3C] == 0x00)
  2743. *(unsigned *) &ship->shipAddr[0] = *(unsigned *) &ship->listenedAddr[0];
  2744. else
  2745. *(unsigned *) &ship->shipAddr[0] = *(unsigned *) &ship->decryptbuf[0x3C];
  2746. ship->shipAddr[5] = 0;
  2747. ship->shipPort = *(unsigned short*) &ship->decryptbuf[0x40];
  2748.  
  2749. /*
  2750. for (ch=0;ch<serverNumShips;ch++)
  2751. {
  2752. shipNum = serverShipList[ch];
  2753. tship = ships[shipNum];
  2754. if ((tship->shipSockfd >= 0) && (tship->authed == 1))
  2755. {
  2756. sameIP = 1;
  2757. for (ch2=0;ch2<4;ch2++)
  2758. if (ship->shipAddr[ch2] != tship->shipAddr[ch2])
  2759. sameIP = 0;
  2760. if (sameIP == 1)
  2761. {
  2762. printf ("Ship IP address was already registered. Disconnecting...\n");
  2763. ShipSend02 (0x02, ship);
  2764. ship->todc = 1;
  2765. shipOK = 0;
  2766. }
  2767. }
  2768. }*/
  2769.  
  2770. if (shipOK == 1)
  2771. {
  2772. // if (ship->shipAddr[0] == 10) shipOK = 0;
  2773. // if ((ship->shipAddr[0] == 192) && (ship->shipAddr[1] == 168)) shipOK = 0;
  2774. // if ((ship->shipAddr[0] == 127) && (ship->shipAddr[1] == 0) &&
  2775. // (ship->shipAddr[2] == 0) && (ship->shipAddr[3] == 1)) shipOK = 0;
  2776.  
  2777. shop_checksum = *(unsigned *) &ship->decryptbuf[0x42];
  2778. memcpy (&check_key[0], &ship->decryptbuf[0x4A], 32);
  2779.  
  2780. if ( shop_checksum != 0xa3552fda )
  2781. {
  2782. ShipSend02 ( 0x04, ship );
  2783. ship->todc = 1;
  2784. shipOK = 0;
  2785. }
  2786. else
  2787. if ( shipOK )
  2788. {
  2789. ship->key_index = *(unsigned *) &ship->decryptbuf[0x46];
  2790.  
  2791. // update max ship key count on the fly
  2792. #ifdef NO_SQL
  2793. max_ship_keys = 0;
  2794. for (ds=0;ds<num_shipkeys;ds++)
  2795. {
  2796. if (ship_data[ds]->idx >= max_ship_keys)
  2797. max_ship_keys = ship_data[ds]->idx;
  2798. }
  2799. #else
  2800.  
  2801. sprintf (&myQuery[0], "SELECT * from ship_data" );
  2802.  
  2803. if ( ! mysql_query ( myData, &myQuery[0] ) )
  2804. {
  2805. unsigned key_rows;
  2806.  
  2807. myResult = mysql_store_result ( myData );
  2808. key_rows = (int) mysql_num_rows ( myResult );
  2809. max_ship_keys = 0;
  2810. while ( key_rows )
  2811. {
  2812. myRow = mysql_fetch_row ( myResult );
  2813. if ( (unsigned) atoi ( myRow[1] ) > max_ship_keys )
  2814. max_ship_keys = atoi ( myRow[1] );
  2815. key_rows --;
  2816. }
  2817. mysql_free_result ( myResult );
  2818. }
  2819. else
  2820. {
  2821. ship->key_index = 0xFFFF; // MySQL problem, don't allow the ship to connect.
  2822. printf ("Unable to query the key database.\n");
  2823. }
  2824.  
  2825. #endif
  2826.  
  2827. if ( ( ship->key_index ) && ( ship->key_index <= max_ship_keys ) )
  2828. {
  2829. if ( keys_in_use [ ship->key_index ] ) // key already in use?
  2830. {
  2831. ShipSend02 ( 0x06, ship );
  2832. ship->todc = 1;
  2833. shipOK = 0;
  2834. }
  2835. else
  2836. {
  2837. key_exists = 0;
  2838. #ifdef NO_SQL
  2839. ds_found = -1;
  2840.  
  2841. for (ds=0;ds<num_shipkeys;ds++)
  2842. {
  2843. if (ship_data[ds]->idx == ship->key_index)
  2844. {
  2845. ds_found = ds;
  2846. for (ch2=0;ch2<32;ch2++)
  2847. if (ship_data[ds]->rc4key[ch2] != check_key[ch2])
  2848. {
  2849. ds_found = -1;
  2850. break;
  2851. }
  2852. break;
  2853. }
  2854. }
  2855.  
  2856. if (ds_found != -1)
  2857. key_exists = 1;
  2858. else
  2859. {
  2860. ShipSend02 (0x05, ship); // Ship key doesn't exist
  2861. ship->todc = 1;
  2862. shipOK = 0;
  2863. }
  2864. #else
  2865. sprintf (&myQuery[0], "SELECT * from ship_data WHERE idx='%u'", ship->key_index );
  2866.  
  2867. if ( ! mysql_query ( myData, &myQuery[0] ) )
  2868. {
  2869. myResult = mysql_store_result ( myData );
  2870. key_exists = (int) mysql_num_rows ( myResult );
  2871. myRow = mysql_fetch_row ( myResult );
  2872. memcpy (&check_key2[0], myRow[0], 32 ); // 1024-bit key
  2873. for (ch2=0;ch2<32;ch2++)
  2874. if (check_key2[ch2] != check_key[ch2])
  2875. {
  2876. key_exists = 0;
  2877. break;
  2878. }
  2879. }
  2880. else
  2881. {
  2882. ShipSend02 (0x05, ship); // Could not query MySQL or ship key doesn't exist
  2883. mysql_free_result ( myResult );
  2884. ship->todc = 1;
  2885. shipOK = 0;
  2886. }
  2887. #endif
  2888.  
  2889. if ( key_exists )
  2890. {
  2891. #ifndef NO_CONNECT_TEST
  2892. tempfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  2893.  
  2894. memset (&sa, 0, sizeof(sa));
  2895. sa.sin_family = AF_INET;
  2896. *(unsigned *) &sa.sin_addr.s_addr = *(unsigned *) &ship->shipAddr[0];
  2897. sa.sin_port = htons((unsigned short) ship->shipPort);
  2898.  
  2899. if ((tempfd >= 0) && (connect(tempfd, (struct sockaddr*) &sa, sizeof(sa)) >= 0))
  2900. {
  2901. closesocket ( tempfd );
  2902. #endif
  2903.  
  2904. printf ("Ship %s (%u.%u.%u.%u:%u) has been successfully registered.\nPlayer count: %u\nShip key index: %u\n", ship->name,
  2905. ship->shipAddr[0], ship->shipAddr[1], ship->shipAddr[2], ship->shipAddr[3], ship->shipPort,
  2906. ship->playerCount, ship->key_index );
  2907.  
  2908. ship->authed = 1;
  2909. ShipSend02 (0x01, ship); // At this point, we should change keys...
  2910.  
  2911. #ifdef NO_SQL
  2912. memcpy (&ship->user_key[0], &ship_data[ds_found]->rc4key, 128);
  2913. #else
  2914. memcpy (&ship->user_key[0], myRow[0], 128 ); // 1024-bit key
  2915. mysql_free_result ( myResult );
  2916. #endif
  2917.  
  2918. // change keys
  2919.  
  2920. for (ch2=0;ch2<128;ch2++)
  2921. if (ship->key_change[ch2] != -1)
  2922. ship->user_key[ch2] = (unsigned char) ship->key_change[ch2]; // update the key
  2923.  
  2924. prepare_key(&ship->user_key[0], sizeof(ship->user_key), &ship->cs_key);
  2925. prepare_key(&ship->user_key[0], sizeof(ship->user_key), &ship->sc_key);
  2926. #ifndef NO_CONNECT_TEST
  2927. }
  2928. else
  2929. {
  2930. debug ("Could not make a connection to the registering ship... Disconnecting...\n");
  2931. ShipSend02 (0x03, ship);
  2932. ship->todc = 1;
  2933. shipOK = 0;
  2934. }
  2935. #endif
  2936.  
  2937. }
  2938. else
  2939. {
  2940. ShipSend02 ( 0x05, ship );
  2941. ship->todc = 1;
  2942. shipOK = 0;
  2943. }
  2944.  
  2945. }
  2946. }
  2947. else
  2948. initialize_ship ( ship );
  2949. }
  2950. }
  2951. }
  2952. break;
  2953. case 0x03:
  2954. break;
  2955. case 0x04:
  2956. switch (ship->decryptbuf[0x05])
  2957. {
  2958. case 0x00:
  2959. {
  2960. // Send full player data here.
  2961.  
  2962. unsigned guildcard;
  2963. unsigned short slotnum;
  2964. unsigned size;
  2965. int char_exists = 0;
  2966. int bank_exists = 0;
  2967. int teamid;
  2968. unsigned short privlevel;
  2969. CHARDATA* PlayerData;
  2970. unsigned shipid;
  2971. int sockfd;
  2972.  
  2973. guildcard = *(unsigned*) &ship->decryptbuf[0x06];
  2974. slotnum = *(unsigned short*) &ship->decryptbuf[0x0A];
  2975. sockfd = *(int *) &ship->decryptbuf[0x0C];
  2976. shipid = *(unsigned*) &ship->decryptbuf[0x10];
  2977.  
  2978. ship->encryptbuf[0x00] = 0x04;
  2979.  
  2980. *(unsigned*) &ship->encryptbuf[0x02] = *(unsigned*) &ship->decryptbuf[0x06];
  2981. *(unsigned short*) &ship->encryptbuf[0x06] = *(unsigned short*) &ship->decryptbuf[0x0A];
  2982. *(unsigned*) &ship->encryptbuf[0x08] = *(unsigned*) &ship->decryptbuf[0x0C];
  2983.  
  2984. #ifdef NO_SQL
  2985. size = 0x0C;
  2986.  
  2987. ds_found = -1;
  2988.  
  2989. for (ds=0;ds<num_characters;ds++)
  2990. {
  2991. if ((character_data[ds]->guildcard == guildcard) &&
  2992. (character_data[ds]->slot == slotnum))
  2993. {
  2994. ds_found = ds;
  2995. break;
  2996. }
  2997. }
  2998.  
  2999. if (ds_found == -1)
  3000. ship->encryptbuf[0x01] = 0x02; // fail
  3001. else
  3002. {
  3003. PlayerData = (CHARDATA*) &ship->encryptbuf[0x0C];
  3004. memcpy (&ship->encryptbuf[0x0C], &character_data[ds_found]->data, sizeof (CHARDATA) );
  3005. size += sizeof (CHARDATA);
  3006. ship->encryptbuf[0x01] = 0x01; // success
  3007.  
  3008. // Copy common bank into packet.
  3009.  
  3010. ds_found = -1;
  3011.  
  3012. for (ds=0;ds<num_bankdata;ds++)
  3013. {
  3014. if (bank_data[ds]->guildcard == guildcard)
  3015. {
  3016. ds_found = ds;
  3017. memcpy (&ship->encryptbuf[0x0C+sizeof(CHARDATA)], &bank_data[ds]->common_bank, sizeof(BANK));
  3018. break;
  3019. }
  3020. }
  3021.  
  3022. if (ds_found == -1)
  3023. {
  3024. // Common bank needs to be created.
  3025.  
  3026. bank_data[num_bankdata] = malloc (sizeof(L_BANK_DATA));
  3027. bank_data[num_bankdata]->guildcard = guildcard;
  3028. memcpy (&bank_data[num_bankdata]->common_bank, &empty_bank, sizeof (BANK));
  3029. memcpy (&ship->encryptbuf[0x0C+sizeof(CHARDATA)], &empty_bank, sizeof(BANK));
  3030. UpdateDataFile ("bank.dat", num_bankdata, bank_data[num_bankdata], sizeof (L_BANK_DATA), 1);
  3031. num_bankdata++;
  3032. }
  3033.  
  3034. size += sizeof (BANK);
  3035.  
  3036. ds_found = 1;
  3037. for (ds=0;ds<num_accounts;ds++)
  3038. {
  3039. if (account_data[ds]->guildcard == guildcard)
  3040. {
  3041. memcpy (&account_data[ds]->lastchar[0], &PlayerData->name[0], 24);
  3042. teamid = account_data[ds]->teamid;
  3043. privlevel = account_data[ds]->privlevel;
  3044. UpdateDataFile ("account.dat", ds, account_data[ds], sizeof (L_ACCOUNT_DATA), 0);
  3045. break;
  3046. }
  3047. }
  3048.  
  3049. if (teamid != -1)
  3050. {
  3051. //debug ("Retrieving some shit... ");
  3052. // Store the team information in the E7 packet...
  3053. PlayerData->guildCard2 = PlayerData->guildCard;
  3054. PlayerData->teamID = (unsigned) teamid;
  3055. PlayerData->privilegeLevel = privlevel;
  3056. ds_found = -1;
  3057. for (ds=0;ds<num_teams;ds++)
  3058. {
  3059. if (team_data[ds]->teamid == teamid)
  3060. {
  3061. PlayerData->teamName[0] = 0x09;
  3062. PlayerData->teamName[2] = 0x45;
  3063. memcpy ( &PlayerData->teamName[4], team_data[ds]->name, 24 );
  3064. memcpy ( &PlayerData->teamFlag[0], team_data[ds]->flag, 2048 );
  3065. break;
  3066. }
  3067. }
  3068. }
  3069. else
  3070. memset ( &PlayerData->guildCard2, 0, 0x83C );
  3071.  
  3072. PlayerData->unknown15 = 0x00986C84; // ??
  3073. memset ( &PlayerData->teamRewards[0], 0xFF, 4 );
  3074. }
  3075.  
  3076. compressShipPacket ( ship, &ship->encryptbuf[0x00], size );
  3077. #else
  3078.  
  3079. sprintf (&myQuery[0], "SELECT * from character_data WHERE guildcard='%u' AND slot='%u'", guildcard, slotnum );
  3080.  
  3081. //debug ("MySQL query executing ... %s ", &myQuery[0] );
  3082.  
  3083. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3084. {
  3085. myResult = mysql_store_result ( myData );
  3086. char_exists = (int) mysql_num_rows ( myResult );
  3087.  
  3088. size = 0x0C;
  3089.  
  3090. PlayerData = (CHARDATA*) &ship->encryptbuf[0x0C];
  3091.  
  3092. if (char_exists)
  3093. {
  3094. myRow = mysql_fetch_row ( myResult );
  3095. memcpy (&ship->encryptbuf[0x0C], myRow[2], sizeof (CHARDATA) );
  3096. size += sizeof (CHARDATA);
  3097. ship->encryptbuf[0x01] = 0x01; // success
  3098.  
  3099. // Get the common bank or create it
  3100.  
  3101. sprintf (&myQuery[0], "SELECT * from bank_data WHERE guildcard='%u'", guildcard );
  3102.  
  3103. //debug ("MySQL query executing ... %s ", &myQuery[0] );
  3104.  
  3105. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3106. {
  3107. myResult = mysql_store_result ( myData );
  3108. bank_exists = (int) mysql_num_rows ( myResult );
  3109.  
  3110. if (bank_exists)
  3111. {
  3112. // Copy bank
  3113. myRow = mysql_fetch_row ( myResult );
  3114. memcpy (&ship->encryptbuf[0x0C+sizeof(CHARDATA)], myRow[1], sizeof (BANK));
  3115. }
  3116. else
  3117. {
  3118. // Create bank
  3119. memcpy (&ship->encryptbuf[0x0C+sizeof(CHARDATA)], &empty_bank, sizeof (BANK));
  3120. mysql_real_escape_string ( myData, &E7chardata[0], (unsigned char*) &empty_bank, sizeof (BANK) );
  3121.  
  3122. sprintf (&myQuery[0], "INSERT into bank_data (guildcard, data) VALUES ('%u','%s')", guildcard, (char*) &E7chardata[0] );
  3123. if ( mysql_query ( myData, &myQuery[0] ) )
  3124. {
  3125. debug ("Could not create common bank for guild card %u.", guildcard);
  3126. return;
  3127. }
  3128. }
  3129. }
  3130. else
  3131. {
  3132. // Something goofed up, let's just copy the blank bank.
  3133. memcpy (&ship->encryptbuf[0x0C+sizeof(CHARDATA)], &empty_bank, sizeof (BANK));
  3134. }
  3135.  
  3136. size += sizeof (BANK);
  3137.  
  3138.  
  3139. // Update the last used character info...
  3140.  
  3141. mysql_real_escape_string ( myData, &E7chardata[0], (unsigned char*) &PlayerData->name[0], 24 );
  3142. sprintf (&myQuery[0], "UPDATE account_data SET lastchar = '%s' WHERE guildcard = '%u'", (char*) &E7chardata[0], PlayerData->guildCard );
  3143. mysql_query ( myData, &myQuery[0] );
  3144.  
  3145. }
  3146. else
  3147. ship->encryptbuf[0x01] = 0x02; // fail
  3148.  
  3149. mysql_free_result ( myResult );
  3150.  
  3151. if ( ship->encryptbuf[0x01] != 0x02 )
  3152. {
  3153. sprintf (&myQuery[0], "SELECT teamid,privlevel from account_data WHERE guildcard='%u'", guildcard );
  3154.  
  3155. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3156. {
  3157. myResult = mysql_store_result ( myData );
  3158. myRow = mysql_fetch_row ( myResult );
  3159.  
  3160. teamid = atoi (myRow[0]);
  3161. privlevel = atoi (myRow[1]);
  3162.  
  3163. mysql_free_result ( myResult );
  3164.  
  3165. if (teamid != -1)
  3166. {
  3167. //debug ("Retrieving some shit... ");
  3168. // Store the team information in the E7 packet...
  3169. PlayerData->guildCard2 = PlayerData->guildCard;
  3170. PlayerData->teamID = (unsigned) teamid;
  3171. PlayerData->privilegeLevel = privlevel;
  3172. sprintf (&myQuery[0], "SELECT name,flag from team_data WHERE teamid = '%i'", teamid);
  3173. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3174. {
  3175. myResult = mysql_store_result ( myData );
  3176. myRow = mysql_fetch_row ( myResult );
  3177. PlayerData->teamName[0] = 0x09;
  3178. PlayerData->teamName[2] = 0x45;
  3179. memcpy ( &PlayerData->teamName[4], myRow[0], 24 );
  3180. memcpy ( &PlayerData->teamFlag[0], myRow[1], 2048);
  3181.  
  3182. mysql_free_result ( myResult );
  3183. }
  3184. }
  3185. else
  3186. memset ( &PlayerData->guildCard2, 0, 0x83C );
  3187. }
  3188. else
  3189. ship->encryptbuf[0x01] = 0x02; // fail
  3190.  
  3191. PlayerData->unknown15 = 0x00986C84; // ??
  3192. memset ( &PlayerData->teamRewards[0], 0xFF, 4 );
  3193. }
  3194.  
  3195. compressShipPacket ( ship, &ship->encryptbuf[0x00], size );
  3196. }
  3197. else
  3198. debug ("Could not select character information for user %u", guildcard);
  3199. #endif
  3200. }
  3201. break;
  3202. case 0x02:
  3203. {
  3204. unsigned guildcard, ch2;
  3205. unsigned short slotnum;
  3206. CHARDATA* character;
  3207. unsigned short maxFace, maxHair, maxHairColorRed, maxHairColorBlue, maxHairColorGreen,
  3208. maxCostume, maxSkin, maxHead;
  3209.  
  3210. guildcard = *(unsigned*) &ship->decryptbuf[0x06];
  3211. slotnum = *(unsigned short*) &ship->decryptbuf[0x0A];
  3212.  
  3213. character = (CHARDATA*) &ship->decryptbuf[0x0C];
  3214.  
  3215. // Update common bank (A common bank SHOULD exist since they've logged on...)
  3216.  
  3217. #ifdef NO_SQL
  3218.  
  3219. for (ds=0;ds<num_bankdata;ds++)
  3220. {
  3221. if (bank_data[ds]->guildcard == guildcard)
  3222. {
  3223. memcpy (&bank_data[ds]->common_bank, &ship->decryptbuf[0x0C+sizeof(CHARDATA)], sizeof (BANK));
  3224. UpdateDataFile ("bank.dat", ds, bank_data[ds], sizeof (L_BANK_DATA), 0);
  3225. break;
  3226. }
  3227. }
  3228.  
  3229. #else
  3230.  
  3231. mysql_real_escape_string ( myData, &E7chardata[0], (unsigned char*) &ship->decryptbuf[0x0C+sizeof(CHARDATA)], sizeof (BANK) );
  3232. sprintf (&myQuery[0], "UPDATE bank_data set data = '%s' WHERE guildcard = '%u'", (char*) &E7chardata[0], guildcard );
  3233. if ( mysql_query ( myData, &myQuery[0] ) )
  3234. {
  3235. debug ("Could not save common bank for guild card %u.", guildcard);
  3236. return;
  3237. }
  3238.  
  3239. #endif
  3240. // Repair malformed data
  3241.  
  3242. character->name[0] = 0x09; // Filter colored names
  3243. character->name[1] = 0x00;
  3244. character->name[2] = 0x45;
  3245. character->name[3] = 0x00;
  3246. character->name[22] = 0x00;
  3247. character->name[23] = 0x00; // Truncate names too long.
  3248. if (character->level > 199) // Bad levels?
  3249. character->level = 199;
  3250.  
  3251. if ((character->_class == CLASS_HUMAR) ||
  3252. (character->_class == CLASS_HUNEWEARL) ||
  3253. (character->_class == CLASS_RAMAR) ||
  3254. (character->_class == CLASS_RAMARL) ||
  3255. (character->_class == CLASS_FOMARL) ||
  3256. (character->_class == CLASS_FONEWM) ||
  3257. (character->_class == CLASS_FONEWEARL) ||
  3258. (character->_class == CLASS_FOMAR))
  3259. {
  3260. maxFace = 0x05;
  3261. maxHair = 0x0A;
  3262. maxHairColorRed = 0xFF;
  3263. maxHairColorBlue = 0xFF;
  3264. maxHairColorGreen = 0xFF;
  3265. maxCostume = 0x11;
  3266. maxSkin = 0x03;
  3267. maxHead = 0x00;
  3268. }
  3269. else
  3270. {
  3271. maxFace = 0x00;
  3272. maxHair = 0x00;
  3273. maxHairColorRed = 0x00;
  3274. maxHairColorBlue = 0x00;
  3275. maxHairColorGreen = 0x00;
  3276. maxCostume = 0x00;
  3277. maxSkin = 0x18;
  3278. maxHead = 0x04;
  3279. }
  3280. character->nameColorTransparency = 0xFF;
  3281. if (character->sectionID > 0x09)
  3282. character->sectionID = 0x00;
  3283. if (character->proportionX > 0x3F800000)
  3284. character->proportionX = 0x3F800000;
  3285. if (character->proportionY > 0x3F800000)
  3286. character->proportionY = 0x3F800000;
  3287. if (character->face > maxFace)
  3288. character->face = 0x00;
  3289. if (character->hair > maxHair)
  3290. character->hair = 0x00;
  3291. if (character->hairColorRed > maxHairColorRed)
  3292. character->hairColorRed = 0x00;
  3293. if (character->hairColorBlue > maxHairColorBlue)
  3294. character->hairColorBlue = 0x00;
  3295. if (character->hairColorGreen > maxHairColorGreen)
  3296. character->hairColorGreen = 0x00;
  3297. if (character->costume > maxCostume)
  3298. character->costume = 0x00;
  3299. if (character->skin > maxSkin)
  3300. character->skin = 0x00;
  3301. if (character->head > maxHead)
  3302. character->head = 0x00;
  3303.  
  3304. // Let's fix hacked mags and weapons
  3305. for (ch2=0;ch2<character->inventoryUse;ch2++)
  3306. {
  3307. if (character->inventory[ch2].in_use)
  3308. FixItem ( &character->inventory[ch2].item );
  3309. }
  3310.  
  3311. for (ch2=0;ch2<character->bankUse;ch2++)
  3312. {
  3313. if (character->inventory[ch2].in_use)
  3314. FixItem ( (ITEM*) &character->bankInventory[ch2] );
  3315. }
  3316.  
  3317. #ifdef NO_SQL
  3318. for (ds=0;ds<num_characters;ds++)
  3319. {
  3320. if ((character_data[ds]->guildcard == guildcard) &&
  3321. (character_data[ds]->slot == slotnum))
  3322. {
  3323. memcpy (&character_data[ds]->data, &ship->decryptbuf[0x0C], sizeof (CHARDATA));
  3324. UpdateDataFile ("character.dat", ds, character_data[ds], sizeof (L_CHARACTER_DATA), 0);
  3325. break;
  3326. }
  3327. }
  3328. #else
  3329. mysql_real_escape_string ( myData, &E7chardata[0], (unsigned char*) &ship->decryptbuf[0x0C], sizeof (CHARDATA) );
  3330. sprintf (&myQuery[0], "UPDATE character_data set data = '%s' WHERE guildcard = '%u' AND slot = '%u'", (char*) &E7chardata[0], guildcard, slotnum );
  3331. if ( mysql_query ( myData, &myQuery[0] ) )
  3332. {
  3333. debug ("Could not save character information for guild card user %u (%02x)", guildcard, slotnum);
  3334. return;
  3335. }
  3336. else
  3337. #endif
  3338. {
  3339. ship->encryptbuf[0x00] = 0x04;
  3340. ship->encryptbuf[0x01] = 0x03;
  3341. *(unsigned*) &ship->encryptbuf[0x02] = guildcard;
  3342. // Send the OK, data saved.
  3343. compressShipPacket ( ship, &ship->encryptbuf[0x00], 0x06 );
  3344. }
  3345. #ifdef NO_SQL
  3346. for (ds=0;ds<num_keydata;ds++)
  3347. {
  3348. if (key_data[ds]->guildcard == guildcard)
  3349. {
  3350. memcpy (&key_data[ds]->controls, &ship->decryptbuf[0x2FCC], 420);
  3351. UpdateDataFile ("keydata.dat", ds, key_data[ds], sizeof (L_KEY_DATA), 0);
  3352. break;
  3353. }
  3354. }
  3355. #else
  3356. mysql_real_escape_string ( myData, &E7chardata[0], (unsigned char*) &ship->decryptbuf[0x2FCC], 420 );
  3357. sprintf (&myQuery[0], "UPDATE key_data set controls = '%s' WHERE guildcard = '%u'", (char*) &E7chardata[0], guildcard );
  3358. if ( mysql_query ( myData, &myQuery[0] ) )
  3359. debug ("Could not save control information for guild card user %u", guildcard);
  3360. #endif
  3361. }
  3362. }
  3363. break;
  3364. case 0x05:
  3365. break;
  3366. case 0x06:
  3367. break;
  3368. case 0x07:
  3369. switch (ship->decryptbuf[0x05])
  3370. {
  3371. case 0x00:
  3372. // Add a guild card here.
  3373. {
  3374. unsigned clientGcn, friendGcn;
  3375. int gc_priority;
  3376. #ifdef NO_SQL
  3377. unsigned ch2;
  3378. #endif
  3379. #ifndef NO_SQL
  3380. unsigned num_gcs;
  3381. int gc_exists;
  3382. unsigned char friendSecID, friendClass;
  3383. #endif
  3384.  
  3385. clientGcn = *(unsigned*) &ship->decryptbuf[0x06];
  3386. friendGcn = *(unsigned*) &ship->decryptbuf[0x0A];
  3387.  
  3388. #ifdef NO_SQL
  3389. ds_found = -1;
  3390. for (ds=0;ds<num_guilds;ds++)
  3391. {
  3392. if ((guild_data[ds]->accountid == clientGcn) &&
  3393. (guild_data[ds]->friendid == friendGcn))
  3394. {
  3395. ds_found = ds;
  3396. break;
  3397. }
  3398. }
  3399. gc_priority = 0;
  3400. ch2 = 0;
  3401. free_record = -1;
  3402. for (ds=0;ds<num_guilds;ds++)
  3403. {
  3404. if (guild_data[ds]->accountid == clientGcn)
  3405. {
  3406. ch2++;
  3407. if (guild_data[ds]->priority > gc_priority)
  3408. gc_priority = guild_data[ds]->priority;
  3409. }
  3410. if (guild_data[ds]->accountid == 0)
  3411. free_record = ds;
  3412. }
  3413. gc_priority++;
  3414. if ( ( ch2 < 40 ) || ( ds_found != -1 ) )
  3415. {
  3416. if ( ds_found != -1 )
  3417. new_record = 0;
  3418. else
  3419. {
  3420. if (free_record != -1)
  3421. ds_found = free_record;
  3422. else
  3423. {
  3424. new_record = 1;
  3425. ds_found = num_guilds;
  3426. guild_data[num_guilds++] = malloc ( sizeof (L_GUILD_DATA) );
  3427. }
  3428. }
  3429.  
  3430. guild_data[ds_found]->sectionid = ship->decryptbuf[0xD6];
  3431. guild_data[ds_found]->pclass = ship->decryptbuf[0xD7];
  3432.  
  3433. gccomment[44] = 0x0000;
  3434.  
  3435. guild_data[ds_found]->accountid = clientGcn;
  3436. guild_data[ds_found]->friendid = friendGcn;
  3437. guild_data[ds_found]->reserved = 257;
  3438. memcpy (&guild_data[ds_found]->friendname[0], &ship->decryptbuf[0x0E], 24);
  3439. memcpy (&guild_data[ds_found]->friendtext[0], &ship->decryptbuf[0x26], 176);
  3440. memcpy (&guild_data[ds_found]->comment[0], &gccomment[0], 90);
  3441. guild_data[ds_found]->priority = gc_priority;
  3442. UpdateDataFile ("guild.dat", ds_found, guild_data[ds_found], sizeof(L_GUILD_DATA), new_record);
  3443. }
  3444. else
  3445. {
  3446. // Card list full.
  3447. ship->encryptbuf[0x00] = 0x07;
  3448. ship->encryptbuf[0x01] = 0x00;
  3449. *(unsigned*) &ship->encryptbuf[0x02] = clientGcn;
  3450. compressShipPacket (ship, &ship->encryptbuf[0x00], 6);
  3451. }
  3452.  
  3453. #else
  3454.  
  3455. // Delete guild card if it exists...
  3456.  
  3457. sprintf (&myQuery[0], "SELECT * from guild_data WHERE accountid='%u' AND friendid='%u'", clientGcn, friendGcn );
  3458.  
  3459. //printf ("MySQL query %s\n", myQuery );
  3460.  
  3461. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3462. {
  3463. myResult = mysql_store_result ( myData );
  3464. gc_exists = (int) mysql_num_rows ( myResult );
  3465. mysql_free_result ( myResult );
  3466. if ( gc_exists )
  3467. {
  3468. sprintf (&myQuery[0], "DELETE from guild_data WHERE accountid='%u' AND friendid='%u'", clientGcn, friendGcn );
  3469. mysql_query ( myData, &myQuery[0] );
  3470. }
  3471. }
  3472. else
  3473. {
  3474. debug ("Could not delete existing guild card information for user %u", clientGcn);
  3475. return;
  3476. }
  3477.  
  3478. gc_priority = 1;
  3479.  
  3480. sprintf (&myQuery[0], "SELECT * from guild_data WHERE accountid='%u'", clientGcn );
  3481.  
  3482. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3483. {
  3484. myResult = mysql_store_result ( myData );
  3485.  
  3486. num_gcs = (int) mysql_num_rows ( myResult );
  3487. mysql_free_result ( myResult );
  3488.  
  3489. if (num_gcs)
  3490. {
  3491. sprintf (&myQuery[0], "SELECT * from guild_data WHERE accountid='%u' ORDER by priority DESC", clientGcn );
  3492. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3493. {
  3494. myResult = mysql_store_result ( myData );
  3495. myRow = mysql_fetch_row ( myResult );
  3496. gc_priority = atoi ( myRow[8] ) + 1;
  3497. mysql_free_result ( myResult );
  3498. }
  3499. }
  3500. }
  3501. else
  3502. {
  3503. debug ("Could not select existing guild card information for user %u", clientGcn);
  3504. return;
  3505. }
  3506.  
  3507. if ( num_gcs < 40 )
  3508. {
  3509. mysql_real_escape_string (myData, &gcname[0], &ship->decryptbuf[0x0E], 24);
  3510. mysql_real_escape_string (myData, &gctext[0], &ship->decryptbuf[0x26], 176);
  3511.  
  3512. friendSecID = ship->decryptbuf[0xD6];
  3513. friendClass = ship->decryptbuf[0xD7];
  3514.  
  3515. gccomment[44] = 0x0000;
  3516.  
  3517. sprintf (&myQuery[0], "INSERT INTO guild_data (accountid,friendid,friendname,friendtext,sectionid,class,comment,priority) VALUES ('%u','%u','%s','%s','%u','%u','%s','%u')",
  3518. clientGcn, friendGcn, (char*) &gcname[0], (char*) &gctext[0], friendSecID, friendClass, (char*) &gccomment[0], gc_priority );
  3519.  
  3520. if ( mysql_query ( myData, &myQuery[0] ) )
  3521. debug ("Could not insert guild card into database for user %u", clientGcn);
  3522. }
  3523. else
  3524. {
  3525. // Card list full.
  3526. ship->encryptbuf[0x00] = 0x07;
  3527. ship->encryptbuf[0x01] = 0x00;
  3528. *(unsigned*) &ship->encryptbuf[0x02] = clientGcn;
  3529. compressShipPacket (ship, &ship->encryptbuf[0x00], 6);
  3530. }
  3531. #endif
  3532. }
  3533. break;
  3534. case 0x01:
  3535. // Delete a guild card here.
  3536. {
  3537. unsigned clientGcn, deletedGcn;
  3538.  
  3539. clientGcn = *(unsigned*) &ship->decryptbuf[0x06];
  3540. deletedGcn = *(unsigned*) &ship->decryptbuf[0x0A];
  3541.  
  3542. #ifdef NO_SQL
  3543. for (ds=0;ds<num_guilds;ds++)
  3544. {
  3545. if ((guild_data[ds]->accountid == clientGcn) &&
  3546. (guild_data[ds]->friendid == deletedGcn))
  3547. {
  3548. guild_data[ds]->accountid = 0;
  3549. UpdateDataFile ("guild.dat", ds, guild_data[ds], sizeof (L_GUILD_DATA), 0);
  3550. break;
  3551. }
  3552. }
  3553. #else
  3554.  
  3555. sprintf (&myQuery[0], "DELETE from guild_data WHERE accountid = '%u' AND friendid = '%u'", clientGcn, deletedGcn );
  3556. if ( mysql_query ( myData, &myQuery[0] ) )
  3557. debug ("Could not delete guild card for user %u", clientGcn );
  3558. #endif
  3559. }
  3560. break;
  3561. case 0x02:
  3562. // Modify guild card comment.
  3563. {
  3564. unsigned clientGcn, friendGcn;
  3565.  
  3566. clientGcn = *(unsigned*) &ship->decryptbuf[0x06];
  3567. friendGcn = *(unsigned*) &ship->decryptbuf[0x0A];
  3568. #ifdef NO_SQL
  3569. for (ds=0;ds<num_guilds;ds++)
  3570. {
  3571. if ((guild_data[ds]->accountid == clientGcn) &&
  3572. (guild_data[ds]->friendid == friendGcn))
  3573. {
  3574. memcpy (&guild_data[ds]->comment[0], &ship->decryptbuf[0x0E], 0x44);
  3575. guild_data[ds]->comment[34] = 0; // ??
  3576. UpdateDataFile ("guild.dat", ds, guild_data[ds], sizeof(L_GUILD_DATA), 0);
  3577. }
  3578. }
  3579. #else
  3580. mysql_real_escape_string (myData, &gctext[0], &ship->decryptbuf[0x0E], 0x44);
  3581.  
  3582. sprintf (&myQuery[0], "UPDATE guild_data set comment = '%s' WHERE accountid = '%u' AND friendid = '%u'", (char*) &gctext[0], clientGcn, friendGcn );
  3583.  
  3584. if ( mysql_query ( myData, &myQuery[0] ) )
  3585. debug ("Could not update guild card comment for user %u", clientGcn );
  3586. #endif
  3587. }
  3588. break;
  3589. case 0x03:
  3590. // Sort guild card
  3591. {
  3592. unsigned clientGcn, gcn1, gcn2;
  3593. int priority1, priority2, priority_save;
  3594. #ifdef NO_SQL
  3595. L_GUILD_DATA tempgc;
  3596. #endif
  3597.  
  3598. priority1 = -1;
  3599. priority2 = -1;
  3600.  
  3601. clientGcn = *(unsigned*) &ship->decryptbuf[0x06];
  3602. gcn1 = *(unsigned*) &ship->decryptbuf[0x0A];
  3603. gcn2 = *(unsigned*) &ship->decryptbuf[0x0E];
  3604.  
  3605. #ifdef NO_SQL
  3606. for (ds=0;ds<num_guilds;ds++)
  3607. {
  3608. if ((guild_data[ds]->accountid == clientGcn) &&
  3609. (guild_data[ds]->friendid == gcn1))
  3610. {
  3611. priority1 = guild_data[ds]->priority;
  3612. ds_found = ds;
  3613. break;
  3614. }
  3615. }
  3616. #else
  3617. sprintf (&myQuery[0], "SELECT * from guild_data WHERE accountid='%u' AND friendid='%u'", clientGcn, gcn1 );
  3618.  
  3619. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3620. {
  3621. myResult = mysql_store_result ( myData );
  3622. if ( mysql_num_rows ( myResult ) )
  3623. {
  3624. myRow = mysql_fetch_row ( myResult );
  3625. priority1 = atoi (myRow[8]);
  3626. }
  3627. mysql_free_result ( myResult );
  3628. }
  3629. else
  3630. {
  3631. debug ("Could not select existing guild card information for user %u", clientGcn);
  3632. return;
  3633. }
  3634. #endif
  3635.  
  3636. #ifdef NO_SQL
  3637. for (ds=0;ds<num_guilds;ds++)
  3638. {
  3639. if ((guild_data[ds]->accountid == clientGcn) &&
  3640. (guild_data[ds]->friendid == gcn2))
  3641. {
  3642. priority2 = guild_data[ds]->priority;
  3643. ds2 = ds;
  3644. break;
  3645. }
  3646. }
  3647. #else
  3648. sprintf (&myQuery[0], "SELECT * from guild_data WHERE accountid='%u' AND friendid='%u'", clientGcn, gcn2 );
  3649.  
  3650. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3651. {
  3652. myResult = mysql_store_result ( myData );
  3653. if ( mysql_num_rows ( myResult ) )
  3654. {
  3655. myRow = mysql_fetch_row ( myResult );
  3656. priority2 = atoi (myRow[8]);
  3657. }
  3658. mysql_free_result ( myResult );
  3659. }
  3660. else
  3661. {
  3662. debug ("Could not select existing guild card information for user %u", clientGcn);
  3663. return;
  3664. }
  3665. #endif
  3666.  
  3667. if ((priority1 != -1) && (priority2 != -1))
  3668. {
  3669. priority_save = priority1;
  3670. priority1 = priority2;
  3671. priority2 = priority_save;
  3672.  
  3673. #ifdef NO_SQL
  3674. guild_data[ds_found]->priority = priority2;
  3675. guild_data[ds2]->priority = priority_save;
  3676. UpdateDataFile ("guild.dat", ds_found, guild_data[ds2], sizeof (L_GUILD_DATA), 0);
  3677. UpdateDataFile ("guild.dat", ds2, guild_data[ds_found], sizeof (L_GUILD_DATA), 0);
  3678. memcpy (&tempgc, guild_data[ds_found], sizeof (L_GUILD_DATA));
  3679. memcpy (guild_data[ds_found], guild_data[ds2], sizeof (L_GUILD_DATA));
  3680. memcpy (guild_data[ds2], &tempgc, sizeof (L_GUILD_DATA));
  3681. #else
  3682. sprintf (&myQuery[0], "UPDATE guild_data SET priority = '%u' WHERE accountid = '%u' AND friendid = '%u'", priority1, clientGcn, gcn1 );
  3683. if ( mysql_query ( myData, &myQuery[0] ) )
  3684. debug ("Could not update guild card sort information for user %u", clientGcn);
  3685. sprintf (&myQuery[0], "UPDATE guild_data SET priority = '%u' WHERE accountid = '%u' AND friendid = '%u'", priority2, clientGcn, gcn2 );
  3686. if ( mysql_query ( myData, &myQuery[0] ) )
  3687. debug ("Could not update guild card sort information for user %u", clientGcn);
  3688. #endif
  3689. }
  3690. }
  3691. break;
  3692. }
  3693. break;
  3694. case 0x08:
  3695. switch (ship->decryptbuf[0x05])
  3696. {
  3697. case 0x01:
  3698. // Ship requesting a guild search
  3699. {
  3700. unsigned clientGcn, friendGcn, ch, teamid;
  3701. int gc_exists = 0;
  3702. ORANGE* tship;
  3703.  
  3704. friendGcn = *(unsigned*) &ship->decryptbuf[0x06];
  3705. clientGcn = *(unsigned*) &ship->decryptbuf[0x0A];
  3706. teamid = *(unsigned*) &ship->decryptbuf[0x12];
  3707.  
  3708. // First let's be sure our friend has this person's guild card....
  3709.  
  3710. #ifdef NO_SQL
  3711. for (ds=0;ds<num_guilds;ds++)
  3712. {
  3713. if ((guild_data[ds]->accountid == clientGcn) &&
  3714. (guild_data[ds]->friendid == friendGcn))
  3715. {
  3716. gc_exists = 1;
  3717. break;
  3718. }
  3719. }
  3720. #else
  3721.  
  3722. sprintf (&myQuery[0], "SELECT * from guild_data WHERE accountid='%u' AND friendid='%u'", clientGcn, friendGcn );
  3723.  
  3724. //printf ("MySQL query %s\n", myQuery );
  3725.  
  3726. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3727. {
  3728. myResult = mysql_store_result ( myData );
  3729. gc_exists = (int) mysql_num_rows ( myResult );
  3730. mysql_free_result ( myResult );
  3731. }
  3732. else
  3733. {
  3734. debug ("Could not select existing guild card information for user %u", clientGcn);
  3735. return;
  3736. }
  3737. #endif
  3738.  
  3739. #ifdef NO_SQL
  3740. if ( ( gc_exists == 0 ) && ( teamid != 0 ) )
  3741. {
  3742. for (ds=0;ds<num_accounts;ds++)
  3743. {
  3744. if ((account_data[ds]->guildcard == friendGcn) &&
  3745. (account_data[ds]->teamid == teamid))
  3746. {
  3747. gc_exists = 1;
  3748. break;
  3749. }
  3750. }
  3751. }
  3752. #else
  3753. if ( ( gc_exists == 0 ) && ( teamid != 0 ) )
  3754. {
  3755. // Well, they don't appear to have this person's guild card... so let's check the team list...
  3756. sprintf (&myQuery[0], "SELECT * from account_data WHERE guildcard='%u' AND teamid='%u'", friendGcn, teamid );
  3757.  
  3758. //printf ("MySQL query %s\n", myQuery );
  3759.  
  3760. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3761. {
  3762. myResult = mysql_store_result ( myData );
  3763. gc_exists = (int) mysql_num_rows ( myResult );
  3764. mysql_free_result ( myResult );
  3765. }
  3766. else
  3767. {
  3768. debug ("Could not select account information for user %u", friendGcn);
  3769. return;
  3770. }
  3771. }
  3772. #endif
  3773.  
  3774. if ( gc_exists )
  3775. {
  3776. // OK! Let's tell the ships to do the search...
  3777. for (ch=0;ch<serverNumShips;ch++)
  3778. {
  3779. shipNum = serverShipList[ch];
  3780. tship = ships[shipNum];
  3781. if ((tship->shipSockfd >= 0) && (tship->authed == 1))
  3782. compressShipPacket ( tship, &ship->decryptbuf[0x04], 0x1D);
  3783. }
  3784. }
  3785. }
  3786. break;
  3787. case 0x02:
  3788. // Got a hit on a guild search
  3789. cv = *(unsigned*) &ship->decryptbuf[0x0A];
  3790. cv--;
  3791. if (cv < serverMaxShips)
  3792. {
  3793. ORANGE* tship;
  3794.  
  3795. tship = ships[cv];
  3796. if ((tship->shipSockfd >= 0) && (tship->authed == 1))
  3797. compressShipPacket ( tship, &ship->decryptbuf[0x04], 0x140 );
  3798. }
  3799. break;
  3800. case 0x03:
  3801. // Send mail
  3802. {
  3803. unsigned clientGcn, friendGcn, ch, teamid;
  3804. int gc_exists = 0;
  3805. ORANGE* tship;
  3806.  
  3807. friendGcn = *(unsigned*) &ship->decryptbuf[0x36];
  3808. clientGcn = *(unsigned*) &ship->decryptbuf[0x12];
  3809. teamid = *(unsigned*) &ship->decryptbuf[0x462];
  3810.  
  3811. // First let's be sure our friend has this person's guild card....
  3812.  
  3813. #ifdef NO_SQL
  3814. for (ds=0;ds<num_guilds;ds++)
  3815. {
  3816. if ((guild_data[ds]->accountid == clientGcn) &&
  3817. (guild_data[ds]->friendid == friendGcn))
  3818. {
  3819. gc_exists = 1;
  3820. break;
  3821. }
  3822. }
  3823. #else
  3824. sprintf (&myQuery[0], "SELECT * from guild_data WHERE accountid='%u' AND friendid='%u'", clientGcn, friendGcn );
  3825.  
  3826. //printf ("MySQL query %s\n", myQuery );
  3827.  
  3828. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3829. {
  3830. myResult = mysql_store_result ( myData );
  3831. gc_exists = (int) mysql_num_rows ( myResult );
  3832. mysql_free_result ( myResult );
  3833. }
  3834. else
  3835. {
  3836. debug ("Could not select existing guild card information for user %u", clientGcn);
  3837. return;
  3838. }
  3839. #endif
  3840.  
  3841.  
  3842. #ifdef NO_SQL
  3843. if ( ( gc_exists == 0 ) && ( teamid != 0 ) )
  3844. {
  3845. for (ds=0;ds<num_accounts;ds++)
  3846. {
  3847. if ((account_data[ds]->guildcard == friendGcn) &&
  3848. (account_data[ds]->teamid == teamid))
  3849. {
  3850. gc_exists = 1;
  3851. break;
  3852. }
  3853. }
  3854. }
  3855. #else
  3856. if ( ( gc_exists == 0 ) && ( teamid != 0 ) )
  3857. {
  3858. // Well, they don't appear to have this person's guild card... so let's check the team list...
  3859. sprintf (&myQuery[0], "SELECT * from account_data WHERE guildcard='%u' AND teamid='%u'", friendGcn, teamid );
  3860.  
  3861. //printf ("MySQL query %s\n", myQuery );
  3862.  
  3863. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3864. {
  3865. myResult = mysql_store_result ( myData );
  3866. gc_exists = (int) mysql_num_rows ( myResult );
  3867. mysql_free_result ( myResult );
  3868. }
  3869. else
  3870. {
  3871. debug ("Could not select existing account information for user %u", friendGcn);
  3872. return;
  3873. }
  3874. }
  3875. #endif
  3876.  
  3877. if ( gc_exists )
  3878. {
  3879. // OK! Let's tell the ships to do the search...
  3880. for (ch=0;ch<serverNumShips;ch++)
  3881. {
  3882. shipNum = serverShipList[ch];
  3883. tship = ships[shipNum];
  3884. if ((tship->shipSockfd >= 0) && (tship->authed == 1))
  3885. compressShipPacket ( tship, &ship->decryptbuf[0x04], 0x45E );
  3886. }
  3887. }
  3888. }
  3889. break;
  3890. case 0x04:
  3891. // Flag account
  3892. break;
  3893. case 0x05:
  3894. // Ban guild card.
  3895. break;
  3896. case 0x06:
  3897. // Ban IP address.
  3898. break;
  3899. case 0x07:
  3900. // Ban HW info.
  3901. break;
  3902. }
  3903. break;
  3904. case 0x09:
  3905. // Reserved for team functions.
  3906. switch (ship->decryptbuf[0x05])
  3907. {
  3908. case 0x00:
  3909. {
  3910. // Create Team
  3911. //
  3912. // 0x06 = Team name (pre-stripped)
  3913. // 0x1E = Guild card of creator
  3914. //
  3915. //
  3916. unsigned char CreateResult;
  3917. int team_exists, teamid;
  3918. unsigned highid;
  3919. unsigned gcn;
  3920. #ifndef NO_SQL
  3921. unsigned char TeamNameCheck[50];
  3922. #else
  3923. unsigned short char_check;
  3924. int match;
  3925. #endif
  3926.  
  3927. gcn = *(unsigned*) &ship->decryptbuf[0x1E];
  3928. // First check to see if the team exists...
  3929.  
  3930. team_exists = 0;
  3931. highid = 0;
  3932.  
  3933. #ifdef NO_SQL
  3934. free_record = -1;
  3935. for (ds=0;ds<num_teams;ds++)
  3936. {
  3937. if (team_data[ds]->owner == 0)
  3938. free_record = ds;
  3939. if (team_data[ds]->teamid >= highid)
  3940. highid = team_data[ds]->teamid;
  3941. match = 1;
  3942. for (ds2=0;ds2<12;ds2++)
  3943. {
  3944. char_check = *(unsigned short*) &ship->decryptbuf[0x06+(ds2*2)];
  3945. if (team_data[ds]->name[ds2] != char_check)
  3946. {
  3947. match = 0;
  3948. break;
  3949. }
  3950. if (char_check == 0x0000)
  3951. break;
  3952. }
  3953. if (match)
  3954. {
  3955. team_exists = 1;
  3956. break;
  3957. }
  3958. }
  3959. #else
  3960. mysql_real_escape_string (myData, &TeamNameCheck[0], &ship->decryptbuf[0x06], 24);
  3961. sprintf (&myQuery[0], "SELECT * from team_data WHERE name='%s'", (char*) &TeamNameCheck[0] );
  3962. if ( ! mysql_query ( myData, &myQuery[0] ) )
  3963. {
  3964. myResult = mysql_store_result ( myData );
  3965. team_exists = (int) mysql_num_rows ( myResult );
  3966. mysql_free_result ( myResult );
  3967. }
  3968. else
  3969. CreateResult = 1;
  3970. #endif
  3971.  
  3972. if ( !team_exists )
  3973. {
  3974. // It doesn't... but it will now. :)
  3975. #ifdef NO_SQL
  3976. if (free_record != -1)
  3977. {
  3978. new_record = 0;
  3979. ds_found = free_record;
  3980. }
  3981. else
  3982. {
  3983. new_record = 1;
  3984. ds_found = num_teams;
  3985. team_data[num_teams++] = malloc ( sizeof (L_TEAM_DATA) );
  3986. }
  3987. memcpy (&team_data[ds_found]->name[0], &ship->decryptbuf[0x06], 24);
  3988. memcpy (&team_data[ds_found]->flag, &DefaultTeamFlag, 2048);
  3989. team_data[ds_found]->owner = gcn;
  3990. highid++;
  3991. team_data[ds_found]->teamid = teamid = highid;
  3992. UpdateDataFile ("team.dat", ds_found, team_data[ds_found], sizeof (L_TEAM_DATA), new_record);
  3993. CreateResult = 0;
  3994. for (ds=0;ds<num_accounts;ds++)
  3995. {
  3996. if (account_data[ds]->guildcard == gcn)
  3997. {
  3998. account_data[ds]->teamid = highid;
  3999. account_data[ds]->privlevel = 0x40;
  4000. UpdateDataFile ("account.dat", ds, account_data[ds], sizeof (L_ACCOUNT_DATA), 0);
  4001. break;
  4002. }
  4003. }
  4004. #else
  4005. sprintf (&myQuery[0], "INSERT into team_data (name,owner,flag) VALUES ('%s','%u','%s')", (char*) &TeamNameCheck[0], gcn, (char*) &DefaultTeamFlagSlashes[0]);
  4006. if ( ! mysql_query ( myData, &myQuery[0] ) )
  4007. {
  4008. teamid = (unsigned) mysql_insert_id( myData );
  4009. sprintf (&myQuery[0], "UPDATE account_data SET teamid='%u', privlevel='%u' WHERE guildcard='%u'", teamid, 0x40, gcn );
  4010. if ( mysql_query ( myData, &myQuery[0] ) )
  4011. CreateResult = 1;
  4012. else
  4013. CreateResult = 0;
  4014. }
  4015. else
  4016. CreateResult = 1;
  4017. #endif
  4018. }
  4019. else
  4020. CreateResult = 2;
  4021. // 1 = MySQL error
  4022. // 2 = Team Exists
  4023. ship->encryptbuf[0x00] = 0x09;
  4024. ship->encryptbuf[0x01] = 0x00;
  4025. ship->encryptbuf[0x02] = CreateResult;
  4026. *(unsigned*) &ship->encryptbuf[0x03] = gcn;
  4027. memcpy (&ship->encryptbuf[0x07], &DefaultTeamFlag[0], 0x800);
  4028. memcpy (&ship->encryptbuf[0x807], &ship->decryptbuf[0x06], 24);
  4029. *(unsigned*) &ship->encryptbuf[0x81F] = teamid;
  4030. compressShipPacket (ship, &ship->encryptbuf[0x00], 0x823);
  4031. }
  4032. break;
  4033. case 0x01:
  4034. // Update Team Flag
  4035. //
  4036. // 0x06 = Flag (2048/0x800) bytes
  4037. // 0x806 = Guild card of invoking person
  4038. //
  4039. {
  4040. unsigned teamid;
  4041.  
  4042. teamid = *(unsigned*) &ship->decryptbuf[0x806];
  4043. #ifdef NO_SQL
  4044. for (ds=0;ds<num_teams;ds++)
  4045. {
  4046. if (team_data[ds]->teamid == teamid)
  4047. {
  4048. memcpy (&team_data[ds]->flag, &ship->decryptbuf[0x06], 0x800);
  4049. ship->encryptbuf[0x00] = 0x09;
  4050. ship->encryptbuf[0x01] = 0x01;
  4051. ship->encryptbuf[0x02] = 0x01;
  4052. *(unsigned*) &ship->encryptbuf[0x03] = teamid;
  4053. memcpy ( &ship->encryptbuf[0x07], &ship->decryptbuf[0x06], 0x800 );
  4054. compressShipPacket (ship, &ship->encryptbuf[0x00], 0x807);
  4055. UpdateDataFile ("team.dat", ds, team_data[ds], sizeof (L_TEAM_DATA), 0);
  4056. break;
  4057. }
  4058. }
  4059. #else
  4060. mysql_real_escape_string ( myData, &FlagSlashes[0], &ship->decryptbuf[0x06], 0x800 );
  4061. sprintf ( &myQuery[0], "UPDATE team_data SET flag='%s' WHERE teamid='%u'", (char*) &FlagSlashes[0], teamid );
  4062. if (! mysql_query ( myData, &myQuery[0] ) )
  4063. {
  4064. ship->encryptbuf[0x00] = 0x09;
  4065. ship->encryptbuf[0x01] = 0x01;
  4066. ship->encryptbuf[0x02] = 0x01;
  4067. *(unsigned*) &ship->encryptbuf[0x03] = teamid;
  4068. memcpy ( &ship->encryptbuf[0x07], &ship->decryptbuf[0x06], 0x800 );
  4069. compressShipPacket (ship, &ship->encryptbuf[0x00], 0x807);
  4070. }
  4071. else
  4072. {
  4073. debug ("Could not update team flag for team %u", teamid);
  4074. return;
  4075. }
  4076. #endif
  4077.  
  4078. }
  4079. break;
  4080. case 0x02:
  4081. // Dissolve Team
  4082. //
  4083. // 0x06 = Guild card of invoking person
  4084. //
  4085. {
  4086. unsigned teamid;
  4087.  
  4088. teamid = *(unsigned*) &ship->decryptbuf[0x06];
  4089. #ifdef NO_SQL
  4090. for (ds=0;ds<num_teams;ds++)
  4091. {
  4092. if (team_data[ds]->teamid == teamid)
  4093. {
  4094. team_data[ds]->teamid = 0;
  4095. team_data[ds]->owner = 0;
  4096. UpdateDataFile ("team.dat", ds, team_data[ds], sizeof (L_TEAM_DATA), 0);
  4097. break;
  4098. }
  4099. }
  4100.  
  4101. for (ds=0;ds<num_accounts;ds++)
  4102. {
  4103. if (account_data[ds]->teamid == teamid)
  4104. account_data[ds]->teamid = -1;
  4105. UpdateDataFile ("account.dat", ds, account_data[ds], sizeof (L_ACCOUNT_DATA), 0);
  4106. }
  4107. #else
  4108. sprintf (&myQuery[0], "DELETE from team_data WHERE teamid='%u'", teamid );
  4109. mysql_query (myData, &myQuery[0]);
  4110. sprintf (&myQuery[0], "UPDATE account_data SET teamid='-1' WHERE teamid='%u'", teamid);
  4111. mysql_query (myData, &myQuery[0]);
  4112. #endif
  4113. ship->encryptbuf[0x00] = 0x09;
  4114. ship->encryptbuf[0x01] = 0x02;
  4115. ship->encryptbuf[0x02] = 0x01;
  4116. *(unsigned*) &ship->encryptbuf[0x03] = teamid;
  4117. compressShipPacket (ship, &ship->encryptbuf[0x00], 7);
  4118. }
  4119. break;
  4120. case 0x03:
  4121. // Remove member
  4122. //
  4123. // 0x06 = Team ID
  4124. // 0x0A = Guild card
  4125. //
  4126. {
  4127. unsigned gcn, teamid;
  4128.  
  4129. teamid = *(unsigned*) &ship->decryptbuf[0x06];
  4130. gcn = *(unsigned*) &ship->decryptbuf[0x0A];
  4131. #ifdef NO_SQL
  4132. for (ds=0;ds<num_accounts;ds++)
  4133. {
  4134. if ((account_data[ds]->guildcard == gcn) &&
  4135. (account_data[ds]->teamid == teamid))
  4136. {
  4137. account_data[ds]->teamid = -1;
  4138. UpdateDataFile ("account.dat", ds, account_data[ds], sizeof (L_ACCOUNT_DATA), 0);
  4139. break;
  4140. }
  4141. }
  4142. #else
  4143. sprintf (&myQuery[0], "UPDATE account_data SET teamid='-1' WHERE guildcard='%u' AND teamid = '%u'", gcn, teamid);
  4144. mysql_query (myData, &myQuery[0]);
  4145. #endif
  4146. ship->encryptbuf[0x00] = 0x09;
  4147. ship->encryptbuf[0x01] = 0x03;
  4148. ship->encryptbuf[0x02] = 0x01;
  4149. compressShipPacket (ship, &ship->encryptbuf[0x00], 3);
  4150. }
  4151. break;
  4152. case 0x04:
  4153. // Team Chat
  4154. {
  4155. ORANGE* tship;
  4156. unsigned size,ch;
  4157.  
  4158. size = *(unsigned*) &ship->decryptbuf[0x00];
  4159. size -= 4;
  4160.  
  4161. // Just pass the packet along...
  4162. for (ch=0;ch<serverNumShips;ch++)
  4163. {
  4164. shipNum = serverShipList[ch];
  4165. tship = ships[shipNum];
  4166. if ((tship->shipSockfd >= 0) && (tship->authed == 1))
  4167. compressShipPacket ( tship, &ship->decryptbuf[0x04], size );
  4168. }
  4169. }
  4170. break;
  4171. case 0x05:
  4172. // Request team list
  4173. {
  4174. unsigned teamid, packet_offset;
  4175. int num_mates;
  4176. #ifndef NO_SQL
  4177. int ch;
  4178. unsigned guildcard, privlevel;
  4179. #else
  4180. unsigned save_offset;
  4181. #endif
  4182.  
  4183.  
  4184. teamid = *(unsigned*) &ship->decryptbuf[0x06];
  4185. ship->encryptbuf[0x00] = 0x09;
  4186. ship->encryptbuf[0x01] = 0x05;
  4187. *(unsigned*) &ship->encryptbuf[0x02] = teamid;
  4188. *(unsigned*) &ship->encryptbuf[0x06] = *(unsigned*) &ship->decryptbuf[0x0A];
  4189. // @ 0x0A store the size
  4190. ship->encryptbuf[0x0C] = 0xEA;
  4191. ship->encryptbuf[0x0D] = 0x09;
  4192. memset (&ship->encryptbuf[0x0E], 0, 4);
  4193. packet_offset = 0x12;
  4194. #ifdef NO_SQL
  4195. save_offset = packet_offset;
  4196. packet_offset += 4;
  4197. num_mates = 0;
  4198. for (ds=0;ds<num_accounts;ds++)
  4199. {
  4200. if (account_data[ds]->teamid == teamid)
  4201. {
  4202. num_mates++;
  4203. *(unsigned*) &ship->encryptbuf[packet_offset] = num_mates;
  4204. packet_offset += 4;
  4205. *(unsigned*) &ship->encryptbuf[packet_offset] = account_data[ds]->privlevel;
  4206. packet_offset += 4;
  4207. *(unsigned*) &ship->encryptbuf[packet_offset] = account_data[ds]->guildcard;
  4208. packet_offset += 4;
  4209. memcpy (&ship->encryptbuf[packet_offset], &account_data[ds]->lastchar, 24);
  4210. packet_offset += 24;
  4211. memset (&ship->encryptbuf[packet_offset], 0, 8);
  4212. packet_offset += 8;
  4213. }
  4214. }
  4215. *(unsigned*) &ship->encryptbuf[save_offset] = num_mates;
  4216. packet_offset -= 0x0A;
  4217. *(unsigned short*) &ship->encryptbuf[0x0A] = (unsigned short) packet_offset;
  4218. packet_offset += 0x0A;
  4219. compressShipPacket (ship, &ship->encryptbuf[0x00], packet_offset);
  4220. #else
  4221. sprintf (&myQuery[0], "SELECT guildcard,privlevel,lastchar from account_data WHERE teamid='%u'", teamid );
  4222. if ( ! mysql_query ( myData, &myQuery[0] ) )
  4223. {
  4224. myResult = mysql_store_result ( myData );
  4225. num_mates = (int) mysql_num_rows ( myResult );
  4226. *(unsigned*) &ship->encryptbuf[packet_offset] = num_mates;
  4227. packet_offset += 4;
  4228. for (ch=1;ch<=num_mates;ch++)
  4229. {
  4230. myRow = mysql_fetch_row ( myResult );
  4231. guildcard = atoi (myRow[0]);
  4232. privlevel = atoi (myRow[1]);
  4233. *(unsigned*) &ship->encryptbuf[packet_offset] = ch;
  4234. packet_offset += 4;
  4235. *(unsigned*) &ship->encryptbuf[packet_offset] = privlevel;
  4236. packet_offset += 4;
  4237. *(unsigned*) &ship->encryptbuf[packet_offset] = guildcard;
  4238. packet_offset += 4;
  4239. memcpy (&ship->encryptbuf[packet_offset], myRow[2], 24);
  4240. packet_offset += 24;
  4241. memset (&ship->encryptbuf[packet_offset], 0, 8);
  4242. packet_offset += 8;
  4243. }
  4244. mysql_free_result ( myResult );
  4245. packet_offset -= 0x0A;
  4246. *(unsigned short*) &ship->encryptbuf[0x0A] = (unsigned short) packet_offset;
  4247. packet_offset += 0x0A;
  4248. compressShipPacket (ship, &ship->encryptbuf[0x00], packet_offset);
  4249. }
  4250. else
  4251. {
  4252. debug ("Could not get team list for team %u", teamid);
  4253. return;
  4254. }
  4255. #endif
  4256. }
  4257. break;
  4258. case 0x06:
  4259. // Promote member
  4260. //
  4261. // 0x06 = Team ID
  4262. // 0x0A = Guild card
  4263. // 0x0B = New level
  4264. //
  4265. {
  4266. unsigned gcn, teamid;
  4267. unsigned char privlevel;
  4268.  
  4269. teamid = *(unsigned*) &ship->decryptbuf[0x06];
  4270. gcn = *(unsigned*) &ship->decryptbuf[0x0A];
  4271. privlevel = (unsigned char) ship->decryptbuf[0x0E];
  4272. #ifdef NO_SQL
  4273. for (ds=0;ds<num_accounts;ds++)
  4274. {
  4275. if ((account_data[ds]->guildcard == gcn) &&
  4276. (account_data[ds]->teamid == teamid))
  4277. {
  4278. account_data[ds]->privlevel = privlevel;
  4279. UpdateDataFile ("account.dat", ds, account_data[ds], sizeof (L_ACCOUNT_DATA), 0);
  4280. break;
  4281. }
  4282. }
  4283.  
  4284. if (privlevel == 0x40)
  4285. {
  4286. for (ds=0;ds<num_accounts;ds++)
  4287. {
  4288. if (team_data[ds]->teamid == teamid)
  4289. {
  4290. team_data[ds]->owner = gcn;
  4291. UpdateDataFile ("team.dat", ds, team_data[ds], sizeof (L_TEAM_DATA), 0);
  4292. break;
  4293. }
  4294. }
  4295. }
  4296. #else
  4297. sprintf (&myQuery[0], "UPDATE account_data SET privlevel='%u' WHERE guildcard='%u' AND teamid='%u'", privlevel, gcn, teamid);
  4298. mysql_query (myData, &myQuery[0]);
  4299. if (privlevel == 0x40) // Master Transfer
  4300. sprintf (&myQuery[0], "UPDATE team_data SET owner='%u' WHERE teamid='%u'", gcn, teamid);
  4301. mysql_query (myData, &myQuery[0]);
  4302. #endif
  4303. ship->encryptbuf[0x00] = 0x09;
  4304. ship->encryptbuf[0x01] = 0x06;
  4305. ship->encryptbuf[0x02] = 0x01;
  4306. compressShipPacket (ship, &ship->encryptbuf[0x00], 3);
  4307. }
  4308. break;
  4309. case 0x07:
  4310. // Add member
  4311. //
  4312. // 0x06 = Team ID
  4313. // 0x0A = Guild card
  4314. //
  4315. {
  4316. unsigned gcn, teamid;
  4317.  
  4318. teamid = *(unsigned*) &ship->decryptbuf[0x06];
  4319. gcn = *(unsigned*) &ship->decryptbuf[0x0A];
  4320. #ifdef NO_SQL
  4321. for (ds=0;ds<num_accounts;ds++)
  4322. {
  4323. if (account_data[ds]->guildcard == gcn)
  4324. {
  4325. account_data[ds]->teamid = teamid;
  4326. account_data[ds]->privlevel = 0;
  4327. UpdateDataFile ("account.dat", ds, account_data[ds], sizeof (L_ACCOUNT_DATA), 0);
  4328. break;
  4329. }
  4330. }
  4331. #else
  4332. sprintf (&myQuery[0], "UPDATE account_data SET teamid='%u', privlevel='0' WHERE guildcard='%u'", teamid, gcn);
  4333. mysql_query (myData, &myQuery[0]);
  4334. #endif
  4335. ship->encryptbuf[0x00] = 0x09;
  4336. ship->encryptbuf[0x01] = 0x07;
  4337. ship->encryptbuf[0x02] = 0x01;
  4338. compressShipPacket (ship, &ship->encryptbuf[0x00], 3);
  4339. }
  4340. break;
  4341. }
  4342. break;
  4343. case 0x0A:
  4344. break;
  4345. case 0x0B:
  4346. // Checking authentication...
  4347. switch (ship->decryptbuf[0x05])
  4348. {
  4349. case 0x00:
  4350. {
  4351. int security_client_thirtytwo, security_thirtytwo_check;
  4352. long long security_client_sixtyfour, security_sixtyfour_check;
  4353. unsigned char fail_to_auth = 0;
  4354. unsigned gcn;
  4355. unsigned char slotnum;
  4356. unsigned char isgm;
  4357.  
  4358. gcn = *(unsigned*) &ship->decryptbuf[0x06];
  4359. #ifdef NO_SQL
  4360. for (ds=0;ds<num_security;ds++)
  4361. {
  4362. if (security_data[ds]->guildcard == gcn)
  4363. {
  4364. int found_match;
  4365.  
  4366. security_thirtytwo_check = security_data[ds]->thirtytwo;
  4367. security_sixtyfour_check = security_data[ds]->sixtyfour;
  4368. slotnum = security_data[ds]->slotnum;
  4369. isgm = security_data[ds]->isgm;
  4370.  
  4371. found_match = 0;
  4372.  
  4373. security_client_sixtyfour = *(long long*) &ship->decryptbuf[0x0E];
  4374. if (security_client_sixtyfour == security_sixtyfour_check)
  4375. found_match = 1;
  4376.  
  4377. security_client_sixtyfour = *(long long*) &ship->decryptbuf[0x16];
  4378. if (security_client_sixtyfour == security_sixtyfour_check)
  4379. found_match = 1;
  4380.  
  4381. security_client_sixtyfour = *(long long*) &ship->decryptbuf[0x1E];
  4382. if (security_client_sixtyfour == security_sixtyfour_check)
  4383. found_match = 1;
  4384.  
  4385. security_client_sixtyfour = *(long long*) &ship->decryptbuf[0x26];
  4386. if (security_client_sixtyfour == security_sixtyfour_check)
  4387. found_match = 1;
  4388.  
  4389. security_client_sixtyfour = *(long long*) &ship->decryptbuf[0x2E];
  4390. if (security_client_sixtyfour == security_sixtyfour_check)
  4391. found_match = 1;
  4392.  
  4393. if (found_match == 0)
  4394. fail_to_auth = 1;
  4395.  
  4396. security_client_thirtytwo = *(unsigned *) &ship->decryptbuf[0x0A];
  4397.  
  4398. if (security_client_thirtytwo != security_thirtytwo_check)
  4399. fail_to_auth = 1;
  4400.  
  4401. break;
  4402. }
  4403. }
  4404. #else
  4405. sprintf (&myQuery[0], "SELECT * from security_data WHERE guildcard='%u'", gcn );
  4406. // Nom nom nom
  4407. if ( ! mysql_query ( myData, &myQuery[0] ) )
  4408. {
  4409. int num_rows, found_match;
  4410.  
  4411. found_match = 0;
  4412.  
  4413. myResult = mysql_store_result ( myData );
  4414. num_rows = (int) mysql_num_rows ( myResult );
  4415.  
  4416. if (num_rows)
  4417. {
  4418. myRow = mysql_fetch_row ( myResult );
  4419.  
  4420. security_thirtytwo_check = atoi ( myRow[1] );
  4421. memcpy (&security_sixtyfour_check, myRow[2], 8 );
  4422. slotnum = atoi (myRow[3]);
  4423. isgm = atoi (myRow[4]);
  4424.  
  4425. security_client_sixtyfour = *(long long*) &ship->decryptbuf[0x0E];
  4426. if (security_client_sixtyfour == security_sixtyfour_check)
  4427. found_match = 1;
  4428.  
  4429. security_client_sixtyfour = *(long long*) &ship->decryptbuf[0x16];
  4430. if (security_client_sixtyfour == security_sixtyfour_check)
  4431. found_match = 1;
  4432.  
  4433. security_client_sixtyfour = *(long long*) &ship->decryptbuf[0x1E];
  4434. if (security_client_sixtyfour == security_sixtyfour_check)
  4435. found_match = 1;
  4436.  
  4437. security_client_sixtyfour = *(long long*) &ship->decryptbuf[0x26];
  4438. if (security_client_sixtyfour == security_sixtyfour_check)
  4439. found_match = 1;
  4440.  
  4441. security_client_sixtyfour = *(long long*) &ship->decryptbuf[0x2E];
  4442. if (security_client_sixtyfour == security_sixtyfour_check)
  4443. found_match = 1;
  4444.  
  4445. if (found_match == 0)
  4446. fail_to_auth = 1;
  4447. }
  4448. else
  4449. fail_to_auth = 1;
  4450.  
  4451. security_client_thirtytwo = *(unsigned *) &ship->decryptbuf[0x0A];
  4452.  
  4453. if (security_client_thirtytwo != security_thirtytwo_check)
  4454. fail_to_auth = 1;
  4455.  
  4456. mysql_free_result ( myResult );
  4457. }
  4458. else
  4459. fail_to_auth = 1;
  4460. #endif
  4461. ship->encryptbuf[0x00] = 0x0B;
  4462. ship->encryptbuf[0x01] = fail_to_auth;
  4463. *(unsigned *) &ship->encryptbuf[0x02] = gcn;
  4464. ship->encryptbuf[0x06] = slotnum;
  4465. ship->encryptbuf[0x07] = isgm;
  4466. *(unsigned *) &ship->encryptbuf[0x08] = security_thirtytwo_check;
  4467. *(long long*) &ship->encryptbuf[0x0C] = security_sixtyfour_check;
  4468. compressShipPacket ( ship, &ship->encryptbuf[0x00], 0x14 );
  4469. }
  4470. break;
  4471. }
  4472. break;
  4473. case 0x0C:
  4474. break;
  4475. case 0x0D:
  4476. // Various commands related to ship transfers...
  4477. ShipSend0D (ship->decryptbuf[0x05], ship);
  4478. break;
  4479. case 0x0E:
  4480. {
  4481. // Update player count.
  4482. unsigned updateID;
  4483.  
  4484. updateID = *(unsigned *) &ship->decryptbuf[0x06];
  4485. updateID--;
  4486.  
  4487. if ( updateID < serverMaxShips )
  4488. ships[updateID]->playerCount = *(unsigned *) &ship->decryptbuf[0x0A];
  4489.  
  4490. construct0xA0();
  4491. }
  4492. break;
  4493. case 0x0F:
  4494. switch ( ship->decryptbuf[0x05] )
  4495. {
  4496. case 0x00:
  4497. keys_in_use[ ship->key_index ] = 1;
  4498. ShipSend0F (0x01, 0x00, ship);
  4499. break;
  4500. case 0x01:
  4501. if ( ship->decryptbuf[0x06] == 0 )
  4502. ShipSend0F (0x01, 0x01, ship);
  4503. else
  4504. ShipSend0F (0x02, 0x00, ship);
  4505. break;
  4506. case 0x02:
  4507. if ( ship->decryptbuf[0x06] == 0 )
  4508. ShipSend0F (0x02, 0x01, ship);
  4509. else
  4510. ShipSend0F (0x03, 0x00, ship);
  4511. break;
  4512. case 0x03:
  4513. if ( ship->decryptbuf[0x06] == 0 )
  4514. ShipSend0F (0x03, 0x01, ship);
  4515. else
  4516. ShipSend10 (ship);
  4517. break;
  4518. default:
  4519. break;
  4520. }
  4521. break;
  4522. case 0x11:
  4523. ship->last_ping = (unsigned) servertime;
  4524. ship->sent_ping = 0;
  4525. break;
  4526. case 0x12:
  4527. // Global announcement
  4528. {
  4529. ORANGE* tship;
  4530. unsigned size,ch;
  4531.  
  4532. size = *(unsigned *) &ship->decryptbuf[0x00];
  4533. size -= 4;
  4534.  
  4535. // Just pass the packet along...
  4536. for (ch=0;ch<serverNumShips;ch++)
  4537. {
  4538. shipNum = serverShipList[ch];
  4539. tship = ships[shipNum];
  4540. if ((tship->shipSockfd >= 0) && (tship->authed == 1))
  4541. compressShipPacket ( tship, &ship->decryptbuf[0x04], size );
  4542. }
  4543. }
  4544. break;
  4545. default:
  4546. // Unknown packet received from ship?
  4547. ship->todc = 1;
  4548. break;
  4549. }
  4550. }
  4551.  
  4552.  
  4553. void CharacterProcessPacket (BANANA* client)
  4554. {
  4555. char username[17];
  4556. char password[34];
  4557. char hwinfo[18];
  4558. unsigned short clientver;
  4559. char md5password[34] = {0};
  4560. unsigned char MDBuffer[17] = {0};
  4561. unsigned gcn;
  4562. unsigned ch;
  4563. unsigned selected;
  4564. unsigned shipNum;
  4565. int security_client_thirtytwo, security_thirtytwo_check;
  4566. long long security_client_sixtyfour, security_sixtyfour_check;
  4567. #ifdef NO_SQL
  4568. long long truehwinfo;
  4569. #endif
  4570.  
  4571. switch (client->decryptbuf[0x02])
  4572. {
  4573. case 0x05:
  4574. printf ("Client has closed the connection.\n");
  4575. client->todc = 1;
  4576. break;
  4577. case 0x10:
  4578. if ((client->guildcard) && (client->slotnum != -1))
  4579. {
  4580. ORANGE* tship;
  4581.  
  4582. selected = *(unsigned *) &client->decryptbuf[0x0C];
  4583. for (ch=0;ch<serverNumShips;ch++)
  4584. {
  4585. shipNum = serverShipList[ch];
  4586. tship = ships[shipNum];
  4587.  
  4588. if ((tship->shipSockfd >= 0) && (tship->authed == 1) &&
  4589. (tship->shipID == selected))
  4590. {
  4591. Send19 (tship->shipAddr[0], tship->shipAddr[1],
  4592. tship->shipAddr[2], tship->shipAddr[3],
  4593. tship->shipPort, client);
  4594. break;
  4595. }
  4596. }
  4597. }
  4598. break;
  4599. case 0x1D:
  4600. // Do nothing.
  4601. break;
  4602. case 0x93:
  4603. if (!client->sendCheck[RECEIVE_PACKET_93])
  4604. {
  4605. int fail_to_auth = 0;
  4606.  
  4607. clientver = *(unsigned short*) &client->decryptbuf[0x10];
  4608. memcpy (&username[0], &client->decryptbuf[0x1C], 17 );
  4609. memcpy (&password[0], &client->decryptbuf[0x4C], 17 );
  4610. memset (&hwinfo[0], 0, 18);
  4611. #ifdef NO_SQL
  4612. *(long long*) &client->hwinfo[0] = *(long long*) &client->decryptbuf[0x84];
  4613. truehwinfo = *(long long*) &client->decryptbuf[0x84];
  4614. fail_to_auth = 2; // default fail with wrong username
  4615. for (ds=0;ds<num_accounts;ds++)
  4616. {
  4617. if (!strcmp(&account_data[ds]->username[0], &username[0]))
  4618. {
  4619. fail_to_auth = 0;
  4620. sprintf (&password[strlen(password)], "_%u_salt", account_data[ds]->regtime );
  4621. MDString (&password[0], &MDBuffer[0] );
  4622. for (ch=0;ch<16;ch++)
  4623. sprintf (&md5password[ch*2], "%02x", (unsigned char) MDBuffer[ch]);
  4624. md5password[32] = 0;
  4625. if (!strcmp(&md5password[0],&account_data[ds]->password[0]))
  4626. {
  4627. if (account_data[ds]->isbanned)
  4628. fail_to_auth = 3;
  4629. if (!account_data[ds]->isactive)
  4630. fail_to_auth = 5;
  4631. if (!fail_to_auth)
  4632. gcn = account_data[ds]->guildcard;
  4633. if (client->decryptbuf[0x10] != PSO_CLIENT_VER)
  4634. fail_to_auth = 7;
  4635. client->isgm = account_data[ds]->isgm;
  4636. }
  4637. else
  4638. fail_to_auth = 2;
  4639. break;
  4640. }
  4641. }
  4642.  
  4643. // DO HW BAN LATER
  4644.  
  4645. if (!fail_to_auth)
  4646. {
  4647. for (ds=0;ds<num_security;ds++)
  4648. {
  4649. if (security_data[ds]->guildcard == gcn)
  4650. {
  4651. int found_match;
  4652.  
  4653. client->dress_flag = 0;
  4654. for (ch=0;ch<MAX_DRESS_FLAGS;ch++)
  4655. {
  4656. if (dress_flags[ch].guildcard == gcn)
  4657. client->dress_flag = 1;
  4658. }
  4659.  
  4660. security_thirtytwo_check = security_data[ds]->thirtytwo;
  4661. security_sixtyfour_check = security_data[ds]->sixtyfour;
  4662. client->slotnum = security_data[ds]->slotnum;
  4663.  
  4664. found_match = 0;
  4665.  
  4666. security_client_sixtyfour = *(long long*) &client->decryptbuf[0x8C];
  4667. if (security_client_sixtyfour == security_sixtyfour_check)
  4668. found_match = 1;
  4669.  
  4670. security_client_sixtyfour = *(long long*) &client->decryptbuf[0x94];
  4671. if (security_client_sixtyfour == security_sixtyfour_check)
  4672. found_match = 1;
  4673.  
  4674. security_client_sixtyfour = *(long long*) &client->decryptbuf[0x9C];
  4675. if (security_client_sixtyfour == security_sixtyfour_check)
  4676. found_match = 1;
  4677.  
  4678. security_client_sixtyfour = *(long long*) &client->decryptbuf[0xA4];
  4679. if (security_client_sixtyfour == security_sixtyfour_check)
  4680. found_match = 1;
  4681.  
  4682. security_client_sixtyfour = *(long long*) &client->decryptbuf[0xAC];
  4683. if (security_client_sixtyfour == security_sixtyfour_check)
  4684. found_match = 1;
  4685.  
  4686. if (found_match == 0)
  4687. fail_to_auth = 6;
  4688.  
  4689. security_client_thirtytwo = *(unsigned *) &client->decryptbuf[0x18];
  4690.  
  4691. if (security_client_thirtytwo == 0)
  4692. client->sendingchars = 1;
  4693. else
  4694. {
  4695. client->sendingchars = 0;
  4696. if (security_client_thirtytwo != security_thirtytwo_check)
  4697. fail_to_auth = 6;
  4698. }
  4699. break;
  4700. }
  4701. }
  4702. }
  4703.  
  4704. #else
  4705. mysql_real_escape_string ( myData, &hwinfo[0], &client->decryptbuf[0x84], 8);
  4706. memcpy (&client->hwinfo[0], &hwinfo[0], 18);
  4707. sprintf (&myQuery[0], "SELECT * from account_data WHERE username='%s'", username );
  4708.  
  4709. // Check to see if that account already exists.
  4710. if ( ! mysql_query ( myData, &myQuery[0] ) )
  4711. {
  4712. int num_rows, max_fields;
  4713.  
  4714. myResult = mysql_store_result ( myData );
  4715. num_rows = (int) mysql_num_rows ( myResult );
  4716.  
  4717. if (num_rows)
  4718. {
  4719. myRow = mysql_fetch_row ( myResult );
  4720. max_fields = mysql_num_fields ( myResult );
  4721. sprintf (&password[strlen(password)], "_%s_salt", myRow[3] );
  4722. MDString (&password[0], &MDBuffer[0] );
  4723. for (ch=0;ch<16;ch++)
  4724. sprintf (&md5password[ch*2], "%02x", (unsigned char) MDBuffer[ch]);
  4725. md5password[32] = 0;
  4726. if (!strcmp(&md5password[0],myRow[1]))
  4727. {
  4728. if (!strcmp("1", myRow[8]))
  4729. fail_to_auth = 3;
  4730. if (!strcmp("1", myRow[9]))
  4731. fail_to_auth = 4;
  4732. if (!strcmp("0", myRow[10]))
  4733. fail_to_auth = 5;
  4734. if (!fail_to_auth)
  4735. gcn = atoi (myRow[6]);
  4736. if (client->decryptbuf[0x10] != PSO_CLIENT_VER)
  4737. fail_to_auth = 7;
  4738. client->isgm = atoi (myRow[7]);
  4739. }
  4740. else
  4741. fail_to_auth = 2;
  4742. }
  4743. else
  4744. fail_to_auth = 2;
  4745.  
  4746. mysql_free_result ( myResult );
  4747. }
  4748. else
  4749. fail_to_auth = 1; // MySQL error.
  4750.  
  4751. // Hardware info ban check...
  4752.  
  4753. sprintf (&myQuery[0], "SELECT * from hw_bans WHERE hwinfo='%s'", hwinfo );
  4754. if ( ! mysql_query ( myData, &myQuery[0] ) )
  4755. {
  4756. myResult = mysql_store_result ( myData );
  4757. if ((int) mysql_num_rows ( myResult ))
  4758. fail_to_auth = 3;
  4759. mysql_free_result ( myResult );
  4760. }
  4761. else
  4762. fail_to_auth = 1;
  4763.  
  4764. if ( fail_to_auth == 0)
  4765. {
  4766. sprintf (&myQuery[0], "SELECT * from security_data WHERE guildcard='%u'", gcn );
  4767. // Nom nom nom
  4768. if ( ! mysql_query ( myData, &myQuery[0] ) )
  4769. {
  4770. int num_rows, found_match;
  4771.  
  4772. found_match = 0;
  4773.  
  4774. myResult = mysql_store_result ( myData );
  4775. num_rows = (int) mysql_num_rows ( myResult );
  4776.  
  4777. if (num_rows)
  4778. {
  4779. myRow = mysql_fetch_row ( myResult );
  4780.  
  4781. client->dress_flag = 0;
  4782. for (ch=0;ch<MAX_DRESS_FLAGS;ch++)
  4783. {
  4784. if (dress_flags[ch].guildcard == gcn)
  4785. client->dress_flag = 1;
  4786. }
  4787.  
  4788. security_thirtytwo_check = atoi ( myRow[1] );
  4789. memcpy (&security_sixtyfour_check, myRow[2], 8 );
  4790. client->slotnum = atoi (myRow[3]);
  4791.  
  4792. security_client_sixtyfour = *(long long*) &client->decryptbuf[0x8C];
  4793. if (security_client_sixtyfour == security_sixtyfour_check)
  4794. found_match = 1;
  4795.  
  4796. security_client_sixtyfour = *(long long*) &client->decryptbuf[0x94];
  4797. if (security_client_sixtyfour == security_sixtyfour_check)
  4798. found_match = 1;
  4799.  
  4800. security_client_sixtyfour = *(long long*) &client->decryptbuf[0x9C];
  4801. if (security_client_sixtyfour == security_sixtyfour_check)
  4802. found_match = 1;
  4803.  
  4804. security_client_sixtyfour = *(long long*) &client->decryptbuf[0xA4];
  4805. if (security_client_sixtyfour == security_sixtyfour_check)
  4806. found_match = 1;
  4807.  
  4808. security_client_sixtyfour = *(long long*) &client->decryptbuf[0xAC];
  4809. if (security_client_sixtyfour == security_sixtyfour_check)
  4810. found_match = 1;
  4811.  
  4812. if (found_match == 0)
  4813. {
  4814. debug ("Couldn't find 64-bit information.");
  4815. fail_to_auth = 6;
  4816. }
  4817. }
  4818. else
  4819. fail_to_auth = 6;
  4820.  
  4821. security_client_thirtytwo = *(unsigned *) &client->decryptbuf[0x18];
  4822.  
  4823. if (security_client_thirtytwo == 0)
  4824. client->sendingchars = 1;
  4825. else
  4826. {
  4827. client->sendingchars = 0;
  4828. if (security_client_thirtytwo != security_thirtytwo_check)
  4829. {
  4830. fail_to_auth = 6;
  4831. debug ("Couldn't find 32-bit information.");
  4832. debug ("Looking for %i, have %i", security_thirtytwo_check, security_client_thirtytwo);
  4833. }
  4834. }
  4835. mysql_free_result ( myResult );
  4836. }
  4837. }
  4838. #endif
  4839.  
  4840. switch (fail_to_auth)
  4841. {
  4842. case 0x00:
  4843. // OK
  4844. memcpy (&client->encryptbuf[0], &PacketE6[0], sizeof (PacketE6));
  4845. *(unsigned *) &client->encryptbuf[0x10] = gcn;
  4846. client->guildcard = gcn;
  4847. _itoa (gcn, &client->guildcard_string[0], 10); /* auth'd, bitch */
  4848. // Store some security shit in the E6 packet.
  4849. *(long long*) &client->encryptbuf[0x38] = security_sixtyfour_check;
  4850. if (security_thirtytwo_check == 0)
  4851. {
  4852. for (ch=0;ch<4;ch++)
  4853. MDBuffer[ch] = (unsigned char)( rand() % 256 );
  4854. security_thirtytwo_check = *(unsigned *) &MDBuffer[0];
  4855. #ifdef NO_SQL
  4856. for (ds=0;ds<num_security;ds++)
  4857. {
  4858. if (security_data[ds]->guildcard == gcn)
  4859. {
  4860. security_data[ds]->thirtytwo = security_thirtytwo_check;
  4861. UpdateDataFile ("security.dat", ds, security_data[ds], sizeof (L_SECURITY_DATA), 0);
  4862. break;
  4863. }
  4864. }
  4865. #else
  4866. sprintf (&myQuery[0], "UPDATE security_data set thirtytwo = '%i' WHERE guildcard = '%u'", security_thirtytwo_check, gcn );
  4867. // Nom, nom, nom.
  4868. if ( mysql_query ( myData, &myQuery[0] ) )
  4869. {
  4870. Send1A ("Couldn't update security information in MySQL database.\nPlease contact the server administrator.", client);
  4871. client->todc = 1;
  4872. return;
  4873. }
  4874. #endif
  4875. }
  4876. *(unsigned *) &client->encryptbuf[0x14] = security_thirtytwo_check;
  4877. cipher_ptr = &client->server_cipher;
  4878. encryptcopy (client, &client->encryptbuf[0], sizeof (PacketE6));
  4879. if (client->slotnum != -1)
  4880. {
  4881. if (client->decryptbuf[0x16] != 0x04)
  4882. {
  4883. Send1A ("Client/Server synchronization error.", client);
  4884. client->todc = 1;
  4885. }
  4886. else
  4887. {
  4888. // User has completed the login process, after updating the SQL info with their
  4889. // access information, give 'em the ship select screen.
  4890. #ifdef NO_SQL
  4891. for (ds=0;ds<num_accounts;ds++)
  4892. {
  4893. if (account_data[ds]->guildcard == gcn)
  4894. {
  4895. memcpy (&account_data[ds]->lastip[0], &client->IP_Address[0], 16);
  4896. account_data[ds]->lasthwinfo = truehwinfo;
  4897. UpdateDataFile ("account.dat", ds, account_data[ds], sizeof (L_ACCOUNT_DATA), 0);
  4898. break;
  4899. }
  4900. }
  4901. #else
  4902. sprintf (&myQuery[0], "UPDATE account_data set lastip = '%s', lasthwinfo = '%s' WHERE username = '%s'", client->IP_Address, hwinfo, username );
  4903. mysql_query ( myData, &myQuery[0] );
  4904. #endif
  4905. client->lastTick = (unsigned) servertime;
  4906. SendB1 (client);
  4907. SendA0 (client);
  4908. SendEE (&Welcome_Message[0], client);
  4909. }
  4910. }
  4911. break;
  4912. case 0x01:
  4913. // MySQL error.
  4914. Send1A ("There is a problem with the MySQL database.\n\nPlease contact the server administrator.", client);
  4915. break;
  4916. case 0x02:
  4917. // Username or password incorrect.
  4918. Send1A ("Username or password is incorrect.", client);
  4919. break;
  4920. case 0x03:
  4921. // Account is banned.
  4922. Send1A ("You are banned from this server.", client);
  4923. break;
  4924. case 0x04:
  4925. // Already logged on.
  4926. Send1A ("This account is already logged on.\n\nPlease wait 120 seconds and try again.", client);
  4927. break;
  4928. case 0x05:
  4929. // Account has not completed e-mail validation.
  4930. Send1A ("Please complete the registration of this account through\ne-mail validation.\n\nThank you.", client);
  4931. break;
  4932. case 0x06:
  4933. // Security violation.
  4934. Send1A ("Security violation.", client);
  4935. break;
  4936. case 0x07:
  4937. // Client version too old.
  4938. Send1A ("Your client executable is too old.\nPlease update your client through the patch server.", client);
  4939. break;
  4940. default:
  4941. Send1A ("Unknown error.", client);
  4942. break;
  4943. }
  4944. client->sendCheck[RECEIVE_PACKET_93] = 0x01;
  4945. }
  4946. break;
  4947. case 0xDC:
  4948. switch (client->decryptbuf[0x03])
  4949. {
  4950. case 0x03:
  4951. // Send another chunk of guild card data.
  4952. if ((client->decryptbuf[0x08] == 0x01) && (client->decryptbuf[0x10] == 0x01))
  4953. SendDC (0x00, client->decryptbuf[0x0C], client );
  4954. break;
  4955. default:
  4956. break;
  4957. }
  4958. break;
  4959. case 0xE0:
  4960. // The gamepad, keyboard config, and other options....
  4961. SendE2 (client);
  4962. break;
  4963. case 0xE3:
  4964. // Client selecting or requesting character.
  4965. SendE4_E5(client->decryptbuf[0x08], client->decryptbuf[0x0C], client);
  4966. break;
  4967. case 0xE5:
  4968. // Create a character in slot.
  4969. // Check invalid data and store character in MySQL store.
  4970. AckCharacter_Creation ( client->decryptbuf[0x08], client );
  4971. break;
  4972. case 0xE8:
  4973. switch (client->decryptbuf[0x03])
  4974. {
  4975. case 0x01:
  4976. // Client just communicating the expected guild card checksum. (Ignoring for now.)
  4977. SendE8 (client);
  4978. break;
  4979. case 0x03:
  4980. // Client requesting guild card checksum.
  4981. SendDC (0x01, 0, client);
  4982. break;
  4983. default:
  4984. break;
  4985. }
  4986. break;
  4987. case 0xEB:
  4988. switch (client->decryptbuf[0x03])
  4989. {
  4990. case 0x03:
  4991. // Send another chunk of the parameter files.
  4992. SendEB (0x02, client->decryptbuf[0x04], client );
  4993. break;
  4994. case 0x04:
  4995. // Send header for parameter files.
  4996. SendEB (0x01, 0x00, client);
  4997. break;
  4998. }
  4999. break;
  5000. case 0xEC:
  5001. if (client->decryptbuf[0x08] == 0x02)
  5002. {
  5003. // Set the dressing room flag (Don't overwrite the character...)
  5004. for (ch=0;ch<MAX_DRESS_FLAGS;ch++)
  5005. if (dress_flags[ch].guildcard == 0)
  5006. {
  5007. dress_flags[ch].guildcard = client->guildcard;
  5008. dress_flags[ch].flagtime = (unsigned) servertime;
  5009. break;
  5010. if (ch == (MAX_DRESS_FLAGS - 1))
  5011. {
  5012. Send1A ("Unable to save dress flag.", client);
  5013. client->todc = 1;
  5014. }
  5015. }
  5016. client->dress_flag = 1;
  5017. }
  5018. break;
  5019. default:
  5020. break;
  5021. }
  5022. }
  5023.  
  5024. void LoginProcessPacket (BANANA* client)
  5025. {
  5026. char username[17];
  5027. char password[34];
  5028. long long security_sixtyfour_check;
  5029. char hwinfo[18];
  5030. unsigned short clientver;
  5031. char md5password[34] = {0};
  5032. unsigned char MDBuffer[17] = {0};
  5033. unsigned gcn;
  5034. unsigned ch,connectNum,shipNum;
  5035. #ifdef NO_SQL
  5036. long long truehwinfo;
  5037. #endif
  5038. ORANGE* tship;
  5039. #ifndef NO_SQL
  5040. char security_sixtyfour_binary[18];
  5041. #endif
  5042.  
  5043.  
  5044. /* Only packet we're expecting during the login is 0x93 and 0x05. */
  5045.  
  5046. switch (client->decryptbuf[0x02])
  5047. {
  5048. case 0x05:
  5049. printf ("Client has closed the connection.\n");
  5050. client->todc = 1;
  5051. break;
  5052. case 0x93:
  5053. if (!client->sendCheck[RECEIVE_PACKET_93])
  5054. {
  5055. int fail_to_auth = 0;
  5056. clientver = *(unsigned short*) &client->decryptbuf[0x10];
  5057. memcpy (&username[0], &client->decryptbuf[0x1C], 17 );
  5058. memcpy (&password[0], &client->decryptbuf[0x4C], 17 );
  5059. memset (&hwinfo[0], 0, 18);
  5060. #ifdef NO_SQL
  5061. *(long long*) &client->hwinfo[0] = *(long long*) &client->decryptbuf[0x84];
  5062. truehwinfo = *(long long*) &client->decryptbuf[0x84];
  5063. fail_to_auth = 2; // default fail with wrong username
  5064. for (ds=0;ds<num_accounts;ds++)
  5065. {
  5066. if (!strcmp(&account_data[ds]->username[0], &username[0]))
  5067. {
  5068. fail_to_auth = 0;
  5069. sprintf (&password[strlen(password)], "_%u_salt", account_data[ds]->regtime );
  5070. MDString (&password[0], &MDBuffer[0] );
  5071. for (ch=0;ch<16;ch++)
  5072. sprintf (&md5password[ch*2], "%02x", (unsigned char) MDBuffer[ch]);
  5073. md5password[32] = 0;
  5074. if (!strcmp(&md5password[0],&account_data[ds]->password[0]))
  5075. {
  5076. if (account_data[ds]->isbanned)
  5077. fail_to_auth = 3;
  5078. if (!account_data[ds]->isactive)
  5079. fail_to_auth = 5;
  5080. if (!fail_to_auth)
  5081. gcn = account_data[ds]->guildcard;
  5082. if ((strcmp(&client->decryptbuf[0x8C], PSO_CLIENT_VER_STRING) != 0) || (client->decryptbuf[0x10] != PSO_CLIENT_VER))
  5083. fail_to_auth = 7;
  5084. client->isgm = account_data[ds]->isgm;
  5085. }
  5086. else
  5087. fail_to_auth = 2;
  5088. break;
  5089. }
  5090. }
  5091.  
  5092. // DO HW BAN LATER
  5093.  
  5094. #else
  5095. mysql_real_escape_string ( myData, &hwinfo[0], &client->decryptbuf[0x84], 8);
  5096. memcpy (&client->hwinfo[0], &hwinfo[0], 18);
  5097.  
  5098. sprintf (&myQuery[0], "SELECT * from account_data WHERE username='%s'", username );
  5099.  
  5100. // Check to see if that account already exists.
  5101. if ( ! mysql_query ( myData, &myQuery[0] ) )
  5102. {
  5103. int num_rows, max_fields;
  5104.  
  5105. myResult = mysql_store_result ( myData );
  5106. num_rows = (int) mysql_num_rows ( myResult );
  5107.  
  5108. if (num_rows)
  5109. {
  5110. myRow = mysql_fetch_row ( myResult );
  5111. max_fields = mysql_num_fields ( myResult );
  5112. sprintf (&password[strlen(password)], "_%s_salt", myRow[3] );
  5113. MDString (&password[0], &MDBuffer[0] );
  5114. for (ch=0;ch<16;ch++)
  5115. sprintf (&md5password[ch*2], "%02x", (unsigned char) MDBuffer[ch]);
  5116. md5password[32] = 0;
  5117. if (!strcmp(&md5password[0],myRow[1]))
  5118. {
  5119. if (!strcmp("1", myRow[8]))
  5120. fail_to_auth = 3;
  5121. if (!strcmp("1", myRow[9]))
  5122. fail_to_auth = 4;
  5123. if (!strcmp("0", myRow[10]))
  5124. fail_to_auth = 5;
  5125. if (!fail_to_auth)
  5126. gcn = atoi (myRow[6]);
  5127. if ((strcmp(&client->decryptbuf[0x8C], PSO_CLIENT_VER_STRING) != 0) || (client->decryptbuf[0x10] != PSO_CLIENT_VER))
  5128. fail_to_auth = 7;
  5129. client->isgm = atoi (myRow[7]);
  5130. }
  5131. else
  5132. fail_to_auth = 2;
  5133. }
  5134. else
  5135. fail_to_auth = 2;
  5136. mysql_free_result ( myResult );
  5137. }
  5138. else
  5139. fail_to_auth = 1; // MySQL error.
  5140.  
  5141. // Hardware info ban check...
  5142.  
  5143. sprintf (&myQuery[0], "SELECT * from hw_bans WHERE hwinfo='%s'", hwinfo );
  5144. if ( ! mysql_query ( myData, &myQuery[0] ) )
  5145. {
  5146. myResult = mysql_store_result ( myData );
  5147. if ((int) mysql_num_rows ( myResult ))
  5148. fail_to_auth = 3;
  5149. mysql_free_result ( myResult );
  5150. }
  5151. else
  5152. fail_to_auth = 1;
  5153. #endif
  5154.  
  5155. switch (fail_to_auth)
  5156. {
  5157. case 0x00:
  5158. // OK
  5159.  
  5160. // If guild card is connected to the login server already, disconnect it.
  5161.  
  5162. for (ch=0;ch<serverNumConnections;ch++)
  5163. {
  5164. connectNum = serverConnectionList[ch];
  5165. if (connections[connectNum]->guildcard == gcn)
  5166. {
  5167. Send1A ("This account has just logged on.\n\nYou are now being disconnected.", connections[connectNum]);
  5168. connections[connectNum]->todc = 1;
  5169. break;
  5170. }
  5171. }
  5172.  
  5173. // If guild card is connected to ships, disconnect it.
  5174.  
  5175. for (ch=0;ch<serverNumShips;ch++)
  5176. {
  5177. shipNum = serverShipList[ch];
  5178. tship = ships[shipNum];
  5179. if ((tship->shipSockfd >= 0) && (tship->authed == 1))
  5180. ShipSend08 (gcn, tship);
  5181. }
  5182.  
  5183.  
  5184. memcpy (&client->encryptbuf[0], &PacketE6[0], sizeof (PacketE6));
  5185. *(unsigned *) &client->encryptbuf[0x10] = gcn;
  5186.  
  5187. // Store some security shit
  5188. for (ch=0;ch<8;ch++)
  5189. client->encryptbuf[0x38+ch] = (unsigned char) rand() % 255;
  5190.  
  5191. security_sixtyfour_check = *(long long*) &client->encryptbuf[0x38];
  5192.  
  5193. // Nom, nom, nom.
  5194.  
  5195. #ifdef NO_SQL
  5196. free_record = -1;
  5197. new_record = 1;
  5198. for (ds=0;ds<num_security;ds++)
  5199. {
  5200. if (security_data[ds]->guildcard == gcn)
  5201. security_data[ds]->guildcard = 0;
  5202. UpdateDataFile ("security.dat", ds, security_data[ds], sizeof (L_SECURITY_DATA), 0);
  5203. if (security_data[ds]->guildcard == 0)
  5204. {
  5205. free_record = ds;
  5206. new_record = 0;
  5207. }
  5208. }
  5209. if (new_record)
  5210. {
  5211. free_record = num_security++;
  5212. security_data[free_record] = malloc ( sizeof (L_SECURITY_DATA) );
  5213. }
  5214. security_data[free_record]->guildcard = gcn;
  5215. security_data[free_record]->thirtytwo = 0;
  5216. security_data[free_record]->sixtyfour = security_sixtyfour_check;
  5217. security_data[free_record]->isgm = client->isgm;
  5218. security_data[free_record]->slotnum = -1;
  5219. UpdateDataFile ("security.dat", free_record, security_data[free_record], sizeof (L_SECURITY_DATA), new_record);
  5220. #else
  5221. sprintf (&myQuery[0], "DELETE from security_data WHERE guildcard = '%u'", gcn );
  5222. mysql_query ( myData, &myQuery[0] );
  5223. mysql_real_escape_string ( myData, &security_sixtyfour_binary[0], (char*) &security_sixtyfour_check, 8);
  5224. sprintf (&myQuery[0], "INSERT INTO security_data (guildcard, thirtytwo, sixtyfour, isgm) VALUES ('%u','0','%s', '%u')", gcn, (char*) &security_sixtyfour_binary, client->isgm );
  5225. if ( mysql_query ( myData, &myQuery[0] ) )
  5226. {
  5227. Send1A ("Couldn't update security information in MySQL database.\nPlease contact the server administrator.", client);
  5228. client->todc = 1;
  5229. return;
  5230. }
  5231. #endif
  5232.  
  5233. cipher_ptr = &client->server_cipher;
  5234. encryptcopy (client, &client->encryptbuf[0], sizeof (PacketE6));
  5235.  
  5236. Send19 (serverIP[0], serverIP[1], serverIP[2], serverIP[3], serverPort+1, client );
  5237. for (ch=0;ch<MAX_DRESS_FLAGS;ch++)
  5238. {
  5239. if ((dress_flags[ch].guildcard == gcn) || ((unsigned) servertime - dress_flags[ch].flagtime > DRESS_FLAG_EXPIRY))
  5240. dress_flags[ch].guildcard = 0;
  5241. }
  5242. break;
  5243. case 0x01:
  5244. // MySQL error.
  5245. Send1A ("There is a problem with the MySQL database.\n\nPlease contact the server administrator.", client);
  5246. break;
  5247. case 0x02:
  5248. // Username or password incorrect.
  5249. Send1A ("Username or password is incorrect.", client);
  5250. break;
  5251. case 0x03:
  5252. // Account is banned.
  5253. Send1A ("You are banned from this server.", client);
  5254. break;
  5255. case 0x04:
  5256. // Already logged on.
  5257. Send1A ("This account is already logged on.\n\nPlease wait 120 seconds and try again.", client);
  5258. break;
  5259. case 0x05:
  5260. // Account has not completed e-mail validation.
  5261. Send1A ("Please complete the registration of this account through\ne-mail validation.\n\nThank you.", client);
  5262. break;
  5263. case 0x07:
  5264. // Client version too old.
  5265. Send1A ("Your client executable is too old.\nPlease update your client through the patch server.", client);
  5266. break;
  5267. default:
  5268. Send1A ("Unknown error.", client);
  5269. break;
  5270. }
  5271. client->sendCheck[RECEIVE_PACKET_93] = 0x01;
  5272. }
  5273. break;
  5274. default:
  5275. client->todc = 1;
  5276. break;
  5277. }
  5278. }
  5279.  
  5280. void LoadQuestAllow ()
  5281. {
  5282. unsigned ch;
  5283. char allow_data[256];
  5284. unsigned char* qa;
  5285. FILE* fp;
  5286.  
  5287. quest_numallows = 0;
  5288. if ( ( fp = fopen ("questitem.txt", "r" ) ) == NULL )
  5289. {
  5290. printf ("questitem.txt is missing.\n");
  5291. printf ("Press [ENTER] to quit...");
  5292. gets(&dp[0]);
  5293. exit (1);
  5294. }
  5295. else
  5296. {
  5297. while (fgets (&allow_data[0], 255, fp) != NULL)
  5298. {
  5299. if ((allow_data[0] != 35) && (strlen(&allow_data[0]) > 5))
  5300. quest_numallows++;
  5301. }
  5302. quest_allow = malloc (quest_numallows * 4);
  5303. ch = 0;
  5304. fseek ( fp, 0, SEEK_SET );
  5305. while (fgets (&allow_data[0], 255, fp) != NULL)
  5306. {
  5307. if ((allow_data[0] != 35) && (strlen(&allow_data[0]) > 5))
  5308. {
  5309. quest_allow[ch] = 0;
  5310. qa = (unsigned char*) &quest_allow[ch++];
  5311. qa[0] = hexToByte (&allow_data[0]);
  5312. qa[1] = hexToByte (&allow_data[2]);
  5313. qa[2] = hexToByte (&allow_data[4]);
  5314. }
  5315. }
  5316. fclose ( fp );
  5317. }
  5318. printf ("Number of quest item allowances: %u\n", quest_numallows);
  5319. }
  5320.  
  5321.  
  5322. void LoadDropData()
  5323. {
  5324. unsigned ch,ch2,ch3,d;
  5325. unsigned char* rt_table;
  5326. char id_file[256];
  5327. FILE* fp;
  5328. char convert_ch[10];
  5329. int look_rate;
  5330.  
  5331. printf ("Loading drop data...\n");
  5332.  
  5333. // Each episode
  5334. for (ch=1;ch<5;ch++)
  5335. {
  5336. if (ch != 3)
  5337. {
  5338. switch (ch)
  5339. {
  5340. case 0x01:
  5341. rt_table = (unsigned char*) &rt_tables_ep1[0];
  5342. break;
  5343. case 0x02:
  5344. rt_table = (unsigned char*) &rt_tables_ep2[0];
  5345. break;
  5346. case 0x04:
  5347. rt_table = (unsigned char*) &rt_tables_ep4[0];
  5348. break;
  5349. }
  5350. // Each difficulty
  5351. for (d=0;d<4;d++)
  5352. {
  5353. // Each section ID
  5354. for (ch2=0;ch2<10;ch2++)
  5355. {
  5356. id_file[0] = 0;
  5357. switch (ch)
  5358. {
  5359. case 0x01:
  5360. strcat (&id_file[0], "drop\\ep1_mob_");
  5361. break;
  5362. case 0x02:
  5363. strcat (&id_file[0], "drop\\ep2_mob_");
  5364. break;
  5365. case 0x04:
  5366. strcat (&id_file[0], "drop\\ep4_mob_");
  5367. break;
  5368. }
  5369. _itoa (d, &convert_ch[0], 10);
  5370. strcat (&id_file[0], &convert_ch[0]);
  5371. strcat (&id_file[0], "_");
  5372. _itoa (ch2, &convert_ch[0], 10);
  5373. strcat (&id_file[0], &convert_ch[0]);
  5374. strcat (&id_file[0], ".txt");
  5375. ch3 = 0;
  5376. fp = fopen ( &id_file[0], "r" );
  5377. if (!fp)
  5378. {
  5379. printf ("Drop table not found \"%s\"", id_file[0] );
  5380. printf ("Hit [ENTER] to quit...");
  5381. gets (&dp[0]);
  5382. exit (1);
  5383. }
  5384. look_rate = 1;
  5385. while ( fgets ( &dp[0], 255, fp ) != NULL )
  5386. {
  5387. if ( dp[0] != 35 ) // not a comment
  5388. {
  5389. if ( look_rate )
  5390. {
  5391. rt_table[ch3++] = (unsigned char) atoi (&dp[0]);
  5392. look_rate = 0;
  5393. }
  5394. else
  5395. {
  5396. if ( strlen ( &dp[0] ) < 6 )
  5397. {
  5398. printf ("Corrupted drop table \"%s\"", id_file[0] );
  5399. printf ("Hit [ENTER] to quit...");
  5400. gets (&dp[0]);
  5401. exit (1);
  5402. }
  5403. _strupr ( &dp[0] );
  5404. rt_table[ch3++] = hexToByte ( &dp[0] );
  5405. rt_table[ch3++] = hexToByte ( &dp[2] );
  5406. rt_table[ch3++] = hexToByte ( &dp[4] );
  5407. look_rate = 1;
  5408. }
  5409. }
  5410. }
  5411. fclose (fp);
  5412. ch3 = 0x194;
  5413. memset (&rt_table[ch3], 0xFF, 30);
  5414. id_file[9] = 98;
  5415. id_file[10] = 111;
  5416. id_file[11] = 120;
  5417. fp = fopen ( &id_file[0], "r" );
  5418. if (!fp)
  5419. {
  5420. printf ("Drop table not found \"%s\"", id_file[0] );
  5421. printf ("Hit [ENTER] to quit...");
  5422. gets (&dp[0]);
  5423. exit (1);
  5424. }
  5425. look_rate = 0;
  5426. while ( ( fgets ( &dp[0], 255, fp ) != NULL ) && ( ch3 < 0x1B2 ) )
  5427. {
  5428. if ( dp[0] != 35 ) // not a comment
  5429. {
  5430. switch ( look_rate )
  5431. {
  5432. case 0x00:
  5433. rt_table[ch3] = (unsigned char) atoi (&dp[0]);
  5434. look_rate = 1;
  5435. break;
  5436. case 0x01:
  5437. rt_table[0x1B2 + ((ch3-0x194)*4)] = (unsigned char) atoi (&dp[0]);
  5438. look_rate = 2;
  5439. break;
  5440. case 0x02:
  5441. if ( strlen ( &dp[0] ) < 6 )
  5442. {
  5443. printf ("Corrupted drop table \"%s\"", id_file[0] );
  5444. printf ("Hit [ENTER] to quit...");
  5445. gets (&dp[0]);
  5446. exit (1);
  5447. }
  5448. _strupr ( &dp[0] );
  5449. rt_table[0x1B3 + ((ch3-0x194)*4)] = hexToByte ( &dp[0] );
  5450. rt_table[0x1B4 + ((ch3-0x194)*4)] = hexToByte ( &dp[2] );
  5451. rt_table[0x1B5 + ((ch3-0x194)*4)] = hexToByte ( &dp[4] );
  5452. look_rate = 0;
  5453. ch3++;
  5454. break;
  5455. }
  5456. }
  5457. }
  5458. fclose (fp);
  5459. rt_table += 0x800;
  5460. }
  5461. }
  5462. }
  5463. }
  5464. }
  5465.  
  5466. #ifdef NO_SQL
  5467.  
  5468. void UpdateDataFile ( const char* filename, unsigned count, void* data, unsigned record_size, int new_record )
  5469. {
  5470. FILE* fp;
  5471. unsigned fs;
  5472.  
  5473. fp = fopen (filename, "r+b");
  5474. if (fp)
  5475. {
  5476. fseek (fp, 0, SEEK_END);
  5477. fs = ftell (fp);
  5478. if ((count * record_size) <= fs)
  5479. {
  5480. fseek (fp, count * record_size, SEEK_SET);
  5481. fwrite (data, 1, record_size, fp);
  5482. }
  5483. else
  5484. debug ("Could not seek to record for updating in %s", filename);
  5485. fclose (fp);
  5486. }
  5487. else
  5488. {
  5489. fp = fopen (filename, "wb");
  5490. if (fp)
  5491. {
  5492. fwrite (data, 1, record_size, fp); // Has to be the first record...
  5493. fclose (fp);
  5494. }
  5495. else
  5496. debug ("Could not open %s for writing!\n", filename);
  5497. }
  5498. }
  5499.  
  5500.  
  5501. void DumpDataFile ( const char* filename, unsigned* count, void** data, unsigned record_size )
  5502. {
  5503. FILE* fp;
  5504. unsigned ch;
  5505.  
  5506. printf ("Dumping \"%s\" ... ", filename);
  5507. fp = fopen (filename, "wb");
  5508. if (fp)
  5509. {
  5510. for (ch=0;ch<*count;ch++)
  5511. fwrite (data[ch], 1, record_size, fp);
  5512. fclose (fp);
  5513. }
  5514. else
  5515. debug ("Could not open %s for writing!\n", filename);
  5516. printf ("done!\n");
  5517. }
  5518.  
  5519. void LoadDataFile ( const char* filename, unsigned* count, void** data, unsigned record_size )
  5520. {
  5521. FILE* fp;
  5522. unsigned ch;
  5523.  
  5524. printf ("Loading \"%s\" ... ", filename);
  5525. fp = fopen (filename, "rb");
  5526. if (fp)
  5527. {
  5528. fseek (fp, 0, SEEK_END);
  5529. *count = ftell (fp) / record_size;
  5530. fseek (fp, 0, SEEK_SET);
  5531. for (ch=0;ch<*count;ch++)
  5532. {
  5533. data[ch] = malloc (record_size);
  5534. if (!data[ch])
  5535. {
  5536. printf ("Out of memory!\nHit [ENTER]");
  5537. gets (&dp[0]);
  5538. exit (1);
  5539. }
  5540. fread (data[ch], 1, record_size, fp);
  5541. }
  5542. fclose (fp);
  5543. }
  5544. printf ("done!\n");
  5545. }
  5546.  
  5547. #endif
  5548.  
  5549.  
  5550. /*LRESULT CALLBACK WndProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
  5551. {
  5552. if(message == MYWM_NOTIFYICON)
  5553. {
  5554. switch (lParam)
  5555. {
  5556. case WM_LBUTTONDBLCLK:
  5557. switch (wParam)
  5558. {
  5559. case 100:
  5560. if (program_hidden)
  5561. {
  5562. program_hidden = 0;
  5563. ShowWindow (consoleHwnd, SW_NORMAL);
  5564. SetForegroundWindow (consoleHwnd);
  5565. SetFocus(consoleHwnd);
  5566. }
  5567. else
  5568. {
  5569. program_hidden = 1;
  5570. ShowWindow (consoleHwnd, SW_HIDE);
  5571. }
  5572. return TRUE;
  5573. break;
  5574. }
  5575. break;
  5576. }
  5577. }
  5578. return DefWindowProc( hwnd, message, wParam, lParam );
  5579. }*/
  5580.  
  5581.  
  5582. /********************************************************
  5583. **
  5584. ** main :-
  5585. **
  5586. ********************************************************/
  5587.  
  5588. int
  5589. main( int argc, char * argv[] )
  5590. {
  5591. unsigned ch,ch2;
  5592. struct in_addr login_in;
  5593. struct in_addr character_in;
  5594. struct in_addr ship_in;
  5595. struct sockaddr_in listen_in;
  5596. unsigned listen_length;
  5597. int login_sockfd = -1, character_sockfd = -1, ship_sockfd = -1;
  5598. int pkt_len, pkt_c, bytes_sent;
  5599. unsigned short this_packet;
  5600. unsigned ship_this_packet;
  5601.  
  5602. FILE* fp;
  5603. //int wserror;
  5604. unsigned char MDBuffer[17] = {0};
  5605. unsigned connectNum, shipNum;
  5606. //HINSTANCE hinst;
  5607. //NOTIFYICONDATA nid = {0};
  5608. //WNDCLASS wc = {0};
  5609. //HWND hwndWindow;
  5610. //MSG msg;
  5611. //WSADATA winsock_data;
  5612.  
  5613. //consoleHwnd = GetConsoleWindow();
  5614. //hinst = GetModuleHandle(NULL);
  5615.  
  5616. dp[0] = 0;
  5617.  
  5618. memset (&dp[0], 0, sizeof (dp));
  5619.  
  5620. strcat (&dp[0], "Tethealla Login Server version ");
  5621. strcat (&dp[0], SERVER_VERSION );
  5622. strcat (&dp[0], " coded by Sodaboy");
  5623. //SetConsoleTitle (&dp[0]);
  5624.  
  5625. printf ("\nTethealla Login Server version %s Copyright (C) 2008 Terry Chatman Jr.\n", SERVER_VERSION);
  5626. printf ("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
  5627. printf ("This program comes with ABSOLUTELY NO WARRANTY; for details\n");
  5628. printf ("see section 15 in gpl-3.0.txt\n");
  5629. printf ("This is free software, and you are welcome to redistribute it\n");
  5630. printf ("under certain conditions; see gpl-3.0.txt for details.\n");
  5631. /*
  5632. for (ch=0;ch<5;ch++)
  5633. {
  5634. printf (".");
  5635. Sleep (1000);
  5636. }*/
  5637. printf ("\n\n");
  5638.  
  5639. //WSAStartup(MAKEWORD(1,1), &winsock_data);
  5640.  
  5641. srand ( (unsigned) time(NULL) );
  5642.  
  5643. memset ( &dress_flags[0], 0, sizeof (DRESSFLAG) * MAX_DRESS_FLAGS);
  5644.  
  5645. printf ("Loading configuration from tethealla.ini ...");
  5646. load_config_file();
  5647. printf (" OK!\n");
  5648.  
  5649. /* Set this up for later. */
  5650.  
  5651. memset (&empty_bank, 0, sizeof (BANK));
  5652.  
  5653. for (ch=0;ch<200;ch++)
  5654. empty_bank.bankInventory[ch].itemid = 0xFFFFFFFF;
  5655.  
  5656. #ifdef NO_SQL
  5657. LoadDataFile ("account.dat", &num_accounts, &account_data[0], sizeof(L_ACCOUNT_DATA));
  5658. LoadDataFile ("bank.dat", &num_bankdata, &bank_data[0], sizeof(L_BANK_DATA));
  5659. LoadDataFile ("character.dat", &num_characters, &character_data[0], sizeof(L_CHARACTER_DATA));
  5660. LoadDataFile ("guild.dat", &num_guilds, &guild_data[0], sizeof(L_GUILD_DATA));
  5661. //LoadDataFile ("hwbans.dat", &num_hwbans, &hw_bans[0], sizeof(L_HW_BANS));
  5662. //LoadDataFile ("ipbans.dat", &num_ipbans, &ip_bans[0], sizeof(L_IP_BANS));
  5663. LoadDataFile ("keydata.dat", &num_keydata, &key_data[0], sizeof(L_KEY_DATA));
  5664. LoadDataFile ("security.dat", &num_security, &security_data[0], sizeof(L_SECURITY_DATA));
  5665. LoadDataFile ("shipkey.dat", &num_shipkeys, &ship_data[0], sizeof(L_SHIP_DATA));
  5666. LoadDataFile ("team.dat", &num_teams, &team_data[0], sizeof(L_TEAM_DATA));
  5667. #endif
  5668. printf ("Loading PlyLevelTbl.bin ...");
  5669. fp = fopen ( "PlyLevelTbl.bin", "rb" );
  5670. if (!fp)
  5671. {
  5672. printf ("Can't proceed without plyleveltbl.bin!\n");
  5673. printf ("Hit [ENTER]");
  5674. gets (&dp[0]);
  5675. exit (1);
  5676. }
  5677. fread ( &startingStats[0], 1, 12*14, fp );
  5678. fclose ( fp );
  5679. printf (" OK!\n");
  5680. printf ("Loading 0xE2 base packet ...");
  5681. fp = fopen ( "e2base.bin", "rb" );
  5682. if (!fp)
  5683. {
  5684. printf ("Can't proceed without e2base.bin!\n");
  5685. printf ("Hit [ENTER]");
  5686. gets (&dp[0]);
  5687. exit (1);
  5688. }
  5689. fread ( &E2_Base[0], 1, 2808, fp );
  5690. fclose ( fp );
  5691. printf (" OK!\n");
  5692. printf ("Loading 0xE7 base packet ...");
  5693. fp = fopen ( "e7base.bin", "rb" );
  5694. if (!fp)
  5695. {
  5696. printf ("Can't proceed without e7base.bin!\n");
  5697. printf ("Hit [ENTER]");
  5698. gets (&dp[0]);
  5699. exit (1);
  5700. }
  5701. fread ( &E7_Base, 1, sizeof(CHARDATA), fp );
  5702. fclose ( fp );
  5703. printf (" OK!\n");
  5704. printf ("Loading parameter files specified in e8send.txt ...");
  5705. construct0xEB();
  5706. memcpy (&Packet03[0x54], &Message03[0], sizeof (Message03));
  5707. printf ("\nLoading quest item allowances...\n");
  5708. LoadQuestAllow();
  5709. LoadDropData();
  5710. printf ("... done!\n");
  5711. #ifdef DEBUG_OUTPUT
  5712. #ifndef NO_SQL
  5713. printf ("\nMySQL connection parameters\n");
  5714. printf ("///////////////////////////\n");
  5715. printf ("Host: %s\n", mySQL_Host );
  5716. printf ("Port: %u\n", mySQL_Port );
  5717. printf ("Username: %s\n", mySQL_Username );
  5718. printf ("Password: %s\n", mySQL_Password );
  5719. printf ("Database: %s\n", mySQL_Database );
  5720. #endif
  5721. #endif
  5722. printf ("\nLogin server parameters\n");
  5723. printf ("///////////////////////\n");
  5724. if (override_on)
  5725. printf ("NOTE: IP override feature is turned on.\nThe server will bind to %u.%u.%u.%u but will send out the IP listed below.\n", overrideIP[0], overrideIP[1], overrideIP[2], overrideIP[3] );
  5726. printf ("IP: %u.%u.%u.%u\n", serverIP[0], serverIP[1], serverIP[2], serverIP[3] );
  5727. printf ("Login Port: %u\n", serverPort );
  5728. printf ("Character Port: %u\n", serverPort+1 );
  5729. printf ("Maximum Connections: %u\n", serverMaxConnections );
  5730. printf ("Maximum Ships: %u\n\n", serverMaxShips );
  5731. printf ("Allocating %u bytes of memory for connections...", sizeof (BANANA) * serverMaxConnections );
  5732. for (ch=0;ch<serverMaxConnections;ch++)
  5733. {
  5734. connections[ch] = malloc ( sizeof (BANANA) );
  5735. if ( !connections[ch] )
  5736. {
  5737. printf ("Out of memory!\n");
  5738. printf ("Hit [ENTER]");
  5739. gets (&dp[0]);
  5740. exit (1);
  5741. }
  5742. initialize_connection (connections[ch]);
  5743. }
  5744. printf (" OK!\n");
  5745. printf ("Allocating %u bytes of memory for ships...", sizeof (ORANGE) * serverMaxShips );
  5746. memset (&ships, 0, 4 * serverMaxShips);
  5747. for (ch=0;ch<serverMaxShips;ch++)
  5748. {
  5749. ships[ch] = malloc ( sizeof (ORANGE) );
  5750. if ( !ships[ch] )
  5751. {
  5752. printf ("Out of memory!\n");
  5753. printf ("Hit [ENTER]");
  5754. gets (&dp[0]);
  5755. exit (1);
  5756. }
  5757. initialize_ship (ships[ch]);
  5758. }
  5759. printf (" OK!\n\n");
  5760. printf ("Constructing default ship list packet ...");
  5761. construct0xA0();
  5762. printf (" OK!\n\n");
  5763.  
  5764. #ifndef NO_SQL
  5765. printf ("Connecting up to the MySQL database ...");
  5766.  
  5767. if ( (myData = mysql_init((MYSQL*) 0)) &&
  5768. mysql_real_connect( myData, &mySQL_Host[0], &mySQL_Username[0], &mySQL_Password[0], NULL, mySQL_Port,
  5769. NULL, 0 ) )
  5770. {
  5771. if ( mysql_select_db( myData, &mySQL_Database[0] ) < 0 ) {
  5772. printf( "Can't select the %s database !\n", mySQL_Database ) ;
  5773. mysql_close( myData ) ;
  5774. return 2 ;
  5775. }
  5776. }
  5777. else {
  5778. printf( "Can't connect to the mysql server (%s) on port %d !\nmysql_error = %s\n",
  5779. mySQL_Host, mySQL_Port, mysql_error(myData) ) ;
  5780.  
  5781. mysql_close( myData ) ;
  5782. return 1 ;
  5783. }
  5784.  
  5785. printf (" OK!\n\n");
  5786.  
  5787. printf ("Setting session wait_timeout ...");
  5788.  
  5789. /* Set MySQL to time out after 7 days of inactivity... lulz :D */
  5790.  
  5791. sprintf (&myQuery[0], "SET SESSION wait_timeout = 604800");
  5792. mysql_query (myData, &myQuery[0]);
  5793. printf (" OK!\n\n");
  5794.  
  5795. #endif
  5796.  
  5797. printf ("Getting max ship key count... ");
  5798.  
  5799. #ifdef NO_SQL
  5800.  
  5801. max_ship_keys = 0;
  5802. for (ds=0;ds<num_shipkeys;ds++)
  5803. {
  5804. if (ship_data[ds]->idx >= max_ship_keys)
  5805. max_ship_keys = ship_data[ds]->idx;
  5806. }
  5807.  
  5808. #else
  5809.  
  5810. sprintf (&myQuery[0], "SELECT * from ship_data" );
  5811.  
  5812. if ( ! mysql_query ( myData, &myQuery[0] ) )
  5813. {
  5814. unsigned key_rows;
  5815.  
  5816. myResult = mysql_store_result ( myData );
  5817. key_rows = (int) mysql_num_rows ( myResult );
  5818. max_ship_keys = 0;
  5819. while ( key_rows )
  5820. {
  5821. myRow = mysql_fetch_row ( myResult );
  5822. if ( (unsigned) atoi ( myRow[1] ) > max_ship_keys )
  5823. max_ship_keys = atoi ( myRow[1] );
  5824. key_rows --;
  5825. }
  5826. printf ("(%u) ", max_ship_keys);
  5827. mysql_free_result ( myResult );
  5828.  
  5829. }
  5830. else
  5831. {
  5832. printf ("Unable to query the key database.\n");
  5833. }
  5834.  
  5835. #endif
  5836.  
  5837. printf (" OK!\n");
  5838.  
  5839. printf ("Loading default.flag ...");
  5840. fp = fopen ( "default.flag", "rb" );
  5841. if (!fp)
  5842. {
  5843. printf ("Can't proceed without default.flag!\n");
  5844. printf ("Hit [ENTER]");
  5845. gets (&dp[0]);
  5846. exit (1);
  5847. }
  5848. fread ( &DefaultTeamFlag[0], 1, 2048, fp );
  5849. fclose ( fp );
  5850. #ifndef NO_SQL
  5851. mysql_real_escape_string (myData, &DefaultTeamFlagSlashes[0], &DefaultTeamFlag[0], 2048);
  5852. #endif
  5853. printf (" OK!\n");
  5854.  
  5855. /* Open the PSO BB Login Server Port... */
  5856.  
  5857. printf ("Opening server login port %u for connections.\n", serverPort);
  5858.  
  5859. #ifdef USEADDR_ANY
  5860. login_in.s_addr = INADDR_ANY;
  5861. #else
  5862. if (override_on)
  5863. *(unsigned *) &login_in.s_addr = *(unsigned *) &overrideIP[0];
  5864. else
  5865. *(unsigned *) &login_in.s_addr = *(unsigned *) &serverIP[0];
  5866. #endif
  5867. login_sockfd = tcp_sock_open( login_in, serverPort );
  5868.  
  5869. tcp_listen (login_sockfd);
  5870.  
  5871. /* Open the PSO BB Character Server Port... */
  5872.  
  5873. printf ("Opening server character port %u for connections.\n", serverPort + 1);
  5874.  
  5875. #ifdef USEADDR_ANY
  5876. character_in.s_addr = INADDR_ANY;
  5877. #else
  5878. if (override_on)
  5879. *(unsigned *) &character_in.s_addr = *(unsigned*) &overrideIP[0];
  5880. else
  5881. *(unsigned *) &character_in.s_addr = *(unsigned *) &serverIP[0];
  5882. #endif
  5883. character_sockfd = tcp_sock_open( character_in, serverPort + 1 );
  5884.  
  5885. tcp_listen (character_sockfd);
  5886.  
  5887. /* Open the Ship Port... */
  5888.  
  5889. printf ("Opening ship port 3455 for connections.\n" );
  5890.  
  5891. #ifdef USEADDR_ANY
  5892. ship_in.s_addr = INADDR_ANY;
  5893. #else
  5894. if (override_on)
  5895. *(unsigned *) &ship_in.s_addr = *(unsigned *) &overrideIP[0];
  5896. else
  5897. *(unsigned *) &ship_in.s_addr = *(unsigned *) &serverIP[0];
  5898. #endif
  5899. ship_sockfd = tcp_sock_open( ship_in, 3455 );
  5900.  
  5901. tcp_listen (ship_sockfd);
  5902.  
  5903. if ((login_sockfd<0) || (character_sockfd<0) || (ship_sockfd<0))
  5904. {
  5905. printf ("Failed to open ports for connections.\n");
  5906. printf ("Hit [ENTER]");
  5907. gets (&dp[0]);
  5908. exit (1);
  5909. }
  5910.  
  5911. printf ("\nListening...\n");
  5912.  
  5913. //wc.hbrBackground =(HBRUSH)GetStockObject(WHITE_BRUSH);
  5914. //wc.hIcon = LoadIcon( hinst, IDI_APPLICATION );
  5915. //wc.hCursor = LoadCursor( hinst, IDC_ARROW );
  5916. //wc.hInstance = hinst;
  5917. //wc.lpfnWndProc = WndProc;
  5918. //wc.lpszClassName = "sodaboy";
  5919. //wc.style = CS_HREDRAW | CS_VREDRAW;
  5920.  
  5921. //if (! RegisterClass( &wc ) )
  5922. //{
  5923. // printf ("RegisterClass failure.\n");
  5924. // exit (1);
  5925. //}
  5926.  
  5927. //hwndWindow = CreateWindow ("sodaboy","hidden window", WS_MINIMIZE, 1, 1, 1, 1,
  5928. // NULL,
  5929. // NULL,
  5930. // hinst,
  5931. // NULL );
  5932.  
  5933. //backupHwnd = hwndWindow;
  5934.  
  5935. /*if (!hwndWindow)
  5936. {
  5937. printf ("Failed to create window.");
  5938. exit (1);
  5939. }
  5940.  
  5941. ShowWindow ( hwndWindow, SW_HIDE );
  5942. UpdateWindow ( hwndWindow );
  5943. ShowWindow ( consoleHwnd, SW_HIDE );
  5944. UpdateWindow ( consoleHwnd );
  5945.  
  5946. nid.cbSize = sizeof(nid);
  5947. nid.hWnd = hwndWindow;
  5948. nid.uID = 100;
  5949. nid.uCallbackMessage = MYWM_NOTIFYICON;
  5950. nid.uFlags = NIF_MESSAGE|NIF_ICON|NIF_TIP;
  5951. nid.hIcon = LoadIcon(hinst, MAKEINTRESOURCE(IDI_ICON1));
  5952. nid.szTip[0] = 0;
  5953. strcat (&nid.szTip[0], "Tethealla Login ");
  5954. strcat (&nid.szTip[0], SERVER_VERSION);
  5955. strcat (&nid.szTip[0], " - Double click to show/hide");
  5956. Shell_NotifyIcon(NIM_ADD, &nid);
  5957.  
  5958. */
  5959. #ifdef NO_SQL
  5960.  
  5961. lastdump = (unsigned) time(NULL);
  5962.  
  5963. #endif
  5964.  
  5965. for (;;)
  5966. {
  5967. int nfds = 0;
  5968.  
  5969. /* Ping pong?! */
  5970.  
  5971. servertime = time(NULL);
  5972.  
  5973. /* Process the system tray icon */
  5974.  
  5975. /*if ( backupHwnd != hwndWindow )
  5976. {
  5977. debug ("hwndWindow has been corrupted...");
  5978. display_packet ( (unsigned char*) &hwndWindow, sizeof (HWND));
  5979. hwndWindow = backupHwnd;
  5980. WriteLog ("hwndWindow corrupted %s", (char*) &dp[0] );
  5981. }
  5982.  
  5983. if ( PeekMessage( &msg, hwndWindow, 0, 0, 1 ) )
  5984. {
  5985. TranslateMessage(&msg);
  5986. DispatchMessage(&msg);
  5987. }*/
  5988.  
  5989.  
  5990. #ifdef NO_SQL
  5991.  
  5992. if ( (unsigned) servertime - lastdump > 600 )
  5993. {
  5994. printf ("Refreshing account and ship key databases...\n");
  5995. for (ch=0;ch<num_accounts;ch++)
  5996. free (account_data[ch]);
  5997. num_accounts = 0;
  5998. LoadDataFile ("account.dat", &num_accounts, &account_data[0], sizeof(L_ACCOUNT_DATA));
  5999. for (ch=0;ch<num_shipkeys;ch++)
  6000. free (ship_data[ch]);
  6001. num_shipkeys = 0;
  6002. LoadDataFile ("shipkey.dat", &num_shipkeys, &ship_data[0], sizeof(L_SHIP_DATA));
  6003. lastdump = (unsigned) servertime;
  6004. }
  6005.  
  6006. #endif
  6007.  
  6008. /* Clear socket activity flags. */
  6009.  
  6010. FD_ZERO (&ReadFDs);
  6011. FD_ZERO (&WriteFDs);
  6012. FD_ZERO (&ExceptFDs);
  6013.  
  6014. for (ch=0;ch<serverNumConnections;ch++)
  6015. {
  6016. connectNum = serverConnectionList[ch];
  6017. workConnect = connections[connectNum];
  6018.  
  6019. if (workConnect->plySockfd >= 0)
  6020. {
  6021. if (workConnect->packetdata)
  6022. {
  6023. this_packet = *(unsigned short*) &workConnect->packet[workConnect->packetread];
  6024. memcpy (&workConnect->decryptbuf[0], &workConnect->packet[workConnect->packetread], this_packet);
  6025.  
  6026. switch (workConnect->login)
  6027. {
  6028. case 0x01:
  6029. // Login server
  6030. LoginProcessPacket (workConnect);
  6031. break;
  6032. case 0x02:
  6033. // Character server
  6034. CharacterProcessPacket (workConnect);
  6035. break;
  6036. }
  6037. workConnect->packetread += this_packet;
  6038. if (workConnect->packetread == workConnect->packetdata)
  6039. workConnect->packetread = workConnect->packetdata = 0;
  6040. }
  6041.  
  6042. if (workConnect->lastTick != (unsigned) servertime)
  6043. {
  6044. if (workConnect->lastTick > (unsigned) servertime)
  6045. ch2 = 1;
  6046. else
  6047. ch2 = 1 + ((unsigned) servertime - workConnect->lastTick);
  6048. workConnect->lastTick = (unsigned) servertime;
  6049. workConnect->packetsSec /= ch2;
  6050. workConnect->toBytesSec /= ch2;
  6051. workConnect->fromBytesSec /= ch2;
  6052. }
  6053.  
  6054. /*
  6055. if (((unsigned) servertime - workConnect->connected >= 300) ||
  6056. (workConnect->connected > (unsigned) servertime))
  6057. {
  6058. Send1A ("You have been idle for too long. Disconnecting...", workConnect);
  6059. workConnect->todc = 1;
  6060. }
  6061. */
  6062.  
  6063. FD_SET (workConnect->plySockfd, &ReadFDs);
  6064. nfds = max (nfds, workConnect->plySockfd);
  6065. FD_SET (workConnect->plySockfd, &ExceptFDs);
  6066. nfds = max (nfds, workConnect->plySockfd);
  6067. if (workConnect->snddata - workConnect->sndwritten)
  6068. {
  6069. FD_SET (workConnect->plySockfd, &WriteFDs);
  6070. nfds = max (nfds, workConnect->plySockfd);
  6071. }
  6072. }
  6073. }
  6074.  
  6075. for (ch=0;ch<serverNumShips;ch++)
  6076. {
  6077. shipNum = serverShipList[ch];
  6078. workShip = ships[shipNum];
  6079.  
  6080. if (workShip->shipSockfd >= 0)
  6081. {
  6082. // Send a ping request to the ship when 30 seconds passes...
  6083. if (((unsigned) servertime - workShip->last_ping >= 30) && (workShip->sent_ping == 0))
  6084. {
  6085. workShip->sent_ping = 1;
  6086. ShipSend11 (workShip);
  6087. }
  6088.  
  6089. // If it's been over a minute since we've heard from a ship, terminate
  6090. // the connection with it.
  6091.  
  6092. if ((unsigned) servertime - workShip->last_ping > 60)
  6093. {
  6094. printf ("%s ship ping timeout.\n", workShip->name );
  6095. initialize_ship (workShip);
  6096. }
  6097. else
  6098. {
  6099. if (workShip->packetdata)
  6100. {
  6101. ship_this_packet = *(unsigned *)&workShip->packet[workShip->packetread];
  6102. memcpy (&workShip->decryptbuf[0], &workShip->packet[workShip->packetread], ship_this_packet);
  6103.  
  6104. ShipProcessPacket (workShip);
  6105.  
  6106. workShip->packetread += ship_this_packet;
  6107.  
  6108. if (workShip->packetread == workShip->packetdata)
  6109. workShip->packetread = workShip->packetdata = 0;
  6110. }
  6111.  
  6112.  
  6113. /* Limit time of authorization to 60 seconds... */
  6114.  
  6115. if ((workShip->authed == 0) && ((unsigned) servertime - workShip->connected >= 60))
  6116. workShip->todc = 1;
  6117.  
  6118.  
  6119. FD_SET (workShip->shipSockfd, &ReadFDs);
  6120. nfds = max (nfds, workShip->shipSockfd);
  6121. if (workShip->snddata - workShip->sndwritten)
  6122. {
  6123. FD_SET (workShip->shipSockfd, &WriteFDs);
  6124. nfds = max (nfds, workShip->shipSockfd);
  6125. }
  6126. }
  6127. }
  6128. }
  6129.  
  6130. FD_SET (login_sockfd, &ReadFDs);
  6131. nfds = max (nfds, login_sockfd);
  6132. FD_SET (character_sockfd, &ReadFDs);
  6133. nfds = max (nfds, character_sockfd);
  6134. FD_SET (ship_sockfd, &ReadFDs);
  6135. nfds = max (nfds, ship_sockfd);
  6136.  
  6137. /* Check sockets for activity. */
  6138.  
  6139. if ( select ( nfds + 1, &ReadFDs, &WriteFDs, &ExceptFDs, &select_timeout ) > 0 )
  6140. {
  6141. if (FD_ISSET (login_sockfd, &ReadFDs))
  6142. {
  6143. // Someone's attempting to connect to the login server.
  6144. ch = free_connection();
  6145. if (ch != 0xFFFF)
  6146. {
  6147. listen_length = sizeof (listen_in);
  6148. workConnect = connections[ch];
  6149. if ( ( workConnect->plySockfd = tcp_accept ( login_sockfd, (struct sockaddr*) &listen_in, &listen_length ) ) >= 0 )
  6150. {
  6151. workConnect->connection_index = ch;
  6152. serverConnectionList[serverNumConnections++] = ch;
  6153. memcpy ( &workConnect->IP_Address[0], inet_ntoa (listen_in.sin_addr), 16 );
  6154. printf ("Accepted LOGIN connection from %s:%u\n", workConnect->IP_Address, listen_in.sin_port );
  6155. start_encryption (workConnect);
  6156. /* Doin' login process... */
  6157. workConnect->login = 1;
  6158. }
  6159. }
  6160. }
  6161.  
  6162. if (FD_ISSET (character_sockfd, &ReadFDs))
  6163. {
  6164. // Someone's attempting to connect to the character server.
  6165. ch = free_connection();
  6166. if (ch != 0xFFFF)
  6167. {
  6168. listen_length = sizeof (listen_in);
  6169. workConnect = connections[ch];
  6170. if ( ( workConnect->plySockfd = tcp_accept ( character_sockfd, (struct sockaddr*) &listen_in, &listen_length ) ) >= 0 )
  6171. {
  6172. workConnect->connection_index = ch;
  6173. serverConnectionList[serverNumConnections++] = ch;
  6174. memcpy ( &workConnect->IP_Address[0], inet_ntoa (listen_in.sin_addr), 16 );
  6175. printf ("Accepted CHARACTER connection from %s:%u\n", inet_ntoa (listen_in.sin_addr), listen_in.sin_port );
  6176. start_encryption (workConnect);
  6177. /* Doin' character process... */
  6178. workConnect->login = 2;
  6179. }
  6180. }
  6181. }
  6182.  
  6183. if (FD_ISSET (ship_sockfd, &ReadFDs))
  6184. {
  6185. // A ship is attempting to connect to the ship transfer port.
  6186. ch = free_shipconnection();
  6187. if (ch != 0xFFFF)
  6188. {
  6189. listen_length = sizeof (listen_in);
  6190. workShip = ships[ch];
  6191. if ( ( workShip->shipSockfd = tcp_accept ( ship_sockfd, (struct sockaddr*) &listen_in, &listen_length ) ) >= 0 )
  6192. {
  6193. workShip->connection_index = ch;
  6194. serverShipList[serverNumShips++] = ch;
  6195. printf ("Accepted SHIP connection from %s:%u\n", inet_ntoa (listen_in.sin_addr), listen_in.sin_port );
  6196. *(unsigned *) &workShip->listenedAddr[0] = *(unsigned*) &listen_in.sin_addr;
  6197. workShip->connected = workShip->last_ping = (unsigned) servertime;
  6198. ShipSend00 (workShip);
  6199. }
  6200. }
  6201. }
  6202.  
  6203. // Process client connections
  6204.  
  6205. for (ch=0;ch<serverNumConnections;ch++)
  6206. {
  6207. connectNum = serverConnectionList[ch];
  6208. workConnect = connections[connectNum];
  6209.  
  6210. if (workConnect->plySockfd >= 0)
  6211. {
  6212. if (FD_ISSET(workConnect->plySockfd, &ReadFDs))
  6213. {
  6214. // Read shit.
  6215. if ( ( pkt_len = recv (workConnect->plySockfd, &tmprcv[0], TCP_BUFFER_SIZE - 1, 0) ) <= 0 )
  6216. {
  6217. /*
  6218. wserror = WSAGetLastError();
  6219. printf ("Could not read data from client...\n");
  6220. printf ("Socket Error %u.\n", wserror );
  6221. */
  6222. initialize_connection (workConnect);
  6223. }
  6224. else
  6225. {
  6226. workConnect->fromBytesSec += (unsigned) pkt_len;
  6227. // Work with it.
  6228. for (pkt_c=0;pkt_c<pkt_len;pkt_c++)
  6229. {
  6230. workConnect->rcvbuf[workConnect->rcvread++] = tmprcv[pkt_c];
  6231.  
  6232. if (workConnect->rcvread == 8)
  6233. {
  6234. /* Decrypt the packet header after receiving 8 bytes. */
  6235.  
  6236. cipher_ptr = &workConnect->client_cipher;
  6237.  
  6238. decryptcopy ( &workConnect->peekbuf[0], &workConnect->rcvbuf[0], 8 );
  6239.  
  6240. /* Make sure we're expecting a multiple of 8 bytes. */
  6241.  
  6242. workConnect->expect = *(unsigned short*) &workConnect->peekbuf[0];
  6243.  
  6244. if ( workConnect->expect % 8 )
  6245. workConnect->expect += ( 8 - ( workConnect->expect % 8 ) );
  6246.  
  6247. if ( workConnect->expect > TCP_BUFFER_SIZE )
  6248. {
  6249. initialize_connection ( workConnect );
  6250. break;
  6251. }
  6252. }
  6253.  
  6254. if ( ( workConnect->rcvread == workConnect->expect ) && ( workConnect->expect != 0 ) )
  6255. {
  6256. if ( workConnect->packetdata + workConnect->expect > TCP_BUFFER_SIZE )
  6257. {
  6258. initialize_connection ( workConnect );
  6259. break;
  6260. }
  6261. else
  6262. {
  6263. /* Decrypt the rest of the data if needed. */
  6264.  
  6265. cipher_ptr = &workConnect->client_cipher;
  6266.  
  6267. *(long long*) &workConnect->packet[workConnect->packetdata] = *(long long*) &workConnect->peekbuf[0];
  6268.  
  6269. if ( workConnect->rcvread > 8 )
  6270. decryptcopy ( &workConnect->packet[workConnect->packetdata + 8], &workConnect->rcvbuf[8], workConnect->expect - 8 );
  6271.  
  6272. this_packet = *(unsigned short*) &workConnect->peekbuf[0];
  6273. workConnect->packetdata += this_packet;
  6274.  
  6275. workConnect->packetsSec ++;
  6276.  
  6277. if ((workConnect->packetsSec > 40) ||
  6278. (workConnect->fromBytesSec > 15000) ||
  6279. (workConnect->toBytesSec > 500000))
  6280. {
  6281. printf ("%u disconnected for possible DDOS. (p/s: %u, tb/s: %u, fb/s: %u)\n", workConnect->guildcard, workConnect->packetsSec, workConnect->toBytesSec, workConnect->fromBytesSec);
  6282. initialize_connection(workConnect);
  6283. break;
  6284. }
  6285.  
  6286. workConnect->rcvread = 0;
  6287. }
  6288. }
  6289. }
  6290. }
  6291. }
  6292.  
  6293. if (FD_ISSET(workConnect->plySockfd, &WriteFDs))
  6294. {
  6295. // Write shit.
  6296.  
  6297. bytes_sent = send (workConnect->plySockfd, &workConnect->sndbuf[workConnect->sndwritten],
  6298. workConnect->snddata - workConnect->sndwritten, 0);
  6299. if (bytes_sent == SOCKET_ERROR)
  6300. {
  6301. /*
  6302. wserror = WSAGetLastError();
  6303. printf ("Could not send data to client...\n");
  6304. printf ("Socket Error %u.\n", wserror );
  6305. */
  6306. initialize_connection (workConnect);
  6307. }
  6308. else
  6309. {
  6310. workConnect->sndwritten += bytes_sent;
  6311. workConnect->toBytesSec += (unsigned) bytes_sent;
  6312. }
  6313.  
  6314. if (workConnect->sndwritten == workConnect->snddata)
  6315. workConnect->sndwritten = workConnect->snddata = 0;
  6316. }
  6317.  
  6318. if (workConnect->todc)
  6319. {
  6320. if ( workConnect->snddata - workConnect->sndwritten )
  6321. send (workConnect->plySockfd, &workConnect->sndbuf[workConnect->sndwritten],
  6322. workConnect->snddata - workConnect->sndwritten, 0);
  6323. initialize_connection (workConnect);
  6324. }
  6325.  
  6326. if (FD_ISSET(workConnect->plySockfd, &ExceptFDs)) // Exception?
  6327. initialize_connection (workConnect);
  6328. }
  6329. }
  6330.  
  6331. // Process ship connections
  6332.  
  6333. for (ch=0;ch<serverNumShips;ch++)
  6334. {
  6335. shipNum = serverShipList[ch];
  6336. workShip = ships[shipNum];
  6337.  
  6338. if (workShip->shipSockfd >= 0)
  6339. {
  6340. if (FD_ISSET(workShip->shipSockfd, &ReadFDs))
  6341. {
  6342. // Read shit.
  6343. if ( ( pkt_len = recv (workShip->shipSockfd, &tmprcv[0], PACKET_BUFFER_SIZE - 1, 0) ) <= 0 )
  6344. {
  6345. /*
  6346. wserror = WSAGetLastError();
  6347. printf ("Could not read data from client...\n");
  6348. printf ("Socket Error %u.\n", wserror );
  6349. */
  6350. printf ("Lost connection with the %s ship...\n", workShip->name );
  6351. initialize_ship (workShip);
  6352. }
  6353. else
  6354. {
  6355. // Work with it.
  6356. for (pkt_c=0;pkt_c<pkt_len;pkt_c++)
  6357. {
  6358. workShip->rcvbuf[workShip->rcvread++] = tmprcv[pkt_c];
  6359.  
  6360. if (workShip->rcvread == 4)
  6361. {
  6362. /* Read out how much data we're expecting this packet. */
  6363. workShip->expect = *(unsigned*) &workShip->rcvbuf[0];
  6364.  
  6365. if ( workShip->expect > TCP_BUFFER_SIZE )
  6366. {
  6367. printf ("Lost connection with the %s ship...\n", workShip->name );
  6368. initialize_ship ( workShip ); /* This shouldn't happen, lol. */
  6369. }
  6370. }
  6371.  
  6372. if ( ( workShip->rcvread == workShip->expect ) && ( workShip->expect != 0 ) )
  6373. {
  6374. decompressShipPacket ( workShip, &workShip->decryptbuf[0], &workShip->rcvbuf[0] );
  6375.  
  6376. workShip->expect = *(unsigned *) &workShip->decryptbuf[0];
  6377.  
  6378. if ( workShip->packetdata + workShip->expect < PACKET_BUFFER_SIZE )
  6379. {
  6380. memcpy ( &workShip->packet[workShip->packetdata], &workShip->decryptbuf[0], workShip->expect );
  6381. workShip->packetdata += workShip->expect;
  6382. }
  6383. else
  6384. {
  6385. initialize_ship ( workShip );
  6386. break;
  6387. }
  6388. workShip->rcvread = 0;
  6389. }
  6390. }
  6391. }
  6392. }
  6393.  
  6394. if (FD_ISSET(workShip->shipSockfd, &WriteFDs))
  6395. {
  6396. // Write shit.
  6397.  
  6398. bytes_sent = send (workShip->shipSockfd, &workShip->sndbuf[workShip->sndwritten],
  6399. workShip->snddata - workShip->sndwritten, 0);
  6400. if (bytes_sent == SOCKET_ERROR)
  6401. {
  6402. /*
  6403. wserror = WSAGetLastError();
  6404. printf ("Could not send data to client...\n");
  6405. printf ("Socket Error %u.\n", wserror );
  6406. */
  6407. printf ("Lost connection with the %s ship...\n", workShip->name );
  6408. initialize_ship (workShip);
  6409. }
  6410. else
  6411. workShip->sndwritten += bytes_sent;
  6412.  
  6413. if (workShip->sndwritten == workShip->snddata)
  6414. workShip->sndwritten = workShip->snddata = 0;
  6415.  
  6416. }
  6417.  
  6418. if (workShip->todc)
  6419. {
  6420. if ( workShip->snddata - workShip->sndwritten )
  6421. send (workShip->shipSockfd, &workShip->sndbuf[workShip->sndwritten],
  6422. workShip->snddata - workShip->sndwritten, 0);
  6423. printf ("Terminated connection with ship...\n" );
  6424. initialize_ship (workShip);
  6425. }
  6426.  
  6427. }
  6428. }
  6429. }
  6430. }
  6431. #ifndef NO_SQL
  6432. mysql_close( myData ) ;
  6433. #endif
  6434. return 0;
  6435. }
  6436.  
  6437.  
  6438. void send_to_server(int sock, char* packet)
  6439. {
  6440. int pktlen;
  6441.  
  6442. pktlen = strlen (packet);
  6443.  
  6444. if (send(sock, packet, pktlen, 0) != pktlen)
  6445. {
  6446. printf ("send_to_server(): failure");
  6447. printf ("Hit [ENTER]");
  6448. gets (&dp[0]);
  6449. exit(1);
  6450. }
  6451.  
  6452. }
  6453.  
  6454. int receive_from_server(int sock, char* packet)
  6455. {
  6456. int pktlen;
  6457.  
  6458. if ((pktlen = recv(sock, packet, TCP_BUFFER_SIZE - 1, 0)) <= 0)
  6459. {
  6460. printf ("receive_from_server(): failure");
  6461. printf ("Hit [ENTER]");
  6462. gets (&dp[0]);
  6463. exit(1);
  6464. }
  6465. packet[pktlen] = 0;
  6466. return pktlen;
  6467. }
  6468.  
  6469. void tcp_listen (int sockfd)
  6470. {
  6471. if (listen(sockfd, 10) < 0)
  6472. {
  6473. debug_perror ("Could not listen for connection");
  6474. printf ("Hit [ENTER]");
  6475. gets (&dp[0]);
  6476. exit(1);
  6477. }
  6478. }
  6479.  
  6480. int tcp_accept (int sockfd, struct sockaddr *client_addr, int *addr_len )
  6481. {
  6482. int fd;
  6483.  
  6484. if ((fd = accept (sockfd, client_addr, addr_len)) < 0)
  6485. debug_perror ("Could not accept connection");
  6486.  
  6487. return (fd);
  6488. }
  6489.  
  6490. int tcp_sock_connect(char* dest_addr, int port)
  6491. {
  6492. int fd;
  6493. struct sockaddr_in sa;
  6494.  
  6495. /* Clear it out */
  6496. memset((void *)&sa, 0, sizeof(sa));
  6497.  
  6498. fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  6499.  
  6500. /* Error */
  6501. if( fd < 0 )
  6502. debug_perror("Could not create socket");
  6503. else
  6504. {
  6505.  
  6506. memset (&sa, 0, sizeof(sa));
  6507. sa.sin_family = AF_INET;
  6508. sa.sin_addr.s_addr = inet_addr (dest_addr);
  6509. sa.sin_port = htons((unsigned short) port);
  6510.  
  6511. if (connect(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0)
  6512. debug_perror("Could not make TCP connection");
  6513. else
  6514. debug ("tcp_sock_connect %s:%u", inet_ntoa (sa.sin_addr), sa.sin_port );
  6515. }
  6516. return(fd);
  6517. }
  6518.  
  6519. /*****************************************************************************/
  6520. int tcp_sock_open(struct in_addr ip, int port)
  6521. {
  6522. int fd, turn_on_option_flag = 1, rcSockopt;
  6523.  
  6524. struct sockaddr_in sa;
  6525.  
  6526. /* Clear it out */
  6527. memset((void *)&sa, 0, sizeof(sa));
  6528.  
  6529. fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
  6530.  
  6531. /* Error */
  6532. if( fd < 0 ){
  6533. debug_perror("Could not create socket");
  6534. printf ("Hit [ENTER]");
  6535. gets (&dp[0]);
  6536. exit(1);
  6537. }
  6538.  
  6539. sa.sin_family = AF_INET;
  6540. memcpy((void *)&sa.sin_addr, (void *)&ip, sizeof(struct in_addr));
  6541. sa.sin_port = htons((unsigned short) port);
  6542.  
  6543. /* Reuse port */
  6544.  
  6545. rcSockopt = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &turn_on_option_flag, sizeof(turn_on_option_flag));
  6546.  
  6547. /* bind() the socket to the interface */
  6548. if (bind(fd, (struct sockaddr *)&sa, sizeof(struct sockaddr)) < 0){
  6549. debug_perror("Could not bind to port");
  6550. printf ("Hit [ENTER]");
  6551. gets (&dp[0]);
  6552. exit(1);
  6553. }
  6554.  
  6555. return(fd);
  6556. }
  6557.  
  6558. /*****************************************************************************
  6559. * same as debug_perror but writes to debug output.
  6560. *
  6561. *****************************************************************************/
  6562. void debug_perror( char * msg ) {
  6563. debug( "%s : %s\n" , msg , strerror(errno) );
  6564. }
  6565. /*****************************************************************************/
  6566. void debug(char *fmt, ...)
  6567. {
  6568. #define MAX_MESG_LEN 1024
  6569.  
  6570. va_list args;
  6571. char text[ MAX_MESG_LEN ];
  6572.  
  6573. va_start (args, fmt);
  6574. strcpy (text + vsprintf( text,fmt,args), "\r\n");
  6575. va_end (args);
  6576.  
  6577. fprintf( stderr, "%s", text);
  6578. }
  6579.  
  6580. /* Blue Burst encryption routines */
  6581.  
  6582. static void pso_crypt_init_key_bb(unsigned char *data)
  6583. {
  6584. unsigned x;
  6585. for (x = 0; x < 48; x += 3)
  6586. {
  6587. data[x] ^= 0x19;
  6588. data[x + 1] ^= 0x16;
  6589. data[x + 2] ^= 0x18;
  6590. }
  6591. }
  6592.  
  6593.  
  6594. void pso_crypt_decrypt_bb(PSO_CRYPT *pcry, unsigned char *data, unsigned
  6595. length)
  6596. {
  6597. unsigned eax, ecx, edx, ebx, ebp, esi, edi;
  6598.  
  6599. edx = 0;
  6600. ecx = 0;
  6601. eax = 0;
  6602. while (edx < length)
  6603. {
  6604. ebx = *(unsigned long *) &data[edx];
  6605. ebx = ebx ^ pcry->tbl[5];
  6606. ebp = ((pcry->tbl[(ebx >> 0x18) + 0x12]+pcry->tbl[((ebx >> 0x10)& 0xff) + 0x112])
  6607. ^ pcry->tbl[((ebx >> 0x8)& 0xff) + 0x212]) + pcry->tbl[(ebx & 0xff) + 0x312];
  6608. ebp = ebp ^ pcry->tbl[4];
  6609. ebp ^= *(unsigned long *) &data[edx+4];
  6610. edi = ((pcry->tbl[(ebp >> 0x18) + 0x12]+pcry->tbl[((ebp >> 0x10)& 0xff) + 0x112])
  6611. ^ pcry->tbl[((ebp >> 0x8)& 0xff) + 0x212]) + pcry->tbl[(ebp & 0xff) + 0x312];
  6612. edi = edi ^ pcry->tbl[3];
  6613. ebx = ebx ^ edi;
  6614. esi = ((pcry->tbl[(ebx >> 0x18) + 0x12]+pcry->tbl[((ebx >> 0x10)& 0xff) + 0x112])
  6615. ^ pcry->tbl[((ebx >> 0x8)& 0xff) + 0x212]) + pcry->tbl[(ebx & 0xff) + 0x312];
  6616. ebp = ebp ^ esi ^ pcry->tbl[2];
  6617. edi = ((pcry->tbl[(ebp >> 0x18) + 0x12]+pcry->tbl[((ebp >> 0x10)& 0xff) + 0x112])
  6618. ^ pcry->tbl[((ebp >> 0x8)& 0xff) + 0x212]) + pcry->tbl[(ebp & 0xff) + 0x312];
  6619. edi = edi ^ pcry->tbl[1];
  6620. ebp = ebp ^ pcry->tbl[0];
  6621. ebx = ebx ^ edi;
  6622. *(unsigned long *) &data[edx] = ebp;
  6623. *(unsigned long *) &data[edx+4] = ebx;
  6624. edx = edx+8;
  6625. }
  6626. }
  6627.  
  6628.  
  6629. void pso_crypt_encrypt_bb(PSO_CRYPT *pcry, unsigned char *data, unsigned
  6630. length)
  6631. {
  6632. unsigned eax, ecx, edx, ebx, ebp, esi, edi;
  6633.  
  6634. edx = 0;
  6635. ecx = 0;
  6636. eax = 0;
  6637. while (edx < length)
  6638. {
  6639. ebx = *(unsigned long *) &data[edx];
  6640. ebx = ebx ^ pcry->tbl[0];
  6641. ebp = ((pcry->tbl[(ebx >> 0x18) + 0x12]+pcry->tbl[((ebx >> 0x10)& 0xff) + 0x112])
  6642. ^ pcry->tbl[((ebx >> 0x8)& 0xff) + 0x212]) + pcry->tbl[(ebx & 0xff) + 0x312];
  6643. ebp = ebp ^ pcry->tbl[1];
  6644. ebp ^= *(unsigned long *) &data[edx+4];
  6645. edi = ((pcry->tbl[(ebp >> 0x18) + 0x12]+pcry->tbl[((ebp >> 0x10)& 0xff) + 0x112])
  6646. ^ pcry->tbl[((ebp >> 0x8)& 0xff) + 0x212]) + pcry->tbl[(ebp & 0xff) + 0x312];
  6647. edi = edi ^ pcry->tbl[2];
  6648. ebx = ebx ^ edi;
  6649. esi = ((pcry->tbl[(ebx >> 0x18) + 0x12]+pcry->tbl[((ebx >> 0x10)& 0xff) + 0x112])
  6650. ^ pcry->tbl[((ebx >> 0x8)& 0xff) + 0x212]) + pcry->tbl[(ebx & 0xff) + 0x312];
  6651. ebp = ebp ^ esi ^ pcry->tbl[3];
  6652. edi = ((pcry->tbl[(ebp >> 0x18) + 0x12]+pcry->tbl[((ebp >> 0x10)& 0xff) + 0x112])
  6653. ^ pcry->tbl[((ebp >> 0x8)& 0xff) + 0x212]) + pcry->tbl[(ebp & 0xff) + 0x312];
  6654. edi = edi ^ pcry->tbl[4];
  6655. ebp = ebp ^ pcry->tbl[5];
  6656. ebx = ebx ^ edi;
  6657. *(unsigned long *) &data[edx] = ebp;
  6658. *(unsigned long *) &data[edx+4] = ebx;
  6659. edx = edx+8;
  6660. }
  6661. }
  6662.  
  6663. void encryptcopy (BANANA* client, const unsigned char* src, unsigned size)
  6664. {
  6665. unsigned char* dest;
  6666.  
  6667. if (TCP_BUFFER_SIZE - client->snddata < ( (int) size + 7 ) )
  6668. client->todc = 1;
  6669. else
  6670. {
  6671. dest = &client->sndbuf[client->snddata];
  6672. memcpy (dest,src,size);
  6673. while (size % 8)
  6674. dest[size++] = 0x00;
  6675. client->snddata += (int) size;
  6676. pso_crypt_encrypt_bb(cipher_ptr,dest,size);
  6677. }
  6678. }
  6679.  
  6680.  
  6681. void decryptcopy (unsigned char* dest, const unsigned char* src, unsigned size)
  6682. {
  6683. memcpy (dest,src,size);
  6684. pso_crypt_decrypt_bb(cipher_ptr,dest,size);
  6685. }
  6686.  
  6687.  
  6688. void pso_crypt_table_init_bb(PSO_CRYPT *pcry, const unsigned char *salt)
  6689. {
  6690. unsigned long eax, ecx, edx, ebx, ebp, esi, edi, ou, x;
  6691. unsigned char s[48];
  6692. unsigned short* pcryp;
  6693. unsigned short* bbtbl;
  6694. unsigned short dx;
  6695.  
  6696. pcry->cur = 0;
  6697. pcry->mangle = NULL;
  6698. pcry->size = 1024 + 18;
  6699.  
  6700. memcpy(s, salt, sizeof(s));
  6701. pso_crypt_init_key_bb(s);
  6702.  
  6703. bbtbl = (unsigned short*) &bbtable[0];
  6704. pcryp = (unsigned short*) &pcry->tbl[0];
  6705.  
  6706. eax = 0;
  6707. ebx = 0;
  6708.  
  6709. for(ecx=0;ecx<0x12;ecx++)
  6710. {
  6711. dx = bbtbl[eax++];
  6712. dx = ( ( dx & 0xFF ) << 8 ) + ( dx >> 8 );
  6713. pcryp[ebx] = dx;
  6714. dx = bbtbl[eax++];
  6715. dx ^= pcryp[ebx++];
  6716. pcryp[ebx++] = dx;
  6717. }
  6718.  
  6719. /*
  6720.  
  6721. pcry->tbl[0] = 0x243F6A88;
  6722. pcry->tbl[1] = 0x85A308D3;
  6723. pcry->tbl[2] = 0x13198A2E;
  6724. pcry->tbl[3] = 0x03707344;
  6725. pcry->tbl[4] = 0xA4093822;
  6726. pcry->tbl[5] = 0x299F31D0;
  6727. pcry->tbl[6] = 0x082EFA98;
  6728. pcry->tbl[7] = 0xEC4E6C89;
  6729. pcry->tbl[8] = 0x452821E6;
  6730. pcry->tbl[9] = 0x38D01377;
  6731. pcry->tbl[10] = 0xBE5466CF;
  6732. pcry->tbl[11] = 0x34E90C6C;
  6733. pcry->tbl[12] = 0xC0AC29B7;
  6734. pcry->tbl[13] = 0xC97C50DD;
  6735. pcry->tbl[14] = 0x3F84D5B5;
  6736. pcry->tbl[15] = 0xB5470917;
  6737. pcry->tbl[16] = 0x9216D5D9;
  6738. pcry->tbl[17] = 0x8979FB1B;
  6739.  
  6740. */
  6741.  
  6742. memcpy(&pcry->tbl[18], &bbtable[18], 4096);
  6743.  
  6744. ecx=0;
  6745. //total key[0] length is min 0x412
  6746. ebx=0;
  6747.  
  6748. while (ebx < 0x12)
  6749. {
  6750. //in a loop
  6751. ebp=((unsigned long) (s[ecx])) << 0x18;
  6752. eax=ecx+1;
  6753. edx=eax-((eax / 48)*48);
  6754. eax=(((unsigned long) (s[edx])) << 0x10) & 0xFF0000;
  6755. ebp=(ebp | eax) & 0xffff00ff;
  6756. eax=ecx+2;
  6757. edx=eax-((eax / 48)*48);
  6758. eax=(((unsigned long) (s[edx])) << 0x8) & 0xFF00;
  6759. ebp=(ebp | eax) & 0xffffff00;
  6760. eax=ecx+3;
  6761. ecx=ecx+4;
  6762. edx=eax-((eax / 48)*48);
  6763. eax=(unsigned long) (s[edx]);
  6764. ebp=ebp | eax;
  6765. eax=ecx;
  6766. edx=eax-((eax / 48)*48);
  6767. pcry->tbl[ebx]=pcry->tbl[ebx] ^ ebp;
  6768. ecx=edx;
  6769. ebx++;
  6770. }
  6771.  
  6772. ebp=0;
  6773. esi=0;
  6774. ecx=0;
  6775. edi=0;
  6776. ebx=0;
  6777. edx=0x48;
  6778.  
  6779. while (edi < edx)
  6780. {
  6781. esi=esi ^ pcry->tbl[0];
  6782. eax=esi >> 0x18;
  6783. ebx=(esi >> 0x10) & 0xff;
  6784. eax=pcry->tbl[eax+0x12]+pcry->tbl[ebx+0x112];
  6785. ebx=(esi >> 8) & 0xFF;
  6786. eax=eax ^ pcry->tbl[ebx+0x212];
  6787. ebx=esi & 0xff;
  6788. eax=eax + pcry->tbl[ebx+0x312];
  6789.  
  6790. eax=eax ^ pcry->tbl[1];
  6791. ecx= ecx ^ eax;
  6792. ebx=ecx >> 0x18;
  6793. eax=(ecx >> 0x10) & 0xFF;
  6794. ebx=pcry->tbl[ebx+0x12]+pcry->tbl[eax+0x112];
  6795. eax=(ecx >> 8) & 0xff;
  6796. ebx=ebx ^ pcry->tbl[eax+0x212];
  6797. eax=ecx & 0xff;
  6798. ebx=ebx + pcry->tbl[eax+0x312];
  6799.  
  6800. for (x = 0; x <= 5; x++)
  6801. {
  6802. ebx=ebx ^ pcry->tbl[(x*2)+2];
  6803. esi= esi ^ ebx;
  6804. ebx=esi >> 0x18;
  6805. eax=(esi >> 0x10) & 0xFF;
  6806. ebx=pcry->tbl[ebx+0x12]+pcry->tbl[eax+0x112];
  6807. eax=(esi >> 8) & 0xff;
  6808. ebx=ebx ^ pcry->tbl[eax+0x212];
  6809. eax=esi & 0xff;
  6810. ebx=ebx + pcry->tbl[eax+0x312];
  6811.  
  6812. ebx=ebx ^ pcry->tbl[(x*2)+3];
  6813. ecx= ecx ^ ebx;
  6814. ebx=ecx >> 0x18;
  6815. eax=(ecx >> 0x10) & 0xFF;
  6816. ebx=pcry->tbl[ebx+0x12]+pcry->tbl[eax+0x112];
  6817. eax=(ecx >> 8) & 0xff;
  6818. ebx=ebx ^ pcry->tbl[eax+0x212];
  6819. eax=ecx & 0xff;
  6820. ebx=ebx + pcry->tbl[eax+0x312];
  6821. }
  6822.  
  6823. ebx=ebx ^ pcry->tbl[14];
  6824. esi= esi ^ ebx;
  6825. eax=esi >> 0x18;
  6826. ebx=(esi >> 0x10) & 0xFF;
  6827. eax=pcry->tbl[eax+0x12]+pcry->tbl[ebx+0x112];
  6828. ebx=(esi >> 8) & 0xff;
  6829. eax=eax ^ pcry->tbl[ebx+0x212];
  6830. ebx=esi & 0xff;
  6831. eax=eax + pcry->tbl[ebx+0x312];
  6832.  
  6833. eax=eax ^ pcry->tbl[15];
  6834. eax= ecx ^ eax;
  6835. ecx=eax >> 0x18;
  6836. ebx=(eax >> 0x10) & 0xFF;
  6837. ecx=pcry->tbl[ecx+0x12]+pcry->tbl[ebx+0x112];
  6838. ebx=(eax >> 8) & 0xff;
  6839. ecx=ecx ^ pcry->tbl[ebx+0x212];
  6840. ebx=eax & 0xff;
  6841. ecx=ecx + pcry->tbl[ebx+0x312];
  6842.  
  6843. ecx=ecx ^ pcry->tbl[16];
  6844. ecx=ecx ^ esi;
  6845. esi= pcry->tbl[17];
  6846. esi=esi ^ eax;
  6847. pcry->tbl[(edi / 4)]=esi;
  6848. pcry->tbl[(edi / 4)+1]=ecx;
  6849. edi=edi+8;
  6850. }
  6851.  
  6852.  
  6853. eax=0;
  6854. edx=0;
  6855. ou=0;
  6856. while (ou < 0x1000)
  6857. {
  6858. edi=0x48;
  6859. edx=0x448;
  6860.  
  6861. while (edi < edx)
  6862. {
  6863. esi=esi ^ pcry->tbl[0];
  6864. eax=esi >> 0x18;
  6865. ebx=(esi >> 0x10) & 0xff;
  6866. eax=pcry->tbl[eax+0x12]+pcry->tbl[ebx+0x112];
  6867. ebx=(esi >> 8) & 0xFF;
  6868. eax=eax ^ pcry->tbl[ebx+0x212];
  6869. ebx=esi & 0xff;
  6870. eax=eax + pcry->tbl[ebx+0x312];
  6871.  
  6872. eax=eax ^ pcry->tbl[1];
  6873. ecx= ecx ^ eax;
  6874. ebx=ecx >> 0x18;
  6875. eax=(ecx >> 0x10) & 0xFF;
  6876. ebx=pcry->tbl[ebx+0x12]+pcry->tbl[eax+0x112];
  6877. eax=(ecx >> 8) & 0xff;
  6878. ebx=ebx ^ pcry->tbl[eax+0x212];
  6879. eax=ecx & 0xff;
  6880. ebx=ebx + pcry->tbl[eax+0x312];
  6881.  
  6882. for (x = 0; x <= 5; x++)
  6883. {
  6884. ebx=ebx ^ pcry->tbl[(x*2)+2];
  6885. esi= esi ^ ebx;
  6886. ebx=esi >> 0x18;
  6887. eax=(esi >> 0x10) & 0xFF;
  6888. ebx=pcry->tbl[ebx+0x12]+pcry->tbl[eax+0x112];
  6889. eax=(esi >> 8) & 0xff;
  6890. ebx=ebx ^ pcry->tbl[eax+0x212];
  6891. eax=esi & 0xff;
  6892. ebx=ebx + pcry->tbl[eax+0x312];
  6893.  
  6894. ebx=ebx ^ pcry->tbl[(x*2)+3];
  6895. ecx= ecx ^ ebx;
  6896. ebx=ecx >> 0x18;
  6897. eax=(ecx >> 0x10) & 0xFF;
  6898. ebx=pcry->tbl[ebx+0x12]+pcry->tbl[eax+0x112];
  6899. eax=(ecx >> 8) & 0xff;
  6900. ebx=ebx ^ pcry->tbl[eax+0x212];
  6901. eax=ecx & 0xff;
  6902. ebx=ebx + pcry->tbl[eax+0x312];
  6903. }
  6904.  
  6905. ebx=ebx ^ pcry->tbl[14];
  6906. esi= esi ^ ebx;
  6907. eax=esi >> 0x18;
  6908. ebx=(esi >> 0x10) & 0xFF;
  6909. eax=pcry->tbl[eax+0x12]+pcry->tbl[ebx+0x112];
  6910. ebx=(esi >> 8) & 0xff;
  6911. eax=eax ^ pcry->tbl[ebx+0x212];
  6912. ebx=esi & 0xff;
  6913. eax=eax + pcry->tbl[ebx+0x312];
  6914.  
  6915. eax=eax ^ pcry->tbl[15];
  6916. eax= ecx ^ eax;
  6917. ecx=eax >> 0x18;
  6918. ebx=(eax >> 0x10) & 0xFF;
  6919. ecx=pcry->tbl[ecx+0x12]+pcry->tbl[ebx+0x112];
  6920. ebx=(eax >> 8) & 0xff;
  6921. ecx=ecx ^ pcry->tbl[ebx+0x212];
  6922. ebx=eax & 0xff;
  6923. ecx=ecx + pcry->tbl[ebx+0x312];
  6924.  
  6925. ecx=ecx ^ pcry->tbl[16];
  6926. ecx=ecx ^ esi;
  6927. esi= pcry->tbl[17];
  6928. esi=esi ^ eax;
  6929. pcry->tbl[(ou / 4)+(edi / 4)]=esi;
  6930. pcry->tbl[(ou / 4)+(edi / 4)+1]=ecx;
  6931. edi=edi+8;
  6932. }
  6933. ou=ou+0x400;
  6934. }
  6935. }
  6936.  
  6937. unsigned RleEncode(unsigned char *src, unsigned char *dest, unsigned src_size)
  6938. {
  6939. unsigned char currChar, prevChar; /* current and previous characters */
  6940. unsigned short count; /* number of characters in a run */
  6941. unsigned src_end, dest_start;
  6942.  
  6943. dest_start = (unsigned)dest;
  6944. src_end = (unsigned)src + src_size;
  6945.  
  6946. prevChar = 0xFF - *src;
  6947.  
  6948. while ((unsigned) src < src_end)
  6949. {
  6950. currChar = *(dest++) = *(src++);
  6951.  
  6952. if ( currChar == prevChar )
  6953. {
  6954. if ( (unsigned) src == src_end )
  6955. {
  6956. *(dest++) = 0;
  6957. *(dest++) = 0;
  6958. }
  6959. else
  6960. {
  6961. count = 0;
  6962. while (((unsigned)src < src_end) && (count < 0xFFF0))
  6963. {
  6964. if (*src == prevChar)
  6965. {
  6966. count++;
  6967. src++;
  6968. if ( (unsigned) src == src_end )
  6969. {
  6970. *(unsigned short*) dest = count;
  6971. dest += 2;
  6972. }
  6973. }
  6974. else
  6975. {
  6976. *(unsigned short*) dest = count;
  6977. dest += 2;
  6978. prevChar = 0xFF - *src;
  6979. break;
  6980. }
  6981. }
  6982. }
  6983. }
  6984. else
  6985. prevChar = currChar;
  6986. }
  6987. return (unsigned)dest - dest_start;
  6988. }
  6989.  
  6990. void RleDecode(unsigned char *src, unsigned char *dest, unsigned src_size)
  6991. {
  6992. unsigned char currChar, prevChar; /* current and previous characters */
  6993. unsigned short count; /* number of characters in a run */
  6994. unsigned src_end;
  6995.  
  6996. src_end = (unsigned) src + src_size;
  6997.  
  6998. /* decode */
  6999.  
  7000. prevChar = 0xFF - *src; /* force next char to be different */
  7001.  
  7002. /* read input until there's nothing left */
  7003.  
  7004. while ((unsigned) src < src_end)
  7005. {
  7006. currChar = *(src++);
  7007.  
  7008. *(dest++) = currChar;
  7009.  
  7010. /* check for run */
  7011. if (currChar == prevChar)
  7012. {
  7013. /* we have a run. write it out. */
  7014. count = *(unsigned short*) src;
  7015. src += 2;
  7016. while (count > 0)
  7017. {
  7018. *(dest++) = currChar;
  7019. count--;
  7020. }
  7021.  
  7022. prevChar = 0xFF - *src; /* force next char to be different */
  7023. }
  7024. else
  7025. {
  7026. /* no run */
  7027. prevChar = currChar;
  7028. }
  7029. }
  7030. }
  7031.  
  7032.  
  7033. /* expand a key (makes a rc4_key) */
  7034.  
  7035. void prepare_key(unsigned char *keydata, unsigned len, struct rc4_key *key)
  7036. {
  7037. unsigned index1, index2, counter;
  7038. unsigned char *state;
  7039.  
  7040. state = key->state;
  7041.  
  7042. for (counter = 0; counter < 256; counter++)
  7043. state[counter] = counter;
  7044.  
  7045. key->x = key->y = index1 = index2 = 0;
  7046.  
  7047. for (counter = 0; counter < 256; counter++) {
  7048. index2 = (keydata[index1] + state[counter] + index2) & 255;
  7049.  
  7050. /* swap */
  7051. state[counter] ^= state[index2];
  7052. state[index2] ^= state[counter];
  7053. state[counter] ^= state[index2];
  7054.  
  7055. index1 = (index1 + 1) % len;
  7056. }
  7057. }
  7058.  
  7059. /* reversible encryption, will encode a buffer updating the key */
  7060.  
  7061. void rc4(unsigned char *buffer, unsigned len, struct rc4_key *key)
  7062. {
  7063. unsigned x, y, xorIndex, counter;
  7064. unsigned char *state;
  7065.  
  7066. /* get local copies */
  7067. x = key->x; y = key->y;
  7068. state = key->state;
  7069.  
  7070. for (counter = 0; counter < len; counter++) {
  7071. x = (x + 1) & 255;
  7072. y = (state[x] + y) & 255;
  7073.  
  7074. /* swap */
  7075. state[x] ^= state[y];
  7076. state[y] ^= state[x];
  7077. state[x] ^= state[y];
  7078.  
  7079. xorIndex = (state[y] + state[x]) & 255;
  7080.  
  7081. buffer[counter] ^= state[xorIndex];
  7082. }
  7083.  
  7084. key->x = x; key->y = y;
  7085. }
  7086.  
  7087. void compressShipPacket ( ORANGE* ship, unsigned char* src, unsigned long src_size )
  7088. {
  7089. unsigned char* dest;
  7090. unsigned long result;
  7091.  
  7092. if (ship->shipSockfd >= 0)
  7093. {
  7094. if (PACKET_BUFFER_SIZE - ship->snddata < (int) ( src_size + 100 ) )
  7095. initialize_ship(ship);
  7096. else
  7097. {
  7098. if ( ship->crypt_on )
  7099. {
  7100. dest = &ship->sndbuf[ship->snddata];
  7101. // Store the original packet size before RLE compression at offset 0x04 of the new packet.
  7102. dest += 4;
  7103. *(unsigned *) dest = src_size;
  7104. // Compress packet using RLE, storing at offset 0x08 of new packet.
  7105. //
  7106. // result = size of RLE compressed data + a DWORD for the original packet size.
  7107. result = RleEncode (src, dest+4, src_size) + 4;
  7108. // Encrypt with RC4
  7109. rc4 (dest, result, &ship->sc_key);
  7110. // Increase result by the size of a DWORD for the final ship packet size.
  7111. result += 4;
  7112. // Copy it to the front of the packet.
  7113. *(unsigned *) &ship->sndbuf[ship->snddata] = result;
  7114. ship->snddata += (int) result;
  7115. }
  7116. else
  7117. {
  7118. memcpy ( &ship->sndbuf[ship->snddata+4], src, src_size );
  7119. src_size += 4;
  7120. *(unsigned *) &ship->sndbuf[ship->snddata] = src_size;
  7121. ship->snddata += src_size;
  7122. }
  7123. }
  7124. }
  7125. }
  7126.  
  7127. void decompressShipPacket ( ORANGE* ship, unsigned char* dest, unsigned char* src )
  7128. {
  7129. unsigned src_size, dest_size;
  7130. unsigned char *srccpy;
  7131.  
  7132. if (ship->crypt_on)
  7133. {
  7134. src_size = *(unsigned *) src;
  7135. src_size -= 8;
  7136. src += 4;
  7137. srccpy = src;
  7138. // Decrypt RC4
  7139. rc4 (src, src_size+4, &ship->cs_key);
  7140. // The first four bytes of the src should now contain the expected uncompressed data size.
  7141. dest_size = *(unsigned *) srccpy;
  7142. // Increase expected size by 4 before inserting into the destination buffer. (To take account for the packet
  7143. // size DWORD...)
  7144. dest_size += 4;
  7145. *(unsigned *) dest = dest_size;
  7146. // Decompress the data...
  7147. RleDecode (srccpy+4, dest+4, src_size);
  7148. }
  7149. else
  7150. {
  7151. src_size = *(unsigned *) src;
  7152. memcpy (dest + 4, src + 4, src_size);
  7153. src_size += 4;
  7154. *(unsigned *) dest = src_size;
  7155. }
  7156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement