void Server::startRound(Player &drawer, std::string word, float duration) { std::cout << "Starting round. Drawer: " << drawer.getName() << " Word: " << word << std::endl; m_roundDuration = duration; m_currentWord = word; m_mode = Play; cpp3ds::Packet packet; packet << NetworkEvent::RoundStart << drawer.getName() << duration; sendToAllSockets(packet); // Send word to the drawer packet.clear(); packet << NetworkEvent::RoundWord << word; m_currentDrawer->send(packet); m_roundClock.restart(); m_roundTimeoutClock.restart(); clearDrawData(); }
Server::Server(unsigned short port, std::string wordFilename) : m_port(port) , m_running(false) , m_wordFilename(wordFilename) , m_mode(Wait) , m_currentDrawer(nullptr) { std::ifstream wordFile(wordFilename); std::string line; if (wordFile.is_open()) { while (std::getline(wordFile, line)) { std::transform(line.begin(), line.end(), line.begin(), ::tolower); m_wordList.push_back(line); } wordFile.close(); } else { cpp3ds::err() << "Failed to open word file: " << wordFilename << std::endl; } clearDrawData(); }
void Server::processSocket(cpp3ds::TcpSocket* socket) { cpp3ds::Packet packet; cpp3ds::Socket::Status status = socket->receive(packet); if (status == cpp3ds::Socket::Done) { cpp3ds::Packet packetSend; NetworkEvent event; while (NetworkEvent::packetToEvent(packet, event)) { if (!validateEvent(socket, event)) continue; switch(event.type) { case NetworkEvent::Version: if (event.server.message.compare(SERVER_VERSION) != 0) { packet.clear(); std::string message = _("Incompatible client version %s (needs %s)", event.server.message.c_str(), SERVER_VERSION); packet << NetworkEvent::ServerShutdown << message; socket->send(packet); removeSocket(socket); } break; case NetworkEvent::PlayerConnected: { std::cout << event.player.name << " connected." << std::endl; bool collision = false; for (auto& player : m_players) { if (event.player.name.compare(player.second.getName()) == 0) { collision = true; break; } } if (collision) { cpp3ds::Packet packet; packet << NetworkEvent::PlayerNameCollision << event.player.name; socket->send(packet); break; } Player player(event.player.name); m_players.emplace(socket, player); NetworkEvent::eventToPacket(event, packetSend); sendToAllSockets(packetSend); packetSend.clear(); if (m_players.size() < MIN_PLAYERS) { sendWaitForPlayers(socket, MIN_PLAYERS); } break; } case NetworkEvent::Text: { NetworkEvent::eventToPacket(event, packetSend); if (m_mode != Play) break; std::string word = event.text.value.toAnsiString(); std::transform(word.begin(), word.end(), word.begin(), ::tolower); if (word.compare(m_currentWord) == 0) { std::cout << event.text.name << " won!" << std::endl; packetSend << NetworkEvent::RoundWord << word << NetworkEvent::RoundWin << event.text.name; for (auto& player : m_players) { if (player.second.getName().compare(event.text.name) == 0) player.second.incrementScore(); if (player.first == m_currentDrawer) player.second.incrementScore(); } m_roundClock.restart(); m_mode = Wait; } break; } case NetworkEvent::DrawMove: case NetworkEvent::DrawEndline: m_drawDataPacket << event.type << event.draw.x << event.draw.y; NetworkEvent::eventToPacket(event, packetSend); m_roundTimeoutClock.restart(); break; case NetworkEvent::DrawClear: clearDrawData(); NetworkEvent::eventToPacket(event, packetSend); m_roundTimeoutClock.restart(); break; case NetworkEvent::DrawUndo: { m_drawDataPacket << event.type; NetworkEvent::eventToPacket(event, packetSend); m_roundTimeoutClock.restart(); break; } case NetworkEvent::RoundPass: packetSend << NetworkEvent::RoundWord << m_currentWord; NetworkEvent::eventToPacket(event, packetSend); m_roundClock.restart(); m_mode = Wait; break; case NetworkEvent::Ping: m_pingResponses[socket] = true; break; default: break; } } if (!packetSend.endOfPacket()) sendToAllSockets(packetSend); } else if (status == cpp3ds::Socket::Disconnected || status == cpp3ds::Socket::Error) { removeSocket(socket); } }
DianVoteControl::DianVoteControl(QWidget *parent) : QWidget(parent), ui(new Ui::DianVoteControl), drawer(NULL), hidControl(NULL), stopWatch(NULL), splash(NULL), voteMode(SINGLE_VOTE), curState(STOP) { QDir dir; dir.setCurrent(QCoreApplication::applicationDirPath()); windowIcon = new QIcon(dir.absoluteFilePath("res/images/app-icon.png")); this->setWindowIcon(*windowIcon); // show splash. QPixmap pixmap(dir.absoluteFilePath("res/images/logo.png")); QSplashScreen *splash = new QSplashScreen(pixmap); splash->setWindowIcon(*windowIcon); splash->setWindowFlags(Qt::WindowStaysOnTopHint); splash->setMask(pixmap.mask()); splash->show(); ui->setupUi(this); pbStart = new QPushButton(this); pbStart->setObjectName(tr("pbStart")); ui->buttonLayout->addWidget(pbStart, 0, 0); pbAuto = new QPushButton(this); pbAuto->setObjectName(tr("pbAuto")); ui->buttonLayout->addWidget(pbAuto, 0, 1); pbPause = new QPushButton(this); pbPause->setObjectName(tr("pbPause")); ui->buttonLayout->addWidget(pbPause, 0, 0); pbPause->hide(); pbStop = new QPushButton(this); pbStop->setObjectName(tr("pbStop")); ui->buttonLayout->addWidget(pbStop, 0, 1); pbStop->hide(); pbResult = new QPushButton(this); pbResult->setObjectName(tr("pbResult")); ui->buttonLayout->addWidget(pbResult, 0, 2); pbOption = new QToolButton(this); pbOption->setObjectName(tr("pbOption")); ui->buttonLayout->addWidget(pbOption, 0, 3); qaSingleMode = new QAction(tr("SingleVoteMode"), this); // 单选模式 qaSingleMode->setCheckable(true); qaSingleMode->setChecked(true); // 默认模式 qaMutipleMode = new QAction(tr("MutipleVoteMode"), this); // 多选 qaMutipleMode->setCheckable(true); qaRaceMode = new QAction(tr("RaceVoteMode"), this); // 抢答 qaRaceMode->setCheckable(true); pbOption->addAction(qaSingleMode); pbOption->addAction(qaMutipleMode); pbOption->addAction(qaRaceMode); connect(qaSingleMode, SIGNAL(triggered()), this, SLOT(DoSingleMode())); connect(qaMutipleMode, SIGNAL(triggered()), this, SLOT(DoMutipleMode())); connect(qaRaceMode, SIGNAL(triggered()), this, SLOT(DoRaceVoteMode())); pbClose = new QPushButton(this); pbClose->setObjectName(tr("pbClose")); ui->buttonLayout->addWidget(pbClose, 0, 4); connect(pbClose, SIGNAL(clicked()), this, SLOT(close())); connect(pbStart, SIGNAL(clicked()), this, SLOT(VoteStart())); connect(pbAuto, SIGNAL(clicked()), this, SLOT(VoteAuto())); connect(pbPause, SIGNAL(clicked()), this, SLOT(VotePause())); connect(pbStop, SIGNAL(clicked()), this, SLOT(VoteStop())); connect(pbResult, SIGNAL(clicked()), this, SLOT(DoShowResults())); drawer = new DianVoteDrawer(); drawer->setWindowIcon(*windowIcon); drawer->setWindowTitle(tr("Result")); connect(pbClose, SIGNAL(clicked()), this->drawer, SLOT(close())); connect(this, SIGNAL(setOptionNum(int)), drawer->histgram, SLOT(SetOptionNums(int))); connect(this, SIGNAL(setOptionNum(int)), drawer->pie, SLOT(SetOptionNums(int))); connect(this, SIGNAL(clearDrawData()), drawer->histgram, SLOT(ClearData())); connect(this, SIGNAL(clearDrawData()), drawer->pie, SLOT(ClearData())); connect(this, SIGNAL(updateGraph(int)), drawer->histgram, SLOT(HandleData(int))); connect(this, SIGNAL(updateGraph(int)), drawer->pie, SLOT(HandleData(int))); LoadStyleSheet("Default"); // 记录初始化窗口大小 initSize = this->size(); this->setMaximumWidth(this->width()); this->setMaximumHeight(this->height() + 100); this->move(0, 0); // 创建Log文件,并打开,程序退出是关闭 VoteLog->open(QIODevice::WriteOnly | QIODevice::Append); // 初始化log记录链表 log = new QList< RevData* >(); }