Author Topic: IRC Communication  (Read 2774 times)

0 Members and 1 Guest are viewing this topic.

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
IRC Communication
« on: July 05, 2007, 06:12:06 pm »
Script Name: IRC Communication
Script Description: Easy to use IRC - SS communication. Constants help choose what the installer prefers.
Original Author: Curt (DorkeyDear)
Core Version: 2.6.1b
Code:
Code: [Select]
const
  IRC_Enabled = true;
  IRC_Server_IP = 'irc.quakenet.org';
  IRC_Server_Port = 6667;
  IRC_Server_Password = '';
  IRC_Nickname = 'Curt-IRC-Bot';
  IRC_Channel = '#soldat.testing';
  IRC_Color = 10;
  IRC_Color_DM = 0;
  IRC_Color_Spectator = 7;
  SS_Color = $FFEF8282;
  NumTeams = 2; {Will be auto next version, i became lazy}

//Allowed messages
  IRCtoSS_Chat = true;
  IRCtoSS_Join = true;
  IRCtoSS_Leave = true;
  SStoIRC_Chat = true;
  SStoIRC_Command = false;
  SStoIRC_Command_File = '';
  SStoIRC_Command_Say = true;
  SStoIRC_Join = true;
  SStoIRC_Join_Color = false;
  SStoIRC_Leave = true;
  SStoIRC_MapChange = true;
  SStoIRC_Capture = false;
  SStoIRC_Capture_Who = false;
  SStoIRC_Capture_Color = false;
  SStoIRC_Grab = false;
  SStoIRC_Grab_For = false;
  SStoIRC_Grab_Base = false;
  SStoIRC_Grab_Color = false;
  SStoIRC_Return = false;
  SStoIRC_Return_Color = false;
  SStoIRC_Kill = false;
  SStoIRC_Kill_Weapon = false;
  SStoIRC_Kill_Color = false;
  SStoIRC_Request = false;
  SStoIRC_Request_State = false;

  IRC_Scores = true;
  IRC_Status = true;
  IRC_Players = true;
  IRC_Players_Color = true;

var
  IRC_Index: integer;
  IRC_FirstFinished: boolean;
  SocketIndex: integer;
  SocketConnected: array of boolean;

  Commands: tstringarray;
  JoinGame: array[1..32] of boolean;

function Split(const Source: string; const Delimiter: string):TStringArray;
var
i,x,d:integer;
s:string;
begin
  d := Length(Delimiter);
  x := 0;
  i := 1;
  SetArrayLength(Result,1);
  while i <= Length(source) do begin
    s := Copy(Source,i,d);
    if s = Delimiter then begin
      Inc(i,d);
      Inc(x,1);
      SetArrayLength(result,x + 1);
    end else begin
      Result[x] := Result[x] + Copy(s,1,1);
      Inc(i,1);
    end;
  end;
end;

function SectoTime(Seconds: integer): string;
var
  m,a,s: string;
begin
  m := iif((Seconds / 60) - ((Seconds mod 60) / 60) = 1,'1 minute',iif((Seconds / 60) - ((Seconds mod 60) / 60) > 1,InttoStr((Seconds / 60) - ((Seconds mod 60) / 60)) + ' minutes',''));
  s := iif(Seconds mod 60 = 1,'1 second',iif(Seconds mod 60 > 1,InttoStr(Seconds mod 60) + ' seconds',''));
  if (m <> '') and (s <> '') then a := ' and ';
  Result := m + a + s;
end;

function PlayerCount(Team: shortint): byte;
var
  i: byte;
begin
  for i := 1 to 32 do if (GetPlayerStat(i,'Active') = true) and ((Team = -1) or (GetPlayerStat(i,'Team') = Team)) then Result := Result + 1;
end;

function FixType(Value: integer): integer;
begin
  Result := StrtoInt(InttoStr(Value));
end;

function StatetoMeaning(State: integer): string;
begin
  Case State of
    1: Result := 'Ok';
    2: Result := 'Wrong version';
    3: Result := 'Wrong password';
    4: Result := 'Banned';
    5: Result := 'Server full';
    6: Result := 'Duplicate IP';
  end;
end;

function IRCColorFix(Value: integer): string;
begin
  if (Value > -10) and (Value < 10) then Result := '0' + InttoStr(Value) else Result := InttoStr(Value);
end;

function TeamtoIRCColor(Team: byte): byte;
begin
  Case Team of
    0: Result := IRC_Color_DM;
    1: Result := 4;
    2: Result := 12;
    3: Result := 8;
    4: Result := 3;
    5: Result := IRC_Color_Spectator;
  end;
end;

function TeamtoTeamName(Team: byte): string;
begin
  Case Team of
    0: Result := 'DM';
    1: Result := 'Alpha';
    2: Result := 'Bravo';
    3: Result := 'Charlie';
    4: Result := 'Delta';
    5: Result := 'Spectator';
  end;
end;

procedure IRC_OnPING(Index: integer; Tick: string; FromUser: boolean);
begin
  SendData(Index,'PONG :' + Tick + Chr(13) + Chr(10));
  WriteLn('[IRC] PONG');
  if IRC_FirstFinished = false then begin
    SendData(Index,'USER guest a b :Soldat Server' + Chr(13) + Chr(10));
    SendData(Index,'JOIN ' + IRC_Channel + Chr(13) + Chr(10));
    IRC_FirstFinished := true;
  end;
end;

procedure IRC_Chat(Channel, Text: string);
begin
  if (IRC_Index = 0) or (SocketConnected[IRC_Index] = false) then exit else SendData(IRC_Index,'PRIVMSG ' + Channel + ' :' + Chr(1) + 'ACTION ' + Text + Chr(13) + Chr(10));
end;

procedure IRC_OnPRIVMSG(Nickname, Message: string);
var
  i,j: byte;
  BuildB: string;
  Build: array[0..5] of string;
begin
  if Copy(Nickname,1,3) <> 'SS-' then begin
    if IRCtoSS_Chat then WriteConsole(0,'[IRC|' + Nickname + '] ' + Message,SS_Color);
    if (IRC_Scores) and (ContainsString(LowerCase(Message),'scores')) and (NumTeams > 0) then IRC_Chat(IRC_Channel,'The scores are: ' + iif(NumTeams >= 1,Chr(3) + IRCColorFix(TeamtoIRCColor(1)) + InttoStr(AlphaScore),'') + iif(NumTeams >= 2,Chr(15) + ', ' + Chr(3) + IRCColorFix(TeamtoIRCColor(2)) + InttoStr(BravoScore),'') + iif(NumTeams >= 3,Chr(15) + ', ' + Chr(3) + IRCColorFix(TeamtoIRCColor(3)) + InttoStr(CharlieScore),'') + iif(NumTeams >= 4,Chr(15) + ', ' + Chr(3) + IRCColorFix(TeamtoIRCColor(4)) + InttoStr(DeltaScore),'') + Chr(15) + '.');
    if (IRC_Status) and (ContainsString(LowerCase(Message),'status')) then IRC_Chat(IRC_Channel,'The status is that there are ' + Chr(3) + IRCColorFix(IRC_Color) + InttoStr(NumPlayers) + Chr(15) + ' / ' + Chr(3) + IRCColorFix(IRC_Color) + InttoStr(MaxPlayers) + Chr(15) + ' people with ' + Chr(3) + IRCColorFix(IRC_Color) + SectoTime(TimeLeft) + Chr(15) + ' / ' + Chr(3) + IRCColorFix(IRC_Color) + SectoTime(TimeLimit * 60) + Chr(15) + ' remaining on ' + Chr(3) + IRCColorFix(IRC_Color) + CurrentMap + Chr(15) + '.');
    if (IRC_Players) and ((ContainsString(LowerCase(Message),'people')) or (ContainsString(LowerCase(Message),'players'))) then begin
      if NumPlayers = 0 then BuildB := 'There is nobody in the server.' else begin
        BuildB := 'There are ';
        for i := 0 to 5 do if ((i <= NumTeams) and (i <> 0)) or (PlayerCount(i) > 0) then BuildB := BuildB + Chr(3) + IRCColorFix(TeamtoIRCColor(i)) + InttoStr(PlayerCount(i)) + Chr(15) + ', ';
        BuildB := Copy(BuildB,1,Length(BuildB) - 2) + ' people in the server.';
      end;
      IRC_Chat(IRC_Channel,BuildB);
      for i := 1 to 32 do if GetPlayerStat(i,'Active') then Build[FixType(GetPlayerStat(i,'Team'))] := Build[FixType(GetPlayerStat(i,'Team'))] + iif(Build[FixType(GetPlayerStat(i,'Team'))] = '','',', ') + GetPlayerStat(i,'Name');
      for i := 0 to 5 do if Build[i] <> '' then IRC_Chat(IRC_Channel,iif(IRC_Players_Color,Chr(3) + IRCColorFix(TeamtoIRCColor(i)),'') + TeamtoTeamName(i) + Chr(15) + ' players include: ' + Build[i]);
    end;
  end;
end;

procedure IRC_OnJOIN(Nickname: string);
begin
  if IRCtoSS_Join then WriteConsole(0,Nickname + ' has joined the IRC channel.',SS_Color);
end;

procedure IRC_OnPART(Nickname: string);
begin
  if IRCtoSS_Leave then WriteConsole(0,Nickname + ' has left the IRC channel.',SS_Color);
end;

procedure IRC_OnQUIT(Nickname, Reason: string);
begin
  if IRCtoSS_Leave then WriteConsole(0,Nickname + ' has disconnected. (' + Reason + ')',SS_Color);
end;

procedure OnDataReceived(Index: Integer; Buffer: String);
var
  Chan: boolean;
begin
  if (Index = 0) or (SocketConnected[Index] = false) then exit else begin
    WriteLn('[IRC] ' + Buffer);
    if Buffer = 'NOTICE AUTH :*** Checking Ident' then begin
      IRC_Index := Index;
      if IRC_Server_Password <> '' then SendData(Index,'PASS ' + IRC_Server_Password + Chr(13) + Chr(10));
      if (IRC_Index <> 0) and (SocketConnected[IRC_Index]) then SendData(IRC_Index,'NICK ' + IRC_Nickname + Chr(13) + Chr(10));
    end;
    if GetPiece(Buffer,' ',0) = 'PING' then IRC_OnPING(Index,Copy(Buffer,7,Length(Buffer)),false);
    if GetPiece(Buffer,' ',2) = IRC_Channel then Chan := true;
    Case GetPiece(Buffer,' ',1) of
      'PRIVMSG': if Chan then IRC_OnPRIVMSG(Copy(Buffer,2,StrPos('!',Buffer) - 2),Copy(Buffer,Length(GetPiece(Buffer,' ',0)) + Length(GetPiece(Buffer,' ',1)) + Length(GetPiece(Buffer,' ',2)) + 5,Length(Buffer)));
      'JOIN': if Chan then IRC_OnJOIN(Copy(Buffer,2,StrPos('!',Buffer) - 2));
      'PART': if Chan then IRC_OnPART(Copy(Buffer,2,StrPos('!',Buffer) - 2));
      'QUIT': IRC_OnQUIT(Copy(Buffer,2,StrPos('!',Buffer) - 2),Copy(Buffer,Length(GetPiece(Buffer,' ',0)) + Length(GetPiece(Buffer,' ',1)) + 4,Length(Buffer)));
    end;
  end;
end;

procedure MainSocketLoop(Index: Integer);
var
  Buff: String;
begin
  while SocketConnected[Index] do begin
    ReadLnSocket(Index,Buff);
    if Buff <> '' then OnDataReceived(Index,Buff);
    sleep(1);
  end;
end;

procedure OnConnected(Index: Integer);
begin
  SetArrayLength(SocketConnected,GetArrayLength(SocketConnected)+2);
  ThreadFunc([Index],'MainSocketLoop');
  SocketConnected[GetArrayLength(SocketConnected) - 1] := true;
end;

procedure OnDisconnected(Index: Integer);
begin
  SocketConnected[GetArrayLength(SocketConnected) - 1] := false;
end;

procedure ThreadedCreate(IP: String;Port: Integer;var IndexVar: Integer);
begin
  ConnectSocket(IP,Port,IndexVar);
  OnConnected(IndexVar);
end;

procedure CreateSocket(IP: String;Port: Integer);
begin
  ThreadFunc([IP,Port,SocketIndex],'ThreadedCreate');
end;

procedure ActivateServer();
begin
  if IRC_Enabled then CreateSocket(IRC_Server_IP,IRC_Server_Port);
  if SStoIRC_Command_File <> '' then Commands := Split(ReadFile(SStoIRC_Command_File),Chr(13) + Chr(10));
end;

function OnCommand(ID: Byte; Text: string): boolean;
var
  Listed: boolean;
  i: integer;
begin
  Result := false;
  if SStoIRC_Command_File <> '' then for i := 0 to ArrayHigh(Commands) - 1 do if Copy(Text,2,Length(Commands[i])) = Commands[i] then begin
    Listed := true;
    break;
  end;
  if SStoIRC_Command_File = '' then Listed := true;
  if (SStoIRC_Command) and (Listed) then IRC_Chat(IRC_Channel,Chr(3) + IRCColorFix(IRC_Color) + GetPlayerStat(ID,'Name') + Chr(15) + ' cmd: ' + Text);
  if (SStoIRC_Command_Say) and (Copy(Text,1,5) = '/say ') then IRC_Chat(IRC_Channel,Copy(Text,6,Length(Text)));
{Commented out due to buggyness
  if Text = '/conenct' then begin
    WriteLn('Bot connected.');
    CreateSocket(IRC_Server_IP,IRC_Server_Port);
  end;
  if Text = '/disconnect' then begin
    WriteLn('Bot disconnected.');
    IRC_FirstFinished := false;
    SendData(IRC_Index,'QUIT :' + GetPlayerStat(ID,'Name') + ' disconnected bot in Soldat Server' + Chr(10) + Chr(13));
  end;}
end;

function OnRequestGame(IP: string; State: integer): integer;
begin
  if SStoIRC_Request then IRC_Chat(IRC_Channel,Chr(3) + IRCColorFix(IRC_Color) + IP + Chr(15) + ' is requesting to join the game' + iif(SStoIRC_Request_State,' with the state of ' + Chr(3) + IRCColorFix(IRC_Color) + StatetoMeaning(State) + Chr(15),'') + '.');
end;

procedure OnJoinGame(ID, Team: byte);
begin
  JoinGame[ID] := true;
end;

procedure OnJoinTeam(ID, Team: byte);
begin
  if SStoIRC_Join then IRC_Chat(IRC_Channel,Chr(3) + IRCColorFix(IRC_Color) + GetPlayerStat(ID,'Name') + iif((Team = 5) or (SStoIRC_Join_Color = false),Chr(15),Chr(3) + InttoStr(TeamtoIRCColor(Team))) + ' has ' + iif(JoinGame[ID],'joined ','changed to ') + iif((Team = 5) and (JoinGame[ID]),'as ','') + TeamtoTeamName(Team) + iif(Team = 5,',','team.'));
  JoinGame[ID] := false;
end;

procedure OnLeaveGame(ID, Team: byte; Kicked: boolean);
begin
  if SStoIRC_Leave then IRC_Chat(IRC_Channel,Chr(3) + IRCColorFix(IRC_Color) + GetPlayerStat(ID,'Name') + Chr(15) + ' has ' + iif(Kicked,'been kicked from','left') + ' the game.');
end;

procedure OnFlagGrab(ID, TeamFlag: byte; GrabbedInBase: boolean);
begin
  if (SStoIRC_Grab) and ((SStoIRC_Grab_Base = false) or (GrabbedInBase)) then IRC_Chat(IRC_Channel,Chr(3) + IRCColorFix(IRC_Color) + GetPlayerStat(ID,'Name') + iif(SStoIRC_Grab_Color,Chr(3) + IRCColorFix(TeamtoIRCColor(GetPlayerStat(ID,'Team'))),Chr(15)) + ' has grabbed the ' + TeamtoTeamName(TeamFlag) + ' flag' + iif(SStoIRC_Grab_For,' for ' + TeamtoTeamName(GetPlayerStat(ID,'Team')) + ' team.','.'));
end;

procedure OnFlagReturn(ID, TeamFlag: byte);
begin
  if SStoIRC_Return then IRC_Chat(IRC_Channel,Chr(3) + IRCColorFix(IRC_Color) + GetPlayerStat(ID,'Name') + iif(SStoIRC_Return_Color,Chr(3) + IRCColorFix(TeamtoIRCColor(TeamFlag)),Chr(15)) + ' has returned the ' + TeamtoTeamName(TeamFlag) + ' flag.');
end;

procedure OnFlagScore(ID, TeamFlag: byte);
begin
  if SStoIRC_Capture then IRC_Chat(IRC_Channel,Chr(3) + IRCColorFix(IRC_Color) + GetPlayerStat(ID,'Name') + iif(SStoIRC_Capture_Color,Chr(3) + IRCColorFix(TeamtoIRCColor(GetPlayerStat(ID,'Team'))),Chr(15)) + ' has captured the ' + iif(SStoIRC_Capture_Who,TeamtoTeamName(TeamFlag) + ' ','') + 'flag for ' + TeamtoTeamName(GetPlayerStat(ID,'Team')) + ' team.');
end;

procedure OnMapChange(NewMap: string);
begin
  if SStoIRC_MapChange then IRC_Chat(IRC_Channel,'The map has changed to ' + Chr(3) + IRCColorFix(IRC_Color) + NewMap + Chr(15) + '.');
end;

procedure OnPlayerKill(Killer, Victim: byte; Weapon: string);
begin
  if Weapon = 'Selfkill' then Weapon := 'USSOCOM'
  if SStoIRC_Kill then if Killer = Victim then IRC_Chat(IRC_Channel,Chr(3) + IRCColorFix(IRC_Color) + GetPlayerStat(Killer,'Name') + iif(SStoIRC_Kill_Color,Chr(3) + IRCColorFix(TeamtoIRCColor(GetPlayerStat(Killer,'Team'))),Chr(15)) + ' has killed himself' + iif(SStoIRC_Kill_Weapon,' using ' + Chr(3) + IRCColorFix(IRC_Color) + Weapon,'') + Chr(15) + '.') else IRC_Chat(IRC_Channel,Chr(3) + IRCColorFix(IRC_Color) + GetPlayerStat(Killer,'Name') + iif(SStoIRC_Kill_Color,Chr(3) + IRCColorFix(TeamtoIRCColor(GetPlayerStat(Killer,'Team'))),Chr(15)) + ' has killed ' + Chr(3) + IRCColorFix(IRC_Color) + GetPlayerStat(Victim,'Name') + iif(SStoIRC_Kill_Color,Chr(3) + IRCColorFix(TeamtoIRCColor(GetPlayerStat(Killer,'Team'))),Chr(15)) + iif(SStoIRC_Kill_Weapon,' using ' + Chr(3) + IRCColorFix(IRC_Color) + Weapon,'') + iif(SStoIRC_Kill_Color,Chr(3) + IRCColorFix(TeamtoIRCColor(GetPlayerStat(Killer,'Team'))),Chr(15)) + '.');
end;

procedure OnPlayerSpeak(ID: byte; Text: string);
begin
  if (SStoIRC_Chat) and (Text[1] <> '^') then begin
    IRC_Chat(IRC_Channel,Chr(3) + IRCColorFix(IRC_Color) + GetPlayerStat(ID,'Name') + Chr(15) + ': ' + Text);
  end;
end;
Future Plans:
  • removing the constants asking for the color and stuff, and adding a file where as each line will be the text that is to be said when an event happens, with both on IRC and SS.. (Ex: %K13%N%O has joined the game.)
« Last Edit: July 14, 2007, 04:55:16 pm by DorkeyDear »

Offline ManSoft|Warlord

  • Major
  • *
  • Posts: 70
  • Soldat.IDE Creator
Re: IRC Communication
« Reply #1 on: July 24, 2007, 03:20:59 am »

Offline zyxstand

  • Veteran
  • *****
  • Posts: 1106
  • Mother of all Bombs
Re: IRC Communication
« Reply #2 on: July 24, 2007, 11:00:52 am »
I have a question:
why dont' people just release a zipped file of their script folder?!
That way nobody will be confused as to where to put text and it'll be very safe.
And if someone can come up with a script combiner where you choose several folders and it combines the folders into one folder containing combined scripts, that would make EVERYTHING 10x easier!  (You can get around duplicate names by adding like _1 after a duplicate variable in multiple folders).......

On topic:
looks interesting and should be easy to use.
But question DD:
why don't you just make a .ini file from which this script reads variables that may change depending on each user.  And a /reload command or something that simply reloads the variables from the .ini file...  That would make things easier too!
Can't think of anything original to put here...

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
Re: IRC Communication
« Reply #3 on: July 24, 2007, 06:52:08 pm »
I am (semi) working on that.. :D Its been a while sense I touched that file so I don't remember where I left off.
If I ever finish, I'll post here saying that it changed.

Offline addict

  • Major(1)
  • Posts: 19
Re: IRC Communication
« Reply #4 on: October 12, 2007, 07:53:52 pm »
not working..
  • Compiling AdminColor -> AdminColor.pas...
  • Compiling irc -> irc.pas...
  • irc -> [Warning] (168:19): "True and" is not needed
  • irc -> [Error] (168:116): String error
  • irc -> [Error] (168:116): Syntax error

Offline DorkeyDear

  • Veteran
  • *****
  • Posts: 1507
  • I also go by Curt or menturi
Re: IRC Communication
« Reply #5 on: October 13, 2007, 10:04:06 am »
If I were to update  this script, I would completely redo it.. I'll start working on it, but it might come by slowly sense I have like 5 other projects. The more people poking me about working on it will speed me up.