diff --git a/src/command.c b/src/command.c index 3eebe32d..6d9c86d3 100644 --- a/src/command.c +++ b/src/command.c @@ -902,7 +902,10 @@ static void COM_Add_f(void) return; } - CV_AddValue(cvar, atoi(COM_Argv(2))); + if (( cvar->flags & CV_FLOAT )) + CV_Set(cvar, va("%f", FIXED_TO_FLOAT (cvar->value) + atof(COM_Argv(2)))); + else + CV_AddValue(cvar, atoi(COM_Argv(2))); } // ========================================================================= diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 1dc2c142..213f5dde 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -1428,8 +1428,14 @@ static void SV_SendPlayerInfo(INT32 node) UINT8 i; netbuffer->packettype = PT_PLAYERINFO; - for (i = 0; i < MAXPLAYERS; i++) + for (i = 0; i < MSCOMPAT_MAXPLAYERS; i++) { + if (i >= MAXPLAYERS) + { + netbuffer->u.playerinfo[i].node = 255; + continue; + } + if (!playeringame[i]) { netbuffer->u.playerinfo[i].node = 255; // This slot is empty. @@ -1477,7 +1483,7 @@ static void SV_SendPlayerInfo(INT32 node) netbuffer->u.playerinfo[i].data |= 0x80; } - HSendPacket(node, false, 0, sizeof(plrinfo) * MAXPLAYERS); + HSendPacket(node, false, 0, sizeof(plrinfo) * MSCOMPAT_MAXPLAYERS); } /** Sends a PT_SERVERCFG packet diff --git a/src/d_clisrv.h b/src/d_clisrv.h index d7f033b6..e961c38f 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -470,7 +470,7 @@ typedef struct serverrefuse_pak serverrefuse; // 65025 bytes (somehow I feel like those values are garbage...) askinfo_pak askinfo; // 61 bytes msaskinfo_pak msaskinfo; // 22 bytes - plrinfo playerinfo[MAXPLAYERS]; // 576 bytes(?) + plrinfo playerinfo[MSCOMPAT_MAXPLAYERS];// 576 bytes(?) plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?) INT32 filesneedednum; // 4 bytes filesneededconfig_pak filesneededcfg; // ??? bytes diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 0bb87556..7dff1231 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2040,7 +2040,7 @@ static void Command_View_f(void) return; } - displayplayerp = &displayplayers[viewnum]; + displayplayerp = &displayplayers[viewnum-1]; if (COM_Argc() > 1)/* switch to player */ { diff --git a/src/d_netfil.c b/src/d_netfil.c index 4dcd3da4..76b66836 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -130,7 +130,8 @@ UINT8 *PutFileNeeded(UINT16 firstfile) nameonly(strcpy(wadfilename, wadfiles[i]->filename)); - if (p + 1 + 4 + strlen(wadfilename) + 16 > p_start + MAXFILENEEDED) + // Look below at the WRITE macros to understand what these numbers mean. + if (p + 1 + 4 + min(strlen(wadfilename) + 1, MAX_WADPATH) + 16 > p_start + MAXFILENEEDED) { // Too many files to send all at once if (netbuffer->packettype == PT_MOREFILESNEEDED) diff --git a/src/doomdef.h b/src/doomdef.h index 4ab40853..24b52e8d 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -252,6 +252,9 @@ extern FILE *logstream; #define PLAYERSMASK (MAXPLAYERS-1) #define MAXPLAYERNAME 21 +// Master Server compatibility ONLY +#define MSCOMPAT_MAXPLAYERS (32) + typedef enum { SKINCOLOR_NONE = 0, diff --git a/src/g_game.c b/src/g_game.c index 10bd76ac..b8a1a3bf 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -6477,10 +6477,10 @@ void G_WriteStanding(UINT8 ranking, char *name, INT32 skinnum, UINT8 color, UINT { char temp[16]; - if (demoinfo_p && (UINT32)(*demoinfo_p) == 0) + if (demoinfo_p && *(UINT32 *)demoinfo_p == 0) { WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - WRITEUINT32(demoinfo_p, demo_p - demobuffer); + *(UINT32 *)demoinfo_p = demo_p - demobuffer; } WRITEUINT8(demo_p, DW_STANDING); @@ -8172,16 +8172,17 @@ boolean G_CheckDemoStatus(void) void G_SaveDemo(void) { - UINT8 *p = demobuffer+16; // checksum position + UINT8 *p = demobuffer+16; // after version + UINT32 length; #ifdef NOMD5 UINT8 i; #endif // Ensure extrainfo pointer is always available, even if no info is present. - if (demoinfo_p && (UINT32)(*demoinfo_p) == 0) + if (demoinfo_p && *(UINT32 *)demoinfo_p == 0) { WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - WRITEUINT32(demoinfo_p, (UINT32)(demo_p - demobuffer)); + *(UINT32 *)demoinfo_p = demo_p - demobuffer; } WRITEUINT8(demo_p, DW_END); // Mark end of demo extra data. @@ -8227,12 +8228,14 @@ void G_SaveDemo(void) sprintf(writepoint, "%s.lmp", demo_slug); } + length = *(UINT32 *)demoinfo_p; + WRITEUINT32(demoinfo_p, length); #ifdef NOMD5 for (i = 0; i < 16; i++, p++) *p = M_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. #else // Make a checksum of everything after the checksum in the file up to the end of the standard data. Extrainfo is freely modifiable. - md5_buffer((char *)p+16, (demobuffer + (UINT32)*demoinfo_p) - (p+16), p); + md5_buffer((char *)p+16, (demobuffer + length) - (p+16), p); #endif diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 63cde0ca..6a08b1c7 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -1319,7 +1319,7 @@ static void HWR_SplitWall(sector_t *sector, wallVert3D *wallVerts, INT32 texnum, // HWR_DrawSkyWalls // Draw walls into the depth buffer so that anything behind is culled properly -static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t bottom, fixed_t top) +static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf) { HWD.pfnSetTexture(NULL); // no texture @@ -1327,9 +1327,6 @@ static void HWR_DrawSkyWall(wallVert3D *wallVerts, FSurfaceInfo *Surf, fixed_t b wallVerts[0].t = wallVerts[1].t = 0; wallVerts[0].s = wallVerts[3].s = 0; wallVerts[2].s = wallVerts[1].s = 0; - // set top/bottom coords - wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(top); // No real way to find the correct height of this - wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(bottom); // worldlow/bottom because it needs to cover up the lower thok barrier wall HWR_ProjectWall(wallVerts, Surf, PF_Invisible|PF_Clip|PF_NoTexture, 255, NULL); // PF_Invisible so it's not drawn into the colour buffer // PF_NoTexture for no texture @@ -1462,6 +1459,111 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) worldlow = gr_backsector->floorheight; #endif + // Sky culling + if (!gr_curline->polyseg) // Don't do it for polyobjects + { + // Sky Ceilings + wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX); + + if (gr_frontsector->ceilingpic == skyflatnum) + { + if (gr_backsector->ceilingpic == skyflatnum) + { + // Both front and back sectors are sky, needs skywall from the frontsector's ceiling, but only if the + // backsector is lower + if ((worldhigh <= worldtop) +#ifdef ESLOPE + && (worldhighslope <= worldtopslope) +#endif + ) + { +#ifdef ESLOPE + wallVerts[0].y = FIXED_TO_FLOAT(worldhigh); + wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope); +#else + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldhigh); +#endif + HWR_DrawSkyWall(wallVerts, &Surf); + } + } + else + { + // Only the frontsector is sky, just draw a skywall from the front ceiling +#ifdef ESLOPE + wallVerts[0].y = FIXED_TO_FLOAT(worldtop); + wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); +#else + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); +#endif + HWR_DrawSkyWall(wallVerts, &Surf); + } + } + else if (gr_backsector->ceilingpic == skyflatnum) + { + // Only the backsector is sky, just draw a skywall from the front ceiling +#ifdef ESLOPE + wallVerts[0].y = FIXED_TO_FLOAT(worldtop); + wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); +#else + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); +#endif + HWR_DrawSkyWall(wallVerts, &Surf); + } + + + // Sky Floors + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); + + if (gr_frontsector->floorpic == skyflatnum) + { + if (gr_backsector->floorpic == skyflatnum) + { + // Both front and back sectors are sky, needs skywall from the backsector's floor, but only if the + // it's higher, also needs to check for bottomtexture as the floors don't usually move down + // when both sides are sky floors + if ((worldlow >= worldbottom) +#ifdef ESLOPE + && (worldlowslope >= worldbottomslope) +#endif + && !(gr_sidedef->bottomtexture)) + { +#ifdef ESLOPE + wallVerts[3].y = FIXED_TO_FLOAT(worldlow); + wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope); +#else + wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldlow); +#endif + + HWR_DrawSkyWall(wallVerts, &Surf); + } + } + else + { + // Only the backsector has sky, just draw a skywall from the back floor +#ifdef ESLOPE + wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); + wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); +#else + wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldbottom); +#endif + + HWR_DrawSkyWall(wallVerts, &Surf); + } + } + else if ((gr_backsector->floorpic == skyflatnum) && !(gr_sidedef->bottomtexture)) + { + // Only the backsector has sky, just draw a skywall from the back floor if there's no bottomtexture +#ifdef ESLOPE + wallVerts[3].y = FIXED_TO_FLOAT(worldlow); + wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope); +#else + wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldlow); +#endif + + HWR_DrawSkyWall(wallVerts, &Surf); + } + } + // hack to allow height changes in outdoor areas // This is what gets rid of the upper textures if there should be sky if (gr_frontsector->ceilingpic == skyflatnum && @@ -1914,85 +2016,6 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) Surf.FlatColor.rgba = 0xffffffff; }*/ } - - // Isn't this just the most lovely mess - if (!gr_curline->polyseg) // Don't do it for polyobjects - { - if (gr_frontsector->ceilingpic == skyflatnum || gr_backsector->ceilingpic == skyflatnum) - { - fixed_t depthwallheight; - - if (!gr_sidedef->toptexture || (gr_frontsector->ceilingpic == skyflatnum && gr_backsector->ceilingpic == skyflatnum)) // when both sectors are sky, the top texture isn't drawn - depthwallheight = gr_frontsector->ceilingheight < gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; - else - depthwallheight = gr_frontsector->ceilingheight > gr_backsector->ceilingheight ? gr_frontsector->ceilingheight : gr_backsector->ceilingheight; - - if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier - { - if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier - { - if (!gr_sidedef->bottomtexture) // Only extend further down if there's no texture - HWR_DrawSkyWall(wallVerts, &Surf, worldbottom < worldlow ? worldbottom : worldlow, INT32_MAX); - else - HWR_DrawSkyWall(wallVerts, &Surf, worldbottom > worldlow ? worldbottom : worldlow, INT32_MAX); - } - // behind sector is not a thok barrier - else if (gr_backsector->ceilingheight <= gr_frontsector->ceilingheight) // behind sector ceiling is lower or equal to current sector - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); - // gr_front/backsector heights need to be used here because of the worldtop being set to worldhigh earlier on - } - else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not - { - if (gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier ceiling height is equal to or greater than current sector ceiling height - || gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier ceiling height is equal to or less than current sector floor height - || gr_backsector->ceilingpic != skyflatnum) // thok barrier is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); - } - else // neither sectors are thok barriers - { - if ((gr_backsector->ceilingheight < gr_frontsector->ceilingheight && !gr_sidedef->toptexture) // no top texture and sector behind is lower - || gr_backsector->ceilingpic != skyflatnum) // behind sector is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, depthwallheight, INT32_MAX); - } - } - // And now for sky floors! - if (gr_frontsector->floorpic == skyflatnum || gr_backsector->floorpic == skyflatnum) - { - fixed_t depthwallheight; - - if (!gr_sidedef->bottomtexture) - depthwallheight = worldbottom > worldlow ? worldbottom : worldlow; - else - depthwallheight = worldbottom < worldlow ? worldbottom : worldlow; - - if (gr_frontsector->ceilingheight-gr_frontsector->floorheight <= 0) // current sector is a thok barrier - { - if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is also a thok barrier - { - if (!gr_sidedef->toptexture) // Only extend up if there's no texture - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop > worldhigh ? worldtop : worldhigh); - else - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldtop < worldhigh ? worldtop : worldhigh); - } - // behind sector is not a thok barrier - else if (gr_backsector->floorheight >= gr_frontsector->floorheight) // behind sector floor is greater or equal to current sector - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); - } - else if (gr_backsector->ceilingheight-gr_backsector->floorheight <= 0) // behind sector is a thok barrier, current sector is not - { - if (gr_backsector->floorheight <= gr_frontsector->floorheight // thok barrier floor height is equal to or less than current sector floor height - || gr_backsector->ceilingheight >= gr_frontsector->ceilingheight // thok barrier floor height is equal to or greater than current sector ceiling height - || gr_backsector->floorpic != skyflatnum) // thok barrier is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); - } - else // neither sectors are thok barriers - { - if ((gr_backsector->floorheight > gr_frontsector->floorheight && !gr_sidedef->bottomtexture) // no bottom texture and sector behind is higher - || gr_backsector->floorpic != skyflatnum) // behind sector is not a sky - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, depthwallheight); - } - } - } } else { @@ -2060,13 +2083,52 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); } } + else + { +#ifdef ESLOPE + //Set textures properly on single sided walls that are sloped + wallVerts[3].y = FIXED_TO_FLOAT(worldtop); + wallVerts[0].y = FIXED_TO_FLOAT(worldbottom); + wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope); + wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope); +#else + // set top/bottom coords + wallVerts[2].y = wallVerts[3].y = FIXED_TO_FLOAT(worldtop); + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldbottom); +#endif + // When there's no midtexture, draw a skywall to prevent rendering behind it + HWR_DrawSkyWall(wallVerts, &Surf); + } + + + // Single sided lines are simple for skywalls, just need to draw from the top or bottom of the sector if there's + // a sky flat if (!gr_curline->polyseg) { if (gr_frontsector->ceilingpic == skyflatnum) // It's a single-sided line with sky for its sector - HWR_DrawSkyWall(wallVerts, &Surf, worldtop, INT32_MAX); + { + wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(INT32_MAX); +#ifdef ESLOPE + wallVerts[0].y = FIXED_TO_FLOAT(worldtop); + wallVerts[1].y = FIXED_TO_FLOAT(worldtopslope); +#else + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(worldtop); +#endif + HWR_DrawSkyWall(wallVerts, &Surf); + } if (gr_frontsector->floorpic == skyflatnum) - HWR_DrawSkyWall(wallVerts, &Surf, INT32_MIN, worldbottom); + { +#ifdef ESLOPE + wallVerts[3].y = FIXED_TO_FLOAT(worldbottom); + wallVerts[2].y = FIXED_TO_FLOAT(worldbottomslope); +#else + wallVerts[3].y = wallVerts[2].y = FIXED_TO_FLOAT(worldbottom); +#endif + wallVerts[0].y = wallVerts[1].y = FIXED_TO_FLOAT(INT32_MIN); + + HWR_DrawSkyWall(wallVerts, &Surf); + } } } @@ -2381,7 +2443,7 @@ static void HWR_StoreWallRange(double startfrac, double endfrac) // e6y: Check whether the player can look beyond this line // #ifdef NEWCLIP -boolean checkforemptylines = true; +static boolean checkforemptylines = true; // Don't modify anything here, just check // Kalaron: Modified for sloped linedefs static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacksector) @@ -2421,62 +2483,47 @@ static boolean CheckClip(seg_t * seg, sector_t * afrontsector, sector_t * abacks backc1 = backc2 = abacksector->ceilingheight; } - // now check for closed sectors! - if (backc1 <= frontf1 && backc2 <= frontf2) + if (viewsector != abacksector && viewsector != afrontsector) { - checkforemptylines = false; - if (!seg->sidedef->toptexture) - return false; + boolean mydoorclosed = false; // My door? Closed!? (doorclosed is actually otherwise unused in openGL) - if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) - return false; - - return true; - } - - if (backf1 >= frontc1 && backf2 >= frontc2) - { - checkforemptylines = false; - if (!seg->sidedef->bottomtexture) - return false; - - // properly render skies (consider door "open" if both floors are sky): - if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) - return false; - - return true; - } - - if (backc1 <= backf1 && backc2 <= backf2) - { - checkforemptylines = false; - // preserve a kind of transparent door/lift special effect: - if (backc1 < frontc1 || backc2 < frontc2) - { - if (!seg->sidedef->toptexture) - return false; - } - if (backf1 > frontf1 || backf2 > frontf2) - { - if (!seg->sidedef->bottomtexture) - return false; - } - if (abacksector->ceilingpic == skyflatnum && afrontsector->ceilingpic == skyflatnum) - return false; - - if (abacksector->floorpic == skyflatnum && afrontsector->floorpic == skyflatnum) - return false; - - return true; - } - - if (backc1 != frontc1 || backc2 != frontc2 - || backf1 != frontf1 || backf2 != frontf2) + // If the sector behind the line blocks all kinds of view past it + // (back ceiling is lower than close floor, or back floor is higher than close ceiling) + if ((backc1 <= frontf1 && backc2 <= frontf2) + || (backf1 >= frontc1 && backf2 >= frontc2)) { checkforemptylines = false; - return false; + return true; } + // The door is closed if: + // backsector is 0 height or less and + // back ceiling is higher than close ceiling or we need to render a top texture and + // back floor is lower than close floor or we need to render a bottom texture and + // neither front or back sectors are using the sky ceiling + mydoorclosed = (backc1 <= backf1 && backc2 <= backf2 + && ((backc1 >= frontc1 && backc2 >= frontc2) || seg->sidedef->toptexture) + && ((backf1 <= frontf1 && backf2 >= frontf2) || seg->sidedef->bottomtexture) + && (abacksector->ceilingpic != skyflatnum || afrontsector->ceilingpic != skyflatnum)); + + if (mydoorclosed) + { + checkforemptylines = false; + return true; + } + } + + // Window. + // We know it's a window when the above isn't true and the back and front sectors don't match + if (backc1 != frontc1 || backc2 != frontc2 + || backf1 != frontf1 || backf2 != frontf2) + { + checkforemptylines = false; + return false; + } + + // In this case we just need to check whether there is actually a need to render any lines, so checkforempty lines + // stays true return false; } #else @@ -5470,7 +5517,7 @@ static void HWR_AddSprites(sector_t *sec) } #ifdef HWPRECIP - // Someone seriously wants infinite draw distance for precipitation? + // No to infinite precipitation draw distance. if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS)) { for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) @@ -5486,13 +5533,6 @@ static void HWR_AddSprites(sector_t *sec) HWR_ProjectPrecipitationSprite(precipthing); } } - else - { - // Draw everything in sector, no checks - for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext) - if (!(precipthing->precipflags & PCF_INVISIBLE)) - HWR_ProjectPrecipitationSprite(precipthing); - } #endif } diff --git a/src/i_tcp.c b/src/i_tcp.c index fb0e5852..f58aa22b 100644 --- a/src/i_tcp.c +++ b/src/i_tcp.c @@ -1311,7 +1311,7 @@ static SINT8 SOCK_NetMakeNodewPort(const char *address, const char *port) int gaie; if (!port || !port[0]) - port = port_name; + port = DEFAULTPORT; DEBFILE(va("Creating new node: %s@%s\n", address, port)); diff --git a/src/m_menu.c b/src/m_menu.c index 9b5e98e4..97b1ce9b 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -522,7 +522,7 @@ static menuitem_t PlaybackMenu[] = {IT_CALL | IT_STRING, "M_PREW", "Rewind", M_PlaybackRewind, 20}, {IT_CALL | IT_STRING, "M_PPAUSE", "Pause", M_PlaybackPause, 36}, - {IT_CALL | IT_STRING, "M_PFFWD", "Fast-Foward", M_PlaybackFastForward, 52}, + {IT_CALL | IT_STRING, "M_PFFWD", "Fast-Forward", M_PlaybackFastForward, 52}, {IT_CALL | IT_STRING, "M_PSTEPB", "Backup Frame", M_PlaybackRewind, 20}, {IT_CALL | IT_STRING, "M_PRESUM", "Resume", M_PlaybackPause, 36}, {IT_CALL | IT_STRING, "M_PFADV", "Advance Frame", M_PlaybackAdvance, 52}, @@ -8432,7 +8432,11 @@ static void M_ConnectMenu(INT32 choice) // first page of servers serverlistpage = 0; if (ms_RoomId < 0) + { M_RoomMenu(0); // Select a room instead of staring at an empty list + // This prevents us from returning to the modified game alert. + currentMenu->prevMenu = &MP_MainDef; + } else M_SetupNextMenu(&MP_ConnectDef); itemOn = 0; diff --git a/src/mserv.c b/src/mserv.c index 29aa99fa..c7344b16 100644 --- a/src/mserv.c +++ b/src/mserv.c @@ -661,19 +661,11 @@ FUNCMATH static const char *int2str(INT32 n) #ifndef NONET static INT32 ConnectionFailed(void) { - time(&MSLastPing); con_state = MSCS_FAILED; CONS_Alert(CONS_ERROR, M_GetText("Connection to Master Server failed\n")); CloseConnection(); return MS_CONNECT_ERROR; } - -static INT32 ConnectionFailedwerrno(int no) -{ - CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error: %s\n"), - strerror(no)); - return ConnectionFailed(); -} #endif /** Tries to register the local game server on the master server. @@ -690,43 +682,57 @@ static INT32 AddToMasterServer(boolean firstadd) msg_server_t *info = (msg_server_t *)msg.buffer; INT32 room = -1; fd_set tset; + time_t timestamp = time(NULL); UINT32 signature, tmp; const char *insname; - if (socket_fd == (SOCKET_TYPE)ERRSOCKET)/* Woah, our socket was closed! */ - { - if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) - return ConnectionFailedwerrno(errno); - } - M_Memcpy(&tset, &wset, sizeof (tset)); res = select(255, NULL, &tset, NULL, &select_timeout); - if (res == ERRSOCKET) - return ConnectionFailedwerrno(errno); - if (res == 0)/* nothing selected */ + if (res != ERRSOCKET && !res) { - /* - Timeout next call because SendPingToMasterServer - (our calling function) already calls this once - every two minutes. - */ - if (retry++ == 1) + if (retry++ > 30) // an about 30 second timeout { retry = 0; CONS_Alert(CONS_ERROR, M_GetText("Master Server timed out\n")); + MSLastPing = timestamp; return ConnectionFailed(); } return MS_CONNECT_ERROR; } retry = 0; + /* + Somehow we can still select our old socket despite it being closed(?). + Atleast, that's what I THINK is happening. Anyway, we have to check that we + haven't open a socket, and actually open it! + */ + /*if (res == ERRSOCKET)*//* wtf? no! */ + if (socket_fd == (SOCKET_TYPE)ERRSOCKET) + { + if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0)) + { + CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error #%u: %s\n"), errno, strerror(errno)); + MSLastPing = timestamp; + return ConnectionFailed(); + } + } // so, the socket is writable, but what does that mean, that the connection is // ok, or bad... let see that! j = (socklen_t)sizeof (i); - if (getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, (char *)&i, &j) == ERRSOCKET) - return ConnectionFailedwerrno(errno); + getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, (char *)&i, &j); + /* + This is also wrong. If getsockopt fails, i doesn't have to be set. Plus, if + it is set (which it appearantly is on linux), we check errno anyway. And in + the case that i is returned as normal, we don't even report the correct + value! So we accomplish NOTHING, except returning due to dumb luck. + If you care, fix this--I don't. -James (R.) + */ if (i) // it was bad - return ConnectionFailedwerrno(i); + { + CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error #%u: %s\n"), errno, strerror(errno)); + MSLastPing = timestamp; + return ConnectionFailed(); + } #ifdef PARANOIA if (ms_RoomId <= 0) @@ -759,12 +765,15 @@ static INT32 AddToMasterServer(boolean firstadd) msg.length = (UINT32)sizeof (msg_server_t); msg.room = 0; if (MS_Write(&msg) < 0) + { + MSLastPing = timestamp; return ConnectionFailed(); + } if(con_state != MSCS_REGISTERED) CONS_Printf(M_GetText("Master Server update successful.\n")); - time(&MSLastPing); + MSLastPing = timestamp; con_state = MSCS_REGISTERED; CloseConnection(); #endif