00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef SERVERCONNECTION_H
00017 #define SERVERCONNECTION_H
00018
00019 #ifndef USE_PCH
00020 #include <boost/shared_ptr.hpp>
00021 #include <sys/time.h>
00022 #include "debug.h"
00023 #include <libcw/events.h>
00024 #endif
00025
00026 #include "MessageOut.h"
00027 #include "ServerSession.h"
00028 #include "IdentityReference.h"
00029 #include "Server.h"
00030 #include "random_nick.h"
00031
00032 class UserAnswerEventType;
00033 class ServerMessageIn;
00034 class ExpressionEventType;
00035
00036
00037 enum state_nt {
00038 disconnected,
00039 authentication_started,
00040 successful_connect,
00041 pong_sent,
00042 login_sent,
00043 real_nick_sent,
00044 real_nick_accepted
00045 };
00046
00047
00048
00049
00050
00051
00052
00053
00054 class ServerConnection : public IdentityReference, public virtual event_client_ct {
00055 private:
00056
00057 boost::shared_ptr<Server> M_server;
00058
00059
00060 ServerSession* M_server_session;
00061
00062
00063 bool M_reconnect;
00064
00065
00066
00067
00068 bool M_connected;
00069
00070
00071 state_nt M_state;
00072
00073 timeval M_connect_delay;
00074 static timeval S_connect_delay_init;
00075
00076
00077 bool M_timed_out;
00078
00079
00080 int M_timed_out_count;
00081
00082
00083 bool M_secondary_connection;
00084
00085
00086 std::string M_my_serverside_nick_name;
00087
00088 public:
00089
00090 ServerConnection(Identity* identity) :
00091 event_client_ct(), IdentityReference(identity), M_server_session(NULL), M_reconnect(false),
00092 M_connected(false), M_state(disconnected),
00093 M_connect_delay(S_connect_delay_init), M_timed_out(false), M_timed_out_count(0),
00094 M_secondary_connection(false)
00095 {
00096 Dout(dc::objects, "Constructing ServerConnection(" << (void*)identity << ")");
00097 }
00098
00099
00100 ServerConnection(Identity* identity, boost::shared_ptr<Server> server) :
00101 event_client_ct(), IdentityReference(identity),
00102 M_server(server), M_server_session(NULL),
00103 M_reconnect(false), M_connected(false), M_state(disconnected),
00104 M_connect_delay(S_connect_delay_init), M_timed_out(false), M_timed_out_count(0),
00105 M_secondary_connection(true), M_my_serverside_nick_name(random_nick())
00106 {
00107 Dout(dc::objects, "Constructing secondary ServerConnection(" << (void*)identity << ")");
00108 }
00109
00110
00111 ~ServerConnection()
00112 {
00113 Dout(dc::objects, "Destructing ServerConnection" << *this);
00114 cancel_all_requests();
00115 if (M_server_session)
00116 disconnect();
00117 }
00118
00119
00120 state_nt state(void) const { return M_state; }
00121
00122
00123 bool secondary_connection(void) const { return M_secondary_connection; }
00124
00125
00126 void set_my_serverside_nick_name(std::string const& my_serverside_nick_name)
00127 { ASSERT(M_secondary_connection); M_my_serverside_nick_name = my_serverside_nick_name; }
00128
00129
00130 std::string const& my_serverside_nick_name(void) const
00131 { ASSERT(M_secondary_connection); return M_my_serverside_nick_name; }
00132
00133
00134 void change_state(state_nt LIBCW_UNUSED_UNLESS_DEBUG(from), state_nt to)
00135 {
00136 Debug(ASSERT(M_state == from));
00137 M_state = to;
00138 }
00139
00140
00141 bool has_server(void) const { return M_server.get(); }
00142
00143
00144 boost::shared_ptr<Server const> server(void) const { ASSERT(has_server()); return boost::const_pointer_cast<Server const>(M_server); }
00145
00146
00147 boost::shared_ptr<Server> server(void) { ASSERT(has_server()); return M_server; }
00148
00149
00150 bool has_server_session(void) const { return M_server_session; }
00151
00152
00153 ServerSession const& server_session(void) const { return *M_server_session; }
00154
00155
00156 ServerSession& server_session(void) { return *M_server_session; }
00157
00158
00159 Network const& network(void) const { return server()->network(); }
00160
00161
00162 Network& network(void) { return server()->network(); }
00163
00164
00165 void connect(bool auto_reconnect);
00166
00167
00168 void disconnect(void)
00169 {
00170 DoutEntering(dc::debug, "ServerConnection::disconnect() for " << *this);
00171 ASSERT(M_server_session);
00172 M_reconnect = false;
00173
00174 M_server_session->del();
00175
00176 }
00177
00178 void session_lost(void);
00179 void delayed_connect(timer_event_type_ct const& expired_at);
00180 void connect_timed_out(timer_event_type_ct const& expired_at);
00181 void received_server_port_answer(UserAnswerEventType const& event_type);
00182 void error_message_received(ServerMessageIn const& msg);
00183 void successful_connection(void);
00184 void decode_ping(ServerMessageIn const& pong_msg);
00185 void send_pong_and_mode(ExpressionEventType const& event_type);
00186 void received_first_umode(MatcherEventType const& event_type);
00187 void quit(std::string const& msg);
00188
00189
00190 bool is_connected(void) const { return M_connected; }
00191
00192
00193 bool reconnect(void) const { return M_reconnect; }
00194
00195
00196 timeval connect_delay(void) const { return M_connect_delay; }
00197
00198
00199 bool timed_out(void) const { return M_timed_out; }
00200
00201
00202 int timed_out_count(void) const { return M_timed_out_count; }
00203
00204
00205 void invisible_event(ExpressionEventType const&);
00206
00207
00208 void make_primary(void) { M_secondary_connection = false; }
00209
00210
00211 void make_secondary(void) { M_secondary_connection = true; }
00212
00213 private:
00214 void do_connect(void);
00215
00216 friend std::ostream& operator<<(std::ostream& os, ServerConnection const& server_connection);
00217 };
00218
00219 #endif // SERVERCONNECTION_H