QWClientPrivate.cpp 48 KB

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