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