作者:赖勇浩(http://blog.csdn.net/lanphaday)
现在去看安装部分,可能显得颇为怪异。其实不然,之前一路假设游戏已经安装完成,是为了早点看到游戏界面,看看页面是怎么样显示的,请求是如何执行的。事实上,在分析前面的代码的过程中,我感觉到有一个明显的不足,就是我们甚至不知道数据库的架构是怎么样的,有几张表,表里有什么字段,字段又是什么意义。这些问题,如果不去分析它的安装文件,已经没有再简单的方法了。所以让我们静一下心,拨去表面的浮华,看看它的内部机理。
这就是安装程序的入口,在分析 ogame/index.php 的时候已经说过如果检测到 XNova/OGame还没有被安装,就跳转到 ogame/install/index.php。
前面仍然是例牌的 include() ogame/extension.php 和 ogame/common.php,还有两个新的文件值得注意,ogame/includes/databaseinfos.php 和 ogame/includes/migrateinfo.php。其中前者定义了各个数据库表的创建语句,后者则定义了一组 SQL 语句模板。
再读一下去,肯定会留意到那个巨大的 switch,根据 $mode 参数选择显示的页面。case 分枝其实是安装的流程,第一个分枝 intro 就不多说了,就是从 ogame/templates/install/ins_intro.tpl 读入简介,然后 parse 为相应语种的简介页面。
ins 分枝是是真正的安装过程,分为 4 个页面,由 $page 变量控制显示哪一个页面。当 $page 值为 1 时,先做可能存在的错误处理;如果没有错误代码,那么就读取 ogame/templates/install/ins_form.tpl 模板,parse 成可以输入服务器地址、数据库名、表名前缀、用户名和密码的 html 页面。用户填入这些数据后,点击 install,就进行 $page 值为 2 的流程。
$page = 2 的流程其实就是创建数据库表的流程。首先程序从 _POST 获取用户填入的数据库信息,然后连接数据库,不成功的话,就跳转到 ogame/install/index.php?$mode=ins$pagee=1&error=* 的页面,其中 * 是相应的错误代号。处理错误的流程前面已经说过了。
假定填入的数据没有错误,数据库也连上了,就尝试写 ogame/config.php 文件,在其中记录下这些数据库的连接。
接着就执行由 ogame/install/databaseinfos.php 定义的数据库语句,分别创建 aks、annonce、alliance、banned、buddy、chat、config、errors、fleets、galaxy、iraks、lunas、messages、notes、planets、rw、statpoints 和 users 这几个表,其中有些表名用的是德语,或者缩写,比较难懂,我们暂时可以不去了解。ogame 比较有特定的是存在 config、errors 等表,将整个游戏的配置和代码放入了数据库中去。关于数据库的各个功能,我们在以后分析各个功能的时候就可以看到了,当然,现在根据表名也能猜个八九不离十。
$page = 3 是让用户输入管理员用户名、密码、email、星球和性别的简单页面,填完提交,进入 $page = 4 的流程。在这一步会检验用户的输入,如果不合法,则返回上一页,并显示相关的提示。一切 OK 的话,就从 ogame/config.php 中读入数据库的数据,连接数据库后先将管理员账号插入到 users 表中去,这样我们游戏的第一个用户就产生了。然后是像 planets 表中插入用户所拥有的星球,这样就产生了游戏中的第一颗星球。然后向 galaxy 表中加入刚才创建的新星球。最后要说的是对 config 表的修改,向 config 表中写入最后设置的星系位置、系统位置和行星位置,另外已注册用户数加一。
至此,安装完毕。
我个人觉得 XNova/OGame的这个 config 表很有意思,所以单独地谈谈它。它只有两个字段,config_name 和 config_value,每一条记录都是一对一的映射。在安装的时候,插入了以下配置数据:
$QryInsertConfig .= "('users_amount' , '0'), ";
当前服务器注册的用户数
$QryInsertConfig .= "('game_speed' , '2500'), ";
游戏速度,那些私服的什么五倍速、十倍速就是在这里改的
$QryInsertConfig .= "('fleet_speed' , '2500'), ";
飞船速度,同样 X 倍速就在这里改
$QryInsertConfig .= "('resource_multiplier' , '1'), ";
资源系数,私服也会在这个数值上动手脚
$QryInsertConfig .= "('Fleet_Cdr' , '30'), ";
$QryInsertConfig .= "('Defs_Cdr' , '30'), ";
不知道这个 cdr 是什么意思,这两个字段是不是限定指挥官的数量?
$QryInsertConfig .= "('initial_fields' , '163'), ";
这个字段的意义也比较难明白,暂且跳过。
$QryInsertConfig .= "('COOKIE_NAME' , 'XNova'), ";
$QryInsertConfig .= "('game_name' , 'XNova'), ";
$QryInsertConfig .= "('game_disable' , '1'), ";
$QryInsertConfig .= "('close_reason' , 'Le jeu est installe, mais on a pas encore mis les parametre !'), ";
这几个字段就简单了,完全可以望文生义。
$QryInsertConfig .= "('metal_basic_income' , '20'), ";
$QryInsertConfig .= "('crystal_basic_income' , '10'), ";
$QryInsertConfig .= "('deuterium_basic_income', '0'), ";
$QryInsertConfig .= "('energy_basic_income' , '0'), ";
在新建的星球(没有任何建筑时)星球的基础产量。
$QryInsertConfig .= "('BuildLabWhileRun' , '0'), ";
$QryInsertConfig .= "('LastSettedGalaxyPos' , '1'), ";
$QryInsertConfig .= "('LastSettedSystemPos' , '8'), ";
$QryInsertConfig .= "('LastSettedPlanetPos' , '3'), ";
最后设置的星系、系统和行星的位置。
$QryInsertConfig .= "('urlaubs_modus_erz' , '1'), ";
$QryInsertConfig .= "('noobprotection' , '1'), ";
$QryInsertConfig .= "('noobprotectiontime' , '5000'), ";
$QryInsertConfig .= "('noobprotectionmulti' , '5'), ";
新手保护相关的配置。
$QryInsertConfig .= "('forum_url' , '../forum' ), ";
$QryInsertConfig .= "('OverviewNewsFrame' , '1' ), ";
$QryInsertConfig .= "('OverviewNewsText' , 'Bienvenue sur le nouveau serveur XNova' ), ";
$QryInsertConfig .= "('OverviewExternChat' , '0' ), ";
$QryInsertConfig .= "('OverviewExternChatCmd' , '' ), ";
$QryInsertConfig .= "('OverviewBanner' , '0' ), ";
$QryInsertConfig .= "('OverviewClickBanner' , '' ), ";
论坛地址和概况页面的一些设置。
$QryInsertConfig .= "('debug' , '0') ";
是否运行在调试模式。
$QryInsertConfig .= ";";