QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1514|回复: 16

GameSrv的需求和接口文档的讨论稿

[复制链接]
发表于 2004-2-6 15:05:16 | 显示全部楼层 |阅读模式
下面是gamesrv的需求及接口文档的讨论稿。

已经加入邮件列表的朋友应该已经收到了这篇文档的拷贝。
文档只为抛砖引玉,贻笑大方之处在所难免,还请大家多多批评指正。

GameSrv Team                                                wesley.wang
                                                          February 2004

  GameSrv SSRS: Game Server Simple Software Requirements Specifications

Status of this Memo

   This document specifies an standards track protocol for the Internet
   community, and requests discussion and suggestions for improvements.
   Distribution of this memo is unlimited.
   This is only a draft!
   这仅仅是一份讨论稿。

Copyright Notice

   Copyright (C) GameSrv Team (2004).  All Rights Reserved.

Abstract

   本文档定义了GameSrv的通用接口,GameSrv是一个开源的通用游戏服务器,用来
   为一般的网络游戏提供基于internet互相访问的能力,以及一定的Player资源,
   使得不具有公网IP的人迅速制作和发布自己的网络游戏成为可能。

   GameSrv是由GameSrv Team开发和维护的一个项目,关于本文档或者本项目的建议
   和意见,可以发邮件到邮件列表:[email protected]

1. 介绍及背景

   游戏是开源项目的薄弱环节,因为游戏的开发通常成本较高,网络游戏更是如此。
   分析问题的关键,一是在于服务器,没有一个公开服务器的游戏往往只能依托于
   局域网进行点对点的对决,但是绝大多数的网友是不具有局域网条件的,这阻碍
   了游戏的普及及提高,二是玩家,由于大家的喜好各有不同,单个游戏很难满足
   所有玩家的需要,但是制作的游戏越多需要的成本也就越高,阻碍了开源游戏项
   目的发展。

   Gamesrv项目的成立主要是想通过制定通用的游戏Server接口来解决这些问题。如
   果大家的游戏能够基于同样的接口,那么Server资源就可以重复利用,分摊到一
   个游戏的成本可以近似于大大降低,并且有Server保留玩家信息,给所有的游戏
   共享,也可以使得游戏在设计初期就可以拥有大量的玩家,可以很好的促进开源
   游戏项目的发展。

2. 整体设计

   我们把一般的游戏分为下面的几个要素,第一是游戏本身,第二是玩家,第三是游
   戏逻辑。游戏本身应该包涵一些信息来定义这个游戏,包括游戏的名称,游戏的下
   载地址,游戏的版本号,至少需要多少玩家等等这些信息。玩家包括的有玩家的名
   字,密码等等,游戏的逻辑抽象出网络层面的关心的,则是一个一个的消息,通常
   这些消息,是一个玩家发给一个或者几个玩家,用来实现一定的游戏逻辑的。在这
   些逻辑中还有一些我们需要的关注的,是为了公平竞赛的原则需要实现的特殊的逻
   辑,比如在纸牌游戏中,发牌就属于这种特殊的逻辑,如果发牌的逻辑由任何一个
   客户端实现,那么这个客户端将知道每个人得到的是那张牌,这样的话,通过简单
   的修改源代码,就可以改造成一个超级的客户端,所以发牌的逻辑是一定要由服务
   器来实现的。

   综上所述,通用服务器关心的要素被分为以下几个部分:

   游戏的登记和注销
   玩家的注册,登入和登出
   游戏中消息的传递
   一些公用特殊逻辑的实现

   除此以外,server关注的还有其他一些属于操作和维护的要素,包括:

   怎样尽可能提供server的性能,使得响应更快,容量更高。
   怎样防止有意或者无意的有害操作对服务器造成的伤害。
   怎样提供给一个普通的游戏玩家友善的界面使得它能更容易找到自己喜欢的游戏等

3. 基本接口定义

   由于游戏中的这种数据传输对可靠性要求比较高,考虑采用TCP协议承载客户端和
   server之间的消息。消息采用二进制方式编码,定义公共的消息头,所有客户端
   和server之间的消息必须填充这个消息头,消息头不合法的消息将被无条件丢弃。
   消息体采用简单数据结构,为每一种消息定义一个消息体的数据结构。虽然这样
   可能会损失对单个消息扩充的灵活性,但是可以简化编程。不过这也就意味着对
   server的扩充将只能采取增加消息类型的方式。

   定义消息头如下:
     typedef struct
     {
        long mGameId;  //在一个游戏登记以后,server分给这个游戏的一个ID
        long mTableId; //在登记一个Table以后,server分给的这个tableID
        long mUserId;  //全局的一个玩家ID
        long mPlayId;  //这个玩家在本游戏桌中的索引
        long mDestMask; //用于处理需要转发的消息时,表明消息的目的地
        long mMsgType;  //消息类型(用枚举值定义)
        long mMsgLength; //消息体(从这个不包括这个域以后的消息长度)
     }GameMsgHeader;

   那么整个通用消息体的定义就是:
    typedef struct
    {
       GameMsgHeader header;
       char mContent[1];
    }GameMsg;

  server收到一个消息以后,判断消息头是否合法,包括gameid是否合法,table是否
  合法,table是否属于这个game等等,不合法的消息统统丢掉。

3.1 登记游戏请求(GS_REG_GAME_REQ)

   消息方向:C->S
   消息说明:无

   消息头:
        mGameId     :  全F
        mTableId    :  全F
        mUserId     :  全F
        mPlayId     :  全F
        mDestMask   :  全F
        mMsgType    :  GS_REG_GAME_REQ
        mMsgLength  :  sizeof(GameInfo)<参见附录,下同>

   消息体:
   
        GameInfo    : 包含游戏名称,版本,下载地址等。

3.2 登记游戏响应(GS_REG_GAME_RSP)

   消息方向:S->C
   消息说明:无

   消息头:
        mGameId     :  不为全F的任意值(全F表明登记失败,下同)
        mTableId    :  全F
        mUserId     :  全F
        mPlayId     :  全F
        mDestMask   :  全F
        mMsgType    :  GS_REG_GAME_RSP
        mMsgLength  :  0

   消息体:
   
        为空

3.3 登记用户请求(GS_REG_USR_REQ)

   消息方向:C->S
   消息说明:无

   消息头:
        mGameId     :  有效值
        mTableId    :  全F
        mUserId     :  全F
        mPlayId     :  全F
        mDestMask   :  全F
        mMsgType    :  GS_REG_USR_REQ
        mMsgLength  :  sizeof(PlayerInfo)

   消息体:
   
        PlayerInfo

3.4 登记用户响应(GS_REG_USR_RSP)

   消息方向:S->C
   消息说明:无

   消息头:
        mGameId     :  有效值
        mTableId    :  全F
        mUserId     :  不为全F的任意值
        mPlayId     :  全F
        mDestMask   :  全F
        mMsgType    :  GS_REG_GAME_RSP
        mMsgLength  :  0

   消息体:
   
        为空

3.5 登记游戏桌请求(GS_REG_TABLE_REQ)

   消息方向:C->S
   消息说明:无

   消息头:
        mGameId     :  有效值
        mTableId    :  全F
        mUserId     :  有效值
        mPlayId     :  全F
        mDestMask   :  全F
        mMsgType    :  GS_REG_TABLE_REQ
        mMsgLength  :  sizeof(TableInfo)

   消息体:
   
        TableInfo

3.6 登记游戏桌响应(GS_REG_TABLE_RSP)

   消息方向:S->C
   消息说明:无

   消息头:
        mGameId     :  有效值
        mTableId    :  不为全F的任意值
        mUserId     :  有效值
        mPlayId     :  全F
        mDestMask   :  全F
        mMsgType    :  GS_REG_TABLE_RSP
        mMsgLength  :  0

   消息体:
   
        为空

3.7 取得目前游戏桌列表(GS_GET_TABLE_LIST_REQ)

   消息方向:C->S
   消息说明:无

   消息头:
        mGameId     :  有效值
        mTableId    :  任意值
        mUserId     :  有效值
        mPlayId     :  全F
        mDestMask   :  全F
        mMsgType    :  GS_GET_TABLE_LIST_REQ
        mMsgLength  :  0

   消息体:
   
        为空

3.8 目前游戏桌列表(GS_GET_TABLE_LIST_RSP)

   消息方向:S->C
   消息说明:无

   消息头:
        mGameId     :  有效值
        mTableId    :  任意值
        mUserId     :  有效值
        mPlayId     :  全F
        mDestMask   :  全F
        mMsgType    :  GS_GET_TABLE_LIST_RSP
        mMsgLength  :  sizeof(TableList)

   消息体:
   
        TableList

3.9 加入游戏桌请求(GS_JOIN_TABLE_REQ)

   消息方向:C->S
   消息说明:无

   消息头:
        mGameId     :  有效值
        mTableId    :  有效值
        mUserId     :  有效值
        mPlayId     :  全F
        mDestMask   :  全F
        mMsgType    :  GS_JOIN_TABLE_REQ
        mMsgLength  :  0

   消息体:
   
        为空

3.10 加入游戏桌响应(GS_JOIN_TABLE_RSP)

   消息方向:S->C
   消息说明:无

   消息头:
        mGameId     :  有效值
        mTableId    :  有效值
        mUserId     :  有效值
        mPlayId     :  有效值
        mDestMask   :  全F
        mMsgType    :  GS_JOIN_TABLE_RSP
        mMsgLength  :  0

   消息体:
   
        为空

3.11 开始游戏 (GS_GAME_START)

   消息方向:S->C
   消息说明:加入本游戏桌的Player个数已经达到game要求的人数,可以开始游戏。

   消息头:
        mGameId     :  有效值
        mTableId    :  有效值
        mUserId     :  有效值
        mPlayId     :  有效值
        mDestMask   :  全F
        mMsgType    :  GS_GAME_START
        mMsgLength  :  sizeof(TableDetail)

   消息体:
   
        TableDetail :各个Player的具体信息

3.12 转发消息 (GS_TRANS_MSG)

   消息方向:S->C,S->C
   消息说明:客户端请求转发消息给玩家,server转发这种类型的消息。

   消息头:
        mGameId     :  有效值
        mTableId    :  有效值
        mUserId     :  有效值
        mPlayId     :  有效值
        mDestMask   :  有效值 GS_ALL_IN_TABLE、GS_ALL_OTHER_IN_TABLE
                               或者是某个PlayId
        mMsgType    :  GS_TRANS_MSG
        mMsgLength  :  不大于最大值

   消息体:
   
        特定游戏自定义结构。

3.13 其他消息

   其他消息用来实现为了游戏公平性需要server实现的请求。比如纸牌游戏中的发牌动作等。

3.14 扩展消息

   通过扩展消息类型来实现消息的扩展


4. 安全需求讨论

   应该保证可靠的经过验证的客户端才可以登陆到稳定的server。
   如何保证是需要考虑的问题

   可以开通用于调试的server。
   并且增加某种机制用于保护这种server。

5. 性能需求讨论

   暂无

6. 附录

   略

本帖子中包含更多资源

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

×
发表于 2004-2-6 16:55:09 | 显示全部楼层
学习ing
回复

使用道具 举报

发表于 2004-2-6 17:53:04 | 显示全部楼层
我也学习ing
回复

使用道具 举报

发表于 2004-2-6 23:51:01 | 显示全部楼层
我也学习ing
不过这些似乎都是数据结构的定义呀
那么整体的架构呢?现在模块、架构等还没有确定呢~~
我正在纸上画架构图,等我全设计好了就用电脑画一个发上来给大家讨论讨论~
回复

使用道具 举报

发表于 2004-2-7 13:50:32 | 显示全部楼层
邮件好像还没有收到
几个问题:
1.登记游戏消息是什么含义? 既然下面也说道了, 应该保证可靠的经过验证的客户端才可以登陆到稳定的server,那就应该不存在这个消息了,而只有服务器端的静态配置
2.我们的模块划分是否该再讨论?还是那句话: 游戏的服务不应该和接入服务放在一齐,也就是他们的消息结构也完全不必要合在一齐.
3.游戏行为应该由游戏自己定义,比方说桌子这个概念,有多少桌等等
期待sjinny, 能先给出一个框架结构
回复

使用道具 举报

 楼主| 发表于 2004-2-7 14:49:45 | 显示全部楼层
桌子的概念还是通用的,如果是一堆人玩的大游戏,可以看成只有一桌。
回复

使用道具 举报

发表于 2004-2-9 09:49:38 | 显示全部楼层
sjinny, 你的冬冬写好了么,发出来大伙儿看看阿
回复

使用道具 举报

发表于 2004-2-9 14:00:21 | 显示全部楼层
看看。
回复

使用道具 举报

发表于 2004-2-9 20:10:31 | 显示全部楼层
一个问题:
玩家的ID是在特定桌面中唯一还是在整个系统中唯一??
回复

使用道具 举报

 楼主| 发表于 2004-2-9 20:20:44 | 显示全部楼层
我觉得玩家应该有两个id,一个是系统唯一的id,一个是特定桌唯一的id。
回复

使用道具 举报

发表于 2004-2-9 20:24:34 | 显示全部楼层
哦?两个ID??这样有什么好处吗?我觉得这样没有什么好处啊~能够简化搜索?我觉得并不是啊~这样作反倒有些浪费空间啊
回复

使用道具 举报

 楼主| 发表于 2004-2-9 20:31:09 | 显示全部楼层
全局唯一的ID的好处不言而喻,桌子内部的索引可以用来控制客户端的某些游戏逻辑,比如麻将游戏的东南西北风,扑克游戏中的出牌顺序等。
回复

使用道具 举报

发表于 2004-2-9 22:32:30 | 显示全部楼层
是不是桌面和系统内都要维护一个表?提供怎样的搜索操作?
回复

使用道具 举报

发表于 2004-2-10 09:28:04 | 显示全部楼层
用户登记的时候必然会有一个序号(比方说为了在数据库中存储) 只要都用这个好就可以了 这样还可延伸到比方说多个服务器同步 用户从一个服务器“转”到另一个的情况
每个桌那个也可以称为id吧 其实应该只是个次序问题
回复

使用道具 举报

发表于 2004-2-10 12:53:12 | 显示全部楼层
全局id是肯定要的,而桌面内的id其实不是我们要关心的,因为主程序和各个游戏是相对独立的,所以我们只要把游戏参与者的数据交给具体的游戏就行了,至于要不要桌面内的局部id就由游戏设计者自己决定就好了~
回复

使用道具 举报

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

本版积分规则

GMT+8, 2024-11-9 02:00 , Processed in 0.049317 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

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