author | koda |
Sat, 27 Mar 2010 16:57:18 +0000 | |
changeset 3113 | 2829ea0dd47c |
parent 3011 | 73c8f618fd8b |
child 3160 | f2a3d861b23a |
permissions | -rw-r--r-- |
/* * Hedgewars, a free turn based strategy game * Copyright (c) 2005-2008 Andrey Korotaev <unC0Rr@gmail.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #include <QString> #include <QByteArray> #include <QUuid> #include "game.h" #include "hwconsts.h" #include "gameuiconfig.h" #include "gamecfgwidget.h" #include "teamselect.h" #include "KB.h" #include "proto.h" #include <QTextStream> QString training; // TODO: Cleaner solution? HWGame::HWGame(GameUIConfig * config, GameCFGWidget * gamecfg, QString ammo, TeamSelWidget* pTeamSelWidget) : TCPBase(true), ammostr(ammo), m_pTeamSelWidget(pTeamSelWidget) { this->config = config; this->gamecfg = gamecfg; TeamCount = 0; } HWGame::~HWGame() { SetGameState(gsDestroyed); } void HWGame::onClientDisconnect() { switch (gameType) { case gtDemo: break; case gtNet: emit HaveRecord(true, demo); break; default: if (gameState == gsInterrupted) emit HaveRecord(false, demo); else if (gameState == gsFinished) emit HaveRecord(true, demo); } SetGameState(gsStopped); } void HWGame::commonConfig() { QByteArray buf; QString gt; switch (gameType) { case gtDemo: gt = "TD"; break; case gtNet: gt = "TN"; break; default: gt = "TL"; } HWProto::addStringToBuffer(buf, gt); HWProto::addStringListToBuffer(buf, gamecfg->getFullConfig()); if (m_pTeamSelWidget) { QList<HWTeam> teams = m_pTeamSelWidget->getPlayingTeams(); for(QList<HWTeam>::iterator it = teams.begin(); it != teams.end(); ++it) { HWProto::addStringListToBuffer(buf, (*it).TeamGameConfig(gamecfg->getInitHealth())); HWProto::addStringToBuffer(buf, QString("eammstore %1").arg(ammostr)); } } RawSendIPC(buf); } void HWGame::SendConfig() { commonConfig(); } void HWGame::SendQuickConfig() { QByteArray teamscfg; HWProto::addStringToBuffer(teamscfg, "TL"); HWProto::addStringToBuffer(teamscfg, QString("etheme %1") .arg((Themes->size() > 0) ? Themes->at(rand() % Themes->size()) : "steel")); HWProto::addStringToBuffer(teamscfg, "eseed " + QUuid::createUuid().toString()); HWNamegen namegen; HWTeam * team1; team1 = new HWTeam; team1->difficulty = 0; team1->teamColor = *color1; team1->numHedgehogs = 4; namegen.TeamRandomNames(team1,TRUE); HWProto::addStringListToBuffer(teamscfg, team1->TeamGameConfig(100)); HWTeam * team2; team2 = new HWTeam; team2->difficulty = 4; team2->teamColor = *color2; team2->numHedgehogs = 4; namegen.TeamRandomNames(team2,TRUE); HWProto::addStringListToBuffer(teamscfg, team2->TeamGameConfig(100)); HWProto::addStringToBuffer(teamscfg, "eammstore " + *cDefaultAmmoStore); HWProto::addStringToBuffer(teamscfg, "eammstore " + *cDefaultAmmoStore); RawSendIPC(teamscfg); } void HWGame::SendTrainingConfig() { QByteArray traincfg; HWProto::addStringToBuffer(traincfg, "TL"); HWProto::addStringToBuffer(traincfg, "escript " + datadir->absolutePath() + "/Missions/Training/" + training + ".lua"); RawSendIPC(traincfg); } void HWGame::SendNetConfig() { commonConfig(); } void HWGame::ParseMessage(const QByteArray & msg) { switch(msg.at(1)) { case '?': { SendIPC("!"); break; } case 'C': { switch (gameType) { case gtLocal: { SendConfig(); break; } case gtQLocal: { SendQuickConfig(); break; } case gtDemo: break; case gtNet: { SendNetConfig(); break; } case gtTraining: { SendTrainingConfig(); break; } } break; } case 'E': { int size = msg.size(); emit ErrorMessage(QString("Last two engine messages:\n") + QString().append(msg.mid(2)).left(size - 4)); return; } case 'K': { ulong kb = msg.mid(2).toULong(); if (kb==1) { qWarning("%s", KBMessages[kb - 1].toLocal8Bit().constData()); return; } if (kb && kb <= KBmsgsCount) { emit ErrorMessage(KBMessages[kb - 1]); } return; } case 'i': { emit GameStats(msg.at(2), QString::fromUtf8(msg.mid(3))); break; } case 'Q': { SetGameState(gsInterrupted); break; } case 'q': { SetGameState(gsFinished); break; } case 's': { int size = msg.size(); QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4)); emit SendChat(msgbody); // FIXME: /me command doesn't work here QByteArray buf; HWProto::addStringToBuffer(buf, "s" + HWProto::formatChatMsg(config->netNick(), msgbody) + "\x20\x20"); demo.append(buf); break; } case 'b': { int size = msg.size(); QString msgbody = QString::fromUtf8(msg.mid(2).left(size - 4)); emit SendTeamMessage(msgbody); break; } default: { if (gameType == gtNet) { emit SendNet(msg); } if (msg.at(1) != 's') demo.append(msg); } } } void HWGame::FromNet(const QByteArray & msg) { RawSendIPC(msg); } void HWGame::FromNetChat(const QString & msg) { QByteArray buf; HWProto::addStringToBuffer(buf, 's' + msg + "\x20\x20"); RawSendIPC(buf); } void HWGame::onClientRead() { quint8 msglen; quint32 bufsize; while (!readbuffer.isEmpty() && ((bufsize = readbuffer.size()) > 0) && ((msglen = readbuffer.data()[0]) < bufsize)) { QByteArray msg = readbuffer.left(msglen + 1); readbuffer.remove(0, msglen + 1); ParseMessage(msg); } } QStringList HWGame::setArguments() { QStringList arguments; QRect resolution = config->vid_Resolution(); arguments << cfgdir->absolutePath(); arguments << QString::number(resolution.width()); arguments << QString::number(resolution.height()); arguments << QString::number(config->bitDepth()); // bpp arguments << QString("%1").arg(ipc_port); arguments << (config->vid_Fullscreen() ? "1" : "0"); arguments << (config->isSoundEnabled() ? "1" : "0"); #ifdef _WIN32 arguments << (config->isSoundHardware() ? "1" : "0"); #else arguments << "0"; #endif arguments << (config->isWeaponTooltip() ? "1" : "0"); arguments << tr("en.txt"); arguments << QString::number(config->volume()); // sound volume arguments << QString::number(config->timerInterval()); arguments << datadir->absolutePath(); arguments << (config->isShowFPSEnabled() ? "1" : "0"); arguments << (config->isAltDamageEnabled() ? "1" : "0"); arguments << config->netNick().toUtf8().toBase64(); arguments << (config->isMusicEnabled() ? "1" : "0"); arguments << (config->isReducedQuality() ? "1" : "0"); return arguments; } void HWGame::AddTeam(const QString & teamname) { if (TeamCount == 5) return; teams[TeamCount] = teamname; TeamCount++; } void HWGame::PlayDemo(const QString & demofilename) { gameType = gtDemo; QFile demofile(demofilename); if (!demofile.open(QIODevice::ReadOnly)) { emit ErrorMessage(tr("Cannot open demofile %1").arg(demofilename)); return ; } // read demo toSendBuf = demofile.readAll(); // run engine demo.clear(); Start(); SetGameState(gsStarted); } void HWGame::StartNet() { gameType = gtNet; demo.clear(); Start(); SetGameState(gsStarted); } void HWGame::StartLocal() { gameType = gtLocal; demo.clear(); Start(); SetGameState(gsStarted); } void HWGame::StartQuick() { gameType = gtQLocal; demo.clear(); Start(); SetGameState(gsStarted); } void HWGame::StartTraining(const QString & file) { gameType = gtTraining; training = file; demo.clear(); Start(); SetGameState(gsStarted); } void HWGame::SetGameState(GameState state) { gameState = state; emit GameStateChanged(state); }