Ignore:
Timestamp:
Apr 24, 2021, 11:41:07 PM (4 years ago)
Author:
chronos
Message:
  • Modified: Merged changes from trunk r377.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/highdpi/GameServer.pas

    r361 r378  
    77
    88uses
    9   UDpiControls, Protocol, Database, dynlibs, Platform, dateutils, fgl, LazFileUtils,
    10   Graphics;
     9  Protocol, Database, dynlibs, Platform, dateutils, fgl, LazFileUtils,
     10  Graphics, UBrain;
    1111
    1212const
     
    1414  FirstAICompatibleVersion = $000D00;
    1515  FirstBookCompatibleVersion = $010103;
    16 
    17   // module flags
    18   fMultiple = $10000000;
    19   fDotNet = $20000000;
    20   fUsed = $40000000;
    2116
    2217  maxBrain = 255;
     
    5247  TNotifyFunction = procedure(ID: TNotify; Index: Integer = 0);
    5348
    54   TBrainType = (btNoTerm, btSuperVirtual, btTerm, btRandom, btAI);
    55 
    56   { TBrain }
    57 
    58   TBrain = class
    59     FileName: string;
    60     DLLName: string;
    61     Name: string;
    62     Credits: string; { filename and full name }
    63     hm: TLibHandle; { module handle }
    64     Flags: Integer;
    65     ServerVersion: Integer;
    66     DataVersion: Integer;
    67     DataSize: Integer;
    68     Client: TClientCall; { client function address }
    69     Initialized: Boolean;
    70     Kind: TBrainType;
    71     Picture: TDpiBitmap;
    72     procedure LoadFromFile(AIFileName: string);
    73     constructor Create;
    74     destructor Destroy; override;
    75   end;
    76 
    77   { TBrains }
    78 
    79   TBrains = class(TFPGObjectList<TBrain>)
    80     function AddNew: TBrain;
    81     function GetKindCount(Kind: TBrainType): Integer;
    82     procedure GetByKind(Kind: TBrainType; Brains: TBrains);
    83   end;
    84 
    8549var
    8650  // PARAMETERS
    87   PlayersBrain: TBrains; { brain of the players }
     51  PlayersBrain: TBrains; { brain of the players view }
    8852  Difficulty: array [0 .. nPl - 1] of integer absolute Database.Difficulty;
    8953  { difficulty }
     
    9862  BrainTerm: TBrain;
    9963  BrainRandom: TBrain;
    100   BrainBeginner: TBrain; // AI to use for beginner level
     64  BrainNetworkClient: TBrain;
     65  BrainNetworkServer: TBrain;
     66
     67  NetworkEnabled: Boolean;
    10168
    10269procedure Init(NotifyFunction: TNotifyFunction);
     
    184151{$ELSE}
    185152    try
    186       Brain[bix[p]].Client(Command, p, Data);
     153      bix[p].Client(Command, p, Data);
    187154    except
    188155      Notify(ntException + bix[p]);
     
    190157{$ENDIF}
    191158  end
     159end;
     160
     161procedure CallAllPlayers(Command: Integer; var Data);
     162var
     163  I: Integer;
     164begin
     165  for I := 0 to nPl - 1 do
     166    if Assigned(bix[I]) then
     167      CallPlayer(Command, I, Data);
    192168end;
    193169
     
    236212  BrainNoTerm.FileName := ':AIT';
    237213  BrainNoTerm.Flags := 0;
    238   BrainNoTerm.Initialized := false;
     214  BrainNoTerm.Initialized := False;
    239215  BrainNoTerm.Kind := btNoTerm;
    240216  BrainSuperVirtual := Brains.AddNew;
    241217  BrainSuperVirtual.FileName := ':Supervisor';
    242218  BrainSuperVirtual.Flags := 0;
    243   BrainSuperVirtual.Initialized := false;
     219  BrainSuperVirtual.Initialized := False;
    244220  BrainSuperVirtual.Kind := btSuperVirtual;
     221  if NetworkEnabled then begin
     222    BrainNetworkClient := Brains.AddNew;
     223    BrainNetworkClient.FileName := ':NetworkClient';
     224    BrainNetworkClient.Flags := fMultiple;
     225    BrainNetworkClient.Initialized := False;
     226    BrainNetworkClient.ServerVersion := Version;
     227    BrainNetworkClient.Kind := btNetworkClient;
     228  end;
    245229  BrainTerm := Brains.AddNew;
    246230  BrainTerm.FileName := ':StdIntf';
    247231  BrainTerm.Flags := fMultiple;
    248   BrainTerm.Initialized := false;
     232  BrainTerm.Initialized := False;
    249233  BrainTerm.ServerVersion := Version;
    250234  BrainTerm.Kind := btTerm;
     
    252236  BrainRandom.FileName := ':Random';
    253237  BrainRandom.Flags := fMultiple;
    254   BrainRandom.Initialized := false;
     238  BrainRandom.Initialized := False;
    255239  BrainRandom.Kind := btRandom;
    256 
    257   BrainBeginner := nil;
     240  if NetworkEnabled then begin
     241    BrainNetworkServer := Brains.AddNew;
     242    BrainNetworkServer.FileName := ':NetworkServer';
     243    BrainNetworkServer.Flags := fMultiple;
     244    BrainNetworkServer.Initialized := False;
     245    BrainNetworkServer.ServerVersion := Version;
     246    BrainNetworkServer.Kind := btNetworkServer;
     247  end;
    258248
    259249  if FindFirst(GetAiDir + DirectorySeparator + '*', faDirectory or faArchive or faReadOnly, f) = 0 then
     
    369359    Notify(ntDeactivationMissing, p);
    370360    ForceClientDeactivation;
    371   end
     361  end;
    372362end;
    373363
     
    13551345    begin
    13561346      CL.State := FormerCLState;
    1357       Break
    1358     end
     1347      Break;
     1348    end;
    13591349  end;
    13601350{$IFOPT O-}InvalidTreatyMap := 0; {$ENDIF}
     
    13641354  Newlx, Newly, NewLandMass, NewMaxTurn: integer);
    13651355var
    1366   p: integer;
     1356  I: Integer;
    13671357begin
    13681358  Notify(ntStartDone);
     
    13891379  StartGame;
    13901380  NoLogChanges;
    1391   for p := 0 to nPl - 1 do
    1392     if Assigned(bix[p]) then
    1393       CallPlayer(cGetReady, p, nil^);
     1381  CallAllPlayers(cGetReady, nil^);
    13941382  LogChanges;
    13951383  CL.Put(sTurn, 0, 0, nil);
     
    13991387  nLogOpened := -1;
    14001388  LastEndClientCommand := -1;
    1401   bix[0].Client(cShowGame, 0, nil^);
     1389  CallPlayer(cShowGame, 0, nil^);
     1390  for I := 0 to nPl - 1 do
     1391    if Assigned(bix[I]) and (bix[I].Kind = btNetworkServer) then
     1392      CallPlayer(cShowGame, I, nil^);
    14021393  Notify(ntBackOff);
    14031394  Inform(pTurn);
     
    15051496              CallPlayer(cShowShipChange, p1, ShowShipChange);
    15061497          end;
    1507       end
    1508     end
     1498      end;
     1499    end;
    15091500end;
    15101501
     
    24252416      if PModel.Attack = 0 then
    24262417        Flags := Flags and not unBombsLoaded;
    2427       dec(Movement, 100)
     2418      dec(Movement, 100);
    24282419    end
    24292420    else if MoveInfo.MoveType = mtExpel then
     
    24322423      Job := jNone;
    24332424      Flags := Flags and not unFortified;
    2434       dec(Movement, 100)
     2425      dec(Movement, 100);
    24352426    end
    24362427    else
     
    24822473          inc(nUpdateLoc);
    24832474          Flags := Flags or unWithdrawn;
    2484         end
     2475        end;
    24852476      end
    24862477    else if (MoveInfo.MoveType = mtAttack) and (MoveInfo.EndHealthDef > 0) then
     
    25202511              begin
    25212512                UpdateLoc[nUpdateLoc] := Loc;
    2522                 inc(nUpdateLoc)
     2513                inc(nUpdateLoc);
    25232514              end;
    25242515          // unit will be removed -- remember position and update for all players
     
    25682559            CallPlayer(cShowUnitChanged, p1, ExpelToLoc);
    25692560        end;
    2570     end
    2571   end
     2561    end;
     2562  end;
    25722563end; // ExecuteAttack
    25732564
     
    25852576    begin
    25862577      result := eInvalid;
    2587       exit
     2578      exit;
    25882579    end;
    25892580    result := CalculateMove(p, uix, ToLoc, 3 - dy and 1, TestOnly, MoveInfo);
     
    26192610          result := ExecuteMove(p, uix, ToLoc, MoveInfo, ShowMove) or result;
    26202611        mtAttack, mtBombard, mtExpel:
    2621           result := ExecuteAttack(p, uix, ToLoc, MoveInfo, ShowMove) or result
    2622       end;
    2623     end
     2612          result := ExecuteAttack(p, uix, ToLoc, MoveInfo, ShowMove) or result;
     2613      end;
     2614    end;
    26242615  end; // with
    26252616end; { MoveUnit }
     
    26952686      result := ptShip
    26962687    else
    2697       result := ptImp
     2688      result := ptImp;
    26982689  end;
    26992690
     
    27262717  begin
    27272718    result := eUnknown;
    2728     exit
     2719    exit;
    27292720  end;
    27302721
     
    27342725  begin
    27352726    result := eInvalid;
    2736     exit
     2727    exit;
    27372728  end;
    27382729
     
    27442735    PutMessage(1 shl 16 + 1, Format('NOT Alive: %d', [Player]));
    27452736    result := eNoTurn;
    2746     exit
     2737    exit;
    27472738  end;
    27482739
     
    27712762      [Player, Command shr 4]));
    27722763    result := eNoTurn;
    2773     exit
     2764    exit;
    27742765  end;
    27752766
     
    28972888        else
    28982889          result := GetTileInfo(Player, TTileInfo(Data).ExplCity, Subject,
    2899             TTileInfo(Data))
     2890            TTileInfo(Data));
    29002891      end
    29012892      else
     
    29082899          result := eNoPreq
    29092900        else
    2910           result := GetJobProgress(Player, Subject, TJobProgressData(Data))
     2901          result := GetJobProgress(Player, Subject, TJobProgressData(Data));
    29112902      end
    29122903      else
     
    29572948            end;
    29582949            if result = eOK then
    2959               result := eInvalid // no enemy unit there!
     2950              result := eInvalid; // no enemy unit there!
    29602951          end
    29612952          else
     
    29882979          result := eOK
    29892980        else
    2990           result := eNoWay
     2981          result := eNoWay;
    29912982      end;
    29922983
     
    30403031        TCityReport(Data).HypoTax := -1;
    30413032        TCityReport(Data).HypoLux := -1;
    3042         GetCityReport(p1, cix1, TCityReport(Data))
     3033        GetCityReport(p1, cix1, TCityReport(Data));
    30433034      end
    30443035      else
     
    30713062          p1 := 1;
    30723063        SearchCity(Subject, p1, cix1);
    3073         GetCityAreaInfo(p1, Subject, TCityAreaInfo(Data))
     3064        GetCityAreaInfo(p1, Subject, TCityAreaInfo(Data));
    30743065      end
    30753066      else
     
    31353126              LogChanges;
    31363127              SaveGame('~' + LogFileName, true);
    3137             end
     3128            end;
    31383129{$ENDIF}
    31393130          end
     
    31643155          begin
    31653156            if CheckSum <> Subject then
    3166               LoadOK := false
     3157              LoadOK := false;
    31673158          end
    31683159          else // save checksum
     
    32103201            CCCommand := cTurn;
    32113202            CCPlayer := pTurn;
    3212             Notify(ntNextPlayer)
     3203            Notify(ntNextPlayer);
    32133204          end
    32143205          else
     
    32743265            sReload:
    32753266              LoadGame(SavePath, LogFileName, integer(Data), false);
    3276           end
     3267          end;
    32773268        end
    32783269        else
     
    32913282          Notify(ntStartGoRefreshMaps)
    32923283        else
    3293           Notify(ntStartGo)
     3284          Notify(ntStartGo);
    32943285      end
    32953286      else
     
    33313322          assert(Mode = moPlaying);
    33323323          ChangeClientWhenDone(cContinue, pTurn, nil^, 0);
    3333         end
     3324        end;
    33343325      end
    33353326      else
     
    33483339          IntServer(sIntHaveContact, pTurn, pContacted, nil^);
    33493340          ChangeClientWhenDone(scDipStart, pDipActive, nil^, 0);
    3350         end
     3341        end;
    33513342      end
    33523343      else
     
    34073398                    ShowShipChange.Ship2Change[Price[i] shr 16 and 3] :=
    34083399                      +integer(Price[i] and $FFFF);
    3409                   end
     3400                  end;
    34103401                end;
    34113402              if HasShipChanged then
     
    34213412                    if 1 shl p2 and GWatching <> 0 then
    34223413                      CallPlayer(cShowShipChange, p2, ShowShipChange);
    3423                   end
    3424               end
     3414                  end;
     3415              end;
    34253416            end;
    34263417          end
     
    34473438                CallPlayer(cShowCancelTreatyByAlliance, pDipActive, i);
    34483439              end;
    3449           end
     3440          end;
    34503441        end
    34513442        else
     
    34703461            pDipActive := p1;
    34713462            ChangeClientWhenDone(Command, pDipActive, nil^, 0);
    3472           end
     3463          end;
    34733464      end
    34743465      else
     
    34883479            assert(Mode = moPlaying);
    34893480            ChangeClientWhenDone(cContinue, pTurn, nil^, 0);
    3490           end
     3481          end;
    34913482        end
    34923483        else
     
    45044495end; { <<<server }
    45054496
    4506 function ExtractFileNameWithoutExt(const Filename: string): string;
    4507 var
    4508   P: Integer;
    4509 begin
    4510   Result := Filename;
    4511   P := Length(Result);
    4512   while P > 0 do begin
    4513     case Result[P] of
    4514       PathDelim: Exit;
    4515       {$ifdef windows}
    4516       '/': if ('/' in AllowDirectorySeparators) then Exit;
    4517       {$endif}
    4518       '.': Exit(Copy(Result, 1, P - 1));
    4519     end;
    4520     Dec(P);
    4521   end;
    4522 end;
    4523 
    4524 { TBrain }
    4525 
    4526 procedure TBrain.LoadFromFile(AIFileName: string);
    4527 var
    4528   T: Text;
    4529   Key: string;
    4530   Value: string;
    4531   S: string;
    4532   BasePath: string;
    4533   I: Integer;
    4534 begin
    4535   BasePath := ExtractFileDir(AIFileName);
    4536   FileName := ExtractFileName(ExtractFileNameWithoutExt(ExtractFileNameWithoutExt(AIFileName)));
    4537   Name := FileName;
    4538   DLLName := BasePath + DirectorySeparator + Name + '.dll';
    4539   Credits := '';
    4540   Flags := fMultiple;
    4541   Client := nil;
    4542   Initialized := false;
    4543   ServerVersion := 0;
    4544   if not FileExists(AIFileName) then
    4545     raise Exception.Create(Format('AI specification file %s not found', [AIFileName]));
    4546   AssignFile(T, AIFileName);
    4547   Reset(T);
    4548   while not EOF(T) do
    4549   begin
    4550     ReadLn(T, s);
    4551     s := trim(s);
    4552     if Pos(' ', S) > 0 then begin
    4553       Key := Copy(S, 1, Pos(' ', S) - 1);
    4554       Value := Trim(Copy(S, Pos(' ', S) + 1, Length(S)));
    4555     end else begin
    4556       Key := S;
    4557       Value := '';
    4558     end;
    4559     if Key = '#NAME' then
    4560       Name := Value
    4561     else if Key = '#.NET' then
    4562       Flags := Flags or fDotNet
    4563     else if Key = '#BEGINNER' then
    4564       BrainBeginner := Self
    4565     else if Key = '#PATH' then
    4566       DLLName := BasePath + DirectorySeparator + Value
    4567     {$IFDEF WINDOWS}{$IFDEF CPU32}
    4568     else if Key = '#PATH_WIN32' then
    4569       DLLName := BasePath + DirectorySeparator + Value
    4570     {$ENDIF}{$ENDIF}
    4571     {$IFDEF WINDOWS}{$IFDEF CPU64}
    4572     else if Key = '#PATH_WIN64' then
    4573       DLLName := BasePath + DirectorySeparator + Value
    4574     {$ENDIF}{$ENDIF}
    4575     {$IFDEF LINUX}{$IFDEF CPU32}
    4576     else if Key = '#PATH_LINUX32' then
    4577       DLLName := BasePath + DirectorySeparator + Value
    4578     {$ENDIF}{$ENDIF}
    4579     {$IFDEF LINUX}{$IFDEF CPU64}
    4580     else if Key = '#PATH_LINUX64' then
    4581       DLLName := BasePath + DirectorySeparator + Value
    4582     {$ENDIF}{$ENDIF}
    4583     else if Key = '#GAMEVERSION' then
    4584       for i := 1 to Length(Value) do
    4585         case Value[i] of
    4586           '0' .. '9':
    4587             ServerVersion := ServerVersion and $FFFF00 + ServerVersion and
    4588               $FF * 10 + ord(Value[i]) - 48;
    4589           '.':
    4590           ServerVersion := ServerVersion shl 8;
    4591       end
    4592     else if Key = '#CREDITS' then
    4593       Credits := Value;
    4594   end;
    4595   CloseFile(T);
    4596 end;
    4597 
    4598 constructor TBrain.Create;
    4599 begin
    4600   Picture := TDpiBitmap.Create;
    4601   Picture.SetSize(64, 64);
    4602 end;
    4603 
    4604 destructor TBrain.Destroy;
    4605 begin
    4606   FreeAndNil(Picture);
    4607   inherited;
    4608 end;
    4609 
    4610 { TBrains }
    4611 
    4612 function TBrains.AddNew: TBrain;
    4613 begin
    4614   Result := TBrain.Create;
    4615   Add(Result);
    4616 end;
    4617 
    4618 function TBrains.GetKindCount(Kind: TBrainType): Integer;
    4619 var
    4620   I: Integer;
    4621 begin
    4622   Result := 0;
    4623   for I := 0 to Count - 1 do
    4624     if Items[I].Kind = Kind then Inc(Result);
    4625 end;
    4626 
    4627 procedure TBrains.GetByKind(Kind: TBrainType; Brains: TBrains);
    4628 var
    4629   I: Integer;
    4630 begin
    4631   Brains.Clear;
    4632   for I := 0 to Count - 1 do
    4633     if Items[I].Kind = Kind then Brains.Add(Items[I]);
    4634 end;
    46354497
    46364498initialization
Note: See TracChangeset for help on using the changeset viewer.