//SmallSocket.cpp /* Copyright (C) 2004 Anders Hedstrom 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ //#include <stdio.h> #include <Parse.h> #include "SmallHandler.h" #include "World.h" #include "cstring.h" #include "ItemFactory.h" #include "SmallSocket.h" SmallSocket::SmallSocket(SocketHandler& h) :TcpSocket(h) ,m_state(STATE_LOGIN) ,m_name("") ,m_x(0) ,m_y(0) ,m_player(NULL) { SetLineProtocol(); } SmallSocket::~SmallSocket() { } void SmallSocket::Send(const std::string& str) { cstring q; q = str; TcpSocket::Send( q.c_str() ); } void SmallSocket::OnAccept() { Send("&WWelcome.&n\n"); SendPrompt(); } void SmallSocket::OnLine(const std::string& line) { switch (m_state) { case STATE_LOGIN: // check player // exist - ask password STATE_PASSWORD // don't exist - ask new player question STATE_NEW_PLAYER_QUESTION m_player = GetPlayerF().FindPlayer(line, ""); if (m_player) { m_state = STATE_PASSWORD; } else { m_name = line; m_state = STATE_NEW_PLAYER_QUESTION; } SendPrompt(); break; case STATE_PROMPT: if (line.size()) { Parse pa(line); std::string cmd = pa.getword(); if (line[0] == 34 || line[0] == '\'') { static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " says '" + line.substr(1) + "'\n",this); Send("You say '" + line.substr(1) + "&n'\n"); } else if (line[0] == '!') { static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " shouts '" + line.substr(1) + "'\n",this,true); Send("You shout '" + line.substr(1) + "&n'\n"); } else if (line == "n" || line == "s" || line == "e" || line == "w") { try_move(line); static_cast<SmallHandler&>(Handler()).ShowCell(this); } else if (line == "l") { static_cast<SmallHandler&>(Handler()).ShowCell(this); } else if (line == "who") { static_cast<SmallHandler&>(Handler()).Who(this); } else if (line == "quit") { m_state = STATE_QUIT; } else if (cmd == "get") { TryGet(this, pa.getrest()); } else if (cmd == "drop") { TryDrop(this, pa.getrest()); } else if (line == "i") { m_player -> DisplayInventory(this); } else if (line == "status") { static_cast<SmallHandler&>(Handler()).ShowStatus(this); } else if (line == "help") { Send("n / s / e / w - move around\n"); Send("l - look around\n"); Send("get / drop <item>\n"); Send("i - display inventory\n"); Send("' / \" - talk ( as in >\"hi )\n"); Send("! - shout ( as in >!Hello anyone??? )\n"); Send("who - is online\n"); Send("status - show game status\n"); Send("help\nquit\n"); } else { Send("Command not recognized - try '&Whelp&n'\n"); } } SendPrompt(); break; case STATE_QUIT: break; case STATE_PASSWORD: if (line == m_player -> m_passwd) { std::string str; m_name = m_player -> m_name; m_state = STATE_PROMPT; GetWorld().GetRandomLocation(m_x,m_y,str); Send("Welcome back, " + m_player -> m_name + ".\n"); Send("You wake up in a room: " + str + "\n"); } else { m_state = STATE_LOGIN; } SendPrompt(); break; case STATE_NEW_PLAYER_QUESTION: if (!line.size() || line[0] == 'y' || line[0] == 'Y') { m_state = STATE_PASSWORD_1; } else { m_state = STATE_LOGIN; } SendPrompt(); break; case STATE_PASSWORD_1: if (line.size() > 3) { m_passwd = line; m_state = STATE_PASSWORD_2; } else { Send("Enter at least 4 characters.\n"); } SendPrompt(); break; case STATE_PASSWORD_2: if (line == m_passwd) { m_player = GetPlayerF().AddPlayer(m_name,m_passwd); m_state = STATE_PASSWORD; OnLine(line); GetPlayerF().Save(); } else { Send("Password mismatch - try again\n"); m_state = STATE_NEW_PLAYER_QUESTION; SendPrompt(); } break; } } void SmallSocket::SendPrompt() { switch (m_state) { case STATE_LOGIN: Send("Enter name: "); break; case STATE_PROMPT: Send("> "); break; case STATE_QUIT: Send("Goodbye!\n"); SetCloseAndDelete(); break; case STATE_PASSWORD: Send("Enter password: "); break; case STATE_NEW_PLAYER_QUESTION: Send("Create a new player (Y,n)? "); break; case STATE_PASSWORD_1: Send("Enter new player password: "); break; case STATE_PASSWORD_2: Send("Repeat password: "); break; } } bool SmallSocket::IsAt(int x,int y) { if (m_x == x && m_y == y) return true; return false; } void SmallSocket::try_move(const std::string& dir) { std::string name; bool n,s,e,w; GetWorld().GetAt(m_x,m_y,name,n,s,e,w); if (dir == "n") { if (n && GetWorld().FindAt(m_x,m_y - 1,name)) { static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " leaves north\n",this); m_y--; static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " enters from the south\n",this); return; } } else if (dir == "s") { if (s && GetWorld().FindAt(m_x,m_y + 1,name)) { static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " leaves south\n",this); m_y++; static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " enters from the north\n",this); return; } } else if (dir == "e") { if (e && GetWorld().FindAt(m_x + 1,m_y,name)) { static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " leaves east\n",this); m_x++; static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " enters from the west\n",this); return; } } else if (dir == "w") { if (w && GetWorld().FindAt(m_x - 1,m_y,name)) { static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " leaves west\n",this); m_x--; static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " enters from the east\n",this); return; } } Send("&ROuch!&n\n"); } void SmallSocket::TryGet(SmallSocket *sendto,const std::string& item) { item_v& ref = static_cast<SmallHandler&>(Handler()).GetItems(m_x,m_y); item_v& ref_to = m_player -> GetInventory(); for (item_v::iterator it = ref.begin(); it != ref.end(); it++) { ITEM *i = *it; bool ok; if (i -> m_amount > 1) { ok = !strcmp(i -> m_plural.uc_str(), item.c_str()); } else { ok = !strcmp(i -> m_name.uc_str(), item.c_str()); } if (ok) { static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " picks up " + i -> GetDescription() + "\n",this); Send("You pick up " + i -> GetDescription() + "\n"); static_cast<SmallHandler&>(Handler()).MergeItem(ref_to,i); ref.erase(it); break; } } } void SmallSocket::TryDrop(SmallSocket *sendto,const std::string& item) { item_v& ref = m_player -> GetInventory(); item_v& ref_to = static_cast<SmallHandler&>(Handler()).GetItems(m_x,m_y); for (item_v::iterator it = ref.begin(); it != ref.end(); it++) { ITEM *i = *it; bool ok; if (i -> m_amount > 1) { ok = !strcmp(i -> m_plural.uc_str(), item.c_str()); } else { ok = !strcmp(i -> m_name.uc_str(), item.c_str()); } if (ok) { static_cast<SmallHandler&>(Handler()).Event(m_x,m_y,m_name + " drops " + i -> GetDescription() + "\n",this); Send("You drop " + i -> GetDescription() + "\n"); static_cast<SmallHandler&>(Handler()).MergeItem(ref_to,i); ref.erase(it); break; } } }