SDL中文论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 6482|回复: 6
打印 上一主题 下一主题

[讨论] 数据服务器细节

[复制链接]

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
跳转到指定楼层
楼主
发表于 2020-11-29 11:50:22 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
注:为叙述方便,以下把数据服器包称为王国插件。

二楼:安装
三楼:内部细节
四楼:命令集
五楼:几个问题
回复

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
沙发
 楼主| 发表于 2020-11-29 11:51:04 | 只看该作者

安装

  • 下载王国插件安装包(140731)(下载),解压缩。
  • 把王国插件安装包上传到论坛源码的“plugin”目录下。让论坛源码看去是以下结构。
  • 以创建者账号登录后台,“应用”。
  • ——如果已安装过旧版本插件,选择“更新”。
  • ——如果是全新安装,选择“安装插件”:“王国战争 14.7.31”;并启用插件。注:全新安装时一定会删除表格,然后重新创建新的;为避免误删,不要随便全新安装。
  • 安装结束。进入论坛首页,安装成功的的话就可在导航栏看到“王国战争”项,进入后台可更改导航栏顺序。对于想把入口放在右上角状态栏,参考五楼的“把插件入口放在用户状态栏”。


回复 支持 反对

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
板凳
 楼主| 发表于 2020-11-29 11:51:54 | 只看该作者

内部细节

表格
王国插件会建立以下表格
名称描述
<pre_>kingdom_hero武将数值。五维、特技、战法、兵科适性等
<pre_>kingdom_save玩家存档。存档编号(sid)、上传人编号(uid)、存档名(name)、上传时间(uploadtime)、版本(version)、批注(remark)

注:
  • 所有表格都是建立在discuz数据库。所以当玩家是把discuz和ucenter分装在两个数据库时,这些表是位在discuz数据库。<pre_>是在安装discuz时的discuz数据库中表前缀。
  • 一旦存在,在论坛后台“数据库”可以看到这些表格。


会涉及到以下表格
名称所属数据库描述
<pre_>common_syscachediscuz做为插件,它一定得把一些信息写入这个表格,像三种翻译install.php为按装插件会修改它
<pre_>common_memberdiscuz要由它验证“uid”指定的账号是否有效只读
<uc_>membersucenter要由它验证“账号/密码”对指定的账号是否有效只读

管理插件私有表格
  • 建立
    安装步骤一中运行install.php时建立所有表格。
  • 插入新记录
    • pre_kingdom_hero:“王国战争”插件检测到当前进入的uid不在该表格,会向它插入一条新记录。
    • pre_kingdom_save:游戏玩家向服务器上传了一个存档,会向它插入一条新记录。
  • 修改
    游戏端会上传武将数据,从而修改pre_kingdom_hero。
  • 备份
    备份discuz数据库会连着备份这些表格
  • 删除
    暂时未做删表格部分,到时会有的。

文件
王国插件会涉及到两种文件:源码和数据。
源码文件
源码文件集中存放在<bbs>/source/plugin/kingdom目录。它在安装时被复制向该目录。在不断运行过程中,这些个文件不会有变动。

数据文件
插件在运行时会产生数据,数据集中放在<bbs>/data/plugindata/kingdom目录。

  • avatar子目录存放图像。像半身像、头像。王国插件存放图像和ucenter一样根据uid进行分类,目录结构和ucenter保持一致。
  • save子目录存放存档。
回复 支持 反对

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
地板
 楼主| 发表于 2020-11-29 11:52:24 | 只看该作者

命令集

  • 客户端有两种:浏览器(IE等)和王国战争游戏。
  • 客户端访问服务器都是通过HTTP协议。即使是要操作数据库的命令,客户端也是把命令发去服务器,服务器根据命令操作数据库。操作结果也是由数据库先交给服务器,服务器再把结果传给客户端。
  • 服务器和客户端接口只一个文件:kingdom.inc.php,它处理/分发所有命令。但在调用上kingdom.inc.php是被论坛根下的plugin.php调起的,外面访问指向的该是plugin.php,而访问的是kingdom插件,plugin.php应是plugin.php?id=kingdom:kingdom。
  • 客户端请求时可使用GET或POST,请求头部分必须存在“Host”、“Connection”字段。
    字段存在描述
    Host必须服务器域名,像www.freeors.com
    Connection必须Keep-Alive
    Content-Length有内容时必须内容数据字节数
  • 命令数据分散在请求的两个地方,1)访问URL,用于存放命令id、此次访问的用户编号或账号/密码对;2)HTTP协议的内容区,按命令不同有不同数据。
  • 只要是字符串,进入或出来插件的一律是UTF-8格式。像账号、密码、存档名必须UTF-8。

命令
标识功能使用场合参数(URL)参数(内容)
index显示服务器主页在论坛访问属于游戏的空间plugin.php?id=kingdom:kingdom&do=index&uid=2,可省略do=index 不需要
synchero同步新武将数据游戏端用它来下载两种头像plugin.php?id=kingdom:kingdom&do=synchero&username=1&password=2leadership=98&charm=72,leadership等是pre_kingdom_hero表格中的字段名
uploadsave上传存档游戏端用它来上传一个存档plugin.php?id=kingdom:kingdom&do=uploadsave&username=1&password=28字节版本号、8字节存档名字节数,存档名,存档数据
downloadsave下载存档游戏端用它来下载一个存档plugin.php?id=kingdom:kingdom&do=downloadsave&username=1&password=28字节存档名字节数、存档名,存档数据
listsave特定于账号的存档列表游戏端用它来知道可下载哪些存档plugin.php?id=kingdom:kingdom&do=listsave&username=1&password=2存档编号,上传人账号,存档名,上传时间,存档版本&(以同样格式表示下一存档)


回复 支持 反对

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
5#
 楼主| 发表于 2020-11-29 11:52:47 | 只看该作者

几个问题

一、插件、ucenter中图像
discuz自带的是每账号三图像(small、middle、big),王国插件是每账号两图像(small、middle),不过要是插件由middle复制出big,理论上说由插件就可以替掉discuz的自带图像。理论上是如此,实际却得考虑几个问题。
  • 插件要求的图像是png,discuz要求的图像扩展名是jpg,而且这个jpg是被硬写进代码。
  • 插件middle图像要求扣掉背景,一些用户可能希望论坛图像有背景。
  • 插件代码是钩注在discuz,无法影响ucenter。

当前实现方式是插件给提供个选项,由用户选择是使用王国战争设定形象还是discuz自带形象。在图像存储上,插件、ucenter中图像互不干扰,但它们在保存图像时有着一致的目录结构。针对9位的uid组织成三级目录,最高三位是一级目录,次二位是二级目录,次次二位是三级目录。举个例子,对uid=13154,它的目录结构是“avatar/000/01/31/54_avatar_small.png”。

二、存档尺寸
游戏支持录像回放,导致存档中回合数越多则存档会越大,要是不限回合那存档大小就没尽头。玩群2这种大地图剧本,玩个200回合存档就可能超过3M。这种大小对网络传输来说是有点大了,于是想过先gzip压缩再上传。要gzip另一目的是要降低存档对服务器硬盘要求,但当前实现的没进行gzip压缩。
  • 将来的网页端应该能显示存档更多信息,像玩到多少回合了,地图尺寸是多少等等,而这些是没法作为玩家在上传存档时的附加信息,只能靠服务器去解析存档中数据。要解析数据,被gzip的必须要先被ungzip,而未gzip自然可省掉这步骤。
  • 游戏会严格要求存档进行版本匹配,即一旦游戏发布了新版本,旧版本存档其实就已没意义。为此服务器可根据pre_kingdom_save表去删除旧版本存档,这样一来服务器中的存档数量其实是可以被控制在一定数目的。

当前实现是未压缩存档直接进行网络传输,服务器上存的也是未压缩过的。这种方式是是否可行,让运行一段时间看实际效果。

三、标准discuz插件
王国插件已符合discuz插件标准,不论是安装还是代码中使用,都要以着标准插件方式。像运行时,php代码/模板会遇到翻译语言问题,安装王国插件时会把包中语言内容写入pre_common_syscache表,php代码/模板尽可按标准去使用插件的语言翻译机制,而且应该按标准去做。

以王国插件为例简述下discuz插件
  • 插件安装分两个步骤:安装、启用。
  • 安装主要任务是从插件提供的discuz_plugin_kingdom.xml读取信息,然后写入pre_common_plugin表。pre_common_plugin存储插件概要信息,像插件名称(name)、标识(pluginid)、支持模块(modules),安装完后会把当中的是否启用字段(available)置为0。如果插件存在install.php的话,这php也会在安装过程被调用。
  • 启用。一旦启用,pre_common_plugin中的available字段将被置为1。对启用过程来说,置下这字段只是个小工作,他的大动作是要追加pre_common_syscache表,用追加,是因为syscache表中字段已经有内容,此时只是在相关字段值中增加新增插件内容。举个例子,setting字段存储着插件支持何样钩子,在启用王国插件前,表中的setting字段已经存储了论坛已安装插件支持的钩子,此次启动王国插件是把该插件支持钩子追加进setting字段。pre_common_syscache正如表名所看到的,它存储了系统缓存信息,而缓存的一部分就是插件信息。比如setting字段是插件支持的钩子,这个字段是通过解析pre_common_plugin中的modules字段得到的,如果每次运行都去解析pre_common_plugin中的modules,然后得到钩子,那太费时间。除去setting,像pluginlanguage_template字段缓存着编写模板时插件支持的翻译文本。在php程序中,pre_common_plugin中字段在discuz->init时被读进$_G,像$_G['setting']对应setting字段。
  • 要理解安装、启动,重点要理解1)modules是如何被形成setting字段;2)如何形成语言包相关字段(pluginlanguage_template等)。对setting,参考get_cachedata_setting_plugin()(<bbs>/source/function/cache/cache_setting.php),为加快理解可嵌入以下代码,然后zend studio进入该函数进行调试。
    1. @include_once libfile('cache/setting', 'function');
    2. list($data['plugins'], $data['pluginlinks'], $data['hookscript'], $data['hookscriptmobile'], $data['threadplugins'], $data['specialicon']) = get_cachedata_setting_plugin();
    复制代码
    对各语言字段,则可使用以下代码。
    1. require_once libfile('function/plugin');
    2. require_once libfile('function/admincp');
    3. $file = DISCUZ_ROOT.'./source/plugin/discuz_plugin_kingdom.xml';
    4. $importtxt = @implode('', file($file));
    5. $pluginarray = getimportdata('Discuz! Plugin', 0, 1);
    6. if ($pluginarray) {
    7.         updatepluginlanguage($pluginarray);
    8. }
    复制代码
    模板翻译总的来说是两条原则,1)对于不属于插件的key,一定会加载source/language/lang_template.php;2)对于属于插件的key,一律从discuz_plugin_kingdom.xml中的template中找(对应pre_common_syscache表中“cname”字段等于“pluginlanguage_template”中的data)。
  • 安装过程需要插件提供两个名称有点特珠的文件:discuz_plugin_kingdom.xml、kingdom.class.php。插件支持何类型钩子来自discuz_plugin_kingdom.xml中module节,但支持的进一步信息则要来自kingdom.class.php,discuz启用时要根据后者提供的类名/类成员函数来确认该插件“最后”是否真存在钩子函数。举个例子,王国插件提供了截取显示形象的钩子函数,要discuz得到这个信息是根据两个地方:1)discuz_plugin_kingdom.xml写有个type=11的module,2)kingdom.class.php存在个类名是plugin_kingdom的类,并且实现了avatar成员函数。这两部分如何协同工作参考get_cachedata_setting_plugin()。

四、插件中的php如何调用discuz自带的css

discuz代码中样式表文件是放在<bbs>/data/cache,而且要使用这些样式表,如果不想修改discuz头模板文件(具体是<bbs>/template/default/common/header_common.htm),那你的php必须位在和data同级的那个目录,即<bbs>根下!原因:header_common.htm形成样式表语句是“<!--{csstemplate}-->”,模板机制解析这语句是调用“this->loadcsstemplate”,this指的是类“class template”,即调用template的成员函数loadccstemplate,而loadccstemplate在指定css文件时使用了固定的相对路径。
  1. function loadcsstemplate(...) {
  2.         $scriptcss = '<link rel="stylesheet" type="text/css" href="data/cache/style_{STYLEID}_common.css?{VERHASH}" />';
  3.         ......
  4. }
复制代码
为让非根下php可调用这些css,修改以上 “href”值。
  1. function loadcsstemplate(...) {
  2.         $scriptcss = '<link rel="stylesheet" type="text/css" href="{$_G[setting][csspath]}data/cache/style_{STYLEID}_common.css?{VERHASH}" />';
  3.         ......
  4. }
复制代码
对于非根下的php应该给$_G[setting][csspath]赋非空值,而这个值极可能就是类似“../../../”。

插件目录不可能是根目录,而又不想修改discuz代码,discuz解决方案:插件php只是个子php,它的头统一是根下的plugin.php。由于plugin.php位在根下,由它启动的一系列过程就可使用discuz自带的css,这自然包括了插件目录中的那些php。

五、把插件入口放在用户状态栏
王国插件安装后,插件入口是放在导航栏,若要在右上角状态栏增加入口,可执行以下步骤。
  • 打开<bbs>/source/plugin/kingdom/kingdom.class.php,去掉对成员函数global_usernav_extra2的注释。保存。
  • 如果不想入口出现在导航栏,打开<bbs>/source/plugin/kingdom/discuz_plugin_kingdom.xml,删掉type=1的那个module,并把后面module的id值减1。保存。
  • 重新安装王国插件。

回复 支持 反对

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
6#
 楼主| 发表于 2020-11-29 11:53:03 | 只看该作者
程序内向discuz注册账号
按照是否调用on_register函数,注册分调用discuz内置的on_register和自写简单的on_reister。
方式一:调用discuz内置的on_register
  • 优点:兼容性好。
  • 缺点:1)当是新注册时,会导致receive_http_buf收到0数据,导致程序误断是“客户端断开链接”(跟踪php代码,查下应该是setloginstatus导致了这个0);2)不方便判断注册结果。

方式二:自写on_register(当前在用
  • 优点:可以方便判断注册结果。
  • 缺点:对discuz版本的兼容性。

回复 支持 反对

使用道具 举报

149

主题

331

帖子

2445

积分

版主

Rank: 7Rank: 7Rank: 7

积分
2445
7#
 楼主| 发表于 2020-11-29 11:53:16 | 只看该作者
从13.11.28升级上来的话,pre_kingdom_pass表的coin、score、type、hash字段类型改为无符号型。
  1. coin tinyint(3) unsigned NOT...               
  2. score tinyint(3) unsigned NOT...               
  3. type tinyint(1) unsigned NOT...
  4. hash mediumint(8) unsigned NOT...
复制代码


何时删除pre_kingdom_siege中的过时记录?
有玩家执行“查看通关记录”(listsiege)时。不管是谁,它就会删除所有玩家30天前的记录。

何时删除pre_kingdom_pass中的过时记录?
有玩家执行“查看过关记录”(listpass)时。不管是谁,它就会删除所有玩家30天前的记录。

何时删除pre_kingdom_board中的无效过关记录?
pre_kingdom_board有一部分是过关排名,一旦它对应的过关记录被删除,它就变得无效了。

有玩家执行“查看过关排名”(listboard:pass)时。不管是谁,它就会删除排名榜中无效记录。

:上传过关记录(uploadpass)时不会删除无效记录。过关记录插入排名榜过程不会涉及到相关具体记录,它只是根据pre_kingdom_board中的积分值就可计算了,出现无效时不立即删除的确可能会造成有些本该进到排名中的不能立即进入,但希望会有玩家立即“查看过关排名”,进而删除无效记录,保证排名榜的正确性。
回复 支持 反对

使用道具 举报

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

本版积分规则

Archiver|手机版|小黑屋|丽谷软件|libsdl.cn

GMT+8, 2025-5-1 23:20 , Processed in 0.075364 second(s), 22 queries .

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

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