void AdviceManager::HandleAdviceRequest( Client *advisee, csString message ) { // psserver->SendSystemInfo( advisee->GetClientNum(), "Sorry for the inconvenience, you cannot request advice right now. The advice system is under maintenaince and will be available after a server restart soon."); // return; if ( advisee->GetAdvisor() ) { psserver->SendSystemInfo( advisee->GetClientNum(), "You cannot request advice while you are an advisor. Lay down your advisor role using \"/advisor off\", then request advice."); return; } if ( advisors.GetSize() == 0 ) //No advisors are online { //Send back an message that there is no advisor online psserver->SendSystemInfo( advisee->GetClientNum(),"The world has no advisors at the moment. You may ask for further help on IRC or on our forums. You may also try to ask players around you for help with \"/tell <player name> <message>\"."); return; } // find existing Advicee in the List AdviceSession *activeSession = AdviseeList.Get(advisee->GetClientNum(), NULL); // Create an adviceSession if one doesn't exist and the message is valid if ( !activeSession ) { WordArray words(message); // Check to make sure the request is 'good' if ( words.GetCount() < 2 ) { psserver->SendSystemInfo( advisee->GetClientNum(), "An Advisor will need more information than this to help you, please include as much as you can in your request."); return; } Debug2( LOG_ANY, advisee->GetClientNum(), "Creating AdviceSession for %d", advisee->GetClientNum() ); activeSession = new AdviceSession( this, NULL, advisee, message ); AdviseeList.Put(activeSession->AdviseeClientNum, activeSession); // Advice is no longer pending. } else { // One unadvised unanswered question at a time if (!activeSession->GetAdvisor() && !activeSession->answered) { psserver->SendSystemError(advisee->GetClientNum(), "Please wait for an advisor to respond to your previous inquiry before asking another question."); return; } } //at this point active session will always be valid because it's either recovered from the //stored sessions or it was just created. // Create psAdviceRequestTimeoutGameEvent to timeout question. if (activeSession->timeoutEvent == NULL && activeSession->requestEvent == NULL) { psAdviceRequestTimeoutGameEvent *ev = new psAdviceRequestTimeoutGameEvent( this, ADVICE_QUESTION_TIMEOUT, advisee->GetActor(), activeSession ); activeSession->requestEvent = ev; psserver->GetEventManager()->Push(ev); } else { WordArray words(message); // Check to make sure the request is 'good' if ( words.GetCount() < 2 ) { psserver->SendSystemInfo(advisee->GetClientNum(), "An Advisor will need more information than this to help you, please include as much as you can in your request."); activeSession->answered = true; return; } if ( activeSession->timeoutEvent ) { activeSession->timeoutEvent->valid = false; } psAdviceSessionTimeoutGameEvent *ev = new psAdviceSessionTimeoutGameEvent( this, activeSession->answered?ADVICE_SESSION_TIMEOUT:ADVICE_SESSION_TIMEOUT/2, advisee->GetActor(), activeSession ); activeSession->timeoutEvent = ev; psserver->GetEventManager()->Push(ev); } //we set the session as unanswered as we have a new message. activeSession->answered = false; activeSession->lastRequest = message; csString buf; if ( activeSession->AdvisorClientNum != (uint32_t)-1 ) { // Source Client Name, Target Client Name, Message buf.Format("%s, %s, \"%s\"", advisee->GetName(), activeSession->GetAdvisor()->GetActor()->GetName(), message.GetData() ); psserver->GetLogCSV()->Write(CSV_ADVICE, buf); psChatMessage msgAdvisor( activeSession->AdvisorClientNum, 0, advisee->GetName(), 0, message , CHAT_ADVICE, false ); msgAdvisor.SendMessage(); // Send message to GM chars as well for (size_t i = 0; i < advisors.GetSize(); i++) { if (!advisors[i].GM || advisors[i].id == activeSession->AdvisorClientNum) continue; psChatMessage msgAdvisor( advisors[i].id, 0, advisee->GetName(), 0, message, CHAT_ADVICE, false); msgAdvisor.SendMessage(); } } else { // Source Client Name, Target Client Name, Message buf.Format("%s, %s, \"%s\"", advisee->GetName(), "All Advisors", message.GetData() ); psserver->GetLogCSV()->Write(CSV_ADVICE, buf); for (size_t i = 0; i < advisors.GetSize(); i++) { psChatMessage msgAdvisor( advisors[i].id, 0, advisee->GetName(), 0, message, CHAT_ADVICE, false); msgAdvisor.SendMessage(); } } psChatMessage msgChat( advisee->GetClientNum() , 0, advisee->GetName(), 0, message, CHAT_ADVICE, false); msgChat.SendMessage(); }
void AdviceManager::HandleAdviceResponse( Client *advisor, csString sAdvisee, csString message) { if ( !advisor->GetAdvisor() ) { psserver->SendSystemInfo(advisor->GetClientNum(),"You need to be an advisor to use this command."); return; } csString buf; // Source Client Name, Target Client Name, Message buf.Format("%s, %s, \"%s\"", advisor->GetName(), sAdvisee.GetData() , message.GetData()); psserver->GetLogCSV()->Write(CSV_ADVICE, buf); // Find Advisee Client by name if (sAdvisee.Length()) { sAdvisee = NormalizeCharacterName(sAdvisee); } Client *advisee = psserver->GetConnections()->Find(sAdvisee); if (!advisee) { // Create a new message to report TELL error and send // back to original person. csString sMsg("No player named "); sMsg += sAdvisee; sMsg += " is logged on to the system currently."; psserver->SendSystemError(advisor->GetClientNum(), sMsg); return; } // Can't allow you to advise yourself if ( advisee == advisor ) { psserver->SendSystemError(advisor->GetClientNum(), "You are not allowed to advise yourself. Please wait for another advisor."); return; } // find existing Advicee in the List AdviceSession key; key.AdviseeClientNum = advisee->GetClientNum(); AdviceSession *activeSession = AdviseeList.Get(advisee->GetClientNum(), NULL); if (!activeSession || (activeSession && ( !activeSession->requestEvent ) && ( activeSession->GetAdvisor() == NULL ) ) ) { psserver->SendSystemError(advisor->GetClientNum(), "%s has not requested help.", advisee->GetName()); return; } if (activeSession && ( activeSession->AdviseeClientNum != advisee->GetClientNum() ) ) { Debug2( LOG_ANY, advisee->GetClientNum(), "Grabbed wrong advisor session: %d", activeSession->AdviseeClientNum ); } if ( ( activeSession->GetAdvisor() != NULL ) && ( activeSession->AdvisorClientNum != advisor->GetClientNum() ) ) { psserver->SendSystemError(advisor->GetClientNum(), "%s is being advised already, thank you.", advisee->GetName()); return; } if ( message.Length() == 0 && activeSession->status == SESSION_STATUS_UNKNOWN ) // advisor is claiming a session { // check to make sure advisor has only one claimed session. AdviceSession *loopSession; csHash< AdviceSession* >::GlobalIterator loop( AdviseeList.GetIterator() ); while(loop.HasNext()) { loopSession = loop.Next(); if (activeSession->status == SESSION_STATUS_CLAIMED && loopSession->GetAdvisor() == advisor ) { psserver->SendSystemInfo(advisor->GetClientNum(), "You cannot have two messengers waiting for you at the same time, please answer %s's request first." , loopSession->adviseeName.GetData() ); return; } } activeSession->SetAdvisor( advisor ); psserver->SendSystemInfo(advisee->GetClientNum(), "An advisor is preparing an answer to your question, please be patient."); psserver->SendSystemInfo(advisor->GetClientNum(), "You have claimed the session with %s. Please provide an answer." , advisee->GetName() ); for (size_t i = 0; i < advisors.GetSize(); i++) { if ( advisors[i].id != activeSession->AdvisorClientNum ) { psserver->SendSystemInfo(advisors[i].id, "%s has proclaimed they know the answer to %s's question.", advisor->GetName(), advisee->GetName() ); } } activeSession->status = SESSION_STATUS_CLAIMED; } else { if (message.IsEmpty()) { psserver->SendSystemInfo(advisor->GetClientNum(), "Please enter the advice you wish to give."); return; } psChatMessage msgChat(activeSession->AdviseeClientNum, 0, advisor->GetName(), advisee->GetName(), message ,CHAT_ADVISOR,false); if ( activeSession->GetAdvisor() == NULL || activeSession->status != SESSION_STATUS_OWNED ) { // Check to make sure the advice is 'good' // if ( message.Length() < 20 ) // { // psserver->SendSystemInfo(advisor->GetClientNum(), "Please be more specific when answering questions. Your advice has been ignored."); // return; // } //activeSession->AdvisorClientNum = me->clientnum; activeSession->SetAdvisor( advisor ); advisor->IncrementAdvisorPoints(activeSession->advisorPoints); psserver->CharacterLoader.SaveCharacterData( advisor->GetCharacterData(), advisor->GetActor(), true ); // Send Confirmation to advisor psserver->SendSystemInfo( advisor->GetClientNum(), "You are now advising %s.",advisee->GetName()); // Send Confirmation to all other advisors so they know they lost this one. for (size_t i = 0; i < advisors.GetSize(); i++) { if ( advisors[i].id != activeSession->AdvisorClientNum ) { psserver->SendSystemInfo( advisors[i].id, "%s has been assigned to %s.", advisee->GetName(), advisor->GetName() ); if ( advisors[i].GM ) continue; msgChat.msg->clientnum = advisors[i].id; msgChat.SendMessage(); } } activeSession->status = SESSION_STATUS_OWNED; } if ( activeSession->requestEvent ) activeSession->requestEvent->valid = false; // This keeps the cancellation timeout from firing. activeSession->answered = true; // Send Message to Advisee msgChat.msg->clientnum = activeSession->AdviseeClientNum; msgChat.SendMessage(); // Send Message to advisor msgChat.msg->clientnum = activeSession->AdvisorClientNum; msgChat.SendMessage(); // Send message to GM chars as well for (size_t i = 0; i < advisors.GetSize(); i++) { if (!advisors[i].GM || advisors[i].id == activeSession->AdvisorClientNum) continue; msgChat.msg->clientnum = advisors[i].id; msgChat.SendMessage(); } } // Add timeout for Advisor-Advisee relationship // this will allow later questions by the same client to go to a different advisor // spreading the wealth and burden amongst all ;) if ( activeSession->timeoutEvent ) { activeSession->timeoutEvent->valid = false; } psAdviceSessionTimeoutGameEvent *ev = new psAdviceSessionTimeoutGameEvent( this, activeSession->answered?ADVICE_SESSION_TIMEOUT:ADVICE_SESSION_TIMEOUT/2, advisee->GetActor(), activeSession ); activeSession->timeoutEvent = ev; psserver->GetEventManager()->Push(ev); }
void AtlantikNetwork::processNode(QDomNode n) { QDomAttr a; for ( ; !n.isNull() ; n = n.nextSibling() ) { QDomElement e = n.toElement(); if(!e.isNull()) { if (e.tagName() == "server") { a = e.attributeNode( QString("version") ); if ( !a.isNull() ) m_serverVersion = a.value(); emit receivedHandshake(); } else if (e.tagName() == "msg") { a = e.attributeNode(QString("type")); if (!a.isNull()) { if (a.value() == "error") emit msgError(e.attributeNode(QString("value")).value()); else if (a.value() == "info") emit msgInfo(e.attributeNode(QString("value")).value()); else if (a.value() == "chat") emit msgChat(e.attributeNode(QString("author")).value(), e.attributeNode(QString("value")).value()); } } else if (e.tagName() == "display") { int estateId = -1; a = e.attributeNode(QString("estateid")); if (!a.isNull()) { estateId = a.value().toInt(); Estate *estate; estate = m_atlanticCore->findEstate(a.value().toInt()); emit displayDetails(e.attributeNode(QString("text")).value(), e.attributeNode(QString("cleartext")).value().toInt(), e.attributeNode(QString("clearbuttons")).value().toInt(), estate); bool hasButtons = false; for( QDomNode nButtons = n.firstChild() ; !nButtons.isNull() ; nButtons = nButtons.nextSibling() ) { QDomElement eButton = nButtons.toElement(); if (!eButton.isNull() && eButton.tagName() == "button") { emit addCommandButton(eButton.attributeNode(QString("command")).value(), eButton.attributeNode(QString("caption")).value(), eButton.attributeNode(QString("enabled")).value().toInt()); hasButtons = true; } } if (!hasButtons) emit addCloseButton(); } } else if (e.tagName() == "client") { a = e.attributeNode(QString("playerid")); if (!a.isNull()) m_playerId = a.value().toInt(); a = e.attributeNode(QString("cookie")); if (!a.isNull()) emit clientCookie(a.value()); } else if (e.tagName() == "configupdate") { int configId = -1; a = e.attributeNode(QString("configid")); if (!a.isNull()) { configId = a.value().toInt(); ConfigOption *configOption; if (!(configOption = m_atlanticCore->findConfigOption(configId))) configOption = m_atlanticCore->newConfigOption( configId ); a = e.attributeNode(QString("name")); if (configOption && !a.isNull()) configOption->setName(a.value()); a = e.attributeNode(QString("description")); if (configOption && !a.isNull()) configOption->setDescription(a.value()); a = e.attributeNode(QString("edit")); if (configOption && !a.isNull()) configOption->setEdit(a.value().toInt()); a = e.attributeNode(QString("value")); if (configOption && !a.isNull()) configOption->setValue(a.value()); if (configOption) configOption->update(); } int gameId = -1; a = e.attributeNode(QString("gameid")); if (!a.isNull()) { gameId = a.value().toInt(); for( QDomNode nOptions = n.firstChild() ; !nOptions.isNull() ; nOptions = nOptions.nextSibling() ) { QDomElement eOption = nOptions.toElement(); if (!eOption.isNull() && eOption.tagName() == "option") emit gameOption(eOption.attributeNode(QString("title")).value(), eOption.attributeNode(QString("type")).value(), eOption.attributeNode(QString("value")).value(), eOption.attributeNode(QString("edit")).value(), eOption.attributeNode(QString("command")).value()); } emit endConfigUpdate(); } } else if (e.tagName() == "deletegame") { a = e.attributeNode(QString("gameid")); if (!a.isNull()) { int gameId = a.value().toInt(); Game *game = m_atlanticCore->findGame(gameId); if (game) m_atlanticCore->removeGame(game); } } else if (e.tagName() == "gameupdate") { int gameId = -1; a = e.attributeNode(QString("gameid")); if (!a.isNull()) { gameId = a.value().toInt(); Player *playerSelf = m_atlanticCore->playerSelf(); if ( playerSelf && playerSelf->game() ) kdDebug() << "gameupdate for " << QString::number(gameId) << " with playerSelf in game " << QString::number(playerSelf->game()->id()) << endl; else kdDebug() << "gameupdate for " << QString::number(gameId) << endl; Game *game = 0; if (gameId == -1) { a = e.attributeNode(QString("gametype")); if ( !a.isNull() && !(game = m_atlanticCore->findGame(a.value())) ) game = m_atlanticCore->newGame(gameId, a.value()); } else if (!(game = m_atlanticCore->findGame(gameId))) game = m_atlanticCore->newGame(gameId); a = e.attributeNode(QString("canbejoined")); if (game && !a.isNull()) game->setCanBeJoined(a.value().toInt()); a = e.attributeNode(QString("description")); if (game && !a.isNull()) game->setDescription(a.value()); a = e.attributeNode(QString("name")); if (game && !a.isNull()) game->setName(a.value()); a = e.attributeNode(QString("players")); if (game && !a.isNull()) game->setPlayers(a.value().toInt()); a = e.attributeNode(QString("master")); if (game && !a.isNull()) { // Ensure setMaster succeeds by creating player if necessary Player *player = m_atlanticCore->findPlayer( a.value().toInt() ); if ( !player ) player = m_atlanticCore->newPlayer( a.value().toInt() ); game->setMaster( player ); } QString status = e.attributeNode(QString("status")).value(); if ( m_serverVersion.left(4) == "0.9." || (playerSelf && playerSelf->game() == game) ) { if (status == "config") emit gameConfig(); else if (status == "init") emit gameInit(); else if (status == "run") emit gameRun(); else if (status == "end") emit gameEnd(); } if (game) game->update(); } } else if (e.tagName() == "deleteplayer") { a = e.attributeNode(QString("playerid")); if (!a.isNull()) { int playerId = a.value().toInt(); Player *player = m_atlanticCore->findPlayer(playerId); if (player) m_atlanticCore->removePlayer(player); } } else if (e.tagName() == "playerupdate") { int playerId = -1; a = e.attributeNode(QString("playerid")); if (!a.isNull()) { playerId = a.value().toInt(); Player *player; if (!(player = m_atlanticCore->findPlayer(playerId))) player = m_atlanticCore->newPlayer( playerId, (m_playerId == playerId) ); // Update player name a = e.attributeNode(QString("name")); if (player && !a.isNull()) player->setName(a.value()); // Update player game a = e.attributeNode(QString("game")); if (player && !a.isNull()) { int gameId = a.value().toInt(); if (gameId == -1) player->setGame( 0 ); else { // Ensure setGame succeeds by creating game if necessary Game *game = m_atlanticCore->findGame(a.value().toInt()); if (!game) game = m_atlanticCore->newGame(a.value().toInt()); // player->setGame( game ); } } // Update player host a = e.attributeNode(QString("host")); if (player && !a.isNull()) player->setHost(a.value()); // Update player image/token a = e.attributeNode(QString("image")); if (player && !a.isNull()) player->setImage(a.value()); // Update player money a = e.attributeNode(QString("money")); if (player && !a.isNull()) player->setMoney(a.value().toInt()); a = e.attributeNode(QString("bankrupt")); if (player && !a.isNull()) player->setBankrupt(a.value().toInt()); a = e.attributeNode(QString("hasdebt")); if (player && !a.isNull()) player->setHasDebt(a.value().toInt()); a = e.attributeNode(QString("hasturn")); if (player && !a.isNull()) player->setHasTurn(a.value().toInt()); // Update whether player can roll a = e.attributeNode(QString("can_roll")); if (player && !a.isNull()) player->setCanRoll(a.value().toInt()); // Update whether player can buy a = e.attributeNode(QString("can_buyestate")); if (player && !a.isNull()) player->setCanBuy(a.value().toInt()); // Update whether player can auction a = e.attributeNode(QString("canauction")); if (player && !a.isNull()) player->setCanAuction(a.value().toInt()); // Update whether player can use a card a = e.attributeNode(QString("canusecard")); if (player && !a.isNull()) player->setCanUseCard(a.value().toInt()); // Update whether player is jailed a = e.attributeNode(QString("jailed")); if (player && !a.isNull()) { player->setInJail(a.value().toInt()); // TODO: emit signal with player ptr so board can setText and display something } // Update player location a = e.attributeNode(QString("location")); if (!a.isNull()) { m_playerLocationMap[player] = a.value().toInt(); bool directMove = false; Estate *estate = m_atlanticCore->findEstate(a.value().toInt()); a = e.attributeNode(QString("directmove")); if (!a.isNull()) directMove = a.value().toInt(); if (player && estate) { if (directMove) player->setLocation(estate); else player->setDestination(estate); } } if (player) player->update(); } } else if (e.tagName() == "estategroupupdate") { a = e.attributeNode(QString("groupid")); if (!a.isNull()) { int groupId = a.value().toInt(); EstateGroup *estateGroup = 0; bool b_newEstateGroup = false; if (!(estateGroup = m_atlanticCore->findEstateGroup(groupId))) { // Create EstateGroup object estateGroup = m_atlanticCore->newEstateGroup(a.value().toInt()); b_newEstateGroup = true; } a = e.attributeNode(QString("name")); if (estateGroup && !a.isNull()) estateGroup->setName(a.value()); // Emit signal so GUI implementations can create view(s) // TODO: port to atlanticcore and create view there if (estateGroup) { if (b_newEstateGroup) emit newEstateGroup(estateGroup); estateGroup->update(); } } } else if (e.tagName() == "estateupdate") { int estateId = -1; a = e.attributeNode(QString("estateid")); if (!a.isNull()) { estateId = a.value().toInt(); Estate *estate = 0; bool b_newEstate = false; // FIXME: allow any estateId, GUI should not use it to determin its geometry if (estateId >= 0 && estateId < 100 && !(estate = m_atlanticCore->findEstate(a.value().toInt()))) { // Create estate object estate = m_atlanticCore->newEstate(estateId); b_newEstate = true; QObject::connect(estate, SIGNAL(estateToggleMortgage(Estate *)), this, SLOT(estateToggleMortgage(Estate *))); QObject::connect(estate, SIGNAL(estateHouseBuy(Estate *)), this, SLOT(estateHouseBuy(Estate *))); QObject::connect(estate, SIGNAL(estateHouseSell(Estate *)), this, SLOT(estateHouseSell(Estate *))); QObject::connect(estate, SIGNAL(newTrade(Player *)), this, SLOT(newTrade(Player *))); // Players without estate should get one Player *player = 0; QPtrList<Player> playerList = m_atlanticCore->players(); for (QPtrListIterator<Player> it(playerList); (player = *it) ; ++it) if (m_playerLocationMap[player] == estate->id()) player->setLocation(estate); } a = e.attributeNode(QString("name")); if (estate && !a.isNull()) estate->setName(a.value()); a = e.attributeNode(QString("color")); if (estate && !a.isNull() && !a.value().isEmpty()) estate->setColor(a.value()); a = e.attributeNode(QString("bgcolor")); if (estate && !a.isNull()) estate->setBgColor(a.value()); a = e.attributeNode(QString("owner")); Player *player = m_atlanticCore->findPlayer(a.value().toInt()); if (estate && !a.isNull()) estate->setOwner(player); a = e.attributeNode(QString("houses")); if (estate && !a.isNull()) estate->setHouses(a.value().toInt()); a = e.attributeNode(QString("mortgaged")); if (estate && !a.isNull()) estate->setIsMortgaged(a.value().toInt()); a = e.attributeNode(QString("group")); if (!a.isNull()) { EstateGroup *estateGroup = m_atlanticCore->findEstateGroup(a.value().toInt()); if (estate) estate->setEstateGroup(estateGroup); } a = e.attributeNode(QString("can_toggle_mortgage")); if (estate && !a.isNull()) estate->setCanToggleMortgage(a.value().toInt()); a = e.attributeNode(QString("can_be_owned")); if (estate && !a.isNull()) estate->setCanBeOwned(a.value().toInt()); a = e.attributeNode(QString("can_buy_houses")); if (estate && !a.isNull()) estate->setCanBuyHouses(a.value().toInt()); a = e.attributeNode(QString("can_sell_houses")); if (estate && !a.isNull()) estate->setCanSellHouses(a.value().toInt()); a = e.attributeNode(QString("price")); if (estate && !a.isNull()) estate->setPrice(a.value().toInt()); a = e.attributeNode(QString("houseprice")); if (estate && !a.isNull()) estate->setHousePrice(a.value().toInt()); a = e.attributeNode(QString("sellhouseprice")); if (estate && !a.isNull()) estate->setHouseSellPrice(a.value().toInt()); a = e.attributeNode(QString("mortgageprice")); if (estate && !a.isNull()) estate->setMortgagePrice(a.value().toInt()); a = e.attributeNode(QString("unmortgageprice")); if (estate && !a.isNull()) estate->setUnmortgagePrice(a.value().toInt()); a = e.attributeNode(QString("money")); if (estate && !a.isNull()) estate->setMoney(a.value().toInt()); // Emit signal so GUI implementations can create view(s) // TODO: port to atlanticcore and create view there if (estate) { if (b_newEstate) emit newEstate(estate); estate->update(); } } }