dxx-rebirth/main/mlticntl.c
2006-03-20 16:43:15 +00:00

437 lines
14 KiB
C
Executable file

/* mlticntl.c - multi control , by GriM FisH */
#ifdef NETWORK
#include <string.h>
#include <stdio.h>
#include "network.h"
#include "multi.h"
#include "text.h"
#include "endlevel.h"
#include "fuelcen.h"
#include "mono.h"
#include "error.h"
#include "ipx.h"
#include "timer.h"
#include "newdemo.h"
#include "hudmsg.h"
#include "collide.h"
#include "ban.h"
#include "reconfig.h"
//added 6/15/99 - Owen Evans
#include "strutil.h"
//end added
#define RESTRICT_WAIT (F1_0/4)*30
#define RESTRICT_TIMEOUT (F1_0/4)*70
//============ Vars ================
int last_cinvul; //Last reactor invuln time.
int last_max_players; //Last number of max players.
int restrict_mode = 0; //Are we using restrict mode?
fix restrict_start_time = 0; //When did we get the restrict alert?
int waiting_to_join = 0; //Are we restricting a player now?
char restricted_callsign[CALLSIGN_LEN+1] = ""; //What is the currently restricted player's name?
int accept_join = 0; //Are we accepting the currently restricted player's join?
int dump_join = 0; //Are we gonna dump this dude who is trying to join our game?
//========== Main Code ==============
int opt_checks,opt_sliders,opt_menus;
void lamer_network_menu_update (int nitems, newmenu_item * menus, int * last_key, int citem) //This function updates the sliders in the previous function.
{
if ( last_max_players != menus[opt_sliders].value ) {
last_max_players = menus[4].value;
sprintf( menus[opt_sliders].text, "%s: %d", "Max Players", menus[opt_sliders].value+2 );
menus[opt_sliders].redraw = 1;
}
#ifndef SHAREWARE
if ( last_cinvul != menus[opt_sliders+1].value ) {
sprintf( menus[opt_sliders+1].text, "%s: %d %s", TXT_REACTOR_LIFE, menus[opt_sliders+1].value*5, TXT_MINUTES_ABBREV );
last_cinvul = menus[opt_sliders+1].value;
menus[opt_sliders+1].redraw = 1;
}
#endif
}
void lamer_do_netgame_menu (void) //This function brings up a menu that lets you modify some of a running netgame's properties real-time. Only takes effect if you are master.
{
newmenu_item m[10];
int item,opt;
char max_player_text[32];
char name[NETGAME_NAME_LEN+1];
#ifndef SHAREWARE
char srinvul[32];
#endif
if(!(Game_mode & GM_MULTI))
return;
if(!network_i_am_master())
return;
//Netgame.max_numplayers = MaxNumNetPlayers;
opt=0;
sprintf( name, "%s", Netgame.game_name);
m[opt].type = NM_TYPE_TEXT; m[opt].text = TXT_DESCRIPTION; opt++;
m[opt].type = NM_TYPE_INPUT; m[opt].text = name; m[opt].text_len = NETGAME_NAME_LEN; opt++;
opt_checks=opt;
m[opt].type = NM_TYPE_CHECK; m[opt].value = Netgame.game_flags & NETGAME_FLAG_CLOSED; m[opt].text = TXT_CLOSED_GAME; opt++;
m[opt].type = NM_TYPE_CHECK; m[opt].value = restrict_mode; m[opt].text = "Restricted"; opt++;
// m[opt].type = NM_TYPE_CHECK; m[opt].value = Netgame.game_flags & NETGAME_FLAG_SHOW_MAP; m[opt].text = TXT_SHOW_ON_MAP; opt++;
opt_sliders = opt;
sprintf( max_player_text, "%s: %d", "Max Players", last_max_players+2 );
last_max_players = Netgame.max_numplayers;
m[opt].type = NM_TYPE_SLIDER; m[opt].value = Netgame.max_numplayers-2; m[opt].text = max_player_text; m[opt].min_value = 0; m[opt].max_value = MAX_NUM_NET_PLAYERS-2; opt++;
#ifndef SHAREWARE
control_invul_time = f2i(Netgame.control_invul_time/5/60);
sprintf( srinvul, "%s: %d %s", TXT_REACTOR_LIFE, 5*control_invul_time, TXT_MINUTES_ABBREV );
last_cinvul = control_invul_time;
m[opt].type = NM_TYPE_SLIDER; m[opt].value = control_invul_time; m[opt].text = srinvul; m[opt].min_value = 0; m[opt].max_value = 15; opt++;
#endif
//added on 11/17/98 by Victor Rachels to blow up mine
opt_menus = opt;
m[opt].type = NM_TYPE_MENU; m[opt].text = "Blow up Mine."; opt++;
m[opt].type = NM_TYPE_MENU; m[opt].text = "Save Bans now."; opt++;
//end this section addition - VR
item = newmenu_do1( NULL, TXT_NETGAME_SETUP, opt, m, lamer_network_menu_update, 1 );
if ( item > -1 )
{
strcpy( Netgame.game_name, name );
if (m[opt_checks].value)
Netgame.game_flags |= NETGAME_FLAG_CLOSED;
else
Netgame.game_flags &= ~NETGAME_FLAG_CLOSED;
if (m[opt_checks+1].value)
restrict_mode = 1;
else
restrict_mode = 0;
/* if (m[opt_checks+2].value)
Netgame.game_flags |= NETGAME_FLAG_SHOW_MAP;
else
Netgame.game_flags &= ~NETGAME_FLAG_SHOW_MAP;
*/
MaxNumNetPlayers = m[opt_sliders].value+2;
Netgame.max_numplayers = MaxNumNetPlayers;
#ifndef SHAREWARE
control_invul_time = m[opt_sliders+1].value;
Netgame.control_invul_time = control_invul_time*5*F1_0*60;
#endif
//added on 11/17/98 by Victor Rachels to blow up mine
if(item==opt_menus && !Fuelcen_control_center_destroyed)
{
net_destroy_controlcen(NULL);
multi_send_destroy_controlcen(-1,Player_num);
}
//end this section addition - VR
//added on 2/2/99 by Victor Rachels to save bans
if(item==opt_menus+1)
nm_messagebox(NULL,1,TXT_OK,"%i Bans saved",writebans());
//end this section addition - BR
//added on 6/7/99 by Victor Rachels for ingame reconfig
reconfig_send_gameinfo();
}
}
void lamer_do_restrict_alert (sequence_packet * their) //This function lets you know that someone wants to join a restricted netgame. Displays joining player's callsign and IP.
{
ubyte ipaddress[6];
if(!restrict_mode)
return;
if((dump_join) && (!stricmp(their->player.callsign, restricted_callsign)))
{
network_dump_player(their->player.server, their->player.node, DUMP_DORK);
dump_join = 0;
return;
}
if((restrict_start_time+RESTRICT_WAIT > GameTime) && (waiting_to_join) && (!stricmp(restricted_callsign, their->player.callsign)))
return;
if(accept_join)
return;
//if ( (*(uint *)their->player.server) != 0 )
// ipx_get_local_target( their->player.server, their->player.node, ipaddress );
//else
memcpy(ipaddress, their->player.node, 6);
digi_play_sample(SOUND_CONTROL_CENTER_WARNING_SIREN, F1_0*4);
hud_message(MSGC_GAME_FEEDBACK,"%s, ip %d.%d.%d.%d, wants to join the game!", their->player.callsign, /*(int)ipaddress[5], (int)ipaddress[4],*/ (int)ipaddress[3], (int)ipaddress[2], (int)ipaddress[1], (int)ipaddress[0]);
restrict_start_time = GameTime;
waiting_to_join = 1;
strcpy(restricted_callsign, their->player.callsign);
//accept_join = 0;
dump_join = 0;
return;
}
void lamer_do_restrict_frame (void) //This function times out a request to join a restricted netgame if the time has been longer than RESTRICT_TIMEOUT.
{
if(!restrict_mode)
return;
if(!waiting_to_join)
return;
if(restrict_start_time+RESTRICT_TIMEOUT < GameTime)
{
waiting_to_join = 0;
accept_join = 0;
}
return;
}
void lamer_accept_joining_player (void) //This function allows a player that wants to join a restricted game in.
{
if(!restrict_mode)
return;
if(!waiting_to_join)
return;
accept_join = 1;
hud_message(MSGC_GAME_FEEDBACK,"Joining in player %s!", restricted_callsign);
return;
}
void lamer_dump_joining_player (void) //This function dumps a player join.
{
if(!restrict_mode)
return;
if(!waiting_to_join)
return;
dump_join = 1;
hud_message(MSGC_GAME_FEEDBACK,"Dumping player %s!", restricted_callsign);
return;
}
void lamer_network_welcome_player_restricted (sequence_packet * their) //This function is a modified network.c join player function that has been modified to allow you to selectively join in players.
{
// Add a player to a game already in progress
ubyte local_address[6];
int player_num;
int i;
// Don't accept new players if we're ending this level. Its safe to
// ignore since they'll request again later
if(!restrict_mode)
return;
if ((Endlevel_sequence) || (Fuelcen_control_center_destroyed))
{
mprintf((0, "Ignored request from new player to join during endgame.\n"));
network_dump_player(their->player.server,their->player.node, DUMP_ENDLEVEL);
return;
}
if (Network_send_objects)
{
// Ignore silently, we're already responding to someone and we can't
// do more than one person at a time. If we don't dump them they will
// re-request in a few seconds.
return;
}
if (their->player.connected != Current_level_num)
{
mprintf((0, "Dumping player due to old level number.\n"));
network_dump_player(their->player.server, their->player.node, DUMP_LEVEL);
return;
}
player_num = -1;
memset(&Network_player_rejoining, 0, sizeof(sequence_packet));
Network_player_added = 0;
#ifndef SHAREWARE
if ( (*(uint *)their->player.server) != 0 )
ipx_get_local_target( their->player.server, their->player.node, local_address );
else
#endif
memcpy(local_address, their->player.node, 6);
for (i = 0; i < N_players; i++)
{
if ( (!stricmp(Players[i].callsign, their->player.callsign )) && (!memcmp(Players[i].net_address,local_address, 6)) )
{
player_num = i;
break;
}
}
if (player_num == -1)
{
// Player is new to this game
if ( !(Netgame.game_flags & NETGAME_FLAG_CLOSED) && (N_players < MaxNumNetPlayers))
{
// Add player in an open slot, game not full yet
lamer_do_restrict_alert(their);
if ((waiting_to_join) && (!accept_join))
return;
if (!waiting_to_join)
return;
if(accept_join)
if(stricmp(their->player.callsign, restricted_callsign) != 0)
return;
waiting_to_join = 0;
accept_join = 0;
player_num = N_players;
Network_player_added = 1;
}
else if (Netgame.game_flags & NETGAME_FLAG_CLOSED)
{
// Slots are open but game is closed
network_dump_player(their->player.server, their->player.node, DUMP_CLOSED);
return;
}
else
{
// Slots are full but game is open, see if anyone is
// disconnected and replace the oldest player with this new one
int oldest_player = -1;
fix oldest_time = timer_get_approx_seconds();
int activeplayers = 0;
Assert(N_players == MaxNumNetPlayers);
for (i = 0; i < Netgame.numplayers; i++)
if (Netgame.players[i].connected)
activeplayers++;
if (activeplayers == Netgame.max_numplayers)
{
// Game is full.
network_dump_player(their->player.server, their->player.node, DUMP_FULL);
return;
}
for (i = 0; i < N_players; i++)
{
if ( (!Players[i].connected) && (LastPacketTime[i] < oldest_time))
{
oldest_time = LastPacketTime[i];
oldest_player = i;
}
}
if (oldest_player == -1)
{
// Everyone is still connected
network_dump_player(their->player.server, their->player.node, DUMP_FULL);
return;
}
else
{
// Found a slot!
lamer_do_restrict_alert(their);
if ((waiting_to_join) && (!accept_join))
return;
if (!waiting_to_join)
return;
if(accept_join)
if(stricmp(their->player.callsign, restricted_callsign) != 0)
return;
waiting_to_join = 0;
accept_join = 0;
player_num = oldest_player;
Network_player_added = 1;
}
}
}
else
{
// Player is reconnecting
if (Players[player_num].connected)
{
mprintf((0, "Extra REQUEST from player ignored.\n"));
return;
}
lamer_do_restrict_alert(their);
if ((waiting_to_join) && (!accept_join))
return;
if (!waiting_to_join)
return;
if(accept_join)
if(stricmp(their->player.callsign, restricted_callsign) != 0)
return;
waiting_to_join = 0;
accept_join = 0;
#ifndef SHAREWARE
if (Newdemo_state == ND_STATE_RECORDING)
newdemo_record_multi_reconnect(player_num);
#endif
Network_player_added = 0;
digi_play_sample(SOUND_HUD_MESSAGE, F1_0);
hud_message(MSGC_GAME_FEEDBACK,"'%s' %s", Players[player_num].callsign, TXT_REJOIN);
}
// Send updated Objects data to the new/returning player
Network_player_rejoining = *their;
Network_player_rejoining.player.connected = player_num;
Network_send_objects = 1;
Network_send_objnum = -1;
network_send_objects();
}
#endif //ifdef NETWORK