10 #include <sys/ioctl.h>
11 #include <sys/socket.h>
12 #include <sys/select.h>
16 #endif /* __WIN32__ */
31 static sock_udp_t
*sock_server_udp
;
33 static list_t
*listRecvMsg
;
35 static buffer_t
*clientRecvBuffer
;
36 static buffer_t
*clientSendBuffer
;
38 static my_time_t lastPing
;
39 static my_time_t lastPingServerAlive
;
41 #ifdef SUPPORT_TRAFFIC
42 static my_time_t lastTraffic
;
43 static int traffic_down
;
44 static int traffic_up
;
45 #endif /* SUPPORT_TRAFFIC */
47 typedef struct proto_cmd_client_struct
{
50 void (*fce_proto
) (char *msg
);
53 static proto_cmd_client_t proto_cmd_list
[] = {
54 {.name
= "error",.len
= 5,.fce_proto
= proto_recv_error_client
},
55 {.name
= "init",.len
= 4,.fce_proto
= proto_recv_init_client
},
56 {.name
= "event",.len
= 5,.fce_proto
= proto_recv_event_client
},
57 {.name
= "newtux",.len
= 6,.fce_proto
= proto_recv_newtux_client
},
58 {.name
= "del",.len
= 3,.fce_proto
= proto_recv_del_client
},
59 {.name
= "additem",.len
= 7,.fce_proto
= proto_recv_additem_client
},
60 {.name
= "shot",.len
= 4,.fce_proto
= proto_recv_shot_client
},
61 {.name
= "kill",.len
= 4,.fce_proto
= proto_recv_kill_client
},
62 {.name
= "module",.len
= 6,.fce_proto
= proto_recv_module_client
},
63 {.name
= "chat",.len
= 4,.fce_proto
= proto_recv_chat_client
},
64 {.name
= "ping",.len
= 4,.fce_proto
= proto_recv_ping_client
},
65 {.name
= "end",.len
= 3,.fce_proto
= proto_recv_end_client
},
66 {.name
= "",.len
= 0,.fce_proto
= NULL
}
69 static proto_cmd_client_t
*findCmdProto(char *msg
)
76 for (i
= 0; proto_cmd_list
[i
].len
!= 0; i
++) {
77 proto_cmd_client_t
*thisCmd
;
79 thisCmd
= &proto_cmd_list
[i
];
81 if (len
>= thisCmd
->len
&&
82 strncmp(msg
, thisCmd
->name
, thisCmd
->len
) == 0) {
90 static int initUdpClient(char *ip
, int port
)
92 sock_server_udp
= sock_udp_connect(ip
, port
);
94 if (sock_server_udp
== NULL
) {
98 debug("Connected to game server [%s]:[%d]", ip
, port
);
103 int client_init(char *ip
, int port
)
105 char name
[STR_NAME_SIZE
];
108 listRecvMsg
= list_new();
109 lastPing
= timer_get_current_time();
110 lastPingServerAlive
= timer_get_current_time();
112 #ifdef SUPPORT_TRAFFIC
113 lastTraffic
= timer_get_current_time();
116 #endif /* SUPPORT_TRAFFIC */
118 clientRecvBuffer
= buffer_new(CLIENT_BUFFER_LIMIT
);
119 clientSendBuffer
= buffer_new(CLIENT_BUFFER_LIMIT
);
121 ret
= initUdpClient(ip
, port
);
127 public_server_get_setting_name_right(name
);
128 proto_send_hello_client(name
);
133 static void errorWithServer()
135 error("Game server is not responding");
136 analyze_set_msg(_("Unable to connect to the game server"));
140 void client_send(char *msg
)
148 if (isParamFlag("--send")) {
149 debug("Sending data: %s", msg
);
152 #ifdef SUPPORT_TRAFFIC
153 traffic_up
+= strlen(msg
);
154 #endif /* SUPPORT_TRAFFIC */
156 if (sock_server_udp
!= NULL
) {
157 ret
= sock_udp_write(sock_server_udp
, sock_server_udp
, msg
, strlen(msg
));
166 static int server_eventSelect()
168 char buffer
[STR_PROTO_SIZE
];
171 memset(buffer
, 0, STR_PROTO_SIZE
);
174 if (sock_server_udp
!= NULL
) {
175 ret
= sock_udp_read(sock_server_udp
, sock_server_udp
, buffer
, STR_PROTO_SIZE
- 1);
183 #ifdef SUPPORT_TRAFFIC
185 #endif /* SUPPORT_TRAFFIC */
187 list_add(listRecvMsg
, strdup(buffer
));
192 static void client_eventWorkRecvList()
194 proto_cmd_client_t
*protoCmd
;
198 /* processing of an event received from a game server */
200 assert(listRecvMsg
!= NULL
);
202 for (i
= 0; i
< listRecvMsg
->count
; i
++) {
203 line
= (char *) listRecvMsg
->list
[i
];
204 protoCmd
= findCmdProto(line
);
206 if (isParamFlag("--recv")) {
207 debug("Recieved data: %s", line
);
210 if (protoCmd
!= NULL
) {
211 protoCmd
->fce_proto(line
);
212 lastPingServerAlive
= timer_get_current_time();
216 list_destroy_item(listRecvMsg
, free
);
217 listRecvMsg
= list_new();
220 static void eventPingServer()
222 my_time_t currentTime
;
224 currentTime
= timer_get_current_time();
226 if (currentTime
- lastPing
> CLIENT_TIMEOUT
) {
227 proto_send_ping_client();
228 lastPing
= timer_get_current_time();
232 static bool_t
isServerAlive()
234 my_time_t currentTime
;
236 currentTime
= timer_get_current_time();
238 if (currentTime
- lastPingServerAlive
> SERVER_TIMEOUT_ALIVE
) {
245 static void selectClientSocket()
256 if (sock_server_udp
!= NULL
) {
257 if (isServerAlive() == FALSE
) {
271 if (sock_server_udp
!= NULL
) {
272 sock
= sock_server_udp
->sock
;
275 FD_SET(sock
, &readfds
);
277 select(max_fd
+ 1, &readfds
, (fd_set
*) NULL
, (fd_set
*) NULL
, &tv
);
279 if (FD_ISSET(sock
, &readfds
)) {
280 if (server_eventSelect() > 0) {
285 } while (isNext
== TRUE
);
288 #ifdef SUPPORT_TRAFFIC
289 static void eventTraffic()
291 my_time_t currentTime
;
293 currentTime
= timer_get_current_time();
295 if (currentTime
- lastTraffic
> 5000) {
296 lastTraffic
= currentTime
;
298 debug("Traffic: down [%d]/up [%d]", traffic_down
, traffic_up
);
304 #endif /* SUPPORT_TRAFFIC */
308 #ifdef SUPPORT_TRAFFIC
310 #endif /* SUPPORT_TRAFFIC */
313 selectClientSocket();
314 client_eventWorkRecvList();
317 static void quitUdpClient()
319 assert(sock_server_udp
!= NULL
);
320 sock_udp_close(sock_server_udp
);
322 debug("Closing connection to game server");
327 proto_send_end_client();
329 assert(listRecvMsg
!= NULL
);
331 list_destroy_item(listRecvMsg
, free
);
332 buffer_destroy(clientRecvBuffer
);
333 buffer_destroy(clientSendBuffer
);
335 if (sock_server_udp
!= NULL
) {