]> icculus.org git repositories - taylor/freespace2.git/blob - src/network/multilag.cpp
Most of network/ works
[taylor/freespace2.git] / src / network / multilag.cpp
1 /*
2  * $Logfile: /Freespace2/code/Network/multilag.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * $Log$
8  * Revision 1.3  2002/05/26 20:22:48  theoddone33
9  * Most of network/ works
10  *
11  * Revision 1.2  2002/05/07 03:16:47  theoddone33
12  * The Great Newline Fix
13  *
14  * Revision 1.1.1.1  2002/05/03 03:28:10  root
15  * Initial import.
16  *
17  * 
18  * 4     11/19/98 8:03a Dave
19  * Full support for D3-style reliable sockets. Revamped packet lag/loss
20  * system, made it receiver side and at the lowest possible level.
21  * 
22  * 3     11/17/98 11:12a Dave
23  * Removed player identification by address. Now assign explicit id #'s.
24  * 
25  * 2     10/07/98 10:53a Dave
26  * Initial checkin.
27  * 
28  * 1     10/07/98 10:50a Dave
29  * 
30  * 15    6/05/98 9:54a Lawrance
31  * OEM changes
32  * 
33  * 14    4/27/98 6:02p Dave
34  * Modify how missile scoring works. Fixed a team select ui bug. Speed up
35  * multi_lag system. Put in new main hall.
36  * 
37  * 13    4/18/98 5:00p Dave
38  * Put in observer zoom key. Made mission sync screen more informative.
39  * 
40  * 12    4/06/98 12:37a Lawrance
41  * fix compile bug with demo
42  * 
43  * 11    4/04/98 8:42p Dave
44  * Tested and debugged UDP reliable socket layer. Modified lag system to
45  * take this into account. 
46  * 
47  * 10    4/02/98 6:29p Lawrance
48  * compile out multilag code for demo
49  * 
50  * 9     3/14/98 2:48p Dave
51  * Cleaned up observer joining code. Put in support for file xfers to
52  * ingame joiners (observers or not). Revamped and reinstalled pseudo
53  * lag/loss system.
54  * 
55  * 8     1/11/98 10:03p Allender
56  * removed <winsock.h> from headers which included it.  Made psnet_socket
57  * type which is defined just as SOCKET type is.
58  * 
59  * 7     12/29/97 5:21p Dave
60  * Put in object update sequencing for multiplayer.
61  * 
62  * 6     12/16/97 6:17p Dave
63  * Put in primary weapon support for multiplayer weapon select screen.
64  * 
65  * 5     12/10/97 4:45p Dave
66  * Added in more detailed support for multiplayer packet lag/loss. Fixed
67  * some multiplayer stuff. Added some controls to the standalone.
68  * 
69  * 4     12/01/97 4:59p Dave
70  * Synchronized multiplayer debris objects. Put in pilot popup in main
71  * hall. Optimized simulated multiplayer lag module. Fixed a potential
72  * file_xfer bug.
73  * 
74  * 3     11/28/97 7:04p Dave
75  * Emergency checkin due to big system crash.
76  * 
77  * 2     11/28/97 5:06p Dave
78  * Put in facilities for simulating multiplayer lag.
79  * 
80  * 1     11/28/97 4:38p Dave
81  * Initial Revision
82  * 
83  * $NoKeywords: $
84  */
85
86 #ifndef PLAT_UNIX
87 #include <winsock.h>
88 #include <wsipx.h>
89 #else
90 #include <sys/time.h>
91 #include <sys/types.h>
92 #include <sys/socket.h>
93 #include <netinet/in.h>
94 #include <arpa/inet.h>
95 #include <netdb.h>
96 #include <unistd.h>
97 #endif
98 #include "pstypes.h"
99 #include "multi.h"
100 #include "multilag.h"
101 #include "cmdline.h"
102 #include "timer.h"
103 #include "linklist.h"
104
105 // ----------------------------------------------------------------------------------------------------
106 // LAGLOSS DEFINES/VARS
107 //
108
109 // default LAGLOSS values
110 #define MULTI_LAGLOSS_DEF_LAG                           (-1)
111 #define MULTI_LAGLOSS_DEF_LAGMIN                        (-1)
112 #define MULTI_LAGLOSS_DEF_LAGMAX                        (-1)
113 #define MULTI_LAGLOSS_DEF_LOSS                  (-1.0f)
114 #define MULTI_LAGLOSS_DEF_LOSSMIN               (-1.0f)
115 #define MULTI_LAGLOSS_DEF_LOSSMAX               (-1.0f)
116 #define MULTI_LAGLOSS_DEF_STREAK                        (2500)
117
118 // if we're running
119 int Multi_lag_inited = 0;
120
121 // lag values (base - max and min)
122 int Multi_lag_base = -1;
123 int Multi_lag_min = -1;
124 int Multi_lag_max = -1;
125
126 // packet loss values (base - max and min)
127 float Multi_loss_base = -1.0f;
128 float Multi_loss_min = -1.0f;
129 float Multi_loss_max = -1.0f;
130
131 // streaks for lagging
132 int Multi_streak_stamp = -1;                            // timestamp telling when the streak of a certain lag is done
133 int Multi_streak_time = 0;                                      // how long each streak will last
134 int Multi_current_streak = -1;                  // what lag the current streak has
135
136 // struct for buffering stuff on receives
137 typedef struct lag_buf {
138         ubyte data[700];                                                        // the data from the packet
139         int data_len;                                                           // length of the data
140         uint socket;                                                            // this can be either a PSNET_SOCKET or a PSNET_SOCKET_RELIABLE
141         int stamp;                                                                      // when this expires, make this packet available        
142         SOCKADDR_IN ip_addr;                                            // ip address when in TCP
143 #ifndef PLAT_UNIX
144         SOCKADDR_IPX ipx_addr;                                  // ipx address when in IPX mode
145 #endif
146
147         struct  lag_buf * prev;                         // prev in the list
148         struct  lag_buf * next;                         // next in the list
149 } lag_buf;
150
151 // lag buffers - malloced
152 #ifdef NDEBUG
153         #define MAX_LAG_BUFFERS                 1               // only 1 buffer in non-debug builds
154 #else
155         #define MAX_LAG_BUFFERS                 1000
156 #endif
157 lag_buf *Lag_buffers[MAX_LAG_BUFFERS];
158 int Lag_buf_count = 0;                                          // how many lag_buf's are currently in use
159
160 lag_buf Lag_free_list;
161 lag_buf Lag_used_list;
162
163
164 // ----------------------------------------------------------------------------------------------------
165 // LAGLOSS FORWARD DECLARATIONS
166 //
167
168 // get a value to lag a packet with (in ms)
169 int multi_lag_get_random_lag();
170
171 // boolean yes or no - should this packet be lost?
172 int multi_lag_should_be_lost();             
173
174 // get a free packet buffer, return NULL on fail
175 lag_buf *multi_lag_get_free();
176
177 // put a lag buffer back
178 void multi_lag_put_free(lag_buf *buf);
179
180 // ----------------------------------------------------------------------------------------------------
181 // LAGLOSS FUNCTIONS
182 //
183
184 void multi_lag_init()
185 {       
186         // never do lag in a non-debug build
187 #if defined(NDEBUG) || !defined(MULTI_USE_LAG)
188         Multi_lag_inited = 0;
189 #else
190         int idx;
191
192         // if we're already inited, don't do anything
193         if(Multi_lag_inited){
194                 return;
195         }
196
197         // try and allocate lag bufs
198         for(idx=0; idx<MAX_LAG_BUFFERS; idx++){
199                 Lag_buffers[idx] = (lag_buf*)malloc(sizeof(lag_buf));
200                 if(Lag_buffers[idx] == NULL){
201                         return;
202                 }
203         }
204
205         // initialize lag buffer lists
206         list_init( &Lag_free_list );
207         list_init( &Lag_used_list );
208
209         // Link all object slots into the free list
210         for (idx=0; idx<MAX_LAG_BUFFERS; idx++) {
211                 list_append(&Lag_free_list, Lag_buffers[idx]);
212         }
213         
214         // set the default lag values
215         Multi_lag_base = MULTI_LAGLOSS_DEF_LAG;
216         Multi_lag_min = MULTI_LAGLOSS_DEF_LAGMIN;
217         Multi_lag_max = MULTI_LAGLOSS_DEF_LAGMAX;
218
219         // set the default loss values
220         Multi_loss_base = MULTI_LAGLOSS_DEF_LOSS;
221         Multi_loss_min  = MULTI_LAGLOSS_DEF_LOSSMIN;
222         Multi_loss_max = MULTI_LAGLOSS_DEF_LOSSMAX;
223
224         // set the default lag streak time      
225         Multi_streak_time = MULTI_LAGLOSS_DEF_STREAK;
226         
227         Multi_lag_inited = 1;
228 #endif
229 }
230
231 void multi_lag_close()
232 {       
233         int idx;
234
235         // if we're not inited already, don't do anything
236         if(!Multi_lag_inited){
237                 return;
238         }       
239
240         // free up lag buffers
241         for(idx=0; idx<MAX_LAG_BUFFERS; idx++){
242                 if(Lag_buffers[idx] != NULL){
243                         free(Lag_buffers[idx]);
244                         Lag_buffers[idx] = NULL;
245                 }
246         }
247
248         Multi_lag_inited = 0;
249 }
250
251 // select for multi_lag
252 int multi_lag_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *except_fds, timeval *timeout)
253 {               
254         char t_buf[1024];
255         int t_from_len;
256         SOCKADDR_IN ip_addr;
257 #ifndef PLAT_UNIX
258         SOCKADDR_IPX ipx_addr;
259 #endif
260         int ret_val;
261         lag_buf *moveup, *item;
262
263         Assert(readfds != NULL);
264         Assert(writefds == NULL);
265         Assert(except_fds == NULL);
266
267         // clear out addresses
268         memset(&ip_addr, 0, sizeof(SOCKADDR_IN));
269 #ifndef PLAT_UNIX
270         memset(&ipx_addr, 0, sizeof(SOCKADDR_IPX));
271 #endif
272
273         // if there's data on the socket, read it
274         if(select(nfds, readfds, writefds, except_fds, timeout)){               
275                 // read the data and stuff it
276                 if(Tcp_active){                                         
277                         t_from_len = sizeof(SOCKADDR_IN);
278                         ret_val = recvfrom(readfds->fd_array[0], t_buf, 1024, 0, (SOCKADDR*)&ip_addr, &t_from_len);
279 #ifndef PLAT_UNIX
280                 } else {
281                         t_from_len = sizeof(SOCKADDR_IPX);
282                         ret_val = recvfrom(readfds->fd_array[0], t_buf, 1024, 0, (SOCKADDR*)&ipx_addr, &t_from_len);
283 #endif
284                 }
285                         
286                 // wacky socket error
287                 if(ret_val == SOCKET_ERROR){
288                         return SOCKET_ERROR;
289                 }
290
291                 // if we should be dropping this packet
292                 if(!multi_lag_should_be_lost()){
293                         // get a free packet buf and stuff the data
294                         item = multi_lag_get_free();
295                         if(item){
296                                 Assert(ret_val < 700);
297                                 memcpy(item->data, t_buf, ret_val);                     
298                                 item->data_len = ret_val;
299                                 item->ip_addr = ip_addr;
300 #ifndef PLAT_UNIX
301                                 item->ipx_addr = ipx_addr;
302 #endif
303                                 item->socket = readfds->fd_array[0];
304                                 item->stamp = timestamp(multi_lag_get_random_lag());
305                         }               
306                 }
307         }
308
309         // always unset the readfds
310         readfds->fd_count = 0;
311
312         // now determine if we have any pending packets - find the first one
313         // NOTE : this _could_ be the packet we just read. In fact, with a 0 lag, this will always be the case
314         moveup=GET_FIRST(&Lag_used_list);
315         while ( moveup!=END_OF_LIST(&Lag_used_list) )   {               
316                 // if the timestamp has elapsed and we have a matching socket
317                 if((readfds->fd_array[0] == (SOCKET)moveup->socket) && ((moveup->stamp <= 0) || timestamp_elapsed(moveup->stamp))){
318                         // set this so we think select returned yes
319                         readfds->fd_count = 1;
320                         return 1;
321                 }
322
323                 moveup = GET_NEXT(moveup);
324         }
325
326         // no data
327         return 0;
328 }
329
330 // recvfrom for multilag
331 int multi_lag_recvfrom(uint s, char *buf, int len, int flags, struct sockaddr *from, int *fromlen)
332 {
333         lag_buf *moveup = NULL;
334         lag_buf *item = NULL;
335
336         // now determine if we have any pending packets - find the first one
337         moveup=GET_FIRST(&Lag_used_list);
338         while ( moveup!=END_OF_LIST(&Lag_used_list) )   {               
339                 // if the timestamp has elapsed
340                 if((s == (SOCKET)moveup->socket) && ((moveup->stamp <= 0) || timestamp_elapsed(moveup->stamp))){
341                         item = moveup;
342                         break;
343                 }
344
345                 moveup = GET_NEXT(moveup);
346         }
347
348         // if this happens, it means that the multi_lag_select() returned an improper value
349         Assert(item);
350         // stuff the data
351         Assert(item->data_len <= len);
352         memcpy(buf, item->data, item->data_len);
353         if(Tcp_active){
354                 memcpy(from, &item->ip_addr, sizeof(SOCKADDR_IN));
355 #ifndef PLAT_UNIX
356         } else {
357                 memcpy(from, &item->ipx_addr, sizeof(SOCKADDR_IPX));
358 #endif
359         }
360
361         // stick the item back on the free list
362         multi_lag_put_free(item);
363
364         // return the size in bytes
365         return item->data_len;
366 }
367
368 // ----------------------------------------------------------------------------------------------------
369 // LAGLOSS FORWARD DEFINITIONS
370 //
371
372 int multi_lag_get_random_lag()
373 {
374         // first determine the percentage we'll be checking against
375         int ret;
376         int mod;        
377
378         // if the lag system isn't inited, don't do anything (no lag)
379         if(!Multi_lag_inited){
380                 return 0;
381         }
382                 
383         // pick a value
384         // see if we should be going up or down (loss max/loss min)
385         mod = 0;
386         if((float)rand()/(float)RAND_MAX < 0.5){
387                 // down
388                 if(Multi_lag_min >= 0){
389                         mod = - (int)((float)(Multi_lag_base - Multi_lag_min) * ((float)rand()/(float)RAND_MAX));
390                 }
391         } else {
392                 // up
393                 if(Multi_lag_max >= 0){
394                         mod = (int)((float)(Multi_lag_max - Multi_lag_base) * ((float)rand()/(float)RAND_MAX));
395                 }
396         }
397         
398         // if the current streak has elapsed, calculate a new one
399         if((Multi_streak_stamp == -1) || (timestamp_elapsed(Multi_streak_stamp))){
400                 // timestamp the new streak
401                 Multi_streak_stamp = timestamp(Multi_streak_time);
402
403                 // set the return value
404                 ret = Multi_lag_base + mod;
405                 
406                 // set the lag value of this current streak
407                 Multi_current_streak = ret;
408         } 
409         // otherwise use the lag for the current streak
410         else {
411                 ret = Multi_current_streak;
412         }
413                         
414         return ret;     
415 }
416
417 // this _may_ be a bit heavyweight, but it _is_ debug code
418 int multi_lag_should_be_lost()
419 {       
420         // first determine the percentage we'll be checking against
421         float mod;      
422
423         // if the lag system isn't inited, don't do anything
424         if(!Multi_lag_inited){
425                 return 0;
426         }
427                 
428         // see if we should be going up or down (loss max/loss min)
429         mod = 0.0f;
430         if((float)rand()/(float)RAND_MAX < 0.5){
431                 // down
432                 if(Multi_loss_min >= 0.0f){
433                         mod = - ((Multi_loss_base - Multi_loss_min) * ((float)rand()/(float)RAND_MAX));
434                 }
435         } else {
436                 // up
437                 if(Multi_loss_max >= 0.0f){
438                         mod = ((Multi_loss_max - Multi_loss_base) * ((float)rand()/(float)RAND_MAX));
439                 }
440         }       
441         
442         if((float)rand()/(float)RAND_MAX <= Multi_loss_base + mod){
443                 return 1;
444         }       
445
446         return 0;
447 }
448
449 // get a free packet buffer, return NULL on fail
450 lag_buf *multi_lag_get_free()
451 {
452         lag_buf *lagp;
453
454         // if we're out of buffers
455         if(Lag_buf_count >= MAX_LAG_BUFFERS){
456                 nprintf(("Network", "Out of lag buffers!\n"));
457                 return NULL;
458         }
459
460         // get a free item
461         lagp = GET_FIRST(&Lag_free_list);
462         Assert( lagp != &Lag_free_list );               // shouldn't have the dummy element
463
464         // remove trailp from the free list
465         list_remove( &Lag_free_list, lagp );
466         
467         // insert trailp onto the end of used list
468         list_append( &Lag_used_list, lagp );
469
470         // increase the count
471         Lag_buf_count++;
472         return lagp;
473 }
474
475 // put a lag buffer back
476 void multi_lag_put_free(lag_buf *buf)
477 {
478         // remove objp from the used list
479         list_remove( &Lag_used_list, buf);
480
481         // add objp to the end of the free
482         list_append( &Lag_free_list, buf );
483
484         // decrement counter
485         Lag_buf_count--;
486 }
487
488 void multi_lagloss_dcf()
489 {
490         // if the lag system isn't inited, don't do anything
491         if(!Multi_lag_inited){
492                 dc_printf("Lag System Not Initialized!\n");
493                 return;
494         }
495
496         // display all available commands
497         dc_printf("Usage :\nlag <ms>  (-1 to disable)\nlag_min <ms>\nlag_max <ms>\nloss <0-100>  (-1 to disable)\nloss_min <0-100>\nloss_max <0-100>\nlag_streak <ms>\nlagloss\n");
498
499         // display lag settings
500         dc_printf("Lag : ");            
501         dc_printf("\n   Base %d\n   Min %d\n   Max %d\n   Streak %d\n", Multi_lag_base, Multi_lag_min, Multi_lag_max, Multi_streak_time);       
502
503         // display loss settings
504         dc_printf("Loss : ");           
505         dc_printf("\n   Base %f\n   Min %f\n   Max %f\n", Multi_loss_base, Multi_loss_min, Multi_loss_max);     
506 }
507
508 DCF(lag, "")
509 {
510         // if the lag system isn't inited, don't do anything
511         if(!Multi_lag_inited){
512                 dc_printf("Lag System Not Initialized!\n");
513                 return;
514         }
515
516         dc_get_arg(ARG_INT);            
517         // parse the argument and change things around accordingly
518         if(Dc_arg_type & ARG_INT){                      
519                 if(Dc_arg_int < 0){
520                         // switch the lag sim off
521                         Multi_lag_base = -1;
522                         Multi_lag_min = -1;
523                         Multi_lag_max = -1;
524                         dc_printf("Turning simulated lag off\n");
525                         multi_lagloss_dcf();
526                 } else if((Multi_lag_max >= 0) && (Dc_arg_int > Multi_lag_max)){
527                         dc_printf("Base value greater than max value, ignoring...");
528                 } else if((Multi_lag_min >= 0) && (Dc_arg_int < Multi_lag_min)){
529                         dc_printf("Base value smaller than min value, ignoring...");
530                 } else {
531                         Multi_lag_base = Dc_arg_int;
532                         multi_lagloss_dcf();
533                 }
534         }       
535 }
536
537 DCF(lag_min, "")
538 {
539         // if the lag system isn't inited, don't do anything
540         if(!Multi_lag_inited){
541                 dc_printf("Lag System Not Initialized!\n");
542                 return;
543         }
544
545         dc_get_arg(ARG_INT);            
546         // parse the argument and change things around accordingly
547         if(Dc_arg_type & ARG_INT){                      
548                 if(Dc_arg_int > Multi_lag_base){
549                         dc_printf("Min value greater than base value, ignoring...");
550                 } else {
551                         if(Dc_arg_int < 0){
552                                 Multi_lag_min = -1;
553                         } else {
554                                 Multi_lag_min = Dc_arg_int;
555                         }
556                         multi_lagloss_dcf();
557                 }
558         }                       
559 }
560
561 DCF(lag_max, "")
562 {
563         // if the lag system isn't inited, don't do anything
564         if(!Multi_lag_inited){
565                 dc_printf("Lag System Not Initialized!\n");
566                 return;
567         }
568
569         // parse the argument and change things around accordingly
570         dc_get_arg(ARG_INT);
571         if(Dc_arg_type & ARG_INT){                      
572                 if((Dc_arg >=0) && (Dc_arg_int < Multi_lag_base)){
573                         dc_printf("Max value smaller than base value, ignoring...");
574                 } else {
575                         if(Dc_arg_int < 0){
576                                 Multi_lag_max = -1;
577                         } else {
578                                 Multi_lag_max = Dc_arg_int;
579                         }
580                         multi_lagloss_dcf();
581                 }
582         }               
583 }
584
585 DCF(loss, "")
586 {
587         // if the lag system isn't inited, don't do anything
588         if(!Multi_lag_inited){
589                 dc_printf("Lag System Not Initialized!\n");
590                 return;
591         }
592
593         // parse the argument and change things around accordingly
594         dc_get_arg(ARG_INT);
595         if(Dc_arg_type & ARG_INT){
596                 float val = (float)Dc_arg_int / 100.0f;
597                         
598                 if(Dc_arg_int > 100){
599                         dc_printf("Illegal loss base value, ignoring...");
600                 } else if(Dc_arg_int < 0){
601                         // switch the loss sim off
602                         dc_printf("Turning simulated loss off\n");
603                         Multi_loss_base = -1.0f;
604                         Multi_loss_min = -1.0f;
605                         Multi_loss_max = -1.0f;
606                         multi_lagloss_dcf();
607                 } else if((Multi_loss_max >= 0.0f) && (val > Multi_loss_max)){
608                         dc_printf("Base value greater than max value, ignoring...");
609                 } else if((Multi_loss_min >= 0.0f) && (val < Multi_loss_min)){
610                         dc_printf("Base value smaller than min value, ignoring...");
611                 } else {
612                         Multi_loss_base = val;
613                         multi_lagloss_dcf();
614                 }
615         }                       
616 }
617
618 DCF(loss_min, "")
619 {
620         // if the lag system isn't inited, don't do anything
621         if(!Multi_lag_inited){
622                 dc_printf("Lag System Not Initialized!\n");
623                 return;
624         }
625
626         // parse the argument and change things around accordingly
627         dc_get_arg(ARG_INT);
628         if(Dc_arg_type & ARG_INT){                      
629       float val = (float)Dc_arg_int / 100.0f;
630
631                 if(val > Multi_loss_base){
632                         dc_printf("Min value greater than base value, ignoring...");
633                 } else {
634                         // otherwise set the value
635                         if(Dc_arg_int < 0){
636                                 Multi_loss_min = -1.0f;
637                         } else {
638                                 Multi_loss_min = val;
639                         }
640                         multi_lagloss_dcf();
641                 }
642         }
643 }
644
645 DCF(loss_max, "")
646 {       
647         // if the lag system isn't inited, don't do anything
648         if(!Multi_lag_inited){
649                 dc_printf("Lag System Not Initialized!\n");
650                 return;
651         }
652
653         // parse the argument and change things around accordingly
654         dc_get_arg(ARG_INT);
655         if(Dc_arg_type & ARG_INT){                      
656       float val = (float)Dc_arg_int / 100.0f;
657
658                 if(val < Multi_loss_base){
659                         dc_printf("Max value smaller than base value, ignoring...");
660                 } else {
661                         // otherwise set the value
662                         if(Dc_arg_int < 0){
663                                 Multi_loss_max = -1.0f;
664                         } else {
665                                 Multi_loss_min = val;
666                         }
667                         multi_lagloss_dcf();
668                 }
669         }                       
670 }
671
672 DCF(lagloss, "")
673 {
674         // if the lag system isn't inited, don't do anything
675         if(!Multi_lag_inited){
676                 dc_printf("Lag System Not Initialized!\n");
677                 return;
678         }
679
680         multi_lagloss_dcf();
681 }
682
683 DCF(lag_streak, "")
684 {
685         // if the lag system isn't inited, don't do anything
686         if(!Multi_lag_inited){
687                 dc_printf("Lag System Not Initialized!\n");
688                 return;
689         }
690
691         dc_get_arg(ARG_INT);
692         if(Dc_arg_type & ARG_INT){                                      
693                 if(Dc_arg_int >= 0){
694                         Multi_streak_time = Dc_arg_int;
695                 } 
696         }
697 }
698
699 DCF(lag_bad, "")
700 {
701         // if the lag system isn't inited, don't do anything
702         if(!Multi_lag_inited){
703                 dc_printf("Lag System Not Initialized!\n");
704                 return;
705         }
706
707         dc_printf("Setting bad lag/loss parameters\n");
708
709         // set good lagloss parameters
710         Multi_lag_base = 500;
711         Multi_lag_min = 400;
712         Multi_lag_max = 600;
713         
714         Multi_loss_base = 0.2f;
715         Multi_loss_min = 0.15f;
716         Multi_loss_max = 0.23f;
717
718         Multi_streak_time = 800;
719         Multi_streak_stamp = -1;
720         Multi_current_streak = -1;
721 }
722
723 DCF(lag_avg, "")
724 {
725         // if the lag system isn't inited, don't do anything
726         if(!Multi_lag_inited){
727                 dc_printf("Lag System Not Initialized!\n");
728                 return;
729         }
730
731         dc_printf("Setting avg lag/loss parameters\n");
732
733         // set good lagloss parameters
734         Multi_lag_base = 275;
735         Multi_lag_min = 200;
736         Multi_lag_max = 400;
737         
738         Multi_loss_base = 0.15f;
739         Multi_loss_min = 0.1f;
740         Multi_loss_max = 0.20f;
741
742         Multi_streak_time = 900;
743         Multi_streak_stamp = -1;
744         Multi_current_streak = -1;
745 }
746
747 DCF(lag_good, "")
748 {
749         // if the lag system isn't inited, don't do anything
750         if(!Multi_lag_inited){
751                 dc_printf("Lag System Not Initialized!\n");
752                 return;
753         }
754
755         dc_printf("Setting good lag/loss parameters\n");
756
757         // set good lagloss parameters
758         Multi_lag_base = 100;
759         Multi_lag_min = 35;
760         Multi_lag_max = 200;
761         
762         Multi_loss_base = 0.08f;
763         Multi_loss_min = 0.0f;
764         Multi_loss_max = 0.1f;
765
766         Multi_streak_time = 1000;
767         Multi_streak_stamp = -1;
768         Multi_current_streak = -1;
769 }
770