Added sample data generation based on Markov chaining.

This commit is contained in:
flash 2022-02-24 23:49:37 +00:00
parent 029e996b58
commit 21526491c6
25 changed files with 634 additions and 2 deletions

View file

@ -2,6 +2,10 @@
> Misuzu can and will steal your lunch money.
## Requirements
- PHP 7.4
- MariaDB 10.4
- PHP 8.1
- MariaDB 10.6
- [Composer](https://getcomposer.org/)
## Important
DON'T RUN ANYTHING IN THE `devel` FOLDER IN PRODUCTION UNLESS YOU SERIOUSLY WANT TO FUCK EVERYTHING UP.

482
devel/insert-bogus-data.php Normal file
View file

@ -0,0 +1,482 @@
<?php
// Rewrite this script when everything has proper objects associated with it and use those objects
require_once __DIR__ . '/../misuzu.php';
if(!MSZ_DEBUG)
die('Not running in debug mode. Are you sure you want to run this?' . PHP_EOL);
require_once __DIR__ . '/sample/MarkovDictionary.php';
define('MKV_DICTS', __DIR__ . '/sample/dicts');
define('MKV_PASSWD', '123456');
define('MKV_MAIL', 'msz-%d@flash.moe');
define('MKV_ALPHA', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
define('MKV_ALPHA_LEN', strlen(MKV_ALPHA));
function mkv_log(string $string): void {
printf('[%s] %s%s', date('H:i:s'), $string, PHP_EOL);
}
mkv_log('Filling database with markov data...');
mkv_log('Yoinked Database instance from Misuzu...');
$db = \Misuzu\DB::getInstance();
mkv_log('Opening role dictionaries...');
$roleNames = new MarkovDictionary(MKV_DICTS . '/roles_names.fmk');
$roleDescs = new MarkovDictionary(MKV_DICTS . '/roles_descs.fmk');
$roleTitles = new MarkovDictionary(MKV_DICTS . '/roles_titles.fmk');
mkv_log('Nuking roles table...');
$db->exec('DELETE FROM `msz_roles` WHERE `role_id` > 1');
$db->exec('ALTER TABLE `msz_roles` AUTO_INCREMENT = 2');
mkv_log('Running slow cron to ensure main role exists...');
// running cron before fuckery
(new \Misuzu\Console\Commands\CronCommand)->dispatch(
new \Misuzu\Console\CommandArgs(['--slow'])
);
mkv_log('Preparing role and permissions insert statements...');
$cr = $db->prepare('INSERT INTO `msz_roles` (`role_hierarchy`, `role_name`, `role_title`, `role_description`, `role_hidden`, `role_can_leave`, `role_colour`) VALUES (:rank, :name, :title, :desc, :hide, :leave, :colour)');
$cp = $db->prepare('REPLACE INTO `msz_permissions` (`role_id`, `general_perms_allow`, `user_perms_allow`, `changelog_perms_allow`, `news_perms_allow`, `forum_perms_allow`, `comments_perms_allow`) VALUES (:role, :general, :user, :changelog, :news, :forum, :comments)');
mkv_log('Adding permissions for main role...');
$cp->bind('role', 1);
$cp->bind('general', 0);
$cp->bind('user', 59);
$cp->bind('changelog', 0);
$cp->bind('news', 0);
$cp->bind('forum', 0);
$cp->bind('comments', 137);
$cp->execute();
mkv_log('Creating Global Moderator role...');
$cr->bind('rank', 5);
$cr->bind('name', 'Global Moderator');
$cr->bind('title', 'Moderator');
$cr->bind('desc', 'They are global and in moderation.');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 1693465);
$cr->execute();
mkv_log('Adding permissions for Global Moderator...');
$cp->bind('role', $rIdMod = $db->lastId());
$cp->bind('general', 3);
$cp->bind('user', 25165887);
$cp->bind('changelog', 0);
$cp->bind('news', 0);
$cp->bind('forum', 0);
$cp->bind('comments', 57);
$cp->execute();
mkv_log('Creating Administrator role...');
$cr->bind('rank', 10);
$cr->bind('name', 'Administrator');
$cr->bind('title', 'Administrator');
$cr->bind('desc', 'Administration nation.');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 16711680);
$cr->execute();
mkv_log('Adding permissions for Administrator...');
$cp->bind('role', $rIdAdm = $db->lastId());
$cp->bind('general', 39);
$cp->bind('user', 28311615);
$cp->bind('changelog', 3);
$cp->bind('news', 3);
$cp->bind('forum', 3);
$cp->bind('comments', 249);
$cp->execute();
mkv_log('Creating Bot role...');
$cr->bind('rank', 7);
$cr->bind('name', 'Bot');
$cr->bind('title', null);
$cr->bind('desc', 'Service users.');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 10390951);
$cr->execute();
$rIdBot = $db->lastId();
mkv_log('Creating Tester role...');
$cr->bind('rank', 1);
$cr->bind('name', 'Tester');
$cr->bind('title', null);
$cr->bind('desc', 'Experimentalists.');
$cr->bind('hide', 1);
$cr->bind('leave', 1);
$cr->bind('colour', 1073741824);
$cr->execute();
mkv_log('Adding permissions for Tester...');
$cp->bind('role', $rIdTest = $db->lastId());
$cp->bind('general', 16);
$cp->bind('user', 0);
$cp->bind('changelog', 3);
$cp->bind('news', 0);
$cp->bind('forum', 0);
$cp->bind('comments', 0);
$cp->execute();
mkv_log('Creating OG role...');
$cr->bind('rank', 1);
$cr->bind('name', 'OG');
$cr->bind('title', null);
$cr->bind('desc', 'Arbitrarily selected people that joined in 2013 and 2014.');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 15740285);
$cr->execute();
mkv_log('Creating Developer role...');
$cr->bind('rank', 5);
$cr->bind('name', 'Developer');
$cr->bind('title', 'Developer');
$cr->bind('desc', 'Moderators but without the requirement to moderate.');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 7558084);
$cr->execute();
mkv_log('Adding permissions for Developer...');
$cp->bind('role', $rIdDev = $db->lastId());
$cp->bind('general', 3);
$cp->bind('user', 25165887);
$cp->bind('changelog', 3);
$cp->bind('news', 0);
$cp->bind('forum', 0);
$cp->bind('comments', 57);
$cp->execute();
mkv_log('Creating Tenshi role...');
$cr->bind('rank', 1);
$cr->bind('name', 'Tenshi');
$cr->bind('title', 'Supporter');
$cr->bind('desc', 'Donators');
$cr->bind('hide', 0);
$cr->bind('leave', 0);
$cr->bind('colour', 15635456);
$cr->execute();
mkv_log('Adding permissions for Tenshi...');
$cp->bind('role', $rIdTen = $db->lastId());
$cp->bind('general', 0);
$cp->bind('user', 4);
$cp->bind('changelog', 0);
$cp->bind('news', 0);
$cp->bind('forum', 0);
$cp->bind('comments', 0);
$cp->execute();
for($i = 0; $i < 10; ++$i) {
mkv_log('Creating bogus role ' . $i . '...');
$cr->bind('rank', mt_rand(1, 4));
$cr->bind('name', $roleNames->generate());
$cr->bind('title', (mt_rand(0, 100) > 50) ? $roleTitles->generate() : null);
$cr->bind('desc', (mt_rand(0, 100) > 10) ? $roleDescs->generate() : null);
$cr->bind('hide', mt_rand(0, 1));
$cr->bind('leave', mt_rand(0, 1));
$cr->bind('colour', ((mt_rand(0, 255) << 16) | (mt_rand(0, 255) << 8) | mt_rand(0, 255)));
$cr->execute();
}
mkv_log('Opening user related markov dictionaries...');
$userNames = new MarkovDictionary(MKV_DICTS . '/users_names.fmk');
$userTitles = new MarkovDictionary(MKV_DICTS . '/users_titles.fmk');
$userSigs = new MarkovDictionary(MKV_DICTS . '/users_sigs.fmk');
$userAbouts = new MarkovDictionary(MKV_DICTS . '/users_abouts.fmk');
mkv_log('Nuking users table...');
$db->exec('DELETE FROM `msz_users`');
$db->exec('ALTER TABLE `msz_users` AUTO_INCREMENT = 1');
mkv_log('Preparing user insert statements...');
$cu = $db->prepare('INSERT INTO `msz_users` (`username`, `password`, `email`, `register_ip`, `last_ip`, `user_super`, `user_country`, `user_about_content`, `user_about_parser`, `user_signature_content`, `user_signature_parser`, `user_birthdate`, `user_title`, `display_role`) VALUES (:name, :pass, :mail, :reg_addr, :last_addr, :super, :country, :about_text, :about_parse, :sig_text, :sig_parse, :birth, :title, :role)');
$ur = $db->prepare('REPLACE INTO `msz_user_roles` (`user_id`, `role_id`) VALUES (:user, :role)');
mkv_log('Creating admin user...');
mkv_log('NOTICE: All passwords will be set to: ' . MKV_PASSWD);
mkv_log('NOTICE: E-mail address will follow the format of: ' . MKV_MAIL);
$cu->bind('name', 'admin');
$cu->bind('pass', password_hash(MKV_PASSWD, PASSWORD_ARGON2ID));
$cu->bind('mail', sprintf(MKV_MAIL, 1));
$cu->bind('reg_addr', "\x7f\0\0\1");
$cu->bind('last_addr', "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1");
$cu->bind('super', 1);
$cu->bind('country', 'NL');
$cu->bind('about_text', '# Default administrator account');
$cu->bind('about_parse', 2);
$cu->bind('sig_text', '[b]Administrative Signature[/b]');
$cu->bind('sig_parse', 1);
$cu->bind('birth', '2013-01-27');
$cu->bind('title', null);
$cu->bind('role', 3);
$cu->execute();
mkv_log('Adding Global Moderator role to admin...');
$ur->bind('user', 1);
$ur->bind('role', 2);
$ur->execute();
mkv_log('Adding Administrator role to admin...');
$ur->bind('user', 1);
$ur->bind('role', 3);
$ur->execute();
mkv_log('Adding Developer role to admin...');
$ur->bind('user', 1);
$ur->bind('role', 8);
$ur->execute();
$cu->bind('super', 0);
for($i = 1; $i < 2000; ++$i) {
mkv_log('Creating bogus user ' . $i . '...');
$cu->bind('name', mb_substr($userNames->generate(), 0, 200, 'utf-8') . $i);
$cu->bind('pass', password_hash(MKV_PASSWD, PASSWORD_ARGON2ID));
$cu->bind('mail', sprintf(MKV_MAIL, ($i + 1)));
$cu->bind('reg_addr', random_bytes(mt_rand(0, 1) ? 4 : 16));
$cu->bind('last_addr', random_bytes(mt_rand(0, 1) ? 4 : 16));
$cu->bind('country', MKV_ALPHA[mt_rand(0, MKV_ALPHA_LEN - 1)] . MKV_ALPHA[mt_rand(0, MKV_ALPHA_LEN - 1)]);
$cu->bind('about_text', mb_substr($userAbouts->generate(), 0, 60000, 'utf-8'));
$cu->bind('about_parse', mt_rand(0, 2));
$cu->bind('sig_text', mb_substr($userSigs->generate(), 0, 1000, 'utf-8'));
$cu->bind('sig_parse', mt_rand(0, 2));
$cu->bind('birth', date('Y-m-d', mt_rand(1, 0x7FFFFFFF)));
$cu->bind('title', mt_rand(0, 100) > 90 ? mb_substr($userTitles->generate(), 0, 64, 'utf-8') : null);
$cu->bind('role', mt_rand(9, 18));
$cu->execute();
$uId = $db->lastId();
for($j = 0; $j < mt_rand(1, 4); ++$j) {
$brid = mt_rand(9, 18);
mkv_log('Adding role ' . $brid . ' to bogus user id ' . $uId . '...');
$ur->bind('user', $uId);
$ur->bind('role', $brid);
$ur->execute();
}
}
mkv_log('Opening changelog tag markov dictionaries...');
$changeTagsNames = new MarkovDictionary(MKV_DICTS . '/changes_tags_names.fmk');
$changeTagsDescs = new MarkovDictionary(MKV_DICTS . '/changes_tags_descs.fmk');
mkv_log('Nuking changelog tags table...');
$db->exec('DELETE FROM `msz_changelog_tags`');
$db->exec('ALTER TABLE `msz_changelog_tags` AUTO_INCREMENT = 1');
mkv_log('Preparing changelog insert statements...');
$ct = $db->prepare('INSERT INTO `msz_changelog_tags` (`tag_name`, `tag_description`) VALUES (:name, :descr)');
$cTagIds = [];
for($i = 0; $i < 20; ++$i) {
mkv_log('Inserting bogus changelog tag...');
$ct->bind('name', mb_substr($changeTagsNames->generate(), 0, 200, 'utf-8') . $i);
$ct->bind('descr', mb_substr($changeTagsDescs->generate(), 0, 60000, 'utf-8'));
$ct->execute();
$cTagIds[] = $db->lastId();
}
mkv_log('Opening changelog changes markov dictionaries...');
$changeLogs = new MarkovDictionary(MKV_DICTS . '/changes_logs.fmk');
$changeTexts = new MarkovDictionary(MKV_DICTS . '/changes_texts.fmk');
mkv_log('Nuking changelog changes tables...');
$db->exec('DELETE FROM `msz_changelog_changes`');
$db->exec('ALTER TABLE `msz_changelog_changes` AUTO_INCREMENT = 1');
mkv_log('Preparing changelog changes statements...');
$cc = $db->prepare('INSERT INTO `msz_changelog_changes` (`user_id`, `change_action`, `change_created`, `change_log`, `change_text`) VALUES (:user, :action, FROM_UNIXTIME(:created), :log, :text)');
$ctt = $db->prepare('REPLACE INTO `msz_changelog_change_tags` (`change_id`, `tag_id`) VALUES (:change, :tag)');
$max = mt_rand(1000, 10000);
mkv_log('Inserting ' . $max . ' changelog entries...');
for($i = 0; $i < $max; ++$i) {
mkv_log('Inserting bogus change ' . $i . '...');
$userId = mt_rand(-100, 2000);
if($userId < 1)
$userId = null;
$cc->bind('user', $userId);
$cc->bind('action', mt_rand(0, 6));
$cc->bind('created', mt_rand(1, 0x7FFFFFFF));
$cc->bind('log', mb_substr($changeLogs->generate(), 0, 240, 'utf-8'));
$cc->bind('text', mt_rand(0, 100) > 90 ? mb_substr($changeTexts->generate(), 0, 60000, 'utf-8') : null);
$cc->execute();
$ctt->bind('change', $db->lastId());
for($j = 0; $j < mt_rand(1, 5); ++$j) {
$btag = $cTagIds[array_rand($cTagIds)];
mkv_log('Adding tag ' . $btag . ' to bogus change ' . $i . '...');
$ctt->bind('tag', $btag);
$ctt->execute();
}
}
mkv_log('Opening news category markov dictionaries...');
$newsCatsNames = new MarkovDictionary(MKV_DICTS . '/news_cats_names.fmk');
$newsCatsDescs = new MarkovDictionary(MKV_DICTS . '/news_cats_descs.fmk');
mkv_log('Nuking news categories table...');
$db->exec('DELETE FROM `msz_news_categories`');
$db->exec('ALTER TABLE `msz_news_categories` AUTO_INCREMENT = 1');
mkv_log('Preparing news categories insert statements...');
$nc = $db->prepare('INSERT INTO `msz_news_categories` (`category_name`, `category_description`, `category_is_hidden`) VALUES (:name, :descr, :hidden)');
$ncIds = [];
for($i = 0; $i < 10; ++$i) {
mkv_log('Creating bogus news category ' . $i . '...');
$nc->bind('name', mb_substr($newsCatsNames->generate(), 0, 200, 'utf-8'));
$nc->bind('descr', mb_substr($newsCatsDescs->generate(), 0, 60000, 'utf-8'));
$nc->bind('hidden', mt_rand(0, 1));
$nc->execute();
$ncIds[] = $db->lastId();
}
mkv_log('Opening news post markov dictionaries...');
$newsPostsTitles = new MarkovDictionary(MKV_DICTS . '/news_posts_titles.fmk');
$newsPostsTexts = new MarkovDictionary(MKV_DICTS . '/news_posts_texts.fmk');
mkv_log('Nuking news posts table...');
$db->exec('DELETE FROM `msz_news_posts`');
$db->exec('ALTER TABLE `msz_news_posts` AUTO_INCREMENT = 1');
mkv_log('Preparing news posts table...');
$np = $db->prepare('INSERT INTO `msz_news_posts` (`category_id`, `user_id`, `post_is_featured`, `post_title`, `post_text`) VALUES (:category, :user, :featured, :title, :text)');
for($i = 0; $i < 200; ++$i) {
mkv_log('Creating bogus news post ' . $i . '...');
$np->bind('category', $ncIds[array_rand($ncIds)]);
$np->bind('user', mt_rand(1, 2000));
$np->bind('featured', mt_rand(0, 1));
$np->bind('title', mb_substr($newsPostsTitles->generate(), 0, 200, 'utf-8'));
$np->bind('text', mb_substr($newsPostsTexts->generate(), 0, 60000, 'utf-8'));
$np->execute();
}
mkv_log('Opening forum category markov dictionaries...');
$forumCatsNames = new MarkovDictionary(MKV_DICTS . '/forums_cats_names.fmk');
$forumCatsDescs = new MarkovDictionary(MKV_DICTS . '/forums_cats_descs.fmk');
mkv_log('Nuking forum category table...');
$db->exec('DELETE FROM `msz_forum_categories`');
$db->exec('ALTER TABLE `msz_forum_categories` AUTO_INCREMENT = 1');
mkv_log('Inserting 5 root categories and permissions...');
for($i = 0; $i < 5; ++$i) {
mkv_log('Inserting bogus category ' . $i . '...');
$ic = $db->prepare('INSERT INTO `msz_forum_categories` (`forum_name`, `forum_type`) VALUES (:name, 1)');
$ic->bind('name', mb_substr($forumCatsNames->generate(), 0, 240, 'utf-8'));
$ic->execute();
mkv_log('Inserting permissions for bogus category ' . $i . '...');
$ip = $db->prepare('INSERT INTO `msz_forum_permissions` (`forum_id`, `forum_perms_allow`) VALUES (:cat, 3)');
$ip->bind('cat', $i + 1);
$ip->execute();
}
$categories = mt_rand(20, 40);
mkv_log('Inserting ' . $categories . ' forum sections...');
$catIds = [];
for($i = 0; $i < $categories; ++$i) {
mkv_log('Inserting bogus forum section ' . $i . '...');
$ic = $db->prepare('INSERT INTO `msz_forum_categories` (`forum_name`, `forum_type`, `forum_description`, `forum_parent`) VALUES (:name, 0, :desc, :parent)');
$ic->bind('name', mb_substr($forumCatsNames->generate(), 0, 240, 'utf-8'));
$ic->bind('desc', mb_substr($forumCatsDescs->generate(), 0, 1200, 'utf-8'));
$ic->bind('parent', mt_rand(1, 5));
$ic->execute();
$catIds[] = $db->lastId();
}
mkv_log('Opening forum topic title markov dictionary...');
$forumTopicsTitles = new MarkovDictionary(MKV_DICTS . '/forums_topics_titles.fmk');
mkv_log('Nuking forum topics table...');
$db->exec('DELETE FROM `msz_forum_topics`');
$db->exec('ALTER TABLE `msz_forum_topics` AUTO_INCREMENT = 1');
mkv_log('Preparing forum topic insertion statement...');
$ft = $db->prepare('INSERT INTO `msz_forum_topics` (`forum_id`, `user_id`, `topic_type`, `topic_title`, `topic_count_views`, `topic_created`, `topic_bumped`, `topic_deleted`, `topic_locked`) VALUES (:cat, :user, :type, :title, :views, FROM_UNIXTIME(:created), FROM_UNIXTIME(:bumped), FROM_UNIXTIME(:deleted), FROM_UNIXTIME(:locked))');
$topics = mt_rand(200, 2000);
mkv_log('Creating ' . $topics . ' bogus forum topics...');
$topIds = [];
for($i = 0; $i < $topics; ++$i) {
mkv_log('Creating bogus topic ' . $i . '...');
$userId = mt_rand(-100, 2000);
if($userId < 1)
$userId = null;
$type = mt_rand(-1000, 2);
if($type < 1)
$type = 0;
$ft->bind('cat', $catIds[array_rand($catIds)]);
$ft->bind('user', $userId);
$ft->bind('type', $type);
$ft->bind('title', mb_substr($forumTopicsTitles->generate(), 0, 240, 'utf-8'));
$ft->bind('views', mt_rand(0, 10000));
$ft->bind('created', mt_rand(1, 0x7FFFFFFF));
$ft->bind('bumped', mt_rand(1, 0x7FFFFFFF));
$ft->bind('deleted', mt_rand(0, 10000) > 9999 ? mt_rand(1, 0x7FFFFFFF) : null);
$ft->bind('locked', mt_rand(0, 10000) > 9900 ? mt_rand(1, 0x7FFFFFFF) : null);
$ft->execute();
$topIds[] = $db->lastId();
}
mkv_log('Opening forum post text markov dictionary...');
$forumPostsTexts = new MarkovDictionary(MKV_DICTS . '/forums_posts_texts.fmk');
mkv_log('Nuking forum posts table...');
$db->exec('DELETE FROM `msz_forum_posts`');
$db->exec('ALTER TABLE `msz_forum_posts` AUTO_INCREMENT = 1');
mkv_log('Preparing forum post insertion statement...');
$fp = $db->prepare('INSERT INTO `msz_forum_posts` (`topic_id`, `forum_id`, `user_id`, `post_ip`, `post_text`, `post_parse`, `post_display_signature`, `post_created`, `post_edited`, `post_deleted`) VALUES (:topic, 1, :user, :addr, :text, :parse, :sig, FROM_UNIXTIME(:created), FROM_UNIXTIME(:edited), FROM_UNIXTIME(:deleted))');
$topCount = count($topIds);
for($t = 0; $t < $topCount; ++$t) {
$posts = mt_rand(1, 600);
$topId = $topIds[$t];
mkv_log('Inserting ' . $posts . ' bogus forum posts for bogus topic ' . $topId . '...');
$fp->bind('topic', $topId);
for($i = 0; $i < $posts; ++$i) {
mkv_log('Inserting bogus post ' . $i . ' into bogus topic ' . $topId . '...');
$userId = mt_rand(-100, 2000);
if($userId < 1)
$userId = null;
$fp->bind('user', $userId);
$fp->bind('addr', random_bytes(mt_rand(0, 1) ? 4 : 16));
$fp->bind('text', mb_substr($forumPostsTexts->generate(), 0, 60000, 'utf-8'));
$fp->bind('parse', mt_rand(0, 2));
$fp->bind('sig', mt_rand(0, 1000) > 900 ? 0 : 1);
$fp->bind('created', mt_rand(1, 0x7FFFFFFF));
$fp->bind('created', mt_rand(1, 0x7FFFFFFF));
$fp->bind('edited', mt_rand(0, 1000) > 900 ? mt_rand(1, 0x7FFFFFFF) : null);
$fp->bind('deleted', mt_rand(0, 10000) > 9000 ? mt_rand(1, 0x7FFFFFFF) : null);
$fp->execute();
}
}
mkv_log('Running slow cron once more...');
// running cron after fuckery
(new \Misuzu\Console\Commands\CronCommand)->dispatch(
new \Misuzu\Console\CommandArgs(['--slow'])
);
mkv_log('Done! Enjoy your garbage filled forum.');

View file

@ -0,0 +1,115 @@
<?php
class MarkovDictionary {
private const MAGIC = 'FMkD';
private const VERSION = 1;
private $handle;
private int $segmentSize;
private int $totalSegments;
private int $startSegments;
public function __construct(string $path) {
if(!is_file($path))
throw new InvalidArgumentException('$path does not exist.');
$this->handle = $handle = fopen($path, 'rb');
$magic = fread($handle, 4);
if($magic !== self::MAGIC)
throw new InvalidArgumentException('$path is not a valid markov dictionary.');
$header = fread($handle, 12);
if(strlen($header) !== 12)
throw new InvalidArgumentException('$path is missing header data.');
extract(unpack('Cversion/Cunused1/Cunused2/CsegmentSize/VtotalSegments/VstartSegments', $header));
if($version !== self::VERSION)
throw new InvalidArgumentException('$path version is incompatible.');
$this->segmentSize = $segmentSize;
$this->totalSegments = $totalSegments;
$this->startSegments = $startSegments;
}
public function close(): void {
if($this->handle !== null) {
fclose($this->handle);
$this->handle = null;
}
}
public function __destruct() {
$this->close();
}
private function reset(): void {
fseek($this->handle, 16, SEEK_SET);
}
public function getStartPosition(): int {
$randomStart = mt_rand(0, $this->startSegments) - 2;
if($randomStart > 0) {
for(;;) {
fseek($this->handle, 4 * $this->segmentSize, SEEK_CUR);
$isStart = fgetc($this->handle) !== "\0";
if($isStart) {
if($randomStart < 1)
break;
--$randomStart;
}
extract(unpack('vnextSegments', fread($this->handle, 2)));
fseek($this->handle, 6 * $nextSegments, SEEK_CUR);
}
fseek($this->handle, -(4 * $this->segmentSize) - 1, SEEK_CUR);
}
$startPos = ftell($this->handle);
$this->reset();
return $startPos;
}
public function generate(int $safety = 2000, int $start = -1): string {
if($start < 0)
$start = $this->getStartPosition();
fseek($this->handle, $start, SEEK_SET);
$string = '';
for($s = 0; $s < $safety; ++$s) {
$string .= fread($this->handle, 4 * $this->segmentSize);
fseek($this->handle, 1, SEEK_CUR);
extract(unpack('vnextSegments', fread($this->handle, 2)));
if($nextSegments < 1)
break;
$nexts = [];
// really shitty weighting system
for($i = 0; $i < $nextSegments; ++$i) {
extract(unpack('Voffset/vweight', fread($this->handle, 6)));
for($j = 0; $j < $weight; ++$j)
$nexts[] = $offset;
}
$offset = $nexts[array_rand($nexts)];
fseek($this->handle, $offset, SEEK_SET);
}
$this->reset();
$string = mb_convert_encoding($string, 'utf-8', 'utf-32le');
return trim($string);
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,27 @@
<?php
require_once __DIR__ . '/../misuzu.php';
if(!MSZ_DEBUG)
die('Not running in debug mode. Are you sure you want to run this?' . PHP_EOL);
define('SRA_URL', 'https://abyss.flash.moe/dev-avatars/_random.php');
// oh boy this'll take a while
$users = \Misuzu\Users\User::all();
printf('[%s] Altering avatars for %d users.%s', date('H:i:s'), count($users), PHP_EOL);
foreach($users as $user) {
printf('[%s] Changing avatar for %d %s...%s', date('H:i:s'), $user->getId(), $user->getUsername(), PHP_EOL);
if(mt_rand(0, 1000) > 950) {
printf('[%s] Skipping this one.%s', date('H:i:s'), PHP_EOL);
continue;
}
printf('[%s] Downloading image from %s...%s', date('H:i:s'), SRA_URL, PHP_EOL);
$data = file_get_contents(SRA_URL);
printf('[%s] Applying through stupid roundabout method...%s', date('H:i:s'), PHP_EOL);
$user->getAvatarInfo()->setFromData($data);
}

View file

@ -35,6 +35,10 @@ final class DB {
return self::$instance->{$name}(...$args);
}
public static function getInstance(): Database {
return self::$instance;
}
public static function buildDSN(array $vars): string {
$dsn = ($vars['driver'] ?? 'mysql') . ':';