2019-03-22 11:03:55 +00:00
<!DOCTYPE html>
< html class = "theme-next muse use-motion" lang = "zh-Hans" >
< head > < meta name = "generator" content = "Hexo 3.8.0" >
< meta charset = "UTF-8" >
< meta http-equiv = "X-UA-Compatible" content = "IE=edge" >
< meta name = "viewport" content = "width=device-width, initial-scale=1, maximum-scale=1" >
< meta name = "theme-color" content = "#222" >
< meta http-equiv = "Cache-Control" content = "no-transform" >
< meta http-equiv = "Cache-Control" content = "no-siteapp" >
< link href = "/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel = "stylesheet" type = "text/css" >
< link href = "/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel = "stylesheet" type = "text/css" >
< link href = "/css/main.css?v=5.1.4" rel = "stylesheet" type = "text/css" >
< link rel = "apple-touch-icon" sizes = "180x180" href = "/images/apple-touch-icon-next.png?v=5.1.4" >
< link rel = "icon" type = "image/png" sizes = "32x32" href = "/images/favicon-32x32-next.png?v=5.1.4" >
< link rel = "icon" type = "image/png" sizes = "16x16" href = "/images/favicon-16x16-next.png?v=5.1.4" >
< link rel = "mask-icon" href = "/images/logo.svg?v=5.1.4" color = "#222" >
< meta name = "keywords" content = "小米,文件格式,SSH," >
< meta name = "description" content = "小米固件工具mkxqimage小米自己改了个打包解包固件的工具, 基于 trx 改的(本质上还是 trx 格式),加了 RSA 验证和解包功能, 路由系统里自带: 1234Usage:mkxqimg [-o outfile] [-p private_key] [-f file] [-f file [-f file [-f file ]]] [-x file] [-I] 固件解" >
< meta name = "keywords" content = "小米,文件格式,SSH" >
< meta property = "og:type" content = "article" >
< meta property = "og:title" content = "小米固件工具mkxqimage" >
< meta property = "og:url" content = "https://cool-y.github.io/2019/03/16/小米固件工具mkxqimage/index.html" >
< meta property = "og:site_name" content = "混元霹雳手" >
< meta property = "og:description" content = "小米固件工具mkxqimage小米自己改了个打包解包固件的工具, 基于 trx 改的(本质上还是 trx 格式),加了 RSA 验证和解包功能, 路由系统里自带: 1234Usage:mkxqimg [-o outfile] [-p private_key] [-f file] [-f file [-f file [-f file ]]] [-x file] [-I] 固件解" >
< meta property = "og:locale" content = "zh-Hans" >
< meta property = "og:updated_time" content = "2019-03-22T10:00:09.461Z" >
< meta name = "twitter:card" content = "summary" >
< meta name = "twitter:title" content = "小米固件工具mkxqimage" >
< meta name = "twitter:description" content = "小米固件工具mkxqimage小米自己改了个打包解包固件的工具, 基于 trx 改的(本质上还是 trx 格式),加了 RSA 验证和解包功能, 路由系统里自带: 1234Usage:mkxqimg [-o outfile] [-p private_key] [-f file] [-f file [-f file [-f file ]]] [-x file] [-I] 固件解" >
< script type = "text/javascript" id = "hexo.configurations" >
var NexT = window.NexT || {};
var CONFIG = {
root: '/',
scheme: 'Muse',
version: '5.1.4',
sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
fancybox: true,
tabs: true,
motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
duoshuo: {
userId: '0',
author: '博主'
},
algolia: {
applicationID: '',
apiKey: '',
indexName: '',
hits: {"per_page":10},
labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
}
};
< / script >
< link rel = "canonical" href = "https://cool-y.github.io/2019/03/16/小米固件工具mkxqimage/" >
< title > 小米固件工具mkxqimage | 混元霹雳手< / title >
< / head >
< body itemscope itemtype = "http://schema.org/WebPage" lang = "zh-Hans" >
< div class = "container sidebar-position-left page-post-detail" >
< div class = "headband" > < / div >
< header id = "header" class = "header" itemscope itemtype = "http://schema.org/WPHeader" >
< div class = "header-inner" > < div class = "site-brand-wrapper" >
< div class = "site-meta " >
< div class = "custom-logo-site-title" >
< a href = "/" class = "brand" rel = "start" >
< span class = "logo-line-before" > < i > < / i > < / span >
< span class = "site-title" > 混元霹雳手< / span >
< span class = "logo-line-after" > < i > < / i > < / span >
< / a >
< / div >
< p class = "site-subtitle" > < / p >
< / div >
< div class = "site-nav-toggle" >
< button >
< span class = "btn-bar" > < / span >
< span class = "btn-bar" > < / span >
< span class = "btn-bar" > < / span >
< / button >
< / div >
< / div >
< nav class = "site-nav" >
< ul id = "menu" class = "menu" >
< li class = "menu-item menu-item-home" >
< a href = "/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-home" > < / i > < br >
首页
< / a >
< / li >
< li class = "menu-item menu-item-about" >
< a href = "/about/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-user" > < / i > < br >
关于
< / a >
< / li >
< li class = "menu-item menu-item-tags" >
< a href = "/tags/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-tags" > < / i > < br >
标签
< / a >
< / li >
< li class = "menu-item menu-item-categories" >
< a href = "/categories/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-th" > < / i > < br >
分类
< / a >
< / li >
< li class = "menu-item menu-item-archives" >
< a href = "/archives/" rel = "section" >
< i class = "menu-item-icon fa fa-fw fa-archive" > < / i > < br >
归档
< / a >
< / li >
< / ul >
< / nav >
< / div >
< / header >
< main id = "main" class = "main" >
< div class = "main-inner" >
< div class = "content-wrap" >
< div id = "content" class = "content" >
< div id = "posts" class = "posts-expand" >
< article class = "post post-type-normal" itemscope itemtype = "http://schema.org/Article" >
< div class = "post-block" >
< link itemprop = "mainEntityOfPage" href = "https://cool-y.github.io/2019/03/16/小米固件工具mkxqimage/" >
< span hidden itemprop = "author" itemscope itemtype = "http://schema.org/Person" >
< meta itemprop = "name" content = "Cool-Y" >
< meta itemprop = "description" content >
< meta itemprop = "image" content = "/images/avatar.gif" >
< / span >
< span hidden itemprop = "publisher" itemscope itemtype = "http://schema.org/Organization" >
< meta itemprop = "name" content = "混元霹雳手" >
< / span >
< header class = "post-header" >
< h1 class = "post-title" itemprop = "name headline" > 小米固件工具mkxqimage< / h1 >
< div class = "post-meta" >
< span class = "post-time" >
< span class = "post-meta-item-icon" >
< i class = "fa fa-calendar-o" > < / i >
< / span >
< span class = "post-meta-item-text" > 发表于< / span >
< time title = "创建于" itemprop = "dateCreated datePublished" datetime = "2019-03-16T14:57:56+08:00" >
2019-03-16
< / time >
< / span >
< span class = "post-category" >
< span class = "post-meta-divider" > |< / span >
< span class = "post-meta-item-icon" >
< i class = "fa fa-folder-o" > < / i >
< / span >
< span class = "post-meta-item-text" > 分类于< / span >
< span itemprop = "about" itemscope itemtype = "http://schema.org/Thing" >
< a href = "/categories/IOT/" itemprop = "url" rel = "index" >
< span itemprop = "name" > IOT< / span >
< / a >
< / span >
< / span >
< span class = "post-comments-count" >
< span class = "post-meta-divider" > |< / span >
< span class = "post-meta-item-icon" >
< i class = "fa fa-comment-o" > < / i >
< / span >
< a href = "/2019/03/16/小米固件工具mkxqimage/#comments" itemprop = "discussionUrl" >
< span class = "post-comments-count gitment-comments-count" data-xid = "/2019/03/16/小米固件工具mkxqimage/" itemprop = "commentsCount" > < / span >
< / a >
< / span >
< span id = "/2019/03/16/小米固件工具mkxqimage/" class = "leancloud_visitors" data-flag-title = "小米固件工具mkxqimage" >
< span class = "post-meta-divider" > |< / span >
< span class = "post-meta-item-icon" >
< i class = "fa fa-eye" > < / i >
< / span >
< span class = "post-meta-item-text" > 阅读次数: < / span >
< span class = "leancloud-visitors-count" > < / span >
< / span >
< / div >
< / header >
< div class = "post-body" itemprop = "articleBody" >
< h1 id = "小米固件工具mkxqimage" > < a href = "#小米固件工具mkxqimage" class = "headerlink" title = "小米固件工具mkxqimage" > < / a > 小米固件工具mkxqimage< / h1 > < p > 小米自己改了个打包解包固件的工具,基于 trx 改的(本质上还是 trx 格式),加了 RSA 验证和解包功能,路由系统里自带:< br > < figure class = "highlight plain" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > Usage:< / span > < br > < span class = "line" > mkxqimg [-o outfile] [-p private_key] [-f file] [-f file [-f file [-f file ]]]< / span > < br > < span class = "line" > [-x file]< / span > < br > < span class = "line" > [-I]< / span > < br > < / pre > < / td > < / tr > < / table > < / figure > < / p >
< h2 id = "固件解包" > < a href = "#固件解包" class = "headerlink" title = "固件解包" > < / a > 固件解包< / h2 > < p > 固件工具mkxqimage完成对固件的解包, 在解包前先检查Checksum是否正确, 然后利用RSA公钥/usr/share/xiaoqiang/public.pem检查RSA签名, 这两个步骤通过后, 根据[0x0C]的固件类型,以及[0x10]、[0x14]、[0x18]和[0x1C]的4个偏移量拆分固件。< / p >
< h2 id = "固件打包" > < a href = "#固件打包" class = "headerlink" title = "固件打包" > < / a > 固件打包< / h2 > < p > 小米官方在打包固件时用RSA私钥计算出固件的RSA签名, 小米路由器下载固件后用RSA公钥来验证RSA签名, 有效地防止固件被篡改。< / p >
< h2 id = "固件格式" > < a href = "#固件格式" class = "headerlink" title = "固件格式" > < / a > < a href = "http://www.iptvfans.cn/wiki/index.php/%E5%B0%8F%E7%B1%B3%E8%B7%AF%E7%94%B1%E5%99%A8%E5%9B%BA%E4%BB%B6%E5%88%86%E6%9E%90" target = "_blank" rel = "noopener" > 固件格式< / a > < / h2 > < p > 路由固件的格式,基本是基于 openwrt 的 trx 这个简单的二进制文件格式< br > < figure class = "highlight plain" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > 48 44 52 30 63 D4 11 03 FE 3D 1A FD 05 00 02 00< / span > < br > < span class = "line" > 20 00 00 00 20 00 FE 00 00 00 00 00 00 00 00 00< / span > < br > < span class = "line" > FF 04 00 EA 14 F0 9F E5 14 F0 9F E5 14 F0 9F E5< / span > < br > < / pre > < / td > < / tr > < / table > < / figure > < / p >
< p > 第1~ 4字节: ASCII字符串“HDR0”, 作为固件的标识; < br > 第5~ 8字节: 4字节整型数0x0311D464, 表示固件的大小: 51500132字节; < br > 第9~12字节: 固件的检查和; < br > 第13~ 14字节: 0x0005, 表示固件中包含哪些部分; < br > 第15~ 16字节: 0x0002, 表示固件格式版本号; < br > 第17~ 20字节: 0x00000020, 表示固件第一部分在整个固件中的偏移量, 0.4.85固件的第一部分是brcm4709_nor.bin, 也就是Flash中除0xfe0000-0xff0000的board_data外的全镜像; < br > 第21~ 24字节: 0x00FE0020, 表示固件第二部分在整个固件中的偏移量, 0.4.85固件的第二部分是root.ext4.lzma, 也就是硬盘中128M固件的压缩包; < br > 第33字节开始是固件的正式内容开始。< / p >
< h2 id = "小米开启ssh工具包" > < a href = "#小米开启ssh工具包" class = "headerlink" title = "小米开启ssh工具包" > < / a > 小米开启ssh工具包< / h2 > < p > 使用mkxqimage解包< br > (现在会提示秘钥不存在)< br > < figure class = "highlight plain" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > error fopen public key< / span > < br > < span class = "line" > Image verify failed, not formal image< / span > < br > < / pre > < / td > < / tr > < / table > < / figure > < / p >
< p > 如果能解包应该可以得到脚本文件upsetting.sh< / p >
< figure class = "highlight plain" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > #!/bin/sh< / span > < br > < span class = "line" > nvram set ssh_en=1< / span > < br > < span class = "line" > nvram set flag_init_root_pwd=1< / span > < br > < span class = "line" > nvram commit< / span > < br > < / pre > < / td > < / tr > < / table > < / figure >
< p > 执行脚本文件upsetting.sh后, 将ssh_en设置为1, 同时设置了flag_init_root_pwd项。当正式启动时, /usr/sbin/boot_check脚本检测到flag_init_root_pwd=1时, 自动修改root用户密码, 具体脚本为: < br > < figure class = "highlight plain" > < table > < tr > < td class = "gutter" > < pre > < span class = "line" > 1< / span > < br > < span class = "line" > 2< / span > < br > < span class = "line" > 3< / span > < br > < span class = "line" > 4< / span > < br > < span class = "line" > 5< / span > < br > < span class = "line" > 6< / span > < br > < span class = "line" > 7< / span > < br > < / pre > < / td > < td class = "code" > < pre > < span class = "line" > flg_init_pwd=`nvram get flag_init_root_pwd`< / span > < br > < span class = "line" > if [ " $flg_init_pwd" = " 1" ]; then< / span > < br > < span class = "line" > init_pwd=`mkxqimage -I`< / span > < br > < span class = "line" > (echo $init_pwd; sleep 1; echo $init_pwd) | passwd root< / span > < br > < span class = "line" > nvram unset flag_init_root_pwd< / span > < br > < span class = "line" > nvram commit< / span > < br > < span class = "line" > fi< / span > < br > < / pre > < / td > < / tr > < / table > < / figure > < / p >
< p > 初始密码是mkxqimage -I的结果, 实际是根据路由器的序列号计算得到。路由器的序列号印在底盖上, 12位数字, 如: 561000088888< / p >
< p > 初始密码计算算法为:< / p >
< p > < code > substr(md5(SN+" A2E371B0-B34B-48A5-8C40-A7133F3B5D88" ), 0, 8)< / code > < / p >
< p > < strong > < em > A2E371B0-B34B-48A5-8C40-A7133F3B5D88< / em > < / strong > 为分析mkxqimage得到的salt< / p >
< / div >
2019-03-22 12:33:24 +00:00
< div >
< div style = "padding: 10px 0; margin: 20px auto; width: 90%; text-align: center;" >
< div > 您的支持将鼓励我继续创作!< / div >
< button id = "rewardButton" disable = "enable" onclick = "var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}" >
< span > 打赏< / span >
< / button >
< div id = "QR" style = "display: none;" >
< div id = "wechat" style = "display: inline-block" >
2019-03-22 12:40:26 +00:00
< img id = "wechat_qr" src = "./source/images/wechatpay.png" alt = "Cool-Y 微信支付" >
2019-03-22 12:33:24 +00:00
< p > 微信支付< / p >
< / div >
< div id = "alipay" style = "display: inline-block" >
2019-03-22 12:40:26 +00:00
< img id = "alipay_qr" src = "./source/images/alipay.png" alt = "Cool-Y 支付宝" >
2019-03-22 12:33:24 +00:00
< p > 支付宝< / p >
< / div >
< / div >
< / div >
< / div >
2019-03-22 11:03:55 +00:00
< footer class = "post-footer" >
< div class = "post-tags" >
< a href = "/tags/小米/" rel = "tag" > # 小米< / a >
< a href = "/tags/文件格式/" rel = "tag" > # 文件格式< / a >
< a href = "/tags/SSH/" rel = "tag" > # SSH< / a >
< / div >
< div class = "post-nav" >
< div class = "post-nav-next post-nav-item" >
< a href = "/2019/02/22/qq数据库的加密解密/" rel = "next" title = "QQ数据库的加密与解密" >
< i class = "fa fa-chevron-left" > < / i > QQ数据库的加密与解密
< / a >
< / div >
< span class = "post-nav-divider" > < / span >
< div class = "post-nav-prev post-nav-item" >
< / div >
< / div >
< / footer >
< / div >
< / article >
< div class = "post-spread" >
< / div >
< / div >
< / div >
< div class = "comments" id = "comments" >
< div id = "gitment-container" > < / div >
< / div >
< / div >
< div class = "sidebar-toggle" >
< div class = "sidebar-toggle-line-wrap" >
< span class = "sidebar-toggle-line sidebar-toggle-line-first" > < / span >
< span class = "sidebar-toggle-line sidebar-toggle-line-middle" > < / span >
< span class = "sidebar-toggle-line sidebar-toggle-line-last" > < / span >
< / div >
< / div >
< aside id = "sidebar" class = "sidebar" >
< div class = "sidebar-inner" >
< ul class = "sidebar-nav motion-element" >
< li class = "sidebar-nav-toc sidebar-nav-active" data-target = "post-toc-wrap" >
文章目录
< / li >
< li class = "sidebar-nav-overview" data-target = "site-overview-wrap" >
站点概览
< / li >
< / ul >
< section class = "site-overview-wrap sidebar-panel" >
< div class = "site-overview" >
< div class = "site-author motion-element" itemprop = "author" itemscope itemtype = "http://schema.org/Person" >
< p class = "site-author-name" itemprop = "name" > Cool-Y< / p >
< p class = "site-description motion-element" itemprop = "description" > < / p >
< / div >
< nav class = "site-state motion-element" >
< div class = "site-state-item site-state-posts" >
< a href = "/archives/" >
< span class = "site-state-item-count" > 5< / span >
< span class = "site-state-item-name" > 日志< / span >
< / a >
< / div >
< div class = "site-state-item site-state-categories" >
< a href = "/categories/index.html" >
< span class = "site-state-item-count" > 4< / span >
< span class = "site-state-item-name" > 分类< / span >
< / a >
< / div >
< div class = "site-state-item site-state-tags" >
< a href = "/tags/index.html" >
< span class = "site-state-item-count" > 11< / span >
< span class = "site-state-item-name" > 标签< / span >
< / a >
< / div >
< / nav >
< / div >
< / section >
<!-- noindex -->
< section class = "post-toc-wrap motion-element sidebar-panel sidebar-panel-active" >
< div class = "post-toc" >
< div class = "post-toc-content" > < ol class = "nav" > < li class = "nav-item nav-level-1" > < a class = "nav-link" href = "#小米固件工具mkxqimage" > < span class = "nav-number" > 1.< / span > < span class = "nav-text" > 小米固件工具mkxqimage< / span > < / a > < ol class = "nav-child" > < li class = "nav-item nav-level-2" > < a class = "nav-link" href = "#固件解包" > < span class = "nav-number" > 1.1.< / span > < span class = "nav-text" > 固件解包< / span > < / a > < / li > < li class = "nav-item nav-level-2" > < a class = "nav-link" href = "#固件打包" > < span class = "nav-number" > 1.2.< / span > < span class = "nav-text" > 固件打包< / span > < / a > < / li > < li class = "nav-item nav-level-2" > < a class = "nav-link" href = "#固件格式" > < span class = "nav-number" > 1.3.< / span > < span class = "nav-text" > 固件格式< / span > < / a > < / li > < li class = "nav-item nav-level-2" > < a class = "nav-link" href = "#小米开启ssh工具包" > < span class = "nav-number" > 1.4.< / span > < span class = "nav-text" > 小米开启ssh工具包< / span > < / a > < / li > < / ol > < / li > < / ol > < / div >
< / div >
< / section >
<!-- /noindex -->
< / div >
< / aside >
< / div >
< / main >
< footer id = "footer" class = "footer" >
< div class = "footer-inner" >
< div class = "copyright" > © < span itemprop = "copyrightYear" > 2019< / span >
< span class = "with-love" >
< i class = "fa fa-user" > < / i >
< / span >
< span class = "author" itemprop = "copyrightHolder" > Cool-Y< / span >
< / div >
< div class = "powered-by" > 由 < a class = "theme-link" target = "_blank" href = "https://hexo.io" > Hexo< / a > 强力驱动< / div >
< span class = "post-meta-divider" > |< / span >
< div class = "theme-info" > 主题 — < a class = "theme-link" target = "_blank" href = "https://github.com/iissnan/hexo-theme-next" > NexT.Muse< / a > v5.1.4< / div >
< / div >
< / footer >
< div class = "back-to-top" >
< i class = "fa fa-arrow-up" > < / i >
< / div >
< / div >
< script type = "text/javascript" >
if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
window.Promise = null;
}
< / script >
< script type = "text/javascript" src = "/lib/jquery/index.js?v=2.1.3" > < / script >
< script type = "text/javascript" src = "/lib/fastclick/lib/fastclick.min.js?v=1.0.6" > < / script >
< script type = "text/javascript" src = "/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7" > < / script >
< script type = "text/javascript" src = "/lib/velocity/velocity.min.js?v=1.2.1" > < / script >
< script type = "text/javascript" src = "/lib/velocity/velocity.ui.min.js?v=1.2.1" > < / script >
< script type = "text/javascript" src = "/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5" > < / script >
< script type = "text/javascript" src = "/js/src/utils.js?v=5.1.4" > < / script >
< script type = "text/javascript" src = "/js/src/motion.js?v=5.1.4" > < / script >
< script type = "text/javascript" src = "/js/src/scrollspy.js?v=5.1.4" > < / script >
< script type = "text/javascript" src = "/js/src/post-details.js?v=5.1.4" > < / script >
< script type = "text/javascript" src = "/js/src/bootstrap.js?v=5.1.4" > < / script >
<!-- LOCAL: You can save these files to your site and update links -->
< link rel = "stylesheet" href = "https://aimingoo.github.io/gitmint/style/default.css" >
< script src = "https://aimingoo.github.io/gitmint/dist/gitmint.browser.js" > < / script >
<!-- END LOCAL -->
< script type = "text/javascript" >
function renderGitment(){
var gitment = new Gitmint({
id: window.location.pathname,
owner: 'Cool-Y',
repo: 'gitment-comments',
lang: "" || navigator.language || navigator.systemLanguage || navigator.userLanguage,
oauth: {
client_secret: '1c5db4da72df5e6fc318d12afe5f4406f7c54343',
client_id: '180955a2c3ae3d966d9a'
}});
gitment.render('gitment-container');
}
renderGitment();
< / script >
< script src = "https://cdn1.lncld.net/static/js/av-core-mini-0.6.4.js" > < / script >
< script > AV . initialize ( "EWwoJgHNdlj6iBjiFlMcabUO-gzGzoHsz" , "x8FxDrYG79C8YFrTww9ljo8K" ) ; < / script >
< script >
function showTime(Counter) {
var query = new AV.Query(Counter);
var entries = [];
var $visitors = $(".leancloud_visitors");
$visitors.each(function () {
entries.push( $(this).attr("id").trim() );
});
query.containedIn('url', entries);
query.find()
.done(function (results) {
var COUNT_CONTAINER_REF = '.leancloud-visitors-count';
if (results.length === 0) {
$visitors.find(COUNT_CONTAINER_REF).text(0);
return;
}
for (var i = 0; i < results.length ; i + + ) {
var item = results[i];
var url = item.get('url');
var time = item.get('time');
var element = document.getElementById(url);
$(element).find(COUNT_CONTAINER_REF).text(time);
}
for(var i = 0; i < entries.length ; i + + ) {
var url = entries[i];
var element = document.getElementById(url);
var countSpan = $(element).find(COUNT_CONTAINER_REF);
if( countSpan.text() == '') {
countSpan.text(0);
}
}
})
.fail(function (object, error) {
console.log("Error: " + error.code + " " + error.message);
});
}
function addCount(Counter) {
var $visitors = $(".leancloud_visitors");
var url = $visitors.attr('id').trim();
var title = $visitors.attr('data-flag-title').trim();
var query = new AV.Query(Counter);
query.equalTo("url", url);
query.find({
success: function(results) {
if (results.length > 0) {
var counter = results[0];
counter.fetchWhenSave(true);
counter.increment("time");
counter.save(null, {
success: function(counter) {
var $element = $(document.getElementById(url));
$element.find('.leancloud-visitors-count').text(counter.get('time'));
},
error: function(counter, error) {
console.log('Failed to save Visitor num, with error message: ' + error.message);
}
});
} else {
var newcounter = new Counter();
/* Set ACL */
var acl = new AV.ACL();
acl.setPublicReadAccess(true);
acl.setPublicWriteAccess(true);
newcounter.setACL(acl);
/* End Set ACL */
newcounter.set("title", title);
newcounter.set("url", url);
newcounter.set("time", 1);
newcounter.save(null, {
success: function(newcounter) {
var $element = $(document.getElementById(url));
$element.find('.leancloud-visitors-count').text(newcounter.get('time'));
},
error: function(newcounter, error) {
console.log('Failed to create');
}
});
}
},
error: function(error) {
console.log('Error:' + error.code + " " + error.message);
}
});
}
$(function() {
var Counter = AV.Object.extend("Counter");
if ($('.leancloud_visitors').length == 1) {
addCount(Counter);
} else if ($('.post-title-link').length > 1) {
showTime(Counter);
}
});
< / script >
< / body >
< / html >