// disconnect from server
CL_Disconnect ();
+ // update networking ports (this is mainly just needed at startup)
+ NetConn_ClientFrame();
+
// open the demo file
strcpy (name, Cmd_Argv(1));
FS_DefaultExtension (name, ".dem");
// clear menu's connect error message
m_return_reason[0] = 0;
-
- // stop demo loop in case this fails
cls.demonum = -1;
- CL_Disconnect();
if (LHNETADDRESS_FromString(&cls.connect_address, host, 26000) && (cls.connect_mysocket = NetConn_ChooseClientSocketForAddress(&cls.connect_address)))
{
+ // stop demo loop in case this fails
+ CL_Disconnect();
+
cls.connect_trying = true;
cls.connect_remainingtries = 3;
cls.connect_nextsendtime = 0;
NetConn_ServerFrame();
}
}
+ else
+ {
+ Con_Printf("Unable to find a suitable network socket to connect to server.\n");
+ strcpy(m_return_reason, "No network");
+ }
}
/*
extern cvar_t cl_avidemo;
qboolean Host_FilterTime (double time)
{
- double timecap;
+ double timecap, timeleft;
realtime += time;
if (slowmo.value < 0.0f)
Cvar_SetValue("cl_avidemo", 0.0f);
// check if framerate is too high
- if (cl_avidemo.value >= 0.1f)
+ if (!cls.timedemo)
{
- timecap = 1.0 / (double)cl_avidemo.value;
- if ((realtime - oldrealtime) < timecap)
- return false;
- }
- else if (!cls.timedemo)
- {
- // default to sys_ticrate (server framerate - presumably low) unless we're the active window and either connected to a server or playing a video
+ // default to sys_ticrate (server framerate - presumably low) unless we
+ // have a good reason to run faster
timecap = sys_ticrate.value;
- if (vid_activewindow && (cls.state == ca_connected || cl_videoplaying))
+ if (cl_avidemo.value >= 0.1f)
+ timecap = 1.0 / (double)cl_avidemo.value;
+ else if (vid_activewindow && !scr_con_current)
timecap = 1.0 / host_maxfps.value;
- if ((realtime - oldrealtime) < timecap)
+ timeleft = oldrealtime + timecap - realtime;
+ if (timeleft > 0)
+ {
+ // don't totally hog the CPU
+ if (timeleft >= 0.02)
+ Sys_Sleep();
return false;
+ }
}
// LordHavoc: copy into host_realframetime as well
// decide the simulation time
if (!Host_FilterTime(time))
- {
- // if time was rejected, don't totally hog the CPU
- Sys_Sleep();
return;
- }
cl.islocalgame = NetConn_IsLocalGame();
Con_DPrintf ("========Initialized=========\n");
if (cls.state != ca_dedicated)
+ {
VID_Open();
+ SCR_BeginLoadingPlaque();
+ }
}
{
int n, y, visible, start, end;
cachepic_t *p;
+ const char *s;
// use as much vertical space as available
M_Background(640, vid.conheight);
// scroll the list as the cursor moves
- visible = (vid.conheight - 16 - 32) / 8;
+ s = va("%i/%i masters %i/%i servers", masterreplycount, masterquerycount, serverreplycount, serverquerycount);
+ M_PrintRed((640 - strlen(s) * 8) / 2, 32, s);
+ if (*m_return_reason)
+ M_Print(16, vid.conheight - 8, m_return_reason);
+ y = 48;
+ visible = (vid.conheight - 16 - y) / 8;
start = bound(0, slist_cursor - (visible >> 1), hostCacheCount - visible);
end = min(start + visible, hostCacheCount);
p = Draw_CachePic("gfx/p_multi.lmp");
M_DrawPic((640 - p->width) / 2, 4, "gfx/p_multi.lmp");
- y = 32;
- for (n = start;n < end;n++)
+ if (end > start)
{
- M_Print(0, y, hostcache[n].line1);y += 8;
- M_Print(0, y, hostcache[n].line2);y += 8;
+ for (n = start;n < end;n++)
+ {
+ DrawQ_Fill(menu_x, menu_y + y, 640, 16, n == slist_cursor ? (0.5 + 0.2 * sin(realtime * M_PI)) : 0, 0, 0, 0.5, 0);
+ M_Print(0, y, hostcache[n].line1);y += 8;
+ M_Print(0, y, hostcache[n].line2);y += 8;
+ }
+ }
+ else if (realtime - masterquerytime < 3)
+ {
+ if (masterquerycount)
+ M_Print(0, y, "No servers found");
+ else
+ M_Print(0, y, "No master servers found (network problem?)");
}
- M_DrawCharacter(0, 32 + (slist_cursor - start) * 16, 12+((int)(realtime*4)&1));
-
- if (*m_return_reason)
- M_Print(16, vid.conheight - 8, m_return_reason);
}
static int reliableMessagesSent = 0;
static int reliableMessagesReceived = 0;
+double masterquerytime = -1000;
+int masterquerycount = 0;
+int masterreplycount = 0;
+int serverquerycount = 0;
+int serverreplycount = 0;
+
int hostCacheCount = 0;
hostcache_t hostcache[HOSTCACHESIZE];
static int hostport = -1;
static void NetConn_UpdateServerStuff(void)
{
- if (clientport2 != cl_netport.integer)
- {
- clientport2 = cl_netport.integer;
- if (cls.state == ca_connected)
- Con_Printf("Changing \"cl_port\" will not take effect until you reconnect.\n");
- }
if (cls.state != ca_dedicated)
{
- if (cls.state == ca_disconnected && clientport != cl_netport.integer)
+ if (clientport2 != cl_netport.integer)
{
- clientport = cl_netport.integer;
+ clientport2 = cl_netport.integer;
+ if (cls.state == ca_connected)
+ Con_Printf("Changing \"cl_port\" will not take effect until you reconnect.\n");
+ }
+ if (cls.state == ca_disconnected && clientport != clientport2)
+ {
+ clientport = clientport2;
NetConn_CloseClientPorts();
}
if (cl_numsockets == 0)
string += 13;
// hostcache only uses text addresses
LHNETADDRESS_ToString(peeraddress, cname, sizeof(cname), true);
- // search the cache for this server
- for (n = 0; n < hostCacheCount; n++)
- if (!strcmp(cname, hostcache[n].cname))
- break;
- // add it or update it
- if (n == hostCacheCount)
- {
- // if cache is full replace highest ping server (the list is
- // kept sorted so this is always the last, and if this server
- // is good it will be sorted into an early part of the list)
- if (hostCacheCount >= HOSTCACHESIZE)
- n = hostCacheCount - 1;
- else
- hostCacheCount++;
- }
if ((s = SearchInfostring(string, "gamename" )) != NULL) strncpy(game, s, sizeof(game) - 1);else game[0] = 0;
if ((s = SearchInfostring(string, "modname" )) != NULL) strncpy(mod , s, sizeof(mod ) - 1);else mod[0] = 0;
if ((s = SearchInfostring(string, "mapname" )) != NULL) strncpy(map , s, sizeof(map ) - 1);else map[0] = 0;
if ((s = SearchInfostring(string, "protocol" )) != NULL) c = atoi(s);else c = -1;
if ((s = SearchInfostring(string, "clients" )) != NULL) users = atoi(s);else users = 0;
if ((s = SearchInfostring(string, "sv_maxclients")) != NULL) maxusers = atoi(s);else maxusers = 0;
- pingtime = 9999;
- for (i = 0;i < HOSTCACHESIZE;i++)
- if (!LHNETADDRESS_Compare(peeraddress, &pingcache[i].peeraddress))
- pingtime = (int)(realtime - pingcache[i].senttime);
- pingtime = bound(0, pingtime, 9999);
- memset(&hostcache[n], 0, sizeof(hostcache[n]));
- // store the data the engine cares about (address and ping)
- strcpy(hostcache[n].cname, cname);
- hostcache[n].ping = pingtime;
- // build description strings for the things users care about
- snprintf(hostcache[n].line1, sizeof(hostcache[n].line1), "%5d%c%3u/%3u %-65.65s", (int)pingtime, c != NET_PROTOCOL_VERSION ? '*' : ' ', users, maxusers, name);
- snprintf(hostcache[n].line2, sizeof(hostcache[n].line2), "%-21.21s %-19.19s %-17.17s %-20.20s", cname, game, mod, map);
- // if ping is especially high, display it as such
- if (pingtime >= 300)
- {
- // orange numbers (lower block)
- for (i = 0;i < 5;i++)
- if (hostcache[n].line1[i] != ' ')
- hostcache[n].line1[i] += 128;
- }
- else if (pingtime >= 200)
- {
- // yellow numbers (in upper block)
- for (i = 0;i < 5;i++)
- if (hostcache[n].line1[i] != ' ')
- hostcache[n].line1[i] -= 30;
- }
- // if not in the slist menu we should print the server to console
- if (m_state != m_slist)
- Con_Printf("%s\n%s\n", hostcache[n].line1, hostcache[n].line2);
- // and finally, re-sort the list
- for (i = 0;i < hostCacheCount;i++)
+ // search the cache for this server and update it
+ for (n = 0; n < hostCacheCount; n++)
{
- for (j = i + 1;j < hostCacheCount;j++)
+ if (!strcmp(cname, hostcache[n].cname))
{
- //if (strcmp(hostcache[j].name, hostcache[i].name) < 0)
- if (hostcache[i].ping > hostcache[j].ping)
+ if (hostcache[n].ping == 100000)
+ serverreplycount++;
+ pingtime = (int)((realtime - hostcache[n].querytime) * 1000.0);
+ pingtime = bound(0, pingtime, 9999);
+ // update the ping
+ hostcache[n].ping = pingtime;
+ // build description strings for the things users care about
+ snprintf(hostcache[n].line1, sizeof(hostcache[n].line1), "%5d%c%3u/%3u %-65.65s", (int)pingtime, c != NET_PROTOCOL_VERSION ? '*' : ' ', users, maxusers, name);
+ snprintf(hostcache[n].line2, sizeof(hostcache[n].line2), "%-21.21s %-19.19s %-17.17s %-20.20s", cname, game, mod, map);
+ // if ping is especially high, display it as such
+ if (pingtime >= 300)
+ {
+ // orange numbers (lower block)
+ for (i = 0;i < 5;i++)
+ if (hostcache[n].line1[i] != ' ')
+ hostcache[n].line1[i] += 128;
+ }
+ else if (pingtime >= 200)
{
- memcpy(&temp, &hostcache[j], sizeof(hostcache_t));
- memcpy(&hostcache[j], &hostcache[i], sizeof(hostcache_t));
- memcpy(&hostcache[i], &temp, sizeof(hostcache_t));
+ // yellow numbers (in upper block)
+ for (i = 0;i < 5;i++)
+ if (hostcache[n].line1[i] != ' ')
+ hostcache[n].line1[i] -= 30;
}
+ // if not in the slist menu we should print the server to console
+ if (m_state != m_slist)
+ Con_Printf("%s\n%s\n", hostcache[n].line1, hostcache[n].line2);
+ // and finally, re-sort the list
+ for (i = 0;i < hostCacheCount;i++)
+ {
+ for (j = i + 1;j < hostCacheCount;j++)
+ {
+ //if (strcmp(hostcache[j].name, hostcache[i].name) < 0)
+ if (hostcache[i].ping > hostcache[j].ping)
+ {
+ memcpy(&temp, &hostcache[j], sizeof(hostcache_t));
+ memcpy(&hostcache[j], &hostcache[i], sizeof(hostcache_t));
+ memcpy(&hostcache[i], &temp, sizeof(hostcache_t));
+ }
+ }
+ }
+ break;
}
}
return true;
}
if (!strncmp(string, "getserversResponse\\", 19) && hostCacheCount < HOSTCACHESIZE)
{
- int i, best;
- double besttime;
+ int i, n, j;
+ hostcache_t temp;
// Extract the IP addresses
data += 18;
length -= 18;
+ masterreplycount++;
+ if (m_state != m_slist)
+ Con_Printf("received server list...\n");
while (length >= 7 && data[0] == '\\' && (data[1] != 0xFF || data[2] != 0xFF || data[3] != 0xFF || data[4] != 0xFF) && data[5] * 256 + data[6] != 0)
{
sprintf(ipstring, "%u.%u.%u.%u:%u", data[1], data[2], data[3], data[4], (data[5] << 8) | data[6]);
Con_Printf("Requesting info from server %s\n", ipstring);
LHNETADDRESS_FromString(&svaddress, ipstring, 0);
NetConn_WriteString(mysocket, "\377\377\377\377getinfo", &svaddress);
- // replace oldest or matching entry in ping cache
- // we scan this later when getting a reply to see how long it took
- besttime = realtime;
- best = 0;
- for (i = 0;i < HOSTCACHESIZE;i++)
+
+
+ // add to slist (hostCache)
+ // search the cache for this server
+ for (n = 0; n < hostCacheCount; n++)
+ if (!strcmp(ipstring, hostcache[n].cname))
+ break;
+ // add it or update it
+ if (n == hostCacheCount)
{
- if (!LHNETADDRESS_Compare(&svaddress, &pingcache[i].peeraddress))
+ // if cache is full replace highest ping server (the list is
+ // kept sorted so this is always the last, and if this server
+ // is good it will be sorted into an early part of the list)
+ if (hostCacheCount >= HOSTCACHESIZE)
+ n = hostCacheCount - 1;
+ else
{
- best = i;
- break;
+ serverquerycount++;
+ hostCacheCount++;
}
- if (besttime > pingcache[i].senttime)
+ }
+ memset(&hostcache[n], 0, sizeof(hostcache[n]));
+ // store the data the engine cares about (address and ping)
+ strcpy(hostcache[n].cname, ipstring);
+ hostcache[n].ping = 100000;
+ hostcache[n].querytime = realtime;
+ // build description strings for the things users care about
+ snprintf(hostcache[n].line1, sizeof(hostcache[n].line1), "?");
+ snprintf(hostcache[n].line2, sizeof(hostcache[n].line2), "%s", ipstring);
+ // if not in the slist menu we should print the server to console
+ if (m_state != m_slist)
+ Con_Printf("querying %s\n", ipstring);
+ // and finally, re-sort the list
+ for (i = 0;i < hostCacheCount;i++)
+ {
+ for (j = i + 1;j < hostCacheCount;j++)
{
- besttime = pingcache[i].senttime;
- best = i;
- // if ping cache isn't full yet we can skip out early
- if (!besttime)
- break;
+ //if (strcmp(hostcache[j].name, hostcache[i].name) < 0)
+ if (hostcache[i].ping > hostcache[j].ping)
+ {
+ memcpy(&temp, &hostcache[j], sizeof(hostcache_t));
+ memcpy(&hostcache[j], &hostcache[i], sizeof(hostcache_t));
+ memcpy(&hostcache[i], &temp, sizeof(hostcache_t));
+ }
}
}
- pingcache[best].peeraddress = svaddress;
- pingcache[best].senttime = realtime;
+
+
// move on to next address in packet
data += 7;
length -= 7;
if (cls.connect_remainingtries == 0)
{
cls.connect_trying = false;
- Con_Printf("Connect failed\n");
+ if (m_state == m_slist)
+ strcpy(m_return_reason, "Connect: Failed");
+ else
+ Con_Printf("Connect failed\n");
return;
}
if (cls.connect_nextsendtime)
- Con_Printf("Still trying...\n");
+ {
+ if (m_state == m_slist)
+ strcpy(m_return_reason, "Connect: Still trying");
+ else
+ Con_Printf("Still trying...\n");
+ }
else
- Con_Printf("Trying...\n");
+ {
+ if (m_state == m_slist)
+ strcpy(m_return_reason, "Connect: Trying");
+ else
+ Con_Printf("Trying...\n");
+ }
cls.connect_nextsendtime = realtime + 1;
cls.connect_remainingtries--;
// try challenge first (newer server)
NetConn_ServerParsePacket(sv_sockets[i], readbuffer, length, &peeraddress);
for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
{
- if (host_client->netconnection && realtime > host_client->netconnection->timeout)
+ // never timeout loopback connections
+ if (host_client->netconnection && realtime > host_client->netconnection->timeout && LHNETADDRESS_GetAddressType(LHNET_AddressFromSocket(host_client->netconnection->mysocket)) != LHNETADDRESSTYPE_LOOP)
{
Con_Printf("Client \"%s\" connection timed out\n", host_client->name);
sv_player = host_client->edict;
// search internet
for (masternum = 0;sv_masters[masternum].name;masternum++)
+ {
if (sv_masters[masternum].string && LHNETADDRESS_FromString(&masteraddress, sv_masters[masternum].string, MASTER_PORT) && LHNETADDRESS_GetAddressType(&masteraddress) == LHNETADDRESS_GetAddressType(LHNET_AddressFromSocket(cl_sockets[i])))
+ {
+ masterquerycount++;
NetConn_WriteString(cl_sockets[i], request, &masteraddress);
+ }
+ }
}
}
+ if (!masterquerycount)
+ {
+ Con_Printf("Unable to query master servers, no suitable network sockets active.\n");
+ strcpy(m_return_reason, "No network");
+ }
}
void NetConn_Heartbeat(int priority)
static void Net_Heartbeat_f(void)
{
- NetConn_Heartbeat(2);
+ if (sv.active)
+ NetConn_Heartbeat(2);
+ else
+ Con_Printf("No server running, can not heartbeat to master server.\n");
}
void PrintStats(netconn_t *conn)
void Net_Slist_f(void)
{
+ masterquerytime = realtime;
+ masterquerycount = 0;
+ masterreplycount = 0;
+ serverquerycount = 0;
+ serverreplycount = 0;
hostCacheCount = 0;
memset(&pingcache, 0, sizeof(pingcache));
if (m_state != m_slist)
typedef struct
{
// ping time for sorting servers
- double ping;
+ int ping;
+ // used to calculate ping when update comes in
+ double querytime;
// address for connecting
char cname[128];
// description (seen by user)
//
//============================================================================
+extern double masterquerytime;
+extern int masterquerycount;
+extern int masterreplycount;
+extern int serverquerycount;
+extern int serverreplycount;
+
extern sizebuf_t net_message;
extern cvar_t cl_fakelocalping_min;
{
m.tex[0] = R_GetTexture(skyboxside[i]);
R_Mesh_State_Texture(&m);
- R_Mesh_Draw(4, 2, skyboxelements + i * 6);
+ R_Mesh_Draw(6*4, 2, skyboxelements + i * 6);
}
}
- todo: difficulty ratings are: 0 = trivial, 1 = easy, 2 = easy-moderate, 3 = moderate, 4 = moderate-hard, 5 = hard, 6 = hard++, 7 = nightmare, d = done, -n = done but have not notified the people who asked for it, f = failed
+-n darkplaces: add stats to slist menu displaying how many masters/servers have been queried and replied (tell yummyluv)
-n darkplaces: check out qe1 textures and make sure they load in all the e1 maps, report of crashing in most but not all maps (Linny Amore)
+-n darkplaces: display "No servers found" instead of a cursor when there are none (yummyluv)
-n darkplaces: fix a crash when changing level while using qe1 textures (Todd)
--n darkplaces: make LHNET_Read print out the names of read errors (yummyluv)
+-n darkplaces: fix skybox geometry (SeienAbunae)
+-n darkplaces: net_slist and the server browser should show servers when they are queried, not just when they reply; which would replace the matching entry (yummyluv)
+-n darkplaces: net_slist should print out "No network." if networking is not initialized (yummyluv)
+-n darkplaces: remove dead master server from default masters list (yummyluv)
-n darkplaces: revert noclip movement to match nq for compatibility with mods that trap movement as input (MauveBib)
+-n darkplaces: segfault reading memory in windows when starting a new server from menu (yummyluv)
+-n darkplaces: server is starting before the "port" cvar is set by commandline and scripts? (yummyluv)
+-n darkplaces: typing ip in join game menu should show 'trying' and 'no response' after a while, or 'no network' if networking is not initialized (yummyluv)
-n dpmod: make grapple off-hand (joe hill)
-0 darkplaces: add Draw2D function to model struct to make it easy to draw models without an entity (Tomaz)
-0 darkplaces: fix "game speed" menu option, it's too far left (Tomaz)
-4 darkplaces: add crude DML model loading with animation list (ask Riot for dml library) (Mitchell)
-5 darkplaces: add crude SKM model loading with animation list (Vermeulen)
-2 darkplaces: should support corona-model shaders somehow (equation: pow(normalizationcubemap(transform(eye, vertexmatrix)) dot3 '0 0 1', 8)), which are normally used around unusually shaped lights instead of flat coronas (Mitchell)
-0 lhfire: make a lhfire.txt and move the scripting info to it, add some more general explanation and tips
-0 darkplaces: add sv_gameplayfix_grenadebouncedownslopes cvar (default 1)
-0 darkplaces: add sv_gameplayfix_swiminbmodels cvar (default 1)
-0 darkplaces: add sv_gameplayfix_stepwhilejumping cvar (default 1), note that sv_jumpstep must also be on to enable this
-0 darkplaces: add sv_gameplayfix_noairborncorpse cvar (default 1)
0 darkplaces: ability to disable fopen builtin access to read /, read data/, write data/, or disable fopen builtin entirely
0 darkplaces: add DP_GFX_QUAKE3MODELTAGS, DP_GFX_SKINFILES, and any other new extensions to the wiki
0 darkplaces: add DP_LITSUPPORT extension and document it
0 darkplaces: add DP_SV_ROTATINGBMODEL extension to explain that MOVETYPE_PUSH/SOLID_BSP support rotation in darkplaces and a demonstration of how to use it without qc modifications (Uffe, Supajoe)
+0 darkplaces: add Draw2D function to model struct to make it easy to draw models without an entity (Tomaz)
0 darkplaces: add a .collision_cancollide QC function call to decide if an entity should collide with another, or pass through it (Uffe)
0 darkplaces: add a clipmask thingy to allow QC to mask off collisions as it wishes (Uffe)
0 darkplaces: add a scr_screenshot_jpeg_quality cvar (Electro)
0 darkplaces: add lightning beam settings to menu (romi)
0 darkplaces: add slowmo to options menu (Cristian Beltramo)
0 darkplaces: add support for multiple -game's (note: this needs an enhanced COM_CheckParm to find the multiple matches) (Static_Fiend)
+0 darkplaces: add sv_gameplayfix_grenadebouncedownslopes cvar (default 1)
+0 darkplaces: add sv_gameplayfix_noairborncorpse cvar (default 1)
+0 darkplaces: add sv_gameplayfix_stepwhilejumping cvar (default 1), note that sv_jumpstep must also be on to enable this
+0 darkplaces: add sv_gameplayfix_swiminbmodels cvar (default 1)
0 darkplaces: add svc_setanglefloat and DP_SVC_SETANGLEFLOAT extension (FrikaC, SeienAbunae)
0 darkplaces: add te_flamejet builtin and add extension (Supajoe)
-0 darkplaces: add view height to chase_active again (yummyluv)
0 darkplaces: alias layers should have a shadow volume pass so that nodraw textures don't cast a shadow (Electro)
0 darkplaces: bug in mod_q3bsp_optimizedtraceline code, bots shooting through walls? (Vermeulen)
0 darkplaces: bullets don't hit walls at steep angles in id1
0 darkplaces: can't move when stuck in a monster (SeienAbunae)
0 darkplaces: change particle() macro in cl_particles.c to have a do{}while(0) to eat the ;
0 darkplaces: cl_particles_maximum cvar (default 32768) which would change number of particles allowed at once (TheBeast)
-0 darkplaces: cl_port 26001 causes server browser to read successfully (yummyluv)
0 darkplaces: clean up the DrawQ_ blendfunc handling, instead of taking DRAWFLAG_ADDITIVE they should take blendfunc values (Black)
0 darkplaces: client colors being reset to "15 15" each level in prydon gate (FrikaC)
0 darkplaces: crashes if you type too long a command line in the console (SeienAbunae)
0 darkplaces: darkplaces-glx -path transfusion crashes, fix the crash even though it's not going to work anyway (Todd)
0 darkplaces: dedicated server hosting prydon with multiple players exhibited severe networking bugs in tests, including failure to find acked network frames, and a segfault (Supajoe, Uffe, FrikaC, Harb)
-0 darkplaces: dedicated server should error out if it has no sockets (yummyluv)
-0 darkplaces: dedicated server should not bother allocating a loopback socket (yummyluv)
0 darkplaces: default to 32bit color
0 darkplaces: delay "connect" and "playdemo" and "timedemo" until after video init to cause quicker video startup (KrimZon)
0 darkplaces: document how polygon collision works in the code (KrimZon)
0 darkplaces: figure out random crashes on map changes (Uffe, QorpsE)
0 darkplaces: figure out what's wrong with gloss rendering vertex calculations, which may be GF2 related (QorpsE)
0 darkplaces: figure out why monsters keep making fall pain sound after they've landed in dpmod (Cruaich)
+0 darkplaces: fix "game speed" menu option, it's too far left (Tomaz)
0 darkplaces: fix 'wall hugging' stuttering, also stuttering movement when walking over steps or monsters (romi)
0 darkplaces: fix con_notify (should control number of lines)
0 darkplaces: fix intermission failing to move view to intermission camera (romi, Zombie_13)
0 darkplaces: fix key based turning being affected by slowmo - it should not be
-0 darkplaces: fix skybox geometry (SeienAbunae)
0 darkplaces: fix the fact singleplayer is using maxplayers 8
0 darkplaces: fix view blends slightly lingering as time goes on, they should go away completely (Cruaich)
0 darkplaces: get rid of stencil options and make 32bit color automatically use stencil
0 darkplaces: hack PF_nextent to skip inaccessible client slots depending on maxplayers - but always report ones that are active at the time (FrikaC)
-0 darkplaces: heartbeat should print an error message if used with no server running (yummyluv)
0 darkplaces: identify weird lightmap texturing bug on TNT cards - goes away in r_textureunits 1 (NotoriousRay, Uffe)
0 darkplaces: increase resolution of particlefont to 512x512 (Chillo)
0 darkplaces: integrate zinx's psycho.c gamma hack as an easteregg
-0 darkplaces: investigate why server is not automatically sending heartbeats (yummyluv)
0 darkplaces: make Com_HexDumpToConsole not use color
0 darkplaces: make DP_EF_FULLBRIGHT extension (FrikaC)
0 darkplaces: make S_Update take a matrix4x4_t *
0 darkplaces: make sure that sound engine does not remove sounds when volume drops to 0 due to going out of range (SeienAbunae)
0 darkplaces: make the WriteEntitiesToClient code call TraceBox directly instead of SV_Move because checking all the entities is far too slow in helm18 (banshee21)
0 darkplaces: model interpolation off crashes? (SeienAbunae)
-0 darkplaces: net_slist and the server browser should show servers when they are queried, not just when they reply; which would replace the matching entry (yummyluv)
-0 darkplaces: net_slist should print out "No network." if networking is not initialized (yummyluv)
0 darkplaces: noclipping out the ceiling of q3dm17 crashes (Static_Fiend)
0 darkplaces: pointcontents crash when building harvester in gvb2? (yummyluv)
0 darkplaces: r_shadow should load .ent when importing light entities
0 darkplaces: r_shadow_portallight 1 (default) mode is broken currently, does not light all surfaces, maybe even fails to go through some portals? (Vermeulen)
0 darkplaces: r_skyscroll1 and r_skyscroll2 cvars (SeienAbunae)
-0 darkplaces: remove dead master server from default masters list (yummyluv)
0 darkplaces: rename r_picmip and r_max_size and such to glquake names
0 darkplaces: reset zoom on connect (Rick)
0 darkplaces: scrags frequently fly through ceilings - this needs to be fixed
-0 darkplaces: segfault reading memory in windows when starting a new server from menu (yummyluv)
-0 darkplaces: server is starting before the "port" cvar is set by commandline and scripts? (yummyluv)
0 darkplaces: shadows are not working with model tag attachments (Electro)
0 darkplaces: test TecnoX and find the frikbot crash in SV_Physics (KrimZon)
0 darkplaces: test zlib support with entirely pk3'd id1 data (should crash because of zlib not being setup early enough - fix this) (Mabus)
0 darkplaces: the new sound engine should have a cvar for random variations of pitch on sounds like in doom (RenegadeC)
0 darkplaces: try not adding gravity when onground to see if it gets rid of ramp sliding (Midgar)
0 darkplaces: tweak the blood decals in the particlefont to make them look more like the q2e_blood.avi video (Vermeulen)
-0 darkplaces: typing ip in join game menu should show 'trying' and 'no response' after a while, or 'no network' if networking is not initialized (yummyluv)
0 dpmod: add a "monsterwander" cvar and default it off, this would enable the spawnwanderpath code (Zombie13)
0 dpmod: add combo kill detection; rapid burst of kills (SeienAbunae)
0 dpmod: add flame thrower enforcers back (scar3crow)
0 dpzoo: thief-like area to sneak past a guard who can easily kill you (shambler?) to demonstrate lightlevel checking
0 dpzoo: transparent glass bmodels (DP_ENT_ALPHA)
0 hmap: add space to seconds reports in all utilities so it doesn't say secondssss (FrikaC)
+0 lhfire: make a lhfire.txt and move the scripting info to it, add some more general explanation and tips
0 litsupport: fix the one COM_HunkFile call that uses two parameters (glquake took one) and fix the few "//lit support begin" messages at the end of code blocks (metlslime)
0 revelation: change the wabbit kill message to " was hunting wabbit but shot " " instead"
0 sv_user.qc: figure out why looking up/down slows movement and fix it (Vermeulen)
1 darkplaces: client crashes on +button8? (Static_Fiend)
1 darkplaces: crashes on radeon in rare situations that seem to occur in dpmod dm 7 mode? (Option42)
1 darkplaces: decide on an extension name for .ent loading and report it, also document in dpextensions (tell FrikaC, Gleeb, and add to wiki)
-1 darkplaces: display "No servers found" instead of a cursor when there are none (yummyluv)
1 darkplaces: don't accept connect packets after first one (tell Willis)
-1 darkplaces: figure out what's causing skybox to go textureless occasionally (yummyluv)
1 darkplaces: finish porting Quake2 keyboard stuff (such as clipboard) (Rick, FrikaC)
1 darkplaces: fix lots of bugs and then retitle the website to get more publicity: DarkPlaces: Re-live Quake again...
1 darkplaces: fix stuck buttons during a level change (mercury82, tkimmet@ezworks.net) (further note: this is from the console becoming active temporarily and catching the key release when the player lets go during the loading stage, make it possible to release a button that was pressed before the console was activated, or make it execute -commands for all pressed binds when level starts)
2 darkplaces: add cvar callbacks and make net cvars have callbacks
2 darkplaces: add fuhquake naming of map textures (textures/start/quake.tga style)
2 darkplaces: add removemapmusic (optional map name or ogg name to clear) and mapmusic commands (<maps/mapname.bsp> <music/whatever.ogg> perhaps) to manipulate list of per-map music overrides (Joseph Caporale, tell Static_Fiend)
-2 darkplaces: add stats to slist menu displaying how many masters/servers have been queried and replied (tell yummyluv)
2 darkplaces: figure out how to prevent "alias a a" - infinite loop when executed, this should be detected when executing it (Vicious)
2 darkplaces: figure out why -sndspeed 22050, 44100 and 16000 are choppy in windows? (cheapalert)
2 darkplaces: frikbot scores don't update - discovered this is because of the fact they have no client (Todd)
2 darkplaces: player ip logging by nickname (sublim3)
2 darkplaces: prevent player name changes faster than twice a second (sublim3)
2 darkplaces: proquake precise aiming support (sublim3 doesn't care, but tell him anyway)
+2 darkplaces: should support corona-model shaders somehow (equation: pow(normalizationcubemap(transform(eye, vertexmatrix)) dot3 '0 0 1', 8)), which are normally used around unusually shaped lights instead of flat coronas (Mitchell)
2 darkplaces: upgrade protocol to have shorts for stats (scar3crow)
2 darkplaces: write a readme (Antti)
2 darkplaces: zym shadows
4 darkplaces: add SKM model support with multianimation support using multiple .frame fields on the entities (Vermeulen)
4 darkplaces: add builtin to clientside qc for reading triangles of model meshes (useful to orient a ui along a triangle of a model mesh)
4 darkplaces: add builtins to clientside qc for gl calls
+4 darkplaces: add crude DML model loading with animation list (ask Riot for dml library) (Mitchell)
4 darkplaces: add traceboxwithcontents function (same as tracebox but adds the startcontents parameter) (LTH, SeienAbunae, http://forums.inside3d.com/showflat.pl?Board=Engine&Number=909 )
4 darkplaces: add wav music playback (tell Joseph Caporale, tell Static_Fiend)
4 darkplaces: figure out what is breaking in prydon gate town curig (Uffe)
5 darkplaces: add a "edictedit" command to open up a dialog to edit an edict (allow multiple dialogs to be open at once)
5 darkplaces: add a new TE_TELEPORTSHELL effect which would take an entity and create a fading plasma shell of its model at the moment of teleportation (tell fuh and Mercury about this)
5 darkplaces: add back colormod extension (FrikaC, Uffe)
+5 darkplaces: add crude SKM model loading with animation list (Vermeulen)
5 darkplaces: add dpshader support
5 darkplaces: add short and long documentation string to each cvar/command (QorpsE)
5 darkplaces: do a minimap that works by simply using nearclip to sheer off anything above the eye, and draws anything below normally, or via a cvar as height coloring (Supajoe)
d darkplaces: add file access functions and string handling (diGGer)
d darkplaces: add multiple skin support to md2/md3 (Vermeuln)
d darkplaces: add scr_conbrightness cvar (0-1) to control brightness of conback (0 = black and does not load conback, resets back to 0 if conback fails to load)
+d darkplaces: add view height to chase_active again (yummyluv)
d darkplaces: add wgl support for mouse buttons 4 and 5 (Intellimouse Explorer) from Q2 (source supplied in email from joseph caporale@sbcglobal.net)
d darkplaces: check if nodrawtoclient works and if not, fix it (Uffe)
d darkplaces: colors of player in demos seems to alter player config (this is clearly a more severe problem than just demos) (tkimmet@ezworks.net)
d darkplaces: debug server crash
+d darkplaces: dedicated server should error out if it has no sockets (yummyluv)
+d darkplaces: dedicated server should not bother allocating a loopback socket (yummyluv)
d darkplaces: default deathmatch 1 in multiplayer games like Nexuiz incase someone starts a game from console (Vermeulen)
d darkplaces: figure out what is broken about the shadow volumes or stencil comparisons
d darkplaces: figure out what is wrong with loading _glow/_luma textures on md3 models (not bsp textures) (kd23 Nexuiz)
d darkplaces: get rid of frags per hour rating in deathmatch scoreboard and mini scoreboard
d darkplaces: gl_flashblend 1 should disable dlighting of models (Tomaz)
d darkplaces: have a look at CFQ and figure out why its b0rked (it assumed nq noclip movement)
+d darkplaces: heartbeat should print an error message if used with no server running (yummyluv)
d darkplaces: loadgame broken (Linny Amore)
+d darkplaces: make LHNET_Read print out the names of read errors (yummyluv)
d darkplaces: make client load .ent files
d darkplaces: make missing skins show as white on models (Electro)
d darkplaces: make model lerping optional