File: multi_sw.cpp

package info (click to toggle)
freespace2 24.2.0%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,716 kB
  • sloc: cpp: 595,001; ansic: 21,741; python: 1,174; sh: 457; makefile: 248; xml: 181
file content (325 lines) | stat: -rw-r--r-- 9,085 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
/*
 * Copyright (C) Volition, Inc. 2005.  All rights reserved.
 * 
 * All source code herein is the property of Volition, Inc. You may not sell 
 * or otherwise commercially exploit the source or things you created based on the 
 * source.
 *
*/

#include "globalincs/systemvars.h"
#include "localization/localize.h"
#include "network/multi.h"
#include "popup/popup.h"
#include "network/ptrack.h"
#include "network/multi_fstracker.h"
#include "network/multimsgs.h"
#include "network/multi_team.h"
#include "network/multi_sw.h"
#include "network/multi_pmsg.h"
#include "network/multiutil.h"
#include "freespace.h"

// ------------------------------------------------------------------------------------
// MULTIPLAYER SQUAD WAR DEFINES/VARS
//

// global request info
static squad_war_request Multi_sw_request;

// global result info
static squad_war_result Multi_sw_result;

// set on the host in response to a standalone sw query, -1 == waiting, 0 == fail, 1 == success
int Multi_sw_std_query = -1;

// match code
char Multi_sw_match_code[MATCH_CODE_LEN];

// reply from a standalone on a bad response
char Multi_sw_bad_reply[MAX_SQUAD_RESPONSE_LEN+1] = "";

// team scores
extern int Multi_team0_score;
extern int Multi_team1_score;

// ------------------------------------------------------------------------------------
// MULTIPLAYER SQUAD WAR FORWARD DECLARATIONS
//

// popup_till_condition do frame function for the host doing verification through the standalone
int multi_sw_query_tracker_A();

// condition do frame function for the standalone querying PXO
int multi_sw_query_tracker_B();

// stuff Multi_sw_request
void multi_sw_stuff_request(char *match_code);

// stuff Multi_sw_result
void multi_sw_stuff_result();

// verify that we have the proper # of players
int multi_sw_verify_squad_counts();


// ------------------------------------------------------------------------------------
// MULTIPLAYER SQUAD WAR FUNCTIONS
//

// call before loading level - mission sync phase. only the server need do this
void multi_sw_level_init()
{	
}

// determine if everything is ok to move forward for a squad war match
int multi_sw_ok_to_commit()
{
	char *ret;
	char match_code[MATCH_CODE_LEN] = "";	
	char bad_response[MAX_SQUAD_RESPONSE_LEN+1] = "";

	// make sure we have enough players per team
	if(!multi_sw_verify_squad_counts()){
		return 0;
	}		

	// prompt the host for the match code
	ret = popup_input(0, XSTR("Please enter the match code", 1076), 32);
	if(ret == nullptr){
		return 0;
	}
	SDL_strlcpy(match_code, ret, SDL_arraysize(match_code));

	SDL_strlcpy(Multi_sw_match_code, "", SDL_arraysize(Multi_sw_match_code));

	// if we're the server, do the nice case
	if(MULTIPLAYER_MASTER){
		// stuff match request
		multi_sw_stuff_request(match_code);
		
		// return an MSW_STATUS_* value
		if(multi_fs_tracker_validate_sw(&Multi_sw_request, bad_response, SDL_arraysize(bad_response)) == MSW_STATUS_VALID){
			// store the match code			
			SDL_strlcpy(Multi_sw_match_code, match_code, SDL_arraysize(Multi_sw_match_code));

			// success		
			return 1;
		} 
		// do - didn't check out properly
		else {
			if(strlen(bad_response) > 0){
				popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", bad_response);
			} else {
				popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", "Unknown");
			}
		}
	}
	// otherwise we have to do it through the standalone - ARRRGHH!
	else {
		// send the query packet and wait for a response
		Multi_sw_std_query = -1;
		memset(Multi_sw_bad_reply, 0, MAX_SQUAD_RESPONSE_LEN+1);
		send_sw_query_packet(SW_STD_START, match_code);
		if(popup_till_condition(multi_sw_query_tracker_A, XSTR("&Cancel", 667), XSTR("Validating squad war", 1075)) == 10){
			// success
			return 1;
		} else {
			if(strlen(Multi_sw_bad_reply) > 0){
				popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", Multi_sw_bad_reply);
			} else {
				popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, "Error validating Squad War match\n\n(%s)", "Unknown");
			}
		}
	}

	// hmm, should probably never get here
	return 0;
}

// query PXO on the standalone
void multi_sw_std_query(char *match_code)
{
	char bad_response[MAX_SQUAD_RESPONSE_LEN+1];

	// stuff match request
	multi_sw_stuff_request(match_code);	

	SDL_strlcpy(Multi_sw_match_code, "", SDL_arraysize(Multi_sw_match_code));

	// return an MSW_STATUS_* value
	if(multi_fs_tracker_validate_sw(&Multi_sw_request, bad_response, SDL_arraysize(bad_response)) != MSW_STATUS_VALID){
		send_sw_query_packet(SW_STD_BAD, bad_response);
	} else {
		// store the match code
		SDL_strlcpy(Multi_sw_match_code, match_code, SDL_arraysize(Multi_sw_match_code));
			
		send_sw_query_packet(SW_STD_OK, nullptr);
	}
}

// call to update everything on the tracker
#define SEND_AND_DISPLAY(mesg)		do { send_game_chat_packet(Net_player, mesg, MULTI_MSG_ALL, nullptr, nullptr, 1); multi_display_chat_msg(mesg, 0, 0); } while(false);
void multi_sw_report(int stats_saved)
{			
	char bad_response[MAX_SQUAD_RESPONSE_LEN+1] = "";

	// stuff Multi_sw_result
	multi_sw_stuff_result();	

	// update on PXO	
	if(stats_saved){
		if ( multi_fs_tracker_store_sw(&Multi_sw_result, bad_response, SDL_arraysize(bad_response)) ) {
			SEND_AND_DISPLAY(XSTR("<SquadWar results stored on PXO>", 1079));
		} else {
			SEND_AND_DISPLAY(XSTR("<SquadWar results rejected by PXO>", 1080));
			if(strlen(bad_response) > 0){
				SEND_AND_DISPLAY(bad_response);
			}
		}	
	}
	// doh. something was bogus
	else {
		SEND_AND_DISPLAY(XSTR("<SquadWar results invalidated>", 1478));
	}
}

// ------------------------------------------------------------------------------------
// MULTIPLAYER SQUAD WAR FORWARD DEFINITIONS
//

// condition do frame function for the standalone querying PXO
int multi_sw_query_tracker_A()
{
	switch(Multi_sw_std_query){
	// still waiting
	case -1 :
		return 0;

	// failure
	case 0 :
		return 1;

	// successs
	case 1 :
		return 10;
	}

	// shouldn't get here	
	return 1;
}

// stuff Multi_sw_request
void multi_sw_stuff_request(char *match_code)
{
	int idx;	
	squad_war_request *s = &Multi_sw_request;

	// stuff squad id #'s, counts, and squad names
	s->squad_count1 = 0;
	s->squad_count2 = 0;
	for(idx=0; idx<MAX_PLAYERS; idx++){
		if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
			// team 0
			if(Net_players[idx].p_info.team == 0){
				s->squad_plr1[s->squad_count1++] = Net_players[idx].tracker_player_id;				
			} 
			// team 1
			else {
				s->squad_plr2[s->squad_count2++] = Net_players[idx].tracker_player_id;				
			}
		}
	}		

	// stuff match code
	SDL_strlcpy(s->match_code, match_code, SDL_arraysize(s->match_code));
}

// verify that we have the proper # of players
int multi_sw_verify_squad_counts()
{
	int idx;
	int team0_count = 0;
	int team1_count = 0;
	char err_string[255] = "";

	for(idx=0; idx<MAX_PLAYERS; idx++){		
		if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
			if(Net_players[idx].p_info.team == 0){
				team0_count++;
			} else {
				team1_count++;
			}
		}
	}
	if((team0_count < MULTI_SW_MIN_PLAYERS) || (team1_count < MULTI_SW_MIN_PLAYERS)){	
		// print up the error string
		SDL_snprintf(err_string, SDL_arraysize(err_string), XSTR("You need to have at least %d players per squad for Squad War", 1073), MULTI_SW_MIN_PLAYERS);
		popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, err_string);
		return 0;
	}

	// we're cool
	return 1;
}

// stuff Multi_sw_result
void multi_sw_stuff_result()
{
	squad_war_result *s = &Multi_sw_result;
	int idx;

	// stuff match code
	SDL_strlcpy(s->match_code, Multi_sw_match_code, SDL_arraysize(s->match_code));

	// determine what happened
	switch(multi_team_winner()){
	// tie
	case -1:
		s->result = 0;
		s->squad_count1 = 0;
		s->squad_count2 = 0;
		break;

	// team 0 won
	case 0:
		s->result = 1;
		// stuff squad id #'s, counts, and squad names
		s->squad_count1 = 0;
		s->squad_count2 = 0;
		for(idx=0; idx<MAX_PLAYERS; idx++){
			if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
				// team 0
				if(Net_players[idx].p_info.team == 0){
					s->squad_winners[s->squad_count1++] = Net_players[idx].tracker_player_id;				
				} 
				// team 1
				else {
					s->squad_losers[s->squad_count2++] = Net_players[idx].tracker_player_id;				
				}
			}
		}		
		break;

	// team 1 won
	case 1:
		s->result = 1;
		// stuff squad id #'s, counts, and squad names
		s->squad_count1 = 0;
		s->squad_count2 = 0;
		for(idx=0; idx<MAX_PLAYERS; idx++){
			if(MULTI_CONNECTED(Net_players[idx]) && !MULTI_STANDALONE(Net_players[idx]) && !MULTI_PERM_OBSERVER(Net_players[idx])){
				// team 1
				if(Net_players[idx].p_info.team == 1){
					s->squad_winners[s->squad_count1++] = Net_players[idx].tracker_player_id;				
				} 
				// team 0
				else {
					s->squad_losers[s->squad_count2++] = Net_players[idx].tracker_player_id;				
				}
			}
		}		
		break;
	}
}