├── .gitignore ├── start_ninsoap.sh ├── ninupdates ├── send_irc.php ├── versionlist.php ├── http_pagelogger_cli.php ├── webhook.py ├── nzone │ └── nzone.php ├── ninsoap_ircbot.php ├── send_mastodon.py ├── db.php ├── manage_titledesc.php ├── deletereport.php ├── manage_consoles.php ├── postproc.php ├── parsesoap.php ├── weblogging.php ├── tweet.php ├── api_cli.php ├── get_officialchangelog_cli.php ├── manage_report_updatever.php ├── difflogs.php ├── merge_reports.php ├── aqua.py ├── send_notif.py ├── setup.php ├── api.php ├── config.php ├── http_pagelogger.php ├── get_officialchangelog.php ├── logs.php └── ninsoap.php ├── README ├── pub_html └── ninupdates │ ├── scanstatus.php │ ├── eshop │ ├── index.php │ └── verlist_parser.php │ ├── sendtweet.php │ ├── get_reportinfo.php │ ├── feed.php │ ├── updatedetails.php │ ├── title_setdesc.php │ ├── 3ds_nzonehotspots.php │ ├── reports.php │ └── titlelist.php └── checkurl_lastmodified.sh /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *~ 3 | *.pyc 4 | -------------------------------------------------------------------------------- /start_ninsoap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | cd /home/yellows8/ninupdates 4 | screen -S ninsoap -d -m php ninsoap.php 5 | 6 | -------------------------------------------------------------------------------- /ninupdates/send_irc.php: -------------------------------------------------------------------------------- 1 | \n"); 8 | exit(1); 9 | } 10 | 11 | for($i=2; $i<$argc; $i++) 12 | { 13 | appendmsg_tofile($argv[1], $argv[$i]); 14 | } 15 | 16 | ?> 17 | -------------------------------------------------------------------------------- /ninupdates/versionlist.php: -------------------------------------------------------------------------------- 1 | \n"); 12 | exit(1); 13 | } 14 | 15 | process_pagelogger("https://tagaya-ctr.cdn.nintendo.net/tagaya/versionlist", "$sitecfg_workdir/versionlist/ctr", "A new 3DS eShop VersionList was downloaded.", "$sitecfg_httpbase/eshop/", $argv[1]); 16 | 17 | ?> 18 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | These scripts check for Nintendo system updates, and generate reports of the updated titles. The base URL for the scripts under this pub_html directory must be specified with $sitecfg_httpbase in site_cfg.php. A configuration file must be located at ninupdates/site_cfg.php, see ninupdates/config.php. 2 | 3 | The required database tables are automatically created when running ninsoap.php (see comments in setup.php). However, additional configuration must be done seperately: run manage_consoles.php for each console (and manually set additional fields in the table-row if needed). Manually insert database rows for: ninupdates_regions, ninupdates_officialchangelog_pages (if wanted), ninupdates_wikiconfig (if wanted). 4 | 5 | -------------------------------------------------------------------------------- /ninupdates/http_pagelogger_cli.php: -------------------------------------------------------------------------------- 1 | [optional msgtarget]\n"); 12 | exit(1); 13 | } 14 | 15 | if($argc<7) 16 | { 17 | process_pagelogger($argv[1], $argv[2], $argv[3], $argv[4], $argv[5]); 18 | } 19 | else if($argc<8) 20 | { 21 | process_pagelogger($argv[1], $argv[2], $argv[3], $argv[4], $argv[5], $argv[6]); 22 | } 23 | else 24 | { 25 | process_pagelogger($argv[1], $argv[2], $argv[3], $argv[4], $argv[5], $argv[6], $argv[7]); 26 | } 27 | 28 | ?> 29 | -------------------------------------------------------------------------------- /pub_html/ninupdates/scanstatus.php: -------------------------------------------------------------------------------- 1 | \n"; 11 | $con .= "Nintendo System Update Last Scan\n"; 12 | 13 | $query="SELECT lastscan FROM ninupdates_management"; 14 | $result=mysqli_query($mysqldb, $query); 15 | $numrows=mysqli_num_rows($result); 16 | 17 | $lastscan = "N/A"; 18 | if($numrows>0) 19 | { 20 | $row = mysqli_fetch_row($result); 21 | $lastscan = $row[0]; 22 | } 23 | 24 | $con.= "Last scan datetime: " . $lastscan . "
\n"; 25 | 26 | $con.= ""; 27 | 28 | dbconnection_end(); 29 | 30 | echo $con; 31 | 32 | ?> 33 | -------------------------------------------------------------------------------- /checkurl_lastmodified.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | url="$1" 4 | filepath="$2" 5 | email="$3" 6 | msg_filepath="$4" 7 | msg_append="$5" 8 | 9 | curl --head $url | grep Last-Modified > ${filepath}new 10 | 11 | if [ $? -ne 0 ] 12 | then 13 | exit 1 14 | fi 15 | 16 | if [ -f $filepath ]; 17 | then 18 | cmp -s ${filepath}new ${filepath} 19 | if [ $? -eq 1 ] 20 | then 21 | echo "Change detected, sending notification(s)..." 22 | msg="Last-Modified for the following URL changed: $url" 23 | 24 | if [ -n "$msg_append" ] 25 | then 26 | msg="${msg} ${msg_append}" 27 | fi 28 | 29 | msg="${msg} Old: `cat ${filepath}` New: `cat ${filepath}new`" 30 | 31 | if [ -n "$msg_filepath" ] 32 | then 33 | echo $msg >> $msg_filepath 34 | fi 35 | 36 | if [ -n "$email" ] 37 | then 38 | echo $msg | mail -s "URL monitor script" $email 39 | fi 40 | fi 41 | fi 42 | 43 | mv ${filepath}new ${filepath} 44 | 45 | -------------------------------------------------------------------------------- /ninupdates/webhook.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import sys 3 | import requests 4 | 5 | # This should be set in webhook_config.py, or have an empty file to disable it. 6 | webhookcfg = None 7 | 8 | from webhook_config import * 9 | 10 | if webhookcfg is None: 11 | print("Webhook config is missing.") 12 | sys.exit(1) 13 | 14 | if len(sys.argv) < 2: 15 | print("Usage: %s [target_hook id]" % sys.argv[0]) 16 | sys.exit(1) 17 | 18 | target_hook = 0 19 | if len(sys.argv) >= 3: 20 | target_hook = int(sys.argv[2]) 21 | 22 | if target_hook >= len(webhookcfg): 23 | print("target_hook is out-of-bounds for the config.") 24 | sys.exit(1) 25 | 26 | headers = {'User-Agent': 'ninupdates-bot (https://github.com/yellows8/ninupdates/, 1.1.0)'} 27 | 28 | for hookcfg in webhookcfg[target_hook]: 29 | payload = {hookcfg['json_msg_field_name']: sys.argv[1]} 30 | r = requests.post(hookcfg['url'], headers=headers, json=payload) 31 | 32 | -------------------------------------------------------------------------------- /pub_html/ninupdates/eshop/index.php: -------------------------------------------------------------------------------- 1 | \n"; 15 | 16 | $con .= "eShop Scanning\n"; 17 | 18 | $con.= "$sitecfg_sitenav_headerHomepage -> eShop Scanning


\n"; 19 | 20 | $con.= "See here for 3DS eShop VersionList scanning. See here for VersionList parsing.

\n"; 21 | 22 | $con.= ""; 23 | 24 | dbconnection_end(); 25 | 26 | if($sitecfg_logplainhttp200!=0)writeNormalLog("RESULT: 200"); 27 | 28 | echo $con; 29 | 30 | ?> 31 | -------------------------------------------------------------------------------- /ninupdates/nzone/nzone.php: -------------------------------------------------------------------------------- 1 | \n \n "; 18 | foreach($f as $line) 19 | { 20 | switch($linenum++) 21 | { 22 | case 0: 23 | case 1: 24 | #echo $line; 25 | break; 26 | 27 | case 2: 28 | $arr = explode(',', trim($line, "\n")); 29 | unset($arr[3]); 30 | unset($arr[5]); 31 | echo " \n \n \n \n"; 32 | break; 33 | 34 | default: 35 | $arr = explode(',', trim($line, "\n")); 36 | $arr[0] = base64_decode(base64_fix($arr[0])); 37 | $arr[2] = base64_decode(base64_fix($arr[2])); 38 | unset($arr[3]); 39 | unset($arr[5]); 40 | echo " \n \n \n \n"; 41 | break; 42 | } 43 | } 44 | echo "
" . implode("", $arr) . "
" . implode("", $arr) . "
\n \n"; 45 | } 46 | ?> 47 | -------------------------------------------------------------------------------- /ninupdates/ninsoap_ircbot.php: -------------------------------------------------------------------------------- 1 | $sitecfg_workdir/ninsoap_ircbottmp"); 27 | echo "Total detected title-listing changes for each of the scanned platforms: "; 28 | system("grep -c \"System update available for regions\" $sitecfg_workdir/ninsoap_ircbottmp"); 29 | echo "Scan finished.\n"; 30 | 31 | dbconnection_end(); 32 | 33 | ?> 34 | -------------------------------------------------------------------------------- /ninupdates/send_mastodon.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import sys 3 | import os 4 | import argparse 5 | from mastodon import Mastodon 6 | 7 | parser = argparse.ArgumentParser(description='Send Fediverse/Mastodon-API-compatible messages.') 8 | parser.add_argument('msg', help='Notification message text.') 9 | parser.add_argument('--visibility', nargs='?', dest='visibility', help='String value for the visibility field, otherwise the account default is used.') 10 | parser.add_argument('--delete', nargs='?', dest='delete', help='If specified, this status id is deleted instead of posting the input message.') 11 | 12 | args = parser.parse_args() 13 | 14 | msg = args.msg 15 | visibility = args.visibility 16 | if visibility is not None and len(visibility)==0: 17 | visibility = None 18 | 19 | delete_id = args.delete 20 | if delete_id is not None and len(delete_id)==0: 21 | delete_id = None 22 | 23 | # This creds file should be located in the same directory as this script. 24 | credpath = os.path.join(os.path.realpath(os.path.dirname(__file__)), 'mastodon_usercred.secret') 25 | if os.path.isfile(credpath) is False: 26 | print("Mastodon creds file doesn't exist.") 27 | sys.exit(2) 28 | 29 | mastodon = Mastodon(access_token = credpath) 30 | 31 | if delete_id is None: 32 | mastodon.status_post(msg, visibility=visibility) 33 | else: 34 | mastodon.status_delete(delete_id) 35 | 36 | -------------------------------------------------------------------------------- /ninupdates/db.php: -------------------------------------------------------------------------------- 1 | 1)return; 13 | 14 | $password = file_get_contents($sitecfg_mysqldb_pwdpath); 15 | 16 | @$mysqldb = mysqli_connect("localhost", $sitecfg_mysqldb_username, $password, $sitecfg_mysqldb_database); 17 | if(mysqli_connect_errno())die("Failed to connect to mysql.\n"); 18 | } 19 | 20 | function dbconnection_end() 21 | { 22 | global $mysqldb, $dbconn_refcount; 23 | if($dbconn_refcount==0)return; 24 | $dbconn_refcount--; 25 | if($dbconn_refcount>0)return; 26 | @mysqli_close($mysqldb); 27 | } 28 | 29 | function db_checkmaintenance($abort) 30 | { 31 | global $mysqldb; 32 | 33 | $query="SELECT maintenanceflag FROM ninupdates_management"; 34 | $result=mysqli_query($mysqldb, $query); 35 | $numrows=mysqli_num_rows($result); 36 | if($numrows) 37 | { 38 | $row = mysqli_fetch_row($result); 39 | if($row[0]==1) 40 | { 41 | if($abort) 42 | { 43 | writeNormalLog("RESULT: 500"); 44 | 45 | dbconnection_end(); 46 | die("Site is currently under maintenance.\n"); 47 | } 48 | 49 | return 1; 50 | } 51 | } 52 | 53 | return 0; 54 | } 55 | 56 | ?> 57 | -------------------------------------------------------------------------------- /pub_html/ninupdates/sendtweet.php: -------------------------------------------------------------------------------- 1 | 63 | -------------------------------------------------------------------------------- /ninupdates/manage_titledesc.php: -------------------------------------------------------------------------------- 1 | \n"); 13 | exit(1); 14 | } 15 | 16 | dbconnection_start(); 17 | 18 | $titleid = ""; 19 | $desc = ""; 20 | $titleid = mysqli_real_escape_string($mysqldb, $argv[1]); 21 | if($argc > 2)$desc = mysqli_real_escape_string($mysqldb, $argv[2]); 22 | 23 | $query = "SELECT id, description FROM ninupdates_titleids WHERE titleid='" . $titleid . "'"; 24 | $result=mysqli_query($mysqldb, $query); 25 | $numrows=mysqli_num_rows($result); 26 | 27 | if($numrows==0) 28 | { 29 | dbconnection_end(); 30 | 31 | echo "Row for titleid not found.\n"; 32 | 33 | exit(2); 34 | } 35 | 36 | $row = mysqli_fetch_row($result); 37 | $rowid = $row[0]; 38 | $curdesc = $row[1]; 39 | 40 | if($curdesc==="" || $curdesc===NULL)$curdesc = "N/A"; 41 | 42 | if($desc==="")echo "$curdesc"; 43 | 44 | if($desc!=="") 45 | { 46 | $query = "UPDATE ninupdates_titleids SET description='".$desc."' WHERE id=$rowid"; 47 | $result=mysqli_query($mysqldb, $query); 48 | 49 | writeNormalLog("manage_titledesc: CHANGED TID $titleid DESC TO $desc."); 50 | } 51 | 52 | dbconnection_end(); 53 | 54 | ?> 55 | -------------------------------------------------------------------------------- /ninupdates/deletereport.php: -------------------------------------------------------------------------------- 1 | \n"); 10 | exit(1); 11 | } 12 | 13 | dbconnection_start(); 14 | 15 | $reportdate = mysqli_real_escape_string($mysqldb, $argv[1]); 16 | $system = mysqli_real_escape_string($mysqldb, $argv[2]); 17 | 18 | $query="SELECT ninupdates_reports.id FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.reportdate='".$reportdate."' && ninupdates_consoles.system='".$system."' && ninupdates_reports.systemid=ninupdates_consoles.id"; 19 | $result=mysqli_query($mysqldb, $query); 20 | $numrows=mysqli_num_rows($result); 21 | 22 | if($numrows==0) 23 | { 24 | dbconnection_end(); 25 | echo("Failed to find the specified report with the input system.\n"); 26 | exit(2); 27 | } 28 | 29 | $row = mysqli_fetch_row($result); 30 | $reportid = $row[0]; 31 | 32 | $query="DELETE FROM ninupdates_titles WHERE reportid=$reportid"; 33 | $result=mysqli_query($mysqldb, $query); 34 | 35 | $query="DELETE FROM ninupdates_systitlehashes WHERE reportid=$reportid"; 36 | $result=mysqli_query($mysqldb, $query); 37 | 38 | $query="DELETE FROM ninupdates_officialchangelogs WHERE reportid=$reportid"; 39 | $result=mysqli_query($mysqldb, $query); 40 | 41 | $query="DELETE FROM ninupdates_reports WHERE id=$reportid"; 42 | $result=mysqli_query($mysqldb, $query); 43 | 44 | dbconnection_end(); 45 | 46 | ?> 47 | -------------------------------------------------------------------------------- /ninupdates/manage_consoles.php: -------------------------------------------------------------------------------- 1 | {optional regions}\n"); 10 | exit(1); 11 | } 12 | 13 | dbconnection_start(); 14 | 15 | $system = mysqli_real_escape_string($mysqldb, $argv[1]); 16 | $sysname = mysqli_real_escape_string($mysqldb, $argv[2]); 17 | $clientcertfn = mysqli_real_escape_string($mysqldb, $argv[3]); 18 | $clientprivfn = mysqli_real_escape_string($mysqldb, $argv[4]); 19 | $nushttpsurl = mysqli_real_escape_string($mysqldb, $argv[5]); 20 | $platformid = mysqli_real_escape_string($mysqldb, $argv[6]); 21 | 22 | if($argc<8) 23 | { 24 | $regions = "EPJCKAT"; 25 | } 26 | else 27 | { 28 | $regions = mysqli_real_escape_string($mysqldb, $argv[7]); 29 | } 30 | 31 | $path = "$sitecfg_workdir/soap$system"; 32 | 33 | if(!is_dir($path)) mkdir($path, 0760); 34 | 35 | for($i=0; $i 50 | -------------------------------------------------------------------------------- /ninupdates/postproc.php: -------------------------------------------------------------------------------- 1 | \n"); 10 | exit(1); 11 | } 12 | 13 | dbconnection_start(); 14 | 15 | $reportdate = mysqli_real_escape_string($mysqldb, $argv[1]); 16 | $system = mysqli_real_escape_string($mysqldb, $argv[2]); 17 | 18 | $query="SELECT ninupdates_reports.id FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.reportdate='".$reportdate."' && ninupdates_reports.postproc_runfinished=0 && ninupdates_consoles.system='".$system."' && ninupdates_reports.systemid=ninupdates_consoles.id"; 19 | $result=mysqli_query($mysqldb, $query); 20 | $numrows=mysqli_num_rows($result); 21 | 22 | if($numrows==0) 23 | { 24 | dbconnection_end(); 25 | echo("Failed to find the specified report with the input system, where the postproc_runfinished flag is set to 0.\n"); 26 | exit(2); 27 | } 28 | 29 | $row = mysqli_fetch_row($result); 30 | $reportid = $row[0]; 31 | 32 | $postproc_runfinished_updateval = 1; 33 | 34 | if(!isset($sitecfg_postproc_cmd)) 35 | { 36 | echo "Config for sitecfg_postproc_cmd is not set, no command will be executed.\n"; 37 | } 38 | else 39 | { 40 | $retval = 0; 41 | system("$sitecfg_postproc_cmd $reportdate $system", $retval); 42 | if($retval!==0)$postproc_runfinished_updateval = 0; 43 | } 44 | 45 | if($postproc_runfinished_updateval===1) 46 | { 47 | $query="UPDATE ninupdates_reports SET ninupdates_reports.postproc_runfinished=1 WHERE ninupdates_reports.id=$reportid"; 48 | $result=mysqli_query($mysqldb, $query); 49 | 50 | $msg = "$sitecfg_httpbase/titlelist.php?date=$reportdate&sys=$system&csv=1"; 51 | $tmp_cmd = "echo '" . $msg . "' >> $sitecfg_workdir/lastupdates_postproc_csvurls"; 52 | system($tmp_cmd); 53 | } 54 | 55 | dbconnection_end(); 56 | 57 | ?> 58 | -------------------------------------------------------------------------------- /ninupdates/parsesoap.php: -------------------------------------------------------------------------------- 1 | \n"); 10 | exit(1); 11 | } 12 | 13 | dbconnection_start(); 14 | 15 | $soapdata = file_get_contents($argv[1]); 16 | $system = mysqli_real_escape_string($mysqldb, $argv[2]); 17 | $reportdate = mysqli_real_escape_string($mysqldb, $argv[3]); 18 | $region = mysqli_real_escape_string($mysqldb, $argv[4]); 19 | 20 | if($soapdata===FALSE) 21 | { 22 | dbconnection_end(); 23 | echo "Failed to read the soapdata.\n"; 24 | exit(2); 25 | } 26 | 27 | $query="SELECT id FROM ninupdates_consoles WHERE system='".$system."'"; 28 | $result=mysqli_query($mysqldb, $query); 29 | 30 | $numrows=mysqli_num_rows($result); 31 | if($numrows==0) 32 | { 33 | dbconnection_end(); 34 | echo "The specified system is invalid.\n"; 35 | exit(3); 36 | } 37 | 38 | $row = mysqli_fetch_row($result); 39 | $systemid = $row[0]; 40 | 41 | $query="SELECT id, curdate FROM ninupdates_reports WHERE systemid='".$systemid."' && reportdate='".$reportdate."'"; 42 | $result=mysqli_query($mysqldb, $query); 43 | 44 | $numrows=mysqli_num_rows($result); 45 | if($numrows==0) 46 | { 47 | dbconnection_end(); 48 | echo "Failed to find the specified report.\n"; 49 | exit(4); 50 | } 51 | 52 | $row = mysqli_fetch_row($result); 53 | $reportid = $row[0]; 54 | $dbcurdate = $row[1]; 55 | 56 | $sysupdate_systitlehashes = array(); 57 | 58 | init_titlelistarray(); 59 | parse_soapresp($soapdata, 0); 60 | 61 | $tmpval = titlelist_dbupdate(); 62 | echo "Total titles added by titlelist_dbupdate(): $tmpval\n"; 63 | 64 | if($tmpval) 65 | { 66 | $query="UPDATE ninupdates_titles SET reportid=$reportid WHERE curdate='".$dbcurdate."' && reportid=0 && systemid=$systemid && region='".$region."'"; 67 | $result=mysqli_query($mysqldb, $query); 68 | } 69 | 70 | dbconnection_end(); 71 | 72 | ?> 73 | -------------------------------------------------------------------------------- /ninupdates/weblogging.php: -------------------------------------------------------------------------------- 1 | 74 | -------------------------------------------------------------------------------- /pub_html/ninupdates/get_reportinfo.php: -------------------------------------------------------------------------------- 1 | 80 | -------------------------------------------------------------------------------- /ninupdates/tweet.php: -------------------------------------------------------------------------------- 1 | setApiVersion('2'); 29 | 30 | return 0; 31 | } 32 | 33 | function sendtweet($msg) 34 | { 35 | $ret = tweet_init($connection); 36 | 37 | if($ret == 0) 38 | { 39 | $out = $connection->post("tweets", ["text" => $msg], $json = true); 40 | $statuscode = $connection->getLastHttpCode(); 41 | 42 | if($statuscode != 200 && $statuscode != 201) 43 | { 44 | echo "sendtweet(): request failed, got HTTP status-code: $statuscode.\n"; 45 | var_dump($out); 46 | $ret = 3; 47 | } 48 | } 49 | 50 | return $ret; 51 | } 52 | 53 | function tweet_delete($in_id) 54 | { 55 | $ret = tweet_init($connection); 56 | 57 | if($ret == 0) 58 | { 59 | $out = $connection->delete("tweets/$in_id"); 60 | $statuscode = $connection->getLastHttpCode(); 61 | 62 | if($statuscode != 200 && $statuscode != 201) 63 | { 64 | echo "tweet_delete(): request failed, got HTTP status-code: $statuscode.\n"; 65 | var_dump($out); 66 | $ret = 3; 67 | } 68 | } 69 | 70 | return $ret; 71 | } 72 | 73 | if($_SERVER['SCRIPT_NAME'] === "tweet.php") 74 | { 75 | if($argc<2) 76 | { 77 | echo("Usage:\nphp tweet.php [if specified, delete this id instead]\n"); 78 | exit(1); 79 | } 80 | 81 | if($argc==2) 82 | { 83 | sendtweet($argv[1]); 84 | } 85 | else 86 | { 87 | tweet_delete($argv[2]); 88 | } 89 | } 90 | 91 | ?> 92 | -------------------------------------------------------------------------------- /pub_html/ninupdates/feed.php: -------------------------------------------------------------------------------- 1 | 23 | 24 | 25 | Sysupdate Reports 26 | 27 | $sitecfg_httpbase/reports.php 28 | Nintendo System Update Reports 29 | $curdate 30 | en 31 | "; 32 | 33 | $query="SELECT ninupdates_reports.reportdate, ninupdates_reports.updateversion, ninupdates_consoles.system, ninupdates_reports.reportdaterfc FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.log='report' && ninupdates_reports.systemid=ninupdates_consoles.id ORDER BY ninupdates_reports.curdate DESC LIMIT 4"; 34 | $result=mysqli_query($mysqldb, $query); 35 | $numrows=mysqli_num_rows($result); 36 | 37 | for($i=0; $i<$numrows; $i++) 38 | { 39 | $row = mysqli_fetch_row($result); 40 | $reportdate = $row[0]; 41 | $updateversion = $row[1]; 42 | $system = $row[2]; 43 | $curdate = gmdate(DATE_RSS, date_timestamp_get(date_create_from_format(DateTimeInterface::RFC822, $row[3]))); 44 | 45 | $sys = getsystem_sysname($system); 46 | 47 | $item_title = "$sys $updateversion"; 48 | if($updateversion=="N/A")$item_title = "$sys $reportdate"; 49 | 50 | $url = "$sitecfg_httpbase/reports.php?date=$reportdate&sys=$system"; 51 | $url = ""; 52 | //$url = str_replace ("&","",htmlspecialchars(strip_tags($url))); 53 | 54 | $con .= " 55 | $item_title 56 | $url 57 | $url 58 | $item_title 59 | $curdate 60 | \n"; 61 | } 62 | 63 | $con.= " 64 | "; 65 | 66 | dbconnection_end(); 67 | 68 | if($sitecfg_logplainhttp200!=0)writeNormalLog("RESULT: 200"); 69 | echo $con; 70 | 71 | ?> 72 | -------------------------------------------------------------------------------- /ninupdates/api_cli.php: -------------------------------------------------------------------------------- 1 | \n"; 12 | echo "Options:\n--format=csv\n--prevreport=\n--prevtitlever=\n"; 13 | exit(1); 14 | } 15 | 16 | $outformat = "plain"; 17 | $prevreport = ""; 18 | $prevtitlever = ""; 19 | 20 | $select_previousentry = 0; 21 | 22 | if($argc>=7) 23 | { 24 | for($argi=6; $argi<$argc; $argi++) 25 | { 26 | if($argv[$argi] === "--format=csv")$outformat = "csv"; 27 | if(substr($argv[$argi], 0, 13) === "--prevreport=")$prevreport = substr($argv[$argi], 13); 28 | if(substr($argv[$argi], 0, 15) === "--prevtitlever=")$prevtitlever = substr($argv[$argi], 15); 29 | } 30 | } 31 | 32 | $retval = ninupdates_api($argv[1], $argv[2], $argv[3], $argv[4], $argv[5], $prevreport); 33 | if($retval!=0) 34 | { 35 | echo("API returned error $retval.\n"); 36 | exit($retval); 37 | } 38 | 39 | if($outformat === "csv") 40 | { 41 | echo "Title version,Report date,Update version\n"; 42 | } 43 | 44 | if($prevreport!=="" && $prevtitlever!=="") 45 | { 46 | echo "prevreport and prevtitlever can't be used at same time.\n"; 47 | exit(1); 48 | } 49 | 50 | if($prevreport!=="" || $prevtitlever!=="")$select_previousentry = 1; 51 | 52 | if($select_previousentry === 1 && $prevreport==="" && $ninupdatesapi_out_total_entries<2) 53 | { 54 | echo "prev-entry was specified but there's less than 2 output entries.\n"; 55 | exit(1); 56 | } 57 | 58 | $version = ""; 59 | $reportdate = ""; 60 | $updateversion = ""; 61 | $foundflag = 0; 62 | 63 | for($i=0; $i<$ninupdatesapi_out_total_entries; $i++) 64 | { 65 | $prev_version = $version; 66 | $prev_reportdate = $reportdate; 67 | $prev_updateversion = $updateversion; 68 | 69 | $version = $ninupdatesapi_out_version_array[$i]; 70 | $reportdate = $ninupdatesapi_out_reportdate_array[$i]; 71 | $updateversion = $ninupdatesapi_out_updateversion_array[$i]; 72 | 73 | if($select_previousentry === 1 && $i>0) 74 | { 75 | if($prevtitlever!=="" && $version === $prevtitlever) 76 | { 77 | $foundflag = 1; 78 | 79 | $version = $prev_version; 80 | $reportdate = $prev_reportdate; 81 | $updateversion = $prev_updateversion; 82 | } 83 | } 84 | 85 | if($select_previousentry === 0 || $foundflag===1 || $prevreport!=="") 86 | { 87 | if($outformat === "plain")echo "ent $i: titleversion = $version, reportdate = $reportdate, updateversion = $updateversion.\n"; 88 | 89 | if($outformat === "csv")echo "$version,$reportdate,$updateversion\n"; 90 | } 91 | 92 | if($foundflag===1)break; 93 | } 94 | 95 | if($select_previousentry === 1 && ($foundflag===0 && $prevreport==="")) 96 | { 97 | echo "Specified prev-entry not found.\n"; 98 | exit(1); 99 | } 100 | 101 | ?> 102 | -------------------------------------------------------------------------------- /ninupdates/get_officialchangelog_cli.php: -------------------------------------------------------------------------------- 1 | = $len)break; 47 | 48 | if($sysupdate_regions[$pos]==',')$pos++; 49 | } 50 | 51 | if($num_pages===0) 52 | { 53 | echo "No pages found for reportdate=".$sysupdate_timestamp." system=".$system.", updating updatever_autoset...\n"; 54 | $query="UPDATE ninupdates_reports, ninupdates_consoles SET ninupdates_reports.updatever_autoset=2 WHERE ninupdates_reports.reportdate='".$sysupdate_timestamp."' AND ninupdates_reports.systemid=ninupdates_consoles.id AND ninupdates_consoles.system='".$system."'"; 55 | $result=mysqli_query($mysqldb, $query); 56 | } 57 | } 58 | 59 | $query="SELECT COUNT(*) FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.updatever_autoset=1 AND ninupdates_reports.wikibot_runfinished=0 AND ninupdates_reports.systemid=ninupdates_consoles.id"; 60 | $result=mysqli_query($mysqldb, $query); 61 | $numrows=mysqli_num_rows($result); 62 | 63 | if($numrows>0) 64 | { 65 | $row = mysqli_fetch_row($result); 66 | $count = $row[0]; 67 | 68 | if($count>0) 69 | { 70 | echo "Starting a wikibot task for processing $count report(s)...\n"; 71 | 72 | $wikibot_timestamp = date("m-d-y_h-i-s"); 73 | 74 | system("php $sitecfg_workdir/wikibot.php scheduled > $sitecfg_workdir/wikibot_out/$wikibot_timestamp 2>&1 &"); 75 | } 76 | } 77 | 78 | dbconnection_end(); 79 | 80 | ?> 81 | -------------------------------------------------------------------------------- /pub_html/ninupdates/updatedetails.php: -------------------------------------------------------------------------------- 1 | \nNintendo System Update Report Update Details\n"; 71 | 72 | $con.= "$sitecfg_sitenav_headerHomepage -> "; 73 | if($reportdate!="")$con.= "$reportname report -> "; 74 | $con.= "Update details"; 75 | $con.= "


\n"; 76 | 77 | $details_path = "$sitecfg_workdir/updatedetails/$system/$reportdate"; 78 | 79 | $details_exists = file_exists($details_path); 80 | if($details_exists===TRUE)$updatedetails_text = file_get_contents($details_path); 81 | 82 | if($details_exists===FALSE || $updatedetails_text===FALSE) 83 | { 84 | dbconnection_end(); 85 | writeNormalLog("UPDATEDETAILS FOR THIS REPORT N/A. RESULT: 200"); 86 | echo "Update-details are not available for this report.\n"; 87 | return; 88 | } 89 | 90 | $con.= nl2br($updatedetails_text); 91 | 92 | $con.= "\n"; 93 | 94 | dbconnection_end(); 95 | 96 | if($sitecfg_logplainhttp200!=0)writeNormalLog("RESULT: 200"); 97 | 98 | echo $con; 99 | 100 | ?> 101 | -------------------------------------------------------------------------------- /pub_html/ninupdates/title_setdesc.php: -------------------------------------------------------------------------------- 1 |
"; 46 | } 47 | 48 | if(!isset($_REQUEST['desc'])) 49 | { 50 | $con = "\nNintendo System Update Set Title Description 51 |
52 | $curdesc 53 | Changes will be messaged to the admin.
Description:
Token:
"; 54 | 55 | dbconnection_end(); 56 | if($sitecfg_logplainhttp200!=0)writeNormalLog("RESULT: 200"); 57 | echo $con; 58 | } 59 | else 60 | { 61 | $tokpath = "$sitecfg_workdir/title_setdesc_authtoken"; 62 | $cmptoken = ""; 63 | if(file_exists($tokpath)!==FALSE)$cmptoken = file_get_contents($tokpath); 64 | if($cmptoken==="")$cmptoken = FALSE; 65 | if($cmptoken===FALSE) 66 | { 67 | header("Content-Type: text/plain"); 68 | echo "Access denied, the internal token is missing.\n"; 69 | writeNormalLog("ATTEMPTED TO CHANGE TITLEDESC BUT CMP TOKEN MISSING, DENIED: $desc. RESULT: 302"); 70 | return; 71 | } 72 | 73 | if(strcmp($intoken,$cmptoken)!==0) 74 | { 75 | header("Content-Type: text/plain"); 76 | echo "Access denied.\n"; 77 | writeNormalLog("ATTEMPTED TO CHANGE TITLEDESC BUT TOKEN IS INVALID, DENIED: $desc. RESULT: 302"); 78 | return; 79 | } 80 | 81 | $desc = strip_tags($desc); 82 | 83 | while(1) 84 | { 85 | $pos = strpos($desc, ","); 86 | if($pos === FALSE)break; 87 | $desc[$pos] = " "; 88 | } 89 | 90 | $query = "UPDATE ninupdates_titleids SET description='".$desc."' WHERE id=$rowid"; 91 | $result=mysqli_query($mysqldb, $query); 92 | dbconnection_end(); 93 | 94 | $msg = "title_setdesc.php: desc for TID $titleid changed to: $desc"; 95 | send_notif([$msg, "--admin"]); 96 | header("Location: reports.php"); 97 | writeNormalLog("CHANGED TID $titleid DESC TO $desc. RESULT: 302"); 98 | } 99 | 100 | ?> 101 | -------------------------------------------------------------------------------- /ninupdates/manage_report_updatever.php: -------------------------------------------------------------------------------- 1 | [Options]\nOptions:\n--updatever=\n--updatever_autoset=\n--wikibot_runfinished=\n--wikipage_exists=\n"); 10 | exit(1); 11 | } 12 | 13 | dbconnection_start(); 14 | 15 | $system = mysqli_real_escape_string($mysqldb, $argv[1]); 16 | $reportdate = mysqli_real_escape_string($mysqldb, $argv[2]); 17 | 18 | $updatever = ""; 19 | $updatever_autoset = ""; 20 | $wikibot_runfinished = ""; 21 | $wikipage_exists = ""; 22 | 23 | if($argc > 3) 24 | { 25 | for($i=3; $i<$argc; $i++) 26 | { 27 | $argend = strpos($argv[$i], "="); 28 | if($argend!==FALSE) 29 | { 30 | $argval = mysqli_real_escape_string($mysqldb, substr($argv[$i], $argend+1)); 31 | if(substr($argv[$i], 0, $argend) === "--updatever") 32 | { 33 | $updatever = $argval; 34 | } 35 | else if(substr($argv[$i], 0, $argend) === "--updatever_autoset") 36 | { 37 | $updatever_autoset = $argval; 38 | } 39 | else if(substr($argv[$i], 0, $argend) === "--wikibot_runfinished") 40 | { 41 | $wikibot_runfinished = $argval; 42 | } 43 | else if(substr($argv[$i], 0, $argend) === "--wikipage_exists") 44 | { 45 | $wikipage_exists = $argval; 46 | } 47 | } 48 | } 49 | } 50 | 51 | $query="SELECT id FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$system."'"; 52 | $result=mysqli_query($mysqldb, $query); 53 | $numrows=mysqli_num_rows($result); 54 | 55 | if($numrows==0) 56 | { 57 | dbconnection_end(); 58 | echo("Failed to find the specified system.\n"); 59 | exit(2); 60 | } 61 | 62 | $row = mysqli_fetch_row($result); 63 | $systemid = $row[0]; 64 | 65 | $query="SELECT ninupdates_reports.id, ninupdates_reports.updateversion FROM ninupdates_reports WHERE ninupdates_reports.reportdate='".$reportdate."' && ninupdates_reports.systemid=$systemid"; 66 | $result=mysqli_query($mysqldb, $query); 67 | $numrows=mysqli_num_rows($result); 68 | 69 | if($numrows==0) 70 | { 71 | dbconnection_end(); 72 | echo("Failed to find the specified report with the input system.\n"); 73 | exit(3); 74 | } 75 | 76 | $row = mysqli_fetch_row($result); 77 | $reportid = $row[0]; 78 | $report_updatever = $row[1]; 79 | 80 | $ret=0; 81 | 82 | if($argc == 3) 83 | { 84 | echo($report_updatever); 85 | } 86 | else 87 | { 88 | $logmsg = "manage_report_updatever: CHANGED REPORT $reportdate-$system: "; 89 | $query = "UPDATE ninupdates_reports SET "; 90 | 91 | $cnt=0; 92 | if($updatever!=="") 93 | { 94 | $query.= "updateversion='".$updatever."'"; 95 | $logmsg.= "updatever = \"$updatever\""; 96 | $cnt++; 97 | } 98 | 99 | $concatstr = ""; 100 | if($updatever_autoset!=="") 101 | { 102 | if($cnt>0) 103 | { 104 | $concatstr = ", "; 105 | } 106 | $query.= $concatstr . "updatever_autoset=".$updatever_autoset.""; 107 | $logmsg.= $concatstr . "updatever_autoset=".$updatever_autoset; 108 | $cnt++; 109 | } 110 | if($wikibot_runfinished!=="") 111 | { 112 | if($cnt>0) 113 | { 114 | $concatstr = ", "; 115 | } 116 | $query.= $concatstr . "wikibot_runfinished=".$wikibot_runfinished.""; 117 | $logmsg.= $concatstr . "wikibot_runfinished=".$wikibot_runfinished; 118 | $cnt++; 119 | } 120 | if($wikipage_exists!=="") 121 | { 122 | if($cnt>0) 123 | { 124 | $concatstr = ", "; 125 | } 126 | $query.= $concatstr . "wikipage_exists=".$wikipage_exists.""; 127 | $logmsg.= $concatstr . "wikipage_exists=".$wikipage_exists; 128 | $cnt++; 129 | } 130 | 131 | if($cnt==0) 132 | { 133 | echo("Unrecognized args.\n"); 134 | $ret = 4; 135 | } 136 | else 137 | { 138 | $query.= " WHERE id=$reportid"; 139 | $result=mysqli_query($mysqldb, $query); 140 | 141 | writeNormalLog($logmsg); 142 | } 143 | } 144 | 145 | dbconnection_end(); 146 | exit($ret); 147 | 148 | ?> 149 | -------------------------------------------------------------------------------- /ninupdates/difflogs.php: -------------------------------------------------------------------------------- 1 | 1) 14 | { 15 | if($argv[1]=="--insertdblog" && $argc>=5) 16 | { 17 | $arg_difflog = $argv[2]; 18 | $arg_diffsys = $argv[3]; 19 | $arg_diffregion = $argv[4]; 20 | if($argc>=6)$arg_logpath = $argv[5]; 21 | } 22 | else if($argv[1]=="--difflogs" && $argc>=5) 23 | { 24 | $arg_difflogold = $argv[2]; 25 | $arg_difflognew = $argv[3]; 26 | $arg_diffsys = $argv[4]; 27 | if($argc>=6)$arg_diffregion = $argv[5]; 28 | } 29 | } 30 | 31 | if($arg_difflog=="" && $arg_difflognew=="")return; 32 | 33 | $system = $arg_diffsys; 34 | 35 | dbconnection_start(); 36 | 37 | if($arg_difflog!="")diffinsert_main(); 38 | if($arg_difflognew!="")difflogshtml(); 39 | 40 | dbconnection_end(); 41 | 42 | function diffinsert_main() 43 | { 44 | global $mysqldb, $dbcurdate, $arg_difflog, $arg_diffregion, $system, $reportid, $arg_logpath; 45 | 46 | $query = "SELECT ninupdates_reports.curdate, ninupdates_reports.id FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.reportdate='".$arg_difflog."' && ninupdates_consoles.system='".$system."' && ninupdates_reports.systemid=ninupdates_consoles.id"; 47 | $result=mysqli_query($mysqldb, $query); 48 | $numrows=mysqli_num_rows($result); 49 | $reportid = 0; 50 | 51 | if($numrows) 52 | { 53 | $row = mysqli_fetch_row($result); 54 | $dbcurdate = $row[0]; 55 | $reportid = $row[1]; 56 | } 57 | else 58 | { 59 | $query = "SELECT now()"; 60 | $result=mysqli_query($mysqldb, $query); 61 | $row = mysqli_fetch_row($result); 62 | $dbcurdate = $row[0]; 63 | } 64 | 65 | if($arg_diffregion=="") 66 | { 67 | if($arg_logpath!=="") 68 | { 69 | echo "Can't use arg_logpath without input region.\n"; 70 | return; 71 | } 72 | $query="SELECT regions FROM ninupdates_consoles WHERE system='".$system."'"; 73 | $result=mysqli_query($mysqldb, $query); 74 | $row = mysqli_fetch_row($result); 75 | $regions = $row[0]; 76 | 77 | for($i=0; $i 166 | -------------------------------------------------------------------------------- /ninupdates/merge_reports.php: -------------------------------------------------------------------------------- 1 | \n"); 10 | exit(1); 11 | } 12 | 13 | dbconnection_start(); 14 | 15 | $system = mysqli_real_escape_string($mysqldb, $argv[1]); 16 | $dst_reportdate = mysqli_real_escape_string($mysqldb, $argv[2]); 17 | $src_reportdate = mysqli_real_escape_string($mysqldb, $argv[3]); 18 | 19 | $query="SELECT id FROM ninupdates_consoles WHERE system='".$system."'"; 20 | $result=mysqli_query($mysqldb, $query); 21 | $numrows=mysqli_num_rows($result); 22 | 23 | if($numrows==0) 24 | { 25 | dbconnection_end(); 26 | echo("Failed to find the specified system.\n"); 27 | exit(2); 28 | } 29 | 30 | $row = mysqli_fetch_row($result); 31 | $systemid = $row[0]; 32 | 33 | $query="SELECT ninupdates_reports.id, ninupdates_reports.curdate, ninupdates_reports.regions FROM ninupdates_reports WHERE ninupdates_reports.reportdate='".$dst_reportdate."' && ninupdates_reports.systemid=$systemid"; 34 | $result=mysqli_query($mysqldb, $query); 35 | $numrows=mysqli_num_rows($result); 36 | 37 | if($numrows==0) 38 | { 39 | dbconnection_end(); 40 | echo("Failed to find the specified dst-report with the input system.\n"); 41 | exit(3); 42 | } 43 | 44 | $row = mysqli_fetch_row($result); 45 | $dst_reportid = $row[0]; 46 | $dst_reportcurdate = $row[1]; 47 | $dst_regions = $row[2]; 48 | 49 | $query="SELECT ninupdates_reports.id, ninupdates_reports.curdate, ninupdates_reports.regions FROM ninupdates_reports WHERE ninupdates_reports.reportdate='".$src_reportdate."' && ninupdates_reports.systemid=$systemid"; 50 | $result=mysqli_query($mysqldb, $query); 51 | $numrows=mysqli_num_rows($result); 52 | 53 | if($numrows==0) 54 | { 55 | dbconnection_end(); 56 | echo("Failed to find the specified src-report with the input system.\n"); 57 | exit(4); 58 | } 59 | 60 | $row = mysqli_fetch_row($result); 61 | $src_reportid = $row[0]; 62 | $src_reportcurdate = $row[1]; 63 | $src_regions = $row[2]; 64 | 65 | $query="SELECT regions FROM ninupdates_consoles WHERE id='".$systemid."'"; 66 | $result=mysqli_query($mysqldb, $query); 67 | $numrows=mysqli_num_rows($result); 68 | 69 | if($numrows==0) 70 | { 71 | dbconnection_end(); 72 | echo("Failed to load the regions field for this system.\n"); 73 | exit(5); 74 | } 75 | 76 | $row = mysqli_fetch_row($result); 77 | $regions = $row[0]; 78 | 79 | $query = "UPDATE ninupdates_titles SET reportid='".$dst_reportid."', curdate='".$dst_reportcurdate."' WHERE curdate='".$src_reportcurdate."' && reportid='".$src_reportid."' && systemid=$systemid"; 80 | $result=mysqli_query($mysqldb, $query); 81 | if($result===FALSE) 82 | { 83 | dbconnection_end(); 84 | echo("Failed to update ninupdates_titles.\n"); 85 | exit(6); 86 | } 87 | 88 | $query = "UPDATE ninupdates_systitlehashes SET reportid='".$dst_reportid."' WHERE reportid='".$src_reportid."'"; 89 | $result=mysqli_query($mysqldb, $query); 90 | if($result===FALSE) 91 | { 92 | dbconnection_end(); 93 | echo("Failed to update ninupdates_systitlehashes.\n"); 94 | exit(7); 95 | } 96 | 97 | $query = "UPDATE ninupdates_officialchangelogs SET reportid='".$dst_reportid."' WHERE reportid='".$src_reportid."'"; 98 | $result=mysqli_query($mysqldb, $query); 99 | if($result===FALSE) 100 | { 101 | dbconnection_end(); 102 | echo("Failed to update ninupdates_officialchangelogs.\n"); 103 | exit(8); 104 | } 105 | 106 | $new_regions = ""; 107 | 108 | for($i=0; $i 168 | -------------------------------------------------------------------------------- /pub_html/ninupdates/3ds_nzonehotspots.php: -------------------------------------------------------------------------------- 1 | \nNintendo Zone Hotspots\n"; 104 | $con.= " 105 | 106 | 107 | 108 | 109 | \n"; 110 | 111 | for($i=0; $i<$total_entries; $i++) 112 | { 113 | $url = "reports.php?date=".$reportdate_array[$i]."&sys=ctr"; 114 | $path = "$sitecfg_workdir/nzone/hotspotconf/" . $version_array[$i] . "_hotspot.conf"; 115 | $parsetext = "N/A"; 116 | 117 | if(file_exists($path)) 118 | { 119 | $urlparse = "3ds_nzonehotspots.php?version=" . $version_array[$i]; 120 | $parsetext = "Available"; 121 | } 122 | 123 | $con.= "\n"; 124 | $con.= "\n"; 125 | $con.= "\n"; 126 | $con.= "\n"; 127 | $con.= "\n"; 128 | } 129 | $con .= "
Title versionUpdate version + reportParsed data
".$version_array[$i]."".$updateversion_array[$i]."$parsetext
"; 130 | 131 | echo $con; 132 | 133 | return; 134 | } 135 | else 136 | { 137 | $found = 0; 138 | for($i=0; $i<$total_entries; $i++) 139 | { 140 | if($version_array[$i] == $reqversion) 141 | { 142 | $found = 1; 143 | break; 144 | } 145 | } 146 | 147 | if(!$found) 148 | { 149 | header("Location: 3ds_nzonehotspots.php"); 150 | writeNormalLog("THE INPUT NZONE HOTSPOT VERSION DOES NOT EXIST IN THE DB. RESULT: 302"); 151 | 152 | return; 153 | } 154 | 155 | $path = "$sitecfg_workdir/nzone/hotspotconf/" . $reqversion . "_hotspot.conf"; 156 | if(!file_exists($path)) 157 | { 158 | header("Location: 3ds_nzonehotspots.php"); 159 | writeNormalLog("THE INPUT NZONE HOTSPOT VERSION DOES NOT HAVE A _hotspot.conf WHICH EXISTS. RESULT: 302"); 160 | 161 | return; 162 | } 163 | 164 | parse_hotspotconf($path); 165 | } 166 | 167 | ?> 168 | -------------------------------------------------------------------------------- /ninupdates/aqua.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import sys 3 | import struct 4 | import os 5 | import requests 6 | import argparse 7 | import json 8 | import csv 9 | import re 10 | from datetime import datetime, date, time, timezone 11 | 12 | from proc_config import * 13 | 14 | datadir = sys.argv[1] 15 | storage_path = "%s/storage.json" % (datadir) 16 | csvpath = "%s/tmp.csv" % (datadir) 17 | 18 | if os.path.exists(datadir) == False: 19 | os.mkdir(datadir) 20 | 21 | storage = {} 22 | storage["data"] = [] 23 | if os.path.isfile(storage_path) is True: 24 | if os.path.getsize(storage_path) > 0: 25 | with open(storage_path, 'r') as json_f: 26 | storage = json.load(json_f) 27 | 28 | useragent = "NintendoSDK Firmware/%s (platform:NX; did:%s; eid:%s)" % (useragent_fw, deviceid, eid) 29 | 30 | r = requests.get("https://aqua.hac.%s.d4c.nintendo.net/required_system_update_meta?device_id=%s" % (eid, deviceid), headers={"User-Agent": useragent, "Accept": "application/json"}, timeout=10, verify=False, cert=(tlsclient_certpath, tlsclient_privkpath)) 31 | aqua_resp = {"status": r.status_code, "httpdata": r.text, "headers": r.headers} 32 | r.raise_for_status() 33 | aqua_json = r.json() 34 | 35 | print(aqua_resp) 36 | print(aqua_json) 37 | 38 | title_id = aqua_json["contents_delivery_required_title_id"] 39 | title_ver = aqua_json["contents_delivery_required_title_version"] 40 | print("%s %d" % (title_id, title_ver)) 41 | 42 | if len(title_id) != 16 or re.search('[0-9a-f]{16}$', title_id) is None: 43 | print("Bad title_id.") 44 | sys.exit(1) 45 | 46 | lastmod = None 47 | if "last-modified" in aqua_resp["headers"]: 48 | lastmod = aqua_resp["headers"]["last-modified"] 49 | print(lastmod) 50 | lastmod_datetime = datetime.strptime(lastmod, '%a, %d %b %Y %H:%M:%S %Z') 51 | lastmod_datestr = '{0:%B} {1}, {0:%Y}'.format(lastmod_datetime, lastmod_datetime.day) 52 | 53 | found = False 54 | for entry in storage["data"]: 55 | tmp_json = json.JSONDecoder() 56 | tmp_json = tmp_json.decode(entry["httpdata"]) 57 | tmp_title_id = tmp_json["contents_delivery_required_title_id"] 58 | tmp_title_ver = tmp_json["contents_delivery_required_title_version"] 59 | if tmp_title_id == title_id and tmp_title_ver == title_ver: 60 | found = True 61 | break 62 | 63 | if found is True: 64 | sys.exit(0) 65 | 66 | storage["data"].append(aqua_resp) 67 | 68 | with open(storage_path, 'w') as json_f: 69 | json.dump(storage, json_f) 70 | 71 | if len(storage["data"]) <= 1: 72 | sys.exit(0) 73 | 74 | msg = "The required sysver returned by aqua for eShop content download changed: v%d" % (title_ver) 75 | 76 | reportdate = None 77 | updateversion = None 78 | 79 | ret = os.system("php /home/yellows8/ninupdates/api_cli.php gettitleversions hac ALL %s 0 --format=csv > %s" % (title_id, csvpath)) 80 | if ret!=0: 81 | print("api_cli failed: %d" % (ret)) 82 | msg += "." 83 | else: 84 | with open(csvpath) as csvfile: 85 | csvrd = csv.reader(csvfile) 86 | cnt=0 87 | for row in csvrd: 88 | cnt = cnt + 1 89 | if cnt==1: 90 | continue 91 | ver = row[0] 92 | if ver[0]=='v': 93 | ver = ver[1:] 94 | ver = int(ver) 95 | if ver == title_ver: 96 | reportdate = row[1] 97 | updateversion = row[2] 98 | msg += ", for sysupdate: https://yls8.mtheall.com/ninupdates/reports.php?date=%s&sys=hac" % (reportdate) 99 | break 100 | 101 | if lastmod is not None: 102 | msg += " Last-Modified: %s" % (lastmod) 103 | 104 | if lastmod is not None and reportdate is not None and updateversion is not None: 105 | wikigen_path = "%s/%s_wikigen.json" % (datadir, reportdate) 106 | print("Writing wikigen to the following path, and then running the wikibot: %s" % (wikigen_path)) 107 | 108 | pos = updateversion.find('_rebootless') 109 | if pos!=-1: 110 | updateversion_norebootless = updateversion[:pos] 111 | else: 112 | updateversion_norebootless = updateversion 113 | 114 | prefix = "On %s (UTC), the required" % (lastmod_datestr) 115 | 116 | wikigen = [] 117 | 118 | page = { 119 | "page_title": updateversion_norebootless, 120 | "search_section": "update was released", 121 | "targets": [ 122 | { 123 | "search_section_end": "\n==Change-log==", 124 | "text_sections": [ 125 | { 126 | "search_text": prefix, 127 | "insert_text": "%s system-version returned by [[Network|aqua]] for eShop contents-download was updated to this sysver (%s).\n" % (prefix, updateversion), 128 | }, 129 | ], 130 | }, 131 | ], 132 | } 133 | wikigen.append(page) 134 | 135 | with open(wikigen_path, 'w') as json_f: 136 | json.dump(wikigen, json_f) 137 | 138 | os.system("php /home/yellows8/ninupdates/wikibot.php hac '--wikigen=%s' >> /home/yellows8/ninupdates/debuglogs/wikibot_aqua_wikigen_log 2>&1 &" % (wikigen_path)) 139 | 140 | print("Sending notifs with msg: %s" % msg) 141 | 142 | ret = os.system("cd /home/yellows8/ninupdates/ && ./send_notif.py \"%s\" --social --webhook >> /home/yellows8/ninupdates/sendnotif_log 2>&1 &" % (msg)) 143 | sys.exit(ret) 144 | 145 | -------------------------------------------------------------------------------- /ninupdates/send_notif.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | import sys 3 | import os 4 | import argparse 5 | from shlex import quote 6 | import asyncio 7 | 8 | notif_config_admin = None 9 | 10 | try: 11 | from notif_config import * 12 | except ImportError: 13 | pass 14 | 15 | parser = argparse.ArgumentParser(description='Send notification messages.') 16 | parser.add_argument('msg', help='Notification message text.') 17 | parser.add_argument('--irctarget', nargs='*', dest='irctarget', help='Target IRC filename. Multiple filenames can be specified as seperate args following --irctarget.') 18 | parser.add_argument('--irc', nargs='?', dest='irc', const='', help='Send IRC notification, with optional message text which overrides msg.') 19 | parser.add_argument('--fedi', nargs='?', dest='fedi', const='', help='Send Fediverse/Mastodon-API-compatible notification, with optional message text which overrides msg.') 20 | parser.add_argument('--fedivisibility', nargs='?', dest='fedivisibility', help='String value for the visibility field (with --fedi), otherwise the account default is used.') 21 | parser.add_argument('--twitter', nargs='?', dest='twitter', const='', help='Send Twitter notification, with optional message text which overrides msg.') 22 | parser.add_argument('--webhook', nargs='?', dest='webhook', const='', help='Send webhook notification, with optional message text which overrides msg.') 23 | parser.add_argument('--webhooktarget', dest='webhooktarget', help='Webhook target_hook id.') 24 | parser.add_argument('--social', nargs='?', dest='social', const='', help='Send social notification, with optional message text which overrides msg. Same as specifying --fediverse and --twitter, those args can optionally be used seperately if overriding the msg is desired.') 25 | parser.add_argument('--admin', nargs='?', dest='admin', const='', help='Send admin notification, with optional message text which overrides msg. Alias which sends notifs with targets specified by config. Other args if specified will override any fields loaded from config.') 26 | 27 | args = parser.parse_args() 28 | 29 | msg = args.msg 30 | 31 | irc_target = None 32 | irc_msg = None 33 | 34 | fedi_msg = None 35 | fedivisibility = None 36 | twitter_msg = None 37 | 38 | webhook_msg = None 39 | webhooktarget = None 40 | 41 | admin_msg = None 42 | if args.admin is not None: 43 | admin_msg = args.admin 44 | if len(admin_msg)==0: 45 | admin_msg = msg 46 | if notif_config_admin is None: 47 | print("Admin notifs are not available since the config isn't set.") 48 | else: 49 | if 'irc' in notif_config_admin: 50 | irc_msg = admin_msg 51 | irc_target = notif_config_admin['irc'] 52 | if 'fedi' in notif_config_admin: 53 | fedi_msg = admin_msg 54 | if 'msg_prefix' in notif_config_admin['fedi']: 55 | fedi_msg = "%s %s" % (notif_config_admin['fedi']['msg_prefix'], fedi_msg) 56 | if 'visibility' in notif_config_admin['fedi']: 57 | fedivisibility = notif_config_admin['fedi']['visibility'] 58 | if 'webhook' in notif_config_admin: 59 | webhook_msg = admin_msg 60 | webhooktarget = notif_config_admin['webhook'] 61 | 62 | if args.irctarget is not None: 63 | irc_target = args.irctarget 64 | if args.irc is not None: 65 | irc_msg = args.irc 66 | if irc_target is None or irc_msg is None: 67 | irc_msg = None 68 | else: 69 | if len(irc_msg)==0: 70 | irc_msg = msg 71 | 72 | social_msg = args.social 73 | if social_msg is not None: 74 | if len(social_msg)==0: 75 | social_msg = msg 76 | fedi_msg = social_msg 77 | twitter_msg = social_msg 78 | 79 | if args.fedi is not None: 80 | fedi_msg = args.fedi 81 | if fedi_msg is not None and len(fedi_msg)==0: 82 | fedi_msg = msg 83 | 84 | if args.fedivisibility is not None: 85 | fedivisibility = args.fedivisibility 86 | if len(fedivisibility)==0: 87 | fedivisibility = None 88 | 89 | if args.twitter is not None: 90 | twitter_msg = args.twitter 91 | if twitter_msg is not None and len(twitter_msg)==0: 92 | twitter_msg = msg 93 | 94 | if args.webhook is not None: 95 | webhook_msg = args.webhook 96 | if len(webhook_msg)==0: 97 | webhook_msg = msg 98 | 99 | if args.webhooktarget is not None: 100 | webhooktarget = args.webhooktarget 101 | 102 | async def run_notif(program, *args): 103 | proc = await asyncio.create_subprocess_exec( 104 | program, *args) 105 | return await proc.communicate() 106 | 107 | notifcnt=0 108 | 109 | if irc_msg is not None: 110 | notifcnt=notifcnt+1 111 | asyncio.run(run_notif("php", "send_irc.php", irc_msg, *irc_target)) 112 | 113 | if fedi_msg is not None: 114 | notifcnt=notifcnt+1 115 | args = [sys.executable, "./send_mastodon.py"] 116 | if fedivisibility is not None: 117 | args.append("--visibility") 118 | args.append(fedivisibility) 119 | args.append(fedi_msg) 120 | asyncio.run(run_notif(*args)) 121 | 122 | if twitter_msg is not None: 123 | notifcnt=notifcnt+1 124 | asyncio.run(run_notif("php", "tweet.php", twitter_msg)) 125 | 126 | if webhook_msg is not None: 127 | notifcnt=notifcnt+1 128 | args = ["./webhook.py", webhook_msg] 129 | if webhooktarget is not None: 130 | args.append(webhooktarget) 131 | asyncio.run(run_notif(sys.executable, *args)) 132 | 133 | if notifcnt==0: 134 | if admin_msg is not None: 135 | tmp = " --admin was specified, but the admin config didn't specify any targets." 136 | else: 137 | tmp = "" 138 | print("No notif was sent, notif targets must be specified.%s" % (tmp)) 139 | sys.exit(1) 140 | 141 | -------------------------------------------------------------------------------- /ninupdates/setup.php: -------------------------------------------------------------------------------- 1 | 157 | -------------------------------------------------------------------------------- /ninupdates/api.php: -------------------------------------------------------------------------------- 1 | 2) 24 | { 25 | dbconnection_end(); 26 | return 1; 27 | } 28 | 29 | if($ninupdatesapi_in_command!=="gettitleversions") 30 | { 31 | dbconnection_end(); 32 | return 2; 33 | } 34 | 35 | $query="SELECT id FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$ninupdatesapi_in_sys."'"; 36 | $result=mysqli_query($mysqldb, $query); 37 | 38 | $numrows=mysqli_num_rows($result); 39 | if($numrows==0) 40 | { 41 | dbconnection_end(); 42 | return 3; 43 | } 44 | 45 | $row = mysqli_fetch_row($result); 46 | $system = $row[0]; 47 | 48 | $query = "SELECT id FROM ninupdates_titleids WHERE ninupdates_titleids.titleid='".$ninupdatesapi_in_titleid."'"; 49 | $result=mysqli_query($mysqldb, $query); 50 | $numrows=mysqli_num_rows($result); 51 | 52 | if($numrows==0) 53 | { 54 | dbconnection_end(); 55 | return 4; 56 | } 57 | 58 | $row = mysqli_fetch_row($result); 59 | $rowid = $row[0]; 60 | 61 | if(strlen($ninupdatesapi_in_region)>1) 62 | { 63 | $query = "SELECT regioncode FROM ninupdates_regions WHERE ninupdates_regions.regionid='".$ninupdatesapi_in_region."'"; 64 | $result=mysqli_query($mysqldb, $query); 65 | $numrows=mysqli_num_rows($result); 66 | 67 | if($numrows==0) 68 | { 69 | dbconnection_end(); 70 | return 4; 71 | } 72 | 73 | $row = mysqli_fetch_row($result); 74 | $ninupdatesapi_in_region = $row[0]; 75 | } 76 | 77 | if($ninupdatesapi_in_reportdate!=="") 78 | { 79 | $query = "SELECT curdate FROM ninupdates_reports WHERE ninupdates_reports.reportdate='".$ninupdatesapi_in_reportdate."'"; 80 | $result=mysqli_query($mysqldb, $query); 81 | $numrows=mysqli_num_rows($result); 82 | 83 | if($numrows==0) 84 | { 85 | dbconnection_end(); 86 | return 5; 87 | } 88 | 89 | $row = mysqli_fetch_row($result); 90 | $curdate = $row[0]; 91 | } 92 | 93 | $versionquery = "GROUP_CONCAT(DISTINCT ninupdates_titles.version ORDER BY ninupdates_titles.version SEPARATOR ','),"; 94 | $reportdatequery = "GROUP_CONCAT(DISTINCT ninupdates_reports.reportdate ORDER BY ninupdates_reports.curdate SEPARATOR ','),"; 95 | $updateverquery = "GROUP_CONCAT(DISTINCT ninupdates_reports.updateversion ORDER BY ninupdates_reports.curdate SEPARATOR ',')"; 96 | 97 | $query = "SELECT $versionquery $reportdatequery $updateverquery FROM ninupdates_titles, ninupdates_reports WHERE ninupdates_titles.tid=$rowid && ninupdates_titles.region='".$ninupdatesapi_in_region."' && ninupdates_titles.systemid=$system && ninupdates_reports.id=ninupdates_titles.reportid"; 98 | 99 | if($ninupdatesapi_in_reportdate!=="") 100 | { 101 | $query.= " && ninupdates_reports.curdate < '".$curdate."'"; 102 | } 103 | 104 | $result=mysqli_query($mysqldb, $query); 105 | $numrows=mysqli_num_rows($result); 106 | 107 | if($numrows==0) 108 | { 109 | dbconnection_end(); 110 | return 5; 111 | } 112 | 113 | $row = mysqli_fetch_row($result); 114 | $versions = $row[0]; 115 | $reportdates = $row[1]; 116 | $updateversions = $row[2]; 117 | 118 | dbconnection_end(); 119 | 120 | $ninupdatesapi_out_total_entries = 0; 121 | $ninupdatesapi_out_version_array = array(); 122 | $ninupdatesapi_out_reportdate_array = array(); 123 | $ninupdatesapi_out_updateversion_array = array(); 124 | 125 | if($versions===NULL || $reportdates===NULL || $updateversions===NULL) return 6; 126 | 127 | $ver = strtok($versions, ","); 128 | while($ver!==FALSE) 129 | { 130 | $ninupdatesapi_out_version_array[] = "v$ver"; 131 | $ninupdatesapi_out_total_entries++; 132 | $ver = strtok(","); 133 | } 134 | 135 | $cur_reportdate = strtok($reportdates, ","); 136 | while($cur_reportdate!==FALSE) 137 | { 138 | $ninupdatesapi_out_reportdate_array[] = $cur_reportdate; 139 | $cur_reportdate = strtok(","); 140 | } 141 | 142 | $updatever = strtok($updateversions, ","); 143 | while($updatever!==FALSE) 144 | { 145 | $ninupdatesapi_out_updateversion_array[] = $updatever; 146 | $updatever = strtok(","); 147 | } 148 | 149 | if($ninupdatesapi_in_filterent!=0 && $ninupdatesapi_out_total_entries>0) 150 | { 151 | if($ninupdatesapi_in_filterent==1)$index = 0; 152 | if($ninupdatesapi_in_filterent==2)$index = $ninupdatesapi_out_total_entries-1; 153 | 154 | $tmp = $ninupdatesapi_out_version_array[$index]; 155 | $ninupdatesapi_out_version_array = array(); 156 | $ninupdatesapi_out_version_array[] = $tmp; 157 | 158 | $tmp = $ninupdatesapi_out_reportdate_array[$index]; 159 | $ninupdatesapi_out_reportdate_array = array(); 160 | $ninupdatesapi_out_reportdate_array[] = $tmp; 161 | 162 | $tmp = $ninupdatesapi_out_updateversion_array[$index]; 163 | $ninupdatesapi_out_updateversion_array = array(); 164 | $ninupdatesapi_out_updateversion_array[] = $tmp; 165 | 166 | $ninupdatesapi_out_total_entries = 1; 167 | } 168 | 169 | return 0; 170 | } 171 | 172 | ?> 173 | -------------------------------------------------------------------------------- /pub_html/ninupdates/eshop/verlist_parser.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 17 | 18 | 19 | 56 | Back 57 | Invalid version list

\n"); 60 | else 61 | { 62 | $data = array(); 63 | 64 | foreach($from as $key => $value) 65 | $data[$key] = array('from' => 'N/A', 'to' => 'N/A'); 66 | foreach($to as $key => $value) 67 | $data[$key] = array('from' => 'N/A', 'to' => 'N/A'); 68 | 69 | foreach($from as $key => $value) 70 | $data[$key]['from'] = (string)$value; 71 | foreach($to as $key => $value) 72 | $data[$key]['to'] = (string)$value; 73 | 74 | ksort($data); 75 | ?> 76 | 77 | 78 | 79 | 80 | 81 | 82 | $value) 84 | { 85 | if($value['from'] != $value['to']) 86 | { 87 | printf(" \n"); 88 | printf(" \n", $key); 89 | printf(" \n", $value['from']); 90 | printf(" \n", $value['to']); 91 | printf(" \n"); 92 | } 93 | } 94 | ?> 95 |
TIDFromTo
%016X%s%s
96 | Invalid version list

\n"); 104 | else 105 | { 106 | ?> 107 | 108 | $value) 110 | { 111 | printf(" \n", 112 | $key, $value); 113 | } 114 | ?> 115 |
%016X%lu
116 | 134 |
135 | 136 | 137 | 138 | 139 | 140 | 141 | \n"); 145 | printf(" \n", $file); 146 | printf(" \n", $file); 147 | printf(" \n", 148 | urlencode($file), htmlentities($file)); 149 | printf(" \n"); 150 | } 151 | ?> 152 |
FromToDate
%s
153 |
154 | 155 |
156 |
157 | 222 | 225 | 226 | 227 | 228 | -------------------------------------------------------------------------------- /ninupdates/config.php: -------------------------------------------------------------------------------- 1 | . 17 | $sitecfg_homepage_footer Optional HTML to include at the very end of the "reports.php"(homepage) . 18 | $sitecfg_reportupdatepage_header Optional HTML to include near the beginning of the reports.php report update-pages . 19 | $sitecfg_reportupdatepage_footer Optional HTML to include at the very end of the reports.php report update-pages . 20 | $sitecfg_sitenav_header Optional HTML to include immediately before the site navigation-bar. 21 | 22 | $sitecfg_irc_msg_dirpath Dirpath used when sending IRC messages with appendmsg_tofile, if not specified this functionality is disabled. 23 | $sitecfg_irc_msgtargets["{system}"]= "{filename}"; IRC msgtarget filename to use with the specified system, if not specified IRC messages are disabled. This is used for sysupdate-detected notifs. 24 | $sitecfg_irc_msgtarget Similar to sitecfg_irc_msgtargets, except this is an optional string filename to use for all systems. 25 | $sitecfg_irc_msgtargets_whitelist Array of strings for filenames allowed to be used by appendmsg_tofile. If not specified, this is loaded from sitecfg_irc_msgtarget(s). 'msgme' is hard-coded to be allowed regardless. 26 | 27 | $sitecfg_notif_fedi_append Optional string, if set " " followed by this string is appended to fedi notifications. Only used for the main sysupdate-detected notif. This can be used for hashtags for example. 28 | $sitecfg_notif_fedi_append_system["{system}"]= "{str}"; Similar to sitecfg_notif_fedi_append, except this is an array of append-strings to use with the specified system. Handled following sitecfg_notif_fedi_append. 29 | 30 | $sitecfg_postproc_cmd This is the command which will be executed by postproc.php, if this is set. The full command passed to system() is: "$sitecfg_postproc_cmd $reportdate $system". 31 | 32 | $sitecfg_load_titlelist_cmd See ninsoap.php. 33 | 34 | $sitecfg_consoles_deviceid["{system}"]["{regioncode}"] = "{id}"; DeviceId to use, overrides the value from the db. 35 | 36 | $sitecfg_wiki_consoles_pageprefix["{system}"] = "prefix"; Optional page-title prefix to use with wiki for the specified system, where needed: "{prefix}{pagetitle}". 37 | $sitecfg_wiki_consoles_tag["{system}"] = "[tag]"; Optional tag text for use with wiki for the specified system, where needed. Used to identify the system on wiki. 38 | */ 39 | 40 | require_once(dirname(__FILE__) . "/site_cfg.php"); 41 | 42 | if(!isset($sitecfg_remotecmd))$sitecfg_remotecmd = 0; 43 | if(!isset($sitecfg_target_email))$sitecfg_target_email = ""; 44 | if(!isset($sitecfg_emailhost))$sitecfg_emailhost = ""; 45 | if(!isset($sitecfg_sshhost))$sitecfg_sshhost = ""; 46 | if(!isset($sitecfg_logplainhttp200))$sitecfg_logplainhttp200 = 0; 47 | if(!isset($sitecfg_homepage_header))$sitecfg_homepage_header = ""; 48 | if(!isset($sitecfg_homepage_footer))$sitecfg_homepage_footer = ""; 49 | if(!isset($sitecfg_reportupdatepage_header))$sitecfg_reportupdatepage_header = ""; 50 | if(!isset($sitecfg_reportupdatepage_footer))$sitecfg_reportupdatepage_footer = ""; 51 | if(!isset($sitecfg_sitenav_header))$sitecfg_sitenav_header = ""; 52 | 53 | if(!isset($sitecfg_irc_msg_dirpath))$sitecfg_irc_msg_dirpath = ""; 54 | if(!isset($sitecfg_irc_msgtargets))$sitecfg_irc_msgtargets = array(); 55 | if(!isset($sitecfg_irc_msgtarget))$sitecfg_irc_msgtarget = ""; 56 | 57 | function appendmsg_tofile($msg, $filename) 58 | { 59 | global $sitecfg_remotecmd, $sitecfg_sshhost, $sitecfg_irc_msg_dirpath, $sitecfg_irc_msgtarget, $sitecfg_irc_msgtargets, $sitecfg_irc_msgtargets_whitelist; 60 | 61 | if($sitecfg_irc_msg_dirpath!="" && strlen($filename)>0) 62 | { 63 | if(!isset($sitecfg_irc_msgtargets_whitelist)) 64 | { 65 | $sitecfg_irc_msgtargets_whitelist = array(); 66 | if(strlen($sitecfg_irc_msgtarget)>0) $sitecfg_irc_msgtargets_whitelist[] = $sitecfg_irc_msgtarget; 67 | foreach($sitecfg_irc_msgtargets as $target) 68 | { 69 | if(strlen($target)>0) 70 | { 71 | $sitecfg_irc_msgtargets_whitelist[] = $target; 72 | } 73 | } 74 | } 75 | 76 | $found = False; 77 | if($filename == "msgme") 78 | { 79 | $found = True; 80 | } 81 | else 82 | { 83 | foreach($sitecfg_irc_msgtargets_whitelist as $target) 84 | { 85 | if(strlen($target)>0 && $target == $filename) 86 | { 87 | $found = True; 88 | break; 89 | } 90 | } 91 | } 92 | if($found===False) 93 | { 94 | echo "appendmsg_tofile(): The specified filename is not whitelisted, msg will not be sent: $filename\n"; 95 | return; 96 | } 97 | 98 | $tmp_cmd = "echo " . escapeshellarg($msg) . " >> " . escapeshellarg("$sitecfg_irc_msg_dirpath/$filename"); 99 | $irc_syscmd = $tmp_cmd; 100 | if($sitecfg_remotecmd==1)$irc_syscmd = "ssh yellows8@$sitecfg_sshhost \"".$tmp_cmd."\""; 101 | system($irc_syscmd); 102 | } 103 | } 104 | 105 | function send_notif($args) 106 | { 107 | global $sitecfg_workdir; 108 | 109 | $cmd = "cd $sitecfg_workdir && "; 110 | $cmd .= $sitecfg_workdir . "/send_notif.py"; 111 | foreach($args as $arg) 112 | { 113 | if(strlen($arg)>0) 114 | { 115 | $cmd.= " " . escapeshellarg($arg); 116 | } 117 | } 118 | $cmd.= " >> $sitecfg_workdir/sendnotif_log 2>&1 &"; 119 | system($cmd); 120 | } 121 | 122 | ?> 123 | -------------------------------------------------------------------------------- /ninupdates/http_pagelogger.php: -------------------------------------------------------------------------------- 1 | "); 68 | if($pos!==FALSE && $posend!==FALSE) 69 | { 70 | $buf = substr($buf, 0, $pos) . substr($buf, $posend+9); 71 | } 72 | else 73 | { 74 | break; 75 | } 76 | } 77 | 78 | $pos = strpos($buf, '
'); 79 | if($pos!==FALSE) $posend = strpos($buf, "
", $pos); 80 | if($pos!==FALSE && $posend!==FALSE) 81 | { 82 | $buf = substr($buf, $pos, $posend+10-$pos); 83 | } 84 | } 85 | 86 | $lastmod_dateid = hash('sha256', $buf); 87 | echo "Last-Modified not available, using hash: $lastmod_dateid\n"; 88 | } 89 | 90 | return $buf; 91 | } 92 | 93 | function sendnotif_pagelogger($msg, $enable_notification, $msgtarget) 94 | { 95 | if($enable_notification>=1) 96 | { 97 | $args = [$msg, "--social"]; 98 | if($enable_notification & (1<<2)) // Previously val1. Use bit2 to avoid collisions with old values. 99 | { 100 | $args[] = "--irc"; 101 | $args[] = "--irctarget=$msgtarget"; 102 | } 103 | if($enable_notification & (1<<1)) $args[] = "--webhook"; // Previously val3. 104 | if($enable_notification & (1<<3)) $args[] = "--fedivisibility=unlisted"; 105 | send_notif($args); 106 | } 107 | } 108 | 109 | function process_pagelogger($url, $datadir, $msgprefix, $msgurl, $enable_notification, $msgtarget = "msg3dsdev", $filterjs = "0") 110 | { 111 | global $httpstat_pagelogger, $lastmod_dateid, $lastmod; 112 | 113 | $enable_notification = intval($enable_notification); 114 | 115 | if(!is_dir($datadir)) mkdir($datadir, 0775); 116 | 117 | $curtime = time(); 118 | init_curl_pagelogger(); 119 | $buf = send_httprequest_pagelogger($url, $filterjs); 120 | close_curl_pagelogger(); 121 | if($httpstat_pagelogger == "0")return 5;//Return immediately when the HTTP request failed. 122 | 123 | $httpstat_file = "$datadir/httpstat"; 124 | 125 | $httpstat_prev = FALSE; 126 | if(file_exists($httpstat_file)===TRUE)$httpstat_prev = file_get_contents($httpstat_file); 127 | 128 | if($httpstat_pagelogger == 200 || $httpstat_pagelogger == 403 || $httpstat_pagelogger == 404)//Only keep track of status-code changes between these (otherwise this might catch server-side issues). 129 | { 130 | $f = fopen($httpstat_file, "w"); 131 | fwrite($f, $httpstat_pagelogger); 132 | fclose($f); 133 | 134 | if($httpstat_prev!==FALSE && $httpstat_prev!=$httpstat_pagelogger) 135 | { 136 | $msg = "The HTTP response status-code changed from $httpstat_prev to $httpstat_pagelogger, with the following URL: $url"; 137 | echo "$msg\n"; 138 | 139 | sendnotif_pagelogger($msg, $enable_notification, $msgtarget); 140 | } 141 | } 142 | 143 | if($httpstat_pagelogger!="200") 144 | { 145 | echo "Request for the pagelogger with url \"$url\" failed: HTTP $httpstat_pagelogger.\n"; 146 | return 4; 147 | } 148 | 149 | $path = "$datadir/$lastmod_dateid"; 150 | 151 | if(file_exists($path)===TRUE)return 0;//Already have this page revision. 152 | 153 | echo "This revision doesn't exist locally, saving it + sending notification...\n"; 154 | 155 | $f = fopen($path, "w"); 156 | fwrite($f, $buf); 157 | fclose($f); 158 | 159 | if($enable_notification>=1) 160 | { 161 | if($lastmod!==-1) 162 | { 163 | $msg_text = "Last-Modified: " . gmdate(DATE_RFC822, $lastmod); 164 | } 165 | else 166 | { 167 | $msg_text = "Request timestamp: " . gmdate(DATE_RFC822, $curtime); 168 | } 169 | $msg = "$msgprefix " . $msg_text . ". $msgurl"; 170 | 171 | sendnotif_pagelogger($msg, $enable_notification, $msgtarget); 172 | } 173 | else 174 | { 175 | echo "Notification sending is disabled.\n"; 176 | } 177 | 178 | return 0; 179 | } 180 | 181 | ?> 182 | -------------------------------------------------------------------------------- /ninupdates/get_officialchangelog.php: -------------------------------------------------------------------------------- 1 | ", "", $changelog); 83 | $display_html = strip_tags($display_html); 84 | while(strpos($display_html, "\\n\\n")!==FALSE)$display_html = str_replace("\\n\\n", "\\n", $display_html);//Don't allow multiple consecutive newlines. 85 | $display_html = str_replace("\\n", "
\\n", $display_html); 86 | 87 | if(substr($display_html, 0, 7) == "
\\n")$display_html = substr($display_html, 7, strlen($display_html)-7);//Remove any newline that occurs at the very beginning. 88 | 89 | $wiki_text = ""; 90 | $wiki_text_tmp = strip_tags($display_html); 91 | 92 | $basepos = 0; 93 | $findpos = 0; 94 | 95 | $findpos = strpos($wiki_text_tmp, "\\n", $basepos); 96 | while($findpos!==FALSE) 97 | { 98 | $wiki_text.= "* ".substr($wiki_text_tmp, $basepos, $findpos-$basepos)."\n"; 99 | $basepos = 2+$findpos; 100 | $findpos = strpos($wiki_text_tmp, "\\n", $basepos); 101 | } 102 | 103 | $query="SELECT id FROM ninupdates_officialchangelogs WHERE pageid=$pageid && reportid=$reportid"; 104 | $result=mysqli_query($mysqldb, $query); 105 | 106 | $numrows=mysqli_num_rows($result); 107 | if($numrows>0) 108 | { 109 | $query="UPDATE ninupdates_officialchangelogs SET ninsite_html='".$changelog."', display_html='".$display_html."', wiki_text='".$wiki_text."' WHERE pageid=$pageid && reportid=$reportid"; 110 | $result=mysqli_query($mysqldb, $query); 111 | } 112 | else 113 | { 114 | $query = "INSERT INTO ninupdates_officialchangelogs (pageid, reportid, ninsite_html, display_html, wiki_text) VALUES ($pageid, $reportid, '".$changelog."', '".$display_html."', '".$wiki_text."')"; 115 | $result=mysqli_query($mysqldb, $query); 116 | } 117 | } 118 | 119 | function get_ninsite_changelog($reportdate, $system, $pageurl, $pageid) 120 | { 121 | global $mysqldb, $httpstat_getchangelog; 122 | 123 | $query="SELECT id FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$system."'"; 124 | $result=mysqli_query($mysqldb, $query); 125 | 126 | $numrows=mysqli_num_rows($result); 127 | if($numrows==0) 128 | { 129 | echo getofficalchangelog_writelog("The specified system is invalid.", 0, $reportdate); 130 | return 1; 131 | } 132 | 133 | $row = mysqli_fetch_row($result); 134 | $systemid = $row[0]; 135 | 136 | $query="SELECT updateversion, id FROM ninupdates_reports WHERE ninupdates_reports.reportdate='".$reportdate."' && ninupdates_reports.systemid=$systemid"; 137 | $result=mysqli_query($mysqldb, $query); 138 | 139 | $numrows=mysqli_num_rows($result); 140 | if($numrows==0) 141 | { 142 | getofficalchangelog_writelog("The specified report was not found.", 0, $reportdate); 143 | return 2; 144 | } 145 | 146 | $row = mysqli_fetch_row($result); 147 | $updateversion = $row[0]; 148 | $reportid = $row[1]; 149 | 150 | $updateversion_set = False; 151 | if($updateversion != "N/A" && $updateversion != "Initial scan" && $updateversion != "Initial_scan") 152 | { 153 | getofficalchangelog_writelog("The updateversion for the specified report is already set, continuing anyway.", 0, $reportdate); 154 | //return 3; 155 | $updateversion_set = True; 156 | } 157 | 158 | if(ctype_alpha($updateversion[strlen($updateversion)-1]) === TRUE)$updateversion = substr($updateversion, 0, strlen($updateversion)-1); 159 | 160 | init_curl_getchangelog(); 161 | $replydata = send_httprequest_getchangelog($pageurl); 162 | close_curl_getchangelog(); 163 | 164 | $changelog_switch_flag = 0; 165 | if($httpstat_getchangelog!="200") 166 | { 167 | getofficalchangelog_writelog("Request to the sysupdate list page failed.", 0, $reportdate); 168 | return 4; 169 | } 170 | else 171 | { 172 | echo "Successfully received the sysupdate list page.\n"; 173 | 174 | $str = FALSE;//strstr($replydata, ">Version");//The Nintendo .uk and .jp sites are not supported with this. 175 | if($str===FALSE) 176 | { 177 | $str = strstr($replydata, "

Improvements Included in Version "); 178 | if($str===FALSE)//Updated site 179 | { 180 | $str = strstr($replydata, "
"); 181 | if($str!==FALSE) $str = strstr($str, "

"); 183 | if($str!==FALSE) $str = substr($str, 2); 184 | 185 | if($str===FALSE) 186 | { 187 | getofficalchangelog_writelog("Failed to find version string.", 0, $reportdate); 188 | return 5; 189 | } 190 | 191 | if($str!==FALSE) 192 | { 193 | $changelog = strstr($str, "

"); 194 | if($changelog!==FALSE) $changelog = substr($changelog, 10); 195 | if($changelog!==FALSE) 196 | { 197 | $posend = strpos($changelog, "
"); 198 | if($posend!==FALSE)$changelog = substr($changelog, 0, $posend); 199 | $posend = strpos($changelog, "

"); 209 | $len = 5; 210 | if($changelog[$len] == "\\n")$len++; 211 | if($changelog!==FALSE) 212 | { 213 | $posend = strpos($changelog, "

Improvements Included"); 214 | if($posend===FALSE) $posend = strpos($changelog, "
  • "); 231 | $str = substr($str, 0, $posend); 232 | } 233 | } 234 | else 235 | { 236 | $len = 10; 237 | $changelog = strstr($str, "
  • ");//3DS 238 | if($changelog!==FALSE) 239 | { 240 | $posend = strpos($changelog, "

    "); 241 | if($posend!==FALSE) 242 | { 243 | $changelog = substr($changelog, $len, $posend-$len); 244 | } 245 | else 246 | { 247 | $changelog = FALSE; 248 | } 249 | } 250 | else//WiiU 251 | { 252 | $changelog = strstr($str, ""); 253 | 254 | if($changelog!==FALSE) 255 | { 256 | $len = 5; 257 | if(strpos($changelog, "

    Released")!==FALSE) 258 | { 259 | $val = strpos($changelog, "

    "); 260 | if($val===FALSE) 261 | { 262 | $changelog = FALSE; 263 | } 264 | else 265 | { 266 | $len = 5 + $val; 267 | } 268 | } 269 | 270 | $posend = FALSE; 271 | if($changelog!==FALSE)$posend = strpos($changelog, "Version"); 272 | if($posend!==FALSE) 273 | { 274 | $changelog = substr($changelog, $len, $posend-$len); 275 | } 276 | else 277 | { 278 | $changelog = FALSE; 279 | } 280 | } 281 | } 282 | } 283 | if($changelog!==FALSE)$changelog = mysqli_real_escape_string($mysqldb, $changelog); 284 | 285 | $strdata = strtok($str, " "); 286 | if($changelog_switch_flag==0)$strdata = strtok(" "); 287 | 288 | $posend = strpos($strdata, " 340 | -------------------------------------------------------------------------------- /ninupdates/logs.php: -------------------------------------------------------------------------------- 1 | "); 73 | if($titlever_posend===FALSE) 74 | { 75 | $titlever_posend = $newline_pos; 76 | } 77 | else 78 | { 79 | $titlever_posend -= 1; 80 | } 81 | 82 | $titlesize_pos = 0; 83 | $titlesize_posend = 0; 84 | $titletiksize_pos = 0; 85 | $titletiksize_posend = 0; 86 | $titletmdsize_pos = 0; 87 | $titletmdsize_posend = 0; 88 | 89 | if(strstr($text, "size")) 90 | { 91 | $titlesize_pos = strpos($text, "size ") + 5; 92 | $titletiksize_pos = strpos($text, "tiksize"); 93 | $titletmdsize_pos = strpos($text, "tmdsize"); 94 | 95 | $titlesize_posend = $titletiksize_pos; 96 | $titletiksize_posend = $titletmdsize_pos; 97 | $titletmdsize_posend = $newline_pos; 98 | 99 | if($titlesize_posend===FALSE) 100 | { 101 | $titlesize_posend = $newline_pos; 102 | } 103 | else 104 | { 105 | $titlesize_posend -= 1; 106 | } 107 | 108 | if($titletiksize_posend===FALSE) 109 | { 110 | $titletiksize_posend = $newline_pos; 111 | } 112 | else 113 | { 114 | $titletiksize_posend -= 1; 115 | } 116 | 117 | if($titletmdsize_posend===FALSE) 118 | { 119 | $titletmdsize_posend = $newline_pos; 120 | } 121 | else 122 | { 123 | $titletmdsize_posend -= 1; 124 | } 125 | } 126 | 127 | $titleid = substr($text, 8, 16); 128 | $titlever = substr($text, $titlever_pos, $titlever_posend - $titlever_pos); 129 | if($titlesize_pos!==FALSE)$titlesize = substr($text, $titlesize_pos, $titlesize_posend - $titlesize_pos); 130 | if($titletiksize_pos!==FALSE)$titlesizetik = substr($text, $titletiksize_pos, $titletiksize_posend - $titletiksize_pos); 131 | if($titletmdsize_pos!==FALSE)$titlesizetmd = substr($text, $titletmdsize_pos, $titletmdsize_posend - $titletmdsize_pos); 132 | 133 | if($titlesizetik=="tagsmissing")$titlesizetik = "0"; 134 | if($titlesizetmd=="tagsmissing")$titlesizetmd = "0"; 135 | 136 | $titlesizetik = intval($titlesizetik); 137 | $titlesizetmd = intval($titlesizetmd); 138 | 139 | $titleids[] = $titleid; 140 | $titleversions[] = intval($titlever); 141 | $titles_sizes[] = intval($titlesize); 142 | $titles_tiksizes[] = $titlesizetik; 143 | $titles_tmdsizes[] = $titlesizetmd; 144 | 145 | $total_titles++; 146 | 147 | $text = strstr($text, "
    "); 148 | } 149 | } 150 | 151 | function diff_titlelists($oldlog, $curdatefn) 152 | { 153 | global $oldtitles, $oldtitlesversions, $oldtitles_sizes, $oldtitles_tiksizes, $oldtitles_tmdsizes, $oldtotal_titles, $newtitles, $newtitlesversions, $newtitles_sizes, $newtitles_tiksizes, $newtitles_tmdsizes, $newtotal_titles, $difflogbuf, $system, $region, $sitecfg_workdir, $soap_timestamp, $dbcurdate; 154 | 155 | $difflogbuf = "\n"; 156 | $text = ""; 157 | $found = 0; 158 | $oldtitleid=""; 159 | $titleid=""; 160 | $oldtitlever=""; 161 | $titlever=""; 162 | $updatedtitles = 0; 163 | $update_size = 0; 164 | 165 | load_oldtitlelist($oldlog); 166 | 167 | for($newi=0; $newi<$newtotal_titles; $newi++) 168 | { 169 | $found = 0; 170 | 171 | $titleid = $newtitles[$newi]; 172 | $titlever = $newtitlesversions[$newi]; 173 | $titlesize = $newtitles_sizes[$newi]; 174 | 175 | for($oldi=0; $oldi<$oldtotal_titles; $oldi++) 176 | { 177 | $oldtitleid = $oldtitles[$oldi]; 178 | $oldtitlever = $oldtitlesversions[$oldi]; 179 | 180 | if($titleid==$oldtitleid) 181 | { 182 | if($titlever<=$oldtitlever) 183 | { 184 | $found = 2; 185 | break;//skip titles which weren't updated 186 | } 187 | $found = 1; 188 | } 189 | } 190 | 191 | if($found!=2) 192 | { 193 | $updatedtitles++; 194 | $update_size+= $titlesize; 195 | $status=""; 196 | if($found==0)$status = "new"; 197 | if($found==1)$status = "updated"; 198 | 199 | $text = "titleid $titleid ver $titlever titlesize $titlesize status $status
    \n"; 200 | $difflogbuf.= $text; 201 | echo $text; 202 | } 203 | } 204 | 205 | if($updatedtitles==0)return 0; 206 | 207 | $difflogbuf .= "Update content size: $update_size
    \n"; 208 | $difflogbuf .= ""; 209 | 210 | $freport = fopen("$sitecfg_workdir/reports$system/$region/$curdatefn", "w"); 211 | fwrite($freport, $difflogbuf); 212 | fclose($freport); 213 | 214 | return 1; 215 | } 216 | 217 | function parse_soapresp($buf, $disable_titlehash_init) 218 | { 219 | global $mysqldb, $newtitles, $newtitlesversions, $newtitles_sizes, $newtitles_tiksizes, $newtitles_tmdsizes, $newtotal_titles, $system, $region, $sysupdate_systitlehashes; 220 | $title = $buf; 221 | $titleid_pos = 0; 222 | $titlever_pos = 0; 223 | $titlesize_pos = 0; 224 | $titleid = ""; 225 | $titlever = ""; 226 | $titlesize = 0; 227 | $titlesizetik = ""; 228 | $titlesizetmd = ""; 229 | $logbuf=""; 230 | 231 | while(($title = strstr($title, ""))) 232 | { 233 | $titleid_pos = strpos($title, "") + 9; 234 | $titleid_posend = strpos($title, ""); 235 | $titlever_pos = strpos($title, "") + 9; 236 | $titlever_posend = strpos($title, ""); 237 | $titlesize_pos = strpos($title, "") + 8; 238 | $titlesize_posend = strpos($title, ""); 239 | $titlesizetik_pos = strpos($title, "") + 12; 240 | $titlesizetik_posend = strpos($title, ""); 241 | $titlesizetmd_pos = strpos($title, "") + 9; 242 | $titlesizetmd_posend = strpos($title, ""); 243 | 244 | if($titlesize_posend===FALSE) 245 | { 246 | $titlesize_pos = strpos($title, "") + 9; 247 | $titlesize_posend = strpos($title, ""); 248 | } 249 | 250 | if($titleid_posend!==FALSE)$titleid = substr($title, $titleid_pos, $titleid_posend - $titleid_pos); 251 | if($titlever_posend!==FALSE)$titlever = substr($title, $titlever_pos, $titlever_posend - $titlever_pos); 252 | if($titlesize_posend!==FALSE)$titlesize = substr($title, $titlesize_pos, $titlesize_posend - $titlesize_pos); 253 | if($titlesizetik_posend!==FALSE)$titlesizetik = substr($title, $titlesizetik_pos, $titlesizetik_posend - $titlesizetik_pos); 254 | if($titlesizetmd_posend!==FALSE)$titlesizetmd = substr($title, $titlesizetmd_pos, $titlesizetmd_posend - $titlesizetmd_pos); 255 | 256 | if($titlever_posend!==FALSE)$titlever = intval($titlever); 257 | if($titlesize_posend!==FALSE)$titlesize = intval($titlesize); 258 | 259 | if($titleid_pos===FALSE)$titleid="tagsmissing"; 260 | if($titlever_pos===FALSE || $titlever_posend===FALSE)$titlever = 0; 261 | if($titlesize_pos===FALSE || $titlesize_posend===FALSE)$titlesize = 0; 262 | if($titlesizetik_pos===FALSE || $titlesizetik_posend===FALSE)$titlesizetik = 0; 263 | if($titlesizetmd_pos===FALSE || $titlesizetmd_posend===FALSE)$titlesizetmd = 0; 264 | 265 | $newtitles[] = mysqli_real_escape_string($mysqldb, $titleid); 266 | $newtitlesversions[] = mysqli_real_escape_string($mysqldb, $titlever); 267 | $newtitles_sizes[] = mysqli_real_escape_string($mysqldb, $titlesize); 268 | $newtitles_tiksizes[] = mysqli_real_escape_string($mysqldb, $titlesizetik); 269 | $newtitles_tmdsizes[] = mysqli_real_escape_string($mysqldb, $titlesizetmd); 270 | 271 | $newtotal_titles++; 272 | 273 | $title = strstr($title, ""); 274 | } 275 | 276 | if($disable_titlehash_init==0) 277 | { 278 | $sysupdate_systitlehashes[$region] = ""; 279 | 280 | $titlehash_pos = strpos($buf, "") + 11; 281 | $titlehash_posend = strpos($buf, ""); 282 | if($titlehash_pos!==FALSE && $titlehash_posend!==FALSE) 283 | { 284 | $titlehash = substr($buf, $titlehash_pos, $titlehash_posend - $titlehash_pos); 285 | $sysupdate_systitlehashes[$region] = mysqli_real_escape_string($mysqldb, $titlehash); 286 | } 287 | } 288 | } 289 | 290 | function parse_json_resp($buf) 291 | { 292 | global $mysqldb, $newtitles, $newtitlesversions, $newtitles_sizes, $newtitles_tiksizes, $newtitles_tmdsizes, $newtotal_titles, $system, $ninupdatesapi_out_version_array, $region, $sysupdate_systitlehashes, $overridden_initial_titleid, $overridden_initial_titleversion; 293 | 294 | $titleid = ""; 295 | $titlever = ""; 296 | $titlesize = 0; 297 | $titlesizetik = 0; 298 | $titlesizetmd = 0; 299 | 300 | $jsonobj = json_decode($buf); 301 | if($jsonobj === NULL) 302 | { 303 | "json_decode() failed.\n"; 304 | return 1; 305 | } 306 | 307 | if(!isset($jsonobj->system_update_metas)) 308 | { 309 | echo "json is missing 'system_update_metas'.\n"; 310 | return 2; 311 | } 312 | 313 | $titlelist = $jsonobj->system_update_metas; 314 | 315 | if(count($titlelist) < 1) 316 | { 317 | echo "json titlelist is empty.\n"; 318 | return 3; 319 | } 320 | 321 | $title_entry = $titlelist[0]; 322 | 323 | if(!isset($title_entry->title_id) || !isset($title_entry->title_version)) 324 | { 325 | echo "json title_entry titleid/titleversion isn't set.\n"; 326 | return 4; 327 | } 328 | 329 | $titleid = mysqli_real_escape_string($mysqldb, $title_entry->title_id); 330 | $titlever = mysqli_real_escape_string($mysqldb, $title_entry->title_version); 331 | 332 | if($overridden_initial_titleid!="")$titleid = mysqli_real_escape_string($mysqldb, $overridden_initial_titleid); 333 | if($overridden_initial_titleversion!="")$titlever = mysqli_real_escape_string($mysqldb, $overridden_initial_titleversion); 334 | 335 | $sysupdate_systitlehashes[$region] = "$titleid,$titlever"; 336 | 337 | $newtitles[] = $titleid; 338 | $newtitlesversions[] = $titlever; 339 | $newtitles_sizes[] = $titlesize; 340 | $newtitles_tiksizes[] = $titlesizetik; 341 | $newtitles_tmdsizes[] = $titlesizetmd; 342 | 343 | $newtotal_titles++; 344 | 345 | return 0; 346 | } 347 | 348 | // Get a title-listing for the specified report (changed/added titles). Duplicate titles in different regions are grouped together. 349 | function report_get_titlelist($system, $reportdate, &$out_titlestatus_new = NULL, &$out_titlestatus_changed = NULL, $ignore_titles = NULL) 350 | { 351 | global $mysqldb; 352 | 353 | $query="SELECT ninupdates_titles.tid, ninupdates_titleids.titleid, ninupdates_titleids.description, ninupdates_titles.version, GROUP_CONCAT(DISTINCT ninupdates_regions.regionid SEPARATOR ','), GROUP_CONCAT(DISTINCT ninupdates_titles.region ORDER BY ninupdates_regions.regionid SEPARATOR ',') FROM ninupdates_titles, ninupdates_titleids, ninupdates_regions, ninupdates_consoles, ninupdates_reports WHERE ninupdates_consoles.system='".$system."' AND ninupdates_titles.systemid=ninupdates_consoles.id AND ninupdates_titles.tid=ninupdates_titleids.id AND ninupdates_titles.reportid=ninupdates_reports.id AND ninupdates_reports.reportdate='".$reportdate."' AND ninupdates_regions.regioncode=ninupdates_titles.region GROUP BY ninupdates_titles.tid, ninupdates_titles.version"; 354 | $result=mysqli_query($mysqldb, $query); 355 | $numrows=mysqli_num_rows($result); 356 | $out = array(); 357 | 358 | for($i=0; $i<$numrows; $i++) 359 | { 360 | $row = mysqli_fetch_row($result); 361 | 362 | $tmp = array(); 363 | $tmp["tid"] = $row[0]; 364 | $tmp["titleid"] = $row[1]; 365 | $tmp["description"] = $row[2]; 366 | $tmp["version"] = $row[3]; 367 | $tmp["regions"] = $row[4]; 368 | $tmp["regionids"] = $row[5]; 369 | $tmp["status"] = "N/A"; 370 | 371 | $found = False; 372 | if($ignore_titles!==NULL) 373 | { 374 | foreach($ignore_titles as $ignore_titleid) 375 | { 376 | if($tmp["titleid"] == $ignore_titleid) 377 | { 378 | $found = True; 379 | break; 380 | } 381 | } 382 | } 383 | if(!$found) 384 | { 385 | $out[] = $tmp; 386 | } 387 | } 388 | 389 | $query = "SELECT ninupdates_titles.tid, ninupdates_titles.region, MIN(ninupdates_titles.version) FROM ninupdates_titles, ninupdates_consoles WHERE ninupdates_consoles.system='".$system."' AND ninupdates_titles.systemid=ninupdates_consoles.id GROUP BY ninupdates_titles.tid, ninupdates_titles.region"; 390 | $result=mysqli_query($mysqldb, $query); 391 | $numrows=mysqli_num_rows($result); 392 | for($rowi=0; $rowi<$numrows; $rowi++) 393 | { 394 | $row = mysqli_fetch_row($result); 395 | $min_tid = $row[0]; 396 | $min_region = $row[1]; 397 | $min_version = $row[2]; 398 | 399 | foreach($out as &$title) 400 | { 401 | $tid = $title["tid"]; 402 | $versions = $title["version"]; 403 | $regionids = $title["regionids"]; 404 | 405 | if($tid == $min_tid && strpos($regionids, $min_region)!==FALSE && $title["status"]==="N/A") 406 | { 407 | $titlestatus = "Changed"; 408 | if($versions==$min_version) 409 | { 410 | $titlestatus = "New"; 411 | if($out_titlestatus_new!==NULL) 412 | { 413 | $out_titlestatus_new[] = $title; 414 | } 415 | } 416 | else 417 | { 418 | if($out_titlestatus_changed!==NULL) 419 | { 420 | $out_titlestatus_changed[] = $title; 421 | } 422 | } 423 | 424 | $title["status"] = $titlestatus; 425 | 426 | break; 427 | } 428 | } 429 | } 430 | 431 | return $out; 432 | } 433 | 434 | function titlelist_dbupdate() 435 | { 436 | global $mysqldb, $dbcurdate, $system, $region, $newtitles, $newtitlesversions, $newtitles_sizes, $newtitles_tiksizes, $newtitles_tmdsizes, $newtotal_titles; 437 | 438 | $titles_added = 0; 439 | 440 | $query="SELECT id FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$system."'"; 441 | $result=mysqli_query($mysqldb, $query); 442 | $row = mysqli_fetch_row($result); 443 | $systemid = $row[0]; 444 | 445 | for($titlei=0; $titlei<$newtotal_titles; $titlei++) 446 | { 447 | $query = "SELECT id FROM ninupdates_titleids WHERE ninupdates_titleids.titleid='".$newtitles[$titlei]."'"; 448 | $result=mysqli_query($mysqldb, $query); 449 | $numrows=mysqli_num_rows($result); 450 | if($numrows==0) 451 | { 452 | $query = "INSERT INTO ninupdates_titleids (titleid) VALUES ('".$newtitles[$titlei]."')"; 453 | $result=mysqli_query($mysqldb, $query); 454 | $tid = mysqli_insert_id($mysqldb); 455 | } 456 | else 457 | { 458 | $row = mysqli_fetch_row($result); 459 | $tid = $row[0]; 460 | } 461 | 462 | $query = "SELECT id FROM ninupdates_titles WHERE ninupdates_titles.version=".$newtitlesversions[$titlei]." AND ninupdates_titles.region='".$region."' AND ninupdates_titles.tid=$tid AND ninupdates_titles.systemid=$systemid"; 463 | $result=mysqli_query($mysqldb, $query); 464 | $numrows=mysqli_num_rows($result); 465 | 466 | if($numrows==0) 467 | { 468 | $query = "INSERT INTO ninupdates_titles (tid, version, fssize, tmdsize, tiksize, systemid, region, curdate, reportid) VALUES ('".$tid."','".$newtitlesversions[$titlei]."','".$newtitles_sizes[$titlei]."','".$newtitles_tmdsizes[$titlei]."','".$newtitles_tiksizes[$titlei]."',$systemid,'".$region."','".$dbcurdate."',0)"; 469 | $result=mysqli_query($mysqldb, $query); 470 | 471 | $titles_added++; 472 | } 473 | else 474 | { 475 | $row = mysqli_fetch_row($result); 476 | $id = $row[0]; 477 | $query="UPDATE ninupdates_titles SET fssize='".$newtitles_sizes[$titlei]."', tmdsize='".$newtitles_tmdsizes[$titlei]."', tiksize='".$newtitles_tiksizes[$titlei]."' WHERE id=$id"; 478 | $result=mysqli_query($mysqldb, $query); 479 | } 480 | } 481 | 482 | return $titles_added; 483 | } 484 | 485 | function getsystem_sysname($sys) 486 | { 487 | global $mysqldb; 488 | 489 | $query="SELECT ninupdates_consoles.sysname FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$sys."'"; 490 | $result=mysqli_query($mysqldb, $query); 491 | 492 | $numrows=mysqli_num_rows($result); 493 | if($numrows==0) 494 | { 495 | dbconnection_end(); 496 | writeNormalLog("THE SPECIFIED SYSTEM DOES NOT EXIST IN THE TABLE. RESULT: 200"); 497 | echo "The specified system is invalid.\n"; 498 | exit; 499 | } 500 | 501 | $row = mysqli_fetch_row($result); 502 | return $row[0]; 503 | } 504 | 505 | ?> 506 | -------------------------------------------------------------------------------- /pub_html/ninupdates/reports.php: -------------------------------------------------------------------------------- 1 | \n\n"; 37 | 38 | if($reportdate!="" && $system!="") 39 | { 40 | if($setver=="1" || $setsysver!="") 41 | { 42 | $con .= "Nintendo System Update $sys $reportdate Set System Version 43 | Manually setting the update-version is disabled since that's supposed to be done automatically, doing it manually would also disable other things which are supposed to be done automatically."; 44 | 45 | dbconnection_end(); 46 | if($sitecfg_logplainhttp200!=0)writeNormalLog("RESULT: 200"); 47 | echo $con; 48 | 49 | return; 50 | 51 | /*$query="SELECT updateversion FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.reportdate='".$reportdate."' && ninupdates_consoles.system='".$system."' && ninupdates_reports.systemid=ninupdates_consoles.id && ninupdates_reports.log='report'"; 52 | $result=mysqli_query($mysqldb, $query); 53 | $numrows=mysqli_num_rows($result); 54 | 55 | if($numrows==0) 56 | { 57 | dbconnection_end(); 58 | 59 | header("Location: reports.php"); 60 | writeNormalLog("ROW FOR SETVER NOT FOUND. RESULT: 302"); 61 | 62 | return; 63 | } 64 | 65 | $row = mysqli_fetch_row($result);*/ 66 | /*if($row[0]!="N/A") 67 | { 68 | dbconnection_end(); 69 | 70 | header("Location: reports.php"); 71 | writeNormalLog("UPDATEVERSION ALREADY SET TO ".$row[0].". RESULT: 302"); 72 | 73 | return; 74 | }*/ 75 | 76 | /*if($setver=="1") 77 | { 78 | $con .= "Nintendo System Update $sys $reportdate Set System Version 79 |
    80 | System version:
    "; 81 | 82 | dbconnection_end(); 83 | if($sitecfg_logplainhttp200!=0)writeNormalLog("RESULT: 200"); 84 | echo $con; 85 | 86 | return; 87 | }*/ 88 | /*else if($setsysver!="") 89 | { 90 | $setsysver = strip_tags($setsysver); 91 | 92 | while(1) 93 | { 94 | $pos = strpos($setsysver, ","); 95 | if($pos === FALSE)break; 96 | $setsysver[$pos] = " "; 97 | 98 | } 99 | 100 | if($setsysver!="N/A") 101 | { 102 | $query = "SELECT updateversion FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.updateversion='".$setsysver."' && ninupdates_consoles.system='".$system."' && ninupdates_reports.systemid=ninupdates_consoles.id && ninupdates_reports.log='report'"; 103 | $result=mysqli_query($mysqldb, $query); 104 | $numrows=mysqli_num_rows($result); 105 | 106 | if($numrows!=0) 107 | { 108 | dbconnection_end(); 109 | 110 | header("Location: reports.php"); 111 | writeNormalLog("THE SPECIFIED SYSVER ALREADY EXISTS FOR A REPORT UNDER THE SPECIFIED SYSTEM. RESULT: 302"); 112 | 113 | return; 114 | } 115 | } 116 | 117 | $query = "UPDATE ninupdates_reports, ninupdates_consoles SET ninupdates_reports.updateversion='".$setsysver."', ninupdates_reports.wikipage_exists=0 WHERE reportdate='".$reportdate."' && ninupdates_consoles.system='".$system."' && ninupdates_reports.systemid=ninupdates_consoles.id && ninupdates_reports.log='report'"; 118 | $result=mysqli_query($mysqldb, $query); 119 | dbconnection_end(); 120 | 121 | header("Location: reports.php?date=".$reportdate."&sys=".$system); 122 | writeNormalLog("CHANGED SYSVER TO $setsysver. RESULT: 302"); 123 | 124 | return; 125 | }*/ 126 | } 127 | } 128 | 129 | $text = "reports"; 130 | $report_titletext = ""; 131 | if($reportdate!="") 132 | { 133 | $query="SELECT updateversion FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.reportdate='".$reportdate."' && ninupdates_consoles.system='".$system."' && ninupdates_reports.systemid=ninupdates_consoles.id && ninupdates_reports.log='report'"; 134 | $result=mysqli_query($mysqldb, $query); 135 | $numrows=mysqli_num_rows($result); 136 | if($numrows==0) 137 | { 138 | $text = "$sys $reportdate report"; 139 | } 140 | else 141 | { 142 | $row = mysqli_fetch_row($result); 143 | if($row[0]=="N/A") 144 | { 145 | $text = "$sys $reportdate report"; 146 | } 147 | else 148 | { 149 | $text = "$sys ".$row[0]." report"; 150 | } 151 | } 152 | 153 | $report_titletext = $text; 154 | } 155 | 156 | $con .= "Nintendo System Update $text\n"; 157 | 158 | if($reportdate=="") 159 | { 160 | $reportdate_columntext = "Report date"; 161 | $system_columntext = "System"; 162 | 163 | if($order=="") 164 | { 165 | $reportdate_columntext = "
    $reportdate_columntext"; 166 | } 167 | else 168 | { 169 | $system_columntext = "$system_columntext"; 170 | } 171 | 172 | $con.= "$sitecfg_homepage_header

    Reports

    173 | 174 | 175 | 176 | 177 | 178 | 179 | \n"; 180 | // 181 | 182 | $orderquery = ""; 183 | if($order=="") 184 | { 185 | $orderquery = "ninupdates_consoles.system, ninupdates_reports.curdate"; 186 | } 187 | else 188 | { 189 | $orderquery = "ninupdates_reports.curdate"; 190 | } 191 | 192 | $query="SELECT ninupdates_reports.reportdate, ninupdates_reports.updateversion, ninupdates_consoles.system, ninupdates_reports.curdate, ninupdates_reports.reportdaterfc FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.log='report' && ninupdates_reports.systemid=ninupdates_consoles.id ORDER BY $orderquery"; 193 | $result=mysqli_query($mysqldb, $query); 194 | $numrows=mysqli_num_rows($result); 195 | 196 | $prev_curdate = ""; 197 | $prev_system = ""; 198 | 199 | for($i=0; $i<$numrows; $i++) 200 | { 201 | $row = mysqli_fetch_row($result); 202 | $reportdate = $row[0]; 203 | $updateversion = $row[1]; 204 | $system = $row[2]; 205 | $curdate = $row[3]; 206 | $reportdaterfc = $row[4]; 207 | 208 | $sys = getsystem_sysname($system); 209 | 210 | $url = "reports.php?date=$reportdate&sys=$system"; 211 | 212 | //if($updateversion=="N/A")$updateversion = "N/A"; 213 | 214 | $con.= "\n"; 215 | 216 | $query="SELECT TIMESTAMPDIFF(DAY,'".$prev_curdate."','".$curdate."'), TIMESTAMPDIFF(WEEK,'".$prev_curdate."','".$curdate."'), TIMESTAMPDIFF(MONTH,'".$prev_curdate."','".$curdate."'), TIMESTAMPDIFF(MINUTE,'".$prev_curdate."','".$curdate."'), TIMESTAMPDIFF(HOUR,'".$prev_curdate."','".$curdate."')"; 217 | $result_new=mysqli_query($mysqldb, $query); 218 | $row_new = mysqli_fetch_row($result_new); 219 | 220 | $timediff0 = $row_new[0]; 221 | $timediff1 = $row_new[1]; 222 | $timediff2 = $row_new[2]; 223 | $timediff3 = $row_new[3] % 60; 224 | $timediff4 = $row_new[4] % 24; 225 | 226 | $lastreport_text = ""; 227 | if($i>0 && $prev_system===$system)$lastreport_text = "$timediff0 day(s) / $timediff1 week(s) / $timediff2 month(s) and $timediff4 hours $timediff3 minutes ago."; 228 | 229 | $con.= "\n"; 230 | $con.= "\n"; 231 | $con.= "\n"; 232 | $con.= "\n"; 233 | $con.= "\n"; 234 | 235 | $con.= "\n"; 236 | 237 | $prev_curdate = $curdate; 238 | $prev_system = $system; 239 | } 240 | $con.= "
    $reportdate_columntextUpdate Version$system_columntextRequest timestampPrevious report
    UTC datetime
    $reportdate".$updateversion."".$sys."".$reportdaterfc."".$lastreport_text."

    \n"; 241 | 242 | $con.= "

    Systems

    243 | 244 | 245 | 246 | 247 | 248 | \n"; 249 | 250 | $query = "SELECT now()"; 251 | $result=mysqli_query($mysqldb, $query); 252 | $row = mysqli_fetch_row($result); 253 | $dbcurdate = $row[0]; 254 | 255 | $query="SELECT DISTINCT ninupdates_consoles.system, ninupdates_consoles.lastreqstatus FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.log='report' && ninupdates_reports.systemid=ninupdates_consoles.id ORDER BY ninupdates_consoles.system"; 256 | $result=mysqli_query($mysqldb, $query); 257 | $numrows=mysqli_num_rows($result); 258 | 259 | for($i=0; $i<$numrows; $i++) 260 | { 261 | $row = mysqli_fetch_row($result); 262 | $system = $row[0]; 263 | $lastreqstatus = $row[1]; 264 | if($lastreqstatus==="" || $lastreqstatus===NULL)$lastreqstatus = "OK"; 265 | 266 | $sys = getsystem_sysname($system); 267 | 268 | $lastreport_text = ""; 269 | 270 | $query="SELECT ninupdates_reports.reportdate, ninupdates_reports.updateversion, ninupdates_reports.curdate FROM ninupdates_reports, ninupdates_consoles WHERE log='report' && ninupdates_reports.systemid=ninupdates_consoles.id && ninupdates_consoles.system='".$system."' ORDER BY ninupdates_reports.curdate DESC LIMIT 1"; 271 | $result_new=mysqli_query($mysqldb, $query); 272 | $numrows_new=mysqli_num_rows($result_new); 273 | if($numrows_new>0) 274 | { 275 | $row_new = mysqli_fetch_row($result_new); 276 | 277 | $reportdate = $row_new[0]; 278 | $updateversion = $row_new[1]; 279 | $report_curdate = $row_new[2]; 280 | 281 | $url = "reports.php?date=$reportdate&sys=$system"; 282 | 283 | $query="SELECT TIMESTAMPDIFF(DAY,'".$report_curdate."','".$dbcurdate."'), TIMESTAMPDIFF(WEEK,'".$report_curdate."','".$dbcurdate."'), TIMESTAMPDIFF(MONTH,'".$report_curdate."','".$dbcurdate."'), TIMESTAMPDIFF(MINUTE,'".$report_curdate."','".$dbcurdate."'), TIMESTAMPDIFF(HOUR,'".$report_curdate."','".$dbcurdate."')"; 284 | $result_new=mysqli_query($mysqldb, $query); 285 | $row_new = mysqli_fetch_row($result_new); 286 | 287 | $timediff0 = $row_new[0]; 288 | $timediff1 = $row_new[1]; 289 | $timediff2 = $row_new[2]; 290 | $timediff3 = $row_new[3] % 60; 291 | $timediff4 = $row_new[4] % 24; 292 | 293 | $lastreport_text = "$reportdate($updateversion), $timediff0 day(s) / $timediff1 week(s) / $timediff2 month(s) and $timediff4 hours $timediff3 minutes ago."; 294 | } 295 | 296 | $url = "titlelist.php?sys=$system"; 297 | 298 | $con.= "\n"; 299 | $con.= "\n"; 300 | $con.= "\n"; 301 | $con.= "\n"; 302 | $con.= "\n"; 303 | $con.= "\n"; 304 | } 305 | 306 | $con.= "
    SystemTitle ListLast reportLast request status
    ".$sys."HTML Wiki CSV".$lastreport_text."".$lastreqstatus."

    \n"; 307 | 308 | $con.= "

    Scan Status



    \n"; 309 | 310 | $con.= "

    Other

    "; 311 | 312 | $con.= "RSS feed is available here."; 313 | $con.= "
    \n"; 314 | $con.= "Source code is available here.
    \n"; 315 | $con.= "Parsed Nintendo Zone Hotspots data is available here.
    \n"; 316 | $con.= "Scanning involving eShop can be found here.
    \n"; 317 | 318 | $con.= "$sitecfg_homepage_footer

    \n"; 319 | 320 | $con.= ""; 321 | } 322 | else 323 | { 324 | $con.= "$sitecfg_reportupdatepage_header"; 325 | 326 | $con.= "$sitecfg_sitenav_headerHomepage -> $report_titletext


    \n"; 327 | 328 | $con.= " 329 | 330 | 331 | 332 | 333 | \n"; 334 | 335 | $query="SELECT ninupdates_reports.regions, ninupdates_reports.reportdaterfc, ninupdates_reports.updateversion, ninupdates_reports.id, ninupdates_reports.wikipage_exists, ninupdates_reports.postproc_runfinished, ninupdates_consoles.generation FROM ninupdates_reports, ninupdates_consoles WHERE reportdate='".$reportdate."' AND ninupdates_consoles.system='".$system."' AND ninupdates_reports.systemid=ninupdates_consoles.id AND log='report'"; 336 | $result=mysqli_query($mysqldb, $query); 337 | $numrows=mysqli_num_rows($result); 338 | if($numrows==0) 339 | { 340 | writeNormalLog("REPORT ROW NOT FOUND. RESULT: 302"); 341 | 342 | header("Location: reports.php"); 343 | 344 | dbconnection_end(); 345 | return; 346 | } 347 | 348 | $row = mysqli_fetch_row($result); 349 | $regions = $row[0]; 350 | $reportdaterfc = $row[1]; 351 | $updateversion = $row[2]; 352 | $reportid = $row[3]; 353 | $wikipage_exists = $row[4]; 354 | $postproc_runfinished = $row[5]; 355 | $generation = $row[6]; 356 | 357 | if(strlen($regions)==0) 358 | { 359 | writeNormalLog("INVALID ROW REGIONS. RESULT: 302"); 360 | 361 | header("Location: reports.php"); 362 | 363 | dbconnection_end(); 364 | return; 365 | } 366 | 367 | $region = strtok($regions, ","); 368 | while($region!==FALSE) 369 | { 370 | if(strlen($region)>1) 371 | { 372 | writeNormalLog("INVALID ROW REGIONS FIELD $region. RESULT: 302"); 373 | 374 | header("Location: reports.php"); 375 | 376 | dbconnection_end(); 377 | return; 378 | } 379 | 380 | $url = "titlelist.php?date=$reportdate&sys=$system&reg=$region"; 381 | 382 | $con.= "\n"; 383 | $con.= "\n"; 384 | $con.= "\n"; 385 | $con.= "\n"; 386 | 387 | $region = strtok(","); 388 | } 389 | 390 | $url = "titlelist.php?date=$reportdate&sys=$system"; 391 | 392 | $con.= "\n"; 393 | $con.= "\n"; 394 | $con.= "\n"; 395 | $con.= "\n"; 396 | 397 | $con.= "
    RegionReportTitlelist
    $region$reportdate Wiki CSV Text$reportdate Wiki CSV Raw server reply
    All$reportdate Wiki CSV Text$reportdate Wiki CSV

    \n"; 398 | 399 | $changelog_count = 0; 400 | 401 | $region = strtok($regions, ","); 402 | while($region!==FALSE) 403 | { 404 | if(strlen($region)>1)break; 405 | 406 | $query="SELECT ninupdates_officialchangelog_pages.url, ninupdates_officialchangelog_pages.id FROM ninupdates_officialchangelog_pages, ninupdates_consoles, ninupdates_regions WHERE ninupdates_consoles.system='".$system."' && ninupdates_officialchangelog_pages.systemid=ninupdates_consoles.id && ninupdates_officialchangelog_pages.regionid=ninupdates_regions.id && ninupdates_regions.regioncode='".$region."'"; 407 | $result=mysqli_query($mysqldb, $query); 408 | $numrows=mysqli_num_rows($result); 409 | if($numrows>0) 410 | { 411 | $changelog_count++; 412 | 413 | $row = mysqli_fetch_row($result); 414 | $pageurl = $row[0]; 415 | $pageid = $row[1]; 416 | 417 | if($changelog_count==1) 418 | { 419 | $con.= "Official changelog(s):

    \n"; 420 | $con.= " 421 | 422 | 423 | 424 | 425 | \n"; 426 | } 427 | 428 | $display_html = ""; 429 | 430 | $query = "SELECT display_html FROM ninupdates_officialchangelogs WHERE pageid=$pageid && reportid=$reportid"; 431 | $result=mysqli_query($mysqldb, $query); 432 | $numrows=mysqli_num_rows($result); 433 | if($numrows>0) 434 | { 435 | $row = mysqli_fetch_row($result); 436 | $display_html = $row[0]; 437 | } 438 | 439 | if($display_html===FALSE)$display_html = ""; 440 | if($display_html=="")$display_html = "N/A"; 441 | 442 | $con.= "\n"; 443 | $con.= "\n"; 444 | $con.= "\n"; 445 | $con.= "\n"; 446 | } 447 | 448 | $region = strtok(","); 449 | } 450 | 451 | if($changelog_count==0) 452 | { 453 | $con.= "Official changelog(s): N/A.

    \n"; 454 | } 455 | else 456 | { 457 | $con.= "
    RegionPage URLChangelog text
    $regionPage link$display_html

    \n"; 458 | } 459 | 460 | if(file_exists("$sitecfg_workdir/updatedetails/$system/$reportdate")===TRUE) 461 | { 462 | $con.= "Update details are available here.
    \n
    \n"; 463 | } 464 | else if($generation!=0 && $postproc_runfinished==0) 465 | { 466 | $con.= "Update details are not yet available, this should be available soon.
    \n
    \n"; 467 | } 468 | 469 | if($wikipage_exists==="1") 470 | { 471 | $query="SELECT ninupdates_wikiconfig.serverbaseurl, ninupdates_wikiconfig.apiprefixuri FROM ninupdates_wikiconfig, ninupdates_consoles WHERE ninupdates_wikiconfig.id=ninupdates_consoles.wikicfgid && ninupdates_consoles.system='".$system."'"; 472 | $result=mysqli_query($mysqldb, $query); 473 | $numrows=mysqli_num_rows($result); 474 | 475 | if($numrows>0) 476 | { 477 | $row = mysqli_fetch_row($result); 478 | $wiki_serverbaseurl = $row[0]; 479 | $wiki_apiprefixuri = $row[1]; 480 | 481 | $wiki_uribase = "wiki/"; 482 | if($wiki_apiprefixuri == "")$wiki_uribase = "index.php?title="; 483 | 484 | $posend = strpos($updateversion, "_rebootless"); 485 | if($posend!==FALSE)$updateversion = substr($updateversion, 0, $posend); 486 | 487 | $system_wiki_pageprefix = ""; 488 | if(isset($sitecfg_wiki_consoles_pageprefix) && isset($sitecfg_wiki_consoles_pageprefix[$system])) $system_wiki_pageprefix = $sitecfg_wiki_consoles_pageprefix[$system]; 489 | 490 | $page_title = $system_wiki_pageprefix . $updateversion; 491 | $page_title_url = str_replace(" ", "_", $page_title); 492 | 493 | $con.= "The wiki page is available here.
    \n
    \n"; 494 | } 495 | } 496 | 497 | $con.= "Request timestamp: $reportdaterfc

    \n"; 498 | //if($updateversion=="N/A")$con.= "Set system version."; 499 | $con.= "$sitecfg_reportupdatepage_footer"; 500 | $con.= ""; 501 | } 502 | 503 | dbconnection_end(); 504 | 505 | if($sitecfg_logplainhttp200!=0)writeNormalLog("RESULT: 200"); 506 | 507 | echo $con; 508 | 509 | ?> 510 | -------------------------------------------------------------------------------- /pub_html/ninupdates/titlelist.php: -------------------------------------------------------------------------------- 1 | \n\n"; 51 | } 52 | 53 | $query="SELECT id FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$system."'"; 54 | $result=mysqli_query($mysqldb, $query); 55 | $row = mysqli_fetch_row($result); 56 | $systemid = $row[0]; 57 | 58 | if($region!="") 59 | { 60 | $query="SELECT id FROM ninupdates_regions WHERE ninupdates_regions.regioncode='".$region."'"; 61 | $result=mysqli_query($mysqldb, $query); 62 | $numrows=mysqli_num_rows($result); 63 | 64 | if($numrows==0) 65 | { 66 | dbconnection_end(); 67 | writeNormalLog("REGION ROW NOT FOUND. RESULT: 200"); 68 | header("Content-Type: text/plain"); 69 | echo "Invalid region.\n"; 70 | return; 71 | } 72 | } 73 | 74 | $reportid = 0; 75 | $curdate = ""; 76 | 77 | $text = ""; 78 | $reportname = ""; 79 | 80 | if($reportdate!="") 81 | { 82 | $query="SELECT id, updateversion, curdate FROM ninupdates_reports WHERE ninupdates_reports.reportdate='".$reportdate."' && ninupdates_reports.systemid=$systemid && ninupdates_reports.log='report'"; 83 | $result=mysqli_query($mysqldb, $query); 84 | $numrows=mysqli_num_rows($result); 85 | 86 | if($numrows==0) 87 | { 88 | dbconnection_end(); 89 | writeNormalLog("REPORT ROW NOT FOUND. RESULT: 200"); 90 | header("Content-Type: text/plain"); 91 | echo "Invalid reportdate.\n"; 92 | return; 93 | } 94 | else 95 | { 96 | $row = mysqli_fetch_row($result); 97 | if($row[1]=="N/A") 98 | { 99 | $text = "$sys $reportdate"; 100 | } 101 | else 102 | { 103 | $text = "$sys ".$row[1]; 104 | } 105 | $reportid = $row[0]; 106 | $curdate = $row[2]; 107 | } 108 | $reportname = $text; 109 | if($region!="")$text.= " $region"; 110 | } 111 | else 112 | { 113 | $text = $sys; 114 | } 115 | 116 | if($soapreply=="1" && $reportdate!="" && $region!="") 117 | { 118 | dbconnection_end(); 119 | 120 | $path = "$sitecfg_workdir/soap$system/$region/$reportdate.html.soap"; 121 | if(!file_exists($path)) 122 | { 123 | writeNormalLog("SOAPREPLY FILE DOESN'T EXIST: $path\n"); 124 | header("Content-Type: text/plain"); 125 | echo "The server reply data for this is not available.\n"; 126 | } 127 | else 128 | { 129 | $con = file_get_contents($path); 130 | 131 | if($con!==FALSE) 132 | { 133 | header("Content-Type: text/plain"); 134 | echo $con; 135 | } 136 | else 137 | { 138 | writeNormalLog("FAILED TO OPEN SOAPREPLY FILE: $path\n"); 139 | header("Content-Type: text/plain"); 140 | echo "The server reply data for this is not available.\n"; 141 | } 142 | } 143 | 144 | return; 145 | 146 | } 147 | 148 | if($genwiki!="") 149 | { 150 | header("Content-Type: text/plain"); 151 | 152 | $con.= "=== $text ===\n"; 153 | $con.= "{| class=\"wikitable\" border=\"1\"\n"; 154 | $con.= "|- 155 | ! TitleID 156 | ! Region 157 | ! Versions\n"; 158 | } 159 | else if($gencsv!="") 160 | { 161 | header("Content-Type: text/plain"); 162 | $con.= "TitleID,Region,Title versions,Update versions\n"; 163 | } 164 | else 165 | { 166 | $con .= "Nintendo System Update Titlelist $text\n"; 167 | 168 | $con.= "$sitecfg_sitenav_headerHomepage -> "; 169 | if($reportdate!="")$con.= "$reportname report -> "; 170 | if($reportdate=="")$con.= "$text "; 171 | if($region!="")$con.= "Region $region Titlelist"; 172 | if($region=="")$con.= "Titlelist"; 173 | if($usesoap!="")$con.= " SOAP"; 174 | $con.= "


    \n"; 175 | 176 | if($gentext=="") 177 | { 178 | $con.= " 179 | 180 | 181 | 182 | 183 | 184 | \n"; 185 | 186 | if($reportdate!="" && $usesoap=="")$con.=" \n"; 187 | 188 | $con.="\n"; 189 | } 190 | } 191 | 192 | $titlelist_array = array(); 193 | $titlelist_array_numentries = 0; 194 | 195 | $numrows = 0; 196 | 197 | $reportquery = ""; 198 | $soapquery = ""; 199 | if($reportdate!="") 200 | { 201 | if($usesoap=="")$reportquery = " && ninupdates_titles.reportid=$reportid && ninupdates_reports.id=$reportid"; 202 | if($usesoap!="")$soapquery = " && ninupdates_titles.curdate<='".$curdate."' && ninupdates_reports.curdate<='".$curdate."'"; 203 | } 204 | 205 | $regionquery = ""; 206 | if($region!="")$regionquery = " && ninupdates_titles.region='".$region."'"; 207 | 208 | $versionquery = "GROUP_CONCAT(DISTINCT ninupdates_titles.version ORDER BY ninupdates_titles.version SEPARATOR ','),"; 209 | 210 | $reportdatequery = "GROUP_CONCAT(DISTINCT ninupdates_reports.reportdate ORDER BY ninupdates_reports.curdate SEPARATOR ','),"; 211 | $updateverquery = "GROUP_CONCAT(DISTINCT ninupdates_reports.updateversion ORDER BY ninupdates_reports.curdate SEPARATOR ','),"; 212 | 213 | $filter_tid_query = ""; 214 | if($filter_tid!="")$filter_tid_query = " && ninupdates_titleids.titleid='".$filter_tid."'"; 215 | 216 | $query = "SELECT ninupdates_titles.tid, ninupdates_titleids.titleid, ninupdates_titleids.description, $versionquery ninupdates_titles.region, ninupdates_regions.regionid, $reportdatequery $updateverquery GROUP_CONCAT(fssize ORDER BY ninupdates_titles.version SEPARATOR ','), GROUP_CONCAT(tmdsize ORDER BY ninupdates_titles.version SEPARATOR ','), GROUP_CONCAT(tiksize ORDER BY ninupdates_titles.version SEPARATOR ','), ninupdates_titles.region FROM ninupdates_titles, ninupdates_titleids, ninupdates_reports, ninupdates_regions WHERE ninupdates_titles.systemid=$systemid && ninupdates_reports.systemid=$systemid && ninupdates_titles.tid=ninupdates_titleids.id && ninupdates_reports.id=ninupdates_titles.reportid && ninupdates_regions.regioncode=ninupdates_titles.region$filter_tid_query"; 217 | if($reportquery!="")$query.= $reportquery; 218 | if($soapquery!="")$query.= $soapquery; 219 | if($regionquery!="")$query.= $regionquery; 220 | 221 | $query.= " GROUP BY ninupdates_titles.tid, ninupdates_titles.region, ninupdates_regions.regionid"; 222 | 223 | $result=mysqli_query($mysqldb, $query); 224 | $numrows=mysqli_num_rows($result); 225 | $titlelist_array_numentries = $numrows; 226 | $titlelist_array_updatedtitles = 0; 227 | $titlelist_array_newtitles = 0; 228 | $regioncode = ""; 229 | 230 | $updatesize = 0; 231 | for($i=0; $i<$numrows; $i++) 232 | { 233 | $row = mysqli_fetch_row($result); 234 | $tid = $row[0]; 235 | $titleid = $row[1]; 236 | $desctext = $row[2]; 237 | $versions = $row[3]; 238 | $reg = $row[4]; 239 | $regionid = $row[5]; 240 | $reportdates = $row[6]; 241 | $updateversions = $row[7]; 242 | $regioncode = $row[11]; 243 | 244 | $versiontext = $versions; 245 | $updatevers = $updateversions; 246 | if($reportdates!=$reportdate) 247 | { 248 | $versiontext = ""; 249 | $updatevers = ""; 250 | $total_entries = 0; 251 | $version_array = array(); 252 | $reportdate_array = array(); 253 | $updateversion_array = array(); 254 | 255 | $ver = strtok($versions, ","); 256 | while($ver!==FALSE) 257 | { 258 | $version_array[] = "v$ver"; 259 | $total_entries++; 260 | $ver = strtok(","); 261 | } 262 | 263 | $cur_reportdate = strtok($reportdates, ","); 264 | while($cur_reportdate!==FALSE) 265 | { 266 | $reportdate_array[] = $cur_reportdate; 267 | $cur_reportdate = strtok(","); 268 | } 269 | 270 | $updatever = strtok($updateversions, ","); 271 | while($updatever!==FALSE) 272 | { 273 | $updateversion_array[] = $updatever; 274 | $updatever = strtok(","); 275 | } 276 | 277 | for($enti=0; $enti<$total_entries; $enti++) 278 | { 279 | $url = "titlelist.php?date=".$reportdate_array[$enti]."&sys=$system"; 280 | if($region!="")$url.= "&reg=$reg"; 281 | 282 | if($gencsv=="") 283 | { 284 | if($enti>0)$versiontext .= ", "; 285 | if($enti>0)$updatevers .= ", "; 286 | } 287 | else 288 | { 289 | if($enti>0)$versiontext .= " "; 290 | if($enti>0)$updatevers .= " "; 291 | } 292 | $updatevers.= $updateversion_array[$enti]; 293 | 294 | if($genwiki!="") 295 | { 296 | $versiontext .= "[[".$updateversion_array[$enti]."|".$version_array[$enti]."]]"; 297 | } 298 | else if($gencsv!="") 299 | { 300 | $versiontext .= $version_array[$enti]; 301 | } 302 | else 303 | { 304 | $versiontext .= "".$version_array[$enti].""; 305 | } 306 | } 307 | } 308 | else 309 | { 310 | $versiontext = "v$versions"; 311 | } 312 | 313 | for($sizei=8; $sizei<=10; $sizei++) 314 | { 315 | $tmpsizes = $row[$sizei]; 316 | $tmpsize = strtok($tmpsizes, ","); 317 | while($tmpsize!==FALSE) 318 | { 319 | $updatesize += $tmpsize; 320 | $tmpsize = strtok(","); 321 | } 322 | } 323 | 324 | $regtext = $regionid; 325 | if($reg!=$region && $genwiki=="" && $gencsv=="") 326 | { 327 | $url = "titlelist.php?"; 328 | if($reportdate!="")$url.= "date=$reportdate&"; 329 | $url.= "sys=$system&reg=$reg"; 330 | if($usesoap!="")$url.= "&soap=1"; 331 | if($filter_tid!="")$url.= "&tid=$titleid"; 332 | $regtext = "$regionid"; 333 | } 334 | 335 | $titleid_text = $titleid; 336 | if($filter_tid=="" && $genwiki=="" && $gencsv=="") 337 | { 338 | $url = "titlelist.php?"; 339 | if($reportdate!="")$url.= "date=$reportdate&"; 340 | $url.= "sys=$system"; 341 | if($region!="")$url.= "&reg=$reg"; 342 | if($usesoap!="")$url.= "&soap=1"; 343 | $url.= "&tid=$titleid"; 344 | $titleid_text = "$titleid"; 345 | } 346 | 347 | if($desctext == NULL || $desctext == "")$desctext = "N/A"; 348 | 349 | $titlelist_array[] = array(); 350 | $titlelist_array[$i][0] = $tid; 351 | $titlelist_array[$i][1] = $titleid; 352 | if($genwiki!="" || $gencsv!="") 353 | { 354 | $titlelist_array[$i][2] = $regionid; 355 | } 356 | else 357 | { 358 | $titlelist_array[$i][2] = $regtext; 359 | } 360 | 361 | $titlelist_array[$i][3] = $desctext; 362 | $titlelist_array[$i][4] = $versiontext; 363 | $titlelist_array[$i][5] = $updatevers; 364 | $titlelist_array[$i][6] = $versions; 365 | $titlelist_array[$i][7] = $regioncode; 366 | $titlelist_array[$i][8] = "N/A"; 367 | $titlelist_array[$i][9] = $titleid_text; 368 | } 369 | 370 | if($reportdate!="" && $usesoap=="" && ($genwiki=="" && $gencsv=="")) 371 | { 372 | $query = "SELECT ninupdates_titles.tid, ninupdates_titles.region, MIN(ninupdates_titles.version) FROM ninupdates_titles WHERE ninupdates_titles.systemid=$systemid".$regionquery." GROUP BY ninupdates_titles.tid, ninupdates_titles.region"; 373 | $result=mysqli_query($mysqldb, $query); 374 | $numrows=mysqli_num_rows($result); 375 | for($rowi=0; $rowi<$numrows; $rowi++) 376 | { 377 | $row = mysqli_fetch_row($result); 378 | $min_tid = $row[0]; 379 | $min_region = $row[1]; 380 | $min_version = $row[2]; 381 | 382 | for($i=0; $i<$titlelist_array_numentries; $i++) 383 | { 384 | $tid = $titlelist_array[$i][0]; 385 | $versions = $titlelist_array[$i][6]; 386 | $regioncode = $titlelist_array[$i][7]; 387 | 388 | if($tid == $min_tid && $regioncode == $min_region) 389 | { 390 | $titlestatus = "Changed"; 391 | if($versions==$min_version) 392 | { 393 | $titlestatus = "New"; 394 | $titlelist_array_newtitles++; 395 | } 396 | else 397 | { 398 | $titlelist_array_updatedtitles++; 399 | } 400 | 401 | $titlelist_array[$i][8] = $titlestatus; 402 | 403 | break; 404 | } 405 | } 406 | } 407 | } 408 | 409 | $count = 0; 410 | for($i=0; $i<$titlelist_array_numentries; $i++) 411 | { 412 | $tid = $titlelist_array[$i][0]; 413 | $titleid = $titlelist_array[$i][1]; 414 | $regtext = $titlelist_array[$i][2]; 415 | $desctext = $titlelist_array[$i][3]; 416 | $versiontext = $titlelist_array[$i][4]; 417 | $updatevers = $titlelist_array[$i][5]; 418 | $versions = $titlelist_array[$i][6]; 419 | $regioncode = $titlelist_array[$i][7]; 420 | $titlestatus = $titlelist_array[$i][8]; 421 | $titleid_text = $titlelist_array[$i][9]; 422 | 423 | if($genwiki!="") 424 | { 425 | $con.= "|- 426 | | $titleid 427 | | $regtext 428 | | $versiontext\n"; 429 | } 430 | else if($gencsv!="") 431 | { 432 | $con.= "$titleid,$regtext,$versiontext,$updatevers\n"; 433 | } 434 | else if($gentext=="") 435 | { 436 | $con.= "\n"; 437 | $con.= "\n"; 438 | $con.= "\n"; 439 | $con.= "\n"; 440 | $con.= "\n"; 441 | $con.= "\n"; 442 | if($reportdate!="" && $usesoap=="")$con.= "\n"; 443 | $con.= "\n"; 444 | } 445 | } 446 | 447 | if($gentext!="" && $titlelist_array_updatedtitles>0) 448 | { 449 | $con.= "
    The following titles were updated: "; 450 | 451 | $count = 0; 452 | for($i=0; $i<$titlelist_array_numentries; $i++) 453 | { 454 | $titleid = $titlelist_array[$i][1]; 455 | $regtext = $titlelist_array[$i][2]; 456 | $desctext = $titlelist_array[$i][3]; 457 | $versiontext = $titlelist_array[$i][4]; 458 | $updatevers = $titlelist_array[$i][5]; 459 | $versions = $titlelist_array[$i][6]; 460 | $regioncode = $titlelist_array[$i][7]; 461 | $titlestatus = $titlelist_array[$i][8]; 462 | 463 | if($titlestatus!="Changed")continue; 464 | 465 | if($count==$titlelist_array_updatedtitles-1 && $titlelist_array_updatedtitles>1)$con.= " and "; 466 | if(strstr($desctext, "N/A")!==FALSE) 467 | { 468 | $con.= "$titleid"; 469 | } 470 | else 471 | { 472 | $con.= "$desctext"; 473 | } 474 | if($region=="")$con.="($regtext)"; 475 | if($count<$titlelist_array_updatedtitles-1 && $titlelist_array_updatedtitles>1) 476 | { 477 | $con.= ", "; 478 | } 479 | else 480 | { 481 | $con.= ".
    \n"; 482 | } 483 | 484 | $count++; 485 | } 486 | } 487 | 488 | if($gentext!="" && $titlelist_array_newtitles>0) 489 | { 490 | $con.= "
    The following new titles were added: "; 491 | 492 | $count = 0; 493 | for($i=0; $i<$titlelist_array_numentries; $i++) 494 | { 495 | $titleid = $titlelist_array[$i][1]; 496 | $regtext = $titlelist_array[$i][2]; 497 | $desctext = $titlelist_array[$i][3]; 498 | $versiontext = $titlelist_array[$i][4]; 499 | $updatevers = $titlelist_array[$i][5]; 500 | $versions = $titlelist_array[$i][6]; 501 | $regioncode = $titlelist_array[$i][7]; 502 | $titlestatus = $titlelist_array[$i][8]; 503 | 504 | if($titlestatus=="Changed")continue; 505 | 506 | if($count==$titlelist_array_newtitles-1 && $titlelist_array_newtitles>1)$con.= " and "; 507 | if(strstr($desctext, "N/A")!==FALSE) 508 | { 509 | $con.= "$titleid"; 510 | } 511 | else 512 | { 513 | $con.= "$desctext"; 514 | } 515 | if($region=="")$con.="($regtext)"; 516 | if($count<$titlelist_array_newtitles-1 && $titlelist_array_newtitles>1) 517 | { 518 | $con.= ", "; 519 | } 520 | else 521 | { 522 | $con.= ".
    \n"; 523 | } 524 | 525 | $count++; 526 | } 527 | } 528 | 529 | if($genwiki=="") 530 | { 531 | if($gencsv=="" && $gentext=="")$con.= "
    TitleIDRegionTitle descriptionTitle versionsUpdate versionsTitle status
    $titleid_text$regtext$desctext$versiontext$updatevers$titlestatus
    "; 532 | } 533 | else 534 | { 535 | $con.= "|}\n"; 536 | } 537 | 538 | if($genwiki=="" && $gencsv=="" && $reportdate!="") 539 | { 540 | $con.= "
    \n"; 541 | if($updatesize!=0)$con.= "Total titles sizes: $updatesize
    \n"; 542 | 543 | if($region!="" && $usesoap=="" && $filter_tid=="") 544 | { 545 | $hashval = ""; 546 | $generation = 0; 547 | 548 | $query="SELECT ninupdates_systitlehashes.titlehash, ninupdates_consoles.generation FROM ninupdates_reports, ninupdates_consoles, ninupdates_systitlehashes WHERE ninupdates_systitlehashes.reportid=ninupdates_reports.id && ninupdates_reports.systemid=ninupdates_consoles.id && ninupdates_consoles.system='".$system."' && ninupdates_systitlehashes.region='".$region."' && ninupdates_reports.log='report' && ninupdates_reports.reportdate='".$reportdate."'"; 549 | $result=mysqli_query($mysqldb, $query); 550 | $numrows=mysqli_num_rows($result); 551 | 552 | if($numrows>0) 553 | { 554 | $row = mysqli_fetch_row($result); 555 | $hashval = $row[0]; 556 | $generation = $row[1]; 557 | } 558 | 559 | if($hashval===FALSE || $hashval=="")$hashval = "N/A"; 560 | 561 | $titlehash_text = "SOAP TitleHash"; 562 | if($generation!=0)$titlehash_text = "titleID+titleversion for sysupdate title"; 563 | $con.= "
    $titlehash_text: $hashval
    \n"; 564 | } 565 | 566 | if($reportdate!="" && $usesoap=="") 567 | { 568 | $con.= "
    \nTitle info:
    \n
    \n"; 569 | $titleinfo_count = 0; 570 | 571 | $titledata_base = "$sitecfg_workdir/sysupdatedl/autodl_sysupdates/$reportdate-$system"; 572 | $maxdepth = 4; 573 | if(is_dir($titledata_base) && $filter_tid!="") 574 | { 575 | if($titlelist_array_numentries>0) // Use the titleid/regtext from the db and not the user input for safety. 576 | { 577 | $titleid = $titlelist_array[0][1]; 578 | $regtext = $titlelist_array[0][2]; 579 | 580 | $maxdepth--; 581 | $titledata_base.= "/".$titleid; 582 | if($region!="") 583 | { 584 | $tmp_path = $titledata_base . "/".$regtext; 585 | if(is_dir($tmp_path)) 586 | { 587 | $titledata_base = $tmp_path; 588 | $maxdepth--; 589 | } 590 | } 591 | } 592 | } 593 | 594 | if(is_dir($titledata_base)) 595 | { 596 | $titledata_base.= "/"; 597 | try { 598 | $diriter = new RecursiveDirectoryIterator($titledata_base); 599 | $iter = new RecursiveIteratorIterator($diriter); 600 | $iter->setMaxDepth($maxdepth); 601 | $regex_iter = new RegexIterator($iter, '/^.*\..*info$/', RecursiveRegexIterator::GET_MATCH); 602 | foreach($regex_iter as $path => $pathobj) 603 | { 604 | $url = substr($path, strlen($sitecfg_workdir)+1); 605 | $con.= "$url
    \n"; 606 | 607 | $titleinfo_count++; 608 | } 609 | } 610 | catch (Exception $e) { 611 | //Don't print/whatever any error. 612 | } 613 | } 614 | 615 | if($titleinfo_count==0)$con.="N/A
    \n"; 616 | } 617 | } 618 | 619 | if($genwiki=="" && $gencsv=="")$con .= ""; 620 | 621 | dbconnection_end(); 622 | 623 | if($sitecfg_logplainhttp200!=0)writeNormalLog("RESULT: 200"); 624 | 625 | echo $con; 626 | 627 | ?> 628 | -------------------------------------------------------------------------------- /ninupdates/ninsoap.php: -------------------------------------------------------------------------------- 1 | =2) 12 | { 13 | //Hour is 24h. 14 | $tmp_month = 0; 15 | $tmp_day = 0; 16 | $tmp_year = 0; 17 | $tmp_hour = 0; 18 | $tmp_min = 0; 19 | $tmp_sec = 0; 20 | if(sscanf($argv[1], "%04u-%02u-%02u_%02u-%02u-%02u", $tmp_year, $tmp_month, $tmp_day, $tmp_hour, $tmp_min, $tmp_sec) == 6) 21 | { 22 | echo "Using the specified curtime_override.\n"; 23 | $curtime_override = gmmktime($tmp_hour, $tmp_min, $tmp_sec, $tmp_month, $tmp_day, $tmp_year); 24 | } 25 | else 26 | { 27 | echo "The specified curtime_override is invalid, ignoring it.\n"; 28 | } 29 | 30 | if($argc>=4) 31 | { 32 | $overridden_initial_titleid = $argv[2]; 33 | $overridden_initial_titleversion = $argv[3]; 34 | } 35 | } 36 | 37 | do_systems_soap(); 38 | 39 | function do_systems_soap() 40 | { 41 | global $mysqldb, $sitecfg_workdir, $sitecfg_httpbase, $reqstatus_notif; 42 | 43 | dbconnection_start(); 44 | ninupdates_setup(); 45 | 46 | $query="SELECT COUNT(*) FROM ninupdates_management"; 47 | $result=mysqli_query($mysqldb, $query); 48 | $numrows=mysqli_num_rows($result); 49 | 50 | if($numrows>0) 51 | { 52 | $row = mysqli_fetch_row($result); 53 | $count = $row[0]; 54 | 55 | if($count==0) 56 | { 57 | $query = "INSERT INTO ninupdates_management (maintenanceflag, lastscan) VALUES (0,'')"; 58 | $result=mysqli_query($mysqldb, $query); 59 | } 60 | } 61 | 62 | if(!db_checkmaintenance(0)) 63 | { 64 | init_curl(); 65 | 66 | $query="SELECT ninupdates_consoles.system FROM ninupdates_consoles WHERE enabled!=0 OR enabled IS NULL"; 67 | $result=mysqli_query($mysqldb, $query); 68 | $numrows=mysqli_num_rows($result); 69 | 70 | $reqstatus_notif=""; 71 | 72 | for($i=0; $i<$numrows; $i++) 73 | { 74 | $row = mysqli_fetch_row($result); 75 | dosystem($row[0]); 76 | } 77 | 78 | $query="UPDATE ninupdates_management SET lastscan='" . gmdate(DATE_RFC822, time()) . "'"; 79 | $result=mysqli_query($mysqldb, $query); 80 | 81 | close_curl(); 82 | 83 | if(strlen($reqstatus_notif)>0) 84 | { 85 | echo "Sending reqstatus notif...\n"; 86 | 87 | $reqstatus_timestamp = gmdate("Y-m-d_H-i-s"); 88 | 89 | $dirpath = "$sitecfg_workdir/reqstatus"; 90 | if(!is_dir($dirpath)) mkdir($dirpath, 0750); 91 | 92 | $ftmp = fopen("$dirpath/$reqstatus_timestamp", "w"); 93 | fwrite($ftmp, $reqstatus_notif); 94 | fclose($ftmp); 95 | 96 | $msg = "Last request status changed for system(s): $sitecfg_httpbase/reqstatus/".$reqstatus_timestamp . " https://www.nintendo.co.jp/netinfo/en_US/index.html"; 97 | 98 | send_notif([$msg, "--webhook", "--social", "--fedivisibility=unlisted"]); 99 | $reqstatus_notif=""; 100 | } 101 | 102 | $query="SELECT COUNT(*) FROM ninupdates_reports, ninupdates_consoles, ninupdates_officialchangelog_pages WHERE ninupdates_reports.updatever_autoset=0 AND ninupdates_reports.systemid=ninupdates_consoles.id AND ninupdates_officialchangelog_pages.systemid=ninupdates_consoles.id"; 103 | $result=mysqli_query($mysqldb, $query); 104 | $numrows=mysqli_num_rows($result); 105 | 106 | if($numrows>0) 107 | { 108 | $row = mysqli_fetch_row($result); 109 | $count = $row[0]; 110 | 111 | if($count>0) 112 | { 113 | echo "Starting a get_officialchangelog task for processing $count report(s)...\n"; 114 | 115 | $get_officialchangelog_timestamp = gmdate("Y-m-d_H-i-s"); 116 | 117 | $dirpath = "$sitecfg_workdir/get_officialchangelog_scheduled_out"; 118 | if(!is_dir($dirpath)) mkdir($dirpath, 0700); 119 | 120 | system("php ".escapeshellarg("$sitecfg_workdir/get_officialchangelog_cli.php")." > ".escapeshellarg("$dirpath/$get_officialchangelog_timestamp")." 2>&1 &"); 121 | } 122 | } 123 | 124 | $query="SELECT COUNT(*) FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.updatever_autoset=1 && ninupdates_reports.wikibot_runfinished=0 AND ninupdates_reports.systemid=ninupdates_consoles.id"; 125 | $result=mysqli_query($mysqldb, $query); 126 | $numrows=mysqli_num_rows($result); 127 | 128 | if($numrows>0) 129 | { 130 | $row = mysqli_fetch_row($result); 131 | $count = $row[0]; 132 | 133 | if($count>0) 134 | { 135 | echo "Starting a wikibot task for processing $count report(s)...\n"; 136 | 137 | $wikibot_timestamp = gmdate("Y-m-d_H-i-s"); 138 | 139 | $dirpath = "$sitecfg_workdir/wikibot_out"; 140 | if(!is_dir($dirpath)) mkdir($dirpath, 0700); 141 | 142 | system("php ".escapeshellarg("$sitecfg_workdir/wikibot.php")." scheduled > ".escapeshellarg("$dirpath/$wikibot_timestamp")." 2>&1 &"); 143 | } 144 | } 145 | 146 | // In case the changelog still isn't available 20mins after the report curdate, run wikibot without waiting on changelog. This assumes the updatever was updated via postproc by now, hence generation!=0. 147 | $query="SELECT COUNT(*) FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.updatever_autoset=0 && ninupdates_reports.wikibot_runfinished=0 AND ninupdates_reports.curdate < FROM_UNIXTIME(".(time() - 20*60).") AND ninupdates_consoles.generation!=0 AND ninupdates_reports.systemid=ninupdates_consoles.id"; 148 | $result=mysqli_query($mysqldb, $query); 149 | $numrows=mysqli_num_rows($result); 150 | 151 | if($numrows>0) 152 | { 153 | $row = mysqli_fetch_row($result); 154 | $count = $row[0]; 155 | 156 | if($count>0) 157 | { 158 | echo "Starting a wikibot updatever_autoset0 task for processing $count report(s)...\n"; 159 | 160 | $wikibot_timestamp = gmdate("Y-m-d_H-i-s"); 161 | 162 | $dirpath = "$sitecfg_workdir/wikibot_out_updatever_autoset0"; 163 | if(!is_dir($dirpath)) mkdir($dirpath, 0700); 164 | 165 | system("php ".escapeshellarg("$sitecfg_workdir/wikibot.php")." scheduled_updatever_autoset0 > ".escapeshellarg("$dirpath/$wikibot_timestamp")." 2>&1 &"); 166 | } 167 | } 168 | 169 | $query="SELECT ninupdates_reports.reportdate, ninupdates_consoles.system FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.postproc_runfinished=0 AND ninupdates_reports.systemid=ninupdates_consoles.id"; 170 | $result=mysqli_query($mysqldb, $query); 171 | $numrows=mysqli_num_rows($result); 172 | 173 | if($numrows>0) 174 | { 175 | echo "Starting post-processing tasks for processing $numrows report(s)...\n"; 176 | 177 | $postproc_timestamp = gmdate("Y-m-d_H-i-s"); 178 | 179 | $dirpath = "$sitecfg_workdir/postproc_out"; 180 | if(!is_dir($dirpath)) mkdir($dirpath, 0700); 181 | 182 | for($i=0; $i<$numrows; $i++) 183 | { 184 | $row = mysqli_fetch_row($result); 185 | $reportdate = $row[0]; 186 | $sys = $row[1]; 187 | 188 | $maincmd_str = "php $sitecfg_workdir/postproc.php $reportdate $sys"; 189 | 190 | $cmdout = system("ps aux | grep -c \"$maincmd_str\""); 191 | $proc_running = 0; 192 | if(is_numeric($cmdout)) 193 | { 194 | if($cmdout > 2)$proc_running = 1; 195 | } 196 | 197 | if($proc_running==0) 198 | { 199 | echo "Starting postproc task for $reportdate-$sys...\n"; 200 | system("$maincmd_str > $dirpath/$postproc_timestamp 2>&1 &"); 201 | } 202 | else 203 | { 204 | echo "The postproc task for $reportdate-$sys wasn't finished but the process is still running, skipping process creation for it.\n"; 205 | } 206 | } 207 | } 208 | 209 | dbconnection_end(); 210 | } 211 | } 212 | 213 | function dosystem($console) 214 | { 215 | global $mysqldb, $region, $system, $sitecfg_irc_msg_dirpath, $sitecfg_irc_msgtarget, $sitecfg_irc_msgtargets, $sitecfg_emailhost, $sitecfg_target_email, $sitecfg_httpbase, $sitecfg_workdir, $sitecfg_notif_fedi_append, $sitecfg_notif_fedi_append_system, $sysupdate_available, $soap_timestamp, $dbcurdate, $sysupdate_regions, $sysupdate_timestamp, $sysupdate_systitlehashes, $curtime_override, $reqstatus_notif; 216 | 217 | $system = $console; 218 | $msgme_message = ""; 219 | $html_message = ""; 220 | $sysupdate_available = 0; 221 | $sysupdate_timestamp = ""; 222 | $soap_timestamp = ""; 223 | $sysupdate_regions = ""; 224 | $dbcurdate = ""; 225 | $sysupdate_systitlehashes = array(); 226 | 227 | echo "System $system\n"; 228 | 229 | $query="SELECT ninupdates_consoles.regions FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$system."'"; 230 | $result=mysqli_query($mysqldb, $query); 231 | $row = mysqli_fetch_row($result); 232 | $regions = $row[0]; 233 | 234 | $query="SELECT ninupdates_consoles.lastreqstatus FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$system."'"; 235 | $result=mysqli_query($mysqldb, $query); 236 | $numrows=mysqli_num_rows($result); 237 | $lastreqstatus = ""; 238 | if($numrows>0) 239 | { 240 | $row = mysqli_fetch_row($result); 241 | $lastreqstatus = $row[0]; 242 | } 243 | 244 | // When the last report is <1h ago and the report regions don't match the system regions, reuse the report in case the remaining regions are detected. 245 | $reuse_report = False; 246 | if($curtime_override===0) 247 | { 248 | $query="SELECT ninupdates_reports.reportdaterfc, ninupdates_reports.regions, ninupdates_reports.reportdate FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.log='report' AND ninupdates_consoles.system='".$system."' AND ninupdates_reports.systemid=ninupdates_consoles.id ORDER BY ninupdates_reports.curdate DESC LIMIT 1"; 249 | $result=mysqli_query($mysqldb, $query); 250 | $numrows=mysqli_num_rows($result); 251 | if($numrows>0) 252 | { 253 | $row = mysqli_fetch_row($result); 254 | $last_report_timestamp = date_timestamp_get(date_create_from_format(DateTimeInterface::RFC822, $row[0])); 255 | $last_report_regions = $row[1]; 256 | $last_reportdate = $row[2]; 257 | $last_report_regions_cmp = str_replace(",", "", $last_report_regions); 258 | $check_time = time(); 259 | if(strlen($last_report_regions_cmp) !== strlen($regions) && $check_time > $last_report_timestamp && $check_time - $last_report_timestamp < 60*60) 260 | { 261 | echo "Regions mismatch compared against system/last-report. Reusing the existing report, last_reportdate = $last_reportdate.\n"; 262 | $sysupdate_timestamp = $last_reportdate; 263 | $reuse_report = True; 264 | } 265 | } 266 | } 267 | 268 | for($i=0; $i0) 277 | { 278 | $row = mysqli_fetch_row($result); 279 | $lastreqstatus_new = $row[0]; 280 | 281 | if($lastreqstatus==="" || $lastreqstatus===NULL)$lastreqstatus = "OK"; 282 | if($lastreqstatus_new==="" || $lastreqstatus_new===NULL)$lastreqstatus_new = "OK"; 283 | 284 | if($lastreqstatus !== $lastreqstatus_new) 285 | { 286 | echo "Req status changed since last scan.\n"; 287 | $msg = "Last " . getsystem_sysname($system) . " request status changed. Previous: \"$lastreqstatus\". Current: \"$lastreqstatus_new\"."; 288 | echo "msg: $msg\n"; 289 | 290 | // Batch these notifs for sending later. 291 | if(strlen($reqstatus_notif)>0) $reqstatus_notif.= "\n"; 292 | $reqstatus_notif.= $msg; 293 | } 294 | } 295 | 296 | if($sysupdate_available==0) 297 | { 298 | echo "System $system: No updated titles available.\n"; 299 | } 300 | else 301 | { 302 | $msgme_message = "$sitecfg_httpbase/reports.php?date=".$sysupdate_timestamp."&sys=".$system; 303 | $email_message = "$msgme_message"; 304 | 305 | $query="SELECT ninupdates_reports.reportdate FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_consoles.system='".$system."' AND ninupdates_reports.systemid=ninupdates_consoles.id AND ninupdates_reports.log='report'"; 306 | $result=mysqli_query($mysqldb, $query); 307 | $numrows=mysqli_num_rows($result); 308 | 309 | $initialscan = 0; 310 | if($numrows==0)$initialscan = 1; 311 | 312 | $updateversion = "N/A"; 313 | if($initialscan)$updateversion = "Initial_scan"; 314 | 315 | $query="SELECT ninupdates_reports.reportdate FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.reportdate='".$sysupdate_timestamp."' AND ninupdates_consoles.system='".$system."' AND ninupdates_reports.systemid=ninupdates_consoles.id AND ninupdates_reports.log='report'"; 316 | $result=mysqli_query($mysqldb, $query); 317 | $numrows=mysqli_num_rows($result); 318 | $report_exists = 0; 319 | $old_sysupdate_regions = ""; 320 | $new_sysupdate_regions = ""; 321 | if($numrows==0) 322 | { 323 | $query="SELECT ninupdates_consoles.id FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$system."'"; 324 | $result=mysqli_query($mysqldb, $query); 325 | $row = mysqli_fetch_row($result); 326 | $systemid = $row[0]; 327 | 328 | $query = "INSERT INTO ninupdates_reports (reportdate, curdate, systemid, log, regions, updateversion, reportdaterfc, initialscan, updatever_autoset, wikibot_runfinished, postproc_runfinished) VALUES ('".$sysupdate_timestamp."','".$dbcurdate."',$systemid,'report','".$sysupdate_regions."','".$updateversion."','".$soap_timestamp."',$initialscan,0,0,0)"; 329 | $result=mysqli_query($mysqldb, $query); 330 | $reportid = mysqli_insert_id($mysqldb); 331 | } 332 | else 333 | { 334 | //this will only happen when the report row already exists. 335 | $report_exists = 1; 336 | $query = "SELECT ninupdates_reports.id, ninupdates_reports.regions FROM ninupdates_reports, ninupdates_consoles WHERE ninupdates_reports.reportdate='".$sysupdate_timestamp."' AND ninupdates_consoles.system='".$system."' AND ninupdates_reports.systemid=ninupdates_consoles.id AND ninupdates_reports.log='report'"; 337 | $result=mysqli_query($mysqldb, $query); 338 | $row = mysqli_fetch_row($result); 339 | $reportid = $row[0]; 340 | $old_sysupdate_regions = $row[1]; 341 | $new_sysupdate_regions = $old_sysupdate_regions; 342 | } 343 | 344 | $region = strtok($sysupdate_regions, ","); 345 | while($region!==FALSE) 346 | { 347 | $query="SELECT COUNT(*) FROM ninupdates_systitlehashes WHERE ninupdates_systitlehashes.reportid='".$reportid."' AND ninupdates_systitlehashes.region='".$region."'"; 348 | $result=mysqli_query($mysqldb, $query); 349 | $numrows=mysqli_num_rows($result); 350 | $count=0; 351 | 352 | if($numrows>0) 353 | { 354 | $row = mysqli_fetch_row($result); 355 | $count = $row[0]; 356 | } 357 | 358 | if($count==0) 359 | { 360 | $query = "INSERT INTO ninupdates_systitlehashes (reportid, region, titlehash) VALUES ('".$reportid."','".$region."','".$sysupdate_systitlehashes[$region]."')"; 361 | $result=mysqli_query($mysqldb, $query); 362 | } 363 | 364 | if($report_exists == 1) 365 | { 366 | if(strstr($old_sysupdate_regions, $region)===FALSE) 367 | { 368 | if(strlen($new_sysupdate_regions)>0) $new_sysupdate_regions.= ","; 369 | $new_sysupdate_regions.= $region; 370 | } 371 | } 372 | 373 | $region = strtok(","); 374 | } 375 | 376 | if($report_exists == 1) 377 | { 378 | $query="UPDATE ninupdates_reports, ninupdates_consoles SET ninupdates_reports.regions='".$new_sysupdate_regions."', ninupdates_reports.updatever_autoset=0 WHERE ninupdates_reports.reportdate='".$sysupdate_timestamp."' AND ninupdates_consoles.system='".$system."' AND ninupdates_reports.systemid=ninupdates_consoles.id AND ninupdates_reports.log='report'"; 379 | $result=mysqli_query($mysqldb, $query); 380 | } 381 | 382 | $query="UPDATE ninupdates_titles SET reportid=$reportid WHERE curdate='".$dbcurdate."' AND reportid=0"; 383 | $result=mysqli_query($mysqldb, $query); 384 | 385 | if($initialscan==0)echo "System $system: System update available for regions $sysupdate_regions.\n"; 386 | if($initialscan)echo "System $system: Initial scan successful for regions $sysupdate_regions.\n"; 387 | 388 | echo "\nSending notifications...\n"; 389 | 390 | $notif_msg = "Sysupdate detected for " . getsystem_sysname($system) . ": $msgme_message"; 391 | 392 | if($reuse_report === True) 393 | { 394 | $notif_msg = "Sysupdate detected for " . getsystem_sysname($system) . " for an existing report with additional region(s): $msgme_message"; 395 | } 396 | 397 | $args = [$notif_msg, "--social", "--webhook"]; 398 | if($reuse_report === True) 399 | { 400 | $args[] = "--fedivisibility=unlisted"; 401 | } 402 | 403 | if($sitecfg_irc_msg_dirpath!="") 404 | { 405 | $targets = array(); 406 | if($sitecfg_irc_msgtarget!="") $targets[] = $sitecfg_irc_msgtarget; 407 | if(isset($sitecfg_irc_msgtargets)) 408 | { 409 | if(isset($sitecfg_irc_msgtargets["$system"])) 410 | { 411 | $targets[] = $sitecfg_irc_msgtargets["$system"]; 412 | } 413 | } 414 | if(count($targets)>0) 415 | { 416 | $args[] = "--irc"; 417 | $args[] = "--irctarget"; 418 | foreach($targets as $target) 419 | { 420 | if(strlen($target)>0) 421 | { 422 | $args[] = $target; 423 | } 424 | } 425 | } 426 | } 427 | if($initialscan==0 && $reuse_report===False) 428 | { 429 | $notif_fedi = ""; 430 | if(isset($sitecfg_notif_fedi_append)) $notif_fedi.= " ".$sitecfg_notif_fedi_append; 431 | if(isset($sitecfg_notif_fedi_append_system)) 432 | { 433 | if(isset($sitecfg_notif_fedi_append_system["$system"])) 434 | { 435 | $notif_fedi.= " ".$sitecfg_notif_fedi_append_system["$system"]; 436 | } 437 | } 438 | if($notif_fedi!="") 439 | { 440 | $args[] = "--fedi"; 441 | $args[] = $notif_msg.$notif_fedi; 442 | } 443 | } 444 | send_notif($args); 445 | if($sitecfg_target_email!="" && $sitecfg_emailhost!="") 446 | { 447 | echo "Sending email...\n"; 448 | if(!mail($sitecfg_target_email, "$system sysupdates", $email_message, "From: ninsoap@$sitecfg_emailhost"))echo "Failed to send mail.\n"; 449 | } 450 | 451 | /*echo "Writing to the lastupdates_csvurls file...\n"; 452 | $msg = "$sitecfg_httpbase/titlelist.php?date=".$sysupdate_timestamp."&sys=".$system."&csv=1"; 453 | $tmp_cmd = "echo '" . $msg . "' >> $sitecfg_workdir/lastupdates_csvurls"; 454 | system($tmp_cmd);*/ 455 | } 456 | } 457 | 458 | function initialize($generation) 459 | { 460 | global $mysqldb, $hdrs, $soapreq, $fp, $system, $region, $sitecfg_workdir, $soapreq_data, $httpreq_useragent, $console_deviceid, $sitecfg_consoles_deviceid; 461 | 462 | error_reporting(E_ALL); 463 | 464 | $regionid = ""; 465 | $countrycode = ""; 466 | 467 | $query="SELECT deviceid, platformid, subplatformid, useragent_fw, eid FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$system."'"; 468 | $result=mysqli_query($mysqldb, $query); 469 | $numrows=mysqli_num_rows($result); 470 | 471 | if($numrows) 472 | { 473 | $row = mysqli_fetch_row($result); 474 | $deviceid = $row[0]; 475 | $platformid = $row[1]; 476 | $subplatformid = $row[2]; 477 | 478 | $useragent_fw = $row[3]; 479 | $eid = $row[4]; 480 | 481 | if(isset($sitecfg_consoles_deviceid)) 482 | { 483 | if(isset($sitecfg_consoles_deviceid["$system"]["$region"])) $deviceid = $sitecfg_consoles_deviceid["$system"]["$region"]; 484 | } 485 | 486 | $console_deviceid = $deviceid; 487 | 488 | if($generation==0) 489 | { 490 | $platformid = ($platformid << 32); 491 | if($subplatformid != NULL && $subplatformid != "")$platformid |= ($subplatformid << 31); 492 | 493 | if($platformid != NULL && $platformid != "") 494 | { 495 | $deviceid = $platformid | rand(0, 0x7fffffff); 496 | } 497 | } 498 | } 499 | else 500 | { 501 | echo("Row doesn't exist in the db for system $system.\n"); 502 | exit(1); 503 | } 504 | 505 | $query="SELECT regionid, countrycode FROM ninupdates_regions WHERE ninupdates_regions.regioncode='".$region."'"; 506 | $result=mysqli_query($mysqldb, $query); 507 | $row = mysqli_fetch_row($result); 508 | 509 | if($numrows) 510 | { 511 | $regionid = $row[0]; 512 | $countrycode = $row[1]; 513 | } 514 | else 515 | { 516 | echo("Row doesn't exist in the db for region $region.\n"); 517 | exit(2); 518 | } 519 | 520 | if($generation==0) 521 | { 522 | $httpreq_useragent = "ds libnup/2.0"; 523 | } 524 | else 525 | { 526 | if($useragent_fw==="" || $useragent_fw===NULL) 527 | { 528 | echo("useragent_fw field isn't set for system $system.\n"); 529 | exit(3); 530 | } 531 | if($eid==="" || $eid===NULL) 532 | { 533 | echo("eid field isn't set for system $system.\n"); 534 | exit(4); 535 | } 536 | 537 | $httpreq_useragent = "NintendoSDK Firmware/" . $useragent_fw . " (platform:NX; did:" . $deviceid . "; eid:" . $eid . ")"; 538 | } 539 | 540 | if($generation==0) 541 | { 542 | $soapreq_data = " 543 | 546 | 547 | 548 | 1.0 549 | 1 550 | $deviceid 551 | $regionid 552 | $countrycode 553 | 2 554 | 555 | 556 | "; 557 | } 558 | 559 | if($generation==0) 560 | { 561 | $hdrs = array('SOAPAction: "urn:nus.wsapi.broadon.com/GetSystemUpdate"', 'Content-Type: application/xml', 'Content-Size: '.strlen($soapreq_data), 'Connection: Keep-Alive', 'Keep-Alive: 30'); 562 | } 563 | else 564 | { 565 | $hdrs = array('Accept:application/json'); 566 | } 567 | 568 | init_titlelistarray(); 569 | } 570 | 571 | function init_curl() 572 | { 573 | global $curl_handle, $sitecfg_workdir, $error_FH; 574 | 575 | $dirpath = "$sitecfg_workdir/debuglogs"; 576 | if(!is_dir($dirpath)) mkdir($dirpath, 0770); 577 | 578 | $path = "$dirpath/error.log"; 579 | $error_FH = fopen($path, "w"); // truncate 580 | fclose($error_FH); 581 | $error_FH = fopen($path, "a"); // Use append-mode so that each curl request logs properly (otherwise only the last request is logged). 582 | $curl_handle = curl_init(); 583 | } 584 | 585 | function close_curl() 586 | { 587 | global $curl_handle, $error_FH; 588 | 589 | curl_close($curl_handle); 590 | fclose($error_FH); 591 | } 592 | 593 | function send_httprequest($url, $generation) 594 | { 595 | global $mysqldb, $hdrs, $soapreq, $httpstat, $sitecfg_workdir, $soapreq_data, $httpreq_useragent, $curl_handle, $system, $region, $error_FH; 596 | 597 | $query="SELECT clientcertfn, clientprivfn FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$system."'"; 598 | $result=mysqli_query($mysqldb, $query); 599 | $row = mysqli_fetch_row($result); 600 | $clientcertfn = $row[0]; 601 | $clientprivfn = $row[1]; 602 | 603 | curl_setopt($curl_handle, CURLOPT_VERBOSE, true); 604 | curl_setopt($curl_handle, CURLOPT_STDERR, $error_FH); 605 | 606 | curl_setopt($curl_handle, CURLOPT_USERAGENT, $httpreq_useragent); 607 | 608 | curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true); 609 | 610 | curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $hdrs); 611 | 612 | if($generation==0) 613 | { 614 | curl_setopt($curl_handle, CURLOPT_POST, 1); 615 | curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $soapreq_data); 616 | } 617 | else 618 | { 619 | curl_setopt($curl_handle, CURLOPT_POST, 0); 620 | } 621 | 622 | curl_setopt($curl_handle, CURLOPT_URL, $url); 623 | 624 | if(strstr($url, "https") && $clientcertfn!="" && $clientprivfn!="") 625 | { 626 | $certbasepath = "$sitecfg_workdir/sslcerts"; 627 | $certbasepath_region = "$certbasepath/$region"; 628 | if(file_exists("$certbasepath_region/$clientcertfn")===TRUE && file_exists("$certbasepath_region/$clientprivfn")===TRUE) $certbasepath = $certbasepath_region; 629 | 630 | curl_setopt($curl_handle, CURLOPT_SSLCERTTYPE, "PEM"); 631 | curl_setopt($curl_handle, CURLOPT_SSLCERT, "$certbasepath/$clientcertfn"); 632 | curl_setopt($curl_handle, CURLOPT_SSLKEY, "$certbasepath/$clientprivfn"); 633 | 634 | curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, 0); 635 | curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, 0); 636 | } 637 | 638 | $buf = curl_exec($curl_handle); 639 | 640 | $errorstr = ""; 641 | 642 | $httpstat = curl_getinfo($curl_handle, CURLINFO_HTTP_CODE); 643 | if($buf===FALSE) 644 | { 645 | $errorstr = "HTTP request failed: " . curl_error ($curl_handle); 646 | $httpstat = "0"; 647 | } else if($httpstat!="200")$errorstr = "HTTP error $httpstat: " . curl_error ($curl_handle); 648 | 649 | if($errorstr!="")$buf = $errorstr; 650 | 651 | $query="UPDATE ninupdates_consoles SET lastreqstatus='" . mysqli_real_escape_string($mysqldb, $errorstr) . "' WHERE ninupdates_consoles.system='".$system."'"; 652 | $result=mysqli_query($mysqldb, $query); 653 | 654 | fflush($error_FH); 655 | 656 | return $buf; 657 | } 658 | 659 | function load_titlelist_withcmd($reportdate) 660 | { 661 | global $sitecfg_workdir, $sitecfg_load_titlelist_cmd, $system, $region, $newtitles, $newtitlesversions, $newtotal_titles; 662 | 663 | if($newtotal_titles < 1) 664 | { 665 | echo "newtotal_titles is <1.\n"; 666 | return -2; 667 | } 668 | 669 | $titleid = $newtitles[0]; 670 | $titlever = $newtitlesversions[0]; 671 | 672 | $dirpath = "$sitecfg_workdir/load_titlelist_data"; 673 | if(!is_dir($dirpath)) mkdir($dirpath, 0700); 674 | 675 | $filepath = "$dirpath/titlelist"; 676 | if(!is_dir($filepath)) mkdir($filepath, 0700); 677 | 678 | $filepath = "$filepath/$reportdate-$system"; 679 | $maincmd_str = "$sitecfg_load_titlelist_cmd ".escapeshellarg($reportdate)." ".escapeshellarg($system)." ".escapeshellarg($region)." ".escapeshellarg($filepath)." ".escapeshellarg($dirpath)." ".escapeshellarg("$titleid,$titlever"); 680 | 681 | echo "Running load_titlelist cmd...\n"; 682 | $retval = 0; 683 | $ret = system("$maincmd_str > ".escapeshellarg("$sitecfg_workdir/load_titlelist_out/$reportdate-$system")." 2>&1", $retval); 684 | if($ret===FALSE || $retval!=0) 685 | { 686 | echo "cmd failed.\n"; 687 | if($retval>0)$retval = -$retval; 688 | if($retval==0)$retval = -3; 689 | return $retval; 690 | } 691 | 692 | if(file_exists($filepath)===FALSE) 693 | { 694 | echo "The titlelist file doesn't exist.\n"; 695 | return -1; 696 | } 697 | 698 | $buf = file_get_contents($filepath); 699 | if($buf===FALSE) 700 | { 701 | echo "Failed to load the titlelist file.\n"; 702 | return -1; 703 | } 704 | 705 | parse_soapresp($buf, 1);//Reuse the SOAP format. 706 | 707 | return 0; 708 | } 709 | 710 | function titlelist_dbupdate_withcmd($curdate, $generation) 711 | { 712 | global $system; 713 | 714 | if($generation!=0) 715 | { 716 | $retval = load_titlelist_withcmd($curdate); 717 | if($retval!=0) 718 | { 719 | $msg = "load_titlelist_withcmd() for $curdate-$system failed."; 720 | echo "Sending notif: $msg\n"; 721 | send_notif([$msg, "--admin"]); 722 | return $retval; 723 | } 724 | } 725 | 726 | return titlelist_dbupdate(); 727 | } 728 | 729 | function compare_titlelists($curdate, $generation) 730 | { 731 | global $mysqldb, $system, $region, $sysupdate_systitlehashes; 732 | 733 | $query="SELECT ninupdates_systitlehashes.titlehash FROM ninupdates_reports, ninupdates_consoles, ninupdates_systitlehashes WHERE ninupdates_systitlehashes.reportid=ninupdates_reports.id AND ninupdates_reports.systemid=ninupdates_consoles.id AND ninupdates_consoles.system='".$system."' AND ninupdates_systitlehashes.region='".$region."' AND ninupdates_reports.log='report' ORDER BY ninupdates_reports.curdate DESC LIMIT 1"; 734 | $result=mysqli_query($mysqldb, $query); 735 | $numrows=mysqli_num_rows($result); 736 | 737 | if($numrows==0) 738 | { 739 | //echo "System $system Region $region: Titlehash is missing.\n"; 740 | return titlelist_dbupdate_withcmd($curdate, $generation); 741 | } 742 | else 743 | { 744 | $row = mysqli_fetch_row($result); 745 | $titlehashold = $row[0]; 746 | 747 | if($sysupdate_systitlehashes[$region]!=$titlehashold) 748 | { 749 | if(($titlehashold!=NULL && $titlehashold!="") && ($sysupdate_systitlehashes[$region]!=NULL && $sysupdate_systitlehashes[$region]!="")) 750 | { 751 | $msg = "Potential sysupdate detected for $system region $region, checking titlelist..."; 752 | echo "Sending notif: $msg\n"; 753 | send_notif([$msg, "--webhook"]); 754 | } 755 | 756 | return titlelist_dbupdate_withcmd($curdate, $generation); 757 | } 758 | else 759 | { 760 | return 0; 761 | } 762 | } 763 | 764 | return 0; 765 | } 766 | 767 | function main($reg) 768 | { 769 | global $mysqldb, $system, $log, $region, $httpstat, $syscmd, $sitecfg_httpbase, $sysupdate_available, $sysupdate_timestamp, $sitecfg_workdir, $curdate, $dbcurdate, $soap_timestamp, $sysupdate_regions, $arg_difflogold, $arg_difflognew, $newtotal_titles, $console_deviceid, $curtime_override; 770 | 771 | $region = $reg; 772 | 773 | $query="SELECT nushttpsurl, generation FROM ninupdates_consoles WHERE ninupdates_consoles.system='".$system."'"; 774 | $result=mysqli_query($mysqldb, $query); 775 | $row = mysqli_fetch_row($result); 776 | $nushttpsurl = $row[0]; 777 | $generation = $row[1]; 778 | 779 | initialize($generation); 780 | 781 | if($generation==0) 782 | { 783 | $url = "$nushttpsurl/nus/services/NetUpdateSOAP"; 784 | } 785 | else 786 | { 787 | $hostpos = strpos($nushttpsurl, ".nintendo.net"); 788 | $chn_host = "n.nintendoswitch.cn"; 789 | if($hostpos!==FALSE && $region=="C") 790 | { 791 | $nushttpsurl = substr($nushttpsurl, 0, $hostpos); 792 | $nushttpsurl = "$nushttpsurl.$chn_host"; 793 | } 794 | else if($region=="C") $nushttpsurl = "$nushttpsurl.$chn_host"; 795 | $url = "$nushttpsurl/v1/system_update_meta?device_id=" . $console_deviceid; 796 | } 797 | 798 | for($i=0; $i<5; $i++) 799 | { 800 | $ret = send_httprequest($url, $generation); 801 | if($httpstat!="0")break; 802 | } 803 | 804 | if($httpstat=="200") 805 | { 806 | if($generation==0) 807 | { 808 | parse_soapresp($ret, 0); 809 | } 810 | else 811 | { 812 | $retval = parse_json_resp($ret); 813 | if($retval!=0)return; 814 | } 815 | } 816 | else 817 | { 818 | echo $ret . "\n"; 819 | return; 820 | } 821 | 822 | if($curtime_override==0) 823 | { 824 | $curtime = time(); 825 | } 826 | else 827 | { 828 | $curtime = $curtime_override; 829 | } 830 | $soap_timestamp = gmdate(DATE_RFC822, $curtime); 831 | 832 | $curdate = gmdate("Y-m-d_H-i-s", $curtime); 833 | if($sysupdate_timestamp!="")$curdate = $sysupdate_timestamp; 834 | $curdatefn = $curdate . ".html"; 835 | 836 | if($dbcurdate=="") 837 | { 838 | $query = "SELECT FROM_UNIXTIME($curtime)"; 839 | $result=mysqli_query($mysqldb, $query); 840 | $row = mysqli_fetch_row($result); 841 | $dbcurdate = $row[0]; 842 | } 843 | 844 | if($curtime_override!=0) 845 | { 846 | echo "Using overridden timestamps: soap_timestamp = '".$soap_timestamp."', curdate='".$curdate."', dbcurdate='".$dbcurdate."'.\n"; 847 | } 848 | 849 | $sendupdatelogs = 0; 850 | 851 | $query = "SELECT COUNT(*) FROM ninupdates_titles, ninupdates_consoles WHERE ninupdates_titles.region='".$region."' AND ninupdates_titles.systemid=ninupdates_consoles.id AND ninupdates_consoles.system='".$system."'"; 852 | $result=mysqli_query($mysqldb, $query); 853 | $numrows=mysqli_num_rows($result); 854 | 855 | if($numrows>0) 856 | { 857 | $row = mysqli_fetch_row($result); 858 | $count = $row[0]; 859 | } 860 | else 861 | { 862 | $count = 0; 863 | } 864 | 865 | if($count==0 && $newtotal_titles>0) 866 | { 867 | $retval = titlelist_dbupdate_withcmd($curdate, $generation); 868 | if($retval < 0) 869 | { 870 | echo "titlelist_dbupdate_withcmd() failed.\n"; 871 | return; 872 | } 873 | 874 | $fsoap = fopen("$sitecfg_workdir/soap$system/$region/$curdatefn.soap", "w"); 875 | fwrite($fsoap, $ret); 876 | fclose($fsoap); 877 | 878 | echo "System $system: This is first scan for region $region, unknown if any titles were recently updated.\n"; 879 | 880 | $sendupdatelogs = 1; 881 | } 882 | else 883 | { 884 | $retval = compare_titlelists($curdate, $generation); 885 | if($retval < 0) 886 | { 887 | echo "compare_titlelists() failed.\n"; 888 | return; 889 | } 890 | 891 | if($retval) 892 | { 893 | $sendupdatelogs = 1; 894 | 895 | $fsoap = fopen("$sitecfg_workdir/soap$system/$region/$curdatefn.soap", "w"); 896 | fwrite($fsoap, $ret); 897 | fclose($fsoap); 898 | } 899 | else 900 | { 901 | $sendupdatelogs = 0; 902 | } 903 | } 904 | 905 | if($sendupdatelogs) 906 | { 907 | $sysupdate_available = 1; 908 | if($sysupdate_timestamp=="")$sysupdate_timestamp = $curdate; 909 | 910 | if($sysupdate_regions!="")$sysupdate_regions.= ","; 911 | $sysupdate_regions.= $region; 912 | } 913 | 914 | } 915 | 916 | ?> 917 | --------------------------------------------------------------------------------