ProjectDescription - ScutGame/Scut GitHub Wiki
此章节介绍如何搭建服务端项目工程
Scut的开发环境要在VS2013以上版本
-
首先打开VS2013,创建一个“类库”类型的项目;
-
选择Scut最新的Lib类库,将Lib目录和Console目录下的所有文件复制到新创建的类库项目中;
-
添加dll引用,切换到VS解决方案管理器中,将所有dll引用到项目中;
-
在VS解决方案管理器中,选择项目点击“显示所有文件”,将Script目录与GameServer.exe.config和Nlog.config文件包含到项目中;
-
调试项目,右击项目选“属性”,打开“调试”栏选择“启动外部程序”设置为“GameServer.exe”路径,并将工作目录设置成与GameSession.exe文件同级目录(此设置会影响Log的输入目录);
下面是Scut服务端项目的目录结构:
- 第一部分: Script脚本目录
包括:Model、CsScript、PyScript和LuaScript子级目录;不能有含有其它自定义的目录或文件,自定义的目录或文件是不会被监听的。
-
Model目录: 所有脚本统一使用的数据实体类目录,它是单独编译的子项目;此目录下的脚本不能调试,因此不要在脚本内写业务处理代码;
-
CsScript目录: C#脚本的业务逻辑目录,C#开发者使用,包括以下子目录和文件:
Action子目录: 与客户端对接的通讯协议处理接口类,包括:处理请求包,响应封包等方法;
Locale子目录: 本地化的多语言化处理类,如:提示语;
MainClass.cs文件: C#脚本启动入口,包括:程序启动,程序停止,接收请求,打开连接,关闭连接和心跳包接收等方法;
扩展子目录: 可以根据需要在CsScript目录下划分子目录,如以功能划分:Chat(聊天)、Plot(副本)、Task(任务)等。
-
PyScript目录: Python脚本的业务逻辑目录,Python开发者使用,包括以下子目录和文件:
Action子目录: 与客户端对接的通讯协议处理接口类,包括:处理请求包,响应封包等方法;
Lib子目录: Python脚本开发者的类库
-
LuaScript目录: Lua脚本的业务逻辑目录,Lua开发者使用;
- 第二部分: Scut类库与第三方类库
包括所有的dll文件,ZyGames名称开头的是Scut的类库,其它的是第三方类库。
- 第三部分: GameServer宿主程序与ScutSMS工具
包括以下文件:
-
GameServer.exe文件: 以Console控制台方式运行的宿主程序;
-
GameServer.exe.config文件: 宿主程序的配置文件;
-
Nlog.Config文件: 第三方错误跟踪Log日志类库的配置文件,包括:输出的目录位置,错误级别输出控制和Log输出的类型控制(输出的类型:文件,控制台,Trace和Azure第三方存日志储等);
-
ScutSMS.exe文件: Scut提供的工具,可以方便配置游戏的参数和Redis数据的操作;
-
NLog.config文件: 游戏服日志文件配置,使用第三方的Nlog类库,结点"logDirectory" 是配置日志文件输出的路径,其它结点按默认配置。
<variable name="logDirectory" value="d:\NLog\XXgame"/>
-
GameServer.exe.config文件: 游戏服的主要配置,包括:数据库连接配置,Redis连接配置和其它游戏环境配置等;可以打开当前目录下的ScutSMS工具进行配置。
<?xml version="1.0"?> <configuration> <!--基本参数配置,其它详细参数通过ScutSMS工具查看参数--> <appSettings> <add key="Redis.Host" value="127.0.0.1:6379"/> <!--Redis服务的连接串,格式:password@host:port --> <add key="Script_IsDebug" value="True"/> <!--开启脚本调试模式--> </appSettings> <!--数据库连接串配置--> <connectionStrings> <!-- @name: 连接串的标识Key,是Entity类配置的EntityTable属性的ConnKey参数值,两者要对应上 @providerName: 连接的数据库驱动类型;SqlDataProvider是SQL数据库的连接,MySqlDataProvider是MySql数据库的连接 @connectionString: 数据库连接串,与SQL或MySql数据库的连接串相同 --> <add name="ConnData" providerName="SqlDataProvider" connectionString="Data Source={服务器地址};Database={数据库名};Uid={登录帐号};Pwd={登录密码};"/> </connectionStrings> </configuration>
Redis配置注意:
- 一个Redis库只能被一个GameServer绑定,防止串库数据回档,否则启动时会有错误,这在新版本中有增加限制了;
- 绑定的规则:机器名+GameServer路径,如果移动了项目位置,可以通过Redis-clie客户端连接到Redis服务器并直接删除"__redisinfo"的键;
-
创建项目时为什么选择的是类库类型项目,而不是Console类型项目
由于Scut已经提供了直接可运行的Consele(GameServer.exe)项目,开发者开发的脚本可以直接宿主在GameServer项目中运行。
-
Model与CsScript之间的类交叉引用运行出错问题
Scut运行时会分别为Model与CsScript两个dll在temp目录下(通过查看属性可以区分哪个是Model的dll),它们之间是有依赖层级关系的,CsScript的程序集引用Model的程序集,如果Model中有类使用了CsScript的类,就会发生编译出错,在Log的Exception目录下会有编译出错详细信息。
-
使用类库类型的项目如何调试框架内的代码
.net项目调试是需要
*.pdb
类型的文件才可以调试,在Scut提供的Lib库中如果没有提供此类文件,需要自己编译源码生成*.dll
与*.pdb
文件, 编译源码步骤如下:- 先Git下载Scut的源码,并打开源码中的Framework项目,使用Debug的编译方式生成代码;
- 接着在Framework目录
\bin\Debug\
的*.dll
与*.pdb
所有文件Copy到你自己的项目目录下(如果使用Release编译,是在bin\Release目录); - 同上,打开源码中的Middleware项目,编译后,Copy GameServer\bin\debug\目录下的
*.dll
与`*.pdb和GameServer.exe; - 接下来,在脚本类中设置断点,VS项目中按F5,启动调试,如果断点显示的是实心红点说明断点设置成功,否则失败,检查以上步骤中是否遗漏;
-
创建项目默认是以脚本源码方式运行,如果想直接使用编译好的dll如何运行
- Scut运行时,对Model会注入属性修改事件,在修改属性时才会保存数据,因此需要将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="{项目程序集的名称}.dll" /> </Target> </Project>
配置好重新编译成功后,使用反射工具(ILSpy)打开生成的dll,可以看到属性中的代码有
BindAndChangeProperty
方法,它会触发保存的事件:[ProtoMember(8), EntityField] public ushort RoleLv { [CompilerGenerated] get { return this.<RoleLv>k__BackingField; } [CompilerGenerated] set { if (!object.Equals(this.<RoleLv>k__BackingField, value)) { this.<RoleLv>k__BackingField = value; base.BindAndChangeProperty(this.<RoleLv>k__BackingField, "RoleLv"); } } }
- 接着需要在GameServer.exe.config文件中配置
ScriptAsmReferences
的键值,将你的项目dll配置进去,多个以';'分隔 - CsScript目录上需要有MainClass文件,Model与CsScript目录下就不需要放其它脚本文件了