Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ////////////////////////////////////////////////////////////////////////
- // OpenTibia - an opensource roleplaying game
- ////////////////////////////////////////////////////////////////////////
- // 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, either version 3 of the License, or
- // (at your option) any later version.
- //
- // 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, see <http://www.gnu.org/licenses/>.
- ////////////////////////////////////////////////////////////////////////
- #include "otpch.h"
- #include "talkaction.h"
- #include <boost/config.hpp>
- #include <boost/version.hpp>
- #include "iologindata.h"
- #include "ioban.h"
- #include "player.h"
- #include "npc.h"
- #include "house.h"
- #include "town.h"
- #include "teleport.h"
- #include "status.h"
- #include "textlogger.h"
- #ifdef __ENABLE_SERVER_DIAGNOSTIC__
- #include "outputmessage.h"
- #include "connection.h"
- #include "admin.h"
- #include "manager.h"
- #include "protocollogin.h"
- #include "protocolold.h"
- #endif
- #include "configmanager.h"
- #include "game.h"
- #include "chat.h"
- #include "tools.h"
- extern ConfigManager g_config;
- extern Game g_game;
- extern Chat g_chat;
- extern TalkActions* g_talkActions;
- TalkActions::TalkActions():
- m_interface("TalkAction Interface")
- {
- m_interface.initState();
- defaultTalkAction = NULL;
- }
- TalkActions::~TalkActions()
- {
- clear();
- }
- void TalkActions::clear()
- {
- for(TalkActionsMap::iterator it = talksMap.begin(); it != talksMap.end(); ++it)
- delete it->second;
- talksMap.clear();
- m_interface.reInitState();
- delete defaultTalkAction;
- defaultTalkAction = NULL;
- }
- Event* TalkActions::getEvent(const std::string& nodeName)
- {
- if(asLowerCaseString(nodeName) == "talkaction")
- return new TalkAction(&m_interface);
- return NULL;
- }
- bool TalkActions::registerEvent(Event* event, xmlNodePtr p, bool override)
- {
- TalkAction* talkAction = dynamic_cast<TalkAction*>(event);
- if(!talkAction)
- return false;
- std::string strValue;
- if(readXMLString(p, "default", strValue) && booleanString(strValue))
- {
- if(!defaultTalkAction)
- defaultTalkAction = talkAction;
- else if(override)
- {
- delete defaultTalkAction;
- defaultTalkAction = talkAction;
- }
- else
- std::cout << "[Warning - TalkAction::registerEvent] You cannot define more than one default talkAction." << std::endl;
- return true;
- }
- if(!readXMLString(p, "separator", strValue) || strValue.empty())
- strValue = ";";
- StringVec strVector = explodeString(talkAction->getWords(), strValue);
- for(StringVec::iterator it = strVector.begin(); it != strVector.end(); ++it)
- {
- trimString(*it);
- talkAction->setWords(*it);
- if(talksMap.find(*it) != talksMap.end())
- {
- if(!override)
- {
- std::clog << "[Warning - TalkAction::registerEvent] Duplicate registered talkaction with words: " << (*it) << std::endl;
- continue;
- }
- else
- delete talksMap[(*it)];
- }
- talksMap[(*it)] = new TalkAction(talkAction);
- }
- delete talkAction;
- return true;
- }
- bool TalkActions::onPlayerSay(Creature* creature, uint16_t channelId, const std::string& words, bool ignoreAccess, ProtocolGame* pg)
- {
- std::string cmd[TALKFILTER_LAST] = words, param[TALKFILTER_LAST] = "";
- std::string::size_type loc = words.find('"', 0);
- if(loc != std::string::npos)
- {
- cmd[TALKFILTER_QUOTATION] = std::string(words, 0, loc);
- param[TALKFILTER_QUOTATION] = std::string(words, (loc + 1), (words.size() - (loc - 1)));
- trimString(cmd[TALKFILTER_QUOTATION]);
- }
- loc = words.find(" ", 0);
- if(loc != std::string::npos)
- {
- cmd[TALKFILTER_WORD] = std::string(words, 0, loc);
- param[TALKFILTER_WORD] = std::string(words, (loc + 1), (words.size() - (loc - 1)));
- std::string::size_type spaceLoc = words.find(" ", ++loc);
- if(spaceLoc != std::string::npos)
- {
- cmd[TALKFILTER_WORD_SPACED] = std::string(words, 0, spaceLoc);
- param[TALKFILTER_WORD_SPACED] = std::string(words, (spaceLoc + 1), (words.size() - (spaceLoc - 1)));
- }
- }
- TalkAction* talkAction = NULL;
- for(TalkActionsMap::iterator it = talksMap.begin(); it != talksMap.end(); ++it)
- {
- if(it->first == cmd[it->second->getFilter()] || (!it->second->isSensitive() &&
- !strcasecmp(it->first.c_str(), cmd[it->second->getFilter()].c_str())))
- {
- talkAction = it->second;
- break;
- }
- }
- if(!talkAction && defaultTalkAction)
- talkAction = defaultTalkAction;
- if(pg != NULL && pg->getIsCast() && creature->getPlayer())
- {
- Player* p = creature->getPlayer();
- if(pg != NULL && words[0] == '/' && pg->getIsCast())
- {
- if(words.substr(1, 4) == "name")
- {
- if(words.length() > 6)
- {
- std::string param = words.substr(6);
- trimString(param);
- if(param.length() > 10)
- {
- //pg->sendChannelMessage("[Chat System]", "This name is too long. (Max 8. letters)", MSG_STATUS_DEFAULT, privchannel->getId());
- pg->publicSendMessage(p, SPEAK_PRIVATE, "This name is too long.");
- return true;
- }
- else if(param.length() <= 2)
- {
- //pg->sendChannelMessage("[Chat System]", "This name is too short. (Min 3. letters)", MSG_STATUS_DEFAULT, privchannel->getId());
- pg->publicSendMessage(p, SPEAK_PRIVATE, "This name is too short.");
- return true;
- }
- if(!isValidName(param, false))
- {
- //pg->sendChannelMessage("[Chat System]", "This name contains invalid characters.", MSG_STATUS_DEFAULT, privchannel->getId());
- pg->publicSendMessage(p, SPEAK_PRIVATE, "This name is invalid.");
- return true;
- }
- for(AutoList<ProtocolGame>::iterator it = Player::cSpectators.begin(); it != Player::cSpectators.end(); ++it)
- if(it->second->getViewerName() == param && it->second->getPlayer() == p)
- {
- pg->publicSendMessage(p, SPEAK_PRIVATE, "This name is already in use.");
- return true;
- }
- PrivateChatChannel* channel = g_chat.getPrivateChannel(p);
- if(channel)
- {
- channel->talk("", SPEAK_CHANNEL_RA, (pg->getViewerName() + " changed nick to " + param));
- }
- pg->setViewerName(param);
- pg->publicSendMessage(p, SPEAK_PRIVATE, "You changed your nick to " + param);
- }
- else
- pg->publicSendMessage(p, SPEAK_PRIVATE, "Invalid param.");
- }
- else if(words.substr(1, 4) == "list")
- {
- PlayerCast pc = p->getCast();
- std::stringstream ss, sl;
- ss << Player::cSpectators.size() << " spectators: ";
- bool first = true;
- for(AutoList<ProtocolGame>::iterator it = Player::cSpectators.begin(); it != Player::cSpectators.end(); ++it)
- {
- if(it->second->getPlayer() == p)
- {
- sl.clear();
- sl << ss;
- if(first)
- first = false;
- else
- ss << ", ";
- ss << it->second->getViewerName();
- if(ss.str().length() > 250)
- {
- ss.clear();
- ss << sl << "...";
- break;
- }
- }
- }
- std::string out = ss.str();
- pg->publicSendMessage(p, SPEAK_PRIVATE, out);
- }
- else if(words.substr(1, 4) == "help")
- {
- PlayerCast pc = p->getCast();
- std::stringstream ss, sl;
- ss << "Commands list: " << " " << "\n/help - print this message" << " " << "\n/list - print spectators list" << " " << "\n/name - change your name" << " " << "\nMore commands are in builds. Will be able in few days.";
- std::string out = ss.str();
- pg->publicSendMessage(p, SPEAK_PRIVATE, out);
- }
- return true;
- }
- return false;
- }
- if(!talkAction || (talkAction->getChannel() != -1 && talkAction->getChannel() != channelId))
- return false;
- Player* player = creature->getPlayer();
- StringVec exceptions = talkAction->getExceptions();
- if(player && ((!ignoreAccess && std::find(exceptions.begin(), exceptions.end(), asLowerCaseString(
- player->getName())) == exceptions.end() && talkAction->getAccess() > player->getAccess())
- || player->isAccountManager()))
- {
- if(player->hasCustomFlag(PlayerCustomFlag_GamemasterPrivileges))
- {
- player->sendTextMessage(MSG_STATUS_SMALL, "You cannot execute this talkaction.");
- return true;
- }
- return false;
- }
- if(talkAction->isLogged())
- {
- if(player)
- player->sendTextMessage(MSG_STATUS_CONSOLE_RED, words.c_str());
- Logger::getInstance()->eFile("talkactions/" + creature->getName() + ".log", words, true);
- }
- if(talkAction->isScripted())
- return talkAction->executeSay(creature, cmd[talkAction->getFilter()], param[talkAction->getFilter()], channelId);
- if(TalkFunction* function = talkAction->getFunction())
- return function(creature, cmd[talkAction->getFilter()], param[talkAction->getFilter()]);
- return false;
- }
- TalkAction::TalkAction(LuaInterface* _interface):
- Event(_interface)
- {
- m_function = NULL;
- m_filter = TALKFILTER_WORD;
- m_access = 0;
- m_channel = -1;
- m_logged = m_hidden = false;
- m_sensitive = true;
- }
- TalkAction::TalkAction(const TalkAction* copy):
- Event(copy)
- {
- m_words = copy->m_words;
- m_function = copy->m_function;
- m_filter = copy->m_filter;
- m_access = copy->m_access;
- m_channel = copy->m_channel;
- m_logged = copy->m_logged;
- m_hidden = copy->m_hidden;
- m_sensitive = copy->m_sensitive;
- m_exceptions = copy->m_exceptions;
- }
- bool TalkAction::configureEvent(xmlNodePtr p)
- {
- std::string strValue;
- if(readXMLString(p, "words", strValue))
- m_words = strValue;
- else if(!readXMLString(p, "default", strValue) || !booleanString(strValue))
- {
- std::clog << "[Error - TalkAction::configureEvent] No words for TalkAction." << std::endl;
- return false;
- }
- if(readXMLString(p, "filter", strValue))
- {
- std::string tmpStrValue = asLowerCaseString(strValue);
- if(tmpStrValue == "quotation")
- m_filter = TALKFILTER_QUOTATION;
- else if(tmpStrValue == "word")
- m_filter = TALKFILTER_WORD;
- else if(tmpStrValue == "word-spaced")
- m_filter = TALKFILTER_WORD_SPACED;
- else
- std::clog << "[Warning - TalkAction::configureEvent] Unknown filter for TalkAction: " << strValue << ", using default." << std::endl;
- }
- int32_t intValue;
- if(readXMLInteger(p, "access", intValue))
- m_access = intValue;
- if(readXMLInteger(p, "channel", intValue))
- m_channel = intValue;
- if(readXMLString(p, "log", strValue) || readXMLString(p, "logged", strValue))
- m_logged = booleanString(strValue);
- if(readXMLString(p, "hide", strValue) || readXMLString(p, "hidden", strValue))
- m_hidden = booleanString(strValue);
- if(readXMLString(p, "case-sensitive", strValue) || readXMLString(p, "casesensitive", strValue) || readXMLString(p, "sensitive", strValue))
- m_sensitive = booleanString(strValue);
- if(readXMLString(p, "exception", strValue))
- m_exceptions = explodeString(asLowerCaseString(strValue), ";");
- return true;
- }
- bool TalkAction::loadFunction(const std::string& functionName)
- {
- m_functionName = asLowerCaseString(functionName);
- if(m_functionName == "housebuy")
- m_function = houseBuy;
- else if(m_functionName == "housesell")
- m_function = houseSell;
- else if(m_functionName == "housekick")
- m_function = houseKick;
- else if(m_functionName == "housedoorlist")
- m_function = houseDoorList;
- else if(m_functionName == "houseguestlist")
- m_function = houseGuestList;
- else if(m_functionName == "housesubownerlist")
- m_function = houseSubOwnerList;
- else if(m_functionName == "guildjoin")
- m_function = guildJoin;
- else if(m_functionName == "guildcreate")
- m_function = guildCreate;
- else if(m_functionName == "thingproporties")
- m_function = thingProporties;
- else if(m_functionName == "banishmentinfo")
- m_function = banishmentInfo;
- else if(m_functionName == "diagnostics")
- m_function = diagnostics;
- else if(m_functionName == "addskill")
- m_function = addSkill;
- else if(m_functionName == "ghost")
- m_function = ghost;
- else if(m_functionName == "software")
- m_function = software;
- else
- {
- std::clog << "[Warning - TalkAction::loadFunction] Function \"" << m_functionName << "\" does not exist." << std::endl;
- return false;
- }
- m_scripted = EVENT_SCRIPT_FALSE;
- return true;
- }
- int32_t TalkAction::executeSay(Creature* creature, const std::string& words, std::string param, uint16_t channel)
- {
- //onSay(cid, words, param, channel)
- if(m_interface->reserveEnv())
- {
- trimString(param);
- ScriptEnviroment* env = m_interface->getEnv();
- if(m_scripted == EVENT_SCRIPT_BUFFER)
- {
- env->setRealPos(creature->getPosition());
- std::stringstream scriptstream;
- scriptstream << "local cid = " << env->addThing(creature) << std::endl;
- scriptstream << "local words = \"" << words << "\"" << std::endl;
- scriptstream << "local param = \"" << param << "\"" << std::endl;
- scriptstream << "local channel = " << channel << std::endl;
- scriptstream << m_scriptData;
- bool result = true;
- if(m_interface->loadBuffer(scriptstream.str()))
- {
- lua_State* L = m_interface->getState();
- result = m_interface->getGlobalBool(L, "_result", true);
- }
- m_interface->releaseEnv();
- return result;
- }
- else
- {
- #ifdef __DEBUG_LUASCRIPTS__
- char desc[125];
- sprintf(desc, "%s - %s- %s", creature->getName().c_str(), words.c_str(), param.c_str());
- env->setEvent(desc);
- #endif
- env->setScriptId(m_scriptId, m_interface);
- env->setRealPos(creature->getPosition());
- lua_State* L = m_interface->getState();
- m_interface->pushFunction(m_scriptId);
- lua_pushnumber(L, env->addThing(creature));
- lua_pushstring(L, words.c_str());
- lua_pushstring(L, param.c_str());
- lua_pushnumber(L, channel);
- bool result = m_interface->callFunction(4);
- m_interface->releaseEnv();
- return result;
- }
- }
- else
- {
- std::clog << "[Error - TalkAction::executeSay] Call stack overflow." << std::endl;
- return 0;
- }
- }
- bool TalkAction::houseBuy(Creature* creature, const std::string&, const std::string&)
- {
- Player* player = creature->getPlayer();
- if(!player || !g_config.getBool(ConfigManager::HOUSE_BUY_AND_SELL))
- return false;
- const Position& pos = getNextPosition(player->getDirection(), player->getPosition());
- Tile* tile = g_game.getTile(pos);
- if(!tile)
- {
- player->sendCancel("You have to be looking at door of flat you would like to purchase.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- HouseTile* houseTile = tile->getHouseTile();
- if(!houseTile)
- {
- player->sendCancel("You have to be looking at door of flat you would like to purchase.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- House* house = houseTile->getHouse();
- if(!house)
- {
- player->sendCancel("You have to be looking at door of flat you would like to purchase.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(!house->getDoorByPosition(pos))
- {
- player->sendCancel("You have to be looking at door of flat you would like to purchase.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(!house->isGuild())
- {
- if(Houses::getInstance()->getHouseByPlayerId(player->getGUID()))
- {
- player->sendCancel("You already rent another house.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- uint16_t accountHouses = g_config.getNumber(ConfigManager::HOUSES_PER_ACCOUNT);
- if(accountHouses > 0 && Houses::getInstance()->getHousesCount(player->getAccount()) >= accountHouses)
- {
- char buffer[80];
- sprintf(buffer, "You may own only %d house%s per account.", accountHouses, (accountHouses != 1 ? "s" : ""));
- player->sendCancel(buffer);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(g_config.getBool(ConfigManager::HOUSE_NEED_PREMIUM) && !player->isPremium())
- {
- player->sendCancelMessage(RET_YOUNEEDPREMIUMACCOUNT);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- uint32_t levelToBuyHouse = g_config.getNumber(ConfigManager::LEVEL_TO_BUY_HOUSE);
- if(player->getLevel() < levelToBuyHouse)
- {
- char buffer[90];
- sprintf(buffer, "You have to be at least Level %d to purchase a house.", levelToBuyHouse);
- player->sendCancel(buffer);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- }
- else
- {
- if(!player->getGuildId() || player->getGuildLevel() != GUILDLEVEL_LEADER)
- {
- player->sendCancel("You have to be at least a guild leader to purchase a hall.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(Houses::getInstance()->getHouseByGuildId(player->getGuildId()))
- {
- player->sendCancel("Your guild rents already another hall.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- }
- if(house->getOwner())
- {
- player->sendCancel("This flat is already owned by someone else.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(player->__getItemTypeCount(2157, -1) < house->getPrice() || !g_game.removeItemOfType(player, 2157, house->getPrice(), -1))
- {
- player->sendCancel("You do not have enough gold nuggets.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- house->setOwnerEx(player->getGUID(), true);
- std::string ret = "You have successfully bought this ";
- if(house->isGuild())
- ret += "hall";
- else
- ret += "house";
- ret += ", remember to leave money at ";
- if(house->isGuild())
- ret += "guild owner ";
- if(g_config.getBool(ConfigManager::BANK_SYSTEM))
- ret += "bank or ";
- ret += "depot of this town for rent.";
- player->sendTextMessage(MSG_INFO_DESCR, ret.c_str());
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_BLUE);
- return false;
- }
- bool TalkAction::houseSell(Creature* creature, const std::string&, const std::string& param)
- {
- Player* player = creature->getPlayer();
- if(!player || !g_config.getBool(ConfigManager::HOUSE_BUY_AND_SELL))
- return false;
- House* house = Houses::getInstance()->getHouseByPlayerId(player->getGUID());
- if(!house && (!player->getGuildId() || !(house = Houses::getInstance()->getHouseByGuildId(player->getGuildId()))))
- {
- player->sendCancel("You do not rent any flat.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(house->isGuild() && player->getGuildLevel() != GUILDLEVEL_LEADER)
- {
- player->sendCancel("You have to be at least a guild leader to sell this hall.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- Player* tradePartner = NULL;
- ReturnValue ret = g_game.getPlayerByNameWildcard(param, tradePartner);
- if(ret != RET_NOERROR)
- {
- player->sendCancelMessage(ret);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(tradePartner == player)
- {
- player->sendCancel("You cannot trade with yourself.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(!house->isGuild())
- {
- if(Houses::getInstance()->getHouseByPlayerId(tradePartner->getGUID()))
- {
- player->sendCancel("Trade player already rents another house.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- uint16_t housesPerAccount = g_config.getNumber(ConfigManager::HOUSES_PER_ACCOUNT);
- if(housesPerAccount > 0 && Houses::getInstance()->getHousesCount(tradePartner->getAccount()) >= housesPerAccount)
- {
- char buffer[100];
- sprintf(buffer, "Trade player has reached limit of %d house%s per account.", housesPerAccount, (housesPerAccount != 1 ? "s" : ""));
- player->sendCancel(buffer);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(!tradePartner->isPremium() && !g_config.getBool(ConfigManager::HOUSE_NEED_PREMIUM))
- {
- player->sendCancel("Trade player does not have a premium account.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- uint32_t levelToBuyHouse = g_config.getNumber(ConfigManager::LEVEL_TO_BUY_HOUSE);
- if(tradePartner->getLevel() < levelToBuyHouse)
- {
- char buffer[100];
- sprintf(buffer, "Trade player has to be at least Level %d to buy house.", levelToBuyHouse);
- player->sendCancel(buffer);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- }
- else
- {
- if(!tradePartner->getGuildId() || tradePartner->getGuildLevel() != GUILDLEVEL_LEADER)
- {
- player->sendCancel("Trade player has to be at least a guild leader to buy a hall.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(Houses::getInstance()->getHouseByGuildId(tradePartner->getGuildId()))
- {
- player->sendCancel("Trade player's guild already rents another hall.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- }
- if(!Position::areInRange<3,3,0>(tradePartner->getPosition(), player->getPosition()))
- {
- player->sendCancel("Trade player is too far away.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- if(!Houses::getInstance()->payRent(player, house, 0))
- {
- player->sendCancel("You have to pay a pre-rent first.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- Item* transferItem = TransferItem::createTransferItem(house);
- player->transferContainer.__addThing(NULL, transferItem);
- player->transferContainer.setParent(player);
- if(!g_game.internalStartTrade(player, tradePartner, transferItem))
- transferItem->onTradeEvent(ON_TRADE_CANCEL, player, NULL);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_BLUE);
- return false;
- }
- bool TalkAction::houseKick(Creature* creature, const std::string&, const std::string& param)
- {
- Player* player = creature->getPlayer();
- if(!player)
- return false;
- Player* targetPlayer = NULL;
- if(g_game.getPlayerByNameWildcard(param, targetPlayer) != RET_NOERROR)
- targetPlayer = player;
- House* house = Houses::getInstance()->getHouseByPlayer(targetPlayer);
- if(!house || !house->kickPlayer(player, targetPlayer))
- {
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- player->sendCancelMessage(RET_NOTPOSSIBLE);
- }
- else
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_BLUE);
- return false;
- }
- bool TalkAction::houseDoorList(Creature* creature, const std::string&, const std::string&)
- {
- Player* player = creature->getPlayer();
- if(!player)
- return false;
- House* house = Houses::getInstance()->getHouseByPlayer(player);
- if(!house)
- {
- player->sendCancelMessage(RET_NOTPOSSIBLE);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return false;
- }
- Door* door = house->getDoorByPosition(getNextPosition(player->getDirection(), player->getPosition()));
- if(door && house->canEditAccessList(door->getDoorId(), player))
- {
- player->setEditHouse(house, door->getDoorId());
- player->sendHouseWindow(house, door->getDoorId());
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_BLUE);
- }
- else
- {
- player->sendCancelMessage(RET_NOTPOSSIBLE);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- }
- return false;
- }
- bool TalkAction::houseGuestList(Creature* creature, const std::string&, const std::string&)
- {
- Player* player = creature->getPlayer();
- if(!player)
- return false;
- House* house = Houses::getInstance()->getHouseByPlayer(player);
- if(house && house->canEditAccessList(GUEST_LIST, player))
- {
- player->setEditHouse(house, GUEST_LIST);
- player->sendHouseWindow(house, GUEST_LIST);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_BLUE);
- }
- else
- {
- player->sendCancelMessage(RET_NOTPOSSIBLE);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- }
- return false;
- }
- bool TalkAction::houseSubOwnerList(Creature* creature, const std::string&, const std::string&)
- {
- Player* player = creature->getPlayer();
- if(!player)
- return false;
- House* house = Houses::getInstance()->getHouseByPlayer(player);
- if(house && house->canEditAccessList(SUBOWNER_LIST, player))
- {
- player->setEditHouse(house, SUBOWNER_LIST);
- player->sendHouseWindow(house, SUBOWNER_LIST);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_WRAPS_BLUE);
- }
- else
- {
- player->sendCancelMessage(RET_NOTPOSSIBLE);
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- }
- return false;
- }
- bool TalkAction::guildJoin(Creature* creature, const std::string&, const std::string& param)
- {
- Player* player = creature->getPlayer();
- if(!player || !g_config.getBool(ConfigManager::INGAME_GUILD_MANAGEMENT))
- return false;
- std::string param_ = param;
- trimString(param_);
- if(!player->getGuildId())
- {
- uint32_t guildId;
- if(IOGuild::getInstance()->getGuildId(guildId, param_))
- {
- if(player->isGuildInvited(guildId))
- {
- IOGuild::getInstance()->joinGuild(player, guildId);
- player->sendTextMessage(MSG_INFO_DESCR, "You have joined the guild.");
- char buffer[80];
- sprintf(buffer, "%s has joined the guild.", player->getName().c_str());
- if(ChatChannel* guildChannel = g_chat.getChannel(player, 0x00))
- guildChannel->talk(player, SPEAK_CHANNEL_RA, buffer);
- }
- else
- player->sendCancel("You are not invited to that guild.");
- }
- else
- player->sendCancel("There's no guild with that name.");
- }
- else
- player->sendCancel("You are already in a guild.");
- return true;
- }
- bool TalkAction::guildCreate(Creature* creature, const std::string&, const std::string& param)
- {
- Player* player = creature->getPlayer();
- if(!player || !g_config.getBool(ConfigManager::INGAME_GUILD_MANAGEMENT))
- return false;
- if(player->getGuildId())
- {
- player->sendCancel("You are already in a guild.");
- return true;
- }
- std::string param_ = param;
- trimString(param_);
- if(!isValidName(param_))
- {
- player->sendCancel("That guild name contains illegal characters, please choose another name.");
- return true;
- }
- const uint32_t minLength = g_config.getNumber(ConfigManager::MIN_GUILDNAME);
- const uint32_t maxLength = g_config.getNumber(ConfigManager::MAX_GUILDNAME);
- if(param_.length() < minLength)
- {
- player->sendCancel("That guild name is too short, please select a longer name.");
- return true;
- }
- if(param_.length() > maxLength)
- {
- player->sendCancel("That guild name is too long, please select a shorter name.");
- return true;
- }
- uint32_t guildId;
- if(IOGuild::getInstance()->getGuildId(guildId, param_))
- {
- player->sendCancel("There is already a guild with that name.");
- return true;
- }
- const uint32_t levelToFormGuild = g_config.getNumber(ConfigManager::LEVEL_TO_FORM_GUILD);
- if(player->getLevel() < levelToFormGuild)
- {
- char buffer[70 + levelToFormGuild];
- sprintf(buffer, "You have to be at least Level %d to form a guild.", levelToFormGuild);
- player->sendCancel(buffer);
- return true;
- }
- const int32_t premiumDays = g_config.getNumber(ConfigManager::GUILD_PREMIUM_DAYS);
- if(player->getPremiumDays() < premiumDays && !g_config.getBool(ConfigManager::FREE_PREMIUM))
- {
- char buffer[70 + premiumDays];
- sprintf(buffer, "You need to have at least %d premium days to form a guild.", premiumDays);
- player->sendCancel(buffer);
- return true;
- }
- player->setGuildName(param_);
- IOGuild::getInstance()->createGuild(player);
- char buffer[50 + maxLength];
- sprintf(buffer, "You have formed guild \"%s\"!", param_.c_str());
- player->sendTextMessage(MSG_INFO_DESCR, buffer);
- return true;
- }
- bool TalkAction::thingProporties(Creature* creature, const std::string&, const std::string& param)
- {
- Player* player = creature->getPlayer();
- if(!player)
- return false;
- const Position& pos = getNextPosition(player->getDirection(), player->getPosition());
- Tile* tile = g_game.getTile(pos);
- if(!tile)
- {
- player->sendTextMessage(MSG_STATUS_SMALL, "No tile found.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return true;
- }
- Thing* thing = tile->getTopVisibleThing(creature);
- if(!thing)
- {
- player->sendTextMessage(MSG_STATUS_SMALL, "No object found.");
- g_game.addMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- return true;
- }
- boost::char_separator<char> sep(" ");
- tokenizer tokens(param, sep);
- std::string invalid;
- for(tokenizer::iterator it = tokens.begin(); it != tokens.end();)
- {
- std::string action = parseParams(it, tokens.end());
- toLowerCaseString(action);
- if(Item* item = thing->getItem())
- {
- if(action == "set")
- {
- std::string type = parseParams(it, tokens.end()), key = parseParams(it,
- tokens.end()), value = parseParams(it, tokens.end());
- if(type == "integer" || type == "number" || type == "int")
- item->setAttribute(key, atoi(value.c_str()));
- else if(type == "float" || type == "double")
- item->setAttribute(key, (float)atof(value.c_str()));
- else if(type == "bool" || type == "boolean")
- item->setAttribute(key, booleanString(value));
- else
- item->setAttribute(key, value);
- }
- else if(action == "erase" || action == "remove")
- item->eraseAttribute(parseParams(it, tokens.end()));
- else if(action == "action" || action == "actionid" || action == "aid")
- {
- int32_t tmp = atoi(parseParams(it, tokens.end()).c_str());
- if(tmp > 0)
- item->setActionId(tmp);
- else
- item->resetActionId();
- }
- else if (action == "level" || action == "lvl")
- {
- int32_t tmp = atoi(parseParams(it, tokens.end()).c_str());
- item->setLevelLimit(tmp);
- }
- else if(action == "unique" || action == "uniqueid" || action == "uid")
- {
- int32_t tmp = atoi(parseParams(it, tokens.end()).c_str());
- if(tmp >= 1000 || tmp <= 0xFFFF)
- item->setUniqueId(tmp);
- }
- else if(action == "destination" || action == "position"
- || action == "pos" || action == "dest") //TODO: doesn't work
- {
- if(Teleport* teleport = item->getTeleport())
- teleport->setDestination(Position(atoi(parseParams(it, tokens.end()).c_str()), atoi(
- parseParams(it, tokens.end()).c_str()), atoi(parseParams(it, tokens.end()).c_str())));
- }
- else
- {
- std::stringstream s;
- s << action << " (" << parseParams(it, tokens.end()) << ")";
- invalid += s.str();
- break;
- }
- }
- else if(Creature* _creature = thing->getCreature())
- {
- if(action == "health")
- _creature->changeHealth(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "maxhealth")
- _creature->changeMaxHealth(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "mana")
- _creature->changeMana(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "maxmana")
- _creature->changeMaxMana(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "basespeed")
- _creature->setBaseSpeed(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "droploot")
- _creature->setDropLoot((lootDrop_t)atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "lossskill")
- _creature->setLossSkill(booleanString(parseParams(it, tokens.end())));
- else if(action == "cannotmove")
- _creature->setNoMove(booleanString(parseParams(it, tokens.end())));
- else if(action == "skull")
- {
- _creature->setSkull(getSkulls(parseParams(it, tokens.end())));
- g_game.updateCreatureSkull(_creature);
- }
- else if(action == "shield")
- {
- _creature->setShield(getShields(parseParams(it, tokens.end())));
- g_game.updateCreatureShield(_creature);
- }
- else if(action == "emblem")
- {
- _creature->setEmblem(getEmblems(parseParams(it, tokens.end())));
- g_game.updateCreatureEmblem(_creature);
- }
- else if(action == "speaktype")
- _creature->setSpeakType((SpeakClasses)atoi(parseParams(it, tokens.end()).c_str()));
- else if(Player* _player = _creature->getPlayer())
- {
- if(action == "fyi")
- _player->sendFYIBox(parseParams(it, tokens.end()).c_str());
- else if(action == "tutorial")
- _player->sendTutorial(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "guildlevel")
- _player->setGuildLevel((GuildLevel_t)atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "guildrank")
- _player->setRankId(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "guildnick")
- _player->setGuildNick(parseParams(it, tokens.end()).c_str());
- else if(action == "group")
- _player->setGroupId(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "vocation")
- _player->setVocation(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "sex" || action == "gender")
- _player->setSex(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "town" || action == "temple")
- {
- if(Town* town = Towns::getInstance()->getTown(parseParams(it, tokens.end())))
- {
- _player->setMasterPosition(town->getPosition());
- _player->setTown(town->getID());
- }
- }
- else if(action == "marriage" || action == "partner")
- _player->marriage = atoi(parseParams(it, tokens.end()).c_str());
- else if(action == "balance")
- _player->balance = atoi(parseParams(it, tokens.end()).c_str());
- else if(action == "rates")
- _player->rates[atoi(parseParams(it, tokens.end()).c_str())] = atof(
- parseParams(it, tokens.end()).c_str());
- else if(action == "idle")
- _player->setIdleTime(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "stamina")
- _player->setStaminaMinutes(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "capacity" || action == "cap")
- _player->setCapacity(atoi(parseParams(it, tokens.end()).c_str()));
- else if(action == "execute")
- g_talkActions->onPlayerSay(_player, atoi(parseParams(it, tokens.end()).c_str()),
- parseParams(it, tokens.end()), booleanString(parseParams(it, tokens.end())));
- else if(action == "saving" || action == "save")
- _player->switchSaving();
- else
- {
- std::stringstream s;
- s << action << " (" << parseParams(it, tokens.end()) << ")";
- invalid += s.str();
- break;
- }
- }
- /*else if(Npc* _npc = _creature->getNpc())
- {
- }
- else if(Monster* _monster = _creature->getMonster())
- {
- }*/
- else
- {
- std::stringstream s;
- s << action << " (" << parseParams(it, tokens.end()) << ")";
- invalid += s.str();
- break;
- }
- }
- }
- const SpectatorVec& list = g_game.getSpectators(pos);
- SpectatorVec::const_iterator it;
- Player* tmpPlayer = NULL;
- for(it = list.begin(); it != list.end(); ++it)
- {
- if((tmpPlayer = (*it)->getPlayer()))
- tmpPlayer->sendUpdateTile(tile, pos);
- }
- for(it = list.begin(); it != list.end(); ++it)
- (*it)->onUpdateTile(tile, pos);
- g_game.addMagicEffect(pos, MAGIC_EFFECT_WRAPS_GREEN);
- if(invalid.empty())
- return true;
- std::string tmp = "Following action was invalid: " + invalid;
- player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, tmp.c_str());
- return true;
- }
- bool TalkAction::banishmentInfo(Creature* creature, const std::string&, const std::string& param)
- {
- Player* player = creature->getPlayer();
- if(!player)
- return false;
- StringVec params = explodeString(param, ",");
- std::string what = "Account";
- trimString(params[0]);
- Ban ban;
- ban.type = BAN_ACCOUNT;
- if(params.size() > 1)
- {
- trimString(params[1]);
- if(params[0].substr(0, 1) == "p")
- {
- what = "Character";
- ban.type = BAN_PLAYER;
- ban.param = PLAYERBAN_BANISHMENT;
- ban.value = atoi(params[1].c_str());
- if(!ban.value)
- {
- IOLoginData::getInstance()->getGuidByName(ban.value, params[1], true);
- if(!ban.value)
- ban.value = IOLoginData::getInstance()->getAccountIdByName(params[1]);
- }
- }
- else
- {
- ban.value = atoi(params[1].c_str());
- if(!ban.value)
- {
- IOLoginData::getInstance()->getAccountId(params[1], ban.value);
- if(!ban.value)
- ban.value = IOLoginData::getInstance()->getAccountIdByName(params[1]);
- }
- }
- }
- else
- {
- ban.value = atoi(params[0].c_str());
- if(!ban.value)
- {
- IOLoginData::getInstance()->getAccountId(params[0], ban.value);
- if(!ban.value)
- ban.value = IOLoginData::getInstance()->getAccountIdByName(params[0]);
- }
- }
- if(!ban.value)
- {
- toLowerCaseString(what);
- player->sendCancel("Invalid " + what + (std::string)" name or id.");
- return true;
- }
- if(!IOBan::getInstance()->getData(ban))
- {
- player->sendCancel("That player or account is not banished or deleted.");
- return true;
- }
- bool deletion = ban.expires < 0;
- std::string admin = "Automatic ";
- if(!ban.adminId)
- admin += (deletion ? "deletion" : "banishment");
- else
- IOLoginData::getInstance()->getNameByGuid(ban.adminId, admin, true);
- std::string end = "Banishment will be lifted at:\n";
- if(deletion)
- end = what + (std::string)" won't be undeleted";
- char buffer[500 + ban.comment.length()];
- sprintf(buffer, "%s has been %s at:\n%s by: %s,\nfor the following reason:\n%s.\nThe action taken was:\n%s.\nThe comment given was:\n%s.\n%s%s.",
- what.c_str(), (deletion ? "deleted" : "banished"), formatDateEx(ban.added, "%d %b %Y").c_str(), admin.c_str(), getReason(ban.reason).c_str(),
- getAction(ban.action, false).c_str(), ban.comment.c_str(), end.c_str(), (deletion ? "." : formatDateEx(ban.expires).c_str()));
- player->sendFYIBox(buffer);
- return true;
- }
- bool TalkAction::diagnostics(Creature* creature, const std::string&, const std::string&)
- {
- Player* player = creature->getPlayer();
- if(!player)
- return false;
- #ifdef __ENABLE_SERVER_DIAGNOSTIC__
- std::stringstream s;
- s << "Server diagonostic:" << std::endl;
- player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, s.str());
- s.str("");
- s << "World:" << std::endl
- << "--------------------" << std::endl
- << "Player: " << g_game.getPlayersOnline() << " (" << Player::playerCount << ")" << std::endl
- << "Npc: " << g_game.getNpcsOnline() << " (" << Npc::npcCount << ")" << std::endl
- << "Monster: " << g_game.getMonstersOnline() << " (" << Monster::monsterCount << ")" << std::endl << std::endl;
- player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, s.str());
- s.str("");
- s << "Protocols:" << std::endl
- << "--------------------" << std::endl
- << "ProtocolGame: " << ProtocolGame::protocolGameCount << std::endl
- << "ProtocolLogin: " << ProtocolLogin::protocolLoginCount << std::endl
- #ifdef __OTADMIN__
- << "ProtocolAdmin: " << ProtocolAdmin::protocolAdminCount << std::endl
- #endif
- << "ProtocolManager: " << ProtocolManager::protocolManagerCount << std::endl
- << "ProtocolStatus: " << ProtocolStatus::protocolStatusCount << std::endl
- << "ProtocolOld: " << ProtocolOld::protocolOldCount << std::endl << std::endl;
- player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, s.str());
- s.str("");
- s << "Connections:" << std::endl
- << "--------------------" << std::endl
- << "Active connections: " << Connection::connectionCount << std::endl
- << "Total message pool: " << OutputMessagePool::getInstance()->getTotalMessageCount() << std::endl
- << "Auto message pool: " << OutputMessagePool::getInstance()->getAutoMessageCount() << std::endl
- << "Queued message pool: " << OutputMessagePool::getInstance()->getQueuedMessageCount() << std::endl
- << "Free message pool: " << OutputMessagePool::getInstance()->getAvailableMessageCount() << std::endl;
- player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, s.str());
- #else
- player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, "Command not available, please rebuild your software with -D__ENABLE_SERVER_DIAG__");
- #endif
- return true;
- }
- bool TalkAction::addSkill(Creature* creature, const std::string&, const std::string& param)
- {
- Player* player = creature->getPlayer();
- if(!player)
- return false;
- StringVec params = explodeString(param, ",");
- if(params.size() < 2)
- {
- player->sendTextMessage(MSG_STATUS_SMALL, "Command requires at least 2 parameters.");
- return true;
- }
- uint32_t amount = 1;
- if(params.size() > 2)
- {
- std::string tmp = params[2];
- trimString(tmp);
- amount = (uint32_t)std::max(1, atoi(tmp.c_str()));
- }
- std::string name = params[0], skill = params[1];
- trimString(name);
- trimString(skill);
- Player* target = NULL;
- ReturnValue ret = g_game.getPlayerByNameWildcard(name, target);
- if(ret != RET_NOERROR)
- {
- player->sendCancelMessage(ret);
- return true;
- }
- if(skill[0] == 'l' || skill[0] == 'e')
- target->addExperience(uint64_t(Player::getExpForLevel(target->getLevel() + amount) - target->getExperience()));
- else if(skill[0] == 'm')
- target->addManaSpent((uint64_t)(target->getVocation()->getReqMana(target->getMagicLevel() +
- amount) - target->getSpentMana()), false);
- else
- {
- skills_t skillId = getSkillId(skill);
- target->addSkillAdvance(skillId, (uint32_t)(target->getVocation()->getReqSkillTries(skillId, target->getSkill(skillId,
- SKILL_LEVEL) + amount) - target->getSkill(skillId, SKILL_TRIES)), false);
- }
- return true;
- }
- bool TalkAction::ghost(Creature* creature, const std::string&, const std::string&)
- {
- Player* player = creature->getPlayer();
- if(!player)
- return false;
- if(player->hasFlag(PlayerFlag_CannotBeSeen))
- {
- player->sendTextMessage(MSG_INFO_DESCR, "Command disabled for players with special, invisibility flag.");
- return true;
- }
- SpectatorVec::iterator it;
- SpectatorVec list = g_game.getSpectators(player->getPosition());
- Player* tmpPlayer = NULL;
- Condition* condition = NULL;
- if((condition = player->getCondition(CONDITION_GAMEMASTER, CONDITIONID_DEFAULT, GAMEMASTER_INVISIBLE)))
- {
- if ((player->getAccess() >= 7))
- {
- player->sendMagicEffect(player->getPosition(), MAGIC_EFFECT_BIGPLANTS);
- }
- player->sendTextMessage(MSG_INFO_DESCR, "You are visible again.");
- IOLoginData::getInstance()->updateOnlineStatus(player->getGUID(), true);
- for(AutoList<Player>::iterator pit = Player::autoList.begin(); pit != Player::autoList.end(); ++pit)
- {
- if(!pit->second->canSeeCreature(player))
- pit->second->notifyLogIn(player);
- }
- for(it = list.begin(); it != list.end(); ++it)
- {
- if((tmpPlayer = (*it)->getPlayer()) && !tmpPlayer->canSeeCreature(player))
- tmpPlayer->sendMagicEffect(player->getPosition(), MAGIC_EFFECT_TELEPORT);
- }
- player->removeCondition(condition);
- g_game.internalCreatureChangeVisible(creature, VISIBLE_GHOST_APPEAR);
- }
- else if((condition = Condition::createCondition(CONDITIONID_DEFAULT, CONDITION_GAMEMASTER, -1, 0, false, GAMEMASTER_INVISIBLE)))
- {
- player->addCondition(condition);
- g_game.internalCreatureChangeVisible(creature, VISIBLE_GHOST_DISAPPEAR);
- for(it = list.begin(); it != list.end(); ++it)
- {
- if((tmpPlayer = (*it)->getPlayer()) && !tmpPlayer->canSeeCreature(player))
- tmpPlayer->sendMagicEffect(player->getPosition(), MAGIC_EFFECT_POFF);
- }
- for(AutoList<Player>::iterator pit = Player::autoList.begin(); pit != Player::autoList.end(); ++pit)
- {
- if(!pit->second->canSeeCreature(player))
- pit->second->notifyLogOut(player);
- }
- IOLoginData::getInstance()->updateOnlineStatus(player->getGUID(), false);
- if(player->isTrading())
- g_game.internalCloseTrade(player);
- player->clearPartyInvitations();
- if(player->getParty())
- player->getParty()->leave(player);
- player->sendTextMessage(MSG_INFO_DESCR, "You are now invisible.");
- }
- return true;
- }
- bool TalkAction::software(Creature* creature, const std::string&, const std::string&)
- {
- Player* player = creature->getPlayer();
- if(!player)
- return false;
- std::stringstream s;
- s << SOFTWARE_NAME << ", version " << SOFTWARE_VERSION << " (" << SOFTWARE_CODENAME << ")" << std::endl;
- player->sendTextMessage(MSG_INFO_DESCR, s.str());
- s.str("");
- s << "Compiled at: " << __DATE__ << ", " << __TIME__ << "." << std::endl;
- player->sendTextMessage(MSG_INFO_DESCR, s.str());
- s.str("");
- s << "Libraries:" << std::endl
- << "--------------------" << std::endl
- << "Platform: " << BOOST_PLATFORM << std::endl
- << "Compiler: " << BOOST_COMPILER << std::endl
- << "Boost: " << BOOST_VERSION << std::endl
- << "ASIO: " << BOOST_ASIO_VERSION << std::endl
- << "XML: " << XML_DEFAULT_VERSION << std::endl
- << "Lua: " << LUA_VERSION << std::endl;
- player->sendTextMessage(MSG_STATUS_CONSOLE_BLUE, s.str());
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement