function dmn_status($dmnpid)
{
    $mninfolast = array();
    $mnlistfinal = array();
    $mnlist2final = array();
    $mnlastseen = array();
    $mnactivesince = array();
    $mnpubkeylistfinal = array();
    $difficultyfinal = 0;
    $daemonactive = array();
    $protocolinfo = array();
    $curprotocol = 0;
    $oldprotocol = 99999;
    $wsstatus = array();
    xecho('Retrieving status for ' . count($dmnpid) . " nodes\n");
    if (!is_dir("/dev/shm/dmnctl")) {
        if (!mkdir("/dev/shm/dmnctl")) {
            echo "Failed to create directory.\n";
            die(100);
        }
    }
    $tmpdate = date('YmdHis');
    $commands = array();
    // First check the pid and getinfo for all nodes
    foreach ($dmnpid as $dmnnum => $dmnpidinfo) {
        $uname = $dmnpidinfo['uname'];
        $dmnpid[$dmnnum]['pidstatus'] = dmn_checkpid($dmnpidinfo['pid']);
        if ($dmnpid[$dmnnum]['pidstatus'] && $dmnpidinfo['currentbin'] != '') {
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "info", "cmd" => "{$uname} getinfo", "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.getinfo.json");
        }
    }
    // Only vh 3+
    foreach ($dmnpid as $dmnnum => $dmnpidinfo) {
        $uname = $dmnpidinfo['uname'];
        if ($dmnpidinfo['pidstatus'] && $dmnpidinfo['currentbin'] != '' && $dmnpidinfo['versionhandling'] >= 3) {
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnlistfull", "cmd" => $uname . ' "masternode list full"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.masternode_list.json");
            // v12.1 (vh=4)
            if ($dmnpidinfo['versionhandling'] >= 4) {
                $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnbudgetshow", "cmd" => $uname . ' "mnbudget list"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.mnbudget_show.json");
                $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnbudgetfinal", "cmd" => $uname . ' "mnfinalbudget list"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.mnfinalbudget_show.json");
            } else {
                $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnbudgetshow", "cmd" => $uname . ' "mnbudget show"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.mnbudget_show.json");
                $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnbudgetfinal", "cmd" => $uname . ' "mnfinalbudget show"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.mnfinalbudget_show.json");
            }
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnbudgetprojection", "cmd" => $uname . ' "mnbudget projection"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.mnbudget_projection.json");
        }
    }
    // Only vh 2 and below
    foreach ($dmnpid as $dmnnum => $dmnpidinfo) {
        $uname = $dmnpidinfo['uname'];
        if ($dmnpidinfo['pidstatus'] && $dmnpidinfo['currentbin'] != '' && $dmnpidinfo['versionhandling'] <= 2) {
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnlist", "cmd" => $uname . ' "masternode list"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.masternode_list.json");
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mndonation", "cmd" => $uname . ' "masternode list donation"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.masternode_list_donation.json");
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnvotes", "cmd" => $uname . ' "masternode list votes"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.masternode_list_votes.json");
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnlastseen", "cmd" => $uname . ' "masternode list lastseen"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.masternode_list_lastseen.json");
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnpubkey", "cmd" => $uname . ' "masternode list pubkey"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.masternode_list_pubkey.json");
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnpose", "cmd" => $uname . ' "masternode list pose"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.masternode_list_pose.json");
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnactiveseconds", "cmd" => $uname . ' "masternode list activeseconds"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.masternode_list_activeseconds.json");
        }
    }
    // All vh
    foreach ($dmnpid as $dmnnum => $dmnpidinfo) {
        $uname = $dmnpidinfo['uname'];
        if ($dmnpidinfo['pidstatus'] && $dmnpidinfo['currentbin'] != '') {
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mncurrent", "cmd" => $uname . ' "masternode current"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.masternode_current.json");
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "spork", "cmd" => $uname . ' "spork show"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.spork_show.json");
        }
    }
    dmn_ctlrpc($commands);
    xecho("Parsing results...\n");
    foreach ($commands as $command) {
        if ($command['status'] != 2) {
            $res = false;
            xecho("Command failed (" . $command['cmd'] . ") [" . $command['result'] . "]\n");
        } else {
            $res = file_get_contents($command['file']);
            if ($res !== false) {
                if ($command['datatype'] == 'mnpubkey') {
                    $res = explode(",", substr($res, 1, -1));
                    $pubkeys = array();
                    foreach ($res as $line) {
                        $raw = explode(":", $line);
                        if (is_array($raw) && count($raw) == 3) {
                            $ip = substr(trim($raw[0]), 1);
                            $port = substr(trim($raw[1]), 0, -1);
                            $pubkey = substr(trim($raw[2]), 1, -1);
                            $pubkeys[] = array("ip" => $ip, "port" => $port, "pubkey" => $pubkey);
                        }
                    }
                    $res = $pubkeys;
                } elseif ($command['datatype'] == 'mndonation') {
                    $res = explode(",", substr($res, 1, -1));
                    $pubkeys = array();
                    foreach ($res as $line) {
                        $raw = explode(":", $line);
                        if (is_array($raw)) {
                            if (count($raw) == 4) {
                                $ip = substr(trim($raw[0]), 1);
                                $port = substr(trim($raw[1]), 0, -1);
                                $pubkey = substr(trim($raw[2]), 1);
                                $percent = substr(trim($raw[3]), 0, -1);
                                $pubkeys[] = array("ip" => $ip, "port" => $port, "pubkey" => $pubkey, "percent" => intval($percent));
                            } elseif (count($raw) == 3) {
                                $ip = substr(trim($raw[0]), 1);
                                $port = substr(trim($raw[1]), 0, -1);
                                $pubkey = substr(trim($raw[2]), 1);
                                $pubkeys[] = array("ip" => $ip, "port" => $port, "pubkey" => '', "percent" => 0);
                            }
                        }
                    }
                    $res = $pubkeys;
                } elseif ($command['datatype'] != 'mncurrent') {
                    $res = json_decode($res, true);
                    if ($res === false) {
                        xecho("Could not decode JSON from " . $command['file'] . "\n");
                    }
                    if (array_key_exists('result', $res)) {
                        $res = $res['result'];
                    }
                }
            } else {
                xecho("Could not read file: " . $command['file'] . "\n");
            }
            if (!unlink($command['file'])) {
                xecho("Could not delete file: " . $command['file'] . "\n");
            }
        }
        $dmnpid[$command['dmnnum']][$command['datatype']] = $res;
    }
    $commands = array();
    $nbuname = 5;
    $nbversion = 7;
    $nbprotocol = 8;
    $nbblocks = 6;
    $nbconnections = 4;
    $nbpid = 3;
    foreach ($dmnpid as $dmnnum => $dmnpidinfo) {
        $uname = $dmnpidinfo['uname'];
        if (strlen($dmnpidinfo['pid']) > $nbpid) {
            $nbpid = strlen($dmnpidinfo['pid']);
        }
        if (strlen($uname) > $nbuname) {
            $nbuname = strlen($uname);
        }
        if (array_key_exists('info', $dmnpidinfo)) {
            if (strlen($dmnpidinfo['info']['version']) > $nbversion) {
                $nbversion = strlen($dmnpidinfo['info']['version']);
            }
            if (strlen($dmnpidinfo['info']['protocolversion']) > $nbprotocol) {
                $nbprotocol = strlen($dmnpidinfo['info']['protocolversion']);
            }
            if (strlen($dmnpidinfo['info']['blocks']) > $nbblocks) {
                $nbblocks = strlen($dmnpidinfo['info']['blocks']);
            }
            if (strlen($dmnpidinfo['info']['connections']) > $nbconnections) {
                $nbconnections = strlen($dmnpidinfo['info']['connections']);
            }
        }
        if ($dmnpidinfo['pidstatus'] && $dmnpidinfo['currentbin'] != '') {
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "blockhash", "cmd" => $uname . ' "getblockhash ' . $dmnpidinfo['info']['blocks'] . '"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.getblockhash.json");
            $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "networkhashps", "cmd" => $uname . ' getnetworkhashps', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.getnetworkhashps.json");
            if ($dmnpidinfo['versionhandling'] >= 3 && array_key_exists("mnbudgetshow", $dmnpidinfo) && is_array($dmnpidinfo["mnbudgetshow"])) {
                foreach ($dmnpidinfo["mnbudgetshow"] as $mnbudgetid => $mnbudgetdata) {
                    $commands[] = array("status" => 0, "dmnnum" => $dmnnum, "datatype" => "mnbudget-getvotes-" . $mnbudgetid, "cmd" => $uname . ' "mnbudget getvotes ' . $mnbudgetid . '"', "file" => "/dev/shm/dmnctl/{$uname}.{$tmpdate}.mnbudget_getvotes_{$mnbudgetid}.json");
                }
            }
        }
    }
    dmn_ctlrpc($commands);
    xecho("Parsing results...\n");
    foreach ($commands as $command) {
        if ($command['status'] != 2) {
            $res = false;
        } else {
            $res = file_get_contents($command['file']);
            if ($res === false) {
                xecho("Could not read file: " . $command['file'] . "\n");
            }
            if (!unlink($command['file'])) {
                xecho("Could not delete file: " . $command['file'] . "\n");
            }
            if (strlen($command['datatype']) > 18 && substr($command['datatype'], 0, 18) == 'mnbudget-getvotes-') {
                $res = json_decode($res, true);
                if ($res === false) {
                    xecho("Could not decode JSON from " . $command['file'] . "\n");
                }
                if (array_key_exists('result', $res)) {
                    $res = $res['result'];
                }
            }
        }
        $dmnpid[$command['dmnnum']][$command['datatype']] = $res;
    }
    xecho(str_pad("Node", $nbuname) . " " . str_pad("PID", $nbpid) . " ST " . str_pad("Version", $nbversion) . " " . str_pad("Protocol", $nbprotocol) . " " . str_pad("Blocks", $nbblocks) . " " . str_pad("Hash", 64) . " " . str_pad("Conn", $nbconnections) . " V IP\n");
    $separator = str_repeat("-", $nbuname + $nbpid + $nbversion + $nbprotocol + $nbblocks + 109) . "\n";
    xecho($separator);
    $networkhashps = false;
    $networkhashpstest = false;
    $spork = array();
    $mninfo2 = array();
    $mnbudgetshow = array();
    $mnbudgetprojection = array(array(), array());
    $mnbudgetfinal = array();
    $mndonationlistfinal = array();
    $mnvoteslistfinal = array();
    $mnbudgetvotes = array(array(), array());
    $dmnpidtorestart = array();
    // Go through all nodes
    foreach ($dmnpid as $dmnnum => $dmnpidinfo) {
        // Get the uname
        $uname = $dmnpidinfo['uname'];
        $conf = $dmnpidinfo['conf'];
        // Is the node enabled in the configuration
        $dmnenabled = $conf->getmnctlconfig('enable') == 1;
        // Get default port
        if ($dmnpidinfo['conf']->getconfig('testnet') == '1') {
            $port = 19999;
        } else {
            $port = 9999;
        }
        // Default values
        $iponly = '';
        $version = 0;
        $protocol = 0;
        $blocks = 0;
        $blockhash = '';
        $connections = 0;
        $country = '';
        $countrycode = '';
        $spork[$uname] = array();
        // Indicate what we are doing
        xecho(str_pad($uname, $nbuname) . " " . str_pad($dmnpidinfo['pid'], $nbpid, ' ', STR_PAD_LEFT) . " ");
        // If the process is running
        if ($dmnpidinfo['pid'] !== false && $dmnpidinfo['currentbin'] != '') {
            // Spork info
            if (array_key_exists("spork", $dmnpidinfo)) {
                $spork[$uname] = $dmnpidinfo['spork'];
            } else {
                $spork[$uname] = array();
            }
            // Parse status
            $dashdinfo = dmn_getstatus($dmnpidinfo['info'], $dmnpidinfo['blockhash']);
            $blocks = $dashdinfo['blocks'];
            $blockhash = $dashdinfo['blockhash'];
            $connections = $dashdinfo['connections'];
            $difficulty = $dashdinfo['difficulty'];
            $protocol = $dashdinfo['protocol'];
            $version = $dashdinfo['version'];
            // Protocol
            //  Current protocol is the max protocol
            if ($curprotocol < $protocol) {
                $curprotocol = $protocol;
            }
            //  Old protocol is the min protocol
            if ($oldprotocol > $protocol) {
                $oldprotocol = $protocol;
            }
            //  Store the protocol of this node
            $protocolinfo[$uname] = $protocol;
            // Store the networkhash
            if ($dashdinfo['testnet'] == 1) {
                $networkhashpstest = intval($dmnpidinfo['networkhashps']);
            } else {
                $networkhashps = intval($dmnpidinfo['networkhashps']);
            }
            // If the version could be retrieved
            if ($version !== false) {
                // Our node is active
                $daemonactive[] = $uname;
                // Remove the notresponding counter file
                if (file_exists(DMN_NRCOUNTDIR . "dmnctl-NR-{$uname}-counter")) {
                    unlink(DMN_NRCOUNTDIR . "dmnctl-NR-{$uname}-counter");
                }
                // Retrieve the IP from the node
                $ip = dmn_getip($dmnpidinfo['pid'], $uname);
                $dmnip = $ip;
                $ipexp = explode(':', $ip);
                $iponly = $ipexp[0];
                $country = dmn_getcountry($ip, $countrycode);
                if ($country === false) {
                    $country = 'Unknown';
                    $countrycode = '__';
                }
                $port = $ipexp[1];
                // Default values
                $processstatus = 'running';
                // Display some feedback
                echo "OK ";
                echo str_pad($version, $nbversion, ' ', STR_PAD_LEFT) . " " . str_pad($protocol, $nbprotocol, ' ', STR_PAD_LEFT) . " " . str_pad($blocks, $nbblocks, ' ', STR_PAD_LEFT) . " {$blockhash} " . str_pad($connections, $nbconnections, ' ', STR_PAD_LEFT) . " ";
                // Store the max difficulty
                if ($difficulty > $difficultyfinal) {
                    $difficultyfinal = $difficulty;
                }
                // Indicates what version handling we are using
                echo $dmnpidinfo['versionhandling'];
                // Old version handling (1 & 2)
                if ($dmnpidinfo['versionhandling'] <= 2) {
                    $mnpose = $dmnpidinfo['mnpose'];
                    $mnlist = $dmnpidinfo['mnlist'];
                    $mncurrentip = $dmnpidinfo['mncurrent'];
                    $mncurrentlist[$uname] = $mncurrentip . ":" . $dashdinfo['testnet'];
                    foreach ($dmnpidinfo['mnlastseen'] as $mnlsip => $data) {
                        $mnlastseen[$uname][$mnlsip . ':' . $dashdinfo['testnet']] = $data;
                    }
                    foreach ($dmnpidinfo['mnactiveseconds'] as $mnlsip => $data) {
                        $mnactivesince[$uname][$mnlsip . ':' . $dashdinfo['testnet']] = $data;
                    }
                    $mndonationlist = $dmnpidinfo['mndonation'];
                    $mnvoteslist = $dmnpidinfo['mnvotes'];
                    $mnpubkeylist = $dmnpidinfo['mnpubkey'];
                    foreach ($mnlist as $ip => $activetrue) {
                        if ($activetrue != 1) {
                            if ($activetrue == "ENABLED" || $activetrue == "PRE_ENABLED") {
                                $active = 1;
                            } else {
                                $active = 0;
                            }
                        } else {
                            $active = $activetrue;
                        }
                        $mnlistfinal["{$ip}:" . $dashdinfo['testnet']][$uname] = array('Status' => $active, 'PoS' => $mnpose[$ip], 'StatusEx' => $activetrue);
                    }
                    if (is_array($mnvoteslist) && count($mnvoteslist) > 0) {
                        foreach ($mnvoteslist as $ip => $vote) {
                            $mnvoteslistfinal["{$ip}:" . $dashdinfo['testnet']][$uname] = $vote;
                        }
                    }
                    foreach ($mnpubkeylist as $data) {
                        $mnpubkeylistfinal[$data["ip"] . ":" . $data["port"] . ":" . $dashdinfo['testnet'] . ":" . $data["pubkey"]] = array("MasternodeIP" => $data["ip"], "MasternodePort" => $data["port"], "MNTestNet" => $dashdinfo['testnet'], "MNPubKey" => $data["pubkey"]);
                    }
                    if (is_array($mndonationlist)) {
                        foreach ($mndonationlist as $donatedata) {
                            $mndonationlistfinal[$donatedata["ip"] . ":" . $donatedata["port"] . ":" . $dashdinfo['testnet'] . ":" . $donatedata["pubkey"]] = array("MasternodeIP" => $donatedata["ip"], "MasternodePort" => $donatedata["port"], "MNTestNet" => $dashdinfo['testnet'], "MNPubKey" => $donatedata["pubkey"], "MNDonationPercentage" => $donatedata["percent"]);
                        }
                    }
                } elseif ($dmnpidinfo['versionhandling'] >= 3) {
                    // Parse masternode budgets proposals
                    if (is_array($dmnpidinfo['mnbudgetshow'])) {
                        foreach ($dmnpidinfo['mnbudgetshow'] as $mnbudgetid => $mnbudgetdata) {
                            if (array_key_exists($dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"], $mnbudgetshow)) {
                                if ($mnbudgetshow[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]["Yeas"] + $mnbudgetshow[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]["Nays"] + $mnbudgetshow[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]["Abstains"] < $mnbudgetdata["Yeas"] + $mnbudgetdata["Nays"] + $mnbudgetdata["Abstains"]) {
                                    $mnbudgetshow[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]] = $mnbudgetdata;
                                    $mnbudgetshow[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]['BudgetId'] = $mnbudgetid;
                                    $mnbudgetshow[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]["BudgetTesnet"] = $dashdinfo['testnet'];
                                }
                            } else {
                                $mnbudgetshow[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]] = $mnbudgetdata;
                                $mnbudgetshow[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]['BudgetId'] = $mnbudgetid;
                                $mnbudgetshow[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]["BudgetTesnet"] = $dashdinfo['testnet'];
                            }
                            if (array_key_exists("mnbudget-getvotes-" . $mnbudgetid, $dmnpidinfo)) {
                                if (!array_key_exists($mnbudgetid, $mnbudgetvotes[$dashdinfo['testnet']])) {
                                    $mnbudgetvotes[$dashdinfo['testnet']][$mnbudgetid] = array();
                                }
                                if (is_array($dmnpidinfo["mnbudget-getvotes-" . $mnbudgetid])) {
                                    foreach ($dmnpidinfo["mnbudget-getvotes-" . $mnbudgetid] as $mnbudgetvotehash => $mnbudgetvotedata) {
                                        if (array_key_exists($mnbudgetvotehash, $mnbudgetvotes[$dashdinfo['testnet']][$mnbudgetid])) {
                                            if ($mnbudgetvotes[$dashdinfo['testnet']][$mnbudgetid][$mnbudgetvotehash]["nTime"] < $mnbudgetvotedata["nTime"]) {
                                                $mnbudgetvotes[$dashdinfo['testnet']][$mnbudgetid][$mnbudgetvotehash] = $mnbudgetvotedata;
                                            }
                                        } else {
                                            $mnbudgetvotes[$dashdinfo['testnet']][$mnbudgetid][$mnbudgetvotehash] = $mnbudgetvotedata;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    // Parse masternode budgets projections
                    if (is_array($dmnpidinfo['mnbudgetprojection'])) {
                        foreach ($dmnpidinfo['mnbudgetprojection'] as $mnbudgetid => $mnbudgetdata) {
                            if (is_array($mnbudgetdata) && array_key_exists("Yeas", $mnbudgetdata) && array_key_exists("Nays", $mnbudgetdata) && array_key_exists("Abstains", $mnbudgetdata)) {
                                if (array_key_exists($mnbudgetdata["Hash"], $mnbudgetprojection[$dashdinfo['testnet']])) {
                                    if ($mnbudgetprojection[$dashdinfo['testnet']][$mnbudgetdata["Hash"]]["Yeas"] + $mnbudgetprojection[$dashdinfo['testnet']][$mnbudgetdata["Hash"]]["Nays"] + $mnbudgetprojection[$dashdinfo['testnet']][$mnbudgetdata["Hash"]]["Abstains"] < $mnbudgetdata["Yeas"] + $mnbudgetdata["Nays"] + $mnbudgetdata["Abstains"]) {
                                        $mnbudgetprojection[$dashdinfo['testnet']][$mnbudgetdata["Hash"]] = $mnbudgetdata;
                                        $mnbudgetprojection[$dashdinfo['testnet']][$mnbudgetdata["Hash"]]['BudgetId'] = $mnbudgetid;
                                        $mnbudgetprojection[$dashdinfo['testnet']][$mnbudgetdata["Hash"]]["BudgetTesnet"] = $dashdinfo['testnet'];
                                    }
                                } else {
                                    $mnbudgetprojection[$dashdinfo['testnet']][$mnbudgetdata["Hash"]] = $mnbudgetdata;
                                    $mnbudgetprojection[$dashdinfo['testnet']][$mnbudgetdata["Hash"]]['BudgetId'] = $mnbudgetid;
                                    $mnbudgetprojection[$dashdinfo['testnet']][$mnbudgetdata["Hash"]]["BudgetTesnet"] = $dashdinfo['testnet'];
                                }
                            }
                        }
                    }
                    // Parse masternode final budget
                    if (is_array($dmnpidinfo['mnbudgetfinal'])) {
                        foreach ($dmnpidinfo['mnbudgetfinal'] as $mnbudgetid => $mnbudgetdata) {
                            if (array_key_exists($dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"], $mnbudgetfinal) && array_key_exists("VoteCount", $mnbudgetfinal[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]])) {
                                if ($mnbudgetfinal[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]["VoteCount"] < $mnbudgetdata["VoteCount"]) {
                                    $mnbudgetfinal[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]] = $mnbudgetdata;
                                    $mnbudgetfinal[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]['BudgetName'] = $mnbudgetid;
                                    $mnbudgetfinal[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]["BudgetTesnet"] = $dashdinfo['testnet'];
                                }
                            } else {
                                $mnbudgetfinal[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]] = $mnbudgetdata;
                                $mnbudgetfinal[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]['BudgetName'] = $mnbudgetid;
                                $mnbudgetfinal[$dashdinfo['testnet'] . "-" . $mnbudgetdata["Hash"]]["BudgetTesnet"] = $dashdinfo['testnet'];
                            }
                        }
                    }
                    // Parse the masternode list
                    $mn3listfull = $dmnpidinfo['mnlistfull'];
                    foreach ($mn3listfull as $mn3output => $mn3data) {
                        // Remove all extra spaces
                        $mn3data = trim($mn3data);
                        do {
                            $rcount = 0;
                            $mn3data = str_replace("  ", " ", $mn3data, $rcount);
                        } while ($rcount > 0);
                        // Store each value separated by spaces
                        if ($dmnpidinfo['versionhandling'] == 3) {
                            list($mn3status, $mn3protocol, $mn3pubkey, $mn3ipport, $mn3lastseen, $mn3activeseconds, $mn3lastpaid) = explode(" ", $mn3data);
                        } else {
                            list($mn3status, $mn3protocol, $mn3pubkey, $mn3lastseen, $mn3activeseconds, $mn3lastpaid, $mn4lastpaidblock, $mn3ipport) = explode(" ", $mn3data);
                        }
                        // Handle the IPs
                        if (substr($mn3ipport, 0, 1) == "[") {
                            // IPv6
                            list($mn3ip, $mn3port) = explode("]:", substr($mn3ipport, 1, strlen($mn3ipport) - 1));
                        } else {
                            // IPv4
                            $test = explode(":", $mn3ipport);
                            if (!array_key_exists(1, $test)) {
                                var_dump($mn3ipport);
                            }
                            list($mn3ip, $mn3port) = $test;
                        }
                        if (array_key_exists($mn3output . "-" . $dashdinfo['testnet'], $mninfo2)) {
                            if ($mn3lastseen < $mninfo2[$mn3output . "-" . $dashdinfo['testnet']]["MasternodeLastSeen"]) {
                                $mninfo2[$mn3output . "-" . $dashdinfo['testnet']]["MasternodeLastSeen"] = intval($mn3lastseen);
                            }
                            if ($mn3activeseconds < $mninfo2[$mn3output . "-" . $dashdinfo['testnet']]["MasternodeActiveSeconds"]) {
                                $mninfo2[$mn3output . "-" . $dashdinfo['testnet']]["MasternodeActiveSeconds"] = intval($mn3activeseconds);
                            }
                            if ($mn3lastpaid > $mninfo2[$mn3output . "-" . $dashdinfo['testnet']]["MasternodeLastPaid"]) {
                                $mninfo2[$mn3output . "-" . $dashdinfo['testnet']]["MasternodeLastPaid"] = intval($mn3lastpaid);
                            }
                        } else {
                            $mninfo2[$mn3output . "-" . $dashdinfo['testnet']] = array("MasternodeProtocol" => intval($mn3protocol), "MasternodePubkey" => $mn3pubkey, "MasternodeIP" => $mn3ip, "MasternodePort" => $mn3port, "MasternodeLastSeen" => intval($mn3lastseen), "MasternodeActiveSeconds" => intval($mn3activeseconds), "MasternodeLastPaid" => $mn3lastpaid);
                        }
                        if ($mn3status == "ENABLED" || $mn3status == "PRE_ENABLED") {
                            $active = 1;
                        } else {
                            $active = 0;
                        }
                        $mnlist2final[$mn3output . "-" . $dashdinfo['testnet']][$uname] = array('Status' => $active, 'StatusEx' => $mn3status);
                    }
                }
                echo " {$dmnip}\n";
            } elseif ($dmnenabled) {
                $iponly = $dmnpidinfo['conf']->getconfig('bind');
                $ip = "{$iponly}:{$port}";
                $country = dmn_getcountry($ip, $countrycode);
                if ($country === false) {
                    $country = 'Unknown';
                    $countrycode = '__';
                }
                $processstatus = 'notresponding';
                $dmnpidtorestart[$dmnnum] = $dmnpidinfo;
                echo "NR " . str_repeat(" ", 96) . "{$ip}\n";
            } else {
                $processstatus = 'disabled';
                echo "--\n";
            }
        } elseif ($dmnenabled) {
            // Remove the notresponding counter file
            if (file_exists(DMN_NRCOUNTDIR . "dmnctl-NR-{$uname}-counter")) {
                unlink(DMN_NRCOUNTDIR . "dmnctl-NR-{$uname}-counter");
            }
            $iponly = $dmnpidinfo['conf']->getconfig('bind');
            $ip = "{$iponly}:{$port}";
            $country = dmn_getcountry($ip, $countrycode);
            if ($country === false) {
                $country = 'Unknown';
                $countrycode = '__';
            }
            $processstatus = 'stopped';
            echo "NS " . str_repeat(" ", 96) . "{$ip}\n";
        } else {
            // Remove the notresponding counter file
            if (file_exists(DMN_NRCOUNTDIR . "dmnctl-NR-{$uname}-counter")) {
                unlink(DMN_NRCOUNTDIR . "dmnctl-NR-{$uname}-counter");
            }
            $processstatus = 'disabled';
            echo "--\n";
        }
        $wsstatus[$uname] = array("ProcessStatus" => $processstatus, "Version" => $version, "Protocol" => $protocol, "Blocks" => $blocks, "LastBlockHash" => $blockhash, "Connections" => $connections, "IP" => $iponly, "Port" => $port, "Country" => $country, "CountryCode" => $countrycode, "Spork" => $spork[$uname]);
    }
    xecho($separator);
    ksort($mnpubkeylistfinal, SORT_NATURAL);
    $mnlastseenfinal = array();
    foreach ($mnlastseen as $uname => $mnlastseenlist) {
        foreach ($mnlastseenlist as $ip => $lastseentimestamp) {
            if (array_key_exists($ip, $mnlastseenfinal) && $mnlastseenfinal[$ip] > $lastseentimestamp || !array_key_exists($ip, $mnlastseenfinal)) {
                $mnlastseenfinal[$ip] = $lastseentimestamp;
            }
        }
    }
    ksort($mnlastseenfinal, SORT_NATURAL);
    $mnactivesincefinal = array();
    foreach ($mnactivesince as $uname => $mnactivesincelist) {
        foreach ($mnactivesincelist as $ip => $activeseconds) {
            if (array_key_exists($ip, $mnactivesincefinal) && $mnactivesincefinal[$ip] < $activeseconds || !array_key_exists($ip, $mnactivesincefinal)) {
                $mnactivesincefinal[$ip] = $activeseconds;
            }
        }
    }
    ksort($mnactivesincefinal, SORT_NATURAL);
    $mncountinactive = 0;
    $mncountactive = 0;
    foreach ($mnlistfinal as $ip => $info) {
        $inactiveresult = true;
        foreach ($info as $uname => $mnactive) {
            $inactiveresult = $inactiveresult && ($mnactive == 0 || $mnactive === false);
        }
        if ($inactiveresult) {
            $mncountinactive++;
        } else {
            $mncountactive++;
        }
    }
    $mninfodel = array();
    foreach ($mninfolast as $ip) {
        if (!array_key_exists($ip, $mnlistfinal)) {
            $info = explode(":", $ip);
            $mninfodel[] = array('ip' => $info[0], 'port' => $info[1]);
        }
    }
    $mncount = $mncountinactive + $mncountactive;
    if (count($mnlistfinal) > 0) {
        ksort($mnlistfinal, SORT_NATURAL);
        $estpayoutdaily = round(dmn_getpayout($mncountactive, $dashdinfo['difficulty']), 2);
    } else {
        $estpayoutdaily = '???';
    }
    //  echo "Total Masternodes: $mncount/$mncountinactive    Est.Payout: $estpayoutdaily DASH/day (diff=$difficultyfinal)\n";
    if (count($wsstatus) > 0) {
        $wsmninfo = array();
        $wsmnlist = array();
        foreach ($mnlistfinal as $ip => $mninfo) {
            $ipport = explode(":", $ip);
            $mnip = $ipport[0];
            $mnport = $ipport[1];
            $mntestnet = $ipport[2];
            if (array_key_exists($ip, $mnactivesincefinal)) {
                $mnactiveseconds = $mnactivesincefinal[$ip];
            } else {
                $mnactiveseconds = 0;
            }
            if (array_key_exists($ip, $mnlastseenfinal)) {
                $mnlastseen = $mnlastseenfinal[$ip];
            } else {
                $mnlastseen = 0;
            }
            $mncountry = dmn_getcountry($ip, $mncountrycode);
            if ($mncountry === false) {
                $mncountry = 'Unknown';
                $mncountrycode = '__';
            }
            $wsmninfo[] = array("MasternodeIP" => $mnip, "MasternodePort" => $mnport, "MNTestNet" => $mntestnet, "MNActiveSeconds" => $mnactiveseconds, "MNLastSeen" => $mnlastseen, "MNCountry" => $mncountry, "MNCountryCode" => $mncountrycode);
            foreach ($mninfo as $mnuname => $mnactive) {
                if ($mnactive['Status'] == 1) {
                    if (array_key_exists($mnuname, $mncurrentlist) && $ip == $mncurrentlist[$uname]) {
                        $mnstatus = 'current';
                    } else {
                        $mnstatus = 'active';
                    }
                } elseif ($mnactive['Status'] === false) {
                    $mnstatus = 'unlisted';
                } else {
                    $mnstatus = 'inactive';
                }
                $wsmnlist[] = array("MasternodeIP" => $mnip, "MasternodePort" => $mnport, "MNTestNet" => $mntestnet, "FromNodeUName" => $mnuname, "MasternodeStatus" => $mnstatus, "MasternodeStatusPoS" => $mnactive['PoS'], "MasternodeStatusEx" => $mnactive['StatusEx']);
            }
        }
        $wsmnpubkeys = array();
        foreach ($mnpubkeylistfinal as $key => $data) {
            $wsmnpubkeys[] = $data;
        }
        $wsmndonation = array();
        foreach ($mndonationlistfinal as $key => $data) {
            $wsmndonation[] = $data;
        }
        $wsmnvotes = array();
        foreach ($mnvoteslistfinal as $ip => $mnvotesinfo) {
            $ipport = explode(":", $ip);
            $mnip = $ipport[0];
            $mnport = $ipport[1];
            $mntestnet = $ipport[2];
            foreach ($mnvotesinfo as $mnuname => $mnvote) {
                $wsmnvotes[] = array("MasternodeIP" => $mnip, "MasternodePort" => $mnport, "MNTestNet" => $mntestnet, "FromNodeUName" => $mnuname, "MasternodeVote" => $mnvote);
            }
        }
        // v12 handling / VersionHandling = 3
        $wsmninfo2 = array();
        foreach ($mninfo2 as $output => $mninfo) {
            list($mnoutputhash, $mnoutputindex, $mntestnet) = explode("-", $output);
            $wsmninfo2[] = array("MasternodeOutputHash" => $mnoutputhash, "MasternodeOutputIndex" => $mnoutputindex, "MasternodeTestNet" => $mntestnet, "MasternodeProtocol" => $mninfo["MasternodeProtocol"], "MasternodePubkey" => $mninfo["MasternodePubkey"], "MasternodeIP" => $mninfo["MasternodeIP"], "MasternodePort" => $mninfo["MasternodePort"], "MasternodeLastSeen" => $mninfo["MasternodeLastSeen"], "MasternodeActiveSeconds" => $mninfo["MasternodeActiveSeconds"], "MasternodeLastPaid" => $mninfo["MasternodeLastPaid"]);
        }
        $wsmnlist2 = array();
        foreach ($mnlist2final as $output => $mninfo) {
            list($mnoutputhash, $mnoutputindex, $mntestnet) = explode("-", $output);
            foreach ($mninfo as $mnuname => $mnactive) {
                if ($mnactive['Status'] == 1) {
                    $mnstatus = 'active';
                } elseif ($mnactive['Status'] === false) {
                    $mnstatus = 'unlisted';
                } else {
                    $mnstatus = 'inactive';
                }
                $wsmnlist2[] = array("MasternodeOutputHash" => $mnoutputhash, "MasternodeOutputIndex" => $mnoutputindex, "MasternodeTestNet" => $mntestnet, "FromNodeUName" => $mnuname, "MasternodeStatus" => $mnstatus, "MasternodeStatusEx" => $mnactive['StatusEx']);
            }
        }
        $wsmnbudgetshow = array();
        foreach ($mnbudgetshow as $budgetinfo) {
            $wsmnbudgetshow[] = $budgetinfo;
        }
        $wsmnbudgetvotes = array();
        foreach ($mnbudgetvotes as $testnet => $mnbudgetvotesdata) {
            foreach ($mnbudgetvotesdata as $budgetid => $mnbudgetvotesdata2) {
                foreach ($mnbudgetvotesdata2 as $mnvotehash => $mnbudgetvotesdata3) {
                    list($mnoutputhash, $mnoutputindex) = explode("-", $mnvotehash);
                    $wsmnbudgetvotes[] = array('BudgetTestnet' => intval($testnet), 'BudgetId' => $budgetid, 'MasternodeOutputHash' => $mnoutputhash, 'MasternodeOutputIndex' => intval($mnoutputindex), 'VoteHash' => $mnbudgetvotesdata3["nHash"], 'VoteValue' => $mnbudgetvotesdata3["Vote"], 'VoteTime' => $mnbudgetvotesdata3["nTime"], 'VoteIsValid' => $mnbudgetvotesdata3["fValid"]);
                }
            }
        }
        $wsmnbudgetprojection = array();
        foreach ($mnbudgetprojection as $mnbudgetdata) {
            foreach ($mnbudgetdata as $budgetinfo) {
                $wsmnbudgetprojection[] = $budgetinfo;
            }
        }
        $wsmnbudgetfinal = array();
        foreach ($mnbudgetfinal as $budgetinfo) {
            $wsmnbudgetfinal[] = $budgetinfo;
        }
        xecho("Submitting status via webservice (" . count($wsstatus) . " entries): ");
        $response = '';
        $payload = array('nodes' => $wsstatus, 'mninfo' => $wsmninfo, 'mninfo2' => $wsmninfo2, 'mnpubkeys' => $wsmnpubkeys, 'mndonation' => $wsmndonation, 'mnlist' => $wsmnlist, 'mnlist2' => $wsmnlist2, 'mnvotes' => $wsmnvotes, 'mnbudgetshow' => $wsmnbudgetshow, 'mnbudgetfinal' => $wsmnbudgetfinal, 'mnbudgetvotes' => $wsmnbudgetvotes, 'mnbudgetprojection' => $wsmnbudgetprojection, 'stats' => array(0 => array('networkhashps' => $networkhashps), 1 => array('networkhashps' => $networkhashpstest)));
        $contentraw = dmn_cmd_post('ping', $payload, $response);
        if (strlen($contentraw) > 0) {
            $content = json_decode($contentraw, true);
            if ($response['http_code'] >= 200 && $response['http_code'] <= 299) {
                echo "Success (" . $response['http_code'] . ")\n";
                if (is_array($content["data"])) {
                    xecho("+ Nodes: ");
                    if ($content["data"]["nodes"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["nodes"] . "\n";
                    }
                    xecho("+ Masternodes Info (<=v0.11): ");
                    if ($content["data"]["mninfo"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mninfo"] . "\n";
                    }
                    xecho("+ Masternodes Info (>=v0.12): ");
                    if ($content["data"]["mninfo2"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mninfo2"] . "\n";
                    }
                    xecho("+ Masternodes Pubkeys (<=v0.11): ");
                    if ($content["data"]["mnpubkeys"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mnpubkeys"] . "\n";
                    }
                    xecho("+ Masternodes Donations (<=v0.11): ");
                    if ($content["data"]["mndonation"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mndonation"] . "\n";
                    }
                    xecho("+ Masternodes List (<=v0.11): ");
                    if ($content["data"]["mnlist"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mnlist"] . "\n";
                    }
                    xecho("+ Masternodes List (>=v0.12): ");
                    if ($content["data"]["mnlist2"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mnlist2"] . "\n";
                    }
                    xecho("+ Masternodes Portcheck: ");
                    if ($content["data"]["portcheck"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["portcheck"] . "\n";
                    }
                    xecho("+ Masternodes Votes: ");
                    if ($content["data"]["mnvotes"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mnvotes"] . "\n";
                    }
                    xecho("+ Spork: ");
                    if ($content["data"]["spork"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["spork"] . "\n";
                    }
                    xecho("+ Stats (Mainnet): ");
                    if ($content["data"]["stats"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["stats"] . "\n";
                    }
                    xecho("+ Stats (Testnet): ");
                    if ($content["data"]["stats2"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["stats2"] . "\n";
                    }
                    xecho("+ Budget (Show): ");
                    if ($content["data"]["mnbudgetshow"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mnbudgetshow"] . "\n";
                    }
                    xecho("+ Budget (Projection): ");
                    if ($content["data"]["mnbudgetprojection"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mnbudgetprojection"] . "\n";
                    }
                    xecho("+ Budget (Votes): ");
                    if ($content["data"]["mnbudgetvotes"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mnbudgetvotes"] . "\n";
                    }
                    xecho("+ Final Budget): ");
                    if ($content["data"]["mnbudgetfinal"] === false) {
                        echo "Failed!\n";
                    } else {
                        echo $content["data"]["mnbudgetfinal"] . "\n";
                    }
                }
            } elseif ($response['http_code'] >= 400 && $response['http_code'] <= 499) {
                echo "Error (" . $response['http_code'] . ": " . $content['message'] . ")\n";
            } else {
                echo "Unknown (" . $response['http_code'] . ")\n";
                var_dump($response);
                var_dump($contentraw);
            }
        } else {
            echo "Error (empty result) [HTTP CODE " . $response['http_code'] . "]\n";
        }
    }
    if (count($dmnpidtorestart) > 0) {
        dmn_restartfrozen($dmnpidtorestart);
    }
}
function dmn_stop($uname, $conf)
{
    $testnet = $conf->getconfig('testnet') == 1;
    if ($testnet) {
        $testinfo = '/testnet3';
    } else {
        $testinfo = '';
    }
    $rpc = new \elbereth\EasyDash($conf->getconfig('rpcuser'), $conf->getconfig('rpcpassword'), 'localhost', $conf->getconfig('rpcport'));
    $pid = dmn_getpid($uname, $testnet);
    if ($pid !== false) {
        $tmp = $rpc->stop();
        if ($rpc->response['result'] != "DarkCoin server stopping" && $rpc->response['result'] != "Dash server stopping" && $rpc->response['result'] != "Dash Core server stopping") {
            echo "Unexpected daemon answer (" . $rpc->response['result'] . ") ";
        }
        usleep(250000);
        $waitcount = 0;
        while (dmn_checkpid($pid) && $waitcount < DMN_STOPWAIT) {
            usleep(1000000);
            $waitcount++;
            echo ".";
        }
        if (dmn_checkpid($pid)) {
            echo "Soft Stop Failed! Forcing Kill... ";
            exec('kill -s kill ' . $pid);
            $waitcount = 0;
            while (dmn_checkpid($pid) && $waitcount < DMN_STOPWAIT) {
                echo '.';
                usleep(1000000);
                $waitcount++;
            }
            if (dmn_checkpid($pid)) {
                echo "Failed!";
                $res = false;
            } else {
                if (file_exists('/home/' . $uname . "/.darkcoin{$testinfo}/darkcoind.pid")) {
                    unlink('/home/' . $uname . "/.darkcoin{$testinfo}/darkcoind.pid");
                }
                if (file_exists('/home/' . $uname . "/.dash{$testinfo}/dashd.pid")) {
                    unlink('/home/' . $uname . "/.dash{$testinfo}/dashd.pid");
                }
                echo "OK (Killed) ";
                $res = true;
            }
        } else {
            echo " OK (Soft Stop) ";
            $res = true;
        }
    } else {
        echo "NOT started ";
        $res = true;
    }
    return $res;
}