-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathVKontakte.dpr
497 lines (420 loc) · 21.4 KB
/
VKontakte.dpr
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
(*
VKontakte plugin for Miranda IM: the free IM client for Microsoft Windows
Copyright (c) 2008-2010 Andrey Lukyanov
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*)
library VKontakte;
uses
m_globaldefs in 'api\m_globaldefs.pas',
m_api in 'api\m_api.pas',
vk_global,
vk_http,
vk_core,
vk_menu,
vk_msgs,
vk_news,
vk_auth,
vk_avatars,
vk_xstatus,
vk_info,
vk_folders,
vk_search,
vk_popup,
vk_wall,
vk_opts,
Windows,
ShellAPI,
SysUtils,
uLkJSON in 'inc\uLkJSON.pas', // module to parse data from feed2.php (in JSON format)
htmlparse in 'htmlparse.pas',
vk_captcha in 'vk_captcha.pas';
const
// constants to provide information about plugin
// values defined in vk_opts
PluginInfoEx: TPLUGININFOEX = (
cbSize: SizeOf(TPLUGININFOEX);
shortName: piShortName;
version: piVersion;
description: piDescription;
author: piAuthor;
authorEmail: piAuthorEmail;
copyright: piCopyright;
homepage: piHomepage;
flags: UNICODE_AWARE;
replacesDefaultModule: 0;
uuid: '{75A5596C-3AD4-4B17-ABEF-5D45DEAA4A83}'
);
PluginInfo: TPLUGININFO = (
cbSize: SizeOf(TPLUGININFO);
shortName: piShortName;
version: piVersion;
description: piDescription;
author: piAuthor;
authorEmail: piAuthorEmail;
copyright: piCopyright;
homepage: piHomepage;
flags: UNICODE_AWARE;
replacesDefaultModule: 0;
);
var
vk_hGetCaps, vk_hGetName, vk_hGetStatus, vk_hSetStatus, vk_hLoadIcon, vk_hOnCreateAccMgrUI, vk_hkContactDeleted, vk_hkModulesLoad, vk_hkOptInitialise, vk_hkHookShutdown, vk_hkHookOkToExit: THandle;
// ccs: PCCSDATA;
PluginInterfaces: array [0..1] of MUUID;
// =============================================================================
// functions to provide information about plugin
// -----------------------------------------------------------------------------
function MirandaPluginInfo(mirandaVersion: DWORD): PPLUGININFO; cdecl;
begin
Result := @PluginInfo;
end;
function MirandaPluginInfoEx(mirandaVersion: DWORD): PPLUGININFOEX; cdecl;
begin
Result := @PluginInfoEx;
end;
function MirandaPluginInterfaces: PMUUID; cdecl;
begin
PluginInterfaces[0] := PluginInfoEx.uuid;
PluginInterfaces[1] := MIID_LAST;
Result := @PluginInterfaces;
end;
// declaration of the functions, which will be defined later
function OnModulesLoad(wParam, lParam: DWord): integer; cdecl; forward;
function PreShutdown(wParam: wParam; lParam: lParam): integer; cdecl; forward;
function OkToExit(wParam: wParam; lParam: lParam): integer; cdecl; forward;
// =============================================================================
// function to identify list of functions supported by the plugin
// -----------------------------------------------------------------------------
function GetCaps(wParam: wParam; lParam: lParam): integer; cdecl;
begin
case wParam of
PFLAGNUM_1:
Result :=
PF1_AUTHREQ or // will get authorisation requests for some or all contacts
PF1_BASICSEARCH or // supports a basic user searching facility
PF1_SEARCHBYNAME or // protocol supports searching by nick/first/last names
PF1_EXTSEARCH or // supports one or more protocol-specific extended search schemes
PF1_EXTSEARCHUI or // has a dialog box to allow searching all the possible fields
PF1_ADDSEARCHRES or // can add search results to the contact list
PF1_IM or // supports IM sending & receiving
PFLAGNUM_1 or // will get authorisation requests for some or all contacts
// PF1_NUMERICUSERID or // the unique user IDs for this protocol are numeric
PF1_SERVERCLIST; // contact lists are stored on the server, not locally
PFLAGNUM_2:
Result := PF2_ONLINE or PF2_INVISIBLE; // list of statuses supported, just online & offline is required
// PFLAGNUM_3 :
// Result := PF2_ONLINE or PF2_LONGAWAY;
PFLAGNUM_4:
Result := // $00000100 or // PF4_IMSENDOFFLINE; protocol is able to send offline messages - this cause problems in miranda 0.8 b27 and higher
PF4_AVATARS; // avatars supported
PFLAG_UNIQUEIDTEXT:
Result := integer(Translate('ID')); // returns a static buffer of text describing the unique field by which this protocol identifies users
// this name will be used for ex. in BASIC SEARCH
PFLAG_MAXLENOFMESSAGE:
Result := 131072; // maximum length of one message (site limit)
PFLAG_UNIQUEIDSETTING:
Result := integer(PChar('ID')); // returns the DB setting name that has the ID which makes this user unique on that system
else
Result := 0;
end;
end;
// =============================================================================
// function to copy the name of the protocole into lParam
// -----------------------------------------------------------------------------
function GetName(wParam: wParam; lParam: lParam): integer; cdecl;
begin
if lParam <> 0 then
StrLCopy(PChar(lParam), Translate(piShortName), wParam);
Result := 0;
end;
// =============================================================================
// function to change the status and notifies everybody
// -----------------------------------------------------------------------------
function SetStatus(wParam: wParam; lParam: lParam): integer; cdecl;
begin
Result := vk_SetStatus(wParam);
end;
// =============================================================================
// function to return the current status
// -----------------------------------------------------------------------------
function GetStatus(wParam: wParam; lParam: lParam): integer; cdecl;
begin
Result := vk_Status;
end;
// =============================================================================
// function loads
// the icon corresponding to the status
// called by the CList when the status changes.
// wParam: one of the following values:
// PLI_PROTOCOL | PLI_ONLINE | PLI_OFFLINE
// returns an HICON in which the icon has been loaded
// -----------------------------------------------------------------------------
function LoadIcon(wParam: wParam; lParam: lParam): integer; cdecl;
var
id: string; // to store id of icon to be loaded
cx: int;
cy: int;
begin
// regardless of the code below, this function is called only when
// wParam = PLI_PROTOCOL and it is required to display proto icon
// in Miranda's main menu -> Status
case (wParam and $ffff) of
PLI_PROTOCOL:
id := 'ICON_PROTO'; // icon representing protocol
PLI_ONLINE:
id := 'ICON_ONLINE'; // online state icon for the protocol
PLI_OFFLINE:
id := 'ICON_OFFLINE'; // offline state icon for the protocol
else
Result := 0;
Exit;
end;
if (bool(wParam and PLIF_SMALL)) then
begin
// if small icon - 16x16 by default
cx := SM_CXSMICON;
cy := SM_CYSMICON;
end
else
begin
// if big icon - 32x32 by default
cx := SM_CXICON;
cy := SM_CYICON;
end;
Result := Int(LoadImage(hInstance,
MAKEINTRESOURCE(PChar(id)),
IMAGE_ICON,
GetSystemMetrics(cx),
GetSystemMetrics(cy),
0));
end;
// =============================================================================
// function identifies what should be done when plugin is being loaded
// -----------------------------------------------------------------------------
function Load(link: PPLUGINLINK): integer; cdecl;
var
pd: TPROTOCOLDESCRIPTOR;
begin
// the following two lines are VERY VERY important, if it's not present, expect crashes
pluginLink := Pointer(link);
InitMMI;
// register new protocol
FillChar(pd, sizeof(pd), 0);
pd.cbSize := sizeof(pd);
pd.szName := piShortName;
pd._type := PROTOTYPE_PROTOCOL;
pluginLink^.CallService(MS_PROTO_REGISTERMODULE, 0, lParam(@pd));
// register additional services required for protocol
vk_hGetCaps := CreateProtoServiceFunction(piShortName, PS_GETCAPS, @GetCaps);
vk_hGetName := CreateProtoServiceFunction(piShortName, PS_GETNAME, @GetName);
vk_hSetStatus := CreateProtoServiceFunction(piShortName, PS_SETSTATUS, @SetStatus);
vk_hGetStatus := CreateProtoServiceFunction(piShortName, PS_GETSTATUS, @GetStatus);
vk_hLoadIcon := CreateProtoServiceFunction(piShortName, PS_LOADICON, @LoadIcon);
vk_hOnCreateAccMgrUI := CreateProtoServiceFunction(piShortName, PS_CREATEACCMGRUI, OnCreateAccMgrUI); // for Miranda 0.8+ Account Manager support
ConnectionErrorsCount := 0;
// register functions to support popups
PopupInit();
// register functions required to send and receive messages
MsgsInit();
// register functions to support search
SearchInit();
AuthInit();
InfoInit();
SetStatusOffline(); // make all contacts offline
// hook event when contact is deleted & delete contact from Friends list on the server
vk_hkContactDeleted := pluginLink^.HookEvent(ME_DB_CONTACT_DELETED, @ContactDeleted);
// identifies the function OnModulesLoad(), which will be run once all
// modules are loaded
vk_hkModulesLoad := pluginLink^.HookEvent(ME_SYSTEM_MODULESLOADED, @OnModulesLoad);
// hook events when Miranda is being closed
vk_hkHookOkToExit := pluginLink^.HookEvent(ME_SYSTEM_OKTOEXIT, @OkToExit);
vk_hkHookShutdown := pluginLink^.HookEvent(ME_SYSTEM_PRESHUTDOWN, @PreShutdown);
Result := 0;
end;
// =============================================================================
// function, which run once all modules are loaded
// -----------------------------------------------------------------------------
function OnModulesLoad(wParam{0}, lParam{0}: DWord): integer; cdecl;
var ood: TOPENOPTIONSDIALOG;
begin
// get preferred vkontakte hosts
vk_url := vk_url_prefix + DBReadString(0, piShortName, opt_UserPreferredHostVKontakteRu, PChar(vk_url_vkontakteru));
vk_url_pda := vk_url_prefix + DBReadString(0, piShortName, opt_UserPreferredHostMVKontakteRu, PChar(vk_url_mvkontakteru));
vk_url_uapi := vk_url_prefix + DBReadString(0, piShortName, opt_UserPreferredHostUserApiCom, PChar(vk_url_userapi));
// reset vk_UserLangId, vk_UserLangHash vars
vk_UserLangId := '';
vk_UserLangHash := '';
// code to identify Options function
vk_hkOptInitialise := pluginLink^.HookEvent(ME_OPT_INITIALISE, @OnOptInitialise);
// updater compatibility data
if PluginLink^.ServiceExists(MS_UPDATE_REGISTER) <> 0 then
begin
// 3730 - id of the plugin on addons.miranda-im.org - http://addons.miranda-im.org/details.php?action=viewfile&id=3730
PluginLink^.CallService(MS_UPDATE_REGISTERFL, 3730, Windows.lParam(@PluginInfo));
end;
// initiate Additional Status support
AddlStatusInit();
MenuInit();
// initiate internet connection
HTTP_NL_Init();
// register avatars folder for Folders plugin
FoldersInit();
AvatarsInit();
// temp code - to be removed in the next versions
if DBGetContactSettingDWord(0, piShortName, 'UserKeepOnlineFreqSecs', 900) <> 900 then
DBWriteContactSettingDWord(0, piShortName, opt_UserKeepOnline, DBGetContactSettingDWord(0, piShortName, 'UserKeepOnlineFreqSecs', 900));
DBDeleteContactSetting(0, piShortName, 'UserKeepOnlineFreqSecs');
if DBGetContactSettingDWord(0, piShortName, 'UserFriendsStatusFreqSecs', 60) <> 60 then
DBWriteContactSettingDWord(0, piShortName, opt_UserUpdateFriendsStatus, DBGetContactSettingDWord(0, piShortName, 'UserFriendsStatusFreqSecs', 60));
DBDeleteContactSetting(0, piShortName, 'UserFriendsStatusFreqSecs');
if DBGetContactSettingByte(0, piShortName, 'UserInfoMinimal', 0) <> 0 then
DBWriteContactSettingByte(0, piShortName, opt_UserGetMinInfo, DBGetContactSettingByte(0, piShortName, 'UserInfoMinimal', 0));
DBDeleteContactSetting(0, piShortName, 'UserInfoMinimal');
if DBReadString(0, piShortName, 'UserFriendsDeleted', '') <> '' then
DBWriteContactSettingString(0, piShortName, opt_UserGetMinInfo, DBReadString(0, piShortName, 'UserFriendsDeleted', nil));
DBDeleteContactSetting(0, piShortName, 'UserFriendsDeleted');
if DBGetContactSettingByte(0, piShortName, 'UserMsgIncRemoveEmptySubject', 1) <> 1 then
DBWriteContactSettingByte(0, piShortName, opt_UserRemoveEmptySubj, DBGetContactSettingByte(0, piShortName, 'UserMsgIncRemoveEmptySubject', 1));
DBDeleteContactSetting(0, piShortName, 'UserMsgIncRemoveEmptySubject');
if DBReadString(0, piShortName, 'UserDefaultGroup', '') <> '' then
DBWriteContactSettingUnicode(0, piShortName, opt_UserGetMinInfo, PWideChar(WideString(DBReadString(0, piShortName, 'UserDefaultGroup', nil))));
DBDeleteContactSetting(0, piShortName, 'UserDefaultGroup');
if DBGetContactSettingByte(0, piShortName, 'UserAddlStatusUpdate', 1) <> 1 then
DBWriteContactSettingByte(0, piShortName, opt_UserUpdateAddlStatus, DBGetContactSettingByte(0, piShortName, 'UserAddlStatusUpdate', 1));
DBDeleteContactSetting(0, piShortName, 'UserAddlStatusUpdate');
if DBGetContactSettingByte(0, piShortName, 'UserAvatarsSupport', 1) <> 1 then
DBWriteContactSettingByte(0, piShortName, opt_UserAvatarsSupport, DBGetContactSettingByte(0, piShortName, 'UserAvatarsSupport', 1));
DBDeleteContactSetting(0, piShortName, 'UserAvatarsSupport');
if DBGetContactSettingDWord(0, piShortName, 'UserAvatarsUpdateFreqSecs', 3600) <> 3600 then
DBWriteContactSettingDWord(0, piShortName, opt_UserKeepOnline, DBGetContactSettingDWord(0, piShortName, 'UserAvatarsUpdateFreqSecs', 3600));
DBDeleteContactSetting(0, piShortName, 'UserAvatarsUpdateFreqSecs');
if DBGetContactSettingByte(0, piShortName, 'UserAvatarsUpdateWhenGetInfo', 1) <> 1 then
DBWriteContactSettingByte(0, piShortName, opt_UserAvatarsUpdateWhenGetInfo, DBGetContactSettingByte(0, piShortName, 'UserAvatarsUpdateWhenGetInfo', 1));
DBDeleteContactSetting(0, piShortName, 'UserAvatarsUpdateWhenGetInfo');
if DBGetContactSettingByte(0, piShortName, 'UserInfoVKontaktePageURL', 0) <> 0 then
DBWriteContactSettingByte(0, piShortName, opt_UserVKontakteURL, DBGetContactSettingByte(0, piShortName, 'UserInfoVKontaktePageURL', 0));
DBDeleteContactSetting(0, piShortName, 'UserInfoVKontaktePageURL');
if DBGetContactSettingByte(0, piShortName, 'UserAddlStatusForOfflineContacts', 1) <> 1 then
DBWriteContactSettingByte(0, piShortName, opt_UserAddlStatusForOffline, DBGetContactSettingByte(0, piShortName, 'UserAddlStatusForOfflineContacts', 1));
DBDeleteContactSetting(0, piShortName, 'UserAddlStatusForOfflineContacts');
if DBGetContactSettingByte(0, piShortName, 'UserMsgIncUseLocalTime', 0) <> 0 then
DBWriteContactSettingByte(0, piShortName, opt_UserUseLocalTimeForIncomingMessages, DBGetContactSettingByte(0, piShortName, 'UserMsgIncUseLocalTime', 0));
DBDeleteContactSetting(0, piShortName, 'UserMsgIncUseLocalTime');
if DBGetContactSettingByte(0, piShortName, 'UserDontDeleteFriendsFromTheServer', 1) <> 1 then
DBWriteContactSettingByte(0, piShortName, opt_UserDontDeleteFriendsFromTheServer, DBGetContactSettingByte(0, piShortName, 'UserDontDeleteFriendsFromTheServer', 1));
DBDeleteContactSetting(0, piShortName, 'UserDontDeleteFriendsFromTheServer');
if DBGetContactSettingByte(0, piShortName, 'UserNonFriendsStatusSupport', 0) <> 0 then
DBWriteContactSettingByte(0, piShortName, opt_UserNonFriendsStatusSupport, DBGetContactSettingByte(0, piShortName, 'UserNonFriendsStatusSupport', 0));
DBDeleteContactSetting(0, piShortName, 'UserNonFriendsStatusSupport');
DBDeleteContactSetting(0, piShortName, 'UserNewMessagesFreqSecs');
// ask to join plugin's group
if DBGetContactSettingByte(0, piShortName, opt_GroupPluginJoined, 0) = 0 then // never asked before
case MessageBoxW(0, TranslateW(qst_join_vk_group), TranslateW(piShortName), MB_YESNOCANCEL + MB_ICONQUESTION) of
idYes:
DBWriteContactSettingByte(0, piShortName, opt_GroupPluginJoined, 2);
idNo:
DBWriteContactSettingByte(0, piShortName, opt_GroupPluginJoined, 1);
end;
// plugin runs first time - give some instructions
if DBGetContactSettingByte(0, piShortName, opt_FirstRun, 1) = 1 then
begin
case MessageBoxW(0, TranslateW(qst_first_run_addl_rights), TranslateW(piShortName), MB_YESNO + MB_ICONQUESTION) of
idYes: // open rights page
ShellAPI.ShellExecute(0, 'open', PChar(vk_url + vk_url_api_session), nil, nil, 0);
end;
case MessageBoxW(0, TranslateW(qst_first_run_go_online), TranslateW(piShortName), MB_YESNOCANCEL + MB_ICONQUESTION) of
idYes: // go online
vk_SetStatus(ID_STATUS_ONLINE);
idNo: // open Settings page
begin
FillChar(ood, sizeof(ood), 0);
ood.cbSize := sizeof(ood);
ood.pszGroup := 'Network';
ood.pszPage := piShortName;
ood.pszTab := 'Account';
PluginLink^.CallService(MS_OPT_OPENOPTIONS, 0, Windows.lParam(@ood));
end;
end;
DBWriteContactSettingByte(0, piShortName, opt_FirstRun, 0);
end;
Result := 0;
end;
// =============================================================================
// function is run, when miranda is asking whether each plugin is ok to exit
// miranda's shutdown sequence is the following:
// ME_SYSTEM_OKTOEXIT: 40072 (online), netlib works, MS_SYSTEM_TERMINATED returns False
// ME_SYSTEM_PRESHUTDOWN: 40071 (offline), netlib doesn't work, MS_SYSTEM_TERMINATED returns True
// Unload: 40071 (offline), netlib doesn't work, MS_SYSTEM_TERMINATED returns True
// -----------------------------------------------------------------------------
function OkToExit(wParam: wParam; lParam: lParam): integer; cdecl;
begin
Netlib_Log(vk_hNetlibUser, PChar('(OkToExit) Starting to exit miranda...'));
Netlib_Log(vk_hNetlibUser, PChar('(OkToExit) ... finishing ThrIDConnect thread'));
if Assigned(ThrIDConnect) then
ThrIDConnect.Terminate; // just send a command to stop thread
Netlib_Log(vk_hNetlibUser, PChar('(OkToExit) ... calling UpdateDataDestroy'));
if Assigned(ThrIDDataUpdate) then
ThrIDDataUpdate.Terminate;
Netlib_Log(vk_hNetlibUser, PChar('(OkToExit) ... making all contacts offline'));
SetStatusOffline(); // make all contacts offline
vk_Logout(); // logout from the site
Netlib_Log(vk_hNetlibUser, PChar('(OkToExit) ... ok to exit miranda'));
Result := 0;
end;
// =============================================================================
// function is run, when miranda is shutting down
// -----------------------------------------------------------------------------
function PreShutdown(wParam: wParam; lParam: lParam): integer; cdecl;
begin
Netlib_Log(vk_hNetlibUser, PChar('(PreShutdown) Starting miranda pre-shutdown...'));
Netlib_Log(vk_hNetlibUser, PChar('(PreShutdown) ... miranda pre-shutdown is completed'));
Result := 0;
end;
// =============================================================================
// function is run, when plugin is being unloaded
// -----------------------------------------------------------------------------
function Unload: int; cdecl;
begin
Netlib_Log(vk_hNetlibUser, PChar('(Unload) Starting to unload plugin...'));
// ask for thread completion
if Assigned(ThrIDConnect) then
ThrIDConnect.Terminate;
// destroy services
pluginLink^.DestroyServiceFunction(vk_hGetCaps);
pluginLink^.DestroyServiceFunction(vk_hGetName);
pluginLink^.DestroyServiceFunction(vk_hGetStatus);
pluginLink^.DestroyServiceFunction(vk_hSetStatus);
SearchDestroy();
pluginLink^.DestroyServiceFunction(vk_hNetlibUser);
pluginLink^.DestroyServiceFunction(vk_hkHookShutdown);
pluginLink^.DestroyServiceFunction(vk_hkHookOkToExit);
pluginLink^.DestroyServiceFunction(vk_hOnCreateAccMgrUI);
PopupDestroy();
MsgsDestroy();
AvatarsDestroy();
FoldersDestroy();
AddlStatusDestroy();
// unhook all events we hooked
pluginLink^.UnhookEvent(vk_hkContactDeleted);
pluginLink^.UnhookEvent(vk_hkModulesLoad);
pluginLink^.UnhookEvent(vk_hkOptInitialise);
Netlib_Log(vk_hNetlibUser, PChar('(Unload) ... unload plugin finished'));
Result := 0;
end;
exports
MirandaPluginInfo,
Load,
Unload,
MirandaPluginInterfaces,
MirandaPluginInfoEx;
begin
end.