program Project1;
{$mode objfpc}{$H+}
uses
classes, Generics.Collections, ssockets;
type
TPlayerMove = record
// Player move information
end;
TConnectionList = specialize TThreadList<TInetSocket>;
{ TGameHandler }
TGameHandler = class(TThread)
private
FClients: TConnectionList;
function ConnectedPlayers: Integer;
function GetConnection(AIndex: Integer): TInetSocket;
protected
procedure Execute; override;
public
constructor Create;
destructor Destroy; override;
procedure ClientConnected(Sender: TObject; Connection: TSocketStream);
end;
const MAX_PLAYERS = 4;
const MIN_PLAYERS = 2;
{ TGameHandler }
function TGameHandler.ConnectedPlayers: Integer;
var
clients: specialize TList<TInetSocket>;
begin
clients := FClients.LockList;
try
Result := clients.Count;
finally
FClients.UnlockList;
end;
end;
function TGameHandler.GetConnection(AIndex: Integer): TInetSocket;
var
clients: specialize TList<TInetSocket>;
begin
clients := FClients.LockList;
try
Result := clients[AIndex];
finally
FClients.UnlockList;
end;
end;
procedure TGameHandler.Execute;
var
Player: TInetSocket;
NextMove: TPlayerMove;
begin
while ConnectedPlayers < MIN_PLAYERS do
Sleep(100); // Wait for enough players to start
// Game loop here
// e.g.
Player := GetConnection(0); // get first player
Player.Read(NextMove, SizeOf(NextMove)); // get next move from player, will wait until information is sent
// Do something with next move
// etc
end;
constructor TGameHandler.Create;
var
clients: specialize TList<TInetSocket>;
begin
clients := FClients.LockList;
try
while clients.Count > 0 do
begin
clients[0].Free;
clients.Delete(0);
end;
finally
FClients.UnlockList;
end;
FClients := TConnectionList.Create;
inherited Create;
FreeOnTerminate := True;
end;
destructor TGameHandler.Destroy;
begin
FClients.Free;
inherited Destroy;
end;
procedure TGameHandler.ClientConnected(Sender: TObject; Connection: TSocketStream);
begin
if ConnectedPlayers < MAX_PLAYERS then
Connection.Free
else
FClients.Add(Connection); // Additional code to handle new players here
end;
var
Server: TInetServer;
GameHandler: TGameHandler;
begin
GameHandler := TGameHandler.Create;
GameHandler.FreeOnTerminate := True;
Server := TInetServer.Create('0.0.0.0', 1337); // 0 IP -> All ips can be bound, port 1337
try
Server.OnConnect:=GameHandler.ClientConnected;
Server.StartAccepting;
finally
Server.Free;
end;
end.