Scut游戲服務器免費開源框架--快速開發(3)


Scut快速開發(3)

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM