fbef0102 / L4D1_2-Plugins

L4D1/2 help server to record, make server more fun, and more useful plugins for adm.
GNU General Public License v3.0
156 stars 67 forks source link

linux_auto_restart plugin bug fixes and some optimization. #51

Closed Hatsune-Imagine closed 8 months ago

Hatsune-Imagine commented 8 months ago
  1. 新增 sm_crash 指令,管理员可在伺服器控制台中输入 sm_crash 或在游戏聊天框中输入 /crash!crash 来使得伺服器强制崩溃。
public void OnPluginStart()
{
    RegAdminCmd("sm_crash", Cmd_RestartServer, ADMFLAG_ROOT, "sm_crash - manually force the server to crash");

    ......
}

Action Cmd_RestartServer(int client, int args)
{
    SetConVarInt(FindConVar("sb_all_bot_game"), 1);

    LogMessage("Manually restarting server...");
    PrintToServer("Manually restarting server...");
    PrintToChatAll("Manually restarting server...");

    UnloadAccelerator();
    CreateTimer(5.0, Timer_RestartServer);

    return Plugin_Continue;
}

  1. 修复了在部分情况下,伺服器无人后,仍然不会触发自动奔溃重启的bug。可能是由于在切换章节时所有玩家退出,未成功触发 player_disconnect 事件导致。且在 OnMapStart() 方法中未实时获取当前是否有玩家在伺服器内,且方法中的判断逻辑有部分漏洞。

原本逻辑如下:

public void OnMapStart()
{    
    if(g_bNoOneInServer || (!g_bFirstMap && g_bCmdMap))
    {
        g_hConVarHibernate.SetBool(false);
        delete COLD_DOWN_Timer;
        COLD_DOWN_Timer = CreateTimer(20.0, COLD_DOWN);
    }

    g_bFirstMap = false;
    g_bCmdMap = false;
}

在判断 if(g_bNoOneInServer || (!g_bFirstMap && g_bCmdMap)) 中,可能因为玩家在伺服器切换章节时退出导致未成功触发 player_disconnect 事件,从而导致 g_bNoOneInServer 变量值仍然为false。且此时 g_bFirstMap 变量值一定为false, g_bCmdMap 变量值一定也为false,从而导致不触发自动奔溃重启的逻辑。

改进后的逻辑如下:

public void OnMapStart()
{
    if(g_bCmdMap || (!CheckPlayerInGame(0) && !g_bFirstMap))
    {
        SetConVarInt(FindConVar("sb_all_bot_game"), 1);
        delete COLD_DOWN_Timer;
        COLD_DOWN_Timer = CreateTimer(20.0, COLD_DOWN);
    }

    g_bFirstMap = false;
    g_bCmdMap = false;
}

去除了 g_bNoOneInServer 变量,使用 CheckPlayerInGame(0) 方法实时判断当前是否有玩家。且判断逻辑改为 当伺服器触发过map指令 或 (此时无人在伺服器中 且 伺服器不是刚刚启动的) ,此时的逻辑则无漏洞。


  1. 优化了部分代码,去除了部分无用方法。

将设置 sv_hibernate_when_empty 为0的逻辑去除,改为 设置 sb_all_bot_game 为1的逻辑。经过测试,当伺服器 sb_all_bot_game 为0时,即使设置 sv_hibernate_when_empty 为0,伺服器无人时也会处于休眠状态(status中可看到hibernating)。此时,如果在伺服器控制台中输入 sm_crash 命令,则不会进行处理,输入后没有任何事情发生,当有玩家加入伺服器后,伺服器这时才突然执行了奔溃重启。

本次修复了此情况,当达成自动奔溃重启条件或手动输入 sm_crash 时,将伺服器的 sb_all_bot_game 设置为1。

fbef0102 commented 8 months ago

第三項 我強制將sv_hibernate_when_empty改成0 所以不是沒有作用 你可以試試看

g_hConVarHibernate = FindConVar("sv_hibernate_when_empty");
g_hConVarHibernate.AddChangeHook(ConVarChanged_Hibernate);

void ConVarChanged_Hibernate(ConVar hCvar, const char[] sOldVal, const char[] sNewVal)
{
    g_hConVarHibernate.SetBool(false);
}
fbef0102 commented 8 months ago

第一項可以加入 第二項我會再做修改 因為有的服會開服後會再換圖刷新一次

Hatsune-Imagine commented 8 months ago

嗯嗯不好意思昨晚出门了没有及时回复,关于第三项,今天我试了一下最新的2.8版,是正常的,没有问题。之前在您的2.7版本基础上我只加上了 sm_crash 的命令,其他的代码都没有任何改动,但是服务器启动后,这时在控制台输入 sm_crash 后没有任何反应(当时看了伺服器是 hibernating 状态),当有人加入伺服器后这时才突然执行了奔溃重启。

当时我在 server.cfg 中加上了 sm_cvar sb_all_bot_game 1 之后就正常了,伺服器会保持 not hibernating 状态,在控制台执行 sm_crash 也能正常奔溃重启了。

Hatsune-Imagine commented 8 months ago

是的,第二项的话如果 “開服後會再換圖刷新一次” 这种情况的话,我这样的逻辑确实会有问题,会无限重启的,您现在的2.8版本应该对于这种情况能正常处理。