// File: /workspace/github_c_makefile_star2_O0/schroeder-lvb[P]sissm/src/pirebooter.c
// Function: pirebooterPeriodicCB
int pirebooterPeriodicCB( char *strIn )
{
    static int skipTime = 0;
    static int queueDailyReboot = 0;
    char *timeNowHuman;
    unsigned long lastValidTimeListPlayers;

    // if currently in IDLE
    //
    if ( 0 == apiPlayersGetCount()) {

	// if this is the first-idle detected, mark the time
	//
        if ( 0L == pirebooterConfig.timeFirstIdle ) {
	     pirebooterConfig.timeFirstIdle = apiTimeGet();
	}

	// if this is not the first idle, check range if reboot is required
	//
	else {
            if ( (pirebooterConfig.timeFirstIdle + pirebooterConfig.rebootIdleSec ) < apiTimeGet() ) {
                pirebooterConfig.timeLastReboot = apiTimeGet();
                pirebooterConfig.timeFirstIdle  = 0L;
                pirebooterConfig.timeLastProgress = apiTimeGet();
                logPrintf( LOG_LEVEL_INFO, "pirebooter", "Reboot due to IDLE timer" );
                apiServerRestart( "Idle>Limit Reboot" );     // since the server is empty, reboot right away
	    }
	}
    }

    // if currently active then invalidate the first-idle time marker
    // 
    else {
        pirebooterConfig.timeFirstIdle = 0L;
    }

    // Now check the RCON loopback interface, detect 'dead' server
    // 
    lastValidTimeListPlayers = apiGetLastRosterTime();
    if ( lastValidTimeListPlayers != 0L ) {     
        if ( (apiTimeGet() - lastValidTimeListPlayers) >  pirebooterConfig.rebootDeadSec ) {
            pirebooterConfig.timeLastReboot   = apiTimeGet();
            pirebooterConfig.timeFirstIdle    = 0L;
            pirebooterConfig.timeLastProgress = apiTimeGet();
            logPrintf( LOG_LEVEL_INFO, "pirebooter", "Reboot due to DEAD timer" );
	    apiServerRestart( "Dead Detect Reboot" );
        }
    }

    // Check for "hung" server - RCON working, players 95% stuck, phantom players online
    //
    if ( (apiTimeGet() - pirebooterConfig.timeLastProgress) > pirebooterConfig.rebootHungSec ) {
        pirebooterConfig.timeLastReboot   = apiTimeGet();
        pirebooterConfig.timeFirstIdle    = 0L;
        pirebooterConfig.timeLastProgress = apiTimeGet();
        logPrintf( LOG_LEVEL_INFO, "pirebooter", "Reboot due to HUNG timer" );
        apiServerRestart( "Hung Detect Reboot" );
    }

    // Log some status for debug and monitoring 
    // 
    if ( (++skipTime) > pirebooterConfig.logUpdateSec ) {
	skipTime = 0;
        if ( 0 == pirebooterConfig.timeFirstIdle ) {
            logPrintf( LOG_LEVEL_INFO, "pirebooter", "nPlayers %d; Reboot timers: idle n/a, busy %ld, dead %ld, hung %ld", 
                apiPlayersGetCount(),
                apiTimeGet() - pirebooterConfig.timeLastReboot,
                apiTimeGet() - apiGetLastRosterTime(),
                apiTimeGet() - pirebooterConfig.timeLastProgress );
	}
	else {
            logPrintf( LOG_LEVEL_INFO, "pirebooter", "nPlayers %d; Reboot timers: idle %ld, busy %ld, dead %ld, hung %ld", 
                apiPlayersGetCount(),
                apiTimeGet() - pirebooterConfig.timeFirstIdle, 
		apiTimeGet() - pirebooterConfig.timeLastReboot, 
                apiTimeGet() - apiGetLastRosterTime(),
                apiTimeGet() - pirebooterConfig.timeLastProgress );
	}
    }

    // "Abrupt" and mdandatory daily reboot - when enabled this reboots the server
    // daily at exectly specified time, without warning, mid-game.
    //
    timeNowHuman = apiTimeGetHuman( 0L );
    if ( 0 != strlen( pirebooterConfig.rebootDailyHM )) {    // if this feature is enabled...
        // check if 'triggered' for reboot
        // 
        if ( NULL != strstr( timeNowHuman, pirebooterConfig.rebootDailyHM )) {
            // wait for the next minute to actually do the reboot
            //
            queueDailyReboot++;
            if (( queueDailyReboot == 1 ) || ( queueDailyReboot == 30 )) {
                logPrintf( LOG_LEVEL_INFO, "pirebooter", "Daily Reboot is queued" );
                apiSay( pirebooterConfig.rebootDaily );
            }
        }
    }
    if ( 0 != queueDailyReboot ) {
        if ( NULL == strstr( timeNowHuman, pirebooterConfig.rebootDailyHM )) {
            queueDailyReboot = 0;
            pirebooterConfig.timeLastReboot   = apiTimeGet();         // when last rebooted
            pirebooterConfig.timeLastProgress = apiTimeGet();
            pirebooterConfig.timeFirstIdle    = 0L;
            logPrintf( LOG_LEVEL_INFO, "pirebooter", "Reboot due to DAILY timer" );
            apiServerRestart( "Daily Reboot" );
        }
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
callq 0x17fe0
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0xf919
xorl %eax, %eax
cmpq 0x7401f(%rip), %rax     # 0x838b8
jne 0xf8a9
callq 0x150c0
movq %rax, 0x74011(%rip)     # 0x838b8
jmp 0xf917
movq 0x74008(%rip), %rax     # 0x838b8
addq 0x73bd1(%rip), %rax     # 0x83488
movq %rax, -0x20(%rbp)
callq 0x150c0
movq %rax, %rcx
movq -0x20(%rbp), %rax
cmpq %rcx, %rax
jae 0xf915
callq 0x150c0
movq %rax, 0x73fd8(%rip)     # 0x838b0
movq $0x0, 0x73fd5(%rip) # 0x838b8
callq 0x150c0
movq %rax, 0x73fd1(%rip)     # 0x838c0
movl $0x2, %edi
leaq 0x1539e(%rip), %rsi     # 0x24c99
leaq 0x153ec(%rip), %rdx     # 0x24cee
movb $0x0, %al
callq 0x21bf0
leaq 0x153f7(%rip), %rdi     # 0x24d07
callq 0x17510
jmp 0xf917
jmp 0xf924
movq $0x0, 0x73f94(%rip) # 0x838b8
callq 0x14ca0
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0xf991
callq 0x150c0
subq -0x18(%rbp), %rax
cmpq 0x73b54(%rip), %rax     # 0x83498
jbe 0xf98f
callq 0x150c0
movq %rax, 0x73f5e(%rip)     # 0x838b0
movq $0x0, 0x73f5b(%rip) # 0x838b8
callq 0x150c0
movq %rax, 0x73f57(%rip)     # 0x838c0
movl $0x2, %edi
leaq 0x15324(%rip), %rsi     # 0x24c99
leaq 0x1539d(%rip), %rdx     # 0x24d19
movb $0x0, %al
callq 0x21bf0
leaq 0x153a8(%rip), %rdi     # 0x24d32
callq 0x17510
jmp 0xf991
callq 0x150c0
subq 0x73f23(%rip), %rax     # 0x838c0
cmpq 0x73afc(%rip), %rax     # 0x834a0
jbe 0xf9ef
callq 0x150c0
movq %rax, 0x73efe(%rip)     # 0x838b0
movq $0x0, 0x73efb(%rip) # 0x838b8
callq 0x150c0
movq %rax, 0x73ef7(%rip)     # 0x838c0
movl $0x2, %edi
leaq 0x152c4(%rip), %rsi     # 0x24c99
leaq 0x15369(%rip), %rdx     # 0x24d45
movb $0x0, %al
callq 0x21bf0
leaq 0x15374(%rip), %rdi     # 0x24d5e
callq 0x17510
movl 0x746db(%rip), %eax     # 0x840d0
addl $0x1, %eax
movl %eax, 0x746d2(%rip)     # 0x840d0
cmpl 0x73a80(%rip), %eax     # 0x83484
jle 0xfb11
movl $0x0, 0x746bc(%rip)     # 0x840d0
xorl %eax, %eax
cmpq 0x73e9b(%rip), %rax     # 0x838b8
jne 0xfa8d
callq 0x17fe0
movl %eax, -0x34(%rbp)
callq 0x150c0
subq 0x73e7d(%rip), %rax     # 0x838b0
movq %rax, -0x30(%rbp)
callq 0x150c0
movq %rax, -0x40(%rbp)
callq 0x14ca0
movq %rax, %rcx
movq -0x40(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x28(%rbp)
callq 0x150c0
movl -0x34(%rbp), %ecx
movq -0x30(%rbp), %r8
movq -0x28(%rbp), %r9
subq 0x73e56(%rip), %rax     # 0x838c0
movl $0x2, %edi
leaq 0x15223(%rip), %rsi     # 0x24c99
leaq 0x152f4(%rip), %rdx     # 0x24d71
movq %rax, (%rsp)
movb $0x0, %al
callq 0x21bf0
jmp 0xfb0f
callq 0x17fe0
movl %eax, -0x5c(%rbp)
callq 0x150c0
subq 0x73e17(%rip), %rax     # 0x838b8
movq %rax, -0x58(%rbp)
callq 0x150c0
subq 0x73dff(%rip), %rax     # 0x838b0
movq %rax, -0x50(%rbp)
callq 0x150c0
movq %rax, -0x68(%rbp)
callq 0x14ca0
movq %rax, %rcx
movq -0x68(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x48(%rbp)
callq 0x150c0
movl -0x5c(%rbp), %ecx
movq -0x58(%rbp), %r8
movq -0x50(%rbp), %r9
movq -0x48(%rbp), %r10
subq 0x73dd4(%rip), %rax     # 0x838c0
movl $0x2, %edi
leaq 0x151a1(%rip), %rsi     # 0x24c99
leaq 0x152b5(%rip), %rdx     # 0x24db4
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x21bf0
jmp 0xfb11
xorl %eax, %eax
movl %eax, %edi
callq 0x17620
movq %rax, -0x10(%rbp)
leaq 0x73983(%rip), %rdi     # 0x834a8
callq 0x8110
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
je 0xfba6
movq -0x10(%rbp), %rdi
leaq 0x73941(%rip), %rsi     # 0x83480
addq $0x28, %rsi
callq 0x8390
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
je 0xfba4
movl 0x7457c(%rip), %eax     # 0x840d4
addl $0x1, %eax
movl %eax, 0x74573(%rip)     # 0x840d4
cmpl $0x1, 0x7456c(%rip)     # 0x840d4
je 0xfb73
cmpl $0x1e, 0x74563(%rip)    # 0x840d4
jne 0xfba2
movl $0x2, %edi
leaq 0x1511a(%rip), %rsi     # 0x24c99
leaq 0x15271(%rip), %rdx     # 0x24df7
movb $0x0, %al
callq 0x21bf0
leaq 0x738ec(%rip), %rdi     # 0x83480
addq $0x848, %rdi            # imm = 0x848
movb $0x0, %al
callq 0x178d0
jmp 0xfba4
jmp 0xfba6
xorl %eax, %eax
cmpl 0x74526(%rip), %eax     # 0x840d4
je 0xfc23
movq -0x10(%rbp), %rdi
leaq 0x738c5(%rip), %rsi     # 0x83480
addq $0x28, %rsi
callq 0x8390
movq %rax, %rcx
xorl %eax, %eax
cmpq %rcx, %rax
jne 0xfc21
movl $0x0, 0x744fc(%rip)     # 0x840d4
callq 0x150c0
movq %rax, 0x73ccc(%rip)     # 0x838b0
callq 0x150c0
movq %rax, 0x73cd0(%rip)     # 0x838c0
movq $0x0, 0x73cbd(%rip) # 0x838b8
movl $0x2, %edi
leaq 0x15092(%rip), %rsi     # 0x24c99
leaq 0x15200(%rip), %rdx     # 0x24e0e
movb $0x0, %al
callq 0x21bf0
leaq 0x1520c(%rip), %rdi     # 0x24e28
callq 0x17510
jmp 0xfc23
xorl %eax, %eax
addq $0x80, %rsp
popq %rbp
retq
nop