QWClientPrivate.cpp 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078
  1. /*
  2. GNU General Public License version 3 notice
  3. Copyright (C) 2012 Mihawk <luiz@netdome.biz>. All rights reserved.
  4. This program is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see < http://www.gnu.org/licenses/ >.
  14. */
  15. #include "QWClient.h"
  16. #include "QWClientPrivate.h"
  17. #include "QWPack.h"
  18. #include "QWTables.h"
  19. #include <QUdpSocket>
  20. #include <QTime>
  21. #include <QBuffer>
  22. #include <QFile>
  23. #include <QDir>
  24. #include <QRegExp>
  25. #include <QStringList>
  26. #include <QFileInfoList>
  27. #include <QHostInfo>
  28. #include <QCryptographicHash>
  29. #include <QCoreApplication>
  30. #include <QtEndian>
  31. #include <QDebug>
  32. const char* QWClientPrivate::ClientName = "libqwclient";
  33. const char* QWClientPrivate::ClientVersion = "0.1";
  34. QWClientPrivate::QWClientPrivate(QWClient* client):
  35. myClient(client),
  36. mySocket(new QUdpSocket),
  37. myTime(new QTime),
  38. myLastServerReplyTime(new QTime),
  39. myDownload(new QFile),
  40. myClientName(ClientName),
  41. myClientVersion(ClientVersion),
  42. myState(QWClient::DisconnectedState),
  43. myGameDir("qw"),
  44. myQuakeDir(QCoreApplication::applicationDirPath()),
  45. myPing(666),
  46. myRate(3000),
  47. myTopColor(0),
  48. myBottomColor(0),
  49. myName(ClientName),
  50. mySpectatorFlag(true),
  51. myTeam("lqwc")
  52. {
  53. /* Setup IO streams */
  54. myInBuffer.setBuffer(&myInData);
  55. myInStream.setDevice(&myInBuffer);
  56. myInStream.setByteOrder(QDataStream::LittleEndian);
  57. myInBuffer.open(QIODevice::ReadOnly);
  58. myUnreliableOutBuffer.setBuffer(&myUnreliableOutData);
  59. myUnreliableOutStream.setDevice(&myUnreliableOutBuffer);
  60. myUnreliableOutBuffer.open(QIODevice::WriteOnly);
  61. myUnreliableOutStream.setByteOrder(QDataStream::LittleEndian);
  62. myReliableOutBuffer.setBuffer(&myReliableOutData);
  63. myReliableOutStream.setDevice(&myReliableOutBuffer);
  64. myReliableOutBuffer.open(QIODevice::WriteOnly);
  65. myReliableOutStream.setByteOrder(QDataStream::LittleEndian);
  66. myOutBuffer.setBuffer(&myOutData);
  67. myOutStream.setDevice(&myOutBuffer);
  68. myOutBuffer.open(QIODevice::ReadWrite);
  69. myOutStream.setByteOrder(QDataStream::LittleEndian);
  70. reloadPackFiles();
  71. }
  72. void QWClientPrivate::setPing(quint16 ping)
  73. {
  74. myPing = qBound<quint16>(13, ping, 999);
  75. }
  76. void QWClientPrivate::reconnect()
  77. {
  78. disconnect();
  79. connect(myHost.toString().toLatin1().data(), myPort);
  80. }
  81. void QWClientPrivate::setRate(quint16 rate)
  82. {
  83. myRate = qBound<quint16>(2500, rate, 30000);
  84. if(myState != QWClient::ConnectedState)
  85. return;
  86. sendCmd("setinfo \"rate\" \"" + QString::number(rate) + "\"");
  87. }
  88. void QWClientPrivate::setSpectator(bool spectate)
  89. {
  90. if(myState == QWClient::ConnectedState)
  91. {
  92. if(spectate && !mySpectatorFlag)
  93. observe();
  94. else if(!spectate && mySpectatorFlag)
  95. join();
  96. return;
  97. }
  98. mySpectatorFlag = spectate;
  99. }
  100. void QWClientPrivate::setPassword(const QString &password)
  101. {
  102. myPassword = password;
  103. }
  104. void QWClientPrivate::setQuakeFolder(const QString &path)
  105. {
  106. myQuakeDir = path;
  107. QDir dir(myQuakeDir);
  108. dir.mkpath(myGameDir);
  109. reloadPackFiles();
  110. }
  111. void QWClientPrivate::join()
  112. {
  113. mySpectatorFlag = false;
  114. if(myState != QWClient::ConnectedState)
  115. return;
  116. writeByte(&myReliableOutStream, clc_stringcmd);
  117. writeString(&myReliableOutStream, "setinfo \"spectator\" \"\"");
  118. writeByte(&myReliableOutStream, clc_stringcmd);
  119. writeString(&myReliableOutStream, "join");
  120. }
  121. void QWClientPrivate::observe()
  122. {
  123. mySpectatorFlag = true;
  124. if(myState != QWClient::ConnectedState)
  125. return;
  126. writeByte(&myReliableOutStream, clc_stringcmd);
  127. writeString(&myReliableOutStream, "setinfo \"spectator\" \"" + QString::number(mySpectatorFlag) + "\"");
  128. writeByte(&myReliableOutStream, clc_stringcmd);
  129. writeString(&myReliableOutStream, "observe");
  130. }
  131. const QString& QWClientPrivate::gameDir() const
  132. {
  133. return myGameDir;
  134. }
  135. const QString& QWClientPrivate::quakeDir() const
  136. {
  137. return myQuakeDir;
  138. }
  139. void QWClientPrivate::setColor(quint8 bottom, quint8 top)
  140. {
  141. myBottomColor = bottom;
  142. myTopColor = top;
  143. if(myState != QWClient::ConnectedState)
  144. return;
  145. writeByte(&myReliableOutStream, clc_stringcmd);
  146. writeString(&myReliableOutStream, "setinfo \"bottomcolor\" \"" + QString::number(myBottomColor) + "\"");
  147. writeByte(&myReliableOutStream, clc_stringcmd);
  148. writeString(&myReliableOutStream, "setinfo \"topcolor\" \"" + QString::number(myTopColor) + "\"");
  149. }
  150. void QWClientPrivate::setName(const char *name)
  151. {
  152. myName = QString(name);
  153. if(myState == QWClient::ConnectedState)
  154. {
  155. writeByte(&myReliableOutStream, clc_stringcmd);
  156. writeString(&myReliableOutStream, "setinfo \"name\" \"" + myName + "\"");
  157. }
  158. }
  159. void QWClientPrivate::setTeam(const char *team)
  160. {
  161. myTeam = QString(team);
  162. if(myState == QWClient::ConnectedState)
  163. {
  164. writeByte(&myReliableOutStream, clc_stringcmd);
  165. writeString(&myReliableOutStream, "setinfo \"name\" \"" + myTeam + "\"");
  166. }
  167. }
  168. void QWClientPrivate::sendCmd(const QString &cmd)
  169. {
  170. if(myState != QWClient::ConnectedState)
  171. return;
  172. writeByte(&myReliableOutStream, clc_stringcmd);
  173. writeString(&myReliableOutStream, cmd);
  174. }
  175. QWClientPrivate::~QWClientPrivate()
  176. {
  177. delete myTime;
  178. delete myLastServerReplyTime;
  179. delete mySocket;
  180. delete myDownload;
  181. }
  182. static QRegExp packRegex("pak[0-9]+\\.pak", Qt::CaseInsensitive);
  183. void QWClientPrivate::reloadPackFiles()
  184. {
  185. for(int i = 0; i < myPacks.size(); ++i)
  186. delete myPacks.at(i);
  187. myPacks.clear();
  188. QDir gameDir(myQuakeDir + "/" + myGameDir);
  189. if(!gameDir.isReadable())
  190. return;
  191. QFileInfoList files = gameDir.entryInfoList(QStringList("*.pak"), QDir::Files);
  192. for(int i = 0; i < files.size(); ++i)
  193. {
  194. if(packRegex.indexIn(files.at(i).fileName()) != -1)
  195. {
  196. QWPack* pack = new QWPack();
  197. if(!pack->load(files.at(i).absoluteFilePath()))
  198. {
  199. delete pack;
  200. continue;
  201. }
  202. myPacks.push_back(pack);
  203. }
  204. }
  205. }
  206. void QWClientPrivate::run()
  207. {
  208. /* Read and parse packets sent by the server */
  209. readPackets();
  210. /* Send something to the server to keep the connection alive */
  211. sendToServer();
  212. }
  213. void QWClientPrivate::sendToServer(bool dontWait)
  214. {
  215. /* Check for resend */
  216. if(myState == QWClient::ConnectingState)
  217. {
  218. if(myTime->elapsed() >= 5000)
  219. {
  220. sendConnectionless("getchallenge\n");
  221. myClient->onChallenge();
  222. myTime->restart();
  223. }
  224. return;
  225. }
  226. /* Go full speed when connecting or downloading a new map */
  227. if(!dontWait && (myState != QWClient::ConnectedState || myDownload->isOpen() ? 12 : myPing) > myTime->elapsed())
  228. return;
  229. sendMovement(); //send some movement every frame
  230. bool sendReliable = false;
  231. if(myIncomingAck > myLastRealiableSeq && myIncomingAckReliableFlag != myOutgoingSeqReliableFlag)
  232. sendReliable = true;
  233. if(!myReliableData.size() && myReliableOutData.size())
  234. {
  235. myReliableData = myReliableOutData;
  236. myOutgoingSeqReliableFlag ^= 1;
  237. sendReliable = true;
  238. myReliableOutData.clear();
  239. myReliableOutStream.device()->seek(0);
  240. }
  241. /* Write packet header */
  242. myOutData.clear();
  243. myOutStream.device()->seek(0);
  244. myOutStream << (myOutgoingSeq | (sendReliable << 31));
  245. myOutStream << (myIncomingSeq | (myIncomingSeqReliableFlag << 31));
  246. myOutStream << myQPort;
  247. myOutgoingSeq++;
  248. /* Write reliable buffer first */
  249. if(sendReliable)
  250. {
  251. myOutData.append(myReliableData);
  252. myLastRealiableSeq = myOutgoingSeq;
  253. }
  254. /* Unreliable part afterwards */
  255. if(myOutData.size() + myUnreliableOutData.size() < MAX_MSGLEN && myUnreliableOutData.size())
  256. {
  257. myOutData.append(myUnreliableOutData);
  258. myUnreliableOutData.clear();
  259. myUnreliableOutStream.device()->seek(0);
  260. }
  261. /* Finally send the packet */
  262. mySocket->write(myOutData);
  263. mySocket->waitForBytesWritten();
  264. myOutData.clear();
  265. myOutStream.device()->seek(0);
  266. myTime->restart();
  267. }
  268. void QWClientPrivate::readPackets()
  269. {
  270. if(!mySocket->isOpen())
  271. return;
  272. if(!mySocket->hasPendingDatagrams())
  273. {
  274. if(myLastServerReplyTime->secsTo(QTime::currentTime()) >= 30)
  275. {
  276. myClient->onError("Client Timed Out.");
  277. disconnect();
  278. return;
  279. }
  280. return;
  281. }
  282. *myLastServerReplyTime = QTime::currentTime();
  283. myInData.resize(mySocket->pendingDatagramSize());
  284. // myInData = mySocket->readAll();
  285. mySocket->readDatagram(myInData.data(), mySocket->pendingDatagramSize());
  286. myInStream.device()->seek(0);
  287. quint32 seq;
  288. myInStream >> seq;
  289. if(seq == 0xffffffff)
  290. parseConnectionless();
  291. else
  292. parseServerMessage();
  293. }
  294. void QWClientPrivate::parseConnectionless()
  295. {
  296. quint8 c;
  297. c = readByte();
  298. switch(c)
  299. {
  300. case S2C_CHALLENGE:
  301. {
  302. QString challenge;
  303. QString connString;
  304. challenge = readString();
  305. connString.append("connect " + QString::number(PROTOCOL_VERSION) + " " + QString::number(myQPort) + " " + challenge);
  306. connString.append(" \"\\rate\\" + QString::number(myRate));
  307. if(!myPassword.isEmpty())
  308. connString.append("\\password\\" + myPassword);
  309. connString.append("\\msg\\1\\noaim\\1\\topcolor\\" + QString::number(myTopColor) + "\\bottomcolor\\" + QString::number(myBottomColor) + "\\w_switch\\2\\b_switch\\2\\*client\\" + myClientName);
  310. connString.append(" " + myClientVersion + "\\name\\" + myName + "\\team\\" + myTeam + "\\spectator\\" + (mySpectatorFlag ? "1" : "0") + "\\pmodel\\33168\\emodel\\6967\\*z_ext\\383\"");
  311. myInStream.device()->seek(0);
  312. sendConnectionless(connString.toLatin1());
  313. myClient->onConnection();
  314. }
  315. break;
  316. case S2C_CONNECTION:
  317. {
  318. myState = QWClient::ConnectedState;
  319. writeByte(&myReliableOutStream, clc_stringcmd);
  320. writeString(&myReliableOutStream, "new");
  321. myClient->onConnected();
  322. }
  323. break;
  324. case A2C_PRINT:
  325. myClient->onOOBPrint(readString().toLatin1().data());
  326. break;
  327. case A2C_CLIENT_COMMAND:
  328. myClient->onOOBCommand(readString().toLatin1().data());
  329. break;
  330. case A2A_PING:
  331. sendConnectionless(QString(QChar(A2A_ACK)).toLatin1());
  332. break;
  333. case A2A_ACK:
  334. // qDebug("Ack");
  335. break;
  336. case A2A_NACK:
  337. // qDebug("Nack");
  338. break;
  339. case A2A_ECHO:
  340. myClient->onOOBEcho(readString().toLatin1().data());
  341. break;
  342. }
  343. }
  344. bool QWClientPrivate::fileExists(const QString &filename)
  345. {
  346. /* Search on the gamedir first */
  347. if(QFile::exists(myQuakeDir + "/" + myGameDir + "/" + filename))
  348. return true;
  349. /* Search quake pak files next */
  350. for(int i = 0; i < myPacks.size(); ++i)
  351. {
  352. if(myPacks[i]->exists(filename))
  353. return true;
  354. }
  355. return false;
  356. }
  357. bool QWClientPrivate::readFile(const QString &filename, char **data, quint64 *len)
  358. {
  359. /* Try disk */
  360. QFile file(myQuakeDir + "/" + myGameDir + "/" + filename);
  361. *len = 0;
  362. if(file.open(QIODevice::ReadOnly))
  363. {
  364. *len = file.size();
  365. *data = new char[*len];
  366. file.read(*data, *len);
  367. return true;
  368. }
  369. /* Try packs */
  370. for(int i = 0; i < myPacks.size(); ++i)
  371. {
  372. QWPack* pack = myPacks.at(i);
  373. if(!pack->exists(filename))
  374. continue;
  375. pack->read(filename, data, len);
  376. return true;
  377. }
  378. return false;
  379. }
  380. //int bitCounts[32]; /// just for protocol profiling
  381. void QWClientPrivate::parseDelta(entityState_t *from, entityState_t *to, int bits)
  382. {
  383. int i;
  384. int morebits;
  385. // set everything to the state we are delta'ing from
  386. *to = *from;
  387. to->number = bits & 511;
  388. bits &= ~511;
  389. if(bits & U_MOREBITS)
  390. { // read in the low order bits
  391. i = readByte();
  392. bits |= i;
  393. }
  394. if(bits & U_FTE_EVENMORE && myFTEProtocolExtensions) {
  395. morebits = readByte();
  396. if (morebits & U_FTE_YETMORE)
  397. morebits |= readByte() << 8;
  398. } else {
  399. morebits = 0;
  400. }
  401. // // count the bits for net profiling
  402. // for (i=0 ; i<16 ; i++)
  403. // if (bits&(1<<i))
  404. // bitCounts[i]++;
  405. to->flags = bits;
  406. if(bits & U_MODEL)
  407. to->modelindex = readByte();
  408. if(bits & U_FRAME)
  409. to->frame = readByte();
  410. if(bits & U_COLORMAP)
  411. to->colormap = readByte();
  412. if(bits & U_SKIN)
  413. to->skinnum = readByte();
  414. if(bits & U_EFFECTS)
  415. to->effects = readByte();
  416. if(bits & U_ORIGIN1)
  417. to->origin[0] = readCoord();
  418. if(bits & U_ANGLE1)
  419. to->angles[0] = readAngle();
  420. if(bits & U_ORIGIN2)
  421. to->origin[1] = readCoord();
  422. if(bits & U_ANGLE2)
  423. to->angles[1] = readAngle();
  424. if(bits & U_ORIGIN3)
  425. to->origin[2] = readCoord();
  426. if(bits & U_ANGLE3)
  427. to->angles[2] = readAngle();
  428. if(bits & U_SOLID)
  429. {}
  430. if(morebits & U_FTE_TRANS && myFTEProtocolExtensions & FTE_PEXT_TRANS)
  431. readByte();
  432. if(morebits & U_FTE_ENTITYDBL)
  433. {}
  434. if(morebits & U_FTE_ENTITYDBL2)
  435. {}
  436. if(morebits & U_FTE_MODELDBL)
  437. {}
  438. }
  439. //========================================================================
  440. // Parser
  441. quint32 QWClientPrivate::littleLong(quint32 l)
  442. {
  443. if(QSysInfo::ByteOrder == QSysInfo::LittleEndian)
  444. return qToLittleEndian<quint32>(l);
  445. else
  446. return l;
  447. }
  448. quint16 QWClientPrivate::littleShort(quint16 s)
  449. {
  450. if(QSysInfo::ByteOrder == QSysInfo::LittleEndian)
  451. return qToLittleEndian<quint16>(s);
  452. else
  453. return s;
  454. }
  455. float QWClientPrivate::littleFloat(float f)
  456. {
  457. if(QSysInfo::ByteOrder == QSysInfo::LittleEndian)
  458. return qToLittleEndian<float>(f);
  459. else
  460. return f;
  461. }
  462. bool QWClientPrivate::checkForBadRead(quint8 typeSize)
  463. {
  464. if(myInStream.device()->pos()+typeSize > myInStream.device()->size())
  465. {
  466. myBadReadFlag = true;
  467. return true;
  468. }
  469. return false;
  470. }
  471. float QWClientPrivate::readAngle()
  472. {
  473. if(checkForBadRead(1))
  474. return -1;
  475. quint8 angle;
  476. myInStream >> angle;
  477. return angle * (360.0f/256);
  478. }
  479. float QWClientPrivate::readAngle16()
  480. {
  481. if(checkForBadRead(2))
  482. return -1;
  483. quint16 angle;
  484. myInStream >> angle;
  485. return angle * (360.0f/65536);
  486. }
  487. float QWClientPrivate::readCoord()
  488. {
  489. if(checkForBadRead(2))
  490. return -1;
  491. quint16 coord;
  492. myInStream >> coord;
  493. return coord * (1.0f/8);
  494. }
  495. quint8 QWClientPrivate::readByte()
  496. {
  497. if(checkForBadRead(1))
  498. return 0xff;
  499. quint8 byte;
  500. myInStream >> byte;
  501. return byte;
  502. }
  503. float QWClientPrivate::readFloat()
  504. {
  505. union
  506. {
  507. quint8 b[4];
  508. int l;
  509. float f;
  510. } d;
  511. d.b[0] = readByte();
  512. d.b[1] = readByte();
  513. d.b[2] = readByte();
  514. d.b[3] = readByte();
  515. return littleFloat(d.f);
  516. }
  517. const QString QWClientPrivate::readString()
  518. {
  519. QString str;
  520. quint8 c;
  521. c = readByte();
  522. while(c && c != 255) //bad read or null terminator
  523. {
  524. str.append(c);
  525. c = readByte();
  526. }
  527. return str;
  528. }
  529. qint32 QWClientPrivate::readLong()
  530. {
  531. if(checkForBadRead(4))
  532. return -1;
  533. quint32 l;
  534. myInStream >> l;
  535. return l;
  536. }
  537. qint16 QWClientPrivate::readShort()
  538. {
  539. if(checkForBadRead(2))
  540. return -1;
  541. qint16 s;
  542. myInStream >> s;
  543. return s;
  544. }
  545. //========================================================================
  546. void QWClientPrivate::parseSvcNoop()
  547. {
  548. }
  549. void QWClientPrivate::parseSvcDisconnect()
  550. {
  551. mySocket->close();
  552. myState = QWClient::DisconnectedState;
  553. myClient->onDisconnect();
  554. }
  555. void QWClientPrivate::parseSvcPrint()
  556. {
  557. quint8 level = readByte();
  558. QString msg = readString();
  559. myClient->onPrint(level, msg.toLatin1().data());
  560. }
  561. void QWClientPrivate::parseSvcCenterPrint()
  562. {
  563. myClient->onCenterPrint(readString().toLatin1().data());
  564. }
  565. void QWClientPrivate::parseSvcStuffText()
  566. {
  567. QStringList commands = readString().split("\n");
  568. for(int i = 0; i < commands.size(); ++i)
  569. {
  570. QString cmd = commands.at(i);
  571. if(cmd == "reconnect" || cmd == "cmd new")
  572. {
  573. writeByte(&myReliableOutStream, clc_stringcmd);
  574. writeString(&myReliableOutStream, "new");
  575. }
  576. else if(cmd == "cmd pext")
  577. {
  578. writeByte(&myReliableOutStream, clc_stringcmd);
  579. writeString(&myReliableOutStream, "pext 0x00000000 0x00000000 0x00000000");
  580. }
  581. else if(cmd.startsWith("cmd spawn"))
  582. {
  583. writeByte(&myReliableOutStream, clc_stringcmd);
  584. writeString(&myReliableOutStream, cmd.section(' ', 1));
  585. }
  586. else if(cmd.startsWith("cmd prespawn"))
  587. {
  588. writeByte(&myReliableOutStream, clc_stringcmd);
  589. writeString(&myReliableOutStream, cmd.section(' ', 1));
  590. }
  591. else if(cmd == "skins")
  592. {
  593. writeByte(&myReliableOutStream, clc_stringcmd);
  594. writeString(&myReliableOutStream, QString("begin " + QString::number(myServerCount)));
  595. }
  596. else if(cmd.startsWith("packet"))
  597. {
  598. QRegExp regex("\"(.+)\"");
  599. int pos = regex.indexIn(cmd);
  600. if(pos != -1)
  601. sendConnectionless(regex.capturedTexts().at(1).toLatin1());
  602. }
  603. myClient->onStuffedCmd(cmd.toLatin1().data());
  604. }
  605. }
  606. void QWClientPrivate::parseSvcDamage()
  607. {
  608. int armor = readByte();
  609. int blood = readByte();
  610. myClient->onDamage(armor, blood);
  611. readCoord();
  612. readCoord();
  613. readCoord();
  614. }
  615. void QWClientPrivate::parseSvcServerData()
  616. {
  617. while (1) {
  618. myProtocolVersion = readLong();
  619. if(myProtocolVersion == PROTOCOL_VERSION_FTE || myProtocolVersion == PROTOCOL_VERSION_FTE2)
  620. {
  621. myFTEProtocolExtensions = readLong();
  622. continue;
  623. }
  624. if(myProtocolVersion == PROTOCOL_VERSION)
  625. break;
  626. }
  627. myServerCount = readLong();
  628. myGameDir = readString();
  629. QDir quakeDir(myQuakeDir);
  630. if(!quakeDir.cd(myGameDir))
  631. quakeDir.mkdir(myGameDir);
  632. quint8 playerNum = readByte(); //playernum
  633. if(playerNum & 0x80)
  634. {
  635. mySpectatorFlag = true;
  636. playerNum &= ~0x80;
  637. }
  638. else
  639. mySpectatorFlag = false;
  640. QString lvlName = readString();
  641. float a = readFloat();
  642. float b = readFloat();
  643. float c = readFloat();
  644. float d = readFloat();
  645. float e = readFloat();
  646. float f = readFloat();
  647. float g = readFloat();
  648. float h = readFloat();
  649. float i = readFloat();
  650. float j = readFloat();
  651. myClient->onLevelChanged(
  652. playerNum,
  653. lvlName.toLatin1().data(),
  654. a,b,c,d,e,f,g,h,i,j
  655. );
  656. writeByte(&myReliableOutStream, clc_stringcmd);
  657. writeString(&myReliableOutStream, QString("soundlist " + QString::number(myServerCount) + " 0"));
  658. if(myDownload->isOpen())
  659. myDownload->close();
  660. }
  661. void QWClientPrivate::parseSvcSetAngle()
  662. {
  663. readAngle();
  664. readAngle();
  665. readAngle();
  666. }
  667. void QWClientPrivate::parseSvcLightStyle()
  668. {
  669. readByte();
  670. readString();
  671. }
  672. void QWClientPrivate::parseSvcSound()
  673. {
  674. quint16 channel;
  675. channel = readShort();
  676. if (channel & SND_VOLUME)
  677. readByte();
  678. if (channel & SND_ATTENUATION)
  679. readByte();
  680. myClient->onPlaySound(readByte());
  681. readCoord();
  682. readCoord();
  683. readCoord();
  684. }
  685. void QWClientPrivate::parseSvcStopSound()
  686. {
  687. readShort();
  688. }
  689. void QWClientPrivate::parseSvcUpdateFrags()
  690. {
  691. //printf("svc_updatefrags\n");
  692. quint8 playerNum = readByte();
  693. quint16 frags = readShort();
  694. myClient->onUpdateFrags(playerNum, frags);
  695. }
  696. void QWClientPrivate::parseSvcUpdatePing()
  697. {
  698. quint8 playerNum = readByte();
  699. quint16 ping = readShort();
  700. myClient->onUpdatePing(playerNum, ping);
  701. }
  702. void QWClientPrivate::parseSvcUpdatePL()
  703. {
  704. quint8 playerNum = readByte();
  705. quint8 pl = readByte();
  706. myClient->onUpdatePL(playerNum, pl);
  707. }
  708. void QWClientPrivate::parseSvcUpdateEnterTime()
  709. {
  710. readByte();
  711. readFloat();
  712. }
  713. void QWClientPrivate::parseSvcSpawnBaseLine()
  714. {
  715. //printf("svc_spawnbaseline\n");
  716. readShort();
  717. readByte();
  718. readByte();
  719. readByte();
  720. readByte();
  721. for(int i = 0; i < 3; i++)
  722. {
  723. readCoord();
  724. readAngle();
  725. }
  726. }
  727. void QWClientPrivate::parseSvcSpawnStatic()
  728. {
  729. //printf("svc_spawnstatic\n");
  730. //rawReadShort();
  731. readByte();
  732. readByte();
  733. readByte();
  734. readByte();
  735. for(int i = 0; i < 3; i++)
  736. {
  737. readCoord();
  738. readAngle();
  739. }
  740. }
  741. void QWClientPrivate::parseSvcTempEntity()
  742. {
  743. //printf("svc_temp_entity\n");
  744. quint8 c = readByte();
  745. bool parsed = false;
  746. switch(c)
  747. {
  748. case TE_LIGHTNING1:
  749. case TE_LIGHTNING2:
  750. case TE_LIGHTNING3:
  751. readShort();
  752. readCoord();
  753. readCoord();
  754. readCoord();
  755. readCoord();
  756. readCoord();
  757. readCoord();
  758. parsed = true;
  759. break;
  760. case TE_GUNSHOT:
  761. readByte();
  762. readCoord();
  763. readCoord();
  764. readCoord();
  765. parsed = true;
  766. break;
  767. case TE_BLOOD:
  768. readByte();
  769. readCoord();
  770. readCoord();
  771. readCoord();
  772. parsed = true;
  773. break;
  774. case TE_LIGHTNINGBLOOD:
  775. readCoord();
  776. readCoord();
  777. readCoord();
  778. parsed = true;
  779. break;
  780. }
  781. if(!parsed)
  782. {
  783. readCoord();
  784. readCoord();
  785. readCoord();
  786. }
  787. }
  788. void QWClientPrivate::parseSvcUpdateStat()
  789. {
  790. readByte();
  791. readByte();
  792. }
  793. void QWClientPrivate::parseSvcUpdateStatLong()
  794. {
  795. //printf("svc_updatestatlong\n");
  796. readByte();
  797. readLong();
  798. }
  799. void QWClientPrivate::parseSvcSpawnStaticSound()
  800. {
  801. //printf("svc_spawnstaticsound\n");
  802. readCoord();
  803. readCoord();
  804. readCoord();
  805. readByte();
  806. readByte();
  807. readByte();
  808. }
  809. void QWClientPrivate::parseSvcCDTrack()
  810. {
  811. readByte();
  812. }
  813. void QWClientPrivate::parseSvcIntermission()
  814. {
  815. //printf("svc_intermission\n");
  816. readCoord();
  817. readCoord();
  818. readCoord();
  819. readAngle();
  820. readAngle();
  821. readAngle();
  822. }
  823. void QWClientPrivate::parseSvcFinale()
  824. {
  825. //printf("svc_finale\n");
  826. readString();
  827. }
  828. void QWClientPrivate::parseSvcSellScreen()
  829. {
  830. }
  831. void QWClientPrivate::parseSvcSmallKick()
  832. {
  833. }
  834. void QWClientPrivate::parseSvcBigKick()
  835. {
  836. }
  837. void QWClientPrivate::parseSvcMuzzleFlash()
  838. {
  839. //printf("svc_muzzleflash\n");
  840. readShort();
  841. }
  842. void QWClientPrivate::parseSvcUpdateUserinfo()
  843. {
  844. quint8 playerNum = readByte();
  845. quint32 userID = readLong();
  846. QString info = readString();
  847. myClient->onUpdateUserInfo(playerNum, userID, info.toLatin1().data());
  848. }
  849. void QWClientPrivate::parseSvcSetinfo()
  850. {
  851. //printf("svc_setinfo\n");
  852. QString key, value;
  853. int playerNum = readByte();
  854. key = readString();
  855. value = readString();
  856. //that must be done
  857. if(key == "rate")
  858. {
  859. myRate = value.toUInt();
  860. sendCmd("setinfo \"rate\" \"" + value + "\"");
  861. }
  862. myClient->onSetInfo(playerNum, key.toLatin1().data(), value.toLatin1().data());
  863. }
  864. void QWClientPrivate::parseSvcServerinfo()
  865. {
  866. //printf("svc_serverinfo\n");
  867. QString key, value;
  868. key = readString();
  869. value = readString();
  870. myClient->onServerInfo(key.toLatin1().data(), value.toLatin1().data());
  871. }
  872. void QWClientPrivate::startDownload(const QString &filename)
  873. {
  874. if(myDownload->isOpen())
  875. myDownload->close();
  876. writeByte(&myReliableOutStream, clc_stringcmd);
  877. writeString(&myReliableOutStream, QString("download " + filename));
  878. if(filename.contains('/'))
  879. {
  880. QString path = filename.mid(0, (filename.size() - filename.section('/', -1).size() - 1));
  881. QDir quakeDir(myGameDir);
  882. quakeDir.mkpath(myQuakeDir + "/" + myGameDir + "/" + path);
  883. }
  884. //generate disk path
  885. int tmpNo = 0;
  886. QString tmpFileName = myQuakeDir + "/" + myGameDir + "/" + filename + QString::number(tmpNo) + ".tmp";
  887. while(myDownload->exists(tmpFileName))
  888. {
  889. tmpNo++;
  890. tmpFileName = myQuakeDir + "/" + myGameDir + "/" + filename + QString::number(tmpNo) + ".tmp";
  891. }
  892. myDownload->setFileName(tmpFileName);
  893. myDownload->open(QIODevice::WriteOnly);
  894. myClient->onDownloadStarted(filename.toLatin1().data());
  895. }
  896. #if 0
  897. void QWClientPrivate::parseChunkedDownload()
  898. {
  899. QString svname;
  900. int totalsize;
  901. int chunknum;
  902. char data[DLBLOCKSIZE];
  903. chunknum = readLong();
  904. if(chunknum < 0)
  905. {
  906. totalsize = readLong();
  907. svname = readString();
  908. if(myDownload->isOpen())
  909. {
  910. // Ensure FILE is closed
  911. if(totalsize != -3) // -3 = dl stopped, so this known issue, do not warn
  912. qDebug("cls.download shouldn't have been set\n");
  913. myDownload->close();
  914. }
  915. if(totalsize < 0)
  916. {
  917. switch(totalsize)
  918. {
  919. case -3: qDebug("Server cancel downloading file %s\n", svname.toLatin1().data()); break;
  920. case -2: qDebug("Server permissions deny downloading file %s\n", svname.toLatin1().data()); break;
  921. default: qDebug("Couldn't find file %s on the server\n", svname.toLatin1().data()); break;
  922. }
  923. myDownload->close();
  924. return;
  925. }
  926. if(cls.downloadmethod == DL_QWCHUNKS)
  927. {
  928. qDebug("Received second download - \"%s\"\n", svname.toLatin1().data());
  929. disconnect();
  930. }
  931. if(!myDownload->isOpen())
  932. {
  933. qDebug("Failed to open %s", myDownload->fileName());
  934. return;
  935. }
  936. cls.downloadmethod = DL_QWCHUNKS;
  937. cls.downloadpercent = 0;
  938. chunked_download_number++;
  939. downloadsize = totalsize;
  940. firstblock = 0;
  941. receivedbytes = 0;
  942. blockcycle = -1; //so it requests 0 first. :)
  943. memset(recievedblock, 0, sizeof(recievedblock));
  944. return;
  945. }
  946. MSG_ReadData(data, DLBLOCKSIZE);
  947. if (myDownload->isOpen())
  948. return;
  949. if (cls.downloadmethod != DL_QWCHUNKS)
  950. Host_Error("cls.downloadmethod != DL_QWCHUNKS\n");
  951. if(chunknum < firstblock)
  952. return;
  953. if(chunknum - firstblock >= MAXBLOCKS)
  954. return;
  955. if(recievedblock[chunknum&(MAXBLOCKS-1)])
  956. return;
  957. receivedbytes += DLBLOCKSIZE;
  958. recievedblock[chunknum&(MAXBLOCKS-1)] = true;
  959. while(recievedblock[firstblock&(MAXBLOCKS-1)])
  960. {
  961. recievedblock[firstblock&(MAXBLOCKS-1)] = false;
  962. firstblock++;
  963. }
  964. fseek(cls.download, chunknum * DLBLOCKSIZE, SEEK_SET);
  965. if (downloadsize - chunknum * DLBLOCKSIZE < DLBLOCKSIZE) //final block is actually meant to be smaller than we recieve.
  966. fwrite(data, 1, downloadsize - chunknum * DLBLOCKSIZE, cls.download);
  967. else
  968. fwrite(data, 1, DLBLOCKSIZE, cls.download);
  969. cls.downloadpercent = receivedbytes/(float)downloadsize*100;
  970. tm = Sys_DoubleTime() - cls.downloadstarttime; // how long we dl-ing
  971. cls.downloadrate = (tm ? receivedbytes / 1024 / tm : 0); // some average dl speed in KB/s
  972. }
  973. #endif
  974. void QWClientPrivate::parseSvcDownload()
  975. {
  976. // if(myFTEProtocolExtensions & FTE_PEXT_CHUNKEDDOWNLOADS)
  977. // {
  978. // parseChunkedDownload();
  979. // return;
  980. // }
  981. qint16 size;
  982. quint8 percent;
  983. size = readShort();
  984. percent = readByte();
  985. if(size == -1)
  986. {
  987. //file not found
  988. disconnect();
  989. return;
  990. }
  991. if(!myDownload->isOpen())
  992. {
  993. myInStream.device()->seek(myInStream.device()->pos() + size);
  994. return;
  995. }
  996. char* temp = new char[size];
  997. myInStream.readRawData(temp, size);
  998. myDownload->write(temp, size);
  999. myDownload->waitForBytesWritten(1000);
  1000. delete[] temp;
  1001. myClient->onDownloadProgress(percent);
  1002. if(percent != 100)
  1003. {
  1004. writeByte(&myReliableOutStream, clc_stringcmd);
  1005. writeString(&myReliableOutStream, "nextdl");
  1006. }
  1007. else
  1008. {
  1009. myDownload->close();
  1010. QString normalFileName = myDownload->fileName().left(myDownload->fileName().length()-5); //strip #.tmp
  1011. if(!myDownload->rename(normalFileName))
  1012. {
  1013. QFile::remove(normalFileName);
  1014. myDownload->rename(normalFileName); //now it should succeed
  1015. }
  1016. myClient->onDownloadFinished();
  1017. preSpawn(mapChecksum(myMapName));
  1018. }
  1019. }
  1020. void QWClientPrivate::readUserDeltaCmd(userCmd_t *from, userCmd_t *move)
  1021. {
  1022. quint8 bits;
  1023. memcpy(move, from, sizeof(*move));
  1024. bits = readByte();
  1025. // read current angles
  1026. if(bits & CM_ANGLE1)
  1027. move->angles[0] = readAngle16();
  1028. if(bits & CM_ANGLE2)
  1029. move->angles[1] = readAngle16();
  1030. if(bits & CM_ANGLE3)
  1031. move->angles[2] = readAngle16();
  1032. // read movement
  1033. if(bits & CM_FORWARD)
  1034. move->forwardmove = readShort();
  1035. if(bits & CM_SIDE)
  1036. move->sidemove = readShort();
  1037. if(bits & CM_UP)
  1038. move->upmove = readShort();
  1039. // read buttons
  1040. if(bits & CM_BUTTONS)
  1041. move->buttons = readByte();
  1042. if(bits & CM_IMPULSE)
  1043. move->impulse = readByte();
  1044. // read time to run command
  1045. move->msec = readByte();
  1046. }
  1047. void QWClientPrivate::parseSvcPlayerinfo()
  1048. {
  1049. quint16 flags;
  1050. userCmd_t from, move;
  1051. memset(&from, 0, sizeof(userCmd_t));
  1052. memset(&move, 0, sizeof(userCmd_t));
  1053. int playerNum = readByte();
  1054. flags = readShort();
  1055. float x = readCoord();
  1056. float y = readCoord();
  1057. float z = readCoord();
  1058. myClient->onPlayerInfo(playerNum, x, y, z);
  1059. readByte();
  1060. if(flags & PF_MSEC)
  1061. readByte();
  1062. if(flags & PF_COMMAND)
  1063. readUserDeltaCmd(&from, &move);
  1064. for(int i = 0; i < 3; i++)
  1065. {
  1066. if(flags & (PF_VELOCITY1<<i))
  1067. readShort();
  1068. }
  1069. if(flags & PF_MODEL)
  1070. readByte();
  1071. if(flags & PF_SKINNUM)
  1072. readByte();
  1073. if(flags & PF_EFFECTS)
  1074. readByte();
  1075. if(flags & PF_WEAPONFRAME)
  1076. readByte();
  1077. if(flags & PF_TRANS_Z && myFTEProtocolExtensions & FTE_PEXT_TRANS)
  1078. readByte();
  1079. }
  1080. void QWClientPrivate::parseSvcNails()
  1081. {
  1082. //printf("svc_nails\n");
  1083. quint8 c = readByte();
  1084. for(int i = 0; i < c; i++)
  1085. {
  1086. for(int j = 0; j < 6; j++)
  1087. readByte();
  1088. }
  1089. }
  1090. void QWClientPrivate::parseSvcChokeCount()
  1091. {
  1092. readByte();
  1093. }
  1094. void QWClientPrivate::parseSvcModellist()
  1095. {
  1096. quint8 i = readByte();
  1097. bool firstLoop = true;
  1098. for(;;)
  1099. {
  1100. QString s = readString();
  1101. if(s.isEmpty())
  1102. break;
  1103. if(!i && firstLoop)
  1104. {
  1105. myMapName = s;
  1106. firstLoop = false;
  1107. }
  1108. myClient->onModelListFile(s.toLatin1().data());
  1109. }
  1110. i = readByte();
  1111. if(i)
  1112. {
  1113. writeByte(&myReliableOutStream, clc_stringcmd);
  1114. writeString(&myReliableOutStream, QString("modellist " + QString::number(myServerCount) + " " + QString::number(i)));
  1115. return;
  1116. }
  1117. if(!fileExists(myMapName) && !QWTables::getOriginalMapChecksum(myMapName))
  1118. {
  1119. startDownload(myMapName);
  1120. return;
  1121. }
  1122. preSpawn(mapChecksum(myMapName));
  1123. }
  1124. void QWClientPrivate::parseSvcSoundlist()
  1125. {
  1126. quint8 i;
  1127. i = readByte();
  1128. for(;;)
  1129. {
  1130. QString s = readString();
  1131. if(s.isEmpty())
  1132. break;
  1133. myClient->onSoundListFile(s.toLatin1().data());
  1134. }
  1135. i = readByte();
  1136. if(i)
  1137. {
  1138. writeByte(&myReliableOutStream, clc_stringcmd);
  1139. writeString(&myReliableOutStream, QString("soundlist " + QString::number(myServerCount) + " " + QString::number(i)));
  1140. return;
  1141. }
  1142. //continue login
  1143. writeByte(&myReliableOutStream, clc_stringcmd);
  1144. writeString(&myReliableOutStream, QString("modellist " + QString::number(myServerCount) + " 0"));
  1145. }
  1146. void QWClientPrivate::parseSvcPacketEntities()
  1147. {
  1148. int word;
  1149. entityState_t olde, newe;
  1150. memset(&olde, 0, sizeof(olde));
  1151. while (1)
  1152. {
  1153. word = (unsigned short)readShort();
  1154. if (!word)
  1155. break; // done
  1156. parseDelta(&olde, &newe, word);
  1157. }
  1158. }
  1159. void QWClientPrivate::parseSvcDeltaPacketEntities()
  1160. {
  1161. parseSvcPacketEntities();
  1162. }
  1163. void QWClientPrivate::parseSvcMaxSpeed()
  1164. {
  1165. myClient->onMaxSpeedChange(readFloat());
  1166. }
  1167. void QWClientPrivate::parseSvcEntGravity()
  1168. {
  1169. myClient->onEntGravityChange(readFloat());
  1170. }
  1171. void QWClientPrivate::parseSvcSetPause()
  1172. {
  1173. myClient->onSetPause(readByte());
  1174. }
  1175. void QWClientPrivate::parseSvcNails2()
  1176. {
  1177. quint8 c = readByte();
  1178. for(int i = 0; i < c; i++)
  1179. {
  1180. readByte();
  1181. for(int j = 0; j < 6; j++)
  1182. readByte();
  1183. }
  1184. }
  1185. void QWClientPrivate::parseSvcFTEModellistShort()
  1186. {
  1187. quint16 i = readShort();
  1188. bool firstLoop = true;
  1189. for(;;)
  1190. {
  1191. QString s;
  1192. s = readString();
  1193. if(s.isEmpty())
  1194. break;
  1195. if(!i && firstLoop)
  1196. {
  1197. myMapName = s;
  1198. firstLoop = false;
  1199. }
  1200. myClient->onModelListFile(s.toLatin1().data());
  1201. }
  1202. i = readByte();
  1203. if(i)
  1204. {
  1205. writeByte(&myReliableOutStream, clc_stringcmd);
  1206. writeString(&myReliableOutStream, QString("modellist " + QString::number(myServerCount) + " " + QString::number(i)));
  1207. return;
  1208. }
  1209. if(!fileExists(myMapName) && !QWTables::getOriginalMapChecksum(myMapName))
  1210. {
  1211. startDownload(myMapName);
  1212. return;
  1213. }
  1214. preSpawn(mapChecksum(myMapName));
  1215. }
  1216. void QWClientPrivate::parseSvcFTESpawnBaseline2()
  1217. {
  1218. entityState_t nullst, es;
  1219. if(!(myFTEProtocolExtensions & FTE_PEXT_SPAWNSTATIC2))
  1220. {
  1221. myClient->onError("illegible server message\nsvc_fte_spawnbaseline2 without FTE_PEXT_SPAWNSTATIC2\n");
  1222. disconnect();
  1223. return;
  1224. }
  1225. memset(&nullst, 0, sizeof (entityState_t));
  1226. memset(&es, 0, sizeof (entityState_t));
  1227. parseDelta(&nullst, &es, readShort());
  1228. }
  1229. void QWClientPrivate::parseSvcQizmoVoice()
  1230. {
  1231. // Read the two-byte header.
  1232. readByte();
  1233. readByte();
  1234. // 32 bytes of voice data follow
  1235. for(int i = 0; i < 32; i++)
  1236. readByte();
  1237. }
  1238. void QWClientPrivate::parseSvcFTEVoiceChat()
  1239. {
  1240. readByte();
  1241. readByte();
  1242. readByte();
  1243. quint16 i = readShort();
  1244. myInStream.device()->seek(myInStream.device()->pos() + i);
  1245. }
  1246. void QWClientPrivate::parseSvcFTESpawnStatic2()
  1247. {
  1248. if(myFTEProtocolExtensions & FTE_PEXT_SPAWNSTATIC2)
  1249. {
  1250. entityState_t from, to;
  1251. memset(&from, 0, sizeof(entityState_t));
  1252. memset(&to, 0, sizeof(entityState_t));
  1253. parseDelta(&from, &to, readShort());
  1254. }
  1255. }
  1256. void QWClientPrivate::parseSvcKilledMonster()
  1257. {
  1258. }
  1259. void QWClientPrivate::parseSvcFoundSecret()
  1260. {
  1261. }
  1262. void QWClientPrivate::parseSvcUpdateName()
  1263. {
  1264. readByte();
  1265. readString();
  1266. }
  1267. void QWClientPrivate::parseSvcUpdateColors()
  1268. {
  1269. readByte();
  1270. readByte();
  1271. }
  1272. void QWClientPrivate::parseSvcTime()
  1273. {
  1274. readFloat();
  1275. }
  1276. void QWClientPrivate::parseSvcSignonNum()
  1277. {
  1278. readByte();
  1279. }
  1280. void QWClientPrivate::parseSvcParticle()
  1281. {
  1282. for(int i = 0; i < 3; ++i)
  1283. readCoord();
  1284. for(int i = 0; i < 3; ++i)
  1285. readByte();
  1286. readByte();
  1287. readByte();
  1288. }
  1289. void QWClientPrivate::parseSvcClientData()
  1290. {
  1291. qDebug() << "WHY?!?!?!?!?!?! WHY ME BEING CALLED!";
  1292. }
  1293. void QWClientPrivate::parseSvcVersion()
  1294. {
  1295. }
  1296. void QWClientPrivate::preSpawn(int mapChecksum)
  1297. {
  1298. writeByte(&myReliableOutStream, clc_stringcmd);
  1299. writeString(&myReliableOutStream, "setinfo pmodel 33168");
  1300. writeByte(&myReliableOutStream, clc_stringcmd);
  1301. writeString(&myReliableOutStream, "setinfo emodel 6967");
  1302. writeByte(&myReliableOutStream, clc_stringcmd);
  1303. writeString(&myReliableOutStream, QString("prespawn " + QString::number(myServerCount) + " 0 " + QString::number(mapChecksum)));
  1304. }
  1305. void QWClientPrivate::parseServerMessage()
  1306. {
  1307. quint32 incomingSeq, incomingAck;
  1308. bool incomingSeqReliable, incomingAckReliable;
  1309. myBadReadFlag = false;
  1310. myInStream.device()->seek(0);
  1311. myInStream >> incomingSeq;
  1312. myInStream >> incomingAck;
  1313. incomingSeqReliable = incomingSeq >> 31;
  1314. incomingAckReliable = incomingAck >> 31;
  1315. incomingSeq &= ~0x80000000;
  1316. incomingAck &= ~0x80000000;
  1317. if(incomingSeq <= myIncomingSeq)
  1318. return;
  1319. myPacketLoss = incomingSeq - (myIncomingSeq + 1);
  1320. if(incomingAckReliable == myOutgoingSeqReliableFlag)
  1321. myReliableData.clear();
  1322. if(incomingSeqReliable)
  1323. myIncomingSeqReliableFlag ^= 1;
  1324. myIncomingSeq = incomingSeq;
  1325. myIncomingAck = incomingAck;
  1326. myIncomingAckReliableFlag = incomingAckReliable;
  1327. while(!myInStream.atEnd())
  1328. {
  1329. if(myBadReadFlag)
  1330. {
  1331. myClient->onError("Bad read from server.");
  1332. disconnect();
  1333. return;
  1334. }
  1335. quint8 c;
  1336. quint8 last = 0;
  1337. myInStream >> c;
  1338. if(c == 0xff)
  1339. break;
  1340. switch(c)
  1341. {
  1342. case svc_bad:
  1343. myClient->onError("Bad read from server.");
  1344. disconnect();
  1345. return;
  1346. case svc_nop:
  1347. parseSvcNoop();
  1348. break;
  1349. case svc_disconnect:
  1350. parseSvcDisconnect();
  1351. break;
  1352. case svc_print:
  1353. parseSvcPrint();
  1354. break;
  1355. case svc_centerprint:
  1356. parseSvcCenterPrint();
  1357. break;
  1358. case svc_stufftext:
  1359. parseSvcStuffText();
  1360. break;
  1361. case svc_damage:
  1362. parseSvcDamage();
  1363. break;
  1364. case svc_serverdata:
  1365. parseSvcServerData();
  1366. break;
  1367. case svc_setangle:
  1368. parseSvcSetAngle();
  1369. break;
  1370. case svc_lightstyle:
  1371. parseSvcLightStyle();
  1372. break;
  1373. case svc_sound:
  1374. parseSvcSound();
  1375. break;
  1376. case svc_stopsound:
  1377. parseSvcStopSound();
  1378. break;
  1379. case svc_updatefrags:
  1380. parseSvcUpdateFrags();
  1381. break;
  1382. case svc_updateping:
  1383. parseSvcUpdatePing();
  1384. break;
  1385. case svc_updatepl:
  1386. parseSvcUpdatePL();
  1387. break;
  1388. case svc_updateentertime:
  1389. parseSvcUpdateEnterTime();
  1390. break;
  1391. case svc_spawnbaseline:
  1392. parseSvcSpawnBaseLine();
  1393. break;
  1394. case svc_spawnstatic:
  1395. parseSvcSpawnStatic();
  1396. break;
  1397. case svc_temp_entity:
  1398. parseSvcTempEntity();
  1399. break;
  1400. case svc_killedmonster:
  1401. parseSvcKilledMonster();
  1402. break;
  1403. case svc_foundsecret:
  1404. parseSvcFoundSecret();
  1405. break;
  1406. case svc_updatestat:
  1407. parseSvcUpdateStat();
  1408. break;
  1409. case svc_updatestatlong:
  1410. parseSvcUpdateStatLong();
  1411. break;
  1412. case svc_spawnstaticsound:
  1413. parseSvcSpawnStaticSound();
  1414. break;
  1415. case svc_cdtrack:
  1416. parseSvcCDTrack();
  1417. break;
  1418. case svc_intermission:
  1419. parseSvcIntermission();
  1420. break;
  1421. case svc_finale:
  1422. parseSvcFinale();
  1423. break;
  1424. case svc_sellscreen:
  1425. parseSvcSellScreen();
  1426. break;
  1427. case svc_smallkick:
  1428. parseSvcSmallKick();
  1429. break;
  1430. case svc_bigkick:
  1431. parseSvcBigKick();
  1432. break;
  1433. case svc_muzzleflash:
  1434. parseSvcMuzzleFlash();
  1435. break;
  1436. case svc_updateuserinfo:
  1437. parseSvcUpdateUserinfo();
  1438. break;
  1439. case svc_setinfo:
  1440. parseSvcSetinfo();
  1441. break;
  1442. case svc_serverinfo:
  1443. parseSvcServerinfo();
  1444. break;
  1445. case svc_download:
  1446. parseSvcDownload();
  1447. break;
  1448. case svc_playerinfo:
  1449. parseSvcPlayerinfo();
  1450. break;
  1451. case svc_nails:
  1452. parseSvcNails();
  1453. break;
  1454. case svc_chokecount:
  1455. parseSvcChokeCount();
  1456. break;
  1457. case svc_modellist:
  1458. parseSvcModellist();
  1459. break;
  1460. case svc_soundlist:
  1461. parseSvcSoundlist();
  1462. break;
  1463. case svc_packetentities:
  1464. parseSvcPacketEntities();
  1465. break;
  1466. case svc_deltapacketentities:
  1467. parseSvcDeltaPacketEntities();
  1468. break;
  1469. case svc_maxspeed:
  1470. parseSvcMaxSpeed();
  1471. break;
  1472. case svc_entgravity:
  1473. parseSvcEntGravity();
  1474. break;
  1475. case svc_setpause:
  1476. parseSvcSetPause();
  1477. break;
  1478. case svc_nails2:
  1479. parseSvcNails2();
  1480. break;
  1481. case svc_fte_modellistshort:
  1482. parseSvcFTEModellistShort();
  1483. break;
  1484. case svc_fte_spawnbaseline2:
  1485. parseSvcFTESpawnBaseline2();
  1486. break;
  1487. case svc_qizmovoice:
  1488. parseSvcQizmoVoice();
  1489. break;
  1490. case svc_fte_voicechat:
  1491. parseSvcFTEVoiceChat();
  1492. break;
  1493. case svc_fte_spawnstatic2:
  1494. parseSvcFTESpawnStatic2();
  1495. break;
  1496. case nq_svc_time:
  1497. parseSvcTime();
  1498. break;
  1499. case nq_svc_clientdata:
  1500. parseSvcClientData();
  1501. break;
  1502. case nq_svc_version:
  1503. parseSvcVersion();
  1504. break;
  1505. case nq_svc_particle:
  1506. parseSvcParticle();
  1507. break;
  1508. case nq_svc_signonnum:
  1509. parseSvcSignonNum();
  1510. break;
  1511. case nq_svc_updatecolors:
  1512. parseSvcUpdateColors();
  1513. break;
  1514. case nq_svc_updatename:
  1515. parseSvcUpdateName();
  1516. break;
  1517. default:
  1518. myClient->onError(QString("Unknown message from server. Last Cmd: [" + QString::number(last) + "] Current Cmd: [" + QString::number(c) + "]").toLatin1().data());
  1519. disconnect();
  1520. return;
  1521. }
  1522. last = c;
  1523. }
  1524. }
  1525. void QWClientPrivate::connect(const char *host, quint16 port)
  1526. {
  1527. if(myState != QWClient::DisconnectedState)
  1528. return;
  1529. /* Disabled this, blocking too much, now user is supposed to send the string already resolved. */
  1530. // QHostInfo hi = QHostInfo::fromName(host);
  1531. // if(hi.error() != QHostInfo::NoError)
  1532. // {
  1533. // myClient->onError(hi.errorString().toLatin1().data());
  1534. // return;
  1535. // }
  1536. myHost.setAddress(host);
  1537. myPort = port;
  1538. myIncomingSeq = 0;
  1539. myIncomingAck = 0;
  1540. myOutgoingSeq = 0;
  1541. myLastRealiableSeq = 0;
  1542. myIncomingSeqReliableFlag = false;
  1543. myIncomingAckReliableFlag = false;
  1544. myOutgoingSeqReliableFlag = false;
  1545. myPacketLoss = 0;
  1546. mySocket->connectToHost(myHost, myPort);
  1547. mySocket->waitForConnected();
  1548. sendConnectionless("getchallenge\n");
  1549. myClient->onChallenge();
  1550. myQPort = qrand() & 0xffff;
  1551. myTime->start();
  1552. myState = QWClient::ConnectingState;
  1553. *myLastServerReplyTime = QTime::currentTime();
  1554. }
  1555. void QWClientPrivate::setBindHost(const QString &host)
  1556. {
  1557. QHostAddress address(host);
  1558. mySocket->bind(address, 0);
  1559. }
  1560. void QWClientPrivate::disconnect()
  1561. {
  1562. if(myState == QWClient::ConnectedState)
  1563. {
  1564. writeByte(&myUnreliableOutStream, clc_stringcmd);
  1565. writeString(&myUnreliableOutStream, "drop");
  1566. sendToServer(true);
  1567. writeByte(&myUnreliableOutStream, clc_stringcmd);
  1568. writeString(&myUnreliableOutStream, "drop");
  1569. sendToServer(true);
  1570. writeByte(&myUnreliableOutStream, clc_stringcmd);
  1571. writeString(&myUnreliableOutStream, "drop");
  1572. sendToServer(true);
  1573. }
  1574. mySocket->close();
  1575. myState = QWClient::DisconnectedState;
  1576. }
  1577. void QWClientPrivate::sendConnectionless(const QByteArray &data)
  1578. {
  1579. QByteArray d;
  1580. d.append("\xff\xff\xff\xff");
  1581. d.append(data);
  1582. mySocket->write(d);
  1583. mySocket->waitForBytesWritten();
  1584. }
  1585. void QWClientPrivate::sendMovement()
  1586. {
  1587. myUnreliableOutStream << (quint8)clc_move << (quint8)0x10 << (quint8)myPacketLoss << (quint8)0x00 << (quint8)0x00 << (quint8)0x00 << (quint8)0x22 << (quint8)0x00 << (quint8)0x21;
  1588. }
  1589. //=====================================================================
  1590. // "GPL map" support. If we encounter a map with a known "GPL" CRC,
  1591. // we fake the CRC so that, on the client side, the CRC of the original
  1592. // map is transferred to the server, and on the server side, comparison
  1593. // of clients' CRC is done against the orignal one
  1594. typedef struct {
  1595. const char *mapname;
  1596. unsigned int original;
  1597. unsigned int gpl;
  1598. } csentry_t;
  1599. static csentry_t table[] = {
  1600. // CRCs for AquaShark's "simpletextures" maps
  1601. { "dm1", 0xc5c7dab3, 0x7d37618e },
  1602. { "dm2", 0x65f63634, 0x7b337440 },
  1603. { "dm3", 0x15e20df8, 0x912781ae },
  1604. { "dm4", 0x9c6fe4bf, 0xc374df89 },
  1605. { "dm5", 0xb02d48fd, 0x77ca7ce5 },
  1606. { "dm6", 0x5208da2b, 0x200c8b5d },
  1607. { "end", 0xbbd4b4a5, 0xf89b12ae }, // this is the version with the extra room
  1608. { NULL, 0, 0 },
  1609. };
  1610. int Com_TranslateMapChecksum (const char *mapname, unsigned int checksum)
  1611. {
  1612. csentry_t *p;
  1613. // Com_Printf ("Map checksum (%s): 0x%x\n", mapname, checksum);
  1614. for (p = table; p->mapname; p++)
  1615. if (!strcmp(p->mapname, mapname)) {
  1616. if (checksum == p->gpl)
  1617. return p->original;
  1618. else
  1619. return checksum;
  1620. }
  1621. return checksum;
  1622. }
  1623. quint32 QWClientPrivate::mapChecksum(const QString &mapName)
  1624. {
  1625. // Check if this is an original map, if it is we have the checksum table ready
  1626. quint32 checksum = 0;
  1627. checksum = QWTables::getOriginalMapChecksum(mapName);
  1628. if(checksum)
  1629. return checksum;
  1630. char* mapdata;
  1631. quint64 maplen;
  1632. if(!readFile(mapName, &mapdata, &maplen))
  1633. return 0;
  1634. if(!maplen || !mapdata)
  1635. return 0;
  1636. dheader_t* header;
  1637. uchar* mod_base;
  1638. header = (dheader_t*)mapdata;
  1639. mod_base = (uchar*)mapdata;
  1640. for(int i = 0; i < HEADER_LUMPS; ++i)
  1641. {
  1642. if(i == LUMP_ENTITIES || i == LUMP_VISIBILITY || i == LUMP_LEAFS || i == LUMP_NODES)
  1643. continue;
  1644. checksum ^= blockCheckSum(mod_base + header->lumps[i].fileofs, header->lumps[i].filelen);
  1645. }
  1646. delete[] mapdata;
  1647. QString cleanMapName;
  1648. cleanMapName = mapName.section('/', -1);
  1649. cleanMapName.chop(4); //strip .bsp
  1650. return Com_TranslateMapChecksum(cleanMapName.toLatin1().data(), checksum);
  1651. }
  1652. unsigned QWClientPrivate::blockCheckSum(void* buffer, int len)
  1653. {
  1654. QByteArray digest = QCryptographicHash::hash(QByteArray((const char*)buffer, len), QCryptographicHash::Md4);
  1655. int *d = (int*)digest.data();
  1656. return (d[0] ^ d[1] ^ d[2] ^ d[3]);
  1657. }
  1658. void QWClientPrivate::writeByte(QDataStream *stream, const quint8 b)
  1659. {
  1660. *stream << b;
  1661. }
  1662. void QWClientPrivate::writeLong(QDataStream *stream, const quint32 l)
  1663. {
  1664. *stream << l;
  1665. }
  1666. void QWClientPrivate::writeShort(QDataStream *stream, const quint16 s)
  1667. {
  1668. *stream << s;
  1669. }
  1670. void QWClientPrivate::writeString(QDataStream *stream, const QString &str)
  1671. {
  1672. stream->writeRawData(str.toLatin1().data(), str.size()+1);
  1673. }
  1674. //========================================================================
  1675. // NAME FUN
  1676. char QWClientPrivate::ourReadableCharsTable[256] = { '.', '_' , '_' , '_' , '_' , '.' , '_' , '_' , '_' , '_' , '\n' , '_' , '\n' , '>' , '.' , '.',
  1677. '[', ']', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '_', '_', '_'
  1678. };
  1679. bool QWClientPrivate::ourReadableCharsTableInitialized = false;
  1680. void QWClientPrivate::fillReadableCharsTable()
  1681. {
  1682. int i;
  1683. for(i = 32; i < 127; i++)
  1684. ourReadableCharsTable[i] = ourReadableCharsTable[128 + i] = i;
  1685. ourReadableCharsTable[127] = ourReadableCharsTable[128 + 127] = '_';
  1686. for(i = 0; i < 32; i++)
  1687. ourReadableCharsTable[128 + i] = ourReadableCharsTable[i];
  1688. ourReadableCharsTable[128] = '_';
  1689. ourReadableCharsTable[10 + 128] = '_';
  1690. ourReadableCharsTable[12 + 128] = '_';
  1691. ourReadableCharsTableInitialized = true;
  1692. }
  1693. void QWClientPrivate::stripColor(char* string)
  1694. {
  1695. /* Parse simple quake red text and special chars */
  1696. if(!ourReadableCharsTableInitialized)
  1697. fillReadableCharsTable();
  1698. while(*string) {
  1699. *string = ourReadableCharsTable[(unsigned char)*string] & 127;
  1700. string++;
  1701. }
  1702. }