// File: /workspace/github_c_makefile_star2_O2/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 0x12ab4
testl %eax, %eax
je 0xd344
andq $0x0, 0x6e6c9(%rip)     # 0x7b8b8
callq 0x10874
testq %rax, %rax
je 0xd251
movq %rax, %rbx
callq 0x10b6a
subq %rbx, %rax
cmpq 0x6e28d(%rip), %rax     # 0x7b498
jbe 0xd251
callq 0x10b6a
movq %rax, 0x6e697(%rip)     # 0x7b8b0
andq $0x0, 0x6e697(%rip)     # 0x7b8b8
callq 0x10b6a
movq %rax, 0x6e693(%rip)     # 0x7b8c0
leaq 0xea3d(%rip), %rsi      # 0x1bc71
leaq 0xeab6(%rip), %rdx      # 0x1bcf1
pushq $0x2
popq %rdi
xorl %eax, %eax
callq 0x1920b
leaq 0xeabe(%rip), %rdi      # 0x1bd0a
callq 0x12304
callq 0x10b6a
subq 0x6e663(%rip), %rax     # 0x7b8c0
cmpq 0x6e23c(%rip), %rax     # 0x7b4a0
jbe 0xd2aa
callq 0x10b6a
movq %rax, 0x6e63e(%rip)     # 0x7b8b0
andq $0x0, 0x6e63e(%rip)     # 0x7b8b8
callq 0x10b6a
movq %rax, 0x6e63a(%rip)     # 0x7b8c0
leaq 0xe9e4(%rip), %rsi      # 0x1bc71
leaq 0xea89(%rip), %rdx      # 0x1bd1d
pushq $0x2
popq %rdi
xorl %eax, %eax
callq 0x1920b
leaq 0xea91(%rip), %rdi      # 0x1bd36
callq 0x12304
movl 0x6ee20(%rip), %eax     # 0x7c0d0
leal 0x1(%rax), %ecx
movl %ecx, 0x6ee17(%rip)     # 0x7c0d0
cmpl 0x6e1c5(%rip), %eax     # 0x7b484
jl 0xd400
andl $0x0, 0x6ee04(%rip)     # 0x7c0d0
movq 0x6e5e5(%rip), %r15     # 0x7b8b8
callq 0x12ab4
movl %eax, %ebx
callq 0x10b6a
movq %rax, %r14
testq %r15, %r15
je 0xd3b2
subq 0x6e5c6(%rip), %r14     # 0x7b8b8
callq 0x10b6a
movq %rax, %r15
subq 0x6e5af(%rip), %r15     # 0x7b8b0
callq 0x10b6a
movq %rax, %r12
callq 0x10874
subq %rax, %r12
callq 0x10b6a
movq %rax, %r10
subq 0x6e5a0(%rip), %r10     # 0x7b8c0
leaq 0xe94a(%rip), %rsi      # 0x1bc71
leaq 0xea5e(%rip), %rdx      # 0x1bd8c
pushq $0x2
popq %rdi
movl %ebx, %ecx
movq %r14, %r8
movq %r15, %r9
xorl %eax, %eax
pushq %r10
pushq %r12
jmp 0xd3f9
movq 0x6e56d(%rip), %rbx     # 0x7b8b8
testq %rbx, %rbx
je 0xd4e5
addq 0x6e12d(%rip), %rbx     # 0x7b488
callq 0x10b6a
cmpq %rax, %rbx
jae 0xd1ef
callq 0x10b6a
movq %rax, 0x6e53b(%rip)     # 0x7b8b0
andq $0x0, 0x6e53b(%rip)     # 0x7b8b8
callq 0x10b6a
movq %rax, 0x6e537(%rip)     # 0x7b8c0
leaq 0xe8e1(%rip), %rsi      # 0x1bc71
leaq 0xe92f(%rip), %rdx      # 0x1bcc6
pushq $0x2
popq %rdi
xorl %eax, %eax
callq 0x1920b
leaq 0xe937(%rip), %rdi      # 0x1bcdf
callq 0x12304
jmp 0xd1ef
subq 0x6e4f7(%rip), %r14     # 0x7b8b0
callq 0x10b6a
movq %rax, %r15
callq 0x10874
subq %rax, %r15
callq 0x10b6a
movq %rax, %r10
subq 0x6e4e8(%rip), %r10     # 0x7b8c0
subq $0x8, %rsp
leaq 0xe88e(%rip), %rsi      # 0x1bc71
leaq 0xe95f(%rip), %rdx      # 0x1bd49
pushq $0x2
popq %rdi
movl %ebx, %ecx
movq %r14, %r8
movq %r15, %r9
xorl %eax, %eax
pushq %r10
callq 0x1920b
popq %rax
popq %rcx
xorl %edi, %edi
callq 0x123cf
movq %rax, %rbx
cmpb $0x0, 0x6e097(%rip)     # 0x7b4a8
je 0xd46e
leaq 0x6e08e(%rip), %rsi     # 0x7b4a8
movq %rbx, %rdi
callq 0x83c0
testq %rax, %rax
je 0xd46e
movl 0x6eca7(%rip), %ecx     # 0x7c0d4
leal 0x1(%rcx), %eax
movl %eax, 0x6ec9e(%rip)     # 0x7c0d4
testl %ecx, %ecx
sete %cl
cmpl $0x1e, %eax
sete %dl
orb %cl, %dl
cmpb $0x1, %dl
jne 0xd474
leaq 0xe822(%rip), %rsi      # 0x1bc71
leaq 0xe979(%rip), %rdx      # 0x1bdcf
pushq $0x2
popq %rdi
xorl %eax, %eax
callq 0x1920b
leaq 0x6e861(%rip), %rdi     # 0x7bcc8
xorl %eax, %eax
callq 0x125a8
movl 0x6ec60(%rip), %eax     # 0x7c0d4
testl %eax, %eax
je 0xd4d7
leaq 0x6e029(%rip), %rsi     # 0x7b4a8
movq %rbx, %rdi
callq 0x83c0
testq %rax, %rax
jne 0xd4d7
andl $0x0, 0x6ec41(%rip)     # 0x7c0d4
callq 0x10b6a
movq %rax, 0x6e411(%rip)     # 0x7b8b0
callq 0x10b6a
movq %rax, 0x6e415(%rip)     # 0x7b8c0
andq $0x0, 0x6e405(%rip)     # 0x7b8b8
leaq 0xe7b7(%rip), %rsi      # 0x1bc71
leaq 0xe925(%rip), %rdx      # 0x1bde6
pushq $0x2
popq %rdi
xorl %eax, %eax
callq 0x1920b
leaq 0xe92e(%rip), %rdi      # 0x1be00
callq 0x12304
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
callq 0x10b6a
movq %rax, 0x6e3c7(%rip)     # 0x7b8b8
jmp 0xd1ef