FS2_Open
Open source remastering of the Freespace 2 engine
multi_kick.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 
11 
12 
13 #include "globalincs/pstypes.h"
14 #include "network/multi.h"
15 #include "network/multi_kick.h"
16 #include "network/multimsgs.h"
17 #include "network/multiutil.h"
18 #include "freespace2/freespace.h"
19 #include "playerman/player.h"
20 #include "io/timer.h"
21 #include "debugconsole/console.h"
22 
23 
24 // ----------------------------------------------------------------------------------
25 // KICK DEFINES/VARS
26 //
27 
28 #define MULTI_KICK_RESPONSE_TIME 4000 // if someone who has been kicked has not responded in this time, disconnect him hard
29 
30 #define MAX_BAN_SLOTS 30
32 int Multi_kick_num_ban_slots; // the # of banned addresses
33 
34 // ----------------------------------------------------------------------------------
35 // KICK FORWARD DECLARATIONS
36 //
37 
38 // send a player kick packet
39 void send_player_kick_packet(int player_index, int ban = 1, int reason = KICK_REASON_NORM);
40 
41 // process a player kick packet
43 
44 // add a net address to the banned list
46 
47 // can the given player perform a kick
49 
50 
51 // ----------------------------------------------------------------------------------
52 // KICK FUNCTIONS
53 //
54 
55 // initialize all kicking details (ban lists, etc). it is safe to call this function at any time
57 {
58  // blast all the ban slots
59  memset(Multi_kick_ban_slots,0,sizeof(net_addr)*MAX_BAN_SLOTS);
61 }
62 
63 // process all kick details (disconnecting players who have been kicked but haven't closed their socket)
65 {
66  int idx;
67 
68  // if i'm not the server, don't do anything
70  return;
71  }
72 
73  // disconnect any kicked players who have timed out on leaving
74  for(idx=0;idx<MAX_PLAYERS;idx++){
75  if(MULTI_CONNECTED(Net_players[idx]) && (Net_players[idx].s_info.kick_timestamp != -1) && timestamp_elapsed(Net_players[idx].s_info.kick_timestamp) ){
76  delete_player(idx, Net_players[idx].s_info.kick_reason);
77  }
78  }
79 }
80 
81 // attempt to kick a player. return success or fail
82 void multi_kick_player(int player_index, int ban, int reason)
83 {
84  // only the standalone should be able to kick the host of the game
86  nprintf(("Network","Cannot kick the host or server of a game!\n"));
87  } else {
88  // if we're the master, then delete the guy
89  if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
90  // if we're supposed to ban him, add his address to the banned list
91  if(ban){
92  multi_kick_add_ban(&Net_players[player_index].p_info.addr);
93  }
94 
95  // mark him as having been kicked
96  Net_players[player_index].flags |= NETINFO_FLAG_KICKED;
97 
98  // set his kick timestamp and send him a leave game packet
100  Net_players[player_index].s_info.kick_reason = reason;
101  send_leave_game_packet(Net_players[player_index].player_id, reason, &Net_players[player_index]);
102 
103  // tell everyone else that he was kicked
104  send_leave_game_packet(Net_players[player_index].player_id, reason);
105 
106  // wait until he either shuts his connection down or he times out)
107  // add the string to the chatbox and the hud (always safe - if it is not inited, nothing bad will happen)
108  char str[512];
109  memset(str, 0, 512);
110  sprintf(str, XSTR("<kicking %s ...>", 1501), Net_players[player_index].m_player->callsign);
111  multi_display_chat_msg(str, player_index, 0);
112  }
113  // otherwise, we should send the packet indicating that this guy should be kicked
114  else {
115  send_player_kick_packet(player_index, ban, reason);
116  }
117  }
118 }
119 
120 // is this net address currently kicked and banded
122 {
123  int idx;
124 
125  // traverse the banned list
126  for(idx=0;idx<Multi_kick_num_ban_slots;idx++){
127  // if we found a duplicate
128  if(psnet_same(&Multi_kick_ban_slots[idx],addr)){
129  return 1;
130  }
131  }
132 
133  // he's not banned
134  return 0;
135 }
136 
137 // debug console function called to determine which player to kick
139 {
140  int player_num,idx;
141  SCP_string arg;
142 
143  // get the callsign of the player to kick
144  dc_stuff_string(arg);
145 
146  player_num = -1;
147  for(idx=0;idx<MAX_PLAYERS;idx++){
148  if(MULTI_CONNECTED(Net_players[idx]) && (stricmp(Net_players[idx].m_player->callsign, arg.c_str()) == 0)) {
149  player_num = idx;
150  break;
151  }
152  }
153 
154  // if we didn't find the player, notify of the results
155  if(player_num == -1){
156  dc_printf("Could not find player %s to kick!", arg.c_str());
157  }
158  // if we found the guy, then try and kick him
159  else {
160  multi_kick_player(player_num);
161  }
162 }
163 
164 // fill in the passed string with the appropriate "kicked" string
165 void multi_kick_get_text(net_player *pl, int reason, char *str)
166 {
167  // safety net
168  if((pl == NULL) || (pl->m_player == NULL)){
169  strcpy(str, NOX(""));
170  return;
171  }
172 
173  switch(reason){
175  sprintf(str, XSTR("<%s was kicked because of mission file xfer failure>", 1003), pl->m_player->callsign);
176  break;
178  sprintf(str, XSTR("<%s was kicked for not having builtin mission %s>", 1004), pl->m_player->callsign, Game_current_mission_filename);
179  break;
181  sprintf(str, XSTR("<%s was kicked for ingame joining an ended game>",1005), pl->m_player->callsign);
182  break;
183  default:
184  sprintf(str, XSTR("<%s was kicked>",687), pl->m_player->callsign);
185  break;
186  }
187 }
188 
189 
190 // ----------------------------------------------------------------------------------
191 // KICK FORWARD DEFINITIONS
192 //
193 
194 // add a net address to the banned list
196 {
197  // if we still have any slots left
199  memcpy(&Multi_kick_ban_slots[Multi_kick_num_ban_slots++],addr,sizeof(net_addr));
200  }
201 }
202 
203 
204 // ----------------------------------------------------------------------------------
205 // KICK PACKET HANDLERS
206 //
207 
208 // send a player kick packet
209 void send_player_kick_packet(int player_index, int ban, int reason)
210 {
212  int packet_size = 0;
213 
215 
216  // add the address of the player to be kicked
217  ADD_SHORT(Net_players[player_index].player_id);
218 
219  // indicate if he should be banned
220  ADD_INT(ban);
221  ADD_INT(reason);
222 
223  // send the request to the server
224  multi_io_send_reliable(Net_player, data, packet_size);
225 }
226 
227 // process a player kick packet
229 {
230  int player_num,from_player,ban,reason;
231  short player_id;
232  int offset = HEADER_LENGTH;
233 
234  // get the address of the guy who is to be kicked
235  GET_SHORT(player_id);
236  GET_INT(ban);
237  GET_INT(reason);
238  player_num = find_player_id(player_id);
239  PACKET_SET_SIZE();
240 
241  // only the server should ever receive a request to kick a guy
243 
244  // determine who sent the packet
245  from_player = find_player_id(hinfo->id);
246 
247  // check to see if this guy is allowed to make such a request
248  if((from_player == -1) || !multi_kick_can_kick(&Net_players[from_player]) ){
249  nprintf(("Network","Received a kick request from an invalid player!!\n"));
250  }
251  // otherwise, process the request fully
252  else {
253  // make sure we have a valid player to kick
254  if(player_num == -1){
255  nprintf(("Network","Received request to kick an unknown player!\n"));
256  } else {
257  // will handle all the rest of the details
258  multi_kick_player(player_num,ban,reason);
259  }
260  }
261 }
262 
263 // can the given player perform a kick
265 {
266  // only host or server can kick
267  if((player->flags & NETINFO_FLAG_AM_MASTER) || (player->flags & NETINFO_FLAG_GAME_HOST)){
268  return 1;
269  }
270 
271  // this guy cannot kick
272  return 0;
273 }
int timestamp(int delta_ms)
Definition: timer.cpp:226
int multi_kick_can_kick(net_player *player)
Definition: multi_kick.cpp:264
int Game_mode
Definition: systemvars.cpp:24
char Game_current_mission_filename[MAX_FILENAME_LEN]
Definition: fredstubs.cpp:26
net_player * Net_player
Definition: multi.cpp:94
#define PACKET_SET_SIZE()
Definition: multimsgs.h:57
player * m_player
Definition: multi.h:459
Assert(pm!=NULL)
#define KICK_REASON_BAD_XFER
Definition: multi_kick.h:24
void multi_io_send_reliable(net_player *pl, ubyte *data, int len)
Definition: multimsgs.cpp:459
int find_player_id(short player_id)
Definition: multiutil.cpp:465
#define KICK_PLAYER
Definition: multi.h:177
std::basic_string< char, std::char_traits< char >, std::allocator< char > > SCP_string
Definition: vmallocator.h:21
int flags
Definition: multi.h:463
int packet_size
Definition: multi_sexp.cpp:41
char callsign[CALLSIGN_LEN+1]
Definition: player.h:91
int psnet_same(net_addr *a1, net_addr *a2)
Definition: psnet2.cpp:785
void dc_stuff_string(char *out_str, size_t maxlen=MAX_TOKEN_LENGTH)
Stuffs a string to out_str from the command line, stopping at the end of the command line...
#define ADD_INT(d)
Definition: multimsgs.h:40
#define MAX_PACKET_SIZE
Definition: psnet2.h:34
void multi_display_chat_msg(const char *msg, int player_index, int add_id)
Definition: multiutil.cpp:2895
GLintptr offset
Definition: Glext.h:5497
Definition: player.h:85
void multi_kick_player(int player_index, int ban, int reason)
Definition: multi_kick.cpp:82
#define NETINFO_FLAG_AM_MASTER
Definition: multi.h:599
#define nprintf(args)
Definition: pstypes.h:239
#define BUILD_HEADER(t)
Definition: multimsgs.h:36
int Multi_kick_num_ban_slots
Definition: multi_kick.cpp:32
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
net_player_server_info s_info
Definition: multi.h:472
void multi_kick_init()
Definition: multi_kick.cpp:56
#define MAX_PLAYERS
Definition: pstypes.h:32
#define ADD_SHORT(d)
Definition: multimsgs.h:38
#define NETINFO_FLAG_GAME_HOST
Definition: multi.h:603
#define KICK_REASON_CANT_XFER
Definition: multi_kick.h:25
void send_player_kick_packet(int player_index, int ban=1, int reason=KICK_REASON_NORM)
Definition: multi_kick.cpp:209
int idx
Definition: multiui.cpp:761
void multi_kick_add_ban(net_addr *addr)
Definition: multi_kick.cpp:195
unsigned char ubyte
Definition: pstypes.h:62
const char * XSTR(const char *str, int index)
Definition: localize.cpp:851
void multi_kick_get_text(net_player *pl, int reason, char *str)
Definition: multi_kick.cpp:165
#define NOX(s)
Definition: pstypes.h:473
#define GM_STANDALONE_SERVER
Definition: systemvars.h:27
GLbitfield flags
Definition: Glext.h:6722
void delete_player(int player_num, int kicked_reason)
Definition: multiutil.cpp:862
#define MULTI_CONNECTED(np)
Definition: multi.h:136
void process_player_kick_packet(ubyte *data, header *hinfo)
Definition: multi_kick.cpp:228
Definition: multi.h:385
#define MAX_BAN_SLOTS
Definition: multi_kick.cpp:30
void multi_dcf_kick()
Definition: multi_kick.cpp:138
int HEADER_LENGTH
Definition: multi.cpp:106
An overhauled/updated debug console to allow monitoring, testing, and general debugging of new featur...
void multi_kick_process()
Definition: multi_kick.cpp:64
GLenum GLsizei GLenum GLenum const GLvoid * data
Definition: Gl.h:1509
#define timestamp_elapsed(stamp)
Definition: timer.h:102
short id
Definition: multi.h:390
#define NETINFO_FLAG_KICKED
Definition: multi.h:613
int multi_kick_is_banned(net_addr *addr)
Definition: multi_kick.cpp:121
#define GET_SHORT(d)
Definition: multimsgs.h:48
void dc_printf(const char *format,...)
Prints the given char string to the debug console.
Definition: console.cpp:358
#define KICK_REASON_INGAME_ENDED
Definition: multi_kick.h:26
#define GET_INT(d)
Definition: multimsgs.h:50
#define KICK_REASON_NORM
Definition: multi_kick.h:23
net_addr Multi_kick_ban_slots[MAX_BAN_SLOTS]
Definition: multi_kick.cpp:31
GLenum const GLvoid * addr
Definition: Glext.h:9092
void send_leave_game_packet(short player_id, int kicked_reason, net_player *target)
Definition: multimsgs.cpp:1680
net_player Net_players[MAX_PLAYERS]
Definition: multi.cpp:93
#define stricmp(s1, s2)
Definition: config.h:271
#define MULTI_KICK_RESPONSE_TIME
Definition: multi_kick.cpp:28