FS2_Open
Open source remastering of the Freespace 2 engine
multi_data.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 <time.h>
14 #include <ctype.h>
15 
16 #include "network/multi.h"
17 #include "network/multi_data.h"
18 #include "network/multi_xfer.h"
19 #include "network/multiutil.h"
20 #include "playerman/player.h"
21 #include "cfile/cfile.h"
22 #include "globalincs/systemvars.h"
23 
24 
25 
26 // -------------------------------------------------------------------------
27 // MULTI DATA DEFINES/VARS
28 //
29 
30 #define MAX_MULTI_DATA 40
31 
32 // player data struct
33 typedef struct np_data {
34  ushort player_id; // id of the player who sent the file
35  char filename[MAX_FILENAME_LEN+1]; // filename
36  ubyte status[MAX_PLAYERS]; // status for all players (0 == don't have it, 1 == have or sending, 2 == i sent it originally)
37  ubyte used; // in use or not
38 } np_data;
39 
41 
42 // this doesn't travel off platform to don't _fs_time_t it
43 time_t Multi_data_time = 0;
44 
45 
46 // -------------------------------------------------------------------------
47 // MULTI DATA FORWARD DECLARATIONS
48 //
49 
50 // is the given filename for a "multi data" file (pcx, wav, etc)
51 int multi_data_is_data(char *filename);
52 
53 // get a free np_data slot
55 
56 // server side - add a new file
57 int multi_data_add_new(char *filename, int player_index);
58 
59 // maybe try and reload player squad logo bitmaps
61 
62 
63 // -------------------------------------------------------------------------
64 // MULTI DATA FUNCTIONS
65 //
66 
67 // reset the data xfer system
69 {
70  int idx;
71 
72  // clear out all used bits
73  for(idx=0; idx<MAX_MULTI_DATA; idx++){
74  Multi_data[idx].used = 0;
75  }
76 }
77 
78 // handle a player join (clear out lists of files, etc)
79 void multi_data_handle_join(int player_index)
80 {
81  int idx;
82 
83  // clear out his status for all files
84  for(idx=0;idx<MAX_MULTI_DATA;idx++){
85  Multi_data[idx].status[player_index] = 0;
86  }
87 }
88 
89 // handle a player drop (essentially the same as multi_data_handle_join)
90 void multi_data_handle_drop(int player_index)
91 {
92  int idx;
93 
94  // mark all files he sent as being unused
95  for(idx=0;idx<MAX_MULTI_DATA;idx++){
96  if(Multi_data[idx].player_id == Net_players[player_index].player_id){
97  Multi_data[idx].used = 0;
98  }
99  }
100 }
101 
102 // do all sync related data stuff (server-side only)
104 {
105  int idx, p_idx;
106 
107  // only do this once a second
108  if((time(NULL) - Multi_data_time) < 1){
109  return;
110  }
111 
112  // maybe try and reload player squad logo bitmaps
114 
115  // reset the time
116  Multi_data_time = time(NULL);
117 
118  // if I'm the server
120  // for all valid files
121  for(idx=0; idx<MAX_MULTI_DATA; idx++){
122  // a valid file that isn't currently xferring (ie, anything we've got completely on our hard drive)
123  if(Multi_data[idx].used && (multi_xfer_lookup(Multi_data[idx].filename) < 0)){
124  // send it to all players who need it
125  for(p_idx=0; p_idx<MAX_PLAYERS; p_idx++){
126  // if he doesn't have it
127  if((Net_player != &Net_players[p_idx]) && MULTI_CONNECTED(Net_players[p_idx]) && (Net_players[p_idx].reliable_socket != INVALID_SOCKET) && (Multi_data[idx].status[p_idx] == 0)){
128  // queue up the file to send to him, or at least try to
130  nprintf(("Network", "Failed to send data file! Trying again later...\n"));
131  } else {
132  // mark his status
133  Multi_data[idx].status[p_idx] = 1;
134  }
135  }
136  }
137  }
138  }
139  }
140 }
141 
142 // handle an incoming xfer request from the xfer system
144 {
145  int player_index = -1;
147  char *fname;
148 
149  // get the player who is sending us this file
150  sock = multi_xfer_get_sock(handle);
151  player_index = find_player_socket(sock);
152 
153  // get the filename of the file
154  fname = multi_xfer_get_filename(handle);
155  if(fname == NULL){
156  nprintf(("Network", "Could not get file xfer filename! wacky...!\n"));
157 
158  // kill the stream
160  return;
161  }
162 
163  // if this is not a valid data file
164  if(!multi_data_is_data(fname)){
165  nprintf(("Network", "Not accepting xfer request because its not a valid data file!\n"));
166 
167  // kill the stream
169  return;
170  }
171 
172  // if we already have a copy of this file, abort the xfer
173  // Does file exist in \multidata?
174  if (cf_exists(fname, CF_TYPE_MULTI_CACHE)) {
175  nprintf(("Network", "Not accepting file xfer because a duplicate exists!\n"));
176 
177  // kill the stream
179 
180  // if we're the server, we still need to add it to the list though
181  if((Net_player->flags & NETINFO_FLAG_AM_MASTER) && (player_index >= 0)){
182  multi_data_add_new(fname, player_index);
183  }
184  return;
185  }
186 
187  // if I'm the server of the game, do stuff a little differently
189  if(player_index == -1){
190  nprintf(("Network", "Could not find player for incoming player data stream!\n"));
191 
192  // kill the stream
194  return;
195  }
196 
197  // attempt to add the file
198  if(!multi_data_add_new(fname, player_index)){
199  // kill the stream
201  return;
202  } else {
203  // force the file to go into the multi cache directory
205 
206  // mark it as autodestroy
208  }
209  }
210  // if i'm a client, this is an incoming file from the server
211  else {
212  // if i'm not accepting pilot pics, abort
214  nprintf(("Network", "Client not accepting files because we don't want 'em!\n"));
215 
216  // kill the stream
218  return;
219  }
220 
221  // set the xfer handle to autodestroy itself since we don't really want to have to manage all incoming pics
223 
224  // force the file to go into the multi cache directory
226 
227  // begin receiving the file
228  nprintf(("Network", "Client receiving xfer handle %d\n",handle));
229  }
230 }
231 
232 // send all my files as necessary
234 {
235  char *with_ext;
236  int bmap, w, h;
237  int ok_to_send = 1;
238 
239  // pilot pic --------------------------------------------------------------
240 
241  // verify that my pilot pic is valid
242  if(strlen(Net_player->m_player->image_filename)){
244  if(bmap == -1){
245  ok_to_send = 0;
246  }
247 
248  // verify image dimensions
249  if(ok_to_send){
250  w = -1;
251  h = -1;
252  bm_get_info(bmap,&w,&h);
253 
254  // release the bitmap
255  bm_release(bmap);
256  bmap = -1;
257 
258  // if the dimensions are invalid, kill the filename
259  if((w != PLAYER_PILOT_PIC_W) || (h != PLAYER_PILOT_PIC_H)){
260  ok_to_send = 0;
261  }
262  }
263  } else {
264  ok_to_send = 0;
265  }
266 
267  if(ok_to_send){
268  with_ext = cf_add_ext(Net_player->m_player->image_filename, NOX(".pcx"));
269  if(with_ext != NULL){
271  }
272 
273  // host should put his own pic file in the list now
276  }
277  // otherwise clients should just queue up a send
278  else {
279  // add a file extension if necessary
281  }
282  }
283 
284 
285  // squad logo --------------------------------------------------------------
286 
287  // verify that my pilot pic is valid
288  ok_to_send = 1;
289  if(strlen(Net_player->m_player->m_squad_filename)){
291  if(bmap == -1){
292  ok_to_send = 0;
293  }
294 
295  if(ok_to_send){
296  // verify image dimensions
297  w = -1;
298  h = -1;
299  bm_get_info(bmap,&w,&h);
300 
301  // release the bitmap
302  bm_release(bmap);
303  bmap = -1;
304 
305  // if the dimensions are invalid, kill the filename
306  if((w != PLAYER_SQUAD_PIC_W) || (h != PLAYER_SQUAD_PIC_H)){
307  ok_to_send = 0;
308  }
309  }
310  } else {
311  ok_to_send = 0;
312  }
313 
314  if(ok_to_send){
315  with_ext = cf_add_ext(Net_player->m_player->m_squad_filename, NOX(".pcx"));
316  if(with_ext != NULL){
318  }
319 
320  // host should put his own pic file in the list now
323  }
324  // otherwise clients should just queue up a send
325  else {
326  // add a file extension if necessary
328  }
329  }
330 }
331 
332 
333 // -------------------------------------------------------------------------
334 // MULTI DATA FORWARD DECLARATIONS
335 //
336 
337 // is the give file xfer handle for a "multi data" file (pcx, wav, etc)
339 {
340  int len,idx;
341 
342  Assert(filename != NULL);
343 
344  // some kind of error
345  if(filename == NULL){
346  return 0;
347  }
348 
349  // convert to lowercase
350  len = strlen(filename);
351  for(idx=0;idx<len;idx++){
352  filename[idx] = (char)tolower(filename[idx]);
353  }
354 
355  // check to see if the extension is .pcx
356  if(strstr(filename, NOX(".pcx"))){
357  return 1;
358  }
359 
360  // not a data file
361  return 0;
362 }
363 
364 // get a free np_data slot
366 {
367  int idx;
368 
369  // find a free slot
370  for(idx=0; idx<MAX_MULTI_DATA; idx++){
371  if(!Multi_data[idx].used){
372  return idx;
373  }
374  }
375 
376  // couldn't find one
377  return -1;
378 }
379 
380 // server side - add a new file. return 1 on success
381 int multi_data_add_new(char *filename, int player_index)
382 {
383  int slot;
384 
385  // try and get a free slot
386  slot = multi_data_get_free();
387  if(slot < 0){
388  nprintf(("Network", "Could not get free np_data slot! yikes!\n"));
389  return 0;
390  }
391 
392  // if the netgame isn't flagged as accepting data files
394  nprintf(("Network", "Server not accepting pilot pic because we don't want 'em!\n"));
395  return 0;
396  }
397 
398  // assign the data
399  memset(&Multi_data[slot], 0, sizeof(np_data)); // clear the slot out
400  strcpy_s(Multi_data[slot].filename, filename); // copy the filename
401  Multi_data[slot].used = 1; // set it as being in use
402  Multi_data[slot].player_id = Net_players[player_index].player_id; // player id of who's sending the file
403  Multi_data[slot].status[player_index] = 2; // mark his status appropriately
404 
405  // success
406  return 1;
407 }
408 
409 // maybe try and reload player squad logo bitmaps
411 {
412  int idx;
413 
414  // go through all connected and try to reload their images if necessary
415  for(idx=0; idx<MAX_PLAYERS; idx++){
416  if(MULTI_CONNECTED(Net_players[idx]) && strlen(Net_players[idx].m_player->m_squad_filename) && (Net_players[idx].m_player->insignia_texture == -1)){
417  Net_players[idx].m_player->insignia_texture = bm_load_duplicate(Net_players[idx].m_player->m_squad_filename);
418 
419  // if the bitmap loaded properly, lock it as a transparent texture
420  if(Net_players[idx].m_player->insignia_texture != -1){
421  bm_lock(Net_players[idx].m_player->insignia_texture, 16, BMP_TEX_XPARENT);
422  bm_unlock(Net_players[idx].m_player->insignia_texture);
423  }
424  }
425  }
426 }
#define PLAYER_SQUAD_PIC_H
Definition: player.h:33
void bm_unlock(int handle)
Unlocks a bitmap.
Definition: bmpman.cpp:3005
#define MAX_FILENAME_LEN
Definition: pstypes.h:324
void multi_data_do()
Definition: multi_data.cpp:103
#define MY_NET_PLAYER_NUM
Definition: multi.h:127
char image_filename[MAX_FILENAME_LEN+1]
Definition: player.h:95
int Game_mode
Definition: systemvars.cpp:24
GLfloat GLfloat GLfloat GLfloat h
Definition: Glext.h:7280
net_player * Net_player
Definition: multi.cpp:94
char * multi_xfer_get_filename(int handle)
Definition: multi_xfer.cpp:370
uint PSNET_SOCKET_RELIABLE
Definition: multi_xfer.h:20
player * m_player
Definition: multi.h:459
#define MULTI_XFER_FLAG_QUEUE
Definition: multi_xfer.h:38
ushort player_id
Definition: multi_data.cpp:34
int insignia_texture
Definition: player.h:195
Assert(pm!=NULL)
int bm_get_info(int handle, int *w, int *h, ubyte *flags, int *nframes, int *fps)
Gets info on the bitmap indexed by handle.
Definition: bmpman.cpp:769
int multi_xfer_lookup(char *filename)
Definition: multi_xfer.cpp:438
int bm_load_duplicate(const char *filename)
Reloads a bitmap as a duplicate.
Definition: bmpman.cpp:1668
#define INVALID_SOCKET
Definition: psnet2.h:53
#define PLAYER_SQUAD_PIC_W
Definition: player.h:32
int flags
Definition: multi.h:463
int bm_release(int handle, int clear_render_targets)
Frees both a bitmap's data and it's associated slot.
Definition: bmpman.cpp:2603
#define CF_TYPE_MULTI_CACHE
Definition: cfile.h:73
#define MULTI_XFER_FLAG_AUTODESTROY
Definition: multi_xfer.h:31
void multi_data_send_my_junk()
Definition: multi_data.cpp:233
void multi_data_handle_incoming(int handle)
Definition: multi_data.cpp:143
net_player_info p_info
Definition: multi.h:473
#define NETINFO_FLAG_AM_MASTER
Definition: multi.h:599
#define nprintf(args)
Definition: pstypes.h:239
multi_server_options options
Definition: multi.h:514
PSNET_SOCKET_RELIABLE reliable_socket
Definition: multi.h:465
char * filename
netgame_info Netgame
Definition: multi.cpp:97
void multi_xfer_handle_force_dir(int handle, int cf_type)
Definition: multi_xfer.cpp:401
#define w(p)
Definition: modelsinc.h:68
void multi_data_maybe_reload()
Definition: multi_data.cpp:410
void multi_xfer_xor_flags(int handle, int flags)
Definition: multi_xfer.cpp:414
#define MULTI_XFER_FLAG_REJECT
Definition: multi_xfer.h:32
int multi_xfer_send_file(PSNET_SOCKET_RELIABLE who, char *filename, int cfile_flags, int flags)
Definition: multi_xfer.cpp:201
void multi_data_handle_drop(int player_index)
Definition: multi_data.cpp:90
#define MAX_PLAYERS
Definition: pstypes.h:32
bitmap * bm_lock(int handle, ubyte bpp, ubyte flags, bool nodebug)
Locks down the bitmap indexed by bitmapnum.
Definition: bmpman.cpp:1754
short player_id
Definition: multi.h:460
void multi_data_handle_join(int player_index)
Definition: multi_data.cpp:79
#define MAX_MULTI_DATA
Definition: multi_data.cpp:30
int idx
Definition: multiui.cpp:761
unsigned char ubyte
Definition: pstypes.h:62
#define NOX(s)
Definition: pstypes.h:473
char filename[MAX_FILENAME_LEN+1]
Definition: multi_data.cpp:35
#define GM_STANDALONE_SERVER
Definition: systemvars.h:27
char * cf_add_ext(const char *filename, const char *ext)
Definition: cfile.cpp:458
int bm_load(const char *real_filename)
Loads a bitmap so we can draw with it later.
Definition: bmpman.cpp:1119
time_t Multi_data_time
Definition: multi_data.cpp:43
np_data Multi_data[MAX_MULTI_DATA]
Definition: multi_data.cpp:40
ubyte used
Definition: multi_data.cpp:37
int multi_data_get_free()
Definition: multi_data.cpp:365
ubyte status[MAX_PLAYERS]
Definition: multi_data.cpp:36
#define MULTI_CONNECTED(np)
Definition: multi.h:136
int multi_data_add_new(char *filename, int player_index)
Definition: multi_data.cpp:381
unsigned short ushort
Definition: pstypes.h:63
void multi_data_reset()
Definition: multi_data.cpp:68
uint multi_xfer_get_sock(int handle)
Definition: multi_xfer.cpp:477
#define MSO_FLAG_ACCEPT_PIX
#define MLO_FLAG_ACCEPT_PIX
Definition: multi_options.h:99
GLenum GLsizei len
Definition: Glext.h:6283
int find_player_socket(PSNET_SOCKET_RELIABLE sock)
Definition: multiutil.cpp:482
#define PLAYER_PILOT_PIC_W
Definition: player.h:29
char m_squad_filename[MAX_FILENAME_LEN+1]
Definition: player.h:98
int multi_data_is_data(char *filename)
Definition: multi_data.cpp:338
#define BMP_TEX_XPARENT
transparent texture
Definition: bmpman.h:53
#define CF_TYPE_ANY
Definition: cfile.h:42
net_player Net_players[MAX_PLAYERS]
Definition: multi.cpp:93
#define PLAYER_PILOT_PIC_H
Definition: player.h:30
int cf_exists(const char *filename, int dir_type)
Definition: cfile.cpp:514
struct np_data np_data
multi_local_options options
Definition: multi.h:452
#define strcpy_s(...)
Definition: safe_strings.h:67