-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlongpollchat.pas
234 lines (206 loc) · 7.85 KB
/
longpollchat.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
unit LongpollChat;
interface
uses
fpjson;
type
THandler = class
public
name: String;
procedure handler(msg: TJSONObject); virtual;
end;
TCommand = class (THandler)
public
keywords: Array of String;
level: Byte;
//procedure handler(msg: TJSONObject); virtual;
end;
var
commandsArray: Array of TCommand;
handlers: Array of THandler;
procedure commandsHandler(msg: TJSONObject);
implementation
uses
sysutils, strutils, FLRE, cwstring,
Database, Utils;
type
TPack = record
handler: THandler;
msg: TJSONObject;
end;
PTPack = ^TPack;
//procedure TCommand.handler(msg: TJSONObject); begin end;
procedure THandler.handler(msg: TJSONObject); begin end;
function thread(pack: Pointer): ptrint;
begin
logThreadId := PTPack(pack)^.msg.integers['local_id'];
try
PTPack(pack)^.handler.handler(PTPack(pack)^.msg);
except
on e: Exception do
logWrite(format('Error while processing message in thread: "%s".%sMSGOBJ: %s',
[e.toString(), LineEnding, PTPack(pack)^.msg.asJSON]), TLogType.logError);
end;
FreeAndNil(PTPack(pack)^.msg);
dispose(PTPack(pack));
logWrite('Message processing finished.');
exit(0);
end;
function veryBadToLower(str: String): String;
const
convLowers: Array [0..87] of String = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï',
'ð', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'а', 'б', 'в', 'г', 'д', 'е', 'ё', 'ж',
'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о', 'п', 'р', 'с', 'т', 'у', 'ф', 'х', 'ц', 'ч', 'ш', 'щ', 'ъ', 'ы',
'ь', 'э', 'ю', 'я');
convUppers: Array [0..87] of String = ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U',
'V', 'W', 'X', 'Y', 'Z', 'À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï',
'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'Ё', 'Ж',
'З', 'И', 'Й', 'К', 'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Х', 'Ц', 'Ч', 'Ш', 'Щ', 'Ъ', 'Ъ',
'Ь', 'Э', 'Ю', 'Я');
var
i: Integer;
begin
result := str;
for i := 0 to 87 do
result := stringReplace(result, convUppers[i], convLowers[i], [rfReplaceAll]);
end;
function unescapeHTML ( const S : String ) : String;
begin
Result := StringReplace(s, '<', '<', [rfReplaceAll]);
Result := StringReplace(Result, '>', '>', [rfReplaceAll]);
Result := StringReplace(Result, '"', '"', [rfReplaceAll]);
Result := StringReplace(Result, ''', #39, [rfReplaceAll]);
Result := StringReplace(Result, ''', #39, [rfReplaceAll]);
Result := StringReplace(Result, '&', '&', [rfReplaceAll]);
Result := StringReplace(Result, '<br/>', LineEnding, [rfReplaceAll]);
end;
procedure commandsHandler(msg: TJSONObject);
var
regexCmdStr: TFLRE;
parts : TFLREMultiStrings = nil;
names: Array of String;
textWithoutSlash: String;
cmd: TCommand;
handler: THandler;
dbResponse: TJSONArray;
enum: TJSONEnum;
pack: PTPack;
i, j: Integer;
begin
msg.integers['local_id'] := msg.integers['date']+msg.integers['peer_id']+msg.integers['from_id'];
if (msg['peer_id'].asInteger > 0) and (msg['peer_id'].asInteger < 2000000000) then
msg.add('chat_type', 'private')
else if msg['peer_id'].asInteger > 2000000000 then
msg.add('chat_type', 'dialog')
else if msg['peer_id'].asInteger < 0 then
msg.add('chat_type', 'group_private');
if msg.indexOfName('text') <> -1 then
msg.strings['text'] := unescapeHTML(msg.strings['text'])
else
msg.add('text', '');
dbResponse := dbExecOut('SELECT * FROM users WHERE id='+msg.integers['from_id'].toString()+';');
if dbResponse.count >= 1 then
msg.add('dbuser', dbResponse.objects[0])
else
begin
dbExecIn('INSERT INTO users (id, perm, data, money) VALUES ('+msg.integers['from_id'].toString()+', 1, "{}", 100);');
dbResponse := dbExecOut('SELECT * FROM users WHERE id='+msg.integers['from_id'].toString()+';');
msg.add('dbuser', dbResponse.objects[0])
end;
for handler in handlers do
if handler.name = dbResponse.objects[0].strings['handler'] then
begin
//logWrite(format('Bot mentioned by id%d in %d. Info { Text: "%s", AttachCount: %d }',
// [msg.integers['from_id'],
// msg.integers['peer_id'],
// msg.strings['text'],
// msg.arrays['attachments'].count]));
handler.handler(msg);
exit;
end;
textWithoutSlash := msg.strings['text'];
//if length(msg.strings['text']) <> 0 then
// if msg.strings['text'][1] = '/' then
// textWithoutSlash := copy(msg.strings['text'], 2, length(msg.strings['text']));
if length(textWithoutSlash) = 0 then
exit;
setLength(names, 0);
for enum in config.arrays['names'] do
begin
setLength(names, length(names)+1);
names[high(names)] := veryBadToLower(enum.value.asString);
end;
regexCmdStr := TFLRE.create('^\s*(\[club(\d+)\|\s*\S+\s*\]|\S+)(?:\s+(\S+)|\s*$)(?:\s+(\S.*)$|\s*$)',
[ rfUTF8, rfSINGLELINE ]);
if regexCmdStr.UTF8ExtractAll(textWithoutSlash, parts)
and (((length(parts[0][2]) > 0) and (strToInt(parts[0][2]) = config.integers['group_id']))
or AnsiMatchStr(veryBadToLower(parts[0][1]), names)
or (not AnsiMatchStr(veryBadToLower(parts[0][1]), names) and (msg.strings['chat_type'] = 'private'))) then
begin
//ИСПРАВЬ НАХУЙ БЛЯ ЙОПТА, ВЗЯЛ ВСЮ РАБОТУ БОТА ОСТАНОВИЛ ПИСЬКА
if (msg.strings['chat_type'] = 'dialog') or (AnsiMatchStr(veryBadToLower(parts[0][1]), names) and (msg.strings['chat_type'] = 'private')) then
begin
msg.add('prefix', parts[0][1]);
msg.add('command', parts[0][3]);
msg.add('argument', parts[0][4]);
end
else
begin
msg.add('prefix', '');
msg.add('command', parts[0][1]);
msg.add('argument', parts[0][3]);
end;
end
else
begin
setLength(names, 0);
// Free regexp memory
for i := 0 to length(parts)-1 do
begin
for j := 0 to length(parts[i])-1 do
setLength(parts[i][j], 0);
setLength(parts[i], 0);
parts[i] := nil;
end;
parts := nil;
FreeAndNil(regexCmdStr);
exit;
end;
setLength(names, 0);
// Free regexp memory
for i := 0 to length(parts)-1 do
begin
//for j := 0 to length(parts[i])-1 do
// setLength(parts[i][j], 0);
setLength(parts[i], 0);
parts[i] := nil;
end;
setLength(parts, 0);
parts := nil;
FreeAndNil(regexCmdStr);
logWrite(format('Mentioned by %d in %d. Info{Text: "%s", AttachCount: %d, ID: %u}',
[msg.integers['from_id'],
msg.integers['peer_id'],
msg.strings['text'],
msg.arrays['attachments'].count,
msg.integers['local_id']]));
for cmd in commandsArray do
begin
if ansiMatchStr(veryBadToLower(msg['command'].asString), cmd.keywords) and (dbResponse.objects[0].integers['perm'] >= cmd.level) then
begin
pack := new(PTPack);
pack^.handler := cmd;
pack^.msg := msg;
beginThread(@thread, pack);
end;
end;
cmd := nil;
end;
initialization
begin
end;
finalization
begin
writeln('sos sas');
end;
end.