TC官方合作论坛

 找回密码
 立即注册
查看: 10686|回复: 33

零基础学TC之学习看源码

[复制链接]
发表于 2012-3-26 00:34:27 | 显示全部楼层 |阅读模式

马上加入TC

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
昨天,我们已经学习了怎么去看TC的帮助文档<零基础学TC之帮助文档>!今天,大家跟着冷月一起来学习怎么看论坛大神们无私奉献出来的经典源码!
首先,在这里,我们感谢"超自然"大神奉献出来的自动登录功能的源代码,<点击进入原帖>
那么我们先打开帖子,然后先回复!(看帖要回复!这是逛论坛的好习惯!)咳..咳..
然后,我们大概浏览一遍帖子,满篇的代码,是不是看得有点晕晕的?什么不晕?你看懂了?那在这里你就不用往下看了!
那好,看晕了的童鞋跟着冷月继续,我们是小白,看不懂代码怎么办?(特别是看不懂英文的!)
那么我们要做的第一件事就是打开"TC帮助文档",然后对照"TC帮助文档"把大神的英文代码全部换成中文的!(当然如果你习惯看英文代码,算我没说)

在正式开始前,冷月要多余说几句,我们膜拜大神们无私奉献出来的源码,目的不是复制粘贴直接拿去用的,而是学习大神们实现功能的方法和代码的逻辑流程!

好的,在这里为了方便大家,冷月把换好的代码发出来:

  1. 功能 字符型 上号(整型 窗口句柄,整型 窗口编号,整型 临界对象)
  2. 字符型[] 账号=字符型[2]
  3. 整型 x,y
  4. 线程.进入临界区(临界对象)
  5. 账号=账号.账号()
  6. 线程.离开临界区(临界对象)
  7. 如果 (账号[0]=="结束")
  8.     返回 "结束"
  9. 如果结束
  10. //...........这里是线程获取到账号找输入框去了,就不详述.这个是线程在走的代码,每个线程各自负责自己的窗口,到这的时候,都集中通过唯一函数
  11. 返回 "结束"
  12. 功能结束


  13. 功能 字符型[] 账号()
  14. 字符型[] 返回串=字符型[2]
  15. 字符型 目标列表
  16. 如果 (方案一&&!方案二)
  17.     目标列表="列表框1"
  18. 否则
  19.     目标列表="列表框5"
  20. 如果结束
  21. 如果 (列表框.获得文本(目标列表,0)!="")
  22.     返回串[0]=字符串.截取(列表框.获得文本(目标列表,0),0,字符串.查找字符串(列表框.获得文本(目标列表,0),"*"))
  23.     返回串[1]=字符串.截取(列表框.获得文本(目标列表,0),(字符串.查找字符串(列表框.获得文本(目标列表,0),"*")+1),字符串.长度(列表框.获得文本(目标列表,0)))
  24.     列表框.删除文本(目标列表,0)
  25.     如果 (列表框.得到个数(目标列表)==0)
  26.         如果 (需切换)
  27.             标签.设置文本("标签42","方案一" )
  28.             已回转=真
  29.             方案一=真
  30.             方案二=假
  31.         否则
  32.             列表框.清空("列表框1")
  33.         如果结束
  34.     如果结束
  35.     功能集.改变数量("标签2",假,1)
  36.     功能集.配对(0)
  37.     返回 返回串
  38. 否则
  39.     返回串[0]="结束"
  40.     返回 返回串
  41. 如果结束
  42. 功能结束
  43. //这段就是发号函数内部


  44. 功能 逻辑型 账号录入()
  45. 字符型 目标列表
  46. 如果 (字符串.长度(编辑框.获得文本("编辑框0"))<=0||字符串.长度(编辑框.获得文本("编辑框1"))<=0)
  47.     辅助.对话框("未设定任何账号或密码信息,请查证","错误",0,真)
  48.     返回 假
  49. 否则
  50.     如果 (单选框.获得状态("单选框13"))
  51.         目标列表="列表框1"
  52.     否则
  53.         目标列表="列表框5"
  54.     如果结束
  55.     列表框.增加文本(目标列表,编辑框.获得文本("编辑框0")+"*"+编辑框.获得文本("编辑框1"))
  56.     列表框.增加文本("列表框2",功能集.时间处理()+" 账号"+编辑框.获得文本("编辑框0")+"被录入至列表")
  57.     编辑框.设置文本("编辑框0","")
  58.     编辑框.设置文本("编辑框1","")
  59.     标签.设置文本("标签2",转换.整型转字符型(列表框.得到个数(目标列表)))
  60.     功能集.改变数量("标签2",true,1)
  61.     返回 真
  62. 如果结束
  63. 功能结束
  64. //这段是录入账号的,录入之后会在列表中呈现这样的格式
  65. //账号*密码
  66. //中间用个*隔开,方便易看,录错了马上就能知道


  67. 功能 逻辑型 保存(字符型 保存对象)
  68. 字符型 列表内容,盘符,目标列表
  69. 整型 计数,返回值,列表数量
  70. 盘符=系统.获取程序路径()
  71. 如果 (保存对象=="收件人")
  72.     列表数量=列表框.得到个数("列表框3")
  73.     如果(列表数量==0)
  74.         辅助.对话框("收件人列表无任何数据,请查证","错误",0,真)
  75.         返回 假
  76.     否则
  77.         如果(文件.是否存在(盘符+"Addressee.ini"))
  78.             计数=辅助.对话框("程序目录下已有一个收件人配置文件,继续保存将覆盖原有文件","是否继续",2,true)
  79.             如果 (计数==4)
  80.                 返回 假
  81.             否则
  82.                 计数=0
  83.                 文件.删除(盘符+"Addressee.ini")
  84.                 循环 (计数<列表数量)
  85.                     列表内容=列表框.获得文本("列表框3",计数)
  86.                     辅助.写配置("Name","B"+转换.整型转字符型(计数),列表内容,盘符+"Addressee.ini")
  87.                     计数=计数+1
  88.                 循环结束
  89.                 辅助.写配置("Overview","Number",转换.整型转字符型(计数),盘符+"Addressee.ini")
  90.                 列表框.清空("列表框3")
  91.                 列表框.增加文本("列表框2",功能集.时间处理()+" 收件人名称列表内容被保存至文件")
  92.                 标签.设置文本("标签8","0" )
  93.                 返回 真
  94.             如果结束
  95.         否则
  96.             循环 (计数<列表数量)
  97.                 列表内容=列表框.获得文本("列表框3",计数)
  98.                 辅助.写配置("Name","B"+转换.整型转字符型(计数),列表内容,盘符+"Addressee.ini")
  99.                 计数=计数+1
  100.             循环结束
  101.             辅助.写配置("Overview","Number",转换.整型转字符型(计数),盘符+"Addressee.ini")
  102.             列表框.清空("列表框3")
  103.             列表框.增加文本("列表框2",功能集.时间处理()+" 收件人名称列表内容被保存至文件")
  104.             标签.设置文本("标签8","0" )
  105.             返回 真
  106.         如果结束
  107.     如果结束
  108. 如果结束
  109. 如果 (保存对象=="账号")
  110.     如果 (单选框.获得状态("单选框13"))
  111.         目标列表="列表框1"
  112.     否则
  113.         目标列表="列表框5"
  114.     如果结束
  115.     列表数量=列表框.得到个数(目标列表)
  116.     如果 (列表数量==0)
  117.         辅助.对话框("账号配置列表无任何数据,请查证","错误",0,真)
  118.         返回 假
  119.     否则
  120.         如果 (文件.是否存在(盘符+"Number of a bank account.ini"))
  121.             计数=辅助.对话框("程序目录下已有一个账号配置文件,继续保存将覆盖原有文件","是否继续",2,true)
  122.             如果 (计数==4)
  123.                 返回 假
  124.             否则
  125.                 计数=0
  126.                 文件.删除文件夹(盘符+"Number of a bank account.ini")
  127.                 循环(计数<列表数量)
  128.                     列表内容=列表框.得到个数((目标列表,计数)
  129.                     辅助.写配置("Name","A"+转换.整型转字符型(计数),字符串.截取(列表内容,0,字符串.查找字符串(列表内容,"*")),盘符+"Number of a bank account.ini")
  130.                     辅助.写配置("pass","A"+转换.整型转字符型(计数),字符串.截取(列表内容,(字符串.查找字符串(列表内容,"*")+1),字符串.长度(列表内容)),盘符+"Number of a bank account.ini")
  131.                     计数=计数+1
  132.                 循环结束
  133.                 辅助.写配置("Overview","Number",转换.整型转字符型(计数),盘符+"Number of a bank account.ini")
  134.                 列表框.清空(目标列表)
  135.                 标签.设置文本("标签2","0")
  136.                 列表框.增加文本("列表框2",功能集.时间处理()+" 账号配置列表内容被保存至文件")
  137.                 返回 真
  138.             如果结束
  139.         否则
  140.             循环 (计数<列表数量)
  141.                 列表内容=列表框.得到个数(目标列表,计数)
  142.                 辅助.写配置("Name","A"+转换.整型转字符型(计数),字符串.截取(列表内容,0,字符串.查找字符串(列表内容,"*")),盘符+"Number of a bank account.ini")
  143.                 辅助.写配置("pass","A"+转换.整型转字符型(计数),字符串.截取(列表内容,(字符串.查找字符串(列表内容,"*")+1),字符串.长度(列表内容)),盘符+"Number of a bank account.ini")
  144.                 计数=计数+1
  145.             循环结束
  146.             辅助.写配置("Overview","Number",convert.inttostr(计数),盘符+"Number of a bank account.ini")
  147.             列表框.清空(目标列表)
  148.             标签.设置文本("标签2","0")
  149.             列表框.增加文本("列表框2",功能集.时间处理()+" 账号配置列表内容被保存至文件")
  150.             返回 真
  151.         如果结束
  152.     如果结束
  153. 如果结束
  154. 功能结束
复制代码

好了,现在我们可以很容易的看出这一大段代码包涵了四个功能函数,那么我们一个一个来看!
第一句:功能 字符型 上号(整型 窗口句柄,整型 窗口编号,整型 临界对象)
从这一句我们可以看出,这个功能函数的返回类型是"字符型"的,函数名是"上号",参数有三个(我们先不管这些参数)
好,再往下看,我们可以看到函数定义了一个包涵两个元素的一维字符型数组"账号"(关于数组的介绍请参考TC帮助文档-数组的使用)
然后设置了一个"线程临界区",在临界区里只有一行代码:账号.账号()
刚接触TC的童鞋看到这里也许就有点迷糊了,这句是什么意思呢?通过TC语法我们知道函数调用的格式是"空间名.函数名(参数)"
那么我们就可以知道这句"账号.账号()"就是调用空间名为"账号"的空间里,函数名为"账号"的,返回类型为字符型数组的功能函数,呼呼,这句是不是很长?
其实我们有耐心看下去的话,看到第二个功能函数:功能 字符型[] 账号() 其实这句就是调用它的!
有人要问了,你怎么知道这句是一个字符型数组功能函数的调用命令呢?因为!"账号="这个等于号左边的变量"账号"我们看到之前已经定义成一个包涵两个元素的一维字符型数组了,所以!我们就能知道等于号右边的函数调用命令"账号.账号()"的返回值是字符型数组!(如果不是那么这句就会出现语法错误了!大神是不会犯这样的错误滴!)
再往下看,是一段如果的判断,条件是(账号[0]=="结束"),从"如果"到"如果结束"我们连起来了解,那就是当数组"账号[0]"里的值为字符串"结束"的时候,函数的返回值为字符串"结束",当数组"账号[0]"里的值不为字符串"结束"的时候,执行"如果结束"以后的代码!
"如果结束"结束是什么代码呢?额,"超自然"大神把代码给略过了,不过他也注释说明了,是一段线程走的代码,功能是把得到的账号密码输入登录界面,每一个线程控制一个窗口,这里你可能又要问了,怎么实现每一个线程控制一个窗口的呢?
还记得函数头的参数么?(整型 窗口句柄,整型 窗口编号,整型 临界对象)
其中定义了一个"整型 窗口句柄",从这里我们可以知道,向这个函数传入不同的窗口句柄,那么函数就在对应的窗口里运行了!当然代码得我们自己写了!
小结:其实这段代码,"超自然"大神主要向我们展示了临界区在自动登录功能里的用法,临界区不单单只是用防止多线程互抢鼠标的情况下,只要一个参数在多线程调用的时候只能是唯一的情况下,我们都可以用临界区!说得直白点,这段函数的功能突出的就是防止了同一个账号被几个线程调用的情况出现!(也就是防止了重复登录)

好,这段函数代码太短,并且不完整,而且还带了参数,也许童鞋们听不懂我在叽歪什么,那么我们继续下一段代码,这段代码就是完整的代码了,我们完全可以用"挪移"大法应用!
当然,最开始冷月已经说过,直接的复制粘贴是行不通滴,我们得分析它,了解它,才能真正的应用它!

首先,老规矩我们先看函数头"功能 字符型[] 账号()",这里我就不重复解释了,再下来是定义变量
然后这个如果的判断条件(方案一&&!方案二)大家就有点迷糊了吧?
感谢TC支持中文变量定义!感谢"超自然"大神用了中文变量!
大家还开着原帖吧?帖子一开始就放了界面图,从界面上我们可以看到两个单选框"操作此方案",我们从界面设计上可以猜到(当然用猜的啦,虽然"超自然"大神没有明确说明,但是已经很明显了,很好猜了!),这两个单选框分别对应上面的两个列表框"方案一账号列表"和"方案二账号列表",那么我们就可以推理出:方案一和方案二两个逻辑型的变量分别存储的是两个单选框的状态!那么,这句如果的判断条件就是:当方案一所获得的单选框状态为真并且方案二所获得的单选框状态为假时,执行"如果"到"如果结束"之间的代码!
好了,接下来,目标列表="列表框1"  这一句是如果的条件成立所执行的代码,在"超自然"大神放出来的界面图上我们可以看到他标示了两个列表框分别为"列表框3"和"列表框5",分边代表了方案一控制的账号数据和方案二控制的账号数据,但是并没有看到"列表框1"
(嗯,在这里,我推测,大神是应该是把"列表框1"隐藏起来了,作为数据的中转站)
那么,我们就知道了,字符型变量"项目列表"在如果条件成立时赋值"列表框1",不成立时赋值"列表框5"
小小结:这段如果判断起什么作用呢?通过之前对"方案一"和"方案二"变量的推测,我们可以理解为,利用单选框的状态来决定需要操作的对应列表框

再接下来是一个嵌套型的如果判断,我们先看外层的这个:如果 (列表框.获得文本(目标列表,0)!="")
看到这样的代码是不是有点晕?先别急着晕后面还有更晕的,对于类似的代码,我们可以把它拆分出来看!
先看"列表框.获得文本(目标列表,0)"这个命令的意思自行参照TC帮助文档里控件命令列表框命令!(呵呵,培养大家养成查看TC帮助文档的好习惯)
有人又要问了,TC帮助文档里"列表框.获得文本"命令的参数不是有个"列表框名称"么?
额,"目标列表"这是一个定义为字符型的变量吖,经过上一个如果的判断,我们已经知道它的值是"列表框1"或"列表框5",这里面的值就是对应列表框名称的了
好!我们继续,(列表框.获得文本(目标列表,0)!="")那么这个如果的判断条件就是获得"目标列表"对应的列表框里序号为"0"里的文本内容,而这个内容不为(!=)空("")
小小结:这一句如果 (列表框.获得文本(目标列表,0)!="") 代码的意思就是判断列表框第一行里的文本内容是否为空

下来到这一句:返回串[0]=字符串.截取(列表框.获得文本(目标列表,0),0,字符串.查找字符串(列表框.获得文本(目标列表,0),"*"))
哈哈,这一句更晕了吧?一样的,我们用拆分法来看,(当然前提是我们要了解每一个命令的参数格式,可以参考TC帮助文档)
首先,"字符串.截取"命令的参数格式为(字符串,截取的开始位置,截取的末尾位置)
那么,通过对比,我们知道"列表框.获得文本(目标列表,0)"就是参数里的字符串,"0"就是参数里的"截取的开始位置","字符串.查找字符串(列表框.获得文本(目标列表,0),"*")"就是截取的末尾位置
然后我们看下一句:返回串[1]=字符串.截取(列表框.获得文本(目标列表,0),(字符串.查找字符串(列表框.获得文本(目标列表,0),"*")+1),字符串.长度(列表框.获得文本(目标列表,0)))
对比上一句,我们可以知道在这一句里,"字符串.截取"命令里的参数"字符串"没变,变的是"截取的开始位置"和"截取的末尾位置"
小小结:第一句的意思是: 截取列表框第一行的文本里"*"符号之前的字符串并存储到数组"返回串[0]"里,第二句的意思是:截取列表框第一行的文本里"*"符号之后的字符串并存储到数组"返回串[1]"里!从后面的代码我们可以了解到,"超自然"大神是把账号密码以"账号*密码"的格式存储在列表框里的,那么这两句的意思其实就是把账号存储在数组"返回串[0]",把密码存储在数组"返回串[1]"里!

下来这一句: 列表框.删除文本(目标列表,0),很明显,这一句的作用就是清空列表框第一行的文本

好!接下来是第二层的如果判断:如果 (列表框.得到个数(目标列表)==0)
这一句也很明显了,就是判断列表框里是否存有文本

然后紧接着第三层的如果判断: 如果 (需切换)
这里...这里我们又要用猜的了,条件(需切换),我们分析知道第一这是一个逻辑型的变量,第二这个变量在函数里是没有定义的,那么就是一个全局变量,第三从字面上理解(再次感谢TC支持中文变量定义!再次感谢"超自然"大神用了中文变量!),这个变量是用来判断是否切换的!
那么切换什么呢?我们联系后面的代码,"如果 (需切换)"到"否则"之间的四条代码,第一条,设置标签的文本为"方案一",这是一种界面输出,作用是让使用者可以清楚了解脚本的运行情况,第二条到第四条是在给三个逻辑型变量分别赋值.然后"否则"到"如果结束"之间只有一条代码,清空列表框文本
好!现在就是考验我们的想象力的时候了,还记得函数第一层如果判断的条件么?对,就是(方案一&&!方案二),这两个变量也是没定义过的,那么也是全局变量,全局变量一般是用于几个功能函数之间的参数传递的,那么,第三层如果里为什么要在(需切换)条件成立时分别给"已回转","方案一"和"方案二"变量赋值呢?这样的情况那就是这个三个变量的值本来不是现在赋的值,所以在这里我们要把它切换成现在赋的值!
小小结:第三层如果判断的功能是:(我猜的哈!)在帖子开头"超自然"大神解释了一点"有两个账号列表,先不用看方案2,那是我在特定时段,使用一段高级账号刷高级任务用的,有另外一套控制方法,程序默认从方案1中执行."这是原话,那么从"特定时段,使用一段高级账号",我们知道脚本会在特定的时段切换到第二个列表框读取账号密码数据来登录账号,那么大神就一定写了另一个函数来判断是否切换列表框,而在这个函数里就给全局变量"需切换","已回转","方案一"和"方案二"赋值了!
那么第三层如果判断就可以这样解释了,判断是否切换到另一个列表框,如果需要切换就改变几个全局变量的赋值(通过这些变量来控制对哪个列表框进行操作),如果不需要就清空"编辑框1"里所有文本!

接下来的连续两句"如果结束"分别是对应第二层的如果判断和第三层的如果判断的结束语

再下来的两句,我们可以猜到,是两个空间名为"功能集"的函数调用语句!从函数对象名的字面上(再再次感谢........)我们可以猜到,第一个函数的功能是在标签上输出当前未操作的账号数量,第二个函数功能就比较难猜了,函数名是"配对"参数是(0),我猜这是一个初始化什么数据的函数,实际功能估计只有问"超自然"大神才能知道了!

最后是一个返回值设定,和对应第一层如果判断的否则和返回值设定,如果结束语,功能结束语,整个函数就结束了!

总结:这两个函数,前一个是把读取到的账号数据输入登录界面上(当然没有具体代码只是让我们学习了临界区的应用),第二个函数,向我们展示了读取账号数据的思路,通过分析代码,我们了解了整个函数的流程是:

一,判断操作的列表框(因为大神有两组账号需要在不同的情况下分别操作,所以我们可以不用这个判断,只设置一个列表框)

二,判断正在操作的列表框第一行文本是否为空(如果为空,说明这一组账号数据已经读取完毕,返回 返回串[0]="结束",给出返回值,让读账号的函数知道账号数据已经读取完毕了),如果条件成立(也就是不为空),那么分割文本字符串,把分割出来的数据分别存储在返回串[0](也就是账号)和返回串[1](也就是密码)中!最后删除正在操作的列表框第一行文本内容!(列表框删除一行文本内容以后如果下面还有内容会自动上移)

三,嵌套的第二层如果判断(在第一层判断条件成立也就是不为空的情况下),判断正在操作的列表框是否还有内容(因为之前删掉一行了,其实也就是判断现在读取的是否最后一个账号),参考第一条,我们也可以不用设置这个判断

四,嵌套的第三层如果判断(在第二层判断条件成立也就是现在读取的是最后一个账号的情况下),判断是否切换列表框,如果需要切换,就通过设置几个逻辑型变量的赋值来实现切换,如果不需要切换,则清空当前列表框文本内容,参考第一条,我们可以不用设置这个判断.

五,通过调用函数输出当前剩余账号数量信息到脚本界面,具体代码自行思考!额,还有个调用的函数不清楚实际功能........

六,函数返回值 设置为数组变量 返回串 (也就是存储了账号密码数据的数组 返回串[0]里是账号数据 返回串[1]里是密码数据)

通过学习了"超自然"大神的这两个函数代码,我们学到了,临界区的灵活运用,列表框控件的灵活运用!

好了,今天的学习就到此结束了,不知不觉洋洋洒洒的写了一大版,也不知道大家看不看得明白,冷月对自己的文字表达能力很没信心吖!

希望能对大家有一点点启发,冷月就开心了!

嗯,后面的两个函数"账号录入"和"保存"就留给大家自己去学习了,相信大家一定能跟冷月一样从中学到很多有用的东西!

最后!再再再次感谢"超自然"大神的无私奉献!!!!还有TC的支持中文命令和中文变量定义!!!!!(让我从此摆脱了万恶的匈牙利变量定义法!)

最最后!如果大家在学习的过程中遇到什么问题,可以到TC官方YY提问!谢谢大家的支持!祝大家使用TC愉快!










回复

使用道具 举报

发表于 2012-3-26 01:03:55 | 显示全部楼层
精彩!!!
我这人比较懒,口才也不好.冷月的解释很详细.
这里有个情况,就是为什么要清空一个列表框呢,是因为为了做无人值守功能,这东西还有个完成后动作的设置,有报警,关机可选,而完成后动作的判断依据是两个,第一,待用列表是否已空,第二,线程句柄是否全部为0,以前只有一个待用账号列表,那么用完了肯定空,所以不用清空,现在两个了,为了给时钟提供判断依据,就清空它一下.而线程句柄操作是这么回事:登陆账号这块,其实是2级调用,它上面还有一级,当账号[0]为结束的时候,返回到上级,那么上级就做了些收尾工作,窗口解绑啊,控件操作啊等等,最后,把自己的线程句柄写成0,标志着该线程已完结,同时给完成动作的时钟提供判断依据
回复 支持 反对

使用道具 举报

 楼主| 发表于 2012-3-26 01:09:16 | 显示全部楼层
回复 2楼超自然的帖子

自然哥这么晚了竟然还抢了沙发!真是让冷月内牛满面了!
谢谢自然哥的指导!
期待下一个经典代码的开源!嘎嘎!:*
回复 支持 反对

使用道具 举报

发表于 2012-3-26 05:06:54 | 显示全部楼层
chizhicindg!
回复 支持 反对

使用道具 举报

发表于 2012-3-26 08:04:47 | 显示全部楼层
先顶起来,再学习!!
回复 支持 反对

使用道具 举报

发表于 2012-3-26 09:27:59 | 显示全部楼层
大半夜还不睡觉。。
回复 支持 反对

使用道具 举报

发表于 2012-3-26 13:08:04 | 显示全部楼层
非常的不错。 支持下
回复 支持 反对

使用道具 举报

发表于 2012-3-26 13:14:57 | 显示全部楼层
先顶下载说别的
回复 支持 反对

使用道具 举报

发表于 2012-3-26 17:45:36 | 显示全部楼层
好好好好好好好好好好
回复 支持 反对

使用道具 举报

发表于 2012-3-26 21:16:53 | 显示全部楼层
谢谢分享!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条

关闭

小黑屋|TC官方合作论坛 (苏ICP备18045623号)

GMT+8, 2024-5-4 15:05 , Processed in 0.047024 second(s), 24 queries .

Powered by 海安简单软件服务部

© 2008-2019 版权所有 保留所有权利

快速回复 返回顶部 返回列表