Clone of Akilla's acserver @ https://github.com/deregtd/ACServer

Network.cpp 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918
  1. #include "stdafx.h"
  2. //#include "Network.h"
  3. #include "FixedPackets.h"
  4. cACServer::cACServer()
  5. {
  6. //Constructor
  7. Listening = false;
  8. WSADATA wsaData;
  9. WORD wVersionRequested = 0x0202;
  10. int err;
  11. err = WSAStartup(wVersionRequested, &wsaData); //for winsock startup
  12. for (int i=0;i<128;i++)
  13. {
  14. ConnUser[i].Connected = false;
  15. ConnUser[i].State = 0;
  16. ConnUser[i].Char = 0;
  17. }
  18. MaxUsers = 0;
  19. NumConnected = 0;
  20. NumStored = 0;
  21. for (i=0;i<16384;i++)
  22. IPStore[i].Enabled = false;
  23. NeedToDelete = true;
  24. LoadOptions();
  25. // CalcNextFreeGUID();
  26. }
  27. cACServer::~cACServer()
  28. {
  29. //Destructor
  30. SaveObjects();
  31. for (int i=0;i<128;i++)
  32. if (ConnUser[i].Connected)
  33. DisconnectUser(i);
  34. WSACleanup(); // Always do this at the end of a winsock program
  35. }
  36. void cACServer::LoadOptions()
  37. {
  38. HKEY keyout;
  39. RegCreateKey(HKEY_CURRENT_USER, "Software\\ACServer\\Server", &keyout);
  40. long outvallen;
  41. outvallen = 2048;
  42. if (RegQueryValue(keyout, "MOTD", MOTDb, &outvallen) != ERROR_SUCCESS)
  43. {
  44. sprintf(MOTDb, "This server's operator needs to set its MOTD in the options...\n");
  45. }
  46. outvallen = 64;
  47. if (RegQueryValue(keyout, "ServerName", ServerName, &outvallen) != ERROR_SUCCESS)
  48. {
  49. sprintf(ServerName, "Unnamed Server");
  50. }
  51. outvallen = 4;
  52. if (RegQueryValueEx(keyout, "ListenPort", 0, NULL, (BYTE *) &ListenPort, (DWORD *) &outvallen) != ERROR_SUCCESS)
  53. {
  54. ListenPort = 9002;
  55. }
  56. outvallen = 16;
  57. if (RegQueryValue(keyout, "Speed", Speed, &outvallen) != ERROR_SUCCESS)
  58. {
  59. sprintf(Speed, "Unset Speed");
  60. }
  61. outvallen = 64;
  62. if (RegQueryValue(keyout, "Admin", Admin, &outvallen) != ERROR_SUCCESS)
  63. {
  64. sprintf(Admin, "Unset Admin");
  65. }
  66. outvallen = 64;
  67. if (RegQueryValue(keyout, "Host", Host, &outvallen) != ERROR_SUCCESS)
  68. {
  69. sprintf(Host, "");
  70. }
  71. outvallen = 4;
  72. if (RegQueryValueEx(keyout, "Private", 0, NULL, (BYTE *) &Private, (DWORD *) &outvallen) != ERROR_SUCCESS)
  73. {
  74. Private = false;
  75. }
  76. outvallen = 4;
  77. if (RegQueryValueEx(keyout, "MOTDaShown", 0, NULL, (BYTE *) &MOTDaShown, (DWORD *) &outvallen) != ERROR_SUCCESS)
  78. {
  79. MOTDaShown = true;
  80. }
  81. RegCloseKey(keyout);
  82. }
  83. void cACServer::SaveOptions()
  84. {
  85. HKEY keyout;
  86. RegCreateKey(HKEY_CURRENT_USER, "Software\\ACServer\\Server", &keyout);
  87. RegSetValue(keyout, "MOTD", REG_SZ, MOTDb, strlen(MOTDb));
  88. RegSetValue(keyout, "ServerName", REG_SZ, ServerName, strlen(ServerName));
  89. RegSetValueEx(keyout, "ListenPort", 0, REG_DWORD, (const BYTE *) &ListenPort, 4);
  90. RegSetValue(keyout, "Admin", REG_SZ, Admin, strlen(Admin));
  91. RegSetValue(keyout, "Speed", REG_SZ, Speed, strlen(Speed));
  92. RegSetValueEx(keyout, "Private", 0, REG_DWORD, (const BYTE *) &Private, 4);
  93. RegSetValueEx(keyout, "MOTDaShown", 0, REG_DWORD, (const BYTE *) &MOTDaShown, 4);
  94. RegSetValue(keyout, "Host", REG_SZ, Host, strlen(Host));
  95. RegCloseKey(keyout);
  96. }
  97. void cACServer::StartListen()
  98. {
  99. LoadObjects();
  100. Listening = true;
  101. srand(time(NULL));
  102. struct sockaddr_in localAddress; //IP and port of the local machine
  103. localAddress.sin_family = AF_INET;
  104. localAddress.sin_addr.s_addr = inet_addr(LocalIP);
  105. localAddress.sin_port = htons(ListenPort);
  106. charSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  107. BOOL newopt = FALSE;
  108. setsockopt(charSocket, SOL_SOCKET, SO_DONTLINGER, (const char *) &newopt, sizeof(newopt));
  109. setsockopt(charSocket, SOL_SOCKET, TCP_NODELAY, (const char *) &newopt, sizeof(newopt));
  110. int newbuf = 0x8000; //448;
  111. setsockopt(charSocket, SOL_SOCKET, SO_SNDBUF, (const char *) &newbuf, sizeof(newbuf));
  112. setsockopt(charSocket, SOL_SOCKET, SO_RCVBUF, (const char *) &newbuf, sizeof(newbuf));
  113. bind(charSocket, (struct sockaddr *)&localAddress, sizeof(sockaddr_in) );
  114. listen(charSocket, SOMAXCONN);
  115. sprintf(sayit, "ACServer Server Up! Listening on port %i...", ListenPort); LogDisp(sayit);
  116. SendDlgItemMessage(MainWnd, IDC_CHARLIST, LB_RESETCONTENT, 0, 0);
  117. char tosay[100];
  118. sprintf(tosay, "User\tIP:Port\tStatus"); SendDlgItemMessage(MainWnd, IDC_CHARLIST, LB_ADDSTRING, 0, (WPARAM) &tosay[0]);
  119. for (int i=0;i<128;i++)
  120. {
  121. sprintf(tosay, "%i\tN/A\tNot Connected", i);
  122. SendDlgItemMessage(MainWnd, IDC_CHARLIST, LB_ADDSTRING, 0, (WPARAM) &tosay[0]);
  123. }
  124. //Set up event notification on main listen socket
  125. int err = WSAAsyncSelect(charSocket, MainWnd, WM_USER+1, FD_ACCEPT);
  126. }
  127. void cACServer::LoadAccounts()
  128. {
  129. FILE *in = fopen("Password.dat","rb");
  130. if (!in)
  131. {
  132. NumPasses = 0;
  133. return;
  134. }
  135. fseek(in, 0, SEEK_END);
  136. int filelen = ftell(in);
  137. fseek(in, 0, SEEK_SET);
  138. NumPasses = (int) (filelen/sizeof(stAccounts));
  139. fread(ZonePasses, filelen, 1, in);
  140. for (int i=0;i<NumPasses;i++)
  141. {
  142. ZonePasses[i].LoggedIn = (WORD) -1;
  143. }
  144. fclose(in);
  145. }
  146. void cACServer::CalcNextFreeGUID()
  147. {
  148. NextFreeCharGUID = 0x50000000;
  149. for (int i=0;i<NumPasses;i++)
  150. {
  151. for (int j=0;j<5;j++)
  152. {
  153. if (ZonePasses[i].Chars[j] >= NextFreeCharGUID)
  154. NextFreeCharGUID = ZonePasses[i].Chars[j] + 1;
  155. }
  156. }
  157. }
  158. void cACServer::SaveAccounts()
  159. {
  160. FILE *out = fopen("Password.dat","wb");
  161. if (!out)
  162. {
  163. MessageBox(NULL, "Error on Password File Save! Very bad!!", "Critical Error!", MB_OK);
  164. return;
  165. }
  166. fwrite(ZonePasses, sizeof(stAccounts)*NumPasses, 1, out);
  167. fclose(out);
  168. }
  169. void cACServer::AcceptUser()
  170. {
  171. sockaddr_in tpsa; int tpsal = sizeof(tpsa);
  172. SOCKET tpsck = accept(charSocket, (sockaddr *) &tpsa, &tpsal);
  173. if (tpsck != SOCKET_ERROR)
  174. {
  175. for (int i=0;i<128;i++)
  176. {
  177. if (!ConnUser[i].Connected)
  178. {
  179. memcpy(&ConnUser[i].sockaddy,&tpsa,sizeof(sockaddr));
  180. ConnUser[i].Socket = tpsck;
  181. ConnUser[i].m_input.clear();
  182. ConnUser[i].m_output.clear();
  183. ConnUser[i].Connected = true;
  184. ConnUser[i].State = -1;
  185. ConnUser[i].RecvState = -1;
  186. int err = WSAAsyncSelect(tpsck, MainWnd, WM_USER+2+i, FD_READ);
  187. break;
  188. }
  189. }
  190. }
  191. }
  192. void cACServer::NewRead(int UserNum)
  193. {
  194. int Ret;
  195. for ( ;; )
  196. {
  197. if (ConnUser[UserNum].RecvState == -1)
  198. {
  199. Ret = recv(ConnUser[UserNum].Socket, (char *) &ConnUser[UserNum].CurrentHeader, sizeof(EmuHeader), NULL);
  200. if (Ret == SOCKET_ERROR)
  201. {
  202. int ErrRet = WSAGetLastError();
  203. if (ErrRet == WSAEWOULDBLOCK)
  204. {
  205. //No more data, come back later...
  206. return;
  207. } else {
  208. //Eep bad... Disconnected...?
  209. DisconnectUser(UserNum);
  210. return;
  211. }
  212. }
  213. ConnUser[UserNum].RecvState = 0;
  214. } else {
  215. Ret = recv(ConnUser[UserNum].Socket, (char *) ConnUser[UserNum].RecvBuff, ConnUser[UserNum].CurrentHeader.payloadsize_, NULL);
  216. if (Ret == SOCKET_ERROR)
  217. {
  218. int ErrRet = WSAGetLastError();
  219. if (ErrRet == WSAEWOULDBLOCK)
  220. {
  221. //No more data, come back later...
  222. return;
  223. } else {
  224. //Eep bad... Disconnected...?
  225. DisconnectUser(UserNum);
  226. return;
  227. }
  228. }
  229. ConnUser[UserNum].RecvState += Ret;
  230. if (ConnUser[UserNum].RecvState == ConnUser[UserNum].CurrentHeader.payloadsize_)
  231. {
  232. ConnUser[UserNum].RecvState = -1;
  233. switch (ConnUser[UserNum].CurrentHeader.type_)
  234. {
  235. case EmuHeader::Authenticate:
  236. AuthenticateUser(UserNum);
  237. break;
  238. case EmuHeader::Payload:
  239. ParseMessage(UserNum);
  240. break;
  241. }
  242. }
  243. }
  244. }
  245. }
  246. void cACServer::AuthenticateUser(int UserParsing)
  247. {
  248. BYTE *RecvBuf = ConnUser[UserParsing].RecvBuff;
  249. //Get l/p here...
  250. char tpLogin[20], tpPass[20];
  251. memcpy(tpLogin, RecvBuf, 20);
  252. memcpy(tpPass, RecvBuf+20, 20);
  253. bool LoginFound = false;
  254. int LoginRet = 2;
  255. //0 = Valid Existing Login
  256. //1 = Valid New Login
  257. //2 = Incorrect Password
  258. //Check for existing Login by that name, or else create new one...
  259. for (int h=0;h<NumPasses;h++)
  260. {
  261. if (strcmp(ZonePasses[h].Login,tpLogin) == 0)
  262. {
  263. //ID Found
  264. LoginFound = true;
  265. if (strcmp(ZonePasses[h].Pass,tpPass) == 0)
  266. {
  267. //Valid Password
  268. sprintf(sayit, "User %s logged in.", ZonePasses[h].Login); LogDisp(sayit);
  269. LoginRet = 0;
  270. ConnUser[UserParsing].ZoneNum = h;
  271. }
  272. h = NumPasses;
  273. }
  274. }
  275. if (!LoginFound)
  276. {
  277. memcpy(ZonePasses[NumPasses].Login, tpLogin, 20);
  278. memcpy(ZonePasses[NumPasses].Pass, tpPass, 20);
  279. ZeroMemory(ZonePasses[NumPasses].Chars, sizeof(ZonePasses[NumPasses].Chars));
  280. ZeroMemory(ZonePasses[NumPasses].Secs2Del, sizeof(ZonePasses[NumPasses].Secs2Del));
  281. ZeroMemory(ZonePasses[NumPasses].Names, sizeof(ZonePasses[NumPasses].Names));
  282. sprintf(sayit, "New User %s logged in.", ZonePasses[NumPasses].Login); LogDisp(sayit);
  283. LoginRet = 1;
  284. ZonePasses[NumPasses].LoggedIn = -1;
  285. ConnUser[UserParsing].ZoneNum = NumPasses;
  286. NumPasses++;
  287. SaveAccounts();
  288. }
  289. memcpy(ConnUser[UserParsing].ZoneName, ZonePasses[ConnUser[UserParsing].ZoneNum].Login, 20);
  290. //Return LoginRet here...
  291. //
  292. //!!!
  293. send(ConnUser[UserParsing].Socket, (char *) &LoginRet, 4, NULL);
  294. if (LoginRet == 2)
  295. {
  296. //Invalid Login...
  297. ConnUser[UserParsing].Connected = false;
  298. closesocket(ConnUser[UserParsing].Socket);
  299. return;
  300. }
  301. ConnUser[UserParsing].State = 1;
  302. ConnUser[UserParsing].curSeq = 1;
  303. ConnUser[UserParsing].EventCount = 0;
  304. ConnUser[UserParsing].ModelCount = 0;
  305. ConnUser[UserParsing].msgID = 1;
  306. ConnUser[UserParsing].bTime = 0;
  307. ConnUser[UserParsing].RecTime = 0;
  308. ConnUser[UserParsing].LastTime = 0;
  309. ConnUser[UserParsing].move_count = 1;
  310. ConnUser[UserParsing].SelectedItem = 0;
  311. ConnUser[UserParsing].PortalCount = 0;
  312. ConnUser[UserParsing].OverrideCount = 0;
  313. ConnUser[UserParsing].AnimCount = 0;
  314. ConnUser[UserParsing].MoveItemCount = 1;
  315. ConnUser[UserParsing].EquipCount = 0;
  316. ConnUser[UserParsing].AttackCount = 0;
  317. ZeroMemory(ConnUser[UserParsing].Count237, sizeof(ConnUser[UserParsing].Count237));
  318. ZeroMemory(ConnUser[UserParsing].Count244,3);
  319. ConnUser[UserParsing].Count23E = 0;
  320. ConnUser[UserParsing].Connable = true;
  321. ConnUser[UserParsing].ConnTimer = 0;
  322. UpdateCharInfo(UserParsing, "Connected...");
  323. if (UserParsing >= MaxUsers)
  324. MaxUsers = UserParsing + 1;
  325. }
  326. void cACServer::ParseMessage(int UserParsing)
  327. {
  328. BYTE *RecvBuf = ConnUser[UserParsing].RecvBuff;
  329. cClientPacketHeader *tphdr = (cClientPacketHeader *) RecvBuf;
  330. memcpy(tphdr, RecvBuf, sizeof(cClientPacketHeader));
  331. int PackSize = ConnUser[UserParsing].CurrentHeader.payloadsize_;
  332. ConnUser[UserParsing].LastTime = ConnUser[UserParsing].RecTime;
  333. ConnUser[UserParsing].lastInSeq = tphdr->m_dwSequence;
  334. switch (tphdr->m_dwFlags)
  335. {
  336. case 0x00000002: //Error
  337. sprintf(sayit, "* Error Packet - 2...");
  338. LogDisp(sayit);
  339. break;
  340. case 0x00000004: //Ping
  341. if (ConnUser[UserParsing].bTime < tphdr->m_bTime)
  342. ConnUser[UserParsing].bTime = tphdr->m_bTime;
  343. //Reply at some point...
  344. break;
  345. case 0x00000020: //Disconnect
  346. DisconnectUser(UserParsing);
  347. break;
  348. case 0x00000040: //Timing
  349. //Ignore
  350. break;
  351. case 0x00100000: //Timing
  352. //Ignore
  353. break;
  354. case 0x00200000: //Unknown
  355. //Ignore
  356. break;
  357. case 0x00000080: //Connection Attempt
  358. if (ConnUser[UserParsing].Connable)
  359. {
  360. UpdateCharInfo(UserParsing, "Sending Initial Info...");
  361. ConnUser[UserParsing].Connable = false;
  362. ConnUser[UserParsing].ConnTimer = 5;
  363. SendCharList(UserParsing);
  364. UpdateCharInfo(UserParsing, "Selecting Character");
  365. }
  366. break;
  367. case 0x00000200:
  368. Parse200(UserParsing, *((DWORD *) (RecvBuf+sizeof(cClientPacketHeader))), &RecvBuf[sizeof(cClientPacketHeader) + 4], PackSize - sizeof(cClientPacketHeader) - 4);
  369. break;
  370. default:
  371. //Unknown Type
  372. char * tps = new char[1 + (PackSize-sizeof(cClientPacketHeader))*5], *tps2 = tps;
  373. if (tps)
  374. {
  375. for (unsigned int tpl=0; tpl < (PackSize-sizeof(cClientPacketHeader)); tpl++)
  376. {
  377. sprintf(tps2, "0x%02X ", RecvBuf+sizeof(cClientPacketHeader)+tpl);
  378. tps2+=5;
  379. }
  380. }
  381. sprintf(sayit, "In:Seq:%08X Flg:%08X Srv:%08X CRC:%08X Size:%04X Tm:%02X Table:%02X * Data: %s", tphdr->m_dwSequence, tphdr->m_dwFlags, tphdr->m_dwServerID, tphdr->m_dwCRC, tphdr->m_wTotalSize, tphdr->m_bTime, tphdr->m_bTable, tps); LogDisp(sayit);
  382. delete [] tps;
  383. break;
  384. }
  385. }
  386. void cACServer::LogDisp(char *toDisp)
  387. {
  388. int numtodisp = 1 + (int) (strlen(toDisp)/90);
  389. char tosay[91];
  390. tosay[90] = 0;
  391. int lognum;
  392. for (int i=0;i<numtodisp;i++)
  393. {
  394. memcpy(&tosay[0],toDisp+(i*90),90);
  395. lognum = SendDlgItemMessage(MainWnd, IDC_LIST1, LB_ADDSTRING/*LB_INSERTSTRING*/, 0, (LPARAM) tosay);
  396. }
  397. SendDlgItemMessage(MainWnd, IDC_LIST1, LB_SETTOPINDEX, lognum-16, 0);
  398. }
  399. void cACServer::IncTimes()
  400. {
  401. for (int i=0;i<MaxUsers;i++)
  402. {
  403. if (ConnUser[i].Connected)
  404. {
  405. if (!ConnUser[i].Connable)
  406. {
  407. ConnUser[i].ConnTimer--;
  408. if (!ConnUser[i].ConnTimer)
  409. ConnUser[i].Connable = true;
  410. }
  411. // ConnUser[i].bTime++;
  412. // if (ConnUser[i].bTime > 80)
  413. // ConnUser[i].bTime = 0;
  414. ConnUser[i].RecTime++;
  415. if ((ConnUser[i].RecTime - ConnUser[i].LastTime) > 30) //If 30 seconds...
  416. {
  417. DisconnectUser(i);
  418. // sprintf(sayit, "* User %i timed out, disconnecting...", i); LogDisp(sayit);
  419. }
  420. }
  421. }
  422. if (NeedToDelete)
  423. {
  424. NeedToDelete = false;
  425. for (i=0;i<NumPasses;i++)
  426. {
  427. for (int j=0;j<5;j++)
  428. {
  429. if (ZonePasses[i].Secs2Del[j])
  430. {
  431. ZonePasses[i].Secs2Del[j]--;
  432. if (!ZonePasses[i].Secs2Del[j])
  433. {
  434. ZonePasses[i].Chars[j] = 0;
  435. ZeroMemory(ZonePasses[i].Names[j], 32);
  436. if (ZonePasses[i].LoggedIn != -1)
  437. SendCharList(ZonePasses[i].LoggedIn);
  438. SaveAccounts();
  439. } else {
  440. NeedToDelete = true;
  441. }
  442. }
  443. }
  444. }
  445. }
  446. }
  447. void cACServer::SendCharList(int UserParsing)
  448. {
  449. BYTE PlayerList[0x2000];
  450. BYTE *PackPointer = PlayerList;
  451. DWORD tpdword;
  452. tpdword = 0x0000F658; memcpy(PackPointer, &tpdword, 4); PackPointer += 4;
  453. tpdword = 0x00000000; memcpy(PackPointer, &tpdword, 4); PackPointer += 4;
  454. int NumChars = 0;
  455. for (int i=0;i<5;i++)
  456. if (ZonePasses[ConnUser[UserParsing].ZoneNum].Chars[i])
  457. NumChars++;
  458. memcpy(PackPointer, &NumChars, 4); PackPointer += 4;
  459. int outlen;
  460. for (i=0;i<5;i++)
  461. {
  462. if (ZonePasses[ConnUser[UserParsing].ZoneNum].Chars[i])
  463. {
  464. tpdword = ZonePasses[ConnUser[UserParsing].ZoneNum].Chars[i] & 0x7FFFFFFF;
  465. memcpy(PackPointer,&tpdword,4); PackPointer += 4; //GUID
  466. GenString(ZonePasses[ConnUser[UserParsing].ZoneNum].Names[i], &outlen, PackPointer); PackPointer += outlen;
  467. //Time remaining till perma-delete
  468. if (ZonePasses[ConnUser[UserParsing].ZoneNum].Chars[i] & 0x80000000)
  469. tpdword = ZonePasses[ConnUser[UserParsing].ZoneNum].Secs2Del[i];
  470. else
  471. tpdword = 0;
  472. memcpy(PackPointer, &tpdword, 4); PackPointer += 4;
  473. }
  474. }
  475. tpdword = 0;
  476. for (i=0;i<5;i++)
  477. if (ZonePasses[ConnUser[UserParsing].ZoneNum].Chars[i] & 0x80000000)
  478. tpdword++;
  479. memcpy(PackPointer,&tpdword,4); PackPointer += 4; //0 - DWORD
  480. tpdword = 5; memcpy(PackPointer,&tpdword,4); PackPointer += 4; //5 - DWORD
  481. tpdword = 0xBEEFBEEF; memcpy(PackPointer,&tpdword,4); PackPointer += 4; //BEEFBEEF - DWORD
  482. memcpy(PackPointer,&ConnUser[UserParsing].ZoneName[0],0x14); PackPointer += 20; //Zone Name - 20 Chars
  483. tpdword = 0; memcpy(PackPointer,&tpdword,4); PackPointer += 4; //0 - DWORD
  484. Send200(PlayerList, (int) (PackPointer - PlayerList), 4, UserParsing);
  485. //MOTD
  486. PackPointer = PlayerList;
  487. NumConnected = 0;
  488. for (int hh=0;hh<128;hh++)
  489. {
  490. if (ConnUser[hh].Connected)
  491. NumConnected++;
  492. }
  493. char tpmult[2] = { 's', 0 };
  494. if (NumConnected == 1)
  495. tpmult[0] = 0;
  496. if (MOTDaShown)
  497. sprintf(MOTDa, "You are in the world of: %s!\n\nThere are currently: %i Client%s Connected.\n\n", ServerName, NumConnected, tpmult);
  498. else
  499. sprintf(MOTDa, "");
  500. DWORD Zero = 0x0000F65A; memcpy(PackPointer,&Zero,4); PackPointer += 4; //F65A - DWORD
  501. GenString(MOTDa, &outlen, PackPointer); PackPointer += outlen;
  502. GenString(MOTDb, &outlen, PackPointer); PackPointer += outlen;
  503. Send200(PlayerList, (int) (PackPointer - PlayerList), 4, UserParsing);
  504. }
  505. void cACServer::Send200(BYTE *data, int datalen, WORD wUnk, int User)
  506. {
  507. EmuHeader tph;
  508. tph.payloadsize_ = datalen;
  509. tph.message_ = wUnk;
  510. send(ConnUser[User].Socket, (char *) &tph, sizeof(tph), NULL);
  511. // send(ConnUser[User].Socket, (char *) data, datalen, NULL);
  512. for (int i=0;i<datalen;i+=448) //Split into 448 byte chunks 4 some reason... :P
  513. {
  514. // cPacket tpp;
  515. // tpp.m_wSize = (datalen - i >= 448) ? 448 : (datalen - i);
  516. // tpp.m_pbPayload = new BYTE[tpp.m_wSize];
  517. // memcpy(tpp.m_pbPayload, data+i, tpp.m_wSize);
  518. // ConnUser[User].m_output.push_back(tpp);
  519. int ret = send(ConnUser[User].Socket, (char *) data+i, (datalen - i >= 448) ? 448 : (datalen - i), NULL);
  520. if (((datalen - i >= 448) && (ret != 448)) || ((datalen - i < 448) && (ret != (datalen - i))))
  521. {
  522. if (ret == SOCKET_ERROR)
  523. {
  524. int la = WSAGetLastError();
  525. } else {
  526. // MessageBox(MainWnd, "Buffer error happened, user is effectively disconnected!", "Doh!", MB_OK);
  527. LogDisp("Buffer error happened, a user has been disconnected...");
  528. }
  529. }
  530. }
  531. }
  532. void cACServer::DisconnectUser(int User)
  533. {
  534. if (ConnUser[User].Connected == false)
  535. return;
  536. ConnUser[User].ObjectCache.clear();
  537. ConnUser[User].Connected = false;
  538. closesocket(ConnUser[User].Socket);
  539. NumConnected = 0;
  540. for (int hh=0;hh<128;hh++)
  541. {
  542. if (ConnUser[hh].Connected)
  543. NumConnected++;
  544. }
  545. ZonePasses[ConnUser[User].ZoneNum].LoggedIn = (WORD) -1;
  546. UpdateCharInfo(User, "Not Connected");
  547. //Recalc MaxUsers
  548. for (int i=127;i>=0;i--)
  549. {
  550. if (ConnUser[i].Connected)
  551. { MaxUsers = i+1; break; }
  552. }
  553. if (ConnUser[User].Char == 0)
  554. return;
  555. SaveCharacter(User);
  556. LBObjects[ConnUser[User].Char->Loc.landblock >> 16].erase(ConnUser[User].Char->GUID);
  557. if (ObjectList[ConnUser[User].Char->GUID])
  558. ObjectList.erase(ConnUser[User].Char->GUID);
  559. sprintf(sayit, "Player %s Disconnected!", ConnUser[User].Char->Name);
  560. ServerMessage(GLOBAL_MESSAGE, sayit, COLOR_GREEN);
  561. ConnUser[User].Char = 0;
  562. }
  563. void cACServer::UpdateCharInfo(int User, char * NewText)
  564. {
  565. SendDlgItemMessage(MainWnd, IDC_CHARLIST, LB_DELETESTRING, User+1, 0);
  566. char TpStr[100];
  567. strcpy(ConnUser[User].Status, NewText);
  568. if (ConnUser[User].Connected)
  569. {
  570. sprintf(TpStr, "%i\t%i.%i.%i.%i:%i\t%s", User,
  571. ConnUser[User].sockaddy.sin_addr.S_un.S_un_b.s_b1,
  572. ConnUser[User].sockaddy.sin_addr.S_un.S_un_b.s_b2,
  573. ConnUser[User].sockaddy.sin_addr.S_un.S_un_b.s_b3,
  574. ConnUser[User].sockaddy.sin_addr.S_un.S_un_b.s_b4,
  575. ntohs(ConnUser[User].sockaddy.sin_port),
  576. NewText);
  577. } else {
  578. sprintf(TpStr, "%i\tN/A\t%s", User, NewText);
  579. }
  580. SendDlgItemMessage(MainWnd, IDC_CHARLIST, LB_INSERTSTRING, User+1, (WPARAM) &TpStr[0]);
  581. }
  582. void cACServer::SaveCharacter(int CharNum)
  583. {
  584. if (!ConnUser[CharNum].Char) return;
  585. FILE *charread = fopen("CharList.dat","r+b");
  586. fseek(charread, 0, SEEK_END);
  587. int numchars = ftell(charread)/(SIZEOFCHAR+68);
  588. fseek(charread, 0, SEEK_SET);
  589. DWORD GUIDtemp;
  590. for (int j=0;j<numchars;j++)
  591. {
  592. fseek(charread, j*(SIZEOFCHAR+68), SEEK_SET);
  593. fread(&GUIDtemp, 4, 1, charread);
  594. if (GUIDtemp == ConnUser[CharNum].Char->GUID)
  595. {
  596. fseek(charread, j*(SIZEOFCHAR+68), SEEK_SET);
  597. BYTE TPlog[0x5000]; int charsize = ConnUser[CharNum].Char->Serialize(TPlog);
  598. fwrite(&ConnUser[CharNum].Char->GUID, 4, 1, charread);
  599. fwrite(ConnUser[CharNum].Char->Name, 32, 1, charread);
  600. fwrite(&ConnUser[CharNum].Char->Loc, sizeof(Location_t), 1, charread);
  601. fwrite(TPlog, charsize, 1, charread);
  602. // fwrite(ConnUser[CharNum].Char, sizeof(cWorldObject_Char), 1, charread);
  603. j = numchars;
  604. }
  605. }
  606. fclose(charread);
  607. }
  608. void cACServer::LoadObjects()
  609. {
  610. sprintf(sayit, "Loading Objects.Dat..."); LogDisp(sayit);
  611. FILE *in = fopen("Objects.dat","rb");
  612. if (!in)
  613. {
  614. sprintf(sayit, "Objects.Dat Empty! Initializing with an empty empty world."); LogDisp(sayit);
  615. return;
  616. }
  617. BYTE ObjData[4096];
  618. cWorldObject *tpObj = (cWorldObject *) ObjData;
  619. int errtest;
  620. cWorldObject *tpo;
  621. while (!feof(in))
  622. {
  623. DWORD ObjType; errtest = fread(&ObjType, 4, 1, in);
  624. if (!errtest)
  625. {
  626. fclose(in);
  627. sprintf(sayit, "Objects.Dat Loaded!"); LogDisp(sayit);
  628. return;
  629. }
  630. switch (ObjType)
  631. {
  632. case OBJECT_LIFESTONE:
  633. tpo = new cWorldObject_LS();
  634. break;
  635. case OBJECT_OBJECTID:
  636. tpo = new cWorldObject_ObjectID();
  637. break;
  638. case OBJECT_PORTAL:
  639. tpo = new cWorldObject_Portal();
  640. break;
  641. case OBJECT_CHARACTER:
  642. //Ignore
  643. MessageBox(NULL, "Fatal Error: Character found in objects.dat...", "Fatal Error", MB_OK);
  644. break;
  645. default:
  646. //eep... bad.
  647. MessageBox(NULL, "Fatal Error: Unknown Object type in Objects.Dat. Please Restore Objects.Dat. Objects.Dat loading halted...", "Fatal Error", MB_OK);
  648. return;
  649. }
  650. if (ObjType != OBJECT_CHARACTER)
  651. {
  652. fread(&tpo->GUID, 4, 1, in);
  653. fread(tpo->Name, 32, 1, in);
  654. fread(&tpo->Loc, 32, 1, in);
  655. fread(&tpo->Owner, 4, 1, in);
  656. fread(ObjData, tpo->Size, 1, in);
  657. tpo->LoadFrom(ObjData);
  658. ObjectList[tpo->GUID] = tpo;
  659. LBObjects[tpo->Loc.landblock >> 16][tpo->GUID] = tpo;
  660. }
  661. if (ObjType == OBJECT_PORTAL)
  662. Portals[tpo->Loc.landblock >> 16][tpo->GUID] = (cWorldObject_Portal *) tpo;
  663. }
  664. }
  665. void cACServer::SaveObjects()
  666. {
  667. //If no objects then don't bother :-)
  668. if (ObjectList.begin() == ObjectList.end())
  669. return;
  670. FILE *out = fopen("Objects.Dat","wb");
  671. if (!out)
  672. {
  673. //bad...
  674. MessageBox(NULL, "Can't open objects.dat for writing... very bad...", "Fatal Error", MB_OK);
  675. return;
  676. }
  677. BYTE SerData[4096]; int SerSize;
  678. for (std::map<DWORD, cWorldObject *>::iterator i = ObjectList.begin(); i != ObjectList.end(); i++)
  679. {
  680. if ((i->second) && (i->second->Type != OBJECT_CHARACTER))
  681. {
  682. fwrite(&i->second->Type, 4, 1, out);
  683. fwrite(&i->second->GUID, 4, 1, out);
  684. fwrite(i->second->Name, 32, 1, out);
  685. fwrite(&i->second->Loc, 32, 1, out);
  686. fwrite(&i->second->Owner, 4, 1, out);
  687. SerSize = i->second->Serialize(SerData);
  688. if (SerSize)
  689. fwrite(SerData, i->second->Size, 1, out);
  690. }
  691. }
  692. fclose(out);
  693. }
  694. void cACServer::SendLandblock(int User, WORD Landblock)
  695. {
  696. int packlen;
  697. BYTE TpP[500];
  698. for (std::map<DWORD, cWorldObject *>::iterator i = LBObjects[Landblock].begin(); i != LBObjects[Landblock].end(); i++)
  699. {
  700. if ((i->second->Type != 0) && (i->second->GUID != ConnUser[User].Char->GUID))
  701. {
  702. packlen = i->second->GenerateCreatePacket(TpP);
  703. Send200(TpP, packlen, 3, User);
  704. }
  705. }
  706. }
  707. float GetDistance(Location_t *loc1, Location_t *loc2)
  708. {
  709. DWORD landblock;
  710. int XX, ns, ew;
  711. double xc, yc, PosNSa, PosEWa, PosNSb, PosEWb;
  712. float Distance;
  713. if ((loc1->landblock & 0x0000FF00) && (loc2->landblock & 0x0000FF00))
  714. {
  715. //Interior
  716. Distance = fabs(sqrt(pow(loc2->x - loc1->x,2) + pow(loc2->y - loc1->y,2) + + pow(loc2->z - loc1->z,2)))/240;
  717. } else {
  718. //Exterior
  719. landblock = loc1->landblock;
  720. xc = loc1->x;
  721. yc = loc1->y;
  722. XX = landblock & 0x3F;
  723. ns = ((((landblock & 0x00FF0000) >> 16) + 1) * 8) + ((XX - 1) & 7) - 1027;
  724. ew = ((((landblock & 0xFF000000) >> 24) + 1) * 8) + (int) ((XX - 1) / 8) - 1027;
  725. xc = xc - ((int) (xc / 24.0f) * 24.0f);
  726. yc = yc - ((int) (yc / 24.0f) * 24.0f);
  727. PosEWa = ((float) (ew) / 10.0f) + (xc / 240.0f);
  728. PosNSa = ((float) (ns) / 10.0f) + (yc / 240.0f);
  729. landblock = loc2->landblock;
  730. xc = loc2->x;
  731. yc = loc2->y;
  732. XX = landblock & 0x3F;
  733. ns = ((((landblock & 0x00FF0000) >> 16) + 1) * 8) + ((XX - 1) & 7) - 1027;
  734. ew = ((((landblock & 0xFF000000) >> 24) + 1) * 8) + (int) ((XX - 1) / 8) - 1027;
  735. xc = xc - (float) ((int) (xc / 24.0f) * 24.0f);
  736. yc = yc - (float) ((int) (yc / 24.0f) * 24.0f);
  737. PosEWb = ((float) (ew) / 10.0f) + (xc / 240.0f);
  738. PosNSb = ((float) (ns) / 10.0f) + (yc / 240.0f);
  739. Distance = fabs(sqrt(pow(PosNSa - PosNSb,2) + pow(PosEWa - PosEWb,2) + pow((loc1->z - loc2->z)/240,2)));
  740. }
  741. return(Distance);
  742. }