00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <Parse.h>
00021 #include <arpa/telnet.h>
00022 #include <Utility.h>
00023
00024 #include "InSocket.h"
00025 #include "cstring.h"
00026 #include "FutureHandler.h"
00027 #include "Login.h"
00028 #include "Player.h"
00029 #include "Command.h"
00030
00031 #define TELOPT_MXP '\x5B'
00032
00033 static const unsigned char will_mxp_str [] = { IAC, WILL, TELOPT_MXP, '\0' };
00034 static const unsigned char start_mxp_str [] = { IAC, SB, TELOPT_MXP, IAC, SE, '\0' };
00035 static const unsigned char do_mxp_str [] = { IAC, DO, TELOPT_MXP, '\0' };
00036 static const unsigned char dont_mxp_str [] = { IAC, DONT, TELOPT_MXP, '\0' };
00037
00038
00039 InSocket::InSocket(ISocketHandler& h)
00040 :TcpSocket(h)
00041 ,IEventOwner(static_cast<FutureHandler&>(h))
00042 ,m_active_command(NULL)
00043 ,m_command_state(0)
00044 ,m_b_use_mxp(false)
00045 ,m_move_event(0)
00046 {
00047 SetLineProtocol();
00048 }
00049
00050
00051 InSocket::~InSocket()
00052 {
00053 printf("~InSocket()\n");
00054 }
00055
00056
00057 void InSocket::OnDelete()
00058 {
00059 Player pl(GetDatabase(), GetAccountName());
00060 static_cast<FutureHandler&>(Handler()).ClearEvents(this);
00061 if (pl.Exists())
00062 {
00063 static_cast<FutureHandler&>(Handler()).GlobalEvent(this, pl.GetDisplayName() + " dropped.");
00064 }
00065 }
00066
00067
00068 void InSocket::OnAccept()
00069 {
00070 static_cast<FutureHandler&>(Handler()).Count("Number of connections");
00071 printf("%s\n", GetRemoteAddress().c_str());
00072 Send("&WWelcome &rto &gFuture&nMud.\n");
00073 write_to_buffer(will_mxp_str);
00074 SetPrompt(static_cast<FutureHandler&>(Handler()).GetLogin(), 0, "Name, please? ");
00075 }
00076
00077
00078 void InSocket::Send(const std::string& s)
00079 {
00080 cstring cs = s;
00081
00082 write_to_buffer(cs.c_str());
00083 }
00084
00085
00086 void InSocket::Sendf(char *format, ...)
00087 {
00088 va_list ap;
00089 va_start(ap, format);
00090 char slask[5000];
00091 #ifdef _WIN32
00092 vsprintf(slask, format, ap);
00093 #else
00094 vsnprintf(slask, 5000, format, ap);
00095 #endif
00096 va_end(ap);
00097 Send( slask );
00098 }
00099
00100
00101 void InSocket::SetPrompt(const std::string& p,bool colorize)
00102 {
00103 m_active_command = NULL;
00104 if (!p.size())
00105 {
00106 m_prompt = "> ";
00107 }
00108 else
00109 {
00110 m_prompt = p;
00111 }
00112 m_colorize_prompt = colorize;
00113 SendPrompt();
00114 }
00115
00116
00117 void InSocket::SetPrompt(Command *cc,int state,const std::string& prompt,bool colorize)
00118 {
00119 m_active_command = cc;
00120 m_command_state = state;
00121 m_prompt = prompt;
00122 m_colorize_prompt = colorize;
00123 SendPrompt();
00124 }
00125
00126
00127 void InSocket::SendPrompt()
00128 {
00129 if (!m_colorize_prompt)
00130 {
00131 write_to_buffer(m_prompt.c_str());
00132 }
00133 else
00134 {
00135 Send(m_prompt);
00136 }
00137 }
00138
00139
00140 void InSocket::ReadLine()
00141 {
00142 if (ibuf.GetLength())
00143 {
00144 size_t x = 0;
00145 size_t n = ibuf.GetLength();
00146 char tmp[TCP_BUFSIZE_READ + 1];
00147
00148 n = (n >= TCP_BUFSIZE_READ) ? TCP_BUFSIZE_READ : n;
00149 ibuf.Read(tmp,n);
00150 tmp[n] = 0;
00151
00152 for (size_t i = 0; i < n; i++)
00153 {
00154 unsigned char uc;
00155 memcpy(&uc, &tmp[i], 1);
00156 if (uc == IAC)
00157 {
00158 size_t l = strlen((char *)do_mxp_str);
00159 if (!memcmp(tmp + i, do_mxp_str, l))
00160 {
00161 m_b_use_mxp = true;
00162 send_mxp_defines();
00163 memmove(tmp + i, tmp + i + l, strlen(tmp + i + l) + 1);
00164 n -= l;
00165 }
00166 else
00167 if (!memcmp(tmp + i, dont_mxp_str, strlen((char *)dont_mxp_str)))
00168 {
00169 m_b_use_mxp = false;
00170 l = strlen((char *)dont_mxp_str);
00171 memmove(tmp + i, tmp + i + l, strlen(tmp + i + l) + 1);
00172 n -= l;
00173 }
00174 }
00175 if (i >= n)
00176 break;
00177 while (tmp[i] == 13 || tmp[i] == 10)
00178 {
00179 char c = tmp[i];
00180 tmp[i] = 0;
00181 if (tmp[x])
00182 {
00183 m_line += (tmp + x);
00184 }
00185 OnLine( m_line );
00186 i++;
00187 if (i < n && (tmp[i] == 13 || tmp[i] == 10) && tmp[i] != c)
00188 {
00189 i++;
00190 }
00191 x = i;
00192 m_line = "";
00193 }
00194 }
00195 if (tmp[x])
00196 {
00197 m_line += (tmp + x);
00198 }
00199 }
00200 }
00201
00202
00203 void InSocket::OnLine(const std::string& line)
00204 {
00205 if (line[0] == ' ')
00206 {
00207 size_t i = 0;
00208 while (line[i] == ' ')
00209 i++;
00210 static_cast<FutureHandler&>(Handler()).Talk(this, line.substr(i));
00211 SendPrompt();
00212 return;
00213 }
00214 if (m_active_command)
00215 {
00216 m_active_command -> OnLine(this, line, m_command_state);
00217 return;
00218 }
00219 if (!line.size())
00220 {
00221 SetPrompt();
00222 return;
00223 }
00224 Parse pa(line);
00225 std::string cmd = pa.getword();
00226 static_cast<FutureHandler&>(Handler()).DoCommand(this, cmd, pa.getrest());
00227 }
00228
00229
00230 void InSocket::send_mxp_defines()
00231 {
00232 write_to_buffer( start_mxp_str );
00233 write_to_buffer( MXPMODE (6) );
00234 write_to_buffer( MXPTAG ("!-- Set up MXP elements --"));
00235
00236 write_to_buffer( MXPTAG ("!ELEMENT Ex '<send>' FLAG=RoomExit"));
00237
00238 write_to_buffer( MXPTAG ("!ELEMENT rdesc '<p>' FLAG=RoomDesc"));
00239
00240 write_to_buffer( MXPTAG
00241 ("!ELEMENT Get \"<send href='"
00242 "get '&name;'|"
00243 "examine '&name;'|"
00244 "drink '&name;'"
00245 "' "
00246 "hint='RH mouse click to use this object|"
00247 "Get &desc;|"
00248 "Examine &desc;|"
00249 "Drink from &desc;"
00250 "'>\" ATT='name desc'") );
00251
00252 write_to_buffer( MXPTAG
00253 ("!ELEMENT Drop \"<send href='"
00254 "drop '&name;'|"
00255 "examine '&name;'|"
00256 "look in '&name;'|"
00257 "wear '&name;'|"
00258 "eat '&name;'|"
00259 "drink '&name;'"
00260 "' "
00261 "hint='RH mouse click to use this object|"
00262 "Drop &desc;|"
00263 "Examine &desc;|"
00264 "Look inside &desc;|"
00265 "Wear &desc;|"
00266 "Eat &desc;|"
00267 "Drink &desc;"
00268 "'>\" ATT='name desc'") );
00269
00270 write_to_buffer( MXPTAG
00271 ("!ELEMENT Bid \"<send href='bid '&name;'' "
00272 "hint='Bid for &desc;'>\" "
00273 "ATT='name desc'") );
00274
00275 write_to_buffer( MXPTAG
00276 ("!ELEMENT List \"<send href='buy '&name;'' "
00277 "hint='Buy &desc;'>\" "
00278 "ATT='name desc'") );
00279
00280 write_to_buffer( MXPTAG
00281 ("!ELEMENT Player \"<send href='tell '&name;' ' "
00282 "hint='Send a message to &name;' prompt>\" "
00283 "ATT='name'") );
00284 }
00285
00286
00287 void InSocket::write_to_buffer(const char *s)
00288 {
00289 std::string tmp;
00290 size_t l = strlen(s);
00291 bool in_mxp = false;
00292 bool in_ent = false;
00293 for (size_t i = 0; i < l; i++)
00294 {
00295 if (in_mxp)
00296 {
00297 if (s[i] == MXP_ENDc)
00298 {
00299 if (m_b_use_mxp)
00300 tmp += '>';
00301 in_mxp = false;
00302 }
00303 else
00304 {
00305 if (m_b_use_mxp)
00306 tmp += s[i];
00307 }
00308 }
00309 else
00310 if (in_ent)
00311 {
00312 if (m_b_use_mxp)
00313 tmp += s[i];
00314 if (s[i] == ';')
00315 in_ent = false;
00316 }
00317 else
00318 switch (s[i])
00319 {
00320 case MXP_BEGc:
00321 if (m_b_use_mxp)
00322 tmp += '<';
00323 in_mxp = true;
00324 break;
00325 case MXP_AMPc:
00326 if (m_b_use_mxp)
00327 tmp += '&';
00328 in_ent = true;
00329 break;
00330 case MXP_ENDc:
00331 break;
00332 case '<':
00333 if (m_b_use_mxp)
00334 tmp += "<";
00335 else
00336 tmp += s[i];
00337 break;
00338 case '>':
00339 if (m_b_use_mxp)
00340 tmp += ">";
00341 else
00342 tmp += s[i];
00343 break;
00344 case '&':
00345 if (m_b_use_mxp)
00346 tmp += "&";
00347 else
00348 tmp += s[i];
00349 break;
00350 case '"':
00351 if (m_b_use_mxp)
00352 tmp += """;
00353 else
00354 tmp += s[i];
00355 break;
00356 default:
00357 tmp += s[i];
00358 }
00359 }
00360 TcpSocket::Send(tmp);
00361 }
00362
00363
00364 void InSocket::write_to_buffer(const unsigned char *s)
00365 {
00366 SendBuf((const char *)s, strlen((char *)s));
00367 }
00368
00369
00370 Database& InSocket::GetDatabase()
00371 {
00372 return static_cast<FutureHandler&>(Handler()).GetDatabase();
00373 }
00374
00375
00376 void InSocket::OnEvent(int id)
00377 {
00378 if (id == m_move_event)
00379 {
00380 m_move_event = 0;
00381 if (m_move_buffer.size())
00382 {
00383 std::list<std::string>::iterator it = m_move_buffer.begin();
00384 std::string move = *it;
00385 m_move_buffer.erase(it);
00386 Command *cc = NULL;
00387 if (move == "forward")
00388 cc = static_cast<FutureHandler&>(Handler()).GetCommand("forward");
00389 else
00390 if (move == "enter")
00391 cc = static_cast<FutureHandler&>(Handler()).GetCommand("enter");
00392 else
00393 switch (move[0])
00394 {
00395 case 'n':
00396 cc = static_cast<FutureHandler&>(Handler()).GetCommand("north");
00397 break;
00398 case 's':
00399 cc = static_cast<FutureHandler&>(Handler()).GetCommand("south");
00400 break;
00401 case 'e':
00402 cc = static_cast<FutureHandler&>(Handler()).GetCommand("east");
00403 break;
00404 case 'w':
00405 cc = static_cast<FutureHandler&>(Handler()).GetCommand("west");
00406 break;
00407 case 'u':
00408 cc = static_cast<FutureHandler&>(Handler()).GetCommand("up");
00409 break;
00410 case 'd':
00411 cc = static_cast<FutureHandler&>(Handler()).GetCommand("down");
00412 break;
00413 }
00414 if (cc)
00415 {
00416 std::string tmp = "nomap";
00417 Parse pa(tmp);
00418 if (move == "forward")
00419 {
00420 Send("\nMoving forward\n");
00421 }
00422 else
00423 if (move == "enter")
00424 {
00425 Send("\nEntering portal...\n");
00426 }
00427 else
00428 {
00429 Send("\nMoving " + cc -> GetCommand() + "\n");
00430 }
00431 cc -> Execute(this, tmp, pa);
00432 }
00433 }
00434 }
00435 else
00436 {
00437 Send("\nEvent: " + Utility::l2string(id) + "\n");
00438 SendPrompt();
00439 }
00440 }
00441
00442
00443 int InSocket::AddEvent(long sec,long usec)
00444 {
00445 return static_cast<FutureHandler&>(Handler()).AddEvent(this, sec, usec);
00446 }
00447
00448
00449 void InSocket::BufferMove(const std::string& x)
00450 {
00451 m_move_buffer.push_back(x);
00452 Send("Buffering move.\n");
00453 SetPrompt();
00454 }
00455
00456
00457 void InSocket::SetMoveEvent(long sec,long usec)
00458 {
00459 m_move_event = AddEvent(sec, usec);
00460 }
00461
00462
00463 void InSocket::CancelMoves()
00464 {
00465 while (m_move_buffer.size())
00466 {
00467 std::list<std::string>::iterator it = m_move_buffer.begin();
00468 m_move_buffer.erase(it);
00469 }
00470 }
00471
00472
00473 void InSocket::GlobalEvent(const std::string& x)
00474 {
00475 static_cast<FutureHandler&>(Handler()).GlobalEvent(this, x);
00476 }
00477
00478
00479 void InSocket::Count(const std::string& x)
00480 {
00481 static_cast<FutureHandler&>(Handler()).Count(x);
00482 }
00483
00484