SRL Archive - OSR Utility Scripts

Person mimicker


rj

2015-03-21 22:08:02

Person mimicker

A script Mimics what selected person says



Instructions
At the top of the script you wil see this:
const
SETUP = true;
PLAYERNAME = 'Zezima';
USECLAN = '';
If setup is set to true then when you start the script you will enter the name of the person you want to mimic. If you set setup to false then the script will use 'PLAYERNAME' as the player to mimic. You must enter the exact player name, it is case sensitive. If you want to mimic a person in a clan chat then make sure you set USECLAN to '/'. Do not use this script on your main or any account that you care about. It is a high probability that you will get muted.



Credits to @Janilabo; for the TSA function

Kyle

2015-03-21 22:45:39

From: rj
..


You have a memory leak in your chat function, it should be the following:


function TReflectionChat.Messages: TStringArray;
var
ChatWidget, ChatChild: TReflectWidget;
i:integer;
begin
setLength(result, 8);
ChatWidget.GetWidget(WIDGET_Chat_Container, 2);
for i := 0 to 8 do
begin
ChatChild.GetChild(ChatWidget, i);
Result[i] := Reflect.Text.RemoveFormatting(ChatChild.GetText);
ChatChild.Free;
end;
ChatWidget.Free;
end;

rj

2015-03-21 22:46:23

From: elfyyy
You have a memory leak in your chat function, it should be the following:


function TReflectionChat.Messages: TStringArray;
var
ChatWidget, ChatChild: TReflectWidget;
i:integer;
begin
setLength(result, 8);
ChatWidget.GetWidget(WIDGET_Chat_Container, 2);
for i := 0 to 8 do
begin
ChatChild.GetChild(ChatWidget, i);
Result[i] := Reflect.Text.RemoveFormatting(ChatChild.GetText);
ChatChild.Free;
end;
ChatWidget.Free;
end;


gotcha ty

acow

2015-03-21 23:03:37

lol, finally, something useful released publicly

you've just gotta be creative. big clan clan fight. the clan caller bring an extra 5 bots with him, he shouts out who to pile ingame and all the bots call him out (maybe with a nice flash2). game over
easily 3m+/hr

Hyperion

2015-03-22 00:27:10

From: No Lifer
lol, finally, something useful released publicly

you've just gotta be creative. big clan clan fight. the clan caller bring an extra 5 bots with him, he shouts out who to pile ingame and all the bots call him out (maybe with a nice flash2). game over
easily 3m+/hr


That, or you can spam penises in Lumbridge.
Fun release, Rj. I'm definitely gonna use this.

rj

2015-03-22 17:25:39

From: zaboomasimba
That, or you can spam penises in Lumbridge.
Fun release, Rj. I'm definitely gonna use this.


Want to test the GUI version?


[spoiler=GUI Version]
{$DEFINE SMART}
{$I Reflection/Reflection.simba}

const
USECLAN = '';

Type
TMimicPlayer = record
playerName, lastSaid:string;
lastChat:TStringArray;
end;

TMimicPlayerarray = array of TMimicPlayer

var
mainForm:TForm;
replaceWith:TEdit;
endButtons:array[0..1] of TButton;
addButton:TButton;
filterAction:TComboBox;
labels:array[0..3] of TLabel;
recentSpoken:TListBox;
filterWords,mimicPlayers:TMemo;
filterWordsBool:TCheckBox;
pressed:boolean;
recentPeople:TStringArray;
lastChat, filterWordsString:TStringArray;
target, a, filterMethod, repWith:string;
targets:TMimicPlayerarray;

procedure TMimicPlayerArray.append(name:string);
begin
if (length(name) <> 0) then
begin
setLength(self, length(self) + 1);
self[length(self) - 1].playerName := name;
end;
end;

function StrContains(str, s: string): Boolean;
begin
if (lowercase(str) = lowercase(s)) then
exit(true)
if ((str <> '') and (s <> '')) then
Result := (Pos(lowercase(s), lowercase(str)) > 0)
else
Result := False;
end;

function stringStartsWith(str, s:string):boolean;
var
i, c:integer;
begin
if (length(str) < length(s)) then
exit(false);
for i := 1 to length(s) do
if (s[i] = str[i]) then
c := c + 1;
result := (c = length(s) - 1);
end;

function prep(str:string):string;
begin
result := replace(str, '[' + between('[', ']', str) + ']', '', [rfreplaceall]);
end;

function TSAPosEx(TSA: TStringArray; str: string): TIntegerArray;
var
i, r, h: Integer;
begin
h := High(TSA);
if (h > -1) then
begin
SetLength(Result, (h + 1));
for i := 0 to h do
if stringStartsWith(trim(prep(tsa[i])), str) then
begin
Result[r] := i;
Inc(r);
end;
end;
SetLength(Result, r);
end;

function TReflectionChat.Messages: TStringArray;
var
ChatWidget, ChatChild: TReflectWidget;
i:integer;
begin
setLength(result, 16);
ChatWidget.GetWidget(WIDGET_Chat_Container, 2);
for i := 0 to 16 do
begin
ChatChild.GetChild(ChatWidget, i);
Result[i] := Reflect.Text.RemoveFormatting(ChatChild.GetText);
ChatChild.Free;
end;
ChatWidget.Free;
end;

function getChat(name:string):TStringArray;
var
t:TStringArray;
res:TStringArray;
i:integer;
pos:TIntegerArray;
begin
t := Reflect.Chat.Messages();
pos := TSAPosEx(t, name);
setLength(res, length(pos));
for i := 0 to high(pos) do
res[i] := t[pos[i] + 1];
result := res;
end;

function string.startsWith(s:string):boolean;
begin
try
result := self[1] = s;
except
end;
end;

function getRecentSpoken():TStringArray;
var
r:TReflectionChat;
begin
result := r.Messages;
end;

function Before(s, str: string): string;
var
p: Integer;
begin
if (Length(s) < Length(str)) then
begin
p := Pos(s, str);
if (p > 1) then
Result := Copy(str, 1, (p - 1))
else
Result := '';
end else
Result := '';
end;

procedure TStringArray.append(const str : String);
begin
self.addIndex(str, length(self));
end;

procedure TStringArray.addIndex(const str : String; const index : Integer);
var
I : Integer;
begin
if not inRange(index, low(self), length(self)) then
begin
WriteLn('ERROR: addIndex: index larger than array length.');
Exit;
end;

setLength(self, length(self)+1);
for I := high(self)-1 downto index do
self[I+1] := self[I];
self[index] := str;
end;

procedure TStringArray.clearEquals();
var
I : Integer;
arr : TStringArray;
begin
for I := 0 to high(self) do
if not arr.isInArray(self[I]) then
arr.append(self[I]);
self := arr;
end;
function TStringArray.returnInArray(const str : String) : Integer;
var
I : Integer;
begin
result := -1;
for I := 0 to high(self) do
if self[I] = str then
begin
result := I;
exit;
end;
end;

function TStringArray.isInArray(const str : String) : Boolean;
begin
result := self.returnInArray(str) > -1;
end;

function string.endsWith(s:string):boolean;
begin
try
result := self[length(self)] = s;
except
end;
end;

function getRecentPlayers():TStringArray;
var
i:integer;
tmpStr:string;
playerText:TStringArray;
c:TReflectionChat;
begin
playerText := c.Messages();
for i := 0 to high(playerText) do
begin
if playerText[i].startsWith('[') then
begin
tmpStr := between(' ', ':', playerText[i]);
if (tmpStr <> '') then
result.append(tmpStr);
tmpStr := '';
end else if playerText[i].endsWith(':') then
begin
tmpStr := before(':', playerText[i]);
if (tmpStr <> '') then
result.append(tmpStr);
tmpStr := '';
end;
end;
result.clearEquals();
end;

function newMessage(lastChat, currentChat:TStringArray):string;
var
i:integer;
begin
try
if (length(lastChat) = 0) and (length(currentChat) > 0) then
exit(currentchat[0])
else if (length(lastChat) = 0) and (length(currentchat) = 0) then
exit('')
else if (lastChat[0] <> currentchat[0]) then
exit(currentchat[0])
else
exit('');
except
end;
end;

procedure TReflectionKeyboard.TypeSend(Text: String; Send: Boolean = True;speed:integer);overload;
var
I: Integer;
begin
for I := 1 to Length(Text) do
begin
SendKeys(Text[I], speed + Random(speed), 5 + Random(15));
Wait(5 + Random(10));
end;
if Send then
Reflect.Keyboard.TypeKey(Vk_Enter);
end;

function StringOfString(str: string; count: Integer): string;
var
i: Integer;
begin
Result := '';
if (count > 0) then
for i := 1 to count do
Result := (Result + string(str));
end;

function replaceOffensiveText(s, text, replaceWith:string):string;
begin
result := replace(lowercase(s), lowercase(text), stringofstring(replaceWith, length(text)), [rfreplaceall]);
end;

function replaceOffensiveTextMulti(s:string;text:TStringArray;replaceWith:string):string;
var
i:integer;
begin
for i := 0 to high(text) do
s := replaceOffensiveText(s, text[i], replaceWith);
result := s;
end;

function replaceMulti(s:string;text:TStringArray;replaceWith:string):string;
var
i:integer;
begin
for i := 0 to high(text) do
s := replace(lowercase(s), text[i], replaceWith, [rfreplaceall]);
result := s;
end;

function StringInArray(str:string;arr:TStringArray):boolean;
var
i:integer;
begin
for i := 0 to high(arr) do
if (StrContains(lowercase(str), lowercase(arr[i]))) then
result := true;
end;

procedure loop();
var
chat:TStringArray;
s:string;
i:integer;
begin
for i := 0 to high(targets) do
begin
chat := getChat(targets[i].playerName);
s := newMessage(lastChat, chat);
if (targets[i].lastSaid = s) and ((s <> '') and (targets[i].lastSaid <>'')) then
begin
wait(10 + random(20));
targets[i].lastChat := chat;
exit();
end;
if (length(chat) <> 0) and (s <> '') then
begin
if StringInArray(s, filterWordsString) then
begin
case lowercase(filterMethod) of
'do not filter words','filter words': Reflect.KeyBoard.TypeSend(USECLAN + s, true, 5);
'do not respond': writeln('Not responding to filtered words');
'replace word': Reflect.KeyBoard.TypeSend(USECLAN + replaceMulti(s, filterWordsString, repWith) , true, 5);
'censor word': Reflect.KeyBoard.TypeSend(USECLAN + replaceOffensiveTextMulti(s, filterWordsString, repWith) , true, 5);
'type message': Reflect.KeyBoard.TypeSend(USECLAN + repWith, true, 5);
end;
end else
begin
Reflect.KeyBoard.TypeSend(USECLAN + s, true, 5);
wait(200 + random(200));
end;
end;
targets[i].lastChat := chat;
targets[i].lastSaid := s;
setLength(chat, 0);
s := '';
end;
exit;
end;

function mInc(var x: Integer; N: Integer = 1): Integer;
begin
Result := x;
x := (x + N);
end;

function mIncrease(var x: Integer; N: Integer = 1): Integer;
begin
x := (x + N);
Result := x;
end;

function mExplode(str: string; d: Char): TStringArray;
var
a, b, l, p, r, s: Integer;
begin
l := Length(str);
SetLength(Result, 1);
if (l > 0) then
begin
b := 1;
a := 1;
p := 0;
r := 0;
s := 0;
while (mInc(p) < l) do
if (str[p] = d) then
begin
Result[mInc(r)] := Copy(str, a, s);
if (b <= r) then
SetLength(Result, mIncrease(b, b));
a := (p + 1);
s := 0;
end else
s := (s + 1);
SetLength(Result, (r + 1));
Result[r] := Copy(str, a, s);
end else
Result[0] := str;
end;

function mLines(str: string): TStringArray;
begin
if (Length(str) = 0) then
begin
SetLength(Result, 1);
Result[0] := str;
end else
Result := mExplode(str, #10);
end;

procedure startScript(sender:TObject); native;
var
error, st:string;
names:TStringArray;
i:integer;
begin
filterMethod := filterAction.getSelText();
case sender of
addButton:
begin
if (recentSpoken.GetSelectedText <> '') then
mimicPlayers.append(recentSpoken.GetSelectedText);
end;
endButtons[0]:
begin
filterWordsString := mlines(filterWords.getText);
repWith := replaceWith.getCaption();
filterMethod := filterAction.getCaption();
if (mimicPlayers.getText = '') then
begin
messageBox('No players to mimic!', 'Error', 8);
exit();
end else begin
names := mlines(mimicPlayers.getText);
try
for i := 0 to high(names) do
targets.append(names[i]);
except
end;
end;
if (repWith = '') then
begin
messageBox(error, 'Error', 8);
exit();
end;
if (filterMethod = 'Censor word') then
repWith := repWith[1];
try
mainForm.close();
pressed := true;
except
end;
end;
endButtons[1]:
begin
mainForm.close();
mainForm.free();
terminateScript();
end;
end;
end;

procedure createForm();
var
i:integer;
pos:TPointArray;
captions:TStringArray;
begin
mainForm.Init(nil); //recentSpoken:TListBox;
with (mainForm) do
begin
setWidth(400);
setHeight(300);
setPosition(poScreenCenter);
setBorderStyle(bsSingle);
setShowHint(true);
setCaption('Mimicer');
end;
replaceWith.init(mainForm);
with (replaceWith) do
begin
setParent(mainForm);
setBounds(215, 150, 140, 20);
setCaption('*');
setHint('Time (ms)');
end;

recentSpoken.init(mainForm);
with (recentSpoken) do
begin
setParent(mainForm);
setBounds(5, 40, 100, 90);
for i := 0 to high(recentPeople) do
AddItem(recentPeople[i], recentSpoken);
end;
mimicPlayers.init(mainForm);
with (mimicPlayers) do
begin
setParent(mainForm);
setBounds(150, 40, 90, 90);
end;
filterWords.init(mainForm);
with (filterWords) do
begin
setParent(mainForm);
setBounds(260, 40, 85, 95);
end;

addButton.init(mainForm);
with (addButton) do
begin
setParent(mainForm);
setBounds(110, 75, 35, 20);
setCaption('-->');
setHint('Add player');
setOnClick(startScript);
end;
Captions := ['Start script', 'Quit']
for i := 0 to high(endButtons) do
begin
endButtons[i].init(mainForm);
with (endButtons[i]) do
begin
setParent(mainForm);
setBounds(5, 200 + (i * 40), 70, 30);
setCaption(Captions[i]);
setHint(Captions[i]);
setOnClick(startScript);
end;
end;

filterWordsBool.init(mainForm);
with (filterWordsBool) do
begin
setParent(mainForm);
setBounds(5, 140, 20, 20);
setCaption('Filter words');
setHint('Fitler words');
end;

filterAction.init(mainForm);
with (filterAction) do
begin
setParent(mainForm);
setBounds(5, 170, 115, 30);
setCaption('Filter words');
setHint('Steal from');
addItem('Do not filter words', filterAction);
addItem('Do not respond', filterAction);
addItem('Replace word', filterAction);
addItem('Censor word', filterAction);
addItem('Type message', filterAction);
end;
captions := ['Recently talked', 'Memic', 'Filter words', 'Replace with'];
pos := [Point(5, 10), Point(160, 10), Point(270, 10), Point(140, 152)];
for i := 0 to high(captions) do
begin
labels[i].Init(mainForm);
with labels[i] do
begin
setParent(mainForm);
setBounds(pos[i].x, pos[i].y, 10, 10);
setCaption(captions[i]);
end;
end;
end;

procedure initForm();native;
begin
createForm();
try
mainForm.showModal();
except
writeln('Unable to start GUI');
finally
mainForm.Free();
end;
end;

procedure showForm();
begin
sync(initForm);
end;

begin
Reflect.Setup;
recentPeople := getRecentPlayers();
showForm();
if (not pressed) then
begin
writeln('Did not press start');
terminateScript();
end;
repeat
loop();
until False;
end.
[/spoiler]

Hyperion

2015-03-23 00:19:39

From: rj
Want to test the GUI version?


[spoiler=GUI Version]
{$DEFINE SMART}
{$I Reflection/Reflection.simba}

const
USECLAN = '';

Type
TMimicPlayer = record
playerName, lastSaid:string;
lastChat:TStringArray;
end;

TMimicPlayerarray = array of TMimicPlayer

var
mainForm:TForm;
replaceWith:TEdit;
endButtons:array[0..1] of TButton;
addButton:TButton;
filterAction:TComboBox;
labels:array[0..3] of TLabel;
recentSpoken:TListBox;
filterWords,mimicPlayers:TMemo;
filterWordsBool:TCheckBox;
pressed:boolean;
recentPeople:TStringArray;
lastChat, filterWordsString:TStringArray;
target, a, filterMethod, repWith:string;
targets:TMimicPlayerarray;

procedure TMimicPlayerArray.append(name:string);
begin
if (length(name) <> 0) then
begin
setLength(self, length(self) + 1);
self[length(self) - 1].playerName := name;
end;
end;

function StrContains(str, s: string): Boolean;
begin
if (lowercase(str) = lowercase(s)) then
exit(true)
if ((str <> '') and (s <> '')) then
Result := (Pos(lowercase(s), lowercase(str)) > 0)
else
Result := False;
end;

function stringStartsWith(str, s:string):boolean;
var
i, c:integer;
begin
if (length(str) < length(s)) then
exit(false);
for i := 1 to length(s) do
if (s[i] = str[i]) then
c := c + 1;
result := (c = length(s) - 1);
end;

function prep(str:string):string;
begin
result := replace(str, '[' + between('[', ']', str) + ']', '', [rfreplaceall]);
end;

function TSAPosEx(TSA: TStringArray; str: string): TIntegerArray;
var
i, r, h: Integer;
begin
h := High(TSA);
if (h > -1) then
begin
SetLength(Result, (h + 1));
for i := 0 to h do
if stringStartsWith(trim(prep(tsa[i])), str) then
begin
Result[r] := i;
Inc(r);
end;
end;
SetLength(Result, r);
end;

function TReflectionChat.Messages: TStringArray;
var
ChatWidget, ChatChild: TReflectWidget;
i:integer;
begin
setLength(result, 16);
ChatWidget.GetWidget(WIDGET_Chat_Container, 2);
for i := 0 to 16 do
begin
ChatChild.GetChild(ChatWidget, i);
Result[i] := Reflect.Text.RemoveFormatting(ChatChild.GetText);
ChatChild.Free;
end;
ChatWidget.Free;
end;

function getChat(name:string):TStringArray;
var
t:TStringArray;
res:TStringArray;
i:integer;
pos:TIntegerArray;
begin
t := Reflect.Chat.Messages();
pos := TSAPosEx(t, name);
setLength(res, length(pos));
for i := 0 to high(pos) do
res[i] := t[pos[i] + 1];
result := res;
end;

function string.startsWith(s:string):boolean;
begin
try
result := self[1] = s;
except
end;
end;

function getRecentSpoken():TStringArray;
var
r:TReflectionChat;
begin
result := r.Messages;
end;

function Before(s, str: string): string;
var
p: Integer;
begin
if (Length(s) < Length(str)) then
begin
p := Pos(s, str);
if (p > 1) then
Result := Copy(str, 1, (p - 1))
else
Result := '';
end else
Result := '';
end;

procedure TStringArray.append(const str : String);
begin
self.addIndex(str, length(self));
end;

procedure TStringArray.addIndex(const str : String; const index : Integer);
var
I : Integer;
begin
if not inRange(index, low(self), length(self)) then
begin
WriteLn('ERROR: addIndex: index larger than array length.');
Exit;
end;

setLength(self, length(self)+1);
for I := high(self)-1 downto index do
self[I+1] := self[I];
self[index] := str;
end;

procedure TStringArray.clearEquals();
var
I : Integer;
arr : TStringArray;
begin
for I := 0 to high(self) do
if not arr.isInArray(self[I]) then
arr.append(self[I]);
self := arr;
end;
function TStringArray.returnInArray(const str : String) : Integer;
var
I : Integer;
begin
result := -1;
for I := 0 to high(self) do
if self[I] = str then
begin
result := I;
exit;
end;
end;

function TStringArray.isInArray(const str : String) : Boolean;
begin
result := self.returnInArray(str) > -1;
end;

function string.endsWith(s:string):boolean;
begin
try
result := self[length(self)] = s;
except
end;
end;

function getRecentPlayers():TStringArray;
var
i:integer;
tmpStr:string;
playerText:TStringArray;
c:TReflectionChat;
begin
playerText := c.Messages();
for i := 0 to high(playerText) do
begin
if playerText[i].startsWith('[') then
begin
tmpStr := between(' ', ':', playerText[i]);
if (tmpStr <> '') then
result.append(tmpStr);
tmpStr := '';
end else if playerText[i].endsWith(':') then
begin
tmpStr := before(':', playerText[i]);
if (tmpStr <> '') then
result.append(tmpStr);
tmpStr := '';
end;
end;
result.clearEquals();
end;

function newMessage(lastChat, currentChat:TStringArray):string;
var
i:integer;
begin
try
if (length(lastChat) = 0) and (length(currentChat) > 0) then
exit(currentchat[0])
else if (length(lastChat) = 0) and (length(currentchat) = 0) then
exit('')
else if (lastChat[0] <> currentchat[0]) then
exit(currentchat[0])
else
exit('');
except
end;
end;

procedure TReflectionKeyboard.TypeSend(Text: String; Send: Boolean = True;speed:integer);overload;
var
I: Integer;
begin
for I := 1 to Length(Text) do
begin
SendKeys(Text[I], speed + Random(speed), 5 + Random(15));
Wait(5 + Random(10));
end;
if Send then
Reflect.Keyboard.TypeKey(Vk_Enter);
end;

function StringOfString(str: string; count: Integer): string;
var
i: Integer;
begin
Result := '';
if (count > 0) then
for i := 1 to count do
Result := (Result + string(str));
end;

function replaceOffensiveText(s, text, replaceWith:string):string;
begin
result := replace(lowercase(s), lowercase(text), stringofstring(replaceWith, length(text)), [rfreplaceall]);
end;

function replaceOffensiveTextMulti(s:string;text:TStringArray;replaceWith:string):string;
var
i:integer;
begin
for i := 0 to high(text) do
s := replaceOffensiveText(s, text[i], replaceWith);
result := s;
end;

function replaceMulti(s:string;text:TStringArray;replaceWith:string):string;
var
i:integer;
begin
for i := 0 to high(text) do
s := replace(lowercase(s), text[i], replaceWith, [rfreplaceall]);
result := s;
end;

function StringInArray(str:string;arr:TStringArray):boolean;
var
i:integer;
begin
for i := 0 to high(arr) do
if (StrContains(lowercase(str), lowercase(arr[i]))) then
result := true;
end;

procedure loop();
var
chat:TStringArray;
s:string;
i:integer;
begin
for i := 0 to high(targets) do
begin
chat := getChat(targets[i].playerName);
s := newMessage(lastChat, chat);
if (targets[i].lastSaid = s) and ((s <> '') and (targets[i].lastSaid <>'')) then
begin
wait(10 + random(20));
targets[i].lastChat := chat;
exit();
end;
if (length(chat) <> 0) and (s <> '') then
begin
if StringInArray(s, filterWordsString) then
begin
case lowercase(filterMethod) of
'do not filter words','filter words': Reflect.KeyBoard.TypeSend(USECLAN + s, true, 5);
'do not respond': writeln('Not responding to filtered words');
'replace word': Reflect.KeyBoard.TypeSend(USECLAN + replaceMulti(s, filterWordsString, repWith) , true, 5);
'censor word': Reflect.KeyBoard.TypeSend(USECLAN + replaceOffensiveTextMulti(s, filterWordsString, repWith) , true, 5);
'type message': Reflect.KeyBoard.TypeSend(USECLAN + repWith, true, 5);
end;
end else
begin
Reflect.KeyBoard.TypeSend(USECLAN + s, true, 5);
wait(200 + random(200));
end;
end;
targets[i].lastChat := chat;
targets[i].lastSaid := s;
setLength(chat, 0);
s := '';
end;
exit;
end;

function mInc(var x: Integer; N: Integer = 1): Integer;
begin
Result := x;
x := (x + N);
end;

function mIncrease(var x: Integer; N: Integer = 1): Integer;
begin
x := (x + N);
Result := x;
end;

function mExplode(str: string; d: Char): TStringArray;
var
a, b, l, p, r, s: Integer;
begin
l := Length(str);
SetLength(Result, 1);
if (l > 0) then
begin
b := 1;
a := 1;
p := 0;
r := 0;
s := 0;
while (mInc(p) < l) do
if (str[p] = d) then
begin
Result[mInc(r)] := Copy(str, a, s);
if (b <= r) then
SetLength(Result, mIncrease(b, b));
a := (p + 1);
s := 0;
end else
s := (s + 1);
SetLength(Result, (r + 1));
Result[r] := Copy(str, a, s);
end else
Result[0] := str;
end;

function mLines(str: string): TStringArray;
begin
if (Length(str) = 0) then
begin
SetLength(Result, 1);
Result[0] := str;
end else
Result := mExplode(str, #10);
end;

procedure startScript(sender:TObject); native;
var
error, st:string;
names:TStringArray;
i:integer;
begin
filterMethod := filterAction.getSelText();
case sender of
addButton:
begin
if (recentSpoken.GetSelectedText <> '') then
mimicPlayers.append(recentSpoken.GetSelectedText);
end;
endButtons[0]:
begin
filterWordsString := mlines(filterWords.getText);
repWith := replaceWith.getCaption();
filterMethod := filterAction.getCaption();
if (mimicPlayers.getText = '') then
begin
messageBox('No players to mimic!', 'Error', 8);
exit();
end else begin
names := mlines(mimicPlayers.getText);
try
for i := 0 to high(names) do
targets.append(names[i]);
except
end;
end;
if (repWith = '') then
begin
messageBox(error, 'Error', 8);
exit();
end;
if (filterMethod = 'Censor word') then
repWith := repWith[1];
try
mainForm.close();
pressed := true;
except
end;
end;
endButtons[1]:
begin
mainForm.close();
mainForm.free();
terminateScript();
end;
end;
end;

procedure createForm();
var
i:integer;
pos:TPointArray;
captions:TStringArray;
begin
mainForm.Init(nil); //recentSpoken:TListBox;
with (mainForm) do
begin
setWidth(400);
setHeight(300);
setPosition(poScreenCenter);
setBorderStyle(bsSingle);
setShowHint(true);
setCaption('Mimicer');
end;
replaceWith.init(mainForm);
with (replaceWith) do
begin
setParent(mainForm);
setBounds(215, 150, 140, 20);
setCaption('*');
setHint('Time (ms)');
end;

recentSpoken.init(mainForm);
with (recentSpoken) do
begin
setParent(mainForm);
setBounds(5, 40, 100, 90);
for i := 0 to high(recentPeople) do
AddItem(recentPeople[i], recentSpoken);
end;
mimicPlayers.init(mainForm);
with (mimicPlayers) do
begin
setParent(mainForm);
setBounds(150, 40, 90, 90);
end;
filterWords.init(mainForm);
with (filterWords) do
begin
setParent(mainForm);
setBounds(260, 40, 85, 95);
end;

addButton.init(mainForm);
with (addButton) do
begin
setParent(mainForm);
setBounds(110, 75, 35, 20);
setCaption('-->');
setHint('Add player');
setOnClick(startScript);
end;
Captions := ['Start script', 'Quit']
for i := 0 to high(endButtons) do
begin
endButtons[i].init(mainForm);
with (endButtons[i]) do
begin
setParent(mainForm);
setBounds(5, 200 + (i * 40), 70, 30);
setCaption(Captions[i]);
setHint(Captions[i]);
setOnClick(startScript);
end;
end;

filterWordsBool.init(mainForm);
with (filterWordsBool) do
begin
setParent(mainForm);
setBounds(5, 140, 20, 20);
setCaption('Filter words');
setHint('Fitler words');
end;

filterAction.init(mainForm);
with (filterAction) do
begin
setParent(mainForm);
setBounds(5, 170, 115, 30);
setCaption('Filter words');
setHint('Steal from');
addItem('Do not filter words', filterAction);
addItem('Do not respond', filterAction);
addItem('Replace word', filterAction);
addItem('Censor word', filterAction);
addItem('Type message', filterAction);
end;
captions := ['Recently talked', 'Memic', 'Filter words', 'Replace with'];
pos := [Point(5, 10), Point(160, 10), Point(270, 10), Point(140, 152)];
for i := 0 to high(captions) do
begin
labels[i].Init(mainForm);
with labels[i] do
begin
setParent(mainForm);
setBounds(pos[i].x, pos[i].y, 10, 10);
setCaption(captions[i]);
end;
end;
end;

procedure initForm();native;
begin
createForm();
try
mainForm.showModal();
except
writeln('Unable to start GUI');
finally
mainForm.Free();
end;
end;

procedure showForm();
begin
sync(initForm);
end;

begin
Reflect.Setup;
recentPeople := getRecentPlayers();
showForm();
if (not pressed) then
begin
writeln('Did not press start');
terminateScript();
end;
repeat
loop();
until False;
end.
[/spoiler]


Doubt I'll be able to really test it out soon, got a calc test this Wednesday and some interviews to do on Thursday. I can check it out afterwards if you're still willing.