<commit_before>program KaM_DedicatedServer;
{$I ..\..\KaM_Remake.inc}

{$IFDEF MSWindows}
  {$APPTYPE CONSOLE}
{$ENDIF}

uses
  {$IFDEF UNIX} cthreads, {$ENDIF} //We use a thread for deleting old log files
  SysUtils,
  {$IFDEF MSWindows} Windows, MMSystem, {$ENDIF}
  {$IFDEF Unix} KM_Utils, {$ENDIF} //Needed in Linux for FakeGetTickCount
  KM_Defaults,
  KM_Log,
  KM_Settings,
  KM_DedicatedServer,
  KM_ServerEventHandler in 'KM_ServerEventHandler.pas';

var
  fEventHandler: TKMServerEventHandler;
  fDedicatedServer: TKMDedicatedServer;
  fSettings: TGameSettings;
  fSettingsLastModified: integer;
  TickCount, fLastSettingsFileCheck: cardinal;

{$IFDEF WDC}
procedure MyProcessMessages;
var Msg: TMsg;
begin
  while PeekMessage(Msg, 0, 0, 0, 0) do
  begin
    GetMessage(Msg, 0, 0, 0);
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
end;
{$ENDIF}

procedure RunTheServer;
begin
  fDedicatedServer := TKMDedicatedServer.Create(fSettings.MaxRooms,
                                                fSettings.AutoKickTimeout,
                                                fSettings.PingInterval,
                                                fSettings.MasterAnnounceInterval,
                                                fSettings.MasterServerAddress,
                                                fSettings.HTMLStatusFile,
                                                fSettings.ServerWelcomeMessage);
  fDedicatedServer.OnMessage := fEventHandler.ServerStatusMessage;
  fDedicatedServer.Start(fSettings.ServerName, fSettings.ServerPort, fSettings.AnnounceServer);

  while True do
  begin
    fDedicatedServer.UpdateState;
    TickCount := {$IFDEF MSWindows}GetTickCount{$ENDIF}
                 {$IFDEF Unix} FakeGetTickCount{$ENDIF};
    //Reload the INI file if it has changed, by checking the file age every 5 seconds
    if (abs(Int64(TickCount)-Int64(fLastSettingsFileCheck)) >= 5000) then
    begin
      fLastSettingsFileCheck := TickCount;
      if FileAge(ExeDir+SETTINGS_FILE) <> fSettingsLastModified then
      begin
        fEventHandler.ServerStatusMessage('Reloading updated settings from '+ExeDir+SETTINGS_FILE);
        fSettings.ReloadSettings;
        fSettingsLastModified := FileAge(ExeDir+SETTINGS_FILE);
        fDedicatedServer.UpdateSettings(fSettings.ServerName,
                                        fSettings.AnnounceServer,
                                        fSettings.AutoKickTimeout,
                                        fSettings.PingInterval,
                                        fSettings.MasterAnnounceInterval,
                                        fSettings.MasterServerAddress,
                                        fSettings.HTMLStatusFile,
                                        fSettings.ServerWelcomeMessage);
      end;
    end;
    //In Lazarus LNet will wait for 1ms in CallAction for the OS to respond with socket events
    //so we don't need to do ProcessMessage or Sleep here.
    {$IFDEF WDC}
    MyProcessMessages; //This will process network (or other) events
    Sleep(1); //Don't hog CPU (this can also be used to create an artifical latency)
    {$ENDIF}
  end;
end;

{$IFDEF FPC}
function GetExceptionCallStack:string;
var I: Integer; p: pointer;<commit_msg>Fixed timing in dedicated server itself<commit_after>program KaM_DedicatedServer;
{$I ..\..\KaM_Remake.inc}

{$IFDEF MSWindows}
  {$APPTYPE CONSOLE}
{$ENDIF}

uses
  {$IFDEF UNIX} cthreads, {$ENDIF} //We use a thread for deleting old log files
  SysUtils,
  {$IFDEF MSWindows} Windows, MMSystem, {$ENDIF}
  KM_Utils,
  KM_Defaults,
  KM_Log,
  KM_Settings,
  KM_DedicatedServer,
  KM_ServerEventHandler in 'KM_ServerEventHandler.pas';

var
  fEventHandler: TKMServerEventHandler;
  fDedicatedServer: TKMDedicatedServer;
  fSettings: TGameSettings;
  fSettingsLastModified: integer;
  fLastSettingsFileCheck: Cardinal;

{$IFDEF WDC}
procedure MyProcessMessages;
var Msg: TMsg;
begin
  while PeekMessage(Msg, 0, 0, 0, 0) do
  begin
    GetMessage(Msg, 0, 0, 0);
    TranslateMessage(Msg);
    DispatchMessage(Msg);
  end;
end;
{$ENDIF}

procedure RunTheServer;
begin
  fDedicatedServer := TKMDedicatedServer.Create(fSettings.MaxRooms,
                                                fSettings.AutoKickTimeout,
                                                fSettings.PingInterval,
                                                fSettings.MasterAnnounceInterval,
                                                fSettings.MasterServerAddress,
                                                fSettings.HTMLStatusFile,
                                                fSettings.ServerWelcomeMessage);
  fDedicatedServer.OnMessage := fEventHandler.ServerStatusMessage;
  fDedicatedServer.Start(fSettings.ServerName, fSettings.ServerPort, fSettings.AnnounceServer);

  while True do
  begin
    fDedicatedServer.UpdateState;
    //Reload the INI file if it has changed, by checking the file age every 5 seconds
    if GetTimeSince(fLastSettingsFileCheck) >= 5000 then
    begin
      fLastSettingsFileCheck := TimeGet;
      if FileAge(ExeDir+SETTINGS_FILE) <> fSettingsLastModified then
      begin
        fEventHandler.ServerStatusMessage('Reloading updated settings from '+ExeDir+SETTINGS_FILE);
        fSettings.ReloadSettings;
        fSettingsLastModified := FileAge(ExeDir+SETTINGS_FILE);
        fDedicatedServer.UpdateSettings(fSettings.ServerName,
                                        fSettings.AnnounceServer,
                                        fSettings.AutoKickTimeout,
                                        fSettings.PingInterval,
                                        fSettings.MasterAnnounceInterval,
                                        fSettings.MasterServerAddress,
                                        fSettings.HTMLStatusFile,
                                        fSettings.ServerWelcomeMessage);
      end;
    end;
    //In Lazarus LNet will wait for 1ms in CallAction for the OS to respond with socket events
    //so we don't need to do ProcessMessage or Sleep here.
    {$IFDEF WDC}
    MyProcessMessages; //This will process network (or other) events
    Sleep(1); //Don't hog CPU (this can also be used to create an artifical latency)
    {$ENDIF}
  end;
end;

{$IFDEF FPC}
function GetExceptionCallStack:string;
var I: Integer; p: pointer;
{'fraction_non_alphanumeric': 0.07200252087600441, 'fraction_numerical': 0.0050417520088230664, 'mean_word_length': 2.133267522211254, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 38, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4617341', 'n_tokens_mistral': 1742, 'n_tokens_neox': 1656, 'n_words': 425}