flushthink

just for essential skill
随笔 - 14, 文章 - 0, 评论 - 30, 引用 - 0
数据加载中……

2010年12月2日

wow私服,arcemu trunk源码编译架设

对我架设一个wow私服,意义有二:1. 玩wow过程中,碰到一些实现手法不解的地方,可以实时去调试。2. 基于此服务端模拟wow客户端若干特性,比如地图资源异步加载,角色并行状态处理等。

需要工具:
1. visual studio 2010(arcemu trunk windows版本解决方案使用),不建议强制修改visual studio版本,因为可能丢失工程配置参数信息。
2. mysql,SQLyog。(mysql数据库不用说了,随便什么版本,SQLyog主要是图形化mysql命令操作)。
3. svn (因为是源码编译嘛)。

源码下载:
1. 服务端程序arcemu trunk, https://arcemu.svn.sourceforge.net/svnroot/arcemu/trunk

2. 服务端使用的数据库whydb, http://svn.xp-dev.com/svn/whydb-users
我是这样放置代码的 

编译源码:
1. 需要简单地修改几处源码,一,src/scripts/src/InstanceScripts/Raid_ZulGurub.cpp中的第184行,将?/改成*/,很明显这是手误。二,src/arcemu-logonserver/LogonCommServer.cpp中的第313~314行注释掉,解释下情况:因为wow每个游戏服务器他们叫做Realm,每个Realm都要注册到LogonServer中。考虑到不是我的Realm不能注册到我的LogonServer,所以存在这授权处理的一关。我去掉主要是烂的去改配置文件。三,src/arcemu-world/HackFixes.cpp中第54~57行注释掉,解释下情况:因为官方只支持enUS和enGB,在加载spell.dbc的时候做了一个本地化核实。可以编译了。
2. 创建3个数据库arc_characters, arc_logon, arc_world.然后通过下图的操作

分别将sql目录下的3800_character_structure.sql导入到arc_characters里,将2834_logon_structure.sql导入到arc_logon里。然后再将sql/character_updates目录里高于3800打头的sql导入到arc_characters,同样将sql/logon_updates目录里高于2834打头的sql导入到arc_logon。为什么不导arc_world?呵呵,因为源码里带的arc_world只是表结构定义,里面并没有数据。这个要用whydb导入。进入whydb目录,双击tool.bat就行了。

回车

继续回车,就安装好了。
然后在arc_logon的表accounts里加入几个账号:



重点说明下,此数据库,服务端程式逻辑适用于3.3.5a版本,也就是wow大灾变前夕的前一个版本。
所以必须准备一个3.3.5a版本的wow。我用的台服的client,当然你用国服的也是一样。很不幸的是我从3.0.3一个个patch打上来的。
如果你也想和我一样过一过打patch的瘾,你可以去http://tlax.5d6d.com/thread-1778-1-1.html一个个补丁下吧。
如下:



至于服务端configs里的*.conf,客户端的登陆配置,上网上随便找找就是了。
我要重点说下服务端适用的dbc和maps资源。如何从client取。
首先说dbc:编译解决方案mpqe_cpp.sln,然后将extractdbc.bat,mpqe_cpp.exe,SFmpq.dll拷贝到Data/zhTW目录下,然后执行bat就生成了dbc,然后将所有*.dbc拷贝到服务端的dbc目录里。
再次说maps:编译解决方案AD100.sln,然后将ad.exe拷贝到world of warcraft目录,和data同层,然后再将Data/zhTW里的locale-zhTW.MPQ拷贝到Data里(因为这个程序比较傻,他没有递归遍历到所有的档案,他想从locale-zhTW.MPQ里去找Map.dbc),然后执行ad.exe,然后将maps里所有的.bin文件拷贝到server的maps里就ok了,基本配置配置就可以跑了。
有什么不清楚的再讨论吧。

posted @ 2010-12-02 05:15 tiny 阅读(15071) | 评论 (19)编辑 收藏

template tips

1.当template parameters和call parameters之间没有明显联系,而且编译器无法推导出template parameters时,必须明确地再调用时指定template arguments
2.如果template parameters作为返回类型,那么也必须显式地指定template parameters,不过你可以把这个返回类型放在template parameters的第一个位置,只指定第一template parameters,其他的让编译器去推导。
3.就像functions一样,function templates也可以被重载。
4.在编译的过程中,编译器会根据每次具体使用的函数(带有template的function),来生成具体的函数代码实例。
5.在自变量推导过程中,惟有当参数不是一个reference类型时,array才会退化为pointer(通过称为退化)。
6.function template或class template的implement必须放在.hw文件里。常规的编程方法是把function或class的declare放在.h的文件中,把implement放在.cpp中,对应declare的implement已经在编译时生成了编译符号,所以可以在运行时调用。而function template或class template不同,它要针对具体的template parameters去生成不同的实例,而这个过程不会去多次解析放在cpp中的实现。

posted @ 2010-12-02 03:56 tiny 阅读(1420) | 评论 (2)编辑 收藏

2010年11月11日

event driver

事件机制最大的好处就是实现了伪并行。 os层提供了thread通过切换时间片来实现软件层面最真的并发。 事件机制处理,通过遍历一个事件的若干个订阅者来实现出类型的并发。

posted @ 2010-11-11 16:04 tiny 阅读(1469) | 评论 (1)编辑 收藏

2010年6月5日

sandbox

在系统级开发,往往需要暴露出一些api给用户使用,暴露出来的api,就像做了一个sandbox(沙箱)给孩子玩耍一样,孩子不会破坏到外面的世界。

posted @ 2010-06-05 11:01 tiny 阅读(1964) | 评论 (1)编辑 收藏

2010年6月4日

linux命令参数类型

在linux下的命令共有三种,例子说明: 1.ls -l. 这种是unix类的命令参数风格。 2.ls --help. 在linux发展,需要扩展unix的命令参数,就用这种形式。 3.ls -version,在linux图形化过程又扩充了之前的命令参数。

posted @ 2010-06-04 09:26 tiny 阅读(1437) | 评论 (0)编辑 收藏

volitale的用法条件

1.当存在线程或中断切换上下文时。 2.变量类型为寄存器类型(整形,bool等)。

posted @ 2010-06-04 09:22 tiny 阅读(2366) | 评论 (0)编辑 收藏

2010年1月20日

多少人画用例?

这几天自己做了一个编辑器,转了一大圈又回到了用例。对需要实现什么功能模棱两可,害的一遍遍重构,后来才发现出在用例上。用例太重要了。
在做这款软件,我需要明确知道我需要它做什么,我的软件就要围绕着它的用途逐一展开。如果在用例的时候就扭曲了,最后它就像一篇走了题的作文,技巧用的再多那都毫无价值。至于类图设计阶段,要尽量做到类体积均衡,一类负责一事。设计类的时候,内存模型,线程模型作为基准。尽量少用内存,在不影响效率的情况下用new。做好new对内存环境潜在的破坏修复。以及后面时序图阶段,保证某一条或某几条时序执行效率(io效率,循环中无效剔除效率)。

posted @ 2010-01-20 16:20 tiny 阅读(1693) | 评论 (2)编辑 收藏

2009年11月26日

serialize

序列化文件可能要注意的几点:(不足给予补充)
1.不同cpu体系结构的硬件所支持的字节序不同,所以序列化的目标数据要以一种字节序为主,一般分为小端,大端,本地端(根据程序运行的机器来的)。
2.在序列化的时候就要考虑反序列化的一些便利,可以对原始数据类型做分类,所有组合原始数据的高级数据一般通过索引原始数据来获取(这样也降低了数据冗余),这样你就可以保证数据的chunk化。
3.尽可能地让文件格式不同于其他,为了此文件格式的扩展可以做一些版本指定。
4.如果你考虑到serialize的灵活性,就一定要抽象device以及stream这2个概念,device控制着使用什么stream去读写,而stream直接操纵buffer,所以在stream你可以控制读写数据的安全性(多线程)与效率。

5.现在不只考虑serialize单个文件,而考虑序列化一个文件层次结构到硬盘,一般会抽象出个archive来,这个archive存储在硬盘上,所以首先这些数据的序列化必须满足os的文件系统格式(这个不用担心了,直接操作FILE,fstream就ok了),而后为了数据包装(一是为了安全,二是为了大小,三是为了不凌乱),我们一般要对archive进行拓展,拓展archive的行为,比如在内存写到硬件这个基本函数的进行压缩并加密,而在硬盘恢复到内存这个基本函数上进行解压缩并解密,这里存在个问题,archive不是一次性读取到内存,所以最好给每个archive做个头数据,至少保证这个头数据一定要读到内存,头数据的意义就是选择性地读取archive的数据段,罗列archive的层次结构等(至于大小写敏感的问题,尽量做一些协调)。

posted @ 2009-11-26 07:33 tiny 阅读(1335) | 评论 (1)编辑 收藏

2009年11月19日

模型视图变换时,法线向量要乘模型视图矩阵的逆转置矩阵

早前一直被这个问题困惑,但是自己推倒了很多遍也没推出来。
哎,在gameres上搜了3年前的谈话,后来在gamedev搜到了答案。
其实在计算机图形学中,只要是变换,无论平移,旋转,缩放,都是乘一个矩阵。
在模型视图变换时,顶点乘模型视图变换矩阵,而顶点对应的顶点法线向量(或其他的法线向量)则要乘模型视图矩阵的逆转置矩阵。
顶点和法线都是向量,他们的区别是什么?无非顶点是<x, y, z>表示缺省的<x, y, z, 1>,而法线向量是<x, y, z>表示缺省的<x, y, z, 0>。关于为什么是这样,不用我说了吧,2个顶点向量减下看看就知道了。
从这点来看,确实不同,或许就是这个不同,造成了变换的不同吧。
法线向量只能保证方向的一致性,而不能保证位置的一致性,所以,所有线向量必须以面的形式进行变换,如下:

Transforming Planes

If we have a plane vector n = [a, b, c, d] which describes a plane then for any point p = [x, y, z, 1] in that plane the follow equation holds:

nt p = ax + by + cz + d = 0

If for a point p on the plane, we apply an invertible transformation R to get the transformed point p1, then the plane vector n1 of the transformed plane is given by applying a corresponding transformation Q to the original plane vector n where Q is unknown.

p1 = R p
n1 = Q n

We can solve for Q by using the resulting plane equation:

n1t p1 = 0

Begin by substituting for n1 and p1:

(Q n)t (R p) = 0
nt Qt R p = 0

If Qt R = I then nt Qt R p = nt I p = nt p = 0 which is given.

Qt R = I
Qt = R-1
Q = (R-1)t

Substituting Q back into our plane vector transformation equation we get:

n1 = Q n = (R-1)t n

posted @ 2009-11-19 14:38 tiny 阅读(3010) | 评论 (4)编辑 收藏

2009年11月10日

compiler opt

公司的平台只编译了release版,我们就必须在release下写具体实现。(依赖release写debug会出问题)
可恶的是,我的代码对象层次颇多,所以我写了很多小函数,这些小函数在release版本下默认是内联的。
就这样造成了悲剧,过多的内联,把调试器都晃晕了,索性,我把编译优化关了,发现dll膨胀到2倍。

posted @ 2009-11-10 07:25 tiny 阅读(1666) | 评论 (0)编辑 收藏