diff --git a/README.md b/README.md index c8d8e8f1..ef2823a4 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/devel/insert-bogus-data.php b/devel/insert-bogus-data.php new file mode 100644 index 00000000..3efb7403 --- /dev/null +++ b/devel/insert-bogus-data.php @@ -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.'); diff --git a/devel/sample/MarkovDictionary.php b/devel/sample/MarkovDictionary.php new file mode 100644 index 00000000..ec2a8a1f --- /dev/null +++ b/devel/sample/MarkovDictionary.php @@ -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); + } +} diff --git a/devel/sample/dicts/changes_logs.fmk b/devel/sample/dicts/changes_logs.fmk new file mode 100644 index 00000000..f687c0dc Binary files /dev/null and b/devel/sample/dicts/changes_logs.fmk differ diff --git a/devel/sample/dicts/changes_tags_descs.fmk b/devel/sample/dicts/changes_tags_descs.fmk new file mode 100644 index 00000000..3b2500af Binary files /dev/null and b/devel/sample/dicts/changes_tags_descs.fmk differ diff --git a/devel/sample/dicts/changes_tags_names.fmk b/devel/sample/dicts/changes_tags_names.fmk new file mode 100644 index 00000000..15b9e826 Binary files /dev/null and b/devel/sample/dicts/changes_tags_names.fmk differ diff --git a/devel/sample/dicts/changes_texts.fmk b/devel/sample/dicts/changes_texts.fmk new file mode 100644 index 00000000..e6afebc5 Binary files /dev/null and b/devel/sample/dicts/changes_texts.fmk differ diff --git a/devel/sample/dicts/comments_texts.fmk b/devel/sample/dicts/comments_texts.fmk new file mode 100644 index 00000000..e03753c1 Binary files /dev/null and b/devel/sample/dicts/comments_texts.fmk differ diff --git a/devel/sample/dicts/forums_cats_descs.fmk b/devel/sample/dicts/forums_cats_descs.fmk new file mode 100644 index 00000000..b37bd22f Binary files /dev/null and b/devel/sample/dicts/forums_cats_descs.fmk differ diff --git a/devel/sample/dicts/forums_cats_names.fmk b/devel/sample/dicts/forums_cats_names.fmk new file mode 100644 index 00000000..a3e346e1 Binary files /dev/null and b/devel/sample/dicts/forums_cats_names.fmk differ diff --git a/devel/sample/dicts/forums_posts_texts.fmk b/devel/sample/dicts/forums_posts_texts.fmk new file mode 100644 index 00000000..aa12504b Binary files /dev/null and b/devel/sample/dicts/forums_posts_texts.fmk differ diff --git a/devel/sample/dicts/forums_topics_titles.fmk b/devel/sample/dicts/forums_topics_titles.fmk new file mode 100644 index 00000000..1d0e75a5 Binary files /dev/null and b/devel/sample/dicts/forums_topics_titles.fmk differ diff --git a/devel/sample/dicts/news_cats_descs.fmk b/devel/sample/dicts/news_cats_descs.fmk new file mode 100644 index 00000000..54e539f8 Binary files /dev/null and b/devel/sample/dicts/news_cats_descs.fmk differ diff --git a/devel/sample/dicts/news_cats_names.fmk b/devel/sample/dicts/news_cats_names.fmk new file mode 100644 index 00000000..24caebf3 Binary files /dev/null and b/devel/sample/dicts/news_cats_names.fmk differ diff --git a/devel/sample/dicts/news_posts_texts.fmk b/devel/sample/dicts/news_posts_texts.fmk new file mode 100644 index 00000000..5810fddf Binary files /dev/null and b/devel/sample/dicts/news_posts_texts.fmk differ diff --git a/devel/sample/dicts/news_posts_titles.fmk b/devel/sample/dicts/news_posts_titles.fmk new file mode 100644 index 00000000..4e5184dc Binary files /dev/null and b/devel/sample/dicts/news_posts_titles.fmk differ diff --git a/devel/sample/dicts/roles_descs.fmk b/devel/sample/dicts/roles_descs.fmk new file mode 100644 index 00000000..439ca9fb Binary files /dev/null and b/devel/sample/dicts/roles_descs.fmk differ diff --git a/devel/sample/dicts/roles_names.fmk b/devel/sample/dicts/roles_names.fmk new file mode 100644 index 00000000..71565c04 Binary files /dev/null and b/devel/sample/dicts/roles_names.fmk differ diff --git a/devel/sample/dicts/roles_titles.fmk b/devel/sample/dicts/roles_titles.fmk new file mode 100644 index 00000000..46ec9487 Binary files /dev/null and b/devel/sample/dicts/roles_titles.fmk differ diff --git a/devel/sample/dicts/users_abouts.fmk b/devel/sample/dicts/users_abouts.fmk new file mode 100644 index 00000000..fc98d38d Binary files /dev/null and b/devel/sample/dicts/users_abouts.fmk differ diff --git a/devel/sample/dicts/users_names.fmk b/devel/sample/dicts/users_names.fmk new file mode 100644 index 00000000..e4a8b763 Binary files /dev/null and b/devel/sample/dicts/users_names.fmk differ diff --git a/devel/sample/dicts/users_sigs.fmk b/devel/sample/dicts/users_sigs.fmk new file mode 100644 index 00000000..16bda6c1 Binary files /dev/null and b/devel/sample/dicts/users_sigs.fmk differ diff --git a/devel/sample/dicts/users_titles.fmk b/devel/sample/dicts/users_titles.fmk new file mode 100644 index 00000000..0254f829 Binary files /dev/null and b/devel/sample/dicts/users_titles.fmk differ diff --git a/devel/set-random-avatars.php b/devel/set-random-avatars.php new file mode 100644 index 00000000..4235e199 --- /dev/null +++ b/devel/set-random-avatars.php @@ -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); +} diff --git a/src/DB.php b/src/DB.php index 6ce4293d..4f671307 100644 --- a/src/DB.php +++ b/src/DB.php @@ -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') . ':';