ProjectDescription

ScutGame edited this page Jul 20, 2015 · 16 revisions

此章节介绍如何搭建服务端项目工程

新建立项目

Scut的开发环境要在VS2013以上版本

  1. 首先打开VS2013,创建一个“类库”类型的项目;

    Project add

  2. 选择Scut最新的Lib类库,将Lib目录和Console目录下的所有文件复制到新创建的类库项目中;

  3. 添加dll引用,切换到VS解决方案管理器中,将所有dll引用到项目中;

  4. 在VS解决方案管理器中,选择项目点击“显示所有文件”,将Script目录与GameServer.exe.config和Nlog.config文件包含到项目中;

  5. 调试项目,右击项目选“属性”,打开“调试”栏选择“启动外部程序”设置为“GameServer.exe”路径,并将工作目录设置成与GameSession.exe文件同级目录(此设置会影响Log的输入目录);

    Project property

下面是Scut服务端项目的目录结构:

ScutProject

理解目录结构

  1. 第一部分: 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开发者使用;

  1. 第二部分: Scut类库与第三方类库

包括所有的dll文件,ZyGames名称开头的是Scut的类库,其它的是第三方类库。

  1. 第三部分: GameServer宿主程序与ScutSMS工具

包括以下文件:

  • GameServer.exe文件: 以Console控制台方式运行的宿主程序;

  • GameServer.exe.config文件: 宿主程序的配置文件;

  • Nlog.Config文件: 第三方错误跟踪Log日志类库的配置文件,包括:输出的目录位置,错误级别输出控制和Log输出的类型控制(输出的类型:文件,控制台,Trace和Azure第三方存日志储等);

  • ScutSMS.exe文件: Scut提供的工具,可以方便配置游戏的参数和Redis数据的操作;

Config配置文件

  1. NLog.config文件: 游戏服日志文件配置,使用第三方的Nlog类库,结点"logDirectory" 是配置日志文件输出的路径,其它结点按默认配置。

    <variablename="logDirectory"value="d:\NLog\XXgame"/>
    
  2. GameServer.exe.config文件: 游戏服的主要配置,包括:数据库连接配置,Redis连接配置和其它游戏环境配置等;可以打开当前目录下的ScutSMS工具进行配置。

    <?xml version="1.0"?>
    <configuration> <!--基本参数配置,其它详细参数通过ScutSMS工具查看参数-->
    <appSettings>
    <addkey="Redis.Host"value="127.0.0.1:6379"/> <!--Redis服务的连接串,格式:password@host:port -->
    <addkey="Script_IsDebug"value="True"/> <!--开启脚本调试模式-->
    </appSettings>
    <!--数据库连接串配置-->
    <connectionStrings>
    <!-- @name: 连接串的标识Key,是Entity类配置的EntityTable属性的ConnKey参数值,两者要对应上 @providerName: 连接的数据库驱动类型;SqlDataProvider是SQL数据库的连接,MySqlDataProvider是MySql数据库的连接 @connectionString: 数据库连接串,与SQL或MySql数据库的连接串相同-->
    <addname="ConnData"providerName="SqlDataProvider"connectionString="Data Source={服务器地址};Database={数据库名};Uid={登录帐号};Pwd={登录密码};"/>
    </connectionStrings>
    </configuration>

Redis配置注意:

  • 一个Redis库只能被一个GameServer绑定,防止串库数据回档,否则启动时会有错误,这在新版本中有增加限制了;
  • 绑定的规则:机器名+GameServer路径,如果移动了项目位置,可以通过Redis-clie客户端连接到Redis服务器并直接删除"__redisinfo"的键;

开发者疑问

  1. 创建项目时为什么选择的是类库类型项目,而不是Console类型项目

    由于Scut已经提供了直接可运行的Consele(GameServer.exe)项目,开发者开发的脚本可以直接宿主在GameServer项目中运行。

  2. Model与CsScript之间的类交叉引用运行出错问题

    Scut运行时会分别为Model与CsScript两个dll在temp目录下(通过查看属性可以区分哪个是Model的dll),它们之间是有依赖层级关系的,CsScript的程序集引用Model的程序集,如果Model中有类使用了CsScript的类,就会发生编译出错,在Log的Exception目录下会有编译出错详细信息。

  3. 使用类库类型的项目如何调试框架内的代码

    .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,启动调试,如果断点显示的是实心红点说明断点设置成功,否则失败,检查以上步骤中是否遗漏;
  4. 创建项目默认是以脚本源码方式运行,如果想直接使用编译好的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目录下就不需要放其它脚本文件了

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

ProjectDescription

ScutGame edited this page Jul 20, 2015 · 16 revisions

此章节介绍如何搭建服务端项目工程

新建立项目

Scut的开发环境要在VS2013以上版本

  1. 首先打开VS2013,创建一个“类库”类型的项目;

    Project add

  2. 选择Scut最新的Lib类库,将Lib目录和Console目录下的所有文件复制到新创建的类库项目中;

  3. 添加dll引用,切换到VS解决方案管理器中,将所有dll引用到项目中;

  4. 在VS解决方案管理器中,选择项目点击“显示所有文件”,将Script目录与GameServer.exe.config和Nlog.config文件包含到项目中;

  5. 调试项目,右击项目选“属性”,打开“调试”栏选择“启动外部程序”设置为“GameServer.exe”路径,并将工作目录设置成与GameSession.exe文件同级目录(此设置会影响Log的输入目录);

    Project property

下面是Scut服务端项目的目录结构:

ScutProject

理解目录结构

  1. 第一部分: 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开发者使用;

  1. 第二部分: Scut类库与第三方类库

包括所有的dll文件,ZyGames名称开头的是Scut的类库,其它的是第三方类库。

  1. 第三部分: GameServer宿主程序与ScutSMS工具

包括以下文件:

  • GameServer.exe文件: 以Console控制台方式运行的宿主程序;

  • GameServer.exe.config文件: 宿主程序的配置文件;

  • Nlog.Config文件: 第三方错误跟踪Log日志类库的配置文件,包括:输出的目录位置,错误级别输出控制和Log输出的类型控制(输出的类型:文件,控制台,Trace和Azure第三方存日志储等);

  • ScutSMS.exe文件: Scut提供的工具,可以方便配置游戏的参数和Redis数据的操作;

Config配置文件

  1. NLog.config文件: 游戏服日志文件配置,使用第三方的Nlog类库,结点"logDirectory" 是配置日志文件输出的路径,其它结点按默认配置。

    <variablename="logDirectory"value="d:\NLog\XXgame"/>
    
  2. GameServer.exe.config文件: 游戏服的主要配置,包括:数据库连接配置,Redis连接配置和其它游戏环境配置等;可以打开当前目录下的ScutSMS工具进行配置。

    <?xml version="1.0"?>
    <configuration> <!--基本参数配置,其它详细参数通过ScutSMS工具查看参数-->
    <appSettings>
    <addkey="Redis.Host"value="127.0.0.1:6379"/> <!--Redis服务的连接串,格式:password@host:port -->
    <addkey="Script_IsDebug"value="True"/> <!--开启脚本调试模式-->
    </appSettings>
    <!--数据库连接串配置-->
    <connectionStrings>
    <!-- @name: 连接串的标识Key,是Entity类配置的EntityTable属性的ConnKey参数值,两者要对应上 @providerName: 连接的数据库驱动类型;SqlDataProvider是SQL数据库的连接,MySqlDataProvider是MySql数据库的连接 @connectionString: 数据库连接串,与SQL或MySql数据库的连接串相同-->
    <addname="ConnData"providerName="SqlDataProvider"connectionString="Data Source={服务器地址};Database={数据库名};Uid={登录帐号};Pwd={登录密码};"/>
    </connectionStrings>
    </configuration>

Redis配置注意:

  • 一个Redis库只能被一个GameServer绑定,防止串库数据回档,否则启动时会有错误,这在新版本中有增加限制了;
  • 绑定的规则:机器名+GameServer路径,如果移动了项目位置,可以通过Redis-clie客户端连接到Redis服务器并直接删除"__redisinfo"的键;

开发者疑问

  1. 创建项目时为什么选择的是类库类型项目,而不是Console类型项目

    由于Scut已经提供了直接可运行的Consele(GameServer.exe)项目,开发者开发的脚本可以直接宿主在GameServer项目中运行。

  2. Model与CsScript之间的类交叉引用运行出错问题

    Scut运行时会分别为Model与CsScript两个dll在temp目录下(通过查看属性可以区分哪个是Model的dll),它们之间是有依赖层级关系的,CsScript的程序集引用Model的程序集,如果Model中有类使用了CsScript的类,就会发生编译出错,在Log的Exception目录下会有编译出错详细信息。

  3. 使用类库类型的项目如何调试框架内的代码

    .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,启动调试,如果断点显示的是实心红点说明断点设置成功,否则失败,检查以上步骤中是否遗漏;
  4. 创建项目默认是以脚本源码方式运行,如果想直接使用编译好的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目录下就不需要放其它脚本文件了

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ProjectDescription

ScutGame edited this page Jul 20, 2015 · 16 revisions

此章节介绍如何搭建服务端项目工程

新建立项目

Scut的开发环境要在VS2013以上版本

  1. 首先打开VS2013,创建一个“类库”类型的项目;

    Project add

  2. 选择Scut最新的Lib类库,将Lib目录和Console目录下的所有文件复制到新创建的类库项目中;

  3. 添加dll引用,切换到VS解决方案管理器中,将所有dll引用到项目中;

  4. 在VS解决方案管理器中,选择项目点击“显示所有文件”,将Script目录与GameServer.exe.config和Nlog.config文件包含到项目中;

  5. 调试项目,右击项目选“属性”,打开“调试”栏选择“启动外部程序”设置为“GameServer.exe”路径,并将工作目录设置成与GameSession.exe文件同级目录(此设置会影响Log的输入目录);

    Project property

下面是Scut服务端项目的目录结构:

ScutProject

理解目录结构

  1. 第一部分: 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开发者使用;

  1. 第二部分: Scut类库与第三方类库

包括所有的dll文件,ZyGames名称开头的是Scut的类库,其它的是第三方类库。

  1. 第三部分: GameServer宿主程序与ScutSMS工具

包括以下文件:

  • GameServer.exe文件: 以Console控制台方式运行的宿主程序;

  • GameServer.exe.config文件: 宿主程序的配置文件;

  • Nlog.Config文件: 第三方错误跟踪Log日志类库的配置文件,包括:输出的目录位置,错误级别输出控制和Log输出的类型控制(输出的类型:文件,控制台,Trace和Azure第三方存日志储等);

  • ScutSMS.exe文件: Scut提供的工具,可以方便配置游戏的参数和Redis数据的操作;

Config配置文件

  1. NLog.config文件: 游戏服日志文件配置,使用第三方的Nlog类库,结点"logDirectory" 是配置日志文件输出的路径,其它结点按默认配置。

    <variablename="logDirectory"value="d:\NLog\XXgame"/>
    
  2. GameServer.exe.config文件: 游戏服的主要配置,包括:数据库连接配置,Redis连接配置和其它游戏环境配置等;可以打开当前目录下的ScutSMS工具进行配置。

    <?xml version="1.0"?>
    <configuration> <!--基本参数配置,其它详细参数通过ScutSMS工具查看参数-->
    <appSettings>
    <addkey="Redis.Host"value="127.0.0.1:6379"/> <!--Redis服务的连接串,格式:password@host:port -->
    <addkey="Script_IsDebug"value="True"/> <!--开启脚本调试模式-->
    </appSettings>
    <!--数据库连接串配置-->
    <connectionStrings>
    <!-- @name: 连接串的标识Key,是Entity类配置的EntityTable属性的ConnKey参数值,两者要对应上 @providerName: 连接的数据库驱动类型;SqlDataProvider是SQL数据库的连接,MySqlDataProvider是MySql数据库的连接 @connectionString: 数据库连接串,与SQL或MySql数据库的连接串相同-->
    <addname="ConnData"providerName="SqlDataProvider"connectionString="Data Source={服务器地址};Database={数据库名};Uid={登录帐号};Pwd={登录密码};"/>
    </connectionStrings>
    </configuration>

Redis配置注意:

  • 一个Redis库只能被一个GameServer绑定,防止串库数据回档,否则启动时会有错误,这在新版本中有增加限制了;
  • 绑定的规则:机器名+GameServer路径,如果移动了项目位置,可以通过Redis-clie客户端连接到Redis服务器并直接删除"__redisinfo"的键;

开发者疑问

  1. 创建项目时为什么选择的是类库类型项目,而不是Console类型项目

    由于Scut已经提供了直接可运行的Consele(GameServer.exe)项目,开发者开发的脚本可以直接宿主在GameServer项目中运行。

  2. Model与CsScript之间的类交叉引用运行出错问题

    Scut运行时会分别为Model与CsScript两个dll在temp目录下(通过查看属性可以区分哪个是Model的dll),它们之间是有依赖层级关系的,CsScript的程序集引用Model的程序集,如果Model中有类使用了CsScript的类,就会发生编译出错,在Log的Exception目录下会有编译出错详细信息。

  3. 使用类库类型的项目如何调试框架内的代码

    .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,启动调试,如果断点显示的是实心红点说明断点设置成功,否则失败,检查以上步骤中是否遗漏;
  4. 创建项目默认是以脚本源码方式运行,如果想直接使用编译好的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目录下就不需要放其它脚本文件了

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ProjectDescription

ScutGame edited this page Jul 20, 2015 · 16 revisions

此章节介绍如何搭建服务端项目工程

新建立项目

Scut的开发环境要在VS2013以上版本

  1. 首先打开VS2013,创建一个“类库”类型的项目;

    Project add

  2. 选择Scut最新的Lib类库,将Lib目录和Console目录下的所有文件复制到新创建的类库项目中;

  3. 添加dll引用,切换到VS解决方案管理器中,将所有dll引用到项目中;

  4. 在VS解决方案管理器中,选择项目点击“显示所有文件”,将Script目录与GameServer.exe.config和Nlog.config文件包含到项目中;

  5. 调试项目,右击项目选“属性”,打开“调试”栏选择“启动外部程序”设置为“GameServer.exe”路径,并将工作目录设置成与GameSession.exe文件同级目录(此设置会影响Log的输入目录);

    Project property

下面是Scut服务端项目的目录结构:

ScutProject

理解目录结构

  1. 第一部分: 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开发者使用;

  1. 第二部分: Scut类库与第三方类库

包括所有的dll文件,ZyGames名称开头的是Scut的类库,其它的是第三方类库。

  1. 第三部分: GameServer宿主程序与ScutSMS工具

包括以下文件:

  • GameServer.exe文件: 以Console控制台方式运行的宿主程序;

  • GameServer.exe.config文件: 宿主程序的配置文件;

  • Nlog.Config文件: 第三方错误跟踪Log日志类库的配置文件,包括:输出的目录位置,错误级别输出控制和Log输出的类型控制(输出的类型:文件,控制台,Trace和Azure第三方存日志储等);

  • ScutSMS.exe文件: Scut提供的工具,可以方便配置游戏的参数和Redis数据的操作;

Config配置文件

  1. NLog.config文件: 游戏服日志文件配置,使用第三方的Nlog类库,结点"logDirectory" 是配置日志文件输出的路径,其它结点按默认配置。

    <variablename="logDirectory"value="d:\NLog\XXgame"/>
    
  2. GameServer.exe.config文件: 游戏服的主要配置,包括:数据库连接配置,Redis连接配置和其它游戏环境配置等;可以打开当前目录下的ScutSMS工具进行配置。

    <?xml version="1.0"?>
    <configuration> <!--基本参数配置,其它详细参数通过ScutSMS工具查看参数-->
    <appSettings>
    <addkey="Redis.Host"value="127.0.0.1:6379"/> <!--Redis服务的连接串,格式:password@host:port -->
    <addkey="Script_IsDebug"value="True"/> <!--开启脚本调试模式-->
    </appSettings>
    <!--数据库连接串配置-->
    <connectionStrings>
    <!-- @name: 连接串的标识Key,是Entity类配置的EntityTable属性的ConnKey参数值,两者要对应上 @providerName: 连接的数据库驱动类型;SqlDataProvider是SQL数据库的连接,MySqlDataProvider是MySql数据库的连接 @connectionString: 数据库连接串,与SQL或MySql数据库的连接串相同-->
    <addname="ConnData"providerName="SqlDataProvider"connectionString="Data Source={服务器地址};Database={数据库名};Uid={登录帐号};Pwd={登录密码};"/>
    </connectionStrings>
    </configuration>

Redis配置注意:

  • 一个Redis库只能被一个GameServer绑定,防止串库数据回档,否则启动时会有错误,这在新版本中有增加限制了;
  • 绑定的规则:机器名+GameServer路径,如果移动了项目位置,可以通过Redis-clie客户端连接到Redis服务器并直接删除"__redisinfo"的键;

开发者疑问

  1. 创建项目时为什么选择的是类库类型项目,而不是Console类型项目

    由于Scut已经提供了直接可运行的Consele(GameServer.exe)项目,开发者开发的脚本可以直接宿主在GameServer项目中运行。

  2. Model与CsScript之间的类交叉引用运行出错问题

    Scut运行时会分别为Model与CsScript两个dll在temp目录下(通过查看属性可以区分哪个是Model的dll),它们之间是有依赖层级关系的,CsScript的程序集引用Model的程序集,如果Model中有类使用了CsScript的类,就会发生编译出错,在Log的Exception目录下会有编译出错详细信息。

  3. 使用类库类型的项目如何调试框架内的代码

    .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,启动调试,如果断点显示的是实心红点说明断点设置成功,否则失败,检查以上步骤中是否遗漏;
  4. 创建项目默认是以脚本源码方式运行,如果想直接使用编译好的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目录下就不需要放其它脚本文件了

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

ProjectDescription

ScutGame edited this page Jul 20, 2015 · 16 revisions

此章节介绍如何搭建服务端项目工程

新建立项目

Scut的开发环境要在VS2013以上版本

  1. 首先打开VS2013,创建一个“类库”类型的项目;

    Project add

  2. 选择Scut最新的Lib类库,将Lib目录和Console目录下的所有文件复制到新创建的类库项目中;

  3. 添加dll引用,切换到VS解决方案管理器中,将所有dll引用到项目中;

  4. 在VS解决方案管理器中,选择项目点击“显示所有文件”,将Script目录与GameServer.exe.config和Nlog.config文件包含到项目中;

  5. 调试项目,右击项目选“属性”,打开“调试”栏选择“启动外部程序”设置为“GameServer.exe”路径,并将工作目录设置成与GameSession.exe文件同级目录(此设置会影响Log的输入目录);

    Project property

下面是Scut服务端项目的目录结构:

ScutProject

理解目录结构

  1. 第一部分: 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开发者使用;

  1. 第二部分: Scut类库与第三方类库

包括所有的dll文件,ZyGames名称开头的是Scut的类库,其它的是第三方类库。

  1. 第三部分: GameServer宿主程序与ScutSMS工具

包括以下文件:

  • GameServer.exe文件: 以Console控制台方式运行的宿主程序;

  • GameServer.exe.config文件: 宿主程序的配置文件;

  • Nlog.Config文件: 第三方错误跟踪Log日志类库的配置文件,包括:输出的目录位置,错误级别输出控制和Log输出的类型控制(输出的类型:文件,控制台,Trace和Azure第三方存日志储等);

  • ScutSMS.exe文件: Scut提供的工具,可以方便配置游戏的参数和Redis数据的操作;

Config配置文件

  1. NLog.config文件: 游戏服日志文件配置,使用第三方的Nlog类库,结点"logDirectory" 是配置日志文件输出的路径,其它结点按默认配置。

    <variablename="logDirectory"value="d:\NLog\XXgame"/>
    
  2. GameServer.exe.config文件: 游戏服的主要配置,包括:数据库连接配置,Redis连接配置和其它游戏环境配置等;可以打开当前目录下的ScutSMS工具进行配置。

    <?xml version="1.0"?>
    <configuration> <!--基本参数配置,其它详细参数通过ScutSMS工具查看参数-->
    <appSettings>
    <addkey="Redis.Host"value="127.0.0.1:6379"/> <!--Redis服务的连接串,格式:password@host:port -->
    <addkey="Script_IsDebug"value="True"/> <!--开启脚本调试模式-->
    </appSettings>
    <!--数据库连接串配置-->
    <connectionStrings>
    <!-- @name: 连接串的标识Key,是Entity类配置的EntityTable属性的ConnKey参数值,两者要对应上 @providerName: 连接的数据库驱动类型;SqlDataProvider是SQL数据库的连接,MySqlDataProvider是MySql数据库的连接 @connectionString: 数据库连接串,与SQL或MySql数据库的连接串相同-->
    <addname="ConnData"providerName="SqlDataProvider"connectionString="Data Source={服务器地址};Database={数据库名};Uid={登录帐号};Pwd={登录密码};"/>
    </connectionStrings>
    </configuration>

Redis配置注意:

  • 一个Redis库只能被一个GameServer绑定,防止串库数据回档,否则启动时会有错误,这在新版本中有增加限制了;
  • 绑定的规则:机器名+GameServer路径,如果移动了项目位置,可以通过Redis-clie客户端连接到Redis服务器并直接删除"__redisinfo"的键;

开发者疑问

  1. 创建项目时为什么选择的是类库类型项目,而不是Console类型项目

    由于Scut已经提供了直接可运行的Consele(GameServer.exe)项目,开发者开发的脚本可以直接宿主在GameServer项目中运行。

  2. Model与CsScript之间的类交叉引用运行出错问题

    Scut运行时会分别为Model与CsScript两个dll在temp目录下(通过查看属性可以区分哪个是Model的dll),它们之间是有依赖层级关系的,CsScript的程序集引用Model的程序集,如果Model中有类使用了CsScript的类,就会发生编译出错,在Log的Exception目录下会有编译出错详细信息。

  3. 使用类库类型的项目如何调试框架内的代码

    .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,启动调试,如果断点显示的是实心红点说明断点设置成功,否则失败,检查以上步骤中是否遗漏;
  4. 创建项目默认是以脚本源码方式运行,如果想直接使用编译好的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目录下就不需要放其它脚本文件了

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ProjectDescription

ScutGame edited this page Jul 20, 2015 · 16 revisions

此章节介绍如何搭建服务端项目工程

新建立项目

Scut的开发环境要在VS2013以上版本

  1. 首先打开VS2013,创建一个“类库”类型的项目;

    Project add

  2. 选择Scut最新的Lib类库,将Lib目录和Console目录下的所有文件复制到新创建的类库项目中;

  3. 添加dll引用,切换到VS解决方案管理器中,将所有dll引用到项目中;

  4. 在VS解决方案管理器中,选择项目点击“显示所有文件”,将Script目录与GameServer.exe.config和Nlog.config文件包含到项目中;

  5. 调试项目,右击项目选“属性”,打开“调试”栏选择“启动外部程序”设置为“GameServer.exe”路径,并将工作目录设置成与GameSession.exe文件同级目录(此设置会影响Log的输入目录);

    Project property

下面是Scut服务端项目的目录结构:

ScutProject

理解目录结构

  1. 第一部分: 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开发者使用;

  1. 第二部分: Scut类库与第三方类库

包括所有的dll文件,ZyGames名称开头的是Scut的类库,其它的是第三方类库。

  1. 第三部分: GameServer宿主程序与ScutSMS工具

包括以下文件:

  • GameServer.exe文件: 以Console控制台方式运行的宿主程序;

  • GameServer.exe.config文件: 宿主程序的配置文件;

  • Nlog.Config文件: 第三方错误跟踪Log日志类库的配置文件,包括:输出的目录位置,错误级别输出控制和Log输出的类型控制(输出的类型:文件,控制台,Trace和Azure第三方存日志储等);

  • ScutSMS.exe文件: Scut提供的工具,可以方便配置游戏的参数和Redis数据的操作;

Config配置文件

  1. NLog.config文件: 游戏服日志文件配置,使用第三方的Nlog类库,结点"logDirectory" 是配置日志文件输出的路径,其它结点按默认配置。

    <variablename="logDirectory"value="d:\NLog\XXgame"/>
    
  2. GameServer.exe.config文件: 游戏服的主要配置,包括:数据库连接配置,Redis连接配置和其它游戏环境配置等;可以打开当前目录下的ScutSMS工具进行配置。

    <?xml version="1.0"?>
    <configuration> <!--基本参数配置,其它详细参数通过ScutSMS工具查看参数-->
    <appSettings>
    <addkey="Redis.Host"value="127.0.0.1:6379"/> <!--Redis服务的连接串,格式:password@host:port -->
    <addkey="Script_IsDebug"value="True"/> <!--开启脚本调试模式-->
    </appSettings>
    <!--数据库连接串配置-->
    <connectionStrings>
    <!-- @name: 连接串的标识Key,是Entity类配置的EntityTable属性的ConnKey参数值,两者要对应上 @providerName: 连接的数据库驱动类型;SqlDataProvider是SQL数据库的连接,MySqlDataProvider是MySql数据库的连接 @connectionString: 数据库连接串,与SQL或MySql数据库的连接串相同-->
    <addname="ConnData"providerName="SqlDataProvider"connectionString="Data Source={服务器地址};Database={数据库名};Uid={登录帐号};Pwd={登录密码};"/>
    </connectionStrings>
    </configuration>

Redis配置注意:

  • 一个Redis库只能被一个GameServer绑定,防止串库数据回档,否则启动时会有错误,这在新版本中有增加限制了;
  • 绑定的规则:机器名+GameServer路径,如果移动了项目位置,可以通过Redis-clie客户端连接到Redis服务器并直接删除"__redisinfo"的键;

开发者疑问

  1. 创建项目时为什么选择的是类库类型项目,而不是Console类型项目

    由于Scut已经提供了直接可运行的Consele(GameServer.exe)项目,开发者开发的脚本可以直接宿主在GameServer项目中运行。

  2. Model与CsScript之间的类交叉引用运行出错问题

    Scut运行时会分别为Model与CsScript两个dll在temp目录下(通过查看属性可以区分哪个是Model的dll),它们之间是有依赖层级关系的,CsScript的程序集引用Model的程序集,如果Model中有类使用了CsScript的类,就会发生编译出错,在Log的Exception目录下会有编译出错详细信息。

  3. 使用类库类型的项目如何调试框架内的代码

    .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,启动调试,如果断点显示的是实心红点说明断点设置成功,否则失败,检查以上步骤中是否遗漏;
  4. 创建项目默认是以脚本源码方式运行,如果想直接使用编译好的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目录下就不需要放其它脚本文件了

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ProjectDescription

ScutGame edited this page Jul 20, 2015 · 16 revisions

此章节介绍如何搭建服务端项目工程

新建立项目

Scut的开发环境要在VS2013以上版本

  1. 首先打开VS2013,创建一个“类库”类型的项目;

    Project add

  2. 选择Scut最新的Lib类库,将Lib目录和Console目录下的所有文件复制到新创建的类库项目中;

  3. 添加dll引用,切换到VS解决方案管理器中,将所有dll引用到项目中;

  4. 在VS解决方案管理器中,选择项目点击“显示所有文件”,将Script目录与GameServer.exe.config和Nlog.config文件包含到项目中;

  5. 调试项目,右击项目选“属性”,打开“调试”栏选择“启动外部程序”设置为“GameServer.exe”路径,并将工作目录设置成与GameSession.exe文件同级目录(此设置会影响Log的输入目录);

    Project property

下面是Scut服务端项目的目录结构:

ScutProject

理解目录结构

  1. 第一部分: 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开发者使用;

  1. 第二部分: Scut类库与第三方类库

包括所有的dll文件,ZyGames名称开头的是Scut的类库,其它的是第三方类库。

  1. 第三部分: GameServer宿主程序与ScutSMS工具

包括以下文件:

  • GameServer.exe文件: 以Console控制台方式运行的宿主程序;

  • GameServer.exe.config文件: 宿主程序的配置文件;

  • Nlog.Config文件: 第三方错误跟踪Log日志类库的配置文件,包括:输出的目录位置,错误级别输出控制和Log输出的类型控制(输出的类型:文件,控制台,Trace和Azure第三方存日志储等);

  • ScutSMS.exe文件: Scut提供的工具,可以方便配置游戏的参数和Redis数据的操作;

Config配置文件

  1. NLog.config文件: 游戏服日志文件配置,使用第三方的Nlog类库,结点"logDirectory" 是配置日志文件输出的路径,其它结点按默认配置。

    <variablename="logDirectory"value="d:\NLog\XXgame"/>
    
  2. GameServer.exe.config文件: 游戏服的主要配置,包括:数据库连接配置,Redis连接配置和其它游戏环境配置等;可以打开当前目录下的ScutSMS工具进行配置。

    <?xml version="1.0"?>
    <configuration> <!--基本参数配置,其它详细参数通过ScutSMS工具查看参数-->
    <appSettings>
    <addkey="Redis.Host"value="127.0.0.1:6379"/> <!--Redis服务的连接串,格式:password@host:port -->
    <addkey="Script_IsDebug"value="True"/> <!--开启脚本调试模式-->
    </appSettings>
    <!--数据库连接串配置-->
    <connectionStrings>
    <!-- @name: 连接串的标识Key,是Entity类配置的EntityTable属性的ConnKey参数值,两者要对应上 @providerName: 连接的数据库驱动类型;SqlDataProvider是SQL数据库的连接,MySqlDataProvider是MySql数据库的连接 @connectionString: 数据库连接串,与SQL或MySql数据库的连接串相同-->
    <addname="ConnData"providerName="SqlDataProvider"connectionString="Data Source={服务器地址};Database={数据库名};Uid={登录帐号};Pwd={登录密码};"/>
    </connectionStrings>
    </configuration>

Redis配置注意:

  • 一个Redis库只能被一个GameServer绑定,防止串库数据回档,否则启动时会有错误,这在新版本中有增加限制了;
  • 绑定的规则:机器名+GameServer路径,如果移动了项目位置,可以通过Redis-clie客户端连接到Redis服务器并直接删除"__redisinfo"的键;

开发者疑问

  1. 创建项目时为什么选择的是类库类型项目,而不是Console类型项目

    由于Scut已经提供了直接可运行的Consele(GameServer.exe)项目,开发者开发的脚本可以直接宿主在GameServer项目中运行。

  2. Model与CsScript之间的类交叉引用运行出错问题

    Scut运行时会分别为Model与CsScript两个dll在temp目录下(通过查看属性可以区分哪个是Model的dll),它们之间是有依赖层级关系的,CsScript的程序集引用Model的程序集,如果Model中有类使用了CsScript的类,就会发生编译出错,在Log的Exception目录下会有编译出错详细信息。

  3. 使用类库类型的项目如何调试框架内的代码

    .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,启动调试,如果断点显示的是实心红点说明断点设置成功,否则失败,检查以上步骤中是否遗漏;
  4. 创建项目默认是以脚本源码方式运行,如果想直接使用编译好的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目录下就不需要放其它脚本文件了

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

ProjectDescription

ScutGame edited this page Jul 20, 2015 · 16 revisions

此章节介绍如何搭建服务端项目工程

新建立项目

Scut的开发环境要在VS2013以上版本

  1. 首先打开VS2013,创建一个“类库”类型的项目;

    Project add

  2. 选择Scut最新的Lib类库,将Lib目录和Console目录下的所有文件复制到新创建的类库项目中;

  3. 添加dll引用,切换到VS解决方案管理器中,将所有dll引用到项目中;

  4. 在VS解决方案管理器中,选择项目点击“显示所有文件”,将Script目录与GameServer.exe.config和Nlog.config文件包含到项目中;

  5. 调试项目,右击项目选“属性”,打开“调试”栏选择“启动外部程序”设置为“GameServer.exe”路径,并将工作目录设置成与GameSession.exe文件同级目录(此设置会影响Log的输入目录);

    Project property

下面是Scut服务端项目的目录结构:

ScutProject

理解目录结构

  1. 第一部分: 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开发者使用;

  1. 第二部分: Scut类库与第三方类库

包括所有的dll文件,ZyGames名称开头的是Scut的类库,其它的是第三方类库。

  1. 第三部分: GameServer宿主程序与ScutSMS工具

包括以下文件:

  • GameServer.exe文件: 以Console控制台方式运行的宿主程序;

  • GameServer.exe.config文件: 宿主程序的配置文件;

  • Nlog.Config文件: 第三方错误跟踪Log日志类库的配置文件,包括:输出的目录位置,错误级别输出控制和Log输出的类型控制(输出的类型:文件,控制台,Trace和Azure第三方存日志储等);

  • ScutSMS.exe文件: Scut提供的工具,可以方便配置游戏的参数和Redis数据的操作;

Config配置文件

  1. NLog.config文件: 游戏服日志文件配置,使用第三方的Nlog类库,结点"logDirectory" 是配置日志文件输出的路径,其它结点按默认配置。

    <variablename="logDirectory"value="d:\NLog\XXgame"/>
    
  2. GameServer.exe.config文件: 游戏服的主要配置,包括:数据库连接配置,Redis连接配置和其它游戏环境配置等;可以打开当前目录下的ScutSMS工具进行配置。

    <?xml version="1.0"?>
    <configuration> <!--基本参数配置,其它详细参数通过ScutSMS工具查看参数-->
    <appSettings>
    <addkey="Redis.Host"value="127.0.0.1:6379"/> <!--Redis服务的连接串,格式:password@host:port -->
    <addkey="Script_IsDebug"value="True"/> <!--开启脚本调试模式-->
    </appSettings>
    <!--数据库连接串配置-->
    <connectionStrings>
    <!-- @name: 连接串的标识Key,是Entity类配置的EntityTable属性的ConnKey参数值,两者要对应上 @providerName: 连接的数据库驱动类型;SqlDataProvider是SQL数据库的连接,MySqlDataProvider是MySql数据库的连接 @connectionString: 数据库连接串,与SQL或MySql数据库的连接串相同-->
    <addname="ConnData"providerName="SqlDataProvider"connectionString="Data Source={服务器地址};Database={数据库名};Uid={登录帐号};Pwd={登录密码};"/>
    </connectionStrings>
    </configuration>

Redis配置注意:

  • 一个Redis库只能被一个GameServer绑定,防止串库数据回档,否则启动时会有错误,这在新版本中有增加限制了;
  • 绑定的规则:机器名+GameServer路径,如果移动了项目位置,可以通过Redis-clie客户端连接到Redis服务器并直接删除"__redisinfo"的键;

开发者疑问

  1. 创建项目时为什么选择的是类库类型项目,而不是Console类型项目

    由于Scut已经提供了直接可运行的Consele(GameServer.exe)项目,开发者开发的脚本可以直接宿主在GameServer项目中运行。

  2. Model与CsScript之间的类交叉引用运行出错问题

    Scut运行时会分别为Model与CsScript两个dll在temp目录下(通过查看属性可以区分哪个是Model的dll),它们之间是有依赖层级关系的,CsScript的程序集引用Model的程序集,如果Model中有类使用了CsScript的类,就会发生编译出错,在Log的Exception目录下会有编译出错详细信息。

  3. 使用类库类型的项目如何调试框架内的代码

    .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,启动调试,如果断点显示的是实心红点说明断点设置成功,否则失败,检查以上步骤中是否遗漏;
  4. 创建项目默认是以脚本源码方式运行,如果想直接使用编译好的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目录下就不需要放其它脚本文件了

Clone this wiki locally