// File: /workspace/github_c_makefile_star2_O1/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 0x134dc
testl %eax, %eax
je 0xd8ca
movq $0x0, 0x6e152(%rip) # 0x7b8b8
callq 0x111ac
testq %rax, %rax
je 0xd7cd
movq %rax, %rbx
callq 0x114b2
subq %rbx, %rax
cmpq 0x6dd16(%rip), %rax     # 0x7b498
jbe 0xd7cd
callq 0x114b2
movq %rax, 0x6e120(%rip)     # 0x7b8b0
movq $0x0, 0x6e11d(%rip) # 0x7b8b8
callq 0x114b2
movq %rax, 0x6e119(%rip)     # 0x7b8c0
leaq 0xf4e3(%rip), %rsi      # 0x1cc91
leaq 0xf55c(%rip), %rdx      # 0x1cd11
movl $0x2, %edi
xorl %eax, %eax
callq 0x1a227
leaq 0xf562(%rip), %rdi      # 0x1cd2a
callq 0x12ce5
callq 0x114b2
subq 0x6e0e7(%rip), %rax     # 0x7b8c0
cmpq 0x6dcc0(%rip), %rax     # 0x7b4a0
jbe 0xd82b
callq 0x114b2
movq %rax, 0x6e0c2(%rip)     # 0x7b8b0
movq $0x0, 0x6e0bf(%rip) # 0x7b8b8
callq 0x114b2
movq %rax, 0x6e0bb(%rip)     # 0x7b8c0
leaq 0xf485(%rip), %rsi      # 0x1cc91
leaq 0xf52a(%rip), %rdx      # 0x1cd3d
movl $0x2, %edi
xorl %eax, %eax
callq 0x1a227
leaq 0xf530(%rip), %rdi      # 0x1cd56
callq 0x12ce5
movl 0x6e89f(%rip), %eax     # 0x7c0d0
leal 0x1(%rax), %ecx
movl %ecx, 0x6e896(%rip)     # 0x7c0d0
cmpl 0x6dc44(%rip), %eax     # 0x7b484
jl 0xd98f
movl $0x0, 0x6e880(%rip)     # 0x7c0d0
movq 0x6e061(%rip), %r15     # 0x7b8b8
callq 0x134dc
movl %eax, %ebx
callq 0x114b2
movq %rax, %r14
testq %r15, %r15
je 0xd93d
subq 0x6e042(%rip), %r14     # 0x7b8b8
callq 0x114b2
movq %rax, %r15
subq 0x6e02b(%rip), %r15     # 0x7b8b0
callq 0x114b2
movq %rax, %r12
callq 0x111ac
subq %rax, %r12
callq 0x114b2
movq %rax, %r10
subq 0x6e01c(%rip), %r10     # 0x7b8c0
leaq 0xf3e6(%rip), %rsi      # 0x1cc91
leaq 0xf4fa(%rip), %rdx      # 0x1cdac
movl $0x2, %edi
movl %ebx, %ecx
movq %r14, %r8
movq %r15, %r9
xorl %eax, %eax
pushq %r10
pushq %r12
jmp 0xd986
movq 0x6dfe7(%rip), %rbx     # 0x7b8b8
testq %rbx, %rbx
je 0xda7d
addq 0x6dba7(%rip), %rbx     # 0x7b488
callq 0x114b2
cmpq %rax, %rbx
jae 0xd766
callq 0x114b2
movq %rax, 0x6dfb5(%rip)     # 0x7b8b0
movq $0x0, 0x6dfb2(%rip) # 0x7b8b8
callq 0x114b2
movq %rax, 0x6dfae(%rip)     # 0x7b8c0
leaq 0xf378(%rip), %rsi      # 0x1cc91
leaq 0xf3c6(%rip), %rdx      # 0x1cce6
movl $0x2, %edi
xorl %eax, %eax
callq 0x1a227
leaq 0xf3cc(%rip), %rdi      # 0x1ccff
callq 0x12ce5
jmp 0xd766
subq 0x6df6c(%rip), %r14     # 0x7b8b0
callq 0x114b2
movq %rax, %r15
callq 0x111ac
subq %rax, %r15
callq 0x114b2
movq %rax, %r10
subq 0x6df5d(%rip), %r10     # 0x7b8c0
subq $0x8, %rsp
leaq 0xf323(%rip), %rsi      # 0x1cc91
leaq 0xf3f4(%rip), %rdx      # 0x1cd69
movl $0x2, %edi
movl %ebx, %ecx
movq %r14, %r8
movq %r15, %r9
xorl %eax, %eax
pushq %r10
callq 0x1a227
addq $0x10, %rsp
xorl %edi, %edi
callq 0x12dd9
movq %rax, %rbx
cmpb $0x0, 0x6db08(%rip)     # 0x7b4a8
je 0xd9ff
leaq 0x6daff(%rip), %rsi     # 0x7b4a8
movq %rbx, %rdi
callq 0x83b0
testq %rax, %rax
je 0xd9ff
movl 0x6e718(%rip), %eax     # 0x7c0d4
leal 0x1(%rax), %ecx
movl %ecx, 0x6e70f(%rip)     # 0x7c0d4
testl %eax, %eax
sete %al
cmpl $0x1e, %ecx
sete %cl
orb %al, %cl
cmpb $0x1, %cl
jne 0xd9ff
leaq 0xf2b3(%rip), %rsi      # 0x1cc91
leaq 0xf40a(%rip), %rdx      # 0x1cdef
movl $0x2, %edi
xorl %eax, %eax
callq 0x1a227
leaq 0x6e2d0(%rip), %rdi     # 0x7bcc8
xorl %eax, %eax
callq 0x12fba
cmpl $0x0, 0x6e6ce(%rip)     # 0x7c0d4
je 0xda6f
leaq 0x6da99(%rip), %rsi     # 0x7b4a8
movq %rbx, %rdi
callq 0x83b0
testq %rax, %rax
jne 0xda6f
movl $0x0, 0x6e6ae(%rip)     # 0x7c0d4
callq 0x114b2
movq %rax, 0x6de7e(%rip)     # 0x7b8b0
callq 0x114b2
movq %rax, 0x6de82(%rip)     # 0x7b8c0
movq $0x0, 0x6de6f(%rip) # 0x7b8b8
leaq 0xf241(%rip), %rsi      # 0x1cc91
leaq 0xf3af(%rip), %rdx      # 0x1ce06
movl $0x2, %edi
xorl %eax, %eax
callq 0x1a227
leaq 0xf3b6(%rip), %rdi      # 0x1ce20
callq 0x12ce5
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
callq 0x114b2
movq %rax, 0x6de2f(%rip)     # 0x7b8b8
jmp 0xd766