1     开发环境

Scut Lib版本:5.2.3.2

需要安装的软件

a)        IIS和消息队列(MSMQ)

b)        数据库,Sql2005以上版本

c)        VS2010开发工具(.Net Framework 4.0以上)

d)        Python2.6(ScutGame官网下载IronPython2.6.1 RC1 for .NET 4.0插件)

工具

a)        协议工具(目录Source\Tools\ContractTools)

2     代码框架

项目划分三层:实体层,组件层,业务逻辑层(脚本层);模型层主要是数据实体映射,自定义缓存结构;组件层主要负责实现中层层扩展功能;业务逻辑层主要负责实现游戏功能;

2.1     数据库创建

游戏划分成三个库:DemoConfig库(负责存储游戏配置数据) 、DemoData库(负责存储游戏玩家数据)和DemoLog库(游戏玩家日志记录数据);如图

这里只为每个库建立一张表:

2.2     项目搭建

2.2.1        创建解决方案

打开VS2010 在菜单上选择 文件 -> 新建 -> 项目;弹出“新建项目”对话窗口,在左则展开“其它项目类型”,选择“Visual Studio解决方案”,选择“.Net Framework 4.0”后,输出项目名称及位置,再点击“确定”;如图:

2.2.2     创建项目

在“资源管理器”中添加新的几个项目Model、Lang、Com、Bll、HostServer;Model项目:负责从数据库中导出表的数据实体类映射;

Lang项目:负责多语言包;

Com项目:负责中间层组件扩展处理,及中间层业务实体类;

Bll项目:负责业务逻辑处理;

HostServer项目:控制台启动程序,及脚本(Python)业务逻辑处理;

如图:

创建项目结果如下:

设置控制台程序“HostServer”属性为“.Net Framework 4.0”

设置成“Release”编译方式

2.2.3      Model项目

组件引用

项目

引用路径

Model

Lib\protobuf-net.dll

Lib\ZyGames.Framework.Common.dll

Lib\ZyGames.Framework.dll

Lib\ZyGames.Framework.Game.dll

组件详情

 

目录划分

划分配置库(ConfigModel)、玩家信息库(DataModel)、玩家日志库(LogModel)和自定义类型数据实体(Model)目录存储数据实体类; Enum目录存储自定枚举;

DbConfig

在生成实体类时,生成配置ConnectKey项中使用

public class DbConfig
{
public const string Config = "DemoConfig";
public const string Data = "DemoData";
public const string Log = "DemoLog";
public const int GlobalPeriodTime = 0;
public const int PeriodTime = 0;
public const string PersonalName = "UserId";
}
//UserId:是玩家库中表的主键字段名称; 红色部分是需要修改的

项目建立完成如图:

实体静态注入配置

用记事本打开Demo.Model.csproj文件,在结尾增加如下配置:

<Project>
... ... <UsingTask TaskName="ZyGames.Framework.Common.Build.WeavingEntityTask" AssemblyFile="bin\$(Configuration)\ZyGames.Framework.Common.dll" />
<Target Name="AfterBuild">
<WeavingEntityTask SolutionDir=".\\bin\$(Configuration)" FilePattern="Demo.Model.dll" />
</Target> ... ...
</Project>

2.2.4     Lang项目

组件引用

项目

引用路径

Lang

Lib\ZyGames.Framework.Common.dll

Lib\ZyGames.Framework.Game.Lang.dll

负责处理多语言包配置,需要实现中层提供的语言包;以下是定义类

LanguageManager

public class LanguageManager
{
private static object thisLock = new object();
private static Dictionary<LangEnum, IGameLanguage> _langTable = new Dictionary<LangEnum, IGameLanguage>();
private static LangEnum _langEnum; static LanguageManager()
{
_langEnum = (ConfigUtils.GetSetting("LanguageType", "0")).ToEnum<LangEnum>();
LanguageHelper.SetLang(_langEnum);
} public static IGameLanguage GetLang()
{
return GetLang(_langEnum);
} public static IGameLanguage GetLang(LangEnum langEnum)
{
IGameLanguage lang = null;
if (!_langTable.ContainsKey(langEnum))
{
lock (thisLock)
{
if (!_langTable.ContainsKey(langEnum))
{
switch (langEnum)
{
case LangEnum.ZH_CN:
_langTable.Add(langEnum, new GameZhLanguage());
break;
default:
throw new Exception("Language is error.");
}
}
}
}
lang = _langTable[langEnum];
return lang;
} }

IGameLanguage接口

public interface IGameLanguage : ILanguage
{
#region
/// <summary>
/// 君主帐号
/// </summary>
int SystemUserId { get; }
/// <summary>
/// 玩家名称
/// </summary>
string KingName { get; }
string Date_Yesterday { get; }
string Date_BeforeYesterday { get; }
string Date_Day { get; }
string St1002_GetRegisterPassportIDError { get; }
string St1005_NickNameOutRange { get; }
string St1005_NickNameExistKeyword { get; }
string St1005_NickNameExist { get; }
string St1006_PasswordTooLong { get;}
string St1006_ChangePasswordError { get;}
string St1006_PasswordError { get;}
string St1066_PayError { get; } #endregion
}

GameZhLanguage

class GameZhLanguage : BaseZHLanguage, IGameLanguage
{
public int SystemUserId
{
get { return 1000000; }
} public string KingName
{
get { return "系统"; }
} public string Date_Yesterday { get { return "昨天"; } }
public string Date_BeforeYesterday { get { return "前天"; } }
public string Date_Day { get { return "{0}天前"; } } public string St1002_GetRegisterPassportIDError { get { return "获取注册通行证ID失败!"; } } public string St1005_NickNameOutRange { get { return "您的昵称输入有误,请重新输入!"; } }
public string St1005_NickNameExistKeyword { get { return "您输入的昵称存在非法字符,请重新输入!"; } }
public string St1005_NickNameExist { get { return "您输入的昵称已存在,请重新输入!"; } } public string St1006_PasswordTooLong { get { return "输入错误,请输入4-12位数字或字母!"; } }
public string St1006_ChangePasswordError { get { return "修改密码失败!"; } }
public string St1006_PasswordError { get { return "密码格式错误!"; } }
public string St1066_PayError { get { return "充值失败"; } }

2.2.5   Com项目

组件引用

项目

引用路径

Com

Lib\protobuf-net.dll

Lib\ZyGames.Framework.Common.dll

Lib\ZyGames.Framework.dll

Lib\ZyGames.Framework.Game.Lang.dll

Lib\ZyGames.Framework.Game.dll

Model

Lang

划分中间件业务实体(Model),聊天组件(Chat)与排行榜(Rank)等目录,如图:

需要使用中间层的功能,请参考《中间层使用文档》

2.2.6   Bll项目

组件引用

项目

引用路径

Bll

LibNewtonsoft.Json.dll

Lib\IronPython.dll

Lib\ZyGames.Framework.Common.dll

Lib\ZyGames.Framework.dll Lib\ZyGames.Framework.Plugin.dll

Lib\ZyGames.Framework.RPC.dll

Lib\ZyGames.Framework.Game.Lang.dll

Lib\ZyGames.Framework.Game.dll

Lib\ ZyGames.Framework.Game.Contract.dll

Model

Lang

Com

功能划分

创建Action目录划分接口协议处理逻辑;主要提供中间层定义的固定协议接口,如:登录(1004)与建角(1005)及充值中间层接口

ActionIDDefine

public class ActionIDDefine
{
///<summary>
///客户端注册Socket
///</summary>
public const Int16 Cst_Action100 = 100; ///<summary>
///错误日志
///</summary>
public const Int16 Cst_Action404 = 404; ///<summary>
///注册通行证ID获取接口
///</summary>
public const Int16 Cst_Action1002 = 1002; ///<summary>
///用户注册
///</summary>
public const Int16 Cst_Action1003 = 1003; ///<summary>
///用户登录
///</summary>
public const Int16 Cst_Action1004 = 1004; ///<summary>
///创建角色
///</summary>
public const Int16 Cst_Action1005 = 1005;
}

BaseAction

public abstract class BaseAction : AuthorizeAction
{
protected BaseAction(short actionID, HttpGet httpGet)
: base(actionID, httpGet)
{
} protected override bool IgnoreActionId
{
get
{
//排除不需要登录授权的协议接口
return actionId == ActionIDDefine.Cst_Action404;
}
}
}

2.2.7   HostServer项目

组件引用

项目

引用路径

HostServer

LibNewtonsoft.Json.dll

LibNLog.dll

Lib\protobuf-net.dll

 

Lib\IronPython.dll

Lib\IronPython.Modules.dll

Lib\Microsoft.Dynamic.dll

Lib\Microsoft.Scripting.dll

 

Lib\ServiceStack.dll

Lib\ ServiceStack.Common.dll

Lib\ ServiceStack.Interfaces.dll

Lib\ ServiceStack.Redis.dll

Lib\ ServiceStack.Text.dll

 

Lib\ZyGames.Framework.Common.dll

Lib\ZyGames.Framework.dll Lib\ZyGames.Framework.Plugin.dll

Lib\ZyGames.Framework.RPC.dll

Lib\ZyGames.Framework.Game.Lang.dll

Lib\ZyGames.Framework.Game.dll

Lib\ ZyGames.Framework.Game.Contract.dll

Model

Lang

Com

Bll

功能划分

划分PyScript目录,存放Python脚本文件;层次如图:

Action目录:处理请求与响应的脚本,可以协议生成器工具中Copy部分模板;

Lib目录:Python中间层脚本,复制Scut开发包中的PythonLib目录;

Remote:应用程序之间内通讯,访问时有IP访问限制;

Route.config.xml:是请求路由配置表,格式如下:

<?xml version="1.0" encoding="utf-8" ?>
<config>
<!--Python安装类库路径-->
<lib path="D:\Python\Lib" />
<route-list>
<!--配置Action路由
action:映射的Action代码
path:指定执行的脚本路径
ignoreAuthorize:是否不需要登录授权,true:不需要登录授权
-->
<route action="404" path="Action\action404.py"/>
<route action="1009" path="Action\action1009.py"/>
</route-list>
</config>

GameHostApp

class GameHostApp : GameSocketHost
{
private static GameHostApp instance; static GameHostApp()
{
instance = new GameHostApp();
} private GameHostApp()
{
} public static GameHostApp Current
{
get { return instance; }
} protected override void OnConnectCompleted(object sender, ConnectionEventArgs e)
{
Console.WriteLine("Client:{0} connect to server.", e.Socket.RemoteEndPoint);
} protected override void OnRequested(HttpGet httpGet, IGameResponse response)
{
try
{
ActionFactory.Request(httpGet, response, null);
}
catch (Exception ex)
{
Console.WriteLine("{0}", ex.Message);
}
} protected override void OnStartAffer()
{
try
{
//时º¡À间?间?隔?更¨¹新?库a
int cacheInterval = 600;
GameEnvironment.Start(cacheInterval, () => true);
Console.WriteLine("The server is staring...");
}
catch (Exception ex)
{
TraceLog.WriteError("The server start error:{0}",ex);
}
} protected override void OnServiceStop()
{
GameEnvironment.Stop();
} }

Program

static void Main(string[] args)
{
try
{
GameHostApp.Current.Start();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
TraceLog.WriteError("HostServer error:{0}", ex);
}
finally
{
Console.WriteLine("Press any key to exit the listener!");
Console.ReadKey();
GameHostApp.Current.Stop();
}
}

宿主程序Config配置

<?xml version="1.0"?>
<configuration> <configSections>
<section name="zyGameBaseBll" type="ZyGames.Framework.Game.Configuration.ZyGameBaseBllSection,ZyGames.Framework.Game"/>
<section name="zyGameBase-GM" type="ZyGames.Framework.Game.Command.GmSection,ZyGames.Framework.Game"/>
<section name="sdkChannel" type="ZyGames.Framework.Game.Sns.Section.SdkChannelSection,ZyGames.Framework.Game"/>
</configSections>
<appSettings>
<!--必须配置
Port:监听端口
Code:产品代码
ServerId:产品游服代码
-->
<add key="Product.Code" value="1" />
<add key="Product.Name" value="" />
<add key="Product.ServerId" value="1" />
<add key="Game.Port" value="9701" /> <!--可选配置
MessageQueuePath:消息队列中创建指定的专用名称
Action.AssemblyName:Python开发不用设置, 当使用C#语言开发的Action接口必须设置
SignKey:请求签名Key
PublishType:发布版本类型,Debug:请求出错会有信息通知客户端(正式发布可删除)
EnableGM:开启可使用GM命令(正式发布可删除)
Python_IsDebug:设置python可以调试(正式发布可删除)
PythonRootPath:修改Python执行的相对路径(正式发布可删除)
-->
<add key="Game.Action.AssemblyName" value="ZyGames.Demo.Bll"/>
<add key="MessageQueuePath" value=".\private$\DemoCmdSql"></add>
<add key="Product.SignKey" value="44CAC8ED53714BF18D60C5C7B6296000"/>
<add key="PublishType" value="Debug"/>
<add key="EnableGM" value="true"/>
<add key="Python_IsDebug" value="true" />
<add key="PythonRootPath" value="..\..\PyScript" /> <!--通用组件配置开始
PayDB:充值模块功能使用的数据库配置(ConnectionString:连接串,Server:服务器,Acount:加密后的登录帐号与密码)
Snscenter:用户中心模块使用的数据库配置(ConnectionString:连接串,Server:服务器,Acount:加密后的登录帐号与密码)
注(Acount原串:"Uid=sa;Pwd=123" 密钥:BF3856AD)
-->
<add key="PayDB_ConnectionString" value="Data Source={0};Database=PayDB;{1}; Pooling=true;" />
<add key="PayDB_Server" value="." />
<add key="PayDB_Acount" value="39B30ED8D3FA3A3E5B3B4CA4F9039D55" />
<add key="Snscenter_ConnectionString" value="Data Source={0};Database=snscenter;{1}; Pooling=true;" />
<add key="Snscenter_Server" value="." />
<add key="Snscenter_Acount" value="39B30ED8D3FA3A3E5B3B4CA4F9039D55" /> </appSettings>
<connectionStrings>
<add name="DemoConfig" providerName="" connectionString="Data Source=.;Database=DemoConfig;Uid=sa;Pwd=123; Pooling=true;"/>
<add name="DemoData" providerName="" connectionString="Data Source=.;Database=Demo1Data;Uid=sa;Pwd=123; Pooling=true;"/>
<add name="DemoLog" providerName="" connectionString="Data Source=.;Database=Demo1Log;Uid=sa;Pwd=123; Pooling=true;"/>
</connectionStrings> <!--业务层自定义配置-->
<zyGameBaseBll>
<login defaultType="ZyGames.Framework.Game.Sns.Login36you,ZyGames.Framework.Game">
<retailList>
<add id="0000" type="ZyGames.Framework.Game.Sns.Login36you,ZyGames.Framework.Game" args="Pid,Pwd,DeviceID"/>
</retailList>
</login>
</zyGameBaseBll> <zyGameBase-GM>
<command>
<!--GM:cache-->
</command>
</zyGameBase-GM> <startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
</configuration>

2.3     定义协议

打开协议生成器工具,增加一个“Demo”项目方案,接着在增加协议(或从现有项目中Copy相同的接口协议),接着定义客户端提供的请求参数和服务器下发的参数(支持多行的格式,字段类型:Record与End组合);定义好客户端与服务器之前通讯的接口后,使用自动生成的服务端Python代码(客户端使用Lua脚本代码)复制到已创建的Python接口文件,如图:

开源地址
GitHub地址https://github.com/ScutGame

Scut快速开发的更多相关文章

  1. Scut游戏服务器免费开源框架--快速开发(2)

    Scut快速开发(2) Python脚本开发 1   开发环境 Scut Lib版本:5.2.3.2 需要安装的软件 a)        IIS和消息队列(MSMQ) 进入控制面板,程序和功能 b)  ...

  2. Scut游戏服务器免费开源框架--快速开发(3)

    Scut快速开发(3) 1     开发环境 Scut Lib版本:5.2.3.2 需要安装的软件 a)        IIS和消息队列(MSMQ) b)        数据库,Sql2005以上版本 ...

  3. Scut游戏服务器免费开源框架--快速开发(1)

    Scut快速开发(1) 1        开发环境 需要安装的软件 a)        VS2010开发工具(.Net Framework 4.0以上) 2        HelloWorld 2.1 ...

  4. arcpy+PyQt+py2exe快速开发桌面端ArcGIS应用程序

    前段时间有一个项目,大体是要做一个GIS数据处理工具. 一般的方法是基于ArcObjects来进行开发,因为我对ArcObjects不太熟悉,所以就思考有没有其他简单快速的方法来做. 在查看ArcGI ...

  5. 快速开发Grunt插件----压缩js模板

    前言 Grunt是一款前端构建工具,帮助我们自动化搭建前端工程.它可以实现自动对js.css.html文件的合并.压缩等一些列操作.Grunt有很多插件,每一款插件实现某个功能,你可以通过npm命名去 ...

  6. winform快速开发平台->让有限的资源创造无限的价值!

    最近一直在维护一套自己的快速开发平台. 主要应对针对C/S架构下的项目.然而对winform这快,还真没有看到过相对好的快速开发平台, 何为快速,在博客园逛了了好久, 预览了很多通用权限管理系统. 确 ...

  7. winform快速开发平台 -> 通用权限管理之动态菜单

    这几个月一直忙APP的项目,没来得及更新项目,想想该抽出时间整理一下开发思路,跟大家分享,同时也希望得到宝贵的建议. 先说一下我们的权限管理的的设计思路,首先一个企业信息化管理系统一定会用到权限管理, ...

  8. winform快速开发平台 -> 工作流组件(仿GooFlow)

    对于web方向的工作流,一直在用gooflow对于目前我的winform开发平台却没有较好的工作流组件.  针对目前的项目经验告诉我们.一个工作流控件是很必要的. 当然在winform方面的工作流第三 ...

  9. winform快速开发平台 -> 快速绑定ComboBox数据控件

    通常我们在处理编辑窗体时.往往会遇到数据绑定.例如combobox控件绑定数据字典可能是我们经常用到的.然而在我的winform快速开发平台中我是如何处理这个频繁的操作呢? 首先,我们要绑定combo ...

随机推荐

  1. cacti (不可以利用yum安装cacti的配置)

    我们如果用yum不可以安装cacti,我们则可以利用tar包来安装!!! //cacti的配置准备 [root@localhost ~]# yum install -y epel-release [r ...

  2. 【hdoj_2079】选课时间(母函数)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2079 此题采用母函数的知识求解,套用母函数模板即可: http://blog.csdn.net/ten_s ...

  3. 【bzoj1132】[POI2008]Tro 计算几何

    题目描述 平面上有N个点. 求出所有以这N个点为顶点的三角形的面积和 N<=3000 输入 第一行给出数字N,N在[3,3000] 下面N行给出N个点的坐标,其值在[0,10000] 输出 保留 ...

  4. GIT的安装及git状态的变更详解

    一.安装git环境 (2)Git安装 Centos: yum install -y git Ubuntu: apt-get install git Windows安装git bash软件 注意不要使用 ...

  5. 【剑指offer】9、斐波拉契数列

    面试题9.斐波拉契数列 题目: 输入整数n,求斐波拉契数列第n个数. 思路: 一.递归式算法: 利用f(n) = f(n-1) + f(n-2)的特性来进行递归,代码如下: 代码: long long ...

  6. python 定义二维数组

    1. myList = [([0] * n) for i in range(m)],n是列,m是行 >>> array=[([0]*3) for i in range(4)] > ...

  7. 【BZOJ 1455】 1455: 罗马游戏 (可并堆-左偏树+并查集)

    1455: 罗马游戏 Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那 ...

  8. 【BZOJ 3166】【HEOI 2013】Alo

    http://www.lydsy.com/JudgeOnline/problem.php?id=3166 这道题难点在于求能对一个次大值有贡献的区间. 设这个次大值为\(a_i\),\(a_i\)左边 ...

  9. 【贪心】Codeforces Round #436 (Div. 2) D. Make a Permutation!

    题意:给你一个长度为n的数组,每个元素都在1~n之间,要你改变最少的元素,使得它变成一个1~n的排列.在保证改动最少的基础上,要求字典序最小. 预处理cnt数组,cnt[i]代表i在原序列中出现的次数 ...

  10. 【SAM】BZOJ2882-工艺

    [题目大意] 求一个循环数列的最小表示法. [思路] 最小表示法的正解:★ SAM乱搞,和前面的POJ那道一样.然而MLE了,当作学习一下map的用法^ ^ map的使用方法(来源:☆) 一.map的 ...