启动游戏过程
// 启动游戏按钮点击事件
procedure TfrmMain.ButtonStartGameClick(Sender: TObject);
begin
// 检查是否已经在运行
if m_nStartStatus = 1 then begin
StopGame(); // 如果正在运行则停止
Exit;
end;
// 开始启动游戏
m_nStartStatus := 1;
ButtonStartGame.Caption := '停止游戏(&S)';
TimerStartGame.Enabled := True; // 启动启动计时器
end;
// 游戏启动计时器事件 - 按顺序启动各服务器
procedure TfrmMain.TimerStartGameTimer(Sender: TObject);
begin
TimerStartGame.Enabled := False;
try
// 1. 启动数据库服务器
if CheckBoxDBServer.Checked then begin
MainOutMessage('正在启动数据库服务器...');
if not StartProgram(EditDBServerProgram.Text, g_sGameDirectory) then begin
MainOutMessage('数据库服务器启动失败!');
Exit;
end;
Sleep(1000); // 等待数据库服务器就绪
end;
// 2. 启动登录服务器
if CheckBoxLoginServer.Checked then begin
MainOutMessage('正在启动登录服务器...');
if not StartProgram(EditLoginSrvProgram.Text, g_sGameDirectory) then begin
MainOutMessage('登录服务器启动失败!');
Exit;
end;
Sleep(500);
end;
// 3. 启动日志服务器
if CheckBoxLogServer.Checked then begin
MainOutMessage('正在启动日志服务器...');
if not StartProgram(EditLogServerProgram.Text, g_sGameDirectory) then begin
MainOutMessage('日志服务器启动失败!');
Exit;
end;
Sleep(500);
end;
// 4. 启动游戏主服务器
if CheckBoxM2Server.Checked then begin
MainOutMessage('正在启动游戏主服务器...');
if not StartProgram(EditM2ServerProgram.Text, g_sGameDirectory) then begin
MainOutMessage('游戏主服务器启动失败!');
Exit;
end;
Sleep(1000);
end;
// 5. 启动登录网关(可多个)
if CheckBoxLoginGate.Checked then begin
MainOutMessage('正在启动登录网关...');
for I := 1 to g_nLoginGate_Count do begin
if not StartProgram(EditLoginGateProgram.Text, g_sGameDirectory) then begin
MainOutMessage(Format('登录网关 %d 启动失败!', [I]));
Continue;
end;
if CheckBoxLoginGateSleep.Checked then
Sleep(SpinEditLoginGateSleep.Value);
end;
end;
// 6. 启动选择网关
if CheckBoxSelGate.Checked then begin
MainOutMessage('正在启动选择网关...');
for I := 1 to g_nSelGate_Count do begin
if not StartProgram(EditSelGateProgram.Text, g_sGameDirectory) then begin
MainOutMessage(Format('选择网关 %d 启动失败!', [I]));
Continue;
end;
Sleep(500);
end;
end;
// 7. 启动运行网关
if CheckBoxRunGate.Checked then begin
MainOutMessage('正在启动运行网关...');
for I := 1 to g_nRunGate_Count do begin
if not StartProgram(EditRunGateProgram.Text, g_sGameDirectory) then begin
MainOutMessage(Format('运行网关 %d 启动失败!', [I]));
Continue;
end;
Sleep(500);
end;
end;
// 启动成功
MainOutMessage('游戏服务器启动完成!');
// 启动监控
TimerCheckRun.Enabled := True;
except
on E: Exception do begin
MainOutMessage('启动过程出错: ' + E.Message);
StopGame();
end;
end;
end;
// 启动单个程序
function TfrmMain.StartProgram(const ProgramFile, WorkDir: string): Boolean;
var
StartupInfo: TStartupInfo;
ProcessInfo: TProcessInformation;
CommandLine: string;
CmdParams: string;
begin
Result := False;
// 检查文件是否存在
if not FileExists(ProgramFile) then begin
MainOutMessage(Format('程序文件不存在: %s', [ProgramFile]));
Exit;
end;
// 获取启动参数
CmdParams := GetServerParams(ProgramFile);
// 准备启动信息
FillChar(StartupInfo, SizeOf(TStartupInfo), 0);
StartupInfo.cb := SizeOf(StartupInfo);
// 设置窗口显示状态
if CheckBoxsw_show.Checked then begin
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_SHOW;
end else begin
StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
StartupInfo.wShowWindow := SW_HIDE;
end;
try
// 构建命令行
CommandLine := Format('"%s" %s', [ProgramFile, CmdParams]);
// 创建进程
if CreateProcess(nil,
PChar(CommandLine),
nil, nil,
False,
NORMAL_PRIORITY_CLASS,
nil,
PChar(WorkDir),
StartupInfo,
ProcessInfo) then begin
Result := True;
// 保存进程信息
SaveProcessInfo(ProgramFile, ProcessInfo);
// 关闭句柄
CloseHandle(ProcessInfo.hProcess);
CloseHandle(ProcessInfo.hThread);
end;
except
on E: Exception do begin
MainOutMessage(Format('启动程序出错: %s - %s',
[ExtractFileName(ProgramFile), E.Message]));
end;
end;
end;
// 获取服务器启动参数
function TfrmMain.GetServerParams(const ProgramFile: string): string;
var
FileName: string;
begin
FileName := ExtractFileName(ProgramFile);
Result := '';
// 根据程序名称返回对应参数
if CompareText(FileName, 'DBServer.exe') = 0 then
Result := Format('/Port:%s', [EditDBServerPort.Text])
else if CompareText(FileName, 'LoginSrv.exe') = 0 then
Result := Format('/Port:%s /GatePort:%s',
[EditLoginSrvPort.Text, EditLoginSrvGatePort.Text])
else if CompareText(FileName, 'M2Server.exe') = 0 then
Result := Format('/Port:%s /GatePort:%s',
[EditM2ServerPort.Text, EditM2ServerGatePort.Text])
// ... 其他服务器参数
end;