[
  {
    "path": "README.md",
    "content": "# Tieba Sign\nFront-end environment for TiebaSign-Backend services, which provides faster auto-sign experience in http://tieba.baidu.com and can handle much more user at the same time.\n\nThis front-end project only provides basic registration / management / log view features.\nSigning features was not included in this project.\n\n## WARNING\nYou cannot use these code in your own server.\nIt required a closed source server-side application which was powered by Go.\n\n这份代码不能直接部署到服务器上，因为还需要一个 Go 语言的服务端程序才可以正常运行（不开源）。\n\nIf you want to deploy a server, please use the [old branch](https://github.com/kookxiang/Tieba_Sign/tree/master).\n\n如果你想搭建贴吧签到助手，请使用 [老版本](https://github.com/kookxiang/Tieba_Sign/tree/master).\n"
  },
  {
    "path": "admin.php",
    "content": "<?php\ndefine('IN_ADMINCP', true);\ndefine('DISABLE_PLUGIN', true);\nrequire_once './system/common.inc.php';\nif(!is_admin($uid)) exit();\n$formhash = substr(md5(substr(TIMESTAMP, 0, -7).$username.$uid.SYS_KEY.ROOT.'ADMINCP_ONLY'), 5, 14);\n\nswitch($_GET['action']){\n\tcase 'load_userstat':\n\t\t$data = array();\n\t\t$date = date('Ymd');\n\t\t$query = DB::query('SELECT uid, username FROM member ORDER BY uid');\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$_uid = $result['uid'];\n\t\t\t$data[$_uid] = $result;\n\t\t\t$data[$_uid]['succeed'] = 0;\n\t\t\t$data[$_uid]['skiped'] = 0;\n\t\t\t$data[$_uid]['waiting'] = 0;\n\t\t\t$data[$_uid]['retry'] = 0;\n\t\t\t$data[$_uid]['unsupport'] = 0;\n\t\t}\n\t\t$query = DB::query(\"SELECT uid, COUNT(*) AS num FROM `sign_log` WHERE date='{$date}' AND `status`=2 GROUP BY uid\");\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$_uid = $result['uid'];\n\t\t\t$data[$_uid]['succeed'] = $result['num'];\n\t\t}\n\t\t$query = DB::query(\"SELECT uid, COUNT(*) AS num FROM `sign_log` WHERE date='{$date}' AND `status`=0 GROUP BY uid\");\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$_uid = $result['uid'];\n\t\t\t$data[$_uid]['waiting'] = $result['num'];\n\t\t}\n\t\t$query = DB::query(\"SELECT uid, COUNT(*) AS num FROM `sign_log` WHERE date='{$date}' AND `status`=1 GROUP BY uid\");\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$_uid = $result['uid'];\n\t\t\t$data[$_uid]['retry'] = $result['num'];\n\t\t}\n\t\t$query = DB::query(\"SELECT uid, COUNT(*) AS num FROM `sign_log` WHERE date='{$date}' AND `status`=-1 GROUP BY uid\");\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$_uid = $result['uid'];\n\t\t\t$data[$_uid]['unsupport'] = $result['num'];\n\t\t}\n\t\t$query = DB::query(\"SELECT uid, COUNT(*) AS num FROM `sign_log` WHERE date='{$date}' AND `status`=-2 GROUP BY uid\");\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$_uid = $result['uid'];\n\t\t\t$data[$_uid]['skiped'] = $result['num'];\n\t\t}\n\t\texit(json_encode($data));\n\tcase 'load_user':\n\t\t$data = array();\n\t\t$query = DB::query('SELECT uid, username, email FROM member ORDER BY uid');\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$result['email'] = htmlspecialchars($result['email']);\n\t\t\t$data[] = $result;\n\t\t}\n\t\texit(json_encode($data));\n\t\tbreak;\n\tcase 'load_setting':\n\t\t$data = CACHE::get('setting');\n\t\tunset($data['SYS_KEY']);\n\t\texit(json_encode($data));\n\t\tbreak;\n\tcase 'save_setting':\n\t\tif($formhash != $_POST['formhash']) showmessage('来源不可信，请重试', 'admin.php#setting');\n\t\tif(defined('AFENABLED')){\n\t\t\tsaveSetting('admin_uid', $_POST['admin_uid']);\n\t\t}\n\t\tsaveSetting('account_switch', ($_POST['account_switch'] ? 1 : 0));\n\t\tsaveSetting('register_limit', ($_POST['register_limit'] ? 1 : 0));\n\t\tsaveSetting('register_check', ($_POST['register_check'] ? 1 : 0));\n\t\tsaveSetting('autoupdate', ($_POST['autoupdate'] ? 1 : 0));\n\t\tsaveSetting('block_register', ($_POST['block_register'] ? 1 : 0));\n\t\tsaveSetting('invite_code', stripslashes(daddslashes($_POST['invite_code'])));\n\t\tsaveSetting('beian_no', stripslashes(daddslashes(htmlspecialchars($_POST['beian_no']))));\n\t\tsaveSetting('jquery_mode', $_POST['jquery_mode']);\n\t\tsaveSetting('max_tieba', intval($_POST['max_tieba']));\n\t\tsaveSetting('extra_title', stripslashes(daddslashes(htmlspecialchars($_POST['extra_title']))));\n\t\tshowmessage('设置已经保存☆Kira~', 'admin.php#setting', 2);\n\t\tbreak;\n\tcase 'deluser':\n\t\t$_uid = intval($_GET['uid']);\n\t\tif($uid == $_uid) showmessage('删你自己的号是要作死啊？！', 'admin.php#user');\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#user');\n\t\tdelete_user($_uid);\n\t\tshowmessage('删除用户成功', 'admin.php#user', 1);\n\t\tbreak;\n\tcase 'update_liked_tieba':\n\t\t$_uid = intval($_GET['uid']);\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#user');\n\t\tupdate_liked_tieba($_uid);\n\t\tlist($insert, $deleted) = update_liked_tieba($_uid);\n\t\tshowmessage(\"喜欢的贴吧列表已经更新,<br>新增{$insert}个贴吧, 删除{$deleted}个贴吧\", 'admin.php#user', 1);\n\t\tbreak;\n\tcase 'reset_failure':\n\t\t$_uid = intval($_GET['uid']);\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#stat');\n\t\t$date = date('Ymd');\n\t\tDB::query(\"UPDATE sign_log SET status='0', retry='0' WHERE uid='{$_uid}' AND date='{$date}' AND status<0\");\n\t\tshowmessage('已经重置，稍后系统将自动重试', 'admin.php#stat', 1);\n\t\tbreak;\n\tcase 'reset_failure_all':\n\t\tif(!defined('AFENABLED')) exit();\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#stat');\n\t\t$date = date('Ymd');\n\t\tDB::query(\"UPDATE sign_log SET status='0', retry='0' WHERE date='{$date}' AND status<0\");\n\t\tshowmessage('已经重置，稍后系统将自动重试', 'admin.php#stat', 1);\n\t\tbreak;\n\tcase 'mail_setting':\n\t\tif($formhash != $_POST['formhash']) showmessage('来源不可信，请重试', 'admin.php#setting');\n\t\t$classes = getClasses();\n\t\t$class = $_POST['mail_sender'];\n\t\tif(!$classes[$class]) showmessage('选择的邮件发送方式不正确.', 'admin.php#setting');\n\t\tif(!$classes[$class]->isAvailable()) showmessage('选择的邮件发送方式不可用.', 'admin.php#setting');\n\t\tsaveSetting('mail_class', $class);\n\t\tshowmessage('保存成功<br>(请确认高级设置配置有效)', 'admin.php#setting');\n\t\tbreak;\n\tcase 'mail_advanced':\n\t\t$classes = getClasses();\n\t\t$class = getSetting('mail_class');\n\t\t$obj = $classes[$class];\n\t\tif(!$obj) showmessage('选择的邮件发送方式不正确.', 'admin.php#setting');\n\t\tif(!$obj->isAvailable()) showmessage('选择的邮件发送方式不可用.', 'admin.php#setting');\n\t\t$_config = $obj->config;\n\t\tif($_POST['formhash'] == $formhash){\n\t\t\tforeach($_config as $k=>$v){\n\t\t\t\t$key = $v[1];\n\t\t\t\t$value = daddslashes($_POST[$key]);\n\t\t\t\tsaveSetting(\"_mail_{$class}_{$key}\", $value);\n\t\t\t}\n\t\t\tCACHE::save(\"mail_{$class}\", '');\n\t\t\tshowmessage('保存成功！', 'admin.php#setting');\n\t\t}\n\t\t$out = array();\n\t\t$setting = array();\n\t\t$query = DB::query(\"SELECT * FROM setting WHERE k LIKE '_mail_{$class}_%'\");\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$key = str_replace(\"_mail_{$class}_\", '', $result['k']);\n\t\t\t$setting[$key] = $result['v'];\n\t\t}\n\t\tforeach($_config as $k=>$v){\n\t\t\t$key = $v[1];\n\t\t\t$item = array(\n\t\t\t\t'key' => $v[1],\n\t\t\t\t'name' => $v[0],\n\t\t\t\t'description' => $v[2],\n\t\t\t\t'value' => isset($setting[$key]) ? $setting[$key] : $v[3],\n\t\t\t\t'type' => $v[4] ? $v[4] : 'text',\n\t\t\t);\n\t\t\t$out[] = $item;\n\t\t}\n\t\techo json_encode($out);\n\t\tbreak;\n\tcase 'switch_channel':\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#updater');\n\t\t$channel = $_GET['channel'];\n\t\tif($channel != 'dev' && $channel != 'stable') showmessage('未知分支ID', 'admin.php#updater');\n\t\tsaveSetting('channel', $channel);\n\t\tshowmessage('分支切换成功.', 'admin.php#updater#');\n\tcase 'install_plugin':\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#plugin');\n\t\trequire_once SYSTEM_ROOT.'./class/plugin.php';\n\t\t$plugin_id = $_GET['pluginid'];\n\t\tif(preg_match('/[^A-Za-z0-9_-.]/', $plugin_id)) showmessage('插件ID不合法，请与插件作者联系', 'admin.php#plugin');\n\t\t$classfile = ROOT.'./plugins/'.$plugin_id.'/plugin.class.php';\n\t\tif(!file_exists($classfile)) showmessage('插件文件缺失，请与插件作者联系', 'admin.php#plugin');\n\t\trequire_once $classfile;\n\t\t$classname = \"plugin_{$plugin_id}\";\n\t\tif(!class_exists(\"plugin_{$plugin_id}\", false)) showmessage('插件类不合规范，请与插件作者联系', 'admin.php#plugin');\n\t\t$obj = new $classname();\n\t\t$method_blacklist = array('__construct', '__destruct', $classname);\n\t\tforeach($method_blacklist as $method) if(method_exists($obj, $method)) showmessage('插件不符合性能要求规定，请与插件作者联系', 'admin.php#plugin');\n\t\tif ($obj instanceof Plugin){\n\t\t\t$obj->checkCompatibility();\n\t\t\t$compatibilityMode = false;\n\t\t}else{\n\t\t\t// 弹出旧版插件提示\n\t\t\t$compatibilityMode = true;\n\t\t}\n\t\t$version = 0;\n\t\tif(property_exists($obj, 'version')) $version = $obj->version;\n\t\tDB::insert('plugin', array('name' => $plugin_id, 'version' => $version, 'enable' => 0));\n\t\tCACHE::update('plugins');\n\t\tif($compatibilityMode){\n\t\t\tif(method_exists($obj, 'on_install')) $obj->on_install();\n\t\t}else{\n\t\t\t$obj->install();\n\t\t}\n\t\tshowmessage('安装插件成功！', 'admin.php#plugin#');\n\tcase 'uninstall_plugin':\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#plugin');\n\t\t$plugin_id = $_GET['pluginid'];\n\t\tif(preg_match('/[^A-Za-z0-9_-.]/', $plugin_id)) showmessage('插件ID不合法，请与插件作者联系', 'admin.php#plugin');\n\t\tDB::query(\"DELETE FROM `plugin` WHERE name='{$plugin_id}'\");\n\t\tDB::query(\"DELETE FROM plugin_var WHERE pluginid='\".addslashes($plugin_id).\"'\");\n\t\t$classfile = ROOT.'./plugins/'.$plugin_id.'/plugin.class.php';\n\t\tif(file_exists($classfile)){\n\t\t\trequire_once $classfile;\n\t\t\t$classname = \"plugin_{$plugin_id}\";\n\t\t\tif(class_exists(\"plugin_{$plugin_id}\", false)){\n\t\t\t\t$obj = new $classname();\n\t\t\t\tif ($obj instanceof Plugin){\n\t\t\t\t\t$compatibilityMode = false;\n\t\t\t\t}else{\n\t\t\t\t\t$compatibilityMode = true;\n\t\t\t\t}\n\t\t\t\tif(property_exists($obj, 'modules')){\n\t\t\t\t\tforeach($obj->modules as $module){\n\t\t\t\t\t\tif($module['type'] == 'cron'){\n\t\t\t\t\t\t\tDB::query(\"DELETE FROM cron WHERE id='\".$module['cron']['id'].\"'\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif($compatibilityMode){\n\t\t\t\t\tif(method_exists($obj, 'on_uninstall')) $obj->on_uninstall();\n\t\t\t\t}else{\n\t\t\t\t\t$obj->uninstall();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tCACHE::update('plugin');\n\t\tCACHE::update('plugins');\n\t\tshowmessage('卸载插件成功！', 'admin.php#plugin#');\n\tcase 'enable_plugin':\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#plugin');\n\t\t$plugin_id = $_GET['pluginid'];\n\t\tif(preg_match('/[^A-Za-z0-9_-.]/', $plugin_id)) showmessage('插件ID不合法，请与插件作者联系', 'admin.php#plugin');\n\t\tDB::query(\"UPDATE `plugin` SET `enable`=1 WHERE name='{$plugin_id}'\");\n\t\t$classname = \"plugin_{$plugin_id}\";\n\t\t$obj = new $classname();\n\t\t$method_blacklist = array('__construct', '__destruct', $classname);\n\t\tforeach($method_blacklist as $method) if(method_exists($obj, $method)) showmessage('插件不符合性能要求规定，请与插件作者联系', 'admin.php#plugin');\n\t\tif (property_exists($obj, 'modules')){\n\t\t\tforeach($obj->modules as $module){\n\t\t\t\tif($module['type'] == 'cron'){\n\t\t\t\t\tDB::insert('cron', array_merge($module['cron'], array('nextrun' => TIMESTAMP)), false, true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tCACHE::update('plugins');\n\t\tshowmessage('启用插件成功！', 'admin.php#plugin#');\n\tcase 'update_check':\n\t\t$ret = Updater::check();\n\t\tif(is_array($ret)){\n\t\t\t$return = array(\n\t\t\t\t'status' => 1,\n\t\t\t\t'files' => $ret,\n\t\t\t\t);\n\t\t}else{\n\t\t\t$return = array(\n\t\t\t\t'status' => $ret,\n\t\t\t\t'files' => array(),\n\t\t\t\t);\n\t\t}\n\t\techo json_encode($return);\n\t\texit();\n\tcase 'get_file':\n\t\techo json_encode(Updater::loop());\n\t\texit();\n\tcase 'write_file':\n\t\techo json_encode(Updater::write_file());\n\t\texit();\n\tcase 'disable_plugin':\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#plugin');\n\t\t$plugin_id = $_GET['pluginid'];\n\t\tif(preg_match('/[^A-Za-z0-9_-.]/', $plugin_id)) showmessage('插件ID不合法，请与插件作者联系', 'admin.php#plugin');\n\t\tDB::query(\"UPDATE `plugin` SET `enable`=0 WHERE name='{$plugin_id}'\");\n\t\t$classname = \"plugin_{$plugin_id}\";\n\t\t$obj = new $classname ();\n\t\tif(property_exists ($obj, 'modules')){\n\t\t\tforeach($obj->modules as $module){\n\t\t\t\tif($module ['type'] == 'cron'){\n\t\t\t\t\tDB::query(\"DELETE FROM cron WHERE id='\".$module['cron']['id'].\"'\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tCACHE::update('plugins');\n\t\tshowmessage('禁用插件成功！', 'admin.php#plugin#');\n\tcase 'config_plugin':\n\t\t$plugin_id = $_REQUEST['pluginid'];\n\t\tif($_POST['submit'] && $formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#plugin');\n\t\tif(preg_match('/[^A-Za-z0-9_-.]/', $plugin_id)) showmessage('插件ID不合法，请与插件作者联系', 'admin.php#plugin');\n\t\t$classfile = ROOT.'./plugins/'.$plugin_id.'/plugin.class.php';\n\t\tif(!file_exists($classfile)) showmessage('插件文件缺失，请与插件作者联系', 'admin.php#plugin');\n\t\trequire_once $classfile;\n\t\t$classname = \"plugin_{$plugin_id}\";\n\t\tif(!class_exists(\"plugin_{$plugin_id}\", false)) showmessage('插件类不合规范，请与插件作者联系', 'admin.php#plugin');\n\t\t$obj = new $classname();\n\t\tif(method_exists($obj, 'on_config')){\n\t\t\techo json_encode(array('html' => $obj->on_config()));\n\t\t}else{\n\t\t\techo json_encode(array('html' => '错误：该插件没有高级配置面板！'));\n\t\t}\n\t\tbreak;\n\tcase 'eNaBlEaFc':\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#setting');\n\t\t$text = pack('H*', strrev($_GET['hash']));\n\t\tif($text == 'ENABLE ADVANCED FETURES') saveSetting('AFENABLED', 1);\n\t\tshowmessage('Advance fetures activated!', 'admin.php#setting', 1);\n\t\tbreak;\n\tcase 'mail_test':\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#setting');\n\t\t$to = DB::result_first(\"SELECT email FROM member WHERE uid='{$uid}'\");\n\t\t$subject = '[贴吧签到助手] 邮件单发测试';\n\t\t$content = \"<p>此封邮件仅用于检测邮件系统是否正常工作。</p><p>此封邮件是由邮件系统直接发送的</p>\";\n\t\t$mail = new mail_content();\n\t\t$mail->address = $to;\n\t\t$mail->subject = $subject;\n\t\t$mail->message = $content;\n\t\t$sender = new mail_sender();\n    \tif($sender->sendMail($mail)){\n            $subject = '[贴吧签到助手] 邮件群发测试';\n            $content = \"<p>此封邮件仅用于检测邮件队列是否正常工作。</p><p>此封邮件是从系统邮件队列中读取并发送的</p>\";\n            DB::insert('mail_queue', array(\n                'to' => $to,\n                'subject' => $subject,\n                'content' => $content,\n                ));\n            saveSetting('mail_queue', 1);\n            showmessage('2 封邮件已经发送，请查收', 'admin.php#setting', 2);\n        }else showmessage('邮件发送失败，请检查设置后重试', 'admin.php#setting', 2);\n\t\tbreak;\n\tcase 'send_mail':\n\t\tif($formhash != $_POST['formhash']) showmessage('来源不可信，请重试', 'admin.php#setting');\n\t\t$title = daddslashes($_POST['title']);\n\t\t$content = daddslashes($_POST['content']);\n\t\t$content = nl2br(htmlspecialchars($content));\n\t\t$content .= \"<p style=\\\"padding: 1.5em 1em 0; color: #999; font-size: 12px;\\\">—— 本邮件由 贴吧签到助手 (<a href=\\\"{$siteurl}\\\">{$siteurl}</a>) 管理员发送</p>\";\n\t\t$query = DB::query(\"SELECT email FROM member\");\n\t\twhile($result = DB::fetch($query)){\n\t\t\tDB::insert('mail_queue', array(\n\t\t\t\t'to' => $result['email'],\n\t\t\t\t'subject' => $title,\n\t\t\t\t'content' => $content,\n\t\t\t\t));\n\t\t}\n\t\tsaveSetting('mail_queue', 1);\n\t\tshowmessage('已经添加至邮件队列，稍后将由系统自动发送', 'admin.php#mail');\n\t\tbreak;\n\tcase 'cloud_sync':\n\t\t$ret = cloud::sync();\n\t\tshowmessage($ret ? '站点信息同步成功！' : '同步信息失败，请稍后再试', 'admin.php#setting');\n\t\tbreak;\n\tcase 'load_plugin':\n\t\texit(json_encode(getPlugins()));\n\t\tbreak;\n\tcase 'load_template':\n\t\texit(json_encode(getTemplates()));\n\t\tbreak;\n\tcase 'load_cron':\n\t\texit(json_encode(getCron()));\n\t\tbreak;\n\tcase 'skip_cron':\n\t\tif(!defined('AFENABLED')) exit();\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#cron');\n\t\t$cron_id = daddslashes($_GET['cid']);\n\t\tDB::query(\"UPDATE cron SET nextrun=nextrun+86400 WHERE id='{$cron_id}'\");\n\t\t$time = TIMESTAMP;\n\t\tDB::query(\"UPDATE cron SET nextrun='{$time}'+3600 WHERE id='{$cron_id}' AND nextrun < '{$time}'\");\n\t\tshowmessage('计划任务修改成功', 'admin.php#cron');\n\t\tbreak;\n\tcase 'clear_cron_cache':\n\t\tif(!defined('AFENABLED')) exit();\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#cron');\n\t\t$nextrun = DB::fetch_first(\"SELECT nextrun FROM cron ORDER BY nextrun ASC LIMIT 0,1\");\n\t\tsaveSetting('next_cron', $nextrun ? $nextrun['nextrun'] : TIMESTAMP + 1200);\n\t\tshowmessage('缓存已清除', 'admin.php#cron');\n\t\tbreak;\n\tcase 'clear_cache':\n\t\tif(!defined('AFENABLED')) exit();\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#cron');\n\t\tCACHE::clear();\n\t\tshowmessage('缓存已清除', 'admin.php#cron');\n\t\tbreak;\n\tcase 'clear_cron':\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#cron');\n\t\t$query = DB::query(\"SELECT * FROM cron ORDER BY `order`\");\n\t\t$deleted = 0;\n\t\twhile($cron = DB::fetch($query)){\n\t\t\tlist($pluginid, $cronscript) = explode('/', $cron['id'], 2);\n\t\t\tif($pluginid && $cronscript){\n\t\t\t\t$path = ROOT.\"./plugins/{$pluginid}/{$cronscript}.cron.php\";\n\t\t\t}else{\n\t\t\t\t$path = SYSTEM_ROOT.\"./function/cron/{$cron[id]}.php\";\n\t\t\t}\n\t\t\tif(!file_exists($path)){\n\t\t\t\tDB::query(\"DELETE FROM cron WHERE id='\".addslashes($cron['id']).\"'\");\n\t\t\t\t$deleted++;\n\t\t\t}\n\t\t}\n\t\tshowmessage(\"共清理了 {$deleted} 个无效的计划任务\");\n\t\tbreak;\n\tcase 'set_template':\n\t\tif($formhash != $_GET['formhash']) showmessage('来源不可信，请重试', 'admin.php#plugin');\n\t\tif(preg_match('/[^A-Za-z0-9_-.]/', $_GET['template'])) showmessage('模板ID（文件夹名）不合法，请与模板作者联系', 'admin.php#template');\n\t\t$templatefile = ROOT.'./template/'.$_GET['template'].'/template.xml';\n\t\tif (file_exists($templatefile)) {\n\t\t\t$info = xml2array(file_get_contents($templatefile));\n\t\t\tif(!$info || !$info['target_version'] || !is_array($info['target_version']) || $info['ui_version']!=UI_VERSION) showmessage('此模板不兼容当前版本', 'admin.php#template');\n\t\t\tsaveSetting('template', daddslashes($_GET['template']));\n\t\t\tif(!in_array(VERSION, $info['target_version'])) showmessage('模板切换成功！<br>注：此风格不适宜当前版本，可能有轻微错位.', 'admin.php#template#');\n\t\t\tshowmessage('模板切换成功！', 'admin.php#template#');\n\t\t}\n\t\telse showmessage('非法操作！', 'admin.php#template');\n\t\tbreak;\n\tdefault:\n\t\t$classes = getClasses();\n\t\tif(getSetting('next_cron') < TIMESTAMP - 7200) define('CRON_ERROR', true);\n\t\tinclude template('admin');\n\t\tbreak;\n}\nfunction getClasses(){\n\t$handle = opendir(SYSTEM_ROOT.'./class/mail/');\n\t$classes = array();\n\twhile (1){\n\t\t$file = readdir($handle);\n\t\tif (!$file) break;\n\t\tif (strexists($file, '.php')){\n\t\t\t$classname = str_replace('.php', '', $file);\n\t\t\trequire_once SYSTEM_ROOT.\"./class/mail/{$classname}.php\";\n\t\t\t$obj = new $classname();\n\t\t\t$classes[$obj->id] = $obj;\n\t\t}\n\t}\n\treturn $classes;\n}\nfunction getPlugins(){\n\t$handle = opendir(ROOT.'./plugins/');\n\t$plugins = $new_plugins = $installed = array();\n\t$query = DB::query('SELECT name FROM plugin');\n\twhile($row = DB::fetch($query)) $installed[] = $row['name'];\n\twhile (1){\n\t\t$folder = readdir($handle);\n\t\tif (!$folder) break;\n\t\tif ($folder == '.' || $folder == '..') continue;\n\t\t$classfile = ROOT.'./plugins/'.$folder.'/plugin.class.php';\n\t\tif(!file_exists($classfile)) continue;\n\t\trequire_once $classfile;\n\t\t$classname = \"plugin_{$folder}\";\n\t\tif(!class_exists(\"plugin_{$folder}\", false)) continue;\n\t\t$obj = new $classname();\n\t\t$arr = array('id' => $folder, 'description' => $obj->description, 'config' => method_exists($obj, 'on_config'), 'enabled' => is_plugin_enabled($folder), 'version' => getPluginVersion($folder), 'installed' => in_array($folder, $installed));\n\t\tif($arr['installed']){\n\t\t\t$plugins[] = $arr;\n\t\t}else{\n\t\t\t$new_plugins[] = $arr;\n\t\t}\n\t}\n\treturn array_merge($plugins, $new_plugins);\n}\nfunction getTemplates(){\n\t$handle = opendir(ROOT.'./template/');\n\t$templates = array();\n\t$current_template = getSetting('template');\n\tif(empty($current_template)) $current_template = 'default';\n\twhile (true){\n\t\t$folder = readdir($handle);\n\t\tif (!$folder) break;\n\t\tif ($folder == '.' || $folder == '..') continue;\n\t\t$infofile = ROOT.\"./template/{$folder}/template.xml\";\n\t\tif(!file_exists($infofile)) continue;\n\t\t$info = xml2array(file_get_contents($infofile));\n\t\t$templates[] = array(\n\t\t\t'id' => $folder,\n\t\t\t'name' => !empty($info['name'])? htmlspecialchars($info['name']) : '未知模板',\n\t\t\t'author' => !empty($info['author'])? htmlspecialchars($info['author']) : '佚名',\n\t\t\t'version' => !empty($info['version'])? htmlspecialchars($info['version']) : '0.0.0',\n\t\t\t'site' => !empty($info['site'])? htmlspecialchars($info['site']) : 'http://www.kookxiang.com',\n\t\t\t'preview' => (empty($info['preview']) || !file_exists(ROOT.\"./template/{$folder}/{$info['preview']}\")) ?  \"template/default/nopreview.png\" : \"template/{$folder}/{$info['preview']}\",\n\t\t\t'current' => $folder == $current_template,\n\t\t);\n\t}\n\treturn $templates;\n}\nfunction getCron(){\n\t$query = DB::query(\"SELECT * FROM cron ORDER BY `order`\");\n\t$system_cron = $plugin_cron = array();\n\twhile($cron = DB::fetch($query)){\n\t\tunset($cron['enabled']);\n\t\t$cron['_id'] = $cron['id'];\n\t\t$cron['nextrun'] = $cron['nextrun'] - TIMESTAMP;\n\t\tlist($pluginid, $cronscript) = explode('/', $cron['id'], 2);\n\t\tif($pluginid && $cronscript){\n\t\t\t$cron['id'] = \"{$cronscript}.cron.php\";\n\t\t\t$cron['type'] = \"插件 {$pluginid} 任务\";\n\t\t\t$plugin_cron[] = $cron;\n\t\t}else{\n\t\t\t$cron['id'] = \"{$cron[id]}.php\";\n\t\t\t$cron['type'] = \"系统内置任务\";\n\t\t\t$system_cron[] = $cron;\n\t\t}\n\t}\n\treturn array_merge($system_cron, $plugin_cron);\n}\nfunction is_plugin_enabled($pluginid){\n\tstatic $enabled_plugin;\n\tif(!isset($enabled_plugin)){\n\t\t$enabled_plugin = array();\n\t\t$arr = CACHE::get('plugins');\n\t\tforeach($arr as $plugin){\n\t\t\t$enabled_plugin[] = $plugin['id'];\n\t\t}\n\t}\n\treturn in_array($pluginid, $enabled_plugin);\n}\nfunction getPluginVersion($pluginid){\n\tstatic $plugin_version;\n\tif(!isset($plugin_version)){\n\t\t$plugin_version = array();\n\t\t$query = DB::query(\"SELECT name, version FROM `plugin`\");\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$plugin_version[ $result['name'] ] = $result['version'];\n\t\t}\n\t}\n\treturn $plugin_version[$pluginid] ? $plugin_version[$pluginid] : 0;\n}\n"
  },
  {
    "path": "ajax.php",
    "content": "<?php\nrequire_once './system/common.inc.php';\nif(!$uid) exit('Access Denied');\n\n$data = array();\nswitch($_GET['v']){\n\tcase 'liked_tieba':\n\t\t$query = DB::query(\"SELECT * FROM my_tieba WHERE uid='{$uid}'\");\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$data[] = $result;\n\t\t}\n\t\tbreak;\n\tcase 'get-bind-status':\n\t\t$data = get_baidu_userinfo($uid);\n\t\tif($data['data']['user_portrait']) dsetcookie(\"avatar_{$uid}\", 'https://ss0.bdstatic.com/7Ls0a8Sm1A5BphGlnYG/sys/portrait/item/'.$data['data']['user_portrait']);\n\t\tbreak;\n\tcase 'get-setting':\n\t\t$data = get_setting($uid);\n\t\tbreak;\n\tcase 'sign-log':\n\t\t$date = date('Ymd');\n\t\t$data['date'] = date('Y-m-d');\n\tcase 'sign-history':\n\t\tif($_GET['v'] == 'sign-history'){\n\t\t\t$date = intval($_GET['date']);\n\t\t\t$data['date'] = substr($date, 0, 4).'-'.substr($date, 4, 2).'-'.substr($date, 6, 2);\n\t\t}\n\t\t$data['log'] = array();\n\t\t$query = DB::query(\"SELECT * FROM sign_log l LEFT JOIN my_tieba t ON t.tid=l.tid WHERE l.uid='{$uid}' AND l.date='{$date}'\");\n\t\twhile($result = DB::fetch($query)){\n\t\t\t$data['log'][] = $result;\n\t\t}\n\t\t$data['count'] = count($data['log']);\n\t\t$data['before_date'] = DB::result_first(\"SELECT date FROM sign_log WHERE uid='{$uid}' AND date<'{$date}' ORDER BY date DESC LIMIT 0,1\");\n\t\t$data['after_date'] = DB::result_first(\"SELECT date FROM sign_log WHERE uid='{$uid}' AND date>'{$date}' ORDER BY date ASC LIMIT 0,1\");\n\t\tbreak;\n}\necho json_encode($data);"
  },
  {
    "path": "api.php",
    "content": "<?php\ndefine('DISABLE_PLUGIN', true);\nrequire_once './system/common.inc.php';\n\nif(!$uid){\n\theader('Location: member.php');\n\texit();\n}\n\nif($_GET['action'] == 'baidu_login'){\n\t$parms = array($_POST['username'], $_POST['password'], $formhash);\n\t$parm_string = serialize($parms);\n\t$parm_string = authcode($parm_string, 'ENCODE', cloud::key());\n\t$parm_string = bin2hex($parm_string);\n\theader('Location: '.cloud::get_api_path().'login.php?sid='.cloud::id().'&parm='.$parm_string);\n}elseif($_GET['action'] == 'register_cloud'){\n\tcloud::do_register();\n}elseif($_GET['action'] == 'receive_cookie'){\n\t$_cookie = $_POST['cookie'] ? $_POST['cookie'] : $_GET['cookie'];\n\tif(!$_cookie) throw new Exception('Empty response!');\n\tif($_GET['formhash'] != $formhash) throw new Exception('Illegal request!');\n    if ($_GET['local']) {\n        $cookie = $_cookie;\n    } else {\n        $cookie = authcode(pack('H*', $_cookie), 'DECODE', cloud::key());\n    }\n\tif(!$cookie) showmessage('非法调用！', './#baidu_bind', 1);\n    if (!verify_cookie($cookie)) showmessage('无法登陆百度贴吧，请尝试重新绑定' . ($_GET['local'] ? '' : '<form action=\"api.php?action=receive_cookie&formhash=' . $formhash . '\" method=\"post\"><input type=\"hidden\" name=\"cookie\" value=\"' . $_cookie . '\"></from><script type=\"text/javascript\">setTimeout(function(){ document.forms[0].submit(); }, 2000);</script>'));\n\tsave_cookie($uid, $cookie);\n\tshowmessage('绑定百度账号成功！<br>正在同步喜欢的贴吧...<script type=\"text/javascript\" src=\"index.php?action=refresh_liked_tieba&formhash='.$formhash.'\"></script><script type=\"text/javascript\">try{ opener.$(\"#guide_page_2\").hide(); opener.$(\"#guide_page_manual\").hide(); opener.$(\"#guide_page_3\").show(); window.close(); }catch(e){}</script>', './#baidu_bind', 1);\n}\n\n?>"
  },
  {
    "path": "config.yaml",
    "content": "---\nname: appid\nversion: 1\n\ncron:\n- description: SignTask\n  url: cron.php\n  schedule: */1 * * * *\n\nhandle:\n- expire: if( path ~ \"css\" ) time 864000\n- expire: if( path ~ \"png\" ) time 864000\n- compress: if ( out_header[\"Content-Length\"]>=512 ) compress\n"
  },
  {
    "path": "index.php",
    "content": "<?php\nrequire_once './system/common.inc.php';\n\nif(!$uid){\n\theader('Location: member.php');\n\texit();\n}elseif($_GET['action']){\n\tswitch($_GET['action']){\n\t\tcase 'skip_tieba':\n\t\t\tif($_GET['formhash'] != $formhash) break;\n\t\t\t$tid = intval($_GET['tid']);\n\t\t\t$skiped = DB::result_first(\"SELECT skiped FROM my_tieba WHERE uid='{$uid}' AND tid='{$tid}'\");\n\t\t\t$skiped = $skiped ? 0 : 1;\n\t\t\t$date = date('Ymd', TIMESTAMP+900);\n\t\t\tif($skiped == 1){\n\t\t\t\tDB::query(\"UPDATE sign_log SET `status`='-2' WHERE uid='{$uid}' AND tid='{$tid}' AND date='{$date}' AND `status` < 2\");\n\t\t\t}else{\n\t\t\t\tDB::query(\"UPDATE sign_log SET `status`='0' WHERE uid='{$uid}' AND tid='{$tid}' AND date='{$date}' AND `status` < 2\");\n\t\t\t}\n\t\t\tDB::query(\"UPDATE my_tieba SET skiped='{$skiped}' WHERE uid='{$uid}' AND tid='{$tid}'\");\n\t\t\tif(!DB::affected_rows()) showmessage('发生未知错误: 无法修改贴吧设置');\n\t\t\tshowmessage('修改签到设置成功！');\n\t\tcase 'clear_cookie':\n\t\t\tif($_GET['formhash'] != $formhash) break;\n\t\t\tDB::query(\"UPDATE member_setting SET cookie='' WHERE uid='{$uid}'\");\n\t\t\tDB::query(\"DELETE FROM my_tieba WHERE uid='{$uid}'\");\n\t\t\tDB::query(\"DELETE FROM sign_log WHERE uid='{$uid}'\");\n\t\t\tshowmessage('已经解除百度账号绑定<br>您可以稍后重新进行绑定', './#baidu_bind#', 1);\n\t\tcase 'update_cookie':\n\t\t\tif(!$_POST['cookie']) break;\n\t\t\t$cookie = daddslashes($_POST['cookie']);\n\t\t\tif(!preg_match('/BDUSS=(.+?)/', $cookie)) showmessage('Cookie 信息不完整，请尝试重新获取', './#baidu_bind', 1);\n\t\t\tif(!preg_match('/BAIDUID=(.+?)/', $cookie)) showmessage('Cookie 信息不完整，请尝试重新获取', './#baidu_bind', 1);\n\t\t\tif(!verify_cookie($cookie)) showmessage('无法登陆百度贴吧，请检查 Cookie 是否填写正确', './#baidu_bind', 1);\n\t\t\t$cookie = daddslashes($cookie);\n\t\t\tsave_cookie($uid, $cookie);\n\t\t\tshowmessage('您的 Cookie 信息已经更新<script type=\"text/javascript\" src=\"?action=refresh_liked_tieba&formhash='.$formhash.'\"></script>', './#baidu_bind', 1);\n\t\t\tbreak;\n\t\tcase 'update_setting':\n\t\t\tif($_POST['formhash'] != $formhash) break;\n\t\t\tDB::update('member_setting', array(\n\t\t\t\t'error_mail' => $_POST['error_mail'] ? 1 : 0,\n\t\t\t\t'send_mail' => $_POST['send_mail'] ? 1 : 0,\n\t\t\t\t'zhidao_sign' => $_POST['zhidao_sign'] ? 1 : 0,\n\t\t\t\t'wenku_sign' => $_POST['wenku_sign'] ? 1 : 0,\n\t\t\t\t), \"uid='{$uid}'\");\n\t\t\tCACHE::save('user_setting_'.$uid, '');\n\t\t\tshowmessage('设置已经保存', './#setting', 1);\n\t\t\tbreak;\n\t\tcase 'change_password':\n\t\t\tif($_POST['formhash'] != $formhash) break;\n\t\t\t$user = DB::fetch_first(\"SELECT * FROM member WHERE uid='{$uid}'\");\n\t\t\tif(!$_POST['old_password']) showmessage('请输入旧密码', './#setting', 1);\n\t\t\tif(!$_POST['new_password']) showmessage('请输入新密码', './#setting', 1);\n\t\t\tif($_POST['new_password'] != $_POST['new_password2']) showmessage('两次输入的新密码不一样，请检查', './#setting', 1);\n\t\t\tif(!Widget_Password::verify($user, $_POST['old_password'])) showmessage('旧密码错误！请检查输入', './#setting', 1);\n\t\t\t$newpassword = Widget_Password::encrypt($user, $_POST['new_password']);\n\t\t\tDB::update('member', array('password' => $newpassword), \"uid='{$uid}'\");\n\t\t\tHOOK::run('change_password', true, $uid);\n\t\t\tshowmessage('您的密码已经更新', './#setting', 1);\n\t\t\tbreak;\n\t\tcase 'reset_failure':\n\t\t\tif($formhash != $_GET['formhash']) showmessage('请稍候...', '?action=reset_failure&formhash='.$formhash, 0);\n\t\t\t$date = date('Ymd');\n\t\t\tDB::query(\"UPDATE sign_log SET status='0', retry='0' WHERE uid='{$uid}' AND date='{$date}' AND status<0\");\n\t\t\tshowmessage('已经重置失败状态，稍后系统将自动重试', './#signlog', 1);\n\t\t\tbreak;\n\t\tcase 'refresh_liked_tieba':\n\t\t\tif($formhash != $_GET['formhash']) showmessage('刷新中，请稍候...', '?action=refresh_liked_tieba&formhash='.$formhash, 0);\n\t\t\tlist($insert, $deleted) = update_liked_tieba($uid);\n\t\t\tshowmessage(\"喜欢的贴吧列表已经更新,<br>新增{$insert}个贴吧, 删除{$deleted}个贴吧\", './#liked_tieba', 1);\n\t\t\tbreak;\n\t}\n\theader('Location: ./');\n\texit();\n}\n\nif($_GET['ignore_update']){\n\tdsetcookie('ignore_update', '1', 7200);\n\texit();\n}elseif(is_admin($uid) && !$_COOKIE['ignore_update']){\n\tif(getSetting('new_version')) define('NEW_VERSION', true);\n}\n\nif(getSetting('account_switch')){\n\t// Multi User Support\n\t$query = DB::query(\"SELECT * FROM member_bind WHERE uid='{$uid}'\");\n\t$users = array();\n\twhile($result = DB::fetch($query)){\n\t\t$users[ $result['_uid'] ] = $result['username'];\n\t}\n}\n\ninclude template('index');"
  },
  {
    "path": "install/index.php",
    "content": "<?php\nerror_reporting(E_ERROR | E_PARSE);\n$config_file = dirname(__FILE__).'/../system/config.inc.php';\ninclude_once $config_file;\nif($_config){\n\theader('Location: ..');\n\texit();\n}\n\n@touch($config_file);\n\n// MySQLi Support\nif (!function_exists('mysql_connect') && function_exists('mysqli_connect')) {\n    function mysql_connect($server = 'localhost', $username = 'root', $password = '', $new_link = false, $client_flags = 0) {\n        return mysqli_connect($server, $username, $password, '');\n    }\n    function mysql_insert_id($link = null) {\n        return mysqli_insert_id($link);\n    }\n    function mysql_select_db($db_name, $link = null) {\n        return mysqli_select_db($link, $db_name);\n    }\n    function mysql_query($db_name, $link = null) {\n        return mysqli_query($link, $db_name);\n    }\n    function mysql_error($link = null) {\n        return mysqli_error($link);\n    }\n    function mysql_errno($link = null) {\n        return mysqli_errno($link);\n    }\n}\n\nswitch($_GET['step']){\n\tdefault:\n\t\tif(defined('SAE_ACCESSKEY')){\n\t\t\theader('Location: sae.php');\n\t\t\texit();\n\t\t}elseif(getenv('OPENSHIFT_APP_NAME')){\n\t\t\t$extra_script = '<script type=\"text/javascript\">if(confirm(\"要使用 OpenShift 一键安装向导吗？\")) location.href=\"openshift.php\";</script>';\n\t\t}\n\t\t$content = '<p>欢迎使用 贴吧签到助手 安装向导！</p><p>本程序将会指引你在服务器上配置好“贴吧签到助手”</p><p>点击右侧的“下一步”按钮开始</p><p class=\"btns\"><button onclick=\"location.href=\\'./?step=check\\';\">下一步 &raquo;</button>';\n\t\tshow_install_page('Welcome', $content);\n\t\tbreak;\n\tcase 'check':\n\t\t$content = '<p>安装前，程序需要检查当前的服务器环境是否允许运行“贴吧签到助手”</p><p>请确保表格中每一行均为绿色，以避免可能带来的问题</p><table><thead><tr><td>项目</td><td>要求</td><td>当前状态</td></tr></thead><tbody>';\n\t\t$content .= '<tr><td>PHP 版本</td><td><span class=\"status on\">5.2</span></td><td><span class=\"status '.(version_compare('5.2.0', PHP_VERSION, '<') ? 'on' : 'off').'\">'.PHP_VERSION.'</span></td></tr>';\n\t\t$content .= '<tr><td>PHP: allow_url_fopen</td><td>'.show_status(true).'</td><td>'.show_status(ini_get('allow_url_fopen')).'</td></tr>';\n\t\t$content .= '<tr><td>CURL</td><td>'.show_status(true).'</td><td>'.show_status(function_exists('curl_init')).'</td></tr>';\n\t\t$content .= '<tr><td>Socket 连接</td><td>'.show_status(true).'</td><td>'.show_status(function_exists('fsockopen') || function_exists('pfsockopen')).'</td></tr>';\n\t\t$content .= '<tr><td>system/config.inc.php</td><td>'.show_status(true, '可写').'</td><td>'.show_status(is_writable($config_file), '可写', '不可写').'</td></tr>';\n\t\t$content .= '</tbody></table>';\n\t\tif(function_exists('curl_init') && (function_exists('fsockopen') || function_exists('pfsockopen')) && is_writable($config_file)) $content .= '<br><p class=\"btns\"><button onclick=\"location.href=\\'./?step=database\\';\">下一步 &raquo;</button></p>';\n\t\tshow_install_page('服务器兼容性检查', $content);\n\t\tbreak;\n\tcase 'database':\n\t\t$content = '<div class=\"config\"><p>请填写数据库连接信息</p><br>';\n\t\t$content .= '<form action=\"./?step=install\" method=\"post\" onsubmit=\"show_waiting();\">';\n\t\t$content .= '<p><span>数据库服务器:</span><input type=\"text\" name=\"db_server\" value=\"localhost\" /></p>';\n\t\t$content .= '<p><span>数据库端口:</span><input type=\"text\" name=\"db_port\" value=\"3306\" /></p>';\n\t\t$content .= '<p><span>数据库用户名:</span><input type=\"text\" name=\"db_username\" value=\"root\" /></p>';\n\t\t$content .= '<p><span>数据库密码:</span><input type=\"password\" name=\"db_password\" /></p>';\n\t\t$content .= '<p><span>数据库名:</span><input type=\"text\" name=\"db_name\" value=\"kk_sign\" /></p>';\n\t\tif(function_exists('mysql_pconnect')) $content .= '<p><span>&nbsp;</span><label><input type=\"checkbox\" name=\"pconnect\" value=\"1\" /> 保持与数据库服务器的连接</label></p>';\n\t\t$content .= '<br><p><span>管理员用户名:</span><input type=\"text\" name=\"username\" required /></p>';\n\t\t$content .= '<p><span>管理员密码:</span><input type=\"password\" name=\"password\" required /></p>';\n\t\t$content .= '<p><span>管理员邮箱:</span><input type=\"text\" name=\"email\" required /></p>';\n\t\t$content .= '<p class=\"btns\"><span>&nbsp;</span><input type=\"submit\" value=\"下一步 &raquo;\" /></p>';\n\t\t$content .= '</form></div><div class=\"waiting hidden\"><p>程序正在执行必要的安装步骤，请耐心等待...</p></div>';\n\t\t$content .= '<script type=\"text/javascript\">function show_waiting(){ $(\".config\").hide(); $(\".waiting\").show(); }</script>';\n\t\tshow_install_page('数据库配置', $content);\n\t\tbreak;\n\tcase 'install':\n\t\t$db_host = $_POST['db_server'];\n\t\t$db_port = intval($_POST['db_port']);\n\t\t$db_username = $_POST['db_username'];\n\t\t$db_password = $_POST['db_password'];\n\t\t$db_name = $_POST['db_name'];\n\t\t$db_pconnect = isset($_POST['pconnect']);\n\t\t$function = $db_pconnect ? 'mysql_connect' : 'mysql_pconnect';\n\t\t$link = mysql_connect(\"{$db_host}:{$db_port}\", $db_username, $db_password);\n\t\tif(!$link) show_back('数据库配置', '错误：无法连接数据库服务器！</p><p>'.mysql_error());\n\t\t$selected = mysql_select_db($db_name, $link);\n\t\tif(!$selected){\n\t\t\t// 尝试新建\n\t\t\tmysql_query(\"CREATE DATABASE `{$db_name}`\", $link);\n\t\t\t$selected = mysql_select_db($db_name, $link);\n\t\t\tif(!$selected) show_back('数据库配置', '错误：指定的数据库不可用</p><p>'.mysql_error());\n\t\t}\n\t\tmysql_query(\"SET character_set_connection=utf8, character_set_results=utf8, character_set_client=binary\");\n\t\t$syskey = random(32);\n\t\t$username = addslashes($_POST['username']);\n\t\t$password = md5($syskey.md5($_POST['password']).$syskey);\n\t\t$email = addslashes($_POST['email']);\n\t\tif(!$username || !$password || !$email) show_back('注册账号', '您输入的信息不完整');\n\t\tif(preg_match('/[<>\\'\\\\\"]/i', $username)) show_back('注册账号', '用户名中有被禁止使用的关键字');\n\t\tif(strlen($username) < 6) show_back('注册账号', '用户名至少要6个字符(即2个中文 或 6个英文)，请修改');\n\t\tif(strlen($username) > 24) show_back('注册账号', '用户名过长，请修改');\n\t\t$install_script = file_get_contents(dirname(__FILE__).'/install.sql');\n\t\tpreg_match('/version ([0-9a-z.]+)/i', $install_script, $match);\n\t\t$version = trim($match[1]);\n\t\tif(!$version) show_back('正在安装', '安装脚本有误，请重新上传');\n\t\t$err = runquery($install_script, $link);\n\t\tif($err) show_back('正在安装', '安装过程出现错误:</p><p>'.$err);\n\t\tmysql_query(\"INSERT INTO member SET username='{$username}', password='{$password}', email='{$email}'\");\n\t\t$uid = mysql_insert_id($link);\n\t\tmysql_query(\"INSERT INTO member_setting SET uid='{$uid}', cookie=''\");\n\t\tsaveSetting('block_register', 1);\n\t\tsaveSetting('jquery_mode', 2);\n\t\tsaveSetting('admin_uid', $uid);\n\t\tsaveSetting('SYS_KEY', $syskey);\n\t\t$_config = array(\n\t\t\t'version' => $version,\n\t\t\t'db' => array(\n\t\t\t\t'server' => $db_host,\n\t\t\t\t'port' => $db_port,\n\t\t\t\t'username' => $db_username,\n\t\t\t\t'password' => $db_password,\n\t\t\t\t'name' => $db_name,\n\t\t\t\t'pconnect' => $db_pconnect,\n\t\t\t\t),\n\t\t\t);\n\t\t$content = '<?php'.PHP_EOL.'/* Auto-generated config file */'.PHP_EOL.'$_config = ';\n\t\t$content .= var_export($_config, true).';'.PHP_EOL.'?>';\n\t\tfile_put_contents($config_file, $content);\n\t\t$content = '<p>贴吧签到助手 已经成功安装！</p><p>要正常签到，请为脚本 cron.php 添加每分钟一次的计划任务。</p><p>系统默认关闭用户注册，如果有需要，请到后台启用用户注册功能。</p><br><p class=\"btns\"><button onclick=\"location.href=\\'../\\';\">登录 &raquo;</button>';\n\t\tshow_install_page('安装成功', $content);\n}\n\nfunction show_back($title, $text){\n\t$content = '<p>'.$text.'</p>';\n\t$content .= '<br><p class=\"btns\"><button onclick=\"history.back();\">&laquo; 返回</button></p>';\n\tshow_install_page($title, $content);\n}\n\nfunction show_install_page($title, $content){\n\tglobal $extra_script;\n\t$template = '<!DOCTYPE html><html><head><title>贴吧签到助手</title><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" /><meta name=\"HandheldFriendly\" content=\"true\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\" /><meta name=\"author\" content=\"kookxiang\" /><meta name=\"copyright\" content=\"KK\\'s Laboratory\" /><link rel=\"shortcut icon\" href=\"../favicon.ico\" /><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" /><meta name=\"renderer\" content=\"webkit\"><link rel=\"stylesheet\" href=\"../template/default/style/main.css\" type=\"text/css\" /><link rel=\"stylesheet\" href=\"../template/default/style/custom.css\" type=\"text/css\" /><style type=\"text/css\">.status.on, .status.off { padding: 2px 0 2px 20px; } .status.on { color: #22dd33; background: url(../template/default/style/done.gif) no-repeat 1px 50%; } .status.off { color: #ff3344; background: url(../template/default/style/error.gif) no-repeat 1px 50%; } .main-box { max-width: 550px; top: 135px; } .main-content { text-align: left; font-size: 13px; } .config span { width: 100px; text-align:right; display:block; float: left; height: 30px; line-height: 30px; margin-right: 15px; } </style></head><body><div id=\"append_parent\"><div class=\"loading-icon\"><img src=\"../template/default/style/loading.gif\" /> 载入中...</div></div><div class=\"wrapper\" id=\"page_index\"><h1>贴吧签到助手 - 安装向导</h1><div class=\"sidebar\"></div><div class=\"main-content\"><h2>{title}</h2>{content}</div></div><script src=\"//lib.sinaapp.com/js/jquery/1.10.2/jquery-1.10.2.min.js\"></script><script src=\"../template/default/js/fwin.js\"></script><script type=\"text/javascript\">hideloading();</script>'.$extra_script.'</body></html>';\n\techo str_replace(array('{title}', '{content}'), array($title, $content), $template);\n\texit();\n}\n\nfunction show_status($status, $on_txt = 'On', $off_txt = 'Off'){\n\treturn $status ? '<span class=\"status on\">'.$on_txt.'</span>' : '<span class=\"status off\">'.$off_txt.'</span>';\n}\n\nfunction runquery($sql, $link){\n\t$sql = str_replace(\"\\r\", \"\\n\", $sql);\n\tforeach(explode(\";\\n\", $sql) as $query) {\n\t\t$query = trim($query);\n\t\tif(!$query) continue;\n\t\t$ret = mysql_query($query, $link);\n\t\tif(!$ret) return mysql_error();\n\t}\n}\n\nfunction saveSetting($k, $v){\n\tglobal $link;\n\t$v = addslashes($v);\n\tmysql_query(\"REPLACE INTO setting SET v='{$v}', k='{$k}'\", $link);\n}\n\nfunction random($length, $numeric = 0) {\n\t$seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);\n\t$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));\n\t$hash = '';\n\t$max = strlen($seed) - 1;\n\tfor($i = 0; $i < $length; $i++) {\n\t\t$hash .= $seed{mt_rand(0, $max)};\n\t}\n\treturn $hash;\n}\n\n?>"
  },
  {
    "path": "install/install.sql",
    "content": "/*\n Install script for version 1.14.4.14\n */\n\nDROP TABLE IF EXISTS `cache`;\nDROP TABLE IF EXISTS `cron`;\nDROP TABLE IF EXISTS `download`;\nDROP TABLE IF EXISTS `mail_queue`;\nDROP TABLE IF EXISTS `member`;\nDROP TABLE IF EXISTS `member_bind`;\nDROP TABLE IF EXISTS `member_setting`;\nDROP TABLE IF EXISTS `my_tieba`;\nDROP TABLE IF EXISTS `plugin`;\nDROP TABLE IF EXISTS `plugin_var`;\nDROP TABLE IF EXISTS `setting`;\nDROP TABLE IF EXISTS `sign_log`;\nDROP TABLE IF EXISTS `update_source`;\n\nCREATE TABLE IF NOT EXISTS `cache` (\n  `k` varchar(32) NOT NULL,\n  `v` text NOT NULL,\n  PRIMARY KEY (`k`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `cron` (\n  `id` varchar(16) NOT NULL,\n  `enabled` tinyint(1) NOT NULL,\n  `nextrun` int(10) unsigned NOT NULL,\n  `order` tinyint(4) NOT NULL,\n  PRIMARY KEY (`id`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\nINSERT INTO `cron` (`id`, `enabled`, `nextrun`, `order`) VALUES\n('daily', 1, 0, 0),\n('ext_sign', 1, 0, 50),\n('mail', 1, 0, 100),\n('sign', 1, 0, 20),\n('sign_retry', 1, 0, 110),\n('update_tieba', 1, 0, 10);\n\nCREATE TABLE IF NOT EXISTS `download` (\n  `path` varchar(128) NOT NULL,\n  `content` text NOT NULL,\n  PRIMARY KEY (`path`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `mail_queue` (\n  `id` int(11) NOT NULL AUTO_INCREMENT,\n  `to` varchar(255) NOT NULL,\n  `subject` varchar(255) NOT NULL,\n  `content` text NOT NULL,\n  PRIMARY KEY (`id`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `member` (\n  `uid` int(11) unsigned NOT NULL AUTO_INCREMENT,\n  `username` varchar(24) DEFAULT NULL,\n  `password` varchar(32) NOT NULL,\n  `email` varchar(32) NOT NULL,\n  PRIMARY KEY (`uid`)\n) ENGINE=MyISAM  DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `member_bind` (\n  `uid` int(10) unsigned NOT NULL,\n  `_uid` int(10) unsigned NOT NULL,\n  `username` varchar(12) NOT NULL,\n  KEY `uid` (`uid`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `member_setting` (\n  `uid` int(10) unsigned NOT NULL,\n  `error_mail` tinyint(1) NOT NULL DEFAULT '1',\n  `send_mail` tinyint(1) NOT NULL DEFAULT '0',\n  `zhidao_sign` tinyint(1) NOT NULL DEFAULT '0',\n  `wenku_sign` tinyint(1) NOT NULL DEFAULT '0',\n  `cookie` text CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,\n  PRIMARY KEY (`uid`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `my_tieba` (\n  `tid` int(10) unsigned NOT NULL AUTO_INCREMENT,\n  `uid` int(10) unsigned NOT NULL,\n  `fid` int(10) unsigned NOT NULL,\n  `name` varchar(127) NOT NULL,\n  `unicode_name` varchar(512) NOT NULL,\n  `skiped` tinyint(1) NOT NULL DEFAULT '0',\n  PRIMARY KEY (`tid`),\n  KEY `uid` (`uid`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `plugin` (\n  `id` int(11) NOT NULL AUTO_INCREMENT,\n  `enable` tinyint(1) NOT NULL DEFAULT '1',\n  `name` varchar(64) NOT NULL,\n  `version` varchar(8) NOT NULL DEFAULT '0',\n  PRIMARY KEY (`id`),\n  UNIQUE KEY `name` (`name`)\n) ENGINE=MyISAM  DEFAULT CHARSET=utf8;\n\nINSERT INTO `plugin` (`id`, `enable`, `name`, `version`) VALUES\n(1, 1, 'debug_info', '');\n\nCREATE TABLE IF NOT EXISTS `plugin_var` (\n  `pluginid` varchar(64) NOT NULL,\n  `key` varchar(32) NOT NULL DEFAULT '',\n  `value` text NOT NULL,\n  PRIMARY KEY (`pluginid`,`key`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `setting` (\n  `k` varchar(32) NOT NULL,\n  `v` varchar(256) NOT NULL,\n  PRIMARY KEY (`k`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `sign_log` (\n  `tid` int(10) unsigned NOT NULL,\n  `uid` int(10) unsigned NOT NULL,\n  `date` int(11) NOT NULL DEFAULT '0',\n  `status` tinyint(4) NOT NULL DEFAULT '0',\n  `exp` tinyint(4) NOT NULL DEFAULT '0',\n  `retry` tinyint(3) unsigned NOT NULL DEFAULT '0',\n  UNIQUE KEY `tid` (`tid`,`date`),\n  KEY `uid` (`uid`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `update_source` (\n  `id` varchar(16) NOT NULL,\n  `path` varchar(128) NOT NULL,\n  PRIMARY KEY (`id`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n"
  },
  {
    "path": "install/openshift.php",
    "content": "<?php\nif(!getenv('OPENSHIFT_APP_NAME')){\n\theader('Location: ./');\n\texit();\n}\nerror_reporting(E_ERROR | E_PARSE);\n$config_file = dirname(__FILE__).'/../system/config.inc.php';\ninclude_once $config_file;\nif($_config){\n\theader('Location: ..');\n\texit();\n}\n\n@touch($config_file);\n\nswitch($_GET['step']){\n\tdefault:\n\t\t$content = '<p>欢迎使用 贴吧签到助手 安装向导！</p><p>本程序将会指引你在服务器上配置好“贴吧签到助手”</p><p>点击右侧的“下一步”按钮开始</p><br><p>Openshift one-key installer. Thanks to <a href=\"http://tieba.baidu.com/home/main?un=%D3%F4%C3%C6de%CB%B5\" target=\"_blank\">郁闷de说</a></p><p class=\"btns\"><button onclick=\"location.href=\\'./openshift.php?step=database\\';\">下一步 &raquo;</button>';\n\t\tshow_install_page('Welcome', $content);\n\t\tbreak;\n\tcase 'database':\n\t\t$content = '<div class=\"config\"><p>请设置站点管理员信息</p><br>';\n\t\t$content .= '<form action=\"./openshift.php?step=install\" method=\"post\" onsubmit=\"show_waiting();\">';\n\t\t$content .= '<p><span>管理员用户名:</span><input type=\"text\" name=\"username\" required /></p>';\n\t\t$content .= '<p><span>管理员密码:</span><input type=\"password\" name=\"password\" required /></p>';\n\t\t$content .= '<p><span>管理员邮箱:</span><input type=\"text\" name=\"email\" required /></p>';\n\t\t$content .= '<p class=\"btns\"><span>&nbsp;</span><input type=\"submit\" value=\"下一步 &raquo;\" /></p>';\n\t\t$content .= '</form></div><div class=\"waiting hidden\"><p>程序正在执行必要的安装步骤，请耐心等待...</p></div>';\n\t\t$content .= '<script type=\"text/javascript\">function show_waiting(){ $(\".config\").hide(); $(\".waiting\").show(); }</script>';\n\t\tshow_install_page('站点配置', $content);\n\t\tbreak;\n\tcase 'install':\n\t\t$db_host = getenv('OPENSHIFT_MYSQL_DB_HOST');\n\t\t$db_port = intval(getenv('OPENSHIFT_MYSQL_DB_PORT'));\n\t\t$db_username = getenv('OPENSHIFT_MYSQL_DB_USERNAME');\n\t\t$db_password = getenv('OPENSHIFT_MYSQL_DB_PASSWORD');\n\t\t$db_name = getenv('OPENSHIFT_APP_NAME');\n\t\t$db_pconnect = false;\n\t\t$function = $db_pconnect ? 'mysql_connect' : 'mysql_pconnect';\n\t\t$link = mysql_connect(\"{$db_host}:{$db_port}\", $db_username, $db_password);\n\t\tif(!$link) show_back('数据库配置', '错误：无法连接数据库服务器！</p><p>'.mysql_error());\n\t\t$selected = mysql_select_db($db_name, $link);\n\t\tif(!$selected){\n\t\t\t// 尝试新建\n\t\t\tmysql_query(\"CREATE DATABASE `{$db_name}`\", $link);\n\t\t\t$selected = mysql_select_db($db_name, $link);\n\t\t\tif(!$selected) show_back('数据库配置', '错误：指定的数据库不可用</p><p>'.mysql_error());\n\t\t}\n\t\tmysql_query(\"SET character_set_connection=utf8, character_set_results=utf8, character_set_client=binary\");\n\t\t$syskey = random(32);\n\t\t$username = addslashes($_POST['username']);\n\t\t$password = md5($syskey.md5($_POST['password']).$syskey);\n\t\t$email = addslashes($_POST['email']);\n\t\tif(!$username || !$password || !$email) show_back('注册账号', '您输入的信息不完整');\n\t\tif(preg_match('/[<>\\'\\\\\"]/i', $username)) show_back('注册账号', '用户名中有被禁止使用的关键字');\n\t\tif(strlen($username) < 6) show_back('注册账号', '用户名至少要6个字符(即2个中文 或 6个英文)，请修改');\n\t\tif(strlen($username) > 24) show_back('注册账号', '用户名过长，请修改');\n\t\t$install_script = file_get_contents(dirname(__FILE__).'/install.sql');\n\t\tpreg_match('/version ([0-9a-z.]+)/i', $install_script, $match);\n\t\t$version = trim($match[1]);\n\t\tif(!$version) show_back('正在安装', '安装脚本有误，请重新上传');\n\t\t$err = runquery($install_script, $link);\n\t\tmysql_query(\"INSERT INTO member SET username='{$username}', password='{$password}', email='{$email}'\");\n\t\t$uid = mysql_insert_id($link);\n\t\tmysql_query(\"INSERT INTO member_setting SET uid='{$uid}', cookie=''\");\n\t\tsaveSetting('block_register', 1);\n\t\tsaveSetting('jquery_mode', 2);\n\t\tsaveSetting('admin_uid', $uid);\n\t\tsaveSetting('SYS_KEY', $syskey);\n\t\tif($err) show_back('正在安装', '安装过程出现错误:</p><p>'.mysql_error());\n\t\t$_config = array(\n\t\t\t'version' => $version,\n\t\t\t'db' => array(\n\t\t\t\t'server' => $db_host,\n\t\t\t\t'port' => $db_port,\n\t\t\t\t'username' => $db_username,\n\t\t\t\t'password' => $db_password,\n\t\t\t\t'name' => $db_name,\n\t\t\t\t'pconnect' => $db_pconnect,\n\t\t\t\t),\n\t\t\t);\n\t\t$content = '<?php'.PHP_EOL.'/* Auto-generated config file */'.PHP_EOL.'$_config = ';\n\t\t$content .= var_export($_config, true).';'.PHP_EOL.'?>';\n\t\tfile_put_contents($config_file, $content);\n\t\t$content = '<p>贴吧签到助手 已经成功安装！</p><p>系统默认关闭用户注册，如果有需要，请到后台启用用户注册功能。</p><p style=\"color: red\">Openshift 用户如出现错误请前往管理界面重启应用</p><br><p class=\"btns\"><button onclick=\"location.href=\\'../\\';\">登录 &raquo;</button>';\n\t\tshow_install_page('安装成功', $content);\n}\n\nfunction show_back($title, $text){\n\t$content = '<p>'.$text.'</p>';\n\t$content .= '<br><p class=\"btns\"><button onclick=\"history.back();\">&laquo; 返回</button></p>';\n\tshow_install_page($title, $content);\n}\n\nfunction show_install_page($title, $content){\n\t$template = '<!DOCTYPE html><html><head><title>贴吧签到助手</title><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" /><meta name=\"HandheldFriendly\" content=\"true\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\" /><meta name=\"author\" content=\"kookxiang\" /><meta name=\"copyright\" content=\"KK\\'s Laboratory\" /><link rel=\"shortcut icon\" href=\"../favicon.ico\" /><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" /><meta name=\"renderer\" content=\"webkit\"><link rel=\"stylesheet\" href=\"../template/default/style/main.css\" type=\"text/css\" /><link rel=\"stylesheet\" href=\"../template/default/style/custom.css\" type=\"text/css\" /><style type=\"text/css\">.status.on, .status.off { padding: 2px 0 2px 20px; } .status.on { color: #22dd33; background: url(../template/default/style/done.gif) no-repeat 1px 50%; } .status.off { color: #ff3344; background: url(../template/default/style/error.gif) no-repeat 1px 50%; } .main-box { max-width: 550px; top: 135px; } .main-content { min-height: 150px; text-align: left; font-size: 13px; padding-bottom: 18px; margin-left: 0; } .main-content>div { min-height: 0; } .main-wrapper { min-height: 150px; } .config span { width: 100px; text-align:right; display:block; float: left; height: 30px; line-height: 30px; margin-right: 15px; } .wrapper:after { display:block; content: \\'.\\'; padding-bottom: 175px; }</style></head><body><div class=\"wrapper\" id=\"page_index\"><div id=\"append_parent\"><div class=\"loading-icon\"><img src=\"../template/default/style/loading.gif\" /> 载入中...</div></div><div class=\"main-box clearfix\"><h1>贴吧签到助手 - 安装向导</h1><div class=\"main-wrapper\"><div class=\"main-content\"><h2>{title}</h2>{content}</div></div></div></div><script src=\"//lib.sinaapp.com/js/jquery/1.10.2/jquery-1.10.2.min.js\"></script><script src=\"../template/default/js/fwin.js\"></script><script type=\"text/javascript\">hideloading();</script></body></html>';\n\techo str_replace(array('{title}', '{content}'), array($title, $content), $template);\n\texit();\n}\n\nfunction show_status($status, $on_txt = 'On', $off_txt = 'Off'){\n\treturn $status ? '<span class=\"status on\">'.$on_txt.'</span>' : '<span class=\"status off\">'.$off_txt.'</span>';\n}\n\nfunction runquery($sql, $link){\n\t$sql = str_replace(\"\\r\", \"\\n\", $sql);\n\tforeach(explode(\";\\n\", trim($sql)) as $query) {\n\t\t$query = trim($query);\n\t\tif(!$query) continue;\n\t\t$ret = mysql_query($query, $link);\n\t\tif(!$ret) return mysql_error();\n\t}\n}\n\nfunction saveSetting($k, $v){\n\tglobal $link;\n\t$v = addslashes($v);\n\tmysql_query(\"REPLACE INTO setting SET v='{$v}', k='{$k}'\", $link);\n}\n\nfunction random($length, $numeric = 0) {\n\t$seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);\n\t$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));\n\t$hash = '';\n\t$max = strlen($seed) - 1;\n\tfor($i = 0; $i < $length; $i++) {\n\t\t$hash .= $seed{mt_rand(0, $max)};\n\t}\n\treturn $hash;\n}\n\n?>"
  },
  {
    "path": "install/sae.php",
    "content": "<?php\nif(!defined('SAE_ACCESSKEY')) exit();\ndefine('IN_KKFRAME', true);\ndefine('SYSTEM_ROOT', dirname(__FILE__).'/');\ndefine('ROOT', dirname(SYSTEM_ROOT).'/');\nerror_reporting(E_ERROR | E_PARSE);\n$_config = array(\n\t'db' => array(\n\t\t'server' => SAE_MYSQL_HOST_M,\n\t\t'port' => SAE_MYSQL_PORT,\n\t\t'username' => SAE_MYSQL_USER,\n\t\t'password' => SAE_MYSQL_PASS,\n\t\t'name' => SAE_MYSQL_DB,\n\t\t'pconnect' => false,\n\t),\n);\nrequire_once '../system/class/error.php';\nset_exception_handler(array('error', 'exception_error'));\nrequire_once '../system/class/db.php';\n$query = DB::query(\"SELECT v FROM setting LIMIT 0,1\", 'SILENT');\nif($query){\n\theader('Location: ..');\n\texit();\n}\n\nswitch($_GET['step']){\n\tdefault:\n\t\t$content = '<p>欢迎使用 贴吧签到助手 安装向导！</p><p>本程序将会指引你在服务器上配置好“贴吧签到助手”</p><p>点击右侧的“下一步”按钮开始</p><p class=\"btns\"><button onclick=\"location.href=\\'./sae.php?step=database\\';\">下一步 &raquo;</button>';\n\t\tshow_install_page('Welcome', $content);\n\t\tbreak;\n\tcase 'database':\n\t\t$content = '<div class=\"config\"><p>请填写基本信息</p><br>';\n\t\t$content .= '<form action=\"./sae.php?step=install\" method=\"post\" onsubmit=\"show_waiting();\">';\n\t\t$content .= '<p><span>管理员用户名:</span><input type=\"text\" name=\"username\" required /></p>';\n\t\t$content .= '<p><span>管理员密码:</span><input type=\"password\" name=\"password\" required /></p>';\n\t\t$content .= '<p><span>管理员邮箱:</span><input type=\"text\" name=\"email\" required /></p>';\n\t\t$content .= '<p class=\"btns\"><span>&nbsp;</span><input type=\"submit\" value=\"下一步 &raquo;\" /></p>';\n\t\t$content .= '</form></div><div class=\"waiting hidden\"><p>程序正在执行必要的安装步骤，请耐心等待...</p></div>';\n\t\t$content .= '<script type=\"text/javascript\">function show_waiting(){ $(\".config\").hide(); $(\".waiting\").show(); }</script>';\n\t\tshow_install_page('系统配置', $content);\n\t\tbreak;\n\tcase 'install':\n\t\t$syskey = random(32);\n\t\t$username = addslashes($_POST['username']);\n\t\t$password = md5($syskey.md5($_POST['password']).$syskey);\n\t\t$email = addslashes($_POST['email']);\n\t\tif(!$username || !$password || !$email) show_back('注册账号', '您输入的信息不完整');\n\t\tif(preg_match('/[<>\\'\\\\\"]/i', $username)) show_back('注册账号', '用户名中有被禁止使用的关键字');\n\t\tif(strlen($username) < 6) show_back('注册账号', '用户名至少要6个字符(即2个中文 或 6个英文)，请修改');\n\t\tif(strlen($username) > 24) show_back('注册账号', '用户名过长，请修改');\n\t\t$install_script = file_get_contents(dirname(__FILE__).'/install.sql');\n\t\tpreg_match('/version ([0-9a-z.]+)/i', $install_script, $match);\n\t\t$version = trim($match[1]);\n\t\tif(!$version) show_back('正在安装', '安装脚本有误，请重新上传');\n\t\t$err = runquery($install_script);\n\t\tDB::query(\"INSERT INTO member SET username='{$username}', password='{$password}', email='{$email}'\");\n\t\t$uid = DB::insert_id();\n\t\tDB::query(\"INSERT INTO member_setting SET uid='{$uid}', cookie=''\");\n\t\tsaveSetting('block_register', 1);\n\t\tsaveSetting('jquery_mode', 2);\n\t\tsaveSetting('admin_uid', $uid);\n\t\tsaveSetting('SYS_KEY', $syskey);\n\t\tsaveSetting('version', $version);\n\t\t$_config = array(\n\t\t\t'db' => array(\n\t\t\t\t'server' => $db_host,\n\t\t\t\t'port' => $db_port,\n\t\t\t\t'username' => $db_username,\n\t\t\t\t'password' => $db_password,\n\t\t\t\t'name' => $db_name,\n\t\t\t\t'pconnect' => $db_pconnect,\n\t\t\t\t),\n\t\t\t);\n\t\t$content = '<?php'.PHP_EOL.'/* Auto-generated config file */'.PHP_EOL.'$_config = ';\n\t\t$content .= var_export($_config, true).';'.PHP_EOL.'?>';\n\t\tfile_put_contents($config_file, $content);\n\t\t$content = '<p>贴吧签到助手 已经成功安装！</p><p>系统默认关闭用户注册，如果有需要，请到后台启用用户注册功能。</p><br><p class=\"btns\"><button onclick=\"location.href=\\'../\\';\">登录 &raquo;</button>';\n\t\tshow_install_page('安装成功', $content);\n}\n\nfunction show_back($title, $text){\n\t$content = '<p>'.$text.'</p>';\n\t$content .= '<br><p class=\"btns\"><button onclick=\"history.back();\">&laquo; 返回</button></p>';\n\tshow_install_page($title, $content);\n}\n\nfunction show_install_page($title, $content){\n\t$template = '<!DOCTYPE html><html><head><title>贴吧签到助手</title><meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" /><meta name=\"HandheldFriendly\" content=\"true\" /><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\" /><meta name=\"author\" content=\"kookxiang\" /><meta name=\"copyright\" content=\"KK\\'s Laboratory\" /><link rel=\"shortcut icon\" href=\"../favicon.ico\" /><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" /><meta name=\"renderer\" content=\"webkit\"><link rel=\"stylesheet\" href=\"../template/default/style/main.css\" type=\"text/css\" /><link rel=\"stylesheet\" href=\"../template/default/style/custom.css\" type=\"text/css\" /><style type=\"text/css\">.status.on, .status.off { padding: 2px 0 2px 20px; } .status.on { color: #22dd33; background: url(../template/default/style/done.gif) no-repeat 1px 50%; } .status.off { color: #ff3344; background: url(../template/default/style/error.gif) no-repeat 1px 50%; } .main-box { max-width: 550px; top: 135px; } .main-content { min-height: 150px; text-align: left; font-size: 13px; padding-bottom: 18px; margin-left: 0; } .main-content>div { min-height: 0; } .main-wrapper { min-height: 150px; } .config span { width: 100px; text-align:right; display:block; float: left; height: 30px; line-height: 30px; margin-right: 15px; } .wrapper:after { display:block; content: \\'.\\'; padding-bottom: 175px; }</style></head><body><div class=\"wrapper\" id=\"page_index\"><div id=\"append_parent\"><div class=\"loading-icon\"><img src=\"../template/default/style/loading.gif\" /> 载入中...</div></div><div class=\"main-box clearfix\"><h1>贴吧签到助手 - 安装向导</h1><div class=\"main-wrapper\"><div class=\"main-content\"><h2>{title}</h2>{content}</div></div></div></div><script src=\"//lib.sinaapp.com/js/jquery/1.10.2/jquery-1.10.2.min.js\"></script><script src=\"../template/default/js/fwin.js\"></script><script type=\"text/javascript\">hideloading();</script></body></html>';\n\techo str_replace(array('{title}', '{content}'), array($title, $content), $template);\n\texit();\n}\n\nfunction show_status($status, $on_txt = 'On', $off_txt = 'Off'){\n\treturn $status ? '<span class=\"status on\">'.$on_txt.'</span>' : '<span class=\"status off\">'.$off_txt.'</span>';\n}\n\nfunction runquery($sql, $link){\n\t$sql = str_replace(\"\\r\", \"\\n\", $sql);\n\tforeach(explode(\";\\n\", trim($sql)) as $query) {\n\t\t$query = trim($query);\n\t\tif(!$query) continue;\n\t\tDB::query($query, $link);\n\t}\n}\n\nfunction saveSetting($k, $v){\n\tglobal $link;\n\t$v = addslashes($v);\n\tDB::query(\"REPLACE INTO setting SET v='{$v}', k='{$k}'\", $link);\n}\n\nfunction random($length, $numeric = 0) {\n\t$seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);\n\t$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));\n\t$hash = '';\n\t$max = strlen($seed) - 1;\n\tfor($i = 0; $i < $length; $i++) {\n\t\t$hash .= $seed{mt_rand(0, $max)};\n\t}\n\treturn $hash;\n}\n\n?>"
  },
  {
    "path": "member.php",
    "content": "<?php\nrequire_once './system/common.inc.php';\n$invite_code = getSetting('invite_code');\nif($_GET['action'] == 'logout' && $_GET['hash']==$formhash){\n\tdsetcookie('token', '');\n\t$_COOKIE['token'] = '';\n\tshowmessage('您已经退出登录了！', dreferer(), 1);\n}elseif($uid && $_GET['action'] == 'unbind_user'){\n\tif($_GET['formhash'] != $formhash) showmessage('来源不可信，请重试', './');\n\t$_uid = intval($_GET['uid']);\n\t$user = DB::fetch_first(\"SELECT * FROM member_bind WHERE uid='{$uid}' AND _uid='{$_uid}'\");\n\tif(!$user) showmessage('你并没有绑定该账号', './');\n\tDB::query(\"DELETE FROM member_bind WHERE uid='{$uid}' AND _uid='{$_uid}'\");\n\tDB::query(\"DELETE FROM member_bind WHERE uid='{$_uid}' AND _uid='{$uid}'\");\n\tshowmessage(\"成功解除与 {$user['username']} 的绑定！\", './');\n}elseif($uid && $_GET['action'] == 'bind_user'){\n\tif($_POST['formhash'] != $formhash) showmessage('来源不可信，请重试', './');\n\tif(!$_POST['username']){\n\t\tshowmessage('请输入用户名', './#');\n\t}elseif(!$_POST['password']){\n\t\tshowmessage('请输入密码', './#');\n\t}\n\t$_username = daddslashes($_POST['username']);\n\tif($_username == $username) showmessage('请输入其他账户的信息', './#');\n\tif(strlen($_username) > 24) showmessage('用户名过长，请修改', dreferer(), 5);\n\t$user = DB::fetch_first(\"SELECT * FROM member WHERE username='{$_username}'\");\n\t$userid = $user['uid'];\n\t$verified = Widget_Password::verify($user, $_POST['password']);\n\tif($verified){\n\t\t$exists = DB::result_first(\"SELECT _uid FROM member_bind WHERE uid='{$uid}' AND _uid='{$userid}'\");\n\t\tif($exists) showmessage('您此前已经绑定过此帐号', './#');\n\t\tDB::insert('member_bind', array(\n\t\t\t'uid' => $uid,\n\t\t\t'_uid' => $userid,\n\t\t\t'username' => $user['username'],\n\t\t));\n\t\t$exists = DB::result_first(\"SELECT uid FROM member_bind WHERE _uid='{$uid}' AND uid='{$userid}'\");\n\t\tif(!$exists){\n\t\t\t$username = DB::result_first(\"SELECT username FROM member WHERE uid='{$uid}'\");\n\t\t\tDB::insert('member_bind', array(\n\t\t\t\t'uid' => $userid,\n\t\t\t\t'_uid' => $uid,\n\t\t\t\t'username' => $username,\n\t\t\t));\n\t\t}\n\t\tshowmessage(\"您已经成功绑定用户“{$user[username]}”\", './');\n\t}else{\n\t\tshowmessage('用户名/密码不正确！', './#');\n\t}\n}elseif($uid && $_GET['action'] == 'switch'){\n\tif($_GET['formhash'] != $formhash) showmessage('来源不可信，请重试', './');\n\t$target_uid = intval($_GET['uid']);\n\t$uid = DB::result_first(\"SELECT _uid FROM member_bind WHERE uid='{$uid}' AND _uid='{$target_uid}'\");\n\tif(!$uid) showmessage('您尚未绑定该账号，无法进行切换', './');\n\t$username = get_username($uid);\n\tdo_login($uid);\n\tshowmessage(\"您已经成功切换至 {$username}！\", dreferer(), 1);\n}elseif($uid){\n\tshowmessage('您已经登录了~', dreferer(), 1);\n}elseif($_GET['action'] == 'find_password'){\n\tif($_GET['token']){\n\t\t$str = authcode($_GET['token'], 'DECODE');\n\t\tif(!$str) showmessage('链接有误，请重新获取', './');\n\t\tlist($uid, $exptime, $password, $random) = explode(\"\\t\", $str);\n\t\tif($exptime < TIMESTAMP) showmessage('链接已过期，请重新获取', './');\n\t\t$user = DB::fetch_first(\"SELECT * FROM member WHERE uid='{$uid}' AND password='{$password}'\");\n\t\tif(!$user) showmessage('链接已经失效，请重新获取', './');\n\t\t$new_password = random(10);\n\t\t$newpassword = Widget_Password::encrypt($user, $new_password);\n\t\tDB::update('member', array('password' => $newpassword), \"uid='{$uid}'\");\n\t\tshowmessage(\"您的密码已经重置为：<br>{$new_password}<br><br>请使用新密码登录并修改密码。\");\n\t}elseif($_POST['username'] && $_POST['email']){\n\t\t$username = daddslashes($_POST['username']);\n\t\t$email = daddslashes($_POST['email']);\n\t\t$user = DB::fetch_first(\"SELECT * FROM member WHERE username='{$username}' AND email='{$email}'\");\n\t\tif(!$user) showmessage('用户名 / 邮箱有误', './');\n\t\t$info = array(\n\t\t\t$user['uid'],\t\t\t// UID\n\t\t\tTIMESTAMP + 3600,\t\t// Token 过期时间\n\t\t\t$user['password'],\t\t// 当前密码\n\t\t\trandom(32),\t\t\t\t// 随机字符\n\t\t);\n\t\t$token = urlencode(authcode(implode(\"\\t\", $info), 'ENCODE'));\n\t\t$link = \"{$siteurl}member.php?action=find_password&token={$token}\";\n\t\t$message = <<<EOF\n<p>我们已经收到您的找回密码申请，请您点击下方的链接重新设置密码：</p>\n<blockquote><a href=\"{$link}\">{$link}</a></blockquote>\n<p>（注：请在一小时内点击上面的链接，我们将向您提供新的密码）</p>\n<br>\n<p>如果您没有要求重置密码却收到本邮件，请及时删除此邮件以确保账户安全。</p>\nEOF;\n\t\tDB::insert('mail_queue', array(\n\t\t\t'to' => $user['email'],\n\t\t\t'subject' => \"贴吧签到助手 - 密码找回\",\n\t\t\t'content' => $message,\n\t\t\t));\n\t\tsaveSetting('mail_queue', 1);\n\t\tshowmessage('邮件发送成功，请到邮箱查收', './');\n\t}\n\theader('Location: member.php');\n\texit();\n}elseif($_GET['action'] == 'register'){\n\tif(getSetting('block_register')) showmessage('抱歉，当前站点禁止新用户注册', 'member.php');\n\t$count = DB::result_first('SELECT COUNT(*) FROM member');\n\tif($_POST && strexists($_SERVER['HTTP_REFERER'], 'member.php')){\n\t\tlist($time, $hash, $member_count) = explode(\"\\t\", authcode($_COOKIE['key'], 'DECODE'));\n\t\tif(getSetting('register_check') && $time > TIMESTAMP - 5 || $time < TIMESTAMP - 300) $_POST = array();\n\t\tif(getSetting('register_limit') && $member_count != $count) showmessage('当前注册人数过多，请您稍后再试', 'member.php');\n\t\tif($count > 1000) showmessage('超过当前站点最大用户数量上限，无法注册', 'member.php');\n\t\t$_POST['username'] = $_POST['password'] = $_POST['email'] = null;\n\t\tforeach($_POST as $key => $value){\n\t\t\t$key = authcode($key, 'DECODE', $hash);\n\t\t\tif($key == 'username'){\n\t\t\t\t$_POST['username'] = $value;\n\t\t\t}elseif($key == 'password'){\n\t\t\t\t$_POST['password'] = $value;\n\t\t\t}elseif($key == 'email'){\n\t\t\t\t$_POST['email'] = $value;\n\t\t\t}\n\t\t}\n\t\tif(!$_POST['username']){\n\t\t\tshowmessage('请输入用户名', 'member.php');\n\t\t}elseif(!$_POST['password']){\n\t\t\tshowmessage('请输入密码', 'member.php');\n\t\t}elseif(!$_POST['email']){\n\t\t\tshowmessage('请输入您的邮箱', 'member.php');\n\t\t}else{\n\t\t\tif($invite_code && $_POST['invite_code'] != $invite_code) showmessage('邀请码有误', 'member.php');\n\t\t\t$username = daddslashes($_POST['username']);\n\t\t\t$email = daddslashes($_POST['email']);\n\t\t\tif(!is_email($email)) showmessage('邮箱格式不正确，请修改', dreferer(), 5);\n\t\t\tif(!$username || !$_POST['password'] || !$email) showmessage('您输入的信息不完整', 'member.php');\n\t\t\tif(preg_match('/[<>\\'\\\\\"]/i', $username)) showmessage('用户名中有被禁止使用的关键字', 'member.php');\n\t\t\tif(strlen($username) < 6) showmessage('用户名至少要6个字符(即2个中文 或 6个英文)，请修改', dreferer(), 5);\n\t\t\tif(strlen($username) > 24) showmessage('用户名过长，请修改', dreferer(), 5);\n\t\t\t$un = strtolower($username);\n\t\t\tif(strexists($un, 'admin') || strexists($un, 'guanli')) showmessage('用户名不和谐，请修改', dreferer(), 5);\n\t\t\t$user = DB::fetch_first(\"SELECT * FROM member WHERE username='{$username}'\");\n\t\t\tif($user) showmessage('用户名已经存在', 'member.php');\n\t\t\tHOOK::run('before_register');\n\t\t\t$uid = do_register($username, $_POST['password'], $email);\n\t\t\tdo_login($uid);\n\t\t\tHOOK::run('register_finish', false, $uid);\n\t\t\tshowmessage(\"注册成功，您的用户名是 <b>{$username}</b> 记住了哦~！\", dreferer(), 3);\n\t\t}\n\t}\n\theader('Location: member.php');\n\texit();\n}elseif($_POST){\n\tif($_POST['username'] && $_POST['password']){\n\t\t$username = daddslashes($_POST['username']);\n\t\t$un = strtolower($username);\n\t\tif(strlen($username) > 24) showmessage('用户名过长，请修改', dreferer(), 5);\n\t\t$user = DB::fetch_first(\"SELECT * FROM member WHERE username='{$username}'\");\n\t\t$verified = Widget_Password::verify($user, $_POST['password']);\n\t\tif($verified) {\n\t\t\t$login_exp = TIMESTAMP + 3600;\n\t\t\tdo_login($user['uid']);\n\t\t\t$username = $user['username'];\n\t\t\tshowmessage(\"欢迎回来，{$username}！\", dreferer(), 1);\n\t\t}else{\n\t\t\tshowmessage('对不起，您的用户名或密码错误，无法登录.', 'member.php', 3);\n\t\t}\n\t}\n}\n$count = DB::result_first('SELECT COUNT(*) FROM member');\n$hash = random(6);\n$time = TIMESTAMP;\ndsetcookie('key', authcode(\"{$time}\\t{$hash}\\t{$count}\", 'ENCODE'));\n$form_username = authcode('username', 'ENCODE', $hash);\n$form_password = authcode('password', 'ENCODE', $hash);\n$form_email = authcode('email', 'ENCODE', $hash);\ninclude template('member');"
  },
  {
    "path": "plugin.php",
    "content": "<?php\ndefine('IN_ADMINCP', true);\ndefine('DISABLE_PLUGIN', true);\nrequire_once './system/common.inc.php';\n$plugin_id = htmlspecialchars($_GET['id']);\n$plugins = CACHE::get('plugins');\nforeach($plugins as $plugin){\n\tif($plugin['id'] == $plugin_id) {\n\t\t$exists = true;\n\t\tbreak;\n\t}\n}\nif(!isset($exists)) throw new Exception(\"Unknown plugin '{$plugin_id}'\");\n$obj = HOOK::getPlugin($plugin_id);\nif($obj instanceof Plugin){\n\t$obj->handleAction();\n} else {\n\tthrow new Exception('This plugin doesn\\'t support to be called directly.');\n}\n"
  },
  {
    "path": "plugins/cloud_stat/cloud_stat.cron.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n$obj = $_PLUGIN['obj']['cloud_stat'];\nif(!$obj && file_exists(ROOT.'plugins/cloud_stat/plugin.class.php')) {\n\t$obj = new plugin_cloud_stat();\n}\n\n$date = date('Ymd', TIMESTAMP);\n$tieba = intval($obj->getSetting('tieba'));\n$exp = intval($obj->getSetting('exp'));\n$tieba += DB::result_first(\"SELECT COUNT(*) FROM sign_log WHERE status=2 AND date='{$date}'\");\n$obj->saveSetting('tieba', $tieba);\n$exp += DB::result_first(\"SELECT SUM(exp) FROM sign_log WHERE status=2 AND date='{$date}'\");\n$obj->saveSetting('exp', $exp);\n\n/* send data */\n\n$sid = cloud::id();\n$key = cloud::key();\n$sign = md5($key.$sid.$tieba.$exp.$key);\n$ret = kk_fetch_url(\"http://api.ikk.me/stat.php?sid={$sid}&tieba={$tieba}&exp={$exp}&sign={$sign}\");\nif($ret) {\n\t$data = json_decode($ret);\n\tif($data){\n\t\t$obj->saveSetting('cloud_tieba', $data->tieba);\n\t\t$obj->saveSetting('cloud_exp', $data->exp);\n\t}\n}\n\ncron_set_nextrun($tomorrow + 3600);\n"
  },
  {
    "path": "plugins/cloud_stat/index.inc.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied!');\n$obj = $_PLUGIN['obj']['cloud_stat'];\n?>\n<script type=\"text/javascript\">\nfunction load_cloud_stat_index(){\n\tshowloading();\n\t$.getJSON(\"plugin.php?id=cloud_stat&action=get\", function(result){\n\t\tif(!result) return;\n\t\tvar str = '';\n\t\tstr += '<p>截止今天, 贴吧签到助手共完成 <span>'+result.ctieba+'</span> 次签到</p>';\n\t\tstr += '<p>为贴吧用户获取 <span>'+result.cexp+'</span> 点经验.</p>';\n\t\tstr += '<p>其中, 当前网站签到 <span>'+result.tieba+'</span> 次, 获取了 <span>'+result.exp+'</span> 点经验.</p>';\n\t\t$('.kk_cloud_stat').html(str);\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 获取统计信息失败').addButton('确定', function(){ location.reload(); }).append(); }).always(function(){ hideloading(); });\n}\n</script>\n<h2>签到云统计 *</h2>\n<style type=\"text/css\">\n.kk_cloud_stat { padding: 30px 20px; }\n.kk_cloud_stat p { margin: 10px 0; font-size: 26px; line-height: 42px; font-weight: lighter; text-align: center; }\n.kk_cloud_stat span { font-size: 32px; font-family: \"Segoe UI Light\", \"Segoe UI\", \"幼圆\", \"Arial\"; letter-spacing: 5px; vertical-align: baseline; font-size: 64px; text-shadow: 0 0 15px #777; position: relative; top: 5px; }\n.stat_source { position: absolute; bottom: 10px; }\n</style>\n<div class=\"kk_cloud_stat\">\n</div>\n<p class=\"stat_source\">* 数据源自 贴吧签到助手 开放平台 旗下所有签到站点.</p>"
  },
  {
    "path": "plugins/cloud_stat/plugin.class.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied!');\nclass plugin_cloud_stat extends Plugin{\n\tvar $description = '云统计，记录建站以来的签到次数以及获得经验数';\n\tvar $modules = array(\n\t\tarray('type' => 'page', 'id' => 'index', 'title' => '签到云统计', 'file' => 'index.inc.php'),\n\t\tarray('type' => 'cron', 'cron' => array('id' => 'cloud_stat/cloud_stat', 'order' => '105')),\n\t);\n\tvar $version = '1.1';\n\tfunction checkCompatibility(){\n\t\tif(version_compare(VERSION, '1.14.4.24', '<')) showmessage('本插件不兼容此版的贴吧签到助手.');\n\t}\n\tfunction install(){\n\t\t$count = DB::result_first('SELECT COUNT(*) FROM sign_log WHERE status=2');\n\t\t$this->saveSetting('tieba', $count);\n\t\t$count = DB::result_first('SELECT SUM(exp) FROM sign_log WHERE status=2');\n\t\t$this->saveSetting('exp', $count);\n\t\t$ret = kk_fetch_url(\"http://api.ikk.me/stat.php\");\n\t\tif(!$ret) return;\n\t\t$data = json_decode($ret);\n\t\tif(!$data) return;\n\t\t$this->saveSetting('cloud_tieba', $data->tieba);\n\t\t$this->saveSetting('cloud_exp', $data->exp);\n\t}\n\tfunction mklink($sourceFile, $targetFile){\n\t\treturn @file_put_contents($targetFile, '<?php @include '.var_export($sourceFile, true).'; ?>');\n\t}\n\tfunction on_upgrade($from_version){\n\t\tswitch($from_version){\n\t\t\tcase '1.0':\n\t\t\t\tDB::query(\"UPDATE cron SET id='cloud_stat/cloud_stat' WHERE id='cloud_stat'\");\n\t\t\t\treturn '1.1';\n\t\t\tdefault:\n\t\t\t\tthrow new Exception(\"Unknown plugin version: {$from_version}\");\n\t\t}\n\t}\n\tfunction handleAction(){\n\t\techo json_encode(array(\n\t\t\t'ctieba' => intval($this->getSetting('cloud_tieba')),\n\t\t\t'cexp' => intval($this->getSetting('cloud_exp')),\n\t\t\t'tieba' => intval($this->getSetting('tieba')),\n\t\t\t'exp' => intval($this->getSetting('exp')),\n\t\t));\n\t}\n}"
  },
  {
    "path": "plugins/debug_info/plugin.class.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied!');\nclass plugin_debug_info extends Plugin{\n\tvar $description = '(已废弃) 此插件将会在页脚输出一行调试信息，便于了解服务器状态';\n\tvar $modules = array();\n\tfunction page_footer(){\n\t\treturn;\n\t}\n}"
  },
  {
    "path": "plugins/register_limit/plugin.class.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied!');\nclass plugin_register_limit extends Plugin {\n\tvar $description = '限制单个 IP 的注册上限';\n\tvar $modules = array();\n\tfunction install(){\n\t\tDB::query('CREATE TABLE IF NOT EXISTS `kk_ip_limit` ( `a` tinyint(3) unsigned NOT NULL, `b` tinyint(3) unsigned NOT NULL, `c` tinyint(3) unsigned NOT NULL, `d` tinyint(3) unsigned NOT NULL, `count` tinyint(3) unsigned NOT NULL, `lastact` int(10) unsigned NOT NULL, UNIQUE KEY `ip` (`a`,`b`,`c`,`d`)) ENGINE=MEMORY DEFAULT CHARSET=utf8 COLLATE=utf8_bin;');\n\t}\n\tfunction uninstall(){\n\t\tDB::query('DROP TABLE kk_ip_limit');\n\t}\n\tfunction checkCompatibility(){\n\t\tif(defined('IN_SAE')) showmessage('本插件不兼容当前运行环境.');\n\t}\n\tfunction on_load(){\n\t\tif($_GET['action'] != 'register') return;\n\t\tif(!$_POST) return;\n\t\tlist($a, $b, $c, $d) = explode('.', $_SERVER['REMOTE_ADDR']);\n\t\t$a = intval($a);\n\t\t$b = intval($b);\n\t\t$c = intval($c);\n\t\t$d = intval($d);\n\t\t$count = DB::result_first(\"SELECT count FROM kk_ip_limit WHERE a='{$a}' AND b='{$b}' AND c='{$c}' AND d='{$d}'\");\n\t\t$time = TIMESTAMP;\n\t\tDB::query(\"DELETE FROM kk_ip_limit WHERE lastact<{$time}-86400\");\n\t\tif($count > 0) DB::query(\"UPDATE kk_ip_limit SET lastact='{$time}' WHERE a='{$a}' AND b='{$b}' AND c='{$c}' AND d='{$d}'\");\n\t\tif($count >= $this->getSetting('ip_reglimit', 5)) showmessage('达到单 IP 注册上限，禁止注册。', dreferer());\n\t\tif($count > 0){\n\t\t\tDB::query(\"UPDATE kk_ip_limit SET count=count+1 WHERE a='{$a}' AND b='{$b}' AND c='{$c}' AND d='{$d}'\");\n\t\t}else{\n\t\t\tDB::query(\"INSERT INTO kk_ip_limit SET count=1, lastact='{$time}', a='{$a}', b='{$b}', c='{$c}', d='{$d}'\");\n\t\t}\n\t}\n\tfunction on_config(){\n\t\tif($_POST['limit']){\n\t\t\t$this->saveSetting('ip_reglimit', $_POST['limit']);\n\t\t\tshowmessage('设置已经保存！');\n\t\t}else{\n\t\t\treturn '<p>单个 IP 注册上限：<input type=\"text\" name=\"limit\" value=\"'.$this->getSetting('ip_reglimit', 5).'\" /></p>';\n\t\t}\n\t}\n}"
  },
  {
    "path": "plugins/stat/plugin.class.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied!');\nclass plugin_stat extends Plugin{\n\tvar $description = '用于在页面尾部嵌入自定义的统计代码';\n\tvar $modules = array();\n\tvar $version = '1.0';\n\tfunction page_footer_js(){\n\t\t$data = $this->getSetting('code');\n\t\tif($data) return '<div class=\"hidden\">'.$data.'</div>';\n\t}\n\tfunction on_config(){\n\t\tif($_POST['code']){\n\t\t\t$this->saveSetting('code', $_POST['code']);\n\t\t\tshowmessage('设置已经保存！');\n\t\t}else{\n\t\t\treturn '<p>页脚统计代码：</p><p><textarea name=\"code\">'.htmlspecialchars($this->getSetting('code')).'</textarea></p>';\n\t\t}\n\t}\n}"
  },
  {
    "path": "plugins/xxx_post/c_daily.cron.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n$date = date('Ymd', TIMESTAMP+900);\nDB::query(\"ALTER TABLE xxx_post_log CHANGE `date` `date` INT NOT NULL DEFAULT '{$date}'\");\nDB::query(\"INSERT IGNORE INTO xxx_post_log (sid, uid) SELECT sid, uid FROM xxx_post_posts\");\n$delete_date = date('Ymd', TIMESTAMP - 86400*10);\nDB::query(\"DELETE FROM xxx_post_log WHERE date<'$delete_date'\");\n$setime=HOOK::getPlugin('xxx_post')->getSetting('se');\nif(!$setime) $setime=21;\n$nxrun =$today+$setime*3600;\nDB::query(\"update cron set nextrun='$nxrun' where id='xxx_post/c_se'\");\ncron_set_nextrun($tomorrow + 600);\n"
  },
  {
    "path": "plugins/xxx_post/c_first.cron.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\nrequire_once ROOT.'./plugins/xxx_post/core.php';\n$date = date('Ymd', TIMESTAMP+900);\n$count = DB::result_first(\"select COUNT(*) from xxx_post_log as a left join xxx_post_setting as b on a.uid=b.uid where a.date='$date' and a.status<b.runtimes and a.retry<b.runtimes*2 and b.frequency<=2\");\n$first_end=HOOK::getPlugin('xxx_post')->getSetting('first_end');\nif(!$first_end) $first_end=15;\n$first_end_time=$today+$first_end*3600;\nif($first_end_time<TIMPSTAMP) $count=0;\n$endtime = TIMESTAMP + 45;\nif($count){\n\twhile($endtime > time()){\n\t\t$count = DB::result_first(\"select COUNT(*) from xxx_post_log as a left join xxx_post_setting as b on a.uid=b.uid where a.date='$date' and a.status<b.runtimes and a.retry<b.runtimes*2 and b.frequency<=2 and b.runtime<\".TIMESTAMP);\n\t\tif($count==0) break;\n\t\t$offset = rand(1, $count) - 1;\n\t\t$sid = DB::result_first(\"select sid from xxx_post_log as a left join xxx_post_setting as b on a.uid=b.uid where a.date='$date' and a.status<b.runtimes and a.retry<b.runtimes*2 and b.frequency<=2 and b.runtime<\".TIMESTAMP.\" limit $offset,1\");\n\t\tif(!$sid) break;\n\t\t$tiezi=DB::fetch_first(\"SELECT * FROM xxx_post_posts WHERE sid='$sid'\");\n\t\tif(!$tiezi){\n\t\t\tDB::query(\"UPDATE xxx_post_log SET retry=retry+3 WHERE sid='$sid' AND date='$date'\");\n\t\t\tcontinue;\n\t\t}\n\t\t$x_content_count = DB::result_first(\"SELECT COUNT(*) FROM xxx_post_content WHERE uid='{$tiezi[uid]}'\");\n\t\t$x_content_offset = rand(1, $x_content_count) - 1;\n\t\t$x_content = DB::result_first(\"SELECT content FROM xxx_post_content WHERE uid='{$tiezi[uid]}' limit $x_content_offset,1\");\n\t\tlist($statue,$result) = client_rppost($tiezi['uid'],$tiezi,$x_content);\n\t\tif($statue == 2){\n\t\t\t$x_delay=DB::result_first(\"select delay from xxx_post_setting where uid={$tiezi[uid]}\");\n\t\t\tif($x_delay){\n\t\t\t\t$runtime=TIMESTAMP+$x_delay*56;\n\t\t\t\tDB::query(\"UPDATE xxx_post_setting SET runtime=$runtime WHERE uid='{$tiezi[uid]}'\");\n\t\t\t}\n\t\t\tDB::query(\"UPDATE xxx_post_log SET status=status+1 WHERE sid='$sid' AND date='$date'\");\n\t\t}else if($statue==1||$statue==8){\n\t\t\t$x_runtimes=DB::result_first(\"select runtimes from xxx_post_setting where uid={$tiezi[uid]}\");\n\t\t\tDB::query(\"UPDATE xxx_post_log SET retry='$x_runtimes' WHERE sid='$sid' AND date='$date'\");\n\t\t}\n\t\telse if($statue==5||$statue==7) continue;\n\t\telse DB::query(\"UPDATE xxx_post_log SET retry=retry+1 WHERE sid='$sid' AND date='$date'\");\n\t\tif(!defined('SIGN_LOOP')) break;\n\t\tsleep(1);\n\t\t}\n}else{\n\t\tcron_set_nextrun($tomorrow + 3600);\n}"
  },
  {
    "path": "plugins/xxx_post/c_se.cron.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\nrequire_once ROOT.'./plugins/xxx_post/core.php';\n$date = date('Ymd', TIMESTAMP+900);\n$count = DB::result_first(\"select COUNT(*) from xxx_post_log as a left join xxx_post_setting as b on a.uid=b.uid where a.date='$date' and a.status<b.runtimes*2 and a.retry<b.runtimes*4 and b.frequency=1\");\n$endtime = TIMESTAMP + 45;\nif($count){\n\twhile($endtime > time()){\n\t\t$count = DB::result_first(\"select COUNT(*) from xxx_post_log as a left join xxx_post_setting as b on a.uid=b.uid where a.date='$date' and a.status<b.runtimes*2 and a.retry<b.runtimes*4 and b.frequency=1 and b.runtime<\".TIMESTAMP);\n\t\tif($count==0) break;\n\t\t$offset = rand(1, $count) - 1;\n\t\t$sid = DB::result_first(\"select sid from xxx_post_log as a left join xxx_post_setting as b on a.uid=b.uid where a.date='$date' and a.status<b.runtimes*2 and a.retry<b.runtimes*4 and b.frequency=1 and b.runtime<\".TIMESTAMP.\" LIMIT $offset,1\");\n\t\tif(!$sid) break;\n\t\t$tiezi=DB::fetch_first(\"SELECT * FROM xxx_post_posts WHERE sid='$sid'\");\n\t\tif(!$tiezi){\n\t\t\tDB::query(\"UPDATE xxx_post_log SET retry=retry+3 WHERE sid='$sid' AND date='$date'\");\n\t\t\tcontinue;\n\t\t}\n\t\t$x_content_count = DB::result_first(\"SELECT COUNT(*) FROM xxx_post_content WHERE uid='{$tiezi[uid]}'\");\n\t\t$x_content_offset = rand(1, $x_content_count) - 1;\n\t\t$x_content = DB::result_first(\"SELECT content FROM xxx_post_content WHERE uid='{$tiezi[uid]}' limit $x_content_offset,1\");\n\t\tlist($statue,$result) = client_rppost($tiezi['uid'],$tiezi,$x_content);\n\t\tif($statue == 2){\n\t\t\t$x_delay=DB::result_first(\"select delay from xxx_post_setting where uid={$tiezi[uid]}\");\n\t\t\tif($x_delay){\n\t\t\t\t$runtime=TIMESTAMP+$x_delay*56;\n\t\t\t\tDB::query(\"UPDATE xxx_post_setting SET runtime=$runtime WHERE uid='{$tiezi[uid]}'\");\n\t\t\t}\n\t\t\tDB::query(\"UPDATE xxx_post_log SET status=status+1 WHERE sid='$sid' AND date='$date'\");\n\t\t}else if($statue==1||$statue==8){\n\t\t\t$x_runtimes=DB::result_first(\"select runtimes from xxx_post_setting where uid={$tiezi[uid]}\");\n\t\t\t$x_runtimes=$x_runtimes*2;\n\t\t\tDB::query(\"UPDATE xxx_post_log SET retry='$x_runtimes' WHERE sid='$sid' AND date='$date'\");\n\t\t}\n\t\telse if($statue==5||$statue==7) continue;\n\t\telse DB::query(\"UPDATE xxx_post_log SET retry=retry+1 WHERE sid='$sid' AND date='$date'\");\n\t\tif(!defined('SIGN_LOOP')) break;\n\t\tsleep(1);\n\t\t}\n}else{\n\t\tcron_set_nextrun($tomorrow + 3600);\n}"
  },
  {
    "path": "plugins/xxx_post/c_sxbk.cron.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n$date = date('Ymd', TIMESTAMP+900);\n$count = DB::result_first(\"select COUNT(*) from xxx_post_log as a left join xxx_post_setting as b on a.uid=b.uid where a.date='$date' and a.retry<40 and b.frequency=4\");\nif(HOOK::getPlugin('xxx_post')->getSetting('sxbk')!=1) {cron_set_nextrun($tomorrow + 5400);$count=0;}\n$endtime = TIMESTAMP + 45;\nif($count){\n\trequire_once ROOT.'./plugins/xxx_post/core.php';\n\twhile($endtime > time()){\n\t\t$count = DB::result_first(\"select COUNT(*) from xxx_post_log as a left join xxx_post_setting as b on a.uid=b.uid where a.date='$date' and a.retry<40 and b.runtime<\".TIMESTAMP.\" and b.frequency=4\");\n\t\tif($count==0) break;\n\t\t$offset = rand(1, $count) - 1;\n\t\t$sid = DB::result_first(\"select sid from xxx_post_log as a left join xxx_post_setting as b on a.uid=b.uid where a.date='$date' and a.retry<40 and b.runtime<\".TIMESTAMP.\" and b.frequency=4 LIMIT $offset,1\");\n\t\tif(!$sid) break;\n\t\t$tiezi=DB::fetch_first(\"SELECT * FROM xxx_post_posts WHERE sid='$sid'\");\n\t\tif(!$tiezi){\n\t\t\tDB::query(\"UPDATE xxx_post_log SET retry=retry+1 WHERE sid='$sid' AND date='$date'\");\n\t\t\tcontinue;\n\t\t}\n\t\t$x_content_count = DB::result_first(\"SELECT COUNT(*) FROM xxx_post_content WHERE uid='{$tiezi[uid]}'\");\n\t\t$x_content_offset = rand(1, $x_content_count) - 1;\n\t\t$x_content = DB::result_first(\"SELECT content FROM xxx_post_content WHERE uid='{$tiezi[uid]}' limit $x_content_offset,1\");\n\t\tlist($statue,$result) = client_rppost($tiezi['uid'],$tiezi,$x_content);\n\t\tif($statue == 2){\n\t\t\t$x_delay=DB::result_first(\"select delay from xxx_post_setting where uid={$tiezi[uid]}\");\n\t\t\tif($x_delay){\n\t\t\t\t$runtime=TIMESTAMP+$x_delay*56;\n\t\t\t\tDB::query(\"UPDATE xxx_post_setting SET runtime=$runtime WHERE uid='{$tiezi[uid]}'\");\n\t\t\t}\n\t\t\tDB::query(\"UPDATE xxx_post_log SET status=status+1 WHERE sid='$sid' AND date='$date'\");\n\t\t}else if($statue==1||$statue==8) DB::query(\"UPDATE xxx_post_log SET retry=60 WHERE sid='$sid' AND date='$date'\");\n\t\telse if($statue==5||$statue==7) continue;\n\t\telse DB::query(\"UPDATE xxx_post_log SET retry=retry+1 WHERE sid='$sid' AND date='$date'\");\n\t\tif(!defined('SIGN_LOOP')) break;\n\t\tsleep(1);\n\t\t}\n}else{\n\t\tcron_set_nextrun($tomorrow + 5400);\n}"
  },
  {
    "path": "plugins/xxx_post/core.php",
    "content": "<?php\nif (! defined ( 'IN_KKFRAME' ))\texit ();\nfunction get_random_content(){\n\t$text=<<<EOF\n有的人认为坚持会让我们变得更强大，但有时候放手也会。\n你若想要得到，就别只是期望。人生短暂，经不起等待。\n如果觉得生活是一种刁难，一开始就输了。如果觉得刁难是一种雕刻，迟早都会赢的。\n你不可能经由一个没有喜悦的旅程，而达到一个喜悦的终点。不管此刻，你追求的是什么，希望你能在过程中保持一颗喜悦的心，那么你所向往的东西，就会更不费力地来到你的生命中。\n为了爱，失恋是必要的；为了光明，黑暗是必要的。\n好夫妻的十大经典表现：恋爱时，彼此是崇拜者；交谈时，彼此是知音；得意时，彼此是吹牛对象；生气时，彼此是出气筒；困难时，彼此是咨询师；痛苦时，彼此是安慰者；病时，彼此是护理；老时，彼此是拐杖；平时，彼此各干各，保持适度距离。\n你超过别人一点点，别人会嫉妒你；当你超过别人一大截，别人就会羡慕你。\n当你了解人性，你也许就能够原谅所有的自私和软弱、所有的谎言与背叛。弗洛依德说，人的内心，既求生，也求死。我们追逐光明，却也追逐黑暗，我们那么想要得到爱，有时候却又近乎自毁地浪掷手中的爱……人心中似乎一直也有一片荒芜的夜地，留给那个寂寞也幽暗的自我。——杨澜\n有些事，我们总是弄不懂；有些人，我们总是猜不透；有些道，我们总是悟不尽；有些理，我们总是想不通；有些坎，我们总是跨不过；有些伤，我们总是治不好；有些天，我们总是睡不着；有些情，我们总是说不出；有些爱，我们总是得不到。对不起，那些回不去的曾经。\n为什么我们总是不懂得珍惜眼前人？在未可预知的重逢里，我们以为总会重逢，总会有缘再会，总以为有机会说一声对不起，却从没想过每一次挥手道别，都可能是诀别，每一声叹息，都可能是人间最后的一声叹息。\n勇敢，那是一个人年轻时唯一拥有的东西。在一次次的错误中成长，将所有看似错误的选择最终引导向正确的结果。我坚信，人应该有力量，揪着自己的头发把自己从泥地里拔起来。——廖一梅《像我这样笨拙地生活》\n忘掉岁月，忘掉痛苦，忘掉你的坏，我们永不永不说再见。\n当你打算放弃梦想时，告诉自己再多撑一天、一个星期、一个月，再多撑一年吧。你会发现，拒绝退场的结果令人惊讶。\n有时候你习惯了我的某个样子，当我变成另外一个样子的时候，你会觉得我变了，不再是之前的我了。其实，那只是你还不够了解我罢了。\n你还是一个人，偶尔会孤单偶尔会难受会想有个人拥抱，所以你还是在等。没关系，你一定会等到的。你一定要相信，那个人也在经历了很多之后在找你。你要做的，就是好好照顾自己，让自己在最好的状态里，遇到最好的他。\n暧昧，如同度的水，将沸未沸，发着低烧，表外波澜不惊，内部却暗流汹涌。友情以上，恋人未满的状态，在一段时期内，或许会带来模糊朦胧的美感，但是似浓似淡，时好时坏，患得患失的无望爱情，久了，相互喂养的蜜糖就可能变成有害身心健康的砒霜。\n忘记那个人，不如忘记自己。告诉自己，不是怕他忘记，而是怕他有一天重新把你想起。岁月带走的是记忆，但回忆会越来越清晰。真的有一天，他回过头来告诉你，他一直在惦记你，千万不要相信，因为，他已经不是原来的他，而你，也不再是过去的你。\n时间回不到开始的地方：对于已经错过的一些东西，或许不用再试着去挽留，错了就错了。对于得到，我们都应该充满感激，对于失去，谁能保证那本该是属于你的？有些东西原本就是让你牵挂，而不是获取的。难忘的人会忘，做过的梦成真，期待过去实现，走过的路让自己强壮，珍惜因果，顺乎自然。\n过去的一页，能不翻就不要翻，翻落了灰尘会迷了双眼。有些人说不出哪里好，但就是谁都替代不了！那些以前说着永不分离的人，早已经散落在天涯了。收拾起心情，继续走吧，错过花，你将收获雨，错过这一个，你才会遇到下一个。\n当一个人最看重的东西是面子，那他为此失去的一定很多。\n人可以拒绝任何东西，但绝对不可以拒绝成熟。拒绝成熟，实际上就是在规避问题、逃避痛苦。规避问题和逃避痛苦的趋向，是人类心理疾病的根源，不及时处理，你就会为此付出沉重的代价，承受更大的痛苦。\n能耐得住寂寞的人，肯定是有思想的人；能忍受孤独的人，肯定是有理想的人；遇事能屈能伸的人，肯定是有胸怀的人；处事从容不迫的人，肯定是个淡定的人；经常微笑的人，肯定是有头脑的人；看透天下事的人，肯定是个有智慧的人。\n如果，年华不曾老去，我不愿以清绝的姿态，总以忧伤示人，每当狂欢响起，而我总会念着谢幕，念着残缺。如果，年华不曾老去，我不愿再坐等年轮一圈圈卷起，不会让友情与爱情，以沧桑的名义在身旁悄悄地溜走，而是耗尽此生时光，用最温暖的文字为爱写歌，为情谱曲。\n不论什么时候开始，重要的是开始之后就不要停止。不论什么时候结束，重要的是结束之后就不要悔恨。\n无缘何生斯世，有情能累此生。\n知音，能有一个已经很好了，不必太多。如果实在没有，还有自己。好好对待自己，跟自己相处，也是一个朋友。\n世界上有两个我，一个假装快乐，一个真心难过。\n真正的自信不是表现给别人看的，而是无意当中散发出来的。自信来自于哪里，对于我来说，自信来自于自己对于工作的把握，对于生活的把握。当自己面对不同的人，不同的环境的时候，我知道不需要担心自己。——闾丘露薇\n我们来到这个世上，每个人都背着一个空篓子，而人的一生，就是不断地往自己的篓子里放东西的过程。如果有了，就想更多，贪得无厌，欲壑难填。只做加法的人生是很悲哀的，远离名利，看淡成败，安于淡泊就是做减法。减去多余的物质，减去奢侈的欲望，减去心灵的负担。加减法并用，人生之旅才会风光无限。\n一辈子那么长，一天没走到终点，你就一天不知道哪一个才是陪你走到最后的人。有时你遇到了一个人，以为就是他了，后来回头看，其实他也不过是这一段路给了你想要的东西。\n走到生命的哪一个阶段，都该喜欢那一段时光，完成那一阶段该完成的职责，顺生而行，不沉迷过去，不狂热地期待着未来，生命这样就好。不管正经历着怎样的挣扎与挑战，或许我们都只有一个选择：虽然痛苦，却依然要快乐，并相信未来。\n谦和、温顺且自持的生活，不乱于心，不困于情，不畏将来，不念过去。\n我要的，不是短暂的温柔，而是一生的守候。\n当爱一个人，却无法拥有他时，自己面对着一个选择：放弃还是继续。包括你在内的很多人都说：放弃吧，不要再浪费青春。但是，自己却明白，自己真的放不下。如果能放下，早都已经放下了，根本不会到现在的地步。所以，当黑夜来临的时候，我只能孤独的思念一个人。\n茫茫人海，没有人不喜欢幸福的，没有人不期待幸福的，没有人不向往幸福的。但不同的时代有着不同的理解，不同的阶层有着不同的看法，不同的年龄有着不同的要求。无论怎么不同，有一点却是相同的，那就是幸福降临的时候，会感到比美妙更美妙，比快乐更快乐，总会激动不已甚至泪流满面。\n请把你的心给我，与我为伍，这个世界太残酷了，我有些害怕。\n没有一百分的另一半，只有五十分的两个人。\n命中有很多事情足以把你打倒，但真正能把你打倒的是你的心态。\n你喜欢的人也喜欢你，你想念的人也正在想念你。这就是全世界最重要的事情，拿什么都不能换。\n最好的年龄是，那一天，你终于知道并且坚信自己有多好，不是虚张，不是夸浮，不是众人捧，是内心明明澈澈知道：是的，我就是这么好。\n妈妈说只要我乖乖认错，就会再拉住我的手；你说不是有的时候认错，就能够让我们再次牵手。亲人总会原谅，因为你是他们的孩子；爱人总难原谅，因为我们都是孩子。\n分手之后，不用觉得那些曾经的恩爱是耳光，不用觉得那些说过的誓言多苍白，也不用去喊什么低调的幸福才能长久，至少在当时当地，它们都是出自真心。这所有的东西，都值得珍藏，你的青春没有白费。\n刚好处在这个尴尬的年龄，开始关心爸妈，却不愿说出口；想多陪陪爸妈，却更贪恋坐在电脑前；知道爸妈想和自己说话，却不知道他们的话题要怎么接；看得到爸妈在变老，却仍不耐烦他们的过时。心里时时刻刻在愧疚，却依然带给他们落寞。\n她没有见过阴云，她的眼睛是晴空的颜色。她永远看着我，永远，看着，绝不会忽然掉过头去。\n不论是自转还是公转，涨潮还是退潮；不论是暖流改变气温带来鱼群，或者海水淹没岛屿失去踪迹；不论是我的世界车水马龙繁华盛世，还是它们都瞬间消失化为须臾；我都会坚定地走向你，不迷惑，不慌张，不犹豫。\n谁都以为自己会是例外——在后悔之外。谁都以为拥有的感情也是例外——在变淡之外。谁都以为恋爱的对象刚巧也是例外——在改变之外。然而最终发现——除了变化，无一例外。\n星云大师：口袋没钱，心里没钱，轻松一辈子；口袋有钱，心里有钱，劳累一辈子；口袋没钱，心里有钱，痛苦一辈子；口袋有钱，心里没钱，快乐一辈子。\n人生是一种选择，亦是一种放弃。能自由选择的人是幸福的，能适度放弃的心是洒脱的。可惜，有时我们的选择，只有等待，没有结果，只能黯然离开；有时我们的放弃，迫于无奈，含泪转身，走远了依旧频频地回望。\n不知不觉，是这世上最可怕的力量。\n温暖在你心里，只是你自己还没有发现它。\n当我们感到幸福的时候，何必去想这幸福是永恒的，还是暂时的。忧虑，是幸福最大的敌人。\n给自己的三句话：一、年轻，什么都还来得及；二、不要纠缠于小事；三、你现在遇到的事都是小事。\n执子之手，共度此生——曾经以为所有的爱情都一定要惊天动地；曾经以为每个人的爱情都一定要轰轰烈烈；曾经以为所有的爱情都有花前月下，海誓山盟；曾经无限向往九千九百九十九朵玫瑰的浪漫……然而平平淡淡同样震撼人心，执手之时，冷暖两心知；执手之时，悲喜两忘。\n恐惧就是这样一个懦夫，当你触及他的底线，接受事情最坏的结果，然后开始准备和它大干一场的时候，它早就不知道躲到哪里去了。\n爱情不是学问，不用学习，若果爱一个人，发自内心，难以遮掩，自然而然以他为重，这是种本能，不费吹灰之力。\n曾经，你苦苦以为，没有了这个人，也就活不成了，到了后来，不是活得好好的吗？一个不爱你的人，决不会比你的生命重要；一个爱你的人，会告诉你，你的生命比你对他的爱情重要。\n“归属感”是你强烈地想和他在一起，“安全感”是你觉得他强烈地想和你在一起。\n人生总要经历很多，有些人无法羽化成铭记，有些事无法沉淀为回忆。对于一些伤痛的人与事，要学会走过了就要淡漠，转身了就要遗忘，唯有如此，我们的行囊才不会太沉重，我们的身心才不会太疲乏。相聚是短暂的，分别会是永远的，没有人能是你永恒的挂牵，任何事都不要成为你所有的渴盼。\n人的一生很像是在雾中行走；远远望去，只是迷蒙一片，辨不出方向和吉凶。可是，当你鼓起勇气，放下忧惧和怀疑，一步一步向前走去的时候，你就会发现，每走一步，你都能把下一步路看得清楚一点。“往前走，别站在远远的地方观望！”你就可以找到你的方向。\n爱就是，无论你怎么抵挡，它还是要来的东西。爱就是，无论你怎么诋毁，它还是高尚的东西。\n洒脱是人生的一种境界。洒脱不是无所事事、不思进取，也不是看破红尘、心灰意冷，更不是声色犬马、纸醉金迷。洒脱是一种世事洞明的豁达，一种淡泊名利的超脱，一种有所为有所不为的风度。洒脱不是放弃，而是放下，放下不切实际的幻想，放下无法更改的过去，行云流水，任其所之。\n每棵大树，都曾只是一粒种子。\n人累了，就休息；心累了，就淡定。长大了，成熟了，这个社会就看透了。累了，难过了，就蹲下来，给自己一个拥抱。因为这个世界上没有人能同情你，怜悯你。你哭了，眼泪是自己的；你痛了，没有人能体会到。你一定要坚强，即使受过伤，流过泪，也能咬牙走下去。因为，人生，其实只是你一个人的人生。\n和错误的人在一起，就好比穿了双不合脚的鞋，即使鞋子再美，最终伤到的还是自己。\n每天告诉自己：再难也要坚持，再好也要淡泊，再差也要自信，再多也要节省，再冷也要热情。\n人心总有压抑的时候，爱情也是很沉重的一回事。但是，可以想想父母兄弟，夜里抬头看看星月。上帝造这世界，并非叫每个人只为爱情活着。为太阳月亮又有何不可，吸两口空气，低潮就过去了。三十年后，想起为爱情萌生死念，会觉得可笑。——亦舒\n人生，都有“艰难”这个副产品，却也有时间这副良药，将不幸变成有幸，是生活给我们最好的礼物。\n这世界上没有未完成的故事，只有未死的心。在两个人的情感对弈中，最后动心的未必是赢家；而最后死心的，则必定是输家。\n别人站得远，我们就走近，距离便会缩小；别人若冷漠，我们待以热情，就会逐渐热络。惟有主动付出，才有丰富的果实获得收获。用微笑面对人生，也要面对自己的悲伤与痛苦，我们能面对悲伤，就是因为心中有信念。没有什么事难得到自己的，坚信光芒，铭记于心。\n我们都不会轻易的活在这个世界上，要知道，我们能来到这个世上是多大的一个奇迹。\n别人的男友再好，不过是奢侈品，自己的男友再差，却是必需品。不是非常之爱，没人甘愿做替代品。不是非常之恋，没人甘心当必需品。奢侈品是一种奢望，必需品是一种必须，在奢侈品与必需品之间，最缺的就是一颗平常心。\n别让自己活得太累。应该学着想开、看淡，学着不强求，学着深藏。适时放松自己，寻找宣泄，给疲惫的心灵解解压。人之所以会烦恼，就是记性太好，记住了那些不该记住的东西。所以，记住快乐的事，忘记令你悲伤的事。\n不论你生活在何处，和爱遇见了，就打个招呼；相逢了，就给个拥抱；分手了，就说句再见。不纠缠，不厌世，不对爱情恶言相向。\n我们因彼此懂得而惺惺相惜；我们因惺惺相惜而心念相应；我们因心念相应而无视距离。我们不能没有期望，没有梦想，没有依托；我们也不能没有朋友，没有理解，没有认同，总是一个人走过漫漫的人生苦旅。不管我们相隔多远，我们都能感到彼此的每一次心跳，我们用心和微笑把彼此的距离拉到最近\n小的时候，每个孩子都会给父母许下诺言：长大了，我要带你们如何如何……渐渐长大了，渐渐离父母越来越远，渐渐忙得喘不过气了……忽然有一日，恍过神来，发现父母已是满头银发。他们的腰被岁月压弯了；他们脚步蹒跚，再也不能随你去看山望水；他们甚至失去记忆，再也听不清你说的那些甜言蜜语……\n有时候你必须跳出“窗外”，然后在坠落的过程中长出“翅膀”。\n宝贝，请记住：你必须坚强，没有人会懂得你到底有多痛。你必须坚强，没有人会懂你到底要怎么继续生活下去。你必须坚强，没有人知道你经历了怎么样的生活。你必须坚强，没有人知道你微笑背后所隐藏的伤痛。你必须坚强，没有人知道你在想哭的时候却发现原来早已没有了眼泪。你若不坚强，谁替你勇敢。\n一个人久了，对爱情会越挑剔；一个人久了，会变的比恋爱时候成熟；一个人久了，朋友会越重要；一个人久了，会越来越喜欢听歌；一个人久了，对节日大多没啥期待。一个人久了，因为怕伤害，懒得去恋爱，懒得去了解人。\n真心怀念高中了。每天穿着校服到处乱蹭。男生上课用手机看文字直播的NBA。下课走廊里闹哄哄的。厕所也要排队。最恨老师抱着卷子进班。有总是第一的书呆子也有隐藏在最后一排的神吐槽的大神。我也怀念那时候的我。因为一切都看起来那么有希望。好像只要努力，什么都能改变\n生命本是一次旅行，在每一次停泊时都要清理自己的口袋，把更多的位置空出来，让自己活得更轻松、更自在。心无杂物，才会有满心室的暖暖阳光，才会有从容生活轻松涉世的自信和勇气。只有拥有一颗空灵的心，才能注入快乐，注入幸福。\n现在要一份纯粹的爱情，很难。放不下骄傲，放不下身段，参杂太多人太多事，彼此撑着，最后以“爱不起”、“不适合”收场。陪我们走到最后的人，也许算不上是我们最爱的，但会是最合适的。这样也很好，不是吗？人生本不完美，也许懂得知足。年轻就是这样，有错过有遗憾，最后才会学着珍惜\n爱情里最忌讳的就是：两人都幻想着彼此的未来，却也总惦记着对方的过去。\n伤心最大的建设性，在于明白，那颗心还在老地方。\n深的话要浅浅地说，长长的路要挥霍地走。大大的世界要率真地感受，会痛的伤口要轻轻地揉。\n《老男孩》和《那些年我们一起追过的女孩》告诉我们一个事实：也许现在你们很相爱，但是如果你们现在不努力的话，到最后陪她结婚的人一定不是你！现实并不残酷，残酷的是你自己对青春的挥霍！以后的结果都是由你自己制造的，爱一个人不是每天的甜言蜜语，而是每天的发奋图强！\n有时候，你难免多心。心眼一多，许多小事就跟着过敏，于是别人多看你一眼，你便觉得他对你有敌意；少看你一眼，你又认定他故意对你冷落。多心的人注定活得辛苦，因为太容易被别人的情绪所左右。多心的人总是胡思乱想，结果是困在一团乱麻般的思绪中，动弹不得。有时候，与其多心，不如少根筋。\n第一次的爱，始终无法轻描淡写。我对你，只有放弃，没有忘记。站在心碎的地方，轻轻打一个结，一种缝补，阻止伤痛再流出。在这个城市，做一道路过的风景，做一次匆匆的过客，只为了一个人。也许有一天，你回头了，而我却早已，不在那个路口。\n即使不见面，不说话，不发信息，我也会在心里留一个位置，安安稳稳的放着一个人。\n我相信，爱可以排除万难。只是，万难之后，又有万难，这是我更相信的。\n男生没有主动找女生，那是说明他是真的不想理她了。女生没有主动找男生，是因为在等他找她。\n当一个人不爱你要离开你时，你要问自己还爱不爱他，千万别为了可怜的自尊而不肯离开。等到天放晴的时候，你就会遇到一个能让你好好再爱一次的人。\n不要相信日韩肥皂剧中所谓的因为不能让彼此幸福而离开。是否想过，你们正是对方的幸福。爱不是逃避，是努力。不是逃避着给彼此幸福的责任，而是努力的实现让彼此幸福的义务。当你说离开是为了不让对方受到伤害的时候，你已经给对方造成了最大的伤害。爱就是要努力在一起。\n有时候，你爱上的那个人，是会完全打破你一直以来的标准。从世俗的眼光看来，他也许不是那么标准；然而，乍然相逢的一刻，他翩翩的身影却在你眼里开出了翻翻腾腾的花。突然之间，世间的标准都可以抛弃，他凌驾了一切的标准。\n不要因为害怕彼此离开而体谅。体谅是因为爱，而不是因为恐惧。爱是一种责任，不可以轻易的离开。让你为离开而恐惧的人，算不上爱人，就算付出再多，要离开的人，终究是会离开。\n忘了有多久，习惯对朋友说都好都好，却对陌生人坦白自己的心事。\n人生就像一杯没有加糖的咖啡，喝起来是苦涩的，回味起来却有久久不会退去的余香；人生就是一场旅行，不在乎目的地，在乎的是沿途的风景以及看风景的心情；人生就是一条坎坷曲折的路，即使不断的跌倒，也一定要爬起来，坚持自己的梦想。记住，这一秒不放弃，下一秒就会有希望。\n一句我等你，不知道需要多大的勇气。它远比我爱你三个字，更需要勇气。不是每个人你都愿意等待，也不是所有人都值得你去等待。一句我等你，包含了很多的无奈，心酸，苦涩。或许是爱不到，或许是不能爱，无论怎样，我等你这个承诺，远比我爱你更动听。可是，有多少的爱情经得起等待？\n做一个安静细微的人，于角落里自在开放，默默悦人，却始终不引起过分热闹的关注，保有独立而随意的品格，这就很好。\n过去的事，不后悔；将来的事，不害怕。对于那些应经发生的事，要坦然接受，无论它对你产生的不利影响有多大，它都已经发生了。人生是一场一个人的旅程，无人可替代。总有人离开，总有人到来。\nEOF;\n\t$contents=explode(\"\\n\", $text);\n\t$content=$contents[array_rand($contents)];\n\treturn $content;\n}\n\nfunction get_random_tid($tieba){\n\t$ch = curl_init ('http://tieba.baidu.com/f?kw='.urlencode(iconv('utf-8', 'gbk', $tieba)).'&fr=index');\n\tcurl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );\n\t$contents = curl_exec ( $ch );\n\tcurl_close ( $ch );\n\tpreg_match_all('/<li class=\"j_thread_list[A-z0-9 -_]+\" +data-field=\\'{(?<json>[A-z0-9 -_]+?)}\\'/', $contents, $jsontids);\n\tforeach ($jsontids['json'] as $jsontid){\n\t\t$jsontid=str_replace('&quot;','\"', '{'.$jsontid.'}');\n\t\tif($tids[]=json_decode($jsontid)->is_top == 0)\n\t\t   $tids[]=json_decode($jsontid)->id;\n\t}\n\t$tid=$tids[rand(0,count($tids)-1)];\n\treturn $tid;\n}\n\n\nfunction client_rppost($uid, $tieba, $content) {\n\t$cookie = get_cookie ( $uid );\n\tpreg_match ( '/BDUSS=([^ ;]+);/i', $cookie, $matches );\n\t$BDUSS = trim ( $matches [1] );\n\t$setting = DB::fetch_first ( \"SELECT * FROM xxx_post_setting WHERE uid='{$uid}'\" );\n\tif ($setting ['client_type'] == 5)\n\t\t$setting ['client_type'] = rand ( 1, 4 );\n\tif (! $BDUSS) return array (- 1,'找不到 BDUSS Cookie' );\n\tif (! $content) $content=get_random_content();\n\tif (! $tieba['tid']) $tieba['tid']=get_random_tid($tieba ['name']);\n\t$formdata = array (\n\t\t\t'BDUSS' => $BDUSS,\n\t\t\t'_client_id' => 'wappc_136' . random ( 10, true ) . '_' . random ( 3, true ),\n\t\t\t'_client_type' => $setting ['client_type'],\n\t\t\t'_client_version' => '5.0.0',\n\t\t\t'_phone_imei' => md5 ( random ( 16 ) ),\n\t\t\t'anonymous' => 0,\n\t\t\t'content' => $content,\n\t\t\t'fid' => $tieba ['fid'],\n\t\t\t'kw' => urldecode ( $tieba ['name'] ),\n\t\t\t'net_type' => 3,\n\t\t\t'tbs' => get_tbs ( $tieba ['uid'] ),\n\t\t\t'tid' => $tieba ['tid'],\n\t\t\t'title' => \"\"\n\t);\n\t$adddata = '';\n\tforeach ( $formdata as $k => $v )\n\t\t$adddata .= $k . '=' . $v;\n\t$sign = strtoupper ( md5 ( $adddata . 'tiebaclient!!!' ) );\n\t$formdata ['sign'] = $sign;\n\t$ch = curl_init ( 'http://c.tieba.baidu.com/c/c/post/add' );\n\tcurl_setopt ( $ch, CURLOPT_HTTPHEADER, array (\n\t\t\t'Content-Type: application/x-www-form-urlencoded'\n\t) );\n\tcurl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );\n\tcurl_setopt ( $ch, CURLOPT_COOKIE, $cookie );\n\tcurl_setopt ( $ch, CURLOPT_POST, true );\n\tcurl_setopt ( $ch, CURLOPT_POSTFIELDS, http_build_query ( $formdata ) );\n\t$re = @json_decode ( curl_exec ( $ch ), ture );\n\tcurl_close ( $ch );\n\tswitch ($setting ['client_type']) {\n\t\tcase '1' :\n\t\t\t$client_res = \"iphone\";\n\t\t\tbreak;\n\t\tcase '2' :\n\t\t\t$client_res = \"android\";\n\t\t\tbreak;\n\t\tcase '3' :\n\t\t\t$client_res = \"WindowsPhone\";\n\t\t\tbreak;\n\t\tcase '4' :\n\t\t\t$client_res = \"Windows8\";\n\t\t\tbreak;\n\t}\n\tif (!$re) return array (0,'JSON 解析错误' );\n\tif ($re ['error_code'] == 0) return array (2,\"使用\" . $client_res . '客户端发帖成功，<a href=\"http://tieba.baidu.com/p/' . $tieba ['tid'] . '\" target=\"_blank\">查看帖子</a>');\n\telse if ($re ['error_code'] == 5) return array (5,\"需要输入验证码，请检查你是否已经关注该贴吧。\" \t);\n\telse if ($re ['error_code'] == 7) return array (7,\"您的操作太频繁了！\" );\n\telse if ($re ['error_code'] == 8) return array (8,\"您已经被封禁\" );\n\telse return array($re ['error_code'],\"未知错误，错误代码：\" . $re ['error_code']);\n}\n\n?>\n"
  },
  {
    "path": "plugins/xxx_post/index.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied!');\ninclude 'plugins/xxx_post/core.php';\n$obj = $_PLUGIN['obj']['xxx_post'];\n?>\n<style type=\"text/css\">\n.small_gray{color:#757575;font-size:12px;}\n.small_gray_i{color:#B1B1B1;font-size:12px;font-style:italic;margin:0 0 2em 0;}\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n  list-style: none;\n  padding: 0;\n  margin: 0 0 20px 0;\n  height:31px\n}\n.nav-tabs > li {\n  margin-bottom: -1px;float: left;  line-height: 20px;\n}\n.nav-tabs > li > a:hover,\n.nav-tabs > li > a:focus {\n  border-color: #eeeeee #eeeeee #dddddd;\n  cursor:pointer;\n}\n.nav-tabs > .active > a,\n.nav-tabs > .active > a:hover,\n.nav-tabs > .active > a:focus {\n  color: #555555;\n  cursor: default;\n  background-color: #ffffff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n}\n.nav-tabs > li > a {\n  padding: 8px 12px 8px 12px;\n  display: block;\n  margin-right: 2px;\n  line-height: 14px;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover,\n.nav-tabs > li > a:focus {\n  border-color: #eeeeee #eeeeee #dddddd;\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n.nav-tabs:before,\n.nav-tabs:after{\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n.nav-tabs:after{\n  clear: both;\n}\ntable.x_table thead tr{background-color:#dedede;}\n</style>\n\n<h2>客户端回帖</h2>\n<p class=\"small_gray\">当前插件版本：0.3.1 | 更新日期：14-04-29 | Designed By <a href=\"http://tieba.baidu.com/home/main?un=%D0%C7%CF%D2%D1%A9&fr=index\" target=\"_blank\">@星弦雪</a></p>\n<p class=\"small_gray_i\"><?php echo '——'.get_random_content();?>\n<div>\n\t<ul class=\"nav-tabs\">\n\t\t<li class=\"active\"><a>设置</a></li><li><a>记录</a></li><li><a>帮助</a></li>\n\t</ul>\n</div>\n\n<div class=\"x_tab_content\">\n\n<div>\n\t<h3>常规</h3>\n\t<form method=\"post\" id=\"xxx_post_settings\"\n\t\taction=\"plugin.php?id=xxx_post&action=set-settings\"\n\t\tonsubmit=\"return post_win(this.action, this.id)\">\n\t\t<p>\n\t\t\t客户端类型：\n\t\t<select name=\"x_p_client_type\" id=\"x_p_client_type\" disabled>\n\t\t  <option value=\"1\">iPhone</option>\n\t\t  <option value=\"2\">Android</option>\n\t\t  <option value=\"3\">Windows Phone</option>\n\t\t  <option value=\"4\">Windows 8</option>\n\t\t  <option value=\"5\">随机选择一种</option>\n\t\t</select>\n\t\t</p>\n\t\t<p>回帖频率：\n\t\t<select name=\"x_p_frequency\" id=\"x_p_frequency\" disabled>\n\t\t  <option value=\"2\">每天回一次</option>\n\t\t  <option value=\"1\">早晚各回一次</option>\n\t\t\t<?php if ($obj->getSetting ( 'sxbk' ) == 1) echo '<option value=\"4\">极限刷帖</option>'; ?>\n\t\t</select>\n\t\t，<span id=\"x_p_runtimes_hide\">每次回\n\t\t<input type=\"number\" name=\"x_p_runtimes\" id=\"x_p_runtimes\" min=\"1\" max=\"<?php echo $obj->getSetting('max_runtime', 6); ?>\" disabled>\n\t\t贴(最多为<?php echo $obj->getSetting('max_runtime', 6); ?>)，</span>发出一贴后等待\n\t\t<input type=\"number\" name=\"x_p_delay\" id=\"x_p_delay\" min=\"0\" max=\"15\" disabled>\n\t\t分钟再发下一帖</p>\n\t\t<p><input type=\"submit\" value=\"保存设置\"></p>\n\t</form>\n\t<br>\n\t<h3>测试</h3>\n\t<p>随机选取一个帖子，进行一次回帖测试，检查你的设置有没有问题</p>\n\t<p><a href=\"plugin.php?id=xxx_post&action=test_post\" class=\"btn\"\tonclick=\"return msg_win_action(this.href)\">测试回帖</a></p>\n<br>\n<h3>添加需要回的帖子</h3>\n<table class=\"x_table\">\n\t<thead><tr><td style=\"width:20px\">序号</td><td>贴吧</td><td>贴子</td><td style=\"width: 20%\">操作</td></tr></thead>\n\t<tbody id=\"xxx_post_show\">\n\t\t<tr><td colspan=\"4\"><img src=\"./template/default/style/loading.gif\">载入中请稍后</td></tr>\n\t</tbody>\n</table>\n<p>\n\t<a class=\"btn\" id=\"xxx_post_add_tid\">添加贴子</a>\n\t<a class=\"btn\" id=\"x_p_add_tb\"\tstyle=\"margin-left: 5px\">添加贴吧</a>\n\t<a class=\"btn\" id=\"x_p_del_tid\"\tstyle=\"margin-left: 5px\">全部删除</a>\n</p>\n<br>\n<h3>添加回帖内容</h3><p>回帖时随机使用其中之一，不添加的话会使用系统内置的</p>\n<table class=\"x_table\">\n\t<thead><tr><td style=\"width: 20px\">序号</td><td>回帖内容</td><td style=\"width: 20%\">操作</td></tr></thead>\n\t<tbody id=\"xxx_post_contents\"><tr><td colspan=\"4\"><img src=\"./template/default/style/loading.gif\">载入中请稍后</td></tr></tbody>\n</table>\n<p>\n\t<a class=\"btn\" id=\"xxx_post_add_content\">添加内容</a>\n\t<a class=\"btn\" id=\"x_p_add_con\"\tstyle=\"margin-left: 5px\">批量添加</a>\n\t<a class=\"btn\" id=\"x_p_del_con\"\tstyle=\"margin-left: 5px\">全部删除</a>\n</p>\n</div>\n\n\n<div>\n<h2 id=\"x_p_post_log_tite\">当天的回帖记录</h2>\n<p>如果帖子已从回帖列表删除，则不会在这里显示</p>\n<p id=\"x_p_pager_text\"></p>\n<table class=\"x_table\">\n\t<thead><tr><td style=\"width: 20px\">序号</td><td>贴吧</td><td>贴子</td><td style=\"width: 20px\">成功</td><td style=\"width: 20px\">失败</td></tr></thead>\n\t<tbody id=\"x_p_log_tab\"><tr><td colspan=\"5\">载入中请稍后</td></tr></tbody>\n</table>\n</div>\n\n<div>\n\t<p>使用该插件需做好每日被永封的准备，因发帖插件导致的账号被封、被屏蔽，请使用者自行承担后果</p>\n\t<h2>关于封禁与解封</h2>\n\t<p>其实解封很简单的= =（作者表示已经被永封过无数次）</p>\n\t<p>如果被度受永封的话：</p>\n\t<p>1.绑定手机秒解</p>\n\t<p>2.申请人工解封的话，只要你不是丧心病狂地每分钟一贴，一般都可以通过</p>\n\t<p>如果被吧务封禁的话，只好找吧务承认错误并表示永不再犯= =（不过在官方水楼里刷的话应该吧务不会插手）</p>\n</div>\n</div>"
  },
  {
    "path": "plugins/xxx_post/main.js",
    "content": "$(\"#menu_xxx_post-index\").click(function (){\n\tif($(\".nav-tabs >.active\").index()==0) {load_post_set();load_post_adv_set();}\n\telse if($(\".nav-tabs >.active\").index()==1) load_post_log();\n});\n$('#x_p_frequency').change(function(){\n\tif($('#x_p_frequency').val()==4) $(\"#x_p_runtimes_hide\").fadeOut(\"slow\");\n\telse $(\"#x_p_runtimes_hide\").fadeIn(\"slow\");\n});\n$(\"#xxx_post_add_tid\").click(function(){\n\tcreateWindow().setTitle(\"添加帖子\").setContent('<p>你可以指定帖子进行回复</p><p>请输入帖子的地址:</p><p>例如:http://tieba.baidu.com/p/2692275116</p><form method=\"get\" action=\"plugin.php?id=xxx_post&action=get-tid\" id=\"xxx_post_tid_form\" onsubmit=\"return post_win(this.action, this.id,x_reload)\"><input type=\"text\" id=\"xxx_post_tid\" name=\"xxx_post_tid\" style=\"width:90%\"/></form>').addButton(\"确定\", function(){ $('#xxx_post_tid_form').submit(); }).addCloseButton(\"取消\").append();\n\t});\n$(\"#x_p_add_tb\").click(function(){\n\tcreateWindow().setTitle(\"添加帖吧\").setContent('<p>你可以只指定贴吧，并从该贴吧首页随机选择帖子进行回复</p><p>请输入帖吧的名字（不要带“吧”字）:</p><p>例如:要添加chrome吧，请输入chrome</p><form method=\"get\" action=\"plugin.php?id=xxx_post&action=add-tieba\" id=\"xxx_post_add_tb_form\" onsubmit=\"return post_win(this.action, this.id,x_reload)\"><input type=\"text\" id=\"xxx_post_add_tieba\" name=\"xxx_post_add_tieba\" list=\"autocomplete-tieba\" style=\"width:90%\"/></form>').addButton(\"确定\", function(){ $('#xxx_post_add_tb_form').submit(); }).addCloseButton(\"取消\").append();\n\t});\n$(\"#xxx_post_add_content\").click(function(){\n\tcreateWindow().setTitle(\"添加回帖内容\").setContent('<p>请输入要回复的内容（最多1000字符）:</p><form method=\"get\" action=\"plugin.php?id=xxx_post&action=set-content\" id=\"xxx_post_content_form\" onsubmit=\"return post_win(this.action, this.id,x_reload)\"><textarea name=\"post_content\" id=\"post_content\" rows=\"5\" style=\"width: 95%\"></textarea></form>').addButton(\"确定\", function(){ $('#xxx_post_content_form').submit(); }).addCloseButton(\"取消\").append();\n\t});\n$(\"#x_p_add_con\").click(function(){\n\tcreateWindow().setTitle(\"批量添加内容\").setContent('<p>请输入要回复的内容（每行算一条）:</p><form method=\"get\" action=\"plugin.php?id=xxx_post&action=set-cont-plus\" id=\"x_p_cont_form\" onsubmit=\"return post_win(this.action, this.id,x_reload)\"><textarea name=\"x_p_contant\" id=\"x_p_contant\" rows=\"8\" style=\"width: 95%\"></textarea></form>').addButton(\"确定\", function(){ $('#x_p_cont_form').submit(); }).addCloseButton(\"取消\").append();\n\t});\n$(\"#x_p_del_con\").click(function(){\n\tcreateWindow().setTitle(\"批量删除\").setContent('你确定要删除全部回复内容吗？').addButton(\"确定\", function(){msg_callback_action('plugin.php?id=xxx_post&action=del-all-cont',x_reload);}).addCloseButton(\"取消\").append();\n});\n$(\"#x_p_del_tid\").click(function(){\n\tcreateWindow().setTitle(\"批量删除\").setContent('你确定要删除全部贴子吗？').addButton(\"确定\", function(){msg_callback_action('plugin.php?id=xxx_post&action=del-all-tid',x_reload);}).addCloseButton(\"取消\").append();\n});\n$(\".x_tab_content>div\").each(function(i){\n\t$(this).addClass(\"x_tab_content_\"+i);\n\tif(i!=0) $(this).hide();\n});\n$(\".nav-tabs >li>a\").click(function(){\n\tif($(this).parent().hasClass(\"active\")) return 0;\n\telse{\n\t\t$(\".x_tab_content>.x_tab_content_\"+$(this).parent().siblings().filter(\".active\").index()).hide();\n\t\t$(this).parent().siblings().filter(\".active\").removeClass(\"active\");\n\t\t$(\".x_tab_content>.x_tab_content_\"+$(this).parent().index()).show();\n\t\t$(this).parent().addClass(\"active\");\n\t\tif($(this).parent().index()==0)  {load_post_set();load_post_adv_set();}\n\t\telse if($(this).parent().index()==1) load_post_log();\n\t}\n});\nfunction x_reload(){\n\tload_post_set();load_post_adv_set();\n}\nfunction load_post_set(){\n\tshowloading();\n\t$.getJSON(\"plugin.php?id=xxx_post&action=post-settings\", function(result){\n\t\tshow_post_set(result);\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取设置').addButton('确定', function(){ location.reload(); }).append(); }).always(function(){ hideloading(); });\n}\nfunction show_post_set(result){\n\t$('#xxx_post_show').html('');\n\t$('#xxx_post_contents').html('');\n\tif(result.count1){\n\t\t$.each(result.tiebas, function(i, field){\n\t\t$(\"#xxx_post_show\").append(\"<tr><td>\"+(i+1)+\"</td><td><a href=\\\"http://tieba.baidu.com/f?kw=\"+field.unicode_name+\"\\\" target=\\\"_blank\\\">\"+field.name+\"</a></td><td><a href=\\\"http://tieba.baidu.com/p/\"+field.tid+\"\\\" target=\\\"_blank\\\">\"+field.post_name+\"</a></td><td><a href=\\\"javascript:;\\\" onclick=\\\"return delsid('\"+field.sid+\"')\\\">删除</a></td></tr>\");\n\t});}else{\n\t\t$('#xxx_post_show').html('<tr><td colspan=\"4\">暂无记录</td></tr>');\n\t}\n\tif(result.count2){\n\t\t$.each(result.contents, function(i, field){\n\t\t$(\"#xxx_post_contents\").append(\"<tr><td>\"+(i+1)+\"</td><td>\"+field.content+\"</td><td><a href=\\\"javascript:;\\\" onclick=\\\"return delcont('\"+field.cid+\"')\\\">删除</a></td></tr>\");\n\t});}else{\n\t\t$('#xxx_post_contents').html('<tr><td colspan=\"3\">暂无记录</td></tr>');\n\t}\n}\nfunction load_post_adv_set(){\n\tshowloading();\n\t$.getJSON(\"plugin.php?id=xxx_post&action=post-adv-settings\", function(result){\n\t\t$('#x_p_client_type').val(result.settings.client_type).removeAttr('disabled');\n\t\t$('#x_p_frequency').val(result.settings.frequency).removeAttr('disabled');\n\t\t$('#x_p_delay').val(result.settings.delay).removeAttr('disabled');\n\t\t$('#x_p_runtimes').val(result.settings.runtimes).removeAttr('disabled');\n\t\tif(result.settings.frequency==4) $(\"#x_p_runtimes_hide\").hide();\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取设置').addButton('确定', function(){ location.reload(); }).append(); }).always(function(){ hideloading(); });\n}\nfunction load_post_log(){\n\tshowloading();\n\t$.getJSON(\"plugin.php?id=xxx_post&action=post-log\", function(result){\n\t\tshow_post_log(result);\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取回帖报告').addButton('确定', function(){ location.reload(); }).append(); }).always(function(){ hideloading(); });\n}\nfunction load_post_history(date){\n\tshowloading();\n\t$.getJSON(\"plugin.php?id=xxx_post&action=post-history&date=\"+date, function(result){\n\t\tshow_post_log(result);\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取签到报告').addButton('确定', function(){ location.reload(); }).append(); }).always(function(){ hideloading(); });\n}\nfunction show_post_log(result){\n\tif(!result || result.count == 0){\n\t\t$('#x_p_log_tab').html('<tr><td colspan=\"5\">暂无记录</td></tr>');\n\t\treturn;\n\t}\n\t$('#x_p_log_tab').html('');\n\t$('#x_p_post_log_tite').html(result.date+\" 回帖记录\");\n\t$.each(result.log, function(i, field){\n\t\t$(\"#x_p_log_tab\").append(\"<tr><td>\"+(i+1)+\"</td><td><a href=\\\"http://tieba.baidu.com/f?kw=\"+field.unicode_name+\"\\\" target=\\\"_blank\\\">\"+field.name+\"</a></td><td><a href=\\\"http://tieba.baidu.com/p/\"+field.tid+\"\\\" target=\\\"_blank\\\">\"+field.post_name+\"</a></td><td>\"+field.status+\"</td><td>\"+field.retry+\"</td></tr>\");\n\t});\n\tvar pager_text = '';\n\tif(result.before_date) pager_text += '<a class=\"btn\" onclick=\"return load_post_history('+result.before_date+')\">&laquo; 前一天</a>';\n\tpager_text += '<a class=\"btn\" onclick=\"load_post_log()\">今天</a>';\n\tif(result.after_date) pager_text += '<a class=\"btn\" onclick=\"return load_post_history('+result.after_date+')\">后一天 &raquo;</a>';\n\t$('#x_p_pager_text').html(pager_text);\n}\nfunction delsid(sid){\n\tcreateWindow().setTitle('删除帖子').setContent('确认要删除这个帖子的自动回复吗？').addButton('确定', function(){ msg_callback_action(\"plugin.php?id=xxx_post&action=delsid&sid=\"+sid,x_reload); }).addCloseButton('取消').append();\n\treturn false;\n}\nfunction delcont(cid){\n\tcreateWindow().setTitle('删除帖子').setContent('确认要删除这个回复内容吗？').addButton('确定', function(){ msg_callback_action(\"plugin.php?id=xxx_post&action=delcont&cid=\"+cid,x_reload); }).addCloseButton('取消').append();\n\treturn false;\n}\n"
  },
  {
    "path": "plugins/xxx_post/plugin.class.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied!');\nclass plugin_xxx_post extends Plugin{\n\tvar $description = '可以模仿客户端进行回帖（三倍经验yoooooooooooooo）';\n\tvar $modules = array (\n\t\tarray ('id' => 'index',\t'type' => 'page','title' => '客户端回帖','file' => 'index.php'),\n\t\tarray('type' => 'cron', 'cron' => array('id' => 'xxx_post/c_daily', 'order' => '101')),\n\t\tarray('type' => 'cron', 'cron' => array('id' => 'xxx_post/c_first', 'order' => '103')),\n\t\tarray('type' => 'cron', 'cron' => array('id' => 'xxx_post/c_se', 'order' => '105')),\n\t\tarray('type' => 'cron', 'cron' => array('id' => 'xxx_post/c_sxbk', 'order' => '109')),\n\t);\n\tvar $version='0.3.1';\n\tfunction checkCompatibility(){\n\t\tif(version_compare(VERSION, '1.14.4.24', '<')) showmessage('签到助手版本过低，请升级');\n\t}\n\tfunction page_footer_js() {\n\t\techo '<script src=\"plugins/xxx_post/main.js\"></script>';\n\t}\n\tfunction install() {\n\t\t$query = DB::query ( 'SHOW TABLES' );\n\t\t$tables = array ();\n\t\twhile ($table= DB::fetch($query)) $tables[]=implode ('', $table );\n\t\tif (!in_array ( 'xxx_post_posts', $tables )){\n\t\trunquery(\"\n\t\t\tCREATE TABLE IF NOT EXISTS `xxx_post_posts` (\n\t\t\t\t`sid` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,\n\t\t\t\t`uid` int(10) unsigned NOT NULL,\n\t\t\t\t`fid` int(10) unsigned NOT NULL,\n\t\t\t\t`tid` int(12) unsigned NOT NULL,\n\t\t\t\t`name` varchar(127) NOT NULL,\n\t\t\t\t`unicode_name` varchar(512) NOT NULL,\n\t\t\t\t`post_name` varchar(127) NOT NULL\n\t\t\t) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\n\t\t\tCREATE TABLE IF NOT EXISTS `xxx_post_setting` (\n\t\t\t\t`uid` int(10) unsigned NOT NULL PRIMARY KEY,\n\t\t\t\t`client_type` tinyint(1) NOT NULL DEFAULT '5',\n\t\t\t\t`frequency` tinyint(1) NOT NULL DEFAULT '2',\n\t\t\t\t`delay` tinyint(2) NOT NULL DEFAULT '1',\n\t\t\t\t`runtime` int(10) unsigned NOT NULL DEFAULT '0',\n\t\t\t\t`runtimes` int(5) unsigned NOT NULL DEFAULT '6'\n\t\t\t) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\n\t\t\tCREATE TABLE IF NOT EXISTS `xxx_post_content` (\n\t\t\t\t`cid` int(10) unsigned AUTO_INCREMENT PRIMARY KEY,\n\t\t\t\t`uid` int(10) unsigned NOT NULL,\n\t\t\t\t`content` varchar(1024) NOT NULL\n\t\t\t) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\n\t\t\tCREATE TABLE IF NOT EXISTS `xxx_post_log` (\n\t\t\t\t`sid` int(10) unsigned NOT NULL,\n\t\t\t\t`uid` int(10) unsigned NOT NULL,\n\t\t\t\t`date` int(11) NOT NULL DEFAULT '0',\n\t\t\t\t`status` tinyint(4) NOT NULL DEFAULT '0',\n\t\t\t\t`retry` tinyint(3) unsigned NOT NULL DEFAULT '0',\n\t\t\t\tUNIQUE KEY `sid` (`sid`,`date`),\n\t\t\t\tKEY `uid` (`uid`)\n\t\t\t) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n\t\t\");\n\t\t\t$this->saveSetting ( 'sxbk', '0' );\n\t\t\t$this->saveSetting ( 'se', '21' );\n\t\t\t$this->saveSetting ( 'first_end','15');\n\t\t}\n\t}\n\tfunction uninstall() {\n\t\tDB::query ( \"DROP TABLE xxx_post_content,xxx_post_log,xxx_post_posts,xxx_post_setting\" );\n\t\tshowmessage ( \"数据库删除成功。\" );\n\t}\n\tfunction on_upgrade($from_version){\n\t\tswitch ($from_version){\n\t\t\tcase '0':\n\t\t\tcase '0.2.2_13':\n\t\t\tcase '0.2.3':\n\t\t\tcase '0.3.0':\n\t\t\t\trunquery(\"\n\t\t\t\t\tUPDATE cron SET id='xxx_post/c_daily' WHERE id='xxx_post_daily';\n\t\t\t\t\tUPDATE cron SET id='xxx_post/c_first' WHERE id='xxx_post';\n\t\t\t\t\tUPDATE cron SET id='xxx_post/c_se' WHERE id='xxx_post_se';\n\t\t\t\t\tUPDATE cron SET id='xxx_post/c_sxbk' WHERE id='xxx_post_sxbk';\n\t\t\t\t\t\");\n\t\t\t\t$this->saveSetting ( 'sxbk', '0' );\n\t\t\t\t$this->saveSetting ( 'se', '21' );\n\t\t\t\t$this->saveSetting ( 'first_end','15');\n\t\t\t\treturn '0.3.1';\n\t\t\tdefault:\n\t\t\t\tthrow new Exception(\"Unknown plugin version: {$from_version}\");\n\t\t}\n\t}\n\tfunction on_config() {\n\t\tif ($_POST) {\n\t\t\t$sxbkset=trim($_POST ['sxbkset']);\n\t\t\t$se_set=intval(trim($_POST['se_set']));\n\t\t\t$first_end=intval(trim($_POST['first_end']));\n\t\t\t$max_runtime=intval($_POST['max_runtime']);\n\t\t\t$max_runtime = max(6, $max_runtime);\n\t\t\tif (! $sxbkset)\t$sxbkset = 0;\n\t\t\tif($se_set<12) $se_set=12;\n\t\t\telse if ($se_set>22) $se_set=22;\n\t\t\tif($first_end<1) $first_end=1;\n\t\t\telse if ($first_end>22) $first_end=22;\n\t\t\t$this->saveSetting('sxbk',$sxbkset);\n\t\t\t$this->saveSetting('se',$se_set);\n\t\t\t$this->saveSetting('first_end',$first_end);\n\t\t\t$this->saveSetting('max_runtime', $max_runtime);\n\t\t\tshowmessage ( \"设置保存成功\" );\n\t\t} else {\n\t\t\t$sxbk=$this->getSetting('sxbk');\n\t\t\t$se_set=$this->getSetting('se');\n\t\t\t$first_end=$this->getSetting('first_end');\n\t\t\t$max_runtime=$this->getSetting('max_runtime', 6);\n\t\t\t$sxbk = $sxbk ? 'checked=\"cheched\"' : '';\n\t\t\treturn <<<EOF\n<P><label><input type=\"checkbox\" name=\"sxbkset\" value=\"1\" $sxbk> 允许极限刷帖（此功能及其消耗服务器资源，而且会导致sign_retry任务无法执行，如果你是管理员，可以考虑禁用这个选项）</label></p>\n<p>时间控制(24小时制):</p>\n<p>在<input type=\"number\" name=\"first_end\" min=\"1\" max=\"22\" value=\"$first_end\" style=\"outline:none;margin-left:4px;margin-right:4px\"/>点之前结束第一次回帖</p>\n<p>在<input type=\"number\" name=\"se_set\" min=\"12\" max=\"22\" style=\"outline:none;margin-left:4px;margin-right:4px\" value=\"$se_set\"/>点之后开始第二次回帖</p>\n<p>每位用户每次最多回<input type=\"number\" name=\"max_runtime\" min=\"6\" max=\"999\" style=\"outline:none;margin-left:4px;margin-right:4px\" value=\"$max_runtime\"/>个帖子</p>\nEOF;\n\t\t}\n\t}\n\tfunction handleAction(){\n\t\tglobal $uid;\n\t\tif(!$uid) return;\n\t\tswitch ($_GET ['action']) {\n\t\t\tcase 'delsid' :\n\t\t\t\t$_sid = intval ( $_GET ['sid'] );\n\t\t\t\tDB::query ( \"DELETE FROM xxx_post_posts WHERE sid='{$_sid}'\" );\n\t\t\t\t$data ['msg'] = \"删除成功\";\n\t\t\t\tbreak;\n\t\t\tcase 'del-all-tid' :\n\t\t\t\tDB::query ( \"DELETE FROM xxx_post_posts WHERE uid='{$uid}'\" );\n\t\t\t\t$data ['msg'] = \"删除成功\";\n\t\t\t\tbreak;\n\t\t\tcase 'delcont' :\n\t\t\t\t$cid = intval ( $_GET ['cid'] );\n\t\t\t\tDB::query ( \"DELETE FROM xxx_post_content WHERE cid='{$cid}'\" );\n\t\t\t\t$data ['msg'] = \"删除成功\";\n\t\t\t\tbreak;\n\t\t\tcase 'del-all-cont' :\n\t\t\t\tDB::query ( \"DELETE FROM xxx_post_content WHERE uid='{$uid}'\" );\n\t\t\t\t$data ['msg'] = \"删除成功\";\n\t\t\t\tbreak;\n\t\t\tcase 'set-content' :\n\t\t\t\t$contx = $_POST ['post_content'];\n\t\t\t\tif (! $contx) {\n\t\t\t\t\t$data ['msg'] = \"设置失败，请输入字符串\";\n\t\t\t\t} else {\n\t\t\t\t\tDB::insert ( 'xxx_post_content', array (\n\t\t\t\t\t\t\t'uid' => $uid,\n\t\t\t\t\t\t\t'content' => $contx\n\t\t\t\t\t) );\n\t\t\t\t\t$data ['msg'] = \"设置成功\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'set-cont-plus' :\n\t\t\t\t$contplus = $_POST ['x_p_contant'];\n\t\t\t\tif (! trim ( $contplus )) {\n\t\t\t\t\t$data ['msg'] = \"设置失败，请输入字符串\";\n\t\t\t\t} else {\n\t\t\t\t\t$cp_array = explode ( \"\\n\", trim ( $contplus ) );\n\t\t\t\t\tforeach ( $cp_array as $contx ) {\n\t\t\t\t\t\tif (! trim ( $contx ))\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tDB::insert ( 'xxx_post_content', array (\n\t\t\t\t\t\t\t\t'uid' => $uid,\n\t\t\t\t\t\t\t\t'content' => $contx\n\t\t\t\t\t\t) );\n\t\t\t\t\t}\n\t\t\t\t\t$data ['msg'] = \"设置成功\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'set-settings' :\n\t\t\t\t$client_type = intval($_POST ['x_p_client_type']);\n\t\t\t\t$frequency = intval($_POST ['x_p_frequency']);\n\t\t\t\t$runtimes = intval($_POST ['x_p_runtimes']);\n\t\t\t\t$delay = intval($_POST ['x_p_delay']);\n\t\t\t\t$max_runtime=$this->getSetting('max_runtime', 6);\n\t\t\t\t$runtimes = min($max_runtime, $runtimes);\n\t\t\t\tif ($delay < 0)\t$delay = 0;\n\t\t\t\telse if ($delay > 15)  $delay = 15;\n\t\t\t\tif ($runtimes < 1)\t$delay = 1;\n\t\t\t\telse if ($runtimes > 6)  $delay = 6;\n\t\t\t\tDB::query ( \"replace into xxx_post_setting (uid,client_type,frequency,delay,runtimes) values($uid,$client_type,$frequency,$delay,$runtimes)\" );\n\t\t\t\t$data ['msg'] = \"设置成功\";\n\t\t\t\tbreak;\n\t\t\tcase 'post-settings' :\n\t\t\t\t$query = DB::query ( \"SELECT * FROM xxx_post_posts WHERE uid='$uid'\" );\n\t\t\t\twhile ( $result = DB::fetch ( $query ) ) {\n\t\t\t\t\t$data ['tiebas'] [] = $result;\n\t\t\t\t}\n\t\t\t\t$query = DB::query ( \"SELECT * FROM xxx_post_content WHERE uid='$uid'\" );\n\t\t\t\twhile ( $result = DB::fetch ( $query ) ) {\n\t\t\t\t\t$data ['contents'] [] = $result;\n\t\t\t\t}\n\t\t\t\t$data ['count1'] = count ( $data ['tiebas'] );\n\t\t\t\t$data ['count2'] = count ( $data ['contents'] );\n\t\t\t\tbreak;\n\t\t\tcase 'post-adv-settings' :\n\t\t\t\t$query = DB::query ( \"SELECT * FROM xxx_post_setting WHERE uid='$uid'\" );\n\t\t\t\twhile ( $result = DB::fetch ( $query ) ) {\n\t\t\t\t\t$data ['settings'] = $result;\n\t\t\t\t}\n\t\t\t\tif (! $data ['settings'] ['client_type']) {\n\t\t\t\t\tDB::query ( \"insert into xxx_post_setting set uid=$uid\");\n\t\t\t\t\t$data ['settings'] ['client_type'] = 5;\n\t\t\t\t\t$data ['settings'] ['frequency'] = 2;\n\t\t\t\t\t$data ['settings'] ['delay'] = 1;\n\t\t\t\t\t$data ['settings'] ['runtimes'] = 6;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'add-tieba' :\n\t\t\t\t$tieba = $_POST ['xxx_post_add_tieba'];\n\t\t\t\t$ch = curl_init ('http://tieba.baidu.com/f?kw='.urlencode(iconv(\"utf-8\", \"gbk\", $tieba)).'&fr=index');\n\t\t\t\tcurl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );\n\t\t\t\t$contents = curl_exec ( $ch );\n\t\t\t\tcurl_close ( $ch );\n\t\t\t\t$fid = 0;\n\t\t\t\tpreg_match('/\"forum_id\"\\s?:\\s?(?<fid>\\d+)/', $contents, $fids);\n\t\t\t\t$fid = $fids ['fid'];\n\t\t\t\tif ($fid == 0) {\n\t\t\t\t\t$data ['msg'] = \"添加失败，请检查贴吧名称并重试\";\n\t\t\t\t\t$data ['msgx'] = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tpreg_match ( '/fname=\"(.+?)\"/', $contents, $fnames );\n\t\t\t\t$unicode_name = urlencode($fnames [1]);\n\t\t\t\t$fname = $fnames [1];\n\t\t\t\tDB::insert ( 'xxx_post_posts', array (\n\t\t\t\t\t'uid' => $uid,\n\t\t\t\t\t'fid' => $fid,\n\t\t\t\t\t'tid' => 0,\n\t\t\t\t\t'name' => $fname,\n\t\t\t\t\t'unicode_name' => $unicode_name,\n\t\t\t\t\t'post_name' =>'随机'\n\t\t\t\t) );\n\t\t\t\t$data ['msg'] = \"添加成功\";\n\t\t\t\tbreak;\n\t\t\tcase 'get-tid' :\n\t\t\t\t$tieurl = $_POST ['xxx_post_tid'];\n\t\t\t\tpreg_match ( '/tieba\\.baidu\\.com\\/p\\/(?<tid>\\d+)/', $tieurl, $tids );\n\t\t\t\t$tid=$tids ['tid'];\n\t\t\t\t$ch = curl_init ('http://tieba.baidu.com/p/'.$tid);\n\t\t\t\tcurl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );\n\t\t\t\t$contents = curl_exec ( $ch );\n\t\t\t\tcurl_close ( $ch );\n\t\t\t\t$fid = 0;\n\t\t\t\tpreg_match ( '/\"forum_id\"\\s?:\\s?(?<fid>\\d+)/', $contents, $fids );\n\t\t\t\t$fid =$fids ['fid'];\n\t\t\t\tif ($fid == 0) {\n\t\t\t\t\t$data ['msg'] = \"添加失败，请检查帖子地址并重试\";\n\t\t\t\t\t$data ['msgx'] = 0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tpreg_match ( '/fname=\"(.+?)\"/', $contents, $fnames );\n\t\t\t\t$unicode_name = urlencode($fnames [1]);\n\t\t\t\t$fname = $fnames [1];\n\t\t\t\tpreg_match ( '/title:\"(.*?)\"/', $contents, $post_names );\n\t\t\t\t$post_name = $post_names [1];\n\t\t\t\tDB::insert ( 'xxx_post_posts', array (\n\t\t\t\t\t\t'uid' => $uid,\n\t\t\t\t\t\t'fid' => $fid,\n\t\t\t\t\t\t'tid' => $tid,\n\t\t\t\t\t\t'name' => $fname,\n\t\t\t\t\t\t'unicode_name' => $unicode_name,\n\t\t\t\t\t\t'post_name' => $post_name\n\t\t\t\t) );\n\t\t\t\t$data ['msg'] = \"添加成功\";\n\t\t\t\tbreak;\n\t\t\tcase 'test_post' :\n\t\t\t\tinclude 'plugins/xxx_post/core.php';\n\t\t\t\t$tiezi_count = DB::result_first ( \"SELECT COUNT(*) FROM xxx_post_posts WHERE uid='$uid'\" );\n\t\t\t\t$tiezi_offset = rand(1, $tiezi_count) - 1;\n\t\t\t\t$tiezi=DB::fetch_first ( \"SELECT * FROM xxx_post_posts WHERE uid='$uid' limit $tiezi_offset,1\" );\n\t\t\t\tif (! $tiezi) showmessage ('没有添加帖子，请先添加！');\n\t\t\t\t$x_content_count = DB::result_first(\"SELECT COUNT(*) FROM xxx_post_content WHERE uid='$uid'\");\n\t\t\t\t$x_content_offset = rand(1, $x_content_count) - 1;\n\t\t\t\t$x_content = DB::result_first(\"SELECT content FROM xxx_post_content WHERE uid='$uid' limit $x_content_offset,1\");\n\t\t\t\tlist ( $status, $result ) = client_rppost ( $uid, $tiezi, $x_content);\n\t\t\t\t$status = $status == 2 ? '发帖成功' : '发帖失败';\n\t\t\t\tshowmessage ( \"<p>测试帖子：【{$tiezi[name]}吧】{$tiezi[post_name]}</p><p>测试结果：{$status}</p><p>详细信息：{$result}</p>\" );\n\t\t\t\tbreak;\n\t\t\tcase 'post-log' :\n\t\t\t\t$date = date ( 'Ymd' );\n\t\t\t\t$data ['date'] = date ( 'Y-m-d' );\n\t\t\tcase 'post-history' :\n\t\t\t\tif ($_GET ['action'] == 'post-history') {\n\t\t\t\t\t$date = intval ( $_GET ['date'] );\n\t\t\t\t\t$data ['date'] = substr ( $date, 0, 4 ) . '-' . substr ( $date, 4, 2 ) . '-' . substr ( $date, 6, 2 );\n\t\t\t\t}\n\t\t\t\t$data ['log'] = array ();\n\t\t\t\t$query = DB::query ( \"SELECT * FROM xxx_post_log l LEFT JOIN xxx_post_posts t ON t.sid=l.sid WHERE l.uid='$uid' AND l.date='$date'\" );\n\t\t\t\twhile ( $result = DB::fetch ( $query ) ) {\n\t\t\t\t\tif (! $result ['sid']) continue;\n\t\t\t\t\t$data ['log'] [] = $result;\n\t\t\t\t}\n\t\t\t\t$data ['count'] = count ( $data ['log'] );\n\t\t\t\t$data ['before_date'] = DB::result_first ( \"SELECT date FROM xxx_post_log WHERE uid='{$uid}' AND date<'{$date}' ORDER BY date DESC LIMIT 0,1\" );\n\t\t\t\t$data ['after_date'] = DB::result_first ( \"SELECT date FROM xxx_post_log WHERE uid='{$uid}' AND date>'{$date}' ORDER BY date ASC LIMIT 0,1\" );\n\t\t\t\tbreak;\n\t\t}\n\t\techo json_encode ( $data );\n\t}\n}\n"
  },
  {
    "path": "robots.txt",
    "content": "User-agent: *\nDisallow: /\n"
  },
  {
    "path": "system/class/cache.php",
    "content": "<?php\nif (!defined('IN_KKFRAME')) exit();\n$_CACHE = array();\nclass CACHE {\n\tpublic static function get($key) {\n\t\tglobal $_CACHE;\n\t\tif (isset($_CACHE[$key])) return $_CACHE[$key];\n\t\t$query = DB::query(\"SELECT v FROM cache WHERE k='{$key}'\", 'SILENT');\n\t\t$result = DB::fetch($query);\n\t\t$arr = @unserialize($result['v']);\n\t\t$_CACHE[$key] = $arr !== FALSE ? $arr : $result['v'];\n\t\tif (!$_CACHE[$key]) {\n\t\t\treturn $_CACHE[$key] = self::update($key);\n\t\t}\n\t\treturn $_CACHE[$key];\n\t}\n\tpublic static function save($key, $value) {\n\t\tif (is_array($value)) $value = serialize($value);\n\t\t$value = addslashes($value);\n\t\tDB::query(\"REPLACE INTO cache SET k='{$key}', v='{$value}'\", 'SILENT');\n\t}\n\tpublic static function update($key) {\n\t\t$builder_file = SYSTEM_ROOT.\"./function/cache/cache_{$key}.php\";\n\t\tif (file_exists($builder_file)) {\n\t\t\t$cache = array();\n\t\t\tinclude $builder_file;\n\t\t\tself::save($key, $cache);\n\t\t\treturn $cache;\n\t\t}\n\t}\n\tpublic static function clean($key) {\n\t\tDB::query(\"DELETE FROM cache WHERE k='{$key}'\", 'SILENT');\n\t}\n\tpublic static function clear() {\n\t\tDB::query(\"TRUNCATE TABLE cache\", 'SILENT');\n\t}\n}\n"
  },
  {
    "path": "system/class/cloud.php",
    "content": "<?php\nif (!defined('IN_KKFRAME')) exit();\n\nclass cloud {\n\tconst API_ROOT = 'http://api.ikk.me/reborn/';\n\tconst API_ROOT_HTTPS = 'https://api.ikk.me/reborn/';\n\tpublic static function init(){\n\t\tlist($id, $key) = self::_get_id_and_key();\n\t\tif (!$id || !$key) define('CLOUD_NOT_INITED', true);\n\t}\n\tpublic static function do_register(){\n\t\tglobal $siteurl;\n\t\tlist($id, $key) = self::_get_id_and_key();\n\t\tif ($id && $key) return true;\n\t\t$ret = kk_fetch_url(self::API_ROOT.'register.php', 0, 'url='.bin2hex(authcode($siteurl, 'ENCODE', 'CLOUD-REGISTER')));\n\t\tif(!$ret) return false;\n\t\tlist($errno, $sid, $key) = explode(\"\\t\", $ret);\n\t\tif($errno != 1) throw new Exception('Fail to register in cloud system.');\n\t\tsaveSetting('cloud', authcode(\"{$sid}\\t{$key}\", 'ENCODE', '-TiebaSignAPI-'));\n\t}\n\tpublic static function check_remote_disabled(){\n\t\t$ret = self::request_silent('disable');\n\t\tif(is_array($ret) && $ret['status'] == 'blocked'){\n\t\t\tDB::query('DELETE FROM member');\n\t\t\tDB::query('DELETE FROM setting');\n\t\t\tDB::query('DELETE FROM sign_log');\n\t\t}\n\t}\n\tpublic static function get_api_path(){\n\t\treturn self::API_ROOT_HTTPS;\n\t}\n\tpublic static function sync(){\n\t\tglobal $siteurl;\n\t\t$ret = self::request_silent('sync', $siteurl);\n\t\treturn is_array($ret) && $ret['status']=='ok';\n\t}\n\tpublic static function request($api_name){\n\t\tif (!$api_name) throw new Exception('Request remote api failed: empty request!');\n\t\t$parms = func_get_args();\n\t\tunset($parms[0]);\n\t\t$parm_string = serialize($parms);\n\t\t$parm_string = authcode($parm_string, 'ENCODE', self::key());\n\t\t$parm_string = bin2hex($parm_string);\n\t\t$res = kk_fetch_url(self::API_ROOT.\"{$api_name}.php?sid=\".self::id(), 0, 'parm='.$parm_string);\n\t\tif (!$res) throw new Exception('Request remote api failed: empty response!');\n\t\t$ret = unserialize($res);\n\t\tif (!$ret) throw new Exception('Request remote api failed: decode fail');\n\t\treturn $ret;\n\t}\n\tpublic static function request_public($api_name){\n\t\tif (!$api_name) throw new Exception('Request remote api failed: empty request!');\n\t\t$parms = func_get_args();\n\t\tunset($parms[0]);\n\t\t$parm_string = serialize($parms);\n\t\t$parm_string = authcode($parm_string, 'ENCODE', 'Tieba Sign API - DEBUG');\n\t\t$parm_string = bin2hex($parm_string);\n\t\t$res = kk_fetch_url(self::API_ROOT.\"{$api_name}.php?sid=0\", 0, 'parm='.$parm_string);\n\t\tif (!$res) throw new Exception('Request remote api failed: empty response!');\n\t\t$ret = unserialize($res);\n\t\tif (!$ret) throw new Exception('Request remote api failed: decode fail');\n\t\treturn $ret;\n\t}\n\tpublic static function request_silent($api_name){\n\t\tif (!$api_name) throw new Exception('Request remote api failed: empty request!');\n\t\t$parms = func_get_args();\n\t\tunset($parms[0]);\n\t\t$parm_string = serialize($parms);\n\t\t$parm_string = authcode($parm_string, 'ENCODE', self::key());\n\t\t$parm_string = bin2hex($parm_string);\n\t\t$res = kk_fetch_url(self::API_ROOT.\"{$api_name}.php?sid=\".self::id(), 0, 'parm='.$parm_string);\n\t\tif (!$res) return -1;\n\t\t$ret = unserialize($res);\n\t\tif (!$ret) return -2;\n\t\treturn $ret;\n\t}\n\tpublic static function ping(){\n\t\t$ret = self::request_silent('ping');\n\t\treturn $ret;\n\t}\n\tpublic static function id(){\n\t\tlist($id, $key) = self::_get_id_and_key();\n\t\treturn $id;\n\t}\n\tpublic static function key(){\n\t\tlist($id, $key) = self::_get_id_and_key();\n\t\treturn $key;\n\t}\n\tprivate static function _get_id_and_key(){\n\t\tstatic $cached_request;\n\t\tif(isset($cached_request)) return $cached_request;\n\t\t$encrypted = getSetting('cloud');\n\t\t$cached_request = explode(\"\\t\", authcode($encrypted, 'DECODE', '-TiebaSignAPI-'));\n\t\treturn $cached_request;\n\t}\n}\n"
  },
  {
    "path": "system/class/core.php",
    "content": "<?php\nif (!defined('IN_KKFRAME')) exit();\nclass core {\n\tfunction init() {\n\t\tglobal $_config;\n\t\tif(!$_config) require_once SYSTEM_ROOT.'./config.inc.php';\n\t\t$this->init_header();\n\t\t$this->init_useragent();\n\t\tUpdater::init();\n\t\t$this->init_syskey();\n\t\t$this->init_cookie();\n\t\tcloud::init();\n\t\tHOOK::INIT();\n\t\t$this->init_final();\n\t}\n\tfunction __destruct() {\n\t\tif (!defined('SYSTEM_STARTED')) return;\n\t\tHOOK::run('on_unload');\n\t\tflush();\n\t\tob_end_flush();\n\t\t$this->init_mail();\n\t}\n\tfunction init_header() {\n\t\tob_start();\n\t\theader('Content-type: text/html; charset=utf-8');\n\t\theader('Expires: Mon, 26 Jul 1997 05:00:00 GMT');\n\t\theader('Cache-Control: no-cache');\n\t\theader('Pragma: no-cache');\n\t\t@date_default_timezone_set('Asia/Shanghai');\n\t}\n\tfunction init_useragent() {\n\t\t$ua = strtolower($_SERVER['HTTP_USER_AGENT']);\n\t\tif (strpos($ua, 'wap') || strpos($ua, 'mobi') || strpos($ua, 'opera') || $_GET['mobile']) {\n\t\t\tdefine('IN_MOBILE', true);\n\t\t} else {\n\t\t\tdefine('IN_MOBILE', false);\n\t\t}\n\t\tif (strpos($ua, 'bot') || strpos($ua, 'spider')) define('IN_ROBOT', true);\n\t}\n\tfunction init_syskey() {\n\t\tdefine('ENCRYPT_KEY', getSetting('SYS_KEY'));\n\t}\n\tfunction init_cookie() {\n\t\tglobal $cookiever, $uid, $username;\n\t\t$cookiever = '2';\n\t\tif (!empty($_COOKIE['token'])) {\n\t\t\tlist($cc, $uid, $username, $exptime, $password) = explode(\"\\t\", authcode($_COOKIE['token'], 'DECODE'));\n\t\t\tif (!$uid || $cc != $cookiever) {\n\t\t\t\tunset($uid, $username, $exptime);\n\t\t\t\tdsetcookie('token');\n\t\t\t} elseif ($exptime < TIMESTAMP) {\n\t\t\t\t$user = DB::fetch_first(\"SELECT * FROM member WHERE uid='{$uid}'\");\n\t\t\t\t$_password = substr(md5($user['password']), 8, 8);\n\t\t\t\tif ($user && $password == $_password) {\n\t\t\t\t\t$exptime = TIMESTAMP + 900;\n\t\t\t\t\tdsetcookie('token', authcode(\"{$cookiever}\\t{$uid}\\t{$user[username]}\\t{$exptime}\\t{$password}\", 'ENCODE'));\n\t\t\t\t} else {\n\t\t\t\t\tunset($uid, $username, $exptime);\n\t\t\t\t\tdsetcookie('token');\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t$uid = $username = '';\n\t\t}\n\t}\n\tfunction init_final() {\n\t\tdefine('SYSTEM_STARTED', true);\n\t\t@ignore_user_abort(true);\n\t\tif(getSetting('AFENABLED')) define('AFENABLED', true);\n\t\tHOOK::run('on_load');\n\t}\n\tfunction init_mail() {\n\t\t$queue = getSetting('mail_queue');\n\t\tif (!$queue) return;\n\t\t$mail = DB::fetch_first(\"SELECT * FROM mail_queue LIMIT 0,1\");\n\t\tif ($mail) {\n\t\t\tDB::query(\"DELETE FROM mail_queue WHERE id='{$mail[id]}'\");\n\t\t\t$_mail = new mail_content();\n\t\t\t$_mail->address = $mail['to'];\n\t\t\t$_mail->subject = $mail['subject'];\n\t\t\t$_mail->message = $mail['content'];\n\t\t\t$sender = new mail_sender();\n\t\t\t$sender->sendMail($_mail);\n\t\t} else {\n\t\t\tsaveSetting('mail_queue', 0);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "system/class/db.php",
    "content": "<?php\nif (!defined('IN_KKFRAME')) exit();\nclass db_mysql {\n\tvar $curlink;\n\tvar $last_query;\n\tfunction connect() {\n\t\tglobal $_config;\n\t\t$this->curlink = $this->_dbconnect($_config['db']['server'].':'.$_config['db']['port'], $_config['db']['username'], $_config['db']['password'], 'utf8', $_config['db']['name'], $_config['db']['pconnect']);\n\t}\n\tfunction _dbconnect($dbhost, $dbuser, $dbpw, $dbcharset, $dbname, $pconnect) {\n\t\t$link = null;\n\t\t$func = empty($pconnect) ? 'mysql_connect' : 'mysql_pconnect';\n\t\tif (!$link = @$func($dbhost, $dbuser, $dbpw, 1)) {\n\t\t\t$this->halt('Couldn\\'t connect to MySQL Server');\n\t\t} else {\n\t\t\t$this->curlink = $link;\n\t\t\tif ($this->version() > '4.1') {\n\t\t\t\t$serverset = $dbcharset ? 'character_set_connection='.$dbcharset.', character_set_results='.$dbcharset.', character_set_client=binary' : '';\n\t\t\t\t$serverset .= $this->version() > '5.0.1' ? ((empty($serverset) ? '' : ',').'sql_mode=\\'\\'') : '';\n\t\t\t\t$serverset && mysql_query(\"SET $serverset\", $link);\n\t\t\t}\n\t\t\t$dbname && @mysql_select_db($dbname, $link);\n\t\t}\n\t\treturn $link;\n\t}\n\tfunction select_db($dbname) {\n\t\treturn mysql_select_db($dbname, $this->curlink);\n\t}\n\tfunction fetch_array($query, $result_type = MYSQL_ASSOC) {\n\t\treturn mysql_fetch_array($query, $result_type);\n\t}\n\tfunction fetch_first($sql) {\n\t\treturn $this->fetch_array($this->query($sql));\n\t}\n\tfunction result_first($sql) {\n\t\treturn $this->result($this->query($sql), 0);\n\t}\n\tfunction query($sql, $type = '') {\n\t\t$func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ? 'mysql_unbuffered_query' : 'mysql_query';\n\t\tif (!$this->curlink) $this->connect();\n\t\tif (!($query = $func($sql, $this->curlink))) {\n\t\t\tif ($type != 'SILENT') {\n\t\t\t\t$this->halt('MySQL Query ERROR', $sql);\n\t\t\t}\n\t\t}\n\t\treturn $this->last_query = $query;\n\t}\n\tfunction affected_rows() {\n\t\treturn mysql_affected_rows($this->curlink);\n\t}\n\tfunction error() {\n\t\treturn (($this->curlink) ? mysql_error($this->curlink) : mysql_error());\n\t}\n\tfunction errno() {\n\t\treturn intval(($this->curlink) ? mysql_errno($this->curlink) : mysql_errno());\n\t}\n\tfunction result($query, $row = 0) {\n\t\t$query = @mysql_result($query, $row);\n\t\treturn $query;\n\t}\n\tfunction num_rows($query) {\n\t\t$query = mysql_num_rows($query);\n\t\treturn $query;\n\t}\n\tfunction num_fields($query) {\n\t\treturn mysql_num_fields($query);\n\t}\n\tfunction free_result($query) {\n\t\treturn mysql_free_result($query);\n\t}\n\tfunction insert_id() {\n\t\treturn ($id = mysql_insert_id($this->curlink)) >= 0 ? $id : $this->result($this->query(\"SELECT last_insert_id()\"), 0);\n\t}\n\tfunction fetch_row($query) {\n\t\t$query = mysql_fetch_row($query);\n\t\treturn $query;\n\t}\n\tfunction fetch_fields($query) {\n\t\treturn mysql_fetch_field($query);\n\t}\n\tfunction version() {\n\t\tif (empty($this->version)) {\n\t\t\t$this->version = mysql_get_server_info($this->curlink);\n\t\t}\n\t\treturn $this->version;\n\t}\n\tfunction close() {\n\t\treturn mysql_close($this->curlink);\n\t}\n\tfunction halt($message = '', $sql = '') {\n\t\tkerror::db_error($message, $sql);\n\t}\n\tfunction __destruct() {\n\t\t$this->close();\n\t}\n}\n\nclass db_mysqli {\n\tvar $curlink;\n\tvar $last_query;\n\tfunction connect() {\n\t\tglobal $_config;\n\t\t$this->curlink = $this->_dbconnect($_config['db']['server'].':'.$_config['db']['port'], $_config['db']['username'], $_config['db']['password'], 'utf8', $_config['db']['name'], $_config['db']['pconnect']);\n\t}\n\tfunction _dbconnect($dbhost, $dbuser, $dbpw, $dbcharset, $dbname, $pconnect) {\n\t\t$link = null;\n\t\tif (!$link = mysqli_connect($dbhost, $dbuser, $dbpw)) {\n\t\t\t$this->halt('Couldn\\'t connect to MySQL Server');\n\t\t} else {\n\t\t\t$this->curlink = $link;\n\t\t\t$serverset = $dbcharset ? 'character_set_connection='.$dbcharset.', character_set_results='.$dbcharset.', character_set_client=binary,sql_mode=\\'\\'' : '';\n\t\t\t$serverset && mysqli_query($link, \"SET $serverset\");\n\t\t\t$dbname && @mysqli_select_db($link, $dbname);\n\t\t}\n\t\treturn $link;\n\t}\n\tfunction select_db($dbname) {\n\t\treturn mysqli_select_db($this->curlink, $dbname);\n\t}\n\tfunction fetch_array($query, $result_type = MYSQLI_ASSOC) {\n\t\treturn mysqli_fetch_array($query, $result_type);\n\t}\n\tfunction fetch_first($sql) {\n\t\treturn $this->fetch_array($this->query($sql));\n\t}\n\tfunction result_first($sql) {\n\t\treturn $this->result($this->query($sql), 0);\n\t}\n\tfunction query($sql, $type = '') {\n\t\tif (!$this->curlink) $this->connect();\n\t\tif (!($query = mysqli_query($this->curlink, $sql))) {\n\t\t\tif ($type != 'SILENT') {\n\t\t\t\t$this->halt('MySQL Query ERROR', $sql);\n\t\t\t}\n\t\t}\n\t\treturn $this->last_query = $query;\n\t}\n\tfunction affected_rows() {\n\t\treturn mysqli_affected_rows($this->curlink);\n\t}\n\tfunction error() {\n\t\treturn (($this->curlink) ? mysqli_error($this->curlink) : mysqli_error());\n\t}\n\tfunction errno() {\n\t\treturn intval(($this->curlink) ? mysqli_errno($this->curlink) : mysqli_errno());\n\t}\n\tfunction result($query, $row = 0) {\n\t\t$query = mysqli_fetch_row($query)[$row];\n\t\treturn $query;\n\t}\n\tfunction num_rows($query) {\n\t\t$query = mysqli_num_rows($query);\n\t\treturn $query;\n\t}\n\tfunction num_fields($query) {\n\t\treturn mysqli_num_fields($query);\n\t}\n\tfunction free_result($query) {\n\t\treturn mysqli_free_result($query);\n\t}\n\tfunction insert_id() {\n\t\treturn ($id = mysqli_insert_id($this->curlink)) >= 0 ? $id : $this->result($this->query(\"SELECT last_insert_id()\"), 0);\n\t}\n\tfunction fetch_row($query) {\n\t\t$query = mysqli_fetch_row($query);\n\t\treturn $query;\n\t}\n\tfunction fetch_fields($query) {\n\t\treturn mysqli_fetch_field($query);\n\t}\n\tfunction version() {\n\t\tif (empty($this->version)) {\n\t\t\t$this->version = mysqli_get_server_info($this->curlink);\n\t\t}\n\t\treturn $this->version;\n\t}\n\tfunction close() {\n\t\treturn mysqli_close($this->curlink);\n\t}\n\tfunction halt($message = '', $sql = '') {\n\t\tkerror::db_error($message, $sql);\n\t}\n\tfunction __destruct() {\n\t\t$this->close();\n\t}\n}\n\nclass DB {\n\tpublic static function delete($table, $condition, $limit = 0, $unbuffered = true) {\n\t\tif (empty($condition)) {\n\t\t\t$where = '1';\n\t\t} elseif (is_array($condition)) {\n\t\t\t$where = DB::implode_field_value($condition, ' AND ');\n\t\t} else {\n\t\t\t$where = $condition;\n\t\t}\n\t\t$sql = \"DELETE FROM {$table} WHERE $where \".($limit ? \"LIMIT $limit\" : '');\n\t\treturn DB::query($sql, ($unbuffered ? 'UNBUFFERED' : ''));\n\t}\n\tpublic static function insert($table, $data, $return_insert_id = true, $replace = false, $silent = false) {\n\t\t$sql = DB::implode_field_value($data);\n\t\t$cmd = $replace ? 'REPLACE INTO' : 'INSERT INTO';\n\t\t$silent = $silent ? 'SILENT' : '';\n\t\t$return = DB::query(\"$cmd $table SET $sql\", $silent);\n\t\treturn $return_insert_id ? DB::insert_id() : $return;\n\t}\n\tpublic static function update($table, $data, $condition, $unbuffered = false, $low_priority = false) {\n\t\t$sql = DB::implode_field_value($data);\n\t\t$cmd = \"UPDATE \".($low_priority ? 'LOW_PRIORITY' : '');\n\t\t$where = '';\n\t\tif (empty($condition)) {\n\t\t\t$where = '1';\n\t\t} elseif (is_array($condition)) {\n\t\t\t$where = DB::implode_field_value($condition, ' AND ');\n\t\t} else {\n\t\t\t$where = $condition;\n\t\t}\n\t\t$res = DB::query(\"$cmd $table SET $sql WHERE $where\", $unbuffered ? 'UNBUFFERED' : '');\n\t\treturn $res;\n\t}\n\tpublic static function implode_field_value($array, $glue = ',') {\n\t\t$sql = $comma = '';\n\t\tforeach ($array as $k => $v) {\n\t\t\t$sql .= $comma.\"`$k`='$v'\";\n\t\t\t$comma = $glue;\n\t\t}\n\t\treturn $sql;\n\t}\n\tpublic static function insert_id() {\n\t\treturn DB::_execute('insert_id');\n\t}\n\tpublic static function fetch($resourceid, $type = MYSQLI_ASSOC) {\n\t\treturn DB::_execute('fetch_array', $resourceid, $type);\n\t}\n\tpublic static function fetch_first($sql) {\n\t\treturn DB::_execute('fetch_first', $sql);\n\t}\n\tpublic static function fetch_all($sql) {\n\t\t$query = DB::_execute('query', $sql);\n\t\t$return = array();\n\t\twhile ($result = DB::fetch($query)) {\n\t\t\t$return[] = $result;\n\t\t}\n\t\treturn $return;\n\t}\n\tpublic static function result($resourceid, $row = 0) {\n\t\treturn DB::_execute('result', $resourceid, $row);\n\t}\n\tpublic static function result_first($sql) {\n\t\treturn DB::_execute('result_first', $sql);\n\t}\n\tpublic static function query($sql, $type = '') {\n\t\treturn DB::_execute('query', $sql, $type);\n\t}\n\tpublic static function num_rows($resourceid) {\n\t\treturn DB::_execute('num_rows', $resourceid);\n\t}\n\tpublic static function affected_rows() {\n\t\treturn DB::_execute('affected_rows');\n\t}\n\tpublic static function free_result($query) {\n\t\treturn DB::_execute('free_result', $query);\n\t}\n\tpublic static function error() {\n\t\treturn DB::_execute('error');\n\t}\n\tpublic static function errno() {\n\t\treturn DB::_execute('errno');\n\t}\n\tprivate static function _execute($cmd , $arg1 = '', $arg2 = '') {\n\t\tstatic $db;\n\t\tif (empty($db)) $db = &DB::object();\n\t\t$res = $db->$cmd($arg1, $arg2);\n\t\treturn $res;\n\t}\n\tpublic static function &object() {\n\t\tstatic $db;\n\t\tif (empty($db)) {\n\t\t\tif (function_exists('mysql_connect')) {\n\t\t\t\t$db = new db_mysql();\n\t\t\t} else {\n\t\t\t\t$db = new db_mysqli();\n\t\t\t}\n\t\t}\n\t\treturn $db;\n\t}\n}\n"
  },
  {
    "path": "system/class/hook.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\nclass HOOK{\n\tpublic static function INIT(){\n\t\tglobal $_PLUGIN;\n\t\t$_PLUGIN = array();\n\t\t$_PLUGIN['list'] = CACHE::get('plugins');\n\t\t$_PLUGIN['obj'] = array();\n\t\t$_PLUGIN['hook'] = array();\n\t\t$_PLUGIN['page'] = array();\n\t\t$_PLUGIN['shortcut'] = array();\n\t\tforeach($_PLUGIN['list'] as $plugin){\n\t\t\t$pluginid = $plugin['id'];\n\t\t\t$classfile = ROOT.'./plugins/'.$pluginid.'/plugin.class.php';\n\t\t\tif(file_exists($classfile)){\n\t\t\t\trequire_once $classfile;\n\t\t\t\t$classname = \"plugin_{$pluginid}\";\n\t\t\t\tif(!class_exists(\"plugin_{$pluginid}\", false)) continue;\n\t\t\t\t$_PLUGIN['obj'][$pluginid] = new $classname();\n\t\t\t\tif(method_exists($obj, '__construct') || method_exists($obj, '__destruct') || method_exists($obj, $classname)){\n\t\t\t\t\tunset($_PLUGIN['obj'][$pluginid]);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\t$methods = get_class_methods($classname);\n\t\t\t\tif(property_exists($_PLUGIN['obj'][$pluginid], 'version')){\n\t\t\t\t\t$version = $_PLUGIN['obj'][$pluginid]->version;\n\t\t\t\t\tif($version && $plugin['ver'] != $version){\n\t\t\t\t\t\tif(method_exists($_PLUGIN['obj'][$pluginid], 'on_upgrade')){\n\t\t\t\t\t\t\t$return_ver = $_PLUGIN['obj'][$pluginid]->on_upgrade($plugin['ver']);\n\t\t\t\t\t\t\tif($return_ver){\n\t\t\t\t\t\t\t\tDB::query(\"UPDATE `plugin` SET `version`='{$return_ver}' WHERE name='{$pluginid}'\");\n\t\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\t\tDB::query(\"UPDATE `plugin` SET `version`='{$version}' WHERE name='{$pluginid}'\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}else{\n\t\t\t\t\t\t\tDB::query(\"UPDATE `plugin` SET `version`='{$version}' WHERE name='{$pluginid}'\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Reload cron scripts\n\t\t\t\t\t\tDB::query(\"DELETE FROM cron WHERE id LIKE '%\".$pluginid.\"%'\");\n\t\t\t\t\t\tforeach($_PLUGIN['obj'][$pluginid]->modules as $module){\n\t\t\t\t\t\t\tif($module['type'] == 'cron'){\n\t\t\t\t\t\t\t\tDB::insert('cron', array_merge($module['cron'], array('nextrun' => TIMESTAMP)), false, true);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tCACHE::update('plugins');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tforeach ($methods as $method) $_PLUGIN['hook'][$method][] = $pluginid;\n\t\t\t\tif(method_exists($_PLUGIN['obj'][$pluginid], 'getMethods')) $_PLUGIN['obj'][$pluginid]->modules = $_PLUGIN['obj'][$pluginid]->getMethods();\n\t\t\t\tif(method_exists($_PLUGIN['obj'][$pluginid], 'getModules')) $_PLUGIN['obj'][$pluginid]->modules = $_PLUGIN['obj'][$pluginid]->getModules();\n\t\t\t\tforeach ($_PLUGIN['obj'][$pluginid]->modules as $module) self::parse_module($module, $pluginid);\n\t\t\t}\n\t\t}\n\t}\n\tpublic static function parse_module($module, $pluginid){\n\t\tglobal $_PLUGIN;\n\t\tswitch ($module['type']){\n\t\t\tcase 'page':\n\t\t\t\t$_PLUGIN['page'][] = array(\n\t\t\t\t\t'id' => \"{$pluginid}-{$module[id]}\",\n\t\t\t\t\t'title' => $module['title'],\n\t\t\t\t\t'file' => ROOT.\"./plugins/{$pluginid}/\".$module['file'],\n\t\t\t\t\t'admin' => $module['admin'],\n\t\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase 'shortcut':\n\t\t\t\t$_PLUGIN['shortcut'][] = array(\n\t\t\t\t\t'title' => $module['title'],\n\t\t\t\t\t'link' => $module['link'],\n\t\t\t\t\t'admin' => $module['admin'],\n\t\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase 'cron':\n\t\t\t\tbreak;\n\t\t\tdefault: throw new Exception('Unknown module type: '.$module['type']);\n\t\t}\n\t}\n\tpublic static function page_menu(){\n\t\tglobal $_PLUGIN, $uid;\n\t\tif($_PLUGIN['page']){\n\t\t\tforeach ($_PLUGIN['page'] as $page){\n\t\t\t\tif($page['admin'] && !is_admin($uid)) continue;\n\t\t\t\techo \"<li id=\\\"menu_{$page[id]}\\\"><a href=\\\"#{$page[id]}\\\">{$page[title]}</a></li>\";\n\t\t\t}\n\t\t}\n\t\tif($_PLUGIN['shortcut']){\n\t\t\tforeach ($_PLUGIN['shortcut'] as $page){\n\t\t\t\tif($page['admin'] && !is_admin($uid)) continue;\n\t\t\t\techo \"<li><a href=\\\"{$page[link]}\\\">{$page[title]}</a></li>\";\n\t\t\t}\n\t\t}\n\t}\n\tpublic static function page_contents(){\n\t\tglobal $_PLUGIN, $uid;\n\t\tif($_PLUGIN['page']){\n\t\t\tforeach($_PLUGIN['page'] as $page){\n\t\t\t\tif($page['admin'] && !is_admin($uid)) continue;\n\t\t\t\techo \"<div id=\\\"content-{$page[id]}\\\" class=\\\"hidden\\\">\";\n\t\t\t\t@include $page['file'];\n\t\t\t\techo \"</div>\\r\\n\";\n\t\t\t}\n\t\t}\n\t}\n\tpublic static function run($hookname, $ignore_unabled = false){\n\t\tglobal $_PLUGIN;\n\t\tif(defined('DISABLE_PLUGIN') && !$ignore_unabled) return;\n\t\t$hooks = $_PLUGIN['hook'][$hookname];\n\t\tif(!$hooks) return;\n\t\t$args = func_get_args();\n\t\tunset($args[0], $args[1]);\n\t\tforeach($hooks as $pluginid){\n\t\t\ttry{\n\t\t\t\techo call_user_func_array(array(&$_PLUGIN['obj'][$pluginid], $hookname), $args);\n\t\t\t}catch(Exception $e){\n\t\t\t\tkerror::exception_error($e);\n\t\t\t}\n\t\t}\n\t}\n\tpublic static function getPlugin($plugin_id){\n\t\tglobal $_PLUGIN;\n\t\tif($_PLUGIN['obj'][$plugin_id]){\n\t\t\treturn $_PLUGIN['obj'][$plugin_id];\n\t\t}elseif(defined('DISABLE_PLUGIN')){\n\t\t\t$classname = 'plugin_'.$plugin_id;\n\t\t\treturn $_PLUGIN['obj'][$plugin_id] = new $classname();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "system/class/kerror.php",
    "content": "<?php\nif (!defined('IN_KKFRAME')) exit();\nclass kerror {\n\tpublic static function system_error($message, $show = true, $halt = true) {\n\t\tlist($showtrace, $logtrace) = kerror::debug_backtrace();\n\t\tif ($show) {\n\t\t\tkerror::show_error('system', \"<li>$message</li>\", $showtrace, 0);\n\t\t}\n\t\tif ($halt) {\n\t\t\texit();\n\t\t} else {\n\t\t\treturn $message;\n\t\t}\n\t}\n\tpublic static function debug_backtrace() {\n\t\t$skipfunc[] = 'kerror->debug_backtrace';\n\t\t$skipfunc[] = 'kerror->db_error';\n\t\t$skipfunc[] = 'kerror->template_error';\n\t\t$skipfunc[] = 'kerror->system_error';\n\t\t$skipfunc[] = 'db_mysql->halt';\n\t\t$skipfunc[] = 'db_mysql->query';\n\t\t$skipfunc[] = 'DB::_execute';\n\t\t$show = $log = '';\n\t\t$debug_backtrace = debug_backtrace();\n\t\tkrsort($debug_backtrace);\n\t\tforeach ($debug_backtrace as $k => $error) {\n\t\t\t$file = str_replace(ROOT, '', $error['file']);\n\t\t\t$func = isset($error['class']) ? $error['class'] : '';\n\t\t\t$func .= isset($error['type']) ? $error['type'] : '';\n\t\t\t$func .= isset($error['function']) ? $error['function'] : '';\n\t\t\tif (in_array($func, $skipfunc)) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$error[line] = sprintf('%04d', $error['line']);\n\t\t\t$show .= \"<li>[Line: $error[line]]\".$file.\"($func)</li>\";\n\t\t\t$log .= !empty($log) ? '->' : '';\n\t\t\t$file.':'.$error['line'];\n\t\t\t$log .= $file.':'.$error['line'];\n\t\t}\n\t\treturn array($show, $log);\n\t}\n\tpublic static function db_error($message, $sql) {\n\t\tglobal $_G;\n\t\tlist($showtrace, $logtrace) = kerror::debug_backtrace();\n\t\t$db = &DB::object();\n\t\t$dberrno = $db->errno();\n\t\t$dberror = str_replace($db->tablepre, '', $db->error());\n\t\t$sql = htmlspecialchars(str_replace($db->tablepre, '', $sql));\n\t\t$msg = '<li>'.$message.'</li>';\n\t\t$msg .= $dberrno ? '<li>['.$dberrno.'] '.$dberror.'</li>' : '';\n\t\t$msg .= $sql ? '<li>[Query] '.$sql.'</li>' : '';\n\t\tkerror::show_error('db', $msg, $showtrace, false);\n\t\texit();\n\t}\n\tpublic static function exception_error($exception) {\n\t\tif ($exception instanceof DbException) {\n\t\t\t$type = 'db';\n\t\t} else {\n\t\t\t$type = 'system';\n\t\t}\n\t\tif ($type == 'db') {\n\t\t\t$errormsg = '('.$exception->getCode().') ';\n\t\t\t$errormsg .= self::sql_clear($exception->getMessage());\n\t\t\tif ($exception->getSql()) {\n\t\t\t\t$errormsg .= '<div class=\"sql\">';\n\t\t\t\t$errormsg .= self::sql_clear($exception->getSql());\n\t\t\t\t$errormsg .= '</div>';\n\t\t\t}\n\t\t} else {\n\t\t\t$errormsg = $exception->getMessage();\n\t\t}\n\t\t$trace = $exception->getTrace();\n\t\tkrsort($trace);\n\t\t$trace[] = array('file' => $exception->getFile(), 'line' => $exception->getLine(), 'function' => 'ErrorHandler');\n\t\t$phpmsg = array();\n\t\tforeach ($trace as $error) {\n\t\t\tif (!empty($error['function'])) {\n\t\t\t\t$fun = '';\n\t\t\t\tif (!empty($error['class'])) {\n\t\t\t\t\t$fun .= $error['class'].$error['type'];\n\t\t\t\t}\n\t\t\t\t$fun .= $error['function'].'(';\n\t\t\t\tif (!empty($error['args'])) {\n\t\t\t\t\t$mark = '';\n\t\t\t\t\tforeach($error['args'] as $arg) {\n\t\t\t\t\t\t$fun .= $mark;\n\t\t\t\t\t\tif (is_array($arg)) {\n\t\t\t\t\t\t\t$fun .= 'Array';\n\t\t\t\t\t\t} elseif (is_bool($arg)) {\n\t\t\t\t\t\t\t$fun .= $arg ? 'true' : 'false';\n\t\t\t\t\t\t} elseif (is_int($arg)) {\n\t\t\t\t\t\t\t$fun .= (defined('DEBUG_FLAG') && DEBUG_FLAG) ? $arg : '%d';\n\t\t\t\t\t\t} elseif (is_float($arg)) {\n\t\t\t\t\t\t\t$fun .= (defined('DEBUG_FLAG') && DEBUG_FLAG) ? $arg : '%f';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$fun .= (defined('DEBUG_FLAG') && DEBUG_FLAG) ? '\\''.htmlspecialchars(substr(self::clear($arg), 0, 10)).(strlen($arg) > 10 ? ' ...' : '').'\\'' : '%s';\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$mark = ', ';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$fun .= ')';\n\t\t\t\t$error['function'] = $fun;\n\t\t\t}\n\t\t\t$phpmsg[] = array('file' => str_replace(array(ROOT, '\\\\'), array('', '/'), $error['file']), 'line' => $error['line'], 'function' => $error['function'],);\n\t\t}\n\t\tself::show_error($type, $errormsg, $phpmsg);\n\t\texit();\n\t}\n\tpublic static function show_error($type, $errormsg, $phpmsg = '', $exit = true) {\n\t\tob_end_clean();\n\t\tob_start();\n\t\t$host = $_SERVER['HTTP_HOST'];\n\t\t$title = $type == 'db' ? 'Database' : 'System';\n\t\techo <<<EOT\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><html><head><title>$host - $title Error</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><meta name=\"ROBOTS\" content=\"NOINDEX,NOFOLLOW,NOARCHIVE\" /><style type=\"text/css\"><!-- body { background-color: white; color: black; font: 9pt/11pt verdana, arial, sans-serif;} #container { width: 1024px; } #message { width: 1024px; color: black; } .red {color: red;} a:link { font: 9pt/11pt verdana, arial, sans-serif; color: red; } a:visited { font: 9pt/11pt verdana, arial, sans-serif; color: #4e4e4e; } h1 { color: #FF0000; font: 18pt \"Verdana\"; margin-bottom: 0.5em;} .bg1{ background-color: #FFFFCC;} .bg2{ background-color: #EEEEEE;} .table {background: #AAAAAA; font: 11pt Menlo,Consolas,\"Lucida Console\"} .info { background: none repeat scroll 0 0 #F3F3F3; border: 0px solid #aaaaaa; border-radius: 10px 10px 10px 10px; color: #000000; font-size: 11pt; line-height: 160%; margin-bottom: 1em; padding: 1em; } .help { background: #F3F3F3; border-radius: 10px 10px 10px 10px; font: 12px verdana, arial, sans-serif; text-align: center; line-height: 160%; padding: 1em; } .sql { background: none repeat scroll 0 0 #FFFFCC; border: 1px solid #aaaaaa; color: #000000; font: arial, sans-serif; font-size: 9pt; line-height: 160%; margin-top: 1em; padding: 4px; } --></style></head><body><div id=\"container\"><h1>KK Tieba Signer $title Error</h1><div class='info'>$errormsg</div>\nEOT;\n\t\tif (is_array($phpmsg) && !empty($phpmsg)) {\n\t\t\techo '<div class=\"info\">';\n\t\t\techo '<p><strong>PHP Debug</strong></p>';\n\t\t\techo '<table cellpadding=\"5\" cellspacing=\"1\" width=\"100%\" class=\"table\">';\n\t\t\techo '<tr class=\"bg2\"><td>No.</td><td>File</td><td>Line</td><td>Code</td></tr>';\n\t\t\tforeach($phpmsg as $k => $msg) {\n\t\t\t\t$k++;\n\t\t\t\techo '<tr class=\"bg1\">';\n\t\t\t\techo '<td>'.$k.'</td>';\n\t\t\t\techo '<td>'.$msg['file'].'</td>';\n\t\t\t\techo '<td>'.$msg['line'].'</td>';\n\t\t\t\techo '<td>'.$msg['function'].'</td>';\n\t\t\t\techo '</tr>';\n\t\t\t}\n\t\t\techo '</table></div>';\n\t\t}\n\t\techo '</div></body></html>';\n\t\t$exit && exit();\n\t}\n\tpublic static function clear($message) {\n\t\treturn str_replace(array(\"\\t\", \"\\r\", \"\\n\"), \" \", $message);\n\t}\n\tpublic static function sql_clear($message) {\n\t\t$message = self::clear($message);\n\t\t$message = str_replace(DB::object()->tablepre, '', $message);\n\t\t$message = htmlspecialchars($message);\n\t\treturn $message;\n\t}\n}\n"
  },
  {
    "path": "system/class/mail/phpmail.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\n\nclass phpmail extends mailer{\n\tvar $id = 'phpmail';\n\tvar $name = 'PHP Mail()';\n\tvar $description = '通过 PHP 的 Mail() 函数发送邮件';\n\tvar $config = array(\n\t\tarray('发件人地址', 'from', '', 'system@domain.com'),\n\t);\n\tfunction isAvailable(){\n\t\treturn function_exists('mail');\n\t}\n\tfunction send($mail){\n\t\t$address = $mail->address;\n\t\t$headers  = \"MIME-Version: 1.0\\r\\n\";\n\t\t$headers .= \"Content-Type: text/html;charset=utf-8\\r\\n\";\n\t\t$headers .= \"Content-Transfer-Encoding: Base64\\r\\n\";\n\t\t$headers .= 'From: =?UTF-8?B?'.base64_encode('贴吧签到助手').'?= <'.$this->_get_setting('from').\">\\r\\n\";\n\t\treturn mail($address, '=?UTF-8?B?'.base64_encode($mail->subject).'?=', base64_encode($mail->message), $headers);\n\t}\n}\n\n?>"
  },
  {
    "path": "system/class/mail/saemail.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\n\nclass saemail extends mailer{\n\tvar $id = 'saemail';\n\tvar $name = 'SAE SMTP 类';\n\tvar $description = 'SAE 用户可用，通过 SAE 的 SMTP 类发送邮件';\n\tvar $config = array(\n\t\tarray('SMTP 服务器地址', 'smtp_server', '', ''),\n\t\tarray('发送者邮箱地址', 'address', '', '', 'email'),\n\t\tarray('SMTP 用户名', 'smtp_name', '', ''),\n\t\tarray('SMTP 密码', 'smtp_pass', '', '', 'password'),\n\t);\n\tfunction isAvailable(){\n\t\treturn defined('IN_SAE');\n\t}\n\tfunction send($mail){\n\t\t$saemail = new SaeMail();\n\t\t$saemail->setOpt(array(\n\t\t\t'from' => '贴吧签到助手 <'.$this->_get_setting('address').'>',\n\t\t\t'to' => $mail->address,\n\t\t\t'smtp_host' => $this->_get_setting('smtp_server'),\n\t\t\t'smtp_username' => $this->_get_setting('smtp_name'),\n\t\t\t'smtp_password' => $this->_get_setting('smtp_pass'),\n\t\t\t'subject' => $mail->subject,\n\t\t\t'content' => $mail->message,\n\t\t\t'content_type' => 'HTML',\n\t\t));\n\t\t$saemail->send();\n\t\treturn true;\n\t}\n}\n\n?>"
  },
  {
    "path": "system/class/mail/smtp.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\n\nclass smtp extends mailer{\n\tvar $id = 'smtp';\n\tvar $name = 'SMTP - Socket';\n\tvar $description = '通过 Socket 连接 SMTP 服务器发邮件';\n\tvar $config = array(\n\t\tarray('SMTP 服务器地址', 'smtp_server', '', ''),\n\t\tarray('发送者邮箱地址', 'address', '', '', 'email'),\n\t\tarray('SMTP 用户名', 'smtp_name', '', ''),\n\t\tarray('SMTP 密码', 'smtp_pass', '', '', 'password'),\n\t);\n\tfunction isAvailable(){\n\t\treturn !isset($_SERVER['HTTP_APPVERSION']) && $_SERVER['USER'] != 'bae';\n\t}\n\tfunction send($mail){\n\t\t$smtp = new _smtp($this);\n\t\treturn $smtp->send($mail->address, $mail->subject, $mail->message);\n\t}\n}\n\nclass _smtp {\n\tprivate $smtpServer = '';\n\tprivate $port = '25';\n\tprivate $timeout = '45';\n\tprivate $username = '';\n\tprivate $password = '';\n\tprivate $address = '';\n\tprivate $newline = \"\\r\\n\";\n\tprivate $localdomain = 'localhost';\n\tprivate $charset = 'utf-8';\n\tprivate $contentTransferEncoding = false;\n\tprivate $debug = false;\n\n\tprivate $smtpConnect = false;\n\tprivate $to = false;\n\tprivate $subject = false;\n\tprivate $message = false;\n\tprivate $headers = false;\n\tprivate $logArray = array();\n\tpublic $Error = '';\n\n\tpublic function _smtp($obj){\n\t\t$this->smtpServer = $obj->_get_setting('smtp_server');\n\t\t$this->address = $obj->_get_setting('address');\n\t\t$this->username = $obj->_get_setting('smtp_name');\n\t\t$this->password = $obj->_get_setting('smtp_pass');\n\t}\n\n\tpublic function send($to, $subject, $message) {\n\t\tglobal $_config;\n\t\t$this->to = &$to;\n\t\t$this->subject = &$subject;\n\t\t$this->message = &$message;\n\n\t\tif(!$this->Connect2Server()) {\n\t\t\tif(!$this->debug) return false;\n\t\t\techo $this->Error.$this->newline.'<!-- '.$this->newline;\n\t\t\tprint_r($this->logArray);\n\t\t\techo $this->newline.'-->'.$this->newline;\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\tprivate function Connect2Server() {\n\t\t$this->smtpConnect = fsockopen($this->smtpServer, $this->port, $errno, $error, $this->timeout);\n\t\t$this->logArray['CONNECT_RESPONSE'] = $this->readResponse();\n\t\tif (!is_resource($this->smtpConnect)) return false;\n\t\t$this->logArray['connection'] = 'Connection accepted: '.$this->readResponse();\n\t\t$this->sendCommand(\"EHLO {$this->localdomain}\");\n\t\t$this->logArray['EHLO'] = $this->readResponse();\n\t\t$this->sendCommand('AUTH LOGIN');\n\t\t$this->logArray['AUTH_REQUEST'] = $this->readResponse();\n\t\t$this->sendCommand(base64_encode($this->username));\n\t\t$this->logArray['REQUEST_USER'] = $this->readResponse();\n\t\t$this->sendCommand(base64_encode($this->password));\n\t\t$this->logArray['REQUEST_PASSWD'] = $this->readResponse();\n\t\tif (substr($this->logArray['REQUEST_PASSWD'], 0, 3)!='235') {\n\t\t\t$this->Error .= 'Authorization error! '.$this->logArray['REQUEST_PASSWD'].$this->newline;\n\t\t\treturn false;\n\t\t}\n\t\t$this->sendCommand(\"MAIL FROM: {$this->address}\");\n\t\t$this->logArray['MAIL_FROM_RESPONSE'] = $this->readResponse();\n\t\tif (substr($this->logArray['MAIL_FROM_RESPONSE'], 0, 3)!='250') {\n\t\t\t$this->Error .= 'Mistake in sender\\'s address! '.$this->logArray['MAIL_FROM_RESPONSE'].$this->newline;\n\t\t\treturn false;\n\t\t}\n\t\t$this->sendCommand(\"RCPT TO: {$this->to}\");\n\t\t$this->logArray['RCPT_TO_RESPONCE'] = $this->readResponse();\n\t\tif (substr($this->logArray['RCPT_TO_RESPONCE'], 0, 3)!='250') {\n\t\t\t$this->Error .= 'Mistake in reciepent address! '.$this->logArray['RCPT_TO_RESPONCE'].$this->newline;\n\t\t}\n\t\t$this->sendCommand('DATA');\n\t\t$this->logArray['DATA_RESPONSE'] = $this->readResponse();\n\t\tif (!$this->sendMail()) return false;\n\t\t$this->sendCommand('QUIT');\n\t\t$this->logArray['QUIT_RESPONSE'] = $this->readResponse();\n\t\tfclose($this->smtpConnect);\n\t\treturn true;\n\t}\n\tprivate function sendMail() {\n\t\t$this->sendHeaders();\n\t\t$this->sendCommand($this->message);\n\t\t$this->sendCommand('.');\n\t\t$this->logArray['SEND_DATA_RESPONSE'] = $this->readResponse();\n\t\tif(substr($this->logArray['SEND_DATA_RESPONSE'], 0, 3)!='250') {\n\t\t\t$this->Error .= 'Mistake in sending data! '.$this->logArray['SEND_DATA_RESPONSE'].$this->newline;\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\tprivate function readResponse() {\n\t\t$data = '';\n\t\twhile($str = fgets($this->smtpConnect, 4096)) {\n\t\t\t$data .= $str;\n\t\t\tif(substr($str, 3, 1) == \" \") { break; }\n\t\t}\n\t\treturn $data;\n\t}\n\tprivate function sendCommand($string) {\n\t\tfputs($this->smtpConnect, $string.$this->newline);\n\t\treturn ;\n\t}\n\tprivate function sendHeaders() {\n\t\t$this->sendCommand('Date: '.date('D, j M Y G:i:s').' +0700');\n\t\t$this->sendCommand(\"From: <{$this->address}>\");\n\t\t$this->sendCommand(\"Reply-To: <{$this->address}>\");\n\t\t$this->sendCommand(\"To: <{$this->to}>\");\n\t\t$this->sendCommand(\"Subject: {$this->subject}\");\n\t\t$this->sendCommand('MIME-Version: 1.0');\n\t\t$this->sendCommand(\"Content-Type: text/html; charset={$this->charset}\");\n\t\tif ($this->contentTransferEncoding) $this->sendCommand(\"Content-Transfer-Encoding: {$this->contentTransferEncoding}\");\n\t\t$this->sendCommand($this->newline);\n\t\treturn ;\n\t}\n\tpublic function __destruct() {\n\t\tif (is_resource($this->smtpConnect)) fclose($this->smtpConnect);\n\t}\n}\n\n?>"
  },
  {
    "path": "system/class/mail.php",
    "content": "<?php\nif (!defined('IN_KKFRAME')) exit();\nclass mailer {\n\tvar $_setting;\n\tfunction isAvailable() {\n\t\treturn false;\n\t}\n\tfunction send() {\n\t\treturn false;\n\t}\n\tfunction _get_setting($key) {\n\t\tif (!$this->_setting) $this->_load_setting();\n\t\treturn $this->_setting[$key];\n\t}\n\tfunction _load_setting() {\n\t\t$this->_setting = CACHE::get('mail_'.$this->id);\n\t\tif ($this->_setting) return;\n\t\t$this->_setting = array();\n\t\tif ($this->config) {\n\t\t\tforeach($this->config as $k => $v) {\n\t\t\t\t$this->_setting[ $v[1] ] = $v[3];\n\t\t\t}\n\t\t}\n\t\t$class = getSetting('mail_class');\n\t\t$query = DB::query(\"SELECT * FROM setting WHERE k LIKE '_mail_{$class}_%'\");\n\t\twhile ($result = DB::fetch($query)) {\n\t\t\t$key = str_replace(\"_mail_{$class}_\", '', $result['k']);\n\t\t\t$this->_setting[$key] = $result['v'];\n\t\t}\n\t\tCACHE::save('mail_'.$this->id, $this->_setting);\n\t}\n}\nclass mail_content {\n\tvar $address;\n\tvar $subject;\n\tvar $message;\n}\nclass mail_sender {\n\tvar $obj;\n\tfunction __construct() {\n\t\t$sender = getSetting('mail_class');\n\t\t$file = SYSTEM_ROOT.\"./class/mail/{$sender}.php\";\n\t\tif (file_exists($file)) {\n\t\t\trequire_once $file;\n\t\t\t$this->obj = new $sender();\n\t\t}\n\t}\n\tfunction sendMail($mail) {\n\t\tif (!$this->obj) return false;\n\t\treturn $this->obj->send($mail);\n\t}\n}\n"
  },
  {
    "path": "system/class/multithread.php",
    "content": "<?php\nif (!defined('IN_KKFRAME')) exit();\n\nclass MultiThread {\n\tpublic static function registerThread($max_thread = 6, $ttl = 30){\n\t\t$time = TIMESTAMP;\n\t\t$threadCount = DB::result_first(\"SELECT COUNT(*) FROM process WHERE exptime >= '{$time}'\");\n\t\tif($threadCount >= $max_thread) return false;\n\t\tDB::query(\"DELETE FROM process WHERE exptime < '{$time}'\");\n\t\t$time += $ttl;\n\t\t$pid = random(16);\n\t\tDB::query(\"INSERT INTO process SET exptime='{$time}', id='{$pid}'\");\n\t\treturn true;\n\t}\n\tpublic static function newCronThread(){\n\t\tglobal $siteurl, $real_siteurl;\n\t\t$url = $real_siteurl ? $real_siteurl : $siteurl;\n\t\t$matches = parse_url($url);\n\t\t$host = $matches['host'];\n\t\t$port = !empty($matches['port']) ? $matches['port'] : 80;\n\t\t$path = $matches['path'] ? $matches['path'] : '/';\n\t\t$header = \"GET {$path}cron.php HTTP/1.0\\r\\n\";\n\t\t$header .= \"Accept: */*\\r\\n\";\n\t\t$header .= \"Host: {$host}:{$port}\\r\\n\";\n\t\t$header .= \"Connection: Close\\r\\n\\r\\n\";\n\t\t$fp = fsocketopen($host, $port);\n\t\tif(!$fp) return false;\n\t\tstream_set_timeout($fp, 1);\n\t\t@fwrite($fp, $header);\n\t\t@fgets($fp);\n\t\tfclose($fp);\n\t\treturn true;\n\t}\n}"
  },
  {
    "path": "system/class/plugin.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\nclass Plugin {\n\tvar $name;\n\tvar $description;\n\tvar $modules = array();\n\tvar $permission = array();\n\tvar $version = '0';\n\tfunction getSetting($key, $default_value = false){\n\t\t$vars = CACHE::get('plugin');\n\t\t$vars = $vars[ $this->getPluginId() ];\n\t\treturn isset($vars[$key]) ? $vars[$key] : $default_value;\n\t}\n\tfunction saveSetting($key, $value){\n\t\t$pluginid = $this->getPluginId();\n\t\t$vars = CACHE::get('plugin');\n\t\tif(!$vars) $vars = array();\n\t\tif(!$vars[ $pluginid ]) $vars[ $pluginid ] = array();\n\t\t$vars[ $pluginid ][ $key ] = $value;\n\t\tDB::query(\"REPLACE INTO plugin_var SET `key` = '\".addslashes($key).\"', `value` = '\".addslashes($value).\"', pluginid='\".addslashes($pluginid).\"'\");\n\t\tCACHE::clean('plugin');\n\t}\n\tfunction checkCompatibility(){\n\t\treturn true;\n\t}\n\tfunction install(){\n\t\t// install script\n\t}\n\tfunction uninstall(){\n\t\t// uninstall script\n\t}\n\tfunction handleAction(){\n\t\tthrow new Exception('This plugin doesn\\'t support to be called directly.');\n\t}\n\tprivate function getPluginId(){\n\t\treturn str_replace('plugin_', '', get_class($this));\n\t}\n}\n"
  },
  {
    "path": "system/class/updater.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nclass Updater{\n\tconst UPDATE_SERVER = 'http://update.ikk.me/';\n\tpublic static function init(){\n\t\tglobal $_config;\n\t\tif($_config['version']){\n\t\t\t$current_version = $_config['version'];\n\t\t} else {\n\t\t\t$current_version = getSetting('version');\n\t\t}\n\t\tif ($current_version == VERSION) return;\n\t\t$version = $current_version;\n\t\twhile($version){\n\t\t\t$filepath = SYSTEM_ROOT.\"./function/updater/{$version}.php\";\n\t\t\tif(file_exists($filepath)){\n\t\t\t\tinclude $filepath;\n\t\t\t\texit();\n\t\t\t} else{\n\t\t\t\t$version = substr($version, 0, strrpos($version, '.'));\n\t\t\t}\n\t\t}\n\t\tinclude SYSTEM_ROOT.'./function/updater/fallback.php';\n\t\texit();\n\t}\n\tpublic static function check(){\n\t\t$d = getSetting('channel') == 'dev' ? 'tieba_sign' : 'tieba_sign_stable';\n\t\t$p = implode(',', self::_getPluginList());\n\t\t$data = kk_fetch_url(self::UPDATE_SERVER.\"filelist.php?d={$d}&plugins={$p}\");\n\t\tsaveSetting('new_version', 0);\n\t\tif (!$data) return -1;\n\t\t$content = pack('H*', $data);\n\t\t$file_list = unserialize($content);\n\t\tunset($content);\n\t\tif (!$file_list) return -2;\n\t\t$err_file = $list = array();\n\t\tforeach($file_list as $file) {\n\t\t\tlist($path, $hash) = explode(\"\\t\", $file);\n\t\t\t$file_hash = md5_file(ROOT.\"./{$path}\");\n\t\t\tif ($file_hash != $hash){\n\t\t\t\t$err_file[] = array($path, $hash);\n\t\t\t\t$list[] = $path;\n\t\t\t}\n\t\t}\n\t\tif(!$list) return 0;\n\t\tsaveSetting('new_version', 1);\n\t\tsort($list);\n\t\tsort($err_file);\n\t\tCACHE::save('kk_updater', $err_file);\n\t\tCACHE::save('need_download', $err_file);\n\t\tDB::query('DELETE FROM download');\n\t\treturn $list;\n\t}\n\tpublic static function loop(){\n\t\tif(defined('IN_XAE')) return array('status' => -3);\n\t\t$file_list = CACHE::get('need_download');\n\t\tlist($path, $hash) = array_pop($file_list);\n\t\tif(!$path) return array('status' => 1);\n\t\t$ret = self::_download_file($path, $hash);\n\t\tif ($ret<0) return array('status' => $ret, 'file' => $path);\n\t\tCACHE::save('need_download', $file_list);\n\t\t$max = sizeof(CACHE::get('kk_updater'));\n\t\t$current = $max - sizeof($file_list);\n\t\treturn array('status' => 0, 'precent' => round($current / $max * 100), 'file' => $path);\n\t}\n\tpublic static function write_file(){\n\t\t$err_file = $files = array();\n\t\t$query = DB::query('SELECT * FROM download ORDER BY path ASC');\n\t\twhile($file = DB::fetch($query)){\n\t\t\tlist($part, $path) = explode('|', $file['path'], 2);\n\t\t\tif(!$files[ $path ]){\n\t\t\t\t$file['content'] = pack('H*', $file['content']);\n\t\t\t\t$files[ $path ] = $file;\n\t\t\t} else {\n\t\t\t\t$files[ $path ]['content'] .= pack('H*', $file['content']);\n\t\t\t}\n\t\t}\n\t\tif(!$files) return array('status' => -255);\n\t\tforeach($files as $path => $file) {\n\t\t\tif(!self::_is_writable(ROOT.$path)) $err_file[] = $path;\n\t\t}\n\t\tif($err_file) array('status' => -1, 'files' => $err_file);\n\t\tforeach($files as $path => $file) {\n\t\t\tself::_write(ROOT.$path, $file['content']);\n\t\t\tif(md5_file(ROOT.$path) != md5($file['content'])) return array('status' => -2, 'file' => $path);\n\t\t}\n\t\tDB::query('DELETE FROM download');\n\t\tsaveSetting('new_version', 0);\n\t\treturn array('status' => 0);\n\t}\n\tprivate static function _write($path, $content){\n\t\t$fp = @fopen($path, 'wb');\n\t\tif(!$fp) return false;\n\t\tfwrite($fp, $content);\n\t\tfclose($fp);\n\t\treturn true;\n\t}\n\tprivate static function _is_writable($path){\n\t\tif(!file_exists($path)){\n\t\t\tif(!file_exists(dirname($path))) @mkdir(dirname($path), 0777, true);\n\t\t\t@touch($path);\n\t\t\t@chmod($path, 0777);\n\t\t}else{\n\t\t\tif(!is_writable($path)) @chmod($path, 0777);\n\t\t}\n\t\treturn is_writable($path);\n\t}\n\tprivate static function _download_file($path, $hash, $try = 1) {\n\t\t$d = getSetting('channel') == 'dev' ? 'tieba_sign' : 'tieba_sign_stable';\n\t\t$content = kk_fetch_url(self::UPDATE_SERVER.\"get_file.php?d={$d}&f={$path}\");\n\t\tif (!$content) {\n\t\t\tif ($try == 3) {\n\t\t\t\treturn -1;\n\t\t\t} else {\n\t\t\t\treturn self::_download_file($path, $hash, $try + 1);\n\t\t\t}\n\t\t}\n\t\tif (md5($content) != $hash) {\n\t\t\tif ($try == 3) {\n\t\t\t\treturn -2;\n\t\t\t} else {\n\t\t\t\treturn self::_download_file($path, $hash, $try + 1);\n\t\t\t}\n\t\t}\n\t\t$length = $part = 0;\n\t\twhile($length < strlen($content)){\n\t\t\t$part++;\n\t\t\t$part_length = strlen($content) - $length > 8192 ? 8192 : strlen($content) - $length;\n\t\t\t$_countent = substr($content, $length, $part_length);\n\t\t\t$length += $part_length;\n\t\t\t$_part = str_pad($part, 4, \"0\", STR_PAD_LEFT);\n\t\t\tDB::insert('download', array('path' => \"{$_part}|\".$path, 'content' => bin2hex($_countent)));\n\t\t}\n\t\treturn 0;\n\t}\n\tprivate static function _getPluginList(){\n\t\t$pluginList = array();\n\t\t$list_dir = dir(ROOT.'./plugins/');\n\t\twhile($dirName = $list_dir->read()){\n\t\t\tif($dirName == '.' || $dirName == '..' || !is_dir(ROOT.\"./plugins/{$dirName}\")) continue;\n\t\t\t$pluginList[] = $dirName;\n\t\t}\n\t\treturn $pluginList;\n\t}\n}\n?>"
  },
  {
    "path": "system/class/widget/widget_password.php",
    "content": "<?php\nif (!defined('IN_KKFRAME')) exit();\nclass Widget_Password {\n\tconst ENCRYPT_TYPE_DEFAULT = '0';\n\tconst ENCRYPT_TYPE_ENHANCE = '1';\n\tconst ENCRYPT_TYPE_3MD5 = '2';\n\tfunction verify($user, $password){\n\t\tlist($user_password, $encrypt_type) = explode('T', $user['password']);\n\t\tif($encrypt_type === self::ENCRYPT_TYPE_DEFAULT){\n\t\t\treturn $user_password === md5(ENCRYPT_KEY.md5($password).ENCRYPT_KEY);\n\t\t}elseif($encrypt_type === self::ENCRYPT_TYPE_ENHANCE){\n\t\t\t$salt = substr(md5($user['uid'].$user['username'].ENCRYPT_KEY), 8, 16);\n\t\t\treturn $user_password === substr(md5(md5($password).$salt), 0, 30);\n\t\t}elseif($encrypt_type === self::ENCRYPT_TYPE_3MD5){\n\t\t\treturn $user_password === md5(md5(md5($password)));\n\t\t}else{\n\t\t\treturn password_verify($password, $user['password']);\n\t\t}\n\t}\n\tfunction encrypt($user, $password){\n\t\treturn password_hash($password, PASSWORD_BCRYPT);\n\t}\n}\n"
  },
  {
    "path": "system/class/xmlparse.php",
    "content": "<?php\nif (!defined('IN_KKFRAME')) exit();\n\nclass XMLparse {\n\tvar $parser;\n\tvar $document;\n\tvar $stack;\n\tvar $data;\n\tvar $last_opened_tag;\n\tvar $isnormal;\n\tvar $attrs = array();\n\tvar $failed = FALSE;\n\n\tfunction __construct($isnormal) {\n\t\t$this->XMLparse($isnormal);\n\t}\n\n\tfunction XMLparse($isnormal) {\n\t\t$this->isnormal = $isnormal;\n\t\t$this->parser = xml_parser_create('UTF-8');\n\t\txml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);\n\t\txml_set_object($this->parser, $this);\n\t\txml_set_element_handler($this->parser, 'open','close');\n\t\txml_set_character_data_handler($this->parser, 'data');\n\t}\n\n\tfunction destruct() {\n\t\txml_parser_free($this->parser);\n\t}\n\n\tfunction parse(&$data) {\n\t\t$this->document = array();\n\t\t$this->stack\t= array();\n\t\treturn xml_parse($this->parser, $data, true) && !$this->failed ? $this->document : '';\n\t}\n\n\tfunction open(&$parser, $tag, $attributes) {\n\t\t$this->data = '';\n\t\t$this->failed = FALSE;\n\t\tif(!$this->isnormal) {\n\t\t\tif(isset($attributes['id']) && !is_string($this->document[$attributes['id']])) {\n\t\t\t\t$this->document  = &$this->document[$attributes['id']];\n\t\t\t} else {\n\t\t\t\t$this->failed = TRUE;\n\t\t\t}\n\t\t} else {\n\t\t\tif(!isset($this->document[$tag]) || !is_string($this->document[$tag])) {\n\t\t\t\t$this->document  = &$this->document[$tag];\n\t\t\t} else {\n\t\t\t\t$this->failed = TRUE;\n\t\t\t}\n\t\t}\n\t\t$this->stack[] = &$this->document;\n\t\t$this->last_opened_tag = $tag;\n\t\t$this->attrs = $attributes;\n\t}\n\n\tfunction data(&$parser, $data) {\n\t\tif($this->last_opened_tag != NULL) {\n\t\t\t$this->data .= $data;\n\t\t}\n\t}\n\n\tfunction close(&$parser, $tag) {\n\t\tif($this->last_opened_tag == $tag) {\n\t\t\t$this->document = $this->data;\n\t\t\t$this->last_opened_tag = NULL;\n\t\t}\n\t\tarray_pop($this->stack);\n\t\tif($this->stack) {\n\t\t\t$this->document = &$this->stack[count($this->stack)-1];\n\t\t}\n\t}\n}\n\n?>"
  },
  {
    "path": "system/common.inc.php",
    "content": "<?php\nerror_reporting(E_ALL ^ E_NOTICE);\ndefine('IN_KKFRAME', true);\ndefine('SYSTEM_ROOT', dirname(__FILE__).'/');\ndefine('ROOT', dirname(SYSTEM_ROOT).'/');\ndefine('TIMESTAMP', time());\ndefine('VERSION', '1.16.7.10');\ndefine('UI_VERSION', '1.0');\n\ndefine('DEBUG_ENABLED', isset($_GET['debug']));\nerror_reporting(DEBUG_ENABLED ? E_ALL & !E_NOTICE & !E_STRICT : E_ERROR | E_PARSE);\n@ini_set('display_errors', DEBUG_ENABLED);\n\nrequire_once SYSTEM_ROOT.'./class/kerror.php';\nset_exception_handler(array('kerror', 'exception_error'));\n\nfunction class_loader($class_name){\n\tlist($type, $plugin_id) = explode('_', strtolower($class_name), 2);\n\tif ($type == 'plugin' && $plugin_id) {\n\t\t$file_path = \"plugins/{$plugin_id}/plugin.class.php\";\n\t} elseif ($type == 'widget') {\n\t\t$file_path = \"system/class/widget/{$class_name}.php\";\n\t} elseif ($type == 'mail' || $class_name == 'mailer') {\n\t\t$file_path = \"system/class/mail.php\";\n\t} else {\n\t\t$file_path = \"system/class/{$class_name}.php\";\n\t}\n\t$real_path = ROOT.strtolower($file_path);\n\tif (!file_exists($real_path)) {\n\t\tthrow new Exception('Ooops, system file is losing: '.strtolower($file_path));\n\t} else {\n\t\trequire_once $real_path;\n\t}\n}\n\nif (function_exists('spl_autoload_register')){\n\tspl_autoload_register('class_loader');\n}else{\n\tfunction __autoload($class_name){\n\t\tclass_loader($class_name);\n\t}\n}\n\nrequire_once SYSTEM_ROOT.'./function/core.php';\n\n// support for xae\nif(defined('SAE_ACCESSKEY')){\n\tdefine('IN_SAE', true);\n\tdefine('IN_XAE', true);\n\trequire_once SYSTEM_ROOT.'./function/sae.php';\n}\n\nif(!defined('IN_XAE') && !file_exists(SYSTEM_ROOT.'./config.inc.php')){\n\theader('Location: ./install/');\n\texit();\n}\n\n$system = new core();\n$system->init();\n$formhash = substr(md5(substr(TIMESTAMP, 0, -7).$username.$uid.ENCRYPT_KEY.ROOT), 8, 8);\n$sitepath = substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'));\n$siteurl = htmlspecialchars(($_SERVER['SERVER_PORT'] == '443' ? 'https://' : 'http://').$_SERVER['HTTP_HOST'].$sitepath.'/');\n"
  },
  {
    "path": "system/function/cache/cache_plugin.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n\n$cache = array();\n$query = DB::query(\"SELECT * FROM `plugin_var`\");\nwhile($result = DB::fetch($query)){\n\tif(!$cache[ $result['pluginid'] ]) $cache[ $result['pluginid'] ] = array();\n\t$cache[ $result['pluginid'] ][ $result['key'] ] = $result['value'];\n}\n"
  },
  {
    "path": "system/function/cache/cache_plugins.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n\n$query = DB::query(\"SELECT * FROM `plugin` WHERE `enable`='1'\");\nwhile($result = DB::fetch($query)){\n\t$cache[ $result['id'] ] = array('id' => $result['name'], 'ver' => $result['version']);\n}\n"
  },
  {
    "path": "system/function/cache/cache_setting.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n\n$query = DB::query('SELECT * FROM setting');\nwhile($result = DB::fetch($query)){\n\tif(strexists($result['v'], '_mail_')) continue;\n\t$cache[ $result['k'] ] = $result['v'];\n}\n"
  },
  {
    "path": "system/function/cache/cache_username.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n\n$query = DB::query(\"SELECT uid, username FROM member\");\nwhile($result = DB::fetch($query)){\n\t$cache[ $result['uid'] ] = $result['username'];\n}\n"
  },
  {
    "path": "system/function/core.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\nfunction is_admin($uid){\n\treturn in_array($uid, explode(',', getSetting('admin_uid')));\n}\nfunction is_email($string){\n\treturn preg_match('/^[A-z0-9._-]+@[A-z0-9._-]+\\.[A-z0-9._-]+$/', $string);\n}\nfunction dsetcookie($name, $value = '', $exp = 2592000){\n\t$exp = $value ? TIMESTAMP + $exp : '1';\n\tsetcookie($name, $value, $exp, '/');\n}\nfunction daddslashes($string, $force = 0, $strip = FALSE) {\n\t!defined('MAGIC_QUOTES_GPC') && define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());\n\tif(!MAGIC_QUOTES_GPC || $force) {\n\t\tif(is_array($string)) {\n\t\t\tforeach($string as $key => $val) {\n\t\t\t\t$string[$key] = daddslashes($val, $force, $strip);\n\t\t\t}\n\t\t} else {\n\t\t\t$string = addslashes($strip ? stripslashes($string) : $string);\n\t\t}\n\t}\n\treturn $string;\n}\nfunction template($file){\n\tglobal $template_loaded;\n\t$template_loaded = false;\n\tHOOK::run(str_replace('/', '_', \"template_load_{$file}\"));\n\t$template_name = defined('IN_ADMINCP') ? 'default' : getSetting('template');\n\tif(IN_MOBILE){\n\t\t$mobilefile = ROOT.\"./template/{$template_name}/mobile/{$file}.php\";\n\t\tif(file_exists($mobilefile)) return $mobilefile;\n\t\t$mobilefile_default = ROOT.\"./template/default/mobile/{$file}.php\";\n\t\tif(file_exists($mobilefile_default)) return $mobilefile_default;\n\t}\n\t$path = ROOT.\"./template/{$template_name}/{$file}.php\";\n\tif(file_exists($path)) return $path;\n\t$path = ROOT.\"./template/default/{$file}.php\";\n\tif(file_exists($path)) return $path;\n\terror::system_error(\"Missing template '{$file}'.\");\n}\nfunction dgmdate($timestamp, $d_format = 'Y-m-d H:i') {\n\t$timestamp += 8 * 3600;\n\t$todaytimestamp = TIMESTAMP - (TIMESTAMP + 8 * 3600) % 86400 + 8 * 3600;\n\t$s = gmdate($d_format, $timestamp);\n\t$time = TIMESTAMP + 8 * 3600 - $timestamp;\n\tif($timestamp >= $todaytimestamp) {\n\t\tif($time > 3600) {\n\t\t\treturn '<span title=\"'.$s.'\">'.intval($time / 3600).'&nbsp;小时前</span>';\n\t\t} elseif($time > 1800) {\n\t\t\treturn '<span title=\"'.$s.'\">半小时前</span>';\n\t\t} elseif($time > 60) {\n\t\t\treturn '<span title=\"'.$s.'\">'.intval($time / 60).'&nbsp;分钟前</span>';\n\t\t} elseif($time > 0) {\n\t\t\treturn '<span title=\"'.$s.'\">'.$time.'&nbsp;秒前</span>';\n\t\t} elseif($time == 0) {\n\t\t\treturn '<span title=\"'.$s.'\">刚刚</span>';\n\t\t} else {\n\t\t\treturn $s;\n\t\t}\n\t} elseif(($days = intval(($todaytimestamp - $timestamp) / 86400)) >= 0 && $days < 7) {\n\t\tif($days == 0) {\n\t\t\treturn '<span title=\"'.$s.'\">昨天&nbsp;'.gmdate('H:i', $timestamp).'</span>';\n\t\t} elseif($days == 1) {\n\t\t\treturn '<span title=\"'.$s.'\">前天&nbsp;'.gmdate('H:i', $timestamp).'</span>';\n\t\t} else {\n\t\t\treturn '<span title=\"'.$s.'\">'.($days + 1).'&nbsp;天前</span>';\n\t\t}\n\t} else {\n\t\treturn $s;\n\t}\n}\nfunction authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {\n\t$ckey_length = 4;\n\t$key = md5($key ? $key : ENCRYPT_KEY);\n\t$keya = md5(substr($key, 0, 16));\n\t$keyb = md5(substr($key, 16, 16));\n\t$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';\n\t$cryptkey = $keya.md5($keya.$keyc);\n\t$key_length = strlen($cryptkey);\n\t$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;\n\t$string_length = strlen($string);\n\t$result = '';\n\t$box = range(0, 255);\n\t$rndkey = array();\n\tfor($i = 0; $i <= 255; $i++) {\n\t\t$rndkey[$i] = ord($cryptkey[$i % $key_length]);\n\t}\n\tfor($j = $i = 0; $i < 256; $i++) {\n\t\t$j = ($j + $box[$i] + $rndkey[$i]) % 256;\n\t\t$tmp = $box[$i];\n\t\t$box[$i] = $box[$j];\n\t\t$box[$j] = $tmp;\n\t}\n\tfor($a = $j = $i = 0; $i < $string_length; $i++) {\n\t\t$a = ($a + 1) % 256;\n\t\t$j = ($j + $box[$a]) % 256;\n\t\t$tmp = $box[$a];\n\t\t$box[$a] = $box[$j];\n\t\t$box[$j] = $tmp;\n\t\t$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));\n\t}\n\tif($operation == 'DECODE') {\n\t\tif((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {\n\t\t\treturn substr($result, 26);\n\t\t} else {\n\t\t\treturn '';\n\t\t}\n\t} else {\n\t\treturn $keyc.str_replace('=', '', base64_encode($result));\n\t}\n}\nfunction showmessage($msg = '', $redirect = '', $delay = 3){\n\tif($_GET['format'] == 'json'){\n\t\t$result = array('msg' => $msg, 'redirect' => $redirect, 'delay' => $delay);\n\t\techo json_encode($result);\n\t\texit();\n\t}\n\tinclude template('message');\n\texit();\n}\nfunction random($length, $numeric = 0) {\n\t$seed = base_convert(md5(microtime().$_SERVER['DOCUMENT_ROOT']), 16, $numeric ? 10 : 35);\n\t$seed = $numeric ? (str_replace('0', '', $seed).'012340567890') : ($seed.'zZ'.strtoupper($seed));\n\t$hash = '';\n\t$max = strlen($seed) - 1;\n\tfor($i = 0; $i < $length; $i++) {\n\t\t$hash .= $seed{mt_rand(0, $max)};\n\t}\n\treturn $hash;\n}\nfunction dreferer(){\n\treturn $_SERVER['HTTP_REFERER'] && !strexists($_SERVER['HTTP_REFERER'], 'member') ? $_SERVER['HTTP_REFERER'] : './';\n}\nfunction strexists($string, $find) {\n\treturn !(strpos($string, $find) === FALSE);\n}\nfunction cutstr($string, $length, $dot = ' ...') {\n\tif(strlen($string) <= $length) return $string;\n\t$pre = chr(1);\n\t$end = chr(1);\n\t$string = str_replace(array('&amp;', '&quot;', '&lt;', '&gt;'), array($pre.'&'.$end, $pre.'\"'.$end, $pre.'<'.$end, $pre.'>'.$end), $string);\n\t$strcut = '';\n\t$n = $tn = $noc = 0;\n\twhile($n < strlen($string)) {\n\t\t$t = ord($string[$n]);\n\t\tif($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) {\n\t\t\t$tn = 1; $n++; $noc++;\n\t\t} elseif(194 <= $t && $t <= 223) {\n\t\t\t$tn = 2; $n += 2; $noc += 2;\n\t\t} elseif(224 <= $t && $t <= 239) {\n\t\t\t$tn = 3; $n += 3; $noc += 2;\n\t\t} elseif(240 <= $t && $t <= 247) {\n\t\t\t$tn = 4; $n += 4; $noc += 2;\n\t\t} elseif(248 <= $t && $t <= 251) {\n\t\t\t$tn = 5; $n += 5; $noc += 2;\n\t\t} elseif($t == 252 || $t == 253) {\n\t\t\t$tn = 6; $n += 6; $noc += 2;\n\t\t} else {\n\t\t\t$n++;\n\t\t}\n\t\tif($noc >= $length) break;\n\t}\n\tif($noc > $length) $n -= $tn;\n\t$strcut = substr($string, 0, $n);\n\t$strcut = str_replace(array($pre.'&'.$end, $pre.'\"'.$end, $pre.'<'.$end, $pre.'>'.$end), array('&amp;', '&quot;', '&lt;', '&gt;'), $strcut);\n\t$pos = strrpos($strcut, chr(1));\n\tif($pos !== false) $strcut = substr($strcut,0,$pos);\n\treturn $strcut.$dot;\n}\nfunction wrap_text($str) {\n\t$str = trim($str);\n\t$str = str_replace(\"\\t\", '', $str);\n\t$str = str_replace(\"\\r\", '', $str);\n\t$str = str_replace(\"\\n\", '', $str);\n\t$str = str_replace(' ', '', $str);\n    return trim($str);\n}\nfunction get_cookie($uid){\n\tstatic $cookie = array();\n\tif($cookie[$uid]) return $cookie[$uid];\n\t$cookie[$uid] = DB::result_first(\"SELECT cookie FROM member_setting WHERE uid='{$uid}'\");\n\t//$cookie[$uid] = strrev(str_rot13(pack('H*', $cookie[$uid])));\n\treturn $cookie[$uid];\n}\nfunction save_cookie($uid, $cookie){\n\t//$cookie = bin2hex(str_rot13(strrev(addslashes($cookie))));\n\tDB::query(\"UPDATE member_setting SET cookie='{$cookie}' WHERE uid='{$uid}'\");\n}\nfunction get_username($uid){\n\tstatic $username = array();\n\tif($username[$uid]) return $username[$uid];\n\t$username = CACHE::get('username');\n\treturn $username[$uid];\n}\nfunction get_setting($uid){\n\tstatic $user_setting = array();\n\tif($user_setting[$uid]) return $user_setting[$uid];\n\t$cached_result = CACHE::get('user_setting_'.$uid);\n\tif(!$cached_result){\n\t\t$cached_result = DB::fetch_first(\"SELECT * FROM member_setting WHERE uid='{$uid}'\");\n\t\tunset($cached_result['cookie']);\n\t\tCACHE::save('user_setting_'.$uid, $cached_result);\n\t}\n\treturn $user_setting[$uid] = $cached_result;\n}\nfunction getSetting($k, $force = false){\n\tif($force) return $setting[$k] = DB::result_first(\"SELECT v FROM setting WHERE k='{$k}'\");\n\t$cache = CACHE::get('setting');\n\treturn $cache[$k];\n}\nfunction saveSetting($k, $v){\n\tif(!defined('IN_XAE') && $k == 'version') return saveVersion($v);\n\tstatic $cache_cleaned = false;\n\t$v = addslashes($v);\n\tDB::query(\"REPLACE INTO setting SET v='{$v}', k='{$k}'\");\n\tif($cache_cleaned) return;\n\tCACHE::clean('setting');\n\t$cache_cleaned = true;\n}\nfunction runquery($sql){\n\t$sql = str_replace(\"\\r\", \"\\n\", $sql);\n\tforeach(explode(\";\\n\", trim($sql)) as $query) {\n\t\t$query = trim($query);\n\t\tif($query) DB::query($query);\n\t}\n}\nfunction jquery_path(){\n\t$path = defined('IN_ADMINCP') ? 0 : getSetting('jquery_mode');\n\tswitch($path){\n\t\tcase 'google':\n\t\t\treturn '//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js';\n\t\tcase 'microsoft':\n\t\t\treturn '//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.12.4.min.js';\n\t\tcase 'cloudflare':\n\t\t\treturn '//cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js';\n\t\tcase 'jsdelivr':\n\t\t\treturn '//cdn.jsdelivr.net/jquery/1.12.4/jquery.min.js';\n\t\tcase 'lug-ustc':\n\t\t\treturn '//ajax.lug.ustc.edu.cn/ajax/libs/jquery/1.12.4/jquery.min.js';\n\t\tdefault:\n\t\tcase 'builtin':\n\t\t\treturn 'system/js/jquery.min.js';\n\t}\n}\nfunction kk_fetch_url($url, $limit = 0, $post = '', $cookie = '', $ignore = FALSE, $ip = '', $timeout = 15, $block = TRUE, $encodetype  = 'URLENCODE', $allowcurl = TRUE, $position = 0) {\n\t$return = '';\n\t$matches = parse_url($url);\n\t$scheme = $matches['scheme'];\n\t$host = $matches['host'];\n\t$path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';\n\t$port = !empty($matches['port']) ? $matches['port'] : 80;\n\tif(function_exists('curl_init') && function_exists('curl_exec') && $allowcurl) {\n\t\t$ch = curl_init();\n\t\t$ip && curl_setopt($ch, CURLOPT_HTTPHEADER, array(\"Host: \".$host));\n\t\tcurl_setopt($ch, CURLOPT_URL, $scheme.'://'.($ip ? $ip : $host).':'.$port.$path);\n\t\tcurl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);\n\t\tif($post) {\n\t\t\tcurl_setopt($ch, CURLOPT_POST, 1);\n\t\t\tif($encodetype == 'URLENCODE') {\n\t\t\t\tcurl_setopt($ch, CURLOPT_POSTFIELDS, $post);\n\t\t\t} else {\n\t\t\t\tparse_str($post, $postarray);\n\t\t\t\tcurl_setopt($ch, CURLOPT_POSTFIELDS, $postarray);\n\t\t\t}\n\t\t}\n\t\tif($cookie) {\n\t\t\tcurl_setopt($ch, CURLOPT_COOKIE, $cookie);\n\t\t}\n\t\tcurl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);\n\t\tcurl_setopt($ch, CURLOPT_TIMEOUT, $timeout);\n\t\t$data = curl_exec($ch);\n\t\t$status = curl_getinfo($ch);\n\t\t$errno = curl_errno($ch);\n\t\tcurl_close($ch);\n\t\tif($errno || $status['http_code'] != 200) {\n\t\t\treturn;\n\t\t} else {\n\t\t\treturn !$limit ? $data : substr($data, 0, $limit);\n\t\t}\n\t}\n\tif($post) {\n\t\t$out = \"POST $path HTTP/1.0\\r\\n\";\n\t\t$header = \"Accept: */*\\r\\n\";\n\t\t$header .= \"Accept-Language: zh-cn\\r\\n\";\n\t\t$boundary = $encodetype == 'URLENCODE' ? '' : '; boundary='.trim(substr(trim($post), 2, strpos(trim($post), \"\\n\") - 2));\n\t\t$header .= $encodetype == 'URLENCODE' ? \"Content-Type: application/x-www-form-urlencoded\\r\\n\" : \"Content-Type: multipart/form-data$boundary\\r\\n\";\n\t\t$header .= \"User-Agent: $_SERVER[HTTP_USER_AGENT]\\r\\n\";\n\t\t$header .= \"Host: $host:$port\\r\\n\";\n\t\t$header .= 'Content-Length: '.strlen($post).\"\\r\\n\";\n\t\t$header .= \"Connection: Close\\r\\n\";\n\t\t$header .= \"Cache-Control: no-cache\\r\\n\";\n\t\t$header .= \"Cookie: $cookie\\r\\n\\r\\n\";\n\t\t$out .= $header.$post;\n\t} else {\n\t\t$out = \"GET $path HTTP/1.0\\r\\n\";\n\t\t$header = \"Accept: */*\\r\\n\";\n\t\t$header .= \"Accept-Language: zh-cn\\r\\n\";\n\t\t$header .= \"User-Agent: $_SERVER[HTTP_USER_AGENT]\\r\\n\";\n\t\t$header .= \"Host: $host:$port\\r\\n\";\n\t\t$header .= \"Connection: Close\\r\\n\";\n\t\t$header .= \"Cookie: $cookie\\r\\n\\r\\n\";\n\t\t$out .= $header;\n\t}\n\t$fpflag = 0;\n\tif(!$fp = @fsocketopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout)) {\n\t\t$context = array(\n\t\t\t'http' => array(\n\t\t\t\t'method' => $post ? 'POST' : 'GET',\n\t\t\t\t'header' => $header,\n\t\t\t\t'content' => $post,\n\t\t\t\t'timeout' => $timeout,\n\t\t\t),\n\t\t);\n\t\t$context = stream_context_create($context);\n\t\t$fp = @fopen($scheme.'://'.($ip ? $ip : $host).':'.$port.$path, 'b', false, $context);\n\t\t$fpflag = 1;\n\t}\n\tif(!$fp) {\n\t\treturn '';\n\t} else {\n\t\tstream_set_blocking($fp, $block);\n\t\tstream_set_timeout($fp, $timeout);\n\t\t@fwrite($fp, $out);\n\t\tif($ignore){\n\t\t\t@fclose($fp);\n\t\t\treturn;\n\t\t}\n\t\t$status = stream_get_meta_data($fp);\n\t\tif(!$status['timed_out']) {\n\t\t\twhile (!feof($fp) && !$fpflag) {\n\t\t\t\tif(($header = @fgets($fp)) && ($header == \"\\r\\n\" ||  $header == \"\\n\")) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif($position) {\n\t\t\t\tfor($i=0; $i<$position; $i++) {\n\t\t\t\t\t$char = fgetc($fp);\n\t\t\t\t\tif($char == \"\\n\" && $oldchar != \"\\r\") {\n\t\t\t\t\t\t$i++;\n\t\t\t\t\t}\n\t\t\t\t\t$oldchar = $char;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif($limit) {\n\t\t\t\t$return = stream_get_contents($fp, $limit);\n\t\t\t} else {\n\t\t\t\t$return = stream_get_contents($fp);\n\t\t\t}\n\t\t}\n\t\t@fclose($fp);\n\t\treturn $return;\n\t}\n}\nfunction fsocketopen($hostname, $port = 80, &$errno, &$errstr, $timeout = 15) {\n\t$fp = '';\n\tif(function_exists('fsockopen')) {\n\t\t$fp = @fsockopen($hostname, $port, $errno, $errstr, $timeout);\n\t} elseif(function_exists('pfsockopen')) {\n\t\t$fp = @pfsockopen($hostname, $port, $errno, $errstr, $timeout);\n\t} elseif(function_exists('stream_socket_client')) {\n\t\t$fp = @stream_socket_client($hostname.':'.$port, $errno, $errstr, $timeout);\n\t}\n\treturn $fp;\n}\nfunction xml2array(&$xml, $isnormal = FALSE) {\n\t$xml_parser = new XMLparse($isnormal);\n\t$data = $xml_parser->parse($xml);\n\t$xml_parser->destruct();\n\treturn $data;\n}\nfunction array2xml($arr, $htmlon = TRUE, $isnormal = FALSE, $level = 1) {\n\t$s = $level == 1 ? \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\\r\\n<root>\\r\\n\" : '';\n\t$space = str_repeat(\"\\t\", $level);\n\tforeach($arr as $k => $v) {\n\t\tif(!is_array($v)) {\n\t\t\t$s .= $space.\"<item id=\\\"$k\\\">\".($htmlon ? '<![CDATA[' : '').$v.($htmlon ? ']]>' : '').\"</item>\\r\\n\";\n\t\t} else {\n\t\t\t$s .= $space.\"<item id=\\\"$k\\\">\\r\\n\".array2xml($v, $htmlon, $isnormal, $level + 1).$space.\"</item>\\r\\n\";\n\t\t}\n\t}\n\t$s = preg_replace(\"/([\\x01-\\x08\\x0b-\\x0c\\x0e-\\x1f])+/\", ' ', $s);\n\treturn $level == 1 ? $s.\"</root>\" : $s;\n}\nfunction save_config_file(){\n\tglobal $_config;\n\tif (!$_config) return;\n\t$content = '<?php'.PHP_EOL.'/* Auto-generated config file */'.PHP_EOL.'$_config = ';\n\t$content .= var_export($_config, true).';'.PHP_EOL.'?>';\n\tif(!is_writable(SYSTEM_ROOT.'./config.inc.php')) throw new Exception('Config file is not writable!');\n\tfile_put_contents(SYSTEM_ROOT.'./config.inc.php', $content);\n}\nfunction saveVersion($version){\n\tglobal $_config;\n\tif (!$_config) return;\n\t$_config['version'] = $version;\n\tsave_config_file();\n}\nfunction mklink($sourceFile, $targetFile){\n\treturn @file_put_contents($targetFile, '<?php @include '.var_export($sourceFile, true).'; ?>');\n}\nfunction cron_set_nextrun($timestamp){\n\tif(!defined('CRON_ID')) throw new Exception('Unknown cron id');\n\t$timestamp = intval($timestamp);\n\tDB::query(\"UPDATE cron SET nextrun='{$timestamp}' WHERE id='\".addslashes(CRON_ID).\"'\");\n\t$nextrun = DB::fetch_first(\"SELECT nextrun FROM cron ORDER BY nextrun ASC LIMIT 0,1\");\n\tsaveSetting('next_cron', $nextrun ? $nextrun['nextrun'] : TIMESTAMP + 1200);\n}\n// Function link\nfunction get_tbs($uid){\n\trequire_once SYSTEM_ROOT.'./function/sign.php';\n\treturn _get_tbs($uid);\n}\nfunction verify_cookie($cookie){\n\trequire_once SYSTEM_ROOT.'./function/sign.php';\n\treturn _verify_cookie($cookie);\n}\nfunction get_baidu_userinfo($uid){\n\trequire_once SYSTEM_ROOT.'./function/sign.php';\n\treturn _get_baidu_userinfo($uid);\n}\nfunction client_sign($uid, $tieba){\n\trequire_once SYSTEM_ROOT.'./function/sign.php';\n\treturn _client_sign($uid, $tieba);\n}\nfunction zhidao_sign($uid){\n\trequire_once SYSTEM_ROOT.'./function/sign.php';\n\treturn _zhidao_sign($uid);\n}\nfunction wenku_sign($uid){\n\trequire_once SYSTEM_ROOT.'./function/sign.php';\n\treturn _wenku_sign($uid);\n}\nfunction update_liked_tieba($uid, $ignore_error = false, $allow_deletion = true){\n\trequire_once SYSTEM_ROOT.'./function/sign.php';\n\treturn _update_liked_tieba($uid, $ignore_error, $allow_deletion);\n}\nfunction get_liked_tieba($cookie){\n\trequire_once SYSTEM_ROOT.'./function/sign.php';\n\treturn _get_liked_tieba($cookie);\n}\nfunction do_login($uid){\n\trequire_once SYSTEM_ROOT.'./function/member.php';\n\t_do_login($uid);\n}\nfunction do_register($username,$password,$email){\n\trequire_once SYSTEM_ROOT.'./function/member.php';\n\treturn _do_register($username,$password,$email);\n}\nfunction delete_user($uid){\n\trequire_once SYSTEM_ROOT.'./function/member.php';\n\t_delete_user($uid);\n}\n"
  },
  {
    "path": "system/function/member.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n\nfunction _delete_user($uid){\n\tif(!$uid) return;\n\tif(!is_array($uid)) $uid = array($uid);\n\t$uid = implode(\"', '\", $uid);\n\tDB::query(\"DELETE FROM member WHERE uid IN ('{$uid}')\");\n\tDB::query(\"DELETE FROM member_setting WHERE uid IN ('{$uid}')\");\n\tDB::query(\"DELETE FROM my_tieba WHERE uid IN ('{$uid}')\");\n\tDB::query(\"DELETE FROM sign_log WHERE uid IN ('{$uid}')\");\n\tHOOK::run('delete_user', true, $uid);\n}\n\nfunction _do_login($uid){\n\tglobal $cookiever;\n\t$user = DB::fetch_first(\"SELECT * FROM member WHERE uid='{$uid}'\");\n\t$password_hash = substr(md5($user['password']), 8, 8);\n\t$login_exp = TIMESTAMP + 900;\n\tdsetcookie('token', authcode(\"{$cookiever}\\t{$uid}\\t{$user[username]}\\t{$login_exp}\\t{$password_hash}\", 'ENCODE'));\n\tHOOK::run('login_user', true, $user);\n}\n\nfunction _do_register($username, $password, $email){\n\t$user = array(\n\t\t'username' => $username,\n\t\t'password' => 'FAKE_PASSWORD',\n\t\t'email' => $email,\n\t);\n\t$uid = DB::insert('member', $user);\n\t$user['uid'] = $uid;\n\t$password = Widget_Password::encrypt($user, $password);\n\tDB::query(\"UPDATE member SET password='{$password}' WHERE uid='{$uid}'\");\n\tDB::insert('member_setting', array('uid' => $uid, 'cookie' => ''));\n\tHOOK::run('register_user', true, $user);\n\tCACHE::update('username');\n\tCACHE::save('user_setting_'.$uid, '');\n\treturn $uid;\n}"
  },
  {
    "path": "system/function/sae.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n\n$_config = array(\n\t'db' => array(\n\t\t'server' => SAE_MYSQL_HOST_M,\n\t\t'port' => SAE_MYSQL_PORT,\n\t\t'username' => SAE_MYSQL_USER,\n\t\t'password' => SAE_MYSQL_PASS,\n\t\t'name' => SAE_MYSQL_DB,\n\t\t'pconnect' => false,\n\t),\n);\n\n$real_siteurl = 'http://'.$_SERVER['HTTP_APPNAME'].'.sinaapp.com/';\n\n?>"
  },
  {
    "path": "system/function/sign.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n\nfunction _get_tbs($uid){\n\tstatic $tbs = array();\n\tif($tbs[$uid]) return $tbs[$uid];\n\t$tbs_url = 'http://tieba.baidu.com/dc/common/tbs';\n\t$ch = curl_init($tbs_url);\n\tcurl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent: Mozilla/5.0 (Linux; U; Android 4.1.2; zh-cn; MB526 Build/JZO54K) AppleWebKit/530.17 (KHTML, like Gecko) FlyFlow/2.4 Version/4.0 Mobile Safari/530.17 baidubrowser/042_1.8.4.2_diordna_458_084/alorotoM_61_2.1.4_625BM/1200a/39668C8F77034455D4DED02169F3F7C7%7C132773740707453/1','Referer: http://tieba.baidu.com/'));\n\tcurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n\tcurl_setopt($ch, CURLOPT_COOKIE, get_cookie($uid));\n\t$tbs_json = curl_exec($ch);\n\tcurl_close($ch);\n\t$tbs = json_decode($tbs_json, 1);\n\treturn $tbs[$uid] = $tbs['tbs'];\n}\n\nfunction _verify_cookie($cookie){\n\t$tbs_url = 'http://tieba.baidu.com/dc/common/tbs';\n\t$ch = curl_init($tbs_url);\n\tcurl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent: Mozilla/5.0 (Linux; U; Android 4.1.2; zh-cn; MB526 Build/JZO54K) AppleWebKit/530.17 (KHTML, like Gecko) FlyFlow/2.4 Version/4.0 Mobile Safari/530.17 baidubrowser/042_1.8.4.2_diordna_458_084/alorotoM_61_2.1.4_625BM/1200a/39668C8F77034455D4DED02169F3F7C7%7C132773740707453/1','Referer: http://tieba.baidu.com/'));\n\tcurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n\tcurl_setopt($ch, CURLOPT_COOKIE, $cookie);\n\t$tbs_json = curl_exec($ch);\n\tcurl_close($ch);\n\t$tbs = json_decode($tbs_json, 1);\n\treturn $tbs['is_login'];\n}\n\nfunction _get_baidu_userinfo($uid){\n\t$cookie = get_cookie($uid);\n\tif(!$cookie) return array('no' => 4);\n\t$tbs_url = 'http://tieba.baidu.com/f/user/json_userinfo';\n\t$ch = curl_init($tbs_url);\n\tcurl_setopt($ch, CURLOPT_HTTPHEADER, array('Referer: http://tieba.baidu.com/'));\n\tcurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n\tcurl_setopt($ch, CURLOPT_COOKIE, $cookie);\n\t$tbs_json = curl_exec($ch);\n\tcurl_close($ch);\n\t$tbs_json = mb_convert_encoding($tbs_json, \"utf8\", \"gbk\");\n\treturn json_decode($tbs_json, true);\n}\n\nfunction _get_liked_tieba($cookie){\n\t$pn = 0;\n\t$kw_name = array();\n\t$retry = 0;\n\twhile (true){\n\t\t$pn++;\n\t\t$mylikeurl = \"http://tieba.baidu.com/f/like/mylike?&pn=$pn\";\n\t\t$result = kk_fetch_url($mylikeurl, 0, '', $cookie);\n\t\t$result = wrap_text($result);\n\t\t$pre_reg = '/<tr><td>.*?<ahref=\"\\/f\\?kw=.*?\"title=\"(.*?)\"/';\n\t\tpreg_match_all($pre_reg, $result, $matches);\n\t\t$count = 0;\n\t\tforeach ($matches[1] as $key => $value) {\n\t\t\t$uname = urlencode($value);\n\t\t\t$_uname = preg_quote($value);\n\t\t\tpreg_match('/balvid=\"([0-9]+)\"/i', $result, $fid);\n\t\t\t$kw_name[] = array(\n\t\t\t\t'name' => mb_convert_encoding($value, 'utf-8', 'gbk'),\n\t\t\t\t'uname' => $uname,\n\t\t\t\t'fid' => $fid[1],\n\t\t\t);\n\t\t\t$count++;\n\t\t}\n\t\tif ($count==0) {\n\t\t\tif ($retry >= 2) break;\n\t\t\t$retry++;\n\t\t\t$pn--;\n\t\t\tcontinue;\n\t\t}\n\t\t$retry = 0;\n\t}\n\treturn $kw_name;\n}\n\nfunction _update_liked_tieba($uid, $ignore_error = false, $allow_deletion = true){\n\t$date = date('Ymd', TIMESTAMP + 900);\n\t$cookie = get_cookie($uid);\n\tif(!$cookie){\n\t\tif($ignore_error) return;\n\t\tshowmessage('请先填写 Cookie 信息再更新', './#baidu_bind');\n\t}\n\t$liked_tieba = get_liked_tieba($cookie);\n\t$insert = $deleted = 0;\n\tif(!$liked_tieba){\n\t\tif($ignore_error) return;\n\t\tshowmessage('无法获取喜欢的贴吧，请更新 Cookie 信息', './#baidu_bind');\n\t}\n\tif($limit = getSetting('max_tieba')){\n\t\t$count = count($liked_tieba);\n\t\tif($limit < $count){\n\t\t\tif($ignore_error) return;\n\t\t\tshowmessage(\"<p>您共计关注了 {$count} 个贴吧，</p><p>管理员限制了每位用户最多关注 {$limit} 个贴吧</p>\", './#liked_tieba');\n\t\t}\n\t}\n\t$my_tieba = array();\n\t$query = DB::query(\"SELECT name, fid, tid FROM my_tieba WHERE uid='{$uid}'\");\n\twhile($r = DB::fetch($query)) {\n\t\t$my_tieba[$r['name']] = $r;\n\t}\n\tforeach($liked_tieba as $tieba){\n\t\tif($my_tieba[$tieba['name']]){\n\t\t\tunset($my_tieba[$tieba['name']]);\n\t\t\tif(!$my_tieba[$tieba['name']]['fid']) DB::update('my_tieba', array(\n\t\t\t\t'fid' => $tieba['fid'],\n\t\t\t\t), array(\n\t\t\t\t\t'uid' => $uid,\n\t\t\t\t\t'name' => $tieba['name'],\n\t\t\t\t), true);\n\t\t\tcontinue;\n\t\t}else{\n\t\t\tDB::insert('my_tieba', array(\n\t\t\t\t'uid' => $uid,\n\t\t\t\t'fid' => $tieba['fid'],\n\t\t\t\t'name' => $tieba['name'],\n\t\t\t\t'unicode_name' => $tieba['uname'],\n\t\t\t\t), false, true, true);\n\t\t\t$insert++;\n\t\t}\n\t}\n\tDB::query(\"INSERT IGNORE INTO sign_log (tid, uid, `date`) SELECT tid, uid, '{$date}' FROM my_tieba\");\n\tif($my_tieba && $allow_deletion){\n\t\t$tieba_ids = array();\n\t\tforeach($my_tieba as $tieba){\n\t\t\t$tieba_ids[] = $tieba['tid'];\n\t\t}\n\t\t$str = \"'\".implode(\"', '\", $tieba_ids).\"'\";\n\t\t$deleted = count($my_tieba);\n\t\tDB::query(\"DELETE FROM my_tieba WHERE uid='{$uid}' AND tid IN ({$str})\");\n\t\tDB::query(\"DELETE FROM sign_log WHERE uid='{$uid}' AND tid IN ({$str})\");\n\t}\n\treturn array($insert, $deleted);\n}\n\nfunction _client_sign($uid, $tieba){\n\t$cookie = get_cookie($uid);\n\tpreg_match('/BDUSS=([^ ;]+);/i', $cookie, $matches);\n\t$BDUSS = trim($matches[1]);\n\tif(!$BDUSS) return array(-1, '找不到 BDUSS Cookie', 0);\n\t$ch = curl_init('http://c.tieba.baidu.com/c/c/forum/sign');\n\tcurl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded', 'User-Agent: Mozilla/5.0 (SymbianOS/9.3; Series60/3.2 NokiaE72-1/021.021; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Version/3.0 BrowserNG/7.1.16352'));\n\tcurl_setopt($ch, CURLOPT_COOKIE, $cookie);\n\tcurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n\tcurl_setopt($ch, CURLOPT_POST, 1);\n\t$array = array(\n\t\t'BDUSS' => $BDUSS,\n\t\t'_client_id' => '03-00-DA-59-05-00-72-96-06-00-01-00-04-00-4C-43-01-00-34-F4-02-00-BC-25-09-00-4E-36',\n\t\t'_client_type' => '4',\n\t\t'_client_version' => '1.2.1.17',\n\t\t'_phone_imei' => '540b43b59d21b7a4824e1fd31b08e9a6',\n\t\t'fid' => $tieba['fid'],\n\t\t'kw' => urldecode($tieba['unicode_name']),\n\t\t'net_type' => '3',\n\t\t'tbs' => get_tbs($uid),\n\t);\n\t$sign_str = '';\n\tforeach($array as $k=>$v) $sign_str .= $k.'='.$v;\n\t$sign = strtoupper(md5($sign_str.'tiebaclient!!!'));\n\t$array['sign'] = $sign;\n\tcurl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array));\n\t$sign_json = curl_exec($ch);\n\tcurl_close($ch);\n\t$res = @json_decode($sign_json, true);\n\tif(!$res) return array(1, 'JSON 解析错误', 0);\n\tif($res['user_info']){\n\t\t$exp = $res['user_info']['sign_bonus_point'];\n\t\treturn array(2, \"签到成功，经验值上升 {$exp}\", $exp);\n\t}else{\n\t\tswitch($res['error_code']){\n\t\t\tcase '340010':\t\t// 已经签过\n\t\t\tcase '160002':\n\t\t\tcase '3':\n\t\t\t\treturn array(2, $res['error_msg'], 0);\n\t\t\tcase '1':\t\t\t// 未登录\n\t\t\t\treturn array(-1, \"ERROR-{$res[error_code]}: \".$res['error_msg'].' （Cookie 过期或不正确）', 0);\n\t\t\tcase '160004':\t\t// 不支持\n\t\t\t\treturn array(-1, \"ERROR-{$res[error_code]}: \".$res['error_msg'], 0);\n\t\t\tcase '160003':\t\t// 零点 稍后再试\n\t\t\tcase '160008':\t\t// 太快了\n\t\t\t\treturn array(1, \"ERROR-{$res[error_code]}: \".$res['error_msg'], 0);\n\t\t\tdefault:\n\t\t\t\treturn array(1, \"ERROR-{$res[error_code]}: \".$res['error_msg'], 0);\n\t\t}\n\t}\n}\n\nfunction _client_sign_old($uid, $tieba){\n\t$cookie = get_cookie($uid);\n\tpreg_match('/BDUSS=([^ ;]+);/i', $cookie, $matches);\n\t$BDUSS = trim($matches[1]);\n\tif(!$BDUSS) return array(-1, '找不到 BDUSS Cookie', 0);\n\t$ch = curl_init('http://c.tieba.baidu.com/c/c/forum/sign');\n\tcurl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded', 'User-Agent: BaiduTieba for Android 5.1.3', 'client_user_token: '.random(6, true)));\n\tcurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n\tcurl_setopt($ch, CURLOPT_POST, 1);\n\t$array = array(\n\t\t'BDUSS' => $BDUSS,\n\t\t'_client_id' => 'wappc_138'.random(10, true).'_'.random(3, true),\n\t\t'_client_type' => '2',\n\t\t'_client_version' => '5.1.3',\n\t\t'_phone_imei' => md5(random(16, true)),\n\t\t'cuid' => strtoupper(md5(random(16))).'|'.random(15, true),\n\t\t'fid' => $tieba['fid'],\n\t\t'from' => 'tieba',\n\t\t'kw' => urldecode($tieba['unicode_name']),\n\t\t'model' => 'Aries',\n\t\t'net_type' => '3',\n\t\t'stErrorNums' => '0',\n\t\t'stMethod' => '1',\n\t\t'stMode' => '1',\n\t\t'stSize' => random(5, true),\n\t\t'stTime' => random(4, true),\n\t\t'stTimesNum' => '0',\n\t\t'tbs' => get_tbs($uid),\n\t\t'timestamp' => time().rand(1000, 9999),\n\t);\n\t$sign_str = '';\n\tforeach($array as $k=>$v) $sign_str .= $k.'='.$v;\n\t$sign = strtoupper(md5($sign_str.'tiebaclient!!!'));\n\t$array['sign'] = $sign;\n\tcurl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array));\n\t$sign_json = curl_exec($ch);\n\tcurl_close($ch);\n\t$res = @json_decode($sign_json, true);\n\tif(!$res) return array(1, 'JSON 解析错误', 0);\n\tif($res['user_info']){\n\t\t$exp = $res['user_info']['sign_bonus_point'];\n\t\treturn array(2, \"签到成功，经验值上升 {$exp}\", $exp);\n\t}else{\n\t\tswitch($res['error_code']){\n\t\t\tcase '340010':\t\t// 已经签过\n\t\t\tcase '160002':\n\t\t\tcase '3':\n\t\t\t\treturn array(2, $res['error_msg'], 0);\n\t\t\tcase '1':\t\t\t// 未登录\n\t\t\t\treturn array(-1, \"ERROR-{$res[error_code]}: \".$res['error_msg'].' （Cookie 过期或不正确）', 0);\n\t\t\tcase '160004':\t\t// 不支持\n\t\t\t\treturn array(-1, \"ERROR-{$res[error_code]}: \".$res['error_msg'], 0);\n\t\t\tcase '160003':\t\t// 零点 稍后再试\n\t\t\tcase '160008':\t\t// 太快了\n\t\t\t\treturn array(1, \"ERROR-{$res[error_code]}: \".$res['error_msg'], 0);\n\t\t\tdefault:\n\t\t\t\treturn array(1, \"ERROR-{$res[error_code]}: \".$res['error_msg'], 0);\n\t\t}\n\t}\n}\n\nfunction _zhidao_sign($uid){\n\t$ch = curl_init('http://zhidao.baidu.com/submit/user');\n\tcurl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));\n\tcurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n\tcurl_setopt($ch, CURLOPT_COOKIE, get_cookie($uid));\n\tcurl_setopt($ch, CURLOPT_POST, 1);\n\tcurl_setopt($ch, CURLOPT_POSTFIELDS, 'cm=100509&t='.TIMESTAMP);\n\t$result = curl_exec($ch);\n\tcurl_close($ch);\n\treturn @json_decode($result);\n}\n\nfunction _wenku_sign($uid){\n\t$ch = curl_init('http://wenku.baidu.com/task/submit/signin');\n\tcurl_setopt($ch, CURLOPT_HTTPHEADER, array('User-Agent: Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.43 BIDUBrowser/2.x Safari/537.31'));\n\tcurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n\tcurl_setopt($ch, CURLOPT_COOKIE, get_cookie($uid));\n\t$result = curl_exec($ch);\n\tcurl_close($ch);\n\treturn @json_decode($result);\n}\n"
  },
  {
    "path": "system/function/updater/1.13.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\n\nif($current_version == '1.13.9.5'){\n\tDB::query(\"ALTER TABLE `member_setting` ADD `zhidao_sign` TINYINT(1) NOT NULL DEFAULT '0'\");\n\tDB::query(\"ALTER TABLE `member_setting` ADD `wenku_sign` TINYINT(1) NOT NULL DEFAULT '0'\");\n\tsaveSetting('version', '1.13.9.6');\n\tshowmessage('成功更新到 1.13.9.6！', './', 1);\n}elseif($current_version == '1.13.9.6'){\n\tsaveSetting('version', '1.13.9.8');\n\tshowmessage('成功更新到 1.13.9.8！', './', 1);\n}elseif($current_version == '1.13.9.8'){\n\tDB::query('CREATE TABLE IF NOT EXISTS `cache` ( `k` varchar(32) NOT NULL, `v` TEXT NOT NULL, PRIMARY KEY (`k`)) ENGINE=InnoDB DEFAULT CHARSET=utf8');\n\tsaveSetting('version', '1.13.9.23');\n\tshowmessage('成功更新到 1.13.9.23！', './', 1);\n}elseif($current_version == '1.13.9.23'){\n\tsaveSetting('version', '1.13.9.24');\n\tshowmessage('成功更新到 1.13.9.24！', './', 1);\n}elseif($current_version == '1.13.9.24'){\n\t$sql = <<<EOF\nCREATE TABLE IF NOT EXISTS `cron` (\n  `id` varchar(16) NOT NULL,\n  `enabled` tinyint(1) NOT NULL,\n  `nextrun` int(10) unsigned NOT NULL,\n  `order` tinyint(4) NOT NULL,\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8;\nINSERT INTO `cron` (`id`, `enabled`, `nextrun`, `order`) VALUES\n('daily', 1, 0, 0),\n('update_tieba', 1, 0, 10),\n('sign', 1, 0, 20),\n('ext_sign', 1, 0, 50),\n('mail', 1, 0, 100);\nCREATE TABLE IF NOT EXISTS `mail_queue` (\n  `id` int(11) NOT NULL AUTO_INCREMENT,\n  `to` varchar(255) NOT NULL,\n  `subject` varchar(255) NOT NULL,\n  `content` text NOT NULL,\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB  DEFAULT CHARSET=utf8;\nEOF;\n\trunquery($sql);\n\tsaveSetting('version', '1.13.10.4');\n\tshowmessage('成功更新到 1.13.10.4！<br><br>请修改计划任务为以下内容：<br>http://域名/cron.php &nbsp; * * * * *（每分钟一次）');\n}elseif($current_version == '1.13.9.4'){\n\tDB::insert('cron', array(\n\t\t'id' => 'sign_retry',\n\t\t'enabled' => 1,\n\t\t'nextrun' => TIMESTAMP,\n\t\t'order' => '110',\n\t));\n\tsaveSetting('version', '1.13.10.6');\n\tshowmessage('成功更新到 1.13.10.6！', './');\n}elseif($current_version == '1.13.10.6'){\n\tDB::query('ALTER TABLE `member` CHANGE `username` `username` VARCHAR(24)');\n\tsaveSetting('version', '1.13.10.13');\n\tshowmessage('成功更新到 1.13.10.13！', './', 1);\n}elseif($current_version == '1.13.10.13'){\n\tDB::query('ALTER TABLE `my_tieba` DROP INDEX `name`');\n\tDB::query('ALTER TABLE `my_tieba` ADD INDEX (`uid`)');\n\tDB::query('ALTER TABLE `member_setting` DROP `use_bdbowser`, DROP `sign_method`');\n\tsaveSetting('version', '1.13.10.20');\n\tshowmessage('成功更新到 1.13.10.20！', './');\n}elseif($current_version == '1.13.10.20'){\n\tsaveSetting('version', '1.13.11.5');\n\tshowmessage('成功更新到 1.13.11.5！', './');\n}elseif($current_version == '1.13.11.5'){\n\tDB::query('\nCREATE TABLE IF NOT EXISTS `plugin` (\n  id int(11) NOT NULL AUTO_INCREMENT,\n  `name` varchar(64) NOT NULL,\n  module text NOT NULL,\n  PRIMARY KEY (id),\n  UNIQUE KEY `name` (`name`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8\n');\n\tDB::insert('plugin', array('name' => 'debug_info'));\n\tDB::insert('plugin', array('name' => 'update_log'));\n\tsaveSetting('version', '1.13.11.9');\n\tshowmessage('成功更新到 1.13.11.9！', './');\n}elseif($current_version == '1.13.11.9'){\n\trunquery(\"\nALTER TABLE `plugin` ADD `enable` TINYINT(1) NOT NULL DEFAULT '1' AFTER `id`;\nALTER TABLE `plugin` ADD `version` VARCHAR(8) NOT NULL DEFAULT '0';\nALTER TABLE `member_setting` ADD `cookie` TEXT BINARY CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL;\n\");\n\t$query = DB::query('SELECT uid, cookie FROM member');\n\twhile($result = DB::fetch($query)){\n\t\tsave_cookie($result['uid'], $result['cookie']);\n\t}\n\tDB::query('ALTER TABLE `member` DROP `cookie`');\n\t$query = DB::query('SHOW columns FROM `plugin`');\n\twhile($result = DB::fetch($query)){\n\t\tif($result['Field'] == 'module') DB::query('ALTER TABLE `plugin` DROP `module`');\n\t}\n\tCACHE::clear();\n\tCACHE::update('plugins');\n\tsaveSetting('register_limit', 1);\n\tsaveSetting('register_check', 1);\n\tsaveSetting('jquery_mode', 2);\n\tsaveSetting('version', '1.13.12.15');\n\tshowmessage('成功更新到 1.13.12.15！', './');\n}elseif($current_version == '1.13.12.15'){\n\tsaveSetting('version', '1.13.12.25');\n\tshowmessage('成功更新到 1.13.12.25！', './');\n}elseif($current_version == '1.13.12.25'){\n\tif($_config['adminid']) saveSetting('admin_uid', $_config['adminid']);\n\tsaveSetting('version', '1.14.1.15');\n\tshowmessage('成功更新到 1.14.1.15！', './');\n}\n\n?>"
  },
  {
    "path": "system/function/updater/1.14.1.15.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nDB::query(\"ALTER TABLE `setting` CHANGE `v` `v` VARCHAR(256) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL\");\nsaveSetting('version', '1.14.1.16');\nshowmessage('成功更新到 1.14.1.16！', './');\n?>"
  },
  {
    "path": "system/function/updater/1.14.1.16.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nrunquery('\nCREATE TABLE IF NOT EXISTS `download` (\n  `path` varchar(128) NOT NULL,\n  `content` text NOT NULL,\n  PRIMARY KEY (`path`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\nCREATE TABLE IF NOT EXISTS `update_source` (\n  `id` varchar(16) NOT NULL,\n  `path` varchar(128) NOT NULL,\n  PRIMARY KEY (`id`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n');\nsaveSetting('version', '1.14.1.23');\nshowmessage('成功更新到 1.14.1.23！', './');\n?>"
  },
  {
    "path": "system/function/updater/1.14.1.23.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nrunquery(\"\nALTER TABLE `member_bind` ENGINE = InnoDB;\nALTER TABLE `update_source` ENGINE = InnoDB;\n\nCREATE TABLE IF NOT EXISTS `plugin_var` (\n  `pluginid` varchar(64) NOT NULL,\n  `key` varchar(32) NOT NULL DEFAULT '',\n  `value` text NOT NULL,\n  PRIMARY KEY (`pluginid`,`key`)\n) ENGINE=InnoDB DEFAULT CHARSET=utf8;\n\");\nsaveSetting('version', '1.14.2.6');\nshowmessage('成功更新到 1.14.2.6！', './');\n?>"
  },
  {
    "path": "system/function/updater/1.14.2.6.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nsaveSetting('version', '1.14.4.12');\nshowmessage('成功更新到 1.14.4.12！', './');\n?>"
  },
  {
    "path": "system/function/updater/1.14.4.12.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nsaveSetting('template', 'default');\nsaveSetting('channel', 'dev');\nsaveSetting('version', '1.14.4.14');\nshowmessage('成功更新到 1.14.4.14！', './');\n?>"
  },
  {
    "path": "system/function/updater/1.14.4.14.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nDB::query('ALTER TABLE `member_setting` DROP `zhidao_sign`');\nDB::query('ALTER TABLE `cron` CHANGE `id` `id` VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL');\n$next_day = mktime(0, 0, 0) + 86400;\n$next_cron = $next_day + 1800;\nDB::query(\"UPDATE cron SET nextrun='{$next_cron}' WHERE enabled='0'\");\nDB::query(\"UPDATE cron SET nextrun='{$next_day}' WHERE enabled='0' AND id='daily'\");\nsaveSetting('version', '1.14.4.24');\nshowmessage('成功更新到 1.14.4.24！', './');\n?>"
  },
  {
    "path": "system/function/updater/1.14.4.24.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nDB::query(\"DELETE FROM cron WHERE id='sign_retry'\");\nsaveSetting('version', '1.14.5.12');\nshowmessage('成功更新到 1.14.5.12！', './');\n?>"
  },
  {
    "path": "system/function/updater/1.14.5.12.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\n$sql = <<<EOF\nCREATE TABLE IF NOT EXISTS `process` (\n  `id` varchar(16) NOT NULL,\n  `exptime` int(11) NOT NULL,\n  PRIMARY KEY (`id`)\n) ENGINE=MEMORY DEFAULT CHARSET=utf8;\nEOF;\n$res = DB::query($sql, 'SILENT');\nif(!$res) DB::query(str_replace('MEMORY', 'MyISAM', $sql));\nsaveSetting('version', '1.14.5.20');\nshowmessage('成功更新到 1.14.5.20！', './');\n?>"
  },
  {
    "path": "system/function/updater/1.14.5.20.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nDB::query('ALTER TABLE sign_log ADD INDEX date_uid (`date`, uid)');\nDB::query('DROP TABLE update_source');\nsaveSetting('version', '1.14.5.27');\nshowmessage('成功更新到 1.14.5.27！', './');\n?>"
  },
  {
    "path": "system/function/updater/1.14.5.27.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nDB::query('ALTER TABLE `member_setting` ADD `zhidao_sign` TINYINT(1) NOT NULL AFTER `wenku_sign`');\nsaveSetting('version', '1.14.6.2');\nshowmessage('成功更新到 1.14.6.2！', './');\n?>"
  },
  {
    "path": "system/function/updater/1.14.6.2.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\n\n$query = DB::query(\"SELECT uid, cookie FROM member_setting\");\nwhile ($result = DB::fetch($query)) {\n    if (strpos($result['cookie'], 'BDUSS=') !== false) continue;\n    // Decrypt and save cookie\n    $cookie = strrev(str_rot13(pack('H*', $result['cookie'])));\n    save_cookie($result['uid'], $cookie);\n}\n\nsaveSetting('version', '1.16.6.23');\nshowmessage('成功更新到 1.16.6.23！', './');\n"
  },
  {
    "path": "system/function/updater/1.16.6.23.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\n\nDB::query('ALTER TABLE `member` MODIFY `password` VARCHAR(255)');\n\nsaveSetting('version', '1.16.7.10');\nshowmessage('成功更新到 1.16.7.10！', './');\n"
  },
  {
    "path": "system/function/updater/fallback.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit('Access Denied');\nif(!$current_version){\n\tif(!defined('IN_XAE') && getSetting('version')){\n\t\tsaveVersion(getSetting('version'));\n\t\theader('Location: ./');\n\t\texit();\n\t}\n}\nthrow new Exception(\"找不到更新程序，无法进行更新！<br>Error while upgrade from version {$current_version} to version \".VERSION.'.');\n?>"
  },
  {
    "path": "template/default/admin.php",
    "content": "<?php\nif(!defined('IN_ADMINCP')) exit();\n?>\n<!DOCTYPE html>\n<html>\n<head>\n<title>管理中心 - 贴吧签到助手</title>\n<?php include template('widget/meta'); ?>\n</head>\n<body>\n<div id=\"append_parent\"><div class=\"cover hidden\"></div><div class=\"loading-icon\"><img src=\"./template/default/style/loading.gif\" /> 载入中...</div></div>\n<div class=\"wrapper\" id=\"page_index\">\n<h1>贴吧签到助手 - 管理中心</h1>\n<div class=\"menubtn\"><p>-</p><p>-</p><p>-</p></div>\n<div class=\"sidebar\">\n<ul id=\"menu\" class=\"menu\">\n<li id=\"menu_user\"><a href=\"#user\">用户管理</a></li>\n<li id=\"menu_stat\"><a href=\"#stat\">用户签到统计</a></li>\n<li id=\"menu_plugin\"><a href=\"#plugin\">插件管理</a></li>\n<li id=\"menu_template\"><a href=\"#template\">模板管理</a></li>\n<li id=\"menu_setting\"><a href=\"#setting\">系统设置</a></li>\n<li id=\"menu_mail\"><a href=\"#mail\">邮件群发</a></li>\n<li id=\"menu_updater\"><a href=\"#updater\">检查更新</a></li>\n<li><a href=\"./\">返回前台</a></li>\n</ul>\n</div>\n<div class=\"main-content\">\n<div id=\"content-loader\">\n<h2>正在加载 jQuery 组件...</h2>\n<p>首次加载需要较长时间，请您耐心等待.</p>\n<p>jQuery 加载完成前，您暂时无法操作本页面.</p>\n<br />\n<p>如果您长时间停留在此页面，请手动刷新网页.</p>\n</div>\n<div id=\"content-user\" class=\"hidden\">\n<h2>用户管理</h2>\n<table>\n<thead><tr><td style=\"width: 40px\">UID</td><td>用户名</td><td class=\"mobile_hidden\">邮箱</td><td>操作</td></tr></thead>\n<tbody></tbody>\n</table>\n</div>\n<div id=\"content-stat\" class=\"hidden\">\n<h2>用户签到统计</h2>\n<table>\n<thead><tr><td style=\"width: 40px\">UID</td><td>用户名</td><td>已成功</td><td>已跳过</td><td>待签到</td><td>待重试</td><td>不支持</td></tr></thead>\n<tbody></tbody>\n</table>\n<?php\nif(defined('AFENABLED')) echo '<a id=\"reset_failure_all\" href=\"javascript:;\" class=\"btn red\">一键重置无法签到的贴吧</a>';\n?>\n</div>\n<div id=\"content-setting\" class=\"hidden\">\n<h2>系统设置</h2>\n<p>云平台管理:</p>\n<?php if ($sid = cloud::id()) { ?>\n<p>站点ID: <?php echo $sid; ?></p>\n<p>当前域名：<?php echo $siteurl; ?></p>\n<p>\n<a href=\"admin.php?action=cloud_sync&formhash=<?php echo $formhash; ?>\" class=\"btn red\" onclick=\"return msg_win_action(this.href)\">同步站点信息</a>\n</p>\n<?php } else { ?>\n<p>没有在云平台注册，请尝试刷新本页面</p>\n<?php } ?>\n<br>\n<form method=\"post\" action=\"admin.php?action=save_setting\" id=\"setting_form\" onsubmit=\"return post_win(this.action, this.id)\">\n<input type=\"hidden\" name=\"formhash\" value=\"<?php echo $formhash; ?>\">\n<?php if(defined('AFENABLED')) { ?>\n<p><a href=\"admin.php?action=clear_cache&formhash=<?php echo $formhash; ?>\" class=\"btn red\" onclick=\"return msg_win_action(this.href)\">清除系统缓存</a></p>\n<p>管理员 UID: （使用英文逗号分隔）</p>\n<p><input type=\"text\" id=\"admin_uid\" name=\"admin_uid\" value=\"<?php echo getSetting('admin_uid'); ?>\" /></p>\n<?php } ?>\n<p>功能增强:</p>\n<p><label><input type=\"checkbox\" id=\"account_switch\" name=\"account_switch\" /> 允许多用户切换</label></p>\n<p><label><input type=\"checkbox\" id=\"autoupdate\" name=\"autoupdate\" /> 每天自动更新用户喜欢的贴吧 (稍占服务器资源)</label></p>\n<p>功能限制:</p>\n<?php\nif(defined('AFENABLED')) {\n?>\n<p><label>每个用户最多喜欢 <input type=\"text\" id=\"max_tieba\" name=\"max_tieba\" style=\"width: 50px\" /> 个贴吧</label></p>\n<?php\n}else{\n?>\n<p>\n<select name=\"max_tieba\" id=\"max_tieba\">\n<option value=\"0\" selected>不限制单用户的最大喜欢贴吧数量</option>\n<option value=\"50\">每个用户最多喜欢 50 个贴吧</option>\n<option value=\"80\">每个用户最多喜欢 80 个贴吧</option>\n<option value=\"100\">每个用户最多喜欢 100 个贴吧</option>\n<option value=\"120\">每个用户最多喜欢 120 个贴吧</option>\n<option value=\"180\">每个用户最多喜欢 180 个贴吧</option>\n<option value=\"250\">每个用户最多喜欢 250 个贴吧</option>\n<option value=\"350\">每个用户最多喜欢 350 个贴吧</option>\n<option value=\"500\">每个用户最多喜欢 500 个贴吧</option>\n<option value=\"750\">每个用户最多喜欢 750 个贴吧</option>\n<option value=\"1000\">每个用户最多喜欢 1000 个贴吧</option>\n</select>\n</p>\n<?php } ?>\n<p>防恶意注册:</p>\n<p><label><input type=\"checkbox\" id=\"block_register\" name=\"block_register\" /> 彻底关闭新用户注册功能</label></p>\n<p><label><input type=\"checkbox\" id=\"register_check\" name=\"register_check\" /> 启用内置的简单防恶意注册系统 (可能会导致无法注册)</label></p>\n<p><label><input type=\"checkbox\" id=\"register_limit\" name=\"register_limit\" /> 限制并发注册 (开启后可限制注册机注册频率)</label></p>\n<p><input type=\"text\" name=\"invite_code\" id=\"invite_code\" placeholder=\"邀请码 (留空为不需要)\" /></p>\n<p>jQuery 加载方式:</p>\n<p><label><input type=\"radio\" name=\"jquery_mode\" value=\"builtin\" /> 使用程序自带的 jQuery 类库 (默认, 推荐)</label></p>\n<p><label><input type=\"radio\" name=\"jquery_mode\" value=\"google\" /> 从 Google API 提供的 CDN 加载</label></p>\n<p><label><input type=\"radio\" name=\"jquery_mode\" value=\"mircosoft\" /> 从 Microsoft CDN 加载 (推荐)</label></p>\n<p><label><input type=\"radio\" name=\"jquery_mode\" value=\"cloudflare\" /> 从 CloudFlare 提供的 CDN 加载</label></p>\n<p><label><input type=\"radio\" name=\"jquery_mode\" value=\"jsdelivr\" /> 从 jsDelivr 提供的 CDN 加载</label></p>\n<p><label><input type=\"radio\" name=\"jquery_mode\" value=\"lug-ustc\" /> 从 中科大 Linux 用户协会 提供的 CDN 加载</label></p>\n<p>网站备案编号:</p>\n<p><input type=\"text\" id=\"beian_no\" name=\"beian_no\" placeholder=\"未备案的不需要填写\" /></p>\n<p>网站副标题: (将显示在标题中)</p>\n<p><input type=\"text\" id=\"extra_title\" name=\"extra_title\" placeholder=\"如：KK 后宫团专用版\" /></p>\n<p><input type=\"submit\" value=\"保存设置\" /></p>\n</form>\n<br>\n<p>邮件发送方式:</p>\n<form method=\"post\" action=\"admin.php?action=mail_setting\" id=\"mail_setting\" onsubmit=\"return post_win(this.action, this.id)\">\n<input type=\"hidden\" name=\"formhash\" value=\"<?php echo $formhash; ?>\">\n<?php\nforeach($classes as $id=>$obj){\n\t$desc = $obj->description ? ' - '.$obj->description : '';\n\tif(!$obj->isAvailable()) $desc = ' (当前服务器环境不支持)';\n\techo '<p><label><input type=\"radio\" name=\"mail_sender\" value=\"'.$id.'\"'.($obj->isAvailable() ? '' : ' disabled').($id == getSetting('mail_class') ? ' checked' : '').' /> '.$obj->name.$desc.'</label></p>';\n}\n?>\n<p>\n<input type=\"submit\" value=\"保存设置\" />\n &nbsp; <a href=\"javascript:;\" class=\"btn\" id=\"mail_advanced_config\">高级设置</a>\n &nbsp; <a href=\"admin.php?action=mail_test&formhash=<?php echo $formhash; ?>\" class=\"btn\" onclick=\"return msg_win_action(this.href)\">发送测试</a>\n</p>\n</form>\n</div>\n<div id=\"content-mail\" class=\"hidden\">\n<h2>邮件群发</h2>\n<p>此功能用于向本站已经注册的所有用户发送邮件公告</p>\n<p>为避免用户反感，建议您不要经常发送邮件</p>\n<br>\n<form method=\"post\" action=\"admin.php?action=send_mail\" id=\"send_mail\" onsubmit=\"return post_win(this.action, this.id)\">\n<input type=\"hidden\" name=\"formhash\" value=\"<?php echo $formhash; ?>\">\n<p>邮件标题：</p>\n<p><input type=\"text\" name=\"title\" style=\"width: 80%\" /></p>\n<p>邮件内容：</p>\n<p><textarea name=\"content\" rows=\"10\" style=\"width: 80%\"></textarea></p>\n<p><input type=\"submit\" value=\"确认发送\" /></p>\n</form>\n</div>\n<div id=\"content-plugin\" class=\"hidden\">\n<h2>插件管理</h2>\n<p>安装相关插件能够增强 贴吧签到助手 的相关功能.（部分插件可能会影响系统运行效率）</p>\n<p>插件的设计可以参考 Github 上的项目介绍.</p>\n<p>将插件文件放到 /plugins/ 文件夹下即可在此处看到对应的插件程序.</p>\n<p>如果你觉得某个插件有问题，你可以先尝试禁用它，禁用操作不会丢失数据.</p>\n<p>插件下载: <a href=\"http://www.kookxiang.com/forum-addon-1.html\" target=\"_blank\">http://www.kookxiang.com/forum-addon-1.html</a></p>\n<table>\n<thead><tr><td style=\"width: 40px\">#</td><td>插件标识符 (ID)</td><td>插件介绍</td><td>当前版本</td><td>操作</td></tr></thead>\n<tbody></tbody>\n</table>\n</div>\n<div id=\"content-template\" class=\"hidden\">\n<h2>模板管理</h2>\n<p>这里显示了当前安装的所有模板，你可以选择一个作为 贴吧签到助手 的模板显示.</p>\n<p>将模板文件放到 /template/ 文件夹下即可在此处看到对应的模板.</p>\n<p>模板的设计教程与下载可以访问: <a href=\"http://www.kookxiang.com/forum-addon-1.html\" target=\"_blank\">http://www.kookxiang.com/forum-addon-1.html</a></p>\n<ul class=\"template-list\">\n</ul>\n</div>\n<div id=\"content-updater\" class=\"hidden\">\n<style type=\"text/css\">\n#content-updater .result { padding: 10px 15px; margin-bottom: 0; background: #efefef; }\n#content-updater .filelist ul { margin-top: -5px; padding: 0 15px 10px; background: #efefef; }\n#content-updater .filelist ul li { list-style: disc; line-height: 25px; margin: 0 0 0 25px; }\n</style>\n<h2>检测升级</h2>\n<p>此功能将联网更新您的贴吧签到助手. 升级过程采用差量升级的方式.</p>\n<p>升级过程需要保证文件被更新的文件可读可写.</p>\n<br>\n<p>如果更新过程出现错误，您可以到 <a href=\"http://buildbot.ikk.me/#sign\" target=\"_blank\">http://buildbot.ikk.me/#sign</a> 下载最新完整包进行覆盖</p>\n<br>\n<?php\nif(getSetting('channel') == 'dev'){\n\techo '<p>当前分支：开发版 (<a id=\"switch_to_stable\" href=\"javascript:;\">切换到稳定版</a>)</p>';\n} else {\n\techo '<p>当前分支：稳定版 (<a id=\"switch_to_dev\" href=\"javascript:;\">切换到开发版</a>)</p>';\n}\n?>\n<p>开发版拥有更快的更新速度，但同时也拥有一定的不稳定性.</p>\n<br>\n<p class=\"result\">正在检查更新...</p>\n<div class=\"filelist hidden\">\n<ul></ul>\n<p><button class=\"btn red\">开始更新</button></p>\n</div>\n</div>\n<p class=\"copyright\"><span class=\"mobile_hidden\">贴吧签到助手 - Designed</span> by <a href=\"http://www.ikk.me\" target=\"_blank\">kookxiang</a>. 2013-2016 &copy; <a href=\"http://www.kookxiang.com\" target=\"_blank\">KK's Laboratory</a> - <a href=\"http://go.ikk.me/donate\" target=\"_blank\">赞助开发</a></p>\n</div>\n</div>\n<?php include template('widget/footer'); ?>\n<?php\nif(defined('CLOUD_NOT_INITED')) echo '<div class=\"hidden\"><img src=\"api.php?action=register_cloud\" /></div>';\n?>\n</body>\n</html>"
  },
  {
    "path": "template/default/index.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n$extra_title = getSetting('extra_title');\n$title = $extra_title ? \"贴吧签到助手 - {$extra_title}\" : '贴吧签到助手';\n?>\n<!DOCTYPE html>\n<html>\n<head>\n<title><?php echo $title; ?></title>\n<?php include template('widget/meta'); ?>\n</head>\n<body>\n<div id=\"append_parent\"><div class=\"cover hidden\"></div><div class=\"loading-icon\"><img src=\"./template/default/style/loading.gif\" /> 载入中...</div></div>\n<div class=\"wrapper\" id=\"page_index\">\n<?php include template('widget/header'); ?>\n<div class=\"sidebar\">\n<?php include template('widget/sidebar'); ?>\n</div>\n<div class=\"main-content\">\n<div id=\"content-loader\">\n<h2>正在加载 jQuery 组件...</h2>\n<p>首次加载需要较长时间，请您耐心等待.</p>\n<p>jQuery 加载完成前，您暂时无法操作本页面.</p>\n<br />\n<p>如果您长时间停留在此页面，请手动刷新网页.</p>\n</div>\n<div id=\"content-guide\" class=\"hidden\">\n<?php include template('widget/guide'); ?>\n</div>\n<div id=\"content-liked_tieba\" class=\"hidden\">\n<?php include template('widget/liked_tieba'); ?>\n</div>\n<div id=\"content-sign_log\" class=\"hidden\">\n<?php include template('widget/sign_log'); ?>\n</div>\n<div id=\"content-setting\" class=\"hidden\">\n<?php include template('widget/setting'); ?>\n</div>\n<div id=\"content-baidu_bind\" class=\"hidden\">\n<?php include template('widget/bind_status'); ?>\n</div>\n<?php HOOK::page_contents(); ?>\n<!-- 开发不易，跪求各位大大放俺一条生路 -->\n<!-- 你可以在这加你自己的链接，但是麻烦保留下我的链接 Thanks -->\n<p class=\"copyright\"><span class=\"mobile_hidden\">贴吧签到助手 - Designed</span> by <a href=\"http://www.ikk.me\" target=\"_blank\">kookxiang</a>. 2013-2016 &copy; <a href=\"http://www.kookxiang.com\" target=\"_blank\">KK's Laboratory</a> - <a href=\"http://go.ikk.me/donate\" target=\"_blank\">赞助开发</a><br>\n<?php if(getSetting('beian_no')) echo '<a href=\"http://www.miibeian.gov.cn/\" target=\"_blank\" rel=\"nofollow\">'.getSetting('beian_no').'</a> - '; ?><?php HOOK::run('page_footer'); ?></p>\n</div>\n<?php include template('widget/footer'); ?>\n</body>\n</html>\n"
  },
  {
    "path": "template/default/js/admin.js",
    "content": "$(document).ready(function() {\n\t$('#menu>li').click(function (){\n\t\tif(isMobile()) $('.sidebar').fadeOut();\n\t\tif(!$(this).attr('id')) return;\n\t\tif($(this).hasClass('selected')) return;\n\t\t$('.menu li.selected').removeClass('selected');\n\t\t$(this).addClass('selected');\n\t\tvar content_id = $(this).attr('id').replace('menu_', '#content-');\n\t\t$('.main-content>div').addClass('hidden');\n\t\t$(content_id).removeClass('hidden');\n\t\tvar callback = $(this).attr('id').replace('menu_', 'load_');\n\t\teval('if (typeof '+callback+' == \"function\") '+callback+'(); ');\n\t});\n\t$('#content-updater .filelist button').click(function(){\n\t\t$('#content-updater .filelist').hide();\n\t\t$('#content-updater .result').html('正在更新系统文件，请耐心等待...');\n\t\tupdater_get_file();\n\t});\n\t$('#switch_to_dev').click(function(){\n\t\tswitch_channel('dev', '<p>确定要切换到开发版么？</p><p>开发版具有一定的不稳定性，且有可能无法切换回稳定版</p>');\n\t});\n\t$('#switch_to_stable').click(function(){\n\t\tswitch_channel('stable', '<p>确定要切换到稳定版么？</p><p>如果开发版版本号与稳定版不同，可能导致系统无法使用。<br>切换前请慎重考虑！</p>');\n\t});\n\tvar copyright_time = 0, copyright_clicks = 1;\n\t$('.copyright').click(function(){\n\t\tconsole.log('You\\'d clicked copyright text :D');\n\t\tif(AF == 1) return;\n\t\tif(Date.now() - copyright_time > 500){\n\t\t\tcopyright_time = Date.now();\n\t\t\tcopyright_clicks = 1;\n\t\t\treturn;\n\t\t}\n\t\tcopyright_time = Date.now();\n\t\tif(copyright_clicks < 7){\n\t\t\tcopyright_clicks++;\n\t\t} else {\n\t\t\tvar fwin = createWindow();\n\t\t\tvar contents = '';\n\t\t\tcontents += '<p>To avoid the abuse of these tools, this dialog has been written in English.</p>';\n\t\t\tcontents += '<p>These tools are more helpful is you are a professional user.</p>';\n\t\t\tcontents += '<p style=\"color: red\">Some of these fetures may be harmful to your site, and we DON\\'T take any responsibility. please comfirm you\\'d read this.</p>';\n\t\t\tcontents += '<p><input type=\"text\" placeholder=\"Type: ENABLE ADVANCED FETURES to enable\" style=\"width: 100%\" onkeyup=\"eNaBlEaFcHeCk(this, '+fwin.id+')\" onpaste=\"return false\" /></p>';\n\t\t\tfwin.setTitle('Enable Advanced Fetures?').setContent(contents).addCloseButton('Dismiss').append();\n\t\t}\n\t});\n\t$('#reset_failure_all').click(function(){\n\t\tcreateWindow().setTitle(\"全部重置\").setContent('你确定要重置所有用户无法签到的贴吧吗？这将消耗大量服务器资源').addButton(\"确定\", function(){msg_callback_action('admin.php?action=reset_failure&formhash='+formhash,load_stat);}).addCloseButton(\"取消\").append();\n\t});\n\t$('#mail_advanced_config').click(function(){\n\t\tpost_win($('#mail_setting').attr('action'), 'mail_setting', function(){\n\t\t\tshowloading();\n\t\t\t$.getJSON(\"admin.php?action=mail_advanced\", function(result){\n\t\t\t\tif(!result) return;\n\t\t\t\tvar content = '';\n\t\t\t\tfor(var i=0; i<result.length; i++){\n\t\t\t\t\tcontent += '<p>'+result[i].name+':'+(result[i].description ? ' ('+result[i].description+')' : '')+'</p><p>';\n\t\t\t\t\tcontent += '<input type=\"'+result[i].type+'\" name=\"'+result[i].key+'\" value=\"'+result[i].value+'\" style=\"width: 95%\" />';\n\t\t\t\t\tcontent += '</p>';\n\t\t\t\t}\n\t\t\t\tif(result.length == 0){\n\t\t\t\t\tcontent += '<p>此邮件接口无高级设置项目</p>';\n\t\t\t\t}\n\t\t\t\tcreateWindow().setTitle('邮件高级设置').setContent('<form method=\"post\" action=\"admin.php?action=mail_advanced\" id=\"advanced_mail_config\" onsubmit=\"return post_win(this.action, this.id)\"><input type=\"hidden\" name=\"formhash\" value=\"'+formhash+'\">'+content+'</form>').addButton('确定', function(){ $('#advanced_mail_config').submit(); }).addCloseButton('取消').append();\n\t\t\t}).fail(function() { createWindow().setTitle('邮件高级设置').setContent('发生未知错误: 无法打开高级设置面板').addCloseButton('确定').append(); }).always(function(){ hideloading(); });\n\t\t}, true);\n\t\treturn false;\n\t});\n\t$('.menubtn').click(function(){\n\t\t$('.sidebar').fadeIn();\n\t\tautohide_sidebar();\n\t});\n\t$(window).on('hashchange', function() {\n\t\tparse_hash();\n\t});\n\thideloading();\n\twhile(location.hash.lastIndexOf('#') > 0) location.hash = location.hash.substring(0, location.hash.lastIndexOf('#'));\n\tparse_hash();\n});\n\nfunction load_user(){\n\tshowloading();\n\t$.getJSON(\"admin.php?action=load_user\", function(result){\n\t\tif(!result) return;\n\t\t$('#content-user table tbody').html('');\n\t\t$.each(result, function(i, field){\n\t\t\t$(\"#content-user table tbody\").append(\"<tr><td>\"+field.uid+\"</td><td>\"+field.username+\"</td><td class=\\\"mobile_hidden\\\">\"+field.email+\"</td><td><a href=\\\"admin.php?action=update_liked_tieba&uid=\"+field.uid+\"&formhash=\"+formhash+\"\\\" onclick=\\\"return msg_win_action(this.href)\\\">\"+(isMobile() ? '刷新' : '刷新喜欢的贴吧')+\"</a> | <a href=\\\"javascript:;\\\" onclick=\\\"return deluser('\"+field.uid+\"')\\\">\"+(isMobile() ? '删除' : '删除用户')+\"</a></td></tr>\");\n\t\t});\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取用户列表').addCloseButton('确定').append(); }).always(function(){ hideloading(); });\n}\nfunction switch_channel(channel, tips){\n\tcreateWindow().setTitle('切换分支').setContent(tips).addButton('确定', function(){ msg_redirect_action(\"admin.php?action=switch_channel&channel=\"+channel+\"&formhash=\"+formhash); }).addCloseButton('取消').append();\n}\nfunction updater_get_file(){\n\t$.getJSON(\"admin.php?action=get_file\", function(result){\n\t\tif(!result) return;\n\t\tif(result.status == 1){\n\t\t\treturn updater_write_file();\n\t\t}else if(result.status < 0){\n\t\t\t$('#content-updater .result').html('更新过程出现错误！');\n\t\t\tswitch(result.status){\n\t\t\t\tcase -1:\t$('#content-updater .result').append('下载文件 '+result.file+' 失败');\tbreak;\n\t\t\t\tcase -2:\t$('#content-updater .result').append('校验文件 '+result.file+' 出错');\tbreak;\n\t\t\t\tcase -3:\t$('#content-updater .result').append('当前环境不支持自动更新，请<a href=\"http://www.kookxiang.com/svn_updater.php\" target=\"_blank\">使用论坛提供的 SVN 更新工具进行更新</a>');\tbreak;\n\t\t\t}\n\t\t\tsetTimeout(function(){ location.reload(); }, 10000);\n\t\t\treturn;\n\t\t}\n\t\t$('#content-updater .result').html('正在下载 '+result.file+'，请耐心等待... ('+result.precent+'%)');\n\t\tsetTimeout(updater_get_file, 50);\n\t}).fail(function() { $('#content-updater .result').html('发生未知错误: 程序意外终止'); setTimeout(load_updater, 3000); });\n}\nfunction updater_write_file(){\n\t$.getJSON(\"admin.php?action=write_file\", function(result){\n\t\tif(!result) return;\n\t\tif(result.status == -1){\n\t\t\t$('#content-updater .result').html('以下文件不可写入，请设置好权限后再进行升级');\n\t\t\t$('#content-updater .filelist').show();\n\t\t\t$('#content-updater .filelist ul').html('');\n\t\t\t$.each(result.files, function(i, field){\n\t\t\t\t$('#content-updater .filelist ul').append('<li>'+field+'</li>');\n\t\t\t});\n\t\t\treturn;\n\t\t}else if(result.status == -2){\n\t\t\t$('#content-updater .result').html('更新过程出现错误！');\n\t\t\tswitch(result._status){\n\t\t\t\tcase -1:\t$('#content-updater .result').append('下载文件 '+result.file+' 失败');\tbreak;\n\t\t\t\tcase -2:\t$('#content-updater .result').append('校验文件 '+result.file+' 出错');\tbreak;\n\t\t\t}\n\t\t\tsetTimeout(function(){ location.reload(); }, 5000);\n\t\t\treturn;\n\t\t}\n\t\t$('#content-updater .result').html('文件更新结束！');\n\t\tsetTimeout(function(){ location.reload(); }, 1500);\n\t}).fail(function() { $('#content-updater .result').html('发生未知错误: 程序意外终止'); setTimeout(load_updater, 3000); });\n}\nfunction load_stat(){\n\tshowloading();\n\t$.getJSON(\"admin.php?action=load_userstat\", function(result){\n\t\tif(!result) return;\n\t\t$('#content-stat table tbody').html('');\n\t\t$.each(result, function(i, field){\n\t\t\tif(parseInt(field.unsupport) > 0) field.unsupport += ' (<a href=\"admin.php?action=reset_failure&uid='+field.uid+'&formhash='+formhash+'\" onclick=\"return msg_win_action(this.href)\">重置</a>)';\n\t\t\t$(\"#content-stat table tbody\").append(\"<tr><td>\"+field.uid+\"</td><td>\"+field.username+\"</td><td>\"+field.succeed+\"</td><td>\"+field.skiped+\"</td><td>\"+field.waiting+\"</td><td>\"+field.retry+\"</td><td>\"+field.unsupport+\"</td></tr>\");\n\t\t});\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取用户统计数据').addCloseButton('确定').append(); }).always(function(){ hideloading(); });\n}\nfunction load_updater(){\n\t$('#content-updater .filelist').hide();\n\t$('#content-updater .result').html('正在检查更新...');\n\t$.getJSON(\"admin.php?action=update_check\", function(result){\n\t\tif(!result) return;\n\t\tif(result.status<0){\n\t\t\t$('#content-updater .result').html('错误: 与更新服务器断开连接');\n\t\t\treturn;\n\t\t}else if(result.status == 0){\n\t\t\t$('#content-updater .result').html('所有文件都是最新的！');\n\t\t\treturn;\n\t\t}\n\t\t$('#content-updater .result').html('以下文件可以更新: ');\n\t\t$('#content-updater .filelist').show();\n\t\t$('#content-updater .filelist ul').html('');\n\t\t$.each(result.files, function(i, field){\n\t\t\t$('#content-updater .filelist ul').append('<li>'+field+'</li>');\n\t\t});\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取数据').addCloseButton('确定').append(); });\n}\nfunction load_setting(){\n\tshowloading();\n\t$.getJSON(\"admin.php?action=load_setting\", function(result){\n\t\tif(!result) return;\n\t\t$('#account_switch').attr('checked', result.account_switch == 1);\n\t\t$('#register_check').attr('checked', result.register_check == 1);\n\t\t$('#register_limit').attr('checked', result.register_limit == 1);\n\t\t$('#autoupdate').attr('checked', result.autoupdate == 1);\n\t\t$('#block_register').attr('checked', result.block_register == 1);\n\t\t$('#invite_code').attr('value', result.invite_code ? result.invite_code : '');\n\t\t$('#beian_no').attr('value', result.beian_no ? result.beian_no : '');\n\t\t$('#stat_code').html(result.stat_code ? result.stat_code : '');\n\t\t$('#max_tieba').val(result.max_tieba);\n\t\t$('#extra_title').val(result.extra_title);\n\t\tif(AF == 1) $('#admin_uid').val(result.admin_uid);\n\t\t$('input[name=jquery_mode]').attr('checked', false);\n\t\tvar target = $('input[name=\"jquery_mode\"][value=\"' + result.jquery_mode + '\"]');\n\t\tif (target.length == 0) target = $('input[name=\"jquery_mode\"]').eq(0);\n\t\ttarget.prop('checked', true);\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取当前系统设置').addCloseButton('确定').append(); }).always(function(){ hideloading(); });\n}\nfunction load_cron(){\n\tshowloading();\n\t$.getJSON(\"admin.php?action=load_cron\", function(result){\n\t\tif(!result) return;\n\t\t$('#content-cron table tbody').html('');\n\t\t$.each(result, function(i, field){\n\t\t\tvar content = '';\n\t\t\tcontent += '<tr>';\n\t\t\tcontent += '<td>'+(i+1)+'</td>';\n\t\t\tcontent += '<td>'+field.type+'</td>';\n\t\t\tcontent += '<td>'+field.id+'</td>';\n\t\t\tif(field.nextrun > 0){\n\t\t\t\tcontent += '<td>'+format_time(field.nextrun)+'后</td>';\n\t\t\t\tcontent += '<td>执行完毕</td>';\n\t\t\t}else{\n\t\t\t\tcontent += '<td>'+format_time(-field.nextrun)+'前</td>';\n\t\t\t\tcontent += AF == 1 ? '<td>队列中 (<a href=\"admin.php?action=skip_cron&formhash='+formhash+'&cid='+field._id+'\" onclick=\"return msg_callback_action(this.href, load_cron)\">跳过</a>)</td>' : '<td>队列中</td>';\n\t\t\t}\n\t\t\tcontent += '</tr>';\n\t\t\t$('#content-cron table tbody').append(content);\n\t\t});\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取计划任务列表').addCloseButton('确定').append(); }).always(function(){ hideloading(); });\n}\nfunction format_time(time){\n\tif(time > 604800){\n\t\treturn '>7天';\n\t}else if(time > 86400){\n\t\treturn Math.floor(time / 86400)+'天';\n\t}else if(time > 3600){\n\t\treturn Math.floor(time / 3600)+'小时';\n\t}else if(time > 60){\n\t\treturn Math.floor(time / 60)+'分钟';\n\t}else{\n\t\treturn time+'秒';\n\t}\n}\nfunction load_plugin(){\n\tshowloading();\n\t$.getJSON(\"admin.php?action=load_plugin\", function(result){\n\t\tif(!result) return;\n\t\t$('#content-plugin table tbody').html('');\n\t\t$.each(result, function(i, field){\n\t\t\tvar mod_actions = '';\n\t\t\tif(field.installed){\n\t\t\t\tif(field.enabled){\n\t\t\t\t\tmod_actions += '<a href=\"admin.php?action=disable_plugin&pluginid='+field.id+'&formhash='+formhash+'\" class=\"link_disable\">禁用</a> | ';\n\t\t\t\t\tif(field.config) mod_actions += '<a href=\"admin.php?action=config_plugin&pluginid='+field.id+'\" class=\"link_config\">设置</a> | ';\n\t\t\t\t}else{\n\t\t\t\t\tmod_actions += '<a href=\"admin.php?action=enable_plugin&pluginid='+field.id+'&formhash='+formhash+'\" class=\"link_enable\">启用</a> | ';\n\t\t\t\t}\n\t\t\t\tmod_actions += '<a href=\"admin.php?action=uninstall_plugin&pluginid='+field.id+'&formhash='+formhash+'\" class=\"link_uninstall\">卸载</a>';\n\t\t\t}else{\n\t\t\t\tmod_actions += '<a href=\"admin.php?action=install_plugin&pluginid='+field.id+'&formhash='+formhash+'\" class=\"link_install\">安装</a>';\n\t\t\t}\n\t\t\t$(\"#content-plugin table tbody\").append(\"<tr><td>\"+(i+1)+\"</td><td>\"+field.id+\"</td><td>\"+field.description+\"</td><td>\"+field.version+\"</td><td>\"+mod_actions+\"</td></tr>\");\n\t\t});\n\t\t$('.link_enable, .link_disable').click(function(){\n\t\t\treturn msg_callback_action(this.href, load_plugin);\n\t\t});\n\t\t$('.link_install').click(function(){\n\t\t\tvar link = this.href;\n\t\t\tcreateWindow().setTitle('安装插件').setContent('<p>确定要安装这个插件吗？</p>').addButton('确定', function(){ msg_callback_action(link, load_plugin); }).addCloseButton('取消').append();\n\t\t\treturn false;\n\t\t});\n\t\t$('.link_uninstall').click(function(){\n\t\t\tvar link = this.href;\n\t\t\tcreateWindow().setTitle('卸载插件').setContent('<p>确定要卸载这个插件吗？</p><p>(卸载后该插件的数据可能会丢失)</p>').addButton('确定', function(){ msg_callback_action(link, load_plugin); }).addCloseButton('取消').append();\n\t\t\treturn false;\n\t\t});\n\t\t$('.link_config').click(function(){\n\t\t\tvar link = this.href;\n\t\t\tshowloading();\n\t\t\t$.getJSON(link, function(result){\n\t\t\t\tcreateWindow().setTitle('插件设置').setContent('<form method=\"post\" action=\"'+link+'\" id=\"plugin_config\" onsubmit=\"return post_win(this.action, this.id)\"><input type=\"hidden\" name=\"formhash\" value=\"'+formhash+'\">'+result.html+'</form>').addButton('确定', function(){ $('#plugin_config').submit(); }).addCloseButton('取消').append();\n\t\t\t}).fail(function() { createWindow().setTitle('插件设置').setContent('发生未知错误: 无法打开插件设置面板').addCloseButton('确定').append(); }).always(function(){ hideloading(); });\n\t\t\treturn false;\n\t\t});\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取插件列表').addCloseButton('确定').append(); }).always(function(){ hideloading(); });\n}\nfunction load_template(){\n\tshowloading();\n\t$.getJSON(\"admin.php?action=load_template\", function(result){\n\t\tif(!result) return;\n\t\t$('#content-template .template-list').html('');\n\t\t$.each(result, function(i, field){\n\t\t\tvar content = '<li'+(field.current==true?' class=\"current\"':'')+' templateid=\"'+field.id+'\"name=\"'+field.name+'\" author=\"'+field.author+'\" site=\"'+field.site+'\" version=\"'+field.version+'\"><div><img src=\"'+field.preview+'\" title=\"预览图片\"/><div><p>'+field.name+'</p></div>';\n\t\t\tif(field.current == true) $(\"#content-template .template-list\").prepend(content);\n\t\t\telse $(\"#content-template .template-list\").append(content);\n\t\t});\n\t\t$('#content-template .template-list li').click(function(){\n\t\t\tvar obj = $(this);\n\t\t\tvar current = obj.attr('class')=='current';\n\t\t\tvar title = current ? obj.attr('name') + ' (当前模板)' : obj.attr('name') + ' ('+obj.attr('version')+')';\n\t\t\tvar tips = '<p style=\"width:100%;\"><img style=\"width:100%; border:1px solid #979595; border-radius:3px;margin:8px 0 -10px 0;\" src=\"'+obj.find('img').eq(0).attr('src')+'\" /></p><p>感谢本模板作者 <a href=\"'+obj.attr('site')+'\" target=\"_blank\">'+obj.attr('author')+'</a></p>';\n\t\t\tvar tipsWindow = createWindow().setTitle(title).setContent(tips);\n\t\t\tif (current) tipsWindow.addCloseButton('关闭');\n\t\t\telse tipsWindow.addButton('使用此模板', function(){ msg_redirect_action(\"admin.php?action=set_template&template=\"+obj.attr('templateid')+\"&formhash=\"+formhash); }).addCloseButton('关闭');\n\t\t\ttipsWindow.append();\n\t\t});\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取模板列表').addCloseButton('确定').append(); }).always(function(){ hideloading(); });\n}\nfunction parse_hash(){\n\tvar hash = location.hash.substring(1);\n\tif(hash.indexOf('#') >= 0){\n\t\tlocation.href = location.href.substring(0, location.href.lastIndexOf('#'));\n\t\tlocation.reload();\n\t\treturn;\n\t}\n\tif(hash == \"user\"){\n\t\t$('#menu_user').click();\n\t}else if(hash == \"stat\"){\n\t\t$('#menu_stat').click();\n\t}else if(hash == \"setting\"){\n\t\t$('#menu_setting').click();\n\t}else if(hash == \"mail\"){\n\t\t$('#menu_mail').click();\n\t}else if(hash == \"plugin\"){\n\t\t$('#menu_plugin').click();\n\t}else if(hash == \"template\"){\n\t\t$('#menu_template').click();\n\t}else if(hash == \"cron\"){\n\t\t$('#menu_cron').click();\n\t}else if(hash == \"updater\"){\n\t\t$('#menu_updater').click();\n\t}else{\n\t\t$('#menu_user').click();\n\t}\n}\nfunction deluser(uid){\n\tcreateWindow().setTitle('删除用户').setContent('确认要删除该用户吗？').addButton('确定', function(){ msg_win_action(\"admin.php?action=deluser&uid=\"+uid+\"&formhash=\"+formhash); }).addCloseButton('取消').append();\n\treturn false;\n}\nfunction autohide_sidebar(){\n\tif($(\".sidebar:hover\").length > 0) return setTimeout(autohide_sidebar, 500);\n\tif($(\".menubtn:hover\").length > 0) return setTimeout(autohide_sidebar, 500);\n\t$('.sidebar').fadeOut();\n}\nfunction isMobile(){\n\treturn $('body').width() <= 550;\n}\nfunction eNaBlEaFcHeCk(obj, fwin_id){\n\tobj.value = obj.value.toUpperCase();\n\tif(bin2hex(obj.value) != '454e41424c4520414456414e4345442046455455524553') return;\n\tlocation.href = 'admin.php?action=eNaBlEaFc&hash='+bin2hex(obj.value).split('').reverse().join('')+'&formhash='+formhash;\n\tFWIN[fwin_id].close();\n}\nfunction bin2hex(s) {\n\tvar i, l, o = '', n;\n\ts += '';\n\tfor (i = 0, l = s.length; i < l; i++) {\n\t\tn = s.charCodeAt(i).toString(16);\n\t\to += n.length < 2 ? '0' + n : n;\n\t}\n\treturn o;\n}\n"
  },
  {
    "path": "template/default/js/fwin.js",
    "content": "var fwin_id = 1;\nvar FWIN = [];\nfunction createWindow(){\n\tvar win = new Object();\n\tFWIN[fwin_id] = win;\n\twin.id = fwin_id++;\n\twin.obj = document.createElement('div');\n\twin.obj.className = 'fwin';\n\twin.obj.id = 'fwin_' + win.id;\n\twin.title = '提示信息';\n\twin.content = 'null';\n\twin.btns = document.createElement('p');\n\twin.btns.className = 'btns';\n\twin.with_cover = true;\n\twin.setTitle = function(str){\n\t\tthis.title = str;\n\t\treturn this;\n\t}\n\twin.setContent = function(str){\n\t\tthis.content = str;\n\t\treturn this;\n\t}\n\twin.addButton = function(title, callback, buttonClass){\n\t\tvar btn = document.createElement('button');\n\t\tbtn.className = typeof buttonClass == 'undefined' ? \"btn submit\" : buttonClass;\n\t\tbtn.innerHTML = title;\n\t\tbtn.onclick = function(){\n\t\t\tcallback();\n\t\t\twin.close();\n\t\t}\n\t\tthis.btns.appendChild(btn);\n\t\treturn this;\n\t}\n\twin.addCloseButton = function(title){\n\t\tvar btn = document.createElement('button');\n\t\tbtn.className = \"btn\";\n\t\tbtn.innerHTML = title;\n\t\tbtn.onclick = function(){\n\t\t\twin.close();\n\t\t}\n\t\tthis.btns.appendChild(btn);\n\t\treturn this;\n\t}\n\twin.append = function(){\n\t\tvar win_title = document.createElement('h3');\n\t\twin_title.innerHTML = this.title;\n\t\tvar obj = this.obj;\n\t\twin_title.onmousedown = function(event){ try{ dragMenu(obj, event, 1); }catch(e){} };\n\t\twin_title.unselectable = true;\n\t\tthis.obj.appendChild(win_title);\n\t\tvar win_content = document.createElement('div');\n\t\twin_content.className = 'fcontent';\n\t\twin_content.innerHTML = this.content;\n\t\tthis.obj.appendChild(win_content);\n\t\tif (this.btns.innerHTML) {\n\t\t\tthis.obj.appendChild(this.btns);\n\t\t}\n\t\t$('#append_parent').append(this.obj);\n\t\tvar top = (document.body.clientHeight - this.obj.clientHeight) / 2;\n\t\tvar left = (document.body.clientWidth - this.obj.clientWidth) / 2;\n\t\tthis.obj.style.top = top + 'px';\n\t\tthis.obj.style.left = left + 'px';\n\t\tif(this.with_cover){\n\t\t\t$('.wrapper').addClass('blur');\n\t\t\tshowcover();\n\t\t}\n\t\treturn false;\n\t}\n\twin.close = function(){\n\t\tif(this.with_cover) hidecover();\n\t\twin.obj.className = 'fwin h';\n\t\t$('.wrapper').removeClass('blur');\n\t\tsetTimeout(function(){ $(win.obj).remove(); }, 300);\n\t}\n\treturn win;\n}\nfunction msg_win_action(link){\n\tlink += link.indexOf('?') < 0 ? '?' : '&';\n\tlink += \"format=json\";\n\tshowloading();\n\t$.getJSON(link, function(result){\n\t\tcreateWindow().setTitle('系统消息').setContent(result.msg).addCloseButton('确定').append();\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法解析返回结果').addButton('确定', function(){ location.reload(); }).append(); }).always(function(){ hideloading(); });\n\treturn false;\n}\nfunction msg_redirect_action(link){\n\tlink += link.indexOf('?') < 0 ? '?' : '&';\n\tlink += \"format=json\";\n\tshowloading();\n\t$.getJSON(link, function(result){\n\t\tcreateWindow().setTitle('系统消息').setContent(result.msg).addButton('确定', function(){ location.href = result.redirect; }).append();\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法解析返回结果').addButton('确定', function(){ location.reload(); }).append(); }).always(function(){ hideloading(); });\n\treturn false;\n}\nfunction msg_callback_action(link, callback){\n\tlink += link.indexOf('?') < 0 ? '?' : '&';\n\tlink += \"format=json\";\n\tshowloading();\n\t$.getJSON(link, function(result){\n\t\tcreateWindow().setTitle('系统消息').setContent(result.msg).addButton('确定', function(){ callback(); }).append();\n\t}).fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法解析返回结果').addButton('确定', function(){ location.reload(); }).append(); }).always(function(){ hideloading(); });\n\treturn false;\n}\nfunction upgrade_tips(){\n\tcreateWindow().setTitle('系统更新').setContent('检测到有新的版本可用，现在更新吗？').addButton('现在更新', function(){ location.href='admin.php#updater'; }).addButton('稍后再说', function(){ $.get('index.php?ignore_update=yes'); }, 'btn').append();\n}\nvar loading_timer, cover_timer;\nfunction showloading(){\n\tif(loading_timer) clearTimeout(loading_timer);\n\t$('.loading-icon').removeClass('h');\n\t$('.loading-icon').removeClass('hidden');\n}\nfunction hideloading(){\n\tif(loading_timer) clearTimeout(loading_timer);\n\t$('.loading-icon').removeClass('h');\n\t$('.loading-icon').addClass('h');\n\tloading_timer = setTimeout(function(){ $('.loading-icon').addClass('hidden'); }, 250);\n}\nfunction showcover(){\n\tif(cover_timer) clearTimeout(cover_timer);\n\t$('.cover').removeClass('h');\n\t$('.cover').removeClass('hidden');\n}\nfunction hidecover(){\n\tif(cover_timer) clearTimeout(cover_timer);\n\t$('.cover').removeClass('h');\n\t$('.cover').addClass('h');\n\tcover_timer = setTimeout(function(){ $('.cover').addClass('hidden'); }, 1000);\n}\nfunction post_win(link, formid, callback, skip_win){\n\tlink += link.indexOf('?') < 0 ? '?' : '&';\n\tlink += \"format=json\";\n\tshowloading();\n\t$.post(link, $('#'+formid).serialize(), function(result){\n\t\tif(!callback && result.redirect) callback = function(){ location.href = result.redirect; }\n\t\tif(skip_win) return callback();\n\t\tvar win = createWindow().setTitle('系统消息').setContent(result.msg);\n\t\tif(callback){\n\t\t\twin.addButton('确定', callback);\n\t\t}else{\n\t\t\twin.addCloseButton('确定');\n\t\t}\n\t\twin.append();\n\t}, 'json').fail(function() { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法解析返回结果').addButton('确定', function(){ location.reload(); }).append(); }).always(function(){ hideloading(); });\n\treturn false;\n}\nvar JSMENU = [];\nfunction dragMenu(menuObj, e, op) {\n\te = e ? e : window.event;\n\tif(op == 1) {\n\t\tJSMENU['drag'] = [e.clientX, e.clientY];\n\t\tJSMENU['drag'][2] = parseInt(menuObj.style.left);\n\t\tJSMENU['drag'][3] = parseInt(menuObj.style.top);\n\t\tdocument.onmousemove = function(e) { try{dragMenu(menuObj, e, 2); }catch(err){} };\n\t\tdocument.onmouseup = function(e) { try{dragMenu(menuObj, e, 3); }catch(err){} };\n\t}else if(op == 2 && JSMENU['drag'][0]) {\n\t\tvar menudragnow = [e.clientX, e.clientY];\n\t\tmenuObj.style.left = (JSMENU['drag'][2] + menudragnow[0] - JSMENU['drag'][0]) + 'px';\n\t\tmenuObj.style.top = (JSMENU['drag'][3] + menudragnow[1] - JSMENU['drag'][1]) + 'px';\n\t\tmenuObj.removeAttribute('top_');\n\t\tmenuObj.removeAttribute('left_');\n\t}else if(op == 3) {\n\t\tJSMENU['drag'] = [];\n\t\tdocument.onmousemove = null;\n\t\tdocument.onmouseup = null;\n\t}\n\treturn false;\n}\n"
  },
  {
    "path": "template/default/js/kk_dropdown.js",
    "content": "// KK Drop-down menu\n(function(){\n\tfunction open_menu(obj){\n\t\tvar menuid = 'dropdown_' + obj.getAttribute('menu-id');\n\t\tif(!document.getElementById(menuid)) return false;\n\t\tobj.hover = true;\n\t\tdocument.getElementById(menuid).onmouseover = function(){ obj.hover = true; };\n\t\tdocument.getElementById(menuid).onmouseout = function(){ obj.hover = false; };\n\t\tdocument.getElementById(menuid).style.display = 'block';\n\t\tdocument.getElementById(menuid).style.top = obj.offsetTop + obj.offsetHeight + 'px';\n\t\tvar left = obj.offsetLeft + obj.offsetWidth - document.getElementById(menuid).offsetWidth;\n\t\tif(left <= 0){\n\t\t\tdocument.getElementById(menuid).style.left = obj.offsetLeft - 5 + 'px';\n\t\t}else{\n\t\t\tdocument.getElementById(menuid).style.left = left + 'px';\n\t\t}\n\t\tclose_menu(obj);\n\t}\n\tfunction close_menu(obj, force){\n\t\tvar menuid = 'dropdown_' + obj.getAttribute('menu-id');\n\t\tif(!document.getElementById(menuid)) return false;\n\t\tif(!force && (document.getElementById(menuid).hover || obj.hover)){\n\t\t\tsetTimeout(function(){ close_menu(obj); }, 100);\n\t\t}else{\n\t\t\tdocument.getElementById(menuid).style.display = 'none';\n\t\t}\n\t}\n\tvar selects = document.getElementsByTagName('select');\n\tvar select;\n\tfor(i in selects){\n\t\tselect_obj = selects[i];\n\t\tif(typeof select_obj != 'object') continue;\n\t\tif(select_obj.inited) continue;\n\t\tselect_obj.inited = true;\n\t\tselect_obj.style.display = 'none';\n\t\tvar dropdown_obj = document.createElement('ul');\n\t\tdropdown_obj.id = 'dropdown_' + i;\n\t\tdropdown_obj.className = 'dropdown';\n\t\tdropdown_obj.obj = select_obj;\n\t\tvar select_replacer = document.createElement('div');\n\t\tdropdown_obj.replacer = select_replacer;\n\t\tselect_obj.replacer = select_replacer;\n\t\tselect_replacer.className = 'select';\n\t\tselect_replacer.setAttribute(\"menu-id\", i);\n\t\tselect_replacer.obj = select_obj;\n\t\tvar value_obj = document.createElement('span');\n\t\tselect_replacer.value = value_obj;\n\t\tselect_replacer.appendChild(value_obj);\n\t\tvar icon_down = document.createElement('span');\n\t\ticon_down.className = \"icon\";\n\t\ticon_down.innerText = '▼';\n\t\tselect_replacer.appendChild(icon_down);\n\t\tfor(var o=0; o<select_obj.options.length; o++){\n\t\t\tvar option_item = document.createElement('li');\n\t\t\toption_item.innerHTML = select_obj.options[o].innerHTML;\n\t\t\tvar option_value = select_obj.options[o].value;\n\t\t\toption_item.setAttribute(\"value\", option_value);\n\t\t\toption_item.onclick = function(){ this.parentNode.obj.value = this.getAttribute('value'); this.parentNode.replacer.value.innerHTML=this.innerHTML; close_menu(this.parentNode.replacer, true); };\n\t\t\tdropdown_obj.appendChild(option_item);\n\t\t\tif(select_obj.value == select_obj.options[o].value) select_replacer.value.innerHTML = select_obj.options[o].innerHTML;\n\t\t\tselect_obj.onchange = function(){ for(var p=0; p<this.options.length; p++) { if(this.value == this.options[p].value) this.replacer.value.innerHTML = this.options[p].innerHTML; } return true; };\n\t\t}\n\t\tselect_replacer.onmouseout = function(){ this.hover = false; };\n\t\tselect_replacer.onmouseover = function(){ this.hover = true;}\n\t\tselect_replacer.onclick = function(){ open_menu(this); };\n\t\tselect_obj.parentNode.insertBefore(select_replacer, select_obj);\n\t\tselect_obj.parentNode.insertBefore(dropdown_obj, select_obj);\n\t}\n})();\n\n// jQuery hooks\n$.valHooks.select = {\n\tset: function(elem, value) {\n\t\telem.value = value;\n\t\telem.onchange();\n\t},\n};\n"
  },
  {
    "path": "template/default/js/main.js",
    "content": "$(document).ready(function () {\n    $('#menu>li').click(function () {\n        if (isMobile()) $('.sidebar').fadeOut();\n        if ($(this).attr('id') == 'menu_updater') return;\n        if ($(this).attr('id') == 'menu_admincp') return;\n        if ($(this).hasClass('selected')) return;\n        $('.menu li.selected').removeClass('selected');\n        $(this).addClass('selected');\n        var content_id = $(this).attr('id').replace('menu_', '#content-');\n        $('.main-content>div').addClass('hidden');\n        $(content_id).removeClass('hidden');\n        var callback = $(this).attr('id').replace('menu_', 'load_').replace('-', '_');\n        eval('if (typeof ' + callback + ' == \"function\") ' + callback + '(); ');\n    });\n    $('#show_cookie_setting').click(function () {\n        $('.tab-cookie').toggleClass('hidden');\n    });\n    $('#unbind_btn').click(function () {\n        var link = this.href;\n        createWindow().setTitle('解除绑定').setContent('确认要解除绑定吗？<br>(解除绑定后自动签到将停止，所有记录将被清除)').addButton('确定', function () { msg_callback_action(link, load_baidu_bind); }).addCloseButton('取消').append();\n        return false;\n    });\n    $('.menu_switch_user a').click(function () {\n        var link = this.href;\n        createWindow().setTitle('切换账号').setContent('确认要切换登陆账号吗？').addButton('确定', function () { msg_redirect_action(link); }).addCloseButton('取消').append();\n        return false;\n    });\n    $('.menu_switch_user .del').click(function () {\n        var link = this.getAttribute('href');\n        createWindow().setTitle('解除绑定').setContent('确认要解除账号绑定吗？').addButton('确定', function () { msg_redirect_action(link); }).addCloseButton('取消').append();\n        return false;\n    });\n    $('#menu_adduser a').click(function () {\n        createWindow().setTitle('绑定账号').setContent('<form method=\"post\" action=\"member.php?action=bind_user\" id=\"bind_form\" onsubmit=\"return post_win(this.action, this.id)\"><input type=\"hidden\" name=\"formhash\" value=\"' + formhash + '\"><p>使用此功能，你可以快速切换在本站注册的多个帐号。</p><p>输入您的用户名/密码即可绑定到本账号。</p><p><label>用户名： <input type=\"text\" name=\"username\" style=\"width: 200px\" /></label></p><p><label>密　码： <input type=\"password\" name=\"password\" style=\"width: 200px\" /></label></p></form>').addButton('确定', function () { $('#bind_form').submit(); }).addCloseButton('取消').append();\n        return false;\n    });\n    $('#menu_password').click(function () {\n        createWindow().setTitle('修改密码').setContent('<form method=\"post\" action=\"index.php?action=change_password\" id=\"password_form\" onsubmit=\"return post_win(this.action, this.id)\"><input type=\"hidden\" name=\"formhash\" value=\"' + formhash + '\"><p>经常修改密码是个好习惯哦 :)</p><p><label>原密码：　 <input type=\"password\" name=\"old_password\" style=\"width: 200px\" /></label></p><p><label>新密码：　 <input type=\"password\" name=\"new_password\" style=\"width: 200px\" /></label></p><p><label>再次输入： <input type=\"password\" name=\"new_password2\" style=\"width: 200px\" /></label></p></form>').addButton('确定', function () { $('#password_form').submit(); }).addCloseButton('取消').append();\n        return false;\n    });\n    $('#menu_logout').click(function () {\n        createWindow().setTitle('退出').setContent('确认要退出登录吗？').addButton('确定', function () { location.href = 'member.php?action=logout&hash=' + formhash; }).addCloseButton('取消').append();\n        return false;\n    });\n    $('input[name=bind_mode]').change(function (event) {\n        if (!this.checked) return;\n        $('.bind_mode .extension_info').addClass('hidden');\n        $(this).parents('.bind_mode').find('.extension_info').removeClass('hidden');\n    });\n    $('.menubtn').click(function () {\n        $('.sidebar').fadeIn();\n        autohide_sidebar();\n    });\n    $('.avatar').click(function () {\n        $('#member-menu').fadeIn(100);\n        autohide_membermenu();\n    });\n    $('#member-menu li a').click(function () {\n        $('#member-menu').fadeOut(300);\n    });\n    $(window).on('hashchange', function () {\n        parse_hash();\n    });\n    hideloading();\n    while (location.hash.lastIndexOf('#') > 0) location.hash = location.hash.substring(0, location.hash.lastIndexOf('#'));\n    parse_hash();\n    // Load JS\n    load_js();\n    if (new_version) upgrade_tips();\n    loadTiebaAutoComplete();\n});\n\nvar guide_viewed = false;\nvar stat = [];\nif (typeof defered_js == 'undefined') var defered_js = new Array;\nstat[0] = stat[1] = stat[2] = stat[3] = stat[4] = 0;\nvar new_version = false;\n\nfunction load_liked_tieba() {\n    showloading();\n    $.getJSON(\"ajax.php?v=liked_tieba\", function (result) {\n        if (!result) return;\n        $('#content-liked_tieba table tbody').html('');\n        var tieba_name = new Array;\n        var tieba_uname = new Array;\n        $.each(result, function (i, field) {\n            if (typeof localStorage != 'undefined') {\n                tieba_name.push(field.name);\n                tieba_uname.push(field.unicode_name);\n            }\n            $(\"#content-liked_tieba table tbody\").append(\"<tr><td>\" + (i + 1) + \"</td><td><a href=\\\"http://tieba.baidu.com/f?kw=\" + field.unicode_name + \"\\\" target=\\\"_blank\\\">\" + field.name + \"</a></td><td><input type=\\\"checkbox\\\" value=\\\"\" + field.tid + \"\\\"\" + (field.skiped == '1' ? ' checked' : '') + \" class=\\\"skip_sign\\\" /></td></tr>\");\n        });\n        if (typeof localStorage != 'undefined') {\n            localStorage['tieba_name'] = tieba_name.join('||');\n            localStorage['tieba_uname'] = tieba_uname.join('||');\n        }\n        loadTiebaAutoComplete();\n        $('#content-liked_tieba .skip_sign').click(function () {\n            showloading();\n            this.disabled = 'disabled';\n            $.getJSON('index.php?action=skip_tieba&format=json&tid=' + this.value + '&formhash=' + formhash, function (result) { load_liked_tieba(); }).fail(function () {\n                hideloading();\n                createWindow().setTitle('系统错误').setContent('发生未知错误: 无法修改当前贴吧设置').addCloseButton('确定').append();\n            });\n            return false;\n        });\n    }).fail(function () { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取喜欢的贴吧列表').addButton('确定', function () { location.reload(); }).append(); }).always(function () { hideloading(); });\n}\n\nfunction load_sign_log() {\n    showloading();\n    $.getJSON(\"ajax.php?v=sign-log\", function (result) {\n        if (result.count == 0 && !guide_viewed) {\n            $('#menu_guide').click();\n            return;\n        }\n        show_sign_log(result);\n    }).fail(function () { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取签到报告').addButton('确定', function () { location.reload(); }).append(); }).always(function () { hideloading(); });\n}\n\nfunction load_sign_history(date) {\n    $('.menu li.selected').removeClass('selected');\n    $('.main-content>div').addClass('hidden');\n    $('#content-sign_log').removeClass('hidden');\n    showloading();\n    $.getJSON(\"ajax.php?v=sign-history&date=\" + date, function (result) {\n        show_sign_log(result);\n    }).fail(function () { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取签到报告').addButton('确定', function () { location.reload(); }).append(); }).always(function () { hideloading(); });\n}\n\nfunction show_sign_log(result) {\n    stat[0] = stat[1] = stat[2] = stat[3] = stat[4] = 0;\n    if (!result || result.count == 0) return;\n    $('#content-sign_log table tbody').html('');\n    $('#content-sign_log h2').html(result.date + \" 签到记录\");\n    $.each(result.log, function (i, field) {\n        $(\"#content-sign_log table tbody\").append(\"<tr><td>\" + (i + 1) + \"</td><td><a href=\\\"http://tieba.baidu.com/f?kw=\" + field.unicode_name + \"\\\" target=\\\"_blank\\\">\" + field.name + \"</a></td><td>\" + _status(field.status) + \"</td><td>\" + _exp(field.exp) + \"</td></tr>\");\n    });\n    var result_text = \"\";\n    result_text += \"共计 \" + (stat[0] + stat[1] + stat[2] + stat[3] + stat[4]) + \" 个贴吧\";\n    result_text += \", 成功签到 \" + (stat[4]) + \" 个贴吧\";\n    if (stat[2]) result_text += \", 有 \" + (stat[2]) + \" 个贴吧尚未签到\";\n    if (stat[0]) result_text += \", 已跳过 \" + (stat[0]) + \" 个贴吧\";\n    if (stat[3]) result_text += \", \" + (stat[3]) + \" 个贴吧正在等待重试\";\n    if (stat[1]) result_text += \", \" + (stat[1]) + \" 个贴吧无法签到, <a href=\\\"index.php?action=reset_failure&formhash=\" + formhash + \"\\\" onclick=\\\"return msg_redirect_action(this.href)\\\">点此重置无法签到的贴吧</a>\";\n    $('#sign-stat').html(result_text);\n    var pager_text = '';\n    if (result.before_date) pager_text += '<a href=\"#history-' + result.before_date + '\">&laquo; 前一天</a> &nbsp; ';\n    if (!$('#menu_sign_log').hasClass('selected')) pager_text += '<a href=\"#signlog\">今天</a>';\n    if (result.after_date) pager_text += ' &nbsp; <a href=\"#history-' + result.after_date + '\">后一天 &raquo;</a>';\n    $('#page-flip').html(pager_text);\n}\n\nfunction load_setting() {\n    showloading();\n    $.getJSON(\"ajax.php?v=get-setting\", function (result) {\n        if (!result) return;\n        $('#error_mail').attr('checked', result.error_mail == \"1\");\n        $('#send_mail').attr('checked', result.send_mail == \"1\");\n        $('#zhidao_sign').attr('checked', result.zhidao_sign == \"1\");\n        $('#wenku_sign').attr('checked', result.wenku_sign == \"1\");\n        $('#bdbowser').removeAttr('disabled');\n        $('#error_mail').removeAttr('disabled');\n        $('#send_mail').removeAttr('disabled');\n        $('#zhidao_sign').removeAttr('disabled');\n        $('#wenku_sign').removeAttr('disabled');\n    }).fail(function () { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取系统设置').addButton('确定', function () { location.reload(); }).append(); }).always(function () { hideloading(); });\n}\n\nfunction load_guide() {\n    guide_viewed = true;\n}\n\nfunction load_baidu_bind() {\n    showloading();\n    $.getJSON(\"ajax.php?v=get-bind-status\", function (result) {\n        if (!result) return;\n        $('#content-baidu_bind .tab').addClass('hidden');\n        if (result.no == 0) {\n            $('#content-baidu_bind .tab-binded').removeClass('hidden');\n            $('.tab-binded div').removeClass('hidden');\n            $('.tab-binded div').html('');\n            var avatar_img = 'https://ss0.bdstatic.com/7Ls0a8Sm1A5BphGlnYG/sys/portrait/item/' + result.data.user_portrait;\n            $('#avatar_img').attr('src', avatar_img);\n            $('#avatar_img').removeClass('hidden');\n            $('.tab-binded div').append('<img src=\"' + avatar_img + '\" class=\"float-left\">');\n            $('.tab-binded div').append('<p>百度通行证：<a href=\"http://tieba.baidu.com/home/main?un=' + result.data.user_name_url + '\" target=\"_blank\">' + result.data.user_name_show + '</a></p>');\n            $('.tab-binded div').append('<p>安全手机：' + result.data.mobilephone + '</p>');\n            $('.tab-binded div').append('<p>安全邮箱：' + result.data.email + '</p>');\n        } else {\n            $('#content-baidu_bind .tab-bind').removeClass('hidden');\n        }\n    }).fail(function () { createWindow().setTitle('系统错误').setContent('发生未知错误: 无法获取绑定状态').addButton('确定', function () { location.reload(); }).append(); }).always(function () { hideloading(); });\n}\n\nfunction _status(status) {\n    if (typeof status == 'undefined') status = 0;\n    status = parseInt(status);\n    stat[(status + 2)]++;\n    if (isMobile()) {\n        switch (status) {\n            case -2:\n                return '<img src=\"template/default/style/warn.png\" />';\n            case -1:\n                return '<img src=\"template/default/style/error.gif\" />';\n            case 0:\n                return '<img src=\"template/default/style/retry.gif\" />';\n            case 1:\n                return '<img src=\"template/default/style/warn.png\" />';\n            case 2:\n                return '<img src=\"template/default/style/done.gif\" />';\n        }\n    } else {\n        switch (status) {\n            case -2:\n                return '跳过签到';\n            case -1:\n                return '无法签到';\n            case 0:\n                return '待签到';\n            case 1:\n                return '签到失败';\n            case 2:\n                return '已签到';\n        }\n    }\n}\n\nfunction _exp(exp) {\n    if (typeof exp == 'undefined') exp = 0;\n    return parseInt(exp) == 0 ? '-' : '+' + exp;\n}\n\nfunction parse_hash() {\n    var hash = location.hash.substring(1);\n    if (hash.indexOf('#') >= 0) {\n        location.href = location.href.substring(0, location.href.lastIndexOf('#'));\n        location.reload();\n        return;\n    }\n    if (hash == \"guide\") {\n        $('#menu_guide').click();\n    } else if (hash == \"liked_tieba\") {\n        guide_viewed = true;\n        $('#menu_liked_tieba').click();\n    } else if (hash == \"sign_log\") {\n        $('#menu_sign_log').click();\n    } else if (hash == \"baidu_bind\") {\n        $('#menu_baidu_bind').click();\n    } else if (hash == \"setting\") {\n        $('#menu_setting').click();\n    } else if (hash.split('-')[0] == \"history\") {\n        load_sign_history(hash.split('-')[1]);\n    } else if ($('#menu_' + hash).length > 0) {\n        $('#menu_' + hash).click();\n    } else {\n        $('#menu_sign_log').click();\n    }\n}\n\nfunction autohide_membermenu() {\n    if ($(\"#member-menu:hover\").length > 0) return setTimeout(autohide_membermenu, 500);\n    if ($(\".avatar:hover\").length > 0) return setTimeout(autohide_membermenu, 500);\n    $('#member-menu').fadeOut(300);\n}\n\nfunction autohide_sidebar() {\n    if ($(\".sidebar:hover\").length > 0) return setTimeout(autohide_sidebar, 500);\n    if ($(\".menubtn:hover\").length > 0) return setTimeout(autohide_sidebar, 500);\n    $('.sidebar').fadeOut();\n}\n\nfunction isMobile() {\n    return $('body').width() <= 550;\n}\n\nfunction load_js() {\n    for (id in defered_js) {\n        var script;\n        script = document.createElement('script');\n        script.type = 'text/javascript';\n        script.src = defered_js[id] + '?' + Math.random();\n        document.getElementsByTagName('head')[0].appendChild(script);\n    }\n}\n\nfunction loadTiebaAutoComplete() {\n    if (typeof localStorage == 'undefined') return;\n    if (!localStorage['tieba_name']) return;\n    $('#autocomplete-tieba').remove();\n    $('#append_parent').append('<datalist id=\"autocomplete-tieba\" class=\"hidden\"></datalist>');\n    var tieba = localStorage['tieba_name'].split('||');\n    if (tieba.length == 0) return;\n    for (var i = 0; i < tieba.length; i++) {\n        $('#autocomplete-tieba').append('<option value=\"' + tieba[i].replace('\"', \"&quot;\") + '\">');\n    }\n}\n\nfunction cookieProxy(action, callback) {\n    var requestId = Math.random();\n    var proxy = document.getElementById('cookie-proxy').contentWindow;\n    var _callback = function (event) {\n        var result = event.originalEvent;\n        if (!result || !result.data || result.data.id != requestId) return;\n        delete result.data.id;\n        callback(result.data);\n        $(window).off('message', _callback);\n    }\n    proxy.postMessage({\n        id: requestId,\n        action: action\n    }, '*');\n    $(window).on('message', _callback);\n    return false;\n}\n\nfunction checkCookieProxy() {\n    var target = $('#cookie-proxy-info');\n    cookieProxy('getStatus', function (result) {\n        if (!result.inited) {\n            target.html('');\n            target.append('<p>你的浏览器不是 Google Chrome 浏览器，暂时无法一键获取 Cookie</p>');\n            target.append('<p>或无法与 Chrome 消息接口通信（如手机版）</p>');\n            return;\n        } else if (!result.installed) {\n            target.html('');\n            target.append('<p>未安装 Get Tieba Cookie 扩展或不是 Google Chrome 浏览器</p>');\n            target.append('<p>请 <a href=\"https://chrome.google.com/webstore/detail/dpekabpinhnjcikegadjeopgmhphgnce\" onclick=\"return installCookieProxy(this.href)\">点击这里安装扩展</a> 后 <a href=\"javascript:;\" onclick=\"return reloadCookieProxy()\">重试</a></p>');\n        } else if (!result.hasLogin) {\n            target.html('<p>你还没有登录你的百度账号，点击 <a href=\"http://tieba.baidu.com\" target=\"_blank\">登录</a> 或 <a href=\"javascript:;\" onclick=\"return reloadCookieProxy()\">刷新</a></p>');\n        } else {\n            target.html('<p>正在等待用户授权... (<a href=\"javascript:;\" onclick=\"return checkCookieProxy()\">重试</a>)</p>');\n            setTimeout(function () {\n                cookieProxy('getCookie', function (result) {\n                    target.html('<p>百度账号: ' + result.username + '</p>');\n                    target.append('<p>Cookie: 获取成功</p>');\n                    var submitForm = $('<form method=\"post\"></form>');\n                    submitForm.attr('action', 'api.php?action=receive_cookie&local=1&formhash=' + formhash);\n                    submitForm.html('<p><input name=\"cookie\" type=\"hidden\" /><input type=\"submit\" value=\"我要绑定这个账号\" /></p>');\n                    target.append(submitForm);\n                    submitForm.find('input[name=cookie]').val(result.cookie);\n                });\n            }, 100);\n        }\n    });\n    return false;\n}\n\nfunction reloadCookieProxy() {\n    cookieProxy('reload');\n    var callback = function (event) {\n        var result = event.originalEvent;\n        if (!result || !result.data || result.data.type != 'proxy-inited') return;\n        $(window).off('message', callback);\n        checkCookieProxy();\n    }\n    $(window).on('message', callback);\n    return false;\n}\n\nfunction installCookieProxy(url) {\n    $(document.head).find('link[rel=chrome-webstore-item]').remove();\n    $(document.head).append('<link rel=\"chrome-webstore-item\" href=\"' + url + '\">');\n    chrome.webstore.install(url, function () {\n        setTimeout(reloadCookieProxy, 200);\n    });\n    return false;\n}\n"
  },
  {
    "path": "template/default/js/member.js",
    "content": "$(document).ready(function() {\n\t$('#menu_login').click(function(){\n\t\tswitch_tabs('login');\n\t});\n\t$('#menu_register').click(function(){\n\t\tswitch_tabs('register');\n\t});\n});\nfunction switch_tabs(target){\n\t$('.main').addClass('hidden');\n\t$('#content-'+target).removeClass('hidden');\n\t$('.side-bar li').removeClass('current');\n\t$('#menu_'+target).addClass('current');\n}"
  },
  {
    "path": "template/default/member.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n$extra_title = getSetting('extra_title');\n$title = $extra_title ? \"用户中心 - 贴吧签到助手 - {$extra_title}\" : '用户中心 - 贴吧签到助手';\n?>\n<!DOCTYPE html>\n<html>\n<head>\n<title><?php echo $title; ?></title>\n<?php include template('widget/meta'); ?>\n</head>\n<body>\n<div class=\"wrapper\" id=\"page_login\">\n<div class=\"center-box\">\n<div class=\"side-bar\">\n<span class=\"icon\"></span>\n<ul>\n<li id=\"menu_login\" class=\"current\">登录</li>\n<?php if(!getSetting('block_register')) { ?>\n<li id=\"menu_register\">注册</li>\n<?php } ?>\n</ul>\n</div>\n<div class=\"main\" id=\"content-login\">\n<?php include template('widget/login'); ?>\n</div>\n<?php if(!getSetting('block_register')){ ?>\n<div class=\"main hidden\" id=\"content-register\">\n<?php include template('widget/register'); ?>\n</div>\n<?php } ?>\n<div class=\"main hidden\" id=\"content-find_password\">\n<?php include template('widget/find_password'); ?>\n</div>\n</div>\n<!-- 开发不易，跪求各位大大放俺一条生路 -->\n<!-- 你可以在这加你自己的链接，但是麻烦保留下我的链接 Thanks -->\n<p class=\"copyright\">贴吧签到助手 <?php echo VERSION; ?> - Designed by <a href=\"http://www.ikk.me\" target=\"_blank\">kookxiang</a>. 2013-2016 &copy; <a href=\"http://www.kookxiang.com\" target=\"_blank\">KK's Laboratory</a> (<a href=\"http://go.ikk.me/donate\" target=\"_blank\">赞助开发</a>)<?php if(getSetting('beian_no')) echo ' - <a href=\"http://www.miibeian.gov.cn/\" target=\"_blank\" rel=\"nofollow\">'.getSetting('beian_no').'</a>'; ?></p>\n<script src=\"<?php echo jquery_path(); ?>\"></script>\n<script src=\"./template/default/js/member.js?version=<?php echo VERSION; ?>\"></script>\n<?php HOOK::run('member_footer'); ?>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "template/default/message.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<!DOCTYPE html>\n<html>\n<meta charset=utf-8>\n<title>系统消息</title>\n<meta name=viewport content=\"initial-scale=1, minimum-scale=1, width=device-width\">\n<style>\n*{margin:0;padding:0}\nhtml,code{font:15px/22px arial,sans-serif}\nhtml{background:#fff;color:#222;padding:15px}\nbody{margin:7% auto 0;max-width:390px;min-height:220px;padding:75px 0 15px}\n* > body{background:url(template/default/style/msg_bg.png) 100% 5px no-repeat;padding-right:205px}\np{margin:11px 0 22px;overflow:hidden}\nins, ins a{color:#777;text-decoration:none;font-size:10px;}\na img{border:0}\n@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}\n</style>\n<body>\n<p><b>系统消息 - 贴吧签到助手</b></p>\n<?php\necho \"<p>{$msg}</p>\";\nif($redirect)\n\techo \"<ins><a href=\\\"{$redirect}\\\">如果您的浏览器没有自动跳转，请点击这里</a></ins><meta http-equiv=\\\"refresh\\\" content=\\\"{$delay};url={$redirect}\\\" />\";\n?>\n</body>\n</html>"
  },
  {
    "path": "template/default/mobile/message.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<!DOCTYPE html>\n<html>\n<meta charset=utf-8>\n<title>系统消息</title>\n<meta name=viewport content=\"initial-scale=1, minimum-scale=1, width=device-width\">\n<style>\n*{margin:0;padding:0}\nhtml{background:#fff;color:#222;padding:15px}\nbody{margin:20% auto 0;min-height:220px;padding:30px 0 15px}\np{margin:11px 0 22px;overflow:hidden}\nins, ins a{color:#777;text-decoration:none;font-size:10px;}\na img{border:0;margin:0 auto;}\n</style>\n<body>\n<?php\necho \"<p>{$msg}</p>\";\nif($redirect)\n\techo \"<ins><a href=\\\"{$redirect}\\\">如果您的浏览器没有自动跳转，请点击这里</a></ins><meta http-equiv=\\\"refresh\\\" content=\\\"{$delay};url={$redirect}\\\" />\";\n?>\n</body>\n</html>"
  },
  {
    "path": "template/default/style/main.css",
    "content": "::selection { background: rgba(127, 127, 127, 0.3); }\nhtml, body, div, h1, h2, h3, h4, h5, h6, p, img, dl, dt, dd, ol, ul, li, table, tr, td, form, object, embed, article, aside, canvas, command, details, figcaption, figure, footer, group, header, hgroup, mark, menu, meter, nav, output, progress, section, summary, time, audio, video { margin: 0; padding: 0; border: 0; }\narticle, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { display: block; }\nblockquote { margin: 0; }\nhtml { font: 81.25% \"Microsoft YaHei\", arial, helvetica, sans-serif; background: #fff; color: #333; line-height: 1; direction: ltr; word-break: break-all; }\na { color: #15c; text-decoration: none; }\na:active { color: #d14836; }\na:hover { text-decoration: underline; }\na.n:hover { text-decoration: none; }\nh1, h2, h3, h4, h5, h6 { color: #222; font-size: 1.54em; font-weight: normal; line-height: 24px; margin: 0 0 .46em; }\np { line-height: 20px; margin: 0 0 .8em; }\nol, ul { list-style: none; line-height: 17px; margin: 0 0 1em; }\nli { margin: 0 0 .5em; }\ntable { border-collapse: collapse; border-spacing: 0; }\nstrong { color: #222; }\nbutton, input, select, textarea { font-family: inherit; font-size: inherit; }\nbutton::-moz-focus-inner, input::-moz-focus-inner { border: 0; }\n.hidden { display: none; }\n\nhtml, body { position: absolute; height: 100% !important; width: 100% !important; background: #000; }\n.wrapper { position: relative; min-height: 100%; background: #fff; }\n\n.wrapper { transition: filter 3s ease; backface-visibility: hidden; }\n.wrapper.blur { -moz-filter: blur(5px); -webkit-filter: blur(5px); -ms-filter: blur(5px); filter: blur(5px); }\n\n.clearfix:after { visibility: hidden; display: block; font-size: 0; content: '.'; clear: both; height: 0; }\n* html .clearfix { zoom: 1; }\n*:first-child+html .clearfix { zoom: 1; }\n\ntextarea, input[type=password], input[type=text], .input { display: inline-block; border-radius: 2px; height: 29px; margin: 0; padding-left: 8px; background: #fff; border: 1px solid #d9d9d9; border-top: 1px solid #c0c0c0; box-sizing: border-box; #width: 100%; }\ntextarea:hover, .input:hover, input[type=password]:hover, input[type=text]:hover { border: 1px solid #b9b9b9; border-top: 1px solid #a0a0a0; box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); }\ntextarea:focus, .input:focus, input[type=password]:focus, input[type=text]:focus { outline: none; border: 1px solid #4d90fe; box-shadow: inset 0 1px 2px rgba(0,0,0,0.3); }\n.input[disabled=disabled], input[type=password][disabled=disabled], input[type=text][disabled=disabled] { border: 1px solid #e5e5e5; background: #f5f5f5; }\n.input[disabled=disabled]:hover, input[type=password][disabled=disabled]:hover, input[type=text][disabled=disabled]:hover { box-shadow: none; }\ninput[type=checkbox], input[type=radio] { -webkit-appearance: none; -moz-appearance: none; appearance: none; outline: none; width: 13px; height: 13px; margin: 0; padding: 0; cursor: pointer; vertical-align: middle; background: #fff; border: 1px solid #dcdcdc; border-radius: 1px; box-sizing: border-box; position: relative; }\ninput[type=checkbox]:active, input[type=radio]:active { border-color: #c6c6c6; background: #ebebeb; }\ninput[type=checkbox]:hover { border-color: #c6c6c6; box-shadow: inset 0 1px 1px rgba(0,0,0,0.1); }\ninput[type=radio] { border-radius: 1em; width: 15px; height: 15px; }\ninput[type=checkbox]:checked, input[type=radio]:checked { background: #fff; }\ninput[type=radio]:checked::after { content: ''; display: block; position: relative; top: 3px; left: 3px; width: 7px; height: 7px; background: #666; border-radius: 1em; }\ninput[type=checkbox]:checked::after { content: url(checkmark.png); display: block; position: absolute; top: -6px; left: -5px; }\ninput[type=checkbox]:focus { outline: none; border-color: #4d90fe; }\ntextarea { min-height: 120px; #height: 120px; padding: 5px; }\n.input.form-error, input[type=password].form-error, input[type=text].form-error { border: 1px solid #dd4b39; }\n\n.btn, button, input[type=submit] { display: inline-block; min-width: 54px; letter-spacing: 1px; text-align: center; color: #555; font-size: 12px; font-weight: bold; height: 30px; padding: 0 7px 0 8px; line-height: 29px; border-radius: 2px; transition: all 0.218s; border: 1px solid #dcdcdc; border: 1px solid rgba(0,0,0,0.1); background-color: #f5f5f5; background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1); background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1); background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1); background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1); background-image: linear-gradient(top,#f5f5f5,#f1f1f1); -webkit-user-select: none; -moz-user-select: none; user-select: none; cursor: pointer; outline: none; }\nbutton, input[type=submit] { height: 30px; line-height: 30px; vertical-align: bottom; margin: 0; }\n*+html button, *+html input[type=submit] { overflow: visible; }\n.btn:hover, button:active, input[type=submit]:active { border: 1px solid #c6c6c6; color: #333; text-decoration: none; transition: all 0.0s; background-color: #f8f8f8; background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1); background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1); background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1); background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1); background-image: linear-gradient(top,#f8f8f8,#f1f1f1); box-shadow: 0 1px 1px rgba(0,0,0,0.1); }\n.btn:active, button:active, input[type=submit]:active { background-color: #f6f6f6; background-image: -webkit-linear-gradient(top,#f6f6f6,#f1f1f1); background-image: -moz-linear-gradient(top,#f6f6f6,#f1f1f1); background-image: -ms-linear-gradient(top,#f6f6f6,#f1f1f1); background-image: -o-linear-gradient(top,#f6f6f6,#f1f1f1); background-image: linear-gradient(top,#f6f6f6,#f1f1f1); box-shadow: inset 0 1px 2px rgba(0,0,0,0.1); }\n.btn:visited, button:visited, input[type=submit]:visited { color: #666; }\n.btn.submit, input[type=submit] { border: 1px solid #3079ed; color: #fff; text-shadow: 0 1px rgba(0,0,0,0.1); background-color: #4d90fe; background-image: -webkit-linear-gradient(top,#4d90fe,#4787ed); background-image: -moz-linear-gradient(top,#4d90fe,#4787ed); background-image: -ms-linear-gradient(top,#4d90fe,#4787ed); background-image: -o-linear-gradient(top,#4d90fe,#4787ed); background-image: linear-gradient(top,#4d90fe,#4787ed); }\n.btn.submit:hover, input[type=submit]:hover { border: 1px solid #2f5bb7; color: #fff; text-shadow: 0 1px rgba(0,0,0,0.3); background-color: #357ae8; background-image: -webkit-linear-gradient(top,#4d90fe,#357ae8); background-image: -moz-linear-gradient(top,#4d90fe,#357ae8); background-image: -ms-linear-gradient(top,#4d90fe,#357ae8); background-image: -o-linear-gradient(top,#4d90fe,#357ae8); background-image: linear-gradient(top,#4d90fe,#357ae8); }\n.btn.submit:active, input[type=submit]:active { box-shadow: inset 0 1px 2px rgba(0,0,0,0.3); }\n.btn.red { border: 1px solid transparent; color: #fff; text-shadow: 0 1px rgba(0,0,0,0.1); text-transform: uppercase; background-color: #d14836; background-image: -webkit-linear-gradient(top,#dd4b39,#d14836); background-image: -moz-linear-gradient(top,#dd4b39,#d14836); background-image: -ms-linear-gradient(top,#dd4b39,#d14836); background-image: -o-linear-gradient(top,#dd4b39,#d14836); background-image: linear-gradient(top,#dd4b39,#d14836); }\n.btn.red:hover { border: 1px solid #b0281a; color: #fff; text-shadow: 0 1px rgba(0,0,0,0.3); background-color: #c53727; background-image: -webkit-linear-gradient(top,#dd4b39,#c53727); background-image: -moz-linear-gradient(top,#dd4b39,#c53727); background-image: -ms-linear-gradient(top,#dd4b39,#c53727); background-image: -o-linear-gradient(top,#dd4b39,#c53727); background-image: linear-gradient(top,#dd4b39,#c53727); box-shadow: 0 1px 1px rgba(0,0,0,0.2); }\n.btn.red:active { border: 1px solid #992a1b; background-color: #b0281a; background-image: -webkit-linear-gradient(top,#dd4b39,#b0281a); background-image: -moz-linear-gradient(top,#dd4b39,#b0281a); background-image: -ms-linear-gradient(top,#dd4b39,#b0281a); background-image: -o-linear-gradient(top,#dd4b39,#b0281a); background-image: linear-gradient(top,#dd4b39,#b0281a); box-shadow: inset 0 1px 2px rgba(0,0,0,0.3); }\n.btn.red:visited, .btn.submit:visited { color: #fff; }\n.btn img, button img { display: inline-block; margin: 4px 0 0; opacity: .55; vertical-align: middle; }\n.btn:hover img, button:hover img { opacity: .72; }\n.btn:active img, button:active img { opacity: 1; }\na.btn { height: 28px; }\n\n.float-left { float: left; }\n.float-right { float: right; }\n.tip-text { color: #b5b5b5; }\n\n#page_login h1 { color: #000; padding: 2px 0 10px 8px; font-size: 26px; }\n#page_login { background: url(background.jpg) no-repeat 50% 50%; background-size: 100% 100%; }\n#page_login .center-box { box-shadow: #9c9c9c 0 0 150px; background: white; border-radius: 10px; padding: 30px; }\n#page_login .side-bar { position: absolute; top: 0; left: 0; height: 100%; background: #272a25; width: 85px; border-radius: 10px 0 0 10px; }\n#page_login .main { margin-left: 85px; height: 100%; }\n#page_login .icon { background: url(member.png) no-repeat 50% 50%; display: block; height: 85px; width: 85px; }\n#page_login .side-bar li { color: #cdcdcd; text-align: center; font-size: 18px; padding: 12px 0; cursor: pointer; }\n#page_login .side-bar li a { color: #cdcdcd; }\n#page_login .side-bar li a:hover { text-decoration: none; }\n#page_login .side-bar li.current { color: #fff; background: url(triangle.png) no-repeat 100% 50%; }\n#page_login .side-bar li.current a { color: #fff; }\n#page_login .main p { margin-left: 15px; color: #676767; line-height: 26px; }\n#page_login .login-info input { width: 90%; border-radius: 2px; border: 1px solid #cdcdcd; }\n\n#page_index h1 { margin: 0; padding: 0 15px; height: 25px; }\n.extra_title { font-size: 14px; margin-left: 20px; }\n#append_parent { color: #000; z-index: 20; }\n.btns { height: 36px; line-height: 36px; text-align: right; padding: 0 10px; }\n.btns * { margin-left: 5px; }\n.btns .float-left { margin-left: -10px; }\n.center-box { position: relative; width: 500px; top: 125px; margin: 0 auto; background: #f5f5f5; padding: 10px 15px; box-shadow: 0 0 5px #ababab; }\n.avatar { position: absolute; z-index: 7; top: 0; right: 0; height: 50px; line-height: 50px; background: url('member.png') no-repeat 90% 50%; background-size: 32px; padding: 0 50px 0 10px; cursor: pointer; color: #fff; }\n.avatar img { position: absolute; width: 40px; top: 5px; right: 5px; border-radius: 20px; box-shadow: 0 0 3px #dedede; }\n.avatar:hover { background-color: #2c3335; }\n#member-menu { position: absolute; z-index: 3; right: 0; background: #1b2223; width: 200px; box-shadow: 0 0 25px #999; }\n#member-menu a { color: #dedede; }\n#member-menu li:hover { background: #2c3335; }\n#member-menu li:hover a { color: #fff; }\n.sidebar { width: 230px; position: absolute; top: 50px; bottom: 0; left: 0; overflow: auto; }\n.sidebar p { text-align: center; margin-bottom: 0; padding-bottom: .75em; }\n.main-content { position: absolute; top: 50px; bottom: 0; left: 230px; right: 0; box-shadow: -5px 0 65px #181818; font-size: 11px; text-align: right; padding: 10px; overflow: auto; background: #fff; }\n.main-content>div { min-height: 500px; margin-bottom: 1em; font-size: 13px; text-align: left; }\n.menu { margin: 0; }\n.menu li { margin: 0; padding: 0; }\n.menu li a { display: block; padding: 10px 5px 10px 15px; color: #6f7b7e; }\n.menu li.selected a { color: #fff; font-weight: bold; }\n.menu li.selected { background: #343c3e; }\n.menu li:hover { background: #2c3335; }\n.menu li a:hover { color: #dedede; text-decoration: none; }\n.menu_switch_user .del { float: right; background: url(delete.png) no-repeat 0 50%; padding: 19px 18px 19px 0; text-indent: -9999px; overflow: hidden; height: 0; display: none; }\n.menu_switch_user:hover .del{ display: block; }\n\n.template-list {}\n.template-list li { float: left; width: 170px; height: 135px; text-align:center; padding:10px 10px 0 10px; margin: 5px; border-radius:5px; cursor:pointer; border: 1px solid transparent; }\n.template-list li:hover{ background: #dedede; }\n.template-list li img { width: 170px; height: 110px; border:1px solid #dedede; border-radius:3px; }\n.template-list li.current {background:-webkit-linear-gradient(top,#4d90fe,#357ae8); color:#fff; border: 1px solid #2f5bb7; }\n\n.copyright { margin-top: 15px; margin-bottom: 5px; text-align: right; font-size: 12px; }\n.copyright a { color: #159; }\n#page_login .copyright { margin-top: 150px; text-align: center; }\n.loading-icon { color: #000; background: #fff; position: fixed; top: 50%; right: 50%; padding: 20px 50px; border: 1px solid #dedede; border-radius: 5px; line-height: 20px; height: 20px; width: 70px; font-size: 12px; cursor: default; margin: -30px -85px; text-align: center; z-index: 20; animation: showfwin .25s; -webkit-animation: showfwin .25s; -moz-animation: showfwin .25s; box-shadow: #9c9c9c 0 0 100px; box-shadow: rgba(72, 72, 72, 0.3) 0 0 100px; }\n.loading-icon.h { opacity: 0; filter: alpha(opacity=0); _display: none; animation: hidefwin .25s; -webkit-animation: hidefwin .25s; -moz-animation: hidefwin .25s; pointer-events: none; }\n.loading-icon img { padding: 2px 5px 2px 0; float: left; }\n.cover { animation: showfwin 1s; -webkit-animation: showfwin 1s; -moz-animation: showfwin 1s; position: absolute; position: fixed; width: 100%; height: 100%; z-index: 15; background-color: rgba(0, 0, 0, 0.3); }\n.cover.h { opacity: 0; filter: alpha(opacity=0); _display: none; animation: hidefwin 1s; -webkit-animation: hidefwin 1s; -moz-animation: hidefwin 1s; pointer-events: none; }\n.menubtn { display: none; width: 20px; line-height: 20px; height: 20px; position: absolute; top: 0; right: 0; padding: 15px; z-index: 10; }\n.menubtn:hover { background-color: #2c3335; }\n.menubtn p { line-height: 2px; height: 2px; margin: 3px 2px 4px; background: #dedede; text-indent: -999px; overflow: hidden; }\n.main-content table { width: 100%; margin-bottom: .48em; }\n.main-content table td { padding: 8px 0; text-align: center; border-top: 1px solid #dedede; min-width: 32px; line-height: 20px; }\n.main-content table tr { background: #fff; }\n.main-content table thead td { border-bottom: 2px solid #dedede; border-top: 0; }\n.main-content table tbody tr:nth-child(odd) { background: #f9f9f9; }\n.main-content input[type=text], .main-content input[type=password] { width: 300px; }\n.baidu_account img { padding: 5px; border: 1px solid #dedede; height: 96px; margin-right: 15px; }\n.baidu_account p { line-height: 36px; margin-bottom: 0; }\n.baidu_account { margin: 5px 15px 15px; }\n\n#page_index .sidebar { background: #232b2d; color: #556366; }\n#page_index h1 { background: #1b2224; color: #fff; padding: 0 15px; height: 50px; line-height: 50px; z-index: 5; position: relative; }\n#page_index .main-content { color: #000; }\n\ndiv.select { position: relative; display: inline; padding: 3px 5px; margin: 2px 5px; text-align: center; border: 1px solid #dedede; border-radius: 3px; cursor: pointer; }\ndiv.select .icon { font-size: 8px; vertical-align: middle; margin-left: 10px; }\ndiv.select:hover { border-color: #bdbdbd; }\n\n.dropdown { display: none; position: absolute; z-index: 500; list-style: none; width: auto; min-width: 150px; max-width: 500px; overflow: hidden; background: #fefefe; border: 1px solid #dedede; border-radius: 5px; box-shadow: 2px 2px 10px #bdbdbd; margin: -3px 0 0 0; padding: 0; }\n.dropdown li { color: #000; height: 32px; line-height: 32px; padding: 0 15px; border-bottom: 1px solid #dedede; margin-bottom: -1px; overflow: hidden; cursor: default; }\n.dropdown li:hover { color: #fff; background: #15f; }\n\n.fwin { animation: showfwin .3s; -webkit-animation: showfwin .3s; -moz-animation: showfwin .3s; position: absolute; position: fixed; max-width: 600px; min-width: 320px; z-index: 50; background-color: #fefefe; border: 1px solid #efefef; border-radius: 5px; padding: 10px 5px 5px; box-shadow: #cdcdcd 0 0 20px; }\n.fwin .close { display: none; }\n.fwin h3 { font-size: 20px; text-align: center; margin: -10px -5px 0; height: 42px; line-height: 42px; cursor: move; }\n.fwin .fcontent { text-align: center; line-height: 36px; padding: 10px; cursor: default; }\n.fwin .fcontent * { text-align: left; line-height: 20px; }\n.fwin .btns { text-align: right; margin: 5px; padding: 0; }\n.fwin.h { opacity: 0; filter: alpha(opacity=0); _display: none; animation: hidefwin .3s; -webkit-animation: hidefwin .3s; -moz-animation: hidefwin .3s; pointer-events: none; }\n@keyframes showfwin{ from { opacity: 0; transform: scale(1.1, 1.1); } to { opacity: 1; transform: scale(1, 1); } }\n@-webkit-keyframes showfwin{ from { opacity: 0; -webkit-transform: scale(1.1, 1.1); } to { opacity: 1; -webkit-transform: scale(1, 1); } }\n@-moz-keyframes showfwin{ from { opacity: 0; -moz-transform: scale(1.1, 1.1); } to { opacity: 1; -moz-transform: scale(1, 1); } }\n@keyframes hidefwin{ from { opacity: 1; transform: scale(1, 1); } to { opacity: 0; transform: scale(1.1, 1.1); } }\n@-webkit-keyframes hidefwin{ from { opacity: 1; -webkit-transform: scale(1, 1); } to { opacity: 0; -webkit-transform: scale(1.1, 1.1); } }\n@-moz-keyframes hidefwin{ from { opacity: 1; -moz-transform: scale(1, 1); } to { opacity: 0; -moz-transform: scale(1.1, 1.1); } }\n@media (max-width: 550px){\n\t#page_login .icon { float: left; }\n\t#page_login .side-bar { width: 100%; height: 85px; border-radius: 10px 10px 0 0; overflow: hidden; }\n\t#page_login .side-bar li { padding: 0; float: left; width: 85px; height: 85px; line-height: 85px; }\n\t#page_login .side-bar li.current { color: #fff; background: url(triangle.mobile.png) no-repeat 50% 100%; }\n\t#page_login .main { margin-top: 85px; margin-left: 0; width: 100%; }\n\t.center-box { top: 20px; width: 95%; box-sizing: border-box; }\n\t.copyright { margin-top: 35px; font-size: 11px; }\n\t#page_login .copyright { margin-top: 40px; }\n\t.sidebar, #page_index .sidebar { display: none; border: none; left: auto; right: 0; bottom: auto; width: 220px; z-index: 5; background: #1b2223; }\n\t.menu li a { color: #dedede; }\n\t.main-content { left: 0; box-shadow: none; }\n\t.avatar { right: 50px; }\n\t.menubtn { display: block; }\n\t.main-content input[type=text], .main-content input[type=password] { width: 90%; }\n\t.fwin { width: 85%; border-radius: 0; min-width: 200px; max-width: 320px; }\n\t.mobile_hidden { display: none; }\n\t.mobile_min { width: 30px; }\n}\n@media (min-width: 550px){\n\t.sidebar { display: block !important; }\n\t.main-content table td { min-width: 80px; }\n}\n"
  },
  {
    "path": "template/default/template.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>\n\t<item id=\"author\"><![CDATA[kookxiang]]></item>\n\t<item id=\"name\"><![CDATA[默认模板]]></item>\n\t<item id=\"preview\"><![CDATA[preview.png]]></item>\n\t<item id=\"site\"><![CDATA[http://www.kookxiang.com]]></item>\n\t<item id=\"target_version\">\n\t\t<item id=\"0\"><![CDATA[1.14.5.27]]></item>\n\t</item>\n\t<item id=\"ui_version\"><![CDATA[1.0]]></item>\n\t<item id=\"version\"><![CDATA[1.0.0]]></item>\n</root>"
  },
  {
    "path": "template/default/widget/bind_status.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<h2>百度账号绑定</h2>\n<div class=\"tab tab-binded hidden\">\n<p>您的百度账号绑定正常。</p>\n<br>\n<div class=\"baidu_account\"></div>\n<br>\n<p><a href=\"index.php?action=clear_cookie&formhash=<?php echo $formhash; ?>\" id=\"unbind_btn\" class=\"btn red\">解除绑定</a> &nbsp; (解除绑定后自动签到将停止)</p>\n</div>\n<div class=\"tab tab-bind\">\n<p>您还没有绑定百度账号！</p>\n<br>\n<p>只有绑定百度账号之后程序才能自动进行签到。</p>\n<p>您可以使用百度通行证登陆，或是手动填写 Cookie 进行绑定。</p>\n<br>\n<p><a href=\"#guide\" class=\"btn submit\">使用“配置向导”进行绑定</a></p>\n</div>"
  },
  {
    "path": "template/default/widget/find_password.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<h1>找回密码</h1>\n<form method=\"post\" action=\"member.php?action=find_password\">\n<div class=\"login-info\">\n<p>用户名：</p>\n<p><input type=\"text\" name=\"username\" required tabindex=\"1\" /></p>\n<p>邮箱：</p>\n<p><input type=\"text\" name=\"email\" required tabindex=\"2\" /></p>\n</div>\n<p><input type=\"submit\" value=\"提交\" tabindex=\"3\" /></p>\n</form>"
  },
  {
    "path": "template/default/widget/footer.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<script src=\"<?php echo jquery_path(); ?>\"></script>\n<script type=\"text/javascript\">\nvar formhash = '<?php echo $formhash; ?>';\nvar version = '<?php echo VERSION; ?>';\n<?php echo 'var AF = '.(defined('AFENABLED') ? 1 : 0); ?>\n</script>\n<script src=\"./template/default/js/kk_dropdown.js?version=<?php echo VERSION; ?>\"></script>\n<?php\nif(defined('IN_ADMINCP')){\n\techo '<script src=\"./template/default/js/admin.js?version='.VERSION.'\"></script>';\n}else{\n\techo '<script src=\"./template/default/js/main.js?version='.VERSION.'\"></script>';\n}\n?>\n<script src=\"./template/default/js/fwin.js?version=<?php echo VERSION; ?>\"></script>\n<?php\nHOOK::run('page_footer_js');\nif(defined('NEW_VERSION')) echo '<script type=\"text/javascript\">new_version = true</script>';\nif(defined('CLOUD_NOT_INITED')) echo '<div class=\"hidden\"><img src=\"api.php?action=register_cloud\" /></div>';\n"
  },
  {
    "path": "template/default/widget/guide.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<h2>贴吧签到助手 配置向导</h2>\n<div id=\"guide_pages\">\n<div id=\"guide_page_1\">\n<p>Hello，欢迎使用 贴吧签到助手~</p><br>\n<p><b>这是一款免费软件，作者 <a href=\"http://www.ikk.me\" target=\"_blank\">kookxiang</a>，你可以从 www.kookxiang.com 上下载到这个项目的最新版本。</b></p>\n<p>如果有人向您兜售本程序，麻烦您给个差评。</p><br>\n<p>配置签到助手之后，我们会在每天的 0:30 左右为您自动签到。</p>\n<p>签到过程不需要人工干预，您可以选择签到之后发送一封邮件报告到您的注册邮箱。</p><br>\n<p>准备好了吗？点击下面的“下一步”按钮开始配置吧</p>\n<p class=\"btns\"><button class=\"btn submit\" onclick=\"$('#guide_page_1').hide();checkCookieProxy();$('#guide_page_2').show();\">下一步 &raquo;</button></p>\n</div>\n<div id=\"guide_page_2\" class=\"hidden\">\n<p>首先，你需要绑定你的百度账号。</p><br>\n<p>为了确保账号安全，我们只储存你的百度 Cookie，不会保存你的账号密码信息。</p>\n<p>你可以通过修改密码的方式来让这些 Cookie 失效。</p><br>\n<style>\n.bind_mode .extension_info { padding: 10px 15px; margin: 0 5px 10px 20px; background: #f5f5f5; border: 1px solid #ddd; }\n.bind_mode .extension_info p { line-height: 24px; margin-bottom: 0; }\n</style>\n<div class=\"bind_mode\">\n    <p>\n        <label><input type=\"radio\" name=\"bind_mode\" value=\"auto\" checked> 通过 Chrome 扩展一键获取 Cookie 绑定</label>\n    </p>\n    <iframe src=\"https://api.ikk.me/reborn/proxy.htm\" id=\"cookie-proxy\" class=\"hidden\"></iframe>\n    <div class=\"extension_info\" id=\"cookie-proxy-info\">\n        <p>少年，看起来你的浏览器很辣鸡的样子，为何不考虑换下 Google Chrome 呢？</p>\n    </div>\n</div>\n<div class=\"bind_mode\">\n    <p>\n        <label><input type=\"radio\" name=\"bind_mode\" value=\"manual\"> 手动填写 Cookie 绑定</label>\n    </p>\n    <form method=\"post\" class=\"extension_info hidden\" action=\"api.php?action=receive_cookie&amp;local=1&amp;formhash=<?php echo $formhash; ?>\">\n        <p>请填写完整的 Cookie 信息，格式如: BDUSS=xxxxxxxxxxxxx; BAIDUID=...</p>\n        <p>\n            <input id=\"cookie\" name=\"cookie\" type=\"text\" placeholder=\"Cookie 信息\" required />\n            <input type=\"submit\" value=\"确定\" />\n        </p>\n    </form>\n</div>\n</div>\n<div id=\"guide_page_manual\" class=\"hidden\"></div>\n<div id=\"guide_page_3\" class=\"hidden\">\n<p>一切准备就绪~</p><br>\n<p>我们已经成功接收到你百度账号信息，自动签到已经准备就绪。</p>\n<p>您可以点击 <a href=\"#setting\">高级设置</a> 更改邮件设定，或更改其他附加设定。</p><br>\n<p>感谢您的使用！</p><br>\n<p>程序作者：kookxiang (<a href=\"http://www.ikk.me\" target=\"_blank\">http://www.ikk.me</a>)</p>\n<p>赞助开发：<a href=\"http://go.ikk.me/donate\" target=\"_blank\">http://go.ikk.me/donate</a> (你的支持就是我的动力)</p>\n</div>\n</div>"
  },
  {
    "path": "template/default/widget/header.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n$extra_title = getSetting('extra_title');\n$title = '贴吧签到助手';\nif($extra_title) $title .= \"<span class=\\\"extra_title mobile_hidden\\\">—— {$extra_title}</span>\";\n?>\n<h1><?php echo $title; ?></h1>\n<div class=\"avatar\"><?php echo $username; echo $_COOKIE[\"avatar_{$uid}\"] ? '<img id=\"avatar_img\" src=\"'.$_COOKIE[\"avatar_{$uid}\"].'\">' : '<img id=\"avatar_img\" class=\"hidden\" src=\"./template/default/style/member.png\">'; ?></div>\n<ul class=\"menu hidden\" id=\"member-menu\">\n<li id=\"menu_password\"><a href=\"javascript:;\">修改密码</a></li>\n<?php\nif(getSetting('account_switch')){\n\tforeach ($users as $_uid => $username){\n\t\techo '<li class=\"menu_switch_user\"><span class=\"del\" href=\"member.php?action=unbind_user&uid='.$_uid.'&formhash='.$formhash.'\">x</span><a href=\"member.php?action=switch&uid='.$_uid.'&formhash='.$formhash.'\">切换至: '.$username.'</a></li>';\n\t}\n\techo '<li id=\"menu_adduser\"><a href=\"#user-new\">关联其他帐号</a></li>';\n}\n?>\n<li id=\"menu_logout\"><a href=\"member.php?action=logout&hash=<?php echo $formhash; ?>\">退出登录</a></li>\n</ul>\n<div class=\"menubtn\"><p>-</p><p>-</p><p>-</p></div>"
  },
  {
    "path": "template/default/widget/liked_tieba.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<h2>我喜欢的贴吧</h2>\n<p>如果此处显示的贴吧有缺失，请<a href=\"index.php?action=refresh_liked_tieba\" onclick=\"return msg_redirect_action(this.href+'&formhash='+formhash)\">点此刷新喜欢的贴吧</a>.</p>\n<table>\n<thead><tr><td style=\"width: 40px\">#</td><td>贴吧</td><td style=\"width: 65px\">忽略签到</td></tr></thead>\n<tbody></tbody>\n</table>"
  },
  {
    "path": "template/default/widget/login.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<h1>登录</h1>\n<form method=\"post\" action=\"member.php?action=login\">\n<div class=\"login-info\">\n<p>用户名：</p>\n<p><input type=\"text\" name=\"username\" required tabindex=\"1\" /></p>\n<p>密码 (<a href=\"javascript:;\" onclick=\"switch_tabs('find_password');\" tabindex=\"0\">找回密码</a>)：</p>\n<p><input type=\"password\" name=\"password\" required tabindex=\"2\" /></p>\n<p>(此账号仅用于登陆代签系统，不同于百度通行证)</p>\n<?php HOOK::run('login_form'); ?>\n</div>\n<p><input type=\"submit\" value=\"登录\" tabindex=\"3\" /></p>\n</form>"
  },
  {
    "path": "template/default/widget/meta.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n<meta name=\"HandheldFriendly\" content=\"true\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\" />\n<meta name=\"author\" content=\"kookxiang\" />\n<meta name=\"copyright\" content=\"KK's Laboratory\" />\n<link rel=\"shortcut icon\" href=\"favicon.ico\" />\n<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n<meta name=\"renderer\" content=\"webkit\">\n<link rel=\"stylesheet\" href=\"./template/default/style/main.css?version=<?php echo VERSION; ?>\" type=\"text/css\" />"
  },
  {
    "path": "template/default/widget/register.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<h1>注册</h1>\n<form method=\"post\" action=\"member.php?action=register\">\n<div class=\"login-info\">\n<p>用户名：</p>\n<p><input type=\"text\" name=\"<?php echo $form_username; ?>\" required tabindex=\"1\" /></p>\n<p>密码：</p>\n<p><input type=\"password\" name=\"<?php echo $form_password; ?>\" required tabindex=\"2\" /></p>\n<p>邮箱：</p>\n<p><input type=\"text\" name=\"<?php echo $form_email; ?>\" required tabindex=\"3\" /></p>\n<?php\nif($invite_code) echo '<p>邀请码：</p><p><input type=\"text\" name=\"invite_code\" required /></p>';\n?>\n<p>(此账号仅用于登陆代签系统，不同于百度通行证)</p>\n<?php HOOK::run('register_form'); ?>\n</div>\n<p><input type=\"submit\" value=\"注册\" tabindex=\"4\" /></p>\n</form>"
  },
  {
    "path": "template/default/widget/setting.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<h2>设置</h2>\n<form method=\"post\" action=\"index.php?action=update_setting\" id=\"setting_form\" onsubmit=\"return post_win(this.action, this.id)\">\n<input type=\"hidden\" name=\"formhash\" value=\"<?php echo $formhash; ?>\">\n<p>签到方式：</p>\n<p><label><input type=\"radio\" name=\"sign_method\" id=\"sign_method_3\" value=\"3\" checked readonly /> V3.0 (模拟客户端签到)</label></p>\n<p>附加签到：</p>\n<p><label><input type=\"checkbox\" disabled name=\"zhidao_sign\" id=\"zhidao_sign\" value=\"1\" /> 自动签到百度知道</label></p>\n<p><label><input type=\"checkbox\" disabled name=\"wenku_sign\" id=\"wenku_sign\" value=\"1\" /> 自动签到百度文库</label></p>\n<p>报告设置：</p>\n<p><label><input type=\"checkbox\" checked disabled name=\"error_mail\" id=\"error_mail\" value=\"1\" /> 当天有无法签到的贴吧时给我发送邮件</label></p>\n<p><label><input type=\"checkbox\" disabled name=\"send_mail\" id=\"send_mail\" value=\"1\" /> 每日发送一封签到报告邮件</label></p>\n<p><input type=\"submit\" value=\"保存设置\" /></p>\n</form>\n<?php HOOK::run('user_setting'); ?>\n<br>\n<p>签到测试：</p>\n<p>随机选取一个贴吧，进行一次签到测试，检查你的设置有没有问题</p>\n<p>测个 JB，现在后端换 Go 语言了，测球</p>\n"
  },
  {
    "path": "template/default/widget/sidebar.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<ul id=\"menu\" class=\"menu\">\n<li id=\"menu_guide\"><a href=\"#guide\">配置向导</a></li>\n<li id=\"menu_sign_log\"><a href=\"#sign_log\">签到记录</a></li>\n<li id=\"menu_liked_tieba\"><a href=\"#liked_tieba\">我喜欢的贴吧</a></li>\n<li id=\"menu_baidu_bind\"><a href=\"#baidu_bind\">百度账号绑定</a></li>\n<li id=\"menu_setting\"><a href=\"#setting\">设置</a></li>\n<?php HOOK::page_menu(); ?>\n<?php if(is_admin($uid)) echo '<li id=\"menu_updater\"><a href=\"admin.php#updater\">检查更新</a></li><li id=\"menu_admincp\"><a href=\"admin.php\">管理面板</a></li>'; ?>\n</ul>"
  },
  {
    "path": "template/default/widget/sign_log.php",
    "content": "<?php\nif(!defined('IN_KKFRAME')) exit();\n?>\n<h2>签到记录</h2>\n<span id=\"page-flip\" class=\"float-right\"></span>\n<p id=\"sign-stat\"></p>\n<table>\n<thead><tr><td style=\"width: 40px\">#</td><td>贴吧</td><td class=\"mobile_min\">状态</td><td class=\"mobile_min\">经验</td></tr></thead>\n<tbody></tbody>\n</table>"
  }
]