// File: /workspace/github_c_makefile_star2_O3/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 %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
callq 0x13853
testl %eax, %eax
je 0xdc0a
movq $0x0, 0x6de12(%rip) # 0x7b8b8
callq 0x114ba
testq %rax, %rax
je 0xdb0d
movq %rax, %rbx
callq 0x117c0
subq %rbx, %rax
cmpq 0x6d9d6(%rip), %rax     # 0x7b498
jbe 0xdb0d
callq 0x117c0
movq %rax, 0x6dde0(%rip)     # 0x7b8b0
movq $0x0, 0x6dddd(%rip) # 0x7b8b8
callq 0x117c0
movq %rax, 0x6ddd9(%rip)     # 0x7b8c0
leaq 0xf17b(%rip), %rsi      # 0x1cc69
leaq 0xf1f4(%rip), %rdx      # 0x1cce9
movl $0x2, %edi
xorl %eax, %eax
callq 0x1a3e3
leaq 0xf1fa(%rip), %rdi      # 0x1cd02
callq 0x13062
callq 0x117c0
subq 0x6dda7(%rip), %rax     # 0x7b8c0
cmpq 0x6d980(%rip), %rax     # 0x7b4a0
jbe 0xdb6b
callq 0x117c0
movq %rax, 0x6dd82(%rip)     # 0x7b8b0
movq $0x0, 0x6dd7f(%rip) # 0x7b8b8
callq 0x117c0
movq %rax, 0x6dd7b(%rip)     # 0x7b8c0
leaq 0xf11d(%rip), %rsi      # 0x1cc69
leaq 0xf1c2(%rip), %rdx      # 0x1cd15
movl $0x2, %edi
xorl %eax, %eax
callq 0x1a3e3
leaq 0xf1c8(%rip), %rdi      # 0x1cd2e
callq 0x13062
movl 0x6e55f(%rip), %eax     # 0x7c0d0
leal 0x1(%rax), %ecx
movl %ecx, 0x6e556(%rip)     # 0x7c0d0
cmpl 0x6d904(%rip), %eax     # 0x7b484
jl 0xdccf
movl $0x0, 0x6e540(%rip)     # 0x7c0d0
movq 0x6dd21(%rip), %r15     # 0x7b8b8
callq 0x13853
movl %eax, %ebx
callq 0x117c0
movq %rax, %r14
testq %r15, %r15
je 0xdc7d
subq 0x6dd02(%rip), %r14     # 0x7b8b8
callq 0x117c0
movq %rax, %r15
subq 0x6dceb(%rip), %r15     # 0x7b8b0
callq 0x117c0
movq %rax, %r12
callq 0x114ba
subq %rax, %r12
callq 0x117c0
movq %rax, %r10
subq 0x6dcdc(%rip), %r10     # 0x7b8c0
leaq 0xf07e(%rip), %rsi      # 0x1cc69
leaq 0xf192(%rip), %rdx      # 0x1cd84
movl $0x2, %edi
movl %ebx, %ecx
movq %r14, %r8
movq %r15, %r9
xorl %eax, %eax
pushq %r10
pushq %r12
jmp 0xdcc6
movq 0x6dca7(%rip), %rbx     # 0x7b8b8
testq %rbx, %rbx
je 0xddbe
addq 0x6d867(%rip), %rbx     # 0x7b488
callq 0x117c0
cmpq %rax, %rbx
jae 0xdaa6
callq 0x117c0
movq %rax, 0x6dc75(%rip)     # 0x7b8b0
movq $0x0, 0x6dc72(%rip) # 0x7b8b8
callq 0x117c0
movq %rax, 0x6dc6e(%rip)     # 0x7b8c0
leaq 0xf010(%rip), %rsi      # 0x1cc69
leaq 0xf05e(%rip), %rdx      # 0x1ccbe
movl $0x2, %edi
xorl %eax, %eax
callq 0x1a3e3
leaq 0xf064(%rip), %rdi      # 0x1ccd7
callq 0x13062
jmp 0xdaa6
subq 0x6dc2c(%rip), %r14     # 0x7b8b0
callq 0x117c0
movq %rax, %r15
callq 0x114ba
subq %rax, %r15
callq 0x117c0
movq %rax, %r10
subq 0x6dc1d(%rip), %r10     # 0x7b8c0
subq $0x8, %rsp
leaq 0xefbb(%rip), %rsi      # 0x1cc69
leaq 0xf08c(%rip), %rdx      # 0x1cd41
movl $0x2, %edi
movl %ebx, %ecx
movq %r14, %r8
movq %r15, %r9
xorl %eax, %eax
pushq %r10
callq 0x1a3e3
addq $0x10, %rsp
xorl %edi, %edi
callq 0x13156
movq %rax, %rbx
cmpb $0x0, 0x6d7c8(%rip)     # 0x7b4a8
je 0xdd3f
leaq 0x6d7bf(%rip), %rsi     # 0x7b4a8
movq %rbx, %rdi
callq 0x83b0
testq %rax, %rax
je 0xdd3f
movl 0x6e3d8(%rip), %ecx     # 0x7c0d4
leal 0x1(%rcx), %eax
movl %eax, 0x6e3cf(%rip)     # 0x7c0d4
testl %ecx, %ecx
sete %cl
cmpl $0x1e, %eax
sete %dl
orb %cl, %dl
cmpb $0x1, %dl
jne 0xdd45
leaq 0xef4b(%rip), %rsi      # 0x1cc69
leaq 0xf0a2(%rip), %rdx      # 0x1cdc7
movl $0x2, %edi
xorl %eax, %eax
callq 0x1a3e3
leaq 0x6df90(%rip), %rdi     # 0x7bcc8
xorl %eax, %eax
callq 0x13337
movl 0x6e38f(%rip), %eax     # 0x7c0d4
testl %eax, %eax
je 0xddb0
leaq 0x6d758(%rip), %rsi     # 0x7b4a8
movq %rbx, %rdi
callq 0x83b0
testq %rax, %rax
jne 0xddb0
movl $0x0, 0x6e36d(%rip)     # 0x7c0d4
callq 0x117c0
movq %rax, 0x6db3d(%rip)     # 0x7b8b0
callq 0x117c0
movq %rax, 0x6db41(%rip)     # 0x7b8c0
movq $0x0, 0x6db2e(%rip) # 0x7b8b8
leaq 0xeed8(%rip), %rsi      # 0x1cc69
leaq 0xf046(%rip), %rdx      # 0x1cdde
movl $0x2, %edi
xorl %eax, %eax
callq 0x1a3e3
leaq 0xf04d(%rip), %rdi      # 0x1cdf8
callq 0x13062
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
callq 0x117c0
movq %rax, 0x6daee(%rip)     # 0x7b8b8
jmp 0xdaa6