--- deliantra/server/socket/init.C 2006/12/25 11:25:50 1.31 +++ deliantra/server/socket/init.C 2007/03/14 01:19:10 1.40 @@ -1,25 +1,26 @@ /* - CrossFire, A Multiplayer game for X-windows - - Copyright (C) 2001 Mark Wedel - Copyright (C) 1992 Frank Tore Johansen - - 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., 675 Mass Ave, Cambridge, MA 02139, USA. - - The author can be reached via e-mail to -*/ + * CrossFire, A Multiplayer game for X-windows + * + * Copyright (C) 2005, 2006, 2007 Marc Lehmann & Crossfire+ Development Team + * Copyright (C) 2001 Mark Wedel + * Copyright (C) 1992 Frank Tore Johansen + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * The author can be reached via e-mail to + */ /** * \file @@ -60,6 +61,8 @@ cmd_ev (this, &client::cmd_cb), cc_inv (this), cc_other (this) { + refcnt_inc (); // the socket is an external reference + { struct linger linger_opt; @@ -129,42 +132,31 @@ mapy = 11; itemcmd = 1; /* Default is version item1 command */ - faces_sent = salloc0 (nrofpixmaps); - /* Do this so we don't send a face command for the client for * this face. Face 0 is sent to the client to say clear * face information. */ - faces_sent[0] = NS_FACESENT_FACE; + faces_sent[0] = true; - // socket I/O is low priority - // we prefer to have the server run instead of handling client requests - socket_ev.prio (PE_PRIO_NORMAL + 1); + socket_ev.prio (PE_PRIO_NORMAL); socket_ev.fd (fd); socket_ev.poll (PE_R); - // command handling is even lower priority - // that way no client can monopolise the server - cmd_ev.prio (PE_PRIO_NORMAL + 2); + cmd_ev.prio (PE_PRIO_NORMAL); // initialisation done, kick it! send_packet_printf ("version %d %d %s\n", VERSION_CS, VERSION_SC, VERSION_INFO); flush (); - // clients are externally referenced by the socket - refcnt_inc (); - clients.push_back (this); - -#if 0//TODO - socket_info.nconns++; - if (socket_info.nconns > cst_tot.max_conn) cst_tot.max_conn = socket_info.nconns; - if (socket_info.nconns > cst_lst.max_conn) cst_lst.max_conn = socket_info.nconns; -#endif + reset_stats (); + + clients.insert (this); } client::~client () { - sfree (faces_sent, nrofpixmaps); + clients.erase (this); + free (stats.range); free (stats.title); free (host); @@ -175,23 +167,54 @@ { attachable::do_destroy (); - sockvec::iterator i = find (clients.begin (), clients.end (), this); - if (i != clients.end ()) - clients.erase (i); - if (pl) pl->disconnect (); if (fd >= 0) - close (fd); + { + send_packet ("goodbye"); + flush (); + + close (fd); + } state = ST_DEAD; socket_ev.suspend (); cmd_ev.suspend (); - // socket now longer references us - refcnt_dec (); + refcnt_dec (); // socket no longer open +} + +void +client::reset_stats () +{ + /* we need to clear these to -1 and not zero - otherwise, + * if a player quits and starts a new character, we wont + * send new values to the client, as things like exp start + * at zero. + */ + for (int i = 0; i < NUM_SKILLS; i++) + last_skill_exp[i] = -1; + + for (int i = 0; i < NROFATTACKS; i++) + last_resist[i] = -1; + + last_weapon_sp = -1; + last_level = -1; + last_stats.exp = -1; + last_weight = (uint32) - 1; + last_flags = 0; + last_weight = 0; + last_weight_limit = 0; + last_path_attuned = 0; + last_path_repelled = 0; + last_path_denied = 0; + last_speed = 0; + flags = 0; + + static living zero_living; + last_stats = zero_living; } /** This sets up the socket and reads all the image information into memory. */ @@ -202,8 +225,6 @@ cst_lst.time_start = time (NULL); LOG (llevDebug, "Initialize new client/server data\n"); - - read_client_images (); } @@ -224,20 +245,9 @@ client * client::create (int fd, const char *peername) { - if (checkbanned (NULL, peername)) - { - LOG (llevInfo, "Banned host tried to connect: [%s]\n", peername); - return 0; - } - else - { - client *ns = new client (dup (fd), peername); - - ns->instantiate (); // effectively a nop right now - - INVOKE_CLIENT (CONNECT, ns); - - return ns; - } + client *ns = new client (dup (fd), peername); + ns->instantiate (); // effectively a nop right now + INVOKE_CLIENT (CONNECT, ns); + return ns; }