X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=sv_main.c;h=37d085088feb3e6e2e15a21da89d905970bc7728;hb=b0f58d418242fbf593e98ba88ff2b1a2a9ff89e8;hp=867c0bdffa4035940f5ae84886782a64953d86b2;hpb=f1572007b4abc4cba2a834095c84e731562926b8;p=xonotic%2Fdarkplaces.git diff --git a/sv_main.c b/sv_main.c index 867c0bdf..37d08508 100644 --- a/sv_main.c +++ b/sv_main.c @@ -147,8 +147,8 @@ cvar_t sv_sound_watersplash = {CF_SERVER, "sv_sound_watersplash", "misc/h2ohit1. cvar_t sv_stepheight = {CF_SERVER | CF_NOTIFY, "sv_stepheight", "18", "how high you can step up (TW_SV_STEPCONTROL extension)"}; cvar_t sv_stopspeed = {CF_SERVER | CF_NOTIFY, "sv_stopspeed","100", "how fast you come to a complete stop"}; cvar_t sv_wallfriction = {CF_SERVER | CF_NOTIFY, "sv_wallfriction", "1", "how much you slow down when sliding along a wall"}; -cvar_t sv_wateraccelerate = {CF_SERVER, "sv_wateraccelerate", "-1", "rate at which a player accelerates to sv_maxspeed while in the air, if less than 0 the sv_accelerate variable is used instead"}; -cvar_t sv_waterfriction = {CF_SERVER | CF_NOTIFY, "sv_waterfriction","-1", "how fast you slow down, if less than 0 the sv_friction variable is used instead"}; +cvar_t sv_wateraccelerate = {CF_SERVER, "sv_wateraccelerate", "-1", "rate at which a player accelerates to sv_maxspeed while in water, if less than 0 the sv_accelerate variable is used instead"}; +cvar_t sv_waterfriction = {CF_SERVER | CF_NOTIFY, "sv_waterfriction","-1", "how fast you slow down in water, if less than 0 the sv_friction variable is used instead"}; cvar_t sv_warsowbunny_airforwardaccel = {CF_SERVER, "sv_warsowbunny_airforwardaccel", "1.00001", "how fast you accelerate until you reach sv_maxspeed"}; cvar_t sv_warsowbunny_accel = {CF_SERVER, "sv_warsowbunny_accel", "0.1585", "how fast you accelerate until after reaching sv_maxspeed (it gets harder as you near sv_warsowbunny_topspeed)"}; cvar_t sv_warsowbunny_topspeed = {CF_SERVER, "sv_warsowbunny_topspeed", "925", "soft speed limit (can get faster with rjs and on ramps)"}; @@ -435,16 +435,16 @@ static void SV_AreaStats_f(cmd_state_t *cmd) static qbool SV_CanSave(void) { prvm_prog_t *prog = SVVM_prog; - if(SV_IsLocalGame() == 1) + if(SV_IsLocalServer() == 1) { // singleplayer checks - if (!(svs.clients[0].active && PRVM_serveredictfloat(svs.clients[0].edict, deadflag))) + if ((svs.clients[0].active && PRVM_serveredictfloat(svs.clients[0].edict, deadflag))) { Con_Print("Can't savegame with a dead player\n"); return false; } - if(!host.hook.CL_Intermission || !host.hook.CL_Intermission()) + if(host.hook.CL_Intermission && host.hook.CL_Intermission()) { Con_Print("Can't save in intermission.\n"); return false; @@ -456,6 +456,56 @@ static qbool SV_CanSave(void) } +static void SV_ServerOptions (void) +{ + int i; + + // general default + svs.maxclients = 8; + +// COMMANDLINEOPTION: Server: -dedicated [playerlimit] starts a dedicated server (with a command console), default playerlimit is 8 +// COMMANDLINEOPTION: Server: -listen [playerlimit] starts a multiplayer server with graphical client, like singleplayer but other players can connect, default playerlimit is 8 + // if no client is in the executable or -dedicated is specified on + // commandline, start a dedicated server + i = Sys_CheckParm ("-dedicated"); + if (i || !cl_available) + { + cls.state = ca_dedicated; + // check for -dedicated specifying how many players + if (i && i + 1 < sys.argc && atoi (sys.argv[i+1]) >= 1) + svs.maxclients = atoi (sys.argv[i+1]); + if (Sys_CheckParm ("-listen")) + Con_Printf ("Only one of -dedicated or -listen can be specified\n"); + // default sv_public on for dedicated servers (often hosted by serious administrators), off for listen servers (often hosted by clueless users) + Cvar_SetValue(&cvars_all, "sv_public", 1); + } + else if (cl_available) + { + // client exists and not dedicated, check if -listen is specified + cls.state = ca_disconnected; + i = Sys_CheckParm ("-listen"); + if (i) + { + // default players unless specified + if (i + 1 < sys.argc && atoi (sys.argv[i+1]) >= 1) + svs.maxclients = atoi (sys.argv[i+1]); + } + else + { + // default players in some games, singleplayer in most + if (gamemode != GAME_GOODVSBAD2 && !IS_NEXUIZ_DERIVED(gamemode) && gamemode != GAME_BATTLEMECH) + svs.maxclients = 1; + } + } + + svs.maxclients = svs.maxclients_next = bound(1, svs.maxclients, MAX_SCOREBOARD); + + svs.clients = (client_t *)Mem_Alloc(sv_mempool, sizeof(client_t) * svs.maxclients); + + if (svs.maxclients > 1 && !deathmatch.integer && !coop.integer) + Cvar_SetValueQuick(&deathmatch, 1); +} + /* =============== SV_Init @@ -659,6 +709,8 @@ void SV_Init (void) host.hook.SV_CanSave = SV_CanSave; sv_mempool = Mem_AllocPool("server", 0, NULL); + + SV_ServerOptions(); } static void SV_SaveEntFile_f(cmd_state_t *cmd) @@ -1325,7 +1377,7 @@ SV_ModelIndex */ int SV_ModelIndex(const char *s, int precachemode) { - int i, limit = ((sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3) ? 256 : MAX_MODELS); + int i, limit = ((sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE) ? 256 : MAX_MODELS); char filename[MAX_QPATH]; if (!s || !*s) return 0; @@ -1388,7 +1440,7 @@ SV_SoundIndex */ int SV_SoundIndex(const char *s, int precachemode) { - int i, limit = ((sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3) ? 256 : MAX_SOUNDS); + int i, limit = ((sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_NEHAHRABJP) ? 256 : MAX_SOUNDS); char filename[MAX_QPATH]; if (!s || !*s) return 0; @@ -1519,12 +1571,12 @@ int SV_ParticleEffectIndex(const char *name) return 0; } -dp_model_t *SV_GetModelByIndex(int modelindex) +model_t *SV_GetModelByIndex(int modelindex) { return (modelindex > 0 && modelindex < MAX_MODELS) ? sv.models[modelindex] : NULL; } -dp_model_t *SV_GetModelFromEdict(prvm_edict_t *ed) +model_t *SV_GetModelFromEdict(prvm_edict_t *ed) { prvm_prog_t *prog = SVVM_prog; int modelindex; @@ -1694,11 +1746,10 @@ void SV_SaveSpawnparms (void) } } -qbool SV_IsLocalServer(void) +// Returns 1 if we're singleplayer, > 1 if we're a listen server +int SV_IsLocalServer(void) { - if(host_isclient.integer && host_client && LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) == LHNETADDRESSTYPE_LOOP) - return true; - return false; + return (host_isclient.integer && sv.active ? svs.maxclients : 0); } /* @@ -1715,7 +1766,7 @@ void SV_SpawnServer (const char *map) prvm_edict_t *ent; int i; char *entities; - dp_model_t *worldmodel; + model_t *worldmodel; char modelname[sizeof(sv.worldname)]; char vabuf[1024]; @@ -2014,17 +2065,6 @@ void SV_SpawnServer (const char *map) // SV_UnlockThreadMutex(); } -/* - * Returns number of slots if we're a listen server. - * Returns 0 if we're a dedicated server. - */ -int SV_IsLocalGame(void) -{ - if (sv.active && LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) == LHNETADDRESSTYPE_LOOP) - return svs.maxclients; - return 0; -} - /* ================== SV_Shutdown @@ -2415,6 +2455,21 @@ static void SV_VM_Setup(void) SV_Prepare_CSQC(); } +static void SV_CheckTimeouts(void) +{ + int i; + + // never timeout loopback connections + for (i = (host_isclient.integer ? 1 : 0), host_client = &svs.clients[i]; i < svs.maxclients; i++, host_client++) + { + if (host_client->netconnection && host.realtime > host_client->netconnection->timeout) + { + Con_Printf("Client \"%s\" connection timed out\n", host_client->name); + SV_DropClient(false); + } + } +} + extern cvar_t host_maxwait; extern cvar_t host_framerate; extern cvar_t cl_maxphysicsframesperserverframe; @@ -2468,7 +2523,10 @@ double SV_Frame(double time) * be undersleeping due to select() detecting a new packet */ if (sv.active) + { NetConn_ServerFrame(); + SV_CheckTimeouts(); + } } /* @@ -2647,7 +2705,10 @@ static int SV_ThreadFunc(void *voiddata) // get new packets if (sv.active) + { NetConn_ServerFrame(); + SV_CheckTimeouts(); + } // if the accumulators haven't become positive yet, wait a while wait = sv_timer * -1000000.0;