QWClientPrivate.cpp 43 KB

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