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
|
/*
* PARSEC - Network Game Functions
*
* $Author: uberlinuxguy $ - $Date: 2004/09/15 12:25:30 $
*
* Orginally written by:
* Copyright (c) Clemens Beer <cbx@parsec.org> 2002
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
// C library
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// compilation flags/debug support
#include "config.h"
#include "debug.h"
// general definitions
#include "general.h"
#include "objstruc.h"
// global externals
#include "globals.h"
// subsystem headers
#include "aud_defs.h"
#include "net_defs.h"
#include "sys_defs.h"
// mathematics header
#include "utl_math.h"
// network code config
#include "net_conf.h"
// subsystem linkage info
#include "linkinfo.h"
// local module header
#include "net_game_gmsv.h"
// proprietary module headers
#include "aud_game.h"
#include "con_aux.h"
#include "g_camera.h"
#include "g_stars.h"
#include "g_supp.h"
#include "h_supp.h"
#include "m_main.h"
#include "net_conn.h"
#include "net_csdf.h"
#include "net_game.h"
#include "net_rmev_gmsv.h"
#include "net_serv.h"
#include "net_stream.h"
#include "net_udpdf.h"
#include "net_wrap.h"
#include "obj_ctrl.h"
#include "obj_xtra.h"
#include "g_sfx.h"
// generic string paste area --------------------------------------------------
//
#define PASTE_STR_LEN 255
static char paste_str[ PASTE_STR_LEN + 1 ];
// game header
//FIXME: move all the inline functions in G_MAIN_CL::G_Main to implementation file
#include "g_main_cl.h"
// set correct function names for dynamic binding------------------------------
//
#ifdef DBIND_PROTOCOL
#undef NETs_RmEvList_GetMaxSize
#undef NETs_UpdateKillStats
#define NETs_RmEvList_GetMaxSize NETs_GAMESERVER_RmEvList_GetMaxSize
#define NETs_UpdateKillStats NETs_GAMESERVER_UpdateKillStats
#endif
// return the max. size of the RE list that can fit in one external packet ----
//
size_t NETs_RmEvList_GetMaxSize()
{
return ( NET_UDP_DATA_LENGTH - sizeof( NetPacketExternal_GMSV ) );
}
// do complete kill stats update from received remote event -------------------
//
void NETs_UpdateKillStats( RE_KillStats* killstats )
{
ASSERT( NetConnected );
ASSERT( killstats != NULL );
//NOTE:
// this function always sets the current kill stat the ones received from the server
// update entire kill stats list
for ( int nPlayer = 0; nPlayer < MAX_NET_ALLOC_SLOTS; nPlayer++ ) {
if ( Player_Status[ nPlayer ] ) {
Player_KillStat[ nPlayer ] = killstats->PlayerKills[ nPlayer ];
}
}
}
// measure ping time to specified server --------------------------------------
//
void NET_PingCurrentServer()
{
// send server ping packet, don't send anonymously, no full info
NET_ServerPing( &Server_Node, FALSE, FALSE );
}
// handle a PKTP_STREAM packet from the server --------------------------------
//
void NET_Handle_STREAM( NetPacket_GMSV* gamepacket )
{
ASSERT( gamepacket != NULL );
ASSERT( gamepacket->Command == PKTP_STREAM );
// STREAM comes from the server ( process only remote events )
ASSERT( ( gamepacket->SendPlayerId == PLAYERID_SERVER ) ||
( ( gamepacket->SendPlayerId == PLAYERID_MASTERSERVER ) && ( gamepacket->MessageId == MSGID_DATAGRAM ) ) );
// process remote event list ( server specific )
NET_ProcessRmEvList_GMSV( gamepacket );
return;
}
// disconnect the client as there is no connection to the server anymore ------
//
void NET_DisconnectNoConnection()
{
MSGOUT( "lost connection to server" );
extern int disable_disc_command_send_to_server;
disable_disc_command_send_to_server = TRUE;
// disconnect and notify menu
if ( NET_CommandDisconnect() ) {
MenuNotifyDisconnect();
}
disable_disc_command_send_to_server = FALSE;
}
// resync the local player with information from the server -------------------
//
void NET_ResyncLocalPlayer( RE_PlayerAndShipStatus* pas_status )
{
ASSERT( pas_status != NULL );
ASSERT( pas_status->senderid == LocalPlayerId );
ASSERT( NET_ConnectedGMSV() );
//FIXME: we need to change RE_PlayerAndShipStatus to a flexible structure
// and specify exactly whats inside via the flags, in order to not
// waste space
// got new position from server ?
if ( pas_status->UpdateFlags & UF_RESYNCPOS ) {
DBGTXT( MSGOUT( "Resync local player with server" ); );
#ifdef PARSEC_DEBUG
MSGPUT( "RESYNC " );
DumpMatrix( pas_status->ObjPosition );
#endif // PARSEC_DEBUG
// override position/orientation
memcpy( MyShip->ObjPosition, pas_status->ObjPosition, sizeof( Xmatrx ) );
// transform world->view to view->world
CalcOrthoInverse( MyShip->ObjPosition, ShipViewCamera );
// reset view camera smoothing filter
CAMERA_ResetFilter();
// init pseudo- and fixed stars
NumPseudoStars = 0;
InitPseudoStars();
// signal that we got a full playerstate from the server
HaveFullPlayerState = TRUE;
}
// got new properties from server ?
if ( HaveFullPlayerState && ( pas_status->UpdateFlags & UF_PROPERTIES ) ) {
#ifdef PARSEC_DEBUG
if ( MyShip->CurEnergy != pas_status->CurEnergy )
MSGOUT("new CurEnergy from server: %d ( was %d )", pas_status->CurEnergy, MyShip->CurEnergy );
#endif // PARSEC_DEBUG
MyShip->CurEnergy = pas_status->CurEnergy;
MyShip->CurDamage = pas_status->CurDamage;
MyShip->CurShield = pas_status->CurShield;
MyShip->NumMissls = pas_status->NumMissls;
MyShip->NumHomMissls = pas_status->NumHomMissls;
MyShip->NumMines = pas_status->NumMines;
}
// got new speeds from server ?
if ( HaveFullPlayerState && ( pas_status->UpdateFlags & UF_SPEEDS ) ) {
MyShip->CurSpeed = pas_status->CurSpeed;
RecYaw = CurYaw = pas_status->CurYaw;
RecPitch = CurPitch = pas_status->CurPitch;
RecRoll = CurRoll = pas_status->CurRoll;
RecSlideHorz = CurSlideHorz = pas_status->CurSlideHorz;
RecSlideVert = CurSlideVert = pas_status->CurSlideVert;
}
// got new status from server ?
if ( pas_status->UpdateFlags & UF_STATUS ) {
ASSERT( ( pas_status->player_status == PLAYER_CONNECTED ) || ( pas_status->player_status == PLAYER_JOINED ) );
if ( Player_Status[ LocalPlayerId ] != pas_status->player_status ) {
// if the last state change ( NETs_Join/NETs_Unjoin ) is ACK by the server,
// we override the local state with the one from the server, otherwise we ignore it
extern int g_dwLastStatusChangeMsg;
if ( ServerStream.IsACK( g_dwLastStatusChangeMsg ) ) {
if ( pas_status->player_status == PLAYER_CONNECTED ) {
Player_Status[ LocalPlayerId ] = PLAYER_CONNECTED;
Player_Ship [ LocalPlayerId ] = NULL;
Player_ShipId[ LocalPlayerId ] = SHIPID_NOSHIP;
// reset global flag
NetJoined = FALSE;
HaveFullPlayerState = FALSE;
// downing of ship starts explosion
ASSERT( pas_status->params[ 0 ] == SHIP_DOWNED );
// exec gamecode when local player ship is downed
TheGameExtraction.GC_LocalPlayerKill( pas_status->params[ 2 ] - KILLERID_BIAS, pas_status->params[ 3 ] ) ;
} else {
// no support of changing the status from CONNECTED to JOINED from the server
ASSERT( FALSE );
}
}
}
}
}
|