isSuccess = $isSuccess; $this->message = $message; $this->data = $data; } public static function Success(?string $message = null, array $data = []): self { return new self(true, $message, $data); } public static function Error(string $message, array $data = []): self { return new self(false, $message, $data); } } class Roles { // 例: if ($user->role & (Roles::STAFF | Roles::NINTENDONDA)) public const int BANNED = 0; public const int MEMBER = 1 << 0; // 1 public const int NINTENDONDA = 1 << 1; // 2 public const int PLAYSTATIONNDA = 1 << 2; // 4 public const int FULLNDA = 1 << 3; // 8 (NINTENDONDA + PLAYSTATIONNDA) public const int SUBSCRIBER = 1 << 4; // 16 public const int NSUBSCRIBER = 1 << 5; // 32 (NINTENDNDA + SUBSCRIBER) public const int PSUBSCRIBER = 1 << 6; // 64 (PLAYSTATIONNDA + SUBSCRIBER) public const int FSUBSCRIBER = 1 << 7; // 128 (NINTENDNDA + PLAYSTATIONNDA + SUBSCRIBER) public const int STAFF = 1 << 8; // 256 public const int ADMIN = 1 << 9; // 512 } class Gender { public const int UNKNOWN = -1; // 不明 public const int MALE = 0; // 男性 public const int FEMALE = 1; // 女性 } $colorPalette = [ 'ultradark' => [ 'black' => '#020102', 'white' => '#b3b1b3', 'grey' => '#5c535c', 'yellow' => '#8d8b0d', 'orange' => '#724e0b', 'green' => '#1e6907', 'purple' => '#410a5a', 'lime' => '#198d5b', 'pink' => '#9e0ea3', 'cyan' => '#1e8c9b', 'red' => '#861623', 'blue' => '#164a85', ], 'dark' => [ 'black' => '#120f12', 'white' => '#cfcbcf', 'grey' => '#746c75', 'yellow' => '#b8b515', 'orange' => '#ac7718', 'green' => '#2c980c', 'purple' => '#550f75', 'lime' => '#10c074', 'pink' => '#c016c6', 'cyan' => '#1cbcd0', 'red' => '#bc1729', 'blue' => '#1a6ecf', ], 'medium' => [ 'black' => '#232023', 'white' => '#f6f6f6', 'grey' => '#988f98', 'yellow' => '#f1ed25', 'orange' => '#f7a717', 'green' => '#2de12c', 'purple' => '#b421f8', 'lime' => '#20f398', 'pink' => '#f545f5', 'cyan' => '#29d3ff', 'red' => '#ee4030', 'blue' => '#2687f7', ], 'light' => [ 'black' => '#443b44', 'white' => '#fcfcfc', 'grey' => '#bdb4bd', 'yellow' => '#ecea71', 'orange' => '#f8c56a', 'green' => '#6cf344', 'purple' => '#ae6bdb', 'lime' => '#88ecc1', 'pink' => '#ea79d8', 'cyan' => '#8ae5ff', 'red' => '#f35869', 'blue' => '#6aa6eb', ], 'ultralight' => [ 'black' => '#574d57', 'white' => '#ffffff', 'grey' => '#d6cfd6', 'yellow' => '#f5f4cf', 'orange' => '#f3d6a3', 'green' => '#baf3a8', 'purple' => '#d2bae2', 'lime' => '#b6e9d3', 'pink' => '#e6b9de', 'cyan' => '#c2e8f3', 'red' => '#ecb0b7', 'blue' => '#bbd4f0', ], ]; function uuid(): string { $data = random_bytes(16); $data[6] = chr(ord($data[6]) & 0x0f | 0x40); $data[8] = chr(ord($data[8]) & 0x3f | 0x80); return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); } function kys(mixed $arg): void { if (!DEBUG_MODE) return; if (gettype($arg) == 'boolean') $arg = $arg === true ? 'true' : 'false'; if (gettype($arg) == 'array' || gettype($arg) == 'object') { foreach ($arg as $a) { if (gettype($a) == 'boolean') $a = $a === true ? 'true' : 'false'; } } echo ''; echo '
KILL
YOUR
SELF
'; echo '
';
  print_r($arg);
  echo '
';
  die();
}

function ffs(): void {
  if (!DEBUG_MODE) return;
  echo '';
  echo '
FOR
FUCKS
SAKE
'; $stack = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 50); $st = []; unset($stack[0]); $i = 0; echo '
';
  print_r($stack);
  echo '
';
  foreach ($stack as $s) {
    if (isset($s['file'])) $st[$i]['file'] = $s['file'].(isset($s['line']) ? ':'.$s['line'] : '');
    else $st[$i]['file'] = '';
    if (isset($s['function'])) $st[$i]['func'] = (isset($s['class']) ? $s['class'].(isset($s['type']) ? $s['type'] : '::') : '').$s['function'];
    else $st[$i]['func'] = '';
    if (isset($s['object'])) $st[$i]['objs'] = $s['object'];
    else $st[$i]['objs'] = new \stdClass;
    if (isset($s['args'])) $st[$i]['args'] = $s['args'];
    else $st[$i]['args'] = [];
    $i++;
  }
  unset($stack[$i]);

  foreach ($st as $s) {
    echo '
'; echo 'ファイル:'; echo $s['file'].'
'; echo '関数:'; echo $s['func'].'
'; echo 'オブジェクト:'; echo print_r($s['objs']).'
'; echo 'その他:'; echo print_r($s['args']).'
'; echo '
'; } die(); } function base58btc_encode(string $bin): string { $a = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; $base = 58; $num = \gmp_import($bin, 1, GMP_LSW_FIRST | GMP_NATIVE_ENDIAN); $res = ''; if (\gmp_cmp($num, 0) == 0) return '1'; while (\gmp_cmp($num, 0) > 0) { $mod = \gmp_intval(\gmp_mod($num, $base)); $res = $a[$mod].$res; $num = \gmp_div_q($num, $base); } $bytes = str_split($bin); foreach ($bytes as $byte) { if (ord($byte) === 0) { $res = '1'.$res; } else { break; } } return $res; } function logger(LogType $section, mixed $arg): void { if (!LOGGING_ENABLED) return; $success = false; $logfile = ROOT.'/log/'; switch ($section) { case LogType::ActivityPub: $logfile .= 'ap_log.text'; $success = true; break; case LogType::Auth: $logfile .= 'auth_log.text'; $success = true; break; case LogType::Mailer: $logfile .= 'mail_log.text'; $success = true; break; default: break; } if ($success) file_put_contents($logfile, $arg."\n", FILE_APPEND); } function to_money($amount, $lang) { $amount = floatval($amount); switch (strtolower($lang)) { case 'ja': if ($amount >= 100000000) { $oku = $amount / 100000000; return $oku.'億円'; } else if ($amount >= 10000) { $man = $amount / 10000; return $man.'万円'; } return number_format($amount, 0).'円'; case 'en': if ($amount >= 1000000000) { $billion = $amount / 1000000000; return '¥ '.$billion.' billion'; } else if ($amount >= 1000000) { $million = $amount / 1000000; return '¥ '.$million.' million'; } else if ($amount >= 1000) { $thousand = $amount / 1000; return '¥ '.$thousand.' thousand'; } return '¥ '.number_format($amount, 0); default: return '¥ '.number_format($amount, 0); } } function randstr(): string { $len = random_int(1, 20); return bin2hex(random_bytes($len)); } function assert_exists(mixed $assertion, Throwable|string|null $description = null): bool { if (ini_get('zend.assertions') < 1) trigger_error('assert機能性が無効です。有効するには、php.iniで「zend.assertions = 1」に設定して下さい。', E_USER_WARNING); if (isset($assertion)) return true; assert(false, $description ?? 'Assertion failed: value is not null'); return false; } function assert_null(mixed $assertion, Throwable|string|null $description = null): bool { if (ini_get('zend.assertions') < 1) trigger_error('assert機能性が無効です。有効するには、php.iniで「zend.assertions = 1」に設定して下さい。', E_USER_WARNING); if (is_null($assertion)) return true; assert(false, $description ?? 'Assertion failed: value is not null'); return false; } function assert_not_null(mixed $assertion, Throwable|string|null $description = null): bool { if (ini_get('zend.assertions') < 1) trigger_error('assert機能性が無効です。有効するには、php.iniで「zend.assertions = 1」に設定して下さい。', E_USER_WARNING); if (!is_null($assertion)) return true; assert(false, $description ?? 'Assertion failed: value is null'); return false; } function assert_unless_success(Result $assertion, Throwable|string|null $description = null): bool { if (ini_get('zend.assertions') < 1) trigger_error('assert機能性が無効です。有効するには、php.iniで「zend.assertions = 1」に設定して下さい。', E_USER_WARNING); if ($assertion->isSuccess) return true; assert(false, $description ?? $assertion->message ?? 'Assertion failed: Result is not successful'); return false; } function getcookie(string $name): string|null { return $_COOKIE[$name] ?? null; } function namecolor(\stdClass $userData): string { $ban = "#888888"; $male = "#97ACEF"; $female = "#F185C9"; $ungender = "#7C60B0"; $gender = 'color: '.($userData->gender === Gender::MALE ? $male : ($userData->gender === Gender::FEMALE ? $female : $ungender)).';'; $style = $userData->namecolor ?: ($userData->role !== Roles::BANNED ? $gender : 'color: '.$ban.';'); $showname = $userData->displayname ?: $userData->username; $color = "{$showname}"; if ($userData->role & (Roles::ADMIN | Roles::STAFF)) $color .= ""; $suffix = $userData->gender === Gender::MALE ? 'くん' : ($userData->gender === Gender::FEMALE ? 'ちゃん' : 'さん'); return $color.$suffix; } function make_csrf_token(?bool $force = false): string { if (null !== getcookie('csrf_token') && !$force) return getcookie('csrf_token'); $token = bin2hex(random_bytes(32)); setcookie('csrf_token', $token, [ 'expires' => time() + 300, // 5分 'path' => '/', 'domain' => $_SERVER['SERVER_NAME'], 'secure' => (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off'), 'httponly' => true, 'samesite' => 'Strict' ]); return $token; } function verify_csrf_token(string $token): bool { return null !== getcookie('csrf_token') && hash_equals(getcookie('csrf_token'), $token); } function count_special_chars(string $str): int { $count = 0; $len = strlen($str); for ($i = 0; $i < $len; ++$i) { if (str_contains('!', $str[$i])) ++$count; if (str_contains('"', $str[$i])) ++$count; if (str_contains('#', $str[$i])) ++$count; if (str_contains('$', $str[$i])) ++$count; if (str_contains('%', $str[$i])) ++$count; if (str_contains('&', $str[$i])) ++$count; if (str_contains('\'', $str[$i])) ++$count; if (str_contains('(', $str[$i])) ++$count; if (str_contains(')', $str[$i])) ++$count; if (str_contains('-', $str[$i])) ++$count; if (str_contains('=', $str[$i])) ++$count; if (str_contains('^', $str[$i])) ++$count; if (str_contains('~', $str[$i])) ++$count; if (str_contains('\\', $str[$i])) ++$count; if (str_contains('|', $str[$i])) ++$count; if (str_contains('[', $str[$i])) ++$count; if (str_contains(']', $str[$i])) ++$count; if (str_contains(':', $str[$i])) ++$count; if (str_contains('@', $str[$i])) ++$count; if (str_contains('`', $str[$i])) ++$count; if (str_contains('*', $str[$i])) ++$count; if (str_contains('{', $str[$i])) ++$count; if (str_contains('}', $str[$i])) ++$count; if (str_contains(';', $str[$i])) ++$count; if (str_contains('+', $str[$i])) ++$count; if (str_contains(',', $str[$i])) ++$count; if (str_contains('<', $str[$i])) ++$count; if (str_contains('.', $str[$i])) ++$count; if (str_contains('>', $str[$i])) ++$count; if (str_contains('/', $str[$i])) ++$count; if (str_contains('?', $str[$i])) ++$count; if (str_contains('_', $str[$i])) ++$count; } return $count; } function countmatch(string $str): bool { $len = strlen($str); $numUpper = preg_match_all('/[A-Z]/', $str) ?? 0; $numLower = preg_match_all('/[a-z]/', $str) ?? 0; $numDigit = preg_match_all('/[0-9]/', $str) ?? 0; $numSymbol = count_special_chars($str); $sum = $numUpper + $numLower + $numDigit + $numSymbol; return $len == $sum; } function getImageInfo(string $url): \Std\Lib\Image { $img = new \Std\Lib\Image($url); return $img; } function align(int $val): int { if ($val <= 0) return 1; if ($val === 1) return 1; $res = 0; $lower = 1; while ($lower * 2 <= $val) $lower *= 2; $upper = $lower * 2; if (($val - $lower) <= ($upper - $val)) return $lower; return $upper; } function align_up(int $val): int { if ($val <= 0) return 1; if ($val === 1) return 1; $res = 0; $lower = 1; while ($lower * 2 <= $val) $lower *= 2; $upper = $lower * 2; return $upper; } function align_down(int $val): int { if ($val <= 0) return 1; if ($val === 1) return 1; $res = 0; $lower = 1; while ($lower * 2 <= $val) $lower *= 2; return $lower; } // PHP 8.3と8.4の場合 if (!function_exists('array_last')) { function array_last(array $array): mixed { return $array === [] ? null : $array[array_key_last($array)]; } }