当前位置:首页 » 硬盘大全 » phpmap缓存
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

phpmap缓存

发布时间: 2022-02-07 15:09:03

‘壹’ 【追加高分】魔兽地图反作弊

"反WE类"
这类可以说是最常见的了,最早的加密就是为了使WE打不开地图,方法也很多
1.删除WE的使用而游戏不需要的地图内部文件.
如war3map.wtg,war3map.w3c,war3map.w3s,war3map.w3r等文件,其中war3map.wtg是触发文件,游戏运行时使用的是war3map.j脚本文件,而触发文件是用来在WE中显示更为直观的T,其余war3map文件则是镜头之类都可以在J文件中定义的东西,游戏也不需要,因此删除这些文件可以使WE因为缺少文件而无法打开地图.
加密方法:使用工具如w3mmaster,Wc3MapOptimizer,其中Wc3MapOptimizer是当前最好的工具,而且与其说是加密还不如说是优化,使用该工具除了删除无用文件外,还可以优化脚本,加快地图读取速度等.(这里推荐使用时参照老狼写的使用说明,写的比较详细,工具现在已经有偶汉化的4.5版,里面集成了老狼的大部分说明,这里推荐大家使用- -).另外一方面还可以手动使用MPQ工具进行删除或在WE中导入同名的空文件(最老的手动加密方式- -),当然手动方法是不被推荐的,因为没有任何优化效果,而且这种加密是最容易破解的.
2.导入错误文件.
这种手段也是比较初级的加密手法,使用错误的war3map.wtg或在非正常数据环境下制作相关触发数据(如修改MPQ包中的blizzard.j文件,加入新函数等- -),同样造成WE错误,没有优化效果.这样做的原因是因为出现了可以忽略常规缺少文件错误的新WE(如反汇编制作的ENE WE等),这类WE可以打开缺少触发等文件的地图(不过由于缺少文件,你依然不能修改和存储地图,这也是一些菜鸟修改者修改完地图后发现地图完全不能游戏的原因),在使用错误数据后这类WE大多会出现内存读取出错.(可见加密技术都是解密而发展的- -)
值得一提的是某些修改war3map.w3u(单位文件)等基础数据文件的做法,这种做法比较另类,向其中加入游戏中用不到的冗余错误数据,同时造成其中数据与war3map.wts等文件中数据错位.这种方式是针对现在比较流行MPQ工具导出相关文件进行外部修改的破解手段的,因为很多人喜欢导出w3u 文件单独放入WE修改,而在没有使用Wc3MapOptimizer的WTS字符优化时,还需要导入WTS文件来查看文本信息,这时冗余的数据会造成错误,导致WE出错退出- -,不得不说很有创意,不过如果使用w3mmaster修改的话就没有任何效果了,外加没有优化效果,因此也是不实用的方法.
3.SLK优化
这种方式最大的好处是可以大幅加快地图读取速度,SLK文件优化得当的话,体积也可能减小,是当前最好用的优化手段之一,很多优秀的地图如DOTA都是这种优化的.
原理:懂得基本的地图组成结构的人都应该知道,单位,技能等信息都是储存在w3u,w3a这样的文件中的,然而没有实质的了解其结构的人可能就不会知道实际上这些文件中储存的不过是改动信息,而这个改动是相对于魔兽基础MPQ文件中的SLK文件而定的.地图在读取地图时会读取w3u等文件,而如果这些信息都作为SLK的基础信息的话则不会占用读取时间,这样就做到了优化,而且SLK的读取速度也比较快.因此优化的过程实际上就是拆散w3u等文件再放到SLK文件中去.
SLK更多的是作为优化而言的,如果说到加密,那就是因为他可以防止w3mmaster这样的外部修改器,同时对于不了解内幕的人,也会因为找不到单位等数据文件而无从下手,不过现在基本上人人都知道SLK文件可以用EXCEL这样的工具来直接修改了,因此作为加密而言只是增加了修改的复杂性.
相关工具:Widgetizer(最早的SLK工具,性能可靠,可惜不支持中文,如果你是英文图的话,还是用这个最好),U9MapOpt(U9地图优化器,目前唯一支持中文的优化器,不过还不能优化大小,而且有加广告的"BUG"...).
总体来说"反WE类"是目前最广泛使用的加密方式,而且这类大部分是优化而非真正意义上的加密,同时我建议使用的SLK+Wc3MapOptimizer的优化方式.
"反MPQ类"
前面说过使用Wc3MapOptimizer等工具只能说是优化而非加密,原因之一是他们主要是做使地图变小,读取变快的优化,另一方面就是对于这类反 WE的地图,修改者最常用的手段是使用MPQ工具进行内部文件的修改,对于这类修改,很长时间内可以说是无敌的解密方法,因此真正可以说得上是加密的就是反MPQ类.
1.MPQ头文件修改
这种修改方式由来已久,直到不久前hackwaly的新加密方法出现之后才真正流行起来要讲其原理,需要先了解一下mpq头文件的结构
struct TMPQHeader文件头结构定义
{
DWORD dwMpqFlag;头文件标志,一般是'MPQ'
DWORD dwHeaderSize; 头文件大小
DWORD dwArchiveSize; MPQ包大小
USHORT wFormatVersion;版本(这个直到WOW燃烧远征才开始有用,MPQ2这个值是1,魔兽的MPQ1是0)
USHORT wBlockSize; 块大小,熟悉的人一般叫它BUFFER SIZE
DWORD dwHashTablePos;哈希表偏移位置
DWORD dwBlockTablePos;块表偏移位置
DWORD dwHashTableSize;哈希表大小
DWORD dwBlockTableSize;块表大小
};
具体的含义在MPQ讲解中我还会介绍,这里只说和加密相关的.
1.同样的这种加密也是随着相关MPQ工具而发展的,最早是soar(GA的c-a)的mpqworkshop,这个工具有一个弱点是其寻找MPQ时需要检验头文件大小(dwHeaderSize)这个值,而由于MPQ1的这个值显然是固定的32,所以当人为的修改这个数为一个随机数时,该工具就会认为这是个无效的MPQ文件,造成无法打开,当然明白了原理后这是很容易破解的,而且现在的MPQ工具都忽略这个错误.不过这个修改这个值几乎成了习惯,虽然没有作用也还一直沿用着.
2.之后出现了w3mmaster和mpqmaster,依然是soar的作品,使用自己制作的mpqlib,可以忽略dwHeaderSize的错误 (同时sfmpq也一样).很长时间内MPQ头的加密没有新的发展,直到今年初,hackwaly公布了他的研究成果,新的killmpqmaster加密,实质上是修改块表大小为大于哈希表大小的数.这里简单讲一下原理:
最通俗的语言来说,MPQ就可以看成一本书,但他有两个目录,哈希表是第一个,当你要找书中的一页时需要先查哈希表,得到块表这个目录的位置,再从块表中查找到具体的页数,而MPQ这本书还有一个特殊之处是哈希表这个目录的大小是固定的,也就是说书里面最多能放的页数也是固定的(这就是MPQ中文件数有上限的原因),而如果我们的内容不能装满整个书的话,那么哈希表的一部分就是空的.而块表不同,他只存放有效的页,因此他的大小是不固定的,哈希表与块表是一一对应的,因此块表不可能比哈希表大.
再讲一下MPQMASTER的文件查找原理,大家就会明白为什么修改块表大小会造成这类工具不能读取地图的原因了.MPQMASTER准确说是 mpqlib.dll是需要枚举MPQ包中的每一个文件的,而魔兽则只需要查找其需要的文件,也就是说,魔兽在翻书时直接查找目录找文件,而不必去管目录到底有多大,什么时候目录会结束.而MPQMASTER则需要知道这个,他要先知道目录的大小才能得知什么时候已经找到了所有文件,mpqlib是根据块表来查找的,因此如果修改了块表大小,就相当于让他去不存在的目录查找文件,这当然是错误的.
3.修改MPQ包大小(dwArchiveSize)为0,这是我个人最先发明的,原理实际上也和修改块表大小差不多,但实际上还是由于mpqlib的严谨性,mpqlib在读取MPQ文件结构时会验证一些数据的准确性,虽然不一定有用,但是正是这项检查造成修改MPQ包大小后,mpqlib将地图识别为错误MPQ.
4.修改哈希表大小(dwHashTableSize),这种加密也和我有一定关系,不过没有流行起来,而且事实证明也并不是一种安全的加密
在killmpqmaster加密(工具为hackwaly的w3xmaster)流行后,mpqmaster的使用受到限制,当然也出现了不少手动破解方法,不过相对而言最好用的是winmpq和我的ShadowEditor,sfmpq是因为其在查表时是检查哈希表而不受块表错误的影响,同时也不检查 MPQ包大小,因而可以正常打开w3xmaster加密的地图,不过从w3xmaster0.006开始采用了修改哈希表的技术而造成其显示错误文件而不那么好用了.同时期我就结合了sfmpq的优点做了ShadowEditor,自动修复所有的头文件错误,修复后可以用mpqmaster打开.作为反 ShadowEditor还原的第一例,就是55YOU的简单做的修改哈希表大小加密,理论上说哈希表大小会直接影响查表的过程,因而不能修改,但确实在一些特例中成功了,但并不是所有图都可以,再加上我第一时间修改了还原程序,这个加密貌似就只出现了那么片刻的时间- -...
2.利用地图大小限制
魔兽连网是有4M大小限制的,而在早期大家都使用MPQMASTER来修改地图时,由于mpqlib的压缩性能较差,因而总会造成地图变大,有些加密就是利用这个漏洞,在地图较大的情况下干脆直接让地图接近4M,这样随便改动都会造成无法连网.这种加密实际上也在winmpq和偶的 ShadowEditor流行起来之后变得用处不大了,因为SFMPQ.DLL的压缩效果要明显好的多.
值得一提的是最近还能见到一些图利用0byte文件来填充的方法把MPQ包添满,当然这也是在地图本身比较大的情况下,这种方法貌似是利用地图大小的升级加密版本,因为这样即使压缩的很好也有可能超出4M,不过解起来也很简单,把这种文件删就好- -,所以感觉是种很搞笑的方法.
3.脚本文件加密
包括3种:
1.最早的是移动脚本,把根目录下的war3map.j放到scripts\下依然可以用,在开始没有人知道的情况下,确实找不到脚本,但是现在已经是路人皆知的事情了,使用Wc3MapOptimizer会自动移到那里去.
2.双脚本,一个在根目录下,另一个在scripts\下,出现两个脚本,迷惑新手罢了,当然只有一个是真的,我给他的评价是劳民伤财,白占体积- -.
3.替身脚本,这个理论上有些技术含量,和后面要讲的我的文件隐藏法有一定的联系,原理上说是利用了魔兽的storm与一般工具的MPQ库之间读取文件的原理差异,在地图中放入两个同名的war3map.j,一个是假的替身文件,在用一般的MPQ工具读取时只能读出假文件,游戏则会读真的,识别方法可以用偶的ShadowEditor打开发现两个同名的war3map.j 且大小不一样(大小不一样很重要,因为w3xmaster也有一种能造成这种假象的),这种方法对所有具有写入功能的MPQ工具都有效,不过估计应该不是用某种专门加密器完成的,估计是用了某个MPQ工具的BUG,而且这种方法加大地图体积,还可以用简单的方法破解,因此我只说他是理论上有技术含量的东西 - -.
4.文件属性加密
这种貌似是最扯淡的加密了,方法简单的出奇,而且不容易察觉,就是把地图的属性改成只读,这样任何MPQ工具都不能对其进行写操作了,当然还原方法不用多说了,不过不仔细的话还真以为是什么厉害的加密呢,汗......
5.MPQ哈希表,块表加密
这种才可以说是真正意义上有技术含量的加密(相对于Wc3MapOptimizer等工具也算不上有技术- -,不过那些是优化...),从hackwaly的w3xmaster开始.
这里只举两个例子:
1.w3xmaster0.009:未公布的地图加密器,主要原理是将块表扩充为确实比哈希表大,同时打乱哈希表与块表间的连接,填充无用的哈希空位,迷惑性的复制哈希表项目(这就是为什么ShadowEditor可能读出两个J文件的原因,大家也可以推想一下替身脚本的原理- -...),再详细的原理我也不想说了,未公布的东西不能乱讲,其实主要是防止我的ShadowEditor对地图进行还原,同时也造成了无法重压缩的问题,虽然不能防止解压,但是确实比较有效的防止了在原图上进行修改.
2.War3map Encrypt:未公布的加密器, 这个是我做的,也是只简单的讲一下原理:前面已经说过war3和一般的mpq工具读图原理是有差别的,这也是制作加密的突破口,简单的说这个差异就是在 MPQ中出现同名文件时的处理机制,因为正常的MPQ是不会有同名文件的,因此一般的MPQ工具不会处理这个错误,而war3则会,因此才有了替身文件和隐藏文件的可能,与替身文件不同的是,我的加密是通过直接修改哈希表制作的,因此我不需要替身文件可以直接隐藏文件,同时在加密中加入了SFMPQ列表读取崩溃和w3xmaster的一些反mpqlib机制,所以现在基本上可以防止所有流行的MPQ写入工具进行修改,甚至读取.不过既然魔兽能够读取,那么就一定有办法能解压文件,这种方法是什么我就不想多说了,这里只是加密讲解.
话说回来任何加密都可以破解,懂得MPQ核心原理的人应该可以自己写程序破解,不过我的SE暂时是不会再写任何破解模块了...
"脚本类"
从这类开始应该说就是反作弊的范畴了,这类出现的前提是无法阻止脚本文件的解压,以及某些外挂作弊(MH)
1.打乱脚本,变量名替换.
这是最早的了,也是沿用至今的基本方法,代表工具是Wc3MapOptimizer,利用他进行脚本优化后,脚本中放在一起的T相关函数被分散并进行同类汇总,删除注释,这样造成脚本可读性变差,但是真正使可读性变得很差的还是重新用字母或数字来替换那些有意义的函数名,这样就给理解脚本造成了很大的麻烦,因此修改脚本时需要的是对于J文件的深刻理解了.
2.添加作弊检查的函数.
这类方法很多,比如检查玩家的资源数等,只要超出合理范围就判定为作弊,同时可以检查是否使用了单机秘籍.其中还有一类比较有趣的方法是在游戏中读取wts文件的字符,如果修改者修改了某些字符,如作者信息之类就判定此图为盗版.
3.禁止单人游戏.
这种多用于ORPG,防止单机秘籍的使用造成游戏平衡性破坏.
方法有几种,比较好用的有判断是否可以保存缓存,单机可以,多人就不行,另外判断是否可以保存游戏也可以做到,同样是只有单机可以.
单机判断和作弊检查函数联合,同时分散写上多个处判断函数,可以使修改者不容易删除判断函数,而且在判断为作弊后采用死循环或大量制造单位的方法来强制地图出错,也可以防止修改者通过文字信息来找到相关函数.
4.反MH函数.
MH无疑是最让对战地图头疼的东西,不过在kook,hackwaly,朱朱等人的研究下,确实找到了一些反MH的脚本方法,我没有仔细看过他们的脚本,所以以下只是简单的写点基本原理,如有不对的地方还请指正- -:
1.通过触发选择不可见单位,然后判断是否出现取消选择的事件来判断是否使用MH,在开了MH后是不会出现取消选择的事件的.
2.通过在不可见区域创建闪电特效,如果没有开MH不会返回句柄,开了就会有.
3.使用由hyp制作的看见就会造成游戏错误的模型.
"特殊标示类"
说到特殊标示,最先想到的应该是官方的兰色小标志,这一类就是采用各种算法来给地图加上独特的标示,通过标示可以方便的辨认正版地图.
1.官方的签名.
这个不知道有多少人想要破解了,不过现在还没有人成功,而且估计也不可能有人成功
原理:对地图内容进行SHA-1摘要,然后对摘要的结果进行RSA运算,当然懂RSA的人应该知道这运算是要有自己的私钥的,结果是一个260字节的签名,放在地图末尾,在game.dll中有检验这个签名的公钥,只要验证成功就会加上兰色小标志.
知道原理就不难理解为什么这个是不可能破解的了,首先RSA现在还没有破解理论,其次你不可能从暴雪手里偷到那个私钥,因此该签名是目前最保险的防盗版方法.
2.GA的签名.
既然我们不可能从官方得到地图签名,那我们就自己改,通过将game.dll中的公钥修改为自定义的和自己的私钥相匹配的数据,我们就可以做自己的签名了,这就有了GA的补丁,不过确实这种补丁的推广很难,广大玩家并不像地图作者那样需要他......
3.盗版地图删除器.
这个东西的作用不是很大,但毕竟起过一些作用,这里把他放在标示类也有一些原因.
原理:早期的盗版地图删除器如3CORC之类的,是根据地图大小来判断是否正版的,这样做的缺点是每更新一张地图就需要更新一次删除器的列表,比较麻烦. 后期我为WOW8制作的删除器是采用类似签名的摘要加密法,不知道原理的情况下很难仿制,而且随便的更改都会造成不匹配,这样只要用删除器对签名进行判断就可以验证是否是正版图,不需要更新列表这种麻烦事.至于算法可以自己随便选择,如MD5,RSA等有名的算法...
4.(attributes)文件.
这个文件是官方检验地图文件是否受损的文件,也是所有改图者必删的文件,否则游戏中就会提示文件错误.
原理:这个文件是按照MPQ中的文件顺序将每个文件的CRC32值,文件时间等数据放入(attributes)中,游戏中进行检验,在MPQ2中应该还包括MD5校验.
这个东西由于一般都被删了所以也没什么作用,不过可以是另外一种盗版地图删除器的判断方法,加入自定义的校验文件(里面包含关键文件的MD5,CRC32等值),然后检查时自动查找就可以了,由于是自定义文件名,也不容易被直接找出来.
我也不知道是不是。

‘贰’ php -> =>的问题

在PHP里面 ->用来引用对象的成员,包括属性和方法,=>只用来数组赋值。

‘叁’ thinkphp5 类库映射怎么用 addclassmap

ThinkPHP 类库说明
ThinkPHP 基类库
类库是 ThinkPHP 的核心部分,而 ThinkPHP 又通过基类库的概念把所有系统类库都集中在一起管理。核心基类库包括完成框架的通用性开发而必须的基础类和常用工具类。
基类库位于 ThinkPHP 系统目录下面的 Lib/Think 目录内,由下面几个部分组成:
Core:核心类库包
Db:数据库类库包
Exception:异常处理类库包
Template:内置模板引擎类库包
Util:系统工具类库包
Core 核心类库
Core 核心类库包括如下类文件(目录):
Think.class.php:系统基类
App.class.php:应用程序类,执行应用管理
Action.class.php:控制器基类
Model.class.php:模型基类
Model/AdvModel.class.php:高级模型类
Model/RelationModel.class.php:关联模型类
Model/ViewModel.class.php:视图模型类
Log.class.php:日志处理类
View.class.php:视图输出类
Db 数据库类库
Db 核心类库包括如下类文件(目录):
Db.class.php:数据库中间层实现类
Driver/DbMysql.class.php:Mysql 数据库驱动类
Driver/DbMysqli.class.php:Mysqli 数据库驱动类
Driver/DbPdo.class.php:PDO 数据库驱动类
Driver/DbPgsql.class.php:Pgsql 数据库驱动类
Driver/DbSqlite.class.php:Sqlite 数据库驱动类
Driver/DbOracle.class.php:Oracle 数据库驱动类
Driver/DbMssql.class.php:Mssql 数据库驱动类
Driver/DbIbase.class.php:Ibase 数据库驱动类
在 Driver 目录下针对不同数据库有不同的数据库驱动类,然后再通过 Db.class.php 数据库中间层实现类加工后,展现在 ThinkPHP 使用者面前的就是统一的数据库操作模型。
Exception 异常处理类库
Exception 异常处理类库包只包含一个类文件:ThinkException.class.php 系统异常基类。
Template 内置模板引擎类库
Template 内置模板引擎类库包括如下类文件(目录):。
ThinkTemplate.class.php:内置模板引擎类
TagLib.class.php:标签库基类
TagLib/TagLibCx.class.php:CX 标签库解析类
TagLib/TagLibHtml.class.php:HTML 标签库解析类
Util 系统工具类库包
Util 系统工具类库包提供了系统开发中一些基本的工具,具体包括:
Behavior.class.php:行为扩展基类
Cache.class.php:缓存管理类
Cookie.class.php:Cookie 管理类
Debug.class.php:系统调试类
Dispatcher.class.php:URL 解析、路由和调度管理类
HtmlCache.class.php:静态缓存类
Session.class.php:Session 管理类
Widget.class.php:插件应用类
Cache/:各类型缓存类文件目录,包括:文件缓存类、Sqlite缓存类、Apachenote缓存类、Memcache缓存类、Xcache缓存类、数据库类型缓存类等
Template/:模板引擎解析类目录,包括:EaseTemplate模板引擎解析类、TemplateLite模板引擎解析类、Smart模板引擎解析类、Smarty模板引擎解析类、Think模板引擎解析类
ThinkPHP 扩展类库
ThinkPHP 官方网站额外提供了很多的基类库扩展,这些扩展类库必须放置于 ThinkPHP系统目录/Lib 目录下的 ORG 或 Com 类库包内进行管理。
对于需要添加进入扩展类库包的类库,可以直接带路径拷贝类库文件到扩展类库管理目录就可以使用了。例如要使用 Util/Page.class.php 分页扩展类库,直接到扩展类库管理目录形成 Lib/ORG/Util/Page.class.php 即可。
对扩展类库需要使用 import 指令导入方可使用,具体参考本节内容《ThinkPHP import 类库导入》。
应用类库
应用类库是指项目中自己定义或者使用的类库。应用类库目录位于项目目录下面的 Lib 目录。
以上是 ThinkPHP 核心 —— 类库的的介绍。了解 ThinkPHP 类库有助于我们了解 ThinkPHP 的层次结构和工作原理,必要的时候参考这些类库的源代码也有助于问题的解决。

‘肆’ 你好!ThinkPHP,上下页代码怎么写

地址:http://www.thinkphp.cn/info/192.html
分页查询
分页类需要和查询相结合,我们可以使用ThinkPHP自带的limit方法或者page方法,目的就是为了获取当前分页的数据(也有先获取完整数据然后前端分页显示的方法,不在本文描述内容中,也不建议)。使用limit方法或者page方法是和数据库类型无关的。
我们首先在数据库里面创建一个think_data数据表用于测试:
CREATE TABLE IF NOT EXISTS `think_data` (
`id` smallint(4) unsigned NOT NULL AUTO_INCREMENT,
`title` varchar(255) NOT NULL,
`content` varchar(255) NOT NULL,
`create_time` int(11) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
复制代码
要使用分页查询,一般来说需要进行两次查询,即第一次查询得到满足条件的总数据量,然后第二次查询当前分页的数据,这样做的作用是告诉分页类当前的数据总数,以便计算生成的总页数(如果你的显示只是需要上下翻页的话,其实总数查询可以省略或者进行缓存)。
一个标准的分页使用示例如下:
$Data = M('Data'); // 实例化Data数据对象
import('ORG.Util.Page');// 导入分页类
$count = $Data->where($map)->count();// 查询满足要求的总记录数 $map表示查询条件
$Page = new Page($count);// 实例化分页类 传入总记录数
$show = $Page->show();// 分页显示输出
// 进行分页数据查询
$list = $Data->where($map)->order('create_time')->limit($Page->firstRow.','.$Page->listRows)->select();
$this->assign('list',$list);// 赋值数据集
$this->assign('page',$show);// 赋值分页输出
$this->display(); // 输出模板
复制代码
如果没有任何数据的话,分页显示为空白。所以在进行测试之前,请确保你的数据表里面有一定的数据,否则可能看不到分页的效果。如果使用page方法查询的话,则可以改成:
$Data = M('Data'); // 实例化Data数据对象
import('ORG.Util.Page');// 导入分页类
$count = $Data->where($map)->count();// 查询满足要求的总记录数
$Page = new Page($count);// 实例化分页类 传入总记录数
// 进行分页数据查询 注意page方法的参数的前面部分是当前的页数使用 $_GET[p]获取
$nowPage = isset($_GET['p'])?$_GET['p']:1;
$list = $Data->where($map)->order('create_time')->page($nowPage.','.$Page->listRows)->select();
$show = $Page->show();// 分页显示输出
$this->assign('page',$show);// 赋值分页输出
$this->assign('list',$list);// 赋值数据集
$this->display(); // 输出模板
复制代码
然后,我们在模板中添加分页输出变量即可:
<table cellpadding=3 cellspacing=5>
<volist name="list" id="vo">
<tr>
<td >[ {$vo.create_time|date='Y-m-d H:i:s',###} ] {$vo.title} </td>
</tr>
</volist>
<tr>
</tr>
</table>
<div class="result page">{$page}</div>