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

HighLevelFuncs.cpp 29KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872
  1. #include "stdafx.h"
  2. #include "HighLevelFuncs.h"
  3. void cACServer::ActionComplete(int User)
  4. {
  5. DWORD ActComp[] = {
  6. 0x0000F7B0,
  7. ConnUser[User].Char->GUID,
  8. ConnUser[User].EventCount,
  9. 0x000001C7,
  10. 0x00000000,
  11. 0x00000000
  12. };
  13. ConnUser[User].EventCount++;
  14. Send200((BYTE *) ActComp, sizeof(ActComp), 3, User);
  15. }
  16. void cACServer::MoveUser(int User, Location_t *loc, bool Portal, bool Override)
  17. {
  18. BYTE MOVE_ENTITY[] = {
  19. 0x48, 0xF7, 0x00, 0x00, 0x03, 0x40, 0x16, 0x78, 0x34, 0x00, 0x00, 0x00, 0x08, 0x01, 0x64, 0x81, //(H÷___@_x4_____d_) - 0000
  20. 0xA1, 0xDB, 0x18, 0x41, 0xF0, 0x07, 0x19, 0x43, 0xD7, 0xA3, 0xBD, 0x41, 0xAA, 0x77, 0x6D, 0x3F, //(___A___C___A_wm?) - 0010
  21. 0xE0, 0x42, 0xBF, 0xBE, 0x39, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, //(_B__9_______) - 0020
  22. };
  23. for (std::map<DWORD, cWorldObject *>::iterator i = Portals[loc->landblock >> 16].begin(); i != Portals[loc->landblock >> 16].end(); i++)
  24. {
  25. if (GetDistance(loc, &i->second->Loc) < 0.03)
  26. {
  27. MoveUser(User, &((cWorldObject_Portal *)i->second)->DestLoc, true, false);
  28. // ServerMessage(User, "Entered Portal... Teleporting...", COLOR_RED);
  29. }
  30. }
  31. float heading = acos(loc->a);
  32. if (loc->w > 0) heading = PI - heading;
  33. heading *= 2;
  34. ConnUser[User].PointX = sin(heading);
  35. ConnUser[User].PointY = cos(heading);
  36. if (!ConnUser[User].Char)
  37. return;
  38. WORD OldLB = ConnUser[User].Char->Loc.landblock >> 16, NewLB = loc->landblock >> 16;
  39. memcpy(&ConnUser[User].Char->Loc, loc, sizeof(Location_t));
  40. DWORD tpf2 = 0x0000F748; memcpy (&MOVE_ENTITY[0x00],&tpf2,4);
  41. memcpy(&MOVE_ENTITY[0x4], &ConnUser[User].Char->GUID, 4);
  42. tpf2 = 0x00000034; memcpy (&MOVE_ENTITY[0x08],&tpf2,4);
  43. memcpy(&MOVE_ENTITY[0x0C], &ConnUser[User].Char->Loc, 4*5);
  44. memcpy(&MOVE_ENTITY[0x20], &ConnUser[User].Char->Loc.w, 4);
  45. if (Portal)
  46. ConnUser[User].PortalCount++;
  47. if (Override)
  48. ConnUser[User].OverrideCount++;
  49. memcpy (&MOVE_ENTITY[0x24],&ConnUser[User].Char->NumLogins,2);
  50. memcpy (&MOVE_ENTITY[0x26],&ConnUser[User].move_count,2);
  51. memcpy (&MOVE_ENTITY[0x28],&ConnUser[User].PortalCount,2);
  52. memcpy (&MOVE_ENTITY[0x2A],&ConnUser[User].OverrideCount,2);
  53. for (int iii=0;iii<MaxUsers;iii++)
  54. {
  55. if ((ConnUser[iii].Connected) && ((ConnUser[iii].State == 6) || (iii == User)))
  56. Send200(&MOVE_ENTITY[0], sizeof(MOVE_ENTITY), 3, iii);
  57. }
  58. ConnUser[User].move_count++;
  59. if (OldLB != NewLB)
  60. {
  61. LBObjects[OldLB].erase(ConnUser[User].Char->GUID);
  62. LBObjects[NewLB][ConnUser[User].Char->GUID] = (cWorldObject *) ConnUser[User].Char;
  63. if (OldLB == NewLB - 1) {
  64. SendLandblock(User, NewLB - 1);
  65. SendLandblock(User, NewLB - 1 - 256);
  66. SendLandblock(User, NewLB - 1 + 256);
  67. } else if (OldLB == NewLB + 1) {
  68. SendLandblock(User, NewLB + 1);
  69. SendLandblock(User, NewLB + 1 - 256);
  70. SendLandblock(User, NewLB + 1 + 256);
  71. } else if (OldLB == NewLB - 256) {
  72. SendLandblock(User, NewLB - 256 - 1);
  73. SendLandblock(User, NewLB - 256);
  74. SendLandblock(User, NewLB - 256 + 1);
  75. } else if (OldLB == NewLB + 256) {
  76. SendLandblock(User, NewLB + 256 - 1);
  77. SendLandblock(User, NewLB + 256);
  78. SendLandblock(User, NewLB + 256 + 1);
  79. //Diagonals Now
  80. } else if (OldLB == NewLB + 256 + 1) {
  81. SendLandblock(User, NewLB + 256 + 1);
  82. SendLandblock(User, NewLB + 256 + 1 - 256);
  83. SendLandblock(User, NewLB + 256 + 1 - 256 - 256 );
  84. SendLandblock(User, NewLB + 256 + 1 - 1);
  85. SendLandblock(User, NewLB + 256 + 1 - 1 - 1);
  86. } else if (OldLB == NewLB + 256 - 1) {
  87. SendLandblock(User, NewLB + 256 - 1);
  88. SendLandblock(User, NewLB + 256 - 1 - 256);
  89. SendLandblock(User, NewLB + 256 - 1 - 256 - 256 );
  90. SendLandblock(User, NewLB + 256 - 1 + 1);
  91. SendLandblock(User, NewLB + 256 - 1 + 1 + 1);
  92. } else if (OldLB == NewLB - 256 + 1) {
  93. SendLandblock(User, NewLB - 256 + 1);
  94. SendLandblock(User, NewLB - 256 + 1 + 256);
  95. SendLandblock(User, NewLB - 256 + 1 + 256 + 256 );
  96. SendLandblock(User, NewLB - 256 + 1 - 1);
  97. SendLandblock(User, NewLB - 256 + 1 - 1 - 1);
  98. } else if (OldLB == NewLB - 256 - 1) {
  99. SendLandblock(User, NewLB - 256 - 1);
  100. SendLandblock(User, NewLB - 256 - 1 + 256);
  101. SendLandblock(User, NewLB - 256 - 1 + 256 + 256 );
  102. SendLandblock(User, NewLB - 256 - 1 + 1);
  103. SendLandblock(User, NewLB - 256 - 1 + 1 + 1);
  104. } else {
  105. SendLandblock(User, NewLB);
  106. SendLandblock(User, NewLB - 1);
  107. SendLandblock(User, NewLB + 1);
  108. SendLandblock(User, NewLB - 256);
  109. SendLandblock(User, NewLB - 256 - 1);
  110. SendLandblock(User, NewLB - 256 + 1);
  111. SendLandblock(User, NewLB + 256);
  112. SendLandblock(User, NewLB + 256 - 1);
  113. SendLandblock(User, NewLB + 256 + 1);
  114. }
  115. }
  116. }
  117. void cACServer::SendAnim(int User, WORD AnimNum, float PlaySpeed)
  118. {
  119. ConnUser[User].AnimCount++;
  120. cAnimStruct ASt;
  121. ASt.dwf74c = 0x0000F74C;
  122. ASt.dwGUID = ConnUser[User].Char->GUID;
  123. ASt.wNumLogins = ConnUser[User].Char->NumLogins;
  124. ASt.wNumInteractions = ConnUser[User].move_count;
  125. ASt.wNumAnimations = ConnUser[User].AnimCount;
  126. ASt.wFlag = 0;
  127. ASt.wUnk1 = 0;
  128. ASt.wAnimation_Family = 0x3D;
  129. ASt.wUnk2 = 0x80;
  130. ASt.wUnk3 = 0;
  131. ASt.wAnimation_Seqnum = ConnUser[User].AnimCount;
  132. ASt.wAnimation_to_Play = (WORD) AnimNum;
  133. ASt.fPlaySpeed = PlaySpeed;
  134. ConnUser[User].move_count++;
  135. for (int i=0;i<MaxUsers;i++)
  136. {
  137. if (ConnUser[i].Connected)
  138. Send200((BYTE *) &ASt, sizeof(ASt), 3, i);
  139. }
  140. }
  141. void cACServer::PointAt(int User, DWORD GUIDAt)
  142. {
  143. ConnUser[User].AnimCount++;
  144. cAnimStructEx ASt;
  145. ASt.dwf74c = 0x0000F74C;
  146. ASt.dwGUID = ConnUser[User].Char->GUID;
  147. ASt.wNumLogins = ConnUser[User].Char->NumLogins;
  148. ASt.wNumInteractions = ConnUser[User].move_count;
  149. ASt.wNumAnimations = ConnUser[User].AnimCount;
  150. ASt.wFlag = 0;
  151. ASt.wUnk1 = 0;
  152. ASt.wAnimation_Family = 0x3D;
  153. ASt.dwf74c = 0x0000F74C;
  154. ASt.dwGUID = ConnUser[User].Char->GUID;
  155. ASt.wNumLogins = ConnUser[User].Char->NumLogins;
  156. ASt.wNumInteractions = ConnUser[User].move_count;
  157. ASt.wNumAnimations = ConnUser[User].AnimCount;
  158. ASt.wFlag = 0;
  159. ASt.wUnk1 = 0x0008;
  160. ASt.wAnimation_Family = 0x3D;
  161. ASt.GUIDTarget = GUIDAt;
  162. ASt.dwUnk1 = 0x429DB3C7;
  163. ASt.dwUnk2 = 0x0155EE0F;
  164. ASt.fUnk1 = 1.0f;
  165. ASt.Zero = 0;
  166. ConnUser[User].move_count++;
  167. for (int i=0;i<MaxUsers;i++)
  168. {
  169. if (ConnUser[i].Connected)
  170. Send200((BYTE *) &ASt, sizeof(ASt), 3, i);
  171. }
  172. }
  173. void cACServer::SendParticle(int User, DWORD ParticleNum, float PlaySpeed)
  174. {
  175. DWORD ParticleEffect[] = {
  176. 0xF755,
  177. ConnUser[User].Char->GUID,
  178. ParticleNum,
  179. 0
  180. };
  181. memcpy(&ParticleEffect[3],&PlaySpeed,4);
  182. ConnUser[User].move_count++;
  183. for (int i=0;i<MaxUsers;i++)
  184. {
  185. if (ConnUser[i].Connected)
  186. Send200((BYTE *) &ParticleEffect, sizeof(ParticleEffect), 3, i);
  187. }
  188. }
  189. void cACServer::SendSound(int User, DWORD SoundNum, float PlaySpeed)
  190. {
  191. DWORD SoundEffect[] = {
  192. 0xF750,
  193. ConnUser[User].Char->GUID,
  194. SoundNum,
  195. 0
  196. };
  197. memcpy(&SoundEffect[3],&PlaySpeed,4);
  198. ConnUser[User].move_count++;
  199. for (int i=0;i<MaxUsers;i++)
  200. {
  201. if (ConnUser[i].Connected)
  202. Send200((BYTE *) &SoundEffect, sizeof(SoundEffect), 3, i);
  203. }
  204. }
  205. void cACServer::GiveXP(int User, int Type, DWORD Amount)
  206. {
  207. BYTE Pack237[0xD];
  208. DWORD tpdword; BYTE tpbyte;
  209. if ((User > 128) || (!ConnUser[User].Connected) || (ConnUser[User].State != 6))
  210. {
  211. ServerMessage(User, "Error in !givexp format... Make sure you're giving a valid User #...", COLOR_RED);
  212. return;
  213. }
  214. DWORD OldXP = ConnUser[User].Char->TotalXP;
  215. ConnUser[User].Char->TotalXP += Amount;
  216. if (ConnUser[User].Char->TotalXP < OldXP)
  217. ConnUser[User].Char->TotalXP = LevelArray[126] + 5000;
  218. if (ConnUser[User].Char->TotalXP > LevelArray[126])
  219. ConnUser[User].Char->TotalXP = LevelArray[126] + 5000;
  220. ZeroMemory(Pack237, 0xD);
  221. tpdword = 0x237; memcpy(&Pack237[0], &tpdword, 4);
  222. tpbyte = ConnUser[User].Count237[0x15]; memcpy(&Pack237[4], &tpbyte, 1);
  223. tpdword = 0x15; memcpy(&Pack237[5], &tpdword, 4); //Total XP
  224. tpdword = ConnUser[User].Char->TotalXP; memcpy(&Pack237[9], &tpdword, 4);
  225. Send200(Pack237, sizeof(Pack237), 4, User);
  226. ConnUser[User].Count237[0x15]++;
  227. int NewLevel = 0;
  228. for (int i=ConnUser[User].Char->Level;i<128;i++)
  229. {
  230. if (ConnUser[User].Char->TotalXP < LevelArray[i])
  231. {
  232. NewLevel = i - 1;
  233. i = 128;
  234. }
  235. }
  236. if (NewLevel == 0)
  237. NewLevel = 126;
  238. bool LL = false;
  239. if (NewLevel > ConnUser[User].Char->Level)
  240. {
  241. //Level him!
  242. SendParticle(User, 0x89, 1.0f);
  243. //Give skill credits as appropriate...
  244. for (i=ConnUser[User].Char->Level+1;i<=NewLevel;i++)
  245. {
  246. for (int h=0;h<=sizeof(CreditLevel)/4;h++)
  247. if (CreditLevel[h] == i)
  248. ConnUser[User].Char->SkillCredits++;
  249. }
  250. ConnUser[User].Char->Level = NewLevel;
  251. ZeroMemory(Pack237, 0xD);
  252. tpdword = 0x237; memcpy(&Pack237[0], &tpdword, 4);
  253. tpbyte = ConnUser[User].Count237[0x19]; memcpy(&Pack237[4], &tpbyte, 1);
  254. tpdword = 0x19; memcpy(&Pack237[5], &tpdword, 4); //Level
  255. tpdword = ConnUser[User].Char->Level; memcpy(&Pack237[9], &tpdword, 4);
  256. Send200(Pack237, sizeof(Pack237), 4, User);
  257. ConnUser[User].Count237[0x19]++;
  258. ZeroMemory(Pack237, 0xD);
  259. tpdword = 0x237; memcpy(&Pack237[0], &tpdword, 4);
  260. tpbyte = ConnUser[User].Count237[0x18]; memcpy(&Pack237[4], &tpbyte, 1);
  261. tpdword = 0x18; memcpy(&Pack237[5], &tpdword, 4); //Credits
  262. tpdword = ConnUser[User].Char->SkillCredits; memcpy(&Pack237[9], &tpdword, 4);
  263. Send200(Pack237, sizeof(Pack237), 4, User);
  264. ConnUser[User].Count237[0x18]++;
  265. LL = true;
  266. }
  267. if ((Type < 0) || ((Type > 39) && (Type != 128)))
  268. {
  269. ServerMessage(User, "Error in !givexp format... Type should be from 0-39 or 128 for unassigned XP...", COLOR_RED);
  270. return;
  271. }
  272. if (Type == SKILL_UNASSIGNED)
  273. {
  274. ConnUser[User].Char->UnassignedXP += Amount;
  275. ZeroMemory(Pack237, 0xD);
  276. tpdword = 0x237; memcpy(&Pack237[0], &tpdword, 4);
  277. tpbyte = ConnUser[User].Count237[0x16]; memcpy(&Pack237[4], &tpbyte, 1);
  278. tpdword = 0x16; memcpy(&Pack237[5], &tpdword, 4); //Unassigned XP
  279. tpdword = ConnUser[User].Char->UnassignedXP; memcpy(&Pack237[9], &tpdword, 4);
  280. Send200(Pack237, sizeof(Pack237), 4, User);
  281. ConnUser[User].Count237[0x16]++;
  282. } else if (Type < 40) {
  283. //Differetiate between train/spec eventually
  284. ConnUser[User].Char->SkillXP[Type] += Amount;
  285. int NewSkillLevel = 0;
  286. for (int i=0;i<200;i++)
  287. {
  288. if (ConnUser[User].Char->SkillXP[Type] < TrainedSkillArray[i])
  289. {
  290. NewSkillLevel = i - 1;
  291. i = 200;
  292. }
  293. }
  294. if (NewSkillLevel > ConnUser[User].Char->SkillInc[Type])
  295. {
  296. ConnUser[User].Char->SkillInc[Type] = NewSkillLevel;
  297. }
  298. //Send skill xp packet
  299. }
  300. if (!LL)
  301. return;
  302. sprintf(sayit, "You are now level %i!", ConnUser[User].Char->Level);
  303. ServerMessage(User, sayit, COLOR_CYAN);
  304. char mults[2] = { 's', 0 };
  305. if (ConnUser[User].Char->SkillCredits == 1)
  306. mults[0] = 0;
  307. sprintf(sayit, "You have %u experience points and %i skill credit%s available to raise skills and attributes.", ConnUser[User].Char->UnassignedXP, ConnUser[User].Char->SkillCredits, mults);
  308. ServerMessage(User, sayit, COLOR_CYAN);
  309. int NextCredit = 0;
  310. i = 0;
  311. while (!NextCredit)
  312. {
  313. if (ConnUser[User].Char->Level < CreditLevel[i])
  314. NextCredit = CreditLevel[i];
  315. i++;
  316. }
  317. if (NextCredit == 666)
  318. {
  319. sprintf(sayit, "Sorry, you will never earn another skill credit with levels...");
  320. } else {
  321. sprintf(sayit, "You will earn another skill credit at level %i.", NextCredit);
  322. }
  323. ServerMessage(User, sayit, COLOR_CYAN);
  324. }
  325. void cACServer::RemoveItem(DWORD GUID)
  326. {
  327. DWORD F747[] = {
  328. 0x0000F747,
  329. GUID,
  330. 0x5
  331. };
  332. for (int i=0;i<MaxUsers;i++)
  333. {
  334. if ((ConnUser[i].Connected) && (ConnUser[i].State == 6)) {
  335. Send200((BYTE *) F747, sizeof(F747), 3, i);
  336. }
  337. }
  338. }
  339. void cACServer::EvalObject(int User, DWORD GUID)
  340. {
  341. cWorldObject *cwoItem = ObjectList[GUID];
  342. if (!cwoItem)
  343. return;
  344. BYTE OutPack[0x500];
  345. BYTE *PackPointer = OutPack;
  346. DWORD tpd;// WORD tpw;
  347. //F7b0 header
  348. tpd = 0xF7B0; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  349. memcpy(PackPointer, &ConnUser[User].Char->GUID, 4); PackPointer += 4;
  350. memcpy(PackPointer, &ConnUser[User].EventCount, 4); PackPointer += 4;
  351. tpd = 0x00C9; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //C9 = Identify Object
  352. ConnUser[User].EventCount++;
  353. memcpy(PackPointer, &GUID, 4); PackPointer += 4;
  354. //Figure out Flags...
  355. switch (cwoItem->Type)
  356. {
  357. case OBJECT_CHARACTER:
  358. tpd = 0x00000080; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //Flags - Char/Monster
  359. break;
  360. case OBJECT_PORTAL:
  361. tpd = 0x00200000; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //Flags - Portal
  362. break;
  363. }
  364. tpd = 0x0001; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //Successful Assess
  365. //Build Packet
  366. if (cwoItem->Type == OBJECT_CHARACTER)
  367. {
  368. tpd = 0x0000000C; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //characterFlags
  369. memcpy(PackPointer, &ConnUser[User].Char->Level, 4); PackPointer += 4;
  370. memcpy(PackPointer, &ConnUser[User].Char->CurrentSecondaryStat[0], 4); PackPointer += 4;
  371. memcpy(PackPointer, &ConnUser[User].Char->BaseSecondaryStat[0], 4); PackPointer += 4;
  372. memcpy(PackPointer, &ConnUser[User].Char->CurrentStat[0], 4); PackPointer += 4;
  373. memcpy(PackPointer, &ConnUser[User].Char->CurrentStat[1], 4); PackPointer += 4;
  374. memcpy(PackPointer, &ConnUser[User].Char->CurrentStat[3], 4); PackPointer += 4;
  375. memcpy(PackPointer, &ConnUser[User].Char->CurrentStat[2], 4); PackPointer += 4;
  376. memcpy(PackPointer, &ConnUser[User].Char->CurrentStat[4], 4); PackPointer += 4;
  377. memcpy(PackPointer, &ConnUser[User].Char->CurrentStat[5], 4); PackPointer += 4;
  378. memcpy(PackPointer, &ConnUser[User].Char->CurrentSecondaryStat[1], 4); PackPointer += 4;
  379. memcpy(PackPointer, &ConnUser[User].Char->BaseSecondaryStat[1], 4); PackPointer += 4;
  380. memcpy(PackPointer, &ConnUser[User].Char->CurrentSecondaryStat[2], 4); PackPointer += 4;
  381. memcpy(PackPointer, &ConnUser[User].Char->BaseSecondaryStat[2], 4); PackPointer += 4;
  382. tpd = 0; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //Species
  383. }
  384. else if (cwoItem->Type == OBJECT_PORTAL)
  385. {
  386. cWorldObject_Portal *tpp = (cWorldObject_Portal *) cwoItem;
  387. DWORD Lower, Upper;
  388. Lower = (tpp->Flags & 0x00FF0000) >> 16;
  389. if (!Lower) Lower = 0xFFFFFFFF;
  390. Upper = (tpp->Flags & 0xFF000000) >> 24;
  391. if (!Upper) Upper = 0xFFFFFFFF;
  392. memcpy(PackPointer, &Lower, 4); PackPointer += 4; //Lower Limit
  393. memcpy(PackPointer, &Upper, 4); PackPointer += 4; //Upper Limit
  394. int packlen;
  395. GenString(tpp->Name, &packlen, PackPointer); PackPointer += packlen;
  396. }
  397. Send200(OutPack, (DWORD) PackPointer - (DWORD) OutPack, 4, User);
  398. ActionComplete(User);
  399. }
  400. void cACServer::ServerMessage(int User, char *Text, DWORD Color)
  401. {
  402. try {
  403. BYTE TpMes[1024]; BYTE * PackPtr = &TpMes[0];
  404. DWORD tpf;
  405. int outlen;
  406. tpf = 0x0000F62C; memcpy(PackPtr,&tpf,4); PackPtr += 4;
  407. GenString(Text, &outlen, PackPtr); PackPtr += outlen;
  408. tpf = Color; memcpy(PackPtr,&tpf,4); PackPtr += 4;
  409. if ((User >= 0) && (User < 128))
  410. {
  411. Send200(&TpMes[0], (int) (PackPtr - &TpMes[0]), 4, User);
  412. } else if (User == GLOBAL_MESSAGE) {
  413. //Global Message...
  414. for (int i=0;i<MaxUsers;i++)
  415. {
  416. if ((ConnUser[i].Connected) && (ConnUser[i].State >= 5))
  417. Send200(&TpMes[0], (int) (PackPtr - &TpMes[0]), 4, i);
  418. }
  419. } else if ((User > -128) && (User < 0)) {
  420. //Global Message except User
  421. for (int i=0;i<MaxUsers;i++)
  422. {
  423. if ((ConnUser[i].Connected) && (ConnUser[i].State >= 5) && (i != (User*-1)-1))
  424. Send200(&TpMes[0], (int) (PackPtr - &TpMes[0]), 4, i);
  425. }
  426. }
  427. } catch (char * ) {
  428. //Meh...
  429. }
  430. }
  431. void cACServer::UpdateSkill(int User, int Skill)
  432. {
  433. //Skill update - send 23E
  434. BYTE Pack23E[40]; WORD tpw = Skill; DWORD tpdword; BYTE tpbyte;
  435. tpdword = 0x023E; memcpy(&Pack23E[0], &tpdword, 4);
  436. memcpy(&Pack23E[4], &tpw, 2);
  437. tpbyte = 0; memcpy(&Pack23E[6], &tpbyte, 1);
  438. tpbyte = ConnUser[User].Count23E; memcpy(&Pack23E[7], &tpbyte, 1);
  439. memcpy(&Pack23E[8], &ConnUser[User].Char->SkillInc[Skill], 4);
  440. memcpy(&Pack23E[12], &ConnUser[User].Char->SkillTrain[Skill], 4);
  441. memcpy(&Pack23E[16], &ConnUser[User].Char->SkillXP[Skill], 4);
  442. memcpy(&Pack23E[20], &ConnUser[User].Char->SkillFreeXP[Skill], 4);
  443. tpdword = 0; memcpy(&Pack23E[24], &tpdword, 4);
  444. DWORD TPT23EShit[3] = {
  445. 0xE34B9579,
  446. 0x4175FD72,
  447. 0x003AF0F8
  448. };
  449. memcpy(&Pack23E[28], TPT23EShit, 12);
  450. Send200(Pack23E, 40, 4, User);
  451. ConnUser[User].Count23E++;
  452. ConnUser[User].Char->SkillBase[Skill] = 0;
  453. if (SkillInfo[Skill].AttribA != STAT_NULL) ConnUser[User].Char->SkillBase[Skill] += ConnUser[User].Char->CurrentStat[SkillInfo[Skill].AttribA];
  454. if (SkillInfo[Skill].AttribB != STAT_NULL) ConnUser[User].Char->SkillBase[Skill] += ConnUser[User].Char->CurrentStat[SkillInfo[Skill].AttribB];
  455. ConnUser[User].Char->SkillBase[Skill] /= SkillInfo[Skill].Divider;
  456. ConnUser[User].Char->SkillBase[Skill] += ConnUser[User].Char->SkillInc[Skill];
  457. }
  458. void cACServer::UpdateStat(int User, int Stat)
  459. {
  460. //Stat update - send 241
  461. BYTE Pack241[20]; WORD tpw = Stat+1; DWORD tpdword; BYTE tpbyte;
  462. if (tpw == 3) tpw = 4;
  463. else if (tpw == 4) tpw = 3;
  464. tpdword = 0x0241; memcpy(&Pack241[0], &tpdword, 4);
  465. memcpy(&Pack241[4], &tpw, 2);
  466. tpbyte = 0; memcpy(&Pack241[6], &tpbyte, 1);
  467. tpbyte = ConnUser[User].Count23E; memcpy(&Pack241[7], &tpbyte, 1);
  468. memcpy(&Pack241[8], &ConnUser[User].Char->CurrentStat[Stat], 4);
  469. memcpy(&Pack241[12], &ConnUser[User].Char->InitialStat[Stat], 4);
  470. memcpy(&Pack241[16], &ConnUser[User].Char->XPIntoStat[Stat], 4);
  471. Send200(Pack241, 20, 4, User);
  472. ConnUser[User].Count23E++;
  473. for (int Skill=1;Skill<40;Skill++)
  474. {
  475. ConnUser[User].Char->SkillBase[Skill] = 0;
  476. if (SkillInfo[Skill].AttribA != STAT_NULL) ConnUser[User].Char->SkillBase[Skill] += ConnUser[User].Char->CurrentStat[SkillInfo[Skill].AttribA];
  477. if (SkillInfo[Skill].AttribB != STAT_NULL) ConnUser[User].Char->SkillBase[Skill] += ConnUser[User].Char->CurrentStat[SkillInfo[Skill].AttribB];
  478. ConnUser[User].Char->SkillBase[Skill] /= SkillInfo[Skill].Divider;
  479. ConnUser[User].Char->SkillBase[Skill] += ConnUser[User].Char->SkillInc[Skill];
  480. }
  481. }
  482. void cACServer::UpdateSecondaryStat(int User, int Stat)
  483. {
  484. if (Stat == 0) ConnUser[User].Char->BaseSecondaryStat[Stat] = ConnUser[User].Char->SecondaryStatInc[Stat] + (ConnUser[User].Char->CurrentStat[1] >> 1);
  485. if (Stat == 1) ConnUser[User].Char->BaseSecondaryStat[Stat] = ConnUser[User].Char->SecondaryStatInc[Stat] + ConnUser[User].Char->CurrentStat[1];
  486. if (Stat == 2) ConnUser[User].Char->BaseSecondaryStat[Stat] = ConnUser[User].Char->SecondaryStatInc[Stat] + ConnUser[User].Char->CurrentStat[5];
  487. //Secondary Stat update - send 243
  488. BYTE Pack243[24]; WORD tpw = 1+(Stat<<1); DWORD tpdword; BYTE tpbyte;
  489. tpdword = 0x0243; memcpy(&Pack243[0], &tpdword, 4);
  490. memcpy(&Pack243[4], &tpw, 2);
  491. tpbyte = 0; memcpy(&Pack243[6], &tpbyte, 1);
  492. tpbyte = ConnUser[User].Count23E; memcpy(&Pack243[7], &tpbyte, 1);
  493. memcpy(&Pack243[8], &ConnUser[User].Char->SecondaryStatInc[Stat], 4);
  494. tpdword = 0; memcpy(&Pack243[12], &tpdword, 4);
  495. memcpy(&Pack243[16], &ConnUser[User].Char->XPIntoSecondaryStat[Stat], 4);
  496. memcpy(&Pack243[20], &ConnUser[User].Char->BaseSecondaryStat[Stat], 4);
  497. Send200(Pack243, 24, 4, User);
  498. ConnUser[User].Count23E++;
  499. }
  500. int cACServer::Generate_F7B0_13(BYTE * OutPack, int User)
  501. {
  502. BYTE *PackPointer = OutPack;
  503. DWORD tpd; WORD tpw;
  504. //F7b0 header
  505. tpd = 0xF7B0; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  506. memcpy(PackPointer, &ConnUser[User].Char->GUID, 4); PackPointer += 4;
  507. memcpy(PackPointer, &ConnUser[User].EventCount, 4); PackPointer += 4;
  508. tpd = 0x0013; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //13 = Login Char
  509. ConnUser[User].EventCount++;
  510. //On the the actual packet... - loginmask1 - 7B in the stuff...
  511. tpd = 0x001B; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //loginMask1
  512. tpd = 0x000A; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //unknown1 - A
  513. //count1
  514. tpw = 0x000C; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //count for next section
  515. tpw = 0x0040; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //unknown for this - 40
  516. tpd = 0x0081; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  517. tpd = 0x02F7; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  518. tpd = 0x0084; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  519. tpd = 0x0004; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  520. //Burden, calc later..
  521. tpd = 0x0005; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //5 = burden
  522. tpd = 1; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //1 = ?
  523. tpd = 0x008B; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  524. tpd = 0x0037; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  525. //Pyreals, calc later
  526. tpd = 0x0014; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //14 = pyreals
  527. tpd = 0; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //0
  528. //Total Xp
  529. tpd = 0x0015; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //15 = total xp
  530. memcpy(PackPointer, &ConnUser[User].Char->TotalXP, 4); PackPointer += 4;
  531. //Unassigned XP
  532. tpd = 0x0016; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //16 = unassigned xp
  533. memcpy(PackPointer, &ConnUser[User].Char->UnassignedXP, 4); PackPointer += 4;
  534. //Unassigned Skill Points
  535. tpd = 0x0018; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //18 = unassigned skill points
  536. memcpy(PackPointer, &ConnUser[User].Char->SkillCredits, 4); PackPointer += 4;
  537. //Level, calc later....
  538. tpd = 0x0019; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //19 = Level
  539. memcpy(PackPointer, &ConnUser[User].Char->Level, 4); PackPointer += 4;
  540. //Rank, calc later
  541. tpd = 0x001e; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //1e = Rank
  542. tpd = 0x0000; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  543. tpd = 0x0028; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  544. tpd = 0x0001; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  545. tpd = 0x002F; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  546. tpd = 0x0000; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  547. //end of that vector
  548. //count2
  549. tpw = 0x0005; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //count2
  550. tpw = 0x0020; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //unknown - 20
  551. //count2 vector here... i.e. nothing yet
  552. //Count2 Stuff...
  553. DWORD CHAR_DATA_VECTOR2[] = {
  554. 0x00000004, 0x00000000, 0x0000002C, 0x00000000,
  555. 0x0000002D, 0x00000000, 0x0000002E, 0x00000000,
  556. 0x0000002F, 0x00000000,
  557. };
  558. memcpy(PackPointer, CHAR_DATA_VECTOR2, sizeof(CHAR_DATA_VECTOR2)); PackPointer += sizeof(CHAR_DATA_VECTOR2);
  559. //strings
  560. tpw = 0x0004; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //stringcount
  561. tpw = 0x0010; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //strings unknown - 10
  562. //Char Name
  563. tpd = 0x0001; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  564. GenString(ConnUser[User].Char->Name, (int *) &tpd, PackPointer); PackPointer += tpd;
  565. //Gender
  566. tpd = 0x0003; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  567. char Gender[7];
  568. if (ConnUser[User].Char->Gender == 0)
  569. sprintf(Gender, "Female");
  570. // if (ConnUser[User].Char->Gender == 1)
  571. else
  572. sprintf(Gender, "Male");
  573. GenString(Gender, (int *) &tpd, PackPointer); PackPointer += tpd;
  574. //Race
  575. char Race[12];
  576. tpd = 0x0004; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  577. if (ConnUser[User].Char->Race == 0)
  578. sprintf(Race, "Aluvian");
  579. if (ConnUser[User].Char->Race == 1)
  580. sprintf(Race, "Gharun'Dim");
  581. // if (ConnUser[User].Char->Race == 2)
  582. else
  583. sprintf(Race, "Sho");
  584. GenString(Race, (int *) &tpd, PackPointer); PackPointer += tpd;
  585. //Class - "Server Tester" for now... ;-)
  586. tpd = 0x0005; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  587. GenString(ConnUser[User].Char->Title, (int *) &tpd, PackPointer); PackPointer += tpd;
  588. //count4
  589. tpw = 0x0001; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //count4
  590. tpw = 0x0020; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //count4unknown - 20
  591. //count4 vector here... i.e. nothing yet
  592. //sec4 stuff
  593. tpd = 0x0004; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //
  594. tpd = 0x30000000; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //
  595. //Loginmask1 info goes here
  596. //End loginmask1 shit
  597. //should be 103, 100 = spellbook, 2 = skills
  598. tpd = 0x0103; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //Loginmask2
  599. tpd = 0x0001; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //unknown14 - always 1
  600. tpd = 0x01ff; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //attributemask - always 0x1ff
  601. //Primary Stats
  602. for (int i=0;i<6;i++)
  603. {
  604. if (i == 3)
  605. {
  606. memcpy(PackPointer, &ConnUser[User].Char->CurrentStat[2], 4); PackPointer += 4;
  607. memcpy(PackPointer, &ConnUser[User].Char->InitialStat[2], 4); PackPointer += 4;
  608. memcpy(PackPointer, &ConnUser[User].Char->XPIntoStat[2], 4); PackPointer += 4;
  609. } else if (i == 2) {
  610. memcpy(PackPointer, &ConnUser[User].Char->CurrentStat[3], 4); PackPointer += 4;
  611. memcpy(PackPointer, &ConnUser[User].Char->InitialStat[3], 4); PackPointer += 4;
  612. memcpy(PackPointer, &ConnUser[User].Char->XPIntoStat[3], 4); PackPointer += 4;
  613. } else {
  614. memcpy(PackPointer, &ConnUser[User].Char->CurrentStat[i], 4); PackPointer += 4;
  615. memcpy(PackPointer, &ConnUser[User].Char->InitialStat[i], 4); PackPointer += 4;
  616. memcpy(PackPointer, &ConnUser[User].Char->XPIntoStat[i], 4); PackPointer += 4;
  617. }
  618. }
  619. //Secondary Stats
  620. for (i=0;i<3;i++)
  621. {
  622. memcpy(PackPointer, &ConnUser[User].Char->SecondaryStatInc[i], 4); PackPointer += 4;
  623. tpd = 0; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //?... always 0 afawct
  624. memcpy(PackPointer, &ConnUser[User].Char->XPIntoSecondaryStat[i], 4); PackPointer += 4;
  625. memcpy(PackPointer, &ConnUser[User].Char->CurrentSecondaryStat[i], 4); PackPointer += 4;
  626. }
  627. //Skillcount
  628. tpw = 0x0023; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //count
  629. tpw = 0x0020; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //unknown - 20
  630. for (i=1;i<40;i++)
  631. {
  632. if (ConnUser[User].Char->SkillTrain[i] > 0)
  633. {
  634. memcpy(PackPointer, &i, 4); PackPointer += 4; //Skill number
  635. memcpy(PackPointer, &ConnUser[User].Char->SkillInc[i], 4); PackPointer += 4; //Skill number
  636. memcpy(PackPointer, &ConnUser[User].Char->SkillTrain[i], 4); PackPointer += 4; //Trained Status
  637. memcpy(PackPointer, &ConnUser[User].Char->SkillXP[i], 4); PackPointer += 4; //Total XP into skill
  638. memcpy(PackPointer, &ConnUser[User].Char->SkillFreeXP[i], 4); PackPointer += 4; //Free XP at gen
  639. tpd = 0x0000; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //unknown2
  640. //double thingy
  641. tpd = 0xE5C9D958; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  642. tpd = 0x4171BA45; memcpy(PackPointer, &tpd, 4); PackPointer += 4;
  643. }
  644. }
  645. //Loginmask2 time
  646. //100 - spellbook
  647. WORD numspells = 0;
  648. for (i=0;i<96;i++)
  649. {
  650. for (DWORD tpdd=ConnUser[User].Char->SpellsLearned[i];tpdd > 0;tpdd >>= 1)
  651. {
  652. if (tpdd & 1)
  653. numspells++;
  654. }
  655. }
  656. memcpy(PackPointer, &numspells, 2); PackPointer += 2; //count
  657. tpw = 0x0040; memcpy(PackPointer, &tpw, 2); PackPointer += 2; //spellcountunknown
  658. int tpinc; float tpcharge = 1.0f;
  659. for (i=0;i<96;i++)
  660. {
  661. tpinc = 0;
  662. for (DWORD TpSpell = ConnUser[User].Char->SpellsLearned[i]; TpSpell > 0; TpSpell >>= 1)
  663. {
  664. if (TpSpell & 1)
  665. {
  666. tpd = (i << 5) | tpinc; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //spell ID
  667. memcpy(PackPointer, &tpcharge, 4); PackPointer += 4; //charge
  668. tpd = 0; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //unknown2
  669. tpd = 0; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //unknown3
  670. }
  671. tpinc++;
  672. }
  673. }
  674. //200 - enchantments... whoooa there cowboy
  675. DWORD Numshorts = 0;
  676. for (i=0;i<10;i++)
  677. if (ConnUser[User].Char->ShortCut[i])
  678. Numshorts++;
  679. if (Numshorts)
  680. tpd = 0x0005;
  681. else
  682. tpd = 0x0004;
  683. memcpy(PackPointer, &tpd, 4); PackPointer += 4; //loginmask3
  684. //4, character options
  685. // tpd = 0x01ECE563; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //loginmask3
  686. tpd = 0x01E4E56A; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //loginmask3
  687. if (Numshorts)
  688. {
  689. //1, shortcut bar
  690. memcpy(PackPointer, &Numshorts, 4); PackPointer += 4;
  691. for (i=0;i<10;i++)
  692. if (ConnUser[User].Char->ShortCut[i])
  693. {
  694. memcpy(PackPointer, &i, 4); PackPointer += 4; //Position
  695. memcpy(PackPointer, &ConnUser[User].Char->ShortCut[i], 4); PackPointer += 4; //Object
  696. tpd = 0; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //Unknown - 0
  697. }
  698. }
  699. //Spellbars
  700. for (i=0;i<5;i++)
  701. {
  702. DWORD numspells = 0;
  703. for (numspells=0;ConnUser[User].Char->SpellBar[i][numspells] > 0;numspells++) { }
  704. memcpy(PackPointer, &numspells, 4); PackPointer += 4;
  705. for (int j=0;j<numspells;j++)
  706. {
  707. memcpy(PackPointer, &ConnUser[User].Char->SpellBar[i][j], 4); PackPointer += 4;
  708. }
  709. }
  710. //comp buyer...
  711. //Inventory
  712. DWORD numinv = 0;
  713. for (i=0;i<7;i++)
  714. if (ConnUser[User].Char->SidePacks[i])
  715. numinv++;
  716. for (i=0;i<102;i++)
  717. if (ConnUser[User].Char->MainPack[i])
  718. numinv++;
  719. memcpy(PackPointer, &numinv, 4); PackPointer += 4;
  720. for (i=0;i<7;i++)
  721. if (ConnUser[User].Char->SidePacks[i])
  722. {
  723. memcpy(PackPointer, &ConnUser[User].Char->SidePacks[i], 4); PackPointer += 4;
  724. tpd = 1; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //IsContainer = 1
  725. }
  726. for (i=0;i<102;i++)
  727. if (ConnUser[User].Char->MainPack[i])
  728. {
  729. memcpy(PackPointer, &ConnUser[User].Char->MainPack[i], 4); PackPointer += 4;
  730. tpd = 0; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //IsContainer = 0
  731. }
  732. //Equipped Shizzit
  733. DWORD numequip = 0;
  734. for (i=0;i<25;i++)
  735. if (ConnUser[User].Char->Equipped[i])
  736. numequip++;
  737. memcpy(PackPointer, &numequip, 4); PackPointer += 4;
  738. for (i=0;i<25;i++)
  739. if (ConnUser[User].Char->Equipped[i])
  740. {
  741. memcpy(PackPointer, &ConnUser[User].Char->Equipped[i], 4); PackPointer += 4;
  742. tpd = (1 << i); memcpy(PackPointer, &tpd, 4); PackPointer += 4; //Coverage
  743. tpd = 0; memcpy(PackPointer, &tpd, 4); PackPointer += 4; //unknown3
  744. }
  745. return((int) (PackPointer - OutPack));
  746. }