public static function loadBasicDummyData() { TestManager::clearDatabase(); $database = new DatabaseManager(); UserManager::verifyTable($database); AddonManager::verifyTable($database); BoardManager::verifyTable($database); TagManager::verifyTable($database); GroupManager::verifyTable($database); DependencyManager::verifyTable($database); CommentManager::verifyTable($database); RatingManager::verifyTable($database); BuildManager::verifyTable($database); StatManager::verifyTable($database); ScreenshotManager::verifyTable($database); if (!$database->query("INSERT INTO `addon_boards` (name, video, description) VALUES ('General Content', 'general_content_bg', 'Bricks, Events, Sounds, Prints, Environments, and much more!')")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("INSERT INTO `addon_boards` (name, video, description) VALUES ('Minigames', 'minigames_bg', 'Weapons, Vehicles, Gamemodes, and all your gaming needs!')")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("INSERT INTO `addon_boards` (name, video, description) VALUES ('Client Mods', 'client_mods_bg', 'Mods that run on your client.')")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("INSERT INTO `addon_boards` (name, video, description) VALUES ('Bargain Bin', 'bargain_bin_bg', 'A home for \\'special\\' content.')")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("INSERT INTO `users` (username, blid, password, email, salt, verified) VALUES ('testuser', '4833', '1d8436e97ef95a7a6151f47b909167c77cfe1985ee5500efa8d46cfe825abc59', '*****@*****.**', '273eb4', '1')")) { throw new Exception("Database error: " . $database->error()); } //the default json types likely need to be reworked if (!$database->query("INSERT INTO `addon_addons` (board, blid, name, filename, description, approved, versionInfo, authorInfo, reviewInfo) VALUES ('1', '4833', 'crapy adon', 'sciprt_hax.zip', 'bad addone pls delete', '1', '{}', '[]', '[]')")) { throw new Exception("Database error: " . $database->error()); } StatManager::addStatsToAddon(1); if (!$database->query("INSERT INTO `addon_tags` (name, base_color, icon) VALUES ('dum tag', 'ff6600', 'brokenimage')")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("INSERT INTO `addon_tagmap` (aid, tid) VALUES ('1', '1')")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("INSERT INTO `group_groups` (leader, name, description, color, icon) VALUES ('4833', 'legion of dumies', 'a group for people who just want to be in a group', '00ff00', 'brokenimage')")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("INSERT INTO `group_usermap` (gid, blid, administrator) VALUES ('1', '4833', '1')")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("INSERT INTO `addon_comments` (blid, aid, comment) VALUES ('4833', '1', 'glorious addon comrade')")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("INSERT INTO `addon_ratings` (blid, aid, rating) VALUES ('4833', '1', '1')")) { throw new Exception("Database error: " . $database->error()); } }
public function getTotalDownloads() { return StatManager::getTotalAddonDownloads($this->id); }
<?php require_once realpath(dirname(__FILE__) . "/StatManager.php"); $sid = StatManager::getPreviousStats(); return StatManager::getFromID($sid);
public static function approveAddon($id, $board, $approver) { $database = new DatabaseManager(); $database->query("UPDATE `addon_addons` SET `approved`='1', `board`='" . $database->sanitize($board) . "' WHERE `id`='" . $database->sanitize($id) . "'"); $manager = AddonManager::getFromId($id)->getManagerBLID(); $params = new stdClass(); $params->vars = array(); $user = new stdClass(); $user->type = "user"; $user->blid = $approver; $addon = new stdClass(); $addon->type = "addon"; $addon->id = $id; $params->vars[] = $user; $params->vars[] = $addon; NotificationManager::createNotification($manager, '$2 was approved by $1', $params); StatManager::addStatsToAddon($id); }
} else { echo "<b>" . $percentage . "%</b>"; } ?> of Blockland as of this moment. Glass has <b> <?php echo $ct = UserLog::getUniqueCount(); ?> </b> active <?php echo $ct == 1 ? "user" : "users"; ?> , with a total of <a href="stats/"><?php $web = StatManager::getAllAddonDownloads("web") + 0; $ingame = StatManager::getAllAddonDownloads("ingame") + 0; $updates = StatManager::getAllAddonDownloads("updates") + 0; echo $web + $ingame; ?> </b></a> downloads and <b><?php echo $updates; ?> </b> updates. </p> <br /> <p> <h3>Want to get involved?</h3> Blockland Glass is an open-source project open to any contributions. If you're interested, please contribute on <a href="https://github.com/BlocklandGlass">GitHub</a> and check out the <a href="https://forum.blockland.us/index.php?topic=284376.0">Blockland Glass Topic</a> over on the Blockland Forums! </p> </div> <?php
public static function endInteration() { $database = new DatabaseManager(); StatManager::verifyTable($database); //gather lifetime counts //do we include AND `banned` = 0 ? $resource = $database->query("SELECT COUNT(*) FROM `users` WHERE `verified` = 1"); if (!$resource) { throw new Exception("Database error: " . $database->error()); } else { $users = $resource->fetch_row()[0]; $resource->close(); } $resource = $database->query("SELECT COUNT(*) FROM `addon_addons` WHERE `deleted` = 0"); if (!$resource) { throw new Exception("Database error: " . $database->error()); } else { $addons = $resource->fetch_row()[0]; $resource->close(); } $resource = $database->query("SELECT SUM(totalDownloads) FROM `addon_stats`"); if (!$resource) { throw new Exception("Database error: " . $database->error()); } else { $downloads = $resource->fetch_row()[0]; $resource->close(); } $resource = $database->query("SELECT COUNT(*) FROM `group_groups`"); if (!$resource) { throw new Exception("Database error: " . $database->error()); } else { $groups = $resource->fetch_row()[0]; $resource->close(); } $resource = $database->query("SELECT COUNT(*) FROM `build_builds` WHERE `deleted` = 0"); if (!$resource) { throw new Exception("Database error: " . $database->error()); } else { $builds = $resource->fetch_row()[0]; $resource->close(); } $resource = $database->query("SELECT COUNT(*) FROM `addon_tags`"); if (!$resource) { throw new Exception("Database error: " . $database->error()); } else { $tags = $resource->fetch_row()[0]; $resource->close(); } //gather top addons, tags, and builds $resource = $database->query("SELECT `aid` FROM `addon_stats`\n\t\t\tORDER BY `iterationDownloads` DESC\n\t\t\tLIMIT '" . $database->sanitize(StatManager::$addonCount) . "'"); if (!$resource) { throw new Exception("Database error: " . $database->error()); } $topAddonID = []; $topAddonDownloads = []; for ($i = 0; $i < StatManager::$addonCount; $i++) { if ($row = $resource->fetch_object()) { $topAddonID[] = $row->aid; $topAddonDownloads[] = $row->iterationDownloads; } else { $topAddonID[] = 1; $topAddonDownloads[] = 0; } } $resource->close(); $resource = $database->query("SELECT `tid` FROM `tag_stats`\n\t\t\tORDER BY `iterationDownloads` DESC\n\t\t\tLIMIT '" . $database->sanitize(StatManager::$tagCount) . "'"); if (!$resource) { throw new Exception("Database error: " . $database->error()); } $topTagID = []; $topTagDownloads = []; for ($i = 0; $i < StatManager::$tagCount; $i++) { if ($row = $resource->fetch_object()) { $topTagID[] = $row->tid; $topTagDownloads[] = $row->iterationDownloads; } else { $topTagID[] = 1; $topTagDownloads[] = 0; } } $resource->close(); $resource = $database->query("SELECT `bid` FROM `build_stats` ORDER BY `iterationDownloads` DESC LIMIT '" . $database->sanitize(StatManager::$buildCount) . "'"); if (!$resource) { throw new Exception("Database error: " . $database->error()); } $topBuildID = []; $topBuildDownloads = []; for ($i = 0; $i < StatManager::$buildCount; $i++) { if ($row = $resource->fetch_object()) { $topBuildID[] = $row->tid; $topBuildDownloads[] = $row->iterationDownloads; } else { $topBuildID[] = 1; $topBuildDownloads[] = 0; } } $resource->close(); //construct a query $baseQuery = "INSERT INTO `statistics` (`users`, `addons`, `downloads`, `groups`, `comments`, `builds`, `tags`"; $valQuery = ") VALUES ('" . $database->sanitize($users) . "', '" . $database->sanitize($addons) . "', '" . $database->sanitize($downloads) . "', '" . $database->sanitize($groups) . "', '" . $database->sanitize($comments) . "', '" . $database->sanitize($builds) . "', '" . $database->sanitize($tags) . "'"; $endQuery = ")"; $addonBase = ""; $addonVal = ""; $tagBase = ""; $tagVal = ""; $buildBase = ""; $buildVal = ""; for ($i = 0; $i < StatManager::$addonCount; $i++) { $addonBase .= ", `addon" . $i . "`, `addonDownloads" . $i . "`"; $addonVal .= ", '" . $database->sanitize($topAddon[$i]) . "', '" . $database->sanitize($topAddonDownloads[$i]) . "'"; } for ($i = 0; $i < StatManager::$tagCount; $i++) { $tagBase .= ", `tag" . $i . "`, `tagDownloads" . $i . "`"; $tagVal .= ", '" . $database->sanitize($topTag[$i]) . "', '" . $database->sanitize($topTagDownloads[$i]) . "'"; } for ($i = 0; $i < StatManager::$buildCount; $i++) { $buildBase .= ", `build" . $i . "`, `buildDownloads" . $i . "`"; $buildVal .= ", '" . $database->sanitize($topBuild[$i]) . "', '" . $database->sanitize($topBuildDownloads[$i]) . "'"; } //push stats into database if (!$database->query($baseQuery . $addonBase . $tagBase . $buildBase . $valQuery . $addonVal . $tagVal . $buildVal . $endQuery)) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("UPDATE `addon_stats` SET `iterationDownloads` = 0")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("UPDATE `tag_stats` SET `iterationDownloads` = 0")) { throw new Exception("Database error: " . $database->error()); } if (!$database->query("UPDATE `build_stats` SET `iterationDownloads` = 0")) { throw new Exception("Database error: " . $database->error()); } apc_delete('lastStats'); }
/** * Upload a build with contents as an array of strings */ public static function uploadBuild($blid, $buildName, $fileName, $contents, $tempPath, $description = false) { //to do, generate a random name for storage?, and allow the build name to contain any characters and be not unique - done - check //if(!preg_match("/^[a-zA-Z0-9\-\_\ \'\!]{1,56}\.bls$/", $fileName)) { if (!BuildManager::validateFileName($fileName)) { $response = ["message" => "Invalid File Name - You may use up to 56 characters followed by '.bls' and include letters, numbers, spaces, and the following symbols: -, ', _, and !"]; return $response; } //if(!preg_match("/^.{1,60}$/", $buildName)) { if (!BuildManager::validateTitle($buildName)) { $response = ["message" => "Your Build Title can only contain up to 60 characters and cannot contain line breaks"]; return $response; } //temporary file storage for now //$targetPath = dirname(__DIR__) . "/../builds/uploads/" . $buildName . ".bls"; $check = BuildManager::validateBLSContents($contents); //to do: //actual file saving - check //create database entries - check //start stat tracking - check? //redirect user to manage page - check //event logging if (!$check['ok']) { $response = ["message" => $check['message']]; return $response; } if ($description === false) { $description = $check['description']; } //it's go time $database = new DatabaseManager(); BuildManager::verifyTable($database); if (!$database->query("INSERT INTO `build_builds` (`blid`, `name`, `filename`, `bricks`, `description`) VALUES ('" . $database->sanitize($blid) . "', '" . $database->sanitize($buildName) . "', '" . $database->sanitize($fileName) . "', '" . $database->sanitize($check['brickcount']) . "', '" . $database->sanitize($description) . "')")) { throw new Exception("Database error: " . $database->error()); } $id = $database->fetchMysqli()->insert_id; require_once realpath(dirname(__FILE__) . '/AWSFileManager.php'); AWSFileManager::uploadNewBuild($id, $fileName, $tempPath); require_once realpath(dirname(__FILE__) . '/StatManager.php'); StatManager::addStatsToBuild($id); $response = ["redirect" => "/builds/manage.php?id=" . $id]; return $response; }
$file["stable"] = $res->file_stable; $file["unstable"] = $res->file_testing; $file["development"] = $res->file_dev; $versionData = array(); foreach ($file as $branch => $fid) { if ($fid != 0) { $version = new stdClass(); $fileRes = $mysql->query("SELECT * FROM `addon_files` WHERE `id`='" . $fid . "'"); $hash = $fileRes->fetch_object()->hash; $oldfile = $dir . $hash . ".zip"; $bid = $branchId[$branch]; echo "Uploading {$oldfile} to AWS as {$res->id}_{$bid}.zip<br />"; //AWSFileManager::upload("addons/{$res->id}_{$bid}", $oldfile); AWSFileManager::uploadNewAddon($res->id, $bid, $res->filename, $oldfile); $updateRes = $mysql->query("SELECT *\nFROM `addon_updates`\nWHERE `aid` = '" . $aid . "'\nAND `branch`='" . $bid . "' ORDER BY `time` DESC\nLIMIT 0 , 1"); if ($updateRes->num_rows == 0) { $version->version = "0.0.0"; $version->restart = "0.0.0"; } else { $obj = $updateRes->fetch_object(); $version->version = $obj->version; $version->restart = $obj->version; //not worth it } $versionData[$branch] = $version; } } $db->query($sql = "INSERT INTO `addon_addons` (`id`, `board`, `blid`, `name`, `filename`, `description`, `versionInfo`, `authorInfo`, `reviewInfo`, `deleted`, `approved`, `uploadDate`) VALUES " . "('" . $db->sanitize($res->id) . "'," . "NULL," . "'" . $db->sanitize($res->author) . "'," . "'" . $db->sanitize($res->name) . "'," . "'" . $db->sanitize($res->filename) . "'," . "'" . $db->sanitize($res->description) . "'," . "'" . $db->sanitize(json_encode($versionData)) . "'," . "'" . $db->sanitize(json_encode($authorDat)) . "'," . "''," . "'0'," . "'0'," . "CURRENT_TIMESTAMP);"); StatManager::addStatsToAddon($res->id); echo "Imported"; echo $db->error();
<?php header('Content-Type: text/json'); require_once dirname(__DIR__) . '/class/CronStatManager.php'; require_once dirname(__DIR__) . '/class/StatManager.php'; StatManager::endIteration();
<?php require_once realpath(dirname(__DIR__) . "/class/AddonManager.php"); require_once realpath(dirname(__DIR__) . "/class/StatManager.php"); $addonIDs = StatManager::getTrendingAddons(10); $addons = []; foreach ($addonIDs as $aid) { $addon = AddonManager::getFromID($aid); if ($addon !== false) { $addons[] = $addon; } } return $addons;
public function getDownloads($type) { return StatManager::getAddonDownloads($this->id, $type); }
<?php header('Content-Type: text/json'); require_once dirname(__DIR__) . '/class/CronStatManager.php'; $csm = new CronStatManager(); $csm->collectHourStat(true); require_once dirname(__DIR__) . '/class/StatManager.php'; StatManager::saveHistory(); //require_once dirname(__DIR__) . '/class/AddonManager.php'; //AddonManager::checkUpstreamRepos();
<?php require_once dirname(__DIR__) . "/private/class/GroupManager.php"; require_once dirname(__DIR__) . "/private/class/UserManager.php"; require_once dirname(__DIR__) . "/private/class/CronStatManager.php"; require_once dirname(__DIR__) . "/private/class/StatUsageManager.php"; $_PAGETITLE = "Blockland Glass | Add-On Stats"; include realpath(dirname(__DIR__) . "/private/header.php"); include realpath(dirname(__DIR__) . "/private/navigationbar.php"); $user = UserManager::getCurrent(); $addon = AddonManager::getFromId($_GET['id']); $csm = new CronStatManager(); //$data = $csm->getRecentAddonUsage($addon->getId()); $dist = StatUsageManager::getDistribution($addon->getId()); $downloadData = StatManager::getHourlyDownloads($addon->getId(), 24); $downloadData[date("Y-m-d H:i:s")] = StatManager::getStatistics($addon->getId()); ?> <div class="maincontainer"> <div class="tile"> <h2><a href="/addons/addon.php?id=<?php echo $addon->getId(); ?> "><?php echo $addon->getName(); ?> </a></h2>Statistics </div> <div class="tile" style="width: calc(50% - 40px); float:left; display: inline-block"> <b>Version Usage Chart</b> <hr /> <canvas id="myChart" style="width:100%;height:300px"></canvas>
public static function uploadNewAddon($user, $name, $type, $file, $filename, $description) { $database = new DatabaseManager(); AddonManager::verifyTable($database); $rsc = $database->query("SELECT * FROM `addon_addons` WHERE `name` = '" . $database->sanitize($name) . "' LIMIT 1"); //I think we should enforce a unique file name, but not a unique addon name if ($rsc->num_rows > 0) { $response = ["message" => "An add-on by this name already exists!"]; $rsc->close(); return $response; } $rsc->close(); $rsc = $database->query("SELECT * FROM `addon_addons` WHERE `filename` = '" . $database->sanitize($filename) . "'"); if ($rsc->num_rows > 0) { $response = ["message" => "An add-on with this filename already exists!"]; $rsc->close(); return $response; } $rsc->close(); $bid = 1; // TODO Specify branch in upload //generate blank version data $versionInfo = AddonFileHandler::getVersionInfo($file); var_dump($versionInfo); if ($versionInfo !== false) { // information to use for upstream repos $version = new stdClass(); $version->stable = new stdClass(); $version->stable->version = $versionInfo->version; $version->stable->restart = "0.0.0"; $url = parse_url($versionInfo->repo->url); if (!isset($url['host'])) { $url['host'] = $versionInfo->repo->url; } if ($url['host'] == "blocklandglass.com" || $url['host'] == "api.blocklandglass.com") { // nothing? } else { $upstream = new stdClass(); $upstream->url = $versionInfo->repo->url; if (isset($versionInfo->repo->mod)) { $upstream->mod = $versionInfo->repo->mod; } $upstream->branch = array(); $upstream->branch[$bid] = $versionInfo->channel; $version->upstream = $upstream; } } else { $version = new stdClass(); $version->stable = new stdClass(); $version->stable->version = "0.0.0"; $version->stable->restart = "0.0.0"; $repo = new stdClass(); } $authorInfo = new stdClass(); $authorInfo->blid = $user->getBlid(); $authorInfo->main = true; $authorInfo->role = "Manager"; $authorArray = [$authorInfo]; // NOTE boards will be decided by reviewers now, they just seem to confuse and anger people // I think making that change at this point will cause more problems than it solves. // It is better to just have reviewers move boards $res = $database->query("INSERT INTO `addon_addons` (`id`, `board`, `blid`, `name`, `filename`, `description`, `versionInfo`, `authorInfo`, `reviewInfo`, `deleted`, `approved`, `uploadDate`) VALUES " . "(NULL," . "NULL," . "'" . $database->sanitize($user->getBlid()) . "'," . "'" . $database->sanitize($name) . "'," . "'" . $database->sanitize($filename) . "'," . "'" . $database->sanitize($description) . "'," . "'" . $database->sanitize(json_encode($version)) . "'," . "'" . $database->sanitize(json_encode($authorArray)) . "'," . "'{}'," . "'0'," . "'0'," . "CURRENT_TIMESTAMP);"); if (!$res) { throw new Exception("Database error: " . $database->error()); } $id = $database->fetchMysqli()->insert_id; AddonFileHandler::injectGlassFile($id, $file); //AddonFileHandler::injectVersionInfo($id, $bid, $file); // TODO need to specify branch in upload require_once realpath(dirname(__FILE__) . '/AWSFileManager.php'); //AWSFileManager::uploadNewAddon($id, $bid, $filename, $file); require_once realpath(dirname(__FILE__) . '/StatManager.php'); StatManager::addStatsToAddon($id); $response = ["redirect" => "/addons/upload/success.php?id=" . $id]; return $response; }
<?php require_once realpath(dirname(__DIR__) . "/private/class/AddonManager.php"); require_once realpath(dirname(__DIR__) . "/private/class/StatManager.php"); $id = $_REQUEST['id']; $addonObject = AddonManager::getFromId($id); if ($addonObject) { StatManager::downloadAddon($addonObject); $branchId["stable"] = 1; $branchId["unstable"] = 2; $branchId["development"] = 3; if (isset($_REQUEST['branch'])) { $bid = $branchId[$_REQUEST['branch']]; } else { $bid = 1; } //StatManager::addStatsToAddon($addonObject->getId()); //header('Location: http://cdn.blocklandglass.com/builds/6.bls'); header('Location: http://cdn.blocklandglass.com/addons/' . $id . "_" . $bid); } else { header('Status: 404'); header('Location: /error.php'); }
public static function getAllAddonDownloads($type) { if ($type == "ingame") { $sql = "ingameDownloads"; } else { if ($type == "update" || $type == "updates") { $sql = "updateDownloads"; } else { $sql = "webDownloads"; } } $db = new DatabaseManager(); StatManager::verifyTable($db); $res = $db->query("SELECT sum(`{$sql}`) as sum FROM `addon_stats`"); $sum = $res->fetch_object()->sum; return $sum; }
$type = $_REQUEST['type']; //addon_update, addon_download, build, rtb if (isset($_REQUEST['debug'])) { $debug = $_REQUEST['debug']; } if ($type == "addon_update" || $type == "addon_download") { $id = $_REQUEST['id']; if (isset($_REQUEST['branch'])) { $branch = $_REQUEST['branch']; } else { $branch = 1; } if ($type == "addon_update") { StatManager::downloadAddonID($id, "update"); } else { StatManager::downloadAddonID($id, "ingame"); } $head = 'Location: http://' . AWSFileManager::getBucket() . '/addons/' . $id . '_' . $branch; if ($debug) { echo $head; } else { header($head); } $ao = AddonManager::getFromID($id); /* //ideal code? need to review how stats work and are kept //(object, type[0=web, 1=ingame, 2=update], increment) AddonManager::incrementDailyDownloads($ao, 1 ,1); AddonManager::incrementWeeklyDownloads($ao, 1, 1); AddonManager::incrementTotalDownloads($ao, 1, 1); */