接著學習GShare.pas的實現部分,其實這個應該叫做GAMECENTER共享單元,我剛開始理解的是錯誤的,這是根據名字起的.
在學習實現部分之前,聲明部分還有一些變量:
//雖然光看這些變量不可能全部知道代表什麼,但是為了學習,還是注釋一下 var //下面4個應該是更新數據(格式)用的,默認為本機更新 g_sDataListAddrs: string = '127.0.0.1'; g_wDataListPort: Word = 18888; g_sDataListPassWord: string = '123456'; g_boGetDataListOK: Boolean = False; //下面3個是獲取更新列表用的, g_DataListReadBuffer: PChar; g_nDataListReadLength: Integer; g_GetDatList: TStringList; //下面6個很明顯,從字面就能看出意思對應啟動設置\窗口\按鈕狀態 g_nFormIdx: Integer; g_IniConf: Tinifile; g_sButtonStartGame: string = '啟動游戲服務器(&S)'; g_sButtonStopGame: string = '停止游戲服務器(&T)'; g_sButtonStopStartGame: string = '中止啟動游戲服務器(&T)'; g_sButtonStopStopGame: string = '中止停止游戲服務器(&T)'; //下面對應的都是配置變量,主窗口都有對應的控件 g_sConfFile: string = '.\Config.ini'; g_sBackListFile: string = '.\BackupList.txt'; g_sGameName: string = '測試引擎'; g_sGameDirectory: string = '.\'; g_sHeroDBName: string = 'HeroDB'; g_sExtIPaddr: string = '127.0.0.1'; g_sExtIPaddr2: string = '127.0.0.1'; g_boAutoRunBak: Boolean = False; g_boCloseWuXin: Boolean = False; g_boIP2: Boolean = False; // 聲明並初始化服務端配置結構,也許類似這樣的應該定義為類,前邊也好多 g_Config: TConfig = ( DBServer: ( MainFormX: 0; MainFormY: 373; GatePort: 5100; ServerPort: 6000; GetStart: True; ProgramFile: 'DBServer.exe'; ); LoginSrv: ( MainFormX: 252; MainFormY: 0; GatePort: 5500; ServerPort: 5600; MonPort: 3000; GetStart: True; ProgramFile: 'LoginSrv.exe'; ); M2Server:( MainFormX: 561; MainFormY: 0; GatePort: 5000; MsgSrvPort: 4900; GetStart: True; ProgramFile: 'M2Server.exe'; ProgramFile: 'PlugTop.exe'; ); LogServer:( MainFormX: 252; MainFormY: 286; Port: 10000; GetStart: True; ProgramFile: 'LogDataServer.exe'; ); RunGate:( MainFormX: 437; MainFormY: 373; GetStart: (True, False, False, False, False, False, False, False); GatePort: (7200, 7201, 7202, 7203, 7204, 7205, 7206, 7207); ProgramFile: 'RunGate.exe'; ); SelGate:( MainFormX: 0; MainFormY: 180; GatePort: (7100, 7101); GetStart1: True; GetStart2: False; ProgramFile: 'SelGate.exe'; ); LoginGate:( MainFormX: 0; MainFormY: 0; GatePort: 7000; GetStart: True; ProgramFile: 'LoginGate.exe'; ); PlugTop:( MainFormX: 525; MainFormY:300; GetStart: True; ProgramFile: 'PlugTop.exe'; ); ); //聲明服務程序變量,暫時就這麼理解吧 DBServer: TProgram; LoginServer: TProgram; LogServer: TProgram; M2Server: TProgram; RunGate: array[0..MAXRUNGATECOUNT - 1] of TProgram; SelGate: TProgram; SelGate1: TProgram; LoginGate: TProgram; LoginGate2: TProgram; PlugTop: TProgram; //下面是檢測程序運行狀態的變量,暫時理解為心跳檢測吧 g_dwStopTick: LongWord; g_dwStopTimeOut: LongWord = 10000; g_dwM2CheckCodeAddr: LongWord; g_dwDBCheckCodeAddr: LongWord; g_BackUpManager: TBackUpManager; m_nBackStartStatus: Integer = 0;
到此GShare.pas的聲明部分結束,覺得還可以優化,接下來是實現部分,實現一共有5個函數\過程:
procedure LoadConfig();//加載配置 procedure SaveConfig();//保存配置 {運行服務} function RunProgram(var ProgramInfo: TProgram; sHandle: string; dwWaitTime: LongWord): LongWord; {停止服務} function StopProgram(var ProgramInfo: TProgram; dwWaitTime: LongWord): Integer; {發送消息} procedure SendProgramMsg(DesForm: THandle; wIdent: Word; sSendMsg: string);
加載保存配置就是讀取和寫入服務端裡邊的INI和TXT配置文件,啟動停止服務發送數據(消息)用的是API:
//讀取配置信息 procedure LoadConfig(); begin //下面一堆都是讀取INI文件,准備後續優化一下 g_sGameDirectory := g_IniConf.ReadString(BasicSectionName, 'GameDirectory', g_sGameDirectory); g_sHeroDBName := g_IniConf.ReadString(BasicSectionName, 'HeroDBName', g_sHeroDBName); g_sGameName := g_IniConf.ReadString(BasicSectionName, 'GameName', g_sGameName); g_sExtIPaddr := g_IniConf.ReadString(BasicSectionName, 'ExtIPaddr', g_sExtIPaddr); g_sExtIPaddr2 := g_IniConf.ReadString(BasicSectionName, 'ExtIPaddr2', g_sExtIPaddr2); g_boAutoRunBak := g_IniConf.ReadBool(BasicSectionName, 'AutoRunBak', g_boAutoRunBak); g_boIP2 := g_IniConf.ReadBool(BasicSectionName, 'IP2', g_boIP2); g_boCloseWuXin := g_IniConf.ReadBool(BasicSectionName, 'CloseWuXin', g_boCloseWuXin); g_Config.DBServer.MainFormX := g_IniConf.ReadInteger(DBServerSectionName, 'MainFormX', g_Config.DBServer.MainFormX); g_Config.DBServer.MainFormY := g_IniConf.ReadInteger(DBServerSectionName, 'MainFormY', g_Config.DBServer.MainFormY); g_Config.DBServer.GatePort := g_IniConf.ReadInteger(DBServerSectionName, 'GatePort', g_Config.DBServer.GatePort); g_Config.DBServer.ServerPort := g_IniConf.ReadInteger(DBServerSectionName, 'ServerPort', g_Config.DBServer.ServerPort); g_Config.DBServer.GetStart := g_IniConf.ReadBool(DBServerSectionName, 'GetStart', g_Config.DBServer.GetStart); g_Config.LoginSrv.MainFormX := g_IniConf.ReadInteger(LoginSrvSectionName, 'MainFormX', g_Config.LoginSrv.MainFormX); g_Config.LoginSrv.MainFormY := g_IniConf.ReadInteger(LoginSrvSectionName, 'MainFormY', g_Config.LoginSrv.MainFormY); g_Config.LoginSrv.GatePort := g_IniConf.ReadInteger(LoginSrvSectionName, 'GatePort', g_Config.LoginSrv.GatePort); g_Config.LoginSrv.ServerPort := g_IniConf.ReadInteger(LoginSrvSectionName, 'ServerPort', g_Config.LoginSrv.ServerPort); g_Config.LoginSrv.MonPort := g_IniConf.ReadInteger(LoginSrvSectionName, 'MonPort', g_Config.LoginSrv.MonPort); g_Config.LoginSrv.GetStart := g_IniConf.ReadBool(LoginSrvSectionName, 'GetStart', g_Config.LoginSrv.GetStart); g_Config.M2Server.MainFormX := g_IniConf.ReadInteger(M2ServerSectionName, 'MainFormX', g_Config.M2Server.MainFormX); g_Config.M2Server.MainFormY := g_IniConf.ReadInteger(M2ServerSectionName, 'MainFormY', g_Config.M2Server.MainFormY); g_Config.M2Server.GatePort := g_IniConf.ReadInteger(M2ServerSectionName, 'GatePort', g_Config.M2Server.GatePort); g_Config.M2Server.MsgSrvPort := g_IniConf.ReadInteger(M2ServerSectionName, 'MsgSrvPort', g_Config.M2Server.MsgSrvPort); g_Config.M2Server.GetStart := g_IniConf.ReadBool(M2ServerSectionName, 'GetStart', g_Config.M2Server.GetStart); g_Config.LogServer.MainFormX := g_IniConf.ReadInteger(LogServerSectionName, 'MainFormX', g_Config.LogServer.MainFormX); g_Config.LogServer.MainFormY := g_IniConf.ReadInteger(LogServerSectionName, 'MainFormY', g_Config.LogServer.MainFormY); g_Config.LogServer.Port := g_IniConf.ReadInteger(LogServerSectionName, 'Port', g_Config.LogServer.Port); g_Config.LogServer.GetStart := g_IniConf.ReadBool(LogServerSectionName, 'GetStart', g_Config.LogServer.GetStart); g_Config.RunGate.MainFormX := g_IniConf.ReadInteger(RunGateSectionName, 'MainFormX', g_Config.RunGate.MainFormX); g_Config.RunGate.MainFormY := g_IniConf.ReadInteger(RunGateSectionName, 'MainFormY', g_Config.RunGate.MainFormY); g_Config.RunGate.GetStart[0] := g_IniConf.ReadBool(RunGateSectionName, 'GetStart1', g_Config.RunGate.GetStart[0]); g_Config.RunGate.GetStart[1] := g_IniConf.ReadBool(RunGateSectionName, 'GetStart2', g_Config.RunGate.GetStart[1]); g_Config.RunGate.GetStart[2] := g_IniConf.ReadBool(RunGateSectionName, 'GetStart3', g_Config.RunGate.GetStart[2]); g_Config.RunGate.GetStart[3] := g_IniConf.ReadBool(RunGateSectionName, 'GetStart4', g_Config.RunGate.GetStart[3]); g_Config.RunGate.GetStart[4] := g_IniConf.ReadBool(RunGateSectionName, 'GetStart5', g_Config.RunGate.GetStart[4]); g_Config.RunGate.GetStart[5] := g_IniConf.ReadBool(RunGateSectionName, 'GetStart6', g_Config.RunGate.GetStart[5]); g_Config.RunGate.GetStart[6] := g_IniConf.ReadBool(RunGateSectionName, 'GetStart7', g_Config.RunGate.GetStart[6]); g_Config.RunGate.GetStart[7] := g_IniConf.ReadBool(RunGateSectionName, 'GetStart8', g_Config.RunGate.GetStart[7]); g_Config.RunGate.GatePort[0] := g_IniConf.ReadInteger(RunGateSectionName, 'GatePort1', g_Config.RunGate.GatePort[0]); g_Config.RunGate.GatePort[1] := g_IniConf.ReadInteger(RunGateSectionName, 'GatePort2', g_Config.RunGate.GatePort[1]); g_Config.RunGate.GatePort[2] := g_IniConf.ReadInteger(RunGateSectionName, 'GatePort3', g_Config.RunGate.GatePort[2]); g_Config.RunGate.GatePort[3] := g_IniConf.ReadInteger(RunGateSectionName, 'GatePort4', g_Config.RunGate.GatePort[3]); g_Config.RunGate.GatePort[4] := g_IniConf.ReadInteger(RunGateSectionName, 'GatePort5', g_Config.RunGate.GatePort[4]); g_Config.RunGate.GatePort[5] := g_IniConf.ReadInteger(RunGateSectionName, 'GatePort6', g_Config.RunGate.GatePort[5]); g_Config.RunGate.GatePort[6] := g_IniConf.ReadInteger(RunGateSectionName, 'GatePort7', g_Config.RunGate.GatePort[6]); g_Config.RunGate.GatePort[7] := g_IniConf.ReadInteger(RunGateSectionName, 'GatePort8', g_Config.RunGate.GatePort[7]); g_Config.SelGate.MainFormX := g_IniConf.ReadInteger(SelGateSectionName, 'MainFormX', g_Config.SelGate.MainFormX); g_Config.SelGate.MainFormY := g_IniConf.ReadInteger(SelGateSectionName, 'MainFormY', g_Config.SelGate.MainFormY); g_Config.SelGate.GatePort[0] := g_IniConf.ReadInteger(SelGateSectionName, 'GatePort1', g_Config.SelGate.GatePort[0]); g_Config.SelGate.GatePort[1] := g_IniConf.ReadInteger(SelGateSectionName, 'GatePort2', g_Config.SelGate.GatePort[1]); g_Config.SelGate.GetStart1 := g_IniConf.ReadBool(SelGateSectionName, 'GetStart1', g_Config.SelGate.GetStart1); g_Config.SelGate.GetStart2 := g_IniConf.ReadBool(SelGateSectionName, 'GetStart2', g_Config.SelGate.GetStart2); g_Config.LoginGate.MainFormX := g_IniConf.ReadInteger(LoginGateSectionName, 'MainFormX', g_Config.LoginGate.MainFormX); g_Config.LoginGate.MainFormY := g_IniConf.ReadInteger(LoginGateSectionName, 'MainFormY', g_Config.LoginGate.MainFormY); g_Config.LoginGate.GatePort := g_IniConf.ReadInteger(LoginGateSectionName, 'GatePort', g_Config.LoginGate.GatePort); g_Config.LoginGate.GetStart := g_IniConf.ReadBool(LoginGateSectionName, 'GetStart', g_Config.LoginGate.GetStart); g_Config.PlugTop.MainFormX := g_IniConf.ReadInteger(PlugTopSectionName, 'MainFormX', g_Config.PlugTop.MainFormX); g_Config.PlugTop.MainFormY := g_IniConf.ReadInteger(PlugTopSectionName, 'MainFormY', g_Config.PlugTop.MainFormY); g_Config.PlugTop.GetStart := g_IniConf.ReadBool(PlugTopSectionName, 'GetStart', g_Config.PlugTop.GetStart); end; procedure SaveConfig(); //保存配置信息 begin //沒什麼可注釋的,寫入INI g_IniConf.WriteString(BasicSectionName, 'GameDirectory', g_sGameDirectory); g_IniConf.WriteString(BasicSectionName, 'HeroDBName', g_sHeroDBName); g_IniConf.WriteString(BasicSectionName, 'GameName', g_sGameName); g_IniConf.WriteString(BasicSectionName, 'ExtIPaddr', g_sExtIPaddr); g_IniConf.WriteString(BasicSectionName, 'ExtIPaddr2', g_sExtIPaddr2); g_IniConf.WriteBool(BasicSectionName, 'AutoRunBak', g_boAutoRunBak); g_IniConf.WriteBool(BasicSectionName, 'IP2', g_boIP2); g_IniConf.WriteBool(BasicSectionName, 'CloseWuXin', g_boCloseWuXin); g_IniConf.WriteInteger(DBServerSectionName, 'MainFormX', g_Config.DBServer.MainFormX); g_IniConf.WriteInteger(DBServerSectionName, 'MainFormY', g_Config.DBServer.MainFormY); g_IniConf.WriteInteger(DBServerSectionName, 'GatePort', g_Config.DBServer.GatePort); g_IniConf.WriteInteger(DBServerSectionName, 'ServerPort', g_Config.DBServer.ServerPort); g_IniConf.WriteBool(DBServerSectionName, 'GetStart', g_Config.DBServer.GetStart); g_IniConf.WriteInteger(LoginSrvSectionName, 'MainFormX', g_Config.LoginSrv.MainFormX); g_IniConf.WriteInteger(LoginSrvSectionName, 'MainFormY', g_Config.LoginSrv.MainFormY); g_IniConf.WriteInteger(LoginSrvSectionName, 'GatePort', g_Config.LoginSrv.GatePort); g_IniConf.WriteInteger(LoginSrvSectionName, 'ServerPort', g_Config.LoginSrv.ServerPort); g_IniConf.WriteInteger(LoginSrvSectionName, 'MonPort', g_Config.LoginSrv.MonPort); g_IniConf.WriteBool(LoginSrvSectionName, 'GetStart', g_Config.LoginSrv.GetStart); g_IniConf.WriteInteger(M2ServerSectionName, 'MainFormX', g_Config.M2Server.MainFormX); g_IniConf.WriteInteger(M2ServerSectionName, 'MainFormY', g_Config.M2Server.MainFormY); g_IniConf.WriteInteger(M2ServerSectionName, 'GatePort', g_Config.M2Server.GatePort); g_IniConf.WriteInteger(M2ServerSectionName, 'MsgSrvPort', g_Config.M2Server.MsgSrvPort); g_IniConf.WriteBool(M2ServerSectionName, 'GetStart', g_Config.M2Server.GetStart); g_IniConf.WriteInteger(LogServerSectionName, 'MainFormX', g_Config.LogServer.MainFormX); g_IniConf.WriteInteger(LogServerSectionName, 'MainFormY', g_Config.LogServer.MainFormY); g_IniConf.WriteInteger(LogServerSectionName, 'Port', g_Config.LogServer.Port); g_IniConf.WriteBool(LogServerSectionName, 'GetStart', g_Config.LogServer.GetStart); g_IniConf.WriteInteger(RunGateSectionName, 'MainFormX', g_Config.RunGate.MainFormX); g_IniConf.WriteInteger(RunGateSectionName, 'MainFormY', g_Config.RunGate.MainFormY); g_IniConf.WriteBool(RunGateSectionName, 'GetStart1', g_Config.RunGate.GetStart[0]); g_IniConf.WriteBool(RunGateSectionName, 'GetStart2', g_Config.RunGate.GetStart[1]); g_IniConf.WriteBool(RunGateSectionName, 'GetStart3', g_Config.RunGate.GetStart[2]); g_IniConf.WriteBool(RunGateSectionName, 'GetStart4', g_Config.RunGate.GetStart[3]); g_IniConf.WriteBool(RunGateSectionName, 'GetStart5', g_Config.RunGate.GetStart[4]); g_IniConf.WriteBool(RunGateSectionName, 'GetStart6', g_Config.RunGate.GetStart[5]); g_IniConf.WriteBool(RunGateSectionName, 'GetStart7', g_Config.RunGate.GetStart[6]); g_IniConf.WriteBool(RunGateSectionName, 'GetStart8', g_Config.RunGate.GetStart[7]); g_IniConf.WriteInteger(RunGateSectionName, 'GatePort1', g_Config.RunGate.GatePort[0]); g_IniConf.WriteInteger(RunGateSectionName, 'GatePort2', g_Config.RunGate.GatePort[1]); g_IniConf.WriteInteger(RunGateSectionName, 'GatePort3', g_Config.RunGate.GatePort[2]); g_IniConf.WriteInteger(RunGateSectionName, 'GatePort4', g_Config.RunGate.GatePort[3]); g_IniConf.WriteInteger(RunGateSectionName, 'GatePort5', g_Config.RunGate.GatePort[4]); g_IniConf.WriteInteger(RunGateSectionName, 'GatePort6', g_Config.RunGate.GatePort[5]); g_IniConf.WriteInteger(RunGateSectionName, 'GatePort7', g_Config.RunGate.GatePort[6]); g_IniConf.WriteInteger(RunGateSectionName, 'GatePort8', g_Config.RunGate.GatePort[7]); g_IniConf.WriteInteger(SelGateSectionName, 'MainFormX', g_Config.SelGate.MainFormX); g_IniConf.WriteInteger(SelGateSectionName, 'MainFormY', g_Config.SelGate.MainFormY); g_IniConf.WriteInteger(SelGateSectionName, 'GatePort1', g_Config.SelGate.GatePort[0]); g_IniConf.WriteInteger(SelGateSectionName, 'GatePort2', g_Config.SelGate.GatePort[1]); g_IniConf.WriteBool(SelGateSectionName, 'GetStart1', g_Config.SelGate.GetStart1); g_IniConf.WriteBool(SelGateSectionName, 'GetStart2', g_Config.SelGate.GetStart2); g_IniConf.WriteInteger(LoginGateSectionName, 'MainFormX', g_Config.LoginGate.MainFormX); g_IniConf.WriteInteger(LoginGateSectionName, 'MainFormY', g_Config.LoginGate.MainFormY); g_IniConf.WriteInteger(LoginGateSectionName, 'GatePort', g_Config.LoginGate.GatePort); g_IniConf.WriteBool(LoginGateSectionName, 'GetStart', g_Config.LoginGate.GetStart); g_IniConf.WriteInteger(PlugTopSectionName, 'MainFormX', g_Config.PlugTop.MainFormX); g_IniConf.WriteInteger(PlugTopSectionName, 'MainFormY', g_Config.PlugTop.MainFormY); g_IniConf.WriteBool(PlugTopSectionName, 'GetStart', g_Config.PlugTop.GetStart); end; {啟動服務,用的大部分是API} function RunProgram(var ProgramInfo: TProgram; sHandle: string; dwWaitTime: LongWord): LongWord; var StartupInfo: TStartupInfo; //獲取窗口狀態 sCommandLine: string; //程序完整路徑 sCurDirectory: string; //程序目錄 begin Result := 0; FillChar(StartupInfo, SizeOf(TStartupInfo), #0); //這個雖然查看了API參考,還是不理解,暫時就認為它是初始化吧 GetStartupInfo(StartupInfo);//獲取進程的啟動信息 {格式化程序完整路徑字符串} sCommandLine := format('%s%s %s %d %d', [ProgramInfo.sDirectory, ProgramInfo.sProgramFile, sHandle, ProgramInfo.nMainFormX, ProgramInfo.nMainFormY]); sCurDirectory := ProgramInfo.sDirectory; //取得程序運行目錄 if not CreateProcess(nil, //如果啟動服務失敗返回錯誤代碼 PChar(sCommandLine), nil, nil, True, 0, nil, PChar(sCurDirectory), StartupInfo, ProgramInfo.ProcessInfo) then begin Result := GetLastError(); end; Sleep(dwWaitTime); //等待 end; {停止服務,這個函數很簡單,不再注釋} function StopProgram(var ProgramInfo: TProgram; dwWaitTime: LongWord): Integer; var dwExitCode: LongWord; begin Result := 0; dwExitCode := 0; if TerminateProcess(ProgramInfo.ProcessHandle, dwExitCode) then begin Result := GetLastError(); end; Sleep(dwWaitTime); end; {這個是向指定程序發送數據} procedure SendProgramMsg(DesForm: THandle; wIdent: Word; sSendMsg: string); var SendData: TCopyDataStruct; nParam: Integer; begin nParam := MakeLong(0, wIdent); SendData.cbData := length(sSendMsg) + 1; GetMem(SendData.lpData, SendData.cbData); StrCopy(SendData.lpData, PChar(sSendMsg)); SendMessage(DesForm, WM_COPYDATA, nParam, Cardinal(@SendData)); FreeMem(SendData.lpData); end; {初始化和反初始化} initialization begin g_IniConf := Tinifile.Create(g_sConfFile); end; finalization begin g_IniConf.Free; end;
主要是加載和保存配置過程過程重復的事情很多,可以考慮改進.
整個GShare.pas單元學習完畢,接下來可以開始主單元文件學習了.