Z Voting: Kick handling improvements

- If a player being voted against leaves before it finishes, then properly activate their penalty.
    - This is handled with a special case for MVT_KICK (let's not even attempt to SendKick(self) during Got_Kick :p), but any possible future vote types that use a victim will simply call K_MidVoteSuccess.
- Actually define behavior for KICK_MSG_VOTE_KICK.
- Default kicktime is now 20 minutes instead of 10.
- Read custom reasons before possibly overriding msg type. Prevents a rare invalid read pointer.
This commit is contained in:
Sally Coolatta 2023-04-20 21:11:25 -04:00
parent 49b1ecddff
commit 68916559aa
3 changed files with 49 additions and 8 deletions

View file

@ -221,7 +221,7 @@ consvar_t cv_playbackspeed = CVAR_INIT ("playbackspeed", "1", 0, playbackspeed_c
consvar_t cv_httpsource = CVAR_INIT ("http_source", "", CV_SAVE, NULL, NULL);
consvar_t cv_kicktime = CVAR_INIT ("kicktime", "10", CV_SAVE, CV_Unsigned, NULL);
consvar_t cv_kicktime = CVAR_INIT ("kicktime", "20", CV_SAVE, CV_Unsigned, NULL);
// Generate a message for an authenticating client to sign, with some guarantees about who we are.
void GenerateChallenge(uint8_t *buf)
@ -3199,6 +3199,11 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
return;
}
if (msg == KICK_MSG_CUSTOM_BAN || msg == KICK_MSG_CUSTOM_KICK)
{
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
}
// Is playernum authorized to make this kick?
if (playernum != serverplayer && !IsPlayerAdmin(playernum)
/*&& !(playernode[playernum] != UINT8_MAX && playerpernode[playernode[playernum]] == 2
@ -3243,9 +3248,20 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
msg = KICK_MSG_CON_FAIL;
}
if (msg == KICK_MSG_CUSTOM_BAN || msg == KICK_MSG_CUSTOM_KICK)
if (g_midVote.active == true && g_midVote.victim == &players[pnum])
{
READSTRINGN(*p, reason, MAX_REASONLENGTH+1);
if (g_midVote.type == MVT_KICK)
{
// Running the callback here would mean a very dumb infinite loop.
// We'll manually handle this here by changing the msg type.
msg = KICK_MSG_VOTE_KICK;
K_MidVoteFinalize(FRACUNIT); // Vote succeeded, so the delay is normal.
}
else
{
// It should be safe to run the vote callback directly.
K_MidVoteSuccess();
}
}
//CONS_Printf("\x82%s ", player_names[pnum]);
@ -3255,7 +3271,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
// to keep it all in one place.
if (server)
{
if (msg == KICK_MSG_KICKED || msg == KICK_MSG_CUSTOM_KICK)
if (msg == KICK_MSG_KICKED || msg == KICK_MSG_VOTE_KICK || msg == KICK_MSG_CUSTOM_KICK)
{
// Kick as a temporary ban.
banMinutes = cv_kicktime.value;
@ -3299,6 +3315,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
HU_AddChatText(va("\x82*%s has been kicked (No reason given)", player_names[pnum]), false);
kickreason = KR_KICK;
break;
case KICK_MSG_VOTE_KICK:
HU_AddChatText(va("\x82*%s has been kicked (Popular demand)", player_names[pnum]), false);
kickreason = KR_KICK;
break;
case KICK_MSG_PING_HIGH:
HU_AddChatText(va("\x82*%s left the game (Broke delay limit)", player_names[pnum]), false);
kickreason = KR_PINGLIMIT;
@ -3406,6 +3426,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
M_StartMessage(va(M_GetText("You have been banned\n(%s)\nPress (B)\n"), reason), NULL, MM_NOTHING);
else if (msg == KICK_MSG_SIGFAIL)
M_StartMessage(M_GetText("Server closed connection\n(Invalid signature)\nPress (B)\n"), NULL, MM_NOTHING);
else if (msg == KICK_MSG_VOTE_KICK)
M_StartMessage(M_GetText("You have been kicked by popular demand\n\nPress (B)\n"), NULL, MM_NOTHING);
else
M_StartMessage(M_GetText("You have been kicked by the server\n\nPress (B)\n"), NULL, MM_NOTHING);
}

View file

@ -612,6 +612,17 @@ void K_InitNewMidVote(player_t *caller, midVoteType_e type, INT32 variable, play
}
}
/*--------------------------------------------------
void K_MidVoteFinalize(fixed_t delayMul)
See header file for description.
--------------------------------------------------*/
void K_MidVoteFinalize(fixed_t delayMul)
{
K_ResetMidVote();
g_midVote.delay = FixedMul(cv_zvote_delay.value * TICRATE, delayMul);
}
/*--------------------------------------------------
void K_MidVoteSuccess(void)
@ -624,8 +635,7 @@ void K_MidVoteSuccess(void)
g_midVoteTypeDefs[ g_midVote.type ].callback();
}
K_ResetMidVote();
g_midVote.delay = cv_zvote_delay.value * TICRATE; // Vote succeeded, so the delay is normal.
K_MidVoteFinalize(FRACUNIT); // Vote succeeded, so the delay is normal.
}
/*--------------------------------------------------
@ -635,8 +645,7 @@ void K_MidVoteSuccess(void)
--------------------------------------------------*/
void K_MidVoteFailure(void)
{
K_ResetMidVote();
g_midVote.delay = (cv_zvote_delay.value * 2) * TICRATE; // Vote failed, so the delay is longer.
K_MidVoteFinalize(2*FRACUNIT); // Vote failed, so the delay is longer.
}
/*--------------------------------------------------

View file

@ -211,6 +211,16 @@ boolean K_AllowNewMidVote(player_t *caller, midVoteType_e type, INT32 variable,
void K_InitNewMidVote(player_t *caller, midVoteType_e type, INT32 variable, player_t *victim);
/*--------------------------------------------------
void K_MidVoteFinalize(fixed_t delayMul);
Ran when a vote is totally done, and we need to
reset the struct and set the delay timer.
--------------------------------------------------*/
void K_MidVoteFinalize(fixed_t delayMul);
/*--------------------------------------------------
void K_MidVoteSuccess(void);